Repository: quarkusio/quarkus
Issue: Mongo clients should be initialized eagerly

**Describe the bug**
Currently the mongo clients are flagged as @ApplicaitonScoped, which means they are wrapped by a proxy making them initialized on first use.

This is annoying as

* we don't respect the configuration of pre-filling the pool on boot
* we can't validate the connection properties, deferring any failure
* it's an overhead

relates to #4507

Changed files:
extensions/mongodb-client/deployment/src/main/java/io/quarkus/mongodb/deployment/MongoClientProcessor.java
extensions/mongodb-client/deployment/src/test/java/io/quarkus/mongodb/MongoMetricsTest.java

diff --git a/extensions/mongodb-client/deployment/src/main/java/io/quarkus/mongodb/deployment/MongoClientProcessor.java b/extensions/mongodb-client/deployment/src/main/java/io/quarkus/mongodb/deployment/MongoClientProcessor.java
index 24fcbf3db90..03e716e6921 100644
--- a/extensions/mongodb-client/deployment/src/main/java/io/quarkus/mongodb/deployment/MongoClientProcessor.java
+++ b/extensions/mongodb-client/deployment/src/main/java/io/quarkus/mongodb/deployment/MongoClientProcessor.java
@@ -11,9 +11,9 @@
 import java.util.Set;
 import java.util.stream.Collectors;
 
-import javax.enterprise.context.ApplicationScoped;
 import javax.enterprise.inject.Default;
 import javax.enterprise.inject.Produces;
+import javax.inject.Singleton;
 
 import org.bson.codecs.configuration.CodecProvider;
 import org.bson.codecs.pojo.annotations.BsonDiscriminator;
