avro_turf 1.10.0 → 1.12.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c0907531d40226b59cd545baf7341f3e41613565d50de98684b266b6b33a081f
4
- data.tar.gz: e472794d6e7ecbd4a32b1a08f4cc0eb6b0ae810d849483d86ab16a7da929a9fb
3
+ metadata.gz: 94e8abd646816e6e375365c50ed19eebb3bfd4722548aba30fca974740fd7788
4
+ data.tar.gz: 18bba7e20c8ac10b52177af05db7b4ea6b461f696f4230c7086d1b5e3a7479df
5
5
  SHA512:
6
- metadata.gz: ac1324149cb3299c3e67ffbd287879da88a09c338b967e2098fed63836c9fba5f775623ee6d6ae2ac0ac5e6f6a4ad28ea4c7bb7ece2d1e5979cee2eb379ac43a
7
- data.tar.gz: 84709d06f4b3d97a23c1f0a1b94f4757c8b7024d17354ec65c7068be8cca52cdeed832096d7ea43f646d3f52d09ebd0f2286375456503d9da14cf6cb7a37772b
6
+ metadata.gz: 8b2b977f70cdc2c497a2cf1449d9f84bf11a6d7ce62022fd9295a58ea1133fe10674431dbf765d8676ba404e54c73f5bc35016868fd6e3ce2cbef4ea5027de07
7
+ data.tar.gz: a3ad6d0518e93b12a5371ac338bcb99e7f7acd22728d2527c16a57888e8fe39567d1c8bc57060451cf2b536c653e8cb470809e76381e2ec07a0c3b8cbaefe734
data/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## v1.12.0
6
+
7
+ - Add `connect_timeout` parameter to `AvroTurf::Messaging` to set the timeout for the connection to the schema registry (#197)
8
+
9
+ ## v1.11.0
10
+
11
+ - Add `decode_all` and `decode_all_from_stream` methods to return all entries in a data file (#194)
12
+ - Improve the way schemas are automatically loaded (#190)
13
+ - Increment dependency on `avro` gem to v1.8.
14
+
5
15
  ## v1.10.0
6
16
 
7
17
  - Add `schema_subject_versions` to `ConfluentSchemaRegistry` to retrieve all subject versions for a schema id. (#189)
data/avro_turf.gemspec CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
20
  spec.require_paths = ["lib"]
21
21
 
22
- spec.add_dependency "avro", ">= 1.7.7", "< 1.12"
22
+ spec.add_dependency "avro", ">= 1.8.0", "< 1.12"
23
23
  spec.add_dependency "excon", "~> 0.71"
24
24
 
25
25
  spec.add_development_dependency "bundler", "~> 2.0"
@@ -15,7 +15,8 @@ class AvroTurf::ConfluentSchemaRegistry
15
15
  client_key_pass: nil,
16
16
  client_cert_data: nil,
17
17
  client_key_data: nil,
18
- path_prefix: nil
18
+ path_prefix: nil,
19
+ connect_timeout: nil
19
20
  )
20
21
  @path_prefix = path_prefix
21
22
  @logger = logger
@@ -33,7 +34,8 @@ class AvroTurf::ConfluentSchemaRegistry
33
34
  client_key: client_key,
34
35
  client_key_pass: client_key_pass,
35
36
  client_cert_data: client_cert_data,
36
- client_key_data: client_key_data
37
+ client_key_data: client_key_data,
38
+ connect_timeout: connect_timeout
37
39
  )
38
40
  end
39
41
 
@@ -55,6 +55,7 @@ class AvroTurf
55
55
  # client_key_pass - Password to go with client_key (optional).
56
56
  # client_cert_data - In-memory client certificate (optional).
57
57
  # client_key_data - In-memory client private key to go with client_cert_data (optional).
58
+ # connect_timeout - Timeout to use in the connection with the schema registry (optional).
58
59
  def initialize(
59
60
  registry: nil,
60
61
  registry_url: nil,
@@ -71,7 +72,8 @@ class AvroTurf
71
72
  client_key: nil,
72
73
  client_key_pass: nil,
73
74
  client_cert_data: nil,
74
- client_key_data: nil
75
+ client_key_data: nil,
76
+ connect_timeout: nil
75
77
  )
76
78
  @logger = logger || Logger.new($stderr)
77
79
  @namespace = namespace
@@ -89,7 +91,8 @@ class AvroTurf
89
91
  client_key_pass: client_key_pass,
90
92
  client_cert_data: client_cert_data,
91
93
  client_key_data: client_key_data,
92
- path_prefix: registry_path_prefix
94
+ path_prefix: registry_path_prefix,
95
+ connect_timeout: connect_timeout
93
96
  )
94
97
  )
