google-cloud-pubsub 0.20.0 → 2.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +5 -5
  2. data/.yardopts +18 -0
  3. data/AUTHENTICATION.md +178 -0
  4. data/CHANGELOG.md +659 -0
  5. data/CODE_OF_CONDUCT.md +40 -0
  6. data/CONTRIBUTING.md +187 -0
  7. data/EMULATOR.md +37 -0
  8. data/LICENSE +201 -0
  9. data/LOGGING.md +32 -0
  10. data/OVERVIEW.md +528 -0
  11. data/TROUBLESHOOTING.md +31 -0
  12. data/lib/google/cloud/pubsub/async_publisher/batch.rb +310 -0
  13. data/lib/google/cloud/pubsub/async_publisher.rb +402 -0
  14. data/lib/google/cloud/pubsub/batch_publisher.rb +100 -0
  15. data/lib/google/cloud/pubsub/convert.rb +91 -0
  16. data/lib/google/cloud/pubsub/credentials.rb +26 -10
  17. data/lib/google/cloud/pubsub/errors.rb +85 -0
  18. data/lib/google/cloud/pubsub/message.rb +82 -20
  19. data/lib/google/cloud/pubsub/policy.rb +40 -61
  20. data/lib/google/cloud/pubsub/project.rb +405 -265
  21. data/lib/google/cloud/pubsub/publish_result.rb +103 -0
  22. data/lib/google/cloud/pubsub/received_message.rb +165 -30
  23. data/lib/google/cloud/pubsub/retry_policy.rb +88 -0
  24. data/lib/google/cloud/pubsub/schema/list.rb +180 -0
  25. data/lib/google/cloud/pubsub/schema.rb +310 -0
  26. data/lib/google/cloud/pubsub/service.rb +304 -162
  27. data/lib/google/cloud/pubsub/snapshot/list.rb +178 -0
  28. data/lib/google/cloud/pubsub/snapshot.rb +205 -0
  29. data/lib/google/cloud/pubsub/subscriber/enumerator_queue.rb +54 -0
  30. data/lib/google/cloud/pubsub/subscriber/inventory.rb +173 -0
  31. data/lib/google/cloud/pubsub/subscriber/sequencer.rb +115 -0
  32. data/lib/google/cloud/pubsub/subscriber/stream.rb +400 -0
  33. data/lib/google/cloud/pubsub/subscriber/timed_unary_buffer.rb +230 -0
  34. data/lib/google/cloud/pubsub/subscriber.rb +417 -0
  35. data/lib/google/cloud/pubsub/subscription/list.rb +38 -43
  36. data/lib/google/cloud/pubsub/subscription/push_config.rb +268 -0
  37. data/lib/google/cloud/pubsub/subscription.rb +1040 -210
  38. data/lib/google/cloud/pubsub/topic/list.rb +32 -37
  39. data/lib/google/cloud/pubsub/topic.rb +726 -177
  40. data/lib/google/cloud/pubsub/version.rb +6 -4
  41. data/lib/google/cloud/pubsub.rb +138 -413
  42. data/lib/google-cloud-pubsub.rb +60 -42
  43. metadata +88 -39
  44. data/lib/google/cloud/pubsub/topic/publisher.rb +0 -87
  45. data/lib/google/iam/v1/iam_policy.rb +0 -33
  46. data/lib/google/iam/v1/iam_policy_services.rb +0 -30
  47. data/lib/google/iam/v1/policy.rb +0 -25
  48. data/lib/google/pubsub/v1/pubsub_pb.rb +0 -129
  49. data/lib/google/pubsub/v1/pubsub_services_pb.rb +0 -117
@@ -1,10 +1,10 @@
1
- # Copyright 2015 Google Inc. All rights reserved.
1
+ # Copyright 2015 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
5
5
  # You may obtain a copy of the License at
6
6
  #
7
- # http://www.apache.org/licenses/LICENSE-2.0
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
8
  #
9
9
  # Unless required by applicable law or agreed to in writing, software
10
10
  # distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,7 +17,7 @@ require "delegate"
17
17
 
18
18
  module Google
19
19
  module Cloud
20
- module Pubsub
20
+ module PubSub
21
21
  class Topic
22
22
  ##
23
23
  # Topic::List is a special case Array with additional values.
@@ -25,7 +25,7 @@ module Google
25
25
  ##
26
26
  # If not empty, indicates that there are more topics
27
27
  # that match the request and this value should be passed to
28
- # the next {Google::Cloud::Pubsub::Project#topics} to continue.
28
+ # the next {Google::Cloud::PubSub::Project#topics} to continue.
29
29
  attr_accessor :token
30
30
 
31
31
  ##
@@ -40,10 +40,9 @@ module Google
40
40
  # @return [Boolean]
41
41
  #
42
42
  # @example
43
- # require "google/cloud"
43
+ # require "google/cloud/pubsub"
44
44
  #
45
- # gcloud = Google::Cloud.new
46
- # pubsub = gcloud.pubsub
45
+ # pubsub = Google::Cloud::PubSub.new
47
46
  #
48
47
  # topics = pubsub.topics
49
48
  # if topics.next?
@@ -60,10 +59,9 @@ module Google
60
59
  # @return [Topic::List]
61
60
  #
62
61
  # @example
63
- # require "google/cloud"
62
+ # require "google/cloud/pubsub"
64
63
  #
65
- # gcloud = Google::Cloud.new
66
- # pubsub = gcloud.pubsub
64
+ # pubsub = Google::Cloud::PubSub.new
67
65
  #
68
66
  # topics = pubsub.topics
69
67
  # if topics.next?
@@ -79,15 +77,15 @@ module Google
79
77
  end
80
78
 
81
79
  ##
82
- # Retrieves all topics by repeatedly loading {#next} until {#next?}
83
- # returns `false`. Calls the given block once for each topic, which is
84
- # passed as the parameter.
80
+ # Retrieves remaining results by repeatedly invoking {#next} until
81
+ # {#next?} returns `false`. Calls the given block once for each
82
+ # result, which is passed as the argument to the block.
85
83
  #
86
84
  # An Enumerator is returned if no block is given.
87
85
  #
88
- # This method may make several API calls until all topics are
89
- # retrieved. Be sure to use as narrow a search criteria as possible.
90
- # Please use with caution.
86
+ # This method will make repeated API calls until all remaining results
87
+ # are retrieved. (Unlike `#each`, for example, which merely iterates
88
+ # over the results returned by a single API call.) Use with caution.
91
89
  #
92
90
  # @param [Integer] request_limit The upper limit of API requests to
93
91
  # make to load all topics. Default is no limit.
@@ -97,10 +95,9 @@ module Google
97
95
  # @return [Enumerator]
98
96
  #
99
97
  # @example Iterating each topic by passing a block:
100
- # require "google/cloud"
98
+ # require "google/cloud/pubsub"
101
99
  #
102
- # gcloud = Google::Cloud.new
103
- # pubsub = gcloud.pubsub
100
+ # pubsub = Google::Cloud::PubSub.new
104
101
  #
105
102
  # topics = pubsub.topics
106
103
  # topics.all do |topic|
@@ -108,10 +105,9 @@ module Google
108
105
  # end
109
106
  #
110
107
  # @example Using the enumerator by not passing a block:
111
- # require "google/cloud"
108
+ # require "google/cloud/pubsub"
112
109
  #
