Search in sources :

Example 1 with ConnectionContext

use of io.servicetalk.transport.api.ConnectionContext in project servicetalk by apple.

the class GracefulConnectionClosureHandlingTest method setUp.

void setUp(HttpProtocol protocol, boolean initiateClosureFromClient, boolean useUds, boolean viaProxy) throws Exception {
    this.protocol = protocol;
    this.initiateClosureFromClient = initiateClosureFromClient;
    if (useUds) {
        Assumptions.assumeTrue(SERVER_CTX.ioExecutor().isUnixDomainSocketSupported(), "Server's IoExecutor does not support UnixDomainSocket");
        Assumptions.assumeTrue(CLIENT_CTX.ioExecutor().isUnixDomainSocketSupported(), "Client's IoExecutor does not support UnixDomainSocket");
        assumeFalse(viaProxy, "UDS cannot be used via proxy");
    }
    assumeFalse(protocol == HTTP_2 && viaProxy, "Proxy is not supported with HTTP/2");
    HttpServerBuilder serverBuilder = (useUds ? forAddress(newSocketAddress()) : forAddress(localAddress(0))).protocols(protocol.config).ioExecutor(SERVER_CTX.ioExecutor()).executor(SERVER_CTX.executor()).executionStrategy(defaultStrategy()).enableWireLogging("servicetalk-tests-wire-logger", TRACE, () -> true).appendConnectionAcceptorFilter(original -> new DelegatingConnectionAcceptor(original) {

        @Override
        public Completable accept(final ConnectionContext context) {
            if (!initiateClosureFromClient) {
                ((NettyConnectionContext) context).onClosing().whenFinally(onClosing::countDown).subscribe();
            }
            context.onClose().whenFinally(serverConnectionClosed::countDown).subscribe();
            connectionAccepted.countDown();
            return completed();
        }
    });
    HostAndPort proxyAddress = null;
    if (viaProxy) {
        // Dummy proxy helps to emulate old intermediate systems that do not support half-closed TCP connections
        proxyTunnel = new ProxyTunnel();
        proxyAddress = proxyTunnel.startProxy();
        serverBuilder.sslConfig(new ServerSslConfigBuilder(DefaultTestCerts::loadServerPem, DefaultTestCerts::loadServerKey).build());
    } else {
        proxyTunnel = null;
    }
    serverContext = serverBuilder.listenBlockingStreamingAndAwait((ctx, request, response) -> {
        serverReceivedRequest.countDown();
        response.addHeader(CONTENT_LENGTH, valueOf(RESPONSE_CONTENT.length()));
        serverSendResponse.await();
        try (HttpPayloadWriter<String> writer = response.sendMetaData(RAW_STRING_SERIALIZER)) {
            // Subscribe to the request payload body before response writer closes
            BlockingIterator<Buffer> iterator = request.payloadBody().iterator();
            // Consume request payload body asynchronously:
            ctx.executionContext().executor().submit(() -> {
                int receivedSize = 0;
                while (iterator.hasNext()) {
                    Buffer chunk = iterator.next();
                    assert chunk != null;
                    receivedSize += chunk.readableBytes();
                }
                serverReceivedRequestPayload.add(receivedSize);
            }).beforeOnError(cause -> {
                LOGGER.error("failure while reading request", cause);
                serverReceivedRequestPayload.add(-1);
            }).toFuture();
            serverSendResponsePayload.await();
            writer.write(RESPONSE_CONTENT);
        }
    });
    serverContext.onClose().whenFinally(serverContextClosed::countDown).subscribe();
    client = (viaProxy ? forSingleAddress(serverHostAndPort(serverContext)).proxyAddress(proxyAddress).sslConfig(new ClientSslConfigBuilder(DefaultTestCerts::loadServerCAPem).peerHost(serverPemHostname()).build()) : forResolvedAddress(serverContext.listenAddress())).protocols(protocol.config).executor(CLIENT_CTX.executor()).ioExecutor(CLIENT_CTX.ioExecutor()).executionStrategy(defaultStrategy()).enableWireLogging("servicetalk-tests-wire-logger", TRACE, Boolean.TRUE::booleanValue).appendConnectionFactoryFilter(ConnectionFactoryFilter.withStrategy(cf -> initiateClosureFromClient ? new OnClosingConnectionFactoryFilter<>(cf, onClosing) : cf, ExecutionStrategy.offloadNone())).buildStreaming();
    connection = client.reserveConnection(client.get("/")).toFuture().get();
    connection.onClose().whenFinally(clientConnectionClosed::countDown).subscribe();
    // wait until server accepts connection
    connectionAccepted.await();
    toClose = initiateClosureFromClient ? connection : serverContext;
}
Also used : SocketAddress(java.net.SocketAddress) HttpProtocol.values(io.servicetalk.http.netty.HttpProtocol.values) PlatformDependent.throwException(io.servicetalk.utils.internal.PlatformDependent.throwException) ServerSslConfigBuilder(io.servicetalk.transport.api.ServerSslConfigBuilder) LoggerFactory(org.slf4j.LoggerFactory) HttpSerializers.stringStreamingSerializer(io.servicetalk.http.api.HttpSerializers.stringStreamingSerializer) ZERO(io.servicetalk.http.api.HttpHeaderValues.ZERO) Future(java.util.concurrent.Future) CloseEvent(io.servicetalk.transport.netty.internal.CloseHandler.CloseEvent) HttpExecutionStrategies.defaultStrategy(io.servicetalk.http.api.HttpExecutionStrategies.defaultStrategy) StreamingHttpClient(io.servicetalk.http.api.StreamingHttpClient) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Arrays.asList(java.util.Arrays.asList) Assumptions.assumeFalse(org.junit.jupiter.api.Assumptions.assumeFalse) DefaultTestCerts(io.servicetalk.test.resources.DefaultTestCerts) MethodSource(org.junit.jupiter.params.provider.MethodSource) GRACEFUL_USER_CLOSING(io.servicetalk.transport.netty.internal.CloseHandler.CloseEvent.GRACEFUL_USER_CLOSING) Matchers.notNullValue(org.hamcrest.Matchers.notNullValue) Collection(java.util.Collection) HttpClients.forSingleAddress(io.servicetalk.http.netty.HttpClients.forSingleAddress) ConnectionFactoryFilter(io.servicetalk.client.api.ConnectionFactoryFilter) CompositeCloseable(io.servicetalk.concurrent.api.CompositeCloseable) CHANNEL_CLOSED_INBOUND(io.servicetalk.transport.netty.internal.CloseHandler.CloseEvent.CHANNEL_CLOSED_INBOUND) BlockingQueue(java.util.concurrent.BlockingQueue) AsyncCloseables.newCompositeCloseable(io.servicetalk.concurrent.api.AsyncCloseables.newCompositeCloseable) Arguments(org.junit.jupiter.params.provider.Arguments) CONTENT_LENGTH(io.servicetalk.http.api.HttpHeaderNames.CONTENT_LENGTH) HttpClients.forResolvedAddress(io.servicetalk.http.netty.HttpClients.forResolvedAddress) DefaultTestCerts.serverPemHostname(io.servicetalk.test.resources.DefaultTestCerts.serverPemHostname) Matchers.instanceOf(org.hamcrest.Matchers.instanceOf) ArrayBlockingQueue(java.util.concurrent.ArrayBlockingQueue) CountDownLatch(java.util.concurrent.CountDownLatch) HttpsProxyTest.safeClose(io.servicetalk.http.netty.HttpsProxyTest.safeClose) Buffer(io.servicetalk.buffer.api.Buffer) DelegatingConnectionAcceptor(io.servicetalk.transport.api.DelegatingConnectionAcceptor) TransportObserver(io.servicetalk.transport.api.TransportObserver) ClientSslConfigBuilder(io.servicetalk.transport.api.ClientSslConfigBuilder) HTTP_2(io.servicetalk.http.netty.HttpProtocol.HTTP_2) Matchers.is(org.hamcrest.Matchers.is) BlockingIterator(io.servicetalk.concurrent.BlockingIterator) ReservedStreamingHttpConnection(io.servicetalk.http.api.ReservedStreamingHttpConnection) Matchers.anyOf(org.hamcrest.Matchers.anyOf) Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse) TRACE(io.servicetalk.logging.api.LogLevel.TRACE) HttpServers.forAddress(io.servicetalk.http.netty.HttpServers.forAddress) FilterableStreamingHttpConnection(io.servicetalk.http.api.FilterableStreamingHttpConnection) ArrayList(java.util.ArrayList) HttpPayloadWriter(io.servicetalk.http.api.HttpPayloadWriter) ExecutionStrategy(io.servicetalk.transport.api.ExecutionStrategy) RegisterExtension(org.junit.jupiter.api.extension.RegisterExtension) CloseEventObservedException(io.servicetalk.transport.netty.internal.CloseHandler.CloseEventObservedException) Objects.requireNonNull(java.util.Objects.requireNonNull) StreamingHttpRequest(io.servicetalk.http.api.StreamingHttpRequest) AddressUtils.serverHostAndPort(io.servicetalk.transport.netty.internal.AddressUtils.serverHostAndPort) AsyncCloseable(io.servicetalk.concurrent.api.AsyncCloseable) NettyConnectionContext(io.servicetalk.transport.netty.internal.NettyConnectionContext) Matchers.contentEqualTo(io.servicetalk.buffer.api.Matchers.contentEqualTo) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) DelegatingConnectionFactory(io.servicetalk.client.api.DelegatingConnectionFactory) Publisher.from(io.servicetalk.concurrent.api.Publisher.from) HttpServerBuilder(io.servicetalk.http.api.HttpServerBuilder) Nullable(javax.annotation.Nullable) ConnectionContext(io.servicetalk.transport.api.ConnectionContext) ConnectionFactory(io.servicetalk.client.api.ConnectionFactory) AddressUtils.localAddress(io.servicetalk.transport.netty.internal.AddressUtils.localAddress) Logger(org.slf4j.Logger) AddressUtils.newSocketAddress(io.servicetalk.transport.netty.internal.AddressUtils.newSocketAddress) ServerContext(io.servicetalk.transport.api.ServerContext) ClosedChannelException(java.nio.channels.ClosedChannelException) UTF_8(java.nio.charset.StandardCharsets.UTF_8) Single(io.servicetalk.concurrent.api.Single) Completable(io.servicetalk.concurrent.api.Completable) ExecutionContextExtension(io.servicetalk.transport.netty.internal.ExecutionContextExtension) IOException(java.io.IOException) OK(io.servicetalk.http.api.HttpResponseStatus.OK) Integer.parseInt(java.lang.Integer.parseInt) ExecutionException(java.util.concurrent.ExecutionException) AfterEach(org.junit.jupiter.api.AfterEach) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) String.valueOf(java.lang.String.valueOf) Assumptions(org.junit.jupiter.api.Assumptions) Executable(org.junit.jupiter.api.function.Executable) Completable.completed(io.servicetalk.concurrent.api.Completable.completed) HttpStreamingSerializer(io.servicetalk.http.api.HttpStreamingSerializer) HostAndPort(io.servicetalk.transport.api.HostAndPort) Buffer(io.servicetalk.buffer.api.Buffer) Completable(io.servicetalk.concurrent.api.Completable) HttpServerBuilder(io.servicetalk.http.api.HttpServerBuilder) DelegatingConnectionAcceptor(io.servicetalk.transport.api.DelegatingConnectionAcceptor) DefaultTestCerts(io.servicetalk.test.resources.DefaultTestCerts) ClientSslConfigBuilder(io.servicetalk.transport.api.ClientSslConfigBuilder) AddressUtils.serverHostAndPort(io.servicetalk.transport.netty.internal.AddressUtils.serverHostAndPort) HostAndPort(io.servicetalk.transport.api.HostAndPort) NettyConnectionContext(io.servicetalk.transport.netty.internal.NettyConnectionContext) ConnectionContext(io.servicetalk.transport.api.ConnectionContext) HttpPayloadWriter(io.servicetalk.http.api.HttpPayloadWriter) BlockingIterator(io.servicetalk.concurrent.BlockingIterator) ServerSslConfigBuilder(io.servicetalk.transport.api.ServerSslConfigBuilder)

Example 2 with ConnectionContext

use of io.servicetalk.transport.api.ConnectionContext in project servicetalk by apple.

the class H2PriorKnowledgeFeatureParityTest method bindHttpEchoServer.

private InetSocketAddress bindHttpEchoServer(@Nullable StreamingHttpServiceFilterFactory filterFactory, @Nullable CountDownLatch connectionOnClosingLatch) throws Exception {
    HttpServerBuilder serverBuilder = HttpServers.forAddress(localAddress(0)).protocols(h2PriorKnowledge ? h2Default() : h1Default());
    if (filterFactory != null) {
        serverBuilder.appendServiceFilter(filterFactory);
    }
    if (connectionOnClosingLatch != null) {
        serverBuilder.appendConnectionAcceptorFilter(original -> new DelegatingConnectionAcceptor(original) {

            @Override
            public Completable accept(final ConnectionContext context) {
                ((NettyConnectionContext) context).onClosing().whenFinally(connectionOnClosingLatch::countDown).subscribe();
                return completed();
            }
        });
    }
    h1ServerContext = serverBuilder.listenStreaming((ctx, request, responseFactory) -> {
        StreamingHttpResponse resp;
        if (request.headers().contains(EXPECT, CONTINUE)) {
            if (request.headers().contains(EXPECT_FAIL_HEADER)) {
                return succeeded(responseFactory.expectationFailed());
            } else {
                resp = responseFactory.continueResponse();
            }
        } else {
            resp = responseFactory.ok();
        }
        resp = resp.transformMessageBody(pub -> pub.ignoreElements().merge(request.messageBody())).transform(new StatelessTrailersTransformer<>());
        CharSequence contentType = request.headers().get(CONTENT_TYPE);
        if (contentType != null) {
            resp.setHeader(CONTENT_TYPE, contentType);
        }
        CharSequence contentLength = request.headers().get(CONTENT_LENGTH);
        if (contentLength != null) {
            resp.setHeader(CONTENT_LENGTH, contentLength);
        }
        CharSequence transferEncoding = request.headers().get(TRANSFER_ENCODING);
        if (transferEncoding != null) {
            resp.setHeader(TRANSFER_ENCODING, transferEncoding);
        }
        resp.headers().set(COOKIE, request.headers().valuesIterator(COOKIE));
        return succeeded(resp);
    }).toFuture().get();
    return (InetSocketAddress) h1ServerContext.listenAddress();
}
Also used : TestUtils.assertNoAsyncErrors(io.servicetalk.test.resources.TestUtils.assertNoAsyncErrors) UnaryOperator.identity(java.util.function.UnaryOperator.identity) ChannelInboundHandlerAdapter(io.netty.channel.ChannelInboundHandlerAdapter) SingleSource(io.servicetalk.concurrent.SingleSource) StreamingHttpServiceFilterFactory(io.servicetalk.http.api.StreamingHttpServiceFilterFactory) UnaryOperator(java.util.function.UnaryOperator) DefaultHttp2DataFrame(io.netty.handler.codec.http2.DefaultHttp2DataFrame) Disabled(org.junit.jupiter.api.Disabled) Matchers.hasItems(org.hamcrest.Matchers.hasItems) SourceAdapters.fromSource(io.servicetalk.concurrent.api.SourceAdapters.fromSource) H2StreamResetException(io.servicetalk.http.netty.NettyHttp2ExceptionUtils.H2StreamResetException) AsyncContext(io.servicetalk.concurrent.api.AsyncContext) HttpRequest(io.servicetalk.http.api.HttpRequest) Assumptions.assumeFalse(org.junit.jupiter.api.Assumptions.assumeFalse) Matchers.nullValue(org.hamcrest.Matchers.nullValue) HttpCookiePair(io.servicetalk.http.api.HttpCookiePair) EXPECT(io.servicetalk.http.api.HttpHeaderNames.EXPECT) BlockingHttpClient(io.servicetalk.http.api.BlockingHttpClient) PrintWriter(java.io.PrintWriter) Matchers.notNullValue(org.hamcrest.Matchers.notNullValue) DefaultHttp2SettingsFrame(io.netty.handler.codec.http2.DefaultHttp2SettingsFrame) HttpClients.forSingleAddress(io.servicetalk.http.netty.HttpClients.forSingleAddress) HttpResponse(io.servicetalk.http.api.HttpResponse) Http2SettingsAckFrame(io.netty.handler.codec.http2.Http2SettingsAckFrame) TRANSFER_ENCODING(io.servicetalk.http.api.HttpHeaderNames.TRANSFER_ENCODING) POST(io.servicetalk.http.api.HttpRequestMethod.POST) BlockingQueue(java.util.concurrent.BlockingQueue) ChannelPipeline(io.netty.channel.ChannelPipeline) MILLISECONDS(java.util.concurrent.TimeUnit.MILLISECONDS) StatelessTrailersTransformer(io.servicetalk.http.api.StatelessTrailersTransformer) StreamingHttpClientFilter(io.servicetalk.http.api.StreamingHttpClientFilter) StreamingHttpConnectionFilter(io.servicetalk.http.api.StreamingHttpConnectionFilter) Arguments(org.junit.jupiter.params.provider.Arguments) Assertions.assertNotSame(org.junit.jupiter.api.Assertions.assertNotSame) Http2HeadersFrame(io.netty.handler.codec.http2.Http2HeadersFrame) CountDownLatch(java.util.concurrent.CountDownLatch) HttpSetCookie(io.servicetalk.http.api.HttpSetCookie) Buffer(io.servicetalk.buffer.api.Buffer) Stream(java.util.stream.Stream) Http2Headers(io.netty.handler.codec.http2.Http2Headers) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) COOKIE(io.servicetalk.http.api.HttpHeaderNames.COOKIE) Matchers.is(org.hamcrest.Matchers.is) CONTENT_TYPE(io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE) Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) Processor(io.servicetalk.concurrent.PublisherSource.Processor) BuilderUtils.serverChannel(io.servicetalk.transport.netty.internal.BuilderUtils.serverChannel) TRAILER(io.netty.handler.codec.http.HttpHeaderNames.TRAILER) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) HttpHeaders(io.servicetalk.http.api.HttpHeaders) ConsumableEvent(io.servicetalk.client.api.ConsumableEvent) StreamingHttpRequester(io.servicetalk.http.api.StreamingHttpRequester) FilterableStreamingHttpConnection(io.servicetalk.http.api.FilterableStreamingHttpConnection) ArrayList(java.util.ArrayList) EMPTY_BUFFER(io.servicetalk.buffer.api.EmptyBuffer.EMPTY_BUFFER) MAX_CONCURRENCY(io.servicetalk.http.api.HttpEventKey.MAX_CONCURRENCY) HeaderUtils.isTransferEncodingChunked(io.servicetalk.http.api.HeaderUtils.isTransferEncodingChunked) HttpServiceContext(io.servicetalk.http.api.HttpServiceContext) Single.succeeded(io.servicetalk.concurrent.api.Single.succeeded) Processors(io.servicetalk.concurrent.api.Processors) BiConsumer(java.util.function.BiConsumer) Assumptions.assumeTrue(org.junit.jupiter.api.Assumptions.assumeTrue) StreamingHttpRequest(io.servicetalk.http.api.StreamingHttpRequest) Matchers.contentEqualTo(io.servicetalk.buffer.api.Matchers.contentEqualTo) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) Nullable(javax.annotation.Nullable) SMALLEST_MAX_CONCURRENT_STREAMS(io.netty.handler.codec.http2.Http2CodecUtil.SMALLEST_MAX_CONCURRENT_STREAMS) DEFAULT(io.servicetalk.http.netty.HttpTestExecutionStrategy.DEFAULT) Single(io.servicetalk.concurrent.api.Single) StringWriter(java.io.StringWriter) Completable(io.servicetalk.concurrent.api.Completable) DefaultHttp2HeadersFrame(io.netty.handler.codec.http2.DefaultHttp2HeadersFrame) IOException(java.io.IOException) ReservedBlockingHttpConnection(io.servicetalk.http.api.ReservedBlockingHttpConnection) OK(io.servicetalk.http.api.HttpResponseStatus.OK) GET(io.servicetalk.http.api.HttpRequestMethod.GET) Channel(io.netty.channel.Channel) Http2Settings(io.netty.handler.codec.http2.Http2Settings) AfterEach(org.junit.jupiter.api.AfterEach) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) String.valueOf(java.lang.String.valueOf) Completable.completed(io.servicetalk.concurrent.api.Completable.completed) Http2MultiplexHandler(io.netty.handler.codec.http2.Http2MultiplexHandler) HttpHeaderNames(io.netty.handler.codec.http.HttpHeaderNames) HttpResponseStatus(io.servicetalk.http.api.HttpResponseStatus) HostAndPort(io.servicetalk.transport.api.HostAndPort) HttpRequestMethod(io.servicetalk.http.api.HttpRequestMethod) Matchers.emptyString(org.hamcrest.Matchers.emptyString) Http2FrameCodecBuilder(io.netty.handler.codec.http2.Http2FrameCodecBuilder) Key.newKey(io.servicetalk.context.api.ContextMap.Key.newKey) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) StreamingHttpClient(io.servicetalk.http.api.StreamingHttpClient) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Http2DataFrame(io.netty.handler.codec.http2.Http2DataFrame) MethodSource(org.junit.jupiter.params.provider.MethodSource) ChannelDuplexHandler(io.netty.channel.ChannelDuplexHandler) ChannelInitializer(io.netty.channel.ChannelInitializer) PublisherSource(io.servicetalk.concurrent.PublisherSource) CONTENT_LENGTH(io.servicetalk.http.api.HttpHeaderNames.CONTENT_LENGTH) InetSocketAddress(java.net.InetSocketAddress) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) HttpEventKey(io.servicetalk.http.api.HttpEventKey) List(java.util.List) ContextMap(io.servicetalk.context.api.ContextMap) DelegatingConnectionAcceptor(io.servicetalk.transport.api.DelegatingConnectionAcceptor) Matchers.equalTo(org.hamcrest.Matchers.equalTo) Writer(java.io.Writer) Queue(java.util.Queue) CONTINUE(io.servicetalk.http.api.HttpHeaderValues.CONTINUE) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse) Publisher(io.servicetalk.concurrent.api.Publisher) Http2Exception(io.servicetalk.http.api.Http2Exception) AtomicReference(java.util.concurrent.atomic.AtomicReference) StreamingHttpServiceFilter(io.servicetalk.http.api.StreamingHttpServiceFilter) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) HttpProtocolConfigs.h1Default(io.servicetalk.http.netty.HttpProtocolConfigs.h1Default) HttpProtocolConfigs.h2Default(io.servicetalk.http.netty.HttpProtocolConfigs.h2Default) HttpSerializers.textSerializerUtf8(io.servicetalk.http.api.HttpSerializers.textSerializerUtf8) HttpExecutionStrategy(io.servicetalk.http.api.HttpExecutionStrategy) NettyConnectionContext(io.servicetalk.transport.netty.internal.NettyConnectionContext) DELIBERATE_EXCEPTION(io.servicetalk.concurrent.internal.DeliberateException.DELIBERATE_EXCEPTION) HttpServerBuilder(io.servicetalk.http.api.HttpServerBuilder) ConnectionContext(io.servicetalk.transport.api.ConnectionContext) INTERNAL_SERVER_ERROR(io.servicetalk.http.api.HttpResponseStatus.INTERNAL_SERVER_ERROR) AddressUtils.localAddress(io.servicetalk.transport.netty.internal.AddressUtils.localAddress) EventLoopGroup(io.netty.channel.EventLoopGroup) ServerContext(io.servicetalk.transport.api.ServerContext) Iterator(java.util.Iterator) EXPECTATION_FAILED(io.servicetalk.http.api.HttpResponseStatus.EXPECTATION_FAILED) NettyIoExecutors.createIoExecutor(io.servicetalk.transport.netty.internal.NettyIoExecutors.createIoExecutor) UTF_8(java.nio.charset.StandardCharsets.UTF_8) Processors.newPublisherProcessor(io.servicetalk.concurrent.api.Processors.newPublisherProcessor) Consumer(java.util.function.Consumer) Matchers.emptyIterable(org.hamcrest.Matchers.emptyIterable) StreamingHttpResponseFactory(io.servicetalk.http.api.StreamingHttpResponseFactory) NO_OFFLOAD(io.servicetalk.http.netty.HttpTestExecutionStrategy.NO_OFFLOAD) ServerBootstrap(io.netty.bootstrap.ServerBootstrap) ChannelHandler(io.netty.channel.ChannelHandler) SET_COOKIE(io.servicetalk.http.api.HttpHeaderNames.SET_COOKIE) DefaultHttpCookiePair(io.servicetalk.http.api.DefaultHttpCookiePair) DefaultHttp2Headers(io.netty.handler.codec.http2.DefaultHttp2Headers) Completable(io.servicetalk.concurrent.api.Completable) InetSocketAddress(java.net.InetSocketAddress) HttpServerBuilder(io.servicetalk.http.api.HttpServerBuilder) DelegatingConnectionAcceptor(io.servicetalk.transport.api.DelegatingConnectionAcceptor) NettyConnectionContext(io.servicetalk.transport.netty.internal.NettyConnectionContext) ConnectionContext(io.servicetalk.transport.api.ConnectionContext) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse)

Example 3 with ConnectionContext

use of io.servicetalk.transport.api.ConnectionContext in project servicetalk by apple.

the class MalformedDataAfterHttpMessageTest method afterResponseNextClientRequestSucceeds.

@ParameterizedTest
@ValueSource(booleans = { true, false })
void afterResponseNextClientRequestSucceeds(boolean doOffloading) throws Exception {
    Queue<ConnectionContext> contextQueue = new LinkedBlockingQueue<>();
    ServerSocketChannel server = nettyServer(RESPONSE_MSG);
    try (BlockingHttpClient client = stClientBuilder(server.localAddress()).executionStrategy(doOffloading ? defaultStrategy() : offloadNever()).appendClientFilter(new RetryingHttpRequesterFilter.Builder().retryOther((req, cause) -> ofConstantBackoffFullJitter(ofNanos(1), MAX_VALUE)).build()).appendConnectionFilter(connection -> new StreamingHttpConnectionFilter(connection) {

        @Override
        public Single<StreamingHttpResponse> request(final StreamingHttpRequest request) {
            contextQueue.add(connectionContext());
            return super.request(request);
        }
    }).buildBlocking()) {
        validateClientResponse(client.request(client.get("/1")));
        validateClientResponse(client.request(client.get("/2")));
        ConnectionContext ctx1 = contextQueue.poll();
        assertThat(ctx1, not(nullValue()));
        // RetryingHttpRequesterFilter or AutoRetry may re-issue the request if a failure is seen locally. Verify
        // the last connection (used for second request) is different from the first.
        ConnectionContext ctx2 = null;
        ConnectionContext tmp;
        while ((tmp = contextQueue.poll()) != null) {
            ctx2 = tmp;
        }
        assertThat(ctx2, not(nullValue()));
        assertThat(ctx1, not(equalTo(ctx2)));
        assertThat(contextQueue, empty());
    } finally {
        server.close().sync();
    }
}
Also used : ReferenceCountUtil.release(io.netty.util.ReferenceCountUtil.release) SocketAddress(java.net.SocketAddress) ChannelInboundHandlerAdapter(io.netty.channel.ChannelInboundHandlerAdapter) MAX_VALUE(java.lang.Integer.MAX_VALUE) Matchers.not(org.hamcrest.Matchers.not) CONTENT_TYPE(io.servicetalk.http.api.HttpHeaderNames.CONTENT_TYPE) HttpExecutionStrategies.defaultStrategy(io.servicetalk.http.api.HttpExecutionStrategies.defaultStrategy) HttpRequest(io.servicetalk.http.api.HttpRequest) Matchers.nullValue(org.hamcrest.Matchers.nullValue) BlockingHttpClient(io.servicetalk.http.api.BlockingHttpClient) DecoderException(io.netty.handler.codec.DecoderException) ChannelInitializer(io.netty.channel.ChannelInitializer) HttpClients.forSingleAddress(io.servicetalk.http.netty.HttpClients.forSingleAddress) HttpResponse(io.servicetalk.http.api.HttpResponse) StreamingHttpConnectionFilter(io.servicetalk.http.api.StreamingHttpConnectionFilter) CONTENT_LENGTH(io.servicetalk.http.api.HttpHeaderNames.CONTENT_LENGTH) FullHttpRequest(io.netty.handler.codec.http.FullHttpRequest) InetSocketAddress(java.net.InetSocketAddress) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) Test(org.junit.jupiter.api.Test) Matchers.instanceOf(org.hamcrest.Matchers.instanceOf) CountDownLatch(java.util.concurrent.CountDownLatch) Buffer(io.servicetalk.buffer.api.Buffer) Matchers.equalTo(org.hamcrest.Matchers.equalTo) Matchers.is(org.hamcrest.Matchers.is) Queue(java.util.Queue) Matchers.anyOf(org.hamcrest.Matchers.anyOf) BackOffPolicy.ofConstantBackoffFullJitter(io.servicetalk.http.netty.RetryingHttpRequesterFilter.BackOffPolicy.ofConstantBackoffFullJitter) Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse) TRACE(io.servicetalk.logging.api.LogLevel.TRACE) BuilderUtils.serverChannel(io.servicetalk.transport.netty.internal.BuilderUtils.serverChannel) ByteBufUtil.writeAscii(io.netty.buffer.ByteBufUtil.writeAscii) HttpServers.forAddress(io.servicetalk.http.netty.HttpServers.forAddress) ServerSocketChannel(io.netty.channel.socket.ServerSocketChannel) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) Duration.ofNanos(java.time.Duration.ofNanos) HostAndPort.of(io.servicetalk.transport.api.HostAndPort.of) RegisterExtension(org.junit.jupiter.api.extension.RegisterExtension) HttpSerializers.textSerializerUtf8(io.servicetalk.http.api.HttpSerializers.textSerializerUtf8) StreamingHttpRequest(io.servicetalk.http.api.StreamingHttpRequest) Matchers.contentEqualTo(io.servicetalk.buffer.api.Matchers.contentEqualTo) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) ConnectionContext(io.servicetalk.transport.api.ConnectionContext) ValueSource(org.junit.jupiter.params.provider.ValueSource) AddressUtils.localAddress(io.servicetalk.transport.netty.internal.AddressUtils.localAddress) Matchers.empty(org.hamcrest.Matchers.empty) EventLoopGroup(io.netty.channel.EventLoopGroup) ServerContext(io.servicetalk.transport.api.ServerContext) EventLoopAwareNettyIoExecutors.toEventLoopAwareNettyIoExecutor(io.servicetalk.transport.netty.internal.EventLoopAwareNettyIoExecutors.toEventLoopAwareNettyIoExecutor) ClosedChannelException(java.nio.channels.ClosedChannelException) Single(io.servicetalk.concurrent.api.Single) ExecutionContextExtension(io.servicetalk.transport.netty.internal.ExecutionContextExtension) IOException(java.io.IOException) ReservedBlockingHttpConnection(io.servicetalk.http.api.ReservedBlockingHttpConnection) OK(io.servicetalk.http.api.HttpResponseStatus.OK) SingleAddressHttpClientBuilder(io.servicetalk.http.api.SingleAddressHttpClientBuilder) Channel(io.netty.channel.Channel) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) String.valueOf(java.lang.String.valueOf) ServerBootstrap(io.netty.bootstrap.ServerBootstrap) HttpRequestDecoder(io.netty.handler.codec.http.HttpRequestDecoder) TEXT_PLAIN(io.servicetalk.http.api.HttpHeaderValues.TEXT_PLAIN) HttpObjectAggregator(io.netty.handler.codec.http.HttpObjectAggregator) HostAndPort(io.servicetalk.transport.api.HostAndPort) HttpExecutionStrategies.offloadNever(io.servicetalk.http.api.HttpExecutionStrategies.offloadNever) StreamingHttpConnectionFilter(io.servicetalk.http.api.StreamingHttpConnectionFilter) BlockingHttpClient(io.servicetalk.http.api.BlockingHttpClient) ConnectionContext(io.servicetalk.transport.api.ConnectionContext) StreamingHttpRequest(io.servicetalk.http.api.StreamingHttpRequest) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse) ServerSocketChannel(io.netty.channel.socket.ServerSocketChannel) ValueSource(org.junit.jupiter.params.provider.ValueSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 4 with ConnectionContext

use of io.servicetalk.transport.api.ConnectionContext in project servicetalk by apple.

the class ConnectionAcceptorFilterTest method testAppend.

@Test
void testAppend() throws Exception {
    Deque<Integer> createOrder = new ArrayDeque<>();
    Deque<Integer> connectOrder = new ArrayDeque<>();
    class AcceptorOrder implements ConnectionAcceptor {

        final int order;

        ConnectionAcceptor original;

        AcceptorOrder(int order, ConnectionAcceptor original) {
            this.order = order;
            this.original = original;
        }

        @Override
        public Completable accept(ConnectionContext context) {
            connectOrder.add(order);
            return original.accept(context);
        }

        @Override
        public Completable closeAsync() {
            return Completable.completed();
        }
    }
    class FilterOrder implements ConnectionAcceptorFactory {

        final int order;

        FilterOrder(int order) {
            this.order = order;
        }

        @Override
        public ConnectionAcceptor create(ConnectionAcceptor original) {
            createOrder.add(order);
            return new AcceptorOrder(order, original);
        }
    }
    FilterOrder first = new FilterOrder(1);
    FilterOrder second = new FilterOrder(2);
    ConnectionAcceptorFactory combined = first.append(second);
    ConnectionAcceptor acceptor = combined.create(ConnectionAcceptor.ACCEPT_ALL);
    @SuppressWarnings("unused") Void nothing = acceptor.accept(mock(ConnectionContext.class)).toFuture().get();
    assertThat(nothing, is(nullValue()));
    assertThat(createOrder, is(hasSize(2)));
    assertThat(createOrder, is(containsInRelativeOrder(2, 1)));
    assertThat(connectOrder, is(hasSize(2)));
    assertThat(connectOrder, is(containsInRelativeOrder(1, 2)));
}
Also used : ConnectionAcceptor(io.servicetalk.transport.api.ConnectionAcceptor) ConnectionContext(io.servicetalk.transport.api.ConnectionContext) ConnectionAcceptorFactory(io.servicetalk.transport.api.ConnectionAcceptorFactory) ArrayDeque(java.util.ArrayDeque) Test(org.junit.jupiter.api.Test)

Example 5 with ConnectionContext

use of io.servicetalk.transport.api.ConnectionContext in project servicetalk by apple.

the class DefaultJerseyStreamingHttpRouter method handle0.

private void handle0(final HttpServiceContext serviceCtx, final StreamingHttpRequest req, final StreamingHttpResponseFactory factory, final Subscriber<? super StreamingHttpResponse> subscriber, final DelayedCancellable delayedCancellable) {
    final CharSequence baseUri = baseUriFunction.apply(serviceCtx, req);
    final CharSequence requestTarget = req.requestTarget();
    final StringBuilder requestUriBuilder = new StringBuilder(baseUri.length() + requestTarget.length()).append(baseUri);
    // Jersey expects the baseUri ends in a '/' and if not will return 404s
    assert baseUri.length() == 0 || baseUri.charAt(baseUri.length() - 1) == '/';
    if (requestTarget.length() > 0 && requestTarget.charAt(0) == '/') {
        requestUriBuilder.append(requestTarget, 1, requestTarget.length());
    } else {
        requestUriBuilder.append(requestTarget);
    }
    final URI baseURI;
    final URI requestURI;
    try {
        baseURI = URI.create(baseUri.toString());
        requestURI = URI.create(requestUriBuilder.toString());
    } catch (IllegalArgumentException cause) {
        Buffer message = serviceCtx.executionContext().bufferAllocator().fromAscii(cause.getMessage());
        StreamingHttpResponse response = factory.badRequest().payloadBody(from(message));
        response.headers().set(CONTENT_LENGTH, Integer.toString(message.readableBytes()));
        response.headers().set(CONTENT_TYPE, TEXT_PLAIN);
        subscriber.onSuccess(response);
        return;
    }
    final ContainerRequest containerRequest = new CloseSignalHandoffAbleContainerRequest(baseURI, requestURI, req.method().name(), UNAUTHENTICATED_SECURITY_CONTEXT, new MapPropertiesDelegate(), new ResourceConfig());
    req.headers().forEach(h -> containerRequest.getHeaders().add(h.getKey().toString(), h.getValue().toString()));
    final BufferPublisherInputStream entityStream = new BufferPublisherInputStream(req.payloadBody(), publisherInputStreamQueueCapacity);
    containerRequest.setEntityStream(entityStream);
    initRequestProperties(entityStream, containerRequest);
    final DefaultContainerResponseWriter responseWriter = new DefaultContainerResponseWriter(containerRequest, req.version(), serviceCtx, factory, subscriber);
    containerRequest.setWriter(responseWriter);
    containerRequest.setRequestScopedInitializer(injectionManager -> {
        injectionManager.<Ref<ConnectionContext>>getInstance(CONNECTION_CONTEXT_REF_TYPE).set(serviceCtx);
        injectionManager.<Ref<StreamingHttpRequest>>getInstance(HTTP_REQUEST_REF_TYPE).set(req);
    });
    delayedCancellable.delayedCancellable(responseWriter::dispose);
    applicationHandler.handle(containerRequest);
}
Also used : Buffer(io.servicetalk.buffer.api.Buffer) BufferPublisherInputStream(io.servicetalk.http.router.jersey.internal.BufferPublisherInputStream) URI(java.net.URI) MapPropertiesDelegate(org.glassfish.jersey.internal.MapPropertiesDelegate) ContainerRequest(org.glassfish.jersey.server.ContainerRequest) ResourceConfig(org.glassfish.jersey.server.ResourceConfig) ConnectionContext(io.servicetalk.transport.api.ConnectionContext) StreamingHttpRequest(io.servicetalk.http.api.StreamingHttpRequest) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse)

Aggregations

ConnectionContext (io.servicetalk.transport.api.ConnectionContext)8 Completable (io.servicetalk.concurrent.api.Completable)5 Buffer (io.servicetalk.buffer.api.Buffer)4 CONTENT_LENGTH (io.servicetalk.http.api.HttpHeaderNames.CONTENT_LENGTH)4 StreamingHttpRequest (io.servicetalk.http.api.StreamingHttpRequest)4 StreamingHttpResponse (io.servicetalk.http.api.StreamingHttpResponse)4 ServerContext (io.servicetalk.transport.api.ServerContext)4 AddressUtils.localAddress (io.servicetalk.transport.netty.internal.AddressUtils.localAddress)4 String.valueOf (java.lang.String.valueOf)4 CountDownLatch (java.util.concurrent.CountDownLatch)4 Matchers.contentEqualTo (io.servicetalk.buffer.api.Matchers.contentEqualTo)3 Completable.completed (io.servicetalk.concurrent.api.Completable.completed)3 Single (io.servicetalk.concurrent.api.Single)3 FilterableStreamingHttpConnection (io.servicetalk.http.api.FilterableStreamingHttpConnection)3 OK (io.servicetalk.http.api.HttpResponseStatus.OK)3 HttpClients.forSingleAddress (io.servicetalk.http.netty.HttpClients.forSingleAddress)3 HttpServers.forAddress (io.servicetalk.http.netty.HttpServers.forAddress)3 DelegatingConnectionAcceptor (io.servicetalk.transport.api.DelegatingConnectionAcceptor)3 HostAndPort (io.servicetalk.transport.api.HostAndPort)3 IOException (java.io.IOException)3