google-cloud-pubsub 0.26.0 → 2.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +5 -5
  2. data/.yardopts +12 -2
  3. data/AUTHENTICATION.md +178 -0
  4. data/CHANGELOG.md +659 -0
  5. data/CODE_OF_CONDUCT.md +40 -0
  6. data/CONTRIBUTING.md +187 -0
  7. data/EMULATOR.md +37 -0
  8. data/LICENSE +2 -2
  9. data/LOGGING.md +32 -0
  10. data/OVERVIEW.md +528 -0
  11. data/TROUBLESHOOTING.md +31 -0
  12. data/lib/google/cloud/pubsub/async_publisher/batch.rb +310 -0
  13. data/lib/google/cloud/pubsub/async_publisher.rb +402 -0
  14. data/lib/google/cloud/pubsub/batch_publisher.rb +100 -0
  15. data/lib/google/cloud/pubsub/convert.rb +91 -0
  16. data/lib/google/cloud/pubsub/credentials.rb +26 -10
  17. data/lib/google/cloud/pubsub/errors.rb +85 -0
  18. data/lib/google/cloud/pubsub/message.rb +80 -17
  19. data/lib/google/cloud/pubsub/policy.rb +17 -14
  20. data/lib/google/cloud/pubsub/project.rb +364 -250
  21. data/lib/google/cloud/pubsub/publish_result.rb +103 -0
  22. data/lib/google/cloud/pubsub/received_message.rb +162 -24
  23. data/lib/google/cloud/pubsub/retry_policy.rb +88 -0
  24. data/lib/google/cloud/pubsub/schema/list.rb +180 -0
  25. data/lib/google/cloud/pubsub/schema.rb +310 -0
  26. data/lib/google/cloud/pubsub/service.rb +281 -265
  27. data/lib/google/cloud/pubsub/snapshot/list.rb +21 -21
  28. data/lib/google/cloud/pubsub/snapshot.rb +55 -15
  29. data/lib/google/cloud/pubsub/subscriber/enumerator_queue.rb +54 -0
  30. data/lib/google/cloud/pubsub/subscriber/inventory.rb +173 -0
  31. data/lib/google/cloud/pubsub/subscriber/sequencer.rb +115 -0
  32. data/lib/google/cloud/pubsub/subscriber/stream.rb +400 -0
  33. data/lib/google/cloud/pubsub/subscriber/timed_unary_buffer.rb +230 -0
  34. data/lib/google/cloud/pubsub/subscriber.rb +417 -0
  35. data/lib/google/cloud/pubsub/subscription/list.rb +28 -28
  36. data/lib/google/cloud/pubsub/subscription/push_config.rb +268 -0
  37. data/lib/google/cloud/pubsub/subscription.rb +900 -172
  38. data/lib/google/cloud/pubsub/topic/list.rb +21 -21
  39. data/lib/google/cloud/pubsub/topic.rb +674 -95
  40. data/lib/google/cloud/pubsub/version.rb +6 -4
  41. data/lib/google/cloud/pubsub.rb +104 -439
  42. data/lib/google-cloud-pubsub.rb +60 -29
  43. metadata +88 -50
  44. data/README.md +0 -69
  45. data/lib/google/cloud/pubsub/topic/publisher.rb +0 -86
  46. data/lib/google/cloud/pubsub/v1/doc/google/protobuf/duration.rb +0 -77
  47. data/lib/google/cloud/pubsub/v1/doc/google/protobuf/field_mask.rb +0 -223
  48. data/lib/google/cloud/pubsub/v1/doc/google/protobuf/timestamp.rb +0 -81
  49. data/lib/google/cloud/pubsub/v1/doc/google/pubsub/v1/pubsub.rb +0 -503
  50. data/lib/google/cloud/pubsub/v1/publisher_client.rb +0 -605
  51. data/lib/google/cloud/pubsub/v1/publisher_client_config.json +0 -96
  52. data/lib/google/cloud/pubsub/v1/subscriber_client.rb +0 -1104
  53. data/lib/google/cloud/pubsub/v1/subscriber_client_config.json +0 -127
  54. data/lib/google/cloud/pubsub/v1.rb +0 -17
  55. data/lib/google/pubsub/v1/pubsub_pb.rb +0 -187
  56. data/lib/google/pubsub/v1/pubsub_services_pb.rb +0 -159
@@ -1,10 +1,10 @@
1
- # Copyright 2015 Google Inc. All rights reserved.
1
+ # Copyright 2015 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
5
5
  # You may obtain a copy of the License at
6
6
  #
7
- # http://www.apache.org/licenses/LICENSE-2.0
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
8
  #
9
9
  # Unless required by applicable law or agreed to in writing, software
10
10
  # distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,7 +17,7 @@ require "delegate"
17
17
 
18
18
  module Google
19
19
  module Cloud
20
- module Pubsub
20
+ module PubSub
21
21
  class Subscription
22
22
  ##
23
23
  # Subscription::List is a special case Array with additional values.
@@ -25,7 +25,7 @@ module Google
25
25
  ##
26
26
  # If not empty, indicates that there are more subscriptions
27
27
  # that match the request and this value should be passed to
28
- # the next {Google::Cloud::Pubsub::Topic#subscriptions} to continue.
28
+ # the next {Google::Cloud::PubSub::Topic#subscriptions} to continue.
29
29
  attr_accessor :token
30
30
 
31
31
  ##
@@ -46,7 +46,7 @@ module Google
46
46
  # @example
47
47
  # require "google/cloud/pubsub"
48
48
  #
49
- # pubsub = Google::Cloud::Pubsub.new
49
+ # pubsub = Google::Cloud::PubSub.new
50
50
  #
51
51
  # subscriptions = pubsub.subscriptions
52
52
  # if subscriptions.next?
@@ -65,7 +65,7 @@ module Google
65
65
  # @example
66
66
  # require "google/cloud/pubsub"
67
67
  #
68
- # pubsub = Google::Cloud::Pubsub.new
68
+ # pubsub = Google::Cloud::PubSub.new
69
69
  #
70
70
  # subscriptions = pubsub.subscriptions
71
71
  # if subscriptions.next?
@@ -103,7 +103,7 @@ module Google
103
103
  # @example Iterating each subscription by passing a block:
104
104
  # require "google/cloud/pubsub"
105
105
  #
106
- # pubsub = Google::Cloud::Pubsub.new
106
+ # pubsub = Google::Cloud::PubSub.new
107
107
  #
108
108
  # subscriptions = pubsub.subscriptions
109
109
  # subscriptions.all do |subscription|
@@ -113,7 +113,7 @@ module Google
113
113
  # @example Using the enumerator by not passing a block:
114
114
  # require "google/cloud/pubsub"
115
115
  #
116
- # pubsub = Google::Cloud::Pubsub.new
116
+ # pubsub = Google::Cloud::PubSub.new
117
117
  #
118
118
  # subscriptions = pubsub.subscriptions
119
119
  # all_names = subscriptions.all.map do |subscription|
@@ -123,24 +123,22 @@ module Google
123
123
  # @example Limit the number of API calls made:
124
124
  # require "google/cloud/pubsub"
125
125
  #
126
- # pubsub = Google::Cloud::Pubsub.new
126
+ # pubsub = Google::Cloud::PubSub.new
127
127
  #
128
128
  # subscriptions = pubsub.subscriptions
129
129
  # subscriptions.all(request_limit: 10) do |subscription|
130
130
  # puts subscription.name
131
131
  # end
132
132
  #
133
- def all request_limit: nil
133
+ def all request_limit: nil, &block
134
134
  request_limit = request_limit.to_i if request_limit
135
- unless block_given?
136
- return enum_for(:all, request_limit: request_limit)
137
- end
135
+ return enum_for :all, request_limit: request_limit unless block_given?
138
136
  results = self
139
137
  loop do
140
- results.each { |r| yield r }
138
+ results.each(&block)
141
139
  if request_limit
142
140
  request_limit -= 1
143
- break if request_limit < 0
141
+ break if request_limit.negative?
144
142
  end
145
143
  break unless results.next?
146
144
  results = results.next
@@ -149,32 +147,32 @@ module Google
149
147
 
150
148
  ##
151
149
  # @private New Subscriptions::List from a
152
- # Google::Pubsub::V1::ListSubscriptionsRequest object.
150
+ # Google::Cloud::PubSub::V1::ListSubscriptionsRequest object.
153
151
  def self.from_grpc grpc_list, service, max = nil
154
152
  subs = new(Array(grpc_list.subscriptions).map do |grpc|
155
153
  Subscription.from_grpc grpc, service
156
154
  end)
157
155
  token = grpc_list.next_page_token
158
- token = nil if token == ""
159
- subs.instance_variable_set "@token", token
160
- subs.instance_variable_set "@service", service
161
- subs.instance_variable_set "@max", max
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
162
160
  subs
163
161
  end
164
162
 
165
163
  ##
166
164
  # @private New Subscriptions::List from a
167
- # Google::Pubsub::V1::ListTopicSubscriptionsResponse object.
165
+ # Google::Cloud::PubSub::V1::ListTopicSubscriptionsResponse object.
168
166
  def self.from_topic_grpc grpc_list, service, topic, max = nil
169
167
  subs = new(Array(grpc_list.subscriptions).map do |grpc|
170
- Subscription.new_lazy grpc, service
168
+ Subscription.from_name grpc, service
171
169
  end)
172
170
  token = grpc_list.next_page_token
173
- token = nil if token == ""
174
- subs.instance_variable_set "@token", token
175
- subs.instance_variable_set "@service", service
176
- subs.instance_variable_set "@topic", topic
177
- subs.instance_variable_set "@max", max
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
178
176
  subs
179
177
  end
180
178
 
@@ -184,7 +182,7 @@ module Google
184
182
  # @private Raise an error unless an active connection to the service
185
183
  # is available.
186
184
  def ensure_service!
187
- fail "Must have active connection to service" unless @service
185
+ raise "Must have active connection to service" unless @service
188
186
  end
189
187
 
190
188
  def next_subscriptions
@@ -201,5 +199,7 @@ module Google
201
199
  end
202
200
  end
203
201
  end
202
+
203
+ Pubsub = PubSub unless const_defined? :Pubsub
204
204
  end
205
205
  end