113
- # gcloud = Google::Cloud.new
114
- # pubsub = gcloud.pubsub
110
+ # pubsub = Google::Cloud::PubSub.new
115
111
  #
116
112
  # topics = pubsub.topics
117
113
  # all_names = topics.all.map do |topic|
@@ -119,27 +115,24 @@ module Google
119
115
  # end
120
116
  #
121
117
  # @example Limit the number of API calls made:
122
- # require "google/cloud"
118
+ # require "google/cloud/pubsub"
123
119
  #
124
- # gcloud = Google::Cloud.new
125
- # pubsub = gcloud.pubsub
120
+ # pubsub = Google::Cloud::PubSub.new
126
121
  #
127
122
  # topics = pubsub.topics
128
123
  # topics.all(request_limit: 10) do |topic|
129
124
  # puts topic.name
130
125
  # end
131
126
  #
132
- def all request_limit: nil
127
+ def all request_limit: nil, &block
133
128
  request_limit = request_limit.to_i if request_limit
134
- unless block_given?
135
- return enum_for(:all, request_limit: request_limit)
136
- end
129
+ return enum_for :all, request_limit: request_limit unless block_given?
137
130
  results = self
138
131
  loop do
139
- results.each { |r| yield r }
132
+ results.each(&block)
140
133
  if request_limit
141
134
  request_limit -= 1
142
- break if request_limit < 0
135
+ break if request_limit.negative?
143
136
  end
144
137
  break unless results.next?
145
138
  results = results.next
@@ -148,16 +141,16 @@ module Google
148
141
 
149
142
  ##
150
143
  # @private New Topic::List from a
151
- # Google::Pubsub::V1::ListTopicsResponse object.
144
+ # Google::Cloud::PubSub::V1::ListTopicsResponse object.
152
145
  def self.from_grpc grpc_list, service, max = nil
153
146
  topics = new(Array(grpc_list.topics).map do |grpc|
154
147
  Topic.from_grpc grpc, service
155
148
  end)
156
149
  token = grpc_list.next_page_token
157
- token = nil if token == ""
158
- topics.instance_variable_set "@token", token
159
- topics.instance_variable_set "@service", service
160
- topics.instance_variable_set "@max", max
150
+ token = nil if token == "".freeze
151
+ topics.instance_variable_set :@token, token
152
+ topics.instance_variable_set :@service, service
153
+ topics.instance_variable_set :@max, max
161
154
  topics
162
155
  end
163
156
 
@@ -167,10 +160,12 @@ module Google
167
160
  # @private Raise an error unless an active connection to the service
168
161
  # is available.
169
162
  def ensure_service!
170
- fail "Must have active connection to service" unless @service
163
+ raise "Must have active connection to service" unless @service
171
164
  end
172
165
  end
173
166
  end
174
167
  end
168
+
169
+ Pubsub = PubSub unless const_defined? :Pubsub
175
170
  end
176
171
  end
@@ -1,10 +1,10 @@
1
- # Copyright 2015 Google Inc. All rights reserved.
1
+ # Copyright 2015 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
5
5
  # You may obtain a copy of the License at
6
6
  #
7
- # http://www.apache.org/licenses/LICENSE-2.0
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
8
  #
9
9
  # Unless required by applicable law or agreed to in writing, software
10
10
  # distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,61 +14,295 @@
14
14
 
15
15
 
16
16
  require "google/cloud/errors"
17
- require "google/cloud/pubsub/topic/publisher"
18
17
  require "google/cloud/pubsub/topic/list"
18
+ require "google/cloud/pubsub/async_publisher"
19
+ require "google/cloud/pubsub/batch_publisher"
19
20
  require "google/cloud/pubsub/subscription"
20
21
  require "google/cloud/pubsub/policy"
22
+ require "google/cloud/pubsub/retry_policy"
21
23
 
22
24
  module Google
23
25
  module Cloud
24
- module Pubsub
26
+ module PubSub
25
27
  ##
26
28
  # # Topic
27
29
  #
28
30
  # A named resource to which messages are published.
29
31
  #
32
+ # See {Project#create_topic} and {Project#topic}.
33
+ #
30
34
  # @example
31
- # require "google/cloud"
35
+ # require "google/cloud/pubsub"
32
36
  #
33
- # gcloud = Google::Cloud.new
34
- # pubsub = gcloud.pubsub
37
+ # pubsub = Google::Cloud::PubSub.new
35
38
  #
36
39
  # topic = pubsub.topic "my-topic"
37
40
  # topic.publish "task completed"
38
41
  #
39
42
  class Topic
40
43
  ##
41
- # @private The gRPC Service object.
44
+ # @private The Service object.
42
45
  attr_accessor :service
43
46
 
44
47
  ##
45
- # @private The gRPC Google::Pubsub::V1::Topic object.
48
+ # @private The Google::Cloud::PubSub::V1::Topic object.
46
49
  attr_accessor :grpc
47
50
 
48
51
  ##
49
52
  # @private Create an empty {Topic} object.
50
53
  def initialize
51
54
  @service = nil
52
- @grpc = Google::Pubsub::V1::Topic.new
53
- @name = nil
55
+ @grpc = nil
56
+ @resource_name = nil
54
57
  @exists = nil
58
+ @async_opts = {}
55
59
  end
56
60
 
57
61
  ##
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
62
+ # AsyncPublisher object used to publish multiple messages in batches.
63
+ #
64
+ # @return [AsyncPublisher] Returns publisher object if calls to
65
+ # {#publish_async} have been made, returns `nil` otherwise.
66
+ #
67
+ # @example
68
+ # require "google/cloud/pubsub"
69
+ #
70
+ # pubsub = Google::Cloud::PubSub.new
71
+ #
72
+ # topic = pubsub.topic "my-topic"
73
+ # topic.publish_async "task completed" do |result|
74
+ # if result.succeeded?
75
+ # log_publish_success result.data
76
+ # else
77
+ # log_publish_failure result.data, result.error
78
+ # end
79
+ # end
80
+ #
81
+ # topic.async_publisher.stop!
82
+ #
83
+ def async_publisher
84
+ @async_publisher
65
85
  end
66
86
 
67
87
  ##
68
- # The name of the topic in the form of
69
- # "/projects/project-identifier/topics/topic-name".
88
+ # The name of the topic.
89
+ #
90
+ # @return [String] A fully-qualified topic name in the form
91
+ # `projects/{project_id}/topics/{topic_id}`.
92
+ #
70
93
  def name
