Fix value data-type & entry-set order of yml properties bound to Map (#556)

implementing PR #554 on 1.1.x branch

Co-authored-by: Michael Moudatsos <v-mmoudatsos@eurobank.gr>
This commit is contained in:
moudatsos
2020-05-18 23:55:25 +03:00
committed by GitHub
parent 5a28981faf
commit 742e418c7c
4 changed files with 31 additions and 19 deletions

View File

@@ -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<String, String> getData(KubernetesClient client, String name,
private static Map<String, Object> getData(KubernetesClient client, String name,
String namespace, Environment environment) {
try {
Map<String, String> result = new HashMap<>();
Map<String, Object> 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<String, String> processAllEntries(Map<String, String> input,
private static Map<String, Object> processAllEntries(Map<String, String> input,
Environment environment) {
Set<Entry<String, String>> entrySet = input.entrySet();
@@ -163,16 +165,17 @@ public class ConfigMapPropertySource extends MapPropertySource {
return defaultProcessAllEntries(input, environment);
}
private static Map<String, String> defaultProcessAllEntries(Map<String, String> input,
private static Map<String, Object> defaultProcessAllEntries(Map<String, String> 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<String, String> extractProperties(String resourceName,
private static Map<String, Object> 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<String, String>() {
return new LinkedHashMap<String, Object>() {
{
put(resourceName, content);
}
};
}
private static Map<String, Object> asObjectMap(Map<String, String> source) {
return source.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
private static Map<String, Object> asObjectMap(Map<String, Object> source) {
return source.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey,
Map.Entry::getValue, throwingMerger(), LinkedHashMap::new));
}
}

View File

@@ -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<String, Map<String, String>> contentToMapFunction, String content,
Function<String, Map<String, Object>> contentToMapFunction, String content,
String name, CompositePropertySource composite) {
Map<String, Object> map = new HashMap<>();

View File

@@ -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, Map<String, String>> PROPERTIES_TO_MAP = p -> p
static final Function<Properties, Map<String, Object>> 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 <T> BinaryOperator<T> throwingMerger() {
return (u, v) -> {
throw new IllegalStateException(String.format("Duplicate key %s", u));
};
}
}

View File

@@ -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