95
98
  @schemas_by_id = {}
@@ -70,28 +70,22 @@ class AvroTurf::SchemaStore
70
70
  @schemas[fullname] = schema
71
71
 
72
72
  schema
73
- rescue ::Avro::SchemaParseError => e
74
- # This is a hack in order to figure out exactly which type was missing. The
75
- # Avro gem ought to provide this data directly.
76
- if e.to_s =~ /"([\w\.]+)" is not a schema we know about/
77
- # Try to first resolve a referenced schema from disk.
78
- # If this is successful, the Avro gem will have mutated the
79
- # local_schemas_cache, adding all the new schemas it found.
80
- load_schema!($1, local_schemas_cache)
81
-
82
- # Attempt to re-parse the original schema now that the dependency
83
- # has been resolved and use the now-updated local_schemas_cache to
84
- # pick up where we left off.
85
- local_schemas_cache.delete(fullname)
86
- # Ensure all sub-schemas are cleaned up to avoid conflicts when re-parsing
87
- # schema.
88
- local_schemas_cache.each do |schema_name, schema|
89
- local_schemas_cache.delete(schema_name) unless File.exist?(build_schema_path(schema_name))
90
- end
91
- load_schema!(fullname, @schemas.dup)
92
- else
93
- raise
73
+ rescue ::Avro::UnknownSchemaError => e
74
+ # Try to first resolve a referenced schema from disk.
75
+ # If this is successful, the Avro gem will have mutated the
76
+ # local_schemas_cache, adding all the new schemas it found.
77
+ load_schema!(e.type_name, local_schemas_cache)
78
+
79
+ # Attempt to re-parse the original schema now that the dependency
80
+ # has been resolved and use the now-updated local_schemas_cache to
81
+ # pick up where we left off.
82
+ local_schemas_cache.delete(fullname)
83
+ # Ensure all sub-schemas are cleaned up to avoid conflicts when re-parsing
84
+ # schema.
85
+ local_schemas_cache.each_key do |schema_name|
86
+ local_schemas_cache.delete(schema_name) unless File.exist?(build_schema_path(schema_name))
94
87
  end
88
+ load_schema!(fullname, @schemas.dup)
95
89
  rescue Errno::ENOENT, Errno::ENAMETOOLONG
96
90
  raise AvroTurf::SchemaNotFoundError, "could not find Avro schema at `#{schema_path}'"
97
91
  end
@@ -1,3 +1,3 @@
1
1
  class AvroTurf
2
- VERSION = "1.10.0"
2
+ VERSION = "1.12.0"
3
3
  end
data/lib/avro_turf.rb CHANGED
@@ -93,24 +93,39 @@ class AvroTurf
93
93
  # namespace - The namespace of the Avro schema used to decode the data.
94
94
  #
95
95
  # Returns whatever is encoded in the data.
96
- def decode(encoded_data, schema_name: nil, namespace: @namespace)
96
+ def decode_first(encoded_data, schema_name: nil, namespace: @namespace)
97
97
  stream = StringIO.new(encoded_data)
98
98
  decode_stream(stream, schema_name: schema_name, namespace: namespace)
99
99
  end
100
100
 
101
- # Decodes Avro data from an IO stream.
101
+ alias decode decode_first
102
+
103
+ # Returns all entries encoded in the data.
104
+ def decode_all(encoded_data, schema_name: nil, namespace: @namespace)
105
+ stream = StringIO.new(encoded_data)
106
+ decode_all_from_stream(stream, schema_name: schema_name, namespace: namespace)
107
+ end
108
+
109
+ # Decodes the first entry from an IO stream containing Avro data.
102
110
  #
103
111
  # stream - An IO object containing Avro data.
104
112
  # schema_name - The String name of the schema that should be used to read
105
113
  # the data. If nil, the writer schema will be used.
106
114
  # namespace - The namespace of the Avro schema used to decode the data.
107
115
  #
