Search in sources :

Example 1 with StreamException

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

the class TrackerClientTest method testCallTrackingStreamRequest.

@Test
public void testCallTrackingStreamRequest() throws Exception {
    URI uri = URI.create("http://test.qa.com:1234/foo");
    SettableClock clock = new SettableClock();
    AtomicInteger action = new AtomicInteger(0);
    TransportClient tc = new TransportClient() {

        @Override
        public void restRequest(RestRequest request, RequestContext requestContext, Map<String, String> wireAttrs, TransportCallback<RestResponse> callback) {
        }

        @Override
        public void streamRequest(StreamRequest request, RequestContext requestContext, Map<String, String> wireAttrs, TransportCallback<StreamResponse> callback) {
            clock.addDuration(5);
            switch(action.get()) {
                // success
                case 0:
                    callback.onResponse(TransportResponseImpl.success(new StreamResponseBuilder().build(EntityStreams.emptyStream())));
                    break;
                // fail with stream exception
                case 1:
                    callback.onResponse(TransportResponseImpl.error(new StreamException(new StreamResponseBuilder().setStatus(500).build(EntityStreams.emptyStream()))));
                    break;
                // fail with timeout exception
                case 2:
                    callback.onResponse(TransportResponseImpl.error(new RemoteInvocationException(new TimeoutException())));
                    break;
                // fail with other exception
                default:
                    callback.onResponse(TransportResponseImpl.error(new RuntimeException()));
                    break;
            }
        }

        @Override
        public void shutdown(Callback<None> callback) {
        }
    };
    TrackerClient client = createTrackerClient(tc, clock, uri);
    CallTracker callTracker = client.getCallTracker();
    CallTracker.CallStats stats;
    DegraderControl degraderControl = client.getDegraderControl(DefaultPartitionAccessor.DEFAULT_PARTITION_ID);
    DelayConsumeCallback delayConsumeCallback = new DelayConsumeCallback();
    client.streamRequest(new StreamRequestBuilder(uri).build(EntityStreams.emptyStream()), new RequestContext(), new HashMap<>(), delayConsumeCallback);
    clock.addDuration(5);
    // we only recorded the time when stream response arrives, but callcompletion.endcall hasn't been called yet.
    Assert.assertEquals(callTracker.getCurrentCallCountTotal(), 0);
    Assert.assertEquals(callTracker.getCurrentErrorCountTotal(), 0);
    // delay
    clock.addDuration(100);
    delayConsumeCallback.consume();
    clock.addDuration(5000);
    // now that we consumed the entity stream, callcompletion.endcall has been called.
    stats = callTracker.getCallStats();
    Assert.assertEquals(stats.getCallCount(), 1);
    Assert.assertEquals(stats.getErrorCount(), 0);
    Assert.assertEquals(stats.getCallCountTotal(), 1);
    Assert.assertEquals(stats.getErrorCountTotal(), 0);
    Assert.assertEquals(degraderControl.getCurrentComputedDropRate(), 0.0, 0.001);
    action.set(1);
    client.streamRequest(new StreamRequestBuilder(uri).build(EntityStreams.emptyStream()), new RequestContext(), new HashMap<>(), delayConsumeCallback);
    clock.addDuration(5);
    // we endcall with error immediately for stream exception, even before the entity is consumed
    Assert.assertEquals(callTracker.getCurrentCallCountTotal(), 2);
    Assert.assertEquals(callTracker.getCurrentErrorCountTotal(), 1);
    delayConsumeCallback.consume();
    clock.addDuration(5000);
    // no change in tracking after entity is consumed
    stats = callTracker.getCallStats();
    Assert.assertEquals(stats.getCallCount(), 1);
    Assert.assertEquals(stats.getErrorCount(), 1);
    Assert.assertEquals(stats.getCallCountTotal(), 2);
    Assert.assertEquals(stats.getErrorCountTotal(), 1);
    Assert.assertEquals(degraderControl.getCurrentComputedDropRate(), 0.2, 0.001);
    action.set(2);
    client.streamRequest(new StreamRequestBuilder(uri).build(EntityStreams.emptyStream()), new RequestContext(), new HashMap<>(), new TestTransportCallback<>());
    clock.addDuration(5);
    Assert.assertEquals(callTracker.getCurrentCallCountTotal(), 3);
    Assert.assertEquals(callTracker.getCurrentErrorCountTotal(), 2);
    clock.addDuration(5000);
    stats = callTracker.getCallStats();
    Assert.assertEquals(stats.getCallCount(), 1);
    Assert.assertEquals(stats.getErrorCount(), 1);
    Assert.assertEquals(stats.getCallCountTotal(), 3);
    Assert.assertEquals(stats.getErrorCountTotal(), 2);
    Assert.assertEquals(degraderControl.getCurrentComputedDropRate(), 0.4, 0.001);
    action.set(3);
    client.streamRequest(new StreamRequestBuilder(uri).build(EntityStreams.emptyStream()), new RequestContext(), new HashMap<>(), new TestTransportCallback<>());
    clock.addDuration(5);
    Assert.assertEquals(callTracker.getCurrentCallCountTotal(), 4);
    Assert.assertEquals(callTracker.getCurrentErrorCountTotal(), 3);
    clock.addDuration(5000);
    stats = callTracker.getCallStats();
    Assert.assertEquals(stats.getCallCount(), 1);
    Assert.assertEquals(stats.getErrorCount(), 1);
    Assert.assertEquals(stats.getCallCountTotal(), 4);
    Assert.assertEquals(stats.getErrorCountTotal(), 3);
    Assert.assertEquals(degraderControl.getCurrentComputedDropRate(), 0.2, 0.001);
}
Also used : TransportCallback(com.linkedin.r2.transport.common.bridge.common.TransportCallback) TransportClient(com.linkedin.r2.transport.common.bridge.client.TransportClient) StreamResponseBuilder(com.linkedin.r2.message.stream.StreamResponseBuilder) DegraderControl(com.linkedin.util.degrader.DegraderControl) URI(java.net.URI) StreamRequestBuilder(com.linkedin.r2.message.stream.StreamRequestBuilder) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) StreamException(com.linkedin.r2.message.stream.StreamException) RestRequest(com.linkedin.r2.message.rest.RestRequest) Callback(com.linkedin.common.callback.Callback) TransportCallback(com.linkedin.r2.transport.common.bridge.common.TransportCallback) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SettableClock(com.linkedin.util.clock.SettableClock) RequestContext(com.linkedin.r2.message.RequestContext) RemoteInvocationException(com.linkedin.r2.RemoteInvocationException) HashMap(java.util.HashMap) Map(java.util.Map) TimeoutException(java.util.concurrent.TimeoutException) CallTracker(com.linkedin.util.degrader.CallTracker) Test(org.testng.annotations.Test)

