Search in sources :

Example 1 with StreamingHttpConnectionFilter

use of io.servicetalk.http.api.StreamingHttpConnectionFilter 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 2 with StreamingHttpConnectionFilter

use of io.servicetalk.http.api.StreamingHttpConnectionFilter in project servicetalk by apple.

the class H2ConcurrencyControllerTest method setUp.

@BeforeEach
void setUp() throws Exception {
    serverEventLoopGroup = createIoExecutor(1, "server-io").eventLoopGroup();
    for (int i = 0; i < N_ITERATIONS; i++) {
        latches[i] = new CountDownLatch(1);
    }
    AtomicBoolean secondAndMore = new AtomicBoolean();
    serverAcceptorChannel = bindH2Server(serverEventLoopGroup, new ChannelInitializer<Http2StreamChannel>() {

        @Override
        protected void initChannel(Http2StreamChannel ch) {
            // Respond only for the first request which is used to propagate MAX_CONCURRENT_STREAMS_VALUE
            if (secondAndMore.compareAndSet(false, true)) {
                ch.pipeline().addLast(new EchoHttp2Handler());
            } else {
                // Do not respond to any subsequent requests, only release the associated latch to notify the client
                // that server received the request.
                ch.pipeline().addLast(new SimpleChannelInboundHandler<Http2HeadersFrame>() {

                    @Override
                    protected void channelRead0(final ChannelHandlerContext ctx, final Http2HeadersFrame msg) {
                        String path = msg.headers().path().toString();
                        int i = parseInt(path.substring(1));
                        latches[i].countDown();
                    }
                });
            }
        }
    }, parentPipeline -> {
    }, h2Builder -> {
        h2Builder.initialSettings().maxConcurrentStreams(MAX_CONCURRENT_STREAMS_VALUE);
        return h2Builder;
    });
    final HostAndPort serverAddress = of((InetSocketAddress) serverAcceptorChannel.localAddress());
    client = forResolvedAddress(serverAddress).ioExecutor(CTX.ioExecutor()).executor(CTX.executor()).executionStrategy(defaultStrategy()).appendClientFilter(// All exceptions should be propagated
    disableAutoRetries()).appendConnectionFilter(MulticastTransportEventsStreamingHttpConnectionFilter::new).appendConnectionFilter(connection -> new StreamingHttpConnectionFilter(connection) {

        @Override
        public Single<StreamingHttpResponse> request(StreamingHttpRequest request) {
            return delegate().request(request).liftSync(subscriber -> new SingleSource.Subscriber<StreamingHttpResponse>() {

                @Override
                public void onSubscribe(final Cancellable cancellable) {
                    // Defer the cancel() signal to let the test thread start a new request
                    subscriber.onSubscribe(() -> CTX.executor().schedule(cancellable::cancel, ofMillis(100)));
                }

                @Override
                public void onSuccess(@Nullable final StreamingHttpResponse result) {
                    subscriber.onSuccess(result);
                }

                @Override
                public void onError(final Throwable t) {
                    subscriber.onError(t);
                }
            });
        }
    }).protocols(h2().enableFrameLogging("servicetalk-tests-h2-frame-logger", TRACE, () -> true).build()).build();
}
Also used : BeforeEach(org.junit.jupiter.api.BeforeEach) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse) StreamObserverTest.safeSync(io.servicetalk.http.netty.StreamObserverTest.safeSync) TRACE(io.servicetalk.logging.api.LogLevel.TRACE) SingleSource(io.servicetalk.concurrent.SingleSource) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Cancellable(io.servicetalk.concurrent.Cancellable) MulticastTransportEventsStreamingHttpConnectionFilter(io.servicetalk.http.netty.StreamObserverTest.MulticastTransportEventsStreamingHttpConnectionFilter) MAX_CONCURRENCY(io.servicetalk.http.api.HttpEventKey.MAX_CONCURRENCY) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) HttpExecutionStrategies.defaultStrategy(io.servicetalk.http.api.HttpExecutionStrategies.defaultStrategy) HostAndPort.of(io.servicetalk.transport.api.HostAndPort.of) RegisterExtension(org.junit.jupiter.api.extension.RegisterExtension) EchoHttp2Handler(io.servicetalk.http.netty.H2PriorKnowledgeFeatureParityTest.EchoHttp2Handler) HttpClient(io.servicetalk.http.api.HttpClient) StreamingHttpRequest(io.servicetalk.http.api.StreamingHttpRequest) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) ReservedHttpConnection(io.servicetalk.http.api.ReservedHttpConnection) Nullable(javax.annotation.Nullable) HttpProtocolConfigs.h2(io.servicetalk.http.netty.HttpProtocolConfigs.h2) Matchers.empty(org.hamcrest.Matchers.empty) EventLoopGroup(io.netty.channel.EventLoopGroup) ChannelInitializer(io.netty.channel.ChannelInitializer) NettyIoExecutors.createIoExecutor(io.servicetalk.transport.netty.internal.NettyIoExecutors.createIoExecutor) Single(io.servicetalk.concurrent.api.Single) HttpResponse(io.servicetalk.http.api.HttpResponse) ExecutionContextExtension(io.servicetalk.transport.netty.internal.ExecutionContextExtension) BlockingQueue(java.util.concurrent.BlockingQueue) MILLISECONDS(java.util.concurrent.TimeUnit.MILLISECONDS) StreamingHttpConnectionFilter(io.servicetalk.http.api.StreamingHttpConnectionFilter) OK(io.servicetalk.http.api.HttpResponseStatus.OK) H2PriorKnowledgeFeatureParityTest.bindH2Server(io.servicetalk.http.netty.H2PriorKnowledgeFeatureParityTest.bindH2Server) InetSocketAddress(java.net.InetSocketAddress) Integer.parseInt(java.lang.Integer.parseInt) Http2HeadersFrame(io.netty.handler.codec.http2.Http2HeadersFrame) HttpClients.forResolvedAddress(io.servicetalk.http.netty.HttpClients.forResolvedAddress) Channel(io.netty.channel.Channel) Test(org.junit.jupiter.api.Test) CountDownLatch(java.util.concurrent.CountDownLatch) AfterEach(org.junit.jupiter.api.AfterEach) HttpsProxyTest.safeClose(io.servicetalk.http.netty.HttpsProxyTest.safeClose) RetryingHttpRequesterFilter.disableAutoRetries(io.servicetalk.http.netty.RetryingHttpRequesterFilter.disableAutoRetries) SimpleChannelInboundHandler(io.netty.channel.SimpleChannelInboundHandler) LinkedBlockingDeque(java.util.concurrent.LinkedBlockingDeque) Matchers.is(org.hamcrest.Matchers.is) Http2StreamChannel(io.netty.handler.codec.http2.Http2StreamChannel) Duration.ofMillis(java.time.Duration.ofMillis) HostAndPort(io.servicetalk.transport.api.HostAndPort) Http2HeadersFrame(io.netty.handler.codec.http2.Http2HeadersFrame) SingleSource(io.servicetalk.concurrent.SingleSource) Cancellable(io.servicetalk.concurrent.Cancellable) EchoHttp2Handler(io.servicetalk.http.netty.H2PriorKnowledgeFeatureParityTest.EchoHttp2Handler) MulticastTransportEventsStreamingHttpConnectionFilter(io.servicetalk.http.netty.StreamObserverTest.MulticastTransportEventsStreamingHttpConnectionFilter) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) CountDownLatch(java.util.concurrent.CountDownLatch) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HostAndPort(io.servicetalk.transport.api.HostAndPort) MulticastTransportEventsStreamingHttpConnectionFilter(io.servicetalk.http.netty.StreamObserverTest.MulticastTransportEventsStreamingHttpConnectionFilter) StreamingHttpConnectionFilter(io.servicetalk.http.api.StreamingHttpConnectionFilter) ChannelInitializer(io.netty.channel.ChannelInitializer) StreamingHttpRequest(io.servicetalk.http.api.StreamingHttpRequest) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse) Http2StreamChannel(io.netty.handler.codec.http2.Http2StreamChannel) BeforeEach(org.junit.jupiter.api.BeforeEach)

Example 3 with StreamingHttpConnectionFilter

use of io.servicetalk.http.api.StreamingHttpConnectionFilter in project servicetalk by apple.

the class H2PriorKnowledgeFeatureParityTest method clientConnectionFilterAsyncContext.

@ParameterizedTest(name = "{displayName} [{index}] client={0}, h2PriorKnowledge={1}")
@MethodSource("clientExecutors")
void clientConnectionFilterAsyncContext(HttpTestExecutionStrategy strategy, boolean h2PriorKnowledge) throws Exception {
    setUp(strategy, h2PriorKnowledge);
    InetSocketAddress serverAddress = bindHttpEchoServer();
    final Queue<Throwable> errorQueue = new ConcurrentLinkedQueue<>();
    try (BlockingHttpClient client = forSingleAddress(HostAndPort.of(serverAddress)).protocols(h2PriorKnowledge ? h2Default() : h1Default()).executionStrategy(clientExecutionStrategy).appendConnectionFilter(connection -> new StreamingHttpConnectionFilter(connection) {

        @Override
        public Single<StreamingHttpResponse> request(final StreamingHttpRequest request) {
            return asyncContextTestRequest(errorQueue, delegate(), request);
        }
    }).buildBlocking()) {
        final String responseBody = "foo";
        HttpResponse response = client.request(client.post("/0").payloadBody(responseBody, textSerializerUtf8()));
        assertEquals(responseBody, response.payloadBody(textSerializerUtf8()));
        assertNoAsyncErrors(errorQueue);
    }
}
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) StreamingHttpConnectionFilter(io.servicetalk.http.api.StreamingHttpConnectionFilter) BlockingHttpClient(io.servicetalk.http.api.BlockingHttpClient) InetSocketAddress(java.net.InetSocketAddress) HttpResponse(io.servicetalk.http.api.HttpResponse) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse) StreamingHttpRequest(io.servicetalk.http.api.StreamingHttpRequest) Matchers.emptyString(org.hamcrest.Matchers.emptyString) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 4 with StreamingHttpConnectionFilter

use of io.servicetalk.http.api.StreamingHttpConnectionFilter in project servicetalk by apple.

the class ClientEffectiveStrategyTest method clientStrategy.

@ParameterizedTest(name = "API={0} builder={1} filter={2} LB={3} CF={4}")
@MethodSource("casesSupplier")
void clientStrategy(ClientType clientType, @Nullable final HttpExecutionStrategy builderStrategy, @Nullable final HttpExecutionStrategy filterStrategy, @Nullable final HttpExecutionStrategy lbStrategy, @Nullable final HttpExecutionStrategy cfStrategy) throws Exception {
    HttpExecutionStrategy effectiveStrategy = computeClientExecutionStrategy(builderStrategy, filterStrategy, lbStrategy, cfStrategy);
    SingleAddressHttpClientBuilder<HostAndPort, InetSocketAddress> clientBuilder = HttpClients.forSingleAddress(serverHostAndPort(context));
    if (builderStrategy != null) {
        clientBuilder.executionStrategy(builderStrategy);
    }
    ClientInvokingThreadRecorder invokingThreadsRecorder = new ClientInvokingThreadRecorder(clientType, effectiveStrategy);
    clientBuilder.appendClientFilter(invokingThreadsRecorder);
    if (null != filterStrategy) {
        clientBuilder.appendClientFilter(new StreamingHttpClientFilterFactory() {

            @Override
            public StreamingHttpClientFilter create(final FilterableStreamingHttpClient client) {
                return new StreamingHttpClientFilter(client) {
                };
            }

            @Override
            public HttpExecutionStrategy requiredOffloads() {
                return filterStrategy;
            }
        });
    }
    if (null != lbStrategy) {
        HttpLoadBalancerFactory<InetSocketAddress> lfFactory = DefaultHttpLoadBalancerFactory.Builder.from(new LoadBalancerFactoryImpl() {

            @Override
            public ExecutionStrategy requiredOffloads() {
                return lbStrategy;
            }
        }).build();
        clientBuilder.loadBalancerFactory(lfFactory);
    }
    if (null != cfStrategy) {
        clientBuilder.appendConnectionFilter(new StreamingHttpConnectionFilterFactory() {

            @Override
            public StreamingHttpConnectionFilter create(final FilterableStreamingHttpConnection connection) {
                return new StreamingHttpConnectionFilter(connection) {
                };
            }

            @Override
            public HttpExecutionStrategy requiredOffloads() {
                return cfStrategy;
            }
        });
    }
    // Exercise the client
    try (StreamingHttpClient client = clientBuilder.buildStreaming()) {
        String responseBody = getResponse(clientType, client);
        assertThat(responseBody, is(GREETING));
        invokingThreadsRecorder.verifyOffloads();
    }
}
Also used : FilterableStreamingHttpClient(io.servicetalk.http.api.FilterableStreamingHttpClient) StreamingHttpClient(io.servicetalk.http.api.StreamingHttpClient) BlockingStreamingHttpClient(io.servicetalk.http.api.BlockingStreamingHttpClient) InetSocketAddress(java.net.InetSocketAddress) FilterableStreamingHttpConnection(io.servicetalk.http.api.FilterableStreamingHttpConnection) StreamingHttpConnectionFilterFactory(io.servicetalk.http.api.StreamingHttpConnectionFilterFactory) StreamingHttpClientFilterFactory(io.servicetalk.http.api.StreamingHttpClientFilterFactory) AddressUtils.serverHostAndPort(io.servicetalk.transport.netty.internal.AddressUtils.serverHostAndPort) HostAndPort(io.servicetalk.transport.api.HostAndPort) StreamingHttpClientFilter(io.servicetalk.http.api.StreamingHttpClientFilter) StreamingHttpConnectionFilter(io.servicetalk.http.api.StreamingHttpConnectionFilter) FilterableStreamingHttpClient(io.servicetalk.http.api.FilterableStreamingHttpClient) HttpExecutionStrategy(io.servicetalk.http.api.HttpExecutionStrategy) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 5 with StreamingHttpConnectionFilter

use of io.servicetalk.http.api.StreamingHttpConnectionFilter 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 TransportObserver observer) {
            return delegate().newConnection(address, 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) 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) 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)

Aggregations

StreamingHttpConnectionFilter (io.servicetalk.http.api.StreamingHttpConnectionFilter)7 Single (io.servicetalk.concurrent.api.Single)6 StreamingHttpRequest (io.servicetalk.http.api.StreamingHttpRequest)6 OK (io.servicetalk.http.api.HttpResponseStatus.OK)5 StreamingHttpResponse (io.servicetalk.http.api.StreamingHttpResponse)5 Channel (io.netty.channel.Channel)4 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)4 Buffer (io.servicetalk.buffer.api.Buffer)4 HttpResponse (io.servicetalk.http.api.HttpResponse)4 StreamingHttpClient (io.servicetalk.http.api.StreamingHttpClient)4 HostAndPort (io.servicetalk.transport.api.HostAndPort)4 InetSocketAddress (java.net.InetSocketAddress)4 Nullable (javax.annotation.Nullable)4 MatcherAssert.assertThat (org.hamcrest.MatcherAssert.assertThat)4 Matchers.is (org.hamcrest.Matchers.is)4 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)4 ChannelInitializer (io.netty.channel.ChannelInitializer)3 EventLoopGroup (io.netty.channel.EventLoopGroup)3 Matchers.contentEqualTo (io.servicetalk.buffer.api.Matchers.contentEqualTo)3 BlockingHttpClient (io.servicetalk.http.api.BlockingHttpClient)3