google-cloud-pubsub 1.9.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.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +18 -0
  3. data/AUTHENTICATION.md +177 -0
  4. data/CHANGELOG.md +538 -0
  5. data/CODE_OF_CONDUCT.md +40 -0
  6. data/CONTRIBUTING.md +188 -0
  7. data/EMULATOR.md +37 -0
  8. data/LICENSE +201 -0
  9. data/LOGGING.md +32 -0
  10. data/OVERVIEW.md +557 -0
  11. data/TROUBLESHOOTING.md +31 -0
  12. data/lib/google-cloud-pubsub.rb +139 -0
  13. data/lib/google/cloud/pubsub.rb +173 -0
  14. data/lib/google/cloud/pubsub/async_publisher.rb +399 -0
  15. data/lib/google/cloud/pubsub/async_publisher/batch.rb +309 -0
  16. data/lib/google/cloud/pubsub/batch_publisher.rb +99 -0
  17. data/lib/google/cloud/pubsub/convert.rb +91 -0
  18. data/lib/google/cloud/pubsub/credentials.rb +47 -0
  19. data/lib/google/cloud/pubsub/errors.rb +85 -0
  20. data/lib/google/cloud/pubsub/message.rb +158 -0
  21. data/lib/google/cloud/pubsub/policy.rb +187 -0
  22. data/lib/google/cloud/pubsub/project.rb +393 -0
  23. data/lib/google/cloud/pubsub/publish_result.rb +103 -0
  24. data/lib/google/cloud/pubsub/received_message.rb +297 -0
  25. data/lib/google/cloud/pubsub/retry_policy.rb +90 -0
  26. data/lib/google/cloud/pubsub/service.rb +514 -0
  27. data/lib/google/cloud/pubsub/snapshot.rb +202 -0
  28. data/lib/google/cloud/pubsub/snapshot/list.rb +178 -0
  29. data/lib/google/cloud/pubsub/subscriber.rb +399 -0
  30. data/lib/google/cloud/pubsub/subscriber/enumerator_queue.rb +54 -0
  31. data/lib/google/cloud/pubsub/subscriber/inventory.rb +166 -0
  32. data/lib/google/cloud/pubsub/subscriber/sequencer.rb +115 -0
  33. data/lib/google/cloud/pubsub/subscriber/stream.rb +401 -0
  34. data/lib/google/cloud/pubsub/subscriber/timed_unary_buffer.rb +231 -0
  35. data/lib/google/cloud/pubsub/subscription.rb +1279 -0
  36. data/lib/google/cloud/pubsub/subscription/list.rb +205 -0
  37. data/lib/google/cloud/pubsub/subscription/push_config.rb +244 -0
  38. data/lib/google/cloud/pubsub/topic.rb +934 -0
  39. data/lib/google/cloud/pubsub/topic/list.rb +171 -0
  40. data/lib/google/cloud/pubsub/v1.rb +17 -0
  41. data/lib/google/cloud/pubsub/v1/credentials.rb +41 -0
  42. data/lib/google/cloud/pubsub/v1/doc/google/iam/v1/iam_policy.rb +21 -0
  43. data/lib/google/cloud/pubsub/v1/doc/google/iam/v1/options.rb +21 -0
  44. data/lib/google/cloud/pubsub/v1/doc/google/iam/v1/policy.rb +21 -0
  45. data/lib/google/cloud/pubsub/v1/doc/google/protobuf/duration.rb +91 -0
  46. data/lib/google/cloud/pubsub/v1/doc/google/protobuf/empty.rb +29 -0
  47. data/lib/google/cloud/pubsub/v1/doc/google/protobuf/field_mask.rb +222 -0
  48. data/lib/google/cloud/pubsub/v1/doc/google/protobuf/timestamp.rb +113 -0
  49. data/lib/google/cloud/pubsub/v1/doc/google/pubsub/v1/pubsub.rb +833 -0
  50. data/lib/google/cloud/pubsub/v1/doc/google/type/expr.rb +19 -0
  51. data/lib/google/cloud/pubsub/v1/publisher_client.rb +928 -0
  52. data/lib/google/cloud/pubsub/v1/publisher_client_config.json +120 -0
  53. data/lib/google/cloud/pubsub/v1/subscriber_client.rb +1466 -0
  54. data/lib/google/cloud/pubsub/v1/subscriber_client_config.json +153 -0
  55. data/lib/google/cloud/pubsub/version.rb +24 -0
  56. data/lib/google/pubsub/v1/pubsub_pb.rb +269 -0
  57. data/lib/google/pubsub/v1/pubsub_services_pb.rb +215 -0
  58. metadata +337 -0
