From 99d9b17a2df0dcc9baf9843991b50bca5cceaa0c Mon Sep 17 00:00:00 2001 From: Biju Kunjummen Date: Tue, 28 Feb 2017 09:00:29 -0800 Subject: [PATCH] Moves EurekaServerConfiguration to auto-configuration Eureka ServerConfiguration is now auto-configuration based, instead of being explicitly specified via configuration pulled in through @EnableEurekaServer. This way specific beans can be conditionally overridden, configuration can be re-ordered. Supports PeerEurekaNodes bean to be overridden by the user Fixes gh-1717 --- .../eureka/server/EnableEurekaServer.java | 10 ++- ...ava => EurekaServerAutoConfiguration.java} | 14 +-- .../EurekaServerMarkerConfiguration.java | 38 ++++++++ .../main/resources/META-INF/spring.factories | 2 + .../eureka/server/ApplicationTests.java | 2 +- .../server/EurekaCustomPeerNodesTest.java | 87 +++++++++++++++++++ 6 files changed, 145 insertions(+), 8 deletions(-) rename spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/{EurekaServerConfiguration.java => EurekaServerAutoConfiguration.java} (95%) create mode 100644 spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerMarkerConfiguration.java create mode 100644 spring-cloud-netflix-eureka-server/src/main/resources/META-INF/spring.factories create mode 100644 spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/EurekaCustomPeerNodesTest.java diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EnableEurekaServer.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EnableEurekaServer.java index 0dd67161..a023a5da 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EnableEurekaServer.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EnableEurekaServer.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-2017 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. @@ -22,16 +22,22 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.context.annotation.Import; /** + * Annotation to activate Eureka Server related configuration {@link EurekaServerAutoConfiguration} + * * @author Dave Syer + * @author Biju Kunjummen * */ + +@EnableDiscoveryClient @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented -@Import(EurekaServerConfiguration.class) +@Import(EurekaServerMarkerConfiguration.class) public @interface EnableEurekaServer { } diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerConfiguration.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerAutoConfiguration.java similarity index 95% rename from spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerConfiguration.java rename to spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerAutoConfiguration.java index 73d4571f..259350c8 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerConfiguration.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerAutoConfiguration.java @@ -29,12 +29,12 @@ import javax.ws.rs.ext.Provider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.eureka.EurekaConstants; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; @@ -66,13 +66,15 @@ import com.sun.jersey.spi.container.servlet.ServletContainer; /** * @author Gunnar Hillert + * @author Biju Kunjummen */ @Configuration @Import(EurekaServerInitializerConfiguration.class) -@EnableDiscoveryClient -@EnableConfigurationProperties({ EurekaDashboardProperties.class, InstanceRegistryProperties.class }) +@ConditionalOnBean(EurekaServerMarkerConfiguration.Marker.class) +@EnableConfigurationProperties({ EurekaDashboardProperties.class, + InstanceRegistryProperties.class }) @PropertySource("classpath:/eureka/server.properties") -public class EurekaServerConfiguration extends WebMvcConfigurerAdapter { +public class EurekaServerAutoConfiguration extends WebMvcConfigurerAdapter { /** * List of packages containing Jersey resources required by the Eureka server */ @@ -98,7 +100,8 @@ public class EurekaServerConfiguration extends WebMvcConfigurerAdapter { @Bean public HasFeatures eurekaServerFeature() { - return HasFeatures.namedFeature("Eureka Server", EurekaServerConfiguration.class); + return HasFeatures.namedFeature("Eureka Server", + EurekaServerAutoConfiguration.class); } @Configuration @@ -163,6 +166,7 @@ public class EurekaServerConfiguration extends WebMvcConfigurerAdapter { } @Bean + @ConditionalOnMissingBean public PeerEurekaNodes peerEurekaNodes(PeerAwareInstanceRegistry registry, ServerCodecs serverCodecs) { return new PeerEurekaNodes(registry, this.eurekaServerConfig, diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerMarkerConfiguration.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerMarkerConfiguration.java new file mode 100644 index 00000000..20ab2b4a --- /dev/null +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerMarkerConfiguration.java @@ -0,0 +1,38 @@ +/* + * Copyright 2017 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.server; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Responsible for adding in a marker bean to activate + * {@link EurekaServerAutoConfiguration} + * + * @author Biju Kunjummen + */ +@Configuration +public class EurekaServerMarkerConfiguration { + + @Bean + public Marker eurekaServerMarkerBean() { + return new Marker(); + } + + class Marker { + } +} diff --git a/spring-cloud-netflix-eureka-server/src/main/resources/META-INF/spring.factories b/spring-cloud-netflix-eureka-server/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..1ce4b307 --- /dev/null +++ b/spring-cloud-netflix-eureka-server/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + org.springframework.cloud.netflix.eureka.server.EurekaServerAutoConfiguration \ No newline at end of file diff --git a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/ApplicationTests.java b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/ApplicationTests.java index 5e9903dc..6f848dd8 100644 --- a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/ApplicationTests.java +++ b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/ApplicationTests.java @@ -106,7 +106,7 @@ public class ApplicationTests { @Test public void customCodecWorks() throws Exception { assertThat("serverCodecs is wrong type", this.serverCodecs, - is(instanceOf(EurekaServerConfiguration.CloudServerCodecs.class))); + is(instanceOf(EurekaServerAutoConfiguration.CloudServerCodecs.class))); CodecWrapper codec = this.serverCodecs.getFullJsonCodec(); assertThat("codec is wrong type", codec, is(instanceOf(CloudJacksonJson.class))); diff --git a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/EurekaCustomPeerNodesTest.java b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/EurekaCustomPeerNodesTest.java new file mode 100644 index 00000000..ee774c35 --- /dev/null +++ b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/EurekaCustomPeerNodesTest.java @@ -0,0 +1,87 @@ +/* + * Copyright 2013-2017 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.server; + +import static org.junit.Assert.*; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.junit4.SpringRunner; + +import com.netflix.appinfo.ApplicationInfoManager; +import com.netflix.discovery.EurekaClientConfig; +import com.netflix.eureka.EurekaServerConfig; +import com.netflix.eureka.cluster.PeerEurekaNodes; +import com.netflix.eureka.registry.PeerAwareInstanceRegistry; +import com.netflix.eureka.resources.ServerCodecs; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = EurekaCustomPeerNodesTest.Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, value = { + "spring.application.name=eureka", "server.contextPath=/context", + "management.security.enabled=false" }) +public class EurekaCustomPeerNodesTest { + + @Autowired + private PeerEurekaNodes peerEurekaNodes; + + @Test + public void testCustomPeerNodesShouldTakePrecedenceOverDefault() { + assertTrue("PeerEurekaNodes should be the user created one", + peerEurekaNodes instanceof CustomEurekaPeerNodes); + } + + @Configuration + @EnableAutoConfiguration + @EnableEurekaServer + protected static class Application { + + public static void main(String[] args) { + new SpringApplicationBuilder(ApplicationContextTests.Application.class) + .properties("spring.application.name=eureka", + "server.contextPath=/context") + .run(args); + } + + @Bean + public PeerEurekaNodes myPeerEurekaNodes(PeerAwareInstanceRegistry registry, + EurekaServerConfig eurekaServerConfig, + EurekaClientConfig eurekaClientConfig, ServerCodecs serverCodecs, + ApplicationInfoManager applicationInfoManager) { + return new CustomEurekaPeerNodes(registry, eurekaServerConfig, + eurekaClientConfig, serverCodecs, applicationInfoManager); + } + + } + + private static class CustomEurekaPeerNodes extends PeerEurekaNodes { + + public CustomEurekaPeerNodes(PeerAwareInstanceRegistry registry, + EurekaServerConfig serverConfig, EurekaClientConfig clientConfig, + ServerCodecs serverCodecs, + ApplicationInfoManager applicationInfoManager) { + super(registry, serverConfig, clientConfig, serverCodecs, + applicationInfoManager); + } + } + +}