use of com.linkedin.r2.filter.FilterChain in project rest.li by linkedin.
the class TestResponseCompression method initClass.
@BeforeClass
public void initClass() throws Exception {
class TestHelperFilter implements Filter {
@Override
public CompletableFuture<Void> onRequest(FilterRequestContext requestContext) {
Map<String, String> requestHeaders = requestContext.getRequestHeaders();
if (requestHeaders.containsKey(EXPECTED_ACCEPT_ENCODING)) {
String expected = requestHeaders.get(EXPECTED_ACCEPT_ENCODING);
if (expected.equals(NONE)) {
if (requestHeaders.containsKey(HttpConstants.ACCEPT_ENCODING)) {
throw new RestLiServiceException(HttpStatus.S_400_BAD_REQUEST, "Accept-Encoding header should not be present.");
}
} else {
if (!expected.equals(requestHeaders.get(HttpConstants.ACCEPT_ENCODING))) {
throw new RestLiServiceException(HttpStatus.S_400_BAD_REQUEST, "Accept-Encoding header should be " + expected + ", but received " + requestHeaders.get(HttpConstants.ACCEPT_ENCODING));
}
}
}
if (requestHeaders.containsKey(EXPECTED_COMPRESSION_THRESHOLD)) {
if (!requestHeaders.get(EXPECTED_COMPRESSION_THRESHOLD).equals(requestHeaders.get(HttpConstants.HEADER_RESPONSE_COMPRESSION_THRESHOLD))) {
throw new RestLiServiceException(HttpStatus.S_400_BAD_REQUEST, "Expected " + HttpConstants.HEADER_RESPONSE_COMPRESSION_THRESHOLD + " " + requestHeaders.get(EXPECTED_COMPRESSION_THRESHOLD) + ", but received " + requestHeaders.get(HttpConstants.HEADER_RESPONSE_COMPRESSION_THRESHOLD));
}
}
return CompletableFuture.completedFuture(null);
}
}
// The default compression threshold is between tiny and huge threshold.
final FilterChain fc = FilterChains.empty().addLastRest(new TestCompressionServer.SaveContentEncodingHeaderFilter()).addLastRest(new ServerCompressionFilter("x-snappy-framed,snappy,gzip,deflate", new CompressionConfig(10000))).addLastRest(new SimpleLoggingFilter());
super.init(Arrays.asList(new TestHelperFilter()), fc, false);
}
use of com.linkedin.r2.filter.FilterChain in project rest.li by linkedin.
the class RestLiServer method handleResourceRequest.
private void handleResourceRequest(final RestRequest request, final RequestContext requestContext, final RequestExecutionCallback<RestResponse> callback, final RestLiAttachmentReader attachmentReader, final boolean isDebugMode) {
try {
ensureRequestUsesValidRestliProtocol(request);
} catch (RestLiServiceException e) {
respondWithPreRoutingError(e, request, attachmentReader, callback);
return;
}
final RoutingResult method;
try {
method = _router.process(request, requestContext, attachmentReader);
} catch (Exception e) {
respondWithPreRoutingError(e, request, attachmentReader, callback);
return;
}
final RequestExecutionCallback<RestResponse> wrappedCallback = notifyInvokeAwares(method, callback);
RequestExecutionReportBuilder requestExecutionReportBuilder = null;
if (isDebugMode) {
requestExecutionReportBuilder = new RequestExecutionReportBuilder();
}
final FilterRequestContextInternal filterContext = new FilterRequestContextInternalImpl((ServerResourceContext) method.getContext(), method.getResourceMethod());
RestLiArgumentBuilder adapter;
try {
RestUtils.validateRequestHeadersAndUpdateResourceContext(request.getHeaders(), (ServerResourceContext) method.getContext());
adapter = buildRestLiArgumentBuilder(method, _errorResponseBuilder);
filterContext.setRequestData(adapter.extractRequestData(method, request));
} catch (Exception e) {
// would not trigger response filters because request filters haven't run yet
wrappedCallback.onError(e, requestExecutionReportBuilder == null ? null : requestExecutionReportBuilder.build(), ((ServerResourceContext) method.getContext()).getRequestAttachmentReader(), null);
return;
}
RestLiFilterResponseContextFactory<Object> filterResponseContextFactory = new RestLiFilterResponseContextFactory<Object>(request, method, _responseHandler);
FilterChainCallback filterChainCallback = new FilterChainCallbackImpl(method, _methodInvoker, adapter, requestExecutionReportBuilder, attachmentReader, _responseHandler, wrappedCallback);
RestLiFilterChain filterChain = new RestLiFilterChain(_filters, filterChainCallback);
filterChain.onRequest(filterContext, filterResponseContextFactory);
}
use of com.linkedin.r2.filter.FilterChain 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.r2.filter.FilterChain in project rest.li by linkedin.
the class TestServerRetryFilter method testStreamRetryFilter.
@Test
public void testStreamRetryFilter() {
String retryMessage = "this is a retry";
ServerRetryFilter retryFilter = new ServerRetryFilter();
StreamFilter captureFilter = new StreamFilter() {
@Override
public void onStreamError(Throwable ex, RequestContext requestContext, Map<String, String> wireAttrs, NextFilter<StreamRequest, StreamResponse> nextFilter) {
Assert.assertEquals(wireAttrs.get(R2Constants.RETRY_MESSAGE_ATTRIBUTE_KEY), retryMessage);
}
};
FilterChain filterChain = FilterChains.createStreamChain(captureFilter, retryFilter);
FilterUtil.fireRestError(filterChain, new StreamException(null, new RetriableRequestException(retryMessage)), new HashMap<String, String>());
}
use of com.linkedin.r2.filter.FilterChain in project rest.li by linkedin.
the class TestStreamFilterAdapters method testRequestFilterAdapterPassThrough.
@Test
public void testRequestFilterAdapterPassThrough() {
FilterChain fc = adaptAndCreateFilterChain(new RestFilter() {
@Override
public void onRestRequest(RestRequest req, RequestContext requestContext, Map<String, String> wireAttrs, NextFilter<RestRequest, RestResponse> nextFilter) {
nextFilter.onRequest(req, requestContext, wireAttrs);
}
});
fc.onStreamRequest(simpleStreamRequest("12345"), FilterUtil.emptyRequestContext(), FilterUtil.emptyWireAttrs());
StreamRequest capturedReq = _afterFilter.getRequest();
Assert.assertEquals(capturedReq.getURI(), SIMPLE_URI);
capturedReq.getEntityStream().setReader(new FullEntityReader(new Callback<ByteString>() {
@Override
public void onError(Throwable e) {
Assert.fail("shouldn't have error");
}
@Override
public void onSuccess(ByteString result) {
Assert.assertEquals(result.asString("UTF8"), "12345");
}
}));
}
Aggregations