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