use of com.linkedin.data.ByteString in project rest.li by linkedin.
the class TestServerTimeout method testServerTimeout.
@Test
public void testServerTimeout() throws Exception {
final StreamRequest request = new StreamRequestBuilder(getHttpUri(BUGGY_SERVER_URI)).build(EntityStreams.emptyStream());
final CountDownLatch latch = new CountDownLatch(1);
final AtomicInteger status = new AtomicInteger(-1);
_client.streamRequest(request, new Callback<StreamResponse>() {
@Override
public void onError(Throwable e) {
latch.countDown();
}
@Override
public void onSuccess(StreamResponse result) {
status.set(result.getStatus());
result.getEntityStream().setReader(new Reader() {
private ReadHandle _rh;
@Override
public void onInit(ReadHandle rh) {
_rh = rh;
_rh.request(Integer.MAX_VALUE);
}
@Override
public void onDataAvailable(ByteString data) {
// do nothing
}
@Override
public void onDone() {
// server would close the connection if TimeoutException, and netty would end the chunked transferring
// with an empty chunk
latch.countDown();
}
@Override
public void onError(Throwable e) {
latch.countDown();
}
});
}
});
// server should timeout so await should return true
Assert.assertTrue(latch.await(SERVER_IOHANDLER_TIMEOUT * 2, TimeUnit.MILLISECONDS));
Assert.assertEquals(status.get(), RestStatus.OK);
}
use of com.linkedin.data.ByteString in project rest.li by linkedin.
the class TestHttpNettyStreamClient method testSlowReaderTimeout.
/**
* Tests slow EntityStream {@link Reader} implementation should be subject to streaming timeout even
* if the entire response entity can be buffered in memory.
*
* @throws Exception
*/
@Test(dataProvider = "slowReaderTimeoutClientProvider")
public void testSlowReaderTimeout(AbstractNettyStreamClient client) throws Exception {
// Sets the response size to be greater than zero but smaller than the in-memory buffer for HTTP/1.1
// and smaller than the receiving window size for HTTP/2 so the receiver will not block sender
Server server = new HttpServerBuilder().responseSize(R2Constants.DEFAULT_DATA_CHUNK_SIZE).build();
StreamRequest request = new StreamRequestBuilder(new URI(URL)).setHeader(HttpHeaderNames.HOST.toString(), HOST_NAME.toString()).build(EntityStreams.emptyStream());
final CountDownLatch responseLatch = new CountDownLatch(1);
final CountDownLatch streamLatch = new CountDownLatch(1);
final AtomicReference<TransportResponse<StreamResponse>> atomicTransportResponse = new AtomicReference<>();
final AtomicReference<Throwable> atomicThrowable = new AtomicReference<>();
try {
server.start();
client.streamRequest(request, new RequestContext(), new HashMap<>(), response -> {
atomicTransportResponse.set(response);
responseLatch.countDown();
// Sets a reader that does not consume any byte
response.getResponse().getEntityStream().setReader(new Reader() {
@Override
public void onInit(ReadHandle rh) {
}
@Override
public void onDataAvailable(ByteString data) {
}
@Override
public void onDone() {
}
@Override
public void onError(Throwable e) {
atomicThrowable.set(e);
streamLatch.countDown();
}
});
});
} finally {
responseLatch.await(5, TimeUnit.SECONDS);
streamLatch.await(5, TimeUnit.SECONDS);
server.stop();
}
TransportResponse<StreamResponse> transportResponse = atomicTransportResponse.get();
Assert.assertNotNull(transportResponse, "Expected to receive a response");
Assert.assertFalse(transportResponse.hasError(), "Expected to receive a response without error");
Assert.assertNotNull(transportResponse.getResponse());
Assert.assertNotNull(transportResponse.getResponse().getEntityStream());
Throwable throwable = atomicThrowable.get();
Assert.assertNotNull(throwable, "Expected onError invoked with TimeoutException");
Assert.assertTrue(throwable instanceof RemoteInvocationException);
Assert.assertNotNull(throwable.getCause());
Assert.assertTrue(throwable.getCause() instanceof TimeoutException);
}
use of com.linkedin.data.ByteString in project rest.li by linkedin.
the class LoggingFilter method onStreamResponse.
@Override
public void onStreamResponse(StreamResponse res, RequestContext requestContext, Map<String, String> wireAttrs, NextFilter<StreamRequest, StreamResponse> nextFilter) {
EntityStream entityStream = res.getEntityStream();
entityStream.addObserver(new Observer() {
private long startTime;
private long bytesNum = 0;
@Override
public void onDataAvailable(ByteString data) {
if (bytesNum == 0) {
startTime = System.nanoTime();
}
bytesNum += data.length();
}
@Override
public void onDone() {
long stopTime = System.nanoTime();
_log.info("Status: success. Total bytes streamed: " + bytesNum + ". Total stream time: " + (stopTime - startTime) + " nano seconds.");
}
@Override
public void onError(Throwable e) {
long stopTime = System.nanoTime();
_log.error("Status: failed. Total bytes streamed: " + bytesNum + ". Total stream time before failure: " + (stopTime - startTime) + " nano seconds.");
}
});
}
use of com.linkedin.data.ByteString in project rest.li by linkedin.
the class MultiplexedCallback method buildIndividualRestResponse.
private static RestResponse buildIndividualRestResponse(Response<?> envelopeResponse, IndividualResponse individualResponse) throws IOException, MimeTypeParseException {
IndividualBody body = individualResponse.getBody(GetMode.NULL);
ByteString entity = (body != null) ? DataMapConverter.dataMapToByteString(individualResponse.getHeaders(), body.data()) : ByteString.empty();
return new RestResponseBuilder().setStatus(individualResponse.getStatus()).setHeaders(inheritHeaders(individualResponse, envelopeResponse)).setCookies(CookieUtil.encodeSetCookies(envelopeResponse.getCookies())).setEntity(entity).build();
}
use of com.linkedin.data.ByteString in project rest.li by linkedin.
the class MultiplexerTestBase method assertRestResponseEquals.
protected static void assertRestResponseEquals(RestResponse actual, RestResponse expected) throws MimeTypeParseException, IOException {
// validate headers & cookies
Assert.assertEquals(normalizeHeaderName(actual.getHeaders()), normalizeHeaderName(expected.getHeaders()));
Assert.assertEquals(normalizeSetCookies(actual.getCookies()), normalizeSetCookies(expected.getCookies()));
// After the IndividualBody is serialized into an entity byte array, it can no longer guarantee the order of its fields.
// So, to compare entity, we should de-serialize the entity back to a DataMap in order to perform the equal assertion.
ByteString actualEntity = actual.getEntity();
ByteString expectedEntity = expected.getEntity();
if (actualEntity.isEmpty() || expectedEntity.isEmpty()) {
Assert.assertEquals(actual, expected);
} else {
DataMap actualDataMap = DataMapConverter.bytesToDataMap(actual.getHeaders(), actualEntity);
DataMap expectedDataMap = DataMapConverter.bytesToDataMap(expected.getHeaders(), expectedEntity);
Assert.assertEquals(actualDataMap, expectedDataMap);
// Compare the rest of RestResponse (excluding the entity)
RestResponse actualRestResponseWithoutEntity = actual.builder().setEntity(ByteString.empty()).build();
RestResponse expectedRestResponseWithoutEntity = expected.builder().setEntity(ByteString.empty()).build();
Assert.assertEquals(actualRestResponseWithoutEntity, expectedRestResponseWithoutEntity);
}
}
Aggregations