@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());
 }
  @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;
  }