Search in sources :

Example 1 with HttpServiceContext

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

the class GrpcRouter method bind.

Single<GrpcServerContext> bind(final ServerBinder binder, final GrpcExecutionContext executionContext) {
    final CompositeCloseable closeable = AsyncCloseables.newCompositeCloseable();
    final Map<String, StreamingHttpService> allRoutes = new HashMap<>();
    populateRoutes(executionContext, allRoutes, routes, closeable, executionStrategies);
    populateRoutes(executionContext, allRoutes, streamingRoutes, closeable, executionStrategies);
    populateRoutes(executionContext, allRoutes, blockingRoutes, closeable, executionStrategies);
    populateRoutes(executionContext, allRoutes, blockingStreamingRoutes, closeable, executionStrategies);
    // TODO: Optimize to bind a specific programming model service based on routes
    return binder.bindStreaming(new StreamingHttpService() {

        @Override
        public Single<StreamingHttpResponse> handle(final HttpServiceContext ctx, final StreamingHttpRequest request, final StreamingHttpResponseFactory responseFactory) {
            final StreamingHttpService service;
            if (!POST.equals(request.method()) || (service = allRoutes.get(request.path())) == null) {
                return NOT_FOUND_SERVICE.handle(ctx, request, responseFactory);
            } else {
                return service.handle(ctx, request, responseFactory);
            }
        }

        @Override
        public Completable closeAsync() {
            return closeable.closeAsync();
        }

        @Override
        public Completable closeAsyncGracefully() {
            return closeable.closeAsyncGracefully();
        }
    }).map(httpServerContext -> new DefaultGrpcServerContext(httpServerContext, executionContext));
}
Also used : HashMap(java.util.HashMap) HttpServiceContext(io.servicetalk.http.api.HttpServiceContext) StreamingHttpResponseFactory(io.servicetalk.http.api.StreamingHttpResponseFactory) CompositeCloseable(io.servicetalk.concurrent.api.CompositeCloseable) BlockingStreamingHttpService(io.servicetalk.http.api.BlockingStreamingHttpService) StreamingHttpServiceToOffloadedStreamingHttpService(io.servicetalk.http.api.StreamingHttpServiceToOffloadedStreamingHttpService) StreamingHttpService(io.servicetalk.http.api.StreamingHttpService) HttpApiConversions.toStreamingHttpService(io.servicetalk.http.api.HttpApiConversions.toStreamingHttpService) BlockingStreamingHttpRequest(io.servicetalk.http.api.BlockingStreamingHttpRequest) StreamingHttpRequest(io.servicetalk.http.api.StreamingHttpRequest) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse)

Example 2 with HttpServiceContext

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

the class H2PriorKnowledgeFeatureParityTest method serverThrowsFromHandler.

@ParameterizedTest(name = "{displayName} [{index}] client={0}, h2PriorKnowledge={1}")
@MethodSource("clientExecutors")
void serverThrowsFromHandler(HttpTestExecutionStrategy strategy, boolean h2PriorKnowledge) throws Exception {
    setUp(strategy, h2PriorKnowledge);
    InetSocketAddress serverAddress = bindHttpEchoServer(service -> new StreamingHttpServiceFilter(service) {

        @Override
        public Single<StreamingHttpResponse> handle(final HttpServiceContext ctx, final StreamingHttpRequest request, final StreamingHttpResponseFactory responseFactory) {
            throw DELIBERATE_EXCEPTION;
        }
    }, null);
    try (BlockingHttpClient client = forSingleAddress(HostAndPort.of(serverAddress)).protocols(h2PriorKnowledge ? h2Default() : h1Default()).executionStrategy(clientExecutionStrategy).buildBlocking()) {
        HttpResponse response = client.request(client.get("/"));
        assertThat(response.status(), is(INTERNAL_SERVER_ERROR));
        assertThat(response.payloadBody(), equalTo(EMPTY_BUFFER));
    }
}
Also used : StreamingHttpServiceFilter(io.servicetalk.http.api.StreamingHttpServiceFilter) Single(io.servicetalk.concurrent.api.Single) BlockingHttpClient(io.servicetalk.http.api.BlockingHttpClient) InetSocketAddress(java.net.InetSocketAddress) HttpServiceContext(io.servicetalk.http.api.HttpServiceContext) StreamingHttpResponseFactory(io.servicetalk.http.api.StreamingHttpResponseFactory) HttpResponse(io.servicetalk.http.api.HttpResponse) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse) StreamingHttpRequest(io.servicetalk.http.api.StreamingHttpRequest) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 3 with HttpServiceContext

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

