Close Fabric8 Client When Context Is Stopped (#1780)

This commit is contained in:
Ryan Baxter
2024-10-23 10:55:18 -04:00
committed by Ryan Baxter
parent 36c190ef91
commit 4d55f69023
3 changed files with 25 additions and 2 deletions

View File

@@ -36,6 +36,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.boot.BootstrapRegistry;
import org.springframework.boot.ConfigurableBootstrapContext;
import org.springframework.context.ApplicationListener;
import org.springframework.core.env.Environment;
import org.springframework.core.style.ToStringCreator;
import org.springframework.util.CollectionUtils;
@@ -60,6 +61,8 @@ public final class ConfigUtils {
|| sourceName.endsWith("-" + activeProfile + ".yaml")
|| sourceName.endsWith("-" + activeProfile + ".properties");
private static final ApplicationListener<?> NO_OP = (e) -> { };
private ConfigUtils() {
}
@@ -329,17 +332,23 @@ public final class ConfigUtils {
}
public static <T> void registerSingle(ConfigurableBootstrapContext bootstrapContext, Class<T> cls, T instance,
String name) {
String name, ApplicationListener<?> listener) {
bootstrapContext.registerIfAbsent(cls, BootstrapRegistry.InstanceSupplier.of(instance));
bootstrapContext.addCloseListener(event -> {
if (event.getApplicationContext().getBeanFactory().getSingleton(name) == null) {
event.getApplicationContext()
.getBeanFactory()
.registerSingleton(name, event.getBootstrapContext().get(cls));
event.getApplicationContext().addApplicationListener(listener);
}
});
}
public static <T> void registerSingle(ConfigurableBootstrapContext bootstrapContext, Class<T> cls, T instance,
String name) {
registerSingle(bootstrapContext, cls, instance, name, NO_OP);
}
/**
* append prefix to the keys and return a new Map with the new values.
*/

View File

@@ -18,11 +18,13 @@ package org.springframework.cloud.kubernetes.fabric8;
import java.time.Duration;
import io.fabric8.kubernetes.client.Client;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.ConfigBuilder;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnCloudPlatform;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -31,6 +33,8 @@ import org.springframework.cloud.kubernetes.commons.KubernetesClientProperties;
import org.springframework.cloud.kubernetes.commons.KubernetesCommonsAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.EventListener;
/**
* Auto configuration for Kubernetes.
@@ -117,4 +121,11 @@ public class Fabric8AutoConfiguration {
return new Fabric8PodUtils(client);
}
@EventListener
void onContextClosed(ContextClosedEvent event) {
// Clean up any open connections from the KubernetesClient when the context is closed
BeanFactoryUtils.beansOfTypeIncludingAncestors(event.getApplicationContext(), KubernetesClient.class).values()
.forEach(Client::close);
}
}

View File

@@ -34,6 +34,8 @@ import org.springframework.cloud.kubernetes.commons.config.KubernetesConfigDataL
import org.springframework.cloud.kubernetes.commons.config.SecretsConfigProperties;
import org.springframework.cloud.kubernetes.commons.config.SecretsPropertySourceLocator;
import org.springframework.cloud.kubernetes.fabric8.Fabric8AutoConfiguration;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.core.env.Environment;
import static org.springframework.cloud.kubernetes.commons.config.ConfigUtils.registerSingle;
@@ -90,7 +92,8 @@ public class Fabric8ConfigDataLocationResolver extends KubernetesConfigDataLocat
registerSingle(bootstrapContext, Config.class, config, "fabric8Config");
KubernetesClient kubernetesClient = new Fabric8AutoConfiguration().kubernetesClient(config);
registerSingle(bootstrapContext, KubernetesClient.class, kubernetesClient, "configKubernetesClient");
registerSingle(bootstrapContext, KubernetesClient.class, kubernetesClient, "configKubernetesClient",
(ApplicationListener<ContextClosedEvent>) event -> kubernetesClient.close());
return kubernetesClient;
}