names = new HashSet<>();
names.add(name);
- if (environment != null) {
+ if (environment != null && includeProfileSpecificSources) {
for (String activeProfile : environment.getActiveProfiles()) {
names.add(name + "-" + activeProfile);
}
diff --git a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapPropertySourceLocator.java b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapPropertySourceLocator.java
index 245c63b4..5f1000e9 100644
--- a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapPropertySourceLocator.java
+++ b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapPropertySourceLocator.java
@@ -88,7 +88,7 @@ public class KubernetesClientConfigMapPropertySourceLocator extends ConfigMapPro
}
return new KubernetesClientConfigMapPropertySource(coreV1Api, name, namespace, environment,
- normalizedSource.getPrefix());
+ normalizedSource.getPrefix(), normalizedSource.isIncludeProfileSpecificSources());
}
}
diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapIncludeProfileSpecificSourcesTests.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapIncludeProfileSpecificSourcesTests.java
new file mode 100644
index 00000000..88127664
--- /dev/null
+++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapIncludeProfileSpecificSourcesTests.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2013-2020 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.kubernetes.client.config;
+
+import com.github.tomakehurst.wiremock.client.WireMock;
+import org.hamcrest.Matchers;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.cloud.kubernetes.client.config.applications.include_profile_specific_sources.IncludeProfileSpecificSourcesApp;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.test.web.reactive.server.WebTestClient;
+
+/**
+ * The stub data for this test is in : IncludeProfileSpecificSourcesConfigurationStub
+ *
+ * @author wind57
+ */
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = IncludeProfileSpecificSourcesApp.class,
+ properties = { "spring.cloud.bootstrap.name=include-profile-specific-sources", "include.profile.specific.sources=true" })
+@AutoConfigureWebTestClient
+@ActiveProfiles("dev")
+class KubernetesClientConfigMapIncludeProfileSpecificSourcesTests {
+
+ @Autowired
+ private WebTestClient webClient;
+
+ @AfterEach
+ public void afterEach() {
+ WireMock.reset();
+ }
+
+ @AfterAll
+ public static void afterAll() {
+ WireMock.shutdownServer();
+ }
+
+ /**
+ *
+ * 'spring.cloud.kubernetes.config.includeProfileSpecificSources=false'
+ * 'spring.cloud.kubernetes.config.sources[0].includeProfileSpecificSources=true'
+ * 'spring.cloud.kubernetes.config.sources[0].name=config-map-one'
+ *
+ * We do not define config-map 'config-map-one', but we do define 'config-map-one-dev'.
+ *
+ * As such: @ConfigurationProperties("one") must be resolved from 'config-map-one-dev'
+ *
+ */
+ @Test
+ public void testOne() {
+ this.webClient.get().uri("/profile-specific/one").exchange().expectStatus().isOk().expectBody(String.class)
+ .value(Matchers.equalTo("one"));
+ }
+
+ /**
+ *
+ * 'spring.cloud.kubernetes.config.includeProfileSpecificSources=false'
+ * 'spring.cloud.kubernetes.config.sources[1].includeProfileSpecificSources=false'
+ * 'spring.cloud.kubernetes.config.sources[1].name=config-map-two'
+ *
+ * We define config-map 'config-map-two', but we also define 'config-map-two-dev'.
+ * This tests proves that data will be read from 'config-map-two' _only_, even if 'config-map-two-dev'
+ * also exists. This happens because of the 'includeProfileSpecificSources=false' property defined at the source level.
+ * If this would be incorrect, the value we read from '/profile-specific/two' would have been 'twoDev' and _not_ 'two',
+ * simply because 'config-map-two-dev' would override the property value.
+ *
+ * As such: @ConfigurationProperties("two") must be resolved from 'config-map-two'
+ *
+ */
+ @Test
+ public void testTwo() {
+ this.webClient.get().uri("/profile-specific/two").exchange().expectStatus().isOk().expectBody(String.class)
+ .value(Matchers.equalTo("two"));
+ }
+
+ /**
+ *
+ * 'spring.cloud.kubernetes.config.includeProfileSpecificSources=false'
+ * 'spring.cloud.kubernetes.config.sources[2].name=config-map-three'
+ *
+ * We define config-map 'config-map-three', but we also define 'config-map-three-dev'.
+ * This tests proves that data will be read from 'config-map-three' _only_, even if 'config-map-three-dev'
+ * also exists. This happens because the 'includeProfileSpecificSources' property is not defined at the source level,
+ * but it is defaulted from the root level, where we set it to false.
+ * If this would be incorrect, the value we read from '/profile-specific/three' would have been 'threeDev' and _not_ 'three',
+ * simply because 'config-map-three-dev' would override the property value.
+ *
+ * As such: @ConfigurationProperties("three") must be resolved from 'config-map-three'
+ *
+ */
+ @Test
+ public void testThree() {
+ this.webClient.get().uri("/profile-specific/three").exchange().expectStatus().isOk().expectBody(String.class)
+ .value(Matchers.equalTo("three"));
+ }
+
+}
diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapNameAsPrefixTests.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapNameAsPrefixTests.java
new file mode 100644
index 00000000..8ad5656e
--- /dev/null
+++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapNameAsPrefixTests.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2013-2020 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.kubernetes.client.config;
+
+import com.github.tomakehurst.wiremock.client.WireMock;
+import org.hamcrest.Matchers;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.cloud.kubernetes.client.config.applications.config_map_name_as_prefix.WithPrefixApp;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.test.web.reactive.server.WebTestClient;
+
+/**
+ * The stub data for this test is in : ConfigMapNameAsPrefixConfigurationStub
+ *
+ * @author wind57
+ */
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = WithPrefixApp.class,
+ properties = { "spring.cloud.bootstrap.name=config-map-name-as-prefix", "config.map.name.as.prefix.stub=true" })
+@AutoConfigureWebTestClient
+public class KubernetesClientConfigMapNameAsPrefixTests {
+
+ @Autowired
+ private WebTestClient webClient;
+
+ @AfterEach
+ public void afterEach() {
+ WireMock.reset();
+ }
+
+ @AfterAll
+ public static void afterAll() {
+ WireMock.shutdownServer();
+ }
+
+ /**
+ *
+ * 'spring.cloud.kubernetes.config.useNameAsPrefix=true'
+ * 'spring.cloud.kubernetes.config.sources[0].useNameAsPrefix=false'
+ * ("one.property", "one")
+ *
+ * As such: @ConfigurationProperties("one")
+ *
+ */
+ @Test
+ public void testOne() {
+ this.webClient.get().uri("/prefix/one").exchange().expectStatus().isOk().expectBody(String.class)
+ .value(Matchers.equalTo("one"));
+ }
+
+ /**
+ *
+ * 'spring.cloud.kubernetes.config.useNameAsPrefix=true'
+ * 'spring.cloud.kubernetes.config.sources[1].explicitPrefix=two'
+ * ("property", "two")
+ *
+ * As such: @ConfigurationProperties("two")
+ *
+ */
+ @Test
+ public void testTwo() {
+ this.webClient.get().uri("/prefix/two").exchange().expectStatus().isOk().expectBody(String.class)
+ .value(Matchers.equalTo("two"));
+ }
+
+ /**
+ *
+ * 'spring.cloud.kubernetes.config.useNameAsPrefix=true'
+ * 'spring.cloud.kubernetes.config.sources[2].name=config-map-three'
+ * ("property", "three")
+ *
+ * As such: @ConfigurationProperties(prefix = "config-map-three")
+ *
+ */
+ @Test
+ public void testThree() {
+ this.webClient.get().uri("/prefix/three").exchange().expectStatus().isOk().expectBody(String.class)
+ .value(Matchers.equalTo("three"));
+ }
+
+}
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 4cc15ebe..47bd1810 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
@@ -63,8 +63,6 @@ class KubernetesClientConfigMapPropertySourceLocatorTests {
+ "logging.level.org.springframework.cloud.kubernetes=TRACE")
.build());
- private static final String API = "/api/v1/namespaces/default/configmaps";
-
private static WireMockServer wireMockServer;
@BeforeAll
@@ -92,7 +90,7 @@ class KubernetesClientConfigMapPropertySourceLocatorTests {
@Test
void locateWithoutSources() {
CoreV1Api api = new CoreV1Api();
- stubFor(get(API)
+ stubFor(get("/api/v1/namespaces/default/configmaps")
.willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(PROPERTIES_CONFIGMAP_LIST))));
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties();
configMapConfigProperties.setName("bootstrap-640");
@@ -107,7 +105,7 @@ class KubernetesClientConfigMapPropertySourceLocatorTests {
@Test
void locateWithSources() {
CoreV1Api api = new CoreV1Api();
- stubFor(get(API)
+ stubFor(get("/api/v1/namespaces/default/configmaps")
.willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(PROPERTIES_CONFIGMAP_LIST))));
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties();
configMapConfigProperties.setName("fake-name");
@@ -135,7 +133,7 @@ class KubernetesClientConfigMapPropertySourceLocatorTests {
@Test
void testLocateWithoutNamespaceDeprecatedConstructor() {
CoreV1Api api = new CoreV1Api();
- stubFor(get(API)
+ stubFor(get("/api/v1/namespaces/default/configmaps")
.willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(PROPERTIES_CONFIGMAP_LIST))));
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties();
configMapConfigProperties.setName("bootstrap-640");
@@ -157,7 +155,7 @@ class KubernetesClientConfigMapPropertySourceLocatorTests {
@Test
void testLocateWithoutNamespace() {
CoreV1Api api = new CoreV1Api();
- stubFor(get(API)
+ stubFor(get("/api/v1/namespaces/default/configmaps")
.willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(PROPERTIES_CONFIGMAP_LIST))));
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties();
configMapConfigProperties.setName("bootstrap-640");
diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapPropertySourceTests.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapPropertySourceTests.java
index 48e04e93..142f5ef0 100644
--- a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapPropertySourceTests.java
+++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapPropertySourceTests.java
@@ -65,8 +65,6 @@ class KubernetesClientConfigMapPropertySourceTests {
"dummy:\n property:\n string2: \"a\"\n int2: 1\n bool2: true\n")
.build());
- private static final String API = "/api/v1/namespaces/default/configmaps";
-
private static WireMockServer wireMockServer;
@BeforeAll
@@ -94,11 +92,11 @@ class KubernetesClientConfigMapPropertySourceTests {
@Test
public void propertiesFile() {
CoreV1Api api = new CoreV1Api();
- stubFor(get(API)
+ stubFor(get("/api/v1/namespaces/default/configmaps")
.willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(PROPERTIES_CONFIGMAP_LIST))));
KubernetesClientConfigMapPropertySource propertySource = new KubernetesClientConfigMapPropertySource(api,
- "bootstrap-640", "default", new MockEnvironment(), "");
- verify(getRequestedFor(urlEqualTo(API)));
+ "bootstrap-640", "default", new MockEnvironment(), "", true);
+ verify(getRequestedFor(urlEqualTo("/api/v1/namespaces/default/configmaps")));
assertThat(propertySource.containsProperty("spring.cloud.kubernetes.configuration.watcher.refreshDelay"))
.isTrue();
assertThat(propertySource.getProperty("spring.cloud.kubernetes.configuration.watcher.refreshDelay"))
@@ -111,10 +109,11 @@ class KubernetesClientConfigMapPropertySourceTests {
@Test
public void yamlFile() {
CoreV1Api api = new CoreV1Api();
- stubFor(get(API).willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(YAML_CONFIGMAP_LIST))));
+ stubFor(get("/api/v1/namespaces/default/configmaps")
+ .willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(YAML_CONFIGMAP_LIST))));
KubernetesClientConfigMapPropertySource propertySource = new KubernetesClientConfigMapPropertySource(api,
- "bootstrap-641", "default", new MockEnvironment(), "");
- verify(getRequestedFor(urlEqualTo(API)));
+ "bootstrap-641", "default", new MockEnvironment(), "", true);
+ verify(getRequestedFor(urlEqualTo("/api/v1/namespaces/default/configmaps")));
assertThat(propertySource.containsProperty("dummy.property.string2")).isTrue();
assertThat(propertySource.getProperty("dummy.property.string2")).isEqualTo("a");
assertThat(propertySource.containsProperty("dummy.property.int2")).isTrue();
@@ -127,11 +126,11 @@ class KubernetesClientConfigMapPropertySourceTests {
@Test
public void propertiesFileWithPrefix() {
CoreV1Api api = new CoreV1Api();
- stubFor(get(API)
+ stubFor(get("/api/v1/namespaces/default/configmaps")
.willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(PROPERTIES_CONFIGMAP_LIST))));
KubernetesClientConfigMapPropertySource propertySource = new KubernetesClientConfigMapPropertySource(api,
- "bootstrap-640", "default", new MockEnvironment(), "prefix");
- verify(getRequestedFor(urlEqualTo(API)));
+ "bootstrap-640", "default", new MockEnvironment(), "prefix", true);
+ verify(getRequestedFor(urlEqualTo("/api/v1/namespaces/default/configmaps")));
assertThat(propertySource.containsProperty("prefix.spring.cloud.kubernetes.configuration.watcher.refreshDelay"))
.isTrue();
assertThat(propertySource.getProperty("prefix.spring.cloud.kubernetes.configuration.watcher.refreshDelay"))
diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/config_map_name_as_prefix/WithPrefixApp.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/config_map_name_as_prefix/WithPrefixApp.java
new file mode 100644
index 00000000..0bdbb15a
--- /dev/null
+++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/config_map_name_as_prefix/WithPrefixApp.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2013-2021 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.kubernetes.client.config.applications.config_map_name_as_prefix;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.cloud.kubernetes.client.config.applications.config_map_name_as_prefix.properties.One;
+import org.springframework.cloud.kubernetes.client.config.applications.config_map_name_as_prefix.properties.Three;
+import org.springframework.cloud.kubernetes.client.config.applications.config_map_name_as_prefix.properties.Two;
+
+@SpringBootApplication
+@EnableConfigurationProperties({ One.class, Two.class, Three.class })
+public class WithPrefixApp {
+
+ public static void main(String[] args) {
+ SpringApplication.run(WithPrefixApp.class, args);
+ }
+
+}
diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/config_map_name_as_prefix/controller/Controller.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/config_map_name_as_prefix/controller/Controller.java
new file mode 100644
index 00000000..e4d65578
--- /dev/null
+++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/config_map_name_as_prefix/controller/Controller.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2013-2020 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.kubernetes.client.config.applications.config_map_name_as_prefix.controller;
+
+import org.springframework.cloud.kubernetes.client.config.applications.config_map_name_as_prefix.properties.One;
+import org.springframework.cloud.kubernetes.client.config.applications.config_map_name_as_prefix.properties.Three;
+import org.springframework.cloud.kubernetes.client.config.applications.config_map_name_as_prefix.properties.Two;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class Controller {
+
+ private final One one;
+
+ private final Two two;
+
+ private final Three three;
+
+ public Controller(One one, Two two, Three three) {
+ this.one = one;
+ this.two = two;
+ this.three = three;
+ }
+
+ @GetMapping("/prefix/one")
+ public String one() {
+ return one.getProperty();
+ }
+
+ @GetMapping("/prefix/two")
+ public String two() {
+ return two.getProperty();
+ }
+
+ @GetMapping("/prefix/three")
+ public String three() {
+ return three.getProperty();
+ }
+
+}
diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/config_map_name_as_prefix/properties/One.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/config_map_name_as_prefix/properties/One.java
new file mode 100644
index 00000000..4a9eb5e4
--- /dev/null
+++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/config_map_name_as_prefix/properties/One.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2013-2021 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.kubernetes.client.config.applications.config_map_name_as_prefix.properties;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@ConfigurationProperties("one")
+public class One {
+
+ private String property;
+
+ public String getProperty() {
+ return property;
+ }
+
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+}
diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/config_map_name_as_prefix/properties/Three.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/config_map_name_as_prefix/properties/Three.java
new file mode 100644
index 00000000..ae83c9a9
--- /dev/null
+++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/config_map_name_as_prefix/properties/Three.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2013-2021 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.kubernetes.client.config.applications.config_map_name_as_prefix.properties;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@ConfigurationProperties(prefix = "config-map-three")
+public class Three {
+
+ private String property;
+
+ public String getProperty() {
+ return property;
+ }
+
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+}
diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/config_map_name_as_prefix/properties/Two.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/config_map_name_as_prefix/properties/Two.java
new file mode 100644
index 00000000..7a3d9d8d
--- /dev/null
+++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/config_map_name_as_prefix/properties/Two.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2013-2021 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.kubernetes.client.config.applications.config_map_name_as_prefix.properties;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@ConfigurationProperties("two")
+public class Two {
+
+ private String property;
+
+ public String getProperty() {
+ return property;
+ }
+
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+}
diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/include_profile_specific_sources/IncludeProfileSpecificSourcesApp.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/include_profile_specific_sources/IncludeProfileSpecificSourcesApp.java
new file mode 100644
index 00000000..d719c422
--- /dev/null
+++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/include_profile_specific_sources/IncludeProfileSpecificSourcesApp.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2013-2021 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.kubernetes.client.config.applications.include_profile_specific_sources;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.cloud.kubernetes.client.config.applications.include_profile_specific_sources.properties.One;
+import org.springframework.cloud.kubernetes.client.config.applications.include_profile_specific_sources.properties.Three;
+import org.springframework.cloud.kubernetes.client.config.applications.include_profile_specific_sources.properties.Two;
+
+@SpringBootApplication
+@EnableConfigurationProperties({ One.class, Two.class, Three.class })
+public class IncludeProfileSpecificSourcesApp {
+
+ public static void main(String[] args) {
+ SpringApplication.run(IncludeProfileSpecificSourcesApp.class, args);
+ }
+
+}
diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/include_profile_specific_sources/controller/IncludeProfileSpecificSourcesController.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/include_profile_specific_sources/controller/IncludeProfileSpecificSourcesController.java
new file mode 100644
index 00000000..fd8e4db0
--- /dev/null
+++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/include_profile_specific_sources/controller/IncludeProfileSpecificSourcesController.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2013-2021 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.kubernetes.client.config.applications.include_profile_specific_sources.controller;
+
+import org.springframework.cloud.kubernetes.client.config.applications.include_profile_specific_sources.properties.One;
+import org.springframework.cloud.kubernetes.client.config.applications.include_profile_specific_sources.properties.Three;
+import org.springframework.cloud.kubernetes.client.config.applications.include_profile_specific_sources.properties.Two;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class IncludeProfileSpecificSourcesController {
+
+ private final One one;
+
+ private final Two two;
+
+ private final Three three;
+
+ public IncludeProfileSpecificSourcesController(One one, Two two, Three three) {
+ this.one = one;
+ this.two = two;
+ this.three = three;
+ }
+
+ @GetMapping("/profile-specific/one")
+ public String one() {
+ return one.getProperty();
+ }
+
+ @GetMapping("/profile-specific/two")
+ public String two() {
+ return two.getProperty();
+ }
+
+ @GetMapping("/profile-specific/three")
+ public String three() {
+ return three.getProperty();
+ }
+
+}
diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/include_profile_specific_sources/properties/One.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/include_profile_specific_sources/properties/One.java
new file mode 100644
index 00000000..1e59b034
--- /dev/null
+++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/include_profile_specific_sources/properties/One.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2013-2021 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.kubernetes.client.config.applications.include_profile_specific_sources.properties;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@ConfigurationProperties("one")
+public class One {
+
+ private String property;
+
+ public String getProperty() {
+ return property;
+ }
+
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+}
diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/include_profile_specific_sources/properties/Three.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/include_profile_specific_sources/properties/Three.java
new file mode 100644
index 00000000..e96da1eb
--- /dev/null
+++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/include_profile_specific_sources/properties/Three.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2013-2021 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.kubernetes.client.config.applications.include_profile_specific_sources.properties;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@ConfigurationProperties("three")
+public class Three {
+
+ private String property;
+
+ public String getProperty() {
+ return property;
+ }
+
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+}
diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/include_profile_specific_sources/properties/Two.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/include_profile_specific_sources/properties/Two.java
new file mode 100644
index 00000000..4dde04d3
--- /dev/null
+++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/applications/include_profile_specific_sources/properties/Two.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2013-2021 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.kubernetes.client.config.applications.include_profile_specific_sources.properties;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@ConfigurationProperties("two")
+public class Two {
+
+ private String property;
+
+ public String getProperty() {
+ return property;
+ }
+
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+}
diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/boostrap/stubs/ConfigMapNameAsPrefixConfigurationStub.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/boostrap/stubs/ConfigMapNameAsPrefixConfigurationStub.java
new file mode 100644
index 00000000..a639d713
--- /dev/null
+++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/boostrap/stubs/ConfigMapNameAsPrefixConfigurationStub.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2013-2020 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.kubernetes.client.config.boostrap.stubs;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import com.github.tomakehurst.wiremock.WireMockServer;
+import com.github.tomakehurst.wiremock.client.WireMock;
+import io.kubernetes.client.openapi.ApiClient;
+import io.kubernetes.client.openapi.JSON;
+import io.kubernetes.client.openapi.models.V1ConfigMap;
+import io.kubernetes.client.openapi.models.V1ConfigMapBuilder;
+import io.kubernetes.client.openapi.models.V1ConfigMapList;
+import io.kubernetes.client.openapi.models.V1ObjectMetaBuilder;
+import io.kubernetes.client.util.ClientBuilder;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+
+import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
+
+/**
+ * A test bootstrap that takes care to initialize ApiClient _before_ our main bootstrap
+ * context; with some stub data already present.
+ *
+ * @author wind57
+ */
+@Order(0)
+@Configuration
+@ConditionalOnProperty("config.map.name.as.prefix.stub")
+public class ConfigMapNameAsPrefixConfigurationStub {
+
+ @Bean
+ public WireMockServer wireMock() {
+ WireMockServer server = new WireMockServer(options().dynamicPort());
+ server.start();
+ WireMock.configureFor("localhost", server.port());
+ return server;
+ }
+
+ @Bean
+ public ApiClient apiClient(WireMockServer wireMockServer) {
+ ApiClient apiClient = new ClientBuilder().setBasePath("http://localhost:" + wireMockServer.port()).build();
+ io.kubernetes.client.openapi.Configuration.setDefaultApiClient(apiClient);
+ apiClient.setDebugging(true);
+ stubData();
+ return apiClient;
+ }
+
+ private void stubData() {
+ V1ConfigMap one = new V1ConfigMapBuilder()
+ .withMetadata(new V1ObjectMetaBuilder().withName("config-map-one").withNamespace("spring-k8s")
+ .withResourceVersion("1").build())
+ .addToData(Collections.singletonMap("one.property", "one")).build();
+
+ V1ConfigMap two = new V1ConfigMapBuilder()
+ .withMetadata(new V1ObjectMetaBuilder().withName("config-map-two").withNamespace("spring-k8s")
+ .withResourceVersion("1").build())
+ .addToData(Collections.singletonMap("property", "two")).build();
+
+ V1ConfigMap three = new V1ConfigMapBuilder()
+ .withMetadata(new V1ObjectMetaBuilder().withName("config-map-three").withNamespace("spring-k8s")
+ .withResourceVersion("1").build())
+ .addToData(Collections.singletonMap("property", "three")).build();
+
+ V1ConfigMapList allConfigMaps = new V1ConfigMapList();
+ allConfigMaps.setItems(Arrays.asList(one, two, three));
+
+ // the actual stub for CoreV1Api calls
+ WireMock.stubFor(WireMock.get("/api/v1/namespaces/spring-k8s/configmaps")
+ .willReturn(WireMock.aResponse().withStatus(200).withBody(new JSON().serialize(allConfigMaps))));
+ }
+
+}
diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/boostrap/stubs/IncludeProfileSpecificSourcesConfigurationStub.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/boostrap/stubs/IncludeProfileSpecificSourcesConfigurationStub.java
new file mode 100644
index 00000000..ee37d971
--- /dev/null
+++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/boostrap/stubs/IncludeProfileSpecificSourcesConfigurationStub.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2013-2020 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.kubernetes.client.config.boostrap.stubs;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import com.github.tomakehurst.wiremock.WireMockServer;
+import com.github.tomakehurst.wiremock.client.WireMock;
+import io.kubernetes.client.openapi.ApiClient;
+import io.kubernetes.client.openapi.JSON;
+import io.kubernetes.client.openapi.models.V1ConfigMap;
+import io.kubernetes.client.openapi.models.V1ConfigMapBuilder;
+import io.kubernetes.client.openapi.models.V1ConfigMapList;
+import io.kubernetes.client.openapi.models.V1ObjectMetaBuilder;
+import io.kubernetes.client.util.ClientBuilder;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+
+import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
+
+/**
+ * A test bootstrap that takes care to initialize ApiClient _before_ our main bootstrap
+ * context; with some stub data already.
+ *
+ * @author wind57
+ */
+@Order(0)
+@Configuration
+@ConditionalOnProperty("include.profile.specific.sources")
+class IncludeProfileSpecificSourcesConfigurationStub {
+
+ @Bean
+ public WireMockServer wireMock() {
+ WireMockServer server = new WireMockServer(options().dynamicPort());
+ server.start();
+ WireMock.configureFor("localhost", server.port());
+ return server;
+ }
+
+ @Bean
+ public ApiClient apiClient(WireMockServer wireMockServer) {
+ ApiClient apiClient = new ClientBuilder().setBasePath("http://localhost:" + wireMockServer.port()).build();
+ io.kubernetes.client.openapi.Configuration.setDefaultApiClient(apiClient);
+ apiClient.setDebugging(true);
+ stubData();
+ return apiClient;
+ }
+
+ private void stubData() {
+ V1ConfigMap one = new V1ConfigMapBuilder()
+ .withMetadata(new V1ObjectMetaBuilder().withName("config-map-one-dev").withNamespace("spring-k8s")
+ .withResourceVersion("1").build())
+ .addToData(Collections.singletonMap("one.property", "one")).build();
+
+ V1ConfigMap two = new V1ConfigMapBuilder()
+ .withMetadata(new V1ObjectMetaBuilder().withName("config-map-two").withNamespace("spring-k8s")
+ .withResourceVersion("1").build())
+ .addToData(Collections.singletonMap("two.property", "two")).build();
+
+ V1ConfigMap twoDev = new V1ConfigMapBuilder()
+ .withMetadata(new V1ObjectMetaBuilder().withName("config-map-two-dev").withNamespace("spring-k8s")
+ .withResourceVersion("1").build())
+ .addToData(Collections.singletonMap("two.property", "twoDev")).build();
+
+ V1ConfigMap three = new V1ConfigMapBuilder()
+ .withMetadata(new V1ObjectMetaBuilder().withName("config-map-three").withNamespace("spring-k8s")
+ .withResourceVersion("1").build())
+ .addToData(Collections.singletonMap("three.property", "three")).build();
+
+ V1ConfigMap threeDev = new V1ConfigMapBuilder()
+ .withMetadata(new V1ObjectMetaBuilder().withName("config-map-three-dev").withNamespace("spring-k8s")
+ .withResourceVersion("1").build())
+ .addToData(Collections.singletonMap("three.property", "threeDev")).build();
+
+ V1ConfigMapList allConfigMaps = new V1ConfigMapList();
+ allConfigMaps.setItems(Arrays.asList(one, two, twoDev, three, threeDev));
+
+ // the actual stub for CoreV1Api calls
+ WireMock.stubFor(WireMock.get("/api/v1/namespaces/spring-k8s/configmaps")
+ .willReturn(WireMock.aResponse().withStatus(200).withBody(new JSON().serialize(allConfigMaps))));
+ }
+
+}
diff --git a/spring-cloud-kubernetes-client-config/src/test/resources/META-INF/spring.factories b/spring-cloud-kubernetes-client-config/src/test/resources/META-INF/spring.factories
new file mode 100644
index 00000000..5d0b2c08
--- /dev/null
+++ b/spring-cloud-kubernetes-client-config/src/test/resources/META-INF/spring.factories
@@ -0,0 +1,3 @@
+org.springframework.cloud.bootstrap.BootstrapConfiguration=\
+org.springframework.cloud.kubernetes.client.config.boostrap.stubs.IncludeProfileSpecificSourcesConfigurationStub, \
+org.springframework.cloud.kubernetes.client.config.boostrap.stubs.ConfigMapNameAsPrefixConfigurationStub
diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/resources/same-key-with-prefix.yaml b/spring-cloud-kubernetes-client-config/src/test/resources/config-map-name-as-prefix.yaml
similarity index 100%
rename from spring-cloud-kubernetes-fabric8-config/src/test/resources/same-key-with-prefix.yaml
rename to spring-cloud-kubernetes-client-config/src/test/resources/config-map-name-as-prefix.yaml
diff --git a/spring-cloud-kubernetes-client-config/src/test/resources/include-profile-specific-sources.yaml b/spring-cloud-kubernetes-client-config/src/test/resources/include-profile-specific-sources.yaml
new file mode 100644
index 00000000..54999aaa
--- /dev/null
+++ b/spring-cloud-kubernetes-client-config/src/test/resources/include-profile-specific-sources.yaml
@@ -0,0 +1,14 @@
+spring:
+ application:
+ name: include-profile-specific-sources
+ cloud:
+ kubernetes:
+ config:
+ includeProfileSpecificSources: false
+ namespace: spring-k8s
+ sources:
+ - name: config-map-one
+ includeProfileSpecificSources: true
+ - name: config-map-two
+ includeProfileSpecificSources: false
+ - name: config-map-three
diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/AbstractConfigProperties.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/AbstractConfigProperties.java
index 4e46486d..4797b789 100644
--- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/AbstractConfigProperties.java
+++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/AbstractConfigProperties.java
@@ -29,8 +29,12 @@ public abstract class AbstractConfigProperties {
protected String namespace;
+ // use config map name to prefix properties
protected boolean useNameAsPrefix;
+ // use profile name to append config map name
+ protected boolean includeProfileSpecificSources = true;
+
public abstract String getConfigurationTarget();
public boolean isEnabled() {
@@ -65,4 +69,11 @@ public abstract class AbstractConfigProperties {
this.useNameAsPrefix = useNameAsPrefix;
}
+ public boolean isIncludeProfileSpecificSources() {
+ return includeProfileSpecificSources;
+ }
+
+ public void setIncludeProfileSpecificSources(boolean includeProfileSpecificSources) {
+ this.includeProfileSpecificSources = includeProfileSpecificSources;
+ }
}
diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/ConfigMapConfigProperties.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/ConfigMapConfigProperties.java
index 52ad6eb8..4c2673a8 100644
--- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/ConfigMapConfigProperties.java
+++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/ConfigMapConfigProperties.java
@@ -82,10 +82,11 @@ public class ConfigMapConfigProperties extends AbstractConfigProperties {
"'spring.cloud.kubernetes.config.useNameAsPrefix' is set to 'true', but 'spring.cloud.kubernetes.config.sources'"
+ " is empty; as such will default 'useNameAsPrefix' to 'false'");
}
- return Collections.singletonList(new NormalizedSource(name, namespace, ""));
+ return Collections.singletonList(new NormalizedSource(name, namespace, "", includeProfileSpecificSources));
}
- return sources.stream().map(s -> s.normalize(name, namespace, useNameAsPrefix)).collect(Collectors.toList());
+ return sources.stream().map(s -> s.normalize(name, namespace, useNameAsPrefix, includeProfileSpecificSources))
+ .collect(Collectors.toList());
}
@Override
@@ -114,6 +115,12 @@ public class ConfigMapConfigProperties extends AbstractConfigProperties {
*/
private Boolean useNameAsPrefix;
+ /**
+ * Use profile name to append to a config map name. Can't be a primitive, we need to
+ * know if it was explicitly set or not
+ */
+ protected Boolean includeProfileSpecificSources;
+
/**
* An explicit prefix to be used for properties.
*/
@@ -160,6 +167,14 @@ public class ConfigMapConfigProperties extends AbstractConfigProperties {
this.explicitPrefix = explicitPrefix;
}
+ public Boolean getIncludeProfileSpecificSources() {
+ return includeProfileSpecificSources;
+ }
+
+ public void setIncludeProfileSpecificSources(Boolean includeProfileSpecificSources) {
+ this.includeProfileSpecificSources = includeProfileSpecificSources;
+ }
+
public boolean isEmpty() {
return !StringUtils.hasLength(this.name) && !StringUtils.hasLength(this.namespace);
}
@@ -169,15 +184,18 @@ public class ConfigMapConfigProperties extends AbstractConfigProperties {
public NormalizedSource normalize(String defaultName, String defaultNamespace) {
String normalizedName = StringUtils.hasLength(this.name) ? this.name : defaultName;
String normalizedNamespace = StringUtils.hasLength(this.namespace) ? this.namespace : defaultNamespace;
- return new NormalizedSource(normalizedName, normalizedNamespace, "");
+ return new NormalizedSource(normalizedName, normalizedNamespace, "", true);
}
- public NormalizedSource normalize(String defaultName, String defaultNamespace, boolean defaultUseNameAsPrefix) {
+ public NormalizedSource normalize(String defaultName, String defaultNamespace, boolean defaultUseNameAsPrefix,
+ boolean defaultIncludeProfileSpecificSources) {
String normalizedName = StringUtils.hasLength(this.name) ? this.name : defaultName;
String normalizedNamespace = StringUtils.hasLength(this.namespace) ? this.namespace : defaultNamespace;
String prefix = ConfigUtils.findPrefix(this.explicitPrefix, useNameAsPrefix, defaultUseNameAsPrefix,
normalizedName);
- return new NormalizedSource(normalizedName, normalizedNamespace, prefix);
+ boolean includeProfileSpecificSources = ConfigUtils.includeProfileSpecificSources(defaultIncludeProfileSpecificSources,
+ this.includeProfileSpecificSources);
+ return new NormalizedSource(normalizedName, normalizedNamespace, prefix, includeProfileSpecificSources);
}
@Override
@@ -207,18 +225,22 @@ public class ConfigMapConfigProperties extends AbstractConfigProperties {
private final String prefix;
+ private final boolean includeProfileSpecificSources;
+
// not used, but not removed because of potential compatibility reasons
@Deprecated
NormalizedSource(String name, String namespace) {
this.name = name;
this.namespace = namespace;
this.prefix = "";
+ this.includeProfileSpecificSources = true;
}
- NormalizedSource(String name, String namespace, String prefix) {
+ NormalizedSource(String name, String namespace, String prefix, boolean includeProfileSpecificSources) {
this.name = name;
this.namespace = namespace;
this.prefix = Objects.requireNonNull(prefix);
+ this.includeProfileSpecificSources = includeProfileSpecificSources;
}
public String getName() {
@@ -233,6 +255,10 @@ public class ConfigMapConfigProperties extends AbstractConfigProperties {
return prefix;
}
+ public boolean isIncludeProfileSpecificSources() {
+ return includeProfileSpecificSources;
+ }
+
@Override
public String toString() {
return "{ config-map name : '" + name + "', namespace : '" + namespace + "', prefix : '" + prefix + "' }";
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 ac92e045..a0e4126d 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
@@ -84,4 +84,19 @@ public final class ConfigUtils {
return "";
}
+ /**
+ * @param defaultIncludeProfileSpecificSources value of
+ * 'spring.cloud.kubernetes.config.includeProfileSpecificSources'
+ * @param includeProfileSpecificSources value of
+ * 'spring.cloud.kubernetes.config.sources.includeProfileSpecificSources'
+ * @return useProfileNameAsPrefix to be used in normalized sources
+ */
+ public static boolean includeProfileSpecificSources(boolean defaultIncludeProfileSpecificSources,
+ Boolean includeProfileSpecificSources) {
+ if (includeProfileSpecificSources != null) {
+ return includeProfileSpecificSources;
+ }
+ return defaultIncludeProfileSpecificSources;
+ }
+
}
diff --git a/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/ConfigMapConfigPropertiesTests.java b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/ConfigMapConfigPropertiesTests.java
index 05406165..4fe06132 100644
--- a/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/ConfigMapConfigPropertiesTests.java
+++ b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/ConfigMapConfigPropertiesTests.java
@@ -218,4 +218,114 @@ public class ConfigMapConfigPropertiesTests {
Assertions.assertEquals(sources.get(3).getPrefix(), "");
}
+ /**
+ *
+ * spring:
+ * cloud:
+ * kubernetes:
+ * config:
+ * name: config-map-a
+ * namespace: spring-k8s
+ *
+ *
+ * a config as above will result in a NormalizedSource where includeProfileSpecificSources
+ * will be true (this test proves that the change we added is not a breaking change
+ * for the already existing functionality)
+ */
+ @Test
+ public void testUseIncludeProfileSpecificSourcesNoChanges() {
+ ConfigMapConfigProperties properties = new ConfigMapConfigProperties();
+ properties.setSources(Collections.emptyList());
+ properties.setName("config-map-a");
+ properties.setNamespace("spring-k8s");
+
+ List sources = properties.determineSources();
+ Assertions.assertEquals(sources.size(), 1, "empty sources must generate a List with a single NormalizedSource");
+
+ Assertions.assertTrue(sources.get(0).isIncludeProfileSpecificSources());
+ }
+
+ /**
+ *
+ * spring:
+ * cloud:
+ * kubernetes:
+ * config:
+ * includeProfileSpecificSources: false
+ * name: config-map-a
+ * namespace: spring-k8s
+ *
+ *
+ * a config as above will result in a NormalizedSource where includeProfileSpecificSources
+ * will be false. Even if we did not define any sources explicitly, one will still be
+ * created, by default. That one might "flatMap" into multiple other, because of
+ * multiple profiles. As such this setting still matters and must be propagated to the
+ * normalized source.
+ */
+ @Test
+ public void testUseIncludeProfileSpecificSourcesDefaultChanged() {
+ ConfigMapConfigProperties properties = new ConfigMapConfigProperties();
+ properties.setSources(Collections.emptyList());
+ properties.setName("config-map-a");
+ properties.setNamespace("spring-k8s");
+ properties.setIncludeProfileSpecificSources(false);
+
+ List sources = properties.determineSources();
+ Assertions.assertEquals(sources.size(), 1, "empty sources must generate a List with a single NormalizedSource");
+
+ Assertions.assertFalse(sources.get(0).isIncludeProfileSpecificSources());
+ }
+
+ /**
+ *
+ * spring:
+ * cloud:
+ * kubernetes:
+ * config:
+ * includeProfileSpecificSources: false
+ * name: config-map-a
+ * namespace: spring-k8s
+ * sources:
+ * - name: one
+ * includeProfileSpecificSources: true
+ * - name: two
+ * - name: three
+ * includeProfileSpecificSources: false
+ *
+ *
+ *
+ * source "one" will have "includeProfileSpecificSources = true".
+ * source "two" will have "includeProfileSpecificSources = false".
+ * source "three" will have "includeProfileSpecificSources = false".
+ *
+ */
+ @Test
+ public void testUseIncludeProfileSpecificSourcesDefaultChangedSourceOverride() {
+ ConfigMapConfigProperties properties = new ConfigMapConfigProperties();
+ properties.setSources(Collections.emptyList());
+ properties.setName("config-map-a");
+ properties.setNamespace("spring-k8s");
+ properties.setIncludeProfileSpecificSources(false);
+
+ ConfigMapConfigProperties.Source one = new ConfigMapConfigProperties.Source();
+ one.setName("config-map-one");
+ one.setIncludeProfileSpecificSources(true);
+
+ ConfigMapConfigProperties.Source two = new ConfigMapConfigProperties.Source();
+ two.setName("config-map-two");
+
+ ConfigMapConfigProperties.Source three = new ConfigMapConfigProperties.Source();
+ three.setName("config-map-three");
+ three.setIncludeProfileSpecificSources(false);
+
+ properties.setSources(Arrays.asList(one, two, three));
+
+ List sources = properties.determineSources();
+ Assertions.assertEquals(sources.size(), 3);
+
+ Assertions.assertTrue(sources.get(0).isIncludeProfileSpecificSources());
+ Assertions.assertFalse(sources.get(1).isIncludeProfileSpecificSources());
+ Assertions.assertFalse(sources.get(2).isIncludeProfileSpecificSources());
+ }
+
}
diff --git a/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/ConfigUtilsTests.java b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/ConfigUtilsTests.java
index d513737d..5bed6bfe 100644
--- a/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/ConfigUtilsTests.java
+++ b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/ConfigUtilsTests.java
@@ -54,4 +54,55 @@ public class ConfigUtilsTests {
Assertions.assertEquals(result, "");
}
+ /**
+ *
+ * spring:
+ * cloud:
+ * kubernetes:
+ * config:
+ * includeProfileSpecificSources: true
+ *
+ *
+ * above will generate "true" for a normalized source
+ */
+ @Test
+ public void testUseIncludeProfileSpecificSourcesOnlyDefaultSet() {
+ Assertions.assertTrue(ConfigUtils.includeProfileSpecificSources(true, null));
+ }
+
+ /**
+ *
+ * spring:
+ * cloud:
+ * kubernetes:
+ * config:
+ * includeProfileSpecificSources: true
+ *
+ *
+ * above will generate "false" for a normalized source
+ */
+ @Test
+ public void testUseIncludeProfileSpecificSourcesOnlyDefaultNotSet() {
+ Assertions.assertFalse(ConfigUtils.includeProfileSpecificSources(false, null));
+ }
+
+ /**
+ *
+ * spring:
+ * cloud:
+ * kubernetes:
+ * config:
+ * includeProfileSpecificSources: true
+ * sources:
+ * - name: one
+ * includeProfileSpecificSources: false
+ *
+ *
+ * above will generate "false" for a normalized source
+ */
+ @Test
+ public void testUseIncludeProfileSpecificSourcesSourcesOverridesDefault() {
+ Assertions.assertFalse(ConfigUtils.includeProfileSpecificSources(true, false));
+ }
+
}
diff --git a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySource.java b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySource.java
index e53962b9..95629245 100644
--- a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySource.java
+++ b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySource.java
@@ -44,7 +44,7 @@ public class Fabric8ConfigMapPropertySource extends ConfigMapPropertySource {
private static final Log LOG = LogFactory.getLog(Fabric8ConfigMapPropertySource.class);
public Fabric8ConfigMapPropertySource(KubernetesClient client, String name) {
- this(client, name, null, null, "");
+ this(client, name, null, null, "", true);
}
/**
@@ -52,27 +52,27 @@ public class Fabric8ConfigMapPropertySource extends ConfigMapPropertySource {
* discouraged.
*/
@Deprecated
- public Fabric8ConfigMapPropertySource(KubernetesClient client, String applicationName, String namespace,
+ public Fabric8ConfigMapPropertySource(KubernetesClient client, String name, String namespace,
Environment environment) {
- super(getName(applicationName, getApplicationNamespace(client, namespace)),
- getData(client, applicationName, getApplicationNamespace(client, namespace), environment, ""));
+ super(getName(name, getApplicationNamespace(client, namespace)),
+ getData(client, name, getApplicationNamespace(client, namespace), environment, "", true));
}
- public Fabric8ConfigMapPropertySource(KubernetesClient client, String applicationName, String namespace,
- Environment environment, String prefix) {
- super(getName(applicationName, getApplicationNamespace(client, namespace)),
- getData(client, applicationName, getApplicationNamespace(client, namespace), environment, prefix));
+ public Fabric8ConfigMapPropertySource(KubernetesClient client, String name, String namespace,
+ Environment environment, String prefix, boolean includeProfileSpecificSources) {
+ super(getName(name, getApplicationNamespace(client, namespace)), getData(client, name,
+ getApplicationNamespace(client, namespace), environment, prefix, includeProfileSpecificSources));
}
- private static Map getData(KubernetesClient client, String applicationName, String namespace,
- Environment environment, String prefix) {
+ private static Map getData(KubernetesClient client, String name, String namespace,
+ Environment environment, String prefix, boolean includeProfileSpecificSources) {
try {
- Map data = getConfigMapData(client, namespace, applicationName);
+ Map data = getConfigMapData(client, namespace, name);
Map result = new HashMap<>(processAllEntries(data, environment));
- if (environment != null) {
+ if (environment != null && includeProfileSpecificSources) {
for (String activeProfile : environment.getActiveProfiles()) {
- String mapNameWithProfile = applicationName + "-" + activeProfile;
+ String mapNameWithProfile = name + "-" + activeProfile;
Map dataWithProfile = getConfigMapData(client, namespace, mapNameWithProfile);
result.putAll(processAllEntries(dataWithProfile, environment));
}
@@ -88,8 +88,7 @@ public class Fabric8ConfigMapPropertySource extends ConfigMapPropertySource {
}
catch (Exception e) {
- LOG.warn("Can't read configMap with name: [" + applicationName + "] in namespace: [" + namespace
- + "]. Ignoring.", e);
+ LOG.warn("Can't read configMap with name: [" + name + "] in namespace: [" + namespace + "]. Ignoring.", e);
}
return Collections.emptyMap();
diff --git a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySourceLocator.java b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySourceLocator.java
index 344f272a..f9614e84 100644
--- a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySourceLocator.java
+++ b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySourceLocator.java
@@ -69,7 +69,7 @@ public class Fabric8ConfigMapPropertySourceLocator extends ConfigMapPropertySour
String namespace = getApplicationNamespace(this.client, normalizedSource.getNamespace(), configurationTarget,
provider);
return new Fabric8ConfigMapPropertySource(this.client, applicationName, namespace, environment,
- normalizedSource.getPrefix());
+ normalizedSource.getPrefix(), normalizedSource.isIncludeProfileSpecificSources());
}
}
diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/ConfigMapWithIncludeProfileSpecificSourcesTests.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/ConfigMapWithIncludeProfileSpecificSourcesTests.java
new file mode 100644
index 00000000..7d1a7021
--- /dev/null
+++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/ConfigMapWithIncludeProfileSpecificSourcesTests.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2013-2021 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.kubernetes.fabric8.config;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import io.fabric8.kubernetes.client.Config;
+import io.fabric8.kubernetes.client.KubernetesClient;
+import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
+import org.hamcrest.Matchers;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.cloud.kubernetes.fabric8.config.include_profile_specific_sources.IncludeProfileSpecificSourcesApp;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.test.web.reactive.server.WebTestClient;
+
+/**
+ * @author wind57
+ */
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = IncludeProfileSpecificSourcesApp.class,
+ properties = { "spring.cloud.bootstrap.name=include-profile-specific-sources" })
+@AutoConfigureWebTestClient
+@EnableKubernetesMockClient(crud = true, https = false)
+@ActiveProfiles("dev")
+class ConfigMapWithIncludeProfileSpecificSourcesTests {
+
+ private static KubernetesClient mockClient;
+
+ @Autowired
+ private WebTestClient webClient;
+
+ @BeforeAll
+ public static void setUpBeforeClass() {
+
+ // Configure the kubernetes master url to point to the mock server
+ System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl());
+ System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true");
+ System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false");
+ System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false");
+ System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "test");
+ System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true");
+
+ Map one = new HashMap<>();
+ one.put("one.property", "one");
+ createConfigmap("config-map-one-dev", one);
+
+ Map two = new HashMap<>();
+ two.put("two.property", "two");
+ createConfigmap("config-map-two", two);
+
+ Map twoDev = new HashMap<>();
+ twoDev.put("two.property", "twoDev");
+ createConfigmap("config-map-two-dev", twoDev);
+
+ Map three = new HashMap<>();
+ three.put("three.property", "three");
+ createConfigmap("config-map-three", three);
+
+ Map threeDev = new HashMap<>();
+ threeDev.put("three.property", "threeDev");
+ createConfigmap("config-map-three-dev", threeDev);
+
+ }
+
+ private static void createConfigmap(String name, Map data) {
+ mockClient.configMaps().inNamespace("spring-k8s").createNew().withNewMetadata().withName(name).endMetadata()
+ .addToData(data).done();
+ }
+
+ /**
+ *
+ * 'spring.cloud.kubernetes.config.includeProfileSpecificSources=false'
+ * 'spring.cloud.kubernetes.config.sources[0].includeProfileSpecificSources=true'
+ * 'spring.cloud.kubernetes.config.sources[0].name=config-map-one'
+ *
+ * We do not define config-map 'config-map-one', but we do define 'config-map-one-dev'.
+ *
+ * As such: @ConfigurationProperties("one") must be resolved from 'config-map-one-dev'
+ *
+ */
+ @Test
+ public void testOne() {
+ this.webClient.get().uri("/profile-specific/one").exchange().expectStatus().isOk().expectBody(String.class)
+ .value(Matchers.equalTo("one"));
+ }
+
+ /**
+ *
+ * 'spring.cloud.kubernetes.config.includeProfileSpecificSources=false'
+ * 'spring.cloud.kubernetes.config.sources[1].includeProfileSpecificSources=false'
+ * 'spring.cloud.kubernetes.config.sources[1].name=config-map-two'
+ *
+ * We define config-map 'config-map-two', but we also define 'config-map-two-dev'.
+ * This tests proves that data will be read from 'config-map-two' _only_, even if 'config-map-two-dev'
+ * also exists. This happens because of the 'includeProfileSpecificSources=false' property defined at the source level.
+ * If this would be incorrect, the value we read from '/profile-specific/two' would have been 'twoDev' and _not_ 'two',
+ * simply because 'config-map-two-dev' would override the property value.
+ *
+ * As such: @ConfigurationProperties("two") must be resolved from 'config-map-two'
+ *
+ */
+ @Test
+ public void testTwo() {
+ this.webClient.get().uri("/profile-specific/two").exchange().expectStatus().isOk().expectBody(String.class)
+ .value(Matchers.equalTo("two"));
+ }
+
+ /**
+ *
+ * 'spring.cloud.kubernetes.config.includeProfileSpecificSources=false'
+ * 'spring.cloud.kubernetes.config.sources[2].name=config-map-three'
+ *
+ * We define config-map 'config-map-three', but we also define 'config-map-three-dev'.
+ * This tests proves that data will be read from 'config-map-three' _only_, even if 'config-map-three-dev'
+ * also exists. This happens because the 'includeProfileSpecificSources' property is not defined at the source level,
+ * but it is defaulted from the root level, where we set it to false.
+ * If this would be incorrect, the value we read from '/profile-specific/three' would have been 'threeDev' and _not_ 'three',
+ * simply because 'config-map-three-dev' would override the property value.
+ *
+ * As such: @ConfigurationProperties("three") must be resolved from 'config-map-three'
+ *
+ */
+ @Test
+ public void testThree() {
+ this.webClient.get().uri("/profile-specific/three").exchange().expectStatus().isOk().expectBody(String.class)
+ .value(Matchers.equalTo("three"));
+ }
+
+}
diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/ConfigMapWithPrefixTests.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/ConfigMapWithPrefixTests.java
index 934034f3..e232034e 100644
--- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/ConfigMapWithPrefixTests.java
+++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/ConfigMapWithPrefixTests.java
@@ -39,10 +39,10 @@ import org.springframework.test.web.reactive.server.WebTestClient;
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = WithPrefixApp.class,
- properties = { "spring.cloud.bootstrap.name=same-key-with-prefix" })
+ properties = { "spring.cloud.bootstrap.name=config-map-name-as-prefix" })
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
-public class ConfigMapWithPrefixTests {
+class ConfigMapWithPrefixTests {
private static KubernetesClient mockClient;
@@ -62,21 +62,20 @@ public class ConfigMapWithPrefixTests {
Map one = new HashMap<>();
one.put("one.property", "one");
- createConfigmap(mockClient, "config-map-one", one);
+ createConfigmap("config-map-one", one);
Map two = new HashMap<>();
two.put("property", "two");
- createConfigmap(mockClient, "config-map-two", two);
+ createConfigmap("config-map-two", two);
Map three = new HashMap<>();
three.put("property", "three");
- createConfigmap(mockClient, "config-map-three", three);
+ createConfigmap("config-map-three", three);
}
- private static void createConfigmap(KubernetesClient client, String name, Map data) {
-
- client.configMaps().inNamespace("spring-k8s").createNew().withNewMetadata().withName(name).endMetadata()
+ private static void createConfigmap(String name, Map data) {
+ mockClient.configMaps().inNamespace("spring-k8s").createNew().withNewMetadata().withName(name).endMetadata()
.addToData(data).done();
}
@@ -91,7 +90,7 @@ public class ConfigMapWithPrefixTests {
*/
@Test
public void testOne() {
- this.webClient.get().uri("/one").exchange().expectStatus().isOk().expectBody(String.class)
+ this.webClient.get().uri("/prefix/one").exchange().expectStatus().isOk().expectBody(String.class)
.value(Matchers.equalTo("one"));
}
@@ -106,7 +105,7 @@ public class ConfigMapWithPrefixTests {
*/
@Test
public void testTwo() {
- this.webClient.get().uri("/two").exchange().expectStatus().isOk().expectBody(String.class)
+ this.webClient.get().uri("/prefix/two").exchange().expectStatus().isOk().expectBody(String.class)
.value(Matchers.equalTo("two"));
}
@@ -121,7 +120,7 @@ public class ConfigMapWithPrefixTests {
*/
@Test
public void testThree() {
- this.webClient.get().uri("/three").exchange().expectStatus().isOk().expectBody(String.class)
+ this.webClient.get().uri("/prefix/three").exchange().expectStatus().isOk().expectBody(String.class)
.value(Matchers.equalTo("three"));
}
diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/include_profile_specific_sources/IncludeProfileSpecificSourcesApp.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/include_profile_specific_sources/IncludeProfileSpecificSourcesApp.java
new file mode 100644
index 00000000..992de0d8
--- /dev/null
+++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/include_profile_specific_sources/IncludeProfileSpecificSourcesApp.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2013-2021 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.kubernetes.fabric8.config.include_profile_specific_sources;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.cloud.kubernetes.fabric8.config.include_profile_specific_sources.properties.One;
+import org.springframework.cloud.kubernetes.fabric8.config.include_profile_specific_sources.properties.Three;
+import org.springframework.cloud.kubernetes.fabric8.config.include_profile_specific_sources.properties.Two;
+
+@SpringBootApplication
+@EnableConfigurationProperties({ One.class, Two.class, Three.class })
+public class IncludeProfileSpecificSourcesApp {
+
+ public static void main(String[] args) {
+ SpringApplication.run(IncludeProfileSpecificSourcesApp.class, args);
+ }
+
+}
diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/include_profile_specific_sources/controller/IncludeProfileSpecificSourcesController.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/include_profile_specific_sources/controller/IncludeProfileSpecificSourcesController.java
new file mode 100644
index 00000000..e6aa453c
--- /dev/null
+++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/include_profile_specific_sources/controller/IncludeProfileSpecificSourcesController.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2013-2021 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.kubernetes.fabric8.config.include_profile_specific_sources.controller;
+
+import org.springframework.cloud.kubernetes.fabric8.config.include_profile_specific_sources.properties.One;
+import org.springframework.cloud.kubernetes.fabric8.config.include_profile_specific_sources.properties.Three;
+import org.springframework.cloud.kubernetes.fabric8.config.include_profile_specific_sources.properties.Two;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class IncludeProfileSpecificSourcesController {
+
+ private final One one;
+
+ private final Two two;
+
+ private final Three three;
+
+ public IncludeProfileSpecificSourcesController(One one, Two two, Three three) {
+ this.one = one;
+ this.two = two;
+ this.three = three;
+ }
+
+ @GetMapping("/profile-specific/one")
+ public String one() {
+ return one.getProperty();
+ }
+
+ @GetMapping("/profile-specific/two")
+ public String two() {
+ return two.getProperty();
+ }
+
+ @GetMapping("/profile-specific/three")
+ public String three() {
+ return three.getProperty();
+ }
+
+}
diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/include_profile_specific_sources/properties/One.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/include_profile_specific_sources/properties/One.java
new file mode 100644
index 00000000..af88a5c0
--- /dev/null
+++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/include_profile_specific_sources/properties/One.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2013-2021 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.kubernetes.fabric8.config.include_profile_specific_sources.properties;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@ConfigurationProperties("one")
+public class One {
+
+ private String property;
+
+ public String getProperty() {
+ return property;
+ }
+
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+}
diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/include_profile_specific_sources/properties/Three.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/include_profile_specific_sources/properties/Three.java
new file mode 100644
index 00000000..239f4374
--- /dev/null
+++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/include_profile_specific_sources/properties/Three.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2013-2021 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.kubernetes.fabric8.config.include_profile_specific_sources.properties;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@ConfigurationProperties("three")
+public class Three {
+
+ private String property;
+
+ public String getProperty() {
+ return property;
+ }
+
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+}
diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/include_profile_specific_sources/properties/Two.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/include_profile_specific_sources/properties/Two.java
new file mode 100644
index 00000000..c14b1b0f
--- /dev/null
+++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/include_profile_specific_sources/properties/Two.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2013-2021 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.kubernetes.fabric8.config.include_profile_specific_sources.properties;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@ConfigurationProperties("two")
+public class Two {
+
+ private String property;
+
+ public String getProperty() {
+ return property;
+ }
+
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+}
diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/with_prefix/controller/Controller.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/with_prefix/controller/Controller.java
index 86886d10..adbed9f9 100644
--- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/with_prefix/controller/Controller.java
+++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/with_prefix/controller/Controller.java
@@ -37,17 +37,17 @@ public class Controller {
this.three = three;
}
- @GetMapping("/one")
+ @GetMapping("/prefix/one")
public String one() {
return one.getProperty();
}
- @GetMapping("/two")
+ @GetMapping("/prefix/two")
public String two() {
return two.getProperty();
}
- @GetMapping("/three")
+ @GetMapping("/prefix/three")
public String three() {
return three.getProperty();
}
diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/resources/config-map-name-as-prefix.yaml b/spring-cloud-kubernetes-fabric8-config/src/test/resources/config-map-name-as-prefix.yaml
new file mode 100644
index 00000000..b52095e4
--- /dev/null
+++ b/spring-cloud-kubernetes-fabric8-config/src/test/resources/config-map-name-as-prefix.yaml
@@ -0,0 +1,14 @@
+spring:
+ application:
+ name: with-prefix
+ cloud:
+ kubernetes:
+ config:
+ useNameAsPrefix: true
+ namespace: spring-k8s
+ sources:
+ - name: config-map-one
+ useNameAsPrefix: false
+ - name: config-map-two
+ explicitPrefix: two
+ - name: config-map-three
diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/resources/include-profile-specific-sources.yaml b/spring-cloud-kubernetes-fabric8-config/src/test/resources/include-profile-specific-sources.yaml
new file mode 100644
index 00000000..54999aaa
--- /dev/null
+++ b/spring-cloud-kubernetes-fabric8-config/src/test/resources/include-profile-specific-sources.yaml
@@ -0,0 +1,14 @@
+spring:
+ application:
+ name: include-profile-specific-sources
+ cloud:
+ kubernetes:
+ config:
+ includeProfileSpecificSources: false
+ namespace: spring-k8s
+ sources:
+ - name: config-map-one
+ includeProfileSpecificSources: true
+ - name: config-map-two
+ includeProfileSpecificSources: false
+ - name: config-map-three