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.
- checksums.yaml +7 -0
- data/.yardopts +18 -0
- data/AUTHENTICATION.md +177 -0
- data/CHANGELOG.md +538 -0
- data/CODE_OF_CONDUCT.md +40 -0
- data/CONTRIBUTING.md +188 -0
- data/EMULATOR.md +37 -0
- data/LICENSE +201 -0
- data/LOGGING.md +32 -0
- data/OVERVIEW.md +557 -0
- data/TROUBLESHOOTING.md +31 -0
- data/lib/google-cloud-pubsub.rb +139 -0
- data/lib/google/cloud/pubsub.rb +173 -0
- data/lib/google/cloud/pubsub/async_publisher.rb +399 -0
- data/lib/google/cloud/pubsub/async_publisher/batch.rb +309 -0
- data/lib/google/cloud/pubsub/batch_publisher.rb +99 -0
- data/lib/google/cloud/pubsub/convert.rb +91 -0
- data/lib/google/cloud/pubsub/credentials.rb +47 -0
- data/lib/google/cloud/pubsub/errors.rb +85 -0
- data/lib/google/cloud/pubsub/message.rb +158 -0
- data/lib/google/cloud/pubsub/policy.rb +187 -0
- data/lib/google/cloud/pubsub/project.rb +393 -0
- data/lib/google/cloud/pubsub/publish_result.rb +103 -0
- data/lib/google/cloud/pubsub/received_message.rb +297 -0
- data/lib/google/cloud/pubsub/retry_policy.rb +90 -0
- data/lib/google/cloud/pubsub/service.rb +514 -0
- data/lib/google/cloud/pubsub/snapshot.rb +202 -0
- data/lib/google/cloud/pubsub/snapshot/list.rb +178 -0
- data/lib/google/cloud/pubsub/subscriber.rb +399 -0
- data/lib/google/cloud/pubsub/subscriber/enumerator_queue.rb +54 -0
- data/lib/google/cloud/pubsub/subscriber/inventory.rb +166 -0
- data/lib/google/cloud/pubsub/subscriber/sequencer.rb +115 -0
- data/lib/google/cloud/pubsub/subscriber/stream.rb +401 -0
- data/lib/google/cloud/pubsub/subscriber/timed_unary_buffer.rb +231 -0
- data/lib/google/cloud/pubsub/subscription.rb +1279 -0
- data/lib/google/cloud/pubsub/subscription/list.rb +205 -0
- data/lib/google/cloud/pubsub/subscription/push_config.rb +244 -0
- data/lib/google/cloud/pubsub/topic.rb +934 -0
- data/lib/google/cloud/pubsub/topic/list.rb +171 -0
- data/lib/google/cloud/pubsub/v1.rb +17 -0
- data/lib/google/cloud/pubsub/v1/credentials.rb +41 -0
- data/lib/google/cloud/pubsub/v1/doc/google/iam/v1/iam_policy.rb +21 -0
- data/lib/google/cloud/pubsub/v1/doc/google/iam/v1/options.rb +21 -0
- data/lib/google/cloud/pubsub/v1/doc/google/iam/v1/policy.rb +21 -0
- data/lib/google/cloud/pubsub/v1/doc/google/protobuf/duration.rb +91 -0
- data/lib/google/cloud/pubsub/v1/doc/google/protobuf/empty.rb +29 -0
- data/lib/google/cloud/pubsub/v1/doc/google/protobuf/field_mask.rb +222 -0
- data/lib/google/cloud/pubsub/v1/doc/google/protobuf/timestamp.rb +113 -0
- data/lib/google/cloud/pubsub/v1/doc/google/pubsub/v1/pubsub.rb +833 -0
- data/lib/google/cloud/pubsub/v1/doc/google/type/expr.rb +19 -0
- data/lib/google/cloud/pubsub/v1/publisher_client.rb +928 -0
- data/lib/google/cloud/pubsub/v1/publisher_client_config.json +120 -0
- data/lib/google/cloud/pubsub/v1/subscriber_client.rb +1466 -0
- data/lib/google/cloud/pubsub/v1/subscriber_client_config.json +153 -0
- data/lib/google/cloud/pubsub/version.rb +24 -0
- data/lib/google/pubsub/v1/pubsub_pb.rb +269 -0
- data/lib/google/pubsub/v1/pubsub_services_pb.rb +215 -0
- 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
|