@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());
 }
Example #2
0
 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);
      }
    }
  }
Example #6
0
 @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();
   }
 }
Example #7
0
  @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);
  }
Example #8
0
@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;
  }
}
Example #10
0
@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();
  }
}
Example #11
0
@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);
  }
}