71
- @grpc ? @grpc.name : @name
94
+ return @resource_name if reference?
95
+ @grpc.name
96
+ end
97
+
98
+ ##
99
+ # A hash of user-provided labels associated with this topic. Labels can
100
+ # be used to organize and group topics. See [Creating and Managing
101
+ # Labels](https://cloud.google.com/pubsub/docs/labels).
102
+ #
103
+ # The returned hash is frozen and changes are not allowed. Use
104
+ # {#labels=} to update the labels for this topic.
105
+ #
106
+ # Makes an API call to retrieve the labels values when called on a
107
+ # reference object. See {#reference?}.
108
+ #
109
+ # @return [Hash] The frozen labels hash.
110
+ #
111
+ def labels
112
+ ensure_grpc!
113
+ @grpc.labels.to_h.freeze
114
+ end
115
+
116
+ ##
117
+ # Sets the hash of user-provided labels associated with this
118
+ # topic. Labels can be used to organize and group topics.
119
+ # Label keys and values can be no longer than 63 characters, can only
120
+ # contain lowercase letters, numeric characters, underscores and dashes.
121
+ # International characters are allowed. Label values are optional. Label
122
+ # keys must start with a letter and each label in the list must have a
123
+ # different key. See [Creating and Managing
124
+ # Labels](https://cloud.google.com/pubsub/docs/labels).
125
+ #
126
+ # @param [Hash] new_labels The new labels hash.
127
+ #
128
+ def labels= new_labels
129
+ raise ArgumentError, "Value must be a Hash" if new_labels.nil?
130
+ update_grpc = Google::Cloud::PubSub::V1::Topic.new name: name, labels: new_labels
131
+ @grpc = service.update_topic update_grpc, :labels
132
+ @resource_name = nil
133
+ end
134
+
135
+ ##
136
+ # The Cloud KMS encryption key that will be used to protect access
137
+ # to messages published on this topic.
138
+ # For example: `projects/a/locations/b/keyRings/c/cryptoKeys/d`
139
+ # The default value is `nil`, which means default encryption is used.
140
+ #
141
+ # Makes an API call to retrieve the KMS encryption key when called on a
142
+ # reference object. See {#reference?}.
143
+ #
144
+ # @return [String]
145
+ #
146
+ # @example
147
+ # require "google/cloud/pubsub"
148
+ #
149
+ # pubsub = Google::Cloud::PubSub.new
150
+ #
151
+ # topic = pubsub.topic "my-topic"
152
+ #
153
+ # topic.kms_key #=> "projects/a/locations/b/keyRings/c/cryptoKeys/d"
154
+ #
155
+ def kms_key
156
+ ensure_grpc!
157
+ @grpc.kms_key_name
158
+ end
159
+
160
+ ##
161
+ # Set the Cloud KMS encryption key that will be used to protect access
162
+ # to messages published on this topic.
163
+ # For example: `projects/a/locations/b/keyRings/c/cryptoKeys/d`
164
+ # The default value is `nil`, which means default encryption is used.
165
+ #
166
+ # @param [String] new_kms_key_name New Cloud KMS key name
167
+ #
168
+ # @example
169
+ # require "google/cloud/pubsub"
170
+ #
171
+ # pubsub = Google::Cloud::PubSub.new
172
+ #
173
+ # topic = pubsub.topic "my-topic"
174
+ #
175
+ # key_name = "projects/a/locations/b/keyRings/c/cryptoKeys/d"
176
+ # topic.kms_key = key_name
177
+ #
178
+ def kms_key= new_kms_key_name
179
+ update_grpc = Google::Cloud::PubSub::V1::Topic.new name: name, kms_key_name: new_kms_key_name
180
+ @grpc = service.update_topic update_grpc, :kms_key_name
181
+ @resource_name = nil
182
+ end
183
+
184
+ ##
185
+ # The list of GCP region IDs where messages that are published to the
186
+ # topic may be persisted in storage.
187
+ #
188
+ # Messages published by publishers running in non-allowed GCP regions
189
+ # (or running outside of GCP altogether) will be routed for storage in
190
+ # one of the allowed regions. An empty list indicates a misconfiguration
191
+ # at the project or organization level, which will result in all publish
192
+ # operations failing.
193
+ #
194
+ # Makes an API call to retrieve the list of GCP region IDs values when
195
+ # called on a reference object. See {#reference?}.
196
+ #
197
+ # @return [Array<String>]
198
+ #
199
+ # @example
200
+ # require "google/cloud/pubsub"
201
+ #
202
+ # pubsub = Google::Cloud::PubSub.new
203
+ #
204
+ # topic = pubsub.topic "my-topic"
205
+ #
206
+ # topic.persistence_regions #=> ["us-central1", "us-central2"]
207
+ #
208
+ def persistence_regions
209
+ ensure_grpc!
210
+ return [] if @grpc.message_storage_policy.nil?
211
+ Array @grpc.message_storage_policy.allowed_persistence_regions
212
+ end
213
+
214
+ ##
215
+ # Sets the list of GCP region IDs where messages that are published to
216
+ # the topic may be persisted in storage.
217
+ #
218
+ # @param [Array<String>] new_persistence_regions
219
+ #
220
+ # @example
221
+ # require "google/cloud/pubsub"
222
+ #
223
+ # pubsub = Google::Cloud::PubSub.new
224
+ #
225
+ # topic = pubsub.topic "my-topic"
226
+ #
227
+ # topic.persistence_regions = ["us-central1", "us-central2"]
228
+ #
229
+ def persistence_regions= new_persistence_regions
230
+ update_grpc = Google::Cloud::PubSub::V1::Topic.new \
231
+ name: name, message_storage_policy: { allowed_persistence_regions: Array(new_persistence_regions) }
232
+ @grpc = service.update_topic update_grpc, :message_storage_policy
233
+ @resource_name = nil
234
+ end
235
+
236
+ ##
237
+ # The name of the schema that messages published should be validated against, if schema settings are configured
238
+ # for the topic. The value is a fully-qualified schema name in the form
239
+ # `projects/{project_id}/schemas/{schema_id}`. If present, {#message_encoding} should also be present. The value
240
+ # of this field will be `_deleted-schema_` if the schema has been deleted.
241
+ #
242
+ # Makes an API call to retrieve the schema settings when called on a reference object. See {#reference?}.
243
+ #
244
+ # @return [String, nil] The schema name, or `nil` if schema settings are not configured for the topic.
245
+ #
246
+ # @example
247
+ # require "google/cloud/pubsub"
248
+ #
249
+ # pubsub = Google::Cloud::PubSub.new
250
+ #
251
+ # topic = pubsub.topic "my-topic"
252
+ #
253
+ # topic.schema_name #=> "projects/my-project/schemas/my-schema"
254
+ #
255
+ def schema_name
256
+ ensure_grpc!
257
+ @grpc.schema_settings&.schema
258
+ end
259
+
260
+ ##
261
+ # The encoding of messages validated against the schema identified by {#schema_name}. If present, {#schema_name}
262
+ # should also be present. Values include:
263
+ #
264
+ # * `JSON` - JSON encoding.
265
+ # * `BINARY` - Binary encoding, as defined by the schema type. For some schema types, binary encoding may not be
266
+ # available.
267
+ #
268
+ # Makes an API call to retrieve the schema settings when called on a reference object. See {#reference?}.
269
+ #
270
+ # @return [Symbol, nil] The schema encoding, or `nil` if schema settings are not configured for the topic.
271
+ #
272
+ # @example
273
+ # require "google/cloud/pubsub"
274
+ #
275
+ # pubsub = Google::Cloud::PubSub.new
276
+ #
277
+ # topic = pubsub.topic "my-topic"
278
+ #
279
+ # topic.message_encoding #=> :JSON
280
+ #
281
+ def message_encoding
282
+ ensure_grpc!
283
+ @grpc.schema_settings&.encoding
284
+ end
285
+
286
+ ##
287
+ # Checks if the encoding of messages in the schema settings is `BINARY`. See {#message_encoding}.
288
+ #
289
+ # Makes an API call to retrieve the schema settings when called on a reference object. See {#reference?}.
290
+ #
291
+ # @return [Boolean] `true` when `BINARY`, `false` if not `BINARY` or schema settings is not set.
292
+ #
293
+ def message_encoding_binary?
294
+ message_encoding.to_s.upcase == "BINARY"
295
+ end
296
+
297
+ ##
298
+ # Checks if the encoding of messages in the schema settings is `JSON`. See {#message_encoding}.
299
+ #
300
+ # Makes an API call to retrieve the schema settings when called on a reference object. See {#reference?}.
301
+ #
302
+ # @return [Boolean] `true` when `JSON`, `false` if not `JSON` or schema settings is not set.
303
+ #
304
+ def message_encoding_json?
305
+ message_encoding.to_s.upcase == "JSON"
72
306
  end
