FHIR Chat · Validating custom resources · ibm

Stream: ibm

Topic: Validating custom resources


view this post on Zulip Matt Sargent (May 04 2020 at 19:29):

Does the IBM FHIR code provide support for validating custom resource definitions? Suppose I have MyPatient which puts some extra constraints on the Patient resource. Is it possible to leverage FHIRValidator to validate this resource? If so, are there examples handy anywhere of how to accomplish this?

I've been trying to do something along the lines of

 val profiles = ... // Seq(strings containing structure definitions)
val customResourceString = ... // String containing JSON representation of a custom resource
val parsedResource = FHIRParser.parser(Format.JSON).parse(IOUtils.toInputStream(resourceString, "UTF-8")).asInstanceOf[Resource]
FHIRValidator.validator().validate(resource, true, profiles: _*)

Depending on the 'resourceType' I use in the custom resource string, either the validator runs, but only appears to validate against the base Patient resource, or if I try to use MyPatient as the resourceType then the FHIRParser chokes on the JSON.

If anyone has advice on how I should try to proceed I would greatly appreciate it. Thanks!

view this post on Zulip Lee Surprenant (May 04 2020 at 20:01):

Hi Matt. Did you have a look at https://ibm.github.io/FHIR/guides/FHIRValidationGuide ? Basically, you need to make your constraints available to the validator via conformance artifacts (StructureDefinition in your case) in the FHIRRegistry

view this post on Zulip Lee Surprenant (May 04 2020 at 20:03):

the validator will look them up from there by uri and version

view this post on Zulip Lee Surprenant (May 04 2020 at 20:06):

as for building those StructureDefinition, we don't really provide any tooling beyond the base fhir model, but there's lots of tools in the community

view this post on Zulip Matt Sargent (May 04 2020 at 20:28):

Thanks for the response. I'll have to dive in deeper to that example, but after a first pass it seems like validation is built with a FHIR server in mind? Is that correct? Or is it also possible to accomplish by hand, but I'd have to tie together the components called out on that page (fhir-model, fhir-validation, fhir-registry, etc.)?

view this post on Zulip Lee Surprenant (May 04 2020 at 21:03):

FHIR Validation is written as a standalone component (a set of modules). It uses a Java ServiceLoader pattern to find RegistryResourceProviders when its initialized. In the webapp, that is initialized during server startup (via a ServletContextListener) so you'd need to do similar for your app.

view this post on Zulip Lee Surprenant (May 04 2020 at 21:07):

https://ibm.github.io/FHIR/guides/CreateFHIRValidationAssembly provides some guidance on building an assembly that contains the validator and all related pieces...although I've never actually gone through that part myself. Let us know if you hit any issues.

view this post on Zulip Matt Sargent (May 15 2020 at 18:24):

Thanks again Lee. Finally have time to circle back to this.

I'll let you know if I hit any technical issues. So far my main issue is trying to decipher what the actual steps are from the documentation, but they might make more sense once I start trying to code.

view this post on Zulip Matt Sargent (May 15 2020 at 21:39):

I worked with a teammate today to get a very simple validation program running with a custom profile. We were able to enforce that a Period was required, when normally it was optional.

Our next step is trying to also enforce that the mandatory Period contains a particular extension, but we have not been able to get that working yet.

Thanks again for the pointers.

view this post on Zulip Matt Sargent (May 18 2020 at 16:23):

@Lee Surprenant , does the FHIR validation support more than "one level" of validation? For example, should I be able to have a profile that specifies that a resource contains a Period, and that the Period itself contains a particular extension?

view this post on Zulip Paul Bastide (May 18 2020 at 18:04):

HI Matt yes absolutely

view this post on Zulip Lee Surprenant (May 18 2020 at 18:10):

Yes, what paul said. How are you creating the profiles today? Did you mention you were using FSH?

view this post on Zulip Lee Surprenant (May 18 2020 at 18:13):

