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