deimos-ruby 1.12.4 → 1.13.0
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/.gemfiles/avro_turf-0.gemfile +3 -0
- data/.gemfiles/avro_turf-1.gemfile +3 -0
- data/.github/workflows/ci.yml +49 -0
- data/.gitignore +2 -1
- data/CHANGELOG.md +16 -0
- data/README.md +3 -3
- data/bin/console +15 -0
- data/deimos-ruby.gemspec +1 -1
- data/docs/CONFIGURATION.md +15 -1
- data/lib/deimos/config/configuration.rb +62 -2
- data/lib/deimos/config/phobos_config.rb +24 -0
- data/lib/deimos/metrics/datadog.rb +1 -1
- data/lib/deimos/schema_backends/avro_schema_registry.rb +4 -1
- data/lib/deimos/version.rb +1 -1
- data/lib/generators/deimos/schema_class_generator.rb +27 -1
- data/spec/active_record_batch_consumer_spec.rb +1 -1
- data/spec/active_record_consumer_spec.rb +6 -6
- data/spec/active_record_producer_spec.rb +1 -1
- data/spec/config/configuration_spec.rb +25 -1
- data/spec/consumer_spec.rb +17 -17
- data/spec/generators/schema_class/my_schema_with_complex_types_spec.rb +3 -2
- data/spec/generators/schema_class_generator_spec.rb +2 -2
- data/spec/producer_spec.rb +24 -24
- data/spec/schema_backends/avro_base_shared.rb +2 -2
- data/spec/schema_classes/my_schema_key.rb +2 -2
- data/spec/schema_classes/my_schema_with_complex_types.rb +34 -2
- data/spec/schemas/com/my-namespace/{MySchemaCompound-key.avsc → MySchemaCompound_key.avsc} +1 -1
- data/spec/schemas/com/my-namespace/MySchemaWithComplexTypes.avsc +11 -0
- data/spec/schemas/com/my-namespace/{MySchema-key.avsc → MySchema_key.avsc} +1 -1
- data/spec/utils/inline_consumer_spec.rb +2 -2
- metadata +19 -9
- data/Gemfile.lock +0 -292
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c57c2700b01b998f358cb4e96ee6e6b2c1c8c32936d741b2371182a6017f7adc
|
4
|
+
data.tar.gz: 440bf25b629ba34da51cd1c0a1b443858bcd4ca270fed800b6e277c050b0741f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 05df77f7f8890959ea91817a7497c11348d3b68f349462275a1ffb133a1c8194d9ee2282ac3dbe14a389bd09f16f059c88b467c05fb959c1a334b7c3789ade92
|
7
|
+
data.tar.gz: bc8b8c832a7399a6c60a4a0ac71582aff4ff324d5a2c9bb2a73241bb64de3a958d09208e1c127d36e8b3c47077857224ec853aaea769ef00aaef88dc6e6cf0e9
|
@@ -0,0 +1,49 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
pull_request:
|
5
|
+
push:
|
6
|
+
branches: [ master ]
|
7
|
+
|
8
|
+
env:
|
9
|
+
GIT_COMMIT_SHA: ${{ github.sha }}
|
10
|
+
GIT_BRANCH: ${{ github.ref }}
|
11
|
+
|
12
|
+
jobs:
|
13
|
+
linting:
|
14
|
+
runs-on: ubuntu-latest
|
15
|
+
env:
|
16
|
+
BUNDLE_WITH: lint
|
17
|
+
BUNDLE_WITHOUT: development:test
|
18
|
+
|
19
|
+
steps:
|
20
|
+
- uses: actions/checkout@v2
|
21
|
+
|
22
|
+
- name: Set up Ruby 2.7
|
23
|
+
uses: ruby/setup-ruby@v1
|
24
|
+
with:
|
25
|
+
ruby-version: 2.7
|
26
|
+
bundler-cache: true
|
27
|
+
|
28
|
+
- name: Rubocop
|
29
|
+
run: bundle exec rubocop --format progress
|
30
|
+
|
31
|
+
build:
|
32
|
+
runs-on: ubuntu-latest
|
33
|
+
env:
|
34
|
+
BUNDLE_GEMFILE: ${{ github.workspace }}/.gemfiles/${{ matrix.gemfile }}.gemfile
|
35
|
+
strategy:
|
36
|
+
fail-fast: false
|
37
|
+
matrix:
|
38
|
+
ruby: [ '2.6', '2.7', '3.0', '3.1' ]
|
39
|
+
gemfile: [ 'avro_turf-0', 'avro_turf-1' ]
|
40
|
+
|
41
|
+
steps:
|
42
|
+
- uses: actions/checkout@v2
|
43
|
+
- uses: ruby/setup-ruby@v1
|
44
|
+
with:
|
45
|
+
ruby-version: ${{ matrix.ruby }}
|
46
|
+
bundler-cache: true
|
47
|
+
|
48
|
+
- name: Test
|
49
|
+
run: bundle exec rspec
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
7
7
|
|
8
8
|
## UNRELEASED
|
9
9
|
|
10
|
+
# 1.13.0 - 2022-03-30
|
11
|
+
|
12
|
+
- Pass the Deimos logger to `AvroTurf::Messaging` for consistent logging
|
13
|
+
- Fix an issue with nullable enums not being included in the auto-generated schema class
|
14
|
+
|
15
|
+
# 1.12.6 - 2022-03-14
|
16
|
+
|
17
|
+
- Fix NameError when using Datadog Metrics
|
18
|
+
- Fix unwanted STDOUT output when loading the main `Deimos` module
|
19
|
+
|
20
|
+
# 1.12.5 - 2022-03-09
|
21
|
+
|
22
|
+
- Allow use of new avro_turf versions where child schemas are not listed with the top level schemas
|
23
|
+
- Add support for SASL authentication with brokers
|
24
|
+
- Add support for Basic auth with Schema Registry
|
25
|
+
|
10
26
|
# 1.12.4 - 2022-01-13
|
11
27
|
|
12
28
|
- Fix bug where schema controller mixin was using the schema name to register and not the namespaced schema name
|
data/README.md
CHANGED
@@ -259,7 +259,7 @@ like this:
|
|
259
259
|
```javascript
|
260
260
|
{
|
261
261
|
"namespace": "com.my-namespace",
|
262
|
-
"name": "
|
262
|
+
"name": "MySchema_key",
|
263
263
|
"type": "record",
|
264
264
|
"doc": "Key for com.my-namespace.MySchema",
|
265
265
|
"fields": [
|
@@ -934,8 +934,8 @@ The following metrics are reported:
|
|
934
934
|
|
935
935
|
### Configuring Metrics Providers
|
936
936
|
|
937
|
-
See the `metrics` field under [Configuration](
|
938
|
-
View all available Metrics Providers [here](lib/deimos/metrics
|
937
|
+
See the `metrics` field under [Configuration](#configuration).
|
938
|
+
View all available Metrics Providers [here](lib/deimos/metrics)
|
939
939
|
|
940
940
|
### Custom Metrics Providers
|
941
941
|
|
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'deimos'
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require 'irb'
|
15
|
+
IRB.start(__FILE__)
|
data/deimos-ruby.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.add_runtime_dependency('avro_turf', '
|
21
|
+
spec.add_runtime_dependency('avro_turf', '>= 0.11', '< 2')
|
22
22
|
spec.add_runtime_dependency('phobos', '>= 1.9', '< 3.0')
|
23
23
|
spec.add_runtime_dependency('ruby-kafka', '< 2')
|
24
24
|
spec.add_runtime_dependency('sigurd', '~> 0.0.1')
|
data/docs/CONFIGURATION.md
CHANGED
@@ -130,9 +130,21 @@ kafka.client_id|`phobos`|Identifier for this application.
|
|
130
130
|
kafka.connect_timeout|15|The socket timeout for connecting to the broker, in seconds.
|
131
131
|
kafka.socket_timeout|15|The socket timeout for reading and writing to the broker, in seconds.
|
132
132
|
kafka.ssl.enabled|false|Whether SSL is enabled on the brokers.
|
133
|
+
kafka.ssl.ca_certs_from_system|false|Use CA certs from system.
|
133
134
|
kafka.ssl.ca_cert|nil| A PEM encoded CA cert, a file path to the cert, or an Array of certs to use with an SSL connection.
|
134
135
|
kafka.ssl.client_cert|nil|A PEM encoded client cert to use with an SSL connection, or a file path to the cert.
|
135
136
|
kafka.ssl.client_cert_key|nil|A PEM encoded client cert key to use with an SSL connection.
|
137
|
+
kafka.sasl.enabled|false|Whether SASL is enabled on the brokers.
|
138
|
+
kafka.sasl.gssapi_principal|nil|A KRB5 principal.
|
139
|
+
kafka.sasl.gssapi_keytab|nil|A KRB5 keytab filepath.
|
140
|
+
kafka.sasl.plain_authzid|nil|Plain authorization ID.
|
141
|
+
kafka.sasl.plain_username|nil|Plain username.
|
142
|
+
kafka.sasl.plain_password|nil|Plain password.
|
143
|
+
kafka.sasl.scram_username|nil|SCRAM username.
|
144
|
+
kafka.sasl.scram_password|nil|SCRAM password.
|
145
|
+
kafka.sasl.scram_mechanism|nil|Scram mechanism, either "sha256" or "sha512".
|
146
|
+
kafka.sasl.enforce_ssl|nil|Whether to enforce SSL with SASL.
|
147
|
+
kafka.sasl.oauth_token_provider|nil|OAuthBearer Token Provider instance that implements method token. See {Sasl::OAuth#initialize}.
|
136
148
|
|
137
149
|
## Consumer Configuration
|
138
150
|
|
@@ -177,9 +189,11 @@ Config name|Default|Description
|
|
177
189
|
-----------|-------|-----------
|
178
190
|
schema.backend|`:mock`|Backend representing the schema encoder/decoder. You can see a full list [here](../lib/deimos/schema_backends).
|
179
191
|
schema.registry_url|`http://localhost:8081`|URL of the Confluent schema registry.
|
192
|
+
schema.user|nil|Basic auth user.
|
193
|
+
schema.password|nil|Basic auth password.
|
180
194
|
schema.path|nil|Local path to find your schemas.
|
181
195
|
schema.use_schema_classes|false|Set this to true to use generated schema classes in your application.
|
182
|
-
schema.
|
196
|
+
schema.generated_class_path|`app/lib/schema_classes`|Local path to generated schema classes.
|
183
197
|
|
184
198
|
## Database Producer Configuration
|
185
199
|
|
@@ -136,6 +136,58 @@ module Deimos
|
|
136
136
|
|
137
137
|
# Verify certificate hostname if supported (ruby >= 2.4.0)
|
138
138
|
setting :verify_hostname, true
|
139
|
+
|
140
|
+
# Use CA certs from system. This is useful to have enabled for Confluent Cloud
|
141
|
+
# @return [Boolean]
|
142
|
+
setting :ca_certs_from_system, false
|
143
|
+
end
|
144
|
+
|
145
|
+
setting :sasl do
|
146
|
+
# Whether SASL is enabled on the brokers.
|
147
|
+
# @return [Boolean]
|
148
|
+
setting :enabled
|
149
|
+
|
150
|
+
# A KRB5 principal.
|
151
|
+
# @return [String]
|
152
|
+
setting :gssapi_principal
|
153
|
+
|
154
|
+
# A KRB5 keytab filepath.
|
155
|
+
# @return [String]
|
156
|
+
setting :gssapi_keytab
|
157
|
+
|
158
|
+
# Plain authorization ID. It needs to default to '' in order for it to work.
|
159
|
+
# This is because Phobos expects it to be truthy for using plain SASL.
|
160
|
+
# @return [String]
|
161
|
+
setting :plain_authzid, ''
|
162
|
+
|
163
|
+
# Plain username.
|
164
|
+
# @return [String]
|
165
|
+
setting :plain_username
|
166
|
+
|
167
|
+
# Plain password.
|
168
|
+
# @return [String]
|
169
|
+
setting :plain_password
|
170
|
+
|
171
|
+
# SCRAM username.
|
172
|
+
# @return [String]
|
173
|
+
setting :scram_username
|
174
|
+
|
175
|
+
# SCRAM password.
|
176
|
+
# @return [String]
|
177
|
+
setting :scram_password
|
178
|
+
|
179
|
+
# Scram mechanism, either "sha256" or "sha512".
|
180
|
+
# @return [String]
|
181
|
+
setting :scram_mechanism
|
182
|
+
|
183
|
+
# Whether to enforce SSL with SASL.
|
184
|
+
# @return [Boolean]
|
185
|
+
setting :enforce_ssl
|
186
|
+
|
187
|
+
# OAuthBearer Token Provider instance that implements
|
188
|
+
# method token. See {Sasl::OAuth#initialize}.
|
189
|
+
# @return [Object]
|
190
|
+
setting :oauth_token_provider
|
139
191
|
end
|
140
192
|
end
|
141
193
|
|
@@ -272,6 +324,14 @@ module Deimos
|
|
272
324
|
# @return [String]
|
273
325
|
setting :registry_url, 'http://localhost:8081'
|
274
326
|
|
327
|
+
# Basic Auth user.
|
328
|
+
# @return [String]
|
329
|
+
setting :user
|
330
|
+
|
331
|
+
# Basic Auth password.
|
332
|
+
# @return [String]
|
333
|
+
setting :password
|
334
|
+
|
275
335
|
# Local path to look for schemas in.
|
276
336
|
# @return [String]
|
277
337
|
setting :path
|
@@ -287,11 +347,11 @@ module Deimos
|
|
287
347
|
|
288
348
|
# The configured metrics provider.
|
289
349
|
# @return [Metrics::Provider]
|
290
|
-
setting :metrics, Metrics::Mock.new
|
350
|
+
setting :metrics, default_proc: proc { Metrics::Mock.new }
|
291
351
|
|
292
352
|
# The configured tracing / APM provider.
|
293
353
|
# @return [Tracing::Provider]
|
294
|
-
setting :tracer, Tracing::Mock.new
|
354
|
+
setting :tracer, default_proc: proc { Tracing::Mock.new }
|
295
355
|
|
296
356
|
setting :db_producer do
|
297
357
|
|
@@ -38,6 +38,7 @@ module Deimos
|
|
38
38
|
connect_timeout: self.kafka.connect_timeout,
|
39
39
|
socket_timeout: self.kafka.socket_timeout,
|
40
40
|
ssl_verify_hostname: self.kafka.ssl.verify_hostname,
|
41
|
+
ssl_ca_certs_from_system: self.kafka.ssl.ca_certs_from_system,
|
41
42
|
seed_brokers: Array.wrap(self.kafka.seed_brokers)
|
42
43
|
},
|
43
44
|
producer: {
|
@@ -84,6 +85,26 @@ module Deimos
|
|
84
85
|
p_config[:kafka]["ssl_#{key}".to_sym] = ssl_var_contents(self.kafka.ssl.send(key))
|
85
86
|
end
|
86
87
|
end
|
88
|
+
|
89
|
+
if self.kafka.sasl.enabled
|
90
|
+
p_config[:kafka][:sasl_over_ssl] = self.kafka.sasl.enforce_ssl
|
91
|
+
%w(
|
92
|
+
gssapi_principal
|
93
|
+
gssapi_keytab
|
94
|
+
plain_authzid
|
95
|
+
plain_username
|
96
|
+
plain_password
|
97
|
+
scram_username
|
98
|
+
scram_password
|
99
|
+
scram_mechanism
|
100
|
+
oauth_token_provider
|
101
|
+
).each do |key|
|
102
|
+
value = self.kafka.sasl.send(key)
|
103
|
+
next if value.blank?
|
104
|
+
|
105
|
+
p_config[:kafka]["sasl_#{key}".to_sym] = value
|
106
|
+
end
|
107
|
+
end
|
87
108
|
p_config
|
88
109
|
end
|
89
110
|
|
@@ -102,6 +123,9 @@ module Deimos
|
|
102
123
|
if k.starts_with?('ssl')
|
103
124
|
k = k.sub('ssl_', '')
|
104
125
|
self.kafka.ssl.send("#{k}=", v)
|
126
|
+
elsif k.starts_with?('sasl')
|
127
|
+
k = (k == 'sasl_over_ssl') ? 'enforce_ssl' : k.sub('sasl_', '')
|
128
|
+
self.kafka.sasl.send("#{k}=", v)
|
105
129
|
else
|
106
130
|
self.kafka.send("#{k}=", v)
|
107
131
|
end
|
@@ -13,7 +13,7 @@ module Deimos
|
|
13
13
|
raise 'Metrics config must specify namespace' if config[:namespace].nil?
|
14
14
|
|
15
15
|
logger.info("DatadogMetricsProvider configured with: #{config}")
|
16
|
-
@client = Datadog::Statsd.new(
|
16
|
+
@client = ::Datadog::Statsd.new(
|
17
17
|
config[:host_ip],
|
18
18
|
config[:host_port]
|
19
19
|
)
|
@@ -26,7 +26,10 @@ module Deimos
|
|
26
26
|
schema_store: @schema_store,
|
27
27
|
registry_url: Deimos.config.schema.registry_url,
|
28
28
|
schemas_path: Deimos.config.schema.path,
|
29
|
-
|
29
|
+
user: Deimos.config.schema.user,
|
30
|
+
password: Deimos.config.schema.password,
|
31
|
+
namespace: @namespace,
|
32
|
+
logger: Deimos.config.logger
|
30
33
|
)
|
31
34
|
end
|
32
35
|
end
|
data/lib/deimos/version.rb
CHANGED
@@ -53,10 +53,36 @@ module Deimos
|
|
53
53
|
generate_class_from_schema_base(schema_base, key_schema_base: key_schema_base)
|
54
54
|
end
|
55
55
|
|
56
|
+
# @param schema [Avro::Schema::NamedSchema]
|
57
|
+
# @return [Array<Avro::Schema::NamedSchema]
|
58
|
+
def child_schemas(schema)
|
59
|
+
if schema.respond_to?(:fields)
|
60
|
+
schema.fields.map(&:type)
|
61
|
+
elsif schema.respond_to?(:values)
|
62
|
+
[schema.values]
|
63
|
+
elsif schema.respond_to?(:items)
|
64
|
+
[schema.items]
|
65
|
+
elsif schema.respond_to?(:schemas)
|
66
|
+
schema.schemas
|
67
|
+
else
|
68
|
+
[]
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# @param schemas [Array<Avro::Schema::NamedSchema>]
|
73
|
+
# @return [Array<Avro::Schema::NamedSchema>]
|
74
|
+
def collect_all_schemas(schemas)
|
75
|
+
schemas.dup.each do |schema|
|
76
|
+
schemas.concat(collect_all_schemas(child_schemas(schema)))
|
77
|
+
end
|
78
|
+
schemas.select { |s| s.respond_to?(:name) }.uniq
|
79
|
+
end
|
80
|
+
|
56
81
|
# @param schema_base [Deimos::SchemaBackends::Base]
|
57
82
|
# @param key_schema_base[Avro::Schema::NamedSchema]
|
58
83
|
def generate_class_from_schema_base(schema_base, key_schema_base: nil)
|
59
|
-
schemas = schema_base.schema_store.schemas.values
|
84
|
+
schemas = collect_all_schemas(schema_base.schema_store.schemas.values)
|
85
|
+
|
60
86
|
sub_schemas = schemas.reject { |s| s.name == schema_base.schema }
|
61
87
|
@sub_schema_templates = sub_schemas.map do |schema|
|
62
88
|
_generate_class_template_from_schema(schema)
|
@@ -315,7 +315,7 @@ module ActiveRecordBatchConsumerTest
|
|
315
315
|
Class.new(described_class) do
|
316
316
|
schema 'MySchema'
|
317
317
|
namespace 'com.my-namespace'
|
318
|
-
key_config schema: '
|
318
|
+
key_config schema: 'MySchemaCompound_key'
|
319
319
|
record_class Widget
|
320
320
|
compacted false
|
321
321
|
|
@@ -76,7 +76,7 @@ module ActiveRecordConsumerTest
|
|
76
76
|
updated_at: 1.day.ago.to_i,
|
77
77
|
some_datetime_int: Time.zone.now.to_i,
|
78
78
|
timestamp: 2.minutes.ago.to_s
|
79
|
-
},
|
79
|
+
}, call_original: true, key: 5)
|
80
80
|
|
81
81
|
expect(Widget.count).to eq(1)
|
82
82
|
widget = Widget.last
|
@@ -96,7 +96,7 @@ module ActiveRecordConsumerTest
|
|
96
96
|
some_int: 3,
|
97
97
|
some_datetime_int: Time.zone.now.to_i,
|
98
98
|
timestamp: 2.minutes.ago.to_s
|
99
|
-
},
|
99
|
+
}, call_original: true, key: 5)
|
100
100
|
expect(Widget.unscoped.count).to eq(1)
|
101
101
|
widget = Widget.unscoped.last
|
102
102
|
expect(widget.id).to eq(5)
|
@@ -120,7 +120,7 @@ module ActiveRecordConsumerTest
|
|
120
120
|
test_consume_message(MyCustomFetchConsumer, {
|
121
121
|
test_id: 'id1',
|
122
122
|
some_int: 3
|
123
|
-
},
|
123
|
+
}, call_original: true)
|
124
124
|
expect(widget1.reload.updated_at.in_time_zone).
|
125
125
|
to eq(Time.local(2020, 5, 6, 5, 5, 5))
|
126
126
|
travel_back
|
@@ -132,13 +132,13 @@ module ActiveRecordConsumerTest
|
|
132
132
|
test_consume_message(MyCustomFetchConsumer, {
|
133
133
|
test_id: 'id1',
|
134
134
|
some_int: 3
|
135
|
-
},
|
135
|
+
}, call_original: true)
|
136
136
|
expect(widget1.reload.some_int).to eq(3)
|
137
137
|
expect(Widget.count).to eq(1)
|
138
138
|
test_consume_message(MyCustomFetchConsumer, {
|
139
139
|
test_id: 'id2',
|
140
140
|
some_int: 4
|
141
|
-
},
|
141
|
+
}, call_original: true)
|
142
142
|
expect(Widget.count).to eq(2)
|
143
143
|
expect(Widget.find_by_test_id('id1').some_int).to eq(3)
|
144
144
|
expect(Widget.find_by_test_id('id2').some_int).to eq(4)
|
@@ -153,7 +153,7 @@ module ActiveRecordConsumerTest
|
|
153
153
|
updated_at: 1.day.ago.to_i,
|
154
154
|
some_datetime_int: Time.zone.now.to_i,
|
155
155
|
timestamp: 2.minutes.ago.to_s
|
156
|
-
},
|
156
|
+
}, call_original: true, key: 5)
|
157
157
|
expect(Widget.count).to eq(0)
|
158
158
|
end
|
159
159
|
end
|
@@ -76,7 +76,7 @@ describe Deimos::ActiveRecordProducer do
|
|
76
76
|
|
77
77
|
it 'should be able to call the record' do
|
78
78
|
widget = Widget.create!(test_id: 'abc2', some_int: 3)
|
79
|
-
MyProducerWithID.send_event(id: widget.id, test_id: 'abc2', some_int: 3)
|
79
|
+
MyProducerWithID.send_event({id: widget.id, test_id: 'abc2', some_int: 3})
|
80
80
|
expect('my-topic-with-id').to have_sent(
|
81
81
|
test_id: 'abc2',
|
82
82
|
some_int: 3,
|
@@ -70,6 +70,7 @@ describe Deimos, 'configuration' do
|
|
70
70
|
connect_timeout: 15,
|
71
71
|
socket_timeout: 15,
|
72
72
|
ssl_verify_hostname: true,
|
73
|
+
ssl_ca_certs_from_system: false,
|
73
74
|
seed_brokers: ['localhost:9092']
|
74
75
|
},
|
75
76
|
listeners: [
|
@@ -138,10 +139,22 @@ describe Deimos, 'configuration' do
|
|
138
139
|
connect_timeout 30
|
139
140
|
socket_timeout 30
|
140
141
|
ssl.enabled(true)
|
142
|
+
ssl.ca_certs_from_system(true)
|
141
143
|
ssl.ca_cert('cert')
|
142
144
|
ssl.client_cert('cert')
|
143
145
|
ssl.client_cert_key('key')
|
144
146
|
ssl.verify_hostname(false)
|
147
|
+
sasl.enabled true
|
148
|
+
sasl.gssapi_principal 'gssapi_principal'
|
149
|
+
sasl.gssapi_keytab 'gssapi_keytab'
|
150
|
+
sasl.plain_authzid 'plain_authzid'
|
151
|
+
sasl.plain_username 'plain_username'
|
152
|
+
sasl.plain_password 'plain_password'
|
153
|
+
sasl.scram_username 'scram_username'
|
154
|
+
sasl.scram_password 'scram_password'
|
155
|
+
sasl.scram_mechanism 'scram_mechanism'
|
156
|
+
sasl.enforce_ssl true
|
157
|
+
sasl.oauth_token_provider 'oauth_token_provider'
|
145
158
|
end
|
146
159
|
consumers do
|
147
160
|
session_timeout 30
|
@@ -210,11 +223,22 @@ describe Deimos, 'configuration' do
|
|
210
223
|
client_id: 'phobos2',
|
211
224
|
connect_timeout: 30,
|
212
225
|
socket_timeout: 30,
|
226
|
+
ssl_ca_certs_from_system: true,
|
213
227
|
ssl_ca_cert: 'cert',
|
214
228
|
ssl_client_cert: 'cert',
|
215
229
|
ssl_client_cert_key: 'key',
|
216
230
|
ssl_verify_hostname: false,
|
217
|
-
seed_brokers: ['my-seed-brokers']
|
231
|
+
seed_brokers: ['my-seed-brokers'],
|
232
|
+
sasl_gssapi_principal: 'gssapi_principal',
|
233
|
+
sasl_gssapi_keytab: 'gssapi_keytab',
|
234
|
+
sasl_plain_authzid: 'plain_authzid',
|
235
|
+
sasl_plain_username: 'plain_username',
|
236
|
+
sasl_plain_password: 'plain_password',
|
237
|
+
sasl_scram_username: 'scram_username',
|
238
|
+
sasl_scram_password: 'scram_password',
|
239
|
+
sasl_scram_mechanism: 'scram_mechanism',
|
240
|
+
sasl_over_ssl: true,
|
241
|
+
sasl_oauth_token_provider: 'oauth_token_provider',
|
218
242
|
},
|
219
243
|
listeners: [
|
220
244
|
{
|
data/spec/consumer_spec.rb
CHANGED
@@ -32,8 +32,8 @@ module ConsumerTest
|
|
32
32
|
|
33
33
|
it 'should consume a message' do
|
34
34
|
test_consume_message(MyConsumer,
|
35
|
-
'test_id' => 'foo',
|
36
|
-
'some_int' => 123) do |payload, _metadata|
|
35
|
+
{'test_id' => 'foo',
|
36
|
+
'some_int' => 123}) do |payload, _metadata|
|
37
37
|
expect(payload['test_id']).to eq('foo')
|
38
38
|
expect(payload['some_int']).to eq(123)
|
39
39
|
end
|
@@ -64,15 +64,15 @@ module ConsumerTest
|
|
64
64
|
|
65
65
|
it 'should consume a message on a topic' do
|
66
66
|
test_consume_message('my_consume_topic',
|
67
|
-
'test_id' => 'foo',
|
68
|
-
'some_int' => 123) do |payload, _metadata|
|
67
|
+
{'test_id' => 'foo',
|
68
|
+
'some_int' => 123}) do |payload, _metadata|
|
69
69
|
expect(payload['test_id']).to eq('foo')
|
70
70
|
expect(payload['some_int']).to eq(123)
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
74
|
it 'should fail on invalid message' do
|
75
|
-
test_consume_invalid_message(MyConsumer, 'invalid' => 'key')
|
75
|
+
test_consume_invalid_message(MyConsumer, {'invalid' => 'key'})
|
76
76
|
end
|
77
77
|
|
78
78
|
it 'should fail if reraise is false but fatal_error is true' do
|
@@ -85,14 +85,14 @@ module ConsumerTest
|
|
85
85
|
config.consumers.fatal_error = proc { true }
|
86
86
|
config.consumers.reraise_errors = false
|
87
87
|
end
|
88
|
-
test_consume_invalid_message(MyConsumer, 'invalid' => 'key')
|
88
|
+
test_consume_invalid_message(MyConsumer, {'invalid' => 'key'})
|
89
89
|
end
|
90
90
|
|
91
91
|
it 'should fail on message with extra fields' do
|
92
92
|
test_consume_invalid_message(MyConsumer,
|
93
|
-
'test_id' => 'foo',
|
93
|
+
{'test_id' => 'foo',
|
94
94
|
'some_int' => 123,
|
95
|
-
'extra_field' => 'field name')
|
95
|
+
'extra_field' => 'field name'})
|
96
96
|
end
|
97
97
|
|
98
98
|
it 'should not fail when before_consume fails without reraising errors' do
|
@@ -102,7 +102,7 @@ module ConsumerTest
|
|
102
102
|
MyConsumer,
|
103
103
|
{ 'test_id' => 'foo',
|
104
104
|
'some_int' => 123 },
|
105
|
-
|
105
|
+
skip_expectation: true
|
106
106
|
) { raise 'OH NOES' }
|
107
107
|
}.not_to raise_error
|
108
108
|
end
|
@@ -113,7 +113,7 @@ module ConsumerTest
|
|
113
113
|
test_consume_message(
|
114
114
|
MyConsumer,
|
115
115
|
{ 'invalid' => 'key' },
|
116
|
-
|
116
|
+
skip_expectation: true
|
117
117
|
)
|
118
118
|
}.not_to raise_error
|
119
119
|
end
|
@@ -122,7 +122,7 @@ module ConsumerTest
|
|
122
122
|
expect {
|
123
123
|
test_consume_message(MyConsumer,
|
124
124
|
{ 'test_id' => 'foo', 'some_int' => 123 },
|
125
|
-
|
125
|
+
call_original: true)
|
126
126
|
}.to raise_error('This should not be called unless call_original is set')
|
127
127
|
end
|
128
128
|
end
|
@@ -189,10 +189,10 @@ module ConsumerTest
|
|
189
189
|
it 'should consume a message' do
|
190
190
|
expect(Deimos.config.metrics).to receive(:histogram).twice
|
191
191
|
test_consume_message('my_consume_topic',
|
192
|
-
'test_id' => 'foo',
|
192
|
+
{'test_id' => 'foo',
|
193
193
|
'some_int' => 123,
|
194
194
|
'updated_at' => Time.now.to_i,
|
195
|
-
'timestamp' => 2.minutes.ago.to_s) do |payload, _metadata|
|
195
|
+
'timestamp' => 2.minutes.ago.to_s}) do |payload, _metadata|
|
196
196
|
expect(payload['test_id']).to eq('foo')
|
197
197
|
end
|
198
198
|
end
|
@@ -200,17 +200,17 @@ module ConsumerTest
|
|
200
200
|
it 'should fail nicely when timestamp wrong format' do
|
201
201
|
expect(Deimos.config.metrics).to receive(:histogram).twice
|
202
202
|
test_consume_message('my_consume_topic',
|
203
|
-
'test_id' => 'foo',
|
203
|
+
{'test_id' => 'foo',
|
204
204
|
'some_int' => 123,
|
205
205
|
'updated_at' => Time.now.to_i,
|
206
|
-
'timestamp' => 'dffdf') do |payload, _metadata|
|
206
|
+
'timestamp' => 'dffdf'}) do |payload, _metadata|
|
207
207
|
expect(payload['test_id']).to eq('foo')
|
208
208
|
end
|
209
209
|
test_consume_message('my_consume_topic',
|
210
|
-
'test_id' => 'foo',
|
210
|
+
{'test_id' => 'foo',
|
211
211
|
'some_int' => 123,
|
212
212
|
'updated_at' => Time.now.to_i,
|
213
|
-
'timestamp' => '') do |payload, _metadata|
|
213
|
+
'timestamp' => ''}) do |payload, _metadata|
|
214
214
|
expect(payload['test_id']).to eq('foo')
|
215
215
|
end
|
216
216
|
end
|
@@ -57,7 +57,7 @@ RSpec.describe Schemas::MySchemaWithComplexTypes do
|
|
57
57
|
end
|
58
58
|
|
59
59
|
let(:schema_fields) do
|
60
|
-
%w(test_id test_float test_int_array test_optional_int test_string_array some_integer_map some_record some_optional_record some_record_array some_record_map some_enum_array)
|
60
|
+
%w(test_id test_float test_int_array test_optional_int test_string_array some_integer_map some_record some_optional_record some_record_array some_record_map some_enum_array some_optional_enum)
|
61
61
|
end
|
62
62
|
|
63
63
|
it 'should return the name of the schema and namespace' do
|
@@ -77,6 +77,7 @@ RSpec.describe Schemas::MySchemaWithComplexTypes do
|
|
77
77
|
'test_float' => 1.2,
|
78
78
|
'test_string_array' => %w(abc def),
|
79
79
|
'test_int_array' => [123, 456],
|
80
|
+
'some_optional_enum' => nil,
|
80
81
|
'test_optional_int' => 123,
|
81
82
|
'some_integer_map' => { 'int_1' => 1, 'int_2' => 2 },
|
82
83
|
'some_record' => { 'a_record_field' => 'field 1' },
|
@@ -96,7 +97,7 @@ RSpec.describe Schemas::MySchemaWithComplexTypes do
|
|
96
97
|
end
|
97
98
|
|
98
99
|
it 'should return a JSON string of the payload' do
|
99
|
-
s = '{"test_id":"test id","test_float":1.2,"test_string_array":["abc","def"],"test_int_array":[123,456],"test_optional_int":123,"some_integer_map":{"int_1":1,"int_2":2},"some_record":{"a_record_field":"field 1"},"some_optional_record":{"a_record_field":"field 2"},"some_record_array":[{"a_record_field":"field 3"},{"a_record_field":"field 4"}],"some_record_map":{"record_1":{"a_record_field":"field 5"},"record_2":{"a_record_field":"field 6"}},"some_enum_array":["sym1","sym2"]}'
|
100
|
+
s = '{"test_id":"test id","test_float":1.2,"test_string_array":["abc","def"],"test_int_array":[123,456],"test_optional_int":123,"some_integer_map":{"int_1":1,"int_2":2},"some_record":{"a_record_field":"field 1"},"some_optional_record":{"a_record_field":"field 2"},"some_record_array":[{"a_record_field":"field 3"},{"a_record_field":"field 4"}],"some_record_map":{"record_1":{"a_record_field":"field 5"},"record_2":{"a_record_field":"field 6"}},"some_enum_array":["sym1","sym2"],"some_optional_enum":null}'
|
100
101
|
expect(klass.to_json).to eq(s)
|
101
102
|
end
|
102
103
|
end
|