Skip to content

Commit

Permalink
merged feature/hapi-fhir-jpaserver-starter-6.10.1
Browse files Browse the repository at this point in the history
  • Loading branch information
OHSUCMP committed Sep 25, 2024
2 parents f6fe7a0 + cb2b9e3 commit 6397064
Show file tree
Hide file tree
Showing 114 changed files with 178,691 additions and 4,079 deletions.
12 changes: 6 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FROM maven:3.8-openjdk-17-slim 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.17.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 .
Expand All @@ -12,13 +12,13 @@ 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


########### 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 && \
Expand All @@ -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.
Expand All @@ -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

CMD ["/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"]
177 changes: 154 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# eCare Plan - Supplemental Data Store (ecp-sds)

This project is hard-forked from the [HAPI FHIR JPA Server Starter Project v6.4.0](https://github.com/hapifhir/hapi-fhir-jpaserver-starter/tree/v6.4.0).
This project is hard-forked from the [HAPI FHIR JPA Server Starter Project v6.10.1](https://github.com/hapifhir/hapi-fhir-jpaserver-starter/tree/image/v6.10.1).

The following documentation is the same as what can be found for the JPA Server Starter project README.md, with modifications applied as required to build for the ecp-sds.

Expand Down Expand Up @@ -64,28 +64,133 @@ docker run -p 8090:8080 -e "--spring.config.location=classpath:/another.applicat
```
Here, the configuration file (*another.application.yaml*) is part of the compiled set of resources.

### Example using docker-compose.yml for docker-compose
### Example using ``docker-compose.yml`` for docker-compose

```
```yaml
version: '3.7'

services:
web:
fhir:
container_name: fhir
image: "hapiproject/hapi:latest"
ports:
- "8090:8080"
- "8080:8080"
configs:
- source: hapi
target: /data/hapi/application.yaml
target: /app/config/application.yaml
depends_on:
- db


db:
image: postgres
restart: always
environment:
POSTGRES_PASSWORD: admin
POSTGRES_USER: admin
POSTGRES_DB: hapi
volumes:
- hapi-data:/data/hapi
- ./hapi.postgress.data:/var/lib/postgresql/data

configs:
hapi:
file: ./hapi.application.yaml
```
Provide the following content in ``./hapi.aplication.yaml``:
```yaml
spring:
datasource:
url: 'jdbc:postgresql://db:5432/hapi'
username: admin
password: admin
driverClassName: org.postgresql.Driver
jpa:
properties:
hibernate.dialect: ca.uhn.fhir.jpa.model.dialect.HapiFhirPostgres94Dialect
hibernate.search.enabled: false
```
### Example running custom interceptor using docker-compose
This example is an extension of the above one, now adding a custom interceptor.
```yaml
version: '3.7'

services:
fhir:
container_name: fhir
image: "hapiproject/hapi:latest"
ports:
- "8080:8080"
configs:
- source: hapi
target: /app/config/application.yaml
- source: hapi-extra-classes
target: /app/extra-classes
depends_on:
- db

db:
image: postgres
restart: always
environment:
SPRING_CONFIG_LOCATION: 'file:///data/hapi/application.yaml'
POSTGRES_PASSWORD: admin
POSTGRES_USER: admin
POSTGRES_DB: hapi
volumes:
- ./hapi.postgress.data:/var/lib/postgresql/data

configs:
hapi:
external: true
volumes:
hapi-data:
external: true
file: ./hapi.application.yaml
hapi-extra-classes:
file: ./hapi-extra-classes
```
Provide the following content in ``./hapi.aplication.yaml``:
```yaml
spring:
datasource:
url: 'jdbc:postgresql://db:5432/hapi'
username: admin
password: admin
driverClassName: org.postgresql.Driver
jpa:
properties:
hibernate.dialect: ca.uhn.fhir.jpa.model.dialect.HapiFhirPostgres94Dialect
hibernate.search.enabled: false
hapi:
fhir:
custom-bean-packages: the.package.containing.your.interceptor
custom-interceptor-classes: the.package.containing.your.interceptor.YourInterceptor
```
The basic interceptor structure would be like this:
```java
package the.package.containing.your.interceptor;

import org.hl7.fhir.instance.model.api.IBaseResource;
import org.springframework.stereotype.Component;

import ca.uhn.fhir.interceptor.api.Hook;
import ca.uhn.fhir.interceptor.api.Interceptor;
import ca.uhn.fhir.interceptor.api.Pointcut;

@Component
@Interceptor
public class YourInterceptor
{
@Hook(Pointcut.STORAGE_PRECOMMIT_RESOURCE_CREATED)
public void resourceCreated(IBaseResource newResource)
{
System.out.println("YourInterceptor.resourceCreated");
}
}
```

## Running locally
Expand Down Expand Up @@ -136,7 +241,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:
Expand All @@ -151,7 +256,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:
Expand All @@ -167,7 +272,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:
Expand Down Expand Up @@ -208,7 +313,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

Expand All @@ -223,26 +328,26 @@ 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.
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.

## Adding custom interceptors
Custom interceptors can be registered with the server by including the property `hapi.fhir.custom-interceptor-classes`. This will take a comma separated list of fully-qualified class names which will be registered with the server.
Interceptors will be discovered in one of two ways:
Custom interceptors can be registered with the server by including the property `hapi.fhir.custom-interceptor-classes`. This will take a comma separated list of fully-qualified class names which will be registered with the server.
Interceptors will be discovered in one of two ways:

1) discovered from the Spring application context as existing Beans (can be used in conjunction with `hapi.fhir.custom-bean-packages`) or registered with Spring via other methods

or
or

2) classes will be instantiated via reflection if no matching Bean is found

Expand Down Expand Up @@ -274,7 +379,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.

Expand All @@ -291,7 +396,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/.

Expand Down Expand Up @@ -416,6 +521,32 @@ To add a custom operation, refer to the documentation in the core hapi-fhir libr

Within `hapi-fhir-jpaserver-starter`, create a generic class (that does not extend or implement any classes or interfaces), add the `@Operation` as a method within the generic class, and then register the class as a provider using `RestfulServer.registerProvider()`.

## Runtime package install

It's possible to install a FHIR Implementation Guide package (`package.tgz`) either from a published package or from a local package with the `$install` operation, without having to restart the server. This is available for R4 and R5.

This feature must be enabled in the application.yaml (or docker command line):

```yaml
hapi:
fhir:
ig_runtime_upload_enabled: true
```

The `$install` operation is triggered with a POST to `[server]/ImplementationGuide/$install`, with the payload below:

```json
{
"resourceType": "Parameters",
"parameter": [
{
"name": "npmContent",
"valueBase64Binary": "[BASE64_ENCODED_NPM_PACKAGE_DATA]"
}
]
}
```

## Enable OpenTelemetry auto-instrumentation

The container image includes the [OpenTelemetry Java auto-instrumentation](https://github.com/open-telemetry/opentelemetry-java-instrumentation)
Expand Down
8 changes: 4 additions & 4 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: 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"
20 changes: 12 additions & 8 deletions charts/hapi-fhir-jpaserver/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,21 @@ 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.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: changed
description: updated HAPI FHIR JPA Server app image version to v6.2.2
- kind: changed
description: updated curl used by helm tests to version to v7.87.0
- kind: added
description: updated starter image to 6.8.3
- kind: fixed
description: incorrect handling of existing secret database config
- kind: added
description: support for using a non-admin user for the postgres database
- kind: added
description: ability to create a dedicated ServiceAccount
Loading

0 comments on commit 6397064

Please sign in to comment.