google-cloud-pubsub 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,31 @@
1
+ # Copyright 2015 Google Inc. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ require "google/cloud/credentials"
17
+
18
+ module Google
19
+ module Cloud
20
+ module Pubsub
21
+ ##
22
+ # @private Represents the OAuth 2.0 signing logic for Pub/Sub.
23
+ class Credentials < Google::Cloud::Credentials
24
+ SCOPE = ["https://www.googleapis.com/auth/pubsub"]
25
+ PATH_ENV_VARS = %w(PUBSUB_KEYFILE GOOGLE_CLOUD_KEYFILE GCLOUD_KEYFILE)
26
+ JSON_ENV_VARS = %w(PUBSUB_KEYFILE_JSON GOOGLE_CLOUD_KEYFILE_JSON
27
+ GCLOUD_KEYFILE_JSON)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,96 @@
1
+ # Copyright 2015 Google Inc. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ require "google/cloud/errors"
17
+
18
+ module Google
19
+ module Cloud
20
+ module Pubsub
21
+ ##
22
+ # # Message
23
+ #
24
+ # Represents a Pub/Sub Message.
25
+ #
26
+ # Message objects are created by {Topic#publish}. {Subscription#pull}
27
+ # returns an array of {ReceivedMessage} objects, each of which contains a
28
+ # Message object. Each {ReceivedMessage} object can be acknowledged and/or
29
+ # delayed.
30
+ #
31
+ # @example
32
+ # require "google/cloud"
33
+ #
34
+ # gcloud = Google::Cloud.new
35
+ # pubsub = gcloud.pubsub
36
+ #
37
+ # # Publish a message
38
+ # topic = pubsub.topic "my-topic"
39
+ # message = topic.publish "new-message"
40
+ # puts message.data #=> "new-message"
41
+ #
42
+ # # Pull a message
43
+ # sub = pubsub.subscription "my-topic-sub"
44
+ # received_message = sub.pull.first
45
+ # puts received_message.message.data #=> "new-message"
46
+ #
47
+ class Message
48
+ ##
49
+ # @private The gRPC Google::Pubsub::V1::PubsubMessage object.
50
+ attr_accessor :grpc
51
+
52
+ ##
53
+ # Create an empty Message object.
54
+ # This can be used to publish several messages in bulk.
55
+ def initialize data = nil, attributes = {}
56
+ # Convert attributes to strings to match the protobuf definition
57
+ attributes = Hash[attributes.map { |k, v| [String(k), String(v)] }]
58
+
59
+ @grpc = Google::Pubsub::V1::PubsubMessage.new(
60
+ data: String(data).encode("ASCII-8BIT"),
61
+ attributes: attributes)
62
+ end
63
+
64
+ ##
65
+ # The received data.
66
+ def data
67
+ @grpc.data
68
+ end
69
+
70
+ ##
71
+ # The received attributes.
72
+ def attributes
73
+ return @grpc.attributes.to_h if @grpc.attributes.respond_to? :to_h
74
+ # Enumerable doesn't have to_h on Ruby 2.0, so fallback to this
75
+ Hash[@grpc.attributes.to_a]
76
+ end
77
+
78
+ ##
79
+ # The ID of this message, assigned by the server at publication time.
80
+ # Guaranteed to be unique within the topic.
81
+ def message_id
82
+ @grpc.message_id
83
+ end
84
+ alias_method :msg_id, :message_id
85
+
86
+ ##
87
+ # @private New Message from a Google::Pubsub::V1::PubsubMessage object.
88
+ def self.from_grpc grpc
89
+ new.tap do |m|
90
+ m.instance_variable_set "@grpc", grpc
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,209 @@
1
+ # Copyright 2016 Google Inc. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ require "google/cloud/errors"
17
+
18
+ module Google
19
+ module Cloud
20
+ module Pubsub
21
+ ##
22
+ # # Policy
23
+ #
24
+ # Represents a Cloud IAM Policy for the Pub/Sub service.
25
+ #
26
+ # A common pattern for updating a resource's metadata, such as its Policy,
27
+ # is to read the current data from the service, update the data locally,
28
+ # and then send the modified data for writing. This pattern may result in
29
+ # a conflict if two or more processes attempt the sequence simultaneously.
30
+ # IAM solves this problem with the {Google::Cloud::Pubsub::Policy#etag}
31
+ # property, which is used to verify whether the policy has changed since
32
+ # the last request. When you make a request to with an `etag` value, Cloud
33
+ # IAM compares the `etag` value in the request with the existing `etag`
34
+ # value associated with the policy. It writes the policy only if the
35
+ # `etag` values match.
36
+ #
37
+ # When you update a policy, first read the policy (and its current `etag`)
38
+ # from the service, then modify the policy locally, and then write the
39
+ # modified policy to the service. See
40
+ # {Google::Cloud::Pubsub::Topic#policy} and
41
+ # {Google::Cloud::Pubsub::Topic#policy=}.
42
+ #
43
+ # @see https://cloud.google.com/iam/docs/managing-policies Managing
44
+ # policies
45
+ # @see https://cloud.google.com/pubsub/reference/rpc/google.iam.v1#iampolicy
46
+ # google.iam.v1.IAMPolicy
47
+ #
48
+ # @attr [String] etag Used to verify whether the policy has changed since
49
+ # the last request. The policy will be written only if the `etag` values
50
+ # match.
51
+ # @attr [Hash{String => Array<String>}] roles The bindings that associate
52
+ # roles with an array of members. See [Understanding
53
+ # Roles](https://cloud.google.com/iam/docs/understanding-roles) for a
54
+ # listing of primitive and curated roles.
55
+ # See [Binding](https://cloud.google.com/pubsub/reference/rpc/google.iam.v1#binding)
56
+ # for a listing of values and patterns for members.
57
+ #
58
+ # @example
59
+ # require "google/cloud"
60
+ #
61
+ # gcloud = Google::Cloud.new
62
+ # pubsub = gcloud.pubsub
63
+ # topic = pubsub.topic "my-topic"
64
+ #
65
+ # policy = topic.policy # API call
66
+ #
67
+ # policy.remove "roles/owner", "user:owner@example.com" # Local call
68
+ # policy.add "roles/owner", "user:newowner@example.com" # Local call
69
+ # policy.roles["roles/viewer"] = ["allUsers"] # Local call
70
+ #
71
+ # topic.policy = policy # API call
72
+ #
73
+ class Policy
74
+ attr_reader :etag, :roles
75
+
76
+ ##
77
+ # @private Creates a Policy object.
78
+ def initialize etag, roles
79
+ @etag = etag
80
+ @roles = roles
81
+ end
82
+
83
+ ##
84
+ # Convenience method for adding a member to a binding on this policy.
85
+ # See [Understanding
86
+ # Roles](https://cloud.google.com/iam/docs/understanding-roles) for a
87
+ # listing of primitive and curated roles.
88
+ # See [Binding](https://cloud.google.com/pubsub/reference/rpc/google.iam.v1#binding)
89
+ # for a listing of values and patterns for members.
90
+ #
91
+ # @param [String] role_name A Cloud IAM role, such as
92
+ # `"roles/pubsub.admin"`.
93
+ # @param [String] member A Cloud IAM identity, such as
94
+ # `"user:owner@example.com"`.
95
+ #
96
+ # @example
97
+ # require "google/cloud"
98
+ #
99
+ # gcloud = Google::Cloud.new
100
+ # pubsub = gcloud.pubsub
101
+ # topic = pubsub.topic "my-topic"
102
+ #
103
+ # policy = topic.policy # API call
104
+ #
105
+ # policy.add "roles/owner", "user:newowner@example.com" # Local call
106
+ #
107
+ # topic.policy = policy # API call
108
+ #
109
+ def add role_name, member
110
+ role(role_name) << member
111
+ end
112
+
113
+ ##
114
+ # Convenience method for removing a member from a binding on this
115
+ # policy. See [Understanding
116
+ # Roles](https://cloud.google.com/iam/docs/understanding-roles) for a
117
+ # listing of primitive and curated roles. See
118
+ # [Binding](https://cloud.google.com/pubsub/reference/rpc/google.iam.v1#binding)
119
+ # for a listing of values and patterns for members.
120
+ #
121
+ # @param [String] role_name A Cloud IAM role, such as
122
+ # `"roles/pubsub.admin"`.
123
+ # @param [String] member A Cloud IAM identity, such as
124
+ # `"user:owner@example.com"`.
125
+ #
126
+ # @example
127
+ # require "google/cloud"
128
+ #
129
+ # gcloud = Google::Cloud.new
130
+ # pubsub = gcloud.pubsub
131
+ # topic = pubsub.topic "my-topic"
132
+ #
133
+ # policy = topic.policy # API call
134
+ #
135
+ # policy.remove "roles/owner", "user:owner@example.com" # Local call
136
+ #
137
+ # topic.policy = policy # API call
138
+ #
139
+ def remove role_name, member
140
+ role(role_name).delete member
141
+ end
142
+
143
+ ##
144
+ # Convenience method returning the array of members bound to a role in
145
+ # this policy, or an empty array if no value is present for the role in
146
+ # {#roles}. See [Understanding
147
+ # Roles](https://cloud.google.com/iam/docs/understanding-roles) for a
148
+ # listing of primitive and curated roles. See
149
+ # [Binding](https://cloud.google.com/pubsub/reference/rpc/google.iam.v1#binding)
150
+ # for a listing of values and patterns for members.
151
+ #
152
+ # @return [Array<String>] The members strings, or an empty array.
153
+ #
154
+ # @example
155
+ # require "google/cloud"
156
+ #
157
+ # gcloud = Google::Cloud.new
158
+ # pubsub = gcloud.pubsub
159
+ # topic = pubsub.topic "my-topic"
160
+ #
161
+ # policy = topic.policy
162
+ #
163
+ # policy.role("roles/viewer") << "user:viewer@example.com"
164
+ #
165
+ def role role_name
166
+ roles[role_name] ||= []
167
+ end
168
+
169
+ ##
170
+ # Returns a deep copy of the policy.
171
+ #
172
+ # @return [Policy]
173
+ #
174
+ def deep_dup
175
+ dup.tap do |p|
176
+ roles_dup = p.roles.each_with_object({}) do |(k, v), memo|
177
+ memo[k] = v.dup rescue value
178
+ end
179
+ p.instance_variable_set "@roles", roles_dup
180
+ end
181
+ end
182
+
183
+ ##
184
+ # @private Convert the Policy to a Google::Iam::V1::Policy object.
185
+ def to_grpc
186
+ Google::Iam::V1::Policy.new(
187
+ etag: etag,
188
+ bindings: roles.keys.map do |role_name|
189
+ next if roles[role_name].empty?
190
+ Google::Iam::V1::Binding.new(
191
+ role: role_name,
192
+ members: roles[role_name]
193
+ )
194
+ end
195
+ )
196
+ end
197
+
198
+ ##
199
+ # @private New Policy from a Google::Iam::V1::Policy object.
200
+ def self.from_grpc grpc
201
+ roles = grpc.bindings.each_with_object({}) do |binding, memo|
202
+ memo[binding.role] = binding.members.to_a
203
+ end
204
+ new grpc.etag, roles
205
+ end
206
+ end
207
+ end
208
+ end
209
+ end
@@ -0,0 +1,487 @@
1
+ # Copyright 2015 Google Inc. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ require "google/cloud/errors"
17
+ require "google/cloud/core/gce"
18
+ require "google/cloud/pubsub/service"
19
+ require "google/cloud/pubsub/credentials"
20
+ require "google/cloud/pubsub/topic"
21
+
22
+ module Google
23
+ module Cloud
24
+ module Pubsub
25
+ ##
26
+ # # Project
27
+ #
28
+ # Represents the project that pubsub messages are pushed to and pulled
29
+ # from. {Topic} is a named resource to which messages are sent by
30
+ # publishers. {Subscription} is a named resource representing the stream
31
+ # of messages from a single, specific topic, to be delivered to the
32
+ # subscribing application. {Message} is a combination of data and
33
+ # attributes that a publisher sends to a topic and is eventually delivered
34
+ # to subscribers.
35
+ #
36
+ # See {Google::Cloud#pubsub}
37
+ #
38
+ # @example
39
+ # require "google/cloud"
40
+ #
41
+ # gcloud = Google::Cloud.new
42
+ # pubsub = gcloud.pubsub
43
+ #
44
+ # topic = pubsub.topic "my-topic"
45
+ # topic.publish "task completed"
46
+ #
47
+ class Project
48
+ ##
49
+ # @private The gRPC Service object.
50
+ attr_accessor :service
51
+
52
+ ##
53
+ # @private Creates a new Pub/Sub Project instance.
54
+ def initialize service
55
+ @service = service
56
+ end
57
+
58
+ # The Pub/Sub project connected to.
59
+ #
60
+ # @example
61
+ # require "google/cloud"
62
+ #
63
+ # gcloud = Google::Cloud.new "my-todo-project",
64
+ # "/path/to/keyfile.json"
65
+ # pubsub = gcloud.pubsub
66
+ #
67
+ # pubsub.project #=> "my-todo-project"
68
+ #
69
+ def project
70
+ service.project
71
+ end
72
+
73
+ ##
74
+ # @private Default project.
75
+ def self.default_project
76
+ ENV["PUBSUB_PROJECT"] ||
77
+ ENV["GOOGLE_CLOUD_PROJECT"] ||
78
+ ENV["GCLOUD_PROJECT"] ||
79
+ Google::Cloud::Core::GCE.project_id
80
+ end
81
+
82
+ ##
83
+ # Retrieves topic by name.
84
+ #
85
+ # The topic will be created if the topic does not exist and the
86
+ # `autocreate` option is set to true.
87
+ #
88
+ # @param [String] topic_name Name of a topic.
89
+ # @param [Boolean] autocreate Flag to control whether the requested
90
+ # topic will be created if it does not exist. Ignored if `skip_lookup`
91
+ # is `true`. The default value is `false`.
92
+ # @param [String] project If the topic belongs to a project other than
93
+ # the one currently connected to, the alternate project ID can be
94
+ # specified here.
95
+ # @param [Boolean] skip_lookup Optionally create a {Topic} object
96
+ # without verifying the topic resource exists on the Pub/Sub service.
97
+ # Calls made on this object will raise errors if the topic resource
98
+ # does not exist. Default is `false`.
99
+ #
100
+ # @return [Google::Cloud::Pubsub::Topic, nil] Returns `nil` if topic
101
+ # does not exist. Will return a newly created{
102
+ # Google::Cloud::Pubsub::Topic} if the topic does not exist and
103
+ # `autocreate` is set to `true`.
104
+ #
105
+ # @example
106
+ # require "google/cloud"
107
+ #
108
+ # gcloud = Google::Cloud.new
109
+ # pubsub = gcloud.pubsub
110
+ # topic = pubsub.topic "existing-topic"
111
+ #
112
+ # @example By default `nil` will be returned if topic does not exist.
113
+ # require "google/cloud"
114
+ #
115
+ # gcloud = Google::Cloud.new
116
+ # pubsub = gcloud.pubsub
117
+ # topic = pubsub.topic "non-existing-topic" #=> nil
118
+ #
119
+ # @example With the `autocreate` option set to `true`.
120
+ # require "google/cloud"
121
+ #
122
+ # gcloud = Google::Cloud.new
123
+ # pubsub = gcloud.pubsub
124
+ # topic = pubsub.topic "non-existing-topic", autocreate: true
125
+ #
126
+ # @example Create topic in a different project with the `project` flag.
127
+ # require "google/cloud"
128
+ #
129
+ # gcloud = Google::Cloud.new
130
+ # pubsub = gcloud.pubsub
131
+ # topic = pubsub.topic "another-topic", project: "another-project"
132
+ #
133
+ # @example Skip the lookup against the service with `skip_lookup`:
134
+ # require "google/cloud"
135
+ #
136
+ # gcloud = Google::Cloud.new
137
+ # pubsub = gcloud.pubsub
138
+ # topic = pubsub.topic "another-topic", skip_lookup: true
139
+ #
140
+ def topic topic_name, autocreate: nil, project: nil, skip_lookup: nil
141
+ ensure_service!
142
+ options = { project: project }
143
+ return Topic.new_lazy(topic_name, service, options) if skip_lookup
144
+ grpc = service.get_topic topic_name
145
+ Topic.from_grpc grpc, service
146
+ rescue Google::Cloud::NotFoundError
147
+ return create_topic(topic_name) if autocreate
148
+ nil
149
+ end
150
+ alias_method :get_topic, :topic
151
+ alias_method :find_topic, :topic
152
+
153
+ ##
154
+ # Creates a new topic.
155
+ #
156
+ # @param [String] topic_name Name of a topic.
157
+ #
158
+ # @return [Google::Cloud::Pubsub::Topic]
159
+ #
160
+ # @example
161
+ # require "google/cloud"
162
+ #
163
+ # gcloud = Google::Cloud.new
164
+ # pubsub = gcloud.pubsub
165
+ # topic = pubsub.create_topic "my-topic"
166
+ #
167
+ def create_topic topic_name
168
+ ensure_service!
169
+ grpc = service.create_topic topic_name
170
+ Topic.from_grpc grpc, service
171
+ end
172
+ alias_method :new_topic, :create_topic
173
+
174
+ ##
175
+ # Retrieves a list of topics for the given project.
176
+ #
177
+ # @param [String] token The `token` value returned by the last call to
178
+ # `topics`; indicates that this is a continuation of a call, and that
179
+ # the system should return the next page of data.
180
+ # @param [Integer] max Maximum number of topics to return.
181
+ #
182
+ # @return [Array<Google::Cloud::Pubsub::Topic>] (See
183
+ # {Google::Cloud::Pubsub::Topic::List})
184
+ #
185
+ # @example
186
+ # require "google/cloud"
187
+ #
188
+ # gcloud = Google::Cloud.new
189
+ # pubsub = gcloud.pubsub
190
+ #
191
+ # topics = pubsub.topics
192
+ # topics.each do |topic|
193
+ # puts topic.name
194
+ # end
195
+ #
196
+ # @example Retrieve all topics: (See {Topic::List#all})
197
+ # require "google/cloud"
198
+ #
199
+ # gcloud = Google::Cloud.new
200
+ # pubsub = gcloud.pubsub
201
+ #
202
+ # topics = pubsub.topics
203
+ # topics.all do |topic|
204
+ # puts topic.name
205
+ # end
206
+ #
207
+ def topics token: nil, max: nil
208
+ ensure_service!
209
+ options = { token: token, max: max }
210
+ grpc = service.list_topics options
211
+ Topic::List.from_grpc grpc, service, max
212
+ end
213
+ alias_method :find_topics, :topics
214
+ alias_method :list_topics, :topics
215
+
216
+ ##
217
+ # Publishes one or more messages to the given topic. The topic will be
218
+ # created if the topic does previously not exist and the `autocreate`
219
+ # option is provided.
220
+ #
221
+ # A note about auto-creating the topic: Any message published to a topic
222
+ # without a subscription will be lost.
223
+ #
224
+ # @param [String] topic_name Name of a topic.
225
+ # @param [String, File] data The message data.
226
+ # @param [Hash] attributes Optional attributes for the message.
227
+ # @option attributes [Boolean] :autocreate Flag to control whether the
228
+ # provided topic will be created if it does not exist.
229
+ # @yield [publisher] a block for publishing multiple messages in one
230
+ # request
231
+ # @yieldparam [Topic::Publisher] publisher the topic publisher object
232
+ #
233
+ # @return [Message, Array<Message>] Returns the published message when
234
+ # called without a block, or an array of messages when called with a
235
+ # block.
236
+ #
237
+ # @example
238
+ # require "google/cloud"
239
+ #
240
+ # gcloud = Google::Cloud.new
241
+ # pubsub = gcloud.pubsub
242
+ #
243
+ # msg = pubsub.publish "my-topic", "new-message"
244
+ #
245
+ # @example A message can be published using a File object:
246
+ # require "google/cloud"
247
+ #
248
+ # gcloud = Google::Cloud.new
249
+ # pubsub = gcloud.pubsub
250
+ #
251
+ # msg = pubsub.publish "my-topic", File.open("message.txt")
252
+ #
253
+ # @example Additionally, a message can be published with attributes:
254
+ # require "google/cloud"
255
+ #
256
+ # gcloud = Google::Cloud.new
257
+ # pubsub = gcloud.pubsub
258
+ #
259
+ # msg = pubsub.publish "my-topic", "new-message", foo: :bar,
260
+ # this: :that
261
+ #
262
+ # @example Multiple messages can be sent at the same time using a block:
263
+ # require "google/cloud"
264
+ #
265
+ # gcloud = Google::Cloud.new
266
+ # pubsub = gcloud.pubsub
267
+ #
268
+ # msgs = pubsub.publish "my-topic" do |p|
269
+ # p.publish "new-message-1", foo: :bar
270
+ # p.publish "new-message-2", foo: :baz
271
+ # p.publish "new-message-3", foo: :bif
272
+ # end
273
+ #
274
+ # @example With `autocreate`:
275
+ # require "google/cloud"
276
+ #
277
+ # gcloud = Google::Cloud.new
278
+ # pubsub = gcloud.pubsub
279
+ #
280
+ # msg = pubsub.publish "new-topic", "new-message", autocreate: true
281
+ #
282
+ def publish topic_name, data = nil, attributes = {}
283
+ # Fix parameters
284
+ if data.is_a?(::Hash) && attributes.empty?
285
+ attributes = data
286
+ data = nil
287
+ end
288
+ # extract autocreate option
289
+ autocreate = attributes.delete :autocreate
290
+ ensure_service!
291
+ publisher = Topic::Publisher.new data, attributes
292
+ yield publisher if block_given?
293
+ return nil if publisher.messages.count.zero?
294
+ publish_batch_messages topic_name, publisher, autocreate
295
+ end
296
+
297
+ ##
298
+ # Creates a new {Subscription} object for the provided topic. The topic
299
+ # will be created if the topic does previously not exist and the
300
+ # `autocreate` option is provided.
301
+ #
302
+ # @param [String] topic_name Name of a topic.
303
+ # @param [String] subscription_name Name of the new subscription. Must
304
+ # start with a letter, and contain only letters ([A-Za-z]), numbers
305
+ # ([0-9], dashes (-), underscores (_), periods (.), tildes (~), plus
306
+ # (+) or percent signs (%). It must be between 3 and 255 characters in
307
+ # length, and it must not start with "goog".
308
+ # @param [Integer] deadline The maximum number of seconds after a
309
+ # subscriber receives a message before the subscriber should
310
+ # acknowledge the message.
311
+ # @param [String] endpoint A URL locating the endpoint to which messages
312
+ # should be pushed.
313
+ # @param [String] autocreate Flag to control whether the topic will be
314
+ # created if it does not exist.
315
+ #
316
+ # @return [Google::Cloud::Pubsub::Subscription]
317
+ #
318
+ # @example
319
+ # require "google/cloud"
320
+ #
321
+ # gcloud = Google::Cloud.new
322
+ # pubsub = gcloud.pubsub
323
+ #
324
+ # sub = pubsub.subscribe "my-topic", "my-topic-sub"
325
+ # puts sub.name # => "my-topic-sub"
326
+ #
327
+ # @example The name is optional, and will be generated if not given.
328
+ # require "google/cloud"
329
+ #
330
+ # gcloud = Google::Cloud.new
331
+ # pubsub = gcloud.pubsub
332
+ #
333
+ # sub = pubsub.subscribe "my-topic"
334
+ # puts sub.name # => "generated-sub-name"
335
+ #
336
+ # @example Wait 2 minutes for acknowledgement and push all to endpoint:
337
+ # require "google/cloud"
338
+ #
339
+ # gcloud = Google::Cloud.new
340
+ # pubsub = gcloud.pubsub
341
+ #
342
+ # sub = pubsub.subscribe "my-topic", "my-topic-sub",
343
+ # deadline: 120,
344
+ # endpoint: "https://example.com/push"
345
+ #
346
+ # @example With `autocreate`:
347
+ # require "google/cloud"
348
+ #
349
+ # gcloud = Google::Cloud.new
350
+ # pubsub = gcloud.pubsub
351
+ #
352
+ # sub = pubsub.subscribe "new-topic", "new-topic-sub",
353
+ # autocreate: true
354
+ #
355
+ def subscribe topic_name, subscription_name, deadline: nil,
356
+ endpoint: nil, autocreate: nil
357
+ ensure_service!
358
+ options = { deadline: deadline, endpoint: endpoint }
359
+ grpc = service.create_subscription topic_name,
360
+ subscription_name, options
361
+ Subscription.from_grpc grpc, service
362
+ rescue Google::Cloud::NotFoundError => e
363
+ if autocreate
364
+ create_topic topic_name
365
+ return subscribe(topic_name, subscription_name,
366
+ deadline: deadline, endpoint: endpoint,
367
+ autocreate: false)
368
+ end
369
+ raise e
370
+ end
371
+ alias_method :create_subscription, :subscribe
372
+ alias_method :new_subscription, :subscribe
373
+
374
+ ##
375
+ # Retrieves subscription by name.
376
+ #
377
+ # @param [String] subscription_name Name of a subscription.
378
+ # @param [String] project If the subscription belongs to a project other
379
+ # than the one currently connected to, the alternate project ID can be
380
+ # specified here.
381
+ # @param [Boolean] skip_lookup Optionally create a {Subscription} object
382
+ # without verifying the subscription resource exists on the Pub/Sub
383
+ # service. Calls made on this object will raise errors if the service
384
+ # resource does not exist. Default is `false`.
385
+ #
386
+ # @return [Google::Cloud::Pubsub::Subscription, nil] Returns `nil` if
387
+ # the subscription does not exist
388
+ #
389
+ # @example
390
+ # require "google/cloud"
391
+ #
392
+ # gcloud = Google::Cloud.new
393
+ # pubsub = gcloud.pubsub
394
+ #
395
+ # subscription = pubsub.subscription "my-sub"
396
+ # puts subscription.name
397
+ #
398
+ # @example Skip the lookup against the service with `skip_lookup`:
399
+ # require "google/cloud"
400
+ #
401
+ # gcloud = Google::Cloud.new
402
+ # pubsub = gcloud.pubsub
403
+ #
404
+ # # No API call is made to retrieve the subscription information.
405
+ # subscription = pubsub.subscription "my-sub", skip_lookup: true
406
+ # puts subscription.name
407
+ #
408
+ def subscription subscription_name, project: nil, skip_lookup: nil
409
+ ensure_service!
410
+ options = { project: project }
411
+ if skip_lookup
412
+ return Subscription.new_lazy subscription_name, service, options
413
+ end
414
+ grpc = service.get_subscription subscription_name
415
+ Subscription.from_grpc grpc, service
416
+ rescue Google::Cloud::NotFoundError
417
+ nil
418
+ end
419
+ alias_method :get_subscription, :subscription
420
+ alias_method :find_subscription, :subscription
421
+
422
+ ##
423
+ # Retrieves a list of subscriptions for the given project.
424
+ #
425
+ # @param [String] token A previously-returned page token representing
426
+ # part of the larger set of results to view.
427
+ # @param [Integer] max Maximum number of subscriptions to return.
428
+ #
429
+ # @return [Array<Google::Cloud::Pubsub::Subscription>] (See
430
+ # {Google::Cloud::Pubsub::Subscription::List})
431
+ #
432
+ # @example
433
+ # require "google/cloud"
434
+ #
435
+ # gcloud = Google::Cloud.new
436
+ # pubsub = gcloud.pubsub
437
+ #
438
+ # subscriptions = pubsub.subscriptions
439
+ # subscriptions.each do |subscription|
440
+ # puts subscription.name
441
+ # end
442
+ #
443
+ # @example Retrieve all subscriptions: (See {Subscription::List#all})
444
+ # require "google/cloud"
445
+ #
446
+ # gcloud = Google::Cloud.new
447
+ # pubsub = gcloud.pubsub
448
+ #
449
+ # subscriptions = pubsub.subscriptions
450
+ # subscriptions.all do |subscription|
451
+ # puts subscription.name
452
+ # end
453
+ #
454
+ def subscriptions token: nil, max: nil
455
+ ensure_service!
456
+ options = { token: token, max: max }
457
+ grpc = service.list_subscriptions options
458
+ Subscription::List.from_grpc grpc, service, max
459
+ end
460
+ alias_method :find_subscriptions, :subscriptions
461
+ alias_method :list_subscriptions, :subscriptions
462
+
463
+ protected
464
+
465
+ ##
466
+ # @private Raise an error unless an active connection to the service is
467
+ # available.
468
+ def ensure_service!
469
+ fail "Must have active connection to service" unless service
470
+ end
471
+
472
+ ##
473
+ # Call the publish API with arrays of data data and attrs.
474
+ def publish_batch_messages topic_name, batch, autocreate = false
475
+ grpc = service.publish topic_name, batch.messages
476
+ batch.to_gcloud_messages Array(grpc.message_ids)
477
+ rescue Google::Cloud::NotFoundError => e
478
+ if autocreate
479
+ create_topic topic_name
480
+ return publish_batch_messages topic_name, batch, false
481
+ end
482
+ raise e
483
+ end
484
+ end
485
+ end
486
+ end
487
+ end