Search in sources :

Example 1 with App

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);
    }
}
Also used : App(rpc.turbo.transport.client.App) EventLoopGroup(io.netty.channel.EventLoopGroup) EventLoopGroupHolder(rpc.turbo.common.EventLoopGroupHolder) RemoteServiceFactory(rpc.turbo.remote.RemoteServiceFactory) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) IOException(java.io.IOException) Objects(java.util.Objects) InvokerUtils(rpc.turbo.invoke.InvokerUtils) App(rpc.turbo.transport.client.App) HostPort(rpc.turbo.config.HostPort) AppConfig(rpc.turbo.config.client.AppConfig) Closeable(java.io.Closeable) RemoteException(rpc.turbo.remote.RemoteException) RemoteInterface(rpc.turbo.remote.RemoteInterface) RpcClientFilter(rpc.turbo.filter.RpcClientFilter) Optional(java.util.Optional) ClientConfig(rpc.turbo.config.client.ClientConfig) Log(org.apache.commons.logging.Log) LogFactory(org.apache.commons.logging.LogFactory) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) FailoverInvokerFactory(rpc.turbo.invoke.FailoverInvokerFactory) RemoteException(rpc.turbo.remote.RemoteException) IOException(java.io.IOException) RemoteException(rpc.turbo.remote.RemoteException)

Example 2 with App

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);
}
Also used : CtMethod(javassist.CtMethod) CompletableFuture(java.util.concurrent.CompletableFuture) CtClass(javassist.CtClass) CtNewMethod(javassist.CtNewMethod) App(rpc.turbo.transport.client.App) CtConstructor(javassist.CtConstructor) MethodConfig(rpc.turbo.config.MethodConfig) Method(java.lang.reflect.Method) Invoker(rpc.turbo.invoke.Invoker) TurboService(rpc.turbo.annotation.TurboService) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) MethodParam(rpc.turbo.param.MethodParam) IOException(java.io.IOException) UUID(java.util.UUID) Field(java.lang.reflect.Field) Collectors(java.util.stream.Collectors) CtField(javassist.CtField) MethodParamClassFactory(rpc.turbo.param.MethodParamClassFactory) List(java.util.List) InvokerUtils(rpc.turbo.invoke.InvokerUtils) Stream(java.util.stream.Stream) Closeable(java.io.Closeable) Modifier(java.lang.reflect.Modifier) Log(org.apache.commons.logging.Log) LogFactory(org.apache.commons.logging.LogFactory) ClassPool(javassist.ClassPool) FailoverInvokerFactory(rpc.turbo.invoke.FailoverInvokerFactory) App(rpc.turbo.transport.client.App) ClassPool(javassist.ClassPool) CtMethod(javassist.CtMethod) CtNewMethod(javassist.CtNewMethod) Method(java.lang.reflect.Method) CtConstructor(javassist.CtConstructor) MethodConfig(rpc.turbo.config.MethodConfig) CtClass(javassist.CtClass) CompletableFuture(java.util.concurrent.CompletableFuture) CtField(javassist.CtField) CtClass(javassist.CtClass) CtMethod(javassist.CtMethod)

Example 3 with 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);
    }
}
Also used : App(rpc.turbo.transport.client.App) EventLoopGroup(io.netty.channel.EventLoopGroup) EventLoopGroupHolder(rpc.turbo.common.EventLoopGroupHolder) RemoteServiceFactory(rpc.turbo.remote.RemoteServiceFactory) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) IOException(java.io.IOException) Objects(java.util.Objects) InvokerUtils(rpc.turbo.invoke.InvokerUtils) App(rpc.turbo.transport.client.App) HostPort(rpc.turbo.config.HostPort) AppConfig(rpc.turbo.config.client.AppConfig) Closeable(java.io.Closeable) RemoteException(rpc.turbo.remote.RemoteException) RemoteInterface(rpc.turbo.remote.RemoteInterface) RpcClientFilter(rpc.turbo.filter.RpcClientFilter) Optional(java.util.Optional) ClientConfig(rpc.turbo.config.client.ClientConfig) Log(org.apache.commons.logging.Log) LogFactory(org.apache.commons.logging.LogFactory) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) FailoverInvokerFactory(rpc.turbo.invoke.FailoverInvokerFactory) RemoteException(rpc.turbo.remote.RemoteException) IOException(java.io.IOException) RemoteException(rpc.turbo.remote.RemoteException)

Example 4 with App

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);
    }
}
Also used : App(rpc.turbo.transport.client.App) RemoteInterface(rpc.turbo.remote.RemoteInterface) RemoteException(rpc.turbo.remote.RemoteException) IOException(java.io.IOException) RemoteException(rpc.turbo.remote.RemoteException)

Example 5 with App

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);
    }
}
Also used : App(rpc.turbo.transport.client.App) RemoteException(rpc.turbo.remote.RemoteException) IOException(java.io.IOException) RemoteException(rpc.turbo.remote.RemoteException)

Aggregations

IOException (java.io.IOException)6 App (rpc.turbo.transport.client.App)6 RemoteException (rpc.turbo.remote.RemoteException)5 Closeable (java.io.Closeable)3 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)3 Log (org.apache.commons.logging.Log)3 LogFactory (org.apache.commons.logging.LogFactory)3 AppConfig (rpc.turbo.config.client.AppConfig)3 FailoverInvokerFactory (rpc.turbo.invoke.FailoverInvokerFactory)3 InvokerUtils (rpc.turbo.invoke.InvokerUtils)3 RemoteInterface (rpc.turbo.remote.RemoteInterface)3 EventLoopGroup (io.netty.channel.EventLoopGroup)2 Objects (java.util.Objects)2 Optional (java.util.Optional)2 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)2 EventLoopGroupHolder (rpc.turbo.common.EventLoopGroupHolder)2 HostPort (rpc.turbo.config.HostPort)2 ClientConfig (rpc.turbo.config.client.ClientConfig)2 RpcClientFilter (rpc.turbo.filter.RpcClientFilter)2 RemoteServiceFactory (rpc.turbo.remote.RemoteServiceFactory)2