google-cloud-pubsub 0.20.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 (49) hide show
  1. checksums.yaml +5 -5
  2. data/.yardopts +18 -0
  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 +201 -0
  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 +82 -20
  19. data/lib/google/cloud/pubsub/policy.rb +40 -61
  20. data/lib/google/cloud/pubsub/project.rb +405 -265
  21. data/lib/google/cloud/pubsub/publish_result.rb +103 -0
  22. data/lib/google/cloud/pubsub/received_message.rb +165 -30
  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 +304 -162
  27. data/lib/google/cloud/pubsub/snapshot/list.rb +178 -0
  28. data/lib/google/cloud/pubsub/snapshot.rb +205 -0
  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 +38 -43
  36. data/lib/google/cloud/pubsub/subscription/push_config.rb +268 -0
  37. data/lib/google/cloud/pubsub/subscription.rb +1040 -210
  38. data/lib/google/cloud/pubsub/topic/list.rb +32 -37
  39. data/lib/google/cloud/pubsub/topic.rb +726 -177
  40. data/lib/google/cloud/pubsub/version.rb +6 -4
  41. data/lib/google/cloud/pubsub.rb +138 -413
  42. data/lib/google-cloud-pubsub.rb +60 -42
  43. metadata +88 -39
  44. data/lib/google/cloud/pubsub/topic/publisher.rb +0 -87
  45. data/lib/google/iam/v1/iam_policy.rb +0 -33
  46. data/lib/google/iam/v1/iam_policy_services.rb +0 -30
  47. data/lib/google/iam/v1/policy.rb +0 -25
  48. data/lib/google/pubsub/v1/pubsub_pb.rb +0 -129
  49. data/lib/google/pubsub/v1/pubsub_services_pb.rb +0 -117
@@ -1,10 +1,10 @@
1
- # Copyright 2016 Google Inc. All rights reserved.
1
+ # Copyright 2016 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,
@@ -14,62 +14,90 @@
14
14
 
15
15
 
16
16
  require "google/cloud/errors"
17
- require "google/cloud/core/grpc_backoff"
18
- require "google/pubsub/v1/pubsub_services_pb"
19
- require "google/iam/v1/iam_policy_services"
20
- require "google/cloud/core/grpc_utils"
21
- require "json"
17
+ require "google/cloud/pubsub/credentials"
18
+ require "google/cloud/pubsub/convert"
19
+ require "google/cloud/pubsub/version"
20
+ require "google/cloud/pubsub/v1"
21
+ require "securerandom"
22
22
 
23
23
  module Google
24
24
  module Cloud
25
- module Pubsub
25
+ module PubSub
26
26
  ##
27
- # @private Represents the gRPC Pub/Sub service, including all the API
28
- # methods.
27
+ # @private Represents the Pub/Sub service API, including IAM mixins.
29
28
  class Service
30
- attr_accessor :project, :credentials, :host, :retries, :timeout
29
+ attr_accessor :project
30
+ attr_accessor :credentials
31
+ attr_accessor :host
32
+ attr_accessor :timeout
33
+ ###
34
+ # The same client_id is used across all streaming pull connections that are created by this client. This is
35
+ # intentional, as it indicates to the server that any guarantees, such as message ordering, made for a stream
36
+ # that is disconnected will be made for the stream that is created to replace it. The attr_accessor allows the
37
+ # value to be replaced for unit testing.
38
+ attr_accessor :client_id
31
39
 
32
40
  ##
33
41
  # Creates a new Service instance.
34
- def initialize project, credentials, host: nil, retries: nil,
35
- timeout: nil
42
+ def initialize project, credentials, host: nil, timeout: nil
36
43
  @project = project
37
44
  @credentials = credentials
38
- @host = host || "pubsub.googleapis.com"
39
- @retries = retries
45
+ @host = host
40
46
  @timeout = timeout
41
- end
42
-
43
- def creds
44
- return credentials if insecure?
45
- GRPC::Core::ChannelCredentials.new.compose \
46
- GRPC::Core::CallCredentials.new credentials.client.updater_proc
47
+ @client_id = SecureRandom.uuid.freeze
47
48
  end
