package com.justdebugit.thrift.consumer; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentMap; import com.google.common.base.Preconditions; import com.google.common.collect.Maps; import com.justdebugit.thrift.client.ThriftClientFactory; import com.justdebugit.thrift.client.ThriftStatefulPoolFactory; import com.justdebugit.thrift.common.AbstractLifeCycle; import com.justdebugit.thrift.common.ServiceConfig; import com.justdebugit.thrift.consumer.RpcConsumerFactory.Builder; import com.justdebugit.thrift.pool.MultiPool; import com.justdebugit.thrift.pool.StatefulPoolFactory; import com.justdebugit.thrift.pool.StatefulPoolMapManager; import com.justdebugit.thrift.proxy.PooledProxyFactory; import com.justdebugit.thrift.registry.CuratorFactory; import com.justdebugit.thrift.registry.DefaultCuratorFactory; import com.justdebugit.thrift.registry.Registry; import com.justdebugit.thrift.registry.ZkCuratorRegistry; public class RpcConsumer extends AbstractLifeCycle{ private List<ServiceConfig> services; private String connectStringForZk; private int sessionTimeOutForZk; private int connectTimeOutForZk; private final ConcurrentMap<String, Object> proxyMap = Maps.newConcurrentMap(); private final Map<ServiceConfig, MultiPool<?>> poolMap = Maps.newHashMap(); private final Registry registry; private final ThriftClientFactory thriftClientFactory; public RpcConsumer(Builder builder) { connectStringForZk = builder.getConnectString(); sessionTimeOutForZk = builder.getSessionTimeout(); connectTimeOutForZk = builder.getConnectTimeout(); CuratorFactory curatorFactory = new DefaultCuratorFactory(connectStringForZk,connectTimeOutForZk,sessionTimeOutForZk); this.registry = new ZkCuratorRegistry(curatorFactory); this.thriftClientFactory = builder.getDefaultThriftClientFactory(); services = builder.getRpcServices(); for (ServiceConfig rpcService : services) { Preconditions.checkNotNull(rpcService.getInterfaceClass()); if (rpcService.getClientFactory()==null) { rpcService.setClientFactory(thriftClientFactory); } String serviceName = rpcService.getServiceName()==null?rpcService.getInterfaceClass().getName():rpcService.getServiceName(); Preconditions.checkNotNull(serviceName, "Servicename must not be null"); rpcService.setServiceName(serviceName); proxyMap.put(serviceName, buildServiceProxy(rpcService)); } } public void addService(ServiceConfig rpcService){ Preconditions.checkNotNull(rpcService.getInterfaceClass()); if (rpcService.getClientFactory()==null) { rpcService.setClientFactory(thriftClientFactory); } proxyMap.put(rpcService.getServiceName(), buildServiceProxy(rpcService)); } @SuppressWarnings("unchecked") private <T> T buildServiceProxy(ServiceConfig rpcService){ MultiPool<T> pool = buildMultiPool(rpcService); poolMap.put(rpcService, pool); return PooledProxyFactory.getProxy((Class<T>)rpcService.getInterfaceClass(),(Class<? extends T>)rpcService.getClientClass(),pool); } private <T> MultiPool<T> buildMultiPool(ServiceConfig rpcService) { StatefulPoolFactory<T> statefulPoolFactory = new ThriftStatefulPoolFactory<T>(rpcService); StatefulPoolMapManager<T> statefulPoolMapManager = new StatefulPoolMapManager<T>(rpcService.getServiceName(), registry, statefulPoolFactory); MultiPool<T> pool = new MultiPool<T>(statefulPoolMapManager); return pool; } public List<ServiceConfig> getServices() { return services; } public void setServices(List<ServiceConfig> services) { this.services = services; } public String getConnectStringForZk() { return connectStringForZk; } public void setConnectStringForZk(String connectStringForZk) { this.connectStringForZk = connectStringForZk; } public int getSessionTimeOutForZk() { return sessionTimeOutForZk; } public void setSessionTimeOutForZk(int sessionTimeOutForZk) { this.sessionTimeOutForZk = sessionTimeOutForZk; } public int getConnectTimeOutForZk() { return connectTimeOutForZk; } public void setConnectTimeOutForZk(int connectTimeOutForZk) { this.connectTimeOutForZk = connectTimeOutForZk; } @SuppressWarnings("unchecked") public <T> T getService(String serviceName){ return (T)proxyMap.get(serviceName); } @Override protected void doStart() { for (Map.Entry<ServiceConfig,MultiPool<?>> entry : poolMap.entrySet()) { MultiPool<?> multiPool = entry.getValue(); multiPool.start(); } } @Override protected void doStop() { for (Map.Entry<ServiceConfig,MultiPool<?>> entry : poolMap.entrySet()) { MultiPool<?> multiPool = entry.getValue(); multiPool.stop(); } } }