Merge pull request #921 from hapifhir/health-check
Standalone Java Health Check & Hibernate Dialect Override Fix
This commit is contained in:
@@ -15,6 +15,9 @@ FROM build-hapi AS build-distroless
|
||||
RUN mvn package -DskipTests spring-boot:repackage -Pboot
|
||||
RUN mkdir /app && cp /tmp/hapi-fhir-jpaserver-starter/target/ROOT.war /app/main.war
|
||||
|
||||
COPY src/main/java/HealthCheck.java /app/HealthCheck.java
|
||||
RUN javac /app/HealthCheck.java
|
||||
|
||||
|
||||
########### Use the official Tomcat image as base image for the Tomcat variant
|
||||
########### it can be built using eg. `docker build --target tomcat .`
|
||||
|
||||
14
README.md
14
README.md
@@ -475,6 +475,20 @@ jpa:
|
||||
# Then comment all hibernate.search.backend.*
|
||||
```
|
||||
|
||||
## Docker Health Check
|
||||
|
||||
The distroless Docker image includes a built-in health check that verifies the FHIR server is operational by calling the `/fhir/metadata` endpoint and confirming a valid `CapabilityStatement` is returned. It uses a standalone Java class with no external dependencies, making it compatible with the distroless base image which has no shell or utilities like `curl`.
|
||||
|
||||
To run the health check inside a running container:
|
||||
|
||||
```
|
||||
docker exec hapi-fhir-jpaserver-start java -cp /app HealthCheck
|
||||
```
|
||||
|
||||
An exit code of `0` indicates the server is healthy. An exit code of `1` indicates a failure, with diagnostic details written to stderr.
|
||||
|
||||
To enable periodic health checks, uncomment the `healthcheck` block in `docker-compose.yml`.
|
||||
|
||||
## 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.
|
||||
|
||||
|
||||
@@ -8,9 +8,17 @@ services:
|
||||
SPRING_DATASOURCE_USERNAME: "admin"
|
||||
SPRING_DATASOURCE_PASSWORD: "admin"
|
||||
SPRING_DATASOURCE_DRIVER_CLASS_NAME: "org.postgresql.Driver"
|
||||
SPRING_JPA_PROPERTIES_HIBERNATE_DIALECT: ca.uhn.fhir.jpa.model.dialect.HapiFhirPostgresDialect
|
||||
HIBERNATE_DIALECT: ca.uhn.fhir.jpa.model.dialect.HapiFhirPostgresDialect
|
||||
ports:
|
||||
- "8080:8080"
|
||||
# Uncomment to enable periodic health checks.
|
||||
# Can also be run manually: docker exec hapi-fhir-jpaserver-start java -cp /app HealthCheck
|
||||
# healthcheck:
|
||||
# test: ["CMD", "java", "-cp", "/app", "HealthCheck"]
|
||||
# interval: 30s
|
||||
# timeout: 10s
|
||||
# start_period: 60s
|
||||
# retries: 3
|
||||
depends_on:
|
||||
hapi-fhir-postgres:
|
||||
condition: service_healthy
|
||||
|
||||
45
src/main/java/HealthCheck.java
Normal file
45
src/main/java/HealthCheck.java
Normal file
@@ -0,0 +1,45 @@
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class HealthCheck {
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
var port = System.getenv().getOrDefault("SERVER_PORT", "8080");
|
||||
var url = new URL("http://localhost:" + port + "/fhir/metadata");
|
||||
var conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setRequestMethod("GET");
|
||||
conn.setRequestProperty("Accept", "application/fhir+json");
|
||||
conn.setConnectTimeout(10000);
|
||||
conn.setReadTimeout(10000);
|
||||
|
||||
var status = conn.getResponseCode();
|
||||
if (status != 200) {
|
||||
System.err.println("Health check failed: HTTP " + status);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
var body = new StringBuilder();
|
||||
try (var reader = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
body.append(line);
|
||||
}
|
||||
}
|
||||
|
||||
var pattern = Pattern.compile("\"resourceType\"\\s*:\\s*\"CapabilityStatement\"");
|
||||
if (pattern.matcher(body.toString()).find()) {
|
||||
System.exit(0);
|
||||
} else {
|
||||
System.err.println("Health check failed: CapabilityStatement not found in response");
|
||||
System.exit(1);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("Health check failed: " + e.getMessage());
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -120,7 +120,7 @@ spring:
|
||||
# Hibernate dialect is auto-detected except for H2/Postgres.
|
||||
# If using H2: ca.uhn.fhir.jpa.model.dialect.HapiFhirH2Dialect
|
||||
# If using Postgres: ca.uhn.fhir.jpa.model.dialect.HapiFhirPostgresDialect
|
||||
dialect: ca.uhn.fhir.jpa.model.dialect.HapiFhirH2Dialect
|
||||
dialect: ${HIBERNATE_DIALECT:ca.uhn.fhir.jpa.model.dialect.HapiFhirH2Dialect}
|
||||
|
||||
# --- Optional Hibernate DDL & tuning (commented out from source) ---
|
||||
hbm2ddl:
|
||||
|
||||
Reference in New Issue
Block a user