google-cloud-pubsub 1.9.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/AUTHENTICATION.md +2 -1
  3. data/CHANGELOG.md +53 -0
  4. data/OVERVIEW.md +26 -58
  5. data/lib/google-cloud-pubsub.rb +14 -13
  6. data/lib/google/cloud/pubsub.rb +15 -18
  7. data/lib/google/cloud/pubsub/async_publisher.rb +2 -3
  8. data/lib/google/cloud/pubsub/credentials.rb +2 -2
  9. data/lib/google/cloud/pubsub/message.rb +1 -1
  10. data/lib/google/cloud/pubsub/project.rb +1 -1
  11. data/lib/google/cloud/pubsub/received_message.rb +4 -4
  12. data/lib/google/cloud/pubsub/service.rb +110 -257
  13. data/lib/google/cloud/pubsub/subscriber.rb +3 -3
  14. data/lib/google/cloud/pubsub/subscriber/stream.rb +1 -2
  15. data/lib/google/cloud/pubsub/subscription.rb +124 -22
  16. data/lib/google/cloud/pubsub/subscription/push_config.rb +55 -31
  17. data/lib/google/cloud/pubsub/topic.rb +50 -15
  18. data/lib/google/cloud/pubsub/version.rb +1 -1
  19. metadata +8 -79
  20. data/lib/google/cloud/pubsub/v1.rb +0 -17
  21. data/lib/google/cloud/pubsub/v1/credentials.rb +0 -41
  22. data/lib/google/cloud/pubsub/v1/doc/google/iam/v1/iam_policy.rb +0 -21
  23. data/lib/google/cloud/pubsub/v1/doc/google/iam/v1/options.rb +0 -21
  24. data/lib/google/cloud/pubsub/v1/doc/google/iam/v1/policy.rb +0 -21
  25. data/lib/google/cloud/pubsub/v1/doc/google/protobuf/duration.rb +0 -91
  26. data/lib/google/cloud/pubsub/v1/doc/google/protobuf/empty.rb +0 -29
  27. data/lib/google/cloud/pubsub/v1/doc/google/protobuf/field_mask.rb +0 -222
  28. data/lib/google/cloud/pubsub/v1/doc/google/protobuf/timestamp.rb +0 -113
  29. data/lib/google/cloud/pubsub/v1/doc/google/pubsub/v1/pubsub.rb +0 -833
  30. data/lib/google/cloud/pubsub/v1/doc/google/type/expr.rb +0 -19
  31. data/lib/google/cloud/pubsub/v1/publisher_client.rb +0 -928
  32. data/lib/google/cloud/pubsub/v1/publisher_client_config.json +0 -120
  33. data/lib/google/cloud/pubsub/v1/subscriber_client.rb +0 -1466
  34. data/lib/google/cloud/pubsub/v1/subscriber_client_config.json +0 -153
  35. data/lib/google/pubsub/v1/pubsub_pb.rb +0 -269
  36. data/lib/google/pubsub/v1/pubsub_services_pb.rb +0 -215
@@ -18,17 +18,15 @@ require "google/cloud/pubsub/credentials"
18
18
  require "google/cloud/pubsub/convert"
19
19
  require "google/cloud/pubsub/version"
20
20
  require "google/cloud/pubsub/v1"
21
- require "google/gax/errors"
22
21
  require "securerandom"
23
22
 
24
23
  module Google
25
24
  module Cloud
26
25
  module PubSub
27
26
  ##
28
- # @private Represents the GAX Pub/Sub service, including all the API
29
- # methods.
27
+ # @private Represents the Pub/Sub service API, including IAM mixins.
30
28
  class Service
31
- attr_accessor :project, :credentials, :host, :timeout, :client_config
29
+ attr_accessor :project, :credentials, :host, :timeout
32
30
  ###
33
31
  # The same client_id is used across all streaming pull connections that are created by this client. This is
34
32
  # intentional, as it indicates to the server that any guarantees, such as message ordering, made for a stream
@@ -38,44 +36,25 @@ module Google
38
36
 
