google-cloud-pubsub 2.15.3 → 3.0.2

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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/AUTHENTICATION.md +8 -26
  3. data/CHANGELOG.md +108 -0
  4. data/OVERVIEW.md +188 -144
  5. data/lib/google/cloud/pubsub/admin_clients.rb +116 -0
  6. data/lib/google/cloud/pubsub/async_publisher.rb +9 -9
  7. data/lib/google/cloud/pubsub/batch_publisher.rb +4 -4
  8. data/lib/google/cloud/pubsub/convert.rb +1 -1
  9. data/lib/google/cloud/pubsub/errors.rb +3 -3
  10. data/lib/google/cloud/pubsub/flow_controller.rb +0 -2
  11. data/lib/google/cloud/pubsub/message.rb +10 -11
  12. data/lib/google/cloud/pubsub/{subscriber → message_listener}/enumerator_queue.rb +1 -1
  13. data/lib/google/cloud/pubsub/{subscriber → message_listener}/inventory.rb +2 -4
  14. data/lib/google/cloud/pubsub/{subscriber → message_listener}/sequencer.rb +1 -1
  15. data/lib/google/cloud/pubsub/{subscriber → message_listener}/stream.rb +15 -14
  16. data/lib/google/cloud/pubsub/{subscriber → message_listener}/timed_unary_buffer.rb +1 -1
  17. data/lib/google/cloud/pubsub/message_listener.rb +413 -0
  18. data/lib/google/cloud/pubsub/project.rb +103 -523
  19. data/lib/google/cloud/pubsub/publisher.rb +373 -0
  20. data/lib/google/cloud/pubsub/received_message.rb +50 -45
  21. data/lib/google/cloud/pubsub/service.rb +40 -352
  22. data/lib/google/cloud/pubsub/subscriber.rb +442 -279
  23. data/lib/google/cloud/pubsub/version.rb +1 -1
  24. data/lib/google/cloud/pubsub.rb +24 -28
  25. data/lib/google-cloud-pubsub.rb +8 -6
  26. metadata +18 -183
  27. data/lib/google/cloud/pubsub/policy.rb +0 -188
  28. data/lib/google/cloud/pubsub/retry_policy.rb +0 -88
  29. data/lib/google/cloud/pubsub/schema/list.rb +0 -180
  30. data/lib/google/cloud/pubsub/schema.rb +0 -310
  31. data/lib/google/cloud/pubsub/snapshot/list.rb +0 -178
  32. data/lib/google/cloud/pubsub/snapshot.rb +0 -205
  33. data/lib/google/cloud/pubsub/subscription/list.rb +0 -205
  34. data/lib/google/cloud/pubsub/subscription/push_config.rb +0 -268
  35. data/lib/google/cloud/pubsub/subscription.rb +0 -1467
  36. data/lib/google/cloud/pubsub/topic/list.rb +0 -171
  37. data/lib/google/cloud/pubsub/topic.rb +0 -1100
@@ -18,6 +18,7 @@ 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/cloud/pubsub/admin_clients"
21
22
  require "securerandom"
22
23
 
23
24
  module Google
@@ -37,51 +38,58 @@ module Google
37
38
  # value to be replaced for unit testing.
38
39
  attr_accessor :client_id
39
40
 
41
+ attr_reader :universe_domain
42
+
40
43
  ##
41
44
  # Creates a new Service instance.
42
- def initialize project, credentials, host: nil, timeout: nil
45
+ def initialize project, credentials, host: nil, timeout: nil, universe_domain: nil
43
46
  @project = project
44
47
  @credentials = credentials
45
48
  @host = host
46
49
  @timeout = timeout
47
50
  @client_id = SecureRandom.uuid.freeze
51
+ @universe_domain = universe_domain || ENV["GOOGLE_CLOUD_UNIVERSE_DOMAIN"] || "googleapis.com"
48
52
  end
49
53
 
50
- def subscriber
51
- return mocked_subscriber if mocked_subscriber
52
- @subscriber ||= V1::Subscriber::Client.new do |config|
54
+ def subscription_admin
55
+ return mocked_subscription_admin if mocked_subscription_admin
56
+ @subscription_admin ||= SubscriptionAdmin::Client.new do |config|
53
57
  config.credentials = credentials if credentials
54
58
  override_client_config_timeouts config if timeout
55
59
  config.endpoint = host if host
60
+ config.universe_domain = universe_domain
56
61
  config.lib_name = "gccl"
57
62
  config.lib_version = Google::Cloud::PubSub::VERSION
58
63
  config.metadata = { "google-cloud-resource-prefix": "projects/#{@project}" }
