deimos-ruby 1.12.4 → 1.12.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b6868444b14bad26f41d6b9ae08e02b402c33e17131df0db31874551c69b2d2b
4
- data.tar.gz: 64d5856bf685c2de06a3fe2124fcbf441953600073a0a1786663877013f52080
3
+ metadata.gz: a9de87883c263b11abeb45f86150cadcdf35566044bf1e579d6b1d6b775020ad
4
+ data.tar.gz: 5a686f11c2d72cbd7e0cbbd3238ad82963f7128ef57096c5c676979cdd42beac
5
5
  SHA512:
6
- metadata.gz: 6e0ff08f0224cf67ccd6361c8e75d30e516acec862edeb233401bfd61ccd2cfd8fe2b38658be1ff6fabfdae396caefa856e22182ed995fd03dc7afa7a644a8c5
7
- data.tar.gz: 543da676aff990c852f2208a39539650f77255f7aa5e50f3e9651352fb84c9303f78daa51e43b27abdc295175b891cca29b578d2b786773da8184f45ff11439b
6
+ metadata.gz: '027995a556c6d790a40e489ffad8e8eb64b927137cfce39ab09c855fbcae875376563eb4349edc1fbe111e491fc9651bed3eced08e1ab79ef9c40f1ea23da95c'
7
+ data.tar.gz: 673ff51ab95750439280f63398e86f31c5f441f6ef528ec933a54fa9f73a3211aafb09fb564f4944586eb7fe178bb6b0e8432d0e33308113af84adbedf59fe5f
@@ -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,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## UNRELEASED
9
9
 
10
+ # 1.12.5 - 2022-03-09
11
+
12
+ - Allow use of new avro_turf versions where child schemas are not listed with the top level schemas
13
+ - Add support for SASL authentication with brokers
14
+ - Add support for Basic auth with Schema Registry
15
+
10
16
  # 1.12.4 - 2022-01-13
11
17
 
12
18
  - 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": [
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
@@ -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
@@ -26,6 +26,8 @@ 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
+ user: Deimos.config.schema.user,
30
+ password: Deimos.config.schema.password,
29
31
  namespace: @namespace
30
32
  )
31
33
  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.12.5'
5
5
  end
@@ -53,10 +53,34 @@ 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
+ else
66
+ []
67
+ end
68
+ end
69
+
70
+ # @param schemas [Array<Avro::Schema::NamedSchema>]
71
+ # @return [Array<Avro::Schema::NamedSchema>]
72
+ def collect_all_schemas(schemas)
73
+ schemas.dup.each do |schema|
74
+ schemas.concat(collect_all_schemas(child_schemas(schema)))
75
+ end
76
+ schemas.select { |s| s.respond_to?(:name) }.uniq
77
+ end
78
+
56
79
  # @param schema_base [Deimos::SchemaBackends::Base]
57
80
  # @param key_schema_base[Avro::Schema::NamedSchema]
58
81
  def generate_class_from_schema_base(schema_base, key_schema_base: nil)
59
- schemas = schema_base.schema_store.schemas.values
82
+ schemas = collect_all_schemas(schema_base.schema_store.schemas.values)
83
+
60
84
  sub_schemas = schemas.reject { |s| s.name == schema_base.schema }
61
85
  @sub_schema_templates = sub_schemas.map do |schema|
62
86
  _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
@@ -81,7 +81,7 @@ RSpec.describe Deimos::Generators::SchemaClassGenerator do
81
81
  topic 'MyTopic'
82
82
  schema 'MySchema'
83
83
  namespace 'com.my-namespace'
84
- key_config schema: 'MySchema-key'
84
+ key_config schema: 'MySchema_key'
85
85
  end
86
86
  end
87
87
  described_class.start
@@ -143,7 +143,7 @@ RSpec.describe Deimos::Generators::SchemaClassGenerator do
143
143
  topic 'MyTopic'
144
144
  schema 'MySchema'
145
145
  namespace 'com.my-namespace'
