Search in sources :

Example 6 with NextFilter

use of com.linkedin.r2.filter.NextFilter in project rest.li by linkedin.

the class TestDisruptFilter method testExecutorRejectExecution.

@Test
public void testExecutorRejectExecution() throws Exception {
    final AtomicBoolean success = new AtomicBoolean(false);
    final CountDownLatch latch = new CountDownLatch(1);
    ExecutorService rejectedExecutor = EasyMock.createStrictMock(ExecutorService.class);
    rejectedExecutor.execute(EasyMock.anyObject(Runnable.class));
    EasyMock.expectLastCall().andAnswer(() -> {
        success.set(true);
        latch.countDown();
        throw new RejectedExecutionException();
    });
    EasyMock.replay(rejectedExecutor);
    final RequestContext requestContext = new RequestContext();
    requestContext.putLocalAttr(DISRUPT_CONTEXT_KEY, DisruptContexts.error(REQUEST_LATENCY));
    final DisruptFilter filter = new DisruptFilter(_scheduler, rejectedExecutor, REQUEST_TIMEOUT);
    final NextFilter<StreamRequest, StreamResponse> next = new NextFilter<StreamRequest, StreamResponse>() {

        @Override
        public void onRequest(StreamRequest restRequest, RequestContext requestContext, Map<String, String> wireAttrs) {
            success.set(false);
            latch.countDown();
        }

        @Override
        public void onResponse(StreamResponse restResponse, RequestContext requestContext, Map<String, String> wireAttrs) {
            success.set(false);
            latch.countDown();
        }

        @Override
        public void onError(Throwable ex, RequestContext requestContext, Map<String, String> wireAttrs) {
            success.set(false);
            latch.countDown();
        }
    };
    filter.onStreamRequest(new StreamRequestBuilder(new URI(URI)).build(EntityStreams.emptyStream()), requestContext, Collections.emptyMap(), next);
    Assert.assertTrue(latch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS), "Missing NextFilter invocation");
    Assert.assertTrue(success.get(), "Unexpected method invocation");
    EasyMock.verify(rejectedExecutor);
    EasyMock.reset(rejectedExecutor);
}
Also used : NextFilter(com.linkedin.r2.filter.NextFilter) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) CountDownLatch(java.util.concurrent.CountDownLatch) StreamRequestBuilder(com.linkedin.r2.message.stream.StreamRequestBuilder) URI(java.net.URI) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) ExecutorService(java.util.concurrent.ExecutorService) RequestContext(com.linkedin.r2.message.RequestContext) Map(java.util.Map) Test(org.testng.annotations.Test)

Example 7 with NextFilter

use of com.linkedin.r2.filter.NextFilter in project rest.li by linkedin.

the class TestDisruptFilter method testStreamErrorDisrupt.

@Test
public void testStreamErrorDisrupt() throws Exception {
    final RequestContext requestContext = new RequestContext();
    requestContext.putLocalAttr(DISRUPT_CONTEXT_KEY, DisruptContexts.error(REQUEST_LATENCY));
    final DisruptFilter filter = new DisruptFilter(_scheduler, _executor, REQUEST_TIMEOUT);
    final CountDownLatch latch = new CountDownLatch(1);
    final AtomicBoolean success = new AtomicBoolean(false);
    final NextFilter<StreamRequest, StreamResponse> next = new NextFilter<StreamRequest, StreamResponse>() {

        @Override
        public void onRequest(StreamRequest restRequest, RequestContext requestContext, Map<String, String> wireAttrs) {
            latch.countDown();
        }

        @Override
        public void onResponse(StreamResponse restResponse, RequestContext requestContext, Map<String, String> wireAttrs) {
            latch.countDown();
        }

        @Override
        public void onError(Throwable ex, RequestContext requestContext, Map<String, String> wireAttrs) {
            success.set(ex instanceof DisruptedException);
            latch.countDown();
        }
    };
    filter.onStreamRequest(new StreamRequestBuilder(new URI(URI)).build(EntityStreams.emptyStream()), requestContext, Collections.emptyMap(), next);
    Assert.assertTrue(latch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS), "Missing NextFilter invocation");
    Assert.assertTrue(success.get(), "Unexpected method invocation");
}
Also used : NextFilter(com.linkedin.r2.filter.NextFilter) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) CountDownLatch(java.util.concurrent.CountDownLatch) StreamRequestBuilder(com.linkedin.r2.message.stream.StreamRequestBuilder) URI(java.net.URI) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) RequestContext(com.linkedin.r2.message.RequestContext) Map(java.util.Map) Test(org.testng.annotations.Test)

