Search in sources :

Example 11 with RestLiTestAttachmentDataSource

use of com.linkedin.restli.internal.testutils.RestLiTestAttachmentDataSource in project rest.li by linkedin.

the class TestParseqTraceDebugRequestHandler method testErrorStreamingAbsorbRequestAbortResponse.

@Test
public void testErrorStreamingAbsorbRequestAbortResponse() throws Exception {
    //This test verifies that in the face of an error, the ParseqTraceDebugRequestHandler aborts any potential outgoing
    //response attachments and absorbs and drops on the ground any incoming request attachments.
    final URI uri = URI.create("http://host/abc/12/__debug/parseqtrace/raw");
    ParseqTraceDebugRequestHandler requestHandler = new ParseqTraceDebugRequestHandler();
    RestRequestBuilder requestBuilder = new RestRequestBuilder(uri);
    RestRequest request = requestBuilder.build();
    RequestContext requestContext = new RequestContext();
    final RequestExecutionCallback<RestResponse> callback = new RequestExecutionCallback<RestResponse>() {

        @Override
        public void onError(Throwable e, RequestExecutionReport executionReport, RestLiAttachmentReader requestAttachmentReader, RestLiResponseAttachments responseAttachments) {
            //Even though we call callback.onError() below to simulate a failed rest.li request execution, the
            //ParseqTraceDebugRequestHandler eventually treats this as a success.
            Assert.fail("Request execution passed unexpectedly.");
        }

        @Override
        public void onSuccess(RestResponse result, RequestExecutionReport executionReport, RestLiResponseAttachments responseAttachments) {
        }
    };
    //Create request and response attachments. This is not the wire protocol for rest.li streaming, but
    //makes this test easier to write and understand.
    //Response attachment.
    final RestLiTestAttachmentDataSource responseDataSource = RestLiTestAttachmentDataSource.createWithRandomPayload("1");
    final RestLiResponseAttachments responseAttachments = new RestLiResponseAttachments.Builder().appendSingleAttachment(responseDataSource).build();
    //Request attachment. We need to create a reader here.
    final RestLiTestAttachmentDataSource requestAttachment = RestLiTestAttachmentDataSource.createWithRandomPayload("2");
    final MultiPartMIMEWriter.Builder builder = new MultiPartMIMEWriter.Builder();
    AttachmentUtils.appendSingleAttachmentToBuilder(builder, requestAttachment);
    final ByteStringWriter byteStringWriter = new ByteStringWriter(ByteString.copyString("Normal rest.li request payload", Charset.defaultCharset()));
    final MultiPartMIMEWriter writer = AttachmentUtils.createMultiPartMIMEWriter(byteStringWriter, "application/json", builder);
    final StreamRequest streamRequest = MultiPartMIMEStreamRequestFactory.generateMultiPartMIMEStreamRequest(new URI(""), "related", writer);
    final MultiPartMIMEReader reader = MultiPartMIMEReader.createAndAcquireStream(streamRequest);
    final RestLiAttachmentReader attachmentReader = new RestLiAttachmentReader(reader);
    //Absorb the first part as rest.li server does and then give the beginning of the next part to the
    //ParseqTraceDebugRequestHandler.
    final MultiPartMIMEReaderCallback multiPartMIMEReaderCallback = new MultiPartMIMEReaderCallback() {

        int partCounter = 0;

        @Override
        public void onNewPart(MultiPartMIMEReader.SinglePartMIMEReader singlePartMIMEReader) {
            if (partCounter == 0) {
                singlePartMIMEReader.drainPart();
                partCounter++;
            } else {
                //When the first part is read in, at the beginning of the 2nd part, we move to the debug request handler.
                requestHandler.handleRequest(request, requestContext, new RestLiDebugRequestHandler.ResourceDebugRequestHandler() {

                    @Override
                    public void handleRequest(RestRequest request, RequestContext requestContext, RequestExecutionCallback<RestResponse> callback) {
                        callback.onError(RestException.forError(500, "An error has occurred"), new RequestExecutionReportBuilder().build(), attachmentReader, responseAttachments);
                    }
                }, attachmentReader, callback);
            }
        }

        @Override
        public void onFinished() {
            Assert.fail();
        }

        @Override
        public void onDrainComplete() {
        //Eventually this should occur.
        }

        @Override
        public void onStreamError(Throwable throwable) {
            Assert.fail();
        }
    };
    reader.registerReaderCallback(multiPartMIMEReaderCallback);
    //The response data source should have been aborted.
    Assert.assertTrue(responseDataSource.dataSourceAborted());
    //The request attachment should have been absorbed and finished.
    Assert.assertTrue(requestAttachment.finished());
}
Also used : RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) URI(java.net.URI) MultiPartMIMEReaderCallback(com.linkedin.multipart.MultiPartMIMEReaderCallback) RequestContext(com.linkedin.r2.message.RequestContext) RestLiTestAttachmentDataSource(com.linkedin.restli.internal.testutils.RestLiTestAttachmentDataSource) MultiPartMIMEWriter(com.linkedin.multipart.MultiPartMIMEWriter) RestResponse(com.linkedin.r2.message.rest.RestResponse) MultiPartMIMEReader(com.linkedin.multipart.MultiPartMIMEReader) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) RestRequest(com.linkedin.r2.message.rest.RestRequest) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) RestLiAttachmentReader(com.linkedin.restli.common.attachments.RestLiAttachmentReader) ByteStringWriter(com.linkedin.r2.message.stream.entitystream.ByteStringWriter) Test(org.testng.annotations.Test)