@@ -0,0 +1,268 @@
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 Create a push config:
26
+ # require "google/cloud/pubsub"
27
+ #
28
+ # pubsub = Google::Cloud::PubSub.new
29
+ # topic = pubsub.topic "my-topic"
30
+ #
31
+ # push_config = Google::Cloud::PubSub::Subscription::PushConfig.new endpoint: "http://example.net/callback"
32
+ # push_config.set_oidc_token "service-account@example.net", "audience-header-value"
33
+ #
34
+ # sub = topic.subscribe "my-subscription", push_config: push_config
35
+ #
36
+ # @example Read a push config:
37
+ # require "google/cloud/pubsub"
38
+ #
39
+ # pubsub = Google::Cloud::PubSub.new
40
+ #
41
+ # sub = pubsub.subscription "my-topic-sub"
42
+ # sub.push_config.endpoint #=> "http://example.com/callback"
43
+ # sub.push_config.authentication.email #=> "user@example.com"
44
+ # sub.push_config.authentication.audience #=> "client-12345"
45
+ #
46
+ # @example Update a push config:
47
+ # require "google/cloud/pubsub"
48
+ #
49
+ # pubsub = Google::Cloud::PubSub.new
50
+ # sub = pubsub.subscription "my-subscription"
51
+ #
52
+ # sub.push_config do |pc|
53
+ # pc.endpoint = "http://example.net/callback"
54
+ # pc.set_oidc_token "user@example.net", "client-67890"
55
+ # end
56
+ #
57
+ class PushConfig
58
+ ##
59
+ # Creates a new push configuration.
60
+ #
61
+ # @param [String] endpoint A URL locating the endpoint to which messages should be pushed. For
62
+ # example, a Webhook endpoint might use `https://example.com/push`.
63
+ # @param [String] email The service account email to be used for generating the OIDC token.
64
+ # The caller must have the `iam.serviceAccounts.actAs` permission for the service account.
65
+ # @param [String] audience The audience to be used when generating OIDC token. The audience claim identifies
66
+ # the recipients that the JWT is intended for. The audience value is a single case-sensitive string. Having
67
+ # multiple values (array) for the audience field is not supported. More info about the OIDC JWT token
68
+ # audience here: https://tools.ietf.org/html/rfc7519#section-4.1.3 Note: if not specified, the `endpoint`
69
+ # URL will be used.
70
+ #
71
+ def initialize endpoint: nil, email: nil, audience: nil
72
+ @grpc = Google::Cloud::PubSub::V1::PushConfig.new
73
+
74
+ self.endpoint = endpoint unless endpoint.nil?
75
+
76
+ raise ArgumentError, "audience provided without email. Authentication is invalid" if audience && !email
77
+
78
+ set_oidc_token email, audience if email
79
+ end
80
+
81
+ ##
82
+ # A URL locating the endpoint to which messages should be pushed. For example, a Webhook endpoint might use
83
+ # `https://example.com/push`.
84
+ #
85
+ # @return [String]
86
+ def endpoint
87
+ @grpc.push_endpoint
88
+ end
89
+
90
+ ##
91
+ # Sets the URL locating the endpoint to which messages should be pushed. For example, a Webhook endpoint might
92
+ # use `https://example.com/push`.
93
+ #
94
+ # @param [String, nil] new_endpoint New URL value
95
+ def endpoint= new_endpoint
96
+ @grpc.push_endpoint = String new_endpoint
97
+ end
98
+
99
+ ##
100
+ # The authentication method used by push endpoints to verify the source of push requests.
101
+ #
102
+ # @return [OidcToken, nil] An OIDC JWT token if specified, `nil`
103
+ # otherwise.
104
+ def authentication
105
+ return nil unless @grpc.authentication_method == :oidc_token
106
+
107
+ OidcToken.from_grpc @grpc.oidc_token
108
+ end
109
+
110
+ ##
111
+ # Sets the authentication method used by push endpoints to verify the source of push requests.
112
+ #
113
+ # @param [OidcToken, nil] new_auth An authentication value.
114
+ def authentication= new_auth
115
+ if new_auth.nil?
116
+ @grpc.oidc_token = nil
117
+ else
118
+ raise ArgumentError unless new_auth.is_a? OidcToken
119
+
120
+ @grpc.oidc_token = new_auth.to_grpc
121
+ end
122
+ end
123
+
124
+ ##
125
+ # Checks whether authentication is an {OidcToken}.
126
+ #
127
+ # @return [Boolean]
128
+ def oidc_token?
129
+ authentication.is_a? OidcToken
130
+ end
131
+
132
+ ##
133
+ # Sets the authentication method to use an {OidcToken}.
134
+ #
135
+ # @param [String] email Service account email.
136
+ # @param [String] audience Audience to be used.
137
+ def set_oidc_token email, audience
138
+ oidc_token = OidcToken.new.tap do |token|
139
+ token.email = email
140
+ token.audience = audience
141
+ end
142
+ self.authentication = oidc_token
143
+ end
144
+
145
+ ##
146
+ # The format of the pushed message. This attribute indicates the version of the data expected by the endpoint.
147
+ # This controls the shape of the pushed message (i.e., its fields and metadata). The endpoint version is based
148
+ # on the version of the Pub/Sub API.
149
+ #
150
+ # If not present during the Subscription creation, it will default to the version of the API used to make such
151
+ # call.
152
+ #
153
+ # The possible values for this attribute are:
154
+ #
155
+ # * `v1beta1`: uses the push format defined in the v1beta1 Pub/Sub
156
+ # API.
157
+ # * `v1` or `v1beta2`: uses the push format defined in the v1 Pub/Sub
158
+ # API.
159
+ #
160
+ # @return [String]
161
+ def version
162
+ @grpc.attributes["x-goog-version"]
163
+ end
164
+
165
+ ##
166
+ # Sets the format of the pushed message.
167
+ #
168
+ # The possible values for this attribute are:
169
+ #
170
+ # * `v1beta1`: uses the push format defined in the v1beta1 Pub/Sub
171
+ # API.
172
+ # * `v1` or `v1beta2`: uses the push format defined in the v1 Pub/Sub
173
+ # API.
174
+ #
175
+ # @param [String, nil] new_version The new version value.
176
+ def version= new_version
177
+ if new_version.nil?
178
+ @grpc.attributes.delete "x-goog-version"
179
+ else
180
+ @grpc.attributes["x-goog-version"] = new_version
181
+ end
182
+ end
183
+
184
+ ##
185
+ # @private
186
+ def to_grpc
187
+ @grpc
188
+ end
189
+
190
+ ##
191
+ # @private
192
+ def self.from_grpc grpc
193
+ new.tap do |pc|
194
+ pc.instance_variable_set :@grpc, grpc.dup if grpc
195
+ end
196
+ end
197
+
198
+ ##
199
+ # Contains information needed for generating an [OpenID Connect
200
+ # token](https://developers.google.com/identity/protocols/OpenIDConnect).
201
+ class OidcToken
202
+ ##
203
+ # @private
204
+ def initialize
205
+ @grpc = Google::Cloud::PubSub::V1::PushConfig::OidcToken.new
206
+ end
207
+
208
+ ##
209
+ # The service account email to be used for generating the OIDC token. The caller must have the
210
+ # `iam.serviceAccounts.actAs` permission for the service account.
211
+ #
212
+ # @return [String]
213
+ def email
214
+ @grpc.service_account_email
215
+ end
216
+
217
+ ##
218
+ # Sets the service account email to be used for generating the OIDC token. The caller must have the
219
+ # `iam.serviceAccounts.actAs` permission for the service account.
220
+ #
221
+ # @param [String] new_email New service account email value.
222
+ def email= new_email
223
+ @grpc.service_account_email = new_email
224
+ end
225
+
226
+ ##
227
+ # The audience to be used when generating OIDC token. The audience claim identifies the recipients that
228
+ # the JWT is intended for. The audience value is a single case-sensitive string. Having multiple values
229
+ # (array) for the audience field is not supported. More info about the OIDC JWT token audience here:
230
+ # https://tools.ietf.org/html/rfc7519#section-4.1.3 Note: if not specified, the `endpoint` URL will be used.
231
+ #
232
+ # @return [String]
233
+ def audience
234
+ @grpc.audience
235
+ end
236
+
237
+ ##
238
+ # Sets the audience to be used when generating OIDC token. The audience claim identifies the recipients that
239
+ # the JWT is intended for. The audience value is a single case-sensitive string. Having multiple values
240
+ # (array) for the audience field is not supported. More info about the OIDC JWT token audience here:
241
+ # https://tools.ietf.org/html/rfc7519#section-4.1.3 Note: if not specified, the `endpoint` URL will be used.
242
+ #
243
+ # @param [String] new_audience New audience value.
244
+ def audience= new_audience
245
+ @grpc.audience = new_audience
246
+ end
247
+
248
+ ##
249
+ # @private
250
+ def to_grpc
251
+ @grpc
252
+ end
253
+
254
+ ##
255
+ # @private
256
+ def self.from_grpc grpc
257
+ grpc ||= Google::Cloud::PubSub::V1::PushConfig::OidcToken.new
258
+
259
+ new.tap do |pc|
260
+ pc.instance_variable_set :@grpc, grpc.dup
261
+ end
262
+ end
263
+ end
264
+ end
265
+ end
266
+ end
267
+ end
268
+ end
@@ -1,10 +1,10 @@
1
- # Copyright 2015 Google Inc. All rights reserved.
1
+ # Copyright 2015 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
5
5
  # You may obtain a copy of the License at
6
6
  #
7
- # http://www.apache.org/licenses/LICENSE-2.0
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
8
  #
9
9
  # Unless required by applicable law or agreed to in writing, software
10
10
  # distributed under the License is distributed on an "AS IS" BASIS,
@@ -13,14 +13,19 @@
13
13
  # limitations under the License.
14
14
 
15
15
 
16
+ require "google/cloud/pubsub/convert"
16
17
  require "google/cloud/errors"
17
18
  require "google/cloud/pubsub/subscription/list"
19
+ require "google/cloud/pubsub/subscription/push_config"
18
20
  require "google/cloud/pubsub/received_message"
21
+ require "google/cloud/pubsub/retry_policy"
19
22
  require "google/cloud/pubsub/snapshot"
23
+ require "google/cloud/pubsub/subscriber"
24
+ require "google/cloud/pubsub/v1"
20
25
 
21
26
  module Google
22
27
  module Cloud
23
- module Pubsub
28
+ module PubSub
24
29
  ##
25
30
  # # Subscription
26
31
  #
@@ -30,79 +35,112 @@ module Google
30
35
  # @example
31
36
  # require "google/cloud/pubsub"
32
37
  #
33
- # pubsub = Google::Cloud::Pubsub.new
38
+ # pubsub = Google::Cloud::PubSub.new
34
39
  #
35
40
  # sub = pubsub.subscription "my-topic-sub"
36
- # msgs = sub.pull
37
- # msgs.each { |msg| msg.acknowledge! }
41
+ # subscriber = sub.listen do |received_message|
42
+ # # process message
43
+ # received_message.acknowledge!
44
+ # end
38
45
  #
46
+ # # Handle exceptions from listener
47
+ # subscriber.on_error do |exception|
48
+ # puts "Exception: #{exception.class} #{exception.message}"
49
+ # end
50
+ #
51
+ # # Gracefully shut down the subscriber
52
+ # at_exit do
53
+ # subscriber.stop!
54
+ # end
55
+ #
56
+ # # Start background threads that will call the block passed to listen.
57
+ # subscriber.start
58
+ # sleep
39
59
  class Subscription
40
60
  ##
41
61
  # @private The Service object.
42
62
  attr_accessor :service
43
63
 
44
64
  ##
45
- # @private The gRPC Google::Pubsub::V1::Subscription object.
65
+ # @private The gRPC Google::Cloud::PubSub::V1::Subscription object.
46
66
  attr_accessor :grpc
47
67
 
48
68
  ##
49
69
  # @private Create an empty {Subscription} object.
50
70
  def initialize
51
71
  @service = nil
52
- @grpc = Google::Pubsub::V1::Subscription.new
53
- @name = nil
72
+ @grpc = nil
73
+ @resource_name = nil
54
74
  @exists = nil
55
75
  end
56
76
 
57
- ##
58
- # @private New lazy {Topic} object without making an HTTP request.
59
- def self.new_lazy name, service, options = {}
60
- new.tap do |s|
61
- s.grpc = nil
62
- s.service = service
63
- s.instance_variable_set "@name",
64
- service.subscription_path(name, options)
65
- end
66
- end
67
-
68
77
  ##
69
78
  # The name of the subscription.
79
+ #
80
+ # @return [String] A fully-qualified subscription name in the form
81
+ # `projects/{project_id}/subscriptions/{subscription_id}`.
82
+ #
70
83
  def name
71
- @grpc ? @grpc.name : @name
84
+ return @resource_name if reference?
85
+ @grpc.name
72
86
  end
73
87
 
74
88
  ##
75
89
  # The {Topic} from which this subscription receives messages.
76
90
  #
91
+ # Makes an API call to retrieve the topic information when called on a
92
+ # reference object. See {#reference?}.
93
+ #
77
94
  # @return [Topic]
78
95
  #
79
96
  # @example
80
97
  # require "google/cloud/pubsub"
81
98
  #
82
- # pubsub = Google::Cloud::Pubsub.new
99
+ # pubsub = Google::Cloud::PubSub.new
83
100
  #
84
101
  # sub = pubsub.subscription "my-topic-sub"
85
102
  # sub.topic.name #=> "projects/my-project/topics/my-topic"
86
103
  #
87
104
  def topic
88
105
  ensure_grpc!
89
- Topic.new_lazy @grpc.topic, service
106
+ Topic.from_name @grpc.topic, service
90
107
  end
91
108
 
92
109
  ##
93
110
  # This value is the maximum number of seconds after a subscriber
94
111
  # receives a message before the subscriber should acknowledge the
95
112
  # message.
113
+ #
114
+ # Makes an API call to retrieve the deadline value when called on a
115
+ # reference object. See {#reference?}.
116
+ #
117
+ # @return [Integer]
96
118
  def deadline
97
119
  ensure_grpc!
98
120
  @grpc.ack_deadline_seconds
99
121
  end
100
122
 
123
+ ##
124
+ # Sets the maximum number of seconds after a subscriber
125
+ # receives a message before the subscriber should acknowledge the
126
+ # message.
127
+ #
128
+ # @param [Integer] new_deadline The new deadline value.
129
+ #
130
+ def deadline= new_deadline
131
+ update_grpc = Google::Cloud::PubSub::V1::Subscription.new name: name, ack_deadline_seconds: new_deadline
132
+ @grpc = service.update_subscription update_grpc, :ack_deadline_seconds
133
+ @resource_name = nil
134
+ end
135
+
101
136
  ##
102
137
  # Indicates whether to retain acknowledged messages. If `true`, then
103
138
  # messages are not expunged from the subscription's backlog, even if
104
- # they are acknowledged, until they fall out of the
105
- # {#retention_duration} window. Default is `false`.
139
+ # they are acknowledged, until they fall out of the {#retention} window.
140
+ # Default is `false`.
141
+ #
142
+ # Makes an API call to retrieve the retain_acked value when called on a
143
+ # reference object. See {#reference?}.
106
144
  #
107
145
  # @return [Boolean] Returns `true` if acknowledged messages are
108
146
  # retained.
@@ -112,6 +150,19 @@ module Google
112
150
  @grpc.retain_acked_messages
113
151
  end
114
152
 
153
+ ##
154
+ # Sets whether to retain acknowledged messages.
155
+ #
156
+ # @param [Boolean] new_retain_acked The new retain acknowledged messages
157
+ # value.
158
+ #
159
+ def retain_acked= new_retain_acked
160
+ update_grpc = Google::Cloud::PubSub::V1::Subscription.new name: name,
161
+ retain_acked_messages: !(!new_retain_acked)
162
+ @grpc = service.update_subscription update_grpc, :retain_acked_messages
163
+ @resource_name = nil
164
+ end
165
+
115
166
  ##
116
167
  # How long to retain unacknowledged messages in the subscription's
117
168
  # backlog, from the moment a message is published. If
@@ -121,69 +172,518 @@ module Google
121
172
  # less than 600 seconds (10 minutes). Default is 604,800 seconds (7
122
173
  # days).
123
174
  #
175
+ # Makes an API call to retrieve the retention value when called on a
176
+ # reference object. See {#reference?}.
177
+ #
124
178
  # @return [Numeric] The message retention duration in seconds.
125
179
  #
126
180
  def retention
127
181
  ensure_grpc!
128
- duration_to_number @grpc.message_retention_duration
182
+ Convert.duration_to_number @grpc.message_retention_duration
183
+ end
184
+
185
+ ##
186
+ # Sets the message retention duration in seconds.
187
+ #
188
+ # @param [Numeric] new_retention The new retention value.
189
+ #
190
+ def retention= new_retention
191
+ new_retention_duration = Convert.number_to_duration new_retention
192
+ update_grpc = Google::Cloud::PubSub::V1::Subscription.new name: name,
193
+ message_retention_duration: new_retention_duration
194
+ @grpc = service.update_subscription update_grpc, :message_retention_duration
195
+ @resource_name = nil
129
196
  end
130
197
 
131
198
  ##
132
199
  # Returns the URL locating the endpoint to which messages should be
133
- # pushed.
200
+ # pushed. For example, a Webhook endpoint might use
201
+ # `https://example.com/push`.
202
+ #
203
+ # Makes an API call to retrieve the endpoint value when called on a
204
+ # reference object. See {#reference?}.
205
+ #
206
+ # @return [String]
207
+ #
134
208
  def endpoint
135
209
  ensure_grpc!
136
- @grpc.push_config.push_endpoint if @grpc.push_config
210
+ @grpc.push_config&.push_endpoint
137
211
  end
138
212
 
139
213
  ##
140
214
  # Sets the URL locating the endpoint to which messages should be pushed.
215
+ # For example, a Webhook endpoint might use `https://example.com/push`.
216
+ #
217
+ # @param [String] new_endpoint The new endpoint value.
218
+ #
141
219
  def endpoint= new_endpoint
142
220
  ensure_service!
143
221
  service.modify_push_config name, new_endpoint, {}
144
- @grpc.push_config = Google::Pubsub::V1::PushConfig.new(
222
+
223
+ return if reference?
224
+
225
+ @grpc.push_config = Google::Cloud::PubSub::V1::PushConfig.new(
145
226
  push_endpoint: new_endpoint,
146
- attributes: {}
147
- ) if @grpc
227
+ attributes: {}
228
+ )
148
229
  end
149
230
 
150
231
  ##
151
- # Determines whether the subscription exists in the Pub/Sub service.
232
+ # Inspect the Subscription's push configuration settings. The
233
+ # configuration can be changed by modifying the values in the method's
234
+ # block.
235
+ #
236
+ # Subscription objects that are reference only will return an empty
237
+ # {Subscription::PushConfig} object, which can be configured and saved
238
+ # using the method's block. Unlike {#endpoint}, which will retrieve the
239
+ # full resource from the API before returning. To get the actual values
240
+ # for a reference object, call {#reload!} before calling {#push_config}.
241
+ #
242
+ # @yield [push_config] a block for modifying the push configuration
243
+ # @yieldparam [Subscription::PushConfig] push_config the push
244
+ # configuration
245
+ #
246
+ # @return [Subscription::PushConfig]
152
247
  #
153
248
  # @example
154
249
  # require "google/cloud/pubsub"
155
250
  #
156
- # pubsub = Google::Cloud::Pubsub.new
251
+ # pubsub = Google::Cloud::PubSub.new
157
252
  #
158
253
  # sub = pubsub.subscription "my-topic-sub"
159
- # sub.exists? #=> true
254
+ # sub.push_config.endpoint #=> "http://example.com/callback"
255
+ # sub.push_config.authentication.email #=> "user@example.com"
256
+ # sub.push_config.authentication.audience #=> "client-12345"
160
257
  #
