package com.github.wangxuehui.rpc.snrpc.client;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.LinkedList;
import java.util.List;
import com.github.wangxuehui.rpc.snrpc.SnRpcConnection;
import com.github.wangxuehui.rpc.snrpc.conf.SnRpcConfig;
import com.github.wangxuehui.rpc.snrpc.serializer.SnRpcRequest;
import com.github.wangxuehui.rpc.snrpc.serializer.SnRpcResponse;
import com.github.wangxuehui.rpc.snrpc.util.Sequence;
import com.github.wangxuehui.rpc.snrpc.SnRpcClient;
import com.github.wangxuehui.rpc.snrpc.SnRpcConnectionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author skyim E-mail:wxh64788665@gmail.com
*/
public class CommonSnRpcClient implements SnRpcClient {
private static final Logger LOGGER = LoggerFactory.getLogger(SnRpcConfig.class);
private SnRpcConnectionFactory snRpcConnectionFactory;
private SnRpcInvoker invoker = new SnRpcInvoker();
public CommonSnRpcClient(SnRpcConnectionFactory snRpcConnectionFactory) {
if(null == snRpcConnectionFactory) {
throw new NullPointerException("snRpcConnectionFactory is null ....");
}
this.snRpcConnectionFactory = snRpcConnectionFactory;
}
@SuppressWarnings("unchecked")
@Override
public <T> T proxy(Class<T> interfaceClass) throws Throwable {
if (!interfaceClass.isInterface()) {
throw new IllegalArgumentException(interfaceClass.getName() + " " + "is not an interface");
}
return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[] { interfaceClass }, invoker);
}
/**
* invoker
*/
private class SnRpcInvoker implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String className = method.getDeclaringClass().getName();
List<String> parameterTypes = new LinkedList<String>();
for (Class<?> parameterType : method.getParameterTypes()) {
parameterTypes.add(parameterType.getName());
}
String requestID = generateRequestID();
//封装rpc调用请求
SnRpcRequest request = new SnRpcRequest(requestID, className,
method.getName(), parameterTypes.toArray(new String[0]), args);
//这是客户端要收到的调用结果
SnRpcResponse response = null;
SnRpcConnection connection = null;
try {
connection = getConnection();
response = connection.sendRequest(request);
}catch(Throwable t){
LOGGER.warn("send rpc request fail! request: <{}>", new Object[] { request }, t);
throw new RuntimeException(t);
}finally {
recycle(connection);
}
if (response.getException() != null) {
throw response.getException();
} else {
return response.getResult();
}
}
//通过工厂类获得连接对象
private SnRpcConnection getConnection() throws Throwable {
return snRpcConnectionFactory.getConnection();
}
private String generateRequestID() {
// TODO Auto-generated method stub
return Sequence.next() + "";
}
/**
* recycle
* @param connection
*/
private void recycle(SnRpcConnection connection) {
if (null != connection && null != snRpcConnectionFactory) {
try {
snRpcConnectionFactory.recycle(connection);
} catch (Throwable t) {
LOGGER.warn("recycle rpc connection fail!", t);
}
}
}
}
}