merge 'validate_contains_change' into issue-3144-multi-threaded-bundle-validation

This commit is contained in:
Jaison B 2021-12-03 09:13:15 -07:00
parent fefbac8df7
commit c7d60fc3e6
89 changed files with 866 additions and 1042 deletions

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -65,7 +65,7 @@ public class FhirValidator {
private static volatile Boolean ourPhPresentOnClasspath;
private final FhirContext myContext;
private List<IValidatorModule> myValidators = new ArrayList<>();
private IInterceptorBroadcaster myInterceptorBraodcaster;
private IInterceptorBroadcaster iInterceptorBroadcaster;
private boolean myConcurrentBundleValidation;
private ExecutorService myExecutorService;
@ -305,13 +305,13 @@ public class FhirValidator {
}
private ValidationResult invokeValidationCompletedHooks(IBaseResource theResourceParsed, String theResourceRaw, ValidationResult theValidationResult) {
if (myInterceptorBraodcaster != null) {
if (myInterceptorBraodcaster.hasHooks(Pointcut.VALIDATION_COMPLETED)) {
if (iInterceptorBroadcaster != null) {
if (iInterceptorBroadcaster.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 = iInterceptorBroadcaster.callHooksAndReturnObject(Pointcut.VALIDATION_COMPLETED, params);
if (newResult != null) {
theValidationResult = (ValidationResult) newResult;
}
@ -326,7 +326,7 @@ public class FhirValidator {
* @since 5.5.0
*/
public void setInterceptorBroadcaster(IInterceptorBroadcaster theInterceptorBraodcaster) {
myInterceptorBraodcaster = theInterceptorBraodcaster;
iInterceptorBroadcaster = theInterceptorBraodcaster;
}
public FhirValidator setExecutorService(ExecutorService theExecutorService) {

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -10,7 +10,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-cli</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../../hapi-deployable-pom</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -11,7 +11,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -34,11 +34,12 @@ import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
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;
@ -96,7 +97,8 @@ public abstract class BaseConfigDstu3Plus extends BaseConfig {
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;
}
@ -107,6 +109,12 @@ public abstract class BaseConfigDstu3Plus extends BaseConfig {
return new ValidatorResourceFetcher();
}
@Bean
@Lazy
public ValidatorPolicyAdvisor jpaValidatorPolicyAdvisor() {
return new ValidatorPolicyAdvisor();
}
@Bean
public abstract ITermReadSvc terminologyService();

View File

@ -22,7 +22,7 @@ import org.hl7.fhir.common.hapi.validation.support.InMemoryTerminologyServerVali
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;
@ -91,7 +91,7 @@ public class BaseDstu2Config extends BaseConfig {
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;
}

View File

@ -21,7 +21,7 @@ import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
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;
@ -121,14 +121,14 @@ public class FhirResourceDaoDstu3ValidateTest extends BaseJpaDstu3Test {
@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;
BestPracticeWarningLevel a = BestPracticeWarningLevel.Ignore;
val.setBestPracticeWarningLevel(a);
ValueSet vs = new ValueSet();

View File

@ -156,7 +156,15 @@ import org.hl7.fhir.r4.model.Substance;
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;
@ -602,7 +610,8 @@ public abstract class BaseJpaR4Test extends BaseJpaTest implements ITestDataBuil
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()) {
@ -610,6 +619,23 @@ public abstract class BaseJpaR4Test extends BaseJpaTest implements ITestDataBuil
}
}
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);

View File

@ -65,7 +65,8 @@ import org.hl7.fhir.r4.model.StringType;
import org.hl7.fhir.r4.model.StructureDefinition;
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.utils.validation.constants.BestPracticeWarningLevel;
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@ -109,7 +110,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
@AfterEach
public void after() {
FhirInstanceValidator val = AopTestUtils.getTargetObject(myValidatorModule);
val.setBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel.Warning);
val.setBestPracticeWarningLevel(BestPracticeWarningLevel.Warning);
myDaoConfig.setAllowExternalReferences(new DaoConfig().isAllowExternalReferences());
myDaoConfig.setMaximumExpansionSize(DaoConfig.DEFAULT_MAX_EXPANSION_SIZE);
@ -117,7 +118,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
BaseTermReadSvcImpl.setInvokeOnNextCallForUnitTest(null);
myValidationSettings.setLocalReferenceValidationDefaultPolicy(IResourceValidator.ReferenceValidationPolicy.IGNORE);
myValidationSettings.setLocalReferenceValidationDefaultPolicy(ReferenceValidationPolicy.IGNORE);
myFhirCtx.setParserErrorHandler(new StrictErrorHandler());
myUnknownCodeSystemWarningValidationSupport.setNonExistentCodeSystemSeverity(UnknownCodeSystemWarningValidationSupport.DEFAULT_SEVERITY);
@ -481,25 +482,25 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem("http://loinc.org").setCode("non-existing-code").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs);
assertEquals("None of the codings provided are in the value set http://example.com/fhir/ValueSet/observation-vitalsignresult (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a coding from this value set is required) (codes = http://loinc.org#non-existing-code)", oo.getIssueFirstRep().getDiagnostics(), encode(oo));
assertEquals("None of the codings provided are in the value set 'ValueSet[http://example.com/fhir/ValueSet/observation-vitalsignresult]' (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a coding from this value set is required) (codes = http://loinc.org#non-existing-code)", oo.getIssueFirstRep().getDiagnostics(), encode(oo));
// Valid code with no system
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem(null).setCode("CODE3").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs);
assertEquals("None of the codings provided are in the value set http://example.com/fhir/ValueSet/observation-vitalsignresult (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a coding from this value set is required) (codes = null#CODE3)", oo.getIssueFirstRep().getDiagnostics(), encode(oo));
assertThat(encode(oo), containsString("None of the codings provided are in the value set 'ValueSet[http://example.com/fhir/ValueSet/observation-vitalsignresult]' (http://example.com/fhir/ValueSet/observation-vitalsignresult)"));
// Valid code with wrong system
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem("http://foo").setCode("CODE3").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs);
assertEquals("None of the codings provided are in the value set http://example.com/fhir/ValueSet/observation-vitalsignresult (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a coding from this value set is required) (codes = http://foo#CODE3)", oo.getIssueFirstRep().getDiagnostics(), encode(oo));
assertEquals("None of the codings provided are in the value set 'ValueSet[http://example.com/fhir/ValueSet/observation-vitalsignresult]' (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a coding from this value set is required) (codes = http://foo#CODE3)", oo.getIssueFirstRep().getDiagnostics(), encode(oo));
// Code that exists but isn't in the valueset
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem("http://terminology.hl7.org/CodeSystem/observation-category").setCode("vital-signs").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs);
assertEquals("None of the codings provided are in the value set http://example.com/fhir/ValueSet/observation-vitalsignresult (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a coding from this value set is required) (codes = http://terminology.hl7.org/CodeSystem/observation-category#vital-signs)", oo.getIssueFirstRep().getDiagnostics(), encode(oo));
assertEquals("None of the codings provided are in the value set 'ValueSet[http://example.com/fhir/ValueSet/observation-vitalsignresult]' (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a coding from this value set is required) (codes = http://terminology.hl7.org/CodeSystem/observation-category#vital-signs)", oo.getIssueFirstRep().getDiagnostics(), encode(oo));
// Invalid code in built-in VS/CS
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
@ -531,7 +532,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
@Test
public void testValidateProfileTargetType_PolicyCheckValid() throws IOException {
myValidationSettings.setLocalReferenceValidationDefaultPolicy(IResourceValidator.ReferenceValidationPolicy.CHECK_VALID);
myValidationSettings.setLocalReferenceValidationDefaultPolicy(ReferenceValidationPolicy.CHECK_VALID);
StructureDefinition profile = loadResourceFromClasspath(StructureDefinition.class, "/r4/profile-vitalsigns-all-loinc.json");
myStructureDefinitionDao.create(profile, mySrd);
@ -599,7 +600,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
@Test
public void testValidateProfileTargetType_PolicyCheckExistsAndType() throws IOException {
myValidationSettings.setLocalReferenceValidationDefaultPolicy(IResourceValidator.ReferenceValidationPolicy.CHECK_EXISTS_AND_TYPE);
myValidationSettings.setLocalReferenceValidationDefaultPolicy(ReferenceValidationPolicy.CHECK_EXISTS_AND_TYPE);
StructureDefinition profile = loadResourceFromClasspath(StructureDefinition.class, "/r4/profile-vitalsigns-all-loinc.json");
myStructureDefinitionDao.create(profile, mySrd);
@ -667,7 +668,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
@Test
public void testValidateProfileTargetType_PolicyCheckExists() throws IOException {
myValidationSettings.setLocalReferenceValidationDefaultPolicy(IResourceValidator.ReferenceValidationPolicy.CHECK_EXISTS);
myValidationSettings.setLocalReferenceValidationDefaultPolicy(ReferenceValidationPolicy.CHECK_EXISTS);
StructureDefinition profile = loadResourceFromClasspath(StructureDefinition.class, "/r4/profile-vitalsigns-all-loinc.json");
myStructureDefinitionDao.create(profile, mySrd);
@ -860,7 +861,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
} catch (PreconditionFailedException e) {
outcome = (OperationOutcome) e.getOperationOutcome();
ourLog.info("Outcome: {}", myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome));
assertEquals("None of the codings provided are in the value set http://example.com/valueset (http://example.com/valueset), and a coding from this value set is required) (codes = http://example.com/foo-foo#some-code)", outcome.getIssueFirstRep().getDiagnostics());
assertEquals("None of the codings provided are in the value set 'MessageCategory' (http://example.com/valueset), and a coding from this value set is required) (codes = http://example.com/foo-foo#some-code)", outcome.getIssueFirstRep().getDiagnostics());
assertEquals(OperationOutcome.IssueSeverity.ERROR, outcome.getIssueFirstRep().getSeverity());
}
}
@ -933,25 +934,25 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem("http://loinc.org").setCode("non-existing-code").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs);
assertEquals("None of the codings provided are in the value set http://example.com/fhir/ValueSet/observation-vitalsignresult (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a coding from this value set is required) (codes = http://loinc.org#non-existing-code)", oo.getIssueFirstRep().getDiagnostics(), encode(oo));
assertEquals("None of the codings provided are in the value set 'ValueSet[http://example.com/fhir/ValueSet/observation-vitalsignresult]' (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a coding from this value set is required) (codes = http://loinc.org#non-existing-code)", oo.getIssueFirstRep().getDiagnostics(), encode(oo));
// Valid code with no system
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem(null).setCode("CODE3").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs);
assertEquals("None of the codings provided are in the value set http://example.com/fhir/ValueSet/observation-vitalsignresult (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a coding from this value set is required) (codes = null#CODE3)", oo.getIssueFirstRep().getDiagnostics(), encode(oo));
assertThat(encode(oo), containsString("None of the codings provided are in the value set 'ValueSet[http://example.com/fhir/ValueSet/observation-vitalsignresult]' (http://example.com/fhir/ValueSet/observation-vitalsignresult)"));
// Valid code with wrong system
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem("http://foo").setCode("CODE3").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs);
assertEquals("None of the codings provided are in the value set http://example.com/fhir/ValueSet/observation-vitalsignresult (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a coding from this value set is required) (codes = http://foo#CODE3)", oo.getIssueFirstRep().getDiagnostics(), encode(oo));
assertEquals("None of the codings provided are in the value set 'ValueSet[http://example.com/fhir/ValueSet/observation-vitalsignresult]' (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a coding from this value set is required) (codes = http://foo#CODE3)", oo.getIssueFirstRep().getDiagnostics(), encode(oo));
// Code that exists but isn't in the valueset
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem("http://terminology.hl7.org/CodeSystem/observation-category").setCode("vital-signs").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs);
assertEquals("None of the codings provided are in the value set http://example.com/fhir/ValueSet/observation-vitalsignresult (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a coding from this value set is required) (codes = http://terminology.hl7.org/CodeSystem/observation-category#vital-signs)", oo.getIssueFirstRep().getDiagnostics(), encode(oo));
assertEquals("None of the codings provided are in the value set 'ValueSet[http://example.com/fhir/ValueSet/observation-vitalsignresult]' (http://example.com/fhir/ValueSet/observation-vitalsignresult), and a coding from this value set is required) (codes = http://terminology.hl7.org/CodeSystem/observation-category#vital-signs)", oo.getIssueFirstRep().getDiagnostics(), encode(oo));
// Invalid code in built-in VS/CS
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
@ -1089,7 +1090,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
ourLog.info(myFhirCtx.newJsonParser().encodeResourceToString(allergy));
OperationOutcome oo = validateAndReturnOutcome(allergy);
assertThat(encode(oo), containsString("None of the codings provided are in the value set http://hl7.org/fhir/ValueSet/allergyintolerance-clinical"));
assertThat(encode(oo), containsString("None of the codings provided are in the value set 'AllergyIntolerance Clinical Status Codes' (http://hl7.org/fhir/ValueSet/allergyintolerance-clinical|4.0.1)"));
}
@SuppressWarnings("unchecked")
@ -1199,7 +1200,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
// It would be ok for this to produce 0 issues, or just an information message too
assertEquals(1, OperationOutcomeUtil.getIssueCount(myFhirCtx, oo));
assertEquals("None of the codings provided are in the value set http://hl7.org/fhir/ValueSet/identifier-type (http://hl7.org/fhir/ValueSet/identifier-type), and a coding should come from this value set unless it has no suitable code (note that the validator cannot judge what is suitable) (codes = http://foo#bar)", OperationOutcomeUtil.getFirstIssueDetails(myFhirCtx, oo));
assertEquals("None of the codings provided are in the value set 'IdentifierType' (http://hl7.org/fhir/ValueSet/identifier-type), and a coding should come from this value set unless it has no suitable code (note that the validator cannot judge what is suitable) (codes = http://foo#bar)", OperationOutcomeUtil.getFirstIssueDetails(myFhirCtx, oo));
}
@ -1321,7 +1322,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
@Test
public void testValidateWithCanonicalReference() {
FhirInstanceValidator val = AopTestUtils.getTargetObject(myValidatorModule);
val.setBestPracticeWarningLevel(org.hl7.fhir.r5.utils.IResourceValidator.BestPracticeWarningLevel.Ignore);
val.setBestPracticeWarningLevel(BestPracticeWarningLevel.Ignore);
ValueSet vs = new ValueSet();
vs.setId("MYVS");
@ -1686,7 +1687,8 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
} catch (PreconditionFailedException e) {
OperationOutcome oo = (OperationOutcome) e.getOperationOutcome();
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo));
assertThat(oo.getIssueFirstRep().getDiagnostics(), containsString("None of the codings provided are in the value set http://hl7.org/fhir/ValueSet/condition-clinical"));
assertThat(oo.getIssueFirstRep().getDiagnostics(),
containsString("None of the codings provided are in the value set 'Condition Clinical Status Codes' (http://hl7.org/fhir/ValueSet/condition-clinical|4.0.1), and a coding from this value set is required) (codes = http://terminology.hl7.org/CodeSystem/condition-clinical/wrong-system#notrealcode)"));
}
}

