Search in sources :

Example 6 with TMessage

use of org.apache.thrift.protocol.TMessage in project dubbo by alibaba.

the class ThriftCodecTest method testDecodeRequest.

@Test
public void testDecodeRequest() throws Exception {
    Request request = createRequest();
    // encode
    RandomAccessByteArrayOutputStream bos = new RandomAccessByteArrayOutputStream(1024);
    TIOStreamTransport transport = new TIOStreamTransport(bos);
    TBinaryProtocol protocol = new TBinaryProtocol(transport);
    int messageLength, headerLength;
    protocol.writeI16(ThriftCodec.MAGIC);
    protocol.writeI32(Integer.MAX_VALUE);
    protocol.writeI16(Short.MAX_VALUE);
    protocol.writeByte(ThriftCodec.VERSION);
    protocol.writeString(((RpcInvocation) request.getData()).getAttachment(Constants.INTERFACE_KEY));
    protocol.writeI64(request.getId());
    protocol.getTransport().flush();
    headerLength = bos.size();
    Demo.echoString_args args = new Demo.echoString_args();
    args.setArg("Hell, World!");
    TMessage message = new TMessage("echoString", TMessageType.CALL, ThriftCodec.getSeqId());
    protocol.writeMessageBegin(message);
    args.write(protocol);
    protocol.writeMessageEnd();
    protocol.getTransport().flush();
    int oldIndex = messageLength = bos.size();
    try {
        bos.setWriteIndex(ThriftCodec.MESSAGE_HEADER_LENGTH_INDEX);
        protocol.writeI16((short) (0xffff & headerLength));
        bos.setWriteIndex(ThriftCodec.MESSAGE_LENGTH_INDEX);
        protocol.writeI32(messageLength);
    } finally {
        bos.setWriteIndex(oldIndex);
    }
    Object obj = codec.decode((Channel) null, ChannelBuffers.wrappedBuffer(encodeFrame(bos.toByteArray())));
    Assert.assertTrue(obj instanceof Request);
    obj = ((Request) obj).getData();
    Assert.assertTrue(obj instanceof RpcInvocation);
    RpcInvocation invocation = (RpcInvocation) obj;
    Assert.assertEquals("echoString", invocation.getMethodName());
    Assert.assertArrayEquals(new Class[] { String.class }, invocation.getParameterTypes());
    Assert.assertArrayEquals(new Object[] { args.getArg() }, invocation.getArguments());
}
Also used : RpcInvocation(com.alibaba.dubbo.rpc.RpcInvocation) Demo(com.alibaba.dubbo.rpc.gen.thrift.Demo) RandomAccessByteArrayOutputStream(com.alibaba.dubbo.rpc.protocol.thrift.io.RandomAccessByteArrayOutputStream) TBinaryProtocol(org.apache.thrift.protocol.TBinaryProtocol) TMessage(org.apache.thrift.protocol.TMessage) Request(com.alibaba.dubbo.remoting.exchange.Request) TIOStreamTransport(org.apache.thrift.transport.TIOStreamTransport) Test(org.junit.Test)

Example 7 with TMessage

use of org.apache.thrift.protocol.TMessage in project providence by morimekta.

the class TTupleProtocolSerializer method serialize.

@Override
public <Message extends PMessage<Message, Field>, Field extends PField> int serialize(@Nonnull OutputStream output, @Nonnull PServiceCall<Message, Field> call) throws IOException {
    CountingOutputStream wrapper = new CountingOutputStream(output);
    TTransport transport = new TIOStreamTransport(wrapper);
    try {
        TTupleProtocol protocol = (TTupleProtocol) protocolFactory.getProtocol(transport);
        TMessage tm = new TMessage(call.getMethod(), (byte) call.getType().asInteger(), call.getSequence());
        protocol.writeMessageBegin(tm);
        writeMessage(call.getMessage(), protocol);
        protocol.writeMessageEnd();
        transport.flush();
        wrapper.flush();
        return wrapper.getByteCount();
    } catch (TException e) {
        throw new SerializerException(e, e.getMessage());
    }
}
Also used : TException(org.apache.thrift.TException) CountingOutputStream(net.morimekta.util.io.CountingOutputStream) TMessage(org.apache.thrift.protocol.TMessage) TIOStreamTransport(org.apache.thrift.transport.TIOStreamTransport) TTransport(org.apache.thrift.transport.TTransport) SerializerException(net.morimekta.providence.serializer.SerializerException) TTupleProtocol(org.apache.thrift.protocol.TTupleProtocol)

