Skip to content

Commit

Permalink
Validate contains change (#3209)
Browse files Browse the repository at this point in the history
* wip

* The updated changes to the validator that were pulled in from the core dependencies are not backwards compat. Need to bump HAPI version.

* pointing to stable core version

* review feedback

* Add changelog

Co-authored-by: markiantorno <[email protected]>
  • Loading branch information
markiantorno and markiantorno committed Dec 6, 2021
1 parent c4ec767 commit d60d07b
Show file tree
Hide file tree
Showing 35 changed files with 806 additions and 977 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public class FhirValidator {
private static volatile Boolean ourPhPresentOnClasspath;
private final FhirContext myContext;
private List<IValidatorModule> myValidators = new ArrayList<>();
private IInterceptorBroadcaster myInterceptorBraodcaster;
private IInterceptorBroadcaster myInterceptorBroadcaster;

/**
* Constructor (this should not be called directly, but rather {@link FhirContext#newValidator()} should be called to obtain an instance of {@link FhirValidator})
Expand Down Expand Up @@ -227,13 +227,13 @@ public ValidationResult validateWithResult(IBaseResource theResource, Validation
}

private ValidationResult invokeValidationCompletedHooks(IBaseResource theResourceParsed, String theResourceRaw, ValidationResult theValidationResult) {
if (myInterceptorBraodcaster != null) {
if (myInterceptorBraodcaster.hasHooks(Pointcut.VALIDATION_COMPLETED)) {
if (myInterceptorBroadcaster != null) {
if (myInterceptorBroadcaster.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);
Object newResult = myInterceptorBroadcaster.callHooksAndReturnObject(Pointcut.VALIDATION_COMPLETED, params);
if (newResult != null) {
theValidationResult = (ValidationResult) newResult;
}
Expand Down Expand Up @@ -272,6 +272,6 @@ public ValidationResult validateWithResult(String theResource, ValidationOptions
* @since 5.5.0
*/
public void setInterceptorBroadcaster(IInterceptorBroadcaster theInterceptorBraodcaster) {
myInterceptorBraodcaster = theInterceptorBraodcaster;
myInterceptorBroadcaster = theInterceptorBraodcaster;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
type: change
issue: 3205
title: "These changes are related to bumping the dependency on org.hl7.fhir.core to version 5.3.0.
The main updates that resulted in the majority of the changes in this PR were the addition of the interface IValidationPolicyAdvisor,
and the refactoring of some of the main validation classes (for cleaning purposes). Also, many of the error messages were
updated, so the resulting tests in HAPI had to be modified to reflect these message changes.
In regard to the new interface IValidationPolicyAdvisor, by implementing this interface and passing it through the
validation context in HAPI to the InstanceValidator in the core libraries, users can now control the behavior of the
validator when validating references, contained resources, and coded content. Previously, only references were controlled
in this way, and users controlled this by overriding the validation fetcher.
Test cases were added in the validation test cases repository to demonstrate it's functionality. In particular, the two
test cases contained-resource-bad-id, and contained-resource-bad-id-ignore. The definitions and expected outcomes of
these test cases are in the manifest.json in that repository."
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

# Changelog: 2020

<th:block th:insert="fragment_changelog.md :: changelog('2020', '2020')"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,12 @@
import ca.uhn.fhir.jpa.term.api.ITermReindexingSvc;
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
import ca.uhn.fhir.jpa.validation.JpaValidationSupportChain;
import ca.uhn.fhir.jpa.validation.ValidatorPolicyAdvisor;
import ca.uhn.fhir.jpa.validation.ValidatorResourceFetcher;
import ca.uhn.fhir.validation.IInstanceValidatorModule;
import org.hl7.fhir.common.hapi.validation.support.CachingValidationSupport;
import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator;
import org.hl7.fhir.r5.utils.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
Expand Down Expand Up @@ -95,7 +96,8 @@ public IValidationSupport validationSupportChain() {
public IInstanceValidatorModule instanceValidator() {
FhirInstanceValidator val = new FhirInstanceValidator(validationSupportChain());
val.setValidatorResourceFetcher(jpaValidatorResourceFetcher());
val.setBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel.Warning);
val.setValidatorPolicyAdvisor(jpaValidatorPolicyAdvisor());
val.setBestPracticeWarningLevel(BestPracticeWarningLevel.Warning);
val.setValidationSupport(validationSupportChain());
return val;
}
Expand All @@ -106,6 +108,12 @@ public ValidatorResourceFetcher jpaValidatorResourceFetcher() {
return new ValidatorResourceFetcher();
}

@Bean
@Lazy
public ValidatorPolicyAdvisor jpaValidatorPolicyAdvisor() {
return new ValidatorPolicyAdvisor();
}

@Bean
public abstract ITermReadSvc terminologyService();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import org.hl7.fhir.common.hapi.validation.support.ValidationSupportChain;
import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator;
import org.hl7.fhir.common.hapi.validation.validator.HapiToHl7OrgDstu2ValidatingSupportWrapper;
import org.hl7.fhir.r5.utils.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand Down Expand Up @@ -91,7 +91,7 @@ public FhirContext fhirContextDstu2Hl7Org() {
public IInstanceValidatorModule instanceValidator(ValidationSupportChain theValidationSupportChain) {
CachingValidationSupport cachingValidationSupport = new CachingValidationSupport(new HapiToHl7OrgDstu2ValidatingSupportWrapper(theValidationSupportChain));
FhirInstanceValidator retVal = new FhirInstanceValidator(cachingValidationSupport);
retVal.setBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel.Warning);
retVal.setBestPracticeWarningLevel(BestPracticeWarningLevel.Warning);
return retVal;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import org.hl7.fhir.dstu3.model.Observation.ObservationStatus;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r5.utils.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Disabled;
Expand Down Expand Up @@ -121,15 +121,15 @@ public void testExpandLocalCodeSystemWithExplicitCodes() throws IOException {
@AfterEach
public void after() {
FhirInstanceValidator val = AopTestUtils.getTargetObject(myValidatorModule);
val.setBestPracticeWarningLevel(org.hl7.fhir.r5.utils.IResourceValidator.BestPracticeWarningLevel.Warning);
val.setBestPracticeWarningLevel(BestPracticeWarningLevel.Warning);
}


@Test
public void testValidateWithCanonicalReference() {
FhirInstanceValidator val = AopTestUtils.getTargetObject(myValidatorModule);
org.hl7.fhir.r5.utils.IResourceValidator.BestPracticeWarningLevel a = IResourceValidator.BestPracticeWarningLevel.Ignore;
val.setBestPracticeWarningLevel(a);
BestPracticeWarningLevel bestPracticeWarningLevel = BestPracticeWarningLevel.Ignore;
val.setBestPracticeWarningLevel(bestPracticeWarningLevel);

ValueSet vs = new ValueSet();
vs.setId("MYVS");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,15 @@
import org.hl7.fhir.r4.model.Task;
import org.hl7.fhir.r4.model.UriType;
import org.hl7.fhir.r4.model.ValueSet;
import org.hl7.fhir.r5.utils.IResourceValidator;
import org.hl7.fhir.r5.elementmodel.Element;
import org.hl7.fhir.r5.model.ElementDefinition;
import org.hl7.fhir.r5.utils.validation.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor;
import org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel;
import org.hl7.fhir.r5.utils.validation.constants.BindingKind;
import org.hl7.fhir.r5.utils.validation.constants.CodedContentValidationPolicy;
import org.hl7.fhir.r5.utils.validation.constants.ContainedReferenceValidationPolicy;
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
Expand Down Expand Up @@ -605,14 +613,32 @@ protected <T extends IBaseResource> T loadResourceFromClasspath(Class<T> type, S
protected void validate(IBaseResource theResource) {
FhirValidator validatorModule = myFhirCtx.newValidator();
FhirInstanceValidator instanceValidator = new FhirInstanceValidator(myValidationSupport);
instanceValidator.setBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel.Ignore);
instanceValidator.setBestPracticeWarningLevel(BestPracticeWarningLevel.Ignore);
instanceValidator.setValidatorPolicyAdvisor(new ValidationPolicyAdvisor());
validatorModule.registerValidatorModule(instanceValidator);
ValidationResult result = validatorModule.validateWithResult(theResource);
if (!result.isSuccessful()) {
fail(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(result.toOperationOutcome()));
}
}

public class ValidationPolicyAdvisor implements IValidationPolicyAdvisor {
@Override
public ReferenceValidationPolicy policyForReference(IResourceValidator validator, Object appContext, String path, String url) {
return ReferenceValidationPolicy.CHECK_VALID;
}

@Override
public CodedContentValidationPolicy policyForCodedContent(IResourceValidator iResourceValidator, Object o, String s, ElementDefinition elementDefinition, org.hl7.fhir.r5.model.StructureDefinition structureDefinition, BindingKind bindingKind, org.hl7.fhir.r5.model.ValueSet valueSet, List<String> list) {
return CodedContentValidationPolicy.CODE;
}

@Override
public ContainedReferenceValidationPolicy policyForContained(IResourceValidator validator, Object appContext, String containerType, String containerId, Element.SpecialElement containingResourceType, String path, String url) {
return ContainedReferenceValidationPolicy.CHECK_VALID;
}
}

@SuppressWarnings("unchecked")
protected void upload(String theClasspath) throws IOException {
String resource = loadResource(theClasspath);
Expand Down
Loading

0 comments on commit d60d07b

Please sign in to comment.