Search in sources :

Example 6 with NettyConnectionContext

use of io.servicetalk.transport.netty.internal.NettyConnectionContext in project servicetalk by apple.

the class FlushStrategyForClientApiTest method aggregatedApiShouldNotOverrideExplicit.

@Test
void aggregatedApiShouldNotOverrideExplicit() throws Exception {
    final StreamingHttpConnection connection = streamingHttpConnection();
    ((NettyConnectionContext) connection.connectionContext()).updateFlushStrategy((prev, isOriginal) -> FlushStrategies.flushOnEach());
    final Single<StreamingHttpResponse> responseSingle = connection.request(connection.asConnection().newRequest(POST, "/").addHeader(TRANSFER_ENCODING, CHUNKED).toStreamingRequest().payloadBody(Publisher.never()));
    // Subscribe, to initiate the request, but we don't care about the response.
    responseSingle.toFuture();
    // Wait for the server to receive the response, meaning the client wrote and flushed.
    requestLatch.await();
}
Also used : NettyConnectionContext(io.servicetalk.transport.netty.internal.NettyConnectionContext) StreamingHttpConnection(io.servicetalk.http.api.StreamingHttpConnection) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse) Test(org.junit.jupiter.api.Test)

Example 7 with NettyConnectionContext

use of io.servicetalk.transport.netty.internal.NettyConnectionContext in project servicetalk by apple.

the class ConnectionFactoryFilterTest method onClosingIsDelegated.

@Test
void onClosingIsDelegated() throws Exception {
    CompletableSource.Processor onClosing = newCompletableProcessor();
    client = clientBuilder.appendConnectionFactoryFilter(newConnectionFactoryFilter(delegate -> new NettyConnectionContextReturningConnection(delegate, onClosing))).buildBlocking();
    ReservedStreamingHttpConnection con = client.asStreamingClient().reserveConnection(client.get("/")).toFuture().get();
    NettyConnectionContext ctx = (NettyConnectionContext) con.connectionContext();
    onClosing.onComplete();
    ctx.onClosing().toFuture().get();
}
Also used : FlushStrategy(io.servicetalk.transport.netty.internal.FlushStrategy) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse) HttpResponseMetaData(io.servicetalk.http.api.HttpResponseMetaData) UnaryOperator(java.util.function.UnaryOperator) Cancellable(io.servicetalk.concurrent.Cancellable) FilterableStreamingHttpConnection(io.servicetalk.http.api.FilterableStreamingHttpConnection) SourceAdapters.fromSource(io.servicetalk.concurrent.api.SourceAdapters.fromSource) ExecutionStrategy(io.servicetalk.transport.api.ExecutionStrategy) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) StreamingHttpRequest(io.servicetalk.http.api.StreamingHttpRequest) AddressUtils.serverHostAndPort(io.servicetalk.transport.netty.internal.AddressUtils.serverHostAndPort) NettyConnectionContext(io.servicetalk.transport.netty.internal.NettyConnectionContext) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) DelegatingConnectionFactory(io.servicetalk.client.api.DelegatingConnectionFactory) Nonnull(javax.annotation.Nonnull) HttpConnectionContext(io.servicetalk.http.api.HttpConnectionContext) Nullable(javax.annotation.Nullable) Processors.newCompletableProcessor(io.servicetalk.concurrent.api.Processors.newCompletableProcessor) BlockingHttpClient(io.servicetalk.http.api.BlockingHttpClient) AddressUtils.localAddress(io.servicetalk.transport.netty.internal.AddressUtils.localAddress) ServerContext(io.servicetalk.transport.api.ServerContext) Single(io.servicetalk.concurrent.api.Single) ConnectionFactoryFilter(io.servicetalk.client.api.ConnectionFactoryFilter) Completable(io.servicetalk.concurrent.api.Completable) CompositeCloseable(io.servicetalk.concurrent.api.CompositeCloseable) HttpResponse(io.servicetalk.http.api.HttpResponse) ReservedBlockingHttpConnection(io.servicetalk.http.api.ReservedBlockingHttpConnection) StreamingHttpConnectionFilter(io.servicetalk.http.api.StreamingHttpConnectionFilter) InetSocketAddress(java.net.InetSocketAddress) CompletableSource(io.servicetalk.concurrent.CompletableSource) SingleAddressHttpClientBuilder(io.servicetalk.http.api.SingleAddressHttpClientBuilder) Channel(io.netty.channel.Channel) Test(org.junit.jupiter.api.Test) CountDownLatch(java.util.concurrent.CountDownLatch) AfterEach(org.junit.jupiter.api.AfterEach) ContextMap(io.servicetalk.context.api.ContextMap) Matchers.equalTo(org.hamcrest.Matchers.equalTo) TransportObserver(io.servicetalk.transport.api.TransportObserver) Matchers.is(org.hamcrest.Matchers.is) AsyncCloseables(io.servicetalk.concurrent.api.AsyncCloseables) ReservedStreamingHttpConnection(io.servicetalk.http.api.ReservedStreamingHttpConnection) DelegatingHttpConnectionContext(io.servicetalk.http.api.DelegatingHttpConnectionContext) HttpResponseStatus(io.servicetalk.http.api.HttpResponseStatus) HostAndPort(io.servicetalk.transport.api.HostAndPort) ReservedStreamingHttpConnection(io.servicetalk.http.api.ReservedStreamingHttpConnection) NettyConnectionContext(io.servicetalk.transport.netty.internal.NettyConnectionContext) CompletableSource(io.servicetalk.concurrent.CompletableSource) Test(org.junit.jupiter.api.Test)