161
- def exists?
162
- # Always true if we have a grpc object
163
- return true unless @grpc.nil?
164
- # If we have a value, return it
165
- return @exists unless @exists.nil?
258
+ # @example Update the push configuration by passing a block:
259
+ # require "google/cloud/pubsub"
260
+ #
261
+ # pubsub = Google::Cloud::PubSub.new
262
+ # sub = pubsub.subscription "my-subscription"
263
+ #
264
+ # sub.push_config do |pc|
265
+ # pc.endpoint = "http://example.net/callback"
266
+ # pc.set_oidc_token "user@example.net", "client-67890"
267
+ # end
268
+ #
269
+ def push_config
270
+ ensure_service!
271
+
272
+ orig_config = reference? ? nil : @grpc.push_config
273
+ config = PushConfig.from_grpc orig_config
274
+
275
+ if block_given?
276
+ old_config = config.to_grpc.dup
277
+ yield config
278
+ new_config = config.to_grpc
279
+
280
+ if old_config != new_config # has the object been changed?
281
+ update_grpc = Google::Cloud::PubSub::V1::Subscription.new name: name, push_config: new_config
282
+ @grpc = service.update_subscription update_grpc, :push_config
283
+ end
284
+ end
285
+
286
+ config.freeze
287
+ end
288
+
289
+ ##
290
+ # A hash of user-provided labels associated with this subscription.
291
+ # Labels can be used to organize and group subscriptions.See [Creating
292
+ # and Managing Labels](https://cloud.google.com/pubsub/docs/labels).
293
+ #
294
+ # The returned hash is frozen and changes are not allowed. Use
295
+ # {#labels=} to update the labels for this subscription.
296
+ #
297
+ # Makes an API call to retrieve the labels value when called on a
298
+ # reference object. See {#reference?}.
299
+ #
300
+ # @return [Hash] The frozen labels hash.
301
+ #
302
+ def labels
166
303
  ensure_grpc!
167
- @exists = !@grpc.nil?
168
- rescue Google::Cloud::NotFoundError
169
- @exists = false
304
+ @grpc.labels.to_h.freeze
170
305
  end
171
306
 
172
307
  ##
173
- # @private
174
- # Determines whether the subscription object was created with an
175
- # HTTP call.
308
+ # Sets the hash of user-provided labels associated with this
309
+ # subscription. Labels can be used to organize and group subscriptions.
310
+ # Label keys and values can be no longer than 63 characters, can only
311
+ # contain lowercase letters, numeric characters, underscores and dashes.
312
+ # International characters are allowed. Label values are optional. Label
313
+ # keys must start with a letter and each label in the list must have a
314
+ # different key. See [Creating and Managing
315
+ # Labels](https://cloud.google.com/pubsub/docs/labels).
316
+ #
317
+ # @param [Hash] new_labels The new labels hash.
318
+ #
319
+ def labels= new_labels
320
+ raise ArgumentError, "Value must be a Hash" if new_labels.nil?
321
+ update_grpc = Google::Cloud::PubSub::V1::Subscription.new name: name, labels: new_labels
322
+ @grpc = service.update_subscription update_grpc, :labels
323
+ @resource_name = nil
324
+ end
325
+
326
+ ##
327
+ # The duration (in seconds) for when a subscription expires after the
328
+ # subscription goes inactive. A subscription is considered active as
329
+ # long as any connected subscriber is successfully consuming messages
330
+ # from the subscription or is issuing operations on the subscription.
331
+ #
332
+ # If {#expires_in=} is not set, a *default* value of of 31 days will be
333
+ # used. The minimum allowed value is 1 day.
334
+ #
335
+ # Makes an API call to retrieve the expires_in value when called on a
336
+ # reference object. See {#reference?}.
337
+ #
338
+ # @return [Numeric, nil] The expiration duration, or `nil` if unset.
339
+ #
340
+ def expires_in
341
+ ensure_grpc!
342
+
343
+ return nil if @grpc.expiration_policy.nil?
344
+
345
+ Convert.duration_to_number @grpc.expiration_policy.ttl
346
+ end
347
+
348
+ ##
349
+ # Sets the duration (in seconds) for when a subscription expires after
350
+ # the subscription goes inactive.
351
+ #
352
+ # See also {#expires_in}.
353
+ #
354
+ # @param [Numeric, nil] ttl The expiration duration in seconds, or `nil`
355
+ # to unset.
356
+ #
357
+ def expires_in= ttl
358
+ new_expiration_policy = Google::Cloud::PubSub::V1::ExpirationPolicy.new ttl: Convert.number_to_duration(ttl)
359
+
360
+ update_grpc = Google::Cloud::PubSub::V1::Subscription.new name: name, expiration_policy: new_expiration_policy
361
+ @grpc = service.update_subscription update_grpc, :expiration_policy
362
+ @resource_name = nil
363
+ end
364
+
365
+ ##
366
+ # An expression written in the Cloud Pub/Sub filter language. If non-empty, then only {Message} instances whose
367
+ # `attributes` field matches the filter are delivered on this subscription. If empty, then no messages are
368
+ # filtered out.
369
+ #
370
+ # Makes an API call to retrieve the filter value when called on a reference
371
+ # object. See {#reference?}.
372
+ #
373
+ # @return [String] The frozen filter string.
374
+ #
375
+ def filter
376
+ ensure_grpc!
377
+ @grpc.filter.freeze
378
+ end
379
+
380
+ ##
381
+ # Returns the {Topic} to which dead letter messages should be published if a dead letter policy is configured,
382
+ # otherwise `nil`. Dead lettering is done on a best effort basis. The same message might be dead lettered
383
+ # multiple times.
384
+ #
385
+ # See also {#dead_letter_topic=}, {#dead_letter_max_delivery_attempts=}, {#dead_letter_max_delivery_attempts}
386
+ # and {#remove_dead_letter_policy}.
387
+ #
388
+ # Makes an API call to retrieve the topic name when called on a reference object. See {#reference?}.
389
+ #
390
+ # @return [Topic, nil]
176
391
  #
177
392
  # @example
178
393
  # require "google/cloud/pubsub"
179
394
  #
180
- # pubsub = Google::Cloud::Pubsub.new
395
+ # pubsub = Google::Cloud::PubSub.new
181
396
  #
182
- # sub = pubsub.get_subscription "my-topic-sub"
183
- # sub.lazy? #=> false
397
+ # sub = pubsub.subscription "my-topic-sub"
398
+ # sub.dead_letter_topic.name #=> "projects/my-project/topics/my-dead-letter-topic"
399
+ # sub.dead_letter_max_delivery_attempts #=> 10
184
400
  #
