use of com.linkedin.multipart.MultiPartMIMEWriter 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());
}
use of com.linkedin.multipart.MultiPartMIMEWriter in project rest.li by linkedin.
the class TestMIMEIntegrationReaderWriter method testEachSingleBodyDataSource.
@Test(dataProvider = "eachSingleBodyDataSource", enabled = false)
public void testEachSingleBodyDataSource(final int chunkSize, final MIMEDataPart bodyPart) throws Exception {
final MultiPartMIMEInputStream inputStreamDataSource = new MultiPartMIMEInputStream.Builder(new ByteArrayInputStream(bodyPart.getPartData().copyBytes()), scheduledExecutorService, bodyPart.getPartHeaders()).withWriteChunkSize(chunkSize).build();
final MultiPartMIMEWriter writer = new MultiPartMIMEWriter.Builder("some preamble", "").appendDataSource(inputStreamDataSource).build();
executeRequestAndAssert(writer, Collections.unmodifiableList(Collections.singletonList(bodyPart)));
}
use of com.linkedin.multipart.MultiPartMIMEWriter in project rest.li by linkedin.
the class TestMIMEIntegrationReaderWriter method testMultipleBodies.
@Test(dataProvider = "chunkSizes")
public void testMultipleBodies(final int chunkSize) throws Exception {
final MultiPartMIMEInputStream normalBodyInputStream = new MultiPartMIMEInputStream.Builder(new ByteArrayInputStream(_normalBody.getPartData().copyBytes()), scheduledExecutorService, _normalBody.getPartHeaders()).withWriteChunkSize(chunkSize).build();
final MultiPartMIMEInputStream headerLessBodyInputStream = new MultiPartMIMEInputStream.Builder(new ByteArrayInputStream(_headerLessBody.getPartData().copyBytes()), scheduledExecutorService, _headerLessBody.getPartHeaders()).withWriteChunkSize(chunkSize).build();
// Copying over empty ByteString, but let's keep things consistent.
final MultiPartMIMEInputStream bodyLessBodyInputStream = new MultiPartMIMEInputStream.Builder(new ByteArrayInputStream(_bodyLessBody.getPartData().copyBytes()), scheduledExecutorService, _bodyLessBody.getPartHeaders()).withWriteChunkSize(chunkSize).build();
final MultiPartMIMEInputStream purelyEmptyBodyInputStream = new MultiPartMIMEInputStream.Builder(new ByteArrayInputStream(_purelyEmptyBody.getPartData().copyBytes()), scheduledExecutorService, _purelyEmptyBody.getPartHeaders()).withWriteChunkSize(chunkSize).build();
final MultiPartMIMEWriter writer = new MultiPartMIMEWriter.Builder("some preamble", "").appendDataSource(normalBodyInputStream).appendDataSource(headerLessBodyInputStream).appendDataSource(bodyLessBodyInputStream).appendDataSource(purelyEmptyBodyInputStream).build();
executeRequestAndAssert(writer, Collections.unmodifiableList(Arrays.asList(_normalBody, _headerLessBody, _bodyLessBody, _purelyEmptyBody)));
}
use of com.linkedin.multipart.MultiPartMIMEWriter in project rest.li by linkedin.
the class TestMIMEChainingMultipleSources method testSinglePartDataSource.
// Test breakdown:
// 1. Main thread sends mime request
// 2. Server A sends a simple POST request to Server B
// 3. Server B sends back a mime response to Server A
// 4. Server A takes the original incoming request from the main thread + a local input
// stream + the first part from the incoming mime response from Server B.
// 5. Main thread then gets all of this and stores it.
// 6. Server A then drains and stores the rest of the parts from Server B's response.
@Test(dataProvider = "chunkSizes", groups = TESTNG_GROUP_KNOWN_ISSUE)
public void testSinglePartDataSource(final int chunkSize) throws Exception {
_chunkSize = chunkSize;
final List<MultiPartMIMEDataSourceWriter> dataSources = generateInputStreamDataSources(chunkSize, _scheduledExecutorService);
final MultiPartMIMEWriter writer = new MultiPartMIMEWriter.Builder().appendDataSources(dataSources).build();
final StreamRequest streamRequest = MultiPartMIMEStreamRequestFactory.generateMultiPartMIMEStreamRequest(Bootstrap.createHttpsURI(PORT_SERVER_A, SERVER_A_URI), "mixed", writer, Collections.<String, String>emptyMap());
ClientMultiPartReceiver clientReceiver = new ClientMultiPartReceiver();
Callback<StreamResponse> callback = generateSuccessChainCallback(clientReceiver);
// Send the request to Server A
_client.streamRequest(streamRequest, callback);
_latch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS);
// Verify client
List<MIMETestUtils.SinglePartMIMEFullReaderCallback> clientSinglePartCallbacks = clientReceiver.getSinglePartMIMEReaderCallbacks();
Assert.assertEquals(clientReceiver.getSinglePartMIMEReaderCallbacks().size(), 6);
Assert.assertEquals(clientSinglePartCallbacks.get(0).getFinishedData(), BODY_1.getPartData());
Assert.assertEquals(clientSinglePartCallbacks.get(0).getHeaders(), BODY_1.getPartHeaders());
Assert.assertEquals(clientSinglePartCallbacks.get(1).getFinishedData(), BODY_5.getPartData());
Assert.assertEquals(clientSinglePartCallbacks.get(1).getHeaders(), BODY_5.getPartHeaders());
Assert.assertEquals(clientSinglePartCallbacks.get(2).getFinishedData(), BODY_A.getPartData());
Assert.assertEquals(clientSinglePartCallbacks.get(2).getHeaders(), BODY_A.getPartHeaders());
Assert.assertEquals(clientSinglePartCallbacks.get(3).getFinishedData(), BODY_B.getPartData());
Assert.assertEquals(clientSinglePartCallbacks.get(3).getHeaders(), BODY_B.getPartHeaders());
Assert.assertEquals(clientSinglePartCallbacks.get(4).getFinishedData(), BODY_C.getPartData());
Assert.assertEquals(clientSinglePartCallbacks.get(4).getHeaders(), BODY_C.getPartHeaders());
Assert.assertEquals(clientSinglePartCallbacks.get(5).getFinishedData(), BODY_D.getPartData());
Assert.assertEquals(clientSinglePartCallbacks.get(5).getHeaders(), BODY_D.getPartHeaders());
// Verify Server A
List<MIMETestUtils.SinglePartMIMEFullReaderCallback> serverASinglePartCallbacks = _serverAMultiPartCallback.getSinglePartMIMEReaderCallbacks();
Assert.assertEquals(serverASinglePartCallbacks.size(), 3);
Assert.assertEquals(serverASinglePartCallbacks.get(0).getFinishedData(), BODY_2.getPartData());
Assert.assertEquals(serverASinglePartCallbacks.get(0).getHeaders(), BODY_2.getPartHeaders());
Assert.assertEquals(serverASinglePartCallbacks.get(1).getFinishedData(), BODY_3.getPartData());
Assert.assertEquals(serverASinglePartCallbacks.get(1).getHeaders(), BODY_3.getPartHeaders());
Assert.assertEquals(serverASinglePartCallbacks.get(2).getFinishedData(), BODY_4.getPartData());
Assert.assertEquals(serverASinglePartCallbacks.get(2).getHeaders(), BODY_4.getPartHeaders());
}
use of com.linkedin.multipart.MultiPartMIMEWriter in project rest.li by linkedin.
the class TestRestLiServer method testMultipartRelatedRequestNoUserAttachments.
@Test
public void testMultipartRelatedRequestNoUserAttachments() throws Exception {
// This test verifies the server's ability to handle a multipart related request that has only one part which is
// the rest.li payload; meaning there are no user defined attachments. Technically the client builders shouldn't do
// this but we allow this to keep the protocol somewhat flexible.
final AsyncStatusCollectionResource statusResource = getMockResource(AsyncStatusCollectionResource.class);
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 no attachments.
final RestLiAttachmentReader attachmentReader = (RestLiAttachmentReader) EasyMock.getCurrentArguments()[1];
Assert.assertNull(attachmentReader);
// Verify the action param.
Assert.assertEquals((String) EasyMock.getCurrentArguments()[0], "someMetadata");
// Now respond back to the request.
@SuppressWarnings("unchecked") Callback<Long> callback = (Callback<Long>) EasyMock.getCurrentArguments()[2];
callback.onSuccess(1234l);
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 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) {
Messages.toRestResponse(streamResponse, new Callback<RestResponse>() {
@Override
public void onError(Throwable e) {
Assert.fail();
}
@Override
public void onSuccess(RestResponse result) {
Assert.assertEquals(result.getStatus(), 200);
try {
ContentType contentType = new ContentType(streamResponse.getHeader(RestConstants.HEADER_CONTENT_TYPE));
Assert.assertEquals(contentType.getBaseType(), RestConstants.HEADER_VALUE_APPLICATION_JSON);
} catch (ParseException parseException) {
Assert.fail();
}
// Verify the response body
Assert.assertEquals(result.getEntity().asAvroString(), "{\"value\":1234}");
EasyMock.verify(statusResource);
EasyMock.reset(statusResource);
}
});
}
@Override
public void onError(Throwable e) {
fail();
}
};
_server.handleRequest(streamRequest, new RequestContext(), callback);
}
Aggregations