Search in sources :

Example 1 with StreamEncodingType

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

the class TestRequestCompression method requestCompressionData.

@DataProvider
public Object[][] requestCompressionData() {
    StreamEncodingType[] encodings = new StreamEncodingType[] { StreamEncodingType.GZIP, StreamEncodingType.DEFLATE, StreamEncodingType.SNAPPY_FRAMED, StreamEncodingType.BZIP2 };
    String[] protocols = new String[] { HttpProtocolVersion.HTTP_1_1.name(), HttpProtocolVersion.HTTP_2.name() };
    Object[][] args = new Object[encodings.length * protocols.length][2];
    int cur = 0;
    for (StreamEncodingType requestEncoding : encodings) {
        for (String protocol : protocols) {
            StreamFilter clientCompressionFilter = new ClientStreamCompressionFilter(requestEncoding, new CompressionConfig(THRESHOLD), null, new CompressionConfig(THRESHOLD), Arrays.asList(new String[] { "*" }), _executor);
            TransportClientFactory factory = new HttpClientFactory.Builder().setFilterChain(FilterChains.createStreamChain(clientCompressionFilter)).build();
            HashMap<String, String> properties = new HashMap<>();
            properties.put(HttpClientFactory.HTTP_PROTOCOL_VERSION, protocol);
            Client client = new TransportClientAdapter(factory.getClient(properties), true);
            args[cur][0] = client;
            args[cur][1] = URI.create("/" + requestEncoding.getHttpName());
            cur++;
            _clientFactories.add(factory);
            _clients.add(client);
        }
    }
    return args;
}
Also used : HashMap(java.util.HashMap) TransportDispatcherBuilder(com.linkedin.r2.transport.common.bridge.server.TransportDispatcherBuilder) StreamRequestBuilder(com.linkedin.r2.message.stream.StreamRequestBuilder) ByteString(com.linkedin.data.ByteString) 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 2 with StreamEncodingType

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

the class TestCompressionEcho method compressionEchoData.

@DataProvider
public Object[][] compressionEchoData() throws Exception {
    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);
            Client client = createClient(FilterChains.createStreamChain(clientCompressionFilter));
            args[cur][0] = client;
            args[cur][1] = LARGE_BYTES_NUM;
            cur++;
            _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);
            Client client = createClient(FilterChains.createStreamChain(clientCompressionFilter));
            args[cur][0] = client;
            args[cur][1] = SMALL_BYTES_NUM;
            cur++;
            _clients.add(client);
        }
    }
    return args;
}
Also used : StreamFilter(com.linkedin.r2.filter.message.stream.StreamFilter) Client(com.linkedin.r2.transport.common.Client) StreamEncodingType(com.linkedin.r2.filter.compression.streaming.StreamEncodingType) ClientStreamCompressionFilter(com.linkedin.r2.filter.compression.ClientStreamCompressionFilter) CompressionConfig(com.linkedin.r2.filter.CompressionConfig) DataProvider(org.testng.annotations.DataProvider)

Example 3 with StreamEncodingType

use of com.linkedin.r2.filter.compression.streaming.StreamEncodingType 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 4 with StreamEncodingType

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

the class ClientStreamCompressionFilter method onStreamError.

@Override
public void onStreamError(Throwable ex, RequestContext requestContext, Map<String, String> wireAttrs, NextFilter<StreamRequest, StreamResponse> nextFilter) {
    if (ex instanceof StreamException) {
        Boolean decompressionOff = (Boolean) requestContext.getLocalAttr(R2Constants.RESPONSE_DECOMPRESSION_OFF);
        if (decompressionOff == null || !decompressionOff) {
            StreamException se = (StreamException) ex;
            StreamResponse response = se.getResponse();
            // Check for header encoding
            String compressionHeader = response.getHeader(HttpConstants.CONTENT_ENCODING);
            // decompress if necessary
            if (compressionHeader != null) {
                StreamEncodingType encoding = StreamEncodingType.get(compressionHeader.trim().toLowerCase());
                if (encoding != null) {
                    final StreamingCompressor compressor = encoding.getCompressor(_executor);
                    EntityStream uncompressedStream = compressor.inflate(response.getEntityStream());
                    StreamResponseBuilder builder = response.builder();
                    Map<String, String> headers = stripHeaders(builder.getHeaders(), HttpConstants.CONTENT_ENCODING, HttpConstants.CONTENT_LENGTH);
                    response = builder.setHeaders(headers).build(uncompressedStream);
                    ex = new StreamException(response);
                }
            }
        }
    }
    nextFilter.onError(ex, requestContext, wireAttrs);
}
Also used : EntityStream(com.linkedin.r2.message.stream.entitystream.EntityStream) StreamResponseBuilder(com.linkedin.r2.message.stream.StreamResponseBuilder) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) StreamingCompressor(com.linkedin.r2.filter.compression.streaming.StreamingCompressor) StreamEncodingType(com.linkedin.r2.filter.compression.streaming.StreamEncodingType) StreamException(com.linkedin.r2.message.stream.StreamException)

