Search in sources :

Example 6 with AcceptEncoding

use of com.linkedin.r2.filter.compression.streaming.AcceptEncoding in project rest.li by linkedin.

the class TestCompressionEcho method compressionEchoData.

@DataProvider
public Object[][] compressionEchoData() {
    StreamEncodingType[] encodings = new StreamEncodingType[] { StreamEncodingType.GZIP, StreamEncodingType.DEFLATE, StreamEncodingType.SNAPPY_FRAMED, StreamEncodingType.BZIP2, StreamEncodingType.IDENTITY };
    Object[][] args = new Object[2 * encodings.length * encodings.length][2];
    int cur = 0;
    for (StreamEncodingType requestEncoding : encodings) {
        for (StreamEncodingType acceptEncoding : encodings) {
            StreamFilter clientCompressionFilter = new ClientStreamCompressionFilter(requestEncoding, new CompressionConfig(THRESHOLD), new StreamEncodingType[] { acceptEncoding }, new CompressionConfig(THRESHOLD), Arrays.asList(new String[] { "*" }), _executor);
            TransportClientFactory factory = new HttpClientFactory.Builder().setFilterChain(FilterChains.createStreamChain(clientCompressionFilter)).build();
            Client client = new TransportClientAdapter(factory.getClient(getClientProperties()), true);
            args[cur][0] = client;
            args[cur][1] = LARGE_BYTES_NUM;
            cur++;
            _clientFactories.add(factory);
            _clients.add(client);
        }
    }
    // test data that won't trigger compression
    for (StreamEncodingType requestEncoding : encodings) {
        for (StreamEncodingType acceptEncoding : encodings) {
            StreamFilter clientCompressionFilter = new ClientStreamCompressionFilter(requestEncoding, new CompressionConfig(THRESHOLD), new StreamEncodingType[] { acceptEncoding }, new CompressionConfig(THRESHOLD), Arrays.asList(new String[] { "*" }), _executor);
            TransportClientFactory factory = new HttpClientFactory.Builder().setFilterChain(FilterChains.createStreamChain(clientCompressionFilter)).build();
            Client client = new TransportClientAdapter(factory.getClient(getClientProperties()), true);
            args[cur][0] = client;
            args[cur][1] = SMALL_BYTES_NUM;
            cur++;
            _clientFactories.add(factory);
            _clients.add(client);
        }
    }
    return args;
}
Also used : StreamRequestBuilder(com.linkedin.r2.message.stream.StreamRequestBuilder) StreamResponseBuilder(com.linkedin.r2.message.stream.StreamResponseBuilder) TransportDispatcherBuilder(com.linkedin.r2.transport.common.bridge.server.TransportDispatcherBuilder) StreamFilter(com.linkedin.r2.filter.message.stream.StreamFilter) StreamEncodingType(com.linkedin.r2.filter.compression.streaming.StreamEncodingType) ClientStreamCompressionFilter(com.linkedin.r2.filter.compression.ClientStreamCompressionFilter) TransportClientAdapter(com.linkedin.r2.transport.common.bridge.client.TransportClientAdapter) Client(com.linkedin.r2.transport.common.Client) TransportClientFactory(com.linkedin.r2.transport.common.TransportClientFactory) CompressionConfig(com.linkedin.r2.filter.CompressionConfig) DataProvider(org.testng.annotations.DataProvider)

Example 7 with AcceptEncoding

use of com.linkedin.r2.filter.compression.streaming.AcceptEncoding in project rest.li by linkedin.

the class ServerCompressionFilter method onRestResponse.

/**
   * Optionally compresses outgoing response
   * */
@Override
public void onRestResponse(RestResponse res, RequestContext requestContext, Map<String, String> wireAttrs, NextFilter<RestRequest, RestResponse> nextFilter) {
    try {
        if (res.getEntity().length() > 0) {
            String responseAcceptedEncodings = (String) requestContext.getLocalAttr(HttpConstants.ACCEPT_ENCODING);
            if (responseAcceptedEncodings == null) {
                throw new CompressionException(HttpConstants.ACCEPT_ENCODING + " not in local attribute.");
            }
            List<AcceptEncoding> parsedEncodings = AcceptEncoding.parseAcceptEncodingHeader(responseAcceptedEncodings, _supportedEncoding);
            EncodingType selectedEncoding = AcceptEncoding.chooseBest(parsedEncodings);
            //Check if there exists an acceptable encoding
            if (selectedEncoding != null) {
                if (selectedEncoding.hasCompressor() && res.getEntity().length() > (Integer) requestContext.getLocalAttr(HttpConstants.HEADER_RESPONSE_COMPRESSION_THRESHOLD)) {
                    Compressor compressor = selectedEncoding.getCompressor();
                    byte[] compressed = compressor.deflate(res.getEntity().asInputStream());
                    if (compressed.length < res.getEntity().length()) {
                        RestResponseBuilder resCompress = res.builder();
                        resCompress.addHeaderValue(HttpConstants.CONTENT_ENCODING, compressor.getContentEncodingName());
                        resCompress.setEntity(compressed);
                        res = resCompress.build();
                    }
                }
            } else {
                //Not acceptable encoding status
                res = res.builder().setStatus(HttpConstants.NOT_ACCEPTABLE).setEntity(new byte[0]).build();
            }
        }
    } catch (CompressionException e) {
        LOG.error(e.getMessage(), e.getCause());
    }
    nextFilter.onResponse(res, requestContext, wireAttrs);
}
Also used : RestResponseBuilder(com.linkedin.r2.message.rest.RestResponseBuilder)

