use of com.linkedin.restli.server.RestLiResponseAttachments in project rest.li by linkedin.
the class TestRestLiMethodInvocation method testExecutionReport.
@Test
public void testExecutionReport() throws RestLiSyntaxException, URISyntaxException {
Map<String, ResourceModel> resourceModelMap = buildResourceModels(StatusCollectionResource.class, AsyncStatusCollectionResource.class, PromiseStatusCollectionResource.class, TaskStatusCollectionResource.class);
ResourceModel statusResourceModel = resourceModelMap.get("/statuses");
ResourceModel asyncStatusResourceModel = resourceModelMap.get("/asyncstatuses");
ResourceModel promiseStatusResourceModel = resourceModelMap.get("/promisestatuses");
ResourceModel taskStatusResourceModel = resourceModelMap.get("/taskstatuses");
ResourceMethodDescriptor methodDescriptor;
StatusCollectionResource statusResource;
AsyncStatusCollectionResource asyncStatusResource;
PromiseStatusCollectionResource promiseStatusResource;
TaskStatusCollectionResource taskStatusResource;
// #1: Sync Method Execution
methodDescriptor = statusResourceModel.findMethod(ResourceMethod.GET);
statusResource = getMockResource(StatusCollectionResource.class);
EasyMock.expect(statusResource.get(eq(1L))).andReturn(null).once();
checkInvocation(statusResource, methodDescriptor, "GET", version, "/statuses/1", null, buildPathKeys("statusID", 1L), new RequestExecutionCallback<RestResponse>() {
//A 404 is considered an error by rest.li
@Override
public void onError(Throwable e, RequestExecutionReport executionReport, RestLiAttachmentReader requestAttachmentReader, RestLiResponseAttachments responseAttachments) {
Assert.assertNull(executionReport.getParseqTrace(), "There should be no parseq trace!");
}
@Override
public void onSuccess(RestResponse result, RequestExecutionReport executionReport, RestLiResponseAttachments responseAttachments) {
Assert.fail("Request failed unexpectedly.");
}
}, true, false);
// #2: Callback based Async Method Execution
Capture<RequestExecutionReport> requestExecutionReportCapture = new Capture<RequestExecutionReport>();
RestLiCallback<?> callback = getCallback(requestExecutionReportCapture);
methodDescriptor = asyncStatusResourceModel.findMethod(ResourceMethod.GET);
asyncStatusResource = getMockResource(AsyncStatusCollectionResource.class);
asyncStatusResource.get(eq(1L), EasyMock.<Callback<Status>>anyObject());
EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
@Override
public Object answer() throws Throwable {
@SuppressWarnings("unchecked") Callback<Status> callback = (Callback<Status>) EasyMock.getCurrentArguments()[1];
callback.onSuccess(null);
return null;
}
});
EasyMock.replay(asyncStatusResource);
checkAsyncInvocation(asyncStatusResource, callback, methodDescriptor, "GET", version, "/asyncstatuses/1", null, buildPathKeys("statusID", 1L), true);
Assert.assertNull(requestExecutionReportCapture.getValue().getParseqTrace());
// #3: Promise based Async Method Execution
methodDescriptor = promiseStatusResourceModel.findMethod(ResourceMethod.GET);
promiseStatusResource = getMockResource(PromiseStatusCollectionResource.class);
EasyMock.expect(promiseStatusResource.get(eq(1L))).andReturn(Promises.<Status>value(null)).once();
checkInvocation(promiseStatusResource, methodDescriptor, "GET", version, "/promisestatuses/1", null, buildPathKeys("statusID", 1L), new RequestExecutionCallback<RestResponse>() {
//A 404 is considered an error by rest.li
@Override
public void onError(Throwable e, RequestExecutionReport executionReport, RestLiAttachmentReader requestAttachmentReader, RestLiResponseAttachments responseAttachments) {
Assert.assertNotNull(executionReport.getParseqTrace(), "There should be a valid parseq trace!");
}
@Override
public void onSuccess(RestResponse result, RequestExecutionReport executionReport, RestLiResponseAttachments responseAttachments) {
Assert.fail("Request failed unexpectedly.");
}
}, true, false);
// #4: Task based Async Method Execution
methodDescriptor = taskStatusResourceModel.findMethod(ResourceMethod.GET);
taskStatusResource = getMockResource(TaskStatusCollectionResource.class);
EasyMock.expect(taskStatusResource.get(eq(1L))).andReturn(Task.callable("myTask", new Callable<Status>() {
@Override
public Status call() throws Exception {
return new Status();
}
})).once();
checkInvocation(taskStatusResource, methodDescriptor, "GET", version, "/taskstatuses/1", null, buildPathKeys("statusID", 1L), new RequestExecutionCallback<RestResponse>() {
@Override
public void onError(Throwable e, RequestExecutionReport executionReport, RestLiAttachmentReader requestAttachmentReader, RestLiResponseAttachments responseAttachments) {
Assert.fail("Request failed unexpectedly.");
}
@Override
public void onSuccess(RestResponse result, RequestExecutionReport executionReport, RestLiResponseAttachments responseAttachments) {
Assert.assertNotNull(executionReport.getParseqTrace());
}
}, true, false);
}
use of com.linkedin.restli.server.RestLiResponseAttachments in project rest.li by linkedin.
the class TestRestLiMethodInvocation method testInvokeWithUnsupportedAcceptMimeType.
@Test
public void testInvokeWithUnsupportedAcceptMimeType() throws Exception {
RestRequestBuilder builder = new RestRequestBuilder(new URI("")).addHeaderValue("Accept", "text/plain").setHeader(RestConstants.HEADER_RESTLI_PROTOCOL_VERSION, version.toString());
RestRequest request = builder.build();
final RestLiAttachmentReader attachmentReader = new RestLiAttachmentReader(null);
final CountDownLatch latch = new CountDownLatch(1);
RestLiResponseHandler restLiResponseHandler = new RestLiResponseHandler.Builder().build();
RequestExecutionCallback<RestResponse> executionCallback = new RequestExecutionCallback<RestResponse>() {
@Override
public void onError(Throwable e, RequestExecutionReport executionReport, RestLiAttachmentReader requestAttachmentReader, RestLiResponseAttachments responseAttachments) {
latch.countDown();
Assert.assertTrue(e instanceof RestException);
RestException ex = (RestException) e;
Assert.assertEquals(ex.getResponse().getStatus(), HttpStatus.S_406_NOT_ACCEPTABLE.getCode());
Assert.assertEquals(requestAttachmentReader, attachmentReader);
Assert.assertNull(responseAttachments);
}
@Override
public void onSuccess(RestResponse result, RequestExecutionReport executionReport, RestLiResponseAttachments responseAttachments) {
Assert.fail();
}
};
ServerResourceContext resourceContext = new ResourceContextImpl(new PathKeysImpl(), new RestRequestBuilder(URI.create("")).setHeader(RestConstants.HEADER_RESTLI_PROTOCOL_VERSION, AllProtocolVersions.LATEST_PROTOCOL_VERSION.toString()).build(), new RequestContext(), false, attachmentReader);
try {
RoutingResult routingResult = new RoutingResult(resourceContext, null);
RestUtils.validateRequestHeadersAndUpdateResourceContext(request.getHeaders(), (ServerResourceContext) routingResult.getContext());
FilterChainCallback filterChainCallback = new FilterChainCallbackImpl(null, _invoker, null, null, null, restLiResponseHandler, executionCallback);
final RestLiCallback<Object> callback = new RestLiCallback<Object>(null, new RestLiFilterResponseContextFactory<Object>(request, null, restLiResponseHandler), new RestLiFilterChain(null, filterChainCallback));
_invoker.invoke(null, routingResult, null, callback, null);
latch.await();
} catch (Exception e) {
// exception is expected
Assert.assertTrue(e instanceof RestLiServiceException);
}
Assert.assertNull(resourceContext.getResponseMimeType());
}
use of com.linkedin.restli.server.RestLiResponseAttachments in project rest.li by linkedin.
the class TestRestLiMethodInvocation method testInvokeWithInvalidAcceptMimeType.
@Test
public void testInvokeWithInvalidAcceptMimeType() throws Exception {
RestRequestBuilder builder = new RestRequestBuilder(new URI("")).addHeaderValue("Accept", "foo").setHeader(RestConstants.HEADER_RESTLI_PROTOCOL_VERSION, version.toString());
RestRequest request = builder.build();
final CountDownLatch latch = new CountDownLatch(1);
RestLiResponseHandler restLiResponseHandler = new RestLiResponseHandler.Builder().build();
RequestExecutionCallback<RestResponse> executionCallback = new RequestExecutionCallback<RestResponse>() {
@Override
public void onError(Throwable e, RequestExecutionReport executionReport, RestLiAttachmentReader requestAttachmentReader, RestLiResponseAttachments responseAttachments) {
latch.countDown();
Assert.assertTrue(e instanceof RestException);
RestException ex = (RestException) e;
Assert.assertEquals(ex.getResponse().getStatus(), HttpStatus.S_400_BAD_REQUEST.getCode());
}
@Override
public void onSuccess(RestResponse result, RequestExecutionReport executionReport, RestLiResponseAttachments responseAttachments) {
}
};
ServerResourceContext context = new ResourceContextImpl();
try {
RoutingResult routingResult = new RoutingResult(context, null);
RestUtils.validateRequestHeadersAndUpdateResourceContext(request.getHeaders(), (ServerResourceContext) routingResult.getContext());
FilterChainCallback filterChainCallback = new FilterChainCallbackImpl(null, _invoker, null, null, null, restLiResponseHandler, executionCallback);
final RestLiCallback<Object> callback = new RestLiCallback<Object>(null, new RestLiFilterResponseContextFactory<Object>(request, null, restLiResponseHandler), new RestLiFilterChain(null, filterChainCallback));
_invoker.invoke(null, routingResult, null, callback, null);
latch.await();
} catch (Exception e) {
// exception is expected
Assert.assertTrue(e instanceof RestLiServiceException);
}
Assert.assertNull(context.getResponseMimeType());
}
use of com.linkedin.restli.server.RestLiResponseAttachments in project rest.li by linkedin.
the class TestResourceContext method testStreamingDataResourceContext.
@Test
public void testStreamingDataResourceContext() throws Exception {
ServerResourceContext fullyStreamingResourceContext = new ResourceContextImpl(new PathKeysImpl(), new MockRequest(URI.create("foobar"), Collections.emptyMap()), new RequestContext(), true, new RestLiAttachmentReader(null));
Assert.assertTrue(fullyStreamingResourceContext.responseAttachmentsSupported());
Assert.assertNotNull(fullyStreamingResourceContext.getRequestAttachmentReader());
//Now set and get response attachments
final RestLiResponseAttachments restLiResponseAttachments = new RestLiResponseAttachments.Builder().build();
fullyStreamingResourceContext.setResponseAttachments(restLiResponseAttachments);
Assert.assertEquals(fullyStreamingResourceContext.getResponseAttachments(), restLiResponseAttachments);
ServerResourceContext responseAllowedNoRequestAttachmentsPresent = new ResourceContextImpl(new PathKeysImpl(), new MockRequest(URI.create("foobar"), Collections.emptyMap()), new RequestContext(), true, null);
Assert.assertTrue(responseAllowedNoRequestAttachmentsPresent.responseAttachmentsSupported());
Assert.assertNull(responseAllowedNoRequestAttachmentsPresent.getRequestAttachmentReader());
//Now set and get response attachments
responseAllowedNoRequestAttachmentsPresent.setResponseAttachments(restLiResponseAttachments);
Assert.assertEquals(responseAllowedNoRequestAttachmentsPresent.getResponseAttachments(), restLiResponseAttachments);
ServerResourceContext noResponseAllowedRequestAttachmentsPresent = new ResourceContextImpl(new PathKeysImpl(), new MockRequest(URI.create("foobar"), Collections.emptyMap()), new RequestContext(), false, new RestLiAttachmentReader(null));
Assert.assertFalse(noResponseAllowedRequestAttachmentsPresent.responseAttachmentsSupported());
Assert.assertNotNull(noResponseAllowedRequestAttachmentsPresent.getRequestAttachmentReader());
//Now try to set and make sure we fail
try {
noResponseAllowedRequestAttachmentsPresent.setResponseAttachments(restLiResponseAttachments);
Assert.fail();
} catch (IllegalStateException illegalStateException) {
//pass
}
}
use of com.linkedin.restli.server.RestLiResponseAttachments in project rest.li by linkedin.
the class TestRestLiCallback method testOnErrorWithFiltersNotHandlingAppEx.
@SuppressWarnings("unchecked")
@Test
public void testOnErrorWithFiltersNotHandlingAppEx() throws Exception {
Exception exFromApp = new RuntimeException("Runtime exception from app");
RestLiServiceException appException = new RestLiServiceException(HttpStatus.S_404_NOT_FOUND);
RequestExecutionReport executionReport = new RequestExecutionReportBuilder().build();
RestLiResponseAttachments responseAttachments = new RestLiResponseAttachments.Builder().build();
final Map<String, String> headersFromApp = Maps.newHashMap();
headersFromApp.put("Key", "Input");
final Map<String, String> headersFromFilter = Maps.newHashMap();
headersFromFilter.put("Key", "Output");
RestLiResponseDataImpl responseData = new RestLiResponseDataImpl(appException, headersFromApp, Collections.<HttpCookie>emptyList());
responseData.setResponseEnvelope(new CreateResponseEnvelope(new EmptyRecord(), responseData));
PartialRestResponse partialResponse = new PartialRestResponse.Builder().build();
when(_requestExecutionReportBuilder.build()).thenReturn(executionReport);
when(_responseHandler.buildExceptionResponseData(eq(_restRequest), eq(_routingResult), any(RestLiServiceException.class), anyMap(), anyList())).thenReturn(responseData);
when(_responseHandler.buildPartialResponse(_routingResult, responseData)).thenReturn(partialResponse);
// Mock the behavior of the first filter.
doAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
Throwable t = (Throwable) args[0];
FilterRequestContext requestContext = (FilterRequestContext) args[1];
FilterResponseContext responseContext = (FilterResponseContext) args[2];
// Verify incoming data.
assertEquals(HttpStatus.S_404_NOT_FOUND, responseContext.getResponseData().getStatus());
assertEquals(headersFromApp, responseContext.getResponseData().getHeaders());
assertNull(responseContext.getResponseData().getRecordResponseEnvelope().getRecord());
// Modify data in filter.
setStatus(responseContext, HttpStatus.S_400_BAD_REQUEST);
responseContext.getResponseData().getHeaders().clear();
return completedFutureWithError(responseContext.getResponseData().getServiceException());
}
}).doAnswer(new Answer<Object>() {
// Mock the behavior of the second filter.
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
Throwable t = (Throwable) args[0];
FilterRequestContext requestContext = (FilterRequestContext) args[1];
FilterResponseContext responseContext = (FilterResponseContext) args[2];
// Verify incoming data.
assertEquals(HttpStatus.S_400_BAD_REQUEST, responseContext.getResponseData().getStatus());
//assertTrue(responseContext.getResponseData().getHeaders().isEmpty());
assertNull(responseContext.getResponseData().getRecordResponseEnvelope().getRecord());
// Modify data in filter.
setStatus(responseContext, HttpStatus.S_403_FORBIDDEN);
responseContext.getResponseData().getHeaders().putAll(headersFromFilter);
return completedFutureWithError(responseContext.getResponseData().getServiceException());
}
}).when(_filter).onError(any(Throwable.class), eq(_filterRequestContext), any(FilterResponseContext.class));
RestException restException = new RestException(new RestResponseBuilder().build());
when(_responseHandler.buildRestException(any(RestLiServiceException.class), eq(partialResponse))).thenReturn(restException);
// invoke request filters so cursor is in correct place
when(_filter.onRequest(any(FilterRequestContext.class))).thenReturn(CompletableFuture.completedFuture(null));
_twoFilterChain.onRequest(_filterRequestContext, _filterResponseContextFactory);
// Invoke.
_twoFilterRestLiCallback.onError(exFromApp, executionReport, _requestAttachmentReader, responseAttachments);
// Verify.
assertNotNull(responseData);
assertEquals(HttpStatus.S_403_FORBIDDEN, responseData.getStatus());
assertNull(responseData.getRecordResponseEnvelope().getRecord());
assertTrue(responseData.isErrorResponse());
assertEquals(responseData.getServiceException().getErrorDetails(), appException.getErrorDetails());
assertEquals(responseData.getServiceException().getOverridingFormat(), appException.getOverridingFormat());
assertEquals(responseData.getServiceException().getServiceErrorCode(), appException.getServiceErrorCode());
assertEquals(responseData.getServiceException().getMessage(), appException.getMessage());
Map<String, String> expectedHeaders = buildErrorHeaders();
expectedHeaders.put("Key", "Output");
assertEquals(expectedHeaders, responseData.getHeaders());
ArgumentCaptor<RestLiServiceException> exCapture = ArgumentCaptor.forClass(RestLiServiceException.class);
verify(_responseHandler, times(1)).buildExceptionResponseData(eq(_restRequest), eq(_routingResult), exCapture.capture(), anyMap(), anyList());
verify(_responseHandler).buildPartialResponse(_routingResult, responseData);
verify(_responseHandler).buildRestException(exCapture.capture(), eq(partialResponse));
verify(_callback).onError(restException, executionReport, _requestAttachmentReader, responseAttachments);
verify(_restRequest, times(1)).getHeaders();
verifyZeroInteractions(_routingResult);
verifyNoMoreInteractions(_restRequest, _responseHandler, _callback);
final RestLiServiceException restliEx1 = exCapture.getAllValues().get(0);
assertNotNull(restliEx1);
assertEquals(HttpStatus.S_500_INTERNAL_SERVER_ERROR, restliEx1.getStatus());
assertEquals(exFromApp.getMessage(), restliEx1.getMessage());
assertEquals(exFromApp, restliEx1.getCause());
final RestLiServiceException restliEx2 = exCapture.getAllValues().get(1);
assertNotNull(restliEx2);
assertEquals(HttpStatus.S_403_FORBIDDEN, restliEx2.getStatus());
}
Aggregations