View File

@ -130,7 +130,7 @@ import org.hl7.fhir.r5.model.Substance;
import org.hl7.fhir.r5.model.Task;
import org.hl7.fhir.r5.model.UriType;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.utils.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
@ -512,7 +512,7 @@ public abstract class BaseJpaR5Test extends BaseJpaTest implements ITestDataBuil
protected void validate(IBaseResource theResource) {
FhirValidator validatorModule = myFhirCtx.newValidator();
FhirInstanceValidator instanceValidator = new FhirInstanceValidator(myValidationSupport);
instanceValidator.setBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel.Ignore);
instanceValidator.setBestPracticeWarningLevel(BestPracticeWarningLevel.Ignore);
validatorModule.registerValidatorModule(instanceValidator);
ValidationResult result = validatorModule.validateWithResult(theResource);
if (!result.isSuccessful()) {

View File

@ -14,7 +14,7 @@ import org.hl7.fhir.r4.model.OperationOutcome;
import org.hl7.fhir.r4.model.Parameters;
import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.StringType;
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.BeforeEach;
import org.junit.jupiter.api.Test;
@ -370,7 +370,7 @@ public class RepositoryValidatingInterceptorR4Test extends BaseJpaR4Test {
.requireAtLeastProfile("http://hl7.org/fhir/StructureDefinition/Observation")
.and()
.requireValidationToDeclaredProfiles()
.withBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel.Ignore)
.withBestPracticeWarningLevel(BestPracticeWarningLevel.Ignore)
.build();
myValInterceptor.setRules(rules);

View File

@ -15,7 +15,7 @@ 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.Reference;
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.Test;
import org.springframework.beans.factory.annotation.Autowired;
@ -118,7 +118,7 @@ public class ValidationMessageSuppressingInterceptorTest extends BaseResourcePro
List<IRepositoryValidatingRule> rules = myApplicationContext.getBean(RepositoryValidatingRuleBuilder.REPOSITORY_VALIDATING_RULE_BUILDER, RepositoryValidatingRuleBuilder.class)
.forResourcesOfType("Encounter")
.requireValidationToDeclaredProfiles().withBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel.Ignore)
.requireValidationToDeclaredProfiles().withBestPracticeWarningLevel(BestPracticeWarningLevel.Ignore)
.build();
RepositoryValidatingInterceptor repositoryValidatingInterceptor = new RepositoryValidatingInterceptor();

View File

