LinuxForHealth / FHIR

The LinuxForHealth FHIR® Server and related projects
https://linuxforhealth.github.io/FHIR
Apache License 2.0
328 stars 157 forks source link

CodeSystem/$lookup: GET method not allowed if property parameter is used #4202

Open paulolaup opened 1 year ago

paulolaup commented 1 year ago

Describe the bug If just the system and code parameters are used with the $lookup operation, then the entire concept including properties is returned (as expected): [base-url]/fhir-server/api/v4/CodeSystem/$lookup?system=http://loinc.org&version=2.7.4&code=8084-6

`

<parameter>
    <name value="version"/>
    <valueString value="2.7.4"/>
</parameter>
<parameter>
    <name value="display"/>
    <valueString value="Neutrophil cytoplasmic Ab.classic [Units/volume] in Serum"/>
</parameter>
<parameter>
    <name value="property"/>
    <part>
        <name value="code"/>
        <valueCode value="component"/>
    </part>
    <part>
        <name value="value"/>
        <valueCode value="Neutrophil cytoplasmic Ab.classic"/>
    </part>
</parameter>
<parameter>
    <name value="property"/>
    <part>
        <name value="code"/>
        <valueCode value="property"/>
    </part>
    <part>
        <name value="value"/>
        <valueCode value="ACnc"/>
    </part>
</parameter>
<parameter>
    <name value="property"/>
    <part>
        <name value="code"/>
        <valueCode value="time-aspect"/>
    </part>
    <part>
        <name value="value"/>
        <valueCode value="Pt"/>
    </part>
</parameter>
<parameter>
    <name value="property"/>
    <part>
        <name value="code"/>
        <valueCode value="system"/>
    </part>
    <part>
        <name value="value"/>
        <valueCode value="Ser"/>
    </part>
</parameter>
<parameter>
    <name value="property"/>
    <part>
        <name value="code"/>
        <valueCode value="scale"/>
    </part>
    <part>
        <name value="value"/>
        <valueCode value="Qn"/>
    </part>
</parameter>

`

However if the property parameter is specified one receives the following response:

[base-url]/fhir-server/api/v4/CodeSystem/$lookup?system=http://loinc.org&version=2.7.4&code=8084-6&property=time-aspect

`<OperationOutcome xmlns="http://hl7.org/fhir">

<issue>
    <severity value="fatal"/>
    <code value="not-supported"/>
    <details>
        <text value="HTTP method 'GET' is not supported for operation: 'lookup'"/>
    </details>
</issue>

`

Even if the property did not exist, I would expect a different error message to indicate that specific issue. I checked the source code for the specific location where this error is thrown and it should be org.linuxforhealth.fhir.spi.operation.AbstractOperation::validateOperationContext (due to isGetMethodAllowed returning false), but none of the requirements should be met. GET is not supported only if:

  • the affectState element has the value true (this is not the case for the $lookup operation) or
  • any parameter has no type or is not primitive (all three parameters have types which are primitive) or
  • any parameter consists of additional parameters (also not the case as per operation definition)

However, this is only one possible cause I could identify. If I just made an error using the API, please provide me with the details. Until this moment, I could not identify an issue with the request itself.

Environment I'm using the latest version (4.11.1) of the ibmcom/ibm-fhir-server image with a Apache Derby persistent storage.

To Reproduce Steps to reproduce the behavior:

  1. Upload CodeSystem resource instance to server via REST-API
  2. Lookup code as described in the first section

I tried this with the LOINC code system as well as confirmed the issue with a test CodeSystem instance.

Expected behavior Property parameter should be supported with GET method or more specific error message should be returned.

paulolaup commented 1 year ago

I investigated the issue and tracked it down to the org.linuxforhealth.fhir.spi.operation.AbstractOperation::isGetAllowed method. You iterate through all lookup Parameters but forget to check if these are input or output parameters (indicated by OperationParameterUse object obtained by OperationDefinition.Parameter::getUse). Since there is a property parameter for the output which is a complex type the GET method is disallowed. You should check if getUse is equal to OperationParameterUse.IN, like:

odParameter.getUse().equals(OperationParameterUse.IN)

as an additional condition.

While testing this fix I also encountered a typo in an issue returned to the client at org.linuxforhealth.fhir.term.service.FHIRTermService (Line 417).