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 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,
@@ -15,77 +15,89 @@
15
15
 
16
16
  require "google/cloud/errors"
17
17
  require "google/cloud/pubsub/credentials"
18
+ require "google/cloud/pubsub/convert"
18
19
  require "google/cloud/pubsub/version"
19
20
  require "google/cloud/pubsub/v1"
20
- require "google/gax/errors"
21
+ require "securerandom"
21
22
 
22
23
  module Google
23
24
  module Cloud
24
- module Pubsub
25
+ module PubSub
25
26
  ##
26
- # @private Represents the GAX Pub/Sub service, including all the API
27
- # methods.
27
+ # @private Represents the Pub/Sub service API, including IAM mixins.
28
28
  class Service
29
- attr_accessor :project, :credentials, :host, :timeout, :client_config
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
30
39
 
31
40
  ##
32
41
  # Creates a new Service instance.
33
- def initialize project, credentials, host: nil, timeout: nil,
34
- client_config: nil
42
+ def initialize project, credentials, host: nil, timeout: nil
35
43
  @project = project
36
44
  @credentials = credentials
37
- @host = host || "pubsub.googleapis.com"
45
+ @host = host
38
46
  @timeout = timeout
39
- @client_config = client_config || {}
40
- end
41
-
42
- def channel
43
- require "grpc"
44
- GRPC::Core::Channel.new host, chan_args, chan_creds
45
- end
46
-
47
- def chan_args
48
- { "grpc.max_send_message_length" => -1,
49
- "grpc.max_receive_message_length" => -1 }
50
- end
51
-
52
- def chan_creds
53
- return credentials if insecure?
54
- require "grpc"
55
- GRPC::Core::ChannelCredentials.new.compose \
56
- GRPC::Core::CallCredentials.new credentials.client.updater_proc
47
+ @client_id = SecureRandom.uuid.freeze
57
48
  end
58
49
 
59
50
  def subscriber
60
51
  return mocked_subscriber if mocked_subscriber
61
- @subscriber ||= begin
62
- V1::SubscriberClient.new(
63
- service_path: host,
64
- channel: channel,
65
- timeout: timeout,
66
- client_config: client_config,
67
- lib_name: "gccl",
68
- lib_version: Google::Cloud::Pubsub::VERSION)
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}" }
69
59
  end
70
60
  end
71
61
  attr_accessor :mocked_subscriber
72
62
 
73
63
  def publisher
74
64
  return mocked_publisher if mocked_publisher
75
- @publisher ||= begin
76
- V1::PublisherClient.new(
77
- service_path: host,
78
- channel: channel,
79
- timeout: timeout,
80
- lib_name: "gccl",
81
- lib_version: Google::Cloud::Pubsub::VERSION)
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}" }
82
72
  end
83
73
  end
84
74
  attr_accessor :mocked_publisher
85
75
 
86
- def insecure?
87
- credentials == :this_channel_is_insecure
76
+ def iam
77
+ return mocked_iam if mocked_iam
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
86
+ end
87
+ attr_accessor :mocked_iam
88
+
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
88
99
  end
100
+ attr_accessor :mocked_schemas
89
101
 
90
102
  ##
91
103
  # Gets the configuration of a topic.
@@ -94,37 +106,55 @@ module Google
94
106
  # If other attributes are added in the future,
95
107
  # they will be returned here.
96
108
  def get_topic topic_name, options = {}
97
- execute do
98
- publisher.get_topic topic_path(topic_name, options),
99
- options: default_options
100
- end
109
+ publisher.get_topic topic: topic_path(topic_name, options)
101
110
  end
102
111
 
103
112
  ##
104
113
  # Lists matching topics.
105
114
  def list_topics options = {}
106
- call_options = default_options
107
- if (token = options[:token])
108
- call_options = Google::Gax::CallOptions.new kwargs: default_headers,
109
- page_token: token
110
- end
115
+ paged_enum = publisher.list_topics project: project_path(options),
116
+ page_size: options[:max],
117
+ page_token: options[:token]
111
118
 
112
- execute do
113
- paged_enum = publisher.list_topics project_path(options),
114
- page_size: options[:max],
115
- options: call_options
116
-
117
- paged_enum.page.response
118
- end
119
+ paged_enum.response
119
120
  end
120
121
 
121
122
  ##
122
123
  # Creates the given topic with the given name.
123
- def create_topic topic_name, options = {}
124
- execute do
125
- publisher.create_topic topic_path(topic_name, options),
126
- options: default_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
+ )
127
145
  end
146
+
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
128
158
  end
129
159
 
130
160
  ##
@@ -133,10 +163,7 @@ module Google
133
163
  # exist. After a topic is deleted, a new topic may be created with the
134
164
  # same name.
