use of rpc.turbo.transport.client.App in project turbo-rpc by hank-whu.
the class TurboClient method register.
/**
* 注册一个远程服务
*
* @param clazz
*/
public <T> void register(Class<T> clazz) {
Objects.requireNonNull(clazz, "clazz");
T service = remoteServiceFactory.getService(clazz);
if (service != null) {
return;
}
Optional<App> appOptional = //
appMap.keySet().stream().filter(//
v -> v.isSupport(clazz)).findFirst();
if (!appOptional.isPresent()) {
throw new RemoteException("not support this service, " + clazz.getName());
}
App app = appOptional.get();
try {
remoteServiceFactory.register(app, clazz);
} catch (Exception e) {
throw new RemoteException(e);
}
}
use of rpc.turbo.transport.client.App in project turbo-rpc by hank-whu.
the class RemoteServiceFactory method generateRemoteObject.
private Object generateRemoteObject(App app, Class<?> clazz, Collection<MethodConfig> configs) throws Exception {
if (app == null) {
throw new RuntimeException("app must not be null");
}
if (clazz == null) {
throw new RuntimeException("clazz must not be null");
}
if (configs == null || configs.isEmpty()) {
throw new RuntimeException("configs must not be empty");
}
for (MethodConfig config : configs) {
if (config == null) {
throw new RuntimeException("config must not be null");
}
if (config.method == null) {
throw new RuntimeException("config.method must not be null");
}
if (config.timeout < 1) {
throw new RuntimeException("config.timeout must > 0");
}
if (config.timeout > 5 * 60 * 1000) {
throw new RuntimeException("config.timeout must < 5 * 60 * 1000 (5 mintues)");
}
}
Method[] allMethods = clazz.getMethods();
List<Method> allPublicMethods = //
Stream.of(//
allMethods).filter(//
m -> Modifier.isPublic(m.getModifiers())).filter(//
m -> !Modifier.isStatic(m.getModifiers())).peek(m -> {
if (!CompletableFuture.class.equals(m.getReturnType())) {
throw new RuntimeException("method return-type must be CompletableFuture, " + InvokerUtils.getServiceMethodName("", "", m));
}
}).collect(Collectors.toList());
if (configs.size() != allPublicMethods.size()) {
throw new RuntimeException("configs must contains all the interface's methods");
}
for (Method method : allMethods) {
if (!CompletableFuture.class.equals(method.getReturnType())) {
throw new RuntimeException("method return-type must be CompletableFuture, " + method);
}
if (!configs.stream().anyMatch(config -> config.method.equals(method))) {
throw new RuntimeException("configs must contains the method: " + method);
}
}
final String remoteClassName = //
clazz.getName() + "_RemoteService_" + UUID.randomUUID().toString().replace("-", "");
// 创建类
ClassPool pool = ClassPool.getDefault();
CtClass remoteCtClass = pool.makeClass(remoteClassName);
CtClass[] interfaces = { pool.getCtClass(clazz.getName()), pool.getCtClass(RemoteInterface.class.getName()) };
remoteCtClass.setInterfaces(interfaces);
// 添加私有成员app
CtField appField = new CtField(pool.get(App.class.getName()), "app", remoteCtClass);
appField.setModifiers(Modifier.PRIVATE | Modifier.FINAL);
remoteCtClass.addField(appField);
// 添加get方法
remoteCtClass.addMethod(CtNewMethod.getter("getApp", appField));
// 添加有参的构造函数
CtConstructor constructor1 = new CtConstructor(new CtClass[] { pool.get(App.class.getName()) }, remoteCtClass);
constructor1.setBody("{$0.app = $1;}");
remoteCtClass.addConstructor(constructor1);
for (MethodConfig config : configs) {
Method method = config.method;
Class<? extends MethodParam> methodParamClass = MethodParamClassFactory.createClass(method);
long timeout = config.timeout;
// 添加私有成员failoverInvoker
String failoverFieldName = getFailoverInvokerFieldName(app, method);
CtField failoverField = new CtField(pool.get(Invoker.class.getName()), failoverFieldName, remoteCtClass);
appField.setModifiers(Modifier.PRIVATE);
remoteCtClass.addField(failoverField);
StringBuilder methodBuilder = new StringBuilder();
methodBuilder.append("public ");
methodBuilder.append(method.getReturnType().getName());
methodBuilder.append(" ");
methodBuilder.append(method.getName());
methodBuilder.append("(");
Class<?>[] parameterTypes = method.getParameterTypes();
for (int i = 0; i < parameterTypes.length; i++) {
Class<?> parameterType = parameterTypes[i];
methodBuilder.append(parameterType.getName());
methodBuilder.append(" param");
methodBuilder.append(i);
if (i != parameterTypes.length - 1) {
methodBuilder.append(", ");
}
}
methodBuilder.append("){\r\n");
methodBuilder.append(" return ");
if (config.ignore) {
if (logger.isInfoEnabled()) {
logger.info(InvokerUtils.getServiceMethodName(app.group, app.app, config.method) + " ignore");
}
methodBuilder.append("$remote_ignore()");
} else {
if (logger.isInfoEnabled()) {
logger.info(//
InvokerUtils.getServiceMethodName(app.group, app.app, config.method) + " register, config:" + config);
}
methodBuilder.append("$remote_execute(");
methodBuilder.append(app.getMethodId(method));
methodBuilder.append(", ");
methodBuilder.append(timeout);
methodBuilder.append("L, ");
methodBuilder.append("new ");
methodBuilder.append(methodParamClass.getName());
methodBuilder.append("(");
for (int i = 0; i < parameterTypes.length; i++) {
methodBuilder.append("param");
methodBuilder.append(i);
if (i != parameterTypes.length - 1) {
methodBuilder.append(",");
}
}
methodBuilder.append("), ");
methodBuilder.append(failoverFieldName);
methodBuilder.append(")");
}
methodBuilder.append(";\r\n}");
CtMethod m = CtNewMethod.make(methodBuilder.toString(), remoteCtClass);
remoteCtClass.addMethod(m);
}
Class<?> invokerClass = remoteCtClass.toClass();
return invokerClass.getConstructor(App.class).newInstance(app);
}
use of rpc.turbo.transport.client.App in project turbo-rpc by hank-whu.
the class TurboClient method register.
/**
* 注册一个远程服务
*
* @param group
* @param app
* @param clazz
* @param failover
*/
public <T> void register(String group, String app, Class<T> clazz, Object failover) {
T service = remoteServiceFactory.getService(clazz);
if (service != null) {
return;
}
Objects.requireNonNull(group, "group");
Objects.requireNonNull(app, "app");
Optional<App> appOptional = //
appMap.keySet().stream().filter(//
v -> v.group.equals(group)).filter(//
v -> v.app.equals(app)).filter(//
v -> v.isSupport(clazz)).findFirst();
if (!appOptional.isPresent()) {
throw new RemoteException("not support this service, " + InvokerUtils.getServiceClassName(group, app, clazz));
}
App application = appOptional.get();
try {
remoteServiceFactory.register(application, clazz);
remoteServiceFactory.setFailover(application, clazz, service, failover);
} catch (Exception e) {
throw new RemoteException(e);
}
}
use of rpc.turbo.transport.client.App in project turbo-rpc by hank-whu.
the class TurboClient method setFailover.
/**
* 设置失败回退方法
*
* @param clazz
* @param failover
*/
public <T> void setFailover(Class<T> clazz, Object failover) {
Objects.requireNonNull(clazz, "clazz");
T service = remoteServiceFactory.getService(clazz);
if (service == null) {
throw new RemoteException("not register this service, " + clazz.getName());
}
try {
App app = ((RemoteInterface) service).getApp();
remoteServiceFactory.setFailover(app, clazz, service, failover);
} catch (Exception e) {
throw new RemoteException(e);
}
}
use of rpc.turbo.transport.client.App in project turbo-rpc by hank-whu.
the class TurboClient method addConnect.
public void addConnect(AppConfig appConfig) {
Objects.requireNonNull(appConfig, "appConfig");
try {
App _app = new App(eventLoopGroup, appConfig, filters);
appMap.put(_app, Boolean.TRUE);
} catch (Exception e) {
throw new RemoteException(e);
}
}
Aggregations