From 1f12902f78f2b83c44f8d53d7650c1e1103ac467 Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Wed, 19 Apr 2017 11:29:33 -0400 Subject: [PATCH] Make sure the EurekaClient bean is recreated after refresh. Fixes #1857. --- .../EurekaDiscoveryClientConfiguration.java | 8 +++ .../eureka/config/ConfigRefreshTests.java | 60 +++++++++++++++++++ .../RefreshEurekaSampleApplication.java | 47 +++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/config/ConfigRefreshTests.java create mode 100644 spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/sample/RefreshEurekaSampleApplication.java diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClientConfiguration.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClientConfiguration.java index 37c938ab..8f068518 100644 --- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClientConfiguration.java +++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClientConfiguration.java @@ -61,11 +61,19 @@ public class EurekaDiscoveryClientConfiguration { @ConditionalOnClass(RefreshScopeRefreshedEvent.class) protected static class EurekaClientConfigurationRefresher { + @Autowired(required = false) + private EurekaClient eurekaClient; + @Autowired(required = false) private EurekaAutoServiceRegistration autoRegistration; @EventListener(RefreshScopeRefreshedEvent.class) public void onApplicationEvent(RefreshScopeRefreshedEvent event) { + //This will force the creation of the EurkaClient bean if not already created + //to make sure the client will be reregistered after a refresh event + if(eurekaClient != null) { + eurekaClient.getApplications(); + } if (autoRegistration != null) { // register in case meta data changed this.autoRegistration.stop(); diff --git a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/config/ConfigRefreshTests.java b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/config/ConfigRefreshTests.java new file mode 100644 index 00000000..bc1a3852 --- /dev/null +++ b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/config/ConfigRefreshTests.java @@ -0,0 +1,60 @@ +/* + * + * * Copyright 2013-2016 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package org.springframework.cloud.netflix.eureka.config; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent; +import org.springframework.cloud.netflix.eureka.sample.RefreshEurekaSampleApplication; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.test.context.junit4.SpringRunner; + +import com.netflix.discovery.EurekaClient; + +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +/** + * @author Ryan Baxter + */ +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = RefreshEurekaSampleApplication.class) +public class ConfigRefreshTests { + + @Autowired + private ApplicationEventPublisher publisher; + + @Autowired + //Mocked in RefreshEurekaSampleApplication + private EurekaClient client; + + @Test + // This test is used to verify that getApplications is called the correct number of times + // when a refresh event is fired. The getApplications call in EurekaClientConfigurationRefresher.onApplicationEvent + // ensures that the EurekaClient bean is recreated after a refresh event and that we reregister the client with + //the server + public void verifyGetApplications() { + if(publisher != null) { + publisher.publishEvent(new RefreshScopeRefreshedEvent()); + } + verify(client, times(3)).getApplications(); + } +} diff --git a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/sample/RefreshEurekaSampleApplication.java b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/sample/RefreshEurekaSampleApplication.java new file mode 100644 index 00000000..6d1e3cd8 --- /dev/null +++ b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/sample/RefreshEurekaSampleApplication.java @@ -0,0 +1,47 @@ +/* + * + * * Copyright 2013-2016 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package org.springframework.cloud.netflix.eureka.sample; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.netflix.eureka.CloudEurekaClient; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.bind.annotation.RestController; + +import com.netflix.discovery.EurekaClient; + +import static org.mockito.Mockito.mock; + +/** + * @author Ryan Baxter + */ +@Configuration +@ComponentScan +@EnableAutoConfiguration +@RestController +@EnableDiscoveryClient +public class RefreshEurekaSampleApplication { + + @Bean + public EurekaClient getClient() { + return mock(CloudEurekaClient.class); + } +}