@@ -126,7 +126,7 @@ public void mongoClientNames(ApplicationArchivesBuildItem applicationArchivesBui
      * 
      * <pre>
      * public class myclass extends AbstractMongoClientProducer {
-     *     &#64;ApplicationScoped
+     *     &#64;Singleton
      *     &#64;Produces
      *     &#64;Default
      *     public MongoClient createDefaultMongoClient() {
@@ -134,7 +134,7 @@ public void mongoClientNames(ApplicationArchivesBuildItem applicationArchivesBui
      *         return createMongoClient(cfg);
      *     }
      * 
-     *     &#64;ApplicationScoped
+     *     &#64;Singleton
      *     &#64;Produces
      *     &#64;Default
      *     public ReactiveMongoClient createDefaultReactiveMongoClient() {
@@ -145,7 +145,7 @@ public void mongoClientNames(ApplicationArchivesBuildItem applicationArchivesBui
      *     // for each named mongoclient configuration
      *     // example:
      *     // quarkus.mongodb.cluster1.connection-string = mongodb://mongo1:27017,mongo2:27017
-     *     &#64;ApplicationScoped
+     *     &#64;Singleton
      *     &#64;Produces
      *     &#64;Named("cluster1")
      *     &#64;MongoClientName("cluster1")
@@ -154,7 +154,7 @@ public void mongoClientNames(ApplicationArchivesBuildItem applicationArchivesBui
      *         return createMongoClient(cfg);
      *     }
      * 
-     *     &#64;ApplicationScoped
+     *     &#64;Singleton
      *     &#64;Produces
      *     &#64;Named("cluster1")
      *     &#64;MongoClientName("cluster1")
@@ -175,11 +175,11 @@ private void createMongoClientProducerBean(List<MongoClientNameBuildItem> mongoC
                 .className(mongoClientProducerClassName)
                 .superClass(AbstractMongoClientProducer.class)
                 .build()) {
-            classCreator.addAnnotation(ApplicationScoped.class);
+            classCreator.addAnnotation(Singleton.class);
 
             try (MethodCreator defaultMongoClientMethodCreator = classCreator.getMethodCreator("createDefaultMongoClient",
                     MongoClient.class)) {
-                defaultMongoClientMethodCreator.addAnnotation(ApplicationScoped.class);
+                defaultMongoClientMethodCreator.addAnnotation(Singleton.class);
                 defaultMongoClientMethodCreator.addAnnotation(Produces.class);
                 defaultMongoClientMethodCreator.addAnnotation(Default.class);
                 if (makeUnremovable) {
@@ -206,7 +206,7 @@ private void createMongoClientProducerBean(List<MongoClientNameBuildItem> mongoC
             try (MethodCreator defaultReactiveMongoClientMethodCreator = classCreator.getMethodCreator(
                     "createDefaultLegacyReactiveMongoClient",
                     ReactiveMongoClient.class)) {
-                defaultReactiveMongoClientMethodCreator.addAnnotation(ApplicationScoped.class);
+                defaultReactiveMongoClientMethodCreator.addAnnotation(Singleton.class);
                 defaultReactiveMongoClientMethodCreator.addAnnotation(Produces.class);
                 defaultReactiveMongoClientMethodCreator.addAnnotation(Default.class);
 
@@ -230,7 +230,7 @@ private void createMongoClientProducerBean(List<MongoClientNameBuildItem> mongoC
             try (MethodCreator defaultReactiveMongoClientMethodCreator = classCreator.getMethodCreator(
                     "createDefaultReactiveMongoClient",
                     io.quarkus.mongodb.reactive.ReactiveMongoClient.class)) {
-                defaultReactiveMongoClientMethodCreator.addAnnotation(ApplicationScoped.class);
+                defaultReactiveMongoClientMethodCreator.addAnnotation(Singleton.class);
                 defaultReactiveMongoClientMethodCreator.addAnnotation(Produces.class);
                 defaultReactiveMongoClientMethodCreator.addAnnotation(Default.class);
                 if (makeUnremovable) {
@@ -258,7 +258,7 @@ private void createMongoClientProducerBean(List<MongoClientNameBuildItem> mongoC
                 try (MethodCreator namedMongoClientMethodCreator = classCreator.getMethodCreator(
                         "createNamedMongoClient_" + HashUtil.sha1(namedMongoClientName),
                         MongoClient.class)) {
-                    namedMongoClientMethodCreator.addAnnotation(ApplicationScoped.class);
+                    namedMongoClientMethodCreator.addAnnotation(Singleton.class);
                     namedMongoClientMethodCreator.addAnnotation(Produces.class);
                     namedMongoClientMethodCreator.addAnnotation(AnnotationInstance.create(DotNames.NAMED, null,
                             new AnnotationValue[] { AnnotationValue.createStringValue("value", namedMongoClientName) }));
@@ -290,7 +290,7 @@ private void createMongoClientProducerBean(List<MongoClientNameBuildItem> mongoC
                 try (MethodCreator namedReactiveMongoClientMethodCreator = classCreator.getMethodCreator(
                         "createNamedLegacyReactiveMongoClient_" + HashUtil.sha1(namedMongoClientName),
                         ReactiveMongoClient.class)) {
-                    namedReactiveMongoClientMethodCreator.addAnnotation(ApplicationScoped.class);
+                    namedReactiveMongoClientMethodCreator.addAnnotation(Singleton.class);
                     namedReactiveMongoClientMethodCreator.addAnnotation(Produces.class);
                     namedReactiveMongoClientMethodCreator.addAnnotation(AnnotationInstance.create(DotNames.NAMED, null,
                             new AnnotationValue[] {
@@ -322,7 +322,7 @@ private void createMongoClientProducerBean(List<MongoClientNameBuildItem> mongoC
                 try (MethodCreator namedReactiveMongoClientMethodCreator = classCreator.getMethodCreator(
                         "createNamedReactiveMongoClient_" + HashUtil.sha1(namedMongoClientName),
                         io.quarkus.mongodb.reactive.ReactiveMongoClient.class)) {
-                    namedReactiveMongoClientMethodCreator.addAnnotation(ApplicationScoped.class);
+                    namedReactiveMongoClientMethodCreator.addAnnotation(Singleton.class);
                     namedReactiveMongoClientMethodCreator.addAnnotation(Produces.class);
                     namedReactiveMongoClientMethodCreator.addAnnotation(AnnotationInstance.create(DotNames.NAMED, null,
                             new AnnotationValue[] {
diff --git a/extensions/mongodb-client/deployment/src/test/java/io/quarkus/mongodb/MongoMetricsTest.java b/extensions/mongodb-client/deployment/src/test/java/io/quarkus/mongodb/MongoMetricsTest.java
index 4baae9ebbb9..3a641435788 100644
--- a/extensions/mongodb-client/deployment/src/test/java/io/quarkus/mongodb/MongoMetricsTest.java
+++ b/extensions/mongodb-client/deployment/src/test/java/io/quarkus/mongodb/MongoMetricsTest.java
@@ -2,7 +2,6 @@
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
 
 import javax.inject.Inject;
 
@@ -47,8 +46,9 @@ void cleanup() {
 
     @Test
     void testMetricsInitialization() {
-        assertNull(getGaugeValueOrNull("mongodb.connection-pool.size", getTags()));
-        assertNull(getGaugeValueOrNull("mongodb.connection-pool.checked-out-count", getTags()));
+        // Clients are created eagerly, this metric should always be initialized to zero once connected
+        assertEquals(0L, getGaugeValueOrNull("mongodb.connection-pool.size", getTags()));
+        assertEquals(0L, getGaugeValueOrNull("mongodb.connection-pool.checked-out-count", getTags()));
 
         // Just need to execute something so that an connection is opened
         String name = client.listDatabaseNames().first();