Search in sources :

Example 51 with RestResponseBuilder

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

the class ResponseUtils method buildResponse.

public static RestResponse buildResponse(RoutingResult routingResult, RestLiResponse restLiResponse) {
    RestResponseBuilder builder = new RestResponseBuilder().setHeaders(restLiResponse.getHeaders()).setCookies(CookieUtil.encodeSetCookies(restLiResponse.getCookies())).setStatus(restLiResponse.getStatus().getCode());
    ServerResourceContext context = routingResult.getContext();
    ResourceEntityType resourceEntityType = routingResult.getResourceMethod().getResourceModel().getResourceEntityType();
    if (restLiResponse.hasData() && ResourceEntityType.STRUCTURED_DATA == resourceEntityType) {
        DataMap dataMap = restLiResponse.getDataMap();
        String mimeType = context.getResponseMimeType();
        URI requestUri = context.getRequestURI();
        Map<String, String> requestHeaders = context.getRequestHeaders();
        builder = encodeResult(mimeType, requestUri, requestHeaders, builder, dataMap);
    }
    return builder.build();
}
Also used : ResourceEntityType(com.linkedin.restli.restspec.ResourceEntityType) ServerResourceContext(com.linkedin.restli.internal.server.ServerResourceContext) RestResponseBuilder(com.linkedin.r2.message.rest.RestResponseBuilder) ByteString(com.linkedin.data.ByteString) URI(java.net.URI) DataMap(com.linkedin.data.DataMap)

Example 52 with RestResponseBuilder

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

the class TestMultiplexedRequestHandlerImpl method testResponseCookiesAggregated.

