Search in sources :

Example 6 with Single

use of io.servicetalk.concurrent.api.Single in project servicetalk by apple.

the class TcpServerBinder method bind.

/**
 * Create a {@link ServerContext} that represents a socket which is bound and listening on the
 * {@code listenAddress}.
 *
 * @param listenAddress The address to bind to.
 * @param config The {@link ReadOnlyTcpServerConfig} to use for the bind socket and newly accepted sockets.
 * @param autoRead if {@code true} auto read will be enabled for new {@link Channel}s.
 * @param executionContext The {@link ExecutionContext} to use for the bind socket.
 * @param connectionAcceptor The {@link ConnectionAcceptor} used to filter newly accepted sockets.
 * @param connectionFunction Used to create a new {@link NettyConnection} from a {@link Channel}.
 * @param connectionConsumer Used to consume the result of {@code connectionFunction} after initialization and
 * filtering is done. This can be used for protocol specific initialization and to start data flow.
 * @param <CC> The type of {@link ConnectionContext} that is created for each accepted socket.
 * @return a {@link Single} that completes with a {@link ServerContext} that represents a socket which is bound and
 * listening on the {@code listenAddress}.
 */
public static <CC extends ConnectionContext> Single<ServerContext> bind(SocketAddress listenAddress, final ReadOnlyTcpServerConfig config, final boolean autoRead, final ExecutionContext<?> executionContext, @Nullable final InfluencerConnectionAcceptor connectionAcceptor, final BiFunction<Channel, ConnectionObserver, Single<CC>> connectionFunction, final Consumer<CC> connectionConsumer) {
    requireNonNull(connectionFunction);
    requireNonNull(connectionConsumer);
    listenAddress = toNettyAddress(listenAddress);
    EventLoopAwareNettyIoExecutor nettyIoExecutor = toEventLoopAwareNettyIoExecutor(executionContext.ioExecutor());
    ServerBootstrap bs = new ServerBootstrap();
    configure(config, autoRead, bs, nettyIoExecutor.eventLoopGroup(), listenAddress.getClass());
    ChannelSet channelSet = new ChannelSet(executionContext.executionStrategy().isCloseOffloaded() ? executionContext.executor() : immediate());
    bs.handler(new ChannelInboundHandlerAdapter() {

        @Override
        public void channelRead(final ChannelHandlerContext ctx, final Object msg) {
            // Verify that we do not leak pooled memory in the "accept" pipeline
            if (msg instanceof ReferenceCounted) {
                try {
                    throw new IllegalArgumentException("Unexpected ReferenceCounted msg in 'accept' pipeline: " + msg);
                } finally {
                    ((ReferenceCounted) msg).release();
                }
            }
            if (msg instanceof Channel) {
                final Channel channel = (Channel) msg;
                if (!channel.isActive()) {
                    channel.close();
                    LOGGER.debug("Channel ({}) is accepted, but was already inactive", msg);
                    return;
                } else if (!channelSet.addIfAbsent(channel)) {
                    LOGGER.warn("Channel ({}) not added to ChannelSet", msg);
                    return;
                }
            }
            ctx.fireChannelRead(msg);
        }
    });
    bs.childHandler(new io.netty.channel.ChannelInitializer<Channel>() {

        @Override
        protected void initChannel(Channel channel) {
            Single<CC> connectionSingle = connectionFunction.apply(channel, config.transportObserver().onNewConnection(channel.localAddress(), channel.remoteAddress()));
            if (connectionAcceptor != null) {
                connectionSingle = connectionSingle.flatMap(conn -> defer(() -> connectionAcceptor.accept(conn).concat(succeeded(conn))).subscribeOn(connectionAcceptor.requiredOffloads().isConnectOffloaded() ? executionContext.executor() : immediate()));
            }
            connectionSingle.beforeOnError(cause -> {
                // Getting the remote-address may involve volatile reads and potentially a syscall, so guard it.
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.debug("Failed to create a connection for remote address {}", channel.remoteAddress(), cause);
                }
                close(channel, cause);
            }).subscribe(connectionConsumer);
        }
    });
    ChannelFuture future = bs.bind(listenAddress);
    return new SubscribableSingle<ServerContext>() {

        @Override
        protected void handleSubscribe(Subscriber<? super ServerContext> subscriber) {
            subscriber.onSubscribe(() -> future.cancel(true));
            future.addListener((ChannelFuture f) -> {
                Channel channel = f.channel();
                Throwable cause = f.cause();
                if (cause == null) {
                    subscriber.onSuccess(NettyServerContext.wrap(channel, channelSet, connectionAcceptor, executionContext));
                } else {
                    close(channel, f.cause());
                    subscriber.onError(f.cause());
                }
            });
        }
    };
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) ChannelSet(io.servicetalk.transport.netty.internal.ChannelSet) Channel(io.netty.channel.Channel) EventLoopAwareNettyIoExecutor(io.servicetalk.transport.netty.internal.EventLoopAwareNettyIoExecutor) EventLoopAwareNettyIoExecutors.toEventLoopAwareNettyIoExecutor(io.servicetalk.transport.netty.internal.EventLoopAwareNettyIoExecutors.toEventLoopAwareNettyIoExecutor) SubscribableSingle(io.servicetalk.concurrent.api.internal.SubscribableSingle) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ServerBootstrap(io.netty.bootstrap.ServerBootstrap) ServerContext(io.servicetalk.transport.api.ServerContext) NettyServerContext(io.servicetalk.transport.netty.internal.NettyServerContext) SubscribableSingle(io.servicetalk.concurrent.api.internal.SubscribableSingle) Single(io.servicetalk.concurrent.api.Single) ChannelInboundHandlerAdapter(io.netty.channel.ChannelInboundHandlerAdapter) ReferenceCounted(io.netty.util.ReferenceCounted)

Example 7 with Single

use of io.servicetalk.concurrent.api.Single in project servicetalk by apple.

the class ProtocolCompatibilityTest method serviceTalkServer.

private static TestServerContext serviceTalkServer(final ErrorMode errorMode, final boolean ssl, final GrpcExecutionStrategy strategy, @Nullable final String compression, @Nullable final Duration timeout, Queue<Throwable> reqStreamError) throws Exception {
    final Compat.CompatService compatService = new Compat.CompatService() {

        @Override
        public Publisher<CompatResponse> bidirectionalStreamingCall(final GrpcServiceContext ctx, final Publisher<CompatRequest> pub) {
            reqStreamError.add(SERVER_PROCESSED_TOKEN);
            maybeThrowFromRpc(errorMode);
            return pub.map(req -> response(req.getId())).beforeFinally(errorConsumer());
        }

        @Override
        public Single<CompatResponse> clientStreamingCall(final GrpcServiceContext ctx, final Publisher<CompatRequest> pub) {
            reqStreamError.add(SERVER_PROCESSED_TOKEN);
            maybeThrowFromRpc(errorMode);
            return pub.collect(() -> 0, (sum, req) -> sum + req.getId()).map(this::response).beforeFinally(errorConsumer());
        }

        @Override
        public Single<CompatResponse> scalarCall(final GrpcServiceContext ctx, final CompatRequest req) {
            maybeThrowFromRpc(errorMode);
            return succeeded(response(req.getId()));
        }

        @Override
        public Publisher<CompatResponse> serverStreamingCall(final GrpcServiceContext ctx, final CompatRequest req) {
            maybeThrowFromRpc(errorMode);
            return Publisher.fromIterable(() -> IntStream.range(0, req.getId()).iterator()).map(this::response);
        }

        private CompatResponse response(final int value) {
            if (errorMode == ErrorMode.SIMPLE_IN_RESPONSE) {
                throwGrpcStatusException();
            } else if (errorMode == ErrorMode.STATUS_IN_RESPONSE) {
                throwGrpcStatusExceptionWithStatus();
            }
            return computeResponse(value);
        }

        private TerminalSignalConsumer errorConsumer() {
            return new TerminalSignalConsumer() {

                @Override
                public void onComplete() {
                }

                @Override
                public void onError(final Throwable throwable) {
                    reqStreamError.add(throwable);
                }

                @Override
                public void cancel() {
                    reqStreamError.add(new IOException("cancelled"));
                }
            };
        }
    };
    final ServiceFactory serviceFactory = new ServiceFactory.Builder().bufferEncoders(serviceTalkCompressions(compression)).bufferDecoderGroup(serviceTalkDecompression(compression)).bidirectionalStreamingCall(strategy, compatService).clientStreamingCall(strategy, compatService).scalarCall(strategy, compatService).serverStreamingCall(strategy, compatService).build();
    final ServerContext serverContext = serviceTalkServerBuilder(errorMode, ssl, timeout, b -> b.executionStrategy(strategy)).listenAndAwait(serviceFactory);
    return TestServerContext.fromServiceTalkServerContext(serverContext);
}
Also used : Arrays(java.util.Arrays) CompatResponse(io.servicetalk.grpc.netty.CompatProto.ResponseContainer.CompatResponse) EmptyBufferDecoderGroup(io.servicetalk.encoding.api.EmptyBufferDecoderGroup) ServerSslConfigBuilder(io.servicetalk.transport.api.ServerSslConfigBuilder) GrpcClientMetadata(io.servicetalk.grpc.api.GrpcClientMetadata) TerminalSignalConsumer(io.servicetalk.concurrent.api.TerminalSignalConsumer) NettyServerBuilder(io.grpc.netty.NettyServerBuilder) SourceAdapters.fromSource(io.servicetalk.concurrent.api.SourceAdapters.fromSource) BidirectionalStreamingCallMetadata(io.servicetalk.grpc.netty.CompatProto.Compat.BidirectionalStreamingCallMetadata) Future(java.util.concurrent.Future) StatusProto(io.grpc.protobuf.StatusProto) Arrays.asList(java.util.Arrays.asList) Duration(java.time.Duration) HttpExecutionStrategies.offloadNone(io.servicetalk.http.api.HttpExecutionStrategies.offloadNone) DefaultTestCerts(io.servicetalk.test.resources.DefaultTestCerts) Status(io.grpc.Status) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) DefaultTestCerts.loadServerKey(io.servicetalk.test.resources.DefaultTestCerts.loadServerKey) FAILED_PRECONDITION(io.servicetalk.grpc.api.GrpcStatusCode.FAILED_PRECONDITION) GrpcStatus(io.servicetalk.grpc.api.GrpcStatus) BlockingCompatClient(io.servicetalk.grpc.netty.CompatProto.Compat.BlockingCompatClient) BlockingQueue(java.util.concurrent.BlockingQueue) Processors.newSingleProcessor(io.servicetalk.concurrent.api.Processors.newSingleProcessor) Arguments(org.junit.jupiter.params.provider.Arguments) DefaultTestCerts.serverPemHostname(io.servicetalk.test.resources.DefaultTestCerts.serverPemHostname) BlockingIterable(io.servicetalk.concurrent.BlockingIterable) Matchers.instanceOf(org.hamcrest.Matchers.instanceOf) ArrayBlockingQueue(java.util.concurrent.ArrayBlockingQueue) ClientStreamingCallMetadata(io.servicetalk.grpc.netty.CompatProto.Compat.ClientStreamingCallMetadata) GRPC_TIMEOUT_HEADER_KEY(io.servicetalk.grpc.internal.DeadlineUtils.GRPC_TIMEOUT_HEADER_KEY) Buffer(io.servicetalk.buffer.api.Buffer) Compat(io.servicetalk.grpc.netty.CompatProto.Compat) StreamingHttpService(io.servicetalk.http.api.StreamingHttpService) Any(com.google.protobuf.Any) Matchers.is(org.hamcrest.Matchers.is) DefaultGrpcClientMetadata(io.servicetalk.grpc.api.DefaultGrpcClientMetadata) Codec(io.grpc.Codec) GrpcClientBuilder(io.servicetalk.grpc.api.GrpcClientBuilder) GrpcExecutionStrategy.from(io.servicetalk.grpc.api.GrpcExecutionStrategy.from) Assertions.fail(org.junit.jupiter.api.Assertions.fail) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) Compressor(io.grpc.Compressor) BlockingCompatService(io.servicetalk.grpc.netty.CompatProto.Compat.BlockingCompatService) ArrayList(java.util.ArrayList) InsecureTrustManagerFactory(io.netty.handler.ssl.util.InsecureTrustManagerFactory) HttpServiceContext(io.servicetalk.http.api.HttpServiceContext) CANCELLED(io.servicetalk.grpc.api.GrpcStatusCode.CANCELLED) Decompressor(io.grpc.Decompressor) Single.succeeded(io.servicetalk.concurrent.api.Single.succeeded) StreamingHttpRequest(io.servicetalk.http.api.StreamingHttpRequest) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) Server(io.grpc.Server) Nullable(javax.annotation.Nullable) SslContext(io.netty.handler.ssl.SslContext) Single(io.servicetalk.concurrent.api.Single) Completable(io.servicetalk.concurrent.api.Completable) IOException(java.io.IOException) StatusRuntimeException(io.grpc.StatusRuntimeException) ExecutionException(java.util.concurrent.ExecutionException) NettyBufferEncoders(io.servicetalk.encoding.netty.NettyBufferEncoders) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) GrpcExecutionStrategy(io.servicetalk.grpc.api.GrpcExecutionStrategy) DefaultTestCerts.loadServerPem(io.servicetalk.test.resources.DefaultTestCerts.loadServerPem) ArrayDeque(java.util.ArrayDeque) HttpResponseStatus(io.servicetalk.http.api.HttpResponseStatus) HttpServers(io.servicetalk.http.netty.HttpServers) GrpcSslContexts(io.grpc.netty.GrpcSslContexts) CompatRequest(io.servicetalk.grpc.netty.CompatProto.RequestContainer.CompatRequest) SocketAddress(java.net.SocketAddress) ManagedChannel(io.grpc.ManagedChannel) UNKNOWN(io.servicetalk.grpc.api.GrpcStatusCode.UNKNOWN) GrpcStatusCode(io.servicetalk.grpc.api.GrpcStatusCode) DEFAULT_TIMEOUT_SECONDS(io.servicetalk.concurrent.internal.TestTimeoutConstants.DEFAULT_TIMEOUT_SECONDS) BAD_REQUEST(io.servicetalk.http.api.HttpResponseStatus.BAD_REQUEST) GrpcStatusException(io.servicetalk.grpc.api.GrpcStatusException) GrpcExecutionStrategies.defaultStrategy(io.servicetalk.grpc.api.GrpcExecutionStrategies.defaultStrategy) ThrowableUtils.addSuppressed(io.servicetalk.utils.internal.ThrowableUtils.addSuppressed) StreamObserver(io.grpc.stub.StreamObserver) StreamingHttpClient(io.servicetalk.http.api.StreamingHttpClient) BufferDecoderGroup(io.servicetalk.encoding.api.BufferDecoderGroup) MethodSource(org.junit.jupiter.params.provider.MethodSource) REQUEST_TIMEOUT(io.servicetalk.http.api.HttpResponseStatus.REQUEST_TIMEOUT) ScalarCallMetadata(io.servicetalk.grpc.netty.CompatProto.Compat.ScalarCallMetadata) BufferDecoderGroupBuilder(io.servicetalk.encoding.api.BufferDecoderGroupBuilder) DEADLINE_EXCEEDED(io.servicetalk.grpc.api.GrpcStatusCode.DEADLINE_EXCEEDED) PublisherSource(io.servicetalk.concurrent.PublisherSource) Collection(java.util.Collection) GrpcPayloadWriter(io.servicetalk.grpc.api.GrpcPayloadWriter) InetSocketAddress(java.net.InetSocketAddress) GrpcServiceContext(io.servicetalk.grpc.api.GrpcServiceContext) Test(org.junit.jupiter.api.Test) Identity(io.servicetalk.encoding.api.Identity) CompatClient(io.servicetalk.grpc.netty.CompatProto.Compat.CompatClient) List(java.util.List) Matchers.equalTo(org.hamcrest.Matchers.equalTo) GrpcExecutionContext(io.servicetalk.grpc.api.GrpcExecutionContext) ClientSslConfigBuilder(io.servicetalk.transport.api.ClientSslConfigBuilder) CompressorRegistry(io.grpc.CompressorRegistry) INTERNAL(io.servicetalk.grpc.api.GrpcStatusCode.INTERNAL) REQUEST_HEADER_FIELDS_TOO_LARGE(io.servicetalk.http.api.HttpResponseStatus.REQUEST_HEADER_FIELDS_TOO_LARGE) Queue(java.util.Queue) Duration.ofMillis(java.time.Duration.ofMillis) IntStream(java.util.stream.IntStream) Publisher.never(io.servicetalk.concurrent.api.Publisher.never) CsvSource(org.junit.jupiter.params.provider.CsvSource) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse) Publisher(io.servicetalk.concurrent.api.Publisher) NANOSECONDS(java.util.concurrent.TimeUnit.NANOSECONDS) DeliberateException(io.servicetalk.concurrent.internal.DeliberateException) Processor(io.servicetalk.concurrent.SingleSource.Processor) PRECONDITION_FAILED(io.servicetalk.http.api.HttpResponseStatus.PRECONDITION_FAILED) StreamingHttpServiceFilter(io.servicetalk.http.api.StreamingHttpServiceFilter) INVALID_ARGUMENT(io.servicetalk.grpc.api.GrpcStatusCode.INVALID_ARGUMENT) OPENSSL(io.servicetalk.transport.api.SslProvider.OPENSSL) DecompressorRegistry(io.grpc.DecompressorRegistry) HttpProtocolConfigs.h2Default(io.servicetalk.http.netty.HttpProtocolConfigs.h2Default) ServerStreamingCallMetadata(io.servicetalk.grpc.netty.CompatProto.Compat.ServerStreamingCallMetadata) HttpServerContext(io.servicetalk.http.api.HttpServerContext) GrpcServerBuilder(io.servicetalk.grpc.api.GrpcServerBuilder) BufferEncoder(io.servicetalk.encoding.api.BufferEncoder) Code(com.google.rpc.Code) HttpServerBuilder(io.servicetalk.http.api.HttpServerBuilder) AddressUtils.localAddress(io.servicetalk.transport.netty.internal.AddressUtils.localAddress) ServiceFactory(io.servicetalk.grpc.netty.CompatProto.Compat.ServiceFactory) ServerContext(io.servicetalk.transport.api.ServerContext) EXPECTATION_FAILED(io.servicetalk.http.api.HttpResponseStatus.EXPECTATION_FAILED) Processors.newPublisherProcessor(io.servicetalk.concurrent.api.Processors.newPublisherProcessor) CLIENT_ERROR_4XX(io.servicetalk.http.api.HttpResponseStatus.StatusClass.CLIENT_ERROR_4XX) SingleAddressHttpClientBuilder(io.servicetalk.http.api.SingleAddressHttpClientBuilder) NettyChannelBuilder(io.grpc.netty.NettyChannelBuilder) StreamingHttpResponseFactory(io.servicetalk.http.api.StreamingHttpResponseFactory) Any.pack(com.google.protobuf.Any.pack) Collections(java.util.Collections) HttpClients(io.servicetalk.http.netty.HttpClients) SECONDS(java.util.concurrent.TimeUnit.SECONDS) TerminalSignalConsumer(io.servicetalk.concurrent.api.TerminalSignalConsumer) ServiceFactory(io.servicetalk.grpc.netty.CompatProto.Compat.ServiceFactory) Compat(io.servicetalk.grpc.netty.CompatProto.Compat) Publisher(io.servicetalk.concurrent.api.Publisher) IOException(java.io.IOException) HttpServerContext(io.servicetalk.http.api.HttpServerContext) ServerContext(io.servicetalk.transport.api.ServerContext) BlockingCompatService(io.servicetalk.grpc.netty.CompatProto.Compat.BlockingCompatService) CompatResponse(io.servicetalk.grpc.netty.CompatProto.ResponseContainer.CompatResponse) GrpcServiceContext(io.servicetalk.grpc.api.GrpcServiceContext) CompatRequest(io.servicetalk.grpc.netty.CompatProto.RequestContainer.CompatRequest)

Example 8 with Single

use of io.servicetalk.concurrent.api.Single in project servicetalk by apple.

the class SingleRequestOrResponseApiTest method setUp.

private void setUp(boolean streamingService, boolean streamingClient) throws Exception {
    this.streamingService = streamingService;
    this.streamingClient = streamingClient;
    serverContext = GrpcServers.forAddress(localAddress(0)).listenAndAwait(streamingService ? new ServiceFactory(new TesterServiceImpl()) : new ServiceFactory(new BlockingTesterServiceImpl()));
    clientBuilder = GrpcClients.forAddress(serverHostAndPort(serverContext)).initializeHttp(builder -> builder.appendClientFilter(origin -> new StreamingHttpClientFilter(origin) {

        @Override
        protected Single<StreamingHttpResponse> request(StreamingHttpRequester delegate, StreamingHttpRequest request) {
            // and generates requested number of response items:
            return defer(() -> {
                request.requestTarget(BlockingTestResponseStreamRpc.PATH);
                return delegate.request(request).shareContextOnSubscribe();
            });
        }
    }));
}
Also used : IntStream(java.util.stream.IntStream) Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse) Publisher(io.servicetalk.concurrent.api.Publisher) StreamingHttpRequester(io.servicetalk.http.api.StreamingHttpRequester) Collections.singletonList(java.util.Collections.singletonList) GrpcStatusException(io.servicetalk.grpc.api.GrpcStatusException) INVALID_ARGUMENT(io.servicetalk.grpc.api.GrpcStatusCode.INVALID_ARGUMENT) ServiceFactory(io.servicetalk.grpc.netty.TesterProto.Tester.ServiceFactory) Arrays.asList(java.util.Arrays.asList) Assumptions.assumeFalse(org.junit.jupiter.api.Assumptions.assumeFalse) TesterClient(io.servicetalk.grpc.netty.TesterProto.Tester.TesterClient) StreamingHttpRequest(io.servicetalk.http.api.StreamingHttpRequest) Publisher.fromIterable(io.servicetalk.concurrent.api.Publisher.fromIterable) AddressUtils.serverHostAndPort(io.servicetalk.transport.netty.internal.AddressUtils.serverHostAndPort) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) NoSuchElementException(java.util.NoSuchElementException) Publisher.from(io.servicetalk.concurrent.api.Publisher.from) Nullable(javax.annotation.Nullable) MethodSource(org.junit.jupiter.params.provider.MethodSource) BlockingTesterClient(io.servicetalk.grpc.netty.TesterProto.Tester.BlockingTesterClient) AddressUtils.localAddress(io.servicetalk.transport.netty.internal.AddressUtils.localAddress) ServerContext(io.servicetalk.transport.api.ServerContext) Single.defer(io.servicetalk.concurrent.api.Single.defer) Collections.emptyList(java.util.Collections.emptyList) Single(io.servicetalk.concurrent.api.Single) GrpcPayloadWriter(io.servicetalk.grpc.api.GrpcPayloadWriter) TesterService(io.servicetalk.grpc.netty.TesterProto.Tester.TesterService) TestRequest(io.servicetalk.grpc.netty.TesterProto.TestRequest) ClientFactory(io.servicetalk.grpc.netty.TesterProto.Tester.ClientFactory) StreamingHttpClientFilter(io.servicetalk.http.api.StreamingHttpClientFilter) Arguments(org.junit.jupiter.params.provider.Arguments) InetSocketAddress(java.net.InetSocketAddress) GrpcServiceContext(io.servicetalk.grpc.api.GrpcServiceContext) BlockingIterable(io.servicetalk.concurrent.BlockingIterable) ExecutionException(java.util.concurrent.ExecutionException) Matchers.instanceOf(org.hamcrest.Matchers.instanceOf) AfterEach(org.junit.jupiter.api.AfterEach) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) Collectors.toList(java.util.stream.Collectors.toList) Stream(java.util.stream.Stream) Matchers.equalTo(org.hamcrest.Matchers.equalTo) Matchers.is(org.hamcrest.Matchers.is) BlockingTestResponseStreamRpc(io.servicetalk.grpc.netty.TesterProto.Tester.BlockingTestResponseStreamRpc) BlockingTesterService(io.servicetalk.grpc.netty.TesterProto.Tester.BlockingTesterService) TestResponse(io.servicetalk.grpc.netty.TesterProto.TestResponse) GrpcClientBuilder(io.servicetalk.grpc.api.GrpcClientBuilder) HostAndPort(io.servicetalk.transport.api.HostAndPort) StreamingHttpClientFilter(io.servicetalk.http.api.StreamingHttpClientFilter) StreamingHttpRequester(io.servicetalk.http.api.StreamingHttpRequester) ServiceFactory(io.servicetalk.grpc.netty.TesterProto.Tester.ServiceFactory) Single(io.servicetalk.concurrent.api.Single) StreamingHttpRequest(io.servicetalk.http.api.StreamingHttpRequest)

