deimos-ruby 1.11.2 → 1.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -2
  3. data/Gemfile.lock +8 -8
  4. data/README.md +96 -0
  5. data/deimos-ruby.gemspec +1 -1
  6. data/docs/CONFIGURATION.md +4 -0
  7. data/lib/deimos/active_record_consume/batch_consumption.rb +7 -9
  8. data/lib/deimos/active_record_consume/message_consumption.rb +4 -3
  9. data/lib/deimos/active_record_consumer.rb +2 -2
  10. data/lib/deimos/active_record_producer.rb +3 -0
  11. data/lib/deimos/config/configuration.rb +29 -0
  12. data/lib/deimos/consume/batch_consumption.rb +2 -2
  13. data/lib/deimos/consume/message_consumption.rb +2 -2
  14. data/lib/deimos/consumer.rb +10 -0
  15. data/lib/deimos/producer.rb +4 -3
  16. data/lib/deimos/schema_backends/avro_base.rb +64 -1
  17. data/lib/deimos/schema_backends/avro_schema_registry.rb +1 -1
  18. data/lib/deimos/schema_backends/base.rb +18 -2
  19. data/lib/deimos/schema_class/base.rb +67 -0
  20. data/lib/deimos/schema_class/enum.rb +24 -0
  21. data/lib/deimos/schema_class/record.rb +59 -0
  22. data/lib/deimos/shared_config.rb +5 -0
  23. data/lib/deimos/test_helpers.rb +43 -7
  24. data/lib/deimos/utils/schema_class.rb +29 -0
  25. data/lib/deimos/version.rb +1 -1
  26. data/lib/deimos.rb +3 -0
  27. data/lib/generators/deimos/schema_class/templates/schema_class.rb.tt +15 -0
  28. data/lib/generators/deimos/schema_class/templates/schema_enum.rb.tt +21 -0
  29. data/lib/generators/deimos/schema_class/templates/schema_record.rb.tt +65 -0
  30. data/lib/generators/deimos/schema_class_generator.rb +247 -0
  31. data/lib/tasks/deimos.rake +8 -0
  32. data/spec/active_record_batch_consumer_spec.rb +120 -110
  33. data/spec/active_record_consumer_spec.rb +97 -88
  34. data/spec/active_record_producer_spec.rb +38 -27
  35. data/spec/batch_consumer_spec.rb +37 -28
  36. data/spec/config/configuration_spec.rb +10 -3
  37. data/spec/consumer_spec.rb +94 -83
  38. data/spec/generators/active_record_generator_spec.rb +1 -0
  39. data/spec/generators/schema_class/my_schema_with_complex_types_spec.rb +206 -0
  40. data/spec/generators/schema_class_generator_spec.rb +186 -0
  41. data/spec/producer_spec.rb +110 -0
  42. data/spec/schema_classes/generated.rb +156 -0
  43. data/spec/schema_classes/my_nested_schema.rb +114 -0
  44. data/spec/schema_classes/my_schema.rb +53 -0
  45. data/spec/schema_classes/my_schema_key.rb +35 -0
  46. data/spec/schema_classes/my_schema_with_complex_types.rb +172 -0
  47. data/spec/schemas/com/my-namespace/Generated.avsc +6 -0
  48. data/spec/schemas/com/my-namespace/MySchemaWithComplexTypes.avsc +95 -0
  49. data/spec/spec_helper.rb +6 -1
  50. metadata +28 -4
@@ -390,6 +390,116 @@ module ProducerTest
390
390
  }, '456', '4561')
391
391
  end
392
392
 
