From 91f60b3f4cad8a5ce2976a43ee33220c39bd762b Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 3 Nov 2017 14:01:29 +0000 Subject: [PATCH] Be more selective with the property sources in a context refresh We need to tread a very fine line. Ideally the process of refreshing the Environment builds it back exactly as happened on startup. In particular we probably don't want to have things like application.properties already there when we start the process. This change replaces the more liberal copy of all property sources only a select few (actually only one), paremeterized as a constant. --- .../context/refresh/ContextRefresher.java | 20 ++++++++++++++----- .../refresh/ContextRefresherTests.java | 2 +- .../cloud/endpoint/RefreshEndpointTests.java | 7 +++---- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/refresh/ContextRefresher.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/refresh/ContextRefresher.java index acdab8d8..0b6dbd78 100644 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/refresh/ContextRefresher.java +++ b/spring-cloud-context/src/main/java/org/springframework/cloud/context/refresh/ContextRefresher.java @@ -33,6 +33,9 @@ public class ContextRefresher { private static final String REFRESH_ARGS_PROPERTY_SOURCE = "refreshArgs"; + private static final String[] DEFAULT_PROPERTY_SOURCES = new String[] { + "defaultProperties" }; + private Set standardSources = new HashSet<>( Arrays.asList(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, @@ -125,11 +128,18 @@ public class ContextRefresher { private StandardEnvironment copyEnvironment(ConfigurableEnvironment input) { StandardEnvironment environment = new StandardEnvironment(); MutablePropertySources capturedPropertySources = environment.getPropertySources(); - for (PropertySource source : capturedPropertySources) { - capturedPropertySources.remove(source.getName()); - } - for (PropertySource source : input.getPropertySources()) { - capturedPropertySources.addLast(source); + // Only copy the default property source(s) and the profiles over from the main + // environment (everything else should be pristine, just like it was on startup). + for (String name : DEFAULT_PROPERTY_SOURCES) { + if (input.getPropertySources().contains(name)) { + if (capturedPropertySources.contains(name)) { + capturedPropertySources.replace(name, + input.getPropertySources().get(name)); + } + else { + capturedPropertySources.addLast(input.getPropertySources().get(name)); + } + } } environment.setActiveProfiles(input.getActiveProfiles()); environment.setDefaultProfiles(input.getDefaultProfiles()); diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/refresh/ContextRefresherTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/refresh/ContextRefresherTests.java index 96e7dd52..99211813 100644 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/refresh/ContextRefresherTests.java +++ b/spring-cloud-context/src/test/java/org/springframework/cloud/context/refresh/ContextRefresherTests.java @@ -63,7 +63,7 @@ public class ContextRefresherTests { List names = names(context.getEnvironment().getPropertySources()); assertThat(names).doesNotContain("bootstrapProperties"); ContextRefresher refresher = new ContextRefresher(context, scope); - EnvironmentTestUtils.addEnvironment(context, + EnvironmentTestUtils.addEnvironment("defaultProperties", context.getEnvironment(), "spring.cloud.bootstrap.sources: org.springframework.cloud.context.refresh.ContextRefresherTests.PropertySourceConfiguration\n" + ""); refresher.refresh(); diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/endpoint/RefreshEndpointTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/endpoint/RefreshEndpointTests.java index 3c400474..4eb75750 100644 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/endpoint/RefreshEndpointTests.java +++ b/spring-cloud-context/src/test/java/org/springframework/cloud/endpoint/RefreshEndpointTests.java @@ -70,7 +70,7 @@ public class RefreshEndpointTests { .run(); RefreshScope scope = new RefreshScope(); scope.setApplicationContext(this.context); - EnvironmentTestUtils.addEnvironment(this.context, "spring.profiles.active=local"); + context.getEnvironment().setActiveProfiles("local"); ContextRefresher contextRefresher = new ContextRefresher(this.context, scope); RefreshEndpoint endpoint = new RefreshEndpoint(contextRefresher); Collection keys = endpoint.invoke(); @@ -84,8 +84,7 @@ public class RefreshEndpointTests { .run(); RefreshScope scope = new RefreshScope(); scope.setApplicationContext(this.context); - EnvironmentTestUtils.addEnvironment(this.context, - "spring.profiles.active=override"); + context.getEnvironment().setActiveProfiles("override"); ContextRefresher contextRefresher = new ContextRefresher(this.context, scope); RefreshEndpoint endpoint = new RefreshEndpoint(contextRefresher); Collection keys = endpoint.invoke(); @@ -99,7 +98,7 @@ public class RefreshEndpointTests { .run(); RefreshScope scope = new RefreshScope(); scope.setApplicationContext(this.context); - EnvironmentTestUtils.addEnvironment(this.context, + EnvironmentTestUtils.addEnvironment("defaultProperties", this.context.getEnvironment(), "spring.cloud.bootstrap.sources=" + ExternalPropertySourceLocator.class.getName()); ContextRefresher contextRefresher = new ContextRefresher(this.context, scope);