avro_turf 1.17.0 → 1.19.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 +4 -4
- data/CHANGELOG.md +9 -0
- data/Gemfile +2 -0
- data/README.md +11 -2
- data/avro_turf.gemspec +1 -1
- data/lib/avro_turf/confluent_schema_registry.rb +24 -5
- data/lib/avro_turf/messaging.rb +10 -3
- data/lib/avro_turf/schema_store.rb +1 -1
- data/lib/avro_turf/version.rb +1 -1
- data/spec/messaging_spec.rb +64 -6
- data/spec/support/authorized_fake_confluent_schema_registry_server.rb +5 -0
- data/spec/support/authorized_fake_prefixed_confluent_schema_registry_server.rb +5 -0
- data/spec/support/confluent_schema_registry_context.rb +3 -3
- data/spec/test/fake_confluent_schema_registry_server_spec.rb +1 -2
- metadata +15 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fffcc17349a4bbbcaa1204610da74800c9a519d4774af83c7059c47bb75efb1b
|
4
|
+
data.tar.gz: e5afce0fa557da110a0dd1fe73add073f994a72bb8e3a1e37865a3393f864c2b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 06aac90715b06f0fdf04918ba73c2533a0cad0b9dff769e1bfc30a1488e0916fc3b38c8f4bee6efab5d667688bd9d407330c603f209ead30d67cb13b3b46c4a5
|
7
|
+
data.tar.gz: 1a3c95047a2522914394b181eaf01afaee84547d64a72d1aebe3534252f49168cebec0cf7edda8bc8a62f769dd22294eb3916d317a71a65305cb6c46ffba84ad
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
+
## v1.19.0
|
6
|
+
|
7
|
+
- Loosen excon dependency to allow 1.x (#220)
|
8
|
+
|
9
|
+
## v1.18.0
|
10
|
+
|
11
|
+
- Add `compatibility_issues` method to `ConfluentSchemaRegistry` to debug compatibility issues between a schema versions for a given subject (#212)
|
12
|
+
- Update tests to support `sinatra` version 4.1 that includes a new `host_authorization` parameter to permit only authorized requests
|
13
|
+
|
5
14
|
## v1.17.0
|
6
15
|
|
7
16
|
- Add `register_schemas` option to `encode` method [#210](https://github.com/dasch/avro_turf/pull/210)
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -254,6 +254,9 @@ registry = AvroTurf::ConfluentSchemaRegistry.new("http://my-registry:8081/")
|
|
254
254
|
|
255
255
|
# Returns true if the schema is compatible, nil if the subject or version is not registered, and false if incompatible.
|
256
256
|
registry.compatible?("person", schema)
|
257
|
+
|
258
|
+
# Returns an array of any breaking changes, nil if the subject or version is not registered
|
259
|
+
registry.compatibility_issues("person", schema)
|
257
260
|
```
|
258
261
|
|
259
262
|
The ConfluentSchemaRegistry client can also change the global compatibility level or the compatibility level for an individual subject using the [Config API](http://docs.confluent.io/3.1.2/schema-registry/docs/api.html#config):
|
@@ -270,17 +273,23 @@ fake schema registry server depends on Sinatra but it is _not_ listed as a runti
|
|
270
273
|
dependency for AvroTurf. Sinatra must be added to your Gemfile or gemspec in order
|
271
274
|
to use the fake server.
|
272
275
|
|
276
|
+
Given the recent update in `sinatra` to fix [CVE-2024-21510](https://github.com/advisories/GHSA-hxx2-7vcw-mqr3) that included a new `HostAuthorization` middleware, the `FakeConfluentSchemaRegistryServer` is provided as a base implementation that has to be inherited into a new class and configured by the user so requests are properly authorised to the test registry host.
|
277
|
+
|
273
278
|
Example using RSpec:
|
274
279
|
|
275
280
|
```ruby
|
276
281
|
require 'avro_turf/test/fake_confluent_schema_registry_server'
|
277
282
|
require 'webmock/rspec'
|
278
283
|
|
284
|
+
class AuthorizedFakeConfluentSchemaRegistryServer < FakeConfluentSchemaRegistryServer
|
285
|
+
set :host_authorization, permitted_hosts: ['registry.example.com']
|
286
|
+
end
|
287
|
+
|
279
288
|
# within an example
|
280
289
|
let(:registry_url) { "http://registry.example.com" }
|
281
290
|
before do
|
282
|
-
stub_request(:any, /^#{registry_url}/).to_rack(
|
283
|
-
|
291
|
+
stub_request(:any, /^#{registry_url}/).to_rack(AuthorizedFakeConfluentSchemaRegistryServer)
|
292
|
+
AuthorizedFakeConfluentSchemaRegistryServer.clear
|
284
293
|
end
|
285
294
|
|
286
295
|
# Messaging objects created with the same registry_url will now use the fake server.
|
data/avro_turf.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.require_paths = ["lib"]
|
21
21
|
|
22
22
|
spec.add_dependency "avro", ">= 1.11.3", "< 1.13"
|
23
|
-
spec.add_dependency "excon", "
|
23
|
+
spec.add_dependency "excon", ">= 0.104", "< 2"
|
24
24
|
|
25
25
|
spec.add_development_dependency "bundler", "~> 2.0"
|
26
26
|
spec.add_development_dependency "rake", "~> 13.0"
|
@@ -18,7 +18,8 @@ class AvroTurf::ConfluentSchemaRegistry
|
|
18
18
|
client_key_data: nil,
|
19
19
|
path_prefix: nil,
|
20
20
|
connect_timeout: nil,
|
21
|
-
resolv_resolver: nil
|
21
|
+
resolv_resolver: nil,
|
22
|
+
retry_limit: nil
|
22
23
|
)
|
23
24
|
@path_prefix = path_prefix
|
24
25
|
@schema_context_prefix = schema_context.nil? ? '' : ":.#{schema_context}:"
|
@@ -27,20 +28,26 @@ class AvroTurf::ConfluentSchemaRegistry
|
|
27
28
|
headers = Excon.defaults[:headers].merge(
|
28
29
|
"Content-Type" => CONTENT_TYPE
|
29
30
|
)
|
30
|
-
|
31
|
-
@connection = Excon.new(
|
32
|
-
url,
|
31
|
+
params = {
|
33
32
|
headers: headers,
|
34
33
|
user: user,
|
35
34
|
password: password,
|
35
|
+
proxy: proxy,
|
36
36
|
ssl_ca_file: ssl_ca_file,
|
37
37
|
client_cert: client_cert,
|
38
38
|
client_key: client_key,
|
39
39
|
client_key_pass: client_key_pass,
|
40
40
|
client_cert_data: client_cert_data,
|
41
41
|
client_key_data: client_key_data,
|
42
|
+
resolv_resolver: resolv_resolver,
|
42
43
|
connect_timeout: connect_timeout,
|
43
|
-
|
44
|
+
retry_limit: retry_limit
|
45
|
+
}
|
46
|
+
# Remove nil params to allow Excon to use its default values
|
47
|
+
params.reject! { |_, v| v.nil? }
|
48
|
+
@connection = Excon.new(
|
49
|
+
url,
|
50
|
+
params
|
44
51
|
)
|
45
52
|
end
|
46
53
|
|
@@ -101,6 +108,18 @@ class AvroTurf::ConfluentSchemaRegistry
|
|
101
108
|
data.fetch('is_compatible', false) unless data.has_key?('error_code')
|
102
109
|
end
|
103
110
|
|
111
|
+
# Check for specific schema compatibility issues
|
112
|
+
# Returns:
|
113
|
+
# - nil if the subject or version does not exist
|
114
|
+
# - a list of compatibility issues
|
115
|
+
# https://docs.confluent.io/platform/current/schema-registry/develop/api.html#sr-api-compatibility
|
116
|
+
def compatibility_issues(subject, schema, version = 'latest')
|
117
|
+
data = post("/compatibility/subjects/#{@schema_context_prefix}#{subject}/versions/#{version}",
|
118
|
+
expects: [200, 404], body: { schema: schema.to_s }.to_json, query: { verbose: true }, idempotent: true)
|
119
|
+
|
120
|
+
data.fetch('messages', []) unless data.has_key?('error_code')
|
121
|
+
end
|
122
|
+
|
104
123
|
# Get global config
|
105
124
|
def global_config
|
106
125
|
get("/config", idempotent: true)
|
data/lib/avro_turf/messaging.rb
CHANGED
@@ -10,6 +10,7 @@ require 'avro_turf/schema_registry'
|
|
10
10
|
require 'avro_turf/cached_schema_registry'
|
11
11
|
|
12
12
|
class AvroTurf
|
13
|
+
class IncompatibleSchemaError < StandardError; end
|
13
14
|
|
14
15
|
# Provides a way to encode and decode messages without having to embed schemas
|
15
16
|
# in the encoded data. Confluent's Schema Registry[1] is used to register
|
@@ -77,7 +78,8 @@ class AvroTurf
|
|
77
78
|
client_cert_data: nil,
|
78
79
|
client_key_data: nil,
|
79
80
|
connect_timeout: nil,
|
80
|
-
resolv_resolver: nil
|
81
|
+
resolv_resolver: nil,
|
82
|
+
retry_limit: nil
|
81
83
|
)
|
82
84
|
@logger = logger || Logger.new($stderr)
|
83
85
|
@namespace = namespace
|
@@ -98,7 +100,8 @@ class AvroTurf
|
|
98
100
|
client_key_data: client_key_data,
|
99
101
|
path_prefix: registry_path_prefix,
|
100
102
|
connect_timeout: connect_timeout,
|
101
|
-
resolv_resolver: resolv_resolver
|
103
|
+
resolv_resolver: resolv_resolver,
|
104
|
+
retry_limit: retry_limit
|
102
105
|
)
|
103
106
|
)
|
104
107
|
@schemas_by_id = {}
|
@@ -216,11 +219,15 @@ class AvroTurf
|
|
216
219
|
end
|
217
220
|
|
218
221
|
# Providing subject and version to determine the schema,
|
219
|
-
# which skips the auto
|
222
|
+
# which skips the auto registration of schema on the schema registry.
|
220
223
|
# Fetch the schema from registry with the provided subject name and version.
|
221
224
|
def fetch_schema(subject:, version: 'latest')
|
222
225
|
schema_data = @registry.subject_version(subject, version)
|
223
226
|
schema_id = schema_data.fetch('id')
|
227
|
+
schema_type = schema_data['schemaType']
|
228
|
+
if schema_type && schema_type != "AVRO"
|
229
|
+
raise IncompatibleSchemaError, "The #{schema_type} schema for #{subject} is incompatible."
|
230
|
+
end
|
224
231
|
schema = Avro::Schema.parse(schema_data.fetch('schema'))
|
225
232
|
[schema, schema_id]
|
226
233
|
end
|
data/lib/avro_turf/version.rb
CHANGED
data/spec/messaging_spec.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
require 'webmock/rspec'
|
2
2
|
require 'avro_turf/messaging'
|
3
|
-
require 'avro_turf/test/fake_confluent_schema_registry_server'
|
4
|
-
require 'avro_turf/test/fake_prefixed_confluent_schema_registry_server'
|
5
3
|
|
6
4
|
describe AvroTurf::Messaging do
|
7
5
|
let(:registry_url) { "http://registry.example.com" }
|
@@ -61,8 +59,8 @@ describe AvroTurf::Messaging do
|
|
61
59
|
end
|
62
60
|
|
63
61
|
before do
|
64
|
-
stub_request(:any, /^#{registry_url}/).to_rack(
|
65
|
-
|
62
|
+
stub_request(:any, /^#{registry_url}/).to_rack(AuthorizedFakeConfluentSchemaRegistryServer)
|
63
|
+
AuthorizedFakeConfluentSchemaRegistryServer.clear
|
66
64
|
end
|
67
65
|
|
68
66
|
before do
|
@@ -379,6 +377,18 @@ describe AvroTurf::Messaging do
|
|
379
377
|
it 'gets schema from registry' do
|
380
378
|
expect(subject).to eq([schema, schema_id])
|
381
379
|
end
|
380
|
+
|
381
|
+
context "with an incompatible schema type" do
|
382
|
+
let(:response) { {'id' => schema_id, 'schema' => 'blah', 'schemaType' => schema_type } }
|
383
|
+
let(:schema_type) { 'PROTOBUF' }
|
384
|
+
|
385
|
+
it 'raises IncompatibleSchemaError' do
|
386
|
+
expect { subject }.to raise_error(
|
387
|
+
AvroTurf::IncompatibleSchemaError,
|
388
|
+
"The #{schema_type} schema for #{subj} is incompatible."
|
389
|
+
)
|
390
|
+
end
|
391
|
+
end
|
382
392
|
end
|
383
393
|
|
384
394
|
context 'using fetch_schema_by_id' do
|
@@ -474,8 +484,8 @@ describe AvroTurf::Messaging do
|
|
474
484
|
}
|
475
485
|
|
476
486
|
before do
|
477
|
-
stub_request(:any, /^#{registry_url}/).to_rack(
|
478
|
-
|
487
|
+
stub_request(:any, /^#{registry_url}/).to_rack(AuthorizedFakePrefixedConfluentSchemaRegistryServer)
|
488
|
+
AuthorizedFakePrefixedConfluentSchemaRegistryServer.clear
|
479
489
|
end
|
480
490
|
|
481
491
|
it_behaves_like "encoding and decoding with the schema from schema store"
|
@@ -506,6 +516,54 @@ describe AvroTurf::Messaging do
|
|
506
516
|
end
|
507
517
|
end
|
508
518
|
|
519
|
+
context 'with a connect timeout' do
|
520
|
+
let(:avro) {
|
521
|
+
AvroTurf::Messaging.new(
|
522
|
+
registry_url: registry_url,
|
523
|
+
schemas_path: "spec/schemas",
|
524
|
+
logger: logger,
|
525
|
+
client_cert: client_cert,
|
526
|
+
client_key: client_key,
|
527
|
+
client_key_pass: client_key_pass,
|
528
|
+
retry_limit: 5
|
529
|
+
)
|
530
|
+
}
|
531
|
+
|
532
|
+
it_behaves_like "encoding and decoding with the schema from schema store"
|
533
|
+
it_behaves_like 'encoding and decoding with the schema from registry'
|
534
|
+
it_behaves_like 'encoding and decoding with the schema_id from registry'
|
535
|
+
|
536
|
+
it 'passes the connect timeout setting to Excon' do
|
537
|
+
expect(Excon).to receive(:new).with(anything, hash_including(retry_limit: 5)).and_call_original
|
538
|
+
avro
|
539
|
+
end
|
540
|
+
end
|
541
|
+
|
542
|
+
context 'with a proxy' do
|
543
|
+
let(:proxy_url) { 'http://proxy.example.com' }
|
544
|
+
let(:avro) {
|
545
|
+
AvroTurf::Messaging.new(
|
546
|
+
registry_url: registry_url,
|
547
|
+
schemas_path: "spec/schemas",
|
548
|
+
logger: logger,
|
549
|
+
client_cert: client_cert,
|
550
|
+
client_key: client_key,
|
551
|
+
client_key_pass: client_key_pass,
|
552
|
+
proxy: proxy_url
|
553
|
+
)
|
554
|
+
}
|
555
|
+
|
556
|
+
it_behaves_like "encoding and decoding with the schema from schema store"
|
557
|
+
it_behaves_like 'encoding and decoding with the schema from registry'
|
558
|
+
it_behaves_like 'encoding and decoding with the schema_id from registry'
|
559
|
+
|
560
|
+
it 'passes the proxy setting to Excon' do
|
561
|
+
expect(Excon).to receive(:new).with(anything, hash_including(proxy: proxy_url)).and_call_original
|
562
|
+
avro
|
563
|
+
end
|
564
|
+
end
|
565
|
+
|
566
|
+
|
509
567
|
context 'with a custom domain name resolver' do
|
510
568
|
let(:resolv_resolver) { Resolv.new([Resolv::Hosts.new, Resolv::DNS.new(nameserver: ['127.0.0.1', '127.0.0.1'])]) }
|
511
569
|
let(:avro) {
|
@@ -18,7 +18,7 @@ shared_examples_for "a confluent schema registry client" do |schema_context: nil
|
|
18
18
|
{
|
19
19
|
'Accept'=>'*/*',
|
20
20
|
'Content-Type'=> AvroTurf::ConfluentSchemaRegistry::CONTENT_TYPE,
|
21
|
-
'Host'=> "#{URI.parse(registry_url).host}
|
21
|
+
'Host'=> "#{URI.parse(registry_url).host}",
|
22
22
|
'User-Agent'=> "excon/#{Excon::VERSION}"
|
23
23
|
}
|
24
24
|
end
|
@@ -26,9 +26,9 @@ shared_examples_for "a confluent schema registry client" do |schema_context: nil
|
|
26
26
|
before do
|
27
27
|
stub_request(:any, /^#{registry_url}/)
|
28
28
|
.with(headers: headers)
|
29
|
-
.to_rack(
|
29
|
+
.to_rack(AuthorizedFakeConfluentSchemaRegistryServer)
|
30
30
|
|
31
|
-
|
31
|
+
AuthorizedFakeConfluentSchemaRegistryServer.clear
|
32
32
|
end
|
33
33
|
|
34
34
|
describe "#register and #fetch" do
|
@@ -1,10 +1,9 @@
|
|
1
1
|
require 'rack/test'
|
2
|
-
require 'avro_turf/test/fake_confluent_schema_registry_server'
|
3
2
|
|
4
3
|
describe FakeConfluentSchemaRegistryServer do
|
5
4
|
include Rack::Test::Methods
|
6
5
|
|
7
|
-
def app;
|
6
|
+
def app; AuthorizedFakeConfluentSchemaRegistryServer; end
|
8
7
|
|
9
8
|
describe 'POST /subjects/:subject/versions' do
|
10
9
|
it 'returns the same schema ID when invoked with same schema and same subject' do
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: avro_turf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.19.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Schierbeck
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: avro
|
@@ -34,16 +33,22 @@ dependencies:
|
|
34
33
|
name: excon
|
35
34
|
requirement: !ruby/object:Gem::Requirement
|
36
35
|
requirements:
|
37
|
-
- - "
|
36
|
+
- - ">="
|
38
37
|
- !ruby/object:Gem::Version
|
39
38
|
version: '0.104'
|
39
|
+
- - "<"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '2'
|
40
42
|
type: :runtime
|
41
43
|
prerelease: false
|
42
44
|
version_requirements: !ruby/object:Gem::Requirement
|
43
45
|
requirements:
|
44
|
-
- - "
|
46
|
+
- - ">="
|
45
47
|
- !ruby/object:Gem::Version
|
46
48
|
version: '0.104'
|
49
|
+
- - "<"
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '2'
|
47
52
|
- !ruby/object:Gem::Dependency
|
48
53
|
name: bundler
|
49
54
|
requirement: !ruby/object:Gem::Requirement
|
@@ -170,7 +175,6 @@ dependencies:
|
|
170
175
|
- - ">="
|
171
176
|
- !ruby/object:Gem::Version
|
172
177
|
version: '0'
|
173
|
-
description:
|
174
178
|
email:
|
175
179
|
- dasch@zendesk.com
|
176
180
|
executables: []
|
@@ -236,6 +240,8 @@ files:
|
|
236
240
|
- spec/schema_store_spec.rb
|
237
241
|
- spec/schema_to_avro_patch_spec.rb
|
238
242
|
- spec/spec_helper.rb
|
243
|
+
- spec/support/authorized_fake_confluent_schema_registry_server.rb
|
244
|
+
- spec/support/authorized_fake_prefixed_confluent_schema_registry_server.rb
|
239
245
|
- spec/support/confluent_schema_registry_context.rb
|
240
246
|
- spec/test/fake_confluent_schema_registry_server_spec.rb
|
241
247
|
homepage: https://github.com/dasch/avro_turf
|
@@ -266,8 +272,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
266
272
|
- !ruby/object:Gem::Version
|
267
273
|
version: '0'
|
268
274
|
requirements: []
|
269
|
-
rubygems_version: 3.
|
270
|
-
signing_key:
|
275
|
+
rubygems_version: 3.6.9
|
271
276
|
specification_version: 4
|
272
277
|
summary: A library that makes it easier to use the Avro serialization format from
|
273
278
|
Ruby
|
@@ -290,5 +295,7 @@ test_files:
|
|
290
295
|
- spec/schema_store_spec.rb
|
291
296
|
- spec/schema_to_avro_patch_spec.rb
|
292
297
|
- spec/spec_helper.rb
|
298
|
+
- spec/support/authorized_fake_confluent_schema_registry_server.rb
|
299
|
+
- spec/support/authorized_fake_prefixed_confluent_schema_registry_server.rb
|
293
300
|
- spec/support/confluent_schema_registry_context.rb
|
294
301
|
- spec/test/fake_confluent_schema_registry_server_spec.rb
|