@Test(dataProvider = "multiplexerConfigurations")
public void testResponseCookiesAggregated(MultiplexerRunMode multiplexerRunMode) throws Exception {
    // Per security review: We should not make cookies for each individual responses visible to the client (especially if the cookie is HttpOnly).
    // Therefore all cookies returned by individual responses will be aggregated at the envelope response level.
    // Create a mockHandler. Make it return different cookies based on the request
    SynchronousRequestHandler mockHandler = new SynchronousRequestHandler() {

        @Override
        public RestResponse handleRequestSync(RestRequest request, RequestContext requestContext) {
            try {
                URI uri = request.getURI();
                RestResponseBuilder restResponseBuilder = new RestResponseBuilder();
                restResponseBuilder.setStatus(HttpStatus.S_200_OK.getCode());
                restResponseBuilder.setEntity(jsonBodyToByteString(fakeIndividualBody("don't care")));
                List<HttpCookie> cookies = new ArrayList<>();
                if (uri.getPath().contains("req1")) {
                    HttpCookie cookie = new HttpCookie("cookie1", "cookie1Value");
                    cookie.setDomain(".www.linkedin.com");
                    cookie.setSecure(false);
                    cookies.add(cookie);
                    HttpCookie commonCookie = new HttpCookie("commonCookie", "commonCookieValue");
                    commonCookie.setDomain(".WWW.linkedin.com");
                    commonCookie.setPath("/foo");
                    commonCookie.setSecure(false);
                    cookies.add(commonCookie);
                } else if (uri.getPath().contains("req2")) {
                    HttpCookie cookie = new HttpCookie("cookie2", "cookie2Value");
                    cookie.setDomain("www.linkedin.com");
                    cookie.setSecure(false);
                    cookies.add(cookie);
                    cookie = new HttpCookie("cookie3", "cookie3Value");
                    cookies.add(cookie);
                    HttpCookie commonCookie = new HttpCookie("commonCookie", "commonCookieValue");
                    commonCookie.setDomain(".www.linkedin.com");
                    commonCookie.setPath("/foo");
                    commonCookie.setSecure(true);
                    cookies.add(commonCookie);
                } else {
                    HttpCookie cookie = new HttpCookie("cookie2", "newCookie2Value");
                    cookie.setDomain("www.linkedin.com");
                    cookie.setSecure(true);
                    cookies.add(cookie);
                }
                return restResponseBuilder.setCookies(CookieUtil.encodeSetCookies(cookies)).build();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    };
    // Prepare request to mux handler
    FutureCallback<RestResponse> callback = new FutureCallback<>();
    RequestContext requestContext = new RequestContext();
    Map<String, IndividualRequest> individualRequests = ImmutableMap.of("0", fakeIndRequest("/req1"), "1", fakeIndRequest("/req2", ImmutableMap.of("2", fakeIndRequest("/req3"))));
    // Create mux handler instance
    MultiplexedRequestHandlerImpl multiplexer = createMultiplexer(mockHandler, null, Collections.<String>emptySet(), 3, multiplexerRunMode);
    try {
        multiplexer.handleRequest(fakeMuxRestRequest(individualRequests), requestContext, callback);
    } catch (Exception e) {
        fail("Multiplexer should not throw exception", e);
    }
    RestResponse muxRestResponse = callback.get();
    // assert multiplexed request should return a 200 status code
    assertEquals(muxRestResponse.getStatus(), 200, "Multiplexer should return 200");
    MultiplexedResponseContent muxResponseContent = new MultiplexedResponseContent(DataMapConverter.bytesToDataMap(muxRestResponse.getHeaders(), muxRestResponse.getEntity()));
    // individual response should not have set-cookie headers
    IndividualResponseMap responses = muxResponseContent.getResponses();
    for (IndividualResponse res : responses.values()) {
        for (String headerName : res.getHeaders().keySet()) {
            assertTrue(headerName.equalsIgnoreCase("set-cookie"), "Individual response header should not container set-cookie header: " + responses.toString());
        }
    }
    // Ensure cookies are aggregated at envelope level
    List<HttpCookie> cookies = CookieUtil.decodeSetCookies(muxRestResponse.getCookies());
    assertEquals(cookies.size(), 4);
    for (HttpCookie cookie : cookies) {
        if ("cookie1".equals(cookie.getName())) {
            assertEquals(cookie.getValue(), "cookie1Value");
            assertEquals(cookie.getDomain(), ".www.linkedin.com");
            assertEquals(cookie.getSecure(), false);
        } else if ("cookie2".equals(cookie.getName())) {
            assertEquals(cookie.getValue(), "newCookie2Value");
            assertEquals(cookie.getDomain(), "www.linkedin.com");
            assertEquals(cookie.getSecure(), true);
        } else if ("cookie3".equals(cookie.getName())) {
            assertEquals(cookie.getValue(), "cookie3Value");
        } else if ("commonCookie".equals(cookie.getName())) {
            assertEquals(cookie.getValue(), "commonCookieValue");
            assertEquals(cookie.getDomain().toLowerCase(), ".www.linkedin.com");
            assertEquals(cookie.getPath(), "/foo");
        // Since request0 and request1 are executed in parallel, depending on which request is completed first,
        // we don't know what will be its final 'secure' attribute value.
        } else {
            fail("Unknown cookie name: " + cookie.getName());
        }
    }
}
Also used : MultiplexedResponseContent(com.linkedin.restli.common.multiplexer.MultiplexedResponseContent) RestResponse(com.linkedin.r2.message.rest.RestResponse) RestResponseBuilder(com.linkedin.r2.message.rest.RestResponseBuilder) ArrayList(java.util.ArrayList) ByteString(com.linkedin.data.ByteString) URI(java.net.URI) IndividualResponse(com.linkedin.restli.common.multiplexer.IndividualResponse) URISyntaxException(java.net.URISyntaxException) RestLiServiceException(com.linkedin.restli.server.RestLiServiceException) RestException(com.linkedin.r2.message.rest.RestException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) IndividualRequest(com.linkedin.restli.common.multiplexer.IndividualRequest) RestRequest(com.linkedin.r2.message.rest.RestRequest) RequestContext(com.linkedin.r2.message.RequestContext) HttpCookie(java.net.HttpCookie) IndividualResponseMap(com.linkedin.restli.common.multiplexer.IndividualResponseMap) FutureCallback(com.linkedin.common.callback.FutureCallback) Test(org.testng.annotations.Test)

Example 53 with RestResponseBuilder

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

the class TestRestLiServer method testRequestHandlers.

@Test(dataProvider = "requestHandlersData")
public void testRequestHandlers(URI uri, String expectedResponse) {
    RestLiConfig config = new RestLiConfig();
    config.addResourcePackageNames("com.linkedin.restli.server.twitter");
    config.setDocumentationRequestHandler(new DefaultDocumentationRequestHandler() {

        @Override
        public void initialize(RestLiConfig config, Map<String, ResourceModel> rootResources) {
        /* no-op */
        }

        @Override
        public void handleRequest(RestRequest req, RequestContext ctx, Callback<RestResponse> cb) {
            cb.onSuccess(new RestResponseBuilder().setEntity(toByteString(DOCUMENTATION_RESPONSE)).build());
        }
    });
    config.addCustomRequestHandlers(new CustomRequestHandler());
    config.addDebugRequestHandlers(new DebugRequestHandler("a", DEBUG_HANDLER_RESPONSE_A), new DebugRequestHandler("b", DEBUG_HANDLER_RESPONSE_B));
    RestLiServer server = new RestLiServer(config, new EasyMockResourceFactory(), createMock(Engine.class));
    RestRequest restReq = new RestRequestBuilder(uri).build();
    server.handleRequest(restReq, createMock(RequestContext.class), new RestResponseAssertionCallback(expectedResponse));
    StreamRequest streamReq = new StreamRequestBuilder(uri).build(EntityStreams.emptyStream());
    server.handleRequest(streamReq, createMock(RequestContext.class), new StreamResponseAssertionCallback(expectedResponse));
}
Also used : RestResponse(com.linkedin.r2.message.rest.RestResponse) DefaultDocumentationRequestHandler(com.linkedin.restli.docgen.DefaultDocumentationRequestHandler) RestResponseBuilder(com.linkedin.r2.message.rest.RestResponseBuilder) ByteString(com.linkedin.data.ByteString) StreamRequestBuilder(com.linkedin.r2.message.stream.StreamRequestBuilder) EasyMockResourceFactory(com.linkedin.restli.server.test.EasyMockResourceFactory) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) RestRequest(com.linkedin.r2.message.rest.RestRequest) ResourceModel(com.linkedin.restli.internal.server.model.ResourceModel) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) FilterRequestContext(com.linkedin.restli.server.filter.FilterRequestContext) RequestContext(com.linkedin.r2.message.RequestContext) Engine(com.linkedin.parseq.Engine) Test(org.testng.annotations.Test) AfterTest(org.testng.annotations.AfterTest) BeforeTest(org.testng.annotations.BeforeTest)