48
49
 
49
50
  def subscriber
50
51
  return mocked_subscriber if mocked_subscriber
51
- @subscriber ||= Google::Pubsub::V1::Subscriber::Stub.new(
52
- host, creds, timeout: timeout)
52
+ @subscriber ||= V1::Subscriber::Client.new do |config|
53
+ config.credentials = credentials if credentials
54
+ config.timeout = timeout if timeout
55
+ config.endpoint = host if host
56
+ config.lib_name = "gccl"
57
+ config.lib_version = Google::Cloud::PubSub::VERSION
58
+ config.metadata = { "google-cloud-resource-prefix": "projects/#{@project}" }
59
+ end
53
60
  end
54
61
  attr_accessor :mocked_subscriber
55
62
 
56
63
  def publisher
57
64
  return mocked_publisher if mocked_publisher
58
- @publisher ||= Google::Pubsub::V1::Publisher::Stub.new(
59
- host, creds, timeout: timeout)
65
+ @publisher ||= 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
60
73
  end
61
74
  attr_accessor :mocked_publisher
62
75
 
63
76
  def iam
64
77
  return mocked_iam if mocked_iam
65
- @iam ||= Google::Iam::V1::IAMPolicy::Stub.new(
66
- host, creds, timeout: timeout)
78
+ @iam ||= V1::IAMPolicy::Client.new do |config|
79
+ config.credentials = credentials if credentials
80
+ config.timeout = timeout 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}" }
85
+ end
67
86
  end
68
87
  attr_accessor :mocked_iam
69
88
 
70
- def insecure?
71
- credentials == :this_channel_is_insecure
89
+ def schemas
90
+ return mocked_schemas if mocked_schemas
91
+ @schemas ||= V1::SchemaService::Client.new do |config|
92
+ config.credentials = credentials if credentials
93
+ config.timeout = timeout if timeout
94
+ config.endpoint = host if host
95
+ config.lib_name = "gccl"
96
+ config.lib_version = Google::Cloud::PubSub::VERSION
97
+ config.metadata = { "google-cloud-resource-prefix" => "projects/#{@project}" }
98
+ end
72
99
  end
100
+ attr_accessor :mocked_schemas
73
101
 
74
102
  ##
75
103
  # Gets the configuration of a topic.
@@ -78,33 +106,55 @@ module Google
78
106
  # If other attributes are added in the future,
79
107
  # they will be returned here.
80
108
  def get_topic topic_name, options = {}
81
- topic_req = Google::Pubsub::V1::GetTopicRequest.new.tap do |r|
82
- r.topic = topic_path(topic_name, options)
83
- end
84
-
85
- execute { publisher.get_topic topic_req }
109
+ publisher.get_topic topic: topic_path(topic_name, options)
86
110
  end
87
111
 
88
112
  ##
89
113
  # Lists matching topics.
90
114
  def list_topics options = {}
91
- topics_req = Google::Pubsub::V1::ListTopicsRequest.new.tap do |r|
92
- r.project = project_path(options)
93
- r.page_token = options[:token] if options[:token]
94
- r.page_size = options[:max] if options[:max]
95
- end
115
+ paged_enum = publisher.list_topics project: project_path(options),
116
+ page_size: options[:max],
117
+ page_token: options[:token]
96
118
 
97
- execute { publisher.list_topics topics_req }
119
+ paged_enum.response
98
120
  end
99
121
 
100
122
  ##
101
123
  # Creates the given topic with the given name.