Example 5 with StreamEncodingType

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

the class AcceptEncoding method parseAcceptEncodingHeader.

/**
 * Takes the value of Accept-Encoding HTTP header field and returns a list of supported types in
 * their order of appearance in the HTTP header value (unsupported types are filtered out).
 * @param headerValue Http header value of Accept-Encoding field
 * @return ArrayList of accepted-encoding entries
 * @throws com.linkedin.r2.filter.compression.CompressionException
 */
public static List<AcceptEncoding> parseAcceptEncodingHeader(String headerValue, Set<StreamEncodingType> supportedEncodings) throws CompressionException {
    headerValue = headerValue.toLowerCase();
    String[] entries = headerValue.split(CompressionConstants.ENCODING_DELIMITER);
    List<AcceptEncoding> parsedEncodings = new ArrayList<>();
    for (String entry : entries) {
        String[] content = entry.trim().split(CompressionConstants.QUALITY_DELIMITER);
        if (content.length < 1 || content.length > 2) {
            throw new IllegalArgumentException(CompressionConstants.ILLEGAL_FORMAT + entry);
        }
        StreamEncodingType type = StreamEncodingType.get(content[0].trim());
        Float quality = 1.0f;
        if (type != null && supportedEncodings.contains(type)) {
            if (content.length > 1) {
                String acceptEncodingPart = content[1].trim();
                if (acceptEncodingPart.startsWith(CompressionConstants.QUALITY_PREFIX)) {
                    try {
                        quality = Float.parseFloat(acceptEncodingPart.substring(CompressionConstants.QUALITY_PREFIX.length()));
                    } catch (NumberFormatException e) {
                        throw new CompressionException(CompressionConstants.ILLEGAL_FORMAT + entry, e);
                    }
                } else {
                    throw new CompressionException(CompressionConstants.ILLEGAL_FORMAT + entry);
                }
            }
            parsedEncodings.add(new AcceptEncoding(type, quality));
        }
    }
    return parsedEncodings;
}
Also used : ArrayList(java.util.ArrayList) CompressionException(com.linkedin.r2.filter.compression.CompressionException)

Aggregations

StreamEncodingType (com.linkedin.r2.filter.compression.streaming.StreamEncodingType)12 CompressionConfig (com.linkedin.r2.filter.CompressionConfig)7 ClientStreamCompressionFilter (com.linkedin.r2.filter.compression.ClientStreamCompressionFilter)7 StreamFilter (com.linkedin.r2.filter.message.stream.StreamFilter)6 Client (com.linkedin.r2.transport.common.Client)6 DataProvider (org.testng.annotations.DataProvider)6 StreamResponseBuilder (com.linkedin.r2.message.stream.StreamResponseBuilder)5 ByteString (com.linkedin.data.ByteString)4 StreamingCompressor (com.linkedin.r2.filter.compression.streaming.StreamingCompressor)4 EntityStream (com.linkedin.r2.message.stream.entitystream.EntityStream)4 HashMap (java.util.HashMap)4 StreamRequestBuilder (com.linkedin.r2.message.stream.StreamRequestBuilder)3 StreamResponse (com.linkedin.r2.message.stream.StreamResponse)3 TransportClientFactory (com.linkedin.r2.transport.common.TransportClientFactory)3 TransportClientAdapter (com.linkedin.r2.transport.common.bridge.client.TransportClientAdapter)3 TransportDispatcherBuilder (com.linkedin.r2.transport.common.bridge.server.TransportDispatcherBuilder)3 StreamException (com.linkedin.r2.message.stream.StreamException)2 Callback (com.linkedin.common.callback.Callback)1 DisruptFilter (com.linkedin.r2.disruptor.DisruptFilter)1 FilterChain (com.linkedin.r2.filter.FilterChain)1