google-cloud-pubsub 2.4.0 → 2.5.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a4148f77602c7b9031ed772a14735b25414034684472928fb5244a3c07c2c080
4
- data.tar.gz: 247fd6d4697c8e4f04858487441a3552f30ebe3010720861a1e2c9e8198de219
3
+ metadata.gz: 00a75b823e392ec6afe50d693ae28a42833c2b40f06e8fa8311dff1cbafcc2df
4
+ data.tar.gz: d1caf14295648c05ac0f067832f1c7c8c51ee8638da47c49d3d5af6ad26ce23f
5
5
  SHA512:
6
- metadata.gz: c926ed2d0bca88e81a0545e86ca4fdd916df9d24f1108e4e74cf9140c0a835b79fb6fc207074d62a920de0958e69071235d0c8874970aae9db3657e24c36b2e1
7
- data.tar.gz: 3f719066bf2ffc015b88dd0ffc5f13c38d853c2e54603daa6190905420a87b4aeb9372e4d1bcb37d68863ac38151d147d465ec3891333608718ede84123dca92
6
+ metadata.gz: 82745cfef6ebc3a5dae4bb44168660c6525ea2a2cac5d16f0087b8791d472a2d3eff5961627bf0ae7701a7f731715a21049b2da80ab551516c8e8da98aa31e6c
7
+ data.tar.gz: e9e2671fcf438f9cc5e7a5baa7cba1a1bb44fa5955bcad7a8ebaaffa111391457ea4d218a173c8f67b6a327e5f622406c20bd223c4799a5720008a5a99eda3c6
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Release History
2
2
 
3
+ ### 2.5.0 / 2021-04-01
4
+
5
+ #### Features
6
+
7
+ * Add Schema support
8
+ * Add Schema
9
+ * Add Project#create_schema
10
+ * Add Project#schema
11
+ * Add Project#schemas (Schema::List)
12
+ * Add Project#valid_schema?
13
+ * Add schema options to Project#create_topic
14
+ * Add Topic#schema_name
15
+ * Add Topic#message_encoding
16
+ * Add Topic#message_encoding_binary?
17
+ * Add Topic#message_encoding_json?
18
+
3
19
  ### 2.4.0 / 2021-03-10
4
20
 
5
21
  #### Features
@@ -18,6 +18,7 @@ require "google/cloud/pubsub/service"
18
18
  require "google/cloud/pubsub/credentials"
19
19
  require "google/cloud/pubsub/topic"
20
20
  require "google/cloud/pubsub/batch_publisher"
21
+ require "google/cloud/pubsub/schema"
21
22
  require "google/cloud/pubsub/snapshot"
22
23
 
23
24
  module Google
@@ -192,15 +193,31 @@ module Google
192
193
  #
193
194
  # Hash keys and values may include the following:
194
195
  #
195
- # * `:max_bytes` (Integer) The maximum size of messages to be collected before the batch is published. Default
196
- # is 1,000,000 (1MB).
197
- # * `:max_messages` (Integer) The maximum number of messages to be collected before the batch is published.
198
- # Default is 100.
199
- # * `:interval` (Numeric) The number of seconds to collect messages before the batch is published. Default is
200
- # 0.01.
201
- # * `:threads` (Hash) The number of threads to create to handle concurrent calls by the publisher:
202
- # * `:publish` (Integer) The number of threads used to publish messages. Default is 2.
203
- # * `:callback` (Integer) The number of threads to handle the published messages' callbacks. Default is 4.
196
+ # * `:max_bytes` (Integer) The maximum size of messages to be collected
197
+ # before the batch is published. Default is 1,000,000 (1MB).
198
+ # * `:max_messages` (Integer) The maximum number of messages to be
199
+ # collected before the batch is published. Default is 100.
200
+ # * `:interval` (Numeric) The number of seconds to collect messages before
201
+ # the batch is published. Default is 0.01.
202
+ # * `:threads` (Hash) The number of threads to create to handle concurrent
203
+ # calls by the publisher:
204
+ #
205
+ # * `:publish` (Integer) The number of threads used to publish messages.
206
+ # Default is 2.
207
+ # * `:callback` (Integer) The number of threads to handle the published
208
+ # messages' callbacks. Default is 4.
209
+ # @param [String] schema_name The name of the schema that messages
210
+ # published should be validated against. Optional. The value can be a
211
+ # simple schema ID (relative name), in which case the current project
212
+ # ID will be supplied, or a fully-qualified schema name in the form
213
+ # `projects/{project_id}/schemas/{schema_id}`. If provided,
214
+ # `message_encoding` must also be provided.
215
+ # @param [String, Symbol] message_encoding The encoding of messages validated
216
+ # against the schema identified by `schema_name`. Optional. Values include:
217
+ #
218
+ # * `JSON` - JSON encoding.
219
+ # * `BINARY` - Binary encoding, as defined by the schema type. For some
220
+ # schema types, binary encoding may not be available.
204
221
  #
