Search in sources :

Example 1 with TFieldIdEnum

use of org.apache.thrift.TFieldIdEnum in project dubbo by alibaba.

the class ThriftCodec method encodeRequest.

private void encodeRequest(Channel channel, ChannelBuffer buffer, Request request) throws IOException {
    RpcInvocation inv = (RpcInvocation) request.getData();
    int seqId = nextSeqId();
    String serviceName = inv.getAttachment(Constants.INTERFACE_KEY);
    if (StringUtils.isEmpty(serviceName)) {
        throw new IllegalArgumentException(new StringBuilder(32).append("Could not find service name in attachment with key ").append(Constants.INTERFACE_KEY).toString());
    }
    TMessage message = new TMessage(inv.getMethodName(), TMessageType.CALL, seqId);
    String methodArgs = ExtensionLoader.getExtensionLoader(ClassNameGenerator.class).getExtension(channel.getUrl().getParameter(ThriftConstants.CLASS_NAME_GENERATOR_KEY, ThriftClassNameGenerator.NAME)).generateArgsClassName(serviceName, inv.getMethodName());
    if (StringUtils.isEmpty(methodArgs)) {
        throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, new StringBuilder(32).append("Could not encode request, the specified interface may be incorrect.").toString());
    }
    Class<?> clazz = cachedClass.get(methodArgs);
    if (clazz == null) {
        try {
            clazz = ClassHelper.forNameWithThreadContextClassLoader(methodArgs);
            cachedClass.putIfAbsent(methodArgs, clazz);
        } catch (ClassNotFoundException e) {
            throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
        }
    }
    TBase args;
    try {
        args = (TBase) clazz.newInstance();
    } catch (InstantiationException e) {
        throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
    } catch (IllegalAccessException e) {
        throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
    }
    for (int i = 0; i < inv.getArguments().length; i++) {
        Object obj = inv.getArguments()[i];
        if (obj == null) {
            continue;
        }
        TFieldIdEnum field = args.fieldForId(i + 1);
        String setMethodName = ThriftUtils.generateSetMethodName(field.getFieldName());
        Method method;
        try {
            method = clazz.getMethod(setMethodName, inv.getParameterTypes()[i]);
        } catch (NoSuchMethodException e) {
            throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
        }
        try {
            method.invoke(args, obj);
        } catch (IllegalAccessException e) {
            throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
        } catch (InvocationTargetException e) {
            throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
        }
    }
    RandomAccessByteArrayOutputStream bos = new RandomAccessByteArrayOutputStream(1024);
    TIOStreamTransport transport = new TIOStreamTransport(bos);
    TBinaryProtocol protocol = new TBinaryProtocol(transport);
    int headerLength, messageLength;
    byte[] bytes = new byte[4];
    try {
        // magic
        protocol.writeI16(MAGIC);
        // message length placeholder
        protocol.writeI32(Integer.MAX_VALUE);
        // message header length placeholder
        protocol.writeI16(Short.MAX_VALUE);
        // version
        protocol.writeByte(VERSION);
        // service name
        protocol.writeString(serviceName);
        // dubbo request id
        protocol.writeI64(request.getId());
        protocol.getTransport().flush();
        // header size
        headerLength = bos.size();
        // message body
        protocol.writeMessageBegin(message);
        args.write(protocol);
        protocol.writeMessageEnd();
        protocol.getTransport().flush();
        int oldIndex = messageLength = bos.size();
        // fill in message length and header length
        try {
            TFramedTransport.encodeFrameSize(messageLength, bytes);
            bos.setWriteIndex(MESSAGE_LENGTH_INDEX);
            protocol.writeI32(messageLength);
            bos.setWriteIndex(MESSAGE_HEADER_LENGTH_INDEX);
            protocol.writeI16((short) (0xffff & headerLength));
        } finally {
            bos.setWriteIndex(oldIndex);
        }
    } catch (TException e) {
        throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
    }
    buffer.writeBytes(bytes);
    buffer.writeBytes(bos.toByteArray());
}
Also used : RpcInvocation(com.alibaba.dubbo.rpc.RpcInvocation) TException(org.apache.thrift.TException) TIOStreamTransport(org.apache.thrift.transport.TIOStreamTransport) Method(java.lang.reflect.Method) InvocationTargetException(java.lang.reflect.InvocationTargetException) RandomAccessByteArrayOutputStream(com.alibaba.dubbo.rpc.protocol.thrift.io.RandomAccessByteArrayOutputStream) TBinaryProtocol(org.apache.thrift.protocol.TBinaryProtocol) TMessage(org.apache.thrift.protocol.TMessage) TFieldIdEnum(org.apache.thrift.TFieldIdEnum) RpcException(com.alibaba.dubbo.rpc.RpcException) TBase(org.apache.thrift.TBase)

