Search in sources :

Example 16 with FullEntityReader

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);
    }
}
Also used : MimeTypeParseException(javax.activation.MimeTypeParseException) ContentType(javax.mail.internet.ContentType) ContentType.getContentType(com.linkedin.restli.common.ContentType.getContentType) ByteString(com.linkedin.data.ByteString) MultiPartMIMEReader(com.linkedin.multipart.MultiPartMIMEReader) ByteString(com.linkedin.data.ByteString) ParseException(javax.mail.internet.ParseException) RestLiDecodingException(com.linkedin.restli.client.RestLiDecodingException) RemoteInvocationException(com.linkedin.r2.RemoteInvocationException) IOException(java.io.IOException) InvocationTargetException(java.lang.reflect.InvocationTargetException) MimeTypeParseException(javax.activation.MimeTypeParseException) DataMap(com.linkedin.data.DataMap) FullEntityReader(com.linkedin.r2.message.stream.entitystream.FullEntityReader) StreamDataCodec(com.linkedin.data.codec.entitystream.StreamDataCodec) RestLiDecodingException(com.linkedin.restli.client.RestLiDecodingException) ParseException(javax.mail.internet.ParseException) MimeTypeParseException(javax.activation.MimeTypeParseException)

Example 17 with 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");
}
Also used : ByteString(com.linkedin.data.ByteString) ArrayList(java.util.ArrayList) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) FullEntityReader(com.linkedin.r2.message.stream.entitystream.FullEntityReader) ByteArrayInputStream(java.io.ByteArrayInputStream) MIMEDataPart(com.linkedin.multipart.utils.MIMEDataPart) FutureCallback(com.linkedin.common.callback.FutureCallback) Test(org.testng.annotations.Test) BeforeTest(org.testng.annotations.BeforeTest)

Example 18 with FullEntityReader

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!");
}
Also used : ByteString(com.linkedin.data.ByteString) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) CountDownLatch(java.util.concurrent.CountDownLatch) URI(java.net.URI) StreamRequestBuilder(com.linkedin.r2.message.stream.StreamRequestBuilder) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) EntityStream(com.linkedin.r2.message.stream.entitystream.EntityStream) FullEntityReader(com.linkedin.r2.message.stream.entitystream.FullEntityReader) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) FutureCallback(com.linkedin.common.callback.FutureCallback) Callback(com.linkedin.common.callback.Callback) RestLiIntegrationTest(com.linkedin.restli.examples.RestLiIntegrationTest) Test(org.testng.annotations.Test)

Example 19 with FullEntityReader

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);
}
Also used : ByteString(com.linkedin.data.ByteString) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) StreamRequestBuilder(com.linkedin.r2.message.stream.StreamRequestBuilder) URI(java.net.URI) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) StreamException(com.linkedin.r2.message.stream.StreamException) FullEntityReader(com.linkedin.r2.message.stream.entitystream.FullEntityReader) SinglePartMIMEFullReaderCallback(com.linkedin.multipart.utils.MIMETestUtils.SinglePartMIMEFullReaderCallback) Callback(com.linkedin.common.callback.Callback) MultiPartMIMEFullReaderCallback(com.linkedin.multipart.utils.MIMETestUtils.MultiPartMIMEFullReaderCallback) 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)

Example 20 with FullEntityReader

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);
}
Also used : ByteString(com.linkedin.data.ByteString) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) StreamRequestBuilder(com.linkedin.r2.message.stream.StreamRequestBuilder) URI(java.net.URI) FeedDownloadResource(com.linkedin.restli.server.twitter.FeedDownloadResource) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) FullEntityReader(com.linkedin.r2.message.stream.entitystream.FullEntityReader) 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

ByteString (com.linkedin.data.ByteString)22 FullEntityReader (com.linkedin.r2.message.stream.entitystream.FullEntityReader)22 Test (org.testng.annotations.Test)18 Callback (com.linkedin.common.callback.Callback)15 RequestContext (com.linkedin.r2.message.RequestContext)14 StreamRequest (com.linkedin.r2.message.stream.StreamRequest)12 RestRequest (com.linkedin.r2.message.rest.RestRequest)10 StreamResponse (com.linkedin.r2.message.stream.StreamResponse)10 RestResponse (com.linkedin.r2.message.rest.RestResponse)9 FilterChain (com.linkedin.r2.filter.FilterChain)8 RestFilter (com.linkedin.r2.filter.message.rest.RestFilter)8 BeforeTest (org.testng.annotations.BeforeTest)8 StreamException (com.linkedin.r2.message.stream.StreamException)7 StreamRequestBuilder (com.linkedin.r2.message.stream.StreamRequestBuilder)7 URI (java.net.URI)7 FutureCallback (com.linkedin.common.callback.FutureCallback)5 FilterRequestContext (com.linkedin.restli.server.filter.FilterRequestContext)5 AfterTest (org.testng.annotations.AfterTest)5 RestRequestBuilder (com.linkedin.r2.message.rest.RestRequestBuilder)4 MIMEDataPart (com.linkedin.multipart.utils.MIMEDataPart)3