146
- key_config schema: 'MySchema-key'
146
+ key_config schema: 'MySchema_key'
147
147
  end
148
148
 
149
149
  producer do
@@ -53,7 +53,7 @@ module ProducerTest
53
53
  schema 'MySchema'
54
54
  namespace 'com.my-namespace'
55
55
  topic 'my-topic2'
56
- key_config schema: 'MySchema-key'
56
+ key_config schema: 'MySchema_key'
57
57
  end
58
58
  stub_const('MySchemaProducer', producer_class)
59
59
 
@@ -79,7 +79,7 @@ module ProducerTest
79
79
  expect(event.payload[:payloads]).to eq([{ 'invalid' => 'key' }])
80
80
  end
81
81
  expect(MyProducer.encoder).to receive(:validate).and_raise('OH NOES')
82
- expect { MyProducer.publish('invalid' => 'key', :payload_key => 'key') }.
82
+ expect { MyProducer.publish({'invalid' => 'key', :payload_key => 'key'}) }.
83
83
  to raise_error('OH NOES')
84
84
  Deimos.unsubscribe(subscriber)
85
85
  end
@@ -294,7 +294,7 @@ module ProducerTest
294
294
 
295
295
  it 'should properly encode and coerce values with a nested record' do
296
296
  expect(MyNestedSchemaProducer.encoder).to receive(:encode_key).with('test_id', 'foo', topic: 'my-topic-key')
