use of io.servicetalk.transport.api.ServerContext in project servicetalk by apple.
the class BlockingStreamingHttpClientTest method iterableSequentialConsumptionDoesNotDeadLock.
@ParameterizedTest
@ValueSource(ints = { 1, 100 })
void iterableSequentialConsumptionDoesNotDeadLock(int numItems) throws Exception {
try (ServerContext ctx = HttpServers.forAddress(localAddress(0)).listenBlockingStreamingAndAwait((ctx1, request, response) -> {
HttpPayloadWriter<String> output = response.sendMetaData(appSerializerAsciiFixLen());
for (String input : request.payloadBody(appSerializerAsciiFixLen())) {
output.write(input);
}
output.close();
});
BlockingStreamingHttpClient client = HttpClients.forResolvedAddress(serverHostAndPort(ctx)).buildBlockingStreaming()) {
NextSuppliers<String> nextSuppliers = NextSuppliers.stringSuppliers(numItems);
// Allow first item in Iterator to return from next().
nextSuppliers.countDownNextLatch();
BlockingStreamingHttpResponse resp = client.request(client.get("/").payloadBody(new TestBlockingIterable<>(nextSuppliers, nextSuppliers), appSerializerAsciiFixLen()));
StringBuilder responseBody = new StringBuilder(numItems);
int i = 0;
for (String respChunk : resp.payloadBody(appSerializerAsciiFixLen())) {
// Goal is to ensure we can write each individual chunk independently without blocking threads or having
// to batch multiple items. As each chunk is echoed back, unblock the next one.
nextSuppliers.countDownNextLatch();
responseBody.append(respChunk);
++i;
}
assertThat("num items: " + i + " responseBody: " + responseBody, i, equalTo(numItems));
}
}
use of io.servicetalk.transport.api.ServerContext in project servicetalk by apple.
the class AbstractHttpServiceAsyncContextTest method newRequestsGetFreshContext.
final void newRequestsGetFreshContext(boolean useImmediate) throws Exception {
final ExecutorService executorService = Executors.newCachedThreadPool();
final int concurrency = 10;
final int numRequests = 10;
final String k1Value = "value";
// The service should get an empty AsyncContext regardless of what is done outside the service.
// There are utilities that may be accessed in a static context or before service initialization that
// shouldn't pollute the service's AsyncContext.
AsyncContext.put(K1, k1Value);
try (ServerContext ctx = serverWithEmptyAsyncContextService(HttpServers.forAddress(localAddress(0)), useImmediate)) {
AtomicReference<Throwable> causeRef = new AtomicReference<>();
CyclicBarrier barrier = new CyclicBarrier(concurrency);
CountDownLatch latch = new CountDownLatch(concurrency);
for (int i = 0; i < concurrency; ++i) {
final int finalI = i;
executorService.execute(() -> {
SingleAddressHttpClientBuilder<HostAndPort, InetSocketAddress> clientBuilder = forResolvedAddress(serverHostAndPort(ctx)).protocols(h1().maxPipelinedRequests(numRequests).build());
try (StreamingHttpClient client = (!useImmediate ? clientBuilder : clientBuilder.executionStrategy(offloadNone())).buildStreaming()) {
try (StreamingHttpConnection connection = client.reserveConnection(client.get("/")).toFuture().get()) {
barrier.await();
for (int x = 0; x < numRequests; ++x) {
makeClientRequestWithId(connection, "thread=" + finalI + " request=" + x);
}
}
} catch (Throwable cause) {
causeRef.compareAndSet(null, cause);
} finally {
latch.countDown();
}
});
}
latch.await();
assertNull(causeRef.get());
assertEquals(k1Value, AsyncContext.get(K1));
} finally {
executorService.shutdown();
}
}
use of io.servicetalk.transport.api.ServerContext in project servicetalk by apple.
the class AbstractNettyHttpServerTest method startServer.
private void startServer() throws Exception {
final InetSocketAddress bindAddress = localAddress(0);
service(new TestServiceStreaming(publisherSupplier));
// A small SNDBUF is needed to test that the server defers closing the connection until writes are complete.
// However, if it is too small, tests that expect certain chunks of data will see those chunks broken up
// differently.
final HttpServerBuilder serverBuilder = HttpServers.forAddress(bindAddress).executor(serverExecutor).socketOption(StandardSocketOptions.SO_SNDBUF, 100).protocols(protocol).transportObserver(serverTransportObserver).enableWireLogging("servicetalk-tests-wire-logger", TRACE, () -> true);
configureServerBuilder(serverBuilder);
if (sslEnabled) {
serverBuilder.sslConfig(new ServerSslConfigBuilder(DefaultTestCerts::loadServerPem, DefaultTestCerts::loadServerKey).build());
}
if (nonOffloadingServiceFilterFactory != null) {
serverBuilder.appendNonOffloadingServiceFilter(nonOffloadingServiceFilterFactory);
}
if (serviceFilterFactory != null) {
serverBuilder.appendServiceFilter(serviceFilterFactory);
}
if (serverLifecycleObserver != NoopHttpLifecycleObserver.INSTANCE) {
serverBuilder.lifecycleObserver(serverLifecycleObserver);
}
serverContext = awaitIndefinitelyNonNull(listen(serverBuilder.ioExecutor(serverIoExecutor).appendConnectionAcceptorFilter(original -> new DelegatingConnectionAcceptor(connectionAcceptor))).beforeOnSuccess(ctx -> LOGGER.debug("Server started on {}.", ctx.listenAddress())).beforeOnError(throwable -> LOGGER.debug("Failed starting server on {}.", bindAddress)));
final SingleAddressHttpClientBuilder<HostAndPort, InetSocketAddress> clientBuilder = newClientBuilder();
if (sslEnabled) {
clientBuilder.sslConfig(new ClientSslConfigBuilder(DefaultTestCerts::loadServerCAPem).peerHost(serverPemHostname()).build());
}
if (connectionFactoryFilter != null) {
clientBuilder.appendConnectionFactoryFilter(connectionFactoryFilter);
}
if (connectionFilterFactory != null) {
clientBuilder.appendConnectionFilter(connectionFilterFactory);
}
if (clientTransportObserver != NoopTransportObserver.INSTANCE) {
clientBuilder.appendConnectionFactoryFilter(new TransportObserverConnectionFactoryFilter<>(clientTransportObserver));
}
if (clientLifecycleObserver != NoopHttpLifecycleObserver.INSTANCE) {
clientBuilder.appendClientFilter(new HttpLifecycleObserverRequesterFilter(clientLifecycleObserver));
}
if (clientFilterFactory != null) {
clientBuilder.appendClientFilter(clientFilterFactory);
}
httpClient = clientBuilder.ioExecutor(clientIoExecutor).executor(clientExecutor).executionStrategy(defaultStrategy()).protocols(protocol).enableWireLogging("servicetalk-tests-wire-logger", TRACE, Boolean.TRUE::booleanValue).buildStreaming();
httpConnection = httpClient.reserveConnection(httpClient.get("/")).toFuture().get();
}
use of io.servicetalk.transport.api.ServerContext in project servicetalk by apple.
the class TracingHttpRequesterFilterTest method testInjectWithParent.
@Test
void testInjectWithParent() throws Exception {
final String requestUrl = "/foo";
CountingInMemorySpanEventListener spanListener = new CountingInMemorySpanEventListener();
DefaultInMemoryTracer tracer = new DefaultInMemoryTracer.Builder(SCOPE_MANAGER).addListener(spanListener).build();
try (ServerContext context = buildServer()) {
try (HttpClient client = forSingleAddress(serverHostAndPort(context)).appendClientFilter(new TracingHttpRequesterFilter(tracer, "testClient")).appendClientFilter(new TestTracingLoggerFilter(TRACING_TEST_LOG_LINE_PREFIX)).build()) {
InMemorySpan clientSpan = tracer.buildSpan("test").start();
try (Scope ignored = tracer.activateSpan(clientSpan)) {
HttpResponse response = client.request(client.get(requestUrl)).toFuture().get();
TestSpanState serverSpanState = response.payloadBody(SPAN_STATE_SERIALIZER);
assertThat(serverSpanState.traceId, isHexId());
assertThat(serverSpanState.spanId, isHexId());
assertThat(serverSpanState.parentSpanId, isHexId());
assertThat(serverSpanState.traceId, equalToIgnoringCase(clientSpan.context().toTraceId()));
assertThat(serverSpanState.parentSpanId, equalToIgnoringCase(clientSpan.context().toSpanId()));
// don't mess with caller span state
assertEquals(clientSpan, tracer.activeSpan());
assertEquals(1, spanListener.spanFinishedCount());
InMemorySpan lastFinishedSpan = spanListener.lastFinishedSpan();
assertNotNull(lastFinishedSpan);
assertEquals(SPAN_KIND_CLIENT, lastFinishedSpan.tags().get(SPAN_KIND.getKey()));
assertEquals(GET.name(), lastFinishedSpan.tags().get(HTTP_METHOD.getKey()));
assertEquals(requestUrl, lastFinishedSpan.tags().get(HTTP_URL.getKey()));
assertEquals(OK.code(), lastFinishedSpan.tags().get(HTTP_STATUS.getKey()));
assertFalse(lastFinishedSpan.tags().containsKey(ERROR.getKey()));
verifyTraceIdPresentInLogs(stableAccumulated(1000), requestUrl, serverSpanState.traceId, serverSpanState.spanId, serverSpanState.parentSpanId, TRACING_TEST_LOG_LINE_PREFIX);
} finally {
clientSpan.finish();
}
}
}
}
use of io.servicetalk.transport.api.ServerContext in project servicetalk by apple.
the class TracingHttpRequesterFilterTest method testInjectWithNoParent.
@Test
void testInjectWithNoParent() throws Exception {
final String requestUrl = "/";
CountingInMemorySpanEventListener spanListener = new CountingInMemorySpanEventListener();
DefaultInMemoryTracer tracer = new DefaultInMemoryTracer.Builder(SCOPE_MANAGER).addListener(spanListener).build();
try (ServerContext context = buildServer()) {
try (HttpClient client = forSingleAddress(serverHostAndPort(context)).appendClientFilter(new TracingHttpRequesterFilter(tracer, "testClient")).appendClientFilter(new TestTracingLoggerFilter(TRACING_TEST_LOG_LINE_PREFIX)).build()) {
HttpResponse response = client.request(client.get(requestUrl)).toFuture().get();
TestSpanState serverSpanState = response.payloadBody(SPAN_STATE_SERIALIZER);
assertThat(serverSpanState.traceId, isHexId());
assertThat(serverSpanState.spanId, isHexId());
assertNull(serverSpanState.parentSpanId);
// don't mess with caller span state
assertNull(tracer.activeSpan());
assertEquals(1, spanListener.spanFinishedCount());
InMemorySpan lastFinishedSpan = spanListener.lastFinishedSpan();
assertNotNull(lastFinishedSpan);
assertEquals(SPAN_KIND_CLIENT, lastFinishedSpan.tags().get(SPAN_KIND.getKey()));
assertEquals(GET.name(), lastFinishedSpan.tags().get(HTTP_METHOD.getKey()));
assertEquals(requestUrl, lastFinishedSpan.tags().get(HTTP_URL.getKey()));
assertEquals(OK.code(), lastFinishedSpan.tags().get(HTTP_STATUS.getKey()));
assertFalse(lastFinishedSpan.tags().containsKey(ERROR.getKey()));
verifyTraceIdPresentInLogs(stableAccumulated(1000), requestUrl, serverSpanState.traceId, serverSpanState.spanId, null, TRACING_TEST_LOG_LINE_PREFIX);
}
}
}
Aggregations