Search in sources :

Example 6 with Request

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

the class TestMultiplexedRequestHandlerImpl method testHandleWrongMethod.

@Test(dataProvider = "multiplexerConfigurations")
public void testHandleWrongMethod(MultiplexerRunMode multiplexerRunMode) throws Exception {
    MultiplexedRequestHandlerImpl multiplexer = createMultiplexer(null, multiplexerRunMode);
    RestRequest request = muxRequestBuilder().setMethod(HttpMethod.PUT.name()).build();
    FutureCallback<RestResponse> callback = new FutureCallback<RestResponse>();
    multiplexer.handleRequest(request, new RequestContext(), callback);
    assertEquals(getErrorStatus(callback), HttpStatus.S_405_METHOD_NOT_ALLOWED);
}
Also used : RestRequest(com.linkedin.r2.message.rest.RestRequest) RestResponse(com.linkedin.r2.message.rest.RestResponse) RequestContext(com.linkedin.r2.message.RequestContext) FutureCallback(com.linkedin.common.callback.FutureCallback) Test(org.testng.annotations.Test)

Example 7 with Request

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

the class TestMultiplexedRequestHandlerImpl method testRequestHeaderWhiteListing.

@Test(dataProvider = "multiplexerConfigurations")
public void testRequestHeaderWhiteListing(MultiplexerRunMode multiplexerRunMode) throws Exception {
    // Validating request header white listing logic
    // 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 {
                return fakeIndRestResponse(jsonBodyToByteString(fakeIndividualBody("foobar")));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    };
    // Prepare request to mux handler
    FutureCallback<RestResponse> callback = new FutureCallback<RestResponse>();
    RequestContext requestContext = new RequestContext();
    Map<String, IndividualRequest> individualRequests = ImmutableMap.of("0", fakeIndRequest("/request1", ImmutableMap.of("x-I-am-a-good-Header", "headerValue"), Collections.<String, IndividualRequest>emptyMap()), "1", fakeIndRequest("/request2", ImmutableMap.of("X-Malicious-Header", "evilHeader"), Collections.<String, IndividualRequest>emptyMap()));
    Set<String> headerWhiteList = new HashSet<String>();
    headerWhiteList.add("X-I-AM-A-GOOD-HEADER");
    // Create mux handler instance
    MultiplexedRequestHandlerImpl multiplexer = createMultiplexer(mockHandler, null, headerWhiteList, individualRequests.size(), 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()));
    assertEquals(muxResponseContent.getResponses().get("0").getStatus().intValue(), 200, "Request with whitelisted request header should complete successfully");
    assertEquals(muxResponseContent.getResponses().get("1").getStatus().intValue(), 400, "Request with non-whitelisted request header should receive a 400 bad request error");
}
Also used : MultiplexedResponseContent(com.linkedin.restli.common.multiplexer.MultiplexedResponseContent) RestResponse(com.linkedin.r2.message.rest.RestResponse) ByteString(com.linkedin.data.ByteString) 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) FutureCallback(com.linkedin.common.callback.FutureCallback) HashSet(java.util.HashSet) Test(org.testng.annotations.Test)

Example 8 with Request

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

the class TestMultiplexedRequestHandlerImpl method testCustomMultiplexedSingletonFilter.

@Test(dataProvider = "multiplexerConfigurations")
public void testCustomMultiplexedSingletonFilter(MultiplexerRunMode multiplexerRunMode) throws Exception {
    SynchronousRequestHandler mockHandler = createMockHandler();
    MultiplexerSingletonFilter mockMuxFilter = EasyMock.createMock(MultiplexerSingletonFilter.class);
    MultiplexedRequestHandlerImpl multiplexer = createMultiplexer(mockHandler, mockMuxFilter, multiplexerRunMode);
    RequestContext requestContext = new RequestContext();
    // Create multiplexer request with 1 individual request
    RestRequest request = fakeMuxRestRequest(ImmutableMap.of("0", fakeIndRequest("/urlNeedToBeRemapped")));
    // Set mock for request handler.
    // Mock handler will take a FOO_URL request and return the corresponding FOO_ENTITY in the response
    RestRequest individualRestRequest = fakeIndRestRequest(FOO_URL);
    RestResponse individualRestResponse = fakeIndRestResponse(FOO_ENTITY);
    expect(mockHandler.handleRequestSync(individualRestRequest, requestContext)).andReturn(individualRestResponse);
    // Set mock/expectation for multiplexer filter
    // Map request from /urlNeedToBeRemapped to FOO_URL so that mock handler will be able to handle the request.
    // Map response's body from FOO_ENTITY to BAR_JSON_BODY to simulate filtering on response
    expect(mockMuxFilter.filterIndividualRequest(EasyMock.anyObject(IndividualRequest.class))).andReturn(fakeIndRequest(FOO_URL)).once();
    expect(mockMuxFilter.filterIndividualResponse(EasyMock.anyObject(IndividualResponse.class))).andReturn(fakeIndResponse(BAR_JSON_BODY)).once();
    // Switch into replay mode
    replay(mockHandler);
    replay(mockMuxFilter);
    FutureCallback<RestResponse> callback = new FutureCallback<RestResponse>();
    multiplexer.handleRequest(request, requestContext, callback);
    RestResponse muxRestResponse = callback.get();
    RestResponse expectedMuxRestResponse = fakeMuxRestResponse(ImmutableMap.of(0, fakeIndResponse(BAR_JSON_BODY)));
    assertEquals(muxRestResponse, expectedMuxRestResponse);
    verify(mockMuxFilter);
}
Also used : RestRequest(com.linkedin.r2.message.rest.RestRequest) RestResponse(com.linkedin.r2.message.rest.RestResponse) RequestContext(com.linkedin.r2.message.RequestContext) FutureCallback(com.linkedin.common.callback.FutureCallback) Test(org.testng.annotations.Test)

