Search in sources :

Example 16 with Response

use of org.apache.dubbo.remoting.exchange.Response in project dubbo by alibaba.

the class ExchangeCodec method encodeResponse.

protected void encodeResponse(Channel channel, ChannelBuffer buffer, Response res) throws IOException {
    int savedWriteIndex = buffer.writerIndex();
    try {
        Serialization serialization = getSerialization(channel, res);
        // header.
        byte[] header = new byte[HEADER_LENGTH];
        // set magic number.
        Bytes.short2bytes(MAGIC, header);
        // set request and serialization flag.
        header[2] = serialization.getContentTypeId();
        if (res.isHeartbeat()) {
            header[2] |= FLAG_EVENT;
        }
        // set response status.
        byte status = res.getStatus();
        header[3] = status;
        // set request id.
        Bytes.long2bytes(res.getId(), header, 4);
        buffer.writerIndex(savedWriteIndex + HEADER_LENGTH);
        ChannelBufferOutputStream bos = new ChannelBufferOutputStream(buffer);
        // encode response data or error message.
        if (status == Response.OK) {
            if (res.isHeartbeat()) {
                // heartbeat response data is always null
                bos.write(CodecSupport.getNullBytesOf(serialization));
            } else {
                ObjectOutput out = serialization.serialize(channel.getUrl(), bos);
                if (res.isEvent()) {
                    encodeEventData(channel, out, res.getResult());
                } else {
                    encodeResponseData(channel, out, res.getResult(), res.getVersion());
                }
                out.flushBuffer();
                if (out instanceof Cleanable) {
                    ((Cleanable) out).cleanup();
                }
            }
        } else {
            ObjectOutput out = serialization.serialize(channel.getUrl(), bos);
            out.writeUTF(res.getErrorMessage());
            out.flushBuffer();
            if (out instanceof Cleanable) {
                ((Cleanable) out).cleanup();
            }
        }
        bos.flush();
        bos.close();
        int len = bos.writtenBytes();
        checkPayload(channel, len);
        Bytes.int2bytes(len, header, 12);
        // write
        buffer.writerIndex(savedWriteIndex);
        // write header.
        buffer.writeBytes(header);
        buffer.writerIndex(savedWriteIndex + HEADER_LENGTH + len);
    } catch (Throwable t) {
        // clear buffer
        buffer.writerIndex(savedWriteIndex);
        // send error message to Consumer, otherwise, Consumer will wait till timeout.
        if (!res.isEvent() && res.getStatus() != Response.BAD_RESPONSE) {
            Response r = new Response(res.getId(), res.getVersion());
            r.setStatus(Response.BAD_RESPONSE);
            if (t instanceof ExceedPayloadLimitException) {
                logger.warn(t.getMessage(), t);
                try {
                    r.setErrorMessage(t.getMessage());
                    channel.send(r);
                    return;
                } catch (RemotingException e) {
                    logger.warn("Failed to send bad_response info back: " + t.getMessage() + ", cause: " + e.getMessage(), e);
                }
            } else {
                // FIXME log error message in Codec and handle in caught() of IoHanndler?
                logger.warn("Fail to encode response: " + res + ", send bad_response info instead, cause: " + t.getMessage(), t);
                try {
                    r.setErrorMessage("Failed to send response: " + res + ", cause: " + StringUtils.toString(t));
                    channel.send(r);
                    return;
                } catch (RemotingException e) {
                    logger.warn("Failed to send bad_response info back: " + res + ", cause: " + e.getMessage(), e);
                }
            }
        }
        // Rethrow exception
        if (t instanceof IOException) {
            throw (IOException) t;
        } else if (t instanceof RuntimeException) {
            throw (RuntimeException) t;
        } else if (t instanceof Error) {
            throw (Error) t;
        } else {
            throw new RuntimeException(t.getMessage(), t);
        }
    }
}
Also used : ChannelBufferOutputStream(org.apache.dubbo.remoting.buffer.ChannelBufferOutputStream) ObjectOutput(org.apache.dubbo.common.serialize.ObjectOutput) IOException(java.io.IOException) Serialization(org.apache.dubbo.common.serialize.Serialization) Response(org.apache.dubbo.remoting.exchange.Response) RemotingException(org.apache.dubbo.remoting.RemotingException) ExceedPayloadLimitException(org.apache.dubbo.remoting.transport.ExceedPayloadLimitException) Cleanable(org.apache.dubbo.common.serialize.Cleanable)

