use of com.linkedin.r2.message.stream.entitystream.FullEntityReader in project rest.li by linkedin.
the class RestResponseDecoder method decodeResponse.
public void decodeResponse(final StreamResponse streamResponse, final Callback<Response<T>> responseCallback) throws RestLiDecodingException {
// Determine content type and take appropriate action.
// If 'multipart/related', then use MultiPartMIMEReader to read first part (which can be json or pson).
final String contentTypeString = streamResponse.getHeader(RestConstants.HEADER_CONTENT_TYPE);
if (contentTypeString != null) {
ContentType contentType = null;
try {
contentType = new ContentType(contentTypeString);
} catch (ParseException parseException) {
responseCallback.onError(new RestLiDecodingException("Could not decode Content-Type header in response", parseException));
return;
}
if (contentType.getBaseType().equalsIgnoreCase(RestConstants.HEADER_VALUE_MULTIPART_RELATED)) {
final MultiPartMIMEReader multiPartMIMEReader = MultiPartMIMEReader.createAndAcquireStream(streamResponse);
final TopLevelReaderCallback topLevelReaderCallback = new TopLevelReaderCallback(responseCallback, streamResponse, multiPartMIMEReader);
multiPartMIMEReader.registerReaderCallback(topLevelReaderCallback);
return;
}
}
// Otherwise if the whole body is json/pson then read everything in.
StreamDataCodec streamDataCodec = null;
try {
streamDataCodec = getContentType(streamResponse.getHeaders().get(RestConstants.HEADER_CONTENT_TYPE)).orElse(JSON).getStreamCodec();
} catch (MimeTypeParseException e) {
responseCallback.onError(e);
return;
}
if (streamDataCodec != null) {
CompletionStage<DataMap> dataMapCompletionStage = streamDataCodec.decodeMap(EntityStreamAdapters.toGenericEntityStream(streamResponse.getEntityStream()));
dataMapCompletionStage.handle((dataMap, e) -> {
if (e != null) {
responseCallback.onError(new RestLiDecodingException("Could not decode REST response", e));
return null;
}
try {
responseCallback.onSuccess(createResponse(streamResponse.getHeaders(), streamResponse.getStatus(), dataMap, streamResponse.getCookies()));
} catch (Throwable throwable) {
responseCallback.onError(throwable);
}
// handle function requires a return statement although there is no more completion stage.
return null;
});
} else {
final FullEntityReader fullEntityReader = new FullEntityReader(new Callback<ByteString>() {
@Override
public void onError(Throwable e) {
responseCallback.onError(e);
}
@Override
public void onSuccess(ByteString result) {
try {
responseCallback.onSuccess(createResponse(streamResponse.getHeaders(), streamResponse.getStatus(), result, streamResponse.getCookies()));
} catch (Exception exception) {
onError(exception);
}
}
});
streamResponse.getEntityStream().setReader(fullEntityReader);
}
}
use of com.linkedin.r2.message.stream.entitystream.FullEntityReader in project rest.li by linkedin.
the class TestMIMEWriter method testMultipleDataSources.
@Test
public void testMultipleDataSources() throws Exception {
final List<MIMEDataPart> expectedParts = new ArrayList<>();
expectedParts.add(_normalBody);
expectedParts.add(_normalBody);
expectedParts.add(_headerLessBody);
expectedParts.add(_normalBody);
expectedParts.add(_bodyLessBody);
expectedParts.add(_purelyEmptyBody);
expectedParts.add(_purelyEmptyBody);
expectedParts.add(_headerLessBody);
expectedParts.add(_headerLessBody);
expectedParts.add(_headerLessBody);
expectedParts.add(_normalBody);
expectedParts.add(_bodyLessBody);
final List<MultiPartMIMEDataSourceWriter> inputStreamDataSources = new ArrayList<>();
inputStreamDataSources.add(new MultiPartMIMEInputStream.Builder(new ByteArrayInputStream(_normalBodyData), _scheduledExecutorService, _normalBodyHeaders).build());
inputStreamDataSources.add(new MultiPartMIMEInputStream.Builder(new ByteArrayInputStream(_normalBodyData), _scheduledExecutorService, _normalBodyHeaders).build());
inputStreamDataSources.add(new MultiPartMIMEInputStream.Builder(new ByteArrayInputStream(_headerLessBodyData), _scheduledExecutorService, Collections.<String, String>emptyMap()).build());
inputStreamDataSources.add(new MultiPartMIMEInputStream.Builder(new ByteArrayInputStream(_normalBodyData), _scheduledExecutorService, _normalBodyHeaders).build());
inputStreamDataSources.add(new MultiPartMIMEInputStream.Builder(new ByteArrayInputStream(new byte[0]), _scheduledExecutorService, _bodyLessHeaders).build());
inputStreamDataSources.add(new MultiPartMIMEInputStream.Builder(new ByteArrayInputStream(new byte[0]), _scheduledExecutorService, Collections.<String, String>emptyMap()).build());
inputStreamDataSources.add(new MultiPartMIMEInputStream.Builder(new ByteArrayInputStream(new byte[0]), _scheduledExecutorService, Collections.<String, String>emptyMap()).build());
inputStreamDataSources.add(new MultiPartMIMEInputStream.Builder(new ByteArrayInputStream(_headerLessBodyData), _scheduledExecutorService, Collections.<String, String>emptyMap()).build());
inputStreamDataSources.add(new MultiPartMIMEInputStream.Builder(new ByteArrayInputStream(_headerLessBodyData), _scheduledExecutorService, Collections.<String, String>emptyMap()).build());
inputStreamDataSources.add(new MultiPartMIMEInputStream.Builder(new ByteArrayInputStream(_headerLessBodyData), _scheduledExecutorService, Collections.<String, String>emptyMap()).build());
inputStreamDataSources.add(new MultiPartMIMEInputStream.Builder(new ByteArrayInputStream(_normalBodyData), _scheduledExecutorService, _normalBodyHeaders).build());
inputStreamDataSources.add(new MultiPartMIMEInputStream.Builder(new ByteArrayInputStream(new byte[0]), _scheduledExecutorService, _bodyLessHeaders).build());
final MultiPartMIMEWriter.Builder multiPartMIMEWriterBuilder = new MultiPartMIMEWriter.Builder("preamble", "epilogue").appendDataSources(inputStreamDataSources);
Assert.assertEquals(multiPartMIMEWriterBuilder.getCurrentSize(), inputStreamDataSources.size());
final MultiPartMIMEWriter multiPartMIMEWriter = multiPartMIMEWriterBuilder.build();
final FutureCallback<ByteString> futureCallback = new FutureCallback<>();
final FullEntityReader fullEntityReader = new FullEntityReader(futureCallback);
multiPartMIMEWriter.getEntityStream().setReader(fullEntityReader);
futureCallback.get(_testTimeout, TimeUnit.MILLISECONDS);
final StreamRequest multiPartMIMEStreamRequest = MultiPartMIMEStreamRequestFactory.generateMultiPartMIMEStreamRequest(URI.create("localhost"), "mixed", multiPartMIMEWriter, Collections.<String, String>emptyMap());
JavaxMailMultiPartMIMEReader javaxMailMultiPartMIMEReader = new JavaxMailMultiPartMIMEReader(multiPartMIMEStreamRequest.getHeader(MultiPartMIMEUtils.CONTENT_TYPE_HEADER), futureCallback.get());
javaxMailMultiPartMIMEReader.parseRequestIntoParts();
List<MIMEDataPart> dataSourceList = javaxMailMultiPartMIMEReader._dataSourceList;
Assert.assertEquals(dataSourceList.size(), 12);
for (int i = 0; i < dataSourceList.size(); i++) {
Assert.assertEquals(dataSourceList.get(i), expectedParts.get(i));
}
// Javax mail incorrectly adds the CRLF for the first boundary to the end of the preamble, so we trim
Assert.assertEquals(javaxMailMultiPartMIMEReader._preamble.trim(), "preamble");
}
use of com.linkedin.r2.message.stream.entitystream.FullEntityReader in project rest.li by linkedin.
the class TestUnstructuredDataClient method testClientWithStreamResponse.
@Test(dataProvider = "goodURLs")
public void testClientWithStreamResponse(String resourceURL) throws Throwable {
ByteString expectedContent = ByteString.copy(GreetingUnstructuredDataUtils.UNSTRUCTURED_DATA_BYTES);
URI testURI = URI.create(RestLiIntegrationTest.URI_PREFIX + resourceURL);
EntityStream emptyStream = EntityStreams.emptyStream();
StreamRequest streamRequest = new StreamRequestBuilder(testURI).build(emptyStream);
final CountDownLatch latch = new CountDownLatch(1);
final AtomicBoolean success = new AtomicBoolean();
_client.streamRequest(streamRequest, new Callback<StreamResponse>() {
@Override
public void onError(Throwable e) {
fail("failed to get response", e);
}
@Override
public void onSuccess(StreamResponse result) {
assertEquals(result.getHeader(RestConstants.HEADER_CONTENT_TYPE), GreetingUnstructuredDataUtils.MIME_TYPE);
FullEntityReader fullEntityReader = new FullEntityReader(new Callback<ByteString>() {
@Override
public void onError(Throwable e) {
success.set(false);
latch.countDown();
}
@Override
public void onSuccess(ByteString result) {
// Won't fail the test, only use to print out error
assertEquals(result, expectedContent);
// Will fail the test if content is not identical
success.set(result.equals(expectedContent));
latch.countDown();
}
});
result.getEntityStream().setReader(fullEntityReader);
}
});
latch.await(10, TimeUnit.SECONDS);
if (!success.get())
fail("Failed to read response data from stream!");
}
use of com.linkedin.r2.message.stream.entitystream.FullEntityReader in project rest.li by linkedin.
the class TestRestLiServer method testStreamRequestMultiplexedRequestMultiPartAcceptType.
@Test
public void testStreamRequestMultiplexedRequestMultiPartAcceptType() throws Exception {
// This test verifies that a StreamRequest sent to the RestLiServer throws an exception if the accept type contains
// multipart/related.
StreamRequest streamRequestMux = new StreamRequestBuilder(new URI("/mux")).setHeader(RestConstants.HEADER_ACCEPT, RestConstants.HEADER_VALUE_MULTIPART_RELATED).build(EntityStreams.emptyStream());
Callback<StreamResponse> callback = new Callback<StreamResponse>() {
@Override
public void onSuccess(StreamResponse restResponse) {
fail();
}
@Override
public void onError(Throwable e) {
assertTrue(e instanceof StreamException);
StreamException streamException = (StreamException) e;
StreamResponse streamResponse = streamException.getResponse();
assertEquals(streamResponse.getStatus(), 406);
final FullEntityReader fullEntityReader = new FullEntityReader(new Callback<ByteString>() {
@Override
public void onError(Throwable e) {
Assert.fail();
}
@Override
public void onSuccess(ByteString result) {
// We have the body so assert
assertTrue(result.length() > 0);
assertEquals(result.asString(Charset.defaultCharset()), "This server cannot handle multiplexed requests that have an accept type of multipart/related");
}
});
streamResponse.getEntityStream().setReader(fullEntityReader);
}
};
_server.handleRequest(streamRequestMux, new RequestContext(), callback);
}
use of com.linkedin.r2.message.stream.entitystream.FullEntityReader in project rest.li by linkedin.
the class TestRestLiServer method testValidUnstructuredDataRequest.
@Test(dataProvider = "validClientProtocolVersionDataStreamOnly")
public void testValidUnstructuredDataRequest(RestLiServer server, ProtocolVersion clientProtocolVersion, String headerConstant) throws URISyntaxException, IOException {
StreamRequest streamRequest = new StreamRequestBuilder(new URI("/feedDownloads/1")).setHeader(headerConstant, clientProtocolVersion.toString()).build(EntityStreams.emptyStream());
final FeedDownloadResource resource = getMockResource(FeedDownloadResource.class);
resource.get(eq(1L), anyObject(UnstructuredDataWriter.class));
EasyMock.expectLastCall().andDelegateTo(new FeedDownloadResource()).once();
replay(resource);
@SuppressWarnings("unchecked") Callback<StreamResponse> r2Callback = createMock(Callback.class);
final Capture<StreamResponse> streamResponse = EasyMock.newCapture();
r2Callback.onSuccess(capture(streamResponse));
expectLastCall().once();
replay(r2Callback);
RequestContext requestContext = new RequestContext();
server.handleRequest(streamRequest, requestContext, r2Callback);
verify(resource);
verify(r2Callback);
assertNotNull(streamResponse);
assertEquals(streamResponse.getValue().getHeader(RestConstants.HEADER_CONTENT_TYPE), FeedDownloadResource.CONTENT_TYPE);
FullEntityReader fullEntityReader = new FullEntityReader(new Callback<ByteString>() {
@Override
public void onError(Throwable e) {
fail("Error inside callback!! Failed to read response data from stream!", e);
}
@Override
public void onSuccess(ByteString result) {
assertEquals(result.copyBytes(), FeedDownloadResource.CONTENT);
}
});
streamResponse.getValue().getEntityStream().setReader(fullEntityReader);
}
Aggregations