205
222
  # @return [Google::Cloud::PubSub::Topic]
206
223
  #
@@ -210,12 +227,20 @@ module Google
210
227
  # pubsub = Google::Cloud::PubSub.new
211
228
  # topic = pubsub.create_topic "my-topic"
212
229
  #
213
- def create_topic topic_name, labels: nil, kms_key: nil, persistence_regions: nil, async: nil
230
+ def create_topic topic_name,
231
+ labels: nil,
232
+ kms_key: nil,
233
+ persistence_regions: nil,
234
+ async: nil,
235
+ schema_name: nil,
236
+ message_encoding: nil
214
237
  ensure_service!
215
238
  grpc = service.create_topic topic_name,
216
239
  labels: labels,
217
240
  kms_key_name: kms_key,
218
- persistence_regions: persistence_regions
241
+ persistence_regions: persistence_regions,
242
+ schema_name: schema_name,
243
+ message_encoding: message_encoding
219
244
  Topic.from_grpc grpc, service, async: async
220
245
  end
221
246
  alias new_topic create_topic
@@ -387,6 +412,198 @@ module Google
387
412
  alias find_snapshots snapshots
388
413
  alias list_snapshots snapshots
389
414
 
415
+ ##
416
+ # Retrieves schema by name.
417
+ #
418
+ # @param [String] schema_name Name of a schema. The value can
419
+ # be a simple schema ID, in which case the current project ID
420
+ # will be supplied, or a fully-qualified schema name in the form
421
+ # `projects/{project_id}/schemas/{schema_id}`.
422
+ # @param view [Symbol, String, nil] Possible values:
423
+ # * `BASIC` - Include the `name` and `type` of the schema, but not the `definition`.
424
+ # * `FULL` - Include all Schema object fields.
425
+ #
426
+ # The default value is `BASIC`.
427
+ # @param [String] project If the schema belongs to a project other
428
+ # than the one currently connected to, the alternate project ID can be
429
+ # specified here. Not used if a fully-qualified schema name is
430
+ # provided for `schema_name`.
431
+ # @param [Boolean] skip_lookup Optionally create a {Schema} object
432
+ # without verifying the schema resource exists on the Pub/Sub
433
+ # service. Calls made on this object will raise errors if the service
434
+ # resource does not exist. Default is `false`.
435
+ #
436
+ # @return [Google::Cloud::PubSub::Schema, nil] Returns `nil` if
437
+ # the schema does not exist.
438
+ #
439
+ # @example
440
+ # require "google/cloud/pubsub"
441
+ #
442
+ # pubsub = Google::Cloud::PubSub.new
443
+ #
444
+ # schema = pubsub.schema "my-schema"
445
+ # schema.name #=> "projects/my-project/schemas/my-schema"
446
+ # schema.type #=> :PROTOCOL_BUFFER
447
+ # # schema.definition # nil - Use view: :full to load complete resource.
448
+ #
449
+ # @example Skip the lookup against the service with `skip_lookup`:
450
+ # require "google/cloud/pubsub"
451
+ #
452
+ # pubsub = Google::Cloud::PubSub.new
453
+ #
454
+ # # No API call is made to retrieve the schema information.
455
+ # # The default project is used in the name.
456
+ # schema = pubsub.schema "my-schema", skip_lookup: true
457
+ # schema.name #=> "projects/my-project/schemas/my-schema"
458
+ # schema.type #=> nil
459
+ # schema.definition #=> nil
460
+ #
461
+ # @example Get the schema definition with `view: :full`:
462
+ # require "google/cloud/pubsub"
463
+ #
464
+ # pubsub = Google::Cloud::PubSub.new
465
+ #
466
+ # schema = pubsub.schema "my-schema", view: :full
467
+ # schema.name #=> "projects/my-project/schemas/my-schema"
468
+ # schema.type #=> :PROTOCOL_BUFFER
469
+ # schema.definition # The schema definition
470
+ #
471
+ def schema schema_name, view: nil, project: nil, skip_lookup: nil
472
+ ensure_service!
473
+ options = { project: project }
474
+ return Schema.from_name schema_name, view, service, options if skip_lookup
475
+ view ||= :BASIC
476
+ grpc = service.get_schema schema_name, view, options
477
+ Schema.from_grpc grpc, service
478
+ rescue Google::Cloud::NotFoundError
479
+ nil
480
+ end
481
+ alias get_schema schema
482
+ alias find_schema schema
483
+
484
+ ##
485
+ # Creates a new schema.
486
+ #
487
+ # @param [String] schema_id The ID to use for the schema, which will
488
+ # become the final component of the schema's resource name. Required.
489
+ #
490
+ # The schema ID (relative name) must start with a letter, and
491
+ # contain only letters (`[A-Za-z]`), numbers (`[0-9]`), dashes (`-`),
492
+ # underscores (`_`), periods (`.`), tildes (`~`), plus (`+`) or percent
493
+ # signs (`%`). It must be between 3 and 255 characters in length, and
494
+ # it must not start with `goog`.
495
+ # @param [String, Symbol] type The type of the schema. Required. Possible
496
+ # values are case-insensitive and include:
497
+ #
498
+ # * `PROTOCOL_BUFFER` - A Protocol Buffer schema definition.
499
+ # * `AVRO` - An Avro schema definition.
500
+ # @param [String] definition The definition of the schema. Required. This
501
+ # should be a string representing the full definition of the schema that
502
+ # is a valid schema definition of the type specified in `type`.
503
+ # @param [String] project If the schema belongs to a project other
504
+ # than the one currently connected to, the alternate project ID can be
505
+ # specified here. Optional.
506
+ #
507
+ # @return [Google::Cloud::PubSub::Schema]
508
+ #
509
+ # @example
510
+ # require "google/cloud/pubsub"
511
+ #
512
+ # pubsub = Google::Cloud::PubSub.new
513
+ #
514
+ # definition = "..."
515
+ # schema = pubsub.create_schema "my-schema", :avro, definition
516
+ # schema.name #=> "projects/my-project/schemas/my-schema"
517
+ #
518
+ def create_schema schema_id, type, definition, project: nil
519
+ ensure_service!
520
+ type = type.to_s.upcase
521
+ grpc = service.create_schema schema_id, type, definition, project: project
522
+ Schema.from_grpc grpc, service
523
+ end
524
+ alias new_schema create_schema
525
+
526
+ ##
527
+ # Retrieves a list of schemas for the given project.
528
+ #
529
+ # @param view [String, Symbol, nil] The set of fields to return in the response. Possible values:
530
+ #
531
+ # * `BASIC` - Include the `name` and `type` of the schema, but not the `definition`.
532
+ # * `FULL` - Include all Schema object fields.
533
+ #
534
+ # The default value is `BASIC`.
535
+ # @param [String] token A previously-returned page token representing
536
+ # part of the larger set of results to view.
537
+ # @param [Integer] max Maximum number of schemas to return.
538
+ #
539
+ # @return [Array<Google::Cloud::PubSub::Schema>] (See
540
+ # {Google::Cloud::PubSub::Schema::List})
541
+ #
542
+ # @example
543
+ # require "google/cloud/pubsub"
544
+ #
545
+ # pubsub = Google::Cloud::PubSub.new
546
+ #
547
+ # schemas = pubsub.schemas
548
+ # schemas.each do |schema|
549
+ # puts schema.name
550
+ # end
551
+ #
552
+ # @example Retrieve all schemas: (See {Schema::List#all})
553
+ # require "google/cloud/pubsub"
554
+ #
555
+ # pubsub = Google::Cloud::PubSub.new
556
+ #
557
+ # schemas = pubsub.schemas
558
+ # schemas.all do |schema|
559
+ # puts schema.name
560
+ # end
561
+ #
562
+ def schemas view: nil, token: nil, max: nil
563
+ ensure_service!
564
+ view ||= :BASIC
565
+ options = { token: token, max: max }
566
+ grpc = service.list_schemas view, options
567
+ Schema::List.from_grpc grpc, service, view, max
568
+ end
569
+ alias find_schemas schemas
570
+ alias list_schemas schemas
571
+
572
+ ##
573
+ # Validates a schema type and definition.
574
+ #
575
+ # @param [String, Symbol] type The type of the schema. Required. Possible
576
+ # values are case-insensitive and include:
577
+ #
578
+ # * `PROTOCOL_BUFFER` - A Protocol Buffer schema definition.
579
+ # * `AVRO` - An Avro schema definition.
580
+ # @param [String] definition The definition of the schema. Required. This
581
+ # should be a string representing the full definition of the schema that
582
+ # is a valid schema definition of the type specified in `type`.
583
+ # @param [String] project If the schema belongs to a project other
584
+ # than the one currently connected to, the alternate project ID can be
585
+ # specified here. Optional.
586
+ #
587
+ # @return [Boolean] `true` if the schema is valid, `false` otherwise.
588
+ #
589
+ # @example
590
+ # require "google/cloud/pubsub"
591
+ #
592
+ # pubsub = Google::Cloud::PubSub.new
593
+ #
594
+ # definition = "..."
595
+ # pubsub.validate_schema :avro, definition #=> true
596
+ #
597
+ def valid_schema? type, definition, project: nil
598
+ ensure_service!
599
+ type = type.to_s.upcase
600
+ service.validate_schema type, definition, project: project # return type is empty
601
+ true
602
+ rescue Google::Cloud::InvalidArgumentError
603
+ false
604
+ end
605
+ alias validate_schema valid_schema?
606
+
390
607
  protected
391
608
 
392
609
  ##
@@ -0,0 +1,310 @@
1
+ # Copyright 2021 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ require "google/cloud/pubsub/schema/list"
17
+ require "google/cloud/pubsub/v1"
18
+
19
+ module Google
20
+ module Cloud
21
+ module PubSub
22
+ ##
23
+ # # Schema
24
+ #
25
+ # A schema resource.
26
+ #
27
+ # @example
28
+ # require "google/cloud/pubsub"
29
+ #
30
+ # pubsub = Google::Cloud::PubSub.new
31
+ #
32
+ # schema = pubsub.schema "my-schema"
33
+ # schema.name #=> "projects/my-project/schemas/my-schema"
34
+ # schema.type #=> :PROTOCOL_BUFFER
35
+ #
36
+ class Schema
37
+ ##
38
+ # @private The Service object.
39
+ attr_accessor :service
40
+
41
+ ##
42
+ # @private The gRPC Google::Cloud::PubSub::V1::Schema object.
43
+ attr_accessor :grpc
44
+
45
+ ##
46
+ # @private Create a new Schema instance.
47
+ def initialize grpc, service, view: nil
48
+ @grpc = grpc
49
+ @service = service
50
+ @exists = nil
51
+ @view = view || :BASIC
52
+ end
53
+
54
+ ##
55
+ # The name of the schema.
56
+ #
57
+ # @return [String] A fully-qualified schema name in the form `projects/{project_id}/schemas/{schema_id}`.
58
+ #
59
+ def name
60
+ @grpc.name
61
+ end
62
+
63
+ ##
64
+ # The type of the schema. Possible values include:
65
+ #
66
+ # * `PROTOCOL_BUFFER` - A Protocol Buffer schema definition.
67
+ # * `AVRO` - An Avro schema definition.
68
+ #
69
+ # @return [String, nil] The upper-case type name.
70
+ #
71
+ def type
72
+ return nil if reference?
73
+ @grpc.type
74
+ end
75
+
76
+ ##
77
+ # The definition of the schema. This should be a string representing the full definition of the schema that is a
78
+ # valid schema definition of the type specified in {#type}.
79
+ #
80
+ # @return [String, nil] The schema definition.
81
+ #
82
+ def definition
83
+ return nil if reference?
84
+ @grpc.definition
85
+ end
86
+
87
+ ##
88
+ # Validates a message against a schema.
89
+ #
90
+ # @param message_data [String] Message to validate against the provided `schema_spec`.
91
+ # @param message_encoding [Symbol, String] The encoding of the message validated against the schema. Values
92
+ # include:
93
+ #
94
+ # * `JSON` - JSON encoding.
95
+ # * `BINARY` - Binary encoding, as defined by the schema type. For some schema types, binary encoding may not
96
+ # be available.
97
+ #
98
+ # @return [Boolean] Returns `true` if the message validiation succeeds, `false` otherwise.
99
+ #
100
+ # @example
101
+ # require "google/cloud/pubsub"
102
+ #
103
+ # pubsub = Google::Cloud::PubSub.new
104
+ # schema = pubsub.schema "my-schema"
105
+ #
106
+ # message_data = { "name" => "Alaska", "post_abbr" => "AK" }.to_json
107
+ # schema.validate_message message_data, :json
108
+ #
109
+ def validate_message message_data, message_encoding
110
+ message_encoding = message_encoding.to_s.upcase
111
+ service.validate_message message_data, message_encoding, schema_name: name
112
+ true
113
+ rescue Google::Cloud::InvalidArgumentError
114
+ false
115
+ end
116
+
117
+ ##
118
+ # Removes the schema, if it exists.
119
+ #
120
+ # @return [Boolean] Returns `true` if the schema was deleted.
121
+ #
122
+ # @example
123
+ # require "google/cloud/pubsub"
124
+ #
125
+ # pubsub = Google::Cloud::PubSub.new
126
+ # schema = pubsub.schema "my-schema"
127
+ #
128
+ # schema.delete
129
+ #
130
+ def delete
131
+ ensure_service!
132
+ service.delete_schema name
133
+ true
134
+ end
135
+
136
+ ##
137
+ # Reloads the schema with current data from the Pub/Sub service.
138
+ #
139
+ # @param view [Symbol, String, nil] The set of fields to return in the response. Possible values:
140
+ # * `BASIC` - Include the `name` and `type` of the schema, but not the `definition`.
141
+ # * `FULL` - Include all Schema object fields.
142
+ #
143
+ # Optional. If not provided or `nil`, the last non-nil `view` argument to this method will be used if one has
144
+ # been given, othewise `BASIC` will be used.
145
+ #
146
+ # @return [Google::Cloud::PubSub::Schema] Returns the reloaded schema.
147
+ #
148
+ # @example Skip retrieving the schema from the service, then load it:
149
+ # require "google/cloud/pubsub"
150
+ #
151
+ # pubsub = Google::Cloud::PubSub.new
152
+ # schema = pubsub.schema "my-schema", skip_lookup: true
153
+ #
154
+ # schema.reload!
155
+ #
156
+ # @example Use the `view` option to load the full resource:
157
+ # require "google/cloud/pubsub"
158
+ #
159
+ # pubsub = Google::Cloud::PubSub.new
160
+ # schema = pubsub.schema "my-schema", view: :basic
161
+ # schema.resource_partial? #=> true
162
+ #
163
+ # schema.reload! view: :full
164
+ # schema.resource_partial? #=> false
165
+ #
166
+ # @!group Lifecycle
167
+ #
168
+ def reload! view: nil
169
+ ensure_service!
170
+ @view = view || @view
171
+ @grpc = service.get_schema name, @view
172
+ @reference = nil
173
+ @exists = nil
174
+ self
175
+ end
176
+ alias refresh! reload!
177
+
178
+ ##
179
+ # Determines whether the schema exists in the Pub/Sub service.
180
+ #
181
+ # @example
182
+ # require "google/cloud/pubsub"
183
+ #
184
+ # pubsub = Google::Cloud::PubSub.new
185
+ #
186
+ # schema = pubsub.schema "my-schema"
187
+ # schema.exists? #=> true
188
+ #
189
+ def exists?
190
+ # Always true if the object is not set as reference
191
+ return true unless reference?
192
+ # If we have a value, return it
193
+ return @exists unless @exists.nil?
194
+ ensure_grpc!
195
+ @exists = true
196
+ rescue Google::Cloud::NotFoundError
197
+ @exists = false
198
+ end
199
+
200
+ ##
201
+ # Determines whether the schema object was created without retrieving the
202
+ # resource representation from the Pub/Sub service.
203
+ #
204
+ # @return [Boolean] `true` when the schema was created without a resource
205
+ # representation, `false` otherwise.
206
+ #
207
+ # @example
208
+ # require "google/cloud/pubsub"
209
+ #
210
+ # pubsub = Google::Cloud::PubSub.new
211
+ #
212
+ # schema = pubsub.schema "my-schema", skip_lookup: true
213
+ # schema.reference? #=> true
214
+ #
215
+ def reference?
216
+ @grpc.type.nil? || @grpc.type == :TYPE_UNSPECIFIED
217
+ end
218
+
219
+ ##
220
+ # Determines whether the schema object was created with a resource
221
+ # representation from the Pub/Sub service.
222
+ #
223
+ # @return [Boolean] `true` when the schema was created with a resource
224
+ # representation, `false` otherwise.
225
+ #
226
+ # @example
227
+ # require "google/cloud/pubsub"
228
+ #
229
+ # pubsub = Google::Cloud::PubSub.new
230
+ #
231
+ # schema = pubsub.schema "my-schema"
232
+ # schema.resource? #=> true
233
+ #
234
+ def resource?
235
+ !reference?
236
+ end
237
+
238
+ ##
239
+ # Whether the schema was created with a partial resource representation
240
+ # from the Pub/Sub service.
241
+ #
242
+ # @return [Boolean] `true` when the schema was created with a partial
243
+ # resource representation, `false` otherwise.
244
+ #
245
+ # @example
246
+ # require "google/cloud/pubsub"
247
+ #
248
+ # pubsub = Google::Cloud::PubSub.new
249
+ # schema = pubsub.schema "my-schema", view: :basic
250
+ #
251
+ # schema.resource_partial? #=> true
252
+ # schema.reload! view: :full # Loads the full resource.
253
+ # schema.resource_partial? #=> false
254
+ #
255
+ def resource_partial?
256
+ resource? && !resource_full?
257
+ end
258
+
259
+ ##
260
+ # Whether the schema was created with a full resource representation
261
+ # from the Pub/Sub service.
262
+ #
263
+ # @return [Boolean] `true` when the schema was created with a full
264
+ # resource representation, `false` otherwise.
265
+ #
266
+ # @example
267
+ # require "google/cloud/pubsub"
268
+ #
269
+ # pubsub = Google::Cloud::PubSub.new
270
+ # schema = pubsub.schema "my-schema", view: :full
271
+ #
272
+ # schema.resource_full? #=> true
273
+ #
274
+ def resource_full?
275
+ resource? && @grpc.definition && !@grpc.definition.empty?
276
+ end
277
+
278
+ ##
279
+ # @private New Schema from a Google::Cloud::PubSub::V1::Schema object.
280
+ def self.from_grpc grpc, service, view: nil
281
+ new grpc, service, view: view
282
+ end
283
+
284
+ ##
285
+ # @private New reference Schema object without making an HTTP request.
286
+ def self.from_name name, view, service, options = {}
287
+ grpc = Google::Cloud::PubSub::V1::Schema.new name: service.schema_path(name, options)
288
+ from_grpc grpc, service, view: view
289
+ end
290
+
291
+ protected
292
+
293
+ ##
294
+ # @private Raise an error unless an active connection to the service is available.
295
+ def ensure_service!
296
+ raise "Must have active connection to service" unless service
297
+ end
298
+
299
+ ##
300
+ # Ensures a Google::Cloud::PubSub::V1::Schema object exists.
301
+ def ensure_grpc!
302
+ ensure_service!
303
+ reload! if reference?
304
+ end
305
+ end
306
+ end
307
+
308
+ Pubsub = PubSub unless const_defined? :Pubsub
309
+ end
310
+ end
@@ -0,0 +1,180 @@
1
+ # Copyright 2021 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ require "delegate"
17
+
18
+ module Google
19
+ module Cloud
20
+ module PubSub
21
+ class Schema
22
+ ##
23
+ # Schema::List is a special case Array with additional values.
24
+ class List < DelegateClass(::Array)
25
+ ##
26
+ # If not empty, indicates that there are more schemas
27
+ # that match the request and this value should be passed to
28
+ # the next {Google::Cloud::PubSub::Project#schemas} to continue.
29
+ attr_accessor :token
30
+
31
+ ##
32
+ # @private Create a new Schema::List with an array of values.
33
+ def initialize arr = []
34
+ @prefix = nil
35
+ @token = nil
36
+ @view = nil
37
+ @max = nil
38
+ super arr
39
+ end
40
+
41
+ ##
42
+ # Whether there a next page of schemas.
43
+ #
44
+ # @return [Boolean]
45
+ #
46
+ # @example
47
+ # require "google/cloud/pubsub"
48
+ #
49
+ # pubsub = Google::Cloud::PubSub.new
50
+ #
51
+ # schemas = pubsub.schemas
52
+ # if schemas.next?
53
+ # next_schemas = schemas.next
54
+ # end
55
+ #
56
+ def next?
57
+ !token.nil?
58
+ end
59
+
60
+ ##
61
+ # Retrieve the next page of schemas.
62
+ #
63
+ # @return [Schema::List]
64
+ #
65
+ # @example
66
+ # require "google/cloud/pubsub"
67
+ #
68
+ # pubsub = Google::Cloud::PubSub.new
69
+ #
70
+ # schemas = pubsub.schemas
71
+ # if schemas.next?
72
+ # next_schemas = schemas.next
73
+ # end
74
+ #
75
+ def next
76
+ return nil unless next?
77
+ ensure_service!
78
+ next_schemas
79
+ end
80
+
81
+ ##
82
+ # Retrieves remaining results by repeatedly invoking {#next} until
83
+ # {#next?} returns `false`. Calls the given block once for each
84
+ # result, which is passed as the argument to the block.
85
+ #
86
+ # An Enumerator is returned if no block is given.
87
+ #
88
+ # This method will make repeated API calls until all remaining results
89
+ # are retrieved. (Unlike `#each`, for example, which merely iterates
90
+ # over the results returned by a single API call.) Use with caution.
91
+ #
92
+ # @param [Integer] request_limit The upper limit of API requests to
93
+ # make to load all schemas. Default is no limit.
94
+ # @yield [schema] The block for accessing each schema.
95
+ # @yieldparam [Schema] schema The schema object.
96
+ #
97
+ # @return [Enumerator]
98
+ #
99
+ # @example Iterating each schema by passing a block:
100
+ # require "google/cloud/pubsub"
101
+ #
102
+ # pubsub = Google::Cloud::PubSub.new
103
+ #
104
+ # schemas = pubsub.schemas
105
+ # schemas.all do |schema|
106
+ # puts schema.name
107
+ # end
108
+ #
109
+ # @example Using the enumerator by not passing a block:
110
+ # require "google/cloud/pubsub"
111
+ #
112
+ # pubsub = Google::Cloud::PubSub.new
113
+ #
114
+ # schemas = pubsub.schemas
115
+ # all_names = schemas.all.map do |schema|
116
+ # schema.name
117
+ # end
118
+ #
119
+ # @example Limit the number of API calls made:
120
+ # require "google/cloud/pubsub"
121
+ #
122
+ # pubsub = Google::Cloud::PubSub.new
123
+ #
124
+ # schemas = pubsub.schemas
125
+ # schemas.all(request_limit: 10) do |schema|
126
+ # puts schema.name
127
+ # end
128
+ #
129
+ def all request_limit: nil, &block
130
+ request_limit = request_limit.to_i if request_limit
131
+ return enum_for :all, request_limit: request_limit unless block_given?
132
+ results = self
133
+ loop do
134
+ results.each(&block)
135
+ if request_limit
136
+ request_limit -= 1
137
+ break if request_limit.negative?
138
+ end
139
+ break unless results.next?
140
+ results = results.next
141
+ end
142
+ end
143
+
144
+ ##
145
+ # @private New Schemas::List from a
146
+ # Google::Cloud::PubSub::V1::ListSchemasRequest object.
147
+ def self.from_grpc grpc_list, service, view, max = nil
148
+ subs = new(Array(grpc_list.schemas).map do |grpc|
149
+ Schema.from_grpc grpc, service
150
+ end)
151
+ token = grpc_list.next_page_token
152
+ token = nil if token == "".freeze
153
+ subs.instance_variable_set :@token, token
154
+ subs.instance_variable_set :@service, service
155
+ subs.instance_variable_set :@view, view
156
+ subs.instance_variable_set :@max, max
157
+ subs
158
+ end
159
+
160
+ protected
161
+
162
+ ##
163
+ # @private Raise an error unless an active connection to the service
164
+ # is available.
165
+ def ensure_service!
166
+ raise "Must have active connection to service" unless @service
167
+ end
168
+
169
+ def next_schemas
170
+ options = { prefix: @prefix, token: @token, max: @max }
171
+ grpc = @service.list_schemas @view, options
172
+ self.class.from_grpc grpc, @service, @view, @max
173
+ end
174
+ end
175
+ end
176
+ end
177
+
178
+ Pubsub = PubSub unless const_defined? :Pubsub
179
+ end
180
+ end
@@ -49,49 +49,56 @@ module Google
49
49
 