59
64
  end
60
65
  end
61
- attr_accessor :mocked_subscriber
66
+ attr_accessor :mocked_subscription_admin
62
67
 
63
- def publisher
64
- return mocked_publisher if mocked_publisher
65
- @publisher ||= V1::Publisher::Client.new do |config|
68
+ def topic_admin
69
+ return mocked_topic_admin if mocked_topic_admin
70
+ @topic_admin ||= TopicAdmin::Client.new do |config|
66
71
  config.credentials = credentials if credentials
67
72
  override_client_config_timeouts config if timeout
68
73
  config.endpoint = host if host
74
+ config.universe_domain = universe_domain
69
75
  config.lib_name = "gccl"
70
76
  config.lib_version = Google::Cloud::PubSub::VERSION
71
77
  config.metadata = { "google-cloud-resource-prefix": "projects/#{@project}" }
72
78
  end
73
79
  end
74
- attr_accessor :mocked_publisher
80
+ attr_accessor :mocked_topic_admin
75
81
 
76
82
  def iam
77
83
  return mocked_iam if mocked_iam
78
- @iam ||= V1::IAMPolicy::Client.new do |config|
79
- config.credentials = credentials if credentials
80
- override_client_config_timeouts config if timeout
81
- config.endpoint = host if host
82
- config.lib_name = "gccl"
83
- config.lib_version = Google::Cloud::PubSub::VERSION
84
- config.metadata = { "google-cloud-resource-prefix": "projects/#{@project}" }
84
+ @iam ||= begin
85
+ iam = (@topic_admin || @subscription_admin || @schemas || topic_admin).iam_policy_client
86
+ iam.configure do |config|
87
+ override_client_config_timeouts config if timeout
88
+ config.lib_name = "gccl"
89
+ config.lib_version = Google::Cloud::PubSub::VERSION
90
+ config.metadata = { "google-cloud-resource-prefix": "projects/#{@project}" }
91
+ end
92
+ iam
85
93
  end
86
94
  end
87
95
  attr_accessor :mocked_iam
@@ -92,6 +100,7 @@ module Google
92
100
  config.credentials = credentials if credentials
93
101
  override_client_config_timeouts config if timeout
94
102
  config.endpoint = host if host
103
+ config.universe_domain = universe_domain
95
104
  config.lib_name = "gccl"
96
105
  config.lib_version = Google::Cloud::PubSub::VERSION
97
106
  config.metadata = { "google-cloud-resource-prefix": "projects/#{@project}" }
@@ -99,75 +108,6 @@ module Google
99
108
  end
100
109
  attr_accessor :mocked_schemas
101
110
 
102
- ##
103
- # Gets the configuration of a topic.
104
- # Since the topic only has the name attribute,
105
- # this method is only useful to check the existence of a topic.
106
- # If other attributes are added in the future,
107
- # they will be returned here.
108
- def get_topic topic_name, options = {}
109
- publisher.get_topic topic: topic_path(topic_name, options)
110
- end
111
-
112
- ##
113
- # Lists matching topics.
114
- def list_topics options = {}
115
- paged_enum = publisher.list_topics project: project_path(options),
116
- page_size: options[:max],
117
- page_token: options[:token]
118
-
119
- paged_enum.response
120
- end
121
-
122
- ##
123
- # Creates the given topic with the given name.
124
- def create_topic topic_name,
125
- labels: nil,
126
- kms_key_name: nil,
127
- persistence_regions: nil,
128
- schema_name: nil,
129
- message_encoding: nil,
130
- retention: nil,
131
- options: {}
132
- if persistence_regions
133
- message_storage_policy = Google::Cloud::PubSub::V1::MessageStoragePolicy.new(
134
- allowed_persistence_regions: Array(persistence_regions)
135
- )
136
- end
137
-
138
- if schema_name || message_encoding
139
- unless schema_name && message_encoding
140
- raise ArgumentError, "Schema settings must include both schema_name and message_encoding."
141
- end
142
- schema_settings = Google::Cloud::PubSub::V1::SchemaSettings.new(
143
- schema: schema_path(schema_name),
144
- encoding: message_encoding.to_s.upcase
145
- )
146
- end
147
-
148
- publisher.create_topic \
149
- name: topic_path(topic_name, options),
150
- labels: labels,
151
- kms_key_name: kms_key_name,
152
- message_storage_policy: message_storage_policy,
153
- schema_settings: schema_settings,
154
- message_retention_duration: Convert.number_to_duration(retention)
155
- end
156
-
157
- def update_topic topic_obj, *fields
158
- mask = Google::Protobuf::FieldMask.new paths: fields.map(&:to_s)
159
- publisher.update_topic topic: topic_obj, update_mask: mask
160
- end
161
-
162
- ##
163
- # Deletes the topic with the given name. All subscriptions to this topic
164
- # are also deleted. Raises GRPC status code 5 if the topic does not
165
- # exist. After a topic is deleted, a new topic may be created with the
166
- # same name.
167
- def delete_topic topic_name
168
- publisher.delete_topic topic: topic_path(topic_name)
169
- end
170
-
171
111
  ##
172
112
  # Adds one or more messages to the topic.
173
113
  # Raises GRPC status code 5 if the topic does not exist.
@@ -176,57 +116,11 @@ module Google
176
116
  def publish topic, messages, compress: false
177
117
  request = { topic: topic_path(topic), messages: messages }
178
118
  compress_options = ::Gapic::CallOptions.new metadata: { "grpc-internal-encoding-request": "gzip" }
179
- compress ? (publisher.publish request, compress_options) : (publisher.publish request)
180
- end
181
-
182
- ##
183
- # Gets the details of a subscription.
184
- def get_subscription subscription_name, options = {}
185
- subscriber.get_subscription subscription: subscription_path(subscription_name, options)
186
- end
187
-
188
- ##
189
- # Lists matching subscriptions by project and topic.
190
- def list_topics_subscriptions topic, options = {}
191
- publisher.list_topic_subscriptions topic: topic_path(topic, options),
192
- page_size: options[:max],
193
- page_token: options[:token]
194
- end
195
-
196
- ##
197
- # Lists matching subscriptions by project.
198
- def list_subscriptions options = {}
199
- paged_enum = subscriber.list_subscriptions project: project_path(options),
200
- page_size: options[:max],
201
- page_token: options[:token]
202
-
203
- paged_enum.response
204
- end
205
-
206
- ##
207
- # Creates a subscription on a given topic for a given subscriber.
208
- def create_subscription topic, subscription_name, options = {}
209
- updated_option = construct_create_subscription_options topic, subscription_name, options
210
- subscriber.create_subscription(**updated_option)
211
- end
212
-
213
- def update_subscription subscription_obj, *fields
214
- mask = Google::Protobuf::FieldMask.new paths: fields.map(&:to_s)
215
- subscriber.update_subscription subscription: subscription_obj, update_mask: mask
216
- end
217
-
218
- ##
219
- # Deletes an existing subscription. All pending messages in the subscription are immediately dropped.
220
- def delete_subscription subscription
221
- subscriber.delete_subscription subscription: subscription_path(subscription)
222
- end
223
-
224
- ##
225
- # Detaches a subscription from its topic. All messages retained in the subscription are dropped. Subsequent
226
- # `Pull` and `StreamingPull` requests will raise `FAILED_PRECONDITION`. If the subscription is a push
227
- # subscription, pushes to the endpoint will stop.
228
- def detach_subscription subscription
229
- publisher.detach_subscription subscription: subscription_path(subscription)
119
+ if compress
120
+ (topic_admin.publish_internal request, compress_options)
121
+ else
122
+ (topic_admin.publish_internal request)
123
+ end
230
124
  end
231
125
 
232
126
  ##
@@ -235,193 +129,32 @@ module Google
235
129
  max_messages = options.fetch(:max, 100).to_i
236
130
  return_immediately = !(!options.fetch(:immediate, true))
237
131
 
238
- subscriber.pull subscription: subscription_path(subscription, options),
239
- max_messages: max_messages,
240
- return_immediately: return_immediately
132
+ subscription_admin.pull_internal subscription: subscription_path(subscription, options),
133
+ max_messages: max_messages,
134
+ return_immediately: return_immediately
241
135
  end
242
136
 
243
- def streaming_pull request_enum
244
- subscriber.streaming_pull request_enum
137
+ def streaming_pull request_enum, options = {}
138
+ subscription_admin.streaming_pull_internal request_enum, options
245
139
  end
246
140
 
247
141
  ##
248
142
  # Acknowledges receipt of a message.
249
143
  def acknowledge subscription, *ack_ids
250
- subscriber.acknowledge subscription: subscription_path(subscription), ack_ids: ack_ids
251
- end
252
-
253
- ##
254
- # Modifies the PushConfig for a specified subscription.
255
- def modify_push_config subscription, endpoint, attributes
256
- # Convert attributes to strings to match the protobuf definition
257
- attributes = Hash[attributes.map { |k, v| [String(k), String(v)] }]
258
- push_config = Google::Cloud::PubSub::V1::PushConfig.new(
259
- push_endpoint: endpoint,
260
- attributes: attributes
261
- )
262
-
263
- subscriber.modify_push_config subscription: subscription_path(subscription),
264
- push_config: push_config
144
+ subscription_admin.acknowledge_internal subscription: subscription_path(subscription),
145
+ ack_ids: ack_ids
265
146
  end