Example 2 with StreamException

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

the class TestServerTimeoutAsyncEvent method testFilterNotCancelButShouldNotTimeout.

@Test
public void testFilterNotCancelButShouldNotTimeout() throws Exception {
    RestRequest request = new RestRequestBuilder(Bootstrap.createHttpURI(PORT, STREAM_EXCEPTION_FILTER_URI)).setEntity(new byte[10240]).build();
    _client.restRequest(request);
    Future<RestResponse> futureResponse = _client.restRequest(request);
    // if server times out, our second request would fail with TimeoutException because it's blocked by first one
    try {
        futureResponse.get(ASYNC_EVENT_TIMEOUT / 2, TimeUnit.MILLISECONDS);
        Assert.fail("Should fail with ExecutionException");
    } catch (ExecutionException ex) {
        Assert.assertTrue(ex.getCause() instanceof RestException);
        RestException restException = (RestException) ex.getCause();
        Assert.assertTrue(restException.getResponse().getEntity().asString("UTF8").contains("StreamException in filter."));
    }
}
Also used : RestRequest(com.linkedin.r2.message.rest.RestRequest) RestResponse(com.linkedin.r2.message.rest.RestResponse) RestException(com.linkedin.r2.message.rest.RestException) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) ExecutionException(java.util.concurrent.ExecutionException) Test(org.testng.annotations.Test)

Example 3 with StreamException

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

the class TestResponseCompression method testEncodingNotAcceptable.