73
307
 
74
308
  ##
@@ -77,10 +311,9 @@ module Google
77
311
  # @return [Boolean] Returns `true` if the topic was deleted.
78
312
  #
79
313
  # @example
80
- # require "google/cloud"
314
+ # require "google/cloud/pubsub"
81
315
  #
82
- # gcloud = Google::Cloud.new
83
- # pubsub = gcloud.pubsub
316
+ # pubsub = Google::Cloud::PubSub.new
84
317
  #
85
318
  # topic = pubsub.topic "my-topic"
86
319
  # topic.delete
@@ -94,101 +327,216 @@ module Google
94
327
  ##
95
328
  # Creates a new {Subscription} object on the current Topic.
96
329
  #
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".
330
+ # @param [String] subscription_name Name of the new subscription. Required.
331
+ # The value can be a simple subscription ID (relative name), in which
332
+ # case the current project ID will be supplied, or a fully-qualified
333
+ # subscription name in the form
334
+ # `projects/{project_id}/subscriptions/{subscription_id}`.
335
+ #
336
+ # The subscription ID (relative name) must start with a letter, and
337
+ # contain only letters (`[A-Za-z]`), numbers (`[0-9]`), dashes (`-`),
338
+ # underscores (`_`), periods (`.`), tildes (`~`), plus (`+`) or percent
339
+ # signs (`%`). It must be between 3 and 255 characters in length, and
340
+ # it must not start with `goog`.
102
341
  # @param [Integer] deadline The maximum number of seconds after a
103
342
  # subscriber receives a message before the subscriber should
104
343
  # acknowledge the message.
344
+ # @param [Boolean] retain_acked Indicates whether to retain acknowledged
345
+ # messages. If `true`, then messages are not expunged from the
346
+ # subscription's backlog, even if they are acknowledged, until they
347
+ # fall out of the `retention` window. Default is `false`.
348
+ # @param [Numeric] retention How long to retain unacknowledged messages
349
+ # in the subscription's backlog, from the moment a message is
350
+ # published. If `retain_acked` is `true`, then this also configures
351
+ # the retention of acknowledged messages, and thus configures how far
352
+ # back in time a {Subscription#seek} can be done. Cannot be more than
353
+ # 604,800 seconds (7 days) or less than 600 seconds (10 minutes).
354
+ # Default is 604,800 seconds (7 days).
105
355
  # @param [String] endpoint A URL locating the endpoint to which messages
106
- # should be pushed.
107
- #
108
- # @return [Google::Cloud::Pubsub::Subscription]
356
+ # should be pushed. The parameters `push_config` and `endpoint` should not both be provided.
357
+ # @param [Google::Cloud::PubSub::Subscription::PushConfig] push_config The configuration for a push delivery
358
+ # endpoint that should contain the endpoint, and can contain authentication data (OIDC token authentication).
359
+ # The parameters `push_config` and `endpoint` should not both be provided.
360
+ # @param [Hash] labels A hash of user-provided labels associated with
361
+ # the subscription. You can use these to organize and group your
362
+ # subscriptions. Label keys and values can be no longer than 63
363
+ # characters, can only contain lowercase letters, numeric characters,
364
+ # underscores and dashes. International characters are allowed. Label
365
+ # values are optional. Label keys must start with a letter and each
366
+ # label in the list must have a different key. See [Creating and
367
+ # Managing Labels](https://cloud.google.com/pubsub/docs/labels).
368
+ # @param [Boolean] message_ordering Whether to enable message ordering
369
+ # on the subscription.
370
+ # @param [String] filter An expression written in the Cloud Pub/Sub filter language. If non-empty, then only
371
+ # {Message} instances whose `attributes` field matches the filter are delivered on this subscription. If
372
+ # empty, then no messages are filtered out. Optional.
373
+ # @param [Topic] dead_letter_topic The {Topic} to which dead letter messages for the subscription should be
374
+ # published. Dead lettering is done on a best effort basis. The same message might be dead lettered multiple
375
+ # times. The Cloud Pub/Sub service account associated with the enclosing subscription's parent project (i.e.,
376
+ # `service-\\{project_number}@gcp-sa-pubsub.iam.gserviceaccount.com`) must have permission to Publish() to
377
+ # this topic.
378
+ #
379
+ # The operation will fail if the topic does not exist. Users should ensure that there is a subscription
380
+ # attached to this topic since messages published to a topic with no subscriptions are lost.
381
+ # @param [Integer] dead_letter_max_delivery_attempts The maximum number of delivery attempts for any message in
382
+ # the subscription's dead letter policy. Dead lettering is done on a best effort basis. The same message might
383
+ # be dead lettered multiple times. The value must be between 5 and 100. If this parameter is 0, a default
384
+ # value of 5 is used. The `dead_letter_topic` must also be set.
385
+ # @param [RetryPolicy] retry_policy A policy that specifies how Cloud Pub/Sub retries message delivery for
386
+ # this subscription. If not set, the default retry policy is applied. This generally implies that messages
387
+ # will be retried as soon as possible for healthy subscribers. Retry Policy will be triggered on NACKs or
388
+ # acknowledgement deadline exceeded events for a given message.
389
+ #
390
+ # @return [Google::Cloud::PubSub::Subscription]
109
391
  #
110
392
  # @example
111
- # require "google/cloud"
393
+ # require "google/cloud/pubsub"
112
394
  #
113
- # gcloud = Google::Cloud.new
114
- # pubsub = gcloud.pubsub
395
+ # pubsub = Google::Cloud::PubSub.new
115
396
  #
116
397
  # topic = pubsub.topic "my-topic"
117
398
  # sub = topic.subscribe "my-topic-sub"
118
- # puts sub.name # => "my-topic-sub"
399
+ # sub.name # => "my-topic-sub"
119
400
  #
120
- # @example The name is optional, and will be generated if not given:
121
- # require "google/cloud"
401
+ # @example Wait 2 minutes for acknowledgement:
402
+ # require "google/cloud/pubsub"
122
403
  #
123
- # gcloud = Google::Cloud.new
124
- # pubsub = gcloud.pubsub
404
+ # pubsub = Google::Cloud::PubSub.new
125
405
  #
126
406
  # topic = pubsub.topic "my-topic"
127
- # sub = topic.subscribe "my-topic-sub"
128
- # puts sub.name # => "generated-sub-name"
407
+ # sub = topic.subscribe "my-topic-sub",
408
+ # deadline: 120
409
+ #
410
+ # @example Configure a push endpoint:
411
+ # require "google/cloud/pubsub"
129
412
  #
130
- # @example Wait 2 minutes for acknowledgement and push all to endpoint:
131
- # require "google/cloud"
413
+ # pubsub = Google::Cloud::PubSub.new
414
+ # topic = pubsub.topic "my-topic"
132
415
  #