39
37
  ##
40
38
  # Creates a new Service instance.
41
- def initialize project, credentials, host: nil, timeout: nil,
42
- client_config: nil
39
+ def initialize project, credentials, host: nil, timeout: nil
43
40
  @project = project
44
41
  @credentials = credentials
45
- @host = host || V1::PublisherClient::SERVICE_ADDRESS
42
+ @host = host
46
43
  @timeout = timeout
47
- @client_config = client_config || {}
48
44
  @client_id = SecureRandom.uuid.freeze
49
45
  end
50
46
 
51
- def channel
52
- require "grpc"
53
- GRPC::Core::Channel.new host, chan_args, chan_creds
54
- end
55
-
56
- def chan_args
57
- { "grpc.max_send_message_length" => -1,
58
- "grpc.max_receive_message_length" => -1,
59
- "grpc.keepalive_time_ms" => 300_000,
60
- "grpc.service_config_disable_resolution" => 1 }
61
- end
62
-
63
- def chan_creds
64
- return credentials if insecure?
65
- require "grpc"
66
- GRPC::Core::ChannelCredentials.new.compose GRPC::Core::CallCredentials.new credentials.client.updater_proc
67
- end
68
-
69
47
  def subscriber
70
48
  return mocked_subscriber if mocked_subscriber
71
49
  @subscriber ||= begin
72
- V1::SubscriberClient.new(
73
- credentials: channel,
74
- timeout: timeout,
75
- client_config: client_config,
76
- lib_name: "gccl",
77
- lib_version: Google::Cloud::PubSub::VERSION
78
- )
50
+ V1::Subscriber::Client.new do |config|
51
+ config.credentials = credentials if credentials
52
+ config.timeout = timeout if timeout
53
+ config.endpoint = host if host
54
+ config.lib_name = "gccl"
55
+ config.lib_version = Google::Cloud::PubSub::VERSION
56
+ config.metadata = { "google-cloud-resource-prefix": "projects/#{@project}" }
57
+ end
79
58
  end
80
59
  end
81
60
  attr_accessor :mocked_subscriber
@@ -83,20 +62,32 @@ module Google
83
62
  def publisher
84
63
  return mocked_publisher if mocked_publisher
85
64
  @publisher ||= begin
86
- V1::PublisherClient.new(
87
- credentials: channel,
88
- timeout: timeout,
89
- client_config: client_config,
90
- lib_name: "gccl",
91
- lib_version: Google::Cloud::PubSub::VERSION
92
- )
65
+ V1::Publisher::Client.new do |config|
66
+ config.credentials = credentials if credentials
67
+ config.timeout = timeout if timeout
68
+ config.endpoint = host if host
69
+ config.lib_name = "gccl"
70
+ config.lib_version = Google::Cloud::PubSub::VERSION
71
+ config.metadata = { "google-cloud-resource-prefix": "projects/#{@project}" }
72
+ end
93
73
  end
94
74
  end
95
75
  attr_accessor :mocked_publisher
96
76
 
97
- def insecure?
98
- credentials == :this_channel_is_insecure
77
+ def iam
78
+ return mocked_iam if mocked_iam
79
+ @iam ||= begin
80
+ V1::IAMPolicy::Client.new do |config|
81
+ config.credentials = credentials if credentials
82
+ config.timeout = timeout if timeout
83
+ config.endpoint = host if host
84
+ config.lib_name = "gccl"
85
+ config.lib_version = Google::Cloud::PubSub::VERSION
86
+ config.metadata = { "google-cloud-resource-prefix" => "projects/#{@project}" }
87
+ end
88
+ end
99
89
  end
90
+ attr_accessor :mocked_iam
100
91
 
101
92
  ##
102
93
  # Gets the configuration of a topic.
@@ -105,30 +96,17 @@ module Google
105
96
  # If other attributes are added in the future,
106
97
  # they will be returned here.
107
98
  def get_topic topic_name, options = {}
