deimos-ruby 1.16.0 → 1.16.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/CHANGELOG.md +9 -1
- data/README.md +17 -0
- data/lib/deimos/active_record_producer.rb +7 -0
- data/lib/deimos/schema_class/base.rb +1 -1
- data/lib/deimos/schema_class/enum.rb +5 -0
- data/lib/deimos/schema_class/record.rb +7 -1
- data/lib/deimos/version.rb +1 -1
- data/lib/generators/deimos/schema_class/templates/schema_record.rb.tt +13 -5
- data/lib/generators/deimos/schema_class_generator.rb +40 -22
- data/regenerate_test_schema_classes.rb +68 -0
- data/spec/active_record_producer_spec.rb +24 -0
- data/spec/generators/schema_class/my_schema_spec.rb +16 -0
- data/spec/generators/schema_class/my_schema_with_circular_reference_spec.rb +1 -1
- data/spec/generators/schema_class/my_schema_with_complex_types_spec.rb +32 -24
- data/spec/producer_spec.rb +11 -11
- data/spec/schemas/{generated.rb → my_namespace/generated.rb} +28 -32
- data/spec/schemas/{my_nested_schema.rb → my_namespace/my_nested_schema.rb} +23 -16
- data/spec/schemas/{my_schema.rb → my_namespace/my_schema.rb} +12 -5
- data/spec/schemas/my_namespace/my_schema_compound_key.rb +41 -0
- data/spec/schemas/my_namespace/my_schema_id_key.rb +36 -0
- data/spec/schemas/{my_schema_key.rb → my_namespace/my_schema_key.rb} +3 -3
- data/spec/schemas/my_namespace/my_schema_with_boolean.rb +41 -0
- data/spec/schemas/{my_schema_with_circular_reference.rb → my_namespace/my_schema_with_circular_reference.rb} +15 -10
- data/spec/schemas/{my_schema_with_complex_type.rb → my_namespace/my_schema_with_complex_type.rb} +34 -49
- data/spec/schemas/my_namespace/my_schema_with_date_time.rb +56 -0
- data/spec/schemas/my_namespace/my_schema_with_id.rb +51 -0
- data/spec/schemas/my_namespace/my_schema_with_unique_id.rb +56 -0
- data/spec/schemas/my_namespace/wibble.rb +76 -0
- data/spec/schemas/my_namespace/widget.rb +56 -0
- data/spec/schemas/my_namespace/widget_the_second.rb +56 -0
- data/spec/schemas/request/create_topic.rb +36 -0
- data/spec/schemas/request/index.rb +36 -0
- data/spec/schemas/request/update_request.rb +36 -0
- data/spec/schemas/response/create_topic.rb +36 -0
- data/spec/schemas/response/index.rb +36 -0
- data/spec/schemas/response/update_response.rb +36 -0
- data/spec/snapshots/consumers-no-nest.snap +93 -86
- data/spec/snapshots/consumers.snap +94 -87
- data/spec/snapshots/consumers_and_producers-no-nest.snap +108 -87
- data/spec/snapshots/consumers_and_producers.snap +109 -88
- data/spec/snapshots/consumers_circular-no-nest.snap +93 -86
- data/spec/snapshots/consumers_circular.snap +94 -87
- data/spec/snapshots/consumers_complex_types-no-nest.snap +93 -86
- data/spec/snapshots/consumers_complex_types.snap +94 -87
- data/spec/snapshots/consumers_nested-no-nest.snap +93 -86
- data/spec/snapshots/consumers_nested.snap +94 -87
- data/spec/snapshots/namespace_folders.snap +111 -90
- data/spec/snapshots/producers_with_key-no-nest.snap +94 -87
- data/spec/snapshots/producers_with_key.snap +95 -88
- data/spec/spec_helper.rb +2 -1
- metadata +48 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ee238a0bcc822c984f19d5a58d1bea52025407d931654371831b0104fcb5aed
|
4
|
+
data.tar.gz: 5b767073027dae54910c69be504ac2da023d540557ef592417f1f60254f9e3f3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 904066c010866aaa6ca1173bbdf4e4044c578ac28df8a0ebcf846c25c73cd484fbeb15dea827c3b64935a8f7588f4a62b65d1bdf6f28604d0f1e588cdb8cb15a
|
7
|
+
data.tar.gz: 3cec3d2ae05d855fb9835252646b6cdef16034f600b0c1b7ed169fc8b7969bb0d6a9847fd5b35092e29ca910daa91cad6b3d838425a3b577dc484d7937af1339
|
data/CHANGELOG.md
CHANGED
@@ -7,7 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
7
7
|
|
8
8
|
## UNRELEASED
|
9
9
|
|
10
|
-
# 1.16.
|
10
|
+
# 1.16.3 - 2022-09-08
|
11
|
+
|
12
|
+
- Add the `tombstone` method to schema classes.
|
13
|
+
|
14
|
+
# 1.16.2 - 2022-09-07
|
15
|
+
|
16
|
+
- Added support of post_process method in ActiveRecordProducer
|
17
|
+
|
18
|
+
# 1.16.1 - 2022-08-03
|
11
19
|
|
12
20
|
- Fix issues with `enum` schema classes (e.g. equality not working, `to_s` not working)
|
13
21
|
- Changed assumption in the base schema class that it was a record (e.g. defining `to_h` instead of `as_json`). Moved record functionality to the record base class.
|
data/README.md
CHANGED
@@ -785,6 +785,21 @@ have one process running at a time. If a particular poll takes longer than
|
|
785
785
|
the poll interval (i.e. interval is set at 1 minute but it takes 75 seconds)
|
786
786
|
the next poll will begin immediately following the first one completing.
|
787
787
|
|
788
|
+
To Post-Process records that are sent to Kafka:
|
789
|
+
|
790
|
+
You need to define one additional method in your producer class to post-process the messages sent to Kafka.
|
791
|
+
|
792
|
+
```ruby
|
793
|
+
class MyProducer < Deimos::ActiveRecordProducer
|
794
|
+
...
|
795
|
+
def post_process(batch)
|
796
|
+
# If you need to do some extra actions with
|
797
|
+
# the collection of elements you just sent to Kafka
|
798
|
+
# write some code here
|
799
|
+
end
|
800
|
+
end
|
801
|
+
```
|
802
|
+
|
788
803
|
## Running consumers
|
789
804
|
|
790
805
|
Deimos includes a rake task. Once it's in your gemfile, just run
|
@@ -824,6 +839,8 @@ One additional configuration option indicates whether nested records should be g
|
|
824
839
|
|
825
840
|
config.schema.nest_child_schemas = false # Flatten all classes into one directory
|
826
841
|
|
842
|
+
You can generate a tombstone message (with only a key and no value) by calling the `YourSchemaClass.tombstone(key)` method. If you're using a `:field` key config, you can pass in just the key scalar value. If using a key schema, you can pass it in as a hash or as another schema class.
|
843
|
+
|
827
844
|
### Consumer
|
828
845
|
|
829
846
|
The consumer interface uses the `decode_message` method to turn JSON hash into the Schemas
|
@@ -44,6 +44,7 @@ module Deimos
|
|
44
44
|
generate_payload(attrs, record).with_indifferent_access
|
45
45
|
end
|
46
46
|
self.publish_list(messages, force_send: force_send)
|
47
|
+
self.post_process(records)
|
47
48
|
end
|
48
49
|
|
49
50
|
# Generate the payload, given a list of attributes or a record..
|
@@ -85,6 +86,12 @@ module Deimos
|
|
85
86
|
time_to
|
86
87
|
)
|
87
88
|
end
|
89
|
+
|
90
|
+
# Post process records after publishing
|
91
|
+
# @param records [Array<ActiveRecord::Base>]
|
92
|
+
def post_process(_records)
|
93
|
+
end
|
94
|
+
|
88
95
|
end
|
89
96
|
end
|
90
97
|
end
|
@@ -8,10 +8,16 @@ module Deimos
|
|
8
8
|
# Base Class of Record Classes generated from Avro.
|
9
9
|
class Record < Base
|
10
10
|
|
11
|
+
attr_accessor :tombstone_key
|
12
|
+
|
11
13
|
# Converts the object attributes to a hash which can be used for Kafka
|
12
14
|
# @return [Hash] the payload as a hash.
|
13
15
|
def to_h
|
14
|
-
self.
|
16
|
+
if self.tombstone_key
|
17
|
+
{ payload_key: self.tombstone_key&.as_json }
|
18
|
+
else
|
19
|
+
self.as_json
|
20
|
+
end
|
15
21
|
end
|
16
22
|
|
17
23
|
# Merge a hash or an identical schema object with this one and return a new object.
|
data/lib/deimos/version.rb
CHANGED
@@ -20,7 +20,7 @@
|
|
20
20
|
<%- if @field_assignments.select{ |h| !h[:is_schema_class] }.any? -%>
|
21
21
|
### Attribute Accessors ###
|
22
22
|
<%- @field_assignments.select{ |h| !h[:is_schema_class] }.each do |method_definition| -%>
|
23
|
-
# @
|
23
|
+
# @return [<%= method_definition[:deimos_type] %>]
|
24
24
|
attr_accessor :<%= method_definition[:field].name %>
|
25
25
|
<%- end -%>
|
26
26
|
|
@@ -28,14 +28,14 @@
|
|
28
28
|
<%- if @field_assignments.select{ |h| h[:is_schema_class] }.any? -%>
|
29
29
|
### Attribute Writers ###
|
30
30
|
<%- @field_assignments.select{ |h| h[:is_schema_class] }.each do |method_definition| -%>
|
31
|
-
# @
|
31
|
+
# @return [<%= method_definition[:deimos_type] %>]
|
32
32
|
def <%= method_definition[:field].name %>=(<%= method_definition[:method_argument] %>)
|
33
33
|
<%- if method_definition[:field_type] == :array -%>
|
34
|
-
@<%= method_definition[:field].name %> = values
|
34
|
+
@<%= method_definition[:field].name %> = values&.map do |value|
|
35
35
|
<%= method_definition[:field_initialization] %>
|
36
36
|
end
|
37
37
|
<%- elsif method_definition[:field_type] == :map -%>
|
38
|
-
@<%= method_definition[:field].name %> = values
|
38
|
+
@<%= method_definition[:field].name %> = values&.transform_values do |value|
|
39
39
|
<%= method_definition[:field_initialization] %>
|
40
40
|
end
|
41
41
|
<%- else -%>
|
@@ -62,7 +62,15 @@
|
|
62
62
|
def namespace
|
63
63
|
'<%= @current_schema.namespace %>'
|
64
64
|
end
|
65
|
-
|
65
|
+
<%- if @tombstone_assignment %>
|
66
|
+
def self.tombstone(key)
|
67
|
+
record = self.new
|
68
|
+
<%- if @tombstone_assignment.present? -%>
|
69
|
+
<%= @tombstone_assignment %>
|
70
|
+
<%- end -%>
|
71
|
+
record
|
72
|
+
end
|
73
|
+
<%- end %>
|
66
74
|
# @override
|
67
75
|
def as_json(_opts={})
|
68
76
|
{
|
@@ -41,16 +41,16 @@ module Deimos
|
|
41
41
|
# Deimos Consumer or Producer Configuration object
|
42
42
|
# @param schema_name [String]
|
43
43
|
# @param namespace [String]
|
44
|
-
# @param
|
45
|
-
def generate_classes(schema_name, namespace,
|
44
|
+
# @param key_config [Hash,nil]
|
45
|
+
def generate_classes(schema_name, namespace, key_config)
|
46
46
|
schema_base = Deimos.schema_backend(schema: schema_name, namespace: namespace)
|
47
47
|
schema_base.load_schema
|
48
|
-
if
|
49
|
-
key_schema_base = Deimos.schema_backend(schema:
|
48
|
+
if key_config&.dig(:schema)
|
49
|
+
key_schema_base = Deimos.schema_backend(schema: key_config[:schema], namespace: namespace)
|
50
50
|
key_schema_base.load_schema
|
51
|
-
generate_class_from_schema_base(key_schema_base)
|
51
|
+
generate_class_from_schema_base(key_schema_base, key_config: nil)
|
52
52
|
end
|
53
|
-
generate_class_from_schema_base(schema_base,
|
53
|
+
generate_class_from_schema_base(schema_base, key_config: key_config)
|
54
54
|
end
|
55
55
|
|
56
56
|
# @param schema [Avro::Schema::NamedSchema]
|
@@ -83,8 +83,8 @@ module Deimos
|
|
83
83
|
end
|
84
84
|
|
85
85
|
# @param schema_base [Deimos::SchemaBackends::Base]
|
86
|
-
# @param
|
87
|
-
def generate_class_from_schema_base(schema_base,
|
86
|
+
# @param key_config [Hash,nil]
|
87
|
+
def generate_class_from_schema_base(schema_base, key_config: nil)
|
88
88
|
@discovered_schemas = Set.new
|
89
89
|
@sub_schema_templates = []
|
90
90
|
schemas = collect_all_schemas(schema_base.schema_store.schemas.values)
|
@@ -93,11 +93,11 @@ module Deimos
|
|
93
93
|
sub_schemas = schemas.reject { |s| s.name == schema_base.schema }.sort_by(&:name)
|
94
94
|
if Deimos.config.schema.nest_child_schemas
|
95
95
|
@sub_schema_templates = sub_schemas.map do |schema|
|
96
|
-
_generate_class_template_from_schema(schema)
|
96
|
+
_generate_class_template_from_schema(schema, nil)
|
97
97
|
end
|
98
|
-
write_file(main_schema,
|
98
|
+
write_file(main_schema, key_config)
|
99
99
|
else
|
100
|
-
write_file(main_schema,
|
100
|
+
write_file(main_schema, key_config)
|
101
101
|
sub_schemas.each do |schema|
|
102
102
|
write_file(schema, nil)
|
103
103
|
end
|
@@ -105,9 +105,9 @@ module Deimos
|
|
105
105
|
end
|
106
106
|
|
107
107
|
# @param schema [Avro::Schema::NamedSchema]
|
108
|
-
# @param key_schema_base [
|
109
|
-
def write_file(schema,
|
110
|
-
class_template = _generate_class_template_from_schema(schema,
|
108
|
+
# @param key_schema_base [Hash]
|
109
|
+
def write_file(schema, key_config)
|
110
|
+
class_template = _generate_class_template_from_schema(schema, key_config)
|
111
111
|
@modules = Utils::SchemaClass.modules_for(schema.namespace)
|
112
112
|
@main_class_definition = class_template
|
113
113
|
|
@@ -154,7 +154,7 @@ module Deimos
|
|
154
154
|
key_schema_name = config.key_config[:schema]
|
155
155
|
found_schemas.add("#{namespace}.#{schema_name}")
|
156
156
|
found_schemas.add("#{namespace}.#{key_schema_name}") if key_schema_name
|
157
|
-
generate_classes(schema_name, namespace,
|
157
|
+
generate_classes(schema_name, namespace, config.key_config)
|
158
158
|
end
|
159
159
|
|
160
160
|
Deimos.config.consumer_objects.each do |config|
|
@@ -163,7 +163,7 @@ module Deimos
|
|
163
163
|
key_schema_name = config.key_config[:schema]
|
164
164
|
found_schemas.add("#{namespace}.#{schema_name}")
|
165
165
|
found_schemas.add("#{namespace}.#{key_schema_name}") if key_schema_name
|
166
|
-
generate_classes(schema_name, namespace,
|
166
|
+
generate_classes(schema_name, namespace, config.key_config)
|
167
167
|
end
|
168
168
|
|
169
169
|
generate_from_schema_files(found_schemas)
|
@@ -191,10 +191,10 @@ module Deimos
|
|
191
191
|
end
|
192
192
|
|
193
193
|
# @param schema[Avro::Schema::NamedSchema]
|
194
|
-
# @param
|
194
|
+
# @param key_config[Hash,nil]
|
195
195
|
# @return [String]
|
196
|
-
def _generate_class_template_from_schema(schema,
|
197
|
-
_set_instance_variables(schema,
|
196
|
+
def _generate_class_template_from_schema(schema, key_config)
|
197
|
+
_set_instance_variables(schema, key_config)
|
198
198
|
|
199
199
|
temp = schema.is_a?(Avro::Schema::RecordSchema) ? _record_class_template : _enum_class_template
|
200
200
|
res = ERB.new(temp, nil, '-')
|
@@ -202,20 +202,38 @@ module Deimos
|
|
202
202
|
end
|
203
203
|
|
204
204
|
# @param schema[Avro::Schema::NamedSchema]
|
205
|
-
# @param
|
206
|
-
def _set_instance_variables(schema,
|
205
|
+
# @param key_config [Hash,nil]
|
206
|
+
def _set_instance_variables(schema, key_config)
|
207
207
|
schema_is_record = schema.is_a?(Avro::Schema::RecordSchema)
|
208
208
|
@current_schema = schema
|
209
209
|
return unless schema_is_record
|
210
210
|
|
211
211
|
@fields = fields(schema)
|
212
|
-
|
212
|
+
key_schema = nil
|
213
|
+
if key_config&.dig(:schema)
|
214
|
+
key_schema_base = Deimos.schema_backend(schema: key_config[:schema], namespace: schema.namespace)
|
213
215
|
key_schema_base.load_schema
|
214
216
|
key_schema = key_schema_base.schema_store.schemas.values.first
|
215
217
|
@fields << Deimos::SchemaField.new('payload_key', key_schema, [], nil)
|
216
218
|
end
|
217
219
|
@initialization_definition = _initialization_definition
|
218
220
|
@field_assignments = _field_assignments
|
221
|
+
@tombstone_assignment = _tombstone_assignment(key_config, key_schema)
|
222
|
+
end
|
223
|
+
|
224
|
+
def _tombstone_assignment(key_config, key_schema)
|
225
|
+
return nil unless key_config
|
226
|
+
|
227
|
+
if key_config[:plain]
|
228
|
+
"record.tombstone_key = key"
|
229
|
+
elsif key_config[:field]
|
230
|
+
"record.tombstone_key = key\n record.#{key_config[:field]} = key"
|
231
|
+
elsif key_schema
|
232
|
+
field_base_type = _field_type(key_schema)
|
233
|
+
"record.tombstone_key = #{field_base_type}.initialize_from_value(key)\n record.payload_key = key"
|
234
|
+
else
|
235
|
+
''
|
236
|
+
end
|
219
237
|
end
|
220
238
|
|
221
239
|
# Defines the initialization method for Schema Records with one keyword argument per line
|
@@ -0,0 +1,68 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
require 'action_controller/railtie'
|
3
|
+
require 'deimos'
|
4
|
+
require 'deimos/metrics/mock'
|
5
|
+
require 'deimos/tracing/mock'
|
6
|
+
# not sure why "require deimos/utils/schema_class" doesn't work
|
7
|
+
require_relative 'lib/deimos/utils/schema_class'
|
8
|
+
|
9
|
+
class DeimosApp < Rails::Application
|
10
|
+
end
|
11
|
+
DeimosApp.initialize!
|
12
|
+
|
13
|
+
class MyConsumer < Deimos::Consumer
|
14
|
+
def consume(payload, metadata); end
|
15
|
+
end
|
16
|
+
|
17
|
+
require_relative "./lib/generators/deimos/schema_class_generator"
|
18
|
+
|
19
|
+
Deimos.configure do |deimos_config|
|
20
|
+
deimos_config.schema.nest_child_schemas = true
|
21
|
+
deimos_config.schema.path = "spec/schemas"
|
22
|
+
deimos_config.schema.backend = :avro_validation
|
23
|
+
deimos_config.schema.generated_class_path = './spec/schemas'
|
24
|
+
deimos_config.schema.generate_namespace_folders = true
|
25
|
+
deimos_config.schema.nest_child_schemas = true
|
26
|
+
|
27
|
+
consumer do
|
28
|
+
class_name 'MyConsumer'
|
29
|
+
topic 'MyTopic'
|
30
|
+
schema 'Generated'
|
31
|
+
namespace 'com.my-namespace'
|
32
|
+
key_config field: :a_string
|
33
|
+
end
|
34
|
+
|
35
|
+
consumer do
|
36
|
+
class_name 'MyConsumer'
|
37
|
+
topic 'MyTopic'
|
38
|
+
schema 'MySchemaWithComplexTypes'
|
39
|
+
namespace 'com.my-namespace'
|
40
|
+
key_config field: :test_id
|
41
|
+
end
|
42
|
+
|
43
|
+
consumer do
|
44
|
+
class_name 'MyConsumer'
|
45
|
+
topic 'MyTopic'
|
46
|
+
schema 'MySchemaWithCircularReference'
|
47
|
+
namespace 'com.my-namespace'
|
48
|
+
key_config none: true
|
49
|
+
end
|
50
|
+
|
51
|
+
consumer do
|
52
|
+
class_name 'MyConsumer'
|
53
|
+
topic 'MyTopic'
|
54
|
+
schema 'MyNestedSchema'
|
55
|
+
namespace 'com.my-namespace'
|
56
|
+
key_config field: :test_id
|
57
|
+
end
|
58
|
+
|
59
|
+
producer do
|
60
|
+
class_name 'MyConsumer'
|
61
|
+
topic 'MyTopic'
|
62
|
+
schema 'MySchema'
|
63
|
+
namespace 'com.my-namespace'
|
64
|
+
key_config schema: 'MySchema_key'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
Deimos::Generators::SchemaClassGenerator.new.generate
|
@@ -45,6 +45,24 @@ describe Deimos::ActiveRecordProducer do
|
|
45
45
|
record_class Widget
|
46
46
|
end
|
47
47
|
stub_const('MyProducerWithUniqueID', producer_class)
|
48
|
+
|
49
|
+
producer_class = Class.new(Deimos::ActiveRecordProducer) do
|
50
|
+
schema 'MySchemaWithUniqueId'
|
51
|
+
namespace 'com.my-namespace'
|
52
|
+
topic 'my-topic-with-unique-id'
|
53
|
+
key_config field: :id
|
54
|
+
record_class Widget
|
55
|
+
|
56
|
+
# :nodoc:
|
57
|
+
def self.post_process(batch)
|
58
|
+
batch.each do |message|
|
59
|
+
message.test_id = 'post_processed'
|
60
|
+
message.save!
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
stub_const('MyProducerWithPostProcess', producer_class)
|
48
66
|
end
|
49
67
|
|
50
68
|
describe 'produce' do
|
@@ -85,6 +103,12 @@ describe Deimos::ActiveRecordProducer do
|
|
85
103
|
)
|
86
104
|
end
|
87
105
|
|
106
|
+
it 'should post process the batch of records in #send_events' do
|
107
|
+
widget = Widget.create!(test_id: 'abc3', some_int: 4)
|
108
|
+
MyProducerWithPostProcess.send_events([widget])
|
109
|
+
expect(widget.reload.test_id).to eq('post_processed')
|
110
|
+
end
|
111
|
+
|
88
112
|
end
|
89
113
|
end
|
90
114
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
RSpec.describe Schemas::MyNamespace::MySchema do
|
2
|
+
let(:key) { Schemas::MyNamespace::MySchemaKey.new(test_id: 123) }
|
3
|
+
|
4
|
+
it 'should produce a tombstone with a hash' do
|
5
|
+
result = described_class.tombstone({test_id: 123})
|
6
|
+
expect(result.payload_key).to eq(key)
|
7
|
+
expect(result.to_h).to eq({ payload_key: { 'test_id' => 123}})
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should work with a record' do
|
11
|
+
key = Schemas::MyNamespace::MySchemaKey.new(test_id: 123)
|
12
|
+
result = described_class.tombstone(key)
|
13
|
+
expect(result.payload_key).to eq(key)
|
14
|
+
expect(result.to_h).to eq({ payload_key: { 'test_id' => 123}})
|
15
|
+
end
|
16
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# For testing the generated class.
|
4
|
-
RSpec.describe Schemas::MySchemaWithComplexType do
|
4
|
+
RSpec.describe Schemas::MyNamespace::MySchemaWithComplexType do
|
5
5
|
let(:payload_hash) do
|
6
6
|
{
|
7
7
|
test_id: 'test id',
|
@@ -9,16 +9,16 @@ RSpec.describe Schemas::MySchemaWithComplexType do
|
|
9
9
|
test_string_array: %w(abc def),
|
10
10
|
test_int_array: [123, 456],
|
11
11
|
some_integer_map: { 'int_1' => 1, 'int_2' => 2 },
|
12
|
-
some_record:
|
13
|
-
some_optional_record:
|
14
|
-
some_record_array: [
|
15
|
-
|
12
|
+
some_record: described_class::ARecord.new(a_record_field: 'field 1'),
|
13
|
+
some_optional_record: described_class::ARecord.new(a_record_field: 'field 2'),
|
14
|
+
some_record_array: [described_class::ARecord.new(a_record_field: 'field 3'),
|
15
|
+
described_class::ARecord.new(a_record_field: 'field 4')],
|
16
16
|
some_record_map: {
|
17
|
-
'record_1' =>
|
18
|
-
'record_2' =>
|
17
|
+
'record_1' => described_class::ARecord.new(a_record_field: 'field 5'),
|
18
|
+
'record_2' => described_class::ARecord.new(a_record_field: 'field 6')
|
19
19
|
},
|
20
|
-
some_enum_array: [
|
21
|
-
|
20
|
+
some_enum_array: [described_class::AnEnum.new('sym1'),
|
21
|
+
described_class::AnEnum.new('sym2')]
|
22
22
|
}
|
23
23
|
end
|
24
24
|
|
@@ -51,6 +51,14 @@ RSpec.describe Schemas::MySchemaWithComplexType do
|
|
51
51
|
|
52
52
|
end
|
53
53
|
|
54
|
+
describe '.tombstone' do
|
55
|
+
it 'should return a tombstone' do
|
56
|
+
record = described_class.tombstone('foo')
|
57
|
+
expect(record.tombstone_key).to eq('foo')
|
58
|
+
expect(record.to_h).to eq({payload_key: 'foo'})
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
54
62
|
describe 'base class methods' do
|
55
63
|
let(:klass) do
|
56
64
|
described_class.new(**payload_hash)
|
@@ -116,7 +124,7 @@ RSpec.describe Schemas::MySchemaWithComplexType do
|
|
116
124
|
payload_hash.delete(:some_record)
|
117
125
|
klass = described_class.new(**payload_hash)
|
118
126
|
expect(klass.some_record).
|
119
|
-
to eq(
|
127
|
+
to eq(described_class::ARecord.new(a_record_field: 'Test String'))
|
120
128
|
end
|
121
129
|
|
122
130
|
it 'should set some_record to nil' do
|
@@ -139,26 +147,26 @@ RSpec.describe Schemas::MySchemaWithComplexType do
|
|
139
147
|
|
140
148
|
it 'should get the value of some_record_array' do
|
141
149
|
some_record_array = klass.some_record_array
|
142
|
-
expect(some_record_array.first).to be_instance_of(
|
150
|
+
expect(some_record_array.first).to be_instance_of(described_class::ARecord)
|
143
151
|
expect(some_record_array.first.a_record_field).to eq('field 3')
|
144
152
|
end
|
145
153
|
|
146
154
|
it 'should get the value of some_record_map' do
|
147
155
|
some_record_map = klass.some_record_map
|
148
156
|
expect(some_record_map['record_1']).
|
149
|
-
to be_instance_of(
|
157
|
+
to be_instance_of(described_class::ARecord)
|
150
158
|
expect(some_record_map['record_1'].a_record_field).to eq('field 5')
|
151
159
|
end
|
152
160
|
|
153
161
|
it 'should get the value of some_enum_array' do
|
154
162
|
some_enum_array = klass.some_enum_array
|
155
|
-
expect(some_enum_array.first).to be_instance_of(
|
163
|
+
expect(some_enum_array.first).to be_instance_of(described_class::AnEnum)
|
156
164
|
expect(some_enum_array.first.value).to eq('sym1')
|
157
165
|
end
|
158
166
|
|
159
167
|
it 'should get the value of some_record' do
|
160
168
|
record = klass.some_record
|
161
|
-
expect(record).to be_instance_of(
|
169
|
+
expect(record).to be_instance_of(described_class::ARecord)
|
162
170
|
expect(record.a_record_field).to eq('field 1')
|
163
171
|
expect(record.to_h).to eq({ 'a_record_field' => 'field 1' })
|
164
172
|
end
|
@@ -180,40 +188,40 @@ RSpec.describe Schemas::MySchemaWithComplexType do
|
|
180
188
|
|
181
189
|
it 'should modify the value of some_optional_record' do
|
182
190
|
expect(klass.some_optional_record).
|
183
|
-
to eq(
|
184
|
-
klass.some_optional_record =
|
191
|
+
to eq(described_class::ARecord.new(a_record_field: 'field 2'))
|
192
|
+
klass.some_optional_record = described_class::ARecord.
|
185
193
|
new(a_record_field: 'new field')
|
186
194
|
|
187
|
-
expect(klass.some_optional_record).to eq(
|
195
|
+
expect(klass.some_optional_record).to eq(described_class::ARecord.
|
188
196
|
new(a_record_field: 'new field'))
|
189
197
|
expect(klass.some_optional_record.as_json).to eq({ 'a_record_field' => 'new field' })
|
190
198
|
end
|
191
199
|
|
192
200
|
it 'should accept a hash object inner records' do
|
193
201
|
klass.some_optional_record = { a_record_field: 'new field' }
|
194
|
-
expect(klass.some_optional_record).
|
195
|
-
new(a_record_field: 'new field'))
|
202
|
+
expect(klass.some_optional_record).
|
203
|
+
to eq(described_class::ARecord.new(a_record_field: 'new field'))
|
196
204
|
expect(klass.some_optional_record.as_json).to eq({ 'a_record_field' => 'new field' })
|
197
205
|
end
|
198
206
|
|
199
207
|
it 'should modify the value of some_enum_array' do
|
200
208
|
klass.some_enum_array.first.value = 'new_sym'
|
201
209
|
expect(klass.some_enum_array.first).
|
202
|
-
to eq(
|
210
|
+
to eq(described_class::AnEnum.new('new_sym'))
|
203
211
|
|
204
|
-
klass.some_enum_array.second.an_enum =
|
212
|
+
klass.some_enum_array.second.an_enum = described_class::AnEnum.
|
205
213
|
new('other_sym')
|
206
214
|
expect(klass.some_enum_array.second.an_enum).to eq('other_sym')
|
207
215
|
end
|
208
216
|
|
209
217
|
it 'should modify the value of some_record_map' do
|
210
218
|
klass.some_record_map['record_1'].a_record_field = 'new field'
|
211
|
-
expect(klass.some_record_map['record_1']).to eq(
|
219
|
+
expect(klass.some_record_map['record_1']).to eq(described_class::ARecord.
|
212
220
|
new(a_record_field: 'new field'))
|
213
221
|
|
214
|
-
klass.some_record_map['record_2'] =
|
222
|
+
klass.some_record_map['record_2'] = described_class::ARecord.
|
215
223
|
new(a_record_field: 'other field')
|
216
|
-
expect(klass.some_record_map['record_2']).to eq(
|
224
|
+
expect(klass.some_record_map['record_2']).to eq(described_class::ARecord.
|
217
225
|
new(a_record_field: 'other field'))
|
218
226
|
end
|
219
227
|
end
|
data/spec/producer_spec.rb
CHANGED
@@ -397,7 +397,7 @@ module ProducerTest
|
|
397
397
|
end
|
398
398
|
expect(MyProducer.encoder).to receive(:validate).and_raise('OH NOES')
|
399
399
|
expect {
|
400
|
-
MyProducer.publish(Schemas::MySchema.new(test_id: 'foo', some_int: 'invalid'))
|
400
|
+
MyProducer.publish(Schemas::MyNamespace::MySchema.new(test_id: 'foo', some_int: 'invalid'))
|
401
401
|
}.to raise_error('OH NOES')
|
402
402
|
Deimos.unsubscribe(subscriber)
|
403
403
|
end
|
@@ -420,8 +420,8 @@ module ProducerTest
|
|
420
420
|
).and_call_original
|
421
421
|
|
422
422
|
MyProducer.publish_list(
|
423
|
-
[Schemas::MySchema.new(test_id: 'foo', some_int: 123),
|
424
|
-
Schemas::MySchema.new(test_id: 'bar', some_int: 124)]
|
423
|
+
[Schemas::MyNamespace::MySchema.new(test_id: 'foo', some_int: 123),
|
424
|
+
Schemas::MyNamespace::MySchema.new(test_id: 'bar', some_int: 124)]
|
425
425
|
)
|
426
426
|
expect('my-topic').to have_sent('test_id' => 'foo', 'some_int' => 123)
|
427
427
|
expect('your-topic').not_to have_sent('test_id' => 'foo', 'some_int' => 123)
|
@@ -432,8 +432,8 @@ module ProducerTest
|
|
432
432
|
expect(described_class).not_to receive(:produce_batch)
|
433
433
|
Deimos.configure { |c| c.producers.disabled = true }
|
434
434
|
MyProducer.publish_list(
|
435
|
-
[Schemas::MySchema.new(test_id: 'foo', some_int: 123),
|
436
|
-
Schemas::MySchema.new(test_id: 'bar', some_int: 124)]
|
435
|
+
[Schemas::MyNamespace::MySchema.new(test_id: 'foo', some_int: 123),
|
436
|
+
Schemas::MyNamespace::MySchema.new(test_id: 'bar', some_int: 124)]
|
437
437
|
)
|
438
438
|
expect(MyProducer.topic).not_to have_sent(anything)
|
439
439
|
end
|
@@ -452,8 +452,8 @@ module ProducerTest
|
|
452
452
|
}, { topic: 'my-topic-value' })
|
453
453
|
|
454
454
|
MyProducer.publish_list(
|
455
|
-
[Schemas::MySchema.new(test_id: 'foo', some_int: 123),
|
456
|
-
Schemas::MySchema.new(test_id: 'bar', some_int: 124)]
|
455
|
+
[Schemas::MyNamespace::MySchema.new(test_id: 'foo', some_int: 123),
|
456
|
+
Schemas::MyNamespace::MySchema.new(test_id: 'bar', some_int: 124)]
|
457
457
|
)
|
458
458
|
end
|
459
459
|
|
@@ -464,19 +464,19 @@ module ProducerTest
|
|
464
464
|
{ topic: 'my-topic2-key' })
|
465
465
|
|
466
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' })]
|
467
|
+
[Schemas::MyNamespace::MySchema.new(test_id: 'foo', some_int: 123, payload_key: { 'test_id' => 'foo_key' }),
|
468
|
+
Schemas::MyNamespace::MySchema.new(test_id: 'bar', some_int: 124, payload_key: { 'test_id' => 'bar_key' })]
|
469
469
|
)
|
470
470
|
end
|
471
471
|
|
472
472
|
it 'should properly encode and coerce values with a nested record' do
|
473
473
|
expect(MyNestedSchemaProducer.encoder).to receive(:encode_key).with('test_id', 'foo', topic: 'my-topic-key')
|
474
474
|
MyNestedSchemaProducer.publish(
|
475
|
-
Schemas::MyNestedSchema.new(
|
475
|
+
Schemas::MyNamespace::MyNestedSchema.new(
|
476
476
|
test_id: 'foo',
|
477
477
|
test_float: BigDecimal('123.456'),
|
478
478
|
test_array: ['1'],
|
479
|
-
some_nested_record: Schemas::MyNestedSchema::MyNestedRecord.new(
|
479
|
+
some_nested_record: Schemas::MyNamespace::MyNestedSchema::MyNestedRecord.new(
|
480
480
|
some_int: 123,
|
481
481
|
some_float: BigDecimal('456.789'),
|
482
482
|
some_string: '123',
|