From afaec85653197db5516f8495eff71a46314e24cf Mon Sep 17 00:00:00 2001 From: Jens Kristian Villadsen Date: Fri, 9 Jun 2023 11:39:54 +0200 Subject: [PATCH 01/18] Addressing https://github.com/hapifhir/hapi-fhir-jpaserver-starter/issues/486 and https://github.com/hapifhir/hapi-fhir-jpaserver-starter/issues/485 --- .../uhn/fhir/jpa/starter/AppProperties.java | 13 +++++++- .../starter/ExtraStaticFilesConfigurer.java | 31 +++++++++++++------ src/main/resources/application.yaml | 3 +- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java b/src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java index b48d4e1..ecd880e 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java @@ -76,6 +76,8 @@ public class AppProperties { private String staticLocation = null; + private String staticLocationPrefix = "/static"; + private Boolean lastn_enabled = false; private boolean store_resource_in_lucene_index_enabled = false; private NormalizedQuantitySearchLevel normalized_quantity_search_level = NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED; @@ -89,7 +91,16 @@ public class AppProperties { private final List custom_interceptor_classes = new ArrayList<>(); - public List getCustomInterceptorClasses() { + public String getStaticLocationPrefix() { + return staticLocationPrefix; + } + + public void setStaticLocationPrefix(String staticLocationPrefix) { + this.staticLocationPrefix = staticLocationPrefix; + } + + + public List getCustomInterceptorClasses() { return custom_interceptor_classes; } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/ExtraStaticFilesConfigurer.java b/src/main/java/ca/uhn/fhir/jpa/starter/ExtraStaticFilesConfigurer.java index d875ec6..a3b528c 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/ExtraStaticFilesConfigurer.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/ExtraStaticFilesConfigurer.java @@ -1,6 +1,5 @@ package ca.uhn.fhir.jpa.starter; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; @@ -14,25 +13,37 @@ import java.net.URI; @ConditionalOnProperty(prefix = "hapi.fhir", name = "staticLocation") public class ExtraStaticFilesConfigurer implements WebMvcConfigurer { - public static final String ROOT_CONTEXT_PATH = "/static"; - @Autowired - AppProperties appProperties; + private String staticLocation; + private String rootContextPath; - @Override + public ExtraStaticFilesConfigurer(AppProperties appProperties) { + + rootContextPath = appProperties.getStaticLocationPrefix(); + if(rootContextPath.endsWith("/")) + rootContextPath = rootContextPath.substring(0, rootContextPath.lastIndexOf('/')); + + staticLocation = appProperties.getStaticLocation(); + if(staticLocation.endsWith("/")) + staticLocation = staticLocation.substring(0, staticLocation.lastIndexOf('/')); + + } + + + @Override public void addResourceHandlers(ResourceHandlerRegistry theRegistry) { - theRegistry.addResourceHandler(ROOT_CONTEXT_PATH + "/**").addResourceLocations(appProperties.getStaticLocation()); + theRegistry.addResourceHandler(rootContextPath + "/**").addResourceLocations(staticLocation); } @Override public void addViewControllers(ViewControllerRegistry registry) { - String path = URI.create(appProperties.getStaticLocation()).getPath(); + String path = URI.create(staticLocation).getPath(); String lastSegment = path.substring(path.lastIndexOf('/') + 1); - registry.addViewController(ROOT_CONTEXT_PATH).setViewName("redirect:" + ROOT_CONTEXT_PATH + "/" + lastSegment + "/index.html"); + registry.addViewController(rootContextPath).setViewName("redirect:" + rootContextPath + "/" + lastSegment + "/index.html"); - registry.addViewController(ROOT_CONTEXT_PATH + "/*").setViewName("redirect:" + ROOT_CONTEXT_PATH + "/" + lastSegment + "/index.html"); + registry.addViewController(rootContextPath + "/*").setViewName("redirect:" + rootContextPath + "/" + lastSegment + "/index.html"); - registry.addViewController(ROOT_CONTEXT_PATH + "/" + lastSegment + "/").setViewName("redirect:" + ROOT_CONTEXT_PATH + "/" + lastSegment + "/index.html"); + registry.addViewController(rootContextPath + "/" + lastSegment + "/").setViewName("redirect:" + rootContextPath + "/" + lastSegment + "/index.html"); registry.setOrder(Ordered.HIGHEST_PRECEDENCE); } diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 13d85fd..c90f37e 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -64,7 +64,8 @@ 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 host content like HTML, css, etc. under the url pattern of /static/** + ### enables the server to host content like HTML, css, etc. under the url pattern of eg. /static/** + # staticLocationPrefix: /static ### the deepest folder level will be used. E.g. - if you put file:/foo/bar/bazz as value then the files are resolved under /static/bazz/** #staticLocation: file:/foo/bar/bazz ### enable to set the Server URL From 776afdee5606c19458bebd47baf27bd471055842 Mon Sep 17 00:00:00 2001 From: Jens Kristian Villadsen Date: Sun, 25 Jun 2023 23:55:48 +0200 Subject: [PATCH 02/18] no message --- .../jpa/starter/common/FhirTesterConfig.java | 2 ++ .../common/FhirTesterConfigCondition.java | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 src/main/java/ca/uhn/fhir/jpa/starter/common/FhirTesterConfigCondition.java diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirTesterConfig.java b/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirTesterConfig.java index cb28659..863e269 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirTesterConfig.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirTesterConfig.java @@ -4,6 +4,7 @@ import ca.uhn.fhir.jpa.starter.AppProperties; import ca.uhn.fhir.to.FhirTesterMvcConfig; import ca.uhn.fhir.to.TesterConfig; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -18,6 +19,7 @@ import org.springframework.context.annotation.Import; */ @Configuration @Import(FhirTesterMvcConfig.class) +@Conditional(FhirTesterConfigCondition.class) public class FhirTesterConfig { /** diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirTesterConfigCondition.java b/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirTesterConfigCondition.java new file mode 100644 index 0000000..f5670d9 --- /dev/null +++ b/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirTesterConfigCondition.java @@ -0,0 +1,16 @@ +package ca.uhn.fhir.jpa.starter.common; + +import ca.uhn.fhir.jpa.starter.util.EnvironmentHelper; +import org.springframework.context.annotation.Condition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.type.AnnotatedTypeMetadata; + +public class FhirTesterConfigCondition implements Condition { + @Override + public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) { + + var properties = EnvironmentHelper.getPropertiesStartingWith((ConfigurableEnvironment) conditionContext.getEnvironment(), "hapi.fhir.tester"); + return !properties.isEmpty(); + } +} From fdcd021e6614bd995dc8a70e31bd9edc1d4857e9 Mon Sep 17 00:00:00 2001 From: chgl Date: Sun, 25 Jun 2023 23:59:09 +0200 Subject: [PATCH 03/18] Updated helm chart and dockerfile dependencies (#540) * Updated Helm chart to use hapi fhir image v6.6.0 * Updated maven base image due to openjdk deprecation * Removed superfluous app/main.war in entrypoint * Update curlimages/curl to 8.1.2 --- .github/ct/config.yaml | 2 -- .github/workflows/chart-release.yaml | 13 +++++----- .github/workflows/chart-test.yaml | 26 ++++++++++--------- Dockerfile | 6 ++--- charts/hapi-fhir-jpaserver/Chart.lock | 8 +++--- charts/hapi-fhir-jpaserver/Chart.yaml | 14 +++++----- charts/hapi-fhir-jpaserver/README.md | 13 ++++++---- charts/hapi-fhir-jpaserver/README.md.gotmpl | 5 ++-- .../templates/deployment.yaml | 2 +- .../templates/tests/test-endpoints.yaml | 6 ++--- charts/hapi-fhir-jpaserver/values.yaml | 2 +- 11 files changed, 51 insertions(+), 46 deletions(-) diff --git a/.github/ct/config.yaml b/.github/ct/config.yaml index 484e994..9d1ae82 100644 --- a/.github/ct/config.yaml +++ b/.github/ct/config.yaml @@ -11,6 +11,4 @@ helm-extra-args: --timeout 300s upgrade: true skip-missing-values: true release-label: release -chart-repos: - - bitnami=https://charts.bitnami.com/bitnami release-name-template: "helm-v{{ .Version }}" diff --git a/.github/workflows/chart-release.yaml b/.github/workflows/chart-release.yaml index ae2045c..38c4fd2 100644 --- a/.github/workflows/chart-release.yaml +++ b/.github/workflows/chart-release.yaml @@ -9,10 +9,14 @@ on: jobs: release: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: + - name: Add workspace as safe directory + run: | + git config --global --add safe.directory /__w/hapi-fhir-jpaserver-starter/hapi-fhir-jpaserver-starter + - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 with: fetch-depth: 0 @@ -21,14 +25,11 @@ jobs: git config user.name "$GITHUB_ACTOR" git config user.email "$GITHUB_ACTOR@users.noreply.github.com" - - name: Add bitnami repo - run: helm repo add bitnami https://charts.bitnami.com/bitnami - - name: Update dependencies run: find charts/ ! -path charts/ -maxdepth 1 -type d -exec helm dependency update {} \; - name: Run chart-releaser - uses: helm/chart-releaser-action@v1.2.0 + uses: helm/chart-releaser-action@be16258da8010256c6e82849661221415f031968 # v1.5.0 with: config: .github/ct/config.yaml env: diff --git a/.github/workflows/chart-test.yaml b/.github/workflows/chart-test.yaml index f4357fb..30d2932 100644 --- a/.github/workflows/chart-test.yaml +++ b/.github/workflows/chart-test.yaml @@ -9,8 +9,8 @@ on: jobs: lint: - runs-on: ubuntu-20.04 - container: quay.io/helmpack/chart-testing:v3.4.0 + runs-on: ubuntu-22.04 + container: quay.io/helmpack/chart-testing:v3.8.0@sha256:f058c660a28d99a9394ae081d98921efe068079531f247c86b8054e3c9d407aa steps: - name: Install helm-docs working-directory: /tmp @@ -22,11 +22,14 @@ jobs: chmod +x /usr/local/bin/helm-docs && \ helm-docs --version + - name: Add workspace as safe directory + run: | + git config --global --add safe.directory /__w/hapi-fhir-jpaserver-starter/hapi-fhir-jpaserver-starter + - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 with: fetch-depth: 0 - - name: Check if documentation is up-to-date run: helm-docs && git diff --exit-code HEAD @@ -34,20 +37,20 @@ jobs: run: ct lint --config .github/ct/config.yaml test: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 strategy: matrix: - k8s-version: [1.22.9, 1.23.6, 1.24.1] + k8s-version: [1.25.9, 1.26.4, 1.27.2] needs: - lint steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 with: fetch-depth: 0 - name: Set up chart-testing - uses: helm/chart-testing-action@v2.2.1 + uses: helm/chart-testing-action@e8788873172cb653a90ca2e819d79d65a66d4e76 # v2.4.0 - name: Run chart-testing (list-changed) id: list-changed @@ -58,13 +61,12 @@ jobs: fi - name: Create k8s Kind Cluster - uses: helm/kind-action@v1.2.0 - if: steps.list-changed.outputs.changed == 'true' + uses: helm/kind-action@fa81e57adff234b2908110485695db0f181f3c67 # v1.7.0 + if: ${{ steps.list-changed.outputs.changed == 'true' }} with: - version: v0.14.0 cluster_name: kind-cluster-k8s-${{ matrix.k8s-version }} node_image: kindest/node:v${{ matrix.k8s-version }} - name: Run chart-testing (install) run: ct install --config .github/ct/config.yaml - if: steps.list-changed.outputs.changed == 'true' + if: ${{ steps.list-changed.outputs.changed == 'true' }} diff --git a/Dockerfile b/Dockerfile index 263fe9c..7c44d37 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ -FROM maven:3.8-openjdk-17-slim as build-hapi +FROM docker.io/library/maven:3.9.2-eclipse-temurin-17 as build-hapi WORKDIR /tmp/hapi-fhir-jpaserver-starter -ARG OPENTELEMETRY_JAVA_AGENT_VERSION=1.17.0 +ARG OPENTELEMETRY_JAVA_AGENT_VERSION=1.26.0 RUN curl -LSsO https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v${OPENTELEMETRY_JAVA_AGENT_VERSION}/opentelemetry-javaagent.jar COPY pom.xml . @@ -46,4 +46,4 @@ WORKDIR /app COPY --chown=nonroot:nonroot --from=build-distroless /app /app COPY --chown=nonroot:nonroot --from=build-hapi /tmp/hapi-fhir-jpaserver-starter/opentelemetry-javaagent.jar /app -ENTRYPOINT ["java", "--class-path", "/app/main.war", "-Dloader.path=main.war!/WEB-INF/classes/,main.war!/WEB-INF/,/app/extra-classes", "org.springframework.boot.loader.PropertiesLauncher", "app/main.war"] +ENTRYPOINT ["java", "--class-path", "/app/main.war", "-Dloader.path=main.war!/WEB-INF/classes/,main.war!/WEB-INF/,/app/extra-classes", "org.springframework.boot.loader.PropertiesLauncher"] diff --git a/charts/hapi-fhir-jpaserver/Chart.lock b/charts/hapi-fhir-jpaserver/Chart.lock index 5c8ec4a..98ba848 100644 --- a/charts/hapi-fhir-jpaserver/Chart.lock +++ b/charts/hapi-fhir-jpaserver/Chart.lock @@ -1,6 +1,6 @@ dependencies: - name: postgresql - repository: https://charts.bitnami.com/bitnami - version: 12.1.2 -digest: sha256:525689611a29f90b0bc8cd674df5d97024c99eda8104216390f6747904fd0208 -generated: "2022-11-21T22:55:45.1699395+01:00" + repository: oci://registry-1.docker.io/bitnamicharts + version: 12.5.6 +digest: sha256:4d21dbc02bbdb55b957b0093e37376853727de82396abfadfaf1d738bd51b8e6 +generated: "2023-06-03T20:58:45.922102213+02:00" diff --git a/charts/hapi-fhir-jpaserver/Chart.yaml b/charts/hapi-fhir-jpaserver/Chart.yaml index 9158007..9fcd564 100644 --- a/charts/hapi-fhir-jpaserver/Chart.yaml +++ b/charts/hapi-fhir-jpaserver/Chart.yaml @@ -7,17 +7,19 @@ sources: - https://github.com/hapifhir/hapi-fhir-jpaserver-starter dependencies: - name: postgresql - version: 12.1.2 - repository: https://charts.bitnami.com/bitnami + version: 12.5.6 + repository: oci://registry-1.docker.io/bitnamicharts condition: postgresql.enabled -appVersion: 6.2.2 -version: 0.11.1 +appVersion: 6.6.0 +version: 0.12.0 annotations: artifacthub.io/license: Apache-2.0 artifacthub.io/changes: | # When using the list of objects option the valid supported kinds are # added, changed, deprecated, removed, fixed, and security. - kind: changed - description: updated HAPI FHIR JPA Server app image version to v6.2.2 + description: updated HAPI FHIR JPA Server app image version to v6.6.0 - kind: changed - description: updated curl used by helm tests to version to v7.87.0 + description: updated curl used by helm tests to version to v8.1.1 + - kind: changed + description: updated postgresql sub-chart to v12.5.6 diff --git a/charts/hapi-fhir-jpaserver/README.md b/charts/hapi-fhir-jpaserver/README.md index 8b4b461..179f68e 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.11.1](https://img.shields.io/badge/Version-0.11.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 6.2.2](https://img.shields.io/badge/AppVersion-6.2.2-informational?style=flat-square) +![Version: 0.12.0](https://img.shields.io/badge/Version-0.12.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 6.6.0](https://img.shields.io/badge/AppVersion-6.6.0-informational?style=flat-square) This helm chart will help you install the HAPI FHIR JPA Server in a Kubernetes environment. @@ -8,11 +8,14 @@ This helm chart will help you install the HAPI FHIR JPA Server in a Kubernetes e ```sh helm repo add hapifhir https://hapifhir.github.io/hapi-fhir-jpaserver-starter/ -helm install --render-subchart-notes hapi-fhir-jpaserver hapifhir/hapi-fhir-jpaserver +helm install hapi-fhir-jpaserver hapifhir/hapi-fhir-jpaserver ``` -> ⚠ By default, the included [PostgreSQL Helm chart](https://github.com/bitnami/charts/tree/master/bitnami/postgresql#upgrading) -> auto-generates a random password for the database which may cause problems when upgrading the chart (see [here for details](https://github.com/bitnami/charts/tree/master/bitnami/postgresql#upgrading)). +## Requirements + +| Repository | Name | Version | +|------------|------|---------| +| oci://registry-1.docker.io/bitnamicharts | postgresql | 12.5.6 | ## Values @@ -32,7 +35,7 @@ helm install --render-subchart-notes hapi-fhir-jpaserver hapifhir/hapi-fhir-jpas | image.pullPolicy | string | `"IfNotPresent"` | image pullPolicy to use | | image.registry | string | `"docker.io"` | registry where the HAPI FHIR server image is hosted | | image.repository | string | `"hapiproject/hapi"` | the path inside the repository | -| image.tag | string | `"v6.2.2@sha256:9c4e8af94d81ac0049dbb589e4cd855bf78c9c13be6f6844e814c63d63545b44"` | the image tag. As of v5.7.0, this is the `distroless` flavor by default, add `-tomcat` to use the Tomcat-based image. | +| image.tag | string | `"v6.6.0@sha256:c00367865ae5dad4e171cbb68bfc1c39818854079d1565bee4c86a45e78335d0"` | the image tag. As of v5.7.0, this is the `distroless` flavor by default, add `-tomcat` to use the Tomcat-based image. | | imagePullSecrets | list | `[]` | image pull secrets to use when pulling the image | | ingress.annotations | object | `{}` | provide any additional annotations which may be required. Evaluated as a template. | | ingress.enabled | bool | `false` | whether to create an Ingress to expose the FHIR server HTTP endpoint | diff --git a/charts/hapi-fhir-jpaserver/README.md.gotmpl b/charts/hapi-fhir-jpaserver/README.md.gotmpl index bfea032..bfe5146 100644 --- a/charts/hapi-fhir-jpaserver/README.md.gotmpl +++ b/charts/hapi-fhir-jpaserver/README.md.gotmpl @@ -8,11 +8,10 @@ This helm chart will help you install the HAPI FHIR JPA Server in a Kubernetes e ```sh helm repo add hapifhir https://hapifhir.github.io/hapi-fhir-jpaserver-starter/ -helm install --render-subchart-notes hapi-fhir-jpaserver hapifhir/hapi-fhir-jpaserver +helm install hapi-fhir-jpaserver hapifhir/hapi-fhir-jpaserver ``` -> ⚠ By default, the included [PostgreSQL Helm chart](https://github.com/bitnami/charts/tree/master/bitnami/postgresql#upgrading) -> auto-generates a random password for the database which may cause problems when upgrading the chart (see [here for details](https://github.com/bitnami/charts/tree/master/bitnami/postgresql#upgrading)). +{{ template "chart.requirementsSection" . }} {{ template "chart.valuesSection" . }} diff --git a/charts/hapi-fhir-jpaserver/templates/deployment.yaml b/charts/hapi-fhir-jpaserver/templates/deployment.yaml index 8f3c65e..227ac4f 100644 --- a/charts/hapi-fhir-jpaserver/templates/deployment.yaml +++ b/charts/hapi-fhir-jpaserver/templates/deployment.yaml @@ -30,7 +30,7 @@ spec: {{- toYaml .Values.podSecurityContext | nindent 8 }} initContainers: - name: wait-for-db-to-be-ready - image: docker.io/bitnami/postgresql:15.1.0-debian-11-r0@sha256:27915588d5203a10a1c23624d9c81644437f33b7c224e25f79bcd9bd09bbb8e2 + image: docker.io/bitnami/postgresql:15.3.0-debian-11-r7@sha256:cc301eef743685f4f69d1d719853988e8a9650c90fd9521f4742ce400b3fdf6a imagePullPolicy: IfNotPresent {{- with .Values.restrictedContainerSecurityContext }} securityContext: diff --git a/charts/hapi-fhir-jpaserver/templates/tests/test-endpoints.yaml b/charts/hapi-fhir-jpaserver/templates/tests/test-endpoints.yaml index 034efb1..7171150 100644 --- a/charts/hapi-fhir-jpaserver/templates/tests/test-endpoints.yaml +++ b/charts/hapi-fhir-jpaserver/templates/tests/test-endpoints.yaml @@ -11,7 +11,7 @@ spec: restartPolicy: Never containers: - name: test-metadata-endpoint - image: docker.io/curlimages/curl:7.87.0@sha256:f7f265d5c64eb4463a43a99b6bf773f9e61a50aaa7cefaf564f43e42549a01dd + image: docker.io/curlimages/curl:8.1.2@sha256:ef501f5efa67be41da985b441bd63130ef39d4d6a4f9c035d737884357438b6c command: ["curl", "--fail-with-body"] args: ["http://{{ include "hapi-fhir-jpaserver.fullname" . }}:{{ .Values.service.port }}/fhir/metadata?_summary=true"] {{- with .Values.restrictedContainerSecurityContext }} @@ -32,7 +32,7 @@ spec: exec: command: ["true"] - name: test-patient-endpoint - image: docker.io/curlimages/curl:7.87.0@sha256:f7f265d5c64eb4463a43a99b6bf773f9e61a50aaa7cefaf564f43e42549a01dd + image: docker.io/curlimages/curl:8.1.2@sha256:ef501f5efa67be41da985b441bd63130ef39d4d6a4f9c035d737884357438b6c command: ["curl", "--fail-with-body"] args: ["http://{{ include "hapi-fhir-jpaserver.fullname" . }}:{{ .Values.service.port }}/fhir/Patient?_count=1&_summary=true"] {{- with .Values.restrictedContainerSecurityContext }} @@ -53,7 +53,7 @@ spec: exec: command: ["true"] - name: test-metrics-endpoint - image: docker.io/curlimages/curl:7.87.0@sha256:f7f265d5c64eb4463a43a99b6bf773f9e61a50aaa7cefaf564f43e42549a01dd + image: docker.io/curlimages/curl:8.1.2@sha256:ef501f5efa67be41da985b441bd63130ef39d4d6a4f9c035d737884357438b6c command: ["curl", "--fail-with-body"] args: ["http://{{ include "hapi-fhir-jpaserver.fullname" . }}:{{ .Values.metrics.service.port }}/actuator/prometheus"] {{- with .Values.restrictedContainerSecurityContext }} diff --git a/charts/hapi-fhir-jpaserver/values.yaml b/charts/hapi-fhir-jpaserver/values.yaml index be02b18..3349e1d 100644 --- a/charts/hapi-fhir-jpaserver/values.yaml +++ b/charts/hapi-fhir-jpaserver/values.yaml @@ -7,7 +7,7 @@ image: # -- the path inside the repository repository: hapiproject/hapi # -- the image tag. As of v5.7.0, this is the `distroless` flavor by default, add `-tomcat` to use the Tomcat-based image. - tag: "v6.2.2@sha256:9c4e8af94d81ac0049dbb589e4cd855bf78c9c13be6f6844e814c63d63545b44" + tag: "v6.6.0@sha256:c00367865ae5dad4e171cbb68bfc1c39818854079d1565bee4c86a45e78335d0" # -- image pullPolicy to use pullPolicy: IfNotPresent From 484aa9deb5c184ef47569b8bb1d2c523b2a969ea Mon Sep 17 00:00:00 2001 From: winne42 Date: Tue, 11 Jul 2023 23:53:18 +0200 Subject: [PATCH 04/18] Boyscouting (#558) * Boyscouting: Docker conventions * Boyscouting: JUnit 5 conventions ("It is generally recommended to omit the public modifier for test classes, test methods, and lifecycle methods unless there is a technical reason for doing so)" * Boyscouting: typo in RepositoryValidationInterceptorFactoryDstu3 * Boyscouting: use List.of instead of Guava; use StandardCharsets instead of Guava; remove unused imports --------- Co-authored-by: Gerlach, Winfried --- Dockerfile | 6 +++--- src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java | 3 +-- .../fhir/jpa/starter/common/FhirServerConfigCommon.java | 4 +--- .../ca/uhn/fhir/jpa/starter/common/StarterJpaConfig.java | 6 +----- .../RepositoryValidationInterceptorFactoryDstu3.java | 4 ++-- .../ca/uhn/fhir/jpa/starter/ips/StarterIpsConfig.java | 6 +++--- src/main/java/ca/uhn/fhir/jpa/starter/mdm/MdmConfig.java | 4 ++-- .../ca/uhn/fhir/jpa/starter/util/EnvironmentHelper.java | 1 - src/test/java/ca/uhn/fhir/jpa/starter/CustomBeanTest.java | 2 +- .../ca/uhn/fhir/jpa/starter/CustomInterceptorTest.java | 2 +- .../ca/uhn/fhir/jpa/starter/ExampleServerDstu2IT.java | 2 +- .../ca/uhn/fhir/jpa/starter/ExampleServerDstu3IT.java | 8 ++++---- .../java/ca/uhn/fhir/jpa/starter/ExampleServerR4BIT.java | 2 +- .../java/ca/uhn/fhir/jpa/starter/ExampleServerR4IT.java | 2 +- .../java/ca/uhn/fhir/jpa/starter/ExampleServerR5IT.java | 8 ++++---- .../ca/uhn/fhir/jpa/starter/MultitenantServerR4IT.java | 6 +++--- .../ca/uhn/fhir/jpa/starter/SocketImplementation.java | 2 +- 17 files changed, 30 insertions(+), 38 deletions(-) diff --git a/Dockerfile b/Dockerfile index 7c44d37..8e6c8b0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM docker.io/library/maven:3.9.2-eclipse-temurin-17 as build-hapi +FROM docker.io/library/maven:3.9.2-eclipse-temurin-17 AS build-hapi WORKDIR /tmp/hapi-fhir-jpaserver-starter ARG OPENTELEMETRY_JAVA_AGENT_VERSION=1.26.0 @@ -18,7 +18,7 @@ RUN mkdir /app && cp /tmp/hapi-fhir-jpaserver-starter/target/ROOT.war /app/main. ########### bitnami tomcat version is suitable for debugging and comes with a shell ########### it can be built using eg. `docker build --target tomcat .` -FROM bitnami/tomcat:9.0 as tomcat +FROM bitnami/tomcat:9.0 AS tomcat RUN rm -rf /opt/bitnami/tomcat/webapps/ROOT && \ mkdir -p /opt/bitnami/hapi/data/hapi/lucenefiles && \ @@ -36,7 +36,7 @@ COPY --from=build-hapi --chown=1001:1001 /tmp/hapi-fhir-jpaserver-starter/opente ENV ALLOW_EMPTY_PASSWORD=yes ########### distroless brings focus on security and runs on plain spring boot - this is the default image -FROM gcr.io/distroless/java17-debian11:nonroot as default +FROM gcr.io/distroless/java17-debian11:nonroot AS default # 65532 is the nonroot user's uid # used here instead of the name to allow Kubernetes to easily detect that the container # is running as a non-root (uid != 0) user. diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java b/src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java index b48d4e1..50e501c 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java @@ -5,7 +5,6 @@ import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.jpa.api.config.JpaStorageSettings.ClientIdStrategyEnum; import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel; import ca.uhn.fhir.rest.api.EncodingEnum; -import com.google.common.collect.ImmutableList; import org.hl7.fhir.r4.model.Bundle; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -577,7 +576,7 @@ public class AppProperties { public static class Cors { private Boolean allow_Credentials = true; - private List allowed_origin = ImmutableList.of("*"); + private List allowed_origin = List.of("*"); public List getAllowed_origin() { return allowed_origin; 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 9751ba7..12d7a8a 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 @@ -9,7 +9,6 @@ import ca.uhn.fhir.jpa.model.config.PartitionSettings.CrossPartitionReferenceMod import ca.uhn.fhir.jpa.model.entity.StorageSettings; import ca.uhn.fhir.jpa.starter.AppProperties; import ca.uhn.fhir.jpa.starter.util.JpaHibernatePropertiesProvider; -import ca.uhn.fhir.jpa.subscription.channel.subscription.SubscriptionDeliveryHandlerFactory; import ca.uhn.fhir.jpa.subscription.match.deliver.email.EmailSenderImpl; import ca.uhn.fhir.jpa.subscription.match.deliver.email.IEmailSender; import ca.uhn.fhir.rest.server.mail.IMailSvc; @@ -27,7 +26,6 @@ import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.transaction.annotation.EnableTransactionManagement; import java.util.HashSet; -import java.util.Optional; import java.util.stream.Collectors; /** @@ -84,7 +82,7 @@ public class FhirServerConfigCommon { public JpaStorageSettings jpaStorageSettings(AppProperties appProperties) { JpaStorageSettings jpaStorageSettings = new JpaStorageSettings(); - jpaStorageSettings.setIndexMissingFields(appProperties.getEnable_index_missing_fields() ? JpaStorageSettings.IndexEnabledEnum.ENABLED : JpaStorageSettings.IndexEnabledEnum.DISABLED); + jpaStorageSettings.setIndexMissingFields(appProperties.getEnable_index_missing_fields() ? StorageSettings.IndexEnabledEnum.ENABLED : StorageSettings.IndexEnabledEnum.DISABLED); jpaStorageSettings.setAutoCreatePlaceholderReferenceTargets(appProperties.getAuto_create_placeholder_reference_targets()); jpaStorageSettings.setEnforceReferentialIntegrityOnWrite(appProperties.getEnforce_referential_integrity_on_write()); jpaStorageSettings.setEnforceReferentialIntegrityOnDelete(appProperties.getEnforce_referential_integrity_on_delete()); 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 c095e27..77af694 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 @@ -24,7 +24,6 @@ import ca.uhn.fhir.jpa.config.util.ResourceCountCacheUtil; import ca.uhn.fhir.jpa.config.util.ValidationSupportConfigUtil; import ca.uhn.fhir.jpa.dao.FulltextSearchSvcImpl; import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc; -import ca.uhn.fhir.jpa.dao.mdm.MdmLinkDaoJpaImpl; import ca.uhn.fhir.jpa.dao.search.HSearchSortHelperImpl; import ca.uhn.fhir.jpa.dao.search.IHSearchSortHelper; import ca.uhn.fhir.jpa.delete.ThreadSafeResourceDeleterSvc; @@ -44,12 +43,10 @@ import ca.uhn.fhir.jpa.starter.AppProperties; import ca.uhn.fhir.jpa.starter.annotations.OnCorsPresent; import ca.uhn.fhir.jpa.starter.annotations.OnImplementationGuidesPresent; import ca.uhn.fhir.jpa.starter.common.validation.IRepositoryValidationInterceptorFactory; -import ca.uhn.fhir.jpa.starter.ips.IpsConfigCondition; import ca.uhn.fhir.jpa.starter.util.EnvironmentHelper; import ca.uhn.fhir.jpa.subscription.util.SubscriptionDebugLogInterceptor; import ca.uhn.fhir.jpa.util.ResourceCountCache; import ca.uhn.fhir.jpa.validation.JpaValidationSupportChain; -import ca.uhn.fhir.mdm.dao.IMdmLinkDao; import ca.uhn.fhir.mdm.provider.MdmProviderLoader; import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator; import ca.uhn.fhir.narrative2.NullNarrativeGenerator; @@ -64,7 +61,6 @@ import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.validation.IValidatorModule; import ca.uhn.fhir.validation.ResultSeverityEnum; import com.google.common.base.Strings; -import com.google.common.collect.ImmutableList; import org.hl7.fhir.common.hapi.validation.support.CachingValidationSupport; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.annotation.Autowired; @@ -205,7 +201,7 @@ public class StarterJpaConfig { packageInstallationSpec.setReloadExisting(appProperties.getReload_existing_implementationguides()); if (appProperties.getInstall_transitive_ig_dependencies()) { packageInstallationSpec.setFetchDependencies(true); - packageInstallationSpec.setDependencyExcludes(ImmutableList.of("hl7.fhir.r2.core", "hl7.fhir.r3.core", "hl7.fhir.r4.core", "hl7.fhir.r5.core")); + packageInstallationSpec.setDependencyExcludes(List.of("hl7.fhir.r2.core", "hl7.fhir.r3.core", "hl7.fhir.r4.core", "hl7.fhir.r5.core")); } packageInstallerSvc.install(packageInstallationSpec); } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryDstu3.java b/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryDstu3.java index f8874b3..edaade7 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryDstu3.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/common/validation/RepositoryValidationInterceptorFactoryDstu3.java @@ -47,12 +47,12 @@ public class RepositoryValidationInterceptorFactoryDstu3 implements IRepositoryV public RepositoryValidatingInterceptor buildUsingStoredStructureDefinitions() { IBundleProvider results = structureDefinitionResourceProvider.search(new SearchParameterMap().add(StructureDefinition.SP_KIND, new TokenParam("resource"))); - Map> structureDefintions = results.getResources(0, results.size()) + 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).requireAtLeastOneProfileOf(urls).and().requireValidationToDeclaredProfiles(); }); diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/ips/StarterIpsConfig.java b/src/main/java/ca/uhn/fhir/jpa/starter/ips/StarterIpsConfig.java index e777879..308a3aa 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/ips/StarterIpsConfig.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/ips/StarterIpsConfig.java @@ -15,18 +15,18 @@ import ca.uhn.fhir.jpa.ips.generator.IpsGeneratorSvcImpl; @Conditional(IpsConfigCondition.class) public class StarterIpsConfig { @Bean - IIpsGenerationStrategy IpsGenerationStrategy() + IIpsGenerationStrategy ipsGenerationStrategy() { return new DefaultIpsGenerationStrategy(); } @Bean - public IpsOperationProvider IpsOperationProvider(IIpsGeneratorSvc theIpsGeneratorSvc){ + public IpsOperationProvider ipsOperationProvider(IIpsGeneratorSvc theIpsGeneratorSvc){ return new IpsOperationProvider(theIpsGeneratorSvc); } @Bean - public IIpsGeneratorSvc IpsGeneratorSvcImpl(FhirContext theFhirContext, IIpsGenerationStrategy theGenerationStrategy, DaoRegistry theDaoRegistry) + public IIpsGeneratorSvc ipsGeneratorSvcImpl(FhirContext theFhirContext, IIpsGenerationStrategy theGenerationStrategy, DaoRegistry theDaoRegistry) { return new IpsGeneratorSvcImpl(theFhirContext, theGenerationStrategy, theDaoRegistry); } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/mdm/MdmConfig.java b/src/main/java/ca/uhn/fhir/jpa/starter/mdm/MdmConfig.java index 50dfe9e..7f0ee4c 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/mdm/MdmConfig.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/mdm/MdmConfig.java @@ -6,7 +6,6 @@ import ca.uhn.fhir.jpa.starter.AppProperties; import ca.uhn.fhir.mdm.api.IMdmSettings; import ca.uhn.fhir.mdm.rules.config.MdmRuleValidator; import ca.uhn.fhir.mdm.rules.config.MdmSettings; -import com.google.common.base.Charsets; import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; @@ -17,6 +16,7 @@ import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.Resource; import java.io.IOException; +import java.nio.charset.StandardCharsets; @Configuration @Conditional(MdmConfigCondition.class) @@ -27,7 +27,7 @@ public class MdmConfig { IMdmSettings mdmSettings(@Autowired MdmRuleValidator theMdmRuleValidator, AppProperties appProperties) throws IOException { DefaultResourceLoader resourceLoader = new DefaultResourceLoader(); Resource resource = resourceLoader.getResource("mdm-rules.json"); - String json = IOUtils.toString(resource.getInputStream(), Charsets.UTF_8); + String json = IOUtils.toString(resource.getInputStream(), StandardCharsets.UTF_8); return new MdmSettings(theMdmRuleValidator).setEnabled(appProperties.getMdm_enabled()).setScriptText(json); } } 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 41bb556..71d947a 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 @@ -17,7 +17,6 @@ import org.hibernate.search.mapper.orm.cfg.HibernateOrmMapperSettings; import org.hibernate.search.mapper.orm.schema.management.SchemaManagementStrategyName; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy; -import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy; import org.springframework.core.env.CompositePropertySource; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.EnumerablePropertySource; diff --git a/src/test/java/ca/uhn/fhir/jpa/starter/CustomBeanTest.java b/src/test/java/ca/uhn/fhir/jpa/starter/CustomBeanTest.java index 07e7f58..fe3fba4 100644 --- a/src/test/java/ca/uhn/fhir/jpa/starter/CustomBeanTest.java +++ b/src/test/java/ca/uhn/fhir/jpa/starter/CustomBeanTest.java @@ -11,7 +11,7 @@ import org.springframework.boot.test.context.SpringBootTest; // "hapi.fhir.enable_repository_validating_interceptor=true", "hapi.fhir.fhir_version=r4" }) -public class CustomBeanTest { +class CustomBeanTest { @Autowired some.custom.pkg1.CustomBean customBean1; diff --git a/src/test/java/ca/uhn/fhir/jpa/starter/CustomInterceptorTest.java b/src/test/java/ca/uhn/fhir/jpa/starter/CustomInterceptorTest.java index 367857b..248bfe3 100644 --- a/src/test/java/ca/uhn/fhir/jpa/starter/CustomInterceptorTest.java +++ b/src/test/java/ca/uhn/fhir/jpa/starter/CustomInterceptorTest.java @@ -21,7 +21,7 @@ import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum; "hapi.fhir.fhir_version=r4" }) -public class CustomInterceptorTest { +class CustomInterceptorTest { @LocalServerPort private int port; diff --git a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu2IT.java b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu2IT.java index 4369086..25776cc 100644 --- a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu2IT.java +++ b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu2IT.java @@ -21,7 +21,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; "hapi.fhir.fhir_version=dstu2", "spring.datasource.url=jdbc:h2:mem:dbr2", }) -public class ExampleServerDstu2IT { +class ExampleServerDstu2IT { private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExampleServerDstu2IT.class); private IGenericClient ourClient; diff --git a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu3IT.java b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu3IT.java index 850bdb3..0d20bab 100644 --- a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu3IT.java +++ b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerDstu3IT.java @@ -49,7 +49,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; }) -public class ExampleServerDstu3IT implements IServerSupport { +class ExampleServerDstu3IT implements IServerSupport { private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExampleServerDstu2IT.class); private IGenericClient ourClient; @@ -71,8 +71,8 @@ public class ExampleServerDstu3IT implements IServerSupport { ourClient.registerInterceptor(new LoggingInterceptor(true)); } - @Test - public void testCreateAndRead() { + @Test + void testCreateAndRead() { String methodName = "testCreateResourceConditional"; @@ -154,7 +154,7 @@ public class ExampleServerDstu3IT implements IServerSupport { } @Test - public void testWebsocketSubscription() throws Exception { + void testWebsocketSubscription() throws Exception { /* * Create subscription */ diff --git a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR4BIT.java b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR4BIT.java index 9f19fcb..f6942c6 100644 --- a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR4BIT.java +++ b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR4BIT.java @@ -52,7 +52,7 @@ class ExampleServerR4BIT { @Test - public void testBatchPutWithIdenticalTags() { + void testBatchPutWithIdenticalTags() { String batchPuts = "{\n" + "\t\"resourceType\": \"Bundle\",\n" + "\t\"id\": \"patients\",\n" + diff --git a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR4IT.java b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR4IT.java index 319ed1c..d08770a 100644 --- a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR4IT.java +++ b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR4IT.java @@ -87,7 +87,7 @@ class ExampleServerR4IT { } @Test - public void testBatchPutWithIdenticalTags() { + void testBatchPutWithIdenticalTags() { String batchPuts = "{\n" + "\t\"resourceType\": \"Bundle\",\n" + "\t\"id\": \"patients\",\n" + diff --git a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR5IT.java b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR5IT.java index 8ecfb73..349d883 100644 --- a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR5IT.java +++ b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR5IT.java @@ -45,15 +45,15 @@ public class ExampleServerR5IT { private IGenericClient ourClient; private FhirContext ourCtx; - public static final String SUBSCRIPTION_TOPIC_TEST_URL = "http://example.com/topic/test"; + public static final String SUBSCRIPTION_TOPIC_TEST_URL = "http://example.com/topic/test"; - @LocalServerPort + @LocalServerPort private int port; @Test - public void testCreateAndRead() { + void testCreateAndRead() { String methodName = "testCreateResourceConditional"; @@ -66,7 +66,7 @@ public class ExampleServerR5IT { } @Test - public void testWebsocketSubscription() throws Exception { + void testWebsocketSubscription() throws Exception { String endpoint = "ws://localhost:" + port + "/websocket"; /* * Create topic diff --git a/src/test/java/ca/uhn/fhir/jpa/starter/MultitenantServerR4IT.java b/src/test/java/ca/uhn/fhir/jpa/starter/MultitenantServerR4IT.java index 463a1c6..cf85478 100644 --- a/src/test/java/ca/uhn/fhir/jpa/starter/MultitenantServerR4IT.java +++ b/src/test/java/ca/uhn/fhir/jpa/starter/MultitenantServerR4IT.java @@ -26,7 +26,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; "hapi.fhir.partitioning.partitioning_include_in_search_hashes=false", }) -public class MultitenantServerR4IT { +class MultitenantServerR4IT { private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExampleServerDstu2IT.class); @@ -40,7 +40,7 @@ public class MultitenantServerR4IT { @Test - public void testCreateAndReadInTenantA() { + void testCreateAndReadInTenantA() { // Create tenant A @@ -66,7 +66,7 @@ public class MultitenantServerR4IT { } @Test - public void testCreateAndReadInTenantB() { + void testCreateAndReadInTenantB() { // Create tenant A diff --git a/src/test/java/ca/uhn/fhir/jpa/starter/SocketImplementation.java b/src/test/java/ca/uhn/fhir/jpa/starter/SocketImplementation.java index 7734a23..4a536f0 100644 --- a/src/test/java/ca/uhn/fhir/jpa/starter/SocketImplementation.java +++ b/src/test/java/ca/uhn/fhir/jpa/starter/SocketImplementation.java @@ -18,7 +18,7 @@ public class SocketImplementation { private final String myCriteria; protected String myError; protected boolean myGotBound; - private final List myMessages = new ArrayList(); + private final List myMessages = new ArrayList<>(); protected int myPingCount; protected String mySubsId; private Session session; From 9d8fc4d2e59d7af4166113325f3e663d77024a09 Mon Sep 17 00:00:00 2001 From: "Gerlach, Winfried" Date: Wed, 12 Jul 2023 17:53:58 +0200 Subject: [PATCH 05/18] #563 Add configuration for auto-versioning references --- .../java/ca/uhn/fhir/jpa/starter/AppProperties.java | 11 +++++++++-- .../jpa/starter/common/FhirServerConfigCommon.java | 7 ++++--- .../uhn/fhir/jpa/starter/common/FhirTesterConfig.java | 2 +- src/main/resources/application.yaml | 2 ++ 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java b/src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java index 50e501c..3ed7679 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java @@ -11,9 +11,11 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.Configuration; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Set; @ConfigurationProperties(prefix = "hapi.fhir") @Configuration @@ -32,6 +34,7 @@ public class AppProperties { private Boolean allow_multiple_delete = false; private Boolean allow_override_default_search_params = true; private Boolean auto_create_placeholder_reference_targets = false; + private final Set auto_version_reference_at_paths = new HashSet<>(); private Boolean dao_scheduling_enabled = true; private Boolean delete_expunge_enabled = false; private Boolean enable_index_missing_fields = false; @@ -84,7 +87,7 @@ public class AppProperties { private Integer bundle_batch_pool_size = 20; private Integer bundle_batch_pool_max_size = 100; - private final List local_base_urls = new ArrayList<>(); + private final Set local_base_urls = new HashSet<>(); private final List custom_interceptor_classes = new ArrayList<>(); @@ -306,6 +309,10 @@ public class AppProperties { this.auto_create_placeholder_reference_targets = auto_create_placeholder_reference_targets; } + public Set getAuto_version_reference_at_paths() { + return auto_version_reference_at_paths; + } + public Integer getDefault_page_size() { return default_page_size; } @@ -570,7 +577,7 @@ public class AppProperties { this.bundle_batch_pool_max_size = bundle_batch_pool_max_size; } - public List getLocal_base_urls() { + public Set getLocal_base_urls() { return local_base_urls; } 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 12d7a8a..6a93161 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 @@ -25,7 +25,6 @@ import org.springframework.context.annotation.Primary; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.transaction.annotation.EnableTransactionManagement; -import java.util.HashSet; import java.util.stream.Collectors; /** @@ -47,6 +46,7 @@ public class FhirServerConfigCommon { ourLog.info("Server configured to " + (appProperties.getExpunge_enabled() ? "enable" : "disable") + " expunges"); 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"); + ourLog.info("Server configured to auto-version references at paths {}", appProperties.getAuto_version_reference_at_paths()); if (appProperties.getSubscription().getEmail() != null) { AppProperties.Subscription.Email email = appProperties.getSubscription().getEmail(); @@ -84,6 +84,7 @@ public class FhirServerConfigCommon { jpaStorageSettings.setIndexMissingFields(appProperties.getEnable_index_missing_fields() ? StorageSettings.IndexEnabledEnum.ENABLED : StorageSettings.IndexEnabledEnum.DISABLED); jpaStorageSettings.setAutoCreatePlaceholderReferenceTargets(appProperties.getAuto_create_placeholder_reference_targets()); + jpaStorageSettings.setAutoVersionReferenceAtPaths(appProperties.getAuto_version_reference_at_paths()); jpaStorageSettings.setEnforceReferentialIntegrityOnWrite(appProperties.getEnforce_referential_integrity_on_write()); jpaStorageSettings.setEnforceReferentialIntegrityOnDelete(appProperties.getEnforce_referential_integrity_on_delete()); jpaStorageSettings.setAllowContainsSearches(appProperties.getAllow_contains_searches()); @@ -125,9 +126,9 @@ public class FhirServerConfigCommon { jpaStorageSettings.setFilterParameterEnabled(appProperties.getFilter_search_enabled()); jpaStorageSettings.setAdvancedHSearchIndexing(appProperties.getAdvanced_lucene_indexing()); - jpaStorageSettings.setTreatBaseUrlsAsLocal(new HashSet<>(appProperties.getLocal_base_urls())); + jpaStorageSettings.setTreatBaseUrlsAsLocal(appProperties.getLocal_base_urls()); - if (appProperties.getLastn_enabled()) { + if (appProperties.getLastn_enabled()) { jpaStorageSettings.setLastNEnabled(true); } diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirTesterConfig.java b/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirTesterConfig.java index cb28659..2bc9aa2 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirTesterConfig.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/common/FhirTesterConfig.java @@ -26,7 +26,7 @@ public class FhirTesterConfig { * server, as well as one public server. If you are creating a project to * deploy somewhere else, you might choose to only put your own server's * address here. - * + *

