Make /refresh endpoint work as designed

All @RefreshScope beans should be invalidated even if there
are no changes in property values (since those might have come from
a POST to /env for instance).
This commit is contained in:
Dave Syer
2014-09-10 18:33:06 -05:00
parent 6dd6e57c57
commit 561c0bd2f1
4 changed files with 28 additions and 17 deletions

View File

@@ -183,8 +183,8 @@ public class RefreshAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public RefreshEndpoint refreshEndpoint(ConfigurableApplicationContext context) {
RefreshEndpoint endpoint = new RefreshEndpoint(context);
public RefreshEndpoint refreshEndpoint(ConfigurableApplicationContext context, RefreshScope scope) {
RefreshEndpoint endpoint = new RefreshEndpoint(context, scope);
return endpoint;
}

View File

@@ -27,6 +27,8 @@ import java.util.Set;
import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.cloud.context.scope.refresh.RefreshScope;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.CompositePropertySource;
@@ -36,7 +38,6 @@ import org.springframework.core.env.PropertySource;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.context.support.StandardServletEnvironment;
@@ -57,9 +58,12 @@ public class RefreshEndpoint extends AbstractEndpoint<Collection<String>> {
private ConfigurableApplicationContext context;
public RefreshEndpoint(ConfigurableApplicationContext context) {
private RefreshScope scope;
public RefreshEndpoint(ConfigurableApplicationContext context, RefreshScope scope) {
super("refresh");
this.context = context;
this.scope = scope;
}
@ManagedOperation
@@ -68,6 +72,7 @@ public class RefreshEndpoint extends AbstractEndpoint<Collection<String>> {
addConfigFilesToEnvironment();
Set<String> keys = changes(before,
extract(context.getEnvironment().getPropertySources())).keySet();
scope.refreshAll();
if (keys.isEmpty()) {
return new String[0];
}

View File

@@ -32,18 +32,18 @@ import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfigurati
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.context.scope.refresh.RefreshScopeIntegrationTests.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.context.scope.refresh.RefreshScopeIntegrationTests.TestConfiguration;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@SpringApplicationConfiguration(classes=TestConfiguration.class)
@SpringApplicationConfiguration(classes = TestConfiguration.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class RefreshScopeIntegrationTests {
@@ -112,7 +112,8 @@ public class RefreshScopeIntegrationTests {
}
public static class ExampleService implements Service, InitializingBean, DisposableBean {
public static class ExampleService implements Service, InitializingBean,
DisposableBean {
private static Log logger = LogFactory.getLog(ExampleService.class);
@@ -159,7 +160,8 @@ public class RefreshScopeIntegrationTests {
logger.debug("Getting message: " + message);
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
logger.info("Returning message: " + message);
@@ -167,15 +169,15 @@ public class RefreshScopeIntegrationTests {
}
}
@Configuration
@EnableConfigurationProperties(TestProperties.class)
@Import({RefreshAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class})
@Import({ RefreshAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class })
protected static class TestConfiguration {
@Autowired
private TestProperties properties;
@Bean
@RefreshScope
public ExampleService service() {
@@ -184,7 +186,7 @@ public class RefreshScopeIntegrationTests {
service.setDelay(properties.getDelay());
return service;
}
}
@ConfigurationProperties
@@ -192,20 +194,24 @@ public class RefreshScopeIntegrationTests {
protected static class TestProperties {
private String message;
private int delay;
@ManagedAttribute
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@ManagedAttribute
public int getDelay() {
return delay;
}
public void setDelay(int delay) {
this.delay = delay;
}
}
}

View File

@@ -1 +1 @@
spring.main.sources: org.springframework.platform.bootstrap.BootstrapConfigurationTests.PropertySourceConfiguration
spring.main.sources: org.springframework.cloud.bootstrap.BootstrapConfigurationTests.PropertySourceConfiguration