Search in sources :

Example 91 with Response

use of com.linkedin.r2.message.Response in project rest.li by linkedin.

the class TestHttpNettyStreamClient method testResponseSize.

public void testResponseSize(AbstractNettyStreamClient client, int responseSize, int expectedResult) throws Exception {
    Server server = new HttpServerBuilder().responseSize(responseSize).build();
    try {
        server.start();
        RestRequest r = new RestRequestBuilder(new URI(URL)).build();
        FutureCallback<StreamResponse> cb = new FutureCallback<StreamResponse>();
        TransportCallback<StreamResponse> callback = new TransportCallbackAdapter<StreamResponse>(cb);
        client.streamRequest(Messages.toStreamRequest(r), new RequestContext(), new HashMap<String, String>(), callback);
        StreamResponse response = cb.get(30, TimeUnit.SECONDS);
        final CountDownLatch latch = new CountDownLatch(1);
        final AtomicReference<Throwable> error = new AtomicReference<Throwable>();
        response.getEntityStream().setReader(new Reader() {

            @Override
            public void onInit(ReadHandle rh) {
                rh.request(Integer.MAX_VALUE);
            }

            @Override
            public void onDataAvailable(ByteString data) {
            }

            @Override
            public void onDone() {
                latch.countDown();
            }

            @Override
            public void onError(Throwable e) {
                error.set(e);
                latch.countDown();
            }
        });
        if (!latch.await(30, TimeUnit.SECONDS)) {
            Assert.fail("Timeout waiting for response");
        }
        if (expectedResult == TOO_LARGE) {
            Assert.assertNotNull(error.get(), "Max response size exceeded, expected exception. ");
            verifyCauseChain(error.get(), TooLongFrameException.class);
        }
        if (expectedResult == RESPONSE_OK) {
            Assert.assertNull(error.get(), "Unexpected Exception: response size <= max size");
        }
    } catch (ExecutionException e) {
        if (expectedResult == RESPONSE_OK) {
            Assert.fail("Unexpected ExecutionException, response was <= max response size.", e);
        }
        verifyCauseChain(e, RemoteInvocationException.class, TooLongFrameException.class);
    } finally {
        server.stop();
    }
}
Also used : TransportCallbackAdapter(com.linkedin.r2.transport.common.bridge.client.TransportCallbackAdapter) TooLongFrameException(io.netty.handler.codec.TooLongFrameException) Server(org.eclipse.jetty.server.Server) ByteString(com.linkedin.data.ByteString) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) Reader(com.linkedin.r2.message.stream.entitystream.Reader) AtomicReference(java.util.concurrent.atomic.AtomicReference) AsciiString(io.netty.util.AsciiString) ByteString(com.linkedin.data.ByteString) CountDownLatch(java.util.concurrent.CountDownLatch) URI(java.net.URI) ReadHandle(com.linkedin.r2.message.stream.entitystream.ReadHandle) RestRequest(com.linkedin.r2.message.rest.RestRequest) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) RequestContext(com.linkedin.r2.message.RequestContext) RemoteInvocationException(com.linkedin.r2.RemoteInvocationException) ExecutionException(java.util.concurrent.ExecutionException) FutureCallback(com.linkedin.common.callback.FutureCallback)

Example 92 with Response

use of com.linkedin.r2.message.Response in project rest.li by linkedin.

the class TestHttpNettyStreamClient method testStreamRequests.

/**
   * Tests implementations of {@link AbstractNettyStreamClient} with different request dimensions.
   *
   * @param client Client implementation of {@link AbstractNettyStreamClient}
   * @param method HTTP request method
   * @param requestSize Request content size
   * @param responseSize Response content size
   * @param isFullRequest Whether to buffer a full request before stream
   * @throws Exception
   */
