Reload functionality clean-up part 3 (#1034)

This commit is contained in:
erabii
2022-06-28 01:28:56 +03:00
committed by GitHub
parent 5692f2f590
commit 774e3ade7f
14 changed files with 203 additions and 451 deletions

View File

@@ -47,6 +47,7 @@ import org.springframework.cloud.kubernetes.commons.config.reload.condition.Poll
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.env.AbstractEnvironment;
/**
@@ -56,7 +57,8 @@ import org.springframework.core.env.AbstractEnvironment;
@ConditionalOnKubernetesAndConfigEnabled
@ConditionalOnClass(EndpointAutoConfiguration.class)
@AutoConfigureAfter({ InfoEndpointAutoConfiguration.class, RefreshEndpointAutoConfiguration.class,
RefreshAutoConfiguration.class, ConfigReloadAutoConfiguration.class })
RefreshAutoConfiguration.class })
@Import(ConfigReloadAutoConfiguration.class)
@EnableConfigurationProperties(ConfigReloadProperties.class)
public class KubernetesClientConfigReloadAutoConfiguration {

View File

@@ -179,7 +179,7 @@ class KubernetesClientEventBasedConfigMapChangeDetectorTests {
}
@Override
public OffsetDateTime read(JsonReader jsonReader) throws IOException {
public OffsetDateTime read(JsonReader jsonReader) {
return OffsetDateTime.now();
}

View File

@@ -176,7 +176,7 @@ class KubernetesClientEventBasedSecretsChangeDetectorTests {
}
@Override
public OffsetDateTime read(JsonReader jsonReader) throws IOException {
public OffsetDateTime read(JsonReader jsonReader) {
return OffsetDateTime.now();
}

View File

@@ -45,66 +45,51 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
@ConditionalOnKubernetesAndConfigEnabled
@ConditionalOnClass(EndpointAutoConfiguration.class)
@AutoConfigureAfter({ InfoEndpointAutoConfiguration.class, RefreshEndpointAutoConfiguration.class,
RefreshAutoConfiguration.class })
RefreshAutoConfiguration.class, RestartEndpoint.class, ContextRefresher.class })
@ConditionalOnProperty("spring.cloud.kubernetes.reload.enabled")
public class ConfigReloadAutoConfiguration {
/**
* Configuration reload must be enabled explicitly.
*/
@ConditionalOnProperty("spring.cloud.kubernetes.reload.enabled")
@ConditionalOnClass({ RestartEndpoint.class, ContextRefresher.class })
protected static class ConfigReloadAutoConfigurationBeans {
@Bean("springCloudKubernetesTaskScheduler")
@ConditionalOnMissingBean
public TaskSchedulerWrapper<TaskScheduler> taskScheduler() {
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
@Bean("springCloudKubernetesTaskScheduler")
@ConditionalOnMissingBean
public TaskSchedulerWrapper<TaskScheduler> taskScheduler() {
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setThreadNamePrefix("spring-cloud-kubernetes-ThreadPoolTaskScheduler-");
threadPoolTaskScheduler.setDaemon(true);
threadPoolTaskScheduler.setThreadNamePrefix("spring-cloud-kubernetes-ThreadPoolTaskScheduler-");
threadPoolTaskScheduler.setDaemon(true);
return new TaskSchedulerWrapper<>(threadPoolTaskScheduler);
}
return new TaskSchedulerWrapper<>(threadPoolTaskScheduler);
@Bean
@ConditionalOnMissingBean
public ConfigurationUpdateStrategy configurationUpdateStrategy(ConfigReloadProperties properties,
ConfigurableApplicationContext ctx, @Autowired(required = false) RestartEndpoint restarter,
ContextRefresher refresher) {
switch (properties.getStrategy()) {
case RESTART_CONTEXT:
Objects.requireNonNull(restarter, "Restart endpoint is not enabled");
return new ConfigurationUpdateStrategy(properties.getStrategy().name(), () -> {
wait(properties);
restarter.restart();
});
case REFRESH:
return new ConfigurationUpdateStrategy(properties.getStrategy().name(), refresher::refresh);
case SHUTDOWN:
return new ConfigurationUpdateStrategy(properties.getStrategy().name(), () -> {
wait(properties);
ctx.close();
});
}
throw new IllegalStateException("Unsupported configuration update strategy: " + properties.getStrategy());
}
/**
* @param properties config reload properties
* @param ctx application context
* @param restarter restart endpoint
* @param refresher context refresher
* @return provides the action to execute when the configuration changes.
*/
@Bean
@ConditionalOnMissingBean
public ConfigurationUpdateStrategy configurationUpdateStrategy(ConfigReloadProperties properties,
ConfigurableApplicationContext ctx, @Autowired(required = false) RestartEndpoint restarter,
ContextRefresher refresher) {
switch (properties.getStrategy()) {
case RESTART_CONTEXT:
Objects.requireNonNull(restarter, "Restart endpoint is not enabled");
return new ConfigurationUpdateStrategy(properties.getStrategy().name(), () -> {
wait(properties);
restarter.restart();
});
case REFRESH:
return new ConfigurationUpdateStrategy(properties.getStrategy().name(), refresher::refresh);
case SHUTDOWN:
return new ConfigurationUpdateStrategy(properties.getStrategy().name(), () -> {
wait(properties);
ctx.close();
});
}
throw new IllegalStateException("Unsupported configuration update strategy: " + properties.getStrategy());
private static void wait(ConfigReloadProperties properties) {
final long waitMillis = ThreadLocalRandom.current().nextLong(properties.getMaxWaitForRestart().toMillis());
try {
Thread.sleep(waitMillis);
}
private static void wait(ConfigReloadProperties properties) {
final long waitMillis = ThreadLocalRandom.current().nextLong(properties.getMaxWaitForRestart().toMillis());
try {
Thread.sleep(waitMillis);
}
catch (InterruptedException ignored) {
}
catch (InterruptedException ignored) {
}
}
}

View File

@@ -29,7 +29,7 @@ import reactor.core.publisher.Mono;
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadProperties;
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationUpdateStrategy;
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySourceLocator;
import org.springframework.cloud.kubernetes.fabric8.config.reload.EventBasedConfigMapChangeDetector;
import org.springframework.cloud.kubernetes.fabric8.config.reload.Fabric8EventBasedConfigMapChangeDetector;
import org.springframework.core.env.AbstractEnvironment;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@@ -37,7 +37,7 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
* @author Ryan Baxter
* @author Kris Iyer
*/
public abstract class ConfigMapWatcherChangeDetector extends EventBasedConfigMapChangeDetector {
public abstract class ConfigMapWatcherChangeDetector extends Fabric8EventBasedConfigMapChangeDetector {
protected Log log = LogFactory.getLog(getClass());

View File

@@ -29,7 +29,7 @@ import reactor.core.publisher.Mono;
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadProperties;
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationUpdateStrategy;
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySourceLocator;
import org.springframework.cloud.kubernetes.fabric8.config.reload.EventBasedSecretsChangeDetector;
import org.springframework.cloud.kubernetes.fabric8.config.reload.Fabric8EventBasedSecretsChangeDetector;
import org.springframework.core.env.AbstractEnvironment;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@@ -37,7 +37,7 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
* @author Ryan Baxter
* @author Kris Iyer
*/
public abstract class SecretsWatcherChangeDetector extends EventBasedSecretsChangeDetector {
public abstract class SecretsWatcherChangeDetector extends Fabric8EventBasedSecretsChangeDetector {
protected Log log = LogFactory.getLog(getClass());

View File

@@ -1,200 +0,0 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.kubernetes.fabric8.config.reload;
import java.util.concurrent.ThreadLocalRandom;
import io.fabric8.kubernetes.client.KubernetesClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
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.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.cloud.kubernetes.commons.config.reload.ConfigReloadProperties;
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationChangeDetector;
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationUpdateStrategy;
import org.springframework.cloud.kubernetes.commons.config.reload.PollingConfigMapChangeDetector;
import org.springframework.cloud.kubernetes.commons.config.reload.PollingSecretsChangeDetector;
import org.springframework.cloud.kubernetes.commons.config.reload.condition.EventReloadDetectionMode;
import org.springframework.cloud.kubernetes.commons.config.reload.condition.PollingReloadDetectionMode;
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySource;
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySourceLocator;
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySource;
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySourceLocator;
import org.springframework.context.ConfigurableApplicationContext;
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.util.Assert;
/**
* Definition of beans needed for the automatic reload of configuration.
*
* @author Nicolla Ferraro
* @author Kris Iyer
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnKubernetesAndConfigEnabled
@ConditionalOnClass(EndpointAutoConfiguration.class)
@AutoConfigureAfter({ InfoEndpointAutoConfiguration.class, RefreshEndpointAutoConfiguration.class,
RefreshAutoConfiguration.class })
@EnableConfigurationProperties(ConfigReloadProperties.class)
public class ConfigReloadAutoConfiguration {
/**
* Configuration reload must be enabled explicitly.
*/
@ConditionalOnProperty("spring.cloud.kubernetes.reload.enabled")
@ConditionalOnClass({ RestartEndpoint.class, ContextRefresher.class })
protected static class ConfigReloadAutoConfigurationBeans {
@Autowired
private AbstractEnvironment environment;
@Autowired
private KubernetesClient kubernetesClient;
/**
* Polling configMap ConfigurationChangeDetector.
* @param properties config reload properties
* @param strategy configuration update strategy
* @param fabric8ConfigMapPropertySourceLocator configMap property source locator
* @return a bean that listen to configuration changes and fire a reload.
*/
@Bean
@ConditionalOnBean(Fabric8ConfigMapPropertySourceLocator.class)
@Conditional(PollingReloadDetectionMode.class)
public ConfigurationChangeDetector configMapPropertyChangePollingWatcher(ConfigReloadProperties properties,
ConfigurationUpdateStrategy strategy,
Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator,
TaskSchedulerWrapper taskSchedulerWrapper) {
return new PollingConfigMapChangeDetector(this.environment, properties, strategy,
Fabric8ConfigMapPropertySource.class, fabric8ConfigMapPropertySourceLocator,
taskSchedulerWrapper.getTaskScheduler());
}
/**
* Polling secrets ConfigurationChangeDetector.
* @param properties config reload properties
* @param strategy configuration update strategy
* @param fabric8SecretsPropertySourceLocator secrets property source locator
* @return a bean that listen to configuration changes and fire a reload.
*/
@Bean
@ConditionalOnBean(Fabric8SecretsPropertySourceLocator.class)
@Conditional(PollingReloadDetectionMode.class)
public ConfigurationChangeDetector secretsPropertyChangePollingWatcher(ConfigReloadProperties properties,
ConfigurationUpdateStrategy strategy,
Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator,
TaskSchedulerWrapper taskScheduler) {
return new PollingSecretsChangeDetector(this.environment, properties, strategy,
Fabric8SecretsPropertySource.class, fabric8SecretsPropertySourceLocator,
taskScheduler.getTaskScheduler());
}
/**
* Event Based configMap ConfigurationChangeDetector.
* @param properties config reload properties
* @param strategy configuration update strategy
* @param fabric8ConfigMapPropertySourceLocator configMap property source locator
* @return a bean that listen to configMap change events and fire a reload.
*/
@Bean
@ConditionalOnBean(Fabric8ConfigMapPropertySourceLocator.class)
@Conditional(EventReloadDetectionMode.class)
public ConfigurationChangeDetector configMapPropertyChangeEventWatcher(ConfigReloadProperties properties,
ConfigurationUpdateStrategy strategy,
Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator) {
return new EventBasedConfigMapChangeDetector(this.environment, properties, this.kubernetesClient, strategy,
fabric8ConfigMapPropertySourceLocator);
}
/**
* Event Based secrets ConfigurationChangeDetector.
* @param properties config reload properties
* @param strategy configuration update strategy
* @param fabric8SecretsPropertySourceLocator secrets property source locator
* @return a bean that listen to secrets change events and fire a reload.
*/
@Bean
@ConditionalOnBean(Fabric8SecretsPropertySourceLocator.class)
@Conditional(EventReloadDetectionMode.class)
public ConfigurationChangeDetector secretsPropertyChangeEventWatcher(ConfigReloadProperties properties,
ConfigurationUpdateStrategy strategy,
Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator) {
return new EventBasedSecretsChangeDetector(this.environment, properties, this.kubernetesClient, strategy,
fabric8SecretsPropertySourceLocator);
}
/**
* @param properties config reload properties
* @param ctx application context
* @param restarter restart endpoint
* @param refresher context refresher
* @return provides the action to execute when the configuration changes.
*/
@Bean
@ConditionalOnMissingBean
public ConfigurationUpdateStrategy configurationUpdateStrategy(ConfigReloadProperties properties,
ConfigurableApplicationContext ctx, @Autowired(required = false) RestartEndpoint restarter,
ContextRefresher refresher) {
switch (properties.getStrategy()) {
case RESTART_CONTEXT:
Assert.notNull(restarter, "Restart endpoint is not enabled");
return new ConfigurationUpdateStrategy(properties.getStrategy().name(), () -> {
wait(properties);
restarter.restart();
});
case REFRESH:
return new ConfigurationUpdateStrategy(properties.getStrategy().name(), refresher::refresh);
case SHUTDOWN:
return new ConfigurationUpdateStrategy(properties.getStrategy().name(), () -> {
wait(properties);
ctx.close();
});
}
throw new IllegalStateException("Unsupported configuration update strategy: " + properties.getStrategy());
}
private static void wait(ConfigReloadProperties properties) {
final long waitMillis = ThreadLocalRandom.current().nextLong(properties.getMaxWaitForRestart().toMillis());
try {
Thread.sleep(waitMillis);
}
catch (InterruptedException ignored) {
}
}
}
}

View File

@@ -1,182 +0,0 @@
/*
* Copyright 2013-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.kubernetes.fabric8.config.reload;
import java.util.concurrent.ThreadLocalRandom;
import io.fabric8.kubernetes.client.KubernetesClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnCloudPlatform;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.cloud.CloudPlatform;
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;
import org.springframework.cloud.kubernetes.commons.config.reload.PollingConfigMapChangeDetector;
import org.springframework.cloud.kubernetes.commons.config.reload.PollingSecretsChangeDetector;
import org.springframework.cloud.kubernetes.commons.config.reload.condition.EventReloadDetectionMode;
import org.springframework.cloud.kubernetes.commons.config.reload.condition.PollingReloadDetectionMode;
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySource;
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySourceLocator;
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySource;
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySourceLocator;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.AbstractEnvironment;
/**
* @author Ryan Baxter
* @author Kris Iyer
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES)
@ConditionalOnMissingBean(ConfigReloadAutoConfiguration.class)
@EnableConfigurationProperties(ConfigReloadProperties.class)
public class ConfigReloadDefaultAutoConfiguration {
/**
* Configuration reload must be enabled explicitly.
*/
@ConditionalOnProperty("spring.cloud.kubernetes.reload.enabled")
protected static class ConfigReloadAutoConfigurationBeans {
@Autowired
private AbstractEnvironment environment;
@Autowired
private KubernetesClient kubernetesClient;
@Autowired
private Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator;
@Autowired
private Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator;
private static void wait(ConfigReloadProperties properties) {
final long waitMillis = ThreadLocalRandom.current().nextLong(properties.getMaxWaitForRestart().toMillis());
try {
Thread.sleep(waitMillis);
}
catch (InterruptedException ignored) {
}
}
/**
* Polling configMap ConfigurationChangeDetector.
* @param properties config reload properties
* @param strategy configuration update strategy
* @param fabric8ConfigMapPropertySourceLocator configMap property source locator
* @return a bean that listen to configuration changes and fire a reload.
*/
@Bean
@ConditionalOnBean(Fabric8ConfigMapPropertySourceLocator.class)
@Conditional(PollingReloadDetectionMode.class)
public ConfigurationChangeDetector configMapPropertyChangePollingWatcher(ConfigReloadProperties properties,
ConfigurationUpdateStrategy strategy,
Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator,
TaskSchedulerWrapper taskSchedulerWrapper) {
return new PollingConfigMapChangeDetector(this.environment, properties, strategy,
Fabric8ConfigMapPropertySource.class, fabric8ConfigMapPropertySourceLocator,
taskSchedulerWrapper.getTaskScheduler());
}
/**
* Polling secrets ConfigurationChangeDetector.
* @param properties config reload properties
* @param strategy configuration update strategy
* @param fabric8SecretsPropertySourceLocator secrets property source locator
* @return a bean that listen to configuration changes and fire a reload.
*/
@Bean
@ConditionalOnBean(Fabric8SecretsPropertySourceLocator.class)
@Conditional(PollingReloadDetectionMode.class)
public ConfigurationChangeDetector secretsPropertyChangePollingWatcher(ConfigReloadProperties properties,
ConfigurationUpdateStrategy strategy,
Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator,
TaskSchedulerWrapper taskScheduler) {
return new PollingSecretsChangeDetector(this.environment, properties, strategy,
Fabric8SecretsPropertySource.class, fabric8SecretsPropertySourceLocator,
taskScheduler.getTaskScheduler());
}
/**
* Event Based configMap ConfigurationChangeDetector.
* @param properties config reload properties
* @param strategy configuration update strategy
* @param fabric8ConfigMapPropertySourceLocator configMap property source locator
* @return a bean that listen to configMap change events and fire a reload.
*/
@Bean
@ConditionalOnBean(Fabric8ConfigMapPropertySourceLocator.class)
@Conditional(EventReloadDetectionMode.class)
public ConfigurationChangeDetector configMapPropertyChangeEventWatcher(ConfigReloadProperties properties,
ConfigurationUpdateStrategy strategy,
Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator) {
return new EventBasedConfigMapChangeDetector(this.environment, properties, this.kubernetesClient, strategy,
fabric8ConfigMapPropertySourceLocator);
}
/**
* Event Based secrets ConfigurationChangeDetector.
* @param properties config reload properties
* @param strategy configuration update strategy
* @param fabric8SecretsPropertySourceLocator secrets property source locator
* @return a bean that listen to secrets change events and fire a reload.
*/
@Bean
@ConditionalOnBean(Fabric8SecretsPropertySourceLocator.class)
@Conditional(EventReloadDetectionMode.class)
public ConfigurationChangeDetector secretsPropertyChangeEventWatcher(ConfigReloadProperties properties,
ConfigurationUpdateStrategy strategy,
Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator) {
return new EventBasedSecretsChangeDetector(this.environment, properties, this.kubernetesClient, strategy,
fabric8SecretsPropertySourceLocator);
}
/**
* @param properties config reload properties
* @param ctx application context
* @return provides the action to execute when the configuration changes.
*/
@Bean
@ConditionalOnMissingBean
public ConfigurationUpdateStrategy configurationUpdateStrategy(ConfigReloadProperties properties,
ConfigurableApplicationContext ctx) {
switch (properties.getStrategy()) {
case SHUTDOWN:
return new ConfigurationUpdateStrategy(properties.getStrategy().name(), () -> {
wait(properties);
ctx.close();
});
}
throw new IllegalStateException("Unsupported configuration update strategy: " + properties.getStrategy());
}
}
}

View File

@@ -0,0 +1,146 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.kubernetes.fabric8.config.reload;
import io.fabric8.kubernetes.client.KubernetesClient;
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
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;
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadAutoConfiguration;
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;
import org.springframework.cloud.kubernetes.commons.config.reload.PollingConfigMapChangeDetector;
import org.springframework.cloud.kubernetes.commons.config.reload.PollingSecretsChangeDetector;
import org.springframework.cloud.kubernetes.commons.config.reload.condition.EventReloadDetectionMode;
import org.springframework.cloud.kubernetes.commons.config.reload.condition.PollingReloadDetectionMode;
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySource;
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySourceLocator;
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySource;
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySourceLocator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.env.AbstractEnvironment;
import org.springframework.scheduling.TaskScheduler;
/**
* Definition of beans needed for the automatic reload of configuration.
*
* @author Nicolla Ferraro
* @author Kris Iyer
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnKubernetesAndConfigEnabled
@ConditionalOnClass(EndpointAutoConfiguration.class)
@AutoConfigureAfter({ InfoEndpointAutoConfiguration.class, RefreshEndpointAutoConfiguration.class,
RefreshAutoConfiguration.class, RestartEndpoint.class, ContextRefresher.class })
@EnableConfigurationProperties(ConfigReloadProperties.class)
@ConditionalOnProperty("spring.cloud.kubernetes.reload.enabled")
@Import(ConfigReloadAutoConfiguration.class)
public class Fabric8ConfigReloadAutoConfiguration {
/**
* Polling configMap ConfigurationChangeDetector.
* @param properties config reload properties
* @param strategy configuration update strategy
* @param fabric8ConfigMapPropertySourceLocator configMap property source locator
* @return a bean that listen to configuration changes and fire a reload.
*/
@Bean
@ConditionalOnBean(Fabric8ConfigMapPropertySourceLocator.class)
@Conditional(PollingReloadDetectionMode.class)
public ConfigurationChangeDetector configMapPropertyChangePollingWatcher(ConfigReloadProperties properties,
ConfigurationUpdateStrategy strategy,
Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator,
TaskSchedulerWrapper<TaskScheduler> taskSchedulerWrapper, AbstractEnvironment environment) {
return new PollingConfigMapChangeDetector(environment, properties, strategy,
Fabric8ConfigMapPropertySource.class, fabric8ConfigMapPropertySourceLocator,
taskSchedulerWrapper.getTaskScheduler());
}
/**
* Polling secrets ConfigurationChangeDetector.
* @param properties config reload properties
* @param strategy configuration update strategy
* @param fabric8SecretsPropertySourceLocator secrets property source locator
* @return a bean that listen to configuration changes and fire a reload.
*/
@Bean
@ConditionalOnBean(Fabric8SecretsPropertySourceLocator.class)
@Conditional(PollingReloadDetectionMode.class)
public ConfigurationChangeDetector secretsPropertyChangePollingWatcher(ConfigReloadProperties properties,
ConfigurationUpdateStrategy strategy,
Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator,
TaskSchedulerWrapper<TaskScheduler> taskScheduler, AbstractEnvironment environment) {
return new PollingSecretsChangeDetector(environment, properties, strategy, Fabric8SecretsPropertySource.class,
fabric8SecretsPropertySourceLocator, taskScheduler.getTaskScheduler());
}
/**
* Event Based configMap ConfigurationChangeDetector.
* @param properties config reload properties
* @param strategy configuration update strategy
* @param fabric8ConfigMapPropertySourceLocator configMap property source locator
* @return a bean that listen to configMap change events and fire a reload.
*/
@Bean
@ConditionalOnBean(Fabric8ConfigMapPropertySourceLocator.class)
@Conditional(EventReloadDetectionMode.class)
public ConfigurationChangeDetector configMapPropertyChangeEventWatcher(ConfigReloadProperties properties,
ConfigurationUpdateStrategy strategy,
Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator,
AbstractEnvironment environment, KubernetesClient kubernetesClient) {
return new Fabric8EventBasedConfigMapChangeDetector(environment, properties, kubernetesClient, strategy,
fabric8ConfigMapPropertySourceLocator);
}
/**
* Event Based secrets ConfigurationChangeDetector.
* @param properties config reload properties
* @param strategy configuration update strategy
* @param fabric8SecretsPropertySourceLocator secrets property source locator
* @return a bean that listen to secrets change events and fire a reload.
*/
@Bean
@ConditionalOnBean(Fabric8SecretsPropertySourceLocator.class)
@Conditional(EventReloadDetectionMode.class)
public ConfigurationChangeDetector secretsPropertyChangeEventWatcher(ConfigReloadProperties properties,
ConfigurationUpdateStrategy strategy,
Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator, AbstractEnvironment environment,
KubernetesClient kubernetesClient) {
return new Fabric8EventBasedSecretsChangeDetector(environment, properties, kubernetesClient, strategy,
fabric8SecretsPropertySourceLocator);
}
}

View File

@@ -46,7 +46,7 @@ import org.springframework.core.env.AbstractEnvironment;
* @author Haytham Mohamed
* @author Kris Iyer
*/
public class EventBasedConfigMapChangeDetector extends ConfigurationChangeDetector {
public class Fabric8EventBasedConfigMapChangeDetector extends ConfigurationChangeDetector {
private final Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator;
@@ -54,7 +54,7 @@ public class EventBasedConfigMapChangeDetector extends ConfigurationChangeDetect
private KubernetesClient kubernetesClient;
public EventBasedConfigMapChangeDetector(AbstractEnvironment environment, ConfigReloadProperties properties,
public Fabric8EventBasedConfigMapChangeDetector(AbstractEnvironment environment, ConfigReloadProperties properties,
KubernetesClient kubernetesClient, ConfigurationUpdateStrategy strategy,
Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator) {
super(environment, properties, strategy);

View File

@@ -46,7 +46,7 @@ import org.springframework.core.env.AbstractEnvironment;
* @author Haytham Mohamed
* @author Kris Iyer
*/
public class EventBasedSecretsChangeDetector extends ConfigurationChangeDetector {
public class Fabric8EventBasedSecretsChangeDetector extends ConfigurationChangeDetector {
private Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator;
@@ -54,7 +54,7 @@ public class EventBasedSecretsChangeDetector extends ConfigurationChangeDetector
private KubernetesClient kubernetesClient;
public EventBasedSecretsChangeDetector(AbstractEnvironment environment, ConfigReloadProperties properties,
public Fabric8EventBasedSecretsChangeDetector(AbstractEnvironment environment, ConfigReloadProperties properties,
KubernetesClient kubernetesClient, ConfigurationUpdateStrategy strategy,
Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator) {
super(environment, properties, strategy);

View File

@@ -1,5 +1,5 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.kubernetes.fabric8.config.reload.ConfigReloadAutoConfiguration
org.springframework.cloud.kubernetes.fabric8.config.reload.Fabric8ConfigReloadAutoConfiguration
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.springframework.cloud.kubernetes.fabric8.config.Fabric8BootstrapConfiguration,\
org.springframework.cloud.kubernetes.fabric8.config.Fabric8RetryBootstrapConfiguration

View File

@@ -35,7 +35,7 @@ import org.springframework.cloud.kubernetes.commons.config.NamedConfigMapNormali
import org.springframework.cloud.kubernetes.commons.config.NormalizedSource;
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadProperties;
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationUpdateStrategy;
import org.springframework.cloud.kubernetes.fabric8.config.reload.EventBasedConfigMapChangeDetector;
import org.springframework.cloud.kubernetes.fabric8.config.reload.Fabric8EventBasedConfigMapChangeDetector;
import org.springframework.mock.env.MockEnvironment;
import static org.assertj.core.api.Assertions.assertThat;
@@ -78,8 +78,8 @@ class EventBasedConfigurationChangeDetectorTests {
});
Fabric8ConfigMapPropertySourceLocator configMapLocator = mock(Fabric8ConfigMapPropertySourceLocator.class);
EventBasedConfigMapChangeDetector detector = new EventBasedConfigMapChangeDetector(env, configReloadProperties,
k8sClient, configurationUpdateStrategy, configMapLocator);
Fabric8EventBasedConfigMapChangeDetector detector = new Fabric8EventBasedConfigMapChangeDetector(env,
configReloadProperties, k8sClient, configurationUpdateStrategy, configMapLocator);
List<Fabric8ConfigMapPropertySource> sources = detector
.findPropertySources(Fabric8ConfigMapPropertySource.class);
assertThat(sources.size()).isEqualTo(1);

View File

@@ -25,7 +25,7 @@ import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoCon
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration;
import org.springframework.cloud.bootstrap.BootstrapConfiguration;
import org.springframework.cloud.kubernetes.fabric8.config.reload.ConfigReloadAutoConfiguration;
import org.springframework.cloud.kubernetes.fabric8.config.reload.Fabric8ConfigReloadAutoConfiguration;
import org.springframework.context.ConfigurableApplicationContext;
/**
@@ -45,8 +45,9 @@ public class KubernetesConfigTestBase {
String[] properties = Stream.concat(Arrays.stream(commonProperties), Arrays.stream(env))
.toArray(size -> new String[size]);
context = new SpringApplicationBuilder(PropertyPlaceholderAutoConfiguration.class, mockClientConfiguration,
BootstrapConfiguration.class, ConfigReloadAutoConfiguration.class, RefreshAutoConfiguration.class)
.web(org.springframework.boot.WebApplicationType.NONE).properties(properties).run();
BootstrapConfiguration.class, Fabric8ConfigReloadAutoConfiguration.class,
RefreshAutoConfiguration.class).web(org.springframework.boot.WebApplicationType.NONE)
.properties(properties).run();
}
@AfterEach