Search in sources :

Example 61 with RestResponse

use of com.linkedin.r2.message.rest.RestResponse 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());
}
Also used : EmptyRecord(com.linkedin.restli.common.EmptyRecord) RestLiServiceException(com.linkedin.restli.server.RestLiServiceException) RecordTemplate(com.linkedin.data.template.RecordTemplate) FilterRequestContext(com.linkedin.restli.server.filter.FilterRequestContext) RestLiResponseAttachments(com.linkedin.restli.server.RestLiResponseAttachments) RequestExecutionReportBuilder(com.linkedin.restli.server.RequestExecutionReportBuilder) RestResponse(com.linkedin.r2.message.rest.RestResponse) RestResponseBuilder(com.linkedin.r2.message.rest.RestResponseBuilder) RequestExecutionReport(com.linkedin.restli.server.RequestExecutionReport) RestLiServiceException(com.linkedin.restli.server.RestLiServiceException) RoutingException(com.linkedin.restli.server.RoutingException) RestException(com.linkedin.r2.message.rest.RestException) FilterResponseContext(com.linkedin.restli.server.filter.FilterResponseContext) InvocationOnMock(org.mockito.invocation.InvocationOnMock) Test(org.testng.annotations.Test) BeforeTest(org.testng.annotations.BeforeTest)

Example 62 with RestResponse

use of com.linkedin.r2.message.rest.RestResponse in project rest.li by linkedin.

the class TestRestLiCallback method testOnSuccessWithFiltersExceptionFromFirstFilterSecondFilterHandlesEx.

