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