50
50
  def subscriber
51
51
  return mocked_subscriber if mocked_subscriber
52
- @subscriber ||= begin
53
- V1::Subscriber::Client.new do |config|
54
- config.credentials = credentials if credentials
55
- config.timeout = timeout if timeout
56
- config.endpoint = host if host
57
- config.lib_name = "gccl"
58
- config.lib_version = Google::Cloud::PubSub::VERSION
59
- config.metadata = { "google-cloud-resource-prefix": "projects/#{@project}" }
60
- end
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}" }
61
59
  end
62
60
  end
63
61
  attr_accessor :mocked_subscriber
64
62
 
65
63
  def publisher
66
64
  return mocked_publisher if mocked_publisher
67
- @publisher ||= begin
68
- V1::Publisher::Client.new do |config|
69
- config.credentials = credentials if credentials
70
- config.timeout = timeout if timeout
71
- config.endpoint = host if host
72
- config.lib_name = "gccl"
73
- config.lib_version = Google::Cloud::PubSub::VERSION
74
- config.metadata = { "google-cloud-resource-prefix": "projects/#{@project}" }
75
- end
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}" }
76
72
  end
77
73
  end
78
74
  attr_accessor :mocked_publisher
79
75
 
80
76
  def iam
81
77
  return mocked_iam if mocked_iam
