schema_registry_client 0.0.11 → 0.1.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/.github/workflows/test.yml +1 -1
- data/CHANGELOG.md +4 -0
- data/Gemfile.lock +1 -1
- data/lib/schema_registry_client/avro_schema_store.rb +0 -7
- data/lib/schema_registry_client/schema/avro.rb +4 -1
- data/lib/schema_registry_client/version.rb +1 -1
- data/schema_registry_client.gemspec +1 -1
- data/spec/encoding_spec.rb +31 -6
- data/spec/schemas/cross_file/v1/Inner.avsc +11 -0
- data/spec/schemas/cross_file/v1/Outer.avsc +11 -0
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ade8a75ca2eb7bacb07566bd5eaa2899bfd69c2ed34dd7c1bc7e186b531b055e
|
|
4
|
+
data.tar.gz: 17174e9182ce1f875006bbe302f8ad7cc9809af3d415e2a9500ccfda114ec95d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4ccea73cc7df695421518ad82de2507950d7d6e300146d5210c982addea11396ad4b4ee154f58ed38aa81891a13df20b5e60f50e84a74d74e7f6cd86c39aa1cb
|
|
7
|
+
data.tar.gz: 0daa9b8085d05991b1be936e8ce0aa209ab0973a05103a8dc8368e394988ec52ef7066110d912542b891342e2842b92b4e7e24d29b8d597a3a39d315d1b8d0bc
|
data/.github/workflows/test.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## UNRELEASED
|
|
9
9
|
|
|
10
|
+
# 0.1.0 - 2026-06-24
|
|
11
|
+
|
|
12
|
+
* Avro: register the fully-resolved (inlined) schema so schemas that reference named types defined in other `.avsc` files are valid standalone.
|
|
13
|
+
|
|
10
14
|
# 0.0.11 - 2026-02-20
|
|
11
15
|
|
|
12
16
|
* Fixes for caching working correctly and ensuring we don't recalculate / re-parse Avro schemas
|
data/Gemfile.lock
CHANGED
|
@@ -7,16 +7,11 @@ module SchemaRegistry
|
|
|
7
7
|
def initialize(path: nil)
|
|
8
8
|
@path = path or raise "Please specify a schema path"
|
|
9
9
|
@schemas = {}
|
|
10
|
-
@schema_text = {}
|
|
11
10
|
@mutex = Mutex.new
|
|
12
11
|
end
|
|
13
12
|
|
|
14
13
|
attr_accessor :schemas
|
|
15
14
|
|
|
16
|
-
def find_text(name)
|
|
17
|
-
@schema_text[name]
|
|
18
|
-
end
|
|
19
|
-
|
|
20
15
|
# Resolves and returns a schema.
|
|
21
16
|
#
|
|
22
17
|
# schema_name - The String name of the schema to resolve.
|
|
@@ -64,7 +59,6 @@ module SchemaRegistry
|
|
|
64
59
|
# we will discard it.
|
|
65
60
|
schema = Avro::Schema.real_parse(schema_hash, @schemas.dup)
|
|
66
61
|
@schemas[full_name] = schema
|
|
67
|
-
@schema_text[full_name] = JSON.pretty_generate(schema_hash)
|
|
68
62
|
|
|
69
63
|
schema
|
|
70
64
|
end
|
|
@@ -96,7 +90,6 @@ module SchemaRegistry
|
|
|
96
90
|
# Essentially, the only schemas that should be resolvable in @schemas
|
|
97
91
|
# are those that have their own .avsc files on disk.
|
|
98
92
|
@schemas[fullname] = schema
|
|
99
|
-
@schema_text[fullname] = schema_text
|
|
100
93
|
|
|
101
94
|
schema
|
|
102
95
|
rescue ::Avro::UnknownSchemaError => e
|
|
@@ -29,8 +29,11 @@ module SchemaRegistry
|
|
|
29
29
|
@schema_store
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
+
# Register the fully-resolved (inlined) schema. The raw .avsc text is not a
|
|
33
|
+
# valid standalone schema when it references a type defined in another file.
|
|
32
34
|
def schema_text(_message, schema_name: nil)
|
|
33
|
-
|
|
35
|
+
@registration_text ||= {}
|
|
36
|
+
@registration_text[schema_name] ||= schema_store.find(schema_name).to_avro.to_json
|
|
34
37
|
end
|
|
35
38
|
|
|
36
39
|
def encode(message, stream, schema_name: nil)
|
|
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
|
12
12
|
spec.summary = "Confluent Schema Registry client with support for Avro and Protobuf"
|
|
13
13
|
spec.homepage = "https://github.com/flipp-oss/schema_registry_client"
|
|
14
14
|
spec.license = "MIT"
|
|
15
|
-
spec.required_ruby_version = ">= 3.
|
|
15
|
+
spec.required_ruby_version = ">= 3.2"
|
|
16
16
|
|
|
17
17
|
spec.metadata["rubygems_mfa_required"] = "true"
|
|
18
18
|
|
data/spec/encoding_spec.rb
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
RSpec.describe "encoding" do
|
|
4
|
+
def avro_registration_text(raw)
|
|
5
|
+
Avro::Schema.parse(raw).to_avro.to_json
|
|
6
|
+
end
|
|
7
|
+
|
|
4
8
|
let(:schema_registry_client) do
|
|
5
9
|
SchemaRegistry::Client.new(
|
|
6
10
|
registry_url: "http://localhost:8081"
|
|
@@ -116,7 +120,7 @@ RSpec.describe "encoding" do
|
|
|
116
120
|
end
|
|
117
121
|
|
|
118
122
|
it "should encode a simple message" do
|
|
119
|
-
schema = File.read("#{__dir__}/schemas/simple/v1/SimpleMessage.avsc")
|
|
123
|
+
schema = avro_registration_text(File.read("#{__dir__}/schemas/simple/v1/SimpleMessage.avsc"))
|
|
120
124
|
stub = stub_request(:post, "http://localhost:8081/subjects/simple/versions")
|
|
121
125
|
.with(body: {"schema" => schema}).to_return_json(body: {id: 15})
|
|
122
126
|
msg = {"name" => "my name"}
|
|
@@ -133,7 +137,7 @@ RSpec.describe "encoding" do
|
|
|
133
137
|
end
|
|
134
138
|
|
|
135
139
|
it "should encode a complex message with nested record" do
|
|
136
|
-
schema = File.read("#{__dir__}/schemas/referenced/v1/MessageBA.avsc")
|
|
140
|
+
schema = avro_registration_text(File.read("#{__dir__}/schemas/referenced/v1/MessageBA.avsc"))
|
|
137
141
|
stub = stub_request(:post, "http://localhost:8081/subjects/referenced/versions")
|
|
138
142
|
.with(body: {"schema" => schema}).to_return_json(body: {id: 20})
|
|
139
143
|
msg = {
|
|
@@ -169,7 +173,7 @@ RSpec.describe "encoding" do
|
|
|
169
173
|
File.write("#{multi_schema_path}/MultiFieldMessage.avsc", schema_json)
|
|
170
174
|
|
|
171
175
|
stub = stub_request(:post, "http://localhost:8081/subjects/multi/versions")
|
|
172
|
-
.with(body: {"schema" => schema_json}).to_return_json(body: {id: 25})
|
|
176
|
+
.with(body: {"schema" => avro_registration_text(schema_json)}).to_return_json(body: {id: 25})
|
|
173
177
|
|
|
174
178
|
msg = {"name" => "Alice", "age" => 30}
|
|
175
179
|
encoded = schema_registry_client.encode(msg, subject: "multi", schema_name: "test.v1.MultiFieldMessage")
|
|
@@ -185,7 +189,7 @@ RSpec.describe "encoding" do
|
|
|
185
189
|
end
|
|
186
190
|
|
|
187
191
|
it "should validate schema before encoding" do
|
|
188
|
-
schema = File.read("#{__dir__}/schemas/simple/v1/SimpleMessage.avsc")
|
|
192
|
+
schema = avro_registration_text(File.read("#{__dir__}/schemas/simple/v1/SimpleMessage.avsc"))
|
|
189
193
|
stub_request(:post, "http://localhost:8081/subjects/simple/versions")
|
|
190
194
|
.with(body: {"schema" => schema}).to_return_json(body: {id: 15})
|
|
191
195
|
|
|
@@ -196,6 +200,27 @@ RSpec.describe "encoding" do
|
|
|
196
200
|
schema_registry_client.encode(msg, subject: "simple", schema_name: "simple.v1.SimpleMessage")
|
|
197
201
|
end.to raise_error(Avro::SchemaValidator::ValidationError)
|
|
198
202
|
end
|
|
203
|
+
|
|
204
|
+
it "registers a self-contained schema when the .avsc references another file" do
|
|
205
|
+
# cross_file.v1.Outer references cross_file.v1.Inner, which is defined in a
|
|
206
|
+
# *separate* .avsc file, so the raw Outer.avsc text is not a valid
|
|
207
|
+
# standalone Avro schema...
|
|
208
|
+
raw = File.read("#{__dir__}/schemas/cross_file/v1/Outer.avsc")
|
|
209
|
+
expect { Avro::Schema.parse(raw) }.to raise_error(Avro::UnknownSchemaError)
|
|
210
|
+
|
|
211
|
+
# ...and the fully-resolved (inlined) schema is registered instead.
|
|
212
|
+
resolved = SchemaRegistry::Schema::Avro.new.schema_text(nil, schema_name: "cross_file.v1.Outer")
|
|
213
|
+
expect { Avro::Schema.parse(resolved) }.not_to raise_error
|
|
214
|
+
|
|
215
|
+
stub = stub_request(:post, "http://localhost:8081/subjects/cross/versions")
|
|
216
|
+
.with(body: {"schema" => resolved}).to_return_json(body: {id: 30})
|
|
217
|
+
|
|
218
|
+
encoded = schema_registry_client.encode({"inner" => {"name" => "my name"}},
|
|
219
|
+
subject: "cross", schema_name: "cross_file.v1.Outer")
|
|
220
|
+
|
|
221
|
+
expect(encoded[1..4].unpack1("N")).to eq(30)
|
|
222
|
+
expect(stub).to have_been_requested.once
|
|
223
|
+
end
|
|
199
224
|
end
|
|
200
225
|
|
|
201
226
|
describe "caching" do
|
|
@@ -302,7 +327,7 @@ RSpec.describe "encoding" do
|
|
|
302
327
|
end
|
|
303
328
|
|
|
304
329
|
it "should not register the same schema twice" do
|
|
305
|
-
schema = File.read("#{__dir__}/schemas/simple/v1/SimpleMessage.avsc")
|
|
330
|
+
schema = avro_registration_text(File.read("#{__dir__}/schemas/simple/v1/SimpleMessage.avsc"))
|
|
306
331
|
stub = stub_request(:post, "http://localhost:8081/subjects/simple/versions")
|
|
307
332
|
.with(body: {"schema" => schema}).to_return_json(body: {id: 15})
|
|
308
333
|
msg = {"name" => "my name"}
|
|
@@ -313,7 +338,7 @@ RSpec.describe "encoding" do
|
|
|
313
338
|
end
|
|
314
339
|
|
|
315
340
|
it "should register schemas for different subjects separately" do
|
|
316
|
-
schema = File.read("#{__dir__}/schemas/simple/v1/SimpleMessage.avsc")
|
|
341
|
+
schema = avro_registration_text(File.read("#{__dir__}/schemas/simple/v1/SimpleMessage.avsc"))
|
|
317
342
|
stub_a = stub_request(:post, "http://localhost:8081/subjects/subject-a/versions")
|
|
318
343
|
.with(body: {"schema" => schema}).to_return_json(body: {id: 15})
|
|
319
344
|
stub_b = stub_request(:post, "http://localhost:8081/subjects/subject-b/versions")
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: schema_registry_client
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Daniel Orner
|
|
@@ -173,6 +173,8 @@ files:
|
|
|
173
173
|
- spec/gen/simple/simple_pb.rb
|
|
174
174
|
- spec/json_schema_spec.rb
|
|
175
175
|
- spec/proto_text_spec.rb
|
|
176
|
+
- spec/schemas/cross_file/v1/Inner.avsc
|
|
177
|
+
- spec/schemas/cross_file/v1/Outer.avsc
|
|
176
178
|
- spec/schemas/everything/everything.json
|
|
177
179
|
- spec/schemas/everything/everything.proto
|
|
178
180
|
- spec/schemas/referenced/referenced.json
|
|
@@ -194,7 +196,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
194
196
|
requirements:
|
|
195
197
|
- - ">="
|
|
196
198
|
- !ruby/object:Gem::Version
|
|
197
|
-
version: '3.
|
|
199
|
+
version: '3.2'
|
|
198
200
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
199
201
|
requirements:
|
|
200
202
|
- - ">="
|