@Test(dataProvider = "requestResponseParameters")
public void testStreamRequests(AbstractNettyStreamClient client, String method, int requestSize, int responseSize, boolean isFullRequest) throws Exception {
    AtomicInteger succeeded = new AtomicInteger(0);
    AtomicInteger failed = new AtomicInteger(0);
    Server server = new HttpServerBuilder().responseSize(responseSize).build();
    try {
        server.start();
        CountDownLatch latch = new CountDownLatch(REQUEST_COUNT);
        for (int i = 0; i < REQUEST_COUNT; i++) {
            StreamRequest request = new StreamRequestBuilder(new URI(URL)).setMethod(method).setHeader(HttpHeaderNames.HOST.toString(), HOST_NAME.toString()).build(EntityStreams.newEntityStream(new ByteStringWriter(ByteString.copy(new byte[requestSize]))));
            RequestContext context = new RequestContext();
            context.putLocalAttr(R2Constants.IS_FULL_REQUEST, isFullRequest);
            client.streamRequest(request, context, new HashMap<>(), new TransportCallbackAdapter<>(new Callback<StreamResponse>() {

                @Override
                public void onSuccess(StreamResponse response) {
                    response.getEntityStream().setReader(new Reader() {

                        ReadHandle _rh;

                        int _consumed = 0;

                        @Override
                        public void onDataAvailable(ByteString data) {
                            _consumed += data.length();
                            _rh.request(1);
                        }

                        @Override
                        public void onDone() {
                            succeeded.incrementAndGet();
                            latch.countDown();
                        }

                        @Override
                        public void onError(Throwable e) {
                            failed.incrementAndGet();
                            latch.countDown();
                        }

                        @Override
                        public void onInit(ReadHandle rh) {
                            _rh = rh;
                            _rh.request(1);
                        }
                    });
                }

                @Override
                public void onError(Throwable e) {
                    failed.incrementAndGet();
                    latch.countDown();
                }
            }));
        }
        if (!latch.await(30, TimeUnit.SECONDS)) {
            Assert.fail("Timeout waiting for responses. " + succeeded + " requests succeeded and " + failed + " requests failed out of total " + REQUEST_COUNT + " requests");
        }
        Assert.assertEquals(latch.getCount(), 0);
        Assert.assertEquals(failed.get(), 0);
        Assert.assertEquals(succeeded.get(), REQUEST_COUNT);
        FutureCallback<None> shutdownCallback = new FutureCallback<>();
        client.shutdown(shutdownCallback);
        shutdownCallback.get(30, TimeUnit.SECONDS);
    } finally {
        server.stop();
    }
}
Also used : Server(org.eclipse.jetty.server.Server) ByteString(com.linkedin.data.ByteString) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) Reader(com.linkedin.r2.message.stream.entitystream.Reader) CountDownLatch(java.util.concurrent.CountDownLatch) StreamRequestBuilder(com.linkedin.r2.message.stream.StreamRequestBuilder) URI(java.net.URI) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) ReadHandle(com.linkedin.r2.message.stream.entitystream.ReadHandle) TransportCallback(com.linkedin.r2.transport.common.bridge.common.TransportCallback) FutureCallback(com.linkedin.common.callback.FutureCallback) Callback(com.linkedin.common.callback.Callback) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) RequestContext(com.linkedin.r2.message.RequestContext) ByteStringWriter(com.linkedin.r2.message.stream.entitystream.ByteStringWriter) None(com.linkedin.common.util.None) FutureCallback(com.linkedin.common.callback.FutureCallback) Test(org.testng.annotations.Test)

Example 93 with Response

use of com.linkedin.r2.message.Response in project rest.li by linkedin.

the class Http2FrameListener method onHeadersRead.

@Override
public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers, int padding, boolean endOfStream) throws Http2Exception {
    LOG.debug("Received HTTP/2 HEADERS frame, stream={}, end={}, headers={}, padding={}bytes", new Object[] { streamId, endOfStream, headers.size(), padding });
    // Ignores response for the upgrade request
    if (streamId == Http2CodecUtil.HTTP_UPGRADE_STREAM_ID) {
        return;
    }
    final StreamResponseBuilder builder = new StreamResponseBuilder();
    // Process HTTP/2 pseudo headers
    if (headers.status() != null) {
        builder.setStatus(Integer.parseInt(headers.status().toString()));
    }
    if (headers.authority() != null) {
        builder.addHeaderValue(HttpHeaderNames.HOST.toString(), headers.authority().toString());
    }
    // Process other HTTP headers
    for (Map.Entry<CharSequence, CharSequence> header : headers) {
        if (Http2Headers.PseudoHeaderName.isPseudoHeader(header.getKey())) {
            // Do no set HTTP/2 pseudo headers to response
            continue;
        }
        final String key = header.getKey().toString();
        final String value = header.getValue().toString();
        if (key.equalsIgnoreCase(HttpConstants.RESPONSE_COOKIE_HEADER_NAME)) {
            builder.addCookie(value);
        } else {
            builder.unsafeAddHeaderValue(key, value);
        }
    }
    // Gets async pool handle from stream properties
    Http2Connection.PropertyKey handleKey = ctx.channel().attr(Http2ClientPipelineInitializer.CHANNEL_POOL_HANDLE_ATTR_KEY).get();
    TimeoutAsyncPoolHandle<?> handle = _connection.stream(streamId).removeProperty(handleKey);
    if (handle == null) {
        _lifecycleManager.onError(ctx, Http2Exception.connectionError(Http2Error.PROTOCOL_ERROR, "No channel pool handle is associated with this stream", streamId));
        return;
    }
    final StreamResponse response;
    if (endOfStream) {
        response = builder.build(EntityStreams.emptyStream());
        ctx.fireChannelRead(handle);
    } else {
        // Associate an entity stream writer to the HTTP/2 stream
        final TimeoutBufferedWriter writer = new TimeoutBufferedWriter(ctx, streamId, _maxContentLength, handle);
        if (_connection.stream(streamId).setProperty(_writerKey, writer) != null) {
            _lifecycleManager.onError(ctx, Http2Exception.connectionError(Http2Error.PROTOCOL_ERROR, "Another writer has already been associated with current stream ID", streamId));
            return;
        }
        // Prepares StreamResponse for the channel pipeline
        EntityStream entityStream = EntityStreams.newEntityStream(writer);
        response = builder.build(entityStream);
    }
    // Gets callback from stream properties
    Http2Connection.PropertyKey callbackKey = ctx.channel().attr(Http2ClientPipelineInitializer.CALLBACK_ATTR_KEY).get();
    TransportCallback<?> callback = _connection.stream(streamId).removeProperty(callbackKey);
    if (callback != null) {
        ctx.fireChannelRead(new ResponseWithCallback<Response, TransportCallback<?>>(response, callback));
    }
}
Also used : TransportCallback(com.linkedin.r2.transport.common.bridge.common.TransportCallback) StreamResponseBuilder(com.linkedin.r2.message.stream.StreamResponseBuilder) Http2Connection(io.netty.handler.codec.http2.Http2Connection) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) ByteString(com.linkedin.data.ByteString) EntityStream(com.linkedin.r2.message.stream.entitystream.EntityStream) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) Response(com.linkedin.r2.message.Response) Map(java.util.Map)