297
- MyNestedSchemaProducer.publish(
297
+ MyNestedSchemaProducer.publish({
298
298
  'test_id' => 'foo',
299
299
  'test_float' => BigDecimal('123.456'),
300
300
  'test_array' => ['1'],
@@ -305,7 +305,7 @@ module ProducerTest
305
305
  'some_optional_int' => nil
306
306
  },
307
307
  'some_optional_record' => nil
308
- )
308
+ })
309
309
  expect(MyNestedSchemaProducer.topic).to have_sent(
310
310
  'test_id' => 'foo',
311
311
  'test_float' => 123.456,
@@ -504,23 +504,23 @@ module ProducerTest
504
504
  it 'should disable globally' do
505
505
  Deimos.disable_producers do
506
506
  Deimos.disable_producers do # test nested
507
- MyProducer.publish(
507
+ MyProducer.publish({
508
508
  'test_id' => 'foo',
509
509
  'some_int' => 123,
510
510
  :payload_key => '123'
511
- )
512
- MyProducerWithID.publish(
511
+ })
512
+ MyProducerWithID.publish({
513
513
  'test_id' => 'foo', 'some_int' => 123
514
- )
514
+ })
515
515
  expect('my-topic').not_to have_sent(anything)
516
516
  expect(Deimos).to be_producers_disabled
517
517
  expect(Deimos).to be_producers_disabled([MyProducer])
518
518
  end
519
519
  end
520
520
 
521
- MyProducerWithID.publish(
521
+ MyProducerWithID.publish({
522
522
  'test_id' => 'foo', 'some_int' => 123, :payload_key => 123
523
- )
523
+ })
524
524
  expect('my-topic').
525
525
  to have_sent('test_id' => 'foo', 'some_int' => 123,
526
526
  'message_id' => anything, 'timestamp' => anything)
@@ -531,15 +531,15 @@ module ProducerTest
531
531
  it 'should disable a single producer' do
532
532
  Deimos.disable_producers(MyProducer) do # test nested
533
533
  Deimos.disable_producers(MyProducer) do
534
- MySchemaProducer.publish(
535
- 'test_id' => 'foo', 'some_int' => 123,
536
- :payload_key => { 'test_id' => 'foo_key' }
537
- )
538
- MyProducer.publish(
539
- 'test_id' => 'foo',
540
- 'some_int' => 123,
541
- :payload_key => '123'
542
- )
534
+ MySchemaProducer.publish({
535
+ 'test_id' => 'foo', 'some_int' => 123,
536
+ :payload_key => { 'test_id' => 'foo_key' }
537
+ })
538
+ MyProducer.publish({
539
+ 'test_id' => 'foo',
540
+ 'some_int' => 123,
541
+ :payload_key => '123'
542
+ })
543
543
  expect('my-topic').not_to have_sent(anything)
544
544
  expect('my-topic2').to have_sent('test_id' => 'foo', 'some_int' => 123)
545
545
  expect(Deimos).not_to be_producers_disabled
@@ -550,11 +550,11 @@ module ProducerTest
550
550
  expect(Deimos).not_to be_producers_disabled
551
551
  expect(Deimos).not_to be_producers_disabled(MyProducer)
552
552
  expect(Deimos).not_to be_producers_disabled(MySchemaProducer)
553
- MyProducer.publish(
554
- 'test_id' => 'foo',
555
- 'some_int' => 123,
556
- :payload_key => '123'
557
- )
553
+ MyProducer.publish({
554
+ 'test_id' => 'foo',
555
+ 'some_int' => 123,
556
+ :payload_key => '123'
557
+ })
558
558
  expect('my-topic').
559
559
  to have_sent('test_id' => 'foo', 'some_int' => 123)
560
560
  end
@@ -87,13 +87,13 @@ RSpec.shared_examples_for('an Avro backend') do
87
87
  describe('#validate') do
88
88
  it 'should pass valid schemas' do
89
89
  expect {
90
- backend.validate({ 'test_id' => 'hi', 'some_int' => 4 }, { schema: 'MySchema' })
90
+ backend.validate({ 'test_id' => 'hi', 'some_int' => 4 }, schema: 'MySchema')
91
91
  }.not_to raise_error
92
92
  end
93
93
 
94
94
  it 'should fail invalid schemas' do
95
95
  expect {
96
- backend.validate({ 'test_id2' => 'hi', 'some_int' => 4 }, { schema: 'MySchema' })
96
+ backend.validate({ 'test_id2' => 'hi', 'some_int' => 4 }, schema: 'MySchema')
97
97
  }.to raise_error(Avro::SchemaValidator::ValidationError)
98
98
  end
99
99
 
@@ -3,7 +3,7 @@
3
3
  # This file is autogenerated by Deimos, Do NOT modify
4
4
  module Schemas
5
5
  ### Primary Schema Class ###
6
- # Autogenerated Schema for Record at com.my-namespace.MySchema-key
6
+ # Autogenerated Schema for Record at com.my-namespace.MySchema_key
7
7
  class MySchemaKey < Deimos::SchemaClass::Record
8
8
  ### Attribute Accessors ###
9
9
  # @param value [String]
@@ -17,7 +17,7 @@ module Schemas
17
17
 
18
18
  # @override
19
19
  def schema
20
- 'MySchema-key'
20
+ 'MySchema_key'
21
21
  end
22
22
 
23
23
  # @override
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "namespace": "com.my-namespace",
3
- "name": "MySchemaCompound-key",
3
+ "name": "MySchemaCompound_key",
4
4
  "type": "record",
5
5
  "doc": "Test schema",
6
6
  "fields": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "namespace": "com.my-namespace",
3
- "name": "MySchema-key",
3
+ "name": "MySchema_key",
4
4
  "type": "record",
5
5
  "doc": "Test schema",
6
6
  "fields": [
@@ -17,14 +17,14 @@ describe Deimos::Utils::SeekListener do
17
17
  it 'should seek offset' do
18
18
  allow(consumer).to receive(:seek)
19
19
  expect(consumer).to receive(:seek).once
20
- seek_listener = described_class.new({ handler: handler, group_id: 999, topic: 'test_topic' })
20
+ seek_listener = described_class.new(handler: handler, group_id: 999, topic: 'test_topic')
21
21
  seek_listener.start_listener
22
22
  end
23
23
 
24
24
  it 'should retry on errors when seeking offset' do
25
25
  allow(consumer).to receive(:seek).and_raise(StandardError)
26
26
  expect(consumer).to receive(:seek).twice
27
- seek_listener = described_class.new({ handler: handler, group_id: 999, topic: 'test_topic' })
27
+ seek_listener = described_class.new(handler: handler, group_id: 999, topic: 'test_topic')
28
28
  seek_listener.start_listener
29
29
  end
30
30
  end
metadata CHANGED
@@ -1,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deimos-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.12.4
4
+ version: 1.12.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Orner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-13 00:00:00.000000000 Z
11
+ date: 2022-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: avro_turf
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0.11'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '2'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
25
28
  - !ruby/object:Gem::Version
26
29
  version: '0.11'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '2'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: phobos
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -347,6 +353,9 @@ extensions: []
347
353
  extra_rdoc_files: []
348
354
  files:
349
355
  - ".circleci/config.yml"
356
+ - ".gemfiles/avro_turf-0.gemfile"
357
+ - ".gemfiles/avro_turf-1.gemfile"
358
+ - ".github/workflows/ci.yml"
350
359
  - ".gitignore"
351
360
  - ".gitmodules"
352
361
  - ".rspec"
@@ -357,7 +366,6 @@ files:
357
366
  - CODE_OF_CONDUCT.md
358
367
  - Dockerfile
359
368
  - Gemfile
360
- - Gemfile.lock
361
369
  - Guardfile
362
370
  - LICENSE.md
363
371
  - README.md
@@ -477,14 +485,14 @@ files:
477
485
  - spec/schema_classes/my_schema_with_complex_types.rb
478
486
  - spec/schemas/com/my-namespace/Generated.avsc
479
487
  - spec/schemas/com/my-namespace/MyNestedSchema.avsc
480
- - spec/schemas/com/my-namespace/MySchema-key.avsc
481
488
  - spec/schemas/com/my-namespace/MySchema.avsc
482
- - spec/schemas/com/my-namespace/MySchemaCompound-key.avsc
489
+ - spec/schemas/com/my-namespace/MySchemaCompound_key.avsc
483
490
  - spec/schemas/com/my-namespace/MySchemaWithBooleans.avsc
484
491
  - spec/schemas/com/my-namespace/MySchemaWithComplexTypes.avsc
485
492
  - spec/schemas/com/my-namespace/MySchemaWithDateTimes.avsc
486
493
  - spec/schemas/com/my-namespace/MySchemaWithId.avsc
487
494
  - spec/schemas/com/my-namespace/MySchemaWithUniqueId.avsc
495
+ - spec/schemas/com/my-namespace/MySchema_key.avsc
488
496
  - spec/schemas/com/my-namespace/Wibble.avsc
489
497
  - spec/schemas/com/my-namespace/Widget.avsc
490
498
  - spec/schemas/com/my-namespace/WidgetTheSecond.avsc
@@ -568,14 +576,14 @@ test_files:
568
576
  - spec/schema_classes/my_schema_with_complex_types.rb
569
577
  - spec/schemas/com/my-namespace/Generated.avsc
570
578
  - spec/schemas/com/my-namespace/MyNestedSchema.avsc
571
- - spec/schemas/com/my-namespace/MySchema-key.avsc
572
579
  - spec/schemas/com/my-namespace/MySchema.avsc
573
- - spec/schemas/com/my-namespace/MySchemaCompound-key.avsc
580
+ - spec/schemas/com/my-namespace/MySchemaCompound_key.avsc
574
581
  - spec/schemas/com/my-namespace/MySchemaWithBooleans.avsc
575
582
  - spec/schemas/com/my-namespace/MySchemaWithComplexTypes.avsc
576
583
  - spec/schemas/com/my-namespace/MySchemaWithDateTimes.avsc
577
584
  - spec/schemas/com/my-namespace/MySchemaWithId.avsc
578
585
  - spec/schemas/com/my-namespace/MySchemaWithUniqueId.avsc
586
+ - spec/schemas/com/my-namespace/MySchema_key.avsc
579
587
  - spec/schemas/com/my-namespace/Wibble.avsc
580
588
  - spec/schemas/com/my-namespace/Widget.avsc
581
589
  - spec/schemas/com/my-namespace/WidgetTheSecond.avsc
data/Gemfile.lock DELETED
@@ -1,292 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- deimos-ruby (1.12.3)
5
- avro_turf (~> 0.11)
6
- fig_tree (~> 0.0.2)
7
- phobos (>= 1.9, < 3.0)
8
- ruby-kafka (< 2)
9
- sigurd (~> 0.0.1)
10
-
11
- GEM
12
- remote: https://rubygems.org/
13
- specs:
14
- actioncable (6.1.3)
15
- actionpack (= 6.1.3)
16
- activesupport (= 6.1.3)
17
- nio4r (~> 2.0)
18
- websocket-driver (>= 0.6.1)
19
- actionmailbox (6.1.3)
20
- actionpack (= 6.1.3)
21
- activejob (= 6.1.3)
22
- activerecord (= 6.1.3)
23
- activestorage (= 6.1.3)
24
- activesupport (= 6.1.3)
25
- mail (>= 2.7.1)
26
- actionmailer (6.1.3)
27
- actionpack (= 6.1.3)
28
- actionview (= 6.1.3)
29
- activejob (= 6.1.3)
30
- activesupport (= 6.1.3)
31
- mail (~> 2.5, >= 2.5.4)
32
- rails-dom-testing (~> 2.0)
33
- actionpack (6.1.3)
34
- actionview (= 6.1.3)
35
- activesupport (= 6.1.3)
36
- rack (~> 2.0, >= 2.0.9)
37
- rack-test (>= 0.6.3)
38
- rails-dom-testing (~> 2.0)
39
- rails-html-sanitizer (~> 1.0, >= 1.2.0)
40
- actiontext (6.1.3)
41
- actionpack (= 6.1.3)
42
- activerecord (= 6.1.3)
43
- activestorage (= 6.1.3)
44
- activesupport (= 6.1.3)
45
- nokogiri (>= 1.8.5)
46
- actionview (6.1.3)
47
- activesupport (= 6.1.3)
48
- builder (~> 3.1)
49
- erubi (~> 1.4)
50
- rails-dom-testing (~> 2.0)
51
- rails-html-sanitizer (~> 1.1, >= 1.2.0)
52
- activejob (6.1.3)
53
- activesupport (= 6.1.3)
54
- globalid (>= 0.3.6)
55
- activemodel (6.1.3)
56
- activesupport (= 6.1.3)
57
- activerecord (6.1.3)
58
- activemodel (= 6.1.3)
59
- activesupport (= 6.1.3)
60
- activerecord-import (1.0.8)
61
- activerecord (>= 3.2)
62
- activestorage (6.1.3)
63
- actionpack (= 6.1.3)
64
- activejob (= 6.1.3)
65
- activerecord (= 6.1.3)
66
- activesupport (= 6.1.3)
67
- marcel (~> 0.3.1)
68
- mimemagic (~> 0.3.2)
69
- activesupport (6.1.3)
70
- concurrent-ruby (~> 1.0, >= 1.0.2)
71
- i18n (>= 1.6, < 2)
72
- minitest (>= 5.1)
73
- tzinfo (~> 2.0)
74
- zeitwerk (~> 2.3)
75
- ast (2.4.2)
76
- avro (1.9.2)
77
- multi_json
78
- avro_turf (0.11.0)
79
- avro (>= 1.7.7, < 1.10)
80
- excon (~> 0.45)
81
- builder (3.2.4)
82
- coderay (1.1.3)
83
- concurrent-ruby (1.1.8)
84
- concurrent-ruby-ext (1.1.8)
85
- concurrent-ruby (= 1.1.8)
86
- crass (1.0.6)
87
- database_cleaner (1.99.0)
88
- ddtrace (0.46.0)
89
- msgpack
90
- diff-lcs (1.4.4)
91
- digest-crc (0.6.4)
92
- rake (>= 12.0.0, < 14.0.0)
93
- dogstatsd-ruby (4.8.3)
94
- erubi (1.10.0)
95
- excon (0.89.0)
96
- exponential-backoff (0.0.4)
97
- ffi (1.15.0)
98
- fig_tree (0.0.2)
99
- activesupport (>= 3.0.0)
100
- formatador (0.2.5)
101
- globalid (0.4.2)
102
- activesupport (>= 4.2.0)
103
- guard (2.16.2)
104
- formatador (>= 0.2.4)
105
- listen (>= 2.7, < 4.0)
106
- lumberjack (>= 1.0.12, < 2.0)
107
- nenv (~> 0.1)
108
- notiffany (~> 0.0)
109
- pry (>= 0.9.12)
110
- shellany (~> 0.0)
111
- thor (>= 0.18.1)
112
- guard-compat (1.2.1)
113
- guard-rspec (4.7.3)
114
- guard (~> 2.1)
115
- guard-compat (~> 1.1)
116
- rspec (>= 2.99.0, < 4.0)
117
- guard-rubocop (1.4.0)
118
- guard (~> 2.0)
119
- rubocop (< 2.0)
120
- i18n (1.8.9)
121
- concurrent-ruby (~> 1.0)
122
- listen (3.4.1)
123
- rb-fsevent (~> 0.10, >= 0.10.3)
124
- rb-inotify (~> 0.9, >= 0.9.10)
125
- little-plugger (1.1.4)
126
- logging (2.3.0)
127
- little-plugger (~> 1.1)
128
- multi_json (~> 1.14)
129
- loofah (2.9.0)
130
- crass (~> 1.0.2)
131
- nokogiri (>= 1.5.9)
132
- lumberjack (1.2.8)
133
- mail (2.7.1)
134
- mini_mime (>= 0.1.1)
135
- marcel (0.3.3)
136
- mimemagic (~> 0.3.2)
137
- method_source (1.0.0)
138
- mimemagic (0.3.10)
139
- nokogiri (~> 1)
140
- rake
141
- mini_mime (1.0.2)
142
- mini_portile2 (2.5.1)
143
- minitest (5.14.4)
144
- msgpack (1.4.2)
145
- multi_json (1.15.0)
146
- mysql2 (0.5.3)
147
- nenv (0.3.0)
148
- nio4r (2.5.7)
149
- nokogiri (1.11.5)
150
- mini_portile2 (~> 2.5.0)
151
- racc (~> 1.4)
152
- notiffany (0.1.3)
153
- nenv (~> 0.1)
154
- shellany (~> 0.0)
155
- parallel (1.20.1)
156
- parser (3.0.1.1)
157
- ast (~> 2.4.1)
158
- pg (1.2.3)
159
- phobos (2.1.0)
160
- activesupport (>= 3.0.0)
161
- concurrent-ruby (>= 1.0.2)
162
- concurrent-ruby-ext (>= 1.0.2)
163
- exponential-backoff
164
- logging
165
- ruby-kafka
166
- thor
167
- pry (0.14.0)
168
- coderay (~> 1.1)
169
- method_source (~> 1.0)
170
- racc (1.5.2)
171
- rack (2.2.3)
172
- rack-test (1.1.0)
173
- rack (>= 1.0, < 3)
174
- rails (6.1.3)
175
- actioncable (= 6.1.3)
176
- actionmailbox (= 6.1.3)
177
- actionmailer (= 6.1.3)
178
- actionpack (= 6.1.3)
179
- actiontext (= 6.1.3)
180
- actionview (= 6.1.3)
181
- activejob (= 6.1.3)
182
- activemodel (= 6.1.3)
183
- activerecord (= 6.1.3)
184
- activestorage (= 6.1.3)
185
- activesupport (= 6.1.3)
186
- bundler (>= 1.15.0)
187
- railties (= 6.1.3)
188
- sprockets-rails (>= 2.0.0)
189
- rails-dom-testing (2.0.3)
190
- activesupport (>= 4.2.0)
191
- nokogiri (>= 1.6)
192
- rails-html-sanitizer (1.3.0)
193
- loofah (~> 2.3)
194
- railties (6.1.3)
195
- actionpack (= 6.1.3)
196
- activesupport (= 6.1.3)
197
- method_source
198
- rake (>= 0.8.7)
199
- thor (~> 1.0)
200
- rainbow (3.0.0)
201
- rake (13.0.3)
202
- rb-fsevent (0.10.4)
203
- rb-inotify (0.10.1)
204
- ffi (~> 1.0)
205
- regexp_parser (2.1.1)
206
- rexml (3.2.5)
207
- rspec (3.10.0)
208
- rspec-core (~> 3.10.0)
209
- rspec-expectations (~> 3.10.0)
210
- rspec-mocks (~> 3.10.0)
211
- rspec-core (3.10.1)
212
- rspec-support (~> 3.10.0)
213
- rspec-expectations (3.10.1)
214
- diff-lcs (>= 1.2.0, < 2.0)
215
- rspec-support (~> 3.10.0)
216
- rspec-mocks (3.10.2)
217
- diff-lcs (>= 1.2.0, < 2.0)
218
- rspec-support (~> 3.10.0)
219
- rspec-rails (4.1.1)
220
- actionpack (>= 4.2)
221
- activesupport (>= 4.2)
222
- railties (>= 4.2)
223
- rspec-core (~> 3.10)
224
- rspec-expectations (~> 3.10)
225
- rspec-mocks (~> 3.10)
226
- rspec-support (~> 3.10)
227
- rspec-support (3.10.2)
228
- rspec_junit_formatter (0.4.1)
229
- rspec-core (>= 2, < 4, != 2.12.0)
230
- rubocop (0.89.0)
231
- parallel (~> 1.10)
232
- parser (>= 2.7.1.1)
233
- rainbow (>= 2.2.2, < 4.0)
234
- regexp_parser (>= 1.7)
235
- rexml
236
- rubocop-ast (>= 0.1.0, < 1.0)
237
- ruby-progressbar (~> 1.7)
238
- unicode-display_width (>= 1.4.0, < 2.0)
239
- rubocop-ast (0.8.0)
240
- parser (>= 2.7.1.5)
241
- rubocop-rspec (1.42.0)
242
- rubocop (>= 0.87.0)
243
- ruby-kafka (1.4.0)
244
- digest-crc
245
- ruby-progressbar (1.11.0)
246
- shellany (0.0.1)
247
- sigurd (0.0.3)
248
- concurrent-ruby (~> 1)
249
- exponential-backoff
250
- sprockets (4.0.2)
251
- concurrent-ruby (~> 1.0)
252
- rack (> 1, < 3)
253
- sprockets-rails (3.2.2)
254
- actionpack (>= 4.0)
255
- activesupport (>= 4.0)
256
- sprockets (>= 3.0.0)
257
- sqlite3 (1.4.2)
258
- thor (1.1.0)
259
- tzinfo (2.0.4)
260
- concurrent-ruby (~> 1.0)
261
- unicode-display_width (1.7.0)
262
- websocket-driver (0.7.3)
263
- websocket-extensions (>= 0.1.0)
264
- websocket-extensions (0.1.5)
265
- zeitwerk (2.4.2)
266
-
267
- PLATFORMS
268
- ruby
269
-
270
- DEPENDENCIES
271
- activerecord-import
272
- avro (~> 1.9)
273
- database_cleaner (~> 1.7)
274
- ddtrace (~> 0.11)
275
- deimos-ruby!
276
- dogstatsd-ruby (~> 4.2)
277
- guard (~> 2)
278
- guard-rspec (~> 4)
279
- guard-rubocop (~> 1)
280
- mysql2 (~> 0.5)
281
- pg (~> 1.1)
282
- rails (~> 6)
283
- rake (~> 13)
284
- rspec (~> 3)
285
- rspec-rails (~> 4)
286
- rspec_junit_formatter (~> 0.3)
287
- rubocop (= 0.89.0)
288
- rubocop-rspec (= 1.42.0)
289
- sqlite3 (~> 1.3)
290
-
291
- BUNDLED WITH
292
- 2.2.17