001package ca.uhn.fhir.interceptor.api; 002 003/*- 004 * #%L 005 * HAPI FHIR - Core Library 006 * %% 007 * Copyright (C) 2014 - 2019 University Health Network 008 * %% 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 * #L% 021 */ 022 023import ca.uhn.fhir.model.base.resource.BaseOperationOutcome; 024import ca.uhn.fhir.rest.annotation.Read; 025import ca.uhn.fhir.rest.annotation.Search; 026import ca.uhn.fhir.rest.server.exceptions.AuthenticationException; 027import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; 028 029import javax.annotation.Nonnull; 030import java.util.*; 031 032/** 033 * Value for {@link Hook#value()} 034 * <p> 035 * Hook pointcuts are divided into several broad categories: 036 * <ul> 037 * <li>INTERCEPTOR_xxx: Hooks on the interceptor infrastructure itself</li> 038 * <li>CLIENT_xxx: Hooks on the HAPI FHIR Client framework</li> 039 * <li>SERVER_xxx: Hooks on the HAPI FHIR Server framework</li> 040 * <li>SUBSCRIPTION_xxx: Hooks on the HAPI FHIR Subscription framework</li> 041 * <li>STORAGE_xxx: Hooks on the storage engine</li> 042 * <li>JPA_PERFTRACE_xxx: Performance tracing hooks on the JPA server</li> 043 * </ul> 044 * </p> 045 */ 046public enum Pointcut { 047 048 /** 049 * <b>Registry Hook: </b> 050 * This pointcut will be called once when a given interceptor is registered 051 */ 052 INTERCEPTOR_REGISTERED(void.class), 053 054 /** 055 * <b>Client Hook:</b> 056 * This hook is called before an HTTP client request is sent 057 * <p> 058 * Hooks may accept the following parameters: 059 * <ul> 060 * <li> 061 * ca.uhn.fhir.rest.client.api.IHttpRequest - The details of the request 062 * </li> 063 * </ul> 064 * </p> 065 * Hook methods must return <code>void</code>. 066 */ 067 CLIENT_REQUEST(void.class, 068 "ca.uhn.fhir.rest.client.api.IHttpRequest" 069 ), 070 071 /** 072 * <b>Client Hook:</b> 073 * This hook is called after an HTTP client request has completed, prior to returning 074 * the results to the calling code. Hook methods may modify the response. 075 * <p> 076 * Hooks may accept the following parameters: 077 * <ul> 078 * <li> 079 * ca.uhn.fhir.rest.client.api.IHttpRequest - The details of the request 080 * ca.uhn.fhir.rest.client.api.IHttpRequest - The details of the response 081 * </li> 082 * </ul> 083 * </p> 084 * Hook methods must return <code>void</code>. 085 */ 086 CLIENT_RESPONSE(void.class, 087 "ca.uhn.fhir.rest.client.api.IHttpRequest", 088 "ca.uhn.fhir.rest.client.api.IHttpResponse" 089 ), 090 091 /** 092 * <b>Server Hook: </b> 093 * This hook is called before any other processing takes place for each incoming request. It may be used to provide 094 * alternate handling for some requests, or to screen requests before they are handled, etc. 095 * <p> 096 * Note that any exceptions thrown by this method will not be trapped by HAPI (they will be passed up to the server) 097 * </p> 098 * <p> 099 * Hooks may accept the following parameters: 100 * <ul> 101 * <li> 102 * javax.servlet.http.HttpServletRequest - The servlet request, when running in a servlet environment 103 * </li> 104 * <li> 105 * javax.servlet.http.HttpServletResponse - The servlet response, when running in a servlet environment 106 * </li> 107 * </ul> 108 * </p> 109 * Hook methods may return <code>true</code> or <code>void</code> if processing should continue normally. 110 * This is generally the right thing to do. If your interceptor is providing a response rather than 111 * letting HAPI handle the response normally, you must return <code>false</code>. In this case, 112 * no further processing will occur and no further interceptors will be called. 113 */ 114 SERVER_INCOMING_REQUEST_PRE_PROCESSED(boolean.class, 115 "javax.servlet.http.HttpServletRequest", 116 "javax.servlet.http.HttpServletResponse" 117 ), 118 119 /** 120 * <b>Server Hook: </b> 121 * This hook is invoked upon any exception being thrown within the server's request processing code. This includes 122 * any exceptions thrown within resource provider methods (e.g. {@link Search} and {@link Read} methods) as well as 123 * any runtime exceptions thrown by the server itself. This also includes any {@link AuthenticationException}s 124 * thrown. 125 * <p> 126 * Hooks may accept the following parameters: 127 * <ul> 128 * <li> 129 * ca.uhn.fhir.rest.api.server.RequestDetails - A bean containing details about the request that is about to be processed, including details such as the 130 * resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been 131 * pulled out of the servlet request. Note that the bean 132 * properties are not all guaranteed to be populated, depending on how early during processing the 133 * exception occurred. 134 * </li> 135 * <li> 136 * ca.uhn.fhir.rest.server.servlet.ServletRequestDetails - A bean containing details about the request that is about to be processed, including details such as the 137 * resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been 138 * pulled out of the servlet request. Note that the bean 139 * properties are not all guaranteed to be populated, depending on how early during processing the 140 * exception occurred. This parameter is identical to the RequestDetails parameter above but will 141 * only be populated when operating in a RestfulServer implementation. It is provided as a convenience. 142 * </li> 143 * <li> 144 * javax.servlet.http.HttpServletRequest - The servlet request, when running in a servlet environment 145 * </li> 146 * <li> 147 * javax.servlet.http.HttpServletResponse - The servlet response, when running in a servlet environment 148 * </li> 149 * <li> 150 * ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException - The exception that was thrown 151 * </li> 152 * </ul> 153 * </p> 154 * <p> 155 * Implementations of this method may choose to ignore/log/count/etc exceptions, and return <code>true</code> or 156 * <code>void</code>. In 157 * this case, processing will continue, and the server will automatically generate an {@link BaseOperationOutcome 158 * OperationOutcome}. Implementations may also choose to provide their own response to the client. In this case, they 159 * should return <code>false</code>, to indicate that they have handled the request and processing should stop. 160 * </p> 161 */ 162 SERVER_HANDLE_EXCEPTION(boolean.class, 163 "ca.uhn.fhir.rest.api.server.RequestDetails", 164 "ca.uhn.fhir.rest.server.servlet.ServletRequestDetails", 165 "javax.servlet.http.HttpServletRequest", 166 "javax.servlet.http.HttpServletResponse", 167 "ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException" 168 ), 169 170 /** 171 * <b>Server Hook:</b> 172 * This method is called just before the actual implementing server method is invoked. 173 * <p> 174 * Hooks may accept the following parameters: 175 * <ul> 176 * <li> 177 * ca.uhn.fhir.rest.api.server.RequestDetails - A bean containing details about the request that is about to be processed, including details such as the 178 * resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been 179 * pulled out of the servlet request. Note that the bean 180 * properties are not all guaranteed to be populated, depending on how early during processing the 181 * exception occurred. 182 * </li> 183 * <li> 184 * ca.uhn.fhir.rest.server.servlet.ServletRequestDetails - A bean containing details about the request that is about to be processed, including details such as the 185 * resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been 186 * pulled out of the servlet request. This parameter is identical to the RequestDetails parameter above but will 187 * only be populated when operating in a RestfulServer implementation. It is provided as a convenience. 188 * </li> 189 * <li> 190 * javax.servlet.http.HttpServletRequest - The servlet request, when running in a servlet environment 191 * </li> 192 * <li> 193 * javax.servlet.http.HttpServletResponse - The servlet response, when running in a servlet environment 194 * </li> 195 * </ul> 196 * <p> 197 * Hook methods may return <code>true</code> or <code>void</code> if processing should continue normally. 198 * This is generally the right thing to do. 199 * If your interceptor is providing an HTTP response rather than letting HAPI handle the response normally, you 200 * must return <code>false</code>. In this case, no further processing will occur and no further interceptors 201 * will be called. 202 * </p> 203 * <p> 204 * Hook methods may also throw {@link AuthenticationException} if they would like. This exception may be thrown 205 * to indicate that the interceptor has detected an unauthorized access 206 * attempt. If thrown, processing will stop and an HTTP 401 will be returned to the client. 207 */ 208 SERVER_INCOMING_REQUEST_POST_PROCESSED(boolean.class, 209 "ca.uhn.fhir.rest.api.server.RequestDetails", 210 "ca.uhn.fhir.rest.server.servlet.ServletRequestDetails", 211 "javax.servlet.http.HttpServletRequest", 212 "javax.servlet.http.HttpServletResponse" 213 ), 214 215 216 /** 217 * <b>Server Hook:</b> 218 * This hook is invoked before an incoming request is processed. Note that this method is called 219 * after the server has begin preparing the response to the incoming client request. 220 * As such, it is not able to supply a response to the incoming request in the way that 221 * SERVER_INCOMING_REQUEST_PRE_HANDLED and 222 * {@link #SERVER_INCOMING_REQUEST_POST_PROCESSED} 223 * are. 224 * <p> 225 * Hooks may accept the following parameters: 226 * <ul> 227 * <li> 228 * ca.uhn.fhir.rest.api.RestOperationTypeEnum - The type of operation that the FHIR server has determined that the client is trying to invoke 229 * </li> 230 * <li> 231 * ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails - An object which will be populated with the details which were extracted from the raw request by the 232 * server, e.g. the FHIR operation type and the parsed resource body (if any). 233 * </li> 234 * </ul> 235 * </p> 236 * <p> 237 * Hook methods must return <code>void</code> 238 * </p> 239 * <p> 240 * Hook methods method may throw a subclass of {@link BaseServerResponseException}, and processing 241 * will be aborted with an appropriate error returned to the client. 242 * </p> 243 */ 244 SERVER_INCOMING_REQUEST_PRE_HANDLED(void.class, 245 "ca.uhn.fhir.rest.api.RestOperationTypeEnum", 246 "ca.uhn.fhir.rest.server.interceptor.IServerInterceptor$ActionRequestDetails" 247 ), 248 249 /** 250 * <b>Server Hook:</b> 251 * This method is called upon any exception being thrown within the server's request processing code. This includes 252 * any exceptions thrown within resource provider methods (e.g. {@link Search} and {@link Read} methods) as well as 253 * any runtime exceptions thrown by the server itself. This hook method is invoked for each interceptor (until one of them 254 * returns a non-<code>null</code> response or the end of the list is reached), after which 255 * {@link #SERVER_HANDLE_EXCEPTION} is 256 * called for each interceptor. 257 * <p> 258 * This may be used to add an OperationOutcome to a response, or to convert between exception types for any reason. 259 * </p> 260 * <p> 261 * Implementations of this method may choose to ignore/log/count/etc exceptions, and return <code>null</code>. In 262 * this case, processing will continue, and the server will automatically generate an {@link BaseOperationOutcome 263 * OperationOutcome}. Implementations may also choose to provide their own response to the client. In this case, they 264 * should return a non-<code>null</code>, to indicate that they have handled the request and processing should stop. 265 * </p> 266 * <p> 267 * Hooks may accept the following parameters: 268 * <ul> 269 * <li> 270 * ca.uhn.fhir.rest.api.server.RequestDetails - A bean containing details about the request that is about to be processed, including details such as the 271 * resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been 272 * pulled out of the servlet request. Note that the bean 273 * properties are not all guaranteed to be populated, depending on how early during processing the 274 * exception occurred. 275 * </li> 276 * <li> 277 * ca.uhn.fhir.rest.server.servlet.ServletRequestDetails - A bean containing details about the request that is about to be processed, including details such as the 278 * resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been 279 * pulled out of the servlet request. This parameter is identical to the RequestDetails parameter above but will 280 * only be populated when operating in a RestfulServer implementation. It is provided as a convenience. 281 * </li> 282 * <li> 283 * java.lang.Throwable - The exception that was thrown. This will often be an instance of 284 * {@link BaseServerResponseException} but will not necessarily be one (e.g. it could be a 285 * {@link NullPointerException} in the case of a bug being triggered. 286 * </li> 287 * <li> 288 * javax.servlet.http.HttpServletRequest - The servlet request, when running in a servlet environment 289 * </li> 290 * <li> 291 * javax.servlet.http.HttpServletResponse - The servlet response, when running in a servlet environment 292 * </li> 293 * </ul> 294 * <p> 295 * Hook methods may return a new exception to use for processing, or <code>null</code> if this interceptor is not trying to 296 * modify the exception. For example, if this interceptor has nothing to do with exception processing, it 297 * should always return <code>null</code>. If this interceptor adds an OperationOutcome to the exception, it 298 * should return an exception. 299 * </p> 300 */ 301 SERVER_PRE_PROCESS_OUTGOING_EXCEPTION(BaseServerResponseException.class, 302 "ca.uhn.fhir.rest.api.server.RequestDetails", 303 "ca.uhn.fhir.rest.server.servlet.ServletRequestDetails", 304 "java.lang.Throwable", 305 "javax.servlet.http.HttpServletRequest", 306 "javax.servlet.http.HttpServletResponse" 307 ), 308 309 /** 310 * <b>Server Hook:</b> 311 * This method is called after the server implementation method has been called, but before any attempt 312 * to stream the response back to the client. Interceptors may examine or modify the response before it 313 * is returned, or even prevent the response. 314 * <p> 315 * Hooks may accept the following parameters: 316 * <ul> 317 * <li> 318 * ca.uhn.fhir.rest.api.server.RequestDetails - A bean containing details about the request that is about to be processed, including details such as the 319 * resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been 320 * pulled out of the servlet request. 321 * </li> 322 * <li> 323 * ca.uhn.fhir.rest.server.servlet.ServletRequestDetails - A bean containing details about the request that is about to be processed, including details such as the 324 * resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been 325 * pulled out of the servlet request. This parameter is identical to the RequestDetails parameter above but will 326 * only be populated when operating in a RestfulServer implementation. It is provided as a convenience. 327 * </li> 328 * <li> 329 * org.hl7.fhir.instance.model.api.IBaseResource - The resource that will be returned. This parameter may be <code>null</code> for some responses. 330 * </li> 331 * <li> 332 * ca.uhn.fhir.rest.api.server.ResponseDetails - This object contains details about the response, including the contents. Hook methods may modify this object to change or replace the response. 333 * </li> 334 * <li> 335 * javax.servlet.http.HttpServletRequest - The servlet request, when running in a servlet environment 336 * </li> 337 * <li> 338 * javax.servlet.http.HttpServletResponse - The servlet response, when running in a servlet environment 339 * </li> 340 * </ul> 341 * </p> 342 * <p> 343 * Hook methods may return <code>true</code> or <code>void</code> if processing should continue normally. 344 * This is generally the right thing to do. If your interceptor is providing a response rather than 345 * letting HAPI handle the response normally, you must return <code>false</code>. In this case, 346 * no further processing will occur and no further interceptors will be called. 347 * </p> 348 * <p> 349 * Hook methods may also throw {@link AuthenticationException} to indicate that the interceptor 350 * has detected an unauthorized access attempt. If thrown, processing will stop and an HTTP 401 351 * will be returned to the client. 352 */ 353 SERVER_OUTGOING_RESPONSE(boolean.class, 354 "ca.uhn.fhir.rest.api.server.RequestDetails", 355 "ca.uhn.fhir.rest.server.servlet.ServletRequestDetails", 356 "org.hl7.fhir.instance.model.api.IBaseResource", 357 "ca.uhn.fhir.rest.api.server.ResponseDetails", 358 "javax.servlet.http.HttpServletRequest", 359 "javax.servlet.http.HttpServletResponse" 360 ), 361 362 /** 363 * <b>Server Hook:</b> 364 * This method is called after all processing is completed for a request, but only if the 365 * request completes normally (i.e. no exception is thrown). 366 * <p> 367 * Hooks may accept the following parameters: 368 * <ul> 369 * <li> 370 * ca.uhn.fhir.rest.api.server.RequestDetails - A bean containing details about the request that is about to be processed, including details such as the 371 * resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been 372 * pulled out of the servlet request. 373 * </li> 374 * <li> 375 * ca.uhn.fhir.rest.server.servlet.ServletRequestDetails - A bean containing details about the request that is about to be processed, including details such as the 376 * resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been 377 * pulled out of the request. This will be null if the server is not deployed to a RestfulServer environment. 378 * </li> 379 * </ul> 380 * </p> 381 * <p> 382 * This method must return <code>void</code> 383 * </p> 384 * <p> 385 * This method should not throw any exceptions. Any exception that is thrown by this 386 * method will be logged, but otherwise not acted upon (i.e. even if a hook method 387 * throws an exception, processing will continue and other interceptors will be 388 * called). Therefore it is considered a bug to throw an exception from hook methods using this 389 * pointcut. 390 * </p> 391 */ 392 SERVER_PROCESSING_COMPLETED_NORMALLY( 393 void.class, 394 new ExceptionHandlingSpec() 395 .addLogAndSwallow(Throwable.class), 396 "ca.uhn.fhir.rest.api.server.RequestDetails", 397 "ca.uhn.fhir.rest.server.servlet.ServletRequestDetails" 398 ), 399 400 /** 401 * Invoked whenever a persisted resource has been modified and is being submitted to the 402 * subscription processing pipeline. This method is called before the resource is placed 403 * on any queues for processing and executes synchronously during the resource modification 404 * operation itself, so it should return quickly. 405 * <p> 406 * Hooks may accept the following parameters: 407 * <ul> 408 * <li>ca.uhn.fhir.jpa.subscription.module.ResourceModifiedMessage - Hooks may modify this parameter. This will affect the checking process.</li> 409 * </ul> 410 * </p> 411 * <p> 412 * Hooks may return <code>void</code> or may return a <code>boolean</code>. If the method returns 413 * <code>void</code> or <code>true</code>, processing will continue normally. If the method 414 * returns <code>false</code>, subscription processing will not proceed for the given resource; 415 * </p> 416 */ 417 SUBSCRIPTION_RESOURCE_MODIFIED(boolean.class, "ca.uhn.fhir.jpa.subscription.module.ResourceModifiedMessage"), 418 419 420 /** 421 * Invoked any time that a resource is matched by an individual subscription, and 422 * is about to be queued for delivery. 423 * <p> 424 * Hooks may make changes to the delivery payload, or make changes to the 425 * canonical subscription such as adding headers, modifying the channel 426 * endpoint, etc. 427 * </p> 428 * Hooks may accept the following parameters: 429 * <ul> 430 * <li>ca.uhn.fhir.jpa.subscription.module.CanonicalSubscription</li> 431 * <li>ca.uhn.fhir.jpa.subscription.module.subscriber.ResourceDeliveryMessage</li> 432 * <li>ca.uhn.fhir.jpa.subscription.module.matcher.SubscriptionMatchResult</li> 433 * </ul> 434 * <p> 435 * Hooks may return <code>void</code> or may return a <code>boolean</code>. If the method returns 436 * <code>void</code> or <code>true</code>, processing will continue normally. If the method 437 * returns <code>false</code>, delivery will be aborted. 438 * </p> 439 */ 440 SUBSCRIPTION_RESOURCE_MATCHED(boolean.class, "ca.uhn.fhir.jpa.subscription.module.CanonicalSubscription", "ca.uhn.fhir.jpa.subscription.module.subscriber.ResourceDeliveryMessage", "ca.uhn.fhir.jpa.subscription.module.matcher.SubscriptionMatchResult"), 441 442 443 /** 444 * Invoked whenever a persisted resource was checked against all active subscriptions, and did not 445 * match any. 446 * <p> 447 * Hooks may accept the following parameters: 448 * <ul> 449 * <li>ca.uhn.fhir.jpa.subscription.module.ResourceModifiedMessage - Hooks should not modify this parameter as changes will not have any effect.</li> 450 * </ul> 451 * </p> 452 * <p> 453 * Hooks should return <code>void</code>. 454 * </p> 455 */ 456 SUBSCRIPTION_RESOURCE_DID_NOT_MATCH_ANY_SUBSCRIPTIONS(void.class, "ca.uhn.fhir.jpa.subscription.module.ResourceModifiedMessage"), 457 458 /** 459 * Invoked immediately before the delivery of a subscription, and right before any channel-specific 460 * hooks are invoked (e.g. {@link #SUBSCRIPTION_BEFORE_REST_HOOK_DELIVERY}. 461 * <p> 462 * Hooks may make changes to the delivery payload, or make changes to the 463 * canonical subscription such as adding headers, modifying the channel 464 * endpoint, etc. 465 * </p> 466 * Hooks may accept the following parameters: 467 * <ul> 468 * <li>ca.uhn.fhir.jpa.subscription.module.CanonicalSubscription</li> 469 * <li>ca.uhn.fhir.jpa.subscription.module.subscriber.ResourceDeliveryMessage</li> 470 * </ul> 471 * <p> 472 * Hooks may return <code>void</code> or may return a <code>boolean</code>. If the method returns 473 * <code>void</code> or <code>true</code>, processing will continue normally. If the method 474 * returns <code>false</code>, processing will be aborted. 475 * </p> 476 */ 477 SUBSCRIPTION_BEFORE_DELIVERY(boolean.class, "ca.uhn.fhir.jpa.subscription.module.CanonicalSubscription", "ca.uhn.fhir.jpa.subscription.module.subscriber.ResourceDeliveryMessage"), 478 479 /** 480 * Invoked immediately after the delivery of a subscription, and right before any channel-specific 481 * hooks are invoked (e.g. {@link #SUBSCRIPTION_AFTER_REST_HOOK_DELIVERY}. 482 * <p> 483 * Hooks may accept the following parameters: 484 * </p> 485 * <ul> 486 * <li>ca.uhn.fhir.jpa.subscription.module.CanonicalSubscription</li> 487 * <li>ca.uhn.fhir.jpa.subscription.module.subscriber.ResourceDeliveryMessage</li> 488 * </ul> 489 * <p> 490 * Hooks should return <code>void</code>. 491 * </p> 492 */ 493 SUBSCRIPTION_AFTER_DELIVERY(void.class, "ca.uhn.fhir.jpa.subscription.module.CanonicalSubscription", "ca.uhn.fhir.jpa.subscription.module.subscriber.ResourceDeliveryMessage"), 494 495 /** 496 * Invoked immediately after the attempted delivery of a subscription, if the delivery 497 * failed. 498 * <p> 499 * Hooks may accept the following parameters: 500 * </p> 501 * <ul> 502 * <li>java.lang.Exception - The exception that caused the failure. Note this could be an exception thrown by a SUBSCRIPTION_BEFORE_DELIVERY or SUBSCRIPTION_AFTER_DELIVERY interceptor</li> 503 * <li>ca.uhn.fhir.jpa.subscription.module.subscriber.ResourceDeliveryMessage - the message that triggered the exception</li> 504 * <li>java.lang.Exception</li> 505 * </ul> 506 * <p> 507 * Hooks may return <code>void</code> or may return a <code>boolean</code>. If the method returns 508 * <code>void</code> or <code>true</code>, processing will continue normally, meaning that 509 * an exception will be thrown by the delivery mechanism. This typically means that the 510 * message will be returned to the processing queue. If the method 511 * returns <code>false</code>, processing will be aborted and no further action will be 512 * taken for the delivery. 513 * </p> 514 */ 515 SUBSCRIPTION_AFTER_DELIVERY_FAILED(boolean.class, "ca.uhn.fhir.jpa.subscription.module.subscriber.ResourceDeliveryMessage", "java.lang.Exception"), 516 517 /** 518 * Invoked immediately after the delivery of a REST HOOK subscription. 519 * <p> 520 * When this hook is called, all processing is complete so this hook should not 521 * make any changes to the parameters. 522 * </p> 523 * Hooks may accept the following parameters: 524 * <ul> 525 * <li>ca.uhn.fhir.jpa.subscription.module.CanonicalSubscription</li> 526 * <li>ca.uhn.fhir.jpa.subscription.module.subscriber.ResourceDeliveryMessage</li> 527 * </ul> 528 * <p> 529 * Hooks should return <code>void</code>. 530 * </p> 531 */ 532 SUBSCRIPTION_AFTER_REST_HOOK_DELIVERY(void.class, "ca.uhn.fhir.jpa.subscription.module.CanonicalSubscription", "ca.uhn.fhir.jpa.subscription.module.subscriber.ResourceDeliveryMessage"), 533 534 /** 535 * Invoked immediately before the delivery of a REST HOOK subscription. 536 * <p> 537 * Hooks may make changes to the delivery payload, or make changes to the 538 * canonical subscription such as adding headers, modifying the channel 539 * endpoint, etc. 540 * </p> 541 * Hooks may accept the following parameters: 542 * <ul> 543 * <li>ca.uhn.fhir.jpa.subscription.module.CanonicalSubscription</li> 544 * <li>ca.uhn.fhir.jpa.subscription.module.subscriber.ResourceDeliveryMessage</li> 545 * </ul> 546 * <p> 547 * Hooks may return <code>void</code> or may return a <code>boolean</code>. If the method returns 548 * <code>void</code> or <code>true</code>, processing will continue normally. If the method 549 * returns <code>false</code>, processing will be aborted. 550 * </p> 551 */ 552 SUBSCRIPTION_BEFORE_REST_HOOK_DELIVERY(boolean.class, "ca.uhn.fhir.jpa.subscription.module.CanonicalSubscription", "ca.uhn.fhir.jpa.subscription.module.subscriber.ResourceDeliveryMessage"), 553 554 555 /** 556 * Invoked whenever a persisted resource (a resource that has just been stored in the 557 * database via a create/update/patch/etc.) is about to be checked for whether any subscriptions 558 * were triggered as a result of the operation. 559 * <p> 560 * Hooks may accept the following parameters: 561 * <ul> 562 * <li>ca.uhn.fhir.jpa.subscription.module.ResourceModifiedMessage - Hooks may modify this parameter. This will affect the checking process.</li> 563 * </ul> 564 * </p> 565 * <p> 566 * Hooks may return <code>void</code> or may return a <code>boolean</code>. If the method returns 567 * <code>void</code> or <code>true</code>, processing will continue normally. If the method 568 * returns <code>false</code>, processing will be aborted. 569 * </p> 570 */ 571 SUBSCRIPTION_BEFORE_PERSISTED_RESOURCE_CHECKED(boolean.class, "ca.uhn.fhir.jpa.subscription.module.ResourceModifiedMessage"), 572 573 /** 574 * Invoked whenever a persisted resource (a resource that has just been stored in the 575 * database via a create/update/patch/etc.) has been checked for whether any subscriptions 576 * were triggered as a result of the operation. 577 * <p> 578 * Hooks may accept the following parameters: 579 * <ul> 580 * <li>ca.uhn.fhir.jpa.subscription.module.ResourceModifiedMessage - This parameter should not be modified as processing is complete when this hook is invoked.</li> 581 * </ul> 582 * </p> 583 * <p> 584 * Hooks should return <code>void</code>. 585 * </p> 586 */ 587 SUBSCRIPTION_AFTER_PERSISTED_RESOURCE_CHECKED(void.class, "ca.uhn.fhir.jpa.subscription.module.ResourceModifiedMessage"), 588 589 /** 590 * Invoked immediately after an active subscription is "registered". In HAPI FHIR, when 591 * a subscription 592 * <p> 593 * Hooks may make changes to the canonicalized subscription and this will have an effect 594 * on processing across this server. Note however that timing issues may occur, since the 595 * subscription is already technically live by the time this hook is called. 596 * </p> 597 * Hooks may accept the following parameters: 598 * <ul> 599 * <li>ca.uhn.fhir.jpa.subscription.module.CanonicalSubscription</li> 600 * </ul> 601 * <p> 602 * Hooks should return <code>void</code>. 603 * </p> 604 */ 605 SUBSCRIPTION_AFTER_ACTIVE_SUBSCRIPTION_REGISTERED(void.class, "ca.uhn.fhir.jpa.subscription.module.CanonicalSubscription"), 606 607 /** 608 * Invoked when a resource may be returned to the user, whether as a part of a READ, 609 * a SEARCH, or even as the response to a CREATE/UPDATE, etc. 610 * <p> 611 * This hook is invoked when a resource has been loaded by the storage engine and 612 * is being returned to the HTTP stack for response. This is not a guarantee that the 613 * client will ultimately see it, since filters/headers/etc may affect what 614 * is returned but if a resource is loaded it is likely to be used. 615 * Note also that caching may affect whether this pointcut is invoked. 616 * </p> 617 * <p> 618 * Hooks will have access to the contents of the resource being returned 619 * and may choose to make modifications. These changes will be reflected in 620 * returned resource but have no effect on storage. 621 * </p> 622 * Hooks may accept the following parameters: 623 * <ul> 624 * <li>org.hl7.fhir.instance.model.api.IBaseResource - The resource being returned</li> 625 * <li> 626 * ca.uhn.fhir.rest.api.server.RequestDetails - A bean containing details about the request that is about to be processed, including details such as the 627 * resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been 628 * pulled out of the servlet request. Note that the bean 629 * properties are not all guaranteed to be populated, depending on how early during processing the 630 * exception occurred. <b>Note that this parameter may be null in contexts where the request is not 631 * known, such as while processing searches</b> 632 * </li> 633 * <li> 634 * ca.uhn.fhir.rest.server.servlet.ServletRequestDetails - A bean containing details about the request that is about to be processed, including details such as the 635 * resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been 636 * pulled out of the servlet request. This parameter is identical to the RequestDetails parameter above but will 637 * only be populated when operating in a RestfulServer implementation. It is provided as a convenience. 638 * </li> 639 * </ul> 640 * <p> 641 * Hooks should return <code>void</code>. 642 * </p> 643 */ 644 STORAGE_PREACCESS_RESOURCE(void.class, 645 "org.hl7.fhir.instance.model.api.IBaseResource", 646 "ca.uhn.fhir.rest.api.server.RequestDetails", 647 "ca.uhn.fhir.rest.server.servlet.ServletRequestDetails" 648 ), 649 650 /** 651 * Invoked before a resource will be created, immediately before the resource 652 * is persisted to the database. 653 * <p> 654 * Hooks will have access to the contents of the resource being created 655 * and may choose to make modifications to it. These changes will be 656 * reflected in permanent storage. 657 * </p> 658 * Hooks may accept the following parameters: 659 * <ul> 660 * <li>org.hl7.fhir.instance.model.api.IBaseResource</li> 661 * <li> 662 * ca.uhn.fhir.rest.api.server.RequestDetails - A bean containing details about the request that is about to be processed, including details such as the 663 * resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been 664 * pulled out of the servlet request. Note that the bean 665 * properties are not all guaranteed to be populated, depending on how early during processing the 666 * exception occurred. 667 * </li> 668 * <li> 669 * ca.uhn.fhir.rest.server.servlet.ServletRequestDetails - A bean containing details about the request that is about to be processed, including details such as the 670 * resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been 671 * pulled out of the servlet request. This parameter is identical to the RequestDetails parameter above but will 672 * only be populated when operating in a RestfulServer implementation. It is provided as a convenience. 673 * </li> 674 * </ul> 675 * <p> 676 * Hooks should return <code>void</code>. 677 * </p> 678 */ 679 STORAGE_PRESTORAGE_RESOURCE_CREATED(void.class, 680 "org.hl7.fhir.instance.model.api.IBaseResource", 681 "ca.uhn.fhir.rest.api.server.RequestDetails", 682 "ca.uhn.fhir.rest.server.servlet.ServletRequestDetails" 683 ), 684 685 /** 686 * Invoked before a resource will be created, immediately before the transaction 687 * is committed (after all validation and other business rules have successfully 688 * completed, and any other database activity is complete. 689 * <p> 690 * Hooks will have access to the contents of the resource being created 691 * but should generally not make any 692 * changes as storage has already occurred. Changes will not be reflected 693 * in storage, but may be reflected in the HTTP response. 694 * </p> 695 * Hooks may accept the following parameters: 696 * <ul> 697 * <li>org.hl7.fhir.instance.model.api.IBaseResource</li> 698 * <li> 699 * ca.uhn.fhir.rest.api.server.RequestDetails - A bean containing details about the request that is about to be processed, including details such as the 700 * resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been 701 * pulled out of the servlet request. Note that the bean 702 * properties are not all guaranteed to be populated, depending on how early during processing the 703 * exception occurred. 704 * </li> 705 * <li> 706 * ca.uhn.fhir.rest.server.servlet.ServletRequestDetails - A bean containing details about the request that is about to be processed, including details such as the 707 * resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been 708 * pulled out of the servlet request. This parameter is identical to the RequestDetails parameter above but will 709 * only be populated when operating in a RestfulServer implementation. It is provided as a convenience. 710 * </li> 711 * </ul> 712 * <p> 713 * Hooks should return <code>void</code>. 714 * </p> 715 */ 716 STORAGE_PRECOMMIT_RESOURCE_CREATED(void.class, 717 "org.hl7.fhir.instance.model.api.IBaseResource", 718 "ca.uhn.fhir.rest.api.server.RequestDetails", 719 "ca.uhn.fhir.rest.server.servlet.ServletRequestDetails" 720 ), 721 722 /** 723 * Invoked before a resource will be created 724 * <p> 725 * Hooks will have access to the contents of the resource being deleted 726 * but should not make any changes as storage has already occurred 727 * </p> 728 * Hooks may accept the following parameters: 729 * <ul> 730 * <li>org.hl7.fhir.instance.model.api.IBaseResource - The resource being deleted</li> 731 * <li> 732 * ca.uhn.fhir.rest.api.server.RequestDetails - A bean containing details about the request that is about to be processed, including details such as the 733 * resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been 734 * pulled out of the servlet request. Note that the bean 735 * properties are not all guaranteed to be populated, depending on how early during processing the 736 * exception occurred. 737 * </li> 738 * <li> 739 * ca.uhn.fhir.rest.server.servlet.ServletRequestDetails - A bean containing details about the request that is about to be processed, including details such as the 740 * resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been 741 * pulled out of the servlet request. This parameter is identical to the RequestDetails parameter above but will 742 * only be populated when operating in a RestfulServer implementation. It is provided as a convenience. 743 * </li> 744 * </ul> 745 * <p> 746 * Hooks should return <code>void</code>. 747 * </p> 748 */ 749 STORAGE_PRECOMMIT_RESOURCE_DELETED(void.class, 750 "org.hl7.fhir.instance.model.api.IBaseResource", 751 "ca.uhn.fhir.rest.api.server.RequestDetails", 752 "ca.uhn.fhir.rest.server.servlet.ServletRequestDetails" 753 ), 754 755 756 /** 757 * Invoked before a resource will be updated, immediately before the transaction 758 * is committed (after all validation and other business rules have successfully 759 * completed, and any other database activity is complete. 760 * <p> 761 * Hooks will have access to the contents of the resource being updated 762 * (both the previous and new contents) but should generally not make any 763 * changes as storage has already occurred. Changes will not be reflected 764 * in storage, but may be reflected in the HTTP response. 765 * </p> 766 * Hooks may accept the following parameters: 767 * <ul> 768 * <li>org.hl7.fhir.instance.model.api.IBaseResource - The previous contents of the resource</li> 769 * <li>org.hl7.fhir.instance.model.api.IBaseResource - The proposed new new contents of the resource</li> 770 * <li> 771 * ca.uhn.fhir.rest.api.server.RequestDetails - A bean containing details about the request that is about to be processed, including details such as the 772 * resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been 773 * pulled out of the servlet request. Note that the bean 774 * properties are not all guaranteed to be populated, depending on how early during processing the 775 * exception occurred. 776 * </li> 777 * <li> 778 * ca.uhn.fhir.rest.server.servlet.ServletRequestDetails - A bean containing details about the request that is about to be processed, including details such as the 779 * resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been 780 * pulled out of the servlet request. This parameter is identical to the RequestDetails parameter above but will 781 * only be populated when operating in a RestfulServer implementation. It is provided as a convenience. 782 * </li> 783 * </ul> 784 * <p> 785 * Hooks should return <code>void</code>. 786 * </p> 787 */ 788 STORAGE_PRECOMMIT_RESOURCE_UPDATED(void.class, 789 "org.hl7.fhir.instance.model.api.IBaseResource", 790 "org.hl7.fhir.instance.model.api.IBaseResource", 791 "ca.uhn.fhir.rest.api.server.RequestDetails", 792 "ca.uhn.fhir.rest.server.servlet.ServletRequestDetails" 793 ), 794 795 /** 796 * Invoked before a resource will be updated, immediately before the resource 797 * is persisted to the database. 798 * <p> 799 * Hooks will have access to the contents of the resource being updated 800 * (both the previous and new contents) and may choose to make modifications 801 * to the new contents of the resource. These changes will be reflected in 802 * permanent storage. 803 * </p> 804 * Hooks may accept the following parameters: 805 * <ul> 806 * <li>org.hl7.fhir.instance.model.api.IBaseResource - The previous contents of the resource being updated</li> 807 * <li>org.hl7.fhir.instance.model.api.IBaseResource - The new contents of the resource being updated</li> 808 * <li> 809 * ca.uhn.fhir.rest.api.server.RequestDetails - A bean containing details about the request that is about to be processed, including details such as the 810 * resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been 811 * pulled out of the servlet request. Note that the bean 812 * properties are not all guaranteed to be populated, depending on how early during processing the 813 * exception occurred. 814 * </li> 815 * <li> 816 * ca.uhn.fhir.rest.server.servlet.ServletRequestDetails - A bean containing details about the request that is about to be processed, including details such as the 817 * resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been 818 * pulled out of the servlet request. This parameter is identical to the RequestDetails parameter above but will 819 * only be populated when operating in a RestfulServer implementation. It is provided as a convenience. 820 * </li> 821 * </ul> 822 * <p> 823 * Hooks should return <code>void</code>. 824 * </p> 825 */ 826 STORAGE_PRESTORAGE_RESOURCE_UPDATED(void.class, 827 "org.hl7.fhir.instance.model.api.IBaseResource", 828 "org.hl7.fhir.instance.model.api.IBaseResource", 829 "ca.uhn.fhir.rest.api.server.RequestDetails", 830 "ca.uhn.fhir.rest.server.servlet.ServletRequestDetails" 831 ), 832 833 /** 834 * Invoked before a resource will be created, immediately before the resource 835 * is persisted to the database. 836 * <p> 837 * Hooks will have access to the contents of the resource being created 838 * and may choose to make modifications to it. These changes will be 839 * reflected in permanent storage. 840 * </p> 841 * Hooks may accept the following parameters: 842 * <ul> 843 * <li>org.hl7.fhir.instance.model.api.IBaseResource - The resource being deleted</li> 844 * <li> 845 * ca.uhn.fhir.rest.api.server.RequestDetails - A bean containing details about the request that is about to be processed, including details such as the 846 * resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been 847 * pulled out of the servlet request. Note that the bean 848 * properties are not all guaranteed to be populated, depending on how early during processing the 849 * exception occurred. 850 * </li> 851 * <li> 852 * ca.uhn.fhir.rest.server.servlet.ServletRequestDetails - A bean containing details about the request that is about to be processed, including details such as the 853 * resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been 854 * pulled out of the servlet request. This parameter is identical to the RequestDetails parameter above but will 855 * only be populated when operating in a RestfulServer implementation. It is provided as a convenience. 856 * </li> 857 * </ul> 858 * <p> 859 * Hooks should return <code>void</code>. 860 * </p> 861 */ 862 STORAGE_PRESTORAGE_RESOURCE_DELETED(void.class, 863 "org.hl7.fhir.instance.model.api.IBaseResource", 864 "ca.uhn.fhir.rest.api.server.RequestDetails", 865 "ca.uhn.fhir.rest.server.servlet.ServletRequestDetails" 866 ), 867 868 /** 869 * Note that this is a performance tracing hook. Use with caution in production 870 * systems, since calling it may (or may not) carry a cost. 871 * <p> 872 * This hook is invoked when any informational or warning messages generated by the 873 * SearchCoordinator are created. It is typically used to provide logging 874 * or capture details related to a specific request. 875 * </p> 876 * Hooks may accept the following parameters: 877 * <ul> 878 * <li> 879 * ca.uhn.fhir.jpa.model.search.StorageProcessingMessage - Contains the message 880 * </li> 881 * </ul> 882 * <p> 883 * Hooks should return <code>void</code>. 884 * </p> 885 */ 886 STORAGE_PROCESSING_MESSAGE(void.class, 887 "ca.uhn.fhir.jpa.model.search.StorageProcessingMessage" 888 ), 889 890 /** 891 * Note that this is a performance tracing hook. Use with caution in production 892 * systems, since calling it may (or may not) carry a cost. 893 * <p> 894 * This hook is invoked when a search has returned the very first result 895 * from the database. The timing on this call can be a good indicator of how 896 * performant a query is in general. 897 * </p> 898 * Hooks may accept the following parameters: 899 * <ul> 900 * <li> 901 * ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails - Contains details about the search being 902 * performed. Hooks should not modify this object. 903 * </li> 904 * </ul> 905 * <p> 906 * Hooks should return <code>void</code>. 907 * </p> 908 */ 909 JPA_PERFTRACE_SEARCH_FIRST_RESULT_LOADED(void.class, "ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails"), 910 911 /** 912 * Note that this is a performance tracing hook. Use with caution in production 913 * systems, since calling it may (or may not) carry a cost. 914 * <p> 915 * This hook is invoked when an individual search query SQL SELECT statement 916 * has completed and no more results are available from that query. Note that this 917 * doesn't necessarily mean that no more matching results exist in the database, 918 * since HAPI FHIR JPA batch loads results in to the query cache in chunks in order 919 * to provide predicable results without overloading memory or the database. 920 * </p> 921 * Hooks may accept the following parameters: 922 * <ul> 923 * <li> 924 * ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails - Contains details about the search being 925 * performed. Hooks should not modify this object. 926 * </li> 927 * </ul> 928 * <p> 929 * Hooks should return <code>void</code>. 930 * </p> 931 */ 932 JPA_PERFTRACE_SEARCH_SELECT_COMPLETE(void.class, "ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails"), 933 934 /** 935 * Note that this is a performance tracing hook. Use with caution in production 936 * systems, since calling it may (or may not) carry a cost. 937 * <p> 938 * This hook is invoked when a search has failed for any reason. When this pointcut 939 * is invoked, the search has completed unsuccessfully and will not be continued. 940 * </p> 941 * Hooks may accept the following parameters: 942 * <ul> 943 * <li> 944 * ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails - Contains details about the search being 945 * performed. Hooks should not modify this object. 946 * </li> 947 * </ul> 948 * <p> 949 * Hooks should return <code>void</code>. 950 * </p> 951 */ 952 JPA_PERFTRACE_SEARCH_FAILED(void.class, "ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails"), 953 954 /** 955 * Note that this is a performance tracing hook. Use with caution in production 956 * systems, since calling it may (or may not) carry a cost. 957 * <p> 958 * This hook is invoked when a search has failed for any reason. When this pointcut 959 * is invoked, a pass in the Search Coordinator has completed successfully, but 960 * not all possible resources have been loaded yet so a future paging request 961 * may trigger a new task that will load further resources. 962 * </p> 963 * Hooks may accept the following parameters: 964 * <ul> 965 * <li> 966 * ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails - Contains details about the search being 967 * performed. Hooks should not modify this object. 968 * </li> 969 * </ul> 970 * <p> 971 * Hooks should return <code>void</code>. 972 * </p> 973 */ 974 JPA_PERFTRACE_SEARCH_PASS_COMPLETE(void.class, "ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails"), 975 976 /** 977 * Note that this is a performance tracing hook. Use with caution in production 978 * systems, since calling it may (or may not) carry a cost. 979 * <p> 980 * This hook is invoked when a search has failed for any reason. When this pointcut 981 * is invoked, a pass in the Search Coordinator has completed successfully, and all 982 * possible results have been fetched and loaded into the query cache. 983 * </p> 984 * Hooks may accept the following parameters: 985 * <ul> 986 * <li> 987 * ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails - Contains details about the search being 988 * performed. Hooks should not modify this object. 989 * </li> 990 * </ul> 991 * <p> 992 * Hooks should return <code>void</code>. 993 * </p> 994 */ 995 JPA_PERFTRACE_SEARCH_COMPLETE(void.class, "ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails"), 996 997 998 /** 999 * This pointcut is used only for unit tests. Do not use in production code as it may be changed or 1000 * removed at any time. 1001 */ 1002 TEST_RB( 1003 boolean.class, 1004 new ExceptionHandlingSpec().addLogAndSwallow(IllegalStateException.class), 1005 String.class.getName(), 1006 String.class.getName()), 1007 1008 /** 1009 * This pointcut is used only for unit tests. Do not use in production code as it may be changed or 1010 * removed at any time. 1011 */ 1012 TEST_RO(BaseServerResponseException.class, String.class.getName(), String.class.getName()); 1013 1014 private final List<String> myParameterTypes; 1015 private final Class<?> myReturnType; 1016 private final ExceptionHandlingSpec myExceptionHandlingSpec; 1017 1018 Pointcut(@Nonnull Class<?> theReturnType, String... theParameterTypes) { 1019 this(theReturnType, new ExceptionHandlingSpec(), theParameterTypes); 1020 } 1021 1022 Pointcut(@Nonnull Class<?> theReturnType, @Nonnull ExceptionHandlingSpec theExceptionHandlingSpec, String... theParameterTypes) { 1023 myReturnType = theReturnType; 1024 myExceptionHandlingSpec = theExceptionHandlingSpec; 1025 myParameterTypes = Collections.unmodifiableList(Arrays.asList(theParameterTypes)); 1026 } 1027 1028 public boolean isShouldLogAndSwallowException(@Nonnull Throwable theException) { 1029 for (Class<? extends Throwable> next : myExceptionHandlingSpec.myTypesToLogAndSwallow) { 1030 if (next.isAssignableFrom(theException.getClass())) { 1031 return true; 1032 } 1033 } 1034 return false; 1035 } 1036 1037 @Nonnull 1038 public Class<?> getReturnType() { 1039 return myReturnType; 1040 } 1041 1042 @Nonnull 1043 public List<String> getParameterTypes() { 1044 return myParameterTypes; 1045 } 1046 1047 private static class ExceptionHandlingSpec { 1048 1049 private final Set<Class<? extends Throwable>> myTypesToLogAndSwallow = new HashSet<>(); 1050 1051 ExceptionHandlingSpec addLogAndSwallow(@Nonnull Class<? extends Throwable> theType) { 1052 myTypesToLogAndSwallow.add(theType); 1053 return this; 1054 } 1055 1056 } 1057 1058}