use of com.linkedin.r2.message.stream.StreamRequest in project rest.li by linkedin.
the class TestHttp2NettyStreamClient method testChannelReusedAfterStreamingTimeout.
/**
* When a request fails due to {@link TimeoutException}, connection should not be destroyed.
* @throws Exception
*/
@Test(timeOut = TEST_TIMEOUT, retryAnalyzer = SingleRetry.class)
public void testChannelReusedAfterStreamingTimeout() throws Exception {
final HttpServerBuilder.HttpServerStatsProvider statsProvider = new HttpServerBuilder.HttpServerStatsProvider();
final HttpServerBuilder serverBuilder = new HttpServerBuilder();
final Server server = serverBuilder.serverStatsProvider(statsProvider).stopTimeout(0).build();
final HttpClientBuilder clientBuilder = new HttpClientBuilder(_eventLoop, _scheduler);
final Http2NettyStreamClient client = clientBuilder.setRequestTimeout(1000).buildHttp2StreamClient();
final TransportResponse<StreamResponse> response1;
final TransportResponse<StreamResponse> response2;
try {
server.start();
final StreamRequestBuilder builder1 = new StreamRequestBuilder(new URI(URL));
final StreamRequest request1 = builder1.setMethod(METHOD).setHeader(HttpHeaderNames.HOST.toString(), HOST_NAME.toString()).build(EntityStreams.newEntityStream(new ByteStringWriter(ByteString.copy(new byte[REQUEST_SIZE]))));
final FutureTransportCallback<StreamResponse> callback1 = new FutureTransportCallback<>();
client.streamRequest(request1, new RequestContext(), new HashMap<>(), callback1);
response1 = callback1.get();
Assert.assertNotNull(response1);
Assert.assertFalse(response1.hasError());
response1.getResponse().getEntityStream().setReader(new TimeoutReader());
final StreamRequestBuilder builder2 = new StreamRequestBuilder(new URI(URL));
final StreamRequest request2 = builder2.setMethod(METHOD).setHeader(HttpHeaderNames.HOST.toString(), HOST_NAME.toString()).build(EntityStreams.newEntityStream(new ByteStringWriter(ByteString.copy(new byte[REQUEST_SIZE]))));
final FutureTransportCallback<StreamResponse> callback2 = new FutureTransportCallback<>();
client.streamRequest(request2, new RequestContext(), new HashMap<>(), callback2);
response2 = callback2.get();
} finally {
server.stop();
}
// The 2nd request should succeed
Assert.assertNotNull(response2);
Assert.assertFalse(response2.hasError());
response2.getResponse().getEntityStream().setReader(new DrainReader());
// The server should have seen 3 requests but establishes only 1 connection with the client
Assert.assertEquals(statsProvider.requestCount(), 3);
Assert.assertEquals(statsProvider.clientConnections().size(), 1);
}
use of com.linkedin.r2.message.stream.StreamRequest in project rest.li by linkedin.
the class TestHttp2NettyStreamClient method testMaxConcurrentStreamExhaustion.
/**
* When the maximum number of concurrent streams is exhausted, the client is expected to throw
* an {@link StreamException} immediately.
*/
@Test(timeOut = TEST_TIMEOUT)
public void testMaxConcurrentStreamExhaustion() throws Exception {
final HttpServerBuilder serverBuilder = new HttpServerBuilder();
final Server server = serverBuilder.maxConcurrentStreams(0).build();
final HttpClientBuilder clientBuilder = new HttpClientBuilder(_eventLoop, _scheduler);
final Http2NettyStreamClient client = clientBuilder.buildHttp2StreamClient();
final FutureTransportCallback<StreamResponse> callback = new FutureTransportCallback<>();
final TransportResponse<StreamResponse> response;
try {
server.start();
// Sends the stream request
final StreamRequestBuilder builder = new StreamRequestBuilder(new URI(URL));
final StreamRequest request = builder.setMethod(METHOD).setHeader(HttpHeaderNames.HOST.toString(), HOST_NAME.toString()).build(EntityStreams.newEntityStream(new ByteStringWriter(ByteString.copy(new byte[REQUEST_SIZE]))));
client.streamRequest(request, new RequestContext(), new HashMap<>(), callback);
response = callback.get();
} finally {
server.stop();
}
Assert.assertNotNull(response);
Assert.assertTrue(response.hasError());
Assert.assertNotNull(response.getError());
ExceptionTestUtil.verifyCauseChain(response.getError(), Http2Exception.StreamException.class);
}
use of com.linkedin.r2.message.stream.StreamRequest in project rest.li by linkedin.
the class TestHttp2NettyStreamClient method testChannelReusedAfterRequestTimeout.
/**
* When a request fails due to {@link TimeoutException}, connection should not be destroyed.
* @throws Exception
*/
@Test(timeOut = TEST_TIMEOUT)
public void testChannelReusedAfterRequestTimeout() throws Exception {
final HttpServerBuilder.HttpServerStatsProvider statsProvider = new HttpServerBuilder.HttpServerStatsProvider();
final HttpServerBuilder serverBuilder = new HttpServerBuilder();
final Server server = serverBuilder.serverStatsProvider(statsProvider).stopTimeout(0).build();
final HttpClientBuilder clientBuilder = new HttpClientBuilder(_eventLoop, _scheduler);
final Http2NettyStreamClient client = clientBuilder.setRequestTimeout(1000).buildHttp2StreamClient();
final TransportResponse<StreamResponse> response1;
final TransportResponse<StreamResponse> response2;
try {
server.start();
final StreamRequestBuilder builder1 = new StreamRequestBuilder(new URI(URL));
final StreamRequest request1 = builder1.setMethod(METHOD).setHeader(HttpHeaderNames.HOST.toString(), HOST_NAME.toString()).build(EntityStreams.newEntityStream(new TimeoutWriter()));
final FutureTransportCallback<StreamResponse> callback1 = new FutureTransportCallback<>();
client.streamRequest(request1, new RequestContext(), new HashMap<>(), callback1);
response1 = callback1.get();
final StreamRequestBuilder builder2 = new StreamRequestBuilder(new URI(URL));
final StreamRequest request2 = builder2.setMethod(METHOD).setHeader(HttpHeaderNames.HOST.toString(), HOST_NAME.toString()).build(EntityStreams.newEntityStream(new ByteStringWriter(ByteString.copy(new byte[REQUEST_SIZE]))));
final FutureTransportCallback<StreamResponse> callback2 = new FutureTransportCallback<>();
client.streamRequest(request2, new RequestContext(), new HashMap<>(), callback2);
response2 = callback2.get();
} finally {
server.stop();
}
// The 1st request should be failed with timeout
Assert.assertNotNull(response1);
Assert.assertTrue(response1.hasError());
Assert.assertNotNull(response1.getError());
ExceptionTestUtil.verifyCauseChain(response1.getError(), TimeoutException.class);
// The 2nd request should succeed
Assert.assertNotNull(response2);
Assert.assertFalse(response2.hasError());
response2.getResponse().getEntityStream().setReader(new DrainReader());
// The server should have seen 2 requests but establishes only 1 connection with the client
Assert.assertEquals(statsProvider.requestCount(), 3);
Assert.assertEquals(statsProvider.clientConnections().size(), 1);
}
use of com.linkedin.r2.message.stream.StreamRequest in project rest.li by linkedin.
the class TestAttachmentUtils method testMultipleAttachments.
@Test
public void testMultipleAttachments() {
final MultiPartMIMEWriter.Builder builder = new MultiPartMIMEWriter.Builder();
final List<RestLiTestAttachmentDataSource> testAttachmentDataSources = generateTestDataSources();
final RestLiTestAttachmentDataSourceIterator dataSourceIterator = new RestLiTestAttachmentDataSourceIterator(testAttachmentDataSources, new IllegalArgumentException());
// Let each data source know its parent, so that when the data source is done, it can notify it's parent to call onNewDataSourceWriter()
for (final RestLiTestAttachmentDataSource dataSource : testAttachmentDataSources) {
dataSource.setParentDataSourceIterator(dataSourceIterator);
}
AttachmentUtils.appendMultipleAttachmentsToBuilder(builder, dataSourceIterator);
final StreamRequest streamRequest = MultiPartMIMEStreamRequestFactory.generateMultiPartMIMEStreamRequest(URI.create("foo"), "related", builder.build());
final MultiPartMIMEReader streamRequestReader = MultiPartMIMEReader.createAndAcquireStream(streamRequest);
final CountDownLatch streamRequestReaderLatch = new CountDownLatch(1);
final MIMETestUtils.MultiPartMIMEFullReaderCallback streamRequestReaderCallback = new MIMETestUtils.MultiPartMIMEFullReaderCallback(streamRequestReaderLatch);
streamRequestReader.registerReaderCallback(streamRequestReaderCallback);
try {
streamRequestReaderLatch.await(3000, TimeUnit.MILLISECONDS);
} catch (InterruptedException interruptedException) {
Assert.fail();
}
verifyAttachments(streamRequestReaderCallback.getSinglePartMIMEReaderCallbacks(), testAttachmentDataSources);
}
use of com.linkedin.r2.message.stream.StreamRequest in project rest.li by linkedin.
the class AttachmentHandlingRestLiServer method handleRequestAttachments.
/**
* Handles multipart/related request as Rest.li payload with attachments.
*
* @return Whether or not the request is a multipart/related Rest.li request with attachments.
*/
private boolean handleRequestAttachments(StreamRequest request, RequestContext requestContext, Callback<StreamResponse> callback) {
// At this point we need to check the content-type to understand how we should handle the request.
String header = request.getHeader(RestConstants.HEADER_CONTENT_TYPE);
if (header != null) {
ContentType contentType;
try {
contentType = new ContentType(header);
} catch (ParseException e) {
callback.onError(Messages.toStreamException(RestException.forError(400, "Unable to parse Content-Type: " + header)));
return true;
}
if (contentType.getBaseType().equalsIgnoreCase(RestConstants.HEADER_VALUE_MULTIPART_RELATED)) {
// We need to reconstruct a RestRequest that has the first part of the multipart/related payload as the
// traditional rest.li payload of a RestRequest.
final MultiPartMIMEReader multiPartMIMEReader = MultiPartMIMEReader.createAndAcquireStream(request);
RoutingResult routingResult;
try {
routingResult = getRoutingResult(request, requestContext);
} catch (Exception e) {
callback.onError(buildPreRoutingStreamException(e, request));
return true;
}
final TopLevelReaderCallback firstPartReader = new TopLevelReaderCallback(routingResult, callback, multiPartMIMEReader, request);
multiPartMIMEReader.registerReaderCallback(firstPartReader);
return true;
}
}
return false;
}
Aggregations