Example 54 with RestResponseBuilder

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

the class TestRestLiCallback method testOnSuccessBuildPartialResponseFailure.

@Test
@SuppressWarnings("unchecked")
public void testOnSuccessBuildPartialResponseFailure() throws Exception {
    String result = "foo";
    RestLiResponseData<UpdateResponseEnvelope> responseData = ResponseDataBuilderUtil.buildUpdateResponseData(HttpStatus.S_200_OK);
    RestResponse restResponse = new RestResponseBuilder().build();
    // Set up.
    when((RestLiResponseData<UpdateResponseEnvelope>) _responseHandler.buildRestLiResponseData(_restRequest, _routingResult, result)).thenReturn(responseData);
    Exception e = new RuntimeException("Error1");
    when(_responseHandler.buildPartialResponse(_routingResult, responseData)).thenThrow(e);
    // Invoke.
    _noFilterRestLiCallback.onSuccess(result);
    // Verify.
    verify(_responseHandler).buildPartialResponse(_routingResult, responseData);
    verify(_responseHandler).buildRestLiResponseData(_restRequest, _routingResult, result);
    ArgumentCaptor<RestLiResponseException> partialRestResponseExceptionCaptor = ArgumentCaptor.forClass(RestLiResponseException.class);
    verify(_callback).onError(partialRestResponseExceptionCaptor.capture());
    verifyZeroInteractions(_restRequest);
    verifyNoMoreInteractions(_responseHandler, _callback);
    RestLiResponse restLiResponse = partialRestResponseExceptionCaptor.getValue().getRestLiResponse();
    assertEquals(restLiResponse.getStatus(), HttpStatus.S_500_INTERNAL_SERVER_ERROR);
    assertEquals(RestConstants.HEADER_VALUE_ERROR, restLiResponse.getHeader(HeaderUtil.getErrorResponseHeaderName(Collections.emptyMap())));
}
Also used : RestResponse(com.linkedin.r2.message.rest.RestResponse) RestResponseBuilder(com.linkedin.r2.message.rest.RestResponseBuilder) RestLiResponseData(com.linkedin.restli.server.RestLiResponseData) RestLiServiceException(com.linkedin.restli.server.RestLiServiceException) RoutingException(com.linkedin.restli.server.RoutingException) RestException(com.linkedin.r2.message.rest.RestException) Test(org.testng.annotations.Test) BeforeTest(org.testng.annotations.BeforeTest)

