Skip to content

Commit 8eae516

Browse files
authored
Fix 1592 empty source on error part 2 (#1800)
1 parent ac23677 commit 8eae516

File tree

21 files changed

+195
-177
lines changed

21 files changed

+195
-177
lines changed

spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapErrorOnReadingSourceTests.java

Lines changed: 27 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,8 @@
3939
import org.springframework.boot.test.system.OutputCaptureExtension;
4040
import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
4141
import org.springframework.cloud.kubernetes.commons.config.ConfigMapConfigProperties;
42-
import org.springframework.cloud.kubernetes.commons.config.Constants;
4342
import org.springframework.cloud.kubernetes.commons.config.RetryProperties;
4443
import org.springframework.core.env.CompositePropertySource;
45-
import org.springframework.core.env.MapPropertySource;
4644
import org.springframework.core.env.PropertySource;
4745
import org.springframework.mock.env.MockEnvironment;
4846

@@ -100,12 +98,11 @@ public void afterEach() {
10098

10199
/**
102100
* <pre>
103-
* we try to read all config maps in a namespace and fail,
104-
* thus generate a well defined name for the source.
101+
* we try to read all config maps in a namespace and fail.
105102
* </pre>
106103
*/
107104
@Test
108-
void namedSingleConfigMapFails() {
105+
void namedSingleConfigMapFails(CapturedOutput output) {
109106
String name = "my-config";
110107
String namespace = "spring-k8s";
111108
String path = "/api/v1/namespaces/" + namespace + "/configmaps";
@@ -120,13 +117,10 @@ void namedSingleConfigMapFails() {
120117
configMapConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment()));
121118

122119
CompositePropertySource propertySource = (CompositePropertySource) locator.locate(new MockEnvironment());
123-
MapPropertySource mapPropertySource = (MapPropertySource) propertySource.getPropertySources()
124-
.stream()
125-
.findAny()
126-
.orElseThrow();
127120

128-
assertThat(mapPropertySource.getName()).isEqualTo("configmap..spring-k8s");
129-
assertThat(propertySource.getProperty(Constants.ERROR_PROPERTY)).isEqualTo("true");
121+
assertThat(propertySource.getPropertySources()).isEmpty();
122+
assertThat(output.getOut()).contains("Failure in reading named sources");
123+
assertThat(output.getOut()).contains("Failed to load source: { config-map name : 'Optional[my-config]'");
130124

131125
}
132126

@@ -168,11 +162,12 @@ void namedTwoConfigMapsOneFails(CapturedOutput output) {
168162
CompositePropertySource propertySource = (CompositePropertySource) locator.locate(new MockEnvironment());
169163
List<String> names = propertySource.getPropertySources().stream().map(PropertySource::getName).toList();
170164

171-
// two sources are present, one being empty
172-
assertThat(names).containsExactly("configmap.two.default", "configmap..default");
173-
assertThat(propertySource.getProperty(Constants.ERROR_PROPERTY)).isEqualTo("true");
165+
// one property source is present
166+
assertThat(names).containsExactly("configmap.two.default");
174167
assertThat(output.getOut())
175168
.doesNotContain("sourceName : two was requested, but not found in namespace : default");
169+
assertThat(output.getOut()).contains("Failure in reading named sources");
170+
assertThat(output.getOut()).contains("Failed to load source: { config-map name : 'Optional[one]'");
176171

177172
}
178173

@@ -212,20 +207,19 @@ void namedTwoConfigMapsBothFail(CapturedOutput output) {
212207
configMapConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment()));
213208

214209
CompositePropertySource propertySource = (CompositePropertySource) locator.locate(new MockEnvironment());
215-
List<String> names = propertySource.getPropertySources().stream().map(PropertySource::getName).toList();
216210

217-
assertThat(names).containsExactly("configmap..default");
218-
assertThat(propertySource.getProperty(Constants.ERROR_PROPERTY)).isEqualTo("true");
211+
assertThat(propertySource.getPropertySources()).isEmpty();
219212
assertThat(output.getOut())
220213
.doesNotContain("sourceName : one was requested, but not found in namespace : default");
221214
assertThat(output.getOut())
222215
.doesNotContain("sourceName : two was requested, but not found in namespace : default");
216+
assertThat(output.getOut()).contains("Failure in reading named sources");
217+
assertThat(output.getOut()).contains("Failed to load source: { config-map name : 'Optional[one]'");
223218
}
224219