108
- # Returns whatever is encoded in the stream.
109
- def decode_stream(stream, schema_name: nil, namespace: @namespace)
116
+ # Returns first entry encoded in the stream.
117
+ def decode_first_from_stream(stream, schema_name: nil, namespace: @namespace)
118
+ data = decode_all_from_stream(stream, schema_name: schema_name, namespace: namespace)
119
+ data.first
120
+ end
121
+
122
+ alias decode_stream decode_first_from_stream
123
+
124
+ # Returns all entries encoded in the stream.
125
+ def decode_all_from_stream(stream, schema_name: nil, namespace: @namespace)
110
126
  schema = schema_name && @schema_store.find(schema_name, namespace)
111
127
  reader = Avro::IO::DatumReader.new(nil, schema)
112
- dr = Avro::DataFile::Reader.new(stream, reader)
113
- dr.first
128
+ Avro::DataFile::Reader.new(stream, reader)
114
129
  end
115
130
 
116
131
  # Validates data against an Avro schema.
@@ -186,6 +186,47 @@ describe AvroTurf do
186
186
  end
187
187
  end
188
188
 
189
+ describe "#decode_all" do
190
+ context "when data contains multiple entries" do
191
+ let(:encoded_data) { "Obj\u0001\u0004\u0014avro.codec\bnull\u0016avro.schema\xB6\u0004[{\"type\": \"record\", \"name\": \"address\", \"fields\": [{\"type\": \"string\", \"name\": \"street\"}, {\"type\": \"string\", \"name\": \"city\"}]}, {\"type\": \"record\", \"name\": \"person\", \"fields\": [{\"type\": \"string\", \"name\": \"name\"}, {\"type\": \"int\", \"name\": \"age\"}, {\"type\": \"address\", \"name\": \"address\"}]}]\u0000\xF9u\x84\xA1c\u0010\x82B\xE2\xCF\xF1\x98\xF7\xF1JH\u0004\x96\u0001\u0002\u0014Python🐍\x80\u0004\u0018Green Street\u001ASan Francisco\u0002\u0010Mojo🐍\u0002\u0016Blue Street\u0014Saturn🪐\xF9u\x84\xA1c\u0010\x82B\xE2\xCF\xF1\x98\xF7\xF1JH" }
192
+
193
+ it "returns array of entries decoded using the inlined writer's schema " do
194
+ expect(avro.decode_all(encoded_data).entries).to eq(
195
+ [
196
+ {"name"=>"Python🐍", "age"=>256, "address"=>{"street"=>"Green Street", "city"=>"San Francisco"}},
197
+ {"name"=>"Mojo🐍", "age"=>1, "address"=>{"street"=>"Blue Street", "city"=>"Saturn🪐"}}
198
+ ]
199
+ )
200
+ end
201
+
202
+ it "returns array of entries decoded using the specified reader's schema " do
203
+ FileUtils.mkdir_p("spec/schemas/reader")
204
+
205
+ define_schema "reader/person.avsc", <<-AVSC
206
+ {
207
+ "name": "person",
208
+ "type": "record",
209
+ "fields": [
210
+ { "name": "fav_color", "type": "string", "default": "red🟥" },
211
+ { "name": "name", "type": "string" },
212
+ { "name": "age", "type": "int" }
213
+ ]
214
+ }
215
+ AVSC
216
+
217
+ expect(
218
+ AvroTurf.new(schemas_path: "spec/schemas/reader")
219
+ .decode_all(encoded_data, schema_name: "person").entries
220
+ ).to eq(
221
+ [
222
+ {"name"=>"Python🐍", "age"=>256, "fav_color"=>"red🟥"},
223
+ {"name"=>"Mojo🐍", "age"=>1, "fav_color"=>"red🟥"}
224
+ ]
225
+ )
226
+ end
227
+ end
228
+ end
229
+
189
230
  describe "#encode_to_stream" do
190
231
  it "writes encoded data to an existing stream" do
191
232
  define_schema "message.avsc", <<-AVSC
@@ -304,6 +345,20 @@ describe AvroTurf do
304
345
  end
305
346
  end
306
347
 