133
- # gcloud = Google::Cloud.new
134
- # pubsub = gcloud.pubsub
416
+ # push_config = Google::Cloud::PubSub::Subscription::PushConfig.new endpoint: "http://example.net/callback"
417
+ # push_config.set_oidc_token "service-account@example.net", "audience-header-value"
418
+ #
419
+ # sub = topic.subscribe "my-subscription", push_config: push_config
420
+ #
421
+ # @example Configure a Dead Letter Queues policy:
422
+ # require "google/cloud/pubsub"
423
+ #
424
+ # pubsub = Google::Cloud::PubSub.new
425
+ #
426
+ # # Dead Letter Queue (DLQ) testing requires IAM bindings to the Cloud Pub/Sub service account that is
427
+ # # automatically created and managed by the service team in a private project.
428
+ # my_project_number = "000000000000"
429
+ # service_account_email = "serviceAccount:service-#{my_project_number}@gcp-sa-pubsub.iam.gserviceaccount.com"
430
+ #
431
+ # dead_letter_topic = pubsub.topic "my-dead-letter-topic"
432
+ # dead_letter_subscription = dead_letter_topic.subscribe "my-dead-letter-sub"
433
+ #
434
+ # dead_letter_topic.policy { |p| p.add "roles/pubsub.publisher", service_account_email }
435
+ # dead_letter_subscription.policy { |p| p.add "roles/pubsub.subscriber", service_account_email }
135
436
  #
136
437
  # topic = pubsub.topic "my-topic"
137
438
  # sub = topic.subscribe "my-topic-sub",
138
- # deadline: 120,
139
- # endpoint: "https://example.com/push"
439
+ # dead_letter_topic: dead_letter_topic,
440
+ # dead_letter_max_delivery_attempts: 10
441
+ #
442
+ # @example Configure a Retry Policy:
443
+ # require "google/cloud/pubsub"
444
+ #
445
+ # pubsub = Google::Cloud::PubSub.new
140
446
  #
141
- def subscribe subscription_name, deadline: nil, endpoint: nil
447
+ # topic = pubsub.topic "my-topic"
448
+ #
449
+ # retry_policy = Google::Cloud::PubSub::RetryPolicy.new minimum_backoff: 5, maximum_backoff: 300
450
+ # sub = topic.subscribe "my-topic-sub", retry_policy: retry_policy
451
+ #
452
+ def subscribe subscription_name,
453
+ deadline: nil,
454
+ retain_acked: false,
455
+ retention: nil,
456
+ endpoint: nil,
457
+ push_config: nil,
458
+ labels: nil,
459
+ message_ordering: nil,
460
+ filter: nil,
461
+ dead_letter_topic: nil,
462
+ dead_letter_max_delivery_attempts: nil,
463
+ retry_policy: nil
142
464
  ensure_service!
143
- options = { deadline: deadline, endpoint: endpoint }
465
+ if push_config && endpoint
466
+ raise ArgumentError, "endpoint and push_config were both provided. Please provide only one."
467
+ end
468
+ push_config = Google::Cloud::PubSub::Subscription::PushConfig.new endpoint: endpoint if endpoint
469
+
470
+ options = {
471
+ deadline: deadline,
472
+ retain_acked: retain_acked,
473
+ retention: retention,
474
+ labels: labels,
475
+ message_ordering: message_ordering,
476
+ filter: filter,
477
+ dead_letter_max_delivery_attempts: dead_letter_max_delivery_attempts
478
+ }
479
+
480
+ options[:dead_letter_topic_name] = dead_letter_topic.name if dead_letter_topic
481
+ if options[:dead_letter_max_delivery_attempts] && !options[:dead_letter_topic_name]
482
+ # Service error message "3:Invalid resource name given (name=)." does not identify param.
483
+ raise ArgumentError, "dead_letter_topic is required with dead_letter_max_delivery_attempts"
484
+ end
485
+ options[:push_config] = push_config.to_grpc if push_config
486
+ options[:retry_policy] = retry_policy.to_grpc if retry_policy
144
487
  grpc = service.create_subscription name, subscription_name, options
145
488
  Subscription.from_grpc grpc, service
146
489
  end
147
- alias_method :create_subscription, :subscribe
148
- alias_method :new_subscription, :subscribe
490
+ alias create_subscription subscribe
491
+ alias new_subscription subscribe
149
492
 
150
493
  ##
151
494
  # Retrieves subscription by name.
152
495
  #
153
- # @param [String] subscription_name Name of a subscription.
496
+ # @param [String] subscription_name Name of a subscription. The value
497
+ # can be a simple subscription ID (relative name), in which case the
498
+ # current project ID will be supplied, or a fully-qualified
499
+ # subscription name in the form
500
+ # `projects/{project_id}/subscriptions/{subscription_id}`.
154
501
  # @param [Boolean] skip_lookup Optionally create a {Subscription} object
155
502
  # without verifying the subscription resource exists on the Pub/Sub
156
503
  # service. Calls made on this object will raise errors if the service
157
504
  # resource does not exist. Default is `false`.
158
505
  #
159
- # @return [Google::Cloud::Pubsub::Subscription, nil] Returns `nil` if
506
+ # @return [Google::Cloud::PubSub::Subscription, nil] Returns `nil` if
160
507
  # the subscription does not exist.
161
508
  #
162
509
  # @example
163
- # require "google/cloud"
510
+ # require "google/cloud/pubsub"
164
511
  #
165
- # gcloud = Google::Cloud.new
166
- # pubsub = gcloud.pubsub
512
+ # pubsub = Google::Cloud::PubSub.new
167
513
  #
168
514
  # topic = pubsub.topic "my-topic"
169
- # subscription = topic.subscription "my-topic-subscription"
170
- # puts subscription.name
515
+ #
516
+ # sub = topic.subscription "my-topic-sub"
517
+ # sub.name #=> "projects/my-project/subscriptions/my-topic-sub"
171
518
  #
172
519
  # @example Skip the lookup against the service with `skip_lookup`:
173
- # require "google/cloud"
520
+ # require "google/cloud/pubsub"
174
521
  #
175
- # gcloud = Google::Cloud.new
176
- # pubsub = gcloud.pubsub
522
+ # pubsub = Google::Cloud::PubSub.new
523
+ #
524
+ # topic = pubsub.topic "my-topic"
177
525
  #
178
526
  # # No API call is made to retrieve the subscription information.
179
- # subscription = pubsub.subscription "my-sub", skip_lookup: true
180
- # puts subscription.name
527
+ # sub = topic.subscription "my-topic-sub", skip_lookup: true
528
+ # sub.name #=> "projects/my-project/subscriptions/my-topic-sub"
181
529
  #
182
530
  def subscription subscription_name, skip_lookup: nil
183
531
  ensure_service!
184
- return Subscription.new_lazy subscription_name, service if skip_lookup
532
+ return Subscription.from_name subscription_name, service if skip_lookup
185
533
  grpc = service.get_subscription subscription_name
186
534
  Subscription.from_grpc grpc, service
187
535
  rescue Google::Cloud::NotFoundError
188
536
  nil
189
537
  end
190
- alias_method :get_subscription, :subscription
191
- alias_method :find_subscription, :subscription
538
+ alias get_subscription subscription
539
+ alias find_subscription subscription
192
540
 
193
541
  ##
194
542
  # Retrieves a list of subscription names for the given project.
@@ -201,25 +549,23 @@ module Google
201
549
  # @return [Array<Subscription>] (See {Subscription::List})
202
550
  #
203
551
  # @example
