Add validation suppression mode (#2675)
* Add validation suppression mode * Add changelog * Compile fix
This commit is contained in:
parent
af44b9c7a0
commit
7a83c76e65
|
@ -25,6 +25,7 @@ import ca.uhn.fhir.rest.annotation.Read;
|
|||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.server.exceptions.AuthenticationException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||
import ca.uhn.fhir.validation.ValidationResult;
|
||||
import org.hl7.fhir.instance.model.api.IBaseConformance;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
@ -45,6 +46,7 @@ import java.util.Set;
|
|||
* <li>SERVER_xxx: Hooks on the HAPI FHIR Server framework</li>
|
||||
* <li>SUBSCRIPTION_xxx: Hooks on the HAPI FHIR Subscription framework</li>
|
||||
* <li>STORAGE_xxx: Hooks on the storage engine</li>
|
||||
* <li>VALIDATION_xxx: Hooks on the HAPI FHIR Validation framework</li>
|
||||
* <li>JPA_PERFTRACE_xxx: Performance tracing hooks on the JPA server</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
|
@ -1851,6 +1853,37 @@ public enum Pointcut implements IPointcut {
|
|||
"ca.uhn.fhir.rest.server.servlet.ServletRequestDetails"
|
||||
),
|
||||
|
||||
/**
|
||||
* <b>Validation Hook:</b>
|
||||
* This hook is called after validation has completed, regardless of whether the validation was successful or failed.
|
||||
* Typically this is used to modify validation results.
|
||||
* <p>
|
||||
* <b>Note on validation Pointcuts:</b> The HAPI FHIR interceptor framework is a part of the client and server frameworks and
|
||||
* not a part of the core FhirContext. Therefore this Pointcut is invoked by the
|
||||
* </p>
|
||||
* <p>
|
||||
* Hooks may accept the following parameters:
|
||||
* <ul>
|
||||
* <li>
|
||||
* org.hl7.fhir.instance.model.api.IBaseResource - The resource being validated, if a parsed version is available (null otherwise)
|
||||
* </li>
|
||||
* <li>
|
||||
* java.lang.String - The resource being validated, if a raw version is available (null otherwise)
|
||||
* </li>
|
||||
* <li>
|
||||
* ca.uhn.fhir.validation.ValidationResult - The outcome of the validation. Hooks methods should not modify this object, but they can return a new one.
|
||||
* </li>
|
||||
* </ul>
|
||||
* </p>
|
||||
* Hook methods may return an instance of {@link ca.uhn.fhir.validation.ValidationResult} if they wish to override the validation results, or they may return <code>null</code> or <code>void</code> otherwise.
|
||||
*/
|
||||
VALIDATION_COMPLETED(ValidationResult.class,
|
||||
"org.hl7.fhir.instance.model.api.IBaseResource",
|
||||
"java.lang.String",
|
||||
"ca.uhn.fhir.validation.ValidationResult"
|
||||
),
|
||||
|
||||
|
||||
/**
|
||||
* <b>MDM(EMPI) Hook:</b>
|
||||
* Invoked whenever a persisted resource (a resource that has just been stored in the
|
||||
|
|
|
@ -19,13 +19,19 @@ package ca.uhn.fhir.validation;
|
|||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
import java.util.*;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.interceptor.api.HookParams;
|
||||
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||
import ca.uhn.fhir.validation.schematron.SchematronProvider;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.validation.schematron.SchematronProvider;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* Resource validator, which checks resources for compliance against various validation schemes (schemas, schematrons, profiles, etc.)
|
||||
|
@ -46,6 +52,7 @@ public class FhirValidator {
|
|||
private static volatile Boolean ourPhPresentOnClasspath;
|
||||
private final FhirContext myContext;
|
||||
private List<IValidatorModule> myValidators = new ArrayList<>();
|
||||
private IInterceptorBroadcaster myInterceptorBraodcaster;
|
||||
|
||||
/**
|
||||
* Constructor (this should not be called directly, but rather {@link FhirContext#newValidator()} should be called to obtain an instance of {@link FhirValidator})
|
||||
|
@ -65,7 +72,7 @@ public class FhirValidator {
|
|||
registerValidatorModule(theInstance);
|
||||
}
|
||||
} else {
|
||||
for (Iterator<IValidatorModule> iter = myValidators.iterator(); iter.hasNext();) {
|
||||
for (Iterator<IValidatorModule> iter = myValidators.iterator(); iter.hasNext(); ) {
|
||||
IValidatorModule next = iter.next();
|
||||
if (next.getClass().equals(type)) {
|
||||
unregisterValidatorModule(next);
|
||||
|
@ -91,6 +98,16 @@ public class FhirValidator {
|
|||
return haveValidatorOfType(SchemaBaseValidator.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the validator validate the resource against the base schema (the schema provided with the FHIR distribution itself)
|
||||
*
|
||||
* @return Returns a referens to <code>this<code> for method chaining
|
||||
*/
|
||||
public synchronized FhirValidator setValidateAgainstStandardSchema(boolean theValidateAgainstStandardSchema) {
|
||||
addOrRemoveValidator(theValidateAgainstStandardSchema, SchemaBaseValidator.class, new SchemaBaseValidator(myContext));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the validator validate the resource against the base schema (the schema provided with the FHIR distribution itself)
|
||||
*/
|
||||
|
@ -104,33 +121,6 @@ public class FhirValidator {
|
|||
return haveValidatorOfType(cls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new validator module to this validator. You may register as many modules as you like at any time.
|
||||
*
|
||||
* @param theValidator
|
||||
* The validator module. Must not be null.
|
||||
* @return Returns a reference to <code>this</code> for easy method chaining.
|
||||
*/
|
||||
public synchronized FhirValidator registerValidatorModule(IValidatorModule theValidator) {
|
||||
Validate.notNull(theValidator, "theValidator must not be null");
|
||||
ArrayList<IValidatorModule> newValidators = new ArrayList<IValidatorModule>(myValidators.size() + 1);
|
||||
newValidators.addAll(myValidators);
|
||||
newValidators.add(theValidator);
|
||||
|
||||
myValidators = newValidators;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the validator validate the resource against the base schema (the schema provided with the FHIR distribution itself)
|
||||
*
|
||||
* @return Returns a referens to <code>this<code> for method chaining
|
||||
*/
|
||||
public synchronized FhirValidator setValidateAgainstStandardSchema(boolean theValidateAgainstStandardSchema) {
|
||||
addOrRemoveValidator(theValidateAgainstStandardSchema, SchemaBaseValidator.class, new SchemaBaseValidator(myContext));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the validator validate the resource against the base schematron (the schematron provided with the FHIR distribution itself)
|
||||
*
|
||||
|
@ -149,11 +139,26 @@ public class FhirValidator {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new validator module to this validator. You may register as many modules as you like at any time.
|
||||
*
|
||||
* @param theValidator The validator module. Must not be null.
|
||||
* @return Returns a reference to <code>this</code> for easy method chaining.
|
||||
*/
|
||||
public synchronized FhirValidator registerValidatorModule(IValidatorModule theValidator) {
|
||||
Validate.notNull(theValidator, "theValidator must not be null");
|
||||
ArrayList<IValidatorModule> newValidators = new ArrayList<IValidatorModule>(myValidators.size() + 1);
|
||||
newValidators.addAll(myValidators);
|
||||
newValidators.add(theValidator);
|
||||
|
||||
myValidators = newValidators;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a validator module from this validator. You may register as many modules as you like, and remove them at any time.
|
||||
*
|
||||
* @param theValidator
|
||||
* The validator module. Must not be null.
|
||||
* @param theValidator The validator module. Must not be null.
|
||||
*/
|
||||
public synchronized void unregisterValidatorModule(IValidatorModule theValidator) {
|
||||
Validate.notNull(theValidator, "theValidator must not be null");
|
||||
|
@ -175,12 +180,10 @@ public class FhirValidator {
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Validates a resource instance returning a {@link ca.uhn.fhir.validation.ValidationResult} which contains the results.
|
||||
* Validates a resource instance returning a {@link ValidationResult} which contains the results.
|
||||
*
|
||||
* @param theResource
|
||||
* the resource to validate
|
||||
* @param theResource the resource to validate
|
||||
* @return the results of validation
|
||||
* @since 0.7
|
||||
*/
|
||||
|
@ -189,10 +192,9 @@ public class FhirValidator {
|
|||
}
|
||||
|
||||
/**
|
||||
* Validates a resource instance returning a {@link ca.uhn.fhir.validation.ValidationResult} which contains the results.
|
||||
* Validates a resource instance returning a {@link ValidationResult} which contains the results.
|
||||
*
|
||||
* @param theResource
|
||||
* the resource to validate
|
||||
* @param theResource the resource to validate
|
||||
* @return the results of validation
|
||||
* @since 1.1
|
||||
*/
|
||||
|
@ -201,12 +203,10 @@ public class FhirValidator {
|
|||
}
|
||||
|
||||
/**
|
||||
* Validates a resource instance returning a {@link ca.uhn.fhir.validation.ValidationResult} which contains the results.
|
||||
* Validates a resource instance returning a {@link ValidationResult} which contains the results.
|
||||
*
|
||||
* @param theResource
|
||||
* the resource to validate
|
||||
* @param theOptions
|
||||
* Optionally provides options to the validator
|
||||
* @param theResource the resource to validate
|
||||
* @param theOptions Optionally provides options to the validator
|
||||
* @return the results of validation
|
||||
* @since 4.0.0
|
||||
*/
|
||||
|
@ -221,16 +221,32 @@ public class FhirValidator {
|
|||
next.validateResource(ctx);
|
||||
}
|
||||
|
||||
return ctx.toResult();
|
||||
ValidationResult result = ctx.toResult();
|
||||
result = invokeValidationCompletedHooks(theResource, null, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private ValidationResult invokeValidationCompletedHooks(IBaseResource theResourceParsed, String theResourceRaw, ValidationResult theValidationResult) {
|
||||
if (myInterceptorBraodcaster != null) {
|
||||
if (myInterceptorBraodcaster.hasHooks(Pointcut.VALIDATION_COMPLETED)) {
|
||||
HookParams params = new HookParams()
|
||||
.add(IBaseResource.class, theResourceParsed)
|
||||
.add(String.class, theResourceRaw)
|
||||
.add(ValidationResult.class, theValidationResult);
|
||||
Object newResult = myInterceptorBraodcaster.callHooksAndReturnObject(Pointcut.VALIDATION_COMPLETED, params);
|
||||
if (newResult != null) {
|
||||
theValidationResult = (ValidationResult) newResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
return theValidationResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a resource instance returning a {@link ca.uhn.fhir.validation.ValidationResult} which contains the results.
|
||||
* Validates a resource instance returning a {@link ValidationResult} which contains the results.
|
||||
*
|
||||
* @param theResource
|
||||
* the resource to validate
|
||||
* @param theOptions
|
||||
* Optionally provides options to the validator
|
||||
* @param theResource the resource to validate
|
||||
* @param theOptions Optionally provides options to the validator
|
||||
* @return the results of validation
|
||||
* @since 4.0.0
|
||||
*/
|
||||
|
@ -245,6 +261,17 @@ public class FhirValidator {
|
|||
next.validateResource(ctx);
|
||||
}
|
||||
|
||||
return ctx.toResult();
|
||||
ValidationResult result = ctx.toResult();
|
||||
result = invokeValidationCompletedHooks(null, theResource, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optionally supplies an interceptor broadcaster that will be used to invoke validation related Pointcut events
|
||||
*
|
||||
* @since 5.5.0
|
||||
*/
|
||||
public void setInterceptorBraodcaster(IInterceptorBroadcaster theInterceptorBraodcaster) {
|
||||
myInterceptorBraodcaster = theInterceptorBraodcaster;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,4 +149,11 @@ public class ValidationResult {
|
|||
public String toString() {
|
||||
return "ValidationResult{" + "messageCount=" + myMessages.size() + ", isSuccessful=" + myIsSuccessful + ", description='" + toDescription() + '\'' + '}';
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 5.5.0
|
||||
*/
|
||||
public FhirContext getContext() {
|
||||
return myCtx;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
type: add
|
||||
issue: 2675
|
||||
title: "A new interceptor ValidationMessageSuppressingInterceptor has been added. This interceptor can be used
|
||||
to selectively suppress specific vaLidation messages."
|
|
@ -58,7 +58,7 @@ import ca.uhn.fhir.jpa.searchparam.matcher.InMemoryResourceMatcher;
|
|||
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
|
||||
import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
|
||||
import ca.uhn.fhir.jpa.util.AddRemoveCount;
|
||||
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.jpa.util.MemoryCacheService;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||
|
@ -1308,14 +1308,14 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
|
|||
|
||||
// Interceptor broadcast: JPA_PERFTRACE_INFO
|
||||
if (!presenceCount.isEmpty()) {
|
||||
if (JpaInterceptorBroadcaster.hasHooks(Pointcut.JPA_PERFTRACE_INFO, myInterceptorBroadcaster, theRequest)) {
|
||||
if (CompositeInterceptorBroadcaster.hasHooks(Pointcut.JPA_PERFTRACE_INFO, myInterceptorBroadcaster, theRequest)) {
|
||||
StorageProcessingMessage message = new StorageProcessingMessage();
|
||||
message.setMessage("For " + entity.getIdDt().toUnqualifiedVersionless().getValue() + " added " + presenceCount.getAddCount() + " and removed " + presenceCount.getRemoveCount() + " resource search parameter presence entries");
|
||||
HookParams params = new HookParams()
|
||||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest)
|
||||
.add(StorageProcessingMessage.class, message);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.JPA_PERFTRACE_INFO, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.JPA_PERFTRACE_INFO, params);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1336,14 +1336,14 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
|
|||
|
||||
// Interceptor broadcast: JPA_PERFTRACE_INFO
|
||||
if (!searchParamAddRemoveCount.isEmpty()) {
|
||||
if (JpaInterceptorBroadcaster.hasHooks(Pointcut.JPA_PERFTRACE_INFO, myInterceptorBroadcaster, theRequest)) {
|
||||
if (CompositeInterceptorBroadcaster.hasHooks(Pointcut.JPA_PERFTRACE_INFO, myInterceptorBroadcaster, theRequest)) {
|
||||
StorageProcessingMessage message = new StorageProcessingMessage();
|
||||
message.setMessage("For " + entity.getIdDt().toUnqualifiedVersionless().getValue() + " added " + searchParamAddRemoveCount.getAddCount() + " and removed " + searchParamAddRemoveCount.getRemoveCount() + " resource search parameter index entries");
|
||||
HookParams params = new HookParams()
|
||||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest)
|
||||
.add(StorageProcessingMessage.class, message);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.JPA_PERFTRACE_INFO, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.JPA_PERFTRACE_INFO, params);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc;
|
|||
import ca.uhn.fhir.jpa.searchparam.MatchUrlService;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.searchparam.extractor.ResourceIndexedSearchParams;
|
||||
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.jpa.util.MemoryCacheService;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.model.dstu2.resource.ListResource;
|
||||
|
@ -1156,7 +1156,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
.add(IPreResourceAccessDetails.class, accessDetails)
|
||||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.STORAGE_PREACCESS_RESOURCES, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.STORAGE_PREACCESS_RESOURCES, params);
|
||||
if (accessDetails.isDontReturnResourceAtIndex(0)) {
|
||||
throw new ResourceNotFoundException(theId);
|
||||
}
|
||||
|
@ -1169,7 +1169,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
.add(IPreResourceShowDetails.class, showDetails)
|
||||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.STORAGE_PRESHOW_RESOURCES, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.STORAGE_PRESHOW_RESOURCES, params);
|
||||
//noinspection unchecked
|
||||
retVal = (T) showDetails.getResource(0);
|
||||
}
|
||||
|
@ -1700,6 +1700,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
|
||||
FhirValidator validator = getContext().newValidator();
|
||||
|
||||
validator.setInterceptorBraodcaster(CompositeInterceptorBroadcaster.newCompositeBroadcaster(myInterceptorBroadcaster, theRequest));
|
||||
validator.registerValidatorModule(getInstanceValidator());
|
||||
validator.registerValidatorModule(new IdChecker(theMode));
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
|||
import ca.uhn.fhir.jpa.searchparam.util.JpaParamUtil;
|
||||
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
|
||||
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
|
||||
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterAnd;
|
||||
import ca.uhn.fhir.rest.api.QualifiedParamList;
|
||||
import ca.uhn.fhir.rest.api.server.IPreResourceAccessDetails;
|
||||
|
@ -247,7 +247,7 @@ public abstract class BaseStorageDao {
|
|||
.add(IPreResourceAccessDetails.class, accessDetails)
|
||||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest);
|
||||
JpaInterceptorBroadcaster.doCallHooks(getInterceptorBroadcaster(), theRequest, Pointcut.STORAGE_PREACCESS_RESOURCES, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(getInterceptorBroadcaster(), theRequest, Pointcut.STORAGE_PREACCESS_RESOURCES, params);
|
||||
if (accessDetails.isDontReturnResourceAtIndex(0)) {
|
||||
outcome.setResource(null);
|
||||
}
|
||||
|
@ -264,7 +264,7 @@ public abstract class BaseStorageDao {
|
|||
.add(IPreResourceShowDetails.class, showDetails)
|
||||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest);
|
||||
JpaInterceptorBroadcaster.doCallHooks(getInterceptorBroadcaster(), theRequest, Pointcut.STORAGE_PRESHOW_RESOURCES, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(getInterceptorBroadcaster(), theRequest, Pointcut.STORAGE_PRESHOW_RESOURCES, params);
|
||||
outcome.setResource(showDetails.getResource(0));
|
||||
}
|
||||
});
|
||||
|
@ -285,7 +285,7 @@ public abstract class BaseStorageDao {
|
|||
.add(IPreResourceAccessDetails.class, accessDetails)
|
||||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest);
|
||||
JpaInterceptorBroadcaster.doCallHooks(getInterceptorBroadcaster(), theRequest, Pointcut.STORAGE_PREACCESS_RESOURCES, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(getInterceptorBroadcaster(), theRequest, Pointcut.STORAGE_PREACCESS_RESOURCES, params);
|
||||
if (accessDetails.isDontReturnResourceAtIndex(0)) {
|
||||
outcome.setResource(null);
|
||||
}
|
||||
|
@ -302,7 +302,7 @@ public abstract class BaseStorageDao {
|
|||
.add(IPreResourceShowDetails.class, showDetails)
|
||||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest);
|
||||
JpaInterceptorBroadcaster.doCallHooks(getInterceptorBroadcaster(), theRequest, Pointcut.STORAGE_PRESHOW_RESOURCES, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(getInterceptorBroadcaster(), theRequest, Pointcut.STORAGE_PRESHOW_RESOURCES, params);
|
||||
outcome.setResource(showDetails.getResource(0));
|
||||
}
|
||||
});
|
||||
|
@ -316,7 +316,7 @@ public abstract class BaseStorageDao {
|
|||
if (theTransactionDetails.isAcceptingDeferredInterceptorBroadcasts(thePointcut)) {
|
||||
theTransactionDetails.addDeferredInterceptorBroadcast(thePointcut, theParams);
|
||||
} else {
|
||||
JpaInterceptorBroadcaster.doCallHooks(getInterceptorBroadcaster(), theRequestDetails, thePointcut, theParams);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(getInterceptorBroadcaster(), theRequestDetails, thePointcut, theParams);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
|
|||
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.model.search.StorageProcessingMessage;
|
||||
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
|
@ -526,7 +526,7 @@ public abstract class BaseTransactionProcessor {
|
|||
transactionStopWatch.endCurrentTask();
|
||||
|
||||
// Interceptor broadcast: JPA_PERFTRACE_INFO
|
||||
if (JpaInterceptorBroadcaster.hasHooks(Pointcut.JPA_PERFTRACE_INFO, myInterceptorBroadcaster, theRequestDetails)) {
|
||||
if (CompositeInterceptorBroadcaster.hasHooks(Pointcut.JPA_PERFTRACE_INFO, myInterceptorBroadcaster, theRequestDetails)) {
|
||||
String taskDurations = transactionStopWatch.formatTaskDurations();
|
||||
StorageProcessingMessage message = new StorageProcessingMessage();
|
||||
message.setMessage("Transaction timing:\n" + taskDurations);
|
||||
|
@ -534,7 +534,7 @@ public abstract class BaseTransactionProcessor {
|
|||
.add(RequestDetails.class, theRequestDetails)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequestDetails)
|
||||
.add(StorageProcessingMessage.class, message);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequestDetails, Pointcut.JPA_PERFTRACE_INFO, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequestDetails, Pointcut.JPA_PERFTRACE_INFO, params);
|
||||
}
|
||||
|
||||
return response;
|
||||
|
@ -955,7 +955,7 @@ public abstract class BaseTransactionProcessor {
|
|||
for (Map.Entry<Pointcut, HookParams> nextEntry : deferredBroadcastEvents.entries()) {
|
||||
Pointcut nextPointcut = nextEntry.getKey();
|
||||
HookParams nextParams = nextEntry.getValue();
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, nextPointcut, nextParams);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, nextPointcut, nextParams);
|
||||
}
|
||||
|
||||
DeferredInterceptorBroadcasts deferredInterceptorBroadcasts = new DeferredInterceptorBroadcasts(deferredBroadcastEvents);
|
||||
|
@ -965,7 +965,7 @@ public abstract class BaseTransactionProcessor {
|
|||
.add(DeferredInterceptorBroadcasts.class, deferredInterceptorBroadcasts)
|
||||
.add(TransactionDetails.class, theTransactionDetails)
|
||||
.add(IBaseBundle.class, theResponse);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.STORAGE_TRANSACTION_PROCESSED, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.STORAGE_TRANSACTION_PROCESSED, params);
|
||||
|
||||
theTransactionDetails.deferredBroadcastProcessingFinished();
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ import ca.uhn.fhir.jpa.searchparam.util.Dstu3DistanceHelper;
|
|||
import ca.uhn.fhir.jpa.searchparam.util.LastNParameterHelper;
|
||||
import ca.uhn.fhir.jpa.util.BaseIterator;
|
||||
import ca.uhn.fhir.jpa.util.CurrentThreadCaptureQueriesListener;
|
||||
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.jpa.util.QueryChunker;
|
||||
import ca.uhn.fhir.jpa.util.ScrollableResultsIterator;
|
||||
import ca.uhn.fhir.jpa.util.SqlQueryList;
|
||||
|
@ -305,7 +305,7 @@ public class LegacySearchBuilder implements ISearchBuilder {
|
|||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest)
|
||||
.add(SearchRuntimeDetails.class, theSearchRuntimeDetails);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.JPA_PERFTRACE_INDEXSEARCH_QUERY_COMPLETE, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.JPA_PERFTRACE_INDEXSEARCH_QUERY_COMPLETE, params);
|
||||
}
|
||||
|
||||
if (pids.isEmpty()) {
|
||||
|
@ -823,7 +823,7 @@ public class LegacySearchBuilder implements ISearchBuilder {
|
|||
.add(IPreResourceAccessDetails.class, accessDetails)
|
||||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.STORAGE_PREACCESS_RESOURCES, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.STORAGE_PREACCESS_RESOURCES, params);
|
||||
|
||||
allAdded = new HashSet<>(includedPidList);
|
||||
|
||||
|
@ -925,7 +925,7 @@ public class LegacySearchBuilder implements ISearchBuilder {
|
|||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest)
|
||||
.add(StorageProcessingMessage.class, msg);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.JPA_PERFTRACE_INFO, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.JPA_PERFTRACE_INFO, params);
|
||||
|
||||
addPredicateCompositeStringUnique(theParams, indexString, myRequestPartitionId);
|
||||
}
|
||||
|
@ -1093,8 +1093,8 @@ public class LegacySearchBuilder implements ISearchBuilder {
|
|||
myStillNeedToFetchIncludes = true;
|
||||
}
|
||||
|
||||
myHavePerfTraceFoundIdHook = JpaInterceptorBroadcaster.hasHooks(Pointcut.JPA_PERFTRACE_SEARCH_FOUND_ID, myInterceptorBroadcaster, myRequest);
|
||||
myHaveRawSqlHooks = JpaInterceptorBroadcaster.hasHooks(Pointcut.JPA_PERFTRACE_RAW_SQL, myInterceptorBroadcaster, myRequest);
|
||||
myHavePerfTraceFoundIdHook = CompositeInterceptorBroadcaster.hasHooks(Pointcut.JPA_PERFTRACE_SEARCH_FOUND_ID, myInterceptorBroadcaster, myRequest);
|
||||
myHaveRawSqlHooks = CompositeInterceptorBroadcaster.hasHooks(Pointcut.JPA_PERFTRACE_RAW_SQL, myInterceptorBroadcaster, myRequest);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1157,7 +1157,7 @@ public class LegacySearchBuilder implements ISearchBuilder {
|
|||
HookParams params = new HookParams()
|
||||
.add(Integer.class, System.identityHashCode(this))
|
||||
.add(Object.class, nextLong);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_SEARCH_FOUND_ID, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_SEARCH_FOUND_ID, params);
|
||||
}
|
||||
|
||||
if (nextLong != null) {
|
||||
|
@ -1184,7 +1184,7 @@ public class LegacySearchBuilder implements ISearchBuilder {
|
|||
.add(RequestDetails.class, myRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, myRequest)
|
||||
.add(StorageProcessingMessage.class, message);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_WARNING, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_WARNING, params);
|
||||
|
||||
initializeIteratorQuery(null, myMaxResultsToFetch);
|
||||
}
|
||||
|
@ -1226,7 +1226,7 @@ public class LegacySearchBuilder implements ISearchBuilder {
|
|||
.add(RequestDetails.class, myRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, myRequest)
|
||||
.add(SqlQueryList.class, capturedQueries);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_RAW_SQL, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_RAW_SQL, params);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1235,7 +1235,7 @@ public class LegacySearchBuilder implements ISearchBuilder {
|
|||
.add(RequestDetails.class, myRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, myRequest)
|
||||
.add(SearchRuntimeDetails.class, mySearchRuntimeDetails);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_SEARCH_FIRST_RESULT_LOADED, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_SEARCH_FIRST_RESULT_LOADED, params);
|
||||
myFirst = false;
|
||||
}
|
||||
|
||||
|
@ -1244,7 +1244,7 @@ public class LegacySearchBuilder implements ISearchBuilder {
|
|||
.add(RequestDetails.class, myRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, myRequest)
|
||||
.add(SearchRuntimeDetails.class, mySearchRuntimeDetails);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_SEARCH_SELECT_COMPLETE, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_SEARCH_SELECT_COMPLETE, params);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
|||
import ca.uhn.fhir.jpa.model.search.StorageProcessingMessage;
|
||||
import ca.uhn.fhir.jpa.searchparam.MatchUrlService;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.jpa.util.MemoryCacheService;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
|
||||
|
@ -43,8 +43,6 @@ import org.apache.commons.lang3.Validate;
|
|||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
@ -99,14 +97,14 @@ public class MatchResourceUrlService {
|
|||
Set<ResourcePersistentId> retVal = dao.searchForIds(theParamMap, theRequest);
|
||||
|
||||
// Interceptor broadcast: JPA_PERFTRACE_INFO
|
||||
if (JpaInterceptorBroadcaster.hasHooks(Pointcut.JPA_PERFTRACE_INFO, myInterceptorBroadcaster, theRequest)) {
|
||||
if (CompositeInterceptorBroadcaster.hasHooks(Pointcut.JPA_PERFTRACE_INFO, myInterceptorBroadcaster, theRequest)) {
|
||||
StorageProcessingMessage message = new StorageProcessingMessage();
|
||||
message.setMessage("Processed conditional resource URL with " + retVal.size() + " result(s) in " + sw.toString());
|
||||
HookParams params = new HookParams()
|
||||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest)
|
||||
.add(StorageProcessingMessage.class, message);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.JPA_PERFTRACE_INFO, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.JPA_PERFTRACE_INFO, params);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
|
|||
import ca.uhn.fhir.jpa.dao.data.IResourceLinkDao;
|
||||
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceLink;
|
||||
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||
|
@ -87,7 +87,7 @@ public class DeleteExpungeService {
|
|||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest)
|
||||
.add(String.class, theUrl);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.STORAGE_PRE_DELETE_EXPUNGE, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.STORAGE_PRE_DELETE_EXPUNGE, params);
|
||||
|
||||
TransactionTemplate txTemplate = new TransactionTemplate(myPlatformTransactionManager);
|
||||
txTemplate.executeWithoutResult(t -> validateOkToDeleteAndExpunge(thePids));
|
||||
|
@ -172,7 +172,7 @@ public class DeleteExpungeService {
|
|||
.add(AtomicLong.class, theExpungedEntitiesCount)
|
||||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.STORAGE_PRE_DELETE_EXPUNGE_PID_LIST, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.STORAGE_PRE_DELETE_EXPUNGE_PID_LIST, params);
|
||||
|
||||
String pidListString = thePids.toString().replace("[", "(").replace("]", ")");
|
||||
List<ResourceForeignKey> resourceForeignKeys = myResourceTableFKProvider.getResourceForeignKeys();
|
||||
|
|
|
@ -64,7 +64,7 @@ import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
|||
import ca.uhn.fhir.jpa.model.entity.ResourceTag;
|
||||
import ca.uhn.fhir.jpa.model.entity.SearchParamPresent;
|
||||
import ca.uhn.fhir.jpa.model.entity.TagDefinition;
|
||||
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||
import ca.uhn.fhir.util.StopWatch;
|
||||
|
@ -113,7 +113,7 @@ public class ExpungeEverythingService {
|
|||
.add(AtomicInteger.class, counter)
|
||||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.STORAGE_PRESTORAGE_EXPUNGE_EVERYTHING, hooks);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.STORAGE_PRESTORAGE_EXPUNGE_EVERYTHING, hooks);
|
||||
|
||||
ourLog.info("BEGINNING GLOBAL $expunge");
|
||||
myTxTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
|
||||
|
|
|
@ -46,7 +46,7 @@ import ca.uhn.fhir.jpa.dao.index.IdHelperService;
|
|||
import ca.uhn.fhir.jpa.model.entity.ForcedId;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.jpa.util.MemoryCacheService;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
|
@ -201,7 +201,7 @@ public class ResourceExpungeService implements IResourceExpungeService {
|
|||
|
||||
private void callHooks(RequestDetails theRequestDetails, AtomicInteger theRemainingCount, ResourceHistoryTable theVersion, IdDt theId) {
|
||||
final AtomicInteger counter = new AtomicInteger();
|
||||
if (JpaInterceptorBroadcaster.hasHooks(Pointcut.STORAGE_PRESTORAGE_EXPUNGE_RESOURCE, myInterceptorBroadcaster, theRequestDetails)) {
|
||||
if (CompositeInterceptorBroadcaster.hasHooks(Pointcut.STORAGE_PRESTORAGE_EXPUNGE_RESOURCE, myInterceptorBroadcaster, theRequestDetails)) {
|
||||
IFhirResourceDao<?> resourceDao = myDaoRegistry.getResourceDao(theId.getResourceType());
|
||||
IBaseResource resource = resourceDao.toResource(theVersion, false);
|
||||
HookParams params = new HookParams()
|
||||
|
@ -210,7 +210,7 @@ public class ResourceExpungeService implements IResourceExpungeService {
|
|||
.add(IBaseResource.class, resource)
|
||||
.add(RequestDetails.class, theRequestDetails)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequestDetails);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequestDetails, Pointcut.STORAGE_PRESTORAGE_EXPUNGE_RESOURCE, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequestDetails, Pointcut.STORAGE_PRESTORAGE_EXPUNGE_RESOURCE, params);
|
||||
}
|
||||
theRemainingCount.addAndGet(-1 * counter.get());
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ import ca.uhn.fhir.jpa.searchparam.ResourceMetaParams;
|
|||
import ca.uhn.fhir.jpa.searchparam.util.JpaParamUtil;
|
||||
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
|
||||
import ca.uhn.fhir.jpa.searchparam.util.SourceParam;
|
||||
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterAnd;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterOr;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
|
@ -475,7 +475,7 @@ class PredicateBuilderReference extends BasePredicateBuilder {
|
|||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest)
|
||||
.add(StorageProcessingMessage.class, msg);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.JPA_PERFTRACE_WARNING, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.JPA_PERFTRACE_WARNING, params);
|
||||
}
|
||||
|
||||
Predicate createResourceLinkPathPredicate(String theResourceName, String theParamName, From<?, ? extends ResourceLink> from) {
|
||||
|
|
|
@ -24,7 +24,7 @@ import ca.uhn.fhir.interceptor.api.HookParams;
|
|||
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||
import ca.uhn.fhir.jpa.api.model.ResourceVersionConflictResolutionStrategy;
|
||||
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
|
||||
|
@ -107,7 +107,7 @@ public class HapiTransactionService {
|
|||
HookParams params = new HookParams()
|
||||
.add(RequestDetails.class, theRequestDetails)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequestDetails);
|
||||
ResourceVersionConflictResolutionStrategy conflictResolutionStrategy = (ResourceVersionConflictResolutionStrategy) JpaInterceptorBroadcaster.doCallHooksAndReturnObject(myInterceptorBroadcaster, theRequestDetails, Pointcut.STORAGE_VERSION_CONFLICT, params);
|
||||
ResourceVersionConflictResolutionStrategy conflictResolutionStrategy = (ResourceVersionConflictResolutionStrategy) CompositeInterceptorBroadcaster.doCallHooksAndReturnObject(myInterceptorBroadcaster, theRequestDetails, Pointcut.STORAGE_VERSION_CONFLICT, params);
|
||||
if (conflictResolutionStrategy != null && conflictResolutionStrategy.isRetry()) {
|
||||
maxRetries = conflictResolutionStrategy.getMaxRetries();
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
|||
import ca.uhn.fhir.jpa.dao.data.IResourceLinkDao;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceLink;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
|
||||
|
@ -121,7 +121,7 @@ public class DeleteConflictService {
|
|||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest)
|
||||
.add(TransactionDetails.class, theTransactionDetails);
|
||||
return (DeleteConflictOutcome) JpaInterceptorBroadcaster.doCallHooksAndReturnObject(myInterceptorBroadcaster, theRequest, Pointcut.STORAGE_PRESTORAGE_DELETE_CONFLICTS, hooks);
|
||||
return (DeleteConflictOutcome) CompositeInterceptorBroadcaster.doCallHooksAndReturnObject(myInterceptorBroadcaster, theRequest, Pointcut.STORAGE_PRESTORAGE_DELETE_CONFLICTS, hooks);
|
||||
}
|
||||
|
||||
private void addConflictsToList(DeleteConflictList theDeleteConflicts, ResourceTable theEntity, List<ResourceLink> theResultList) {
|
||||
|
|
|
@ -32,7 +32,7 @@ import ca.uhn.fhir.jpa.api.model.DeleteConflict;
|
|||
import ca.uhn.fhir.jpa.api.model.DeleteConflictList;
|
||||
import ca.uhn.fhir.jpa.delete.DeleteConflictOutcome;
|
||||
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
|
||||
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.api.DeleteCascadeModeEnum;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
|
@ -135,7 +135,7 @@ public class CascadingDeleteInterceptor {
|
|||
.addIfMatchesType(ServletRequestDetails.class, theRequest)
|
||||
.add(DeleteConflictList.class, theConflictList)
|
||||
.add(IBaseResource.class, resource);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.STORAGE_CASCADE_DELETE, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.STORAGE_CASCADE_DELETE, params);
|
||||
|
||||
// Actually perform the delete
|
||||
ourLog.info("Have delete conflict {} - Cascading delete", next);
|
||||
|
|
|
@ -22,6 +22,7 @@ package ca.uhn.fhir.jpa.interceptor.validation;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.support.IValidationSupport;
|
||||
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.jpa.validation.ValidatorResourceFetcher;
|
||||
import ca.uhn.fhir.rest.server.interceptor.ValidationResultEnrichingInterceptor;
|
||||
import ca.uhn.fhir.validation.ResultSeverityEnum;
|
||||
|
@ -54,6 +55,8 @@ public final class RepositoryValidatingRuleBuilder implements IRuleRoot {
|
|||
private IValidationSupport myValidationSupport;
|
||||
@Autowired
|
||||
private ValidatorResourceFetcher myValidatorResourceFetcher;
|
||||
@Autowired
|
||||
private IInterceptorBroadcaster myInterceptorBroadcaster;
|
||||
|
||||
/**
|
||||
* Begin a new rule for a specific resource type.
|
||||
|
@ -171,7 +174,7 @@ public final class RepositoryValidatingRuleBuilder implements IRuleRoot {
|
|||
* @see ValidationResultEnrichingInterceptor
|
||||
*/
|
||||
public FinalizedRequireValidationRule requireValidationToDeclaredProfiles() {
|
||||
RequireValidationRule rule = new RequireValidationRule(myFhirContext, myType, myValidationSupport, myValidatorResourceFetcher);
|
||||
RequireValidationRule rule = new RequireValidationRule(myFhirContext, myType, myValidationSupport, myValidatorResourceFetcher, myInterceptorBroadcaster);
|
||||
myRules.add(rule);
|
||||
return new FinalizedRequireValidationRule(rule);
|
||||
}
|
||||
|
@ -248,6 +251,7 @@ public final class RepositoryValidatingRuleBuilder implements IRuleRoot {
|
|||
}
|
||||
|
||||
/**
|
||||
* Specifies the minimum validation result severity that should cause a rejection. For example, if
|
||||
* Specifies the minimum validation result severity that should cause a rejection. For example, if
|
||||
* this is set to <code>ERROR</code> (which is the default), any validation results with a severity
|
||||
* of <code>ERROR</code> or <code>FATAL</code> will cause the create/update operation to be rejected and
|
||||
|
|
|
@ -22,6 +22,8 @@ package ca.uhn.fhir.jpa.interceptor.validation;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.support.IValidationSupport;
|
||||
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.jpa.validation.ValidatorResourceFetcher;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.interceptor.ValidationResultEnrichingInterceptor;
|
||||
|
@ -43,12 +45,15 @@ import java.util.List;
|
|||
|
||||
class RequireValidationRule extends BaseTypedRule {
|
||||
private final FhirInstanceValidator myValidator;
|
||||
private final IInterceptorBroadcaster myInterceptorBroadcaster;
|
||||
private ResultSeverityEnum myRejectOnSeverity = ResultSeverityEnum.ERROR;
|
||||
private List<TagOnSeverity> myTagOnSeverity = Collections.emptyList();
|
||||
|
||||
public RequireValidationRule(FhirContext theFhirContext, String theType, IValidationSupport theValidationSupport, ValidatorResourceFetcher theValidatorResourceFetcher) {
|
||||
public RequireValidationRule(FhirContext theFhirContext, String theType, IValidationSupport theValidationSupport, ValidatorResourceFetcher theValidatorResourceFetcher, IInterceptorBroadcaster theInterceptorBroadcaster) {
|
||||
super(theFhirContext, theType);
|
||||
|
||||
myInterceptorBroadcaster = theInterceptorBroadcaster;
|
||||
|
||||
myValidator = new FhirInstanceValidator(theValidationSupport);
|
||||
myValidator.setValidatorResourceFetcher(theValidatorResourceFetcher);
|
||||
myValidator.setBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel.Warning);
|
||||
|
@ -63,6 +68,7 @@ class RequireValidationRule extends BaseTypedRule {
|
|||
public RuleEvaluation evaluate(RequestDetails theRequestDetails, @Nonnull IBaseResource theResource) {
|
||||
|
||||
FhirValidator validator = getFhirContext().newValidator();
|
||||
validator.setInterceptorBraodcaster(CompositeInterceptorBroadcaster.newCompositeBroadcaster(myInterceptorBroadcaster, theRequestDetails));
|
||||
validator.registerValidatorModule(myValidator);
|
||||
ValidationResult outcome = validator.validateWithResult(theResource);
|
||||
|
||||
|
|
|
@ -46,9 +46,9 @@ import java.util.List;
|
|||
import java.util.Objects;
|
||||
|
||||
import static ca.uhn.fhir.jpa.model.util.JpaConstants.ALL_PARTITIONS_NAME;
|
||||
import static ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster.doCallHooks;
|
||||
import static ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster.doCallHooksAndReturnObject;
|
||||
import static ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster.hasHooks;
|
||||
import static ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster.doCallHooks;
|
||||
import static ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster.doCallHooksAndReturnObject;
|
||||
import static ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster.hasHooks;
|
||||
import static org.slf4j.LoggerFactory.getLogger;
|
||||
|
||||
public class RequestPartitionHelperSvc implements IRequestPartitionHelperSvc {
|
||||
|
|
|
@ -41,7 +41,7 @@ import ca.uhn.fhir.jpa.partition.RequestPartitionHelperSvc;
|
|||
import ca.uhn.fhir.jpa.search.cache.ISearchCacheSvc;
|
||||
import ca.uhn.fhir.jpa.search.cache.SearchCacheStatusEnum;
|
||||
import ca.uhn.fhir.jpa.util.InterceptorUtil;
|
||||
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.jpa.util.MemoryCacheService;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
|
@ -171,7 +171,7 @@ public class PersistedJpaBundleProvider implements IBundleProvider {
|
|||
.add(IPreResourceAccessDetails.class, accessDetails)
|
||||
.add(RequestDetails.class, myRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, myRequest);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.STORAGE_PREACCESS_RESOURCES, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.STORAGE_PREACCESS_RESOURCES, params);
|
||||
|
||||
for (int i = retVal.size() - 1; i >= 0; i--) {
|
||||
if (accessDetails.isDontReturnResourceAtIndex(i)) {
|
||||
|
@ -187,7 +187,7 @@ public class PersistedJpaBundleProvider implements IBundleProvider {
|
|||
.add(IPreResourceShowDetails.class, showDetails)
|
||||
.add(RequestDetails.class, myRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, myRequest);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.STORAGE_PRESHOW_RESOURCES, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.STORAGE_PRESHOW_RESOURCES, params);
|
||||
retVal = showDetails.toList();
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ import ca.uhn.fhir.jpa.search.cache.ISearchResultCacheSvc;
|
|||
import ca.uhn.fhir.jpa.search.cache.SearchCacheStatusEnum;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.util.InterceptorUtil;
|
||||
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.rest.api.CacheControlDirective;
|
||||
|
@ -316,7 +316,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
|
|||
.add(RequestDetails.class, theRequestDetails)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequestDetails)
|
||||
.add(SearchParameterMap.class, theParams);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequestDetails, Pointcut.STORAGE_PRESEARCH_REGISTERED, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequestDetails, Pointcut.STORAGE_PRESEARCH_REGISTERED, params);
|
||||
Class<? extends IBaseResource> resourceTypeClass = myContext.getResourceDefinition(theResourceType).getImplementingClass();
|
||||
final ISearchBuilder sb = mySearchBuilderFactory.newSearchBuilder(theCallingDao, theResourceType, resourceTypeClass);
|
||||
sb.setFetchSize(mySyncSize);
|
||||
|
@ -400,7 +400,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
|
|||
// .add(RequestDetails.class, theRequestDetails)
|
||||
// .addIfMatchesType(ServletRequestDetails.class, theRequestDetails)
|
||||
// .add(SearchParameterMap.class, theParams);
|
||||
// JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequestDetails, Pointcut.STORAGE_PRESEARCH_REGISTERED, params);
|
||||
// CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequestDetails, Pointcut.STORAGE_PRESEARCH_REGISTERED, params);
|
||||
|
||||
SearchTask task = new SearchTask(theSearch, theCallingDao, theParams, theResourceType, theRequestDetails, theRequestPartitionId);
|
||||
myIdToSearchTask.put(theSearch.getUuid(), task);
|
||||
|
@ -424,7 +424,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
|
|||
.add(SearchParameterMap.class, theParams)
|
||||
.add(RequestDetails.class, theRequestDetails)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequestDetails);
|
||||
Object outcome = JpaInterceptorBroadcaster.doCallHooksAndReturnObject(myInterceptorBroadcaster, theRequestDetails, Pointcut.STORAGE_PRECHECK_FOR_CACHED_SEARCH, params);
|
||||
Object outcome = CompositeInterceptorBroadcaster.doCallHooksAndReturnObject(myInterceptorBroadcaster, theRequestDetails, Pointcut.STORAGE_PRECHECK_FOR_CACHED_SEARCH, params);
|
||||
if (Boolean.FALSE.equals(outcome)) {
|
||||
return null;
|
||||
}
|
||||
|
@ -441,7 +441,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
|
|||
.add(SearchParameterMap.class, theParams)
|
||||
.add(RequestDetails.class, theRequestDetails)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequestDetails);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequestDetails, Pointcut.JPA_PERFTRACE_SEARCH_REUSING_CACHED, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequestDetails, Pointcut.JPA_PERFTRACE_SEARCH_REUSING_CACHED, params);
|
||||
|
||||
return myPersistedJpaBundleProviderFactory.newInstance(theRequestDetails, searchToUse.getUuid());
|
||||
});
|
||||
|
@ -515,7 +515,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
|
|||
.add(IPreResourceAccessDetails.class, accessDetails)
|
||||
.add(RequestDetails.class, theRequestDetails)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequestDetails);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequestDetails, Pointcut.STORAGE_PREACCESS_RESOURCES, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequestDetails, Pointcut.STORAGE_PREACCESS_RESOURCES, params);
|
||||
|
||||
for (int i = pids.size() - 1; i >= 0; i--) {
|
||||
if (accessDetails.isDontReturnResourceAtIndex(i)) {
|
||||
|
@ -854,7 +854,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
|
|||
.add(IPreResourceAccessDetails.class, accessDetails)
|
||||
.add(RequestDetails.class, mySearchRuntimeDetails.getRequestDetails())
|
||||
.addIfMatchesType(ServletRequestDetails.class, mySearchRuntimeDetails.getRequestDetails());
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.STORAGE_PREACCESS_RESOURCES, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.STORAGE_PREACCESS_RESOURCES, params);
|
||||
|
||||
for (int i = unsyncedPids.size() - 1; i >= 0; i--) {
|
||||
if (accessDetails.isDontReturnResourceAtIndex(i)) {
|
||||
|
@ -974,13 +974,13 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
|
|||
.add(RequestDetails.class, myRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, myRequest)
|
||||
.add(SearchRuntimeDetails.class, mySearchRuntimeDetails);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_SEARCH_COMPLETE, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_SEARCH_COMPLETE, params);
|
||||
} else {
|
||||
HookParams params = new HookParams()
|
||||
.add(RequestDetails.class, myRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, myRequest)
|
||||
.add(SearchRuntimeDetails.class, mySearchRuntimeDetails);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_SEARCH_PASS_COMPLETE, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_SEARCH_PASS_COMPLETE, params);
|
||||
}
|
||||
|
||||
ourLog.trace("Have completed search for [{}{}] and found {} resources in {}ms - Status is {}", mySearch.getResourceType(), mySearch.getSearchQueryString(), mySyncedPids.size(), sw.getMillis(), mySearch.getStatus());
|
||||
|
@ -1028,7 +1028,7 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
|
|||
.add(RequestDetails.class, myRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, myRequest)
|
||||
.add(SearchRuntimeDetails.class, mySearchRuntimeDetails);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_SEARCH_FAILED, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_SEARCH_FAILED, params);
|
||||
|
||||
saveSearch();
|
||||
span.captureException(t);
|
||||
|
|
|
@ -63,7 +63,7 @@ import ca.uhn.fhir.jpa.searchparam.util.LastNParameterHelper;
|
|||
import ca.uhn.fhir.rest.api.SearchContainedModeEnum;
|
||||
import ca.uhn.fhir.jpa.util.BaseIterator;
|
||||
import ca.uhn.fhir.jpa.util.CurrentThreadCaptureQueriesListener;
|
||||
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.jpa.util.QueryChunker;
|
||||
import ca.uhn.fhir.jpa.util.SqlQueryList;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
|
@ -331,7 +331,7 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest)
|
||||
.add(SearchRuntimeDetails.class, theSearchRuntimeDetails);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.JPA_PERFTRACE_INDEXSEARCH_QUERY_COMPLETE, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.JPA_PERFTRACE_INDEXSEARCH_QUERY_COMPLETE, params);
|
||||
}
|
||||
|
||||
if (pids.isEmpty()) {
|
||||
|
@ -952,14 +952,14 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
// the user has a chance to know that they were in the results
|
||||
if (allAdded.size() > 0) {
|
||||
|
||||
if (JpaInterceptorBroadcaster.hasHooks(Pointcut.STORAGE_PREACCESS_RESOURCES, myInterceptorBroadcaster, theRequest)) {
|
||||
if (CompositeInterceptorBroadcaster.hasHooks(Pointcut.STORAGE_PREACCESS_RESOURCES, myInterceptorBroadcaster, theRequest)) {
|
||||
List<ResourcePersistentId> includedPidList = new ArrayList<>(allAdded);
|
||||
JpaPreResourceAccessDetails accessDetails = new JpaPreResourceAccessDetails(includedPidList, () -> this);
|
||||
HookParams params = new HookParams()
|
||||
.add(IPreResourceAccessDetails.class, accessDetails)
|
||||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.STORAGE_PREACCESS_RESOURCES, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.STORAGE_PREACCESS_RESOURCES, params);
|
||||
|
||||
for (int i = includedPidList.size() - 1; i >= 0; i--) {
|
||||
if (accessDetails.isDontReturnResourceAtIndex(i)) {
|
||||
|
@ -1060,7 +1060,7 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest)
|
||||
.add(StorageProcessingMessage.class, msg);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.JPA_PERFTRACE_INFO, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.JPA_PERFTRACE_INFO, params);
|
||||
|
||||
theQueryStack3.addPredicateCompositeUnique(indexString, myRequestPartitionId);
|
||||
|
||||
|
@ -1182,8 +1182,8 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
myStillNeedToFetchIncludes = true;
|
||||
}
|
||||
|
||||
myHavePerfTraceFoundIdHook = JpaInterceptorBroadcaster.hasHooks(Pointcut.JPA_PERFTRACE_SEARCH_FOUND_ID, myInterceptorBroadcaster, myRequest);
|
||||
myHaveRawSqlHooks = JpaInterceptorBroadcaster.hasHooks(Pointcut.JPA_PERFTRACE_RAW_SQL, myInterceptorBroadcaster, myRequest);
|
||||
myHavePerfTraceFoundIdHook = CompositeInterceptorBroadcaster.hasHooks(Pointcut.JPA_PERFTRACE_SEARCH_FOUND_ID, myInterceptorBroadcaster, myRequest);
|
||||
myHaveRawSqlHooks = CompositeInterceptorBroadcaster.hasHooks(Pointcut.JPA_PERFTRACE_RAW_SQL, myInterceptorBroadcaster, myRequest);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1239,7 +1239,7 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
HookParams params = new HookParams()
|
||||
.add(Integer.class, System.identityHashCode(this))
|
||||
.add(Object.class, nextLong);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_SEARCH_FOUND_ID, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_SEARCH_FOUND_ID, params);
|
||||
}
|
||||
|
||||
if (nextLong != null) {
|
||||
|
@ -1266,7 +1266,7 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
.add(RequestDetails.class, myRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, myRequest)
|
||||
.add(StorageProcessingMessage.class, message);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_WARNING, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_WARNING, params);
|
||||
|
||||
initializeIteratorQuery(myOffset, myMaxResultsToFetch);
|
||||
}
|
||||
|
@ -1308,7 +1308,7 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
.add(RequestDetails.class, myRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, myRequest)
|
||||
.add(SqlQueryList.class, capturedQueries);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_RAW_SQL, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_RAW_SQL, params);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1317,7 +1317,7 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
.add(RequestDetails.class, myRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, myRequest)
|
||||
.add(SearchRuntimeDetails.class, mySearchRuntimeDetails);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_SEARCH_FIRST_RESULT_LOADED, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_SEARCH_FIRST_RESULT_LOADED, params);
|
||||
myFirst = false;
|
||||
}
|
||||
|
||||
|
@ -1326,7 +1326,7 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
.add(RequestDetails.class, myRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, myRequest)
|
||||
.add(SearchRuntimeDetails.class, mySearchRuntimeDetails);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_SEARCH_SELECT_COMPLETE, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, myRequest, Pointcut.JPA_PERFTRACE_SEARCH_SELECT_COMPLETE, params);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ import ca.uhn.fhir.jpa.searchparam.ResourceMetaParams;
|
|||
import ca.uhn.fhir.jpa.searchparam.util.JpaParamUtil;
|
||||
import ca.uhn.fhir.rest.api.SearchContainedModeEnum;
|
||||
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
|
||||
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
|
@ -291,7 +291,7 @@ public class ResourceLinkPredicateBuilder extends BaseJoiningPredicateBuilder {
|
|||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest)
|
||||
.add(StorageProcessingMessage.class, msg);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.JPA_PERFTRACE_WARNING, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.JPA_PERFTRACE_WARNING, params);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -25,11 +25,10 @@ import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
|
|||
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedSearchParamUriDao;
|
||||
import ca.uhn.fhir.jpa.dao.predicate.SearchFilterParser;
|
||||
import ca.uhn.fhir.jpa.model.entity.BaseResourceIndexedSearchParam;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamUri;
|
||||
import ca.uhn.fhir.jpa.model.search.StorageProcessingMessage;
|
||||
import ca.uhn.fhir.jpa.search.builder.sql.SearchQueryBuilder;
|
||||
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.param.UriParam;
|
||||
|
@ -111,7 +110,7 @@ public class UriPredicateBuilder extends BaseSearchParamPredicateBuilder {
|
|||
.add(RequestDetails.class, theRequestDetails)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequestDetails)
|
||||
.add(StorageProcessingMessage.class, message);
|
||||
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequestDetails, Pointcut.JPA_PERFTRACE_WARNING, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequestDetails, Pointcut.JPA_PERFTRACE_WARNING, params);
|
||||
|
||||
Collection<String> candidates = myResourceIndexedSearchParamUriDao.findAllByResourceTypeAndParamName(getResourceType(), theParamName);
|
||||
List<String> toFind = new ArrayList<>();
|
||||
|
|
|
@ -27,6 +27,7 @@ import ca.uhn.fhir.rest.api.server.IPreResourceShowDetails;
|
|||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.api.server.SimplePreResourceShowDetails;
|
||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -51,7 +52,7 @@ public class InterceptorUtil {
|
|||
.add(IPreResourceShowDetails.class, accessDetails)
|
||||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest);
|
||||
JpaInterceptorBroadcaster.doCallHooks(theInterceptorBroadcaster, theRequest, Pointcut.STORAGE_PRESHOW_RESOURCES, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(theInterceptorBroadcaster, theRequest, Pointcut.STORAGE_PRESHOW_RESOURCES, params);
|
||||
|
||||
retVal = accessDetails.toList();
|
||||
retVal.removeIf(t -> t == null);
|
||||
|
|
|
@ -573,6 +573,10 @@ public abstract class BaseJpaR4Test extends BaseJpaTest implements ITestDataBuil
|
|||
return dao.update(theResource, mySrd).getId().toUnqualifiedVersionless();
|
||||
}
|
||||
|
||||
protected String encode(IBaseResource theResource) {
|
||||
return myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(theResource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FhirContext getFhirContext() {
|
||||
return myFhirCtx;
|
||||
|
|
|
@ -1142,11 +1142,6 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
|
|||
|
||||
}
|
||||
|
||||
private String encode(IBaseResource theResource) {
|
||||
return myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(theResource);
|
||||
}
|
||||
|
||||
|
||||
private OperationOutcome doTestValidateResourceContainingProfileDeclaration(String methodName, EncodingEnum enc) throws IOException {
|
||||
Bundle vss = loadResourceFromClasspath(Bundle.class, "/org/hl7/fhir/r4/model/valueset/valuesets.xml");
|
||||
myValueSetDao.update((ValueSet) findResourceByIdInBundle(vss, "observation-status"), mySrd);
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
package ca.uhn.fhir.jpa.interceptor.validation;
|
||||
|
||||
import ca.uhn.fhir.context.support.IValidationSupport;
|
||||
import ca.uhn.fhir.jpa.config.BaseConfig;
|
||||
import ca.uhn.fhir.jpa.provider.r4.BaseResourceProviderR4Test;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
|
||||
import ca.uhn.fhir.rest.server.interceptor.validation.ValidationMessageSuppressingInterceptor;
|
||||
import ca.uhn.fhir.validation.IValidatorModule;
|
||||
import ca.uhn.fhir.validation.ResultSeverityEnum;
|
||||
import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.r4.model.Coding;
|
||||
import org.hl7.fhir.r4.model.Encounter;
|
||||
import org.hl7.fhir.r4.model.Observation;
|
||||
import org.hl7.fhir.r4.model.OperationOutcome;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
import org.hl7.fhir.r4.model.Reference;
|
||||
import org.hl7.fhir.r5.utils.IResourceValidator;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.matchesPattern;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
public class ValidationMessageSuppressingInterceptorTest extends BaseResourceProviderR4Test {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ValidationMessageSuppressingInterceptorTest.class);
|
||||
@Autowired
|
||||
private ApplicationContext myApplicationContext;
|
||||
@Autowired
|
||||
private IValidationSupport myValidationSupport;
|
||||
|
||||
@Override
|
||||
@AfterEach
|
||||
public void after() throws Exception {
|
||||
super.after();
|
||||
myInterceptorRegistry.unregisterInterceptorsIf(t -> t instanceof RepositoryValidatingInterceptor);
|
||||
myInterceptorRegistry.unregisterInterceptorsIf(t -> t instanceof ValidationMessageSuppressingInterceptor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDaoValidation() throws IOException {
|
||||
upload("/r4/uscore/CodeSystem-dummy-loinc.json");
|
||||
upload("/r4/uscore/StructureDefinition-us-core-pulse-oximetry.json");
|
||||
|
||||
String input = loadResource("/r4/uscore/observation-pulseox.json");
|
||||
Observation inputObs = loadResource(myFhirCtx, Observation.class, "/r4/uscore/observation-pulseox.json");
|
||||
|
||||
try {
|
||||
myObservationDao.validate(inputObs, null, input, null, null, null, null);
|
||||
fail();
|
||||
} catch (PreconditionFailedException e) {
|
||||
// good
|
||||
}
|
||||
|
||||
ValidationMessageSuppressingInterceptor interceptor = new ValidationMessageSuppressingInterceptor();
|
||||
interceptor.addMessageSuppressionPatterns("Unknown code 'http://loinc.org#59408-5'");
|
||||
myInterceptorRegistry.registerInterceptor(interceptor);
|
||||
|
||||
MethodOutcome validationOutcome = myObservationDao.validate(inputObs, null, input, null, null, null, null);
|
||||
OperationOutcome oo = (OperationOutcome) validationOutcome.getOperationOutcome();
|
||||
String encode = encode(oo);
|
||||
ourLog.info(encode);
|
||||
assertThat(encode, containsString("All observations should have a performer"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestValidatingInterceptor() throws IOException {
|
||||
createPatient(withActiveTrue(), withId("AmyBaxter"));
|
||||
upload("/r4/uscore/CodeSystem-dummy-loinc.json");
|
||||
upload("/r4/uscore/StructureDefinition-us-core-pulse-oximetry.json");
|
||||
|
||||
|
||||
RequestValidatingInterceptor requestInterceptor = new RequestValidatingInterceptor();
|
||||
requestInterceptor.setFailOnSeverity(ResultSeverityEnum.ERROR);
|
||||
requestInterceptor.setValidatorModules(Collections.singletonList(new FhirInstanceValidator(myValidationSupport)));
|
||||
requestInterceptor.setInterceptorBroadcaster(myInterceptorRegistry);
|
||||
ourRestServer.registerInterceptor(requestInterceptor);
|
||||
|
||||
|
||||
// Without suppression
|
||||
{
|
||||
Observation inputObs = loadResource(myFhirCtx, Observation.class, "/r4/uscore/observation-pulseox.json");
|
||||
try {
|
||||
myClient.create().resource(inputObs).execute().getId().toUnqualifiedVersionless().getValue();
|
||||
fail();
|
||||
} catch (UnprocessableEntityException e) {
|
||||
String encode = encode(e.getOperationOutcome());
|
||||
ourLog.info(encode);
|
||||
assertThat(encode, containsString("Unknown code 'http://loinc.org#59408-5'"));
|
||||
}
|
||||
}
|
||||
|
||||
// With suppression
|
||||
ValidationMessageSuppressingInterceptor interceptor = new ValidationMessageSuppressingInterceptor();
|
||||
interceptor.addMessageSuppressionPatterns("Unknown code 'http://loinc.org#59408-5'");
|
||||
myInterceptorRegistry.registerInterceptor(interceptor);
|
||||
{
|
||||
Observation inputObs = loadResource(myFhirCtx, Observation.class, "/r4/uscore/observation-pulseox.json");
|
||||
String id = myClient.create().resource(inputObs).execute().getId().toUnqualifiedVersionless().getValue();
|
||||
assertThat(id, matchesPattern("Observation/[0-9]+"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRepositoryValidation() {
|
||||
createPatient(withActiveTrue(), withId("A"));
|
||||
|
||||
List<IRepositoryValidatingRule> rules = myApplicationContext.getBean(BaseConfig.REPOSITORY_VALIDATING_RULE_BUILDER, RepositoryValidatingRuleBuilder.class)
|
||||
.forResourcesOfType("Encounter")
|
||||
.requireValidationToDeclaredProfiles().withBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel.Ignore)
|
||||
.build();
|
||||
|
||||
RepositoryValidatingInterceptor repositoryValidatingInterceptor = new RepositoryValidatingInterceptor();
|
||||
repositoryValidatingInterceptor.setFhirContext(myFhirCtx);
|
||||
repositoryValidatingInterceptor.setRules(rules);
|
||||
myInterceptorRegistry.registerInterceptor(repositoryValidatingInterceptor);
|
||||
|
||||
// Without suppression
|
||||
try {
|
||||
Encounter encounter = new Encounter();
|
||||
encounter.setSubject(new Reference("Patient/A"));
|
||||
IIdType id = myEncounterDao.create(encounter).getId();
|
||||
assertEquals("1", id.getVersionIdPart());
|
||||
fail();
|
||||
} catch (PreconditionFailedException e) {
|
||||
String encode = encode(e.getOperationOutcome());
|
||||
ourLog.info(encode);
|
||||
assertThat(encode, containsString("Encounter.status: minimum required = 1"));
|
||||
}
|
||||
|
||||
// With suppression
|
||||
ValidationMessageSuppressingInterceptor interceptor = new ValidationMessageSuppressingInterceptor();
|
||||
interceptor.addMessageSuppressionPatterns("Encounter.status");
|
||||
interceptor.addMessageSuppressionPatterns("Encounter.class");
|
||||
myInterceptorRegistry.registerInterceptor(interceptor);
|
||||
|
||||
Encounter encounter = new Encounter();
|
||||
encounter.setSubject(new Reference("Patient/A"));
|
||||
IIdType id = myEncounterDao.create(encounter).getId().toUnqualifiedVersionless();
|
||||
assertThat(id.getValue(), matchesPattern("Encounter/[0-9]+"));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"resourceType": "CodeSystem",
|
||||
"id": "loinc",
|
||||
"url": "http://loinc.org",
|
||||
"version": "20160128",
|
||||
"name": "LOINC",
|
||||
"title": "ACME Codes for Cholesterol in Serum/Plasma",
|
||||
"status": "active",
|
||||
"experimental": true,
|
||||
"date": "2016-01-28",
|
||||
"publisher": "Acme Co",
|
||||
"description": "This is an example code system that includes all the ACME codes for serum/plasma cholesterol from v2.36.",
|
||||
"caseSensitive": true,
|
||||
"content": "complete",
|
||||
"concept": [
|
||||
{
|
||||
"code" : "59408-5",
|
||||
"display" : "Oxygen saturation in Arterial blood by Pulse oximetry"
|
||||
},
|
||||
{
|
||||
"code" : "3151-8",
|
||||
"display" : "Inhaled oxygen flow rate"
|
||||
},
|
||||
{
|
||||
"code": "2708-6",
|
||||
"display": "Oxygen saturation in Arterial blood"
|
||||
},
|
||||
{
|
||||
"code": "3150-0",
|
||||
"display": "Inhaled oxygen concentration"
|
||||
}
|
||||
]
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,92 @@
|
|||
{
|
||||
"resourceType": "Observation",
|
||||
"id": "satO2-fiO2",
|
||||
"meta": {
|
||||
"profile": [
|
||||
"http://hl7.org/fhir/us/core/StructureDefinition/us-core-pulse-oximetry"
|
||||
]
|
||||
},
|
||||
"text": {
|
||||
"status": "generated",
|
||||
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p><b>Generated Narrative</b></p><p><b>id</b>: satO2-fiO2</p><p><b>meta</b>: </p><p><b>identifier</b>: o1223435-10</p><p></p><p><b>category</b>: <span title=\"Codes: {http://terminology.hl7.org/CodeSystem/observation-category vital-signs}\">Vital Signs</span></p><p><b>code</b>: <span title=\"Codes: {http://loinc.org 2708-6}, {http://loinc.org 59408-5}, {urn:iso:std:iso:11073:10101 150456}\">Oxygen saturation in Arterial blood</span></p><p><b>subject</b>: <a href=\"Patient-example.html\">Generated Summary: id: example; Medical Record Number = 1032702 (USUAL); active; Amy V. Shaw , Amy V. Baxter ; ph: 555-555-5555(HOME), amy.shaw@example.com; gender: female; birthDate: 1987-02-20</a></p><p><b>effective</b>: Dec 5, 2014, 8:30:10 AM</p><p><b>value</b>: 95 %</p><p><b>interpretation</b>: <span title=\"Codes: {http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation N}\">Normal (applies to non-numeric results)</span></p><p><b>device</b>: <span>Acme Pulse Oximeter 2000</span></p><h3>ReferenceRanges</h3><table class=\"grid\"><tr><td>-</td><td><b>Low</b></td><td><b>High</b></td></tr><tr><td>*</td><td>90 %</td><td>99 %</td></tr></table><h3>Components</h3><table class=\"grid\"><tr><td>-</td><td><b>Code</b></td><td><b>Value[x]</b></td></tr><tr><td>*</td><td><span title=\"Codes: {http://loinc.org 3151-8}\">Inhaled oxygen flow rate</span></td><td>6 liters/min</td></tr></table></div>"
|
||||
},
|
||||
"identifier": [
|
||||
{
|
||||
"system": "http://goodcare.org/observation/id",
|
||||
"value": "o1223435-10"
|
||||
}
|
||||
],
|
||||
"status": "final",
|
||||
"category": [
|
||||
{
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://terminology.hl7.org/CodeSystem/observation-category",
|
||||
"code": "vital-signs",
|
||||
"display": "Vital Signs"
|
||||
}
|
||||
],
|
||||
"text": "Vital Signs"
|
||||
}
|
||||
],
|
||||
"code": {
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://loinc.org",
|
||||
"code": "2708-6",
|
||||
"display": "Oxygen saturation in Arterial blood"
|
||||
},
|
||||
{
|
||||
"system": "http://loinc.org",
|
||||
"code": "59408-5",
|
||||
"display": "Oxygen saturation in Arterial blood by Pulse oximetry"
|
||||
},
|
||||
{
|
||||
"system": "urn:iso:std:iso:11073:10101",
|
||||
"code": "150456",
|
||||
"display": "MDC_PULS_OXIM_SAT_O2"
|
||||
}
|
||||
]
|
||||
},
|
||||
"subject": {
|
||||
"reference": "Patient/AmyBaxter"
|
||||
},
|
||||
"effectiveDateTime": "2014-12-05T09:30:10+01:00",
|
||||
"valueQuantity": {
|
||||
"value": 95,
|
||||
"unit": "%",
|
||||
"system": "http://unitsofmeasure.org",
|
||||
"code": "%"
|
||||
},
|
||||
"interpretation": [
|
||||
{
|
||||
"coding": [
|
||||
{
|
||||
"system": "http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation",
|
||||
"code": "N",
|
||||
"display": "Normal"
|
||||
}
|
||||
],
|
||||
"text": "Normal (applies to non-numeric results)"
|
||||
}
|
||||
],
|
||||
"device": {
|
||||
"display": "Acme Pulse Oximeter 2000"
|
||||
},
|
||||
"referenceRange": [
|
||||
{
|
||||
"low": {
|
||||
"value": 90,
|
||||
"unit": "%",
|
||||
"system": "http://unitsofmeasure.org",
|
||||
"code": "%"
|
||||
},
|
||||
"high": {
|
||||
"value": 99,
|
||||
"unit": "%",
|
||||
"system": "http://unitsofmeasure.org",
|
||||
"code": "%"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
package ca.uhn.fhir.jpa.util;
|
||||
|
||||
/*-
|
||||
* #%L
|
||||
* HAPI FHIR JPA Model
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2021 Smile CDR, Inc.
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import ca.uhn.fhir.interceptor.api.HookParams;
|
||||
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class JpaInterceptorBroadcaster {
|
||||
|
||||
/**
|
||||
* Non instantiable
|
||||
*/
|
||||
private JpaInterceptorBroadcaster() {
|
||||
// nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast hooks to both the interceptor service associated with the request, as well
|
||||
* as the one associated with the JPA module.
|
||||
*/
|
||||
public static boolean doCallHooks(IInterceptorBroadcaster theInterceptorBroadcaster, @Nullable RequestDetails theRequestDetails, Pointcut thePointcut, HookParams theParams) {
|
||||
boolean retVal = true;
|
||||
if (theInterceptorBroadcaster != null) {
|
||||
retVal = theInterceptorBroadcaster.callHooks(thePointcut, theParams);
|
||||
}
|
||||
if (theRequestDetails != null && theRequestDetails.getInterceptorBroadcaster() != null && retVal) {
|
||||
IInterceptorBroadcaster interceptorBroadcaster = theRequestDetails.getInterceptorBroadcaster();
|
||||
interceptorBroadcaster.callHooks(thePointcut, theParams);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast hooks to both the interceptor service associated with the request, as well
|
||||
* as the one associated with the JPA module.
|
||||
*/
|
||||
public static Object doCallHooksAndReturnObject(IInterceptorBroadcaster theInterceptorBroadcaster, RequestDetails theRequestDetails, Pointcut thePointcut, HookParams theParams) {
|
||||
Object retVal = true;
|
||||
if (theInterceptorBroadcaster != null) {
|
||||
retVal = theInterceptorBroadcaster.callHooksAndReturnObject(thePointcut, theParams);
|
||||
}
|
||||
if (theRequestDetails != null && theRequestDetails.getInterceptorBroadcaster() != null && retVal == null) {
|
||||
IInterceptorBroadcaster interceptorBroadcaster = theRequestDetails.getInterceptorBroadcaster();
|
||||
retVal = interceptorBroadcaster.callHooksAndReturnObject(thePointcut, theParams);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public static boolean hasHooks(Pointcut thePointcut, IInterceptorBroadcaster theInterceptorBroadcaster, RequestDetails theRequestDetails) {
|
||||
if (theInterceptorBroadcaster != null && theInterceptorBroadcaster.hasHooks(thePointcut)) {
|
||||
return true;
|
||||
}
|
||||
return theRequestDetails != null &&
|
||||
theRequestDetails.getInterceptorBroadcaster() != null &&
|
||||
theRequestDetails.getInterceptorBroadcaster().hasHooks(thePointcut);
|
||||
}
|
||||
}
|
|
@ -44,7 +44,7 @@ import ca.uhn.fhir.jpa.model.entity.ResourceLink;
|
|||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.model.search.StorageProcessingMessage;
|
||||
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
|
||||
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
|
||||
|
@ -469,8 +469,8 @@ public class SearchParamExtractorService {
|
|||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setInterceptorBroadcasterForUnitTest(IInterceptorBroadcaster theJpaInterceptorBroadcaster) {
|
||||
myInterceptorBroadcaster = theJpaInterceptorBroadcaster;
|
||||
void setInterceptorBroadcasterForUnitTest(IInterceptorBroadcaster theInterceptorBroadcaster) {
|
||||
myInterceptorBroadcaster = theInterceptorBroadcaster;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
|
@ -491,7 +491,7 @@ public class SearchParamExtractorService {
|
|||
.add(RequestDetails.class, theRequestDetails)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequestDetails)
|
||||
.add(StorageProcessingMessage.class, messageHolder);
|
||||
JpaInterceptorBroadcaster.doCallHooks(theInterceptorBroadcaster, theRequestDetails, Pointcut.JPA_PERFTRACE_WARNING, params);
|
||||
CompositeInterceptorBroadcaster.doCallHooks(theInterceptorBroadcaster, theRequestDetails, Pointcut.JPA_PERFTRACE_WARNING, params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import ca.uhn.fhir.jpa.subscription.match.matcher.matching.IResourceModifiedCons
|
|||
import ca.uhn.fhir.jpa.subscription.match.matcher.subscriber.SubscriptionMatchingSubscriber;
|
||||
import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedJsonMessage;
|
||||
import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedMessage;
|
||||
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
@ -100,7 +100,7 @@ public class SubscriptionMatcherInterceptor implements IResourceModifiedConsumer
|
|||
// Interceptor call: SUBSCRIPTION_RESOURCE_MODIFIED
|
||||
HookParams params = new HookParams()
|
||||
.add(ResourceModifiedMessage.class, msg);
|
||||
boolean outcome = JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.SUBSCRIPTION_RESOURCE_MODIFIED, params);
|
||||
boolean outcome = CompositeInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.SUBSCRIPTION_RESOURCE_MODIFIED, params);
|
||||
if (!outcome) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -21,18 +21,23 @@ package ca.uhn.fhir.rest.server.interceptor;
|
|||
*/
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.interceptor.api.IInterceptorService;
|
||||
import ca.uhn.fhir.interceptor.api.Interceptor;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||
import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.util.OperationOutcomeUtil;
|
||||
import ca.uhn.fhir.validation.*;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.lang3.text.StrLookup;
|
||||
import org.apache.commons.lang3.text.StrSubstitutor;
|
||||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -55,7 +60,7 @@ public abstract class BaseValidatingInterceptor<T> extends ValidationResultEnric
|
|||
*/
|
||||
public static final String DEFAULT_RESPONSE_HEADER_VALUE = "${row}:${col} ${severity} ${message} (${location})";
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseValidatingInterceptor.class);
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(BaseValidatingInterceptor.class);
|
||||
|
||||
private Integer myAddResponseIssueHeaderOnSeverity = null;
|
||||
private Integer myAddResponseOutcomeHeaderOnSeverity = null;
|
||||
|
@ -68,6 +73,7 @@ public abstract class BaseValidatingInterceptor<T> extends ValidationResultEnric
|
|||
private String myResponseOutcomeHeaderName = provideDefaultResponseHeaderName();
|
||||
|
||||
private List<IValidatorModule> myValidatorModules;
|
||||
private IInterceptorBroadcaster myInterceptorBroadcaster;
|
||||
|
||||
private void addResponseIssueHeader(RequestDetails theRequestDetails, SingleValidationMessage theNext) {
|
||||
// Perform any string substitutions from the message format
|
||||
|
@ -279,6 +285,10 @@ public abstract class BaseValidatingInterceptor<T> extends ValidationResultEnric
|
|||
*/
|
||||
protected ValidationResult validate(T theRequest, RequestDetails theRequestDetails) {
|
||||
FhirValidator validator = theRequestDetails.getServer().getFhirContext().newValidator();
|
||||
|
||||
IInterceptorBroadcaster interceptorBroadcaster = CompositeInterceptorBroadcaster.newCompositeBroadcaster(myInterceptorBroadcaster, theRequestDetails);
|
||||
validator.setInterceptorBraodcaster(interceptorBroadcaster);
|
||||
|
||||
if (myValidatorModules != null) {
|
||||
for (IValidatorModule next : myValidatorModules) {
|
||||
validator.registerValidatorModule(next);
|
||||
|
@ -357,6 +367,14 @@ public abstract class BaseValidatingInterceptor<T> extends ValidationResultEnric
|
|||
return validationResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* This can be used to specify an interceptor to broadcast validation events through. This
|
||||
* is mostly intended for the
|
||||
*/
|
||||
public void setInterceptorBroadcaster(IInterceptorBroadcaster theInterceptorBroadcaster) {
|
||||
myInterceptorBroadcaster = theInterceptorBroadcaster;
|
||||
}
|
||||
|
||||
private static class MyLookup extends StrLookup<String> {
|
||||
|
||||
private SingleValidationMessage myMessage;
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
package ca.uhn.fhir.rest.server.interceptor.validation;
|
||||
|
||||
import ca.uhn.fhir.interceptor.api.Hook;
|
||||
import ca.uhn.fhir.interceptor.api.Interceptor;
|
||||
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||
import ca.uhn.fhir.validation.SingleValidationMessage;
|
||||
import ca.uhn.fhir.validation.ValidationResult;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
@Interceptor
|
||||
public class ValidationMessageSuppressingInterceptor {
|
||||
|
||||
private List<Pattern> mySuppressPatterns = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public ValidationMessageSuppressingInterceptor() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Supplies one or more patterns to suppress. Any validation messages (of any severity) will be suppressed
|
||||
* if they match this pattern. Patterns are in Java Regular Expression format (as defined by the {@link Pattern} class)
|
||||
* and are treated as partial maches. They are also case insensitive.
|
||||
* <p>
|
||||
* For example, a pattern of <code>loinc.*1234</code> would suppress the following message:<br/>
|
||||
* <code>The LOINC code 1234 is not valid</code>
|
||||
* </p>
|
||||
*/
|
||||
public ValidationMessageSuppressingInterceptor addMessageSuppressionPatterns(String... thePatterns) {
|
||||
return addMessageSuppressionPatterns(Arrays.asList(thePatterns));
|
||||
}
|
||||
|
||||
/**
|
||||
* Supplies one or more patterns to suppress. Any validation messages (of any severity) will be suppressed
|
||||
* if they match this pattern. Patterns are in Java Regular Expression format (as defined by the {@link Pattern} class)
|
||||
* and are treated as partial maches. They are also case insensitive.
|
||||
* <p>
|
||||
* For example, a pattern of <code>loinc.*1234</code> would suppress the following message:<br/>
|
||||
* <code>The LOINC code 1234 is not valid</code>
|
||||
* </p>
|
||||
*/
|
||||
public ValidationMessageSuppressingInterceptor addMessageSuppressionPatterns(List<String> thePatterns) {
|
||||
for (String next : thePatterns) {
|
||||
if (isNotBlank(next)) {
|
||||
Pattern pattern = Pattern.compile(next, Pattern.CASE_INSENSITIVE);
|
||||
mySuppressPatterns.add(pattern);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Hook(Pointcut.VALIDATION_COMPLETED)
|
||||
public ValidationResult handle(ValidationResult theResult) {
|
||||
|
||||
List<SingleValidationMessage> newMessages = new ArrayList<>(theResult.getMessages().size());
|
||||
for (SingleValidationMessage next : theResult.getMessages()) {
|
||||
|
||||
String nextMessage = next.getMessage();
|
||||
boolean suppress = false;
|
||||
for (Pattern nextSuppressPattern : mySuppressPatterns) {
|
||||
if (nextSuppressPattern.matcher(nextMessage).find()) {
|
||||
suppress = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!suppress) {
|
||||
newMessages.add(next);
|
||||
}
|
||||
}
|
||||
|
||||
if (newMessages.size() == theResult.getMessages().size()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ValidationResult(theResult.getContext(), newMessages);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
package ca.uhn.fhir.rest.server.util;
|
||||
|
||||
/*-
|
||||
* #%L
|
||||
* HAPI FHIR JPA Model
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2021 Smile CDR, Inc.
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import ca.uhn.fhir.interceptor.api.HookParams;
|
||||
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class CompositeInterceptorBroadcaster {
|
||||
|
||||
/**
|
||||
* Non instantiable
|
||||
*/
|
||||
private CompositeInterceptorBroadcaster() {
|
||||
// nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast hooks to both the interceptor service associated with the request, as well
|
||||
* as the one associated with the JPA module.
|
||||
*/
|
||||
public static boolean doCallHooks(IInterceptorBroadcaster theInterceptorBroadcaster, @Nullable RequestDetails theRequestDetails, Pointcut thePointcut, HookParams theParams) {
|
||||
return newCompositeBroadcaster(theInterceptorBroadcaster, theRequestDetails).callHooks(thePointcut, theParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast hooks to both the interceptor service associated with the request, as well
|
||||
* as the one associated with the JPA module.
|
||||
*/
|
||||
public static Object doCallHooksAndReturnObject(IInterceptorBroadcaster theInterceptorBroadcaster, RequestDetails theRequestDetails, Pointcut thePointcut, HookParams theParams) {
|
||||
return newCompositeBroadcaster(theInterceptorBroadcaster, theRequestDetails).callHooksAndReturnObject(thePointcut, theParams);
|
||||
}
|
||||
|
||||
public static boolean hasHooks(Pointcut thePointcut, IInterceptorBroadcaster theInterceptorBroadcaster, RequestDetails theRequestDetails) {
|
||||
return newCompositeBroadcaster(theInterceptorBroadcaster, theRequestDetails).hasHooks(thePointcut);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 5.5.0
|
||||
*/
|
||||
public static IInterceptorBroadcaster newCompositeBroadcaster(IInterceptorBroadcaster theInterceptorBroadcaster, RequestDetails theRequestDetails) {
|
||||
return new IInterceptorBroadcaster() {
|
||||
@Override
|
||||
public boolean callHooks(Pointcut thePointcut, HookParams theParams) {
|
||||
boolean retVal = true;
|
||||
if (theInterceptorBroadcaster != null) {
|
||||
retVal = theInterceptorBroadcaster.callHooks(thePointcut, theParams);
|
||||
}
|
||||
if (theRequestDetails != null && theRequestDetails.getInterceptorBroadcaster() != null && retVal) {
|
||||
IInterceptorBroadcaster interceptorBroadcaster = theRequestDetails.getInterceptorBroadcaster();
|
||||
interceptorBroadcaster.callHooks(thePointcut, theParams);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object callHooksAndReturnObject(Pointcut thePointcut, HookParams theParams) {
|
||||
Object retVal = true;
|
||||
if (theInterceptorBroadcaster != null) {
|
||||
retVal = theInterceptorBroadcaster.callHooksAndReturnObject(thePointcut, theParams);
|
||||
}
|
||||
if (theRequestDetails != null && theRequestDetails.getInterceptorBroadcaster() != null && retVal == null) {
|
||||
IInterceptorBroadcaster interceptorBroadcaster = theRequestDetails.getInterceptorBroadcaster();
|
||||
retVal = interceptorBroadcaster.callHooksAndReturnObject(thePointcut, theParams);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasHooks(Pointcut thePointcut) {
|
||||
if (theInterceptorBroadcaster != null && theInterceptorBroadcaster.hasHooks(thePointcut)) {
|
||||
return true;
|
||||
}
|
||||
return theRequestDetails != null &&
|
||||
theRequestDetails.getInterceptorBroadcaster() != null &&
|
||||
theRequestDetails.getInterceptorBroadcaster().hasHooks(thePointcut);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue