use of io.servicetalk.grpc.netty.CompatProto.RequestContainer.CompatRequest 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);
}
use of io.servicetalk.grpc.netty.CompatProto.RequestContainer.CompatRequest in project servicetalk by apple.
the class ProtocolCompatibilityTest method grpcJavaClient.
// Wrap grpc client in our client interface to simplify test code
private static CompatClient grpcJavaClient(final SocketAddress address, @Nullable final String compression, final boolean ssl, @Nullable Duration timeout) throws Exception {
final NettyChannelBuilder builder = NettyChannelBuilder.forAddress(address);
if (ssl) {
final SslContext context = GrpcSslContexts.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build();
builder.sslContext(context);
} else {
builder.usePlaintext();
}
final ManagedChannel channel = builder.build();
// stub is immutable and each builder step returns a new instance.
CompatGrpc.CompatStub stub = CompatGrpc.newStub(channel);
if (compression != null) {
stub = stub.withCompression(compression);
}
if (null != timeout) {
stub = stub.withDeadlineAfter(timeout.toNanos(), NANOSECONDS);
}
final CompatGrpc.CompatStub finalStub = stub;
return new CompatClient() {
@Override
public GrpcExecutionContext executionContext() {
throw new UnsupportedOperationException();
}
@Override
public Publisher<CompatResponse> bidirectionalStreamingCall(final Publisher<CompatRequest> request) {
final PublisherSource.Processor<CompatResponse, CompatResponse> processor = newPublisherProcessor(3);
sendRequest(request, finalStub.bidirectionalStreamingCall(adaptResponse(processor)));
return fromSource(processor);
}
@Override
public Publisher<CompatResponse> bidirectionalStreamingCall(final GrpcClientMetadata metadata, final Publisher<CompatRequest> request) {
return bidirectionalStreamingCall(request);
}
@Deprecated
@Override
public Publisher<CompatResponse> bidirectionalStreamingCall(final BidirectionalStreamingCallMetadata metadata, final Publisher<CompatRequest> request) {
return bidirectionalStreamingCall(request);
}
@SuppressWarnings("unchecked")
@Override
public Single<CompatResponse> clientStreamingCall(final Publisher<CompatRequest> request) {
final Processor<CompatResponse, CompatResponse> processor = newSingleProcessor();
final StreamObserver<CompatRequest> requestObserver = finalStub.clientStreamingCall(adaptResponse(processor));
sendRequest(request, requestObserver);
return (Single<CompatResponse>) processor;
}
@Deprecated
@Override
public Single<CompatResponse> clientStreamingCall(final ClientStreamingCallMetadata metadata, final Publisher<CompatRequest> request) {
return clientStreamingCall(request);
}
@Override
public Single<CompatResponse> clientStreamingCall(final GrpcClientMetadata metadata, final Publisher<CompatRequest> request) {
return clientStreamingCall(request);
}
@SuppressWarnings("unchecked")
@Override
public Single<CompatResponse> scalarCall(final CompatRequest request) {
final Processor<CompatResponse, CompatResponse> processor = newSingleProcessor();
finalStub.scalarCall(request, adaptResponse(processor));
return (Single<CompatResponse>) processor;
}
@Deprecated
@Override
public Single<CompatResponse> scalarCall(final ScalarCallMetadata metadata, final CompatRequest request) {
return scalarCall(request);
}
@Override
public Single<CompatResponse> scalarCall(final GrpcClientMetadata metadata, final CompatRequest request) {
return scalarCall(request);
}
@Override
public Publisher<CompatResponse> serverStreamingCall(final CompatRequest request) {
final PublisherSource.Processor<CompatResponse, CompatResponse> processor = newPublisherProcessor(3);
finalStub.serverStreamingCall(request, adaptResponse(processor));
return fromSource(processor);
}
@Deprecated
@Override
public Publisher<CompatResponse> serverStreamingCall(final ServerStreamingCallMetadata metadata, final CompatRequest request) {
return serverStreamingCall(request);
}
@Override
public Publisher<CompatResponse> serverStreamingCall(final GrpcClientMetadata metadata, final CompatRequest request) {
return serverStreamingCall(request);
}
@Override
public void close() throws Exception {
channel.shutdown().awaitTermination(DEFAULT_TIMEOUT_SECONDS, SECONDS);
}
@Override
public Completable closeAsync() {
throw new UnsupportedOperationException();
}
@Override
public Completable onClose() {
throw new UnsupportedOperationException();
}
@Override
public BlockingCompatClient asBlockingClient() {
throw new UnsupportedOperationException();
}
private void sendRequest(final Publisher<CompatRequest> request, final StreamObserver<CompatRequest> requestObserver) {
request.whenOnComplete(requestObserver::onCompleted).whenOnError(requestObserver::onError).forEach(requestObserver::onNext);
}
private StreamObserver<CompatResponse> adaptResponse(final Processor<CompatResponse, CompatResponse> processor) {
return new StreamObserver<CompatResponse>() {
@Override
public void onNext(final CompatResponse value) {
processor.onSuccess(value);
}
@Override
public void onError(final Throwable t) {
processor.onError(t);
}
@Override
public void onCompleted() {
// ignored
}
};
}
private StreamObserver<CompatResponse> adaptResponse(final PublisherSource.Processor<CompatResponse, CompatResponse> processor) {
return new StreamObserver<CompatResponse>() {
@Override
public void onNext(final CompatResponse value) {
processor.onNext(value);
}
@Override
public void onError(final Throwable t) {
processor.onError(t);
}
@Override
public void onCompleted() {
processor.onComplete();
}
};
}
};
}
use of io.servicetalk.grpc.netty.CompatProto.RequestContainer.CompatRequest in project servicetalk by apple.
the class ProtocolCompatibilityTest method timeoutMidRequest.
@ParameterizedTest
@CsvSource({ "false,false,false", "false,false,true", "false,true,false", "false,true,true", "true,false,false", "true,false,true", "true,true,false", "true,true,true" })
void timeoutMidRequest(boolean stClient, boolean stServer, boolean clientInitiatedTimeout) throws Exception {
Duration clientTimeout = clientInitiatedTimeout ? DEFAULT_DEADLINE : null;
Duration serverTimeout = clientInitiatedTimeout ? null : DEFAULT_DEADLINE;
BlockingQueue<Throwable> serverErrorQueue = new ArrayBlockingQueue<>(16);
final TestServerContext server = stServer ? serviceTalkServer(ErrorMode.NONE, false, offloadNever(), null, null, serverErrorQueue) : grpcJavaServer(ErrorMode.NONE, false, null);
try (ServerContext proxyCtx = buildTimeoutProxy(server.listenAddress(), serverTimeout, false)) {
final CompatClient client = stClient ? serviceTalkClient(proxyCtx.listenAddress(), false, null, clientTimeout) : grpcJavaClient(proxyCtx.listenAddress(), null, false, clientTimeout);
try {
PublisherSource.Processor<CompatRequest, CompatRequest> reqPub = newPublisherProcessor();
reqPub.onNext(CompatRequest.newBuilder().setId(3).build());
validateGrpcErrorInResponse(client.bidirectionalStreamingCall(fromSource(reqPub)).toFuture(), false, clientInitiatedTimeout ? DEADLINE_EXCEEDED : CANCELLED, null);
// It is possible that the timeout on the client occurred before writing the request, in which case the
// server will never request the request, and therefore no error is expected.
Throwable cause = serverErrorQueue.poll(DEFAULT_DEADLINE.toNanos() * 2, NANOSECONDS);
if (cause != null) {
assertThat(cause, is(SERVER_PROCESSED_TOKEN));
cause = serverErrorQueue.take();
assertThat(cause, instanceOf(IOException.class));
}
} finally {
closeAll(server, client);
}
}
}
use of io.servicetalk.grpc.netty.CompatProto.RequestContainer.CompatRequest in project servicetalk by apple.
the class ProtocolCompatibilityTest method grpcJavaServer.
private static TestServerContext grpcJavaServer(final ErrorMode errorMode, final boolean ssl, @Nullable final String compression) throws Exception {
final NettyServerBuilder builder = NettyServerBuilder.forAddress(localAddress(0));
if (ssl) {
builder.useTransportSecurity(loadServerPem(), loadServerKey());
}
if (compression != null) {
DecompressorRegistry dRegistry = DecompressorRegistry.emptyInstance();
CompressorRegistry cRegistry = CompressorRegistry.newEmptyInstance();
Compressor gz = new Codec.Gzip();
Compressor id = Codec.Identity.NONE;
if (compression.equals(gz.getMessageEncoding())) {
dRegistry = dRegistry.with((Decompressor) gz, true);
cRegistry.register(gz);
}
// Always include identity otherwise it's not available
dRegistry = dRegistry.with((Decompressor) id, false);
cRegistry.register(id);
builder.decompressorRegistry(dRegistry);
builder.compressorRegistry(cRegistry);
} else {
builder.decompressorRegistry(DecompressorRegistry.emptyInstance());
builder.compressorRegistry(CompressorRegistry.newEmptyInstance());
}
final Server server = builder.addService(new CompatGrpc.CompatImplBase() {
@Override
public void scalarCall(final CompatRequest request, final StreamObserver<CompatResponse> responseObserver) {
try {
responseObserver.onNext(response(request.getId()));
responseObserver.onCompleted();
} catch (final Throwable t) {
responseObserver.onError(t);
}
}
@Override
public StreamObserver<CompatRequest> clientStreamingCall(final StreamObserver<CompatResponse> responseObserver) {
return new StreamObserver<CompatRequest>() {
int sum;
@Override
public void onNext(final CompatRequest value) {
sum += value.getId();
}
@Override
public void onError(final Throwable t) {
responseObserver.onError(t);
}
@Override
public void onCompleted() {
try {
responseObserver.onNext(response(sum));
responseObserver.onCompleted();
} catch (final Throwable t) {
responseObserver.onError(t);
}
}
};
}
@Override
public void serverStreamingCall(final CompatRequest request, final StreamObserver<CompatResponse> responseObserver) {
for (int i = 0; i < request.getId(); ++i) {
try {
responseObserver.onNext(response(i));
} catch (final Throwable t) {
responseObserver.onError(t);
return;
}
}
responseObserver.onCompleted();
}
@Override
public StreamObserver<CompatRequest> bidirectionalStreamingCall(final StreamObserver<CompatResponse> responseObserver) {
return new StreamObserver<CompatRequest>() {
private boolean errored;
@Override
public void onNext(final CompatRequest demoRequest) {
try {
responseObserver.onNext(response(demoRequest.getId()));
} catch (final Throwable t) {
onError(t);
}
}
@Override
public void onError(final Throwable t) {
if (errored) {
return;
}
errored = true;
responseObserver.onError(t);
}
@Override
public void onCompleted() {
if (errored) {
return;
}
responseObserver.onCompleted();
}
};
}
private CompatResponse response(final int value) throws Exception {
if (errorMode == ErrorMode.SIMPLE) {
throw Status.INVALID_ARGUMENT.augmentDescription(CUSTOM_ERROR_MESSAGE).asException();
}
if (errorMode == ErrorMode.STATUS) {
throw StatusProto.toStatusException(newStatus());
}
return computeResponse(value);
}
}).build().start();
return TestServerContext.fromGrpcJavaServer(server);
}
Aggregations