From 36babba90c5a70cea6e92307a58bfa1091f41687 Mon Sep 17 00:00:00 2001 From: Chris O Riordan Date: Fri, 18 Jul 2025 11:53:43 -0700 Subject: [PATCH 1/4] Add TerminologySeverClientSettings to CR Properties & Config --- .../ca/uhn/fhir/jpa/starter/cr/CrCommonConfig.java | 6 ++++++ .../java/ca/uhn/fhir/jpa/starter/cr/CrProperties.java | 10 ++++++++++ src/main/resources/application.yaml | 5 +++++ src/main/resources/cds.application.yaml | 5 +++++ 4 files changed, 26 insertions(+) diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrCommonConfig.java b/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrCommonConfig.java index 1822340..af3768b 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrCommonConfig.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrCommonConfig.java @@ -22,6 +22,7 @@ import org.opencds.cqf.fhir.cr.hapi.common.ElmCacheResourceChangeListener; import org.opencds.cqf.fhir.cr.measure.CareGapsProperties; import org.opencds.cqf.fhir.cr.measure.MeasureEvaluationOptions; import org.opencds.cqf.fhir.utility.ValidationProfile; +import org.opencds.cqf.fhir.utility.client.TerminologyServerClientSettings; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; @@ -57,6 +58,11 @@ public class CrCommonConfig { return theCrProperties.getCql().getTerminology(); } + @Bean + TerminologyServerClientSettings terminologyServerClientSettings(CrProperties theCrProperties) { + return theCrProperties.getTerminologyServerClientSettings(); + } + @Bean public EvaluationSettings evaluationSettings( CrProperties theCrProperties, diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrProperties.java b/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrProperties.java index 8ba5ccf..8a986b3 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrProperties.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrProperties.java @@ -1,11 +1,15 @@ package ca.uhn.fhir.jpa.starter.cr; +import org.opencds.cqf.fhir.utility.client.TerminologyServerClientSettings; + public class CrProperties { private Boolean enabled; private CareGapsProperties careGaps = new CareGapsProperties(); private CqlProperties cql = new CqlProperties(); + private TerminologyServerClientSettings terminologyServerClientSettings = new TerminologyServerClientSettings(); + public Boolean getEnabled() { return enabled; } @@ -29,4 +33,10 @@ public class CrProperties { public void setCql(CqlProperties cql) { this.cql = cql; } + + public TerminologyServerClientSettings getTerminologyServerClientSettings() { return terminologyServerClientSettings; } + + public void setTerminologyServerClientSettings(TerminologyServerClientSettings terminologyServerClientSettings) { + this.terminologyServerClientSettings = terminologyServerClientSettings; + } } diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index cb0c0ce..10787ce 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -89,6 +89,11 @@ hapi: caregaps: reporter: "default" section_author: "default" + terminologyServerClientSettings: + maxRetryCount: 3 + retryIntervalMillis: 1000 + timeoutSeconds: 30 + socketTimeout: 60 cql: use_embedded_libraries: true compiler: diff --git a/src/main/resources/cds.application.yaml b/src/main/resources/cds.application.yaml index 2d98309..dd2d349 100644 --- a/src/main/resources/cds.application.yaml +++ b/src/main/resources/cds.application.yaml @@ -87,6 +87,11 @@ hapi: caregaps: reporter: "default" section_author: "default" + terminologyServerClientSettings: + maxRetryCount: 3 + retryIntervalMillis: 1000 + timeoutSeconds: 30 + socketTimeout: 60 cql: use_embedded_libraries: true compiler: From 0e17b198d04b236952fd729b4a825f186a7d0c5c Mon Sep 17 00:00:00 2001 From: Chris O Riordan Date: Fri, 1 Aug 2025 07:38:53 -0700 Subject: [PATCH 2/4] Apply spotless --- src/main/java/ca/uhn/fhir/jpa/starter/cr/CrProperties.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrProperties.java b/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrProperties.java index 8a986b3..e4af126 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrProperties.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cr/CrProperties.java @@ -34,7 +34,9 @@ public class CrProperties { this.cql = cql; } - public TerminologyServerClientSettings getTerminologyServerClientSettings() { return terminologyServerClientSettings; } + public TerminologyServerClientSettings getTerminologyServerClientSettings() { + return terminologyServerClientSettings; + } public void setTerminologyServerClientSettings(TerminologyServerClientSettings terminologyServerClientSettings) { this.terminologyServerClientSettings = terminologyServerClientSettings; From d6e9fba839430802d4b8c17ce6cbf79f356ebcbb Mon Sep 17 00:00:00 2001 From: Brenin Rhodes Date: Wed, 13 Aug 2025 07:20:23 -0600 Subject: [PATCH 3/4] Update to CR release 3.24.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0145c05..d5e173d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 17 2 - 3.23.0 + 3.24.0 From 8224cae13113e65da570b02406b0f46b19c8e4c9 Mon Sep 17 00:00:00 2001 From: winfriedgerlach <158032591+winfriedgerlach@users.noreply.github.com> Date: Tue, 19 Aug 2025 20:00:34 +0200 Subject: [PATCH 4/4] some cleanup (#840) * some cleanup * results from mvn spotless:apply * fix contructor --> constructor * revert change to fix CdsHooksServletIT * revert change to charts README.md * bump chart version, required due to changes in README.md --- .gitignore | 1 - README.md | 16 +-- charts/hapi-fhir-jpaserver/Chart.yaml | 14 +-- charts/hapi-fhir-jpaserver/README.md | 4 +- charts/hapi-fhir-jpaserver/README.md.gotmpl | 2 +- pom.xml | 2 +- .../ca/uhn/fhir/jpa/starter/Application.java | 2 +- .../jpa/starter/cdshooks/CdsHooksServlet.java | 3 + .../ModuleConfigurationPrefetchSvc.java | 5 +- .../common/FhirServerConfigCommon.java | 89 ++++++++------ .../jpa/starter/common/StarterJpaConfig.java | 10 +- ...ositoryValidationInterceptorFactoryR4.java | 4 +- ...sitoryValidationInterceptorFactoryR4B.java | 4 +- ...ositoryValidationInterceptorFactoryR5.java | 4 +- .../cr/PostInitProviderRegisterer.java | 2 +- .../jpa/starter/util/EnvironmentHelper.java | 6 +- src/main/resources/application.yaml | 8 +- src/main/resources/cds.application.yaml | 12 +- src/main/webapp/WEB-INF/templates/about.html | 8 +- .../fhir/jpa/starter/CdsHooksServletIT.java | 47 +++---- .../jpa/starter/ElasticsearchLastNR4IT.java | 14 +-- .../jpa/starter/ExampleServerDbpmR5IT.java | 2 +- .../jpa/starter/ExampleServerDstu3IT.java | 2 - .../fhir/jpa/starter/ExampleServerR4BIT.java | 93 +++++++------- .../fhir/jpa/starter/ExampleServerR4IT.java | 116 ++++++++---------- .../uhn/fhir/jpa/starter/IServerSupport.java | 4 +- .../jpa/starter/MeasureEvaluationConfig.java | 4 - .../ParallelUpdatesVersionConflictTest.java | 67 +++++----- .../jpa/starter/SocketImplementation.java | 7 +- .../custom/pkg1/CustomInterceptorBean.java | 3 +- .../custom/pkg1/CustomInterceptorPojo.java | 3 +- src/test/resources/application.yaml | 6 +- src/test/smoketest/SMOKE_TEST.md | 4 +- src/test/smoketest/plain_server.http | 4 +- 34 files changed, 272 insertions(+), 300 deletions(-) diff --git a/.gitignore b/.gitignore index 6e006b7..7468cdc 100644 --- a/.gitignore +++ b/.gitignore @@ -124,7 +124,6 @@ local.properties .factorypath .project .settings -.springBeans .sts4-cache # Code Recommenders diff --git a/README.md b/README.md index e88cfc0..a5d58a1 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ HAPI looks in the environment variables for properties in the [application.yaml] ### Configuration via overridden application.yaml file and using Docker -You can customize HAPI by telling HAPI to look for the configuration file in a different location, eg.: +You can customize HAPI by telling HAPI to look for the configuration file in a different location, e.g.: ``` docker run -p 8090:8080 -v $(pwd)/yourLocalFolder:/configs -e "--spring.config.location=file:///configs/another.application.yaml" hapiproject/hapi:latest @@ -237,7 +237,7 @@ The Server will then be accessible at http://localhost:8888/fhir and the Capabil ```bash mvn clean spring-boot:run -Pboot ``` -Server will then be accessible at http://localhost:8080/ and eg. http://localhost:8080/fhir/metadata. Remember to adjust you overlay configuration in the application.yaml to the following: +Server will then be accessible at http://localhost:8080/ and e.g. http://localhost:8080/fhir/metadata. Remember to adjust you overlay configuration in the application.yaml to the following: ```yaml tester: @@ -253,7 +253,7 @@ Server will then be accessible at http://localhost:8080/ and eg. http://localhos ```bash mvn clean package spring-boot:repackage -DskipTests=true -Pboot && java -jar target/ROOT.war ``` -Server will then be accessible at http://localhost:8080/ and eg. http://localhost:8080/fhir/metadata. Remember to adjust your overlay configuration in the application.yaml to the following: +Server will then be accessible at http://localhost:8080/ and e.g. http://localhost:8080/fhir/metadata. Remember to adjust your overlay configuration in the application.yaml to the following: ```yaml tester: @@ -268,7 +268,7 @@ Server will then be accessible at http://localhost:8080/ and eg. http://localhos ```bash mvn clean package com.google.cloud.tools:jib-maven-plugin:dockerBuild -Dimage=distroless-hapi && docker run -p 8080:8080 distroless-hapi ``` -Server will then be accessible at http://localhost:8080/ and eg. http://localhost:8080/fhir/metadata. Remember to adjust your overlay configuration in the application.yaml to the following: +Server will then be accessible at http://localhost:8080/ and e.g. http://localhost:8080/fhir/metadata. Remember to adjust your overlay configuration in the application.yaml to the following: ```yaml tester: @@ -284,7 +284,7 @@ Server will then be accessible at http://localhost:8080/ and eg. http://localhos ```bash ./build-docker-image.sh && docker run -p 8080:8080 hapi-fhir/hapi-fhir-jpaserver-starter:latest ``` -Server will then be accessible at http://localhost:8080/ and eg. http://localhost:8080/fhir/metadata. Remember to adjust your overlay configuration in the application.yaml to the following: +Server will then be accessible at http://localhost:8080/ and e.g. http://localhost:8080/fhir/metadata. Remember to adjust your overlay configuration in the application.yaml to the following: ```yaml tester: @@ -384,7 +384,7 @@ Several template files that can be customized are found in the following directo Using the Maven-Embedded Jetty method above is convenient, but it is not a good solution if you want to leave the server running in the background. -Most people who are using HAPI FHIR JPA as a server that is accessible to other people (whether internally on your network or publically hosted) will do so using an Application Server, such as [Apache Tomcat](http://tomcat.apache.org/) or [Jetty](https://www.eclipse.org/jetty/). Note that any Servlet 3.0+ compatible Web Container will work (e.g Wildfly, Websphere, etc.). +Most people who are using HAPI FHIR JPA as a server that is accessible to other people (whether internally on your network or publicly hosted) will do so using an Application Server, such as [Apache Tomcat](http://tomcat.apache.org/) or [Jetty](https://www.eclipse.org/jetty/). Note that any Servlet 3.0+ compatible Web Container will work (e.g. Wildfly, Websphere, etc.). Tomcat is very popular, so it is a good choice simply because you will be able to find many tutorials online. Jetty is a great alternative due to its fast startup time and good overall performance. @@ -402,7 +402,7 @@ Again, browse to the following link to use the server (note that the port 8080 m You will then be able to access the JPA server e.g. using http://localhost:8080/fhir/metadata. -If you would like it to be hosted at eg. hapi-fhir-jpaserver, eg. http://localhost:8080/hapi-fhir-jpaserver/ or http://localhost:8080/hapi-fhir-jpaserver/fhir/metadata - then rename the WAR file to ```hapi-fhir-jpaserver.war``` and adjust the overlay configuration accordingly e.g. +If you would like it to be hosted at e.g. hapi-fhir-jpaserver, e.g. http://localhost:8080/hapi-fhir-jpaserver/ or http://localhost:8080/hapi-fhir-jpaserver/fhir/metadata - then rename the WAR file to ```hapi-fhir-jpaserver.war``` and adjust the overlay configuration accordingly e.g. ```yaml tester: @@ -525,7 +525,7 @@ Set `hapi.fhir.store_resource_in_lucene_index_enabled` in the [application.yaml] ## Changing cached search results time -It is possible to change the cached search results time. The option `reuse_cached_search_results_millis` in the [application.yaml](https://github.com/hapifhir/hapi-fhir-jpaserver-starter/blob/master/src/main/resources/application.yaml) is 6000 miliseconds by default. +It is possible to change the cached search results time. The option `reuse_cached_search_results_millis` in the [application.yaml](https://github.com/hapifhir/hapi-fhir-jpaserver-starter/blob/master/src/main/resources/application.yaml) is 6000 milliseconds by default. Set `reuse_cached_search_results_millis: -1` in the [application.yaml](https://github.com/hapifhir/hapi-fhir-jpaserver-starter/blob/master/src/main/resources/application.yaml) file to ignore the cache time every search. ## Build the distroless variant of the image (for lower footprint and improved security) diff --git a/charts/hapi-fhir-jpaserver/Chart.yaml b/charts/hapi-fhir-jpaserver/Chart.yaml index dac5171..ff22918 100644 --- a/charts/hapi-fhir-jpaserver/Chart.yaml +++ b/charts/hapi-fhir-jpaserver/Chart.yaml @@ -14,7 +14,7 @@ dependencies: repository: oci://registry-1.docker.io/bitnamicharts version: 2.31.3 appVersion: 8.2.0 -version: 0.20.0 +version: 0.20.1 annotations: artifacthub.io/license: Apache-2.0 artifacthub.io/containsSecurityUpdates: "false" @@ -27,14 +27,4 @@ annotations: # When using the list of objects option the valid supported kinds are # added, changed, deprecated, removed, fixed, and security. - kind: changed - description: "updated postgresql sub-chart to 16.7.11" - - kind: changed - description: "updated common sub-chart to 2.31.3" - - kind: changed - description: "updated curlimages/curl to 8.14.1" - - kind: changed - description: "updated hapiproject/hapi to v8.2.0-1" - - kind: changed - description: "use ca.uhn.fhir.jpa.model.dialect.HapiFhirPostgresDialect dialect" - - kind: changed - description: "made the init container waiting for the database to be ready configurable" + description: "fixed typo in README.md" diff --git a/charts/hapi-fhir-jpaserver/README.md b/charts/hapi-fhir-jpaserver/README.md index 30a0e2f..b807fdc 100644 --- a/charts/hapi-fhir-jpaserver/README.md +++ b/charts/hapi-fhir-jpaserver/README.md @@ -1,6 +1,6 @@ # HAPI FHIR JPA Server Starter Helm Chart -![Version: 0.20.0](https://img.shields.io/badge/Version-0.20.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 8.2.0](https://img.shields.io/badge/AppVersion-8.2.0-informational?style=flat-square) +![Version: 0.20.1](https://img.shields.io/badge/Version-0.20.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 8.2.0](https://img.shields.io/badge/AppVersion-8.2.0-informational?style=flat-square) This helm chart will help you install the HAPI FHIR JPA Server in a Kubernetes environment. @@ -98,7 +98,7 @@ INFO[2021-11-20T12:38:04Z] Found Chart directories [charts/hapi-fhir-jpaserver] INFO[2021-11-20T12:38:04Z] Generating README Documentation for chart /usr/src/app/charts/hapi-fhir-jpaserver ``` -## Enable Distributed Tracing based on the OpenTelemtry Java Agent +## Enable Distributed Tracing based on the OpenTelemetry Java Agent The container image includes the [OpenTelemetry Java agent JAR](https://github.com/open-telemetry/opentelemetry-java-instrumentation) which can be used to enable distributed tracing. It can be configured entirely using environment variables, diff --git a/charts/hapi-fhir-jpaserver/README.md.gotmpl b/charts/hapi-fhir-jpaserver/README.md.gotmpl index 4647395..2d7f487 100644 --- a/charts/hapi-fhir-jpaserver/README.md.gotmpl +++ b/charts/hapi-fhir-jpaserver/README.md.gotmpl @@ -27,7 +27,7 @@ INFO[2021-11-20T12:38:04Z] Found Chart directories [charts/hapi-fhir-jpaserver] INFO[2021-11-20T12:38:04Z] Generating README Documentation for chart /usr/src/app/charts/hapi-fhir-jpaserver ``` -## Enable Distributed Tracing based on the OpenTelemtry Java Agent +## Enable Distributed Tracing based on the OpenTelemetry Java Agent The container image includes the [OpenTelemetry Java agent JAR](https://github.com/open-telemetry/opentelemetry-java-instrumentation) which can be used to enable distributed tracing. It can be configured entirely using environment variables, diff --git a/pom.xml b/pom.xml index d5e173d..9bdd5bc 100644 --- a/pom.xml +++ b/pom.xml @@ -191,7 +191,7 @@ provided - + org.thymeleaf thymeleaf diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/Application.java b/src/main/java/ca/uhn/fhir/jpa/starter/Application.java index 5be155f..c3033ad 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/Application.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/Application.java @@ -45,7 +45,7 @@ public class Application extends SpringBootServletInitializer { SpringApplication.run(Application.class, args); - // Server is now accessible at eg. http://localhost:8080/fhir/metadata + // Server is now accessible at e.g. http://localhost:8080/fhir/metadata // UI is now accessible at http://localhost:8080/ } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/CdsHooksServlet.java b/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/CdsHooksServlet.java index 034d5cf..bc90000 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/CdsHooksServlet.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/CdsHooksServlet.java @@ -22,6 +22,7 @@ import org.springframework.beans.factory.annotation.Configurable; import org.springframework.beans.factory.annotation.Qualifier; import java.io.IOException; +import java.io.Serial; import java.util.stream.Collectors; import static org.opencds.cqf.fhir.cr.hapi.config.test.TestCdsHooksConfig.CDS_HOOKS_OBJECT_MAPPER_FACTORY; @@ -29,6 +30,8 @@ import static org.opencds.cqf.fhir.cr.hapi.config.test.TestCdsHooksConfig.CDS_HO @Configurable public class CdsHooksServlet extends HttpServlet { private static final Logger logger = LoggerFactory.getLogger(CdsHooksServlet.class); + + @Serial private static final long serialVersionUID = 1L; @Autowired diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/ModuleConfigurationPrefetchSvc.java b/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/ModuleConfigurationPrefetchSvc.java index 12e5594..c76e0e7 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/ModuleConfigurationPrefetchSvc.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/ModuleConfigurationPrefetchSvc.java @@ -179,9 +179,8 @@ public class ModuleConfigurationPrefetchSvc extends CdsPrefetchSvc { return true; } if (resource instanceof IBaseBundle) { - return BundleUtil.toListOfEntries(fhirContext, (IBaseBundle) resource) - .size() - > 0; + return !BundleUtil.toListOfEntries(fhirContext, (IBaseBundle) resource) + .isEmpty(); } return false; } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigCommon.java b/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigCommon.java index 468f1f5..c3728b8 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigCommon.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirServerConfigCommon.java @@ -41,24 +41,28 @@ public class FhirServerConfigCommon { private static final Logger ourLog = LoggerFactory.getLogger(FhirServerConfigCommon.class); public FhirServerConfigCommon(AppProperties appProperties) { - ourLog.info("Server configured to " + (appProperties.getAllow_contains_searches() ? "allow" : "deny") - + " contains searches"); - ourLog.info("Server configured to " + (appProperties.getAllow_multiple_delete() ? "allow" : "deny") - + " multiple deletes"); - ourLog.info("Server configured to " + (appProperties.getAllow_external_references() ? "allow" : "deny") - + " external references"); - ourLog.info("Server configured to " + (appProperties.getDao_scheduling_enabled() ? "enable" : "disable") - + " DAO scheduling"); - ourLog.info("Server configured to " + (appProperties.getDelete_expunge_enabled() ? "enable" : "disable") - + " delete expunges"); ourLog.info( - "Server configured to " + (appProperties.getExpunge_enabled() ? "enable" : "disable") + " expunges"); + "Server configured to {} contains searches", + appProperties.getAllow_contains_searches() ? "allow" : "deny"); ourLog.info( - "Server configured to " + (appProperties.getAllow_override_default_search_params() ? "allow" : "deny") - + " overriding default search params"); - ourLog.info("Server configured to " - + (appProperties.getAuto_create_placeholder_reference_targets() ? "allow" : "disable") - + " auto-creating placeholder references"); + "Server configured to {} multiple deletes", + appProperties.getAllow_multiple_delete() ? "allow" : "deny"); + ourLog.info( + "Server configured to {} external references", + appProperties.getAllow_external_references() ? "allow" : "deny"); + ourLog.info( + "Server configured to {} DAO scheduling", + appProperties.getDao_scheduling_enabled() ? "enable" : "disable"); + ourLog.info( + "Server configured to {} delete expunges", + appProperties.getDelete_expunge_enabled() ? "enable" : "disable"); + ourLog.info("Server configured to {} expunges", appProperties.getExpunge_enabled() ? "enable" : "disable"); + ourLog.info( + "Server configured to {} overriding default search params", + appProperties.getAllow_override_default_search_params() ? "allow" : "deny"); + ourLog.info( + "Server configured to {} auto-creating placeholder references", + appProperties.getAuto_create_placeholder_reference_targets() ? "allow" : "disable"); ourLog.info( "Server configured to auto-version references at paths {}", appProperties.getAuto_version_reference_at_paths()); @@ -66,12 +70,14 @@ public class FhirServerConfigCommon { if (appProperties.getSubscription().getEmail() != null) { AppProperties.Subscription.Email email = appProperties.getSubscription().getEmail(); - ourLog.info("Server is configured to enable email with host '" + email.getHost() + "' and port " - + email.getPort()); - ourLog.info("Server will use '" + email.getFrom() + "' as the from email address"); + ourLog.info( + "Server is configured to enable email with host '{}' and port {}", + email.getHost(), + email.getPort()); + ourLog.info("Server will use '{}' as the from email address", email.getFrom()); if (!Strings.isNullOrEmpty(email.getUsername())) { - ourLog.info("Server is configured to use username '" + email.getUsername() + "' for email"); + ourLog.info("Server is configured to use username '{}' for email", email.getUsername()); } if (!Strings.isNullOrEmpty(email.getPassword())) { @@ -91,17 +97,19 @@ public class FhirServerConfigCommon { ourLog.info("Indexed on contained resource enabled"); } - ourLog.info("Server configured to " + (appProperties.getPre_expand_value_sets() ? "enable" : "disable") - + " value set pre-expansion"); ourLog.info( - "Server configured to " + (appProperties.getEnable_task_pre_expand_value_sets() ? "enable" : "disable") - + " value set pre-expansion task"); - ourLog.info("Server configured for pre-expand value set default count of " - + (appProperties.getPre_expand_value_sets_default_count().toString())); - ourLog.info("Server configured for pre-expand value set max count of " - + (appProperties.getPre_expand_value_sets_max_count().toString())); - ourLog.info("Server configured for maximum expansion size of " - + (appProperties.getMaximum_expansion_size().toString())); + "Server configured to {} value set pre-expansion", + appProperties.getPre_expand_value_sets() ? "enable" : "disable"); + ourLog.info( + "Server configured to {} value set pre-expansion task", + appProperties.getEnable_task_pre_expand_value_sets() ? "enable" : "disable"); + ourLog.info( + "Server configured for pre-expand value set default count of {}", + appProperties.getPre_expand_value_sets_default_count()); + ourLog.info( + "Server configured for pre-expand value set max count of {}", + appProperties.getPre_expand_value_sets_max_count()); + ourLog.info("Server configured for maximum expansion size of {}", appProperties.getMaximum_expansion_size()); } @Bean @@ -194,8 +202,9 @@ public class FhirServerConfigCommon { Integer maxFetchSize = appProperties.getMax_page_size(); jpaStorageSettings.setFetchSizeDefaultMaximum(maxFetchSize); - ourLog.info("Server configured to have a maximum fetch size of " - + (maxFetchSize == Integer.MAX_VALUE ? "'unlimited'" : maxFetchSize)); + ourLog.info( + "Server configured to have a maximum fetch size of {}", + maxFetchSize == Integer.MAX_VALUE ? "'unlimited'" : maxFetchSize); Long reuseCachedSearchResultsMillis = appProperties.getReuse_cached_search_results_millis(); jpaStorageSettings.setReuseCachedSearchResultsForMillis(reuseCachedSearchResultsMillis); @@ -237,19 +246,21 @@ public class FhirServerConfigCommon { // Set and/or recommend default Server ID Strategy of UUID when using the ANY Client ID Strategy if (appProperties.getClient_id_strategy() == JpaStorageSettings.ClientIdStrategyEnum.ANY) { if (appProperties.getServer_id_strategy() == null) { - ourLog.info("Defaulting server to use '" + JpaStorageSettings.IdStrategyEnum.UUID - + "' Server ID Strategy when using the '" + JpaStorageSettings.ClientIdStrategyEnum.ANY - + "' Client ID Strategy"); + ourLog.info( + "Defaulting server to use '{}' Server ID Strategy when using the '{}' Client ID Strategy", + JpaStorageSettings.IdStrategyEnum.UUID, + JpaStorageSettings.ClientIdStrategyEnum.ANY); appProperties.setServer_id_strategy(JpaStorageSettings.IdStrategyEnum.UUID); } else if (appProperties.getServer_id_strategy() != JpaStorageSettings.IdStrategyEnum.UUID) { - ourLog.warn("WARNING: '" + JpaStorageSettings.IdStrategyEnum.UUID - + "' Server ID Strategy is highly recommended when using the '" - + JpaStorageSettings.ClientIdStrategyEnum.ANY + "' Client ID Strategy"); + ourLog.warn( + "WARNING: '{}' Server ID Strategy is highly recommended when using the '{}' Client ID Strategy", + JpaStorageSettings.IdStrategyEnum.UUID, + JpaStorageSettings.ClientIdStrategyEnum.ANY); } } if (appProperties.getServer_id_strategy() != null) { jpaStorageSettings.setResourceServerIdStrategy(appProperties.getServer_id_strategy()); - ourLog.info("Server configured to use '" + appProperties.getServer_id_strategy() + "' Server ID Strategy"); + ourLog.info("Server configured to use '{}' Server ID Strategy", appProperties.getServer_id_strategy()); } // to Disable the Resource History diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/common/StarterJpaConfig.java b/src/main/java/ca/uhn/fhir/jpa/starter/common/StarterJpaConfig.java index 386c503..2344f12 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/common/StarterJpaConfig.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/common/StarterJpaConfig.java @@ -248,7 +248,7 @@ public class StarterJpaConfig { List allAllowedCORSOrigins = appProperties.getCors().getAllowed_origin(); allAllowedCORSOrigins.forEach(config::addAllowedOriginPattern); - ourLog.info("CORS allows the following origins: " + String.join(", ", allAllowedCORSOrigins)); + ourLog.info("CORS allows the following origins: {}", String.join(", ", allAllowedCORSOrigins)); config.addExposedHeader("Location"); config.addExposedHeader("Content-Location"); @@ -467,9 +467,7 @@ public class StarterJpaConfig { registerCustomInterceptors(fhirServer, appContext, appProperties.getCustomInterceptorClasses()); // register the IPS Provider - if (!theIpsOperationProvider.isEmpty()) { - fhirServer.registerProvider(theIpsOperationProvider.get()); - } + theIpsOperationProvider.ifPresent(fhirServer::registerProvider); if (appProperties.getUserRequestRetryVersionConflictsInterceptorEnabled()) { fhirServer.registerInterceptor(new UserRequestRetryVersionConflictsInterceptor()); @@ -500,7 +498,7 @@ public class StarterJpaConfig { throw new ConfigurationException("Interceptor class was not found on classpath: " + className, e); } - // first check if the class a Bean in the app context + // first check if the class is a Bean in the app context Object interceptor = null; try { interceptor = theAppContext.getBean(clazz); @@ -541,7 +539,7 @@ public class StarterJpaConfig { throw new ConfigurationException("Provider class was not found on classpath: " + className, e); } - // first check if the class a Bean in the app context + // first check if the class is a Bean in the app context Object provider = null; try { provider = theAppContext.getBean(clazz); diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryR4.java b/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryR4.java index 685a355..94f0538 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryR4.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryR4.java @@ -50,11 +50,11 @@ public class RepositoryValidationInterceptorFactoryR4 implements IRepositoryVali IBundleProvider results = structureDefinitionResourceProvider.search(new SearchParameterMap() .setLoadSynchronous(true) .add(StructureDefinition.SP_KIND, new TokenParam("resource"))); - Map> structureDefintions = results.getResources(0, results.size()).stream() + Map> structureDefinitions = results.getResources(0, results.size()).stream() .map(StructureDefinition.class::cast) .collect(Collectors.groupingBy(StructureDefinition::getType)); - structureDefintions.forEach((key, value) -> { + structureDefinitions.forEach((key, value) -> { String[] urls = value.stream().map(StructureDefinition::getUrl).toArray(String[]::new); repositoryValidatingRuleBuilder .forResourcesOfType(key) diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryR4B.java b/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryR4B.java index 00a1bcc..8f38d31 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryR4B.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryR4B.java @@ -50,11 +50,11 @@ public class RepositoryValidationInterceptorFactoryR4B implements IRepositoryVal IBundleProvider results = structureDefinitionResourceProvider.search(new SearchParameterMap() .setLoadSynchronous(true) .add(StructureDefinition.SP_KIND, new TokenParam("resource"))); - Map> structureDefintions = results.getResources(0, results.size()).stream() + Map> structureDefinitions = results.getResources(0, results.size()).stream() .map(StructureDefinition.class::cast) .collect(Collectors.groupingBy(StructureDefinition::getType)); - structureDefintions.forEach((key, value) -> { + structureDefinitions.forEach((key, value) -> { String[] urls = value.stream().map(StructureDefinition::getUrl).toArray(String[]::new); repositoryValidatingRuleBuilder .forResourcesOfType(key) diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryR5.java b/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryR5.java index 2a84eac..60c2366 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryR5.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryR5.java @@ -49,11 +49,11 @@ public class RepositoryValidationInterceptorFactoryR5 implements IRepositoryVali IBundleProvider results = structureDefinitionResourceProvider.search(new SearchParameterMap() .setLoadSynchronous(true) .add(StructureDefinition.SP_KIND, new TokenParam("resource"))); - Map> structureDefintions = results.getResources(0, results.size()).stream() + Map> structureDefinitions = results.getResources(0, results.size()).stream() .map(StructureDefinition.class::cast) .collect(Collectors.groupingBy(StructureDefinition::getType)); - structureDefintions.forEach((key, value) -> { + structureDefinitions.forEach((key, value) -> { String[] urls = value.stream().map(StructureDefinition::getUrl).toArray(String[]::new); repositoryValidatingRuleBuilder .forResourcesOfType(key) diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/cr/PostInitProviderRegisterer.java b/src/main/java/ca/uhn/fhir/jpa/starter/cr/PostInitProviderRegisterer.java index a82c876..f617355 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/cr/PostInitProviderRegisterer.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cr/PostInitProviderRegisterer.java @@ -11,7 +11,7 @@ public class PostInitProviderRegisterer { resourceProviderFactory.attach(new Observer(restfulServer)); } - private class Observer implements IResourceProviderFactoryObserver { + private static class Observer implements IResourceProviderFactoryObserver { private RestfulServer restfulServer; public Observer(RestfulServer restfulServer) { diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/util/EnvironmentHelper.java b/src/main/java/ca/uhn/fhir/jpa/starter/util/EnvironmentHelper.java index e22a179..5d983ec 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/util/EnvironmentHelper.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/util/EnvironmentHelper.java @@ -188,14 +188,12 @@ public class EnvironmentHelper { public static Map getAllProperties(PropertySource aPropSource) { Map result = new HashMap<>(); - if (aPropSource instanceof CompositePropertySource) { - CompositePropertySource cps = (CompositePropertySource) aPropSource; + if (aPropSource instanceof CompositePropertySource cps) { cps.getPropertySources().forEach(ps -> addAll(result, getAllProperties(ps))); return result; } - if (aPropSource instanceof EnumerablePropertySource) { - EnumerablePropertySource ps = (EnumerablePropertySource) aPropSource; + if (aPropSource instanceof EnumerablePropertySource ps) { Arrays.asList(ps.getPropertyNames()).forEach(key -> result.put(key, ps.getProperty(key))); return result; } diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 965027c..ed0dc64 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -6,7 +6,7 @@ server: tomcat: # allow | as a separator in the URL relaxed-query-chars: "|" -#Adds the option to go to eg. http://localhost:8080/actuator/health for seeing the running configuration +#Adds the option to go to e.g. http://localhost:8080/actuator/health for seeing the running configuration #see https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html#actuator.endpoints management: #The following configuration will enable the actuator endpoints at /actuator/health, /actuator/info, /actuator/prometheus, /actuator/metrics. For security purposes, only /actuator/health is enabled by default. @@ -14,7 +14,7 @@ management: enabled-by-default: false web: exposure: - include: 'health' # or e.g. 'info,health,prometheus,metrics' or '*' for all' + include: 'health' # or e.g. 'info,health,prometheus,metrics' or '*' for all endpoint: info: enabled: true @@ -293,12 +293,12 @@ hapi: # comma-separated list of fully qualified interceptor classes. # classes listed here will be fetched from the Spring context when combined with 'custom-bean-packages', - # or will be instantiated via reflection using an no-arg contructor; then registered with the server + # or will be instantiated via reflection using a no-arg constructor; then registered with the server #custom-interceptor-classes: # comma-separated list of fully qualified provider classes. # classes listed here will be fetched from the Spring context when combined with 'custom-bean-packages', - # or will be instantiated via reflection using an no-arg contructor; then registered with the server + # or will be instantiated via reflection using a no-arg constructor; then registered with the server #custom-provider-classes: # specify what should be stored in meta.source based on StoreMetaSourceInformationEnum defaults to NONE # store_meta_source_information: NONE diff --git a/src/main/resources/cds.application.yaml b/src/main/resources/cds.application.yaml index dd2d349..2a8cf9d 100644 --- a/src/main/resources/cds.application.yaml +++ b/src/main/resources/cds.application.yaml @@ -3,7 +3,7 @@ server: # servlet: # context-path: /example/path port: 8080 -#Adds the option to go to eg. http://localhost:8080/actuator/health for seeing the running configuration +#Adds the option to go to e.g. http://localhost:8080/actuator/health for seeing the running configuration #see https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html#actuator.endpoints management: #The following configuration will enable the actuator endpoints at /actuator/health, /actuator/info, /actuator/prometheus, /actuator/metrics. For security purposes, only /actuator/health is enabled by default. @@ -11,7 +11,7 @@ management: enabled-by-default: false web: exposure: - include: 'health' # or e.g. 'info,health,prometheus,metrics' or '*' for all' + include: 'health' # or e.g. 'info,health,prometheus,metrics' or '*' for all endpoint: info: enabled: true @@ -149,7 +149,7 @@ hapi: ### forces the use of the https:// protocol for the returned server address. ### alternatively, it may be set using the X-Forwarded-Proto header. # use_apache_address_strategy_https: false - ### enables the server to overwrite defaults on HTML, css, etc. under the url pattern of eg. /content/custom ** + ### enables the server to overwrite defaults on HTML, css, etc. under the url pattern of e.g. /content/custom ** ### Folder with custom content MUST be named custom. If omitted then default content applies #custom_content_path: ./custom ### enables the server host custom content. If e.g. the value ./configs/app is supplied then the content @@ -198,7 +198,7 @@ hapi: # enable_index_of_type: true # enable_index_contained_resource: false # resource_dbhistory_enabled: false - ### !!Extended Lucene/Elasticsearch Indexing is still a experimental feature, expect some features (e.g. _total=accurate) to not work as expected!! + ### !!Extended Lucene/Elasticsearch Indexing is still an experimental feature, expect some features (e.g. _total=accurate) to not work as expected!! ### more information here: https://hapifhir.io/hapi-fhir/docs/server_jpa/elastic.html advanced_lucene_indexing: false search_index_full_text_enabled: false @@ -257,12 +257,12 @@ hapi: # comma-separated list of fully qualified interceptor classes. # classes listed here will be fetched from the Spring context when combined with 'custom-bean-packages', - # or will be instantiated via reflection using an no-arg contructor; then registered with the server + # or will be instantiated via reflection using a no-arg constructor; then registered with the server #custom-interceptor-classes: # comma-separated list of fully qualified provider classes. # classes listed here will be fetched from the Spring context when combined with 'custom-bean-packages', - # or will be instantiated via reflection using an no-arg contructor; then registered with the server + # or will be instantiated via reflection using a no-arg constructor; then registered with the server #custom-provider-classes: # Threadpool size for BATCH'ed GETs in a bundle. diff --git a/src/main/webapp/WEB-INF/templates/about.html b/src/main/webapp/WEB-INF/templates/about.html index 4859418..ef5569f 100644 --- a/src/main/webapp/WEB-INF/templates/about.html +++ b/src/main/webapp/WEB-INF/templates/about.html @@ -47,7 +47,7 @@

This UI can be customized! You might want to put rules on who can use this server here, or - notices about privacy, or whatever else you want.. + notices about privacy, or whatever else you want.

@@ -63,7 +63,7 @@