use of io.servicetalk.http.api.FilterableStreamingHttpConnection in project servicetalk by apple.
the class HttpClientBuilderTest method withConnectionFactoryFilter.
@Test
void withConnectionFactoryFilter() throws Exception {
ConnectionFactory<InetSocketAddress, FilterableStreamingHttpConnection> factory1 = newFilter();
ConnectionFactory<InetSocketAddress, FilterableStreamingHttpConnection> factory2 = newFilter();
StreamingHttpClient requester = HttpClients.forSingleAddress(serverHostAndPort(serverContext)).appendConnectionFactoryFilter(factoryFilter(factory1)).appendConnectionFactoryFilter(factoryFilter(factory2)).ioExecutor(CTX.ioExecutor()).executionStrategy(offloadNever()).buildStreaming();
makeRequestValidateResponseAndClose(requester);
InOrder verifier = inOrder(factory1, factory2);
verifier.verify(factory1).newConnection(any(), any());
verifier.verify(factory2).newConnection(any(), any());
}
use of io.servicetalk.http.api.FilterableStreamingHttpConnection in project servicetalk by apple.
the class TimeoutHttpRequesterFilterTest method applyFilter.
private static Single<StreamingHttpResponse> applyFilter(TimeoutHttpRequesterFilter filterFactory, final HttpExecutionStrategy strategy, final Single<StreamingHttpResponse> responseSingle) {
HttpExecutionContext executionContext = new DefaultHttpExecutionContext(DEFAULT_ALLOCATOR, IO_EXECUTOR, EXECUTOR, strategy);
HttpConnectionContext connectionContext = mock(HttpConnectionContext.class);
when(connectionContext.executionContext()).thenReturn(executionContext);
FilterableStreamingHttpConnection connection = mock(FilterableStreamingHttpConnection.class);
when(connection.executionContext()).thenReturn(executionContext);
when(connection.request(any())).thenReturn(responseSingle);
StreamingHttpRequester requester = filterFactory.create(connection);
return requester.request(mock(StreamingHttpRequest.class));
}
use of io.servicetalk.http.api.FilterableStreamingHttpConnection in project servicetalk by apple.
the class ConditionalFilterFactory method append.
public FilterFactory append(FilterFactory append) {
StreamingHttpClientFilterFactory clientFactory = appendClientFilterFactory(this, append);
StreamingHttpConnectionFilterFactory connectionFactory = appendConnectionFilterFactory(this, append);
return new FilterFactory() {
@Override
public StreamingHttpClientFilter create(final FilterableStreamingHttpClient client) {
return clientFactory.create(client);
}
@Override
public StreamingHttpConnectionFilter create(final FilterableStreamingHttpConnection connection) {
return connectionFactory.create(connection);
}
};
}
use of io.servicetalk.http.api.FilterableStreamingHttpConnection in project servicetalk by apple.
the class H2PriorKnowledgeFeatureParityTest method clientRespectsSettingsFrame.
@ParameterizedTest(name = "{displayName} [{index}] client={0}, h2PriorKnowledge={1}")
@MethodSource("clientExecutors")
void clientRespectsSettingsFrame(HttpTestExecutionStrategy strategy, boolean h2PriorKnowledge) throws Exception {
setUp(strategy, h2PriorKnowledge);
assumeTrue(h2PriorKnowledge, "Only HTTP/2 supports SETTINGS frames");
int expectedMaxConcurrent = 1;
BlockingQueue<FilterableStreamingHttpConnection> connectionQueue = new LinkedBlockingQueue<>();
BlockingQueue<Publisher<? extends ConsumableEvent<Integer>>> maxConcurrentPubQueue = new LinkedBlockingQueue<>();
AtomicReference<Channel> serverParentChannelRef = new AtomicReference<>();
CountDownLatch serverChannelLatch = new CountDownLatch(1);
CountDownLatch serverSettingsAckLatch = new CountDownLatch(2);
serverAcceptorChannel = bindH2Server(serverEventLoopGroup, new ChannelInitializer<Channel>() {
@Override
protected void initChannel(final Channel ch) {
ch.pipeline().addLast(new EchoHttp2Handler());
}
}, parentPipeline -> parentPipeline.addLast(new ChannelInboundHandlerAdapter() {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
if (serverParentChannelRef.compareAndSet(null, ctx.channel())) {
serverChannelLatch.countDown();
}
super.channelActive(ctx);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof Http2SettingsAckFrame) {
serverSettingsAckLatch.countDown();
}
super.channelRead(ctx, msg);
}
}), identity());
InetSocketAddress serverAddress = (InetSocketAddress) serverAcceptorChannel.localAddress();
try (StreamingHttpClient client = forSingleAddress(HostAndPort.of(serverAddress)).protocols(h2PriorKnowledge ? h2Default() : h1Default()).executionStrategy(clientExecutionStrategy).appendConnectionFilter(conn -> new TestConnectionFilter(conn, connectionQueue, maxConcurrentPubQueue)).buildStreaming()) {
Processor<Buffer, Buffer> requestPayload = newProcessor();
client.request(client.post("/0").payloadBody(fromSource(requestPayload))).toFuture().get();
serverChannelLatch.await();
Channel serverParentChannel = serverParentChannelRef.get();
serverParentChannel.writeAndFlush(new DefaultHttp2SettingsFrame(new Http2Settings().maxConcurrentStreams(expectedMaxConcurrent))).sync();
Iterator<? extends ConsumableEvent<Integer>> maxItr = maxConcurrentPubQueue.take().toIterable().iterator();
// Verify that the initial maxConcurrency value is the default number
assertThat("No initial maxConcurrency value", maxItr.hasNext(), is(true));
ConsumableEvent<Integer> next = maxItr.next();
assertThat(next, is(notNullValue()));
assertThat("First event is not the default", next.event(), is(SMALLEST_MAX_CONCURRENT_STREAMS));
// We previously made a request, and intentionally didn't complete the request body. We want to verify
// that we have received the SETTINGS frame reducing the total number of streams to 1.
assertThat("No maxConcurrency value received", maxItr.hasNext(), is(true));
next = maxItr.next();
assertThat(next, is(notNullValue()));
assertThat("maxConcurrency did not change to the expected value", next.event(), is(expectedMaxConcurrent));
// Wait for a server to receive a settings ack
serverSettingsAckLatch.await();
// After this point we want to issue a new request and verify that client selects a new connection.
Processor<Buffer, Buffer> requestPayload2 = newProcessor();
client.request(client.post("/1").payloadBody(fromSource(requestPayload2))).toFuture().get();
// We expect 2 connections to be created.
assertNotSame(connectionQueue.take(), connectionQueue.take());
requestPayload.onComplete();
requestPayload2.onComplete();
}
}
use of io.servicetalk.http.api.FilterableStreamingHttpConnection 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();
}
}
Aggregations