@SuppressWarnings("unchecked")
@Test
public void testOnSuccessWithFiltersExceptionFromFirstFilterSecondFilterHandlesEx() throws Exception {
    // App stuff.
    final RecordTemplate entityFromApp = Foo.createFoo("Key", "One");
    RequestExecutionReport executionReport = new RequestExecutionReportBuilder().build();
    RestLiResponseAttachments responseAttachments = new RestLiResponseAttachments.Builder().build();
    RestLiResponseDataImpl appResponseData = new RestLiResponseDataImpl(HttpStatus.S_200_OK, Collections.<String, String>emptyMap(), Collections.<HttpCookie>emptyList());
    appResponseData.setResponseEnvelope(new CreateResponseEnvelope(entityFromApp, appResponseData));
    // Filter stuff.
    final Map<String, String> errorHeaders = buildErrorHeaders();
    ArgumentCaptor<RestLiServiceException> exFromFilterCapture = ArgumentCaptor.forClass(RestLiServiceException.class);
    final Map<String, String> headersFromFilter = Maps.newHashMap();
    headersFromFilter.put("Key", "Error from filter");
    final RestLiServiceException exceptionFromFilter = new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR);
    RestLiResponseDataImpl responseErrorData = new RestLiResponseDataImpl(exceptionFromFilter, headersFromFilter, Collections.<HttpCookie>emptyList());
    responseErrorData.setResponseEnvelope(new CreateResponseEnvelope(new EmptyRecord(), responseErrorData));
    final RecordTemplate entityFromFilter = Foo.createFoo("Key", "Two");
    PartialRestResponse partialFilterErrorResponse = new PartialRestResponse.Builder().build();
    final Exception exFromFilter = new RuntimeException("Exception From Filter");
    // Common stuff.
    RestResponse restResponse = new RestResponseBuilder().build();
    // Setup.
    when(_requestExecutionReportBuilder.build()).thenReturn(executionReport);
    when(_responseHandler.buildRestLiResponseData(_restRequest, _routingResult, entityFromApp)).thenReturn(appResponseData);
    when(_restRequest.getHeaders()).thenReturn(null);
    when(_responseHandler.buildPartialResponse(_routingResult, appResponseData)).thenReturn(partialFilterErrorResponse);
    when(_responseHandler.buildResponse(eq(_routingResult), any(PartialRestResponse.class))).thenReturn(restResponse);
    // Mock filter behavior.
    doThrow(exFromFilter).when(_filter).onResponse(eq(_filterRequestContext), any(FilterResponseContext.class));
    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];
            // The second filter should be invoked with details of the exception thrown by the first
            // filter.
            assertEquals(responseContext.getResponseData().getStatus(), HttpStatus.S_500_INTERNAL_SERVER_ERROR);
            assertNull(responseContext.getResponseData().getRecordResponseEnvelope().getRecord());
            assertEquals(responseContext.getResponseData().getHeaders(), errorHeaders);
            assertEquals(responseContext.getResponseData().getServiceException().getStatus(), HttpStatus.S_500_INTERNAL_SERVER_ERROR);
            // Modify data.
            setStatus(responseContext, HttpStatus.S_402_PAYMENT_REQUIRED);
            // The second filter handles the exception thrown by the first filter (i.e.) sets an entity
            // response in the response data.
            responseContext.getResponseData().getRecordResponseEnvelope().setRecord(entityFromFilter, HttpStatus.S_402_PAYMENT_REQUIRED);
            responseContext.getResponseData().getHeaders().put("error-fixed", "second-filter");
            return CompletableFuture.completedFuture(null);
        }
    }).when(_filter).onError(any(Throwable.class), eq(_filterRequestContext), any(FilterResponseContext.class));
    // 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.onSuccess(entityFromApp, executionReport, responseAttachments);
    // Verify.
    verify(_responseHandler).buildRestLiResponseData(_restRequest, _routingResult, entityFromApp);
    verify(_responseHandler).buildPartialResponse(_routingResult, appResponseData);
    verify(_responseHandler).buildResponse(eq(_routingResult), any(PartialRestResponse.class));
    verify(_callback).onSuccess(restResponse, executionReport, responseAttachments);
    Map<String, String> expectedHeaders = Maps.newHashMap();
    expectedHeaders.put("X-RestLi-Protocol-Version", "1.0.0");
    expectedHeaders.put("error-fixed", "second-filter");
    verifyZeroInteractions(_routingResult);
    verifyNoMoreInteractions(_responseHandler, _callback);
    assertFalse(appResponseData.isErrorResponse());
    assertEquals(appResponseData.getRecordResponseEnvelope().getRecord(), entityFromFilter);
    assertNotNull(appResponseData);
    assertEquals(HttpStatus.S_402_PAYMENT_REQUIRED, appResponseData.getStatus());
    assertEquals(appResponseData.getHeaders(), expectedHeaders);
    assertNull(appResponseData.getServiceException());
}
Also used : EmptyRecord(com.linkedin.restli.common.EmptyRecord) RestLiServiceException(com.linkedin.restli.server.RestLiServiceException) RecordTemplate(com.linkedin.data.template.RecordTemplate) FilterRequestContext(com.linkedin.restli.server.filter.FilterRequestContext) RestLiResponseAttachments(com.linkedin.restli.server.RestLiResponseAttachments) RequestExecutionReportBuilder(com.linkedin.restli.server.RequestExecutionReportBuilder) RestResponse(com.linkedin.r2.message.rest.RestResponse) RestResponseBuilder(com.linkedin.r2.message.rest.RestResponseBuilder) RequestExecutionReport(com.linkedin.restli.server.RequestExecutionReport) RestLiServiceException(com.linkedin.restli.server.RestLiServiceException) RoutingException(com.linkedin.restli.server.RoutingException) RestException(com.linkedin.r2.message.rest.RestException) FilterResponseContext(com.linkedin.restli.server.filter.FilterResponseContext) InvocationOnMock(org.mockito.invocation.InvocationOnMock) Test(org.testng.annotations.Test) BeforeTest(org.testng.annotations.BeforeTest)

Example 63 with RestResponse

use of com.linkedin.r2.message.rest.RestResponse in project rest.li by linkedin.

the class TestRestLiCallback method testOnErrorWithFiltersExceptionFromFirstFilterSecondFilterHandles.