Example 9 with Single

use of io.servicetalk.concurrent.api.Single in project servicetalk by apple.

the class ExecutionStrategyInContextTest method testStreaming.

@ParameterizedTest(name = "customStrategy={0}")
@ValueSource(booleans = { false, true })
void testStreaming(boolean customStrategy) throws Exception {
    StreamingHttpClient client = initClientAndServer(builder -> builder.listenStreaming(new StreamingHttpService() {

        @Override
        public Single<StreamingHttpResponse> handle(final HttpServiceContext ctx, final StreamingHttpRequest request, final StreamingHttpResponseFactory responseFactory) {
            serviceStrategyRef.set(ctx.executionContext().executionStrategy());
            return succeeded(responseFactory.ok());
        }

        @Override
        public HttpExecutionStrategy requiredOffloads() {
            return offloadNone();
        }
    }), customStrategy).buildStreaming();
    clientAsCloseable = client;
    if (!customStrategy) {
        assert expectedClientStrategy == null;
        expectedClientStrategy = defaultStrategy();
        assert expectedServerStrategy == null;
        expectedServerStrategy = offloadNone();
    }
    HttpExecutionStrategy clientStrat = client.executionContext().executionStrategy();
    assertThat("Unexpected client strategy.", clientStrat, equalStrategies(expectedClientStrategy));
    client.request(client.get("/")).toFuture().get();
    assertThat("Unexpected service strategy", serviceStrategyRef.get(), equalStrategies(expectedServerStrategy));
    ReservedStreamingHttpConnection conn = client.reserveConnection(client.get("/")).toFuture().get();
    assertThat("Unexpected connection strategy (from execution context).", conn.executionContext().executionStrategy(), equalStrategies(expectedClientStrategy));
    assertThat("Unexpected connection strategy (from execution context).", conn.connectionContext().executionContext().executionStrategy(), equalStrategies(expectedClientStrategy));
}
Also used : StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) HttpServiceContext(io.servicetalk.http.api.HttpServiceContext) HttpExecutionStrategies.defaultStrategy(io.servicetalk.http.api.HttpExecutionStrategies.defaultStrategy) StreamingHttpClient(io.servicetalk.http.api.StreamingHttpClient) ExecutionStrategy(io.servicetalk.transport.api.ExecutionStrategy) Single.succeeded(io.servicetalk.concurrent.api.Single.succeeded) HttpExecutionStrategies(io.servicetalk.http.api.HttpExecutionStrategies) HttpServerContext(io.servicetalk.http.api.HttpServerContext) HttpExecutionStrategy(io.servicetalk.http.api.HttpExecutionStrategy) HttpClient(io.servicetalk.http.api.HttpClient) StreamingHttpRequest(io.servicetalk.http.api.StreamingHttpRequest) HttpExecutionStrategies.offloadNone(io.servicetalk.http.api.HttpExecutionStrategies.offloadNone) AddressUtils.serverHostAndPort(io.servicetalk.transport.netty.internal.AddressUtils.serverHostAndPort) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) ReservedHttpConnection(io.servicetalk.http.api.ReservedHttpConnection) HttpServerBuilder(io.servicetalk.http.api.HttpServerBuilder) Nullable(javax.annotation.Nullable) BlockingHttpClient(io.servicetalk.http.api.BlockingHttpClient) ReservedBlockingStreamingHttpConnection(io.servicetalk.http.api.ReservedBlockingStreamingHttpConnection) ValueSource(org.junit.jupiter.params.provider.ValueSource) Description(org.hamcrest.Description) AddressUtils.localAddress(io.servicetalk.transport.netty.internal.AddressUtils.localAddress) ServerContext(io.servicetalk.transport.api.ServerContext) Single(io.servicetalk.concurrent.api.Single) HttpClients.forSingleAddress(io.servicetalk.http.netty.HttpClients.forSingleAddress) ReservedBlockingHttpConnection(io.servicetalk.http.api.ReservedBlockingHttpConnection) TypeSafeMatcher(org.hamcrest.TypeSafeMatcher) InetSocketAddress(java.net.InetSocketAddress) BlockingStreamingHttpClient(io.servicetalk.http.api.BlockingStreamingHttpClient) SingleAddressHttpClientBuilder(io.servicetalk.http.api.SingleAddressHttpClientBuilder) Objects(java.util.Objects) HttpExecutionStrategies.customStrategyBuilder(io.servicetalk.http.api.HttpExecutionStrategies.customStrategyBuilder) AfterEach(org.junit.jupiter.api.AfterEach) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) StreamingHttpService(io.servicetalk.http.api.StreamingHttpService) Matcher(org.hamcrest.Matcher) StreamingHttpResponseFactory(io.servicetalk.http.api.StreamingHttpResponseFactory) ReservedStreamingHttpConnection(io.servicetalk.http.api.ReservedStreamingHttpConnection) HostAndPort(io.servicetalk.transport.api.HostAndPort) ReservedStreamingHttpConnection(io.servicetalk.http.api.ReservedStreamingHttpConnection) StreamingHttpClient(io.servicetalk.http.api.StreamingHttpClient) BlockingStreamingHttpClient(io.servicetalk.http.api.BlockingStreamingHttpClient) Single(io.servicetalk.concurrent.api.Single) HttpServiceContext(io.servicetalk.http.api.HttpServiceContext) StreamingHttpResponseFactory(io.servicetalk.http.api.StreamingHttpResponseFactory) StreamingHttpService(io.servicetalk.http.api.StreamingHttpService) StreamingHttpRequest(io.servicetalk.http.api.StreamingHttpRequest) HttpExecutionStrategy(io.servicetalk.http.api.HttpExecutionStrategy) ValueSource(org.junit.jupiter.params.provider.ValueSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 10 with Single

use of io.servicetalk.concurrent.api.Single in project servicetalk by apple.

the class HttpConnectionEmptyPayloadTest method headRequestContentEmpty.

@Test
void headRequestContentEmpty() throws Exception {
    try (CompositeCloseable closeable = AsyncCloseables.newCompositeCloseable()) {
        final int expectedContentLength = 128;
        byte[] expectedPayload = new byte[expectedContentLength];
        ThreadLocalRandom.current().nextBytes(expectedPayload);
        ServerContext serverContext = closeable.merge(HttpServers.forAddress(localAddress(0)).ioExecutor(executionContextRule.ioExecutor()).executionStrategy(offloadNone()).listenStreamingAndAwait((ctx, req, factory) -> {
            StreamingHttpResponse resp = factory.ok().payloadBody(from(HEAD.equals(req.method()) ? EMPTY_BUFFER : ctx.executionContext().bufferAllocator().newBuffer(expectedContentLength).writeBytes(expectedPayload)));
            resp.addHeader(CONTENT_LENGTH, String.valueOf(expectedContentLength));
            return succeeded(resp);
        }));
        StreamingHttpClient client = closeable.merge(forResolvedAddress(serverHostAndPort(serverContext)).ioExecutor(executionContextRule.ioExecutor()).protocols(h1().maxPipelinedRequests(3).build()).executor(executionContextRule.executor()).executionStrategy(defaultStrategy()).buildStreaming());
        StreamingHttpConnection connection = closeable.merge(client.reserveConnection(client.get("/")).toFuture().get());
        // Request HEAD, GET, HEAD to verify that we can keep reading data despite a HEAD request providing a hint
        // about content-length (and not actually providing the content).
        Single<StreamingHttpResponse> response1Single = connection.request(connection.newRequest(HEAD, "/"));
        Single<StreamingHttpResponse> response2Single = connection.request(connection.get("/"));
        Single<StreamingHttpResponse> response3Single = connection.request(connection.newRequest(HEAD, "/"));
        StreamingHttpResponse response = awaitIndefinitelyNonNull(response1Single);
        assertEquals(OK, response.status());
        CharSequence contentLength = response.headers().get(CONTENT_LENGTH);
        assertNotNull(contentLength);
        assertEquals(expectedContentLength, parseInt(contentLength.toString()));
        // Drain the current response content so we will be able to read the next response.
        response.messageBody().ignoreElements().toFuture().get();
        response = awaitIndefinitelyNonNull(response2Single);
        assertEquals(OK, response.status());
        contentLength = response.headers().get(CONTENT_LENGTH);
        assertNotNull(contentLength);
        assertEquals(expectedContentLength, parseInt(contentLength.toString()));
        Buffer buffer = awaitIndefinitelyNonNull(response.payloadBody().collect(() -> connection.connectionContext().executionContext().bufferAllocator().newBuffer(), Buffer::writeBytes));
        byte[] actualBytes = new byte[buffer.readableBytes()];
        buffer.readBytes(actualBytes);
        assertArrayEquals(expectedPayload, actualBytes);
        response = awaitIndefinitelyNonNull(response3Single);
        assertEquals(OK, response.status());
        contentLength = response.headers().get(CONTENT_LENGTH);
        assertNotNull(contentLength);
        assertEquals(expectedContentLength, parseInt(contentLength.toString()));
        response.messageBody().ignoreElements().toFuture().get();
    }
}
Also used : Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse) EMPTY_BUFFER(io.servicetalk.buffer.api.EmptyBuffer.EMPTY_BUFFER) HttpExecutionStrategies.defaultStrategy(io.servicetalk.http.api.HttpExecutionStrategies.defaultStrategy) StreamingHttpClient(io.servicetalk.http.api.StreamingHttpClient) RegisterExtension(org.junit.jupiter.api.extension.RegisterExtension) HEAD(io.servicetalk.http.api.HttpRequestMethod.HEAD) Single.succeeded(io.servicetalk.concurrent.api.Single.succeeded) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) BlockingTestUtils.awaitIndefinitelyNonNull(io.servicetalk.concurrent.api.BlockingTestUtils.awaitIndefinitelyNonNull) HttpExecutionStrategies.offloadNone(io.servicetalk.http.api.HttpExecutionStrategies.offloadNone) AddressUtils.serverHostAndPort(io.servicetalk.transport.netty.internal.AddressUtils.serverHostAndPort) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) Publisher.from(io.servicetalk.concurrent.api.Publisher.from) AddressUtils.localAddress(io.servicetalk.transport.netty.internal.AddressUtils.localAddress) ExecutionContextExtension.immediate(io.servicetalk.transport.netty.internal.ExecutionContextExtension.immediate) ServerContext(io.servicetalk.transport.api.ServerContext) HttpProtocolConfigs.h1(io.servicetalk.http.netty.HttpProtocolConfigs.h1) StreamingHttpConnection(io.servicetalk.http.api.StreamingHttpConnection) Single(io.servicetalk.concurrent.api.Single) CompositeCloseable(io.servicetalk.concurrent.api.CompositeCloseable) ExecutionContextExtension(io.servicetalk.transport.netty.internal.ExecutionContextExtension) CONTENT_LENGTH(io.servicetalk.http.api.HttpHeaderNames.CONTENT_LENGTH) OK(io.servicetalk.http.api.HttpResponseStatus.OK) Integer.parseInt(java.lang.Integer.parseInt) HttpClients.forResolvedAddress(io.servicetalk.http.netty.HttpClients.forResolvedAddress) Test(org.junit.jupiter.api.Test) Assertions.assertArrayEquals(org.junit.jupiter.api.Assertions.assertArrayEquals) Buffer(io.servicetalk.buffer.api.Buffer) AsyncCloseables(io.servicetalk.concurrent.api.AsyncCloseables) Buffer(io.servicetalk.buffer.api.Buffer) StreamingHttpClient(io.servicetalk.http.api.StreamingHttpClient) ServerContext(io.servicetalk.transport.api.ServerContext) CompositeCloseable(io.servicetalk.concurrent.api.CompositeCloseable) StreamingHttpConnection(io.servicetalk.http.api.StreamingHttpConnection) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse) Test(org.junit.jupiter.api.Test)