82
- @iam ||= begin
83
- V1::IAMPolicy::Client.new do |config|
84
- config.credentials = credentials if credentials
85
- config.timeout = timeout if timeout
86
- config.endpoint = host if host
87
- config.lib_name = "gccl"
88
- config.lib_version = Google::Cloud::PubSub::VERSION
89
- config.metadata = { "google-cloud-resource-prefix" => "projects/#{@project}" }
90
- end
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}" }
91
85
  end
92
86
  end
93
87
  attr_accessor :mocked_iam
94
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
99
+ end
100
+ attr_accessor :mocked_schemas
101
+
95
102
  ##
96
103
  # Gets the configuration of a topic.
97
104
  # Since the topic only has the name attribute,
@@ -114,18 +121,35 @@ module Google
114
121
 
115
122
  ##
116
123
  # Creates the given topic with the given name.
117
- def create_topic topic_name, labels: nil, kms_key_name: nil, persistence_regions: nil, 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: {}
118
131
  if persistence_regions
119
- message_storage_policy = {
132
+ message_storage_policy = Google::Cloud::PubSub::V1::MessageStoragePolicy.new(
120
133
  allowed_persistence_regions: Array(persistence_regions)
121
- }
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
+ )
122
145
  end
123
146
 
124
147
  publisher.create_topic \
