From 859c96d31b3f024bfb7891e4a335eb93a10146bd Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 17 Oct 2014 09:54:18 +0100 Subject: [PATCH] Switch to using EurekaClientConfig to determine client zone This makes perfect sense since there is already support in the API. Unfortunately Eureka also uses that information to set the Server zones by default (duh?!) - see DiscoveryClient.getZone(InstanceInfo), so unless you aggressively update them, the zones will all be the same in all servers. I fixed that problem by unconditionally applying the "domain as zone" guess algorithm, which is fine unless you actually want to use the Amazon metadata. So that's an outstanding problem See gh-30 --- ....java => DiscoveryManagerInitializer.java} | 2 +- .../eureka/EurekaClientConfigBean.java | 1 + .../eureka/EurekaClientConfiguration.java | 6 ++-- .../eureka/DomainExtractingServerList.java | 33 +++++++------------ .../eureka/EurekaRibbonInitializer.java | 30 ++++++++--------- .../eureka/RibbonEurekaAutoConfiguration.java | 10 +++--- .../eureka/EurekaRibbonInitializerTests.java | 8 ++--- .../server/EurekaServerConfiguration.java | 2 +- .../EurekaServerInitializerConfiguration.java | 8 ++--- 9 files changed, 43 insertions(+), 57 deletions(-) rename spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/{DiscoveryManagerIntitializer.java => DiscoveryManagerInitializer.java} (92%) diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/DiscoveryManagerIntitializer.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/DiscoveryManagerInitializer.java similarity index 92% rename from spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/DiscoveryManagerIntitializer.java rename to spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/DiscoveryManagerInitializer.java index b36cb952..cbc9a607 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/DiscoveryManagerIntitializer.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/DiscoveryManagerInitializer.java @@ -6,7 +6,7 @@ import org.springframework.beans.factory.annotation.Autowired; /** * @author Spencer Gibb */ -public class DiscoveryManagerIntitializer { +public class DiscoveryManagerInitializer { @Autowired private EurekaClientConfigBean clientConfig; diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientConfigBean.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientConfigBean.java index 569f6cc3..ffc0c96d 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientConfigBean.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientConfigBean.java @@ -83,6 +83,7 @@ public class EurekaClientConfigBean implements EurekaClientConfig { { serviceUrl.put(DEFAULT_ZONE, "http://localhost:8761/v2/"); + serviceUrl.put("default", "http://localhost:8761/v2/"); } private boolean gZipContent = true; 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 9a55f2af..27de09f7 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 @@ -126,9 +126,9 @@ public class EurekaClientConfiguration implements SmartLifecycle, Ordered { } @Bean - @ConditionalOnMissingBean(DiscoveryManagerIntitializer.class) - public DiscoveryManagerIntitializer discoveryManagerIntitializer() { - return new DiscoveryManagerIntitializer(); + @ConditionalOnMissingBean(DiscoveryManagerInitializer.class) + public DiscoveryManagerInitializer discoveryManagerIntitializer() { + return new DiscoveryManagerInitializer(); } @Bean diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerList.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerList.java index 3685fed8..eb9093da 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerList.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/DomainExtractingServerList.java @@ -15,8 +15,6 @@ */ package org.springframework.cloud.netflix.ribbon.eureka; -import java.net.MalformedURLException; -import java.net.URL; import java.util.List; import org.springframework.util.StringUtils; @@ -50,32 +48,23 @@ public class DomainExtractingServerList implements ServerList { private List setZones(List servers) { for (Server server : servers) { - if (!server.getZone().equals("default")) { - String zone = extractApproximateZone(server.getId()); - server.setZone(zone); - } + String zone = extractApproximateZone(server); + server.setZone(zone); } return servers; } - private String extractApproximateZone(String id) { - try { - URL url = new URL("http://" + id); - String host = url.getHost(); - if (!host.contains(".")) { - return host; - } - String[] split = StringUtils.split(host, "."); - StringBuilder builder = new StringBuilder(split[1]); - for (int i=2; i 0 ? zones[0] : null; if (zone != null) { + // You can set this with archaius.deployment.* (maybe requires + // custom deployment context)? ConfigurationManager.getDeploymentContext().setValue(ContextKey.zone, zone); } @@ -71,10 +67,10 @@ public class EurekaRibbonInitializer implements ServerListInitializer { @SuppressWarnings("unchecked") DynamicServerListLoadBalancer dynamic = (DynamicServerListLoadBalancer) balancer; ServerList list = dynamic.getServerListImpl(); - if (!(list instanceof DomainExtractingServerList) - && !(instance.getDataCenterInfo() instanceof AmazonInfo)) { - // This is optional: you can use the native Eureka AWS features by making - // the EurekaInstanceConfig.dataCenterInfo an AmazonInfo + if (!(list instanceof DomainExtractingServerList)) { + // This is optional: you can use the native Eureka AWS features as long as + // the server zone is populated. TODO: find a way to back off if AWS + // metadata *is* available. dynamic.setServerListImpl(new DomainExtractingServerList(list)); } } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonEurekaAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonEurekaAutoConfiguration.java index f40f0525..2554c346 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonEurekaAutoConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/eureka/RibbonEurekaAutoConfiguration.java @@ -15,9 +15,6 @@ */ package org.springframework.cloud.netflix.ribbon.eureka; -import com.netflix.appinfo.EurekaInstanceConfig; -import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -28,6 +25,9 @@ import org.springframework.cloud.netflix.ribbon.ServerListInitializer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import com.netflix.discovery.EurekaClientConfig; +import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList; + /** * @author Dave Syer * @@ -40,10 +40,10 @@ import org.springframework.context.annotation.Configuration; public class RibbonEurekaAutoConfiguration { @Autowired(required=false) - private EurekaInstanceConfig instance; + private EurekaClientConfig client; @Bean public ServerListInitializer serverListInitializer() { - return new EurekaRibbonInitializer(instance); + return new EurekaRibbonInitializer(client); } } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonInitializerTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonInitializerTests.java index 50f88402..c427711e 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonInitializerTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/eureka/EurekaRibbonInitializerTests.java @@ -21,7 +21,7 @@ import static org.junit.Assert.assertTrue; import org.junit.After; import org.junit.Test; -import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; +import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean; import com.netflix.client.ClientFactory; import com.netflix.config.ConfigurationManager; @@ -43,10 +43,10 @@ public class EurekaRibbonInitializerTests { @Test public void basicConfigurationCreatedForLoadBalancer() { - EurekaInstanceConfigBean instance = new EurekaInstanceConfigBean(); - instance.getMetadataMap().put("zone", "foo"); + EurekaClientConfigBean client = new EurekaClientConfigBean(); + client.getAvailabilityZones().put(client.getRegion(), "foo"); EurekaRibbonInitializer initializer = new EurekaRibbonInitializer( - instance); + client); initializer.initialize("service"); ILoadBalancer balancer = ClientFactory.getNamedLoadBalancer("service"); assertNotNull(balancer); 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/EurekaServerConfiguration.java index db838012..3c614e8f 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/EurekaServerConfiguration.java @@ -36,7 +36,7 @@ public class EurekaServerConfiguration extends WebMvcConfigurerAdapter { bean.setOrder(Ordered.LOWEST_PRECEDENCE); bean.addInitParameter("com.sun.jersey.config.property.packages", "com.netflix.discovery;com.netflix.eureka"); - bean.addInitParameter(ServletContainer.FEATURE_FILTER_FORWARD_ON_404, "true"); + // bean.addInitParameter(ServletContainer.FEATURE_FILTER_FORWARD_ON_404, "true"); bean.setUrlPatterns(Lists.newArrayList("/v2/*")); return bean; } diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerInitializerConfiguration.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerInitializerConfiguration.java index c785114f..9644e232 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerInitializerConfiguration.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerInitializerConfiguration.java @@ -30,7 +30,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.netflix.eureka.DiscoveryManagerIntitializer; +import org.springframework.cloud.netflix.eureka.DiscoveryManagerInitializer; import org.springframework.cloud.netflix.eureka.EurekaServerConfigBean; import org.springframework.cloud.netflix.eureka.server.advice.LeaseManagerLite; import org.springframework.cloud.netflix.eureka.server.advice.PiggybackMethodInterceptor; @@ -82,9 +82,9 @@ public class EurekaServerInitializerConfiguration implements ServletContextAware } @Bean - @ConditionalOnMissingBean(DiscoveryManagerIntitializer.class) - public DiscoveryManagerIntitializer discoveryManagerIntitializer() { - return new DiscoveryManagerIntitializer(); + @ConditionalOnMissingBean(DiscoveryManagerInitializer.class) + public DiscoveryManagerInitializer discoveryManagerIntitializer() { + return new DiscoveryManagerInitializer(); } @Override