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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '09a16bc0d516a981c823ec6aef2c356cae10f4dca61279870b741741c1f9baa4'
4
- data.tar.gz: 7bbcbe0b5b6ffeb494c264983e137fc1864387440bc9ecc41b21f2405d15a361
3
+ metadata.gz: ade8a75ca2eb7bacb07566bd5eaa2899bfd69c2ed34dd7c1bc7e186b531b055e
4
+ data.tar.gz: 17174e9182ce1f875006bbe302f8ad7cc9809af3d415e2a9500ccfda114ec95d
5
5
  SHA512:
6
- metadata.gz: 88a82ff70e5fdc2a5b5b783630a218a58b02cdc1f2513470ffd31f14e1d75356eff1f1ccef7e684954ce9d72ce07571e71b50900e61e1cf98de998d3513a5718
7
- data.tar.gz: 9c5a98b3299615b052a8eb2f9f4356cc75dea85b283c5cee8e8759b97c373be17350a7df9d3f9232200cf3d6f406dd64ddff80d4292d5be3982807779f9ae4b9
6
+ metadata.gz: 4ccea73cc7df695421518ad82de2507950d7d6e300146d5210c982addea11396ad4b4ee154f58ed38aa81891a13df20b5e60f50e84a74d74e7f6cd86c39aa1cb
7
+ data.tar.gz: 0daa9b8085d05991b1be936e8ce0aa209ab0973a05103a8dc8368e394988ec52ef7066110d912542b891342e2842b92b4e7e24d29b8d597a3a39d315d1b8d0bc
@@ -9,7 +9,7 @@ jobs:
9
9
  strategy:
10
10
  fail-fast: false
11
11
  matrix:
12
- ruby: [3.1, 3.2, 3.3, 3.4]
12
+ ruby: [3.2, 3.3, 3.4]
13
13
 
14
14
  steps:
15
15
  - uses: actions/checkout@v3
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
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- schema_registry_client (0.0.11)
4
+ schema_registry_client (0.1.0)
5
5
  avro
6
6
  excon
7
7
  google-protobuf
@@ -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
- schema_store.find_text(schema_name)
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)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SchemaRegistry
4
- VERSION = "0.0.11"
4
+ VERSION = "0.1.0"
5
5
  end
@@ -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.0"
15
+ spec.required_ruby_version = ">= 3.2"
16
16
 
17
17
  spec.metadata["rubygems_mfa_required"] = "true"
18
18
 
@@ -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")
@@ -0,0 +1,11 @@
1
+ {
2
+ "type": "record",
3
+ "name": "Inner",
4
+ "namespace": "cross_file.v1",
5
+ "fields": [
6
+ {
7
+ "name": "name",
8
+ "type": "string"
9
+ }
10
+ ]
11
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "type": "record",
3
+ "name": "Outer",
4
+ "namespace": "cross_file.v1",
5
+ "fields": [
6
+ {
7
+ "name": "inner",
8
+ "type": "cross_file.v1.Inner"
9
+ }
10
+ ]
11
+ }
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.11
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.0'
199
+ version: '3.2'
198
200
  required_rubygems_version: !ruby/object:Gem::Requirement
199
201
  requirements:
200
202
  - - ">="