proto_turf 0.0.2 → 0.0.3
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/.rspec +2 -0
- data/CHANGELOG.md +1 -1
- data/Gemfile +5 -0
- data/Gemfile.lock +106 -0
- data/README.md +9 -1
- data/lib/proto_turf/cached_confluent_schema_registry.rb +3 -5
- data/lib/proto_turf/confluent_schema_registry.rb +7 -9
- data/lib/proto_turf/version.rb +1 -1
- data/lib/proto_turf.rb +29 -25
- data/proto_turf.gemspec +14 -13
- data/spec/decoding_spec.rb +37 -0
- data/spec/encoding_spec.rb +58 -0
- data/spec/gen/referenced/referer_pb.rb +24 -0
- data/spec/gen/simple/simple_pb.rb +17 -0
- data/spec/schemas/referenced/referer.proto +24 -0
- data/spec/schemas/simple/simple.proto +7 -0
- data/spec/spec_helper.rb +13 -0
- metadata +54 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9af9eb4df4dd0323090363e65378d08d4b9a55050eb0a08ea6ddfe2cd7bd8b59
|
4
|
+
data.tar.gz: 32fb8b5f560d5e49978930f5e863d5851efc17b288f75c26e45ee7d1cf8e98dd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3286859be78192d3495c3dc58e15dad50273aed4d611ddf579b9b27a16b01bbf0652d17af367192ed6dd9154a693a1991342439d53bde14777a5e61e5402a036
|
7
|
+
data.tar.gz: e8d941d3a7b153345e407ed62fb4e6201b93a65e01810f06cacb4fa616bbbf3c93b1456be349f3f53fd8e41d5a7f4fc4fcd0fad9fc380f8c7ff4ea101678fc18
|
data/.rspec
ADDED
data/CHANGELOG.md
CHANGED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
proto_turf (0.0.2)
|
5
|
+
excon
|
6
|
+
google-protobuf
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
addressable (2.8.7)
|
12
|
+
public_suffix (>= 2.0.2, < 7.0)
|
13
|
+
ast (2.4.3)
|
14
|
+
bigdecimal (3.2.2)
|
15
|
+
crack (1.0.0)
|
16
|
+
bigdecimal
|
17
|
+
rexml
|
18
|
+
diff-lcs (1.6.1)
|
19
|
+
excon (1.2.9)
|
20
|
+
logger
|
21
|
+
google-protobuf (4.30.2-arm64-darwin)
|
22
|
+
bigdecimal
|
23
|
+
rake (>= 13)
|
24
|
+
hashdiff (1.2.0)
|
25
|
+
json (2.13.2)
|
26
|
+
language_server-protocol (3.17.0.5)
|
27
|
+
lint_roller (1.1.0)
|
28
|
+
logger (1.7.0)
|
29
|
+
parallel (1.27.0)
|
30
|
+
parser (3.3.9.0)
|
31
|
+
ast (~> 2.4.1)
|
32
|
+
racc
|
33
|
+
prism (1.4.0)
|
34
|
+
public_suffix (6.0.2)
|
35
|
+
racc (1.8.1)
|
36
|
+
rainbow (3.1.1)
|
37
|
+
rake (13.3.0)
|
38
|
+
regexp_parser (2.11.2)
|
39
|
+
rexml (3.4.1)
|
40
|
+
rspec (3.13.0)
|
41
|
+
rspec-core (~> 3.13.0)
|
42
|
+
rspec-expectations (~> 3.13.0)
|
43
|
+
rspec-mocks (~> 3.13.0)
|
44
|
+
rspec-core (3.13.3)
|
45
|
+
rspec-support (~> 3.13.0)
|
46
|
+
rspec-expectations (3.13.4)
|
47
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
48
|
+
rspec-support (~> 3.13.0)
|
49
|
+
rspec-mocks (3.13.3)
|
50
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
51
|
+
rspec-support (~> 3.13.0)
|
52
|
+
rspec-support (3.13.3)
|
53
|
+
rubocop (1.75.8)
|
54
|
+
json (~> 2.3)
|
55
|
+
language_server-protocol (~> 3.17.0.2)
|
56
|
+
lint_roller (~> 1.1.0)
|
57
|
+
parallel (~> 1.10)
|
58
|
+
parser (>= 3.3.0.2)
|
59
|
+
rainbow (>= 2.2.2, < 4.0)
|
60
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
61
|
+
rubocop-ast (>= 1.44.0, < 2.0)
|
62
|
+
ruby-progressbar (~> 1.7)
|
63
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
64
|
+
rubocop-ast (1.46.0)
|
65
|
+
parser (>= 3.3.7.2)
|
66
|
+
prism (~> 1.4)
|
67
|
+
rubocop-performance (1.25.0)
|
68
|
+
lint_roller (~> 1.1)
|
69
|
+
rubocop (>= 1.75.0, < 2.0)
|
70
|
+
rubocop-ast (>= 1.38.0, < 2.0)
|
71
|
+
ruby-progressbar (1.13.0)
|
72
|
+
standard (1.50.0)
|
73
|
+
language_server-protocol (~> 3.17.0.2)
|
74
|
+
lint_roller (~> 1.0)
|
75
|
+
rubocop (~> 1.75.5)
|
76
|
+
standard-custom (~> 1.0.0)
|
77
|
+
standard-performance (~> 1.8)
|
78
|
+
standard-custom (1.0.2)
|
79
|
+
lint_roller (~> 1.0)
|
80
|
+
rubocop (~> 1.50)
|
81
|
+
standard-performance (1.8.0)
|
82
|
+
lint_roller (~> 1.1)
|
83
|
+
rubocop-performance (~> 1.25.0)
|
84
|
+
standardrb (1.0.1)
|
85
|
+
standard
|
86
|
+
unicode-display_width (3.1.5)
|
87
|
+
unicode-emoji (~> 4.0, >= 4.0.4)
|
88
|
+
unicode-emoji (4.0.4)
|
89
|
+
webmock (3.25.1)
|
90
|
+
addressable (>= 2.8.0)
|
91
|
+
crack (>= 0.3.2)
|
92
|
+
hashdiff (>= 0.4.0, < 2.0.0)
|
93
|
+
|
94
|
+
PLATFORMS
|
95
|
+
arm64-darwin
|
96
|
+
|
97
|
+
DEPENDENCIES
|
98
|
+
bundler (~> 2.0)
|
99
|
+
proto_turf!
|
100
|
+
rake (~> 13.0)
|
101
|
+
rspec (~> 3.2)
|
102
|
+
standardrb
|
103
|
+
webmock
|
104
|
+
|
105
|
+
BUNDLED WITH
|
106
|
+
2.6.7
|
data/README.md
CHANGED
@@ -27,7 +27,7 @@ Example usage:
|
|
27
27
|
```ruby
|
28
28
|
require 'proto_turf'
|
29
29
|
|
30
|
-
proto_turf = ProtoTurf.new(registry_url: 'http://localhost:8081')
|
30
|
+
proto_turf = ProtoTurf.new(registry_url: 'http://localhost:8081', schema_paths: ['path/to/protos'])
|
31
31
|
message = MyProto::MyMessage.new(field1: 'value1', field2: 42)
|
32
32
|
encoded = proto_turf.encode(message, subject: 'my-subject')
|
33
33
|
|
@@ -38,7 +38,15 @@ decoded_proto_message = proto_turf.decode(encoded_string)
|
|
38
38
|
|
39
39
|
If you're using [buf](https://buf.build/) to manage your Protobuf definitions, you should run `buf export` before using `proto_turf` to ensure that all the dependencies are available as `.proto` files in your project. The actual proto text is needed when registering the schema with the Schema Registry.
|
40
40
|
|
41
|
+
Because `buf export` overwrites/deletes existing files, you should run it into a different directory and provide both as `schema_paths` to the `ProtoTurf` constructor.
|
42
|
+
|
41
43
|
## Notes about usage
|
42
44
|
|
43
45
|
* When decoding, this library does *not* attempt to fully parse the Proto definition stored on the schema registry and generate dynamic classes. Instead, it simply parses out the package and message and assumes that the reader has the message available in the descriptor pool. Any compatibility issues should be detected through normal means, i.e. just by instantiating the message and seeing if any errors are raised.
|
44
46
|
|
47
|
+
### Regenerating test protos
|
48
|
+
Run the following to regenerate:
|
49
|
+
|
50
|
+
```sh
|
51
|
+
protoc -I spec/schemas --ruby_out=spec/gen --ruby_opt=paths=source_relative spec/schemas/**/*.proto
|
52
|
+
```
|
@@ -1,5 +1,4 @@
|
|
1
1
|
class ProtoTurf::CachedConfluentSchemaRegistry
|
2
|
-
|
3
2
|
# @param upstream [ProtoTurf::ConfluentSchemaRegistry]
|
4
3
|
def initialize(upstream)
|
5
4
|
@upstream = upstream
|
@@ -9,7 +8,7 @@ class ProtoTurf::CachedConfluentSchemaRegistry
|
|
9
8
|
end
|
10
9
|
|
11
10
|
# Delegate the following methods to the upstream
|
12
|
-
%i
|
11
|
+
%i[subject_versions schema_subject_versions].each do |name|
|
13
12
|
define_method(name) do |*args|
|
14
13
|
instance_variable_get(:@upstream).send(name, *args)
|
15
14
|
end
|
@@ -29,14 +28,14 @@ class ProtoTurf::CachedConfluentSchemaRegistry
|
|
29
28
|
return @versions_by_subject_and_id[key] if @versions_by_subject_and_id[key]
|
30
29
|
|
31
30
|
results = @upstream.schema_subject_versions(id)
|
32
|
-
@versions_by_subject_and_id[key] = results&.find { |r| r[
|
31
|
+
@versions_by_subject_and_id[key] = results&.find { |r| r["subject"] == subject }&.dig("version")
|
33
32
|
end
|
34
33
|
|
35
34
|
# @param subject [String] the subject to check
|
36
35
|
# @param schema [String] the schema text to check
|
37
36
|
# @return [Boolean] true if we know the schema has been registered for that subject.
|
38
37
|
def registered?(subject, schema)
|
39
|
-
@ids_by_schema[[subject, schema]].
|
38
|
+
@ids_by_schema[[subject, schema]] && !@ids_by_schema[[subject, schema]].empty?
|
40
39
|
end
|
41
40
|
|
42
41
|
# @param subject [String] the subject to register the schema under
|
@@ -47,5 +46,4 @@ class ProtoTurf::CachedConfluentSchemaRegistry
|
|
47
46
|
|
48
47
|
@ids_by_schema[key] ||= @upstream.register(subject, schema, references: references)
|
49
48
|
end
|
50
|
-
|
51
49
|
end
|
@@ -1,8 +1,7 @@
|
|
1
|
-
require
|
1
|
+
require "excon"
|
2
2
|
|
3
3
|
class ProtoTurf
|
4
4
|
class ConfluentSchemaRegistry
|
5
|
-
|
6
5
|
CONTENT_TYPE = "application/vnd.schemaregistry.v1+json".freeze
|
7
6
|
|
8
7
|
def initialize(
|
@@ -24,7 +23,7 @@ class ProtoTurf
|
|
24
23
|
retry_limit: nil
|
25
24
|
)
|
26
25
|
@path_prefix = path_prefix
|
27
|
-
@schema_context_prefix = schema_context.nil? ?
|
26
|
+
@schema_context_prefix = schema_context.nil? ? "" : ":.#{schema_context}:"
|
28
27
|
@schema_context_options = schema_context.nil? ? {} : {query: {subject: @schema_context_prefix}}
|
29
28
|
@logger = logger
|
30
29
|
headers = Excon.defaults[:headers].merge(
|
@@ -57,7 +56,7 @@ class ProtoTurf
|
|
57
56
|
# @return [String] the schema string stored in the registry for the given id
|
58
57
|
def fetch(id)
|
59
58
|
@logger.info "Fetching schema with id #{id}"
|
60
|
-
data = get("/schemas/ids/#{id}", idempotent: true, **@schema_context_options
|
59
|
+
data = get("/schemas/ids/#{id}", idempotent: true, **@schema_context_options)
|
61
60
|
data.fetch("schema")
|
62
61
|
end
|
63
62
|
|
@@ -73,9 +72,9 @@ class ProtoTurf
|
|
73
72
|
# @return [Integer] the ID of the registered schema
|
74
73
|
def register(subject, schema, references: [])
|
75
74
|
data = post("/subjects/#{@schema_context_prefix}#{CGI.escapeURIComponent(subject)}/versions",
|
76
|
-
|
77
|
-
|
78
|
-
|
75
|
+
body: {schemaType: "PROTOBUF",
|
76
|
+
references: references,
|
77
|
+
schema: schema.to_s}.to_json)
|
79
78
|
|
80
79
|
id = data.fetch("id")
|
81
80
|
|
@@ -105,7 +104,7 @@ class ProtoTurf
|
|
105
104
|
end
|
106
105
|
|
107
106
|
def request(path, **options)
|
108
|
-
options = {
|
107
|
+
options = {expects: 200}.merge!(options)
|
109
108
|
path = File.join(@path_prefix, path) unless @path_prefix.nil?
|
110
109
|
response = @connection.request(path: path, **options)
|
111
110
|
JSON.parse(response.body)
|
@@ -113,6 +112,5 @@ class ProtoTurf
|
|
113
112
|
@logger.error("Error while requesting #{path}: #{e.response.body}")
|
114
113
|
raise
|
115
114
|
end
|
116
|
-
|
117
115
|
end
|
118
116
|
end
|
data/lib/proto_turf/version.rb
CHANGED
data/lib/proto_turf.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "logger"
|
2
|
+
require "google/protobuf"
|
3
|
+
require "google/protobuf/well_known_types"
|
4
|
+
require "google/protobuf/descriptor_pb"
|
5
|
+
require "json"
|
6
|
+
require "proto_turf/confluent_schema_registry"
|
7
|
+
require "proto_turf/cached_confluent_schema_registry"
|
4
8
|
|
5
9
|
class ProtoTurf
|
6
10
|
# Provides a way to encode and decode messages without having to embed schemas
|
@@ -15,14 +19,13 @@ class ProtoTurf
|
|
15
19
|
# https://docs.confluent.io/platform/current/schema-registry/fundamentals/serdes-develop/index.html#wire-format
|
16
20
|
MAGIC_BYTE = [0].pack("C").freeze
|
17
21
|
|
18
|
-
|
19
22
|
# Instantiate a new ProtoTurf instance with the given configuration.
|
20
23
|
#
|
21
24
|
# registry - A schema registry object that responds to all methods in the
|
22
25
|
# ProtoTurf::ConfluentSchemaRegistry interface.
|
23
26
|
# registry_url - The String URL of the schema registry that should be used.
|
24
27
|
# schema_context - Schema registry context name (optional)
|
25
|
-
#
|
28
|
+
# schema_paths - The String file system path where local schemas are stored.
|
26
29
|
# registry_path_prefix - The String URL path prefix used to namespace schema registry requests (optional).
|
27
30
|
# logger - The Logger that should be used to log information (optional).
|
28
31
|
# proxy - Forward the request via proxy (optional).
|
@@ -40,7 +43,7 @@ class ProtoTurf
|
|
40
43
|
registry: nil,
|
41
44
|
registry_url: nil,
|
42
45
|
schema_context: nil,
|
43
|
-
|
46
|
+
schema_paths: nil,
|
44
47
|
registry_path_prefix: nil,
|
45
48
|
logger: nil,
|
46
49
|
proxy: nil,
|
@@ -57,7 +60,7 @@ class ProtoTurf
|
|
57
60
|
retry_limit: nil
|
58
61
|
)
|
59
62
|
@logger = logger || Logger.new($stderr)
|
60
|
-
@
|
63
|
+
@paths = Array(schema_paths)
|
61
64
|
@registry = registry || ProtoTurf::CachedConfluentSchemaRegistry.new(
|
62
65
|
ProtoTurf::ConfluentSchemaRegistry.new(
|
63
66
|
registry_url,
|
@@ -101,7 +104,7 @@ class ProtoTurf
|
|
101
104
|
stream.write([id].pack("N"))
|
102
105
|
|
103
106
|
_, indexes = find_index(message.class.descriptor.to_proto,
|
104
|
-
|
107
|
+
file_descriptor.to_proto.message_type)
|
105
108
|
|
106
109
|
if indexes == [0]
|
107
110
|
write_int(stream, 0)
|
@@ -138,7 +141,7 @@ class ProtoTurf
|
|
138
141
|
end
|
139
142
|
|
140
143
|
# The schema id is a 4-byte big-endian integer.
|
141
|
-
schema_id = stream.read(4).
|
144
|
+
schema_id = stream.read(4).unpack1("N")
|
142
145
|
|
143
146
|
# For now, we're only going to support a single message per schema. See
|
144
147
|
# https://docs.confluent.io/platform/current/schema-registry/fundamentals/serdes-develop/index.html#wire-format
|
@@ -161,7 +164,7 @@ class ProtoTurf
|
|
161
164
|
|
162
165
|
private
|
163
166
|
|
164
|
-
def find_index(descriptor, messages, indexes=[])
|
167
|
+
def find_index(descriptor, messages, indexes = [])
|
165
168
|
messages.each_with_index do |sub_descriptor, i|
|
166
169
|
if sub_descriptor == descriptor
|
167
170
|
indexes.push(i)
|
@@ -221,7 +224,7 @@ class ProtoTurf
|
|
221
224
|
raise "Could not find schema for #{full_name}. Make sure the corresponding .proto file has been compiled and loaded."
|
222
225
|
end
|
223
226
|
path = find_descriptor(indexes, descriptor.file_descriptor.to_proto.message_type)
|
224
|
-
correct_message = Google::Protobuf::DescriptorPool.generated_pool.lookup("#{package}.#{path.join(
|
227
|
+
correct_message = Google::Protobuf::DescriptorPool.generated_pool.lookup("#{package}.#{path.join(".")}")
|
225
228
|
correct_message.msgclass.decode(encoded)
|
226
229
|
end
|
227
230
|
|
@@ -230,7 +233,7 @@ class ProtoTurf
|
|
230
233
|
return if @registry.registered?(file_descriptor.name, subject)
|
231
234
|
|
232
235
|
# register dependencies first
|
233
|
-
dependencies = file_descriptor.to_proto.dependency.to_a.reject { |d| d.start_with?(
|
236
|
+
dependencies = file_descriptor.to_proto.dependency.to_a.reject { |d| d.start_with?("google/protobuf/") }
|
234
237
|
versions = dependencies.map do |dependency|
|
235
238
|
dependency_descriptor = @all_schemas[dependency]
|
236
239
|
result = register_schema(dependency_descriptor, subject: dependency_descriptor.name)
|
@@ -238,20 +241,22 @@ class ProtoTurf
|
|
238
241
|
end
|
239
242
|
|
240
243
|
@registry.register(subject,
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
)
|
244
|
+
schema_text(file_descriptor),
|
245
|
+
references: dependencies.map.with_index do |dependency, i|
|
246
|
+
{
|
247
|
+
name: dependency,
|
248
|
+
subject: dependency,
|
249
|
+
version: versions[i]
|
250
|
+
}
|
251
|
+
end)
|
250
252
|
end
|
251
253
|
|
252
254
|
def schema_text(file_descriptor)
|
253
|
-
|
254
|
-
|
255
|
+
@paths.each do |path|
|
256
|
+
filename = "#{path}/#{file_descriptor.name}"
|
257
|
+
return File.read(filename) if File.exist?(filename)
|
258
|
+
end
|
259
|
+
""
|
255
260
|
end
|
256
261
|
|
257
262
|
def load_schemas!
|
@@ -261,10 +266,9 @@ class ProtoTurf
|
|
261
266
|
all_messages.each do |m|
|
262
267
|
file_desc = m.descriptor.file_descriptor
|
263
268
|
file_path = file_desc.name
|
264
|
-
next if file_path.start_with?(
|
269
|
+
next if file_path.start_with?("google/protobuf/") # skip built-in protos
|
265
270
|
|
266
271
|
@all_schemas[file_path] = file_desc
|
267
272
|
end
|
268
273
|
end
|
269
|
-
|
270
274
|
end
|
data/proto_turf.gemspec
CHANGED
@@ -1,27 +1,28 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
3
|
+
require "proto_turf/version"
|
5
4
|
|
6
5
|
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
|
6
|
+
spec.name = "proto_turf"
|
7
|
+
spec.version = ProtoTurf::VERSION
|
8
|
+
spec.authors = ["Daniel Orner"]
|
9
|
+
spec.email = ["daniel.orner@flipp.com"]
|
10
|
+
spec.summary = "Support for Protobuf files in Confluent Schema Registry"
|
11
|
+
spec.homepage = "https://github.com/flipp-oss/proto_turf"
|
12
|
+
spec.license = "MIT"
|
14
13
|
|
15
14
|
spec.metadata["rubygems_mfa_required"] = "true"
|
16
15
|
|
17
|
-
spec.files
|
18
|
-
spec.executables
|
19
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
18
|
spec.require_paths = ["lib"]
|
21
19
|
|
22
20
|
spec.add_dependency "google-protobuf"
|
21
|
+
spec.add_dependency "excon"
|
23
22
|
|
24
23
|
spec.add_development_dependency "bundler", "~> 2.0"
|
25
24
|
spec.add_development_dependency "rake", "~> 13.0"
|
26
25
|
spec.add_development_dependency "rspec", "~> 3.2"
|
26
|
+
spec.add_development_dependency "webmock"
|
27
|
+
spec.add_development_dependency "standardrb"
|
27
28
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
RSpec.describe "encoding" do
|
2
|
+
let(:proto_turf) do
|
3
|
+
ProtoTurf.new(
|
4
|
+
registry_url: "http://localhost:8081",
|
5
|
+
schema_paths: ["spec/schemas"]
|
6
|
+
)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should decode a simple message" do
|
10
|
+
schema = File.read("#{__dir__}/schemas/simple/simple.proto")
|
11
|
+
stub = stub_request(:get, "http://localhost:8081/schemas/ids/15")
|
12
|
+
.to_return_json(body: {schema: schema})
|
13
|
+
msg = Simple::V1::SimpleMessage.new(name: "my name")
|
14
|
+
encoded = "\u0000\u0000\u0000\u0000\u000F\u0000" + msg.to_proto
|
15
|
+
expect(proto_turf.decode(encoded)).to eq(msg)
|
16
|
+
|
17
|
+
# if we do it again we should not see any more requests
|
18
|
+
expect(proto_turf.decode(encoded)).to eq(msg)
|
19
|
+
|
20
|
+
expect(stub).to have_been_requested.once
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should decode a complex message" do
|
24
|
+
schema = File.read("#{__dir__}/schemas/referenced/referer.proto")
|
25
|
+
stub = stub_request(:get, "http://localhost:8081/schemas/ids/20")
|
26
|
+
.to_return_json(body: {schema: schema})
|
27
|
+
msg = Referenced::V1::MessageB::MessageBA.new(
|
28
|
+
simple: Simple::V1::SimpleMessage.new(name: "my name")
|
29
|
+
)
|
30
|
+
encoded = "\u0000\u0000\u0000\u0000\u0014\u0004\u0002\u0000" + msg.to_proto
|
31
|
+
expect(proto_turf.decode(encoded)).to eq(msg)
|
32
|
+
|
33
|
+
# if we do it again we should not see any more requests
|
34
|
+
expect(proto_turf.decode(encoded)).to eq(msg)
|
35
|
+
expect(stub).to have_been_requested.once
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
RSpec.describe "encoding" do
|
2
|
+
let(:proto_turf) do
|
3
|
+
ProtoTurf.new(
|
4
|
+
registry_url: "http://localhost:8081",
|
5
|
+
schema_paths: ["spec/schemas"]
|
6
|
+
)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should encode a simple message" do
|
10
|
+
schema = File.read("#{__dir__}/schemas/simple/simple.proto")
|
11
|
+
stub = stub_request(:post, "http://localhost:8081/subjects/simple/versions")
|
12
|
+
.with(body: {"schemaType" => "PROTOBUF",
|
13
|
+
"references" => [],
|
14
|
+
"schema" => schema}).to_return_json(body: {id: 15})
|
15
|
+
msg = Simple::V1::SimpleMessage.new(name: "my name")
|
16
|
+
encoded = proto_turf.encode(msg, subject: "simple")
|
17
|
+
expect(encoded).to eq("\u0000\u0000\u0000\u0000\u000F\u0000" + msg.to_proto)
|
18
|
+
|
19
|
+
# if we do it again we should not see any more requests
|
20
|
+
encoded2 = proto_turf.encode(msg, subject: "simple")
|
21
|
+
expect(encoded2).to eq(encoded)
|
22
|
+
|
23
|
+
expect(stub).to have_been_requested.once
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should encode a complex message" do
|
27
|
+
schema = File.read("#{__dir__}/schemas/referenced/referer.proto")
|
28
|
+
dep_schema = File.read("#{__dir__}/schemas/simple/simple.proto")
|
29
|
+
dep_stub = stub_request(:post, "http://localhost:8081/subjects/simple%2Fsimple.proto/versions")
|
30
|
+
.with(body: {"schemaType" => "PROTOBUF",
|
31
|
+
"references" => [],
|
32
|
+
"schema" => dep_schema}).to_return_json(body: {id: 15})
|
33
|
+
version_stub = stub_request(:get, "http://localhost:8081/schemas/ids/15/versions")
|
34
|
+
.to_return_json(body: [{version: 1, subject: "simple/simple.proto"}])
|
35
|
+
stub = stub_request(:post, "http://localhost:8081/subjects/referenced/versions")
|
36
|
+
.with(body: {"schemaType" => "PROTOBUF",
|
37
|
+
"references" => [
|
38
|
+
{
|
39
|
+
name: "simple/simple.proto",
|
40
|
+
subject: "simple/simple.proto",
|
41
|
+
version: 1
|
42
|
+
}
|
43
|
+
],
|
44
|
+
"schema" => schema}).to_return_json(body: {id: 20})
|
45
|
+
msg = Referenced::V1::MessageB::MessageBA.new(
|
46
|
+
simple: Simple::V1::SimpleMessage.new(name: "my name")
|
47
|
+
)
|
48
|
+
encoded = proto_turf.encode(msg, subject: "referenced")
|
49
|
+
expect(encoded).to eq("\u0000\u0000\u0000\u0000\u0014\u0004\u0002\u0000" + msg.to_proto)
|
50
|
+
|
51
|
+
# if we do it again we should not see any more requests
|
52
|
+
encoded2 = proto_turf.encode(msg, subject: "referenced")
|
53
|
+
expect(encoded2).to eq(encoded)
|
54
|
+
expect(stub).to have_been_requested.once
|
55
|
+
expect(dep_stub).to have_been_requested.once
|
56
|
+
expect(version_stub).to have_been_requested.once
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
4
|
+
# source: referenced/referer.proto
|
5
|
+
|
6
|
+
require "google/protobuf"
|
7
|
+
|
8
|
+
require "simple/simple_pb"
|
9
|
+
|
10
|
+
descriptor_data = "\n\x18referenced/referer.proto\x12\rreferenced.v1\x1a\x13simple/simple.proto\"j\n\x08MessageA\x1a\x43\n\tMessageAA\x12\x0c\n\x04name\x18\x01 \x01(\t\x12(\n\x06simple\x18\x02 \x01(\x0b\x32\x18.simple.v1.SimpleMessage\x1a\x19\n\tMessageAB\x12\x0c\n\x04name\x18\x01 \x01(\t\"j\n\x08MessageB\x1a\x43\n\tMessageBA\x12\x0c\n\x04name\x18\x01 \x01(\t\x12(\n\x06simple\x18\x02 \x01(\x0b\x32\x18.simple.v1.SimpleMessage\x1a\x19\n\tMessageBB\x12\x0c\n\x04name\x18\x01 \x01(\tb\x06proto3"
|
11
|
+
|
12
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
13
|
+
pool.add_serialized_file(descriptor_data)
|
14
|
+
|
15
|
+
module Referenced
|
16
|
+
module V1
|
17
|
+
MessageA = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("referenced.v1.MessageA").msgclass
|
18
|
+
MessageA::MessageAA = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("referenced.v1.MessageA.MessageAA").msgclass
|
19
|
+
MessageA::MessageAB = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("referenced.v1.MessageA.MessageAB").msgclass
|
20
|
+
MessageB = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("referenced.v1.MessageB").msgclass
|
21
|
+
MessageB::MessageBA = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("referenced.v1.MessageB.MessageBA").msgclass
|
22
|
+
MessageB::MessageBB = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("referenced.v1.MessageB.MessageBB").msgclass
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
4
|
+
# source: simple/simple.proto
|
5
|
+
|
6
|
+
require "google/protobuf"
|
7
|
+
|
8
|
+
descriptor_data = "\n\x13simple/simple.proto\x12\tsimple.v1\"\x1d\n\rSimpleMessage\x12\x0c\n\x04name\x18\x01 \x01(\tb\x06proto3"
|
9
|
+
|
10
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
11
|
+
pool.add_serialized_file(descriptor_data)
|
12
|
+
|
13
|
+
module Simple
|
14
|
+
module V1
|
15
|
+
SimpleMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("simple.v1.SimpleMessage").msgclass
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
syntax = "proto3";
|
2
|
+
|
3
|
+
package referenced.v1;
|
4
|
+
import "simple/simple.proto";
|
5
|
+
|
6
|
+
message MessageA {
|
7
|
+
message MessageAA {
|
8
|
+
string name = 1;
|
9
|
+
simple.v1.SimpleMessage simple = 2;
|
10
|
+
}
|
11
|
+
message MessageAB {
|
12
|
+
string name = 1;
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
message MessageB {
|
17
|
+
message MessageBA {
|
18
|
+
string name = 1;
|
19
|
+
simple.v1.SimpleMessage simple = 2;
|
20
|
+
}
|
21
|
+
message MessageBB {
|
22
|
+
string name = 1;
|
23
|
+
}
|
24
|
+
}
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
|
4
|
+
$LOAD_PATH.unshift(File.expand_path("gen", __dir__))
|
5
|
+
Dir["#{__dir__}/gen/**/*.rb"].each { |file| require file }
|
6
|
+
require "proto_turf"
|
7
|
+
require "webmock/rspec"
|
8
|
+
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.full_backtrace = true
|
11
|
+
|
12
|
+
config.shared_context_metadata_behavior = :apply_to_host_groups
|
13
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: proto_turf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Orner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-08-
|
11
|
+
date: 2025-08-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: google-protobuf
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: excon
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: bundler
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,6 +80,34 @@ dependencies:
|
|
66
80
|
- - "~>"
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: '3.2'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: webmock
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: standardrb
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
69
111
|
description:
|
70
112
|
email:
|
71
113
|
- daniel.orner@flipp.com
|
@@ -73,7 +115,10 @@ executables: []
|
|
73
115
|
extensions: []
|
74
116
|
extra_rdoc_files: []
|
75
117
|
files:
|
118
|
+
- ".rspec"
|
76
119
|
- CHANGELOG.md
|
120
|
+
- Gemfile
|
121
|
+
- Gemfile.lock
|
77
122
|
- LICENSE
|
78
123
|
- README.md
|
79
124
|
- lib/proto_turf.rb
|
@@ -81,6 +126,13 @@ files:
|
|
81
126
|
- lib/proto_turf/confluent_schema_registry.rb
|
82
127
|
- lib/proto_turf/version.rb
|
83
128
|
- proto_turf.gemspec
|
129
|
+
- spec/decoding_spec.rb
|
130
|
+
- spec/encoding_spec.rb
|
131
|
+
- spec/gen/referenced/referer_pb.rb
|
132
|
+
- spec/gen/simple/simple_pb.rb
|
133
|
+
- spec/schemas/referenced/referer.proto
|
134
|
+
- spec/schemas/simple/simple.proto
|
135
|
+
- spec/spec_helper.rb
|
84
136
|
homepage: https://github.com/flipp-oss/proto_turf
|
85
137
|
licenses:
|
86
138
|
- MIT
|