Example 8 with AcceptEncoding

use of com.linkedin.r2.filter.compression.streaming.AcceptEncoding in project rest.li by linkedin.

the class ServerStreamCompressionFilter method onStreamResponse.

/**
   * Optionally compresses outgoing response
   * */
@Override
public void onStreamResponse(final StreamResponse res, final RequestContext requestContext, final Map<String, String> wireAttrs, final NextFilter<StreamRequest, StreamResponse> nextFilter) {
    StreamResponse response = res;
    try {
        String responseCompression = (String) requestContext.getLocalAttr(HttpConstants.ACCEPT_ENCODING);
        if (responseCompression == null) {
            throw new CompressionException(HttpConstants.ACCEPT_ENCODING + " not in local attribute.");
        }
        List<AcceptEncoding> parsedEncodings = AcceptEncoding.parseAcceptEncodingHeader(responseCompression, _supportedEncoding);
        StreamEncodingType selectedEncoding = AcceptEncoding.chooseBest(parsedEncodings);
        //Check if there exists an acceptable encoding
        if (selectedEncoding == null) {
            //Not acceptable encoding status
            response = new StreamResponseBuilder().setStatus(HttpConstants.NOT_ACCEPTABLE).build(EntityStreams.emptyStream());
        } else if (selectedEncoding != StreamEncodingType.IDENTITY) {
            final int threshold = (Integer) requestContext.getLocalAttr(HttpConstants.HEADER_RESPONSE_COMPRESSION_THRESHOLD);
            final StreamingCompressor compressor = selectedEncoding.getCompressor(_executor);
            PartialReader reader = new PartialReader(threshold, new Callback<EntityStream[]>() {

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

                @Override
                public void onSuccess(EntityStream[] results) {
                    if (// entity stream is less than threshold
                    results.length == 1) {
                        StreamResponse response = res.builder().build(results[0]);
                        nextFilter.onResponse(response, requestContext, wireAttrs);
                    } else {
                        EntityStream compressedStream = compressor.deflate(EntityStreams.newEntityStream(new CompositeWriter(results)));
                        StreamResponseBuilder builder = res.builder();
                        // remove original content-length header if presents.
                        if (builder.getHeader(HttpConstants.CONTENT_LENGTH) != null) {
                            Map<String, String> headers = stripHeaders(builder.getHeaders(), HttpConstants.CONTENT_LENGTH);
                            builder.setHeaders(headers);
                        }
                        StreamResponse response = builder.addHeaderValue(HttpConstants.CONTENT_ENCODING, compressor.getContentEncodingName()).build(compressedStream);
                        nextFilter.onResponse(response, requestContext, wireAttrs);
                    }
                }
            });
            res.getEntityStream().setReader(reader);
            return;
        }
    } catch (CompressionException e) {
        LOG.error(e.getMessage(), e.getCause());
    }
    nextFilter.onResponse(response, requestContext, wireAttrs);
}
Also used : StreamResponseBuilder(com.linkedin.r2.message.stream.StreamResponseBuilder) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) CompositeWriter(com.linkedin.r2.message.stream.entitystream.CompositeWriter) PartialReader(com.linkedin.r2.filter.compression.streaming.PartialReader) StreamEncodingType(com.linkedin.r2.filter.compression.streaming.StreamEncodingType) EntityStream(com.linkedin.r2.message.stream.entitystream.EntityStream) Callback(com.linkedin.common.callback.Callback) StreamingCompressor(com.linkedin.r2.filter.compression.streaming.StreamingCompressor) AcceptEncoding(com.linkedin.r2.filter.compression.streaming.AcceptEncoding)

Aggregations

Client (com.linkedin.r2.transport.common.Client)4 RestResponseBuilder (com.linkedin.r2.message.rest.RestResponseBuilder)3 StreamRequestBuilder (com.linkedin.r2.message.stream.StreamRequestBuilder)3 StreamResponse (com.linkedin.r2.message.stream.StreamResponse)3 FutureCallback (com.linkedin.common.callback.FutureCallback)2 CompressionConfig (com.linkedin.r2.filter.CompressionConfig)2 StreamEncodingType (com.linkedin.r2.filter.compression.streaming.StreamEncodingType)2 StreamRequest (com.linkedin.r2.message.stream.StreamRequest)2 StreamResponseBuilder (com.linkedin.r2.message.stream.StreamResponseBuilder)2 EntityStream (com.linkedin.r2.message.stream.entitystream.EntityStream)2 TransportClientFactory (com.linkedin.r2.transport.common.TransportClientFactory)2 TransportClientAdapter (com.linkedin.r2.transport.common.bridge.client.TransportClientAdapter)2 TransportDispatcherBuilder (com.linkedin.r2.transport.common.bridge.server.TransportDispatcherBuilder)2 DataProvider (org.testng.annotations.DataProvider)2 Callback (com.linkedin.common.callback.Callback)1 None (com.linkedin.common.util.None)1 ClientCompressionFilter (com.linkedin.r2.filter.compression.ClientCompressionFilter)1 ClientStreamCompressionFilter (com.linkedin.r2.filter.compression.ClientStreamCompressionFilter)1 CompressionException (com.linkedin.r2.filter.compression.CompressionException)1 EncodingType (com.linkedin.r2.filter.compression.EncodingType)1