125
148
  name: topic_path(topic_name, options),
126
149
  labels: labels,
127
150
  kms_key_name: kms_key_name,
128
- message_storage_policy: message_storage_policy
151
+ message_storage_policy: message_storage_policy,
152
+ schema_settings: schema_settings
129
153
  end
130
154
 
131
155
  def update_topic topic_obj, *fields
@@ -297,6 +321,89 @@ module Google
297
321
  end
298
322
  end
299
323
 
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
346
+ )
347
+ schemas.create_schema parent: project_path(options),
348
+ schema: schema,
349
+ schema_id: schema_id
350
+ end
351
+
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
+ end
363
+
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
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
406
+
300
407
  def get_topic_policy topic_name, options = {}
301
408
  iam.get_iam_policy resource: topic_path(topic_name, options)
302
409
  end
@@ -341,6 +448,11 @@ module Google
341
448
  "#{project_path options}/snapshots/#{snapshot_name}"
342
449
  end
343
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}"
454
+ end
455
+
344
456
  def inspect
345
457
  "#<#{self.class.name} (#{@project})>"
346
458
  end
@@ -15,6 +15,7 @@
15
15
 
16
16
  require "google/cloud/errors"
17
17
  require "google/cloud/pubsub/snapshot/list"
18
+ require "google/cloud/pubsub/v1"
18
19
 