135
165
  def delete_topic topic_name
136
- execute do
137
- publisher.delete_topic topic_path(topic_name),
138
- options: default_options
139
- end
166
+ publisher.delete_topic topic: topic_path(topic_name)
140
167
  end
141
168
 
142
169
  ##
@@ -145,256 +172,260 @@ module Google
145
172
  # The messages parameter is an array of arrays.
146
173
  # The first element is the data, second is attributes hash.
147
174
  def publish topic, messages
148
- messages = messages.map do |data, attributes|
149
- Google::Pubsub::V1::PubsubMessage.new(
150
- data: data, attributes: attributes)
151
- end
152
-
153
- execute do
154
- publisher.publish topic_path(topic), messages,
155
- options: default_options
156
- end
175
+ publisher.publish topic: topic_path(topic), messages: messages
157
176
  end
158
177
 
159
178
  ##
160
179
  # Gets the details of a subscription.
161
180
  def get_subscription subscription_name, options = {}
162
- subscription = subscription_path(subscription_name, options)
163
- execute do
164
- subscriber.get_subscription subscription, options: default_options
165
- end
181
+ subscriber.get_subscription subscription: subscription_path(subscription_name, options)
166
182
  end
167
183
 
168
184
  ##
169
185
  # Lists matching subscriptions by project and topic.
170
186
  def list_topics_subscriptions topic, options = {}
171
- call_options = default_options
172
- if (token = options[:token])
173
- call_options = Google::Gax::CallOptions.new kwargs: default_headers,
174
- page_token: token
175
- end
176
-
177
- execute do
178
- paged_enum = publisher.list_topic_subscriptions \
179
- topic_path(topic, options),
180
- page_size: options[:max],
181
- options: call_options
182
-
183
- paged_enum.page.response
184
- end
187
+ publisher.list_topic_subscriptions topic: topic_path(topic, options),
188
+ page_size: options[:max],
189
+ page_token: options[:token]
185
190
  end
186
191
 
187
192
  ##
188
193
  # Lists matching subscriptions by project.
189
194
  def list_subscriptions options = {}
190
- call_options = default_options
191
- if (token = options[:token])
192
- call_options = Google::Gax::CallOptions.new kwargs: default_headers,
193
- page_token: token
194
- end
195
-
196
- execute do
197
- paged_enum = subscriber.list_subscriptions project_path(options),
198
- page_size: options[:max],
199
- options: call_options
195
+ paged_enum = subscriber.list_subscriptions project: project_path(options),
196
+ page_size: options[:max],
197
+ page_token: options[:token]
200
198
 
201
- paged_enum.page.response
202
- end
199
+ paged_enum.response
203
200
  end
204
201
 
205
202
  ##
206
203
  # Creates a subscription on a given topic for a given subscriber.
207
204
  def create_subscription topic, subscription_name, options = {}
208
- name = subscription_path(subscription_name, options)
209
- topic = topic_path(topic)
210
- push_config = if options[:endpoint]
211
- Google::Pubsub::V1::PushConfig.new \
212
- push_endpoint: options[:endpoint],
213
- attributes: (options[:attributes] || {}).to_h
214
- end
215
- deadline = options[:deadline]
216
- retain_acked = options[:retain_acked]
217
- mrd = number_to_duration options[:retention]
218
-
219
- execute do
220
- subscriber.create_subscription name,
221
- topic,
222
- push_config: push_config,
223
- ack_deadline_seconds: deadline,
224
- retain_acked_messages: retain_acked,
225
- message_retention_duration: mrd,
226
- options: default_options
227
- 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
218
+
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
228
222
  end
229
223
 
230
224
  ##
231
- # Deletes an existing subscription.
232
- # All pending messages in the subscription are immediately dropped.
225
+ # Deletes an existing subscription. All pending messages in the subscription are immediately dropped.
233
226
  def delete_subscription subscription
234
- execute do
235
- subscriber.delete_subscription subscription_path(subscription),
236
- options: default_options
237
- end
227
+ subscriber.delete_subscription subscription: subscription_path(subscription)
228
+ end
229
+
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)
238
236
  end
239
237
 
240
238
  ##
241
239
  # Pulls a single message from the server.
242
240
  def pull subscription, options = {}
243
- subscription = subscription_path(subscription, options)
244
241
  max_messages = options.fetch(:max, 100).to_i
245
242
  return_immediately = !(!options.fetch(:immediate, true))
246
243
 
247
- execute do
248
- subscriber.pull subscription,
249
- max_messages,
250
- return_immediately: return_immediately,
251
- options: default_options
252
- end
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
253
251
  end
254
252
 
255
253
  ##
256
254
  # Acknowledges receipt of a message.
257
255
  def acknowledge subscription, *ack_ids