Example 94 with Response

use of com.linkedin.r2.message.Response in project rest.li by linkedin.

the class TestChannelPoolStreamHandler method getChannel.

private static EmbeddedChannel getChannel() {
    EmbeddedChannel ch = new EmbeddedChannel(new RAPResponseDecoder(1000), new RAPStreamResponseHandler(), new ChannelPoolStreamHandler());
    ch.attr(RAPResponseDecoder.TIMEOUT_ATTR_KEY).set(new Timeout<None>(Executors.newSingleThreadScheduledExecutor(), 1000, TimeUnit.MILLISECONDS, None.none()));
    ch.attr(RAPStreamResponseHandler.CALLBACK_ATTR_KEY).set(response -> {
        StreamResponse streamResponse = response.getResponse();
        streamResponse.getEntityStream().setReader(new DrainReader());
    });
    return ch;
}
Also used : StreamResponse(com.linkedin.r2.message.stream.StreamResponse) EmbeddedChannel(io.netty.channel.embedded.EmbeddedChannel) None(com.linkedin.common.util.None) DrainReader(com.linkedin.r2.message.stream.entitystream.DrainReader)

Example 95 with Response

use of com.linkedin.r2.message.Response in project rest.li by linkedin.

the class TestChannelPoolHandler method testConnectionKeepAlive.

@Test(dataProvider = "connectionKeepAlive")
public void testConnectionKeepAlive(String headerName, String headerValue) {
    EmbeddedChannel ch = new EmbeddedChannel(new ChannelPoolHandler());
    FakePool pool = new FakePool();
    ch.attr(ChannelPoolHandler.CHANNEL_POOL_ATTR_KEY).set(pool);
    RestResponse response = new RestResponseBuilder().setHeader(headerName, headerValue).build();
    ch.writeInbound(response);
    Assert.assertFalse(pool.isDisposeCalled());
    Assert.assertTrue(pool.isPutCalled());
}
Also used : RestResponse(com.linkedin.r2.message.rest.RestResponse) RestResponseBuilder(com.linkedin.r2.message.rest.RestResponseBuilder) EmbeddedChannel(io.netty.channel.embedded.EmbeddedChannel) Test(org.testng.annotations.Test)

Aggregations

RestResponse (com.linkedin.r2.message.rest.RestResponse)100 Test (org.testng.annotations.Test)95 RestRequest (com.linkedin.r2.message.rest.RestRequest)63 RequestContext (com.linkedin.r2.message.RequestContext)51 RestRequestBuilder (com.linkedin.r2.message.rest.RestRequestBuilder)47 URI (java.net.URI)45 ByteString (com.linkedin.data.ByteString)42 StreamResponse (com.linkedin.r2.message.stream.StreamResponse)37 RestException (com.linkedin.r2.message.rest.RestException)32 HashMap (java.util.HashMap)29 FutureCallback (com.linkedin.common.callback.FutureCallback)25 StreamRequest (com.linkedin.r2.message.stream.StreamRequest)25 ExecutionException (java.util.concurrent.ExecutionException)25 RestResponseBuilder (com.linkedin.r2.message.rest.RestResponseBuilder)24 StreamRequestBuilder (com.linkedin.r2.message.stream.StreamRequestBuilder)22 CountDownLatch (java.util.concurrent.CountDownLatch)22 URISyntaxException (java.net.URISyntaxException)21 TransportCallback (com.linkedin.r2.transport.common.bridge.common.TransportCallback)18 IOException (java.io.IOException)18 Map (java.util.Map)17