001/*-
002 * #%L
003 * Smile CDR - CDR
004 * %%
005 * Copyright (C) 2016 - 2025 Smile CDR, Inc.
006 * %%
007 * All rights reserved.
008 * #L%
009 */
010package ca.cdr.api.fhir.interceptor;
011
012import ca.cdr.api.consent.ConsentActiveResourceResolutionRequest;
013import ca.cdr.api.consent.ConsentFetchQueries;
014import ca.cdr.api.consent.ConsentFixedPolicyRequest;
015import ca.cdr.api.consent.ConsentLookupContext;
016import ca.cdr.api.fhirgw.json.AvailableRoutesJson;
017import ca.cdr.api.fhirgw.json.GatewayTargetJson;
018import ca.cdr.api.fhirgw.json.MatchedRoutesJson;
019import ca.cdr.api.fhirgw.model.CreateRequest;
020import ca.cdr.api.fhirgw.model.DeleteRequest;
021import ca.cdr.api.fhirgw.model.HistoryRequest;
022import ca.cdr.api.fhirgw.model.ISearchResultsAccumulator;
023import ca.cdr.api.fhirgw.model.OperationRequest;
024import ca.cdr.api.fhirgw.model.OperationResponse;
025import ca.cdr.api.fhirgw.model.ReadRequest;
026import ca.cdr.api.fhirgw.model.SearchPageRequest;
027import ca.cdr.api.fhirgw.model.SearchRequest;
028import ca.cdr.api.fhirgw.model.SearchResponse;
029import ca.cdr.api.fhirgw.model.TransactionRequest;
030import ca.cdr.api.fhirgw.model.UpdateRequest;
031import ca.cdr.api.model.json.AuditEventJson;
032import ca.cdr.api.model.json.AuditEventPrePersistJson;
033import ca.cdr.api.model.json.ConvertedTransactionBundlesJson;
034import ca.cdr.api.model.json.IOAuth2ClientDetails;
035import ca.cdr.api.model.json.OAuth2ClientDetailsJson;
036import ca.cdr.api.model.json.OpenIdTokenResponse;
037import ca.cdr.api.model.json.UserSessionDetailsJson;
038import ca.cdr.api.model.json.appgallery.common.AGApplicationJson;
039import ca.cdr.api.model.json.appgallery.console.AGConsoleJson;
040import ca.cdr.api.persistence.megascale.MegaScaleCredentialRequestJson;
041import ca.cdr.api.persistence.megascale.MegaScaleCredentialResponseJson;
042import ca.cdr.api.priorauth.PriorAuthCrdContextJson;
043import ca.cdr.api.pub.cdaexchange.model.CdaToFhirConversionResultJson;
044import ca.cdr.api.pub.hl7v2.model.Hl7v2ToFhirConversionResultJson;
045import ca.uhn.fhir.interceptor.api.IPointcut;
046import ca.uhn.fhir.rest.api.server.RequestDetails;
047import ca.uhn.fhir.rest.api.server.cdshooks.CdsServiceRequestJson;
048import ca.uhn.fhir.rest.server.interceptor.consent.IConsentService;
049import ca.uhn.fhir.rest.server.messaging.json.ResourceOperationJsonMessage;
050import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
051import ca.uhn.hl7v2.model.Message;
052import jakarta.annotation.Nonnull;
053import org.apache.commons.lang3.ArrayUtils;
054import org.apache.http.client.methods.HttpRequestBase;
055import org.hl7.fhir.instance.model.api.IBaseBundle;
056import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
057import org.hl7.fhir.instance.model.api.IBaseResource;
058
059import java.security.KeyStore;
060import java.util.Arrays;
061import java.util.Collections;
062import java.util.HashSet;
063import java.util.List;
064import java.util.Set;
065import java.util.stream.Collectors;
066
067/**
068 * Value for {@link CdrHook#value()}
069 * <p>
070 * Hook pointcuts are divided into several broad categories:
071 * <ul>
072 * <li>FHIRGW_xxx: Hooks on the FHIR Gateway module</li>
073 * </ul>
074 * </p>
075 */
076public enum CdrPointcut implements IPointcut {
077
078        /**
079         * <b>CDA pre-import Hook:</b>
080         * <p>This pointcut provides access to documents before they are imported via the $import-cda endpoint.</p>
081         * <p>Hooks may accept the following parameters:</p>
082         * <ul>
083         *    <li>{@link java.lang.String} - the document to be imported, in xml format.</li>
084         *    <li>{@link ca.cdr.api.pub.cdaexchange.model.CdaToFhirConversionResultJson} - object used to contain all
085         *    relevant data involved in the conversion of a CDA document to an IBaseBundle.</li>
086         * </ul>
087         * <p>Hooks should return the document after performing any modifications.</p>
088         */
089        CDA_PRE_IMPORT(String.class, String.class, CdaToFhirConversionResultJson.class),
090
091        /**
092         * <b>CDA post-import Hook:</b>
093         * <p>This pointcut provides access to documents after they are imported via the $import-cda endpoint.</p>
094         * <p>Hooks may accept the following parameters:</p>
095         * <ul>
096         *    <li>{@link IBaseOperationOutcome} - an operation outcome which can be used to track issues with the import.</li>
097         *    <li>{@link IBaseBundle} - the transaction bundle which can be modified by this Hook.</li>
098         *    <li>{@link java.lang.String} - the document that was imported, in xml format.</li>
099         *    <li>{@link ca.cdr.api.pub.cdaexchange.model.CdaToFhirConversionResultJson} - object used to contain all
100         *    relevant data involved in the conversion of a CDA document to an IBaseBundle.</li>
101         * </ul>
102         * <p>To modify the document before the {@link IBaseBundle} is generated, use the pre-import Hook instead.</p>
103         */
104        CDA_POST_IMPORT(
105                        void.class,
106                        IBaseOperationOutcome.class,
107                        IBaseBundle.class,
108                        String.class,
109                        CdaToFhirConversionResultJson.class),
110
111        /**
112         * <b>CDA post-export Hook:</b>
113         * <p>This pointcut provides access to documents after they are exported, and immediately
114         * before they are returned to the API client.</p>
115         * <p>Hooks may accept the following parameters:</p>
116         * <ul>
117         *    <li>{@link IBaseBundle} - the bundle associated with this export.</li>
118         *    <li>{@link java.lang.String} - the document being exported, in xml format.</li>
119         * </ul>
120         * <p>Hooks should return the document after performing any modifications. The resulting document
121         * is what will be returned to the API client.</p>
122         */
123        CDA_POST_EXPORT(String.class, IBaseBundle.class, String.class),
124
125        /**
126         * <b>Channel Import Hook:</b>
127         * The pointcut provides access to messages received on a broker queue.  It allows an interceptor to
128         * inspect, modify or mark for discard incoming messages before ingestion by the Channel Import module.
129         * <p>
130         * <p>
131         * Hooks may accept the following parameters:
132         * <ul>
133         * <li>
134         * {@link ResourceOperationJsonMessage} - Hook methods for this
135         * pointcut should take a single parameter of ResourceOperationJsonMessage as the input. This object
136         * contains the pre-processed channel import message.
137         * </li>
138         * </ul>
139         *
140         * </p>
141         * Hook methods must return a <code>Boolean</code> which indicates whether to process the message.
142         */
143        CHANNEL_IMPORT_MESSAGE_PRE_PROCESSED(Boolean.class, ResourceOperationJsonMessage.class),
144
145        /**
146         * <b>FHIR Gateway Hook:</b>
147         * This hook is called when the FHIR Gateway has just determined which routes should be invoked for
148         * a given FHIR <b>delete</b> operation. This hook is called once per client request, regardless of how many individual
149         * targets are eventually invoked against.
150         * <p>
151         * Hooks may accept the following parameters:
152         * <ul>
153         * <li>
154         * {@link ca.uhn.fhir.rest.server.servlet.ServletRequestDetails} - A bean containing details about the request that
155         * is about to be processed.
156         * </li>
157         * <li>
158         * {@link ca.cdr.api.fhirgw.model.DeleteRequest} - The delete that is about to be invoked. The hook method can modify this request, and modifications will affect all the operations that are performed against the target servers
159         * </li>
160         * <li>
161         * {@link ca.cdr.api.fhirgw.json.MatchedRoutesJson} - A collection of {@link ca.cdr.api.fhirgw.json.IBaseRouteJson} which have been selected for this request. Routes can be added or removed from this collection to affect which routes are invoked. They can be cast to their specific subclasses if necessary.
162         * </li>
163         * <li>
164         * {@link ca.cdr.api.fhirgw.json.AvailableRoutesJson} - A collection of {@link ca.cdr.api.fhirgw.json.IBaseRouteJson} which match the operation type of the request, e.g. read, create, delete, search, operation.
165         * </li>
166         * </ul>
167         * </p>
168         * Hook methods must return <code>void</code>.
169         *
170         */
171        FHIRGW_DELETE_POST_SELECT_ROUTE(
172                        void.class,
173                        ServletRequestDetails.class,
174                        DeleteRequest.class,
175                        MatchedRoutesJson.class,
176                        AvailableRoutesJson.class),
177
178        /**
179         * <b>FHIR Gateway Hook:</b>
180         * This hook is called when the FHIR Gateway has just determined which routes should be invoked for
181         * a given FHIR <b>update</b> operation. This hook is called once per client request, regardless of how many individual
182         * targets are eventually invoked against.
183         * <p>
184         * Hooks may accept the following parameters:
185         * <ul>
186         * <li>
187         * {@link ca.uhn.fhir.rest.server.servlet.ServletRequestDetails} - A bean containing details about the request that
188         * is about to be processed.
189         * </li>
190         * <li>
191         * {@link ca.cdr.api.fhirgw.model.UpdateRequest} - The update that is about to be invoked. The hook method can modify this request, and modifications will affect all the operations that are performed against the target servers
192         * </li>
193         * <li>
194         * {@link ca.cdr.api.fhirgw.json.MatchedRoutesJson} - A collection of {@link ca.cdr.api.fhirgw.json.IBaseRouteJson} which have been selected for this request. Routes can be added or removed from this collection to affect which routes are invoked. They can be cast to their specific subclasses if necessary.
195         * </li>
196         * <li>
197         * {@link ca.cdr.api.fhirgw.json.AvailableRoutesJson} - A collection of {@link ca.cdr.api.fhirgw.json.IBaseRouteJson} which match the operation type of the request, e.g. read, create, delete, search, operation.
198         * </li>
199         * </ul>
200         * </p>
201         * Hook methods must return <code>void</code>.
202         *
203         */
204        FHIRGW_UPDATE_POST_SELECT_ROUTE(
205                        void.class,
206                        ServletRequestDetails.class,
207                        UpdateRequest.class,
208                        MatchedRoutesJson.class,
209                        AvailableRoutesJson.class),
210
211        /**
212         * <b>FHIR Gateway Hook:</b>
213         * This hook is called when the FHIR Gateway has just determined which routes should be invoked for
214         * a given FHIR <b>operation</b> operation. This hook is called once per client request, regardless of how many individual
215         * targets are eventually invoked against.
216         * <p>
217         * Hooks may accept the following parameters:
218         * <ul>
219         * <li>
220         * {@link ca.uhn.fhir.rest.server.servlet.ServletRequestDetails} - A bean containing details about the request that
221         * is about to be processed.
222         * </li>
223         * <li>
224         * {@link ca.cdr.api.fhirgw.model.OperationRequest} - The operation that is about to be invoked. The hook method can modify this request, and modifications will affect all the operations that are performed against the target servers
225         * </li>
226         * <li>
227         * {@link ca.cdr.api.fhirgw.json.MatchedRoutesJson} - A collection of {@link ca.cdr.api.fhirgw.json.IBaseRouteJson} which have been selected for this request. Routes can be added or removed from this collection to affect which routes are invoked. They can be cast to their specific subclasses if necessary.
228         * </li>
229         * <li>
230         * {@link ca.cdr.api.fhirgw.json.AvailableRoutesJson} - A collection of {@link ca.cdr.api.fhirgw.json.IBaseRouteJson} which match the operation type of the request, e.g. read, create, delete, search, operation.
231         * </li>
232         * </ul>
233         * </p>
234         * Hook methods must return <code>void</code>.
235         *
236         */
237        FHIRGW_OPERATION_POST_SELECT_ROUTE(
238                        void.class,
239                        ServletRequestDetails.class,
240                        OperationRequest.class,
241                        MatchedRoutesJson.class,
242                        AvailableRoutesJson.class),
243
244        /**
245         * <b>FHIR Gateway Hook:</b>
246         * This hook is called when the FHIR Gateway has just determined which routes should be invoked for
247         * a given FHIR <b>search</b> operation. This hook is called once per client request, regardless of how many individual
248         * targets are eventually invoked against.
249         * <p>
250         * Hooks may accept the following parameters:
251         * <ul>
252         * <li>
253         * {@link ca.uhn.fhir.rest.server.servlet.ServletRequestDetails} - A bean containing details about the request that
254         * is about to be processed.
255         * </li>
256         * <li>
257         * {@link ca.cdr.api.fhirgw.model.SearchRequest} - The search that is about to be invoked. The hook method can modify this request, and modifications will affect all the operations that are performed against the target servers
258         * </li>
259         * <li>
260         * {@link ca.cdr.api.fhirgw.json.MatchedRoutesJson} - A collection of {@link ca.cdr.api.fhirgw.json.IBaseRouteJson} which have been selected for this request. Routes can be added or removed from this collection to affect which routes are invoked. They can be cast to their specific subclasses if necessary.
261         * </li>
262         * <li>
263         * {@link ca.cdr.api.fhirgw.json.AvailableRoutesJson} - A collection of {@link ca.cdr.api.fhirgw.json.IBaseRouteJson} which match the operation type of the request, e.g. read, create, delete, search, operation.
264         * </li>
265         * </ul>
266         * </p>
267         * Hook methods must return <code>void</code>.
268         *
269         */
270        FHIRGW_SEARCH_POST_SELECT_ROUTE(
271                        void.class,
272                        ServletRequestDetails.class,
273                        SearchRequest.class,
274                        MatchedRoutesJson.class,
275                        AvailableRoutesJson.class),
276
277        /**
278         * <b>FHIR Gateway Hook:</b>
279         * This hook is called when the FHIR Gateway has just determined which routes should be invoked for
280         * a given FHIR <b>create</b> operation. This hook is called once per client request, regardless of how many individual
281         * targets are eventually invoked against.
282         * <p>
283         * Hooks may accept the following parameters:
284         * <ul>
285         * <li>
286         * {@link ca.uhn.fhir.rest.server.servlet.ServletRequestDetails} - A bean containing details about the request that
287         * is about to be processed.
288         * </li>
289         * <li>
290         * {@link ca.cdr.api.fhirgw.model.CreateRequest} - The create that is about to be invoked. The hook method can modify this request, and modifications will affect all the operations that are performed against the target servers
291         * </li>
292         * <li>
293         * {@link ca.cdr.api.fhirgw.json.MatchedRoutesJson} - A collection of {@link ca.cdr.api.fhirgw.json.IBaseRouteJson} which have been selected for this request. Routes can be added or removed from this collection to affect which routes are invoked. They can be cast to their specific subclasses if necessary.
294         * </li>
295         * <li>
296         * {@link ca.cdr.api.fhirgw.json.AvailableRoutesJson} - A collection of {@link ca.cdr.api.fhirgw.json.IBaseRouteJson} which match the operation type of the request, e.g. read, create, delete, search, operation.
297         * </li>
298         * </ul>
299         * </p>
300         * Hook methods must return <code>void</code>.
301         *
302         */
303        FHIRGW_CREATE_POST_SELECT_ROUTE(
304                        void.class,
305                        ServletRequestDetails.class,
306                        CreateRequest.class,
307                        MatchedRoutesJson.class,
308                        AvailableRoutesJson.class),
309
310        /**
311         * <b>FHIR Gateway Hook:</b>
312         * This hook is called when the FHIR Gateway has just determined which routes should be invoked for
313         * a given FHIR <b>read</b> operation. This hook is called once per client request, regardless of how many individual
314         * targets are eventually invoked against.
315         * <p>
316         * Hooks may accept the following parameters:
317         * <ul>
318         * <li>
319         * {@link ca.uhn.fhir.rest.server.servlet.ServletRequestDetails} - A bean containing details about the request that
320         * is about to be processed.
321         * </li>
322         * <li>
323         * {@link ca.cdr.api.fhirgw.model.ReadRequest} - The read that is about to be invoked. The hook method can modify this request, and modifications will affect all the operations that are performed against the target servers
324         * </li>
325         * <li>
326         * {@link ca.cdr.api.fhirgw.json.MatchedRoutesJson} - A collection of {@link ca.cdr.api.fhirgw.json.IBaseRouteJson} which have been selected for this request. Routes can be added or removed from this collection to affect which routes are invoked. They can be cast to their specific subclasses if necessary.
327         * </li>
328         * <li>
329         * {@link ca.cdr.api.fhirgw.json.AvailableRoutesJson} - A collection of {@link ca.cdr.api.fhirgw.json.IBaseRouteJson} which match the operation type of the request, e.g. read, create, delete, search, operation.
330         * </li>
331         * </ul>
332         * </p>
333         * Hook methods must return <code>void</code>.
334         *
335         */
336        FHIRGW_READ_POST_SELECT_ROUTE(
337                        void.class,
338                        ServletRequestDetails.class,
339                        ReadRequest.class,
340                        MatchedRoutesJson.class,
341                        AvailableRoutesJson.class),
342
343        /**
344         * <b>FHIR Gateway Hook:</b>
345         * This hook is called when the FHIR Gateway has just determined which routes should be invoked for
346         * a given FHIR <b>transaction</b> operation. This hook is called once per client request, regardless of how many individual
347         * targets are eventually invoked against.
348         * <p>
349         * Hooks may accept the following parameters:
350         * <ul>
351         * <li>
352         * {@link ca.uhn.fhir.rest.server.servlet.ServletRequestDetails} - A bean containing details about the request that
353         * is about to be processed.
354         * </li>
355         * <li>
356         * {@link ca.cdr.api.fhirgw.model.TransactionRequest} - The transaction that is about to be invoked. The hook method can modify this request, and modifications will affect all the operations that are performed against the target servers.
357         * </li>
358         * <li>
359         * {@link ca.cdr.api.fhirgw.json.MatchedRoutesJson} - A collection of {@link ca.cdr.api.fhirgw.json.IBaseRouteJson} which have been selected for this request. Routes can be added or removed from this collection to affect which routes are invoked. They can be cast to their specific subclasses if necessary.
360         * </li>
361         * <li>
362         * {@link ca.cdr.api.fhirgw.json.AvailableRoutesJson} - A collection of {@link ca.cdr.api.fhirgw.json.IBaseRouteJson} which match the operation type of the request, e.g. read, create, delete, search, operation.
363         * </li>
364         * </ul>
365         * </p>
366         * Hook methods must return <code>void</code>.
367         *
368         */
369        FHIRGW_TRANSACTION_POST_SELECT_ROUTE(
370                        void.class,
371                        ServletRequestDetails.class,
372                        TransactionRequest.class,
373                        MatchedRoutesJson.class,
374                        AvailableRoutesJson.class),
375
376        /**
377         * <b>FHIR Gateway Hook:</b>
378         * This hook is called when the FHIR Gateway is about to invoke a FHIR <b>read</b> or <b>vread</b> operation against an individual
379         * target server. This hook is called once for each target that will be called, so if a single client read is being
380         * multicasted against two target servers, this hook will be invoked twice.
381         * <p>
382         * Hooks may accept the following parameters:
383         * <ul>
384         * <li>
385         * {@link ca.cdr.api.fhirgw.model.ReadRequest} - The read that is about to be invoked. The hook method can modify this request, and modifications will affect the operation that is actually performed against the target server.
386         * </li>
387         * <li>
388         * {@link ca.cdr.api.fhirgw.json.GatewayTargetJson} - The gateway target server definition. Hook methods should not modify this object, and any changes will be ignored.
389         * </li>
390         * <li>
391         * {@link ca.uhn.fhir.rest.server.servlet.ServletRequestDetails} - A bean containing details about the request that
392         * is about to be processed.
393         * </li>
394         * </ul>
395         * </p>
396         * Hook methods must return <code>void</code>.
397         */
398        FHIRGW_READ_TARGET_PREINVOKE(void.class, ReadRequest.class, GatewayTargetJson.class, ServletRequestDetails.class),
399
400        /**
401         * <b>FHIR Gateway Hook:</b>
402         * This hook is called when the FHIR Gateway is about to invoke a FHIR <b>instance history</b> operation against an individual
403         * target server. This hook is called once for each target that will be called, so if a single client instance history is being
404         * multicast against two target servers, this hook will be invoked twice.
405         * <p>
406         * Hooks may accept the following parameters:
407         * <ul>
408         * <li>
409         * {@link ca.cdr.api.fhirgw.model.HistoryRequest} - The instance history that is about to be invoked. The hook method can modify this request, and modifications will affect the operation that is actually performed against the target server.
410         * </li>
411         * <li>
412         * {@link ca.cdr.api.fhirgw.json.GatewayTargetJson} - The gateway target server definition. Hook methods should not modify this object, and any changes will be ignored.
413         * </li>
414         * <li>
415         * {@link ca.uhn.fhir.rest.server.servlet.ServletRequestDetails} - A bean containing details about the request that
416         * is about to be processed.
417         * </li>
418         * </ul>
419         * </p>
420         * Hook methods must return <code>void</code>.
421         */
422        FHIRGW_INSTANCE_HISTORY_TARGET_PREINVOKE(
423                        void.class, HistoryRequest.class, GatewayTargetJson.class, ServletRequestDetails.class),
424
425        /**
426         * <b>FHIR Gateway Hook:</b>
427         * This hook is called when the FHIR Gateway has just determined which routes should be invoked for
428         * a given FHIR <b>instance history</b> operation. This hook is called once per client request, regardless of how many individual
429         * targets are eventually invoked.
430         * <p>
431         * Hooks may accept the following parameters:
432         * <ul>
433         * <li>
434         * {@link ca.uhn.fhir.rest.server.servlet.ServletRequestDetails} - A bean containing details about the request that
435         * is about to be processed.
436         * </li>
437         * <li>
438         * {@link ca.cdr.api.fhirgw.model.HistoryRequest} - The transaction that is about to be invoked. The hook method can modify this request, and modifications will affect all the operations that are performed against the target servers.
439         * </li>
440         * <li>
441         * {@link ca.cdr.api.fhirgw.json.MatchedRoutesJson} - A collection of {@link ca.cdr.api.fhirgw.json.IBaseRouteJson} which have been selected for this request. Routes can be added or removed from this collection to affect which routes are invoked. They can be cast to their specific subclasses if necessary.
442         * </li>
443         * <li>
444         * {@link ca.cdr.api.fhirgw.json.AvailableRoutesJson} - A collection of {@link ca.cdr.api.fhirgw.json.IBaseRouteJson} which match the operation type of the request, e.g. read, create, delete, search, operation.
445         * </li>
446         * </ul>
447         * </p>
448         * Hook methods must return <code>void</code>.
449         *
450         */
451        FHIRGW_INSTANCE_HISTORY_POST_SELECT_ROUTE(
452                        void.class,
453                        ServletRequestDetails.class,
454                        HistoryRequest.class,
455                        MatchedRoutesJson.class,
456                        AvailableRoutesJson.class),
457
458        /**
459         * <b>FHIR Gateway Hook:</b>
460         * This hook is called when the FHIR Gateway is about to invoke a FHIR <b>operation</b> operation against an individual
461         * target server.
462         * <p>
463         * Hooks may accept the following parameters:
464         * <ul>
465         * <li>
466         * {@link ca.cdr.api.fhirgw.model.OperationRequest} - The read that is about to be invoked. The hook method can modify this request, and modifications will affect the operation that is actually performed against the target server.
467         * </li>
468         * <li>
469         * {@link ca.cdr.api.fhirgw.json.GatewayTargetJson} - The gateway target server definition. Hook methods should not modify this object, and any changes will be ignored.
470         * </li>
471         * <li>
472         * {@link ca.uhn.fhir.rest.server.servlet.ServletRequestDetails} - A bean containing details about the request that
473         * is about to be processed.
474         * </li>
475         * </ul>
476         * </p>
477         * Hook methods must return <code>void</code>.
478         */
479        FHIRGW_OPERATION_TARGET_PREINVOKE(
480                        void.class, OperationRequest.class, GatewayTargetJson.class, ServletRequestDetails.class),
481
482        /**
483         * <b>FHIR Gateway Hook:</b>
484         * This hook is called when the FHIR Gateway has finished invoking a FHIR <b>extended operation</b> operation against an individual
485         * target server. This hook is called once for each target that has been called, so if a single client operation is being
486         * multicasted against two target servers, this hook will be invoked twice.
487         * <p>
488         * <p>
489         * Hooks may accept the following parameters:
490         * <ul>
491         * <li>
492         * {@link ca.cdr.api.fhirgw.json.GatewayTargetJson} - The gateway target server definition. Hook methods should not modify this object, and any changes will be ignored.
493         * </li>
494         * <li>
495         * {@link ISearchResultsAccumulator} - The accumulator being used to collect the search results so far. This may be empty in the case of operations
496         * which do not return search results. Some operations, such as <b>$everything</b>, will return search results, but others such as <b>$</b>
497         * Hook methods may use this object to inspect results received by other endpoints when searching in serial mode, and can
498         * modify the results as needed. Note that the {@link #FHIRGW_SEARCH_TARGET_POSTINVOKE} pointcut is invoked once for each gateway
499         * target, <b>before</b> the search results are added to the accumulator. Results from the current target are found in the
500         * {@link SearchResponse} object, and will be moved from that object into the accumulator after this pointcut is complete.
501         * </li>
502         * <li>
503         * {@link ca.cdr.api.fhirgw.model.OperationResponse} - This object contains the Operation Response from the individual Gateway Target that was called. Interceptors may modify this object in any way they want. This may be null if the operation returns a Bundle (check the SearchResultsAccumulator instead).
504         * </li>
505         * </ul>
506         * </p>
507         * Hook methods must return <code>void</code>.
508         *
509         **/
510        FHIRGW_OPERATION_TARGET_POSTINVOKE(
511                        void.class,
512                        OperationRequest.class,
513                        ISearchResultsAccumulator.class,
514                        OperationResponse.class,
515                        GatewayTargetJson.class,
516                        ServletRequestDetails.class),
517
518        /**
519         * <b>FHIR Gateway Hook:</b>
520         * This hook is called when the FHIR Gateway is about to invoke a FHIR <b>search</b> operation against an individual
521         * target server. This hook is called once for each target that will be called, so if a single client search is being
522         * multicasted against two target servers, this hook will be invoked twice.
523         * <p>
524         * This hook can be contrasted with {@link #FHIRGW_SEARCH_PAGE_TARGET_PREINVOKE}:
525         * <ul>
526         *    <li>{@link #FHIRGW_SEARCH_TARGET_PREINVOKE} is called before the initial search is performed (which should return search results as well as paging links)</li>
527         *    <li>{@link #FHIRGW_SEARCH_PAGE_TARGET_PREINVOKE} is called before the subsequent pages of results are fetched</li>
528         * </ul>
529         * </p>
530         * <p>
531         * Hooks may accept the following parameters:
532         * <ul>
533         * <li>
534         * {@link ca.cdr.api.fhirgw.model.SearchRequest} - The search that is about to be invoked. The hook method can modify this request, and modifications will affect the operation that is actually performed against the target server.
535         * </li>
536         * <li>
537         * {@link ca.cdr.api.fhirgw.json.GatewayTargetJson} - The gateway target server definition. Hook methods should not modify this object, and any changes will be ignored.
538         * </li>
539         * <li>
540         * {@link ISearchResultsAccumulator} - The accumulator being used to collect the search results so far. Hook methods may use this object to inspect results recieved by other endpoints when searching in serial mode, and can modify the results as needed.
541         * </li>
542         * <li>
543         * {@link ca.uhn.fhir.rest.server.servlet.ServletRequestDetails} - A bean containing details about the request that
544         * is about to be processed.
545         * </li>
546         * </ul>
547         * </p>
548         * Hook methods must return <code>void</code>.
549         */
550        FHIRGW_SEARCH_TARGET_PREINVOKE(
551                        void.class,
552                        SearchRequest.class,
553                        GatewayTargetJson.class,
554                        ISearchResultsAccumulator.class,
555                        ServletRequestDetails.class),
556
557        /**
558         * <b>FHIR Gateway Hook:</b>
559         * This hook is called when the FHIR Gateway is about to invoke a FHIR <b>search</b> paging operation against an individual
560         * target server. This hook is called once for each target that will be called, so if a single client search is being
561         * multicasted against two target servers, this hook will be invoked twice.
562         * <p>
563         * This hook can be contrasted with {@link #FHIRGW_SEARCH_TARGET_PREINVOKE}:
564         * <ul>
565         *    <li>{@link #FHIRGW_SEARCH_TARGET_PREINVOKE} is called before the initial search is performed (which should return search results as well as paging links)</li>
566         *    <li>{@link #FHIRGW_SEARCH_PAGE_TARGET_PREINVOKE} is called before the subsequent pages of results are fetched</li>
567         * </ul>
568         * </p>
569         * <p>
570         * Hooks may accept the following parameters:
571         * <ul>
572         * <li>
573         * {@link ca.cdr.api.fhirgw.model.SearchPageRequest} - The search that is about to be invoked. The hook method can modify this request, and modifications will affect the operation that is actually performed against the target server.
574         * </li>
575         * <li>
576         * {@link ca.cdr.api.fhirgw.json.GatewayTargetJson} - The gateway target server definition. Hook methods should not modify this object, and any changes will be ignored.
577         * </li>
578         * <li>
579         * {@link ISearchResultsAccumulator} - The accumulator being used to collect the search results so far. Hook methods may use this object to inspect results received by other endpoints when searching in serial mode, and can modify the results as needed.
580         * </li>
581         * <li>
582         * {@link ca.uhn.fhir.rest.server.servlet.ServletRequestDetails} - A bean containing details about the request that
583         * is about to be processed.
584         * </li>
585         * </ul>
586         * </p>
587         * Hook methods must return <code>void</code>.
588         */
589        FHIRGW_SEARCH_PAGE_TARGET_PREINVOKE(
590                        void.class,
591                        SearchPageRequest.class,
592                        GatewayTargetJson.class,
593                        ISearchResultsAccumulator.class,
594                        ServletRequestDetails.class),
595
596        /**
597         * <b>FHIR Gateway Hook:</b>
598         * This hook is called when the FHIR Gateway has finished invoking a FHIR <b>search</b> operation against an individual
599         * target server. This hook is called once for each target that has been called, so if a single client search is being
600         * multicasted against two target servers, this hook will be invoked twice.
601         * <p>
602         * <p>
603         * Hooks may accept the following parameters:
604         * <ul>
605         * <li>
606         * {@link ca.cdr.api.fhirgw.json.GatewayTargetJson} - The gateway target server definition. Hook methods should not modify this object, and any changes will be ignored.
607         * </li>
608         * <li>
609         * {@link ISearchResultsAccumulator} - The accumulator being used to collect the search results so far.
610         * Hook methods may use this object to inspect results received by other endpoints when searching in serial mode, and can
611         * modify the results as needed. Note that the {@link #FHIRGW_SEARCH_TARGET_POSTINVOKE} pointcut is invoked once for each gateway
612         * target, <b>before</b> the search results are added to the accumulator. Results from the current target are found in the
613         * {@link SearchResponse} object, and will be moved from that object into the accumulator after this pointcut is complete.
614         * </li>
615         * <li>
616         * {@link ca.cdr.api.fhirgw.model.SearchResponse} - This object contains the search results from the individual Gateway Target that was called. Interceptors may modify this object in any way they want.
617         * </li>
618         * </ul>
619         * </p>
620         * Hook methods must return <code>void</code>.
621         */
622        FHIRGW_SEARCH_TARGET_POSTINVOKE(
623                        void.class,
624                        GatewayTargetJson.class,
625                        ISearchResultsAccumulator.class,
626                        SearchResponse.class,
627                        ServletRequestDetails.class),
628
629        /**
630         * <b>FHIR Gateway Hook:</b>
631         * This hook is called when the FHIR Gateway is about to invoke a FHIR <b>create</b> operation against an individual
632         * target server. This hook is called once for each target that will be called, so if a single client create is being
633         * multicasted against two target servers, this hook will be invoked twice.
634         * <p>
635         * For creates where a client id is specified, the <b>update</b> hook will be fired instead.
636         * </p>
637         * <p>
638         * Hooks may accept the following parameters:
639         * <ul>
640         * <li>
641         * {@link ca.cdr.api.fhirgw.model.CreateRequest} - The create that is about to be invoked. The hook method can modify this request, and modifications will affect the operation that is actually performed against the target server.
642         * </li>
643         * <li>
644         * {@link ca.cdr.api.fhirgw.json.GatewayTargetJson} - The gateway target server definition. Hook methods should not modify this object, and any changes will be ignored.
645         * </li>
646         * <li>
647         * {@link ca.uhn.fhir.rest.server.servlet.ServletRequestDetails} - A bean containing details about the request that
648         * is about to be processed.
649         * </li>
650         * </ul>
651         * </p>
652         * Hook methods must return <code>void</code>.
653         */
654        FHIRGW_CREATE_TARGET_PREINVOKE(
655                        void.class, CreateRequest.class, GatewayTargetJson.class, ServletRequestDetails.class),
656
657        /**
658         * <b>FHIR Gateway Hook:</b>
659         * This hook is called when the FHIR Gateway is about to invoke a FHIR <b>transaction</b> operation against an individual
660         * target server. This hook is called once for each target that will be called, so if a single client create is being
661         * multicasted against two target servers, this hook will be invoked twice.
662         * <p>
663         * For creates where a client id is specified, the <b>update</b> hook will be fired instead.
664         * </p>
665         * <p>
666         * Hooks may accept the following parameters:
667         * <ul>
668         * <li>
669         * {@link ca.cdr.api.fhirgw.model.TransactionRequest} - The transaction that is about to be invoked. The hook method can modify this request, and modifications will affect the operation that is actually performed against the target server.
670         * </li>
671         * <li>
672         * {@link ca.cdr.api.fhirgw.json.GatewayTargetJson} - The gateway target server definition. Hook methods should not modify this object, and any changes will be ignored.
673         * </li>
674         * <li>
675         * {@link ca.uhn.fhir.rest.server.servlet.ServletRequestDetails} - A bean containing details about the request that
676         * is about to be processed.
677         * </li>
678         * </ul>
679         * </p>
680         * Hook methods must return <code>void</code>.
681         */
682        FHIRGW_TRANSACTION_TARGET_PREINVOKE(
683                        void.class, TransactionRequest.class, GatewayTargetJson.class, ServletRequestDetails.class),
684
685        /**
686         * <b>FHIR Gateway Hook:</b>
687         * This hook is called when the FHIR Gateway is about to invoke a FHIR <b>update</b> operation against an individual
688         * target server. This hook is called once for each target that will be called, so if a single client update is being
689         * multicasted against two target servers, this hook will be invoked twice.
690         * <p>
691         * This hook will also be called for <b>create</b> operations when a client id is provided.
692         * </p>
693         * <p>
694         * Hooks may accept the following parameters:
695         * <ul>
696         * <li>
697         * {@link ca.cdr.api.fhirgw.model.UpdateRequest} - The update that is about to be invoked. The hook method can modify this request, and modifications will affect the operation that is actually performed against the target server.
698         * </li>
699         * <li>
700         * {@link ca.cdr.api.fhirgw.json.GatewayTargetJson} - The gateway target server definition. Hook methods should not modify this object, and any changes will be ignored.
701         * </li>
702         * <li>
703         * {@link ca.uhn.fhir.rest.server.servlet.ServletRequestDetails} - A bean containing details about the request that
704         * is about to be processed.
705         * </li>
706         * </ul>
707         * </p>
708         * Hook methods must return <code>void</code>.
709         */
710        FHIRGW_UPDATE_TARGET_PREINVOKE(
711                        void.class, UpdateRequest.class, GatewayTargetJson.class, ServletRequestDetails.class),
712
713        /**
714         * <b>FHIR Gateway Hook:</b>
715         * This hook is called when the FHIR Gateway is about to invoke a FHIR <b>delete</b> operation against an individual
716         * target server. This hook is called once for each target that will be called, so if a single client delete is being
717         * multicasted against two target servers, this hook will be invoked twice.
718         * <p>
719         * Hooks may accept the following parameters:
720         * <ul>
721         * <li>
722         * {@link ca.cdr.api.fhirgw.model.DeleteRequest} - The delete that is about to be invoked. The hook method can modify this request, and modifications will affect the operation that is actually performed against the target server.
723         * </li>
724         * <li>
725         * {@link ca.cdr.api.fhirgw.json.GatewayTargetJson} - The gateway target server definition. Hook methods should not modify this object, and any changes will be ignored.
726         * </li>
727         * <li>
728         * {@link ca.uhn.fhir.rest.server.servlet.ServletRequestDetails} - A bean containing details about the request that
729         * is about to be processed.
730         * </li>
731         * </ul>
732         * </p>
733         * Hook methods must return <code>void</code>.
734         */
735        FHIRGW_DELETE_TARGET_PREINVOKE(
736                        void.class, DeleteRequest.class, GatewayTargetJson.class, ServletRequestDetails.class),
737
738        /**
739         * <b>HL7v2 Hook:</b>
740         * This hook is the first one called when a HL7v2 endpoint processes incoming messages.  It is invoked before
741         * the HL7v2 to FHIR mapping takes place for each incoming request. It may be used to provide
742         * alternate handling for some requests, screen requests before they are handled, alter the incoming message,etc.
743         * <p>
744         * Note that any exceptions thrown by this method will not be trapped by HAPI (they will be passed up to the server)
745         * </p>
746         * <p>
747         * Hooks may accept the following parameters:
748         * <ul>
749         * <li>
750         * {@link ca.uhn.hl7v2.model.Message} - the message that is about to be processed. The hook method can modify this
751         * message and modifications will affect the end result of processing the message by this server.
752         * <br/>
753         * <b>NOTE:</b> This parameter is deprecated. Use {@link Hl7v2ToFhirConversionResultJson#getModifiableMessage()}
754         * or {@link Hl7v2ToFhirConversionResultJson#setModifiableMessage(Message)} instead.
755         * </li>
756         * <li>
757         * {@link Hl7v2ToFhirConversionResultJson} - Contains all relevant data involved in the conversion of an HL7 v2.x
758         * message to a list of IBaseBundle resources.
759         * </li>
760         * </ul>
761         * </p>
762         * Hook methods may return <code>true</code> or <code>void</code> if processing should continue normally.
763         * This is generally the right thing to do. If your interceptor is processing the response rather than
764         * letting HAPI do it, you must return <code>false</code>. In this case,
765         * no further processing will occur.
766         */
767        HL7V2IN_PRE_HL7V2_TO_FHIR_MAPPING_PROCESSING(
768                        Boolean.class, "ca.uhn.hl7v2.model.Message", "ca.cdr.api.pub.hl7v2.model.Hl7v2ToFhirConversionResultJson"),
769
770        /**
771         * <b>HL7v2 Hook:</b>
772         * This hook is invoked after Smile has transformed an HL7V2 message into a collection of Transaction Bundle operations.
773         * <p>
774         * Note that any exceptions thrown by this method will not be trapped by HAPI (they will be passed up to the server)
775         * </p>
776         * <p>
777         * Hooks may accept the following parameters:
778         * <ul>
779         * <li>
780         * {@link ConvertedTransactionBundlesJson} - Contains a list of IBaseBundle objects, each of which represents a transaction about to be executed
781         * against the FHIR repository. Any modifications to this bundle, or additions to it, will be propagated into the repository.
782         * <br/>
783         * <b>NOTE:</b> This parameter is deprecated. Use {@link Hl7v2ToFhirConversionResultJson#getBundles()}
784         * or {@link Hl7v2ToFhirConversionResultJson#setBundles(List)} instead.
785         * </li>
786         * <li>
787         * {@link ca.uhn.hl7v2.model.Message} - the message that was just processed. Any changes to this message will be ignored,
788         * as it has already been processed.
789         * <br/>
790         * <b>NOTE:</b> This parameter is deprecated. Use {@link Hl7v2ToFhirConversionResultJson#getModifiableMessage()}
791         * or {@link Hl7v2ToFhirConversionResultJson#setModifiableMessage(Message)} instead.
792         * </li>
793         * <li>
794         * {@link Hl7v2ToFhirConversionResultJson} - Contains all relevant data involved in the conversion of an HL7 v2.x
795         * message to a list of IBaseBundle resources.
796         * </li>
797         * </ul>
798         * </p>
799         */
800        HL7V2IN_POST_HL7V2_TO_FHIR_MAPPING_PROCESSING(
801                        void.class,
802                        "ca.uhn.hl7v2.model.Message",
803                        "ca.cdr.api.model.json.ConvertedTransactionBundlesJson",
804                        "ca.cdr.api.pub.hl7v2.model.Hl7v2ToFhirConversionResultJson"),
805
806        /**
807         * <b>Persistence (RDBMS) Hook:</b>
808         * This pointcut is invoked once by the Persistence (RDBMS) module when
809         * the module is starting up.
810         *
811         * <p>
812         * Hooks may accept the following parameters:
813         * <ul>
814         * <li>
815         * No parameters.
816         * </li>
817         * </ul>
818         * </p>
819         * Hook methods should not return a value.
820         *
821         * @since 2025.05.R01
822         */
823        STORAGE_STARTING_PRE_START(void.class),
824
825        /**
826         * <b>Persistence (RDBMS) Hook:</b>
827         * This pointcut is invoked my the Persistence (RDBMS) module when
828         * running in MegaScale mode in order to request the database credentials
829         * associated with a given partition ID.
830         * <p>
831         * Hooks may accept the following parameters:
832         * <ul>
833         * <li>
834         * {@link MegaScaleCredentialRequestJson} - Hook methods for this
835         * pointcut should take a {@link MegaScaleCredentialRequestJson}
836         * as input. This object contains the numeric ID of the partition
837         * for which database credentials are wanted.
838         * </li>
839         * </ul>
840         * </p>
841         *
842         * Hook methods for this pointcut must return a
843         * {@link MegaScaleCredentialResponseJson} object which contains the
844         * JDBC URL and credentials associated with the partition ID. These
845         * credentials will be cached, so this Pointcut will not be invoked
846         * repeatedly for the same partition ID (therefore it is ok if hook
847         * methods have some latency).
848         *
849         * @since 2023.02.R01
850         */
851        STORAGE_MEGASCALE_PROVIDE_DB_INFO(MegaScaleCredentialResponseJson.class, MegaScaleCredentialRequestJson.class),
852
853        /**
854         * <b>Server Endpoint Hook:</b>
855         * The pointcut provides the capability to supply a provisioned KeyStore file for TLS base encryption.
856         * Note that pointcut {@link #SERVER_CONFIGURATION_KEYSTORE} is invoked only if the endpoint listener
857         * is said to required TLS encryption for incoming connections through environment property <b>tls.enabled</b>
858         * <p>
859         * <p>
860         * Hooks may accept the following parameters:
861         * <ul>
862         * <li>
863         * {@link java.lang.String} - The keystore password
864         * </li>
865         * </ul>
866         * </p>
867         * <p>
868         * Interceptors for this pointcut must be registered with the specific
869         * endpoint module where the keystore will be used.
870         * </p>
871         * Hook methods must return <code>KeyStore</code>.
872         */
873        SERVER_CONFIGURATION_KEYSTORE(KeyStore.class, String.class),
874
875        /**
876         * <b>SMART/OIDC Hook:</b>
877         * The pointcut is called when a SMART Outbound Security module is configured in
878         * federated mode, and there are multiple federated providers configured, prior to
879         * the user being asked to select a provider. This pointcut can be used to
880         * programmatically select a provider instead of relying on the user to
881         * make a selection.
882         * <p>
883         * Hooks may accept the following parameters:
884         * <ul>
885         * <li>
886         * {@literal ca.cdr.api.fhir.interceptor.OidcAuthRequestDetails} - This object contains details about the auth request and can be used to extract request parameter values.
887         * </li>
888         * </ul>
889         * </p>
890         * Hook methods may return a {@link String}, which should be the Registration ID of an
891         * OpenID Connect Server definition (i.e. the value of the "Registration ID" field in the
892         * Smile CDR OIDC Server definition page). If the returned String is not {@literal null} and
893         * does not match any server definition, the flow will be halted and the user will
894         * see an error. If the returned string is {@literal null}, the user will be
895         * redirected to a server selection screen.
896         */
897        SMART_FEDERATED_OIDC_PRE_PROVIDER_SELECTION(String.class, OidcAuthRequestDetails.class),
898
899        /**
900         * <b>SMART/OIDC Hook:</b>
901         * The pointcut is called when an OIDC client is being saved. This could
902         * mean that a new client is being created, or an existing client
903         * is being updated or disabled.
904         * <p>
905         * This hook is called after the database transaction used to
906         * save the object has been committed. This means that the record already
907         * appears in the database. Any exceptions thrown by hooks for this
908         * pointcut may cause an error to appear for the user requesting the
909         * operation, but will not affect what has been saved in the database,
910         * so no exceptions should be thrown within this pointcut.
911         * </p>
912         * <p>
913         * Hooks may accept the following parameters:
914         * <ul>
915         * <li>
916         * {@link ca.cdr.api.model.json.IOAuth2ClientDetails} - The Client being saved. Pointcuts should not modify this object.
917         * </li>
918         * </ul>
919         * </p>
920         * Hook methods must return <code>void</code>.
921         */
922        SMART_OIDC_CLIENT_SAVED(void.class, IOAuth2ClientDetails.class),
923
924        /**
925         * <b>SMART/OIDC Hook:</b>
926         * The pointcut is called when an OIDC client is being saved. This could
927         * mean that a new client is being created, or an existing client
928         * is being updated or disabled.
929         * <p>
930         * This hook is called within the open database transaction used to
931         * save the object. This means that at the time this pointcut is invoked,
932         * the record does not yet appear in the database. It also means that any
933         * exception thrown by this pointcut will block the operation.
934         * </p>
935         * <p>
936         * Hooks may accept the following parameters:
937         * <ul>
938         * <li>
939         * {@link ca.cdr.api.model.json.IOAuth2ClientDetails} - The Client being saved. Pointcuts should not modify this object.
940         * </li>
941         * </ul>
942         * </p>
943         * Hook methods must return <code>void</code>.
944         */
945        SMART_OIDC_CLIENT_SAVING(void.class, IOAuth2ClientDetails.class),
946
947        /**
948         * <b>appSphere Hook:</b>
949         * The Pointcut is called when an appSphere admin updates the status of an application or service
950         * <p>
951         * This hook is called within the open database transaction used to
952         * save the object. This means that at the time this pointcut is invoked,
953         * the record does not yet appear in the database. It also means that any
954         * exception thrown by this pointcut will block the operation.
955         * </p>
956         * <p>
957         * Hooks may accept the following parameters:
958         * <ul>
959         * <li>
960         * {@link AGConsoleJson} - The application or service being updated. Pointcuts should not modify this object.
961         * </li>
962         * </ul>
963         * </p>
964         * Hook methods must return <code>void</code>.
965         */
966        AG_APPLICATION_STATUS_UPDATING(void.class, AGConsoleJson.class),
967
968        /**
969         * <b>appSphere Hook:</b>
970         * The pointcut is called after an appSphere admin updates the status of an application or service
971         * <p>
972         * This hook is called after the database transaction used to
973         * save the object has been committed. This means that the record already
974         * appears in the database. Any exceptions thrown by hooks for this
975         * pointcut may cause an error to appear for the user requesting the
976         * operation, but will not affect what has been saved in the database,
977         * so no exceptions should be thrown within this pointcut.
978         * </p>
979         * <p>
980         * Hooks may accept the following parameters:
981         * <ul>
982         * <li>
983         * {@link AGConsoleJson} - The application or service that was updated. Pointcuts should not modify this object.
984         * </li>
985         * </ul>
986         * </p>
987         * Hook methods must return <code>void</code>.
988         */
989        AG_APPLICATION_STATUS_UPDATED(void.class, AGConsoleJson.class),
990
991        /**
992         * <b>appSphere Hook:</b>
993         * The Pointcut is called when an appSphere developer registers an application, prior to commiting the registration to the database
994         * <p>
995         * This hook is called within the open database transaction used to
996         * save the object. This means that at the time this pointcut is invoked,
997         * the record does not yet appear in the database. It also means that any
998         * exception thrown by this pointcut will block the operation.
999         * </p>
1000         * <p>
1001         * Hooks may accept the following parameters:
1002         * <ul>
1003         * <li>
1004         * {@link AGApplicationJson} - The application or service being registered. Pointcuts can modify this object.
1005         * </li>
1006         * </ul>
1007         * </p>
1008         * Hook methods must return <code>void</code>.
1009         */
1010        AG_APPLICATION_REGISTER(void.class, AGApplicationJson.class),
1011
1012        /**
1013         * <b>appSphere Hook:</b>
1014         * The Pointcut is called when an appSphere developer re-registers an application, prior to commiting the registration to the database
1015         * <p>
1016         * This hook is called within the open database transaction used to
1017         * save the object. This means that at the time this pointcut is invoked,
1018         * the record does not yet appear in the database. It also means that any
1019         * exception thrown by this pointcut will block the operation.
1020         * </p>
1021         * <p>
1022         * Hooks may accept the following parameters:
1023         * <ul>
1024         * <li>
1025         * {@link AGApplicationJson} - The application or service being re-registered. Pointcuts can modify this object.
1026         * </li>
1027         * </ul>
1028         * </p>
1029         * Hook methods must return <code>void</code>.
1030         */
1031        AG_APPLICATION_RE_REGISTER(void.class, AGApplicationJson.class),
1032
1033        /**
1034         * <b>System-to-System Data Exchange Hook:</b>
1035         * This pointcut is called when doing resource matching in the $member-match operation. It provides the ability for
1036         * clients to execute custom matching JavaScript for the patient matching in $member-match.
1037         * <p>
1038         * Hooks may accept the following parameters:
1039         * <ul>
1040         * <li>
1041         * {@link ca.cdr.api.fhir.interceptor.IMemberMatchRequest} - the wrapper request object that contains memberPatient
1042         * and CoverageToMatch Resources.
1043         * </li>
1044         * <li>
1045         * {@link ca.uhn.fhir.rest.api.server.RequestDetails} - A bean containing details about the request that is about to
1046         * be processed.
1047         * </li>
1048         * </ul>
1049         * </p>
1050         * Hook methods may return <code>Patient</code> if a matching patient is found, or <code>void</code> otherwise.
1051         * Note that if <code>void</code> is returned, then the system will perform the default matching algorithm to try to
1052         * find any matching patient.
1053         */
1054        MEMBER_MATCH(IBaseResource.class, IMemberMatchRequest.class, RequestDetails.class),
1055
1056        /**
1057         * <b>Consent Module Hook:</b>
1058         * <p>This pointcut can be used by customers to add a new implementation of a Consent resource policy.
1059         * This policy will be used if it is specified in the <code>consentResourcePolicy</code> property of a consent rule.</p>
1060         * <p>Parameters:</p>
1061         * <ul>
1062         * <li>
1063         * {@link String} The policy name of the IConsentService that will be built. This will come from the <code>consentResourcePolicy</code>
1064         *      property of a <code>consentRule</code>.
1065         * </li>
1066         * <li>
1067         * {@link IBaseResource} The Consent resource to use to build the IConsentService.
1068         * </li>
1069         * <li>
1070         * {@link UserSessionDetailsJson} The user session details
1071         * </li>
1072         * </ul>
1073         * <p>Return Value:</p>
1074         * <ul><li>{@link IConsentService} The consent service that should be built from the provided policy name.
1075         * If an <code>IConsentService</code> cannot be mapped to the provided policy, null should be returned.</li></ul>
1076         */
1077        CONSENT_BUILD_CONSENT_RESOURCE_POLICY_CONSENT_SERVICE(
1078                        IConsentService.class, String.class, IBaseResource.class, UserSessionDetailsJson.class),
1079
1080        /**
1081         * <b>Consent Module Hook:</b>
1082         * <p>This pointcut can be used by customers to add a new implementation of a fixed consent policy.
1083         * This policy will be used if it is specified in the <code>fixedPolicy</code> property of a consent rule.
1084         * Unlike a <code>consentResourcePolicy</code>, a <code>fixedPolicy</code> is not dependent on Consent resource.
1085         * A <code>fixedPolicy</code> can be used to make consent decisions based on the user that is requesting to access a resource.</p>
1086         * <p>Parameters:</p>
1087         * <ul>
1088         * <li>
1089         * {@link ConsentFixedPolicyRequest} The fixed policy request containing the policy name and a list of parameters. The
1090         * policy name is the name of the <code>IConsentService</code> that will be built. This will come from the <code>fixedPolicy</code>
1091         * property of a <code>consentRule</code>.
1092         * </li>
1093         * <li>
1094         * {@link UserSessionDetailsJson} The user session details
1095         * </li>
1096         * </ul>
1097         * <p>Return Value:</p>
1098         * <ul><li>{@link IConsentService} The consent service that should be built from the provided policy name.
1099         * If an <code>IConsentService</code> cannot be mapped to the provided policy, null should be returned.</li></ul>
1100         */
1101        CONSENT_BUILD_FIXED_POLICY_CONSENT_SERVICE(
1102                        IConsentService.class, ConsentFixedPolicyRequest.class, UserSessionDetailsJson.class),
1103
1104        /**
1105         * <b>Consent Hook:</b>
1106         * This pointcut can be used by customers to customize the default behavior of the Consent resource-based
1107         * Consent Service.
1108         * Add the string representation of the (initial) queries that should be used to fetch consent resources to the {@link ConsentFetchQueries} object.
1109         * Implementers can use the {@link RequestDetails}, {@link ConsentLookupContext}, {@link IBaseResource}, and {@link UserSessionDetailsJson}
1110         * to determine the applicable queries.
1111         * <br/><br/>
1112         * <b>Note:</b> At least one of the CONSENT_FETCH_QUERIES or CONSENT_ACTIVE_CONSENT_RESOURCES_RESOLVE pointcuts must be implemented. Both pointcuts may also be implemented.
1113         * <p>
1114         * The hook can have the following parameters:
1115         * <ul>
1116         * <li>
1117         * {@link ConsentFetchQueries} the object that consent fetch queries should be added to.
1118         * </li>
1119         * <li>
1120         * {@link RequestDetails} the request
1121         * </li>
1122         * <li>
1123         * {@link ConsentLookupContext} the consent context object
1124         * </li>
1125         * <li>
1126         * {@link IBaseResource} the current clinical resource being evaluated for consent.  Will be present for willSeeResource and canSeeResource, but null for startOperation.
1127         * </li>
1128         * <li>
1129         * {@link UserSessionDetailsJson} the user session details.
1130         * </li>
1131         * </ul>
1132         * </p>
1133         * Hook methods need to add string representations of the consent queries to the {@link ConsentFetchQueries} object. This should
1134         * consist of one query to have a better performance, but in rare cases multiple queries can be provided.
1135         */
1136        CONSENT_FETCH_QUERIES(
1137                        void.class,
1138                        ConsentFetchQueries.class,
1139                        RequestDetails.class,
1140                        ConsentLookupContext.class,
1141                        IBaseResource.class,
1142                        UserSessionDetailsJson.class),
1143
1144        /**
1145         * <b>Consent Hook:</b> This pointcut can be used by customers to customize the default behavior of the Consent resource-based
1146         * Consent Service.
1147         * Add the Consent resources that should be used for the incoming request to the {@link ConsentActiveResourceResolutionRequest} object.
1148         * Implementers can use the {@link RequestDetails}, {@link ConsentLookupContext}, {@link IBaseResource}, and {@link UserSessionDetailsJson}
1149         * to determine the applicable consents.
1150         * <br/><br/>
1151         * <b>Note:</b> At least one of the CONSENT_ACTIVE_CONSENT_RESOURCES_RESOLVE or CONSENT_FETCH_QUERIES pointcuts must be implemented. Both pointcuts may also be implemented.
1152         * <p>
1153         * The hook can have the following parameters:
1154         * <ul>
1155         * <li>
1156         * {@link ConsentActiveResourceResolutionRequest} the object Consent resources should be added to
1157         * </li>
1158         * <li>
1159         * {@link RequestDetails} the request
1160         * </li>
1161         * <li>
1162         * {@link ConsentLookupContext} the consent context object
1163         * </li>
1164         * <li>
1165         * {@link IBaseResource} the current clinical resource being evaluated for consent.  Will be present for willSeeResource and canSeeResource, but null for startOperation.
1166         * </li>
1167         * <li>
1168         * {@link UserSessionDetailsJson} the user session details.
1169         * </li>
1170         * </ul>
1171         * </p>
1172         */
1173        CONSENT_ACTIVE_CONSENT_RESOURCES_RESOLVE(
1174                        void.class,
1175                        ConsentActiveResourceResolutionRequest.class,
1176                        RequestDetails.class,
1177                        ConsentLookupContext.class,
1178                        IBaseResource.class,
1179                        UserSessionDetailsJson.class),
1180
1181        /**
1182         * <b>Prior Auth CRD Gather context hook:</b>
1183         * This pointcut can be used by customers to customize the default behavior of the Prior Auth CRD
1184         * for determining patientId in Coverage context.
1185         * <p>
1186         * The hook can have the following parameters:
1187         * <ul>
1188         * <li>
1189         * {@link CdsServiceRequestJson} the CdsServiceRequestJson from the hook request
1190         * </li>
1191         * <li>
1192         * {@link PriorAuthCrdContextJson} the PriorAuthCrdContextJson to return result i.e. patientId
1193         * </li>
1194         * </ul>
1195         * </p>
1196         * Hook methods must return <code>void</code>.
1197         */
1198        PRIOR_AUTH_CRD_GATHER_CONTEXT(void.class, CdsServiceRequestJson.class, PriorAuthCrdContextJson.class),
1199
1200        /**
1201         * <b>Audit Event Pre Persist Hook:</b>
1202         * The pointcut is invoked right before an audit event is handed off to the persistence layer.
1203         * <p>
1204         * This hook is used to select key/value pairs that should be marshalled into a JSON string and saved as
1205         * additional user information with the audit event.
1206         * </p>
1207         *
1208         * <p>
1209         * The hook will have the following parameters:
1210         * <ul>
1211         * <li>
1212         * {@link AuditEventJson} the audit event that will be persisted. It is provided for reference only as any modification
1213         * to the object will be ignored.
1214         * </li>
1215         * <li>
1216         * {@link UserSessionDetailsJson} if present, the object capturing the details pertaining to the user whose actions lead
1217         * to the audit event which is about to be persisted.
1218         * </li>
1219         * <li>
1220         * {@link OAuth2ClientDetailsJson} if present, the object capturing the details pertaining to the Oauth2 client whose actions lead
1221         * to the audit event which is about to be persisted.
1222         * </li>
1223         * <li>
1224         * {@link AuditEventPrePersistJson} the parameter object accumulating key/value pairs the client wishes to see
1225         * added as additional information persisted with the audit event.
1226         * </li>
1227         * </ul>
1228         * </p>
1229         */
1230        AUDIT_EVENT_PRE_PERSIST(
1231                        void.class,
1232                        "ca.cdr.api.model.json.AuditEventJson",
1233                        "ca.cdr.api.model.json.UserSessionDetailsJson",
1234                        "ca.cdr.api.model.json.OAuth2ClientDetailsJson",
1235                        "ca.cdr.api.model.json.AuditEventPrePersistJson"),
1236
1237        /**
1238         * <b>Client Auth Pre Token Hook:</b>
1239         * The pointcut is invoked right before making the auth token call before member-match and batch-export call. If the
1240         * token needs to be different than the default client-secret, an OpenIdTokenResponse needs to be returned. The
1241         * token returned must not be null if the the execution is to continue.
1242         *
1243         * <p>
1244         * The hook will have the following parameters:
1245         * <ul>
1246         * <li>
1247         * {@link HttpRequestBase} the oauth token request to be executed.
1248         * </li>
1249         * </ul>
1250         * </p>
1251         */
1252        CLIENT_AUTH_PRE_TOKEN_REQUEST(OpenIdTokenResponse.class, HttpRequestBase.class);
1253
1254        private final List<String> myParameterTypes;
1255        private final Class<?> myReturnType;
1256        private final ExceptionHandlingSpec myExceptionHandlingSpec;
1257
1258        CdrPointcut(
1259                        @Nonnull Class<?> theReturnType,
1260                        @Nonnull ExceptionHandlingSpec theExceptionHandlingSpec,
1261                        String... theParameterTypes) {
1262
1263                // This class uses capital-B Boolean for the boolean return type
1264                assert !theReturnType.equals(boolean.class);
1265
1266                myReturnType = theReturnType;
1267                myExceptionHandlingSpec = theExceptionHandlingSpec;
1268                myParameterTypes = Collections.unmodifiableList(Arrays.asList(theParameterTypes));
1269        }
1270
1271        CdrPointcut(@Nonnull Class<?> theReturnType, String... theParameterTypes) {
1272                this(theReturnType, new ExceptionHandlingSpec(), theParameterTypes);
1273        }
1274
1275        CdrPointcut(@Nonnull Class<?> theReturnType, Class<?>... theParameterTypes) {
1276                this(theReturnType, new ExceptionHandlingSpec(), toNames(theParameterTypes));
1277        }
1278
1279        CdrPointcut(@Nonnull Class<?> theReturnType) {
1280                this(theReturnType, new ExceptionHandlingSpec(), ArrayUtils.EMPTY_STRING_ARRAY);
1281        }
1282
1283        CdrPointcut(@Nonnull Class<?> theReturnType, Class<?> theParameterTypes) {
1284                this(theReturnType, new ExceptionHandlingSpec(), theParameterTypes.getName());
1285        }
1286
1287        private static String[] toNames(Class<?>[] theParameterTypes) {
1288                return Arrays.stream(theParameterTypes)
1289                                .map(Class::getName)
1290                                .collect(Collectors.toList())
1291                                .toArray(new String[0]);
1292        }
1293
1294        @Override
1295        public boolean isShouldLogAndSwallowException(@Nonnull Throwable theException) {
1296                for (Class<? extends Throwable> next : myExceptionHandlingSpec.myTypesToLogAndSwallow) {
1297                        if (next.isAssignableFrom(theException.getClass())) {
1298                                return true;
1299                        }
1300                }
1301                return false;
1302        }
1303
1304        @Override
1305        @Nonnull
1306        public Class<?> getReturnType() {
1307                return myReturnType;
1308        }
1309
1310        @Override
1311        public Class<?> getBooleanReturnTypeForEnum() {
1312                return Boolean.class;
1313        }
1314
1315        @Override
1316        @Nonnull
1317        public List<String> getParameterTypes() {
1318                return myParameterTypes;
1319        }
1320
1321        private static class ExceptionHandlingSpec {
1322
1323                private final Set<Class<? extends Throwable>> myTypesToLogAndSwallow = new HashSet<>();
1324
1325                ExceptionHandlingSpec addLogAndSwallow(@Nonnull Class<? extends Throwable> theType) {
1326                        myTypesToLogAndSwallow.add(theType);
1327                        return this;
1328                }
1329        }
1330}