Search in sources :

Example 41 with TransportCallback

use of com.linkedin.r2.transport.common.bridge.common.TransportCallback in project rest.li by linkedin.

the class RetryTrackerClient method restRequest.

@Override
public void restRequest(RestRequest request, RequestContext requestContext, Map<String, String> wireAttrs, TransportCallback<RestResponse> callback) {
    TransportResponse<RestResponse> response;
    if (_uri.toString().startsWith("http://test.linkedin.com/retry")) {
        RetriableRequestException ex = new RetriableRequestException("Data not available");
        response = TransportResponseImpl.error(ex);
    } else if (_uri.toString().equals("http://test.linkedin.com/bad")) {
        response = TransportResponseImpl.error(RestException.forError(404, "exception happens"), wireAttrs);
    } else {
        response = TransportResponseImpl.success(new RestResponseBuilder().build(), wireAttrs);
    }
    callback.onResponse(response);
}
Also used : RetriableRequestException(com.linkedin.r2.RetriableRequestException) RestResponse(com.linkedin.r2.message.rest.RestResponse) RestResponseBuilder(com.linkedin.r2.message.rest.RestResponseBuilder)

Example 42 with TransportCallback

use of com.linkedin.r2.transport.common.bridge.common.TransportCallback in project rest.li by linkedin.

the class DispatcherRequestFilter method onStreamRequest.

@Override
public void onStreamRequest(StreamRequest req, RequestContext requestContext, Map<String, String> wireAttrs, NextFilter<StreamRequest, StreamResponse> nextFilter) {
    Connector connector = null;
    try {
        final AtomicBoolean responded = new AtomicBoolean(false);
        TransportCallback<StreamResponse> callback = createStreamCallback(requestContext, nextFilter, responded);
        connector = new Connector(responded, nextFilter, requestContext, wireAttrs);
        req.getEntityStream().setReader(connector);
        EntityStream newStream = EntityStreams.newEntityStream(connector);
        _dispatcher.handleStreamRequest(req.builder().build(newStream), wireAttrs, requestContext, callback);
    } catch (Exception e) {
        nextFilter.onError(e, requestContext, new HashMap<String, String>());
        if (connector != null) {
            connector.cancel();
        }
    }
}
Also used : EntityStream(com.linkedin.r2.message.stream.entitystream.EntityStream) BaseConnector(com.linkedin.r2.message.stream.entitystream.BaseConnector) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) StreamResponse(com.linkedin.r2.message.stream.StreamResponse)

Example 43 with TransportCallback

use of com.linkedin.r2.transport.common.bridge.common.TransportCallback in project rest.li by linkedin.

the class TransportDispatcherImpl method handleRestRequest.

@Override
public void handleRestRequest(RestRequest req, Map<String, String> wireAttrs, RequestContext requestContext, TransportCallback<RestResponse> callback) {
    final URI address = req.getURI();
    RestRequestHandler handler = _restHandlers.get(address);
    if (handler == null) {
        callback.onResponse(TransportResponseImpl.success(RestStatus.responseForStatus(RestStatus.NOT_FOUND, "No resource for URI:" + address)));
        return;
    }
    try {
        handler.handleRequest(req, requestContext, new TransportCallbackAdapter<RestResponse>(callback));
    } catch (Exception e) {
        callback.onResponse(TransportResponseImpl.<RestResponse>error(RestException.forError(RestStatus.INTERNAL_SERVER_ERROR, e)));
    }
}
Also used : RestResponse(com.linkedin.r2.message.rest.RestResponse) URI(java.net.URI) RestRequestHandler(com.linkedin.r2.transport.common.RestRequestHandler) RestException(com.linkedin.r2.message.rest.RestException)

Example 44 with TransportCallback

use of com.linkedin.r2.transport.common.bridge.common.TransportCallback in project rest.li by linkedin.

the class AbstractAsyncR2StreamServlet method service.