204
- # require "google/cloud"
552
+ # require "google/cloud/pubsub"
205
553
  #
206
- # gcloud = Google::Cloud.new
207
- # pubsub = gcloud.pubsub
554
+ # pubsub = Google::Cloud::PubSub.new
208
555
  #
209
556
  # topic = pubsub.topic "my-topic"
210
- # subscription = topic.subscriptions
557
+ # subscriptions = topic.subscriptions
211
558
  # subscriptions.each do |subscription|
212
559
  # puts subscription.name
213
560
  # end
214
561
  #
215
562
  # @example Retrieve all subscriptions: (See {Subscription::List#all})
216
- # require "google/cloud"
563
+ # require "google/cloud/pubsub"
217
564
  #
218
- # gcloud = Google::Cloud.new
219
- # pubsub = gcloud.pubsub
565
+ # pubsub = Google::Cloud::PubSub.new
220
566
  #
221
567
  # topic = pubsub.topic "my-topic"
222
- # subscription = topic.subscriptions
568
+ # subscriptions = topic.subscriptions
223
569
  # subscriptions.all do |subscription|
224
570
  # puts subscription.name
225
571
  # end
@@ -230,84 +576,251 @@ module Google
230
576
  grpc = service.list_topics_subscriptions name, options
231
577
  Subscription::List.from_topic_grpc grpc, service, name, max
232
578
  end
233
- alias_method :find_subscriptions, :subscriptions
234
- alias_method :list_subscriptions, :subscriptions
579
+ alias find_subscriptions subscriptions
580
+ alias list_subscriptions subscriptions
235
581
 
236
582
  ##
237
583
  # Publishes one or more messages to the topic.
238
584
  #
239
- # @param [String, File] data The message data.
585
+ # The message payload must not be empty; it must contain either a
586
+ # non-empty data field, or at least one attribute.
587
+ #
588
+ # @param [String, File] data The message payload. This will be converted
589
+ # to bytes encoded as ASCII-8BIT.
240
590
  # @param [Hash] attributes Optional attributes for the message.
241
- # @yield [publisher] a block for publishing multiple messages in one
591
+ # @param [String] ordering_key Identifies related messages for which
592
+ # publish order should be respected.
593
+ # @yield [batch] a block for publishing multiple messages in one
242
594
  # request
243
- # @yieldparam [Topic::Publisher] publisher the topic publisher object
595
+ # @yieldparam [BatchPublisher] batch the topic batch publisher
596
+ # object
244
597
  #
245
598
  # @return [Message, Array<Message>] Returns the published message when
246
599
  # called without a block, or an array of messages when called with a
247
600
  # block.
248
601
  #
249
602
  # @example
250
- # require "google/cloud"
603
+ # require "google/cloud/pubsub"
251
604
  #
252
- # gcloud = Google::Cloud.new
253
- # pubsub = gcloud.pubsub
605
+ # pubsub = Google::Cloud::PubSub.new
254
606
  #
255
607
  # topic = pubsub.topic "my-topic"
256
- # msg = topic.publish "new-message"
608
+ # msg = topic.publish "task completed"
257
609
  #
258
610
  # @example A message can be published using a File object:
259
- # require "google/cloud"
611
+ # require "google/cloud/pubsub"
260
612
  #
261
- # gcloud = Google::Cloud.new
262
- # pubsub = gcloud.pubsub
613
+ # pubsub = Google::Cloud::PubSub.new
263
614
  #
264
615
  # topic = pubsub.topic "my-topic"
265
- # msg = topic.publish File.open("message.txt")
616
+ # file = File.open "message.txt", mode: "rb"
617
+ # msg = topic.publish file
266
618
  #
267
619
  # @example Additionally, a message can be published with attributes:
268
- # require "google/cloud"
620
+ # require "google/cloud/pubsub"
269
621
  #
270
- # gcloud = Google::Cloud.new
271
- # pubsub = gcloud.pubsub
622
+ # pubsub = Google::Cloud::PubSub.new
272
623
  #
273
624
  # topic = pubsub.topic "my-topic"
274
- # msg = topic.publish "new-message",
625
+ # msg = topic.publish "task completed",
275
626
  # foo: :bar,
276
627
  # this: :that
277
628
  #
278
629
  # @example Multiple messages can be sent at the same time using a block:
279
- # require "google/cloud"
630
+ # require "google/cloud/pubsub"
280
631
  #
281
- # gcloud = Google::Cloud.new
282
- # pubsub = gcloud.pubsub
632
+ # pubsub = Google::Cloud::PubSub.new
283
633
  #
284
634
  # topic = pubsub.topic "my-topic"
285
635
  # 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
636
+ # t.publish "task 1 completed", foo: :bar
637
+ # t.publish "task 2 completed", foo: :baz
638
+ # t.publish "task 3 completed", foo: :bif
289
639
  # end
290
640
  #
291
- def publish data = nil, attributes = {}
641
+ # @example Ordered messages are supported using ordering_key:
642
+ # require "google/cloud/pubsub"
643
+ #
644
+ # pubsub = Google::Cloud::PubSub.new
645
+ #
646
+ # topic = pubsub.topic "my-ordered-topic"
647
+ #
648
+ # # Ensure that message ordering is enabled.
649
+ # topic.enable_message_ordering!
650
+ #
651
+ # # Publish an ordered message with an ordering key.
652
+ # topic.publish "task completed",
653
+ # ordering_key: "task-key"
654
+ #
655
+ def publish data = nil, attributes = nil, ordering_key: nil, **extra_attrs, &block
292
656
  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