Example 2 with TFieldIdEnum

use of org.apache.thrift.TFieldIdEnum in project jstorm by alibaba.

the class JStormUtils method thriftToMap.

public static Map<String, Object> thriftToMap(org.apache.thrift.TBase thriftObj) {
    Map<String, Object> ret = new HashMap<String, Object>();
    int i = 1;
    TFieldIdEnum field = thriftObj.fieldForId(i);
    while (field != null) {
        if (thriftObj.isSet(field)) {
            Object obj = thriftObj.getFieldValue(field);
            ret.put(field.getFieldName(), thriftToObject(obj));
        }
        field = thriftObj.fieldForId(++i);
    }
    return ret;
}
Also used : HashMap(java.util.HashMap) TFieldIdEnum(org.apache.thrift.TFieldIdEnum)

Example 3 with TFieldIdEnum

use of org.apache.thrift.TFieldIdEnum in project hive by apache.

the class ThriftUnionObjectInspector method init.

/**
   * This method is only intended to be used by Utilities class in this package.
   * The reason that this method is not recursive by itself is because we want
   * to allow recursive types.
   */
@Override
protected void init(Type type, Class<?> objectClass, ObjectInspectorFactory.ObjectInspectorOptions options) {
    this.type = type;
    verifyObjectClassType(objectClass);
    this.objectClass = objectClass;
    final Field fieldMetaData;
    try {
        fieldMetaData = objectClass.getDeclaredField(FIELD_METADATA_MAP);
        assert (Map.class.isAssignableFrom(fieldMetaData.getType()));
        fieldMetaData.setAccessible(true);
    } catch (NoSuchFieldException e) {
        throw new RuntimeException("Unable to find field metadata for thrift union field ", e);
    }
    try {
        final Map<? extends TFieldIdEnum, FieldMetaData> fieldMap = (Map<? extends TFieldIdEnum, FieldMetaData>) fieldMetaData.get(null);
        synchronized (this) {
            fields = new ArrayList<StandardStructObjectInspector.MyField>(fieldMap.size());
            this.ois = new ArrayList<ObjectInspector>();
            for (Map.Entry<? extends TFieldIdEnum, FieldMetaData> metadata : fieldMap.entrySet()) {
                int fieldId = metadata.getKey().getThriftFieldId();
                String fieldName = metadata.getValue().fieldName;
                final Type fieldType = ThriftObjectInspectorUtils.getFieldType(objectClass, fieldName);
                final ObjectInspector reflectionObjectInspector = ObjectInspectorFactory.getReflectionObjectInspector(fieldType, options, false);
                fields.add(new StandardStructObjectInspector.MyField(fieldId, fieldName, reflectionObjectInspector));
                this.ois.add(reflectionObjectInspector);
            }
            inited = true;
        }
    } catch (IllegalAccessException e) {
        throw new RuntimeException("Unable to find field metadata for thrift union field ", e);
    }
}
Also used : Field(java.lang.reflect.Field) FieldMetaData(org.apache.thrift.meta_data.FieldMetaData) Type(java.lang.reflect.Type) TFieldIdEnum(org.apache.thrift.TFieldIdEnum) Map(java.util.Map)

Example 4 with TFieldIdEnum

use of org.apache.thrift.TFieldIdEnum in project dubbo by alibaba.

the class ThriftCodec method encodeResponse.