258
- execute do
259
- subscriber.acknowledge subscription_path(subscription), ack_ids,
260
- options: default_options
261
- end
256
+ subscriber.acknowledge subscription: subscription_path(subscription), ack_ids: ack_ids
262
257
  end
263
258
 
264
259
  ##
265
260
  # Modifies the PushConfig for a specified subscription.
266
261
  def modify_push_config subscription, endpoint, attributes
267
- subscription = subscription_path(subscription)
268
262
  # Convert attributes to strings to match the protobuf definition
269
263
  attributes = Hash[attributes.map { |k, v| [String(k), String(v)] }]
270
- push_config = Google::Pubsub::V1::PushConfig.new(
264
+ push_config = Google::Cloud::PubSub::V1::PushConfig.new(
271
265
  push_endpoint: endpoint,
272
- attributes: attributes
266
+ attributes: attributes
273
267
  )
274
268
 
275
- execute do
276
- subscriber.modify_push_config subscription, push_config,
277
- options: default_options
278
- end
269
+ subscriber.modify_push_config subscription: subscription_path(subscription),
270
+ push_config: push_config
279
271
  end
280
272
 
281
273
  ##
282
274
  # Modifies the ack deadline for a specific message.
283
275
  def modify_ack_deadline subscription, ids, deadline
284
- execute do
285
- subscriber.modify_ack_deadline subscription_path(subscription),
286
- Array(ids),
287
- deadline, options: default_options
288
- end
276
+ subscriber.modify_ack_deadline subscription: subscription_path(subscription),
277
+ ack_ids: Array(ids),
278
+ ack_deadline_seconds: deadline
289
279
  end
290
280
 
291
281
  ##
292
282
  # Lists snapshots by project.
293
283
  def list_snapshots options = {}
294
- call_options = default_options
295
- if (token = options[:token])
296
- call_options = Google::Gax::CallOptions.new kwargs: default_headers,
297
- page_token: token
298
- end
299
-
300
- execute do
301
- paged_enum = subscriber.list_snapshots project_path(options),
302
- page_size: options[:max],
303
- options: call_options
284
+ paged_enum = subscriber.list_snapshots project: project_path(options),
285
+ page_size: options[:max],
286
+ page_token: options[:token]
304
287
 
305
- paged_enum.page.response
306
- end
288
+ paged_enum.response
307
289
  end
308
290
 
309
291
  ##
310
292
  # Creates a snapshot on a given subscription.
311
- def create_snapshot subscription, snapshot_name
312
- name = snapshot_path snapshot_name
313
- execute do
314
- subscriber.create_snapshot name,
315
- subscription_path(subscription),
316
- options: default_options
317
- end
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
298
+
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
318
302
  end
319
303
 
320
304
  ##
321
305
  # Deletes an existing snapshot.
322
306
  # All pending messages in the snapshot are immediately dropped.
323
307
  def delete_snapshot snapshot
324
- execute do
325
- subscriber.delete_snapshot snapshot_path(snapshot),
326
- options: default_options
327
- end
308
+ subscriber.delete_snapshot snapshot: snapshot_path(snapshot)
328
309
  end
329
310
 
330
311
  ##
331
312
  # Adjusts the given subscription to a time or snapshot.
332
313
  def seek subscription, time_or_snapshot
333
- subscription = subscription_path(subscription)
334
- execute do
335
- if (time = time_to_timestamp time_or_snapshot)
336
- subscriber.seek subscription, time: time, options: default_options
337
- else
338
- if time_or_snapshot.is_a? Snapshot
339
- time_or_snapshot = time_or_snapshot.name
340
- end
341
- subscriber.seek subscription,
342
- snapshot: snapshot_path(time_or_snapshot),
343
- options: default_options
344
- end
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)
345
321
  end
346
322
  end
347
323
 
348
- def get_topic_policy topic_name, options = {}
349
- execute do
350
- publisher.get_iam_policy topic_path(topic_name, options),
351
- options: default_options
352
- end
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
353
338
  end
354
339
 
355
- def set_topic_policy topic_name, new_policy, options = {}
356
- resource = topic_path(topic_name, options)
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
346
+ )
347
+ schemas.create_schema parent: project_path(options),
348
+ schema: schema,
349
+ schema_id: schema_id
350
+ end
357
351
 
358
- execute do
359
- publisher.set_iam_policy resource, new_policy,
360
- options: default_options
361
- end
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
362
362
  end
363
363
 
364
- def test_topic_permissions topic_name, permissions, options = {}
365
- resource = topic_path(topic_name, options)
364
+ ##
365
+ # Delete a schema.
366
+ def delete_schema schema_name
367
+ schemas.delete_schema name: schema_path(schema_name)
368
+ end
366
369
 