185
- def lazy?
186
- @grpc.nil?
401
+ def dead_letter_topic
402
+ ensure_grpc!
403
+ return nil unless @grpc.dead_letter_policy
404
+ Topic.from_name @grpc.dead_letter_policy.dead_letter_topic, service
405
+ end
406
+
407
+ ##
408
+ # Sets the {Topic} to which dead letter messages for the subscription should be published. Dead lettering is
409
+ # done on a best effort basis. The same message might be dead lettered multiple times.
410
+ # The Cloud Pub/Sub service account associated with the enclosing subscription's parent project (i.e.,
411
+ # `service-\\{project_number}@gcp-sa-pubsub.iam.gserviceaccount.com`) must have permission to Publish() to this
412
+ # topic.
413
+ #
414
+ # The operation will fail if the topic does not exist. Users should ensure that there is a subscription attached
415
+ # to this topic since messages published to a topic with no subscriptions are lost.
416
+ #
417
+ # Makes an API call to retrieve the dead_letter_policy value when called on a
418
+ # reference object. See {#reference?}.
419
+ #
420
+ # See also {#dead_letter_topic}, {#dead_letter_max_delivery_attempts=}, {#dead_letter_max_delivery_attempts}
421
+ # and {#remove_dead_letter_policy}.
422
+ #
423
+ # @param [Topic] new_dead_letter_topic The topic to which dead letter messages for the subscription should be
424
+ # published.
425
+ #
426
+ # @example
427
+ # require "google/cloud/pubsub"
428
+ #
429
+ # pubsub = Google::Cloud::PubSub.new
430
+ #
431
+ # sub = pubsub.subscription "my-topic-sub"
432
+ # dead_letter_topic = pubsub.topic "my-dead-letter-topic", skip_lookup: true
433
+ # sub.dead_letter_topic = dead_letter_topic
434
+ #
435
+ def dead_letter_topic= new_dead_letter_topic
436
+ ensure_grpc!
437
+ dead_letter_policy = @grpc.dead_letter_policy || Google::Cloud::PubSub::V1::DeadLetterPolicy.new
438
+ dead_letter_policy.dead_letter_topic = new_dead_letter_topic.name
439
+ update_grpc = Google::Cloud::PubSub::V1::Subscription.new name: name, dead_letter_policy: dead_letter_policy
440
+ @grpc = service.update_subscription update_grpc, :dead_letter_policy
441
+ @resource_name = nil
442
+ end
443
+
444
+ ##
445
+ # Returns the maximum number of delivery attempts for any message in the subscription's dead letter policy if a
446
+ # dead letter policy is configured, otherwise `nil`. Dead lettering is done on a best effort basis. The same
447
+ # message might be dead lettered multiple times. The value must be between 5 and 100.
448
+ #
449
+ # The number of delivery attempts is defined as 1 + (the sum of number of NACKs and number of times the
450
+ # acknowledgement deadline has been exceeded for the message). A NACK is any call to ModifyAckDeadline with a 0
451
+ # deadline. Note that client libraries may automatically extend ack_deadlines.
452
+ #
453
+ # This field will be honored on a best effort basis. If this parameter is `nil` or `0`, a default value of `5`
454
+ # is used.
455
+ #
456
+ # See also {#dead_letter_max_delivery_attempts=}, {#dead_letter_topic=}, {#dead_letter_topic}
457
+ # and {#remove_dead_letter_policy}.
458
+ #
459
+ # Makes an API call to retrieve the dead_letter_policy when called on a reference object. See {#reference?}.
460
+ #
461
+ # @return [Integer, nil] A value between `5` and `100`, or `nil` if no dead letter policy is configured.
462
+ #
463
+ # @example
464
+ # require "google/cloud/pubsub"
465
+ #
466
+ # pubsub = Google::Cloud::PubSub.new
467
+ #
468
+ # sub = pubsub.subscription "my-topic-sub"
469
+ # sub.dead_letter_topic.name #=> "projects/my-project/topics/my-dead-letter-topic"
470
+ # sub.dead_letter_max_delivery_attempts #=> 10
471
+ #
472
+ def dead_letter_max_delivery_attempts
473
+ ensure_grpc!
474
+ @grpc.dead_letter_policy&.max_delivery_attempts
475
+ end
476
+
477
+ ##
478
+ # Sets the maximum number of delivery attempts for any message in the subscription's dead letter policy.
479
+ # Dead lettering is done on a best effort basis. The same message might be dead lettered multiple times.
480
+ # The value must be between 5 and 100.
481
+ #
482
+ # The number of delivery attempts is defined as 1 + (the sum of number of NACKs and number of times the
483
+ # acknowledgement deadline has been exceeded for the message). A NACK is any call to ModifyAckDeadline with a 0
484
+ # deadline. Note that client libraries may automatically extend ack_deadlines.
485
+ #
486
+ # This field will be honored on a best effort basis. If this parameter is 0, a default value of 5 is used.
487
+ #
488
+ # Makes an API call to retrieve the dead_letter_policy when called on a reference object. See {#reference?}.
489
+ #
490
+ # The dead letter topic must be set first. See {#dead_letter_topic=}, {#dead_letter_topic} and
491
+ # {#remove_dead_letter_policy}.
492
+ #
493
+ # @param [Integer, nil] new_dead_letter_max_delivery_attempts A value between 5 and 100. If this parameter is
494
+ # `nil` or `0`, a default value of 5 is used.
495
+ #
496
+ # @raise [ArgumentError] if the dead letter topic has not been set. See {#dead_letter_topic=}.
497
+ #
498
+ # @example
499
+ # require "google/cloud/pubsub"
500
+ #
501
+ # pubsub = Google::Cloud::PubSub.new
502
+ #
503
+ # sub = pubsub.subscription "my-topic-sub"
504
+ # sub.dead_letter_topic.name #=> "projects/my-project/topics/my-dead-letter-topic"
505
+ #
506
+ # sub.dead_letter_max_delivery_attempts = 20
507
+ #
508
+ def dead_letter_max_delivery_attempts= new_dead_letter_max_delivery_attempts
509
+ ensure_grpc!
510
+ unless @grpc.dead_letter_policy&.dead_letter_topic
511
+ # Service error message "3:Invalid resource name given (name=)." does not identify param.
512
+ raise ArgumentError, "dead_letter_topic is required with dead_letter_max_delivery_attempts"
513
+ end
514
+ dead_letter_policy = @grpc.dead_letter_policy || Google::Cloud::PubSub::V1::DeadLetterPolicy.new
515
+ dead_letter_policy.max_delivery_attempts = new_dead_letter_max_delivery_attempts
516
+ update_grpc = Google::Cloud::PubSub::V1::Subscription.new name: name, dead_letter_policy: dead_letter_policy
517
+ @grpc = service.update_subscription update_grpc, :dead_letter_policy
518
+ @resource_name = nil
519
+ end
520
+
521
+ ##
522
+ # Removes an existing dead letter policy. A dead letter policy specifies the conditions for dead lettering
523
+ # messages in the subscription. If a dead letter policy is not set, dead lettering is disabled.
524
+ #
525
+ # Makes an API call to retrieve the dead_letter_policy when called on a reference object. See {#reference?}.
526
+ #
527
+ # See {#dead_letter_topic}, {#dead_letter_topic=}, {#dead_letter_max_delivery_attempts} and
528
+ # {#dead_letter_max_delivery_attempts=}.
529
+ #
530
+ # @return [Boolean] `true` if an existing dead letter policy was removed, `false` if no existing dead letter
531
+ # policy was present.
532
+ #
533
+ # @example
534
+ # require "google/cloud/pubsub"
535
+ #
536
+ # pubsub = Google::Cloud::PubSub.new
537
+ #
538
+ # sub = pubsub.subscription "my-topic-sub"
539
+ #
540
+ # sub.dead_letter_topic.name #=> "projects/my-project/topics/my-dead-letter-topic"
541
+ # sub.dead_letter_max_delivery_attempts #=> 10
542
+ #
543
+ # sub.remove_dead_letter_policy
544
+ #
545
+ # sub.dead_letter_topic #=> nil
546
+ # sub.dead_letter_max_delivery_attempts #=> nil
547
+ #
548
+ def remove_dead_letter_policy
549
+ ensure_grpc!
550
+ return false if @grpc.dead_letter_policy.nil?
551
+ update_grpc = Google::Cloud::PubSub::V1::Subscription.new name: name, dead_letter_policy: nil
552
+ @grpc = service.update_subscription update_grpc, :dead_letter_policy
553
+ true
554
+ end
555
+
556
+ ##
557
+ # A policy that specifies how Cloud Pub/Sub retries message delivery for this subscription. If `nil`, the
558
+ # default retry policy is applied. This generally implies that messages will be retried as soon as possible
559
+ # for healthy subscribers. Retry Policy will be triggered on NACKs or acknowledgement deadline exceeded events
560
+ # for a given message.
561
+ #
562
+ # Makes an API call to retrieve the retry_policy when called on a reference object. See {#reference?}.
563
+ #
564
+ # @return [RetryPolicy, nil] The retry policy for the subscription, or `nil`.
565
+ #
566
+ # @example
567
+ # require "google/cloud/pubsub"
568
+ #
569
+ # pubsub = Google::Cloud::PubSub.new
570
+ #
571
+ # sub = pubsub.subscription "my-topic-sub"
572
+ #
573
+ # sub.retry_policy = Google::Cloud::PubSub::RetryPolicy.new minimum_backoff: 5, maximum_backoff: 300
574
+ #
575
+ # sub.retry_policy.minimum_backoff #=> 5
576
+ # sub.retry_policy.maximum_backoff #=> 300
577
+ #
578
+ def retry_policy
579
+ ensure_grpc!
580
+ return nil unless @grpc.retry_policy
581
+ RetryPolicy.from_grpc @grpc.retry_policy
582
+ end
583
+
584
+ ##
585
+ # Sets a policy that specifies how Cloud Pub/Sub retries message delivery for this subscription. If `nil`, the
586
+ # default retry policy is applied. This generally implies that messages will be retried as soon as possible
587
+ # for healthy subscribers. Retry Policy will be triggered on NACKs or acknowledgement deadline exceeded events
588
+ # for a given message.
589
+ #
590
+ # @param [RetryPolicy, nil] new_retry_policy A new retry policy for the subscription, or `nil`.
591
+ #
592
+ # @example
593
+ # require "google/cloud/pubsub"
594
+ #
595
+ # pubsub = Google::Cloud::PubSub.new
596
+ #
597
+ # sub = pubsub.subscription "my-topic-sub"
598
+ #
599
+ # sub.retry_policy = Google::Cloud::PubSub::RetryPolicy.new minimum_backoff: 5, maximum_backoff: 300
600
+ #
601
+ # sub.retry_policy.minimum_backoff #=> 5
602
+ # sub.retry_policy.maximum_backoff #=> 300
603
+ #
604
+ def retry_policy= new_retry_policy
605
+ ensure_service!
606
+ new_retry_policy = new_retry_policy.to_grpc if new_retry_policy
607
+ update_grpc = Google::Cloud::PubSub::V1::Subscription.new name: name, retry_policy: new_retry_policy
608
+ @grpc = service.update_subscription update_grpc, :retry_policy
609
+ @resource_name = nil
610
+ end
611
+
612
+ ##
613
+ # Whether message ordering has been enabled. When enabled, messages
614
+ # published with the same `ordering_key` will be delivered in the order
615
+ # they were published. When disabled, messages may be delivered in any
616
+ # order.
617
+ #
618
+ # @note At the time of this release, ordering keys are not yet publicly
619
+ # enabled and requires special project enablements.
620
+ #
621
+ # See {Topic#publish_async}, {#listen}, and {Message#ordering_key}.
622
+ #
623
+ # Makes an API call to retrieve the enable_message_ordering value when called on a
624
+ # reference object. See {#reference?}.
625
+ #
626
+ # @return [Boolean]
627
+ #
628
+ def message_ordering?
629
+ ensure_grpc!
630
+ @grpc.enable_message_ordering
631
+ end
632
+
633
+ ##
634
+ # Whether the subscription is detached from its topic. Detached subscriptions don't receive messages from their
635
+ # topic and don't retain any backlog. {#pull} and {#listen} (pull and streaming pull) operations will raise
636
+ # `FAILED_PRECONDITION`. If the subscription is a push subscription (see {#push_config}), pushes to the endpoint
637
+ # will not be made. The default value is `false`.
638
+ #
639
+ # See {Topic#subscribe} and {#detach}.
640
+ #
641
+ # Makes an API call to retrieve the detached value when called on a
642
+ # reference object. See {#reference?}.
643
+ #
644
+ # @return [Boolean]
645
+ #
646
+ # @example
647
+ # require "google/cloud/pubsub"
648
+ #
649
+ # pubsub = Google::Cloud::PubSub.new
650
+ #
651
+ # sub = pubsub.subscription "my-topic-sub"
652
+ # sub.detach
653
+ #
654
+ # # sleep 120
655
+ # sub.detached? #=> true
656
+ #
657
+ def detached?
658
+ ensure_grpc!
659
+ @grpc.detached
660
+ end
661
+
662
+ ##
663
+ # Determines whether the subscription exists in the Pub/Sub service.
664
+ #
665
+ # Makes an API call to determine whether the subscription resource
666
+ # exists when called on a reference object. See {#reference?}.
667
+ #
668
+ # @return [Boolean]
669
+ #
670
+ # @example
671
+ # require "google/cloud/pubsub"
672
+ #
673
+ # pubsub = Google::Cloud::PubSub.new
674
+ #
675
+ # sub = pubsub.subscription "my-topic-sub"
676
+ # sub.exists? #=> true
677
+ #
678
+ def exists?
679
+ # Always true if the object is not set as reference
680
+ return true unless reference?
681
+ # If we have a value, return it
682
+ return @exists unless @exists.nil?
683
+ ensure_grpc!
684
+ @exists = true
685
+ rescue Google::Cloud::NotFoundError
686
+ @exists = false
187
687
  end
188
688
 
189
689
  ##
@@ -195,7 +695,7 @@ module Google
195
695
  # @example
196
696
  # require "google/cloud/pubsub"
197
697
  #
198
- # pubsub = Google::Cloud::Pubsub.new
698
+ # pubsub = Google::Cloud::PubSub.new
199
699
  #
200
700
  # sub = pubsub.subscription "my-topic-sub"
201
701
  # sub.delete
@@ -207,58 +707,92 @@ module Google
207
707
  end
208
708
 
209
709
  ##
210
- # Pulls messages from the server. Returns an empty list if there are no
211
- # messages available in the backlog. Raises an ApiError with status
212
- # `UNAVAILABLE` if there are too many concurrent pull requests pending
213
- # for the given subscription.
710
+ # Detaches a subscription from its topic. All messages retained in the subscription are dropped. Detached
711
+ # subscriptions don't receive messages from their topic and don't retain any backlog. Subsequent {#pull} and
712
+ # {#listen} (pull and streaming pull) operations will raise `FAILED_PRECONDITION`. If the subscription is a push
713
+ # subscription (see {#push_config}), pushes to the endpoint will stop. It may take a few minutes for the
714
+ # subscription's detached state to be reflected in subsequent calls to {#detached?}.
214
715
  #
