LinuxForHealth / FHIR

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

Customers need to be able to set the `default` IG for the multiple IGs in the projects. #2832

Closed prb112 closed 3 years ago

prb112 commented 3 years ago

Is your feature request related to a problem? Please describe. Customers need to be able to set the default IG for the multiple IGs in the projects.

It must answer which profile/version is correct for this server/implementation.

Describe the solution you'd like A clear and concise description of what you want to happen.

Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.

Acceptance Criteria

  1. LATEST is used GIVEN an IG with multiple versions AND a system default WHEN an IG is used AND an StructureDefinition in LATEST is referenced THEN the latest is used AND the latest-1 is NOT used

  2. LATEST-1 is used
    GIVEN an IG with multiple versions AND a system default WHEN an IG is used AND an StructureDefinition in LATEST-1 is referenced THEN the latest-1 is used AND the latest is NOT used

Additional context n/a

lmsurpre commented 3 years ago

I wonder if its worth advertising which version is the default in the CapabilityStatement as well...maybe an extension on either https://www.hl7.org/fhir/capabilitystatement-definitions.html#CapabilityStatement.rest.resource or https://www.hl7.org/fhir/capabilitystatement-definitions.html#CapabilityStatement.rest.resource.supportedProfile ?

If so, we might want to expose some of our other metadata as well (such as the atLeastOne list and maybe the notAllowed list)

lmsurpre commented 3 years ago

I consider two main options for this one: A. add something to fhirServer/resources/<resourceType>/profiles/ that is focused on only profiles B. add a new config section at fhirServer/registry that has a map of (url, version) pairs that could apply to ANY definitional resource in the registry

I think A would be significantly simpler and addresses the description of this issue, so I'm thinking we should just start there.

Here is an example of what a fhirServer/resources/<resourceType>/profiles object contains to date:

"Patient": {
    "profiles": {
        "allowUnknown": true,
        "atLeastOne": [
            "http://example.com/StructureDefinition/profileA",
            "http://example.com/StructureDefinition/profileB|1",
        ],
        "notAllowed": [
            "http://example.com/StructureDefinition/profileC"
        ]
    }
}

The thought is to add a new defaultVersions property under here which will consist of a map from a url to its default version:

"Patient": {
    "profiles": {
        "allowUnknown": true,
        "atLeastOne": [
            "http://example.com/StructureDefinition/profileA",
            "http://example.com/StructureDefinition/profileB|1",
        ],
        "notAllowed": [
            "http://example.com/StructureDefinition/profileC"
        ],
        "defaultVersions": {
            "http://example.com/StructureDefinition/profileA": "1.0.0"
            "http://example.com/StructureDefinition/profileC": "2.0.1"
        }
    }
}

Now suppose we have this config and the server registry contains version 1.0.0 and 1.1.1 of profile A.

Here is how that would translate to validate a resource (e.g. on resource creation or on a call to $validate with no profile version argument):

Resource.meta.profile Version of profile A we will validate against
http://example.com/StructureDefinition/profileA 1.0.0
http://example.com/StructureDefinition/profileA\|1.0.0 1.0.0
http://example.com/StructureDefinition/profileA\|1.1.1 1.1.1
http://example.com/StructureDefinition/profileA\|bogus bogus

So versioned references will work the same irregardless of this new setting...it will only affect which version we validate against if a versionless reference comes in. In this case, if the defaultVersions object does not contain a key for the profile in question, then we will use the current default which is the "latest" version of this profile (as determined by https://github.com/IBM/FHIR/blob/main/fhir-registry/src/main/java/com/ibm/fhir/registry/resource/FHIRRegistryResource.java#L158)

In the case of the last row in this table, that version isn't in the registry and so we'd check allowUnknown..since its set to true here the resource would be accepted and validation would return a warning that says this version of this profile is not supported.

I think the main downside of focusing on just the profiles for now is that it might also be useful to be able to designate a default for other resource types. For example, for CodeSystem or ValueSet resources where the user invokes a $lookup without specifying a version.

lmsurpre commented 3 years ago

There is one additional property that I was debating whether to introduce to this section or not and that is implicitProfiles and so I opened this as #2887. I don't think we have an immediate need for this property, but I wanted to mention it here while we are designing this section of the config.

prb112 commented 3 years ago

This makes sense to me. (even with the limitations on CodeSystems and ValueSets)

michaelwschroeder commented 3 years ago

I think option A makes sense for specifying at the profile level. Wondering if we want to allow for specifying at the IG level as well (which could address the limitation on CodeSystems, ValueSets, SearchParameters) . For example, add an implementationGuides property under fhirServer/resources, and then a defaultVersions property under that, so something like this (or maybe even move the implementationGuides property directly under fhirServer):

"fhirServer": {
    "resources": {
        "implementationGuides": {
            "defaultVersions": {
                "http://hl7.org/fhir/us/core/ImplementationGuide/hl7.fhir.us.core": "3.1.1"
                "http://hl7.org/fhir/us/carin-bb/ImplementationGuide/hl7.fhir.us.carin-bb": "1.1.0"
            }
        }
    }
}
lmsurpre commented 3 years ago

Wondering if we want to allow for specifying at the IG level as well (which could address the limitation on CodeSystems, ValueSets, SearchParameters)

One challenge with this is where / how to apply this config. fhir-regsitry doesn't currently rely on fhir-config...I think it could but I'm not sure if we want it to since its used by other packages like our validation package as well. I'd almost want to introduce it as a peer to fhirServer at that point...

Additionally, we don't lookup these resources in the context of their ImplementationGuide resources at this time. Most of the time, its just a lookup by resourceType + url + version. So what you'd really be configuring there is the individual "PackageRegistryResourceProvider" implementations I think.

These are some of the complications that led me to propose that we just focus on part A for now. Are there other important use cases that you think we need to cover in round 1 of this stuff?

michaelwschroeder commented 3 years ago

No, I'm comfortable with just addressing the profile stuff for now with option A.

lmsurpre commented 3 years ago

with a config like:

"defaultVersions": {
  "profile1": "1.0.0",
  "profile2": "2.0.0",
  "http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient": "3.1.1"
}
Resource.meta.profile result
["profile1"] "Profile 'profile1|1.0.0' is not supported"
["profile2"] "Profile 'profile2|2.0.0' is not supported"
["profile1|a"] "Profile 'profile1|a' is not supported"
["http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient"] 200 OK
["http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient\|3.1.1"] 200 OK
["http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient\|4.0.0"] 200 OK

I then added:

"notAllowed": [
  "http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient|4.0.0"
]
Resource.meta.profile result
["http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient"] 200 OK
["http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient\|4.0.0"] A profile was specified which is not allowed.
and finally I updated the default version to 4.0.0: Resource.meta.profile result
["http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient"] A profile was specified which is not allowed.
["http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient\|3.1.1"] 200 OK

The one thing from above that might be a tad confusing is when a versionless profile is sent in but then the error message comes back with a versioned url (e.g. in the first two rows of the first table above). However, it is working as designed and documented, so I think this one is good-to-go.