Example 12 with RestLiTestAttachmentDataSource

use of com.linkedin.restli.internal.testutils.RestLiTestAttachmentDataSource in project rest.li by linkedin.

the class TestStreamingGreetings method resourceMethodDoesNotAcceptAttachments.

@Test(dataProvider = com.linkedin.restli.internal.common.TestConstants.RESTLI_PROTOCOL_1_2_PREFIX + "requestBuilderDataProvider")
public void resourceMethodDoesNotAcceptAttachments(final RootBuilderWrapper<Long, Greeting> builders) throws RemoteInvocationException {
    //Resource method does not desire request attachments. Assert that all the attachments are drained and that a 400
    //bad request is observed.
    final RestLiTestAttachmentDataSource greetingAttachment = new RestLiTestAttachmentDataSource("1", ByteString.copyString("clientData", Charset.defaultCharset()));
    RootBuilderWrapper.MethodBuilderWrapper<Long, Greeting, Object> methodBuilderWrapper = builders.action("actionNoAttachmentsAllowed");
    methodBuilderWrapper.appendSingleAttachment(greetingAttachment);
    final Request<Object> request = methodBuilderWrapper.build();
    try {
        getClient().sendRequest(request).getResponse().getEntity();
        Assert.fail();
    } catch (final RestLiResponseException responseException) {
        Assert.assertEquals(responseException.getStatus(), 400);
        Assert.assertEquals(responseException.getServiceErrorMessage(), "Resource method endpoint invoked does not accept any request attachments.");
    }
    //Then verify the response and request attachments were fully absorbed.
    Assert.assertTrue(greetingAttachment.finished());
}
Also used : Greeting(com.linkedin.restli.examples.greetings.api.Greeting) RootBuilderWrapper(com.linkedin.restli.test.util.RootBuilderWrapper) RestLiResponseException(com.linkedin.restli.client.RestLiResponseException) RestLiTestAttachmentDataSource(com.linkedin.restli.internal.testutils.RestLiTestAttachmentDataSource) Test(org.testng.annotations.Test)

Example 13 with RestLiTestAttachmentDataSource

use of com.linkedin.restli.internal.testutils.RestLiTestAttachmentDataSource in project rest.li by linkedin.

the class TestAttachmentUtils method testSingleAttachment.

@Test
public void testSingleAttachment() {
    final MultiPartMIMEWriter.Builder builder = new MultiPartMIMEWriter.Builder();
    final List<RestLiTestAttachmentDataSource> testAttachmentDataSources = generateTestDataSources();
    for (RestLiTestAttachmentDataSource dataSource : testAttachmentDataSources) {
        AttachmentUtils.appendSingleAttachmentToBuilder(builder, dataSource);
    }
    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);
}
Also used : MultiPartMIMEReader(com.linkedin.multipart.MultiPartMIMEReader) RestLiTestAttachmentDataSource(com.linkedin.restli.internal.testutils.RestLiTestAttachmentDataSource) CountDownLatch(java.util.concurrent.CountDownLatch) MultiPartMIMEWriter(com.linkedin.multipart.MultiPartMIMEWriter) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) MIMETestUtils(com.linkedin.multipart.utils.MIMETestUtils) Test(org.testng.annotations.Test)

Example 14 with RestLiTestAttachmentDataSource

use of com.linkedin.restli.internal.testutils.RestLiTestAttachmentDataSource in project rest.li by linkedin.

