From 8eae516c0924af93beb989ccd38ae3e5a1fad74b Mon Sep 17 00:00:00 2001 From: erabii Date: Mon, 25 Nov 2024 16:25:36 +0200 Subject: [PATCH] Fix 1592 empty source on error part 2 (#1800) --- ...entConfigMapErrorOnReadingSourceTests.java | 65 ++++++++----------- ...ntConfigMapPropertySourceLocatorTests.java | 21 +++++- ...ientSecretsPropertySourceLocatorTests.java | 19 +++++- .../reload_it/EventReloadConfigMapTest.java | 7 +- .../reload_it/EventReloadSecretTest.java | 7 +- .../reload_it/PollingReloadConfigMapTest.java | 7 +- .../reload_it/PollingReloadSecretTest.java | 7 +- .../ConfigMapPropertySourceLocator.java | 9 ++- .../commons/config/LabeledSourceData.java | 2 +- .../commons/config/NamedSourceData.java | 2 +- .../config/SecretsPropertySourceLocator.java | 10 ++- .../config/reload/ConfigReloadUtil.java | 9 +-- .../config/reload/ConfigReloadUtilTests.java | 11 ---- ...ic8ConfigMapErrorOnReadingSourceTests.java | 64 +++++++----------- ...c8ConfigMapPropertySourceLocatorTests.java | 21 +++++- ...abric8SecretErrorOnReadingSourceTests.java | 61 ++++++++--------- ...ric8SecretsPropertySourceLocatorTests.java | 22 ++++++- .../reload_it/EventReloadConfigMapTest.java | 7 +- .../reload_it/EventReloadSecretTest.java | 7 +- .../reload_it/PollingReloadConfigMapTest.java | 7 +- .../reload_it/PollingReloadSecretTest.java | 7 +- 21 files changed, 195 insertions(+), 177 deletions(-) diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapErrorOnReadingSourceTests.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapErrorOnReadingSourceTests.java index 2c79b63c80..13174e7cc3 100644 --- a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapErrorOnReadingSourceTests.java +++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapErrorOnReadingSourceTests.java @@ -39,10 +39,8 @@ import org.springframework.boot.test.system.OutputCaptureExtension; import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider; import org.springframework.cloud.kubernetes.commons.config.ConfigMapConfigProperties; -import org.springframework.cloud.kubernetes.commons.config.Constants; import org.springframework.cloud.kubernetes.commons.config.RetryProperties; import org.springframework.core.env.CompositePropertySource; -import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.PropertySource; import org.springframework.mock.env.MockEnvironment; @@ -100,12 +98,11 @@ public void afterEach() { /** *
-	 *     we try to read all config maps in a namespace and fail,
-	 *     thus generate a well defined name for the source.
+	 *     we try to read all config maps in a namespace and fail.
 	 * 
*/ @Test - void namedSingleConfigMapFails() { + void namedSingleConfigMapFails(CapturedOutput output) { String name = "my-config"; String namespace = "spring-k8s"; String path = "/api/v1/namespaces/" + namespace + "/configmaps"; @@ -120,13 +117,10 @@ void namedSingleConfigMapFails() { configMapConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment())); CompositePropertySource propertySource = (CompositePropertySource) locator.locate(new MockEnvironment()); - MapPropertySource mapPropertySource = (MapPropertySource) propertySource.getPropertySources() - .stream() - .findAny() - .orElseThrow(); - assertThat(mapPropertySource.getName()).isEqualTo("configmap..spring-k8s"); - assertThat(propertySource.getProperty(Constants.ERROR_PROPERTY)).isEqualTo("true"); + assertThat(propertySource.getPropertySources()).isEmpty(); + assertThat(output.getOut()).contains("Failure in reading named sources"); + assertThat(output.getOut()).contains("Failed to load source: { config-map name : 'Optional[my-config]'"); } @@ -168,11 +162,12 @@ void namedTwoConfigMapsOneFails(CapturedOutput output) { CompositePropertySource propertySource = (CompositePropertySource) locator.locate(new MockEnvironment()); List names = propertySource.getPropertySources().stream().map(PropertySource::getName).toList(); - // two sources are present, one being empty - assertThat(names).containsExactly("configmap.two.default", "configmap..default"); - assertThat(propertySource.getProperty(Constants.ERROR_PROPERTY)).isEqualTo("true"); + // one property source is present + assertThat(names).containsExactly("configmap.two.default"); assertThat(output.getOut()) .doesNotContain("sourceName : two was requested, but not found in namespace : default"); + assertThat(output.getOut()).contains("Failure in reading named sources"); + assertThat(output.getOut()).contains("Failed to load source: { config-map name : 'Optional[one]'"); } @@ -212,20 +207,19 @@ void namedTwoConfigMapsBothFail(CapturedOutput output) { configMapConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment())); CompositePropertySource propertySource = (CompositePropertySource) locator.locate(new MockEnvironment()); - List names = propertySource.getPropertySources().stream().map(PropertySource::getName).toList(); - assertThat(names).containsExactly("configmap..default"); - assertThat(propertySource.getProperty(Constants.ERROR_PROPERTY)).isEqualTo("true"); + assertThat(propertySource.getPropertySources()).isEmpty(); assertThat(output.getOut()) .doesNotContain("sourceName : one was requested, but not found in namespace : default"); assertThat(output.getOut()) .doesNotContain("sourceName : two was requested, but not found in namespace : default"); + assertThat(output.getOut()).contains("Failure in reading named sources"); + assertThat(output.getOut()).contains("Failed to load source: { config-map name : 'Optional[one]'"); } /** *
-	 *     we try to read all config maps in a namespace and fail,
-	 *     thus generate a well defined name for the source.
+	 *     we try to read all config maps in a namespace and fail.
 	 * 
*/ @Test @@ -256,12 +250,11 @@ void labeledSingleConfigMapFails(CapturedOutput output) { configMapConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment())); CompositePropertySource propertySource = (CompositePropertySource) locator.locate(new MockEnvironment()); - List sourceNames = propertySource.getPropertySources().stream().map(PropertySource::getName).toList(); - assertThat(sourceNames).containsExactly("configmap..spring-k8s"); - assertThat(propertySource.getProperty(Constants.ERROR_PROPERTY)).isEqualTo("true"); - assertThat(output).contains("failure in reading labeled sources"); - assertThat(output).contains("failure in reading named sources"); + assertThat(propertySource.getPropertySources()).isEmpty(); + assertThat(output.getOut()).contains("Failure in reading labeled sources"); + assertThat(output.getOut()).contains("Failure in reading named sources"); + assertThat(output.getOut()).contains("Failed to load source: { config map labels : '{a=b}'"); } /** @@ -311,12 +304,11 @@ void labeledTwoConfigMapsOneFails(CapturedOutput output) { CompositePropertySource propertySource = (CompositePropertySource) locator.locate(new MockEnvironment()); List names = propertySource.getPropertySources().stream().map(PropertySource::getName).toList(); - // two sources are present, one being empty - assertThat(names).containsExactly("configmap.two.default", "configmap..default"); - assertThat(propertySource.getProperty(Constants.ERROR_PROPERTY)).isEqualTo("true"); - - assertThat(output).contains("failure in reading labeled sources"); - assertThat(output).contains("failure in reading named sources"); + // one source is present + assertThat(names).containsExactly("configmap.two.default"); + assertThat(output.getOut()).contains("Failure in reading labeled sources"); + assertThat(output.getOut()).contains("Failure in reading named sources"); + assertThat(output.getOut()).contains("Failed to load source: { config map labels : '{one=1}'"); } @@ -364,15 +356,12 @@ void labeledTwoConfigMapsBothFail(CapturedOutput output) { configMapConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment())); CompositePropertySource propertySource = (CompositePropertySource) locator.locate(new MockEnvironment()); - List names = propertySource.getPropertySources().stream().map(PropertySource::getName).toList(); - - // all 3 sources ('application' named source, and two labeled sources) - assertThat(names).containsExactly("configmap..default"); - assertThat(propertySource.getProperty(Constants.ERROR_PROPERTY)).isEqualTo("true"); - - assertThat(output).contains("failure in reading labeled sources"); - assertThat(output).contains("failure in reading named sources"); + assertThat(propertySource.getPropertySources()).isEmpty(); + assertThat(output).contains("Failure in reading labeled sources"); + assertThat(output).contains("Failure in reading named sources"); + assertThat(output.getOut()).contains("Failed to load source: { config map labels : '{one=1}'"); + assertThat(output.getOut()).contains("Failed to load source: { config map labels : '{two=2}'"); } } diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapPropertySourceLocatorTests.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapPropertySourceLocatorTests.java index 1266b00f70..8a40326020 100644 --- a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapPropertySourceLocatorTests.java +++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapPropertySourceLocatorTests.java @@ -16,6 +16,7 @@ package org.springframework.cloud.kubernetes.client.config; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; @@ -34,12 +35,16 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.test.system.CapturedOutput; +import org.springframework.boot.test.system.OutputCaptureExtension; import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider; import org.springframework.cloud.kubernetes.commons.config.ConfigMapConfigProperties; import org.springframework.cloud.kubernetes.commons.config.Constants; import org.springframework.cloud.kubernetes.commons.config.NamespaceResolutionFailedException; import org.springframework.cloud.kubernetes.commons.config.RetryProperties; +import org.springframework.core.env.CompositePropertySource; import org.springframework.core.env.PropertySource; import org.springframework.mock.env.MockEnvironment; @@ -55,6 +60,7 @@ * @author Ryan Baxter * @author Isik Erhan */ +@ExtendWith(OutputCaptureExtension.class) class KubernetesClientConfigMapPropertySourceLocatorTests { private static final V1ConfigMapList PROPERTIES_CONFIGMAP_LIST = new V1ConfigMapList() @@ -185,7 +191,7 @@ public void locateShouldThrowExceptionOnFailureWhenFailFastIsEnabled() { } @Test - public void locateShouldNotThrowExceptionOnFailureWhenFailFastIsDisabled() { + public void locateShouldNotThrowExceptionOnFailureWhenFailFastIsDisabled(CapturedOutput output) { CoreV1Api api = new CoreV1Api(); stubFor(get("/api/v1/namespaces/default/configmaps") .willReturn(aResponse().withStatus(500).withBody("Internal Server Error"))); @@ -196,7 +202,18 @@ public void locateShouldNotThrowExceptionOnFailureWhenFailFastIsDisabled() { KubernetesClientConfigMapPropertySourceLocator locator = new KubernetesClientConfigMapPropertySourceLocator(api, configMapConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment())); - assertThatNoException().isThrownBy(() -> locator.locate(new MockEnvironment())); + List> result = new ArrayList<>(); + assertThatNoException().isThrownBy(() -> { + PropertySource source = locator.locate(new MockEnvironment()); + result.add(source); + }); + + assertThat(result.get(0)).isInstanceOf(CompositePropertySource.class); + CompositePropertySource composite = (CompositePropertySource) result.get(0); + assertThat(composite.getPropertySources()).hasSize(0); + assertThat(output.getOut()).contains("Failed to load source:"); + + } } diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientSecretsPropertySourceLocatorTests.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientSecretsPropertySourceLocatorTests.java index 5bcf6ca005..030c62b968 100644 --- a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientSecretsPropertySourceLocatorTests.java +++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientSecretsPropertySourceLocatorTests.java @@ -16,6 +16,7 @@ package org.springframework.cloud.kubernetes.client.config; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; @@ -30,11 +31,15 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.test.system.CapturedOutput; +import org.springframework.boot.test.system.OutputCaptureExtension; import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider; import org.springframework.cloud.kubernetes.commons.config.NamespaceResolutionFailedException; import org.springframework.cloud.kubernetes.commons.config.RetryProperties; import org.springframework.cloud.kubernetes.commons.config.SecretsConfigProperties; +import org.springframework.core.env.CompositePropertySource; import org.springframework.core.env.PropertySource; import org.springframework.mock.env.MockEnvironment; @@ -50,6 +55,7 @@ * @author Ryan Baxter * @author Isik Erhan */ +@ExtendWith(OutputCaptureExtension.class) class KubernetesClientSecretsPropertySourceLocatorTests { private static final String LIST_API = "/api/v1/namespaces/default/secrets"; @@ -200,7 +206,7 @@ void locateShouldThrowExceptionOnFailureWhenFailFastIsEnabled() { } @Test - void locateShouldNotThrowExceptionOnFailureWhenFailFastIsDisabled() { + void locateShouldNotThrowExceptionOnFailureWhenFailFastIsDisabled(CapturedOutput output) { CoreV1Api api = new CoreV1Api(); stubFor(get(LIST_API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error"))); @@ -210,7 +216,16 @@ void locateShouldNotThrowExceptionOnFailureWhenFailFastIsDisabled() { KubernetesClientSecretsPropertySourceLocator locator = new KubernetesClientSecretsPropertySourceLocator(api, new KubernetesNamespaceProvider(new MockEnvironment()), secretsConfigProperties); - assertThatNoException().isThrownBy(() -> locator.locate(new MockEnvironment())); + List> result = new ArrayList<>(); + assertThatNoException().isThrownBy(() -> { + PropertySource source = locator.locate(new MockEnvironment()); + result.add(source); + }); + + assertThat(result.get(0)).isInstanceOf(CompositePropertySource.class); + CompositePropertySource composite = (CompositePropertySource) result.get(0); + assertThat(composite.getPropertySources()).hasSize(0); + assertThat(output.getOut()).contains("Failed to load source:"); } } diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/EventReloadConfigMapTest.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/EventReloadConfigMapTest.java index a0d458f710..cfdbfb9f2d 100644 --- a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/EventReloadConfigMapTest.java +++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/EventReloadConfigMapTest.java @@ -154,11 +154,10 @@ void test(CapturedOutput output) { // we fail while reading 'configMapOne' Awaitility.await().atMost(Duration.ofSeconds(10)).pollInterval(Duration.ofSeconds(1)).until(() -> { - boolean one = output.getOut().contains("failure in reading named sources"); - boolean two = output.getOut() - .contains("there was an error while reading config maps/secrets, no reload will happen"); + boolean one = output.getOut().contains("Failure in reading named sources"); + boolean two = output.getOut().contains("Failed to load source"); boolean three = output.getOut() - .contains("reloadable condition was not satisfied, reload will not be triggered"); + .contains("Reloadable condition was not satisfied, reload will not be triggered"); boolean updateStrategyNotCalled = !strategyCalled[0]; return one && two && three && updateStrategyNotCalled; }); diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/EventReloadSecretTest.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/EventReloadSecretTest.java index cc4af32b82..86e3b09ed0 100644 --- a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/EventReloadSecretTest.java +++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/EventReloadSecretTest.java @@ -156,11 +156,10 @@ void test(CapturedOutput output) { // we fail while reading 'configMapOne' Awaitility.await().atMost(Duration.ofSeconds(10)).pollInterval(Duration.ofSeconds(1)).until(() -> { - boolean one = output.getOut().contains("failure in reading named sources"); - boolean two = output.getOut() - .contains("there was an error while reading config maps/secrets, no reload will happen"); + boolean one = output.getOut().contains("Failure in reading named sources"); + boolean two = output.getOut().contains("Failed to load source"); boolean three = output.getOut() - .contains("reloadable condition was not satisfied, reload will not be triggered"); + .contains("Reloadable condition was not satisfied, reload will not be triggered"); boolean updateStrategyNotCalled = !strategyCalled[0]; return one && two && three && updateStrategyNotCalled; }); diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/PollingReloadConfigMapTest.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/PollingReloadConfigMapTest.java index 0e55494d6e..2fd0b3f659 100644 --- a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/PollingReloadConfigMapTest.java +++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/PollingReloadConfigMapTest.java @@ -136,11 +136,10 @@ static void after() { void test(CapturedOutput output) { // we fail while reading 'configMapOne' Awaitility.await().atMost(Duration.ofSeconds(10)).pollInterval(Duration.ofSeconds(1)).until(() -> { - boolean one = output.getOut().contains("failure in reading named sources"); - boolean two = output.getOut() - .contains("there was an error while reading config maps/secrets, no reload will happen"); + boolean one = output.getOut().contains("Failure in reading named sources"); + boolean two = output.getOut().contains("Failed to load source"); boolean three = output.getOut() - .contains("reloadable condition was not satisfied, reload will not be triggered"); + .contains("Reloadable condition was not satisfied, reload will not be triggered"); boolean updateStrategyNotCalled = !strategyCalled[0]; return one && two && three && updateStrategyNotCalled; }); diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/PollingReloadSecretTest.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/PollingReloadSecretTest.java index 4173ac8da2..a9b3b9b40c 100644 --- a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/PollingReloadSecretTest.java +++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/PollingReloadSecretTest.java @@ -137,11 +137,10 @@ static void after() { void test(CapturedOutput output) { // we fail while reading 'secretOne' Awaitility.await().atMost(Duration.ofSeconds(10)).pollInterval(Duration.ofSeconds(1)).until(() -> { - boolean one = output.getOut().contains("failure in reading named sources"); - boolean two = output.getOut() - .contains("there was an error while reading config maps/secrets, no reload will happen"); + boolean one = output.getOut().contains("Failure in reading named sources"); + boolean two = output.getOut().contains("Failed to load source"); boolean three = output.getOut() - .contains("reloadable condition was not satisfied, reload will not be triggered"); + .contains("Reloadable condition was not satisfied, reload will not be triggered"); boolean updateStrategyNotCalled = !strategyCalled[0]; return one && two && three && updateStrategyNotCalled; }); 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 f299629309..4fe25ff676 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 @@ -84,8 +84,13 @@ public PropertySource locate(Environment environment) { LOG.debug("Config Map normalized sources : " + sources); sources.forEach(s -> { MapPropertySource propertySource = getMapPropertySource(s, env); - LOG.debug("Adding config map property source " + propertySource.getName()); - composite.addFirstPropertySource(propertySource); + if ("true".equals(propertySource.getProperty(Constants.ERROR_PROPERTY))) { + LOG.warn("Failed to load source: " + s); + } + else { + LOG.debug("Adding config map property source " + propertySource.getName()); + composite.addFirstPropertySource(propertySource); + } }); } diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/LabeledSourceData.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/LabeledSourceData.java index 61178346d9..428949d427 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/LabeledSourceData.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/LabeledSourceData.java @@ -79,7 +79,7 @@ public final SourceData compute(Map labels, ConfigUtils.Prefix p } } catch (Exception e) { - LOG.warn("failure in reading labeled sources"); + LOG.warn("Failure in reading labeled sources"); onException(failFast, e); data = new MultipleSourcesContainer(data.names(), Map.of(ERROR_PROPERTY, "true")); } 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 acd39b64ba..34da831a86 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 @@ -71,7 +71,7 @@ public final SourceData compute(String sourceName, ConfigUtils.Prefix prefix, St } catch (Exception e) { - LOG.warn("failure in reading named sources"); + LOG.warn("Failure in reading named sources"); onException(failFast, e); data = new MultipleSourcesContainer(data.names(), Map.of(ERROR_PROPERTY, "true")); } 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 f35e40e0e6..07365b3fe5 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 @@ -90,8 +90,14 @@ public PropertySource locate(Environment environment) { if (this.properties.enableApi()) { uniqueSources.forEach(s -> { MapPropertySource propertySource = getSecretsPropertySourceForSingleSecret(env, s); - LOG.debug("Adding secret property source " + propertySource.getName()); - composite.addFirstPropertySource(propertySource); + + if ("true".equals(propertySource.getProperty(Constants.ERROR_PROPERTY))) { + LOG.warn("Failed to load source: " + s); + } + else { + LOG.debug("Adding secret property source " + propertySource.getName()); + composite.addFirstPropertySource(propertySource); + } }); } 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 02de15f2c1..3986f6c825 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 @@ -33,8 +33,6 @@ import org.springframework.core.env.PropertySource; import org.springframework.core.log.LogAccessor; -import static org.springframework.cloud.kubernetes.commons.config.Constants.ERROR_PROPERTY; - /** * @author wind57 */ @@ -77,7 +75,7 @@ public static boolean reload(PropertySourceLocator locator, ConfigurableEnvironm return true; } else { - LOG.debug("reloadable condition was not satisfied, reload will not be triggered"); + LOG.debug("Reloadable condition was not satisfied, reload will not be triggered"); } return false; @@ -165,11 +163,6 @@ else if (propertySource instanceof CompositePropertySource source) { static boolean changed(List k8sSources, List appSources) { - if (k8sSources.stream().anyMatch(source -> "true".equals(source.getProperty(ERROR_PROPERTY)))) { - LOG.info(() -> "there was an error while reading config maps/secrets, no reload will happen"); - return false; - } - if (k8sSources.size() != appSources.size()) { if (LOG.isDebugEnabled()) { LOG.debug("k8s property sources size: " + k8sSources.size()); diff --git a/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadUtilTests.java b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadUtilTests.java index df1f54b2b2..280d95f9d5 100644 --- a/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadUtilTests.java +++ b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/reload/ConfigReloadUtilTests.java @@ -26,7 +26,6 @@ import org.junit.jupiter.api.Test; import org.springframework.cloud.bootstrap.config.BootstrapPropertySource; -import org.springframework.cloud.kubernetes.commons.config.Constants; import org.springframework.cloud.kubernetes.commons.config.MountConfigMapPropertySource; import org.springframework.core.env.CompositePropertySource; import org.springframework.core.env.EnumerablePropertySource; @@ -151,16 +150,6 @@ public Object getProperty(String name) { Assertions.assertEquals("from-inner-two-composite", result.get(3).getProperty("")); } - @Test - void testEmptySourceNameOnError() { - Object value = new Object(); - Map rightMap = Map.of("key", value); - MapPropertySource left = new MapPropertySource("on-error", Map.of(Constants.ERROR_PROPERTY, "true")); - MapPropertySource right = new MapPropertySource("right", rightMap); - boolean changed = ConfigReloadUtil.changed(List.of(left), List.of(right)); - assertThat(changed).isFalse(); - } - private static final class OneComposite extends CompositePropertySource { private OneComposite() { diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapErrorOnReadingSourceTests.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapErrorOnReadingSourceTests.java index 549cb4dd5f..9d6be13557 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapErrorOnReadingSourceTests.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapErrorOnReadingSourceTests.java @@ -33,10 +33,8 @@ import org.springframework.boot.test.system.OutputCaptureExtension; import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider; import org.springframework.cloud.kubernetes.commons.config.ConfigMapConfigProperties; -import org.springframework.cloud.kubernetes.commons.config.Constants; import org.springframework.cloud.kubernetes.commons.config.RetryProperties; import org.springframework.core.env.CompositePropertySource; -import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.PropertySource; import org.springframework.mock.env.MockEnvironment; @@ -62,11 +60,11 @@ static void beforeAll() { /** *
 	 *     we try to read all config maps in a namespace and fail,
-	 *     thus generate a well defined name for the source.
+	 *     thus the composite property source is empty.
 	 * 
*/ @Test - void namedSingleConfigMapFails() { + void namedSingleConfigMapFails(CapturedOutput output) { String name = "my-config"; String namespace = "spring-k8s"; String path = "/api/v1/namespaces/" + namespace + "/configmaps"; @@ -80,13 +78,8 @@ void namedSingleConfigMapFails() { configMapConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment())); CompositePropertySource propertySource = (CompositePropertySource) locator.locate(new MockEnvironment()); - MapPropertySource mapPropertySource = (MapPropertySource) propertySource.getPropertySources() - .stream() - .findAny() - .orElseThrow(); - - assertThat(mapPropertySource.getProperty(Constants.ERROR_PROPERTY)).isEqualTo("true"); - + assertThat(propertySource.getPropertySources()).isEmpty(); + assertThat(output.getOut()).contains("Failed to load source: { config-map name : 'Optional[my-config]'"); } /** @@ -96,7 +89,7 @@ void namedSingleConfigMapFails() { * */ @Test - void namedTwoConfigMapsOneFails() { + void namedTwoConfigMapsOneFails(CapturedOutput output) { String configMapNameOne = "one"; String configMapNameTwo = "two"; String namespace = "default"; @@ -123,10 +116,9 @@ void namedTwoConfigMapsOneFails() { CompositePropertySource propertySource = (CompositePropertySource) locator.locate(new MockEnvironment()); List names = propertySource.getPropertySources().stream().map(PropertySource::getName).toList(); - // two sources are present - assertThat(names).containsExactly("configmap.two.default", "configmap..default"); - assertThat(propertySource.getProperty(Constants.ERROR_PROPERTY)).isEqualTo("true"); - + // one source is present + assertThat(names).containsExactly("configmap.two.default"); + assertThat(output.getOut()).contains("Failed to load source: { config-map name : 'Optional[one]'"); } /** @@ -136,7 +128,7 @@ void namedTwoConfigMapsOneFails() { * */ @Test - void namedTwoConfigMapsBothFail() { + void namedTwoConfigMapsBothFail(CapturedOutput output) { String configMapNameOne = "one"; String configMapNameTwo = "two"; String namespace = "default"; @@ -158,15 +150,14 @@ void namedTwoConfigMapsBothFail() { CompositePropertySource propertySource = (CompositePropertySource) locator.locate(new MockEnvironment()); List names = propertySource.getPropertySources().stream().map(PropertySource::getName).toList(); - assertThat(names).containsExactly("configmap..default"); - assertThat(propertySource.getProperty(Constants.ERROR_PROPERTY)).isEqualTo("true"); - + assertThat(propertySource.getPropertySources()).isEmpty(); + assertThat(output.getOut()).contains("Failed to load source: { config-map name : 'Optional[one]'"); + assertThat(output.getOut()).contains("Failed to load source: { config-map name : 'Optional[two]'"); } /** *
-	 *     we try to read all config maps in a namespace and fail,
-	 *     thus generate a well defined name for the source.
+	 *     we try to read all config maps in a namespace and fail.
 	 * 
*/ @Test @@ -190,10 +181,8 @@ void labeledSingleConfigMapFails(CapturedOutput output) { CompositePropertySource propertySource = (CompositePropertySource) locator.locate(new MockEnvironment()); List sourceNames = propertySource.getPropertySources().stream().map(PropertySource::getName).toList(); - assertThat(sourceNames).containsExactly("configmap..spring-k8s"); - assertThat(propertySource.getProperty(Constants.ERROR_PROPERTY)).isEqualTo("true"); - assertThat(output).contains("failure in reading labeled sources"); - assertThat(output).contains("failure in reading named sources"); + assertThat(propertySource.getPropertySources()).isEmpty(); + assertThat(output.getOut()).contains("Failed to load source: { config map labels : '{a=b}'"); } /** @@ -236,12 +225,11 @@ void labeledTwoConfigMapsOneFails(CapturedOutput output) { CompositePropertySource propertySource = (CompositePropertySource) locator.locate(new MockEnvironment()); List names = propertySource.getPropertySources().stream().map(PropertySource::getName).toList(); - // two sources are present, one being empty - assertThat(names).containsExactly("configmap.two.default", "configmap..default"); - assertThat(propertySource.getProperty(Constants.ERROR_PROPERTY)).isEqualTo("true"); - - assertThat(output).contains("failure in reading labeled sources"); - assertThat(output).contains("failure in reading named sources"); + // one property source is present + assertThat(names).containsExactly("configmap.two.default"); + assertThat(output.getOut()).contains("Failure in reading labeled sources"); + assertThat(output.getOut()).contains("Failure in reading named sources"); + assertThat(output.getOut()).contains("Failed to load source: { config map labels : '{one=1}'"); } @@ -274,14 +262,12 @@ void labeledTwoConfigMapsBothFail(CapturedOutput output) { configMapConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment())); CompositePropertySource propertySource = (CompositePropertySource) locator.locate(new MockEnvironment()); - List names = propertySource.getPropertySources().stream().map(PropertySource::getName).toList(); - - assertThat(names).containsExactly("configmap..default"); - assertThat(propertySource.getProperty(Constants.ERROR_PROPERTY)).isEqualTo("true"); - - assertThat(output).contains("failure in reading labeled sources"); - assertThat(output).contains("failure in reading named sources"); + assertThat(propertySource.getPropertySources()).isEmpty(); + assertThat(output.getOut()).contains("Failure in reading labeled sources"); + assertThat(output.getOut()).contains("Failure in reading named sources"); + assertThat(output.getOut()).contains("Failed to load source: { config map labels : '{two=2}'"); + assertThat(output.getOut()).contains("Failed to load source: { config map labels : '{one=1}'"); } private ConfigMap configMap(String name, Map labels) { 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 68026db2d0..9b26bf7f1b 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 @@ -16,6 +16,7 @@ package org.springframework.cloud.kubernetes.fabric8.config; +import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -24,12 +25,18 @@ import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.test.system.CapturedOutput; +import org.springframework.boot.test.system.OutputCaptureExtension; import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider; import org.springframework.cloud.kubernetes.commons.config.ConfigMapConfigProperties; import org.springframework.cloud.kubernetes.commons.config.RetryProperties; +import org.springframework.core.env.CompositePropertySource; +import org.springframework.core.env.PropertySource; import org.springframework.mock.env.MockEnvironment; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatNoException; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -37,6 +44,7 @@ * @author Isik Erhan */ @EnableKubernetesMockClient +@ExtendWith(OutputCaptureExtension.class) class Fabric8ConfigMapPropertySourceLocatorTests { private static KubernetesMockServer mockServer; @@ -67,7 +75,7 @@ void locateShouldThrowExceptionOnFailureWhenFailFastIsEnabled() { } @Test - void locateShouldNotThrowExceptionOnFailureWhenFailFastIsDisabled() { + void locateShouldNotThrowExceptionOnFailureWhenFailFastIsDisabled(CapturedOutput output) { String name = "my-config"; String namespace = "default"; String path = "/api/v1/namespaces/default/configmaps"; @@ -80,7 +88,16 @@ void locateShouldNotThrowExceptionOnFailureWhenFailFastIsDisabled() { Fabric8ConfigMapPropertySourceLocator locator = new Fabric8ConfigMapPropertySourceLocator(mockClient, configMapConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment())); - assertThatNoException().isThrownBy(() -> locator.locate(new MockEnvironment())); + List> result = new ArrayList<>(); + assertThatNoException().isThrownBy(() -> { + PropertySource source = locator.locate(new MockEnvironment()); + result.add(source); + }); + + assertThat(result.get(0)).isInstanceOf(CompositePropertySource.class); + CompositePropertySource composite = (CompositePropertySource) result.get(0); + assertThat(composite.getPropertySources()).hasSize(0); + assertThat(output.getOut()).contains("Failed to load source:"); } } diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8SecretErrorOnReadingSourceTests.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8SecretErrorOnReadingSourceTests.java index 4c203861f3..00bee4b51b 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8SecretErrorOnReadingSourceTests.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8SecretErrorOnReadingSourceTests.java @@ -32,11 +32,9 @@ import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider; -import org.springframework.cloud.kubernetes.commons.config.Constants; import org.springframework.cloud.kubernetes.commons.config.RetryProperties; import org.springframework.cloud.kubernetes.commons.config.SecretsConfigProperties; import org.springframework.core.env.CompositePropertySource; -import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.PropertySource; import org.springframework.mock.env.MockEnvironment; @@ -61,8 +59,7 @@ static void beforeAll() { /** *
-	 *     we try to read all secrets in a namespace and fail,
-	 *     thus generate a well defined name for the source.
+	 *     we try to read all secrets in a namespace and fail.
 	 * 
*/ @Test @@ -80,14 +77,9 @@ void namedSingleSecretFails(CapturedOutput output) { secretsConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment())); CompositePropertySource propertySource = (CompositePropertySource) locator.locate(new MockEnvironment()); - MapPropertySource mapPropertySource = (MapPropertySource) propertySource.getPropertySources() - .stream() - .findAny() - .orElseThrow(); - - assertThat(mapPropertySource.getName()).isEqualTo("secret..spring-k8s"); - assertThat(propertySource.getProperty(Constants.ERROR_PROPERTY)).isEqualTo("true"); - assertThat(output).contains("failure in reading named sources"); + assertThat(propertySource.getPropertySources()).isEmpty(); + assertThat(output.getOut()).contains("Failure in reading named sources"); + assertThat(output.getOut()).contains("Failed to load source: { secret name : 'Optional[my-secret]'"); } @@ -98,7 +90,7 @@ void namedSingleSecretFails(CapturedOutput output) { * */ @Test - void namedTwoSecretsOneFails() { + void namedTwoSecretsOneFails(CapturedOutput output) { String secretNameOne = "one"; String secretNameTwo = "two"; String namespace = "default"; @@ -121,9 +113,10 @@ void namedTwoSecretsOneFails() { CompositePropertySource propertySource = (CompositePropertySource) locator.locate(new MockEnvironment()); List names = propertySource.getPropertySources().stream().map(PropertySource::getName).toList(); - // two sources are present, one being empty - assertThat(names).containsExactly("secret.two.default", "secret..default"); - assertThat(propertySource.getProperty(Constants.ERROR_PROPERTY)).isEqualTo("true"); + // one property source is present + assertThat(names).containsExactly("secret.two.default"); + assertThat(output.getOut()).contains("Failure in reading named sources"); + assertThat(output.getOut()).contains("Failed to load source: { secret name : 'Optional[one]'"); } @@ -134,7 +127,7 @@ void namedTwoSecretsOneFails() { * */ @Test - void namedTwoSecretsBothFail() { + void namedTwoSecretsBothFail(CapturedOutput output) { String secretNameOne = "one"; String secretNameTwo = "two"; String namespace = "default"; @@ -153,10 +146,9 @@ void namedTwoSecretsBothFail() { secretsConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment())); CompositePropertySource propertySource = (CompositePropertySource) locator.locate(new MockEnvironment()); - List names = propertySource.getPropertySources().stream().map(PropertySource::getName).toList(); - assertThat(names).containsExactly("secret..default"); - assertThat(propertySource.getProperty(Constants.ERROR_PROPERTY)).isEqualTo("true"); + assertThat(propertySource.getPropertySources()).isEmpty(); + assertThat(output.getOut()).contains("Failed to load source: { secret name : 'Optional[two]'"); } @@ -185,12 +177,11 @@ void labeledSingleSecretFails(CapturedOutput output) { secretsConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment())); CompositePropertySource propertySource = (CompositePropertySource) locator.locate(new MockEnvironment()); - List sourceNames = propertySource.getPropertySources().stream().map(PropertySource::getName).toList(); - assertThat(sourceNames).containsExactly("secret..spring-k8s"); - assertThat(propertySource.getProperty(Constants.ERROR_PROPERTY)).isEqualTo("true"); - assertThat(output).contains("failure in reading labeled sources"); - assertThat(output).contains("failure in reading named sources"); + assertThat(propertySource.getPropertySources()).isEmpty(); + assertThat(output.getOut()).contains("Failure in reading labeled sources"); + assertThat(output.getOut()).contains("Failure in reading named sources"); + assertThat(output.getOut()).contains("Failed to load source: { secret labels : '{a=b}'"); } /** @@ -233,12 +224,12 @@ void labeledTwoSecretsOneFails(CapturedOutput output) { CompositePropertySource propertySource = (CompositePropertySource) locator.locate(new MockEnvironment()); List names = propertySource.getPropertySources().stream().map(PropertySource::getName).toList(); - // two sources are present, one being empty - assertThat(names).containsExactly("secret.two.default", "secret..default"); - assertThat(propertySource.getProperty(Constants.ERROR_PROPERTY)).isEqualTo("true"); + // one property source is present + assertThat(names).containsExactly("secret.two.default"); - assertThat(output).contains("failure in reading labeled sources"); - assertThat(output).contains("failure in reading named sources"); + assertThat(output.getOut()).contains("Failure in reading labeled sources"); + assertThat(output.getOut()).contains("Failure in reading named sources"); + assertThat(output.getOut()).contains("Failed to load source: { secret labels : '{one=1}'"); } @@ -271,13 +262,13 @@ void labeledTwoConfigMapsBothFail(CapturedOutput output) { secretsConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment())); CompositePropertySource propertySource = (CompositePropertySource) locator.locate(new MockEnvironment()); - List names = propertySource.getPropertySources().stream().map(PropertySource::getName).toList(); - assertThat(names).containsExactly("secret..default"); - assertThat(propertySource.getProperty(Constants.ERROR_PROPERTY)).isEqualTo("true"); + assertThat(propertySource.getPropertySources()).isEmpty(); - assertThat(output).contains("failure in reading labeled sources"); - assertThat(output).contains("failure in reading named sources"); + assertThat(output).contains("Failure in reading labeled sources"); + assertThat(output).contains("Failure in reading named sources"); + assertThat(output.getOut()).contains("Failed to load source: { secret labels : '{one=1}'"); + assertThat(output.getOut()).contains("Failed to load source: { secret labels : '{two=2}'"); } 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 53c4d0a711..e8ac439dc3 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 @@ -16,6 +16,7 @@ package org.springframework.cloud.kubernetes.fabric8.config; +import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -24,12 +25,18 @@ import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.test.system.CapturedOutput; +import org.springframework.boot.test.system.OutputCaptureExtension; import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider; import org.springframework.cloud.kubernetes.commons.config.RetryProperties; import org.springframework.cloud.kubernetes.commons.config.SecretsConfigProperties; +import org.springframework.core.env.CompositePropertySource; +import org.springframework.core.env.PropertySource; import org.springframework.mock.env.MockEnvironment; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatNoException; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -37,6 +44,7 @@ * @author Isik Erhan */ @EnableKubernetesMockClient +@ExtendWith(OutputCaptureExtension.class) class Fabric8SecretsPropertySourceLocatorTests { private static KubernetesMockServer mockServer; @@ -67,7 +75,7 @@ void locateShouldThrowExceptionOnFailureWhenFailFastIsEnabled() { } @Test - void locateShouldNotThrowExceptionOnFailureWhenFailFastIsDisabled() { + void locateShouldNotThrowExceptionOnFailureWhenFailFastIsDisabled(CapturedOutput output) { String name = "my-secret"; String namespace = "default"; String path = "/api/v1/namespaces/default/secrets/my-secret"; @@ -80,7 +88,17 @@ void locateShouldNotThrowExceptionOnFailureWhenFailFastIsDisabled() { Fabric8SecretsPropertySourceLocator locator = new Fabric8SecretsPropertySourceLocator(mockClient, configMapConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment())); - assertThatNoException().isThrownBy(() -> locator.locate(new MockEnvironment())); + List> result = new ArrayList<>(); + assertThatNoException().isThrownBy(() -> { + PropertySource source = locator.locate(new MockEnvironment()); + result.add(source); + }); + + assertThat(result.get(0)).isInstanceOf(CompositePropertySource.class); + CompositePropertySource composite = (CompositePropertySource) result.get(0); + assertThat(composite.getPropertySources()).hasSize(0); + assertThat(output.getOut()).contains("Failed to load source:"); + } } diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/EventReloadConfigMapTest.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/EventReloadConfigMapTest.java index d14efbabab..0f4c7c3db9 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/EventReloadConfigMapTest.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/EventReloadConfigMapTest.java @@ -114,11 +114,10 @@ void test(CapturedOutput output) { // we fail while reading 'configMapTwo' Awaitility.await().atMost(Duration.ofSeconds(10)).pollInterval(Duration.ofSeconds(1)).until(() -> { - boolean one = output.getOut().contains("failure in reading named sources"); - boolean two = output.getOut() - .contains("there was an error while reading config maps/secrets, no reload will happen"); + boolean one = output.getOut().contains("Failure in reading named sources"); + boolean two = output.getOut().contains("Failed to load source"); boolean three = output.getOut() - .contains("reloadable condition was not satisfied, reload will not be triggered"); + .contains("Reloadable condition was not satisfied, reload will not be triggered"); boolean updateStrategyNotCalled = !strategyCalled[0]; return one && two && three && updateStrategyNotCalled; }); diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/EventReloadSecretTest.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/EventReloadSecretTest.java index 546ae964b4..57a699bc5c 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/EventReloadSecretTest.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/EventReloadSecretTest.java @@ -116,11 +116,10 @@ void test(CapturedOutput output) { // we fail while reading 'secretTwo' Awaitility.await().atMost(Duration.ofSeconds(10)).pollInterval(Duration.ofSeconds(1)).until(() -> { - boolean one = output.getOut().contains("failure in reading named sources"); - boolean two = output.getOut() - .contains("there was an error while reading config maps/secrets, no reload will happen"); + boolean one = output.getOut().contains("Failure in reading named sources"); + boolean two = output.getOut().contains("Failed to load source"); boolean three = output.getOut() - .contains("reloadable condition was not satisfied, reload will not be triggered"); + .contains("Reloadable condition was not satisfied, reload will not be triggered"); boolean updateStrategyNotCalled = !strategyCalled[0]; return one && two && three && updateStrategyNotCalled; }); diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/PollingReloadConfigMapTest.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/PollingReloadConfigMapTest.java index 372ca8be31..0f980577f0 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/PollingReloadConfigMapTest.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/PollingReloadConfigMapTest.java @@ -109,11 +109,10 @@ static void beforeAll() { void test(CapturedOutput output) { // we fail while reading 'configMapOne' Awaitility.await().atMost(Duration.ofSeconds(10)).pollInterval(Duration.ofSeconds(1)).until(() -> { - boolean one = output.getOut().contains("failure in reading named sources"); - boolean two = output.getOut() - .contains("there was an error while reading config maps/secrets, no reload will happen"); + boolean one = output.getOut().contains("Failure in reading named sources"); + boolean two = output.getOut().contains("Failed to load source"); boolean three = output.getOut() - .contains("reloadable condition was not satisfied, reload will not be triggered"); + .contains("Reloadable condition was not satisfied, reload will not be triggered"); boolean updateStrategyNotCalled = !strategyCalled[0]; return one && two && three && updateStrategyNotCalled; }); diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/PollingReloadSecretTest.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/PollingReloadSecretTest.java index 68667637ce..4c100084ee 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/PollingReloadSecretTest.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/reload_it/PollingReloadSecretTest.java @@ -112,11 +112,10 @@ static void beforeAll() { void test(CapturedOutput output) { // we fail while reading 'secretOne' Awaitility.await().atMost(Duration.ofSeconds(10)).pollInterval(Duration.ofSeconds(1)).until(() -> { - boolean one = output.getOut().contains("failure in reading named sources"); - boolean two = output.getOut() - .contains("there was an error while reading config maps/secrets, no reload will happen"); + boolean one = output.getOut().contains("Failure in reading named sources"); + boolean two = output.getOut().contains("Failed to load source"); boolean three = output.getOut() - .contains("reloadable condition was not satisfied, reload will not be triggered"); + .contains("Reloadable condition was not satisfied, reload will not be triggered"); boolean updateStrategyNotCalled = !strategyCalled[0]; return one && two && three && updateStrategyNotCalled; });