waterdrop 1.2.5 → 1.3.0.rc1
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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/{.coditsu.yml → .coditsu/ci.yml} +1 -1
- data/.github/FUNDING.yml +1 -0
- data/.gitignore +2 -1
- data/.ruby-version +1 -1
- data/.travis.yml +5 -17
- data/CHANGELOG.md +19 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +44 -34
- data/README.md +2 -10
- data/certs/mensfeld.pem +25 -0
- data/config/errors.yml +18 -5
- data/lib/water_drop.rb +6 -17
- data/lib/water_drop/async_producer.rb +2 -2
- data/lib/water_drop/base_producer.rb +10 -3
- data/lib/water_drop/config.rb +23 -6
- data/lib/water_drop/config_applier.rb +2 -1
- data/lib/water_drop/contracts.rb +9 -0
- data/lib/water_drop/contracts/config.rb +138 -0
- data/lib/water_drop/contracts/message_options.rb +19 -0
- data/lib/water_drop/errors.rb +2 -2
- data/lib/water_drop/instrumentation/monitor.rb +2 -3
- data/lib/water_drop/instrumentation/{listener.rb → stdout_listener.rb} +1 -9
- data/lib/water_drop/sync_producer.rb +2 -2
- data/lib/water_drop/version.rb +1 -1
- data/log/.keep +0 -0
- data/waterdrop.gemspec +9 -8
- metadata +54 -25
- metadata.gz.sig +0 -0
- data/lib/water_drop/schemas/config.rb +0 -81
- data/lib/water_drop/schemas/message_options.rb +0 -19
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 29f20d39798734c2c3530de25b44ff2d8987236adccde1c5fe8b04c624487e4b
|
|
4
|
+
data.tar.gz: 9bd463eac4f7e02a7aad4681e8bcc4e52f809673ea7c6ddbab8c0e0c4d722d52
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 883ded4f2e72051543258d96d5c9a9ffd32785a7fb10f9e90c17460fd55616faf812f57711efb75a61355c27296ebf7b25a8c50536df39d7c4b3683cf2f8aac1
|
|
7
|
+
data.tar.gz: 55e13aedda6a2626e6078259a4d3e3da0c99405259bf0c549c66e4bf3e88e6671e7390a8f4e995308b9229138e4c80eace5039d1c4f22f8f0008ff44b55f0485
|
checksums.yaml.gz.sig
ADDED
|
Binary file
|
data.tar.gz.sig
ADDED
|
Binary file
|
data/.github/FUNDING.yml
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
open_collective: karafka
|
data/.gitignore
CHANGED
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.6.
|
|
1
|
+
2.6.3
|
data/.travis.yml
CHANGED
|
@@ -2,7 +2,6 @@ services:
|
|
|
2
2
|
- docker
|
|
3
3
|
|
|
4
4
|
dist: trusty
|
|
5
|
-
sudo: false
|
|
6
5
|
cache: bundler
|
|
7
6
|
|
|
8
7
|
git:
|
|
@@ -19,30 +18,19 @@ test: &test
|
|
|
19
18
|
jobs:
|
|
20
19
|
include:
|
|
21
20
|
- <<: *test
|
|
22
|
-
rvm: 2.6.
|
|
21
|
+
rvm: 2.6.3
|
|
23
22
|
- <<: *test
|
|
24
|
-
rvm: 2.5.
|
|
23
|
+
rvm: 2.5.5
|
|
25
24
|
- <<: *test
|
|
26
|
-
rvm: 2.4.
|
|
27
|
-
- <<: *test
|
|
28
|
-
rvm: 2.3.8
|
|
25
|
+
rvm: 2.4.6
|
|
29
26
|
|
|
30
27
|
- stage: coditsu
|
|
31
28
|
language: ruby
|
|
32
|
-
rvm: 2.6.
|
|
29
|
+
rvm: 2.6.3
|
|
33
30
|
before_install:
|
|
34
31
|
- gem update --system
|
|
35
32
|
- gem install bundler
|
|
36
|
-
|
|
37
|
-
- docker create -v /sources --name sources alpine:3.4 /bin/true
|
|
38
|
-
- docker cp ./ sources:/sources
|
|
39
|
-
script: >
|
|
40
|
-
docker run
|
|
41
|
-
-e CODITSU_API_KEY
|
|
42
|
-
-e CODITSU_API_SECRET
|
|
43
|
-
-e CODITSU_REPOSITORY_ID
|
|
44
|
-
--volumes-from sources
|
|
45
|
-
coditsu/build-runner:latest
|
|
33
|
+
script: \curl -sSL https://api.coditsu.io/run/ci | bash
|
|
46
34
|
|
|
47
35
|
stages:
|
|
48
36
|
- coditsu
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# WaterDrop changelog
|
|
2
2
|
|
|
3
|
+
## 1.3.0.rc1 (2019-07-31)
|
|
4
|
+
- Drop Ruby 2.3 support
|
|
5
|
+
- Drop support for Kafka 0.10 in favor of native support for Kafka 0.11.
|
|
6
|
+
- Ruby 2.6.3 support
|
|
7
|
+
- Support message headers
|
|
8
|
+
- `sasl_over_ssl` support
|
|
9
|
+
- Unlock Ruby Kafka + provide support for 0.7 only
|
|
10
|
+
- #60 - Rename listener to StdoutListener
|
|
11
|
+
- Drop support for Kafka 0.10 in favor of native support for Kafka 0.11.
|
|
12
|
+
- Support ruby-kafka 0.7
|
|
13
|
+
- Support message headers
|
|
14
|
+
- `sasl_over_ssl` support
|
|
15
|
+
- `ssl_client_cert_key_password` support
|
|
16
|
+
- #87 - Make stdout listener as instance
|
|
17
|
+
- Use Zeitwerk for gem code loading
|
|
18
|
+
- #93 - zstd compression support
|
|
19
|
+
- #99 - schemas are renamed to contracts
|
|
20
|
+
- Bump delivery_boy (0.2.7 => 0.2.8)
|
|
21
|
+
|
|
3
22
|
## 1.2.5
|
|
4
23
|
- Bump deps to match Karafka
|
|
5
24
|
- drop jruby support
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,92 +1,102 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
waterdrop (1.
|
|
4
|
+
waterdrop (1.3.0.rc1)
|
|
5
5
|
delivery_boy (~> 0.2)
|
|
6
6
|
dry-configurable (~> 0.8)
|
|
7
7
|
dry-monitor (~> 0.3)
|
|
8
|
-
dry-validation (~>
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
dry-validation (~> 1.2)
|
|
9
|
+
ruby-kafka (>= 0.7.8)
|
|
10
|
+
zeitwerk (~> 2.1)
|
|
11
11
|
|
|
12
12
|
GEM
|
|
13
13
|
remote: https://rubygems.org/
|
|
14
14
|
specs:
|
|
15
|
-
concurrent-ruby (1.1.
|
|
16
|
-
delivery_boy (0.2.
|
|
17
|
-
king_konf (~> 0.
|
|
18
|
-
ruby-kafka (~> 0.
|
|
15
|
+
concurrent-ruby (1.1.5)
|
|
16
|
+
delivery_boy (0.2.8)
|
|
17
|
+
king_konf (~> 0.3)
|
|
18
|
+
ruby-kafka (~> 0.7.8)
|
|
19
19
|
diff-lcs (1.3)
|
|
20
20
|
digest-crc (0.4.1)
|
|
21
|
-
docile (1.3.
|
|
22
|
-
dry-configurable (0.8.
|
|
21
|
+
docile (1.3.2)
|
|
22
|
+
dry-configurable (0.8.3)
|
|
23
23
|
concurrent-ruby (~> 1.0)
|
|
24
24
|
dry-core (~> 0.4, >= 0.4.7)
|
|
25
|
-
dry-container (0.7.
|
|
25
|
+
dry-container (0.7.2)
|
|
26
26
|
concurrent-ruby (~> 1.0)
|
|
27
27
|
dry-configurable (~> 0.1, >= 0.1.3)
|
|
28
|
-
dry-core (0.4.
|
|
28
|
+
dry-core (0.4.8)
|
|
29
29
|
concurrent-ruby (~> 1.0)
|
|
30
|
-
dry-equalizer (0.2.
|
|
31
|
-
dry-events (0.
|
|
30
|
+
dry-equalizer (0.2.2)
|
|
31
|
+
dry-events (0.2.0)
|
|
32
32
|
concurrent-ruby (~> 1.0)
|
|
33
33
|
dry-core (~> 0.4)
|
|
34
34
|
dry-equalizer (~> 0.2)
|
|
35
35
|
dry-inflector (0.1.2)
|
|
36
|
-
dry-
|
|
37
|
-
|
|
36
|
+
dry-initializer (3.0.1)
|
|
37
|
+
dry-logic (1.0.2)
|
|
38
|
+
concurrent-ruby (~> 1.0)
|
|
38
39
|
dry-core (~> 0.2)
|
|
39
40
|
dry-equalizer (~> 0.2)
|
|
40
|
-
dry-monitor (0.3.
|
|
41
|
+
dry-monitor (0.3.1)
|
|
41
42
|
dry-configurable (~> 0.5)
|
|
42
43
|
dry-core (~> 0.4)
|
|
43
44
|
dry-equalizer (~> 0.2)
|
|
44
45
|
dry-events (~> 0.1)
|
|
45
|
-
dry-
|
|
46
|
+
dry-schema (1.3.1)
|
|
47
|
+
concurrent-ruby (~> 1.0)
|
|
48
|
+
dry-configurable (~> 0.8, >= 0.8.3)
|
|
49
|
+
dry-core (~> 0.4)
|
|
50
|
+
dry-equalizer (~> 0.2)
|
|
51
|
+
dry-initializer (~> 3.0)
|
|
52
|
+
dry-logic (~> 1.0)
|
|
53
|
+
dry-types (~> 1.0)
|
|
54
|
+
dry-types (1.1.1)
|
|
46
55
|
concurrent-ruby (~> 1.0)
|
|
47
56
|
dry-container (~> 0.3)
|
|
48
57
|
dry-core (~> 0.4, >= 0.4.4)
|
|
49
|
-
dry-equalizer (~> 0.2)
|
|
58
|
+
dry-equalizer (~> 0.2, >= 0.2.2)
|
|
50
59
|
dry-inflector (~> 0.1, >= 0.1.2)
|
|
51
|
-
dry-logic (~> 0
|
|
52
|
-
dry-validation (
|
|
60
|
+
dry-logic (~> 1.0, >= 1.0.2)
|
|
61
|
+
dry-validation (1.2.1)
|
|
53
62
|
concurrent-ruby (~> 1.0)
|
|
54
|
-
dry-
|
|
55
|
-
dry-core (~> 0.
|
|
63
|
+
dry-container (~> 0.7, >= 0.7.1)
|
|
64
|
+
dry-core (~> 0.4)
|
|
56
65
|
dry-equalizer (~> 0.2)
|
|
57
|
-
dry-
|
|
58
|
-
dry-
|
|
59
|
-
json (2.
|
|
66
|
+
dry-initializer (~> 3.0)
|
|
67
|
+
dry-schema (~> 1.0, >= 1.3.1)
|
|
68
|
+
json (2.2.0)
|
|
60
69
|
king_konf (0.3.7)
|
|
61
|
-
null-logger (0.1.5)
|
|
62
70
|
rspec (3.8.0)
|
|
63
71
|
rspec-core (~> 3.8.0)
|
|
64
72
|
rspec-expectations (~> 3.8.0)
|
|
65
73
|
rspec-mocks (~> 3.8.0)
|
|
66
|
-
rspec-core (3.8.
|
|
74
|
+
rspec-core (3.8.2)
|
|
67
75
|
rspec-support (~> 3.8.0)
|
|
68
|
-
rspec-expectations (3.8.
|
|
76
|
+
rspec-expectations (3.8.4)
|
|
69
77
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
70
78
|
rspec-support (~> 3.8.0)
|
|
71
|
-
rspec-mocks (3.8.
|
|
79
|
+
rspec-mocks (3.8.1)
|
|
72
80
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
73
81
|
rspec-support (~> 3.8.0)
|
|
74
|
-
rspec-support (3.8.
|
|
75
|
-
ruby-kafka (0.7.
|
|
82
|
+
rspec-support (3.8.2)
|
|
83
|
+
ruby-kafka (0.7.9)
|
|
76
84
|
digest-crc
|
|
77
|
-
simplecov (0.
|
|
85
|
+
simplecov (0.17.0)
|
|
78
86
|
docile (~> 1.1)
|
|
79
87
|
json (>= 1.8, < 3)
|
|
80
88
|
simplecov-html (~> 0.10.0)
|
|
81
89
|
simplecov-html (0.10.2)
|
|
90
|
+
zeitwerk (2.1.9)
|
|
82
91
|
|
|
83
92
|
PLATFORMS
|
|
84
93
|
ruby
|
|
85
94
|
|
|
86
95
|
DEPENDENCIES
|
|
96
|
+
dry-validation
|
|
87
97
|
rspec
|
|
88
98
|
simplecov
|
|
89
99
|
waterdrop!
|
|
90
100
|
|
|
91
101
|
BUNDLED WITH
|
|
92
|
-
2.0.
|
|
102
|
+
2.0.2
|
data/README.md
CHANGED
|
@@ -11,7 +11,7 @@ It is:
|
|
|
11
11
|
|
|
12
12
|
- Thread safe
|
|
13
13
|
- Supports sync and async producers
|
|
14
|
-
- Working with 0.
|
|
14
|
+
- Working with 0.11+ Kafka
|
|
15
15
|
|
|
16
16
|
## Installation
|
|
17
17
|
|
|
@@ -31,15 +31,6 @@ and run
|
|
|
31
31
|
bundle install
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
## Kafka 0.10 or prior
|
|
35
|
-
|
|
36
|
-
If you're using Kafka 0.10, please lock `ruby-kafka` gem in your Gemfile to version `0.6.8`:
|
|
37
|
-
|
|
38
|
-
```ruby
|
|
39
|
-
gem 'waterdrop'
|
|
40
|
-
gem 'ruby-kafka', '~> 0.6.8'
|
|
41
|
-
```
|
|
42
|
-
|
|
43
34
|
## Setup
|
|
44
35
|
|
|
45
36
|
WaterDrop is a complex tool, that contains multiple configuration options. To keep everything organized, all the configuration options were divided into two groups:
|
|
@@ -113,6 +104,7 @@ Both ```SyncProducer``` and ```AsyncProducer``` accept following options:
|
|
|
113
104
|
| ```partition``` | false | Integer | A specific partition number that should be written to |
|
|
114
105
|
| ```partition_key``` | false | String | A string that can be used to deterministically select the partition |
|
|
115
106
|
| ```create_time``` | false | Time | The timestamp that should be set on the message |
|
|
107
|
+
| ```headers``` | false | Hash | Headers for the message |
|
|
116
108
|
|
|
117
109
|
Keep in mind, that message you want to send should be either binary or stringified (to_s, to_json, etc).
|
|
118
110
|
|
data/certs/mensfeld.pem
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
|
2
|
+
MIIEODCCAqCgAwIBAgIBATANBgkqhkiG9w0BAQsFADAjMSEwHwYDVQQDDBhtYWNp
|
|
3
|
+
ZWovREM9bWVuc2ZlbGQvREM9cGwwHhcNMTkwNzMwMTQ1NDU0WhcNMjAwNzI5MTQ1
|
|
4
|
+
NDU0WjAjMSEwHwYDVQQDDBhtYWNpZWovREM9bWVuc2ZlbGQvREM9cGwwggGiMA0G
|
|
5
|
+
CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQC9fCwtaHZG2SyyNXiH8r0QbJQx/xxl
|
|
6
|
+
dkvwWz9QGJO+O8rEx20FB1Ab+MVkfOscwIv5jWpmk1U9whzDPl1uFtIbgu+sk+Zb
|
|
7
|
+
uQlZyK/DPN6c+/BbBL+RryTBRyvkPLoCVwm7uxc/JZ1n4AI6eF4cCZ2ieZ9QgQbU
|
|
8
|
+
MQs2QPqs9hT50Ez/40GnOdadVfiDDGz+NME2C4ms0BriXwZ1tcRTfJIHe2xjIbbb
|
|
9
|
+
y5qRGfsLKcgMzvLQR24olixyX1MR0s4+Wveq3QL/gBhL4veUcv+UABJA8IJR0kyB
|
|
10
|
+
seHHutusiwZ1v3SjjjW1xLLrc2ARV0mgCb0WaK2T4iA3oFTGLh6Ydz8LNl31KQFv
|
|
11
|
+
94nRd8IhmJxrhQ6dQ/WT9IXoa5S9lfT5lPJeINemH4/6QPABzf9W2IZlCdI9wCdB
|
|
12
|
+
TBaw57MKneGAYZiKjw6OALSy2ltQUCl3RqFl3VP7n8uFy1U987Q5VIIQ3O1UUsQD
|
|
13
|
+
Oe/h+r7GUU4RSPKgPlrwvW9bD/UQ+zF51v8CAwEAAaN3MHUwCQYDVR0TBAIwADAL
|
|
14
|
+
BgNVHQ8EBAMCBLAwHQYDVR0OBBYEFJNIBHdfEUD7TqHqIer2YhWaWhwcMB0GA1Ud
|
|
15
|
+
EQQWMBSBEm1hY2llakBtZW5zZmVsZC5wbDAdBgNVHRIEFjAUgRJtYWNpZWpAbWVu
|
|
16
|
+
c2ZlbGQucGwwDQYJKoZIhvcNAQELBQADggGBAKA4eqko6BTNhlysip6rfBkVTGri
|
|
17
|
+
ZXsL+kRb2hLvsQJS/kLyM21oMlu+LN0aPj3qEFR8mE/YeDD8rLAfruBRTltPNbR7
|
|
18
|
+
xA5eE1gkxY5LfExUtK3b2wPqfmo7mZgfcsMwfYg/tUXw1WpBCnrhAJodpGH6SXmp
|
|
19
|
+
A40qFUZst0vjiOoO+aTblIHPmMJXoZ3K42dTlNKlEiDKUWMRKSgpjjYGEYalFNWI
|
|
20
|
+
hHfCz2r8L2t+dYdMZg1JGbEkq4ADGsAA8ioZIpJd7V4hI17u5TCdi7X5wh/0gN0E
|
|
21
|
+
CgP+nLox3D+l2q0QuQEkayr+auFYkzTCkF+BmEk1D0Ru4mcf3F4CJvEmW4Pzbjqt
|
|
22
|
+
i1tsCWPtJ4E/UUKnKaWKqGbjrjHJ0MuShYzHkodox5IOiCXIQg+1+YSzfXUV6WEK
|
|
23
|
+
KJG/fhg1JV5vVDdVy6x+tv5SQ5ctU0feCsVfESi3rE3zRd+nvzE9HcZ5aXeL1UtJ
|
|
24
|
+
nT5Xrioegu2w1jPyVEgyZgTZC5rvD0nNS5sFNQ==
|
|
25
|
+
-----END CERTIFICATE-----
|
data/config/errors.yml
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
en:
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
dry_validation:
|
|
3
|
+
errors:
|
|
4
|
+
broker_schema: >
|
|
5
|
+
has an invalid format.
|
|
6
|
+
Expected schema, host and port number.
|
|
7
|
+
Example: kafka://127.0.0.1:9092 or kafka+ssl://127.0.0.1:9092
|
|
8
|
+
ssl_client_cert_with_ssl_client_cert_key: >
|
|
9
|
+
Both ssl_client_cert and ssl_client_cert_key need to be provided.
|
|
10
|
+
ssl_client_cert_key_with_ssl_client_cert: >
|
|
11
|
+
Both ssl_client_cert_key and ssl_client_cert need to be provided.
|
|
12
|
+
ssl_client_cert_chain_with_ssl_client_cert: >
|
|
13
|
+
Both ssl_client_cert_chain and ssl_client_cert need to be provided.
|
|
14
|
+
ssl_client_cert_chain_with_ssl_client_cert_key: >
|
|
15
|
+
Both ssl_client_cert_chain and ssl_client_cert_key need to be provided.
|
|
16
|
+
ssl_client_cert_key_password_with_ssl_client_cert_key: >
|
|
17
|
+
Both ssl_client_cert_key_password and ssl_client_cert_key need to be provided.
|
|
18
|
+
sasl_oauth_token_provider_respond_to_token: >
|
|
19
|
+
sasl_oauth_token_provider needs to respond to a #token method.
|
data/lib/water_drop.rb
CHANGED
|
@@ -4,16 +4,13 @@
|
|
|
4
4
|
%w[
|
|
5
5
|
json
|
|
6
6
|
delivery_boy
|
|
7
|
-
null_logger
|
|
8
7
|
singleton
|
|
9
8
|
dry-configurable
|
|
10
9
|
dry/monitor/notifications
|
|
11
10
|
dry-validation
|
|
11
|
+
zeitwerk
|
|
12
12
|
].each { |lib| require lib }
|
|
13
13
|
|
|
14
|
-
# Internal components
|
|
15
|
-
base_path = File.dirname(__FILE__) + '/water_drop'
|
|
16
|
-
|
|
17
14
|
# WaterDrop library
|
|
18
15
|
module WaterDrop
|
|
19
16
|
class << self
|
|
@@ -44,16 +41,8 @@ module WaterDrop
|
|
|
44
41
|
end
|
|
45
42
|
end
|
|
46
43
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
schemas/config
|
|
53
|
-
config
|
|
54
|
-
config_applier
|
|
55
|
-
errors
|
|
56
|
-
base_producer
|
|
57
|
-
sync_producer
|
|
58
|
-
async_producer
|
|
59
|
-
].each { |lib| require "#{base_path}/#{lib}" }
|
|
44
|
+
Zeitwerk::Loader
|
|
45
|
+
.for_gem
|
|
46
|
+
.tap { |loader| loader.ignore("#{__dir__}/waterdrop.rb") }
|
|
47
|
+
.tap(&:setup)
|
|
48
|
+
.tap(&:eager_load)
|
|
@@ -19,8 +19,8 @@ module WaterDrop
|
|
|
19
19
|
d_method = WaterDrop.config.raise_on_buffer_overflow ? :deliver_async! : :deliver_async
|
|
20
20
|
|
|
21
21
|
DeliveryBoy.send(d_method, message, options)
|
|
22
|
-
rescue Kafka::Error =>
|
|
23
|
-
graceful_attempt?(attempts_count, message, options,
|
|
22
|
+
rescue Kafka::Error => e
|
|
23
|
+
graceful_attempt?(attempts_count, message, options, e) ? retry : raise(e)
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
end
|
|
@@ -4,6 +4,12 @@ module WaterDrop
|
|
|
4
4
|
# Base messages producer that contains all the logic that is exactly the same for both
|
|
5
5
|
# sync and async producers
|
|
6
6
|
class BaseProducer
|
|
7
|
+
# Contract for checking the correctness of the provided data that someone wants to
|
|
8
|
+
# dispatch to Kafka
|
|
9
|
+
SCHEMA = Contracts::MessageOptions.new.freeze
|
|
10
|
+
|
|
11
|
+
private_constant :SCHEMA
|
|
12
|
+
|
|
7
13
|
class << self
|
|
8
14
|
private
|
|
9
15
|
|
|
@@ -12,18 +18,19 @@ module WaterDrop
|
|
|
12
18
|
# @raise [WaterDrop::Errors::InvalidMessageOptions] raised when message options are
|
|
13
19
|
# somehow invalid and we cannot perform delivery because of that
|
|
14
20
|
def validate!(options)
|
|
15
|
-
validation_result =
|
|
21
|
+
validation_result = SCHEMA.call(options)
|
|
16
22
|
return true if validation_result.success?
|
|
23
|
+
|
|
17
24
|
raise Errors::InvalidMessageOptions, validation_result.errors
|
|
18
25
|
end
|
|
19
26
|
|
|
20
27
|
# Upon failed delivery, we may try to resend a message depending on the attempt number
|
|
21
|
-
# or
|
|
28
|
+
# or re-raise an error if we're unable to do that after given number of retries
|
|
22
29
|
# This method checks that and also instruments errors and retries for the delivery
|
|
23
30
|
# @param attempts_count [Integer] number of attempt (starting from 1) for the delivery
|
|
24
31
|
# @param message [String] message that we want to send to Kafka
|
|
25
32
|
# @param options [Hash] options (including topic) for producer
|
|
26
|
-
# @param error [Kafka::Error] error that
|
|
33
|
+
# @param error [Kafka::Error] error that occurred
|
|
27
34
|
# @return [Boolean] true if this is a graceful attempt and we can retry or false it this
|
|
28
35
|
# was the final one and we should deal with the fact, that we cannot deliver a given
|
|
29
36
|
# message
|
data/lib/water_drop/config.rb
CHANGED
|
@@ -3,18 +3,24 @@
|
|
|
3
3
|
# Configuration and descriptions are based on the delivery boy zendesk gem
|
|
4
4
|
# @see https://github.com/zendesk/delivery_boy
|
|
5
5
|
module WaterDrop
|
|
6
|
-
#
|
|
6
|
+
# Configuration object for setting up all options required by WaterDrop
|
|
7
7
|
class Config
|
|
8
8
|
extend Dry::Configurable
|
|
9
9
|
|
|
10
|
+
# Config schema definition
|
|
11
|
+
# @note We use a single instance not to create new one upon each usage
|
|
12
|
+
SCHEMA = Contracts::Config.new.freeze
|
|
13
|
+
|
|
14
|
+
private_constant :SCHEMA
|
|
15
|
+
|
|
10
16
|
# WaterDrop options
|
|
11
17
|
# option client_id [String] identifier of this producer
|
|
12
18
|
setting :client_id, 'waterdrop'
|
|
13
19
|
# option [Instance, nil] logger that we want to use or nil to fallback to ruby-kafka logger
|
|
14
|
-
setting :logger,
|
|
20
|
+
setting :logger, Logger.new($stdout, level: Logger::WARN)
|
|
15
21
|
# option [Instance] monitor that we want to use. See instrumentation part of the README for
|
|
16
22
|
# more details
|
|
17
|
-
setting :monitor, WaterDrop::Instrumentation::Monitor.
|
|
23
|
+
setting :monitor, WaterDrop::Instrumentation::Monitor.new
|
|
18
24
|
# option [Boolean] should we send messages. Setting this to false can be really useful when
|
|
19
25
|
# testing and or developing because when set to false, won't actually ping Kafka
|
|
20
26
|
setting :deliver, true
|
|
@@ -108,10 +114,20 @@ module WaterDrop
|
|
|
108
114
|
setting :sasl_scram_password, nil
|
|
109
115
|
# option sasl_scram_mechanism [String, nil] Scram mechanism, either 'sha256' or 'sha512'
|
|
110
116
|
setting :sasl_scram_mechanism, nil
|
|
117
|
+
# option sasl_over_ssl [Boolean] whether to enforce SSL with SASL
|
|
118
|
+
setting :sasl_over_ssl, true
|
|
119
|
+
# option ssl_client_cert_chain [String, nil] client cert chain or nil if not used
|
|
120
|
+
setting :ssl_client_cert_chain, nil
|
|
121
|
+
# option ssl_client_cert_key_password [String, nil] the password required to read
|
|
122
|
+
# the ssl_client_cert_key
|
|
123
|
+
setting :ssl_client_cert_key_password, nil
|
|
124
|
+
# @param sasl_oauth_token_provider [Object, nil] OAuthBearer Token Provider instance that
|
|
125
|
+
# implements method token.
|
|
126
|
+
setting :sasl_oauth_token_provider, nil
|
|
111
127
|
end
|
|
112
128
|
|
|
113
129
|
class << self
|
|
114
|
-
#
|
|
130
|
+
# Configuration method
|
|
115
131
|
# @yield Runs a block of code providing a config singleton instance to it
|
|
116
132
|
# @yieldparam [WaterDrop::Config] WaterDrop config instance
|
|
117
133
|
def setup
|
|
@@ -128,9 +144,10 @@ module WaterDrop
|
|
|
128
144
|
# @raise [WaterDrop::Errors::InvalidConfiguration] raised when something is wrong with
|
|
129
145
|
# the configuration
|
|
130
146
|
def validate!(config_hash)
|
|
131
|
-
validation_result =
|
|
147
|
+
validation_result = SCHEMA.call(config_hash)
|
|
132
148
|
return true if validation_result.success?
|
|
133
|
-
|
|
149
|
+
|
|
150
|
+
raise Errors::InvalidConfiguration, validation_result.errors.to_h
|
|
134
151
|
end
|
|
135
152
|
end
|
|
136
153
|
end
|
|
@@ -29,13 +29,14 @@ module WaterDrop
|
|
|
29
29
|
# that are ported 1:1 from ruby-kafka
|
|
30
30
|
# For some crazy reason, delivery boy requires compression codec as a string, when
|
|
31
31
|
# ruby-kafka as a symbol. We follow ruby-kafka internal design, so we had to mimic
|
|
32
|
-
# that by assigning a
|
|
32
|
+
# that by assigning a string version that down the road will be symbolized again
|
|
33
33
|
# by delivery boy
|
|
34
34
|
# @param delivery_boy_config [DeliveryBoy::Config] delivery boy config instance
|
|
35
35
|
# @param codec_name [Symbol] codec name as a symbol
|
|
36
36
|
def compression_codec(delivery_boy_config, codec_name)
|
|
37
37
|
# If there is no compression codec, we don't apply anything
|
|
38
38
|
return unless codec_name
|
|
39
|
+
|
|
39
40
|
delivery_boy_config.compression_codec = codec_name.to_s
|
|
40
41
|
end
|
|
41
42
|
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module WaterDrop
|
|
4
|
+
module Contracts
|
|
5
|
+
# Contract with validation rules for WaterDrop configuration details
|
|
6
|
+
class Config < Dry::Validation::Contract
|
|
7
|
+
# Valid uri schemas of Kafka broker url
|
|
8
|
+
URI_SCHEMES = %w[kafka kafka+ssl plaintext ssl].freeze
|
|
9
|
+
|
|
10
|
+
# Available sasl scram mechanism of authentication (plus nil)
|
|
11
|
+
SASL_SCRAM_MECHANISMS = %w[sha256 sha512].freeze
|
|
12
|
+
|
|
13
|
+
# Supported compression codecs
|
|
14
|
+
COMPRESSION_CODECS = %i[snappy gzip lz4 zstd].freeze
|
|
15
|
+
|
|
16
|
+
config.messages.load_paths << File.join(WaterDrop.gem_root, 'config', 'errors.yml')
|
|
17
|
+
|
|
18
|
+
class << self
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
# Builder for kafka scoped data custom rules
|
|
22
|
+
# @param keys [Symbol, Hash] the keys names
|
|
23
|
+
# @param block [Proc] block we want to run with validations within the kafka scope
|
|
24
|
+
def kafka_scope_rule(*keys, &block)
|
|
25
|
+
rule(*[:kafka].product(keys)) do
|
|
26
|
+
instance_exec(values[:kafka], &block)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
# Uri validator to check if uri is in a Kafka acceptable format
|
|
34
|
+
# @param uri [String] uri we want to validate
|
|
35
|
+
# @return [Boolean] true if it is a valid uri, otherwise false
|
|
36
|
+
def broker_schema?(uri)
|
|
37
|
+
uri = URI.parse(uri)
|
|
38
|
+
URI_SCHEMES.include?(uri.scheme) && uri.port
|
|
39
|
+
rescue URI::InvalidURIError
|
|
40
|
+
false
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
params do
|
|
44
|
+
required(:client_id).filled(:str?, format?: Contracts::TOPIC_REGEXP)
|
|
45
|
+
required(:logger).filled
|
|
46
|
+
required(:deliver).filled(:bool?)
|
|
47
|
+
required(:raise_on_buffer_overflow).filled(:bool?)
|
|
48
|
+
|
|
49
|
+
required(:kafka).schema do
|
|
50
|
+
required(:seed_brokers).value(:array, :filled?).each(:str?)
|
|
51
|
+
required(:connect_timeout).filled(:int?, gt?: 0)
|
|
52
|
+
required(:socket_timeout).filled(:int?, gt?: 0)
|
|
53
|
+
required(:compression_threshold).filled(:int?, gteq?: 1)
|
|
54
|
+
optional(:compression_codec).maybe(included_in?: COMPRESSION_CODECS)
|
|
55
|
+
|
|
56
|
+
required(:max_buffer_bytesize).filled(:int?, gt?: 0)
|
|
57
|
+
required(:max_buffer_size).filled(:int?, gt?: 0)
|
|
58
|
+
required(:max_queue_size).filled(:int?, gt?: 0)
|
|
59
|
+
|
|
60
|
+
required(:ack_timeout).filled(:int?, gt?: 0)
|
|
61
|
+
required(:delivery_interval).filled(:int?, gteq?: 0)
|
|
62
|
+
required(:delivery_threshold).filled(:int?, gteq?: 0)
|
|
63
|
+
|
|
64
|
+
required(:max_retries).filled(:int?, gteq?: 0)
|
|
65
|
+
required(:retry_backoff).filled(:int?, gteq?: 0)
|
|
66
|
+
required(:required_acks).filled(included_in?: [1, 0, -1, :all])
|
|
67
|
+
|
|
68
|
+
%i[
|
|
69
|
+
ssl_ca_cert
|
|
70
|
+
ssl_ca_cert_file_path
|
|
71
|
+
ssl_client_cert
|
|
72
|
+
ssl_client_cert_key
|
|
73
|
+
ssl_client_cert_chain
|
|
74
|
+
ssl_client_cert_key_password
|
|
75
|
+
sasl_gssapi_principal
|
|
76
|
+
sasl_gssapi_keytab
|
|
77
|
+
sasl_plain_authzid
|
|
78
|
+
sasl_plain_username
|
|
79
|
+
sasl_plain_password
|
|
80
|
+
sasl_scram_username
|
|
81
|
+
sasl_scram_password
|
|
82
|
+
].each do |encryption_attribute|
|
|
83
|
+
optional(encryption_attribute).maybe(:str?)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
optional(:ssl_ca_certs_from_system).maybe(:bool?)
|
|
87
|
+
optional(:sasl_over_ssl).maybe(:bool?)
|
|
88
|
+
optional(:sasl_oauth_token_provider).value(:any)
|
|
89
|
+
|
|
90
|
+
# It's not with other encryptions as it has some more rules
|
|
91
|
+
optional(:sasl_scram_mechanism)
|
|
92
|
+
.maybe(:str?, included_in?: SASL_SCRAM_MECHANISMS)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
kafka_scope_rule(:seed_brokers) do |kafka|
|
|
97
|
+
unless kafka[:seed_brokers].all?(&method(:broker_schema?))
|
|
98
|
+
key(%i[kafka seed_brokers]).failure(:broker_schema)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
kafka_scope_rule(:ssl_client_cert, :ssl_client_cert_key) do |kafka|
|
|
103
|
+
if kafka[:ssl_client_cert] &&
|
|
104
|
+
kafka[:ssl_client_cert_key].nil?
|
|
105
|
+
key(%i[kafka ssl_client_cert_key]).failure(:ssl_client_cert_with_ssl_client_cert_key)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
kafka_scope_rule(:ssl_client_cert_key, :ssl_client_cert) do |kafka|
|
|
110
|
+
if kafka[:ssl_client_cert_key] &&
|
|
111
|
+
kafka[:ssl_client_cert].nil?
|
|
112
|
+
key.failure(:ssl_client_cert_key_with_ssl_client_cert)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
kafka_scope_rule(:ssl_client_cert_chain, :ssl_client_cert) do |kafka|
|
|
117
|
+
if kafka[:ssl_client_cert_chain] &&
|
|
118
|
+
kafka[:ssl_client_cert].nil?
|
|
119
|
+
key.failure(:ssl_client_cert_chain_with_ssl_client_cert)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
kafka_scope_rule(:ssl_client_cert_key_password, :ssl_client_cert_key) do |kafka|
|
|
124
|
+
if kafka[:ssl_client_cert_key_password] &&
|
|
125
|
+
kafka[:ssl_client_cert_key].nil?
|
|
126
|
+
key.failure(:ssl_client_cert_key_password_with_ssl_client_cert_key)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
kafka_scope_rule(:sasl_oauth_token_provider) do |kafka|
|
|
131
|
+
if kafka[:sasl_oauth_token_provider] &&
|
|
132
|
+
!kafka[:sasl_oauth_token_provider].respond_to?(:token)
|
|
133
|
+
key.failure(:sasl_oauth_token_provider_respond_to_token)
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module WaterDrop
|
|
4
|
+
module Contracts
|
|
5
|
+
# Contract with validation rules for validating that all the message options that
|
|
6
|
+
# we provide to producer ale valid and usable
|
|
7
|
+
# @note Does not validate message itself as it is not our concern
|
|
8
|
+
class MessageOptions < Dry::Validation::Contract
|
|
9
|
+
params do
|
|
10
|
+
required(:topic).filled(:str?, format?: TOPIC_REGEXP)
|
|
11
|
+
optional(:key).maybe(:str?, :filled?)
|
|
12
|
+
optional(:partition).filled(:int?, gteq?: 0)
|
|
13
|
+
optional(:partition_key).maybe(:str?, :filled?)
|
|
14
|
+
optional(:create_time).maybe(:time?)
|
|
15
|
+
optional(:headers).maybe(:hash?)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
data/lib/water_drop/errors.rb
CHANGED
|
@@ -6,10 +6,10 @@ module WaterDrop
|
|
|
6
6
|
# Base class for all the WaterDrop internal errors
|
|
7
7
|
BaseError = Class.new(StandardError)
|
|
8
8
|
|
|
9
|
-
# Raised when configuration doesn't match with validation
|
|
9
|
+
# Raised when configuration doesn't match with validation contract
|
|
10
10
|
InvalidConfiguration = Class.new(BaseError)
|
|
11
11
|
|
|
12
|
-
# Raised when we try to send message with invalid
|
|
12
|
+
# Raised when we try to send message with invalid options
|
|
13
13
|
InvalidMessageOptions = Class.new(BaseError)
|
|
14
14
|
|
|
15
15
|
# Raised when want to hook up to an event that is not registered and supported
|
|
@@ -5,13 +5,11 @@ module WaterDrop
|
|
|
5
5
|
module Instrumentation
|
|
6
6
|
# Monitor is used to hookup external monitoring services to monitor how WaterDrop works
|
|
7
7
|
# Since it is a pub-sub based on dry-monitor, you can use as many subscribers/loggers at the
|
|
8
|
-
# same time, which means that you might have for example file logging and
|
|
8
|
+
# same time, which means that you might have for example file logging and NewRelic at the same
|
|
9
9
|
# time
|
|
10
10
|
# @note This class acts as a singleton because we are only permitted to have single monitor
|
|
11
11
|
# per running process (just as logger)
|
|
12
12
|
class Monitor < Dry::Monitor::Notifications
|
|
13
|
-
include Singleton
|
|
14
|
-
|
|
15
13
|
# List of events that we support in the system and to which a monitor client can hook up
|
|
16
14
|
# @note The non-error once support timestamp benchmarking
|
|
17
15
|
BASE_EVENTS = %w[
|
|
@@ -35,6 +33,7 @@ module WaterDrop
|
|
|
35
33
|
def subscribe(event_name_or_listener)
|
|
36
34
|
return super unless event_name_or_listener.is_a?(String)
|
|
37
35
|
return super if available_events.include?(event_name_or_listener)
|
|
36
|
+
|
|
38
37
|
raise Errors::UnregisteredMonitorEvent, event_name_or_listener
|
|
39
38
|
end
|
|
40
39
|
|
|
@@ -6,7 +6,7 @@ module WaterDrop
|
|
|
6
6
|
# It can be removed/replaced or anything without any harm to the Waterdrop flow
|
|
7
7
|
# @note It is a module as we can use it then as a part of the Karafka framework listener
|
|
8
8
|
# as well as we can use it standalone
|
|
9
|
-
|
|
9
|
+
class StdoutListener
|
|
10
10
|
# Log levels that we use in this particular listener
|
|
11
11
|
USED_LOG_LEVELS = %i[
|
|
12
12
|
info
|
|
@@ -33,20 +33,12 @@ module WaterDrop
|
|
|
33
33
|
|
|
34
34
|
info "Attempt #{attempts_count} of delivery to: #{options} because of #{error}"
|
|
35
35
|
end
|
|
36
|
-
|
|
37
|
-
module_function error_name
|
|
38
|
-
module_function retry_name
|
|
39
|
-
public error_name
|
|
40
|
-
public retry_name
|
|
41
36
|
end
|
|
42
37
|
|
|
43
38
|
USED_LOG_LEVELS.each do |log_level|
|
|
44
39
|
define_method log_level do |*args|
|
|
45
40
|
WaterDrop.logger.send(log_level, *args)
|
|
46
41
|
end
|
|
47
|
-
|
|
48
|
-
module_function log_level
|
|
49
|
-
private_class_method log_level
|
|
50
42
|
end
|
|
51
43
|
end
|
|
52
44
|
end
|
|
@@ -17,8 +17,8 @@ module WaterDrop
|
|
|
17
17
|
return unless WaterDrop.config.deliver
|
|
18
18
|
|
|
19
19
|
DeliveryBoy.deliver(message, options)
|
|
20
|
-
rescue Kafka::Error =>
|
|
21
|
-
graceful_attempt?(attempts_count, message, options,
|
|
20
|
+
rescue Kafka::Error => e
|
|
21
|
+
graceful_attempt?(attempts_count, message, options, e) ? retry : raise(e)
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
end
|
data/lib/water_drop/version.rb
CHANGED
data/log/.keep
ADDED
|
File without changes
|
data/waterdrop.gemspec
CHANGED
|
@@ -19,16 +19,17 @@ Gem::Specification.new do |spec|
|
|
|
19
19
|
spec.add_dependency 'delivery_boy', '~> 0.2'
|
|
20
20
|
spec.add_dependency 'dry-configurable', '~> 0.8'
|
|
21
21
|
spec.add_dependency 'dry-monitor', '~> 0.3'
|
|
22
|
-
spec.add_dependency 'dry-validation', '~>
|
|
23
|
-
spec.add_dependency '
|
|
24
|
-
spec.add_dependency '
|
|
22
|
+
spec.add_dependency 'dry-validation', '~> 1.2'
|
|
23
|
+
spec.add_dependency 'ruby-kafka', '>= 0.7.8'
|
|
24
|
+
spec.add_dependency 'zeitwerk', '~> 2.1'
|
|
25
25
|
|
|
26
|
-
spec.
|
|
27
|
-
\e[93mWarning:\e[0m If you're using Kafka 0.10, please lock ruby-kafka in your Gemfile to version '0.6.8':
|
|
28
|
-
gem 'ruby-kafka', '~> 0.6.8'
|
|
29
|
-
MSG
|
|
26
|
+
spec.required_ruby_version = '>= 2.4.0'
|
|
30
27
|
|
|
31
|
-
spec.
|
|
28
|
+
spec.cert_chain = ['certs/mensfeld.pem']
|
|
29
|
+
|
|
30
|
+
if $PROGRAM_NAME.end_with?('gem')
|
|
31
|
+
spec.signing_key = File.expand_path('~/.ssh/gem-private_key.pem')
|
|
32
|
+
end
|
|
32
33
|
|
|
33
34
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec)/}) }
|
|
34
35
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
metadata
CHANGED
|
@@ -1,14 +1,40 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: waterdrop
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.0.rc1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Maciej Mensfeld
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
|
-
cert_chain:
|
|
11
|
-
|
|
10
|
+
cert_chain:
|
|
11
|
+
- |
|
|
12
|
+
-----BEGIN CERTIFICATE-----
|
|
13
|
+
MIIEODCCAqCgAwIBAgIBATANBgkqhkiG9w0BAQsFADAjMSEwHwYDVQQDDBhtYWNp
|
|
14
|
+
ZWovREM9bWVuc2ZlbGQvREM9cGwwHhcNMTkwNzMwMTQ1NDU0WhcNMjAwNzI5MTQ1
|
|
15
|
+
NDU0WjAjMSEwHwYDVQQDDBhtYWNpZWovREM9bWVuc2ZlbGQvREM9cGwwggGiMA0G
|
|
16
|
+
CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQC9fCwtaHZG2SyyNXiH8r0QbJQx/xxl
|
|
17
|
+
dkvwWz9QGJO+O8rEx20FB1Ab+MVkfOscwIv5jWpmk1U9whzDPl1uFtIbgu+sk+Zb
|
|
18
|
+
uQlZyK/DPN6c+/BbBL+RryTBRyvkPLoCVwm7uxc/JZ1n4AI6eF4cCZ2ieZ9QgQbU
|
|
19
|
+
MQs2QPqs9hT50Ez/40GnOdadVfiDDGz+NME2C4ms0BriXwZ1tcRTfJIHe2xjIbbb
|
|
20
|
+
y5qRGfsLKcgMzvLQR24olixyX1MR0s4+Wveq3QL/gBhL4veUcv+UABJA8IJR0kyB
|
|
21
|
+
seHHutusiwZ1v3SjjjW1xLLrc2ARV0mgCb0WaK2T4iA3oFTGLh6Ydz8LNl31KQFv
|
|
22
|
+
94nRd8IhmJxrhQ6dQ/WT9IXoa5S9lfT5lPJeINemH4/6QPABzf9W2IZlCdI9wCdB
|
|
23
|
+
TBaw57MKneGAYZiKjw6OALSy2ltQUCl3RqFl3VP7n8uFy1U987Q5VIIQ3O1UUsQD
|
|
24
|
+
Oe/h+r7GUU4RSPKgPlrwvW9bD/UQ+zF51v8CAwEAAaN3MHUwCQYDVR0TBAIwADAL
|
|
25
|
+
BgNVHQ8EBAMCBLAwHQYDVR0OBBYEFJNIBHdfEUD7TqHqIer2YhWaWhwcMB0GA1Ud
|
|
26
|
+
EQQWMBSBEm1hY2llakBtZW5zZmVsZC5wbDAdBgNVHRIEFjAUgRJtYWNpZWpAbWVu
|
|
27
|
+
c2ZlbGQucGwwDQYJKoZIhvcNAQELBQADggGBAKA4eqko6BTNhlysip6rfBkVTGri
|
|
28
|
+
ZXsL+kRb2hLvsQJS/kLyM21oMlu+LN0aPj3qEFR8mE/YeDD8rLAfruBRTltPNbR7
|
|
29
|
+
xA5eE1gkxY5LfExUtK3b2wPqfmo7mZgfcsMwfYg/tUXw1WpBCnrhAJodpGH6SXmp
|
|
30
|
+
A40qFUZst0vjiOoO+aTblIHPmMJXoZ3K42dTlNKlEiDKUWMRKSgpjjYGEYalFNWI
|
|
31
|
+
hHfCz2r8L2t+dYdMZg1JGbEkq4ADGsAA8ioZIpJd7V4hI17u5TCdi7X5wh/0gN0E
|
|
32
|
+
CgP+nLox3D+l2q0QuQEkayr+auFYkzTCkF+BmEk1D0Ru4mcf3F4CJvEmW4Pzbjqt
|
|
33
|
+
i1tsCWPtJ4E/UUKnKaWKqGbjrjHJ0MuShYzHkodox5IOiCXIQg+1+YSzfXUV6WEK
|
|
34
|
+
KJG/fhg1JV5vVDdVy6x+tv5SQ5ctU0feCsVfESi3rE3zRd+nvzE9HcZ5aXeL1UtJ
|
|
35
|
+
nT5Xrioegu2w1jPyVEgyZgTZC5rvD0nNS5sFNQ==
|
|
36
|
+
-----END CERTIFICATE-----
|
|
37
|
+
date: 2019-07-31 00:00:00.000000000 Z
|
|
12
38
|
dependencies:
|
|
13
39
|
- !ruby/object:Gem::Dependency
|
|
14
40
|
name: delivery_boy
|
|
@@ -58,42 +84,42 @@ dependencies:
|
|
|
58
84
|
requirements:
|
|
59
85
|
- - "~>"
|
|
60
86
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
87
|
+
version: '1.2'
|
|
62
88
|
type: :runtime
|
|
63
89
|
prerelease: false
|
|
64
90
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
91
|
requirements:
|
|
66
92
|
- - "~>"
|
|
67
93
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '
|
|
94
|
+
version: '1.2'
|
|
69
95
|
- !ruby/object:Gem::Dependency
|
|
70
|
-
name:
|
|
96
|
+
name: ruby-kafka
|
|
71
97
|
requirement: !ruby/object:Gem::Requirement
|
|
72
98
|
requirements:
|
|
73
|
-
- - "
|
|
99
|
+
- - ">="
|
|
74
100
|
- !ruby/object:Gem::Version
|
|
75
|
-
version:
|
|
101
|
+
version: 0.7.8
|
|
76
102
|
type: :runtime
|
|
77
103
|
prerelease: false
|
|
78
104
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
105
|
requirements:
|
|
80
|
-
- - "
|
|
106
|
+
- - ">="
|
|
81
107
|
- !ruby/object:Gem::Version
|
|
82
|
-
version:
|
|
108
|
+
version: 0.7.8
|
|
83
109
|
- !ruby/object:Gem::Dependency
|
|
84
|
-
name:
|
|
110
|
+
name: zeitwerk
|
|
85
111
|
requirement: !ruby/object:Gem::Requirement
|
|
86
112
|
requirements:
|
|
87
|
-
- - "
|
|
113
|
+
- - "~>"
|
|
88
114
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: '
|
|
115
|
+
version: '2.1'
|
|
90
116
|
type: :runtime
|
|
91
117
|
prerelease: false
|
|
92
118
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
119
|
requirements:
|
|
94
|
-
- - "
|
|
120
|
+
- - "~>"
|
|
95
121
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: '
|
|
122
|
+
version: '2.1'
|
|
97
123
|
description: Kafka messaging made easy!
|
|
98
124
|
email:
|
|
99
125
|
- maciej@mensfeld.pl
|
|
@@ -101,7 +127,8 @@ executables: []
|
|
|
101
127
|
extensions: []
|
|
102
128
|
extra_rdoc_files: []
|
|
103
129
|
files:
|
|
104
|
-
- ".coditsu.yml"
|
|
130
|
+
- ".coditsu/ci.yml"
|
|
131
|
+
- ".github/FUNDING.yml"
|
|
105
132
|
- ".gitignore"
|
|
106
133
|
- ".rspec"
|
|
107
134
|
- ".ruby-gemset"
|
|
@@ -112,27 +139,29 @@ files:
|
|
|
112
139
|
- Gemfile.lock
|
|
113
140
|
- MIT-LICENCE
|
|
114
141
|
- README.md
|
|
142
|
+
- certs/mensfeld.pem
|
|
115
143
|
- config/errors.yml
|
|
116
144
|
- lib/water_drop.rb
|
|
117
145
|
- lib/water_drop/async_producer.rb
|
|
118
146
|
- lib/water_drop/base_producer.rb
|
|
119
147
|
- lib/water_drop/config.rb
|
|
120
148
|
- lib/water_drop/config_applier.rb
|
|
149
|
+
- lib/water_drop/contracts.rb
|
|
150
|
+
- lib/water_drop/contracts/config.rb
|
|
151
|
+
- lib/water_drop/contracts/message_options.rb
|
|
121
152
|
- lib/water_drop/errors.rb
|
|
122
|
-
- lib/water_drop/instrumentation/listener.rb
|
|
123
153
|
- lib/water_drop/instrumentation/monitor.rb
|
|
124
|
-
- lib/water_drop/
|
|
125
|
-
- lib/water_drop/schemas/message_options.rb
|
|
154
|
+
- lib/water_drop/instrumentation/stdout_listener.rb
|
|
126
155
|
- lib/water_drop/sync_producer.rb
|
|
127
156
|
- lib/water_drop/version.rb
|
|
128
157
|
- lib/waterdrop.rb
|
|
158
|
+
- log/.keep
|
|
129
159
|
- waterdrop.gemspec
|
|
130
160
|
homepage: https://github.com/karafka/waterdrop
|
|
131
161
|
licenses:
|
|
132
162
|
- MIT
|
|
133
163
|
metadata: {}
|
|
134
|
-
post_install_message:
|
|
135
|
-
ruby-kafka in your Gemfile to version '0.6.8':\ngem 'ruby-kafka', '~> 0.6.8'\n"
|
|
164
|
+
post_install_message:
|
|
136
165
|
rdoc_options: []
|
|
137
166
|
require_paths:
|
|
138
167
|
- lib
|
|
@@ -140,14 +169,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
140
169
|
requirements:
|
|
141
170
|
- - ">="
|
|
142
171
|
- !ruby/object:Gem::Version
|
|
143
|
-
version: 2.
|
|
172
|
+
version: 2.4.0
|
|
144
173
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
145
174
|
requirements:
|
|
146
|
-
- - "
|
|
175
|
+
- - ">"
|
|
147
176
|
- !ruby/object:Gem::Version
|
|
148
|
-
version:
|
|
177
|
+
version: 1.3.1
|
|
149
178
|
requirements: []
|
|
150
|
-
rubygems_version: 3.0.
|
|
179
|
+
rubygems_version: 3.0.3
|
|
151
180
|
signing_key:
|
|
152
181
|
specification_version: 4
|
|
153
182
|
summary: Kafka messaging made easy!
|
metadata.gz.sig
ADDED
|
Binary file
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module WaterDrop
|
|
4
|
-
# Namespace for all the schemas for config validations
|
|
5
|
-
module Schemas
|
|
6
|
-
# Schema with validation rules for WaterDrop configuration details
|
|
7
|
-
Config = Dry::Validation.Schema do
|
|
8
|
-
# Valid uri schemas of Kafka broker url
|
|
9
|
-
URI_SCHEMES = %w[
|
|
10
|
-
kafka
|
|
11
|
-
kafka+ssl
|
|
12
|
-
].freeze
|
|
13
|
-
|
|
14
|
-
# Available sasl scram mechanism of authentication (plus nil)
|
|
15
|
-
SASL_SCRAM_MECHANISMS ||= %w[sha256 sha512].freeze
|
|
16
|
-
|
|
17
|
-
configure do
|
|
18
|
-
config.messages_file = File.join(
|
|
19
|
-
WaterDrop.gem_root, 'config', 'errors.yml'
|
|
20
|
-
)
|
|
21
|
-
|
|
22
|
-
# Uri validator to check if uri is in a Kafka acceptable format
|
|
23
|
-
# @param uri [String] uri we want to validate
|
|
24
|
-
# @return [Boolean] true if it is a valid uri, otherwise false
|
|
25
|
-
def broker_schema?(uri)
|
|
26
|
-
uri = URI.parse(uri)
|
|
27
|
-
URI_SCHEMES.include?(uri.scheme) && uri.port
|
|
28
|
-
rescue URI::InvalidURIError
|
|
29
|
-
false
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
required(:client_id).filled(:str?, format?: Schemas::TOPIC_REGEXP)
|
|
34
|
-
required(:logger).filled
|
|
35
|
-
required(:deliver).filled(:bool?)
|
|
36
|
-
required(:raise_on_buffer_overflow).filled(:bool?)
|
|
37
|
-
|
|
38
|
-
required(:kafka).schema do
|
|
39
|
-
required(:seed_brokers).filled { each(:broker_schema?) }
|
|
40
|
-
required(:connect_timeout).filled(:int?, gt?: 0)
|
|
41
|
-
required(:socket_timeout).filled(:int?, gt?: 0)
|
|
42
|
-
required(:compression_threshold).filled(:int?, gteq?: 1)
|
|
43
|
-
optional(:compression_codec).maybe(included_in?: %i[snappy gzip lz4])
|
|
44
|
-
|
|
45
|
-
required(:max_buffer_bytesize).filled(:int?, gt?: 0)
|
|
46
|
-
required(:max_buffer_size).filled(:int?, gt?: 0)
|
|
47
|
-
required(:max_queue_size).filled(:int?, gt?: 0)
|
|
48
|
-
|
|
49
|
-
required(:ack_timeout).filled(:int?, gt?: 0)
|
|
50
|
-
required(:delivery_interval).filled(:int?, gteq?: 0)
|
|
51
|
-
required(:delivery_threshold).filled(:int?, gteq?: 0)
|
|
52
|
-
|
|
53
|
-
required(:max_retries).filled(:int?, gteq?: 0)
|
|
54
|
-
required(:retry_backoff).filled(:int?, gteq?: 0)
|
|
55
|
-
required(:required_acks).filled(included_in?: [1, 0, -1, :all])
|
|
56
|
-
|
|
57
|
-
%i[
|
|
58
|
-
ssl_ca_cert
|
|
59
|
-
ssl_ca_cert_file_path
|
|
60
|
-
ssl_client_cert
|
|
61
|
-
ssl_client_cert_key
|
|
62
|
-
sasl_gssapi_principal
|
|
63
|
-
sasl_gssapi_keytab
|
|
64
|
-
sasl_plain_authzid
|
|
65
|
-
sasl_plain_username
|
|
66
|
-
sasl_plain_password
|
|
67
|
-
sasl_scram_username
|
|
68
|
-
sasl_scram_password
|
|
69
|
-
].each do |encryption_attribute|
|
|
70
|
-
optional(encryption_attribute).maybe(:str?)
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
optional(:ssl_ca_certs_from_system).maybe(:bool?)
|
|
74
|
-
|
|
75
|
-
# It's not with other encryptions as it has some more rules
|
|
76
|
-
optional(:sasl_scram_mechanism)
|
|
77
|
-
.maybe(:str?, included_in?: WaterDrop::Schemas::SASL_SCRAM_MECHANISMS)
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
end
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module WaterDrop
|
|
4
|
-
module Schemas
|
|
5
|
-
# Regexp to check that topic has a valid format
|
|
6
|
-
TOPIC_REGEXP = /\A(\w|\-|\.)+\z/
|
|
7
|
-
|
|
8
|
-
# Schema with validation rules for validating that all the message options that
|
|
9
|
-
# we provide to producer ale valid and usable
|
|
10
|
-
# @note Does not validate message itself as it is not our concern
|
|
11
|
-
MessageOptions = Dry::Validation.Schema do
|
|
12
|
-
required(:topic).filled(:str?, format?: TOPIC_REGEXP)
|
|
13
|
-
optional(:key).maybe(:str?, :filled?)
|
|
14
|
-
optional(:partition).filled(:int?, gteq?: 0)
|
|
15
|
-
optional(:partition_key).maybe(:str?, :filled?)
|
|
16
|
-
optional(:create_time).maybe(:time?)
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|