hapifhir / hapi-fhir

🔥 HAPI FHIR - Java API for HL7 FHIR Clients and Servers
http://hapifhir.io
Apache License 2.0
1.99k stars 1.31k forks source link

PrePopulatedValidationSupport is not version-aware; causes code validation to fail when used with InMemoryTerminologyServerValidationSupport #2442

Open fkleon opened 3 years ago

fkleon commented 3 years ago

Describe the bug

Code validation fails when using PrePopulatedValidationSupport together with InMemoryTerminologyServerValidationSupport in a validation chain; when the value set include specifies a codesystem version.

This is internally caused by the valueset expansion not yielding any results.

The root cause seems to be that PrePopulatedValidationSupport is not version-aware, but InMemoryTerminologyServerValidationSupport uses canonical URLs (including pipe-separated version) to lookup codesystems from the context with the codesystemLoader.

To Reproduce The following code snippet illustrates the issue:

public void shouldExpandValueSetCanonical() {
    FhirContext ctx = FhirContext.forR4();
    IParser parser = ctx.newXmlParser();

    InputStream csIs = getClass().getResourceAsStream("codesystem.xml");
    InputStream vsIs = getClass().getResourceAsStream("valueset.xml");

    CodeSystem cs = (CodeSystem) parser.parseResource(csIs);
    ValueSet vs = (ValueSet) parser.parseResource(vsIs);

    PrePopulatedValidationSupport prePopulatedSupport = new PrePopulatedValidationSupport(ctx);
    prePopulatedSupport.addCodeSystem(cs);
    prePopulatedSupport.addValueSet(vs);

    InMemoryTerminologyServerValidationSupport inMemoryTerminologyServiceSupport = new InMemoryTerminologyServerValidationSupport(ctx);

    ValidationSupportChain supportChain = new ValidationSupportChain(
            prePopulatedSupport,
            inMemoryTerminologyServiceSupport);

    ValidationSupportContext vCtx = new ValidationSupportContext(supportChain);
    CodeValidationResult result = supportChain.validateCodeInValueSet(vCtx, null, "https://example.nz/cs/example-code", "EXAMPLE", "Example", vs);
    assertNotNull(result); // FAILS

    ValueSetExpansionOutcome outcome = supportChain.expandValueSet(vCtx, null, vs);
    assertNotNull(outcome); // FAILS
}

The root cause is shown here:

    IBaseResource csRes = prePopulatedSupport.fetchCodeSystem("https://example.nz/cs/example-code");
    assertNotNull(csRes); // WORKS
    IBaseResource vsRes = prePopulatedSupport.fetchValueSet("https://example.nz/vs/example-code");
    assertNotNull(vsRes); // WORKS

    // This is how InMemoryTerminologyServerValidationSupport looks up the codesystem
    csRes = prePopulatedSupport.fetchCodeSystem("https://example.nz/cs/example-code|1.0");
    assertNotNull(csRes); // FAILS
    vsRes = prePopulatedSupport.fetchValueSet("https://example.nz/vs/example-code|1.0");
    assertNotNull(vsRes); // FAILS

codesystem.xml

<CodeSystem xmlns="http://hl7.org/fhir">
    <meta>
        <profile
            value="http://hl7.org/fhir/StructureDefinition/shareablecodesystem" />
    </meta>
    <url value="https://example.nz/cs/example-code" />
    <version value="1.0" />
    <name value="Example_CodeSystem" />
    <title value="Example CodeSystem" />
    <status value="active" />
    <experimental value="false" />
    <date value="2021-03-04T00:00:00+13:00" />
    <publisher value="Example Org" />
    <description value="Example description" />
    <caseSensitive value="false" />
    <versionNeeded value="true" />
    <content value="complete" />
    <count value="1" />
    <concept>
        <code value="EXAMPLE" />
        <display value="An example code" />
    </concept>
</CodeSystem>

valueset.xml

<ValueSet xmlns="http://hl7.org/fhir">
    <meta>
      <profile
          value="http://hl7.org/fhir/StructureDefinition/shareablevalueset" />
    </meta>
    <url value="https://example.nz/vs/example-code" />
    <version value="1.0" />
    <name value="Example_ValueSet" />
    <title value="Example Value Set" />
    <status value="active" />
    <experimental value="false" />
    <date value="2021-03-04T00:00:00+13:00" />
    <publisher value="Example Org" />
    <description value="Example Value Set" />
    <compose>
      <include>
          <system value="https://example.nz/cs/example-code" />
          <version value="1.0" />
      </include>
  </compose>
</ValueSet>

Expected behavior The code validation to succeed.

Environment (please complete the following information):

Additional context Happy to provide a test case in a pull request if required.

jkiddo commented 2 years ago

I'm sure a PR certainly will speed up the process ;)