108
- execute do
109
- publisher.get_topic topic_path(topic_name, options),
110
- options: default_options
111
- end
99
+ publisher.get_topic topic: topic_path(topic_name, options)
112
100
  end
113
101
 
114
102
  ##
115
103
  # Lists matching topics.
116
104
  def list_topics options = {}
117
- call_options = default_options
118
- if (token = options[:token])
119
- call_options = Google::Gax::CallOptions.new(
120
- kwargs: default_headers,
121
- page_token: token
122
- )
123
- end
105
+ paged_enum = publisher.list_topics project: project_path(options),
106
+ page_size: options[:max],
107
+ page_token: options[:token]
124
108
 
125
- execute do
126
- paged_enum = publisher.list_topics project_path(options),
127
- page_size: options[:max],
128
- options: call_options
129
-
130
- paged_enum.page.response
131
- end
109
+ paged_enum.response
132
110
  end
133
111
 
134
112
  ##
@@ -140,21 +118,16 @@ module Google
140
118
  }
141
119
  end
142
120
 
143
- execute do
144
- publisher.create_topic \
145
- topic_path(topic_name, options),
146
- labels: labels,
147
- kms_key_name: kms_key_name,
148
- message_storage_policy: message_storage_policy,
149
- options: default_options
150
- end
121
+ publisher.create_topic \
122
+ name: topic_path(topic_name, options),
123
+ labels: labels,
124
+ kms_key_name: kms_key_name,
125
+ message_storage_policy: message_storage_policy
151
126
  end
152
127
 
153
128
  def update_topic topic_obj, *fields
154
129
  mask = Google::Protobuf::FieldMask.new paths: fields.map(&:to_s)
155
- execute do
156
- publisher.update_topic topic_obj, mask, options: default_options
157
- end
130
+ publisher.update_topic topic: topic_obj, update_mask: mask
158
131
  end
159
132
 
160
133
  ##
@@ -163,10 +136,7 @@ module Google
163
136
  # exist. After a topic is deleted, a new topic may be created with the
164
137
  # same name.
165
138
  def delete_topic topic_name
166
- execute do
167
- publisher.delete_topic topic_path(topic_name),
168
- options: default_options
169
- end
139
+ publisher.delete_topic topic: topic_path(topic_name)
170
140
  end
171
141
 
172
142
  ##
@@ -175,140 +145,93 @@ module Google
175
145
  # The messages parameter is an array of arrays.
176
146
  # The first element is the data, second is attributes hash.
177
147
  def publish topic, messages
178
- execute do
179
- publisher.publish topic_path(topic), messages,
180
- options: default_options
181
- end
148
+ publisher.publish topic: topic_path(topic), messages: messages
182
149
  end
183
150
 
184
151
  ##
185
152
  # Gets the details of a subscription.
186
153
  def get_subscription subscription_name, options = {}
187
- subscription = subscription_path subscription_name, options
188
- execute do
189
- subscriber.get_subscription subscription, options: default_options
190
- end
154
+ subscriber.get_subscription subscription: subscription_path(subscription_name, options)
191
155
  end
192
156
 
193
157
  ##
194
158
  # Lists matching subscriptions by project and topic.
195
159
  def list_topics_subscriptions topic, options = {}
196
- call_options = default_options
197
- if (token = options[:token])
198
- call_options = Google::Gax::CallOptions.new(
199
- kwargs: default_headers,
200
- page_token: token
201
- )
202
- end
203
-
204
- execute do
205
- paged_enum = publisher.list_topic_subscriptions \
206
- topic_path(topic, options),
207
- page_size: options[:max],
208
- options: call_options
209
-
210
- paged_enum.page.response
211
- end
160
+ publisher.list_topic_subscriptions topic: topic_path(topic, options),
161
+ page_size: options[:max],
162
+ page_token: options[:token]
212
163
  end
213
164
 
214
165
  ##
215
166
  # Lists matching subscriptions by project.
216
167
  def list_subscriptions options = {}