the class HttpLifecycleObserverTest method testClientCancelsRequestAfterResponse.

@ParameterizedTest(name = "{displayName} [{index}] protocol={0}")
@EnumSource(HttpProtocol.class)
void testClientCancelsRequestAfterResponse(HttpProtocol protocol) throws Exception {
    TestPublisher<Buffer> serverResponsePayload = new TestPublisher<>();
    serviceFilterFactory(service -> new StreamingHttpServiceFilter(service) {

        @Override
        public Single<StreamingHttpResponse> handle(HttpServiceContext ctx, StreamingHttpRequest request, StreamingHttpResponseFactory responseFactory) {
            return request.payloadBody().ignoreElements().concat(succeeded(responseFactory.ok().payloadBody(serverResponsePayload)));
        }
    });
    setUp(protocol);
    StreamingHttpConnection connection = streamingHttpConnection();
    StreamingHttpRequest request = connection.post("/").payloadBody(Publisher.from(CONTENT.duplicate())).transform(// adds empty trailers
    new StatelessTrailersTransformer<>());
    StreamingHttpResponse response = connection.request(request).toFuture().get();
    assertResponse(response, protocol.version, OK);
    Future<Collection<Buffer>> payload = response.payloadBody().toFuture();
    payload.cancel(true);
    if (protocol == HttpProtocol.HTTP_1) {
        // wait for cancellation to close the connection:
        connection.onClose().toFuture().get();
    }
    // try to write server content to trigger write failure and close the server-side connection:
    serverResponsePayload.onNext(CONTENT.duplicate());
    bothTerminate.await();
    clientInOrder.verify(clientLifecycleObserver).onNewExchange();
    clientInOrder.verify(clientExchangeObserver).onConnectionSelected(any(ConnectionInfo.class));
    clientInOrder.verify(clientExchangeObserver).onRequest(any(StreamingHttpRequest.class));
    clientInOrder.verify(clientExchangeObserver).onResponse(any(StreamingHttpResponse.class));
    clientInOrder.verify(clientResponseObserver).onResponseCancel();
    clientRequestInOrder.verify(clientRequestObserver).onRequestData(any(Buffer.class));
    clientRequestInOrder.verify(clientRequestObserver).onRequestTrailers(any(HttpHeaders.class));
    clientRequestInOrder.verify(clientRequestObserver).onRequestComplete();
    clientInOrder.verify(clientExchangeObserver).onExchangeFinally();
    verifyNoMoreInteractions(clientLifecycleObserver, clientExchangeObserver, clientRequestObserver, clientResponseObserver);
    serverInOrder.verify(serverLifecycleObserver).onNewExchange();
    serverInOrder.verify(serverExchangeObserver).onConnectionSelected(any(ConnectionInfo.class));
    serverInOrder.verify(serverExchangeObserver).onRequest(any(StreamingHttpRequest.class));
    serverInOrder.verify(serverExchangeObserver).onResponse(any(StreamingHttpResponse.class));
    verify(serverResponseObserver, atMostOnce()).onResponseData(any(Buffer.class));
    serverInOrder.verify(serverResponseObserver).onResponseCancel();
    serverRequestInOrder.verify(serverRequestObserver).onRequestData(any(Buffer.class));
    serverRequestInOrder.verify(serverRequestObserver).onRequestComplete();
    serverInOrder.verify(serverExchangeObserver).onExchangeFinally();
    verifyNoMoreInteractions(serverLifecycleObserver, serverExchangeObserver, serverRequestObserver, serverResponseObserver);
}
Also used : Buffer(io.servicetalk.buffer.api.Buffer) HttpHeaders(io.servicetalk.http.api.HttpHeaders) TestPublisher(io.servicetalk.concurrent.api.TestPublisher) StreamingHttpResponseFactory(io.servicetalk.http.api.StreamingHttpResponseFactory) StreamingHttpServiceFilter(io.servicetalk.http.api.StreamingHttpServiceFilter) Single(io.servicetalk.concurrent.api.Single) HttpServiceContext(io.servicetalk.http.api.HttpServiceContext) Collection(java.util.Collection) StreamingHttpRequest(io.servicetalk.http.api.StreamingHttpRequest) ConnectionInfo(io.servicetalk.transport.api.ConnectionInfo) StreamingHttpConnection(io.servicetalk.http.api.StreamingHttpConnection) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse) EnumSource(org.junit.jupiter.params.provider.EnumSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 4 with HttpServiceContext

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

the class HttpTransportObserverTest method setUp.

private void setUp(HttpProtocol protocol) {
    this.protocol = protocol;
    protocol(protocol.config);
    connectionAcceptor(ctx -> {
        ctx.onClose().whenFinally(serverConnectionClosed::countDown).subscribe();
        return completed();
    });
    serviceFilterFactory(service -> new StreamingHttpServiceFilter(service) {

        @Override
        public Single<StreamingHttpResponse> handle(HttpServiceContext ctx, StreamingHttpRequest request, StreamingHttpResponseFactory responseFactory) {
            requestReceived.countDown();
            try {
                processRequest.await();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throwException(e);
            }
            return delegate().handle(ctx, request, responseFactory);
        }
    });
    clientTransportObserver = mock(TransportObserver.class, "clientTransportObserver");
    clientConnectionObserver = mock(ConnectionObserver.class, "clientConnectionObserver");
    clientDataObserver = mock(DataObserver.class, "clientDataObserver");
    clientMultiplexedObserver = mock(MultiplexedObserver.class, "clientMultiplexedObserver");
    clientStreamObserver = mock(StreamObserver.class, "clientStreamObserver");
    clientReadObserver = mock(ReadObserver.class, "clientReadObserver");
    clientWriteObserver = mock(WriteObserver.class, "clientWriteObserver");
    when(clientTransportObserver.onNewConnection(any(), any())).thenReturn(clientConnectionObserver);
    lenient().when(clientConnectionObserver.connectionEstablished(any(ConnectionInfo.class))).thenReturn(clientDataObserver);
    lenient().when(clientConnectionObserver.multiplexedConnectionEstablished(any(ConnectionInfo.class))).thenReturn(clientMultiplexedObserver);
    lenient().when(clientMultiplexedObserver.onNewStream()).thenReturn(clientStreamObserver);
    lenient().when(clientStreamObserver.streamEstablished()).thenReturn(clientDataObserver);
    lenient().when(clientDataObserver.onNewRead()).thenReturn(clientReadObserver);
    lenient().when(clientDataObserver.onNewWrite()).thenReturn(clientWriteObserver);
    serverTransportObserver = mock(TransportObserver.class, "serverTransportObserver");
    serverConnectionObserver = mock(ConnectionObserver.class, "serverConnectionObserver");
    serverDataObserver = mock(DataObserver.class, "serverDataObserver");
    serverMultiplexedObserver = mock(MultiplexedObserver.class, "serverMultiplexedObserver");
    serverStreamObserver = mock(StreamObserver.class, "serverStreamObserver");
    serverReadObserver = mock(ReadObserver.class, "serverReadObserver");
    serverWriteObserver = mock(WriteObserver.class, "serverWriteObserver");
    when(serverTransportObserver.onNewConnection(any(), any())).thenReturn(serverConnectionObserver);
    lenient().when(serverConnectionObserver.connectionEstablished(any(ConnectionInfo.class))).thenReturn(serverDataObserver);
    lenient().when(serverConnectionObserver.multiplexedConnectionEstablished(any(ConnectionInfo.class))).thenReturn(serverMultiplexedObserver);
    lenient().when(serverMultiplexedObserver.onNewStream()).thenReturn(serverStreamObserver);
    lenient().when(serverStreamObserver.streamEstablished()).thenReturn(serverDataObserver);
    lenient().when(serverDataObserver.onNewRead()).thenReturn(serverReadObserver);
    lenient().when(serverDataObserver.onNewWrite()).thenReturn(serverWriteObserver);
    transportObserver(clientTransportObserver, serverTransportObserver);
    setUp(CACHED, CACHED_SERVER);
}
Also used : StreamObserver(io.servicetalk.transport.api.ConnectionObserver.StreamObserver) MultiplexedObserver(io.servicetalk.transport.api.ConnectionObserver.MultiplexedObserver) StreamingHttpResponseFactory(io.servicetalk.http.api.StreamingHttpResponseFactory) TransportObserver(io.servicetalk.transport.api.TransportObserver) WriteObserver(io.servicetalk.transport.api.ConnectionObserver.WriteObserver) DataObserver(io.servicetalk.transport.api.ConnectionObserver.DataObserver) ConnectionObserver(io.servicetalk.transport.api.ConnectionObserver) StreamingHttpServiceFilter(io.servicetalk.http.api.StreamingHttpServiceFilter) Single(io.servicetalk.concurrent.api.Single) HttpServiceContext(io.servicetalk.http.api.HttpServiceContext) StreamingHttpRequest(io.servicetalk.http.api.StreamingHttpRequest) ConnectionInfo(io.servicetalk.transport.api.ConnectionInfo) ReadObserver(io.servicetalk.transport.api.ConnectionObserver.ReadObserver)

Example 5 with HttpServiceContext

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

the class AbstractHttpServiceAsyncContextTest method filterFactory.

private StreamingHttpServiceFilterFactory filterFactory(final boolean useImmediate, final boolean asyncFilter, final Queue<Throwable> errorQueue) {
    return service -> new StreamingHttpServiceFilter(service) {

        @Override
        public Single<StreamingHttpResponse> handle(final HttpServiceContext ctx, final StreamingHttpRequest request, final StreamingHttpResponseFactory factory) {
            return asyncFilter ? defer(() -> doHandle(ctx, request, factory).shareContextOnSubscribe()) : doHandle(ctx, request, factory);
        }

        private Single<StreamingHttpResponse> doHandle(final HttpServiceContext ctx, final StreamingHttpRequest request, final StreamingHttpResponseFactory factory) {
            if (useImmediate && !currentThread().getName().startsWith(IO_THREAD_PREFIX)) {
                // verify that if we expect to be offloaded, that we actually are
                return succeeded(factory.internalServerError());
            }
            CharSequence requestId = request.headers().getAndRemove(REQUEST_ID_HEADER);
            if (requestId != null) {
                AsyncContext.put(K1, requestId);
            }
            final StreamingHttpRequest filteredRequest = request.transformMessageBody(pub -> pub.afterSubscriber(assertAsyncContextSubscriber(requestId, errorQueue)));
            return delegate().handle(ctx, filteredRequest, factory).map(resp -> {
                assertAsyncContext(requestId, errorQueue);
                return resp.transformMessageBody(pub -> pub.afterSubscriber(assertAsyncContextSubscriber(requestId, errorQueue)));
            });
        }
    };
}
Also used : StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) StreamingHttpServiceFilterFactory(io.servicetalk.http.api.StreamingHttpServiceFilterFactory) CharSequences.newAsciiString(io.servicetalk.buffer.api.CharSequences.newAsciiString) Thread.currentThread(java.lang.Thread.currentThread) AtomicReference(java.util.concurrent.atomic.AtomicReference) Supplier(java.util.function.Supplier) Key.newKey(io.servicetalk.context.api.ContextMap.Key.newKey) StreamingHttpServiceFilter(io.servicetalk.http.api.StreamingHttpServiceFilter) HttpServiceContext(io.servicetalk.http.api.HttpServiceContext) AsyncContext(io.servicetalk.concurrent.api.AsyncContext) StreamingHttpClient(io.servicetalk.http.api.StreamingHttpClient) Single.succeeded(io.servicetalk.concurrent.api.Single.succeeded) StreamingHttpRequest(io.servicetalk.http.api.StreamingHttpRequest) AddressUtils.serverHostAndPort(io.servicetalk.transport.netty.internal.AddressUtils.serverHostAndPort) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) HttpServerBuilder(io.servicetalk.http.api.HttpServerBuilder) ExecutorService(java.util.concurrent.ExecutorService) Nullable(javax.annotation.Nullable) CyclicBarrier(java.util.concurrent.CyclicBarrier) AddressUtils.localAddress(io.servicetalk.transport.netty.internal.AddressUtils.localAddress) Matchers.empty(org.hamcrest.Matchers.empty) ServerContext(io.servicetalk.transport.api.ServerContext) HttpProtocolConfigs.h1(io.servicetalk.http.netty.HttpProtocolConfigs.h1) StreamingHttpConnection(io.servicetalk.http.api.StreamingHttpConnection) Single.defer(io.servicetalk.concurrent.api.Single.defer) PublisherSource(io.servicetalk.concurrent.PublisherSource) Single(io.servicetalk.concurrent.api.Single) OK(io.servicetalk.http.api.HttpResponseStatus.OK) InetSocketAddress(java.net.InetSocketAddress) Executors(java.util.concurrent.Executors) HttpClients.forResolvedAddress(io.servicetalk.http.netty.HttpClients.forResolvedAddress) SingleAddressHttpClientBuilder(io.servicetalk.http.api.SingleAddressHttpClientBuilder) Test(org.junit.jupiter.api.Test) ExecutionException(java.util.concurrent.ExecutionException) CountDownLatch(java.util.concurrent.CountDownLatch) ContextMap(io.servicetalk.context.api.ContextMap) DelegatingConnectionAcceptor(io.servicetalk.transport.api.DelegatingConnectionAcceptor) Completable.completed(io.servicetalk.concurrent.api.Completable.completed) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) StreamingHttpResponseFactory(io.servicetalk.http.api.StreamingHttpResponseFactory) Queue(java.util.Queue) HostAndPort(io.servicetalk.transport.api.HostAndPort) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) HttpExecutionStrategies.offloadNever(io.servicetalk.http.api.HttpExecutionStrategies.offloadNever) StreamingHttpServiceFilter(io.servicetalk.http.api.StreamingHttpServiceFilter) HttpServiceContext(io.servicetalk.http.api.HttpServiceContext) StreamingHttpResponseFactory(io.servicetalk.http.api.StreamingHttpResponseFactory) StreamingHttpRequest(io.servicetalk.http.api.StreamingHttpRequest) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse)

Aggregations

HttpServiceContext (io.servicetalk.http.api.HttpServiceContext)18 StreamingHttpRequest (io.servicetalk.http.api.StreamingHttpRequest)17 StreamingHttpResponseFactory (io.servicetalk.http.api.StreamingHttpResponseFactory)17 Single (io.servicetalk.concurrent.api.Single)15 StreamingHttpServiceFilter (io.servicetalk.http.api.StreamingHttpServiceFilter)15 StreamingHttpResponse (io.servicetalk.http.api.StreamingHttpResponse)14 Buffer (io.servicetalk.buffer.api.Buffer)8 BlockingHttpClient (io.servicetalk.http.api.BlockingHttpClient)7 HttpResponse (io.servicetalk.http.api.HttpResponse)7 MatcherAssert.assertThat (org.hamcrest.MatcherAssert.assertThat)7 Single.succeeded (io.servicetalk.concurrent.api.Single.succeeded)6 OK (io.servicetalk.http.api.HttpResponseStatus.OK)6 StreamingHttpService (io.servicetalk.http.api.StreamingHttpService)6 InetSocketAddress (java.net.InetSocketAddress)6 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)6 Publisher (io.servicetalk.concurrent.api.Publisher)5 HttpHeaders (io.servicetalk.http.api.HttpHeaders)5 Completable (io.servicetalk.concurrent.api.Completable)4 Publisher.from (io.servicetalk.concurrent.api.Publisher.from)4 DELIBERATE_EXCEPTION (io.servicetalk.concurrent.internal.DeliberateException.DELIBERATE_EXCEPTION)4