Search in sources :

Example 36 with TransportCallback

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

the class TestHttpNettyStreamClient method testBadAddress.

@Test(dataProvider = "badAddressClients")
public void testBadAddress(AbstractNettyStreamClient client) throws InterruptedException, IOException, TimeoutException {
    RestRequest r = new RestRequestBuilder(URI.create("http://this.host.does.not.exist.linkedin.com")).build();
    FutureCallback<StreamResponse> cb = new FutureCallback<StreamResponse>();
    TransportCallback<StreamResponse> callback = new TransportCallbackAdapter<StreamResponse>(cb);
    client.streamRequest(Messages.toStreamRequest(r), new RequestContext(), new HashMap<String, String>(), callback);
    try {
        cb.get(30, TimeUnit.SECONDS);
        Assert.fail("Get was supposed to fail");
    } catch (ExecutionException e) {
        verifyCauseChain(e, RemoteInvocationException.class, UnknownHostException.class);
    }
}
Also used : TransportCallbackAdapter(com.linkedin.r2.transport.common.bridge.client.TransportCallbackAdapter) UnknownHostException(java.net.UnknownHostException) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) AsciiString(io.netty.util.AsciiString) ByteString(com.linkedin.data.ByteString) RestRequest(com.linkedin.r2.message.rest.RestRequest) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) RequestContext(com.linkedin.r2.message.RequestContext) RemoteInvocationException(com.linkedin.r2.RemoteInvocationException) ExecutionException(java.util.concurrent.ExecutionException) FutureCallback(com.linkedin.common.callback.FutureCallback) Test(org.testng.annotations.Test)

Example 37 with TransportCallback

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

the class AbstractNettyStreamClient method writeRequestWithTimeout.

private void writeRequestWithTimeout(final StreamRequest request, RequestContext requestContext, Map<String, String> wireAttrs, TransportCallback<StreamResponse> callback) {
    StreamExecutionCallback executionCallback = new StreamExecutionCallback(_callbackExecutors, callback);
    // By wrapping the callback in a Timeout callback before passing it along, we deny the rest
    // of the code access to the unwrapped callback.  This ensures two things:
    // 1. The user callback will always be invoked, since the Timeout will eventually expire
    // 2. The user callback is never invoked more than once
    final TimeoutTransportCallback<StreamResponse> timeoutCallback = new TimeoutTransportCallback<StreamResponse>(_scheduler, _requestTimeout, TimeUnit.MILLISECONDS, executionCallback, _requestTimeoutMessage);
    final StreamRequest requestWithWireAttrHeaders = request.builder().overwriteHeaders(WireAttributeHelper.toWireAttributes(wireAttrs)).build(request.getEntityStream());
    // talk to legacy R2 servers without problem if they're just using restRequest (full request).
    if (isFullRequest(requestContext)) {
        Messages.toRestRequest(requestWithWireAttrHeaders, new Callback<RestRequest>() {

            @Override
            public void onError(Throwable e) {
                errorResponse(timeoutCallback, e);
            }

            @Override
            public void onSuccess(RestRequest restRequest) {
                writeRequest(restRequest, requestContext, timeoutCallback);
            }
        });
    } else {
        writeRequest(requestWithWireAttrHeaders, requestContext, timeoutCallback);
    }
}
Also used : RestRequest(com.linkedin.r2.message.rest.RestRequest) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) StreamRequest(com.linkedin.r2.message.stream.StreamRequest)

Example 38 with TransportCallback

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

the class Http2FrameListener method onHeadersRead.

@Override
public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers, int padding, boolean endOfStream) throws Http2Exception {
    LOG.debug("Received HTTP/2 HEADERS frame, stream={}, end={}, headers={}, padding={}bytes", new Object[] { streamId, endOfStream, headers.size(), padding });
    // Ignores response for the upgrade request
    if (streamId == Http2CodecUtil.HTTP_UPGRADE_STREAM_ID) {
        return;
    }
    final StreamResponseBuilder builder = new StreamResponseBuilder();
    // Process HTTP/2 pseudo headers
    if (headers.status() != null) {
        builder.setStatus(Integer.parseInt(headers.status().toString()));
    }
    if (headers.authority() != null) {
        builder.addHeaderValue(HttpHeaderNames.HOST.toString(), headers.authority().toString());
    }
    // Process other HTTP headers
    for (Map.Entry<CharSequence, CharSequence> header : headers) {
        if (Http2Headers.PseudoHeaderName.isPseudoHeader(header.getKey())) {
            // Do no set HTTP/2 pseudo headers to response
            continue;
        }
        final String key = header.getKey().toString();
        final String value = header.getValue().toString();
        if (key.equalsIgnoreCase(HttpConstants.RESPONSE_COOKIE_HEADER_NAME)) {
            builder.addCookie(value);
        } else {
            builder.unsafeAddHeaderValue(key, value);
        }
    }
    // Gets async pool handle from stream properties
    Http2Connection.PropertyKey handleKey = ctx.channel().attr(Http2ClientPipelineInitializer.CHANNEL_POOL_HANDLE_ATTR_KEY).get();
    TimeoutAsyncPoolHandle<?> handle = _connection.stream(streamId).removeProperty(handleKey);
    if (handle == null) {
        _lifecycleManager.onError(ctx, Http2Exception.connectionError(Http2Error.PROTOCOL_ERROR, "No channel pool handle is associated with this stream", streamId));
        return;
    }
    final StreamResponse response;
    if (endOfStream) {
        response = builder.build(EntityStreams.emptyStream());
        ctx.fireChannelRead(handle);
    } else {
        // Associate an entity stream writer to the HTTP/2 stream
        final TimeoutBufferedWriter writer = new TimeoutBufferedWriter(ctx, streamId, _maxContentLength, handle);
        if (_connection.stream(streamId).setProperty(_writerKey, writer) != null) {
            _lifecycleManager.onError(ctx, Http2Exception.connectionError(Http2Error.PROTOCOL_ERROR, "Another writer has already been associated with current stream ID", streamId));
            return;
        }
        // Prepares StreamResponse for the channel pipeline
        EntityStream entityStream = EntityStreams.newEntityStream(writer);
        response = builder.build(entityStream);
    }
    // Gets callback from stream properties
    Http2Connection.PropertyKey callbackKey = ctx.channel().attr(Http2ClientPipelineInitializer.CALLBACK_ATTR_KEY).get();
    TransportCallback<?> callback = _connection.stream(streamId).removeProperty(callbackKey);
    if (callback != null) {
        ctx.fireChannelRead(new ResponseWithCallback<Response, TransportCallback<?>>(response, callback));
    }
}
Also used : TransportCallback(com.linkedin.r2.transport.common.bridge.common.TransportCallback) StreamResponseBuilder(com.linkedin.r2.message.stream.StreamResponseBuilder) Http2Connection(io.netty.handler.codec.http2.Http2Connection) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) ByteString(com.linkedin.data.ByteString) EntityStream(com.linkedin.r2.message.stream.entitystream.EntityStream) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) Response(com.linkedin.r2.message.Response) Map(java.util.Map)