private void encodeResponse(Channel channel, ChannelBuffer buffer, Response response) throws IOException {
    RpcResult result = (RpcResult) response.getResult();
    RequestData rd = cachedRequest.get(response.getId());
    String resultClassName = ExtensionLoader.getExtensionLoader(ClassNameGenerator.class).getExtension(channel.getUrl().getParameter(ThriftConstants.CLASS_NAME_GENERATOR_KEY, ThriftClassNameGenerator.NAME)).generateResultClassName(rd.serviceName, rd.methodName);
    if (StringUtils.isEmpty(resultClassName)) {
        throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, new StringBuilder(32).append("Could not encode response, the specified interface may be incorrect.").toString());
    }
    Class clazz = cachedClass.get(resultClassName);
    if (clazz == null) {
        try {
            clazz = ClassHelper.forNameWithThreadContextClassLoader(resultClassName);
            cachedClass.putIfAbsent(resultClassName, clazz);
        } catch (ClassNotFoundException e) {
            throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
        }
    }
    TBase resultObj;
    try {
        resultObj = (TBase) clazz.newInstance();
    } catch (InstantiationException e) {
        throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
    } catch (IllegalAccessException e) {
        throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
    }
    TApplicationException applicationException = null;
    TMessage message;
    if (result.hasException()) {
        Throwable throwable = result.getException();
        int index = 1;
        boolean found = false;
        while (true) {
            TFieldIdEnum fieldIdEnum = resultObj.fieldForId(index++);
            if (fieldIdEnum == null) {
                break;
            }
            String fieldName = fieldIdEnum.getFieldName();
            String getMethodName = ThriftUtils.generateGetMethodName(fieldName);
            String setMethodName = ThriftUtils.generateSetMethodName(fieldName);
            Method getMethod;
            Method setMethod;
            try {
                getMethod = clazz.getMethod(getMethodName);
                if (getMethod.getReturnType().equals(throwable.getClass())) {
                    found = true;
                    setMethod = clazz.getMethod(setMethodName, throwable.getClass());
                    setMethod.invoke(resultObj, throwable);
                }
            } catch (NoSuchMethodException e) {
                throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
            } catch (InvocationTargetException e) {
                throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
            } catch (IllegalAccessException e) {
                throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
            }
        }
        if (!found) {
            applicationException = new TApplicationException(throwable.getMessage());
        }
    } else {
        Object realResult = result.getResult();
        // result field id is 0
        String fieldName = resultObj.fieldForId(0).getFieldName();
        String setMethodName = ThriftUtils.generateSetMethodName(fieldName);
        String getMethodName = ThriftUtils.generateGetMethodName(fieldName);
        Method getMethod;
        Method setMethod;
        try {
            getMethod = clazz.getMethod(getMethodName);
            setMethod = clazz.getMethod(setMethodName, getMethod.getReturnType());
            setMethod.invoke(resultObj, realResult);
        } catch (NoSuchMethodException e) {
            throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
        } catch (InvocationTargetException e) {
            throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
        } catch (IllegalAccessException e) {
            throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
        }
    }
    if (applicationException != null) {
        message = new TMessage(rd.methodName, TMessageType.EXCEPTION, rd.id);
    } else {
        message = new TMessage(rd.methodName, TMessageType.REPLY, rd.id);
    }
    RandomAccessByteArrayOutputStream bos = new RandomAccessByteArrayOutputStream(1024);
    TIOStreamTransport transport = new TIOStreamTransport(bos);
    TBinaryProtocol protocol = new TBinaryProtocol(transport);
    int messageLength;
    int headerLength;
    byte[] bytes = new byte[4];
    try {
        // magic
        protocol.writeI16(MAGIC);
        // message length
        protocol.writeI32(Integer.MAX_VALUE);
        // message header length
        protocol.writeI16(Short.MAX_VALUE);
        // version
        protocol.writeByte(VERSION);
        // service name
        protocol.writeString(rd.serviceName);
        // id
        protocol.writeI64(response.getId());
        protocol.getTransport().flush();
        headerLength = bos.size();
        // message
        protocol.writeMessageBegin(message);
        switch(message.type) {
            case TMessageType.EXCEPTION:
                applicationException.write(protocol);
                break;
            case TMessageType.REPLY:
                resultObj.write(protocol);
                break;
        }
        protocol.writeMessageEnd();
        protocol.getTransport().flush();
        int oldIndex = messageLength = bos.size();
        try {
            TFramedTransport.encodeFrameSize(messageLength, bytes);
            bos.setWriteIndex(MESSAGE_LENGTH_INDEX);
            protocol.writeI32(messageLength);
            bos.setWriteIndex(MESSAGE_HEADER_LENGTH_INDEX);
            protocol.writeI16((short) (0xffff & headerLength));
        } finally {
            bos.setWriteIndex(oldIndex);
        }
    } catch (TException e) {
        throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
    }
    buffer.writeBytes(bytes);
    buffer.writeBytes(bos.toByteArray());
}
Also used : TException(org.apache.thrift.TException) TMessage(org.apache.thrift.protocol.TMessage) RpcException(com.alibaba.dubbo.rpc.RpcException) RpcResult(com.alibaba.dubbo.rpc.RpcResult) TIOStreamTransport(org.apache.thrift.transport.TIOStreamTransport) Method(java.lang.reflect.Method) InvocationTargetException(java.lang.reflect.InvocationTargetException) TApplicationException(org.apache.thrift.TApplicationException) RandomAccessByteArrayOutputStream(com.alibaba.dubbo.rpc.protocol.thrift.io.RandomAccessByteArrayOutputStream) TBinaryProtocol(org.apache.thrift.protocol.TBinaryProtocol) TFieldIdEnum(org.apache.thrift.TFieldIdEnum) TBase(org.apache.thrift.TBase)