Example 8 with TMessage

use of org.apache.thrift.protocol.TMessage in project accumulo by apache.

the class TServiceClientWrapper method receiveBase.

@Override
protected void receiveBase(TBase<?, ?> result, String methodName) throws TException {
    TMessage msg = iprot_.readMessageBegin();
    if (msg.type == TMessageType.EXCEPTION) {
        TApplicationException x = new TApplicationException();
        x.read(iprot_);
        iprot_.readMessageEnd();
        throw x;
    }
    if (msg.seqid != seqid_) {
        throw new TApplicationException(TApplicationException.BAD_SEQUENCE_ID, String.format("%s failed: out of sequence response: expected %d but got %d", methodName, seqid_, msg.seqid));
    }
    result.read(iprot_);
    iprot_.readMessageEnd();
}
Also used : TMessage(org.apache.thrift.protocol.TMessage) TApplicationException(org.apache.thrift.TApplicationException)

Example 9 with TMessage

use of org.apache.thrift.protocol.TMessage in project dubbo by alibaba.

the class ThriftCodec method decode.

private Object decode(TProtocol protocol) throws IOException {
    // version
    String serviceName;
    String path;
    long id;
    TMessage message;
    try {
        protocol.readI16();
        protocol.readByte();
        serviceName = protocol.readString();
        path = 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(INTERFACE_KEY, serviceName);
        result.setAttachment(PATH_KEY, path);
        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 = CACHED_CLASS.get(argsClassName);
        if (clazz == null) {
            try {
                clazz = ClassUtils.forNameWithThreadContextClassLoader(argsClassName);
                CACHED_CLASS.putIfAbsent(argsClassName, clazz);
            } catch (ClassNotFoundException e) {
                throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
            }
        }
        TBase args;
        try {
            args = (TBase) clazz.newInstance();
        } catch (InstantiationException | 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<>();
        List<Class<?>> parameterTypes = new ArrayList<>();
        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 | InvocationTargetException e) {
                throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
            }
        }
        result.setArguments(parameters.toArray());
        result.setParameterTypes(parameterTypes.toArray(new Class[0]));
        Request request = new Request(id);
        request.setData(result);
        CACHED_REQUEST.putIfAbsent(id, RequestData.create(message.seqid, serviceName, message.name));
        return request;
    } else if (message.type == TMessageType.EXCEPTION) {
        TApplicationException exception;
        try {
            exception = TApplicationException.readFrom(protocol);
            protocol.readMessageEnd();
        } catch (TException e) {
            throw new IOException(e.getMessage(), e);
        }
        AppResponse result = new AppResponse();
        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("Could not infer service result class name from service name " + serviceName + ", the service name you specified may not generated by thrift idl compiler");
        }
        Class<?> clazz = CACHED_CLASS.get(resultClassName);
        if (clazz == null) {
            try {
                clazz = ClassUtils.forNameWithThreadContextClassLoader(resultClassName);
                CACHED_CLASS.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 | 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());
                ReflectUtils.makeAccessible(field);
            } 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);
        AppResponse appResponse = new AppResponse();
        if (realResult instanceof Throwable) {
            appResponse.setException((Throwable) realResult);
        } else {
            appResponse.setValue(realResult);
        }
        response.setResult(appResponse);
        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) AppResponse(org.apache.dubbo.rpc.AppResponse) RpcException(org.apache.dubbo.rpc.RpcException) RpcInvocation(org.apache.dubbo.rpc.RpcInvocation) Request(org.apache.dubbo.remoting.exchange.Request) IOException(java.io.IOException) Method(java.lang.reflect.Method) InvocationTargetException(java.lang.reflect.InvocationTargetException) TApplicationException(org.apache.thrift.TApplicationException) AppResponse(org.apache.dubbo.rpc.AppResponse) Response(org.apache.dubbo.remoting.exchange.Response) TFieldIdEnum(org.apache.thrift.TFieldIdEnum) TBase(org.apache.thrift.TBase)