102
- def create_topic topic_name, options = {}
103
- topic_req = Google::Pubsub::V1::Topic.new.tap do |r|
104
- r.name = topic_path(topic_name, options)
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
+ options: {}
131
+ if persistence_regions
132
+ message_storage_policy = Google::Cloud::PubSub::V1::MessageStoragePolicy.new(
133
+ allowed_persistence_regions: Array(persistence_regions)
134
+ )
135
+ end
136
+
137
+ if schema_name || message_encoding
138
+ unless schema_name && message_encoding
139
+ raise ArgumentError, "Schema settings must include both schema_name and message_encoding."
140
+ end
141
+ schema_settings = Google::Cloud::PubSub::V1::SchemaSettings.new(
142
+ schema: schema_path(schema_name),
143
+ encoding: message_encoding.to_s.upcase
144
+ )
105
145
  end
106
146
 
107
- execute { publisher.create_topic topic_req }
147
+ publisher.create_topic \
148
+ name: topic_path(topic_name, options),
149
+ labels: labels,
150
+ kms_key_name: kms_key_name,
151
+ message_storage_policy: message_storage_policy,
152
+ schema_settings: schema_settings
153
+ end
154
+
155
+ def update_topic topic_obj, *fields
156
+ mask = Google::Protobuf::FieldMask.new paths: fields.map(&:to_s)
157
+ publisher.update_topic topic: topic_obj, update_mask: mask
108
158
  end
109
159
 
110
160
  ##
@@ -113,11 +163,7 @@ module Google
113
163
  # exist. After a topic is deleted, a new topic may be created with the
114
164
  # same name.
115
165
  def delete_topic topic_name
116
- topic_req = Google::Pubsub::V1::DeleteTopicRequest.new.tap do |r|
117
- r.topic = topic_path(topic_name)
118
- end
119
-
120
- execute { publisher.delete_topic topic_req }
166
+ publisher.delete_topic topic: topic_path(topic_name)
121
167
  end
122
168
 
123
169
  ##
@@ -126,102 +172,88 @@ module Google
126
172
  # The messages parameter is an array of arrays.
127
173
  # The first element is the data, second is attributes hash.
128
174
  def publish topic, messages
129
- publish_req = Google::Pubsub::V1::PublishRequest.new(
130
- topic: topic_path(topic),
131
- messages: messages.map do |data, attributes|
132
- Google::Pubsub::V1::PubsubMessage.new(
133
- data: data, attributes: attributes)
134
- end
135
- )
136
-
137
- execute { publisher.publish publish_req }
175
+ publisher.publish topic: topic_path(topic), messages: messages
138
176
  end
139
177
 
140
178
  ##
141
179
  # Gets the details of a subscription.
142
180
  def get_subscription subscription_name, options = {}
143
- sub_req = Google::Pubsub::V1::GetSubscriptionRequest.new(
144
- subscription: subscription_path(subscription_name, options)
145
- )
146
-
147
- execute { subscriber.get_subscription sub_req }
181
+ subscriber.get_subscription subscription: subscription_path(subscription_name, options)
148
182
  end
149
183
 
150
184
  ##
151
185
  # Lists matching subscriptions by project and topic.
152
186
  def list_topics_subscriptions topic, options = {}
153
- list_params = { topic: topic_path(topic, options),
154
- page_token: options[:token],
155
- page_size: options[:max]
156
- }.delete_if { |_, v| v.nil? }
157
- list_req = Google::Pubsub::V1::ListTopicSubscriptionsRequest.new \
158
- list_params
159
-
160
- execute { publisher.list_topic_subscriptions list_req }
187
+ publisher.list_topic_subscriptions topic: topic_path(topic, options),
188
+ page_size: options[:max],
189
+ page_token: options[:token]
161
190
  end
162
191
 
163
192
  ##
164
193
  # Lists matching subscriptions by project.
165
194
  def list_subscriptions options = {}
166
- list_params = { project: project_path(options),
167
- page_token: options[:token],
168
- page_size: options[:max]
169
- }.delete_if { |_, v| v.nil? }
170
- list_req = Google::Pubsub::V1::ListSubscriptionsRequest.new(
171
- list_params)
195
+ paged_enum = subscriber.list_subscriptions project: project_path(options),
196
+ page_size: options[:max],
197
+ page_token: options[:token]
172
198
 
173
- execute { subscriber.list_subscriptions list_req }
199
+ paged_enum.response
174
200
  end
