schema_registry_client 0.0.8 → 0.0.9
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 +4 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +1 -1
- data/Rakefile +1 -1
- data/lib/schema_registry_client/avro_schema_store.rb +8 -8
- data/lib/schema_registry_client/cached_confluent_schema_registry.rb +5 -5
- data/lib/schema_registry_client/confluent_schema_registry.rb +16 -12
- data/lib/schema_registry_client/output/json_schema.rb +12 -12
- data/lib/schema_registry_client/output/proto_text.rb +45 -45
- data/lib/schema_registry_client/schema/avro.rb +8 -8
- data/lib/schema_registry_client/schema/base.rb +4 -4
- data/lib/schema_registry_client/schema/proto_json_schema.rb +3 -3
- data/lib/schema_registry_client/schema/protobuf.rb +20 -20
- data/lib/schema_registry_client/version.rb +1 -1
- data/lib/schema_registry_client.rb +19 -19
- data/schema_registry_client.gemspec +20 -20
- data/spec/decoding_spec.rb +51 -51
- data/spec/encoding_spec.rb +84 -88
- data/spec/json_schema_spec.rb +2 -2
- data/spec/proto_text_spec.rb +1 -1
- data/spec/spec_helper.rb +5 -5
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d0919f12f0457fbdf7becd62389a7ed72e34afe9d7f3ce5c819f2e0ebf145174
|
|
4
|
+
data.tar.gz: 4dc5c91669e508e89bc07763bebb6b754403ee72ccbe125ecfc888c48cf974fa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 07d614eaceb30420a69221399fab2e360f3f3b4089e5271b42fcaca30eb9f643cebcdd59187bdfc6a33d721641b960e2855fefce4703e59f455e459088bbd996
|
|
7
|
+
data.tar.gz: 65a8cf4a6899e8f32febb2b408ebb20ed379224b7fbd0d716da33c6e0e6c10844559e5d4e1af73c3ee06a1601ecd0dc3853137aa3987837157bbd07c07655a21
|
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.0.9 - 2026-02-11
|
|
11
|
+
|
|
12
|
+
* Fix: Do not send `schemaType` if schema type is `AVRO`, for backwards compatibility with older schema registries.
|
|
13
|
+
|
|
10
14
|
# 0.0.8 - 2026-02-04
|
|
11
15
|
|
|
12
16
|
* Support passing a `schema_store` into the `Avro` schema backend.
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/Rakefile
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "avro"
|
|
4
4
|
|
|
5
5
|
module SchemaRegistry
|
|
6
6
|
class AvroSchemaStore
|
|
7
7
|
def initialize(path: nil)
|
|
8
|
-
@path = path or raise
|
|
8
|
+
@path = path or raise "Please specify a schema path"
|
|
9
9
|
@schemas = {}
|
|
10
10
|
@schema_text = {}
|
|
11
11
|
@mutex = Mutex.new
|
|
@@ -38,14 +38,14 @@ module SchemaRegistry
|
|
|
38
38
|
|
|
39
39
|
# Loads all schema definition files in the `schemas_dir`.
|
|
40
40
|
def load_schemas!
|
|
41
|
-
pattern = [@path,
|
|
41
|
+
pattern = [@path, "**", "*.avsc"].join("/")
|
|
42
42
|
|
|
43
43
|
Dir.glob(pattern) do |schema_path|
|
|
44
44
|
# Remove the path prefix.
|
|
45
|
-
schema_path.sub!(%r{^/?#{@path}/},
|
|
45
|
+
schema_path.sub!(%r{^/?#{@path}/}, "")
|
|
46
46
|
|
|
47
47
|
# Replace `/` with `.` and chop off the file extension.
|
|
48
|
-
schema_name = File.basename(schema_path.tr(
|
|
48
|
+
schema_name = File.basename(schema_path.tr("/", "."), ".avsc")
|
|
49
49
|
|
|
50
50
|
# Load and cache the schema.
|
|
51
51
|
find(schema_name)
|
|
@@ -54,8 +54,8 @@ module SchemaRegistry
|
|
|
54
54
|
|
|
55
55
|
# @param schema_hash [Hash]
|
|
56
56
|
def add_schema(schema_hash)
|
|
57
|
-
name = schema_hash[
|
|
58
|
-
namespace = schema_hash[
|
|
57
|
+
name = schema_hash["name"]
|
|
58
|
+
namespace = schema_hash["namespace"]
|
|
59
59
|
full_name = Avro::Name.make_fullname(name, namespace)
|
|
60
60
|
return if @schemas.key?(full_name)
|
|
61
61
|
|
|
@@ -120,7 +120,7 @@ module SchemaRegistry
|
|
|
120
120
|
end
|
|
121
121
|
|
|
122
122
|
def build_schema_path(fullname)
|
|
123
|
-
*namespace, schema_name = fullname.split(
|
|
123
|
+
*namespace, schema_name = fullname.split(".")
|
|
124
124
|
File.join(@path, *namespace, "#{schema_name}.avsc")
|
|
125
125
|
end
|
|
126
126
|
end
|
|
@@ -31,7 +31,7 @@ module SchemaRegistry
|
|
|
31
31
|
return @versions_by_subject_and_id[key] if @versions_by_subject_and_id[key]
|
|
32
32
|
|
|
33
33
|
results = @upstream.schema_subject_versions(id)
|
|
34
|
-
@versions_by_subject_and_id[key] = results&.find { |r| r[
|
|
34
|
+
@versions_by_subject_and_id[key] = results&.find { |r| r["subject"] == subject }&.dig("version")
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
# @param subject [String] the subject to check
|
|
@@ -45,13 +45,13 @@ module SchemaRegistry
|
|
|
45
45
|
# @param schema [String] the schema text to register
|
|
46
46
|
# @param references [Array<Hash>] optional references to other schemas
|
|
47
47
|
# @param schema_type [String]
|
|
48
|
-
def register(subject, schema, references: [], schema_type:
|
|
48
|
+
def register(subject, schema, references: [], schema_type: "PROTOBUF")
|
|
49
49
|
key = [subject, schema]
|
|
50
50
|
|
|
51
51
|
@ids_by_schema[key] ||= @upstream.register(subject,
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
schema,
|
|
53
|
+
references: references,
|
|
54
|
+
schema_type: schema_type)
|
|
55
55
|
end
|
|
56
56
|
end
|
|
57
57
|
end
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "excon"
|
|
4
4
|
|
|
5
5
|
module SchemaRegistry
|
|
6
6
|
class ConfluentSchemaRegistry
|
|
7
|
-
CONTENT_TYPE =
|
|
7
|
+
CONTENT_TYPE = "application/vnd.schemaregistry.v1+json"
|
|
8
8
|
|
|
9
9
|
def initialize( # rubocop:disable Metrics/ParameterLists
|
|
10
10
|
url,
|
|
@@ -25,11 +25,11 @@ module SchemaRegistry
|
|
|
25
25
|
retry_limit: nil
|
|
26
26
|
)
|
|
27
27
|
@path_prefix = path_prefix
|
|
28
|
-
@schema_context_prefix = schema_context.nil? ?
|
|
29
|
-
@schema_context_options = schema_context.nil? ? {} : {
|
|
28
|
+
@schema_context_prefix = schema_context.nil? ? "" : ":.#{schema_context}:"
|
|
29
|
+
@schema_context_options = schema_context.nil? ? {} : {query: {subject: @schema_context_prefix}}
|
|
30
30
|
@logger = logger
|
|
31
31
|
headers = Excon.defaults[:headers].merge(
|
|
32
|
-
|
|
32
|
+
"Content-Type" => CONTENT_TYPE
|
|
33
33
|
)
|
|
34
34
|
params = {
|
|
35
35
|
headers: headers,
|
|
@@ -59,7 +59,7 @@ module SchemaRegistry
|
|
|
59
59
|
def fetch(id)
|
|
60
60
|
@logger.info "Fetching schema with id #{id}"
|
|
61
61
|
data = get("/schemas/ids/#{id}", idempotent: true, **@schema_context_options)
|
|
62
|
-
data.fetch(
|
|
62
|
+
data.fetch("schema")
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
# @param schema_id [Integer] the schema ID to fetch versions for
|
|
@@ -72,13 +72,17 @@ module SchemaRegistry
|
|
|
72
72
|
# @param schema [String] the schema text to check
|
|
73
73
|
# @param references [Array<Hash>] optional references to other schemas
|
|
74
74
|
# @return [Integer] the ID of the registered schema
|
|
75
|
-
def register(subject, schema, references: [], schema_type:
|
|
75
|
+
def register(subject, schema, references: [], schema_type: "PROTOBUF")
|
|
76
|
+
body = {references: references,
|
|
77
|
+
schema: schema.to_s}
|
|
78
|
+
# Not all schema registry versions support schemaType
|
|
79
|
+
if schema_type != "AVRO"
|
|
80
|
+
body[:schemaType] = schema_type
|
|
81
|
+
end
|
|
76
82
|
data = post("/subjects/#{@schema_context_prefix}#{CGI.escapeURIComponent(subject)}/versions",
|
|
77
|
-
|
|
78
|
-
references: references,
|
|
79
|
-
schema: schema.to_s }.to_json)
|
|
83
|
+
body: body.to_json)
|
|
80
84
|
|
|
81
|
-
id = data.fetch(
|
|
85
|
+
id = data.fetch("id")
|
|
82
86
|
|
|
83
87
|
@logger.info "Registered schema for subject `#{@schema_context_prefix}#{subject}`; id = #{id}"
|
|
84
88
|
|
|
@@ -106,7 +110,7 @@ module SchemaRegistry
|
|
|
106
110
|
end
|
|
107
111
|
|
|
108
112
|
def request(path, **options)
|
|
109
|
-
options = {
|
|
113
|
+
options = {expects: 200}.merge!(options)
|
|
110
114
|
path = File.join(@path_prefix, path) unless @path_prefix.nil?
|
|
111
115
|
response = @connection.request(path: path, **options)
|
|
112
116
|
JSON.parse(response.body)
|
|
@@ -5,20 +5,20 @@ module SchemaRegistry
|
|
|
5
5
|
module JsonSchema
|
|
6
6
|
class << self
|
|
7
7
|
def fetch(message_name)
|
|
8
|
-
name = message_name.start_with?(
|
|
8
|
+
name = message_name.start_with?(".") ? message_name[1..] : message_name
|
|
9
9
|
Google::Protobuf::DescriptorPool.generated_pool.lookup(name)
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def output(descriptor, path: nil)
|
|
13
13
|
properties = {}
|
|
14
14
|
result = {
|
|
15
|
-
"$schema":
|
|
16
|
-
type:
|
|
15
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
16
|
+
type: "object",
|
|
17
17
|
properties: properties
|
|
18
18
|
}
|
|
19
19
|
if path
|
|
20
20
|
# follow path down
|
|
21
|
-
parts = path.split(
|
|
21
|
+
parts = path.split(".")
|
|
22
22
|
field_name = parts.last
|
|
23
23
|
parts[...-1].each do |part|
|
|
24
24
|
field = descriptor.field.find { |f| f.name == part }
|
|
@@ -42,12 +42,12 @@ module SchemaRegistry
|
|
|
42
42
|
if field.label == :LABEL_REPEATED && !ignore_repeated
|
|
43
43
|
if klass&.options.respond_to?(:map_entry) && klass.options.map_entry
|
|
44
44
|
return {
|
|
45
|
-
type:
|
|
45
|
+
type: "object",
|
|
46
46
|
additionalProperties: field_object(klass.field[1])
|
|
47
47
|
}
|
|
48
48
|
end
|
|
49
49
|
return {
|
|
50
|
-
type:
|
|
50
|
+
type: "array",
|
|
51
51
|
items: field_object(field, ignore_repeated: true)
|
|
52
52
|
}
|
|
53
53
|
end
|
|
@@ -57,18 +57,18 @@ module SchemaRegistry
|
|
|
57
57
|
def field_type(field, klass)
|
|
58
58
|
case field.type
|
|
59
59
|
when :TYPE_INT32, :TYPE_UINT32, :TYPE_SINT32, :TYPE_FIXED32, :TYPE_SFIXED32
|
|
60
|
-
{
|
|
60
|
+
{type: "integer"}
|
|
61
61
|
when :TYPE_FLOAT, :TYPE_DOUBLE
|
|
62
|
-
{
|
|
62
|
+
{type: "number"}
|
|
63
63
|
when :TYPE_INT64, :TYPE_UINT64, :TYPE_SINT64, :TYPE_FIXED64, :TYPE_SFIXED64, :TYPE_STRING, :TYPE_BYTES
|
|
64
|
-
{
|
|
64
|
+
{type: "string"}
|
|
65
65
|
when :TYPE_BOOL
|
|
66
|
-
{
|
|
66
|
+
{type: "boolean"}
|
|
67
67
|
else
|
|
68
68
|
if klass.is_a?(Google::Protobuf::EnumDescriptorProto)
|
|
69
|
-
{
|
|
69
|
+
{enum: klass.to_h[:value].map { |h| h[:name] }}
|
|
70
70
|
else
|
|
71
|
-
{
|
|
71
|
+
{type: "object"}
|
|
72
72
|
end
|
|
73
73
|
end
|
|
74
74
|
end
|
|
@@ -18,7 +18,7 @@ module SchemaRegistry
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def write_indent(str)
|
|
21
|
-
@indent.times { write(
|
|
21
|
+
@indent.times { write(" ") }
|
|
22
22
|
write(str)
|
|
23
23
|
end
|
|
24
24
|
|
|
@@ -42,7 +42,7 @@ module SchemaRegistry
|
|
|
42
42
|
|
|
43
43
|
class << self
|
|
44
44
|
def fetch(message_name)
|
|
45
|
-
name = message_name.start_with?(
|
|
45
|
+
name = message_name.start_with?(".") ? message_name[1..] : message_name
|
|
46
46
|
Google::Protobuf::DescriptorPool.generated_pool.lookup(name)
|
|
47
47
|
end
|
|
48
48
|
|
|
@@ -87,23 +87,23 @@ module SchemaRegistry
|
|
|
87
87
|
info.indent
|
|
88
88
|
write_field(info, extension)
|
|
89
89
|
info.dedent
|
|
90
|
-
info.write_line(
|
|
90
|
+
info.write_line("}")
|
|
91
91
|
end
|
|
92
92
|
descriptor.extension.any?
|
|
93
93
|
end
|
|
94
94
|
|
|
95
95
|
def write_reserved(writer, descriptor)
|
|
96
96
|
reserved = descriptor.reserved_range.map do |range|
|
|
97
|
-
range.start == range.end - 1 ? range.start.to_s : "#{range.start} to #{range.end - 1}"
|
|
97
|
+
(range.start == range.end - 1) ? range.start.to_s : "#{range.start} to #{range.end - 1}"
|
|
98
98
|
end
|
|
99
99
|
found = false
|
|
100
100
|
if reserved.any?
|
|
101
101
|
found = true
|
|
102
|
-
writer.write_line("reserved #{reserved.join(
|
|
102
|
+
writer.write_line("reserved #{reserved.join(", ")};")
|
|
103
103
|
end
|
|
104
104
|
if descriptor.reserved_name.any?
|
|
105
105
|
found = true
|
|
106
|
-
writer.write_line("reserved #{descriptor.reserved_name.map(&:to_json).join(
|
|
106
|
+
writer.write_line("reserved #{descriptor.reserved_name.map(&:to_json).join(", ")};")
|
|
107
107
|
end
|
|
108
108
|
writer.writenl if found
|
|
109
109
|
end
|
|
@@ -124,7 +124,7 @@ module SchemaRegistry
|
|
|
124
124
|
|
|
125
125
|
def write_message(info, message_type)
|
|
126
126
|
info.message = message_type
|
|
127
|
-
info.write_indent(
|
|
127
|
+
info.write_indent("message ")
|
|
128
128
|
info.write("#{message_type.name} {")
|
|
129
129
|
info.writenl
|
|
130
130
|
info.indent
|
|
@@ -150,61 +150,61 @@ module SchemaRegistry
|
|
|
150
150
|
write_message(info, subtype)
|
|
151
151
|
end
|
|
152
152
|
info.dedent
|
|
153
|
-
info.write_line(
|
|
153
|
+
info.write_line("}")
|
|
154
154
|
end
|
|
155
155
|
|
|
156
156
|
def field_type(info, field_type)
|
|
157
157
|
case field_type.type
|
|
158
158
|
when :TYPE_INT32
|
|
159
|
-
|
|
159
|
+
"int32"
|
|
160
160
|
when :TYPE_INT64
|
|
161
|
-
|
|
161
|
+
"int64"
|
|
162
162
|
when :TYPE_UINT32
|
|
163
|
-
|
|
163
|
+
"uint32"
|
|
164
164
|
when :TYPE_UINT64
|
|
165
|
-
|
|
165
|
+
"uint64"
|
|
166
166
|
when :TYPE_SINT32
|
|
167
|
-
|
|
167
|
+
"sint32"
|
|
168
168
|
when :TYPE_SINT64
|
|
169
|
-
|
|
169
|
+
"sint64"
|
|
170
170
|
when :TYPE_FIXED32
|
|
171
|
-
|
|
171
|
+
"fixed32"
|
|
172
172
|
when :TYPE_FIXED64
|
|
173
|
-
|
|
173
|
+
"fixed64"
|
|
174
174
|
when :TYPE_SFIXED32
|
|
175
|
-
|
|
175
|
+
"sfixed32"
|
|
176
176
|
when :TYPE_SFIXED64
|
|
177
|
-
|
|
177
|
+
"sfixed64"
|
|
178
178
|
when :TYPE_FLOAT
|
|
179
|
-
|
|
179
|
+
"float"
|
|
180
180
|
when :TYPE_DOUBLE
|
|
181
|
-
|
|
181
|
+
"double"
|
|
182
182
|
when :TYPE_BOOL
|
|
183
|
-
|
|
183
|
+
"bool"
|
|
184
184
|
when :TYPE_STRING
|
|
185
|
-
|
|
185
|
+
"string"
|
|
186
186
|
when :TYPE_BYTES
|
|
187
|
-
|
|
187
|
+
"bytes"
|
|
188
188
|
when :TYPE_ENUM, :TYPE_MESSAGE
|
|
189
189
|
# remove leading .
|
|
190
190
|
type = fetch(field_type.type_name[1..])
|
|
191
|
-
name = type.name.sub("#{info.package}.#{info.message.name}.",
|
|
192
|
-
name.sub("#{info.package}.",
|
|
191
|
+
name = type.name.sub("#{info.package}.#{info.message.name}.", "")
|
|
192
|
+
name.sub("#{info.package}.", "")
|
|
193
193
|
end
|
|
194
194
|
end
|
|
195
195
|
|
|
196
196
|
def write_field(info, field, oneof: false)
|
|
197
197
|
return if !oneof && field.has_oneof_index?
|
|
198
198
|
|
|
199
|
-
info.write_indent(
|
|
199
|
+
info.write_indent("")
|
|
200
200
|
|
|
201
201
|
klass = nil
|
|
202
|
-
klass = fetch(field.type_name).to_proto if field.type_name && field.type_name !=
|
|
202
|
+
klass = fetch(field.type_name).to_proto if field.type_name && field.type_name != ""
|
|
203
203
|
|
|
204
204
|
if field.proto3_optional
|
|
205
|
-
info.write(
|
|
205
|
+
info.write("optional ")
|
|
206
206
|
elsif field.label == :LABEL_REPEATED && !klass&.options&.map_entry
|
|
207
|
-
info.write(
|
|
207
|
+
info.write("repeated ")
|
|
208
208
|
end
|
|
209
209
|
|
|
210
210
|
if klass&.options&.map_entry
|
|
@@ -215,24 +215,24 @@ module SchemaRegistry
|
|
|
215
215
|
info.write(" #{field.name} = #{field.number}")
|
|
216
216
|
|
|
217
217
|
write_field_options(info, field)
|
|
218
|
-
info.write(
|
|
218
|
+
info.write(";")
|
|
219
219
|
info.writenl
|
|
220
220
|
end
|
|
221
221
|
|
|
222
222
|
def write_field_options(info, field)
|
|
223
223
|
return unless field.options
|
|
224
224
|
|
|
225
|
-
info.write(
|
|
226
|
-
info.write(field.options.to_h.map { |name, value| "#{name} = #{value}" }.join(
|
|
225
|
+
info.write(" [")
|
|
226
|
+
info.write(field.options.to_h.map { |name, value| "#{name} = #{value}" }.join(", "))
|
|
227
227
|
write_options(info, field, include_option_label: false)
|
|
228
|
-
info.write(
|
|
228
|
+
info.write("]")
|
|
229
229
|
end
|
|
230
230
|
|
|
231
231
|
def write_oneofs(info, message)
|
|
232
232
|
message.oneof_decl.each_with_index do |oneof, i|
|
|
233
233
|
# synthetic oneof for proto3 optional fields
|
|
234
|
-
next if oneof.name.start_with?(
|
|
235
|
-
|
|
234
|
+
next if oneof.name.start_with?("_") &&
|
|
235
|
+
message.field.any? { |f| f.proto3_optional && f.name == oneof.name[1..] }
|
|
236
236
|
|
|
237
237
|
info.write_line("oneof #{oneof.name} {")
|
|
238
238
|
info.indent
|
|
@@ -240,12 +240,12 @@ module SchemaRegistry
|
|
|
240
240
|
write_field(info, field, oneof: true)
|
|
241
241
|
end
|
|
242
242
|
info.dedent
|
|
243
|
-
info.write_line(
|
|
243
|
+
info.write_line("}")
|
|
244
244
|
end
|
|
245
245
|
end
|
|
246
246
|
|
|
247
247
|
def write_enum(info, enum_type)
|
|
248
|
-
info.write(
|
|
248
|
+
info.write("enum ")
|
|
249
249
|
info.write("#{enum_type.name} {")
|
|
250
250
|
info.writenl
|
|
251
251
|
info.indent
|
|
@@ -254,30 +254,30 @@ module SchemaRegistry
|
|
|
254
254
|
info.write_line("#{value.name} = #{value.number};")
|
|
255
255
|
end
|
|
256
256
|
info.dedent
|
|
257
|
-
info.write_line(
|
|
257
|
+
info.write_line("}")
|
|
258
258
|
info.writenl
|
|
259
259
|
end
|
|
260
260
|
|
|
261
261
|
def method_type(package, name)
|
|
262
|
-
output = name.sub("#{package}.",
|
|
263
|
-
output = output[1..] if output.start_with?(
|
|
262
|
+
output = name.sub("#{package}.", "")
|
|
263
|
+
output = output[1..] if output.start_with?(".")
|
|
264
264
|
output
|
|
265
265
|
end
|
|
266
266
|
|
|
267
267
|
def write_service(info, service)
|
|
268
268
|
info.write_line("service #{service.name} {")
|
|
269
269
|
info.indent
|
|
270
|
-
service[
|
|
270
|
+
service["method"].each do |method|
|
|
271
271
|
info.write_indent("rpc #{method.name}(#{method_type(info.package, method.input_type)}) ")
|
|
272
272
|
info.write("returns (#{method_type(info.package, method.output_type)}) {")
|
|
273
273
|
info.writenl
|
|
274
274
|
info.indent
|
|
275
275
|
write_options(info, method) if method.options
|
|
276
276
|
info.dedent
|
|
277
|
-
info.write_line(
|
|
277
|
+
info.write_line("};")
|
|
278
278
|
end
|
|
279
279
|
info.dedent
|
|
280
|
-
info.write_line(
|
|
280
|
+
info.write_line("}")
|
|
281
281
|
end
|
|
282
282
|
|
|
283
283
|
# @return [Boolean] true if any options were written
|
|
@@ -289,7 +289,7 @@ module SchemaRegistry
|
|
|
289
289
|
|
|
290
290
|
found = false
|
|
291
291
|
json.each_key do |name|
|
|
292
|
-
option_name = name.tr(
|
|
292
|
+
option_name = name.tr("[]", "")
|
|
293
293
|
ext = fetch(option_name)
|
|
294
294
|
next if ext.nil?
|
|
295
295
|
|
|
@@ -306,7 +306,7 @@ module SchemaRegistry
|
|
|
306
306
|
info.write_indent(line)
|
|
307
307
|
info.writenl if i < lines.length - 1
|
|
308
308
|
end
|
|
309
|
-
info.write(
|
|
309
|
+
info.write(";")
|
|
310
310
|
else
|
|
311
311
|
info.write(options.to_json)
|
|
312
312
|
end
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
3
|
+
require "schema_registry_client/schema/base"
|
|
4
|
+
require "schema_registry_client/avro_schema_store"
|
|
5
5
|
|
|
6
6
|
module SchemaRegistry
|
|
7
7
|
module Schema
|
|
8
8
|
class Avro < Base
|
|
9
|
-
DEFAULT_SCHEMAS_PATH =
|
|
9
|
+
DEFAULT_SCHEMAS_PATH = "./schemas"
|
|
10
10
|
|
|
11
11
|
def self.schema_type
|
|
12
|
-
|
|
12
|
+
"AVRO"
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
# @param schema_store [SchemaRegistry::AvroSchemaStore, nil]
|
|
@@ -31,9 +31,9 @@ module SchemaRegistry
|
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
def encode(message, stream, schema_name: nil)
|
|
34
|
-
validate_options = {
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
validate_options = {recursive: true,
|
|
35
|
+
encoded: false,
|
|
36
|
+
fail_on_extra_fields: true}
|
|
37
37
|
schema = schema_store.find(schema_name)
|
|
38
38
|
|
|
39
39
|
::Avro::SchemaValidator.validate!(schema, message, **validate_options)
|
|
@@ -53,7 +53,7 @@ module SchemaRegistry
|
|
|
53
53
|
# Try to find the reader schema locally, fall back to writer schema
|
|
54
54
|
readers_schema = begin
|
|
55
55
|
schema_store.find(writers_schema.fullname)
|
|
56
|
-
rescue
|
|
56
|
+
rescue
|
|
57
57
|
writers_schema
|
|
58
58
|
end
|
|
59
59
|
|
|
@@ -9,19 +9,19 @@ module SchemaRegistry
|
|
|
9
9
|
# @param schema_name [String]
|
|
10
10
|
# @return [String]
|
|
11
11
|
def schema_text(_message, schema_name: nil)
|
|
12
|
-
raise MissingImplementationError,
|
|
12
|
+
raise MissingImplementationError, "Subclasses must implement schema_text"
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
# @return [String]
|
|
16
16
|
def self.schema_type
|
|
17
|
-
raise MissingImplementationError,
|
|
17
|
+
raise MissingImplementationError, "Subclasses must implement schema_type"
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
# @param message [Object]
|
|
21
21
|
# @param stream [StringIO]
|
|
22
22
|
# @param schema_name [String]
|
|
23
23
|
def encode(_message, _stream, schema_name: nil)
|
|
24
|
-
raise MissingImplementationError,
|
|
24
|
+
raise MissingImplementationError, "Subclasses must implement encode"
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
# @param stream [StringIO]
|
|
@@ -29,7 +29,7 @@ module SchemaRegistry
|
|
|
29
29
|
# @param registry [Object]
|
|
30
30
|
# @return [Object]
|
|
31
31
|
def decode(_stream, _schema_text)
|
|
32
|
-
raise MissingImplementationError,
|
|
32
|
+
raise MissingImplementationError, "Subclasses must implement decode"
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
# @param message [Object]
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
3
|
+
require "schema_registry_client/schema/base"
|
|
4
|
+
require "schema_registry_client/output/json_schema"
|
|
5
5
|
|
|
6
6
|
module SchemaRegistry
|
|
7
7
|
module Schema
|
|
8
8
|
class ProtoJsonSchema < Base
|
|
9
9
|
def self.schema_type
|
|
10
|
-
|
|
10
|
+
"JSON"
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def schema_text(message, schema_name: nil)
|