Example 39 with TransportCallback

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

the class TestHttpNettyClient method testBadAddress.

@Test
public void testBadAddress() throws InterruptedException, IOException, TimeoutException {
    HttpNettyClient client = new HttpClientBuilder(_eventLoop, _scheduler).setRequestTimeout(30000).setIdleTimeout(10000).setShutdownTimeout(500).buildRest();
    RestRequest r = new RestRequestBuilder(URI.create("http://this.host.does.not.exist.linkedin.com")).build();
    FutureCallback<RestResponse> cb = new FutureCallback<RestResponse>();
    TransportCallback<RestResponse> callback = new TransportCallbackAdapter<RestResponse>(cb);
    client.restRequest(r, new RequestContext(), new HashMap<String, String>(), callback);
    try {
        cb.get(30, TimeUnit.SECONDS);
        Assert.fail("Get was supposed to fail");
    } catch (ExecutionException e) {
        verifyCauseChain(e, RemoteInvocationException.class, UnknownHostException.class);
    }
}
Also used : TransportCallbackAdapter(com.linkedin.r2.transport.common.bridge.client.TransportCallbackAdapter) UnknownHostException(java.net.UnknownHostException) RestResponse(com.linkedin.r2.message.rest.RestResponse) RestRequest(com.linkedin.r2.message.rest.RestRequest) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) RequestContext(com.linkedin.r2.message.RequestContext) RemoteInvocationException(com.linkedin.r2.RemoteInvocationException) ExecutionException(java.util.concurrent.ExecutionException) FutureCallback(com.linkedin.common.callback.FutureCallback) Test(org.testng.annotations.Test)

Example 40 with TransportCallback

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

the class TestHttpNettyClient method testNoResponseTimeout.

@Test
public void testNoResponseTimeout() throws InterruptedException, IOException {
    TestServer testServer = new TestServer();
    HttpNettyClient client = new HttpClientBuilder(_eventLoop, _scheduler).setRequestTimeout(500).setIdleTimeout(10000).setShutdownTimeout(500).buildRest();
    RestRequest r = new RestRequestBuilder(testServer.getNoResponseURI()).build();
    FutureCallback<RestResponse> cb = new FutureCallback<RestResponse>();
    TransportCallback<RestResponse> callback = new TransportCallbackAdapter<RestResponse>(cb);
    client.restRequest(r, new RequestContext(), new HashMap<String, String>(), callback);
    try {
        // This timeout needs to be significantly larger than the getTimeout of the netty client;
        // we're testing that the client will generate its own timeout
        cb.get(30, TimeUnit.SECONDS);
        Assert.fail("Get was supposed to time out");
    } catch (TimeoutException e) {
        // TimeoutException means the timeout for Future.get() elapsed and nothing happened.
        // Instead, we are expecting our callback to be invoked before the future timeout
        // with a timeout generated by the HttpNettyClient.
        Assert.fail("Unexpected TimeoutException, should have been ExecutionException", e);
    } catch (ExecutionException e) {
        verifyCauseChain(e, RemoteInvocationException.class, TimeoutException.class);
    }
    testServer.shutdown();
}
Also used : TransportCallbackAdapter(com.linkedin.r2.transport.common.bridge.client.TransportCallbackAdapter) RestResponse(com.linkedin.r2.message.rest.RestResponse) RestRequest(com.linkedin.r2.message.rest.RestRequest) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) RequestContext(com.linkedin.r2.message.RequestContext) RemoteInvocationException(com.linkedin.r2.RemoteInvocationException) ExecutionException(java.util.concurrent.ExecutionException) FutureCallback(com.linkedin.common.callback.FutureCallback) TimeoutException(java.util.concurrent.TimeoutException) Test(org.testng.annotations.Test)

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