@Override
public void service(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
    final AsyncContext ctx = req.startAsync(req, resp);
    ctx.setTimeout(_timeout);
    final WrappedAsyncContext wrappedCtx = new WrappedAsyncContext(ctx);
    final AsyncEventIOHandler ioHandler = new AsyncEventIOHandler(req.getInputStream(), resp.getOutputStream(), wrappedCtx, MAX_BUFFERED_CHUNKS);
    final RequestContext requestContext = ServletHelper.readRequestContext(req);
    final StreamRequest streamRequest;
    try {
        streamRequest = ServletHelper.readFromServletRequest(req, ioHandler);
    } catch (URISyntaxException e) {
        ServletHelper.writeToServletError(resp, RestStatus.BAD_REQUEST, e.toString());
        wrappedCtx.complete();
        return;
    }
    final AtomicBoolean startedResponding = new AtomicBoolean(false);
    ctx.addListener(new AsyncListener() {

        @Override
        public void onTimeout(AsyncEvent event) throws IOException {
            LOG.error("Server timeout for request: " + formatURI(req.getRequestURI()));
            if (startedResponding.compareAndSet(false, true)) {
                LOG.info("Returning server timeout response");
                ServletHelper.writeToServletError(resp, RestStatus.INTERNAL_SERVER_ERROR, "Server timeout");
            } else {
                req.setAttribute(ASYNC_IOEXCEPTION, new ServletException("Server timeout"));
            }
            ioHandler.exitLoop();
            wrappedCtx.complete();
        }

        @Override
        public void onStartAsync(AsyncEvent event) throws IOException {
        // Nothing to do here
        }

        @Override
        public void onError(AsyncEvent event) throws IOException {
            LOG.error("Server error for request: " + formatURI(req.getRequestURI()));
            if (startedResponding.compareAndSet(false, true)) {
                LOG.info("Returning server error response");
                ServletHelper.writeToServletError(resp, RestStatus.INTERNAL_SERVER_ERROR, "Server error");
            } else {
                req.setAttribute(ASYNC_IOEXCEPTION, new ServletException("Server error"));
            }
            ioHandler.exitLoop();
            wrappedCtx.complete();
        }

        @Override
        public void onComplete(AsyncEvent event) throws IOException {
            Object exception = req.getAttribute(ASYNC_IOEXCEPTION);
            if (exception != null) {
                throw new IOException((Throwable) exception);
            }
        }
    });
    final TransportCallback<StreamResponse> callback = new TransportCallback<StreamResponse>() {

        @Override
        public void onResponse(final TransportResponse<StreamResponse> response) {
            if (startedResponding.compareAndSet(false, true)) {
                ctx.start(new Runnable() {

                    @Override
                    public void run() {
                        try {
                            StreamResponse streamResponse = ServletHelper.writeResponseHeadersToServletResponse(response, resp);
                            streamResponse.getEntityStream().setReader(ioHandler);
                            ioHandler.loop();
                        } catch (Exception e) {
                            req.setAttribute(ASYNC_IOEXCEPTION, e);
                            wrappedCtx.complete();
                        }
                    }
                });
            } else {
                LOG.error("Dropped a response; this is mostly like because that AsyncContext timeout or error had already happened");
            }
        }
    };
    // we have to use a new thread and let this thread return to pool. otherwise the timeout won't start
    ctx.start(new Runnable() {

        @Override
        public void run() {
            try {
                getDispatcher().handleRequest(streamRequest, requestContext, callback);
                ioHandler.loop();
            } catch (Exception e) {
                req.setAttribute(ASYNC_IOEXCEPTION, e);
                wrappedCtx.complete();
            }
        }
    });
}
Also used : TransportCallback(com.linkedin.r2.transport.common.bridge.common.TransportCallback) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) AsyncContext(javax.servlet.AsyncContext) URISyntaxException(java.net.URISyntaxException) IOException(java.io.IOException) AsyncEvent(javax.servlet.AsyncEvent) TransportResponse(com.linkedin.r2.transport.common.bridge.common.TransportResponse) ServletException(javax.servlet.ServletException) URISyntaxException(java.net.URISyntaxException) IOException(java.io.IOException) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) ServletException(javax.servlet.ServletException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AsyncListener(javax.servlet.AsyncListener) RequestContext(com.linkedin.r2.message.RequestContext)

Example 45 with TransportCallback

use of com.linkedin.r2.transport.common.bridge.common.TransportCallback in project rest.li by linkedin.

the class AbstractR2StreamServlet method service.

@Override
protected void service(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
    final SyncIOHandler ioHandler = new SyncIOHandler(req.getInputStream(), resp.getOutputStream(), 2, _ioHandlerTimeout);
    RequestContext requestContext = ServletHelper.readRequestContext(req);
    StreamRequest streamRequest;
    try {
        streamRequest = ServletHelper.readFromServletRequest(req, ioHandler);
    } catch (URISyntaxException e) {
        ServletHelper.writeToServletError(resp, RestStatus.BAD_REQUEST, e.toString());
        return;
    }
    TransportCallback<StreamResponse> callback = new TransportCallback<StreamResponse>() {

        @Override
        public void onResponse(TransportResponse<StreamResponse> response) {
            StreamResponse streamResponse = ServletHelper.writeResponseHeadersToServletResponse(response, resp);
            streamResponse.getEntityStream().setReader(ioHandler);
        }
    };
    getDispatcher().handleRequest(streamRequest, requestContext, callback);
    ioHandler.loop();
}
Also used : TransportCallback(com.linkedin.r2.transport.common.bridge.common.TransportCallback) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) RequestContext(com.linkedin.r2.message.RequestContext) URISyntaxException(java.net.URISyntaxException) TransportResponse(com.linkedin.r2.transport.common.bridge.common.TransportResponse) StreamRequest(com.linkedin.r2.message.stream.StreamRequest)

Aggregations

RestRequest (com.linkedin.r2.message.rest.RestRequest)32 RequestContext (com.linkedin.r2.message.RequestContext)30 StreamResponse (com.linkedin.r2.message.stream.StreamResponse)29 RestResponse (com.linkedin.r2.message.rest.RestResponse)26 FutureCallback (com.linkedin.common.callback.FutureCallback)22 TransportCallbackAdapter (com.linkedin.r2.transport.common.bridge.client.TransportCallbackAdapter)22 Test (org.testng.annotations.Test)22 RestRequestBuilder (com.linkedin.r2.message.rest.RestRequestBuilder)21 TransportCallback (com.linkedin.r2.transport.common.bridge.common.TransportCallback)19 ByteString (com.linkedin.data.ByteString)16 ExecutionException (java.util.concurrent.ExecutionException)16 RemoteInvocationException (com.linkedin.r2.RemoteInvocationException)14 TimeoutException (java.util.concurrent.TimeoutException)14 HashMap (java.util.HashMap)13 URI (java.net.URI)12 Map (java.util.Map)12 StreamRequest (com.linkedin.r2.message.stream.StreamRequest)11 RestException (com.linkedin.r2.message.rest.RestException)10 StreamResponseBuilder (com.linkedin.r2.message.stream.StreamResponseBuilder)10 RestResponseBuilder (com.linkedin.r2.message.rest.RestResponseBuilder)9