diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_0_0/3436-allow-unknown-codesystem-warning.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_0_0/3436-allow-unknown-codesystem-warning.yaml new file mode 100644 index 00000000000..e1c8b5c2198 --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_0_0/3436-allow-unknown-codesystem-warning.yaml @@ -0,0 +1,7 @@ +--- +type: fix +issue: 3436 +jira: SMILE-3563 +title: "A regression in HAPI FHIR 5.7.0 meant that when UnknownCodeSystemWarningValidationSupport was + configured for WARNING behaviour, validating a field with an implicit code system could + incorrectly result in an error." diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/validation/JpaValidationSupportChain.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/validation/JpaValidationSupportChain.java index af776a697ff..a665cd44fa2 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/validation/JpaValidationSupportChain.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/validation/JpaValidationSupportChain.java @@ -75,16 +75,17 @@ public class JpaValidationSupportChain extends ValidationSupportChain { @PostConstruct public void postConstruct() { - addValidationSupport(myUnknownCodeSystemWarningValidationSupport); addValidationSupport(myDefaultProfileValidationSupport); addValidationSupport(myJpaValidationSupport); - //TODO MAKE SURE THAT THIS IS BEING CAL addValidationSupport(myTerminologyService); addValidationSupport(new SnapshotGeneratingValidationSupport(myFhirContext)); addValidationSupport(new InMemoryTerminologyServerValidationSupport(myFhirContext)); addValidationSupport(myNpmJpaValidationSupport); addValidationSupport(new CommonCodeSystemsTerminologyService(myFhirContext)); addValidationSupport(myConceptMappingSvc); + + // This needs to be last in the chain, it was designed for that + addValidationSupport(myUnknownCodeSystemWarningValidationSupport); } } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ValidateTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ValidateTest.java index d1dc4f006f1..eeddfd45f59 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ValidateTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ValidateTest.java @@ -36,6 +36,7 @@ import org.hl7.fhir.instance.model.api.IBaseOperationOutcome; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.r4.model.AllergyIntolerance; +import org.hl7.fhir.r4.model.Binary; import org.hl7.fhir.r4.model.Bundle; import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent; import org.hl7.fhir.r4.model.CanonicalType; @@ -125,23 +126,11 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test { myUnknownCodeSystemWarningValidationSupport.setNonExistentCodeSystemSeverity(UnknownCodeSystemWarningValidationSupport.DEFAULT_SEVERITY); } - /** - * By default an unknown code system should fail vaildation - */ @Test public void testValidateCodeInValueSetWithUnknownCodeSystem_FailValidation() { - createStructureDefWithBindingToUnknownCs(); + createStructureDefWithBindingToUnknownCs(true); - Observation obs = new Observation(); - obs.getMeta().addProfile("http://sd"); - obs.getText().setDivAsString("
Hello
"); - obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED); - obs.getCategoryFirstRep().addCoding().setSystem("http://terminology.hl7.org/CodeSystem/observation-category").setCode("vital-signs"); - obs.getCode().setText("hello"); - obs.setSubject(new Reference("Patient/123")); - obs.addPerformer(new Reference("Practitioner/123")); - obs.setEffective(DateTimeType.now()); - obs.setStatus(ObservationStatus.FINAL); + Observation obs = createObservationForUnknownCodeSystemTest(); OperationOutcome oo; @@ -163,6 +152,210 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test { } + @Test + public void testValidateCodeInEnumeratedValueSetWithUnknownCodeSystem_Information() { + myUnknownCodeSystemWarningValidationSupport.setNonExistentCodeSystemSeverity(IValidationSupport.IssueSeverity.INFORMATION); + + createStructureDefWithBindingToUnknownCs(true); + + Observation obs = createObservationForUnknownCodeSystemTest(); + + OperationOutcome oo; + String encoded; + + // Valid code + obs.setValue(new Quantity().setSystem("http://cs").setCode("code1").setValue(123)); + oo = validateAndReturnOutcome(obs, false); + encoded = encode(oo); + ourLog.info(encoded); + assertEquals(1, oo.getIssue().size()); + assertEquals("No issues detected during validation", oo.getIssueFirstRep().getDiagnostics()); + assertEquals(OperationOutcome.IssueSeverity.INFORMATION, oo.getIssueFirstRep().getSeverity()); + + // Invalid code + obs.setValue(new Quantity().setSystem("http://cs").setCode("code99").setValue(123)); + oo = validateAndReturnOutcome(obs, true); + encoded = encode(oo); + ourLog.info(encoded); + assertEquals(1, oo.getIssue().size()); + assertEquals("The code provided (http://cs#code99) is not in the value set http://vs, and a code from this value set is required: Unknown code 'http://cs#code99' for in-memory expansion of ValueSet 'http://vs'", oo.getIssueFirstRep().getDiagnostics()); + assertEquals(OperationOutcome.IssueSeverity.ERROR, oo.getIssueFirstRep().getSeverity()); + } + + /** + * By default, an unknown code system should fail validation + */ + @Test + public void testValidateCodeInEnumeratedValueSetWithUnknownCodeSystem_Warning() { + // set to warning + myUnknownCodeSystemWarningValidationSupport.setNonExistentCodeSystemSeverity(IValidationSupport.IssueSeverity.WARNING); + + createStructureDefWithBindingToUnknownCs(true); + + Observation obs = createObservationForUnknownCodeSystemTest(); + + OperationOutcome oo; + String encoded; + + // Valid code + obs.setValue(new Quantity().setSystem("http://cs").setCode("code1").setValue(123)); + oo = validateAndReturnOutcome(obs, false); + encoded = encode(oo); + ourLog.info(encoded); + assertEquals(1, oo.getIssue().size()); + assertEquals("CodeSystem is unknown and can't be validated: http://cs for 'http://cs#code1'", oo.getIssueFirstRep().getDiagnostics()); + assertEquals(OperationOutcome.IssueSeverity.WARNING, oo.getIssueFirstRep().getSeverity()); + + // Invalid code + obs.setValue(new Quantity().setSystem("http://cs").setCode("code99").setValue(123)); + oo = validateAndReturnOutcome(obs, true); + encoded = encode(oo); + ourLog.info(encoded); + assertEquals(2, oo.getIssue().size()); + assertEquals("CodeSystem is unknown and can't be validated: http://cs for 'http://cs#code99'", oo.getIssue().get(0).getDiagnostics()); + assertEquals(OperationOutcome.IssueSeverity.WARNING, oo.getIssue().get(0).getSeverity()); + assertEquals("The code provided (http://cs#code99) is not in the value set http://vs, and a code from this value set is required: Unknown code 'http://cs#code99' for in-memory expansion of ValueSet 'http://vs'", oo.getIssue().get(1).getDiagnostics()); + assertEquals(OperationOutcome.IssueSeverity.ERROR, oo.getIssue().get(1).getSeverity()); + } + + @Test + public void testValidateCodeInEnumeratedValueSetWithUnknownCodeSystem_Error() { + myUnknownCodeSystemWarningValidationSupport.setNonExistentCodeSystemSeverity(IValidationSupport.IssueSeverity.ERROR); + + createStructureDefWithBindingToUnknownCs(true); + + Observation obs = new Observation(); + obs.getMeta().addProfile("http://sd"); + obs.getText().setDivAsString("
Hello
"); + obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED); + obs.getCategoryFirstRep().addCoding().setSystem("http://terminology.hl7.org/CodeSystem/observation-category").setCode("vital-signs"); + obs.getCode().setText("hello"); + obs.setSubject(new Reference("Patient/123")); + obs.addPerformer(new Reference("Practitioner/123")); + obs.setEffective(DateTimeType.now()); + obs.setStatus(ObservationStatus.FINAL); + + OperationOutcome oo; + String encoded; + + // Valid code + obs.setValue(new Quantity().setSystem("http://cs").setCode("code1").setValue(123)); + oo = validateAndReturnOutcome(obs, false); + encoded = encode(oo); + ourLog.info(encoded); + assertEquals(1, oo.getIssue().size()); + assertTrue(oo.getIssueFirstRep().getDiagnostics().contains("No issues detected during validation")); + assertEquals(OperationOutcome.IssueSeverity.INFORMATION, oo.getIssueFirstRep().getSeverity()); + + // Invalid code + obs.setValue(new Quantity().setSystem("http://cs").setCode("code99").setValue(123)); + oo = validateAndReturnOutcome(obs, true); + encoded = encode(oo); + ourLog.info(encoded); + assertEquals(1, oo.getIssue().size()); + assertTrue(oo.getIssueFirstRep() + .getDiagnostics().contains("The code provided (http://cs#code99) is not in the value set http://vs, and a code from this value set is required: Unknown code 'http://cs#code99' for in-memory expansion of ValueSet 'http://vs'") + ); + assertEquals(OperationOutcome.IssueSeverity.ERROR, oo.getIssueFirstRep().getSeverity()); + } + + + @Test + public void testValidateCodeInNonEnumeratedValueSetWithUnknownCodeSystem_Information() { + myUnknownCodeSystemWarningValidationSupport.setNonExistentCodeSystemSeverity(IValidationSupport.IssueSeverity.INFORMATION); + + createStructureDefWithBindingToUnknownCs(false); + + Observation obs = createObservationForUnknownCodeSystemTest(); + + OperationOutcome oo; + String encoded; + + // Valid code + obs.setValue(new Quantity().setSystem("http://cs").setCode("code1").setValue(123)); + oo = validateAndReturnOutcome(obs, false); + encoded = encode(oo); + ourLog.info(encoded); + assertEquals(1, oo.getIssue().size()); + assertEquals("No issues detected during validation", oo.getIssueFirstRep().getDiagnostics()); + assertEquals(OperationOutcome.IssueSeverity.INFORMATION, oo.getIssueFirstRep().getSeverity()); + + // Invalid code + obs.setValue(new Quantity().setSystem("http://cs").setCode("code99").setValue(123)); + oo = validateAndReturnOutcome(obs, false); + encoded = encode(oo); + ourLog.info(encoded); + assertEquals(1, oo.getIssue().size()); + assertEquals("No issues detected during validation", oo.getIssueFirstRep().getDiagnostics()); + assertEquals(OperationOutcome.IssueSeverity.INFORMATION, oo.getIssueFirstRep().getSeverity()); + } + + /** + * By default, an unknown code system should fail validation + */ + @Test + public void testValidateCodeInNonEnumeratedValueSetWithUnknownCodeSystem_Warning() { + // set to warning + myUnknownCodeSystemWarningValidationSupport.setNonExistentCodeSystemSeverity(IValidationSupport.IssueSeverity.WARNING); + + createStructureDefWithBindingToUnknownCs(false); + + Observation obs = createObservationForUnknownCodeSystemTest(); + + OperationOutcome oo; + String encoded; + + // Valid code + obs.setValue(new Quantity().setSystem("http://cs").setCode("code1").setValue(123)); + oo = validateAndReturnOutcome(obs, false); + encoded = encode(oo); + ourLog.info(encoded); + assertEquals(1, oo.getIssue().size()); + assertEquals("CodeSystem is unknown and can't be validated: http://cs for 'http://cs#code1'", oo.getIssueFirstRep().getDiagnostics()); + assertEquals(OperationOutcome.IssueSeverity.WARNING, oo.getIssueFirstRep().getSeverity()); + + // Invalid code + obs.setValue(new Quantity().setSystem("http://cs").setCode("code99").setValue(123)); + oo = validateAndReturnOutcome(obs, false); + encoded = encode(oo); + ourLog.info(encoded); + assertEquals(1, oo.getIssue().size()); + assertEquals("CodeSystem is unknown and can't be validated: http://cs for 'http://cs#code99'", oo.getIssue().get(0).getDiagnostics()); + assertEquals(OperationOutcome.IssueSeverity.WARNING, oo.getIssue().get(0).getSeverity()); + } + + @Test + public void testValidateCodeInNonEnumeratedValueSetWithUnknownCodeSystem_Error() { + myUnknownCodeSystemWarningValidationSupport.setNonExistentCodeSystemSeverity(IValidationSupport.IssueSeverity.ERROR); + + createStructureDefWithBindingToUnknownCs(false); + + Observation obs = new Observation(); + obs.getMeta().addProfile("http://sd"); + obs.getText().setDivAsString("
Hello
"); + obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED); + obs.getCategoryFirstRep().addCoding().setSystem("http://terminology.hl7.org/CodeSystem/observation-category").setCode("vital-signs"); + obs.getCode().setText("hello"); + obs.setSubject(new Reference("Patient/123")); + obs.addPerformer(new Reference("Practitioner/123")); + obs.setEffective(DateTimeType.now()); + obs.setStatus(ObservationStatus.FINAL); + + OperationOutcome oo; + String encoded; + + // Valid code + obs.setValue(new Quantity().setSystem("http://cs").setCode("code1").setValue(123)); + oo = validateAndReturnOutcome(obs, true); + encoded = encode(oo); + ourLog.info(encoded); + assertEquals(1, oo.getIssue().size()); + assertEquals("The code provided (http://cs#code1) is not in the value set http://vs, and a code from this value set is required: Failed to expand ValueSet 'http://vs' (in-memory). Could not validate code http://cs#code1. Error was: HAPI-0702: Unable to expand ValueSet because CodeSystem could not be found: http://cs", oo.getIssueFirstRep().getDiagnostics()); + assertEquals(OperationOutcome.IssueSeverity.ERROR, oo.getIssueFirstRep().getSeverity()); + + } + + private Observation createObservationForUnknownCodeSystemTest() { Observation obs = new Observation(); obs.getMeta().addProfile("http://sd"); @@ -177,85 +370,60 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test { return obs; } - /** - * By default, an unknown code system should fail validation - */ @Test - public void testValidateCodeInValueSetWithUnknownCodeSystem_Warning() { + public void testValidateCodeInValueSet_InferredCodeSystem_WarningOnUnknown() { // set to warning myUnknownCodeSystemWarningValidationSupport.setNonExistentCodeSystemSeverity(IValidationSupport.IssueSeverity.WARNING); - createStructureDefWithBindingToUnknownCs(); - - Observation obs = createObservationForUnknownCodeSystemTest(); - OperationOutcome oo; String encoded; + Binary binary = new Binary(); + binary.setContentType("application/text"); + binary.setContent("hello".getBytes(StandardCharsets.UTF_8)); + // Valid code - obs.setValue(new Quantity().setSystem("http://cs").setCode("code1").setValue(123)); - oo = validateAndReturnOutcome(obs); + oo = validateAndReturnOutcome(binary); encoded = encode(oo); ourLog.info(encoded); assertTrue(oo.getIssueFirstRep().getDiagnostics().contains("No issues detected during validation")); - // Invalid code - obs.setValue(new Quantity().setSystem("http://cs").setCode("code99").setValue(123)); - oo = validateAndReturnOutcome(obs); - encoded = encode(oo); - ourLog.info(encoded); - assertTrue(oo.getIssueFirstRep().getDiagnostics().contains("No issues detected during validation")); } @Test - public void testValidateCodeInValueSetWithUnknownCodeSystem_Error() { + public void testValidateCodeInValueSet_InferredCodeSystem_ErrorOnUnknown() { + // set to warning myUnknownCodeSystemWarningValidationSupport.setNonExistentCodeSystemSeverity(IValidationSupport.IssueSeverity.ERROR); - createStructureDefWithBindingToUnknownCs(); - - Observation obs = new Observation(); - obs.getMeta().addProfile("http://sd"); - obs.getText().setDivAsString("
Hello
"); - obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED); - obs.getCategoryFirstRep().addCoding().setSystem("http://terminology.hl7.org/CodeSystem/observation-category").setCode("vital-signs"); - obs.getCode().setText("hello"); - obs.setSubject(new Reference("Patient/123")); - obs.addPerformer(new Reference("Practitioner/123")); - obs.setEffective(DateTimeType.now()); - obs.setStatus(ObservationStatus.FINAL); - OperationOutcome oo; String encoded; + Binary binary = new Binary(); + binary.setContentType("application/text"); + binary.setContent("hello".getBytes(StandardCharsets.UTF_8)); + // Valid code - obs.setValue(new Quantity().setSystem("http://cs").setCode("code1").setValue(123)); - oo = validateAndReturnOutcome(obs); + oo = validateAndReturnOutcome(binary); encoded = encode(oo); ourLog.info(encoded); assertTrue(oo.getIssueFirstRep().getDiagnostics().contains("No issues detected during validation")); - - // Invalid code - obs.setValue(new Quantity().setSystem("http://cs").setCode("code99").setValue(123)); - oo = validateAndReturnOutcome(obs); - encoded = encode(oo); - ourLog.info(encoded); - assertTrue(oo.getIssueFirstRep() - .getDiagnostics().contains("The code provided (http://cs#code99) is not in the value set http://vs, and a code from this value set is required: Unknown code 'http://cs#code99' for in-memory expansion of ValueSet 'http://vs'") - ); } - public void createStructureDefWithBindingToUnknownCs() { + + public void createStructureDefWithBindingToUnknownCs(boolean theEnumeratedCodeSystem) { myValidationSupport.fetchCodeSystem("http://not-exist"); // preload DefaultProfileValidationSupport ValueSet vs = new ValueSet(); vs.setUrl("http://vs"); - vs + ValueSet.ConceptSetComponent include = vs .getCompose() .addInclude() - .setSystem("http://cs") - .addConcept(new ValueSet.ConceptReferenceComponent(new CodeType("code1"))) - .addConcept(new ValueSet.ConceptReferenceComponent(new CodeType("code2"))); + .setSystem("http://cs"); + if (theEnumeratedCodeSystem) { + include.addConcept(new ValueSet.ConceptReferenceComponent(new CodeType("code1"))); + include.addConcept(new ValueSet.ConceptReferenceComponent(new CodeType("code2"))); + } myValueSetDao.create(vs); StructureDefinition sd = new StructureDefinition(); @@ -1105,6 +1273,17 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test { } } + private OperationOutcome validateAndReturnOutcome(T theObs, Boolean theWantError) { + IFhirResourceDao dao = (IFhirResourceDao) myDaoRegistry.getResourceDao(theObs.getClass()); + try { + MethodOutcome outcome = dao.validate(theObs, null, null, null, ValidationModeEnum.CREATE, null, mySrd); + assertTrue(theWantError == null || !theWantError, "Wanted an error response but got a non-error"); + return (OperationOutcome) outcome.getOperationOutcome(); + } catch (PreconditionFailedException e) { + assertTrue(theWantError == null || theWantError, "Wanted a non-error response but got an error"); + return (OperationOutcome) e.getOperationOutcome(); + } + } @Test public void testValidateStructureDefinition() throws Exception { @@ -1140,6 +1319,9 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test { ourLog.info("Starting validation"); try { MethodOutcome outcome = myBundleDao.validate(document, null, null, null, ValidationModeEnum.CREATE, null, mySrd); + String encodedResponse = myFhirContext.newJsonParser().encodeResourceToString(outcome.getOperationOutcome()); + ourLog.info("Validation result: {}", encodedResponse); + fail(); } catch (PreconditionFailedException e) { ourLog.info(myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome())); } diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/HttpProxyTest.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/HttpProxyTest.java index 999a8ce2cc3..e04b623afe2 100644 --- a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/HttpProxyTest.java +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/HttpProxyTest.java @@ -77,24 +77,6 @@ public class HttpProxyTest { int port = JettyUtil.getPortForStartedServer(server); try { -// final String authUser = "username"; -// final String authPassword = "password"; -// CredentialsProvider credsProvider = new BasicCredentialsProvider(); -// credsProvider.setCredentials(new AuthScope("127.0.0.1", port), new UsernamePasswordCredentials(authUser, authPassword)); -// -// HttpHost myProxy = new HttpHost("127.0.0.1", port); -// -// //@formatter:off -// HttpClientBuilder clientBuilder = HttpClientBuilder.create(); -// clientBuilder -// .setProxy(myProxy) -// .setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy()) -// .setDefaultCredentialsProvider(credsProvider) -// .disableCookieManagement(); -// CloseableHttpClient httpClient = clientBuilder.build(); -// //@formatter:on -// ourCtx.getRestfulClientFactory().setHttpClient(httpClient); - ourCtx.getRestfulClientFactory().setProxy("127.0.0.1", port); ourCtx.getRestfulClientFactory().setProxyCredentials("username", "password"); diff --git a/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/HtmlUtil.java b/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/HtmlUtil.java index f7750b91683..2d5450cc787 100644 --- a/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/HtmlUtil.java +++ b/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/HtmlUtil.java @@ -34,6 +34,9 @@ import java.net.URL; public class HtmlUtil { + private HtmlUtil() { + } + public static HtmlPage parseAsHtml(String theRespString, URL theUrl) throws IOException { StringWebResponse response = new StringWebResponse(theRespString, theUrl); WebClient client = new WebClient(BrowserVersion.BEST_SUPPORTED, false, null, -1); @@ -42,7 +45,7 @@ public class HtmlUtil { final HtmlPage page = new HtmlPage(response, client.getCurrentWindow()); HtmlUnitNekoHtmlParser htmlUnitNekoHtmlParser = new HtmlUnitNekoHtmlParser(); - htmlUnitNekoHtmlParser.parse(response, page, false); + htmlUnitNekoHtmlParser.parse(response, page, false, false); return page; } diff --git a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/UnknownCodeSystemWarningValidationSupport.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/UnknownCodeSystemWarningValidationSupport.java index cd409da2d76..18392bd55a5 100644 --- a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/UnknownCodeSystemWarningValidationSupport.java +++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/support/UnknownCodeSystemWarningValidationSupport.java @@ -3,6 +3,7 @@ package org.hl7.fhir.common.hapi.validation.support; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.support.ConceptValidationOptions; import ca.uhn.fhir.context.support.ValidationSupportContext; +import org.apache.commons.lang3.Validate; import org.hl7.fhir.instance.model.api.IBaseResource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,28 +43,35 @@ public class UnknownCodeSystemWarningValidationSupport extends BaseValidationSup return canValidateCodeSystem(theValidationSupportContext, theSystem); } + @Nullable + @Override + public LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode, String theDisplayLanguage) { + // filters out error/fatal + if (canValidateCodeSystem(theValidationSupportContext, theSystem)) { + return new LookupCodeResult() + .setFound(true); + } + + return null; + } + @Override public CodeValidationResult validateCode(@Nonnull ValidationSupportContext theValidationSupportContext, @Nonnull ConceptValidationOptions theOptions, String theCodeSystem, String theCode, String theDisplay, String theValueSetUrl) { // filters out error/fatal - // NB: this is a secondary check. isCodeSystemSupported - // should prevent this from ever calling validate code here - // ... but should it ever get called, we'll return null if (!canValidateCodeSystem(theValidationSupportContext, theCodeSystem)) { return null; } - CodeValidationResult result = new CodeValidationResult() - .setSeverity(myNonExistentCodeSystemSeverity); // will be warning or info (error/fatal filtered out above) + CodeValidationResult result = new CodeValidationResult(); + // will be warning or info (error/fatal filtered out above) + result.setSeverity(myNonExistentCodeSystemSeverity); + result.setMessage("CodeSystem is unknown and can't be validated: " + theCodeSystem); - result.setMessage("No issues detected during validation"); - - switch (myNonExistentCodeSystemSeverity) { - case INFORMATION: - // for warnings, we don't set the code - // cause if we do, the severity is stripped out - // (see VersionSpecificWorkerContextWrapper.convertValidationResult) - result.setCode(theCode); - break; + if (myNonExistentCodeSystemSeverity == IssueSeverity.INFORMATION) { + // for warnings, we don't set the code + // cause if we do, the severity is stripped out + // (see VersionSpecificWorkerContextWrapper.convertValidationResult) + result.setCode(theCode); } return result; @@ -126,8 +134,6 @@ public class UnknownCodeSystemWarningValidationSupport extends BaseValidationSup /** * If set to allow, code system violations will be flagged with Warning by default. * Use setNonExistentCodeSystemSeverity instead. - * - * @param theAllowNonExistentCodeSystem */ @Deprecated public void setAllowNonExistentCodeSystem(boolean theAllowNonExistentCodeSystem) { @@ -140,9 +146,9 @@ public class UnknownCodeSystemWarningValidationSupport extends BaseValidationSup /** * Sets the non-existent code system severity. - * @param theSeverity */ - public void setNonExistentCodeSystemSeverity(IssueSeverity theSeverity) { + public void setNonExistentCodeSystemSeverity(@Nonnull IssueSeverity theSeverity) { + Validate.notNull(theSeverity, "theSeverity must not be null"); myNonExistentCodeSystemSeverity = theSeverity; } } diff --git a/pom.xml b/pom.xml index 2a94197e9ca..1ef8141e9af 100644 --- a/pom.xml +++ b/pom.xml @@ -1197,7 +1197,7 @@ net.sourceforge.htmlunit htmlunit - 2.56.0 + 2.58.0 net.sf.json-lib