@SuppressWarnings("unchecked")
@Test(dataProvider = "provideResponseEntities")
public void testOnErrorWithFiltersExceptionFromFirstFilterSecondFilterHandles(final ResourceMethod resourceMethod, final Object entityFromFilter2) throws Exception {
    // App stuff.
    RestLiServiceException exFromApp = new RestLiServiceException(HttpStatus.S_404_NOT_FOUND, "App failure");
    RequestExecutionReport executionReport = new RequestExecutionReportBuilder().build();
    RestLiResponseAttachments responseAttachments = new RestLiResponseAttachments.Builder().build();
    RestLiServiceException appException = new RestLiServiceException(HttpStatus.S_404_NOT_FOUND);
    RestLiResponseDataImpl responseAppData = new RestLiResponseDataImpl(appException, Collections.<String, String>emptyMap(), Collections.<HttpCookie>emptyList());
    RestLiResponseEnvelope responseAppEnvelope = EnvelopeBuilderUtil.buildBlankResponseEnvelope(resourceMethod, responseAppData);
    responseAppData.setResponseEnvelope(responseAppEnvelope);
    // Filter stuff.
    final Exception exFromFirstFilter = new RuntimeException("Runtime exception from first filter");
    RestLiServiceException filterException = new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR);
    final Map<String, String> headersFromFilter = Maps.newHashMap();
    headersFromFilter.put(RestConstants.HEADER_RESTLI_PROTOCOL_VERSION, AllProtocolVersions.LATEST_PROTOCOL_VERSION.toString());
    String errorResponseHeaderName = HeaderUtil.getErrorResponseHeaderName(AllProtocolVersions.LATEST_PROTOCOL_VERSION);
    headersFromFilter.put(errorResponseHeaderName, RestConstants.HEADER_VALUE_ERROR);
    RestLiResponseDataImpl responseFilterData = new RestLiResponseDataImpl(filterException, headersFromFilter, Collections.<HttpCookie>emptyList());
    RestLiResponseEnvelope responseFilterEnvelope = EnvelopeBuilderUtil.buildBlankResponseEnvelope(resourceMethod, responseFilterData);
    responseFilterData.setResponseEnvelope(responseFilterEnvelope);
    PartialRestResponse partialResponse = new PartialRestResponse.Builder().build();
    ArgumentCaptor<RestLiServiceException> wrappedExCapture = ArgumentCaptor.forClass(RestLiServiceException.class);
    RestResponse restResponse = new RestResponseBuilder().build();
    final String customHeader = "Custom-Header";
    final String customHeaderValue = "CustomValue";
    // Setup.
    when(_requestExecutionReportBuilder.build()).thenReturn(executionReport);
    when(_responseHandler.buildExceptionResponseData(eq(_restRequest), eq(_routingResult), wrappedExCapture.capture(), anyMap(), anyList())).thenReturn(responseAppData);
    when(_responseHandler.buildPartialResponse(_routingResult, responseAppData)).thenReturn(partialResponse);
    when(_responseHandler.buildResponse(_routingResult, partialResponse)).thenReturn(restResponse);
    when(_restRequest.getHeaders()).thenReturn(null);
    // Mock filter behavior.
    doAnswer(new Answer<Object>() {

        @Override
        public Object answer(InvocationOnMock invocation) throws Throwable {
            Object[] args = invocation.getArguments();
            FilterRequestContext requestContext = (FilterRequestContext) args[1];
            FilterResponseContext responseContext = (FilterResponseContext) args[2];
            ((RestLiResponseDataImpl) responseContext.getResponseData()).setException(exFromFirstFilter);
            responseContext.getResponseData().getHeaders().putAll(headersFromFilter);
            return completedFutureWithError(exFromFirstFilter);
        }
    }).doAnswer(new Answer<Object>() {

        @Override
        public Object answer(InvocationOnMock invocation) throws Throwable {
            Object[] args = invocation.getArguments();
            FilterRequestContext requestContext = (FilterRequestContext) args[1];
            FilterResponseContext responseContext = (FilterResponseContext) args[2];
            // The second filter should be invoked with details of the exception thrown by the first
            // filter. Verify incoming data.
            assertEquals(responseContext.getResponseData().getStatus(), HttpStatus.S_500_INTERNAL_SERVER_ERROR);
            switch(ResponseType.fromMethodType(resourceMethod)) {
                case SINGLE_ENTITY:
                    assertNull(responseContext.getResponseData().getRecordResponseEnvelope().getRecord());
                    break;
                case GET_COLLECTION:
                    assertNull(responseContext.getResponseData().getCollectionResponseEnvelope().getCollectionResponse());
                    break;
                case CREATE_COLLECTION:
                    assertNull(responseContext.getResponseData().getBatchCreateResponseEnvelope().getCreateResponses());
                    break;
                case BATCH_ENTITIES:
                    assertNull(responseContext.getResponseData().getBatchResponseEnvelope().getBatchResponseMap());
                    break;
                case STATUS_ONLY:
                    break;
            }
            assertEquals(responseContext.getResponseData().getHeaders(), headersFromFilter);
            assertTrue(responseContext.getResponseData().isErrorResponse());
            // Modify data.
            responseContext.getResponseData().getHeaders().put(customHeader, customHeaderValue);
            setStatus(responseContext, HttpStatus.S_402_PAYMENT_REQUIRED);
            // filter.
            if (entityFromFilter2 instanceof RecordTemplate) {
                responseContext.getResponseData().getRecordResponseEnvelope().setRecord((RecordTemplate) entityFromFilter2, HttpStatus.S_402_PAYMENT_REQUIRED);
            } else if (entityFromFilter2 instanceof List) {
                responseContext.getResponseData().getCollectionResponseEnvelope().setCollectionResponse((List<? extends RecordTemplate>) entityFromFilter2, new CollectionMetadata(), null, HttpStatus.S_402_PAYMENT_REQUIRED);
            } else {
                Map<Object, BatchResponseEnvelope.BatchResponseEntry> responseMap = new HashMap<Object, BatchResponseEnvelope.BatchResponseEntry>();
                for (Map.Entry<?, RecordTemplate> entry : ((Map<?, RecordTemplate>) entityFromFilter2).entrySet()) {
                    responseMap.put(entry.getKey(), new BatchResponseEnvelope.BatchResponseEntry(HttpStatus.S_200_OK, entry.getValue()));
                }
                responseContext.getResponseData().getBatchResponseEnvelope().setBatchResponseMap(responseMap, HttpStatus.S_402_PAYMENT_REQUIRED);
            }
            return CompletableFuture.completedFuture(null);
        }
    }).when(_filter).onError(any(Throwable.class), eq(_filterRequestContext), any(FilterResponseContext.class));
    // 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.
    verify(_responseHandler).buildExceptionResponseData(eq(_restRequest), eq(_routingResult), wrappedExCapture.capture(), anyMap(), anyList());
    verify(_responseHandler).buildPartialResponse(_routingResult, responseAppData);
    verify(_responseHandler).buildResponse(_routingResult, partialResponse);
    verify(_callback).onSuccess(restResponse, executionReport, responseAttachments);
    verify(_restRequest).getHeaders();
    verifyZeroInteractions(_routingResult);
    verifyNoMoreInteractions(_restRequest, _responseHandler, _callback);
    assertNotNull(responseAppData);
    assertEquals(HttpStatus.S_402_PAYMENT_REQUIRED, responseAppData.getStatus());
    // Only the error header should have been cleared.
    assertFalse(responseAppData.getHeaders().containsKey(errorResponseHeaderName));
    assertEquals(responseAppData.getHeaders().get(customHeader), customHeaderValue);
    if (entityFromFilter2 instanceof RecordTemplate) {
        assertTrue(responseAppData.getResponseType() == ResponseType.SINGLE_ENTITY);
        assertEquals(responseAppData.getRecordResponseEnvelope().getRecord(), entityFromFilter2);
    } else if (entityFromFilter2 instanceof List) {
        if (responseAppData.getResponseType() == ResponseType.GET_COLLECTION) {
            assertEquals(responseAppData.getCollectionResponseEnvelope().getCollectionResponse(), entityFromFilter2);
        } else {
            fail();
        }
    } else {
        assertTrue(responseAppData.getResponseType() == ResponseType.BATCH_ENTITIES);
        Map<Object, RecordTemplate> values = new HashMap<Object, RecordTemplate>();
        for (Map.Entry<?, BatchResponseEnvelope.BatchResponseEntry> entry : responseAppData.getBatchResponseEnvelope().getBatchResponseMap().entrySet()) {
            values.put(entry.getKey(), entry.getValue().getRecord());
        }
        assertEquals(values, entityFromFilter2);
    }
    assertFalse(responseAppData.isErrorResponse());
    RestLiServiceException restliEx = wrappedExCapture.getAllValues().get(0);
    assertNotNull(restliEx);
    assertEquals(exFromApp.getStatus(), restliEx.getStatus());
    assertEquals(exFromApp.getMessage(), restliEx.getMessage());
}
Also used : HashMap(java.util.HashMap) RestLiServiceException(com.linkedin.restli.server.RestLiServiceException) RecordTemplate(com.linkedin.data.template.RecordTemplate) List(java.util.List) ArrayList(java.util.ArrayList) Matchers.anyList(org.mockito.Matchers.anyList) FilterRequestContext(com.linkedin.restli.server.filter.FilterRequestContext) RestLiResponseAttachments(com.linkedin.restli.server.RestLiResponseAttachments) RequestExecutionReportBuilder(com.linkedin.restli.server.RequestExecutionReportBuilder) CollectionMetadata(com.linkedin.restli.common.CollectionMetadata) RestResponse(com.linkedin.r2.message.rest.RestResponse) RestResponseBuilder(com.linkedin.r2.message.rest.RestResponseBuilder) RequestExecutionReport(com.linkedin.restli.server.RequestExecutionReport) RestLiServiceException(com.linkedin.restli.server.RestLiServiceException) RoutingException(com.linkedin.restli.server.RoutingException) RestException(com.linkedin.r2.message.rest.RestException) Mockito.doAnswer(org.mockito.Mockito.doAnswer) Answer(org.mockito.stubbing.Answer) FilterResponseContext(com.linkedin.restli.server.filter.FilterResponseContext) InvocationOnMock(org.mockito.invocation.InvocationOnMock) Map(java.util.Map) Matchers.anyMap(org.mockito.Matchers.anyMap) HashMap(java.util.HashMap) DataMap(com.linkedin.data.DataMap) Test(org.testng.annotations.Test) BeforeTest(org.testng.annotations.BeforeTest)