367
- execute do
368
- publisher.test_iam_permissions resource, permissions,
369
- options: default_options
370
- end
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
376
+ )
377
+ schemas.validate_schema parent: project_path(options),
378
+ schema: schema
371
379
  end
372
380
 
373
- def get_subscription_policy subscription_name, options = {}
374
- resource = subscription_path(subscription_name, options)
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
375
406
 
376
- execute do
377
- subscriber.get_iam_policy resource, options: default_options
378
- end
407
+ def get_topic_policy topic_name, options = {}
408
+ iam.get_iam_policy resource: topic_path(topic_name, options)
379
409
  end
380
410
 
381
- def set_subscription_policy subscription_name, new_policy, options = {}
382
- resource = subscription_path(subscription_name, options)
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
383
414
 
384
- execute do
385
- subscriber.set_iam_policy resource, new_policy,
386
- options: default_options
387
- end
415
+ def test_topic_permissions topic_name, permissions, options = {}
416
+ iam.test_iam_permissions resource: topic_path(topic_name, options), permissions: permissions
417
+ end
418
+
419
+ def get_subscription_policy subscription_name, options = {}
420
+ iam.get_iam_policy resource: subscription_path(subscription_name, options)
388
421
  end
389
422
 
390
- def test_subscription_permissions subscription_name,
391
- permissions, options = {}
392
- resource = subscription_path(subscription_name, options)
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
393
426
 
394
- execute do
395
- subscriber.test_iam_permissions resource, permissions,
396
- options: default_options
397
- end
427
+ def test_subscription_permissions subscription_name, permissions, options = {}
428
+ iam.test_iam_permissions resource: subscription_path(subscription_name, options), permissions: permissions
398
429
  end
399
430
 
400
431
  def project_path options = {}
@@ -404,63 +435,48 @@ module Google
404
435
 
405
436
  def topic_path topic_name, options = {}
406
437
  return topic_name if topic_name.to_s.include? "/"
407
- "#{project_path(options)}/topics/#{topic_name}"
438
+ "#{project_path options}/topics/#{topic_name}"
408
439
  end
409
440
 
410
441
  def subscription_path subscription_name, options = {}
411
442
  return subscription_name if subscription_name.to_s.include? "/"
412
- "#{project_path(options)}/subscriptions/#{subscription_name}"
443
+ "#{project_path options}/subscriptions/#{subscription_name}"
413
444
  end
414
445
 
415
446
  def snapshot_path snapshot_name, options = {}
416
- if snapshot_name.nil? || snapshot_name.to_s.include?("/")
417
- return snapshot_name
418
- end
419
- "#{project_path(options)}/snapshots/#{snapshot_name}"
447
+ return snapshot_name if snapshot_name.nil? || snapshot_name.to_s.include?("/")
448
+ "#{project_path options}/snapshots/#{snapshot_name}"
420
449
  end
421
450
 
422
- def inspect
423
- "#{self.class}(#{@project})"
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}"
424
454
  end
425
455
 
426
- protected
427
-
428
- def default_headers
429
- { "google-cloud-resource-prefix" => "projects/#{@project}" }
456
+ def inspect
457
+ "#<#{self.class.name} (#{@project})>"
430
458
  end
431
459
 
432
- def default_options
433
- Google::Gax::CallOptions.new kwargs: default_headers
434
- end
460
+ protected
435
461
 
436
- ##
437
- # @private Get a Google::Protobuf::Timestamp object from a Time object.
438
- def time_to_timestamp time
439
- return nil if time.nil?
440
- # Make sure to_time is supported.
441
- return nil unless time.respond_to? :to_time
442
- time = time.to_time
443
- # Make sure we have a Time object.
462
+ def a_time? obj
463
+ return false unless obj.respond_to? :to_time
444
464
  # Rails' String#to_time returns nil if the string doesn't parse.
445
- return nil unless time
446
- Google::Protobuf::Timestamp.new seconds: time.to_i, nanos: time.nsec
465
+ return false if obj.to_time.nil?
466
+ true
447
467
  end
448
468
 
449
- def number_to_duration number
450
- return nil if number.nil?
451
-
452
- Google::Protobuf::Duration.new \
453
- seconds: number.to_i,
454
- nanos: (number.remainder(1) * 1000000000).round
455
- end
456
-
457
- def execute
458
- yield
459
- rescue Google::Gax::GaxError => e
460
- # GaxError wraps BadStatus, but exposes it as #cause
461
- raise Google::Cloud::Error.from_error(e.cause)
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]
474
+ end
475
+ policy
462
476
  end
463
477
  end
464
478
  end
479
+
480
+ Pubsub = PubSub unless const_defined? :Pubsub
465
481
  end
466
482
  end