Skip to content

Commit

Permalink
Merge commit '2daf365bdf0c6826bb0ebd3cbe12110877584dad' into rel_6_0_1
Browse files Browse the repository at this point in the history
# Conflicts:
#	pom.xml
  • Loading branch information
jkiddo committed Jun 2, 2022
2 parents 089ea5c + 2daf365 commit bc4c221
Show file tree
Hide file tree
Showing 27 changed files with 858 additions and 100 deletions.
24 changes: 12 additions & 12 deletions .github/workflows/build-images.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,24 @@ jobs:
name: Build
runs-on: ubuntu-20.04
steps:
- name: Docker meta
- name: Container meta for default (distroless) image
id: docker_meta
uses: docker/metadata-action@v3
with:
images: ${{ env.IMAGES }}
tags: |
type=match,pattern=image-(.*),group=1,enable=${{github.event_name != 'pull_request'}}
type=sha
- name: Docker distroless meta
id: docker_distroless_meta
- name: Container meta for tomcat image
id: docker_tomcat_meta
uses: docker/metadata-action@v3
with:
images: ${{ env.IMAGES }}
tags: |
type=match,pattern=image-(.*),group=1,enable=${{github.event_name != 'pull_request'}}
type=sha
flavor: |
suffix=-distroless,onlatest=true
suffix=-tomcat,onlatest=true
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
Expand All @@ -60,7 +59,7 @@ jobs:
restore-keys: |
${{ runner.os }}-buildx-
- name: Build and push
- name: Build and push default (distroless) image
id: docker_build
uses: docker/build-push-action@v2
with:
Expand All @@ -70,15 +69,16 @@ jobs:
tags: ${{ steps.docker_meta.outputs.tags }}
labels: ${{ steps.docker_meta.outputs.labels }}
platforms: ${{ env.PLATFORMS }}
target: default

- name: Build and push distroless
id: docker_build_distroless
- name: Build and push tomcat image
id: docker_build_tomcat
uses: docker/build-push-action@v2
with:
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.docker_distroless_meta.outputs.tags }}
labels: ${{ steps.docker_distroless_meta.outputs.labels }}
tags: ${{ steps.docker_tomcat_meta.outputs.tags }}
labels: ${{ steps.docker_tomcat_meta.outputs.labels }}
platforms: ${{ env.PLATFORMS }}
target: release-distroless
target: tomcat
40 changes: 25 additions & 15 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,33 +1,43 @@
FROM maven:3.8.2-jdk-11-slim as build-hapi
FROM maven:3.8-openjdk-17-slim as build-hapi
WORKDIR /tmp/hapi-fhir-jpaserver-starter

COPY pom.xml .
COPY server.xml .
RUN mvn -ntp dependency:go-offline

COPY src/ /tmp/hapi-fhir-jpaserver-starter/src/
RUN mvn clean install -DskipTests
RUN mvn clean install -DskipTests -Djdk.lang.Process.launchMechanism=vfork

FROM build-hapi AS build-distroless
RUN mvn package spring-boot:repackage -Pboot
RUN mkdir /app && \
cp /tmp/hapi-fhir-jpaserver-starter/target/ROOT.war /app/main.war
RUN mkdir /app && cp /tmp/hapi-fhir-jpaserver-starter/target/ROOT.war /app/main.war

FROM gcr.io/distroless/java-debian11:11 AS release-distroless

########### 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

RUN rm -rf /opt/bitnami/tomcat/webapps/ROOT && \
rm -rf /opt/bitnami/tomcat/webapps_default/ROOT && \
mkdir -p /opt/bitnami/hapi/data/hapi/lucenefiles && \
chmod 775 /opt/bitnami/hapi/data/hapi/lucenefiles

USER root
RUN mkdir -p /target && chown -R 1001:1001 target
USER 1001

COPY --chown=1001:1001 catalina.properties /opt/bitnami/tomcat/conf/catalina.properties
COPY --chown=1001:1001 server.xml /opt/bitnami/tomcat/conf/server.xml
COPY --from=build-hapi --chown=1001:1001 /tmp/hapi-fhir-jpaserver-starter/target/ROOT.war /opt/bitnami/tomcat/webapps_default/ROOT.war

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:nonroot as default
COPY --chown=nonroot:nonroot --from=build-distroless /app /app
# 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.
USER 65532:65532
WORKDIR /app
CMD ["/app/main.war"]

