diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigMapPropertySource.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigMapPropertySource.java index c0442e4a..4d561dbd 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigMapPropertySource.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigMapPropertySource.java @@ -16,7 +16,7 @@ package org.springframework.cloud.kubernetes.config; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; @@ -34,6 +34,7 @@ import org.springframework.util.StringUtils; import static org.springframework.cloud.kubernetes.config.PropertySourceUtils.KEY_VALUE_TO_PROPERTIES; import static org.springframework.cloud.kubernetes.config.PropertySourceUtils.PROPERTIES_TO_MAP; +import static org.springframework.cloud.kubernetes.config.PropertySourceUtils.throwingMerger; import static org.springframework.cloud.kubernetes.config.PropertySourceUtils.yamlParserGenerator; /** @@ -41,6 +42,7 @@ import static org.springframework.cloud.kubernetes.config.PropertySourceUtils.ya * * @author Ioannis Canellos * @author Ali Shahbour + * @author Michael Moudatsos */ public class ConfigMapPropertySource extends MapPropertySource { @@ -86,10 +88,10 @@ public class ConfigMapPropertySource extends MapPropertySource { .toString(); } - private static Map getData(KubernetesClient client, String name, + private static Map getData(KubernetesClient client, String name, String namespace, Environment environment) { try { - Map result = new HashMap<>(); + Map result = new LinkedHashMap<>(); ConfigMap map = StringUtils.isEmpty(namespace) ? client.configMaps().withName(name).get() : client.configMaps().inNamespace(namespace).withName(name).get(); @@ -124,10 +126,10 @@ public class ConfigMapPropertySource extends MapPropertySource { + namespace + "]. Ignoring.", e); } - return new HashMap<>(); + return new LinkedHashMap<>(); } - private static Map processAllEntries(Map input, + private static Map processAllEntries(Map input, Environment environment) { Set> entrySet = input.entrySet(); @@ -163,16 +165,17 @@ public class ConfigMapPropertySource extends MapPropertySource { return defaultProcessAllEntries(input, environment); } - private static Map defaultProcessAllEntries(Map input, + private static Map defaultProcessAllEntries(Map input, Environment environment) { return input.entrySet().stream() .map(e -> extractProperties(e.getKey(), e.getValue(), environment)) .filter(m -> !m.isEmpty()).flatMap(m -> m.entrySet().stream()) - .collect(Collectors.toMap(Entry::getKey, Entry::getValue)); + .collect(Collectors.toMap(Entry::getKey, Entry::getValue, + throwingMerger(), LinkedHashMap::new)); } - private static Map extractProperties(String resourceName, + private static Map extractProperties(String resourceName, String content, Environment environment) { if (resourceName.equals(APPLICATION_YAML) @@ -184,16 +187,16 @@ public class ConfigMapPropertySource extends MapPropertySource { return KEY_VALUE_TO_PROPERTIES.andThen(PROPERTIES_TO_MAP).apply(content); } - return new HashMap() { + return new LinkedHashMap() { { put(resourceName, content); } }; } - private static Map asObjectMap(Map source) { - return source.entrySet().stream() - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + private static Map asObjectMap(Map source) { + return source.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, + Map.Entry::getValue, throwingMerger(), LinkedHashMap::new)); } } diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigMapPropertySourceLocator.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigMapPropertySourceLocator.java index 205998b4..39116614 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigMapPropertySourceLocator.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/ConfigMapPropertySourceLocator.java @@ -47,6 +47,7 @@ import static org.springframework.cloud.kubernetes.config.PropertySourceUtils.ya * A {@link PropertySourceLocator} that uses config maps. * * @author Ioannis Canellos + * @author Michael Moudatsos */ @Order(0) public class ConfigMapPropertySourceLocator implements PropertySourceLocator { @@ -133,7 +134,7 @@ public class ConfigMapPropertySourceLocator implements PropertySourceLocator { } private void addPropertySourceIfNeeded( - Function> contentToMapFunction, String content, + Function> contentToMapFunction, String content, String name, CompositePropertySource composite) { Map map = new HashMap<>(); diff --git a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/PropertySourceUtils.java b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/PropertySourceUtils.java index 39f7bb15..b89294dd 100644 --- a/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/PropertySourceUtils.java +++ b/spring-cloud-kubernetes-config/src/main/java/org/springframework/cloud/kubernetes/config/PropertySourceUtils.java @@ -20,6 +20,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.Map; import java.util.Properties; +import java.util.function.BinaryOperator; import java.util.function.Function; import java.util.stream.Collectors; @@ -37,6 +38,7 @@ import static org.springframework.beans.factory.config.YamlProcessor.MatchStatus * Utility class to work with property sources. * * @author Georgios Andrianakis + * @author Michael Moudatsos */ public final class PropertySourceUtils { @@ -50,9 +52,9 @@ public final class PropertySourceUtils { throw new IllegalArgumentException(); } }; - static final Function> PROPERTIES_TO_MAP = p -> p + static final Function> PROPERTIES_TO_MAP = p -> p .entrySet().stream().collect(Collectors.toMap(e -> String.valueOf(e.getKey()), - e -> String.valueOf(e.getValue()))); + Map.Entry::getValue, throwingMerger(), java.util.LinkedHashMap::new)); private PropertySourceUtils() { throw new IllegalStateException("Can't instantiate a utility class"); @@ -76,4 +78,10 @@ public final class PropertySourceUtils { }; } + static BinaryOperator throwingMerger() { + return (u, v) -> { + throw new IllegalStateException(String.format("Duplicate key %s", u)); + }; + } + } diff --git a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsTest.java b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsTest.java index 97058716..c77f5784 100644 --- a/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsTest.java +++ b/spring-cloud-kubernetes-config/src/test/java/org/springframework/cloud/kubernetes/config/ConfigMapsTest.java @@ -109,8 +109,8 @@ public class ConfigMapsTest { this.server.getClient().inNamespace(namespace), configMapName); assertThat(cmps.getProperty("dummy.property.string2")).isEqualTo("a"); - assertThat(cmps.getProperty("dummy.property.int2")).isEqualTo("1"); - assertThat(cmps.getProperty("dummy.property.bool2")).isEqualTo("true"); + assertThat(cmps.getProperty("dummy.property.int2")).isEqualTo(1); + assertThat(cmps.getProperty("dummy.property.bool2")).isEqualTo(true); } @Test @@ -129,8 +129,8 @@ public class ConfigMapsTest { this.server.getClient().inNamespace(namespace), configMapName); assertThat(cmps.getProperty("dummy.property.string3")).isEqualTo("a"); - assertThat(cmps.getProperty("dummy.property.int3")).isEqualTo("1"); - assertThat(cmps.getProperty("dummy.property.bool3")).isEqualTo("true"); + assertThat(cmps.getProperty("dummy.property.int3")).isEqualTo(1); + assertThat(cmps.getProperty("dummy.property.bool3")).isEqualTo(true); } @Test