Example 64 with RestResponse

use of com.linkedin.r2.message.rest.RestResponse in project rest.li by linkedin.

the class TestRestLiCallback method testOnSuccessWithFiltersSuccessful.

@Test
public void testOnSuccessWithFiltersSuccessful() throws Exception {
    String result = "foo";
    RequestExecutionReport executionReport = new RequestExecutionReportBuilder().build();
    final RestLiResponseAttachments restLiResponseAttachments = new RestLiResponseAttachments.Builder().build();
    final RecordTemplate entityFromApp = Foo.createFoo("Key", "One");
    final Map<String, String> headersFromApp = Maps.newHashMap();
    headersFromApp.put("Key", "Input");
    final RecordTemplate entityFromFilter1 = Foo.createFoo("Key", "Two");
    final RecordTemplate entityFromFilter2 = Foo.createFoo("Key", "Three");
    final Map<String, String> headersFromFilters = Maps.newHashMap();
    headersFromFilters.put("Key", "Output");
    RestLiResponseDataImpl appResponseData = new RestLiResponseDataImpl(HttpStatus.S_200_OK, headersFromApp, Collections.<HttpCookie>emptyList());
    appResponseData.setResponseEnvelope(new CreateResponseEnvelope(entityFromApp, appResponseData));
    PartialRestResponse partialResponse = new PartialRestResponse.Builder().build();
    // Setup.
    when(_requestExecutionReportBuilder.build()).thenReturn(executionReport);
    when(_responseHandler.buildRestLiResponseData(_restRequest, _routingResult, result)).thenReturn(appResponseData);
    when(_responseHandler.buildPartialResponse(_routingResult, appResponseData)).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();
            FilterRequestContext requestContext = (FilterRequestContext) args[0];
            FilterResponseContext responseContext = (FilterResponseContext) args[1];
            // Verify incoming data.
            assertEquals(HttpStatus.S_200_OK, responseContext.getResponseData().getStatus());
            assertEquals(headersFromApp, responseContext.getResponseData().getHeaders());
            assertEquals(entityFromApp, responseContext.getResponseData().getRecordResponseEnvelope().getRecord());
            // Modify data in filter.
            setStatus(responseContext, HttpStatus.S_400_BAD_REQUEST);
            responseContext.getResponseData().getRecordResponseEnvelope().setRecord(entityFromFilter1, HttpStatus.S_400_BAD_REQUEST);
            responseContext.getResponseData().getHeaders().clear();
            return CompletableFuture.completedFuture(null);
        }
    }).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());
            assertEquals(responseContext.getResponseData().getRecordResponseEnvelope().getRecord(), entityFromFilter1);
            // Modify data in filter.
            setStatus(responseContext, HttpStatus.S_403_FORBIDDEN);
            responseContext.getResponseData().getRecordResponseEnvelope().setRecord(entityFromFilter2, HttpStatus.S_403_FORBIDDEN);
            responseContext.getResponseData().getHeaders().putAll(headersFromFilters);
            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 with some response attachments.
    _twoFilterRestLiCallback.onSuccess(result, executionReport, restLiResponseAttachments);
    // Verify.
    assertNotNull(appResponseData);
    assertEquals(HttpStatus.S_403_FORBIDDEN, appResponseData.getStatus());
    assertEquals(entityFromFilter2, appResponseData.getRecordResponseEnvelope().getRecord());
    assertEquals(headersFromFilters, appResponseData.getHeaders());
    verify(_responseHandler).buildRestLiResponseData(_restRequest, _routingResult, result);
    verify(_responseHandler).buildPartialResponse(_routingResult, appResponseData);
    verify(_responseHandler).buildResponse(_routingResult, partialResponse);
    verify(_callback).onSuccess(restResponse, executionReport, restLiResponseAttachments);
    verifyZeroInteractions(_restRequest, _routingResult);
    verifyNoMoreInteractions(_responseHandler, _callback);
}
Also used : RequestExecutionReportBuilder(com.linkedin.restli.server.RequestExecutionReportBuilder) RestResponse(com.linkedin.r2.message.rest.RestResponse) RestResponseBuilder(com.linkedin.r2.message.rest.RestResponseBuilder) RequestExecutionReport(com.linkedin.restli.server.RequestExecutionReport) Mockito.doAnswer(org.mockito.Mockito.doAnswer) Answer(org.mockito.stubbing.Answer) FilterResponseContext(com.linkedin.restli.server.filter.FilterResponseContext) RecordTemplate(com.linkedin.data.template.RecordTemplate) InvocationOnMock(org.mockito.invocation.InvocationOnMock) FilterRequestContext(com.linkedin.restli.server.filter.FilterRequestContext) RestLiResponseAttachments(com.linkedin.restli.server.RestLiResponseAttachments) Test(org.testng.annotations.Test) BeforeTest(org.testng.annotations.BeforeTest)