657
+ batch = BatchPublisher.new data, attributes, ordering_key, extra_attrs
658
+ block&.call batch
659
+ return nil if batch.messages.count.zero?
660
+ publish_batch_messages batch
661
+ end
662
+
663
+ ##
664
+ # Publishes a message asynchronously to the topic using
665
+ # {#async_publisher}.
666
+ #
667
+ # The message payload must not be empty; it must contain either a
668
+ # non-empty data field, or at least one attribute.
669
+ #
670
+ # Google Cloud Pub/Sub ordering keys provide the ability to ensure
671
+ # related messages are sent to subscribers in the order in which they
672
+ # were published. Messages can be tagged with an ordering key, a string
673
+ # that identifies related messages for which publish order should be
674
+ # respected. The service guarantees that, for a given ordering key and
675
+ # publisher, messages are sent to subscribers in the order in which they
676
+ # were published. Ordering does not require sacrificing high throughput
677
+ # or scalability, as the service automatically distributes messages for
678
+ # different ordering keys across subscribers.
679
+ #
680
+ # To use ordering keys, specify `ordering_key`. Before specifying
681
+ # `ordering_key` on a message a call to `#enable_message_ordering!` must
682
+ # be made or an error will be raised.
683
+ #
684
+ # @note At the time of this release, ordering keys are not yet publicly
685
+ # enabled and requires special project enablements.
686
+ #
687
+ # @param [String, File] data The message payload. This will be converted
688
+ # to bytes encoded as ASCII-8BIT.
689
+ # @param [Hash] attributes Optional attributes for the message.
690
+ # @param [String] ordering_key Identifies related messages for which
691
+ # publish order should be respected.
692
+ # @yield [result] the callback for when the message has been published
693
+ # @yieldparam [PublishResult] result the result of the asynchronous
694
+ # publish
695
+ # @raise [Google::Cloud::PubSub::AsyncPublisherStopped] when the
696
+ # publisher is stopped. (See {AsyncPublisher#stop} and
697
+ # {AsyncPublisher#stopped?}.)
698
+ # @raise [Google::Cloud::PubSub::OrderedMessagesDisabled] when
699
+ # publishing a message with an `ordering_key` but ordered messages are
700
+ # not enabled. (See {#message_ordering?} and
701
+ # {#enable_message_ordering!}.)
702
+ # @raise [Google::Cloud::PubSub::OrderingKeyError] when publishing a
703
+ # message with an `ordering_key` that has already failed when
704
+ # publishing. Use {#resume_publish} to allow this `ordering_key` to be
705
+ # published again.
706
+ #
707
+ # @example
708
+ # require "google/cloud/pubsub"
709
+ #
710
+ # pubsub = Google::Cloud::PubSub.new
711
+ #
712
+ # topic = pubsub.topic "my-topic"
713
+ # topic.publish_async "task completed" do |result|
714
+ # if result.succeeded?
715
+ # log_publish_success result.data
716
+ # else
717
+ # log_publish_failure result.data, result.error
718
+ # end
719
+ # end
720
+ #
721
+ # # Shut down the publisher when ready to stop publishing messages.
722
+ # topic.async_publisher.stop!
723
+ #
724
+ # @example A message can be published using a File object:
725
+ # require "google/cloud/pubsub"
726
+ #
727
+ # pubsub = Google::Cloud::PubSub.new
728
+ #
729
+ # topic = pubsub.topic "my-topic"
730
+ # file = File.open "message.txt", mode: "rb"
731
+ # topic.publish_async file
732
+ #
733
+ # # Shut down the publisher when ready to stop publishing messages.
734
+ # topic.async_publisher.stop!
735
+ #
736
+ # @example Additionally, a message can be published with attributes:
737
+ # require "google/cloud/pubsub"
738
+ #
739
+ # pubsub = Google::Cloud::PubSub.new
740
+ #
741
+ # topic = pubsub.topic "my-topic"
742
+ # topic.publish_async "task completed",
743
+ # foo: :bar, this: :that
744
+ #
745
+ # # Shut down the publisher when ready to stop publishing messages.
746
+ # topic.async_publisher.stop!
747
+ #
748
+ # @example Ordered messages are supported using ordering_key:
749
+ # require "google/cloud/pubsub"
750
+ #
751
+ # pubsub = Google::Cloud::PubSub.new
752
+ #
753
+ # topic = pubsub.topic "my-ordered-topic"
754
+ #
755
+ # # Ensure that message ordering is enabled.
756
+ # topic.enable_message_ordering!
757
+ #
758
+ # # Publish an ordered message with an ordering key.
759
+ # topic.publish_async "task completed",
760
+ # ordering_key: "task-key"
761
+ #
762
+ # # Shut down the publisher when ready to stop publishing messages.
763
+ # topic.async_publisher.stop!
764
+ #
765
+ def publish_async data = nil, attributes = nil, ordering_key: nil, **extra_attrs, &callback
766
+ ensure_service!
767
+
768
+ @async_publisher ||= AsyncPublisher.new name, service, **@async_opts
769
+ @async_publisher.publish data, attributes, ordering_key: ordering_key, **extra_attrs, &callback
770
+ end
771
+
772
+ ##
773
+ # Enables message ordering for messages with ordering keys on the
774
+ # {#async_publisher}. When enabled, messages published with the same
775
+ # `ordering_key` will be delivered in the order they were published.
776
+ #
777
+ # @note At the time of this release, ordering keys are not yet publicly
778
+ # enabled and requires special project enablements.
779
+ #
780
+ # See {#message_ordering?}. See {#publish_async},
781
+ # {Subscription#listen}, and {Message#ordering_key}.
782
+ #
783
+ def enable_message_ordering!
784
+ @async_publisher ||= AsyncPublisher.new name, service, **@async_opts
785
+ @async_publisher.enable_message_ordering!
786
+ end
787
+
788
+ ##
789
+ # Whether message ordering for messages with ordering keys has been
790
+ # enabled on the {#async_publisher}. When enabled, messages published
791
+ # with the same `ordering_key` will be delivered in the order they were
792
+ # published. When disabled, messages may be delivered in any order.
793
+ #
794
+ # See {#enable_message_ordering!}. See {#publish_async},
795
+ # {Subscription#listen}, and {Message#ordering_key}.
796
+ #
797
+ # @return [Boolean]
798
+ #
799
+ def message_ordering?
800
+ @async_publisher ||= AsyncPublisher.new name, service, **@async_opts
801
+ @async_publisher.message_ordering?
802
+ end
803
+
804
+ ##
805
+ # Resume publishing ordered messages for the provided ordering key.
806
+ #
807
+ # @param [String] ordering_key Identifies related messages for which
808
+ # publish order should be respected.
809
+ #
810
+ # @return [boolean] `true` when resumed, `false` otherwise.
811
+ #
812
+ def resume_publish ordering_key
813
+ @async_publisher ||= AsyncPublisher.new name, service, **@async_opts
814
+ @async_publisher.resume_publish ordering_key
297
815
  end
298
816
 
299
817
  ##
300
818
  # Gets the [Cloud IAM](https://cloud.google.com/iam/) access control
301
819
  # policy for this topic.
302
820
  #
303
- # @see https://cloud.google.com/pubsub/reference/rpc/google.iam.v1#iampolicy
821
+ # @see https://cloud.google.com/pubsub/docs/reference/rpc/google.iam.v1#iampolicy
304
822
  # google.iam.v1.IAMPolicy
305
823
  #
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
824
  # @yield [policy] A block for updating the policy. The latest policy
312
825
  # will be read from the Pub/Sub service and passed to the block. After
313
826
  # the block completes, the modified policy will be written to the
@@ -317,83 +830,68 @@ module Google
317
830
  #
318
831
  # @return [Policy] the current Cloud IAM Policy for this topic
319
832
  #
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"
833
+ # @example
834
+ # require "google/cloud/pubsub"
332
835
  #
333
- # gcloud = Google::Cloud.new
334
- # pubsub = gcloud.pubsub
836
+ # pubsub = Google::Cloud::PubSub.new
335
837
  # topic = pubsub.topic "my-topic"
336
838
  #
337
- # policy = topic.policy force: true # API call
338
- # policy_2 = topic.policy force: true # API call
839
+ # policy = topic.policy
339
840
  #
340
841
  # @example Update the policy by passing a block:
341
- # require "google/cloud"
842
+ # require "google/cloud/pubsub"
342
843
  #
343
- # gcloud = Google::Cloud.new
344
- # pubsub = gcloud.pubsub
844
+ # pubsub = Google::Cloud::PubSub.new
345
845
  # topic = pubsub.topic "my-topic"
346
846
  #
347
- # policy = topic.policy do |p|
847
+ # topic.policy do |p|
348
848
  # 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
849
+ # end
850
+ #
851
+ def policy
852
+ ensure_service!
853
+ grpc = service.get_topic_policy name
854
+ policy = Policy.from_grpc grpc
855
+ return policy unless block_given?
856
+ yield policy
857
+ update_policy policy
362
858
  end
363
859
 
364
860
  ##
365
861
  # Updates the [Cloud IAM](https://cloud.google.com/iam/) access control
366
862
  # policy for this topic. The policy should be read from {#policy}. See
