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}