266
147
 
267
148
  ##
268
149
  # Modifies the ack deadline for a specific message.
269
150
  def modify_ack_deadline subscription, ids, deadline
270
- subscriber.modify_ack_deadline subscription: subscription_path(subscription),
271
- ack_ids: Array(ids),
272
- ack_deadline_seconds: deadline
273
- end
274
-
275
- ##
276
- # Lists snapshots by project.
277
- def list_snapshots options = {}
278
- paged_enum = subscriber.list_snapshots project: project_path(options),
279
- page_size: options[:max],
280
- page_token: options[:token]
281
-
282
- paged_enum.response
283
- end
284
-
285
- ##
286
- # Creates a snapshot on a given subscription.
287
- def create_snapshot subscription, snapshot_name, labels: nil
288
- subscriber.create_snapshot name: snapshot_path(snapshot_name),
289
- subscription: subscription_path(subscription),
290
- labels: labels
291
- end
292
-
293
- def update_snapshot snapshot_obj, *fields
294
- mask = Google::Protobuf::FieldMask.new paths: fields.map(&:to_s)
295
- subscriber.update_snapshot snapshot: snapshot_obj, update_mask: mask
296
- end
297
-
298
- ##
299
- # Deletes an existing snapshot.
300
- # All pending messages in the snapshot are immediately dropped.
301
- def delete_snapshot snapshot
302
- subscriber.delete_snapshot snapshot: snapshot_path(snapshot)
303
- end
304
-
305
- ##
306
- # Adjusts the given subscription to a time or snapshot.
307
- def seek subscription, time_or_snapshot
308
- if a_time? time_or_snapshot
309
- time = Convert.time_to_timestamp time_or_snapshot
310
- subscriber.seek subscription: subscription, time: time
311
- else
312
- time_or_snapshot = time_or_snapshot.name if time_or_snapshot.is_a? Snapshot
313
- subscriber.seek subscription: subscription_path(subscription),
314
- snapshot: snapshot_path(time_or_snapshot)
315
- end
316
- end
317
-
318
- ##
319
- # Lists schemas in the current (or given) project.
320
- # @param view [String, Symbol, nil] Possible values:
321
- # * `BASIC` - Include the name and type of the schema, but not the definition.
322
- # * `FULL` - Include all Schema object fields.
323
- #
324
- def list_schemas view, options = {}
325
- schema_view = Google::Cloud::PubSub::V1::SchemaView.const_get view.to_s.upcase
326
- paged_enum = schemas.list_schemas parent: project_path(options),
327
- view: schema_view,
328
- page_size: options[:max],
329
- page_token: options[:token]
330
-
331
- paged_enum.response
332
- end
333
-
334
- ##
335
- # Creates a schema in the current (or given) project.
336
- def create_schema schema_id, type, definition, options = {}
337
- schema = Google::Cloud::PubSub::V1::Schema.new(
338
- type: type,
339
- definition: definition
340
- )
341
- schemas.create_schema parent: project_path(options),
342
- schema: schema,
343
- schema_id: schema_id
344
- end
345
-
346
- ##
347
- # Gets the details of a schema.
348
- # @param view [String, Symbol, nil] The set of fields to return in the response. Possible values:
349
- # * `BASIC` - Include the name and type of the schema, but not the definition.
350
- # * `FULL` - Include all Schema object fields.
351
- #
352
- def get_schema schema_name, view, options = {}
353
- schema_view = Google::Cloud::PubSub::V1::SchemaView.const_get view.to_s.upcase
354
- schemas.get_schema name: schema_path(schema_name, options),
355
- view: schema_view
356
- end
357
-
358
- ##
359
- # Delete a schema.
360
- def delete_schema schema_name
361
- schemas.delete_schema name: schema_path(schema_name)
362
- end
363
-
364
- ##
365
- # Validate the definition string intended for a schema.
366
- def validate_schema type, definition, options = {}
367
- schema = Google::Cloud::PubSub::V1::Schema.new(
368
- type: type,
369
- definition: definition
370
- )
371
- schemas.validate_schema parent: project_path(options),
372
- schema: schema
373
- end
374
-
375
- ##
376
- # Validates a message against a schema.
377
- #
378
- # @param message_data [String] Message to validate against the provided `schema_spec`.
379
- # @param message_encoding [Google::Cloud::PubSub::V1::Encoding] The encoding expected for messages.
380
- # @param schema_name [String] Name of the schema against which to validate.
381
- # @param project [String] Name of the project if not the default project.
382
- # @param type [String] Ad-hoc schema type against which to validate.
383
- # @param definition [String] Ad-hoc schema definition against which to validate.
384
- #
385
- def validate_message message_data, message_encoding, schema_name: nil, project: nil, type: nil, definition: nil
386
- if type && definition
387
- schema = Google::Cloud::PubSub::V1::Schema.new(
388
- type: type,
389
- definition: definition
390
- )
391
- end
392
- schemas.validate_message parent: project_path(project: project),
393
- name: schema_path(schema_name),
394
- schema: schema,
395
- message: message_data,
396
- encoding: message_encoding
151
+ subscription_admin.modify_ack_deadline_internal subscription: subscription_path(subscription),
152
+ ack_ids: Array(ids),
153
+ ack_deadline_seconds: deadline
397
154
  end
