google-cloud-pubsub 0.26.0 → 2.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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