hapi-fhir-jpaserver-starter icon indicating copy to clipboard operation
hapi-fhir-jpaserver-starter copied to clipboard

Automatically load npm installed FHIR packages in the Validator [Feature request]

Open cdelanchy opened this issue 1 year ago • 1 comments

Hello there!

I managed easily with the documentation to set-up an HAPI FHIR JPA server running with the supported resources I wanted. However, I also wanted to add specific profiles from my country (FrPatient for example) and to set HAPI to validate the Patient resource it will get against this profile. It was really difficult: I managed it with the help of other people.

In fact, the solution was to put my .tgz FHIR packages of the specific profiles in a directory and to intercep the cachingValidationSupport, loading my packages with an npmPackageValidationSupport and create a new ValidationChain. This new validation chain replaces the default one in place.

As the class name sugest (npmPackageValidationSupport), do you think it should be possible to add a feature that automatically loads FHIR packages installed with npm (or in a specified directory in application.yml) and add them to the default validation chain? This will allows eeveryone to simply add validation against custom profiles easily.

What are your thoughts about this? Maybe there is already an easy way to do this and I missed it.

Thank again for your work. Have a nice day!

cdelanchy avatar Aug 05 '22 15:08 cdelanchy

Hi @cdelanchy - good to know you succeeded. I think you missed the point around https://github.com/hapifhir/hapi-fhir-jpaserver-starter/blob/4978f32e320da49317ba490db11712d83834c8c6/src/main/resources/application.yaml#L75 which automatically makes the server go fetch the npm from the designated url and then loads it into the database. From there you can eg. then use https://github.com/hapifhir/hapi-fhir-jpaserver-starter/blob/4978f32e320da49317ba490db11712d83834c8c6/src/main/resources/application.yaml#L92 which then validates anything where the profile is stated within the resource. I'm not saying what you did was wrong - it may be the perfect fit for your case. I'm just saying there is also another way to do it ;)

jkiddo avatar Aug 16 '22 21:08 jkiddo

Hi @jkiddo!

Thank you for your answer. And sorry for the long delay in my response (but yes, summer vacations were great :D).

I want to try your method, which seems a lot easier than mine. But the package I want to use is available on Simplifier: https://simplifier.net/packages/hl7-france-fhir.administrative/11.2021.1

The website gives us a command to download the package using npm: npm --registry https://packages.simplifier.net install [email protected].

How can I tell correctly in the application.yml file how to get this package?

Also, the link example have all the letters "ig", meaning it must be Implementation Guides? This package is not a full implementation guide. Will it works?

Thank you for your time and have a nice day!

cdelanchy avatar Sep 07 '22 19:09 cdelanchy

I'm adding more details after some testing.

I get the .tgz file using this URL: https://packages.simplifier.net/hl7-france-fhir.administrative/11.2021.1 (tested with a wget, rename the file with .tgz, and tar xvf the file: I get the same file as using npm).

Thus, I changed my application.yml this way:

hapi:
  fhir:
    openapi_enabled: true
    fhir_version: R4
    ### enable to set the Server URL
    #    server_address: http://hapi.fhir.org/baseR4
    #    defer_indexing_for_codesystems_of_size: 101
    #    install_transitive_ig_dependencies: true
    #    implementationguides:
    ###    example from registry (packages.fhir.org)
    #      swiss:
    #        name: swiss.mednet.fhir
    #        version: 0.8.0
    #      example not from registry
    #      ips_1_0_0:
    #        url: https://build.fhir.org/ig/HL7/fhir-ips/package.tgz
    #        name: hl7.fhir.uv.ips
    #        version: 1.0.0
    implementationguides:
      hl7-france-fhir.administrative_11.2021.1:
        url: https://packages.simplifier.net/hl7-france-fhir.administrative/11.2021.1
        name: hl7-france-fhir.administrative
        version: 11.2021.1
    supported_resource_types:
      - StructureDefinition
      - Subscription
      - ValueSet
      - CodingSystem
      - Bundle
      - Patient
      - Practitioner
      - PractitionerRole
      - Organization
      - RelatedPerson
      - CareTeam

I repackaged the server with mvn clean package -DskipTests spring-boot:repackage -Pboot && java -jar target/ROOT.war. The server started but I haven't seen much change in the start logs.

I tried to push a fresh patient using Postman. It's a Patient that doesn't comply with the profile FrPatient - as it requires a birthdate - which is in the tarball I mentionned before.