Example 10 with TMessage

use of org.apache.thrift.protocol.TMessage in project dubbo by alibaba.

the class ThriftCodec method encodeResponse.

private void encodeResponse(Channel channel, ChannelBuffer buffer, Response response) throws IOException {
    AppResponse result = (AppResponse) response.getResult();
    RequestData rd = CACHED_REQUEST.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, "Could not encode response, the specified interface may be incorrect.");
    }
    Class clazz = CACHED_CLASS.get(resultClassName);
    if (clazz == null) {
        try {
            clazz = ClassUtils.forNameWithThreadContextClassLoader(resultClassName);
            CACHED_CLASS.putIfAbsent(resultClassName, clazz);
        } catch (ClassNotFoundException e) {
            throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
        }
    }
    TBase resultObj;
    try {
        resultObj = (TBase) clazz.newInstance();
    } catch (InstantiationException | 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 | InvocationTargetException | IllegalAccessException e) {
                throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, e.getMessage(), e);
            }
        }
        if (!found) {
            applicationException = new TApplicationException(throwable.getMessage());
        }
    } else {
        Object realResult = result.getValue();
        // 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 | InvocationTargetException | 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;
            default:
        }
        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) AppResponse(org.apache.dubbo.rpc.AppResponse) RpcException(org.apache.dubbo.rpc.RpcException) TIOStreamTransport(org.apache.thrift.transport.TIOStreamTransport) Method(java.lang.reflect.Method) InvocationTargetException(java.lang.reflect.InvocationTargetException) TApplicationException(org.apache.thrift.TApplicationException) RandomAccessByteArrayOutputStream(org.apache.dubbo.rpc.protocol.thrift.io.RandomAccessByteArrayOutputStream) TBinaryProtocol(org.apache.thrift.protocol.TBinaryProtocol) TFieldIdEnum(org.apache.thrift.TFieldIdEnum) TBase(org.apache.thrift.TBase)

Aggregations

TMessage (org.apache.thrift.protocol.TMessage)29 TIOStreamTransport (org.apache.thrift.transport.TIOStreamTransport)20 TBinaryProtocol (org.apache.thrift.protocol.TBinaryProtocol)16 TException (org.apache.thrift.TException)15 TApplicationException (org.apache.thrift.TApplicationException)12 TTransport (org.apache.thrift.transport.TTransport)10 Request (com.alibaba.dubbo.remoting.exchange.Request)7 InvocationTargetException (java.lang.reflect.InvocationTargetException)7 Request (org.apache.dubbo.remoting.exchange.Request)7 RpcResult (com.alibaba.dubbo.rpc.RpcResult)6 Demo (com.alibaba.dubbo.rpc.gen.thrift.Demo)6 ByteArrayInputStream (java.io.ByteArrayInputStream)6 Method (java.lang.reflect.Method)6 AppResponse (org.apache.dubbo.rpc.AppResponse)6 Demo (org.apache.dubbo.rpc.gen.thrift.Demo)6 TBase (org.apache.thrift.TBase)6 TFieldIdEnum (org.apache.thrift.TFieldIdEnum)6 Test (org.junit.jupiter.api.Test)6 ChannelBuffer (com.alibaba.dubbo.remoting.buffer.ChannelBuffer)5 Response (com.alibaba.dubbo.remoting.exchange.Response)5