Example 65 with RestResponse

use of com.linkedin.r2.message.rest.RestResponse in project rest.li by linkedin.

the class TestRestLiMethodInvocation method checkInvocation.

private void checkInvocation(Object resource, ResourceMethodDescriptor resourceMethodDescriptor, String httpMethod, ProtocolVersion version, String uri, String entityBody, MutablePathKeys pathkeys, final RequestExecutionCallback<RestResponse> callback, final boolean isDebugMode, final boolean expectRoutingException, final RestLiAttachmentReader expectedRequestAttachments, final RestLiResponseAttachments expectedResponseAttachments) throws URISyntaxException, RestLiSyntaxException {
    assertNotNull(resource);
    assertNotNull(resourceMethodDescriptor);
    try {
        EasyMock.replay(resource);
        RestRequestBuilder builder = new RestRequestBuilder(new URI(uri)).setMethod(httpMethod).addHeaderValue("Accept", "application/json").setHeader(RestConstants.HEADER_RESTLI_PROTOCOL_VERSION, version.toString());
        if (entityBody != null) {
            builder.setEntity(entityBody.getBytes(Data.UTF_8_CHARSET));
        }
        RestRequest request = builder.build();
        final ResourceContext resourceContext = new ResourceContextImpl(pathkeys, request, new RequestContext(), true, expectedRequestAttachments);
        resourceContext.setResponseAttachments(expectedResponseAttachments);
        RoutingResult routingResult = new RoutingResult(resourceContext, resourceMethodDescriptor);
        FilterRequestContextInternal filterContext = new FilterRequestContextInternalImpl((ServerResourceContext) routingResult.getContext(), resourceMethodDescriptor);
        final CountDownLatch latch = new CountDownLatch(1);
        final CountDownLatch expectedRoutingExceptionLatch = new CountDownLatch(1);
        RestLiArgumentBuilder adapter = _methodAdapterRegistry.getArgumentBuilder(resourceMethodDescriptor.getType());
        RestLiRequestData requestData = adapter.extractRequestData(routingResult, request);
        filterContext.setRequestData(requestData);
        RestLiResponseHandler restLiResponseHandler = new RestLiResponseHandler.Builder().build();
        RequestExecutionReportBuilder requestExecutionReportBuilder = null;
        if (isDebugMode) {
            requestExecutionReportBuilder = new RequestExecutionReportBuilder();
        }
        RequestExecutionCallback<RestResponse> executionCallback = new RequestExecutionCallback<RestResponse>() {

            @Override
            public void onError(Throwable e, RequestExecutionReport executionReport, RestLiAttachmentReader requestAttachmentReader, RestLiResponseAttachments responseAttachments) {
                if (isDebugMode) {
                    Assert.assertNotNull(executionReport);
                } else {
                    Assert.assertNull(executionReport);
                }
                if (e.getCause().getCause() instanceof RoutingException) {
                    expectedRoutingExceptionLatch.countDown();
                }
                if (callback != null) {
                    callback.onError(e, executionReport, null, null);
                }
                Assert.assertEquals(requestAttachmentReader, expectedRequestAttachments);
                Assert.assertEquals(responseAttachments, expectedResponseAttachments);
                latch.countDown();
            }

            @Override
            public void onSuccess(final RestResponse result, RequestExecutionReport executionReport, RestLiResponseAttachments responseAttachments) {
                if (isDebugMode) {
                    Assert.assertNotNull(executionReport);
                } else {
                    Assert.assertNull(executionReport);
                }
                if (callback != null) {
                    callback.onSuccess(result, executionReport, null);
                }
                Assert.assertEquals(responseAttachments, expectedResponseAttachments);
                latch.countDown();
            }
        };
        FilterChainCallback filterChainCallback = new FilterChainCallbackImpl(routingResult, _invoker, adapter, requestExecutionReportBuilder, expectedRequestAttachments, restLiResponseHandler, executionCallback);
        final RestLiCallback<Object> outerCallback = new RestLiCallback<Object>(filterContext, new RestLiFilterResponseContextFactory<Object>(request, routingResult, restLiResponseHandler), new RestLiFilterChain(null, filterChainCallback));
        RestUtils.validateRequestHeadersAndUpdateResourceContext(request.getHeaders(), (ServerResourceContext) routingResult.getContext());
        filterContext.setRequestData(adapter.extractRequestData(routingResult, request));
        _invoker.invoke(filterContext.getRequestData(), routingResult, adapter, outerCallback, requestExecutionReportBuilder);
        try {
            latch.await();
            if (expectRoutingException) {
                expectedRoutingExceptionLatch.await();
            }
        } catch (InterruptedException e) {
        // Ignore
        }
        EasyMock.verify(resource);
        Assert.assertEquals(((ServerResourceContext) routingResult.getContext()).getResponseMimeType(), "application/json");
    } catch (RestLiSyntaxException e) {
        throw new RoutingException("syntax exception", 400);
    } finally {
        EasyMock.reset(resource);
        EasyMock.makeThreadSafe(resource, true);
    }
}
Also used : FilterRequestContextInternalImpl(com.linkedin.restli.internal.server.filter.FilterRequestContextInternalImpl) RoutingException(com.linkedin.restli.server.RoutingException) ResourceContext(com.linkedin.restli.server.ResourceContext) ServerResourceContext(com.linkedin.restli.internal.server.ServerResourceContext) RestLiSyntaxException(com.linkedin.restli.internal.server.util.RestLiSyntaxException) URI(java.net.URI) RestLiFilterChain(com.linkedin.restli.internal.server.filter.RestLiFilterChain) RequestExecutionCallback(com.linkedin.restli.server.RequestExecutionCallback) RoutingResult(com.linkedin.restli.internal.server.RoutingResult) FilterChainCallback(com.linkedin.restli.internal.server.filter.FilterChainCallback) RestLiResponseHandler(com.linkedin.restli.internal.server.response.RestLiResponseHandler) FilterChainCallbackImpl(com.linkedin.restli.internal.server.filter.FilterChainCallbackImpl) RestLiCallback(com.linkedin.restli.internal.server.RestLiCallback) FilterRequestContext(com.linkedin.restli.server.filter.FilterRequestContext) RequestContext(com.linkedin.r2.message.RequestContext) ResourceContextImpl(com.linkedin.restli.internal.server.ResourceContextImpl) RestLiResponseAttachments(com.linkedin.restli.server.RestLiResponseAttachments) RequestExecutionReportBuilder(com.linkedin.restli.server.RequestExecutionReportBuilder) RestResponse(com.linkedin.r2.message.rest.RestResponse) RestLiArgumentBuilder(com.linkedin.restli.internal.server.methods.arguments.RestLiArgumentBuilder) CountDownLatch(java.util.concurrent.CountDownLatch) RequestExecutionReport(com.linkedin.restli.server.RequestExecutionReport) RestRequest(com.linkedin.r2.message.rest.RestRequest) FilterRequestContextInternal(com.linkedin.restli.internal.server.filter.FilterRequestContextInternal) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) EasyMock.anyObject(org.easymock.EasyMock.anyObject) RestLiAttachmentReader(com.linkedin.restli.common.attachments.RestLiAttachmentReader) RestLiRequestData(com.linkedin.restli.server.RestLiRequestData)