public void testEncodingNotAcceptable(String acceptEncoding) throws TimeoutException, InterruptedException {
    for (Client client : clients()) {
        StreamRequestBuilder builder = new StreamRequestBuilder((Bootstrap.createHttpURI(PORT, SMALL_URI)));
        if (acceptEncoding != null) {
            builder.addHeaderValue(HttpConstants.ACCEPT_ENCODING, acceptEncoding);
        }
        StreamRequest request = builder.build(EntityStreams.emptyStream());
        final FutureCallback<StreamResponse> callback = new FutureCallback<StreamResponse>();
        client.streamRequest(request, callback);
        try {
            final StreamResponse response = callback.get(60, TimeUnit.SECONDS);
            Assert.fail("Should have thrown exception when encoding is not acceptable");
        } catch (ExecutionException e) {
            Throwable t = e.getCause();
            Assert.assertTrue(t instanceof StreamException);
            StreamResponse response = ((StreamException) t).getResponse();
            Assert.assertEquals(response.getStatus(), HttpConstants.NOT_ACCEPTABLE);
        }
    }
}
Also used : StreamResponse(com.linkedin.r2.message.stream.StreamResponse) Client(com.linkedin.r2.transport.common.Client) ExecutionException(java.util.concurrent.ExecutionException) StreamRequestBuilder(com.linkedin.r2.message.stream.StreamRequestBuilder) FutureCallback(com.linkedin.common.callback.FutureCallback) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) StreamException(com.linkedin.r2.message.stream.StreamException)

Example 4 with StreamException

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

the class TestChannelPoolBehavior method testChannelReuse.

@Test
public void testChannelReuse() throws Exception {
    _client2.streamRequest(new StreamRequestBuilder(Bootstrap.createHttpURI(PORT, NOT_FOUND_URI)).build(EntityStreams.newEntityStream(new SlowWriter())), new Callback<StreamResponse>() {

        @Override
        public void onError(Throwable e) {
            if (e instanceof StreamException) {
                StreamException streamException = (StreamException) e;
                streamException.getResponse().getEntityStream().setReader(new CancelingReader());
            }
            throw new RuntimeException(e);
        }

        @Override
        public void onSuccess(StreamResponse result) {
            result.getEntityStream().setReader(new DrainReader());
        }
    });
    Future<RestResponse> responseFuture = _client2.restRequest(new RestRequestBuilder(Bootstrap.createHttpURI(PORT, NORMAL_URI)).build());
    RestResponse response = responseFuture.get(WRITER_DELAY * 1000, TimeUnit.MILLISECONDS);
    Assert.assertEquals(response.getStatus(), RestStatus.OK);
}
Also used : CancelingReader(com.linkedin.r2.message.stream.entitystream.CancelingReader) RestResponse(com.linkedin.r2.message.rest.RestResponse) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) StreamRequestBuilder(com.linkedin.r2.message.stream.StreamRequestBuilder) DrainReader(com.linkedin.r2.message.stream.entitystream.DrainReader) StreamException(com.linkedin.r2.message.stream.StreamException) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) Test(org.testng.annotations.Test)

Example 5 with StreamException

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

the class TestRestLiServer method testCustomizedInternalErrorMessage.

