Commit 859c96d3 by Dave Syer

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
parent 997f5310
...@@ -6,7 +6,7 @@ import org.springframework.beans.factory.annotation.Autowired; ...@@ -6,7 +6,7 @@ import org.springframework.beans.factory.annotation.Autowired;
/** /**
* @author Spencer Gibb * @author Spencer Gibb
*/ */
public class DiscoveryManagerIntitializer { public class DiscoveryManagerInitializer {
@Autowired @Autowired
private EurekaClientConfigBean clientConfig; private EurekaClientConfigBean clientConfig;
......
...@@ -83,6 +83,7 @@ public class EurekaClientConfigBean implements EurekaClientConfig { ...@@ -83,6 +83,7 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
{ {
serviceUrl.put(DEFAULT_ZONE, "http://localhost:8761/v2/"); serviceUrl.put(DEFAULT_ZONE, "http://localhost:8761/v2/");
serviceUrl.put("default", "http://localhost:8761/v2/");
} }
private boolean gZipContent = true; private boolean gZipContent = true;
......
...@@ -126,9 +126,9 @@ public class EurekaClientConfiguration implements SmartLifecycle, Ordered { ...@@ -126,9 +126,9 @@ public class EurekaClientConfiguration implements SmartLifecycle, Ordered {
} }
@Bean @Bean
@ConditionalOnMissingBean(DiscoveryManagerIntitializer.class) @ConditionalOnMissingBean(DiscoveryManagerInitializer.class)
public DiscoveryManagerIntitializer discoveryManagerIntitializer() { public DiscoveryManagerInitializer discoveryManagerIntitializer() {
return new DiscoveryManagerIntitializer(); return new DiscoveryManagerInitializer();
} }
@Bean @Bean
......
...@@ -15,8 +15,6 @@ ...@@ -15,8 +15,6 @@
*/ */
package org.springframework.cloud.netflix.ribbon.eureka; package org.springframework.cloud.netflix.ribbon.eureka;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List; import java.util.List;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
...@@ -50,32 +48,23 @@ public class DomainExtractingServerList implements ServerList<Server> { ...@@ -50,32 +48,23 @@ public class DomainExtractingServerList implements ServerList<Server> {
private List<Server> setZones(List<Server> servers) { private List<Server> setZones(List<Server> servers) {
for (Server server : servers) { for (Server server : servers) {
if (!server.getZone().equals("default")) { String zone = extractApproximateZone(server);
String zone = extractApproximateZone(server.getId());
server.setZone(zone); server.setZone(zone);
} }
}
return servers; return servers;
} }
private String extractApproximateZone(String id) { private String extractApproximateZone(Server server) {
try { String host = server.getHost();
URL url = new URL("http://" + id);
String host = url.getHost();
if (!host.contains(".")) { if (!host.contains(".")) {
return host; return host;
} }
String[] split = StringUtils.split(host, "."); String[] split = StringUtils.split(host, ".");
StringBuilder builder = new StringBuilder(split[1]); StringBuilder builder = new StringBuilder(split[1]);
for (int i=2; i<split.length; i++) { for (int i = 2; i < split.length; i++) {
builder.append(".").append(split[i]); builder.append(".").append(split[i]);
} }
return builder.toString(); return builder.toString();
} }
catch (MalformedURLException e) {
}
return "defaultZone";
}
} }
...@@ -8,11 +8,10 @@ import static com.netflix.client.config.CommonClientConfigKey.NIWSServerListFilt ...@@ -8,11 +8,10 @@ import static com.netflix.client.config.CommonClientConfigKey.NIWSServerListFilt
import org.springframework.cloud.netflix.ribbon.ServerListInitializer; import org.springframework.cloud.netflix.ribbon.ServerListInitializer;
import com.netflix.appinfo.AmazonInfo;
import com.netflix.appinfo.EurekaInstanceConfig;
import com.netflix.client.ClientFactory; import com.netflix.client.ClientFactory;
import com.netflix.config.ConfigurationManager; import com.netflix.config.ConfigurationManager;
import com.netflix.config.DeploymentContext.ContextKey; import com.netflix.config.DeploymentContext.ContextKey;
import com.netflix.discovery.EurekaClientConfig;
import com.netflix.loadbalancer.DynamicServerListLoadBalancer; import com.netflix.loadbalancer.DynamicServerListLoadBalancer;
import com.netflix.loadbalancer.ILoadBalancer; import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server; import com.netflix.loadbalancer.Server;
...@@ -29,24 +28,21 @@ import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList; ...@@ -29,24 +28,21 @@ import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList;
*/ */
public class EurekaRibbonInitializer implements ServerListInitializer { public class EurekaRibbonInitializer implements ServerListInitializer {
private EurekaInstanceConfig instance; private EurekaClientConfig client;
public EurekaRibbonInitializer(EurekaInstanceConfig instance) { public EurekaRibbonInitializer(EurekaClientConfig client) {
this.instance = instance; this.client = client;
} }
@Override @Override
public void initialize(String serviceId) { public void initialize(String serviceId) {
if (instance != null if (client != null
&& ConfigurationManager.getDeploymentContext().getValue(ContextKey.zone) == null) { && ConfigurationManager.getDeploymentContext().getValue(ContextKey.zone) == null) {
String[] zones = client.getAvailabilityZones(client.getRegion());
String zone = zones != null && zones.length > 0 ? zones[0] : null;
if (zone != null) {
// You can set this with archaius.deployment.* (maybe requires // You can set this with archaius.deployment.* (maybe requires
// custom deployment context)? // custom deployment context)?
String zone = instance.getMetadataMap().get("zone");
if (zone == null && instance.getDataCenterInfo() instanceof AmazonInfo) {
AmazonInfo info = (AmazonInfo) instance.getDataCenterInfo();
zone = info.getMetadata().get(AmazonInfo.MetaDataKey.availabilityZone);
}
if (zone != null) {
ConfigurationManager.getDeploymentContext().setValue(ContextKey.zone, ConfigurationManager.getDeploymentContext().setValue(ContextKey.zone,
zone); zone);
} }
...@@ -71,10 +67,10 @@ public class EurekaRibbonInitializer implements ServerListInitializer { ...@@ -71,10 +67,10 @@ public class EurekaRibbonInitializer implements ServerListInitializer {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
DynamicServerListLoadBalancer<Server> dynamic = (DynamicServerListLoadBalancer<Server>) balancer; DynamicServerListLoadBalancer<Server> dynamic = (DynamicServerListLoadBalancer<Server>) balancer;
ServerList<Server> list = dynamic.getServerListImpl(); ServerList<Server> list = dynamic.getServerListImpl();
if (!(list instanceof DomainExtractingServerList) if (!(list instanceof DomainExtractingServerList)) {
&& !(instance.getDataCenterInfo() instanceof AmazonInfo)) { // This is optional: you can use the native Eureka AWS features as long as
// This is optional: you can use the native Eureka AWS features by making // the server zone is populated. TODO: find a way to back off if AWS
// the EurekaInstanceConfig.dataCenterInfo an AmazonInfo // metadata *is* available.
dynamic.setServerListImpl(new DomainExtractingServerList(list)); dynamic.setServerListImpl(new DomainExtractingServerList(list));
} }
} }
......
...@@ -15,9 +15,6 @@ ...@@ -15,9 +15,6 @@
*/ */
package org.springframework.cloud.netflix.ribbon.eureka; 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.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
...@@ -28,6 +25,9 @@ import org.springframework.cloud.netflix.ribbon.ServerListInitializer; ...@@ -28,6 +25,9 @@ import org.springframework.cloud.netflix.ribbon.ServerListInitializer;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import com.netflix.discovery.EurekaClientConfig;
import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList;
/** /**
* @author Dave Syer * @author Dave Syer
* *
...@@ -40,10 +40,10 @@ import org.springframework.context.annotation.Configuration; ...@@ -40,10 +40,10 @@ import org.springframework.context.annotation.Configuration;
public class RibbonEurekaAutoConfiguration { public class RibbonEurekaAutoConfiguration {
@Autowired(required=false) @Autowired(required=false)
private EurekaInstanceConfig instance; private EurekaClientConfig client;
@Bean @Bean
public ServerListInitializer serverListInitializer() { public ServerListInitializer serverListInitializer() {
return new EurekaRibbonInitializer(instance); return new EurekaRibbonInitializer(client);
} }
} }
...@@ -21,7 +21,7 @@ import static org.junit.Assert.assertTrue; ...@@ -21,7 +21,7 @@ import static org.junit.Assert.assertTrue;
import org.junit.After; import org.junit.After;
import org.junit.Test; 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.client.ClientFactory;
import com.netflix.config.ConfigurationManager; import com.netflix.config.ConfigurationManager;
...@@ -43,10 +43,10 @@ public class EurekaRibbonInitializerTests { ...@@ -43,10 +43,10 @@ public class EurekaRibbonInitializerTests {
@Test @Test
public void basicConfigurationCreatedForLoadBalancer() { public void basicConfigurationCreatedForLoadBalancer() {
EurekaInstanceConfigBean instance = new EurekaInstanceConfigBean(); EurekaClientConfigBean client = new EurekaClientConfigBean();
instance.getMetadataMap().put("zone", "foo"); client.getAvailabilityZones().put(client.getRegion(), "foo");
EurekaRibbonInitializer initializer = new EurekaRibbonInitializer( EurekaRibbonInitializer initializer = new EurekaRibbonInitializer(
instance); client);
initializer.initialize("service"); initializer.initialize("service");
ILoadBalancer balancer = ClientFactory.getNamedLoadBalancer("service"); ILoadBalancer balancer = ClientFactory.getNamedLoadBalancer("service");
assertNotNull(balancer); assertNotNull(balancer);
......
...@@ -36,7 +36,7 @@ public class EurekaServerConfiguration extends WebMvcConfigurerAdapter { ...@@ -36,7 +36,7 @@ public class EurekaServerConfiguration extends WebMvcConfigurerAdapter {
bean.setOrder(Ordered.LOWEST_PRECEDENCE); bean.setOrder(Ordered.LOWEST_PRECEDENCE);
bean.addInitParameter("com.sun.jersey.config.property.packages", bean.addInitParameter("com.sun.jersey.config.property.packages",
"com.netflix.discovery;com.netflix.eureka"); "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/*")); bean.setUrlPatterns(Lists.newArrayList("/v2/*"));
return bean; return bean;
} }
......
...@@ -30,7 +30,7 @@ import org.springframework.beans.factory.annotation.Autowired; ...@@ -30,7 +30,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties; 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.EurekaServerConfigBean;
import org.springframework.cloud.netflix.eureka.server.advice.LeaseManagerLite; import org.springframework.cloud.netflix.eureka.server.advice.LeaseManagerLite;
import org.springframework.cloud.netflix.eureka.server.advice.PiggybackMethodInterceptor; import org.springframework.cloud.netflix.eureka.server.advice.PiggybackMethodInterceptor;
...@@ -82,9 +82,9 @@ public class EurekaServerInitializerConfiguration implements ServletContextAware ...@@ -82,9 +82,9 @@ public class EurekaServerInitializerConfiguration implements ServletContextAware
} }
@Bean @Bean
@ConditionalOnMissingBean(DiscoveryManagerIntitializer.class) @ConditionalOnMissingBean(DiscoveryManagerInitializer.class)
public DiscoveryManagerIntitializer discoveryManagerIntitializer() { public DiscoveryManagerInitializer discoveryManagerIntitializer() {
return new DiscoveryManagerIntitializer(); return new DiscoveryManagerInitializer();
} }
@Override @Override
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment