grpc 0.5.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grpc might be problematic. Click here for more details.

Files changed (86) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rspec +1 -0
  4. data/.rubocop.yml +10 -0
  5. data/.rubocop_todo.yml +52 -0
  6. data/Gemfile +4 -0
  7. data/README.md +82 -0
  8. data/Rakefile +54 -0
  9. data/bin/apis/google/protobuf/empty.rb +44 -0
  10. data/bin/apis/pubsub_demo.rb +267 -0
  11. data/bin/apis/tech/pubsub/proto/pubsub.rb +174 -0
  12. data/bin/apis/tech/pubsub/proto/pubsub_services.rb +103 -0
  13. data/bin/interop/README.md +8 -0
  14. data/bin/interop/interop_client.rb +334 -0
  15. data/bin/interop/interop_server.rb +192 -0
  16. data/bin/interop/test/cpp/interop/empty.rb +44 -0
  17. data/bin/interop/test/cpp/interop/messages.rb +89 -0
  18. data/bin/interop/test/cpp/interop/test.rb +43 -0
  19. data/bin/interop/test/cpp/interop/test_services.rb +60 -0
  20. data/bin/math.proto +80 -0
  21. data/bin/math.rb +61 -0
  22. data/bin/math_client.rb +147 -0
  23. data/bin/math_server.rb +190 -0
  24. data/bin/math_services.rb +56 -0
  25. data/bin/noproto_client.rb +108 -0
  26. data/bin/noproto_server.rb +112 -0
  27. data/ext/grpc/extconf.rb +76 -0
  28. data/ext/grpc/rb_byte_buffer.c +241 -0
  29. data/ext/grpc/rb_byte_buffer.h +54 -0
  30. data/ext/grpc/rb_call.c +569 -0
  31. data/ext/grpc/rb_call.h +59 -0
  32. data/ext/grpc/rb_channel.c +264 -0
  33. data/ext/grpc/rb_channel.h +49 -0
  34. data/ext/grpc/rb_channel_args.c +154 -0
  35. data/ext/grpc/rb_channel_args.h +52 -0
  36. data/ext/grpc/rb_completion_queue.c +185 -0
  37. data/ext/grpc/rb_completion_queue.h +50 -0
  38. data/ext/grpc/rb_credentials.c +281 -0
  39. data/ext/grpc/rb_credentials.h +50 -0
  40. data/ext/grpc/rb_event.c +361 -0
  41. data/ext/grpc/rb_event.h +53 -0
  42. data/ext/grpc/rb_grpc.c +274 -0
  43. data/ext/grpc/rb_grpc.h +74 -0
  44. data/ext/grpc/rb_metadata.c +215 -0
  45. data/ext/grpc/rb_metadata.h +53 -0
  46. data/ext/grpc/rb_server.c +278 -0
  47. data/ext/grpc/rb_server.h +50 -0
  48. data/ext/grpc/rb_server_credentials.c +210 -0
  49. data/ext/grpc/rb_server_credentials.h +50 -0
  50. data/grpc.gemspec +41 -0
  51. data/lib/grpc.rb +39 -0
  52. data/lib/grpc/core/event.rb +44 -0
  53. data/lib/grpc/core/time_consts.rb +71 -0
  54. data/lib/grpc/errors.rb +61 -0
  55. data/lib/grpc/generic/active_call.rb +536 -0
  56. data/lib/grpc/generic/bidi_call.rb +221 -0
  57. data/lib/grpc/generic/client_stub.rb +413 -0
  58. data/lib/grpc/generic/rpc_desc.rb +150 -0
  59. data/lib/grpc/generic/rpc_server.rb +404 -0
  60. data/lib/grpc/generic/service.rb +235 -0
  61. data/lib/grpc/logconfig.rb +40 -0
  62. data/lib/grpc/version.rb +33 -0
  63. data/spec/alloc_spec.rb +44 -0
  64. data/spec/byte_buffer_spec.rb +67 -0
  65. data/spec/call_spec.rb +163 -0
  66. data/spec/channel_spec.rb +181 -0
  67. data/spec/client_server_spec.rb +372 -0
  68. data/spec/completion_queue_spec.rb +74 -0
  69. data/spec/credentials_spec.rb +71 -0
  70. data/spec/event_spec.rb +53 -0
  71. data/spec/generic/active_call_spec.rb +373 -0
  72. data/spec/generic/client_stub_spec.rb +519 -0
  73. data/spec/generic/rpc_desc_spec.rb +357 -0
  74. data/spec/generic/rpc_server_pool_spec.rb +139 -0
  75. data/spec/generic/rpc_server_spec.rb +404 -0
  76. data/spec/generic/service_spec.rb +342 -0
  77. data/spec/metadata_spec.rb +64 -0
  78. data/spec/server_credentials_spec.rb +69 -0
  79. data/spec/server_spec.rb +212 -0
  80. data/spec/spec_helper.rb +51 -0
  81. data/spec/testdata/README +1 -0
  82. data/spec/testdata/ca.pem +15 -0
  83. data/spec/testdata/server1.key +16 -0
  84. data/spec/testdata/server1.pem +16 -0
  85. data/spec/time_consts_spec.rb +89 -0
  86. metadata +353 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dddc434bf5d95c1b4ac1c3155ca4889e21f061ee
4
+ data.tar.gz: 7486c06904d714662cd3a5506beec8b1785e5319
5
+ SHA512:
6
+ metadata.gz: 0c9da1478c53f528754b5723fd261a0e605862a9025ff5646d521f87dc1a678fdf69aeee48df6a37c46d4a17e8f614ba4c84a0ba0863663acdddcd242bc82f45
7
+ data.tar.gz: a2cd9ada86192f9ebd499d1e80e109511b5cede5eafc812074908be7c2495f70a011d00dbbd289f8d69dfec674fc121732b98c8993959015a0683cb08192437d
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ vendor
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ -I.
@@ -0,0 +1,10 @@
1
+ # This is the configuration used to check the rubocop source code.
2
+
3
+ inherit_from: .rubocop_todo.yml
4
+
5
+ AllCops:
6
+ Exclude:
7
+ - 'bin/apis/**/*'
8
+ - 'bin/interop/test/**/*'
9
+ - 'bin/math.rb'
10
+ - 'bin/math_services.rb'
@@ -0,0 +1,52 @@
1
+ # This configuration was generated by `rubocop --auto-gen-config`
2
+ # on 2015-01-16 02:30:04 -0800 using RuboCop version 0.28.0.
3
+ # The point is for the user to remove these configuration records
4
+ # one by one as the offenses are removed from the code base.
5
+ # Note that changes in the inspected code, or installation of new
6
+ # versions of RuboCop, may require this file to be generated again.
7
+
8
+ # Offense count: 3
9
+ # Lint/UselessAssignment:
10
+ # Enabled: false
11
+
12
+ # Offense count: 33
13
+ Metrics/AbcSize:
14
+ Max: 39
15
+
16
+ # Offense count: 3
17
+ # Configuration parameters: CountComments.
18
+ Metrics/ClassLength:
19
+ Max: 231
20
+
21
+ # Offense count: 2
22
+ Metrics/CyclomaticComplexity:
23
+ Max: 8
24
+
25
+ # Offense count: 36
26
+ # Configuration parameters: CountComments.
27
+ Metrics/MethodLength:
28
+ Max: 37
29
+
30
+ # Offense count: 8
31
+ # Configuration parameters: CountKeywordArgs.
32
+ Metrics/ParameterLists:
33
+ Max: 8
34
+
35
+ # Offense count: 2
36
+ Metrics/PerceivedComplexity:
37
+ Max: 10
38
+
39
+ # Offense count: 7
40
+ # Configuration parameters: AllowedVariables.
41
+ Style/GlobalVars:
42
+ Enabled: false
43
+
44
+ # Offense count: 1
45
+ # Configuration parameters: EnforcedStyle, MinBodyLength, SupportedStyles.
46
+ Style/Next:
47
+ Enabled: false
48
+
49
+ # Offense count: 2
50
+ # Configuration parameters: Methods.
51
+ Style/SingleLineBlockParams:
52
+ Enabled: false
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in grpc.gemspec
4
+ gemspec
@@ -0,0 +1,82 @@
1
+ gRPC Ruby
2
+ =========
3
+
4
+ A Ruby implementation of gRPC.
5
+
6
+ Status
7
+ -------
8
+
9
+ Alpha : Ready for early adopters
10
+
11
+ INSTALLATION PREREQUISITES
12
+ --------------------------
13
+
14
+ This requires Ruby 2.1, as the RPC API surface uses keyword args.
15
+
16
+
17
+ QUICK - INSTALL
18
+ ---------------
19
+
20
+ - Clone this repository.
21
+ - Follow the instructions in [INSTALL](../../INSTALL) to install the gRPC C core.
22
+ - If you don't have Ruby 2.1 installed, switch to the more detailed instructions below
23
+ - Use bundler to install
24
+ ```sh
25
+ $ # from this directory
26
+ $ gem install bundler && bundle install
27
+ ```
28
+
29
+ Installing from source
30
+ ----------------------
31
+
32
+ - Build the gRPC C core
33
+ E.g, from the root of the gRPC [git repo](https://github.com/google/grpc)
34
+ ```sh
35
+ $ cd ../..
36
+ $ make && sudo make install
37
+ ```
38
+
39
+ - Install Ruby 2.1. Consider doing this with [RVM](http://rvm.io), it's a nice way of controlling
40
+ the exact ruby version that's used.
41
+ ```sh
42
+ $ command curl -sSL https://rvm.io/mpapis.asc | gpg --import -
43
+ $ \curl -sSL https://get.rvm.io | bash -s stable --ruby=ruby-2.1
44
+ $
45
+ $ # follow the instructions to ensure that your're using the latest stable version of Ruby
46
+ $ # and that the rvm command is installed
47
+ ```
48
+
49
+ - Make sure your run `source $HOME/.rvm/scripts/rvm` as instructed to complete the set up of RVM
50
+
51
+ - Install [bundler](http://bundler.io/)
52
+ ```
53
+ $ gem install bundler
54
+ ```
55
+
56
+ - Finally, install the gRPC gem locally.
57
+ ```sh
58
+ $ # from this directory
59
+ $ bundle install # creates the ruby bundle, including building the grpc extension
60
+ $ rake # runs the unit tests, see rake -T for other options
61
+ ```
62
+
63
+ CONTENTS
64
+ --------
65
+
66
+ Directory structure is the layout for [ruby extensions](http://guides.rubygems.org/gems-with-extensions/)
67
+
68
+ - ext:
69
+ the gRPC ruby extension
70
+ - lib:
71
+ the entrypoint gRPC ruby library to be used in a 'require' statement
72
+ - spec:
73
+ Rspec unittest
74
+ - bin:
75
+ example gRPC clients and servers, e.g,
76
+ ```ruby
77
+ stub = Math::Math::Stub.new('my.test.math.server.com:8080')
78
+ req = Math::DivArgs.new(dividend: 7, divisor: 3)
79
+ logger.info("div(7/3): req=#{req.inspect}")
80
+ resp = stub.div(req)
81
+ logger.info("Answer: #{resp.inspect}")
82
+ ```
@@ -0,0 +1,54 @@
1
+ # -*- ruby -*-
2
+ require 'rake/extensiontask'
3
+ require 'rspec/core/rake_task'
4
+ require 'rubocop/rake_task'
5
+
6
+ desc 'Run Rubocop to check for style violations'
7
+ RuboCop::RakeTask.new
8
+
9
+ Rake::ExtensionTask.new 'grpc' do |ext|
10
+ ext.lib_dir = File.join('lib', 'grpc')
11
+ end
12
+
13
+ SPEC_SUITES = [
14
+ { id: :wrapper, title: 'wrapper layer', files: %w(spec/*.rb) },
15
+ { id: :idiomatic, title: 'idiomatic layer', dir: %w(spec/generic),
16
+ tags: ['~bidi', '~server'] },
17
+ { id: :bidi, title: 'bidi tests', dir: %w(spec/generic),
18
+ tag: 'bidi' },
19
+ { id: :server, title: 'rpc server thread tests', dir: %w(spec/generic),
20
+ tag: 'server' }
21
+ ]
22
+
23
+ desc 'Run all RSpec tests'
24
+ namespace :spec do
25
+ namespace :suite do
26
+ SPEC_SUITES.each do |suite|
27
+ desc "Run all specs in #{suite[:title]} spec suite"
28
+ RSpec::Core::RakeTask.new(suite[:id]) do |t|
29
+ spec_files = []
30
+ suite[:files].each { |f| spec_files += Dir[f] } if suite[:files]
31
+
32
+ if suite[:dirs]
33
+ suite[:dirs].each { |f| spec_files += Dir["#{f}/**/*_spec.rb"] }
34
+ end
35
+
36
+ t.pattern = spec_files
37
+ t.rspec_opts = "--tag #{suite[:tag]}" if suite[:tag]
38
+ if suite[:tags]
39
+ t.rspec_opts = suite[:tags].map { |x| "--tag #{x}" }.join(' ')
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ desc 'Compiles the extension then runs all the tests'
47
+ task :all
48
+
49
+ task default: :all
50
+ task 'spec:suite:wrapper' => [:compile, :rubocop]
51
+ task 'spec:suite:idiomatic' => 'spec:suite:wrapper'
52
+ task 'spec:suite:bidi' => 'spec:suite:wrapper'
53
+ task 'spec:suite:server' => 'spec:suite:wrapper'
54
+ task all: ['spec:suite:idiomatic', 'spec:suite:bidi', 'spec:suite:server']
@@ -0,0 +1,44 @@
1
+ # Copyright 2015, Google Inc.
2
+ # All rights reserved.
3
+ #
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are
6
+ # met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright
9
+ # notice, this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above
11
+ # copyright notice, this list of conditions and the following disclaimer
12
+ # in the documentation and/or other materials provided with the
13
+ # distribution.
14
+ # * Neither the name of Google Inc. nor the names of its
15
+ # contributors may be used to endorse or promote products derived from
16
+ # this software without specific prior written permission.
17
+ #
18
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+
30
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
31
+ # source: google/protobuf/empty.proto
32
+
33
+ require 'google/protobuf'
34
+
35
+ Google::Protobuf::DescriptorPool.generated_pool.build do
36
+ add_message "google.protobuf.Empty" do
37
+ end
38
+ end
39
+
40
+ module Google
41
+ module Protobuf
42
+ Empty = Google::Protobuf::DescriptorPool.generated_pool.lookup("google.protobuf.Empty").msgclass
43
+ end
44
+ end
@@ -0,0 +1,267 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Copyright 2015, Google Inc.
4
+ # All rights reserved.
5
+ #
6
+ # Redistribution and use in source and binary forms, with or without
7
+ # modification, are permitted provided that the following conditions are
8
+ # met:
9
+ #
10
+ # * Redistributions of source code must retain the above copyright
11
+ # notice, this list of conditions and the following disclaimer.
12
+ # * Redistributions in binary form must reproduce the above
13
+ # copyright notice, this list of conditions and the following disclaimer
14
+ # in the documentation and/or other materials provided with the
15
+ # distribution.
16
+ # * Neither the name of Google Inc. nor the names of its
17
+ # contributors may be used to endorse or promote products derived from
18
+ # this software without specific prior written permission.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+
32
+ # pubsub_demo demos accesses the Google PubSub API via its gRPC interface
33
+ #
34
+ # $ GOOGLE_APPLICATION_CREDENTIALS=<path_to_service_account_key_file> \
35
+ # SSL_CERT_FILE=<path/to/ssl/certs> \
36
+ # path/to/pubsub_demo.rb \
37
+ # [--action=<chosen_demo_action> ]
38
+ #
39
+ # There are options related to the chosen action, see #parse_args below.
40
+ # - the possible actions are given by the method names of NamedAction class
41
+ # - the default action is list_some_topics
42
+
43
+ this_dir = File.expand_path(File.dirname(__FILE__))
44
+ lib_dir = File.join(File.dirname(File.dirname(this_dir)), 'lib')
45
+ $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
46
+ $LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir)
47
+
48
+ require 'optparse'
49
+
50
+ require 'grpc'
51
+ require 'googleauth'
52
+ require 'google/protobuf'
53
+
54
+ require 'google/protobuf/empty'
55
+ require 'tech/pubsub/proto/pubsub'
56
+ require 'tech/pubsub/proto/pubsub_services'
57
+
58
+ # loads the certificates used to access the test server securely.
59
+ def load_prod_cert
60
+ fail 'could not find a production cert' if ENV['SSL_CERT_FILE'].nil?
61
+ p "loading prod certs from #{ENV['SSL_CERT_FILE']}"
62
+ File.open(ENV['SSL_CERT_FILE']) do |f|
63
+ return f.read
64
+ end
65
+ end
66
+
67
+ # creates a SSL Credentials from the production certificates.
68
+ def ssl_creds
69
+ GRPC::Core::Credentials.new(load_prod_cert)
70
+ end
71
+
72
+ # Builds the metadata authentication update proc.
73
+ def auth_proc(opts)
74
+ auth_creds = Google::Auth.get_application_default(opts.oauth_scope)
75
+ return auth_creds.updater_proc
76
+ end
77
+
78
+ # Creates a stub for accessing the publisher service.
79
+ def publisher_stub(opts)
80
+ address = "#{opts.host}:#{opts.port}"
81
+ stub_clz = Tech::Pubsub::PublisherService::Stub # shorter
82
+ logger.info("... access PublisherService at #{address}")
83
+ stub_clz.new(address,
84
+ creds: ssl_creds, update_metadata: auth_proc(opts),
85
+ GRPC::Core::Channel::SSL_TARGET => opts.host)
86
+ end
87
+
88
+ # Creates a stub for accessing the subscriber service.
89
+ def subscriber_stub(opts)
90
+ address = "#{opts.host}:#{opts.port}"
91
+ stub_clz = Tech::Pubsub::SubscriberService::Stub # shorter
92
+ logger.info("... access SubscriberService at #{address}")
93
+ stub_clz.new(address,
94
+ creds: ssl_creds, update_metadata: auth_proc(opts),
95
+ GRPC::Core::Channel::SSL_TARGET => opts.host)
96
+ end
97
+
98
+ # defines methods corresponding to each interop test case.
99
+ class NamedActions
100
+ include Tech::Pubsub
101
+
102
+ # Initializes NamedActions
103
+ #
104
+ # @param pub [Stub] a stub for accessing the publisher service
105
+ # @param sub [Stub] a stub for accessing the publisher service
106
+ # @param args [Args] provides access to the command line
107
+ def initialize(pub, sub, args)
108
+ @pub = pub
109
+ @sub = sub
110
+ @args = args
111
+ end
112
+
113
+ # Removes the test topic if it exists
114
+ def remove_topic
115
+ name = test_topic_name
116
+ p "... removing Topic #{name}"
117
+ @pub.delete_topic(DeleteTopicRequest.new(topic: name))
118
+ p "removed Topic: #{name} OK"
119
+ rescue GRPC::BadStatus => e
120
+ p "Could not delete a topics: rpc failed with '#{e}'"
121
+ end
122
+
123
+ # Creates a test topic
124
+ def create_topic
125
+ name = test_topic_name
126
+ p "... creating Topic #{name}"
127
+ resp = @pub.create_topic(Topic.new(name: name))
128
+ p "created Topic: #{resp.name} OK"
129
+ rescue GRPC::BadStatus => e
130
+ p "Could not create a topics: rpc failed with '#{e}'"
131
+ end
132
+
133
+ # Lists topics in the project
134
+ def list_some_topics
135
+ p 'Listing topics'
136
+ p '-------------_'
137
+ list_project_topics.topic.each { |t| p t.name }
138
+ rescue GRPC::BadStatus => e
139
+ p "Could not list topics: rpc failed with '#{e}'"
140
+ end
141
+
142
+ # Checks if a topics exists in a project
143
+ def check_exists
144
+ name = test_topic_name
145
+ p "... checking for topic #{name}"
146
+ exists = topic_exists?(name)
147
+ p "#{name} is a topic" if exists
148
+ p "#{name} is not a topic" unless exists
149
+ rescue GRPC::BadStatus => e
150
+ p "Could not check for a topics: rpc failed with '#{e}'"
151
+ end
152
+
153
+ # Publishes some messages
154
+ def random_pub_sub
155
+ topic_name, sub_name = test_topic_name, test_sub_name
156
+ create_topic_if_needed(topic_name)
157
+ @sub.create_subscription(Subscription.new(name: sub_name,
158
+ topic: topic_name))
159
+ msg_count = rand(10..30)
160
+ msg_count.times do |x|
161
+ msg = PubsubMessage.new(data: "message #{x}")
162
+ @pub.publish(PublishRequest.new(topic: topic_name, message: msg))
163
+ end
164
+ p "Sent #{msg_count} messages to #{topic_name}, checking for them now."
165
+ batch = @sub.pull_batch(PullBatchRequest.new(subscription: sub_name,
166
+ max_events: msg_count))
167
+ ack_ids = batch.pull_responses.map { |x| x.ack_id }
168
+ p "Got #{ack_ids.size} messages; acknowledging them.."
169
+ @sub.acknowledge(AcknowledgeRequest.new(subscription: sub_name,
170
+ ack_id: ack_ids))
171
+ p "Test messages were acknowledged OK, deleting the subscription"
172
+ del_req = DeleteSubscriptionRequest.new(subscription: sub_name)
173
+ @sub.delete_subscription(del_req)
174
+ rescue GRPC::BadStatus => e
175
+ p "Could not do random pub sub: rpc failed with '#{e}'"
176
+ end
177
+
178
+ private
179
+
180
+ # test_topic_name is the topic name to use in this test.
181
+ def test_topic_name
182
+ unless @args.topic_name.nil?
183
+ return "/topics/#{@args.project_id}/#{@args.topic_name}"
184
+ end
185
+ now_text = Time.now.utc.strftime('%Y%m%d%H%M%S%L')
186
+ "/topics/#{@args.project_id}/#{ENV['USER']}-#{now_text}"
187
+ end
188
+
189
+ # test_sub_name is the subscription name to use in this test.
190
+ def test_sub_name
191
+ unless @args.sub_name.nil?
192
+ return "/subscriptions/#{@args.project_id}/#{@args.sub_name}"
193
+ end
194
+ now_text = Time.now.utc.strftime('%Y%m%d%H%M%S%L')
195
+ "/subscriptions/#{@args.project_id}/#{ENV['USER']}-#{now_text}"
196
+ end
197
+
198
+ # determines if the topic name exists
199
+ def topic_exists?(name)
200
+ topics = list_project_topics.topic.map { |t| t.name }
201
+ topics.include?(name)
202
+ end
203
+
204
+ def create_topic_if_needed(name)
205
+ return if topic_exists?(name)
206
+ @pub.create_topic(Topic.new(name: name))
207
+ end
208
+
209
+ def list_project_topics
210
+ q = "cloud.googleapis.com/project in (/projects/#{@args.project_id})"
211
+ @pub.list_topics(ListTopicsRequest.new(query: q))
212
+ end
213
+ end
214
+
215
+ # Args is used to hold the command line info.
216
+ Args = Struct.new(:host, :oauth_scope, :port, :action, :project_id, :topic_name,
217
+ :sub_name)
218
+
219
+ # validates the the command line options, returning them as an Arg.
220
+ def parse_args
221
+ args = Args.new('pubsub-staging.googleapis.com',
222
+ 'https://www.googleapis.com/auth/pubsub',
223
+ 443, 'list_some_topics', 'stoked-keyword-656')
224
+ OptionParser.new do |opts|
225
+ opts.on('--oauth_scope scope',
226
+ 'Scope for OAuth tokens') { |v| args['oauth_scope'] = v }
227
+ opts.on('--server_host SERVER_HOST', 'server hostname') do |v|
228
+ args.host = v
229
+ end
230
+ opts.on('--server_port SERVER_PORT', 'server port') do |v|
231
+ args.port = v
232
+ end
233
+
234
+ # instance_methods(false) gives only the methods defined in that class.
235
+ scenes = NamedActions.instance_methods(false).map { |t| t.to_s }
236
+ scene_list = scenes.join(',')
237
+ opts.on("--action CODE", scenes, {}, 'pick a demo action',
238
+ " (#{scene_list})") do |v|
239
+ args.action = v
240
+ end
241
+
242
+ # Set the remaining values.
243
+ %w(project_id topic_name sub_name).each do |o|
244
+ opts.on("--#{o} VALUE", "#{o}") do |v|
245
+ args[o] = v
246
+ end
247
+ end
248
+ end.parse!
249
+ _check_args(args)
250
+ end
251
+
252
+ def _check_args(args)
253
+ %w(host port action oauth_scope).each do |a|
254
+ if args[a].nil?
255
+ raise OptionParser::MissingArgument.new("please specify --#{a}")
256
+ end
257
+ end
258
+ args
259
+ end
260
+
261
+ def main
262
+ args = parse_args
263
+ pub, sub = publisher_stub(args), subscriber_stub(args)
264
+ NamedActions.new(pub, sub, args).method(args.action).call
265
+ end
266
+
267
+ main