* Note the use of the ${serverBase} variable below. This will be replaced with * the base URL as reported by the server itself. Often for a simple Tomcat * (or other container) installation, this will end up being something diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 9b1e118..cd2dbb0 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -99,6 +99,8 @@ hapi: # allow_multiple_delete: true # allow_override_default_search_params: true # auto_create_placeholder_reference_targets: false + ### tells the server to automatically append the current version of the target to references at these paths + # auto_version_reference_at_paths: Device.patient, Device.location, Device.parent, DeviceMetric.parent, DeviceMetric.source, Observation.device, Observation.subject # cr_enabled: true # ips_enabled: false # default_encoding: JSON From 98165e848ff9cfba415d8d8098efdeaf7302664a Mon Sep 17 00:00:00 2001 From: "Gerlach, Winfried" Date: Thu, 13 Jul 2023 09:06:42 +0200 Subject: [PATCH 06/18] #563 fix indentation --- .../ca/uhn/fhir/jpa/starter/common/FhirServerConfigCommon.java | 2 +- src/main/resources/application.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 6a93161..f040ab7 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 @@ -84,7 +84,7 @@ public class FhirServerConfigCommon { jpaStorageSettings.setIndexMissingFields(appProperties.getEnable_index_missing_fields() ? StorageSettings.IndexEnabledEnum.ENABLED : StorageSettings.IndexEnabledEnum.DISABLED); jpaStorageSettings.setAutoCreatePlaceholderReferenceTargets(appProperties.getAuto_create_placeholder_reference_targets()); - jpaStorageSettings.setAutoVersionReferenceAtPaths(appProperties.getAuto_version_reference_at_paths()); + jpaStorageSettings.setAutoVersionReferenceAtPaths(appProperties.getAuto_version_reference_at_paths()); jpaStorageSettings.setEnforceReferentialIntegrityOnWrite(appProperties.getEnforce_referential_integrity_on_write()); jpaStorageSettings.setEnforceReferentialIntegrityOnDelete(appProperties.getEnforce_referential_integrity_on_delete()); jpaStorageSettings.setAllowContainsSearches(appProperties.getAllow_contains_searches()); diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index cd2dbb0..557654c 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -99,7 +99,7 @@ hapi: # allow_multiple_delete: true # allow_override_default_search_params: true # auto_create_placeholder_reference_targets: false - ### tells the server to automatically append the current version of the target to references at these paths + ### tells the server to automatically append the current version of the target resource to references at these paths # auto_version_reference_at_paths: Device.patient, Device.location, Device.parent, DeviceMetric.parent, DeviceMetric.source, Observation.device, Observation.subject # cr_enabled: true # ips_enabled: false From 8ef50832d3459d4eb35ecb4f116c580475acb59d Mon Sep 17 00:00:00 2001 From: chgl Date: Fri, 21 Jul 2023 16:26:10 +0200 Subject: [PATCH 07/18] Updated helm chart with additional config settings (#566) --- charts/hapi-fhir-jpaserver/Chart.yaml | 12 ++-- charts/hapi-fhir-jpaserver/README.md | 21 ++----- charts/hapi-fhir-jpaserver/README.md.gotmpl | 2 +- .../ci/extra-config-values.yaml | 17 ++++++ .../templates/application-config.yaml | 11 ++++ .../templates/deployment.yaml | 52 ++++++++--------- .../templates/tests/test-endpoints.yaml | 33 ++++------- charts/hapi-fhir-jpaserver/values.yaml | 58 ++++++++++++++++--- 8 files changed, 126 insertions(+), 80 deletions(-) create mode 100644 charts/hapi-fhir-jpaserver/ci/extra-config-values.yaml create mode 100644 charts/hapi-fhir-jpaserver/templates/application-config.yaml diff --git a/charts/hapi-fhir-jpaserver/Chart.yaml b/charts/hapi-fhir-jpaserver/Chart.yaml index 9fcd564..a81e108 100644 --- a/charts/hapi-fhir-jpaserver/Chart.yaml +++ b/charts/hapi-fhir-jpaserver/Chart.yaml @@ -11,15 +11,17 @@ dependencies: repository: oci://registry-1.docker.io/bitnamicharts condition: postgresql.enabled appVersion: 6.6.0 -version: 0.12.0 +version: 0.13.0 annotations: artifacthub.io/license: Apache-2.0 artifacthub.io/changes: | # When using the list of objects option the valid supported kinds are # added, changed, deprecated, removed, fixed, and security. + - kind: added + description: allow specifying application properties via yaml config + - kind: added + description: allow setting resource limits and requests for the Helm test pods - kind: changed - description: updated HAPI FHIR JPA Server app image version to v6.6.0 + description: updated curl used by helm tests to version to v8.2.0 - kind: changed - description: updated curl used by helm tests to version to v8.1.1 - - kind: changed - description: updated postgresql sub-chart to v12.5.6 + description: allow disabling the liveness-, readiness-, and startup-probes entirely diff --git a/charts/hapi-fhir-jpaserver/README.md b/charts/hapi-fhir-jpaserver/README.md index 179f68e..7d4d338 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.12.0](https://img.shields.io/badge/Version-0.12.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 6.6.0](https://img.shields.io/badge/AppVersion-6.6.0-informational?style=flat-square) +![Version: 0.13.0](https://img.shields.io/badge/Version-0.13.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 6.6.0](https://img.shields.io/badge/AppVersion-6.6.0-informational?style=flat-square) This helm chart will help you install the HAPI FHIR JPA Server in a Kubernetes environment. @@ -30,6 +30,7 @@ helm install hapi-fhir-jpaserver hapifhir/hapi-fhir-jpaserver | externalDatabase.password | string | `""` | database password | | externalDatabase.port | int | `5432` | database port number | | externalDatabase.user | string | `"fhir"` | username for the external database | +| extraConfig | string | `""` | additional Spring Boot application config. Mounted as a file and automatically loaded by the application. | | extraEnv | list | `[]` | extra environment variables to set on the server container | | fullnameOverride | string | `""` | override the chart fullname | | image.pullPolicy | string | `"IfNotPresent"` | image pullPolicy to use | @@ -43,11 +44,6 @@ helm install hapi-fhir-jpaserver hapifhir/hapi-fhir-jpaserver | ingress.hosts[0].pathType | string | `"ImplementationSpecific"` | | | ingress.hosts[0].paths[0] | string | `"/"` | | | ingress.tls | list | `[]` | ingress TLS config | -| livenessProbe.failureThreshold | int | `5` | | -| livenessProbe.initialDelaySeconds | int | `30` | | -| livenessProbe.periodSeconds | int | `20` | | -| livenessProbe.successThreshold | int | `1` | | -| livenessProbe.timeoutSeconds | int | `30` | | | metrics.service.port | int | `8081` | | | metrics.serviceMonitor.additionalLabels | object | `{}` | additional labels to apply to the ServiceMonitor object, e.g. `release: prometheus` | | metrics.serviceMonitor.enabled | bool | `false` | if enabled, creates a ServiceMonitor instance for Prometheus Operator-based monitoring | @@ -65,11 +61,6 @@ helm install hapi-fhir-jpaserver hapifhir/hapi-fhir-jpaserver | postgresql.primary.containerSecurityContext.capabilities.drop[0] | string | `"ALL"` | | | postgresql.primary.containerSecurityContext.runAsNonRoot | bool | `true` | | | postgresql.primary.containerSecurityContext.seccompProfile.type | string | `"RuntimeDefault"` | | -| readinessProbe.failureThreshold | int | `5` | | -| readinessProbe.initialDelaySeconds | int | `30` | | -| readinessProbe.periodSeconds | int | `20` | | -| readinessProbe.successThreshold | int | `1` | | -| readinessProbe.timeoutSeconds | int | `20` | | | replicaCount | int | `1` | number of replicas to deploy | | resources | object | `{}` | configure the FHIR server's resource requests and limits | | securityContext.allowPrivilegeEscalation | bool | `false` | | @@ -82,18 +73,14 @@ helm install hapi-fhir-jpaserver hapifhir/hapi-fhir-jpaserver | securityContext.seccompProfile.type | string | `"RuntimeDefault"` | | | service.port | int | `8080` | port where the server will be exposed at | | service.type | string | `"ClusterIP"` | service type | -| startupProbe.failureThreshold | int | `10` | | -| startupProbe.initialDelaySeconds | int | `30` | | -| startupProbe.periodSeconds | int | `30` | | -| startupProbe.successThreshold | int | `1` | | -| startupProbe.timeoutSeconds | int | `30` | | +| tests.resources | object | `{}` | configure the test pods resource requests and limits | | tolerations | list | `[]` | pod tolerations | | topologySpreadConstraints | list | `[]` | pod topology spread configuration see: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/#api | ## Development To update the Helm chart when a new version of the `hapiproject/hapi` image is released, [values.yaml](values.yaml) `image.tag` and the [Chart.yaml](Chart.yaml)'s -`version` and optionally the `appVersion` field on major releases need to be updated. Afterwards, re-generate the [README.md](README.md) +`version` and optionally the `appVersion` field need to be updated. Afterwards, re-generate the [README.md](README.md) by running: ```sh diff --git a/charts/hapi-fhir-jpaserver/README.md.gotmpl b/charts/hapi-fhir-jpaserver/README.md.gotmpl index bfe5146..4647395 100644 --- a/charts/hapi-fhir-jpaserver/README.md.gotmpl +++ b/charts/hapi-fhir-jpaserver/README.md.gotmpl @@ -18,7 +18,7 @@ helm install hapi-fhir-jpaserver hapifhir/hapi-fhir-jpaserver ## Development To update the Helm chart when a new version of the `hapiproject/hapi` image is released, [values.yaml](values.yaml) `image.tag` and the [Chart.yaml](Chart.yaml)'s -`version` and optionally the `appVersion` field on major releases need to be updated. Afterwards, re-generate the [README.md](README.md) +`version` and optionally the `appVersion` field need to be updated. Afterwards, re-generate the [README.md](README.md) by running: ```sh diff --git a/charts/hapi-fhir-jpaserver/ci/extra-config-values.yaml b/charts/hapi-fhir-jpaserver/ci/extra-config-values.yaml new file mode 100644 index 0000000..d2406ac --- /dev/null +++ b/charts/hapi-fhir-jpaserver/ci/extra-config-values.yaml @@ -0,0 +1,17 @@ +extraConfig: | + hapi: + fhir: + cr_enabled: true + tester: + home: + name: Hello HAPI FHIR + server_address: "http://fhir-server.127.0.0.1.nip.io/fhir" + refuse_to_fetch_third_party_urls: true + fhir_version: R4 + +ingress: + enabled: true + hosts: + - host: fhir-server.127.0.0.1.nip.io + pathType: ImplementationSpecific + paths: ["/"] diff --git a/charts/hapi-fhir-jpaserver/templates/application-config.yaml b/charts/hapi-fhir-jpaserver/templates/application-config.yaml new file mode 100644 index 0000000..e4df9ce --- /dev/null +++ b/charts/hapi-fhir-jpaserver/templates/application-config.yaml @@ -0,0 +1,11 @@ +{{- if .Values.extraConfig -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "hapi-fhir-jpaserver.fullname" . }}-application-config + labels: + {{- include "hapi-fhir-jpaserver.labels" . | nindent 4 }} +data: + application-extra.yaml: |- + {{ .Values.extraConfig | nindent 4 }} +{{- end }} diff --git a/charts/hapi-fhir-jpaserver/templates/deployment.yaml b/charts/hapi-fhir-jpaserver/templates/deployment.yaml index 227ac4f..c15609f 100644 --- a/charts/hapi-fhir-jpaserver/templates/deployment.yaml +++ b/charts/hapi-fhir-jpaserver/templates/deployment.yaml @@ -63,38 +63,17 @@ spec: - name: http-metrics containerPort: 8081 protocol: TCP - startupProbe: - httpGet: - path: /readyz - port: http {{- with .Values.startupProbe }} - initialDelaySeconds: {{ .initialDelaySeconds }} - periodSeconds: {{ .periodSeconds }} - timeoutSeconds: {{ .timeoutSeconds }} - successThreshold: {{ .successThreshold }} - failureThreshold: {{ .failureThreshold }} + startupProbe: + {{- toYaml . | nindent 12 }} {{- end }} - readinessProbe: - httpGet: - path: /readyz - port: http - {{- with .Values.readinessProbe }} - initialDelaySeconds: {{ .initialDelaySeconds }} - periodSeconds: {{ .periodSeconds }} - timeoutSeconds: {{ .timeoutSeconds }} - successThreshold: {{ .successThreshold }} - failureThreshold: {{ .failureThreshold }} - {{- end }} - livenessProbe: - httpGet: - path: /livez - port: http {{- with .Values.livenessProbe }} - initialDelaySeconds: {{ .initialDelaySeconds }} - periodSeconds: {{ .periodSeconds }} - timeoutSeconds: {{ .timeoutSeconds }} - successThreshold: {{ .successThreshold }} - failureThreshold: {{ .failureThreshold }} + livenessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 12 }} {{- end }} resources: {{- toYaml .Values.resources | nindent 12 }} @@ -118,6 +97,10 @@ spec: value: "true" - name: MANAGEMENT_SERVER_PORT value: "8081" + {{- if .Values.extraConfig }} + - name: SPRING_CONFIG_IMPORT + value: "/app/config/application-extra.yaml" + {{- end }} {{- if .Values.extraEnv }} {{ toYaml .Values.extraEnv | nindent 12 }} {{- end }} @@ -126,6 +109,12 @@ spec: name: tmp-volume - mountPath: /app/target name: lucenefiles-volume + {{- if .Values.extraConfig }} + - name: application-extra-config + mountPath: /app/config/application-extra.yaml + readOnly: true + subPath: application-extra.yaml + {{- end }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} @@ -147,3 +136,8 @@ spec: emptyDir: {} - name: lucenefiles-volume emptyDir: {} + {{- if .Values.extraConfig }} + - name: application-extra-config + configMap: + name: {{ include "hapi-fhir-jpaserver.fullname" . }}-application-config + {{- end }} diff --git a/charts/hapi-fhir-jpaserver/templates/tests/test-endpoints.yaml b/charts/hapi-fhir-jpaserver/templates/tests/test-endpoints.yaml index 7171150..bd81c4a 100644 --- a/charts/hapi-fhir-jpaserver/templates/tests/test-endpoints.yaml +++ b/charts/hapi-fhir-jpaserver/templates/tests/test-endpoints.yaml @@ -11,20 +11,17 @@ spec: restartPolicy: Never containers: - name: test-metadata-endpoint - image: docker.io/curlimages/curl:8.1.2@sha256:ef501f5efa67be41da985b441bd63130ef39d4d6a4f9c035d737884357438b6c + image: "{{ .Values.curl.image.registry }}/{{ .Values.curl.image.repository }}:{{ .Values.curl.image.tag }}" command: ["curl", "--fail-with-body"] args: ["http://{{ include "hapi-fhir-jpaserver.fullname" . }}:{{ .Values.service.port }}/fhir/metadata?_summary=true"] {{- with .Values.restrictedContainerSecurityContext }} securityContext: {{- toYaml . | nindent 8 }} {{- end }} + {{- with .Values.tests.resources }} resources: - limits: - cpu: 100m - memory: 128Mi - requests: - cpu: 100m - memory: 128Mi + {{- toYaml . | nindent 8 }} + {{- end }} livenessProbe: exec: command: ["true"] @@ -32,20 +29,17 @@ spec: exec: command: ["true"] - name: test-patient-endpoint - image: docker.io/curlimages/curl:8.1.2@sha256:ef501f5efa67be41da985b441bd63130ef39d4d6a4f9c035d737884357438b6c + image: "{{ .Values.curl.image.registry }}/{{ .Values.curl.image.repository }}:{{ .Values.curl.image.tag }}" command: ["curl", "--fail-with-body"] args: ["http://{{ include "hapi-fhir-jpaserver.fullname" . }}:{{ .Values.service.port }}/fhir/Patient?_count=1&_summary=true"] {{- with .Values.restrictedContainerSecurityContext }} securityContext: {{- toYaml . | nindent 8 }} {{- end }} + {{- with .Values.tests.resources }} resources: - limits: - cpu: 100m - memory: 128Mi - requests: - cpu: 100m - memory: 128Mi + {{- toYaml . | nindent 8 }} + {{- end }} livenessProbe: exec: command: ["true"] @@ -53,20 +47,17 @@ spec: exec: command: ["true"] - name: test-metrics-endpoint - image: docker.io/curlimages/curl:8.1.2@sha256:ef501f5efa67be41da985b441bd63130ef39d4d6a4f9c035d737884357438b6c + image: "{{ .Values.curl.image.registry }}/{{ .Values.curl.image.repository }}:{{ .Values.curl.image.tag }}" command: ["curl", "--fail-with-body"] args: ["http://{{ include "hapi-fhir-jpaserver.fullname" . }}:{{ .Values.metrics.service.port }}/actuator/prometheus"] {{- with .Values.restrictedContainerSecurityContext }} securityContext: {{- toYaml . | nindent 8 }} {{- end }} + {{- with .Values.tests.resources }} resources: - limits: - cpu: 100m - memory: 128Mi - requests: - cpu: 100m - memory: 128Mi + {{- toYaml . | nindent 8 }} + {{- end }} livenessProbe: exec: command: ["true"] diff --git a/charts/hapi-fhir-jpaserver/values.yaml b/charts/hapi-fhir-jpaserver/values.yaml index 3349e1d..9e9c187 100644 --- a/charts/hapi-fhir-jpaserver/values.yaml +++ b/charts/hapi-fhir-jpaserver/values.yaml @@ -131,27 +131,42 @@ postgresql: seccompProfile: type: RuntimeDefault +# -- readiness probe +# @ignored readinessProbe: + httpGet: + path: /readyz + port: http failureThreshold: 5 initialDelaySeconds: 30 periodSeconds: 20 successThreshold: 1 timeoutSeconds: 20 -startupProbe: - failureThreshold: 10 - initialDelaySeconds: 30 - periodSeconds: 30 - successThreshold: 1 - timeoutSeconds: 30 - +# -- liveness probe +# @ignored livenessProbe: + httpGet: + path: /livez + port: http failureThreshold: 5 initialDelaySeconds: 30 periodSeconds: 20 successThreshold: 1 timeoutSeconds: 30 +# -- startup probe +# @ignored +startupProbe: + httpGet: + path: /readyz + port: http + failureThreshold: 10 + initialDelaySeconds: 30 + periodSeconds: 30 + successThreshold: 1 + timeoutSeconds: 30 + externalDatabase: # -- external database host used with `postgresql.enabled=false` host: localhost @@ -208,3 +223,32 @@ restrictedContainerSecurityContext: runAsGroup: 65534 seccompProfile: type: RuntimeDefault + +# @ignored +curl: + image: + registry: docker.io + repository: curlimages/curl + tag: 8.2.0@sha256:daf3f46a2639c1613b25e85c9ee4193af8a1d538f92483d67f9a3d7f21721827 + +tests: + # -- configure the test pods resource requests and limits + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +# -- additional Spring Boot application config. Mounted as a file and automatically loaded by the application. +extraConfig: "" + # # For example: + # | + # hapi: + # fhir: + # implementationguides: + # gh_0_1_0: + # url: https://build.fhir.org/ig/hl7-eu/gravitate-health/package.tgz + # name: hl7.eu.fhir.gh + # version: 0.1.0 From e9f29af1aac64f9a0453bd95b602e6b019a7388f Mon Sep 17 00:00:00 2001 From: dotasek Date: Mon, 31 Jul 2023 14:34:47 -0400 Subject: [PATCH 08/18] Bump to hapi 6.8.0-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1fc9a25..67495df 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ ca.uhn.hapi.fhir hapi-fhir - 6.6.0 + 6.8.0-SNAPSHOT hapi-fhir-jpaserver-starter From aafd4fa0d9484214ffd49f6e68ef665551ccc117 Mon Sep 17 00:00:00 2001 From: dotasek Date: Mon, 31 Jul 2023 14:43:58 -0400 Subject: [PATCH 09/18] Switch to new ca.uhn.fhir.batch2.jobs.export to fix StarterJpaConfig --- .../java/ca/uhn/fhir/jpa/starter/common/StarterJpaConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 c095e27..4788d59 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 @@ -18,7 +18,7 @@ import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; import ca.uhn.fhir.jpa.binary.interceptor.BinaryStorageInterceptor; import ca.uhn.fhir.jpa.binary.provider.BinaryAccessProvider; -import ca.uhn.fhir.jpa.bulk.export.provider.BulkDataExportProvider; +import ca.uhn.fhir.batch2.jobs.export.BulkDataExportProvider; import ca.uhn.fhir.jpa.config.util.HapiEntityManagerFactoryUtil; import ca.uhn.fhir.jpa.config.util.ResourceCountCacheUtil; import ca.uhn.fhir.jpa.config.util.ValidationSupportConfigUtil; From 3c395e9dbe23ee7de43869f3e2ad8dfc3ad06521 Mon Sep 17 00:00:00 2001 From: dotasek Date: Thu, 10 Aug 2023 12:08:57 -0400 Subject: [PATCH 10/18] WIP try to expand default max_result_window --- .../jpa/starter/ElasticsearchLastNR4IT.java | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/test/java/ca/uhn/fhir/jpa/starter/ElasticsearchLastNR4IT.java b/src/test/java/ca/uhn/fhir/jpa/starter/ElasticsearchLastNR4IT.java index 5cb0a4e..f8728bb 100644 --- a/src/test/java/ca/uhn/fhir/jpa/starter/ElasticsearchLastNR4IT.java +++ b/src/test/java/ca/uhn/fhir/jpa/starter/ElasticsearchLastNR4IT.java @@ -8,6 +8,10 @@ import ca.uhn.fhir.rest.client.api.IGenericClient; import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum; import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor; import java.io.IOException; +import java.io.OutputStreamWriter; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; import java.time.Duration; import java.time.temporal.ChronoUnit; import java.util.Date; @@ -43,6 +47,9 @@ import org.testcontainers.elasticsearch.ElasticsearchContainer; "hapi.fhir.lastn_enabled=true", "hapi.fhir.store_resource_in_lucene_index_enabled=true", "hapi.fhir.advanced_lucene_indexing=true", + "hapi.fhir.subscription.websocket_enabled=false", + "hapi.fhir.subscription.resthook_enabled=false", + "hapi.fhir.subscription.email_enabled=false", "elasticsearch.enabled=true", // Because the port is set randomly, we will set the rest_url using the Initializer. // "elasticsearch.rest_url='http://localhost:9200'", @@ -69,9 +76,21 @@ public class ElasticsearchLastNR4IT { private ElasticsearchSvcImpl myElasticsearchSvc; @BeforeAll - public static void beforeClass() { + public static void beforeClass() throws IOException { embeddedElastic = new ElasticsearchContainer(ELASTIC_IMAGE).withStartupTimeout(Duration.of(300, ChronoUnit.SECONDS)); embeddedElastic.start(); + + URL url = new URL("http://" + embeddedElastic.getHost() + ":9200/_settings"); + HttpURLConnection httpCon = (HttpURLConnection) url.openConnection(); + httpCon.setDoOutput(true); + httpCon.setRequestMethod("PUT"); + OutputStreamWriter out = new OutputStreamWriter( + httpCon.getOutputStream()); + out.write("{\n" + + " \"index.max_result_window\": 50000\n" + + "}"); + out.close(); + httpCon.getInputStream(); } @PreDestroy From f7853f5e19afd1f16854c3fd352fe1fc423ef04e Mon Sep 17 00:00:00 2001 From: Tadgh Date: Thu, 10 Aug 2023 09:30:01 -0700 Subject: [PATCH 11/18] Fix up test --- pom.xml | 6 +++ .../jpa/starter/ElasticsearchLastNR4IT.java | 45 ++++++++++++------- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/pom.xml b/pom.xml index 67495df..e84aeed 100644 --- a/pom.xml +++ b/pom.xml @@ -247,6 +247,12 @@ + + ca.uhn.hapi.fhir + hapi-fhir-jpaserver-test-utilities + ${project.version} + test + org.eclipse.jetty jetty-servlets diff --git a/src/test/java/ca/uhn/fhir/jpa/starter/ElasticsearchLastNR4IT.java b/src/test/java/ca/uhn/fhir/jpa/starter/ElasticsearchLastNR4IT.java index f8728bb..240cd29 100644 --- a/src/test/java/ca/uhn/fhir/jpa/starter/ElasticsearchLastNR4IT.java +++ b/src/test/java/ca/uhn/fhir/jpa/starter/ElasticsearchLastNR4IT.java @@ -3,20 +3,28 @@ package ca.uhn.fhir.jpa.starter; import static org.junit.jupiter.api.Assertions.assertEquals; import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.jpa.search.lastn.ElasticsearchRestClientFactory; import ca.uhn.fhir.jpa.search.lastn.ElasticsearchSvcImpl; +import ca.uhn.fhir.jpa.test.config.TestElasticsearchContainerHelper; import ca.uhn.fhir.rest.client.api.IGenericClient; import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum; import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor; import java.io.IOException; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; -import java.net.MalformedURLException; import java.net.URL; import java.time.Duration; import java.time.temporal.ChronoUnit; import java.util.Date; import java.util.GregorianCalendar; +import java.util.List; import javax.annotation.PreDestroy; + +import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest; +import org.elasticsearch.client.RequestOptions; +import org.elasticsearch.client.RestHighLevelClient; +import org.elasticsearch.client.indices.PutIndexTemplateRequest; +import org.elasticsearch.common.settings.Settings; import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.r4.model.Bundle; import org.hl7.fhir.r4.model.DateTimeType; @@ -38,8 +46,11 @@ import org.springframework.context.ConfigurableApplicationContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.testcontainers.elasticsearch.ElasticsearchContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; @ExtendWith(SpringExtension.class) +@Testcontainers @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = {Application.class, JpaStarterWebsocketDispatcherConfig.class}, properties = { "spring.datasource.url=jdbc:h2:mem:dbr4", @@ -70,29 +81,28 @@ public class ElasticsearchLastNR4IT { private static final String ELASTIC_VERSION = "7.16.3"; private static final String ELASTIC_IMAGE = "docker.elastic.co/elasticsearch/elasticsearch:" + ELASTIC_VERSION; - private static ElasticsearchContainer embeddedElastic; + + @Container + public static ElasticsearchContainer embeddedElastic = TestElasticsearchContainerHelper.getEmbeddedElasticSearch(); @Autowired private ElasticsearchSvcImpl myElasticsearchSvc; @BeforeAll public static void beforeClass() throws IOException { - embeddedElastic = new ElasticsearchContainer(ELASTIC_IMAGE).withStartupTimeout(Duration.of(300, ChronoUnit.SECONDS)); - embeddedElastic.start(); + //Given + RestHighLevelClient elasticsearchHighLevelRestClient = ElasticsearchRestClientFactory.createElasticsearchHighLevelRestClient( + "http", embeddedElastic.getHost() + ":" + embeddedElastic.getMappedPort(9200), "", ""); + + PutIndexTemplateRequest putIndexTemplateRequest = new PutIndexTemplateRequest("hapi_fhir_template"); + putIndexTemplateRequest.patterns(List.of("*")); + Settings settings = Settings.builder().put("index.max_result_window", 50000).build(); + putIndexTemplateRequest.settings(settings); + elasticsearchHighLevelRestClient.indices().putTemplate(putIndexTemplateRequest, RequestOptions.DEFAULT); + - URL url = new URL("http://" + embeddedElastic.getHost() + ":9200/_settings"); - HttpURLConnection httpCon = (HttpURLConnection) url.openConnection(); - httpCon.setDoOutput(true); - httpCon.setRequestMethod("PUT"); - OutputStreamWriter out = new OutputStreamWriter( - httpCon.getOutputStream()); - out.write("{\n" + - " \"index.max_result_window\": 50000\n" + - "}"); - out.close(); - httpCon.getInputStream(); } - + @PreDestroy public void stop() { embeddedElastic.stop(); @@ -134,7 +144,7 @@ public class ElasticsearchLastNR4IT { } @BeforeEach - void beforeEach() { + void beforeEach() throws IOException { ourCtx = FhirContext.forR4(); ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER); @@ -142,6 +152,7 @@ public class ElasticsearchLastNR4IT { String ourServerBase = "http://localhost:" + port + "/fhir/"; ourClient = ourCtx.newRestfulGenericClient(ourServerBase); ourClient.registerInterceptor(new LoggingInterceptor(true)); + } static class Initializer From bdf593f151e9210d0c7736f022fa4fe9ae7ab335 Mon Sep 17 00:00:00 2001 From: dotasek Date: Thu, 10 Aug 2023 12:34:45 -0400 Subject: [PATCH 12/18] Clean up code --- .../fhir/jpa/starter/ElasticsearchLastNR4IT.java | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/test/java/ca/uhn/fhir/jpa/starter/ElasticsearchLastNR4IT.java b/src/test/java/ca/uhn/fhir/jpa/starter/ElasticsearchLastNR4IT.java index 240cd29..f65a572 100644 --- a/src/test/java/ca/uhn/fhir/jpa/starter/ElasticsearchLastNR4IT.java +++ b/src/test/java/ca/uhn/fhir/jpa/starter/ElasticsearchLastNR4IT.java @@ -10,17 +10,12 @@ import ca.uhn.fhir.rest.client.api.IGenericClient; import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum; import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor; import java.io.IOException; -import java.io.OutputStreamWriter; -import java.net.HttpURLConnection; -import java.net.URL; -import java.time.Duration; -import java.time.temporal.ChronoUnit; + import java.util.Date; import java.util.GregorianCalendar; import java.util.List; import javax.annotation.PreDestroy; -import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.PutIndexTemplateRequest; @@ -58,9 +53,7 @@ import org.testcontainers.junit.jupiter.Testcontainers; "hapi.fhir.lastn_enabled=true", "hapi.fhir.store_resource_in_lucene_index_enabled=true", "hapi.fhir.advanced_lucene_indexing=true", - "hapi.fhir.subscription.websocket_enabled=false", - "hapi.fhir.subscription.resthook_enabled=false", - "hapi.fhir.subscription.email_enabled=false", + "elasticsearch.enabled=true", // Because the port is set randomly, we will set the rest_url using the Initializer. // "elasticsearch.rest_url='http://localhost:9200'", @@ -79,10 +72,7 @@ public class ElasticsearchLastNR4IT { private IGenericClient ourClient; private FhirContext ourCtx; - private static final String ELASTIC_VERSION = "7.16.3"; - private static final String ELASTIC_IMAGE = "docker.elastic.co/elasticsearch/elasticsearch:" + ELASTIC_VERSION; - - @Container + @Container public static ElasticsearchContainer embeddedElastic = TestElasticsearchContainerHelper.getEmbeddedElasticSearch(); @Autowired From 1907536d28ec527cc57a6f9536f1742af0fa6e60 Mon Sep 17 00:00:00 2001 From: dotasek Date: Thu, 10 Aug 2023 12:51:34 -0400 Subject: [PATCH 13/18] Fix one more failing IT config --- src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR4IT.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR4IT.java b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR4IT.java index d08770a..26f27f6 100644 --- a/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR4IT.java +++ b/src/test/java/ca/uhn/fhir/jpa/starter/ExampleServerR4IT.java @@ -1,6 +1,7 @@ package ca.uhn.fhir.jpa.starter; import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.jpa.searchparam.config.NicknameServiceConfig; import ca.uhn.fhir.rest.api.CacheControlDirective; import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.api.MethodOutcome; @@ -30,7 +31,7 @@ import static org.awaitility.Awaitility.await; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = {Application.class, JpaStarterWebsocketDispatcherConfig.class}, properties = { +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = {Application.class, JpaStarterWebsocketDispatcherConfig.class, NicknameServiceConfig.class}, properties = { "spring.datasource.url=jdbc:h2:mem:dbr4", "hapi.fhir.enable_repository_validating_interceptor=true", "hapi.fhir.fhir_version=r4", From 7265b115dd83664d972235f677d898e89a1d3c48 Mon Sep 17 00:00:00 2001 From: dotasek Date: Thu, 10 Aug 2023 12:55:30 -0400 Subject: [PATCH 14/18] Leave comment in case of updates --- .../java/ca/uhn/fhir/jpa/starter/ElasticsearchLastNR4IT.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/java/ca/uhn/fhir/jpa/starter/ElasticsearchLastNR4IT.java b/src/test/java/ca/uhn/fhir/jpa/starter/ElasticsearchLastNR4IT.java index f65a572..6f358d4 100644 --- a/src/test/java/ca/uhn/fhir/jpa/starter/ElasticsearchLastNR4IT.java +++ b/src/test/java/ca/uhn/fhir/jpa/starter/ElasticsearchLastNR4IT.java @@ -84,6 +84,10 @@ public class ElasticsearchLastNR4IT { RestHighLevelClient elasticsearchHighLevelRestClient = ElasticsearchRestClientFactory.createElasticsearchHighLevelRestClient( "http", embeddedElastic.getHost() + ":" + embeddedElastic.getMappedPort(9200), "", ""); + /* As of 2023-08-10, HAPI FHIR sets SubscriptionConstants.MAX_SUBSCRIPTION_RESULTS to 50000 + which is in excess of elastic's default max_result_window. If MAX_SUBSCRIPTION_RESULTS is changed + to a value <= 10000, the following will no longer be necessary. - dotasek + */ PutIndexTemplateRequest putIndexTemplateRequest = new PutIndexTemplateRequest("hapi_fhir_template"); putIndexTemplateRequest.patterns(List.of("*")); Settings settings = Settings.builder().put("index.max_result_window", 50000).build(); From 69ff8c4d0675ba88521b6050e0975634381de7f4 Mon Sep 17 00:00:00 2001 From: dotasek Date: Thu, 17 Aug 2023 09:54:46 -0400 Subject: [PATCH 15/18] Bump to HAPI 6.8.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e84aeed..3b38277 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ ca.uhn.hapi.fhir hapi-fhir - 6.8.0-SNAPSHOT + 6.8.0 hapi-fhir-jpaserver-starter From b88ffdada00cb16d19e9dad68289cd07d1473f88 Mon Sep 17 00:00:00 2001 From: dotasek Date: Thu, 17 Aug 2023 13:02:02 -0400 Subject: [PATCH 16/18] Fix breakages due to https://github.com/hapifhir/hapi-fhir/pull/5180 --- .../ca/uhn/fhir/jpa/starter/common/StarterJpaConfig.java | 5 ++--- .../ca/uhn/fhir/jpa/starter/cr/StarterCrDstu3Config.java | 2 +- .../java/ca/uhn/fhir/jpa/starter/cr/StarterCrR4Config.java | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) 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 33b498b..7a1934f 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 @@ -9,7 +9,7 @@ import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.support.IValidationSupport; -import ca.uhn.fhir.cr.config.CrProviderLoader; + import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster; import ca.uhn.fhir.jpa.api.IDaoRegistry; import ca.uhn.fhir.jpa.api.config.JpaStorageSettings; @@ -111,8 +111,7 @@ public class StarterJpaConfig { @Autowired private ConfigurableEnvironment configurableEnvironment; - @Autowired(required=false) - private CrProviderLoader crProviderLoader; + /** * Customize the default/max page sizes for search results. You can set these however diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/cr/StarterCrDstu3Config.java b/src/main/java/ca/uhn/fhir/jpa/starter/cr/StarterCrDstu3Config.java index 9efc086..06d95f4 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/cr/StarterCrDstu3Config.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cr/StarterCrDstu3Config.java @@ -1,6 +1,6 @@ package ca.uhn.fhir.jpa.starter.cr; -import ca.uhn.fhir.cr.config.CrDstu3Config; +import ca.uhn.fhir.cr.config.dstu3.CrDstu3Config; import ca.uhn.fhir.jpa.starter.annotations.OnDSTU3Condition; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/cr/StarterCrR4Config.java b/src/main/java/ca/uhn/fhir/jpa/starter/cr/StarterCrR4Config.java index a97cea7..586a324 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/cr/StarterCrR4Config.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/cr/StarterCrR4Config.java @@ -1,6 +1,6 @@ package ca.uhn.fhir.jpa.starter.cr; -import ca.uhn.fhir.cr.config.CrR4Config; +import ca.uhn.fhir.cr.config.r4.CrR4Config; import ca.uhn.fhir.jpa.starter.annotations.OnR4Condition; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Import; From 37a9317355a96fb438d6d9ba027bd34ada3d9db6 Mon Sep 17 00:00:00 2001 From: Jens Kristian Villadsen Date: Tue, 22 Aug 2023 20:14:43 +0200 Subject: [PATCH 17/18] Feature/using package installer spec (#577) * Adjusting to HAPI core classes * Added example as default * Commented the example IG out again --- .../uhn/fhir/jpa/starter/AppProperties.java | 37 ++----------------- .../jpa/starter/common/StarterJpaConfig.java | 15 ++++---- src/main/resources/application.yaml | 11 +++--- src/test/resources/application.yaml | 3 +- 4 files changed, 20 insertions(+), 46 deletions(-) diff --git a/src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java b/src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java index ec922de..c8a9f63 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java @@ -4,6 +4,7 @@ package ca.uhn.fhir.jpa.starter; import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.jpa.api.config.JpaStorageSettings.ClientIdStrategyEnum; import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel; +import ca.uhn.fhir.jpa.packages.PackageInstallationSpec; import ca.uhn.fhir.rest.api.EncodingEnum; import org.hl7.fhir.r4.model.Bundle; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -74,7 +75,7 @@ public class AppProperties { private Partitioning partitioning = null; private Boolean install_transitive_ig_dependencies = true; private Boolean reload_existing_implementationguides = false; - private Map implementationGuides = null; + private Map implementationGuides = null; private String staticLocation = null; @@ -148,11 +149,11 @@ public class AppProperties { this.defer_indexing_for_codesystems_of_size = defer_indexing_for_codesystems_of_size; } - public Map getImplementationGuides() { + public Map getImplementationGuides() { return implementationGuides; } - public void setImplementationGuides(Map implementationGuides) { + public void setImplementationGuides(Map implementationGuides) { this.implementationGuides = implementationGuides; } @@ -696,36 +697,6 @@ public class AppProperties { } } - public static class ImplementationGuide - { - private String url; - private String name; - private String version; - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getVersion() { - return version; - } - - public void setVersion(String version) { - this.version = version; - } - } public static class Validation { 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 7a1934f..7276777 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 @@ -76,7 +76,6 @@ import org.springframework.web.cors.CorsConfiguration; import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; - import java.util.*; import static ca.uhn.fhir.jpa.starter.common.validation.IRepositoryValidationInterceptorFactory.ENABLE_REPOSITORY_VALIDATING_INTERCEPTOR; @@ -194,13 +193,15 @@ public class StarterJpaConfig { jobDefinitionRegistry.addJobDefinitionIfNotRegistered(reindexJobParametersJobDefinition); if (appProperties.getImplementationGuides() != null) { - Map guides = appProperties.getImplementationGuides(); - for (Map.Entry guide : guides.entrySet()) { - PackageInstallationSpec packageInstallationSpec = new PackageInstallationSpec().setPackageUrl(guide.getValue().getUrl()).setName(guide.getValue().getName()).setVersion(guide.getValue().getVersion()).setInstallMode(PackageInstallationSpec.InstallModeEnum.STORE_AND_INSTALL); - packageInstallationSpec.setReloadExisting(appProperties.getReload_existing_implementationguides()); + Map guides = appProperties.getImplementationGuides(); + for (Map.Entry guidesEntry : guides.entrySet()) { + PackageInstallationSpec packageInstallationSpec = guidesEntry.getValue(); if (appProperties.getInstall_transitive_ig_dependencies()) { - packageInstallationSpec.setFetchDependencies(true); - packageInstallationSpec.setDependencyExcludes(List.of("hl7.fhir.r2.core", "hl7.fhir.r3.core", "hl7.fhir.r4.core", "hl7.fhir.r5.core")); + + packageInstallationSpec.addDependencyExclude("hl7.fhir.r2.core") + .addDependencyExclude("hl7.fhir.r3.core") + .addDependencyExclude("hl7.fhir.r4.core") + .addDependencyExclude("hl7.fhir.r5.core"); } packageInstallerSvc.install(packageInstallationSpec); } diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index a38c9c2..0180008 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -77,14 +77,15 @@ hapi: # install_transitive_ig_dependencies: true ### tells the server whether to attempt to load IG resources that are already present # reload_existing_implementationGuides : false - # implementationguides: + #implementationguides: ### example from registry (packages.fhir.org) - # swiss: - # name: swiss.mednet.fhir - # version: 0.8.0 + # swiss: + # name: swiss.mednet.fhir + # version: 0.8.0 + # reloadExisting : false # example not from registry # ips_1_0_0: - # url: https://build.fhir.org/ig/HL7/fhir-ips/package.tgz + # packageUrl: https://build.fhir.org/ig/HL7/fhir-ips/package.tgz # name: hl7.fhir.uv.ips # version: 1.0.0 # supported_resource_types: diff --git a/src/test/resources/application.yaml b/src/test/resources/application.yaml index 89229c9..9f473c5 100644 --- a/src/test/resources/application.yaml +++ b/src/test/resources/application.yaml @@ -64,9 +64,10 @@ hapi: # swiss: # name: swiss.mednet.fhir # version: 0.8.0 + # reloadExisting : false # example not from registry # ips_1_0_0: - # url: https://build.fhir.org/ig/HL7/fhir-ips/package.tgz + # packageUrl: https://build.fhir.org/ig/HL7/fhir-ips/package.tgz # name: hl7.fhir.uv.ips # version: 1.0.0 # supported_resource_types: From 63c4825d569b070ae2f47b8fb5cb96a647c2391a Mon Sep 17 00:00:00 2001 From: Husam Nujaim <60360833+HussamNujaim@users.noreply.github.com> Date: Sun, 3 Sep 2023 01:15:10 +0200 Subject: [PATCH 18/18] Fixing some typos in README.md --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index dbb5740..0184cc5 100644 --- a/README.md +++ b/README.md @@ -235,7 +235,7 @@ Server will then be accessible at http://localhost:8080/ and eg. http://localhos ```bash mvn clean package spring-boot:repackage -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 you overlay configuration in the application.yaml to eg. +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 eg. ```yaml tester: @@ -250,7 +250,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 you overlay configuration in the application.yaml to eg. +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 eg. ```yaml tester: @@ -266,7 +266,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 you overlay configuration in the application.yaml to eg. +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 eg. ```yaml tester: @@ -307,7 +307,7 @@ spring: # Then comment all hibernate.search.backend.* ``` -Because the integration tests within the project rely on the default H2 database configuration, it is important to either explicity skip the integration tests during the build process, i.e., `mvn install -DskipTests`, or delete the tests altogether. Failure to skip or delete the tests once you've configured PostgreSQL for the datasource.driver, datasource.url, and hibernate.dialect as outlined above will result in build errors and compilation failure. +Because the integration tests within the project rely on the default H2 database configuration, it is important to either explicitly skip the integration tests during the build process, i.e., `mvn install -DskipTests`, or delete the tests altogether. Failure to skip or delete the tests once you've configured PostgreSQL for the datasource.driver, datasource.url, and hibernate.dialect as outlined above will result in build errors and compilation failure. ### Microsoft SQL Server configuration @@ -322,14 +322,14 @@ spring: driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver ``` -Also, make sure you are not setting the Hibernate dialect explicitly, in other words remove any lines similar to: +Also, make sure you are not setting the Hibernate dialect explicitly, in other words, remove any lines similar to: ``` hibernate.dialect: {some none Microsoft SQL dialect} ``` -Because the integration tests within the project rely on the default H2 database configuration, it is important to either explicity skip the integration tests during the build process, i.e., `mvn install -DskipTests`, or delete the tests altogether. Failure to skip or delete the tests once you've configured PostgreSQL for the datasource.driver, datasource.url, and hibernate.dialect as outlined above will result in build errors and compilation failure. +Because the integration tests within the project rely on the default H2 database configuration, it is important to either explicitly skip the integration tests during the build process, i.e., `mvn install -DskipTests`, or delete the tests altogether. Failure to skip or delete the tests once you've configured PostgreSQL for the datasource.driver, datasource.url, and hibernate.dialect as outlined above will result in build errors and compilation failure. NOTE: MS SQL Server by default uses a case-insensitive codepage. This will cause errors with some operations - such as when expanding case-sensitive valuesets (UCUM) as there are unique indexes defined on the terminology tables for codes. @@ -373,7 +373,7 @@ Again, browse to the following link to use the server (note that the port 8080 m [http://localhost:8080/](http://localhost:8080/) -You will then be able access the JPA server e.g. using http://localhost:8080/fhir/metadata. +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. @@ -390,7 +390,7 @@ If you would like it to be hosted at eg. hapi-fhir-jpaserver, eg. http://localho ## Deploy with docker compose -Docker compose is a simple option to build and deploy container. To deploy with docker compose, you should build the project +Docker compose is a simple option to build and deploy containers. To deploy with docker compose, you should build the project with `mvn clean install` and then bring up the containers with `docker-compose up -d --build`. The server can be reached at http://localhost:8080/.