Example 5 with TFieldIdEnum

use of org.apache.thrift.TFieldIdEnum in project dubbo by alibaba.

the class ThriftCodec method decode.

private Object decode(TProtocol protocol) throws IOException {
    // version
    String serviceName;
    long id;
    TMessage message;
    try {
        protocol.readI16();
        protocol.readByte();
        serviceName = protocol.readString();
        id = protocol.readI64();
        message = protocol.readMessageBegin();
    } catch (TException e) {
        throw new IOException(e.getMessage(), e);
    }
    if (message.type == TMessageType.CALL) {
        RpcInvocation result = new RpcInvocation();
        result.setAttachment(Constants.INTERFACE_KEY, serviceName);
        result.setMethodName(message.name);
        String argsClassName = ExtensionLoader.getExtensionLoader(ClassNameGenerator.class).getExtension(ThriftClassNameGenerator.NAME).generateArgsClassName(serviceName, message.name);
        if (StringUtils.isEmpty(argsClassName)) {
            throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, "The specified interface name incorrect.");
        }
        Class clazz = cachedClass.get(argsClassName);
        if (clazz == null) {
            try {
                clazz = ClassHelper.forNameWithThreadContextClassLoader(argsClassName);
                cachedClass.putIfAbsent(argsClassName, clazz);
            } catch (ClassNotFoundException e) {
                throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
            }
        }
        TBase args;
        try {
            args = (TBase) clazz.newInstance();
        } catch (InstantiationException e) {
            throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
        } catch (IllegalAccessException e) {
            throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
        }
        try {
            args.read(protocol);
            protocol.readMessageEnd();
        } catch (TException e) {
            throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
        }
        List<Object> parameters = new ArrayList<Object>();
        List<Class<?>> parameterTypes = new ArrayList<Class<?>>();
        int index = 1;
        while (true) {
            TFieldIdEnum fieldIdEnum = args.fieldForId(index++);
            if (fieldIdEnum == null) {
                break;
            }
            String fieldName = fieldIdEnum.getFieldName();
            String getMethodName = ThriftUtils.generateGetMethodName(fieldName);
            Method getMethod;
            try {
                getMethod = clazz.getMethod(getMethodName);
            } catch (NoSuchMethodException e) {
                throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
            }
            parameterTypes.add(getMethod.getReturnType());
            try {
                parameters.add(getMethod.invoke(args));
            } catch (IllegalAccessException e) {
                throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
            } catch (InvocationTargetException e) {
                throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
            }
        }
        result.setArguments(parameters.toArray());
        result.setParameterTypes(parameterTypes.toArray(new Class[parameterTypes.size()]));
        Request request = new Request(id);
        request.setData(result);
        cachedRequest.putIfAbsent(id, RequestData.create(message.seqid, serviceName, message.name));
        return request;
    } else if (message.type == TMessageType.EXCEPTION) {
        TApplicationException exception;
        try {
            exception = TApplicationException.read(protocol);
            protocol.readMessageEnd();
        } catch (TException e) {
            throw new IOException(e.getMessage(), e);
        }
        RpcResult result = new RpcResult();
        result.setException(new RpcException(exception.getMessage()));
        Response response = new Response();
        response.setResult(result);
        response.setId(id);
        return response;
    } else if (message.type == TMessageType.REPLY) {
        String resultClassName = ExtensionLoader.getExtensionLoader(ClassNameGenerator.class).getExtension(ThriftClassNameGenerator.NAME).generateResultClassName(serviceName, message.name);
        if (StringUtils.isEmpty(resultClassName)) {
            throw new IllegalArgumentException(new StringBuilder(32).append("Could not infer service result class name from service name ").append(serviceName).append(", the service name you specified may not generated by thrift idl compiler").toString());
        }
        Class<?> clazz = cachedClass.get(resultClassName);
        if (clazz == null) {
            try {
                clazz = ClassHelper.forNameWithThreadContextClassLoader(resultClassName);
                cachedClass.putIfAbsent(resultClassName, clazz);
            } catch (ClassNotFoundException e) {
                throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
            }
        }
        TBase<?, ? extends TFieldIdEnum> result;
        try {
            result = (TBase<?, ?>) clazz.newInstance();
        } catch (InstantiationException e) {
            throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
        } catch (IllegalAccessException e) {
            throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
        }
        try {
            result.read(protocol);
            protocol.readMessageEnd();
        } catch (TException e) {
            throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
        }
        Object realResult = null;
        int index = 0;
        while (true) {
            TFieldIdEnum fieldIdEnum = result.fieldForId(index++);
            if (fieldIdEnum == null) {
                break;
            }
            Field field;
            try {
                field = clazz.getDeclaredField(fieldIdEnum.getFieldName());
                field.setAccessible(true);
            } catch (NoSuchFieldException e) {
                throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
            }
            try {
                realResult = field.get(result);
            } catch (IllegalAccessException e) {
                throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
            }
            if (realResult != null) {
                break;
            }
        }
        Response response = new Response();
        response.setId(id);
        RpcResult rpcResult = new RpcResult();
        if (realResult instanceof Throwable) {
            rpcResult.setException((Throwable) realResult);
        } else {
            rpcResult.setValue(realResult);
        }
        response.setResult(rpcResult);
        return response;
    } else {
        // Impossible
        throw new IOException();
    }
}
Also used : TException(org.apache.thrift.TException) ArrayList(java.util.ArrayList) Field(java.lang.reflect.Field) TMessage(org.apache.thrift.protocol.TMessage) RpcException(com.alibaba.dubbo.rpc.RpcException) RpcInvocation(com.alibaba.dubbo.rpc.RpcInvocation) Request(com.alibaba.dubbo.remoting.exchange.Request) RpcResult(com.alibaba.dubbo.rpc.RpcResult) IOException(java.io.IOException) Method(java.lang.reflect.Method) InvocationTargetException(java.lang.reflect.InvocationTargetException) TApplicationException(org.apache.thrift.TApplicationException) Response(com.alibaba.dubbo.remoting.exchange.Response) TFieldIdEnum(org.apache.thrift.TFieldIdEnum) TBase(org.apache.thrift.TBase)