217
- call_options = default_options
218
- if (token = options[:token])
219
- call_options = Google::Gax::CallOptions.new(
220
- kwargs: default_headers,
221
- page_token: token
222
- )
223
- end
168
+ paged_enum = subscriber.list_subscriptions project: project_path(options),
169
+ page_size: options[:max],
170
+ page_token: options[:token]
224
171
 
225
- execute do
226
- paged_enum = subscriber.list_subscriptions project_path(options),
227
- page_size: options[:max],
228
- options: call_options
229
-
230
- paged_enum.page.response
231
- end
172
+ paged_enum.response
232
173
  end
233
174
 
234
175
  ##
235
176
  # Creates a subscription on a given topic for a given subscriber.
236
177
  def create_subscription topic, subscription_name, options = {}
237
- name = subscription_path subscription_name, options
238
- topic = topic_path topic
239
- push_config = if options[:endpoint]
240
- Google::Cloud::PubSub::V1::PushConfig.new \
241
- push_endpoint: options[:endpoint],
242
- attributes: (options[:attributes] || {}).to_h
243
- end
244
- mrd = Convert.number_to_duration options[:retention]
245
- execute do
246
- subscriber.create_subscription \
247
- name, topic,
248
- push_config: push_config,
249
- ack_deadline_seconds: options[:deadline],
250
- retain_acked_messages: options[:retain_acked],
251
- message_retention_duration: mrd,
252
- labels: options[:labels],
253
- enable_message_ordering: options[:message_ordering],
254
- filter: options[:filter],
255
- dead_letter_policy: dead_letter_policy(options),
256
- retry_policy: options[:retry_policy],
257
- options: default_options
258
- end
178
+ subscriber.create_subscription \
179
+ name: subscription_path(subscription_name, options),
180
+ topic: topic_path(topic),
181
+ push_config: options[:push_config],
182
+ ack_deadline_seconds: options[:deadline],
183
+ retain_acked_messages: options[:retain_acked],
184
+ message_retention_duration: Convert.number_to_duration(options[:retention]),
185
+ labels: options[:labels],
186
+ enable_message_ordering: options[:message_ordering],
187
+ filter: options[:filter],
188
+ dead_letter_policy: dead_letter_policy(options),
189
+ retry_policy: options[:retry_policy]
259
190
  end
260
191
 
261
192
  def update_subscription subscription_obj, *fields
262
193
  mask = Google::Protobuf::FieldMask.new paths: fields.map(&:to_s)
263
- execute do
264
- subscriber.update_subscription subscription_obj, mask, options: default_options
265
- end
194
+ subscriber.update_subscription subscription: subscription_obj, update_mask: mask
266
195
  end
267
196
 
268
197
  ##
269
- # Deletes an existing subscription.
270
- # All pending messages in the subscription are immediately dropped.
198
+ # Deletes an existing subscription. All pending messages in the subscription are immediately dropped.
271
199
  def delete_subscription subscription
272
- execute do
273
- subscriber.delete_subscription subscription_path(subscription),
274
- options: default_options
275
- end
200
+ subscriber.delete_subscription subscription: subscription_path(subscription)
201
+ end
202
+
203
+ ##
204
+ # Detaches a subscription from its topic. All messages retained in the subscription are dropped. Subsequent
205
+ # `Pull` and `StreamingPull` requests will raise `FAILED_PRECONDITION`. If the subscription is a push
206
+ # subscription, pushes to the endpoint will stop.
207
+ def detach_subscription subscription
208
+ publisher.detach_subscription subscription: subscription_path(subscription)
276
209
  end
277
210
 
278
211
  ##
279
212
  # Pulls a single message from the server.
280
213
  def pull subscription, options = {}
281
- subscription = subscription_path subscription, options
282
214
  max_messages = options.fetch(:max, 100).to_i
283
215
  return_immediately = !(!options.fetch(:immediate, true))
284
216
 
285
- execute do
286
- subscriber.pull subscription,
287
- max_messages,
288
- return_immediately: return_immediately,
289
- options: default_options
290
- end
217
+ subscriber.pull subscription: subscription_path(subscription, options),
218
+ max_messages: max_messages,
219
+ return_immediately: return_immediately
291
220
  end
