diff --git a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientConfigReloadAutoConfiguration.java b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientConfigReloadAutoConfiguration.java index 19b05b55..eb1f9e33 100644 --- a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientConfigReloadAutoConfiguration.java +++ b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientConfigReloadAutoConfiguration.java @@ -27,6 +27,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; import org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration; +import org.springframework.cloud.commons.util.TaskSchedulerWrapper; import org.springframework.cloud.context.refresh.ContextRefresher; import org.springframework.cloud.context.restart.RestartEndpoint; import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySource; @@ -47,8 +48,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.AbstractEnvironment; -import org.springframework.scheduling.annotation.EnableAsync; -import org.springframework.scheduling.annotation.EnableScheduling; /** * @author Ryan Baxter @@ -66,8 +65,6 @@ public class KubernetesClientConfigReloadAutoConfiguration { */ @ConditionalOnProperty("spring.cloud.kubernetes.reload.enabled") @ConditionalOnClass({ RestartEndpoint.class, ContextRefresher.class }) - @EnableScheduling - @EnableAsync protected static class ConfigReloadAutoConfigurationBeans { /** @@ -83,10 +80,11 @@ public class KubernetesClientConfigReloadAutoConfiguration { public ConfigurationChangeDetector configMapPropertyChangePollingWatcher(ConfigReloadProperties properties, ConfigurationUpdateStrategy strategy, KubernetesClientConfigMapPropertySourceLocator configMapPropertySourceLocator, - AbstractEnvironment environment) { + AbstractEnvironment environment, TaskSchedulerWrapper taskScheduler) { return new PollingConfigMapChangeDetector(environment, properties, strategy, - KubernetesClientConfigMapPropertySource.class, configMapPropertySourceLocator); + KubernetesClientConfigMapPropertySource.class, configMapPropertySourceLocator, + taskScheduler.getTaskScheduler()); } /** @@ -102,10 +100,11 @@ public class KubernetesClientConfigReloadAutoConfiguration { public ConfigurationChangeDetector secretsPropertyChangePollingWatcher(ConfigReloadProperties properties, ConfigurationUpdateStrategy strategy, KubernetesClientSecretsPropertySourceLocator secretsPropertySourceLocator, - AbstractEnvironment environment) { + AbstractEnvironment environment, TaskSchedulerWrapper taskScheduler) { return new PollingSecretsChangeDetector(environment, properties, strategy, - KubernetesClientSecretsPropertySource.class, secretsPropertySourceLocator); + KubernetesClientSecretsPropertySource.class, secretsPropertySourceLocator, + taskScheduler.getTaskScheduler()); } /** diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java index b64fe81f..67b066bb 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadAutoConfiguration.java @@ -27,12 +27,14 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; import org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration; +import org.springframework.cloud.commons.util.TaskSchedulerWrapper; import org.springframework.cloud.context.refresh.ContextRefresher; import org.springframework.cloud.context.restart.RestartEndpoint; import org.springframework.cloud.kubernetes.commons.config.ConditionalOnKubernetesAndConfigEnabled; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.util.Assert; /** @@ -52,6 +54,17 @@ public class ConfigReloadAutoConfiguration { @ConditionalOnClass({ RestartEndpoint.class, ContextRefresher.class }) protected static class ConfigReloadAutoConfigurationBeans { + @Bean("springCloudKubernetesTaskScheduler") + @ConditionalOnMissingBean + public TaskSchedulerWrapper taskScheduler() { + ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); + + threadPoolTaskScheduler.setThreadNamePrefix("spring-cloud-kubernetes-ThreadPoolTaskScheduler-"); + threadPoolTaskScheduler.setDaemon(true); + + return new TaskSchedulerWrapper(threadPoolTaskScheduler); + } + /** * @param properties config reload properties * @param ctx application context diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingConfigMapChangeDetector.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingConfigMapChangeDetector.java index e8b9701d..05fb547c 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingConfigMapChangeDetector.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingConfigMapChangeDetector.java @@ -16,6 +16,7 @@ package org.springframework.cloud.kubernetes.commons.config.reload; +import java.time.Duration; import java.util.List; import javax.annotation.PostConstruct; @@ -23,10 +24,12 @@ import javax.annotation.PostConstruct; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.boot.task.TaskSchedulerBuilder; import org.springframework.cloud.bootstrap.config.PropertySourceLocator; import org.springframework.core.env.AbstractEnvironment; import org.springframework.core.env.MapPropertySource; -import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.scheduling.TaskScheduler; +import org.springframework.scheduling.support.PeriodicTrigger; /** * A change detector that periodically retrieves configmaps and fire a reload when @@ -44,21 +47,38 @@ public class PollingConfigMapChangeDetector extends ConfigurationChangeDetector private Class propertySourceClass; + private TaskScheduler taskExecutor; + + private Duration period = Duration.ofMillis(1500); + + @Deprecated public PollingConfigMapChangeDetector(AbstractEnvironment environment, ConfigReloadProperties properties, ConfigurationUpdateStrategy strategy, Class propertySourceClass, PropertySourceLocator propertySourceLocator) { super(environment, properties, strategy); this.propertySourceLocator = propertySourceLocator; this.propertySourceClass = propertySourceClass; + this.taskExecutor = new TaskSchedulerBuilder().build(); + } + + public PollingConfigMapChangeDetector(AbstractEnvironment environment, ConfigReloadProperties properties, + ConfigurationUpdateStrategy strategy, Class propertySourceClass, + PropertySourceLocator propertySourceLocator, TaskScheduler taskExecutor) { + super(environment, properties, strategy); + this.propertySourceLocator = propertySourceLocator; + this.propertySourceClass = propertySourceClass; + this.taskExecutor = taskExecutor; + this.period = properties.getPeriod(); } @PostConstruct public void init() { this.log.info("Kubernetes polling configMap change detector activated"); + PeriodicTrigger trigger = new PeriodicTrigger(period.toMillis()); + trigger.setInitialDelay(period.toMillis()); + taskExecutor.schedule(this::executeCycle, trigger); } - @Scheduled(initialDelayString = "${spring.cloud.kubernetes.reload.period:15000}", - fixedDelayString = "${spring.cloud.kubernetes.reload.period:15000}") public void executeCycle() { boolean changedConfigMap = false; diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingSecretsChangeDetector.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingSecretsChangeDetector.java index 4d99c082..3a2873c7 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingSecretsChangeDetector.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/PollingSecretsChangeDetector.java @@ -16,6 +16,7 @@ package org.springframework.cloud.kubernetes.commons.config.reload; +import java.time.Duration; import java.util.List; import javax.annotation.PostConstruct; @@ -23,10 +24,12 @@ import javax.annotation.PostConstruct; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.boot.task.TaskSchedulerBuilder; import org.springframework.cloud.bootstrap.config.PropertySourceLocator; import org.springframework.core.env.AbstractEnvironment; import org.springframework.core.env.MapPropertySource; -import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.scheduling.TaskScheduler; +import org.springframework.scheduling.support.PeriodicTrigger; /** * A change detector that periodically retrieves secrets and fire a reload when something @@ -44,21 +47,38 @@ public class PollingSecretsChangeDetector extends ConfigurationChangeDetector { private Class propertySourceClass; + private TaskScheduler taskExecutor; + + private Duration period = Duration.ofMillis(1500); + + @Deprecated public PollingSecretsChangeDetector(AbstractEnvironment environment, ConfigReloadProperties properties, ConfigurationUpdateStrategy strategy, Class propertySourceClass, PropertySourceLocator propertySourceLocator) { super(environment, properties, strategy); this.propertySourceClass = propertySourceClass; this.propertySourceLocator = propertySourceLocator; + this.taskExecutor = new TaskSchedulerBuilder().build(); + } + + public PollingSecretsChangeDetector(AbstractEnvironment environment, ConfigReloadProperties properties, + ConfigurationUpdateStrategy strategy, Class propertySourceClass, + PropertySourceLocator propertySourceLocator, TaskScheduler taskExecutor) { + super(environment, properties, strategy); + this.propertySourceLocator = propertySourceLocator; + this.propertySourceClass = propertySourceClass; + this.taskExecutor = taskExecutor; + this.period = properties.getPeriod(); } @PostConstruct public void init() { this.log.info("Kubernetes polling secrets change detector activated"); + PeriodicTrigger trigger = new PeriodicTrigger(period.toMillis()); + trigger.setInitialDelay(period.toMillis()); + taskExecutor.schedule(this::executeCycle, trigger); } - @Scheduled(initialDelayString = "${spring.cloud.kubernetes.reload.period:15000}", - fixedDelayString = "${spring.cloud.kubernetes.reload.period:15000}") public void executeCycle() { boolean changedSecrets = false; diff --git a/spring-cloud-kubernetes-fabric8-config/pom.xml b/spring-cloud-kubernetes-fabric8-config/pom.xml index 46d159a6..85cdb485 100644 --- a/spring-cloud-kubernetes-fabric8-config/pom.xml +++ b/spring-cloud-kubernetes-fabric8-config/pom.xml @@ -50,7 +50,6 @@ org.springframework.boot spring-boot-autoconfigure - org.springframework.cloud spring-cloud-starter @@ -60,7 +59,10 @@ org.springframework.cloud spring-cloud-starter-bootstrap - + + org.springframework.cloud + spring-cloud-commons + org.springframework.security spring-security-rsa diff --git a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/ConfigReloadAutoConfiguration.java b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/ConfigReloadAutoConfiguration.java index 5a47853c..0b933565 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/ConfigReloadAutoConfiguration.java +++ b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/ConfigReloadAutoConfiguration.java @@ -31,6 +31,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; import org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration; +import org.springframework.cloud.commons.util.TaskSchedulerWrapper; import org.springframework.cloud.context.refresh.ContextRefresher; import org.springframework.cloud.context.restart.RestartEndpoint; import org.springframework.cloud.kubernetes.commons.config.ConditionalOnKubernetesAndConfigEnabled; @@ -50,8 +51,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.AbstractEnvironment; -import org.springframework.scheduling.annotation.EnableAsync; -import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.util.Assert; /** @@ -73,8 +72,6 @@ public class ConfigReloadAutoConfiguration { */ @ConditionalOnProperty("spring.cloud.kubernetes.reload.enabled") @ConditionalOnClass({ RestartEndpoint.class, ContextRefresher.class }) - @EnableScheduling - @EnableAsync protected static class ConfigReloadAutoConfigurationBeans { @Autowired @@ -95,10 +92,12 @@ public class ConfigReloadAutoConfiguration { @Conditional(PollingReloadDetectionMode.class) public ConfigurationChangeDetector configMapPropertyChangePollingWatcher(ConfigReloadProperties properties, ConfigurationUpdateStrategy strategy, - Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator) { + Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator, + TaskSchedulerWrapper taskSchedulerWrapper) { return new PollingConfigMapChangeDetector(this.environment, properties, strategy, - Fabric8ConfigMapPropertySource.class, fabric8ConfigMapPropertySourceLocator); + Fabric8ConfigMapPropertySource.class, fabric8ConfigMapPropertySourceLocator, + taskSchedulerWrapper.getTaskScheduler()); } /** @@ -113,10 +112,12 @@ public class ConfigReloadAutoConfiguration { @Conditional(PollingReloadDetectionMode.class) public ConfigurationChangeDetector secretsPropertyChangePollingWatcher(ConfigReloadProperties properties, ConfigurationUpdateStrategy strategy, - Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator) { + Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator, + TaskSchedulerWrapper taskScheduler) { return new PollingSecretsChangeDetector(this.environment, properties, strategy, - Fabric8SecretsPropertySource.class, fabric8SecretsPropertySourceLocator); + Fabric8SecretsPropertySource.class, fabric8SecretsPropertySourceLocator, + taskScheduler.getTaskScheduler()); } /** diff --git a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/ConfigReloadDefaultAutoConfiguration.java b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/ConfigReloadDefaultAutoConfiguration.java index b6e381e5..4fd4e1f8 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/ConfigReloadDefaultAutoConfiguration.java +++ b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/reload/ConfigReloadDefaultAutoConfiguration.java @@ -25,6 +25,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.commons.util.TaskSchedulerWrapper; import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadProperties; import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationChangeDetector; import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationUpdateStrategy; @@ -41,8 +42,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.AbstractEnvironment; -import org.springframework.scheduling.annotation.EnableAsync; -import org.springframework.scheduling.annotation.EnableScheduling; /** * @author Ryan Baxter @@ -58,8 +57,6 @@ public class ConfigReloadDefaultAutoConfiguration { * Configuration reload must be enabled explicitly. */ @ConditionalOnProperty("spring.cloud.kubernetes.reload.enabled") - @EnableScheduling - @EnableAsync protected static class ConfigReloadAutoConfigurationBeans { @Autowired @@ -95,10 +92,12 @@ public class ConfigReloadDefaultAutoConfiguration { @Conditional(PollingReloadDetectionMode.class) public ConfigurationChangeDetector configMapPropertyChangePollingWatcher(ConfigReloadProperties properties, ConfigurationUpdateStrategy strategy, - Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator) { + Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator, + TaskSchedulerWrapper taskSchedulerWrapper) { return new PollingConfigMapChangeDetector(this.environment, properties, strategy, - Fabric8ConfigMapPropertySource.class, fabric8ConfigMapPropertySourceLocator); + Fabric8ConfigMapPropertySource.class, fabric8ConfigMapPropertySourceLocator, + taskSchedulerWrapper.getTaskScheduler()); } /** @@ -113,10 +112,12 @@ public class ConfigReloadDefaultAutoConfiguration { @Conditional(PollingReloadDetectionMode.class) public ConfigurationChangeDetector secretsPropertyChangePollingWatcher(ConfigReloadProperties properties, ConfigurationUpdateStrategy strategy, - Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator) { + Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator, + TaskSchedulerWrapper taskScheduler) { return new PollingSecretsChangeDetector(this.environment, properties, strategy, - Fabric8SecretsPropertySource.class, fabric8SecretsPropertySourceLocator); + Fabric8SecretsPropertySource.class, fabric8SecretsPropertySourceLocator, + taskScheduler.getTaskScheduler()); } /**