Search in sources :

Example 21 with FullEntityReader

use of com.linkedin.r2.message.stream.entitystream.FullEntityReader in project rest.li by linkedin.

the class TestRestLiServer method testRequestAttachmentsResponseAttachmentsException.

@Test
public void testRequestAttachmentsResponseAttachmentsException() throws Exception {
    // This test verifies the server's behavior in the face of an exception. In this case the resource method
    // threw an exception AFTER setting response attachments. Additionally the resource method failed to absorb any
    // incoming request attachments. We verify in this test that StreamResponseCallbackAdaptor in RestLiServer
    // drains and absorbs all bytes from the incoming request and that the response attachments set by the resource method
    // are told to abort.
    // Define the server side resource attachments to be sent back.
    final RestLiResponseAttachments.Builder responseAttachmentsBuilder = new RestLiResponseAttachments.Builder();
    final RestLiTestAttachmentDataSource toBeAbortedDataSource = RestLiTestAttachmentDataSource.createWithRandomPayload("1");
    responseAttachmentsBuilder.appendSingleAttachment(toBeAbortedDataSource);
    Capture<ResourceContext> resourceContextCapture = EasyMock.newCapture();
    final AsyncStatusCollectionResource statusResource = getMockResource(AsyncStatusCollectionResource.class, capture(resourceContextCapture));
    statusResource.streamingAction(EasyMock.<String>anyObject(), EasyMock.<RestLiAttachmentReader>anyObject(), EasyMock.<Callback<Long>>anyObject());
    EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {

        @Override
        public Object answer() throws Throwable {
            // Verify there are still attachments to be read.
            final RestLiAttachmentReader attachmentReader = (RestLiAttachmentReader) EasyMock.getCurrentArguments()[1];
            Assert.assertFalse(attachmentReader.haveAllAttachmentsFinished());
            // Verify the action param.
            Assert.assertEquals((String) EasyMock.getCurrentArguments()[0], "someMetadata");
            // Set the response attachments
            resourceContextCapture.getValue().setResponseAttachments(responseAttachmentsBuilder.build());
            // Now throw an exception.
            @SuppressWarnings("unchecked") Callback<Long> callback = (Callback<Long>) EasyMock.getCurrentArguments()[2];
            callback.onError(new RestLiServiceException(HttpStatus.S_409_CONFLICT, "Some conflict"));
            return null;
        }
    });
    replay(statusResource);
    // Now we create a multipart/related payload.
    final String payload = "{\"metadata\": \"someMetadata\"}";
    final ByteStringWriter byteStringWriter = new ByteStringWriter(ByteString.copyString(payload, Charset.defaultCharset()));
    final MultiPartMIMEWriter.Builder builder = new MultiPartMIMEWriter.Builder();
    final RestLiTestAttachmentDataSource toBeDrainedDataSource = RestLiTestAttachmentDataSource.createWithRandomPayload("2");
    AttachmentUtils.appendSingleAttachmentToBuilder(builder, toBeDrainedDataSource);
    final MultiPartMIMEWriter writer = AttachmentUtils.createMultiPartMIMEWriter(byteStringWriter, "application/json", builder);
    final StreamRequest streamRequest = MultiPartMIMEStreamRequestFactory.generateMultiPartMIMEStreamRequest(new URI("/asyncstatuses/?action=streamingAction"), "related", writer, Collections.<String, String>emptyMap(), "POST", ImmutableMap.of(RestConstants.HEADER_ACCEPT, RestConstants.HEADER_VALUE_MULTIPART_RELATED), Collections.emptyList());
    final Callback<StreamResponse> callback = new Callback<StreamResponse>() {

        @Override
        public void onSuccess(StreamResponse streamResponse) {
            fail();
        }

        @Override
        public void onError(Throwable e) {
            // Verify the exception.
            assertTrue(e instanceof StreamException);
            StreamException streamException = (StreamException) e;
            StreamResponse streamResponse = streamException.getResponse();
            assertEquals(streamResponse.getStatus(), 409);
            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 exception made it.
                    assertTrue(result.length() > 0);
                    assertTrue(result.asString(Charset.defaultCharset()).contains("Some conflict"));
                }
            });
            streamResponse.getEntityStream().setReader(fullEntityReader);
            EasyMock.verify(statusResource);
            EasyMock.reset(statusResource);
        }
    };
    _server.handleRequest(streamRequest, new RequestContext(), callback);
    // Verify that the request level attachments were drained.
    Assert.assertTrue(toBeDrainedDataSource.finished());
    // Verify that response attachments were told to abort.
    Assert.assertTrue(toBeAbortedDataSource.dataSourceAborted());
}
Also used : ByteString(com.linkedin.data.ByteString) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) ErrorResponseBuilder(com.linkedin.restli.internal.server.response.ErrorResponseBuilder) StreamRequestBuilder(com.linkedin.r2.message.stream.StreamRequestBuilder) RestResponseBuilder(com.linkedin.r2.message.rest.RestResponseBuilder) ByteString(com.linkedin.data.ByteString) URI(java.net.URI) StreamException(com.linkedin.r2.message.stream.StreamException) FullEntityReader(com.linkedin.r2.message.stream.entitystream.FullEntityReader) RestLiTestAttachmentDataSource(com.linkedin.restli.internal.testutils.RestLiTestAttachmentDataSource) FilterRequestContext(com.linkedin.restli.server.filter.FilterRequestContext) RequestContext(com.linkedin.r2.message.RequestContext) MultiPartMIMEWriter(com.linkedin.multipart.MultiPartMIMEWriter) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) AsyncStatusCollectionResource(com.linkedin.restli.server.twitter.AsyncStatusCollectionResource) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) SinglePartMIMEFullReaderCallback(com.linkedin.multipart.utils.MIMETestUtils.SinglePartMIMEFullReaderCallback) Callback(com.linkedin.common.callback.Callback) MultiPartMIMEFullReaderCallback(com.linkedin.multipart.utils.MIMETestUtils.MultiPartMIMEFullReaderCallback) RestLiAttachmentReader(com.linkedin.restli.common.attachments.RestLiAttachmentReader) ByteStringWriter(com.linkedin.r2.message.stream.entitystream.ByteStringWriter) Test(org.testng.annotations.Test) AfterTest(org.testng.annotations.AfterTest) BeforeTest(org.testng.annotations.BeforeTest)

