From 898561a25800ce09752c69ea61958a25ca1200d7 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 17 May 2016 15:42:31 +0100 Subject: [PATCH] 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 --- ...ntConfigServiceBootstrapConfiguration.java | 13 ++++++++++- ...figServiceBootstrapConfigurationTests.java | 23 +++++++++++++++---- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/DiscoveryClientConfigServiceBootstrapConfiguration.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/DiscoveryClientConfigServiceBootstrapConfiguration.java index a049e172..ca70599d 100644 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/DiscoveryClientConfigServiceBootstrapConfiguration.java +++ b/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/DiscoveryClientConfigServiceBootstrapConfiguration.java @@ -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"); diff --git a/spring-cloud-config-client/src/test/java/org/springframework/cloud/config/client/DiscoveryClientConfigServiceBootstrapConfigurationTests.java b/spring-cloud-config-client/src/test/java/org/springframework/cloud/config/client/DiscoveryClientConfigServiceBootstrapConfigurationTests.java index 6bf966df..ff334fd5 100644 --- a/spring-cloud-config-client/src/test/java/org/springframework/cloud/config/client/DiscoveryClientConfigServiceBootstrapConfigurationTests.java +++ b/spring-cloud-config-client/src/test/java/org/springframework/cloud/config/client/DiscoveryClientConfigServiceBootstrapConfigurationTests.java @@ -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);