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,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