From 289cf09e386648083a30e4800ef4250a7b7a06f7 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Mon, 13 Jan 2025 11:38:13 +0200 Subject: [PATCH] Fix Mongo health checks Prior to this change, the health checks would erroneously report the connection was up if the database had yet to be contacted by the application --- extensions/mongodb-client/deployment/pom.xml | 5 ++ .../mongodb/MongoClientConfigTest.java | 9 ++++ .../mongodb/NoConnectionHealthCheckTest.java | 52 +++++++++++++++++++ .../mongodb/health/MongoHealthCheck.java | 5 +- .../quarkus/mongodb/runtime/MongoClients.java | 14 ----- 5 files changed, 68 insertions(+), 17 deletions(-) create mode 100644 extensions/mongodb-client/deployment/src/test/java/io/quarkus/mongodb/NoConnectionHealthCheckTest.java diff --git a/extensions/mongodb-client/deployment/pom.xml b/extensions/mongodb-client/deployment/pom.xml index 36b104c57bf4b..bafad10a55454 100644 --- a/extensions/mongodb-client/deployment/pom.xml +++ b/extensions/mongodb-client/deployment/pom.xml @@ -101,6 +101,11 @@ assertj-core test + + io.rest-assured + rest-assured + test + io.quarkus quarkus-resteasy-deployment diff --git a/extensions/mongodb-client/deployment/src/test/java/io/quarkus/mongodb/MongoClientConfigTest.java b/extensions/mongodb-client/deployment/src/test/java/io/quarkus/mongodb/MongoClientConfigTest.java index 97161fe578bfb..8508f88af45b7 100644 --- a/extensions/mongodb-client/deployment/src/test/java/io/quarkus/mongodb/MongoClientConfigTest.java +++ b/extensions/mongodb-client/deployment/src/test/java/io/quarkus/mongodb/MongoClientConfigTest.java @@ -1,11 +1,13 @@ package io.quarkus.mongodb; +import static io.restassured.RestAssured.when; import static org.assertj.core.api.Assertions.assertThat; import java.util.concurrent.TimeUnit; import jakarta.inject.Inject; +import org.hamcrest.CoreMatchers; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledOnOs; @@ -97,4 +99,11 @@ public void testReactiveClientConfiuration() { assertThat(clientImpl.getSettings().getReadConcern()).isEqualTo(new ReadConcern(ReadConcernLevel.SNAPSHOT)); assertThat(clientImpl.getSettings().getReadPreference()).isEqualTo(ReadPreference.primary()); } + + @Test + public void healthCheck() { + when().get("/q/health/ready") + .then() + .body("status", CoreMatchers.equalTo("UP")); + } } diff --git a/extensions/mongodb-client/deployment/src/test/java/io/quarkus/mongodb/NoConnectionHealthCheckTest.java b/extensions/mongodb-client/deployment/src/test/java/io/quarkus/mongodb/NoConnectionHealthCheckTest.java new file mode 100644 index 0000000000000..c68bba88da4d9 --- /dev/null +++ b/extensions/mongodb-client/deployment/src/test/java/io/quarkus/mongodb/NoConnectionHealthCheckTest.java @@ -0,0 +1,52 @@ +package io.quarkus.mongodb; + +import static io.restassured.RestAssured.when; + +import jakarta.inject.Inject; + +import org.bson.Document; +import org.hamcrest.CoreMatchers; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.RegisterExtension; + +import com.mongodb.MongoClientException; +import com.mongodb.client.MongoClient; + +import io.quarkus.test.QuarkusUnitTest; + +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class NoConnectionHealthCheckTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .overrideConfigKey("quarkus.devservices.enabled", "false") + .overrideConfigKey("quarkus.mongodb.connection-string", "mongodb://localhost:9999") + // timeouts set to the test doesn't take too long to run + .overrideConfigKey("quarkus.mongodb.connect-timeout", "2s") + .overrideConfigKey("quarkus.mongodb.server-selection-timeout", "2s") + .overrideConfigKey("quarkus.mongodb.read-timeout", "2s"); + + @Inject + MongoClient mongo; + + @Order(1) // done to ensure the health check runs before any application code touches the database + @Test + public void healthCheck() { + when().get("/q/health/ready") + .then() + .body("status", CoreMatchers.equalTo("DOWN")); + } + + @Order(2) + @Test + public void tryConnection() { + Assertions.assertThrows(MongoClientException.class, () -> { + mongo.getDatabase("admin").runCommand(new Document("ping", 1)); + }); + } + +} diff --git a/extensions/mongodb-client/runtime/src/main/java/io/quarkus/mongodb/health/MongoHealthCheck.java b/extensions/mongodb-client/runtime/src/main/java/io/quarkus/mongodb/health/MongoHealthCheck.java index 953971bcf3455..382e3fb699238 100644 --- a/extensions/mongodb-client/runtime/src/main/java/io/quarkus/mongodb/health/MongoHealthCheck.java +++ b/extensions/mongodb-client/runtime/src/main/java/io/quarkus/mongodb/health/MongoHealthCheck.java @@ -42,7 +42,7 @@ public class MongoHealthCheck implements HealthCheck { private static final Document COMMAND = new Document("ping", 1); - public void configure(MongodbConfig config) { + public MongoHealthCheck(MongodbConfig config) { Iterable> handle = Arc.container().select(MongoClient.class, Any.Literal.INSTANCE) .handles(); Iterable> reactiveHandlers = Arc.container() @@ -61,7 +61,7 @@ public void configure(MongodbConfig config) { } } - config.mongoClientConfigs.forEach(new BiConsumer() { + config.mongoClientConfigs.forEach(new BiConsumer<>() { @Override public void accept(String name, MongoClientConfig cfg) { MongoClient client = getClient(handle, name); @@ -76,7 +76,6 @@ public void accept(String name, MongoClientConfig cfg) { } } }); - } private MongoClient getClient(Iterable> handle, String name) { diff --git a/extensions/mongodb-client/runtime/src/main/java/io/quarkus/mongodb/runtime/MongoClients.java b/extensions/mongodb-client/runtime/src/main/java/io/quarkus/mongodb/runtime/MongoClients.java index 6997039882567..09cc31391f018 100644 --- a/extensions/mongodb-client/runtime/src/main/java/io/quarkus/mongodb/runtime/MongoClients.java +++ b/extensions/mongodb-client/runtime/src/main/java/io/quarkus/mongodb/runtime/MongoClients.java @@ -58,12 +58,9 @@ import com.mongodb.event.ConnectionPoolListener; import com.mongodb.reactivestreams.client.ReactiveContextProvider; -import io.quarkus.arc.Arc; -import io.quarkus.arc.InstanceHandle; import io.quarkus.credentials.CredentialsProvider; import io.quarkus.credentials.runtime.CredentialsProviderFinder; import io.quarkus.mongodb.MongoClientName; -import io.quarkus.mongodb.health.MongoHealthCheck; import io.quarkus.mongodb.impl.ReactiveMongoClientImpl; import io.quarkus.mongodb.reactive.ReactiveMongoClient; @@ -111,17 +108,6 @@ public MongoClients(MongodbConfig mongodbConfig, MongoClientSupport mongoClientS Class.forName("sun.net.ext.ExtendedSocketOptions", true, ClassLoader.getSystemClassLoader()); } catch (ClassNotFoundException ignored) { } - - try { - Class.forName("org.eclipse.microprofile.health.HealthCheck"); - InstanceHandle instance = Arc.container() - .instance(MongoHealthCheck.class, Any.Literal.INSTANCE); - if (instance.isAvailable()) { - instance.get().configure(mongodbConfig); - } - } catch (ClassNotFoundException e) { - // Ignored - no health check - } } public MongoClient createMongoClient(String clientName) throws MongoException {