From 2b5637615a20802ddf452321ded71f351e2803f8 Mon Sep 17 00:00:00 2001
From: Tim Emiola <temiola@google.com>
Date: Wed, 21 Jan 2015 12:59:41 -0800
Subject: [PATCH] Updates ruby to stop using grpc_start_invoke

---
 src/ruby/ext/grpc/rb_call.c               | 20 +++----
 src/ruby/ext/grpc/rb_event.c              |  6 +-
 src/ruby/lib/grpc/auth.rb                 | 68 +++++++++++++++++++++++
 src/ruby/lib/grpc/generic/active_call.rb  | 28 ++++------
 src/ruby/lib/grpc/generic/bidi_call.rb    |  4 +-
 src/ruby/spec/call_spec.rb                | 16 +-----
 src/ruby/spec/client_server_spec.rb       |  8 +--
 src/ruby/spec/event_spec.rb               |  3 +-
 src/ruby/spec/generic/active_call_spec.rb | 56 +++++++++----------
 9 files changed, 123 insertions(+), 86 deletions(-)
 create mode 100644 src/ruby/lib/grpc/auth.rb

diff --git a/src/ruby/ext/grpc/rb_call.c b/src/ruby/ext/grpc/rb_call.c
index 76b80bcaa1..1b6565f729 100644
--- a/src/ruby/ext/grpc/rb_call.c
+++ b/src/ruby/ext/grpc/rb_call.c
@@ -153,7 +153,7 @@ int grpc_rb_call_add_metadata_hash_cb(VALUE key, VALUE val, VALUE call_obj) {
 
   Add metadata elements to the call from a ruby hash, to be sent upon
   invocation. flags is a bit-field combination of the write flags defined
-  above.  REQUIRES: grpc_call_start_invoke/grpc_call_accept have not been
+  above.  REQUIRES: grpc_call_invoke/grpc_call_accept have not been
   called on this call.  Produces no events. */
 
 static VALUE grpc_rb_call_add_metadata(int argc, VALUE *argv, VALUE self) {
@@ -196,16 +196,15 @@ static VALUE grpc_rb_call_cancel(VALUE self) {
 
 /*
   call-seq:
-     call.start_invoke(completion_queue, tag, flags=nil)
+     call.invoke(completion_queue, tag, flags=nil)
 
    Invoke the RPC. Starts sending metadata and request headers on the wire.
    flags is a bit-field combination of the write flags defined above.
    REQUIRES: Can be called at most once per call.
              Can only be called on the client.
    Produces a GRPC_INVOKE_ACCEPTED event on completion. */
-static VALUE grpc_rb_call_start_invoke(int argc, VALUE *argv, VALUE self) {
+static VALUE grpc_rb_call_invoke(int argc, VALUE *argv, VALUE self) {
   VALUE cqueue = Qnil;
-  VALUE invoke_accepted_tag = Qnil;
   VALUE metadata_read_tag = Qnil;
   VALUE finished_tag = Qnil;
   VALUE flags = Qnil;
@@ -213,17 +212,16 @@ static VALUE grpc_rb_call_start_invoke(int argc, VALUE *argv, VALUE self) {
   grpc_completion_queue *cq = NULL;
   grpc_call_error err;
 
-  /* "41" == 4 mandatory args, 1 (flags) is optional */
-  rb_scan_args(argc, argv, "41", &cqueue, &invoke_accepted_tag,
-               &metadata_read_tag, &finished_tag, &flags);
+  /* "31" == 3 mandatory args, 1 (flags) is optional */
+  rb_scan_args(argc, argv, "31", &cqueue, &metadata_read_tag, &finished_tag,
+               &flags);
   if (NIL_P(flags)) {
     flags = UINT2NUM(0); /* Default to no flags */
   }
   cq = grpc_rb_get_wrapped_completion_queue(cqueue);
   Data_Get_Struct(self, grpc_call, call);
-  err = grpc_call_start_invoke(call, cq, ROBJECT(invoke_accepted_tag),
-                               ROBJECT(metadata_read_tag),
-                               ROBJECT(finished_tag), NUM2UINT(flags));
+  err = grpc_call_invoke(call, cq, ROBJECT(metadata_read_tag),
+                         ROBJECT(finished_tag), NUM2UINT(flags));
   if (err != GRPC_CALL_OK) {
     rb_raise(rb_eCallError, "invoke failed: %s (code=%d)",
              grpc_call_error_detail_of(err), err);
@@ -519,7 +517,7 @@ void Init_google_rpc_call() {
                    grpc_rb_call_server_end_initial_metadata, -1);
   rb_define_method(rb_cCall, "add_metadata", grpc_rb_call_add_metadata, -1);
   rb_define_method(rb_cCall, "cancel", grpc_rb_call_cancel, 0);
-  rb_define_method(rb_cCall, "start_invoke", grpc_rb_call_start_invoke, -1);
+  rb_define_method(rb_cCall, "invoke", grpc_rb_call_invoke, -1);
   rb_define_method(rb_cCall, "start_read", grpc_rb_call_start_read, 1);
   rb_define_method(rb_cCall, "start_write", grpc_rb_call_start_write, -1);
   rb_define_method(rb_cCall, "start_write_status",
diff --git a/src/ruby/ext/grpc/rb_event.c b/src/ruby/ext/grpc/rb_event.c
index 0fae9502c3..a1ab6251c8 100644
--- a/src/ruby/ext/grpc/rb_event.c
+++ b/src/ruby/ext/grpc/rb_event.c
@@ -105,10 +105,6 @@ static VALUE grpc_rb_event_type(VALUE self) {
     case GRPC_READ:
       return rb_const_get(rb_mCompletionType, rb_intern("READ"));
 
-    case GRPC_INVOKE_ACCEPTED:
-      grpc_rb_event_result(self); /* validates the result */
-      return rb_const_get(rb_mCompletionType, rb_intern("INVOKE_ACCEPTED"));
-
     case GRPC_WRITE_ACCEPTED:
       grpc_rb_event_result(self); /* validates the result */
       return rb_const_get(rb_mCompletionType, rb_intern("WRITE_ACCEPTED"));
@@ -359,6 +355,8 @@ void Init_google_rpc_event() {
   rb_define_const(rb_mCompletionType, "FINISHED", INT2NUM(GRPC_FINISHED));
   rb_define_const(rb_mCompletionType, "SERVER_RPC_NEW",
                   INT2NUM(GRPC_SERVER_RPC_NEW));
+  rb_define_const(rb_mCompletionType, "SERVER_SHUTDOWN",
+                  INT2NUM(GRPC_SERVER_SHUTDOWN));
   rb_define_const(rb_mCompletionType, "RESERVED",
                   INT2NUM(GRPC_COMPLETION_DO_NOT_USE));
 }
diff --git a/src/ruby/lib/grpc/auth.rb b/src/ruby/lib/grpc/auth.rb
new file mode 100644
index 0000000000..8817205b24
--- /dev/null
+++ b/src/ruby/lib/grpc/auth.rb
@@ -0,0 +1,68 @@
+# Copyright 2014, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+require 'grpc'
+require 'signet'
+
+
+module Google
+  import Signet::OAuth2
+
+  # Google::RPC contains the General RPC module.
+  module RPC
+    # ServiceAccounCredentials can obtain credentials for a configured service
+    # account, scopes and issuer.
+    module Auth
+      class ServiceAccountCredentials
+        CREDENTIAL_URI = 'https://accounts.google.com/o/oauth2/token'
+        AUDIENCE_URI = 'https://accounts.google.com/o/oauth2/token'
+
+        # Initializes an instance with the given scope, issuer and signing_key
+        def initialize(scope, issuer, key)
+          @auth_client =  Client.new(token_credential_uri: CREDENTIAL_URI,
+                                     audience: AUDIENCE_URI,
+                                     scope: scope,
+                                     issuer: issuer,
+                                     signing_key: key)
+          @auth_token = nil
+        end
+
+        def metadata_update_proc
+          proc do |input_md|
+            input
+          end
+        end
+
+        def auth_creds
+          key = Google::APIClient::KeyUtils.load_from_pkcs12('client.p12', 'notasecret')
+        end
+      end
+    end
+  end
+end
diff --git a/src/ruby/lib/grpc/generic/active_call.rb b/src/ruby/lib/grpc/generic/active_call.rb
index bd684a8d07..1cdc168bfe 100644
--- a/src/ruby/lib/grpc/generic/active_call.rb
+++ b/src/ruby/lib/grpc/generic/active_call.rb
@@ -47,7 +47,7 @@ module Google
       include Core::TimeConsts
       attr_reader(:deadline)
 
-      # client_start_invoke begins a client invocation.
+      # client_invoke begins a client invocation.
       #
       # Flow Control note: this blocks until flow control accepts that client
       # request can go ahead.
@@ -59,9 +59,9 @@ module Google
       # if a keyword value is a list, multiple metadata for it's key are sent
       #
       # @param call [Call] a call on which to start and invocation
-      # @param q [CompletionQueue] used to wait for INVOKE_ACCEPTED
-      # @param deadline [Fixnum,TimeSpec] the deadline for INVOKE_ACCEPTED
-      def self.client_start_invoke(call, q, _deadline, **kw)
+      # @param q [CompletionQueue] the completion queue
+      # @param deadline [Fixnum,TimeSpec] the deadline
+      def self.client_invoke(call, q, _deadline, **kw)
         fail(ArgumentError, 'not a call') unless call.is_a? Core::Call
         unless q.is_a? Core::CompletionQueue
           fail(ArgumentError, 'not a CompletionQueue')
@@ -69,24 +69,16 @@ module Google
         call.add_metadata(kw) if kw.length > 0
         invoke_accepted, client_metadata_read = Object.new, Object.new
         finished_tag = Object.new
-        call.start_invoke(q, invoke_accepted, client_metadata_read,
-                          finished_tag)
-
-        # wait for the invocation to be accepted
-        ev = q.pluck(invoke_accepted, INFINITE_FUTURE)
-        fail OutOfTime if ev.nil?
-        ev.close
-
+        call.invoke(q, client_metadata_read, finished_tag)
         [finished_tag, client_metadata_read]
       end
 
       # Creates an ActiveCall.
       #
-      # ActiveCall should only be created after a call is accepted.  That means
-      # different things on a client and a server.  On the client, the call is
-      # accepted after call.start_invoke followed by receipt of the
-      # corresponding INVOKE_ACCEPTED.  on the server, this is after
-      # call.accept.
+      # ActiveCall should only be created after a call is accepted.  That
+      # means different things on a client and a server.  On the client, the
+      # call is accepted after calling call.invoke.  On the server, this is
+      # after call.accept.
       #
       # #initialize cannot determine if the call is accepted or not; so if a
       # call that's not accepted is used here, the error won't be visible until
@@ -495,7 +487,7 @@ module Google
       private
 
       def start_call(**kw)
-        tags = ActiveCall.client_start_invoke(@call, @cq, @deadline, **kw)
+        tags = ActiveCall.client_invoke(@call, @cq, @deadline, **kw)
         @finished_tag, @read_metadata_tag = tags
         @started = true
       end
diff --git a/src/ruby/lib/grpc/generic/bidi_call.rb b/src/ruby/lib/grpc/generic/bidi_call.rb
index 14ef6c531f..7653192ad6 100644
--- a/src/ruby/lib/grpc/generic/bidi_call.rb
+++ b/src/ruby/lib/grpc/generic/bidi_call.rb
@@ -50,9 +50,7 @@ module Google
       #
       # BidiCall should only be created after a call is accepted.  That means
       # different things on a client and a server.  On the client, the call is
-      # accepted after call.start_invoke followed by receipt of the
-      # corresponding INVOKE_ACCEPTED.  On the server, this is after
-      # call.accept.
+      # accepted after call.invoke. On the server, this is after call.accept.
       #
       # #initialize cannot determine if the call is accepted or not; so if a
       # call that's not accepted is used here, the error won't be visible until
diff --git a/src/ruby/spec/call_spec.rb b/src/ruby/spec/call_spec.rb
index b8ecd64f39..9a510df1f3 100644
--- a/src/ruby/spec/call_spec.rb
+++ b/src/ruby/spec/call_spec.rb
@@ -122,24 +122,10 @@ describe GRPC::Core::Call do
     end
   end
 
-  describe '#start_invoke' do
-    it 'should cause the INVOKE_ACCEPTED event' do
-      call = make_test_call
-      expect(call.start_invoke(@client_queue, @tag, @tag, @tag)).to be_nil
-      ev = @client_queue.next(deadline)
-      expect(ev.call).to be_a(GRPC::Core::Call)
-      expect(ev.tag).to be(@tag)
-      expect(ev.type).to be(GRPC::Core::CompletionType::INVOKE_ACCEPTED)
-      expect(ev.call).to_not be(call)
-    end
-  end
-
   describe '#start_write' do
     it 'should cause the WRITE_ACCEPTED event' do
       call = make_test_call
-      call.start_invoke(@client_queue, @tag, @tag, @tag)
-      ev = @client_queue.next(deadline)
-      expect(ev.type).to be(GRPC::Core::CompletionType::INVOKE_ACCEPTED)
+      call.invoke(@client_queue, @tag, @tag)
       expect(call.start_write(GRPC::Core::ByteBuffer.new('test_start_write'),
                               @tag)).to be_nil
       ev = @client_queue.next(deadline)
diff --git a/src/ruby/spec/client_server_spec.rb b/src/ruby/spec/client_server_spec.rb
index 1bcbc66446..59b4bbd9d8 100644
--- a/src/ruby/spec/client_server_spec.rb
+++ b/src/ruby/spec/client_server_spec.rb
@@ -83,10 +83,7 @@ shared_context 'setup: tags' do
 
   def client_sends(call, sent = 'a message')
     req = ByteBuffer.new(sent)
-    call.start_invoke(@client_queue, @tag, @tag, @client_finished_tag)
-    ev = @client_queue.pluck(@tag, TimeConsts::INFINITE_FUTURE)
-    expect(ev).not_to be_nil
-    expect(ev.type).to be(INVOKE_ACCEPTED)
+    call.invoke(@client_queue,  @tag, @client_finished_tag)
     call.start_write(req, @tag)
     ev = @client_queue.pluck(@tag, TimeConsts::INFINITE_FUTURE)
     expect(ev).not_to be_nil
@@ -233,8 +230,7 @@ shared_examples 'GRPC metadata delivery works OK' do
         call.add_metadata(md)
 
         # Client begins a call OK
-        call.start_invoke(@client_queue, @tag, @tag, @client_finished_tag)
-        expect_next_event_on(@client_queue, INVOKE_ACCEPTED, @tag)
+        call.invoke(@client_queue, @tag, @client_finished_tag)
 
         # ... server has all metadata available even though the client did not
         # send a write
diff --git a/src/ruby/spec/event_spec.rb b/src/ruby/spec/event_spec.rb
index 5dec07e1ed..7ef08d021b 100644
--- a/src/ruby/spec/event_spec.rb
+++ b/src/ruby/spec/event_spec.rb
@@ -40,7 +40,8 @@ describe GRPC::Core::CompletionType do
       CLIENT_METADATA_READ: 5,
       FINISHED: 6,
       SERVER_RPC_NEW: 7,
-      RESERVED: 8
+      SERVER_SHUTDOWN: 8,
+      RESERVED: 9
     }
   end
 
diff --git a/src/ruby/spec/generic/active_call_spec.rb b/src/ruby/spec/generic/active_call_spec.rb
index 898022f185..443ba3d192 100644
--- a/src/ruby/spec/generic/active_call_spec.rb
+++ b/src/ruby/spec/generic/active_call_spec.rb
@@ -60,8 +60,8 @@ describe GRPC::ActiveCall do
   describe 'restricted view methods' do
     before(:each) do
       call = make_test_call
-      done_tag, meta_tag = ActiveCall.client_start_invoke(call, @client_queue,
-                                                          deadline)
+      done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
+                                                    deadline)
       @client_call = ActiveCall.new(call, @client_queue, @pass_through,
                                     @pass_through, deadline,
                                     finished_tag: done_tag,
@@ -92,8 +92,8 @@ describe GRPC::ActiveCall do
   describe '#remote_send' do
     it 'allows a client to send a payload to the server' do
       call = make_test_call
-      done_tag, meta_tag = ActiveCall.client_start_invoke(call, @client_queue,
-                                                          deadline)
+      done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
+                                                    deadline)
       @client_call = ActiveCall.new(call, @client_queue, @pass_through,
                                     @pass_through, deadline,
                                     finished_tag: done_tag,
@@ -118,8 +118,8 @@ describe GRPC::ActiveCall do
 
     it 'marshals the payload using the marshal func' do
       call = make_test_call
-      done_tag, meta_tag = ActiveCall.client_start_invoke(call, @client_queue,
-                                                          deadline)
+      done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
+                                                    deadline)
       marshal = proc { |x| 'marshalled:' + x }
       client_call = ActiveCall.new(call, @client_queue, marshal,
                                    @pass_through, deadline,
@@ -139,11 +139,11 @@ describe GRPC::ActiveCall do
     end
   end
 
-  describe '#client_start_invoke' do
+  describe '#client_invoke' do
     it 'sends keywords as metadata to the server when the are present' do
       call = make_test_call
-      ActiveCall.client_start_invoke(call, @client_queue, deadline,
-                                     k1: 'v1', k2: 'v2')
+      ActiveCall.client_invoke(call, @client_queue, deadline,
+                               k1: 'v1', k2: 'v2')
       @server.request_call(@server_tag)
       ev = @server_queue.next(deadline)
       expect(ev).to_not be_nil
@@ -155,8 +155,8 @@ describe GRPC::ActiveCall do
   describe '#remote_read' do
     it 'reads the response sent by a server' do
       call = make_test_call
-      done_tag, meta_tag = ActiveCall.client_start_invoke(call, @client_queue,
-                                                          deadline)
+      done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
+                                                    deadline)
       client_call = ActiveCall.new(call, @client_queue, @pass_through,
                                    @pass_through, deadline,
                                    finished_tag: done_tag,
@@ -170,8 +170,8 @@ describe GRPC::ActiveCall do
 
     it 'saves metadata { status=200 } when the server adds no metadata' do
       call = make_test_call
-      done_tag, meta_tag = ActiveCall.client_start_invoke(call, @client_queue,
-                                                          deadline)
+      done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
+                                                    deadline)
       client_call = ActiveCall.new(call, @client_queue, @pass_through,
                                    @pass_through, deadline,
                                    finished_tag: done_tag,
@@ -187,8 +187,8 @@ describe GRPC::ActiveCall do
 
     it 'saves metadata add by the server' do
       call = make_test_call
-      done_tag, meta_tag = ActiveCall.client_start_invoke(call, @client_queue,
-                                                          deadline)
+      done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
+                                                    deadline)
       client_call = ActiveCall.new(call, @client_queue, @pass_through,
                                    @pass_through, deadline,
                                    finished_tag: done_tag,
@@ -205,7 +205,7 @@ describe GRPC::ActiveCall do
 
     it 'get a nil msg before a status when an OK status is sent' do
       call = make_test_call
-      done_tag, meta_tag = ActiveCall.client_start_invoke(call, @client_queue,
+      done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
                                                           deadline)
       client_call = ActiveCall.new(call, @client_queue, @pass_through,
                                    @pass_through, deadline,
@@ -224,8 +224,8 @@ describe GRPC::ActiveCall do
 
     it 'unmarshals the response using the unmarshal func' do
       call = make_test_call
-      done_tag, meta_tag = ActiveCall.client_start_invoke(call, @client_queue,
-                                                          deadline)
+      done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
+                                                    deadline)
       unmarshal = proc { |x| 'unmarshalled:' + x }
       client_call = ActiveCall.new(call, @client_queue, @pass_through,
                                    unmarshal, deadline,
@@ -251,8 +251,8 @@ describe GRPC::ActiveCall do
 
     it 'the returns an enumerator that can read n responses' do
       call = make_test_call
-      done_tag, meta_tag = ActiveCall.client_start_invoke(call, @client_queue,
-                                                          deadline)
+      done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
+                                                    deadline)
       client_call = ActiveCall.new(call, @client_queue, @pass_through,
                                    @pass_through, deadline,
                                    finished_tag: done_tag,
@@ -271,8 +271,8 @@ describe GRPC::ActiveCall do
 
     it 'the returns an enumerator that stops after an OK Status' do
       call = make_test_call
-      done_tag, meta_tag = ActiveCall.client_start_invoke(call, @client_queue,
-                                                          deadline)
+      done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
+                                                    deadline)
       client_call = ActiveCall.new(call, @client_queue, @pass_through,
                                    @pass_through, deadline,
                                    read_metadata_tag: meta_tag,
@@ -296,8 +296,8 @@ describe GRPC::ActiveCall do
   describe '#writes_done' do
     it 'finishes ok if the server sends a status response' do
       call = make_test_call
-      done_tag, meta_tag = ActiveCall.client_start_invoke(call, @client_queue,
-                                                          deadline)
+      done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
+                                                    deadline)
       client_call = ActiveCall.new(call, @client_queue, @pass_through,
                                    @pass_through, deadline,
                                    finished_tag: done_tag,
@@ -315,8 +315,8 @@ describe GRPC::ActiveCall do
 
     it 'finishes ok if the server sends an early status response' do
       call = make_test_call
-      done_tag, meta_tag = ActiveCall.client_start_invoke(call, @client_queue,
-                                                          deadline)
+      done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
+                                                    deadline)
       client_call = ActiveCall.new(call, @client_queue, @pass_through,
                                    @pass_through, deadline,
                                    read_metadata_tag: meta_tag,
@@ -334,8 +334,8 @@ describe GRPC::ActiveCall do
 
     it 'finishes ok if writes_done is true' do
       call = make_test_call
-      done_tag, meta_tag = ActiveCall.client_start_invoke(call, @client_queue,
-                                                          deadline)
+      done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
+                                                    deadline)
       client_call = ActiveCall.new(call, @client_queue, @pass_through,
                                    @pass_through, deadline,
                                    read_metadata_tag: meta_tag,
-- 
GitLab