Example 8 with NextFilter

use of com.linkedin.r2.filter.NextFilter in project rest.li by linkedin.

the class TestDisruptFilter method testRestErrorDisrupt.

@Test
public void testRestErrorDisrupt() throws Exception {
    final RequestContext requestContext = new RequestContext();
    requestContext.putLocalAttr(DISRUPT_CONTEXT_KEY, DisruptContexts.error(REQUEST_LATENCY));
    final DisruptFilter filter = new DisruptFilter(_scheduler, _executor, REQUEST_TIMEOUT);
    final CountDownLatch latch = new CountDownLatch(1);
    final AtomicBoolean success = new AtomicBoolean(false);
    final NextFilter<RestRequest, RestResponse> next = new NextFilter<RestRequest, RestResponse>() {

        @Override
        public void onRequest(RestRequest restRequest, RequestContext requestContext, Map<String, String> wireAttrs) {
            latch.countDown();
        }

        @Override
        public void onResponse(RestResponse restResponse, RequestContext requestContext, Map<String, String> wireAttrs) {
            latch.countDown();
        }

        @Override
        public void onError(Throwable ex, RequestContext requestContext, Map<String, String> wireAttrs) {
            success.set(ex instanceof DisruptedException);
            latch.countDown();
        }
    };
    filter.onRestRequest(new RestRequestBuilder(new URI(URI)).build(), requestContext, Collections.emptyMap(), next);
    Assert.assertTrue(latch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS), "Missing NextFilter invocation");
    Assert.assertTrue(success.get(), "Unexpected method invocation");
}
Also used : NextFilter(com.linkedin.r2.filter.NextFilter) RestResponse(com.linkedin.r2.message.rest.RestResponse) CountDownLatch(java.util.concurrent.CountDownLatch) URI(java.net.URI) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) RestRequest(com.linkedin.r2.message.rest.RestRequest) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) RequestContext(com.linkedin.r2.message.RequestContext) Map(java.util.Map) Test(org.testng.annotations.Test)

Example 9 with NextFilter

use of com.linkedin.r2.filter.NextFilter in project rest.li by linkedin.

the class ClientStreamCompressionFilter method onStreamResponse.

/**
   *  Decompresses server response
   */
@Override
public void onStreamResponse(StreamResponse res, RequestContext requestContext, Map<String, String> wireAttrs, NextFilter<StreamRequest, StreamResponse> nextFilter) {
    Boolean decompressionOff = (Boolean) requestContext.getLocalAttr(R2Constants.RESPONSE_DECOMPRESSION_OFF);
    if (decompressionOff == null || !decompressionOff) {
        //Check for header encoding
        String compressionHeader = res.getHeader(HttpConstants.CONTENT_ENCODING);
        //decompress if necessary
        if (compressionHeader != null) {
            final StreamEncodingType encoding = StreamEncodingType.get(compressionHeader.trim().toLowerCase());
            if (encoding == null) {
                nextFilter.onError(new IllegalArgumentException("Server returned unrecognized content encoding: " + compressionHeader), requestContext, wireAttrs);
                return;
            }
            final StreamingCompressor compressor = encoding.getCompressor(_executor);
            EntityStream uncompressedStream = compressor.inflate(res.getEntityStream());
            StreamResponseBuilder builder = res.builder();
            Map<String, String> headers = stripHeaders(builder.getHeaders(), HttpConstants.CONTENT_ENCODING, HttpConstants.CONTENT_LENGTH);
            res = builder.setHeaders(headers).build(uncompressedStream);
        }
    }
    nextFilter.onResponse(res, requestContext, wireAttrs);
}
Also used : EntityStream(com.linkedin.r2.message.stream.entitystream.EntityStream) StreamResponseBuilder(com.linkedin.r2.message.stream.StreamResponseBuilder) StreamingCompressor(com.linkedin.r2.filter.compression.streaming.StreamingCompressor) StreamEncodingType(com.linkedin.r2.filter.compression.streaming.StreamEncodingType)

Example 10 with NextFilter

use of com.linkedin.r2.filter.NextFilter in project rest.li by linkedin.

the class ClientStreamCompressionFilter method onStreamRequest.