Aggregations

Single (io.servicetalk.concurrent.api.Single)57 StreamingHttpRequest (io.servicetalk.http.api.StreamingHttpRequest)34 StreamingHttpResponse (io.servicetalk.http.api.StreamingHttpResponse)34 Nullable (javax.annotation.Nullable)29 MatcherAssert.assertThat (org.hamcrest.MatcherAssert.assertThat)25 HttpServiceContext (io.servicetalk.http.api.HttpServiceContext)23 StreamingHttpResponseFactory (io.servicetalk.http.api.StreamingHttpResponseFactory)23 Buffer (io.servicetalk.buffer.api.Buffer)22 Single.succeeded (io.servicetalk.concurrent.api.Single.succeeded)21 Test (org.junit.jupiter.api.Test)21 Publisher (io.servicetalk.concurrent.api.Publisher)20 OK (io.servicetalk.http.api.HttpResponseStatus.OK)20 ServerContext (io.servicetalk.transport.api.ServerContext)19 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)19 StreamingHttpServiceFilter (io.servicetalk.http.api.StreamingHttpServiceFilter)18 Matchers.is (org.hamcrest.Matchers.is)18 Completable (io.servicetalk.concurrent.api.Completable)17 InetSocketAddress (java.net.InetSocketAddress)17 AddressUtils.localAddress (io.servicetalk.transport.netty.internal.AddressUtils.localAddress)16 ContextMap (io.servicetalk.context.api.ContextMap)13