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();
}
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();
}
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());
}
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);
}
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));
}
Aggregations