215
- # @param [Boolean] immediate When `true` the system will respond
216
- # immediately even if it is not able to return messages. When `false`
217
- # the system is allowed to wait until it can return least one message.
218
- # No messages are returned when a request times out. The default value
219
- # is `true`.
220
- # @param [Integer] max The maximum number of messages to return for this
221
- # request. The Pub/Sub system may return fewer than the number
222
- # specified. The default value is `100`, the maximum value is `1000`.
223
- # @param [Boolean] autoack Automatically acknowledge the message as it
224
- # is pulled. The default value is `false`.
225
- #
226
- # @return [Array<Google::Cloud::Pubsub::ReceivedMessage>]
716
+ # @return [Boolean] Returns `true` if the detach operation was successful.
227
717
  #
228
718
  # @example
229
719
  # require "google/cloud/pubsub"
230
720
  #
231
- # pubsub = Google::Cloud::Pubsub.new
721
+ # pubsub = Google::Cloud::PubSub.new
232
722
  #
233
723
  # sub = pubsub.subscription "my-topic-sub"
234
- # sub.pull.each { |msg| msg.acknowledge! }
724
+ # sub.detach
235
725
  #
236
- # @example A maximum number of messages returned can also be specified:
726
+ # # sleep 120
727
+ # sub.detached? #=> true
728
+ #
729
+ def detach
730
+ ensure_service!
731
+ service.detach_subscription name
732
+ true
733
+ end
734
+
735
+ ##
736
+ # Pulls messages from the server, blocking until messages are available
737
+ # when called with the `immediate: false` option, which is recommended
738
+ # to avoid adverse impacts on the performance of pull operations.
739
+ #
740
+ # Raises an API error with status `UNAVAILABLE` if there are too many
741
+ # concurrent pull requests pending for the given subscription.
742
+ #
743
+ # See also {#listen} for the preferred way to process messages as they
744
+ # become available.
745
+ #
746
+ # @param [Boolean] immediate Whether to return immediately or block until
747
+ # messages are available.
748
+ #
749
+ # **Warning:** The default value of this field is `true`. However, sending
750
+ # `true` is discouraged because it adversely impacts the performance of
751
+ # pull operations. We recommend that users always explicitly set this field
752
+ # to `false`.
753
+ #
754
+ # If this field set to `true`, the system will respond immediately
755
+ # even if it there are no messages available to return in the pull
756
+ # response. Otherwise, the system may wait (for a bounded amount of time)
757
+ # until at least one message is available, rather than returning no messages.
758
+ #
759
+ # See also {#listen} for the preferred way to process messages as they
760
+ # become available.
761
+ # @param [Integer] max The maximum number of messages to return for this
762
+ # request. The Pub/Sub system may return fewer than the number
763
+ # specified. The default value is `100`, the maximum value is `1000`.
764
+ #
765
+ # @return [Array<Google::Cloud::PubSub::ReceivedMessage>]
766
+ #
767
+ # @example The `immediate: false` option is now recommended to avoid adverse impacts on pull operations:
237
768
  # require "google/cloud/pubsub"
238
769
  #
239
- # pubsub = Google::Cloud::Pubsub.new
770
+ # pubsub = Google::Cloud::PubSub.new
240
771
  #
241
772
  # sub = pubsub.subscription "my-topic-sub"
242
- # sub.pull(max: 10).each { |msg| msg.acknowledge! }
773
+ # received_messages = sub.pull immediate: false
774
+ # received_messages.each do |received_message|
775
+ # received_message.acknowledge!
776
+ # end
243
777
  #
244
- # @example The call can block until messages are available:
778
+ # @example A maximum number of messages returned can also be specified:
245
779
  # require "google/cloud/pubsub"
246
780
  #
247
- # pubsub = Google::Cloud::Pubsub.new
781
+ # pubsub = Google::Cloud::PubSub.new
248
782
  #
249
783
  # sub = pubsub.subscription "my-topic-sub"
250
- # msgs = sub.pull immediate: false
251
- # msgs.each { |msg| msg.acknowledge! }
784
+ # received_messages = sub.pull immediate: false, max: 10
785
+ # received_messages.each do |received_message|
786
+ # received_message.acknowledge!
787
+ # end
252
788
  #
253
- def pull immediate: true, max: 100, autoack: false
789
+ def pull immediate: true, max: 100
254
790
  ensure_service!
255
791
  options = { immediate: immediate, max: max }
256
792
  list_grpc = service.pull name, options
257
- messages = Array(list_grpc.received_messages).map do |msg_grpc|
793
+ Array(list_grpc.received_messages).map do |msg_grpc|
258
794
  ReceivedMessage.from_grpc msg_grpc, self
259
795
  end
260
- acknowledge messages if autoack
261
- messages
262
796
  rescue Google::Cloud::DeadlineExceededError
263
797
  []
264
798
  end
@@ -269,82 +803,194 @@ module Google
269
803
  #
270
804
  # subscription.pull immediate: false
271
805
  #
806
+ # See also {#listen} for the preferred way to process messages as they
807
+ # become available.
808
+ #
272
809
  # @param [Integer] max The maximum number of messages to return for this
273
810
  # request. The Pub/Sub system may return fewer than the number
274
811
  # specified. The default value is `100`, the maximum value is `1000`.
275
- # @param [Boolean] autoack Automatically acknowledge the message as it
276
- # is pulled. The default value is `false`.
277
812
  #
278
- # @return [Array<Google::Cloud::Pubsub::ReceivedMessage>]
813
+ # @return [Array<Google::Cloud::PubSub::ReceivedMessage>]
279
814
  #
280
815
  # @example
281
816
  # require "google/cloud/pubsub"
282
817
  #
283
- # pubsub = Google::Cloud::Pubsub.new
818
+ # pubsub = Google::Cloud::PubSub.new
284
819
  #
285
820
  # sub = pubsub.subscription "my-topic-sub"
286
- # msgs = sub.wait_for_messages
287
- # msgs.each { |msg| msg.acknowledge! }
821
+ # received_messages = sub.wait_for_messages
822
+ # received_messages.each do |received_message|
823
+ # received_message.acknowledge!
824
+ # end
288
825
  #
289
- def wait_for_messages max: 100, autoack: false
290
- pull immediate: false, max: max, autoack: autoack
826
+ def wait_for_messages max: 100
827
+ pull immediate: false, max: max
291
828
  end
292
829
 
293
830
  ##
294
- # Poll the backend for new messages. This runs a loop to ping the API,
295
- # blocking indefinitely, yielding retrieved messages as they are
296
- # received.
297
- #
298
- # @param [Integer] max The maximum number of messages to return for this
299
- # request. The Pub/Sub system may return fewer than the number
300
- # specified. The default value is `100`, the maximum value is `1000`.
301
- # @param [Boolean] autoack Automatically acknowledge the message as it
302
- # is pulled. The default value is `false`.
303
- # @param [Number] delay The number of seconds to pause between requests
304
- # when the Google Cloud service has no messages to return. The default
305
- # value is `1`.
306
- # @yield [msg] a block for processing new messages
307
- # @yieldparam [ReceivedMessage] msg the newly received message
831
+ # Create a {Subscriber} object that receives and processes messages
832
+ # using the code provided in the callback. Messages passed to the
833
+ # callback should acknowledge ({ReceivedMessage#acknowledge!}) or reject
834
+ # ({ReceivedMessage#reject!}) the message. If no action is taken, the
835
+ # message will be removed from the subscriber and made available for
836
+ # redelivery after the callback is completed.
837
+ #
838
+ # Google Cloud Pub/Sub ordering keys provide the ability to ensure
839
+ # related messages are sent to subscribers in the order in which they
840
+ # were published. Messages can be tagged with an ordering key, a string
841
+ # that identifies related messages for which publish order should be
842
+ # respected. The service guarantees that, for a given ordering key and
843
+ # publisher, messages are sent to subscribers in the order in which they
844
+ # were published. Ordering does not require sacrificing high throughput
845
+ # or scalability, as the service automatically distributes messages for
846
+ # different ordering keys across subscribers.
847
+ #
848
+ # To use ordering keys, the subscription must be created with message
849
+ # ordering enabled (See {Topic#subscribe} and {#message_ordering?})
850
+ # before calling {#listen}. When enabled, the subscriber will deliver
851
+ # messages with the same `ordering_key` in the order they were
852
+ # published.
853
+ #
854
+ # @note At the time of this release, ordering keys are not yet publicly
855
+ # enabled and requires special project enablements.
856
+ #
857
+ # @param [Numeric] deadline The default number of seconds the stream
858
+ # will hold received messages before modifying the message's ack
859
+ # deadline. The minimum is 10, the maximum is 600. Default is
860
+ # {#deadline}. Optional.
861
+ #
862
+ # When using a reference object an API call will be made to retrieve
863
+ # the default deadline value for the subscription when this argument
864
+ # is not provided. See {#reference?}.
865
+ # @param [Boolean] message_ordering Whether message ordering has been
866
+ # enabled. The value provided must match the value set on the Pub/Sub
867
+ # service. See {#message_ordering?}. Optional.
868
+ #
869
+ # When using a reference object an API call will be made to retrieve
870
+ # the default message_ordering value for the subscription when this
871
+ # argument is not provided. See {#reference?}.
872
+ # @param [Integer] streams The number of concurrent streams to open to
873
+ # pull messages from the subscription. Default is 4. Optional.
874
+ # @param [Hash, Integer] inventory The settings to control how received messages are to be handled by the
875
+ # subscriber. When provided as an Integer instead of a Hash only `max_outstanding_messages` will be set.
876
+ # Optional.
877
+ #
878
+ # Hash keys and values may include the following:
879
+ #
880
+ # * `:max_outstanding_messages` [Integer] The number of received messages to be collected by subscriber.
881
+ # Default is 1,000. (Note: replaces `:limit`, which is deprecated.)
882
+ # * `:max_outstanding_bytes` [Integer] The total byte size of received messages to be collected by
883
+ # subscriber. Default is 100,000,000 (100MB). (Note: replaces `:bytesize`, which is deprecated.)
884
+ # * `:use_legacy_flow_control` [Boolean] Disables enforcing flow control settings at the Cloud PubSub
885
+ # server and the less accurate method of only enforcing flow control at the client side is used instead.
886
+ # Default is false.
887
+ # * `:max_total_lease_duration` [Integer] The number of seconds that received messages can be held awaiting
888
+ # processing. Default is 3,600 (1 hour). (Note: replaces `:extension`, which is deprecated.)
889
+ # * `:max_duration_per_lease_extension` [Integer] The maximum amount of time in seconds for a single lease
890
+ # extension attempt. Bounds the delay before a message redelivery if the subscriber fails to extend the
891
+ # deadline. Default is 0 (disabled).
892
+ # @param [Hash] threads The number of threads to create to handle
893
+ # concurrent calls by each stream opened by the subscriber. Optional.
894
+ #
895
+ # Hash keys and values may include the following:
896
+ #
897
+ # * `:callback` (Integer) The number of threads used to handle the
898
+ # received messages. Default is 8.
899
+ # * `:push` (Integer) The number of threads to handle
900
+ # acknowledgement ({ReceivedMessage#ack!}) and modify ack deadline
901
+ # messages ({ReceivedMessage#nack!},
902
+ # {ReceivedMessage#modify_ack_deadline!}). Default is 4.
903
+ #
904
+ # @yield [received_message] a block for processing new messages
905
+ # @yieldparam [ReceivedMessage] received_message the newly received
906
+ # message
907
+ #
908
+ # @return [Subscriber]
308
909
  #
