diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | Dockerfile | 36 | ||||
| -rw-r--r-- | HealthCheck.java | 20 | ||||
| -rw-r--r-- | README.md | 21 | ||||
| -rw-r--r-- | build.gradle.kts | 10 | ||||
| -rw-r--r-- | deploy/docker-compose.yaml | 27 | ||||
| -rw-r--r-- | deploy/env-sample.env | 44 |
7 files changed, 153 insertions, 6 deletions
@@ -36,3 +36,4 @@ out/ ### VS Code ### .vscode/ /dev/gpas* +/deploy/.env diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..2d38c6a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,36 @@ +FROM gradle:8.1-jdk17 AS build +WORKDIR /home/gradle/src +ENV GRADLE_USER_HOME /gradle + +COPY build.gradle.kts settings.gradle.kts ./ + +COPY --chown=gradle:gradle . . +RUN gradle build --info && \ + java -Djarmode=layertools -jar build/libs/*.jar extract + +FROM gcr.io/distroless/java17:nonroot +WORKDIR /opt/kafka-streams-template +COPY --from=build /home/gradle/src/dependencies/ ./ +COPY --from=build /home/gradle/src/spring-boot-loader/ ./ +COPY --from=build /home/gradle/src/application/ ./ +COPY HealthCheck.java . + +USER nonroot +ARG GIT_REF="" +ARG GIT_URL="" +ARG BUILD_TIME="" +ARG VERSION=0.0.0 +ENV APP_VERSION=${VERSION} \ + SPRING_PROFILES_ACTIVE="prod" +ENTRYPOINT ["java", "-XX:MaxRAMPercentage=90", "org.springframework.boot.loader.JarLauncher"] + +HEALTHCHECK --interval=25s --timeout=3s --retries=2 CMD ["java", "HealthCheck.java", "||", "exit", "1"] + +LABEL org.opencontainers.image.created=${BUILD_TIME} \ + org.opencontainers.image.authors="Paul-Chrisitan Volkmer, Jakub Lidke" \ + org.opencontainers.image.source=${GIT_URL} \ + org.opencontainers.image.version=${VERSION} \ + org.opencontainers.image.revision=${GIT_REF} \ + org.opencontainers.image.vendor="" \ + org.opencontainers.image.title="etl-processor" \ + org.opencontainers.image.description="Relay application between Onkostar and bwHc for pseudonymization or anonymization of patient data and profide additional monitoring of processed data." diff --git a/HealthCheck.java b/HealthCheck.java new file mode 100644 index 0000000..0aac2a6 --- /dev/null +++ b/HealthCheck.java @@ -0,0 +1,20 @@ +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse.BodyHandlers; + +public class HealthCheck { + + public static void main(String[] args) throws InterruptedException, IOException { + var client = HttpClient.newHttpClient(); + var request = HttpRequest.newBuilder() + .uri(URI.create("http://localhost:8001/actuator/health")) + .header("accept", "application/json") + .build(); + var response = client.send(request, BodyHandlers.ofString()); + if (response.statusCode() != 200 || !response.body().contains("UP")) { + throw new RuntimeException("Healthcheck failed"); + } + } +}
\ No newline at end of file @@ -26,7 +26,7 @@ Siehe hierzu auch: https://github.com/CCC-MF/kafka-to-bwhc ## Pseudonymisierung der Patienten-ID -Wenn eine URI zu einer gPAS-Instanz angegeben ist, wird diese verwendet. +Wenn eine URI zu einer gPAS-Instanz (Version >= 2023.1.0) angegeben ist, wird diese verwendet. Ist diese nicht gesetzt. wird intern eine Anonymisierung der Patienten-ID vorgenommen. * `APP_PSEUDONYMIZE_PREFIX`: Standortbezogenes Prefix - `UNKNOWN`, wenn nicht gesetzt @@ -42,7 +42,8 @@ als Patienten-Pseudonym verwendet. Wurde die Verwendung von gPAS konfiguriert, so sind weitere Angaben zu konfigurieren. -* `APP_PSEUDONYMIZE_GPAS_URI`: URI der gPAS-Instanz inklusive Endpoint (z.B. `http://localhost:8080/ttp-fhir/fhir/gpas/$pseudonymizeAllowCreate`) +* `APP_PSEUDONYMIZE_GPAS_URI`: URI der gPAS-Instanz inklusive Endpoint ( + z.B. `http://localhost:8080/ttp-fhir/fhir/gpas/$pseudonymizeAllowCreate`) * `APP_PSEUDONYMIZE_GPAS_TARGET`: gPas Domänenname * `APP_PSEUDONYMIZE_GPAS_USERNAME`: gPas Basic-Auth Benutzername * `APP_PSEUDONYMIZE_GPAS_PASSWORD`: gPas Basic-Auth Passwort @@ -120,6 +121,22 @@ ein Consent-Widerspruch erfolgte. Diese Anwendung ist auch als Docker-Image verfügbar: https://github.com/CCC-MF/etl-processor/pkgs/container/etl-processor +### Images lokal bauen + +```bash +docker build . -t "imageName" +``` + +## Deployment +*Ausführen als Docker Conatiner:* +Wenn gewünscht, Änderungen in der `env` vornehmen. Beachten, dass *MONITORING_HTTP_PORT* über +Host-Umgebung gesetzt werden muss (z.B. .env oder Parameter --env-file ) + +```bash +cd ./deploy +docker compose up -d +``` + ## Entwicklungssetup Zum Starten einer lokalen Entwicklungs- und Testumgebung kann die beiliegende Datei `dev-compose.yml` verwendet werden. diff --git a/build.gradle.kts b/build.gradle.kts index 8eee6d0..d8389e6 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,9 +3,8 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.springframework.boot.gradle.tasks.bundling.BootBuildImage plugins { - war - id("org.springframework.boot") version "3.1.2" - id("io.spring.dependency-management") version "1.1.3" + id("org.springframework.boot") version "3.1.1" + id("io.spring.dependency-management") version "1.1.0" kotlin("jvm") version "1.9.0" kotlin("plugin.spring") version "1.9.0" } @@ -49,6 +48,10 @@ repositories { mavenCentral() } +tasks.getByName<Jar>("jar") { + enabled = false +} + dependencies { implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("org.springframework.boot:spring-boot-starter-thymeleaf") @@ -68,7 +71,6 @@ dependencies { developmentOnly("org.springframework.boot:spring-boot-devtools") developmentOnly("org.springframework.boot:spring-boot-docker-compose") annotationProcessor("org.springframework.boot:spring-boot-configuration-processor") - providedRuntime("org.springframework.boot:spring-boot-starter-tomcat") testImplementation("org.springframework.boot:spring-boot-starter-test") testImplementation("io.projectreactor:reactor-test") testImplementation("org.mockito.kotlin:mockito-kotlin:${versions["mockito-kotlin"]}") diff --git a/deploy/docker-compose.yaml b/deploy/docker-compose.yaml new file mode 100644 index 0000000..8dccd4c --- /dev/null +++ b/deploy/docker-compose.yaml @@ -0,0 +1,27 @@ + + +services: + dnpm-etl-processor: + image: dnpm-elt-processor:latest + env_file: + - ./env-sample.env + depends_on: + - db + networks: + - dnpm_processor + ports: + - "${MONITORING_HTTP_PORT:-8080}:8080" + + db: + image: mariadb:10 + environment: + MARIADB_DATABASE: dev + MARIADB_USER: dev + MARIADB_PASSWORD: dev + MARIADB_ROOT_PASSWORD: dev + expose: + - "3306" + networks: + - dnpm_processor +networks: + dnpm_processor: {} diff --git a/deploy/env-sample.env b/deploy/env-sample.env new file mode 100644 index 0000000..1589096 --- /dev/null +++ b/deploy/env-sample.env @@ -0,0 +1,44 @@ +# monitoring access port +MONITORING_HTTP_PORT=8088 + +# GPAS or BUILDIN +APP_PSEUDONYMIZE_GENERATOR=BUILDIN +APP_PSEUDONYMIZE_PREFIX= +APP_PSEUDONYMIZE_GPAS_URI= +APP_PSEUDONYMIZE_GPAS_TARGET= +APP_PSEUDONYMIZE_GPAS_USERNAME= +APP_PSEUDONYMIZE_GPAS_PASSWORD= + +# path to ca root cert if needed +APP_PSEUDONYMIZE_GPAS_SSLCALOCATION= + +# monitoring data db +SPRING_DATASOURCE_URL:jdbc:mariadb://db:3306/dev +SPRING_DATASOURCE_PASSWORD: dev +SPRING_DATASOURCE_USERNAME: dev + +## TARGET SYSTEMS CONFIG +# DIRECT BWHC +# in case of direct access to bwhc enter endpoint url here +APP_REST_URI= + +## Apache KAFKA +# list of broker instances +APP_KAFKA_SERVERS= + +# produce mtb files to this topic +APP_KAFKA_TOPIC=mtb-file-json + +# here we receive responses from bwhc +APP_KAFKA_RESPONSE_TOPIC= +APP_KAFKA_GROUP_ID=dnpm + +# SSL or PLAINTEXT +SPRING_KAFKA_SECURITY_PROTOCOL=PLAINTEXT +SPRING_KAFKA_SSL_TRUST-STORE-TYPE=PKCS12 +SPRING_KAFKA_SSL_TRUST-STORE-LOCATION=file://opt/kafka-certs/ca.p12} +SPRING_KAFKA_SSL_TRUST-STORE-PASSWORD= +SPRING_KAFKA_SSL_KEY-STORE-TYPE=PKCS12 +SPRING_KAFKA_SSL_KEY-STORE-LOCATION=file://opt/kafka-certs/user.p12} +SPRING_KAFKA_SSL_KEY-STORE-PASSWORD= +SPRING_KAFKA_PRODUCER_COMPRESSION-TYPE: gzip |