FROM tomcat:9.0.53-jdk11-openjdk-slim-bullseye

RUN mkdir -p /data/hapi/lucenefiles && chmod 775 /data/hapi/lucenefiles
COPY --from=build-hapi /tmp/hapi-fhir-jpaserver-starter/target/*.war /usr/local/tomcat/webapps/

COPY catalina.properties /usr/local/tomcat/conf/catalina.properties
COPY server.xml /usr/local/tomcat/conf/server.xml

CMD ["catalina.sh", "run"]
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,13 @@ spring:
password: admin
driverClassName: com.mysql.jdbc.Driver
```
Also, make sure you are not setting the Hibernate dialect explicitly, in other words remove any lines similar to:
```
hibernate.dialect: {some none MySQL dialect}
```
On some systems, it might be necessary to override hibernate's default naming strategy. The naming strategy must be set using spring.jpa.hibernate.physical_naming_strategy.
```yaml
Expand All @@ -215,6 +222,26 @@ spring:

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.

### Microsoft SQL Server configuration

To configure the starter app to use MS SQL Server, instead of the default H2, update the application.yaml file to have the following:

```yaml
spring:
datasource:
url: 'jdbc:sqlserver://<server>:<port>;databaseName=<databasename>'
username: admin
password: admin
driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
```


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.


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.
It is recommended to deploy a case-sensitive database prior to running HAPI FHIR when using MS SQL Server to avoid these and potentially other issues.

## Customizing The Web Testpage UI

The UI that comes with this server is an exact clone of the server available at [http://hapi.fhir.org](http://hapi.fhir.org). You may skin this UI if you'd like. For example, you might change the introductory text or replace the logo with your own.
Expand Down Expand Up @@ -279,6 +306,8 @@ spring:
driverClassName: com.mysql.jdbc.Driver
```

Also, make sure you are not setting the Hibernate Dialect explicitly, see more details in the section about MySQL.

## Running hapi-fhir-jpaserver directly from IntelliJ as Spring Boot
Make sure you run with the maven profile called ```boot``` and NOT also ```jetty```. Then you are ready to press debug the project directly without any extra Application Servers.

Expand Down
6 changes: 3 additions & 3 deletions charts/hapi-fhir-jpaserver/Chart.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
dependencies:
- name: postgresql
repository: https://charts.bitnami.com/bitnami
version: 10.12.2
digest: sha256:38ee315eae1af3e3f6eb20e1dd8ffd60d4ab7ee0c51bf26941b56c8bcb376c11
generated: "2021-10-07T00:19:18.9743522+02:00"
version: 11.1.19
digest: sha256:5bb38230bfa62c63547851e6f46f66a61441a4a4f18e3689827546277e34d192
generated: "2022-04-08T21:55:34.6868891+02:00"
17 changes: 10 additions & 7 deletions charts/hapi-fhir-jpaserver/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,23 @@ sources:
- https://github.com/hapifhir/hapi-fhir-jpaserver-starter
dependencies:
- name: postgresql
version: 10.12.2
version: 11.1.19
repository: https://charts.bitnami.com/bitnami
condition: postgresql.enabled
annotations:
artifacthub.io/license: Apache-2.0
artifacthub.io/prerelease: "true"
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 starter image to 5.6.0
- kind: added
updated HAPI FHIR starter image to 5.7.0
- kind: changed
description: |
BREAKING CHANGE: updated included PostgreSQL-subchart to v11
- kind: changed
description: |
added support for configuring PodDisruptionBudget for the server pods
appVersion: v5.6.0
version: 0.7.0
BREAKING CHANGE: removed ability to override the image flavor.
The one based on distroless is now the new default.
appVersion: v5.7.0
version: 0.8.0
13 changes: 6 additions & 7 deletions charts/hapi-fhir-jpaserver/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# HAPI FHIR JPA Server Starter Helm Chart

![Version: 0.7.0](https://img.shields.io/badge/Version-0.7.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v5.6.0](https://img.shields.io/badge/AppVersion-v5.6.0-informational?style=flat-square)
![Version: 0.8.0](https://img.shields.io/badge/Version-0.8.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v5.7.0](https://img.shields.io/badge/AppVersion-v5.7.0-informational?style=flat-square)

This helm chart will help you install the HAPI FHIR JPA Server in a Kubernetes environment.

Expand Down Expand Up @@ -29,11 +29,10 @@ helm install --render-subchart-notes hapi-fhir-jpaserver hapifhir/hapi-fhir-jpas
| externalDatabase.user | string | `"fhir"` | username for the external database |
| extraEnv | list | `[]` | extra environment variables to set on the server container |
| fullnameOverride | string | `""` | override the chart fullname |
| image.flavor | string | `"distroless"` | the flavor or variant of the image to use. appended to the image tag by `-`. |
| 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 | `""` | defaults to `Chart.appVersion` |
| image.tag | string | `""` | defaults to `Chart.appVersion`. As of v5.7.0, this is the `distroless` flavor |
| 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 |
Expand All @@ -51,11 +50,11 @@ helm install --render-subchart-notes hapi-fhir-jpaserver hapifhir/hapi-fhir-jpas
| podDisruptionBudget.maxUnavailable | string | `""` | maximum unavailable instances |
| podDisruptionBudget.minAvailable | int | `1` | minimum available instances |
| podSecurityContext | object | `{}` | pod security context |
| postgresql.containerSecurityContext.allowPrivilegeEscalation | bool | `false` | |
| postgresql.containerSecurityContext.capabilities.drop[0] | string | `"ALL"` | |
| postgresql.auth.database | string | `"fhir"` | name for a custom database to create |
| postgresql.auth.existingSecret | string | `""` | Name of existing secret to use for PostgreSQL credentials `auth.postgresPassword`, `auth.password`, and `auth.replicationPassword` will be ignored and picked up from this secret The secret must contain the keys `postgres-password` (which is the password for "postgres" admin user), `password` (which is the password for the custom user to create when `auth.username` is set), and `replication-password` (which is the password for replication user). The secret might also contains the key `ldap-password` if LDAP is enabled. `ldap.bind_password` will be ignored and picked from this secret in this case. The value is evaluated as a template. |
| postgresql.enabled | bool | `true` | enable an included PostgreSQL DB. see <https://github.com/bitnami/charts/tree/master/bitnami/postgresql> for details if set to `false`, the values under `externalDatabase` are used |
| postgresql.existingSecret | string | `""` | Name of existing secret to use for PostgreSQL passwords. The secret has to contain the keys `postgresql-password` which is the password for `postgresqlUsername` when it is different of `postgres`, `postgresql-postgres-password` which will override `postgresqlPassword`, `postgresql-replication-password` which will override `replication.password` and `postgresql-ldap-password` which will be sed to authenticate on LDAP. The value is evaluated as a template. |
| postgresql.postgresqlDatabase | string | `"fhir"` | name of the database to create see: <https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md#creating-a-database-on-first-run> |
| postgresql.primary.containerSecurityContext.allowPrivilegeEscalation | bool | `false` | |
| postgresql.primary.containerSecurityContext.capabilities.drop[0] | string | `"ALL"` | |
| readinessProbe.failureThreshold | int | `5` | |
| readinessProbe.initialDelaySeconds | int | `30` | |
| readinessProbe.periodSeconds | int | `20` | |
Expand Down
6 changes: 6 additions & 0 deletions charts/hapi-fhir-jpaserver/ci/enabled-ingress-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
ingress:
enabled: true

postgresql:
auth:
postgresPassword: secretpassword
24 changes: 6 additions & 18 deletions charts/hapi-fhir-jpaserver/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,6 @@ Create chart name and version as used by the chart label.
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create image tag
*/}}
{{- define "hapi-fhir-jpaserver.imageTag" -}}
{{- $version := default .Chart.AppVersion .Values.image.tag -}}
{{- if .Values.image.flavor }}
{{- printf "%s-%s" $version .Values.image.flavor }}
{{- else }}
{{- printf "%s" $version }}
{{- end }}
{{- end }}

