oehf / ipf

Open eHealth Integration Platform
http://oehf.github.io/ipf-docs
Apache License 2.0
175 stars 65 forks source link

ITI-81 rejects some search parameters #358

Closed Ivan1pl closed 3 years ago

Ivan1pl commented 3 years ago

ITI-81 transaction rejects some search parameters that are available in fhir but not specified in Add RESTful ATNA (Query and Feed) Trial Implementation.

According to the specification (3.81.4.1.2.2 Additional ATNA Search Parameters):

The HL7® FHIR® standard provides additional search parameters. This transaction does not define specific behavior on those parameters (such as _sort, _include, etc.). See http://hl7.org/fhir/R4/search.html for details about available parameters.

On that page, in section 3.1.1.4.2 Parameters for each resource, we can find that:

each FHIR resource type defines its own set of search parameters with their names, types, and meanings

AuditEvent specification lists several search parameters that are not included in ITI-81 specification and IPF rejects them. Since it is not specified how the application should treat them, this behavior is correct. However, it would be much better to be able to provide a list of additional supported parameters. Some of them can be quite useful and we would like to use them in our application.

Example:

Code:

from("atna-iti81:atna-iti81")
    .to(Routes.AUDIT_SEARCH)

Request: GET http://localhost:8771/fhir/AuditEvent?date=ge2021-07-08&date=le2021-07-08&subtype=ITI-18&altid=1

Result:

<OperationOutcome xmlns="http://hl7.org/fhir">
   <issue>
      <severity value="error"/>
      <code value="processing"/>
      <diagnostics value="Invalid request: The FHIR endpoint on this server does not know how to handle GET operation[AuditEvent] with parameters [[date, subtype, altid]]"/>
   </issue>
</OperationOutcome>
Ivan1pl commented 3 years ago

Alright, after a bit of digging through library code, I found a way to do this. It is not ideal but at least it works. It would really help if such things were documented.

Solution

  1. Define a custom search parameters class containing additional parameters you want to handle:

    @Builder(excludes = ["sortSpec", "includeSpec", "patientIdParam", "fhirContext"])
    @CompileStatic
    class CustomIti81SearchParameters implements FhirSearchParameters {
    Iti81SearchParameters defaultParameters
    TokenAndListParam altid
    
    @Override
    SortSpec getSortSpec() {
        defaultParameters.sortSpec
    }
    
    @Override
    Set<Include> getIncludeSpec() {
        defaultParameters.includeSpec
    }
    
    @Override
    List<TokenParam> getPatientIdParam() {
        defaultParameters.patientIdParam
    }
    
    @Override
    FhirContext getFhirContext() {
        defaultParameters.fhirContext
    }
    }
  2. Define a custom resource provider with additional parameters and make it a Spring bean

    @Component
    @CompileStatic
    class CustomIti81ResourceProvider extends AbstractPlainProvider {
    
    @SuppressWarnings("unused")
    @Search(type = AuditEvent.class)
    IBundleProvider auditSearch(
            @RequiredParam(name = AuditEvent.SP_DATE) DateRangeParam interval,
            @OptionalParam(name = AuditEvent.SP_ADDRESS) StringAndListParam address,
            @OptionalParam(name = "patient.identifier") TokenAndListParam patientId,
            @OptionalParam(name = AuditEvent.SP_ENTITY) ReferenceParam entity,
            @OptionalParam(name = AuditEvent.SP_ENTITY_TYPE) TokenAndListParam entityType,
            @OptionalParam(name = AuditEvent.SP_ENTITY_ROLE) TokenAndListParam entityRole,
            @OptionalParam(name = AuditEvent.SP_SOURCE) StringAndListParam source,
            @OptionalParam(name = AuditEvent.SP_TYPE) TokenAndListParam type,
            @OptionalParam(name = AuditEvent.SP_SUBTYPE) TokenAndListParam subtype,
            @OptionalParam(name = Iti81Constants.SP_OUTCOME) TokenAndListParam outcome,
            @OptionalParam(name = AuditEvent.SP_ALTID) TokenAndListParam altid,
            @Sort SortSpec sortSpec,
            @IncludeParam Set<Include> includeSpec,
            RequestDetails requestDetails,
            HttpServletRequest httpServletRequest,
            HttpServletResponse httpServletResponse) {
    
        Iti81SearchParameters iti81SearchParameters = Iti81SearchParameters.builder()
                .interval(interval)
                .address(address)
                .patientId(patientId)
                .entity(entity)
                .entityType(entityType)
                .entityRole(entityRole)
                .source(source)
                .type(type)
                .subtype(subtype)
                .outcome(outcome)
                .sortSpec(sortSpec)
                .includeSpec(includeSpec)
                .fhirContext(getFhirContext())
                .build()
        CustomIti81SearchParameters searchParameters = CustomIti81SearchParameters.builder()
                .defaultParameters(iti81SearchParameters)
                .altid(altid)
                .build()
    
        // Run down the route
        return requestBundleProvider(null, searchParameters, ResourceType.AuditEvent.name(),
                httpServletRequest, httpServletResponse, requestDetails)
    
    }
    }
  3. Override default resource provider using a query parameter in route definition
    from("atna-iti81:atna-iti81?resourceProvider=#customIti81ResourceProvider")
        .to(Routes.AUDIT_SEARCH)

Issues/Suggestions

Ivan1pl commented 3 years ago

After further reading I found this in the documentation:

If search parameters other than those defined in Section 3.81.4.1.2.2 (e.g., _sort, _include FHIR search result parameters) are specified in the request URL, then

  • If the Audit Record Repository does not support the parameter, it shall be ignored;
  • If the Audit Record Repository supports the parameter, the matching or other behavior shall comply with the matching rules for its datatype in FHIR.

This means that the default implementation where other search parameters cause an error is actually incorrect. The best solution would be to just include them in Iti81ResourceProvider as optional parameters and add them to Iti81SearchParameters.

ohr commented 3 years ago

Feel free to open an issue or submit a PR to fix this.

Thanks for helping Christian

Am Mi., 14. Juli 2021 um 12:24 Uhr schrieb Mikołaj Nowak < @.***>:

After further reading I found this in the documentation:

If search parameters other than those defined in Section 3.81.4.1.2.2 (e.g., _sort, _include FHIR search result parameters) are specified in the request URL, then

  • If the Audit Record Repository does not support the parameter, it shall be ignored;
  • If the Audit Record Repository supports the parameter, the matching or other behavior shall comply with the matching rules for its datatype in FHIR.

This means that the default implementation where other search parameters cause an error is actually incorrect. The best solution would be to just include them in Iti81ResourceProvider as optional parameters and add them to Iti81SearchParameters.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/oehf/ipf/issues/358#issuecomment-879777445, or unsubscribe https://github.com/notifications/unsubscribe-auth/AACU7KHBKII6RAIVSZHXH7TTXVQXNANCNFSM5ACQDIRQ .

ohr commented 3 years ago

Added altid parameter to Iti81. Added @RequiredArgsConstructor annotations to search parameters

Clients can also specify how the server should behave, by using the prefer header:

Prefer: handling=strict: Client requests that the server return an error for any unknown or unsupported parameter Prefer: handling=lenient: Client requests that the server ignore any unknown or unsupported parameter