Browse Source

Ensure spring.main.sources is not used in refresh cycle

When the RefreshEndpoint makes a new Environment it creates a new
ApplicationContext with (hopefully) empty sources. If the user has
set spring.main.sources it won't be empty, so we should take care
to mask it off in the process.

Fixes gh-79
pull/89/head
Dave Syer 9 years ago
parent
commit
9c6aeba780
  1. 4
      spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapApplicationListener.java
  2. 11
      spring-cloud-context/src/main/java/org/springframework/cloud/endpoint/RefreshEndpoint.java
  3. 21
      spring-cloud-context/src/test/java/org/springframework/cloud/endpoint/RefreshEndpointTests.java

4
spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapApplicationListener.java

@ -111,6 +111,10 @@ public class BootstrapApplicationListener @@ -111,6 +111,10 @@ public class BootstrapApplicationListener
// Use names and ensure unique to protect against duplicates
List<String> names = SpringFactoriesLoader
.loadFactoryNames(BootstrapConfiguration.class, classLoader);
for (String name : StringUtils.commaDelimitedListToStringArray(
environment.getProperty("spring.cloud.bootstrap.sources", ""))) {
names.add(name);
}
// TODO: is it possible or sensible to share a ResourceLoader?
SpringApplicationBuilder builder = new SpringApplicationBuilder()
.profiles(environment.getActiveProfiles()).bannerMode(Mode.OFF)

11
spring-cloud-context/src/main/java/org/springframework/cloud/endpoint/RefreshEndpoint.java

@ -37,6 +37,7 @@ import org.springframework.context.annotation.Configuration; @@ -37,6 +37,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.CompositePropertySource;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.core.env.StandardEnvironment;
@ -52,6 +53,8 @@ import org.springframework.web.context.support.StandardServletEnvironment; @@ -52,6 +53,8 @@ import org.springframework.web.context.support.StandardServletEnvironment;
@ManagedResource
public class RefreshEndpoint extends AbstractEndpoint<Collection<String>> {
private static final String REFRESH_ARGS_PROPERTY_SOURCE = "refreshArgs";
private Set<String> standardSources = new HashSet<String>(
Arrays.asList(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME,
StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME,
@ -88,6 +91,9 @@ public class RefreshEndpoint extends AbstractEndpoint<Collection<String>> { @@ -88,6 +91,9 @@ public class RefreshEndpoint extends AbstractEndpoint<Collection<String>> {
this.context.getEnvironment());
capture = new SpringApplicationBuilder(Empty.class).bannerMode(Mode.OFF)
.web(false).environment(environment).run();
if (environment.getPropertySources().contains(REFRESH_ARGS_PROPERTY_SOURCE)) {
environment.getPropertySources().remove(REFRESH_ARGS_PROPERTY_SOURCE);
}
MutablePropertySources target = this.context.getEnvironment()
.getPropertySources();
String targetName = null;
@ -144,6 +150,11 @@ public class RefreshEndpoint extends AbstractEndpoint<Collection<String>> { @@ -144,6 +150,11 @@ public class RefreshEndpoint extends AbstractEndpoint<Collection<String>> {
}
environment.setActiveProfiles(input.getActiveProfiles());
environment.setDefaultProfiles(input.getDefaultProfiles());
Map<String, Object> map = new HashMap<String, Object>();
map.put("spring.jmx.enabled", false);
map.put("spring.main.sources", "");
capturedPropertySources
.addFirst(new MapPropertySource(REFRESH_ARGS_PROPERTY_SOURCE, map));
return environment;
}

21
spring-cloud-context/src/test/java/org/springframework/cloud/endpoint/RefreshEndpointTests.java

@ -44,6 +44,7 @@ import org.springframework.util.ClassUtils; @@ -44,6 +44,7 @@ import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
@ -96,12 +97,30 @@ public class RefreshEndpointTests { @@ -96,12 +97,30 @@ public class RefreshEndpointTests {
RefreshScope scope = new RefreshScope();
scope.setApplicationContext(this.context);
EnvironmentTestUtils.addEnvironment(this.context,
"spring.main.sources=" + ExternalPropertySourceLocator.class.getName());
"spring.cloud.bootstrap.sources="
+ ExternalPropertySourceLocator.class.getName());
RefreshEndpoint endpoint = new RefreshEndpoint(this.context, scope);
Collection<String> keys = endpoint.invoke();
assertTrue("Wrong keys: " + keys, keys.contains("external.message"));
}
@Test
public void springMainSourcesEmptyInRefreshCycle() throws Exception {
this.context = new SpringApplicationBuilder(Empty.class).web(false)
.bannerMode(Mode.OFF).properties("spring.cloud.bootstrap.name:none")
.run();
RefreshScope scope = new RefreshScope();
scope.setApplicationContext(this.context);
// spring.main.sources should be empty when the refresh cycle starts (we don't
// want any config files from the application context getting into the one used to
// construct the environment for refresh)
EnvironmentTestUtils.addEnvironment(this.context,
"spring.main.sources=" + ExternalPropertySourceLocator.class.getName());
RefreshEndpoint endpoint = new RefreshEndpoint(this.context, scope);
Collection<String> keys = endpoint.invoke();
assertFalse("Wrong keys: " + keys, keys.contains("external.message"));
}
@Test
public void eventsPublishedInOrder() throws Exception {
this.context = new SpringApplicationBuilder(Empty.class).web(false)

Loading…
Cancel
Save