deimos-ruby 2.2.0 → 2.2.2
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 +33 -30
- data/CHANGELOG.md +10 -0
- data/Gemfile +0 -6
- data/deimos-ruby.gemspec +15 -11
- data/karafka.rb +7 -4
- data/lib/deimos/active_record_consume/batch_consumption.rb +7 -7
- data/lib/deimos/active_record_consume/batch_record.rb +2 -2
- data/lib/deimos/active_record_consume/message_consumption.rb +6 -5
- data/lib/deimos/active_record_consume/schema_model_converter.rb +2 -2
- data/lib/deimos/active_record_consumer.rb +1 -0
- data/lib/deimos/active_record_producer.rb +4 -2
- data/lib/deimos/backends/base.rb +1 -3
- data/lib/deimos/backends/outbox.rb +1 -1
- data/lib/deimos/config/configuration.rb +88 -75
- data/lib/deimos/consume/batch_consumption.rb +5 -5
- data/lib/deimos/consume/message_consumption.rb +3 -3
- data/lib/deimos/ext/consumer_route.rb +3 -3
- data/lib/deimos/ext/producer_metrics_listener.rb +2 -2
- data/lib/deimos/ext/producer_middleware.rb +19 -15
- data/lib/deimos/ext/producer_route.rb +4 -2
- data/lib/deimos/ext/routing_defaults.rb +9 -7
- data/lib/deimos/ext/schema_route.rb +22 -15
- data/lib/deimos/kafka_message.rb +1 -1
- data/lib/deimos/kafka_source.rb +36 -31
- data/lib/deimos/kafka_topic_info.rb +1 -1
- data/lib/deimos/logging.rb +20 -19
- data/lib/deimos/message.rb +1 -1
- data/lib/deimos/metrics/minimal_datadog_listener.rb +19 -6
- data/lib/deimos/metrics/provider.rb +4 -4
- data/lib/deimos/producer.rb +3 -1
- data/lib/deimos/railtie.rb +1 -1
- data/lib/deimos/schema_backends/avro_base.rb +1 -1
- data/lib/deimos/schema_backends/avro_schema_coercer.rb +46 -27
- data/lib/deimos/schema_backends/avro_schema_registry.rb +8 -8
- data/lib/deimos/schema_backends/base.rb +9 -9
- data/lib/deimos/schema_backends/plain.rb +1 -1
- data/lib/deimos/schema_backends/proto_base.rb +7 -5
- data/lib/deimos/schema_backends/proto_local.rb +0 -2
- data/lib/deimos/schema_backends/proto_schema_registry.rb +0 -2
- data/lib/deimos/schema_class/base.rb +1 -1
- data/lib/deimos/schema_class/record.rb +3 -3
- data/lib/deimos/test_helpers.rb +31 -26
- data/lib/deimos/tracing/provider.rb +5 -5
- data/lib/deimos/transcoder.rb +6 -2
- data/lib/deimos/utils/db_poller/base.rb +3 -3
- data/lib/deimos/utils/deadlock_retry.rb +2 -2
- data/lib/deimos/utils/outbox_producer.rb +14 -14
- data/lib/deimos/version.rb +1 -1
- data/lib/deimos.rb +4 -4
- data/lib/generators/deimos/active_record_generator.rb +2 -1
- data/lib/generators/deimos/db_poller_generator.rb +1 -0
- data/lib/generators/deimos/outbox_backend_generator.rb +1 -0
- data/lib/generators/deimos/schema_class_generator.rb +3 -2
- data/lib/generators/deimos/v2_generator.rb +184 -155
- data/spec/active_record_batch_consumer_association_spec.rb +6 -2
- data/spec/active_record_batch_consumer_spec.rb +83 -106
- data/spec/active_record_consume/batch_consumption_spec.rb +27 -28
- data/spec/active_record_consume/batch_slicer_spec.rb +4 -12
- data/spec/active_record_consume/mass_updater_spec.rb +42 -46
- data/spec/active_record_consume/schema_model_converter_spec.rb +1 -1
- data/spec/active_record_consumer_spec.rb +7 -5
- data/spec/active_record_producer_spec.rb +83 -73
- data/spec/backends/outbox_spec.rb +1 -1
- data/spec/batch_consumer_spec.rb +20 -20
- data/spec/consumer_spec.rb +23 -12
- data/spec/gen/sample/v1/sample_pb.rb +3 -3
- data/spec/generators/active_record_generator_spec.rb +4 -4
- data/spec/generators/schema_class/my_schema_with_circular_reference_spec.rb +2 -1
- data/spec/generators/schema_class/my_schema_with_complex_types_spec.rb +9 -2
- data/spec/generators/schema_class_generator_spec.rb +5 -5
- data/spec/kafka_source_spec.rb +13 -6
- data/spec/kafka_topic_info_spec.rb +7 -7
- data/spec/karafka/karafka.rb +6 -5
- data/spec/karafka_config/karafka_spec.rb +22 -19
- data/spec/logging_spec.rb +2 -0
- data/spec/producer_spec.rb +25 -20
- data/spec/schema_backends/avro_base_shared.rb +8 -8
- data/spec/schema_backends/avro_local_spec.rb +5 -6
- data/spec/schema_backends/avro_schema_registry_spec.rb +5 -6
- data/spec/schema_backends/proto_schema_registry_spec.rb +9 -12
- data/spec/schemas/my_namespace/generated.rb +1 -2
- data/spec/schemas/my_namespace/my_schema_with_complex_type.rb +5 -8
- data/spec/schemas/my_namespace/my_schema_with_union_type.rb +22 -23
- data/spec/spec_helper.rb +13 -17
- data/spec/utils/db_poller_spec.rb +5 -5
- data/spec/utils/deadlock_retry_spec.rb +1 -4
- data/spec/utils/outbox_producer_spec.rb +36 -24
- metadata +68 -161
- data/.ruby-version +0 -1
|
@@ -33,7 +33,7 @@ each_db_config(Deimos::KafkaTopicInfo) do
|
|
|
33
33
|
locked_at: nil, error: true)
|
|
34
34
|
expect(described_class.lock('my-topic', 'abc')).to be_falsey
|
|
35
35
|
expect(described_class.count).to eq(1)
|
|
36
|
-
expect(described_class.first.locked_by).to
|
|
36
|
+
expect(described_class.first.locked_by).to be_nil
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
specify '#clear_lock' do
|
|
@@ -47,15 +47,15 @@ each_db_config(Deimos::KafkaTopicInfo) do
|
|
|
47
47
|
Deimos::KafkaTopicInfo.clear_lock('my-topic', 'abc')
|
|
48
48
|
expect(Deimos::KafkaTopicInfo.count).to eq(2)
|
|
49
49
|
record = Deimos::KafkaTopicInfo.first
|
|
50
|
-
expect(record.locked_by).to
|
|
51
|
-
expect(record.locked_at).to
|
|
52
|
-
expect(record.error).to
|
|
50
|
+
expect(record.locked_by).to be_nil
|
|
51
|
+
expect(record.locked_at).to be_nil
|
|
52
|
+
expect(record.error).to be(false)
|
|
53
53
|
expect(record.retries).to eq(0)
|
|
54
54
|
expect(record.last_processed_at.in_time_zone.to_s).to eq(Time.zone.now.to_s)
|
|
55
55
|
record = Deimos::KafkaTopicInfo.last
|
|
56
|
-
expect(record.locked_by).not_to
|
|
57
|
-
expect(record.locked_at).not_to
|
|
58
|
-
expect(record.error).not_to
|
|
56
|
+
expect(record.locked_by).not_to be_nil
|
|
57
|
+
expect(record.locked_at).not_to be_nil
|
|
58
|
+
expect(record.error).not_to be(false)
|
|
59
59
|
expect(record.retries).not_to eq(0)
|
|
60
60
|
expect(record.last_processed_at.in_time_zone.to_s).to eq(20.seconds.ago.to_s)
|
|
61
61
|
end
|
data/spec/karafka/karafka.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
class KarafkaApp < Karafka::App
|
|
3
4
|
setup do |config|
|
|
4
5
|
config.kafka = { 'bootstrap.servers': '127.0.0.1:9092' }
|
|
@@ -52,11 +53,11 @@ class KarafkaApp < Karafka::App
|
|
|
52
53
|
# You need to define the topic per each queue name you use
|
|
53
54
|
# active_job_topic :default
|
|
54
55
|
# topic :example do
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
# Uncomment this if you want Karafka to manage your topics configuration
|
|
57
|
+
# Managing topics configuration via routing will allow you to ensure config consistency
|
|
58
|
+
# across multiple environments
|
|
59
|
+
#
|
|
60
|
+
# config(partitions: 2, 'cleanup.policy': 'compact')
|
|
60
61
|
# consumer ExampleConsumer
|
|
61
62
|
# end
|
|
62
63
|
end
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rubocop:disable Style/GlobalVars
|
|
4
|
+
RSpec.describe Karafka::Routing::Topic do
|
|
2
5
|
before(:each) do
|
|
3
6
|
KarafkaApp.routes.clear
|
|
4
7
|
$found_stuff = nil
|
|
@@ -13,8 +16,7 @@ RSpec.describe 'Karafka configs' do
|
|
|
13
16
|
end
|
|
14
17
|
|
|
15
18
|
let(:producer_class) do
|
|
16
|
-
Class.new(Deimos::Producer)
|
|
17
|
-
end
|
|
19
|
+
Class.new(Deimos::Producer)
|
|
18
20
|
end
|
|
19
21
|
|
|
20
22
|
describe 'producers' do
|
|
@@ -31,8 +33,8 @@ RSpec.describe 'Karafka configs' do
|
|
|
31
33
|
key_config(none: true)
|
|
32
34
|
end
|
|
33
35
|
end
|
|
34
|
-
producer_class.publish({test_id:
|
|
35
|
-
expect('MyTopic').to have_sent({test_id:
|
|
36
|
+
producer_class.publish({ test_id: 'id1', some_int: 5 })
|
|
37
|
+
expect('MyTopic').to have_sent({ test_id: 'id1', some_int: 5 })
|
|
36
38
|
end
|
|
37
39
|
|
|
38
40
|
it 'should work with key plain' do
|
|
@@ -41,11 +43,11 @@ RSpec.describe 'Karafka configs' do
|
|
|
41
43
|
producer_class MyProducer
|
|
42
44
|
schema 'MySchema'
|
|
43
45
|
namespace 'com.my-namespace'
|
|
44
|
-
key_config({plain: true})
|
|
46
|
+
key_config({ plain: true })
|
|
45
47
|
end
|
|
46
48
|
end
|
|
47
|
-
producer_class.publish({test_id:
|
|
48
|
-
expect('MyTopic').to have_sent({test_id:
|
|
49
|
+
producer_class.publish({ test_id: 'id1', some_int: 5, payload_key: 'key' })
|
|
50
|
+
expect('MyTopic').to have_sent({ test_id: 'id1', some_int: 5 }, 'key')
|
|
49
51
|
end
|
|
50
52
|
|
|
51
53
|
it 'should work with key field' do
|
|
@@ -54,11 +56,11 @@ RSpec.describe 'Karafka configs' do
|
|
|
54
56
|
producer_class MyProducer
|
|
55
57
|
schema 'MySchema'
|
|
56
58
|
namespace 'com.my-namespace'
|
|
57
|
-
key_config({field: :test_id})
|
|
59
|
+
key_config({ field: :test_id })
|
|
58
60
|
end
|
|
59
61
|
end
|
|
60
|
-
producer_class.publish({test_id:
|
|
61
|
-
expect('MyTopic').to have_sent({test_id:
|
|
62
|
+
producer_class.publish({ test_id: 'id1', some_int: 5 })
|
|
63
|
+
expect('MyTopic').to have_sent({ test_id: 'id1', some_int: 5 }, 'id1')
|
|
62
64
|
end
|
|
63
65
|
|
|
64
66
|
it 'should work with key schema' do
|
|
@@ -67,11 +69,11 @@ RSpec.describe 'Karafka configs' do
|
|
|
67
69
|
producer_class MyProducer
|
|
68
70
|
schema 'MySchema'
|
|
69
71
|
namespace 'com.my-namespace'
|
|
70
|
-
key_config({schema: 'MySchema_key'})
|
|
72
|
+
key_config({ schema: 'MySchema_key' })
|
|
71
73
|
end
|
|
72
74
|
end
|
|
73
|
-
producer_class.publish({test_id:
|
|
74
|
-
expect('MyTopic').to have_sent({test_id:
|
|
75
|
+
producer_class.publish({ test_id: 'id1', some_int: 5, payload_key: { test_id: 'id3' } })
|
|
76
|
+
expect('MyTopic').to have_sent({ test_id: 'id1', some_int: 5 }, { test_id: 'id3' })
|
|
75
77
|
end
|
|
76
78
|
|
|
77
79
|
end
|
|
@@ -83,15 +85,16 @@ RSpec.describe 'Karafka configs' do
|
|
|
83
85
|
consumer MyConsumer
|
|
84
86
|
schema 'MySchema'
|
|
85
87
|
namespace 'com.my-namespace'
|
|
86
|
-
key_config({field: :test_id})
|
|
88
|
+
key_config({ field: :test_id })
|
|
87
89
|
end
|
|
88
90
|
end
|
|
89
91
|
|
|
90
|
-
test_consume_message('MyTopic', {test_id:
|
|
91
|
-
expect($found_stuff).to eq({'test_id' =>
|
|
92
|
+
test_consume_message('MyTopic', { test_id: 'id1', some_int: 5 }, key: 'id1')
|
|
93
|
+
expect($found_stuff).to eq({ 'test_id' => 'id1', 'some_int' => 5 })
|
|
92
94
|
$found_stuff = nil
|
|
93
|
-
test_consume_message(MyConsumer, {test_id:
|
|
94
|
-
expect($found_stuff).to eq({'test_id' =>
|
|
95
|
+
test_consume_message(MyConsumer, { test_id: 'id1', some_int: 5 }, key: 'id1')
|
|
96
|
+
expect($found_stuff).to eq({ 'test_id' => 'id1', 'some_int' => 5 })
|
|
95
97
|
end
|
|
96
98
|
|
|
97
99
|
end
|
|
100
|
+
# rubocop:enable Style/GlobalVars
|
data/spec/logging_spec.rb
CHANGED
data/spec/producer_spec.rb
CHANGED
|
@@ -5,10 +5,10 @@ module ProducerTest
|
|
|
5
5
|
describe Deimos::Producer do
|
|
6
6
|
|
|
7
7
|
prepend_before(:each) do
|
|
8
|
-
producer_class = Class.new(
|
|
8
|
+
producer_class = Class.new(described_class)
|
|
9
9
|
stub_const('MyProducer', producer_class)
|
|
10
10
|
|
|
11
|
-
producer_class = Class.new(
|
|
11
|
+
producer_class = Class.new(described_class)
|
|
12
12
|
stub_const('MyProducerWithID', producer_class)
|
|
13
13
|
|
|
14
14
|
producer_class = Class.new(Deimos::Producer) do
|
|
@@ -19,16 +19,16 @@ module ProducerTest
|
|
|
19
19
|
end
|
|
20
20
|
stub_const('MyNonEncodedProducer', producer_class)
|
|
21
21
|
|
|
22
|
-
producer_class = Class.new(
|
|
22
|
+
producer_class = Class.new(described_class)
|
|
23
23
|
stub_const('MyNoKeyProducer', producer_class)
|
|
24
24
|
|
|
25
|
-
producer_class = Class.new(
|
|
25
|
+
producer_class = Class.new(described_class)
|
|
26
26
|
stub_const('MyNestedSchemaProducer', producer_class)
|
|
27
27
|
|
|
28
|
-
producer_class = Class.new(
|
|
28
|
+
producer_class = Class.new(described_class)
|
|
29
29
|
stub_const('MySchemaProducer', producer_class)
|
|
30
30
|
|
|
31
|
-
producer_class = Class.new(
|
|
31
|
+
producer_class = Class.new(described_class)
|
|
32
32
|
stub_const('MyErrorProducer', producer_class)
|
|
33
33
|
|
|
34
34
|
Karafka::App.routes.redraw do
|
|
@@ -84,7 +84,7 @@ module ProducerTest
|
|
|
84
84
|
end
|
|
85
85
|
|
|
86
86
|
it 'should fail on invalid message' do
|
|
87
|
-
|
|
87
|
+
allow(Deimos::ProducerMiddleware).to receive(:call).and_raise('OH NOES')
|
|
88
88
|
expect { MyProducer.publish({ 'invalid' => 'key', :payload_key => 'key' }) }.
|
|
89
89
|
to raise_error('OH NOES')
|
|
90
90
|
end
|
|
@@ -110,7 +110,7 @@ module ProducerTest
|
|
|
110
110
|
[{ 'test_id' => 'foo', 'some_int' => 123 },
|
|
111
111
|
{ 'test_id' => 'bar', 'some_int' => 124 }]
|
|
112
112
|
)
|
|
113
|
-
expect('my-topic').to have_sent({'test_id' => 'foo', 'some_int' => 123}, 'foo', 'foo')
|
|
113
|
+
expect('my-topic').to have_sent({ 'test_id' => 'foo', 'some_int' => 123 }, 'foo', 'foo')
|
|
114
114
|
expect('your-topic').not_to have_sent('test_id' => 'foo', 'some_int' => 123)
|
|
115
115
|
expect('my-topic').not_to have_sent('test_id' => 'foo2', 'some_int' => 123)
|
|
116
116
|
end
|
|
@@ -277,12 +277,13 @@ module ProducerTest
|
|
|
277
277
|
allow(Karafka.logger).to receive(:info)
|
|
278
278
|
allow(Karafka.logger).to receive(:tagged).and_yield(Karafka.logger)
|
|
279
279
|
end
|
|
280
|
+
|
|
280
281
|
context 'with default / full' do
|
|
281
282
|
it 'should log full payload' do
|
|
282
283
|
MyProducerWithID.publish_list(
|
|
283
284
|
[
|
|
284
285
|
{ 'test_id' => 'foo', 'some_int' => 123, :payload_key => 'key' },
|
|
285
|
-
{ 'test_id' => 'foo2', 'some_int' => 123, :payload_key => 'key2' }
|
|
286
|
+
{ 'test_id' => 'foo2', 'some_int' => 123, :payload_key => 'key2' }
|
|
286
287
|
]
|
|
287
288
|
)
|
|
288
289
|
expect(Karafka.logger).to have_received(:info).with(match_message({
|
|
@@ -303,7 +304,7 @@ module ProducerTest
|
|
|
303
304
|
|
|
304
305
|
context 'with count' do
|
|
305
306
|
it 'should log only count' do
|
|
306
|
-
Deimos.karafka_config_for(topic: 'my-topic-with-id').payload_log
|
|
307
|
+
Deimos.karafka_config_for(topic: 'my-topic-with-id').payload_log(:count)
|
|
307
308
|
MyProducerWithID.publish_list(
|
|
308
309
|
[
|
|
309
310
|
{ 'test_id' => 'foo', 'some_int' => 123, :payload_key => 'key' },
|
|
@@ -320,7 +321,7 @@ module ProducerTest
|
|
|
320
321
|
|
|
321
322
|
context 'with Schema Class payloads' do
|
|
322
323
|
it 'should fail on invalid message with error handler' do
|
|
323
|
-
|
|
324
|
+
allow(Deimos::ProducerMiddleware).to receive(:call).and_raise('OH NOES')
|
|
324
325
|
expect { MyProducer.publish(Schemas::MyNamespace::MySchema.new(test_id: 'foo', some_int: 'invalid')) }.
|
|
325
326
|
to raise_error('OH NOES')
|
|
326
327
|
end
|
|
@@ -332,7 +333,7 @@ module ProducerTest
|
|
|
332
333
|
hash_including({
|
|
333
334
|
payload: { 'test_id' => 'foo', 'some_int' => 123, 'payload_key' => nil },
|
|
334
335
|
topic: 'my-topic',
|
|
335
|
-
partition_key: nil
|
|
336
|
+
partition_key: nil
|
|
336
337
|
}),
|
|
337
338
|
hash_including({
|
|
338
339
|
payload: { 'test_id' => 'bar', 'some_int' => 124, 'payload_key' => nil },
|
|
@@ -364,17 +365,21 @@ module ProducerTest
|
|
|
364
365
|
it 'should encode the key' do
|
|
365
366
|
Deimos.configure { |c| c.producers.topic_prefix = nil }
|
|
366
367
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
368
|
+
expect {
|
|
369
|
+
MyProducer.publish_list(
|
|
370
|
+
[Schemas::MyNamespace::MySchema.new(test_id: 'foo', some_int: 123),
|
|
371
|
+
Schemas::MyNamespace::MySchema.new(test_id: 'bar', some_int: 124)]
|
|
372
|
+
)
|
|
373
|
+
}.not_to raise_error
|
|
371
374
|
end
|
|
372
375
|
|
|
373
376
|
it 'should encode with a schema' do
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
377
|
+
expect {
|
|
378
|
+
MySchemaProducer.publish_list(
|
|
379
|
+
[Schemas::MyNamespace::MySchema.new(test_id: 'foo', some_int: 123, payload_key: { 'test_id' => 'foo_key' }),
|
|
380
|
+
Schemas::MyNamespace::MySchema.new(test_id: 'bar', some_int: 124, payload_key: { 'test_id' => 'bar_key' })]
|
|
381
|
+
)
|
|
382
|
+
}.not_to raise_error
|
|
378
383
|
end
|
|
379
384
|
|
|
380
385
|
it 'should properly encode and coerce values with a nested record' do
|
|
@@ -62,9 +62,10 @@ RSpec.shared_examples_for('an Avro backend') do
|
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
specify('#encode_key') do
|
|
65
|
-
|
|
66
|
-
with({ 'test_id' => 1 }, { schema: 'MySchema_key', topic: 'topic' }).and_return('itsme')
|
|
65
|
+
allow(backend).to receive(:encode).and_return('itsme')
|
|
67
66
|
expect(backend.encode_key('test_id', 1, topic: 'topic')).to eq('itsme')
|
|
67
|
+
expect(backend).to have_received(:encode).
|
|
68
|
+
with({ 'test_id' => 1 }, { schema: 'MySchema_key', topic: 'topic' })
|
|
68
69
|
expect(backend.schema_store.find('MySchema_key', 'com.my-namespace').to_avro).
|
|
69
70
|
to eq(
|
|
70
71
|
'doc' => 'Key for com.my-namespace.MySchema - autogenerated by Deimos',
|
|
@@ -78,10 +79,9 @@ RSpec.shared_examples_for('an Avro backend') do
|
|
|
78
79
|
end
|
|
79
80
|
|
|
80
81
|
specify('#decode_key') do
|
|
81
|
-
|
|
82
|
-
with('payload', schema: 'MySchema_key').
|
|
83
|
-
and_return('test_id' => 1)
|
|
82
|
+
allow(backend).to receive(:decode).and_return('test_id' => 1)
|
|
84
83
|
expect(backend.decode_key('payload', 'test_id')).to eq(1)
|
|
84
|
+
expect(backend).to have_received(:decode).with('payload', schema: 'MySchema_key')
|
|
85
85
|
end
|
|
86
86
|
|
|
87
87
|
describe('#validate') do
|
|
@@ -126,8 +126,8 @@ RSpec.shared_examples_for('an Avro backend') do
|
|
|
126
126
|
expect(result['long-field']).to eq(11_111_111_111_111_111_111)
|
|
127
127
|
expect(result['float-field']).to eq(1.0)
|
|
128
128
|
expect(result['double-field']).to eq(2.0)
|
|
129
|
-
expect(result['boolean-field']).to
|
|
130
|
-
expect(result['union-field']).to
|
|
129
|
+
expect(result['boolean-field']).to be(true)
|
|
130
|
+
expect(result['union-field']).to be_nil
|
|
131
131
|
end
|
|
132
132
|
|
|
133
133
|
it 'should coerce strings to numbers' do
|
|
@@ -177,7 +177,7 @@ RSpec.shared_examples_for('an Avro backend') do
|
|
|
177
177
|
|
|
178
178
|
it 'should convert null to false' do
|
|
179
179
|
result = backend.coerce(payload.merge('boolean-field' => nil))
|
|
180
|
-
expect(result['boolean-field']).to
|
|
180
|
+
expect(result['boolean-field']).to be(false)
|
|
181
181
|
end
|
|
182
182
|
|
|
183
183
|
it 'should convert unions' do
|
|
@@ -16,17 +16,16 @@ RSpec.describe Deimos::SchemaBackends::AvroLocal do
|
|
|
16
16
|
|
|
17
17
|
it 'should encode and decode correctly' do
|
|
18
18
|
avro_turf = instance_double(AvroTurf)
|
|
19
|
-
|
|
20
|
-
with(payload, schema_name: 'MySchema', namespace: 'com.my-namespace').
|
|
21
|
-
and_return('encoded-payload')
|
|
22
|
-
expect(avro_turf).to receive(:decode).
|
|
23
|
-
with('encoded-payload', schema_name: 'MySchema', namespace: 'com.my-namespace').
|
|
24
|
-
and_return(payload)
|
|
19
|
+
allow(avro_turf).to receive_messages(encode: 'encoded-payload', decode: payload)
|
|
25
20
|
allow(backend).to receive(:avro_turf).and_return(avro_turf)
|
|
26
21
|
results = backend.encode(payload)
|
|
27
22
|
expect(results).to eq('encoded-payload')
|
|
28
23
|
results = backend.decode(results)
|
|
29
24
|
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')
|
|
30
29
|
end
|
|
31
30
|
|
|
32
31
|
end
|
|
@@ -16,17 +16,16 @@ RSpec.describe Deimos::SchemaBackends::AvroSchemaRegistry do
|
|
|
16
16
|
|
|
17
17
|
it 'should encode and decode correctly' do
|
|
18
18
|
avro_turf = instance_double(AvroTurf::Messaging)
|
|
19
|
-
|
|
20
|
-
with(payload, schema_name: 'MySchema', subject: 'topic').
|
|
21
|
-
and_return('encoded-payload')
|
|
22
|
-
expect(avro_turf).to receive(:decode).
|
|
23
|
-
with('encoded-payload', schema_name: 'MySchema').
|
|
24
|
-
and_return(payload)
|
|
19
|
+
allow(avro_turf).to receive_messages(encode: 'encoded-payload', decode: payload)
|
|
25
20
|
allow(backend).to receive(:avro_turf_messaging).and_return(avro_turf)
|
|
26
21
|
results = backend.encode(payload, topic: 'topic')
|
|
27
22
|
expect(results).to eq('encoded-payload')
|
|
28
23
|
results = backend.decode(results)
|
|
29
24
|
expect(results).to eq(payload)
|
|
25
|
+
expect(avro_turf).to have_received(:encode).
|
|
26
|
+
with(payload, schema_name: 'MySchema', subject: 'topic')
|
|
27
|
+
expect(avro_turf).to have_received(:decode).
|
|
28
|
+
with('encoded-payload', schema_name: 'MySchema')
|
|
30
29
|
end
|
|
31
30
|
|
|
32
31
|
end
|
|
@@ -6,14 +6,14 @@ require_relative "#{__dir__}/../gen/sample/v1/sample_pb"
|
|
|
6
6
|
RSpec.describe Deimos::SchemaBackends::ProtoSchemaRegistry do
|
|
7
7
|
let(:payload) do
|
|
8
8
|
Sample::V1::SampleMessage.new(
|
|
9
|
-
str:
|
|
9
|
+
str: 'string',
|
|
10
10
|
num: 123,
|
|
11
|
-
str_arr: %w
|
|
11
|
+
str_arr: %w(one two),
|
|
12
12
|
flag: true,
|
|
13
13
|
timestamp: Time.utc(2017, 1, 1),
|
|
14
|
-
nested: Sample::V1::NestedMessage.new(nested_str:
|
|
14
|
+
nested: Sample::V1::NestedMessage.new(nested_str: 'string'),
|
|
15
15
|
non_union_nested: Sample::V1::NestedMessage.new(nested_num: 456),
|
|
16
|
-
str_map: {'foo' => 'bar'}
|
|
16
|
+
str_map: { 'foo' => 'bar' }
|
|
17
17
|
)
|
|
18
18
|
end
|
|
19
19
|
|
|
@@ -22,29 +22,26 @@ RSpec.describe Deimos::SchemaBackends::ProtoSchemaRegistry do
|
|
|
22
22
|
specify('#encode_key') do
|
|
23
23
|
expect(backend.encode_key(nil, 789)).to eq('789')
|
|
24
24
|
expect(backend.encode_key(nil, 'string')).to eq('string')
|
|
25
|
-
expect(backend.encode_key(nil, {foo: 'bar'})).to eq('{"foo":"bar"}')
|
|
25
|
+
expect(backend.encode_key(nil, { foo: 'bar' })).to eq('{"foo":"bar"}')
|
|
26
26
|
expect(backend.encode_key(:foo, 'bar')).to eq('bar')
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
specify('#decode_key') do
|
|
30
30
|
expect(backend.decode_key('789', nil)).to eq(789)
|
|
31
31
|
expect(backend.decode_key('{"foo":"bar"}', :foo)).to eq('bar')
|
|
32
|
-
expect(backend.decode_key('{"foo":"bar"}', nil)).to eq({
|
|
32
|
+
expect(backend.decode_key('{"foo":"bar"}', nil)).to eq({ 'foo' => 'bar' })
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
it 'should encode and decode correctly' do
|
|
36
36
|
proto_turf = instance_double(ProtoTurf)
|
|
37
|
-
|
|
38
|
-
with(payload, subject: 'topic').
|
|
39
|
-
and_return('encoded-payload')
|
|
40
|
-
expect(proto_turf).to receive(:decode).
|
|
41
|
-
with('encoded-payload').
|
|
42
|
-
and_return(payload)
|
|
37
|
+
allow(proto_turf).to receive_messages(encode: 'encoded-payload', decode: payload)
|
|
43
38
|
allow(described_class).to receive(:proto_turf).and_return(proto_turf)
|
|
44
39
|
results = backend.encode(payload, topic: 'topic')
|
|
45
40
|
expect(results).to eq('encoded-payload')
|
|
46
41
|
results = backend.decode(results)
|
|
47
42
|
expect(results).to eq(payload)
|
|
43
|
+
expect(proto_turf).to have_received(:encode).with(payload, subject: 'topic')
|
|
44
|
+
expect(proto_turf).to have_received(:decode).with('encoded-payload')
|
|
48
45
|
end
|
|
49
46
|
|
|
50
47
|
end
|
|
@@ -44,8 +44,7 @@ module Schemas; module MyNamespace
|
|
|
44
44
|
# @override
|
|
45
45
|
def symbols
|
|
46
46
|
%w(sym1 sym2)
|
|
47
|
-
end
|
|
48
|
-
|
|
47
|
+
end
|
|
49
48
|
|
|
50
49
|
def sym1?
|
|
51
50
|
@value == 'sym1'
|
|
@@ -62,8 +61,7 @@ module Schemas; module MyNamespace
|
|
|
62
61
|
# @override
|
|
63
62
|
def symbols
|
|
64
63
|
%w(sym3 sym4)
|
|
65
|
-
end
|
|
66
|
-
|
|
64
|
+
end
|
|
67
65
|
|
|
68
66
|
def sym3?
|
|
69
67
|
@value == 'sym3'
|
|
@@ -80,8 +78,7 @@ module Schemas; module MyNamespace
|
|
|
80
78
|
# @override
|
|
81
79
|
def symbols
|
|
82
80
|
%w(sym5 sym6)
|
|
83
|
-
end
|
|
84
|
-
|
|
81
|
+
end
|
|
85
82
|
|
|
86
83
|
def sym5?
|
|
87
84
|
@value == 'sym5'
|
|
@@ -175,8 +172,8 @@ module Schemas; module MyNamespace
|
|
|
175
172
|
test_string_array: ["test"],
|
|
176
173
|
test_int_array: [123],
|
|
177
174
|
test_optional_int: 123,
|
|
178
|
-
some_integer_map: {"abc"=>123},
|
|
179
|
-
some_record: {"a_record_field"=>"Test String"},
|
|
175
|
+
some_integer_map: { "abc"=>123 },
|
|
176
|
+
some_record: { "a_record_field"=>"Test String" },
|
|
180
177
|
some_optional_record: nil,
|
|
181
178
|
some_record_array: nil,
|
|
182
179
|
some_record_map: nil,
|
|
@@ -9,13 +9,13 @@ module Schemas; module MyNamespace
|
|
|
9
9
|
### Secondary Schema Classes ###
|
|
10
10
|
# Autogenerated Schema for Record at com.flipp.content.Record1
|
|
11
11
|
class Record1 < Deimos::SchemaClass::Record
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
### Attribute Accessors ###
|
|
14
14
|
# @return [Hash<String, Integer>]
|
|
15
15
|
attr_accessor :record1_map
|
|
16
16
|
# @return [Integer]
|
|
17
17
|
attr_accessor :record1_id
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
# @override
|
|
20
20
|
def initialize(_from_message: false, record1_map: {},
|
|
21
21
|
record1_id: 0)
|
|
@@ -24,17 +24,17 @@ module Schemas; module MyNamespace
|
|
|
24
24
|
self.record1_map = record1_map
|
|
25
25
|
self.record1_id = record1_id
|
|
26
26
|
end
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
# @override
|
|
29
29
|
def schema
|
|
30
30
|
'Record1'
|
|
31
31
|
end
|
|
32
|
-
|
|
32
|
+
|
|
33
33
|
# @override
|
|
34
34
|
def namespace
|
|
35
35
|
'com.flipp.content'
|
|
36
36
|
end
|
|
37
|
-
|
|
37
|
+
|
|
38
38
|
# @override
|
|
39
39
|
def as_json(_opts={})
|
|
40
40
|
{
|
|
@@ -46,28 +46,28 @@ module Schemas; module MyNamespace
|
|
|
46
46
|
|
|
47
47
|
# Autogenerated Schema for Record at com.flipp.content.Record2
|
|
48
48
|
class Record2 < Deimos::SchemaClass::Record
|
|
49
|
-
|
|
49
|
+
|
|
50
50
|
### Attribute Accessors ###
|
|
51
51
|
# @return [String]
|
|
52
52
|
attr_accessor :record2_id
|
|
53
|
-
|
|
53
|
+
|
|
54
54
|
# @override
|
|
55
|
-
def initialize(_from_message: false, record2_id:
|
|
55
|
+
def initialize(_from_message: false, record2_id: '')
|
|
56
56
|
@_from_message = _from_message
|
|
57
57
|
super
|
|
58
58
|
self.record2_id = record2_id
|
|
59
59
|
end
|
|
60
|
-
|
|
60
|
+
|
|
61
61
|
# @override
|
|
62
62
|
def schema
|
|
63
63
|
'Record2'
|
|
64
64
|
end
|
|
65
|
-
|
|
65
|
+
|
|
66
66
|
# @override
|
|
67
67
|
def namespace
|
|
68
68
|
'com.flipp.content'
|
|
69
69
|
end
|
|
70
|
-
|
|
70
|
+
|
|
71
71
|
# @override
|
|
72
72
|
def as_json(_opts={})
|
|
73
73
|
{
|
|
@@ -78,28 +78,28 @@ module Schemas; module MyNamespace
|
|
|
78
78
|
|
|
79
79
|
# Autogenerated Schema for Record at com.flipp.content.Record3
|
|
80
80
|
class Record3 < Deimos::SchemaClass::Record
|
|
81
|
-
|
|
81
|
+
|
|
82
82
|
### Attribute Accessors ###
|
|
83
83
|
# @return [Float]
|
|
84
84
|
attr_accessor :record3_id
|
|
85
|
-
|
|
85
|
+
|
|
86
86
|
# @override
|
|
87
87
|
def initialize(_from_message: false, record3_id: 0.0)
|
|
88
88
|
@_from_message = _from_message
|
|
89
89
|
super
|
|
90
90
|
self.record3_id = record3_id
|
|
91
91
|
end
|
|
92
|
-
|
|
92
|
+
|
|
93
93
|
# @override
|
|
94
94
|
def schema
|
|
95
95
|
'Record3'
|
|
96
96
|
end
|
|
97
|
-
|
|
97
|
+
|
|
98
98
|
# @override
|
|
99
99
|
def namespace
|
|
100
100
|
'com.flipp.content'
|
|
101
101
|
end
|
|
102
|
-
|
|
102
|
+
|
|
103
103
|
# @override
|
|
104
104
|
def as_json(_opts={})
|
|
105
105
|
{
|
|
@@ -110,28 +110,28 @@ module Schemas; module MyNamespace
|
|
|
110
110
|
|
|
111
111
|
# Autogenerated Schema for Record at com.flipp.content.Record4
|
|
112
112
|
class Record4 < Deimos::SchemaClass::Record
|
|
113
|
-
|
|
113
|
+
|
|
114
114
|
### Attribute Accessors ###
|
|
115
115
|
# @return [Integer]
|
|
116
116
|
attr_accessor :record4_id
|
|
117
|
-
|
|
117
|
+
|
|
118
118
|
# @override
|
|
119
119
|
def initialize(_from_message: false, record4_id: 0)
|
|
120
120
|
@_from_message = _from_message
|
|
121
121
|
super
|
|
122
122
|
self.record4_id = record4_id
|
|
123
123
|
end
|
|
124
|
-
|
|
124
|
+
|
|
125
125
|
# @override
|
|
126
126
|
def schema
|
|
127
127
|
'Record4'
|
|
128
128
|
end
|
|
129
|
-
|
|
129
|
+
|
|
130
130
|
# @override
|
|
131
131
|
def namespace
|
|
132
132
|
'com.flipp.content'
|
|
133
133
|
end
|
|
134
|
-
|
|
134
|
+
|
|
135
135
|
# @override
|
|
136
136
|
def as_json(_opts={})
|
|
137
137
|
{
|
|
@@ -140,7 +140,6 @@ module Schemas; module MyNamespace
|
|
|
140
140
|
end
|
|
141
141
|
end
|
|
142
142
|
|
|
143
|
-
|
|
144
143
|
### Attribute Readers ###
|
|
145
144
|
# @return [nil, Record1, Record2, Record3, Record4, Integer, Array<String>]
|
|
146
145
|
attr_reader :test_union_type
|
|
@@ -173,7 +172,7 @@ module Schemas; module MyNamespace
|
|
|
173
172
|
end
|
|
174
173
|
|
|
175
174
|
# @override
|
|
176
|
-
def initialize(_from_message: false, test_id:
|
|
175
|
+
def initialize(_from_message: false, test_id: '',
|
|
177
176
|
test_long: nil,
|
|
178
177
|
test_union_type: nil)
|
|
179
178
|
@_from_message = _from_message
|