Search in sources :

Example 11 with StreamResponse

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

the class TestReplaceableFilter method testStreamingPassThrough.

@Test
public void testStreamingPassThrough() {
    ReplaceableFilter filter = getFilter();
    CountRequestChunksFilter countRequestChunksFilter = new CountRequestChunksFilter();
    CountResponseChunksFilter countResponseChunksFilter = new CountResponseChunksFilter();
    FilterChain filterChain = FilterChains.empty().addLast(countResponseChunksFilter).addLast(filter).addLast(countRequestChunksFilter);
    int requestChunks = 100;
    int responseChunks = 200;
    StreamRequest streamRequest = new StreamRequestBuilder(URI.create("/test")).build(EntityStreams.newEntityStream(new Writer() {

        private WriteHandle _wh;

        int _count = 0;

        @Override
        public void onInit(WriteHandle wh) {
            _wh = wh;
        }

        @Override
        public void onWritePossible() {
            while (_wh.remaining() > 0) {
                if (_count < requestChunks) {
                    _wh.write(ByteString.copy(new byte[10]));
                    _count++;
                } else {
                    _wh.done();
                }
            }
        }

        @Override
        public void onAbort(Throwable e) {
        }
    }));
    StreamResponse streamResponse = new StreamResponseBuilder().build(EntityStreams.newEntityStream(new Writer() {

        private WriteHandle _wh;

        int _count = 0;

        @Override
        public void onInit(WriteHandle wh) {
            _wh = wh;
        }

        @Override
        public void onWritePossible() {
            while (_wh.remaining() > 0) {
                if (_count < responseChunks) {
                    _wh.write(ByteString.copy(new byte[10]));
                    _count++;
                } else {
                    _wh.done();
                }
            }
        }

        @Override
        public void onAbort(Throwable e) {
        }
    }));
    FilterUtil.fireStreamRequest(filterChain, streamRequest);
    FilterUtil.fireStreamResponse(filterChain, streamResponse, new RequestContext(), new HashMap<>());
    Assert.assertEquals(countRequestChunksFilter.getRequestChunks(), requestChunks);
    Assert.assertEquals(countResponseChunksFilter.getResponseChunks(), responseChunks);
}
Also used : StreamResponseBuilder(com.linkedin.r2.message.stream.StreamResponseBuilder) WriteHandle(com.linkedin.r2.message.stream.entitystream.WriteHandle) ReplaceableFilter(com.linkedin.r2.caprep.ReplaceableFilter) FilterChain(com.linkedin.r2.filter.FilterChain) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) StreamRequestBuilder(com.linkedin.r2.message.stream.StreamRequestBuilder) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) RequestContext(com.linkedin.r2.message.RequestContext) Writer(com.linkedin.r2.message.stream.entitystream.Writer) BaseFilterTest(com.linkedin.r2.testutils.filter.BaseFilterTest) Test(org.testng.annotations.Test)

Example 12 with StreamResponse

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

the class TransportClientAdapter method streamRequest.

@Override
public void streamRequest(StreamRequest request, RequestContext requestContext, Callback<StreamResponse> callback) {
    final Map<String, String> wireAttrs = new HashMap<String, String>();
    //make a copy of the caller's RequestContext to ensure that we have a unique instance per-request
    _client.streamRequest(request, new RequestContext(requestContext), wireAttrs, new TransportCallbackAdapter<StreamResponse>(callback));
}
Also used : HashMap(java.util.HashMap) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) RequestContext(com.linkedin.r2.message.RequestContext)

Example 13 with StreamResponse

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

the class TransportDispatcherImpl method handleStreamRequest.

