diff --git a/customer-api-provider/pom.xml b/customer-api-provider/pom.xml index 5946dde..0cb2938 100644 --- a/customer-api-provider/pom.xml +++ b/customer-api-provider/pom.xml @@ -92,6 +92,10 @@ io.quarkus quarkus-jdbc-h2 + + io.quarkus + quarkus-smallrye-health + diff --git a/customer-api-provider/src/main/java/de/schulung/sample/quarkus/infrastructure/LongRunningStartup.java b/customer-api-provider/src/main/java/de/schulung/sample/quarkus/infrastructure/LongRunningStartup.java new file mode 100644 index 0000000..85ebad7 --- /dev/null +++ b/customer-api-provider/src/main/java/de/schulung/sample/quarkus/infrastructure/LongRunningStartup.java @@ -0,0 +1,64 @@ +package de.schulung.sample.quarkus.infrastructure; + +import io.quarkus.runtime.Startup; +import io.smallrye.mutiny.Uni; +import io.smallrye.mutiny.infrastructure.Infrastructure; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.inject.Produces; +import org.eclipse.microprofile.health.HealthCheck; +import org.eclipse.microprofile.health.HealthCheckResponse; +import org.eclipse.microprofile.health.Liveness; +import org.eclipse.microprofile.health.Readiness; + +@ApplicationScoped +public class LongRunningStartup { + + private volatile boolean initialized = false; + private volatile boolean initializingFailed = false; + + // check during startup: http://localhost:9090/q/health/ready + + private Uni doLongRunningInitialization() { + try { + Thread.sleep(5000); + initialized = true; + return Uni.createFrom().voidItem(); + } catch (InterruptedException e) { + initializingFailed = true; + return Uni.createFrom().failure(e); + } + } + + @Startup + public void init() { + Uni + .createFrom() + .voidItem() + .emitOn(Infrastructure.getDefaultWorkerPool()) + .subscribe() + .with(v -> this.doLongRunningInitialization()); + } + + @Produces + @ApplicationScoped + @Liveness + public HealthCheck myStartupLiveness() { + return () -> { + final var result = HealthCheckResponse + .named("My long-running startup"); + return (initializingFailed ? result.down() : result.up()).build(); + }; + } + + @Produces + @ApplicationScoped + @Readiness + public HealthCheck myStartupReadyness() { + return () -> { + final var result = HealthCheckResponse + .named("My long-running startup"); + return (initialized ? result.up() : result.down()).build(); + }; + } + +} diff --git a/customer-api-provider/src/main/resources/application.properties b/customer-api-provider/src/main/resources/application.properties index b200a40..714055f 100644 --- a/customer-api-provider/src/main/resources/application.properties +++ b/customer-api-provider/src/main/resources/application.properties @@ -19,4 +19,15 @@ persistence.sink.implementation=panache %dev.quarkus.hibernate-orm.database.generation=update +# Observability - serve on another port +# https://quarkus.io/guides/management-interface-reference +# https://quarkus.io/guides/smallrye-health +# https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ +# https://developers.redhat.com/blog/2020/11/10/you-probably-need-liveness-and-readiness-probes +quarkus.management.enabled=true +quarkus.management.port=9090 +%dev.quarkus.management.host=localhost +quarkus.datasource.health.enabled=true +# Liveness: if fails -> container must be restarted +# Readyness: if fails -> container is just initializing \ No newline at end of file