Example 8 with NettyConnectionContext

use of io.servicetalk.transport.netty.internal.NettyConnectionContext in project servicetalk by apple.

the class FlushStrategyOverrideTest method overrideFlush.

@Test
void overrideFlush() throws Throwable {
    NettyConnectionContext nctx = (NettyConnectionContext) conn.connectionContext();
    MockFlushStrategy clientStrategy = new MockFlushStrategy();
    Cancellable c = nctx.updateFlushStrategy((old, isOriginal) -> isOriginal ? clientStrategy : old);
    CountDownLatch reqWritten = new CountDownLatch(1);
    StreamingHttpRequest req = client.get("/flush").payloadBody(from(1, 2, 3).map(count -> ctx.bufferAllocator().fromAscii("" + count)).afterFinally(reqWritten::countDown));
    Future<? extends Collection<Object>> clientResp = conn.request(req).flatMapPublisher(StreamingHttpResponse::messageBody).toFuture();
    // Wait for request to be written.
    reqWritten.await();
    FlushSender clientFlush = clientStrategy.verifyApplied();
    clientStrategy.verifyWriteStarted();
    clientStrategy.verifyItemWritten(5);
    clientStrategy.verifyWriteTerminated();
    clientFlush.flush();
    MockFlushStrategy serverStrategy = service.getLastUsedStrategy();
    FlushSender serverFlush = serverStrategy.verifyApplied();
    serverStrategy.verifyWriteStarted();
    serverStrategy.verifyItemWritten(5);
    serverStrategy.verifyWriteTerminated();
    serverFlush.flush();
    Collection<Object> chunks = clientResp.get();
    assertThat("Unexpected items received.", chunks, hasSize(3));
    // revert to flush on each.
    c.cancel();
    // No more custom strategies.
    Collection<Object> secondReqChunks = conn.request(conn.get("")).flatMapPublisher(StreamingHttpResponse::messageBody).toFuture().get();
    clientStrategy.verifyNoMoreInteractions();
    service.getLastUsedStrategy();
    serverStrategy.verifyNoMoreInteractions();
    assertThat("Unexpected payload for regular flush.", secondReqChunks, empty());
}
Also used : NettyConnectionContext(io.servicetalk.transport.netty.internal.NettyConnectionContext) Cancellable(io.servicetalk.concurrent.Cancellable) FlushSender(io.servicetalk.transport.netty.internal.FlushStrategy.FlushSender) MockFlushStrategy(io.servicetalk.transport.netty.internal.MockFlushStrategy) StreamingHttpRequest(io.servicetalk.http.api.StreamingHttpRequest) CountDownLatch(java.util.concurrent.CountDownLatch) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse) Test(org.junit.jupiter.api.Test)

Example 9 with NettyConnectionContext

use of io.servicetalk.transport.netty.internal.NettyConnectionContext in project servicetalk by apple.

the class RetryRequestWithNonRepeatablePayloadTest method setUp.