398
155
 
399
156
  # Helper methods
400
157
 
401
- def get_topic_policy topic_name, options = {}
402
- iam.get_iam_policy resource: topic_path(topic_name, options)
403
- end
404
-
405
- def set_topic_policy topic_name, new_policy, options = {}
406
- iam.set_iam_policy resource: topic_path(topic_name, options), policy: new_policy
407
- end
408
-
409
- def test_topic_permissions topic_name, permissions, options = {}
410
- iam.test_iam_permissions resource: topic_path(topic_name, options), permissions: permissions
411
- end
412
-
413
- def get_subscription_policy subscription_name, options = {}
414
- iam.get_iam_policy resource: subscription_path(subscription_name, options)
415
- end
416
-
417
- def set_subscription_policy subscription_name, new_policy, options = {}
418
- iam.set_iam_policy resource: subscription_path(subscription_name, options), policy: new_policy
419
- end
420
-
421
- def test_subscription_permissions subscription_name, permissions, options = {}
422
- iam.test_iam_permissions resource: subscription_path(subscription_name, options), permissions: permissions
423
- end
424
-
425
158
  def project_path options = {}
426
159
  project_name = options[:project] || project
427
160
  "projects/#{project_name}"
@@ -447,10 +180,6 @@ module Google
447
180
  "#{project_path options}/schemas/#{schema_name}"
448
181
  end
449
182
 
450
- def inspect
451
- "#<#{self.class.name} (#{@project})>"
452
- end
453
-
454
183
  protected
455
184
 
456
185
  # Set the timeout in the client config.
@@ -464,49 +193,8 @@ module Google
464
193
  rpc.timeout = timeout if rpc.respond_to? :timeout=
465
194
  end
466
195
  end
467
-
468
- def a_time? obj
469
- return false unless obj.respond_to? :to_time
470
- # Rails' String#to_time returns nil if the string doesn't parse.
471
- return false if obj.to_time.nil?
472
- true
473
- end
474
-
475
- def dead_letter_policy options
476
- return nil unless options[:dead_letter_topic_name]
477
- policy = Google::Cloud::PubSub::V1::DeadLetterPolicy.new dead_letter_topic: options[:dead_letter_topic_name]
478
- if options[:dead_letter_max_delivery_attempts]
479
- policy.max_delivery_attempts = options[:dead_letter_max_delivery_attempts]
480
- end
481
- policy
482
- end
483
-
484
- private
485
-
486
- def construct_create_subscription_options topic, subscription_name, options
487
- excess_options = [:deadline,
488
- :retention,
489
- :retain_acked,
490
- :message_ordering,
491
- :endpoint,
492
- :dead_letter_topic_name,
493
- :dead_letter_max_delivery_attempts,
494
- :dead_letter_topic]
495
-
496
- new_options = options.filter { |k, v| !v.nil? && !excess_options.include?(k) }
497
- new_options[:name] = subscription_path subscription_name, options
498
- new_options[:topic] = topic_path topic
499
- new_options[:message_retention_duration] = Convert.number_to_duration options[:retention]
500
- new_options[:dead_letter_policy] = dead_letter_policy options
501
- new_options[:ack_deadline_seconds] = options[:deadline]
502
- new_options[:retain_acked_messages] = options[:retain_acked]
503
- new_options[:enable_message_ordering] = options[:message_ordering]
504
-
505
- new_options.compact
506
- end
507
196
  end
508
197
  end
509
-
510
198
  Pubsub = PubSub unless const_defined? :Pubsub
511
199
  end
512
200
  end