Irregardless of which tools you are using to produce the profile, I think the result will be 3 structureDefinitions:

  1. The StructureDefinition of the extension you want to make mandatory on the Period (call it http://example.com/StructureDefinition/my-extension)
  2. The StructureDefinition of the profile for the Period datatype (call it http://example.com/StructureDefintion/period-with-extension
  3. The StructureDefinition of the profile for the resource type where you are making the Period required

view this post on Zulip Lee Surprenant (May 18 2020 at 18:14):

although #1 may be optional for what you're trying to accomplish

view this post on Zulip Matt Sargent (May 18 2020 at 19:03):

We are using FSH and sushi to generate profiles.

There are definitions covering items 2 and 3 from the list above, but I did not add a definition for the extension itself yet. I'll add that in and see if the result is any different.

view this post on Zulip Matt Sargent (May 18 2020 at 20:33):

(apologies ahead of time for this wall of text)

Here's a minimal cut of the FSH files in use.

Profile: MyCoverage
Parent: Coverage
Id: my-coverage
* period 1..1
* period only PeriodWithMyExtension

Profile: PeriodWithMyExtension
Parent: Period
Title: "Period with my extension"
Id: period-with-my-extension
* extension contains MyExtension named myExtension 1..1

Extension: MyExtension
Title: "My Extension"
Id: my-extension
Description: "An extension"
* value[x] only integer

I generated the structure definitions and added them to our project. I also updated .index.json to the following:

{
  "index-version": 1,
  "files": [
    {
      "filename": "my-coverage.json",
      "resourceType": "StructureDefinition",
      "id": "my-coverage",
      "url": "http://myurl.org/my-coverage",
      "version": "4.0.1",
      "kind": "resource",
      "type": "Coverage"
    },
    {
      "filename": "my-extension.json",
      "resourceType": "StructureDefinition",
      "id": "my-extension",
      "url": "http://myurl.org/my-extension",
      "version": "4.0.1",
      "kind": "complex-type",
      "type": "Extension"
    },
    {
      "filename": "period-with-my-extension.json",
      "resourceType": "StructureDefinition",
      "id": "period-with-my-extension",
      "url": "http://myurl.org/period-with-my-extension",
      "version": "4.0.1",
      "kind": "complex-type",
      "type": "Period"
    }
  ]
}

Finally, I tried running this toy program:

package org.myurl.validation

import com.ibm.fhir.model.`type`.code.CoverageStatus
import com.ibm.fhir.model.`type`.{Canonical, Meta, Period, Reference, String => FHIRString, DateTime => FHIRDateTime}
import com.ibm.fhir.model.resource.Coverage
import com.ibm.fhir.validation.FHIRValidator

object FHIRValidationPgm {

    val validator = FHIRValidator.validator()

    def main(args: Array[String]): Unit = {
        val coverage = Coverage.builder()
          .status(CoverageStatus.ACTIVE)
          .beneficiary(Reference.builder().reference(FHIRString.of("none")).build())
          .payor(Reference.builder().reference(FHIRString.of("none")).build())
//          .period(Period.builder().start(FHIRDateTime.of("2020-01-01")).end(FHIRDateTime.of("2020-01-31")).build())
          .meta(Meta.builder()
              .profile(Canonical.builder().value("http://myurl.org/my-coverage").build())
            .build()
          )
          .build()


        System.out.println(validator.validate(coverage))
    }

}

With the period() line commented out, I see that a constraint is violated in the output:

 "text": "generated-my-coverage-1: Constraint violation: period.exists()"

However, when I include the Period line, there is no such complaint about a missing extension on the Period. Any thoughts on what might be going wrong? I'm wondering if I have a mistake all the way back in the FSH files, or if I am adding the structure definitions to the project incorrectly. Thanks for any help you can offer.

view this post on Zulip Lee Surprenant (May 18 2020 at 21:00):

Unfortunately, I'm not much good with FSH... is it possible for you to share your StructureDefinitions here (or via other means if sensitive at all)?

view this post on Zulip Lee Surprenant (May 18 2020 at 21:01):

@John Timm fyi ^

view this post on Zulip Lee Surprenant (May 18 2020 at 21:09):

specifically what i'm wondering is if * extension contains MyExtension named myExtension 1..1 is doing what you expect it to be doing. extension is a repeating field and so typically the way to "constrain" that is via a "slice"

view this post on Zulip Lee Surprenant (May 18 2020 at 21:10):

so is this line properly identifying that the profile must contain one (and only one) instance of myExtension in the list of extensions?

view this post on Zulip Matt Sargent (May 18 2020 at 21:18):

my-coverage.json my-extension.json period-with-my-extension.json

view this post on Zulip John Timm (May 18 2020 at 21:25):

We currently don't support the generation of constraints on complex data types that are specified in the way that FSH has generated for this example. We need to convince FSH to generate a structure definition that references the extension definition directly as opposed to doing it through an intermediate profiled complex data type (as you have done). For example:

Coverage.period
Coverage.period.extension
Coverage.period.extension:sliceName

view this post on Zulip John Timm (May 18 2020 at 21:36):

Here's what I think needs to happen:

  1. Figure out how to get FSH to generate what we do support
  2. Create an enhancement request to look into what it would take to expand what our constraint generator supports

view this post on Zulip John Timm (May 18 2020 at 21:46):

https://github.com/IBM/FHIR/issues/1117

view this post on Zulip Matt Sargent (May 18 2020 at 22:07):

Thanks John. Knowing that the FSH files are the place to start tweaking for now is helpful.

view this post on Zulip John Timm (May 19 2020 at 16:59):

@Matt Sargent An enhancement to the constraint generator was delivered with this PR:
https://github.com/IBM/FHIR/pull/1121

view this post on Zulip Matt Sargent (May 22 2020 at 21:09):

Initial testing with 4.2.2 is looking good so far. Thank you for such a quick turnaround on this new feature!


Last updated: Apr 12 2022 at 19:14 UTC