225220
/**
226221
* <pre>
227-
* we try to read all config maps in a namespace and fail,
228-
* thus generate a well defined name for the source.
222+
* we try to read all config maps in a namespace and fail.
229223
* </pre>
230224
*/
231225
@Test
@@ -256,12 +250,11 @@ void labeledSingleConfigMapFails(CapturedOutput output) {
256250
configMapConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment()));
257251

258252
CompositePropertySource propertySource = (CompositePropertySource) locator.locate(new MockEnvironment());
259-
List<String> sourceNames = propertySource.getPropertySources().stream().map(PropertySource::getName).toList();
260253

261-
assertThat(sourceNames).containsExactly("configmap..spring-k8s");
262-
assertThat(propertySource.getProperty(Constants.ERROR_PROPERTY)).isEqualTo("true");
263-
assertThat(output).contains("failure in reading labeled sources");
264-
assertThat(output).contains("failure in reading named sources");
254+
assertThat(propertySource.getPropertySources()).isEmpty();
255+
assertThat(output.getOut()).contains("Failure in reading labeled sources");
256+
assertThat(output.getOut()).contains("Failure in reading named sources");
257+
assertThat(output.getOut()).contains("Failed to load source: { config map labels : '{a=b}'");
265258
}
266259

267260
/**
@@ -311,12 +304,11 @@ void labeledTwoConfigMapsOneFails(CapturedOutput output) {
311304
CompositePropertySource propertySource = (CompositePropertySource) locator.locate(new MockEnvironment());
312305
List<String> names = propertySource.getPropertySources().stream().map(PropertySource::getName).toList();
313306

314-
// two sources are present, one being empty
315-
assertThat(names).containsExactly("configmap.two.default", "configmap..default");
316-
assertThat(propertySource.getProperty(Constants.ERROR_PROPERTY)).isEqualTo("true");
317-
318-
assertThat(output).contains("failure in reading labeled sources");
319-
assertThat(output).contains("failure in reading named sources");
307+
// one source is present
308+
assertThat(names).containsExactly("configmap.two.default");
309+
assertThat(output.getOut()).contains("Failure in reading labeled sources");
310+
assertThat(output.getOut()).contains("Failure in reading named sources");
311+
assertThat(output.getOut()).contains("Failed to load source: { config map labels : '{one=1}'");
320312

321313
}
322314

@@ -364,15 +356,12 @@ void labeledTwoConfigMapsBothFail(CapturedOutput output) {
364356
configMapConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment()));
365357

366358
CompositePropertySource propertySource = (CompositePropertySource) locator.locate(new MockEnvironment());
367-
List<String> names = propertySource.getPropertySources().stream().map(PropertySource::getName).toList();
368-
369-
// all 3 sources ('application' named source, and two labeled sources)
370-
assertThat(names).containsExactly("configmap..default");
371-
assertThat(propertySource.getProperty(Constants.ERROR_PROPERTY)).isEqualTo("true");
372-
373-
assertThat(output).contains("failure in reading labeled sources");
374-
assertThat(output).contains("failure in reading named sources");
375359

360+
assertThat(propertySource.getPropertySources()).isEmpty();
361+
assertThat(output).contains("Failure in reading labeled sources");
362+
assertThat(output).contains("Failure in reading named sources");
363+
assertThat(output.getOut()).contains("Failed to load source: { config map labels : '{one=1}'");
364+
assertThat(output.getOut()).contains("Failed to load source: { config map labels : '{two=2}'");
376365
}
377366

378367
}

spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapPropertySourceLocatorTests.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.cloud.kubernetes.client.config;
1818

19+
import java.util.ArrayList;
1920
import java.util.Collections;
2021
import java.util.List;
2122
import java.util.Map;
@@ -34,12 +35,16 @@
3435
import org.junit.jupiter.api.AfterEach;
3536
import org.junit.jupiter.api.BeforeAll;
3637
import org.junit.jupiter.api.Test;
38+
import org.junit.jupiter.api.extension.ExtendWith;
3739

40+
import org.springframework.boot.test.system.CapturedOutput;
41+
import org.springframework.boot.test.system.OutputCaptureExtension;
3842
import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
3943
import org.springframework.cloud.kubernetes.commons.config.ConfigMapConfigProperties;
4044
import org.springframework.cloud.kubernetes.commons.config.Constants;
4145
import org.springframework.cloud.kubernetes.commons.config.NamespaceResolutionFailedException;
4246
import org.springframework.cloud.kubernetes.commons.config.RetryProperties;
47+
import org.springframework.core.env.CompositePropertySource;
4348
import org.springframework.core.env.PropertySource;
4449
import org.springframework.mock.env.MockEnvironment;
4550

@@ -55,6 +60,7 @@
5560
* @author Ryan Baxter
5661
* @author Isik Erhan
5762
*/
63+
@ExtendWith(OutputCaptureExtension.class)
5864
class KubernetesClientConfigMapPropertySourceLocatorTests {
5965

6066
private static final V1ConfigMapList PROPERTIES_CONFIGMAP_LIST = new V1ConfigMapList()
@@ -185,7 +191,7 @@ public void locateShouldThrowExceptionOnFailureWhenFailFastIsEnabled() {
185191
}
186192

187193
@Test
188-
public void locateShouldNotThrowExceptionOnFailureWhenFailFastIsDisabled() {
194+
public void locateShouldNotThrowExceptionOnFailureWhenFailFastIsDisabled(CapturedOutput output) {
189195
CoreV1Api api = new CoreV1Api();
190196
stubFor(get("/api/v1/namespaces/default/configmaps")
191197
.willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
@@ -196,7 +202,18 @@ public void locateShouldNotThrowExceptionOnFailureWhenFailFastIsDisabled() {
196202
KubernetesClientConfigMapPropertySourceLocator locator = new KubernetesClientConfigMapPropertySourceLocator(api,
197203
configMapConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment()));
198204

199-
assertThatNoException().isThrownBy(() -> locator.locate(new MockEnvironment()));
205+
List<PropertySource<?>> result = new ArrayList<>();
206+
assertThatNoException().isThrownBy(() -> {
207+
PropertySource<?> source = locator.locate(new MockEnvironment());
208+
result.add(source);
209+
});
210+
211+
assertThat(result.get(0)).isInstanceOf(CompositePropertySource.class);
212+
CompositePropertySource composite = (CompositePropertySource) result.get(0);
213+
assertThat(composite.getPropertySources()).hasSize(0);
214+
assertThat(output.getOut()).contains("Failed to load source:");
215+
216+
200217
}
201218

202219
}

spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientSecretsPropertySourceLocatorTests.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.cloud.kubernetes.client.config;
1818

19+
import java.util.ArrayList;
1920
import java.util.Collections;
2021
import java.util.List;
2122
import java.util.Map;
@@ -30,11 +31,15 @@
3031
import org.junit.jupiter.api.AfterEach;
3132
import org.junit.jupiter.api.BeforeAll;
3233
import org.junit.jupiter.api.Test;
34+
import org.junit.jupiter.api.extension.ExtendWith;
3335

36+
import org.springframework.boot.test.system.CapturedOutput;
37+
import org.springframework.boot.test.system.OutputCaptureExtension;
3438
import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
3539
import org.springframework.cloud.kubernetes.commons.config.NamespaceResolutionFailedException;
3640
import org.springframework.cloud.kubernetes.commons.config.RetryProperties;
3741
import org.springframework.cloud.kubernetes.commons.config.SecretsConfigProperties;
42+
import org.springframework.core.env.CompositePropertySource;
3843
import org.springframework.core.env.PropertySource;
3944
import org.springframework.mock.env.MockEnvironment;
4045

@@ -50,6 +55,7 @@
5055
* @author Ryan Baxter
5156
* @author Isik Erhan
5257
*/
58+
@ExtendWith(OutputCaptureExtension.class)
5359
class KubernetesClientSecretsPropertySourceLocatorTests {
5460

5561
private static final String LIST_API = "/api/v1/namespaces/default/secrets";
@@ -200,7 +206,7 @@ void locateShouldThrowExceptionOnFailureWhenFailFastIsEnabled() {
200206
}
201207

202208
@Test
203-
void locateShouldNotThrowExceptionOnFailureWhenFailFastIsDisabled() {
209+
void locateShouldNotThrowExceptionOnFailureWhenFailFastIsDisabled(CapturedOutput output) {
204210
CoreV1Api api = new CoreV1Api();
205211
stubFor(get(LIST_API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
206212

@@ -210,7 +216,16 @@ void locateShouldNotThrowExceptionOnFailureWhenFailFastIsDisabled() {
210216
KubernetesClientSecretsPropertySourceLocator locator = new KubernetesClientSecretsPropertySourceLocator(api,
211217
new KubernetesNamespaceProvider(new MockEnvironment()), secretsConfigProperties);
212218

213-
assertThatNoException().isThrownBy(() -> locator.locate(new MockEnvironment()));
219+
List<PropertySource<?>> result = new ArrayList<>();
220+
assertThatNoException().isThrownBy(() -> {
221+
PropertySource<?> source = locator.locate(new MockEnvironment());
222+
result.add(source);
223+
});
224+
225+
assertThat(result.get(0)).isInstanceOf(CompositePropertySource.class);
226+
CompositePropertySource composite = (CompositePropertySource) result.get(0);
227+
assertThat(composite.getPropertySources()).hasSize(0);
228+
assertThat(output.getOut()).contains("Failed to load source:");
214229
}
215230

216231
}

spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/EventReloadConfigMapTest.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,11 +154,10 @@ void test(CapturedOutput output) {
154154

155155
// we fail while reading 'configMapOne'
156156
Awaitility.await().atMost(Duration.ofSeconds(10)).pollInterval(Duration.ofSeconds(1)).until(() -> {
157-
boolean one = output.getOut().contains("failure in reading named sources");
158-
boolean two = output.getOut()
159-
.contains("there was an error while reading config maps/secrets, no reload will happen");
157+
boolean one = output.getOut().contains("Failure in reading named sources");
158+
boolean two = output.getOut().contains("Failed to load source");
160159
boolean three = output.getOut()
161-
.contains("reloadable condition was not satisfied, reload will not be triggered");
160+
.contains("Reloadable condition was not satisfied, reload will not be triggered");
162161
boolean updateStrategyNotCalled = !strategyCalled[0];
163162
return one && two && three && updateStrategyNotCalled;
164163
});

spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/EventReloadSecretTest.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,10 @@ void test(CapturedOutput output) {
156156

157157
// we fail while reading 'configMapOne'
158158
Awaitility.await().atMost(Duration.ofSeconds(10)).pollInterval(Duration.ofSeconds(1)).until(() -> {
159-
boolean one = output.getOut().contains("failure in reading named sources");
160-
boolean two = output.getOut()
161-
.contains("there was an error while reading config maps/secrets, no reload will happen");
159+
boolean one = output.getOut().contains("Failure in reading named sources");
160+
boolean two = output.getOut().contains("Failed to load source");
162161
boolean three = output.getOut()
163-
.contains("reloadable condition was not satisfied, reload will not be triggered");
162+
.contains("Reloadable condition was not satisfied, reload will not be triggered");
164163
boolean updateStrategyNotCalled = !strategyCalled[0];
165164
return one && two && three && updateStrategyNotCalled;
166165
});

spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/PollingReloadConfigMapTest.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,10 @@ static void after() {
136136
void test(CapturedOutput output) {
137137
// we fail while reading 'configMapOne'
138138
Awaitility.await().atMost(Duration.ofSeconds(10)).pollInterval(Duration.ofSeconds(1)).until(() -> {
139-
boolean one = output.getOut().contains("failure in reading named sources");
140-
boolean two = output.getOut()
141-
.contains("there was an error while reading config maps/secrets, no reload will happen");
139+
boolean one = output.getOut().contains("Failure in reading named sources");
140+
boolean two = output.getOut().contains("Failed to load source");
142141
boolean three = output.getOut()
143-
.contains("reloadable condition was not satisfied, reload will not be triggered");
142+
.contains("Reloadable condition was not satisfied, reload will not be triggered");
144143
boolean updateStrategyNotCalled = !strategyCalled[0];
145144
return one && two && three && updateStrategyNotCalled;
146145
});

spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/reload_it/PollingReloadSecretTest.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,10 @@ static void after() {
137137
void test(CapturedOutput output) {
138138
// we fail while reading 'secretOne'
139139
Awaitility.await().atMost(Duration.ofSeconds(10)).pollInterval(Duration.ofSeconds(1)).until(() -> {
140-
boolean one = output.getOut().contains("failure in reading named sources");
141-
boolean two = output.getOut()
142-
.contains("there was an error while reading config maps/secrets, no reload will happen");
140+
boolean one = output.getOut().contains("Failure in reading named sources");
141+
boolean two = output.getOut().contains("Failed to load source");
143142
boolean three = output.getOut()
144-
.contains("reloadable condition was not satisfied, reload will not be triggered");
143+
.contains("Reloadable condition was not satisfied, reload will not be triggered");
145144
boolean updateStrategyNotCalled = !strategyCalled[0];
146145
return one && two && three && updateStrategyNotCalled;
147146
});

spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/ConfigMapPropertySourceLocator.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,13 @@ public PropertySource<?> locate(Environment environment) {
8484
LOG.debug("Config Map normalized sources : " + sources);
8585
sources.forEach(s -> {
8686
MapPropertySource propertySource = getMapPropertySource(s, env);
87-
LOG.debug("Adding config map property source " + propertySource.getName());
88-
composite.addFirstPropertySource(propertySource);
87+
if ("true".equals(propertySource.getProperty(Constants.ERROR_PROPERTY))) {
88+
LOG.warn("Failed to load source: " + s);
89+
}
90+
else {
91+
LOG.debug("Adding config map property source " + propertySource.getName());
92+
composite.addFirstPropertySource(propertySource);
93+
}
8994
});
9095
}
9196

spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/LabeledSourceData.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public final SourceData compute(Map<String, String> labels, ConfigUtils.Prefix p
7979
}
8080
}
8181
catch (Exception e) {
82-
LOG.warn("failure in reading labeled sources");
82+
LOG.warn("Failure in reading labeled sources");
8383
onException(failFast, e);
8484
data = new MultipleSourcesContainer(data.names(), Map.of(ERROR_PROPERTY, "true"));
8585
}

spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/NamedSourceData.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public final SourceData compute(String sourceName, ConfigUtils.Prefix prefix, St
7171

7272
}
7373
catch (Exception e) {
74-
LOG.warn("failure in reading named sources");
74+
LOG.warn("Failure in reading named sources");
7575
onException(failFast, e);
7676
data = new MultipleSourcesContainer(data.names(), Map.of(ERROR_PROPERTY, "true"));
7777
}

0 commit comments

Comments
 (0)