309
910
  # @example
310
911
  # require "google/cloud/pubsub"
311
912
  #
312
- # pubsub = Google::Cloud::Pubsub.new
913
+ # pubsub = Google::Cloud::PubSub.new
313
914
  #
314
915
  # sub = pubsub.subscription "my-topic-sub"
315
- # sub.listen do |msg|
316
- # # process msg
916
+ #
917
+ # subscriber = sub.listen do |received_message|
918
+ # # process message
919
+ # puts "Data: #{received_message.message.data}, published at #{received_message.message.published_at}"
920
+ # received_message.acknowledge!
317
921
  # end
318
922
  #
319
- # @example Limit number of messages pulled per API request with `max`:
923
+ # # Start background threads that will call block passed to listen.
924
+ # subscriber.start
925
+ #
926
+ # # Shut down the subscriber when ready to stop receiving messages.
927
+ # subscriber.stop!
928
+ #
929
+ # @example Configuring to increase concurrent callbacks:
320
930
  # require "google/cloud/pubsub"
321
931
  #
322
- # pubsub = Google::Cloud::Pubsub.new
932
+ # pubsub = Google::Cloud::PubSub.new
323
933
  #
324
934
  # sub = pubsub.subscription "my-topic-sub"
325
- # sub.listen max: 20 do |msg|
326
- # # process msg
935
+ #
936
+ # subscriber = sub.listen threads: { callback: 16 } do |rec_message|
937
+ # # store the message somewhere before acknowledging
938
+ # store_in_backend rec_message.data # takes a few seconds
939
+ # rec_message.acknowledge!
327
940
  # end
328
941
  #
329
- # @example Automatically acknowledge messages with `autoack`:
942
+ # # Start background threads that will call block passed to listen.
943
+ # subscriber.start
944
+ #
945
+ # # Shut down the subscriber when ready to stop receiving messages.
946
+ # subscriber.stop!
947
+ #
948
+ # @example Ordered messages are supported using ordering_key:
330
949
  # require "google/cloud/pubsub"
331
950
  #
332
- # pubsub = Google::Cloud::Pubsub.new
951
+ # pubsub = Google::Cloud::PubSub.new
952
+ #
953
+ # sub = pubsub.subscription "my-ordered-topic-sub"
954
+ # sub.message_ordering? #=> true
955
+ #
956
+ # subscriber = sub.listen do |received_message|
957
+ # # messsages with the same ordering_key are received
958
+ # # in the order in which they were published.
959
+ # received_message.acknowledge!
960
+ # end
961
+ #
962
+ # # Start background threads that will call block passed to listen.
963
+ # subscriber.start
964
+ #
965
+ # # Shut down the subscriber when ready to stop receiving messages.
966
+ # subscriber.stop!
967
+ #
968
+ # @example Set the maximum amount of time before redelivery if the subscriber fails to extend the deadline:
969
+ # require "google/cloud/pubsub"
970
+ #
971
+ # pubsub = Google::Cloud::PubSub.new
333
972
  #
334
973
  # sub = pubsub.subscription "my-topic-sub"
335
- # sub.listen autoack: true do |msg|
336
- # # process msg
974
+ #
975
+ # subscriber = sub.listen inventory: { max_duration_per_lease_extension: 20 } do |received_message|
976
+ # # Process message very slowly with possibility of failure.
977
+ # process rec_message.data # takes minutes
978
+ # rec_message.acknowledge!
337
979
  # end
338
980
  #
339
- def listen max: 100, autoack: false, delay: 1
340
- loop do
341
- msgs = wait_for_messages max: max, autoack: autoack
342
- if msgs.any?
343
- msgs.each { |msg| yield msg }
344
- else
345
- sleep delay
346
- end
347
- end
981
+ # # Start background threads that will call block passed to listen.
982
+ # subscriber.start
983
+ #
984
+ # # Shut down the subscriber when ready to stop receiving messages.
985
+ # subscriber.stop!
986
+ #
987
+ def listen deadline: nil, message_ordering: nil, streams: nil, inventory: nil, threads: {}, &block
988
+ ensure_service!
989
+ deadline ||= self.deadline
990
+ message_ordering = message_ordering? if message_ordering.nil?
991
+
992
+ Subscriber.new name, block, deadline: deadline, streams: streams, inventory: inventory,
993
+ message_ordering: message_ordering, threads: threads, service: service
348
994
  end
349
995
 
350
996
  ##
@@ -355,17 +1001,19 @@ module Google
355
1001
  # Acknowledging a message more than once will not result in an error.
356
1002
  # This is only used for messages received via pull.
357
1003
  #
1004
+ # See also {ReceivedMessage#acknowledge!}.
1005
+ #
358
1006
  # @param [ReceivedMessage, String] messages One or more
359
1007
  # {ReceivedMessage} objects or ack_id values.
360
1008
  #
361
1009
  # @example
362
1010
  # require "google/cloud/pubsub"
363
1011
  #
364
- # pubsub = Google::Cloud::Pubsub.new
1012
+ # pubsub = Google::Cloud::PubSub.new
365
1013
  #
366
1014
  # sub = pubsub.subscription "my-topic-sub"
367
- # messages = sub.pull
368
- # sub.acknowledge messages
1015
+ # received_messages = sub.pull immediate: false
1016
+ # sub.acknowledge received_messages
369
1017
  #
370
1018
  def acknowledge *messages
371
1019
  ack_ids = coerce_ack_ids messages
@@ -374,7 +1022,7 @@ module Google
374
1022
  service.acknowledge name, *ack_ids
375
1023
  true
376
1024
  end
377
- alias_method :ack, :acknowledge
1025
+ alias ack acknowledge
378
1026
 
379
1027
  ##
380
1028
  # Modifies the acknowledge deadline for messages.
@@ -383,6 +1031,8 @@ module Google
383
1031
  # make the messages available for redelivery if the processing was
384
1032
  # interrupted.
385
1033
  #
1034
+ # See also {ReceivedMessage#modify_ack_deadline!}.
1035
+ #
386
1036
  # @param [Integer] new_deadline The new ack deadline in seconds from the
387
1037
  # time this request is sent to the Pub/Sub system. Must be >= 0. For
388
1038
  # example, if the value is `10`, the new ack deadline will expire 10
@@ -394,13 +1044,13 @@ module Google
394
1044
  # @example
395
1045
  # require "google/cloud/pubsub"
396
1046
  #
397
- # pubsub = Google::Cloud::Pubsub.new
1047
+ # pubsub = Google::Cloud::PubSub.new
398
1048
  #
399
1049
  # sub = pubsub.subscription "my-topic-sub"
400
- # messages = sub.pull
401
- # sub.delay 120, messages
1050
+ # received_messages = sub.pull immediate: false
1051
+ # sub.modify_ack_deadline 120, received_messages
402
1052
  #
403
- def delay new_deadline, *messages
1053
+ def modify_ack_deadline new_deadline, *messages
404
1054
  ack_ids = coerce_ack_ids messages
405
1055
  ensure_service!
406
1056
  service.modify_ack_deadline name, ack_ids, new_deadline
@@ -418,21 +1068,34 @@ module Google
418
1068
  # * Any messages published to the subscription's topic following the
419
1069
  # successful completion of the `create_snapshot` operation.
420
1070
  #
421
- # @param [String, nil] snapshot_name Name of the new snapshot. If the
422
- # name is not provided, the server will assign a random name
423
- # for this snapshot on the same project as the subscription. The
424
- # format is `projects/{project}/snapshots/{snap}`. The name must start
425
- # with a letter, and contain only letters ([A-Za-z]), numbers
426
- # ([0-9], dashes (-), underscores (_), periods (.), tildes (~), plus
427
- # (+) or percent signs (%). It must be between 3 and 255 characters in
428
- # length, and it must not start with "goog". Optional.
429
- #
430
- # @return [Google::Cloud::Pubsub::Snapshot]
1071
+ # @param [String, nil] snapshot_name Name of the new snapshot. Optional.
1072
+ # If the name is not provided, the server will assign a random name
1073
+ # for this snapshot on the same project as the subscription.
1074
+ # The value can be a simple snapshot ID (relative name), in which
1075
+ # case the current project ID will be supplied, or a fully-qualified
1076
+ # snapshot name in the form
1077
+ # `projects/{project_id}/snapshots/{snapshot_id}`.
1078
+ #
1079
+ # The snapshot ID (relative name) must start with a letter, and
1080
+ # contain only letters (`[A-Za-z]`), numbers (`[0-9]`), dashes (`-`),
1081
+ # underscores (`_`), periods (`.`), tildes (`~`), plus (`+`) or percent
1082
+ # signs (`%`). It must be between 3 and 255 characters in length, and
1083
+ # it must not start with `goog`.
1084
+ # @param [Hash] labels A hash of user-provided labels associated with
1085
+ # the snapshot. You can use these to organize and group your
1086
+ # snapshots. Label keys and values can be no longer than 63
1087
+ # characters, can only contain lowercase letters, numeric characters,
1088
+ # underscores and dashes. International characters are allowed. Label
1089
+ # values are optional. Label keys must start with a letter and each
1090
+ # label in the list must have a different key. See [Creating and
1091
+ # Managing Labels](https://cloud.google.com/pubsub/docs/labels).
1092
+ #
1093
+ # @return [Google::Cloud::PubSub::Snapshot]
431
1094
  #
