google-cloud-pubsub 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,210 @@
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 "delegate"
17
+
18
+ module Google
19
+ module Cloud
20
+ module Pubsub
21
+ class Subscription
22
+ ##
23
+ # Subscription::List is a special case Array with additional values.
24
+ class List < DelegateClass(::Array)
25
+ ##
26
+ # If not empty, indicates that there are more subscriptions
27
+ # that match the request and this value should be passed to
28
+ # the next {Google::Cloud::Pubsub::Topic#subscriptions} to continue.
29
+ attr_accessor :token
30
+
31
+ ##
32
+ # @private Create a new Subscription::List with an array of values.
33
+ def initialize arr = []
34
+ @topic = nil
35
+ @prefix = nil
36
+ @token = nil
37
+ @max = nil
38
+ super arr
39
+ end
40
+
41
+ ##
42
+ # Whether there a next page of subscriptions.
43
+ #
44
+ # @return [Boolean]
45
+ #
46
+ # @example
47
+ # require "google/cloud"
48
+ #
49
+ # gcloud = Google::Cloud.new
50
+ # pubsub = gcloud.pubsub
51
+ #
52
+ # subscriptions = pubsub.subscriptions
53
+ # if subscriptions.next?
54
+ # next_subscriptions = subscriptions.next
55
+ # end
56
+ #
57
+ def next?
58
+ !token.nil?
59
+ end
60
+
61
+ ##
62
+ # Retrieve the next page of subscriptions.
63
+ #
64
+ # @return [Subscription::List]
65
+ #
66
+ # @example
67
+ # require "google/cloud"
68
+ #
69
+ # gcloud = Google::Cloud.new
70
+ # pubsub = gcloud.pubsub
71
+ #
72
+ # subscriptions = pubsub.subscriptions
73
+ # if subscriptions.next?
74
+ # next_subscriptions = subscriptions.next
75
+ # end
76
+ #
77
+ def next
78
+ return nil unless next?
79
+ ensure_service!
80
+ if @topic
81
+ next_topic_subscriptions
82
+ else
83
+ next_subscriptions
84
+ end
85
+ end
86
+
87
+ ##
88
+ # Retrieves all subscriptions by repeatedly loading {#next} until
89
+ # {#next?} returns `false`. Calls the given block once for each
90
+ # subscription, which is passed as the parameter.
91
+ #
92
+ # An Enumerator is returned if no block is given.
93
+ #
94
+ # This method may make several API calls until all subscriptions are
95
+ # retrieved. Be sure to use as narrow a search criteria as possible.
96
+ # Please use with caution.
97
+ #
98
+ # @param [Integer] request_limit The upper limit of API requests to
99
+ # make to load all subscriptions. Default is no limit.
100
+ # @yield [subscription] The block for accessing each subscription.
101
+ # @yieldparam [Subscription] subscription The subscription object.
102
+ #
103
+ # @return [Enumerator]
104
+ #
105
+ # @example Iterating each subscription by passing a block:
106
+ # require "google/cloud"
107
+ #
108
+ # gcloud = Google::Cloud.new
109
+ # pubsub = gcloud.pubsub
110
+ #
111
+ # subscriptions = pubsub.subscriptions
112
+ # subscriptions.all do |subscription|
113
+ # puts subscription.name
114
+ # end
115
+ #
116
+ # @example Using the enumerator by not passing a block:
117
+ # require "google/cloud"
118
+ #
119
+ # gcloud = Google::Cloud.new
120
+ # pubsub = gcloud.pubsub
121
+ #
122
+ # subscriptions = pubsub.subscriptions
123
+ # all_names = subscriptions.all.map do |subscription|
124
+ # subscription.name
125
+ # end
126
+ #
127
+ # @example Limit the number of API calls made:
128
+ # require "google/cloud"
129
+ #
130
+ # gcloud = Google::Cloud.new
131
+ # pubsub = gcloud.pubsub
132
+ #
133
+ # subscriptions = pubsub.subscriptions
134
+ # subscriptions.all(request_limit: 10) do |subscription|
135
+ # puts subscription.name
136
+ # end
137
+ #
138
+ def all request_limit: nil
139
+ request_limit = request_limit.to_i if request_limit
140
+ unless block_given?
141
+ return enum_for(:all, request_limit: request_limit)
142
+ end
143
+ results = self
144
+ loop do
145
+ results.each { |r| yield r }
146
+ if request_limit
147
+ request_limit -= 1
148
+ break if request_limit < 0
149
+ end
150
+ break unless results.next?
151
+ results = results.next
152
+ end
153
+ end
154
+
155
+ ##
156
+ # @private New Subscriptions::List from a
157
+ # Google::Pubsub::V1::ListSubscriptionsRequest object.
158
+ def self.from_grpc grpc_list, service, max = nil
159
+ subs = new(Array(grpc_list.subscriptions).map do |grpc|
160
+ Subscription.from_grpc grpc, service
161
+ end)
162
+ token = grpc_list.next_page_token
163
+ token = nil if token == ""
164
+ subs.instance_variable_set "@token", token
165
+ subs.instance_variable_set "@service", service
166
+ subs.instance_variable_set "@max", max
167
+ subs
168
+ end
169
+
170
+ ##
171
+ # @private New Subscriptions::List from a
172
+ # Google::Pubsub::V1::ListTopicSubscriptionsResponse object.
173
+ def self.from_topic_grpc grpc_list, service, topic, max = nil
174
+ subs = new(Array(grpc_list.subscriptions).map do |grpc|
175
+ Subscription.new_lazy grpc, service
176
+ end)
177
+ token = grpc_list.next_page_token
178
+ token = nil if token == ""
179
+ subs.instance_variable_set "@token", token
180
+ subs.instance_variable_set "@service", service
181
+ subs.instance_variable_set "@topic", topic
182
+ subs.instance_variable_set "@max", max
183
+ subs
184
+ end
185
+
186
+ protected
187
+
188
+ ##
189
+ # @private Raise an error unless an active connection to the service
190
+ # is available.
191
+ def ensure_service!
192
+ fail "Must have active connection to service" unless @service
193
+ end
194
+
195
+ def next_subscriptions
196
+ options = { prefix: @prefix, token: @token, max: @max }
197
+ grpc = @service.list_subscriptions options
198
+ self.class.from_grpc grpc, @service, @max
199
+ end
200
+
201
+ def next_topic_subscriptions
202
+ options = { token: @token, max: @max }
203
+ grpc = @service.list_topics_subscriptions @topic, options
204
+ self.class.from_topic_grpc grpc, @service, @topic, @max
205
+ end
206
+ end
207
+ end
208
+ end
209
+ end
210
+ end
@@ -0,0 +1,515 @@
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/pubsub/topic/publisher"
18
+ require "google/cloud/pubsub/topic/list"
19
+ require "google/cloud/pubsub/subscription"
20
+ require "google/cloud/pubsub/policy"
21
+
22
+ module Google
23
+ module Cloud
24
+ module Pubsub
25
+ ##
26
+ # # Topic
27
+ #
28
+ # A named resource to which messages are published.
29
+ #
30
+ # @example
31
+ # require "google/cloud"
32
+ #
33
+ # gcloud = Google::Cloud.new
34
+ # pubsub = gcloud.pubsub
35
+ #
36
+ # topic = pubsub.topic "my-topic"
37
+ # topic.publish "task completed"
38
+ #
39
+ class Topic
40
+ ##
41
+ # @private The gRPC Service object.
42
+ attr_accessor :service
43
+
44
+ ##
45
+ # @private The gRPC Google::Pubsub::V1::Topic object.
46
+ attr_accessor :grpc
47
+
48
+ ##
49
+ # @private Create an empty {Topic} object.
50
+ def initialize
51
+ @service = nil
52
+ @grpc = Google::Pubsub::V1::Topic.new
53
+ @name = nil
54
+ @exists = nil
55
+ end
56
+
57
+ ##
58
+ # @private New lazy {Topic} object without making an HTTP request.
59
+ def self.new_lazy name, service, options = {}
60
+ new.tap do |t|
61
+ t.grpc = nil
62
+ t.service = service
63
+ t.instance_variable_set "@name", service.topic_path(name, options)
64
+ end
65
+ end
66
+
67
+ ##
68
+ # The name of the topic in the form of
69
+ # "/projects/project-identifier/topics/topic-name".
70
+ def name
71
+ @grpc ? @grpc.name : @name
72
+ end
73
+
74
+ ##
75
+ # Permanently deletes the topic.
76
+ #
77
+ # @return [Boolean] Returns `true` if the topic was deleted.
78
+ #
79
+ # @example
80
+ # require "google/cloud"
81
+ #
82
+ # gcloud = Google::Cloud.new
83
+ # pubsub = gcloud.pubsub
84
+ #
85
+ # topic = pubsub.topic "my-topic"
86
+ # topic.delete
87
+ #
88
+ def delete
89
+ ensure_service!
90
+ service.delete_topic name
91
+ true
92
+ end
93
+
94
+ ##
95
+ # Creates a new {Subscription} object on the current Topic.
96
+ #
97
+ # @param [String] subscription_name Name of the new subscription. Must
98
+ # start with a letter, and contain only letters ([A-Za-z]), numbers
99
+ # ([0-9], dashes (-), underscores (_), periods (.), tildes (~), plus
100
+ # (+) or percent signs (%). It must be between 3 and 255 characters in
101
+ # length, and it must not start with "goog".
102
+ # @param [Integer] deadline The maximum number of seconds after a
103
+ # subscriber receives a message before the subscriber should
104
+ # acknowledge the message.
105
+ # @param [String] endpoint A URL locating the endpoint to which messages
106
+ # should be pushed.
107
+ #
108
+ # @return [Google::Cloud::Pubsub::Subscription]
109
+ #
110
+ # @example
111
+ # require "google/cloud"
112
+ #
113
+ # gcloud = Google::Cloud.new
114
+ # pubsub = gcloud.pubsub
115
+ #
116
+ # topic = pubsub.topic "my-topic"
117
+ # sub = topic.subscribe "my-topic-sub"
118
+ # puts sub.name # => "my-topic-sub"
119
+ #
120
+ # @example The name is optional, and will be generated if not given:
121
+ # require "google/cloud"
122
+ #
123
+ # gcloud = Google::Cloud.new
124
+ # pubsub = gcloud.pubsub
125
+ #
126
+ # topic = pubsub.topic "my-topic"
127
+ # sub = topic.subscribe "my-topic-sub"
128
+ # puts sub.name # => "generated-sub-name"
129
+ #
130
+ # @example Wait 2 minutes for acknowledgement and push all to endpoint:
131
+ # require "google/cloud"
132
+ #
133
+ # gcloud = Google::Cloud.new
134
+ # pubsub = gcloud.pubsub
135
+ #
136
+ # topic = pubsub.topic "my-topic"
137
+ # sub = topic.subscribe "my-topic-sub",
138
+ # deadline: 120,
139
+ # endpoint: "https://example.com/push"
140
+ #
141
+ def subscribe subscription_name, deadline: nil, endpoint: nil
142
+ ensure_service!
143
+ options = { deadline: deadline, endpoint: endpoint }
144
+ grpc = service.create_subscription name, subscription_name, options
145
+ Subscription.from_grpc grpc, service
146
+ end
147
+ alias_method :create_subscription, :subscribe
148
+ alias_method :new_subscription, :subscribe
149
+
150
+ ##
151
+ # Retrieves subscription by name.
152
+ #
153
+ # @param [String] subscription_name Name of a subscription.
154
+ # @param [Boolean] skip_lookup Optionally create a {Subscription} object
155
+ # without verifying the subscription resource exists on the Pub/Sub
156
+ # service. Calls made on this object will raise errors if the service
157
+ # resource does not exist. Default is `false`.
158
+ #
159
+ # @return [Google::Cloud::Pubsub::Subscription, nil] Returns `nil` if
160
+ # the subscription does not exist.
161
+ #
162
+ # @example
163
+ # require "google/cloud"
164
+ #
165
+ # gcloud = Google::Cloud.new
166
+ # pubsub = gcloud.pubsub
167
+ #
168
+ # topic = pubsub.topic "my-topic"
169
+ # subscription = topic.subscription "my-topic-subscription"
170
+ # puts subscription.name
171
+ #
172
+ # @example Skip the lookup against the service with `skip_lookup`:
173
+ # require "google/cloud"
174
+ #
175
+ # gcloud = Google::Cloud.new
176
+ # pubsub = gcloud.pubsub
177
+ #
178
+ # # No API call is made to retrieve the subscription information.
179
+ # subscription = pubsub.subscription "my-sub", skip_lookup: true
180
+ # puts subscription.name
181
+ #
182
+ def subscription subscription_name, skip_lookup: nil
183
+ ensure_service!
184
+ return Subscription.new_lazy subscription_name, service if skip_lookup
185
+ grpc = service.get_subscription subscription_name
186
+ Subscription.from_grpc grpc, service
187
+ rescue Google::Cloud::NotFoundError
188
+ nil
189
+ end
190
+ alias_method :get_subscription, :subscription
191
+ alias_method :find_subscription, :subscription
192
+
193
+ ##
194
+ # Retrieves a list of subscription names for the given project.
195
+ #
196
+ # @param [String] token The `token` value returned by the last call to
197
+ # `subscriptions`; indicates that this is a continuation of a call,
198
+ # and that the system should return the next page of data.
199
+ # @param [Integer] max Maximum number of subscriptions to return.
200
+ #
201
+ # @return [Array<Subscription>] (See {Subscription::List})
202
+ #
203
+ # @example
204
+ # require "google/cloud"
205
+ #
206
+ # gcloud = Google::Cloud.new
207
+ # pubsub = gcloud.pubsub
208
+ #
209
+ # topic = pubsub.topic "my-topic"
210
+ # subscription = topic.subscriptions
211
+ # subscriptions.each do |subscription|
212
+ # puts subscription.name
213
+ # end
214
+ #
215
+ # @example Retrieve all subscriptions: (See {Subscription::List#all})
216
+ # require "google/cloud"
217
+ #
218
+ # gcloud = Google::Cloud.new
219
+ # pubsub = gcloud.pubsub
220
+ #
221
+ # topic = pubsub.topic "my-topic"
222
+ # subscription = topic.subscriptions
223
+ # subscriptions.all do |subscription|
224
+ # puts subscription.name
225
+ # end
226
+ #
227
+ def subscriptions token: nil, max: nil
228
+ ensure_service!
229
+ options = { token: token, max: max }
230
+ grpc = service.list_topics_subscriptions name, options
231
+ Subscription::List.from_topic_grpc grpc, service, name, max
232
+ end
233
+ alias_method :find_subscriptions, :subscriptions
234
+ alias_method :list_subscriptions, :subscriptions
235
+
236
+ ##
237
+ # Publishes one or more messages to the topic.
238
+ #
239
+ # @param [String, File] data The message data.
240
+ # @param [Hash] attributes Optional attributes for the message.
241
+ # @yield [publisher] a block for publishing multiple messages in one
242
+ # request
243
+ # @yieldparam [Topic::Publisher] publisher the topic publisher object
244
+ #
245
+ # @return [Message, Array<Message>] Returns the published message when
246
+ # called without a block, or an array of messages when called with a
247
+ # block.
248
+ #
249
+ # @example
250
+ # require "google/cloud"
251
+ #
252
+ # gcloud = Google::Cloud.new
253
+ # pubsub = gcloud.pubsub
254
+ #
255
+ # topic = pubsub.topic "my-topic"
256
+ # msg = topic.publish "new-message"
257
+ #
258
+ # @example A message can be published using a File object:
259
+ # require "google/cloud"
260
+ #
261
+ # gcloud = Google::Cloud.new
262
+ # pubsub = gcloud.pubsub
263
+ #
264
+ # topic = pubsub.topic "my-topic"
265
+ # msg = topic.publish File.open("message.txt")
266
+ #
267
+ # @example Additionally, a message can be published with attributes:
268
+ # require "google/cloud"
269
+ #
270
+ # gcloud = Google::Cloud.new
271
+ # pubsub = gcloud.pubsub
272
+ #
273
+ # topic = pubsub.topic "my-topic"
274
+ # msg = topic.publish "new-message",
275
+ # foo: :bar,
276
+ # this: :that
277
+ #
278
+ # @example Multiple messages can be sent at the same time using a block:
279
+ # require "google/cloud"
280
+ #
281
+ # gcloud = Google::Cloud.new
282
+ # pubsub = gcloud.pubsub
283
+ #
284
+ # topic = pubsub.topic "my-topic"
285
+ # msgs = topic.publish do |t|
286
+ # t.publish "new-message-1", foo: :bar
287
+ # t.publish "new-message-2", foo: :baz
288
+ # t.publish "new-message-3", foo: :bif
289
+ # end
290
+ #
291
+ def publish data = nil, attributes = {}
292
+ ensure_service!
293
+ publisher = Publisher.new data, attributes
294
+ yield publisher if block_given?
295
+ return nil if publisher.messages.count.zero?
296
+ publish_batch_messages publisher
297
+ end
298
+
299
+ ##
300
+ # Gets the [Cloud IAM](https://cloud.google.com/iam/) access control
301
+ # policy for this topic.
302
+ #
303
+ # @see https://cloud.google.com/pubsub/reference/rpc/google.iam.v1#iampolicy
304
+ # google.iam.v1.IAMPolicy
305
+ #
306
+ # @param [Boolean] force Force the latest policy to be retrieved from
307
+ # the Pub/Sub service when `true`. Otherwise the policy will be
308
+ # memoized to reduce the number of API calls made to the Pub/Sub
309
+ # service. The default is `false`.
310
+ #
311
+ # @yield [policy] A block for updating the policy. The latest policy
312
+ # will be read from the Pub/Sub service and passed to the block. After
313
+ # the block completes, the modified policy will be written to the
314
+ # service.
315
+ # @yieldparam [Policy] policy the current Cloud IAM Policy for this
316
+ # topic
317
+ #
318
+ # @return [Policy] the current Cloud IAM Policy for this topic
319
+ #
320
+ # @example Policy values are memoized to reduce the number of API calls:
321
+ # require "google/cloud"
322
+ #
323
+ # gcloud = Google::Cloud.new
324
+ # pubsub = gcloud.pubsub
325
+ # topic = pubsub.topic "my-topic"
326
+ #
327
+ # policy = topic.policy # API call
328
+ # policy_2 = topic.policy # No API call
329
+ #
330
+ # @example Use `force` to retrieve the latest policy from the service:
331
+ # require "google/cloud"
332
+ #
333
+ # gcloud = Google::Cloud.new
334
+ # pubsub = gcloud.pubsub
335
+ # topic = pubsub.topic "my-topic"
336
+ #
337
+ # policy = topic.policy force: true # API call
338
+ # policy_2 = topic.policy force: true # API call
339
+ #
340
+ # @example Update the policy by passing a block:
341
+ # require "google/cloud"
342
+ #
343
+ # gcloud = Google::Cloud.new
344
+ # pubsub = gcloud.pubsub
345
+ # topic = pubsub.topic "my-topic"
346
+ #
347
+ # policy = topic.policy do |p|
348
+ # p.add "roles/owner", "user:owner@example.com"
349
+ # end # 2 API calls
350
+ #
351
+ def policy force: nil
352
+ @policy = nil if force || block_given?
353
+ @policy ||= begin
354
+ ensure_service!
355
+ grpc = service.get_topic_policy name
356
+ Policy.from_grpc grpc
357
+ end
358
+ return @policy unless block_given?
359
+ p = @policy.deep_dup
360
+ yield p
361
+ self.policy = p
362
+ end
363
+
364
+ ##
365
+ # Updates the [Cloud IAM](https://cloud.google.com/iam/) access control
366
+ # policy for this topic. The policy should be read from {#policy}. See
367
+ # {Google::Cloud::Pubsub::Policy} for an explanation of the policy
368
+ # `etag` property and how to modify policies.
369
+ #
370
+ # You can also update the policy by passing a block to {#policy}, which
371
+ # will call this method internally after the block completes.
372
+ #
373
+ # @see https://cloud.google.com/pubsub/reference/rpc/google.iam.v1#iampolicy
374
+ # google.iam.v1.IAMPolicy
375
+ #
376
+ # @param [Policy] new_policy a new or modified Cloud IAM Policy for this
377
+ # topic
378
+ #
379
+ # @example
380
+ # require "google/cloud"
381
+ #
382
+ # gcloud = Google::Cloud.new
383
+ # pubsub = gcloud.pubsub
384
+ # topic = pubsub.topic "my-topic"
385
+ #
386
+ # policy = topic.policy # API call
387
+ #
388
+ # policy.add "roles/owner", "user:owner@example.com"
389
+ #
390
+ # topic.policy = policy # API call
391
+ #
392
+ def policy= new_policy
393
+ ensure_service!
394
+ grpc = service.set_topic_policy name, new_policy.to_grpc
395
+ @policy = Policy.from_grpc grpc
396
+ end
397
+
398
+ ##
399
+ # Tests the specified permissions against the [Cloud
400
+ # IAM](https://cloud.google.com/iam/) access control policy.
401
+ #
402
+ # @see https://cloud.google.com/iam/docs/managing-policies Managing
403
+ # Policies
404
+ #
405
+ # @param [String, Array<String>] permissions The set of permissions to
406
+ # check access for. Permissions with wildcards (such as `*` or
407
+ # `storage.*`) are not allowed.
408
+ #
409
+ # The permissions that can be checked on a topic are:
410
+ #
411
+ # * pubsub.topics.publish
412
+ # * pubsub.topics.attachSubscription
413
+ # * pubsub.topics.get
414
+ # * pubsub.topics.delete
415
+ # * pubsub.topics.update
416
+ # * pubsub.topics.getIamPolicy
417
+ # * pubsub.topics.setIamPolicy
418
+ #
419
+ # @return [Array<Strings>] The permissions that have access.
420
+ #
421
+ # @example
422
+ # require "google/cloud"
423
+ #
424
+ # gcloud = Google::Cloud.new
425
+ # pubsub = gcloud.pubsub
426
+ # topic = pubsub.topic "my-topic"
427
+ # perms = topic.test_permissions "pubsub.topics.get",
428
+ # "pubsub.topics.publish"
429
+ # perms.include? "pubsub.topics.get" #=> true
430
+ # perms.include? "pubsub.topics.publish" #=> false
431
+ #
432
+ def test_permissions *permissions
433
+ permissions = Array(permissions).flatten
434
+ permissions = Array(permissions).flatten
435
+ ensure_service!
436
+ grpc = service.test_topic_permissions name, permissions
437
+ grpc.permissions
438
+ end
439
+
440
+ ##
441
+ # Determines whether the topic exists in the Pub/Sub service.
442
+ #
443
+ # @example
444
+ # require "google/cloud"
445
+ #
446
+ # gcloud = Google::Cloud.new
447
+ # pubsub = gcloud.pubsub
448
+ #
449
+ # topic = pubsub.topic "my-topic"
450
+ # topic.exists? #=> true
451
+ #
452
+ def exists?
453
+ # Always true if we have a grpc object
454
+ return true unless @grpc.nil?
455
+ # If we have a value, return it
456
+ return @exists unless @exists.nil?
457
+ ensure_grpc!
458
+ @exists = !@grpc.nil?
459
+ end
460
+
461
+ ##
462
+ # @private
463
+ # Determines whether the topic object was created with an HTTP call.
464
+ #
465
+ # @example
466
+ # require "google/cloud"
467
+ #
468
+ # gcloud = Google::Cloud.new
469
+ # pubsub = gcloud.pubsub
470
+ #
471
+ # topic = pubsub.topic "my-topic"
472
+ # topic.lazy? #=> false
473
+ #
474
+ def lazy?
475
+ @grpc.nil?
476
+ end
477
+
478
+ ##
479
+ # @private New Topic from a Google::Pubsub::V1::Topic object.
480
+ def self.from_grpc grpc, service
481
+ new.tap do |f|
482
+ f.grpc = grpc
483
+ f.service = service
484
+ end
485
+ end
486
+
487
+ protected
488
+
489
+ ##
490
+ # @private Raise an error unless an active connection to the service is
491
+ # available.
492
+ def ensure_service!
493
+ fail "Must have active connection to service" unless service
494
+ end
495
+
496
+ ##
497
+ # Ensures a Google::Pubsub::V1::Topic object exists.
498
+ def ensure_grpc!
499
+ ensure_service!
500
+ return @grpc if @grpc
501
+ @grpc = service.get_topic @name
502
+ rescue Google::Cloud::NotFoundError
503
+ nil
504
+ end
505
+
506
+ ##
507
+ # Call the publish API with arrays of data data and attrs.
508
+ def publish_batch_messages batch
509
+ grpc = service.publish name, batch.messages
510
+ batch.to_gcloud_messages Array(grpc.message_ids)
511
+ end
512
+ end
513
+ end
514
+ end
515
+ end