delegate reload to common code (#1061)
* fix * simplify labels * fix * fix test * trigger
This commit is contained in:
@@ -29,14 +29,17 @@ import io.kubernetes.client.openapi.models.V1ConfigMapList;
|
||||
import io.kubernetes.client.util.CallGeneratorParams;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.PreDestroy;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySource;
|
||||
import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySourceLocator;
|
||||
import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
|
||||
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadProperties;
|
||||
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadUtil;
|
||||
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationChangeDetector;
|
||||
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationUpdateStrategy;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
|
||||
import static org.springframework.cloud.kubernetes.client.KubernetesClientUtils.createApiClientForInformerClient;
|
||||
import static org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigUtils.namespaces;
|
||||
@@ -46,6 +49,9 @@ import static org.springframework.cloud.kubernetes.client.config.KubernetesClien
|
||||
*/
|
||||
public class KubernetesClientEventBasedConfigMapChangeDetector extends ConfigurationChangeDetector {
|
||||
|
||||
private static final LogAccessor LOG = new LogAccessor(
|
||||
LogFactory.getLog(KubernetesClientEventBasedConfigMapChangeDetector.class));
|
||||
|
||||
private final CoreV1Api coreV1Api;
|
||||
|
||||
private final KubernetesClientConfigMapPropertySourceLocator propertySourceLocator;
|
||||
@@ -64,19 +70,19 @@ public class KubernetesClientEventBasedConfigMapChangeDetector extends Configura
|
||||
|
||||
@Override
|
||||
public void onAdd(V1ConfigMap obj) {
|
||||
log.debug(() -> "ConfigMap " + obj.getMetadata().getName() + " was added.");
|
||||
LOG.debug(() -> "ConfigMap " + obj.getMetadata().getName() + " was added.");
|
||||
onEvent(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(V1ConfigMap oldObj, V1ConfigMap newObj) {
|
||||
log.debug(() -> "ConfigMap " + newObj.getMetadata().getName() + " was updated.");
|
||||
LOG.debug(() -> "ConfigMap " + newObj.getMetadata().getName() + " was updated.");
|
||||
onEvent(newObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDelete(V1ConfigMap obj, boolean deletedFinalStateUnknown) {
|
||||
log.debug(() -> "ConfigMap " + obj.getMetadata() + " was deleted.");
|
||||
LOG.debug(() -> "ConfigMap " + obj.getMetadata() + " was deleted.");
|
||||
onEvent(obj);
|
||||
}
|
||||
};
|
||||
@@ -104,7 +110,7 @@ public class KubernetesClientEventBasedConfigMapChangeDetector extends Configura
|
||||
@PostConstruct
|
||||
void inform() {
|
||||
if (monitorConfigMaps) {
|
||||
log.info(() -> "Kubernetes event-based configMap change detector activated");
|
||||
LOG.info(() -> "Kubernetes event-based configMap change detector activated");
|
||||
|
||||
namespaces.forEach(namespace -> {
|
||||
SharedIndexInformer<V1ConfigMap> informer;
|
||||
@@ -112,10 +118,10 @@ public class KubernetesClientEventBasedConfigMapChangeDetector extends Configura
|
||||
|
||||
if (enableReloadFiltering) {
|
||||
filter = ConfigReloadProperties.RELOAD_LABEL_FILTER + "=true";
|
||||
log.debug(() -> "added configmap informer for namespace : " + namespace + " with enabled filter");
|
||||
LOG.debug(() -> "added configmap informer for namespace : " + namespace + " with enabled filter");
|
||||
}
|
||||
else {
|
||||
log.debug(() -> "added configmap informer for namespace : " + namespace);
|
||||
LOG.debug(() -> "added configmap informer for namespace : " + namespace);
|
||||
}
|
||||
|
||||
String filterOnInformerLabel = filter;
|
||||
@@ -140,16 +146,11 @@ public class KubernetesClientEventBasedConfigMapChangeDetector extends Configura
|
||||
}
|
||||
|
||||
protected void onEvent(V1ConfigMap configMap) {
|
||||
log.debug(() -> "onEvent configMap: " + configMap.toString());
|
||||
boolean changed = changed(locateMapPropertySources(this.propertySourceLocator, this.environment),
|
||||
findPropertySources(KubernetesClientConfigMapPropertySource.class));
|
||||
if (changed) {
|
||||
log.info(() -> "Configuration change detected, reloading properties.");
|
||||
boolean reload = ConfigReloadUtil.reload("config-map", configMap.toString(), propertySourceLocator, environment,
|
||||
KubernetesClientConfigMapPropertySource.class);
|
||||
if (reload) {
|
||||
reloadProperties();
|
||||
}
|
||||
else {
|
||||
log.warn(() -> "Configuration change was not detected.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -29,14 +29,17 @@ import io.kubernetes.client.openapi.models.V1SecretList;
|
||||
import io.kubernetes.client.util.CallGeneratorParams;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.PreDestroy;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsPropertySource;
|
||||
import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsPropertySourceLocator;
|
||||
import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
|
||||
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadProperties;
|
||||
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadUtil;
|
||||
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationChangeDetector;
|
||||
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationUpdateStrategy;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
|
||||
import static org.springframework.cloud.kubernetes.client.KubernetesClientUtils.createApiClientForInformerClient;
|
||||
import static org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigUtils.namespaces;
|
||||
@@ -46,6 +49,9 @@ import static org.springframework.cloud.kubernetes.client.config.KubernetesClien
|
||||
*/
|
||||
public class KubernetesClientEventBasedSecretsChangeDetector extends ConfigurationChangeDetector {
|
||||
|
||||
private static final LogAccessor LOG = new LogAccessor(
|
||||
LogFactory.getLog(KubernetesClientEventBasedSecretsChangeDetector.class));
|
||||
|
||||
private final CoreV1Api coreV1Api;
|
||||
|
||||
private final KubernetesClientSecretsPropertySourceLocator propertySourceLocator;
|
||||
@@ -64,19 +70,19 @@ public class KubernetesClientEventBasedSecretsChangeDetector extends Configurati
|
||||
|
||||
@Override
|
||||
public void onAdd(V1Secret obj) {
|
||||
log.debug(() -> "Secret " + obj.getMetadata().getName() + " was added.");
|
||||
LOG.debug(() -> "Secret " + obj.getMetadata().getName() + " was added.");
|
||||
onEvent(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(V1Secret oldObj, V1Secret newObj) {
|
||||
log.debug(() -> "Secret " + newObj.getMetadata().getName() + " was updated.");
|
||||
LOG.debug(() -> "Secret " + newObj.getMetadata().getName() + " was updated.");
|
||||
onEvent(newObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDelete(V1Secret obj, boolean deletedFinalStateUnknown) {
|
||||
log.debug(() -> "Secret " + obj.getMetadata() + " was deleted.");
|
||||
LOG.debug(() -> "Secret " + obj.getMetadata() + " was deleted.");
|
||||
onEvent(obj);
|
||||
}
|
||||
};
|
||||
@@ -104,7 +110,7 @@ public class KubernetesClientEventBasedSecretsChangeDetector extends Configurati
|
||||
@PostConstruct
|
||||
void inform() {
|
||||
if (monitorSecrets) {
|
||||
log.info(() -> "Kubernetes event-based secrets change detector activated");
|
||||
LOG.info(() -> "Kubernetes event-based secrets change detector activated");
|
||||
|
||||
namespaces.forEach(namespace -> {
|
||||
SharedIndexInformer<V1Secret> informer;
|
||||
@@ -112,10 +118,10 @@ public class KubernetesClientEventBasedSecretsChangeDetector extends Configurati
|
||||
|
||||
if (enableReloadFiltering) {
|
||||
filter = ConfigReloadProperties.RELOAD_LABEL_FILTER + "=true";
|
||||
log.debug(() -> "added secret informer for namespace : " + namespace + " with enabled filter");
|
||||
LOG.debug(() -> "added secret informer for namespace : " + namespace + " with enabled filter");
|
||||
}
|
||||
else {
|
||||
log.debug(() -> "added secret informer for namespace : " + namespace);
|
||||
LOG.debug(() -> "added secret informer for namespace : " + namespace);
|
||||
}
|
||||
|
||||
String filterOnInformerLabel = filter;
|
||||
@@ -139,11 +145,9 @@ public class KubernetesClientEventBasedSecretsChangeDetector extends Configurati
|
||||
}
|
||||
|
||||
protected void onEvent(V1Secret secret) {
|
||||
log.debug(() -> "onEvent secret: " + secret.toString());
|
||||
boolean changed = changed(locateMapPropertySources(this.propertySourceLocator, this.environment),
|
||||
findPropertySources(KubernetesClientSecretsPropertySource.class));
|
||||
if (changed) {
|
||||
log.info(() -> "Detected change in secrets");
|
||||
boolean reload = ConfigReloadUtil.reload("secrets", secret.toString(), propertySourceLocator, environment,
|
||||
KubernetesClientSecretsPropertySource.class);
|
||||
if (reload) {
|
||||
reloadProperties();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright 2013-2022 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.commons.config.reload;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.cloud.bootstrap.config.BootstrapPropertySource;
|
||||
import org.springframework.cloud.bootstrap.config.PropertySourceLocator;
|
||||
import org.springframework.core.env.CompositePropertySource;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
public final class ConfigReloadUtil {
|
||||
|
||||
private ConfigReloadUtil() {
|
||||
|
||||
}
|
||||
|
||||
private static final LogAccessor LOG = new LogAccessor(LogFactory.getLog(ConfigReloadUtil.class));
|
||||
|
||||
public static boolean reload(String target, String eventSourceType, PropertySourceLocator locator,
|
||||
ConfigurableEnvironment environment, Class<? extends MapPropertySource> existingSourcesType) {
|
||||
LOG.debug(() -> "onEvent " + target + ": " + eventSourceType);
|
||||
|
||||
List<? extends MapPropertySource> sourceFromK8s = locateMapPropertySources(locator, environment);
|
||||
List<? extends MapPropertySource> existingSources = findPropertySources(existingSourcesType, environment);
|
||||
|
||||
boolean changed = changed(sourceFromK8s, existingSources);
|
||||
if (changed) {
|
||||
LOG.info("Detected change in config maps");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
LOG.debug("No change detected in config maps, reload will not happen");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param <S> property source type
|
||||
* @param sourceClass class for which property sources will be found
|
||||
* @return finds all registered property sources of the given type
|
||||
*/
|
||||
public static <S extends PropertySource<?>> List<S> findPropertySources(Class<S> sourceClass,
|
||||
ConfigurableEnvironment environment) {
|
||||
List<S> managedSources = new ArrayList<>();
|
||||
|
||||
List<PropertySource<?>> sources = environment.getPropertySources().stream()
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
LOG.debug(() -> "environment: " + environment);
|
||||
LOG.debug(() -> "environment sources: " + sources);
|
||||
|
||||
while (!sources.isEmpty()) {
|
||||
PropertySource<?> source = sources.remove(0);
|
||||
if (source instanceof CompositePropertySource comp) {
|
||||
sources.addAll(comp.getPropertySources());
|
||||
}
|
||||
else if (sourceClass.isInstance(source)) {
|
||||
managedSources.add(sourceClass.cast(source));
|
||||
}
|
||||
else if (source instanceof BootstrapPropertySource) {
|
||||
PropertySource<?> propertySource = ((BootstrapPropertySource<?>) source).getDelegate();
|
||||
if (sourceClass.isInstance(propertySource)) {
|
||||
sources.add(propertySource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return managedSources;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of MapPropertySource that correspond to the current state of the
|
||||
* system. This only handles the PropertySource objects that are returned.
|
||||
* @param propertySourceLocator Spring's property source locator
|
||||
* @param environment Spring environment
|
||||
* @return a list of MapPropertySource that correspond to the current state of the
|
||||
* system
|
||||
*/
|
||||
static List<MapPropertySource> locateMapPropertySources(PropertySourceLocator propertySourceLocator,
|
||||
ConfigurableEnvironment environment) {
|
||||
|
||||
List<MapPropertySource> result = new ArrayList<>();
|
||||
PropertySource<?> propertySource = propertySourceLocator.locate(environment);
|
||||
if (propertySource instanceof MapPropertySource) {
|
||||
result.add((MapPropertySource) propertySource);
|
||||
}
|
||||
else if (propertySource instanceof CompositePropertySource source) {
|
||||
|
||||
List<MapPropertySource> list = source.getPropertySources().stream()
|
||||
.filter(p -> p instanceof MapPropertySource).map(x -> (MapPropertySource) x).toList();
|
||||
result.addAll(list);
|
||||
}
|
||||
else {
|
||||
LOG.debug(() -> "Found property source that cannot be handled: " + propertySource.getClass());
|
||||
}
|
||||
|
||||
LOG.debug(() -> "environment: " + environment);
|
||||
LOG.debug(() -> "sources: " + result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static boolean changed(List<? extends MapPropertySource> left, List<? extends MapPropertySource> right) {
|
||||
if (left.size() != right.size()) {
|
||||
LOG.warn(() -> "The current number of ConfigMap PropertySources does not match "
|
||||
+ "the ones loaded from the Kubernetes - No reload will take place");
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("left size: " + left.size());
|
||||
left.forEach(item -> LOG.debug(item.toString()));
|
||||
|
||||
LOG.debug("right size: " + right.size());
|
||||
right.forEach(item -> LOG.debug(item.toString()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < left.size(); i++) {
|
||||
if (changed(left.get(i), right.get(i))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if two property sources are different.
|
||||
* @param left left map property sources
|
||||
* @param right right map property sources
|
||||
* @return {@code true} if source has changed
|
||||
*/
|
||||
static boolean changed(MapPropertySource left, MapPropertySource right) {
|
||||
if (left == right) {
|
||||
return false;
|
||||
}
|
||||
if (left == null || right == null) {
|
||||
return true;
|
||||
}
|
||||
Map<String, Object> leftMap = left.getSource();
|
||||
Map<String, Object> rightMap = right.getSource();
|
||||
return !Objects.equals(leftMap, rightMap);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,21 +16,11 @@
|
||||
|
||||
package org.springframework.cloud.kubernetes.commons.config.reload;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.cloud.bootstrap.config.BootstrapPropertySource;
|
||||
import org.springframework.cloud.bootstrap.config.PropertySourceLocator;
|
||||
import org.springframework.core.env.CompositePropertySource;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
|
||||
/**
|
||||
@@ -41,7 +31,7 @@ import org.springframework.core.log.LogAccessor;
|
||||
*/
|
||||
public abstract class ConfigurationChangeDetector {
|
||||
|
||||
protected LogAccessor log = new LogAccessor(LogFactory.getLog(this.getClass()));
|
||||
private static final LogAccessor LOG = new LogAccessor(LogFactory.getLog(ConfigurationChangeDetector.class));
|
||||
|
||||
protected ConfigurableEnvironment environment;
|
||||
|
||||
@@ -57,114 +47,8 @@ public abstract class ConfigurationChangeDetector {
|
||||
}
|
||||
|
||||
public void reloadProperties() {
|
||||
log.info(() -> "Reloading using strategy: " + this.strategy.name());
|
||||
LOG.info(() -> "Reloading using strategy: " + this.strategy.name());
|
||||
strategy.reloadProcedure().run();
|
||||
}
|
||||
|
||||
public boolean changed(List<? extends MapPropertySource> left, List<? extends MapPropertySource> right) {
|
||||
if (left.size() != right.size()) {
|
||||
log.warn(() -> "The current number of ConfigMap PropertySources does not match "
|
||||
+ "the ones loaded from the Kubernetes - No reload will take place");
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("left size: " + left.size());
|
||||
left.forEach(item -> log.debug(item.toString()));
|
||||
|
||||
log.debug("right size: " + right.size());
|
||||
right.forEach(item -> log.debug(item.toString()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < left.size(); i++) {
|
||||
if (changed(left.get(i), right.get(i))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param <S> property source type
|
||||
* @param sourceClass class for which property sources will be found
|
||||
* @return finds all registered property sources of the given type
|
||||
*/
|
||||
public <S extends PropertySource<?>> List<S> findPropertySources(Class<S> sourceClass) {
|
||||
List<S> managedSources = new ArrayList<>();
|
||||
|
||||
List<PropertySource<?>> sources = environment.getPropertySources().stream()
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
log.debug(() -> "environment: " + environment);
|
||||
log.debug(() -> "environment sources: " + sources);
|
||||
|
||||
while (!sources.isEmpty()) {
|
||||
PropertySource<?> source = sources.remove(0);
|
||||
if (source instanceof CompositePropertySource comp) {
|
||||
sources.addAll(comp.getPropertySources());
|
||||
}
|
||||
else if (sourceClass.isInstance(source)) {
|
||||
managedSources.add(sourceClass.cast(source));
|
||||
}
|
||||
else if (source instanceof BootstrapPropertySource) {
|
||||
PropertySource<?> propertySource = ((BootstrapPropertySource<?>) source).getDelegate();
|
||||
if (sourceClass.isInstance(propertySource)) {
|
||||
sources.add(propertySource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return managedSources;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of MapPropertySource that correspond to the current state of the
|
||||
* system. This only handles the PropertySource objects that are returned.
|
||||
* @param propertySourceLocator Spring's property source locator
|
||||
* @param environment Spring environment
|
||||
* @return a list of MapPropertySource that correspond to the current state of the
|
||||
* system
|
||||
*/
|
||||
protected List<MapPropertySource> locateMapPropertySources(PropertySourceLocator propertySourceLocator,
|
||||
Environment environment) {
|
||||
|
||||
List<MapPropertySource> result = new ArrayList<>();
|
||||
PropertySource<?> propertySource = propertySourceLocator.locate(environment);
|
||||
if (propertySource instanceof MapPropertySource) {
|
||||
result.add((MapPropertySource) propertySource);
|
||||
}
|
||||
else if (propertySource instanceof CompositePropertySource source) {
|
||||
|
||||
List<MapPropertySource> list = source.getPropertySources().stream()
|
||||
.filter(p -> p instanceof MapPropertySource).map(x -> (MapPropertySource) x)
|
||||
.collect(Collectors.toList());
|
||||
result.addAll(list);
|
||||
}
|
||||
else {
|
||||
log.debug(() -> "Found property source that cannot be handled: " + propertySource.getClass());
|
||||
}
|
||||
|
||||
log.debug(() -> "environment: " + environment);
|
||||
log.debug(() -> "sources: " + result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if two property sources are different.
|
||||
* @param left left map property sources
|
||||
* @param right right map property sources
|
||||
* @return {@code true} if source has changed
|
||||
*/
|
||||
boolean changed(MapPropertySource left, MapPropertySource right) {
|
||||
if (left == right) {
|
||||
return false;
|
||||
}
|
||||
if (left == null || right == null) {
|
||||
return true;
|
||||
}
|
||||
Map<String, Object> leftMap = left.getSource();
|
||||
Map<String, Object> rightMap = right.getSource();
|
||||
return !Objects.equals(leftMap, rightMap);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
* Copyright 2013-2022 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.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.cloud.kubernetes.commons.config.reload;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
@@ -28,6 +29,10 @@ import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.scheduling.TaskScheduler;
|
||||
import org.springframework.scheduling.support.PeriodicTrigger;
|
||||
|
||||
import static org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadUtil.changed;
|
||||
import static org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadUtil.findPropertySources;
|
||||
import static org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadUtil.locateMapPropertySources;
|
||||
|
||||
/**
|
||||
* A change detector that periodically retrieves configmaps and fire a reload when
|
||||
* something changes.
|
||||
@@ -64,8 +69,8 @@ public class PollingConfigMapChangeDetector extends ConfigurationChangeDetector
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
log.info("Kubernetes polling configMap change detector activated");
|
||||
PeriodicTrigger trigger = new PeriodicTrigger(period);
|
||||
trigger.setInitialDelay(period);
|
||||
PeriodicTrigger trigger = new PeriodicTrigger(Duration.ofMillis(period));
|
||||
trigger.setInitialDelay(Duration.ofMillis(period));
|
||||
taskExecutor.schedule(this::executeCycle, trigger);
|
||||
}
|
||||
|
||||
@@ -74,7 +79,8 @@ public class PollingConfigMapChangeDetector extends ConfigurationChangeDetector
|
||||
boolean changedConfigMap = false;
|
||||
if (monitorConfigMaps) {
|
||||
log.debug("Polling for changes in config maps");
|
||||
List<? extends MapPropertySource> currentConfigMapSources = findPropertySources(propertySourceClass);
|
||||
List<? extends MapPropertySource> currentConfigMapSources = findPropertySources(propertySourceClass,
|
||||
environment);
|
||||
|
||||
if (!currentConfigMapSources.isEmpty()) {
|
||||
changedConfigMap = changed(locateMapPropertySources(this.propertySourceLocator, this.environment),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
* Copyright 2013-2022 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.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.cloud.kubernetes.commons.config.reload;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
@@ -28,6 +29,10 @@ import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.scheduling.TaskScheduler;
|
||||
import org.springframework.scheduling.support.PeriodicTrigger;
|
||||
|
||||
import static org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadUtil.changed;
|
||||
import static org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadUtil.findPropertySources;
|
||||
import static org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadUtil.locateMapPropertySources;
|
||||
|
||||
/**
|
||||
* A change detector that periodically retrieves secrets and fires a reload when something
|
||||
* changes.
|
||||
@@ -64,8 +69,8 @@ public class PollingSecretsChangeDetector extends ConfigurationChangeDetector {
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
log.info("Kubernetes polling secrets change detector activated");
|
||||
PeriodicTrigger trigger = new PeriodicTrigger(period);
|
||||
trigger.setInitialDelay(period);
|
||||
PeriodicTrigger trigger = new PeriodicTrigger(Duration.ofMillis(period));
|
||||
trigger.setInitialDelay(Duration.ofMillis(period));
|
||||
taskExecutor.schedule(this::executeCycle, trigger);
|
||||
}
|
||||
|
||||
@@ -76,8 +81,9 @@ public class PollingSecretsChangeDetector extends ConfigurationChangeDetector {
|
||||
log.debug("Polling for changes in secrets");
|
||||
List<MapPropertySource> currentSecretSources = locateMapPropertySources(this.propertySourceLocator,
|
||||
this.environment);
|
||||
if (currentSecretSources != null && !currentSecretSources.isEmpty()) {
|
||||
List<? extends MapPropertySource> propertySources = findPropertySources(this.propertySourceClass);
|
||||
if (!currentSecretSources.isEmpty()) {
|
||||
List<? extends MapPropertySource> propertySources = findPropertySources(propertySourceClass,
|
||||
environment);
|
||||
changedSecrets = changed(currentSecretSources, propertySources);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,31 +38,25 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
class ConfigurationChangeDetectorTests {
|
||||
|
||||
private final ConfigurationChangeDetector changeDetector = new ConfigurationChangeDetector(new MockEnvironment(),
|
||||
new ConfigReloadProperties(), new ConfigurationUpdateStrategy("some", () -> {
|
||||
|
||||
})) {
|
||||
};
|
||||
class ConfigReloadUtilTests {
|
||||
|
||||
@Test
|
||||
void testChangedTwoNulls() {
|
||||
boolean changed = changeDetector.changed(null, (MapPropertySource) null);
|
||||
boolean changed = ConfigReloadUtil.changed(null, (MapPropertySource) null);
|
||||
assertThat(changed).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testChangedLeftNullRightNonNull() {
|
||||
MapPropertySource right = new MapPropertySource("rightNonNull", Collections.emptyMap());
|
||||
boolean changed = changeDetector.changed(null, right);
|
||||
boolean changed = ConfigReloadUtil.changed(null, right);
|
||||
assertThat(changed).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testChangedLeftNonNullRightNull() {
|
||||
MapPropertySource left = new MapPropertySource("leftNonNull", Collections.emptyMap());
|
||||
boolean changed = changeDetector.changed(left, null);
|
||||
boolean changed = ConfigReloadUtil.changed(left, null);
|
||||
assertThat(changed).isTrue();
|
||||
}
|
||||
|
||||
@@ -75,7 +69,7 @@ class ConfigurationChangeDetectorTests {
|
||||
rightMap.put("key", value);
|
||||
MapPropertySource left = new MapPropertySource("left", leftMap);
|
||||
MapPropertySource right = new MapPropertySource("right", rightMap);
|
||||
boolean changed = changeDetector.changed(left, right);
|
||||
boolean changed = ConfigReloadUtil.changed(left, right);
|
||||
assertThat(changed).isFalse();
|
||||
}
|
||||
|
||||
@@ -89,7 +83,7 @@ class ConfigurationChangeDetectorTests {
|
||||
rightMap.put("key", value);
|
||||
MapPropertySource left = new MapPropertySource("left", leftMap);
|
||||
MapPropertySource right = new MapPropertySource("right", rightMap);
|
||||
boolean changed = changeDetector.changed(left, right);
|
||||
boolean changed = ConfigReloadUtil.changed(left, right);
|
||||
assertThat(changed).isTrue();
|
||||
}
|
||||
|
||||
@@ -97,7 +91,7 @@ class ConfigurationChangeDetectorTests {
|
||||
void testChangedListsDifferentSizes() {
|
||||
List<MapPropertySource> left = Collections.singletonList(new MapPropertySource("one", Collections.emptyMap()));
|
||||
List<MapPropertySource> right = Collections.emptyList();
|
||||
boolean changed = changeDetector.changed(left, right);
|
||||
boolean changed = ConfigReloadUtil.changed(left, right);
|
||||
assertThat(changed).isFalse();
|
||||
}
|
||||
|
||||
@@ -110,7 +104,7 @@ class ConfigurationChangeDetectorTests {
|
||||
leftMap.put("anotherKey", value);
|
||||
List<MapPropertySource> left = Collections.singletonList(new MapPropertySource("one", leftMap));
|
||||
List<MapPropertySource> right = Collections.singletonList(new MapPropertySource("two", rightMap));
|
||||
boolean changed = changeDetector.changed(left, right);
|
||||
boolean changed = ConfigReloadUtil.changed(left, right);
|
||||
assertThat(changed).isTrue();
|
||||
}
|
||||
|
||||
@@ -123,19 +117,13 @@ class ConfigurationChangeDetectorTests {
|
||||
leftMap.put("key", value);
|
||||
List<MapPropertySource> left = Collections.singletonList(new MapPropertySource("one", leftMap));
|
||||
List<MapPropertySource> right = Collections.singletonList(new MapPropertySource("two", rightMap));
|
||||
boolean changed = changeDetector.changed(left, right);
|
||||
boolean changed = ConfigReloadUtil.changed(left, right);
|
||||
assertThat(changed).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindPropertySources() {
|
||||
MockEnvironment environment = new MockEnvironment();
|
||||
ConfigurationChangeDetector detector = new ConfigurationChangeDetector(environment,
|
||||
new ConfigReloadProperties(), new ConfigurationUpdateStrategy("some", () -> {
|
||||
|
||||
})) {
|
||||
};
|
||||
|
||||
MutablePropertySources propertySources = environment.getPropertySources();
|
||||
propertySources.addFirst(new OneComposite());
|
||||
propertySources.addFirst(new PlainPropertySource("plain"));
|
||||
@@ -151,7 +139,7 @@ class ConfigurationChangeDetectorTests {
|
||||
}
|
||||
}));
|
||||
|
||||
List<PlainPropertySource> result = detector.findPropertySources(PlainPropertySource.class);
|
||||
List<PlainPropertySource> result = ConfigReloadUtil.findPropertySources(PlainPropertySource.class, environment);
|
||||
Assertions.assertEquals(3, result.size());
|
||||
Assertions.assertEquals("plain", result.get(0).getProperty(""));
|
||||
Assertions.assertEquals("from-bootstrap", result.get(1).getProperty(""));
|
||||
@@ -79,7 +79,7 @@ public abstract class ConfigMapWatcherChangeDetector extends KubernetesClientEve
|
||||
else {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Not publishing event. ConfigMap " + configMap.getMetadata().getName()
|
||||
+ " does not contain the label " + k8SConfigurationProperties.getConfigLabel());
|
||||
+ " does not contain the label " + ConfigurationWatcherConfigurationProperties.CONFIG_LABEL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -88,8 +88,8 @@ public abstract class ConfigMapWatcherChangeDetector extends KubernetesClientEve
|
||||
if (configMap.getMetadata() == null || configMap.getMetadata().getLabels() == null) {
|
||||
return false;
|
||||
}
|
||||
return Boolean.parseBoolean(
|
||||
configMap.getMetadata().getLabels().getOrDefault(k8SConfigurationProperties.getConfigLabel(), "false"));
|
||||
return Boolean.parseBoolean(configMap.getMetadata().getLabels()
|
||||
.getOrDefault(ConfigurationWatcherConfigurationProperties.CONFIG_LABEL, "false"));
|
||||
}
|
||||
|
||||
protected abstract Mono<Void> triggerRefresh(V1ConfigMap configMap);
|
||||
|
||||
@@ -28,6 +28,16 @@ import org.springframework.boot.convert.DurationUnit;
|
||||
@ConfigurationProperties("spring.cloud.kubernetes.configuration.watcher")
|
||||
public class ConfigurationWatcherConfigurationProperties {
|
||||
|
||||
/**
|
||||
* label to enable refresh/restart when using configmaps.
|
||||
*/
|
||||
public static final String CONFIG_LABEL = "spring.cloud.kubernetes.config";
|
||||
|
||||
/**
|
||||
* label to enable refresh/restart when using secrets.
|
||||
*/
|
||||
public static final String SECRET_LABEL = "spring.cloud.kubernetes.secret";
|
||||
|
||||
/**
|
||||
* Amount of time to delay the posting of the event to allow the app volume to update
|
||||
* data.
|
||||
@@ -37,10 +47,6 @@ public class ConfigurationWatcherConfigurationProperties {
|
||||
|
||||
private int threadPoolSize = 1;
|
||||
|
||||
private String configLabel = "spring.cloud.kubernetes.config";
|
||||
|
||||
private String secretLabel = "spring.cloud.kubernetes.secret";
|
||||
|
||||
private String actuatorPath = "/actuator";
|
||||
|
||||
private Integer actuatorPort = -1;
|
||||
@@ -68,22 +74,6 @@ public class ConfigurationWatcherConfigurationProperties {
|
||||
this.actuatorPort = actuatorPort;
|
||||
}
|
||||
|
||||
public String getSecretLabel() {
|
||||
return secretLabel;
|
||||
}
|
||||
|
||||
public void setSecretLabel(String secretLabel) {
|
||||
this.secretLabel = secretLabel;
|
||||
}
|
||||
|
||||
public String getConfigLabel() {
|
||||
return configLabel;
|
||||
}
|
||||
|
||||
public void setConfigLabel(String configLabel) {
|
||||
this.configLabel = configLabel;
|
||||
}
|
||||
|
||||
public Duration getRefreshDelay() {
|
||||
return refreshDelay;
|
||||
}
|
||||
|
||||
@@ -62,8 +62,8 @@ public abstract class SecretsWatcherChangeDetector extends KubernetesClientEvent
|
||||
if (secret.getMetadata() == null || secret.getMetadata().getLabels() == null) {
|
||||
return false;
|
||||
}
|
||||
return Boolean.parseBoolean(
|
||||
secret.getMetadata().getLabels().getOrDefault(k8SConfigurationProperties.getSecretLabel(), "false"));
|
||||
return Boolean.parseBoolean(secret.getMetadata().getLabels()
|
||||
.getOrDefault(ConfigurationWatcherConfigurationProperties.SECRET_LABEL, "false"));
|
||||
}
|
||||
|
||||
protected abstract Mono<Void> triggerRefresh(V1Secret secret);
|
||||
@@ -88,7 +88,7 @@ public abstract class SecretsWatcherChangeDetector extends KubernetesClientEvent
|
||||
else {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Not publishing event. Secret " + secret.getMetadata().getName()
|
||||
+ " does not contain the label " + k8SConfigurationProperties.getSecretLabel());
|
||||
+ " does not contain the label " + ConfigurationWatcherConfigurationProperties.SECRET_LABEL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,14 +28,17 @@ import io.fabric8.kubernetes.client.informers.SharedIndexInformer;
|
||||
import io.fabric8.kubernetes.client.informers.SharedInformer;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.PreDestroy;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
|
||||
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadProperties;
|
||||
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadUtil;
|
||||
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationChangeDetector;
|
||||
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationUpdateStrategy;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySource;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySourceLocator;
|
||||
import org.springframework.core.env.AbstractEnvironment;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
|
||||
import static org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigUtils.namespaces;
|
||||
|
||||
@@ -49,6 +52,9 @@ import static org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigU
|
||||
*/
|
||||
public class Fabric8EventBasedConfigMapChangeDetector extends ConfigurationChangeDetector {
|
||||
|
||||
private static final LogAccessor LOG = new LogAccessor(
|
||||
LogFactory.getLog(Fabric8EventBasedConfigMapChangeDetector.class));
|
||||
|
||||
private final Fabric8ConfigMapPropertySourceLocator fabric8ConfigMapPropertySourceLocator;
|
||||
|
||||
private final KubernetesClient kubernetesClient;
|
||||
@@ -76,18 +82,18 @@ public class Fabric8EventBasedConfigMapChangeDetector extends ConfigurationChang
|
||||
@PostConstruct
|
||||
private void inform() {
|
||||
if (monitoringConfigMaps) {
|
||||
log.info("Kubernetes event-based configMap change detector activated");
|
||||
LOG.info("Kubernetes event-based configMap change detector activated");
|
||||
|
||||
namespaces.forEach(namespace -> {
|
||||
SharedIndexInformer<ConfigMap> informer;
|
||||
if (enableReloadFiltering) {
|
||||
informer = kubernetesClient.configMaps().inNamespace(namespace)
|
||||
.withLabels(Map.of(ConfigReloadProperties.RELOAD_LABEL_FILTER, "true")).inform();
|
||||
log.debug("added configmap informer for namespace : " + namespace + " with enabled filter");
|
||||
LOG.debug("added configmap informer for namespace : " + namespace + " with enabled filter");
|
||||
}
|
||||
else {
|
||||
informer = kubernetesClient.configMaps().inNamespace(namespace).inform();
|
||||
log.debug("added configmap informer for namespace : " + namespace);
|
||||
LOG.debug("added configmap informer for namespace : " + namespace);
|
||||
}
|
||||
|
||||
informer.addEventHandler(new ConfigMapInformerAwareEventHandler(informer));
|
||||
@@ -105,11 +111,9 @@ public class Fabric8EventBasedConfigMapChangeDetector extends ConfigurationChang
|
||||
}
|
||||
|
||||
protected void onEvent(ConfigMap configMap) {
|
||||
log.debug("onEvent configMap: " + configMap.toString());
|
||||
boolean changed = changed(locateMapPropertySources(fabric8ConfigMapPropertySourceLocator, environment),
|
||||
findPropertySources(Fabric8ConfigMapPropertySource.class));
|
||||
if (changed) {
|
||||
log.info("Detected change in config maps");
|
||||
boolean reload = ConfigReloadUtil.reload("config-map", configMap.toString(),
|
||||
fabric8ConfigMapPropertySourceLocator, environment, Fabric8ConfigMapPropertySource.class);
|
||||
if (reload) {
|
||||
reloadProperties();
|
||||
}
|
||||
}
|
||||
@@ -124,27 +128,27 @@ public class Fabric8EventBasedConfigMapChangeDetector extends ConfigurationChang
|
||||
|
||||
@Override
|
||||
public void onAdd(ConfigMap configMap) {
|
||||
log.debug("ConfigMap " + configMap.getMetadata().getName() + " was added.");
|
||||
LOG.debug("ConfigMap " + configMap.getMetadata().getName() + " was added.");
|
||||
onEvent(configMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(ConfigMap oldConfigMap, ConfigMap newConfigMap) {
|
||||
log.debug("ConfigMap " + newConfigMap.getMetadata().getName() + " was updated.");
|
||||
LOG.debug("ConfigMap " + newConfigMap.getMetadata().getName() + " was updated.");
|
||||
onEvent(newConfigMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDelete(ConfigMap configMap, boolean deletedFinalStateUnknown) {
|
||||
log.debug("ConfigMap " + configMap.getMetadata().getName() + " was deleted.");
|
||||
LOG.debug("ConfigMap " + configMap.getMetadata().getName() + " was deleted.");
|
||||
onEvent(configMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothing() {
|
||||
List<ConfigMap> store = informer.getStore().list();
|
||||
log.info("onNothing called with a store of size : " + store.size());
|
||||
log.info("this might be an indication of a HTTP_GONE code");
|
||||
LOG.info("onNothing called with a store of size : " + store.size());
|
||||
LOG.info("this might be an indication of a HTTP_GONE code");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,14 +28,17 @@ import io.fabric8.kubernetes.client.informers.SharedIndexInformer;
|
||||
import io.fabric8.kubernetes.client.informers.SharedInformer;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.PreDestroy;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
|
||||
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadProperties;
|
||||
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadUtil;
|
||||
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationChangeDetector;
|
||||
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigurationUpdateStrategy;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySource;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySourceLocator;
|
||||
import org.springframework.core.env.AbstractEnvironment;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
|
||||
import static org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigUtils.namespaces;
|
||||
|
||||
@@ -49,6 +52,9 @@ import static org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigU
|
||||
*/
|
||||
public class Fabric8EventBasedSecretsChangeDetector extends ConfigurationChangeDetector {
|
||||
|
||||
private static final LogAccessor LOG = new LogAccessor(
|
||||
LogFactory.getLog(Fabric8EventBasedSecretsChangeDetector.class));
|
||||
|
||||
private final Fabric8SecretsPropertySourceLocator fabric8SecretsPropertySourceLocator;
|
||||
|
||||
private final KubernetesClient kubernetesClient;
|
||||
@@ -84,18 +90,18 @@ public class Fabric8EventBasedSecretsChangeDetector extends ConfigurationChangeD
|
||||
@PostConstruct
|
||||
private void inform() {
|
||||
if (monitorSecrets) {
|
||||
log.info("Kubernetes event-based secrets change detector activated");
|
||||
LOG.info("Kubernetes event-based secrets change detector activated");
|
||||
|
||||
namespaces.forEach(namespace -> {
|
||||
SharedIndexInformer<Secret> informer;
|
||||
if (enableReloadFiltering) {
|
||||
informer = kubernetesClient.secrets().inNamespace(namespace)
|
||||
.withLabels(Map.of(ConfigReloadProperties.RELOAD_LABEL_FILTER, "true")).inform();
|
||||
log.debug("added secret informer for namespace : " + namespace + " with enabled filter");
|
||||
LOG.debug("added secret informer for namespace : " + namespace + " with enabled filter");
|
||||
}
|
||||
else {
|
||||
informer = kubernetesClient.secrets().inNamespace(namespace).inform();
|
||||
log.debug("added secret informer for namespace : " + namespace);
|
||||
LOG.debug("added secret informer for namespace : " + namespace);
|
||||
}
|
||||
|
||||
informer.addEventHandler(new SecretInformerAwareEventHandler(informer));
|
||||
@@ -105,13 +111,13 @@ public class Fabric8EventBasedSecretsChangeDetector extends ConfigurationChangeD
|
||||
}
|
||||
|
||||
protected void onEvent(Secret secret) {
|
||||
log.debug("onEvent secrets: " + secret.toString());
|
||||
boolean changed = changed(locateMapPropertySources(fabric8SecretsPropertySourceLocator, environment),
|
||||
findPropertySources(Fabric8SecretsPropertySource.class));
|
||||
if (changed) {
|
||||
log.info("Detected change in secrets");
|
||||
|
||||
boolean reload = ConfigReloadUtil.reload("secrets", secret.toString(), fabric8SecretsPropertySourceLocator,
|
||||
environment, Fabric8SecretsPropertySource.class);
|
||||
if (reload) {
|
||||
reloadProperties();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final class SecretInformerAwareEventHandler implements ResourceEventHandler<Secret> {
|
||||
@@ -124,27 +130,27 @@ public class Fabric8EventBasedSecretsChangeDetector extends ConfigurationChangeD
|
||||
|
||||
@Override
|
||||
public void onAdd(Secret secret) {
|
||||
log.debug("Secret " + secret.getMetadata().getName() + " was added.");
|
||||
LOG.debug("Secret " + secret.getMetadata().getName() + " was added.");
|
||||
onEvent(secret);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(Secret oldSecret, Secret newSecret) {
|
||||
log.debug("Secret " + newSecret.getMetadata().getName() + " was updated.");
|
||||
LOG.debug("Secret " + newSecret.getMetadata().getName() + " was updated.");
|
||||
onEvent(newSecret);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDelete(Secret secret, boolean deletedFinalStateUnknown) {
|
||||
log.debug("Secret " + secret.getMetadata().getName() + " was deleted.");
|
||||
LOG.debug("Secret " + secret.getMetadata().getName() + " was deleted.");
|
||||
onEvent(secret);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothing() {
|
||||
List<Secret> store = informer.getStore().list();
|
||||
log.info("onNothing called with a store of size : " + store.size());
|
||||
log.info("this might be an indication of a HTTP_GONE code");
|
||||
LOG.info("onNothing called with a store of size : " + store.size());
|
||||
LOG.info("this might be an indication of a HTTP_GONE code");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,12 +31,9 @@ import io.fabric8.kubernetes.client.dsl.Resource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.cloud.bootstrap.config.BootstrapPropertySource;
|
||||
import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
|
||||
import org.springframework.cloud.kubernetes.commons.config.NamedConfigMapNormalizedSource;
|
||||
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.Fabric8EventBasedConfigMapChangeDetector;
|
||||
import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadUtil;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -51,7 +48,6 @@ class EventBasedConfigurationChangeDetectorTests {
|
||||
@SuppressWarnings({ "unchecked", "raw" })
|
||||
@Test
|
||||
void verifyConfigChangesAccountsForBootstrapPropertySources() {
|
||||
ConfigReloadProperties configReloadProperties = new ConfigReloadProperties();
|
||||
MockEnvironment env = new MockEnvironment();
|
||||
KubernetesClient k8sClient = mock(KubernetesClient.class);
|
||||
ConfigMap configMap = new ConfigMap();
|
||||
@@ -75,15 +71,8 @@ class EventBasedConfigurationChangeDetectorTests {
|
||||
Fabric8ConfigMapPropertySource fabric8ConfigMapPropertySource = new Fabric8ConfigMapPropertySource(context);
|
||||
env.getPropertySources().addFirst(new BootstrapPropertySource<>(fabric8ConfigMapPropertySource));
|
||||
|
||||
ConfigurationUpdateStrategy configurationUpdateStrategy = new ConfigurationUpdateStrategy("strategy", () -> {
|
||||
|
||||
});
|
||||
Fabric8ConfigMapPropertySourceLocator configMapLocator = mock(Fabric8ConfigMapPropertySourceLocator.class);
|
||||
Fabric8EventBasedConfigMapChangeDetector detector = new Fabric8EventBasedConfigMapChangeDetector(env,
|
||||
configReloadProperties, k8sClient, configurationUpdateStrategy, configMapLocator,
|
||||
new KubernetesNamespaceProvider(new MockEnvironment()));
|
||||
List<Fabric8ConfigMapPropertySource> sources = detector
|
||||
.findPropertySources(Fabric8ConfigMapPropertySource.class);
|
||||
List<Fabric8ConfigMapPropertySource> sources = ConfigReloadUtil
|
||||
.findPropertySources(Fabric8ConfigMapPropertySource.class, env);
|
||||
assertThat(sources.size()).isEqualTo(1);
|
||||
assertThat(sources.get(0).getProperty("foo")).isEqualTo("bar");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user