{{/*
Common labels
*/}}
Expand Down Expand Up @@ -75,10 +63,10 @@ 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.existingSecret) -}}
{{- 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.existingSecret) -}}
{{- printf "%s" .Values.postgresql.existingSecret -}}
{{- else if and (.Values.postgresql.enabled) (.Values.postgresql.auth.existingSecret) -}}
{{- printf "%s" .Values.postgresql.auth.existingSecret -}}
{{- else }}
{{- if .Values.externalDatabase.existingSecret -}}
{{- printf "%s" .Values.externalDatabase.existingSecret -}}
Expand All @@ -95,7 +83,7 @@ Get the Postgresql credentials secret key.
{{- if (.Values.externalDatabase.existingSecret) -}}
{{- printf "%s" .Values.externalDatabase.existingSecretKey -}}
{{- else }}
{{- printf "postgresql-password" -}}
{{- printf "postgres-password" -}}
{{- end -}}
{{- end -}}

Expand All @@ -110,14 +98,14 @@ Add environment variables to configure database values
Add environment variables to configure database values
*/}}
{{- define "hapi-fhir-jpaserver.database.user" -}}
{{- ternary .Values.postgresql.postgresqlUsername .Values.externalDatabase.user .Values.postgresql.enabled -}}
{{- ternary "postgres" .Values.externalDatabase.user .Values.postgresql.enabled -}}
{{- end -}}