Example 9 with Request

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

the class TestMultiplexedRequestHandlerImpl method testMultiplexedSingletonFilterFailures.

@Test(dataProvider = "multiplexerConfigurations")
public void testMultiplexedSingletonFilterFailures(MultiplexerRunMode multiplexerRunMode) throws Exception {
    // This test validates when a failure occurred in MultiplexedSingletonFilter for an individual request, only the individual
    // request should fail. The multiplexed request should still be completed successfully with a 200 status code.
    // Setup mock request handler: make handler return a json that contains the request uri
    // We are using this uri in our mock MultiplexerSingletonFilter.filterIndividualResponse function so that
    // we can simulate different response based on the request.
    SynchronousRequestHandler mockHandler = new SynchronousRequestHandler() {

        @Override
        public RestResponse handleRequestSync(RestRequest request, RequestContext requestContext) {
            try {
                return fakeIndRestResponse(jsonBodyToByteString(fakeIndividualBody(request.getURI().toString())));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    };
    // Create a mock MultiplexerSingletonFilter to it simulate different type of failures.
    // Failure is simulated are base on the request uri.
    MultiplexerSingletonFilter muxFilterWithSimulatedFailures = new MultiplexerSingletonFilter() {

        @Override
        public IndividualRequest filterIndividualRequest(IndividualRequest request) {
            if (request.getRelativeUrl().contains("bad_request")) {
                throw new RestLiServiceException(HttpStatus.S_400_BAD_REQUEST, "not found");
            } else if (request.getRelativeUrl().contains("error_request")) {
                throw new IllegalArgumentException("Something really bad happened in filterIndividualRequest");
            }
            return request;
        }

        @Override
        public IndividualResponse filterIndividualResponse(IndividualResponse response) {
            if (response.getStatus() == HttpStatus.S_200_OK.getCode()) {
                if (response.getBody().data().getString("value").contains("notfound_response")) {
                    throw new RestLiServiceException(HttpStatus.S_404_NOT_FOUND, "not found");
                } else if (response.getBody().data().getString("value").contains("error_response")) {
                    // simulate an unexpected exception
                    throw new UnsupportedOperationException("Something really bad happened in filterIndividualResponse");
                }
            }
            return response;
        }
    };
    // Prepare request to mux handler
    FutureCallback<RestResponse> callback = new FutureCallback<RestResponse>();
    RequestContext requestContext = new RequestContext();
    Map<String, IndividualRequest> individualRequests = new HashMap<String, IndividualRequest>();
    individualRequests.put("0", fakeIndRequest("/good_request"));
    individualRequests.put("1", fakeIndRequest("/bad_request"));
    individualRequests.put("2", fakeIndRequest("/error_request"));
    individualRequests.put("3", fakeIndRequest("/notfound_response"));
    individualRequests.put("4", fakeIndRequest("/error_response"));
    individualRequests.put("5", fakeIndRequest("/good_request", ImmutableMap.of("6", fakeIndRequest("/bad_request"))));
    RestRequest request = fakeMuxRestRequest(individualRequests);
    // Create mux handler instance
    MultiplexedRequestHandlerImpl multiplexer = createMultiplexer(mockHandler, muxFilterWithSimulatedFailures, Collections.<String>emptySet(), 10, multiplexerRunMode);
    try {
        multiplexer.handleRequest(request, requestContext, callback);
    } catch (Exception e) {
        fail("Multiplexer should not blow up because one of the individual requests failed", e);
    }
    RestResponse muxRestResponse = callback.get();
    // Assert multiplexed request should return a 200 status code
    assertEquals(muxRestResponse.getStatus(), 200, "Failure in indivudal request should not cause the entire multliplexed request to fail");
    MultiplexedResponseContent muxResponseContent = new MultiplexedResponseContent(DataMapConverter.bytesToDataMap(muxRestResponse.getHeaders(), muxRestResponse.getEntity()));
    IndividualResponseMap responses = muxResponseContent.getResponses();
    // Validate the status code for each of the response
    assertEquals(responses.get("0").getStatus().intValue(), 200, "Mux response body is: " + responses.toString());
    assertEquals(responses.get("1").getStatus().intValue(), 400, "Mux response body is: " + responses.toString());
    assertEquals(responses.get("2").getStatus().intValue(), 500, "Mux response body is: " + responses.toString());
    assertEquals(responses.get("3").getStatus().intValue(), 404, "Mux response body is: " + responses.toString());
    assertEquals(responses.get("4").getStatus().intValue(), 500, "Mux response body is: " + responses.toString());
    assertEquals(responses.get("5").getStatus().intValue(), 200, "Mux response body is: " + responses.toString());
    assertEquals(responses.get("6").getStatus().intValue(), 400, "Mux response body is: " + responses.toString());
}
Also used : MultiplexedResponseContent(com.linkedin.restli.common.multiplexer.MultiplexedResponseContent) HashMap(java.util.HashMap) RestResponse(com.linkedin.r2.message.rest.RestResponse) ByteString(com.linkedin.data.ByteString) 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) RestLiServiceException(com.linkedin.restli.server.RestLiServiceException) RequestContext(com.linkedin.r2.message.RequestContext) IndividualResponseMap(com.linkedin.restli.common.multiplexer.IndividualResponseMap) FutureCallback(com.linkedin.common.callback.FutureCallback) Test(org.testng.annotations.Test)

Example 10 with Request

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

the class TestAsyncMethodInvocationPlanClass method testAsyncGet.

@Test(dataProvider = "requestData")
public void testAsyncGet(String uri, String method, String expectedPlanClass) throws URISyntaxException, IOException, InterruptedException {
    RestLiConfig config = new RestLiConfig();
    config.addResourcePackageNames("com.linkedin.restli.server.multiplexer.resources");
    SettablePromise<Trace> traceHolder = Promises.settable();
    Engine engine = engine(traceHolder);
    RestLiServer server = new RestLiServer(config, resourceFactory(), engine);
    RestRequest request = new RestRequestBuilder(new URI(uri)).setMethod(method).setHeader(RestConstants.HEADER_RESTLI_PROTOCOL_VERSION, AllProtocolVersions.BASELINE_PROTOCOL_VERSION.toString()).build();
    CountDownLatch latch = new CountDownLatch(1);
    server.handleRequest(request, new RequestContext(), callback(latch));
    assertTrue(latch.await(5, TimeUnit.SECONDS));
    assertTrue(traceHolder.await(5, TimeUnit.SECONDS));
    assertTrue(latch.await(5, TimeUnit.SECONDS));
    assertTrue(traceHolder.await(5, TimeUnit.SECONDS));
    assertEquals(traceHolder.get().getPlanClass(), expectedPlanClass);
}
Also used : Trace(com.linkedin.parseq.trace.Trace) RestRequest(com.linkedin.r2.message.rest.RestRequest) RestLiServer(com.linkedin.restli.server.RestLiServer) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) RequestContext(com.linkedin.r2.message.RequestContext) CountDownLatch(java.util.concurrent.CountDownLatch) URI(java.net.URI) RestLiConfig(com.linkedin.restli.server.RestLiConfig) Engine(com.linkedin.parseq.Engine) Test(org.testng.annotations.Test)