Example 17 with Response

use of org.apache.dubbo.remoting.exchange.Response in project dubbo by alibaba.

the class ExchangeCodec method finishRespWhenOverPayload.

private Object finishRespWhenOverPayload(Channel channel, long size, byte[] header) {
    int payload = getPayload(channel);
    boolean overPayload = isOverPayload(payload, size);
    if (overPayload) {
        long reqId = Bytes.bytes2long(header, 4);
        byte flag = header[2];
        if ((flag & FLAG_REQUEST) == 0) {
            Response res = new Response(reqId);
            if ((flag & FLAG_EVENT) != 0) {
                res.setEvent(true);
            }
            res.setStatus(Response.CLIENT_ERROR);
            String errorMsg = "Data length too large: " + size + ", max payload: " + payload + ", channel: " + channel;
            logger.error(errorMsg);
            res.setErrorMessage(errorMsg);
            return res;
        }
    }
    return null;
}
Also used : Response(org.apache.dubbo.remoting.exchange.Response)

Example 18 with Response

use of org.apache.dubbo.remoting.exchange.Response in project dubbo by alibaba.

the class NettyClientHandler method write.

@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
    super.write(ctx, msg, promise);
    final NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);
    final boolean isRequest = msg instanceof Request;
    // We add listeners to make sure our out bound event is correct.
    // If our out bound event has an error (in most cases the encoder fails),
    // we need to have the request return directly instead of blocking the invoke process.
    promise.addListener(future -> {
        if (future.isSuccess()) {
            // if our future is success, mark the future to sent.
            handler.sent(channel, msg);
            return;
        }
        Throwable t = future.cause();
        if (t != null && isRequest) {
            Request request = (Request) msg;
            Response response = buildErrorResponse(request, t);
            handler.received(channel, response);
        }
    });
}
Also used : Response(org.apache.dubbo.remoting.exchange.Response) Request(org.apache.dubbo.remoting.exchange.Request)

Example 19 with Response

use of org.apache.dubbo.remoting.exchange.Response in project dubbo by alibaba.

the class NettyClientHandler method buildErrorResponse.

/**
 * build a bad request's response
 *
 * @param request the request
 * @param t       the throwable. In most cases, serialization fails.
 * @return the response
 */
private static Response buildErrorResponse(Request request, Throwable t) {
    Response response = new Response(request.getId(), request.getVersion());
    response.setStatus(Response.BAD_REQUEST);
    response.setErrorMessage(StringUtils.toString(t));
    return response;
}
Also used : Response(org.apache.dubbo.remoting.exchange.Response)

Example 20 with Response

use of org.apache.dubbo.remoting.exchange.Response in project dubbo by alibaba.

the class ThriftCodecTest method testDecodeExceptionResponse.