@Override
public void handleStreamRequest(StreamRequest req, Map<String, String> wireAttrs, RequestContext requestContext, TransportCallback<StreamResponse> callback) {
    final URI address = req.getURI();
    final StreamRequestHandler handler = _streamHandlers.get(address);
    if (handler == null) {
        final RestResponse response = RestStatus.responseForStatus(RestStatus.NOT_FOUND, "No resource for URI: " + address);
        callback.onResponse(TransportResponseImpl.success(Messages.toStreamResponse(response)));
        req.getEntityStream().setReader(new DrainReader());
        return;
    }
    try {
        handler.handleRequest(req, requestContext, new TransportCallbackAdapter<StreamResponse>(callback));
    } catch (Exception e) {
        final Exception ex = RestException.forError(RestStatus.INTERNAL_SERVER_ERROR, e);
        callback.onResponse(TransportResponseImpl.<StreamResponse>error(ex));
    }
}
Also used : StreamRequestHandler(com.linkedin.r2.transport.common.StreamRequestHandler) RestResponse(com.linkedin.r2.message.rest.RestResponse) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) URI(java.net.URI) DrainReader(com.linkedin.r2.message.stream.entitystream.DrainReader) RestException(com.linkedin.r2.message.rest.RestException)

Example 14 with StreamResponse

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

the class TestServerTimeout method testServerTimeout.

@Test
public void testServerTimeout() throws Exception {
    final StreamRequest request = new StreamRequestBuilder(Bootstrap.createHttpURI(PORT, BUGGY_SERVER_URI)).build(EntityStreams.emptyStream());
    final CountDownLatch latch = new CountDownLatch(1);
    final AtomicInteger status = new AtomicInteger(-1);
    _client.streamRequest(request, new Callback<StreamResponse>() {

        @Override
        public void onError(Throwable e) {
            latch.countDown();
        }

        @Override
        public void onSuccess(StreamResponse result) {
            status.set(result.getStatus());
            result.getEntityStream().setReader(new Reader() {

                private ReadHandle _rh;

                @Override
                public void onInit(ReadHandle rh) {
                    _rh = rh;
                    _rh.request(Integer.MAX_VALUE);
                }

                @Override
                public void onDataAvailable(ByteString data) {
                // do nothing
                }

                @Override
                public void onDone() {
                    // server would close the connection if TimeoutException, and netty would end the chunked transferring
                    // with an empty chunk
                    latch.countDown();
                }

                @Override
                public void onError(Throwable e) {
                    latch.countDown();
                }
            });
        }
    });
    // server should timeout so await should return true
    Assert.assertTrue(latch.await(SERVER_IOHANDLER_TIMEOUT * 2, TimeUnit.MILLISECONDS));
    Assert.assertEquals(status.get(), RestStatus.OK);
}
Also used : ReadHandle(com.linkedin.r2.message.stream.entitystream.ReadHandle) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ByteString(com.linkedin.data.ByteString) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) DrainReader(com.linkedin.r2.message.stream.entitystream.DrainReader) Reader(com.linkedin.r2.message.stream.entitystream.Reader) CountDownLatch(java.util.concurrent.CountDownLatch) StreamRequestBuilder(com.linkedin.r2.message.stream.StreamRequestBuilder) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) Test(org.testng.annotations.Test)

Example 15 with StreamResponse

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

the class TestServerTimeout method setup.