292
221
 
293
222
  def streaming_pull request_enum
294
- execute do
295
- subscriber.streaming_pull request_enum, options: default_options
296
- end
223
+ subscriber.streaming_pull request_enum
297
224
  end
298
225
 
299
226
  ##
300
227
  # Acknowledges receipt of a message.
301
228
  def acknowledge subscription, *ack_ids
302
- execute do
303
- subscriber.acknowledge subscription_path(subscription), ack_ids,
304
- options: default_options
305
- end
229
+ subscriber.acknowledge subscription: subscription_path(subscription), ack_ids: ack_ids
306
230
  end
307
231
 
308
232
  ##
309
233
  # Modifies the PushConfig for a specified subscription.
310
234
  def modify_push_config subscription, endpoint, attributes
311
- subscription = subscription_path subscription
312
235
  # Convert attributes to strings to match the protobuf definition
313
236
  attributes = Hash[attributes.map { |k, v| [String(k), String(v)] }]
314
237
  push_config = Google::Cloud::PubSub::V1::PushConfig.new(
@@ -316,138 +239,83 @@ module Google
316
239
  attributes: attributes
317
240
  )
318
241
 
319
- execute do
320
- subscriber.modify_push_config subscription, push_config,
321
- options: default_options
322
- end
242
+ subscriber.modify_push_config subscription: subscription_path(subscription),
243
+ push_config: push_config
323
244
  end
324
245
 
325
246
  ##
326
247
  # Modifies the ack deadline for a specific message.
327
248
  def modify_ack_deadline subscription, ids, deadline
328
- execute do
329
- subscriber.modify_ack_deadline subscription_path(subscription),
330
- Array(ids),
331
- deadline, options: default_options
332
- end
249
+ subscriber.modify_ack_deadline subscription: subscription_path(subscription),
250
+ ack_ids: Array(ids),
251
+ ack_deadline_seconds: deadline
333
252
  end
334
253
 
335
254
  ##
336
255
  # Lists snapshots by project.
337
256
  def list_snapshots options = {}
338
- call_options = default_options
339
- if (token = options[:token])
340
- call_options = Google::Gax::CallOptions.new(
341
- kwargs: default_headers,
342
- page_token: token
343
- )
344
- end
345
-
346
- execute do
347
- paged_enum = subscriber.list_snapshots project_path(options),
348
- page_size: options[:max],
349
- options: call_options
257
+ paged_enum = subscriber.list_snapshots project: project_path(options),
258
+ page_size: options[:max],
259
+ page_token: options[:token]
350
260
 
351
- paged_enum.page.response
352
- end
261
+ paged_enum.response
353
262
  end
354
263
 
355
264
  ##
356
265
  # Creates a snapshot on a given subscription.
357
266
  def create_snapshot subscription, snapshot_name, labels: nil
358
- name = snapshot_path snapshot_name
359
- execute do
360
- subscriber.create_snapshot name,
361
- subscription_path(subscription),
362
- labels: labels,
363
- options: default_options
364
- end
267
+ subscriber.create_snapshot name: snapshot_path(snapshot_name),
268
+ subscription: subscription_path(subscription),
269
+ labels: labels
365
270
  end
366
271
 
367
272
  def update_snapshot snapshot_obj, *fields
368
273
  mask = Google::Protobuf::FieldMask.new paths: fields.map(&:to_s)
369
- execute do
370
- subscriber.update_snapshot snapshot_obj, mask, options: default_options
371
- end
274
+ subscriber.update_snapshot snapshot: snapshot_obj, update_mask: mask
372
275
  end
373
276
 
374
277
  ##
375
278
  # Deletes an existing snapshot.
376
279
  # All pending messages in the snapshot are immediately dropped.
377
280
  def delete_snapshot snapshot
378
- execute do
379
- subscriber.delete_snapshot snapshot_path(snapshot),
380
- options: default_options
381
- end
281
+ subscriber.delete_snapshot snapshot: snapshot_path(snapshot)
382
282
  end
