diff --git a/docs/modules/ROOT/pages/property-source-config/propertysource-reload.adoc b/docs/modules/ROOT/pages/property-source-config/propertysource-reload.adoc index d656135def..6053e6a4fa 100644 --- a/docs/modules/ROOT/pages/property-source-config/propertysource-reload.adoc +++ b/docs/modules/ROOT/pages/property-source-config/propertysource-reload.adoc @@ -2,8 +2,8 @@ = `PropertySource` Reload WARNING: This functionality has been deprecated in the 2020.0 release. Please see -the xref:spring-cloud-kubernetes-configuration-watcher.adoc#spring-cloud-kubernetes-configuration-watcher[null] controller for an alternative way -to achieve the same functionality. +the xref:spring-cloud-kubernetes-configuration-watcher.adoc#spring-cloud-kubernetes-configuration-watcher[Spring Cloud Kubernetes Configuration Watcher] +controller for an alternative way to achieve the same functionality. Some applications may need to detect changes on external property sources and update their internal status to reflect the new configuration. The reload feature of Spring Cloud Kubernetes is able to trigger an application reload when a related `ConfigMap` or diff --git a/docs/package.json b/docs/package.json index 37c3765900..872725687a 100644 --- a/docs/package.json +++ b/docs/package.json @@ -2,7 +2,7 @@ "dependencies": { "antora": "3.2.0-alpha.4", "@antora/atlas-extension": "1.0.0-alpha.2", - "@antora/collector-extension": "1.0.0-beta.3", + "@antora/collector-extension": "1.0.0-beta.4", "@asciidoctor/tabs": "1.0.0-beta.6", "@springio/antora-extensions": "1.11.1", "@springio/asciidoctor-extensions": "1.0.0-alpha.14" diff --git a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigUtils.java b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigUtils.java index 21bc92b9ee..f4be4ef88e 100644 --- a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigUtils.java +++ b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigUtils.java @@ -147,7 +147,7 @@ private static List strippedConfigMaps(CoreV1Api coreV1 private static List strippedSecrets(CoreV1Api coreV1Api, String namespace) { List strippedSecrets = KubernetesClientSecretsCache.byNamespace(coreV1Api, namespace); if (strippedSecrets.isEmpty()) { - LOG.debug("No configmaps in namespace '" + namespace + "'"); + LOG.debug("No secrets in namespace '" + namespace + "'"); } return strippedSecrets; } diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/ConfigMapPropertySourceLocator.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/ConfigMapPropertySourceLocator.java index 7c2688472b..f299629309 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/ConfigMapPropertySourceLocator.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/ConfigMapPropertySourceLocator.java @@ -82,7 +82,11 @@ public PropertySource locate(Environment environment) { if (this.properties.enableApi()) { Set sources = new LinkedHashSet<>(this.properties.determineSources(environment)); LOG.debug("Config Map normalized sources : " + sources); - sources.forEach(s -> composite.addFirstPropertySource(getMapPropertySource(s, env))); + sources.forEach(s -> { + MapPropertySource propertySource = getMapPropertySource(s, env); + LOG.debug("Adding config map property source " + propertySource.getName()); + composite.addFirstPropertySource(propertySource); + }); } addPropertySourcesFromPaths(environment, composite); diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/ConfigUtils.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/ConfigUtils.java index 423c72696d..886e9e7b2f 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/ConfigUtils.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/ConfigUtils.java @@ -61,7 +61,8 @@ public final class ConfigUtils { || sourceName.endsWith("-" + activeProfile + ".yaml") || sourceName.endsWith("-" + activeProfile + ".properties"); - private static final ApplicationListener NO_OP = (e) -> { }; + private static final ApplicationListener NO_OP = (e) -> { + }; private ConfigUtils() { } @@ -209,7 +210,7 @@ public static MultipleSourcesContainer processNamedData(List { StrippedSourceContainer stripped = hashByName.get(sourceName); if (stripped != null) { - LOG.debug("Found source with name : '" + sourceName + " in namespace: '" + namespace + "'"); + LOG.debug("Found source with name : '" + sourceName + "' in namespace: '" + namespace + "'"); foundSourceNames.add(sourceName); // see if data is a single yaml/properties file and if it needs decoding Map rawData = stripped.data(); @@ -228,6 +229,9 @@ public static MultipleSourcesContainer processNamedData(List labels, ConfigUtils.Prefix p data = dataSupplier(labels, profiles); // need this check because when there is no data, the name of the property - // source - // is using provided labels, + // source is using provided labels, // unlike when the data is present: when we use secret names if (data.names().isEmpty()) { String names = labels.keySet() diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/NamedSourceData.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/NamedSourceData.java index f98464650c..c198e43316 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/NamedSourceData.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/NamedSourceData.java @@ -17,9 +17,11 @@ package org.springframework.cloud.kubernetes.commons.config; import java.util.LinkedHashSet; -import java.util.Map; import java.util.stream.Collectors; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import static org.springframework.cloud.kubernetes.commons.config.ConfigUtils.onException; import static org.springframework.cloud.kubernetes.commons.config.Constants.PROPERTY_SOURCE_NAME_SEPARATOR; @@ -31,6 +33,8 @@ */ public abstract class NamedSourceData { + private static final Log LOG = LogFactory.getLog(NamedSourceData.class); + public final SourceData compute(String sourceName, ConfigUtils.Prefix prefix, String target, boolean profileSources, boolean failFast, String namespace, String[] activeProfiles) { @@ -51,7 +55,9 @@ public final SourceData compute(String sourceName, ConfigUtils.Prefix prefix, St data = dataSupplier(sourceNames); if (data.names().isEmpty()) { - return new SourceData(ConfigUtils.sourceName(target, sourceName, namespace), Map.of()); + String emptySourceName = ConfigUtils.sourceName(target, sourceName, namespace); + LOG.debug("Will return empty source with name : " + emptySourceName); + return SourceData.emptyRecord(emptySourceName); } if (prefix != ConfigUtils.Prefix.DEFAULT) { diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/SecretsPropertySourceLocator.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/SecretsPropertySourceLocator.java index ca954a6ef0..f35e40e0e6 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/SecretsPropertySourceLocator.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/SecretsPropertySourceLocator.java @@ -42,6 +42,7 @@ 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; /** @@ -87,8 +88,11 @@ public PropertySource locate(Environment environment) { putPathConfig(composite); if (this.properties.enableApi()) { - uniqueSources - .forEach(s -> composite.addPropertySource(getSecretsPropertySourceForSingleSecret(env, s))); + uniqueSources.forEach(s -> { + MapPropertySource propertySource = getSecretsPropertySourceForSingleSecret(env, s); + LOG.debug("Adding secret property source " + propertySource.getName()); + composite.addFirstPropertySource(propertySource); + }); } cache.discardAll(); diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/SourceData.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/SourceData.java index 29b4280e22..b9eb46c0b2 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/SourceData.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/SourceData.java @@ -16,7 +16,6 @@ package org.springframework.cloud.kubernetes.commons.config; -import java.util.Collections; import java.util.Map; /** @@ -25,10 +24,10 @@ * * @author wind57 */ -public final record SourceData(String sourceName, Map sourceData) { +public record SourceData(String sourceName, Map sourceData) { public static SourceData emptyRecord(String sourceName) { - return new SourceData(sourceName, Collections.emptyMap()); + return new SourceData(sourceName, Map.of()); } } diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/SourceDataEntriesProcessor.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/SourceDataEntriesProcessor.java index 7e313b70d1..5f51e9700d 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/SourceDataEntriesProcessor.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/SourceDataEntriesProcessor.java @@ -48,7 +48,7 @@ public class SourceDataEntriesProcessor extends MapPropertySource { private static final Log LOG = LogFactory.getLog(SourceDataEntriesProcessor.class); - private static Predicate ENDS_IN_EXTENSION = x -> x.endsWith(".yml") || x.endsWith(".yaml") + private static final Predicate ENDS_IN_EXTENSION = x -> x.endsWith(".yml") || x.endsWith(".yaml") || x.endsWith(".properties"); public SourceDataEntriesProcessor(SourceData sourceData) { diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadUtil.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadUtil.java index 9044815080..4279694418 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadUtil.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadUtil.java @@ -44,13 +44,31 @@ private ConfigReloadUtil() { private static final LogAccessor LOG = new LogAccessor(LogFactory.getLog(ConfigReloadUtil.class)); - public static boolean reload(String target, String eventSourceType, PropertySourceLocator locator, + /** + * used for the event based reloading. + */ + public static boolean reload(String target, String sourceAsString, PropertySourceLocator locator, ConfigurableEnvironment environment, Class existingSourcesType) { - LOG.debug(() -> "onEvent " + target + ": " + eventSourceType); + LOG.debug(() -> "onEvent " + target + ": " + sourceAsString); + + return reload(locator, environment, existingSourcesType); + } + + /** + * used for the poll based reloading. + */ + public static boolean reload(PropertySourceLocator locator, ConfigurableEnvironment environment, + Class existingSourcesType) { - List sourceFromK8s = locateMapPropertySources(locator, environment); List existingSources = findPropertySources(existingSourcesType, environment); + if (existingSources.isEmpty()) { + LOG.debug(() -> "no existingSources found, reload will not happen"); + return false; + } + + List sourceFromK8s = locateMapPropertySources(locator, environment); + boolean changed = changed(sourceFromK8s, existingSources); if (changed) { LOG.info("Detected change in config maps/secrets"); @@ -67,7 +85,9 @@ public static boolean reload(String target, String eventSourceType, PropertySour * @param property source type * @param sourceClass class for which property sources will be found * @return finds all registered property sources of the given type + * @deprecated this method will not be public in the next major release. */ + @Deprecated(forRemoval = false) public static > List findPropertySources(Class sourceClass, ConfigurableEnvironment environment) { List managedSources = new ArrayList<>(); @@ -141,25 +161,25 @@ else if (propertySource instanceof CompositePropertySource source) { return result; } - static boolean changed(List left, List right) { - if (left.size() != right.size()) { + static boolean changed(List k8sSources, List appSources) { + if (k8sSources.size() != appSources.size()) { if (LOG.isDebugEnabled()) { - LOG.debug("left size: " + left.size()); - left.forEach(item -> LOG.debug(item.toString())); + LOG.debug("k8s property sources size: " + k8sSources.size()); + k8sSources.forEach(item -> LOG.debug(item.toString())); - LOG.debug("right size: " + right.size()); - right.forEach(item -> LOG.debug(item.toString())); + LOG.debug("app property sources size size: " + appSources.size()); + appSources.forEach(item -> LOG.debug(item.toString())); } - LOG.warn(() -> "The current number of ConfigMap PropertySources does not match " + LOG.warn(() -> "The current number of PropertySources does not match " + "the ones loaded from Kubernetes - No reload will take place"); return false; } - for (int i = 0; i < left.size(); i++) { - MapPropertySource leftPropertySource = left.get(i); - MapPropertySource rightPropertySource = right.get(i); - if (changed(leftPropertySource, rightPropertySource)) { - LOG.debug(() -> "found change in : " + leftPropertySource); + for (int i = 0; i < k8sSources.size(); i++) { + MapPropertySource k8sSource = k8sSources.get(i); + MapPropertySource appSource = appSources.get(i); + if (changed(k8sSource, appSource)) { + LOG.debug(() -> "found change in : " + k8sSource); return true; } } @@ -169,20 +189,20 @@ static boolean changed(List left, List leftMap = left.getSource(); - Map rightMap = right.getSource(); - return !Objects.equals(leftMap, rightMap); + Map k8sMap = k8sSource.getSource(); + Map appMap = appSource.getSource(); + return !Objects.equals(k8sMap, appMap); } } 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 bcd568b178..e26aa85673 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 @@ -17,7 +17,6 @@ package org.springframework.cloud.kubernetes.commons.config.reload; import java.time.Duration; -import java.util.List; import jakarta.annotation.PostConstruct; import org.apache.commons.logging.Log; @@ -29,10 +28,6 @@ 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. @@ -75,23 +70,13 @@ private void init() { } private void executeCycle() { - - boolean changedConfigMap = false; if (monitorConfigMaps) { - log.debug("Polling for changes in config maps"); - List currentConfigMapSources = findPropertySources(propertySourceClass, - environment); - - if (!currentConfigMapSources.isEmpty()) { - changedConfigMap = changed(locateMapPropertySources(this.propertySourceLocator, this.environment), - currentConfigMapSources); + boolean changedConfigMap = ConfigReloadUtil.reload(propertySourceLocator, environment, propertySourceClass); + if (changedConfigMap) { + log.info("Detected change in config maps"); + reloadProperties(); } } - - if (changedConfigMap) { - log.info("Detected change in config maps"); - reloadProperties(); - } } } 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 b70975a5c7..da0422bb68 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 @@ -17,7 +17,6 @@ package org.springframework.cloud.kubernetes.commons.config.reload; import java.time.Duration; -import java.util.List; import jakarta.annotation.PostConstruct; import org.apache.commons.logging.Log; @@ -29,10 +28,6 @@ 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. @@ -75,23 +70,13 @@ private void init() { } private void executeCycle() { - - boolean changedSecrets = false; if (monitorSecrets) { - log.debug("Polling for changes in secrets"); - List currentSecretSources = locateMapPropertySources(this.propertySourceLocator, - this.environment); - if (!currentSecretSources.isEmpty()) { - List propertySources = findPropertySources(propertySourceClass, - environment); - changedSecrets = changed(currentSecretSources, propertySources); + boolean changedSecrets = ConfigReloadUtil.reload(propertySourceLocator, environment, propertySourceClass); + if (changedSecrets) { + log.info("Detected change in secrets"); + reloadProperties(); } } - - if (changedSecrets) { - log.info("Detected change in secrets"); - reloadProperties(); - } } } diff --git a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml index ced15a4988..794bc8bd14 100644 --- a/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml +++ b/spring-cloud-kubernetes-examples/kubernetes-leader-election-example/pom.xml @@ -75,11 +75,11 @@ maven-surefire-plugin - 3.5.1 + 3.5.2 maven-failsafe-plugin - 3.5.1 + 3.5.2 diff --git a/spring-cloud-kubernetes-fabric8-autoconfig/src/main/java/org/springframework/cloud/kubernetes/fabric8/Fabric8AutoConfiguration.java b/spring-cloud-kubernetes-fabric8-autoconfig/src/main/java/org/springframework/cloud/kubernetes/fabric8/Fabric8AutoConfiguration.java index 4b66c76054..fb52604755 100644 --- a/spring-cloud-kubernetes-fabric8-autoconfig/src/main/java/org/springframework/cloud/kubernetes/fabric8/Fabric8AutoConfiguration.java +++ b/spring-cloud-kubernetes-fabric8-autoconfig/src/main/java/org/springframework/cloud/kubernetes/fabric8/Fabric8AutoConfiguration.java @@ -123,9 +123,11 @@ public Fabric8PodUtils kubernetesPodUtils(KubernetesClient client) { @EventListener void onContextClosed(ContextClosedEvent event) { - // Clean up any open connections from the KubernetesClient when the context is closed - BeanFactoryUtils.beansOfTypeIncludingAncestors(event.getApplicationContext(), KubernetesClient.class).values() - .forEach(Client::close); + // Clean up any open connections from the KubernetesClient when the context is + // closed + BeanFactoryUtils.beansOfTypeIncludingAncestors(event.getApplicationContext(), KubernetesClient.class) + .values() + .forEach(Client::close); } } diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySourceLocatorTests.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySourceLocatorTests.java index e289bbc43e..68026db2d0 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySourceLocatorTests.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySourceLocatorTests.java @@ -22,6 +22,7 @@ import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient; import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider; @@ -38,9 +39,14 @@ @EnableKubernetesMockClient class Fabric8ConfigMapPropertySourceLocatorTests { - private KubernetesMockServer mockServer; + private static KubernetesMockServer mockServer; - private KubernetesClient mockClient; + private static KubernetesClient mockClient; + + @BeforeAll + static void beforeAll() { + mockClient.getConfiguration().setRequestRetryBackoffLimit(1); + } @Test void locateShouldThrowExceptionOnFailureWhenFailFastIsEnabled() { diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySourceTests.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySourceTests.java index 482e8ba32d..8e550838ba 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySourceTests.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySourceTests.java @@ -20,6 +20,7 @@ import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient; import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.cloud.kubernetes.commons.config.ConfigUtils; @@ -42,6 +43,11 @@ class Fabric8ConfigMapPropertySourceTests { private static final ConfigUtils.Prefix DEFAULT = ConfigUtils.findPrefix("default", false, false, "irrelevant"); + @BeforeEach + void beforeEach() { + mockClient.getConfiguration().setRequestRetryBackoffLimit(1); + } + @AfterEach void afterEach() { new Fabric8ConfigMapsCache().discardAll(); @@ -51,7 +57,7 @@ void afterEach() { void constructorShouldThrowExceptionOnFailureWhenFailFastIsEnabled() { String name = "my-config"; String namespace = "default"; - String path = String.format("/api/v1/namespaces/%s/configmaps", namespace); + String path = "/api/v1/namespaces/" + namespace + "/configmaps"; mockServer.expect().withPath(path).andReturn(500, "Internal Server Error").always(); NormalizedSource source = new NamedConfigMapNormalizedSource(name, namespace, true, DEFAULT, true); @@ -64,11 +70,11 @@ void constructorShouldThrowExceptionOnFailureWhenFailFastIsEnabled() { void constructorShouldNotThrowExceptionOnFailureWhenFailFastIsDisabled() { String name = "my-config"; String namespace = "default"; - String path = String.format("/api/v1/namespaces/%s/configmaps/%s", namespace, name); + String path = "/api/v1/namespaces/" + namespace + "/configmaps"; mockServer.expect().withPath(path).andReturn(500, "Internal Server Error").always(); NormalizedSource source = new NamedConfigMapNormalizedSource(name, namespace, false, false); - Fabric8ConfigContext context = new Fabric8ConfigContext(mockClient, source, "", new MockEnvironment()); + Fabric8ConfigContext context = new Fabric8ConfigContext(mockClient, source, "default", new MockEnvironment()); assertThatNoException().isThrownBy(() -> new Fabric8ConfigMapPropertySource(context)); } diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8SecretsPropertySourceLocatorTests.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8SecretsPropertySourceLocatorTests.java index 5223490912..53c4d0a711 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8SecretsPropertySourceLocatorTests.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8SecretsPropertySourceLocatorTests.java @@ -22,6 +22,7 @@ import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient; import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider; @@ -38,9 +39,14 @@ @EnableKubernetesMockClient class Fabric8SecretsPropertySourceLocatorTests { - KubernetesMockServer mockServer; + private static KubernetesMockServer mockServer; - KubernetesClient mockClient; + private static KubernetesClient mockClient; + + @BeforeAll + static void beforeAll() { + mockClient.getConfiguration().setRequestRetryBackoffInterval(1); + } @Test void locateShouldThrowExceptionOnFailureWhenFailFastIsEnabled() { diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8SecretsPropertySourceMockTests.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8SecretsPropertySourceMockTests.java index c048667484..a0a246eded 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8SecretsPropertySourceMockTests.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8SecretsPropertySourceMockTests.java @@ -22,6 +22,7 @@ import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient; import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.springframework.cloud.kubernetes.commons.config.LabeledSecretNormalizedSource; @@ -43,6 +44,11 @@ class Fabric8SecretsPropertySourceMockTests { private static KubernetesClient client; + @BeforeAll + static void beforeAll() { + client.getConfiguration().setRequestRetryBackoffInterval(1); + } + @Test void namedStrategyShouldThrowExceptionOnFailureWhenFailFastIsEnabled() { final String name = "my-secret"; diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/main/resources/application-with-secret.yaml b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/main/resources/application-with-secret.yaml index fb84489801..2208fa1ad3 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/main/resources/application-with-secret.yaml +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-reload/src/main/resources/application-with-secret.yaml @@ -1,6 +1,9 @@ logging: level: - root: DEBUG + org: + springframework: + cloud: + kubernetes: debug spring: application: @@ -18,3 +21,6 @@ spring: secrets: enabled: true enable-api: true + + config: + enabled: false