/**
   * Optionally compresses outgoing Stream requests
   * */
public void onStreamRequest(StreamRequest req, final RequestContext requestContext, final Map<String, String> wireAttrs, final NextFilter<StreamRequest, StreamResponse> nextFilter) {
    //Set accepted encoding for compressed response
    String operation = (String) requestContext.getLocalAttr(R2Constants.OPERATION);
    if (!_acceptEncodingHeader.isEmpty() && _helper.shouldCompressResponseForOperation(operation)) {
        CompressionOption responseCompressionOverride = (CompressionOption) requestContext.getLocalAttr(R2Constants.RESPONSE_COMPRESSION_OVERRIDE);
        req = addResponseCompressionHeaders(responseCompressionOverride, req);
    }
    if (_requestContentEncoding != StreamEncodingType.IDENTITY) {
        final StreamRequest request = req;
        final StreamingCompressor compressor = _requestContentEncoding.getCompressor(_executor);
        CompressionOption option = (CompressionOption) requestContext.getLocalAttr(R2Constants.REQUEST_COMPRESSION_OVERRIDE);
        if (option == null || option != CompressionOption.FORCE_OFF) {
            final int threshold = option == CompressionOption.FORCE_ON ? 0 : _requestCompressionConfig.getCompressionThreshold();
            PartialReader reader = new PartialReader(threshold, new Callback<EntityStream[]>() {

                @Override
                public void onError(Throwable ex) {
                    nextFilter.onError(ex, requestContext, wireAttrs);
                }

                @Override
                public void onSuccess(EntityStream[] result) {
                    if (result.length == 1) {
                        StreamRequest uncompressedRequest = request.builder().build(result[0]);
                        nextFilter.onRequest(uncompressedRequest, requestContext, wireAttrs);
                    } else {
                        StreamRequestBuilder builder = request.builder();
                        EntityStream compressedStream = compressor.deflate(EntityStreams.newEntityStream(new CompositeWriter(result)));
                        Map<String, String> headers = stripHeaders(builder.getHeaders(), HttpConstants.CONTENT_LENGTH);
                        StreamRequest compressedRequest = builder.setHeaders(headers).setHeader(HttpConstants.CONTENT_ENCODING, compressor.getContentEncodingName()).build(compressedStream);
                        nextFilter.onRequest(compressedRequest, requestContext, wireAttrs);
                    }
                }
            });
            req.getEntityStream().setReader(reader);
            return;
        }
    }
    nextFilter.onRequest(req, requestContext, wireAttrs);
}
Also used : CompositeWriter(com.linkedin.r2.message.stream.entitystream.CompositeWriter) PartialReader(com.linkedin.r2.filter.compression.streaming.PartialReader) StreamRequestBuilder(com.linkedin.r2.message.stream.StreamRequestBuilder) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) EntityStream(com.linkedin.r2.message.stream.entitystream.EntityStream) CompressionOption(com.linkedin.r2.filter.CompressionOption) StreamingCompressor(com.linkedin.r2.filter.compression.streaming.StreamingCompressor) Map(java.util.Map) TreeMap(java.util.TreeMap)

Aggregations

RequestContext (com.linkedin.r2.message.RequestContext)23 Test (org.testng.annotations.Test)22 Map (java.util.Map)18 NextFilter (com.linkedin.r2.filter.NextFilter)17 FilterChain (com.linkedin.r2.filter.FilterChain)15 RestResponse (com.linkedin.r2.message.rest.RestResponse)15 RestFilter (com.linkedin.r2.filter.message.rest.RestFilter)14 RestRequest (com.linkedin.r2.message.rest.RestRequest)14 StreamResponse (com.linkedin.r2.message.stream.StreamResponse)13 Callback (com.linkedin.common.callback.Callback)10 HashMap (java.util.HashMap)10 ByteString (com.linkedin.data.ByteString)9 StreamRequest (com.linkedin.r2.message.stream.StreamRequest)9 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)9 FullEntityReader (com.linkedin.r2.message.stream.entitystream.FullEntityReader)8 URI (java.net.URI)8 CountDownLatch (java.util.concurrent.CountDownLatch)8 StreamException (com.linkedin.r2.message.stream.StreamException)7 EntityStream (com.linkedin.r2.message.stream.entitystream.EntityStream)7 RestException (com.linkedin.r2.message.rest.RestException)6