Search in sources :

Example 66 with ByteString

use of com.linkedin.data.ByteString in project rest.li by linkedin.

the class AbstractR2Servlet method writeToServletResponse.

protected void writeToServletResponse(TransportResponse<RestResponse> response, HttpServletResponse resp) throws IOException {
    Map<String, String> wireAttrs = response.getWireAttributes();
    for (Map.Entry<String, String> e : WireAttributeHelper.toWireAttributes(wireAttrs).entrySet()) {
        resp.setHeader(e.getKey(), e.getValue());
    }
    RestResponse restResponse = null;
    if (response.hasError()) {
        Throwable e = response.getError();
        if (e instanceof RestException) {
            restResponse = ((RestException) e).getResponse();
        }
        if (restResponse == null) {
            restResponse = RestStatus.responseForError(RestStatus.INTERNAL_SERVER_ERROR, e);
        }
    } else {
        restResponse = response.getResponse();
    }
    resp.setStatus(restResponse.getStatus());
    Map<String, String> headers = restResponse.getHeaders();
    for (Map.Entry<String, String> e : headers.entrySet()) {
        // TODO multi-valued headers
        resp.setHeader(e.getKey(), e.getValue());
    }
    for (String cookie : restResponse.getCookies()) {
        resp.addHeader(HttpConstants.RESPONSE_COOKIE_HEADER_NAME, cookie);
    }
    final ByteString entity = restResponse.getEntity();
    entity.write(resp.getOutputStream());
    resp.getOutputStream().close();
}
Also used : RestResponse(com.linkedin.r2.message.rest.RestResponse) ByteString(com.linkedin.data.ByteString) RestException(com.linkedin.r2.message.rest.RestException) ByteString(com.linkedin.data.ByteString) Map(java.util.Map)

Example 67 with ByteString

use of com.linkedin.data.ByteString in project rest.li by linkedin.

the class HttpDispatcher method handleRequest.

/**
 * handle a {@link com.linkedin.r2.message.stream.StreamRequest} using the given request context.
 * @see com.linkedin.r2.transport.common.bridge.server.TransportDispatcher#handleStreamRequest
 *
 * @param req the request to be handled.
 * @param context the request context.
 * @param callback the callback to be invoked with the response or error.
 */
public void handleRequest(StreamRequest req, RequestContext context, final TransportCallback<StreamResponse> callback) {
    markOnRequestTimings(context);
    final Map<String, String> headers = new HashMap<>(req.getHeaders());
    final Map<String, String> wireAttrs = WireAttributeHelper.removeWireAttributes(headers);
    final BaseConnector connector = new BaseConnector();
    try {
        MessageType.Type msgType = MessageType.getMessageType(wireAttrs, MessageType.Type.REST);
        switch(msgType) {
            default:
            case REST:
                req.getEntityStream().setReader(connector);
                StreamRequest newReq = req.builder().build(EntityStreams.newEntityStream(connector));
                // decorate the call back so that if response is error or response finishes streaming,
                // we cancel the request stream
                TransportCallback<StreamResponse> decorateCallback = new TransportCallback<StreamResponse>() {

                    @Override
                    public void onResponse(TransportResponse<StreamResponse> response) {
                        // no need to check StreamException because that's handled by HttpBridge.httpToStreamCallback
                        if (response.hasError()) {
                            connector.cancel();
                        } else {
                            Observer observer = new Observer() {

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

                                @Override
                                public void onDone() {
                                    connector.cancel();
                                }

                                @Override
                                public void onError(Throwable e) {
                                    connector.cancel();
                                }
                            };
                            response.getResponse().getEntityStream().addObserver(observer);
                        }
                        callback.onResponse(response);
                    }
                };
                _dispatcher.handleStreamRequest(HttpBridge.toStreamRequest(newReq, headers), wireAttrs, context, HttpBridge.httpToStreamCallback(decorateCallback));
        }
    } catch (Exception e) {
        connector.cancel();
        callback.onResponse(TransportResponseImpl.<StreamResponse>error(e, Collections.<String, String>emptyMap()));
    }
}
Also used : TransportCallback(com.linkedin.r2.transport.common.bridge.common.TransportCallback) HashMap(java.util.HashMap) BaseConnector(com.linkedin.r2.message.stream.entitystream.BaseConnector) ByteString(com.linkedin.data.ByteString) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) ByteString(com.linkedin.data.ByteString) TransportResponse(com.linkedin.r2.transport.common.bridge.common.TransportResponse) StreamRequest(com.linkedin.r2.message.stream.StreamRequest) Observer(com.linkedin.r2.message.stream.entitystream.Observer) MessageType(com.linkedin.r2.transport.common.MessageType)

Example 68 with ByteString

use of com.linkedin.data.ByteString in project rest.li by linkedin.

the class ServletHelper method writeToServletError.

static void writeToServletError(HttpServletResponse resp, int statusCode, String message) throws IOException {
    RestResponse restResponse = RestStatus.responseForStatus(statusCode, message);
    writeResponseHeadersToServletResponse(TransportResponseImpl.success(Messages.toStreamResponse(restResponse)), resp);
    final ByteString entity = restResponse.getEntity();
    entity.write(resp.getOutputStream());
    resp.getOutputStream().close();
}
Also used : RestResponse(com.linkedin.r2.message.rest.RestResponse) ByteString(com.linkedin.data.ByteString)

