deimos-ruby 2.3.5 → 2.4.0.pre.beta1
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/.rubocop.yml +1 -1
- data/CHANGELOG.md +1 -16
- data/CLAUDE.md +270 -0
- data/README.md +0 -6
- data/deimos-ruby.gemspec +2 -3
- data/lib/deimos/active_record_consume/batch_consumption.rb +1 -19
- data/lib/deimos/active_record_consume/message_consumption.rb +0 -1
- data/lib/deimos/active_record_consumer.rb +0 -1
- data/lib/deimos/active_record_producer.rb +5 -11
- data/lib/deimos/config/configuration.rb +1 -1
- data/lib/deimos/ext/producer_middleware.rb +2 -2
- data/lib/deimos/kafka_source.rb +1 -1
- data/lib/deimos/metrics/minimal_datadog.rb +3 -14
- data/lib/deimos/schema_backends/avro_base.rb +4 -6
- data/lib/deimos/schema_backends/avro_local.rb +13 -12
- data/lib/deimos/schema_backends/avro_schema_registry.rb +14 -15
- data/lib/deimos/schema_backends/avro_validation.rb +1 -1
- data/lib/deimos/schema_backends/base.rb +5 -4
- data/lib/deimos/schema_backends/mock.rb +1 -1
- data/lib/deimos/schema_backends/plain.rb +1 -1
- data/lib/deimos/schema_backends/proto_base.rb +36 -11
- data/lib/deimos/schema_backends/proto_local.rb +5 -5
- data/lib/deimos/schema_backends/proto_schema_registry.rb +32 -7
- data/lib/deimos/transcoder.rb +1 -1
- data/lib/deimos/utils/outbox_producer.rb +1 -1
- data/lib/deimos/version.rb +1 -1
- data/lib/generators/deimos/active_record_generator.rb +1 -1
- data/lib/generators/deimos/schema_class_generator.rb +3 -3
- data/lib/generators/deimos/v2_generator.rb +2 -2
- data/spec/active_record_batch_consumer_association_spec.rb +1 -1
- data/spec/active_record_batch_consumer_spec.rb +0 -85
- data/spec/active_record_consumer_spec.rb +0 -23
- data/spec/gen/sample/v1/sample_key_pb.rb +17 -0
- data/spec/generators/schema_class_generator_spec.rb +1 -1
- data/spec/protos/sample/v1/sample_key.proto +7 -0
- data/spec/schema_backends/avro_base_shared.rb +1 -1
- data/spec/schema_backends/avro_local_spec.rb +1 -8
- data/spec/schema_backends/avro_schema_registry_spec.rb +7 -7
- data/spec/schema_backends/base_spec.rb +2 -2
- data/spec/schema_backends/proto_schema_registry_spec.rb +222 -19
- data/spec/spec_helper.rb +1 -1
- metadata +32 -49
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative 'avro_base'
|
|
4
|
-
require 'avro_turf/messaging'
|
|
5
4
|
|
|
6
5
|
module Deimos
|
|
7
6
|
module SchemaBackends
|
|
@@ -9,27 +8,27 @@ module Deimos
|
|
|
9
8
|
class AvroSchemaRegistry < AvroBase
|
|
10
9
|
# @override
|
|
11
10
|
def decode_payload(payload, schema:)
|
|
12
|
-
|
|
11
|
+
schema_registry.decode(payload.to_s)
|
|
13
12
|
end
|
|
14
13
|
|
|
15
14
|
# @override
|
|
16
|
-
def encode_payload(payload, schema: nil,
|
|
17
|
-
|
|
15
|
+
def encode_payload(payload, schema: nil, subject: nil)
|
|
16
|
+
schema_registry.encode(payload, subject: subject || schema, schema_name: "#{@namespace}.#{schema}")
|
|
18
17
|
end
|
|
19
18
|
|
|
20
19
|
private
|
|
21
20
|
|
|
22
|
-
# @return [
|
|
23
|
-
def
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
21
|
+
# @return [SchemaRegistry::Client]
|
|
22
|
+
def schema_registry
|
|
23
|
+
@schema_registry ||= SchemaRegistry::Client.new(
|
|
24
|
+
registry_url: Deimos.config.schema.registry_url,
|
|
25
|
+
logger: Karafka.logger,
|
|
26
|
+
user: Deimos.config.schema.user,
|
|
27
|
+
password: Deimos.config.schema.password,
|
|
28
|
+
schema_type: SchemaRegistry::Schema::Avro
|
|
29
|
+
)
|
|
30
|
+
SchemaRegistry.avro_schema_path = Deimos.config.schema.path
|
|
31
|
+
@schema_registry
|
|
33
32
|
end
|
|
34
33
|
end
|
|
35
34
|
end
|
|
@@ -56,9 +56,10 @@ module Deimos
|
|
|
56
56
|
# @param schema [String,Symbol]
|
|
57
57
|
# @param topic [String]
|
|
58
58
|
# @return [String]
|
|
59
|
-
def encode(payload, schema: nil, topic: nil)
|
|
59
|
+
def encode(payload, schema: nil, topic: nil, is_key: false)
|
|
60
60
|
validate(payload, schema: schema || @schema)
|
|
61
|
-
|
|
61
|
+
subject = is_key ? "#{topic}-key" : "#{topic}-value"
|
|
62
|
+
encode_payload(payload, schema: schema || @schema, subject: subject)
|
|
62
63
|
end
|
|
63
64
|
|
|
64
65
|
# Decode a payload with a schema. Public method.
|
|
@@ -114,9 +115,9 @@ module Deimos
|
|
|
114
115
|
# Encode a payload. To be defined by subclass.
|
|
115
116
|
# @param payload [Hash]
|
|
116
117
|
# @param schema [String,Symbol]
|
|
117
|
-
# @param
|
|
118
|
+
# @param subject [String]
|
|
118
119
|
# @return [String]
|
|
119
|
-
def encode_payload(_payload, schema:,
|
|
120
|
+
def encode_payload(_payload, schema:, subject: nil)
|
|
120
121
|
raise MissingImplementationError
|
|
121
122
|
end
|
|
122
123
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative 'base'
|
|
4
|
-
require '
|
|
4
|
+
require 'schema_registry_client'
|
|
5
5
|
|
|
6
6
|
module Deimos
|
|
7
7
|
module SchemaBackends
|
|
@@ -24,26 +24,51 @@ module Deimos
|
|
|
24
24
|
float: :float,
|
|
25
25
|
message: :record
|
|
26
26
|
}.freeze
|
|
27
|
+
|
|
27
28
|
def proto_schema(schema=@schema)
|
|
28
|
-
Google::Protobuf::DescriptorPool.generated_pool.lookup(schema)
|
|
29
|
+
proto = Google::Protobuf::DescriptorPool.generated_pool.lookup(schema)
|
|
30
|
+
if proto.nil?
|
|
31
|
+
raise "Could not find Protobuf schema '#{schema}'."
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
proto
|
|
29
35
|
end
|
|
30
36
|
|
|
31
37
|
# @override
|
|
32
38
|
def encode_key(key_id, key, topic: nil)
|
|
33
|
-
if key.
|
|
34
|
-
|
|
39
|
+
if key.respond_to?(:to_h)
|
|
40
|
+
hash = if key_id
|
|
41
|
+
key_id.to_s.split('.')[...-1].each do |k|
|
|
42
|
+
key = key.with_indifferent_access[k]
|
|
43
|
+
end
|
|
44
|
+
key.to_h.with_indifferent_access.slice(key_id.split('.').last)
|
|
45
|
+
else
|
|
46
|
+
key.to_h.sort.to_h
|
|
47
|
+
end
|
|
48
|
+
self.encode_proto_key(hash, topic: topic, field: key_id)
|
|
49
|
+
elsif key_id
|
|
50
|
+
hash = { key_id.to_s.split('.').last => key }
|
|
51
|
+
self.encode_proto_key(hash, topic: topic, field: key_id)
|
|
35
52
|
else
|
|
36
53
|
key.to_s
|
|
37
54
|
end
|
|
38
55
|
end
|
|
39
56
|
|
|
57
|
+
# @param hash [Hash]
|
|
58
|
+
# @return [String]
|
|
59
|
+
def encode_proto_key(hash, topic: nil)
|
|
60
|
+
hash.sort.to_h.to_json
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def decode_proto_key(payload)
|
|
64
|
+
JSON.parse(payload)
|
|
65
|
+
rescue StandardError
|
|
66
|
+
payload
|
|
67
|
+
end
|
|
68
|
+
|
|
40
69
|
# @override
|
|
41
70
|
def decode_key(payload, key_id)
|
|
42
|
-
val =
|
|
43
|
-
JSON.parse(payload)
|
|
44
|
-
rescue StandardError
|
|
45
|
-
payload
|
|
46
|
-
end
|
|
71
|
+
val = decode_proto_key(payload)
|
|
47
72
|
key_id ? val[key_id.to_s] : val
|
|
48
73
|
end
|
|
49
74
|
|
|
@@ -85,8 +110,8 @@ module Deimos
|
|
|
85
110
|
:mock
|
|
86
111
|
end
|
|
87
112
|
|
|
88
|
-
def
|
|
89
|
-
|
|
113
|
+
def supports_key_schemas?
|
|
114
|
+
false
|
|
90
115
|
end
|
|
91
116
|
|
|
92
117
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative 'proto_base'
|
|
4
|
-
require '
|
|
4
|
+
require 'schema_registry_client'
|
|
5
5
|
|
|
6
6
|
module Deimos
|
|
7
7
|
module SchemaBackends
|
|
@@ -14,14 +14,14 @@ module Deimos
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
# @override
|
|
17
|
-
def encode_payload(payload, schema: nil,
|
|
17
|
+
def encode_payload(payload, schema: nil, subject: nil)
|
|
18
18
|
msg = payload.is_a?(Hash) ? proto_schema.msgclass.new(**payload) : payload
|
|
19
19
|
proto_schema.msgclass.encode(msg)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
# @return [
|
|
23
|
-
def self.
|
|
24
|
-
@
|
|
22
|
+
# @return [SchemaRegistry::Client]
|
|
23
|
+
def self.schema_registry
|
|
24
|
+
@schema_registry ||= SchemaRegistry::Client.new(
|
|
25
25
|
registry_url: Deimos.config.schema.registry_url,
|
|
26
26
|
logger: Karafka.logger
|
|
27
27
|
)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative 'proto_base'
|
|
4
|
-
require '
|
|
4
|
+
require 'schema_registry_client'
|
|
5
5
|
|
|
6
6
|
module Deimos
|
|
7
7
|
module SchemaBackends
|
|
@@ -10,22 +10,47 @@ module Deimos
|
|
|
10
10
|
|
|
11
11
|
# @override
|
|
12
12
|
def decode_payload(payload, schema:)
|
|
13
|
-
self.class.
|
|
13
|
+
self.class.schema_registry.decode(payload)
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
# @override
|
|
17
|
-
def encode_payload(payload, schema: nil,
|
|
17
|
+
def encode_payload(payload, schema: nil, subject: nil)
|
|
18
18
|
msg = payload.is_a?(Hash) ? proto_schema.msgclass.new(**payload) : payload
|
|
19
|
-
self.class.
|
|
19
|
+
encoder = subject&.ends_with?('-key') ? self.class.key_schema_registry : self.class.schema_registry
|
|
20
|
+
encoder.encode(msg, subject: subject)
|
|
20
21
|
end
|
|
21
22
|
|
|
22
|
-
# @
|
|
23
|
-
def
|
|
24
|
-
|
|
23
|
+
# @override
|
|
24
|
+
def encode_proto_key(key, topic: nil, field: nil)
|
|
25
|
+
schema_text = SchemaRegistry::Output::JsonSchema.output(proto_schema.to_proto, path: field)
|
|
26
|
+
self.class.key_schema_registry.encode(key, subject: "#{topic}-key", schema_text: schema_text)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @override
|
|
30
|
+
def decode_proto_key(payload)
|
|
31
|
+
self.class.key_schema_registry.decode(payload)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# @return [SchemaRegistry::Client]
|
|
35
|
+
def self.schema_registry
|
|
36
|
+
@schema_registry ||= SchemaRegistry::Client.new(
|
|
25
37
|
registry_url: Deimos.config.schema.registry_url,
|
|
38
|
+
user: Deimos.config.schema.user,
|
|
39
|
+
password: Deimos.config.schema.password,
|
|
26
40
|
logger: Karafka.logger
|
|
27
41
|
)
|
|
28
42
|
end
|
|
43
|
+
|
|
44
|
+
def self.key_schema_registry
|
|
45
|
+
@key_schema_registry ||= SchemaRegistry::Client.new(
|
|
46
|
+
registry_url: Deimos.config.schema.registry_url,
|
|
47
|
+
user: Deimos.config.schema.user,
|
|
48
|
+
password: Deimos.config.schema.password,
|
|
49
|
+
logger: Karafka.logger,
|
|
50
|
+
schema_type: SchemaRegistry::Schema::ProtoJsonSchema
|
|
51
|
+
)
|
|
52
|
+
end
|
|
53
|
+
|
|
29
54
|
end
|
|
30
55
|
end
|
|
31
56
|
end
|
data/lib/deimos/transcoder.rb
CHANGED
|
@@ -205,7 +205,7 @@ module Deimos
|
|
|
205
205
|
batch_size = batch.size
|
|
206
206
|
current_index = 0
|
|
207
207
|
|
|
208
|
-
batch[current_index
|
|
208
|
+
batch[current_index..].in_groups_of(batch_size, false).each do |group|
|
|
209
209
|
@logger.debug("Publishing #{group.size} messages to #{@current_topic}")
|
|
210
210
|
Deimos.producer_for(@current_topic).produce_many_sync(group)
|
|
211
211
|
current_index += group.size
|
data/lib/deimos/version.rb
CHANGED
|
@@ -13,7 +13,7 @@ module Deimos
|
|
|
13
13
|
# @return [Array<Symbol>]
|
|
14
14
|
SPECIAL_TYPES = %i(record enum).freeze
|
|
15
15
|
# @return [String]
|
|
16
|
-
INITIALIZE_WHITESPACE = "\n#{' ' * 19}"
|
|
16
|
+
INITIALIZE_WHITESPACE = "\n#{' ' * 19}".freeze
|
|
17
17
|
# @return [Array<String>]
|
|
18
18
|
IGNORE_DEFAULTS = %w(message_id timestamp).freeze
|
|
19
19
|
# @return [String]
|
|
@@ -192,7 +192,7 @@ module Deimos
|
|
|
192
192
|
|
|
193
193
|
def generate_from_schema_files(found_schemas)
|
|
194
194
|
path = Deimos.config.schema.path || Deimos.config.schema.paths[:avro].first
|
|
195
|
-
schema_store =
|
|
195
|
+
schema_store = SchemaRegistry::AvroSchemaStore.new(path: path)
|
|
196
196
|
schema_store.load_schemas!
|
|
197
197
|
schema_store.schemas.values.sort_by { |s| "#{s.namespace}#{s.name}" }.each do |schema|
|
|
198
198
|
name = "#{schema.namespace}.#{schema.name}"
|
|
@@ -265,7 +265,7 @@ module Deimos
|
|
|
265
265
|
end
|
|
266
266
|
|
|
267
267
|
result = "def initialize(_from_message: false, #{arguments.first}"
|
|
268
|
-
arguments[1
|
|
268
|
+
arguments[1..].each_with_index do |arg, _i|
|
|
269
269
|
result += ",#{INITIALIZE_WHITESPACE}#{arg}"
|
|
270
270
|
end
|
|
271
271
|
"#{result})"
|
|
@@ -119,7 +119,7 @@ module Deimos
|
|
|
119
119
|
end
|
|
120
120
|
|
|
121
121
|
def consumer_configs
|
|
122
|
-
deimos_config.consumer_objects.group_by(&:group_id).
|
|
122
|
+
deimos_config.consumer_objects.group_by(&:group_id).to_h do |group_id, consumers|
|
|
123
123
|
[group_id, consumers.map do |consumer|
|
|
124
124
|
kafka_configs = {}
|
|
125
125
|
kafka_configs['auto.offset.reset'] = consumer.start_from_beginning ? 'earliest' : 'latest'
|
|
@@ -159,7 +159,7 @@ module Deimos
|
|
|
159
159
|
configs[:each_message] = true unless consumer.delivery.to_s == 'inline_batch'
|
|
160
160
|
configs
|
|
161
161
|
end]
|
|
162
|
-
|
|
162
|
+
end
|
|
163
163
|
end
|
|
164
164
|
|
|
165
165
|
def producer_configs
|
|
@@ -70,7 +70,7 @@ module ActiveRecordBatchConsumerTest # rubocop:disable Metrics/ModuleLength
|
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
before(:each) do
|
|
73
|
-
ActiveRecord::Base.connection.truncate_tables(
|
|
73
|
+
ActiveRecord::Base.connection.truncate_tables(%i(widgets details locales))
|
|
74
74
|
Widget.create!(test_id: 'bad_id', some_int: 100) # should not show up
|
|
75
75
|
end
|
|
76
76
|
|
|
@@ -57,12 +57,6 @@ module ActiveRecordBatchConsumerTest
|
|
|
57
57
|
Class.new(described_class) do
|
|
58
58
|
record_class Widget
|
|
59
59
|
compacted false
|
|
60
|
-
|
|
61
|
-
def process_message?(payload)
|
|
62
|
-
return true if payload.nil?
|
|
63
|
-
|
|
64
|
-
payload['test_id'] != 'skipme'
|
|
65
|
-
end
|
|
66
60
|
end
|
|
67
61
|
end
|
|
68
62
|
|
|
@@ -109,27 +103,6 @@ module ActiveRecordBatchConsumerTest
|
|
|
109
103
|
)
|
|
110
104
|
end
|
|
111
105
|
|
|
112
|
-
it 'should not create records for messages that return false from process_message?' do
|
|
113
|
-
publish_batch(
|
|
114
|
-
[
|
|
115
|
-
{ key: 1,
|
|
116
|
-
payload: { test_id: 'abc', some_int: 3 } },
|
|
117
|
-
{ key: 2,
|
|
118
|
-
payload: { test_id: 'skipme', some_int: 4 } },
|
|
119
|
-
{ key: 3,
|
|
120
|
-
payload: { test_id: 'ghi', some_int: 5 } }
|
|
121
|
-
]
|
|
122
|
-
)
|
|
123
|
-
|
|
124
|
-
expect(all_widgets).
|
|
125
|
-
to contain_exactly(
|
|
126
|
-
have_attributes(id: 1, test_id: 'abc', some_int: 3, updated_at: start,
|
|
127
|
-
created_at: start),
|
|
128
|
-
have_attributes(id: 3, test_id: 'ghi', some_int: 5, updated_at: start,
|
|
129
|
-
created_at: start)
|
|
130
|
-
)
|
|
131
|
-
end
|
|
132
|
-
|
|
133
106
|
it 'should handle deleting a record that doesn\'t exist' do
|
|
134
107
|
publish_batch(
|
|
135
108
|
[
|
|
@@ -832,64 +805,6 @@ module ActiveRecordBatchConsumerTest
|
|
|
832
805
|
|
|
833
806
|
end
|
|
834
807
|
|
|
835
|
-
describe 'post_process_batch' do
|
|
836
|
-
before(:each) do
|
|
837
|
-
register_consumer(consumer_class,
|
|
838
|
-
'MySchema',
|
|
839
|
-
key_config: { plain: true })
|
|
840
|
-
MyBatchConsumer.last_post_process_batch = nil
|
|
841
|
-
end
|
|
842
|
-
|
|
843
|
-
let(:consumer_class) do
|
|
844
|
-
Class.new(described_class) do
|
|
845
|
-
class << self
|
|
846
|
-
attr_accessor :last_post_process_batch
|
|
847
|
-
end
|
|
848
|
-
|
|
849
|
-
record_class Widget
|
|
850
|
-
compacted false
|
|
851
|
-
|
|
852
|
-
def post_process_batch(messages)
|
|
853
|
-
self.class.last_post_process_batch = messages
|
|
854
|
-
end
|
|
855
|
-
|
|
856
|
-
def process_message?(payload)
|
|
857
|
-
payload['test_id'] != 'skipme'
|
|
858
|
-
end
|
|
859
|
-
end
|
|
860
|
-
end
|
|
861
|
-
|
|
862
|
-
it 'is called after the batch is processed with the processed messages' do
|
|
863
|
-
publish_batch(
|
|
864
|
-
[
|
|
865
|
-
{ key: 1,
|
|
866
|
-
payload: { test_id: 'abc', some_int: 3 } },
|
|
867
|
-
{ key: 2,
|
|
868
|
-
payload: { test_id: 'def', some_int: 4 } }
|
|
869
|
-
]
|
|
870
|
-
)
|
|
871
|
-
expect(MyBatchConsumer.last_post_process_batch.map(&:payload).map do |p|
|
|
872
|
-
p[:test_id]
|
|
873
|
-
end).to contain_exactly('abc', 'def')
|
|
874
|
-
end
|
|
875
|
-
|
|
876
|
-
it 'is called with filtered messages when process_message? excludes some' do
|
|
877
|
-
publish_batch(
|
|
878
|
-
[
|
|
879
|
-
{ key: 1,
|
|
880
|
-
payload: { test_id: 'abc', some_int: 3 } },
|
|
881
|
-
{ key: 2,
|
|
882
|
-
payload: { test_id: 'skipme', some_int: 4 } },
|
|
883
|
-
{ key: 3,
|
|
884
|
-
payload: { test_id: 'ghi', some_int: 5 } }
|
|
885
|
-
]
|
|
886
|
-
)
|
|
887
|
-
|
|
888
|
-
expect(MyBatchConsumer.last_post_process_batch.size).to eq(2)
|
|
889
|
-
expect(MyBatchConsumer.last_post_process_batch.map(&:key).map(&:to_i)).to contain_exactly(1, 3)
|
|
890
|
-
end
|
|
891
|
-
end
|
|
892
|
-
|
|
893
808
|
end
|
|
894
809
|
end
|
|
895
810
|
# rubocop:enable Lint/ConstantDefinitionInBlock
|
|
@@ -255,29 +255,6 @@ module ActiveRecordConsumerTest
|
|
|
255
255
|
expect(Widget.find_by_test_id('id2').some_int).to eq(4)
|
|
256
256
|
end
|
|
257
257
|
|
|
258
|
-
it 'should handle record_class as a string' do
|
|
259
|
-
consumer_class = Class.new(Deimos::ActiveRecordConsumer) do
|
|
260
|
-
record_class 'ActiveRecordConsumerTest::Widget'
|
|
261
|
-
end
|
|
262
|
-
stub_const('MyStringRecordClassConsumer', consumer_class)
|
|
263
|
-
Karafka::App.routes.redraw do
|
|
264
|
-
topic 'my-topic-string' do
|
|
265
|
-
consumer MyStringRecordClassConsumer
|
|
266
|
-
schema 'MySchema'
|
|
267
|
-
namespace 'com.my-namespace'
|
|
268
|
-
key_config plain: true
|
|
269
|
-
end
|
|
270
|
-
end
|
|
271
|
-
|
|
272
|
-
expect(Widget.count).to eq(0)
|
|
273
|
-
test_consume_message(MyStringRecordClassConsumer, {
|
|
274
|
-
test_id: 'abc',
|
|
275
|
-
some_int: 3
|
|
276
|
-
}, call_original: true, key: 5)
|
|
277
|
-
expect(Widget.count).to eq(1)
|
|
278
|
-
expect(Widget.last.test_id).to eq('abc')
|
|
279
|
-
end
|
|
280
|
-
|
|
281
258
|
it 'should not create record of process_message returns false' do
|
|
282
259
|
allow_any_instance_of(MyConsumer).to receive(:process_message?).and_return(false)
|
|
283
260
|
expect(Widget.count).to eq(0)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
|
+
# source: sample/v1/sample_key.proto
|
|
4
|
+
|
|
5
|
+
require 'google/protobuf'
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
descriptor_data = "\n\x1asample/v1/sample_key.proto\x12\tsample.v1\"\x1f\n\x10SampleMessageKey\x12\x0b\n\x03str\x18\x01 \x01(\tb\x06proto3"
|
|
9
|
+
|
|
10
|
+
pool = ::Google::Protobuf::DescriptorPool.generated_pool
|
|
11
|
+
pool.add_serialized_file(descriptor_data)
|
|
12
|
+
|
|
13
|
+
module Sample
|
|
14
|
+
module V1
|
|
15
|
+
SampleMessageKey = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("sample.v1.SampleMessageKey").msgclass
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -20,7 +20,7 @@ end
|
|
|
20
20
|
|
|
21
21
|
RSpec.describe Deimos::Generators::SchemaClassGenerator do
|
|
22
22
|
let(:schema_class_path) { 'spec/app/lib/schema_classes' }
|
|
23
|
-
let(:files) { Dir["#{schema_class_path}/**/*.rb"].
|
|
23
|
+
let(:files) { Dir["#{schema_class_path}/**/*.rb"].to_h { |f| [f, File.read(f)]} }
|
|
24
24
|
|
|
25
25
|
before(:each) do
|
|
26
26
|
Deimos.config.reset!
|
|
@@ -66,7 +66,7 @@ RSpec.shared_examples_for('an Avro backend') do
|
|
|
66
66
|
expect(backend.encode_key('test_id', 1, topic: 'topic')).to eq('itsme')
|
|
67
67
|
expect(backend).to have_received(:encode).
|
|
68
68
|
with({ 'test_id' => 1 }, { schema: 'MySchema_key', topic: 'topic' })
|
|
69
|
-
expect(backend.schema_store.find('
|
|
69
|
+
expect(backend.schema_store.find('com.my-namespace.MySchema_key').to_avro).
|
|
70
70
|
to eq(
|
|
71
71
|
'doc' => 'Key for com.my-namespace.MySchema - autogenerated by Deimos',
|
|
72
72
|
'fields' => [
|
|
@@ -15,17 +15,10 @@ RSpec.describe Deimos::SchemaBackends::AvroLocal do
|
|
|
15
15
|
it_should_behave_like 'an Avro backend'
|
|
16
16
|
|
|
17
17
|
it 'should encode and decode correctly' do
|
|
18
|
-
avro_turf = instance_double(AvroTurf)
|
|
19
|
-
allow(avro_turf).to receive_messages(encode: 'encoded-payload', decode: payload)
|
|
20
|
-
allow(backend).to receive(:avro_turf).and_return(avro_turf)
|
|
21
18
|
results = backend.encode(payload)
|
|
22
|
-
expect(results).to
|
|
19
|
+
expect(results).to start_with("Obj\u0001\u0004\u0014avro.codec\bnull\u0016avro.schema\x94")
|
|
23
20
|
results = backend.decode(results)
|
|
24
21
|
expect(results).to eq(payload)
|
|
25
|
-
expect(avro_turf).to have_received(:encode).
|
|
26
|
-
with(payload, schema_name: 'MySchema', namespace: 'com.my-namespace')
|
|
27
|
-
expect(avro_turf).to have_received(:decode).
|
|
28
|
-
with('encoded-payload', schema_name: 'MySchema', namespace: 'com.my-namespace')
|
|
29
22
|
end
|
|
30
23
|
|
|
31
24
|
end
|
|
@@ -15,17 +15,17 @@ RSpec.describe Deimos::SchemaBackends::AvroSchemaRegistry do
|
|
|
15
15
|
it_should_behave_like 'an Avro backend'
|
|
16
16
|
|
|
17
17
|
it 'should encode and decode correctly' do
|
|
18
|
-
|
|
19
|
-
allow(
|
|
20
|
-
allow(backend).to receive(:
|
|
18
|
+
schema_registry = instance_double(SchemaRegistry::Client)
|
|
19
|
+
allow(schema_registry).to receive_messages(encode: 'encoded-payload', decode: payload)
|
|
20
|
+
allow(backend).to receive(:schema_registry).and_return(schema_registry)
|
|
21
21
|
results = backend.encode(payload, topic: 'topic')
|
|
22
22
|
expect(results).to eq('encoded-payload')
|
|
23
23
|
results = backend.decode(results)
|
|
24
24
|
expect(results).to eq(payload)
|
|
25
|
-
expect(
|
|
26
|
-
with(payload, schema_name: 'MySchema', subject: 'topic')
|
|
27
|
-
expect(
|
|
28
|
-
with('encoded-payload'
|
|
25
|
+
expect(schema_registry).to have_received(:encode).
|
|
26
|
+
with(payload, schema_name: 'com.my-namespace.MySchema', subject: 'topic-value')
|
|
27
|
+
expect(schema_registry).to have_received(:decode).
|
|
28
|
+
with('encoded-payload')
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
end
|
|
@@ -6,13 +6,13 @@ describe Deimos::SchemaBackends::Base do
|
|
|
6
6
|
|
|
7
7
|
it 'should validate on encode' do
|
|
8
8
|
expect(backend).to receive(:validate).with(payload, schema: 'schema')
|
|
9
|
-
expect(backend).to receive(:encode_payload).with(payload, schema: 'schema',
|
|
9
|
+
expect(backend).to receive(:encode_payload).with(payload, schema: 'schema', subject: 'topic-value')
|
|
10
10
|
backend.encode(payload, topic: 'topic')
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
it 'should validate and encode a passed schema' do
|
|
14
14
|
expect(backend).to receive(:validate).with(payload, schema: 'schema2')
|
|
15
|
-
expect(backend).to receive(:encode_payload).with(payload, schema: 'schema2',
|
|
15
|
+
expect(backend).to receive(:encode_payload).with(payload, schema: 'schema2', subject: 'topic-value')
|
|
16
16
|
backend.encode(payload, schema: 'schema2', topic: 'topic')
|
|
17
17
|
end
|
|
18
18
|
|