net.dongliu.prettypb.rpc.client.StubServiceFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of prettypb-rpc Show documentation
Show all versions of prettypb-rpc Show documentation
proto rpc libs, compatible with proto-rpc-pro
package net.dongliu.prettypb.rpc.client;
import net.dongliu.prettypb.rpc.RpcClient;
import net.dongliu.prettypb.rpc.exception.ServiceException;
import net.dongliu.prettypb.rpc.protocol.RpcRequest;
import net.dongliu.prettypb.rpc.info.MethodInfo;
import net.dongliu.prettypb.rpc.info.ServiceInfo;
import net.dongliu.prettypb.runtime.ProtobufSerializer;
import net.dongliu.prettypb.runtime.include.RpcCallback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
/**
* proto rpc client service factory.
*
* @author dongliu
*/
public class StubServiceFactory {
private Logger logger = LoggerFactory.getLogger(StubServiceFactory.class);
private final AtomicInteger correlationId;
private final RpcClient rpcClient;
public StubServiceFactory(AtomicInteger correlationId, RpcClient rpcClient) {
this.correlationId = correlationId;
this.rpcClient = rpcClient;
}
@SuppressWarnings("unchecked")
public T getService(Class interfaceClass, int timeout) {
if (timeout <= 0) {
throw new IllegalArgumentException("timeout should be larger than 0");
}
InvocationHandler handler = new RpcInvocationHandler(interfaceClass, timeout);
return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(),
new Class[]{interfaceClass}, handler);
}
/**
* generate service impl for protobuf rpc client
*/
class RpcInvocationHandler implements InvocationHandler {
private ServiceInfo serviceInfo;
/**
* time out for this service
*/
private int timeout;
public RpcInvocationHandler(Class> interfaceClass, int timeout) {
this.serviceInfo = ServiceInfo.inspect(interfaceClass);
this.serviceInfo.setAllowTimeout(true);
this.timeout = timeout;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws ServiceException {
MethodInfo methodInfo = this.serviceInfo.getMethodInfo(method.getName());
if (methodInfo == null) {
throw new ServiceException("Method not found:" + this.serviceInfo.getName() + "#"
+ method.getName());
}
RpcRequest rpcRequest = new RpcRequest();
rpcRequest.setMethodIdentifier(methodInfo.getName());
rpcRequest.setCorrelationId(correlationId.getAndIncrement());
rpcRequest.setServicePackage(serviceInfo.getPackageName());
rpcRequest.setServiceIdentifier(serviceInfo.getName());
rpcRequest.setTimeoutMs(timeout);
Class>[] parameterTypes = method.getParameterTypes();
rpcRequest.setRequestBytes(ProtobufSerializer.toBytes(args[0],
(Class