432
1095
  # @example
433
1096
  # require "google/cloud/pubsub"
434
1097
  #
435
- # pubsub = Google::Cloud::Pubsub.new
1098
+ # pubsub = Google::Cloud::PubSub.new
436
1099
  # sub = pubsub.subscription "my-sub"
437
1100
  #
438
1101
  # snapshot = sub.create_snapshot "my-snapshot"
@@ -441,18 +1104,18 @@ module Google
441
1104
  # @example Without providing a name:
442
1105
  # require "google/cloud/pubsub"
443
1106
  #
444
- # pubsub = Google::Cloud::Pubsub.new
1107
+ # pubsub = Google::Cloud::PubSub.new
445
1108
  # sub = pubsub.subscription "my-sub"
446
1109
  #
447
1110
  # snapshot = sub.create_snapshot
448
1111
  # snapshot.name #=> "projects/my-project/snapshots/gcr-analysis-..."
449
1112
  #
450
- def create_snapshot snapshot_name = nil
1113
+ def create_snapshot snapshot_name = nil, labels: nil
451
1114
  ensure_service!
452
- grpc = service.create_snapshot name, snapshot_name
1115
+ grpc = service.create_snapshot name, snapshot_name, labels: labels
453
1116
  Snapshot.from_grpc grpc, service
454
1117
  end
455
- alias_method :new_snapshot, :create_snapshot
1118
+ alias new_snapshot create_snapshot
456
1119
 
457
1120
  ##
458
1121
  # Resets the subscription's backlog to a given {Snapshot} or to a point
@@ -477,26 +1140,26 @@ module Google
477
1140
  # @example Using a snapshot
478
1141
  # require "google/cloud/pubsub"
479
1142
  #
480
- # pubsub = Google::Cloud::Pubsub.new
1143
+ # pubsub = Google::Cloud::PubSub.new
481
1144
  # sub = pubsub.subscription "my-sub"
482
1145
  #
483
1146
  # snapshot = sub.create_snapshot
484
1147
  #
485
- # messages = sub.pull
486
- # sub.acknowledge messages
1148
+ # received_messages = sub.pull immediate: false
1149
+ # sub.acknowledge received_messages
487
1150
  #
488
1151
  # sub.seek snapshot
489
1152
  #
490
1153
  # @example Using a time:
491
1154
  # require "google/cloud/pubsub"
492
1155
  #
493
- # pubsub = Google::Cloud::Pubsub.new
1156
+ # pubsub = Google::Cloud::PubSub.new
494
1157
  # sub = pubsub.subscription "my-sub"
495
1158
  #
496
1159
  # time = Time.now
497
1160
  #
498
- # messages = sub.pull
499
- # sub.acknowledge messages
1161
+ # received_messages = sub.pull immediate: false
1162
+ # sub.acknowledge received_messages
500
1163
  #
501
1164
  # sub.seek time
502
1165
  #
@@ -506,6 +1169,66 @@ module Google
506
1169
  true
507
1170
  end
508
1171
 
1172
+ ##
1173
+ # Determines whether the subscription object was created without
1174
+ # retrieving the resource representation from the Pub/Sub service.
1175
+ #
1176
+ # @return [Boolean] `true` when the subscription was created without a
1177
+ # resource representation, `false` otherwise.
1178
+ #
1179
+ # @example
1180
+ # require "google/cloud/pubsub"
1181
+ #
1182
+ # pubsub = Google::Cloud::PubSub.new
1183
+ #
1184
+ # sub = pubsub.get_subscription "my-topic-sub", skip_lookup: true
1185
+ # sub.reference? #=> true
1186
+ #
1187
+ def reference?
1188
+ @grpc.nil?
1189
+ end
1190
+
1191
+ ##
1192
+ # Determines whether the subscription object was created with a resource
1193
+ # representation from the Pub/Sub service.
1194
+ #
1195
+ # @return [Boolean] `true` when the subscription was created with a
1196
+ # resource representation, `false` otherwise.
1197
+ #
1198
+ # @example
1199
+ # require "google/cloud/pubsub"
1200
+ #
1201
+ # pubsub = Google::Cloud::PubSub.new
1202
+ #
1203
+ # sub = pubsub.get_subscription "my-topic-sub"
1204
+ # sub.resource? #=> true
1205
+ #
1206
+ def resource?
1207
+ !@grpc.nil?
1208
+ end
1209
+
1210
+ ##
1211
+ # Reloads the subscription with current data from the Pub/Sub service.
1212
+ #
1213
+ # @return [Google::Cloud::PubSub::Subscription] Returns the reloaded
1214
+ # subscription
1215
+ #
1216
+ # @example
1217
+ # require "google/cloud/pubsub"
1218
+ #
1219
+ # pubsub = Google::Cloud::PubSub.new
1220
+ #
1221
+ # sub = pubsub.get_subscription "my-topic-sub"
1222
+ # sub.reload!
1223
+ #
1224
+ def reload!
1225
+ ensure_service!
1226
+ @grpc = service.get_subscription name
1227
+ @resource_name = nil
1228
+ self
1229
+ end
1230
+ alias refresh! reload!
1231
+
509
1232
  ##
510
1233
  # Gets the [Cloud IAM](https://cloud.google.com/iam/) access control
511
1234
  # policy for this subscription.
@@ -525,7 +1248,7 @@ module Google
525
1248
  # @example
526
1249
  # require "google/cloud/pubsub"
527
1250
  #
528
- # pubsub = Google::Cloud::Pubsub.new
1251
+ # pubsub = Google::Cloud::PubSub.new
529
1252
  # sub = pubsub.subscription "my-subscription"
530
1253
  #
531
1254
  # policy = sub.policy
@@ -533,7 +1256,7 @@ module Google
533
1256
  # @example Update the policy by passing a block:
534
1257
  # require "google/cloud/pubsub"
535
1258
  #
536
- # pubsub = Google::Cloud::Pubsub.new
1259
+ # pubsub = Google::Cloud::PubSub.new
537
1260
  # sub = pubsub.subscription "my-subscription"
538
1261
  #
539
1262
  # sub.policy do |p|
@@ -546,13 +1269,13 @@ module Google
546
1269
  policy = Policy.from_grpc grpc
547
1270
  return policy unless block_given?
548
1271
  yield policy
549
- self.policy = policy
1272
+ update_policy policy
550
1273
  end
551
1274
 
552
1275
  ##
553
1276
  # Updates the [Cloud IAM](https://cloud.google.com/iam/) access control
554
1277
  # policy for this subscription. The policy should be read from
555
- # {#policy}. See {Google::Cloud::Pubsub::Policy} for an explanation of
1278
+ # {#policy}. See {Google::Cloud::PubSub::Policy} for an explanation of
556
1279
  # the policy `etag` property and how to modify policies.
557
1280
  #
558
1281
  # You can also update the policy by passing a block to {#policy}, which
@@ -569,20 +1292,21 @@ module Google
569
1292
  # @example
570
1293
  # require "google/cloud/pubsub"
571
1294
  #
572
- # pubsub = Google::Cloud::Pubsub.new
1295
+ # pubsub = Google::Cloud::PubSub.new
573
1296
  # sub = pubsub.subscription "my-subscription"
574
1297
  #
575
1298
  # policy = sub.policy # API call
576
1299
  #
577
1300
  # policy.add "roles/owner", "user:owner@example.com"
578
1301
  #
579
- # sub.policy = policy # API call
1302
+ # sub.update_policy policy # API call
580
1303
  #
581
- def policy= new_policy
1304
+ def update_policy new_policy
582
1305
  ensure_service!
583
1306
  grpc = service.set_subscription_policy name, new_policy.to_grpc
584
1307
  Policy.from_grpc grpc
585
1308
  end
1309
+ alias policy= update_policy
586
1310
 
587
1311
  ##
588
1312
  # Tests the specified permissions against the [Cloud
@@ -609,7 +1333,7 @@ module Google
609
1333
  # @example
610
1334
  # require "google/cloud/pubsub"
611
1335
  #
612
- # pubsub = Google::Cloud::Pubsub.new
1336
+ # pubsub = Google::Cloud::PubSub.new
613
1337
  # sub = pubsub.subscription "my-subscription"
614
1338
  # perms = sub.test_permissions "pubsub.subscriptions.get",
615
1339
  # "pubsub.subscriptions.consume"
@@ -624,7 +1348,8 @@ module Google
624
1348
  end
625
1349
 
626
1350
  ##
627
- # @private New Subscription from a Google::Pubsub::V1::Subscription
1351
+ # @private
1352
+ # New Subscription from a Google::Cloud::PubSub::V1::Subscription
628
1353
  # object.
629
1354
  def self.from_grpc grpc, service
630
1355
  new.tap do |f|
@@ -633,29 +1358,30 @@ module Google
633
1358
  end
634
1359
  end
635
1360
 
636
- protected
637
-
638
- def duration_to_number duration
639
- return nil if duration.nil?
640
-
641
- return duration.seconds if duration.nanos == 0
642
-
643
- duration.seconds + (duration.nanos / 1000000000.0)
1361
+ ##
1362
+ # @private New reference {Subscription} object without making an HTTP
1363
+ # request.
1364
+ def self.from_name name, service, options = {}
1365
+ name = service.subscription_path name, options
1366
+ from_grpc(nil, service).tap do |s|
1367
+ s.instance_variable_set :@resource_name, name
1368
+ end
644
1369
  end
645
1370
 
1371
+ protected
1372
+
646
1373
  ##
647
1374
  # @private Raise an error unless an active connection to the service is
648
1375
  # available.
649
1376
  def ensure_service!
650
- fail "Must have active connection to service" unless service
1377
+ raise "Must have active connection to service" unless service
651
1378
  end
652
1379
 
653
1380
  ##
654
- # Ensures a Google::Pubsub::V1::Subscription object exists.
1381
+ # Ensures a Google::Cloud::PubSub::V1::Subscription object exists.
655
1382
  def ensure_grpc!
656
1383
  ensure_service!
657
- return @grpc if @grpc
658
- @grpc = service.get_subscription @name
1384
+ reload! if reference?
659
1385
  end
660
1386
 
661
1387
  ##
@@ -668,5 +1394,7 @@ module Google
668
1394
  end
669
1395
  end
670
1396
  end
1397
+
1398
+ Pubsub = PubSub unless const_defined? :Pubsub
671
1399
  end
672
1400
  end