@Test(dataProvider = "restOrStream")
public void testCustomizedInternalErrorMessage(final RestOrStream restOrStream) throws Exception {
    final StatusCollectionResource statusResource = getMockResource(StatusCollectionResource.class);
    EasyMock.expect(statusResource.get(eq(1L))).andThrow(new IllegalArgumentException("oops")).once();
    EasyMock.replay(statusResource);
    Callback<RestResponse> restResponseCallback = new Callback<RestResponse>() {

        @Override
        public void onSuccess(RestResponse restResponse) {
            fail();
        }

        @Override
        public void onError(Throwable e) {
            assertTrue(e instanceof RestException);
            RestException restException = (RestException) e;
            RestResponse restResponse = restException.getResponse();
            try {
                ErrorResponse responseBody = DataMapUtils.read(restResponse.getEntity().asInputStream(), ErrorResponse.class);
                assertEquals(responseBody.getMessage(), "kthxbye.");
                EasyMock.verify(statusResource);
                EasyMock.reset(statusResource);
            } catch (Exception e2) {
                fail(e2.toString());
            }
        }
    };
    if (restOrStream == RestOrStream.REST) {
        RestRequest request = new RestRequestBuilder(new URI("/statuses/1")).setHeader(RestConstants.HEADER_RESTLI_PROTOCOL_VERSION, AllProtocolVersions.BASELINE_PROTOCOL_VERSION.toString()).build();
        _serverWithCustomErrorResponseConfig.handleRequest(request, new RequestContext(), restResponseCallback);
    } else {
        StreamRequest streamRequest = new StreamRequestBuilder(new URI("/statuses/1")).setHeader(RestConstants.HEADER_RESTLI_PROTOCOL_VERSION, AllProtocolVersions.BASELINE_PROTOCOL_VERSION.toString()).build(EntityStreams.emptyStream());
        Callback<StreamResponse> callback = new Callback<StreamResponse>() {

            @Override
            public void onSuccess(StreamResponse streamResponse) {
                fail();
            }

            @Override
            public void onError(Throwable e) {
                Messages.toRestException((StreamException) e, new Callback<RestException>() {

                    @Override
                    public void onError(Throwable e) {
                        Assert.fail();
                    }

                    @Override
                    public void onSuccess(RestException result) {
                        restResponseCallback.onError(result);
                    }
                });
            }
        };
        _serverWithCustomErrorResponseConfig.handleRequest(streamRequest, new RequestContext(), callback);
    }
}
Also used : RestResponse(com.linkedin.r2.message.rest.RestResponse) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) RestException(com.linkedin.r2.message.rest.RestException) URI(java.net.URI) StreamRequestBuilder(com.linkedin.r2.message.stream.StreamRequestBuilder) URISyntaxException(java.net.URISyntaxException) StreamException(com.linkedin.r2.message.stream.StreamException) ParseException(javax.mail.internet.ParseException) RestException(com.linkedin.r2.message.rest.RestException) IOException(java.io.IOException) ErrorResponse(com.linkedin.restli.common.ErrorResponse) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) SinglePartMIMEFullReaderCallback(com.linkedin.multipart.utils.MIMETestUtils.SinglePartMIMEFullReaderCallback) Callback(com.linkedin.common.callback.Callback) MultiPartMIMEFullReaderCallback(com.linkedin.multipart.utils.MIMETestUtils.MultiPartMIMEFullReaderCallback) RestRequest(com.linkedin.r2.message.rest.RestRequest) AsyncStatusCollectionResource(com.linkedin.restli.server.twitter.AsyncStatusCollectionResource) StatusCollectionResource(com.linkedin.restli.server.twitter.StatusCollectionResource) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) FilterRequestContext(com.linkedin.restli.server.filter.FilterRequestContext) RequestContext(com.linkedin.r2.message.RequestContext) Test(org.testng.annotations.Test) AfterTest(org.testng.annotations.AfterTest) BeforeTest(org.testng.annotations.BeforeTest)

Aggregations

StreamException (com.linkedin.r2.message.stream.StreamException)24 StreamResponse (com.linkedin.r2.message.stream.StreamResponse)24 Test (org.testng.annotations.Test)23 Callback (com.linkedin.common.callback.Callback)19 RequestContext (com.linkedin.r2.message.RequestContext)17 RestResponse (com.linkedin.r2.message.rest.RestResponse)17 RestRequest (com.linkedin.r2.message.rest.RestRequest)15 StreamRequestBuilder (com.linkedin.r2.message.stream.StreamRequestBuilder)15 RestException (com.linkedin.r2.message.rest.RestException)14 StreamRequest (com.linkedin.r2.message.stream.StreamRequest)14 RestRequestBuilder (com.linkedin.r2.message.rest.RestRequestBuilder)13 ByteString (com.linkedin.data.ByteString)12 URI (java.net.URI)12 MultiPartMIMEFullReaderCallback (com.linkedin.multipart.utils.MIMETestUtils.MultiPartMIMEFullReaderCallback)11 SinglePartMIMEFullReaderCallback (com.linkedin.multipart.utils.MIMETestUtils.SinglePartMIMEFullReaderCallback)11 FilterRequestContext (com.linkedin.restli.server.filter.FilterRequestContext)11 AfterTest (org.testng.annotations.AfterTest)10 BeforeTest (org.testng.annotations.BeforeTest)10 FullEntityReader (com.linkedin.r2.message.stream.entitystream.FullEntityReader)9 AsyncStatusCollectionResource (com.linkedin.restli.server.twitter.AsyncStatusCollectionResource)8