Merge remote-tracking branch 'origin/1.0.x'
This commit is contained in:
@@ -182,6 +182,59 @@ However, if the `production` profile is active, the configuration becomes:
|
||||
|
||||
If both profiles are active, the property that appears last within the `ConfigMap` overwrites any preceding values.
|
||||
|
||||
Another option is to create a different config map per profile and spring boot will automatically fetch it based
|
||||
on active profiles
|
||||
|
||||
====
|
||||
[source,yaml]
|
||||
----
|
||||
kind: ConfigMap
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: demo
|
||||
data:
|
||||
application.yml: |-
|
||||
greeting:
|
||||
message: Say Hello to the World
|
||||
farewell:
|
||||
message: Say Goodbye
|
||||
----
|
||||
====
|
||||
====
|
||||
[source,yaml]
|
||||
----
|
||||
kind: ConfigMap
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: demo-development
|
||||
data:
|
||||
application.yml: |-
|
||||
spring:
|
||||
profiles: development
|
||||
greeting:
|
||||
message: Say Hello to the Developers
|
||||
farewell:
|
||||
message: Say Goodbye to the Developers
|
||||
----
|
||||
====
|
||||
====
|
||||
[source,yaml]
|
||||
----
|
||||
kind: ConfigMap
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: demo-production
|
||||
data:
|
||||
application.yml: |-
|
||||
spring:
|
||||
profiles: production
|
||||
greeting:
|
||||
message: Say Hello to the Ops
|
||||
farewell:
|
||||
message: Say Goodbye
|
||||
----
|
||||
====
|
||||
|
||||
|
||||
To tell Spring Boot which `profile` should be enabled at bootstrap, you can pass `SPRING_PROFILES_ACTIVE` environment variable.
|
||||
To do so, you can launch your Spring Boot application with an environment variable that you can define it in the PodSpec at the container specification.
|
||||
|
||||
@@ -40,6 +40,7 @@ import static org.springframework.cloud.kubernetes.config.PropertySourceUtils.ya
|
||||
* A {@link MapPropertySource} that uses Kubernetes config maps.
|
||||
*
|
||||
* @author Ioannis Canellos
|
||||
* @author Ali Shahbour
|
||||
*/
|
||||
public class ConfigMapPropertySource extends MapPropertySource {
|
||||
|
||||
@@ -59,7 +60,7 @@ public class ConfigMapPropertySource extends MapPropertySource {
|
||||
|
||||
public ConfigMapPropertySource(KubernetesClient client, String name, String namespace,
|
||||
String[] profiles) {
|
||||
this(client, name, null, createEnvironmentWithActiveProfiles(profiles));
|
||||
this(client, name, namespace, createEnvironmentWithActiveProfiles(profiles));
|
||||
}
|
||||
|
||||
private static Environment createEnvironmentWithActiveProfiles(
|
||||
@@ -88,13 +89,33 @@ public class ConfigMapPropertySource extends MapPropertySource {
|
||||
private static Map<String, String> getData(KubernetesClient client, String name,
|
||||
String namespace, Environment environment) {
|
||||
try {
|
||||
Map<String, String> result = new HashMap<>();
|
||||
ConfigMap map = StringUtils.isEmpty(namespace)
|
||||
? client.configMaps().withName(name).get()
|
||||
: client.configMaps().inNamespace(namespace).withName(name).get();
|
||||
|
||||
if (map != null) {
|
||||
return processAllEntries(map.getData(), environment);
|
||||
result.putAll(processAllEntries(map.getData(), environment));
|
||||
}
|
||||
|
||||
if (environment != null) {
|
||||
for (String activeProfile:environment.getActiveProfiles()) {
|
||||
|
||||
String mapNameWithProfile = name + "-" + activeProfile;
|
||||
|
||||
ConfigMap mapWithProfile = StringUtils.isEmpty(namespace)
|
||||
? client.configMaps().withName(mapNameWithProfile).get()
|
||||
: client.configMaps().inNamespace(namespace).withName(mapNameWithProfile).get();
|
||||
|
||||
if (mapWithProfile != null) {
|
||||
result.putAll(processAllEntries(mapWithProfile.getData(), environment));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.warn("Can't read configMap with name: [" + name + "] in namespace:["
|
||||
@@ -104,6 +125,7 @@ public class ConfigMapPropertySource extends MapPropertySource {
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
|
||||
private static Map<String, String> processAllEntries(Map<String, String> input,
|
||||
Environment environment) {
|
||||
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2013-2019 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
|
||||
*
|
||||
* http://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.config;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
|
||||
import io.fabric8.kubernetes.client.Config;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import io.fabric8.kubernetes.client.server.mock.KubernetesServer;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
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.config.example.App;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
|
||||
import static org.springframework.cloud.kubernetes.config.ConfigMapTestUtil.readResourceFile;
|
||||
|
||||
/**
|
||||
* @author Ali Shahbour
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class, properties = {
|
||||
"spring.application.name=configmap-with-active-profile-name-example",
|
||||
"spring.cloud.kubernetes.reload.enabled=false" })
|
||||
@ActiveProfiles("development")
|
||||
@AutoConfigureWebTestClient
|
||||
public class ConfigMapsWithActiveProfilesNameSpringBootTest {
|
||||
|
||||
private static final String APPLICATION_NAME = "configmap-with-active-profile-name-example";
|
||||
|
||||
@ClassRule
|
||||
public static KubernetesServer server = new KubernetesServer();
|
||||
|
||||
private static KubernetesClient mockClient;
|
||||
|
||||
@Autowired(required = false)
|
||||
Config config;
|
||||
|
||||
@Autowired
|
||||
private WebTestClient webClient;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpBeforeClass() {
|
||||
mockClient = server.getClient();
|
||||
|
||||
// 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");
|
||||
|
||||
HashMap<String, String> data = new HashMap<>();
|
||||
data.put("application.yml", readResourceFile("application-with-profiles.yaml"));
|
||||
server.expect().withPath("/api/v1/namespaces/test/configmaps/" + APPLICATION_NAME)
|
||||
.andReturn(200, new ConfigMapBuilder().withNewMetadata()
|
||||
.withName(APPLICATION_NAME).endMetadata().addToData(data).build())
|
||||
.always();
|
||||
|
||||
HashMap<String, String> dataWithName = new HashMap<>();
|
||||
dataWithName.put("application.yml",
|
||||
readResourceFile("application-with-active-profiles-name.yaml"));
|
||||
server.expect()
|
||||
.withPath("/api/v1/namespaces/test/configmaps/" + APPLICATION_NAME
|
||||
+ "-development")
|
||||
.andReturn(200,
|
||||
new ConfigMapBuilder().withNewMetadata()
|
||||
.withName(APPLICATION_NAME + "-development").endMetadata()
|
||||
.addToData(dataWithName).build())
|
||||
.always();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGreetingEndpoint() {
|
||||
this.webClient.get().uri("/api/greeting").exchange().expectStatus().isOk()
|
||||
.expectBody().jsonPath("content")
|
||||
.isEqualTo("Hello ConfigMap Active Profile Name, World!");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFarewellEndpoint() {
|
||||
this.webClient.get().uri("/api/farewell").exchange().expectStatus().isOk()
|
||||
.expectBody().jsonPath("content")
|
||||
.isEqualTo("Goodbye ConfigMap default, World!");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
spring:
|
||||
profiles: development
|
||||
bean:
|
||||
greeting: "Hello ConfigMap Active Profile Name, %s!"
|
||||
Reference in New Issue
Block a user