393
+ context 'with Schema Class payloads' do
394
+ it 'should fail on invalid message with error handler' do
395
+ subscriber = Deimos.subscribe('produce') do |event|
396
+ expect(event.payload[:payloads]).to eq([{ 'invalid' => 'key' }])
397
+ end
398
+ expect(MyProducer.encoder).to receive(:validate).and_raise('OH NOES')
399
+ expect {
400
+ MyProducer.publish(Schemas::MySchema.new(test_id: 'foo', some_int: 'invalid'))
401
+ }.to raise_error('OH NOES')
402
+ Deimos.unsubscribe(subscriber)
403
+ end
404
+
405
+ it 'should produce a message' do
406
+ expect(described_class).to receive(:produce_batch).once.with(
407
+ Deimos::Backends::Test,
408
+ [
409
+ Deimos::Message.new({ 'test_id' => 'foo', 'some_int' => 123 },
410
+ MyProducer,
411
+ topic: 'my-topic',
412
+ partition_key: 'foo',
413
+ key: 'foo'),
414
+ Deimos::Message.new({ 'test_id' => 'bar', 'some_int' => 124 },
415
+ MyProducer,
416
+ topic: 'my-topic',
417
+ partition_key: 'bar',
418
+ key: 'bar')
419
+ ]
420
+ ).and_call_original
421
+
422
+ MyProducer.publish_list(
423
+ [Schemas::MySchema.new(test_id: 'foo', some_int: 123),
424
+ Schemas::MySchema.new(test_id: 'bar', some_int: 124)]
425
+ )
426
+ expect('my-topic').to have_sent('test_id' => 'foo', 'some_int' => 123)
427
+ expect('your-topic').not_to have_sent('test_id' => 'foo', 'some_int' => 123)
428
+ expect('my-topic').not_to have_sent('test_id' => 'foo2', 'some_int' => 123)
429
+ end
430
+
431
+ it 'should not publish if publish disabled' do
432
+ expect(described_class).not_to receive(:produce_batch)
433
+ Deimos.configure { |c| c.producers.disabled = true }
434
+ MyProducer.publish_list(
435
+ [Schemas::MySchema.new(test_id: 'foo', some_int: 123),
436
+ Schemas::MySchema.new(test_id: 'bar', some_int: 124)]
437
+ )
438
+ expect(MyProducer.topic).not_to have_sent(anything)
439
+ end
440
+
441
+ it 'should encode the key' do
442
+ Deimos.configure { |c| c.producers.topic_prefix = nil }
443
+ expect(MyProducer.encoder).to receive(:encode_key).with('test_id', 'foo', topic: 'my-topic-key')
444
+ expect(MyProducer.encoder).to receive(:encode_key).with('test_id', 'bar', topic: 'my-topic-key')
445
+ expect(MyProducer.encoder).to receive(:encode).with({
446
+ 'test_id' => 'foo',
447
+ 'some_int' => 123
448
+ }, { topic: 'my-topic-value' })
449
+ expect(MyProducer.encoder).to receive(:encode).with({
450
+ 'test_id' => 'bar',
451
+ 'some_int' => 124
452
+ }, { topic: 'my-topic-value' })
453
+
454
+ MyProducer.publish_list(
455
+ [Schemas::MySchema.new(test_id: 'foo', some_int: 123),
456
+ Schemas::MySchema.new(test_id: 'bar', some_int: 124)]
457
+ )
458
+ end
459
+
460
+ it 'should encode with a schema' do
461
+ expect(MySchemaProducer.key_encoder).to receive(:encode).with({ 'test_id' => 'foo_key' },
462
+ { topic: 'my-topic2-key' })
463
+ expect(MySchemaProducer.key_encoder).to receive(:encode).with({ 'test_id' => 'bar_key' },
464
+ { topic: 'my-topic2-key' })
465
+
466
+ MySchemaProducer.publish_list(
467
+ [Schemas::MySchema.new(test_id: 'foo', some_int: 123, payload_key: { 'test_id' => 'foo_key' }),
468
+ Schemas::MySchema.new(test_id: 'bar', some_int: 124, payload_key: { 'test_id' => 'bar_key' })]
469
+ )
470
+ end
471
+
472
+ it 'should properly encode and coerce values with a nested record' do
473
+ expect(MyNestedSchemaProducer.encoder).to receive(:encode_key).with('test_id', 'foo', topic: 'my-topic-key')
474
+ MyNestedSchemaProducer.publish(
475
+ Schemas::MyNestedSchema.new(
476
+ test_id: 'foo',
477
+ test_float: BigDecimal('123.456'),
478
+ test_array: ['1'],
479
+ some_nested_record: Schemas::MyNestedRecord.new(
480
+ some_int: 123,
481
+ some_float: BigDecimal('456.789'),
482
+ some_string: '123',
483
+ some_optional_int: nil
484
+ ),
485
+ some_optional_record: nil
486
+ )
487
+ )
488
+ expect(MyNestedSchemaProducer.topic).to have_sent(
489
+ 'test_id' => 'foo',
490
+ 'test_float' => 123.456,
491
+ 'test_array' => ['1'],
492
+ 'some_nested_record' => {
493
+ 'some_int' => 123,
494
+ 'some_float' => 456.789,
495
+ 'some_string' => '123',
496
+ 'some_optional_int' => nil
497
+ },
498
+ 'some_optional_record' => nil
499
+ )
500
+ end
501
+ end
502
+
393
503
  describe 'disabling' do