the class TestAttachmentUtils method testMixtureOfAttachments.

@Test
public void testMixtureOfAttachments() {
    final MultiPartMIMEWriter.Builder builder = new MultiPartMIMEWriter.Builder();
    final List<RestLiTestAttachmentDataSource> iteratorDataSources = generateTestDataSources();
    final RestLiTestAttachmentDataSourceIterator dataSourceIterator = new RestLiTestAttachmentDataSourceIterator(iteratorDataSources, 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 : iteratorDataSources) {
        dataSource.setParentDataSourceIterator(dataSourceIterator);
    }
    //Now one at the beginning
    final RestLiTestAttachmentDataSource dataSourceBeginning = RestLiTestAttachmentDataSource.createWithRandomPayload("BEG");
    //And one at the end
    final RestLiTestAttachmentDataSource dataSourceEnd = RestLiTestAttachmentDataSource.createWithRandomPayload("END");
    AttachmentUtils.appendSingleAttachmentToBuilder(builder, dataSourceBeginning);
    AttachmentUtils.appendMultipleAttachmentsToBuilder(builder, dataSourceIterator);
    AttachmentUtils.appendSingleAttachmentToBuilder(builder, dataSourceEnd);
    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();
    }
    final List<RestLiTestAttachmentDataSource> allAttachmentDataSources = new ArrayList<>();
    allAttachmentDataSources.add(dataSourceBeginning);
    allAttachmentDataSources.addAll(iteratorDataSources);
    allAttachmentDataSources.add(dataSourceEnd);
    verifyAttachments(streamRequestReaderCallback.getSinglePartMIMEReaderCallbacks(), allAttachmentDataSources);
}
Also used : RestLiTestAttachmentDataSourceIterator(com.linkedin.restli.internal.testutils.RestLiTestAttachmentDataSourceIterator) MultiPartMIMEReader(com.linkedin.multipart.MultiPartMIMEReader) ArrayList(java.util.ArrayList) CountDownLatch(java.util.concurrent.CountDownLatch) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) RestLiTestAttachmentDataSource(com.linkedin.restli.internal.testutils.RestLiTestAttachmentDataSource) MultiPartMIMEWriter(com.linkedin.multipart.MultiPartMIMEWriter) MIMETestUtils(com.linkedin.multipart.utils.MIMETestUtils) Test(org.testng.annotations.Test)

Example 15 with RestLiTestAttachmentDataSource

use of com.linkedin.restli.internal.testutils.RestLiTestAttachmentDataSource 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 = new Capture<ResourceContext>();
    final AsyncStatusCollectionResource statusResource = getMockResource(AsyncStatusCollectionResource.class, EasyMock.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;
        }
    });
    EasyMock.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) Capture(org.easymock.Capture) 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)

Aggregations

RestLiTestAttachmentDataSource (com.linkedin.restli.internal.testutils.RestLiTestAttachmentDataSource)17 Test (org.testng.annotations.Test)14 MultiPartMIMEWriter (com.linkedin.multipart.MultiPartMIMEWriter)7 StreamRequest (com.linkedin.r2.message.stream.StreamRequest)6 MultiPartMIMEReader (com.linkedin.multipart.MultiPartMIMEReader)5 RestLiAttachmentReader (com.linkedin.restli.common.attachments.RestLiAttachmentReader)5 CountDownLatch (java.util.concurrent.CountDownLatch)5 RequestContext (com.linkedin.r2.message.RequestContext)4 RestRequestBuilder (com.linkedin.r2.message.rest.RestRequestBuilder)4 RestLiTestAttachmentDataSourceIterator (com.linkedin.restli.internal.testutils.RestLiTestAttachmentDataSourceIterator)4 URI (java.net.URI)4 ByteString (com.linkedin.data.ByteString)3 MIMETestUtils (com.linkedin.multipart.utils.MIMETestUtils)3 ByteStringWriter (com.linkedin.r2.message.stream.entitystream.ByteStringWriter)3 TestRecord (com.linkedin.restli.client.test.TestRecord)3 ArrayList (java.util.ArrayList)3 Callback (com.linkedin.common.callback.Callback)2 DataMap (com.linkedin.data.DataMap)2 MultiPartMIMEFullReaderCallback (com.linkedin.multipart.utils.MIMETestUtils.MultiPartMIMEFullReaderCallback)2 SinglePartMIMEFullReaderCallback (com.linkedin.multipart.utils.MIMETestUtils.SinglePartMIMEFullReaderCallback)2