@Test public void createMethodDescriptor() { MethodDescriptor<String, String> descriptor = MethodDescriptor.<String, String>create( MethodType.CLIENT_STREAMING, "/package.service/method", new StringMarshaller(), new StringMarshaller()); assertEquals(MethodType.CLIENT_STREAMING, descriptor.getType()); assertEquals("/package.service/method", descriptor.getFullMethodName()); assertFalse(descriptor.isIdempotent()); }
ClientCallImpl( MethodDescriptor<ReqT, RespT> method, Executor executor, CallOptions callOptions, ClientTransportProvider clientTransportProvider, ScheduledExecutorService deadlineCancellationExecutor) { this.method = method; // If we know that the executor is a direct executor, we don't need to wrap it with a // SerializingExecutor. This is purely for performance reasons. // See https://github.com/grpc/grpc-java/issues/368 this.callExecutor = executor == directExecutor() ? new SerializeReentrantCallsDirectExecutor() : new SerializingExecutor(executor); // Propagate the context from the thread which initiated the call to all callbacks. this.parentContext = Context.current(); this.unaryRequest = method.getType() == MethodType.UNARY || method.getType() == MethodType.SERVER_STREAMING; this.callOptions = callOptions; this.clientTransportProvider = clientTransportProvider; this.deadlineCancellationExecutor = deadlineCancellationExecutor; }
@Test public void idempotent() { MethodDescriptor<String, String> descriptor = MethodDescriptor.<String, String>create( MethodType.SERVER_STREAMING, "/package.service/method", new StringMarshaller(), new StringMarshaller()); assertFalse(descriptor.isIdempotent()); // Create a new desriptor by setting idempotent to true MethodDescriptor<String, String> newDescriptor = descriptor.withIdempotent(true); assertTrue(newDescriptor.isIdempotent()); // All other fields should staty the same assertEquals(MethodType.SERVER_STREAMING, newDescriptor.getType()); assertEquals("/package.service/method", newDescriptor.getFullMethodName()); }
@Override public ClientStream newStream( MethodDescriptor<?, ?> method, Metadata.Headers headers, ClientStreamListener listener) { Preconditions.checkNotNull(method, "method"); Preconditions.checkNotNull(headers, "headers"); Preconditions.checkNotNull(listener, "listener"); // Create the stream. final NettyClientStream stream = new NettyClientStream(listener, channel, handler); // Convert the headers into Netty HTTP/2 headers. AsciiString defaultPath = new AsciiString("/" + method.getFullMethodName()); Http2Headers http2Headers = Utils.convertClientHeaders(headers, negotiationHandler.scheme(), defaultPath, authority); ChannelFutureListener failureListener = new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (!future.isSuccess()) { // Stream creation failed. Close the stream if not already closed. stream.transportReportStatus( Status.fromThrowable(future.cause()), true, new Metadata()); } } }; // Write the command requesting the creation of the stream. handler .getWriteQueue() .enqueue( new CreateStreamCommand(http2Headers, stream), !method.getType().clientSendsOneMessage()) .addListener(failureListener); return stream; }
@Override public void messageRead(final InputStream inputStream) { if (serverCallState.isCancelled()) { return; } try { ServerTransportManager.set(serverTransport); final RequestT request = methodDescriptor.parseRequest(inputStream); listener.onMessage(request); } finally { try { inputStream.close(); } catch (IOException e) { throw new RuntimeException(e); } } }
@Override public void sendMessage(ReqT message) { Preconditions.checkState(stream != null, "Not started"); Preconditions.checkState(!cancelCalled, "call was cancelled"); Preconditions.checkState(!halfCloseCalled, "call was half-closed"); try { // TODO(notcarl): Find out if messageIs needs to be closed. InputStream messageIs = method.streamRequest(message); stream.writeMessage(messageIs); } catch (Throwable e) { stream.cancel(Status.CANCELLED.withCause(e).withDescription("Failed to stream message")); return; } // For unary requests, we don't flush since we know that halfClose should be coming soon. This // allows us to piggy-back the END_STREAM=true on the last message frame without opening the // possibility of broken applications forgetting to call halfClose without noticing. if (!unaryRequest) { stream.flush(); } }
@Test public void advertisedEncodingsAreSent() { MethodDescriptor<Void, Void> descriptor = MethodDescriptor.create( MethodType.UNARY, "service/method", new TestMarshaller<Void>(), new TestMarshaller<Void>()); final ClientTransport transport = mock(ClientTransport.class); final ClientStream stream = mock(ClientStream.class); ClientTransportProvider provider = new ClientTransportProvider() { @Override public ListenableFuture<ClientTransport> get(CallOptions callOptions) { return Futures.immediateFuture(transport); } }; when(transport.newStream( any(MethodDescriptor.class), any(Metadata.class), any(ClientStreamListener.class))) .thenReturn(stream); ClientCallImpl<Void, Void> call = new ClientCallImpl<Void, Void>( descriptor, executor, CallOptions.DEFAULT, provider, deadlineCancellationExecutor) .setDecompressorRegistry(decompressorRegistry); call.start(new TestClientCallListener<Void>(), new Metadata()); ArgumentCaptor<Metadata> metadataCaptor = ArgumentCaptor.forClass(Metadata.class); verify(transport) .newStream(eq(descriptor), metadataCaptor.capture(), isA(ClientStreamListener.class)); Metadata actual = metadataCaptor.getValue(); Set<String> acceptedEncodings = ImmutableSet.copyOf(actual.getAll(GrpcUtil.MESSAGE_ACCEPT_ENCODING_KEY)); assertEquals(decompressorRegistry.getAdvertisedMessageEncodings(), acceptedEncodings); }
@javax.annotation.Generated("by gRPC proto compiler") public class IRCServiceGrpc { // Static method descriptors that strictly reflect the proto. public static final io.grpc.MethodDescriptor< if4031.common.LoginRequest, if4031.common.LoginResponse> METHOD_LOGIN = io.grpc.MethodDescriptor.create( io.grpc.MethodDescriptor.MethodType.UNARY, "if4031.IRCService", "login", io.grpc.protobuf.ProtoUtils.marshaller(if4031.common.LoginRequest.parser()), io.grpc.protobuf.ProtoUtils.marshaller(if4031.common.LoginResponse.parser())); public static final io.grpc.MethodDescriptor< if4031.common.ChangeNickRequest, if4031.common.StatusResponse> METHOD_CHANGE_NICKNAME = io.grpc.MethodDescriptor.create( io.grpc.MethodDescriptor.MethodType.UNARY, "if4031.IRCService", "changeNickname", io.grpc.protobuf.ProtoUtils.marshaller(if4031.common.ChangeNickRequest.parser()), io.grpc.protobuf.ProtoUtils.marshaller(if4031.common.StatusResponse.parser())); public static final io.grpc.MethodDescriptor< if4031.common.ActionRequest, if4031.common.StatusResponse> METHOD_LOGOUT = io.grpc.MethodDescriptor.create( io.grpc.MethodDescriptor.MethodType.UNARY, "if4031.IRCService", "logout", io.grpc.protobuf.ProtoUtils.marshaller(if4031.common.ActionRequest.parser()), io.grpc.protobuf.ProtoUtils.marshaller(if4031.common.StatusResponse.parser())); public static final io.grpc.MethodDescriptor< if4031.common.ChannelRequest, if4031.common.StatusResponse> METHOD_JOIN_CHANNEL = io.grpc.MethodDescriptor.create( io.grpc.MethodDescriptor.MethodType.UNARY, "if4031.IRCService", "joinChannel", io.grpc.protobuf.ProtoUtils.marshaller(if4031.common.ChannelRequest.parser()), io.grpc.protobuf.ProtoUtils.marshaller(if4031.common.StatusResponse.parser())); public static final io.grpc.MethodDescriptor< if4031.common.ActionRequest, if4031.common.MessagesResponse> METHOD_GET_MESSAGE = io.grpc.MethodDescriptor.create( io.grpc.MethodDescriptor.MethodType.UNARY, "if4031.IRCService", "getMessage", io.grpc.protobuf.ProtoUtils.marshaller(if4031.common.ActionRequest.parser()), io.grpc.protobuf.ProtoUtils.marshaller(if4031.common.MessagesResponse.parser())); public static final io.grpc.MethodDescriptor< if4031.common.ChannelMessageRequest, if4031.common.MessagesResponse> METHOD_SEND_MESSAGE_TO_CHANNEL = io.grpc.MethodDescriptor.create( io.grpc.MethodDescriptor.MethodType.UNARY, "if4031.IRCService", "sendMessageToChannel", io.grpc.protobuf.ProtoUtils.marshaller(if4031.common.ChannelMessageRequest.parser()), io.grpc.protobuf.ProtoUtils.marshaller(if4031.common.MessagesResponse.parser())); public static final io.grpc.MethodDescriptor< if4031.common.MessageRequest, if4031.common.MessagesResponse> METHOD_SEND_MESSAGE = io.grpc.MethodDescriptor.create( io.grpc.MethodDescriptor.MethodType.UNARY, "if4031.IRCService", "sendMessage", io.grpc.protobuf.ProtoUtils.marshaller(if4031.common.MessageRequest.parser()), io.grpc.protobuf.ProtoUtils.marshaller(if4031.common.MessagesResponse.parser())); public static final io.grpc.MethodDescriptor< if4031.common.ChannelRequest, if4031.common.StatusResponse> METHOD_LEAVE_CHANNEL = io.grpc.MethodDescriptor.create( io.grpc.MethodDescriptor.MethodType.UNARY, "if4031.IRCService", "leaveChannel", io.grpc.protobuf.ProtoUtils.marshaller(if4031.common.ChannelRequest.parser()), io.grpc.protobuf.ProtoUtils.marshaller(if4031.common.StatusResponse.parser())); public static IRCServiceStub newStub(io.grpc.Channel channel) { return new IRCServiceStub(channel); } public static IRCServiceBlockingStub newBlockingStub(io.grpc.Channel channel) { return new IRCServiceBlockingStub(channel); } public static IRCServiceFutureStub newFutureStub(io.grpc.Channel channel) { return new IRCServiceFutureStub(channel); } public static interface IRCService { public void login( if4031.common.LoginRequest request, io.grpc.stub.StreamObserver<if4031.common.LoginResponse> responseObserver); public void changeNickname( if4031.common.ChangeNickRequest request, io.grpc.stub.StreamObserver<if4031.common.StatusResponse> responseObserver); public void logout( if4031.common.ActionRequest request, io.grpc.stub.StreamObserver<if4031.common.StatusResponse> responseObserver); public void joinChannel( if4031.common.ChannelRequest request, io.grpc.stub.StreamObserver<if4031.common.StatusResponse> responseObserver); public void getMessage( if4031.common.ActionRequest request, io.grpc.stub.StreamObserver<if4031.common.MessagesResponse> responseObserver); public void sendMessageToChannel( if4031.common.ChannelMessageRequest request, io.grpc.stub.StreamObserver<if4031.common.MessagesResponse> responseObserver); public void sendMessage( if4031.common.MessageRequest request, io.grpc.stub.StreamObserver<if4031.common.MessagesResponse> responseObserver); public void leaveChannel( if4031.common.ChannelRequest request, io.grpc.stub.StreamObserver<if4031.common.StatusResponse> responseObserver); } public static interface IRCServiceBlockingClient { public if4031.common.LoginResponse login(if4031.common.LoginRequest request); public if4031.common.StatusResponse changeNickname(if4031.common.ChangeNickRequest request); public if4031.common.StatusResponse logout(if4031.common.ActionRequest request); public if4031.common.StatusResponse joinChannel(if4031.common.ChannelRequest request); public if4031.common.MessagesResponse getMessage(if4031.common.ActionRequest request); public if4031.common.MessagesResponse sendMessageToChannel( if4031.common.ChannelMessageRequest request); public if4031.common.MessagesResponse sendMessage(if4031.common.MessageRequest request); public if4031.common.StatusResponse leaveChannel(if4031.common.ChannelRequest request); } public static interface IRCServiceFutureClient { public com.google.common.util.concurrent.ListenableFuture<if4031.common.LoginResponse> login( if4031.common.LoginRequest request); public com.google.common.util.concurrent.ListenableFuture<if4031.common.StatusResponse> changeNickname(if4031.common.ChangeNickRequest request); public com.google.common.util.concurrent.ListenableFuture<if4031.common.StatusResponse> logout( if4031.common.ActionRequest request); public com.google.common.util.concurrent.ListenableFuture<if4031.common.StatusResponse> joinChannel(if4031.common.ChannelRequest request); public com.google.common.util.concurrent.ListenableFuture<if4031.common.MessagesResponse> getMessage(if4031.common.ActionRequest request); public com.google.common.util.concurrent.ListenableFuture<if4031.common.MessagesResponse> sendMessageToChannel(if4031.common.ChannelMessageRequest request); public com.google.common.util.concurrent.ListenableFuture<if4031.common.MessagesResponse> sendMessage(if4031.common.MessageRequest request); public com.google.common.util.concurrent.ListenableFuture<if4031.common.StatusResponse> leaveChannel(if4031.common.ChannelRequest request); } public static class IRCServiceStub extends io.grpc.stub.AbstractStub<IRCServiceStub> implements IRCService { private IRCServiceStub(io.grpc.Channel channel) { super(channel); } private IRCServiceStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); } @java.lang.Override protected IRCServiceStub build(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { return new IRCServiceStub(channel, callOptions); } @java.lang.Override public void login( if4031.common.LoginRequest request, io.grpc.stub.StreamObserver<if4031.common.LoginResponse> responseObserver) { asyncUnaryCall(channel.newCall(METHOD_LOGIN, callOptions), request, responseObserver); } @java.lang.Override public void changeNickname( if4031.common.ChangeNickRequest request, io.grpc.stub.StreamObserver<if4031.common.StatusResponse> responseObserver) { asyncUnaryCall( channel.newCall(METHOD_CHANGE_NICKNAME, callOptions), request, responseObserver); } @java.lang.Override public void logout( if4031.common.ActionRequest request, io.grpc.stub.StreamObserver<if4031.common.StatusResponse> responseObserver) { asyncUnaryCall(channel.newCall(METHOD_LOGOUT, callOptions), request, responseObserver); } @java.lang.Override public void joinChannel( if4031.common.ChannelRequest request, io.grpc.stub.StreamObserver<if4031.common.StatusResponse> responseObserver) { asyncUnaryCall(channel.newCall(METHOD_JOIN_CHANNEL, callOptions), request, responseObserver); } @java.lang.Override public void getMessage( if4031.common.ActionRequest request, io.grpc.stub.StreamObserver<if4031.common.MessagesResponse> responseObserver) { asyncUnaryCall(channel.newCall(METHOD_GET_MESSAGE, callOptions), request, responseObserver); } @java.lang.Override public void sendMessageToChannel( if4031.common.ChannelMessageRequest request, io.grpc.stub.StreamObserver<if4031.common.MessagesResponse> responseObserver) { asyncUnaryCall( channel.newCall(METHOD_SEND_MESSAGE_TO_CHANNEL, callOptions), request, responseObserver); } @java.lang.Override public void sendMessage( if4031.common.MessageRequest request, io.grpc.stub.StreamObserver<if4031.common.MessagesResponse> responseObserver) { asyncUnaryCall(channel.newCall(METHOD_SEND_MESSAGE, callOptions), request, responseObserver); } @java.lang.Override public void leaveChannel( if4031.common.ChannelRequest request, io.grpc.stub.StreamObserver<if4031.common.StatusResponse> responseObserver) { asyncUnaryCall(channel.newCall(METHOD_LEAVE_CHANNEL, callOptions), request, responseObserver); } } public static class IRCServiceBlockingStub extends io.grpc.stub.AbstractStub<IRCServiceBlockingStub> implements IRCServiceBlockingClient { private IRCServiceBlockingStub(io.grpc.Channel channel) { super(channel); } private IRCServiceBlockingStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); } @java.lang.Override protected IRCServiceBlockingStub build( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { return new IRCServiceBlockingStub(channel, callOptions); } @java.lang.Override public if4031.common.LoginResponse login(if4031.common.LoginRequest request) { return blockingUnaryCall(channel.newCall(METHOD_LOGIN, callOptions), request); } @java.lang.Override public if4031.common.StatusResponse changeNickname(if4031.common.ChangeNickRequest request) { return blockingUnaryCall(channel.newCall(METHOD_CHANGE_NICKNAME, callOptions), request); } @java.lang.Override public if4031.common.StatusResponse logout(if4031.common.ActionRequest request) { return blockingUnaryCall(channel.newCall(METHOD_LOGOUT, callOptions), request); } @java.lang.Override public if4031.common.StatusResponse joinChannel(if4031.common.ChannelRequest request) { return blockingUnaryCall(channel.newCall(METHOD_JOIN_CHANNEL, callOptions), request); } @java.lang.Override public if4031.common.MessagesResponse getMessage(if4031.common.ActionRequest request) { return blockingUnaryCall(channel.newCall(METHOD_GET_MESSAGE, callOptions), request); } @java.lang.Override public if4031.common.MessagesResponse sendMessageToChannel( if4031.common.ChannelMessageRequest request) { return blockingUnaryCall( channel.newCall(METHOD_SEND_MESSAGE_TO_CHANNEL, callOptions), request); } @java.lang.Override public if4031.common.MessagesResponse sendMessage(if4031.common.MessageRequest request) { return blockingUnaryCall(channel.newCall(METHOD_SEND_MESSAGE, callOptions), request); } @java.lang.Override public if4031.common.StatusResponse leaveChannel(if4031.common.ChannelRequest request) { return blockingUnaryCall(channel.newCall(METHOD_LEAVE_CHANNEL, callOptions), request); } } public static class IRCServiceFutureStub extends io.grpc.stub.AbstractStub<IRCServiceFutureStub> implements IRCServiceFutureClient { private IRCServiceFutureStub(io.grpc.Channel channel) { super(channel); } private IRCServiceFutureStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); } @java.lang.Override protected IRCServiceFutureStub build(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { return new IRCServiceFutureStub(channel, callOptions); } @java.lang.Override public com.google.common.util.concurrent.ListenableFuture<if4031.common.LoginResponse> login( if4031.common.LoginRequest request) { return futureUnaryCall(channel.newCall(METHOD_LOGIN, callOptions), request); } @java.lang.Override public com.google.common.util.concurrent.ListenableFuture<if4031.common.StatusResponse> changeNickname(if4031.common.ChangeNickRequest request) { return futureUnaryCall(channel.newCall(METHOD_CHANGE_NICKNAME, callOptions), request); } @java.lang.Override public com.google.common.util.concurrent.ListenableFuture<if4031.common.StatusResponse> logout( if4031.common.ActionRequest request) { return futureUnaryCall(channel.newCall(METHOD_LOGOUT, callOptions), request); } @java.lang.Override public com.google.common.util.concurrent.ListenableFuture<if4031.common.StatusResponse> joinChannel(if4031.common.ChannelRequest request) { return futureUnaryCall(channel.newCall(METHOD_JOIN_CHANNEL, callOptions), request); } @java.lang.Override public com.google.common.util.concurrent.ListenableFuture<if4031.common.MessagesResponse> getMessage(if4031.common.ActionRequest request) { return futureUnaryCall(channel.newCall(METHOD_GET_MESSAGE, callOptions), request); } @java.lang.Override public com.google.common.util.concurrent.ListenableFuture<if4031.common.MessagesResponse> sendMessageToChannel(if4031.common.ChannelMessageRequest request) { return futureUnaryCall(channel.newCall(METHOD_SEND_MESSAGE_TO_CHANNEL, callOptions), request); } @java.lang.Override public com.google.common.util.concurrent.ListenableFuture<if4031.common.MessagesResponse> sendMessage(if4031.common.MessageRequest request) { return futureUnaryCall(channel.newCall(METHOD_SEND_MESSAGE, callOptions), request); } @java.lang.Override public com.google.common.util.concurrent.ListenableFuture<if4031.common.StatusResponse> leaveChannel(if4031.common.ChannelRequest request) { return futureUnaryCall(channel.newCall(METHOD_LEAVE_CHANNEL, callOptions), request); } } public static io.grpc.ServerServiceDefinition bindService(final IRCService serviceImpl) { return io.grpc.ServerServiceDefinition.builder("if4031.IRCService") .addMethod( io.grpc.ServerMethodDefinition.create( METHOD_LOGIN, asyncUnaryCall( new io.grpc.stub.ServerCalls.UnaryMethod< if4031.common.LoginRequest, if4031.common.LoginResponse>() { @java.lang.Override public void invoke( if4031.common.LoginRequest request, io.grpc.stub.StreamObserver<if4031.common.LoginResponse> responseObserver) { serviceImpl.login(request, responseObserver); } }))) .addMethod( io.grpc.ServerMethodDefinition.create( METHOD_CHANGE_NICKNAME, asyncUnaryCall( new io.grpc.stub.ServerCalls.UnaryMethod< if4031.common.ChangeNickRequest, if4031.common.StatusResponse>() { @java.lang.Override public void invoke( if4031.common.ChangeNickRequest request, io.grpc.stub.StreamObserver<if4031.common.StatusResponse> responseObserver) { serviceImpl.changeNickname(request, responseObserver); } }))) .addMethod( io.grpc.ServerMethodDefinition.create( METHOD_LOGOUT, asyncUnaryCall( new io.grpc.stub.ServerCalls.UnaryMethod< if4031.common.ActionRequest, if4031.common.StatusResponse>() { @java.lang.Override public void invoke( if4031.common.ActionRequest request, io.grpc.stub.StreamObserver<if4031.common.StatusResponse> responseObserver) { serviceImpl.logout(request, responseObserver); } }))) .addMethod( io.grpc.ServerMethodDefinition.create( METHOD_JOIN_CHANNEL, asyncUnaryCall( new io.grpc.stub.ServerCalls.UnaryMethod< if4031.common.ChannelRequest, if4031.common.StatusResponse>() { @java.lang.Override public void invoke( if4031.common.ChannelRequest request, io.grpc.stub.StreamObserver<if4031.common.StatusResponse> responseObserver) { serviceImpl.joinChannel(request, responseObserver); } }))) .addMethod( io.grpc.ServerMethodDefinition.create( METHOD_GET_MESSAGE, asyncUnaryCall( new io.grpc.stub.ServerCalls.UnaryMethod< if4031.common.ActionRequest, if4031.common.MessagesResponse>() { @java.lang.Override public void invoke( if4031.common.ActionRequest request, io.grpc.stub.StreamObserver<if4031.common.MessagesResponse> responseObserver) { serviceImpl.getMessage(request, responseObserver); } }))) .addMethod( io.grpc.ServerMethodDefinition.create( METHOD_SEND_MESSAGE_TO_CHANNEL, asyncUnaryCall( new io.grpc.stub.ServerCalls.UnaryMethod< if4031.common.ChannelMessageRequest, if4031.common.MessagesResponse>() { @java.lang.Override public void invoke( if4031.common.ChannelMessageRequest request, io.grpc.stub.StreamObserver<if4031.common.MessagesResponse> responseObserver) { serviceImpl.sendMessageToChannel(request, responseObserver); } }))) .addMethod( io.grpc.ServerMethodDefinition.create( METHOD_SEND_MESSAGE, asyncUnaryCall( new io.grpc.stub.ServerCalls.UnaryMethod< if4031.common.MessageRequest, if4031.common.MessagesResponse>() { @java.lang.Override public void invoke( if4031.common.MessageRequest request, io.grpc.stub.StreamObserver<if4031.common.MessagesResponse> responseObserver) { serviceImpl.sendMessage(request, responseObserver); } }))) .addMethod( io.grpc.ServerMethodDefinition.create( METHOD_LEAVE_CHANNEL, asyncUnaryCall( new io.grpc.stub.ServerCalls.UnaryMethod< if4031.common.ChannelRequest, if4031.common.StatusResponse>() { @java.lang.Override public void invoke( if4031.common.ChannelRequest request, io.grpc.stub.StreamObserver<if4031.common.StatusResponse> responseObserver) { serviceImpl.leaveChannel(request, responseObserver); } }))) .build(); } }
@javax.annotation.Generated( value = "by gRPC proto compiler (version 1.1.0-SNAPSHOT)", comments = "Source: io/grpc/reflection/v1alpha/reflection.proto") public class ServerReflectionGrpc { private ServerReflectionGrpc() {} public static final String SERVICE_NAME = "grpc.reflection.v1alpha.ServerReflection"; // Static method descriptors that strictly reflect the proto. @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901") public static final io.grpc.MethodDescriptor< io.grpc.reflection.v1alpha.ServerReflectionRequest, io.grpc.reflection.v1alpha.ServerReflectionResponse> METHOD_SERVER_REFLECTION_INFO = io.grpc.MethodDescriptor.create( io.grpc.MethodDescriptor.MethodType.BIDI_STREAMING, generateFullMethodName( "grpc.reflection.v1alpha.ServerReflection", "ServerReflectionInfo"), io.grpc.protobuf.ProtoUtils.marshaller( io.grpc.reflection.v1alpha.ServerReflectionRequest.getDefaultInstance()), io.grpc.protobuf.ProtoUtils.marshaller( io.grpc.reflection.v1alpha.ServerReflectionResponse.getDefaultInstance())); /** Creates a new async stub that supports all call types for the service */ public static ServerReflectionStub newStub(io.grpc.Channel channel) { return new ServerReflectionStub(channel); } /** * Creates a new blocking-style stub that supports unary and streaming output calls on the service */ public static ServerReflectionBlockingStub newBlockingStub(io.grpc.Channel channel) { return new ServerReflectionBlockingStub(channel); } /** * Creates a new ListenableFuture-style stub that supports unary and streaming output calls on the * service */ public static ServerReflectionFutureStub newFutureStub(io.grpc.Channel channel) { return new ServerReflectionFutureStub(channel); } /** */ public abstract static class ServerReflectionImplBase implements io.grpc.BindableService { /** * * * <pre> * The reflection service is structured as a bidirectional stream, ensuring * all related requests go to a single server. * </pre> */ public io.grpc.stub.StreamObserver<io.grpc.reflection.v1alpha.ServerReflectionRequest> serverReflectionInfo( io.grpc.stub.StreamObserver<io.grpc.reflection.v1alpha.ServerReflectionResponse> responseObserver) { return asyncUnimplementedStreamingCall(METHOD_SERVER_REFLECTION_INFO, responseObserver); } @java.lang.Override public io.grpc.ServerServiceDefinition bindService() { return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) .addMethod( METHOD_SERVER_REFLECTION_INFO, asyncBidiStreamingCall( new MethodHandlers< io.grpc.reflection.v1alpha.ServerReflectionRequest, io.grpc.reflection.v1alpha.ServerReflectionResponse>( this, METHODID_SERVER_REFLECTION_INFO))) .build(); } } /** */ public static final class ServerReflectionStub extends io.grpc.stub.AbstractStub<ServerReflectionStub> { private ServerReflectionStub(io.grpc.Channel channel) { super(channel); } private ServerReflectionStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); } @java.lang.Override protected ServerReflectionStub build(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { return new ServerReflectionStub(channel, callOptions); } /** * * * <pre> * The reflection service is structured as a bidirectional stream, ensuring * all related requests go to a single server. * </pre> */ public io.grpc.stub.StreamObserver<io.grpc.reflection.v1alpha.ServerReflectionRequest> serverReflectionInfo( io.grpc.stub.StreamObserver<io.grpc.reflection.v1alpha.ServerReflectionResponse> responseObserver) { return asyncBidiStreamingCall( getChannel().newCall(METHOD_SERVER_REFLECTION_INFO, getCallOptions()), responseObserver); } } /** */ public static final class ServerReflectionBlockingStub extends io.grpc.stub.AbstractStub<ServerReflectionBlockingStub> { private ServerReflectionBlockingStub(io.grpc.Channel channel) { super(channel); } private ServerReflectionBlockingStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); } @java.lang.Override protected ServerReflectionBlockingStub build( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { return new ServerReflectionBlockingStub(channel, callOptions); } } /** */ public static final class ServerReflectionFutureStub extends io.grpc.stub.AbstractStub<ServerReflectionFutureStub> { private ServerReflectionFutureStub(io.grpc.Channel channel) { super(channel); } private ServerReflectionFutureStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); } @java.lang.Override protected ServerReflectionFutureStub build( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { return new ServerReflectionFutureStub(channel, callOptions); } } private static final int METHODID_SERVER_REFLECTION_INFO = 0; private static class MethodHandlers<Req, Resp> implements io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>, io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>, io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>, io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> { private final ServerReflectionImplBase serviceImpl; private final int methodId; public MethodHandlers(ServerReflectionImplBase serviceImpl, int methodId) { this.serviceImpl = serviceImpl; this.methodId = methodId; } @java.lang.Override @java.lang.SuppressWarnings("unchecked") public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) { switch (methodId) { default: throw new AssertionError(); } } @java.lang.Override @java.lang.SuppressWarnings("unchecked") public io.grpc.stub.StreamObserver<Req> invoke( io.grpc.stub.StreamObserver<Resp> responseObserver) { switch (methodId) { case METHODID_SERVER_REFLECTION_INFO: return (io.grpc.stub.StreamObserver<Req>) serviceImpl.serverReflectionInfo( (io.grpc.stub.StreamObserver<io.grpc.reflection.v1alpha.ServerReflectionResponse>) responseObserver); default: throw new AssertionError(); } } } private static final class ServerReflectionDescriptorSupplier implements io.grpc.protobuf.ProtoFileDescriptorSupplier { @java.lang.Override public com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() { return io.grpc.reflection.v1alpha.ServerReflectionProto.getDescriptor(); } } private static io.grpc.ServiceDescriptor serviceDescriptor; public static synchronized io.grpc.ServiceDescriptor getServiceDescriptor() { if (serviceDescriptor == null) { serviceDescriptor = new io.grpc.ServiceDescriptor( SERVICE_NAME, new ServerReflectionDescriptorSupplier(), METHOD_SERVER_REFLECTION_INFO); } return serviceDescriptor; } }
@javax.annotation.Generated("by gRPC proto compiler") public class TestServiceGrpc { private TestServiceGrpc() {} public static final String SERVICE_NAME = "grpc.testing.TestService"; // Static method descriptors that strictly reflect the proto. @io.grpc.ExperimentalApi public static final io.grpc.MethodDescriptor< io.grpc.testing.SimpleRequest, io.grpc.testing.SimpleResponse> METHOD_UNARY_CALL = io.grpc.MethodDescriptor.create( io.grpc.MethodDescriptor.MethodType.UNARY, generateFullMethodName("grpc.testing.TestService", "UnaryCall"), io.grpc.protobuf.ProtoUtils.marshaller( io.grpc.testing.SimpleRequest.getDefaultInstance()), io.grpc.protobuf.ProtoUtils.marshaller( io.grpc.testing.SimpleResponse.getDefaultInstance())); @io.grpc.ExperimentalApi public static final io.grpc.MethodDescriptor< io.grpc.testing.SimpleRequest, io.grpc.testing.SimpleResponse> METHOD_STREAMING_CALL = io.grpc.MethodDescriptor.create( io.grpc.MethodDescriptor.MethodType.BIDI_STREAMING, generateFullMethodName("grpc.testing.TestService", "StreamingCall"), io.grpc.protobuf.ProtoUtils.marshaller( io.grpc.testing.SimpleRequest.getDefaultInstance()), io.grpc.protobuf.ProtoUtils.marshaller( io.grpc.testing.SimpleResponse.getDefaultInstance())); public static TestServiceStub newStub(io.grpc.Channel channel) { return new TestServiceStub(channel); } public static TestServiceBlockingStub newBlockingStub(io.grpc.Channel channel) { return new TestServiceBlockingStub(channel); } public static TestServiceFutureStub newFutureStub(io.grpc.Channel channel) { return new TestServiceFutureStub(channel); } public static interface TestService { public void unaryCall( io.grpc.testing.SimpleRequest request, io.grpc.stub.StreamObserver<io.grpc.testing.SimpleResponse> responseObserver); public io.grpc.stub.StreamObserver<io.grpc.testing.SimpleRequest> streamingCall( io.grpc.stub.StreamObserver<io.grpc.testing.SimpleResponse> responseObserver); } public static interface TestServiceBlockingClient { public io.grpc.testing.SimpleResponse unaryCall(io.grpc.testing.SimpleRequest request); } public static interface TestServiceFutureClient { public com.google.common.util.concurrent.ListenableFuture<io.grpc.testing.SimpleResponse> unaryCall(io.grpc.testing.SimpleRequest request); } public static class TestServiceStub extends io.grpc.stub.AbstractStub<TestServiceStub> implements TestService { private TestServiceStub(io.grpc.Channel channel) { super(channel); } private TestServiceStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); } @java.lang.Override protected TestServiceStub build(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { return new TestServiceStub(channel, callOptions); } @java.lang.Override public void unaryCall( io.grpc.testing.SimpleRequest request, io.grpc.stub.StreamObserver<io.grpc.testing.SimpleResponse> responseObserver) { asyncUnaryCall( getChannel().newCall(METHOD_UNARY_CALL, getCallOptions()), request, responseObserver); } @java.lang.Override public io.grpc.stub.StreamObserver<io.grpc.testing.SimpleRequest> streamingCall( io.grpc.stub.StreamObserver<io.grpc.testing.SimpleResponse> responseObserver) { return asyncBidiStreamingCall( getChannel().newCall(METHOD_STREAMING_CALL, getCallOptions()), responseObserver); } } public static class TestServiceBlockingStub extends io.grpc.stub.AbstractStub<TestServiceBlockingStub> implements TestServiceBlockingClient { private TestServiceBlockingStub(io.grpc.Channel channel) { super(channel); } private TestServiceBlockingStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); } @java.lang.Override protected TestServiceBlockingStub build( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { return new TestServiceBlockingStub(channel, callOptions); } @java.lang.Override public io.grpc.testing.SimpleResponse unaryCall(io.grpc.testing.SimpleRequest request) { return blockingUnaryCall(getChannel().newCall(METHOD_UNARY_CALL, getCallOptions()), request); } } public static class TestServiceFutureStub extends io.grpc.stub.AbstractStub<TestServiceFutureStub> implements TestServiceFutureClient { private TestServiceFutureStub(io.grpc.Channel channel) { super(channel); } private TestServiceFutureStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); } @java.lang.Override protected TestServiceFutureStub build( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { return new TestServiceFutureStub(channel, callOptions); } @java.lang.Override public com.google.common.util.concurrent.ListenableFuture<io.grpc.testing.SimpleResponse> unaryCall(io.grpc.testing.SimpleRequest request) { return futureUnaryCall(getChannel().newCall(METHOD_UNARY_CALL, getCallOptions()), request); } } private static final int METHODID_UNARY_CALL = 0; private static final int METHODID_STREAMING_CALL = 1; private static class MethodHandlers<Req, Resp> implements io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>, io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>, io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>, io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> { private final TestService serviceImpl; private final int methodId; public MethodHandlers(TestService serviceImpl, int methodId) { this.serviceImpl = serviceImpl; this.methodId = methodId; } @java.lang.SuppressWarnings("unchecked") public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) { switch (methodId) { case METHODID_UNARY_CALL: serviceImpl.unaryCall( (io.grpc.testing.SimpleRequest) request, (io.grpc.stub.StreamObserver<io.grpc.testing.SimpleResponse>) responseObserver); break; default: throw new AssertionError(); } } @java.lang.SuppressWarnings("unchecked") public io.grpc.stub.StreamObserver<Req> invoke( io.grpc.stub.StreamObserver<Resp> responseObserver) { switch (methodId) { case METHODID_STREAMING_CALL: return (io.grpc.stub.StreamObserver<Req>) serviceImpl.streamingCall( (io.grpc.stub.StreamObserver<io.grpc.testing.SimpleResponse>) responseObserver); default: throw new AssertionError(); } } } public static io.grpc.ServerServiceDefinition bindService(final TestService serviceImpl) { return io.grpc.ServerServiceDefinition.builder(SERVICE_NAME) .addMethod( METHOD_UNARY_CALL, asyncUnaryCall( new MethodHandlers<io.grpc.testing.SimpleRequest, io.grpc.testing.SimpleResponse>( serviceImpl, METHODID_UNARY_CALL))) .addMethod( METHOD_STREAMING_CALL, asyncBidiStreamingCall( new MethodHandlers<io.grpc.testing.SimpleRequest, io.grpc.testing.SimpleResponse>( serviceImpl, METHODID_STREAMING_CALL))) .build(); } }
@javax.annotation.Generated( value = "by gRPC proto compiler (version 1.0.3)", comments = "Source: coprocess_object.proto") public class DispatcherGrpc { private DispatcherGrpc() {} public static final String SERVICE_NAME = "coprocess.Dispatcher"; // Static method descriptors that strictly reflect the proto. @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901") public static final io.grpc.MethodDescriptor< coprocess.CoprocessObject.Object, coprocess.CoprocessObject.Object> METHOD_DISPATCH = io.grpc.MethodDescriptor.create( io.grpc.MethodDescriptor.MethodType.UNARY, generateFullMethodName("coprocess.Dispatcher", "Dispatch"), io.grpc.protobuf.ProtoUtils.marshaller( coprocess.CoprocessObject.Object.getDefaultInstance()), io.grpc.protobuf.ProtoUtils.marshaller( coprocess.CoprocessObject.Object.getDefaultInstance())); @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901") public static final io.grpc.MethodDescriptor< coprocess.CoprocessObject.Event, coprocess.CoprocessObject.EventReply> METHOD_DISPATCH_EVENT = io.grpc.MethodDescriptor.create( io.grpc.MethodDescriptor.MethodType.UNARY, generateFullMethodName("coprocess.Dispatcher", "DispatchEvent"), io.grpc.protobuf.ProtoUtils.marshaller( coprocess.CoprocessObject.Event.getDefaultInstance()), io.grpc.protobuf.ProtoUtils.marshaller( coprocess.CoprocessObject.EventReply.getDefaultInstance())); /** Creates a new async stub that supports all call types for the service */ public static DispatcherStub newStub(io.grpc.Channel channel) { return new DispatcherStub(channel); } /** * Creates a new blocking-style stub that supports unary and streaming output calls on the service */ public static DispatcherBlockingStub newBlockingStub(io.grpc.Channel channel) { return new DispatcherBlockingStub(channel); } /** * Creates a new ListenableFuture-style stub that supports unary and streaming output calls on the * service */ public static DispatcherFutureStub newFutureStub(io.grpc.Channel channel) { return new DispatcherFutureStub(channel); } /** */ public abstract static class DispatcherImplBase implements io.grpc.BindableService { /** */ public void dispatch( coprocess.CoprocessObject.Object request, io.grpc.stub.StreamObserver<coprocess.CoprocessObject.Object> responseObserver) { asyncUnimplementedUnaryCall(METHOD_DISPATCH, responseObserver); } /** */ public void dispatchEvent( coprocess.CoprocessObject.Event request, io.grpc.stub.StreamObserver<coprocess.CoprocessObject.EventReply> responseObserver) { asyncUnimplementedUnaryCall(METHOD_DISPATCH_EVENT, responseObserver); } @java.lang.Override public io.grpc.ServerServiceDefinition bindService() { return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) .addMethod( METHOD_DISPATCH, asyncUnaryCall( new MethodHandlers< coprocess.CoprocessObject.Object, coprocess.CoprocessObject.Object>( this, METHODID_DISPATCH))) .addMethod( METHOD_DISPATCH_EVENT, asyncUnaryCall( new MethodHandlers< coprocess.CoprocessObject.Event, coprocess.CoprocessObject.EventReply>( this, METHODID_DISPATCH_EVENT))) .build(); } } /** */ public static final class DispatcherStub extends io.grpc.stub.AbstractStub<DispatcherStub> { private DispatcherStub(io.grpc.Channel channel) { super(channel); } private DispatcherStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); } @java.lang.Override protected DispatcherStub build(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { return new DispatcherStub(channel, callOptions); } /** */ public void dispatch( coprocess.CoprocessObject.Object request, io.grpc.stub.StreamObserver<coprocess.CoprocessObject.Object> responseObserver) { asyncUnaryCall( getChannel().newCall(METHOD_DISPATCH, getCallOptions()), request, responseObserver); } /** */ public void dispatchEvent( coprocess.CoprocessObject.Event request, io.grpc.stub.StreamObserver<coprocess.CoprocessObject.EventReply> responseObserver) { asyncUnaryCall( getChannel().newCall(METHOD_DISPATCH_EVENT, getCallOptions()), request, responseObserver); } } /** */ public static final class DispatcherBlockingStub extends io.grpc.stub.AbstractStub<DispatcherBlockingStub> { private DispatcherBlockingStub(io.grpc.Channel channel) { super(channel); } private DispatcherBlockingStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); } @java.lang.Override protected DispatcherBlockingStub build( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { return new DispatcherBlockingStub(channel, callOptions); } /** */ public coprocess.CoprocessObject.Object dispatch(coprocess.CoprocessObject.Object request) { return blockingUnaryCall(getChannel(), METHOD_DISPATCH, getCallOptions(), request); } /** */ public coprocess.CoprocessObject.EventReply dispatchEvent( coprocess.CoprocessObject.Event request) { return blockingUnaryCall(getChannel(), METHOD_DISPATCH_EVENT, getCallOptions(), request); } } /** */ public static final class DispatcherFutureStub extends io.grpc.stub.AbstractStub<DispatcherFutureStub> { private DispatcherFutureStub(io.grpc.Channel channel) { super(channel); } private DispatcherFutureStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); } @java.lang.Override protected DispatcherFutureStub build(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { return new DispatcherFutureStub(channel, callOptions); } /** */ public com.google.common.util.concurrent.ListenableFuture<coprocess.CoprocessObject.Object> dispatch(coprocess.CoprocessObject.Object request) { return futureUnaryCall(getChannel().newCall(METHOD_DISPATCH, getCallOptions()), request); } /** */ public com.google.common.util.concurrent.ListenableFuture<coprocess.CoprocessObject.EventReply> dispatchEvent(coprocess.CoprocessObject.Event request) { return futureUnaryCall( getChannel().newCall(METHOD_DISPATCH_EVENT, getCallOptions()), request); } } private static final int METHODID_DISPATCH = 0; private static final int METHODID_DISPATCH_EVENT = 1; private static class MethodHandlers<Req, Resp> implements io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>, io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>, io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>, io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> { private final DispatcherImplBase serviceImpl; private final int methodId; public MethodHandlers(DispatcherImplBase serviceImpl, int methodId) { this.serviceImpl = serviceImpl; this.methodId = methodId; } @java.lang.Override @java.lang.SuppressWarnings("unchecked") public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) { switch (methodId) { case METHODID_DISPATCH: serviceImpl.dispatch( (coprocess.CoprocessObject.Object) request, (io.grpc.stub.StreamObserver<coprocess.CoprocessObject.Object>) responseObserver); break; case METHODID_DISPATCH_EVENT: serviceImpl.dispatchEvent( (coprocess.CoprocessObject.Event) request, (io.grpc.stub.StreamObserver<coprocess.CoprocessObject.EventReply>) responseObserver); break; default: throw new AssertionError(); } } @java.lang.Override @java.lang.SuppressWarnings("unchecked") public io.grpc.stub.StreamObserver<Req> invoke( io.grpc.stub.StreamObserver<Resp> responseObserver) { switch (methodId) { default: throw new AssertionError(); } } } public static io.grpc.ServiceDescriptor getServiceDescriptor() { return new io.grpc.ServiceDescriptor(SERVICE_NAME, METHOD_DISPATCH, METHOD_DISPATCH_EVENT); } }
/** Test for {@link ClientCallImpl}. */ @RunWith(JUnit4.class) public class ClientCallImplTest { private static final MethodDescriptor<Void, Void> DESCRIPTOR = MethodDescriptor.create( MethodType.UNARY, "service/method", new TestMarshaller<Void>(), new TestMarshaller<Void>()); private final FakeClock fakeClock = new FakeClock(); private final ScheduledExecutorService deadlineCancellationExecutor = fakeClock.scheduledExecutorService; private final DecompressorRegistry decompressorRegistry = DecompressorRegistry.getDefaultInstance().with(new Codec.Gzip(), true); private final MethodDescriptor<Void, Void> method = MethodDescriptor.create( MethodType.UNARY, "service/method", new TestMarshaller<Void>(), new TestMarshaller<Void>()); @Mock private ClientStreamListener streamListener; @Mock private ClientTransport clientTransport; @Captor private ArgumentCaptor<Status> statusCaptor; @Mock private ClientTransport transport; @Mock private ClientTransportProvider provider; @Mock private ClientStream stream; @Mock private ClientCall.Listener<Void> callListener; @Captor private ArgumentCaptor<ClientStreamListener> listenerArgumentCaptor; @Captor private ArgumentCaptor<Status> statusArgumentCaptor; @Before public void setUp() { MockitoAnnotations.initMocks(this); when(provider.get(any(CallOptions.class))).thenReturn(transport); when(transport.newStream( any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class))) .thenReturn(stream); } @After public void tearDown() { Context.ROOT.attach(); } @Test public void advertisedEncodingsAreSent() { ClientCallImpl<Void, Void> call = new ClientCallImpl<Void, Void>( method, MoreExecutors.directExecutor(), CallOptions.DEFAULT, provider, deadlineCancellationExecutor) .setDecompressorRegistry(decompressorRegistry); call.start(callListener, new Metadata()); ArgumentCaptor<Metadata> metadataCaptor = ArgumentCaptor.forClass(Metadata.class); verify(transport).newStream(eq(method), metadataCaptor.capture(), same(CallOptions.DEFAULT)); Metadata actual = metadataCaptor.getValue(); Set<String> acceptedEncodings = ImmutableSet.copyOf(actual.getAll(GrpcUtil.MESSAGE_ACCEPT_ENCODING_KEY)); assertEquals(decompressorRegistry.getAdvertisedMessageEncodings(), acceptedEncodings); } @Test public void authorityPropagatedToStream() { ClientCallImpl<Void, Void> call = new ClientCallImpl<Void, Void>( method, MoreExecutors.directExecutor(), CallOptions.DEFAULT.withAuthority("overridden-authority"), provider, deadlineCancellationExecutor) .setDecompressorRegistry(decompressorRegistry); call.start(callListener, new Metadata()); verify(stream).setAuthority("overridden-authority"); } @Test public void callOptionsPropagatedToTransport() { final CallOptions callOptions = CallOptions.DEFAULT.withAuthority("dummy_value"); final ClientCallImpl<Void, Void> call = new ClientCallImpl<Void, Void>( method, MoreExecutors.directExecutor(), callOptions, provider, deadlineCancellationExecutor) .setDecompressorRegistry(decompressorRegistry); final Metadata metadata = new Metadata(); call.start(callListener, metadata); verify(transport).newStream(same(method), same(metadata), same(callOptions)); } @Test public void authorityNotPropagatedToStream() { ClientCallImpl<Void, Void> call = new ClientCallImpl<Void, Void>( method, MoreExecutors.directExecutor(), // Don't provide an authority CallOptions.DEFAULT, provider, deadlineCancellationExecutor) .setDecompressorRegistry(decompressorRegistry); call.start(callListener, new Metadata()); verify(stream, never()).setAuthority(any(String.class)); } @Test public void prepareHeaders_userAgentIgnored() { Metadata m = new Metadata(); m.put(GrpcUtil.USER_AGENT_KEY, "batmobile"); ClientCallImpl.prepareHeaders(m, decompressorRegistry, Codec.Identity.NONE); // User Agent is removed and set by the transport assertThat(m.get(GrpcUtil.USER_AGENT_KEY)).isNotNull(); } @Test public void prepareHeaders_ignoreIdentityEncoding() { Metadata m = new Metadata(); ClientCallImpl.prepareHeaders(m, decompressorRegistry, Codec.Identity.NONE); assertNull(m.get(GrpcUtil.MESSAGE_ENCODING_KEY)); } @Test public void prepareHeaders_acceptedEncodingsAdded() { Metadata m = new Metadata(); DecompressorRegistry customRegistry = DecompressorRegistry.emptyInstance() .with( new Decompressor() { @Override public String getMessageEncoding() { return "a"; } @Override public InputStream decompress(InputStream is) throws IOException { return null; } }, true) .with( new Decompressor() { @Override public String getMessageEncoding() { return "b"; } @Override public InputStream decompress(InputStream is) throws IOException { return null; } }, true) .with( new Decompressor() { @Override public String getMessageEncoding() { return "c"; } @Override public InputStream decompress(InputStream is) throws IOException { return null; } }, false); // not advertised ClientCallImpl.prepareHeaders(m, customRegistry, Codec.Identity.NONE); Iterable<String> acceptedEncodings = ACCEPT_ENCODING_SPLITER.split(m.get(GrpcUtil.MESSAGE_ACCEPT_ENCODING_KEY)); // Order may be different, since decoder priorities have not yet been implemented. assertEquals(ImmutableSet.of("b", "a"), ImmutableSet.copyOf(acceptedEncodings)); } @Test public void prepareHeaders_removeReservedHeaders() { Metadata m = new Metadata(); m.put(GrpcUtil.MESSAGE_ENCODING_KEY, "gzip"); m.put(GrpcUtil.MESSAGE_ACCEPT_ENCODING_KEY, "gzip"); ClientCallImpl.prepareHeaders(m, DecompressorRegistry.emptyInstance(), Codec.Identity.NONE); assertNull(m.get(GrpcUtil.MESSAGE_ENCODING_KEY)); assertNull(m.get(GrpcUtil.MESSAGE_ACCEPT_ENCODING_KEY)); } @Test public void callerContextPropagatedToListener() throws Exception { // Attach the context which is recorded when the call is created final Context.Key<String> testKey = Context.key("testing"); Context.current().withValue(testKey, "testValue").attach(); ClientCallImpl<Void, Void> call = new ClientCallImpl<Void, Void>( DESCRIPTOR, new SerializingExecutor(Executors.newSingleThreadExecutor()), CallOptions.DEFAULT, provider, deadlineCancellationExecutor) .setDecompressorRegistry(decompressorRegistry); Context.ROOT.attach(); // Override the value after creating the call, this should not be seen by callbacks Context.current().withValue(testKey, "badValue").attach(); final AtomicBoolean onHeadersCalled = new AtomicBoolean(); final AtomicBoolean onMessageCalled = new AtomicBoolean(); final AtomicBoolean onReadyCalled = new AtomicBoolean(); final AtomicBoolean observedIncorrectContext = new AtomicBoolean(); final CountDownLatch latch = new CountDownLatch(1); call.start( new ClientCall.Listener<Void>() { @Override public void onHeaders(Metadata headers) { onHeadersCalled.set(true); checkContext(); } @Override public void onMessage(Void message) { onMessageCalled.set(true); checkContext(); } @Override public void onClose(Status status, Metadata trailers) { checkContext(); latch.countDown(); } @Override public void onReady() { onReadyCalled.set(true); checkContext(); } private void checkContext() { if (!"testValue".equals(testKey.get())) { observedIncorrectContext.set(true); } } }, new Metadata()); verify(stream).start(listenerArgumentCaptor.capture()); ClientStreamListener listener = listenerArgumentCaptor.getValue(); listener.onReady(); listener.headersRead(new Metadata()); listener.messageRead(new ByteArrayInputStream(new byte[0])); listener.messageRead(new ByteArrayInputStream(new byte[0])); listener.closed(Status.OK, new Metadata()); assertTrue(latch.await(5, TimeUnit.SECONDS)); assertTrue(onHeadersCalled.get()); assertTrue(onMessageCalled.get()); assertTrue(onReadyCalled.get()); assertFalse(observedIncorrectContext.get()); } @Test public void contextCancellationCancelsStream() throws Exception { // Attach the context which is recorded when the call is created Context.CancellableContext cancellableContext = Context.current().withCancellation(); Context previous = cancellableContext.attach(); ClientCallImpl<Void, Void> call = new ClientCallImpl<Void, Void>( DESCRIPTOR, new SerializingExecutor(Executors.newSingleThreadExecutor()), CallOptions.DEFAULT, provider, deadlineCancellationExecutor) .setDecompressorRegistry(decompressorRegistry); previous.attach(); call.start(callListener, new Metadata()); Throwable t = new Throwable(); cancellableContext.cancel(t); verify(stream, times(1)).cancel(statusArgumentCaptor.capture()); verify(stream, times(1)).cancel(statusCaptor.capture()); assertEquals(Status.Code.CANCELLED, statusCaptor.getValue().getCode()); } @Test public void contextAlreadyCancelledNotifiesImmediately() throws Exception { // Attach the context which is recorded when the call is created Context.CancellableContext cancellableContext = Context.current().withCancellation(); Throwable cause = new Throwable(); cancellableContext.cancel(cause); Context previous = cancellableContext.attach(); ClientCallImpl<Void, Void> call = new ClientCallImpl<Void, Void>( DESCRIPTOR, new SerializingExecutor(Executors.newSingleThreadExecutor()), CallOptions.DEFAULT, provider, deadlineCancellationExecutor) .setDecompressorRegistry(decompressorRegistry); previous.attach(); final SettableFuture<Status> statusFuture = SettableFuture.create(); call.start( new ClientCall.Listener<Void>() { @Override public void onClose(Status status, Metadata trailers) { statusFuture.set(status); } }, new Metadata()); // Caller should receive onClose callback. Status status = statusFuture.get(5, TimeUnit.SECONDS); assertEquals(Status.Code.CANCELLED, status.getCode()); assertSame(cause, status.getCause()); // Following operations should be no-op. call.request(1); call.sendMessage(null); call.halfClose(); // Stream should never be created. verifyZeroInteractions(transport); try { call.sendMessage(null); fail("Call has been cancelled"); } catch (IllegalStateException ise) { // expected } } @Test public void deadlineExceededBeforeCallStarted() { CallOptions callOptions = CallOptions.DEFAULT.withDeadlineAfter(0, TimeUnit.SECONDS); fakeClock.forwardTime(System.nanoTime(), TimeUnit.NANOSECONDS); ClientCallImpl<Void, Void> call = new ClientCallImpl<Void, Void>( DESCRIPTOR, new SerializingExecutor(Executors.newSingleThreadExecutor()), callOptions, provider, deadlineCancellationExecutor) .setDecompressorRegistry(decompressorRegistry); call.start(callListener, new Metadata()); verify(transport, times(0)).newStream(any(MethodDescriptor.class), any(Metadata.class)); verify(callListener, timeout(1000)).onClose(statusCaptor.capture(), any(Metadata.class)); assertEquals(Status.Code.DEADLINE_EXCEEDED, statusCaptor.getValue().getCode()); verifyZeroInteractions(provider); } @Test public void contextDeadlineShouldBePropagatedInMetadata() { long deadlineNanos = TimeUnit.SECONDS.toNanos(1); Context context = Context.current() .withDeadlineAfter(deadlineNanos, TimeUnit.NANOSECONDS, deadlineCancellationExecutor); context.attach(); ClientCallImpl<Void, Void> call = new ClientCallImpl<Void, Void>( DESCRIPTOR, MoreExecutors.directExecutor(), CallOptions.DEFAULT, provider, deadlineCancellationExecutor); Metadata headers = new Metadata(); call.start(callListener, headers); assertTrue(headers.containsKey(GrpcUtil.TIMEOUT_KEY)); Long timeout = headers.get(GrpcUtil.TIMEOUT_KEY); assertNotNull(timeout); long deltaNanos = TimeUnit.MILLISECONDS.toNanos(400); assertTimeoutBetween(timeout, deadlineNanos - deltaNanos, deadlineNanos); } @Test public void contextDeadlineShouldOverrideLargerMetadataTimeout() { long deadlineNanos = TimeUnit.SECONDS.toNanos(1); Context context = Context.current() .withDeadlineAfter(deadlineNanos, TimeUnit.NANOSECONDS, deadlineCancellationExecutor); context.attach(); CallOptions callOpts = CallOptions.DEFAULT.withDeadlineAfter(2, TimeUnit.SECONDS); ClientCallImpl<Void, Void> call = new ClientCallImpl<Void, Void>( DESCRIPTOR, MoreExecutors.directExecutor(), callOpts, provider, deadlineCancellationExecutor); Metadata headers = new Metadata(); call.start(callListener, headers); assertTrue(headers.containsKey(GrpcUtil.TIMEOUT_KEY)); Long timeout = headers.get(GrpcUtil.TIMEOUT_KEY); assertNotNull(timeout); long deltaNanos = TimeUnit.MILLISECONDS.toNanos(400); assertTimeoutBetween(timeout, deadlineNanos - deltaNanos, deadlineNanos); } @Test public void contextDeadlineShouldNotOverrideSmallerMetadataTimeout() { long deadlineNanos = TimeUnit.SECONDS.toNanos(2); Context context = Context.current() .withDeadlineAfter(deadlineNanos, TimeUnit.NANOSECONDS, deadlineCancellationExecutor); context.attach(); CallOptions callOpts = CallOptions.DEFAULT.withDeadlineAfter(1, TimeUnit.SECONDS); ClientCallImpl<Void, Void> call = new ClientCallImpl<Void, Void>( DESCRIPTOR, MoreExecutors.directExecutor(), callOpts, provider, deadlineCancellationExecutor); Metadata headers = new Metadata(); call.start(callListener, headers); assertTrue(headers.containsKey(GrpcUtil.TIMEOUT_KEY)); Long timeout = headers.get(GrpcUtil.TIMEOUT_KEY); assertNotNull(timeout); long callOptsNanos = TimeUnit.SECONDS.toNanos(1); long deltaNanos = TimeUnit.MILLISECONDS.toNanos(400); assertTimeoutBetween(timeout, callOptsNanos - deltaNanos, callOptsNanos); } @Test public void expiredDeadlineCancelsStream_CallOptions() { fakeClock.forwardTime(System.nanoTime(), TimeUnit.NANOSECONDS); ClientCallImpl<Void, Void> call = new ClientCallImpl<Void, Void>( DESCRIPTOR, MoreExecutors.directExecutor(), CallOptions.DEFAULT.withDeadline(Deadline.after(1000, TimeUnit.MILLISECONDS)), provider, deadlineCancellationExecutor); call.start(callListener, new Metadata()); fakeClock.forwardMillis(1001); verify(stream, times(1)).cancel(statusCaptor.capture()); assertEquals(Status.Code.DEADLINE_EXCEEDED, statusCaptor.getValue().getCode()); } @Test public void expiredDeadlineCancelsStream_Context() { fakeClock.forwardTime(System.nanoTime(), TimeUnit.NANOSECONDS); Context.current() .withDeadlineAfter(1000, TimeUnit.MILLISECONDS, deadlineCancellationExecutor) .attach(); ClientCallImpl<Void, Void> call = new ClientCallImpl<Void, Void>( DESCRIPTOR, MoreExecutors.directExecutor(), CallOptions.DEFAULT, provider, deadlineCancellationExecutor); call.start(callListener, new Metadata()); fakeClock.forwardMillis(TimeUnit.SECONDS.toMillis(1001)); verify(stream, times(1)).cancel(statusCaptor.capture()); assertEquals(Status.Code.DEADLINE_EXCEEDED, statusCaptor.getValue().getCode()); } @Test public void streamCancelAbortsDeadlineTimer() { fakeClock.forwardTime(System.nanoTime(), TimeUnit.NANOSECONDS); ClientCallImpl<Void, Void> call = new ClientCallImpl<Void, Void>( DESCRIPTOR, MoreExecutors.directExecutor(), CallOptions.DEFAULT.withDeadline(Deadline.after(1000, TimeUnit.MILLISECONDS)), provider, deadlineCancellationExecutor); call.start(callListener, new Metadata()); call.cancel("canceled", null); // Run the deadline timer, which should have been cancelled by the previous call to cancel() fakeClock.forwardMillis(1001); verify(stream, times(1)).cancel(statusCaptor.capture()); assertEquals(Status.CANCELLED.getCode(), statusCaptor.getValue().getCode()); } /** Without a context or call options deadline, a timeout should not be set in metadata. */ @Test public void timeoutShouldNotBeSet() { ClientCallImpl<Void, Void> call = new ClientCallImpl<Void, Void>( DESCRIPTOR, MoreExecutors.directExecutor(), CallOptions.DEFAULT, provider, deadlineCancellationExecutor); Metadata headers = new Metadata(); call.start(callListener, headers); assertFalse(headers.containsKey(GrpcUtil.TIMEOUT_KEY)); } @Test public void cancelInOnMessageShouldInvokeStreamCancel() throws Exception { final ClientCallImpl<Void, Void> call = new ClientCallImpl<Void, Void>( DESCRIPTOR, MoreExecutors.directExecutor(), CallOptions.DEFAULT, provider, deadlineCancellationExecutor); final Exception cause = new Exception(); ClientCall.Listener<Void> callListener = new ClientCall.Listener<Void>() { @Override public void onMessage(Void message) { call.cancel("foo", cause); } }; call.start(callListener, new Metadata()); call.halfClose(); call.request(1); verify(stream).start(listenerArgumentCaptor.capture()); ClientStreamListener streamListener = listenerArgumentCaptor.getValue(); streamListener.onReady(); streamListener.headersRead(new Metadata()); streamListener.messageRead(new ByteArrayInputStream(new byte[0])); verify(stream).cancel(statusCaptor.capture()); Status status = statusCaptor.getValue(); assertEquals(Status.CANCELLED.getCode(), status.getCode()); assertEquals("foo", status.getDescription()); assertSame(cause, status.getCause()); } private static class TestMarshaller<T> implements Marshaller<T> { @Override public InputStream stream(T value) { return null; } @Override public T parse(InputStream stream) { return null; } } private static void assertTimeoutBetween(long timeout, long from, long to) { assertTrue("timeout: " + timeout + " ns", timeout <= to); assertTrue("timeout: " + timeout + " ns", timeout >= from); } }
@javax.annotation.Generated( value = "by gRPC proto compiler (version 1.1.0-SNAPSHOT)", comments = "Source: io/grpc/testing/integration/metrics.proto") public class MetricsServiceGrpc { private MetricsServiceGrpc() {} public static final String SERVICE_NAME = "grpc.testing.MetricsService"; // Static method descriptors that strictly reflect the proto. @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901") public static final io.grpc.MethodDescriptor< io.grpc.testing.integration.Metrics.EmptyMessage, io.grpc.testing.integration.Metrics.GaugeResponse> METHOD_GET_ALL_GAUGES = io.grpc.MethodDescriptor.create( io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING, generateFullMethodName("grpc.testing.MetricsService", "GetAllGauges"), io.grpc.protobuf.ProtoUtils.marshaller( io.grpc.testing.integration.Metrics.EmptyMessage.getDefaultInstance()), io.grpc.protobuf.ProtoUtils.marshaller( io.grpc.testing.integration.Metrics.GaugeResponse.getDefaultInstance())); @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901") public static final io.grpc.MethodDescriptor< io.grpc.testing.integration.Metrics.GaugeRequest, io.grpc.testing.integration.Metrics.GaugeResponse> METHOD_GET_GAUGE = io.grpc.MethodDescriptor.create( io.grpc.MethodDescriptor.MethodType.UNARY, generateFullMethodName("grpc.testing.MetricsService", "GetGauge"), io.grpc.protobuf.ProtoUtils.marshaller( io.grpc.testing.integration.Metrics.GaugeRequest.getDefaultInstance()), io.grpc.protobuf.ProtoUtils.marshaller( io.grpc.testing.integration.Metrics.GaugeResponse.getDefaultInstance())); /** Creates a new async stub that supports all call types for the service */ public static MetricsServiceStub newStub(io.grpc.Channel channel) { return new MetricsServiceStub(channel); } /** * Creates a new blocking-style stub that supports unary and streaming output calls on the service */ public static MetricsServiceBlockingStub newBlockingStub(io.grpc.Channel channel) { return new MetricsServiceBlockingStub(channel); } /** * Creates a new ListenableFuture-style stub that supports unary and streaming output calls on the * service */ public static MetricsServiceFutureStub newFutureStub(io.grpc.Channel channel) { return new MetricsServiceFutureStub(channel); } /** */ public abstract static class MetricsServiceImplBase implements io.grpc.BindableService { /** * * * <pre> * Returns the values of all the gauges that are currently being maintained by * the service * </pre> */ public void getAllGauges( io.grpc.testing.integration.Metrics.EmptyMessage request, io.grpc.stub.StreamObserver<io.grpc.testing.integration.Metrics.GaugeResponse> responseObserver) { asyncUnimplementedUnaryCall(METHOD_GET_ALL_GAUGES, responseObserver); } /** * * * <pre> * Returns the value of one gauge * </pre> */ public void getGauge( io.grpc.testing.integration.Metrics.GaugeRequest request, io.grpc.stub.StreamObserver<io.grpc.testing.integration.Metrics.GaugeResponse> responseObserver) { asyncUnimplementedUnaryCall(METHOD_GET_GAUGE, responseObserver); } @java.lang.Override public io.grpc.ServerServiceDefinition bindService() { return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) .addMethod( METHOD_GET_ALL_GAUGES, asyncServerStreamingCall( new MethodHandlers< io.grpc.testing.integration.Metrics.EmptyMessage, io.grpc.testing.integration.Metrics.GaugeResponse>( this, METHODID_GET_ALL_GAUGES))) .addMethod( METHOD_GET_GAUGE, asyncUnaryCall( new MethodHandlers< io.grpc.testing.integration.Metrics.GaugeRequest, io.grpc.testing.integration.Metrics.GaugeResponse>(this, METHODID_GET_GAUGE))) .build(); } } /** */ public static final class MetricsServiceStub extends io.grpc.stub.AbstractStub<MetricsServiceStub> { private MetricsServiceStub(io.grpc.Channel channel) { super(channel); } private MetricsServiceStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); } @java.lang.Override protected MetricsServiceStub build(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { return new MetricsServiceStub(channel, callOptions); } /** * * * <pre> * Returns the values of all the gauges that are currently being maintained by * the service * </pre> */ public void getAllGauges( io.grpc.testing.integration.Metrics.EmptyMessage request, io.grpc.stub.StreamObserver<io.grpc.testing.integration.Metrics.GaugeResponse> responseObserver) { asyncServerStreamingCall( getChannel().newCall(METHOD_GET_ALL_GAUGES, getCallOptions()), request, responseObserver); } /** * * * <pre> * Returns the value of one gauge * </pre> */ public void getGauge( io.grpc.testing.integration.Metrics.GaugeRequest request, io.grpc.stub.StreamObserver<io.grpc.testing.integration.Metrics.GaugeResponse> responseObserver) { asyncUnaryCall( getChannel().newCall(METHOD_GET_GAUGE, getCallOptions()), request, responseObserver); } } /** */ public static final class MetricsServiceBlockingStub extends io.grpc.stub.AbstractStub<MetricsServiceBlockingStub> { private MetricsServiceBlockingStub(io.grpc.Channel channel) { super(channel); } private MetricsServiceBlockingStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); } @java.lang.Override protected MetricsServiceBlockingStub build( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { return new MetricsServiceBlockingStub(channel, callOptions); } /** * * * <pre> * Returns the values of all the gauges that are currently being maintained by * the service * </pre> */ public java.util.Iterator<io.grpc.testing.integration.Metrics.GaugeResponse> getAllGauges( io.grpc.testing.integration.Metrics.EmptyMessage request) { return blockingServerStreamingCall( getChannel(), METHOD_GET_ALL_GAUGES, getCallOptions(), request); } /** * * * <pre> * Returns the value of one gauge * </pre> */ public io.grpc.testing.integration.Metrics.GaugeResponse getGauge( io.grpc.testing.integration.Metrics.GaugeRequest request) { return blockingUnaryCall(getChannel(), METHOD_GET_GAUGE, getCallOptions(), request); } } /** */ public static final class MetricsServiceFutureStub extends io.grpc.stub.AbstractStub<MetricsServiceFutureStub> { private MetricsServiceFutureStub(io.grpc.Channel channel) { super(channel); } private MetricsServiceFutureStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); } @java.lang.Override protected MetricsServiceFutureStub build( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { return new MetricsServiceFutureStub(channel, callOptions); } /** * * * <pre> * Returns the value of one gauge * </pre> */ public com.google.common.util.concurrent.ListenableFuture< io.grpc.testing.integration.Metrics.GaugeResponse> getGauge(io.grpc.testing.integration.Metrics.GaugeRequest request) { return futureUnaryCall(getChannel().newCall(METHOD_GET_GAUGE, getCallOptions()), request); } } private static final int METHODID_GET_ALL_GAUGES = 0; private static final int METHODID_GET_GAUGE = 1; private static class MethodHandlers<Req, Resp> implements io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>, io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>, io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>, io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> { private final MetricsServiceImplBase serviceImpl; private final int methodId; public MethodHandlers(MetricsServiceImplBase serviceImpl, int methodId) { this.serviceImpl = serviceImpl; this.methodId = methodId; } @java.lang.Override @java.lang.SuppressWarnings("unchecked") public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) { switch (methodId) { case METHODID_GET_ALL_GAUGES: serviceImpl.getAllGauges( (io.grpc.testing.integration.Metrics.EmptyMessage) request, (io.grpc.stub.StreamObserver<io.grpc.testing.integration.Metrics.GaugeResponse>) responseObserver); break; case METHODID_GET_GAUGE: serviceImpl.getGauge( (io.grpc.testing.integration.Metrics.GaugeRequest) request, (io.grpc.stub.StreamObserver<io.grpc.testing.integration.Metrics.GaugeResponse>) responseObserver); break; default: throw new AssertionError(); } } @java.lang.Override @java.lang.SuppressWarnings("unchecked") public io.grpc.stub.StreamObserver<Req> invoke( io.grpc.stub.StreamObserver<Resp> responseObserver) { switch (methodId) { default: throw new AssertionError(); } } } public static io.grpc.ServiceDescriptor getServiceDescriptor() { return new io.grpc.ServiceDescriptor(SERVICE_NAME, METHOD_GET_ALL_GAUGES, METHOD_GET_GAUGE); } }
/** * * * <pre> * Service for creating, configuring, and deleting Cloud Bigtable tables. * Provides access to the table schemas only, not the data stored within * the tables. * </pre> */ @javax.annotation.Generated( value = "by gRPC proto compiler (version 0.14.1)", comments = "Source: google/bigtable/admin/v2/bigtable_table_admin.proto") public class BigtableTableAdminGrpc { private BigtableTableAdminGrpc() {} public static final String SERVICE_NAME = "google.bigtable.admin.v2.BigtableTableAdmin"; // Static method descriptors that strictly reflect the proto. @io.grpc.ExperimentalApi public static final io.grpc.MethodDescriptor< com.google.bigtable.admin.v2.CreateTableRequest, com.google.bigtable.admin.v2.Table> METHOD_CREATE_TABLE = io.grpc.MethodDescriptor.create( io.grpc.MethodDescriptor.MethodType.UNARY, generateFullMethodName("google.bigtable.admin.v2.BigtableTableAdmin", "CreateTable"), io.grpc.protobuf.ProtoUtils.marshaller( com.google.bigtable.admin.v2.CreateTableRequest.getDefaultInstance()), io.grpc.protobuf.ProtoUtils.marshaller( com.google.bigtable.admin.v2.Table.getDefaultInstance())); @io.grpc.ExperimentalApi public static final io.grpc.MethodDescriptor< com.google.bigtable.admin.v2.ListTablesRequest, com.google.bigtable.admin.v2.ListTablesResponse> METHOD_LIST_TABLES = io.grpc.MethodDescriptor.create( io.grpc.MethodDescriptor.MethodType.UNARY, generateFullMethodName("google.bigtable.admin.v2.BigtableTableAdmin", "ListTables"), io.grpc.protobuf.ProtoUtils.marshaller( com.google.bigtable.admin.v2.ListTablesRequest.getDefaultInstance()), io.grpc.protobuf.ProtoUtils.marshaller( com.google.bigtable.admin.v2.ListTablesResponse.getDefaultInstance())); @io.grpc.ExperimentalApi public static final io.grpc.MethodDescriptor< com.google.bigtable.admin.v2.GetTableRequest, com.google.bigtable.admin.v2.Table> METHOD_GET_TABLE = io.grpc.MethodDescriptor.create( io.grpc.MethodDescriptor.MethodType.UNARY, generateFullMethodName("google.bigtable.admin.v2.BigtableTableAdmin", "GetTable"), io.grpc.protobuf.ProtoUtils.marshaller( com.google.bigtable.admin.v2.GetTableRequest.getDefaultInstance()), io.grpc.protobuf.ProtoUtils.marshaller( com.google.bigtable.admin.v2.Table.getDefaultInstance())); @io.grpc.ExperimentalApi public static final io.grpc.MethodDescriptor< com.google.bigtable.admin.v2.DeleteTableRequest, com.google.protobuf.Empty> METHOD_DELETE_TABLE = io.grpc.MethodDescriptor.create( io.grpc.MethodDescriptor.MethodType.UNARY, generateFullMethodName("google.bigtable.admin.v2.BigtableTableAdmin", "DeleteTable"), io.grpc.protobuf.ProtoUtils.marshaller( com.google.bigtable.admin.v2.DeleteTableRequest.getDefaultInstance()), io.grpc.protobuf.ProtoUtils.marshaller( com.google.protobuf.Empty.getDefaultInstance())); @io.grpc.ExperimentalApi public static final io.grpc.MethodDescriptor< com.google.bigtable.admin.v2.ModifyColumnFamiliesRequest, com.google.bigtable.admin.v2.Table> METHOD_MODIFY_COLUMN_FAMILIES = io.grpc.MethodDescriptor.create( io.grpc.MethodDescriptor.MethodType.UNARY, generateFullMethodName( "google.bigtable.admin.v2.BigtableTableAdmin", "ModifyColumnFamilies"), io.grpc.protobuf.ProtoUtils.marshaller( com.google.bigtable.admin.v2.ModifyColumnFamiliesRequest.getDefaultInstance()), io.grpc.protobuf.ProtoUtils.marshaller( com.google.bigtable.admin.v2.Table.getDefaultInstance())); @io.grpc.ExperimentalApi public static final io.grpc.MethodDescriptor< com.google.bigtable.admin.v2.DropRowRangeRequest, com.google.protobuf.Empty> METHOD_DROP_ROW_RANGE = io.grpc.MethodDescriptor.create( io.grpc.MethodDescriptor.MethodType.UNARY, generateFullMethodName("google.bigtable.admin.v2.BigtableTableAdmin", "DropRowRange"), io.grpc.protobuf.ProtoUtils.marshaller( com.google.bigtable.admin.v2.DropRowRangeRequest.getDefaultInstance()), io.grpc.protobuf.ProtoUtils.marshaller( com.google.protobuf.Empty.getDefaultInstance())); /** Creates a new async stub that supports all call types for the service */ public static BigtableTableAdminStub newStub(io.grpc.Channel channel) { return new BigtableTableAdminStub(channel); } /** * Creates a new blocking-style stub that supports unary and streaming output calls on the service */ public static BigtableTableAdminBlockingStub newBlockingStub(io.grpc.Channel channel) { return new BigtableTableAdminBlockingStub(channel); } /** * Creates a new ListenableFuture-style stub that supports unary and streaming output calls on the * service */ public static BigtableTableAdminFutureStub newFutureStub(io.grpc.Channel channel) { return new BigtableTableAdminFutureStub(channel); } /** * * * <pre> * Service for creating, configuring, and deleting Cloud Bigtable tables. * Provides access to the table schemas only, not the data stored within * the tables. * </pre> */ public static interface BigtableTableAdmin { /** * * * <pre> * Creates a new table in the specified instance. * The table can be created with a full set of initial column families, * specified in the request. * </pre> */ public void createTable( com.google.bigtable.admin.v2.CreateTableRequest request, io.grpc.stub.StreamObserver<com.google.bigtable.admin.v2.Table> responseObserver); /** * * * <pre> * Lists all tables served from a specified instance. * </pre> */ public void listTables( com.google.bigtable.admin.v2.ListTablesRequest request, io.grpc.stub.StreamObserver<com.google.bigtable.admin.v2.ListTablesResponse> responseObserver); /** * * * <pre> * Gets metadata information about the specified table. * </pre> */ public void getTable( com.google.bigtable.admin.v2.GetTableRequest request, io.grpc.stub.StreamObserver<com.google.bigtable.admin.v2.Table> responseObserver); /** * * * <pre> * Permanently deletes a specified table and all of its data. * </pre> */ public void deleteTable( com.google.bigtable.admin.v2.DeleteTableRequest request, io.grpc.stub.StreamObserver<com.google.protobuf.Empty> responseObserver); /** * * * <pre> * Atomically performs a series of column family modifications * on the specified table. * </pre> */ public void modifyColumnFamilies( com.google.bigtable.admin.v2.ModifyColumnFamiliesRequest request, io.grpc.stub.StreamObserver<com.google.bigtable.admin.v2.Table> responseObserver); /** * * * <pre> * Permanently drop/delete a row range from a specified table. The request can * specify whether to delete all rows in a table, or only those that match a * particular prefix. * </pre> */ public void dropRowRange( com.google.bigtable.admin.v2.DropRowRangeRequest request, io.grpc.stub.StreamObserver<com.google.protobuf.Empty> responseObserver); } @io.grpc.ExperimentalApi public abstract static class AbstractBigtableTableAdmin implements BigtableTableAdmin, io.grpc.BindableService { @java.lang.Override public void createTable( com.google.bigtable.admin.v2.CreateTableRequest request, io.grpc.stub.StreamObserver<com.google.bigtable.admin.v2.Table> responseObserver) { asyncUnimplementedUnaryCall(METHOD_CREATE_TABLE, responseObserver); } @java.lang.Override public void listTables( com.google.bigtable.admin.v2.ListTablesRequest request, io.grpc.stub.StreamObserver<com.google.bigtable.admin.v2.ListTablesResponse> responseObserver) { asyncUnimplementedUnaryCall(METHOD_LIST_TABLES, responseObserver); } @java.lang.Override public void getTable( com.google.bigtable.admin.v2.GetTableRequest request, io.grpc.stub.StreamObserver<com.google.bigtable.admin.v2.Table> responseObserver) { asyncUnimplementedUnaryCall(METHOD_GET_TABLE, responseObserver); } @java.lang.Override public void deleteTable( com.google.bigtable.admin.v2.DeleteTableRequest request, io.grpc.stub.StreamObserver<com.google.protobuf.Empty> responseObserver) { asyncUnimplementedUnaryCall(METHOD_DELETE_TABLE, responseObserver); } @java.lang.Override public void modifyColumnFamilies( com.google.bigtable.admin.v2.ModifyColumnFamiliesRequest request, io.grpc.stub.StreamObserver<com.google.bigtable.admin.v2.Table> responseObserver) { asyncUnimplementedUnaryCall(METHOD_MODIFY_COLUMN_FAMILIES, responseObserver); } @java.lang.Override public void dropRowRange( com.google.bigtable.admin.v2.DropRowRangeRequest request, io.grpc.stub.StreamObserver<com.google.protobuf.Empty> responseObserver) { asyncUnimplementedUnaryCall(METHOD_DROP_ROW_RANGE, responseObserver); } @java.lang.Override public io.grpc.ServerServiceDefinition bindService() { return BigtableTableAdminGrpc.bindService(this); } } /** * * * <pre> * Service for creating, configuring, and deleting Cloud Bigtable tables. * Provides access to the table schemas only, not the data stored within * the tables. * </pre> */ public static interface BigtableTableAdminBlockingClient { /** * * * <pre> * Creates a new table in the specified instance. * The table can be created with a full set of initial column families, * specified in the request. * </pre> */ public com.google.bigtable.admin.v2.Table createTable( com.google.bigtable.admin.v2.CreateTableRequest request); /** * * * <pre> * Lists all tables served from a specified instance. * </pre> */ public com.google.bigtable.admin.v2.ListTablesResponse listTables( com.google.bigtable.admin.v2.ListTablesRequest request); /** * * * <pre> * Gets metadata information about the specified table. * </pre> */ public com.google.bigtable.admin.v2.Table getTable( com.google.bigtable.admin.v2.GetTableRequest request); /** * * * <pre> * Permanently deletes a specified table and all of its data. * </pre> */ public com.google.protobuf.Empty deleteTable( com.google.bigtable.admin.v2.DeleteTableRequest request); /** * * * <pre> * Atomically performs a series of column family modifications * on the specified table. * </pre> */ public com.google.bigtable.admin.v2.Table modifyColumnFamilies( com.google.bigtable.admin.v2.ModifyColumnFamiliesRequest request); /** * * * <pre> * Permanently drop/delete a row range from a specified table. The request can * specify whether to delete all rows in a table, or only those that match a * particular prefix. * </pre> */ public com.google.protobuf.Empty dropRowRange( com.google.bigtable.admin.v2.DropRowRangeRequest request); } /** * * * <pre> * Service for creating, configuring, and deleting Cloud Bigtable tables. * Provides access to the table schemas only, not the data stored within * the tables. * </pre> */ public static interface BigtableTableAdminFutureClient { /** * * * <pre> * Creates a new table in the specified instance. * The table can be created with a full set of initial column families, * specified in the request. * </pre> */ public com.google.common.util.concurrent.ListenableFuture<com.google.bigtable.admin.v2.Table> createTable(com.google.bigtable.admin.v2.CreateTableRequest request); /** * * * <pre> * Lists all tables served from a specified instance. * </pre> */ public com.google.common.util.concurrent.ListenableFuture< com.google.bigtable.admin.v2.ListTablesResponse> listTables(com.google.bigtable.admin.v2.ListTablesRequest request); /** * * * <pre> * Gets metadata information about the specified table. * </pre> */ public com.google.common.util.concurrent.ListenableFuture<com.google.bigtable.admin.v2.Table> getTable(com.google.bigtable.admin.v2.GetTableRequest request); /** * * * <pre> * Permanently deletes a specified table and all of its data. * </pre> */ public com.google.common.util.concurrent.ListenableFuture<com.google.protobuf.Empty> deleteTable(com.google.bigtable.admin.v2.DeleteTableRequest request); /** * * * <pre> * Atomically performs a series of column family modifications * on the specified table. * </pre> */ public com.google.common.util.concurrent.ListenableFuture<com.google.bigtable.admin.v2.Table> modifyColumnFamilies(com.google.bigtable.admin.v2.ModifyColumnFamiliesRequest request); /** * * * <pre> * Permanently drop/delete a row range from a specified table. The request can * specify whether to delete all rows in a table, or only those that match a * particular prefix. * </pre> */ public com.google.common.util.concurrent.ListenableFuture<com.google.protobuf.Empty> dropRowRange(com.google.bigtable.admin.v2.DropRowRangeRequest request); } public static class BigtableTableAdminStub extends io.grpc.stub.AbstractStub<BigtableTableAdminStub> implements BigtableTableAdmin { private BigtableTableAdminStub(io.grpc.Channel channel) { super(channel); } private BigtableTableAdminStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); } @java.lang.Override protected BigtableTableAdminStub build( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { return new BigtableTableAdminStub(channel, callOptions); } @java.lang.Override public void createTable( com.google.bigtable.admin.v2.CreateTableRequest request, io.grpc.stub.StreamObserver<com.google.bigtable.admin.v2.Table> responseObserver) { asyncUnaryCall( getChannel().newCall(METHOD_CREATE_TABLE, getCallOptions()), request, responseObserver); } @java.lang.Override public void listTables( com.google.bigtable.admin.v2.ListTablesRequest request, io.grpc.stub.StreamObserver<com.google.bigtable.admin.v2.ListTablesResponse> responseObserver) { asyncUnaryCall( getChannel().newCall(METHOD_LIST_TABLES, getCallOptions()), request, responseObserver); } @java.lang.Override public void getTable( com.google.bigtable.admin.v2.GetTableRequest request, io.grpc.stub.StreamObserver<com.google.bigtable.admin.v2.Table> responseObserver) { asyncUnaryCall( getChannel().newCall(METHOD_GET_TABLE, getCallOptions()), request, responseObserver); } @java.lang.Override public void deleteTable( com.google.bigtable.admin.v2.DeleteTableRequest request, io.grpc.stub.StreamObserver<com.google.protobuf.Empty> responseObserver) { asyncUnaryCall( getChannel().newCall(METHOD_DELETE_TABLE, getCallOptions()), request, responseObserver); } @java.lang.Override public void modifyColumnFamilies( com.google.bigtable.admin.v2.ModifyColumnFamiliesRequest request, io.grpc.stub.StreamObserver<com.google.bigtable.admin.v2.Table> responseObserver) { asyncUnaryCall( getChannel().newCall(METHOD_MODIFY_COLUMN_FAMILIES, getCallOptions()), request, responseObserver); } @java.lang.Override public void dropRowRange( com.google.bigtable.admin.v2.DropRowRangeRequest request, io.grpc.stub.StreamObserver<com.google.protobuf.Empty> responseObserver) { asyncUnaryCall( getChannel().newCall(METHOD_DROP_ROW_RANGE, getCallOptions()), request, responseObserver); } } public static class BigtableTableAdminBlockingStub extends io.grpc.stub.AbstractStub<BigtableTableAdminBlockingStub> implements BigtableTableAdminBlockingClient { private BigtableTableAdminBlockingStub(io.grpc.Channel channel) { super(channel); } private BigtableTableAdminBlockingStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); } @java.lang.Override protected BigtableTableAdminBlockingStub build( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { return new BigtableTableAdminBlockingStub(channel, callOptions); } @java.lang.Override public com.google.bigtable.admin.v2.Table createTable( com.google.bigtable.admin.v2.CreateTableRequest request) { return blockingUnaryCall(getChannel(), METHOD_CREATE_TABLE, getCallOptions(), request); } @java.lang.Override public com.google.bigtable.admin.v2.ListTablesResponse listTables( com.google.bigtable.admin.v2.ListTablesRequest request) { return blockingUnaryCall(getChannel(), METHOD_LIST_TABLES, getCallOptions(), request); } @java.lang.Override public com.google.bigtable.admin.v2.Table getTable( com.google.bigtable.admin.v2.GetTableRequest request) { return blockingUnaryCall(getChannel(), METHOD_GET_TABLE, getCallOptions(), request); } @java.lang.Override public com.google.protobuf.Empty deleteTable( com.google.bigtable.admin.v2.DeleteTableRequest request) { return blockingUnaryCall(getChannel(), METHOD_DELETE_TABLE, getCallOptions(), request); } @java.lang.Override public com.google.bigtable.admin.v2.Table modifyColumnFamilies( com.google.bigtable.admin.v2.ModifyColumnFamiliesRequest request) { return blockingUnaryCall( getChannel(), METHOD_MODIFY_COLUMN_FAMILIES, getCallOptions(), request); } @java.lang.Override public com.google.protobuf.Empty dropRowRange( com.google.bigtable.admin.v2.DropRowRangeRequest request) { return blockingUnaryCall(getChannel(), METHOD_DROP_ROW_RANGE, getCallOptions(), request); } } public static class BigtableTableAdminFutureStub extends io.grpc.stub.AbstractStub<BigtableTableAdminFutureStub> implements BigtableTableAdminFutureClient { private BigtableTableAdminFutureStub(io.grpc.Channel channel) { super(channel); } private BigtableTableAdminFutureStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); } @java.lang.Override protected BigtableTableAdminFutureStub build( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { return new BigtableTableAdminFutureStub(channel, callOptions); } @java.lang.Override public com.google.common.util.concurrent.ListenableFuture<com.google.bigtable.admin.v2.Table> createTable(com.google.bigtable.admin.v2.CreateTableRequest request) { return futureUnaryCall(getChannel().newCall(METHOD_CREATE_TABLE, getCallOptions()), request); } @java.lang.Override public com.google.common.util.concurrent.ListenableFuture< com.google.bigtable.admin.v2.ListTablesResponse> listTables(com.google.bigtable.admin.v2.ListTablesRequest request) { return futureUnaryCall(getChannel().newCall(METHOD_LIST_TABLES, getCallOptions()), request); } @java.lang.Override public com.google.common.util.concurrent.ListenableFuture<com.google.bigtable.admin.v2.Table> getTable(com.google.bigtable.admin.v2.GetTableRequest request) { return futureUnaryCall(getChannel().newCall(METHOD_GET_TABLE, getCallOptions()), request); } @java.lang.Override public com.google.common.util.concurrent.ListenableFuture<com.google.protobuf.Empty> deleteTable(com.google.bigtable.admin.v2.DeleteTableRequest request) { return futureUnaryCall(getChannel().newCall(METHOD_DELETE_TABLE, getCallOptions()), request); } @java.lang.Override public com.google.common.util.concurrent.ListenableFuture<com.google.bigtable.admin.v2.Table> modifyColumnFamilies(com.google.bigtable.admin.v2.ModifyColumnFamiliesRequest request) { return futureUnaryCall( getChannel().newCall(METHOD_MODIFY_COLUMN_FAMILIES, getCallOptions()), request); } @java.lang.Override public com.google.common.util.concurrent.ListenableFuture<com.google.protobuf.Empty> dropRowRange(com.google.bigtable.admin.v2.DropRowRangeRequest request) { return futureUnaryCall( getChannel().newCall(METHOD_DROP_ROW_RANGE, getCallOptions()), request); } } private static final int METHODID_CREATE_TABLE = 0; private static final int METHODID_LIST_TABLES = 1; private static final int METHODID_GET_TABLE = 2; private static final int METHODID_DELETE_TABLE = 3; private static final int METHODID_MODIFY_COLUMN_FAMILIES = 4; private static final int METHODID_DROP_ROW_RANGE = 5; private static class MethodHandlers<Req, Resp> implements io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>, io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>, io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>, io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> { private final BigtableTableAdmin serviceImpl; private final int methodId; public MethodHandlers(BigtableTableAdmin serviceImpl, int methodId) { this.serviceImpl = serviceImpl; this.methodId = methodId; } @java.lang.Override @java.lang.SuppressWarnings("unchecked") public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) { switch (methodId) { case METHODID_CREATE_TABLE: serviceImpl.createTable( (com.google.bigtable.admin.v2.CreateTableRequest) request, (io.grpc.stub.StreamObserver<com.google.bigtable.admin.v2.Table>) responseObserver); break; case METHODID_LIST_TABLES: serviceImpl.listTables( (com.google.bigtable.admin.v2.ListTablesRequest) request, (io.grpc.stub.StreamObserver<com.google.bigtable.admin.v2.ListTablesResponse>) responseObserver); break; case METHODID_GET_TABLE: serviceImpl.getTable( (com.google.bigtable.admin.v2.GetTableRequest) request, (io.grpc.stub.StreamObserver<com.google.bigtable.admin.v2.Table>) responseObserver); break; case METHODID_DELETE_TABLE: serviceImpl.deleteTable( (com.google.bigtable.admin.v2.DeleteTableRequest) request, (io.grpc.stub.StreamObserver<com.google.protobuf.Empty>) responseObserver); break; case METHODID_MODIFY_COLUMN_FAMILIES: serviceImpl.modifyColumnFamilies( (com.google.bigtable.admin.v2.ModifyColumnFamiliesRequest) request, (io.grpc.stub.StreamObserver<com.google.bigtable.admin.v2.Table>) responseObserver); break; case METHODID_DROP_ROW_RANGE: serviceImpl.dropRowRange( (com.google.bigtable.admin.v2.DropRowRangeRequest) request, (io.grpc.stub.StreamObserver<com.google.protobuf.Empty>) responseObserver); break; default: throw new AssertionError(); } } @java.lang.Override @java.lang.SuppressWarnings("unchecked") public io.grpc.stub.StreamObserver<Req> invoke( io.grpc.stub.StreamObserver<Resp> responseObserver) { switch (methodId) { default: throw new AssertionError(); } } } public static io.grpc.ServerServiceDefinition bindService(final BigtableTableAdmin serviceImpl) { return io.grpc.ServerServiceDefinition.builder(SERVICE_NAME) .addMethod( METHOD_CREATE_TABLE, asyncUnaryCall( new MethodHandlers< com.google.bigtable.admin.v2.CreateTableRequest, com.google.bigtable.admin.v2.Table>(serviceImpl, METHODID_CREATE_TABLE))) .addMethod( METHOD_LIST_TABLES, asyncUnaryCall( new MethodHandlers< com.google.bigtable.admin.v2.ListTablesRequest, com.google.bigtable.admin.v2.ListTablesResponse>( serviceImpl, METHODID_LIST_TABLES))) .addMethod( METHOD_GET_TABLE, asyncUnaryCall( new MethodHandlers< com.google.bigtable.admin.v2.GetTableRequest, com.google.bigtable.admin.v2.Table>(serviceImpl, METHODID_GET_TABLE))) .addMethod( METHOD_DELETE_TABLE, asyncUnaryCall( new MethodHandlers< com.google.bigtable.admin.v2.DeleteTableRequest, com.google.protobuf.Empty>( serviceImpl, METHODID_DELETE_TABLE))) .addMethod( METHOD_MODIFY_COLUMN_FAMILIES, asyncUnaryCall( new MethodHandlers< com.google.bigtable.admin.v2.ModifyColumnFamiliesRequest, com.google.bigtable.admin.v2.Table>( serviceImpl, METHODID_MODIFY_COLUMN_FAMILIES))) .addMethod( METHOD_DROP_ROW_RANGE, asyncUnaryCall( new MethodHandlers< com.google.bigtable.admin.v2.DropRowRangeRequest, com.google.protobuf.Empty>( serviceImpl, METHODID_DROP_ROW_RANGE))) .build(); } }
/** * Unit tests for {@link TransportSet}. * * <p>It only tests the logic that is not covered by {@link ManagedChannelImplTransportManagerTest}. */ @RunWith(JUnit4.class) public class TransportSetTest { private static final String AUTHORITY = "fakeauthority"; private static final String USER_AGENT = "mosaic"; private FakeClock fakeClock; private FakeClock fakeExecutor; @Mock private LoadBalancer<ClientTransport> mockLoadBalancer; @Mock private BackoffPolicy mockBackoffPolicy1; @Mock private BackoffPolicy mockBackoffPolicy2; @Mock private BackoffPolicy mockBackoffPolicy3; @Mock private BackoffPolicy.Provider mockBackoffPolicyProvider; @Mock private ClientTransportFactory mockTransportFactory; @Mock private TransportSet.Callback mockTransportSetCallback; @Mock private ClientStreamListener mockStreamListener; private final MethodDescriptor<String, Integer> method = MethodDescriptor.create( MethodDescriptor.MethodType.UNKNOWN, "/service/method", new StringMarshaller(), new IntegerMarshaller()); private final Metadata headers = new Metadata(); private final CallOptions waitForReadyCallOptions = CallOptions.DEFAULT.withWaitForReady(); private final CallOptions failFastCallOptions = CallOptions.DEFAULT; private final StatsTraceContext statsTraceCtx = StatsTraceContext.NOOP; private TransportSet transportSet; private EquivalentAddressGroup addressGroup; private BlockingQueue<MockClientTransportInfo> transports; @Before public void setUp() { MockitoAnnotations.initMocks(this); fakeClock = new FakeClock(); fakeExecutor = new FakeClock(); when(mockBackoffPolicyProvider.get()) .thenReturn(mockBackoffPolicy1, mockBackoffPolicy2, mockBackoffPolicy3); when(mockBackoffPolicy1.nextBackoffMillis()).thenReturn(10L, 100L); when(mockBackoffPolicy2.nextBackoffMillis()).thenReturn(10L, 100L); when(mockBackoffPolicy3.nextBackoffMillis()).thenReturn(10L, 100L); transports = TestUtils.captureTransports(mockTransportFactory); } @After public void noMorePendingTasks() { assertEquals(0, fakeClock.numPendingTasks()); assertEquals(0, fakeExecutor.numPendingTasks()); } @Test public void singleAddressReconnect() { SocketAddress addr = mock(SocketAddress.class); createTransportSet(addr); assertEquals(ConnectivityState.IDLE, transportSet.getState(false)); // Invocation counters int transportsCreated = 0; int backoff1Consulted = 0; int backoff2Consulted = 0; int backoffReset = 0; int onAllAddressesFailed = 0; // First attempt transportSet .obtainActiveTransport() .newStream(method, new Metadata(), waitForReadyCallOptions, statsTraceCtx); assertEquals(ConnectivityState.CONNECTING, transportSet.getState(false)); verify(mockTransportFactory, times(++transportsCreated)) .newClientTransport(addr, AUTHORITY, USER_AGENT); // Fail this one transports.poll().listener.transportShutdown(Status.UNAVAILABLE); assertEquals(ConnectivityState.TRANSIENT_FAILURE, transportSet.getState(false)); verify(mockTransportSetCallback, times(++onAllAddressesFailed)).onAllAddressesFailed(); // Backoff reset and using first back-off value interval verify(mockBackoffPolicy1, times(++backoff1Consulted)).nextBackoffMillis(); verify(mockBackoffPolicyProvider, times(++backoffReset)).get(); // Second attempt // Transport creation doesn't happen until time is due fakeClock.forwardMillis(9); verify(mockTransportFactory, times(transportsCreated)) .newClientTransport(addr, AUTHORITY, USER_AGENT); assertEquals(ConnectivityState.TRANSIENT_FAILURE, transportSet.getState(false)); fakeClock.forwardMillis(1); assertEquals(ConnectivityState.CONNECTING, transportSet.getState(false)); verify(mockTransportFactory, times(++transportsCreated)) .newClientTransport(addr, AUTHORITY, USER_AGENT); // Fail this one too transports.poll().listener.transportShutdown(Status.UNAVAILABLE); assertEquals(ConnectivityState.TRANSIENT_FAILURE, transportSet.getState(false)); verify(mockTransportSetCallback, times(++onAllAddressesFailed)).onAllAddressesFailed(); // Second back-off interval verify(mockBackoffPolicy1, times(++backoff1Consulted)).nextBackoffMillis(); verify(mockBackoffPolicyProvider, times(backoffReset)).get(); // Third attempt // Transport creation doesn't happen until time is due fakeClock.forwardMillis(99); verify(mockTransportFactory, times(transportsCreated)) .newClientTransport(addr, AUTHORITY, USER_AGENT); assertEquals(ConnectivityState.TRANSIENT_FAILURE, transportSet.getState(false)); fakeClock.forwardMillis(1); assertEquals(ConnectivityState.CONNECTING, transportSet.getState(false)); verify(mockTransportFactory, times(++transportsCreated)) .newClientTransport(addr, AUTHORITY, USER_AGENT); // Let this one succeed transports.peek().listener.transportReady(); assertEquals(ConnectivityState.READY, transportSet.getState(false)); fakeClock.runDueTasks(); verify(mockTransportSetCallback, never()).onConnectionClosedByServer(any(Status.class)); // And close it transports.poll().listener.transportShutdown(Status.UNAVAILABLE); assertEquals(ConnectivityState.IDLE, transportSet.getState(false)); verify(mockTransportSetCallback).onConnectionClosedByServer(same(Status.UNAVAILABLE)); verify(mockTransportSetCallback, times(onAllAddressesFailed)).onAllAddressesFailed(); // Back-off is reset, and the next attempt will happen immediately transportSet.obtainActiveTransport(); assertEquals(ConnectivityState.CONNECTING, transportSet.getState(false)); verify(mockBackoffPolicyProvider, times(backoffReset)).get(); verify(mockTransportFactory, times(++transportsCreated)) .newClientTransport(addr, AUTHORITY, USER_AGENT); // Final checks for consultations on back-off policies verify(mockBackoffPolicy1, times(backoff1Consulted)).nextBackoffMillis(); verify(mockBackoffPolicy2, times(backoff2Consulted)).nextBackoffMillis(); verify(mockTransportSetCallback, atLeast(0)).onInUse(transportSet); verify(mockTransportSetCallback, atLeast(0)).onNotInUse(transportSet); verifyNoMoreInteractions(mockTransportSetCallback); fakeExecutor.runDueTasks(); // Drain new 'real' stream creation; not important to this test. } @Test public void twoAddressesReconnect() { SocketAddress addr1 = mock(SocketAddress.class); SocketAddress addr2 = mock(SocketAddress.class); createTransportSet(addr1, addr2); assertEquals(ConnectivityState.IDLE, transportSet.getState(false)); // Invocation counters int transportsAddr1 = 0; int transportsAddr2 = 0; int backoff1Consulted = 0; int backoff2Consulted = 0; int backoff3Consulted = 0; int backoffReset = 0; int onAllAddressesFailed = 0; // First attempt DelayedClientTransport delayedTransport1 = (DelayedClientTransport) transportSet.obtainActiveTransport(); assertEquals(ConnectivityState.CONNECTING, transportSet.getState(false)); verify(mockTransportFactory, times(++transportsAddr1)) .newClientTransport(addr1, AUTHORITY, USER_AGENT); delayedTransport1.newStream(method, new Metadata(), waitForReadyCallOptions, statsTraceCtx); // Let this one fail without success transports.poll().listener.transportShutdown(Status.UNAVAILABLE); assertEquals(ConnectivityState.CONNECTING, transportSet.getState(false)); assertNull(delayedTransport1.getTransportSupplier()); verify(mockTransportSetCallback, times(onAllAddressesFailed)).onAllAddressesFailed(); // Second attempt will start immediately. Still no back-off policy. DelayedClientTransport delayedTransport2 = (DelayedClientTransport) transportSet.obtainActiveTransport(); assertEquals(ConnectivityState.CONNECTING, transportSet.getState(false)); assertSame(delayedTransport1, delayedTransport2); verify(mockBackoffPolicyProvider, times(backoffReset)).get(); verify(mockTransportFactory, times(++transportsAddr2)) .newClientTransport(addr2, AUTHORITY, USER_AGENT); // Fail this one too transports.poll().listener.transportShutdown(Status.UNAVAILABLE); // All addresses have failed. Delayed transport will be in back-off interval. assertEquals(ConnectivityState.TRANSIENT_FAILURE, transportSet.getState(false)); assertNull(delayedTransport2.getTransportSupplier()); assertTrue(delayedTransport2.isInBackoffPeriod()); verify(mockTransportSetCallback, times(++onAllAddressesFailed)).onAllAddressesFailed(); // Backoff reset and first back-off interval begins verify(mockBackoffPolicy1, times(++backoff1Consulted)).nextBackoffMillis(); verify(mockBackoffPolicyProvider, times(++backoffReset)).get(); // Third attempt is the first address, thus controlled by the first back-off interval. DelayedClientTransport delayedTransport3 = (DelayedClientTransport) transportSet.obtainActiveTransport(); assertEquals(ConnectivityState.TRANSIENT_FAILURE, transportSet.getState(false)); assertSame(delayedTransport2, delayedTransport3); fakeClock.forwardMillis(9); verify(mockTransportFactory, times(transportsAddr1)) .newClientTransport(addr1, AUTHORITY, USER_AGENT); assertEquals(ConnectivityState.TRANSIENT_FAILURE, transportSet.getState(false)); fakeClock.forwardMillis(1); assertEquals(ConnectivityState.CONNECTING, transportSet.getState(false)); verify(mockTransportFactory, times(++transportsAddr1)) .newClientTransport(addr1, AUTHORITY, USER_AGENT); // Fail this one too transports.poll().listener.transportShutdown(Status.UNAVAILABLE); assertEquals(ConnectivityState.CONNECTING, transportSet.getState(false)); assertNull(delayedTransport3.getTransportSupplier()); verify(mockTransportSetCallback, times(onAllAddressesFailed)).onAllAddressesFailed(); // Forth attempt will start immediately. Keep back-off policy. DelayedClientTransport delayedTransport4 = (DelayedClientTransport) transportSet.obtainActiveTransport(); assertEquals(ConnectivityState.CONNECTING, transportSet.getState(false)); assertSame(delayedTransport3, delayedTransport4); verify(mockBackoffPolicyProvider, times(backoffReset)).get(); verify(mockTransportFactory, times(++transportsAddr2)) .newClientTransport(addr2, AUTHORITY, USER_AGENT); // Fail this one too transports.poll().listener.transportShutdown(Status.UNAVAILABLE); // All addresses have failed again. Delayed transport will be in back-off interval. assertEquals(ConnectivityState.TRANSIENT_FAILURE, transportSet.getState(false)); assertNull(delayedTransport4.getTransportSupplier()); assertTrue(delayedTransport4.isInBackoffPeriod()); verify(mockTransportSetCallback, times(++onAllAddressesFailed)).onAllAddressesFailed(); // Second back-off interval begins verify(mockBackoffPolicy1, times(++backoff1Consulted)).nextBackoffMillis(); verify(mockBackoffPolicyProvider, times(backoffReset)).get(); // Fifth attempt for the first address, thus controlled by the second back-off interval. DelayedClientTransport delayedTransport5 = (DelayedClientTransport) transportSet.obtainActiveTransport(); assertEquals(ConnectivityState.TRANSIENT_FAILURE, transportSet.getState(false)); assertSame(delayedTransport4, delayedTransport5); fakeClock.forwardMillis(99); verify(mockTransportFactory, times(transportsAddr1)) .newClientTransport(addr1, AUTHORITY, USER_AGENT); assertEquals(ConnectivityState.TRANSIENT_FAILURE, transportSet.getState(false)); fakeClock.forwardMillis(1); assertEquals(ConnectivityState.CONNECTING, transportSet.getState(false)); verify(mockTransportFactory, times(++transportsAddr1)) .newClientTransport(addr1, AUTHORITY, USER_AGENT); // Let it through transports.peek().listener.transportReady(); assertEquals(ConnectivityState.READY, transportSet.getState(false)); // Delayed transport will see the connected transport. assertSame(transports.peek().transport, delayedTransport5.getTransportSupplier().get()); verify(mockTransportSetCallback, never()).onConnectionClosedByServer(any(Status.class)); // Then close it. transports.poll().listener.transportShutdown(Status.UNAVAILABLE); assertEquals(ConnectivityState.IDLE, transportSet.getState(false)); verify(mockTransportSetCallback).onConnectionClosedByServer(same(Status.UNAVAILABLE)); verify(mockTransportSetCallback, times(onAllAddressesFailed)).onAllAddressesFailed(); // First attempt after a successful connection. Old back-off policy should be ignored, but there // is not yet a need for a new one. Start from the first address. DelayedClientTransport delayedTransport6 = (DelayedClientTransport) transportSet.obtainActiveTransport(); assertEquals(ConnectivityState.CONNECTING, transportSet.getState(false)); assertNotSame(delayedTransport5, delayedTransport6); delayedTransport6.newStream(method, headers, waitForReadyCallOptions, statsTraceCtx); verify(mockBackoffPolicyProvider, times(backoffReset)).get(); verify(mockTransportFactory, times(++transportsAddr1)) .newClientTransport(addr1, AUTHORITY, USER_AGENT); // Fail the transport transports.poll().listener.transportShutdown(Status.UNAVAILABLE); assertEquals(ConnectivityState.CONNECTING, transportSet.getState(false)); assertNull(delayedTransport6.getTransportSupplier()); verify(mockTransportSetCallback, times(onAllAddressesFailed)).onAllAddressesFailed(); // Second attempt will start immediately. Still no new back-off policy. DelayedClientTransport delayedTransport7 = (DelayedClientTransport) transportSet.obtainActiveTransport(); assertSame(delayedTransport6, delayedTransport7); verify(mockBackoffPolicyProvider, times(backoffReset)).get(); verify(mockTransportFactory, times(++transportsAddr2)) .newClientTransport(addr2, AUTHORITY, USER_AGENT); // Fail this one too assertEquals(ConnectivityState.CONNECTING, transportSet.getState(false)); transports.poll().listener.transportShutdown(Status.UNAVAILABLE); // All addresses have failed. Delayed transport will be in back-off interval. assertEquals(ConnectivityState.TRANSIENT_FAILURE, transportSet.getState(false)); assertNull(delayedTransport7.getTransportSupplier()); assertTrue(delayedTransport7.isInBackoffPeriod()); verify(mockTransportSetCallback, times(++onAllAddressesFailed)).onAllAddressesFailed(); // Back-off reset and first back-off interval begins verify(mockBackoffPolicy2, times(++backoff2Consulted)).nextBackoffMillis(); verify(mockBackoffPolicyProvider, times(++backoffReset)).get(); // Third attempt is the first address, thus controlled by the first back-off interval. DelayedClientTransport delayedTransport8 = (DelayedClientTransport) transportSet.obtainActiveTransport(); assertSame(delayedTransport7, delayedTransport8); fakeClock.forwardMillis(9); verify(mockTransportFactory, times(transportsAddr1)) .newClientTransport(addr1, AUTHORITY, USER_AGENT); assertEquals(ConnectivityState.TRANSIENT_FAILURE, transportSet.getState(false)); fakeClock.forwardMillis(1); assertEquals(ConnectivityState.CONNECTING, transportSet.getState(false)); verify(mockTransportFactory, times(++transportsAddr1)) .newClientTransport(addr1, AUTHORITY, USER_AGENT); // Final checks on invocations on back-off policies verify(mockBackoffPolicy1, times(backoff1Consulted)).nextBackoffMillis(); verify(mockBackoffPolicy2, times(backoff2Consulted)).nextBackoffMillis(); verify(mockBackoffPolicy3, times(backoff3Consulted)).nextBackoffMillis(); verify(mockTransportSetCallback, atLeast(0)).onInUse(transportSet); verify(mockTransportSetCallback, atLeast(0)).onNotInUse(transportSet); verifyNoMoreInteractions(mockTransportSetCallback); fakeExecutor.runDueTasks(); // Drain new 'real' stream creation; not important to this test. } @Test public void verifyFailFastAndNonFailFastBehaviors() { int pendingStreamsCount = 0; int failFastPendingStreamsCount = 0; final SocketAddress addr1 = mock(SocketAddress.class); final SocketAddress addr2 = mock(SocketAddress.class); createTransportSet(addr1, addr2); final DelayedClientTransport delayedTransport = (DelayedClientTransport) transportSet.obtainActiveTransport(); assertEquals(ConnectivityState.CONNECTING, transportSet.getState(false)); assertFalse(delayedTransport.isInBackoffPeriod()); // Create a new fail fast stream. ClientStream ffStream = delayedTransport.newStream(method, headers, failFastCallOptions, statsTraceCtx); ffStream.start(mockStreamListener); // Verify it is queued. assertEquals(++pendingStreamsCount, delayedTransport.getPendingStreamsCount()); failFastPendingStreamsCount++; // Create a new non fail fast stream. delayedTransport.newStream(method, headers, waitForReadyCallOptions, statsTraceCtx); // Verify it is queued. assertEquals(++pendingStreamsCount, delayedTransport.getPendingStreamsCount()); // Let this 1st address fail without success. transports.poll().listener.transportShutdown(Status.UNAVAILABLE); assertEquals(ConnectivityState.CONNECTING, transportSet.getState(false)); assertFalse(delayedTransport.isInBackoffPeriod()); // Verify pending streams still in queue. assertEquals(pendingStreamsCount, delayedTransport.getPendingStreamsCount()); // Create a new fail fast stream. delayedTransport.newStream(method, headers, failFastCallOptions, statsTraceCtx); // Verify it is queued. assertEquals(++pendingStreamsCount, delayedTransport.getPendingStreamsCount()); failFastPendingStreamsCount++; // Create a new non fail fast stream delayedTransport.newStream(method, headers, waitForReadyCallOptions, statsTraceCtx); // Verify it is queued. assertEquals(++pendingStreamsCount, delayedTransport.getPendingStreamsCount()); // Let this 2nd address fail without success. Status failureStatus = Status.UNAVAILABLE.withDescription("some unique failure"); transports.poll().listener.transportShutdown(failureStatus); assertEquals(ConnectivityState.TRANSIENT_FAILURE, transportSet.getState(false)); assertTrue(delayedTransport.isInBackoffPeriod()); // Fail fast pending streams should be cleared assertEquals( pendingStreamsCount - failFastPendingStreamsCount, delayedTransport.getPendingStreamsCount()); pendingStreamsCount -= failFastPendingStreamsCount; failFastPendingStreamsCount = 0; fakeExecutor.runDueTasks(); verify(mockStreamListener).closed(same(failureStatus), any(Metadata.class)); // Create a new fail fast stream. delayedTransport.newStream(method, headers, failFastCallOptions, statsTraceCtx); // Verify it is not queued. assertEquals(pendingStreamsCount, delayedTransport.getPendingStreamsCount()); // Create a new non fail fast stream delayedTransport.newStream(method, headers, waitForReadyCallOptions, statsTraceCtx); // Verify it is queued. assertEquals(++pendingStreamsCount, delayedTransport.getPendingStreamsCount()); fakeClock.forwardMillis(10); // Now back-off is over assertEquals(ConnectivityState.CONNECTING, transportSet.getState(false)); assertFalse(delayedTransport.isInBackoffPeriod()); // Create a new fail fast stream. delayedTransport.newStream(method, headers, failFastCallOptions, statsTraceCtx); // Verify it is queued. assertEquals(++pendingStreamsCount, delayedTransport.getPendingStreamsCount()); failFastPendingStreamsCount++; assertEquals(1, failFastPendingStreamsCount); fakeExecutor.runDueTasks(); // Drain new 'real' stream creation; not important to this test. } @Test public void connectIsLazy() { SocketAddress addr = mock(SocketAddress.class); createTransportSet(addr); // Invocation counters int transportsCreated = 0; // Won't connect until requested verify(mockTransportFactory, times(transportsCreated)) .newClientTransport(addr, AUTHORITY, USER_AGENT); // First attempt transportSet.obtainActiveTransport().newStream(method, new Metadata()); assertEquals(ConnectivityState.CONNECTING, transportSet.getState(false)); verify(mockTransportFactory, times(++transportsCreated)) .newClientTransport(addr, AUTHORITY, USER_AGENT); // Fail this one transports.poll().listener.transportShutdown(Status.UNAVAILABLE); assertEquals(ConnectivityState.TRANSIENT_FAILURE, transportSet.getState(false)); // Will always reconnect after back-off fakeClock.forwardMillis(10); assertEquals(ConnectivityState.CONNECTING, transportSet.getState(false)); verify(mockTransportFactory, times(++transportsCreated)) .newClientTransport(addr, AUTHORITY, USER_AGENT); // Make this one proceed transports.peek().listener.transportReady(); assertEquals(ConnectivityState.READY, transportSet.getState(false)); // Then go-away transports.poll().listener.transportShutdown(Status.UNAVAILABLE); assertEquals(ConnectivityState.IDLE, transportSet.getState(false)); // Request immediately transportSet .obtainActiveTransport() .newStream(method, new Metadata(), waitForReadyCallOptions, statsTraceCtx); assertEquals(ConnectivityState.CONNECTING, transportSet.getState(false)); verify(mockTransportFactory, times(++transportsCreated)) .newClientTransport(addr, AUTHORITY, USER_AGENT); fakeExecutor.runDueTasks(); // Drain new 'real' stream creation; not important to this test. } @Test public void shutdownBeforeTransportCreatedWithPendingStream() throws Exception { SocketAddress addr = mock(SocketAddress.class); createTransportSet(addr); // First transport is created immediately ClientTransport pick = transportSet.obtainActiveTransport(); assertEquals(ConnectivityState.CONNECTING, transportSet.getState(false)); verify(mockTransportFactory).newClientTransport(addr, AUTHORITY, USER_AGENT); assertNotNull(pick); // Fail this one MockClientTransportInfo transportInfo = transports.poll(); transportInfo.listener.transportShutdown(Status.UNAVAILABLE); assertEquals(ConnectivityState.TRANSIENT_FAILURE, transportSet.getState(false)); transportInfo.listener.transportTerminated(); // Second transport will wait for back-off pick = transportSet.obtainActiveTransport(); assertTrue(pick instanceof DelayedClientTransport); // Start a stream, which will be pending in the delayed transport ClientStream pendingStream = pick.newStream(method, headers, waitForReadyCallOptions, statsTraceCtx); pendingStream.start(mockStreamListener); // Shut down TransportSet before the transport is created. Further call to // obtainActiveTransport() gets failing transports assertEquals(ConnectivityState.TRANSIENT_FAILURE, transportSet.getState(false)); transportSet.shutdown(); assertEquals(ConnectivityState.SHUTDOWN, transportSet.getState(false)); pick = transportSet.obtainActiveTransport(); assertNotNull(pick); assertTrue(pick instanceof FailingClientTransport); verify(mockTransportFactory).newClientTransport(addr, AUTHORITY, USER_AGENT); // Reconnect will eventually happen, even though TransportSet has been shut down fakeClock.forwardMillis(10); assertEquals(ConnectivityState.SHUTDOWN, transportSet.getState(false)); verify(mockTransportFactory, times(2)).newClientTransport(addr, AUTHORITY, USER_AGENT); // The pending stream will be started on this newly started transport after it's ready. // The transport is shut down by TransportSet right after the stream is created. transportInfo = transports.poll(); verify(transportInfo.transport, times(0)).shutdown(); assertEquals(0, fakeExecutor.numPendingTasks()); transportInfo.listener.transportReady(); assertEquals(ConnectivityState.SHUTDOWN, transportSet.getState(false)); verify(transportInfo.transport, times(0)) .newStream(any(MethodDescriptor.class), any(Metadata.class)); assertEquals(1, fakeExecutor.runDueTasks()); verify(transportInfo.transport) .newStream( same(method), same(headers), same(waitForReadyCallOptions), any(StatsTraceContext.class)); verify(transportInfo.transport).shutdown(); transportInfo.listener.transportShutdown(Status.UNAVAILABLE); assertEquals(ConnectivityState.SHUTDOWN, transportSet.getState(false)); verify(mockTransportSetCallback, never()).onTerminated(any(TransportSet.class)); // Terminating the transport will let TransportSet to be terminated. transportInfo.listener.transportTerminated(); assertEquals(ConnectivityState.SHUTDOWN, transportSet.getState(false)); verify(mockTransportSetCallback).onTerminated(transportSet); // No more transports will be created. fakeClock.forwardMillis(10000); assertEquals(ConnectivityState.SHUTDOWN, transportSet.getState(false)); verifyNoMoreInteractions(mockTransportFactory); assertEquals(0, transports.size()); } @Test public void shutdownBeforeTransportCreatedWithoutPendingStream() throws Exception { SocketAddress addr = mock(SocketAddress.class); createTransportSet(addr); // First transport is created immediately ClientTransport pick = transportSet.obtainActiveTransport(); verify(mockTransportFactory).newClientTransport(addr, AUTHORITY, USER_AGENT); assertNotNull(pick); // Fail this one MockClientTransportInfo transportInfo = transports.poll(); transportInfo.listener.transportShutdown(Status.UNAVAILABLE); transportInfo.listener.transportTerminated(); // Second transport will wait for back-off pick = transportSet.obtainActiveTransport(); assertTrue(pick instanceof DelayedClientTransport); // Shut down TransportSet before the transport is created. Futher call to // obtainActiveTransport() gets failing transports transportSet.shutdown(); assertEquals(ConnectivityState.SHUTDOWN, transportSet.getState(false)); pick = transportSet.obtainActiveTransport(); assertEquals(ConnectivityState.SHUTDOWN, transportSet.getState(false)); assertNotNull(pick); assertTrue(pick instanceof FailingClientTransport); // TransportSet terminated promptly. verify(mockTransportSetCallback).onTerminated(transportSet); assertEquals(ConnectivityState.SHUTDOWN, transportSet.getState(false)); // No more transports will be created. fakeClock.forwardMillis(10000); assertEquals(ConnectivityState.SHUTDOWN, transportSet.getState(false)); verifyNoMoreInteractions(mockTransportFactory); assertEquals(0, transports.size()); } @Test public void shutdownBeforeTransportReady() throws Exception { SocketAddress addr = mock(SocketAddress.class); createTransportSet(addr); ClientTransport pick = transportSet.obtainActiveTransport(); assertEquals(ConnectivityState.CONNECTING, transportSet.getState(false)); MockClientTransportInfo transportInfo = transports.poll(); assertNotSame(transportInfo.transport, pick); // Shutdown the TransportSet before the pending transport is ready transportSet.shutdown(); assertEquals(ConnectivityState.SHUTDOWN, transportSet.getState(false)); // The transport should've been shut down even though it's not the active transport yet. verify(transportInfo.transport).shutdown(); transportInfo.listener.transportShutdown(Status.UNAVAILABLE); transportInfo.listener.transportTerminated(); assertEquals(ConnectivityState.SHUTDOWN, transportSet.getState(false)); } @Test public void obtainTransportAfterShutdown() throws Exception { SocketAddress addr = mock(SocketAddress.class); createTransportSet(addr); transportSet.shutdown(); assertEquals(ConnectivityState.SHUTDOWN, transportSet.getState(false)); ClientTransport pick = transportSet.obtainActiveTransport(); assertNotNull(pick); verify(mockTransportFactory, times(0)).newClientTransport(addr, AUTHORITY, USER_AGENT); assertEquals(ConnectivityState.SHUTDOWN, transportSet.getState(false)); } @Test public void requireConnectionThroughGetState() throws Exception { SocketAddress addr = mock(SocketAddress.class); createTransportSet(addr); assertEquals(ConnectivityState.IDLE, transportSet.getState(false)); assertEquals(ConnectivityState.CONNECTING, transportSet.getState(true)); assertEquals(ConnectivityState.CONNECTING, transportSet.getState(true)); transportSet .obtainActiveTransport() .newStream(method, new Metadata(), waitForReadyCallOptions, statsTraceCtx); assertEquals(ConnectivityState.CONNECTING, transportSet.getState(true)); // Fail it transports.peek().listener.transportShutdown(Status.UNAVAILABLE); // requireConnection == true doesn't skip the back-off assertEquals(ConnectivityState.TRANSIENT_FAILURE, transportSet.getState(true)); transports.poll().listener.transportTerminated(); fakeClock.forwardMillis(9); assertEquals(ConnectivityState.TRANSIENT_FAILURE, transportSet.getState(true)); fakeClock.forwardMillis(1); // Only when back-off is over, do we try to connect again assertEquals(ConnectivityState.CONNECTING, transportSet.getState(false)); // Let it through and fail, thus a go-away transports.peek().listener.transportReady(); transports.peek().listener.transportShutdown(Status.UNAVAILABLE); assertEquals(ConnectivityState.IDLE, transportSet.getState(false)); transports.poll().listener.transportTerminated(); // Request for connecting again assertEquals(ConnectivityState.CONNECTING, transportSet.getState(true)); // And fail it again transports.peek().listener.transportShutdown(Status.UNAVAILABLE); assertEquals(ConnectivityState.TRANSIENT_FAILURE, transportSet.getState(true)); // Shut it down transportSet.shutdown(); assertEquals(ConnectivityState.SHUTDOWN, transportSet.getState(true)); assertEquals(ConnectivityState.SHUTDOWN, transportSet.getState(false)); assertFalse(transportSet.isTerminated()); // Terminate it transports.poll().listener.transportTerminated(); assertTrue(transportSet.isTerminated()); assertEquals(ConnectivityState.SHUTDOWN, transportSet.getState(true)); assertEquals(ConnectivityState.SHUTDOWN, transportSet.getState(false)); fakeExecutor.runDueTasks(); // What tasks are scheduled is not important to this test. } @Test public void logId() { createTransportSet(mock(SocketAddress.class)); assertNotNull(transportSet.getLogId()); } @Test public void inUseState() { SocketAddress addr = mock(SocketAddress.class); createTransportSet(addr); // Invocation counters int inUse = 0; int notInUse = 0; verify(mockTransportSetCallback, never()).onInUse(any(TransportSet.class)); transportSet .obtainActiveTransport() .newStream(method, new Metadata(), waitForReadyCallOptions, statsTraceCtx); verify(mockTransportSetCallback, times(++inUse)).onInUse(transportSet); MockClientTransportInfo t0 = transports.poll(); verify(mockTransportSetCallback, never()).onNotInUse(any(TransportSet.class)); t0.listener.transportReady(); // The race between delayed transport being terminated (thus not in-use) and // the real transport become in-use, caused a brief period of TransportSet not in-use. verify(mockTransportSetCallback, times(++notInUse)).onNotInUse(transportSet); // Delayed transport calls newStream() on the real transport in the executor fakeExecutor.runDueTasks(); verify(t0.transport) .newStream( same(method), any(Metadata.class), same(waitForReadyCallOptions), any(StatsTraceContext.class)); verify(mockTransportSetCallback, times(inUse)).onInUse(transportSet); t0.listener.transportInUse(true); verify(mockTransportSetCallback, times(++inUse)).onInUse(transportSet); t0.listener.transportInUse(false); verify(mockTransportSetCallback, times(++notInUse)).onNotInUse(transportSet); t0.listener.transportInUse(true); verify(mockTransportSetCallback, times(++inUse)).onInUse(transportSet); // Simulate that the server sends a go-away t0.listener.transportShutdown(Status.UNAVAILABLE); // Creates a new transport transportSet .obtainActiveTransport() .newStream(method, new Metadata(), waitForReadyCallOptions, statsTraceCtx); MockClientTransportInfo t1 = transports.poll(); t1.listener.transportReady(); // Delayed transport calls newStream() on the real transport in the executor fakeExecutor.runDueTasks(); verify(t1.transport) .newStream( same(method), any(Metadata.class), same(waitForReadyCallOptions), any(StatsTraceContext.class)); t1.listener.transportInUse(true); // No turbulance from the race mentioned eariler, because t0 has been in-use verify(mockTransportSetCallback, times(inUse)).onInUse(transportSet); verify(mockTransportSetCallback, times(notInUse)).onNotInUse(transportSet); // TransportSet is not in-use when both transports are not in-use. t1.listener.transportInUse(false); verify(mockTransportSetCallback, times(notInUse)).onNotInUse(transportSet); t0.listener.transportInUse(false); verify(mockTransportSetCallback, times(++notInUse)).onNotInUse(transportSet); verify(mockTransportSetCallback, times(inUse)).onInUse(transportSet); } @Test public void scheduleBackoff_DoNotScheduleEndOfBackoffIfAlreadyShutdown() { // Setup final boolean[] startBackoffAndShutdownAreCalled = {false}; Executor executor = new Executor() { @Override public void execute(Runnable command) { if (command.getClass().getName().contains("FailTheFailFastPendingStreams")) { // shutdown during startBackoff transportSet.shutdown(); startBackoffAndShutdownAreCalled[0] = true; } fakeExecutor.getScheduledExecutorService().execute(command); } }; SocketAddress addr = mock(SocketAddress.class); addressGroup = new EquivalentAddressGroup(Arrays.asList(addr)); transportSet = new TransportSet( addressGroup, AUTHORITY, USER_AGENT, mockLoadBalancer, mockBackoffPolicyProvider, mockTransportFactory, fakeClock.getScheduledExecutorService(), fakeClock.getStopwatchSupplier(), executor, mockTransportSetCallback); // Attempt and fail, scheduleBackoff should be triggered, // and transportSet.shutdown should be triggered by setup transportSet .obtainActiveTransport() .newStream(method, new Metadata(), waitForReadyCallOptions, statsTraceCtx); transports.poll().listener.transportShutdown(Status.UNAVAILABLE); verify(mockTransportSetCallback, times(1)).onAllAddressesFailed(); assertTrue(startBackoffAndShutdownAreCalled[0]); fakeExecutor.runDueTasks(); // verify endOfBackoff not scheduled verify(mockBackoffPolicy1, never()).nextBackoffMillis(); } private void createTransportSet(SocketAddress... addrs) { addressGroup = new EquivalentAddressGroup(Arrays.asList(addrs)); transportSet = new TransportSet( addressGroup, AUTHORITY, USER_AGENT, mockLoadBalancer, mockBackoffPolicyProvider, mockTransportFactory, fakeClock.getScheduledExecutorService(), fakeClock.getStopwatchSupplier(), fakeExecutor.getScheduledExecutorService(), mockTransportSetCallback); } }