aboutsummaryrefslogtreecommitdiffhomepage
path: root/examples/ruby
diff options
context:
space:
mode:
Diffstat (limited to 'examples/ruby')
-rw-r--r--examples/ruby/grpc-demo.gemspec1
-rw-r--r--examples/ruby/pubsub/google/protobuf/empty.rb29
-rwxr-xr-xexamples/ruby/pubsub/pubsub_demo.rb241
-rw-r--r--examples/ruby/pubsub/tech/pubsub/proto/pubsub.rb159
-rw-r--r--examples/ruby/pubsub/tech/pubsub/proto/pubsub_services.rb88
5 files changed, 518 insertions, 0 deletions
diff --git a/examples/ruby/grpc-demo.gemspec b/examples/ruby/grpc-demo.gemspec
index 4423fd34d4..c77446249e 100644
--- a/examples/ruby/grpc-demo.gemspec
+++ b/examples/ruby/grpc-demo.gemspec
@@ -18,6 +18,7 @@ Gem::Specification.new do |s|
s.platform = Gem::Platform::RUBY
s.add_dependency 'grpc', '~> 1.0'
+ s.add_dependency 'googleauth', '>= 0.5.1', '< 0.7'
s.add_development_dependency 'bundler', '~> 1.7'
end
diff --git a/examples/ruby/pubsub/google/protobuf/empty.rb b/examples/ruby/pubsub/google/protobuf/empty.rb
new file mode 100644
index 0000000000..4743bded3d
--- /dev/null
+++ b/examples/ruby/pubsub/google/protobuf/empty.rb
@@ -0,0 +1,29 @@
+# Copyright 2015 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: google/protobuf/empty.proto
+
+require 'google/protobuf'
+
+Google::Protobuf::DescriptorPool.generated_pool.build do
+ add_message "google.protobuf.Empty" do
+ end
+end
+
+module Google
+ module Protobuf
+ Empty = Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Empty").msgclass
+ end
+end
diff --git a/examples/ruby/pubsub/pubsub_demo.rb b/examples/ruby/pubsub/pubsub_demo.rb
new file mode 100755
index 0000000000..c565771d45
--- /dev/null
+++ b/examples/ruby/pubsub/pubsub_demo.rb
@@ -0,0 +1,241 @@
+#!/usr/bin/env ruby
+
+# Copyright 2015 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# pubsub_demo demos accesses the Google PubSub API via its gRPC interface
+#
+# $ GOOGLE_APPLICATION_CREDENTIALS=<path_to_service_account_key_file> \
+# path/to/pubsub_demo.rb \
+# [--action=<chosen_demo_action> ]
+#
+# There are options related to the chosen action, see #parse_args below.
+# - the possible actions are given by the method names of NamedAction class
+# - the default action is list_some_topics
+
+this_dir = File.expand_path(File.dirname(__FILE__))
+lib_dir = File.join(File.dirname(File.dirname(this_dir)), 'lib')
+$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
+$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir)
+
+require 'optparse'
+
+require 'grpc'
+require 'googleauth'
+require 'google/protobuf'
+
+require 'google/protobuf/empty'
+require 'tech/pubsub/proto/pubsub'
+require 'tech/pubsub/proto/pubsub_services'
+
+# creates a SSL Credentials from the production certificates.
+def ssl_creds
+ GRPC::Core::ChannelCredentials.new()
+end
+
+# Builds the metadata authentication update proc.
+def auth_proc(opts)
+ auth_creds = Google::Auth.get_application_default
+ return auth_creds.updater_proc
+end
+
+# Creates a stub for accessing the publisher service.
+def publisher_stub(opts)
+ address = "#{opts.host}:#{opts.port}"
+ stub_clz = Tech::Pubsub::PublisherService::Stub # shorter
+ GRPC.logger.info("... access PublisherService at #{address}")
+ call_creds = GRPC::Core::CallCredentials.new(auth_proc(opts))
+ combined_creds = ssl_creds.compose(call_creds)
+ stub_clz.new(address, creds: combined_creds,
+ GRPC::Core::Channel::SSL_TARGET => opts.host)
+end
+
+# Creates a stub for accessing the subscriber service.
+def subscriber_stub(opts)
+ address = "#{opts.host}:#{opts.port}"
+ stub_clz = Tech::Pubsub::SubscriberService::Stub # shorter
+ GRPC.logger.info("... access SubscriberService at #{address}")
+ call_creds = GRPC::Core::CallCredentials.new(auth_proc(opts))
+ combined_creds = ssl_creds.compose(call_creds)
+ stub_clz.new(address, creds: combined_creds,
+ GRPC::Core::Channel::SSL_TARGET => opts.host)
+end
+
+# defines methods corresponding to each interop test case.
+class NamedActions
+ include Tech::Pubsub
+
+ # Initializes NamedActions
+ #
+ # @param pub [Stub] a stub for accessing the publisher service
+ # @param sub [Stub] a stub for accessing the publisher service
+ # @param args [Args] provides access to the command line
+ def initialize(pub, sub, args)
+ @pub = pub
+ @sub = sub
+ @args = args
+ end
+
+ # Removes the test topic if it exists
+ def remove_topic
+ name = test_topic_name
+ p "... removing Topic #{name}"
+ @pub.delete_topic(DeleteTopicRequest.new(topic: name))
+ p "removed Topic: #{name} OK"
+ rescue GRPC::BadStatus => e
+ p "Could not delete a topics: rpc failed with '#{e}'"
+ end
+
+ # Creates a test topic
+ def create_topic
+ name = test_topic_name
+ p "... creating Topic #{name}"
+ resp = @pub.create_topic(Topic.new(name: name))
+ p "created Topic: #{resp.name} OK"
+ rescue GRPC::BadStatus => e
+ p "Could not create a topics: rpc failed with '#{e}'"
+ end
+
+ # Lists topics in the project
+ def list_some_topics
+ p 'Listing topics'
+ p '-------------_'
+ list_project_topics.topic.each { |t| p t.name }
+ rescue GRPC::BadStatus => e
+ p "Could not list topics: rpc failed with '#{e}'"
+ end
+
+ # Checks if a topics exists in a project
+ def check_exists
+ name = test_topic_name
+ p "... checking for topic #{name}"
+ exists = topic_exists?(name)
+ p "#{name} is a topic" if exists
+ p "#{name} is not a topic" unless exists
+ rescue GRPC::BadStatus => e
+ p "Could not check for a topics: rpc failed with '#{e}'"
+ end
+
+ # Publishes some messages
+ def random_pub_sub
+ topic_name, sub_name = test_topic_name, test_sub_name
+ create_topic_if_needed(topic_name)
+ @sub.create_subscription(Subscription.new(name: sub_name,
+ topic: topic_name))
+ msg_count = rand(10..30)
+ msg_count.times do |x|
+ msg = PubsubMessage.new(data: "message #{x}")
+ @pub.publish(PublishRequest.new(topic: topic_name, message: msg))
+ end
+ p "Sent #{msg_count} messages to #{topic_name}, checking for them now."
+ batch = @sub.pull_batch(PullBatchRequest.new(subscription: sub_name,
+ max_events: msg_count))
+ ack_ids = batch.pull_responses.map { |x| x.ack_id }
+ p "Got #{ack_ids.size} messages; acknowledging them.."
+ @sub.acknowledge(AcknowledgeRequest.new(subscription: sub_name,
+ ack_id: ack_ids))
+ p "Test messages were acknowledged OK, deleting the subscription"
+ del_req = DeleteSubscriptionRequest.new(subscription: sub_name)
+ @sub.delete_subscription(del_req)
+ rescue GRPC::BadStatus => e
+ p "Could not do random pub sub: rpc failed with '#{e}'"
+ end
+
+ private
+
+ # test_topic_name is the topic name to use in this test.
+ def test_topic_name
+ unless @args.topic_name.nil?
+ return "/topics/#{@args.project_id}/#{@args.topic_name}"
+ end
+ now_text = Time.now.utc.strftime('%Y%m%d%H%M%S%L')
+ "/topics/#{@args.project_id}/#{ENV['USER']}-#{now_text}"
+ end
+
+ # test_sub_name is the subscription name to use in this test.
+ def test_sub_name
+ unless @args.sub_name.nil?
+ return "/subscriptions/#{@args.project_id}/#{@args.sub_name}"
+ end
+ now_text = Time.now.utc.strftime('%Y%m%d%H%M%S%L')
+ "/subscriptions/#{@args.project_id}/#{ENV['USER']}-#{now_text}"
+ end
+
+ # determines if the topic name exists
+ def topic_exists?(name)
+ topics = list_project_topics.topic.map { |t| t.name }
+ topics.include?(name)
+ end
+
+ def create_topic_if_needed(name)
+ return if topic_exists?(name)
+ @pub.create_topic(Topic.new(name: name))
+ end
+
+ def list_project_topics
+ q = "cloud.googleapis.com/project in (/projects/#{@args.project_id})"
+ @pub.list_topics(ListTopicsRequest.new(query: q))
+ end
+end
+
+# Args is used to hold the command line info.
+Args = Struct.new(:host, :port, :action, :project_id, :topic_name,
+ :sub_name)
+
+# validates the command line options, returning them as an Arg.
+def parse_args
+ args = Args.new('pubsub-staging.googleapis.com',
+ 443, 'list_some_topics', 'stoked-keyword-656')
+ OptionParser.new do |opts|
+ opts.on('--server_host SERVER_HOST', 'server hostname') do |v|
+ args.host = v
+ end
+ opts.on('--server_port SERVER_PORT', 'server port') do |v|
+ args.port = v
+ end
+
+ # instance_methods(false) gives only the methods defined in that class.
+ scenes = NamedActions.instance_methods(false).map { |t| t.to_s }
+ scene_list = scenes.join(',')
+ opts.on("--action CODE", scenes, {}, 'pick a demo action',
+ " (#{scene_list})") do |v|
+ args.action = v
+ end
+
+ # Set the remaining values.
+ %w(project_id topic_name sub_name).each do |o|
+ opts.on("--#{o} VALUE", "#{o}") do |v|
+ args[o] = v
+ end
+ end
+ end.parse!
+ _check_args(args)
+end
+
+def _check_args(args)
+ %w(host port action).each do |a|
+ if args[a].nil?
+ raise OptionParser::MissingArgument.new("please specify --#{a}")
+ end
+ end
+ args
+end
+
+def main
+ args = parse_args
+ pub, sub = publisher_stub(args), subscriber_stub(args)
+ NamedActions.new(pub, sub, args).method(args.action).call
+end
+
+main
diff --git a/examples/ruby/pubsub/tech/pubsub/proto/pubsub.rb b/examples/ruby/pubsub/tech/pubsub/proto/pubsub.rb
new file mode 100644
index 0000000000..73a0d5d9e4
--- /dev/null
+++ b/examples/ruby/pubsub/tech/pubsub/proto/pubsub.rb
@@ -0,0 +1,159 @@
+# Copyright 2015 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: tech/pubsub/proto/pubsub.proto
+
+require 'google/protobuf'
+
+require 'google/protobuf/empty'
+Google::Protobuf::DescriptorPool.generated_pool.build do
+ add_message "tech.pubsub.Topic" do
+ optional :name, :string, 1
+ end
+ add_message "tech.pubsub.PubsubMessage" do
+ optional :data, :string, 1
+ optional :message_id, :string, 3
+ end
+ add_message "tech.pubsub.GetTopicRequest" do
+ optional :topic, :string, 1
+ end
+ add_message "tech.pubsub.PublishRequest" do
+ optional :topic, :string, 1
+ optional :message, :message, 2, "tech.pubsub.PubsubMessage"
+ end
+ add_message "tech.pubsub.PublishBatchRequest" do
+ optional :topic, :string, 1
+ repeated :messages, :message, 2, "tech.pubsub.PubsubMessage"
+ end
+ add_message "tech.pubsub.PublishBatchResponse" do
+ repeated :message_ids, :string, 1
+ end
+ add_message "tech.pubsub.ListTopicsRequest" do
+ optional :query, :string, 1
+ optional :max_results, :int32, 2
+ optional :page_token, :string, 3
+ end
+ add_message "tech.pubsub.ListTopicsResponse" do
+ repeated :topic, :message, 1, "tech.pubsub.Topic"
+ optional :next_page_token, :string, 2
+ end
+ add_message "tech.pubsub.DeleteTopicRequest" do
+ optional :topic, :string, 1
+ end
+ add_message "tech.pubsub.Subscription" do
+ optional :name, :string, 1
+ optional :topic, :string, 2
+ optional :query, :string, 3
+ optional :truncation_policy, :message, 4, "tech.pubsub.Subscription.TruncationPolicy"
+ optional :push_config, :message, 5, "tech.pubsub.PushConfig"
+ optional :ack_deadline_seconds, :int32, 6
+ optional :garbage_collect_seconds, :int64, 7
+ end
+ add_message "tech.pubsub.Subscription.TruncationPolicy" do
+ optional :max_bytes, :int64, 1
+ optional :max_age_seconds, :int64, 2
+ end
+ add_message "tech.pubsub.PushConfig" do
+ optional :push_endpoint, :string, 1
+ end
+ add_message "tech.pubsub.PubsubEvent" do
+ optional :subscription, :string, 1
+ optional :message, :message, 2, "tech.pubsub.PubsubMessage"
+ optional :truncated, :bool, 3
+ optional :deleted, :bool, 4
+ end
+ add_message "tech.pubsub.GetSubscriptionRequest" do
+ optional :subscription, :string, 1
+ end
+ add_message "tech.pubsub.ListSubscriptionsRequest" do
+ optional :query, :string, 1
+ optional :max_results, :int32, 3
+ optional :page_token, :string, 4
+ end
+ add_message "tech.pubsub.ListSubscriptionsResponse" do
+ repeated :subscription, :message, 1, "tech.pubsub.Subscription"
+ optional :next_page_token, :string, 2
+ end
+ add_message "tech.pubsub.TruncateSubscriptionRequest" do
+ optional :subscription, :string, 1
+ end
+ add_message "tech.pubsub.DeleteSubscriptionRequest" do
+ optional :subscription, :string, 1
+ end
+ add_message "tech.pubsub.ModifyPushConfigRequest" do
+ optional :subscription, :string, 1
+ optional :push_config, :message, 2, "tech.pubsub.PushConfig"
+ end
+ add_message "tech.pubsub.PullRequest" do
+ optional :subscription, :string, 1
+ optional :return_immediately, :bool, 2
+ end
+ add_message "tech.pubsub.PullResponse" do
+ optional :ack_id, :string, 1
+ optional :pubsub_event, :message, 2, "tech.pubsub.PubsubEvent"
+ end
+ add_message "tech.pubsub.PullBatchRequest" do
+ optional :subscription, :string, 1
+ optional :return_immediately, :bool, 2
+ optional :max_events, :int32, 3
+ end
+ add_message "tech.pubsub.PullBatchResponse" do
+ repeated :pull_responses, :message, 2, "tech.pubsub.PullResponse"
+ end
+ add_message "tech.pubsub.ModifyAckDeadlineRequest" do
+ optional :subscription, :string, 1
+ optional :ack_id, :string, 2
+ optional :ack_deadline_seconds, :int32, 3
+ end
+ add_message "tech.pubsub.AcknowledgeRequest" do
+ optional :subscription, :string, 1
+ repeated :ack_id, :string, 2
+ end
+ add_message "tech.pubsub.NackRequest" do
+ optional :subscription, :string, 1
+ repeated :ack_id, :string, 2
+ end
+end
+
+module Tech
+ module Pubsub
+ Topic = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.Topic").msgclass
+ PubsubMessage = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PubsubMessage").msgclass
+ GetTopicRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.GetTopicRequest").msgclass
+ PublishRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PublishRequest").msgclass
+ PublishBatchRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PublishBatchRequest").msgclass
+ PublishBatchResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PublishBatchResponse").msgclass
+ ListTopicsRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.ListTopicsRequest").msgclass
+ ListTopicsResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.ListTopicsResponse").msgclass
+ DeleteTopicRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.DeleteTopicRequest").msgclass
+ Subscription = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.Subscription").msgclass
+ Subscription::TruncationPolicy = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.Subscription.TruncationPolicy").msgclass
+ PushConfig = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PushConfig").msgclass
+ PubsubEvent = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PubsubEvent").msgclass
+ GetSubscriptionRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.GetSubscriptionRequest").msgclass
+ ListSubscriptionsRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.ListSubscriptionsRequest").msgclass
+ ListSubscriptionsResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.ListSubscriptionsResponse").msgclass
+ TruncateSubscriptionRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.TruncateSubscriptionRequest").msgclass
+ DeleteSubscriptionRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.DeleteSubscriptionRequest").msgclass
+ ModifyPushConfigRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.ModifyPushConfigRequest").msgclass
+ PullRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PullRequest").msgclass
+ PullResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PullResponse").msgclass
+ PullBatchRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PullBatchRequest").msgclass
+ PullBatchResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.PullBatchResponse").msgclass
+ ModifyAckDeadlineRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.ModifyAckDeadlineRequest").msgclass
+ AcknowledgeRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.AcknowledgeRequest").msgclass
+ NackRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("tech.pubsub.NackRequest").msgclass
+ end
+end
diff --git a/examples/ruby/pubsub/tech/pubsub/proto/pubsub_services.rb b/examples/ruby/pubsub/tech/pubsub/proto/pubsub_services.rb
new file mode 100644
index 0000000000..b34db57b44
--- /dev/null
+++ b/examples/ruby/pubsub/tech/pubsub/proto/pubsub_services.rb
@@ -0,0 +1,88 @@
+# Copyright 2015 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# Source: tech/pubsub/proto/pubsub.proto for package 'tech.pubsub'
+
+require 'grpc'
+require 'google/protobuf/empty'
+require 'tech/pubsub/proto/pubsub'
+
+module Tech
+ module Pubsub
+ module PublisherService
+
+ # TODO: add proto service documentation here
+ class Service
+
+ include GRPC::GenericService
+
+ self.marshal_class_method = :encode
+ self.unmarshal_class_method = :decode
+ self.service_name = 'tech.pubsub.PublisherService'
+
+ rpc :CreateTopic, Topic, Topic
+ rpc :Publish, PublishRequest, Google::Protobuf::Empty
+ rpc :PublishBatch, PublishBatchRequest, PublishBatchResponse
+ rpc :GetTopic, GetTopicRequest, Topic
+ rpc :ListTopics, ListTopicsRequest, ListTopicsResponse
+ rpc :DeleteTopic, DeleteTopicRequest, Google::Protobuf::Empty
+ end
+
+ Stub = Service.rpc_stub_class
+ end
+ module SubscriberService
+
+ # TODO: add proto service documentation here
+ class Service
+
+ include GRPC::GenericService
+
+ self.marshal_class_method = :encode
+ self.unmarshal_class_method = :decode
+ self.service_name = 'tech.pubsub.SubscriberService'
+
+ rpc :CreateSubscription, Subscription, Subscription
+ rpc :GetSubscription, GetSubscriptionRequest, Subscription
+ rpc :ListSubscriptions, ListSubscriptionsRequest, ListSubscriptionsResponse
+ rpc :DeleteSubscription, DeleteSubscriptionRequest, Google::Protobuf::Empty
+ rpc :TruncateSubscription, TruncateSubscriptionRequest, Google::Protobuf::Empty
+ rpc :ModifyPushConfig, ModifyPushConfigRequest, Google::Protobuf::Empty
+ rpc :Pull, PullRequest, PullResponse
+ rpc :PullBatch, PullBatchRequest, PullBatchResponse
+ rpc :ModifyAckDeadline, ModifyAckDeadlineRequest, Google::Protobuf::Empty
+ rpc :Acknowledge, AcknowledgeRequest, Google::Protobuf::Empty
+ rpc :Nack, NackRequest, Google::Protobuf::Empty
+ end
+
+ Stub = Service.rpc_stub_class
+ end
+ module PushEndpointService
+
+ # TODO: add proto service documentation here
+ class Service
+
+ include GRPC::GenericService
+
+ self.marshal_class_method = :encode
+ self.unmarshal_class_method = :decode
+ self.service_name = 'tech.pubsub.PushEndpointService'
+
+ rpc :HandlePubsubEvent, PubsubEvent, Google::Protobuf::Empty
+ end
+
+ Stub = Service.rpc_stub_class
+ end
+ end
+end