Example 69 with ByteString

use of com.linkedin.data.ByteString in project rest.li by linkedin.

the class SyncIOHandler method eventLoop.

private void eventLoop() throws ServletException, IOException, InterruptedException, TimeoutException {
    final long startTime = System.currentTimeMillis();
    byte[] buf = new byte[DEFAULT_DATA_CHUNK_SIZE];
    while (shouldContinue() && !_forceExit) {
        long timeSpent = System.currentTimeMillis() - startTime;
        long maxWaitTime = timeSpent < _timeout ? _timeout - timeSpent : 0;
        Event event = _eventQueue.poll(maxWaitTime, TimeUnit.MILLISECONDS);
        if (event == null) {
            throw new TimeoutException("Timeout after " + _timeout + " milliseconds.");
        }
        switch(event.getEventType()) {
            case ResponseDataAvailable:
                {
                    ByteString data = (ByteString) event.getData();
                    data.write(_os);
                    _rh.request(1);
                    break;
                }
            case WriteRequestPossible:
                {
                    while (_wh.remaining() > 0) {
                        final int actualLen = _is.read(buf);
                        if (actualLen < 0) {
                            _wh.done();
                            _requestReadFinished = true;
                            break;
                        }
                        _wh.write(ByteString.copy(buf, 0, actualLen));
                    }
                    break;
                }
            case FullResponseReceived:
                {
                    _os.close();
                    _responseWriteFinished = true;
                    break;
                }
            case ResponseDataError:
                {
                    _os.close();
                    _responseWriteFinished = true;
                    break;
                }
            case WriteRequestAborted:
                {
                    if (event.getData() instanceof AbortedException) {
                        // reader cancels, we'll drain the stream on behalf of reader
                        // we don't directly drain it here because we'd like to give other events
                        // some opportunities to be executed; e.g. return an error response
                        _eventQueue.add(Event.DrainRequestEvent);
                    } else {
                        // TODO: do we want to be smarter and return server error response?
                        throw new ServletException((Throwable) event.getData());
                    }
                    break;
                }
            case DrainRequest:
                {
                    for (int i = 0; i < 10; i++) {
                        final int actualLen = _is.read(buf);
                        if (actualLen < 0) {
                            _requestReadFinished = true;
                            break;
                        }
                    }
                    if (!_requestReadFinished) {
                        // add self back to event queue and give others a chance to run
                        _eventQueue.add(Event.DrainRequestEvent);
                    }
                    break;
                }
            case ForceExit:
                {
                    _forceExit = true;
                    break;
                }
            default:
                throw new IllegalStateException("Unknown event type:" + event.getEventType());
        }
    }
}
Also used : ServletException(javax.servlet.ServletException) ByteString(com.linkedin.data.ByteString) AbortedException(com.linkedin.r2.message.stream.entitystream.AbortedException) TimeoutException(java.util.concurrent.TimeoutException)

Example 70 with ByteString

use of com.linkedin.data.ByteString in project rest.li by linkedin.

the class TestHttpClient method testClient.

@Test
public void testClient() throws Exception {
    RestRequestBuilder rb = new RestRequestBuilder(getHttpUri(DISPATCHER_URI));
    rb.setMethod("GET");
    RestRequest request = rb.build();
    Future<RestResponse> f = _client.restRequest(request);
    // This will block
    RestResponse response = f.get();
    final ByteString entity = response.getEntity();
    if (entity != null) {
        System.out.println(entity.asString("UTF-8"));
    } else {
        System.out.println("NOTHING!");
    }
    assertEquals(response.getStatus(), 200);
}
Also used : RestRequest(com.linkedin.r2.message.rest.RestRequest) RestResponse(com.linkedin.r2.message.rest.RestResponse) ByteString(com.linkedin.data.ByteString) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) Test(org.testng.annotations.Test) AbstractServiceTest(test.r2.integ.clientserver.providers.AbstractServiceTest)

Aggregations

ByteString (com.linkedin.data.ByteString)152 Test (org.testng.annotations.Test)77 ByteArrayOutputStream (java.io.ByteArrayOutputStream)33 MimeMultipart (javax.mail.internet.MimeMultipart)31 MimeBodyPart (javax.mail.internet.MimeBodyPart)26 DataMap (com.linkedin.data.DataMap)25 RestResponse (com.linkedin.r2.message.rest.RestResponse)25 StreamResponse (com.linkedin.r2.message.stream.StreamResponse)22 FullEntityReader (com.linkedin.r2.message.stream.entitystream.FullEntityReader)22 RestRequest (com.linkedin.r2.message.rest.RestRequest)21 StreamRequest (com.linkedin.r2.message.stream.StreamRequest)21 URI (java.net.URI)21 CountDownLatch (java.util.concurrent.CountDownLatch)20 RequestContext (com.linkedin.r2.message.RequestContext)18 RestRequestBuilder (com.linkedin.r2.message.rest.RestRequestBuilder)18 Callback (com.linkedin.common.callback.Callback)17 StreamRequestBuilder (com.linkedin.r2.message.stream.StreamRequestBuilder)14 RestException (com.linkedin.r2.message.rest.RestException)12 HashMap (java.util.HashMap)12 DataList (com.linkedin.data.DataList)11