Example 22 with FullEntityReader

use of com.linkedin.r2.message.stream.entitystream.FullEntityReader in project rest.li by linkedin.

the class TestRestLiServer method testMultipartRelatedNoAttachmentsAtAll.

@Test
public void testMultipartRelatedNoAttachmentsAtAll() throws Exception {
    // This test verifies the server's ability to throw an exception if there are absolutely no attachments at all
    // in the request. The protocol allows no user attachments to be required, but there must always be at least a rest.li
    // payload in the first part.
    final MultiPartMIMEWriter.Builder builder = new MultiPartMIMEWriter.Builder();
    final StreamRequest streamRequest = MultiPartMIMEStreamRequestFactory.generateMultiPartMIMEStreamRequest(new URI("/statuses/1"), "related", builder.build(), Collections.emptyMap(), "POST", ImmutableMap.of(RestConstants.HEADER_ACCEPT, RestConstants.HEADER_VALUE_MULTIPART_RELATED), Collections.emptyList());
    final Callback<StreamResponse> callback = new Callback<StreamResponse>() {

        @Override
        public void onSuccess(StreamResponse streamResponse) {
            Assert.fail();
        }

        @Override
        public void onError(Throwable e) {
            // Verify the exception.
            assertTrue(e instanceof StreamException);
            StreamException streamException = (StreamException) e;
            StreamResponse streamResponse = streamException.getResponse();
            assertEquals(streamResponse.getStatus(), 400);
            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 that the exception made it.
                    assertTrue(result.length() > 0);
                    assertTrue(result.asString(Charset.defaultCharset()).contains("Did not receive any parts in the multipart mime request"));
                }
            });
            streamResponse.getEntityStream().setReader(fullEntityReader);
        }
    };
    _server.handleRequest(streamRequest, new RequestContext(), callback);
}
Also used : ByteString(com.linkedin.data.ByteString) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) ErrorResponseBuilder(com.linkedin.restli.internal.server.response.ErrorResponseBuilder) StreamRequestBuilder(com.linkedin.r2.message.stream.StreamRequestBuilder) RestResponseBuilder(com.linkedin.r2.message.rest.RestResponseBuilder) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) 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) MultiPartMIMEWriter(com.linkedin.multipart.MultiPartMIMEWriter) 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