367
- # {Google::Cloud::Pubsub::Policy} for an explanation of the policy
863
+ # {Google::Cloud::PubSub::Policy} for an explanation of the policy
368
864
  # `etag` property and how to modify policies.
369
865
  #
370
866
  # You can also update the policy by passing a block to {#policy}, which
371
867
  # will call this method internally after the block completes.
372
868
  #
373
- # @see https://cloud.google.com/pubsub/reference/rpc/google.iam.v1#iampolicy
869
+ # @see https://cloud.google.com/pubsub/docs/reference/rpc/google.iam.v1#iampolicy
374
870
  # google.iam.v1.IAMPolicy
375
871
  #
376
872
  # @param [Policy] new_policy a new or modified Cloud IAM Policy for this
377
873
  # topic
378
874
  #
875
+ # @return [Policy] the policy returned by the API update operation
876
+ #
379
877
  # @example
380
- # require "google/cloud"
878
+ # require "google/cloud/pubsub"
381
879
  #
382
- # gcloud = Google::Cloud.new
383
- # pubsub = gcloud.pubsub
880
+ # pubsub = Google::Cloud::PubSub.new
384
881
  # topic = pubsub.topic "my-topic"
385
882
  #
386
883
  # policy = topic.policy # API call
387
884
  #
388
885
  # policy.add "roles/owner", "user:owner@example.com"
389
886
  #
390
- # topic.policy = policy # API call
887
+ # topic.update_policy policy # API call
391
888
  #
392
- def policy= new_policy
889
+ def update_policy new_policy
393
890
  ensure_service!
394
891
  grpc = service.set_topic_policy name, new_policy.to_grpc
395
892
  @policy = Policy.from_grpc grpc
396
893
  end
894
+ alias policy= update_policy
397
895
 
398
896
  ##
399
897
  # Tests the specified permissions against the [Cloud
@@ -419,10 +917,9 @@ module Google
419
917
  # @return [Array<Strings>] The permissions that have access.
420
918
  #
421
919
  # @example
422
- # require "google/cloud"
920
+ # require "google/cloud/pubsub"
423
921
  #
424
- # gcloud = Google::Cloud.new
425
- # pubsub = gcloud.pubsub
922
+ # pubsub = Google::Cloud::PubSub.new
426
923
  # topic = pubsub.topic "my-topic"
427
924
  # perms = topic.test_permissions "pubsub.topics.get",
428
925
  # "pubsub.topics.publish"
@@ -441,46 +938,99 @@ module Google
441
938
  # Determines whether the topic exists in the Pub/Sub service.
442
939
  #
443
940
  # @example
444
- # require "google/cloud"
941
+ # require "google/cloud/pubsub"
445
942
  #
446
- # gcloud = Google::Cloud.new
447
- # pubsub = gcloud.pubsub
943
+ # pubsub = Google::Cloud::PubSub.new
448
944
  #
449
945
  # topic = pubsub.topic "my-topic"
450
946
  # topic.exists? #=> true
451
947
  #
452
948
  def exists?
453
- # Always true if we have a grpc object
454
- return true unless @grpc.nil?
949
+ # Always true if the object is not set as reference
950
+ return true unless reference?
455
951
  # If we have a value, return it
456
952
  return @exists unless @exists.nil?
457
953
  ensure_grpc!
458
- @exists = !@grpc.nil?
954
+ @exists = true
955
+ rescue Google::Cloud::NotFoundError
956
+ @exists = false
459
957
  end
460
958
 
461
959
  ##
462
- # @private
463
- # Determines whether the topic object was created with an HTTP call.
960
+ # Determines whether the topic object was created without retrieving the
961
+ # resource representation from the Pub/Sub service.
962
+ #
963
+ # @return [Boolean] `true` when the topic was created without a resource
964
+ # representation, `false` otherwise.
464
965
  #
465
966
  # @example
466
- # require "google/cloud"
967
+ # require "google/cloud/pubsub"
467
968
  #
468
- # gcloud = Google::Cloud.new
469
- # pubsub = gcloud.pubsub
969
+ # pubsub = Google::Cloud::PubSub.new
470
970
  #
471
- # topic = pubsub.topic "my-topic"
472
- # topic.lazy? #=> false
971
+ # topic = pubsub.topic "my-topic", skip_lookup: true
972
+ # topic.reference? #=> true
473
973
  #
474
- def lazy?
974
+ def reference?
475
975
  @grpc.nil?
476
976
  end
477
977
 
478
978
  ##
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
979
+ # Determines whether the topic object was created with a resource
980
+ # representation from the Pub/Sub service.
981
+ #
982
+ # @return [Boolean] `true` when the topic was created with a resource
983
+ # representation, `false` otherwise.
984
+ #
985
+ # @example
986
+ # require "google/cloud/pubsub"
987
+ #
988
+ # pubsub = Google::Cloud::PubSub.new
989
+ #
990
+ # topic = pubsub.topic "my-topic"
991
+ # topic.resource? #=> true
992
+ #
993
+ def resource?
994
+ !@grpc.nil?
995
+ end
996
+
997
+ ##
998
+ # Reloads the topic with current data from the Pub/Sub service.
999
+ #
1000
+ # @return [Google::Cloud::PubSub::Topic] Returns the reloaded topic
1001
+ #
1002
+ # @example
1003
+ # require "google/cloud/pubsub"
1004
+ #
1005
+ # pubsub = Google::Cloud::PubSub.new
1006
+ #
1007
+ # topic = pubsub.topic "my-topic"
1008
+ # topic.reload!
1009
+ #
1010
+ def reload!
1011
+ ensure_service!
1012
+ @grpc = service.get_topic name
1013
+ @resource_name = nil
1014
+ self
1015
+ end
1016
+ alias refresh! reload!
1017
+
1018
+ ##
1019
+ # @private New Topic from a Google::Cloud::PubSub::V1::Topic object.
1020
+ def self.from_grpc grpc, service, async: nil
1021
+ new.tap do |t|
1022
+ t.grpc = grpc
1023
+ t.service = service
1024
+ t.instance_variable_set :@async_opts, async if async
1025
+ end
1026
+ end
1027
+
1028
+ ##
1029
+ # @private New reference {Topic} object without making an HTTP request.
1030
+ def self.from_name name, service, options = {}
1031
+ name = service.topic_path name, options
1032
+ from_grpc(nil, service).tap do |t|
1033
+ t.instance_variable_set :@resource_name, name
484
1034
  end
485
1035
  end
486
1036
 
@@ -490,17 +1040,14 @@ module Google
490
1040
  # @private Raise an error unless an active connection to the service is
491
1041
  # available.
492
1042
  def ensure_service!
493
- fail "Must have active connection to service" unless service
1043
+ raise "Must have active connection to service" unless service
494
1044
  end
495
1045
 
496
1046
  ##
497
- # Ensures a Google::Pubsub::V1::Topic object exists.
1047
+ # Ensures a Google::Cloud::PubSub::V1::Topic object exists.
498
1048
  def ensure_grpc!
499
1049
  ensure_service!
500
- return @grpc if @grpc
501
- @grpc = service.get_topic @name
502
- rescue Google::Cloud::NotFoundError
503
- nil
1050
+ reload! if reference?
504
1051
  end
505
1052
 
506
1053
  ##
@@ -511,5 +1058,7 @@ module Google
511
1058
  end
512
1059
  end
513
1060
  end
1061
+
1062
+ Pubsub = PubSub unless const_defined? :Pubsub
514
1063
  end
515
1064
  end