From 226db4697f9e2cd12db7ffe769aa21b8f2686981 Mon Sep 17 00:00:00 2001 From: Madhura Bhave Date: Wed, 10 May 2017 12:33:12 -0700 Subject: [PATCH] Make SpringApplicationJsonEnvironmentPostProcessor origin aware Closes gh-8932 --- ...plicationJsonEnvironmentPostProcessor.java | 46 ++++++++++++------- ...tionJsonEnvironmentPostProcessorTests.java | 13 ++++++ 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/spring-boot/src/main/java/org/springframework/boot/env/SpringApplicationJsonEnvironmentPostProcessor.java b/spring-boot/src/main/java/org/springframework/boot/env/SpringApplicationJsonEnvironmentPostProcessor.java index 3dba6bafb8..921782200a 100644 --- a/spring-boot/src/main/java/org/springframework/boot/env/SpringApplicationJsonEnvironmentPostProcessor.java +++ b/spring-boot/src/main/java/org/springframework/boot/env/SpringApplicationJsonEnvironmentPostProcessor.java @@ -19,6 +19,7 @@ package org.springframework.boot.env; import java.util.Collection; import java.util.LinkedHashMap; import java.util.Map; +import java.util.stream.StreamSupport; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -26,15 +27,15 @@ import org.apache.commons.logging.LogFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.json.JsonParser; import org.springframework.boot.json.JsonParserFactory; +import org.springframework.boot.origin.OriginTrackedValue; +import org.springframework.boot.origin.PropertySourceOrigin; import org.springframework.core.Ordered; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.Environment; -import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.MutablePropertySources; import org.springframework.core.env.PropertySource; import org.springframework.core.env.StandardEnvironment; import org.springframework.util.ClassUtils; -import org.springframework.util.StringUtils; import org.springframework.web.context.support.StandardServletEnvironment; /** @@ -45,6 +46,7 @@ import org.springframework.web.context.support.StandardServletEnvironment; * * @author Dave Syer * @author Phillip Webb + * @author Madhura Bhave * @since 1.3.0 */ public class SpringApplicationJsonEnvironmentPostProcessor @@ -75,20 +77,30 @@ public class SpringApplicationJsonEnvironmentPostProcessor @Override public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { - String json = environment.resolvePlaceholders( - "${spring.application.json:${SPRING_APPLICATION_JSON:}}"); - if (StringUtils.hasText(json)) { - processJson(environment, json); + MutablePropertySources propertySources = environment.getPropertySources(); + PropertySource source = StreamSupport.stream(propertySources.spliterator(), false) + .filter(s -> getProperty(s) != null) + .findFirst().orElse(null); + if (source != null) { + String json = (String) getProperty(source); + processJson(environment, json, source); } } - private void processJson(ConfigurableEnvironment environment, String json) { + private Object getProperty(PropertySource source) { + if (source.containsProperty("spring.application.json")) { + return source.getProperty("spring.application.json"); + } + return source.getProperty("SPRING_APPLICATION_JSON"); + } + + private void processJson(ConfigurableEnvironment environment, String json, PropertySource source) { try { JsonParser parser = JsonParserFactory.getJsonParser(); Map map = parser.parseMap(json); if (!map.isEmpty()) { addJsonPropertySource(environment, - new MapPropertySource("spring.application.json", flatten(map))); + new OriginTrackedMapPropertySource("spring.application.json", flatten(map, source))); } } catch (Exception ex) { @@ -99,36 +111,38 @@ public class SpringApplicationJsonEnvironmentPostProcessor /** * Flatten the map keys using period separator. * @param map The map that should be flattened + * @param source The property source for spring.application.json or SPRING_APPLICATION_JSON * @return the flattened map */ - private Map flatten(Map map) { + private Map flatten(Map map, PropertySource source) { Map result = new LinkedHashMap<>(); - flatten(null, result, map); + flatten(null, result, map, source); return result; } private void flatten(String prefix, Map result, - Map map) { + Map map, PropertySource source) { prefix = (prefix == null ? "" : prefix + "."); for (Map.Entry entry : map.entrySet()) { - extract(prefix + entry.getKey(), result, entry.getValue()); + extract(prefix + entry.getKey(), result, entry.getValue(), source); } } @SuppressWarnings("unchecked") - private void extract(String name, Map result, Object value) { + private void extract(String name, Map result, Object value, PropertySource source) { if (value instanceof Map) { - flatten(name, result, (Map) value); + flatten(name, result, (Map) value, source); } else if (value instanceof Collection) { int index = 0; for (Object object : (Collection) value) { - extract(name + "[" + index + "]", result, object); + extract(name + "[" + index + "]", result, object, source); index++; } } else { - result.put(name, value); + OriginTrackedValue originTrackedValue = OriginTrackedValue.of(value, PropertySourceOrigin.get(source, name)); + result.put(name, originTrackedValue); } } diff --git a/spring-boot/src/test/java/org/springframework/boot/env/SpringApplicationJsonEnvironmentPostProcessorTests.java b/spring-boot/src/test/java/org/springframework/boot/env/SpringApplicationJsonEnvironmentPostProcessorTests.java index e952de8284..9f65c43905 100644 --- a/spring-boot/src/test/java/org/springframework/boot/env/SpringApplicationJsonEnvironmentPostProcessorTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/env/SpringApplicationJsonEnvironmentPostProcessorTests.java @@ -18,7 +18,9 @@ package org.springframework.boot.env; import org.junit.Test; +import org.springframework.boot.origin.PropertySourceOrigin; import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.PropertySource; import org.springframework.core.env.StandardEnvironment; import org.springframework.test.context.support.TestPropertySourceUtils; @@ -116,4 +118,15 @@ public class SpringApplicationJsonEnvironmentPostProcessorTests { .isEqualTo("spam"); } + @Test + public void propertySourceShouldTrackOrigin() throws Exception { + assertThat(this.environment.resolvePlaceholders("${foo:}")).isEmpty(); + TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment, + "spring.application.json={\"foo\":\"bar\"}"); + this.processor.postProcessEnvironment(this.environment, null); + PropertySource propertySource = this.environment.getPropertySources().get("spring.application.json"); + PropertySourceOrigin origin = (PropertySourceOrigin) PropertySourceOrigin.get(propertySource, "foo"); + assertThat(origin.getPropertySource().getName()).isEqualTo("Inlined Test Properties"); + assertThat(this.environment.resolvePlaceholders("${foo:}")).isEqualTo("bar"); + } }