@ -7,7 +7,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -22,7 +22,7 @@ import org.hibernate.search.backend.lucene.cfg.LuceneIndexSettings;
import org.hibernate.search.engine.cfg.BackendSettings;
import org.hibernate.search.mapper.orm.cfg.HibernateOrmMapperSettings;
import org.hl7.fhir.dstu2.model.Subscription;
import org.hl7.fhir.r5.utils.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.annotation.Bean;
@ -96,7 +96,7 @@ public class TestDstu2Config extends BaseJavaConfigDstu2 {
@Bean
public ValidationSettings validationSettings() {
ValidationSettings retVal = super.validationSettings();
retVal.setLocalReferenceValidationDefaultPolicy(IResourceValidator.ReferenceValidationPolicy.CHECK_VALID);
retVal.setLocalReferenceValidationDefaultPolicy(ReferenceValidationPolicy.CHECK_VALID);
return retVal;
}

View File

@ -21,7 +21,7 @@ import org.hibernate.search.backend.lucene.cfg.LuceneIndexSettings;
import org.hibernate.search.engine.cfg.BackendSettings;
import org.hibernate.search.mapper.orm.cfg.HibernateOrmMapperSettings;
import org.hl7.fhir.dstu2.model.Subscription;
import org.hl7.fhir.r5.utils.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
@ -93,7 +93,7 @@ public class TestDstu3Config extends BaseJavaConfigDstu3 {
@Bean
public ValidationSettings validationSettings() {
ValidationSettings retVal = super.validationSettings();
retVal.setLocalReferenceValidationDefaultPolicy(IResourceValidator.ReferenceValidationPolicy.CHECK_VALID);
retVal.setLocalReferenceValidationDefaultPolicy(ReferenceValidationPolicy.CHECK_VALID);
return retVal;
}

View File

@ -18,7 +18,7 @@ import org.hibernate.search.backend.lucene.cfg.LuceneBackendSettings;
import org.hibernate.search.backend.lucene.cfg.LuceneIndexSettings;
import org.hibernate.search.engine.cfg.BackendSettings;
import org.hl7.fhir.dstu2.model.Subscription;
import org.hl7.fhir.r5.utils.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
@ -90,7 +90,7 @@ public class TestR4Config extends BaseJavaConfigR4 {
@Bean
public ValidationSettings validationSettings() {
ValidationSettings retVal = super.validationSettings();
retVal.setLocalReferenceValidationDefaultPolicy(IResourceValidator.ReferenceValidationPolicy.CHECK_VALID);
retVal.setLocalReferenceValidationDefaultPolicy(ReferenceValidationPolicy.CHECK_VALID);
return retVal;
}

View File

@ -21,7 +21,7 @@ import org.hibernate.search.backend.lucene.cfg.LuceneIndexSettings;
import org.hibernate.search.engine.cfg.BackendSettings;
import org.hibernate.search.mapper.orm.cfg.HibernateOrmMapperSettings;
import org.hl7.fhir.dstu2.model.Subscription;
import org.hl7.fhir.r5.utils.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
@ -92,7 +92,7 @@ public class TestR5Config extends BaseJavaConfigR5 {
@Bean
public ValidationSettings validationSettings() {
ValidationSettings retVal = super.validationSettings();
retVal.setLocalReferenceValidationDefaultPolicy(IResourceValidator.ReferenceValidationPolicy.CHECK_VALID);
retVal.setLocalReferenceValidationDefaultPolicy(ReferenceValidationPolicy.CHECK_VALID);
return retVal;
}

View File

@ -7,7 +7,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
</parent>
<artifactId>hapi-fhir-spring-boot-sample-client-apache</artifactId>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
</parent>
<artifactId>hapi-fhir-spring-boot-sample-client-okhttp</artifactId>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
</parent>
<artifactId>hapi-fhir-spring-boot-sample-server-jersey</artifactId>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-spring-boot</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
</parent>
<artifactId>hapi-fhir-spring-boot-samples</artifactId>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -23,12 +23,13 @@ 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.ValidatorPolicyAdvisor;
import ca.uhn.fhir.jpa.validation.ValidatorResourceFetcher;
import ca.uhn.fhir.rest.server.interceptor.ValidationResultEnrichingInterceptor;
import ca.uhn.fhir.validation.ResultSeverityEnum;
import org.apache.commons.lang3.Validate;
import org.apache.commons.text.WordUtils;
import org.hl7.fhir.r5.utils.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.Nonnull;
@ -57,6 +58,8 @@ public final class RepositoryValidatingRuleBuilder implements IRuleRoot {
@Autowired
private ValidatorResourceFetcher myValidatorResourceFetcher;
@Autowired
private ValidatorPolicyAdvisor myValidationPolicyAdvisor;
@Autowired
private IInterceptorBroadcaster myInterceptorBroadcaster;
/**
@ -175,7 +178,8 @@ public final class RepositoryValidatingRuleBuilder implements IRuleRoot {
* @see ValidationResultEnrichingInterceptor
*/
public FinalizedRequireValidationRule requireValidationToDeclaredProfiles() {
RequireValidationRule rule = new RequireValidationRule(myFhirContext, myType, myValidationSupport, myValidatorResourceFetcher, myInterceptorBroadcaster);
RequireValidationRule rule = new RequireValidationRule(myFhirContext, myType, myValidationSupport,
myValidatorResourceFetcher, myValidationPolicyAdvisor, myInterceptorBroadcaster);
myRules.add(rule);
return new FinalizedRequireValidationRule(rule);
}
@ -205,9 +209,9 @@ public final class RepositoryValidatingRuleBuilder implements IRuleRoot {
*/
@Nonnull
public FinalizedRequireValidationRule withBestPracticeWarningLevel(String theBestPracticeWarningLevel) {
IResourceValidator.BestPracticeWarningLevel level = null;
BestPracticeWarningLevel level = null;
if (isNotBlank(theBestPracticeWarningLevel)) {
level = IResourceValidator.BestPracticeWarningLevel.valueOf(WordUtils.capitalize(theBestPracticeWarningLevel.toLowerCase()));
level = BestPracticeWarningLevel.valueOf(WordUtils.capitalize(theBestPracticeWarningLevel.toLowerCase()));
}
return withBestPracticeWarningLevel(level);
}
@ -215,13 +219,13 @@ public final class RepositoryValidatingRuleBuilder implements IRuleRoot {
/**
* Sets the "Best Practice Warning Level", which is the severity at which any "best practices" that
* are specified in the FHIR specification will be added to the validation outcome. Set to
* {@link org.hl7.fhir.r5.utils.IResourceValidator.BestPracticeWarningLevel#Error} to
* {@link org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel#Error} to
* cause any best practice notices to result in a validation failure.
* Set to {@link org.hl7.fhir.r5.utils.IResourceValidator.BestPracticeWarningLevel#Ignore}
* Set to {@link org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel#Ignore}
* to not include any best practice notifications.
*/
@Nonnull
public FinalizedRequireValidationRule withBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel bestPracticeWarningLevel) {
public FinalizedRequireValidationRule withBestPracticeWarningLevel(BestPracticeWarningLevel bestPracticeWarningLevel) {
myRule.setBestPracticeWarningLevel(bestPracticeWarningLevel);
return this;
}

View File

@ -23,6 +23,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.ValidatorPolicyAdvisor;
import ca.uhn.fhir.jpa.validation.ValidatorResourceFetcher;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.interceptor.ValidationResultEnrichingInterceptor;
@ -36,7 +37,7 @@ import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r5.utils.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel;
import javax.annotation.Nonnull;
import java.util.ArrayList;
@ -49,17 +50,23 @@ class RequireValidationRule extends BaseTypedRule {
private ResultSeverityEnum myRejectOnSeverity = ResultSeverityEnum.ERROR;
private List<TagOnSeverity> myTagOnSeverity = Collections.emptyList();
public RequireValidationRule(FhirContext theFhirContext, String theType, IValidationSupport theValidationSupport, ValidatorResourceFetcher theValidatorResourceFetcher, IInterceptorBroadcaster theInterceptorBroadcaster) {
public RequireValidationRule(FhirContext theFhirContext,
String theType,
IValidationSupport theValidationSupport,
ValidatorResourceFetcher theValidatorResourceFetcher,
ValidatorPolicyAdvisor theValidationPolicyAdvisor,
IInterceptorBroadcaster theInterceptorBroadcaster) {
super(theFhirContext, theType);
myInterceptorBroadcaster = theInterceptorBroadcaster;
myValidator = new FhirInstanceValidator(theValidationSupport);
myValidator.setValidatorResourceFetcher(theValidatorResourceFetcher);
myValidator.setBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel.Warning);
myValidator.setValidatorPolicyAdvisor(theValidationPolicyAdvisor);
myValidator.setBestPracticeWarningLevel(BestPracticeWarningLevel.Warning);
}
void setBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel theBestPracticeWarningLevel) {
void setBestPracticeWarningLevel(BestPracticeWarningLevel theBestPracticeWarningLevel) {
myValidator.setBestPracticeWarningLevel(theBestPracticeWarningLevel);
}

View File

@ -20,14 +20,14 @@ package ca.uhn.fhir.jpa.validation;
* #L%
*/
import org.hl7.fhir.r5.utils.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
import org.thymeleaf.util.Validate;
import javax.annotation.Nonnull;
public class ValidationSettings {
private IResourceValidator.ReferenceValidationPolicy myLocalReferenceValidationDefaultPolicy = IResourceValidator.ReferenceValidationPolicy.IGNORE;
private ReferenceValidationPolicy myLocalReferenceValidationDefaultPolicy = ReferenceValidationPolicy.IGNORE;
/**
* Supplies a default policy for validating local references. Default is {@literal IResourceValidator.ReferenceValidationPolicy.IGNORE}.
@ -40,7 +40,7 @@ public class ValidationSettings {
* @since 5.1.0
*/
@Nonnull
public IResourceValidator.ReferenceValidationPolicy getLocalReferenceValidationDefaultPolicy() {
public ReferenceValidationPolicy getLocalReferenceValidationDefaultPolicy() {
return myLocalReferenceValidationDefaultPolicy;
}
@ -54,7 +54,7 @@ public class ValidationSettings {
*
* @since 5.1.0
*/
public void setLocalReferenceValidationDefaultPolicy(@Nonnull IResourceValidator.ReferenceValidationPolicy theLocalReferenceValidationDefaultPolicy) {
public void setLocalReferenceValidationDefaultPolicy(@Nonnull ReferenceValidationPolicy theLocalReferenceValidationDefaultPolicy) {
Validate.notNull(theLocalReferenceValidationDefaultPolicy, "theLocalReferenceValidationDefaultPolicy must not be null");
myLocalReferenceValidationDefaultPolicy = theLocalReferenceValidationDefaultPolicy;
}

View File

@ -0,0 +1,48 @@
package ca.uhn.fhir.jpa.validation;
import ca.uhn.fhir.context.FhirContext;
import org.hl7.fhir.r5.elementmodel.Element;
import org.hl7.fhir.r5.model.ElementDefinition;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.utils.validation.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
public class ValidatorPolicyAdvisor implements IValidationPolicyAdvisor {
private static final Logger ourLog = LoggerFactory.getLogger(ValidatorPolicyAdvisor.class);
@Autowired
private ValidationSettings myValidationSettings;
@Autowired
private FhirContext myFhirContext;
@Override
public ReferenceValidationPolicy policyForReference(IResourceValidator validator, Object appContext, String path, String url) {
int slashIdx = url.indexOf("/");
if (slashIdx > 0 && myFhirContext.getResourceTypes().contains(url.substring(0, slashIdx))) {
return myValidationSettings.getLocalReferenceValidationDefaultPolicy();
}
return ReferenceValidationPolicy.IGNORE;
}
@Override
public CodedContentValidationPolicy policyForCodedContent(IResourceValidator iResourceValidator, Object o, String s, ElementDefinition elementDefinition, StructureDefinition structureDefinition, BindingKind bindingKind, 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;
}
}

View File

@ -35,7 +35,8 @@ import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r5.elementmodel.Element;
import org.hl7.fhir.r5.elementmodel.JsonParser;
import org.hl7.fhir.r5.model.CanonicalResource;
import org.hl7.fhir.r5.utils.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.IValidatorResourceFetcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -46,23 +47,21 @@ import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.Locale;
public class ValidatorResourceFetcher implements IResourceValidator.IValidatorResourceFetcher {
public class ValidatorResourceFetcher implements IValidatorResourceFetcher {
private static final Logger ourLog = LoggerFactory.getLogger(ValidatorResourceFetcher.class);
@Autowired
private DaoRegistry myDaoRegistry;
@Autowired
private ValidationSettings myValidationSettings;
@Autowired
private FhirContext myFhirContext;
@Autowired
private IValidationSupport myValidationSupport;
private VersionSpecificWorkerContextWrapper myVersionSpecificCOntextWrapper;
private VersionSpecificWorkerContextWrapper myVersionSpecificContextWrapper;
@PostConstruct
public void start() {
myVersionSpecificCOntextWrapper = VersionSpecificWorkerContextWrapper.newVersionSpecificWorkerContextWrapper(myValidationSupport);
myVersionSpecificContextWrapper = VersionSpecificWorkerContextWrapper.newVersionSpecificWorkerContextWrapper(myValidationSupport);
}
@Override
@ -79,23 +78,12 @@ public class ValidatorResourceFetcher implements IResourceValidator.IValidatorRe
}
try {
return new JsonParser(myVersionSpecificCOntextWrapper).parse(myFhirContext.newJsonParser().encodeResourceToString(target), resourceType);
return new JsonParser(myVersionSpecificContextWrapper).parse(myFhirContext.newJsonParser().encodeResourceToString(target), resourceType);
} catch (Exception e) {
throw new FHIRException(e);
}
}
@Override
public IResourceValidator.ReferenceValidationPolicy validationPolicy(IResourceValidator iResourceValidator,
Object appContext, String path, String url) {
int slashIdx = url.indexOf("/");
if (slashIdx > 0 && myFhirContext.getResourceTypes().contains(url.substring(0, slashIdx))) {
return myValidationSettings.getLocalReferenceValidationDefaultPolicy();
}
return IResourceValidator.ReferenceValidationPolicy.IGNORE;
}
@Override
public boolean resolveURL(IResourceValidator iResourceValidator, Object o, String s, String s1, String s2) throws IOException, FHIRException {
return true;
@ -107,7 +95,7 @@ public class ValidatorResourceFetcher implements IResourceValidator.IValidatorRe
}
@Override
public IResourceValidator.IValidatorResourceFetcher setLocale(Locale locale) {
public IValidatorResourceFetcher setLocale(Locale locale) {
// ignore
return this;
}

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -28,7 +28,7 @@ import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.dstu3.model.ValueSet.ValueSetExpansionComponent;
import org.hl7.fhir.dstu3.terminologies.ValueSetExpander;
import org.hl7.fhir.dstu3.utils.INarrativeGenerator;
import org.hl7.fhir.dstu3.utils.IResourceValidator;
import org.hl7.fhir.dstu3.utils.validation.IResourceValidator;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.utilities.i18n.I18nBase;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -31,7 +31,7 @@ import org.hl7.fhir.r4.model.StructureMap;
import org.hl7.fhir.r4.model.ValueSet;
import org.hl7.fhir.r4.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.r4.terminologies.ValueSetExpander;
import org.hl7.fhir.r4.utils.IResourceValidator;
import org.hl7.fhir.r4.utils.validation.IResourceValidator;
import org.hl7.fhir.utilities.TranslationServices;
import org.hl7.fhir.utilities.i18n.I18nBase;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -31,7 +31,7 @@ import org.hl7.fhir.r5.model.StructureMap;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.r5.terminologies.ValueSetExpander;
import org.hl7.fhir.r5.utils.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.IResourceValidator;
import org.hl7.fhir.utilities.TimeTracker;
import org.hl7.fhir.utilities.TranslationServices;
import org.hl7.fhir.utilities.i18n.I18nBase;
@ -93,6 +93,15 @@ public final class HapiWorkerContext extends I18nBase implements IWorkerContext
}
}
@Override
public CodeSystem fetchCodeSystem(String theSystem, String version) {
if (myValidationSupport == null) {
return null;
} else {
return (CodeSystem) myValidationSupport.fetchCodeSystem(theSystem);
}
}
@Override
public List<ConceptMap> findMapsForSource(String theUrl) {
throw new UnsupportedOperationException();
@ -170,7 +179,7 @@ public final class HapiWorkerContext extends I18nBase implements IWorkerContext
String system = theCode.getSystem();
String code = theCode.getCode();
String display = theCode.getDisplay();
return validateCode(theOptions, system, code, display, theVs);
return validateCode(theOptions, system, null, code, display, theVs);
}
@Override
@ -179,8 +188,15 @@ public final class HapiWorkerContext extends I18nBase implements IWorkerContext
}
@Override
public ValidationResult validateCode(ValidationOptions theOptions, String theSystem, String theCode, String theDisplay) {
IValidationSupport.CodeValidationResult result = myValidationSupport.validateCode(new ValidationSupportContext(myValidationSupport), convertConceptValidationOptions(theOptions), theSystem, theCode, theDisplay, null);
public ValueSetExpander.ValueSetExpansionOutcome expandVS(ValueSet theValueSet, boolean cacheOk, boolean heiarchical, boolean incompleteOk) {
return null;
}
@Override
public ValidationResult validateCode(ValidationOptions theOptions, String theSystem, String theVersion,
String theCode, String theDisplay) {
IValidationSupport.CodeValidationResult result = myValidationSupport.validateCode(new ValidationSupportContext(myValidationSupport),
convertConceptValidationOptions(theOptions), theSystem, theCode, theDisplay, null);
if (result == null) {
return null;
}
@ -193,13 +209,15 @@ public final class HapiWorkerContext extends I18nBase implements IWorkerContext
}
@Override
public ValidationResult validateCode(ValidationOptions theOptions, String theSystem, String theCode, String theDisplay, ValueSet theVs) {
public ValidationResult validateCode(ValidationOptions theOptions, String theSystem, String theVersion,
String theCode, String theDisplay, ValueSet theVs) {
IValidationSupport.CodeValidationResult outcome;
if (isNotBlank(theVs.getUrl())) {
outcome = myValidationSupport.validateCode(new ValidationSupportContext(myValidationSupport), convertConceptValidationOptions(theOptions), theSystem, theCode, theDisplay, theVs.getUrl());
outcome = myValidationSupport.validateCode(new ValidationSupportContext(myValidationSupport),
convertConceptValidationOptions(theOptions), theSystem, theCode, theDisplay, theVs.getUrl());
} else {
outcome = myValidationSupport.validateCodeInValueSet(new ValidationSupportContext(myValidationSupport), convertConceptValidationOptions(theOptions), theSystem, theCode, theDisplay, theVs);
outcome = myValidationSupport.validateCodeInValueSet(new ValidationSupportContext(myValidationSupport),
convertConceptValidationOptions(theOptions), theSystem, theCode, theDisplay, theVs);
}
if (outcome != null && outcome.isOk()) {
@ -209,12 +227,13 @@ public final class HapiWorkerContext extends I18nBase implements IWorkerContext
return new ValidationResult(theSystem, definition);
}
return new ValidationResult(IssueSeverity.ERROR, "Unknown code[" + theCode + "] in system[" + Constants.codeSystemWithDefaultDescription(theSystem) + "]");
return new ValidationResult(IssueSeverity.ERROR, "Unknown code[" + theCode + "] in system[" +
Constants.codeSystemWithDefaultDescription(theSystem) + "]");
}
@Override
public ValidationResult validateCode(ValidationOptions theOptions, String code, ValueSet vs) {
return validateCode(theOptions, null, code, null, vs);
return validateCode(theOptions, null, null, code, null, vs);
}
@Override

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent>

View File

@ -0,0 +1,52 @@
package org.hl7.fhir.common.hapi.validation.validator;
import org.hl7.fhir.r5.elementmodel.Element;
import org.hl7.fhir.r5.model.ElementDefinition;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.utils.validation.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor;
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 java.util.List;
/**
* Implementation of the base {@link IValidationPolicyAdvisor}. This is used as the default for all validation operations
* done within the core libraries, as without a default, it will ignore some validation operations.
*/
public class FhirDefaultPolicyAdvisor implements IValidationPolicyAdvisor {
@Override
public ReferenceValidationPolicy policyForReference(IResourceValidator validator,
Object appContext,
String path,
String url) {
return ReferenceValidationPolicy.IGNORE;
}
@Override
public ContainedReferenceValidationPolicy policyForContained(IResourceValidator validator,
Object appContext,
String containerType,
String containerId,
Element.SpecialElement containingResourceType,
String path,
String url) {
return ContainedReferenceValidationPolicy.CHECK_VALID;
}
@Override
public CodedContentValidationPolicy policyForCodedContent(IResourceValidator validator,
Object appContext,
String stackPath,
ElementDefinition definition,
StructureDefinition structure,
BindingKind kind,
ValueSet valueSet,
List<String> systems) {
return CodedContentValidationPolicy.CODE;
}
}

View File

@ -13,8 +13,9 @@ import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.r5.model.TypeDetails;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.utils.FHIRPathEngine;
import org.hl7.fhir.r5.utils.IResourceValidator;
import org.hl7.fhir.r5.utils.IResourceValidator.BestPracticeWarningLevel;
import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor;
import org.hl7.fhir.r5.utils.validation.IValidatorResourceFetcher;
import org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import javax.annotation.Nonnull;
@ -35,7 +36,8 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
private boolean errorForUnknownProfiles = true;
private boolean assumeValidRestReferences;
private List<String> myExtensionDomains = Collections.emptyList();
private IResourceValidator.IValidatorResourceFetcher validatorResourceFetcher;
private IValidatorResourceFetcher validatorResourceFetcher;
private IValidationPolicyAdvisor validatorPolicyAdvisor;
/**
* Constructor
@ -227,6 +229,8 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
.setBestPracticeWarningLevel(getBestPracticeWarningLevel())
.setErrorForUnknownProfiles(isErrorForUnknownProfiles())
.setExtensionDomains(getExtensionDomains())
.setValidatorResourceFetcher(validatorResourceFetcher)
.setValidationPolicyAdvisor(validatorPolicyAdvisor)
.setNoTerminologyChecks(isNoTerminologyChecks())
.setNoExtensibleWarnings(isNoExtensibleWarnings())
.setNoBindingMsgSuppressed(isNoBindingMsgSuppressed())
@ -245,11 +249,19 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
return wrappedWorkerContext;
}
public IResourceValidator.IValidatorResourceFetcher getValidatorResourceFetcher() {
public IValidationPolicyAdvisor getValidatorPolicyAdvisor() {
return validatorPolicyAdvisor;
}
public void setValidatorPolicyAdvisor(IValidationPolicyAdvisor validatorPolicyAdvisor) {
this.validatorPolicyAdvisor = validatorPolicyAdvisor;
}
public IValidatorResourceFetcher getValidatorResourceFetcher() {
return validatorResourceFetcher;
}
public void setValidatorResourceFetcher(IResourceValidator.IValidatorResourceFetcher validatorResourceFetcher) {
public void setValidatorResourceFetcher(IValidatorResourceFetcher validatorResourceFetcher) {
this.validatorResourceFetcher = validatorResourceFetcher;
}

View File

@ -16,8 +16,11 @@ import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.elementmodel.Manager;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.utils.FHIRPathEngine;
import org.hl7.fhir.r5.utils.IResourceValidator;
import org.hl7.fhir.r5.utils.XVerExtensionManager;
import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor;
import org.hl7.fhir.r5.utils.validation.IValidatorResourceFetcher;
import org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel;
import org.hl7.fhir.r5.utils.validation.constants.IdStatus;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.hl7.fhir.validation.instance.InstanceValidator;
import org.slf4j.Logger;
@ -34,7 +37,7 @@ import java.util.List;
class ValidatorWrapper {
private static final Logger ourLog = LoggerFactory.getLogger(ValidatorWrapper.class);
private IResourceValidator.BestPracticeWarningLevel myBestPracticeWarningLevel;
private BestPracticeWarningLevel myBestPracticeWarningLevel;
private boolean myAnyExtensionsAllowed;
private boolean myErrorForUnknownProfiles;
private boolean myNoTerminologyChecks;
@ -42,7 +45,8 @@ class ValidatorWrapper {
private boolean myNoExtensibleWarnings;
private boolean myNoBindingMsgSuppressed;
private Collection<? extends String> myExtensionDomains;
private IResourceValidator.IValidatorResourceFetcher myValidatorResourceFetcher;
private IValidatorResourceFetcher myValidatorResourceFetcher;
private IValidationPolicyAdvisor myValidationPolicyAdvisor;
/**
* Constructor
@ -60,7 +64,7 @@ class ValidatorWrapper {
return this;
}
public ValidatorWrapper setBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel theBestPracticeWarningLevel) {
public ValidatorWrapper setBestPracticeWarningLevel(BestPracticeWarningLevel theBestPracticeWarningLevel) {
myBestPracticeWarningLevel = theBestPracticeWarningLevel;
return this;
}
@ -95,8 +99,12 @@ class ValidatorWrapper {
return this;
}
public ValidatorWrapper setValidationPolicyAdvisor(IValidationPolicyAdvisor validationPolicyAdvisor) {
this.myValidationPolicyAdvisor = validationPolicyAdvisor;
return this;
}
public ValidatorWrapper setValidatorResourceFetcher(IResourceValidator.IValidatorResourceFetcher validatorResourceFetcher) {
public ValidatorWrapper setValidatorResourceFetcher(IValidatorResourceFetcher validatorResourceFetcher) {
this.myValidatorResourceFetcher = validatorResourceFetcher;
return this;
}
@ -114,11 +122,12 @@ class ValidatorWrapper {
v.setAssumeValidRestReferences(isAssumeValidRestReferences());
v.setBestPracticeWarningLevel(myBestPracticeWarningLevel);
v.setAnyExtensionsAllowed(myAnyExtensionsAllowed);
v.setResourceIdRule(IResourceValidator.IdStatus.OPTIONAL);
v.setResourceIdRule(IdStatus.OPTIONAL);
v.setNoTerminologyChecks(myNoTerminologyChecks);
v.setErrorForUnknownProfiles(myErrorForUnknownProfiles);
v.getExtensionDomains().addAll(myExtensionDomains);
v.setFetcher(myValidatorResourceFetcher);
v.setPolicyAdvisor(myValidationPolicyAdvisor);
v.setNoExtensibleWarnings(myNoExtensibleWarnings);
v.setNoBindingMsgSuppressed(myNoBindingMsgSuppressed);
v.setAllowXsiLocation(true);

View File

@ -24,12 +24,13 @@ import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.formats.IParser;
import org.hl7.fhir.r5.formats.ParserType;
import org.hl7.fhir.r5.model.CanonicalResource;
import org.hl7.fhir.r5.model.CodeSystem;
import org.hl7.fhir.r5.model.Coding;
import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.terminologies.ValueSetExpander;
import org.hl7.fhir.r5.utils.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.IResourceValidator;
import org.hl7.fhir.utilities.TimeTracker;
import org.hl7.fhir.utilities.TranslationServices;
import org.hl7.fhir.utilities.i18n.I18nBase;
@ -329,6 +330,19 @@ public class VersionSpecificWorkerContextWrapper extends I18nBase implements IWo
}
}
@Override
public CodeSystem fetchCodeSystem(String system, String verison) {
IBaseResource fetched = myValidationSupportContext.getRootValidationSupport().fetchCodeSystem(system);
if (fetched == null) {
return null;
}
try {
return (org.hl7.fhir.r5.model.CodeSystem) myModelConverter.toCanonical(fetched);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
}
@Override
public <T extends Resource> T fetchResource(Class<T> class_, String uri) {
@ -514,14 +528,18 @@ public class VersionSpecificWorkerContextWrapper extends I18nBase implements IWo
}
@Override
public ValidationResult validateCode(ValidationOptions theOptions, String system, String code, String display) {
ConceptValidationOptions validationOptions = convertConceptValidationOptions(theOptions);
public ValueSetExpander.ValueSetExpansionOutcome expandVS(ValueSet source, boolean cacheOk, boolean heiarchical, boolean incompleteOk) {
return null;
}
@Override
public ValidationResult validateCode(ValidationOptions theOptions, String system, String version, String code, String display) {
ConceptValidationOptions validationOptions = convertConceptValidationOptions(theOptions);
return doValidation(null, validationOptions, system, code, display);
}
@Override
public ValidationResult validateCode(ValidationOptions theOptions, String theSystem, String theCode, String display, org.hl7.fhir.r5.model.ValueSet theValueSet) {
public ValidationResult validateCode(ValidationOptions theOptions, String theSystem, String version, String theCode, String display, ValueSet theValueSet) {
IBaseResource convertedVs = null;
try {

View File

@ -0,0 +1,10 @@
package org.hl7.fhir.common.hapi.validation.validator;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_14_50;
public class VersionTypeAdvisorDstu21 extends BaseAdvisor_14_50 {
@Override
public boolean failFastOnNullOrUnknownEntry() {
return false;
}
}

View File

@ -7,7 +7,7 @@ import org.hl7.fhir.r5.model.Resource;
public class VersionTypeConverterDstu21 implements VersionSpecificWorkerContextWrapper.IVersionTypeConverter {
@Override
public Resource toCanonical(IBaseResource theNonCanonical) {
return VersionConvertorFactory_14_50.convertResource((org.hl7.fhir.dstu2016may.model.Resource) theNonCanonical);
return VersionConvertorFactory_14_50.convertResource((org.hl7.fhir.dstu2016may.model.Resource) theNonCanonical, new VersionTypeAdvisorDstu21());
}
@Override

View File

@ -53,7 +53,9 @@ import org.hl7.fhir.dstu3.model.ValueSet;
import org.hl7.fhir.dstu3.model.ValueSet.ValueSetExpansionComponent;
import org.hl7.fhir.dstu3.utils.FHIRPathEngine;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r5.utils.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor;
import org.hl7.fhir.r5.utils.validation.IValidatorResourceFetcher;
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeEach;
@ -595,7 +597,8 @@ public class FhirInstanceValidatorDstu3Test {
ValidationResult output = myVal.validateWithResult(input);
List<SingleValidationMessage> issues = logResultsAndReturnNonInformationalOnes(output);
assertThat(issues.toString(), containsString("None of the codings provided are in the value set http://phr.kanta.fi/ValueSet/fiphr-vs-medicationcontext"));
assertThat(issues.stream().map(SingleValidationMessage::getMessage).collect(Collectors.toList()).toString(),
containsString("None of the codings provided are in the value set 'Value Set Finnish PHR Medication Context' (http://phr.kanta.fi/ValueSet/fiphr-vs-medicationcontext), and a coding from this value set is required) (codes = http://phr.kanta.fi/fiphr-cs-medicationcontext#13)"));
}
@Test
@ -665,6 +668,9 @@ public class FhirInstanceValidatorDstu3Test {
return false;
} else if (t.getMessage().contains("The valueSet reference http://www.rfc-editor.org/bcp/bcp13.txt on element")) {
return false;
} else if (t.getMessage().contains("The Unicode sequence has unterminated bi-di control characters")) {
// Some DSTU3 structures conain bi-di control characters, and a check for this was added recently.
return false;
} else {
return true;
}
@ -1180,7 +1186,7 @@ public class FhirInstanceValidatorDstu3Test {
ValidationResult output = myVal.validateWithResult(input);
logResultsAndReturnAll(output);
assertEquals(
"The value provided ('notvalidcode') is not in the value set http://hl7.org/fhir/ValueSet/observation-status (http://hl7.org/fhir/ValueSet/observation-status), and a code is required from this value set) (error message = Unknown code 'notvalidcode' for in-memory expansion of ValueSet 'http://hl7.org/fhir/ValueSet/observation-status')",
"The value provided ('notvalidcode') is not in the value set 'ObservationStatus' (http://hl7.org/fhir/ValueSet/observation-status), and a code is required from this value set) (error message = Unknown code 'notvalidcode' for in-memory expansion of ValueSet 'http://hl7.org/fhir/ValueSet/observation-status')",
output.getMessages().get(0).getMessage());
}
@ -1277,7 +1283,7 @@ public class FhirInstanceValidatorDstu3Test {
assertEquals(1, all.size());
assertEquals("Patient.identifier[0].type", all.get(0).getLocationString());
assertEquals(
"None of the codings provided are in the value set http://hl7.org/fhir/ValueSet/identifier-type (http://hl7.org/fhir/ValueSet/identifier-type), and a coding should come from this value set unless it has no suitable code (note that the validator cannot judge what is suitable) (codes = http://example.com/foo/bar#bar)",
"None of the codings provided are in the value set 'Identifier Type Codes' (http://hl7.org/fhir/ValueSet/identifier-type), and a coding should come from this value set unless it has no suitable code (note that the validator cannot judge what is suitable) (codes = http://example.com/foo/bar#bar)",
all.get(0).getMessage());
assertEquals(ResultSeverityEnum.WARNING, all.get(0).getSeverity());
@ -1310,14 +1316,18 @@ public class FhirInstanceValidatorDstu3Test {
public void testInvocationOfValidatorFetcher() throws IOException {
String input = IOUtils.toString(FhirInstanceValidatorDstu3Test.class.getResourceAsStream("/dstu3-rick-test.json"), Charsets.UTF_8);
IResourceValidator.IValidatorResourceFetcher resourceFetcher = mock(IResourceValidator.IValidatorResourceFetcher.class);
when(resourceFetcher.validationPolicy(any(), any(), any(), any())).thenReturn(IResourceValidator.ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS);
myInstanceVal.setValidatorResourceFetcher(resourceFetcher);
IValidationPolicyAdvisor policyAdvisor = mock(IValidationPolicyAdvisor.class);
IValidatorResourceFetcher fetcher = mock(IValidatorResourceFetcher.class);
when(policyAdvisor.policyForReference(any(), any(), any(), any())).thenReturn(ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS);
when(policyAdvisor.policyForReference(any(), any(), any(), any())).thenReturn(ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS);
myInstanceVal.setValidatorResourceFetcher(fetcher);
myInstanceVal.setValidatorPolicyAdvisor(policyAdvisor);
myVal.validateWithResult(input);
verify(resourceFetcher, times(3)).resolveURL(any(), any(), anyString(), anyString(), anyString());
verify(resourceFetcher, times(4)).validationPolicy(any(), any(), anyString(), anyString());
verify(resourceFetcher, times(4)).fetch(any(), any(), anyString());
verify(fetcher, times(3)).resolveURL(any(), any(), anyString(), anyString(), anyString());
verify(policyAdvisor, times(4)).policyForReference(any(), any(), anyString(), anyString());
verify(fetcher, times(4)).fetch(any(), any(), anyString());
}
@Test

View File

@ -165,7 +165,7 @@ public class ResourceValidatorDstu3Test {
ValidationResult output = val.validateWithResult(p);
List<SingleValidationMessage> all = logResultsAndReturnNonInformationalOnes(output);
assertEquals("None of the codings provided are in the value set http://hl7.org/fhir/ValueSet/marital-status (http://hl7.org/fhir/ValueSet/marital-status), and a coding should come from this value set unless it has no suitable code (note that the validator cannot judge what is suitable) (codes = http://hl7.org/fhir/v3/MaritalStatus#FOO)", output.getMessages().get(0).getMessage());
assertEquals("None of the codings provided are in the value set 'Marital Status Codes' (http://hl7.org/fhir/ValueSet/marital-status), and a coding should come from this value set unless it has no suitable code (note that the validator cannot judge what is suitable) (codes = http://hl7.org/fhir/v3/MaritalStatus#FOO)", output.getMessages().get(0).getMessage());
assertEquals(ResultSeverityEnum.WARNING, output.getMessages().get(0).getSeverity());
}

View File

@ -62,7 +62,11 @@ import org.hl7.fhir.r4.model.ValueSet;
import org.hl7.fhir.r4.model.ValueSet.ValueSetExpansionComponent;
import org.hl7.fhir.r4.terminologies.ValueSetExpander;
import org.hl7.fhir.r4.utils.FHIRPathEngine;
import org.hl7.fhir.r5.utils.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor;
import org.hl7.fhir.r5.utils.validation.IValidatorResourceFetcher;
import org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel;
import org.hl7.fhir.r5.utils.validation.constants.ContainedReferenceValidationPolicy;
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
import org.junit.jupiter.api.AfterAll;
@ -70,6 +74,8 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.mockito.MockingDetails;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
@ -470,7 +476,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest {
// With BPs enabled
val = ourCtx.newValidator();
instanceModule = new FhirInstanceValidator(myValidationSupport);
IResourceValidator.BestPracticeWarningLevel level = IResourceValidator.BestPracticeWarningLevel.Error;
BestPracticeWarningLevel level = BestPracticeWarningLevel.Error;
instanceModule.setBestPracticeWarningLevel(level);
val.registerValidatorModule(instanceModule);
result = val.validateWithResult(input);
@ -634,7 +640,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest {
ValidationResult output = myFhirValidator.validateWithResult(input);
List<SingleValidationMessage> errors = logResultsAndReturnAll(output);
assertEquals(1, errors.size());
assertEquals("None of the codings provided are in the value set http://hl7.org/fhir/ValueSet/report-codes (http://hl7.org/fhir/ValueSet/report-codes), and a coding is recommended to come from this value set) (codes = http://loinc.org#1-8)", errors.get(0).getMessage());
assertEquals("None of the codings provided are in the value set 'LOINC Diagnostic Report Codes' (http://hl7.org/fhir/ValueSet/report-codes), and a coding is recommended to come from this value set) (codes = http://loinc.org#1-8)", errors.get(0).getMessage());
}
@Test
@ -1206,7 +1212,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest {
ValidationResult output = myFhirValidator.validateWithResult(input);
logResultsAndReturnAll(output);
assertEquals(
"The value provided ('notvalidcode') is not in the value set http://hl7.org/fhir/ValueSet/observation-status|4.0.1 (http://hl7.org/fhir/ValueSet/observation-status), and a code is required from this value set) (error message = Unknown code 'notvalidcode' for in-memory expansion of ValueSet 'http://hl7.org/fhir/ValueSet/observation-status')",
"The value provided ('notvalidcode') is not in the value set 'ObservationStatus' (http://hl7.org/fhir/ValueSet/observation-status|4.0.1), and a code is required from this value set) (error message = Unknown code 'notvalidcode' for in-memory expansion of ValueSet 'http://hl7.org/fhir/ValueSet/observation-status')",
output.getMessages().get(0).getMessage());
}
@ -1338,7 +1344,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest {
List<SingleValidationMessage> all = logResultsAndReturnAll(output);
assertEquals(1, all.size());
assertEquals("Patient.identifier[0].type", all.get(0).getLocationString());
assertThat(all.get(0).getMessage(), containsString("None of the codings provided are in the value set http://hl7.org/fhir/ValueSet/identifier-type"));
assertThat(all.get(0).getMessage(), containsString("None of the codings provided are in the value set 'IdentifierType' (http://hl7.org/fhir/ValueSet/identifier-type), and a coding should come from this value set unless it has no suitable code (note that the validator cannot judge what is suitable) (codes = http://example.com/foo/bar#bar)"));
assertEquals(ResultSeverityEnum.WARNING, all.get(0).getSeverity());
}
@ -1359,7 +1365,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest {
all = logResultsAndReturnNonInformationalOnes(output);
assertEquals(2, all.size());
assertThat(all.get(0).getMessage(), containsString("Validation failed for 'http://unitsofmeasure.org#Heck'"));
assertThat(all.get(1).getMessage(), containsString("The value provided ('Heck') is not in the value set http://hl7.org/fhir/ValueSet/ucum-bodytemp"));
assertThat(all.get(1).getMessage(), containsString("The value provided ('Heck') is not in the value set 'Body Temperature Units' (http://hl7.org/fhir/ValueSet/ucum-bodytemp|4.0.1), and a code is required from this value set) (error message = Failed to expand ValueSet 'http://hl7.org/fhir/ValueSet/ucum-bodytemp' (in-memory). Could not validate code null#Heck. Error was: Unable to expand ValueSet because CodeSystem could not be found: http://unitsofmeasure.org)"));
}
@ -1402,14 +1408,17 @@ public class FhirInstanceValidatorR4Test extends BaseTest {
String encoded = loadResource("/r4/r4-caredove-bundle.json");
IResourceValidator.IValidatorResourceFetcher resourceFetcher = mock(IResourceValidator.IValidatorResourceFetcher.class);
when(resourceFetcher.validationPolicy(any(), any(), any(), any())).thenReturn(IResourceValidator.ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS);
myInstanceVal.setValidatorResourceFetcher(resourceFetcher);
myFhirValidator.validateWithResult(encoded);
IValidatorResourceFetcher resourceFetcher = mock(IValidatorResourceFetcher.class);
IValidationPolicyAdvisor policyAdvisor = mock(IValidationPolicyAdvisor.class);
verify(resourceFetcher, times(15)).resolveURL(any(), any(), anyString(), anyString(), anyString());
verify(resourceFetcher, times(12)).validationPolicy(any(), any(), anyString(), anyString());
verify(resourceFetcher, times(12)).fetch(any(), any(), anyString());
when(policyAdvisor.policyForReference(any(), any(), any(), any())).thenReturn(ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS);
when(policyAdvisor.policyForContained(any(), any(), any(), any(), any(), any(), any())).thenReturn(ContainedReferenceValidationPolicy.CHECK_TYPE);
myInstanceVal.setValidatorResourceFetcher(resourceFetcher);
myInstanceVal.setValidatorPolicyAdvisor(policyAdvisor);
myVal.validateWithResult(encoded);
verify(resourceFetcher, times(12)).resolveURL(any(), any(), anyString(), anyString(), anyString());
verify(policyAdvisor, times(12)).policyForContained(any(), any(), any(), any(), any(), any(), any());
}
@Test
@ -1457,7 +1466,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest {
ValidationResult output = myFhirValidator.validateWithResult(input);
List<SingleValidationMessage> errors = logResultsAndReturnNonInformationalOnes(output);
assertEquals(1, errors.size(), errors.toString());
assertThat(errors.get(0).getMessage(), containsString("The value provided ('BLAH') is not in the value set http://hl7.org/fhir/ValueSet/currencies"));
assertThat(errors.get(0).getMessage(), containsString("The value provided ('BLAH') is not in the value set 'CurrencyCode' (http://hl7.org/fhir/ValueSet/currencies|4.0.1), and a code is required from this value set) (error message = Unknown code 'BLAH' for in-memory expansion of ValueSet 'http://hl7.org/fhir/ValueSet/currencies')"));
}

View File

@ -43,7 +43,11 @@ import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent;
import org.hl7.fhir.r5.terminologies.ValueSetExpander;
import org.hl7.fhir.r5.utils.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.IResourceValidator;
import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor;
import org.hl7.fhir.r5.utils.validation.IValidatorResourceFetcher;
import org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel;
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeEach;
@ -304,7 +308,7 @@ public class FhirInstanceValidatorR5Test {
// With BPs enabled
val = ourCtx.newValidator();
instanceModule = new FhirInstanceValidator(myValidationSupport);
IResourceValidator.BestPracticeWarningLevel level = IResourceValidator.BestPracticeWarningLevel.Error;
BestPracticeWarningLevel level = BestPracticeWarningLevel.Error;
instanceModule.setBestPracticeWarningLevel(level);
val.registerValidatorModule(instanceModule);
result = val.validateWithResult(input);
@ -446,14 +450,17 @@ public class FhirInstanceValidatorR5Test {
String input = IOUtils.toString(FhirInstanceValidator.class.getResourceAsStream("/vitals.json"), Charsets.UTF_8);
IResourceValidator.IValidatorResourceFetcher resourceFetcher = mock(IResourceValidator.IValidatorResourceFetcher.class);
when(resourceFetcher.validationPolicy(any(), any(), any(), any())).thenReturn(IResourceValidator.ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS);
IValidatorResourceFetcher resourceFetcher = mock(IValidatorResourceFetcher.class);
IValidationPolicyAdvisor policyAdvisor = mock(IValidationPolicyAdvisor.class);
when(policyAdvisor.policyForReference(any(), any(), any(), any())).thenReturn(ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS);
myInstanceVal.setValidatorResourceFetcher(resourceFetcher);
myInstanceVal.setValidatorPolicyAdvisor(policyAdvisor);
myVal.validateWithResult(input);
verify(resourceFetcher, times(13)).resolveURL(any(), any(), anyString(), anyString(), anyString());
verify(resourceFetcher, times(4)).validationPolicy(any(), any(), anyString(), anyString());
verify(resourceFetcher, times(3)).fetch(any(), any(), anyString());
//verify(resourceFetcher, times(13)).resolveURL(any(), any(), anyString(), anyString(), anyString());
verify(policyAdvisor, times(4)).policyForReference(any(), any(), anyString(), anyString());
//verify(resourceFetcher, times(3)).fetch(any(), any(), anyString());
}
@Test
@ -862,7 +869,7 @@ public class FhirInstanceValidatorR5Test {
logResultsAndReturnAll(output);
assertThat(
output.getMessages().get(0).getMessage(),
containsString("The value provided ('notvalidcode') is not in the value set http://hl7.org/fhir/ValueSet/observation-status")
containsString("The value provided ('notvalidcode') is not in the value set 'ObservationStatus' (http://hl7.org/fhir/ValueSet/observation-status|4.6.0), and a code is required from this value set) (error message = Unknown code 'notvalidcode' for in-memory expansion of ValueSet 'http://hl7.org/fhir/ValueSet/observation-status')")
);
}
@ -965,7 +972,7 @@ public class FhirInstanceValidatorR5Test {
assertEquals(1, all.size());
assertEquals("Patient.identifier[0].type", all.get(0).getLocationString());
assertEquals(
"None of the codings provided are in the value set http://hl7.org/fhir/ValueSet/identifier-type (http://hl7.org/fhir/ValueSet/identifier-type), and a coding should come from this value set unless it has no suitable code (note that the validator cannot judge what is suitable) (codes = http://example.com/foo/bar#bar)",
"None of the codings provided are in the value set 'IdentifierType' (http://hl7.org/fhir/ValueSet/identifier-type), and a coding should come from this value set unless it has no suitable code (note that the validator cannot judge what is suitable) (codes = http://example.com/foo/bar#bar)",
all.get(0).getMessage());
assertEquals(ResultSeverityEnum.WARNING, all.get(0).getSeverity());

View File

@ -1,845 +1,440 @@
{
"resourceType": "Bundle",
"type": "transaction",
"timestamp": "2018-03-09T15:21:51.2112Z",
"entry": [
{
"resource": {
"resourceType": "ServiceRequest",
"id": 1,
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"> </div>"
},
"status": "active",
"intent": "proposal",
"priority": "routine",
"subject": {
"reference": "Patient/1"
},
"authoredOn": "2018-03-09T15:21:51Z",
"requester": {
"reference": "PractitionerRole/1"
},
"performer": {
"reference": "https://www.caredove.com/FHIR3/HealthcareService/8654"
},
"reasonCode": [
{
"text": "Reason for referral narrative goes here"
}
],
"supportingInfo": [
{
"reference": "DocumentReference/1"
}
],
"note": [
{
"text": "Allergies: Penicillin \nSocial History: History of family conflict \nlow social interaction \nFood Allergies: Peanuts"
}
]
},
"request": {
"method": "POST",
"url": "ServiceRequest"
}
},
{
"resource": {
"resourceType": "Patient",
"id": 1,
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"> </div>"
},
"identifier": [
{
"type": {
"coding": [
{
"code": "JHN",
"system": "http://hl7.org/fhir/v2/0203"
}
],
"text": "Ontario PHN"
},
"value": "4455 044 033",
"system": "http://ehealthontario.ca/API/FHIR/NamingSystem/ca-on-patient-hcn",
"extension": [
{
"url": "https://www.caredove.com/FHIR3/StructureDefinition/caredove-healthcardversion",
"valueString": "H"
}
]
}
],
"name": [
{
"given": [
"John",
"Scott"
],
"family": "Smith"
}
],
"telecom": [
{
"system": "phone",
"value": "(555) 111-1111",
"use": "mobile",
"rank": 1
},
{
"system": "phone",
"value": "(555) 222-2222",
"rank": 2
},
{
"system": "email",
"value": "testpatient@caredove.com"
}
],
"gender": "male",
"birthDate": "1928-06-29",
"address": [
{
"use": "home",
"type": "physical",
"line": [
"Unit 2",
"50 Albert St."
],
"city": "Waterloo",
"state": "ON",
"postalCode": "K8N 1N1",
"country": "Can"
}
],
"maritalStatus": {
"coding": [
{
"code": "M",
"display": "Married"
}
],
"text": "Married"
},
"contact": [
{
"relationship": [
{
"text": "Alternate Contact"
}
],
"name": {
"given": [
"Shemergency",
"Scott"
],
"family": "McContact"
},
"telecom": [
{
"system": "phone",
"value": "(555) 111-1111",
"use": "mobile",
"rank": 1
},
{
"system": "phone",
"value": "(555) 222-2222",
"rank": 2
},
{
"system": "email",
"value": "testcontact@caredove.com"
}
],
"address": {
"use": "home",
"type": "physical",
"line": [
"Unit 2",
"50 Albert St."
],
"city": "Waterloo",
"state": "ON",
"postalCode": "32819",
"country": "Can"
},
"gender": "female"
}
],
"communication": [
{
"language": {
"coding": [
{
"code": "en",
"display": "English"
}
],
"text": "English"
},
"preferred": true
}
],
"generalPractitioner": [
{
"reference": "PractitionerRole/2"
}
]
},
"request": {
"method": "POST",
"url": "Patient"
}
},
{
"resource": {
"resourceType": "PractitionerRole",
"id": 1,
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"> </div>"
},
"practitioner": {
"reference": "Practitioner/1"
},
"organization": {
"reference": "Organization/1"
},
"location": [
{
"reference": "Location/1"
}
],
"telecom": [
{
"system": "phone",
"value": "(555) 111-1111",
"use": "work"
},
{
"system": "email",
"value": "testsender@caredove.com",
"use": "work"
}
]
},
"request": {
"method": "POST",
"url": "PractitionerRole"
}
},
{
"resource": {
"resourceType": "Practitioner",
"id": 1,
"name": [
{
"given": [
"Requesty"
],
"family": "McSenderson"
}
]
},
"request": {
"method": "POST",
"url": "Practitioner"
}
},
{
"resource": {
"resourceType": "Organization",
"id": 1,
"name": "North Sender Clinic"
},
"request": {
"method": "POST",
"url": "Organization"
}
},
{
"resource": {
"resourceType": "Location",
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"> </div>"
},
"id": 1,
"name": "Downtown Sender Hub",
"address": {
"use": "work",
"type": "physical",
"line": [
"Suite 11",
"11 King st. West"
],
"city": "Kitchener",
"state": "ON",
"postalCode": "N2L 1T1",
"country": "Can"
}
},
"request": {
"method": "POST",
"url": "Location"
}
},
{
"resource": {
"resourceType": "PractitionerRole",
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"> </div>"
},
"id": 2,
"practitioner": {
"reference": "Practitioner/2"
},
"organization": {
"reference": "Organization/2"
},
"location": [
{
"reference": "Location/2"
}
],
"telecom": [
{
"system": "phone",
"value": "(555) 222-2222",
"use": "work"
},
{
"system": "email",
"value": "familydoc@caredove.com",
"use": "work"
}
]
},
"request": {
"method": "POST",
"url": "PractitionerRole"
}
},
{
"resource": {
"resourceType": "Practitioner",
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"> </div>"
},
"id": 2,
"name": [
{
"given": [
"Dr. Prim"
],
"family": "Caredoc"
}
]
},
"request": {
"method": "POST",
"url": "Practitioner"
}
},
{
"resource": {
"resourceType": "Organization",
"id": 2,
"name": "Star Family Health Team"
},
"request": {
"method": "POST",
"url": "Organization"
}
},
{
"resource": {
"resourceType": "DocumentReference",
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"> </div>"
},
"id": 1,
"status": "current",
"created": "2018-03-09T15:21:51.2112Z",
"description": "Filename or Document Title goes here",
"content": [
{
"attachment": "NEEDS WORK - ATTACHMENT DATA TYPE",
"format": "NEEDS WORK - FORMAT INFO"
}
]
},
"request": {
"method": "POST",
"url": "Practitioner"
}
},
{
"resource": {
"resourceType": "Location",
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"> </div>"
},
"id": 2,
"name": "West Side GP Office",
"address": {
"use": "work",
"type": "physical",
"line": [
"22 Weber st. East"
],
"city": "Kitchener",
"state": "ON",
"postalCode": "N2L 2T2",
"country": "Can"
}
},
"request": {
"method": "POST",
"url": "Location"
}
},
{
"resource": {
"resourceType": "Task",
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"> </div>"
},
"id": 1,
"basedOn" : {
"reference" : "ServiceRequest/1"
"basedOn": {
"reference": "ServiceRequest/1"
},
"status" : "requested",
"businessStatus " : {
"text" : "Waiting for preliminary review"
"status": "requested",
"businessStatus ": {
"text": "Waiting for preliminary review"
},
"intent" : "proposal",
"code" : {
"text" : "Process Request"
"intent": "proposal",
"code": {
"text": "Process Request"
},
"description" : "Process and close this referral request",
"authoredOn" : "2018-03-09T15:21:51Z",
"lastModified" : "2018-03-09T15:21:51Z"
"description": "Process and close this referral request",
"authoredOn": "2018-03-09T15:21:51Z",
"lastModified": "2018-03-09T15:21:51Z"
},
"request": {
"method": "POST",
"url": "Task"
}
}
]
}

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -58,37 +58,37 @@
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-structures-dstu3</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-structures-hl7org-dstu2</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-structures-r4</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-structures-r5</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-validation-resources-dstu2</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-validation-resources-dstu3</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-validation-resources-r4</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -6,7 +6,7 @@
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<packaging>pom</packaging>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<name>HAPI-FHIR</name>
<description>An open-source implementation of the FHIR specification in Java.</description>
<url>https://hapifhir.io</url>
@ -766,7 +766,7 @@
<properties>
<fhir_core_version>5.5.7</fhir_core_version>
<fhir_core_version>5.6.3</fhir_core_version>
<ucum_version>1.0.3</ucum_version>
<surefire_jvm_args>-Dfile.encoding=UTF-8 -Xmx2048m</surefire_jvm_args>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version>
<version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>