19
20
  module Google
20
21
  module Cloud
@@ -233,6 +233,78 @@ module Google
233
233
  @resource_name = nil
234
234
  end
235
235
 
236
+ ##
237
+ # The name of the schema that messages published should be validated against, if schema settings are configured
238
+ # for the topic. The value is a fully-qualified schema name in the form
239
+ # `projects/{project_id}/schemas/{schema_id}`. If present, {#message_encoding} should also be present. The value
240
+ # of this field will be `_deleted-schema_` if the schema has been deleted.
241
+ #
242
+ # Makes an API call to retrieve the schema settings when called on a reference object. See {#reference?}.
243
+ #
244
+ # @return [String, nil] The schema name, or `nil` if schema settings are not configured for the topic.
245
+ #
246
+ # @example
247
+ # require "google/cloud/pubsub"
248
+ #
249
+ # pubsub = Google::Cloud::PubSub.new
250
+ #
251
+ # topic = pubsub.topic "my-topic"
252
+ #
253
+ # topic.schema_name #=> "projects/my-project/schemas/my-schema"
254
+ #
255
+ def schema_name
256
+ ensure_grpc!
257
+ @grpc.schema_settings&.schema
258
+ end
259
+
260
+ ##
261
+ # The encoding of messages validated against the schema identified by {#schema_name}. If present, {#schema_name}
262
+ # should also be present. Values include:
263
+ #
264
+ # * `JSON` - JSON encoding.
265
+ # * `BINARY` - Binary encoding, as defined by the schema type. For some schema types, binary encoding may not be
266
+ # available.
267
+ #
268
+ # Makes an API call to retrieve the schema settings when called on a reference object. See {#reference?}.
269
+ #
270
+ # @return [Symbol, nil] The schema encoding, or `nil` if schema settings are not configured for the topic.
271
+ #
272
+ # @example
273
+ # require "google/cloud/pubsub"
274
+ #
275
+ # pubsub = Google::Cloud::PubSub.new
276
+ #
277
+ # topic = pubsub.topic "my-topic"
278
+ #
279
+ # topic.message_encoding #=> :JSON
280
+ #
281
+ def message_encoding
282
+ ensure_grpc!
283
+ @grpc.schema_settings&.encoding
284
+ end
285
+
286
+ ##
287
+ # Checks if the encoding of messages in the schema settings is `BINARY`. See {#message_encoding}.
288
+ #
289
+ # Makes an API call to retrieve the schema settings when called on a reference object. See {#reference?}.
290
+ #
291
+ # @return [Boolean] `true` when `BINARY`, `false` if not `BINARY` or schema settings is not set.
292
+ #
293
+ def message_encoding_binary?
294
+ message_encoding.to_s.upcase == "BINARY"
295
+ end
296
+
297
+ ##
298
+ # Checks if the encoding of messages in the schema settings is `JSON`. See {#message_encoding}.
299
+ #
300
+ # Makes an API call to retrieve the schema settings when called on a reference object. See {#reference?}.
301
+ #
302
+ # @return [Boolean] `true` when `JSON`, `false` if not `JSON` or schema settings is not set.
303
+ #
304
+ def message_encoding_json?
305
+ message_encoding.to_s.upcase == "JSON"
306
+ end
307
+
236
308
  ##
