diff --git a/.github/workflows/chart-test.yaml b/.github/workflows/chart-test.yaml index 30d2932..629789f 100644 --- a/.github/workflows/chart-test.yaml +++ b/.github/workflows/chart-test.yaml @@ -15,7 +15,7 @@ jobs: - name: Install helm-docs working-directory: /tmp env: - HELM_DOCS_URL: https://github.com/norwoodj/helm-docs/releases/download/v1.11.0/helm-docs_1.11.0_Linux_x86_64.tar.gz + HELM_DOCS_URL: https://github.com/norwoodj/helm-docs/releases/download/v1.11.3/helm-docs_1.11.3_Linux_x86_64.tar.gz run: | curl -LSs $HELM_DOCS_URL | tar xz && \ mv ./helm-docs /usr/local/bin/helm-docs && \ @@ -30,6 +30,7 @@ jobs: 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 diff --git a/Dockerfile b/Dockerfile index 8e6c8b0..6f03d4c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ -FROM docker.io/library/maven:3.9.2-eclipse-temurin-17 AS build-hapi +FROM docker.io/library/maven:3.9.4-eclipse-temurin-17 AS build-hapi WORKDIR /tmp/hapi-fhir-jpaserver-starter -ARG OPENTELEMETRY_JAVA_AGENT_VERSION=1.26.0 +ARG OPENTELEMETRY_JAVA_AGENT_VERSION=1.31.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 . @@ -12,7 +12,7 @@ COPY src/ /tmp/hapi-fhir-jpaserver-starter/src/ RUN mvn clean install -DskipTests -Djdk.lang.Process.launchMechanism=vfork FROM build-hapi AS build-distroless -RUN mvn package spring-boot:repackage -Pboot +RUN mvn package -DskipTests spring-boot:repackage -Pboot RUN mkdir /app && cp /tmp/hapi-fhir-jpaserver-starter/target/ROOT.war /app/main.war diff --git a/charts/hapi-fhir-jpaserver/Chart.yaml b/charts/hapi-fhir-jpaserver/Chart.yaml index a81e108..ed55661 100644 --- a/charts/hapi-fhir-jpaserver/Chart.yaml +++ b/charts/hapi-fhir-jpaserver/Chart.yaml @@ -10,18 +10,18 @@ dependencies: version: 12.5.6 repository: oci://registry-1.docker.io/bitnamicharts condition: postgresql.enabled -appVersion: 6.6.0 -version: 0.13.0 +appVersion: 6.8.3 +version: 0.14.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 + description: updated starter image to 6.8.3 + - kind: fixed + description: incorrect handling of existing secret database config - kind: added - description: allow setting resource limits and requests for the Helm test pods - - kind: changed - description: updated curl used by helm tests to version to v8.2.0 - - kind: changed - description: allow disabling the liveness-, readiness-, and startup-probes entirely + description: support for using a non-admin user for the postgres database + - kind: added + description: ability to create a dedicated ServiceAccount diff --git a/charts/hapi-fhir-jpaserver/README.md b/charts/hapi-fhir-jpaserver/README.md index 7d4d338..af318f1 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.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) +![Version: 0.14.0](https://img.shields.io/badge/Version-0.14.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 6.8.3](https://img.shields.io/badge/AppVersion-6.8.3-informational?style=flat-square) This helm chart will help you install the HAPI FHIR JPA Server in a Kubernetes environment. @@ -36,7 +36,7 @@ helm install hapi-fhir-jpaserver hapifhir/hapi-fhir-jpaserver | 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.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. | +| image.tag | string | `"v6.8.3@sha256:6195f1116ebabfb0a608addde043b3e524c456c4d4f35b3d25025afd7dcd2e27"` | 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 | @@ -73,6 +73,10 @@ 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 | +| serviceAccount.annotations | object | `{}` | Annotations to add to the service account | +| serviceAccount.automount | bool | `true` | Automatically mount a ServiceAccount's API credentials? | +| serviceAccount.create | bool | `false` | Specifies whether a service account should be created. | +| serviceAccount.name | string | `""` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template | | 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 | @@ -139,4 +143,4 @@ kubectl port-forward -n observability service/simplest-query 16686:16686 and opening in your browser. ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.11.0](https://github.com/norwoodj/helm-docs/releases/v1.11.0) +Autogenerated from chart metadata using [helm-docs v1.11.3](https://github.com/norwoodj/helm-docs/releases/v1.11.3) diff --git a/charts/hapi-fhir-jpaserver/ci/custom-postgres-user-values.yaml b/charts/hapi-fhir-jpaserver/ci/custom-postgres-user-values.yaml new file mode 100644 index 0000000..ca2d9fe --- /dev/null +++ b/charts/hapi-fhir-jpaserver/ci/custom-postgres-user-values.yaml @@ -0,0 +1,7 @@ +postgresql: + enabled: true + auth: + username: hapi_fhir_jpaserver_starter_user + database: hapi_fhir_jpaserver_starter + password: secret_user_password + postgresPassword: secret_postgres_password diff --git a/charts/hapi-fhir-jpaserver/templates/_helpers.tpl b/charts/hapi-fhir-jpaserver/templates/_helpers.tpl index eee1ed5..954d1e9 100644 --- a/charts/hapi-fhir-jpaserver/templates/_helpers.tpl +++ b/charts/hapi-fhir-jpaserver/templates/_helpers.tpl @@ -50,6 +50,17 @@ app.kubernetes.io/name: {{ include "hapi-fhir-jpaserver.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} {{- end }} +{{/* +Create the name of the service account to use +*/}} +{{- define "hapi-fhir-jpaserver.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "hapi-fhir-jpaserver.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + {{/* Create a default fully qualified postgresql name. We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). @@ -63,10 +74,12 @@ We truncate at 63 chars because some Kubernetes name fields are limited to this Get the Postgresql credentials secret name. */}} {{- define "hapi-fhir-jpaserver.postgresql.secretName" -}} -{{- if and (.Values.postgresql.enabled) (not .Values.postgresql.auth.existingSecret) -}} - {{- printf "%s" (include "hapi-fhir-jpaserver.postgresql.fullname" .) -}} -{{- else if and (.Values.postgresql.enabled) (.Values.postgresql.auth.existingSecret) -}} - {{- printf "%s" .Values.postgresql.auth.existingSecret -}} +{{- if .Values.postgresql.enabled -}} + {{- if .Values.postgresql.auth.existingSecret -}} + {{- printf "%s" .Values.postgresql.auth.existingSecret -}} + {{- else -}} + {{- printf "%s" (include "hapi-fhir-jpaserver.postgresql.fullname" .) -}} + {{- end -}} {{- else }} {{- if .Values.externalDatabase.existingSecret -}} {{- printf "%s" .Values.externalDatabase.existingSecret -}} @@ -80,10 +93,18 @@ Get the Postgresql credentials secret name. Get the Postgresql credentials secret key. */}} {{- define "hapi-fhir-jpaserver.postgresql.secretKey" -}} -{{- if (.Values.externalDatabase.existingSecret) -}} - {{- printf "%s" .Values.externalDatabase.existingSecretKey -}} +{{- if .Values.postgresql.enabled -}} + {{- if .Values.postgresql.auth.username -}} + {{- printf "%s" .Values.postgresql.auth.secretKeys.userPasswordKey -}} + {{- else -}} + {{- printf "%s" .Values.postgresql.auth.secretKeys.adminPasswordKey -}} + {{- end -}} {{- else }} - {{- printf "postgres-password" -}} + {{- if .Values.externalDatabase.existingSecret -}} + {{- printf "%s" .Values.externalDatabase.existingSecretKey -}} + {{- else -}} + {{- printf "postgres-password" -}} + {{- end -}} {{- end -}} {{- end -}} @@ -98,7 +119,11 @@ Add environment variables to configure database values Add environment variables to configure database values */}} {{- define "hapi-fhir-jpaserver.database.user" -}} -{{- ternary "postgres" .Values.externalDatabase.user .Values.postgresql.enabled -}} +{{- if .Values.postgresql.enabled -}} + {{- printf "%s" .Values.postgresql.auth.username | default "postgres" -}} +{{- else -}} + {{- printf "%s" .Values.externalDatabase.user -}} +{{- end -}} {{- end -}} {{/* diff --git a/charts/hapi-fhir-jpaserver/templates/deployment.yaml b/charts/hapi-fhir-jpaserver/templates/deployment.yaml index c15609f..febfded 100644 --- a/charts/hapi-fhir-jpaserver/templates/deployment.yaml +++ b/charts/hapi-fhir-jpaserver/templates/deployment.yaml @@ -26,6 +26,7 @@ spec: imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} + serviceAccountName: {{ include "hapi-fhir-jpaserver.serviceAccountName" . }} securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }} initContainers: diff --git a/charts/hapi-fhir-jpaserver/templates/serviceaccount.yaml b/charts/hapi-fhir-jpaserver/templates/serviceaccount.yaml new file mode 100644 index 0000000..b60d7a7 --- /dev/null +++ b/charts/hapi-fhir-jpaserver/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "hapi-fhir-jpaserver.serviceAccountName" . }} + labels: + {{- include "hapi-fhir-jpaserver.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automount }} +{{- end }} diff --git a/charts/hapi-fhir-jpaserver/values.yaml b/charts/hapi-fhir-jpaserver/values.yaml index 9e9c187..56332bc 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.6.0@sha256:c00367865ae5dad4e171cbb68bfc1c39818854079d1565bee4c86a45e78335d0" + tag: "v6.8.3@sha256:6195f1116ebabfb0a608addde043b3e524c456c4d4f35b3d25025afd7dcd2e27" # -- image pullPolicy to use pullPolicy: IfNotPresent @@ -198,6 +198,17 @@ podDisruptionBudget: # -- maximum unavailable instances maxUnavailable: "" +serviceAccount: + # -- Specifies whether a service account should be created. + create: false + # -- Annotations to add to the service account + annotations: {} + # -- The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + # -- Automatically mount a ServiceAccount's API credentials? + automount: true + metrics: serviceMonitor: # -- if enabled, creates a ServiceMonitor instance for Prometheus Operator-based monitoring @@ -229,7 +240,7 @@ curl: image: registry: docker.io repository: curlimages/curl - tag: 8.2.0@sha256:daf3f46a2639c1613b25e85c9ee4193af8a1d538f92483d67f9a3d7f21721827 + tag: 8.4.0@sha256:4a3396ae573c44932d06ba33f8696db4429c419da87cbdc82965ee96a37dd0af tests: # -- configure the test pods resource requests and limits @@ -242,7 +253,8 @@ tests: # memory: 128Mi # -- additional Spring Boot application config. Mounted as a file and automatically loaded by the application. -extraConfig: "" +extraConfig: + "" # # For example: # | # hapi: diff --git a/pom.xml b/pom.xml index 9549b8c..f750d54 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ ca.uhn.hapi.fhir hapi-fhir - 6.10.0 + 6.10.0 hapi-fhir-jpaserver-starter @@ -42,6 +42,15 @@ + + + + org.glassfish.jaxb + jaxb-runtime + 2.3.8 + + + @@ -62,17 +71,7 @@ com.microsoft.sqlserver mssql-jdbc - - jakarta.xml.bind - jakarta.xml.bind-api - 2.3.3 - - - com.sun.xml.bind - jaxb-ri - 2.3.5 - pom - + org.simplejavamail @@ -222,11 +221,6 @@ - - org.webjars - bootstrap - 5.1.3 - org.webjars Eonasdan-bootstrap-datetimepicker @@ -262,6 +256,12 @@ hapi-fhir-jpaserver-test-utilities ${project.version} test + + + com.sun.xml.bind + jaxb-impl + + org.eclipse.jetty @@ -329,7 +329,7 @@ org.awaitility awaitility - 4.1.0 + 4.2.0 test @@ -349,14 +349,14 @@ io.micrometer micrometer-core - 1.9.4 + 1.11.3 io.micrometer micrometer-registry-prometheus - 1.9.4 + 1.11.3 @@ -412,7 +412,12 @@ org.apache.maven.plugins maven-dependency-plugin - 3.2.0 + 3.6.0 + + + org.apache.maven.plugins + maven-surefire-plugin + 3.1.2 @@ -440,7 +445,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.1 + 3.11.0 11 @@ -591,7 +596,7 @@ --> - + 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 5ad6c83..7df8e69 100644 --- a/src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java +++ b/src/main/java/ca/uhn/fhir/jpa/starter/AppProperties.java @@ -6,9 +6,6 @@ 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.cqframework.cql.cql2elm.CqlCompilerException; -import org.cqframework.cql.cql2elm.CqlTranslator; -import org.cqframework.cql.cql2elm.LibraryBuilder; import org.hl7.fhir.r4.model.Bundle; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -25,7 +22,7 @@ import java.util.Set; @Configuration @EnableConfigurationProperties public class AppProperties { - + private Boolean ips_enabled = false; private Boolean openapi_enabled = false; private Boolean mdm_enabled = false; @@ -68,7 +65,6 @@ public class AppProperties { private List supported_resource_types = new ArrayList<>(); private List allowed_bundle_types = null; private Boolean narrative_enabled = true; - private Validation validation = new Validation(); private Map tester = null; private Logger logger = new Logger(); @@ -78,22 +74,17 @@ public class AppProperties { private Boolean install_transitive_ig_dependencies = true; private Boolean reload_existing_implementationguides = false; private Map implementationGuides = null; - + private Boolean cr_enabled = false; 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; - private Boolean use_apache_address_strategy = false; private Boolean use_apache_address_strategy_https = false; - private Integer bundle_batch_pool_size = 20; private Integer bundle_batch_pool_max_size = 100; private final Set local_base_urls = new HashSet<>(); - private final List custom_interceptor_classes = new ArrayList<>(); public String getStaticLocationPrefix() { 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 2f673ed..b8d3f0f 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 @@ -11,7 +11,6 @@ import ca.uhn.fhir.jpa.starter.AppProperties; import ca.uhn.fhir.jpa.starter.util.JpaHibernatePropertiesProvider; 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; import ca.uhn.fhir.rest.server.mail.MailConfig; import ca.uhn.fhir.rest.server.mail.MailSvc; import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory; @@ -139,111 +138,112 @@ public class FhirServerConfigCommon { jpaStorageSettings.setLastNEnabled(true); } - if (appProperties.getInline_resource_storage_below_size() != 0) { - jpaStorageSettings.setInlineResourceTextBelowSize(appProperties.getInline_resource_storage_below_size()); - } + if(appProperties.getInline_resource_storage_below_size() != 0){ + jpaStorageSettings.setInlineResourceTextBelowSize(appProperties.getInline_resource_storage_below_size()); + } - jpaStorageSettings.setStoreResourceInHSearchIndex(appProperties.getStore_resource_in_lucene_index_enabled()); - jpaStorageSettings.setNormalizedQuantitySearchLevel(appProperties.getNormalized_quantity_search_level()); - jpaStorageSettings.setIndexOnContainedResources(appProperties.getEnable_index_contained_resource()); + jpaStorageSettings.setStoreResourceInHSearchIndex(appProperties.getStore_resource_in_lucene_index_enabled()); + jpaStorageSettings.setNormalizedQuantitySearchLevel(appProperties.getNormalized_quantity_search_level()); + jpaStorageSettings.setIndexOnContainedResources(appProperties.getEnable_index_contained_resource()); - if (appProperties.getAllowed_bundle_types() != null) { - jpaStorageSettings.setBundleTypesAllowedForStorage( - appProperties.getAllowed_bundle_types().stream().map(BundleType::toCode).collect(Collectors.toSet())); - } - jpaStorageSettings - .setDeferIndexingForCodesystemsOfSize(appProperties.getDefer_indexing_for_codesystems_of_size()); - if (appProperties.getClient_id_strategy() == JpaStorageSettings.ClientIdStrategyEnum.ANY) { - jpaStorageSettings.setResourceServerIdStrategy(JpaStorageSettings.IdStrategyEnum.UUID); - jpaStorageSettings.setResourceClientIdStrategy(appProperties.getClient_id_strategy()); - } - // Parallel Batch GET execution settings - jpaStorageSettings.setBundleBatchPoolSize(appProperties.getBundle_batch_pool_size()); - jpaStorageSettings.setBundleBatchPoolSize(appProperties.getBundle_batch_pool_max_size()); + if (appProperties.getAllowed_bundle_types() != null) { + jpaStorageSettings.setBundleTypesAllowedForStorage(appProperties.getAllowed_bundle_types().stream().map(BundleType::toCode).collect(Collectors.toSet())); + } - storageSettings(appProperties, jpaStorageSettings); - return jpaStorageSettings; + jpaStorageSettings.setDeferIndexingForCodesystemsOfSize(appProperties.getDefer_indexing_for_codesystems_of_size()); + + + if (appProperties.getClient_id_strategy() == JpaStorageSettings.ClientIdStrategyEnum.ANY) { + jpaStorageSettings.setResourceServerIdStrategy(JpaStorageSettings.IdStrategyEnum.UUID); + jpaStorageSettings.setResourceClientIdStrategy(appProperties.getClient_id_strategy()); + } + //Parallel Batch GET execution settings + jpaStorageSettings.setBundleBatchPoolSize(appProperties.getBundle_batch_pool_size()); + jpaStorageSettings.setBundleBatchPoolSize(appProperties.getBundle_batch_pool_max_size()); + + storageSettings(appProperties, jpaStorageSettings); + return jpaStorageSettings; + } + + @Bean + public YamlPropertySourceLoader yamlPropertySourceLoader() { + return new YamlPropertySourceLoader(); + } + + @Bean + public PartitionSettings partitionSettings(AppProperties appProperties) { + PartitionSettings retVal = new PartitionSettings(); + + // Partitioning + if (appProperties.getPartitioning() != null) { + retVal.setPartitioningEnabled(true); + retVal.setIncludePartitionInSearchHashes(appProperties.getPartitioning().getPartitioning_include_in_search_hashes()); + if(appProperties.getPartitioning().getAllow_references_across_partitions()) { + retVal.setAllowReferencesAcrossPartitions(CrossPartitionReferenceMode.ALLOWED_UNQUALIFIED); + } else { + retVal.setAllowReferencesAcrossPartitions(CrossPartitionReferenceMode.NOT_ALLOWED); + } + } + + return retVal; + } + + + @Primary + @Bean + public HibernatePropertiesProvider jpaStarterDialectProvider(LocalContainerEntityManagerFactoryBean myEntityManagerFactory) { + return new JpaHibernatePropertiesProvider(myEntityManagerFactory); + } + + + protected StorageSettings storageSettings(AppProperties appProperties, JpaStorageSettings jpaStorageSettings) { + jpaStorageSettings.setAllowContainsSearches(appProperties.getAllow_contains_searches()); + jpaStorageSettings.setAllowExternalReferences(appProperties.getAllow_external_references()); + jpaStorageSettings.setDefaultSearchParamsCanBeOverridden(appProperties.getAllow_override_default_search_params()); + if(appProperties.getSubscription() != null && appProperties.getSubscription().getEmail() != null) + jpaStorageSettings.setEmailFromAddress(appProperties.getSubscription().getEmail().getFrom()); + + jpaStorageSettings.setNormalizedQuantitySearchLevel(appProperties.getNormalized_quantity_search_level()); + + jpaStorageSettings.setIndexOnContainedResources(appProperties.getEnable_index_contained_resource()); + jpaStorageSettings.setIndexIdentifierOfType(appProperties.getEnable_index_of_type()); + return jpaStorageSettings; + } + + @Lazy + @Bean + public IBinaryStorageSvc binaryStorageSvc(AppProperties appProperties) { + DatabaseBlobBinaryStorageSvcImpl binaryStorageSvc = new DatabaseBlobBinaryStorageSvcImpl(); + + if (appProperties.getMax_binary_size() != null) { + binaryStorageSvc.setMaximumBinarySize(appProperties.getMax_binary_size()); + } + + return binaryStorageSvc; + } + + @Bean + public IEmailSender emailSender(AppProperties appProperties) { + if (appProperties.getSubscription() != null && appProperties.getSubscription().getEmail() != null) { + + return buildEmailSender(appProperties.getSubscription().getEmail()); + } + + // Return a dummy anonymous function instead of null. Spring does not like null beans. + // TODO Get the signature of ca.uhn.fhir.jpa.subscription.channel.subscription.SubscriptionDeliveryHandlerFactory + // changed so it does not require an instance of an IEmailSender + return theDetails -> {}; + } + + private static IEmailSender buildEmailSender(AppProperties.Subscription.Email email) { + + return new EmailSenderImpl(new MailSvc(new MailConfig() + .setSmtpHostname(email.getHost()) + .setSmtpPort(email.getPort()) + .setSmtpUsername(email.getUsername()) + .setSmtpPassword(email.getPassword()) + .setSmtpUseStartTLS(email.getStartTlsEnable()))); } - - @Bean - public YamlPropertySourceLoader yamlPropertySourceLoader() { - return new YamlPropertySourceLoader(); - } - - @Bean - public PartitionSettings partitionSettings(AppProperties appProperties) { - PartitionSettings retVal = new PartitionSettings(); - - // Partitioning - if (appProperties.getPartitioning() != null) { - retVal.setPartitioningEnabled(true); - retVal.setIncludePartitionInSearchHashes( - appProperties.getPartitioning().getPartitioning_include_in_search_hashes()); - if (appProperties.getPartitioning().getAllow_references_across_partitions()) { - retVal.setAllowReferencesAcrossPartitions(CrossPartitionReferenceMode.ALLOWED_UNQUALIFIED); - } else { - retVal.setAllowReferencesAcrossPartitions(CrossPartitionReferenceMode.NOT_ALLOWED); - } - } - - return retVal; - } - - @Primary - @Bean - public HibernatePropertiesProvider jpaStarterDialectProvider( - LocalContainerEntityManagerFactoryBean myEntityManagerFactory) { - return new JpaHibernatePropertiesProvider(myEntityManagerFactory); - } - - protected StorageSettings storageSettings(AppProperties appProperties, JpaStorageSettings jpaStorageSettings) { - jpaStorageSettings.setAllowContainsSearches(appProperties.getAllow_contains_searches()); - jpaStorageSettings.setAllowExternalReferences(appProperties.getAllow_external_references()); - jpaStorageSettings.setDefaultSearchParamsCanBeOverridden(appProperties.getAllow_override_default_search_params()); - if (appProperties.getSubscription() != null && appProperties.getSubscription().getEmail() != null) - jpaStorageSettings.setEmailFromAddress(appProperties.getSubscription().getEmail().getFrom()); - - jpaStorageSettings.setNormalizedQuantitySearchLevel(appProperties.getNormalized_quantity_search_level()); - - jpaStorageSettings.setIndexOnContainedResources(appProperties.getEnable_index_contained_resource()); - jpaStorageSettings.setIndexIdentifierOfType(appProperties.getEnable_index_of_type()); - return jpaStorageSettings; - } - - @Lazy - @Bean - public IBinaryStorageSvc binaryStorageSvc(AppProperties appProperties) { - DatabaseBlobBinaryStorageSvcImpl binaryStorageSvc = new DatabaseBlobBinaryStorageSvcImpl(); - - if (appProperties.getMax_binary_size() != null) { - binaryStorageSvc.setMaximumBinarySize(appProperties.getMax_binary_size()); - } - - return binaryStorageSvc; - } - - @Bean - public IEmailSender emailSender(AppProperties appProperties) { - if (appProperties.getSubscription() != null && appProperties.getSubscription().getEmail() != null) { - MailConfig mailConfig = new MailConfig(); - - AppProperties.Subscription.Email email = appProperties.getSubscription().getEmail(); - mailConfig.setSmtpHostname(email.getHost()); - mailConfig.setSmtpPort(email.getPort()); - mailConfig.setSmtpUsername(email.getUsername()); - mailConfig.setSmtpPassword(email.getPassword()); - mailConfig.setSmtpUseStartTLS(email.getStartTlsEnable()); - - IMailSvc mailSvc = new MailSvc(mailConfig); - IEmailSender emailSender = new EmailSenderImpl(mailSvc); - - return emailSender; - } - - return null; - } - - } diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index c065191..a47434d 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -81,14 +81,13 @@ hapi: # server_address: http://hapi.fhir.org/baseR4 # defer_indexing_for_codesystems_of_size: 101 # install_transitive_ig_dependencies: true - ### tells the server whether to attempt to load IG resources that are already present - # reload_existing_implementationGuides : false #implementationguides: ### example from registry (packages.fhir.org) # swiss: # name: swiss.mednet.fhir # version: 0.8.0 - # reloadExisting : false + # reloadExisting: false + # installMode: STORE_AND_INSTALL # example not from registry # ips_1_0_0: # packageUrl: https://build.fhir.org/ig/HL7/fhir-ips/package.tgz