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> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version> <version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

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

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -10,7 +10,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

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

View File

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

View File

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

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

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

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -11,7 +11,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </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.ITermReindexingSvc;
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc; import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
import ca.uhn.fhir.jpa.validation.JpaValidationSupportChain; 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.jpa.validation.ValidatorResourceFetcher;
import ca.uhn.fhir.validation.IInstanceValidatorModule; import ca.uhn.fhir.validation.IInstanceValidatorModule;
import org.hl7.fhir.common.hapi.validation.support.CachingValidationSupport; import org.hl7.fhir.common.hapi.validation.support.CachingValidationSupport;
import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator; 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.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
@ -96,7 +97,8 @@ public abstract class BaseConfigDstu3Plus extends BaseConfig {
public IInstanceValidatorModule instanceValidator() { public IInstanceValidatorModule instanceValidator() {
FhirInstanceValidator val = new FhirInstanceValidator(validationSupportChain()); FhirInstanceValidator val = new FhirInstanceValidator(validationSupportChain());
val.setValidatorResourceFetcher(jpaValidatorResourceFetcher()); val.setValidatorResourceFetcher(jpaValidatorResourceFetcher());
val.setBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel.Warning); val.setValidatorPolicyAdvisor(jpaValidatorPolicyAdvisor());
val.setBestPracticeWarningLevel(BestPracticeWarningLevel.Warning);
val.setValidationSupport(validationSupportChain()); val.setValidationSupport(validationSupportChain());
return val; return val;
} }
@ -107,6 +109,12 @@ public abstract class BaseConfigDstu3Plus extends BaseConfig {
return new ValidatorResourceFetcher(); return new ValidatorResourceFetcher();
} }
@Bean
@Lazy
public ValidatorPolicyAdvisor jpaValidatorPolicyAdvisor() {
return new ValidatorPolicyAdvisor();
}
@Bean @Bean
public abstract ITermReadSvc terminologyService(); 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.support.ValidationSupportChain;
import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator; import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator;
import org.hl7.fhir.common.hapi.validation.validator.HapiToHl7OrgDstu2ValidatingSupportWrapper; 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.beans.factory.annotation.Autowire;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -91,7 +91,7 @@ public class BaseDstu2Config extends BaseConfig {
public IInstanceValidatorModule instanceValidator(ValidationSupportChain theValidationSupportChain) { public IInstanceValidatorModule instanceValidator(ValidationSupportChain theValidationSupportChain) {
CachingValidationSupport cachingValidationSupport = new CachingValidationSupport(new HapiToHl7OrgDstu2ValidatingSupportWrapper(theValidationSupportChain)); CachingValidationSupport cachingValidationSupport = new CachingValidationSupport(new HapiToHl7OrgDstu2ValidatingSupportWrapper(theValidationSupportChain));
FhirInstanceValidator retVal = new FhirInstanceValidator(cachingValidationSupport); FhirInstanceValidator retVal = new FhirInstanceValidator(cachingValidationSupport);
retVal.setBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel.Warning); retVal.setBestPracticeWarningLevel(BestPracticeWarningLevel.Warning);
return retVal; 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.dstu3.model.Observation.ObservationStatus;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType; 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.AfterEach;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Disabled;
@ -121,14 +121,14 @@ public class FhirResourceDaoDstu3ValidateTest extends BaseJpaDstu3Test {
@AfterEach @AfterEach
public void after() { public void after() {
FhirInstanceValidator val = AopTestUtils.getTargetObject(myValidatorModule); FhirInstanceValidator val = AopTestUtils.getTargetObject(myValidatorModule);
val.setBestPracticeWarningLevel(org.hl7.fhir.r5.utils.IResourceValidator.BestPracticeWarningLevel.Warning); val.setBestPracticeWarningLevel(BestPracticeWarningLevel.Warning);
} }
@Test @Test
public void testValidateWithCanonicalReference() { public void testValidateWithCanonicalReference() {
FhirInstanceValidator val = AopTestUtils.getTargetObject(myValidatorModule); FhirInstanceValidator val = AopTestUtils.getTargetObject(myValidatorModule);
org.hl7.fhir.r5.utils.IResourceValidator.BestPracticeWarningLevel a = IResourceValidator.BestPracticeWarningLevel.Ignore; BestPracticeWarningLevel a = BestPracticeWarningLevel.Ignore;
val.setBestPracticeWarningLevel(a); val.setBestPracticeWarningLevel(a);
ValueSet vs = new ValueSet(); 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.Task;
import org.hl7.fhir.r4.model.UriType; import org.hl7.fhir.r4.model.UriType;
import org.hl7.fhir.r4.model.ValueSet; 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.AfterAll;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
@ -602,7 +610,8 @@ public abstract class BaseJpaR4Test extends BaseJpaTest implements ITestDataBuil
protected void validate(IBaseResource theResource) { protected void validate(IBaseResource theResource) {
FhirValidator validatorModule = myFhirCtx.newValidator(); FhirValidator validatorModule = myFhirCtx.newValidator();
FhirInstanceValidator instanceValidator = new FhirInstanceValidator(myValidationSupport); FhirInstanceValidator instanceValidator = new FhirInstanceValidator(myValidationSupport);
instanceValidator.setBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel.Ignore); instanceValidator.setBestPracticeWarningLevel(BestPracticeWarningLevel.Ignore);
instanceValidator.setValidatorPolicyAdvisor(new ValidationPolicyAdvisor());
validatorModule.registerValidatorModule(instanceValidator); validatorModule.registerValidatorModule(instanceValidator);
ValidationResult result = validatorModule.validateWithResult(theResource); ValidationResult result = validatorModule.validateWithResult(theResource);
if (!result.isSuccessful()) { 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") @SuppressWarnings("unchecked")
protected void upload(String theClasspath) throws IOException { protected void upload(String theClasspath) throws IOException {
String resource = loadResource(theClasspath); 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.StructureDefinition;
import org.hl7.fhir.r4.model.UriType; import org.hl7.fhir.r4.model.UriType;
import org.hl7.fhir.r4.model.ValueSet; 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.AfterEach;
import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -109,7 +110,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
@AfterEach @AfterEach
public void after() { public void after() {
FhirInstanceValidator val = AopTestUtils.getTargetObject(myValidatorModule); FhirInstanceValidator val = AopTestUtils.getTargetObject(myValidatorModule);
val.setBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel.Warning); val.setBestPracticeWarningLevel(BestPracticeWarningLevel.Warning);
myDaoConfig.setAllowExternalReferences(new DaoConfig().isAllowExternalReferences()); myDaoConfig.setAllowExternalReferences(new DaoConfig().isAllowExternalReferences());
myDaoConfig.setMaximumExpansionSize(DaoConfig.DEFAULT_MAX_EXPANSION_SIZE); myDaoConfig.setMaximumExpansionSize(DaoConfig.DEFAULT_MAX_EXPANSION_SIZE);
@ -117,7 +118,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
BaseTermReadSvcImpl.setInvokeOnNextCallForUnitTest(null); BaseTermReadSvcImpl.setInvokeOnNextCallForUnitTest(null);
myValidationSettings.setLocalReferenceValidationDefaultPolicy(IResourceValidator.ReferenceValidationPolicy.IGNORE); myValidationSettings.setLocalReferenceValidationDefaultPolicy(ReferenceValidationPolicy.IGNORE);
myFhirCtx.setParserErrorHandler(new StrictErrorHandler()); myFhirCtx.setParserErrorHandler(new StrictErrorHandler());
myUnknownCodeSystemWarningValidationSupport.setNonExistentCodeSystemSeverity(UnknownCodeSystemWarningValidationSupport.DEFAULT_SEVERITY); myUnknownCodeSystemWarningValidationSupport.setNonExistentCodeSystemSeverity(UnknownCodeSystemWarningValidationSupport.DEFAULT_SEVERITY);
@ -481,25 +482,25 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED); obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem("http://loinc.org").setCode("non-existing-code").setDisplay("Display 3"); obs.getCode().getCodingFirstRep().setSystem("http://loinc.org").setCode("non-existing-code").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs); 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 // Valid code with no system
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED); obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem(null).setCode("CODE3").setDisplay("Display 3"); obs.getCode().getCodingFirstRep().setSystem(null).setCode("CODE3").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs); 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 // Valid code with wrong system
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED); obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem("http://foo").setCode("CODE3").setDisplay("Display 3"); obs.getCode().getCodingFirstRep().setSystem("http://foo").setCode("CODE3").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs); 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 // Code that exists but isn't in the valueset
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED); obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem("http://terminology.hl7.org/CodeSystem/observation-category").setCode("vital-signs").setDisplay("Display 3"); obs.getCode().getCodingFirstRep().setSystem("http://terminology.hl7.org/CodeSystem/observation-category").setCode("vital-signs").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs); 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 // Invalid code in built-in VS/CS
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED); obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
@ -531,7 +532,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
@Test @Test
public void testValidateProfileTargetType_PolicyCheckValid() throws IOException { 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"); StructureDefinition profile = loadResourceFromClasspath(StructureDefinition.class, "/r4/profile-vitalsigns-all-loinc.json");
myStructureDefinitionDao.create(profile, mySrd); myStructureDefinitionDao.create(profile, mySrd);
@ -599,7 +600,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
@Test @Test
public void testValidateProfileTargetType_PolicyCheckExistsAndType() throws IOException { 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"); StructureDefinition profile = loadResourceFromClasspath(StructureDefinition.class, "/r4/profile-vitalsigns-all-loinc.json");
myStructureDefinitionDao.create(profile, mySrd); myStructureDefinitionDao.create(profile, mySrd);
@ -667,7 +668,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
@Test @Test
public void testValidateProfileTargetType_PolicyCheckExists() throws IOException { 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"); StructureDefinition profile = loadResourceFromClasspath(StructureDefinition.class, "/r4/profile-vitalsigns-all-loinc.json");
myStructureDefinitionDao.create(profile, mySrd); myStructureDefinitionDao.create(profile, mySrd);
@ -860,7 +861,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
} catch (PreconditionFailedException e) { } catch (PreconditionFailedException e) {
outcome = (OperationOutcome) e.getOperationOutcome(); outcome = (OperationOutcome) e.getOperationOutcome();
ourLog.info("Outcome: {}", myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome)); 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()); assertEquals(OperationOutcome.IssueSeverity.ERROR, outcome.getIssueFirstRep().getSeverity());
} }
} }
@ -933,25 +934,25 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED); obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem("http://loinc.org").setCode("non-existing-code").setDisplay("Display 3"); obs.getCode().getCodingFirstRep().setSystem("http://loinc.org").setCode("non-existing-code").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs); 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 // Valid code with no system
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED); obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem(null).setCode("CODE3").setDisplay("Display 3"); obs.getCode().getCodingFirstRep().setSystem(null).setCode("CODE3").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs); 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 // Valid code with wrong system
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED); obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem("http://foo").setCode("CODE3").setDisplay("Display 3"); obs.getCode().getCodingFirstRep().setSystem("http://foo").setCode("CODE3").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs); 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 // Code that exists but isn't in the valueset
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED); obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
obs.getCode().getCodingFirstRep().setSystem("http://terminology.hl7.org/CodeSystem/observation-category").setCode("vital-signs").setDisplay("Display 3"); obs.getCode().getCodingFirstRep().setSystem("http://terminology.hl7.org/CodeSystem/observation-category").setCode("vital-signs").setDisplay("Display 3");
oo = validateAndReturnOutcome(obs); 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 // Invalid code in built-in VS/CS
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED); obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
@ -1089,7 +1090,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
ourLog.info(myFhirCtx.newJsonParser().encodeResourceToString(allergy)); ourLog.info(myFhirCtx.newJsonParser().encodeResourceToString(allergy));
OperationOutcome oo = validateAndReturnOutcome(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") @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 // It would be ok for this to produce 0 issues, or just an information message too
assertEquals(1, OperationOutcomeUtil.getIssueCount(myFhirCtx, oo)); 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 @Test
public void testValidateWithCanonicalReference() { public void testValidateWithCanonicalReference() {
FhirInstanceValidator val = AopTestUtils.getTargetObject(myValidatorModule); FhirInstanceValidator val = AopTestUtils.getTargetObject(myValidatorModule);
val.setBestPracticeWarningLevel(org.hl7.fhir.r5.utils.IResourceValidator.BestPracticeWarningLevel.Ignore); val.setBestPracticeWarningLevel(BestPracticeWarningLevel.Ignore);
ValueSet vs = new ValueSet(); ValueSet vs = new ValueSet();
vs.setId("MYVS"); vs.setId("MYVS");
@ -1686,7 +1687,8 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
} catch (PreconditionFailedException e) { } catch (PreconditionFailedException e) {
OperationOutcome oo = (OperationOutcome) e.getOperationOutcome(); OperationOutcome oo = (OperationOutcome) e.getOperationOutcome();
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(oo)); 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.Task;
import org.hl7.fhir.r5.model.UriType; import org.hl7.fhir.r5.model.UriType;
import org.hl7.fhir.r5.model.ValueSet; 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.AfterAll;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
@ -512,7 +512,7 @@ public abstract class BaseJpaR5Test extends BaseJpaTest implements ITestDataBuil
protected void validate(IBaseResource theResource) { protected void validate(IBaseResource theResource) {
FhirValidator validatorModule = myFhirCtx.newValidator(); FhirValidator validatorModule = myFhirCtx.newValidator();
FhirInstanceValidator instanceValidator = new FhirInstanceValidator(myValidationSupport); FhirInstanceValidator instanceValidator = new FhirInstanceValidator(myValidationSupport);
instanceValidator.setBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel.Ignore); instanceValidator.setBestPracticeWarningLevel(BestPracticeWarningLevel.Ignore);
validatorModule.registerValidatorModule(instanceValidator); validatorModule.registerValidatorModule(instanceValidator);
ValidationResult result = validatorModule.validateWithResult(theResource); ValidationResult result = validatorModule.validateWithResult(theResource);
if (!result.isSuccessful()) { 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.Parameters;
import org.hl7.fhir.r4.model.Patient; import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.StringType; 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.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -370,7 +370,7 @@ public class RepositoryValidatingInterceptorR4Test extends BaseJpaR4Test {
.requireAtLeastProfile("http://hl7.org/fhir/StructureDefinition/Observation") .requireAtLeastProfile("http://hl7.org/fhir/StructureDefinition/Observation")
.and() .and()
.requireValidationToDeclaredProfiles() .requireValidationToDeclaredProfiles()
.withBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel.Ignore) .withBestPracticeWarningLevel(BestPracticeWarningLevel.Ignore)
.build(); .build();
myValInterceptor.setRules(rules); 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.Observation;
import org.hl7.fhir.r4.model.OperationOutcome; import org.hl7.fhir.r4.model.OperationOutcome;
import org.hl7.fhir.r4.model.Reference; 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.AfterEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; 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) List<IRepositoryValidatingRule> rules = myApplicationContext.getBean(RepositoryValidatingRuleBuilder.REPOSITORY_VALIDATING_RULE_BUILDER, RepositoryValidatingRuleBuilder.class)
.forResourcesOfType("Encounter") .forResourcesOfType("Encounter")
.requireValidationToDeclaredProfiles().withBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel.Ignore) .requireValidationToDeclaredProfiles().withBestPracticeWarningLevel(BestPracticeWarningLevel.Ignore)
.build(); .build();
RepositoryValidatingInterceptor repositoryValidatingInterceptor = new RepositoryValidatingInterceptor(); RepositoryValidatingInterceptor repositoryValidatingInterceptor = new RepositoryValidatingInterceptor();

View File

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>5.7.0-PRE3-SNAPSHOT</version> <version>5.7.0-PRE4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </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.engine.cfg.BackendSettings;
import org.hibernate.search.mapper.orm.cfg.HibernateOrmMapperSettings; import org.hibernate.search.mapper.orm.cfg.HibernateOrmMapperSettings;
import org.hl7.fhir.dstu2.model.Subscription; 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.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
@ -96,7 +96,7 @@ public class TestDstu2Config extends BaseJavaConfigDstu2 {
@Bean @Bean
public ValidationSettings validationSettings() { public ValidationSettings validationSettings() {
ValidationSettings retVal = super.validationSettings(); ValidationSettings retVal = super.validationSettings();
retVal.setLocalReferenceValidationDefaultPolicy(IResourceValidator.ReferenceValidationPolicy.CHECK_VALID); retVal.setLocalReferenceValidationDefaultPolicy(ReferenceValidationPolicy.CHECK_VALID);
return retVal; 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.engine.cfg.BackendSettings;
import org.hibernate.search.mapper.orm.cfg.HibernateOrmMapperSettings; import org.hibernate.search.mapper.orm.cfg.HibernateOrmMapperSettings;
import org.hl7.fhir.dstu2.model.Subscription; 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.Autowire;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
@ -93,7 +93,7 @@ public class TestDstu3Config extends BaseJavaConfigDstu3 {
@Bean @Bean
public ValidationSettings validationSettings() { public ValidationSettings validationSettings() {
ValidationSettings retVal = super.validationSettings(); ValidationSettings retVal = super.validationSettings();
retVal.setLocalReferenceValidationDefaultPolicy(IResourceValidator.ReferenceValidationPolicy.CHECK_VALID); retVal.setLocalReferenceValidationDefaultPolicy(ReferenceValidationPolicy.CHECK_VALID);
return retVal; 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.backend.lucene.cfg.LuceneIndexSettings;
import org.hibernate.search.engine.cfg.BackendSettings; import org.hibernate.search.engine.cfg.BackendSettings;
import org.hl7.fhir.dstu2.model.Subscription; 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.Autowire;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
@ -90,7 +90,7 @@ public class TestR4Config extends BaseJavaConfigR4 {
@Bean @Bean
public ValidationSettings validationSettings() { public ValidationSettings validationSettings() {
ValidationSettings retVal = super.validationSettings(); ValidationSettings retVal = super.validationSettings();
retVal.setLocalReferenceValidationDefaultPolicy(IResourceValidator.ReferenceValidationPolicy.CHECK_VALID); retVal.setLocalReferenceValidationDefaultPolicy(ReferenceValidationPolicy.CHECK_VALID);
return retVal; 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.engine.cfg.BackendSettings;
import org.hibernate.search.mapper.orm.cfg.HibernateOrmMapperSettings; import org.hibernate.search.mapper.orm.cfg.HibernateOrmMapperSettings;
import org.hl7.fhir.dstu2.model.Subscription; 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.Autowire;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
@ -92,7 +92,7 @@ public class TestR5Config extends BaseJavaConfigR5 {
@Bean @Bean
public ValidationSettings validationSettings() { public ValidationSettings validationSettings() {
ValidationSettings retVal = super.validationSettings(); ValidationSettings retVal = super.validationSettings();
retVal.setLocalReferenceValidationDefaultPolicy(IResourceValidator.ReferenceValidationPolicy.CHECK_VALID); retVal.setLocalReferenceValidationDefaultPolicy(ReferenceValidationPolicy.CHECK_VALID);
return retVal; return retVal;
} }

View File

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

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

View File

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

View File

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

View File

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

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

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

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </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.FhirContext;
import ca.uhn.fhir.context.support.IValidationSupport; import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster; 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.jpa.validation.ValidatorResourceFetcher;
import ca.uhn.fhir.rest.server.interceptor.ValidationResultEnrichingInterceptor; import ca.uhn.fhir.rest.server.interceptor.ValidationResultEnrichingInterceptor;
import ca.uhn.fhir.validation.ResultSeverityEnum; import ca.uhn.fhir.validation.ResultSeverityEnum;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.apache.commons.text.WordUtils; 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 org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -57,6 +58,8 @@ public final class RepositoryValidatingRuleBuilder implements IRuleRoot {
@Autowired @Autowired
private ValidatorResourceFetcher myValidatorResourceFetcher; private ValidatorResourceFetcher myValidatorResourceFetcher;
@Autowired @Autowired
private ValidatorPolicyAdvisor myValidationPolicyAdvisor;
@Autowired
private IInterceptorBroadcaster myInterceptorBroadcaster; private IInterceptorBroadcaster myInterceptorBroadcaster;
/** /**
@ -175,7 +178,8 @@ public final class RepositoryValidatingRuleBuilder implements IRuleRoot {
* @see ValidationResultEnrichingInterceptor * @see ValidationResultEnrichingInterceptor
*/ */
public FinalizedRequireValidationRule requireValidationToDeclaredProfiles() { 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); myRules.add(rule);
return new FinalizedRequireValidationRule(rule); return new FinalizedRequireValidationRule(rule);
} }
@ -205,9 +209,9 @@ public final class RepositoryValidatingRuleBuilder implements IRuleRoot {
*/ */
@Nonnull @Nonnull
public FinalizedRequireValidationRule withBestPracticeWarningLevel(String theBestPracticeWarningLevel) { public FinalizedRequireValidationRule withBestPracticeWarningLevel(String theBestPracticeWarningLevel) {
IResourceValidator.BestPracticeWarningLevel level = null; BestPracticeWarningLevel level = null;
if (isNotBlank(theBestPracticeWarningLevel)) { if (isNotBlank(theBestPracticeWarningLevel)) {
level = IResourceValidator.BestPracticeWarningLevel.valueOf(WordUtils.capitalize(theBestPracticeWarningLevel.toLowerCase())); level = BestPracticeWarningLevel.valueOf(WordUtils.capitalize(theBestPracticeWarningLevel.toLowerCase()));
} }
return withBestPracticeWarningLevel(level); 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 * 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 * 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. * 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. * to not include any best practice notifications.
*/ */
@Nonnull @Nonnull
public FinalizedRequireValidationRule withBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel bestPracticeWarningLevel) { public FinalizedRequireValidationRule withBestPracticeWarningLevel(BestPracticeWarningLevel bestPracticeWarningLevel) {
myRule.setBestPracticeWarningLevel(bestPracticeWarningLevel); myRule.setBestPracticeWarningLevel(bestPracticeWarningLevel);
return this; 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.FhirContext;
import ca.uhn.fhir.context.support.IValidationSupport; import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster; 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.jpa.validation.ValidatorResourceFetcher;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.interceptor.ValidationResultEnrichingInterceptor; 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.apache.commons.lang3.builder.ToStringStyle;
import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator; import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator;
import org.hl7.fhir.instance.model.api.IBaseResource; 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 javax.annotation.Nonnull;
import java.util.ArrayList; import java.util.ArrayList;
@ -49,17 +50,23 @@ class RequireValidationRule extends BaseTypedRule {
private ResultSeverityEnum myRejectOnSeverity = ResultSeverityEnum.ERROR; private ResultSeverityEnum myRejectOnSeverity = ResultSeverityEnum.ERROR;
private List<TagOnSeverity> myTagOnSeverity = Collections.emptyList(); 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); super(theFhirContext, theType);
myInterceptorBroadcaster = theInterceptorBroadcaster; myInterceptorBroadcaster = theInterceptorBroadcaster;
myValidator = new FhirInstanceValidator(theValidationSupport); myValidator = new FhirInstanceValidator(theValidationSupport);
myValidator.setValidatorResourceFetcher(theValidatorResourceFetcher); 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); myValidator.setBestPracticeWarningLevel(theBestPracticeWarningLevel);
} }

View File

@ -20,14 +20,14 @@ package ca.uhn.fhir.jpa.validation;
* #L% * #L%
*/ */
import org.hl7.fhir.r5.utils.IResourceValidator; import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
import org.thymeleaf.util.Validate; import org.thymeleaf.util.Validate;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
public class ValidationSettings { 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}. * 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 * @since 5.1.0
*/ */
@Nonnull @Nonnull
public IResourceValidator.ReferenceValidationPolicy getLocalReferenceValidationDefaultPolicy() { public ReferenceValidationPolicy getLocalReferenceValidationDefaultPolicy() {
return myLocalReferenceValidationDefaultPolicy; return myLocalReferenceValidationDefaultPolicy;
} }
@ -54,7 +54,7 @@ public class ValidationSettings {
* *
* @since 5.1.0 * @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"); Validate.notNull(theLocalReferenceValidationDefaultPolicy, "theLocalReferenceValidationDefaultPolicy must not be null");
myLocalReferenceValidationDefaultPolicy = theLocalReferenceValidationDefaultPolicy; 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.Element;
import org.hl7.fhir.r5.elementmodel.JsonParser; import org.hl7.fhir.r5.elementmodel.JsonParser;
import org.hl7.fhir.r5.model.CanonicalResource; 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.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -46,23 +47,21 @@ import java.net.MalformedURLException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.Locale; import java.util.Locale;
public class ValidatorResourceFetcher implements IResourceValidator.IValidatorResourceFetcher { public class ValidatorResourceFetcher implements IValidatorResourceFetcher {
private static final Logger ourLog = LoggerFactory.getLogger(ValidatorResourceFetcher.class); private static final Logger ourLog = LoggerFactory.getLogger(ValidatorResourceFetcher.class);
@Autowired @Autowired
private DaoRegistry myDaoRegistry; private DaoRegistry myDaoRegistry;
@Autowired @Autowired
private ValidationSettings myValidationSettings;
@Autowired
private FhirContext myFhirContext; private FhirContext myFhirContext;
@Autowired @Autowired
private IValidationSupport myValidationSupport; private IValidationSupport myValidationSupport;
private VersionSpecificWorkerContextWrapper myVersionSpecificCOntextWrapper; private VersionSpecificWorkerContextWrapper myVersionSpecificContextWrapper;
@PostConstruct @PostConstruct
public void start() { public void start() {
myVersionSpecificCOntextWrapper = VersionSpecificWorkerContextWrapper.newVersionSpecificWorkerContextWrapper(myValidationSupport); myVersionSpecificContextWrapper = VersionSpecificWorkerContextWrapper.newVersionSpecificWorkerContextWrapper(myValidationSupport);
} }
@Override @Override
@ -79,23 +78,12 @@ public class ValidatorResourceFetcher implements IResourceValidator.IValidatorRe
} }
try { try {
return new JsonParser(myVersionSpecificCOntextWrapper).parse(myFhirContext.newJsonParser().encodeResourceToString(target), resourceType); return new JsonParser(myVersionSpecificContextWrapper).parse(myFhirContext.newJsonParser().encodeResourceToString(target), resourceType);
} catch (Exception e) { } catch (Exception e) {
throw new FHIRException(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 @Override
public boolean resolveURL(IResourceValidator iResourceValidator, Object o, String s, String s1, String s2) throws IOException, FHIRException { public boolean resolveURL(IResourceValidator iResourceValidator, Object o, String s, String s1, String s2) throws IOException, FHIRException {
return true; return true;
@ -107,7 +95,7 @@ public class ValidatorResourceFetcher implements IResourceValidator.IValidatorRe
} }
@Override @Override
public IResourceValidator.IValidatorResourceFetcher setLocale(Locale locale) { public IValidatorResourceFetcher setLocale(Locale locale) {
// ignore // ignore
return this; return this;
} }

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </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.model.ValueSet.ValueSetExpansionComponent;
import org.hl7.fhir.dstu3.terminologies.ValueSetExpander; import org.hl7.fhir.dstu3.terminologies.ValueSetExpander;
import org.hl7.fhir.dstu3.utils.INarrativeGenerator; 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.exceptions.FHIRException;
import org.hl7.fhir.utilities.i18n.I18nBase; import org.hl7.fhir.utilities.i18n.I18nBase;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </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;
import org.hl7.fhir.r4.model.ValueSet.ConceptSetComponent; import org.hl7.fhir.r4.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.r4.terminologies.ValueSetExpander; 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.TranslationServices;
import org.hl7.fhir.utilities.i18n.I18nBase; import org.hl7.fhir.utilities.i18n.I18nBase;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </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;
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent; import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.r5.terminologies.ValueSetExpander; 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.TimeTracker;
import org.hl7.fhir.utilities.TranslationServices; import org.hl7.fhir.utilities.TranslationServices;
import org.hl7.fhir.utilities.i18n.I18nBase; 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 @Override
public List<ConceptMap> findMapsForSource(String theUrl) { public List<ConceptMap> findMapsForSource(String theUrl) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
@ -170,7 +179,7 @@ public final class HapiWorkerContext extends I18nBase implements IWorkerContext
String system = theCode.getSystem(); String system = theCode.getSystem();
String code = theCode.getCode(); String code = theCode.getCode();
String display = theCode.getDisplay(); String display = theCode.getDisplay();
return validateCode(theOptions, system, code, display, theVs); return validateCode(theOptions, system, null, code, display, theVs);
} }
@Override @Override
@ -179,8 +188,15 @@ public final class HapiWorkerContext extends I18nBase implements IWorkerContext
} }
@Override @Override
public ValidationResult validateCode(ValidationOptions theOptions, String theSystem, String theCode, String theDisplay) { public ValueSetExpander.ValueSetExpansionOutcome expandVS(ValueSet theValueSet, boolean cacheOk, boolean heiarchical, boolean incompleteOk) {
IValidationSupport.CodeValidationResult result = myValidationSupport.validateCode(new ValidationSupportContext(myValidationSupport), convertConceptValidationOptions(theOptions), theSystem, theCode, theDisplay, null); 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) { if (result == null) {
return null; return null;
} }
@ -193,13 +209,15 @@ public final class HapiWorkerContext extends I18nBase implements IWorkerContext
} }
@Override @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; IValidationSupport.CodeValidationResult outcome;
if (isNotBlank(theVs.getUrl())) { 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 { } 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()) { 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(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 @Override
public ValidationResult validateCode(ValidationOptions theOptions, String code, ValueSet vs) { 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 @Override

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

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

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <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> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </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.TypeDetails;
import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.utils.FHIRPathEngine; import org.hl7.fhir.r5.utils.FHIRPathEngine;
import org.hl7.fhir.r5.utils.IResourceValidator; import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor;
import org.hl7.fhir.r5.utils.IResourceValidator.BestPracticeWarningLevel; 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 org.hl7.fhir.utilities.validation.ValidationMessage;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -35,7 +36,8 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
private boolean errorForUnknownProfiles = true; private boolean errorForUnknownProfiles = true;
private boolean assumeValidRestReferences; private boolean assumeValidRestReferences;
private List<String> myExtensionDomains = Collections.emptyList(); private List<String> myExtensionDomains = Collections.emptyList();
private IResourceValidator.IValidatorResourceFetcher validatorResourceFetcher; private IValidatorResourceFetcher validatorResourceFetcher;
private IValidationPolicyAdvisor validatorPolicyAdvisor;
/** /**
* Constructor * Constructor
@ -227,6 +229,8 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
.setBestPracticeWarningLevel(getBestPracticeWarningLevel()) .setBestPracticeWarningLevel(getBestPracticeWarningLevel())
.setErrorForUnknownProfiles(isErrorForUnknownProfiles()) .setErrorForUnknownProfiles(isErrorForUnknownProfiles())
.setExtensionDomains(getExtensionDomains()) .setExtensionDomains(getExtensionDomains())
.setValidatorResourceFetcher(validatorResourceFetcher)
.setValidationPolicyAdvisor(validatorPolicyAdvisor)
.setNoTerminologyChecks(isNoTerminologyChecks()) .setNoTerminologyChecks(isNoTerminologyChecks())
.setNoExtensibleWarnings(isNoExtensibleWarnings()) .setNoExtensibleWarnings(isNoExtensibleWarnings())
.setNoBindingMsgSuppressed(isNoBindingMsgSuppressed()) .setNoBindingMsgSuppressed(isNoBindingMsgSuppressed())
@ -245,11 +249,19 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IInsta
return wrappedWorkerContext; return wrappedWorkerContext;
} }
public IResourceValidator.IValidatorResourceFetcher getValidatorResourceFetcher() { public IValidationPolicyAdvisor getValidatorPolicyAdvisor() {
return validatorPolicyAdvisor;
}
public void setValidatorPolicyAdvisor(IValidationPolicyAdvisor validatorPolicyAdvisor) {
this.validatorPolicyAdvisor = validatorPolicyAdvisor;
}
public IValidatorResourceFetcher getValidatorResourceFetcher() {
return validatorResourceFetcher; return validatorResourceFetcher;
} }
public void setValidatorResourceFetcher(IResourceValidator.IValidatorResourceFetcher validatorResourceFetcher) { public void setValidatorResourceFetcher(IValidatorResourceFetcher validatorResourceFetcher) {
this.validatorResourceFetcher = 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.elementmodel.Manager;
import org.hl7.fhir.r5.model.StructureDefinition; import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.utils.FHIRPathEngine; 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.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.utilities.validation.ValidationMessage;
import org.hl7.fhir.validation.instance.InstanceValidator; import org.hl7.fhir.validation.instance.InstanceValidator;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -34,7 +37,7 @@ import java.util.List;
class ValidatorWrapper { class ValidatorWrapper {
private static final Logger ourLog = LoggerFactory.getLogger(ValidatorWrapper.class); private static final Logger ourLog = LoggerFactory.getLogger(ValidatorWrapper.class);
private IResourceValidator.BestPracticeWarningLevel myBestPracticeWarningLevel; private BestPracticeWarningLevel myBestPracticeWarningLevel;
private boolean myAnyExtensionsAllowed; private boolean myAnyExtensionsAllowed;
private boolean myErrorForUnknownProfiles; private boolean myErrorForUnknownProfiles;
private boolean myNoTerminologyChecks; private boolean myNoTerminologyChecks;
@ -42,7 +45,8 @@ class ValidatorWrapper {
private boolean myNoExtensibleWarnings; private boolean myNoExtensibleWarnings;
private boolean myNoBindingMsgSuppressed; private boolean myNoBindingMsgSuppressed;
private Collection<? extends String> myExtensionDomains; private Collection<? extends String> myExtensionDomains;
private IResourceValidator.IValidatorResourceFetcher myValidatorResourceFetcher; private IValidatorResourceFetcher myValidatorResourceFetcher;
private IValidationPolicyAdvisor myValidationPolicyAdvisor;
/** /**
* Constructor * Constructor
@ -60,7 +64,7 @@ class ValidatorWrapper {
return this; return this;
} }
public ValidatorWrapper setBestPracticeWarningLevel(IResourceValidator.BestPracticeWarningLevel theBestPracticeWarningLevel) { public ValidatorWrapper setBestPracticeWarningLevel(BestPracticeWarningLevel theBestPracticeWarningLevel) {
myBestPracticeWarningLevel = theBestPracticeWarningLevel; myBestPracticeWarningLevel = theBestPracticeWarningLevel;
return this; return this;
} }
@ -95,8 +99,12 @@ class ValidatorWrapper {
return this; 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; this.myValidatorResourceFetcher = validatorResourceFetcher;
return this; return this;
} }
@ -114,11 +122,12 @@ class ValidatorWrapper {
v.setAssumeValidRestReferences(isAssumeValidRestReferences()); v.setAssumeValidRestReferences(isAssumeValidRestReferences());
v.setBestPracticeWarningLevel(myBestPracticeWarningLevel); v.setBestPracticeWarningLevel(myBestPracticeWarningLevel);
v.setAnyExtensionsAllowed(myAnyExtensionsAllowed); v.setAnyExtensionsAllowed(myAnyExtensionsAllowed);
v.setResourceIdRule(IResourceValidator.IdStatus.OPTIONAL); v.setResourceIdRule(IdStatus.OPTIONAL);
v.setNoTerminologyChecks(myNoTerminologyChecks); v.setNoTerminologyChecks(myNoTerminologyChecks);
v.setErrorForUnknownProfiles(myErrorForUnknownProfiles); v.setErrorForUnknownProfiles(myErrorForUnknownProfiles);
v.getExtensionDomains().addAll(myExtensionDomains); v.getExtensionDomains().addAll(myExtensionDomains);
v.setFetcher(myValidatorResourceFetcher); v.setFetcher(myValidatorResourceFetcher);
v.setPolicyAdvisor(myValidationPolicyAdvisor);
v.setNoExtensibleWarnings(myNoExtensibleWarnings); v.setNoExtensibleWarnings(myNoExtensibleWarnings);
v.setNoBindingMsgSuppressed(myNoBindingMsgSuppressed); v.setNoBindingMsgSuppressed(myNoBindingMsgSuppressed);
v.setAllowXsiLocation(true); 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.IParser;
import org.hl7.fhir.r5.formats.ParserType; import org.hl7.fhir.r5.formats.ParserType;
import org.hl7.fhir.r5.model.CanonicalResource; 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.Coding;
import org.hl7.fhir.r5.model.Resource; import org.hl7.fhir.r5.model.Resource;
import org.hl7.fhir.r5.model.StructureDefinition; import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.terminologies.ValueSetExpander; 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.TimeTracker;
import org.hl7.fhir.utilities.TranslationServices; import org.hl7.fhir.utilities.TranslationServices;
import org.hl7.fhir.utilities.i18n.I18nBase; 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 @Override
public <T extends Resource> T fetchResource(Class<T> class_, String uri) { public <T extends Resource> T fetchResource(Class<T> class_, String uri) {
@ -514,14 +528,18 @@ public class VersionSpecificWorkerContextWrapper extends I18nBase implements IWo
} }
@Override @Override
public ValidationResult validateCode(ValidationOptions theOptions, String system, String code, String display) { public ValueSetExpander.ValueSetExpansionOutcome expandVS(ValueSet source, boolean cacheOk, boolean heiarchical, boolean incompleteOk) {
ConceptValidationOptions validationOptions = convertConceptValidationOptions(theOptions); 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); return doValidation(null, validationOptions, system, code, display);
} }
@Override @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; IBaseResource convertedVs = null;
try { 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 { public class VersionTypeConverterDstu21 implements VersionSpecificWorkerContextWrapper.IVersionTypeConverter {
@Override @Override
public Resource toCanonical(IBaseResource theNonCanonical) { 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 @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.model.ValueSet.ValueSetExpansionComponent;
import org.hl7.fhir.dstu3.utils.FHIRPathEngine; import org.hl7.fhir.dstu3.utils.FHIRPathEngine;
import org.hl7.fhir.instance.model.api.IBaseResource; 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.hl7.fhir.utilities.validation.ValidationMessage;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
@ -595,7 +597,8 @@ public class FhirInstanceValidatorDstu3Test {
ValidationResult output = myVal.validateWithResult(input); ValidationResult output = myVal.validateWithResult(input);
List<SingleValidationMessage> issues = logResultsAndReturnNonInformationalOnes(output); 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 @Test
@ -665,6 +668,9 @@ public class FhirInstanceValidatorDstu3Test {
return false; return false;
} else if (t.getMessage().contains("The valueSet reference http://www.rfc-editor.org/bcp/bcp13.txt on element")) { } else if (t.getMessage().contains("The valueSet reference http://www.rfc-editor.org/bcp/bcp13.txt on element")) {
return false; 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 { } else {
return true; return true;
} }
@ -1180,7 +1186,7 @@ public class FhirInstanceValidatorDstu3Test {
ValidationResult output = myVal.validateWithResult(input); ValidationResult output = myVal.validateWithResult(input);
logResultsAndReturnAll(output); logResultsAndReturnAll(output);
assertEquals( 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()); output.getMessages().get(0).getMessage());
} }
@ -1277,7 +1283,7 @@ public class FhirInstanceValidatorDstu3Test {
assertEquals(1, all.size()); assertEquals(1, all.size());
assertEquals("Patient.identifier[0].type", all.get(0).getLocationString()); assertEquals("Patient.identifier[0].type", all.get(0).getLocationString());
assertEquals( 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()); all.get(0).getMessage());
assertEquals(ResultSeverityEnum.WARNING, all.get(0).getSeverity()); assertEquals(ResultSeverityEnum.WARNING, all.get(0).getSeverity());
@ -1310,14 +1316,18 @@ public class FhirInstanceValidatorDstu3Test {
public void testInvocationOfValidatorFetcher() throws IOException { public void testInvocationOfValidatorFetcher() throws IOException {
String input = IOUtils.toString(FhirInstanceValidatorDstu3Test.class.getResourceAsStream("/dstu3-rick-test.json"), Charsets.UTF_8); String input = IOUtils.toString(FhirInstanceValidatorDstu3Test.class.getResourceAsStream("/dstu3-rick-test.json"), Charsets.UTF_8);
IResourceValidator.IValidatorResourceFetcher resourceFetcher = mock(IResourceValidator.IValidatorResourceFetcher.class); IValidationPolicyAdvisor policyAdvisor = mock(IValidationPolicyAdvisor.class);
when(resourceFetcher.validationPolicy(any(), any(), any(), any())).thenReturn(IResourceValidator.ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS); IValidatorResourceFetcher fetcher = mock(IValidatorResourceFetcher.class);
myInstanceVal.setValidatorResourceFetcher(resourceFetcher);
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); myVal.validateWithResult(input);
verify(resourceFetcher, times(3)).resolveURL(any(), any(), anyString(), anyString(), anyString()); verify(fetcher, times(3)).resolveURL(any(), any(), anyString(), anyString(), anyString());
verify(resourceFetcher, times(4)).validationPolicy(any(), any(), anyString(), anyString()); verify(policyAdvisor, times(4)).policyForReference(any(), any(), anyString(), anyString());
verify(resourceFetcher, times(4)).fetch(any(), any(), anyString()); verify(fetcher, times(4)).fetch(any(), any(), anyString());
} }
@Test @Test

View File

@ -165,7 +165,7 @@ public class ResourceValidatorDstu3Test {
ValidationResult output = val.validateWithResult(p); ValidationResult output = val.validateWithResult(p);
List<SingleValidationMessage> all = logResultsAndReturnNonInformationalOnes(output); 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()); 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.model.ValueSet.ValueSetExpansionComponent;
import org.hl7.fhir.r4.terminologies.ValueSetExpander; import org.hl7.fhir.r4.terminologies.ValueSetExpander;
import org.hl7.fhir.r4.utils.FHIRPathEngine; 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.validation.ValidationMessage;
import org.hl7.fhir.utilities.xhtml.XhtmlNode; import org.hl7.fhir.utilities.xhtml.XhtmlNode;
import org.junit.jupiter.api.AfterAll; 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.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.extension.RegisterExtension;
import org.mockito.MockingDetails;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock; import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer; import org.mockito.stubbing.Answer;
@ -470,7 +476,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest {
// With BPs enabled // With BPs enabled
val = ourCtx.newValidator(); val = ourCtx.newValidator();
instanceModule = new FhirInstanceValidator(myValidationSupport); instanceModule = new FhirInstanceValidator(myValidationSupport);
IResourceValidator.BestPracticeWarningLevel level = IResourceValidator.BestPracticeWarningLevel.Error; BestPracticeWarningLevel level = BestPracticeWarningLevel.Error;
instanceModule.setBestPracticeWarningLevel(level); instanceModule.setBestPracticeWarningLevel(level);
val.registerValidatorModule(instanceModule); val.registerValidatorModule(instanceModule);
result = val.validateWithResult(input); result = val.validateWithResult(input);
@ -634,7 +640,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest {
ValidationResult output = myFhirValidator.validateWithResult(input); ValidationResult output = myFhirValidator.validateWithResult(input);
List<SingleValidationMessage> errors = logResultsAndReturnAll(output); List<SingleValidationMessage> errors = logResultsAndReturnAll(output);
assertEquals(1, errors.size()); 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 @Test
@ -1206,7 +1212,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest {
ValidationResult output = myFhirValidator.validateWithResult(input); ValidationResult output = myFhirValidator.validateWithResult(input);
logResultsAndReturnAll(output); logResultsAndReturnAll(output);
assertEquals( 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()); output.getMessages().get(0).getMessage());
} }
@ -1338,7 +1344,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest {
List<SingleValidationMessage> all = logResultsAndReturnAll(output); List<SingleValidationMessage> all = logResultsAndReturnAll(output);
assertEquals(1, all.size()); assertEquals(1, all.size());
assertEquals("Patient.identifier[0].type", all.get(0).getLocationString()); 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()); assertEquals(ResultSeverityEnum.WARNING, all.get(0).getSeverity());
} }
@ -1359,7 +1365,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest {
all = logResultsAndReturnNonInformationalOnes(output); all = logResultsAndReturnNonInformationalOnes(output);
assertEquals(2, all.size()); assertEquals(2, all.size());
assertThat(all.get(0).getMessage(), containsString("Validation failed for 'http://unitsofmeasure.org#Heck'")); 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"); String encoded = loadResource("/r4/r4-caredove-bundle.json");
IResourceValidator.IValidatorResourceFetcher resourceFetcher = mock(IResourceValidator.IValidatorResourceFetcher.class); IValidatorResourceFetcher resourceFetcher = mock(IValidatorResourceFetcher.class);
when(resourceFetcher.validationPolicy(any(), any(), any(), any())).thenReturn(IResourceValidator.ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS); IValidationPolicyAdvisor policyAdvisor = mock(IValidationPolicyAdvisor.class);
myInstanceVal.setValidatorResourceFetcher(resourceFetcher);
myFhirValidator.validateWithResult(encoded);
verify(resourceFetcher, times(15)).resolveURL(any(), any(), anyString(), anyString(), anyString()); when(policyAdvisor.policyForReference(any(), any(), any(), any())).thenReturn(ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS);
verify(resourceFetcher, times(12)).validationPolicy(any(), any(), anyString(), anyString()); when(policyAdvisor.policyForContained(any(), any(), any(), any(), any(), any(), any())).thenReturn(ContainedReferenceValidationPolicy.CHECK_TYPE);
verify(resourceFetcher, times(12)).fetch(any(), any(), anyString()); 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 @Test
@ -1457,7 +1466,7 @@ public class FhirInstanceValidatorR4Test extends BaseTest {
ValidationResult output = myFhirValidator.validateWithResult(input); ValidationResult output = myFhirValidator.validateWithResult(input);
List<SingleValidationMessage> errors = logResultsAndReturnNonInformationalOnes(output); List<SingleValidationMessage> errors = logResultsAndReturnNonInformationalOnes(output);
assertEquals(1, errors.size(), errors.toString()); 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;
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent;
import org.hl7.fhir.r5.terminologies.ValueSetExpander; 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.hl7.fhir.utilities.xhtml.XhtmlNode;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
@ -304,7 +308,7 @@ public class FhirInstanceValidatorR5Test {
// With BPs enabled // With BPs enabled
val = ourCtx.newValidator(); val = ourCtx.newValidator();
instanceModule = new FhirInstanceValidator(myValidationSupport); instanceModule = new FhirInstanceValidator(myValidationSupport);
IResourceValidator.BestPracticeWarningLevel level = IResourceValidator.BestPracticeWarningLevel.Error; BestPracticeWarningLevel level = BestPracticeWarningLevel.Error;
instanceModule.setBestPracticeWarningLevel(level); instanceModule.setBestPracticeWarningLevel(level);
val.registerValidatorModule(instanceModule); val.registerValidatorModule(instanceModule);
result = val.validateWithResult(input); result = val.validateWithResult(input);
@ -446,14 +450,17 @@ public class FhirInstanceValidatorR5Test {
String input = IOUtils.toString(FhirInstanceValidator.class.getResourceAsStream("/vitals.json"), Charsets.UTF_8); String input = IOUtils.toString(FhirInstanceValidator.class.getResourceAsStream("/vitals.json"), Charsets.UTF_8);
IResourceValidator.IValidatorResourceFetcher resourceFetcher = mock(IResourceValidator.IValidatorResourceFetcher.class); IValidatorResourceFetcher resourceFetcher = mock(IValidatorResourceFetcher.class);
when(resourceFetcher.validationPolicy(any(), any(), any(), any())).thenReturn(IResourceValidator.ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS); IValidationPolicyAdvisor policyAdvisor = mock(IValidationPolicyAdvisor.class);
when(policyAdvisor.policyForReference(any(), any(), any(), any())).thenReturn(ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS);
myInstanceVal.setValidatorResourceFetcher(resourceFetcher); myInstanceVal.setValidatorResourceFetcher(resourceFetcher);
myInstanceVal.setValidatorPolicyAdvisor(policyAdvisor);
myVal.validateWithResult(input); myVal.validateWithResult(input);
verify(resourceFetcher, times(13)).resolveURL(any(), any(), anyString(), anyString(), anyString()); //verify(resourceFetcher, times(13)).resolveURL(any(), any(), anyString(), anyString(), anyString());
verify(resourceFetcher, times(4)).validationPolicy(any(), any(), anyString(), anyString()); verify(policyAdvisor, times(4)).policyForReference(any(), any(), anyString(), anyString());
verify(resourceFetcher, times(3)).fetch(any(), any(), anyString()); //verify(resourceFetcher, times(3)).fetch(any(), any(), anyString());
} }
@Test @Test
@ -862,7 +869,7 @@ public class FhirInstanceValidatorR5Test {
logResultsAndReturnAll(output); logResultsAndReturnAll(output);
assertThat( assertThat(
output.getMessages().get(0).getMessage(), 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(1, all.size());
assertEquals("Patient.identifier[0].type", all.get(0).getLocationString()); assertEquals("Patient.identifier[0].type", all.get(0).getLocationString());
assertEquals( 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()); all.get(0).getMessage());
assertEquals(ResultSeverityEnum.WARNING, all.get(0).getSeverity()); assertEquals(ResultSeverityEnum.WARNING, all.get(0).getSeverity());

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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