Skip to content

Commit

Permalink
Merge pull request #399 from elandau/feature/factory_api
Browse files Browse the repository at this point in the history
Pluggable object creation
  • Loading branch information
elandau authored Feb 11, 2019
2 parents 4878457 + 375fbd1 commit a219149
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,21 @@
*
*/
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
* {@link IClientConfig} (which in turn were set via Archaius properties) will be taken into consideration
*
* @param clientConfig
*/
public abstract void initWithNiwsConfig(IClientConfig clientConfig);
default void initWithNiwsConfig(IClientConfig clientConfig) {
}

default void initWithNiwsConfig(IClientConfig clientConfig, Factory factory) {
initWithNiwsConfig(clientConfig);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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"){};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -236,7 +236,7 @@ public static Object instantiateInstanceWithClientConfig(String className, IClie
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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,11 @@ public BaseLoadBalancer(IClientConfig config) {
}

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) {
Expand Down Expand Up @@ -208,29 +208,31 @@ void initWithConfig(IClientConfig clientConfig, IRule rule, IPing ping, LoadBala

@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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,4 @@ public DummyPing() {
public boolean isAlive(Server server) {
return true;
}

@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,17 @@ public DynamicServerListLoadBalancer(IClientConfig clientConfig) {

@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) {
Expand All @@ -118,8 +123,7 @@ public void initWithNiwsConfig(IClientConfig clientConfig) {
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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
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;
Expand All @@ -16,15 +17,20 @@ 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() {
}

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;
Expand Down Expand Up @@ -57,49 +63,49 @@ public LoadBalancerBuilder<T> withServerListUpdater(ServerListUpdater serverList

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);
}
Expand All @@ -114,10 +120,10 @@ private static ServerList<Server> createServerListFromConfig(IClientConfig confi
*/
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);
}
Expand All @@ -134,13 +140,13 @@ public ZoneAwareLoadBalancer<T> buildDynamicServerListLoadBalancer() {
*/
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);
}
Expand All @@ -156,7 +162,7 @@ public ILoadBalancer buildLoadBalancerFromConfigWithReflection() {
}
ILoadBalancer lb;
try {
lb = (ILoadBalancer) ClientFactory.instantiateInstanceWithClientConfig(loadBalancerClassName, config);
lb = (ILoadBalancer) factory.create(loadBalancerClassName, config);
} catch (Exception e) {
throw new RuntimeException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,4 @@ protected int chooseRandomInt(int serverCount) {
public Server choose(Object key) {
return choose(getLoadBalancer(), key);
}

@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
// TODO Auto-generated method stub

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,4 @@ public Server choose(ILoadBalancer lb, Object key) {
public Server choose(Object key) {
return choose(getLoadBalancer(), key);
}

@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,4 @@ private int incrementAndGetModulo(int modulo) {
public Server choose(Object key) {
return choose(getLoadBalancer(), key);
}

@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
}
}

0 comments on commit a219149

Please sign in to comment.