From 61ea78430062530a7b2c69566e0324bbe9f81d27 Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Tue, 2 Dec 2014 13:47:55 -0700 Subject: [PATCH] added @EnableDiscoveryClient, deprecated @EnableEurekaClient --- .../discovery/EnableDiscoveryClient.java | 17 ++++++ .../EnableDiscoveryClientImportSelector.java | 59 +++++++++++++++++++ .../netflix/eureka/EnableEurekaClient.java | 1 + .../eureka/EurekaClientConfiguration.java | 23 ++++---- .../main/resources/META-INF/spring.factories | 5 +- .../netflix/eureka/sample/Application.java | 4 +- 6 files changed, 96 insertions(+), 13 deletions(-) create mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/client/discovery/EnableDiscoveryClient.java create mode 100644 spring-cloud-netflix-core/src/main/java/org/springframework/cloud/client/discovery/EnableDiscoveryClientImportSelector.java diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/client/discovery/EnableDiscoveryClient.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/client/discovery/EnableDiscoveryClient.java new file mode 100644 index 00000000..f72323ed --- /dev/null +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/client/discovery/EnableDiscoveryClient.java @@ -0,0 +1,17 @@ +package org.springframework.cloud.client.discovery; + +/** + * @author Spencer Gibb + */ + +import org.springframework.context.annotation.Import; + +import java.lang.annotation.*; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +@Import(EnableDiscoveryClientImportSelector.class) +public @interface EnableDiscoveryClient { +} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/client/discovery/EnableDiscoveryClientImportSelector.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/client/discovery/EnableDiscoveryClientImportSelector.java new file mode 100644 index 00000000..d580a7a3 --- /dev/null +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/client/discovery/EnableDiscoveryClientImportSelector.java @@ -0,0 +1,59 @@ +package org.springframework.cloud.client.discovery; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.BeanClassLoaderAware; +import org.springframework.context.annotation.DeferredImportSelector; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.AnnotationAttributes; +import org.springframework.core.annotation.Order; +import org.springframework.core.io.support.SpringFactoriesLoader; +import org.springframework.core.type.AnnotationMetadata; +import org.springframework.util.Assert; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; + +/** + * @author Spencer Gibb + */ +@Order(Ordered.LOWEST_PRECEDENCE - 100) +@Slf4j +public class EnableDiscoveryClientImportSelector implements DeferredImportSelector, + BeanClassLoaderAware { + + private ClassLoader beanClassLoader; + + @Override + public String[] selectImports(AnnotationMetadata metadata) { + AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata + .getAnnotationAttributes(EnableDiscoveryClient.class.getName(), + true)); + + Assert.notNull(attributes, "No EnableDiscoveryClient attributes found. Is " + + metadata.getClassName() + + " annotated with @EnableDiscoveryClient?"); + + // Find all possible auto configuration classes, filtering duplicates + List factories = new ArrayList<>(new LinkedHashSet<>( + SpringFactoriesLoader.loadFactoryNames(EnableDiscoveryClient.class, + this.beanClassLoader))); + + if (factories.size() > 1) { + String factory = factories.get(0); + //there should only every be one DiscoveryClient + log.warn("More than one implementation of @EnableDiscoveryClient. Using {} out of available {}", factory, factories); + factories = Collections.singletonList(factory); + } + + return factories.toArray(new String[factories.size()]); + + } + + @Override + public void setBeanClassLoader(ClassLoader classLoader) { + this.beanClassLoader = classLoader; + } + +} diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EnableEurekaClient.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EnableEurekaClient.java index f89b39fe..7afed2ca 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EnableEurekaClient.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EnableEurekaClient.java @@ -31,6 +31,7 @@ import org.springframework.context.annotation.Import; @Retention(RetentionPolicy.RUNTIME) @Documented @Import(EurekaClientConfiguration.class) +@Deprecated public @interface EnableEurekaClient { } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientConfiguration.java index 41a0604b..8506ad64 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientConfiguration.java @@ -43,6 +43,9 @@ import com.netflix.appinfo.InstanceInfo.InstanceStatus; import com.netflix.discovery.DiscoveryManager; import com.netflix.discovery.EurekaClientConfig; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + /** * @author Dave Syer * @@ -56,11 +59,11 @@ public class EurekaClientConfiguration implements SmartLifecycle, Ordered { private static final Logger logger = LoggerFactory .getLogger(EurekaClientConfiguration.class); - private boolean running; + private AtomicBoolean running = new AtomicBoolean(false); private int order = 0; - private int port = 0; + private AtomicInteger port = new AtomicInteger(0); @Autowired private EurekaInstanceConfigBean instanceConfig; @@ -80,12 +83,12 @@ public class EurekaClientConfiguration implements SmartLifecycle, Ordered { @Override public void start() { //only set the port if the nonSecurePort is 0 and this.port != 0 - if (port != 0 && instanceConfig.getNonSecurePort() == 0) { - instanceConfig.setNonSecurePort(port); + if (port.get() != 0 && instanceConfig.getNonSecurePort() == 0) { + instanceConfig.setNonSecurePort(port.get()); } //only initialize if nonSecurePort is greater than 0 and it isn't already running //because of containerPortInitializer below - if (!running && instanceConfig.getNonSecurePort() > 0) { + if (!running.get() && instanceConfig.getNonSecurePort() > 0) { discoveryManagerIntitializer().init(); logger.info("Registering application {} with eureka with status {}", @@ -96,7 +99,7 @@ public class EurekaClientConfiguration implements SmartLifecycle, Ordered { DiscoveryManager.getInstance().getDiscoveryClient().registerHealthCheck(healthCheckHandler); } context.publishEvent(new InstanceRegisteredEvent(this, instanceConfig)); - running = true; + running.set(true); } } @@ -105,12 +108,12 @@ public class EurekaClientConfiguration implements SmartLifecycle, Ordered { logger.info("Unregistering application {} with eureka with status OUT_OF_SERVICE", instanceConfig.getAppname()); ApplicationInfoManager.getInstance().setInstanceStatus(InstanceStatus.OUT_OF_SERVICE); - running = false; + running.set(false); } @Override public boolean isRunning() { - return running; + return running.get(); } @Override @@ -159,8 +162,8 @@ public class EurekaClientConfiguration implements SmartLifecycle, Ordered { @Override public void onApplicationEvent(EmbeddedServletContainerInitializedEvent event) { // TODO: take SSL into account when Spring Boot 1.2 is available - EurekaClientConfiguration.this.port = event.getEmbeddedServletContainer() - .getPort(); + EurekaClientConfiguration.this.port.compareAndSet(0, event.getEmbeddedServletContainer() + .getPort()); EurekaClientConfiguration.this.start(); } }; diff --git a/spring-cloud-netflix-core/src/main/resources/META-INF/spring.factories b/spring-cloud-netflix-core/src/main/resources/META-INF/spring.factories index ea0512e6..1fb9c4e8 100644 --- a/spring-cloud-netflix-core/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-netflix-core/src/main/resources/META-INF/spring.factories @@ -9,4 +9,7 @@ org.springframework.cloud.netflix.ribbon.eureka.RibbonEurekaAutoConfiguration,\ org.springframework.cloud.netflix.servo.ServoMetricsAutoConfiguration org.springframework.cloud.bootstrap.BootstrapConfiguration=\ -org.springframework.cloud.netflix.config.DiscoveryClientConfigServiceBootstrapConfiguration \ No newline at end of file +org.springframework.cloud.netflix.config.DiscoveryClientConfigServiceBootstrapConfiguration + +org.springframework.cloud.client.discovery.EnableDiscoveryClient=\ +org.springframework.cloud.netflix.eureka.EurekaClientConfiguration \ No newline at end of file diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/eureka/sample/Application.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/eureka/sample/Application.java index 68e0b2ce..6df09292 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/eureka/sample/Application.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/eureka/sample/Application.java @@ -4,7 +4,7 @@ import com.netflix.appinfo.HealthCheckHandler; import com.netflix.appinfo.InstanceInfo; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.cloud.netflix.eureka.EnableEurekaClient; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @@ -15,7 +15,7 @@ import org.springframework.web.bind.annotation.RestController; @ComponentScan @EnableAutoConfiguration @RestController -@EnableEurekaClient +@EnableDiscoveryClient public class Application { @Bean