383
283
 
384
284
  ##
385
285
  # Adjusts the given subscription to a time or snapshot.
386
286
  def seek subscription, time_or_snapshot
387
- subscription = subscription_path subscription
388
- execute do
389
- if a_time? time_or_snapshot
390
- time = Convert.time_to_timestamp time_or_snapshot
391
- subscriber.seek subscription, time: time, options: default_options
392
- else
393
- time_or_snapshot = time_or_snapshot.name if time_or_snapshot.is_a? Snapshot
394
- subscriber.seek subscription,
395
- snapshot: snapshot_path(time_or_snapshot),
396
- options: default_options
397
- end
287
+ if a_time? time_or_snapshot
288
+ time = Convert.time_to_timestamp time_or_snapshot
289
+ subscriber.seek subscription: subscription, time: time
290
+ else
291
+ time_or_snapshot = time_or_snapshot.name if time_or_snapshot.is_a? Snapshot
292
+ subscriber.seek subscription: subscription_path(subscription),
293
+ snapshot: snapshot_path(time_or_snapshot)
398
294
  end
399
295
  end
400
296
 
401
297
  def get_topic_policy topic_name, options = {}
402
- execute do
403
- publisher.get_iam_policy topic_path(topic_name, options),
404
- options: default_options
405
- end
298
+ iam.get_iam_policy resource: topic_path(topic_name, options)
406
299
  end
407
300
 
408
301
  def set_topic_policy topic_name, new_policy, options = {}
409
- resource = topic_path topic_name, options
410
-
411
- execute do
412
- publisher.set_iam_policy resource, new_policy,
413
- options: default_options
414
- end
302
+ iam.set_iam_policy resource: topic_path(topic_name, options), policy: new_policy
415
303
  end
416
304
 
417
305
  def test_topic_permissions topic_name, permissions, options = {}
418
- resource = topic_path topic_name, options
419
-
420
- execute do
421
- publisher.test_iam_permissions resource, permissions,
422
- options: default_options
423
- end
306
+ iam.test_iam_permissions resource: topic_path(topic_name, options), permissions: permissions
424
307
  end
425
308
 
426
309
  def get_subscription_policy subscription_name, options = {}
427
- resource = subscription_path subscription_name, options
428
-
429
- execute do
430
- subscriber.get_iam_policy resource, options: default_options
431
- end
310
+ iam.get_iam_policy resource: subscription_path(subscription_name, options)
432
311
  end
433
312
 
434
313
  def set_subscription_policy subscription_name, new_policy, options = {}
435
- resource = subscription_path subscription_name, options
436
-
437
- execute do
438
- subscriber.set_iam_policy resource, new_policy,
439
- options: default_options
440
- end
314
+ iam.set_iam_policy resource: subscription_path(subscription_name, options), policy: new_policy
441
315
  end
442
316
 
443
- def test_subscription_permissions subscription_name,
444
- permissions, options = {}
445
- resource = subscription_path subscription_name, options
446
-
447
- execute do
448
- subscriber.test_iam_permissions resource, permissions,
449
- options: default_options
450
- end
317
+ def test_subscription_permissions subscription_name, permissions, options = {}
318
+ iam.test_iam_permissions resource: subscription_path(subscription_name, options), permissions: permissions
451
319
  end
452
320
 
453
321
  def project_path options = {}
@@ -491,21 +359,6 @@ module Google
491
359
  end
492
360
  policy
493
361
  end
494
-
495
- def default_headers
496
- { "google-cloud-resource-prefix" => "projects/#{@project}" }
497
- end
498
-
499
- def default_options
500
- Google::Gax::CallOptions.new kwargs: default_headers
501
- end
502
-
503
- def execute
504
- yield
505
- rescue Google::Gax::GaxError => e
506
- # GaxError wraps BadStatus, but exposes it as #cause
507
- raise Google::Cloud::Error.from_error(e.cause)
508
- end
509
362
  end
510
363
  end
511
364