From 47aaae7e141db565dfad9c56198161f3851c23de Mon Sep 17 00:00:00 2001
From: Marc Nuri <marc@marcnuri.com>
Date: Mon, 16 Dec 2024 10:33:17 +0100
Subject: [PATCH] fix(vertx): VertxHttpClientFactory reuses the same Vertx
 instance for each VertxHttpClient instance

Signed-off-by: Marc Nuri <marc@marcnuri.com>
---
 CHANGELOG.md                                  |  5 ++
 .../client/vertx/VertxHttpClientFactory.java  | 61 ++++++++++++-------
 2 files changed, 43 insertions(+), 23 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 967a3902ee2..9fb629faa30 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,11 @@
 
 #### _**Note**_: Breaking changes
 
+### 7.0.1 (TBD)
+
+#### Bugs
+
+* Fix #6709: VertxHttpClientFactory reuses the same Vertx instance for each VertxHttpClient instance
 
 ### 7.0.0 (2024-12-03)
 
diff --git a/httpclient-vertx/src/main/java/io/fabric8/kubernetes/client/vertx/VertxHttpClientFactory.java b/httpclient-vertx/src/main/java/io/fabric8/kubernetes/client/vertx/VertxHttpClientFactory.java
index c0e70a0e56f..c5d969aaf21 100644
--- a/httpclient-vertx/src/main/java/io/fabric8/kubernetes/client/vertx/VertxHttpClientFactory.java
+++ b/httpclient-vertx/src/main/java/io/fabric8/kubernetes/client/vertx/VertxHttpClientFactory.java
@@ -25,10 +25,47 @@
 
 public class VertxHttpClientFactory implements io.fabric8.kubernetes.client.http.HttpClient.Factory {
 
+  private static final class VertxHolder {
+
+    private static final Vertx INSTANCE = createVertxInstance();
+
+    private static synchronized Vertx createVertxInstance() {
+      // We must disable the async DNS resolver as it can cause issues when resolving the Vault instance.
+      // This is done using the DISABLE_DNS_RESOLVER_PROP_NAME system property.
+      // The DNS resolver used by vert.x is configured during the (synchronous) initialization.
+      // So, we just need to disable the async resolver around the Vert.x instance creation.
+      final String originalValue = System.getProperty(DISABLE_DNS_RESOLVER_PROP_NAME);
+      Vertx vertx;
+      try {
+        System.setProperty(DISABLE_DNS_RESOLVER_PROP_NAME, "true");
+        vertx = Vertx.vertx(new VertxOptions()
+            .setFileSystemOptions(new FileSystemOptions().setFileCachingEnabled(false).setClassPathResolvingEnabled(false))
+            .setUseDaemonThread(true));
+      } finally {
+        // Restore the original value
+        if (originalValue == null) {
+          System.clearProperty(DISABLE_DNS_RESOLVER_PROP_NAME);
+        } else {
+          System.setProperty(DISABLE_DNS_RESOLVER_PROP_NAME, originalValue);
+        }
+      }
+      return vertx;
+    }
+  }
+
   private final Vertx vertx;
 
   public VertxHttpClientFactory() {
-    this.vertx = createVertxInstance();
+    this(VertxHolder.INSTANCE);
+    Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+      if (vertx != null) {
+        vertx.close();
+      }
+    }));
+  }
+
+  public VertxHttpClientFactory(Vertx vertx) {
+    this.vertx = vertx;
   }
 
   @Override
@@ -36,28 +73,6 @@ public VertxHttpClientBuilder<VertxHttpClientFactory> newBuilder() {
     return new VertxHttpClientBuilder<>(this, vertx);
   }
 
-  private static synchronized Vertx createVertxInstance() {
-    // We must disable the async DNS resolver as it can cause issues when resolving the Vault instance.
-    // This is done using the DISABLE_DNS_RESOLVER_PROP_NAME system property.
-    // The DNS resolver used by vert.x is configured during the (synchronous) initialization.
-    // So, we just need to disable the async resolver around the Vert.x instance creation.
-    final String originalValue = System.getProperty(DISABLE_DNS_RESOLVER_PROP_NAME);
-    Vertx vertx;
-    try {
-      System.setProperty(DISABLE_DNS_RESOLVER_PROP_NAME, "true");
-      vertx = Vertx.vertx(new VertxOptions()
-          .setFileSystemOptions(new FileSystemOptions().setFileCachingEnabled(false).setClassPathResolvingEnabled(false)));
-    } finally {
-      // Restore the original value
-      if (originalValue == null) {
-        System.clearProperty(DISABLE_DNS_RESOLVER_PROP_NAME);
-      } else {
-        System.setProperty(DISABLE_DNS_RESOLVER_PROP_NAME, originalValue);
-      }
-    }
-    return vertx;
-  }
-
   /**
    * Additional configuration to be applied to the options after the {@link Config} has been processed.
    */