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