use of com.linkedin.restli.server.RestLiResponseAttachments in project rest.li by linkedin.
the class StreamingGreetings method respondWithResponseAttachment.
private void respondWithResponseAttachment(final Callback<UpdateResponse> callback) {
if (getContext().responseAttachmentsSupported()) {
//Echo the bytes back from the header
final String headerValue = getContext().getRequestHeaders().get("getHeader");
final GreetingWriter greetingWriter = new GreetingWriter(ByteString.copy(headerValue.getBytes()));
final RestLiResponseAttachments streamingAttachments = new RestLiResponseAttachments.Builder().appendSingleAttachment(greetingWriter).build();
getContext().setResponseAttachments(streamingAttachments);
callback.onSuccess(new UpdateResponse(HttpStatus.S_200_OK));
}
callback.onError(new RestLiServiceException(HttpStatus.S_400_BAD_REQUEST, "You must be able to receive attachments!"));
}
use of com.linkedin.restli.server.RestLiResponseAttachments in project rest.li by linkedin.
the class StreamingGreetings method get.
@Override
public void get(Long key, @CallbackParam Callback<Greeting> callback) {
if (getContext().responseAttachmentsSupported()) {
final GreetingWriter greetingWriter = new GreetingWriter(ByteString.copy(greetingBytes));
final RestLiResponseAttachments streamingAttachments = new RestLiResponseAttachments.Builder().appendSingleAttachment(greetingWriter).build();
getContext().setResponseAttachments(streamingAttachments);
final String headerValue = getContext().getRequestHeaders().get("getHeader");
getContext().setResponseHeader("getHeader", headerValue);
callback.onSuccess(new Greeting().setMessage("Your greeting has an attachment since you were kind and " + "decided you wanted to read it!").setId(key));
}
callback.onError(new RestLiServiceException(HttpStatus.S_400_BAD_REQUEST, "You must be able to receive attachments!"));
}
use of com.linkedin.restli.server.RestLiResponseAttachments in project rest.li by linkedin.
the class TestRestLiMethodInvocation method testStreaming.
@Test
public void testStreaming() throws RestLiSyntaxException, URISyntaxException {
Map<String, ResourceModel> resourceModelMap = buildResourceModels(StatusCollectionResource.class, AsyncStatusCollectionResource.class, PromiseStatusCollectionResource.class, TaskStatusCollectionResource.class);
final String payload = "{\"metadata\": \"someMetadata\"}";
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;
//Sync Method Execution - Successful scenario
methodDescriptor = statusResourceModel.findActionMethod("streamingAction", ResourceLevel.COLLECTION);
statusResource = getMockResource(StatusCollectionResource.class);
EasyMock.expect(statusResource.streamingAction(EasyMock.<String>anyObject(), EasyMock.<RestLiAttachmentReader>anyObject())).andReturn(1234l).once();
checkInvocation(statusResource, methodDescriptor, "POST", version, "/statuses/?action=streamingAction", payload, null, 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) {
}
}, false, false, new RestLiAttachmentReader(null), new RestLiResponseAttachments.Builder().build());
//Sync Method Execution - Error scenario
statusResource = getMockResource(StatusCollectionResource.class);
EasyMock.expect(statusResource.streamingAction(EasyMock.<String>anyObject(), EasyMock.<RestLiAttachmentReader>anyObject())).andThrow(new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR)).once();
checkInvocation(statusResource, methodDescriptor, "POST", version, "/statuses/?action=streamingAction", payload, null, new RequestExecutionCallback<RestResponse>() {
@Override
public void onError(Throwable e, RequestExecutionReport executionReport, RestLiAttachmentReader requestAttachmentReader, RestLiResponseAttachments responseAttachments) {
}
@Override
public void onSuccess(RestResponse result, RequestExecutionReport executionReport, RestLiResponseAttachments responseAttachments) {
Assert.fail("Request passed unexpectedly.");
}
}, false, false, new RestLiAttachmentReader(null), new RestLiResponseAttachments.Builder().build());
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Callback Method Execution - Successful scenario
methodDescriptor = asyncStatusResourceModel.findMethod(ResourceMethod.ACTION);
asyncStatusResource = getMockResource(AsyncStatusCollectionResource.class);
asyncStatusResource.streamingAction(EasyMock.<String>anyObject(), EasyMock.<RestLiAttachmentReader>anyObject(), EasyMock.<Callback<Long>>anyObject());
EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
@Override
public Object answer() throws Throwable {
@SuppressWarnings("unchecked") Callback<Long> callback = (Callback<Long>) EasyMock.getCurrentArguments()[2];
callback.onSuccess(1234l);
return null;
}
});
checkInvocation(asyncStatusResource, methodDescriptor, "POST", version, "/asyncstatuses/?action=streamingAction", payload, null, 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) {
}
}, false, false, new RestLiAttachmentReader(null), new RestLiResponseAttachments.Builder().build());
//Callback Method Execution - Error scenario
asyncStatusResource = getMockResource(AsyncStatusCollectionResource.class);
asyncStatusResource.streamingAction(EasyMock.<String>anyObject(), EasyMock.<RestLiAttachmentReader>anyObject(), EasyMock.<Callback<Long>>anyObject());
EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
@Override
public Object answer() throws Throwable {
@SuppressWarnings("unchecked") Callback<Long> callback = (Callback<Long>) EasyMock.getCurrentArguments()[2];
callback.onError(new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR));
return null;
}
});
checkInvocation(asyncStatusResource, methodDescriptor, "POST", version, "/asyncstatuses/?action=streamingAction", payload, null, new RequestExecutionCallback<RestResponse>() {
@Override
public void onError(Throwable e, RequestExecutionReport executionReport, RestLiAttachmentReader requestAttachmentReader, RestLiResponseAttachments responseAttachments) {
}
@Override
public void onSuccess(RestResponse result, RequestExecutionReport executionReport, RestLiResponseAttachments responseAttachments) {
Assert.fail("Request passed unexpectedly.");
}
}, false, false, new RestLiAttachmentReader(null), new RestLiResponseAttachments.Builder().build());
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Promise Method Execution - Successful scenario
methodDescriptor = promiseStatusResourceModel.findActionMethod("streamingAction", ResourceLevel.COLLECTION);
promiseStatusResource = getMockResource(PromiseStatusCollectionResource.class);
promiseStatusResource.streamingAction(EasyMock.<String>anyObject(), EasyMock.<RestLiAttachmentReader>anyObject());
EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
@Override
public Object answer() throws Throwable {
final SettablePromise<Long> result = Promises.settable();
final Runnable requestHandler = new Runnable() {
public void run() {
try {
result.done(1234l);
} catch (final Throwable throwable) {
result.fail(throwable);
}
}
};
_scheduler.schedule(requestHandler, 0, TimeUnit.MILLISECONDS);
return result;
}
});
checkInvocation(promiseStatusResource, methodDescriptor, "POST", version, "/promisestatuses/?action=streamingAction", payload, null, 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) {
}
}, false, false, new RestLiAttachmentReader(null), new RestLiResponseAttachments.Builder().build());
//Promise Method Execution - Error scenario
promiseStatusResource = getMockResource(PromiseStatusCollectionResource.class);
promiseStatusResource.streamingAction(EasyMock.<String>anyObject(), EasyMock.<RestLiAttachmentReader>anyObject());
EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
@Override
public Object answer() throws Throwable {
final SettablePromise<Long> result = Promises.settable();
final Runnable requestHandler = new Runnable() {
public void run() {
result.fail(new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR));
}
};
_scheduler.schedule(requestHandler, 0, TimeUnit.MILLISECONDS);
return result;
}
});
checkInvocation(promiseStatusResource, methodDescriptor, "POST", version, "/promisestatuses/?action=streamingAction", payload, null, new RequestExecutionCallback<RestResponse>() {
@Override
public void onError(Throwable e, RequestExecutionReport executionReport, RestLiAttachmentReader requestAttachmentReader, RestLiResponseAttachments responseAttachments) {
}
@Override
public void onSuccess(RestResponse result, RequestExecutionReport executionReport, RestLiResponseAttachments responseAttachments) {
Assert.fail("Request passed unexpectedly.");
}
}, false, false, new RestLiAttachmentReader(null), new RestLiResponseAttachments.Builder().build());
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Task Method Execution - Successful scenario
methodDescriptor = taskStatusResourceModel.findMethod(ResourceMethod.ACTION);
taskStatusResource = getMockResource(TaskStatusCollectionResource.class);
taskStatusResource.streamingAction(EasyMock.<String>anyObject(), EasyMock.<RestLiAttachmentReader>anyObject());
EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
@Override
public Object answer() throws Throwable {
return new BaseTask<Long>() {
protected Promise<Long> run(final Context context) throws Exception {
return Promises.value(1234l);
}
};
}
});
checkInvocation(taskStatusResource, methodDescriptor, "POST", version, "/taskstatuses/?action=streamingAction", payload, null, 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) {
}
}, false, false, new RestLiAttachmentReader(null), new RestLiResponseAttachments.Builder().build());
//Task Method Execution - Error scenario
taskStatusResource = getMockResource(TaskStatusCollectionResource.class);
taskStatusResource.streamingAction(EasyMock.<String>anyObject(), EasyMock.<RestLiAttachmentReader>anyObject());
EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
@Override
public Object answer() throws Throwable {
return new BaseTask<Long>() {
protected Promise<Long> run(final Context context) throws Exception {
return Promises.error(new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR));
}
};
}
});
checkInvocation(taskStatusResource, methodDescriptor, "POST", version, "/taskstatuses/?action=streamingAction", payload, null, new RequestExecutionCallback<RestResponse>() {
@Override
public void onError(Throwable e, RequestExecutionReport executionReport, RestLiAttachmentReader requestAttachmentReader, RestLiResponseAttachments responseAttachments) {
}
@Override
public void onSuccess(RestResponse result, RequestExecutionReport executionReport, RestLiResponseAttachments responseAttachments) {
Assert.fail("Request passed unexpectedly.");
}
}, false, false, new RestLiAttachmentReader(null), new RestLiResponseAttachments.Builder().build());
}
use of com.linkedin.restli.server.RestLiResponseAttachments in project rest.li by linkedin.
the class TestRestLiMethodInvocation method testInvokerWithFilters.
@Test(dataProvider = "provideFilterConfig")
public void testInvokerWithFilters(final boolean throwExceptionFromFirstFilter) throws Exception {
RestLiArgumentBuilder mockBuilder = createMock(RestLiArgumentBuilder.class);
Filter mockFilter = createMock(Filter.class);
@SuppressWarnings("unchecked") RequestExecutionCallback<Object> mockCallback = createMock(RequestExecutionCallback.class);
FilterRequestContextInternal mockFilterContext = createMock(FilterRequestContextInternal.class);
RestLiRequestData requestData = new RestLiRequestDataImpl.Builder().key("Key").build();
RestLiMethodInvoker invokerWithFilters = new RestLiMethodInvoker(_resourceFactory, _engine, new ErrorResponseBuilder());
Map<String, ResourceModel> resourceModelMap = buildResourceModels(StatusCollectionResource.class, LocationResource.class, DiscoveredItemsResource.class);
ResourceModel statusResourceModel = resourceModelMap.get("/statuses");
ResourceMethodDescriptor resourceMethodDescriptor = statusResourceModel.findMethod(ResourceMethod.GET);
final StatusCollectionResource resource = getMockResource(StatusCollectionResource.class);
RestRequestBuilder builder = new RestRequestBuilder(new URI("/statuses/1")).setMethod("GET").addHeaderValue("Accept", "application/json").setHeader(RestConstants.HEADER_RESTLI_PROTOCOL_VERSION, AllProtocolVersions.LATEST_PROTOCOL_VERSION.toString());
RestRequest request = builder.build();
RoutingResult routingResult = new RoutingResult(new ResourceContextImpl(buildPathKeys("statusID", 1L), request, new RequestContext()), resourceMethodDescriptor);
mockFilterContext.setRequestData(requestData);
expectLastCall();
expect(mockBuilder.extractRequestData(routingResult, request)).andReturn(requestData);
FilterChainCallback filterChainCallback = new FilterChainCallback() {
@Override
public void onRequestSuccess(RestLiRequestData requestData, RestLiCallback<Object> restLiCallback) {
// only invoke if filter chain's requests were successful
invokerWithFilters.invoke(requestData, routingResult, mockBuilder, restLiCallback, null);
}
@Override
public void onResponseSuccess(RestLiResponseData responseData, RestLiResponseAttachments responseAttachments) {
// unused
}
@Override
public void onError(Throwable th, RestLiResponseData responseData, RestLiResponseAttachments responseAttachments) {
// unused
}
};
final Exception exFromFilter = new RuntimeException("Exception from filter!");
if (throwExceptionFromFirstFilter) {
mockFilter.onRequest(eq(mockFilterContext));
expectLastCall().andThrow(exFromFilter);
mockCallback.onError(eq(exFromFilter), anyObject(RequestExecutionReport.class), EasyMock.isNull(RestLiAttachmentReader.class), EasyMock.isNull(RestLiResponseAttachments.class));
} else {
expect(mockFilterContext.getRequestData()).andReturn(requestData).times(3);
mockFilter.onRequest(eq(mockFilterContext));
expectLastCall().andAnswer(new IAnswer<Object>() {
@Override
public Object answer() throws Throwable {
FilterRequestContext filterContext = (FilterRequestContext) getCurrentArguments()[0];
RestLiRequestData data = filterContext.getRequestData();
// Verify incoming data.
assertEquals(data.getKey(), "Key");
// Update data.
data.setKey("Key-Filter1");
return CompletableFuture.completedFuture(null);
}
}).andAnswer(new IAnswer<Object>() {
@Override
public Object answer() throws Throwable {
FilterRequestContext filterContext = (FilterRequestContext) getCurrentArguments()[0];
RestLiRequestData data = filterContext.getRequestData();
// Verify incoming data.
assertEquals(data.getKey(), "Key-Filter1");
// Update data.
data.setKey("Key-Filter2");
return CompletableFuture.completedFuture(null);
}
});
Long[] argsArray = { 1L };
expect(mockBuilder.buildArguments(requestData, routingResult)).andReturn(argsArray);
expect(resource.get(eq(1L))).andReturn(null).once();
mockCallback.onSuccess(eq(null), anyObject(RequestExecutionReport.class), anyObject(RestLiResponseAttachments.class));
}
replay(resource, mockBuilder, mockFilterContext, mockFilter, mockCallback);
RestUtils.validateRequestHeadersAndUpdateResourceContext(request.getHeaders(), (ServerResourceContext) routingResult.getContext());
mockFilterContext.setRequestData(mockBuilder.extractRequestData(routingResult, request));
RestLiFilterChain filterChain = new RestLiFilterChain(Arrays.asList(mockFilter, mockFilter), filterChainCallback);
filterChain.onRequest(mockFilterContext, new RestLiFilterResponseContextFactory<Object>(request, routingResult, new RestLiResponseHandler.Builder().build()));
verify(mockBuilder, mockFilterContext, mockFilter);
if (throwExceptionFromFirstFilter) {
assertEquals(requestData.getKey(), "Key");
} else {
assertEquals(requestData.getKey(), "Key-Filter2");
verify(resource);
}
EasyMock.reset(resource);
EasyMock.makeThreadSafe(resource, true);
}
use of com.linkedin.restli.server.RestLiResponseAttachments in project rest.li by linkedin.
the class TestRestLiCallback method testOnErrorWithFiltersSuccessfulyHandlingAppEx.
@SuppressWarnings("unchecked")
@Test
public void testOnErrorWithFiltersSuccessfulyHandlingAppEx() 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 RecordTemplate entityFromFilter = Foo.createFoo("Key", "Two");
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();
ArgumentCaptor<RestLiServiceException> exCapture = ArgumentCaptor.forClass(RestLiServiceException.class);
when(_requestExecutionReportBuilder.build()).thenReturn(executionReport);
when(_responseHandler.buildExceptionResponseData(eq(_restRequest), eq(_routingResult), exCapture.capture(), 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 CompletableFuture.completedFuture(null);
}
}).when(_filter).onError(any(Throwable.class), eq(_filterRequestContext), any(FilterResponseContext.class));
doAnswer(new Answer<Object>() {
// Mock the behavior of the second filter.
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
FilterRequestContext requestContext = (FilterRequestContext) args[0];
FilterResponseContext responseContext = (FilterResponseContext) args[1];
// 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().getRecordResponseEnvelope().setRecord(entityFromFilter, HttpStatus.S_403_FORBIDDEN);
responseContext.getResponseData().getHeaders().putAll(headersFromFilter);
return CompletableFuture.completedFuture(null);
}
}).when(_filter).onResponse(eq(_filterRequestContext), any(FilterResponseContext.class));
RestResponse restResponse = new RestResponseBuilder().build();
when(_responseHandler.buildResponse(_routingResult, partialResponse)).thenReturn(restResponse);
// 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());
assertEquals(entityFromFilter, responseData.getRecordResponseEnvelope().getRecord());
assertEquals(headersFromFilter, responseData.getHeaders());
verify(_responseHandler).buildExceptionResponseData(eq(_restRequest), eq(_routingResult), exCapture.capture(), anyMap(), anyList());
verify(_responseHandler).buildPartialResponse(_routingResult, responseData);
verify(_responseHandler).buildResponse(_routingResult, partialResponse);
verify(_callback).onSuccess(restResponse, executionReport, responseAttachments);
verify(_restRequest, times(1)).getHeaders();
verifyZeroInteractions(_routingResult);
verifyNoMoreInteractions(_restRequest, _responseHandler, _callback);
RestLiServiceException restliEx = exCapture.getValue();
assertNotNull(restliEx);
assertEquals(HttpStatus.S_500_INTERNAL_SERVER_ERROR, restliEx.getStatus());
assertEquals(exFromApp.getMessage(), restliEx.getMessage());
assertEquals(exFromApp, restliEx.getCause());
}
Aggregations