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;
/**
* @author Spencer Gibb
*/
public class DiscoveryManagerIntitializer {
public class DiscoveryManagerInitializer {
@Autowired
private EurekaClientConfigBean clientConfig;
......
......@@ -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;
......
......@@ -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
......
......@@ -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<Server> {
private List<Server> setZones(List<Server> servers) {
for (Server server : servers) {
if (!server.getZone().equals("default")) {
String zone = extractApproximateZone(server.getId());
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();
private String extractApproximateZone(Server server) {
String host = server.getHost();
if (!host.contains(".")) {
return host;
}
String[] split = StringUtils.split(host, ".");
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]);
}
return builder.toString();
}
catch (MalformedURLException e) {
}
return "defaultZone";
}
}
......@@ -8,11 +8,10 @@ import static com.netflix.client.config.CommonClientConfigKey.NIWSServerListFilt
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.config.ConfigurationManager;
import com.netflix.config.DeploymentContext.ContextKey;
import com.netflix.discovery.EurekaClientConfig;
import com.netflix.loadbalancer.DynamicServerListLoadBalancer;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
......@@ -29,24 +28,21 @@ import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList;
*/
public class EurekaRibbonInitializer implements ServerListInitializer {
private EurekaInstanceConfig instance;
private EurekaClientConfig client;
public EurekaRibbonInitializer(EurekaInstanceConfig instance) {
this.instance = instance;
public EurekaRibbonInitializer(EurekaClientConfig client) {
this.client = client;
}
@Override
public void initialize(String serviceId) {
if (instance != null
if (client != 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
// 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,
zone);
}
......@@ -71,10 +67,10 @@ public class EurekaRibbonInitializer implements ServerListInitializer {
@SuppressWarnings("unchecked")
DynamicServerListLoadBalancer<Server> dynamic = (DynamicServerListLoadBalancer<Server>) balancer;
ServerList<Server> 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));
}
}
......
......@@ -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);
}
}
......@@ -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);
......
......@@ -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;
}
......
......@@ -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
......
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