未验证 提交 a219149d 编写于 作者: E elandau 提交者: GitHub

Merge pull request #399 from elandau/feature/factory_api

Pluggable object creation
......@@ -29,6 +29,9 @@ import com.netflix.client.config.IClientConfig;
*
*/
public interface IClientConfigAware {
interface Factory {
Object create(String type, IClientConfig config) throws InstantiationException, IllegalAccessException, ClassNotFoundException;
}
/**
* Concrete implementation should implement this method so that the configuration set via
......@@ -36,6 +39,11 @@ public interface IClientConfigAware {
*
* @param clientConfig
*/
public abstract void initWithNiwsConfig(IClientConfig clientConfig);
default void initWithNiwsConfig(IClientConfig clientConfig) {
}
default void initWithNiwsConfig(IClientConfig clientConfig, Factory factory) {
initWithNiwsConfig(clientConfig);
}
}
......@@ -160,7 +160,7 @@ public abstract class CommonClientConfigKey<T> implements IClientConfigKey<T> {
public static final IClientConfigKey<Integer> NFLoadBalancerMaxTotalPingTime = new CommonClientConfigKey<Integer>("NFLoadBalancerMaxTotalPingTime"){};
public static final IClientConfigKey<String> NFLoadBalancerStatsClassName = new CommonClientConfigKey<String>("NFLoadBalancerStatsClassName"){};
public static final IClientConfigKey<String> NFLoadBalancerStatsClassName = new CommonClientConfigKey<String>("NFLoadBalancerStatsClassName", "com.netflix.loadbalancer.LoadBalancerStats"){};
public static final IClientConfigKey<String> NIWSServerListClassName = new CommonClientConfigKey<String>("NIWSServerListClassName", "com.netflix.loadbalancer.ConfigurationBasedServerList"){};
......
......@@ -45,11 +45,11 @@ public class ClientFactory {
private static ConcurrentHashMap<String, IClientConfig> namedConfig = new ConcurrentHashMap<String, IClientConfig>();
private static Logger logger = LoggerFactory.getLogger(ClientFactory.class);
/**
* Utility method to create client and load balancer (if enabled in client config) given the name and client config.
* 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
......@@ -236,7 +236,7 @@ public class ClientFactory {
logger.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 the resolved {@link ClientConfigFactory} if it does not exist.
*
......
......@@ -159,11 +159,11 @@ public class BaseLoadBalancer extends AbstractLoadBalancer implements
}
public BaseLoadBalancer(IClientConfig config, IRule rule, IPing ping) {
initWithConfig(config, rule, ping, createLoadBalancerStatsFromConfig(config));
initWithConfig(config, rule, ping, createLoadBalancerStatsFromConfig(config, ClientFactory::instantiateInstanceWithClientConfig));
}
void initWithConfig(IClientConfig clientConfig, IRule rule, IPing ping) {
initWithConfig(clientConfig, rule, ping, createLoadBalancerStatsFromConfig(config));
initWithConfig(clientConfig, rule, ping, createLoadBalancerStatsFromConfig(config, ClientFactory::instantiateInstanceWithClientConfig));
}
void initWithConfig(IClientConfig clientConfig, IRule rule, IPing ping, LoadBalancerStats stats) {
......@@ -208,29 +208,31 @@ public class BaseLoadBalancer extends AbstractLoadBalancer implements
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
try {
initWithNiwsConfig(clientConfig, ClientFactory::instantiateInstanceWithClientConfig);
} catch (Exception e) {
throw new RuntimeException("Error initializing load balancer", e);
}
}
@Override
public void initWithNiwsConfig(IClientConfig clientConfig, Factory factory) {
String ruleClassName = clientConfig.getOrDefault(CommonClientConfigKey.NFLoadBalancerRuleClassName);
String pingClassName = clientConfig.getOrDefault(CommonClientConfigKey.NFLoadBalancerPingClassName);
IRule rule;
IPing ping;
LoadBalancerStats stats;
try {
rule = (IRule) ClientFactory.instantiateInstanceWithClientConfig(
ruleClassName, clientConfig);
ping = (IPing) ClientFactory.instantiateInstanceWithClientConfig(
pingClassName, clientConfig);
stats = createLoadBalancerStatsFromConfig(clientConfig);
IRule rule = (IRule)factory.create(ruleClassName, clientConfig);
IPing ping = (IPing)factory.create(pingClassName, clientConfig);
LoadBalancerStats stats = createLoadBalancerStatsFromConfig(clientConfig, factory);
initWithConfig(clientConfig, rule, ping, stats);
} catch (Exception e) {
throw new RuntimeException("Error initializing load balancer", e);
}
initWithConfig(clientConfig, rule, ping, stats);
}
private LoadBalancerStats createLoadBalancerStatsFromConfig(IClientConfig clientConfig) {
String loadBalancerStatsClassName = clientConfig
.get(CommonClientConfigKey.NFLoadBalancerStatsClassName, LoadBalancerStats.class.getName());
private LoadBalancerStats createLoadBalancerStatsFromConfig(IClientConfig clientConfig, Factory factory) {
String loadBalancerStatsClassName = clientConfig.getOrDefault(CommonClientConfigKey.NFLoadBalancerStatsClassName);
try {
return (LoadBalancerStats) ClientFactory.instantiateInstanceWithClientConfig(
loadBalancerStatsClassName, clientConfig);
return (LoadBalancerStats) factory.create(loadBalancerStatsClassName, clientConfig);
} catch (Exception e) {
logger.warn("Error initializing configured LoadBalancerStats class - " + String.valueOf(loadBalancerStatsClassName)
+ ". Falling-back to a new LoadBalancerStats instance instead.", e);
......
......@@ -33,8 +33,4 @@ public class DummyPing extends AbstractLoadBalancerPing {
public boolean isAlive(Server server) {
return true;
}
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
}
}
......@@ -100,12 +100,17 @@ public class DynamicServerListLoadBalancer<T extends Server> extends BaseLoadBal
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
this.initWithNiwsConfig(clientConfig, ClientFactory::instantiateInstanceWithClientConfig);
}
@Override
public void initWithNiwsConfig(IClientConfig clientConfig, Factory factory) {
try {
super.initWithNiwsConfig(clientConfig);
super.initWithNiwsConfig(clientConfig, factory);
String niwsServerListClassName = clientConfig.getOrDefault(CommonClientConfigKey.NIWSServerListClassName);
ServerList<T> niwsServerListImpl = (ServerList<T>) ClientFactory
.instantiateInstanceWithClientConfig(niwsServerListClassName, clientConfig);
ServerList<T> niwsServerListImpl = (ServerList<T>) factory.create(niwsServerListClassName, clientConfig);
this.serverListImpl = niwsServerListImpl;
if (niwsServerListImpl instanceof AbstractServerList) {
......@@ -118,8 +123,7 @@ public class DynamicServerListLoadBalancer<T extends Server> extends BaseLoadBal
String serverListUpdaterClassName = clientConfig.getOrDefault(
CommonClientConfigKey.ServerListUpdaterClassName);
this.serverListUpdater = (ServerListUpdater) ClientFactory
.instantiateInstanceWithClientConfig(serverListUpdaterClassName, clientConfig);
this.serverListUpdater = (ServerListUpdater) factory.create(serverListUpdaterClassName, clientConfig);
restOfInit(clientConfig);
} catch (Exception e) {
......
package com.netflix.loadbalancer;
import com.netflix.client.ClientFactory;
import com.netflix.client.IClientConfigAware;
import com.netflix.client.config.ClientConfigFactory;
import com.netflix.client.config.CommonClientConfigKey;
import com.netflix.client.config.IClientConfig;
......@@ -16,7 +17,7 @@ public class LoadBalancerBuilder<T extends Server> {
private IPing ping = new DummyPing();
private ServerList serverListImpl;
private ServerListUpdater serverListUpdater;
private IClientConfigAware.Factory factory = ClientFactory::instantiateInstanceWithClientConfig;
private LoadBalancerBuilder() {
}
......@@ -24,7 +25,12 @@ public class LoadBalancerBuilder<T extends Server> {
public static <T extends Server> LoadBalancerBuilder<T> newBuilder() {
return new LoadBalancerBuilder<T>();
}
public LoadBalancerBuilder<T> withFactory(IClientConfigAware.Factory factory) {
this.factory = factory;
return this;
}
public LoadBalancerBuilder<T> withClientConfig(IClientConfig config) {
this.config = config;
return this;
......@@ -57,49 +63,49 @@ public class LoadBalancerBuilder<T extends Server> {
public BaseLoadBalancer buildFixedServerListLoadBalancer(List<T> servers) {
if (rule == null) {
rule = createRuleFromConfig(config);
rule = createRuleFromConfig(config, factory);
}
BaseLoadBalancer lb = new BaseLoadBalancer(config, rule, ping);
lb.setServersList(servers);
return lb;
}
private static IRule createRuleFromConfig(IClientConfig config) {
private static IRule createRuleFromConfig(IClientConfig config, IClientConfigAware.Factory factory) {
String ruleClassName = config.getOrDefault(IClientConfigKey.Keys.NFLoadBalancerRuleClassName);
if (ruleClassName == null) {
throw new IllegalArgumentException("NFLoadBalancerRuleClassName is not specified in the config");
}
IRule rule;
try {
rule = (IRule) ClientFactory.instantiateInstanceWithClientConfig(ruleClassName, config);
rule = (IRule) factory.create(ruleClassName, config);
} catch (Exception e) {
throw new RuntimeException(e);
}
return rule;
}
private static ServerListUpdater createServerListUpdaterFromConfig(IClientConfig config) {
private static ServerListUpdater createServerListUpdaterFromConfig(IClientConfig config, IClientConfigAware.Factory factory) {
String serverListUpdaterClassName = config.getOrDefault(IClientConfigKey.Keys.ServerListUpdaterClassName);
if (serverListUpdaterClassName == null) {
throw new IllegalArgumentException("NIWSServerListClassName is not specified in the config");
}
ServerListUpdater updater;
try {
updater = (ServerListUpdater) ClientFactory.instantiateInstanceWithClientConfig(serverListUpdaterClassName, config);
updater = (ServerListUpdater) factory.create(serverListUpdaterClassName, config);
} catch (Exception e) {
throw new RuntimeException(e);
}
return updater;
}
private static ServerList<Server> createServerListFromConfig(IClientConfig config) {
private static ServerList<Server> createServerListFromConfig(IClientConfig config, IClientConfigAware.Factory factory) {
String serverListClassName = config.get(IClientConfigKey.Keys.NIWSServerListClassName);
if (serverListClassName == null) {
throw new IllegalArgumentException("NIWSServerListClassName is not specified in the config");
}
ServerList<Server> list;
try {
list = (ServerList<Server>) ClientFactory.instantiateInstanceWithClientConfig(serverListClassName, config);
list = (ServerList<Server>) factory.create(serverListClassName, config);
} catch (Exception e) {
throw new RuntimeException(e);
}
......@@ -114,10 +120,10 @@ public class LoadBalancerBuilder<T extends Server> {
*/
public ZoneAwareLoadBalancer<T> buildDynamicServerListLoadBalancer() {
if (serverListImpl == null) {
serverListImpl = createServerListFromConfig(config);
serverListImpl = createServerListFromConfig(config, factory);
}
if (rule == null) {
rule = createRuleFromConfig(config);
rule = createRuleFromConfig(config, factory);
}
return new ZoneAwareLoadBalancer<T>(config, rule, ping, serverListImpl, serverListFilter);
}
......@@ -134,13 +140,13 @@ public class LoadBalancerBuilder<T extends Server> {
*/
public ZoneAwareLoadBalancer<T> buildDynamicServerListLoadBalancerWithUpdater() {
if (serverListImpl == null) {
serverListImpl = createServerListFromConfig(config);
serverListImpl = createServerListFromConfig(config, factory);
}
if (rule == null) {
rule = createRuleFromConfig(config);
rule = createRuleFromConfig(config, factory);
}
if (serverListUpdater == null) {
serverListUpdater = createServerListUpdaterFromConfig(config);
serverListUpdater = createServerListUpdaterFromConfig(config, factory);
}
return new ZoneAwareLoadBalancer<T>(config, rule, ping, serverListImpl, serverListFilter, serverListUpdater);
}
......@@ -156,7 +162,7 @@ public class LoadBalancerBuilder<T extends Server> {
}
ILoadBalancer lb;
try {
lb = (ILoadBalancer) ClientFactory.instantiateInstanceWithClientConfig(loadBalancerClassName, config);
lb = (ILoadBalancer) factory.create(loadBalancerClassName, config);
} catch (Exception e) {
throw new RuntimeException(e);
}
......
......@@ -91,10 +91,4 @@ public class RandomRule extends AbstractLoadBalancerRule {
public Server choose(Object key) {
return choose(getLoadBalancer(), key);
}
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
// TODO Auto-generated method stub
}
}
......@@ -115,8 +115,4 @@ public class RetryRule extends AbstractLoadBalancerRule {
public Server choose(Object key) {
return choose(getLoadBalancer(), key);
}
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
}
}
......@@ -110,8 +110,4 @@ public class RoundRobinRule extends AbstractLoadBalancerRule {
public Server choose(Object key) {
return choose(getLoadBalancer(), key);
}
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册