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);
}
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."));
}
}
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);
}
}
}
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);
}
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);
}
}
Aggregations