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

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

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

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

import com.alibaba.dts.client.executor.job.context.ClientContextImpl;
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;


/**
 * 客户端代理调用接口
 *
 * @author tianyao.myc
 */
public class ClientInvocationHandler implements InvocationHandler, Constants {

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

    private final ClientContextImpl clientContext;

    public ClientInvocationHandler(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("[ClientInvocationHandler]: getAndCreateChannel error"
                    + ", server:" + remoteMachine.getRemoteAddress()
                    + ", timeout:" + remoteMachine.getTimeout()
                    + ", methodName:" + method.getName());

            InvocationContext.clean();
            return null;
        }
        if (Constants.ENVIRONMENT_SCX.equals(clientContext.getClientConfig().getEnvironment())) {
            InetSocketAddress inetSocketAddress = (InetSocketAddress) channel.localAddress();
            StringBuilder localAddrBuilder = new StringBuilder(clientContext.getClientConfig().getLocalAddress());
            localAddrBuilder.append(":").append(inetSocketAddress.getPort());
            remoteMachine.setLocalAddress(localAddrBuilder.toString());
        } else {
            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("[ClientInvocationHandler]: objectToBytes error"
                    + ", server:" + remoteMachine.getRemoteAddress()
                    + ", timeout:" + remoteMachine.getTimeout()
                    + ", methodName:" + method.getName(), e);
            InvocationContext.clean();
            return null;
        }
        if (null == requestBody) {
            logger.error("[ClientInvocationHandler]: 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("[ClientInvocationHandler]: 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("[ClientInvocationHandler]: 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("[ClientInvocationHandler]: bytesToObject error"
                    + ", server:" + remoteMachine.getRemoteAddress()
                    + ", timeout:" + remoteMachine.getTimeout()
                    + ", methodName:" + method.getName(), e);
        }
        if (StringUtil.isBlank(json)) {
            logger.error("[ClientInvocationHandler]: json is null"
                    + ", server:" + remoteMachine.getRemoteAddress()
                    + ", timeout:" + remoteMachine.getTimeout()
                    + ", methodName:" + method.getName());

            return null;
        }

        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