@@ -0,0 +1,205 @@
1
+ # Copyright 2015 Google LLC
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
+ # https://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/pubsub"
48
+ #
49
+ # pubsub = Google::Cloud::PubSub.new
50
+ #
51
+ # subscriptions = pubsub.subscriptions
52
+ # if subscriptions.next?
53
+ # next_subscriptions = subscriptions.next
54
+ # end
55
+ #
56
+ def next?
57
+ !token.nil?
58
+ end
59
+
60
+ ##
61
+ # Retrieve the next page of subscriptions.
62
+ #
63
+ # @return [Subscription::List]
64
+ #
65
+ # @example
66
+ # require "google/cloud/pubsub"
67
+ #
68
+ # pubsub = Google::Cloud::PubSub.new
69
+ #
70
+ # subscriptions = pubsub.subscriptions
71
+ # if subscriptions.next?
72
+ # next_subscriptions = subscriptions.next
73
+ # end
74
+ #
75
+ def next
76
+ return nil unless next?
77
+ ensure_service!
78
+ if @topic
79
+ next_topic_subscriptions
80
+ else
81
+ next_subscriptions
82
+ end
83
+ end
84
+
85
+ ##
86
+ # Retrieves remaining results by repeatedly invoking {#next} until
87
+ # {#next?} returns `false`. Calls the given block once for each
88
+ # result, which is passed as the argument to the block.
89
+ #
90
+ # An Enumerator is returned if no block is given.
91
+ #
92
+ # This method will make repeated API calls until all remaining results
93
+ # are retrieved. (Unlike `#each`, for example, which merely iterates
94
+ # over the results returned by a single API call.) Use with caution.
95
+ #
96
+ # @param [Integer] request_limit The upper limit of API requests to
97
+ # make to load all subscriptions. Default is no limit.
98
+ # @yield [subscription] The block for accessing each subscription.
99
+ # @yieldparam [Subscription] subscription The subscription object.
100
+ #
101
+ # @return [Enumerator]
102
+ #
103
+ # @example Iterating each subscription by passing a block:
104
+ # require "google/cloud/pubsub"
105
+ #
106
+ # pubsub = Google::Cloud::PubSub.new
107
+ #
108
+ # subscriptions = pubsub.subscriptions
109
+ # subscriptions.all do |subscription|
110
+ # puts subscription.name
111
+ # end
112
+ #
113
+ # @example Using the enumerator by not passing a block:
114
+ # require "google/cloud/pubsub"
115
+ #
116
+ # pubsub = Google::Cloud::PubSub.new
117
+ #
118
+ # subscriptions = pubsub.subscriptions
119
+ # all_names = subscriptions.all.map do |subscription|
120
+ # subscription.name
121
+ # end
122
+ #
123
+ # @example Limit the number of API calls made:
124
+ # require "google/cloud/pubsub"
125
+ #
126
+ # pubsub = Google::Cloud::PubSub.new
127
+ #
128
+ # subscriptions = pubsub.subscriptions
129
+ # subscriptions.all(request_limit: 10) do |subscription|
130
+ # puts subscription.name
131
+ # end
132
+ #
133
+ def all request_limit: nil
134
+ request_limit = request_limit.to_i if request_limit
135
+ return enum_for :all, request_limit: request_limit unless block_given?
136
+ results = self
137
+ loop do
138
+ results.each { |r| yield r }
139
+ if request_limit
140
+ request_limit -= 1
141
+ break if request_limit.negative?
142
+ end
143
+ break unless results.next?
144
+ results = results.next
145
+ end
146
+ end
147
+
148
+ ##
149
+ # @private New Subscriptions::List from a
150
+ # Google::Cloud::PubSub::V1::ListSubscriptionsRequest object.
151
+ def self.from_grpc grpc_list, service, max = nil
152
+ subs = new(Array(grpc_list.subscriptions).map do |grpc|
153
+ Subscription.from_grpc grpc, service
154
+ end)
155
+ token = grpc_list.next_page_token
156
+ token = nil if token == "".freeze
157
+ subs.instance_variable_set :@token, token
158
+ subs.instance_variable_set :@service, service
159
+ subs.instance_variable_set :@max, max
160
+ subs
161
+ end
162
+
163
+ ##
164
+ # @private New Subscriptions::List from a
165
+ # Google::Cloud::PubSub::V1::ListTopicSubscriptionsResponse object.
166
+ def self.from_topic_grpc grpc_list, service, topic, max = nil
167
+ subs = new(Array(grpc_list.subscriptions).map do |grpc|
168
+ Subscription.from_name grpc, service
169
+ end)
170
+ token = grpc_list.next_page_token
171
+ token = nil if token == "".freeze
172
+ subs.instance_variable_set :@token, token
173
+ subs.instance_variable_set :@service, service
174
+ subs.instance_variable_set :@topic, topic
175
+ subs.instance_variable_set :@max, max
176
+ subs
177
+ end
178
+
179
+ protected
180
+
181
+ ##
182
+ # @private Raise an error unless an active connection to the service
183
+ # is available.
184
+ def ensure_service!
185
+ raise "Must have active connection to service" unless @service
186
+ end
187
+
188
+ def next_subscriptions
189
+ options = { prefix: @prefix, token: @token, max: @max }
190
+ grpc = @service.list_subscriptions options
191
+ self.class.from_grpc grpc, @service, @max
192
+ end
193
+
194
+ def next_topic_subscriptions
195
+ options = { token: @token, max: @max }
196
+ grpc = @service.list_topics_subscriptions @topic, options
197
+ self.class.from_topic_grpc grpc, @service, @topic, @max
198
+ end
199
+ end
200
+ end
201
+ end
202
+
203
+ Pubsub = PubSub unless const_defined? :Pubsub
204
+ end
205
+ end
@@ -0,0 +1,244 @@
1
+ # Copyright 2019 Google LLC
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
+ # https://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/pubsub/v1/pubsub_pb"
17
+
18
+ module Google
19
+ module Cloud
20
+ module PubSub
21
+ class Subscription
22
+ ##
23
+ # Configuration for a push delivery endpoint.
24
+ #
25
+ # @example
26
+ # require "google/cloud/pubsub"
27
+ #
28
+ # pubsub = Google::Cloud::PubSub.new
29
+ #
30
+ # sub = pubsub.subscription "my-topic-sub"
31
+ # sub.push_config.endpoint #=> "http://example.com/callback"
32
+ # sub.push_config.authentication.email #=> "user@example.com"
33
+ # sub.push_config.authentication.audience #=> "client-12345"
34
+ #
35
+ # @example Update the push configuration by passing a block:
36
+ # require "google/cloud/pubsub"
37
+ #
38
+ # pubsub = Google::Cloud::PubSub.new
39
+ # sub = pubsub.subscription "my-subscription"
40
+ #
41
+ # sub.push_config do |pc|
42
+ # pc.endpoint = "http://example.net/callback"
43
+ # pc.set_oidc_token "user@example.net", "client-67890"
44
+ # end
45
+ #
46
+ class PushConfig
47
+ ##
48
+ # @private
49
+ def initialize
50
+ @grpc = Google::Cloud::PubSub::V1::PushConfig.new
51
+ end
52
+
53
+ ##
54
+ # A URL locating the endpoint to which messages should be pushed. For
55
+ # example, a Webhook endpoint might use `https://example.com/push`.
56
+ #
57
+ # @return [String]
58
+ def endpoint
59
+ @grpc.push_endpoint
60
+ end
61
+
62
+ ##
63
+ # Sets the URL locating the endpoint to which messages should be
64
+ # pushed. For example, a Webhook endpoint might use
65
+ # `https://example.com/push`.
66
+ #
67
+ # @param [String, nil] new_endpoint New URL value
68
+ def endpoint= new_endpoint
69
+ @grpc.push_endpoint = String new_endpoint
70
+ end
71
+
72
+ ##
73
+ # The authentication method used by push endpoints to verify the
74
+ # source of push requests.
75
+ #
76
+ # @return [OidcToken, nil] An OIDC JWT token if specified, `nil`
77
+ # otherwise.
78
+ def authentication
79
+ return nil unless @grpc.authentication_method == :oidc_token
80
+
81
+ OidcToken.from_grpc @grpc.oidc_token
82
+ end
83
+
84
+ ##
85
+ # Sets the authentication method used by push endpoints to verify the
86
+ # source of push requests.
87
+ #
88
+ # @param [OidcToken, nil] new_auth An authentication value.
89
+ def authentication= new_auth
90
+ if new_auth.nil?
91
+ @grpc.oidc_token = nil
92
+ else
93
+ raise ArgumentError unless new_auth.is_a? OidcToken
94
+
95
+ @grpc.oidc_token = new_auth.to_grpc
96
+ end
97
+ end
98
+
99
+ ##
100
+ # Checks whether authentication is an {OidcToken}.
101
+ #
102
+ # @return [Boolean]
103
+ def oidc_token?
104
+ authentication.is_a? OidcToken
105
+ end
106
+
107
+ ##
108
+ # Sets the authentication method to use an {OidcToken}.
109
+ #
110
+ # @param [String] email Service account email.
111
+ # @param [String] audience Audience to be used.
112
+ def set_oidc_token email, audience
113
+ oidc_token = OidcToken.new.tap do |token|
114
+ token.email = email
115
+ token.audience = audience
116
+ end
117
+ self.authentication = oidc_token
118
+ end
119
+
120
+ ##
121
+ # The format of the pushed message. This attribute indicates the
122
+ # version of the data expected by the endpoint. This controls the
123
+ # shape of the pushed message (i.e., its fields and metadata). The
124
+ # endpoint version is based on the version of the Pub/Sub API.
125
+ #
126
+ # If not present during the Subscription creation, it will default to
127
+ # the version of the API used to make such call.
128
+ #
129
+ # The possible values for this attribute are:
130
+ #
131
+ # * `v1beta1`: uses the push format defined in the v1beta1 Pub/Sub
132
+ # API.
133
+ # * `v1` or `v1beta2`: uses the push format defined in the v1 Pub/Sub
134
+ # API.
135
+ #
136
+ # @return [String]
137
+ def version
138
+ @grpc.attributes["x-goog-version"]
139
+ end
140
+
141
+ ##
142
+ # Sets the format of the pushed message.
143
+ #
144
+ # The possible values for this attribute are:
145
+ #
146
+ # * `v1beta1`: uses the push format defined in the v1beta1 Pub/Sub
147
+ # API.
148
+ # * `v1` or `v1beta2`: uses the push format defined in the v1 Pub/Sub
149
+ # API.
150
+ #
151
+ # @param [String, nil] new_version The new version value.
152
+ def version= new_version
153
+ if new_version.nil?
154
+ @grpc.attributes.delete "x-goog-version"
155
+ else
156
+ @grpc.attributes["x-goog-version"] = new_version
157
+ end
158
+ end
159
+
160
+ ##
161
+ # @private
162
+ def to_grpc
163
+ @grpc
164
+ end
165
+
166
+ ##
167
+ # @private
168
+ def self.from_grpc grpc
169
+ new.tap do |pc|
170
+ pc.instance_variable_set :@grpc, grpc.dup if grpc
171
+ end
172
+ end
173
+
174
+ ##
175
+ # Contains information needed for generating an [OpenID Connect
176
+ # token](https://developers.google.com/identity/protocols/OpenIDConnect).
177
+ class OidcToken
178
+ ##
179
+ # @private
180
+ def initialize
181
+ @grpc = Google::Cloud::PubSub::V1::PushConfig::OidcToken.new
182
+ end
183
+
184
+ ##
185
+ # Service account email to be used for generating the OIDC token.
186
+ #
187
+ # @return [String]
188
+ def email
189
+ @grpc.service_account_email
190
+ end
191
+
192
+ ##
193
+ # Service account email to be used for generating the OIDC token.
194
+ #
195
+ # @param [String] new_email New service account email value.
196
+ def email= new_email
197
+ @grpc.service_account_email = new_email
198
+ end
199
+
200
+ ##
201
+ # Audience to be used when generating OIDC token. The audience claim
202
+ # identifies the recipients that the JWT is intended for. The
203
+ # audience value is a single case-sensitive string.
204
+ #
205
+ # Having multiple values (array) for the audience field is not
206
+ # supported.
207
+ #
208
+ # More info about the OIDC JWT token audience here:
209
+ # https://tools.ietf.org/html/rfc7519#section-4.1.3
210
+ #
211
+ # @return [String]
212
+ def audience
213
+ @grpc.audience
214
+ end
215
+
216
+ ##
217
+ # Sets the audience to be used when generating OIDC token.
218
+ #
219
+ # @param [String] new_audience New audience value.
220
+ def audience= new_audience
221
+ @grpc.audience = new_audience
222
+ end
223
+
224
+ ##
225
+ # @private
226
+ def to_grpc
227
+ @grpc
228
+ end
229
+
230
+ ##
231
+ # @private
232
+ def self.from_grpc grpc
233
+ grpc ||= Google::Cloud::PubSub::V1::PushConfig::OidcToken.new
234
+
235
+ new.tap do |pc|
236
+ pc.instance_variable_set :@grpc, grpc.dup
237
+ end
238
+ end
239
+ end
240
+ end
241
+ end
242
+ end
243
+ end
244
+ end
@@ -0,0 +1,934 @@
1
+ # Copyright 2015 Google LLC
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
+ # https://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/list"
18
+ require "google/cloud/pubsub/async_publisher"
19
+ require "google/cloud/pubsub/batch_publisher"
20
+ require "google/cloud/pubsub/subscription"
21
+ require "google/cloud/pubsub/policy"
22
+ require "google/cloud/pubsub/retry_policy"
23
+
24
+ module Google
25
+ module Cloud
26
+ module PubSub
27
+ ##
28
+ # # Topic
29
+ #
30
+ # A named resource to which messages are published.
31
+ #
32
+ # See {Project#create_topic} and {Project#topic}.
33
+ #
34
+ # @example
35
+ # require "google/cloud/pubsub"
36
+ #
37
+ # pubsub = Google::Cloud::PubSub.new
38
+ #
39
+ # topic = pubsub.topic "my-topic"
40
+ # topic.publish "task completed"
41
+ #
42
+ class Topic
43
+ ##
44
+ # @private The Service object.
45
+ attr_accessor :service
46
+
47
+ ##
48
+ # @private The Google::Cloud::PubSub::V1::Topic object.
49
+ attr_accessor :grpc
50
+
51
+ ##
52
+ # @private Create an empty {Topic} object.
53
+ def initialize
54
+ @service = nil
55
+ @grpc = nil
56
+ @resource_name = nil
57
+ @exists = nil
58
+ @async_opts = {}
59
+ end
60
+
61
+ ##
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.wait!
82
+ #
83
+ def async_publisher
84
+ @async_publisher
85
+ end
86
+
87
+ ##
88
+ # The name of the topic in the form of
89
+ # "/projects/project-identifier/topics/topic-name".
90
+ #
91
+ # @return [String]
92
+ #
93
+ def 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
+ # Permanently deletes the topic.
238
+ #
239
+ # @return [Boolean] Returns `true` if the topic was deleted.
240
+ #
241
+ # @example
242
+ # require "google/cloud/pubsub"
243
+ #
244
+ # pubsub = Google::Cloud::PubSub.new
245
+ #
246
+ # topic = pubsub.topic "my-topic"
247
+ # topic.delete
248
+ #
249
+ def delete
250
+ ensure_service!
251
+ service.delete_topic name
252
+ true
253
+ end
254
+
255
+ ##
256
+ # Creates a new {Subscription} object on the current Topic.
257
+ #
258
+ # @param [String] subscription_name Name of the new subscription. Must
259
+ # start with a letter, and contain only letters ([A-Za-z]), numbers
260
+ # ([0-9], dashes (-), underscores (_), periods (.), tildes (~), plus
261
+ # (+) or percent signs (%). It must be between 3 and 255 characters in
262
+ # length, and it must not start with "goog". Required.
263
+ # @param [Integer] deadline The maximum number of seconds after a
264
+ # subscriber receives a message before the subscriber should
265
+ # acknowledge the message.
266
+ # @param [Boolean] retain_acked Indicates whether to retain acknowledged
267
+ # messages. If `true`, then messages are not expunged from the
268
+ # subscription's backlog, even if they are acknowledged, until they
269
+ # fall out of the `retention` window. Default is `false`.
270
+ # @param [Numeric] retention How long to retain unacknowledged messages
271
+ # in the subscription's backlog, from the moment a message is
272
+ # published. If `retain_acked` is `true`, then this also configures
273
+ # the retention of acknowledged messages, and thus configures how far
274
+ # back in time a {Subscription#seek} can be done. Cannot be more than
275
+ # 604,800 seconds (7 days) or less than 600 seconds (10 minutes).
276
+ # Default is 604,800 seconds (7 days).
277
+ # @param [String] endpoint A URL locating the endpoint to which messages
278
+ # should be pushed.
279
+ # @param [Hash] labels A hash of user-provided labels associated with
280
+ # the subscription. You can use these to organize and group your
281
+ # subscriptions. Label keys and values can be no longer than 63
282
+ # characters, can only contain lowercase letters, numeric characters,
283
+ # underscores and dashes. International characters are allowed. Label
284
+ # values are optional. Label keys must start with a letter and each
285
+ # label in the list must have a different key. See [Creating and
286
+ # Managing Labels](https://cloud.google.com/pubsub/docs/labels).
287
+ # @param [Boolean] message_ordering Whether to enable message ordering
288
+ # on the subscription.
289
+ # @param [String] filter An expression written in the Cloud Pub/Sub filter language. If non-empty, then only
290
+ # {Message} instances whose `attributes` field matches the filter are delivered on this subscription. If
291
+ # empty, then no messages are filtered out. Optional.
292
+ # @param [Topic] dead_letter_topic The {Topic} to which dead letter messages for the subscription should be
293
+ # published. Dead lettering is done on a best effort basis. The same message might be dead lettered multiple
294
+ # times. The Cloud Pub/Sub service account associated with the enclosing subscription's parent project (i.e.,
295
+ # `service-\\{project_number}@gcp-sa-pubsub.iam.gserviceaccount.com`) must have permission to Publish() to
296
+ # this topic.
297
+ #
298
+ # The operation will fail if the topic does not exist. Users should ensure that there is a subscription
299
+ # attached to this topic since messages published to a topic with no subscriptions are lost.
300
+ # @param [Integer] dead_letter_max_delivery_attempts The maximum number of delivery attempts for any message in
301
+ # the subscription's dead letter policy. Dead lettering is done on a best effort basis. The same message might
302
+ # be dead lettered multiple times. The value must be between 5 and 100. If this parameter is 0, a default
303
+ # value of 5 is used. The `dead_letter_topic` must also be set.
304
+ # @param [RetryPolicy] retry_policy A policy that specifies how Cloud Pub/Sub retries message delivery for
305
+ # this subscription. If not set, the default retry policy is applied. This generally implies that messages
306
+ # will be retried as soon as possible for healthy subscribers. Retry Policy will be triggered on NACKs or
307
+ # acknowledgement deadline exceeded events for a given message.
308
+ #
309
+ # **EXPERIMENTAL:** This API might be changed in backward-incompatible ways and is not recommended for
310
+ # production use. It is not subject to any SLA or deprecation policy.
311
+ #
312
+ # @return [Google::Cloud::PubSub::Subscription]
313
+ #
314
+ # @example
315
+ # require "google/cloud/pubsub"
316
+ #
317
+ # pubsub = Google::Cloud::PubSub.new
318
+ #
319
+ # topic = pubsub.topic "my-topic"
320
+ # sub = topic.subscribe "my-topic-sub"
321
+ # sub.name # => "my-topic-sub"
322
+ #
323
+ # @example Wait 2 minutes for acknowledgement and push all to endpoint:
324
+ # require "google/cloud/pubsub"
325
+ #
326
+ # pubsub = Google::Cloud::PubSub.new
327
+ #
328
+ # topic = pubsub.topic "my-topic"
329
+ # sub = topic.subscribe "my-topic-sub",
330
+ # deadline: 120,
331
+ # endpoint: "https://example.com/push"
332
+ #
333
+ # @example Configure a Dead Letter Queues policy:
334
+ # require "google/cloud/pubsub"
335
+ #
336
+ # pubsub = Google::Cloud::PubSub.new
337
+ #
338
+ # # Dead Letter Queue (DLQ) testing requires IAM bindings to the Cloud Pub/Sub service account that is
339
+ # # automatically created and managed by the service team in a private project.
340
+ # my_project_number = "000000000000"
341
+ # service_account_email = "serviceAccount:service-#{my_project_number}@gcp-sa-pubsub.iam.gserviceaccount.com"
342
+ #
343
+ # dead_letter_topic = pubsub.topic "my-dead-letter-topic"
344
+ # dead_letter_subscription = dead_letter_topic.subscribe "my-dead-letter-sub"
345
+ #
346
+ # dead_letter_topic.policy { |p| p.add "roles/pubsub.publisher", service_account_email }
347
+ # dead_letter_subscription.policy { |p| p.add "roles/pubsub.subscriber", service_account_email }
348
+ #
349
+ # topic = pubsub.topic "my-topic"
350
+ # sub = topic.subscribe "my-topic-sub",
351
+ # dead_letter_topic: dead_letter_topic,
352
+ # dead_letter_max_delivery_attempts: 10
353
+ #
354
+ # @example Configure a Retry Policy:
355
+ # require "google/cloud/pubsub"
356
+ #
357
+ # pubsub = Google::Cloud::PubSub.new
358
+ #
359
+ # topic = pubsub.topic "my-topic"
360
+ #
361
+ # retry_policy = Google::Cloud::PubSub::RetryPolicy.new minimum_backoff: 5, maximum_backoff: 300
362
+ # sub = topic.subscribe "my-topic-sub", retry_policy: retry_policy
363
+ #
364
+ def subscribe subscription_name, deadline: nil, retain_acked: false, retention: nil, endpoint: nil, labels: nil,
365
+ message_ordering: nil, filter: nil, dead_letter_topic: nil,
366
+ dead_letter_max_delivery_attempts: nil, retry_policy: nil
367
+ ensure_service!
368
+ options = { deadline: deadline, retain_acked: retain_acked, retention: retention, endpoint: endpoint,
369
+ labels: labels, message_ordering: message_ordering, filter: filter,
370
+ dead_letter_max_delivery_attempts: dead_letter_max_delivery_attempts }
371
+ options[:dead_letter_topic_name] = dead_letter_topic.name if dead_letter_topic
372
+ if options[:dead_letter_max_delivery_attempts] && !options[:dead_letter_topic_name]
373
+ # Service error message "3:Invalid resource name given (name=)." does not identify param.
374
+ raise ArgumentError, "dead_letter_topic is required with dead_letter_max_delivery_attempts"
375
+ end
376
+ options[:retry_policy] = retry_policy.to_grpc if retry_policy
377
+ grpc = service.create_subscription name, subscription_name, options
378
+ Subscription.from_grpc grpc, service
379
+ end
380
+ alias create_subscription subscribe
381
+ alias new_subscription subscribe
382
+
383
+ ##
384
+ # Retrieves subscription by name.
385
+ #
386
+ # @param [String] subscription_name Name of a subscription.
387
+ # @param [Boolean] skip_lookup Optionally create a {Subscription} object
388
+ # without verifying the subscription resource exists on the Pub/Sub
389
+ # service. Calls made on this object will raise errors if the service
390
+ # resource does not exist. Default is `false`.
391
+ #
392
+ # @return [Google::Cloud::PubSub::Subscription, nil] Returns `nil` if
393
+ # the subscription does not exist.
394
+ #
395
+ # @example
396
+ # require "google/cloud/pubsub"
397
+ #
398
+ # pubsub = Google::Cloud::PubSub.new
399
+ #
400
+ # topic = pubsub.topic "my-topic"
401
+ #
402
+ # sub = topic.subscription "my-topic-sub"
403
+ # sub.name #=> "projects/my-project/subscriptions/my-topic-sub"
404
+ #
405
+ # @example Skip the lookup against the service with `skip_lookup`:
406
+ # require "google/cloud/pubsub"
407
+ #
408
+ # pubsub = Google::Cloud::PubSub.new
409
+ #
410
+ # topic = pubsub.topic "my-topic"
411
+ #
412
+ # # No API call is made to retrieve the subscription information.
413
+ # sub = topic.subscription "my-topic-sub", skip_lookup: true
414
+ # sub.name #=> "projects/my-project/subscriptions/my-topic-sub"
415
+ #
416
+ def subscription subscription_name, skip_lookup: nil
417
+ ensure_service!
418
+ return Subscription.from_name subscription_name, service if skip_lookup
419
+ grpc = service.get_subscription subscription_name
420
+ Subscription.from_grpc grpc, service
421
+ rescue Google::Cloud::NotFoundError
422
+ nil
423
+ end
424
+ alias get_subscription subscription
425
+ alias find_subscription subscription
426
+
427
+ ##
428
+ # Retrieves a list of subscription names for the given project.
429
+ #
430
+ # @param [String] token The `token` value returned by the last call to
431
+ # `subscriptions`; indicates that this is a continuation of a call,
432
+ # and that the system should return the next page of data.
433
+ # @param [Integer] max Maximum number of subscriptions to return.
434
+ #
435
+ # @return [Array<Subscription>] (See {Subscription::List})
436
+ #
437
+ # @example
438
+ # require "google/cloud/pubsub"
439
+ #
440
+ # pubsub = Google::Cloud::PubSub.new
441
+ #
442
+ # topic = pubsub.topic "my-topic"
443
+ # subscriptions = topic.subscriptions
444
+ # subscriptions.each do |subscription|
445
+ # puts subscription.name
446
+ # end
447
+ #
448
+ # @example Retrieve all subscriptions: (See {Subscription::List#all})
449
+ # require "google/cloud/pubsub"
450
+ #
451
+ # pubsub = Google::Cloud::PubSub.new
452
+ #
453
+ # topic = pubsub.topic "my-topic"
454
+ # subscriptions = topic.subscriptions
455
+ # subscriptions.all do |subscription|
456
+ # puts subscription.name
457
+ # end
458
+ #
459
+ def subscriptions token: nil, max: nil
460
+ ensure_service!
461
+ options = { token: token, max: max }
462
+ grpc = service.list_topics_subscriptions name, options
463
+ Subscription::List.from_topic_grpc grpc, service, name, max
464
+ end
465
+ alias find_subscriptions subscriptions
466
+ alias list_subscriptions subscriptions
467
+
468
+ ##
469
+ # Publishes one or more messages to the topic.
470
+ #
471
+ # The message payload must not be empty; it must contain either a
472
+ # non-empty data field, or at least one attribute.
473
+ #
474
+ # @param [String, File] data The message payload. This will be converted
475
+ # to bytes encoded as ASCII-8BIT.
476
+ # @param [Hash] attributes Optional attributes for the message.
477
+ # @yield [batch] a block for publishing multiple messages in one
478
+ # request
479
+ # @yieldparam [BatchPublisher] batch the topic batch publisher
480
+ # object
481
+ #
482
+ # @return [Message, Array<Message>] Returns the published message when
483
+ # called without a block, or an array of messages when called with a
484
+ # block.
485
+ #
486
+ # @example
487
+ # require "google/cloud/pubsub"
488
+ #
489
+ # pubsub = Google::Cloud::PubSub.new
490
+ #
491
+ # topic = pubsub.topic "my-topic"
492
+ # msg = topic.publish "task completed"
493
+ #
494
+ # @example A message can be published using a File object:
495
+ # require "google/cloud/pubsub"
496
+ #
497
+ # pubsub = Google::Cloud::PubSub.new
498
+ #
499
+ # topic = pubsub.topic "my-topic"
500
+ # file = File.open "message.txt", mode: "rb"
501
+ # msg = topic.publish file
502
+ #
503
+ # @example Additionally, a message can be published with attributes:
504
+ # require "google/cloud/pubsub"
505
+ #
506
+ # pubsub = Google::Cloud::PubSub.new
507
+ #
508
+ # topic = pubsub.topic "my-topic"
509
+ # msg = topic.publish "task completed",
510
+ # foo: :bar,
511
+ # this: :that
512
+ #
513
+ # @example Multiple messages can be sent at the same time using a block:
514
+ # require "google/cloud/pubsub"
515
+ #
516
+ # pubsub = Google::Cloud::PubSub.new
517
+ #
518
+ # topic = pubsub.topic "my-topic"
519
+ # msgs = topic.publish do |t|
520
+ # t.publish "task 1 completed", foo: :bar
521
+ # t.publish "task 2 completed", foo: :baz
522
+ # t.publish "task 3 completed", foo: :bif
523
+ # end
524
+ #
525
+ def publish data = nil, attributes = {}
526
+ ensure_service!
527
+ batch = BatchPublisher.new data, attributes
528
+ yield batch if block_given?
529
+ return nil if batch.messages.count.zero?
530
+ publish_batch_messages batch
531
+ end
532
+
533
+ ##
534
+ # Publishes a message asynchronously to the topic using
535
+ # {#async_publisher}.
536
+ #
537
+ # The message payload must not be empty; it must contain either a
538
+ # non-empty data field, or at least one attribute.
539
+ #
540
+ # Google Cloud Pub/Sub ordering keys provide the ability to ensure
541
+ # related messages are sent to subscribers in the order in which they
542
+ # were published. Messages can be tagged with an ordering key, a string
543
+ # that identifies related messages for which publish order should be
544
+ # respected. The service guarantees that, for a given ordering key and
545
+ # publisher, messages are sent to subscribers in the order in which they
546
+ # were published. Ordering does not require sacrificing high throughput
547
+ # or scalability, as the service automatically distributes messages for
548
+ # different ordering keys across subscribers.
549
+ #
550
+ # To use ordering keys, specify `ordering_key`. Before specifying
551
+ # `ordering_key` on a message a call to `#enable_message_ordering!` must
552
+ # be made or an error will be raised.
553
+ #
554
+ # @note At the time of this release, ordering keys are not yet publicly
555
+ # enabled and requires special project enablements.
556
+ #
557
+ # @param [String, File] data The message payload. This will be converted
558
+ # to bytes encoded as ASCII-8BIT.
559
+ # @param [Hash] attributes Optional attributes for the message.
560
+ # @param [String] ordering_key Identifies related messages for which
561
+ # publish order should be respected.
562
+ # @yield [result] the callback for when the message has been published
563
+ # @yieldparam [PublishResult] result the result of the asynchronous
564
+ # publish
565
+ # @raise [Google::Cloud::PubSub::AsyncPublisherStopped] when the
566
+ # publisher is stopped. (See {AsyncPublisher#stop} and
567
+ # {AsyncPublisher#stopped?}.)
568
+ # @raise [Google::Cloud::PubSub::OrderedMessagesDisabled] when
569
+ # publishing a message with an `ordering_key` but ordered messages are
570
+ # not enabled. (See {#message_ordering?} and
571
+ # {#enable_message_ordering!}.)
572
+ # @raise [Google::Cloud::PubSub::OrderingKeyError] when publishing a
573
+ # message with an `ordering_key` that has already failed when
574
+ # publishing. Use {#resume_publish} to allow this `ordering_key` to be
575
+ # published again.
576
+ #
577
+ # @example
578
+ # require "google/cloud/pubsub"
579
+ #
580
+ # pubsub = Google::Cloud::PubSub.new
581
+ #
582
+ # topic = pubsub.topic "my-topic"
583
+ # topic.publish_async "task completed" do |result|
584
+ # if result.succeeded?
585
+ # log_publish_success result.data
586
+ # else
587
+ # log_publish_failure result.data, result.error
588
+ # end
589
+ # end
590
+ #
591
+ # # Shut down the publisher when ready to stop publishing messages.
592
+ # topic.async_publisher.stop.wait!
593
+ #
594
+ # @example A message can be published using a File object:
595
+ # require "google/cloud/pubsub"
596
+ #
597
+ # pubsub = Google::Cloud::PubSub.new
598
+ #
599
+ # topic = pubsub.topic "my-topic"
600
+ # file = File.open "message.txt", mode: "rb"
601
+ # topic.publish_async file
602
+ #
603
+ # # Shut down the publisher when ready to stop publishing messages.
604
+ # topic.async_publisher.stop.wait!
605
+ #
606
+ # @example Additionally, a message can be published with attributes:
607
+ # require "google/cloud/pubsub"
608
+ #
609
+ # pubsub = Google::Cloud::PubSub.new
610
+ #
611
+ # topic = pubsub.topic "my-topic"
612
+ # topic.publish_async "task completed",
613
+ # foo: :bar, this: :that
614
+ #
615
+ # # Shut down the publisher when ready to stop publishing messages.
616
+ # topic.async_publisher.stop.wait!
617
+ #
618
+ # @example Ordered messages are supported using ordering_key:
619
+ # require "google/cloud/pubsub"
620
+ #
621
+ # pubsub = Google::Cloud::PubSub.new
622
+ #
623
+ # topic = pubsub.topic "my-ordered-topic"
624
+ #
625
+ # # Ensure that message ordering is enabled.
626
+ # topic.enable_message_ordering!
627
+ #
628
+ # # Publish an ordered message with an ordering key.
629
+ # topic.publish_async "task completed",
630
+ # ordering_key: "task-key"
631
+ #
632
+ # # Shut down the publisher when ready to stop publishing messages.
633
+ # topic.async_publisher.stop.wait!
634
+ #
635
+ def publish_async data = nil, attributes = nil, ordering_key: nil, **extra_attrs, &callback
636
+ ensure_service!
637
+
638
+ @async_publisher ||= AsyncPublisher.new name, service, @async_opts
639
+ @async_publisher.publish data, attributes, ordering_key: ordering_key, **extra_attrs, &callback
640
+ end
641
+
642
+ ##
643
+ # Enables message ordering for messages with ordering keys on the
644
+ # {#async_publisher}. When enabled, messages published with the same
645
+ # `ordering_key` will be delivered in the order they were published.
646
+ #
647
+ # @note At the time of this release, ordering keys are not yet publicly
648
+ # enabled and requires special project enablements.
649
+ #
650
+ # See {#message_ordering?}. See {#publish_async},
651
+ # {Subscription#listen}, and {Message#ordering_key}.
652
+ #
653
+ def enable_message_ordering!
654
+ @async_publisher ||= AsyncPublisher.new name, service, @async_opts
655
+ @async_publisher.enable_message_ordering!
656
+ end
657
+
658
+ ##
659
+ # Whether message ordering for messages with ordering keys has been
660
+ # enabled on the {#async_publisher}. When enabled, messages published
661
+ # with the same `ordering_key` will be delivered in the order they were
662
+ # published. When disabled, messages may be delivered in any order.
663
+ #
664
+ # See {#enable_message_ordering!}. See {#publish_async},
665
+ # {Subscription#listen}, and {Message#ordering_key}.
666
+ #
667
+ # @return [Boolean]
668
+ #
669
+ def message_ordering?
670
+ @async_publisher ||= AsyncPublisher.new name, service, @async_opts
671
+ @async_publisher.message_ordering?
672
+ end
673
+
674
+ ##
675
+ # Resume publishing ordered messages for the provided ordering key.
676
+ #
677
+ # @param [String] ordering_key Identifies related messages for which
678
+ # publish order should be respected.
679
+ #
680
+ # @return [boolean] `true` when resumed, `false` otherwise.
681
+ #
682
+ def resume_publish ordering_key
683
+ @async_publisher ||= AsyncPublisher.new name, service, @async_opts
684
+ @async_publisher.resume_publish ordering_key
685
+ end
686
+
687
+ ##
688
+ # Gets the [Cloud IAM](https://cloud.google.com/iam/) access control
689
+ # policy for this topic.
690
+ #
691
+ # @see https://cloud.google.com/pubsub/docs/reference/rpc/google.iam.v1#iampolicy
692
+ # google.iam.v1.IAMPolicy
693
+ #
694
+ # @yield [policy] A block for updating the policy. The latest policy
695
+ # will be read from the Pub/Sub service and passed to the block. After
696
+ # the block completes, the modified policy will be written to the
697
+ # service.
698
+ # @yieldparam [Policy] policy the current Cloud IAM Policy for this
699
+ # topic
700
+ #
701
+ # @return [Policy] the current Cloud IAM Policy for this topic
702
+ #
703
+ # @example
704
+ # require "google/cloud/pubsub"
705
+ #
706
+ # pubsub = Google::Cloud::PubSub.new
707
+ # topic = pubsub.topic "my-topic"
708
+ #
709
+ # policy = topic.policy
710
+ #
711
+ # @example Update the policy by passing a block:
712
+ # require "google/cloud/pubsub"
713
+ #
714
+ # pubsub = Google::Cloud::PubSub.new
715
+ # topic = pubsub.topic "my-topic"
716
+ #
717
+ # topic.policy do |p|
718
+ # p.add "roles/owner", "user:owner@example.com"
719
+ # end
720
+ #
721
+ def policy
722
+ ensure_service!
723
+ grpc = service.get_topic_policy name
724
+ policy = Policy.from_grpc grpc
725
+ return policy unless block_given?
726
+ yield policy
727
+ update_policy policy
728
+ end
729
+
730
+ ##
731
+ # Updates the [Cloud IAM](https://cloud.google.com/iam/) access control
732
+ # policy for this topic. The policy should be read from {#policy}. See
733
+ # {Google::Cloud::PubSub::Policy} for an explanation of the policy
734
+ # `etag` property and how to modify policies.
735
+ #
736
+ # You can also update the policy by passing a block to {#policy}, which
737
+ # will call this method internally after the block completes.
738
+ #
739
+ # @see https://cloud.google.com/pubsub/docs/reference/rpc/google.iam.v1#iampolicy
740
+ # google.iam.v1.IAMPolicy
741
+ #
742
+ # @param [Policy] new_policy a new or modified Cloud IAM Policy for this
743
+ # topic
744
+ #
745
+ # @return [Policy] the policy returned by the API update operation
746
+ #
747
+ # @example
748
+ # require "google/cloud/pubsub"
749
+ #
750
+ # pubsub = Google::Cloud::PubSub.new
751
+ # topic = pubsub.topic "my-topic"
752
+ #
753
+ # policy = topic.policy # API call
754
+ #
755
+ # policy.add "roles/owner", "user:owner@example.com"
756
+ #
757
+ # topic.update_policy policy # API call
758
+ #
759
+ def update_policy new_policy
760
+ ensure_service!
761
+ grpc = service.set_topic_policy name, new_policy.to_grpc
762
+ @policy = Policy.from_grpc grpc
763
+ end
764
+ alias policy= update_policy
765
+
766
+ ##
767
+ # Tests the specified permissions against the [Cloud
768
+ # IAM](https://cloud.google.com/iam/) access control policy.
769
+ #
770
+ # @see https://cloud.google.com/iam/docs/managing-policies Managing
771
+ # Policies
772
+ #
773
+ # @param [String, Array<String>] permissions The set of permissions to
774
+ # check access for. Permissions with wildcards (such as `*` or
775
+ # `storage.*`) are not allowed.
776
+ #
777
+ # The permissions that can be checked on a topic are:
778
+ #
779
+ # * pubsub.topics.publish
780
+ # * pubsub.topics.attachSubscription
781
+ # * pubsub.topics.get
782
+ # * pubsub.topics.delete
783
+ # * pubsub.topics.update
784
+ # * pubsub.topics.getIamPolicy
785
+ # * pubsub.topics.setIamPolicy
786
+ #
787
+ # @return [Array<Strings>] The permissions that have access.
788
+ #
789
+ # @example
790
+ # require "google/cloud/pubsub"
791
+ #
792
+ # pubsub = Google::Cloud::PubSub.new
793
+ # topic = pubsub.topic "my-topic"
794
+ # perms = topic.test_permissions "pubsub.topics.get",
795
+ # "pubsub.topics.publish"
796
+ # perms.include? "pubsub.topics.get" #=> true
797
+ # perms.include? "pubsub.topics.publish" #=> false
798
+ #
799
+ def test_permissions *permissions
800
+ permissions = Array(permissions).flatten
801
+ permissions = Array(permissions).flatten
802
+ ensure_service!
803
+ grpc = service.test_topic_permissions name, permissions
804
+ grpc.permissions
805
+ end
806
+
807
+ ##
808
+ # Determines whether the topic exists in the Pub/Sub service.
809
+ #
810
+ # @example
811
+ # require "google/cloud/pubsub"
812
+ #
813
+ # pubsub = Google::Cloud::PubSub.new
814
+ #
815
+ # topic = pubsub.topic "my-topic"
816
+ # topic.exists? #=> true
817
+ #
818
+ def exists?
819
+ # Always true if the object is not set as reference
820
+ return true unless reference?
821
+ # If we have a value, return it
822
+ return @exists unless @exists.nil?
823
+ ensure_grpc!
824
+ @exists = true
825
+ rescue Google::Cloud::NotFoundError
826
+ @exists = false
827
+ end
828
+
829
+ ##
830
+ # Determines whether the topic object was created without retrieving the
831
+ # resource representation from the Pub/Sub service.
832
+ #
833
+ # @return [Boolean] `true` when the topic was created without a resource
834
+ # representation, `false` otherwise.
835
+ #
836
+ # @example
837
+ # require "google/cloud/pubsub"
838
+ #
839
+ # pubsub = Google::Cloud::PubSub.new
840
+ #
841
+ # topic = pubsub.topic "my-topic", skip_lookup: true
842
+ # topic.reference? #=> true
843
+ #
844
+ def reference?
845
+ @grpc.nil?
846
+ end
847
+
848
+ ##
849
+ # Determines whether the topic object was created with a resource
850
+ # representation from the Pub/Sub service.
851
+ #
852
+ # @return [Boolean] `true` when the topic was created with a resource
853
+ # representation, `false` otherwise.
854
+ #
855
+ # @example
856
+ # require "google/cloud/pubsub"
857
+ #
858
+ # pubsub = Google::Cloud::PubSub.new
859
+ #
860
+ # topic = pubsub.topic "my-topic"
861
+ # topic.resource? #=> true
862
+ #
863
+ def resource?
864
+ !@grpc.nil?
865
+ end
866
+
867
+ ##
868
+ # Reloads the topic with current data from the Pub/Sub service.
869
+ #
870
+ # @return [Google::Cloud::PubSub::Topic] Returns the reloaded topic
871
+ #
872
+ # @example
873
+ # require "google/cloud/pubsub"
874
+ #
875
+ # pubsub = Google::Cloud::PubSub.new
876
+ #
877
+ # topic = pubsub.topic "my-topic"
878
+ # topic.reload!
879
+ #
880
+ def reload!
881
+ ensure_service!
882
+ @grpc = service.get_topic name
883
+ @resource_name = nil
884
+ self
885
+ end
886
+ alias refresh! reload!
887
+
888
+ ##
889
+ # @private New Topic from a Google::Cloud::PubSub::V1::Topic object.
890
+ def self.from_grpc grpc, service, async: nil
891
+ new.tap do |t|
892
+ t.grpc = grpc
893
+ t.service = service
894
+ t.instance_variable_set :@async_opts, async if async
895
+ end
896
+ end
897
+
898
+ ##
899
+ # @private New reference {Topic} object without making an HTTP request.
900
+ def self.from_name name, service, options = {}
901
+ name = service.topic_path name, options
902
+ from_grpc(nil, service).tap do |t|
903
+ t.instance_variable_set :@resource_name, name
904
+ end
905
+ end
906
+
907
+ protected
908
+
909
+ ##
910
+ # @private Raise an error unless an active connection to the service is
911
+ # available.
912
+ def ensure_service!
913
+ raise "Must have active connection to service" unless service
914
+ end
915
+
916
+ ##
917
+ # Ensures a Google::Cloud::PubSub::V1::Topic object exists.
918
+ def ensure_grpc!
919
+ ensure_service!
920
+ reload! if reference?
921
+ end
922
+
923
+ ##
924
+ # Call the publish API with arrays of data data and attrs.
925
+ def publish_batch_messages batch
926
+ grpc = service.publish name, batch.messages
927
+ batch.to_gcloud_messages Array(grpc.message_ids)
928
+ end
929
+ end
930
+ end
931
+
932
+ Pubsub = PubSub unless const_defined? :Pubsub
933
+ end
934
+ end