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

com.alibaba.dts.client.remoting.proxy.NodeServerInvocationHandler 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 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.StringUtil;
import com.alibaba.fastjson.JSON;

/**
 * Node服务端代理发出请求的调用接口
 *
 * @author Ronan Zhan
 */
public class NodeServerInvocationHandler implements InvocationHandler, Constants {

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

    private ClientContextImpl clientContext;

    public NodeServerInvocationHandler(ClientContextImpl clientContext) {
        this.clientContext = clientContext;
    }

    /**
     * 拦截方法调用各项参数
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {

        RemoteMachine remoteMachine = InvocationContext.acquireRemoteMachine();
        remoteMachine.setLocalAddress(clientContext.getNodeConfig().getLocalAddress());

        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("[NodeServerInvocationHandler]: objectToBytes error"
                    + ", remoteMachine:" + remoteMachine.toString()
                    + ", timeout:" + remoteMachine.getTimeout()
                    + ", methodName:" + method.getName(), e);
            InvocationContext.clean();
            return null;
        }
        if (null == requestBody) {
            logger.error("[NodeServerInvocationHandler]: requestBody is null"
                    + ", remoteMachine:" + remoteMachine.toString()
                    + ", timeout:" + remoteMachine.getTimeout()
                    + ", methodName:" + method.getName());
            InvocationContext.clean();
            return null;
        }

        RemotingCommand request = new RemotingCommand();
        request.setBody(requestBody);
        RemotingCommand response = null;
        try {
            response = clientContext.getNodeRemoting().invokeSync(remoteMachine.getChannel(), 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("[NodeServerInvocationHandler]: response is null"
                    + ", remoteMachine:" + remoteMachine.toString()
                    + ", 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.error("[NodeServerInvocationHandler]: responseBody is null"
                    + ", remoteMachine:" + remoteMachine.toString()
                    + ", timeout:" + remoteMachine.getTimeout()
                    + ", methodName:" + method.getName());
            return null;
        }

        String json = null;
        try {
            json = (String) BytesUtil.bytesToObject(responseBody);
        } catch (Throwable e) {
            logger.error("[NodeServerInvocationHandler]: bytesToObject error"
                    + ", remoteMachine:" + remoteMachine.toString()
                    + ", timeout:" + remoteMachine.getTimeout()
                    + ", methodName:" + method.getName(), e);
        }
        if (StringUtil.isBlank(json)) {
            logger.error("[NodeServerInvocationHandler]: json is null"
                    + ", remoteMachine:" + remoteMachine.toString()
                    + ", 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