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.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/.gemfiles/avro_turf-0.gemfile +3 -0
  3. data/.gemfiles/avro_turf-1.gemfile +3 -0
  4. data/.github/workflows/ci.yml +49 -0
  5. data/.gitignore +2 -1
  6. data/CHANGELOG.md +16 -0
  7. data/README.md +3 -3
  8. data/bin/console +15 -0
  9. data/deimos-ruby.gemspec +1 -1
  10. data/docs/CONFIGURATION.md +15 -1
  11. data/lib/deimos/config/configuration.rb +62 -2
  12. data/lib/deimos/config/phobos_config.rb +24 -0
  13. data/lib/deimos/metrics/datadog.rb +1 -1
  14. data/lib/deimos/schema_backends/avro_schema_registry.rb +4 -1
  15. data/lib/deimos/version.rb +1 -1
  16. data/lib/generators/deimos/schema_class_generator.rb +27 -1
  17. data/spec/active_record_batch_consumer_spec.rb +1 -1
  18. data/spec/active_record_consumer_spec.rb +6 -6
  19. data/spec/active_record_producer_spec.rb +1 -1
  20. data/spec/config/configuration_spec.rb +25 -1
  21. data/spec/consumer_spec.rb +17 -17
  22. data/spec/generators/schema_class/my_schema_with_complex_types_spec.rb +3 -2
  23. data/spec/generators/schema_class_generator_spec.rb +2 -2
  24. data/spec/producer_spec.rb +24 -24
  25. data/spec/schema_backends/avro_base_shared.rb +2 -2
  26. data/spec/schema_classes/my_schema_key.rb +2 -2
  27. data/spec/schema_classes/my_schema_with_complex_types.rb +34 -2
  28. data/spec/schemas/com/my-namespace/{MySchemaCompound-key.avsc → MySchemaCompound_key.avsc} +1 -1
  29. data/spec/schemas/com/my-namespace/MySchemaWithComplexTypes.avsc +11 -0
  30. data/spec/schemas/com/my-namespace/{MySchema-key.avsc → MySchema_key.avsc} +1 -1
  31. data/spec/utils/inline_consumer_spec.rb +2 -2
  32. metadata +19 -9
  33. data/Gemfile.lock +0 -292
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b6868444b14bad26f41d6b9ae08e02b402c33e17131df0db31874551c69b2d2b
4
- data.tar.gz: 64d5856bf685c2de06a3fe2124fcbf441953600073a0a1786663877013f52080
3
+ metadata.gz: c57c2700b01b998f358cb4e96ee6e6b2c1c8c32936d741b2371182a6017f7adc
4
+ data.tar.gz: 440bf25b629ba34da51cd1c0a1b443858bcd4ca270fed800b6e277c050b0741f
5
5
  SHA512:
6
- metadata.gz: 6e0ff08f0224cf67ccd6361c8e75d30e516acec862edeb233401bfd61ccd2cfd8fe2b38658be1ff6fabfdae396caefa856e22182ed995fd03dc7afa7a644a8c5
7
- data.tar.gz: 543da676aff990c852f2208a39539650f77255f7aa5e50f3e9651352fb84c9303f78daa51e43b27abdc295175b891cca29b578d2b786773da8184f45ff11439b
6
+ metadata.gz: 05df77f7f8890959ea91817a7497c11348d3b68f349462275a1ffb133a1c8194d9ee2282ac3dbe14a389bd09f16f059c88b467c05fb959c1a334b7c3789ade92
7
+ data.tar.gz: bc8b8c832a7399a6c60a4a0ac71582aff4ff324d5a2c9bb2a73241bb64de3a958d09208e1c127d36e8b3c47077857224ec853aaea769ef00aaef88dc6e6cf0e9
@@ -0,0 +1,3 @@
1
+ eval_gemfile '../Gemfile'
2
+
3
+ gem 'avro_turf', '~> 0.11'
@@ -0,0 +1,3 @@
1
+ eval_gemfile '../Gemfile'
2
+
3
+ gem 'avro_turf', '~> 1.0'
@@ -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
@@ -12,6 +12,7 @@
12
12
  /test/version_tmp/
13
13
  /tmp/
14
14
  /log/
15
+ Gemfile.lock
15
16
 
16
17
  # Used by dotenv library to load environment variables.
17
18
  # .env
@@ -38,4 +39,4 @@
38
39
 
39
40
  test.sqlite3
40
41
 
41
- .idea
42
+ .idea
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": "MySchema-key",
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](CONFIGURATION.md).
938
- View all available Metrics Providers [here](lib/deimos/metrics/metrics_providers)
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', '~> 0.11')
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')
@@ -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.generated_schema_path|`app/lib/schema_classes`|Local path to generated schema classes.
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
- namespace: @namespace
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Deimos
4
- VERSION = '1.12.4'
4
+ VERSION = '1.13.0'
5
5
  end
@@ -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: 'MySchemaCompound-key'
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
- }, { call_original: true, key: 5 })
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
- }, { call_original: true, key: 5 })
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
- }, { call_original: true })
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
- }, { call_original: true })
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
- }, { call_original: true })
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
- }, { call_original: true, key: 5 })
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
  {
@@ -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
- { skip_expectation: true }
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
- { skip_expectation: true }
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
- { call_original: true })
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