Make SpringApplicationJsonEnvironmentPostProcessor origin aware
Closes gh-8932
This commit is contained in:
@@ -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<String, Object> 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<String, Object> flatten(Map<String, Object> map) {
|
||||
private Map<String, Object> flatten(Map<String, Object> map, PropertySource source) {
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
flatten(null, result, map);
|
||||
flatten(null, result, map, source);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void flatten(String prefix, Map<String, Object> result,
|
||||
Map<String, Object> map) {
|
||||
Map<String, Object> map, PropertySource source) {
|
||||
prefix = (prefix == null ? "" : prefix + ".");
|
||||
for (Map.Entry<String, Object> 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<String, Object> result, Object value) {
|
||||
private void extract(String name, Map<String, Object> result, Object value, PropertySource source) {
|
||||
if (value instanceof Map) {
|
||||
flatten(name, result, (Map<String, Object>) value);
|
||||
flatten(name, result, (Map<String, Object>) value, source);
|
||||
}
|
||||
else if (value instanceof Collection) {
|
||||
int index = 0;
|
||||
for (Object object : (Collection<Object>) 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user