{
  "resourceType": "Patient",
  "id": "002",
  "gender": "male",
  "name": [
    {
      "family": "TestBis",
      "given": ["TestBis"]
    }
  ]
}

I got a 201 Created, which is not what I'm expected, as it's not compliant with the FrProfile.

I stopped the server, update my application.yml with this line: enable_repository_validating_interceptor: true. I restarted the server and retried with a similar Patient (just changing the name and id). The patient was also accepted whereas not compliant with the (theoritically) loaded FrPatient profile...

The server's logs are not indicating something with the validation of the ressource:

2022-09-07 22:03:05.627 [main] INFO  c.uhn.fhir.rest.server.RestfulServer [RestfulServer.java:1351] Initializing HAPI FHIR restful server running in R4 mode
2022-09-07 22:03:05.627 [main] INFO  c.uhn.fhir.rest.server.RestfulServer [RestfulServer.java:1723] Added 12 resource provider(s). Total 12
2022-09-07 22:03:05.764 [main] INFO  c.uhn.fhir.rest.server.RestfulServer [RestfulServer.java:1729] Added 4 plain provider(s). Total 4
2022-09-07 22:03:05.787 [main] INFO  c.uhn.fhir.rest.server.RestfulServer [RestfulServer.java:1399] A FHIR has been lit on this server
2022-09-07 22:03:05.789 [main] INFO  o.a.c.c.C.[Tomcat].[localhost].[/] [DirectJDKLog.java:173] Initializing Spring DispatcherServlet 'dispatcherServlet'
2022-09-07 22:03:05.790 [main] INFO  o.s.web.servlet.DispatcherServlet [FrameworkServlet.java:525] Initializing Servlet 'dispatcherServlet'
2022-09-07 22:03:16.992 [main] INFO  c.u.f.j.s.m.m.s.MatchingQueueSubscriberLoader [MatchingQueueSubscriberLoader.java:56] Subscription Matching Subscriber subscribed to Matching Channel ca.uhn.fhir.jpa.subscription.channel.subscription.BroadcastingSubscribableChannelWrapper with name subscription-matching
2022-09-07 22:03:16.997 [main] INFO  o.s.web.servlet.DispatcherServlet [FrameworkServlet.java:547] Completed initialization in 11207 ms
2022-09-07 22:03:16.999 [main] INFO  o.s.b.w.e.tomcat.TomcatWebServer [TomcatWebServer.java:220] Tomcat started on port(s): 8080 (http) with context path ''
2022-09-07 22:03:17.000 [main] INFO  o.s.s.quartz.SchedulerFactoryBean [SchedulerFactoryBean.java:729] Starting Quartz Scheduler now
2022-09-07 22:03:17.000 [main] INFO  org.quartz.core.QuartzScheduler [QuartzScheduler.java:547] Scheduler quartzScheduler_$_NON_CLUSTERED started.
2022-09-07 22:03:17.025 [main] INFO  c.u.f.j.s.m.m.s.MatchingQueueSubscriberLoader [MatchingQueueSubscriberLoader.java:56] Subscription Matching Subscriber subscribed to Matching Channel ca.uhn.fhir.jpa.subscription.channel.subscription.BroadcastingSubscribableChannelWrapper with name subscription-matching
2022-09-07 22:03:17.026 [main] INFO  ca.uhn.fhir.jpa.starter.Application [StartupInfoLogger.java:61] Started Application in 54.827 seconds (JVM running for 56.371)
2022-09-07 22:04:10.988 [http-nio-8080-exec-1] INFO  c.u.f.j.s.u.S.SUBS1 [SubscriptionDebugLogInterceptor.java:167] Resource Patient/52/_history/1 was submitted to the processing pipeline (op=CREATE)
2022-09-07 22:04:11.035 [subscription-matching-1] INFO  c.u.f.j.s.u.S.SUBS2 [SubscriptionDebugLogInterceptor.java:167] Checking resource Patient/52/_history/1 (op=CREATE) for matching subscriptions
2022-09-07 22:04:11.036 [subscription-matching-1] INFO  c.u.f.j.s.u.S.SUBS4 [SubscriptionDebugLogInterceptor.java:167] Resource Patient/52/_history/1 did not match any subscriptions
2022-09-07 22:04:11.059 [http-nio-8080-exec-1] INFO  fhirtest.access [LoggingInterceptor.java:175] Path[/fhir] Source[] Operation[create  Patient] UA[PostmanRuntime/7.29.2] Params[] ResponseEncoding[JSON] Operation[create  Patient] UA[PostmanRuntime/7.29.2] Params[] ResponseEncoding[JSON]
2022-09-07 22:04:57.068 [http-nio-8080-exec-3] INFO  ca.uhn.fhir.context.FhirContext [FhirContext.java:208] Creating new FHIR context for FHIR version [R4]
2022-09-07 22:04:58.344 [http-nio-8080-exec-4] INFO  fhirtest.access [LoggingInterceptor.java:175] Path[/fhir] Source[] Operation[metadata  ] UA[HAPI-FHIR/6.0.1 (FHIR Client; FHIR 4.0.1/R4; apache)] Params[?_pretty=true] ResponseEncoding[JSON] Operation[metadata  ] UA[HAPI-FHIR/6.0.1 (FHIR Client; FHIR 4.0.1/R4; apache)] Params[?_pretty=true] ResponseEncoding[JSON]
2022-09-07 22:04:58.403 [http-nio-8080-exec-3] INFO  ca.uhn.fhir.to.Controller [Controller.java:464] [server=home] - Executing a search
2022-09-07 22:04:58.561 [http-nio-8080-exec-5] INFO  fhirtest.access [LoggingInterceptor.java:175] Path[/fhir] Source[] Operation[search-type  Patient] UA[HAPI-FHIR/6.0.1 (FHIR Client; FHIR 4.0.1/R4; apache)] Params[?_pretty=true] ResponseEncoding[JSON] Operation[search-type  Patient] UA[HAPI-FHIR/6.0.1 (FHIR Client; FHIR 4.0.1/R4; apache)] Params[?_pretty=true] ResponseEncoding[JSON]
2022-09-07 22:05:06.169 [http-nio-8080-exec-3] INFO  fhirtest.access [LoggingInterceptor.java:175] Path[/fhir] Source[] Operation[vread  Patient/52/_history/1] UA[Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:104.0) Gecko/20100101 Firefox/104.0] Params[] ResponseEncoding[XML] Operation[vread  Patient/52/_history/1] UA[Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:104.0) Gecko/20100101 Firefox/104.0] Params[] ResponseEncoding[XML]
2022-09-07 22:16:50.091 [http-nio-8080-exec-3] INFO  c.u.f.j.s.u.S.SUBS1 [SubscriptionDebugLogInterceptor.java:167] Resource Patient/53/_history/1 was submitted to the processing pipeline (op=CREATE)
2022-09-07 22:16:50.125 [subscription-matching-2] INFO  c.u.f.j.s.u.S.SUBS2 [SubscriptionDebugLogInterceptor.java:167] Checking resource Patient/53/_history/1 (op=CREATE) for matching subscriptions
2022-09-07 22:16:50.125 [subscription-matching-2] INFO  c.u.f.j.s.u.S.SUBS4 [SubscriptionDebugLogInterceptor.java:167] Resource Patient/53/_history/1 did not match any subscriptions
2022-09-07 22:16:50.128 [http-nio-8080-exec-3] INFO  fhirtest.access [LoggingInterceptor.java:175] Path[/fhir] Source[] Operation[create  Patient] UA[PostmanRuntime/7.29.2] Params[] ResponseEncoding[JSON] Operation[create  Patient] UA[PostmanRuntime/7.29.2] Params[] ResponseEncoding[JSON]

I would be grateful for some insights regarding this 🙏

cdelanchy avatar Sep 07 '22 20:09 cdelanchy

    implementationguides:
      france:
        name: hl7-france-fhir.administrative
        version: 11.2021.1

is enough for HAPI to download the IG as it is already posted to the global registry

jkiddo avatar Sep 07 '22 20:09 jkiddo

Hello there!

Thank you for your reply, @jkiddo: it really helped!

I had 2 packages to download. And they are both on the FHIR registry. I managed to fully download one, HAPI managed to import it and the validation is successful when I try to post a ressource with the corresponding profile.

For the second package, HAPI failed to import them, but thanks to the logs, I reported the problems to the package owner and I'm waiting for a fix.

Thank you again!

cdelanchy avatar Sep 22 '22 16:09 cdelanchy

np

jkiddo avatar Sep 28 '22 21:09 jkiddo