private void setUp(HttpProtocol protocol, TestPublisher<Buffer> payloadBody, Queue<Throwable> errors, boolean offloading) {
    protocol(protocol.config);
    ChannelOutboundHandler firstWriteHandler = new FailingFirstWriteHandler();
    connectionFactoryFilter(ConnectionFactoryFilter.withStrategy(factory -> new DelegatingConnectionFactory<InetSocketAddress, FilterableStreamingHttpConnection>(factory) {

        @Override
        public Single<FilterableStreamingHttpConnection> newConnection(InetSocketAddress address, @Nullable ContextMap context, @Nullable TransportObserver observer) {
            return delegate().newConnection(address, context, observer).map(c -> {
                final Channel channel = ((NettyConnectionContext) c.connectionContext()).nettyChannel();
                if (protocol == HTTP_1) {
                    // Insert right before HttpResponseDecoder to avoid seeing failed frames on wire logs
                    channel.pipeline().addBefore(HttpRequestEncoder.class.getSimpleName() + "#0", null, firstWriteHandler);
                } else if (protocol == HTTP_2) {
                    // Insert right before Http2MultiplexHandler to avoid failing connection-level frames and
                    // seeing failed stream frames on frame/wire logs
                    channel.pipeline().addBefore(Http2MultiplexHandler.class.getSimpleName() + "#0", null, firstWriteHandler);
                }
                return new StreamingHttpConnectionFilter(c) {

                    @Override
                    public Single<StreamingHttpResponse> request(StreamingHttpRequest request) {
                        return delegate().request(request).whenOnError(t -> {
                            try {
                                assertThat("Unexpected exception type", t, instanceOf(RetryableException.class));
                                assertThat("Unexpected exception type", t.getCause(), instanceOf(DeliberateException.class));
                                assertThat("Unexpected subscribe to payload body", payloadBody.isSubscribed(), is(false));
                            } catch (Throwable error) {
                                errors.add(error);
                            }
                        });
                    }
                };
            });
        }
    }, ExecutionStrategy.offloadNone()));
    setUp(offloading ? CACHED : IMMEDIATE, offloading ? CACHED_SERVER : IMMEDIATE);
}
Also used : ChannelOutboundHandler(io.netty.channel.ChannelOutboundHandler) TestUtils.assertNoAsyncErrors(io.servicetalk.test.resources.TestUtils.assertNoAsyncErrors) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse) TestPublisher(io.servicetalk.concurrent.api.TestPublisher) DeliberateException(io.servicetalk.concurrent.internal.DeliberateException) FilterableStreamingHttpConnection(io.servicetalk.http.api.FilterableStreamingHttpConnection) Sharable(io.netty.channel.ChannelHandler.Sharable) ArrayList(java.util.ArrayList) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ChannelPromise(io.netty.channel.ChannelPromise) StreamingHttpClient(io.servicetalk.http.api.StreamingHttpClient) ExecutionStrategy(io.servicetalk.transport.api.ExecutionStrategy) StreamingHttpRequest(io.servicetalk.http.api.StreamingHttpRequest) NettyConnectionContext(io.servicetalk.transport.netty.internal.NettyConnectionContext) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) DelegatingConnectionFactory(io.servicetalk.client.api.DelegatingConnectionFactory) DELIBERATE_EXCEPTION(io.servicetalk.concurrent.internal.DeliberateException.DELIBERATE_EXCEPTION) Nullable(javax.annotation.Nullable) CACHED_SERVER(io.servicetalk.http.netty.AbstractNettyHttpServerTest.ExecutorSupplier.CACHED_SERVER) MethodSource(org.junit.jupiter.params.provider.MethodSource) IMMEDIATE(io.servicetalk.http.netty.AbstractNettyHttpServerTest.ExecutorSupplier.IMMEDIATE) ChannelOutboundHandlerAdapter(io.netty.channel.ChannelOutboundHandlerAdapter) ChannelOutboundHandler(io.netty.channel.ChannelOutboundHandler) Single(io.servicetalk.concurrent.api.Single) Collection(java.util.Collection) ConnectionFactoryFilter(io.servicetalk.client.api.ConnectionFactoryFilter) StreamingHttpConnectionFilter(io.servicetalk.http.api.StreamingHttpConnectionFilter) Arguments(org.junit.jupiter.params.provider.Arguments) OK(io.servicetalk.http.api.HttpResponseStatus.OK) InetSocketAddress(java.net.InetSocketAddress) Channel(io.netty.channel.Channel) Matchers.instanceOf(org.hamcrest.Matchers.instanceOf) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) List(java.util.List) Buffer(io.servicetalk.buffer.api.Buffer) CACHED(io.servicetalk.http.netty.AbstractNettyHttpServerTest.ExecutorSupplier.CACHED) ContextMap(io.servicetalk.context.api.ContextMap) RetryableException(io.servicetalk.transport.api.RetryableException) ReferenceCountUtil(io.netty.util.ReferenceCountUtil) TransportObserver(io.servicetalk.transport.api.TransportObserver) LinkedBlockingDeque(java.util.concurrent.LinkedBlockingDeque) Http2MultiplexHandler(io.netty.handler.codec.http2.Http2MultiplexHandler) HTTP_2(io.servicetalk.http.netty.HttpProtocol.HTTP_2) Matchers.is(org.hamcrest.Matchers.is) Queue(java.util.Queue) HTTP_1(io.servicetalk.http.netty.HttpProtocol.HTTP_1) InetSocketAddress(java.net.InetSocketAddress) FilterableStreamingHttpConnection(io.servicetalk.http.api.FilterableStreamingHttpConnection) Channel(io.netty.channel.Channel) TransportObserver(io.servicetalk.transport.api.TransportObserver) ContextMap(io.servicetalk.context.api.ContextMap) NettyConnectionContext(io.servicetalk.transport.netty.internal.NettyConnectionContext) DelegatingConnectionFactory(io.servicetalk.client.api.DelegatingConnectionFactory) Http2MultiplexHandler(io.netty.handler.codec.http2.Http2MultiplexHandler) StreamingHttpConnectionFilter(io.servicetalk.http.api.StreamingHttpConnectionFilter) RetryableException(io.servicetalk.transport.api.RetryableException) StreamingHttpRequest(io.servicetalk.http.api.StreamingHttpRequest) DeliberateException(io.servicetalk.concurrent.internal.DeliberateException) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse) Nullable(javax.annotation.Nullable)

