google-cloud-pubsub 0.26.0 → 2.6.1

Sign up to get free protection for your applications and to get access to all the features.
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