diff --git a/pom.xml b/pom.xml
index 70b5d9a2..631c7056 100644
--- a/pom.xml
+++ b/pom.xml
@@ -90,6 +90,7 @@
3.5
+ 2.8.2
2.19.1
3.1.69
1.2
diff --git a/spring-cloud-kubernetes-core/src/main/java/io/fabric8/spring/cloud/kubernetes/reload/ConfigReloadAutoConfiguration.java b/spring-cloud-kubernetes-core/src/main/java/io/fabric8/spring/cloud/kubernetes/reload/ConfigReloadAutoConfiguration.java
index bdec7c62..9b31ff07 100644
--- a/spring-cloud-kubernetes-core/src/main/java/io/fabric8/spring/cloud/kubernetes/reload/ConfigReloadAutoConfiguration.java
+++ b/spring-cloud-kubernetes-core/src/main/java/io/fabric8/spring/cloud/kubernetes/reload/ConfigReloadAutoConfiguration.java
@@ -1,17 +1,9 @@
package io.fabric8.spring.cloud.kubernetes.reload;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Function;
-import javax.annotation.PreDestroy;
-
import io.fabric8.kubernetes.client.KubernetesClient;
-import io.fabric8.kubernetes.client.Watch;
import io.fabric8.spring.cloud.kubernetes.config.ConfigMapPropertySourceLocator;
import io.fabric8.spring.cloud.kubernetes.config.SecretsPropertySourceLocator;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -23,10 +15,8 @@ import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.AbstractEnvironment;
-import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
-import org.springframework.stereotype.Component;
/**
* Definition of beans needed for the automatic reload of configuration.
@@ -62,12 +52,12 @@ public class ConfigReloadAutoConfiguration {
*/
@Bean
@ConditionalOnMissingBean
- public ConfigurationChangeDetector propertyChangeWatcher(ConfigReloadProperties properties, ConfigurationUpdateStrategy strategy, EventWatcher eventWatcher) {
+ public ConfigurationChangeDetector propertyChangeWatcher(ConfigReloadProperties properties, ConfigurationUpdateStrategy strategy) {
switch (properties.getMode()) {
case POLLING:
return new PollingConfigurationChangeDetector(environment, properties, kubernetesClient, strategy, configMapPropertySourceLocator, secretsPropertySourceLocator);
case EVENT:
- return new EventBasedConfigurationChangeDetector(environment, properties, kubernetesClient, strategy, configMapPropertySourceLocator, secretsPropertySourceLocator, eventWatcher);
+ return new EventBasedConfigurationChangeDetector(environment, properties, kubernetesClient, strategy, configMapPropertySourceLocator, secretsPropertySourceLocator);
}
throw new IllegalStateException("Unsupported configuration reload mode: " + properties.getMode());
}
@@ -89,49 +79,6 @@ public class ConfigReloadAutoConfiguration {
throw new IllegalStateException("Unsupported configuration update strategy: " + properties.getStrategy());
}
-
- /**
- * Manages watches asynchronously and clean them up on context close.
- */
- @Component
- public static class DefaultEventWatcher implements EventWatcher {
- private Logger log = LoggerFactory.getLogger(getClass());
-
- private KubernetesClient kubernetesClient;
-
- private Map watches;
-
- @Autowired
- public DefaultEventWatcher(KubernetesClient kubernetesClient) {
- this.kubernetesClient = kubernetesClient;
- this.watches = new ConcurrentHashMap<>();
- }
-
- @Async
- public void addWatch(String name, Function watch) {
- if (watches.containsKey(name)) {
- throw new IllegalArgumentException("Watch already present: " + name);
- }
-
- watches.put(name, watch.apply(kubernetesClient));
- log.info("Added new Kubernetes watch: {}", name);
- }
-
- @PreDestroy
- public void unwatch() {
- if (this.watches != null) {
- for (Watch watch : this.watches.values()) {
- try {
- watch.close();
-
- } catch (Exception e) {
- log.error("Error while closing the watch connection", e);
- }
- }
- }
- }
-
- }
}
}
diff --git a/spring-cloud-kubernetes-core/src/main/java/io/fabric8/spring/cloud/kubernetes/reload/ConfigurationChangeDetector.java b/spring-cloud-kubernetes-core/src/main/java/io/fabric8/spring/cloud/kubernetes/reload/ConfigurationChangeDetector.java
index b0b2169e..91b0e3da 100644
--- a/spring-cloud-kubernetes-core/src/main/java/io/fabric8/spring/cloud/kubernetes/reload/ConfigurationChangeDetector.java
+++ b/spring-cloud-kubernetes-core/src/main/java/io/fabric8/spring/cloud/kubernetes/reload/ConfigurationChangeDetector.java
@@ -5,7 +5,6 @@ import java.util.List;
import java.util.Map;
import javax.annotation.PreDestroy;
-import io.fabric8.kubernetes.client.Client;
import io.fabric8.kubernetes.client.KubernetesClient;
import org.slf4j.Logger;
@@ -40,9 +39,7 @@ public abstract class ConfigurationChangeDetector {
@PreDestroy
public void shutdown() {
// Ensure the kubernetes client is cleaned up from spare threads when shutting down
- if (kubernetesClient instanceof Client) {
- ((Client) kubernetesClient).close();
- }
+ kubernetesClient.close();
}
public void reloadProperties() {
diff --git a/spring-cloud-kubernetes-core/src/main/java/io/fabric8/spring/cloud/kubernetes/reload/EventBasedConfigurationChangeDetector.java b/spring-cloud-kubernetes-core/src/main/java/io/fabric8/spring/cloud/kubernetes/reload/EventBasedConfigurationChangeDetector.java
index 1832d7f6..c99bef8b 100644
--- a/spring-cloud-kubernetes-core/src/main/java/io/fabric8/spring/cloud/kubernetes/reload/EventBasedConfigurationChangeDetector.java
+++ b/spring-cloud-kubernetes-core/src/main/java/io/fabric8/spring/cloud/kubernetes/reload/EventBasedConfigurationChangeDetector.java
@@ -1,11 +1,15 @@
package io.fabric8.spring.cloud.kubernetes.reload;
+import java.util.HashMap;
+import java.util.Map;
import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
import io.fabric8.kubernetes.api.model.ConfigMap;
import io.fabric8.kubernetes.api.model.Secret;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientException;
+import io.fabric8.kubernetes.client.Watch;
import io.fabric8.kubernetes.client.Watcher;
import io.fabric8.spring.cloud.kubernetes.config.ConfigMapPropertySource;
import io.fabric8.spring.cloud.kubernetes.config.ConfigMapPropertySourceLocator;
@@ -24,27 +28,27 @@ public class EventBasedConfigurationChangeDetector extends ConfigurationChangeDe
private SecretsPropertySourceLocator secretsPropertySourceLocator;
- private EventWatcher eventWatcher;
+ private Map watches;
public EventBasedConfigurationChangeDetector(AbstractEnvironment environment,
ConfigReloadProperties properties,
KubernetesClient kubernetesClient,
ConfigurationUpdateStrategy strategy,
ConfigMapPropertySourceLocator configMapPropertySourceLocator,
- SecretsPropertySourceLocator secretsPropertySourceLocator,
- EventWatcher eventWatcher) {
+ SecretsPropertySourceLocator secretsPropertySourceLocator) {
super(environment, properties, kubernetesClient, strategy);
- this.eventWatcher = eventWatcher;
this.configMapPropertySourceLocator = configMapPropertySourceLocator;
this.secretsPropertySourceLocator = secretsPropertySourceLocator;
+ this.watches = new HashMap<>();
}
@PostConstruct
public void watch() {
if (properties.isMonitoringConfigMaps()) {
- eventWatcher.addWatch("config-maps-watch", k -> k.configMaps()
+ String name = "config-maps-watch";
+ watches.put(name, kubernetesClient.configMaps()
.watch(new Watcher() {
@Override
public void eventReceived(Action action, ConfigMap configMap) {
@@ -55,10 +59,12 @@ public class EventBasedConfigurationChangeDetector extends ConfigurationChangeDe
public void onClose(KubernetesClientException e) {
}
}));
+ log.info("Added new Kubernetes watch: {}", name);
}
if (properties.isMonitoringSecrets()) {
- eventWatcher.addWatch("secrets-watch", k -> k.secrets()
+ String name = "secrets-watch";
+ watches.put(name, kubernetesClient.secrets()
.watch(new Watcher() {
@Override
public void eventReceived(Action action, Secret secret) {
@@ -69,11 +75,27 @@ public class EventBasedConfigurationChangeDetector extends ConfigurationChangeDe
public void onClose(KubernetesClientException e) {
}
}));
+ log.info("Added new Kubernetes watch: {}", name);
}
log.info("Kubernetes polling configuration change detector activated");
}
+ @PreDestroy
+ public void unwatch() {
+ if (this.watches != null) {
+ for (Map.Entry entry : this.watches.entrySet()) {
+ try {
+ log.debug("Closing the watch {}", entry.getKey());
+ entry.getValue().close();
+
+ } catch (Exception e) {
+ log.error("Error while closing the watch connection", e);
+ }
+ }
+ }
+ }
+
private void onEvent(ConfigMap configMap) {
MapPropertySource currentConfigMapSource = findPropertySource(ConfigMapPropertySource.class);
if (currentConfigMapSource != null) {
diff --git a/spring-cloud-kubernetes-core/src/main/java/io/fabric8/spring/cloud/kubernetes/reload/EventWatcher.java b/spring-cloud-kubernetes-core/src/main/java/io/fabric8/spring/cloud/kubernetes/reload/EventWatcher.java
deleted file mode 100644
index 24f5061e..00000000
--- a/spring-cloud-kubernetes-core/src/main/java/io/fabric8/spring/cloud/kubernetes/reload/EventWatcher.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package io.fabric8.spring.cloud.kubernetes.reload;
-
-import java.util.function.Function;
-
-import io.fabric8.kubernetes.client.KubernetesClient;
-import io.fabric8.kubernetes.client.Watch;
-
-/**
- * Provides a way to start Kubernetes watches and bind their lifecycle to the application context.
- */
-public interface EventWatcher {
-
- void addWatch(String name, Function watch);
-
-}
diff --git a/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml
index 71d3314d..addde65e 100644
--- a/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml
+++ b/spring-cloud-kubernetes-examples/kubernetes-reload-example/pom.xml
@@ -62,15 +62,39 @@
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+
+
+ repackage
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+ ${maven-deploy-plugin.version}
+
+ true
+
+
+
io.fabric8
fabric8-maven-plugin
${fabric8.maven.plugin.version}
+ fmp
resource
- build
+ helm
@@ -78,4 +102,53 @@
+
+
+ release
+
+
+
+ io.fabric8
+ fabric8-maven-plugin
+ ${fabric8.maven.plugin.version}
+
+
+ fmp
+
+ resource
+ helm
+ build
+ push
+
+
+
+
+
+
+
+
+
+ docker
+
+
+
+ io.fabric8
+ fabric8-maven-plugin
+ ${fabric8.maven.plugin.version}
+
+
+ fmp
+
+ resource
+ helm
+ build
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-cloud-kubernetes-examples/kubernetes-reload-example/readme.md b/spring-cloud-kubernetes-examples/kubernetes-reload-example/readme.md
index 6c65369b..2817c7d1 100644
--- a/spring-cloud-kubernetes-examples/kubernetes-reload-example/readme.md
+++ b/spring-cloud-kubernetes-examples/kubernetes-reload-example/readme.md
@@ -16,7 +16,7 @@ oc policy add-role-to-user view --serviceaccount=default
You can deploy the application using the fabric8 maven plugin:
```
-mvn clean install fabric8:deploy
+mvn clean install fabric8:build fabric8:deploy
```
### Changing the configuration