diff --git a/monitoring/opentelemetry-reactive/src/main/java/io/quarkus/ts/opentelemetry/reactive/grpc/GrpcHealthService.java b/monitoring/opentelemetry-reactive/src/main/java/io/quarkus/ts/opentelemetry/reactive/grpc/GrpcHealthService.java new file mode 100644 index 000000000..ba5fa8826 --- /dev/null +++ b/monitoring/opentelemetry-reactive/src/main/java/io/quarkus/ts/opentelemetry/reactive/grpc/GrpcHealthService.java @@ -0,0 +1,23 @@ +package io.quarkus.ts.opentelemetry.reactive.grpc; + +import io.quarkus.example.HealthCheckRequest; +import io.quarkus.example.HealthCheckResponse; +import io.quarkus.example.HealthService; +import io.quarkus.grpc.GrpcService; +import io.smallrye.mutiny.Multi; +import io.smallrye.mutiny.Uni; + +@GrpcService +// todo this should return statuses, but it isn't failing the deployment +public class GrpcHealthService implements HealthService { + + @Override + public Uni check(HealthCheckRequest request) { + return Uni.createFrom().failure(new RuntimeException("Error!")); + } + + @Override + public Multi watch(HealthCheckRequest request) { + return Multi.createFrom().failure(new RuntimeException("Error!")); + } +} diff --git a/monitoring/opentelemetry-reactive/src/main/proto/health.proto b/monitoring/opentelemetry-reactive/src/main/proto/health.proto new file mode 100644 index 000000000..e1e3d72c8 --- /dev/null +++ b/monitoring/opentelemetry-reactive/src/main/proto/health.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; + +option java_multiple_files = true; +option java_package = "io.quarkus.example"; + +package grpc.health.v1;; + +message HealthCheckRequest { + string service = 1; +} + +message HealthCheckResponse { + enum ServingStatus { + UNKNOWN = 0; + SERVING = 1; + NOT_SERVING = 2; + SERVICE_UNKNOWN = 3; // Used only by the Watch method. + } + ServingStatus status = 1; +} + +service HealthService { + rpc Check(HealthCheckRequest) returns (HealthCheckResponse); + rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse); +} diff --git a/monitoring/opentelemetry-reactive/src/main/resources/application.properties b/monitoring/opentelemetry-reactive/src/main/resources/application.properties index 64e8ba552..5c9ac48eb 100644 --- a/monitoring/opentelemetry-reactive/src/main/resources/application.properties +++ b/monitoring/opentelemetry-reactive/src/main/resources/application.properties @@ -7,4 +7,8 @@ io.quarkus.ts.opentelemetry.reactive.sse.ServerSentEventsPongClient/mp-rest/scop # gRPC quarkus.grpc.clients.pong.host=localhost -quarkus.application.name=pingpong \ No newline at end of file +quarkus.application.name=pingpong + +quarkus.openshift.readiness-probe.grpc-action=9000:grpc.health.v1.HealthService +quarkus.openshift.startup-probe.grpc-action=9000:grpc.health.v1.HealthService +quarkus.openshift.liveness-probe.grpc-action=9000:grpc.health.v1.HealthService diff --git a/monitoring/opentelemetry-reactive/src/test/java/io/quarkus/ts/opentelemetry/reactive/OpenTelemetryGrpcIT.java b/monitoring/opentelemetry-reactive/src/test/java/io/quarkus/ts/opentelemetry/reactive/GrpcIT.java similarity index 98% rename from monitoring/opentelemetry-reactive/src/test/java/io/quarkus/ts/opentelemetry/reactive/OpenTelemetryGrpcIT.java rename to monitoring/opentelemetry-reactive/src/test/java/io/quarkus/ts/opentelemetry/reactive/GrpcIT.java index 57d49c2f1..33206d2b1 100644 --- a/monitoring/opentelemetry-reactive/src/test/java/io/quarkus/ts/opentelemetry/reactive/OpenTelemetryGrpcIT.java +++ b/monitoring/opentelemetry-reactive/src/test/java/io/quarkus/ts/opentelemetry/reactive/GrpcIT.java @@ -18,7 +18,7 @@ import io.quarkus.test.services.QuarkusApplication; @QuarkusScenario -public class OpenTelemetryGrpcIT { +public class GrpcIT { @JaegerContainer(useOtlpCollector = true) static final JaegerService jaeger = new JaegerService(); @@ -61,5 +61,4 @@ protected void assertTraceIdWithPongService(String expected) { assertEquals(expected, pongTraceId); } - } diff --git a/monitoring/opentelemetry-reactive/src/test/java/io/quarkus/ts/opentelemetry/reactive/OpenShiftGrpcIT.java b/monitoring/opentelemetry-reactive/src/test/java/io/quarkus/ts/opentelemetry/reactive/OpenShiftGrpcIT.java new file mode 100644 index 000000000..1f2348d0e --- /dev/null +++ b/monitoring/opentelemetry-reactive/src/test/java/io/quarkus/ts/opentelemetry/reactive/OpenShiftGrpcIT.java @@ -0,0 +1,42 @@ +package io.quarkus.ts.opentelemetry.reactive; + +import java.util.List; + +import jakarta.inject.Inject; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import io.fabric8.kubernetes.api.model.Container; +import io.fabric8.kubernetes.api.model.GRPCAction; +import io.fabric8.kubernetes.api.model.Pod; +import io.fabric8.kubernetes.api.model.Probe; +import io.quarkus.test.bootstrap.inject.OpenShiftClient; +import io.quarkus.test.scenarios.OpenShiftDeploymentStrategy; +import io.quarkus.test.scenarios.OpenShiftScenario; + +@OpenShiftScenario(deployment = OpenShiftDeploymentStrategy.UsingOpenShiftExtension) +public class OpenShiftGrpcIT extends GrpcIT { + + @Inject + static OpenShiftClient oc; + + @Test + void grpcProbes() { + List pods = oc.podsInService(app); + Assertions.assertEquals(1, pods.size()); + List containers = pods.get(0).getSpec().getContainers(); + Assertions.assertEquals(1, containers.size()); + Container container = containers.get(0); + validateProbe(container.getLivenessProbe()); + validateProbe(container.getReadinessProbe()); + } + + private static void validateProbe(Probe probe) { + Assertions.assertNotNull(probe); + GRPCAction grpcAction = probe.getGrpc(); + Assertions.assertNotNull(grpcAction); + Assertions.assertEquals("grpc.health.v1.HealthService", grpcAction.getService()); + Assertions.assertEquals(9000, grpcAction.getPort()); + } +}