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 b36cb952c..cbc9a607d 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 569f6cc3b..ffc0c96da 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 9a55f2afa..27de09f7a 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 3685fed8b..eb9093da5 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 f40f05259..2554c3469 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 50f884025..c427711e0 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 db838012d..3c614e8fb 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 c785114f2..9644e2321 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