237
309
  # Permanently deletes the topic.
238
310
  #
@@ -16,7 +16,7 @@
16
16
  module Google
17
17
  module Cloud
18
18
  module PubSub
19
- VERSION = "2.4.0".freeze
19
+ VERSION = "2.5.0".freeze
20
20
  end
21
21
 
22
22
  Pubsub = PubSub unless const_defined? :Pubsub
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google-cloud-pubsub
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.0
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Moore
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-03-11 00:00:00.000000000 Z
12
+ date: 2021-04-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: concurrent-ruby
@@ -67,6 +67,20 @@ dependencies:
67
67
  - - "~>"
68
68
  - !ruby/object:Gem::Version
69
69
  version: '1.1'
70
+ - !ruby/object:Gem::Dependency
71
+ name: avro
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '1.10'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '1.10'
70
84
  - !ruby/object:Gem::Dependency
71
85
  name: google-style
72
86
  requirement: !ruby/object:Gem::Requirement
@@ -225,6 +239,8 @@ files:
225
239
  - lib/google/cloud/pubsub/publish_result.rb
226
240
  - lib/google/cloud/pubsub/received_message.rb
227
241
  - lib/google/cloud/pubsub/retry_policy.rb
242
+ - lib/google/cloud/pubsub/schema.rb
243
+ - lib/google/cloud/pubsub/schema/list.rb
228
244
  - lib/google/cloud/pubsub/service.rb
229
245
  - lib/google/cloud/pubsub/snapshot.rb
230
246
  - lib/google/cloud/pubsub/snapshot/list.rb