avro_turf 1.19.0 → 1.20.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/ruby.yml +20 -11
- data/CHANGELOG.md +6 -0
- data/Gemfile +5 -2
- data/Rakefile +2 -1
- data/avro_turf.gemspec +16 -16
- data/lib/avro_turf/cached_confluent_schema_registry.rb +9 -8
- data/lib/avro_turf/cached_schema_registry.rb +3 -1
- data/lib/avro_turf/confluent_schema_registry.rb +23 -17
- data/lib/avro_turf/core_ext/date.rb +2 -0
- data/lib/avro_turf/core_ext/enumerable.rb +2 -0
- data/lib/avro_turf/core_ext/false_class.rb +2 -0
- data/lib/avro_turf/core_ext/hash.rb +4 -2
- data/lib/avro_turf/core_ext/nil_class.rb +2 -0
- data/lib/avro_turf/core_ext/numeric.rb +2 -0
- data/lib/avro_turf/core_ext/string.rb +2 -0
- data/lib/avro_turf/core_ext/symbol.rb +2 -0
- data/lib/avro_turf/core_ext/time.rb +2 -0
- data/lib/avro_turf/core_ext/true_class.rb +2 -0
- data/lib/avro_turf/core_ext.rb +12 -10
- data/lib/avro_turf/disk_cache.rb +13 -12
- data/lib/avro_turf/in_memory_cache.rb +2 -0
- data/lib/avro_turf/messaging.rb +22 -14
- data/lib/avro_turf/mutable_schema_store.rb +25 -4
- data/lib/avro_turf/schema_registry.rb +3 -1
- data/lib/avro_turf/schema_store.rb +3 -2
- data/lib/avro_turf/schema_to_avro_patch.rb +14 -12
- data/lib/avro_turf/test/fake_confluent_schema_registry_server.rb +24 -23
- data/lib/avro_turf/test/fake_prefixed_confluent_schema_registry_server.rb +12 -10
- data/lib/avro_turf/test/fake_schema_registry_server.rb +3 -1
- data/lib/avro_turf/version.rb +3 -1
- data/lib/avro_turf.rb +15 -13
- data/perf/encoding_size.rb +4 -2
- data/perf/encoding_speed.rb +4 -2
- data/spec/avro_turf_spec.rb +24 -23
- data/spec/cached_confluent_schema_registry_spec.rb +9 -7
- data/spec/confluent_schema_registry_spec.rb +31 -10
- data/spec/core_ext/date_spec.rb +2 -0
- data/spec/core_ext/enumerable_spec.rb +2 -0
- data/spec/core_ext/false_class_spec.rb +2 -0
- data/spec/core_ext/hash_spec.rb +3 -1
- data/spec/core_ext/nil_class_spec.rb +2 -0
- data/spec/core_ext/numeric_spec.rb +2 -0
- data/spec/core_ext/string_spec.rb +2 -0
- data/spec/core_ext/symbol_spec.rb +2 -0
- data/spec/core_ext/time_spec.rb +2 -0
- data/spec/core_ext/true_class_spec.rb +2 -0
- data/spec/disk_cached_confluent_schema_registry_spec.rb +23 -21
- data/spec/messaging_spec.rb +124 -99
- data/spec/mutable_schema_store_spec.rb +134 -0
- data/spec/schema_store_spec.rb +23 -21
- data/spec/schema_to_avro_patch_spec.rb +8 -7
- data/spec/spec_helper.rb +9 -9
- data/spec/support/authorized_fake_confluent_schema_registry_server.rb +4 -2
- data/spec/support/authorized_fake_prefixed_confluent_schema_registry_server.rb +4 -2
- data/spec/support/confluent_schema_registry_context.rb +32 -30
- data/spec/test/fake_confluent_schema_registry_server_spec.rb +97 -94
- metadata +5 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0f3d6b25c3e25a9137581fbe4bdb3e45015d371c479f8beeb54fa30ee8a3475e
|
4
|
+
data.tar.gz: a59d1634303784ae309a40c45f6abf70acdd5b681abe9a89bac40fa0497c5a63
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 85b800371ca6102518333c64732a26af7d103d35453923e1ac332b6c643e1826c00c90b826e9332c23e4de5f995bd40c8411447184289c2834fc45dbeded1664
|
7
|
+
data.tar.gz: df05accd07e4876a776a6dffb1850bfecd73d82727fc22ab5d25a4e002c069d50c7d9bb0e5fe9ae23e2f528b189c49d31ad87189d0ec07f5c2dcefb707110719
|
data/.github/workflows/ruby.yml
CHANGED
@@ -4,20 +4,29 @@ on: [push, pull_request]
|
|
4
4
|
|
5
5
|
jobs:
|
6
6
|
build:
|
7
|
-
|
8
7
|
runs-on: ubuntu-latest
|
9
8
|
strategy:
|
10
9
|
fail-fast: false
|
11
10
|
matrix:
|
12
|
-
ruby: [3.0, 3.1, 3.2, 3.3]
|
11
|
+
ruby: ["3.0", 3.1, 3.2, 3.3, 3.4]
|
12
|
+
steps:
|
13
|
+
- uses: actions/checkout@v5
|
14
|
+
- name: Set up Ruby ${{ matrix.ruby }}
|
15
|
+
uses: ruby/setup-ruby@v1
|
16
|
+
with:
|
17
|
+
ruby-version: ${{ matrix.ruby }}
|
18
|
+
bundler-cache: true
|
19
|
+
- name: Build and test with RSpec
|
20
|
+
env:
|
21
|
+
RUBYOPT: '--enable=frozen-string-literal --debug=frozen-string-literal'
|
22
|
+
run: bundle exec rspec
|
13
23
|
|
24
|
+
lint:
|
25
|
+
runs-on: ubuntu-24.04-arm
|
14
26
|
steps:
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
- name: Build and test with RSpec
|
22
|
-
run: |
|
23
|
-
bundle exec rspec
|
27
|
+
- uses: actions/checkout@v5
|
28
|
+
- uses: ruby/setup-ruby@v1
|
29
|
+
with:
|
30
|
+
ruby-version: 3
|
31
|
+
bundler-cache: true
|
32
|
+
- run: bundle exec standardrb
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,12 @@
|
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
+
## v1.20.0
|
6
|
+
|
7
|
+
- Add support for client certificate chains via `client_chain` and `client_chain_data` parameters (#233)
|
8
|
+
- Ensure the gem works with frozen strings.
|
9
|
+
- Stop caching nested sub-schemas in MutableSchemaStore (#232)
|
10
|
+
|
5
11
|
## v1.19.0
|
6
12
|
|
7
13
|
- Loosen excon dependency to allow 1.x (#220)
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
data/avro_turf.gemspec
CHANGED
@@ -1,22 +1,22 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
5
|
+
require "avro_turf/version"
|
5
6
|
|
6
7
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name
|
8
|
-
spec.version
|
9
|
-
spec.authors
|
10
|
-
spec.email
|
11
|
-
spec.summary
|
12
|
-
spec.homepage
|
13
|
-
spec.license
|
8
|
+
spec.name = "avro_turf"
|
9
|
+
spec.version = AvroTurf::VERSION
|
10
|
+
spec.authors = ["Daniel Schierbeck"]
|
11
|
+
spec.email = ["dasch@zendesk.com"]
|
12
|
+
spec.summary = "A library that makes it easier to use the Avro serialization format from Ruby"
|
13
|
+
spec.homepage = "https://github.com/dasch/avro_turf"
|
14
|
+
spec.license = "MIT"
|
14
15
|
|
15
16
|
spec.metadata["rubygems_mfa_required"] = "true"
|
16
17
|
|
17
|
-
spec.files
|
18
|
-
spec.executables
|
19
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.files = `git ls-files -z`.split("\x0")
|
19
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
20
|
spec.require_paths = ["lib"]
|
21
21
|
|
22
22
|
spec.add_dependency "avro", ">= 1.11.3", "< 1.13"
|
@@ -25,14 +25,14 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_development_dependency "bundler", "~> 2.0"
|
26
26
|
spec.add_development_dependency "rake", "~> 13.0"
|
27
27
|
spec.add_development_dependency "rspec", "~> 3.2"
|
28
|
-
spec.add_development_dependency "fakefs", "
|
28
|
+
spec.add_development_dependency "fakefs", "~> 3"
|
29
29
|
spec.add_development_dependency "webmock"
|
30
30
|
spec.add_development_dependency "sinatra"
|
31
31
|
spec.add_development_dependency "json_spec"
|
32
32
|
spec.add_development_dependency "rack-test"
|
33
33
|
spec.add_development_dependency "resolv"
|
34
34
|
|
35
|
-
spec.post_install_message = %
|
35
|
+
spec.post_install_message = %(
|
36
36
|
avro_turf v0.8.0 deprecates the names AvroTurf::SchemaRegistry,
|
37
37
|
AvroTurf::CachedSchemaRegistry, and FakeSchemaRegistryServer.
|
38
38
|
|
@@ -40,5 +40,5 @@ Use AvroTurf::ConfluentSchemaRegistry, AvroTurf::CachedConfluentSchemaRegistry,
|
|
40
40
|
and FakeConfluentSchemaRegistryServer instead.
|
41
41
|
|
42
42
|
See https://github.com/dasch/avro_turf#deprecation-notice
|
43
|
-
|
43
|
+
)
|
44
44
|
end
|
@@ -1,10 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "avro_turf/confluent_schema_registry"
|
4
|
+
require "avro_turf/in_memory_cache"
|
5
|
+
require "avro_turf/disk_cache"
|
4
6
|
|
5
7
|
# Caches registrations and lookups to the schema registry in memory.
|
6
8
|
class AvroTurf::CachedConfluentSchemaRegistry
|
7
|
-
|
8
9
|
# Instantiate a new CachedConfluentSchemaRegistry instance with the given configuration.
|
9
10
|
# By default, uses a provided InMemoryCache to prevent repeated calls to the upstream registry.
|
10
11
|
#
|
@@ -17,8 +18,8 @@ class AvroTurf::CachedConfluentSchemaRegistry
|
|
17
18
|
end
|
18
19
|
|
19
20
|
# Delegate the following methods to the upstream
|
20
|
-
%i
|
21
|
-
|
21
|
+
%i[subjects subject_versions schema_subject_versions compatible?
|
22
|
+
global_config update_global_config subject_config update_subject_config].each do |name|
|
22
23
|
define_method(name) do |*args|
|
23
24
|
instance_variable_get(:@upstream).send(name, *args)
|
24
25
|
end
|
@@ -36,8 +37,8 @@ class AvroTurf::CachedConfluentSchemaRegistry
|
|
36
37
|
@cache.lookup_by_schema(subject, schema) || @cache.store_by_schema(subject, schema, @upstream.register(subject, schema))
|
37
38
|
end
|
38
39
|
|
39
|
-
def subject_version(subject, version =
|
40
|
-
return @upstream.subject_version(subject, version) if version ==
|
40
|
+
def subject_version(subject, version = "latest")
|
41
|
+
return @upstream.subject_version(subject, version) if version == "latest"
|
41
42
|
|
42
43
|
@cache.lookup_by_version(subject, version) ||
|
43
44
|
@cache.store_by_version(subject, version, @upstream.subject_version(subject, version))
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "avro_turf/cached_confluent_schema_registry"
|
2
4
|
|
3
5
|
# AvroTurf::CachedSchemaRegistry is deprecated and will be removed in a future release.
|
4
6
|
# Use AvroTurf::CachedConfluentSchemaRegistry instead.
|
@@ -1,7 +1,9 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "excon"
|
2
4
|
|
3
5
|
class AvroTurf::ConfluentSchemaRegistry
|
4
|
-
CONTENT_TYPE = "application/vnd.schemaregistry.v1+json"
|
6
|
+
CONTENT_TYPE = "application/vnd.schemaregistry.v1+json"
|
5
7
|
|
6
8
|
def initialize(
|
7
9
|
url,
|
@@ -12,9 +14,11 @@ class AvroTurf::ConfluentSchemaRegistry
|
|
12
14
|
password: nil,
|
13
15
|
ssl_ca_file: nil,
|
14
16
|
client_cert: nil,
|
17
|
+
client_chain: nil,
|
15
18
|
client_key: nil,
|
16
19
|
client_key_pass: nil,
|
17
20
|
client_cert_data: nil,
|
21
|
+
client_chain_data: nil,
|
18
22
|
client_key_data: nil,
|
19
23
|
path_prefix: nil,
|
20
24
|
connect_timeout: nil,
|
@@ -22,7 +26,7 @@ class AvroTurf::ConfluentSchemaRegistry
|
|
22
26
|
retry_limit: nil
|
23
27
|
)
|
24
28
|
@path_prefix = path_prefix
|
25
|
-
@schema_context_prefix = schema_context.nil? ?
|
29
|
+
@schema_context_prefix = schema_context.nil? ? "" : ":.#{schema_context}:"
|
26
30
|
@schema_context_options = schema_context.nil? ? {} : {query: {subject: @schema_context_prefix}}
|
27
31
|
@logger = logger
|
28
32
|
headers = Excon.defaults[:headers].merge(
|
@@ -35,9 +39,11 @@ class AvroTurf::ConfluentSchemaRegistry
|
|
35
39
|
proxy: proxy,
|
36
40
|
ssl_ca_file: ssl_ca_file,
|
37
41
|
client_cert: client_cert,
|
42
|
+
client_chain: client_chain,
|
38
43
|
client_key: client_key,
|
39
44
|
client_key_pass: client_key_pass,
|
40
45
|
client_cert_data: client_cert_data,
|
46
|
+
client_chain_data: client_chain_data,
|
41
47
|
client_key_data: client_key_data,
|
42
48
|
resolv_resolver: resolv_resolver,
|
43
49
|
connect_timeout: connect_timeout,
|
@@ -53,12 +59,12 @@ class AvroTurf::ConfluentSchemaRegistry
|
|
53
59
|
|
54
60
|
def fetch(id)
|
55
61
|
@logger.info "Fetching schema with id #{id}"
|
56
|
-
data = get("/schemas/ids/#{id}", idempotent: true, **@schema_context_options
|
62
|
+
data = get("/schemas/ids/#{id}", idempotent: true, **@schema_context_options)
|
57
63
|
data.fetch("schema")
|
58
64
|
end
|
59
65
|
|
60
66
|
def register(subject, schema)
|
61
|
-
data = post("/subjects/#{@schema_context_prefix}#{subject}/versions", body: {
|
67
|
+
data = post("/subjects/#{@schema_context_prefix}#{subject}/versions", body: {schema: schema.to_s}.to_json)
|
62
68
|
|
63
69
|
id = data.fetch("id")
|
64
70
|
|
@@ -69,7 +75,7 @@ class AvroTurf::ConfluentSchemaRegistry
|
|
69
75
|
|
70
76
|
# List all subjects
|
71
77
|
def subjects
|
72
|
-
get(
|
78
|
+
get("/subjects", idempotent: true)
|
73
79
|
end
|
74
80
|
|
75
81
|
# List all versions for a subject
|
@@ -78,7 +84,7 @@ class AvroTurf::ConfluentSchemaRegistry
|
|
78
84
|
end
|
79
85
|
|
80
86
|
# Get a specific version for a subject
|
81
|
-
def subject_version(subject, version =
|
87
|
+
def subject_version(subject, version = "latest")
|
82
88
|
get("/subjects/#{@schema_context_prefix}#{subject}/versions/#{version}", idempotent: true)
|
83
89
|
end
|
84
90
|
|
@@ -90,9 +96,9 @@ class AvroTurf::ConfluentSchemaRegistry
|
|
90
96
|
# Check if a schema exists. Returns nil if not found.
|
91
97
|
def check(subject, schema)
|
92
98
|
data = post("/subjects/#{@schema_context_prefix}#{subject}",
|
93
|
-
|
94
|
-
|
95
|
-
|
99
|
+
expects: [200, 404],
|
100
|
+
body: {schema: schema.to_s}.to_json,
|
101
|
+
idempotent: true)
|
96
102
|
data unless data.has_key?("error_code")
|
97
103
|
end
|
98
104
|
|
@@ -102,10 +108,10 @@ class AvroTurf::ConfluentSchemaRegistry
|
|
102
108
|
# - nil if the subject or version does not exist
|
103
109
|
# - false if incompatible
|
104
110
|
# http://docs.confluent.io/3.1.2/schema-registry/docs/api.html#compatibility
|
105
|
-
def compatible?(subject, schema, version =
|
111
|
+
def compatible?(subject, schema, version = "latest")
|
106
112
|
data = post("/compatibility/subjects/#{@schema_context_prefix}#{subject}/versions/#{version}",
|
107
|
-
|
108
|
-
data.fetch(
|
113
|
+
expects: [200, 404], body: {schema: schema.to_s}.to_json, idempotent: true)
|
114
|
+
data.fetch("is_compatible", false) unless data.has_key?("error_code")
|
109
115
|
end
|
110
116
|
|
111
117
|
# Check for specific schema compatibility issues
|
@@ -113,11 +119,11 @@ class AvroTurf::ConfluentSchemaRegistry
|
|
113
119
|
# - nil if the subject or version does not exist
|
114
120
|
# - a list of compatibility issues
|
115
121
|
# https://docs.confluent.io/platform/current/schema-registry/develop/api.html#sr-api-compatibility
|
116
|
-
def compatibility_issues(subject, schema, version =
|
122
|
+
def compatibility_issues(subject, schema, version = "latest")
|
117
123
|
data = post("/compatibility/subjects/#{@schema_context_prefix}#{subject}/versions/#{version}",
|
118
|
-
expects: [200, 404], body: {
|
124
|
+
expects: [200, 404], body: {schema: schema.to_s}.to_json, query: {verbose: true}, idempotent: true)
|
119
125
|
|
120
|
-
data.fetch(
|
126
|
+
data.fetch("messages", []) unless data.has_key?("error_code")
|
121
127
|
end
|
122
128
|
|
123
129
|
# Get global config
|
@@ -155,7 +161,7 @@ class AvroTurf::ConfluentSchemaRegistry
|
|
155
161
|
end
|
156
162
|
|
157
163
|
def request(path, **options)
|
158
|
-
options = {
|
164
|
+
options = {expects: 200}.merge!(options)
|
159
165
|
path = File.join(@path_prefix, path) unless @path_prefix.nil?
|
160
166
|
response = @connection.request(path: path, **options)
|
161
167
|
JSON.parse(response.body)
|
data/lib/avro_turf/core_ext.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "avro_turf/core_ext/string"
|
4
|
+
require "avro_turf/core_ext/numeric"
|
5
|
+
require "avro_turf/core_ext/enumerable"
|
6
|
+
require "avro_turf/core_ext/hash"
|
7
|
+
require "avro_turf/core_ext/time"
|
8
|
+
require "avro_turf/core_ext/date"
|
9
|
+
require "avro_turf/core_ext/symbol"
|
10
|
+
require "avro_turf/core_ext/nil_class"
|
11
|
+
require "avro_turf/core_ext/true_class"
|
12
|
+
require "avro_turf/core_ext/false_class"
|
data/lib/avro_turf/disk_cache.rb
CHANGED
@@ -1,23 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# A cache for the CachedConfluentSchemaRegistry.
|
2
4
|
# Extends the InMemoryCache to provide a write-thru to disk for persistent cache.
|
3
5
|
class AvroTurf::DiskCache
|
4
|
-
|
5
6
|
def initialize(disk_path, logger: Logger.new($stdout))
|
6
7
|
@logger = logger
|
7
8
|
|
8
9
|
# load the write-thru cache on startup, if it exists
|
9
|
-
@schemas_by_id_path = File.join(disk_path,
|
10
|
+
@schemas_by_id_path = File.join(disk_path, "schemas_by_id.json")
|
10
11
|
hash = read_from_disk_cache(@schemas_by_id_path)
|
11
12
|
@schemas_by_id = hash || {}
|
12
13
|
|
13
|
-
@ids_by_schema_path = File.join(disk_path,
|
14
|
+
@ids_by_schema_path = File.join(disk_path, "ids_by_schema.json")
|
14
15
|
hash = read_from_disk_cache(@ids_by_schema_path)
|
15
16
|
@ids_by_schema = hash || {}
|
16
17
|
|
17
|
-
@schemas_by_subject_version_path = File.join(disk_path,
|
18
|
+
@schemas_by_subject_version_path = File.join(disk_path, "schemas_by_subject_version.json")
|
18
19
|
@schemas_by_subject_version = {}
|
19
20
|
|
20
|
-
@data_by_schema_path = File.join(disk_path,
|
21
|
+
@data_by_schema_path = File.join(disk_path, "data_by_schema.json")
|
21
22
|
hash = read_from_disk_cache(@data_by_schema_path)
|
22
23
|
@data_by_schema = hash || {}
|
23
24
|
end
|
@@ -94,11 +95,11 @@ class AvroTurf::DiskCache
|
|
94
95
|
key = "#{subject}#{version}"
|
95
96
|
hash = read_from_disk_cache(@schemas_by_subject_version_path)
|
96
97
|
hash = if hash
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
98
|
+
hash[key] = schema
|
99
|
+
hash
|
100
|
+
else
|
101
|
+
{key => schema}
|
102
|
+
end
|
102
103
|
|
103
104
|
write_to_disk_cache(@schemas_by_subject_version_path, hash)
|
104
105
|
|
@@ -110,7 +111,7 @@ class AvroTurf::DiskCache
|
|
110
111
|
private def read_from_disk_cache(path)
|
111
112
|
if File.exist?(path)
|
112
113
|
if File.size(path) != 0
|
113
|
-
json_data = File.open(path,
|
114
|
+
json_data = File.open(path, "r") do |file|
|
114
115
|
file.flock(File::LOCK_SH)
|
115
116
|
file.read
|
116
117
|
end
|
@@ -127,7 +128,7 @@ class AvroTurf::DiskCache
|
|
127
128
|
|
128
129
|
private def write_to_disk_cache(path, hash)
|
129
130
|
# don't use "w" because it truncates the file before lock
|
130
|
-
File.open(path, File::RDWR | File::CREAT,
|
131
|
+
File.open(path, File::RDWR | File::CREAT, 0o644) do |file|
|
131
132
|
file.flock(File::LOCK_EX)
|
132
133
|
file.write(JSON.pretty_generate(hash))
|
133
134
|
end
|
data/lib/avro_turf/messaging.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "logger"
|
4
|
+
require "avro_turf"
|
5
|
+
require "avro_turf/schema_store"
|
6
|
+
require "avro_turf/confluent_schema_registry"
|
7
|
+
require "avro_turf/cached_confluent_schema_registry"
|
6
8
|
|
7
9
|
# For back-compatibility require the aliases along with the Messaging API.
|
8
10
|
# These names are deprecated and will be removed in a future release.
|
9
|
-
require
|
10
|
-
require
|
11
|
+
require "avro_turf/schema_registry"
|
12
|
+
require "avro_turf/cached_schema_registry"
|
11
13
|
|
12
14
|
class AvroTurf
|
13
15
|
class IncompatibleSchemaError < StandardError; end
|
@@ -56,7 +58,9 @@ class AvroTurf
|
|
56
58
|
# client_key - Name of file containing client private key to go with client_cert (optional).
|
57
59
|
# client_key_pass - Password to go with client_key (optional).
|
58
60
|
# client_cert_data - In-memory client certificate (optional).
|
61
|
+
# client_chain - Name of file containing client certificate chain (optional).
|
59
62
|
# client_key_data - In-memory client private key to go with client_cert_data (optional).
|
63
|
+
# client_chain_data - In-memory client certificate chain (optional).
|
60
64
|
# connect_timeout - Timeout to use in the connection with the schema registry (optional).
|
61
65
|
# resolv_resolver - Custom domain name resolver (optional).
|
62
66
|
def initialize(
|
@@ -73,9 +77,11 @@ class AvroTurf
|
|
73
77
|
password: nil,
|
74
78
|
ssl_ca_file: nil,
|
75
79
|
client_cert: nil,
|
80
|
+
client_chain: nil,
|
76
81
|
client_key: nil,
|
77
82
|
client_key_pass: nil,
|
78
83
|
client_cert_data: nil,
|
84
|
+
client_chain_data: nil,
|
79
85
|
client_key_data: nil,
|
80
86
|
connect_timeout: nil,
|
81
87
|
resolv_resolver: nil,
|
@@ -94,9 +100,11 @@ class AvroTurf
|
|
94
100
|
password: password,
|
95
101
|
ssl_ca_file: ssl_ca_file,
|
96
102
|
client_cert: client_cert,
|
103
|
+
client_chain: client_chain,
|
97
104
|
client_key: client_key,
|
98
105
|
client_key_pass: client_key_pass,
|
99
106
|
client_cert_data: client_cert_data,
|
107
|
+
client_chain_data: client_chain_data,
|
100
108
|
client_key_data: client_key_data,
|
101
109
|
path_prefix: registry_path_prefix,
|
102
110
|
connect_timeout: connect_timeout,
|
@@ -129,7 +137,7 @@ class AvroTurf
|
|
129
137
|
#
|
130
138
|
# Returns the encoded data as a String.
|
131
139
|
def encode(message, schema_name: nil, namespace: @namespace, subject: nil, version: nil, schema_id: nil, validate: false,
|
132
|
-
|
140
|
+
register_schemas: true)
|
133
141
|
schema, schema_id = if schema_id
|
134
142
|
fetch_schema_by_id(schema_id)
|
135
143
|
elsif subject && version
|
@@ -139,7 +147,7 @@ class AvroTurf
|
|
139
147
|
elsif schema_name
|
140
148
|
register_schema(subject: subject, schema_name: schema_name, namespace: namespace)
|
141
149
|
else
|
142
|
-
raise ArgumentError.new(
|
150
|
+
raise ArgumentError.new("Neither schema_name nor schema_id nor subject + version provided to determine the schema.")
|
143
151
|
end
|
144
152
|
|
145
153
|
if validate
|
@@ -203,7 +211,7 @@ class AvroTurf
|
|
203
211
|
end
|
204
212
|
|
205
213
|
# The schema id is a 4-byte big-endian integer.
|
206
|
-
schema_id = decoder.read(4).
|
214
|
+
schema_id = decoder.read(4).unpack1("N")
|
207
215
|
|
208
216
|
writers_schema = @schemas_by_id.fetch(schema_id) do
|
209
217
|
schema_json = @registry.fetch(schema_id)
|
@@ -221,14 +229,14 @@ class AvroTurf
|
|
221
229
|
# Providing subject and version to determine the schema,
|
222
230
|
# which skips the auto registration of schema on the schema registry.
|
223
231
|
# Fetch the schema from registry with the provided subject name and version.
|
224
|
-
def fetch_schema(subject:, version:
|
232
|
+
def fetch_schema(subject:, version: "latest")
|
225
233
|
schema_data = @registry.subject_version(subject, version)
|
226
|
-
schema_id = schema_data.fetch(
|
227
|
-
schema_type = schema_data[
|
234
|
+
schema_id = schema_data.fetch("id")
|
235
|
+
schema_type = schema_data["schemaType"]
|
228
236
|
if schema_type && schema_type != "AVRO"
|
229
237
|
raise IncompatibleSchemaError, "The #{schema_type} schema for #{subject} is incompatible."
|
230
238
|
end
|
231
|
-
schema = Avro::Schema.parse(schema_data.fetch(
|
239
|
+
schema = Avro::Schema.parse(schema_data.fetch("schema"))
|
232
240
|
[schema, schema_id]
|
233
241
|
end
|
234
242
|
|
@@ -1,18 +1,39 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "avro_turf/schema_store"
|
2
4
|
|
3
5
|
class AvroTurf
|
4
6
|
# A schema store that allows you to add or remove schemas, and to access
|
5
7
|
# them externally.
|
8
|
+
#
|
9
|
+
# Only the top-level schema is cached. It is important to not register
|
10
|
+
# sub-schema as other schemas may define the same sub-schema and
|
11
|
+
# the Avro gem will raise an Avro::SchemaParseError when parsing another
|
12
|
+
# schema with a subschema with the same name as one encounted previously:
|
13
|
+
# <Avro::SchemaParseError: The name "foo.bar" is already in use.>
|
14
|
+
#
|
15
|
+
# Essentially, the only schemas that should be resolvable in @schemas
|
16
|
+
# are those that have their own .avsc files on disk.
|
17
|
+
#
|
18
|
+
# See https://github.com/dasch/avro_turf/pull/111
|
19
|
+
# and the implementation in AvroTurf::SchemaStore#load_schema!
|
6
20
|
class MutableSchemaStore < SchemaStore
|
7
21
|
attr_accessor :schemas
|
8
22
|
|
9
23
|
# @param schema_hash [Hash]
|
10
24
|
def add_schema(schema_hash)
|
11
|
-
name = schema_hash[
|
12
|
-
namespace = schema_hash[
|
25
|
+
name = schema_hash["name"]
|
26
|
+
namespace = schema_hash["namespace"]
|
13
27
|
full_name = Avro::Name.make_fullname(name, namespace)
|
14
28
|
return if @schemas.key?(full_name)
|
15
|
-
|
29
|
+
|
30
|
+
# We pass in copy of @schemas which Avro can freely modify
|
31
|
+
# and register the sub-schema. It doesn't matter because
|
32
|
+
# we will discard it.
|
33
|
+
schema = Avro::Schema.real_parse(schema_hash, @schemas.dup)
|
34
|
+
@schemas[full_name] = schema
|
35
|
+
|
36
|
+
schema
|
16
37
|
end
|
17
38
|
end
|
18
39
|
end
|