Aggregations

TFieldIdEnum (org.apache.thrift.TFieldIdEnum)6 RpcException (com.alibaba.dubbo.rpc.RpcException)3 InvocationTargetException (java.lang.reflect.InvocationTargetException)3 Method (java.lang.reflect.Method)3 TBase (org.apache.thrift.TBase)3 TException (org.apache.thrift.TException)3 TMessage (org.apache.thrift.protocol.TMessage)3 RpcInvocation (com.alibaba.dubbo.rpc.RpcInvocation)2 RpcResult (com.alibaba.dubbo.rpc.RpcResult)2 RandomAccessByteArrayOutputStream (com.alibaba.dubbo.rpc.protocol.thrift.io.RandomAccessByteArrayOutputStream)2 Field (java.lang.reflect.Field)2 HashMap (java.util.HashMap)2 TApplicationException (org.apache.thrift.TApplicationException)2 FieldMetaData (org.apache.thrift.meta_data.FieldMetaData)2 TBinaryProtocol (org.apache.thrift.protocol.TBinaryProtocol)2 TIOStreamTransport (org.apache.thrift.transport.TIOStreamTransport)2 Request (com.alibaba.dubbo.remoting.exchange.Request)1 Response (com.alibaba.dubbo.remoting.exchange.Response)1 IOException (java.io.IOException)1 Type (java.lang.reflect.Type)1