waterdrop 1.2.2 → 1.3.1
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/ci.yml +3 -0
- data/.github/FUNDING.yml +1 -0
- data/.gitignore +2 -1
- data/.ruby-version +1 -1
- data/.travis.yml +35 -18
- data/CHANGELOG.md +37 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +60 -49
- data/README.md +3 -2
- 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 +25 -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 +139 -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 +11 -5
- metadata +62 -18
- 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: bc0f332e73321a83f3e2026ee435542e85129149e033381428ea5ed10fb65d4f
|
|
4
|
+
data.tar.gz: 1d677bffde0a588a5242568179b84c4a72705a25b6a4720373946b74bbecf411
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9a166e5eafefcda2314eb2348b95d18b364cfb3c05fea120a704e42fa945379c7d59960800c1755ca5e6e92ed084c05d4f5f4589fca04be90446947491d19193
|
|
7
|
+
data.tar.gz: f20cf44b891a343616082e41b9d50354102843c95dbe62b9b71e68a7cfec0d1c54a1aaa88540072ecabc937fe7e02f7ad881c4e2f44ef6af55f051390378e5cc
|
checksums.yaml.gz.sig
ADDED
|
Binary file
|
data.tar.gz.sig
ADDED
|
Binary file
|
data/.coditsu/ci.yml
ADDED
data/.github/FUNDING.yml
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
open_collective: karafka
|
data/.gitignore
CHANGED
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.5
|
|
1
|
+
2.6.5
|
data/.travis.yml
CHANGED
|
@@ -1,18 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
1
|
+
services:
|
|
2
|
+
- docker
|
|
3
|
+
|
|
4
|
+
dist: trusty
|
|
5
|
+
cache: bundler
|
|
6
|
+
|
|
7
|
+
git:
|
|
8
|
+
depth: false
|
|
9
|
+
|
|
10
|
+
test: &test
|
|
11
|
+
stage: Test
|
|
12
|
+
language: ruby
|
|
13
|
+
before_install:
|
|
14
|
+
- gem install bundler
|
|
15
|
+
- gem update --system
|
|
16
|
+
script: bundle exec rspec
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
include:
|
|
20
|
+
- <<: *test
|
|
21
|
+
rvm: 2.6.5
|
|
22
|
+
- <<: *test
|
|
23
|
+
rvm: 2.5.5
|
|
24
|
+
|
|
25
|
+
- stage: coditsu
|
|
26
|
+
language: ruby
|
|
27
|
+
rvm: 2.6.5
|
|
28
|
+
before_install:
|
|
29
|
+
- gem update --system
|
|
30
|
+
- gem install bundler
|
|
31
|
+
script: \curl -sSL https://api.coditsu.io/run/ci | bash
|
|
32
|
+
|
|
33
|
+
stages:
|
|
34
|
+
- coditsu
|
|
35
|
+
- test
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
# WaterDrop changelog
|
|
2
2
|
|
|
3
|
+
## 1.3.1 (2019-10-21)
|
|
4
|
+
- Ruby 2.6.5 support
|
|
5
|
+
- Expose setting to optionally verify hostname on ssl certs #109 (tabdollahi)
|
|
6
|
+
|
|
7
|
+
## 1.3.0 (2019-09-09)
|
|
8
|
+
- Drop Ruby 2.4 support
|
|
9
|
+
|
|
10
|
+
## 1.3.0.rc1 (2019-07-31)
|
|
11
|
+
- Drop Ruby 2.3 support
|
|
12
|
+
- Drop support for Kafka 0.10 in favor of native support for Kafka 0.11.
|
|
13
|
+
- Ruby 2.6.3 support
|
|
14
|
+
- Support message headers
|
|
15
|
+
- `sasl_over_ssl` support
|
|
16
|
+
- Unlock Ruby Kafka + provide support for 0.7 only
|
|
17
|
+
- #60 - Rename listener to StdoutListener
|
|
18
|
+
- Drop support for Kafka 0.10 in favor of native support for Kafka 0.11.
|
|
19
|
+
- Support ruby-kafka 0.7
|
|
20
|
+
- Support message headers
|
|
21
|
+
- `sasl_over_ssl` support
|
|
22
|
+
- `ssl_client_cert_key_password` support
|
|
23
|
+
- #87 - Make stdout listener as instance
|
|
24
|
+
- Use Zeitwerk for gem code loading
|
|
25
|
+
- #93 - zstd compression support
|
|
26
|
+
- #99 - schemas are renamed to contracts
|
|
27
|
+
- Bump delivery_boy (0.2.7 => 0.2.8)
|
|
28
|
+
|
|
29
|
+
## 1.2.5
|
|
30
|
+
- Bump deps to match Karafka
|
|
31
|
+
- drop jruby support
|
|
32
|
+
- drop ruby 2.2 support
|
|
33
|
+
|
|
34
|
+
## 1.2.4
|
|
35
|
+
- Due to multiple requests, unlock of 0.7 with an additional post-install message
|
|
36
|
+
|
|
37
|
+
## 1.2.3
|
|
38
|
+
- Lock ruby-kafka to 0.6 (0.7 support targeted for WaterDrop 1.3)
|
|
39
|
+
|
|
3
40
|
## 1.2.2
|
|
4
41
|
- #55 - Codec settings unification and config applier
|
|
5
42
|
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,82 +1,93 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
waterdrop (1.
|
|
4
|
+
waterdrop (1.3.1)
|
|
5
5
|
delivery_boy (~> 0.2)
|
|
6
|
-
dry-configurable (~> 0.
|
|
7
|
-
dry-monitor (~> 0.
|
|
8
|
-
dry-validation (~>
|
|
9
|
-
|
|
6
|
+
dry-configurable (~> 0.8)
|
|
7
|
+
dry-monitor (~> 0.3)
|
|
8
|
+
dry-validation (~> 1.2)
|
|
9
|
+
ruby-kafka (>= 0.7.8)
|
|
10
|
+
zeitwerk (~> 2.1)
|
|
10
11
|
|
|
11
12
|
GEM
|
|
12
13
|
remote: https://rubygems.org/
|
|
13
14
|
specs:
|
|
14
|
-
concurrent-ruby (1.
|
|
15
|
-
delivery_boy (0.2.
|
|
16
|
-
king_konf (~> 0.
|
|
17
|
-
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)
|
|
18
19
|
diff-lcs (1.3)
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
digest-crc (0.4.1)
|
|
21
|
+
docile (1.3.2)
|
|
22
|
+
dry-configurable (0.8.3)
|
|
21
23
|
concurrent-ruby (~> 1.0)
|
|
22
|
-
|
|
24
|
+
dry-core (~> 0.4, >= 0.4.7)
|
|
25
|
+
dry-container (0.7.2)
|
|
23
26
|
concurrent-ruby (~> 1.0)
|
|
24
27
|
dry-configurable (~> 0.1, >= 0.1.3)
|
|
25
|
-
dry-core (0.4.
|
|
28
|
+
dry-core (0.4.9)
|
|
26
29
|
concurrent-ruby (~> 1.0)
|
|
27
|
-
dry-equalizer (0.2.
|
|
28
|
-
dry-events (0.
|
|
30
|
+
dry-equalizer (0.2.2)
|
|
31
|
+
dry-events (0.2.0)
|
|
29
32
|
concurrent-ruby (~> 1.0)
|
|
30
33
|
dry-core (~> 0.4)
|
|
31
34
|
dry-equalizer (~> 0.2)
|
|
32
|
-
dry-
|
|
33
|
-
|
|
35
|
+
dry-inflector (0.2.0)
|
|
36
|
+
dry-initializer (3.0.1)
|
|
37
|
+
dry-logic (1.0.3)
|
|
38
|
+
concurrent-ruby (~> 1.0)
|
|
34
39
|
dry-core (~> 0.2)
|
|
35
40
|
dry-equalizer (~> 0.2)
|
|
36
|
-
dry-monitor (0.1
|
|
41
|
+
dry-monitor (0.3.1)
|
|
37
42
|
dry-configurable (~> 0.5)
|
|
43
|
+
dry-core (~> 0.4)
|
|
38
44
|
dry-equalizer (~> 0.2)
|
|
39
45
|
dry-events (~> 0.1)
|
|
40
|
-
|
|
41
|
-
dry-types (0.12.2)
|
|
46
|
+
dry-schema (1.4.1)
|
|
42
47
|
concurrent-ruby (~> 1.0)
|
|
43
|
-
dry-configurable (~> 0.
|
|
44
|
-
dry-
|
|
45
|
-
dry-core (~> 0.2, >= 0.2.1)
|
|
48
|
+
dry-configurable (~> 0.8, >= 0.8.3)
|
|
49
|
+
dry-core (~> 0.4)
|
|
46
50
|
dry-equalizer (~> 0.2)
|
|
47
|
-
dry-
|
|
48
|
-
|
|
49
|
-
|
|
51
|
+
dry-initializer (~> 3.0)
|
|
52
|
+
dry-logic (~> 1.0)
|
|
53
|
+
dry-types (~> 1.2)
|
|
54
|
+
dry-types (1.2.0)
|
|
50
55
|
concurrent-ruby (~> 1.0)
|
|
51
|
-
dry-
|
|
52
|
-
dry-core (~> 0.
|
|
56
|
+
dry-container (~> 0.3)
|
|
57
|
+
dry-core (~> 0.4, >= 0.4.4)
|
|
58
|
+
dry-equalizer (~> 0.2, >= 0.2.2)
|
|
59
|
+
dry-inflector (~> 0.1, >= 0.1.2)
|
|
60
|
+
dry-logic (~> 1.0, >= 1.0.2)
|
|
61
|
+
dry-validation (1.3.1)
|
|
62
|
+
concurrent-ruby (~> 1.0)
|
|
63
|
+
dry-container (~> 0.7, >= 0.7.1)
|
|
64
|
+
dry-core (~> 0.4)
|
|
53
65
|
dry-equalizer (~> 0.2)
|
|
54
|
-
dry-
|
|
55
|
-
dry-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
rspec-
|
|
64
|
-
|
|
65
|
-
rspec-core (3.7.1)
|
|
66
|
-
rspec-support (~> 3.7.0)
|
|
67
|
-
rspec-expectations (3.7.0)
|
|
66
|
+
dry-initializer (~> 3.0)
|
|
67
|
+
dry-schema (~> 1.0, >= 1.3.1)
|
|
68
|
+
json (2.2.0)
|
|
69
|
+
king_konf (0.3.7)
|
|
70
|
+
rspec (3.9.0)
|
|
71
|
+
rspec-core (~> 3.9.0)
|
|
72
|
+
rspec-expectations (~> 3.9.0)
|
|
73
|
+
rspec-mocks (~> 3.9.0)
|
|
74
|
+
rspec-core (3.9.0)
|
|
75
|
+
rspec-support (~> 3.9.0)
|
|
76
|
+
rspec-expectations (3.9.0)
|
|
68
77
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
69
|
-
rspec-support (~> 3.
|
|
70
|
-
rspec-mocks (3.
|
|
78
|
+
rspec-support (~> 3.9.0)
|
|
79
|
+
rspec-mocks (3.9.0)
|
|
71
80
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
72
|
-
rspec-support (~> 3.
|
|
73
|
-
rspec-support (3.
|
|
74
|
-
ruby-kafka (0.
|
|
75
|
-
|
|
81
|
+
rspec-support (~> 3.9.0)
|
|
82
|
+
rspec-support (3.9.0)
|
|
83
|
+
ruby-kafka (0.7.10)
|
|
84
|
+
digest-crc
|
|
85
|
+
simplecov (0.17.1)
|
|
76
86
|
docile (~> 1.1)
|
|
77
87
|
json (>= 1.8, < 3)
|
|
78
88
|
simplecov-html (~> 0.10.0)
|
|
79
89
|
simplecov-html (0.10.2)
|
|
90
|
+
zeitwerk (2.2.0)
|
|
80
91
|
|
|
81
92
|
PLATFORMS
|
|
82
93
|
ruby
|
|
@@ -87,4 +98,4 @@ DEPENDENCIES
|
|
|
87
98
|
waterdrop!
|
|
88
99
|
|
|
89
100
|
BUNDLED WITH
|
|
90
|
-
|
|
101
|
+
2.0.2
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# WaterDrop
|
|
2
2
|
|
|
3
|
-
[](https://travis-ci.org/karafka/waterdrop)
|
|
4
4
|
[](https://gitter.im/karafka/karafka?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
|
5
5
|
|
|
6
6
|
Gem used to send messages to Kafka in an easy way with an extra validation layer. It is a part of the [Karafka](https://github.com/karafka/karafka) ecosystem.
|
|
@@ -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
|
|
|
@@ -104,6 +104,7 @@ Both ```SyncProducer``` and ```AsyncProducer``` accept following options:
|
|
|
104
104
|
| ```partition``` | false | Integer | A specific partition number that should be written to |
|
|
105
105
|
| ```partition_key``` | false | String | A string that can be used to deterministically select the partition |
|
|
106
106
|
| ```create_time``` | false | Time | The timestamp that should be set on the message |
|
|
107
|
+
| ```headers``` | false | Hash | Headers for the message |
|
|
107
108
|
|
|
108
109
|
Keep in mind, that message you want to send should be either binary or stringified (to_s, to_json, etc).
|
|
109
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
|
|
@@ -88,6 +94,8 @@ module WaterDrop
|
|
|
88
94
|
# option ssl_ca_certs_from_system [Boolean] Use the CA certs from your system's default
|
|
89
95
|
# certificate store
|
|
90
96
|
setting :ssl_ca_certs_from_system, false
|
|
97
|
+
# option ssl_verify_hostname [Boolean] Verify the hostname for client certs
|
|
98
|
+
setting :ssl_verify_hostname, true
|
|
91
99
|
# option ssl_client_cert [String, nil] SSL client certificate
|
|
92
100
|
setting :ssl_client_cert, nil
|
|
93
101
|
# option ssl_client_cert_key [String, nil] SSL client certificate password
|
|
@@ -108,10 +116,20 @@ module WaterDrop
|
|
|
108
116
|
setting :sasl_scram_password, nil
|
|
109
117
|
# option sasl_scram_mechanism [String, nil] Scram mechanism, either 'sha256' or 'sha512'
|
|
110
118
|
setting :sasl_scram_mechanism, nil
|
|
119
|
+
# option sasl_over_ssl [Boolean] whether to enforce SSL with SASL
|
|
120
|
+
setting :sasl_over_ssl, true
|
|
121
|
+
# option ssl_client_cert_chain [String, nil] client cert chain or nil if not used
|
|
122
|
+
setting :ssl_client_cert_chain, nil
|
|
123
|
+
# option ssl_client_cert_key_password [String, nil] the password required to read
|
|
124
|
+
# the ssl_client_cert_key
|
|
125
|
+
setting :ssl_client_cert_key_password, nil
|
|
126
|
+
# @param sasl_oauth_token_provider [Object, nil] OAuthBearer Token Provider instance that
|
|
127
|
+
# implements method token.
|
|
128
|
+
setting :sasl_oauth_token_provider, nil
|
|
111
129
|
end
|
|
112
130
|
|
|
113
131
|
class << self
|
|
114
|
-
#
|
|
132
|
+
# Configuration method
|
|
115
133
|
# @yield Runs a block of code providing a config singleton instance to it
|
|
116
134
|
# @yieldparam [WaterDrop::Config] WaterDrop config instance
|
|
117
135
|
def setup
|
|
@@ -128,9 +146,10 @@ module WaterDrop
|
|
|
128
146
|
# @raise [WaterDrop::Errors::InvalidConfiguration] raised when something is wrong with
|
|
129
147
|
# the configuration
|
|
130
148
|
def validate!(config_hash)
|
|
131
|
-
validation_result =
|
|
149
|
+
validation_result = SCHEMA.call(config_hash)
|
|
132
150
|
return true if validation_result.success?
|
|
133
|
-
|
|
151
|
+
|
|
152
|
+
raise Errors::InvalidConfiguration, validation_result.errors.to_h
|
|
134
153
|
end
|
|
135
154
|
end
|
|
136
155
|
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,139 @@
|
|
|
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_verify_hostname).maybe(:bool?)
|
|
87
|
+
optional(:ssl_ca_certs_from_system).maybe(:bool?)
|
|
88
|
+
optional(:sasl_over_ssl).maybe(:bool?)
|
|
89
|
+
optional(:sasl_oauth_token_provider).value(:any)
|
|
90
|
+
|
|
91
|
+
# It's not with other encryptions as it has some more rules
|
|
92
|
+
optional(:sasl_scram_mechanism)
|
|
93
|
+
.maybe(:str?, included_in?: SASL_SCRAM_MECHANISMS)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
kafka_scope_rule(:seed_brokers) do |kafka|
|
|
98
|
+
unless kafka[:seed_brokers].all?(&method(:broker_schema?))
|
|
99
|
+
key(%i[kafka seed_brokers]).failure(:broker_schema)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
kafka_scope_rule(:ssl_client_cert, :ssl_client_cert_key) do |kafka|
|
|
104
|
+
if kafka[:ssl_client_cert] &&
|
|
105
|
+
kafka[:ssl_client_cert_key].nil?
|
|
106
|
+
key(%i[kafka ssl_client_cert_key]).failure(:ssl_client_cert_with_ssl_client_cert_key)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
kafka_scope_rule(:ssl_client_cert_key, :ssl_client_cert) do |kafka|
|
|
111
|
+
if kafka[:ssl_client_cert_key] &&
|
|
112
|
+
kafka[:ssl_client_cert].nil?
|
|
113
|
+
key.failure(:ssl_client_cert_key_with_ssl_client_cert)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
kafka_scope_rule(:ssl_client_cert_chain, :ssl_client_cert) do |kafka|
|
|
118
|
+
if kafka[:ssl_client_cert_chain] &&
|
|
119
|
+
kafka[:ssl_client_cert].nil?
|
|
120
|
+
key.failure(:ssl_client_cert_chain_with_ssl_client_cert)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
kafka_scope_rule(:ssl_client_cert_key_password, :ssl_client_cert_key) do |kafka|
|
|
125
|
+
if kafka[:ssl_client_cert_key_password] &&
|
|
126
|
+
kafka[:ssl_client_cert_key].nil?
|
|
127
|
+
key.failure(:ssl_client_cert_key_password_with_ssl_client_cert_key)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
kafka_scope_rule(:sasl_oauth_token_provider) do |kafka|
|
|
132
|
+
if kafka[:sasl_oauth_token_provider] &&
|
|
133
|
+
!kafka[:sasl_oauth_token_provider].respond_to?(:token)
|
|
134
|
+
key.failure(:sasl_oauth_token_provider_respond_to_token)
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
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
|
@@ -17,13 +17,19 @@ Gem::Specification.new do |spec|
|
|
|
17
17
|
spec.license = 'MIT'
|
|
18
18
|
|
|
19
19
|
spec.add_dependency 'delivery_boy', '~> 0.2'
|
|
20
|
-
spec.add_dependency 'dry-configurable', '~> 0.
|
|
21
|
-
spec.add_dependency 'dry-monitor', '~> 0.
|
|
22
|
-
spec.add_dependency 'dry-validation', '~>
|
|
23
|
-
spec.add_dependency '
|
|
20
|
+
spec.add_dependency 'dry-configurable', '~> 0.8'
|
|
21
|
+
spec.add_dependency 'dry-monitor', '~> 0.3'
|
|
22
|
+
spec.add_dependency 'dry-validation', '~> 1.2'
|
|
23
|
+
spec.add_dependency 'ruby-kafka', '>= 0.7.8'
|
|
24
|
+
spec.add_dependency 'zeitwerk', '~> 2.1'
|
|
24
25
|
|
|
25
|
-
spec.required_ruby_version = '>= 2.
|
|
26
|
+
spec.required_ruby_version = '>= 2.5.0'
|
|
26
27
|
|
|
28
|
+
if $PROGRAM_NAME.end_with?('gem')
|
|
29
|
+
spec.signing_key = File.expand_path('~/.ssh/gem-private_key.pem')
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
spec.cert_chain = %w[certs/mensfeld.pem]
|
|
27
33
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec)/}) }
|
|
28
34
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
29
35
|
spec.require_paths = %w[lib]
|
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.1
|
|
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-10-21 00:00:00.000000000 Z
|
|
12
38
|
dependencies:
|
|
13
39
|
- !ruby/object:Gem::Dependency
|
|
14
40
|
name: delivery_boy
|
|
@@ -30,56 +56,70 @@ dependencies:
|
|
|
30
56
|
requirements:
|
|
31
57
|
- - "~>"
|
|
32
58
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '0.
|
|
59
|
+
version: '0.8'
|
|
34
60
|
type: :runtime
|
|
35
61
|
prerelease: false
|
|
36
62
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
63
|
requirements:
|
|
38
64
|
- - "~>"
|
|
39
65
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '0.
|
|
66
|
+
version: '0.8'
|
|
41
67
|
- !ruby/object:Gem::Dependency
|
|
42
68
|
name: dry-monitor
|
|
43
69
|
requirement: !ruby/object:Gem::Requirement
|
|
44
70
|
requirements:
|
|
45
71
|
- - "~>"
|
|
46
72
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: '0.
|
|
73
|
+
version: '0.3'
|
|
48
74
|
type: :runtime
|
|
49
75
|
prerelease: false
|
|
50
76
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
77
|
requirements:
|
|
52
78
|
- - "~>"
|
|
53
79
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: '0.
|
|
80
|
+
version: '0.3'
|
|
55
81
|
- !ruby/object:Gem::Dependency
|
|
56
82
|
name: dry-validation
|
|
57
83
|
requirement: !ruby/object:Gem::Requirement
|
|
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
|
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
|
98
|
+
requirements:
|
|
99
|
+
- - ">="
|
|
100
|
+
- !ruby/object:Gem::Version
|
|
101
|
+
version: 0.7.8
|
|
102
|
+
type: :runtime
|
|
103
|
+
prerelease: false
|
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
105
|
+
requirements:
|
|
106
|
+
- - ">="
|
|
107
|
+
- !ruby/object:Gem::Version
|
|
108
|
+
version: 0.7.8
|
|
109
|
+
- !ruby/object:Gem::Dependency
|
|
110
|
+
name: zeitwerk
|
|
71
111
|
requirement: !ruby/object:Gem::Requirement
|
|
72
112
|
requirements:
|
|
73
113
|
- - "~>"
|
|
74
114
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '
|
|
115
|
+
version: '2.1'
|
|
76
116
|
type: :runtime
|
|
77
117
|
prerelease: false
|
|
78
118
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
119
|
requirements:
|
|
80
120
|
- - "~>"
|
|
81
121
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '
|
|
122
|
+
version: '2.1'
|
|
83
123
|
description: Kafka messaging made easy!
|
|
84
124
|
email:
|
|
85
125
|
- maciej@mensfeld.pl
|
|
@@ -87,6 +127,8 @@ executables: []
|
|
|
87
127
|
extensions: []
|
|
88
128
|
extra_rdoc_files: []
|
|
89
129
|
files:
|
|
130
|
+
- ".coditsu/ci.yml"
|
|
131
|
+
- ".github/FUNDING.yml"
|
|
90
132
|
- ".gitignore"
|
|
91
133
|
- ".rspec"
|
|
92
134
|
- ".ruby-gemset"
|
|
@@ -97,20 +139,23 @@ files:
|
|
|
97
139
|
- Gemfile.lock
|
|
98
140
|
- MIT-LICENCE
|
|
99
141
|
- README.md
|
|
142
|
+
- certs/mensfeld.pem
|
|
100
143
|
- config/errors.yml
|
|
101
144
|
- lib/water_drop.rb
|
|
102
145
|
- lib/water_drop/async_producer.rb
|
|
103
146
|
- lib/water_drop/base_producer.rb
|
|
104
147
|
- lib/water_drop/config.rb
|
|
105
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
|
|
106
152
|
- lib/water_drop/errors.rb
|
|
107
|
-
- lib/water_drop/instrumentation/listener.rb
|
|
108
153
|
- lib/water_drop/instrumentation/monitor.rb
|
|
109
|
-
- lib/water_drop/
|
|
110
|
-
- lib/water_drop/schemas/message_options.rb
|
|
154
|
+
- lib/water_drop/instrumentation/stdout_listener.rb
|
|
111
155
|
- lib/water_drop/sync_producer.rb
|
|
112
156
|
- lib/water_drop/version.rb
|
|
113
157
|
- lib/waterdrop.rb
|
|
158
|
+
- log/.keep
|
|
114
159
|
- waterdrop.gemspec
|
|
115
160
|
homepage: https://github.com/karafka/waterdrop
|
|
116
161
|
licenses:
|
|
@@ -124,15 +169,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
124
169
|
requirements:
|
|
125
170
|
- - ">="
|
|
126
171
|
- !ruby/object:Gem::Version
|
|
127
|
-
version: 2.
|
|
172
|
+
version: 2.5.0
|
|
128
173
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
129
174
|
requirements:
|
|
130
175
|
- - ">="
|
|
131
176
|
- !ruby/object:Gem::Version
|
|
132
177
|
version: '0'
|
|
133
178
|
requirements: []
|
|
134
|
-
|
|
135
|
-
rubygems_version: 2.7.6
|
|
179
|
+
rubygems_version: 3.0.3
|
|
136
180
|
signing_key:
|
|
137
181
|
specification_version: 4
|
|
138
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
|