From 96235ea674a474f49272e72bf3dce1bed8f57632 Mon Sep 17 00:00:00 2001 From: Madhura Bhave Date: Wed, 31 Jul 2019 12:43:08 -0700 Subject: [PATCH] Fix ordering of JSON property source relative to servlet sources Fixes gh-17652 --- ...plicationJsonEnvironmentPostProcessor.java | 19 ++++++-- ...tionJsonEnvironmentPostProcessorTests.java | 48 +++++++++++++++++++ 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/env/SpringApplicationJsonEnvironmentPostProcessor.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/env/SpringApplicationJsonEnvironmentPostProcessor.java index 19f5bb44d73..2eda5f9257b 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/env/SpringApplicationJsonEnvironmentPostProcessor.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/env/SpringApplicationJsonEnvironmentPostProcessor.java @@ -16,10 +16,13 @@ package org.springframework.boot.env; +import java.util.Arrays; import java.util.Collection; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.Map; import java.util.Objects; +import java.util.Set; import org.springframework.boot.SpringApplication; import org.springframework.boot.json.JsonParser; @@ -65,6 +68,11 @@ public class SpringApplicationJsonEnvironmentPostProcessor implements Environmen private static final String SERVLET_ENVIRONMENT_CLASS = "org.springframework.web." + "context.support.StandardServletEnvironment"; + private static final Set SERVLET_ENVIRONMENT_PROPERTY_SOURCES = new LinkedHashSet<>( + Arrays.asList(StandardServletEnvironment.JNDI_PROPERTY_SOURCE_NAME, + StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME, + StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME)); + /** * The default order for the processor. */ @@ -141,10 +149,13 @@ public class SpringApplicationJsonEnvironmentPostProcessor implements Environmen } private String findPropertySource(MutablePropertySources sources) { - if (ClassUtils.isPresent(SERVLET_ENVIRONMENT_CLASS, null) - && sources.contains(StandardServletEnvironment.JNDI_PROPERTY_SOURCE_NAME)) { - return StandardServletEnvironment.JNDI_PROPERTY_SOURCE_NAME; - + if (ClassUtils.isPresent(SERVLET_ENVIRONMENT_CLASS, null)) { + PropertySource servletPropertySource = sources.stream() + .filter((source) -> SERVLET_ENVIRONMENT_PROPERTY_SOURCES.contains(source.getName())).findFirst() + .orElse(null); + if (servletPropertySource != null) { + return servletPropertySource.getName(); + } } return StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME; } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/env/SpringApplicationJsonEnvironmentPostProcessorTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/env/SpringApplicationJsonEnvironmentPostProcessorTests.java index 91107ec7f89..ddc85f82380 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/env/SpringApplicationJsonEnvironmentPostProcessorTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/env/SpringApplicationJsonEnvironmentPostProcessorTests.java @@ -16,14 +16,18 @@ package org.springframework.boot.env; +import java.util.Collections; + import org.junit.Test; import org.springframework.boot.json.JsonParseException; import org.springframework.boot.origin.PropertySourceOrigin; import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.PropertySource; import org.springframework.core.env.StandardEnvironment; import org.springframework.test.context.support.TestPropertySourceUtils; +import org.springframework.web.context.support.StandardServletEnvironment; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -134,4 +138,48 @@ public class SpringApplicationJsonEnvironmentPostProcessorTests { assertThat(this.environment.resolvePlaceholders("${foo:}")).isEqualTo("bar"); } + @Test + public void propertySourceShouldBeOrderedBeforeJndiPropertySource() { + testServletPropertySource(StandardServletEnvironment.JNDI_PROPERTY_SOURCE_NAME); + } + + @Test + public void propertySourceShouldBeOrderedBeforeServletContextPropertySource() { + testServletPropertySource(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME); + } + + @Test + public void propertySourceShouldBeOrderedBeforeServletConfigPropertySource() { + testServletPropertySource(StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME); + } + + @Test + public void propertySourceOrderingWhenMultipleServletSpecificPropertySources() { + MapPropertySource jndi = getPropertySource(StandardServletEnvironment.JNDI_PROPERTY_SOURCE_NAME, "jndi"); + this.environment.getPropertySources().addFirst(jndi); + MapPropertySource servlet = getPropertySource(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME, + "servlet"); + this.environment.getPropertySources().addFirst(servlet); + MapPropertySource custom = getPropertySource("custom", "custom"); + this.environment.getPropertySources().addFirst(custom); + TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment, + "SPRING_APPLICATION_JSON={\"foo\":\"bar\"}"); + this.processor.postProcessEnvironment(this.environment, null); + PropertySource json = this.environment.getPropertySources().get("spring.application.json"); + assertThat(this.environment.getProperty("foo")).isEqualTo("custom"); + assertThat(this.environment.getPropertySources()).containsSequence(custom, json, servlet, jndi); + } + + private void testServletPropertySource(String servletContextPropertySourceName) { + this.environment.getPropertySources().addFirst(getPropertySource(servletContextPropertySourceName, "servlet")); + TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.environment, + "SPRING_APPLICATION_JSON={\"foo\":\"bar\"}"); + this.processor.postProcessEnvironment(this.environment, null); + assertThat(this.environment.getProperty("foo")).isEqualTo("bar"); + } + + private MapPropertySource getPropertySource(String name, String value) { + return new MapPropertySource(name, Collections.singletonMap("foo", value)); + } + }