Example 55 with RestResponseBuilder

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

the class TestRestLiSymbolTableProvider method testGetRemoteRequestSymbolTableFetchNon404Error.

@Test
public void testGetRemoteRequestSymbolTableFetchNon404Error() {
    AtomicInteger networkCallCount = new AtomicInteger(0);
    RestResponseBuilder builder = new RestResponseBuilder();
    builder.setStatus(500);
    when(_client.restRequest(eq(new RestRequestBuilder(URI.create("d2://serviceName/symbolTable")).setHeaders(Collections.singletonMap(RestConstants.HEADER_FETCH_SYMBOL_TABLE, Boolean.TRUE.toString())).build()))).thenAnswer(invocation -> {
        networkCallCount.incrementAndGet();
        return CompletableFuture.completedFuture(builder.build());
    });
    // First fetch should trigger a network request.
    Assert.assertNull(_provider.getRequestSymbolTable(URI.create("d2://serviceName")));
    Assert.assertEquals(networkCallCount.get(), 1);
    // Subsequent fetch should also trigger a network request because response should not have been cached.
    Assert.assertNull(_provider.getRequestSymbolTable(URI.create("d2://serviceName")));
    Assert.assertEquals(networkCallCount.get(), 2);
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) RestResponseBuilder(com.linkedin.r2.message.rest.RestResponseBuilder) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) Test(org.testng.annotations.Test)

Aggregations

RestResponseBuilder (com.linkedin.r2.message.rest.RestResponseBuilder)87 RestResponse (com.linkedin.r2.message.rest.RestResponse)55 Test (org.testng.annotations.Test)53 RestRequest (com.linkedin.r2.message.rest.RestRequest)22 RestException (com.linkedin.r2.message.rest.RestException)18 RestRequestBuilder (com.linkedin.r2.message.rest.RestRequestBuilder)17 RequestContext (com.linkedin.r2.message.RequestContext)15 ByteString (com.linkedin.data.ByteString)13 Map (java.util.Map)10 RestLiServiceException (com.linkedin.restli.server.RestLiServiceException)8 HashMap (java.util.HashMap)8 TransportCallback (com.linkedin.r2.transport.common.bridge.common.TransportCallback)6 RoutingException (com.linkedin.restli.server.RoutingException)6 DataMap (com.linkedin.data.DataMap)5 FilterChain (com.linkedin.r2.filter.FilterChain)5 CaptureLastCallFilter (com.linkedin.r2.testutils.filter.CaptureLastCallFilter)5 FilterRequestContext (com.linkedin.restli.server.filter.FilterRequestContext)5 FilterResponseContext (com.linkedin.restli.server.filter.FilterResponseContext)5 IOException (java.io.IOException)5 URI (java.net.URI)5