All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alibaba.dts.client.remoting.proxy.ClientSystemInvocationHandler Maven / Gradle / Ivy

package com.alibaba.dts.client.remoting.proxy;

import com.alibaba.dts.client.executor.job.context.ClientContextImpl;
import com.alibaba.dts.client.remoting.NodeRemoting;
import com.alibaba.dts.common.constants.Constants;
import com.alibaba.dts.common.context.InvocationContext;
import com.alibaba.dts.common.domain.remoting.RemoteMachine;
import com.alibaba.dts.common.domain.remoting.protocol.InvokeMethod;
import com.alibaba.dts.common.logger.SchedulerXLoggerFactory;
import com.alibaba.dts.common.logger.innerlog.Logger;
import com.alibaba.dts.common.proxy.ProxyService;
import com.alibaba.dts.common.remoting.protocol.RemotingCommand;
import com.alibaba.dts.common.remoting.protocol.RemotingSerializable;
import com.alibaba.dts.common.util.BytesUtil;
import com.alibaba.dts.common.util.RemotingUtil;
import com.alibaba.dts.common.util.StringUtil;
import com.alibaba.fastjson.JSON;
import io.netty.channel.Channel;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * @author Ronan Zhan
 */
public class ClientSystemInvocationHandler implements InvocationHandler, Constants {

    private static final Logger logger = SchedulerXLoggerFactory.getLogger(ClientSystemInvocationHandler.class);

    private final ClientContextImpl clientContext;

    public ClientSystemInvocationHandler(final ClientContextImpl clientContext) {
        this.clientContext = clientContext;
    }


    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {

        RemoteMachine remoteMachine = InvocationContext.acquireRemoteMachine();
        remoteMachine.setGroupId(this.clientContext.getClientConfig().getGroupId());
        remoteMachine.setClientId(this.clientContext.getClientConfig().getClientId());
        remoteMachine.setLocalVersion(this.clientContext.getClientConfig().getVersion());
        remoteMachine.setCrashRetry(this.clientContext.getClientConfig().isCrashRetry());
        remoteMachine.setEnvironment(this.clientContext.getClientConfig().getEnvironment());
        remoteMachine.setSignature(this.clientContext.getClientConfig().getSignature());
        remoteMachine.setClientAK(this.clientContext.getClientConfig().getAccessKey());
        remoteMachine.setConnectTime(this.clientContext.getClientConfig().getConnectTime());
        remoteMachine.setServiceGroup(this.clientContext.getClientConfig().getServiceGroup());
        remoteMachine.setRegionName(this.clientContext.getClientConfig().getRegionName());
        remoteMachine.setNodeListenPort(this.clientContext.nodeConfig.getListenPort());
        remoteMachine.setNodeSystemListenPort(this.clientContext.nodeConfig.getSystemListenPort());

        Channel channel = this.clientContext.getClientRemoting().getAndCreateChannel(remoteMachine.getRemoteAddress());
        if (null == channel) {
            logger.info("[ClientSystemInvocationHandler]: getAndCreateChannel error"
                    + ", server:" + remoteMachine.getRemoteAddress()
                    + ", timeout:" + remoteMachine.getTimeout()
                    + ", methodName:" + method.getName());
            InvocationContext.clean();
            return null;
        }
        remoteMachine.setLocalAddress(RemotingUtil.socketAddress2String(channel.localAddress()));

        Class[] parameterTypesClass = method.getParameterTypes();
        String[] parameterTypesString = new String[parameterTypesClass.length];
        String[] arguments = new String[parameterTypesClass.length];
        for (int i = 0; i < parameterTypesClass.length; i++) {
            parameterTypesString[i] = parameterTypesClass[i].getName();
            arguments[i] = RemotingSerializable.toJson(args[i], false);
        }
        InvokeMethod invokeMethod = new InvokeMethod(remoteMachine, method.getName(), parameterTypesString, arguments, method.getReturnType().getName());
        byte[] requestBody = null;
        try {
            requestBody = BytesUtil.objectToBytes(invokeMethod.toString());
        } catch (Throwable e) {
            logger.error("[ClientSystemInvocationHandler]: objectToBytes error"
                    + ", server:" + remoteMachine.getRemoteAddress()
                    + ", timeout:" + remoteMachine.getTimeout()
                    + ", methodName:" + method.getName(), e);
            InvocationContext.clean();
            return null;
        }
        if (null == requestBody) {
            logger.error("[ClientSystemInvocationHandler]: requestBody is null"
                    + ", server:" + remoteMachine.getRemoteAddress()
                    + ", timeout:" + remoteMachine.getTimeout()
                    + ", methodName:" + method.getName());
            InvocationContext.clean();
            return null;
        }
        RemotingCommand request = new RemotingCommand();
        request.setBody(requestBody);
        RemotingCommand response = null;
        try {
            response = this.clientContext.getClientRemoting().invokeSync(remoteMachine.getRemoteAddress(), request, remoteMachine.getTimeout());
        } catch (Throwable e) {
            if (method.getName().equals("connect")) {
                logger.info("[ClientInvocationHandler]: invoke error"
                        + ", server:" + remoteMachine.getRemoteAddress()
                        + ", timeout:" + remoteMachine.getTimeout()
                        + ", methodName:" + method.getName(), e);
            } else {
                logger.error("[ClientInvocationHandler]: invoke error"
                        + ", server:" + remoteMachine.getRemoteAddress()
                        + ", timeout:" + remoteMachine.getTimeout()
                        + ", methodName:" + method.getName(), e);
            }
        }
        InvocationContext.clean();
        if (null == response) {
            logger.info("[ClientSystemInvocationHandler]: response is null"
                    + ", server:" + remoteMachine.getRemoteAddress()
                    + ", timeout:" + remoteMachine.getTimeout()
                    + ", methodName:" + method.getName());

            return null;
        }
        Class returnClass = ProxyService.getClass(invokeMethod.getReturnType());
        if (void.class == returnClass) {
            return null;
        }
        byte[] responseBody = response.getBody();
        if (null == responseBody) {
            logger.info("[ClientSystemInvocationHandler]: responseBody is null"
                    + ", server:" + remoteMachine.getRemoteAddress()
                    + ", timeout:" + remoteMachine.getTimeout()
                    + ", methodName:" + method.getName());

            return null;
        }

        String json = null;
        try {
            json = (String) BytesUtil.bytesToObject(responseBody);
        } catch (Throwable e) {
            logger.error("[ClientSystemInvocationHandler]: bytesToObject error"
                    + ", server:" + remoteMachine.getRemoteAddress()
                    + ", timeout:" + remoteMachine.getTimeout()
                    + ", methodName:" + method.getName(), e);
        }
        if (StringUtil.isBlank(json)) {
            logger.error("[ClientSystemInvocationHandler]: json is null"
                    + ", server:" + remoteMachine.getRemoteAddress()
                    + ", timeout:" + remoteMachine.getTimeout()
                    + ", methodName:" + method.getName());

            return null;
        }

        if ("\"NO_SUCH_METHOD\"".equals(json) && ("getNodeIps").equals(method.getName())) {
            NodeRemoting.isGetNodeIpsAvailable = false;
        }
        Type returnType = method.getGenericReturnType();
        if (returnType instanceof ParameterizedType) {
            return JSON.parseObject(json, (ParameterizedType) returnType);
        }
        return RemotingSerializable.fromJson(json, returnClass);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy