Add listener for HearbeatEvent in discovery client config boostrap

The HeartbeatEvent can tell us when the config server might have moved,
so we listen for it and refresh the configuration if there is a
change in the service catalog. On startup if there is a retry
configured it will catch the change. After that the app has to be
/refresh'ed to propagate the change to the environment.

Fixes gh-400
This commit is contained in:
Dave Syer
2016-05-17 15:42:31 +01:00
parent 8bff9d2649
commit 898561a258
2 changed files with 31 additions and 5 deletions

View File

@@ -25,6 +25,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
import org.springframework.cloud.client.discovery.event.HeartbeatMonitor;
import org.springframework.cloud.commons.util.UtilAutoConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@@ -52,11 +54,20 @@ public class DiscoveryClientConfigServiceBootstrapConfiguration {
@Autowired
private DiscoveryClient client;
private HeartbeatMonitor monitor = new HeartbeatMonitor();
@EventListener(ContextRefreshedEvent.class)
public void onApplicationEvent(ContextRefreshedEvent event) {
public void startup(ContextRefreshedEvent event) {
refresh();
}
@EventListener(HeartbeatEvent.class)
public void heartbeat(HeartbeatEvent event) {
if (monitor.update(event.getValue())) {
refresh();
}
}
private void refresh() {
try {
logger.debug("Locating configserver via discovery");

View File

@@ -16,6 +16,10 @@
package org.springframework.cloud.config.client;
import static org.junit.Assert.assertEquals;
import static org.mockito.BDDMockito.given;
import static org.springframework.cloud.config.client.ConfigClientProperties.Discovery.DEFAULT_CONFIG_SERVER;
import java.util.Arrays;
import org.junit.After;
@@ -26,13 +30,10 @@ import org.springframework.boot.test.EnvironmentTestUtils;
import org.springframework.cloud.client.DefaultServiceInstance;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
import org.springframework.cloud.commons.util.UtilAutoConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import static org.junit.Assert.assertEquals;
import static org.mockito.BDDMockito.given;
import static org.springframework.cloud.config.client.ConfigClientProperties.Discovery.DEFAULT_CONFIG_SERVER;
/**
* @author Dave Syer
*/
@@ -73,6 +74,20 @@ public class DiscoveryClientConfigServiceBootstrapConfigurationTests {
assertEquals("http://foo:8877/", locator.getRawUri());
}
@Test
public void onWhenHeartbeat() throws Exception {
setup("spring.cloud.config.discovery.enabled=true");
assertEquals(1, this.context.getBeanNamesForType(
DiscoveryClientConfigServiceBootstrapConfiguration.class).length);
given(this.client.getInstances(DEFAULT_CONFIG_SERVER))
.willReturn(Arrays.asList(this.info));
Mockito.verify(this.client).getInstances(DEFAULT_CONFIG_SERVER);
context.publishEvent(new HeartbeatEvent(context, "new"));
ConfigClientProperties locator = this.context
.getBean(ConfigClientProperties.class);
assertEquals("http://foo:8877/", locator.getRawUri());
}
@Test
public void secureWhenRequested() throws Exception {
this.info = new DefaultServiceInstance("app", "foo", 443, true);