create SpringClientFactory for ribbon to not fail on client creation if LoadBalancer is already created. SpringClientFactory is not a static factory, but an instance factory.
Remove unused hystrix configuration classes.
This commit is contained in:
@@ -27,7 +27,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
||||
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.cloud.netflix.EurekaDiscoverClient;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
import org.springframework.cloud.netflix.servo.ServoMetricReader;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.SmartLifecycle;
|
||||
@@ -140,7 +140,12 @@ public class EurekaClientConfiguration implements SmartLifecycle, Ordered {
|
||||
|
||||
@Bean
|
||||
public DiscoveryClient discoveryClient() {
|
||||
return new EurekaDiscoverClient();
|
||||
return new EurekaDiscoveryClient();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SpringClientFactory springClientFactory() {
|
||||
return new SpringClientFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.springframework.cloud.netflix;
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
@@ -8,7 +8,7 @@ import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class EurekaDiscoverClient implements DiscoveryClient {
|
||||
public class EurekaDiscoveryClient implements DiscoveryClient {
|
||||
|
||||
@Autowired
|
||||
private EurekaInstanceConfigBean config;
|
||||
@@ -15,9 +15,7 @@
|
||||
*/
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import org.springframework.context.annotation.AdviceMode;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@@ -27,34 +25,6 @@ import java.lang.annotation.*;
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Import(HystrixConfigurationSelector.class)
|
||||
@Import(HystrixConfiguration.class)
|
||||
public @interface EnableHystrix {
|
||||
|
||||
/**
|
||||
* Indicate whether subclass-based (CGLIB) proxies are to be created ({@code true}) as
|
||||
* opposed to standard Java interface-based proxies ({@code false}). The default is
|
||||
* {@code false}. <strong>Applicable only if {@link #mode()} is set to
|
||||
* {@link org.springframework.context.annotation.AdviceMode#PROXY}</strong>.
|
||||
* <p>Note that setting this attribute to {@code true} will affect <em>all</em>
|
||||
* Spring-managed beans requiring proxying, not just those marked with
|
||||
* {@code @Transactional}. For example, other beans marked with Spring's
|
||||
* {@code @Async} annotation will be upgraded to subclass proxying at the same
|
||||
* time. This approach has no negative impact in practice unless one is explicitly
|
||||
* expecting one type of proxy vs another, e.g. in tests.
|
||||
*/
|
||||
boolean proxyTargetClass() default false;
|
||||
|
||||
/**
|
||||
* Indicate how transactional advice should be applied. The default is
|
||||
* {@link org.springframework.context.annotation.AdviceMode#PROXY}.
|
||||
* @see org.springframework.context.annotation.AdviceMode
|
||||
*/
|
||||
AdviceMode mode() default AdviceMode.PROXY;
|
||||
|
||||
/**
|
||||
* Indicate the ordering of the execution of the transaction advisor
|
||||
* when multiple advices are applied at a specific joinpoint.
|
||||
* The default is {@link org.springframework.core.Ordered#LOWEST_PRECEDENCE}.
|
||||
*/
|
||||
int order() default Ordered.LOWEST_PRECEDENCE;
|
||||
}
|
||||
@@ -29,6 +29,7 @@ import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.metrics.GaugeService;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.context.SmartLifecycle;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -65,7 +66,7 @@ public class HystrixConfiguration implements ImportAware {
|
||||
}
|
||||
|
||||
@Bean
|
||||
// TODO: add enable/disable
|
||||
@ConditionalOnExpression("${hystrix.stream.endpoint.enabled:true}")
|
||||
// TODO: make it @ConditionalOnWebApp (need a nested class)
|
||||
public HystrixStreamEndpoint hystrixStreamEndpoint() {
|
||||
return new HystrixStreamEndpoint();
|
||||
@@ -81,20 +82,6 @@ public class HystrixConfiguration implements ImportAware {
|
||||
+ importMetadata.getClassName());
|
||||
}
|
||||
|
||||
@Autowired(required = false)
|
||||
void setConfigurers(Collection<HystrixConfigurer> configurers) {
|
||||
if (CollectionUtils.isEmpty(configurers)) {
|
||||
return;
|
||||
}
|
||||
if (configurers.size() > 1) {
|
||||
throw new IllegalStateException(
|
||||
"Only one HystrixConfigurer may exist");
|
||||
}
|
||||
// TODO: create CircuitBreakerConfigurer API
|
||||
// CircuitBreakerConfigurer configurer = configurers.iterator().next();
|
||||
// this.txManager = configurer.annotationDrivenTransactionManager();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(GaugeService.class)
|
||||
protected static class HystrixMetricsPollerConfiguration implements SmartLifecycle {
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2014 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.hystrix;
|
||||
|
||||
import org.springframework.context.annotation.AdviceMode;
|
||||
import org.springframework.context.annotation.AdviceModeImportSelector;
|
||||
import org.springframework.context.annotation.AutoProxyRegistrar;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class HystrixConfigurationSelector extends AdviceModeImportSelector<EnableHystrix> {
|
||||
|
||||
/**
|
||||
* The name of the AspectJ transaction management @{@code Configuration} class.
|
||||
*/
|
||||
private static final String TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME =
|
||||
"org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration";
|
||||
|
||||
@Override
|
||||
protected String[] selectImports(AdviceMode adviceMode) {
|
||||
switch (adviceMode) {
|
||||
case PROXY:
|
||||
return new String[]{AutoProxyRegistrar.class.getName(), HystrixConfiguration.class.getName()};
|
||||
case ASPECTJ:
|
||||
return new String[]{TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2014 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.hystrix;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public interface HystrixConfigurer {
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
|
||||
|
||||
import com.netflix.client.ClientFactory;
|
||||
import com.netflix.loadbalancer.BaseLoadBalancer;
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
@@ -22,6 +21,9 @@ public class RibbonLoadBalancerClient implements LoadBalancerClient {
|
||||
@Autowired
|
||||
private ServerListInitializer serverListInitializer;
|
||||
|
||||
@Autowired
|
||||
private SpringClientFactory clientFactory;
|
||||
|
||||
private Map<String, ILoadBalancer> balancers = new HashMap<String, ILoadBalancer>();
|
||||
|
||||
public RibbonLoadBalancerClient(List<BaseLoadBalancer> balancers) {
|
||||
@@ -35,7 +37,7 @@ public class RibbonLoadBalancerClient implements LoadBalancerClient {
|
||||
serverListInitializer.initialize(serviceId);
|
||||
ILoadBalancer loadBalancer = this.balancers.get(serviceId);
|
||||
if (loadBalancer == null) {
|
||||
loadBalancer = ClientFactory.getNamedLoadBalancer(serviceId);
|
||||
loadBalancer = clientFactory.getNamedLoadBalancer(serviceId);
|
||||
}
|
||||
Server server = loadBalancer.chooseServer("default");
|
||||
if (server == null) {
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.netflix.client.AbstractLoadBalancerAwareClient;
|
||||
import com.netflix.client.ClientException;
|
||||
import com.netflix.client.IClient;
|
||||
import com.netflix.client.IClientConfigAware;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import com.netflix.client.config.CommonClientConfigKey;
|
||||
import com.netflix.client.config.DefaultClientConfigImpl;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import com.netflix.servo.monitor.Monitors;
|
||||
|
||||
/**
|
||||
* A factory that creates client, load balancer and client configuration instances from properties. It also keeps mappings of client names to
|
||||
* the created instances.
|
||||
*
|
||||
*/
|
||||
@Slf4j
|
||||
public class SpringClientFactory {
|
||||
|
||||
private Map<String, IClient<?,?>> simpleClientMap = new ConcurrentHashMap<>();
|
||||
private Map<String, ILoadBalancer> namedLBMap = new ConcurrentHashMap<>();
|
||||
private ConcurrentHashMap<String, IClientConfig> namedConfig = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Utility method to create client and load balancer (if enabled in client config) given the name and client config.
|
||||
* Instances are created using reflection (see {@link #instantiateInstanceWithClientConfig(String, IClientConfig)}
|
||||
*
|
||||
* @param restClientName
|
||||
* @param clientConfig
|
||||
* @throws ClientException if any errors occurs in the process, or if the client with the same name already exists
|
||||
*/
|
||||
public synchronized IClient<?, ?> registerClientFromProperties(String restClientName, IClientConfig clientConfig) throws ClientException {
|
||||
IClient<?, ?> client;
|
||||
ILoadBalancer loadBalancer = null;
|
||||
if (simpleClientMap.get(restClientName) != null) {
|
||||
throw new ClientException(
|
||||
ClientException.ErrorType.GENERAL,
|
||||
"A Rest Client with this name is already registered. Please use a different name");
|
||||
}
|
||||
try {
|
||||
String clientClassName = (String) clientConfig.getProperty(CommonClientConfigKey.ClientClassName);
|
||||
client = (IClient<?, ?>) instantiateInstanceWithClientConfig(clientClassName, clientConfig);
|
||||
boolean initializeNFLoadBalancer = Boolean.parseBoolean(clientConfig.getProperty(
|
||||
CommonClientConfigKey.InitializeNFLoadBalancer, DefaultClientConfigImpl.DEFAULT_ENABLE_LOADBALANCER).toString());
|
||||
if (initializeNFLoadBalancer) {
|
||||
loadBalancer = getNamedLoadBalancer(restClientName, clientConfig.getClass());
|
||||
}
|
||||
if (client instanceof AbstractLoadBalancerAwareClient) {
|
||||
((AbstractLoadBalancerAwareClient) client).setLoadBalancer(loadBalancer);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
String message = "Unable to InitializeAndAssociateNFLoadBalancer set for RestClient:"
|
||||
+ restClientName;
|
||||
log.warn(message, e);
|
||||
throw new ClientException(ClientException.ErrorType.CONFIGURATION,
|
||||
message, e);
|
||||
}
|
||||
simpleClientMap.put(restClientName, client);
|
||||
|
||||
Monitors.registerObject("Client_" + restClientName, client);
|
||||
|
||||
log.info("Client Registered:" + client.toString());
|
||||
return client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the named client from map if already created. Otherwise creates the client using the configuration returned by {@link #getNamedConfig(String)}.
|
||||
*
|
||||
* @throws RuntimeException if an error occurs in creating the client.
|
||||
*/
|
||||
public synchronized IClient getNamedClient(String name) {
|
||||
return getNamedClient(name, DefaultClientConfigImpl.class);
|
||||
}
|
||||
|
||||
public synchronized <C extends IClient> C namedClient(String name, Class<C> clientClass) {
|
||||
return clientClass.cast(getNamedClient(name, DefaultClientConfigImpl.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the named client from map if already created. Otherwise creates the client using the configuration returned by {@link #createNamedClient(String, Class)}.
|
||||
*
|
||||
* @throws RuntimeException if an error occurs in creating the client.
|
||||
*/
|
||||
public synchronized IClient getNamedClient(String name, Class<? extends IClientConfig> configClass) {
|
||||
if (simpleClientMap.get(name) != null) {
|
||||
return simpleClientMap.get(name);
|
||||
}
|
||||
try {
|
||||
return createNamedClient(name, configClass);
|
||||
} catch (ClientException e) {
|
||||
throw new RuntimeException("Unable to create client", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a named client using a IClientConfig instance created off the configClass class object passed in as the parameter.
|
||||
*
|
||||
* @throws ClientException if any error occurs, or if the client with the same name already exists
|
||||
*/
|
||||
public synchronized IClient createNamedClient(String name, Class<? extends IClientConfig> configClass) throws ClientException {
|
||||
IClientConfig config = getNamedConfig(name, configClass);
|
||||
return registerClientFromProperties(name, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the load balancer associated with the name, or create one with an instance {@link DefaultClientConfigImpl} if does not exist
|
||||
*
|
||||
* @throws RuntimeException if any error occurs
|
||||
*/
|
||||
public synchronized ILoadBalancer getNamedLoadBalancer(String name) {
|
||||
return getNamedLoadBalancer(name, DefaultClientConfigImpl.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the load balancer associated with the name, or create one with an instance of configClass if does not exist
|
||||
*
|
||||
* @throws RuntimeException if any error occurs
|
||||
* @see #registerNamedLoadBalancerFromProperties(String, Class)
|
||||
*/
|
||||
public synchronized ILoadBalancer getNamedLoadBalancer(String name, Class<? extends IClientConfig> configClass) {
|
||||
ILoadBalancer lb = namedLBMap.get(name);
|
||||
if (lb != null) {
|
||||
return lb;
|
||||
} else {
|
||||
try {
|
||||
lb = registerNamedLoadBalancerFromProperties(name, configClass);
|
||||
} catch (ClientException e) {
|
||||
throw new RuntimeException("Unable to create load balancer", e);
|
||||
}
|
||||
return lb;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and register a load balancer with the name and given the class of configClass.
|
||||
*
|
||||
* @throws ClientException if load balancer with the same name already exists or any error occurs
|
||||
* @see #instantiateInstanceWithClientConfig(String, IClientConfig)
|
||||
*/
|
||||
public ILoadBalancer registerNamedLoadBalancerFromclientConfig(String name, IClientConfig clientConfig) throws ClientException {
|
||||
if (namedLBMap.get(name) != null) {
|
||||
throw new ClientException("LoadBalancer for name " + name + " already exists");
|
||||
}
|
||||
ILoadBalancer lb = null;
|
||||
try {
|
||||
String loadBalancerClassName = (String) clientConfig.getProperty(CommonClientConfigKey.NFLoadBalancerClassName);
|
||||
lb = (ILoadBalancer) instantiateInstanceWithClientConfig(loadBalancerClassName, clientConfig);
|
||||
namedLBMap.put(name, lb);
|
||||
log.info("Client:" + name
|
||||
+ " instantiated a LoadBalancer:" + lb.toString());
|
||||
return lb;
|
||||
} catch (Exception e) {
|
||||
throw new ClientException("Unable to instantiate/associate LoadBalancer with Client:" + name, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and register a load balancer with the name and given the class of configClass.
|
||||
*
|
||||
* @throws ClientException if load balancer with the same name already exists or any error occurs
|
||||
* @see #instantiateInstanceWithClientConfig(String, IClientConfig)
|
||||
*/
|
||||
public synchronized ILoadBalancer registerNamedLoadBalancerFromProperties(String name, Class<? extends IClientConfig> configClass) throws ClientException {
|
||||
if (namedLBMap.get(name) != null) {
|
||||
throw new ClientException("LoadBalancer for name " + name + " already exists");
|
||||
}
|
||||
IClientConfig clientConfig = getNamedConfig(name, configClass);
|
||||
return registerNamedLoadBalancerFromclientConfig(name, clientConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates instance related to client framework using reflection. It first checks if the object is an instance of
|
||||
* {@link IClientConfigAware} and if so invoke {@link IClientConfigAware#initWithNiwsConfig(IClientConfig)}. If that does not
|
||||
* apply, it tries to find if there is a constructor with {@link IClientConfig} as a parameter and if so invoke that constructor. If neither applies,
|
||||
* it simply invokes the no-arg constructor and ignores the clientConfig parameter.
|
||||
*
|
||||
* @param className Class name of the object
|
||||
* @param clientConfig IClientConfig object used for initialization.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object instantiateInstanceWithClientConfig(String className, IClientConfig clientConfig)
|
||||
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
|
||||
Class clazz = Class.forName(className);
|
||||
if (IClientConfigAware.class.isAssignableFrom(clazz)) {
|
||||
IClientConfigAware obj = (IClientConfigAware) clazz.newInstance();
|
||||
obj.initWithNiwsConfig(clientConfig);
|
||||
return obj;
|
||||
} else {
|
||||
try {
|
||||
if (clazz.getConstructor(IClientConfig.class) != null) {
|
||||
return clazz.getConstructor(IClientConfig.class).newInstance(clientConfig);
|
||||
}
|
||||
} catch (Throwable e) { // NOPMD
|
||||
}
|
||||
}
|
||||
log.warn("Class " + className + " neither implements IClientConfigAware nor provides a constructor with IClientConfig as the parameter. Only default constructor will be used.");
|
||||
return clazz.newInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the client configuration given the name or create one with {@link DefaultClientConfigImpl} if it does not exist.
|
||||
*
|
||||
* @see #getNamedConfig(String, Class)
|
||||
*/
|
||||
public IClientConfig getNamedConfig(String name) {
|
||||
return getNamedConfig(name, DefaultClientConfigImpl.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the client configuration given the name or create one with clientConfigClass if it does not exist. An instance of IClientConfig
|
||||
* is created and {@link IClientConfig#loadProperties(String)} will be called.
|
||||
*/
|
||||
public IClientConfig getNamedConfig(String name, Class<? extends IClientConfig> clientConfigClass) {
|
||||
IClientConfig config = namedConfig.get(name);
|
||||
if (config != null) {
|
||||
return config;
|
||||
} else {
|
||||
try {
|
||||
config = (IClientConfig) clientConfigClass.newInstance();
|
||||
config.loadProperties(name);
|
||||
} catch (Throwable e) {
|
||||
log.error("Unable to create client config instance", e);
|
||||
return null;
|
||||
}
|
||||
config.loadProperties(name);
|
||||
IClientConfig old = namedConfig.putIfAbsent(name, config);
|
||||
if (old != null) {
|
||||
config = old;
|
||||
}
|
||||
return config;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,9 +6,9 @@ import static com.netflix.client.config.CommonClientConfigKey.NFLoadBalancerRule
|
||||
import static com.netflix.client.config.CommonClientConfigKey.NIWSServerListClassName;
|
||||
import static com.netflix.client.config.CommonClientConfigKey.NIWSServerListFilterClassName;
|
||||
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
import org.springframework.cloud.netflix.ribbon.ServerListInitializer;
|
||||
|
||||
import com.netflix.client.ClientFactory;
|
||||
import com.netflix.config.ConfigurationManager;
|
||||
import com.netflix.config.DeploymentContext.ContextKey;
|
||||
import com.netflix.discovery.EurekaClientConfig;
|
||||
@@ -28,17 +28,19 @@ import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList;
|
||||
*/
|
||||
public class EurekaRibbonInitializer implements ServerListInitializer {
|
||||
|
||||
private EurekaClientConfig client;
|
||||
private EurekaClientConfig clientConfig;
|
||||
private SpringClientFactory clientFactory;
|
||||
|
||||
public EurekaRibbonInitializer(EurekaClientConfig client) {
|
||||
this.client = client;
|
||||
}
|
||||
public EurekaRibbonInitializer(EurekaClientConfig clientConfig, SpringClientFactory clientFactory) {
|
||||
this.clientConfig = clientConfig;
|
||||
this.clientFactory = clientFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(String serviceId) {
|
||||
if (client != null
|
||||
if (clientConfig != null
|
||||
&& ConfigurationManager.getDeploymentContext().getValue(ContextKey.zone) == null) {
|
||||
String[] zones = client.getAvailabilityZones(client.getRegion());
|
||||
String[] zones = clientConfig.getAvailabilityZones(clientConfig.getRegion());
|
||||
String zone = zones != null && zones.length > 0 ? zones[0] : null;
|
||||
if (zone != null) {
|
||||
// You can set this with archaius.deployment.* (maybe requires
|
||||
@@ -58,7 +60,7 @@ public class EurekaRibbonInitializer implements ServerListInitializer {
|
||||
setProp(serviceId, NIWSServerListFilterClassName.key(),
|
||||
ZonePreferenceServerListFilter.class.getName());
|
||||
setProp(serviceId, EnableZoneAffinity.key(), "true");
|
||||
ILoadBalancer loadBalancer = ClientFactory.getNamedLoadBalancer(serviceId);
|
||||
ILoadBalancer loadBalancer = clientFactory.getNamedLoadBalancer(serviceId);
|
||||
wrapServerList(loadBalancer);
|
||||
}
|
||||
|
||||
@@ -71,6 +73,7 @@ public class EurekaRibbonInitializer implements ServerListInitializer {
|
||||
// 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.
|
||||
// @see com.netflix.appinfo.AmazonInfo.Builder
|
||||
dynamic.setServerListImpl(new DomainExtractingServerList(list));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.ServerListInitializer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -40,10 +41,10 @@ import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList;
|
||||
public class RibbonEurekaAutoConfiguration {
|
||||
|
||||
@Autowired(required=false)
|
||||
private EurekaClientConfig client;
|
||||
private EurekaClientConfig clientConfig;
|
||||
|
||||
@Bean
|
||||
public ServerListInitializer serverListInitializer() {
|
||||
return new EurekaRibbonInitializer(client);
|
||||
public ServerListInitializer serverListInitializer(SpringClientFactory clientFactory) {
|
||||
return new EurekaRibbonInitializer(clientConfig, clientFactory);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,13 +16,13 @@ import org.apache.commons.io.IOUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.actuate.trace.TraceRepository;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
import org.springframework.cloud.netflix.ribbon.ServerListInitializer;
|
||||
import org.springframework.cloud.netflix.zuul.RibbonCommand;
|
||||
import org.springframework.cloud.netflix.zuul.SpringFilter;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.netflix.client.ClientException;
|
||||
import com.netflix.client.ClientFactory;
|
||||
import com.netflix.client.http.HttpRequest.Verb;
|
||||
import com.netflix.client.http.HttpResponse;
|
||||
import com.netflix.hystrix.exception.HystrixRuntimeException;
|
||||
@@ -71,10 +71,9 @@ public class RibbonRoutingFilter extends SpringFilter {
|
||||
|
||||
String serviceId = (String) context.get("serviceId");
|
||||
|
||||
//TODO: should this be an interface or just config?
|
||||
getBean(ServerListInitializer.class).initialize(serviceId);
|
||||
|
||||
RestClient restClient = (RestClient) ClientFactory.getNamedClient(serviceId);
|
||||
RestClient restClient = getBean(SpringClientFactory.class).namedClient(serviceId, RestClient.class);
|
||||
|
||||
String uri = request.getRequestURI();
|
||||
if (context.get("requestURI") != null) {
|
||||
|
||||
@@ -21,9 +21,9 @@ import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean;
|
||||
|
||||
import com.netflix.client.ClientFactory;
|
||||
import com.netflix.config.ConfigurationManager;
|
||||
import com.netflix.config.DeploymentContext.ContextKey;
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
@@ -45,10 +45,11 @@ public class EurekaRibbonInitializerTests {
|
||||
public void basicConfigurationCreatedForLoadBalancer() {
|
||||
EurekaClientConfigBean client = new EurekaClientConfigBean();
|
||||
client.getAvailabilityZones().put(client.getRegion(), "foo");
|
||||
EurekaRibbonInitializer initializer = new EurekaRibbonInitializer(
|
||||
client);
|
||||
SpringClientFactory clientFactory = new SpringClientFactory();
|
||||
EurekaRibbonInitializer initializer = new EurekaRibbonInitializer(
|
||||
client, clientFactory);
|
||||
initializer.initialize("service");
|
||||
ILoadBalancer balancer = ClientFactory.getNamedLoadBalancer("service");
|
||||
ILoadBalancer balancer = clientFactory.getNamedLoadBalancer("service");
|
||||
assertNotNull(balancer);
|
||||
@SuppressWarnings("unchecked")
|
||||
ZoneAwareLoadBalancer<Server> aware = (ZoneAwareLoadBalancer<Server>) balancer;
|
||||
|
||||
Reference in New Issue
Block a user