@Test
public void testDecodeExceptionResponse() throws Exception {
    int port = NetUtils.getAvailablePort();
    URL url = URL.valueOf(ThriftProtocol.NAME + "://127.0.0.1:" + port + "/" + Demo.class.getName());
    Channel channel = new MockedChannel(url);
    RandomAccessByteArrayOutputStream bos = new RandomAccessByteArrayOutputStream(128);
    Request request = createRequest();
    DefaultFuture future = DefaultFuture.newFuture(channel, request, 10, null);
    TMessage message = new TMessage("echoString", TMessageType.EXCEPTION, ThriftCodec.getSeqId());
    TTransport transport = new TIOStreamTransport(bos);
    TBinaryProtocol protocol = new TBinaryProtocol(transport);
    TApplicationException exception = new TApplicationException();
    int messageLength, headerLength;
    // prepare
    protocol.writeI16(ThriftCodec.MAGIC);
    protocol.writeI32(Integer.MAX_VALUE);
    protocol.writeI16(Short.MAX_VALUE);
    protocol.writeByte(ThriftCodec.VERSION);
    protocol.writeString(Demo.class.getName());
    // path
    protocol.writeString(Demo.class.getName());
    protocol.writeI64(request.getId());
    protocol.getTransport().flush();
    headerLength = bos.size();
    protocol.writeMessageBegin(message);
    exception.write(protocol);
    protocol.writeMessageEnd();
    protocol.getTransport().flush();
    int oldIndex = messageLength = bos.size();
    try {
        bos.setWriteIndex(ThriftCodec.MESSAGE_LENGTH_INDEX);
        protocol.writeI32(messageLength);
        bos.setWriteIndex(ThriftCodec.MESSAGE_HEADER_LENGTH_INDEX);
        protocol.writeI16((short) (0xffff & headerLength));
    } finally {
        bos.setWriteIndex(oldIndex);
    }
    // prepare
    ChannelBuffer bis = ChannelBuffers.wrappedBuffer(encodeFrame(bos.toByteArray()));
    Object obj = codec.decode((Channel) null, bis);
    Assertions.assertNotNull(obj);
    Assertions.assertTrue(obj instanceof Response);
    Response response = (Response) obj;
    Assertions.assertTrue(response.getResult() instanceof AppResponse);
    AppResponse result = (AppResponse) response.getResult();
    Assertions.assertTrue(result.hasException());
    Assertions.assertTrue(result.getException() instanceof RpcException);
}
Also used : Demo(org.apache.dubbo.rpc.gen.thrift.Demo) Channel(org.apache.dubbo.remoting.Channel) Request(org.apache.dubbo.remoting.exchange.Request) TIOStreamTransport(org.apache.thrift.transport.TIOStreamTransport) URL(org.apache.dubbo.common.URL) DefaultFuture(org.apache.dubbo.remoting.exchange.support.DefaultFuture) TApplicationException(org.apache.thrift.TApplicationException) ChannelBuffer(org.apache.dubbo.remoting.buffer.ChannelBuffer) AppResponse(org.apache.dubbo.rpc.AppResponse) Response(org.apache.dubbo.remoting.exchange.Response) RandomAccessByteArrayOutputStream(org.apache.dubbo.rpc.protocol.thrift.io.RandomAccessByteArrayOutputStream) TBinaryProtocol(org.apache.thrift.protocol.TBinaryProtocol) TMessage(org.apache.thrift.protocol.TMessage) AppResponse(org.apache.dubbo.rpc.AppResponse) RpcException(org.apache.dubbo.rpc.RpcException) TTransport(org.apache.thrift.transport.TTransport) Test(org.junit.jupiter.api.Test)

Aggregations

Response (org.apache.dubbo.remoting.exchange.Response)39 Request (org.apache.dubbo.remoting.exchange.Request)21 Test (org.junit.jupiter.api.Test)20 Channel (org.apache.dubbo.remoting.Channel)12 ChannelBuffer (org.apache.dubbo.remoting.buffer.ChannelBuffer)9 IOException (java.io.IOException)6 RemotingException (org.apache.dubbo.remoting.RemotingException)6 AppResponse (org.apache.dubbo.rpc.AppResponse)6 ExchangeChannel (org.apache.dubbo.remoting.exchange.ExchangeChannel)5 TMessage (org.apache.thrift.protocol.TMessage)5 ByteArrayInputStream (java.io.ByteArrayInputStream)4 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)4 URL (org.apache.dubbo.common.URL)4 Demo (org.apache.dubbo.rpc.gen.thrift.Demo)4 TBinaryProtocol (org.apache.thrift.protocol.TBinaryProtocol)4 TIOStreamTransport (org.apache.thrift.transport.TIOStreamTransport)4 DefaultFuture (org.apache.dubbo.remoting.exchange.support.DefaultFuture)3 HeaderExchangeHandler (org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler)3 TApplicationException (org.apache.thrift.TApplicationException)3 ObjectInput (org.apache.dubbo.common.serialize.ObjectInput)2