Aggregations

RestResponse (com.linkedin.r2.message.rest.RestResponse)231 Test (org.testng.annotations.Test)174 RestRequest (com.linkedin.r2.message.rest.RestRequest)147 RequestContext (com.linkedin.r2.message.RequestContext)108 RestRequestBuilder (com.linkedin.r2.message.rest.RestRequestBuilder)100 URI (java.net.URI)74 RestException (com.linkedin.r2.message.rest.RestException)68 RestResponseBuilder (com.linkedin.r2.message.rest.RestResponseBuilder)55 ByteString (com.linkedin.data.ByteString)50 FutureCallback (com.linkedin.common.callback.FutureCallback)45 Callback (com.linkedin.common.callback.Callback)43 HashMap (java.util.HashMap)41 ExecutionException (java.util.concurrent.ExecutionException)40 Map (java.util.Map)38 StreamResponse (com.linkedin.r2.message.stream.StreamResponse)35 StreamRequest (com.linkedin.r2.message.stream.StreamRequest)29 URISyntaxException (java.net.URISyntaxException)27 FilterRequestContext (com.linkedin.restli.server.filter.FilterRequestContext)24 FilterChain (com.linkedin.r2.filter.FilterChain)23 BeforeTest (org.testng.annotations.BeforeTest)23