175
201
 
176
202
  ##
177
203
  # Creates a subscription on a given topic for a given subscriber.
178
204
  def create_subscription topic, subscription_name, options = {}
179
- sub_params = { name: subscription_path(subscription_name, options),
180
- topic: topic_path(topic),
181
- ack_deadline_seconds: options[:deadline]
182
- }.delete_if { |_, v| v.nil? }
183
- sub_req = Google::Pubsub::V1::Subscription.new sub_params
184
- if options[:endpoint]
185
- sub_req.push_config = Google::Pubsub::V1::PushConfig.new(
186
- push_endpoint: options[:endpoint],
187
- attributes: (options[:attributes] || {}).to_h)
188
- end
205
+ subscriber.create_subscription \
206
+ name: subscription_path(subscription_name, options),
207
+ topic: topic_path(topic),
208
+ push_config: options[:push_config],
209
+ ack_deadline_seconds: options[:deadline],
210
+ retain_acked_messages: options[:retain_acked],
211
+ message_retention_duration: Convert.number_to_duration(options[:retention]),
212
+ labels: options[:labels],
213
+ enable_message_ordering: options[:message_ordering],
214
+ filter: options[:filter],
215
+ dead_letter_policy: dead_letter_policy(options),
216
+ retry_policy: options[:retry_policy]
217
+ end
189
218
 
190
- execute { subscriber.create_subscription sub_req }
219
+ def update_subscription subscription_obj, *fields
220
+ mask = Google::Protobuf::FieldMask.new paths: fields.map(&:to_s)
221
+ subscriber.update_subscription subscription: subscription_obj, update_mask: mask
191
222
  end
192
223
 
193
224
  ##
194
- # Deletes an existing subscription.
195
- # All pending messages in the subscription are immediately dropped.
225
+ # Deletes an existing subscription. All pending messages in the subscription are immediately dropped.
196
226
  def delete_subscription subscription
197
- del_req = Google::Pubsub::V1::DeleteSubscriptionRequest.new(
198
- subscription: subscription_path(subscription)
199
- )
227
+ subscriber.delete_subscription subscription: subscription_path(subscription)
228
+ end
200
229
 
201
- execute { subscriber.delete_subscription del_req }
230
+ ##
231
+ # Detaches a subscription from its topic. All messages retained in the subscription are dropped. Subsequent
232
+ # `Pull` and `StreamingPull` requests will raise `FAILED_PRECONDITION`. If the subscription is a push
233
+ # subscription, pushes to the endpoint will stop.
234
+ def detach_subscription subscription
235
+ publisher.detach_subscription subscription: subscription_path(subscription)
202
236
  end
203
237
 
204
238
  ##
205
239
  # Pulls a single message from the server.
206
240
  def pull subscription, options = {}
207
- pull_req = Google::Pubsub::V1::PullRequest.new(
208
- subscription: subscription_path(subscription, options),
209
- return_immediately: !(!options.fetch(:immediate, true)),
210
- max_messages: options.fetch(:max, 100).to_i
211
- )
241
+ max_messages = options.fetch(:max, 100).to_i
242
+ return_immediately = !(!options.fetch(:immediate, true))
212
243
 
213
- execute { subscriber.pull pull_req }
244
+ subscriber.pull subscription: subscription_path(subscription, options),
245
+ max_messages: max_messages,
246
+ return_immediately: return_immediately
247
+ end
248
+
249
+ def streaming_pull request_enum
250
+ subscriber.streaming_pull request_enum
214
251
  end
215
252
 
216
253
  ##
217
254
  # Acknowledges receipt of a message.
218
255
  def acknowledge subscription, *ack_ids
219
- ack_req = Google::Pubsub::V1::AcknowledgeRequest.new(
220
- subscription: subscription_path(subscription),
221
- ack_ids: ack_ids
222
- )
223
-
224
- execute { subscriber.acknowledge ack_req }
256
+ subscriber.acknowledge subscription: subscription_path(subscription), ack_ids: ack_ids
225
257
  end
