Sets the zone based on the hostname of the service if approximateZoneFromHostname is true.
The flag has always been there, it just isn't carried through to the ribbon client configuration without this change if I understand this change correctly. Fixes gh-315, fixes gh-423.
This commit is contained in:
@@ -22,8 +22,6 @@ import java.util.List;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.client.config.CommonClientConfigKey;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
@@ -92,7 +90,7 @@ class DomainExtractingServer extends DiscoveryEnabledServer {
|
||||
setZone(server.getInstanceInfo().getMetadata().get("zone"));
|
||||
}
|
||||
else if (approximateZoneFromHostname) {
|
||||
setZone(extractApproximateZone(server));
|
||||
setZone(ZoneUtils.extractApproximateZone(server.getHost()));
|
||||
}
|
||||
else {
|
||||
setZone(server.getZone());
|
||||
@@ -112,18 +110,4 @@ class DomainExtractingServer extends DiscoveryEnabledServer {
|
||||
}
|
||||
return super.getId();
|
||||
}
|
||||
|
||||
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++) {
|
||||
builder.append(".").append(split[i]);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,11 +21,15 @@ import static com.netflix.client.config.CommonClientConfigKey.EnableZoneAffinity
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.config.ConfigurationManager;
|
||||
@@ -45,8 +49,10 @@ import com.netflix.niws.loadbalancer.NIWSDiscoveryPing;
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
* @author Dave Syer
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@Configuration
|
||||
@CommonsLog
|
||||
public class EurekaRibbonClientConfiguration {
|
||||
|
||||
@Value("${ribbon.eureka.approximateZoneFromHostname:false}")
|
||||
@@ -62,13 +68,19 @@ public class EurekaRibbonClientConfiguration {
|
||||
@Autowired(required = false)
|
||||
private EurekaClientConfig clientConfig;
|
||||
|
||||
@Autowired
|
||||
private EurekaInstanceConfigBean eurekaConfig;
|
||||
|
||||
public EurekaRibbonClientConfiguration() {
|
||||
}
|
||||
|
||||
public EurekaRibbonClientConfiguration(EurekaClientConfig clientConfig,
|
||||
String serviceId) {
|
||||
String serviceId, EurekaInstanceConfigBean eurekaConfig,
|
||||
boolean approximateZoneFromHostname) {
|
||||
this.clientConfig = clientConfig;
|
||||
this.serviceId = serviceId;
|
||||
this.eurekaConfig = eurekaConfig;
|
||||
this.approximateZoneFromHostname = approximateZoneFromHostname;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -82,23 +94,36 @@ public class EurekaRibbonClientConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ServerList<?> ribbonServerList(IClientConfig config) {
|
||||
DiscoveryEnabledNIWSServerList discoveryServerList = new DiscoveryEnabledNIWSServerList(config);
|
||||
DomainExtractingServerList serverList = new DomainExtractingServerList(discoveryServerList, config, this.approximateZoneFromHostname);
|
||||
DiscoveryEnabledNIWSServerList discoveryServerList = new DiscoveryEnabledNIWSServerList(
|
||||
config);
|
||||
DomainExtractingServerList serverList = new DomainExtractingServerList(
|
||||
discoveryServerList, config, this.approximateZoneFromHostname);
|
||||
return serverList;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void preprocess() {
|
||||
if (this.clientConfig != null
|
||||
&& ConfigurationManager.getDeploymentContext().getValue(ContextKey.zone) == null) {
|
||||
String[] zones = this.clientConfig.getAvailabilityZones(this.clientConfig
|
||||
.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 = ConfigurationManager.getDeploymentContext().getValue(
|
||||
ContextKey.zone);
|
||||
if (this.clientConfig != null && StringUtils.isEmpty(zone)) {
|
||||
if (approximateZoneFromHostname) {
|
||||
String approxZone = ZoneUtils.extractApproximateZone(eurekaConfig
|
||||
.getHostname());
|
||||
log.debug("Setting Zone To " + approxZone);
|
||||
ConfigurationManager.getDeploymentContext().setValue(ContextKey.zone,
|
||||
zone);
|
||||
approxZone);
|
||||
}
|
||||
else {
|
||||
String[] zones = this.clientConfig.getAvailabilityZones(this.clientConfig
|
||||
.getRegion());
|
||||
String availabilityZone = zones != null && zones.length > 0 ? zones[0]
|
||||
: null;
|
||||
if (availabilityZone != null) {
|
||||
// You can set this with archaius.deployment.* (maybe requires
|
||||
// custom deployment context)?
|
||||
ConfigurationManager.getDeploymentContext().setValue(ContextKey.zone,
|
||||
availabilityZone);
|
||||
}
|
||||
}
|
||||
}
|
||||
setProp(this.serviceId, DeploymentContextBasedVipAddresses.key(), this.serviceId);
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.cloud.netflix.ribbon.eureka;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Utility class for dealing with zones.
|
||||
* @author Ryan Baxter
|
||||
*
|
||||
*/
|
||||
public class ZoneUtils {
|
||||
|
||||
/**
|
||||
* Approximates Eureka zones from a host name. This method approximates the zone to be
|
||||
* everything after the first "." in the host name.
|
||||
* @param host The host name to extract the host name from
|
||||
* @return The approximate zone
|
||||
*/
|
||||
public static String extractApproximateZone(String host) {
|
||||
if (!host.contains(".")) {
|
||||
return host;
|
||||
}
|
||||
String[] split = StringUtils.split(host, ".");
|
||||
StringBuilder builder = new StringBuilder(split[1]);
|
||||
for (int i = 2; i < split.length; i++) {
|
||||
builder.append(".").append(split[i]);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,10 +16,17 @@
|
||||
|
||||
package org.springframework.cloud.netflix.ribbon.eureka;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.springframework.cloud.netflix.ribbon.eureka.EurekaRibbonClientConfiguration.VALUE_NOT_SET;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
|
||||
import com.netflix.config.ConfigurationManager;
|
||||
@@ -29,15 +36,14 @@ import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import com.netflix.loadbalancer.ZoneAwareLoadBalancer;
|
||||
import com.netflix.niws.loadbalancer.DiscoveryEnabledServer;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.cloud.netflix.ribbon.eureka.EurekaRibbonClientConfiguration.VALUE_NOT_SET;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public class EurekaRibbonClientConfigurationTests {
|
||||
|
||||
@After
|
||||
@Before
|
||||
public void close() {
|
||||
ConfigurationManager.getDeploymentContext().setValue(ContextKey.zone, "");
|
||||
}
|
||||
@@ -46,10 +52,11 @@ public class EurekaRibbonClientConfigurationTests {
|
||||
@Ignore
|
||||
public void basicConfigurationCreatedForLoadBalancer() {
|
||||
EurekaClientConfigBean client = new EurekaClientConfigBean();
|
||||
EurekaInstanceConfigBean configBean = new EurekaInstanceConfigBean();
|
||||
client.getAvailabilityZones().put(client.getRegion(), "foo");
|
||||
SpringClientFactory clientFactory = new SpringClientFactory();
|
||||
EurekaRibbonClientConfiguration clientPreprocessor = new EurekaRibbonClientConfiguration(
|
||||
client, "service");
|
||||
client, "service", configBean, false);
|
||||
clientPreprocessor.preprocess();
|
||||
ILoadBalancer balancer = clientFactory.getLoadBalancer("service");
|
||||
assertNotNull(balancer);
|
||||
@@ -63,8 +70,9 @@ public class EurekaRibbonClientConfigurationTests {
|
||||
@Test
|
||||
public void testSetProp() {
|
||||
EurekaClientConfigBean client = new EurekaClientConfigBean();
|
||||
EurekaInstanceConfigBean configBean = new EurekaInstanceConfigBean();
|
||||
EurekaRibbonClientConfiguration preprocessor = new EurekaRibbonClientConfiguration(
|
||||
client, "myService");
|
||||
client, "myService", configBean, false);
|
||||
String serviceId = "myService";
|
||||
String suffix = "mySuffix";
|
||||
String value = "myValue";
|
||||
@@ -76,5 +84,26 @@ public class EurekaRibbonClientConfigurationTests {
|
||||
preprocessor.setProp(serviceId, suffix, value);
|
||||
assertEquals("property has wrong value", value, property.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultZone() {
|
||||
EurekaClientConfigBean client = new EurekaClientConfigBean();
|
||||
EurekaInstanceConfigBean configBean = new EurekaInstanceConfigBean();
|
||||
EurekaRibbonClientConfiguration preprocessor = new EurekaRibbonClientConfiguration(
|
||||
client, "myService", configBean, false);
|
||||
preprocessor.preprocess();
|
||||
assertEquals("defaultZone", ConfigurationManager.getDeploymentContext().getValue(ContextKey.zone));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApproximateZone() {
|
||||
EurekaClientConfigBean client = new EurekaClientConfigBean();
|
||||
EurekaInstanceConfigBean configBean = new EurekaInstanceConfigBean();
|
||||
configBean.setHostname("this.is.a.test.com");
|
||||
EurekaRibbonClientConfiguration preprocessor = new EurekaRibbonClientConfiguration(
|
||||
client, "myService", configBean, true);
|
||||
preprocessor.preprocess();
|
||||
assertEquals("is.a.test.com", ConfigurationManager.getDeploymentContext().getValue(ContextKey.zone));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClient;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
@@ -98,6 +99,12 @@ public class RibbonClientPreprocessorIntegrationTests {
|
||||
filter.setZone("myTestZone");
|
||||
return filter;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public EurekaInstanceConfigBean getEurekaInstanceConfigBean() {
|
||||
EurekaInstanceConfigBean bean = new EurekaInstanceConfigBean();
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/* Copyright 2013-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.cloud.netflix.ribbon.eureka;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ryan Baxter
|
||||
*
|
||||
*/
|
||||
public class ZoneUtilsTest {
|
||||
|
||||
@Test
|
||||
public void extractApproximateZoneTest() {
|
||||
assertTrue("foo".equals(ZoneUtils.extractApproximateZone("foo")));
|
||||
assertTrue("bar".equals(ZoneUtils.extractApproximateZone("foo.bar")));
|
||||
assertTrue("world.foo.bar".equals(ZoneUtils
|
||||
.extractApproximateZone("hello.world.foo.bar")));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user