394
504
  it 'should disable globally' do
395
505
  Deimos.disable_producers do
@@ -0,0 +1,156 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is autogenerated by Deimos, Do NOT modify
4
+ module Schemas
5
+ ### Secondary Schema Classes ###
6
+ # Autogenerated Schema for Enum at com.my-namespace.AnEnum
7
+ class AnEnum < Deimos::SchemaClass::Enum
8
+ # @return ['sym1', 'sym2']
9
+ attr_accessor :an_enum
10
+
11
+ # :nodoc:
12
+ def initialize(an_enum)
13
+ super
14
+ self.an_enum = an_enum
15
+ end
16
+
17
+ # @override
18
+ def symbols
19
+ %w(sym1 sym2)
20
+ end
21
+
22
+ # @override
23
+ def to_h
24
+ @an_enum
25
+ end
26
+ end
27
+
28
+ # Autogenerated Schema for Record at com.my-namespace.ARecord
29
+ class ARecord < Deimos::SchemaClass::Record
30
+ ### Attribute Accessors ###
31
+ # @param value [String]
32
+ attr_accessor :a_record_field
33
+
34
+ # @override
35
+ def initialize(a_record_field: nil)
36
+ super
37
+ self.a_record_field = a_record_field
38
+ end
39
+
40
+ # @override
41
+ def schema
42
+ 'ARecord'
43
+ end
44
+
45
+ # @override
46
+ def namespace
47
+ 'com.my-namespace'
48
+ end
49
+
50
+ # @override
51
+ def to_h
52
+ {
53
+ 'a_record_field' => @a_record_field
54
+ }
55
+ end
56
+ end
57
+
58
+ ### Primary Schema Class ###
59
+ # Autogenerated Schema for Record at com.my-namespace.Generated
60
+ class Generated < Deimos::SchemaClass::Record
61
+ ### Attribute Readers ###
62
+ # @return [AnEnum]
63
+ attr_reader :an_enum
64
+ # @return [ARecord]
65
+ attr_reader :a_record
66
+
67
+ ### Attribute Accessors ###
68
+ # @param value [String]
69
+ attr_accessor :a_string
70
+ # @param value [Integer]
71
+ attr_accessor :a_int
72
+ # @param value [Integer]
73
+ attr_accessor :a_long
74
+ # @param value [Float]
75
+ attr_accessor :a_float
76
+ # @param value [Float]
77
+ attr_accessor :a_double
78
+ # @param value [nil, Integer]
79
+ attr_accessor :an_optional_int
80
+ # @param values [Array<Integer>]
81
+ attr_accessor :an_array
82
+ # @param values [Hash<String, String>]
83
+ attr_accessor :a_map
84
+ # @param value [String]
85
+ attr_accessor :timestamp
86
+ # @param value [String]
87
+ attr_accessor :message_id
88
+
89
+ ### Attribute Writers ###
90
+ # @param value [AnEnum]
91
+ def an_enum=(value)
92
+ @an_enum = AnEnum.initialize_from_value(value)
93
+ end
94
+
95
+ # @param value [ARecord]
96
+ def a_record=(value)
97
+ @a_record = ARecord.initialize_from_value(value)
98
+ end
99
+
100
+ # @override
101
+ def initialize(a_string: nil,
102
+ a_int: nil,
103
+ a_long: nil,
104
+ a_float: nil,
105
+ a_double: nil,
106
+ an_optional_int: nil,
107
+ an_enum: nil,
108
+ an_array: nil,
109
+ a_map: nil,
110
+ timestamp: nil,
111
+ message_id: nil,
112
+ a_record: nil)
113
+ super
114
+ self.a_string = a_string
115
+ self.a_int = a_int
116
+ self.a_long = a_long
117
+ self.a_float = a_float
118
+ self.a_double = a_double
119
+ self.an_optional_int = an_optional_int
120
+ self.an_enum = an_enum
121
+ self.an_array = an_array
122
+ self.a_map = a_map
123
+ self.timestamp = timestamp
124
+ self.message_id = message_id
125
+ self.a_record = a_record
126
+ end
127
+
128
+ # @override
129
+ def schema
130
+ 'Generated'
131
+ end
132
+
133
+ # @override
134
+ def namespace
135
+ 'com.my-namespace'
136
+ end
137
+
138
+ # @override
139
+ def to_h
140
+ {
141
+ 'a_string' => @a_string,
142
+ 'a_int' => @a_int,
143
+ 'a_long' => @a_long,
144
+ 'a_float' => @a_float,
145
+ 'a_double' => @a_double,
146
+ 'an_optional_int' => @an_optional_int,
147
+ 'an_enum' => @an_enum&.to_h,
148
+ 'an_array' => @an_array,
149
+ 'a_map' => @a_map,
150
+ 'timestamp' => @timestamp,
151
+ 'message_id' => @message_id,
152
+ 'a_record' => @a_record&.to_h
153
+ }
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is autogenerated by Deimos, Do NOT modify
4
+ module Schemas
5
+ ### Secondary Schema Classes ###
6
+ # Autogenerated Schema for Record at com.my-namespace.MyNestedRecord
7
+ class MyNestedRecord < Deimos::SchemaClass::Record
8
+ ### Attribute Accessors ###
9
+ # @param value [Integer]
10
+ attr_accessor :some_int
11
+ # @param value [Float]
12
+ attr_accessor :some_float
13
+ # @param value [String]
14
+ attr_accessor :some_string
15
+ # @param value [nil, Integer]
16
+ attr_accessor :some_optional_int
17
+
18
+ # @override
19
+ def initialize(some_int: nil,
20
+ some_float: nil,
21
+ some_string: nil,
22
+ some_optional_int: nil)
23
+ super
24
+ self.some_int = some_int
25
+ self.some_float = some_float
26
+ self.some_string = some_string
27
+ self.some_optional_int = some_optional_int
28
+ end
29
+
30
+ # @override
31
+ def schema
32
+ 'MyNestedRecord'
33
+ end
34
+
35
+ # @override
36
+ def namespace
37
+ 'com.my-namespace'
38
+ end
39
+
40
+ # @override
41
+ def to_h
42
+ {
43
+ 'some_int' => @some_int,
44
+ 'some_float' => @some_float,
45
+ 'some_string' => @some_string,
46
+ 'some_optional_int' => @some_optional_int
47
+ }
48
+ end
49
+ end
50
+
51
+ ### Primary Schema Class ###
52
+ # Autogenerated Schema for Record at com.my-namespace.MyNestedSchema
53
+ class MyNestedSchema < Deimos::SchemaClass::Record
54
+ ### Attribute Readers ###
55
+ # @return [MyNestedRecord]
56
+ attr_reader :some_nested_record
57
+ # @return [nil, MyNestedRecord]
58
+ attr_reader :some_optional_record
59
+
60
+ ### Attribute Accessors ###
61
+ # @param value [String]
62
+ attr_accessor :test_id
63
+ # @param value [Float]
64
+ attr_accessor :test_float
65
+ # @param values [Array<String>]
66
+ attr_accessor :test_array
67
+
68
+ ### Attribute Writers ###
69
+ # @param value [MyNestedRecord]
70
+ def some_nested_record=(value)
71
+ @some_nested_record = MyNestedRecord.initialize_from_value(value)
72
+ end
73
+
74
+ # @param value [nil, MyNestedRecord]
75
+ def some_optional_record=(value)
76
+ @some_optional_record = MyNestedRecord.initialize_from_value(value)
77
+ end
78
+
79
+ # @override
80
+ def initialize(test_id: nil,
81
+ test_float: nil,
82
+ test_array: nil,
83
+ some_nested_record: nil,
84
+ some_optional_record: nil)
85
+ super
86
+ self.test_id = test_id
87
+ self.test_float = test_float
88
+ self.test_array = test_array
89
+ self.some_nested_record = some_nested_record
90
+ self.some_optional_record = some_optional_record
91
+ end
92
+
93
+ # @override
94
+ def schema
95
+ 'MyNestedSchema'
96
+ end
97
+
98
+ # @override
99
+ def namespace
100
+ 'com.my-namespace'
101
+ end
102
+
103
+ # @override
104
+ def to_h
105
+ {
106
+ 'test_id' => @test_id,
107
+ 'test_float' => @test_float,
108
+ 'test_array' => @test_array,
109
+ 'some_nested_record' => @some_nested_record&.to_h,
110
+ 'some_optional_record' => @some_optional_record&.to_h
111
+ }
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is autogenerated by Deimos, Do NOT modify
4
+ module Schemas
5
+ ### Primary Schema Class ###
6
+ # Autogenerated Schema for Record at com.my-namespace.MySchema
7
+ class MySchema < Deimos::SchemaClass::Record
8
+ ### Attribute Readers ###
9
+ # @return [MySchemaKey]
10
+ attr_reader :payload_key
11
+
12
+ ### Attribute Accessors ###
13
+ # @param value [String]
14
+ attr_accessor :test_id
15
+ # @param value [Integer]
16
+ attr_accessor :some_int
17
+
18
+ ### Attribute Writers ###
19
+ # @param value [MySchemaKey]
20
+ def payload_key=(value)
21
+ @payload_key = MySchemaKey.initialize_from_value(value)
22
+ end
23
+
24
+ # @override
25
+ def initialize(test_id: nil,
26
+ some_int: nil,
27
+ payload_key: nil)
28
+ super
29
+ self.test_id = test_id
30
+ self.some_int = some_int
31
+ self.payload_key = payload_key
32
+ end
33
+
34
+ # @override
35
+ def schema
36
+ 'MySchema'
37
+ end
38
+
39
+ # @override
40
+ def namespace
41
+ 'com.my-namespace'
42
+ end
43
+
44
+ # @override
45
+ def to_h
46
+ {
47
+ 'test_id' => @test_id,
48
+ 'some_int' => @some_int,
49
+ 'payload_key' => @payload_key&.to_h
50
+ }
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is autogenerated by Deimos, Do NOT modify
4
+ module Schemas
5
+ ### Primary Schema Class ###
6
+ # Autogenerated Schema for Record at com.my-namespace.MySchema-key
7
+ class MySchemaKey < Deimos::SchemaClass::Record
8
+ ### Attribute Accessors ###
9
+ # @param value [String]
10
+ attr_accessor :test_id
11
+
12
+ # @override
13
+ def initialize(test_id: nil)
14
+ super
15
+ self.test_id = test_id
16
+ end
17
+
18
+ # @override
19
+ def schema
20
+ 'MySchema-key'
21
+ end
22
+
23
+ # @override
24
+ def namespace
25
+ 'com.my-namespace'
26
+ end
27
+
28
+ # @override
29
+ def to_h
30
+ {
31
+ 'test_id' => @test_id
32
+ }
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,172 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is autogenerated by Deimos, Do NOT modify
4
+ module Schemas
5
+ ### Secondary Schema Classes ###
6
+ # Autogenerated Schema for Record at com.my-namespace.ARecord
7
+ class ARecord < Deimos::SchemaClass::Record
8
+ ### Attribute Accessors ###
9
+ # @param value [String]
10
+ attr_accessor :a_record_field
11
+
12
+ # @override
13
+ def initialize(a_record_field: nil)
14
+ super
15
+ self.a_record_field = a_record_field
16
+ end
17
+
18
+ # @override
19
+ def schema
20
+ 'ARecord'
21
+ end
22
+
23
+ # @override
24
+ def namespace
25
+ 'com.my-namespace'
26
+ end
27
+
28
+ # @override
29
+ def to_h
30
+ {
31
+ 'a_record_field' => @a_record_field
32
+ }
33
+ end
34
+ end
35
+
36
+ # Autogenerated Schema for Enum at com.my-namespace.AnEnum
37
+ class AnEnum < Deimos::SchemaClass::Enum
38
+ # @return ['sym1', 'sym2']
39
+ attr_accessor :an_enum
40
+
41
+ # :nodoc:
42
+ def initialize(an_enum)
43
+ super
44
+ self.an_enum = an_enum
45
+ end
46
+
47
+ # @override
48
+ def symbols
49
+ %w(sym1 sym2)
50
+ end
51
+
52
+ # @override
53
+ def to_h
54
+ @an_enum
55
+ end
56
+ end
57
+
58
+ ### Primary Schema Class ###
59
+ # Autogenerated Schema for Record at com.my-namespace.MySchemaWithComplexTypes
60
+ class MySchemaWithComplexTypes < Deimos::SchemaClass::Record
61
+ ### Attribute Readers ###
62
+ # @return [ARecord]
63
+ attr_reader :some_record
64
+ # @return [nil, ARecord]
65
+ attr_reader :some_optional_record
66
+ # @return [Array<ARecord>]
67
+ attr_reader :some_record_array
68
+ # @return [Hash<String, ARecord>]
69
+ attr_reader :some_record_map
70
+ # @return [Array<AnEnum>]
71
+ attr_reader :some_enum_array
72
+
73
+ ### Attribute Accessors ###
74
+ # @param value [String]
75
+ attr_accessor :test_id
76
+ # @param value [Float]
77
+ attr_accessor :test_float
78
+ # @param values [Array<String>]
79
+ attr_accessor :test_string_array
80
+ # @param values [Array<Integer>]
81
+ attr_accessor :test_int_array
82
+ # @param value [Integer, nil]
83
+ attr_accessor :test_optional_int
84
+ # @param values [Hash<String, Integer>]
85
+ attr_accessor :some_integer_map
86
+
87
+ ### Attribute Writers ###
88
+ # @param value [ARecord]
89
+ def some_record=(value)
90
+ @some_record = ARecord.initialize_from_value(value)
91
+ end
92
+
93
+ # @param value [nil, ARecord]
94
+ def some_optional_record=(value)
95
+ @some_optional_record = ARecord.initialize_from_value(value)
96
+ end
97
+
98
+ # @param values [Array<ARecord>]
99
+ def some_record_array=(values)
100
+ @some_record_array = values.map do |value|
101
+ ARecord.initialize_from_value(value)
102
+ end
103
+ end
104
+
105
+ # @param values [Hash<String, ARecord>]
106
+ def some_record_map=(values)
107
+ @some_record_map = values.transform_values do |value|
108
+ ARecord.initialize_from_value(value)
109
+ end
110
+ end
111
+
112
+ # @param values [Array<AnEnum>]
113
+ def some_enum_array=(values)
114
+ @some_enum_array = values.map do |value|
115
+ AnEnum.initialize_from_value(value)
116
+ end
117
+ end
118
+
119
+ # @override
120
+ def initialize(test_id: nil,
121
+ test_float: nil,
122
+ test_string_array: ["test"],
123
+ test_int_array: [123],
124
+ test_optional_int: 123,
125
+ some_integer_map: {"abc"=>123},
126
+ some_record: {"a_record_field"=>"Test String"},
127
+ some_optional_record: nil,
128
+ some_record_array: nil,
129
+ some_record_map: nil,
130
+ some_enum_array: nil)
131
+ super
132
+ self.test_id = test_id
133
+ self.test_float = test_float
134
+ self.test_string_array = test_string_array
135
+ self.test_int_array = test_int_array
136
+ self.test_optional_int = test_optional_int
137
+ self.some_integer_map = some_integer_map
138
+ self.some_record = some_record
139
+ self.some_optional_record = some_optional_record
140
+ self.some_record_array = some_record_array
141
+ self.some_record_map = some_record_map
142
+ self.some_enum_array = some_enum_array
143
+ end
144
+
145
+ # @override
146
+ def schema
147
+ 'MySchemaWithComplexTypes'
148
+ end
149
+
150
+ # @override
151
+ def namespace
152
+ 'com.my-namespace'
153
+ end
154
+
155
+ # @override
156
+ def to_h
157
+ {
158
+ 'test_id' => @test_id,
159
+ 'test_float' => @test_float,
160
+ 'test_string_array' => @test_string_array,
161
+ 'test_int_array' => @test_int_array,
162
+ 'test_optional_int' => @test_optional_int,
163
+ 'some_integer_map' => @some_integer_map,
164
+ 'some_record' => @some_record&.to_h,
165
+ 'some_optional_record' => @some_optional_record&.to_h,
166
+ 'some_record_array' => @some_record_array.map { |v| v&.to_h },
167
+ 'some_record_map' => @some_record_map.transform_values { |v| v&.to_h },
168
+ 'some_enum_array' => @some_enum_array.map { |v| v&.to_h }
169
+ }
170
+ end
171
+ end
172
+ end
@@ -24,6 +24,12 @@
24
24
  "name": "a_double",
25
25
  "type": "double"
26
26
  },
27
+ {
28
+ "name": "an_optional_int",
29
+ "type": [ "null", "int" ],
30
+ "doc": "an optional int",
31
+ "default": null
32
+ },
27
33
  {
28
34
  "name": "an_enum",
29
35
  "type": {