348
+ describe "#decode_all_from_stream" do
349
+ it "returns all entries when decodes Avro data from a stream containing multiple entries" do
350
+ encoded_data = "Obj\u0001\u0004\u0014avro.codec\bnull\u0016avro.schema\xB6\u0004[{\"type\": \"record\", \"name\": \"address\", \"fields\": [{\"type\": \"string\", \"name\": \"street\"}, {\"type\": \"string\", \"name\": \"city\"}]}, {\"type\": \"record\", \"name\": \"person\", \"fields\": [{\"type\": \"string\", \"name\": \"name\"}, {\"type\": \"int\", \"name\": \"age\"}, {\"type\": \"address\", \"name\": \"address\"}]}]\u0000\xF9u\x84\xA1c\u0010\x82B\xE2\xCF\xF1\x98\xF7\xF1JH\u0004\x96\u0001\u0002\u0014Python🐍\x80\u0004\u0018Green Street\u001ASan Francisco\u0002\u0010Mojo🐍\u0002\u0016Blue Street\u0014Saturn🪐\xF9u\x84\xA1c\u0010\x82B\xE2\xCF\xF1\x98\xF7\xF1JH"
351
+ stream = StringIO.new(encoded_data)
352
+
353
+ expect(avro.decode_all_from_stream(stream).entries).to eq(
354
+ [
355
+ {"name"=>"Python🐍", "age"=>256, "address"=>{"street"=>"Green Street", "city"=>"San Francisco"}},
356
+ {"name"=>"Mojo🐍", "age"=>1, "address"=>{"street"=>"Blue Street", "city"=>"Saturn🪐"}}
357
+ ]
358
+ )
359
+ end
360
+ end
361
+
307
362
  describe "#valid?" do
308
363
  before do
309
364
  define_schema "message.avsc", <<-AVSC
@@ -8,6 +8,7 @@ describe AvroTurf::ConfluentSchemaRegistry do
8
8
  let(:client_cert) { "test client cert" }
9
9
  let(:client_key) { "test client key" }
10
10
  let(:client_key_pass) { "test client key password" }
11
+ let(:connect_timeout) { 10 }
11
12
 
12
13
  it_behaves_like "a confluent schema registry client" do
13
14
  let(:registry) {
@@ -30,4 +31,15 @@ describe AvroTurf::ConfluentSchemaRegistry do
30
31
  )
31
32
  }
32
33
  end
34
+
35
+ it_behaves_like "a confluent schema registry client" do
36
+ let(:registry) {
37
+ described_class.new(
38
+ registry_url,
39
+ user: user,
40
+ password: password,
41
+ connect_timeout: connect_timeout
42
+ )
43
+ }
44
+ end
33
45
  end
@@ -425,4 +425,27 @@ describe AvroTurf::Messaging do
425
425
  it_behaves_like 'encoding and decoding with the schema from registry'
426
426
  it_behaves_like 'encoding and decoding with the schema_id from registry'
427
427
  end
428
- end
428
+
429
+ context 'with a connect timeout' do
430
+ let(:avro) {
431
+ AvroTurf::Messaging.new(
432
+ registry_url: registry_url,
433
+ schemas_path: "spec/schemas",
434
+ logger: logger,
435
+ client_cert: client_cert,
436
+ client_key: client_key,
437
+ client_key_pass: client_key_pass,
438
+ connect_timeout: 10
439
+ )
440
+ }
441
+
442
+ it_behaves_like "encoding and decoding with the schema from schema store"
443
+ it_behaves_like 'encoding and decoding with the schema from registry'
444
+ it_behaves_like 'encoding and decoding with the schema_id from registry'
445
+
446
+ it 'passes the connect timeout setting to Excon' do
447
+ expect(Excon).to receive(:new).with(anything, hash_including(connect_timeout: 10)).and_call_original
448
+ avro
449
+ end
450
+ end
451
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: avro_turf
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.10.0
4
+ version: 1.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Schierbeck
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-08-25 00:00:00.000000000 Z
11
+ date: 2023-09-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: avro
@@ -16,7 +16,7 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 1.7.7
19
+ version: 1.8.0
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
22
  version: '1.12'
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: 1.7.7
29
+ version: 1.8.0
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: '1.12'
@@ -156,7 +156,7 @@ dependencies:
156
156
  - - ">="
157
157
  - !ruby/object:Gem::Version
158
158
  version: '0'
159
- description:
159
+ description:
160
160
  email:
161
161
  - dasch@zendesk.com
162
162
  executables: []
@@ -251,8 +251,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
251
251
  - !ruby/object:Gem::Version
252
252
  version: '0'
253
253
  requirements: []
254
- rubygems_version: 3.0.3.1
255
- signing_key:
254
+ rubygems_version: 3.4.10
255
+ signing_key:
256
256
  specification_version: 4
257
257
  summary: A library that makes it easier to use the Avro serialization format from
258
258
  Ruby