{{/*
Add environment variables to configure database values
*/}}
{{- define "hapi-fhir-jpaserver.database.name" -}}
{{- ternary .Values.postgresql.postgresqlDatabase .Values.externalDatabase.database .Values.postgresql.enabled -}}
{{- ternary .Values.postgresql.auth.database .Values.externalDatabase.database .Values.postgresql.enabled -}}
{{- end -}}

{{/*
Expand Down
8 changes: 3 additions & 5 deletions charts/hapi-fhir-jpaserver/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ spec:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: {{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ include "hapi-fhir-jpaserver.imageTag" . }}
image: {{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ default .Chart.AppVersion .Values.image.tag }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
Expand Down Expand Up @@ -102,12 +102,10 @@ spec:
key: {{ include "hapi-fhir-jpaserver.postgresql.secretKey" . }}
- name: SPRING_DATASOURCE_DRIVERCLASSNAME
value: org.postgresql.Driver
- name: SPRING_JPA_PROPERTIES_HIBERNATE_DIALECT
value: org.hibernate.dialect.PostgreSQL10Dialect
- name: spring.jpa.properties.hibernate.dialect
value: ca.uhn.fhir.jpa.model.dialect.HapiFhirPostgres94Dialect
- name: HAPI_FHIR_USE_APACHE_ADDRESS_STRATEGY
value: "true"
- name: SPRING_JPA_DATABASE_PLATFORM
value: org.hibernate.dialect.PostgreSQLDialect
{{- if .Values.extraEnv }}
{{ toYaml .Values.extraEnv | nindent 12 }}
{{- end }}
Expand Down
4 changes: 2 additions & 2 deletions charts/hapi-fhir-jpaserver/templates/externaldb-secret.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{- if and (not .Values.postgresql.enabled) (not .Values.externalDatabase.existingSecret) (not .Values.postgresql.existingSecret) }}
{{- if and (not .Values.postgresql.enabled) (not .Values.externalDatabase.existingSecret) (not .Values.postgresql.auth.existingSecret) }}
apiVersion: v1
kind: Secret
metadata:
Expand All @@ -7,5 +7,5 @@ metadata:
{{- include "hapi-fhir-jpaserver.labels" . | nindent 4 }}
type: Opaque
data:
postgresql-password: {{ .Values.externalDatabase.password | b64enc | quote }}
postgres-password: {{ .Values.externalDatabase.password | b64enc | quote }}
{{- end }}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "hapi-fhir-jpaserver.fullname" . }}-test-connection"
name: "{{ include "hapi-fhir-jpaserver.fullname" . }}-test-endpoints"
labels:
{{- include "hapi-fhir-jpaserver.labels" . | nindent 4 }}
{{ include "hapi-fhir-jpaserver.fullname" . }}-client: "true"
Expand All @@ -10,7 +10,32 @@ metadata:
spec:
restartPolicy: Never
containers:
- name: wget
- name: test-metadata-endpoint
image: busybox:1
command: ['wget', '-O', '-']
args: ['http://{{ include "hapi-fhir-jpaserver.fullname" . }}:{{ .Values.service.port }}/fhir/metadata']
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsUser: 22222
runAsNonRoot: true
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
livenessProbe:
exec:
command: ["true"]
readinessProbe:
exec:
command: ["true"]
- name: test-patient-endpoint
image: busybox:1
command: ['wget', '-O', '-']
args: ['http://{{ include "hapi-fhir-jpaserver.fullname" . }}:{{ .Values.service.port }}/fhir/Patient?_count=1']
Expand Down
Loading

0 comments on commit bc4c221

Please sign in to comment.