avro_turf 1.16.0 → 1.18.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/push_gem.yml +24 -0
- data/CHANGELOG.md +9 -0
- data/README.md +14 -2
- data/lib/avro_turf/cached_confluent_schema_registry.rb +5 -1
- data/lib/avro_turf/confluent_schema_registry.rb +12 -0
- data/lib/avro_turf/disk_cache.rb +19 -0
- data/lib/avro_turf/in_memory_cache.rb +13 -1
- data/lib/avro_turf/messaging.rb +29 -15
- data/lib/avro_turf/schema_store.rb +1 -1
- data/lib/avro_turf/test/fake_prefixed_confluent_schema_registry_server.rb +2 -1
- data/lib/avro_turf/version.rb +1 -1
- data/spec/cached_confluent_schema_registry_spec.rb +23 -3
- data/spec/disk_cached_confluent_schema_registry_spec.rb +60 -0
- data/spec/messaging_spec.rb +61 -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 +2 -2
- data/spec/test/fake_confluent_schema_registry_server_spec.rb +1 -2
- metadata +11 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1c6f4cafa2c752c6b0dbe23703a4d2efccf558e11cec1c33db5a1af911cca43a
|
4
|
+
data.tar.gz: 61c9bc9c1963bb89f8b00c01ad0c4195d8cf48473ea191b3d91afa88361c7aa5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b7792365879b2d4dab3f7a160687ba7308c8f5cb6f9d788506ad087bfb56056f867328bc5357ab011917588bb7e67219300c00e3cadcdef389b927f8cf398de
|
7
|
+
data.tar.gz: 834dcc062ca3e2a6f6b4eafecd8425abacad9ca64d972bbe03100def4e7af2adb706d2fcde541d31d6ff199e9b3ce51f47774269adc55191a7b6d9dc2ed5e224
|
@@ -0,0 +1,24 @@
|
|
1
|
+
on:
|
2
|
+
push:
|
3
|
+
branches:
|
4
|
+
- master
|
5
|
+
jobs:
|
6
|
+
push:
|
7
|
+
name: Push gem to RubyGems.org
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
|
10
|
+
permissions:
|
11
|
+
id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
|
12
|
+
contents: write # IMPORTANT: this permission is required for `rake release` to push the release tag
|
13
|
+
|
14
|
+
steps:
|
15
|
+
# Set up
|
16
|
+
- uses: actions/checkout@v4
|
17
|
+
- name: Set up Ruby
|
18
|
+
uses: ruby/setup-ruby@v1
|
19
|
+
with:
|
20
|
+
bundler-cache: true
|
21
|
+
ruby-version: ruby
|
22
|
+
|
23
|
+
# Release
|
24
|
+
- uses: rubygems/release-gem@v1
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
+
## v1.18.0
|
6
|
+
|
7
|
+
- Add `compatibility_issues` method to `ConfluentSchemaRegistry` to debug compatibility issues between a schema versions for a given subject (#212)
|
8
|
+
- Update tests to support `sinatra` version 4.1 that includes a new `host_authorization` parameter to permit only authorized requests
|
9
|
+
|
10
|
+
## v1.17.0
|
11
|
+
|
12
|
+
- Add `register_schemas` option to `encode` method [#210](https://github.com/dasch/avro_turf/pull/210)
|
13
|
+
|
5
14
|
## v1.16.0
|
6
15
|
|
7
16
|
- Add compatibility with Avro v1.12.x.
|
data/README.md
CHANGED
@@ -92,6 +92,9 @@ avro.encode({ "name" => "Jane", "age" => 28 }, schema_name: "person")
|
|
92
92
|
# Data can be validated before encoding to get a description of problem through
|
93
93
|
# Avro::SchemaValidator::ValidationError exception
|
94
94
|
avro.encode({ "titl" => "hello, world" }, schema_name: "person", validate: true)
|
95
|
+
|
96
|
+
# If you do not want to register the schema in case it does not exist, you can pass the register_schemas option as false
|
97
|
+
avro.encode({ "name" => "Jane", "age" => 28 }, schema_name: "person", register_schemas: false)
|
95
98
|
```
|
96
99
|
|
97
100
|
### Inter-schema references
|
@@ -251,6 +254,9 @@ registry = AvroTurf::ConfluentSchemaRegistry.new("http://my-registry:8081/")
|
|
251
254
|
|
252
255
|
# Returns true if the schema is compatible, nil if the subject or version is not registered, and false if incompatible.
|
253
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)
|
254
260
|
```
|
255
261
|
|
256
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):
|
@@ -267,17 +273,23 @@ fake schema registry server depends on Sinatra but it is _not_ listed as a runti
|
|
267
273
|
dependency for AvroTurf. Sinatra must be added to your Gemfile or gemspec in order
|
268
274
|
to use the fake server.
|
269
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
|
+
|
270
278
|
Example using RSpec:
|
271
279
|
|
272
280
|
```ruby
|
273
281
|
require 'avro_turf/test/fake_confluent_schema_registry_server'
|
274
282
|
require 'webmock/rspec'
|
275
283
|
|
284
|
+
class AuthorizedFakeConfluentSchemaRegistryServer < FakeConfluentSchemaRegistryServer
|
285
|
+
set :host_authentication, permitted_hosts: ['registry.example.com']
|
286
|
+
end
|
287
|
+
|
276
288
|
# within an example
|
277
289
|
let(:registry_url) { "http://registry.example.com" }
|
278
290
|
before do
|
279
|
-
stub_request(:any, /^#{registry_url}/).to_rack(
|
280
|
-
|
291
|
+
stub_request(:any, /^#{registry_url}/).to_rack(AuthorizedFakeConfluentSchemaRegistryServer)
|
292
|
+
AuthorizedFakeConfluentSchemaRegistryServer.clear
|
281
293
|
end
|
282
294
|
|
283
295
|
# Messaging objects created with the same registry_url will now use the fake server.
|
@@ -17,13 +17,17 @@ class AvroTurf::CachedConfluentSchemaRegistry
|
|
17
17
|
end
|
18
18
|
|
19
19
|
# Delegate the following methods to the upstream
|
20
|
-
%i(subjects subject_versions schema_subject_versions
|
20
|
+
%i(subjects subject_versions schema_subject_versions 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)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
def check(subject, schema)
|
28
|
+
@cache.lookup_data_by_schema(subject, schema) || @cache.store_data_by_schema(subject, schema, @upstream.check(subject, schema))
|
29
|
+
end
|
30
|
+
|
27
31
|
def fetch(id)
|
28
32
|
@cache.lookup_by_id(id) || @cache.store_by_id(id, @upstream.fetch(id))
|
29
33
|
end
|
@@ -101,6 +101,18 @@ class AvroTurf::ConfluentSchemaRegistry
|
|
101
101
|
data.fetch('is_compatible', false) unless data.has_key?('error_code')
|
102
102
|
end
|
103
103
|
|
104
|
+
# Check for specific schema compatibility issues
|
105
|
+
# Returns:
|
106
|
+
# - nil if the subject or version does not exist
|
107
|
+
# - a list of compatibility issues
|
108
|
+
# https://docs.confluent.io/platform/current/schema-registry/develop/api.html#sr-api-compatibility
|
109
|
+
def compatibility_issues(subject, schema, version = 'latest')
|
110
|
+
data = post("/compatibility/subjects/#{@schema_context_prefix}#{subject}/versions/#{version}",
|
111
|
+
expects: [200, 404], body: { schema: schema.to_s }.to_json, query: { verbose: true }, idempotent: true)
|
112
|
+
|
113
|
+
data.fetch('messages', []) unless data.has_key?('error_code')
|
114
|
+
end
|
115
|
+
|
104
116
|
# Get global config
|
105
117
|
def global_config
|
106
118
|
get("/config", idempotent: true)
|
data/lib/avro_turf/disk_cache.rb
CHANGED
@@ -16,6 +16,10 @@ class AvroTurf::DiskCache
|
|
16
16
|
|
17
17
|
@schemas_by_subject_version_path = File.join(disk_path, 'schemas_by_subject_version.json')
|
18
18
|
@schemas_by_subject_version = {}
|
19
|
+
|
20
|
+
@data_by_schema_path = File.join(disk_path, 'data_by_schema.json')
|
21
|
+
hash = read_from_disk_cache(@data_by_schema_path)
|
22
|
+
@data_by_schema = hash || {}
|
19
23
|
end
|
20
24
|
|
21
25
|
# override
|
@@ -40,6 +44,12 @@ class AvroTurf::DiskCache
|
|
40
44
|
@ids_by_schema[key]
|
41
45
|
end
|
42
46
|
|
47
|
+
# override to use a json serializable cache key
|
48
|
+
def lookup_data_by_schema(subject, schema)
|
49
|
+
key = "#{subject}#{schema}"
|
50
|
+
@data_by_schema[key]
|
51
|
+
end
|
52
|
+
|
43
53
|
# override to use a json serializable cache key and update the file cache
|
44
54
|
def store_by_schema(subject, schema, id)
|
45
55
|
key = "#{subject}#{schema}"
|
@@ -49,6 +59,15 @@ class AvroTurf::DiskCache
|
|
49
59
|
id
|
50
60
|
end
|
51
61
|
|
62
|
+
def store_data_by_schema(subject, schema, data)
|
63
|
+
return unless data
|
64
|
+
|
65
|
+
key = "#{subject}#{schema}"
|
66
|
+
@data_by_schema[key] = data
|
67
|
+
write_to_disk_cache(@data_by_schema_path, @data_by_schema)
|
68
|
+
data
|
69
|
+
end
|
70
|
+
|
52
71
|
# checks instance var (in-memory cache) for schema
|
53
72
|
# checks disk cache if in-memory cache doesn't exists
|
54
73
|
# if file exists but no in-memory cache, read from file and sync in-memory cache
|
@@ -1,11 +1,11 @@
|
|
1
1
|
# A cache for the CachedConfluentSchemaRegistry.
|
2
2
|
# Simply stores the schemas and ids in in-memory hashes.
|
3
3
|
class AvroTurf::InMemoryCache
|
4
|
-
|
5
4
|
def initialize
|
6
5
|
@schemas_by_id = {}
|
7
6
|
@ids_by_schema = {}
|
8
7
|
@schema_by_subject_version = {}
|
8
|
+
@data_by_schema = {}
|
9
9
|
end
|
10
10
|
|
11
11
|
def lookup_by_id(id)
|
@@ -21,11 +21,23 @@ class AvroTurf::InMemoryCache
|
|
21
21
|
@ids_by_schema[key]
|
22
22
|
end
|
23
23
|
|
24
|
+
def lookup_data_by_schema(subject, schema)
|
25
|
+
key = [subject, schema]
|
26
|
+
@data_by_schema[key]
|
27
|
+
end
|
28
|
+
|
24
29
|
def store_by_schema(subject, schema, id)
|
25
30
|
key = [subject, schema]
|
26
31
|
@ids_by_schema[key] = id
|
27
32
|
end
|
28
33
|
|
34
|
+
def store_data_by_schema(subject, schema, data)
|
35
|
+
return unless data
|
36
|
+
|
37
|
+
key = [subject, schema]
|
38
|
+
@data_by_schema[key] = data
|
39
|
+
end
|
40
|
+
|
29
41
|
def lookup_by_version(subject, version)
|
30
42
|
key = "#{subject}#{version}"
|
31
43
|
@schema_by_subject_version[key]
|
data/lib/avro_turf/messaging.rb
CHANGED
@@ -106,27 +106,33 @@ class AvroTurf
|
|
106
106
|
|
107
107
|
# Encodes a message using the specified schema.
|
108
108
|
#
|
109
|
-
# message
|
110
|
-
#
|
111
|
-
# schema_name
|
112
|
-
#
|
113
|
-
# namespace
|
114
|
-
# subject
|
115
|
-
#
|
116
|
-
# version
|
117
|
-
#
|
118
|
-
# schema_id
|
119
|
-
#
|
120
|
-
# validate
|
121
|
-
#
|
122
|
-
#
|
109
|
+
# message - The message that should be encoded. Must be compatible with
|
110
|
+
# the schema.
|
111
|
+
# schema_name - The String name of the schema that should be used to encode
|
112
|
+
# the data.
|
113
|
+
# namespace - The namespace of the schema (optional).
|
114
|
+
# subject - The subject name the schema should be registered under in
|
115
|
+
# the schema registry (optional).
|
116
|
+
# version - The integer version of the schema that should be used to decode
|
117
|
+
# the data. Must match the schema used when encoding (optional).
|
118
|
+
# schema_id - The integer id of the schema that should be used to encode
|
119
|
+
# the data.
|
120
|
+
# validate - The boolean for performing complete message validation before
|
121
|
+
# encoding it, Avro::SchemaValidator::ValidationError with
|
122
|
+
# a descriptive message will be raised in case of invalid message.
|
123
|
+
# register_schemas - The boolean that indicates whether or not the schema should be
|
124
|
+
# registered in case it does not exist, or if it should be fetched
|
125
|
+
# from the registry without registering it (register_schemas: false).
|
123
126
|
#
|
124
127
|
# Returns the encoded data as a String.
|
125
|
-
def encode(message, schema_name: nil, namespace: @namespace, subject: nil, version: nil, schema_id: nil, validate: false
|
128
|
+
def encode(message, schema_name: nil, namespace: @namespace, subject: nil, version: nil, schema_id: nil, validate: false,
|
129
|
+
register_schemas: true)
|
126
130
|
schema, schema_id = if schema_id
|
127
131
|
fetch_schema_by_id(schema_id)
|
128
132
|
elsif subject && version
|
129
133
|
fetch_schema(subject: subject, version: version)
|
134
|
+
elsif schema_name && !register_schemas
|
135
|
+
fetch_schema_by_body(subject: subject, schema_name: schema_name, namespace: namespace)
|
130
136
|
elsif schema_name
|
131
137
|
register_schema(subject: subject, schema_name: schema_name, namespace: namespace)
|
132
138
|
else
|
@@ -228,6 +234,14 @@ class AvroTurf
|
|
228
234
|
[schema, schema_id]
|
229
235
|
end
|
230
236
|
|
237
|
+
def fetch_schema_by_body(schema_name:, subject: nil, namespace: nil)
|
238
|
+
schema = @schema_store.find(schema_name, namespace)
|
239
|
+
schema_data = @registry.check(subject || schema.fullname, schema)
|
240
|
+
raise SchemaNotFoundError.new("Schema with structure: #{schema} not found on registry") unless schema_data
|
241
|
+
|
242
|
+
[schema, schema_data["id"]]
|
243
|
+
end
|
244
|
+
|
231
245
|
# Schemas are registered under the full name of the top level Avro record
|
232
246
|
# type, or `subject` if it's provided.
|
233
247
|
def register_schema(schema_name:, subject: nil, namespace: nil)
|
@@ -64,7 +64,8 @@ class FakePrefixedConfluentSchemaRegistryServer < FakeConfluentSchemaRegistrySer
|
|
64
64
|
|
65
65
|
# Note: this does not actually handle the same schema registered under
|
66
66
|
# multiple subjects
|
67
|
-
|
67
|
+
context, _subject = parse_qualified_subject(params[:subject])
|
68
|
+
schema_id = SCHEMAS[context].index(schema)
|
68
69
|
|
69
70
|
halt(404, SCHEMA_NOT_FOUND) unless schema_id
|
70
71
|
|
data/lib/avro_turf/version.rb
CHANGED
@@ -6,6 +6,7 @@ describe AvroTurf::CachedConfluentSchemaRegistry do
|
|
6
6
|
let(:upstream) { instance_double(AvroTurf::ConfluentSchemaRegistry) }
|
7
7
|
let(:registry) { described_class.new(upstream) }
|
8
8
|
let(:id) { rand(999) }
|
9
|
+
let(:subject_name) { 'a_subject' }
|
9
10
|
let(:schema) do
|
10
11
|
{
|
11
12
|
type: "record",
|
@@ -25,8 +26,6 @@ describe AvroTurf::CachedConfluentSchemaRegistry do
|
|
25
26
|
end
|
26
27
|
|
27
28
|
describe "#register" do
|
28
|
-
let(:subject_name) { "a_subject" }
|
29
|
-
|
30
29
|
it "caches the result of register" do
|
31
30
|
# multiple calls return same result, with only one upstream call
|
32
31
|
allow(upstream).to receive(:register).with(subject_name, schema).and_return(id)
|
@@ -36,8 +35,29 @@ describe AvroTurf::CachedConfluentSchemaRegistry do
|
|
36
35
|
end
|
37
36
|
end
|
38
37
|
|
38
|
+
describe "#check" do
|
39
|
+
let(:schema_data) do
|
40
|
+
{
|
41
|
+
"subject" => subject_name,
|
42
|
+
"version" => 123,
|
43
|
+
"id" => id,
|
44
|
+
"schema" => schema
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
before do
|
49
|
+
allow(upstream).to receive(:check).with(subject_name, schema).and_return(schema_data)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "caches the result of check" do
|
53
|
+
# multiple calls return same result, with only one upstream call
|
54
|
+
expect(registry.check(subject_name, schema)).to eq(schema_data)
|
55
|
+
expect(registry.check(subject_name, schema)).to eq(schema_data)
|
56
|
+
expect(upstream).to have_received(:check).exactly(1).times
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
39
60
|
describe '#subject_version' do
|
40
|
-
let(:subject_name) { 'a_subject' }
|
41
61
|
let(:version) { 1 }
|
42
62
|
let(:schema_with_meta) do
|
43
63
|
{
|
@@ -222,6 +222,66 @@ describe AvroTurf::CachedConfluentSchemaRegistry do
|
|
222
222
|
end
|
223
223
|
end
|
224
224
|
|
225
|
+
describe "#check" do
|
226
|
+
let(:city_name) { "a_city" }
|
227
|
+
let(:schema_data) do
|
228
|
+
{
|
229
|
+
"subject" => subject,
|
230
|
+
"version" => version,
|
231
|
+
"id" => id,
|
232
|
+
"schema" => schema
|
233
|
+
}
|
234
|
+
end
|
235
|
+
|
236
|
+
let(:city_schema_data) do
|
237
|
+
{
|
238
|
+
"subject" => city_name,
|
239
|
+
"version" => version,
|
240
|
+
"id" => city_id,
|
241
|
+
"schema" => city_schema
|
242
|
+
}
|
243
|
+
end
|
244
|
+
|
245
|
+
let(:cache_before) do
|
246
|
+
{
|
247
|
+
"#{subject}#{schema}" => schema_data
|
248
|
+
}
|
249
|
+
end
|
250
|
+
|
251
|
+
let(:cache_after) do
|
252
|
+
{
|
253
|
+
"#{subject}#{schema}" => schema_data,
|
254
|
+
"#{city_name}#{city_schema}" => city_schema_data
|
255
|
+
}
|
256
|
+
end
|
257
|
+
|
258
|
+
# setup the disk cache to avoid performing the upstream fetch
|
259
|
+
before do
|
260
|
+
store_cache("data_by_schema.json", cache_before)
|
261
|
+
allow(upstream).to receive(:check).with(subject, schema).and_return(schema_data)
|
262
|
+
allow(upstream).to receive(:check).with(city_name, city_schema).and_return(city_schema_data)
|
263
|
+
end
|
264
|
+
|
265
|
+
context "when the schema is not found in the cache" do
|
266
|
+
it "makes only one request using upstream" do
|
267
|
+
expect(registry.check(city_name, city_schema)).to eq(city_schema_data)
|
268
|
+
expect(registry.check(city_name, city_schema)).to eq(city_schema_data)
|
269
|
+
expect(upstream).to have_received(:check).with(city_name, city_schema).exactly(1).times
|
270
|
+
expect(load_cache("data_by_schema.json")).to eq cache_after
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
context "when schema is already in the cache" do
|
275
|
+
it "uses preloaded disk cache" do
|
276
|
+
# multiple calls return same result, with zero upstream calls
|
277
|
+
expect(registry.check(subject, schema)).to eq(schema_data)
|
278
|
+
expect(registry.check(subject, schema)).to eq(schema_data)
|
279
|
+
expect(upstream).to have_received(:check).exactly(0).times
|
280
|
+
expect(load_cache("data_by_schema.json")).to eq cache_before
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
225
285
|
it_behaves_like "a confluent schema registry client" do
|
226
286
|
let(:upstream) { AvroTurf::ConfluentSchemaRegistry.new(registry_url, logger: logger) }
|
227
287
|
let(:registry) { described_class.new(upstream) }
|
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" }
|
@@ -36,6 +34,24 @@ describe AvroTurf::Messaging do
|
|
36
34
|
}
|
37
35
|
AVSC
|
38
36
|
end
|
37
|
+
|
38
|
+
let(:city_message) { { "name" => "Paris" } }
|
39
|
+
let(:city_schema_json) do
|
40
|
+
<<-AVSC
|
41
|
+
{
|
42
|
+
"name": "city",
|
43
|
+
"type": "record",
|
44
|
+
"fields": [
|
45
|
+
{
|
46
|
+
"type": "string",
|
47
|
+
"name": "name"
|
48
|
+
}
|
49
|
+
]
|
50
|
+
}
|
51
|
+
AVSC
|
52
|
+
end
|
53
|
+
|
54
|
+
let(:city_schema) { Avro::Schema.parse(city_schema_json) }
|
39
55
|
let(:schema) { Avro::Schema.parse(schema_json) }
|
40
56
|
|
41
57
|
before do
|
@@ -43,12 +59,13 @@ describe AvroTurf::Messaging do
|
|
43
59
|
end
|
44
60
|
|
45
61
|
before do
|
46
|
-
stub_request(:any, /^#{registry_url}/).to_rack(
|
47
|
-
|
62
|
+
stub_request(:any, /^#{registry_url}/).to_rack(AuthorizedFakeConfluentSchemaRegistryServer)
|
63
|
+
AuthorizedFakeConfluentSchemaRegistryServer.clear
|
48
64
|
end
|
49
65
|
|
50
66
|
before do
|
51
67
|
define_schema "person.avsc", schema_json
|
68
|
+
define_schema "city.avsc", city_schema_json
|
52
69
|
end
|
53
70
|
|
54
71
|
shared_examples_for "encoding and decoding with the schema from schema store" do
|
@@ -92,6 +109,16 @@ describe AvroTurf::Messaging do
|
|
92
109
|
expect { avro.encode(message, subject: 'missing', version: 1) }.to raise_error(AvroTurf::SchemaNotFoundError)
|
93
110
|
end
|
94
111
|
|
112
|
+
it 'raises AvroTurf::SchemaNotFoundError when the schema does not exist on registry and register_schemas false' do
|
113
|
+
expect { avro.encode(city_message, schema_name: 'city', register_schemas: false) }.
|
114
|
+
to raise_error(AvroTurf::SchemaNotFoundError, "Schema with structure: #{city_schema} not found on registry")
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'encodes with register_schemas false when the schema exists on the registry' do
|
118
|
+
data = avro.encode(message, schema_name: 'person', register_schemas: false)
|
119
|
+
expect(avro.decode(data, schema_name: 'person')).to eq message
|
120
|
+
end
|
121
|
+
|
95
122
|
it 'caches parsed schemas for decoding' do
|
96
123
|
data = avro.encode(message, subject: 'person', version: 1)
|
97
124
|
avro.decode(data)
|
@@ -364,6 +391,34 @@ describe AvroTurf::Messaging do
|
|
364
391
|
end
|
365
392
|
end
|
366
393
|
|
394
|
+
context 'using fetch_schema_by_body' do
|
395
|
+
let(:subject_name) { 'city' }
|
396
|
+
let(:schema_name) { 'city' }
|
397
|
+
let(:namespace) { 'namespace' }
|
398
|
+
let(:city_schema_id) { 125 }
|
399
|
+
let(:city_schema_data) do
|
400
|
+
{
|
401
|
+
"subject" => subject_name,
|
402
|
+
"version" => 123,
|
403
|
+
"id" => city_schema_id,
|
404
|
+
"schema" => city_schema
|
405
|
+
}
|
406
|
+
end
|
407
|
+
|
408
|
+
subject(:fetch_schema_by_body) do
|
409
|
+
avro.fetch_schema_by_body(schema_name: schema_name, namespace: namespace, subject: subject_name)
|
410
|
+
end
|
411
|
+
|
412
|
+
before do
|
413
|
+
allow(schema_store).to receive(:find).with(schema_name, namespace).and_return(city_schema)
|
414
|
+
allow(registry).to receive(:check).with(subject_name, city_schema).and_return(city_schema_data)
|
415
|
+
end
|
416
|
+
|
417
|
+
it 'gets schema from registry' do
|
418
|
+
expect(fetch_schema_by_body).to eq([city_schema, city_schema_id])
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
367
422
|
context 'using register_schema' do
|
368
423
|
let(:schema_name) { 'schema_name' }
|
369
424
|
|
@@ -417,8 +472,8 @@ describe AvroTurf::Messaging do
|
|
417
472
|
}
|
418
473
|
|
419
474
|
before do
|
420
|
-
stub_request(:any, /^#{registry_url}/).to_rack(
|
421
|
-
|
475
|
+
stub_request(:any, /^#{registry_url}/).to_rack(AuthorizedFakePrefixedConfluentSchemaRegistryServer)
|
476
|
+
AuthorizedFakePrefixedConfluentSchemaRegistryServer.clear
|
422
477
|
end
|
423
478
|
|
424
479
|
it_behaves_like "encoding and decoding with the schema from schema store"
|
@@ -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,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.18.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: 2024-
|
11
|
+
date: 2024-12-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: avro
|
@@ -170,13 +170,14 @@ dependencies:
|
|
170
170
|
- - ">="
|
171
171
|
- !ruby/object:Gem::Version
|
172
172
|
version: '0'
|
173
|
-
description:
|
173
|
+
description:
|
174
174
|
email:
|
175
175
|
- dasch@zendesk.com
|
176
176
|
executables: []
|
177
177
|
extensions: []
|
178
178
|
extra_rdoc_files: []
|
179
179
|
files:
|
180
|
+
- ".github/workflows/push_gem.yml"
|
180
181
|
- ".github/workflows/ruby.yml"
|
181
182
|
- ".github/workflows/stale.yml"
|
182
183
|
- ".gitignore"
|
@@ -235,6 +236,8 @@ files:
|
|
235
236
|
- spec/schema_store_spec.rb
|
236
237
|
- spec/schema_to_avro_patch_spec.rb
|
237
238
|
- spec/spec_helper.rb
|
239
|
+
- spec/support/authorized_fake_confluent_schema_registry_server.rb
|
240
|
+
- spec/support/authorized_fake_prefixed_confluent_schema_registry_server.rb
|
238
241
|
- spec/support/confluent_schema_registry_context.rb
|
239
242
|
- spec/test/fake_confluent_schema_registry_server_spec.rb
|
240
243
|
homepage: https://github.com/dasch/avro_turf
|
@@ -265,8 +268,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
265
268
|
- !ruby/object:Gem::Version
|
266
269
|
version: '0'
|
267
270
|
requirements: []
|
268
|
-
rubygems_version: 3.
|
269
|
-
signing_key:
|
271
|
+
rubygems_version: 3.5.22
|
272
|
+
signing_key:
|
270
273
|
specification_version: 4
|
271
274
|
summary: A library that makes it easier to use the Avro serialization format from
|
272
275
|
Ruby
|
@@ -289,5 +292,7 @@ test_files:
|
|
289
292
|
- spec/schema_store_spec.rb
|
290
293
|
- spec/schema_to_avro_patch_spec.rb
|
291
294
|
- spec/spec_helper.rb
|
295
|
+
- spec/support/authorized_fake_confluent_schema_registry_server.rb
|
296
|
+
- spec/support/authorized_fake_prefixed_confluent_schema_registry_server.rb
|
292
297
|
- spec/support/confluent_schema_registry_context.rb
|
293
298
|
- spec/test/fake_confluent_schema_registry_server_spec.rb
|