Aggregations

Test (org.testng.annotations.Test)209 RestRequest (com.linkedin.r2.message.rest.RestRequest)189 RequestContext (com.linkedin.r2.message.RequestContext)124 URI (java.net.URI)112 RestResponse (com.linkedin.r2.message.rest.RestResponse)111 RestRequestBuilder (com.linkedin.r2.message.rest.RestRequestBuilder)105 ByteString (com.linkedin.data.ByteString)67 StreamRequest (com.linkedin.r2.message.stream.StreamRequest)61 RoutingResult (com.linkedin.restli.internal.server.RoutingResult)59 RestException (com.linkedin.r2.message.rest.RestException)54 StreamResponse (com.linkedin.r2.message.stream.StreamResponse)50 StreamRequestBuilder (com.linkedin.r2.message.stream.StreamRequestBuilder)47 ResourceMethodDescriptor (com.linkedin.restli.internal.server.model.ResourceMethodDescriptor)44 FutureCallback (com.linkedin.common.callback.FutureCallback)41 ResourceModel (com.linkedin.restli.internal.server.model.ResourceModel)38 HashMap (java.util.HashMap)38 Callback (com.linkedin.common.callback.Callback)34 FilterRequestContext (com.linkedin.restli.server.filter.FilterRequestContext)34 ExecutionException (java.util.concurrent.ExecutionException)33 BeforeTest (org.testng.annotations.BeforeTest)31