google-cloud-pubsub 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
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