@BeforeClass
public void setup() throws IOException {
    _clientFactory = new HttpClientFactory();
    Map<String, Object> clientProperties = new HashMap<String, Object>();
    clientProperties.put(HttpClientFactory.HTTP_REQUEST_TIMEOUT, String.valueOf(SERVER_IOHANDLER_TIMEOUT * 20));
    clientProperties.put(HttpClientFactory.HTTP_POOL_MIN_SIZE, "1");
    clientProperties.put(HttpClientFactory.HTTP_POOL_SIZE, "1");
    _client = new TransportClientAdapter(_clientFactory.getClient(clientProperties), true);
    final Map<URI, StreamRequestHandler> handlers = new HashMap<URI, StreamRequestHandler>();
    handlers.put(BUGGY_SERVER_URI, new BuggyRequestHandler());
    handlers.put(THROW_BUT_SHOULD_NOT_TIMEOUT_URI, new ThrowHandler());
    handlers.put(BUGGY_FILTER_URI, new NormalHandler());
    TransportDispatcher transportDispatcher = new TransportDispatcher() {

        @Override
        public void handleRestRequest(RestRequest req, Map<String, String> wireAttrs, RequestContext requestContext, TransportCallback<RestResponse> callback) {
            throw new UnsupportedOperationException("This dispatcher only supports stream");
        }

        @Override
        public void handleStreamRequest(StreamRequest req, Map<String, String> wireAttrs, RequestContext requestContext, TransportCallback<StreamResponse> callback) {
            StreamRequestHandler handler = handlers.get(req.getURI());
            if (handler != null) {
                handler.handleRequest(req, requestContext, new TransportCallbackAdapter<StreamResponse>(callback));
            } else {
                req.getEntityStream().setReader(new DrainReader());
                callback.onResponse(TransportResponseImpl.<StreamResponse>error(new IllegalStateException("Handler not found for URI " + req.getURI())));
            }
        }
    };
    FilterChain filterChain = FilterChains.createStreamChain(new BuggyFilter());
    _server = new HttpServerFactory(filterChain).createRAPServer(PORT, transportDispatcher, SERVER_IOHANDLER_TIMEOUT, true);
    _server.start();
}
Also used : HttpServerFactory(com.linkedin.r2.transport.http.server.HttpServerFactory) TransportCallback(com.linkedin.r2.transport.common.bridge.common.TransportCallback) HashMap(java.util.HashMap) FilterChain(com.linkedin.r2.filter.FilterChain) TransportDispatcher(com.linkedin.r2.transport.common.bridge.server.TransportDispatcher) ByteString(com.linkedin.data.ByteString) URI(java.net.URI) TransportClientAdapter(com.linkedin.r2.transport.common.bridge.client.TransportClientAdapter) RequestContext(com.linkedin.r2.message.RequestContext) HttpClientFactory(com.linkedin.r2.transport.http.client.HttpClientFactory) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) DrainReader(com.linkedin.r2.message.stream.entitystream.DrainReader) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) StreamRequestHandler(com.linkedin.r2.transport.common.StreamRequestHandler) RestRequest(com.linkedin.r2.message.rest.RestRequest) Map(java.util.Map) HashMap(java.util.HashMap) BeforeClass(org.testng.annotations.BeforeClass)

Aggregations

StreamResponse (com.linkedin.r2.message.stream.StreamResponse)104 StreamRequest (com.linkedin.r2.message.stream.StreamRequest)71 Test (org.testng.annotations.Test)68 RequestContext (com.linkedin.r2.message.RequestContext)59 StreamRequestBuilder (com.linkedin.r2.message.stream.StreamRequestBuilder)53 ByteString (com.linkedin.data.ByteString)43 URI (java.net.URI)42 Callback (com.linkedin.common.callback.Callback)36 RestRequest (com.linkedin.r2.message.rest.RestRequest)33 CountDownLatch (java.util.concurrent.CountDownLatch)31 RestResponse (com.linkedin.r2.message.rest.RestResponse)28 RestRequestBuilder (com.linkedin.r2.message.rest.RestRequestBuilder)27 StreamException (com.linkedin.r2.message.stream.StreamException)25 HashMap (java.util.HashMap)24 FutureCallback (com.linkedin.common.callback.FutureCallback)22 Map (java.util.Map)20 SinglePartMIMEFullReaderCallback (com.linkedin.multipart.utils.MIMETestUtils.SinglePartMIMEFullReaderCallback)17 StreamResponseBuilder (com.linkedin.r2.message.stream.StreamResponseBuilder)17 TransportCallback (com.linkedin.r2.transport.common.bridge.common.TransportCallback)17 MultiPartMIMEFullReaderCallback (com.linkedin.multipart.utils.MIMETestUtils.MultiPartMIMEFullReaderCallback)16