avro_turf 1.9.0 → 1.10.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 +5 -0
- data/lib/avro_turf/cached_confluent_schema_registry.rb +1 -1
- data/lib/avro_turf/confluent_schema_registry.rb +5 -0
- data/lib/avro_turf/schema_store.rb +1 -1
- data/lib/avro_turf/test/fake_confluent_schema_registry_server.rb +22 -10
- data/lib/avro_turf/version.rb +1 -1
- data/spec/messaging_spec.rb +2 -2
- data/spec/schema_store_spec.rb +43 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/support/confluent_schema_registry_context.rb +27 -0
- data/spec/test/fake_confluent_schema_registry_server_spec.rb +63 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0907531d40226b59cd545baf7341f3e41613565d50de98684b266b6b33a081f
|
4
|
+
data.tar.gz: e472794d6e7ecbd4a32b1a08f4cc0eb6b0ae810d849483d86ab16a7da929a9fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ac1324149cb3299c3e67ffbd287879da88a09c338b967e2098fed63836c9fba5f775623ee6d6ae2ac0ac5e6f6a4ad28ea4c7bb7ece2d1e5979cee2eb379ac43a
|
7
|
+
data.tar.gz: 84709d06f4b3d97a23c1f0a1b94f4757c8b7024d17354ec65c7068be8cca52cdeed832096d7ea43f646d3f52d09ebd0f2286375456503d9da14cf6cb7a37772b
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,11 @@
|
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
+
## v1.10.0
|
6
|
+
|
7
|
+
- Add `schema_subject_versions` to `ConfluentSchemaRegistry` to retrieve all subject versions for a schema id. (#189)
|
8
|
+
- `FakeConfluentSchemaRegistryServer` now returns same id if identical schema is created for a different subject (#188)
|
9
|
+
|
5
10
|
## v1.9.0
|
6
11
|
|
7
12
|
- Send Accept and User-Agent headers on every request (#184)
|
@@ -17,7 +17,7 @@ class AvroTurf::CachedConfluentSchemaRegistry
|
|
17
17
|
end
|
18
18
|
|
19
19
|
# Delegate the following methods to the upstream
|
20
|
-
%i(subjects subject_versions check compatible?
|
20
|
+
%i(subjects subject_versions schema_subject_versions check compatible?
|
21
21
|
global_config update_global_config subject_config update_subject_config).each do |name|
|
22
22
|
define_method(name) do |*args|
|
23
23
|
instance_variable_get(:@upstream).send(name, *args)
|
@@ -68,6 +68,11 @@ class AvroTurf::ConfluentSchemaRegistry
|
|
68
68
|
get("/subjects/#{subject}/versions/#{version}")
|
69
69
|
end
|
70
70
|
|
71
|
+
# Get the subject and version for a schema id
|
72
|
+
def schema_subject_versions(schema_id)
|
73
|
+
get("/schemas/ids/#{schema_id}/versions")
|
74
|
+
end
|
75
|
+
|
71
76
|
# Check if a schema exists. Returns nil if not found.
|
72
77
|
def check(subject, schema)
|
73
78
|
data = post("/subjects/#{subject}",
|
@@ -35,23 +35,35 @@ class FakeConfluentSchemaRegistryServer < Sinatra::Base
|
|
35
35
|
|
36
36
|
post "/subjects/:subject/versions" do
|
37
37
|
schema = parse_schema
|
38
|
-
|
39
|
-
|
40
|
-
schemas_for_subject =
|
41
|
-
SCHEMAS.select
|
42
|
-
.with_index { |_, i| ids_for_subject.include?(i) }
|
43
|
-
|
44
|
-
if schemas_for_subject.include?(schema)
|
45
|
-
schema_id = SCHEMAS.index(schema)
|
46
|
-
else
|
38
|
+
schema_id = SCHEMAS.index(schema)
|
39
|
+
if schema_id.nil?
|
47
40
|
SCHEMAS << schema
|
48
41
|
schema_id = SCHEMAS.size - 1
|
49
|
-
|
42
|
+
end
|
43
|
+
|
44
|
+
subject = params[:subject]
|
45
|
+
unless SUBJECTS[subject].include?(schema_id)
|
46
|
+
SUBJECTS[subject] = SUBJECTS[subject] << schema_id
|
50
47
|
end
|
51
48
|
|
52
49
|
{ id: schema_id }.to_json
|
53
50
|
end
|
54
51
|
|
52
|
+
get "/schemas/ids/:schema_id/versions" do
|
53
|
+
schema_id = params[:schema_id].to_i
|
54
|
+
schema = SCHEMAS.at(schema_id)
|
55
|
+
halt(404, SCHEMA_NOT_FOUND) unless schema
|
56
|
+
|
57
|
+
related_subjects = SUBJECTS.select {|_, vs| vs.include? schema_id }
|
58
|
+
|
59
|
+
related_subjects.map do |subject, versions|
|
60
|
+
{
|
61
|
+
subject: subject,
|
62
|
+
version: versions.find_index(schema_id) + 1
|
63
|
+
}
|
64
|
+
end.to_json
|
65
|
+
end
|
66
|
+
|
55
67
|
get "/schemas/ids/:schema_id" do
|
56
68
|
schema = SCHEMAS.at(params[:schema_id].to_i)
|
57
69
|
halt(404, SCHEMA_NOT_FOUND) unless schema
|
data/lib/avro_turf/version.rb
CHANGED
data/spec/messaging_spec.rb
CHANGED
@@ -109,7 +109,7 @@ describe AvroTurf::Messaging do
|
|
109
109
|
end
|
110
110
|
|
111
111
|
it 'encodes and decodes messages' do
|
112
|
-
data = avro.encode(message, schema_id:
|
112
|
+
data = avro.encode(message, schema_id: 0)
|
113
113
|
expect(avro.decode(data)).to eq message
|
114
114
|
end
|
115
115
|
|
@@ -118,7 +118,7 @@ describe AvroTurf::Messaging do
|
|
118
118
|
end
|
119
119
|
|
120
120
|
it 'caches parsed schemas for decoding' do
|
121
|
-
data = avro.encode(message, schema_id:
|
121
|
+
data = avro.encode(message, schema_id: 0)
|
122
122
|
avro.decode(data)
|
123
123
|
allow(Avro::Schema).to receive(:parse).and_call_original
|
124
124
|
expect(avro.decode(data)).to eq message
|
data/spec/schema_store_spec.rb
CHANGED
@@ -361,6 +361,49 @@ describe AvroTurf::SchemaStore do
|
|
361
361
|
end
|
362
362
|
|
363
363
|
describe "#load_schemas!" do
|
364
|
+
it "do not try to reload known schemas" do
|
365
|
+
define_schema "first.avsc", <<-AVSC
|
366
|
+
{
|
367
|
+
"name": "first",
|
368
|
+
"type": "record",
|
369
|
+
"fields": [
|
370
|
+
{
|
371
|
+
"type": "string",
|
372
|
+
"name": "a_value"
|
373
|
+
}
|
374
|
+
]
|
375
|
+
}
|
376
|
+
AVSC
|
377
|
+
|
378
|
+
define_schema "second.avsc", <<-AVSC
|
379
|
+
{
|
380
|
+
"name": "second",
|
381
|
+
"type": "record",
|
382
|
+
"fields": [
|
383
|
+
{
|
384
|
+
"type": "first",
|
385
|
+
"name": "full_name"
|
386
|
+
}
|
387
|
+
]
|
388
|
+
}
|
389
|
+
AVSC
|
390
|
+
|
391
|
+
define_schema "third.avsc", <<-AVSC
|
392
|
+
{
|
393
|
+
"name": "third",
|
394
|
+
"type": "record",
|
395
|
+
"fields": [
|
396
|
+
{
|
397
|
+
"type": "second",
|
398
|
+
"name": "embedded_first"
|
399
|
+
}
|
400
|
+
]
|
401
|
+
}
|
402
|
+
AVSC
|
403
|
+
|
404
|
+
expect { store.load_schemas! }.not_to raise_error
|
405
|
+
end
|
406
|
+
|
364
407
|
it "loads schemas defined in the `schemas_path` directory" do
|
365
408
|
define_schema "person.avsc", <<-AVSC
|
366
409
|
{
|
data/spec/spec_helper.rb
CHANGED
@@ -77,6 +77,33 @@ shared_examples_for "a confluent schema registry client" do
|
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
80
|
+
describe "#schema_subject_versions" do
|
81
|
+
it "returns subject and version for a schema id" do
|
82
|
+
schema_id1 = registry.register(subject_name, { type: :record, name: "r1", fields: [] }.to_json)
|
83
|
+
registry.register(subject_name, { type: :record, name: "r2", fields: [] }.to_json)
|
84
|
+
schema_id2 = registry.register("other#{subject_name}", { type: :record, name: "r2", fields: [] }.to_json)
|
85
|
+
expect(registry.schema_subject_versions(schema_id1)).to eq([
|
86
|
+
'subject' => subject_name,
|
87
|
+
'version' => 1
|
88
|
+
])
|
89
|
+
expect(registry.schema_subject_versions(schema_id2)).to include({
|
90
|
+
'subject' => subject_name,
|
91
|
+
'version' => 2
|
92
|
+
},{
|
93
|
+
'subject' => "other#{subject_name}",
|
94
|
+
'version' => 1
|
95
|
+
} )
|
96
|
+
end
|
97
|
+
|
98
|
+
context "when the schema does not exist" do
|
99
|
+
it "raises an error" do
|
100
|
+
expect do
|
101
|
+
registry.schema_subject_versions(-1)
|
102
|
+
end.to raise_error(Excon::Errors::NotFound)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
80
107
|
describe "#subject_versions" do
|
81
108
|
it "lists all the versions for the subject" do
|
82
109
|
2.times do |n|
|
@@ -27,14 +27,75 @@ describe FakeConfluentSchemaRegistryServer do
|
|
27
27
|
expect(JSON.parse(last_response.body).fetch('id')).to eq expected_id
|
28
28
|
end
|
29
29
|
|
30
|
-
it 'returns
|
30
|
+
it 'returns the same schema ID when invoked with same schema and different subject' do
|
31
31
|
post '/subjects/person/versions', { schema: schema }.to_json, 'CONTENT_TYPE' => 'application/vnd.schemaregistry+json'
|
32
32
|
|
33
33
|
original_id = JSON.parse(last_response.body).fetch('id')
|
34
34
|
|
35
35
|
post '/subjects/happy-person/versions', { schema: schema }.to_json, 'CONTENT_TYPE' => 'application/vnd.schemaregistry+json'
|
36
36
|
|
37
|
-
expect(JSON.parse(last_response.body).fetch('id')).
|
37
|
+
expect(JSON.parse(last_response.body).fetch('id')).to eq original_id
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'returns a different schema ID when invoked with a different schema' do
|
41
|
+
post '/subjects/person/versions', { schema: schema }.to_json, 'CONTENT_TYPE' => 'application/vnd.schemaregistry+json'
|
42
|
+
|
43
|
+
original_id = JSON.parse(last_response.body).fetch('id')
|
44
|
+
|
45
|
+
other_schema = {
|
46
|
+
type: "record",
|
47
|
+
name: "other",
|
48
|
+
fields: [
|
49
|
+
{ name: "name", type: "string" }
|
50
|
+
]
|
51
|
+
}.to_json
|
52
|
+
|
53
|
+
post '/subjects/person/versions', { schema: other_schema }.to_json, 'CONTENT_TYPE' => 'application/vnd.schemaregistry+json'
|
54
|
+
|
55
|
+
expect(JSON.parse(last_response.body).fetch('id')).to_not eq original_id
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe 'GET /schemas/ids/:id/versions' do
|
60
|
+
def schema(name:)
|
61
|
+
{
|
62
|
+
type: "record",
|
63
|
+
name: name,
|
64
|
+
fields: [
|
65
|
+
{ name: "name", type: "string" },
|
66
|
+
]
|
67
|
+
}.to_json
|
68
|
+
end
|
69
|
+
|
70
|
+
it "returns array containing subjects and versions for given schema id" do
|
71
|
+
schema1 = schema(name: "name1")
|
72
|
+
schema2 = schema(name: "name2")
|
73
|
+
|
74
|
+
post "/subjects/cats/versions", { schema: schema1 }.to_json, 'CONTENT_TYPE' => 'application/vnd.schemaregistry+json'
|
75
|
+
schema1_id = JSON.parse(last_response.body).fetch('id') # Original cats schema
|
76
|
+
|
77
|
+
post "/subjects/dogs/versions", { schema: schema2 }.to_json, 'CONTENT_TYPE' => 'application/vnd.schemaregistry+json'
|
78
|
+
post "/subjects/cats/versions", { schema: schema2 }.to_json, 'CONTENT_TYPE' => 'application/vnd.schemaregistry+json'
|
79
|
+
schema2_id = JSON.parse(last_response.body).fetch('id') # Changed cats schema == Original Dogs schema
|
80
|
+
|
81
|
+
get "/schemas/ids/#{schema1_id}/versions"
|
82
|
+
result = JSON.parse(last_response.body)
|
83
|
+
|
84
|
+
expect(result).to eq [{
|
85
|
+
'subject' => 'cats',
|
86
|
+
'version' => 1
|
87
|
+
}]
|
88
|
+
|
89
|
+
get "/schemas/ids/#{schema2_id}/versions"
|
90
|
+
result = JSON.parse(last_response.body)
|
91
|
+
|
92
|
+
expect(result).to include( {
|
93
|
+
'subject' => 'cats',
|
94
|
+
'version' => 2
|
95
|
+
}, {
|
96
|
+
'subject' => 'dogs',
|
97
|
+
'version' => 1
|
98
|
+
})
|
38
99
|
end
|
39
100
|
end
|
40
101
|
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.
|
4
|
+
version: 1.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Schierbeck
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-08-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: avro
|