226
258
 
227
259
  ##
@@ -229,81 +261,171 @@ module Google
229
261
  def modify_push_config subscription, endpoint, attributes
230
262
  # Convert attributes to strings to match the protobuf definition
231
263
  attributes = Hash[attributes.map { |k, v| [String(k), String(v)] }]
232
-
233
- mpc_req = Google::Pubsub::V1::ModifyPushConfigRequest.new(
234
- subscription: subscription_path(subscription),
235
- push_config: Google::Pubsub::V1::PushConfig.new(
236
- push_endpoint: endpoint,
237
- attributes: attributes
238
- )
264
+ push_config = Google::Cloud::PubSub::V1::PushConfig.new(
265
+ push_endpoint: endpoint,
266
+ attributes: attributes
239
267
  )
240
268
 
241
- execute { subscriber.modify_push_config mpc_req }
269
+ subscriber.modify_push_config subscription: subscription_path(subscription),
270
+ push_config: push_config
242
271
  end
243
272
 
244
273
  ##
245
274
  # Modifies the ack deadline for a specific message.
246
275
  def modify_ack_deadline subscription, ids, deadline
247
- mad_req = Google::Pubsub::V1::ModifyAckDeadlineRequest.new(
248
- subscription: subscription_path(subscription),
249
- ack_ids: Array(ids),
250
- ack_deadline_seconds: deadline
251
- )
276
+ subscriber.modify_ack_deadline subscription: subscription_path(subscription),
277
+ ack_ids: Array(ids),
278
+ ack_deadline_seconds: deadline
279
+ end
252
280
 
253
- execute { subscriber.modify_ack_deadline mad_req }
281
+ ##
282
+ # Lists snapshots by project.
283
+ def list_snapshots options = {}
284
+ paged_enum = subscriber.list_snapshots project: project_path(options),
285
+ page_size: options[:max],
286
+ page_token: options[:token]
287
+
288
+ paged_enum.response
254
289
  end
255
290
 
256
- def get_topic_policy topic_name, options = {}
257
- get_req = Google::Iam::V1::GetIamPolicyRequest.new(
258
- resource: topic_path(topic_name, options)
259
- )
291
+ ##
292
+ # Creates a snapshot on a given subscription.
293
+ def create_snapshot subscription, snapshot_name, labels: nil
294
+ subscriber.create_snapshot name: snapshot_path(snapshot_name),
295
+ subscription: subscription_path(subscription),
296
+ labels: labels
297
+ end
260
298
 
261
- execute { iam.get_iam_policy get_req }
299
+ def update_snapshot snapshot_obj, *fields
300
+ mask = Google::Protobuf::FieldMask.new paths: fields.map(&:to_s)
301
+ subscriber.update_snapshot snapshot: snapshot_obj, update_mask: mask
262
302
  end
263
303
 
264
- def set_topic_policy topic_name, new_policy, options = {}
265
- set_req = Google::Iam::V1::SetIamPolicyRequest.new(
266
- resource: topic_path(topic_name, options),
267
- policy: new_policy
268
- )
304
+ ##
305
+ # Deletes an existing snapshot.
306
+ # All pending messages in the snapshot are immediately dropped.
307
+ def delete_snapshot snapshot
308
+ subscriber.delete_snapshot snapshot: snapshot_path(snapshot)
309
+ end
269
310
 
270
- execute { iam.set_iam_policy set_req }
311
+ ##
312
+ # Adjusts the given subscription to a time or snapshot.
313
+ def seek subscription, time_or_snapshot
314
+ if a_time? time_or_snapshot
315
+ time = Convert.time_to_timestamp time_or_snapshot
316
+ subscriber.seek subscription: subscription, time: time
317
+ else
318
+ time_or_snapshot = time_or_snapshot.name if time_or_snapshot.is_a? Snapshot
319
+ subscriber.seek subscription: subscription_path(subscription),
320
+ snapshot: snapshot_path(time_or_snapshot)
321
+ end
271
322
  end
272
323
 
273
- def test_topic_permissions topic_name, permissions, options = {}
274
- test_req = Google::Iam::V1::TestIamPermissionsRequest.new(
275
- resource: topic_path(topic_name, options),
276
- permissions: permissions
324
+ ##
325
+ # Lists schemas in the current (or given) project.
326
+ # @param view [String, Symbol, nil] Possible values:
327
+ # * `BASIC` - Include the name and type of the schema, but not the definition.
328
+ # * `FULL` - Include all Schema object fields.
329
+ #
330
+ def list_schemas view, options = {}
331
+ schema_view = Google::Cloud::PubSub::V1::SchemaView.const_get view.to_s.upcase
332
+ paged_enum = schemas.list_schemas parent: project_path(options),
333
+ view: schema_view,
334
+ page_size: options[:max],
335
+ page_token: options[:token]
336
+
337
+ paged_enum.response
338
+ end
339
+
340
+ ##
341
+ # Creates a schema in the current (or given) project.
342
+ def create_schema schema_id, type, definition, options = {}
343
+ schema = Google::Cloud::PubSub::V1::Schema.new(
344
+ type: type,
345
+ definition: definition
277
346
  )
347
+ schemas.create_schema parent: project_path(options),
348
+ schema: schema,
349
+ schema_id: schema_id
350
+ end
278
351
 
279
- execute { iam.test_iam_permissions test_req }
352
+ ##
353
+ # Gets the details of a schema.
354
+ # @param view [String, Symbol, nil] The set of fields to return in the response. Possible values:
355
+ # * `BASIC` - Include the name and type of the schema, but not the definition.
356
+ # * `FULL` - Include all Schema object fields.
357
+ #
358
+ def get_schema schema_name, view, options = {}
359
+ schema_view = Google::Cloud::PubSub::V1::SchemaView.const_get view.to_s.upcase
360
+ schemas.get_schema name: schema_path(schema_name, options),
361
+ view: schema_view
280
362
  end
281
363
 
282
- def get_subscription_policy subscription_name, options = {}
283
- get_req = Google::Iam::V1::GetIamPolicyRequest.new(
284
- resource: subscription_path(subscription_name, options)
364
+ ##
365
+ # Delete a schema.
366
+ def delete_schema schema_name
367
+ schemas.delete_schema name: schema_path(schema_name)
368
+ end
369
+
370
+ ##
371
+ # Validate the definition string intended for a schema.
372
+ def validate_schema type, definition, options = {}
373
+ schema = Google::Cloud::PubSub::V1::Schema.new(
374
+ type: type,
375
+ definition: definition
285
376
  )
377
+ schemas.validate_schema parent: project_path(options),
378
+ schema: schema
379
+ end
380
+
381
+ ##
382
+ # Validates a message against a schema.
383
+ #
384
+ # @param message_data [String] Message to validate against the provided `schema_spec`.
385
+ # @param message_encoding [Google::Cloud::PubSub::V1::Encoding] The encoding expected for messages.
386
+ # @param schema_name [String] Name of the schema against which to validate.
387
+ # @param project [String] Name of the project if not the default project.
388
+ # @param type [String] Ad-hoc schema type against which to validate.
389
+ # @param definition [String] Ad-hoc schema definition against which to validate.
390
+ #
391
+ def validate_message message_data, message_encoding, schema_name: nil, project: nil, type: nil, definition: nil
392
+ if type && definition
393
+ schema = Google::Cloud::PubSub::V1::Schema.new(
394
+ type: type,
395
+ definition: definition
396
+ )
397
+ end
398
+ schemas.validate_message parent: project_path(project: project),
399
+ name: schema_path(schema_name),
400
+ schema: schema,
401
+ message: message_data,
402
+ encoding: message_encoding
403
+ end
404
+
405
+ # Helper methods
286
406
 
287
- execute { iam.get_iam_policy get_req }
407
+ def get_topic_policy topic_name, options = {}
408
+ iam.get_iam_policy resource: topic_path(topic_name, options)
288
409
  end
289
410
 
290
- def set_subscription_policy subscription_name, new_policy, options = {}
291
- set_req = Google::Iam::V1::SetIamPolicyRequest.new(
292
- resource: subscription_path(subscription_name, options),
293
- policy: new_policy
294
- )
411
+ def set_topic_policy topic_name, new_policy, options = {}
412
+ iam.set_iam_policy resource: topic_path(topic_name, options), policy: new_policy
413
+ end
295
414
 
296
- execute { iam.set_iam_policy set_req }
415
+ def test_topic_permissions topic_name, permissions, options = {}
416
+ iam.test_iam_permissions resource: topic_path(topic_name, options), permissions: permissions
297
417
  end
298
418
 
299
- def test_subscription_permissions subscription_name,
300
- permissions, options = {}
301
- test_req = Google::Iam::V1::TestIamPermissionsRequest.new(
302
- resource: subscription_path(subscription_name, options),
303
- permissions: permissions
304
- )
419
+ def get_subscription_policy subscription_name, options = {}
420
+ iam.get_iam_policy resource: subscription_path(subscription_name, options)
421
+ end
422
+
423
+ def set_subscription_policy subscription_name, new_policy, options = {}
424
+ iam.set_iam_policy resource: subscription_path(subscription_name, options), policy: new_policy
425
+ end
305
426
 
306
- execute { iam.test_iam_permissions test_req }
427
+ def test_subscription_permissions subscription_name, permissions, options = {}
428
+ iam.test_iam_permissions resource: subscription_path(subscription_name, options), permissions: permissions
307
429
  end
308
430
 
309
431
  def project_path options = {}
@@ -313,28 +435,48 @@ module Google
313
435
 
314
436
  def topic_path topic_name, options = {}
315
437
  return topic_name if topic_name.to_s.include? "/"
316
- "#{project_path(options)}/topics/#{topic_name}"
438
+ "#{project_path options}/topics/#{topic_name}"
317
439
  end
318
440
 
319
441
  def subscription_path subscription_name, options = {}
320
442
  return subscription_name if subscription_name.to_s.include? "/"
321
- "#{project_path(options)}/subscriptions/#{subscription_name}"
443
+ "#{project_path options}/subscriptions/#{subscription_name}"
444
+ end
445
+
446
+ def snapshot_path snapshot_name, options = {}
447
+ return snapshot_name if snapshot_name.nil? || snapshot_name.to_s.include?("/")
448
+ "#{project_path options}/snapshots/#{snapshot_name}"
449
+ end
450
+
451
+ def schema_path schema_name, options = {}
452
+ return schema_name if schema_name.nil? || schema_name.to_s.include?("/")
453
+ "#{project_path options}/schemas/#{schema_name}"
322
454
  end
323
455
 
324
456
  def inspect
325
- "#{self.class}(#{@project})"
457
+ "#<#{self.class.name} (#{@project})>"
326
458
  end
327
459
 
328
460
  protected
329
461
 
330
- def execute
331
- Google::Cloud::Core::GrpcBackoff.new(retries: retries).execute do
332
- yield
462
+ def a_time? obj
463
+ return false unless obj.respond_to? :to_time
464
+ # Rails' String#to_time returns nil if the string doesn't parse.
465
+ return false if obj.to_time.nil?
466
+ true
467
+ end
468
+
469
+ def dead_letter_policy options
470
+ return nil unless options[:dead_letter_topic_name]
471
+ policy = Google::Cloud::PubSub::V1::DeadLetterPolicy.new dead_letter_topic: options[:dead_letter_topic_name]
472
+ if options[:dead_letter_max_delivery_attempts]
473
+ policy.max_delivery_attempts = options[:dead_letter_max_delivery_attempts]
333
474
  end
334
- rescue GRPC::BadStatus => e
335
- raise Error.from_error(e)
475
+ policy
336
476
  end
337
477
  end
338
478
  end
479
+
480
+ Pubsub = PubSub unless const_defined? :Pubsub
339
481
  end
340
482
  end