net.dongliu.prettypb.rpc.common.ServiceInfo 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.common;
import net.dongliu.prettypb.runtime.include.ProtoMethod;
import net.dongliu.prettypb.runtime.include.ProtoService;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
/**
* rpc service info.
* for client side, impl is null.
* once construct, the instance should be read only
*
* @author Dong Liu
*/
public class ServiceInfo {
/**
* the proto package name
*/
private final String packageName;
/**
* service name
*/
private String name;
/**
* service impl object. for client side, is null
*/
private Object impl;
/**
* is async(callback format)
*/
private boolean async;
/**
* timeout check is on
*/
private boolean allowTimeout;
/**
* all method the interface have
*/
private final Map methodMap;
public ServiceInfo(String packageName, String name, boolean async, Map methodMap) {
this.packageName = packageName;
this.name = name;
this.async = async;
this.methodMap = methodMap;
}
/**
* inspect interface class, get service and methods info
*
* @param interfaceClass
* @return
*/
public static ServiceInfo inspect(Class> interfaceClass) {
Method[] methods = interfaceClass.getDeclaredMethods();
ProtoService protoService = interfaceClass.getAnnotation(ProtoService.class);
Map methodMap = new HashMap<>();
for (Method method : methods) {
ProtoMethod protoMethod = method.getAnnotation(ProtoMethod.class);
if (protoMethod == null) {
continue;
}
Class> requestType;
Class> responseType;
Class>[] parameterTypes = method.getParameterTypes();
if (protoService.async()) {
// async
if (parameterTypes.length != 2) {
throw new RuntimeException("Service method have more than one parameter");
}
requestType = parameterTypes[0];
Type[] type = method.getGenericParameterTypes();
ParameterizedType ptype = (ParameterizedType) type[1];
responseType = (Class>) ptype.getActualTypeArguments()[0];
} else {
// block
if (parameterTypes.length != 1) {
throw new RuntimeException("Service method have more than one parameter");
}
requestType = parameterTypes[0];
responseType = method.getReturnType();
}
MethodInfo smInfo = new MethodInfo(protoMethod.name(), method, null, requestType,
responseType);
methodMap.put(protoMethod.name(), smInfo);
}
ServiceInfo serviceInfo = new ServiceInfo(protoService.protoPackage(), protoService.name(),
protoService.async(), methodMap);
for (MethodInfo methodInfo : methodMap.values()) {
methodInfo.setServiceInfo(serviceInfo);
}
return serviceInfo;
}
public String getPackageName() {
return packageName;
}
public String getName() {
return name;
}
public String getFullName() {
if (packageName == null || packageName.isEmpty()) {
return name;
} else {
return packageName + "." + name;
}
}
public void setImpl(Object impl) {
this.impl = impl;
}
public Object getImpl() {
return impl;
}
public boolean isAsync() {
return async;
}
public MethodInfo getMethodInfo(String name) {
return this.methodMap.get(name);
}
public Map getMethodMap() {
return this.methodMap;
}
/**
* @return the allowTimeout
*/
public boolean isAllowTimeout() {
return allowTimeout;
}
public void setAllowTimeout(boolean allowTimeout) {
this.allowTimeout = allowTimeout;
}
}