Example 10 with NettyConnectionContext

use of io.servicetalk.transport.netty.internal.NettyConnectionContext in project servicetalk by apple.

the class NettyHttpServerTest method testErrorDuringRead.

@ParameterizedTest(name = "{displayName} [{index}] client={0} server={1}")
@MethodSource("clientExecutors")
void testErrorDuringRead(ExecutorSupplier clientExecutorSupplier, ExecutorSupplier serverExecutorSupplier) throws Exception {
    setUp(clientExecutorSupplier, serverExecutorSupplier);
    ignoreTestWhen(CACHED, IMMEDIATE);
    final StreamingHttpRequest request = reqRespFactory.newRequest(GET, SVC_ERROR_DURING_READ).payloadBody(getChunkPublisherFromStrings("Goodbye", "cruel", "world!"));
    final StreamingHttpResponse response = makeRequest(request);
    assertEquals(OK, response.status());
    assertEquals(HTTP_1_1, response.version());
    final BlockingIterator<Buffer> httpPayloadChunks = response.payloadBody().toIterable().iterator();
    StringBuilder sb = new StringBuilder();
    // the client throws NativeIoException (KQueue) or IOException (NIO).
    try {
        while (httpPayloadChunks.hasNext()) {
            sb.append(httpPayloadChunks.next().toString(US_ASCII));
        }
        fail("Server should close upon receiving the request");
    } catch (Throwable cause) {
        assertClientTransportInboundClosed(cause);
    }
    assertEquals("Goodbyecruelworld!", sb.toString());
    assertConnectionClosed();
    // Client inbound channel closed - should be same exception as above
    Throwable clientThrowable = ((NettyConnectionContext) streamingHttpConnection().connectionContext()).transportError().toFuture().get();
    assertClientTransportInboundClosed(clientThrowable);
    // Server outbound channel force closed (reset)
    Throwable serverThrowable = capturedServiceTransportErrorRef.get().toFuture().get();
    assertThat(serverThrowable, is(DELIBERATE_EXCEPTION));
}
Also used : Buffer(io.servicetalk.buffer.api.Buffer) NettyConnectionContext(io.servicetalk.transport.netty.internal.NettyConnectionContext) StreamingHttpRequest(io.servicetalk.http.api.StreamingHttpRequest) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Aggregations

NettyConnectionContext (io.servicetalk.transport.netty.internal.NettyConnectionContext)11 StreamingHttpResponse (io.servicetalk.http.api.StreamingHttpResponse)8 FilterableStreamingHttpConnection (io.servicetalk.http.api.FilterableStreamingHttpConnection)6 StreamingHttpRequest (io.servicetalk.http.api.StreamingHttpRequest)6 Buffer (io.servicetalk.buffer.api.Buffer)5 Completable (io.servicetalk.concurrent.api.Completable)5 Single (io.servicetalk.concurrent.api.Single)5 Nullable (javax.annotation.Nullable)5 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)5 MethodSource (org.junit.jupiter.params.provider.MethodSource)5 Channel (io.netty.channel.Channel)4 ContextMap (io.servicetalk.context.api.ContextMap)4 HttpExecutionStrategy (io.servicetalk.http.api.HttpExecutionStrategy)4 ConnectionContext (io.servicetalk.transport.api.ConnectionContext)4 CountDownLatch (java.util.concurrent.CountDownLatch)4 Completable.completed (io.servicetalk.concurrent.api.Completable.completed)3 StreamingHttpClient (io.servicetalk.http.api.StreamingHttpClient)3 ServerContext (io.servicetalk.transport.api.ServerContext)3 AddressUtils.localAddress (io.servicetalk.transport.netty.internal.AddressUtils.localAddress)3 AddressUtils.serverHostAndPort (io.servicetalk.transport.netty.internal.AddressUtils.serverHostAndPort)3