karafka 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.github/FUNDING.yml +1 -0
- data/.github/workflows/ci.yml +40 -16
- data/.rspec +4 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +459 -796
- data/Gemfile +3 -2
- data/Gemfile.lock +44 -32
- data/LICENSE +1 -1
- data/README.md +22 -17
- data/bin/integrations +86 -26
- data/bin/karafka +1 -13
- data/bin/rspecs +6 -0
- data/bin/verify_license_integrity +37 -0
- data/certs/cert_chain.pem +26 -0
- data/config/{errors.yml → locales/errors.yml} +34 -6
- data/config/locales/pro_errors.yml +34 -0
- data/docker-compose.yml +4 -30
- data/karafka.gemspec +17 -10
- data/lib/active_job/karafka.rb +3 -7
- data/lib/active_job/queue_adapters/karafka_adapter.rb +7 -1
- data/lib/karafka/active_job/consumer.rb +29 -6
- data/lib/karafka/active_job/current_attributes/loading.rb +36 -0
- data/lib/karafka/active_job/current_attributes/persistence.rb +28 -0
- data/lib/karafka/active_job/current_attributes.rb +42 -0
- data/lib/karafka/active_job/dispatcher.rb +34 -3
- data/lib/karafka/active_job/job_options_contract.rb +13 -2
- data/lib/karafka/admin.rb +246 -0
- data/lib/karafka/app.rb +30 -7
- data/lib/karafka/base_consumer.rb +124 -82
- data/lib/karafka/cli/base.rb +20 -0
- data/lib/karafka/cli/console.rb +13 -8
- data/lib/karafka/cli/info.rb +3 -2
- data/lib/karafka/cli/server.rb +55 -8
- data/lib/karafka/cli/topics.rb +146 -0
- data/lib/karafka/connection/client.rb +118 -61
- data/lib/karafka/connection/consumer_group_coordinator.rb +48 -0
- data/lib/karafka/connection/listener.rb +78 -30
- data/lib/karafka/connection/listeners_batch.rb +18 -2
- data/lib/karafka/connection/rebalance_manager.rb +3 -0
- data/lib/karafka/contracts/config.rb +1 -1
- data/lib/karafka/contracts/consumer_group.rb +22 -9
- data/lib/karafka/contracts/server_cli_options.rb +71 -11
- data/lib/karafka/contracts/topic.rb +65 -0
- data/lib/karafka/contracts.rb +1 -1
- data/lib/karafka/embedded.rb +36 -0
- data/lib/karafka/errors.rb +6 -4
- data/lib/karafka/helpers/colorize.rb +6 -0
- data/lib/karafka/instrumentation/callbacks/error.rb +3 -4
- data/lib/karafka/instrumentation/callbacks/statistics.rb +14 -4
- data/lib/karafka/instrumentation/logger_listener.rb +151 -22
- data/lib/karafka/instrumentation/notifications.rb +26 -7
- data/lib/karafka/instrumentation/proctitle_listener.rb +7 -16
- data/lib/karafka/instrumentation/vendors/datadog/dashboard.json +1 -1
- data/lib/karafka/instrumentation/vendors/datadog/logger_listener.rb +153 -0
- data/lib/karafka/instrumentation/vendors/datadog/{listener.rb → metrics_listener.rb} +62 -35
- data/lib/karafka/instrumentation/vendors/kubernetes/liveness_listener.rb +166 -0
- data/lib/karafka/licenser.rb +53 -50
- data/lib/karafka/messages/builders/batch_metadata.rb +8 -8
- data/lib/karafka/messages/builders/messages.rb +6 -2
- data/lib/karafka/messages/message.rb +14 -2
- data/lib/karafka/messages/messages.rb +5 -0
- data/lib/karafka/messages/parser.rb +14 -0
- data/lib/karafka/patches/rdkafka/bindings.rb +132 -0
- data/lib/karafka/pro/active_job/consumer.rb +10 -9
- data/lib/karafka/pro/active_job/dispatcher.rb +28 -3
- data/lib/karafka/pro/active_job/job_options_contract.rb +16 -3
- data/lib/karafka/pro/encryption/cipher.rb +58 -0
- data/lib/karafka/pro/encryption/contracts/config.rb +79 -0
- data/lib/karafka/pro/encryption/errors.rb +24 -0
- data/lib/karafka/pro/encryption/messages/middleware.rb +46 -0
- data/lib/karafka/pro/encryption/messages/parser.rb +56 -0
- data/lib/karafka/pro/encryption/setup/config.rb +48 -0
- data/lib/karafka/pro/encryption.rb +47 -0
- data/lib/karafka/pro/iterator.rb +253 -0
- data/lib/karafka/pro/loader.rb +52 -26
- data/lib/karafka/pro/performance_tracker.rb +10 -6
- data/lib/karafka/pro/processing/collapser.rb +62 -0
- data/lib/karafka/pro/processing/coordinator.rb +92 -16
- data/lib/karafka/pro/processing/filters/base.rb +61 -0
- data/lib/karafka/pro/processing/filters/delayer.rb +70 -0
- data/lib/karafka/pro/processing/filters/expirer.rb +51 -0
- data/lib/karafka/pro/processing/filters/throttler.rb +84 -0
- data/lib/karafka/pro/processing/filters/virtual_limiter.rb +52 -0
- data/lib/karafka/pro/processing/filters_applier.rb +104 -0
- data/lib/karafka/pro/processing/jobs/consume_non_blocking.rb +7 -5
- data/lib/karafka/pro/processing/jobs/revoked_non_blocking.rb +37 -0
- data/lib/karafka/pro/processing/jobs_builder.rb +22 -4
- data/lib/karafka/pro/processing/partitioner.rb +33 -24
- data/lib/karafka/pro/processing/scheduler.rb +27 -8
- data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_lrj_mom.rb +68 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_lrj_mom_vp.rb +74 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_mom.rb +72 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_mom_vp.rb +76 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_lrj_mom.rb +64 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_lrj_mom_vp.rb +68 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_mom.rb +64 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_mom_vp.rb +69 -0
- data/lib/karafka/pro/processing/strategies/aj/ftr_lrj_mom.rb +38 -0
- data/lib/karafka/pro/processing/strategies/aj/ftr_lrj_mom_vp.rb +64 -0
- data/lib/karafka/pro/processing/strategies/aj/ftr_mom.rb +38 -0
- data/lib/karafka/pro/processing/strategies/aj/ftr_mom_vp.rb +58 -0
- data/lib/karafka/pro/processing/strategies/aj/lrj_mom.rb +37 -0
- data/lib/karafka/pro/processing/strategies/aj/lrj_mom_vp.rb +79 -0
- data/lib/karafka/pro/processing/strategies/aj/mom.rb +36 -0
- data/lib/karafka/pro/processing/strategies/aj/mom_vp.rb +52 -0
- data/lib/karafka/pro/processing/strategies/base.rb +26 -0
- data/lib/karafka/pro/processing/strategies/default.rb +105 -0
- data/lib/karafka/pro/processing/strategies/dlq/default.rb +131 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr.rb +61 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj.rb +75 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_mom.rb +71 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_mom_vp.rb +43 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_vp.rb +41 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_mom.rb +69 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_mom_vp.rb +41 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_vp.rb +40 -0
- data/lib/karafka/pro/processing/strategies/dlq/lrj.rb +63 -0
- data/lib/karafka/pro/processing/strategies/dlq/lrj_mom.rb +63 -0
- data/lib/karafka/pro/processing/strategies/dlq/lrj_mom_vp.rb +36 -0
- data/lib/karafka/pro/processing/strategies/dlq/lrj_vp.rb +39 -0
- data/lib/karafka/pro/processing/strategies/dlq/mom.rb +68 -0
- data/lib/karafka/pro/processing/strategies/dlq/mom_vp.rb +37 -0
- data/lib/karafka/pro/processing/strategies/dlq/vp.rb +40 -0
- data/lib/karafka/pro/processing/strategies/ftr/default.rb +104 -0
- data/lib/karafka/pro/processing/strategies/ftr/vp.rb +40 -0
- data/lib/karafka/pro/processing/strategies/lrj/default.rb +87 -0
- data/lib/karafka/pro/processing/strategies/lrj/ftr.rb +69 -0
- data/lib/karafka/pro/processing/strategies/lrj/ftr_mom.rb +67 -0
- data/lib/karafka/pro/processing/strategies/lrj/ftr_mom_vp.rb +40 -0
- data/lib/karafka/pro/processing/strategies/lrj/ftr_vp.rb +39 -0
- data/lib/karafka/pro/processing/strategies/lrj/mom.rb +80 -0
- data/lib/karafka/pro/processing/strategies/lrj/mom_vp.rb +38 -0
- data/lib/karafka/pro/processing/strategies/lrj/vp.rb +36 -0
- data/lib/karafka/pro/processing/strategies/mom/default.rb +46 -0
- data/lib/karafka/pro/processing/strategies/mom/ftr.rb +53 -0
- data/lib/karafka/pro/processing/strategies/mom/ftr_vp.rb +37 -0
- data/lib/karafka/pro/processing/strategies/mom/vp.rb +35 -0
- data/lib/karafka/pro/processing/strategies/vp/default.rb +104 -0
- data/lib/karafka/pro/{contracts/base.rb → processing/strategies.rb} +6 -5
- data/lib/karafka/pro/processing/strategy_selector.rb +84 -0
- data/lib/karafka/pro/processing/virtual_offset_manager.rb +147 -0
- data/lib/karafka/pro/routing/features/base.rb +24 -0
- data/lib/karafka/pro/routing/features/dead_letter_queue/contract.rb +50 -0
- data/lib/karafka/pro/routing/features/dead_letter_queue.rb +27 -0
- data/lib/karafka/pro/routing/{builder_extensions.rb → features/delaying/config.rb} +8 -11
- data/lib/karafka/pro/routing/features/delaying/contract.rb +38 -0
- data/lib/karafka/pro/routing/features/delaying/topic.rb +59 -0
- data/lib/karafka/pro/routing/features/delaying.rb +29 -0
- data/lib/karafka/pro/routing/features/expiring/config.rb +27 -0
- data/lib/karafka/pro/routing/features/expiring/contract.rb +38 -0
- data/lib/karafka/pro/routing/features/expiring/topic.rb +59 -0
- data/lib/karafka/pro/routing/features/expiring.rb +27 -0
- data/lib/karafka/pro/routing/features/filtering/config.rb +40 -0
- data/lib/karafka/pro/routing/features/filtering/contract.rb +41 -0
- data/lib/karafka/pro/routing/features/filtering/topic.rb +51 -0
- data/lib/karafka/pro/routing/features/filtering.rb +27 -0
- data/lib/karafka/pro/routing/features/long_running_job/config.rb +28 -0
- data/lib/karafka/pro/routing/features/long_running_job/contract.rb +37 -0
- data/lib/karafka/pro/routing/features/long_running_job/topic.rb +42 -0
- data/lib/karafka/pro/routing/features/long_running_job.rb +28 -0
- data/lib/karafka/pro/routing/features/throttling/config.rb +32 -0
- data/lib/karafka/pro/routing/features/throttling/contract.rb +41 -0
- data/lib/karafka/pro/routing/features/throttling/topic.rb +69 -0
- data/lib/karafka/pro/routing/features/throttling.rb +30 -0
- data/lib/karafka/pro/routing/features/virtual_partitions/config.rb +30 -0
- data/lib/karafka/pro/routing/features/virtual_partitions/contract.rb +52 -0
- data/lib/karafka/pro/routing/features/virtual_partitions/topic.rb +56 -0
- data/lib/karafka/pro/routing/features/virtual_partitions.rb +27 -0
- data/lib/karafka/process.rb +23 -8
- data/lib/karafka/processing/coordinator.rb +102 -23
- data/lib/karafka/processing/coordinators_buffer.rb +5 -1
- data/lib/karafka/processing/executor.rb +51 -21
- data/lib/karafka/processing/executors_buffer.rb +10 -26
- data/lib/karafka/processing/jobs/base.rb +6 -2
- data/lib/karafka/processing/jobs/consume.rb +8 -5
- data/lib/karafka/processing/jobs/idle.rb +24 -0
- data/lib/karafka/processing/jobs_builder.rb +2 -3
- data/lib/karafka/processing/jobs_queue.rb +14 -8
- data/lib/karafka/processing/partitioner.rb +3 -1
- data/lib/karafka/processing/result.rb +14 -1
- data/lib/karafka/processing/strategies/aj_dlq_mom.rb +44 -0
- data/lib/karafka/processing/strategies/aj_mom.rb +21 -0
- data/lib/karafka/processing/strategies/base.rb +52 -0
- data/lib/karafka/processing/strategies/default.rb +142 -0
- data/lib/karafka/processing/strategies/dlq.rb +88 -0
- data/lib/karafka/processing/strategies/dlq_mom.rb +49 -0
- data/lib/karafka/processing/strategies/mom.rb +29 -0
- data/lib/karafka/processing/strategy_selector.rb +47 -0
- data/lib/karafka/processing/worker.rb +8 -3
- data/lib/karafka/railtie.rb +24 -12
- data/lib/karafka/routing/activity_manager.rb +84 -0
- data/lib/karafka/routing/builder.rb +20 -0
- data/lib/karafka/routing/consumer_group.rb +38 -4
- data/lib/karafka/routing/consumer_mapper.rb +0 -10
- data/lib/karafka/routing/features/active_job/builder.rb +33 -0
- data/lib/karafka/routing/features/active_job/config.rb +15 -0
- data/lib/karafka/routing/features/active_job/contract.rb +41 -0
- data/lib/karafka/routing/features/active_job/topic.rb +33 -0
- data/lib/karafka/routing/features/active_job.rb +13 -0
- data/lib/karafka/routing/features/base/expander.rb +53 -0
- data/lib/karafka/routing/features/base.rb +34 -0
- data/lib/karafka/routing/features/dead_letter_queue/config.rb +19 -0
- data/lib/karafka/routing/features/dead_letter_queue/contract.rb +42 -0
- data/lib/karafka/routing/features/dead_letter_queue/topic.rb +41 -0
- data/lib/karafka/routing/features/dead_letter_queue.rb +16 -0
- data/lib/karafka/routing/features/declaratives/config.rb +18 -0
- data/lib/karafka/routing/features/declaratives/contract.rb +30 -0
- data/lib/karafka/routing/features/declaratives/topic.rb +44 -0
- data/lib/karafka/routing/features/declaratives.rb +14 -0
- data/lib/karafka/routing/features/manual_offset_management/config.rb +15 -0
- data/lib/karafka/routing/features/manual_offset_management/contract.rb +24 -0
- data/lib/karafka/routing/features/manual_offset_management/topic.rb +35 -0
- data/lib/karafka/routing/features/manual_offset_management.rb +18 -0
- data/lib/karafka/routing/proxy.rb +18 -20
- data/lib/karafka/routing/router.rb +27 -2
- data/lib/karafka/routing/subscription_group.rb +43 -5
- data/lib/karafka/routing/subscription_groups_builder.rb +6 -1
- data/lib/karafka/routing/topic.rb +17 -5
- data/lib/karafka/routing/topics.rb +8 -0
- data/lib/karafka/runner.rb +1 -0
- data/lib/karafka/serialization/json/deserializer.rb +1 -0
- data/lib/karafka/server.rb +58 -28
- data/lib/karafka/setup/attributes_map.rb +344 -0
- data/lib/karafka/setup/config.rb +48 -19
- data/lib/karafka/status.rb +35 -7
- data/lib/karafka/templates/karafka.rb.erb +14 -6
- data/lib/karafka/time_trackers/base.rb +1 -6
- data/lib/karafka/time_trackers/pause.rb +49 -19
- data/lib/karafka/time_trackers/poll.rb +7 -3
- data/lib/karafka/version.rb +1 -1
- data/lib/karafka.rb +56 -3
- data/renovate.json +6 -0
- data.tar.gz.sig +0 -0
- metadata +189 -61
- metadata.gz.sig +0 -0
- data/bin/wait_for_kafka +0 -20
- data/certs/mensfeld.pem +0 -25
- data/lib/karafka/active_job/routing/extensions.rb +0 -31
- data/lib/karafka/contracts/consumer_group_topic.rb +0 -42
- data/lib/karafka/instrumentation.rb +0 -21
- data/lib/karafka/pro/base_consumer.rb +0 -82
- data/lib/karafka/pro/contracts/consumer_group.rb +0 -34
- data/lib/karafka/pro/contracts/consumer_group_topic.rb +0 -33
- data/lib/karafka/pro/routing/topic_extensions.rb +0 -38
data/lib/karafka/licenser.rb
CHANGED
|
@@ -8,68 +8,71 @@ module Karafka
|
|
|
8
8
|
|
|
9
9
|
private_constant :PUBLIC_KEY_LOCATION
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
verify(license_config)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
private
|
|
11
|
+
class << self
|
|
12
|
+
# Tries to load the license and yields if successful
|
|
13
|
+
def detect
|
|
14
|
+
# If required, do not require again
|
|
15
|
+
require('karafka-license') unless const_defined?('::Karafka::License')
|
|
20
16
|
|
|
21
|
-
|
|
22
|
-
def prepare(license_config)
|
|
23
|
-
# If there is token, no action needed
|
|
24
|
-
# We support a case where someone would put the token in instead of using one from the
|
|
25
|
-
# license. That's in case there are limitations to using external package sources, etc
|
|
26
|
-
return if license_config.token
|
|
17
|
+
yield
|
|
27
18
|
|
|
28
|
-
|
|
29
|
-
license_config.token || require('karafka-license')
|
|
19
|
+
true
|
|
30
20
|
rescue LoadError
|
|
31
|
-
|
|
21
|
+
false
|
|
32
22
|
end
|
|
33
23
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
# If no license, it will just run LGPL components without anything extra
|
|
41
|
-
return unless license_config.token
|
|
24
|
+
# Tries to prepare license and verifies it
|
|
25
|
+
#
|
|
26
|
+
# @param license_config [Karafka::Core::Configurable::Node] config related to the licensing
|
|
27
|
+
def prepare_and_verify(license_config)
|
|
28
|
+
# If license is not loaded, nothing to do
|
|
29
|
+
return unless const_defined?('::Karafka::License')
|
|
42
30
|
|
|
43
|
-
|
|
31
|
+
prepare(license_config)
|
|
32
|
+
verify(license_config)
|
|
33
|
+
end
|
|
44
34
|
|
|
45
|
-
|
|
46
|
-
formatted_token = license_config.token.strip.delete("\n").delete(' ')
|
|
47
|
-
decoded_token = Base64.decode64(formatted_token)
|
|
35
|
+
private
|
|
48
36
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
data = nil
|
|
37
|
+
# @param license_config [Karafka::Core::Configurable::Node] config related to the licensing
|
|
38
|
+
def prepare(license_config)
|
|
39
|
+
license_config.token = Karafka::License.token
|
|
53
40
|
end
|
|
54
41
|
|
|
55
|
-
|
|
42
|
+
# Check license and setup license details (if needed)
|
|
43
|
+
# @param license_config [Karafka::Core::Configurable::Node] config related to the licensing
|
|
44
|
+
def verify(license_config)
|
|
45
|
+
public_key = OpenSSL::PKey::RSA.new(File.read(PUBLIC_KEY_LOCATION))
|
|
56
46
|
|
|
57
|
-
|
|
58
|
-
|
|
47
|
+
# We gsub and strip in case someone copy-pasted it as a multi line string
|
|
48
|
+
formatted_token = license_config.token.strip.delete("\n").delete(' ')
|
|
49
|
+
decoded_token = Base64.decode64(formatted_token)
|
|
59
50
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
51
|
+
begin
|
|
52
|
+
data = public_key.public_decrypt(decoded_token)
|
|
53
|
+
rescue OpenSSL::OpenSSLError
|
|
54
|
+
data = nil
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
details = data ? JSON.parse(data) : raise_invalid_license_token(license_config)
|
|
58
|
+
|
|
59
|
+
license_config.entity = details.fetch('entity')
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Raises an error with info, that used token is invalid
|
|
63
|
+
# @param license_config [Karafka::Core::Configurable::Node]
|
|
64
|
+
def raise_invalid_license_token(license_config)
|
|
65
|
+
# We set it to false so `Karafka.pro?` method behaves as expected
|
|
66
|
+
license_config.token = false
|
|
67
|
+
|
|
68
|
+
raise(
|
|
69
|
+
Errors::InvalidLicenseTokenError,
|
|
70
|
+
<<~MSG.tr("\n", ' ')
|
|
71
|
+
License key you provided is invalid.
|
|
72
|
+
Please reach us at contact@karafka.io or visit https://karafka.io to obtain a valid one.
|
|
73
|
+
MSG
|
|
74
|
+
)
|
|
75
|
+
end
|
|
73
76
|
end
|
|
74
77
|
end
|
|
75
78
|
end
|
|
@@ -10,27 +10,27 @@ module Karafka
|
|
|
10
10
|
#
|
|
11
11
|
# @param messages [Array<Karafka::Messages::Message>] messages array
|
|
12
12
|
# @param topic [Karafka::Routing::Topic] topic for which we've fetched the batch
|
|
13
|
+
# @param partition [Integer] partition of this metadata
|
|
13
14
|
# @param scheduled_at [Time] moment when the batch was scheduled for processing
|
|
14
15
|
# @return [Karafka::Messages::BatchMetadata] batch metadata object
|
|
15
16
|
#
|
|
16
17
|
# @note We do not set `processed_at` as this needs to be assigned when the batch is
|
|
17
18
|
# picked up for processing.
|
|
18
|
-
def call(messages, topic, scheduled_at)
|
|
19
|
+
def call(messages, topic, partition, scheduled_at)
|
|
19
20
|
Karafka::Messages::BatchMetadata.new(
|
|
20
21
|
size: messages.count,
|
|
21
|
-
first_offset: messages.first
|
|
22
|
-
last_offset: messages.last
|
|
22
|
+
first_offset: messages.first&.offset || -1001,
|
|
23
|
+
last_offset: messages.last&.offset || -1001,
|
|
23
24
|
deserializer: topic.deserializer,
|
|
24
|
-
partition:
|
|
25
|
+
partition: partition,
|
|
25
26
|
topic: topic.name,
|
|
26
27
|
# We go with the assumption that the creation of the whole batch is the last message
|
|
27
28
|
# creation time
|
|
28
|
-
created_at: messages.last
|
|
29
|
+
created_at: messages.last&.timestamp || nil,
|
|
29
30
|
# When this batch was built and scheduled for execution
|
|
30
31
|
scheduled_at: scheduled_at,
|
|
31
|
-
#
|
|
32
|
-
|
|
33
|
-
processed_at: Time.now
|
|
32
|
+
# This needs to be set to a correct value prior to processing starting
|
|
33
|
+
processed_at: nil
|
|
34
34
|
)
|
|
35
35
|
end
|
|
36
36
|
end
|
|
@@ -11,14 +11,18 @@ module Karafka
|
|
|
11
11
|
#
|
|
12
12
|
# @param messages [Array<Karafka::Messages::Message>] karafka messages array
|
|
13
13
|
# @param topic [Karafka::Routing::Topic] topic for which we're received messages
|
|
14
|
+
# @param partition [Integer] partition of those messages
|
|
14
15
|
# @param received_at [Time] moment in time when the messages were received
|
|
15
16
|
# @return [Karafka::Messages::Messages] messages batch object
|
|
16
|
-
def call(messages, topic, received_at)
|
|
17
|
+
def call(messages, topic, partition, received_at)
|
|
18
|
+
# We cannot freeze the batch metadata because it is altered with the processed_at time
|
|
19
|
+
# prior to the consumption. It is being frozen there
|
|
17
20
|
metadata = BatchMetadata.call(
|
|
18
21
|
messages,
|
|
19
22
|
topic,
|
|
23
|
+
partition,
|
|
20
24
|
received_at
|
|
21
|
-
)
|
|
25
|
+
)
|
|
22
26
|
|
|
23
27
|
Karafka::Messages::Messages.new(
|
|
24
28
|
messages,
|
|
@@ -9,7 +9,19 @@ module Karafka
|
|
|
9
9
|
class Message
|
|
10
10
|
extend Forwardable
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
class << self
|
|
13
|
+
# @return [Object] general parser
|
|
14
|
+
# @note We cache it here for performance reasons. It is 2.5x times faster than getting it
|
|
15
|
+
# via the config chain.
|
|
16
|
+
def parser
|
|
17
|
+
@parser ||= App.config.internal.messages.parser
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
attr_reader :metadata
|
|
22
|
+
# raw payload needs to be mutable as we want to have option to change it in the parser
|
|
23
|
+
# prior to the final deserialization
|
|
24
|
+
attr_accessor :raw_payload
|
|
13
25
|
|
|
14
26
|
def_delegators :metadata, *Metadata.members
|
|
15
27
|
|
|
@@ -42,7 +54,7 @@ module Karafka
|
|
|
42
54
|
|
|
43
55
|
# @return [Object] deserialized data
|
|
44
56
|
def deserialize
|
|
45
|
-
|
|
57
|
+
self.class.parser.call(self)
|
|
46
58
|
end
|
|
47
59
|
end
|
|
48
60
|
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Karafka
|
|
4
|
+
module Messages
|
|
5
|
+
# Default message parser. The only thing it does, is calling the deserializer
|
|
6
|
+
class Parser
|
|
7
|
+
# @param message [::Karafka::Messages::Message]
|
|
8
|
+
# @return [Object] deserialized payload
|
|
9
|
+
def call(message)
|
|
10
|
+
message.metadata.deserializer.call(message)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Karafka
|
|
4
|
+
module Patches
|
|
5
|
+
module Rdkafka
|
|
6
|
+
# Binding patches that slightly change how rdkafka operates in certain places
|
|
7
|
+
module Bindings
|
|
8
|
+
include ::Rdkafka::Bindings
|
|
9
|
+
|
|
10
|
+
# Alias internally
|
|
11
|
+
RB = ::Rdkafka::Bindings
|
|
12
|
+
|
|
13
|
+
class << self
|
|
14
|
+
# Handle assignments on cooperative rebalance
|
|
15
|
+
#
|
|
16
|
+
# @param client_ptr [FFI::Pointer]
|
|
17
|
+
# @param code [Integer]
|
|
18
|
+
# @param partitions_ptr [FFI::Pointer]
|
|
19
|
+
def on_cooperative_rebalance(client_ptr, code, partitions_ptr)
|
|
20
|
+
case code
|
|
21
|
+
when RB::RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS
|
|
22
|
+
RB.rd_kafka_incremental_assign(client_ptr, partitions_ptr)
|
|
23
|
+
when RB::RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS
|
|
24
|
+
RB.rd_kafka_commit(client_ptr, nil, false)
|
|
25
|
+
RB.rd_kafka_incremental_unassign(client_ptr, partitions_ptr)
|
|
26
|
+
else
|
|
27
|
+
RB.rd_kafka_assign(client_ptr, FFI::Pointer::NULL)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Handle assignments on a eager rebalance
|
|
32
|
+
#
|
|
33
|
+
# @param client_ptr [FFI::Pointer]
|
|
34
|
+
# @param code [Integer]
|
|
35
|
+
# @param partitions_ptr [FFI::Pointer]
|
|
36
|
+
def on_eager_rebalance(client_ptr, code, partitions_ptr)
|
|
37
|
+
case code
|
|
38
|
+
when RB::RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS
|
|
39
|
+
RB.rd_kafka_assign(client_ptr, partitions_ptr)
|
|
40
|
+
when RB::RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS
|
|
41
|
+
RB.rd_kafka_commit(client_ptr, nil, false)
|
|
42
|
+
RB.rd_kafka_assign(client_ptr, FFI::Pointer::NULL)
|
|
43
|
+
else
|
|
44
|
+
RB.rd_kafka_assign(client_ptr, FFI::Pointer::NULL)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Trigger Karafka callbacks
|
|
49
|
+
#
|
|
50
|
+
# @param code [Integer]
|
|
51
|
+
# @param opaque [Rdkafka::Opaque]
|
|
52
|
+
# @param consumer [Rdkafka::Consumer]
|
|
53
|
+
# @param tpl [Rdkafka::Consumer::TopicPartitionList]
|
|
54
|
+
def trigger_callbacks(code, opaque, consumer, tpl)
|
|
55
|
+
case code
|
|
56
|
+
when RB::RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS
|
|
57
|
+
opaque.call_on_partitions_assigned(consumer, tpl)
|
|
58
|
+
when RB::RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS
|
|
59
|
+
opaque.call_on_partitions_revoked(consumer, tpl)
|
|
60
|
+
end
|
|
61
|
+
rescue StandardError => e
|
|
62
|
+
Karafka.monitor.instrument(
|
|
63
|
+
'error.occurred',
|
|
64
|
+
caller: self,
|
|
65
|
+
error: e,
|
|
66
|
+
type: 'connection.client.rebalance_callback.error'
|
|
67
|
+
)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# This patch changes few things:
|
|
72
|
+
# - it commits offsets (if any) upon partition revocation, so less jobs need to be
|
|
73
|
+
# reprocessed if they are assigned to a different process
|
|
74
|
+
# - reports callback errors into the errors instrumentation instead of the logger
|
|
75
|
+
# - catches only StandardError instead of Exception as we fully control the directly
|
|
76
|
+
# executed callbacks
|
|
77
|
+
#
|
|
78
|
+
# @see https://docs.confluent.io/2.0.0/clients/librdkafka/classRdKafka_1_1RebalanceCb.html
|
|
79
|
+
RebalanceCallback = FFI::Function.new(
|
|
80
|
+
:void, %i[pointer int pointer pointer]
|
|
81
|
+
) do |client_ptr, code, partitions_ptr, opaque_ptr|
|
|
82
|
+
# Patch reference
|
|
83
|
+
pr = ::Karafka::Patches::Rdkafka::Bindings
|
|
84
|
+
|
|
85
|
+
if RB.rd_kafka_rebalance_protocol(client_ptr) == 'COOPERATIVE'
|
|
86
|
+
pr.on_cooperative_rebalance(client_ptr, code, partitions_ptr)
|
|
87
|
+
else
|
|
88
|
+
pr.on_eager_rebalance(client_ptr, code, partitions_ptr)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
opaque = ::Rdkafka::Config.opaques[opaque_ptr.to_i]
|
|
92
|
+
return unless opaque
|
|
93
|
+
|
|
94
|
+
tpl = ::Rdkafka::Consumer::TopicPartitionList.from_native_tpl(partitions_ptr).freeze
|
|
95
|
+
consumer = ::Rdkafka::Consumer.new(client_ptr)
|
|
96
|
+
|
|
97
|
+
pr.trigger_callbacks(code, opaque, consumer, tpl)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# We need to replace the original callback with ours.
|
|
105
|
+
# At the moment there is no API in rdkafka-ruby to do so
|
|
106
|
+
::Rdkafka::Bindings.send(
|
|
107
|
+
:remove_const,
|
|
108
|
+
'RebalanceCallback'
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
::Rdkafka::Bindings.const_set(
|
|
112
|
+
'RebalanceCallback',
|
|
113
|
+
Karafka::Patches::Rdkafka::Bindings::RebalanceCallback
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
::Rdkafka::Bindings.attach_function(
|
|
117
|
+
:rd_kafka_rebalance_protocol,
|
|
118
|
+
%i[pointer],
|
|
119
|
+
:string
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
::Rdkafka::Bindings.attach_function(
|
|
123
|
+
:rd_kafka_incremental_assign,
|
|
124
|
+
%i[pointer pointer],
|
|
125
|
+
:string
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
::Rdkafka::Bindings.attach_function(
|
|
129
|
+
:rd_kafka_incremental_unassign,
|
|
130
|
+
%i[pointer pointer],
|
|
131
|
+
:string
|
|
132
|
+
)
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# This Karafka component is a Pro component.
|
|
3
|
+
# This Karafka component is a Pro component under a commercial license.
|
|
4
|
+
# This Karafka component is NOT licensed under LGPL.
|
|
5
|
+
#
|
|
4
6
|
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
5
7
|
# repository and their usage requires commercial license agreement.
|
|
6
8
|
#
|
|
@@ -20,23 +22,22 @@ module Karafka
|
|
|
20
22
|
#
|
|
21
23
|
# It contains slightly better revocation warranties than the regular blocking consumer as
|
|
22
24
|
# it can stop processing batch of jobs in the middle after the revocation.
|
|
23
|
-
class Consumer < Karafka::
|
|
25
|
+
class Consumer < ::Karafka::ActiveJob::Consumer
|
|
24
26
|
# Runs ActiveJob jobs processing and handles lrj if needed
|
|
25
27
|
def consume
|
|
26
28
|
messages.each do |message|
|
|
27
29
|
# If for any reason we've lost this partition, not worth iterating over new messages
|
|
28
30
|
# as they are no longer ours
|
|
29
31
|
break if revoked?
|
|
30
|
-
break if Karafka::App.stopping?
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
# We cannot early stop when running virtual partitions because the intermediate state
|
|
34
|
+
# would force us not to commit the offsets. This would cause extensive
|
|
35
|
+
# double-processing
|
|
36
|
+
break if Karafka::App.stopping? && !topic.virtual_partitions?
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
# this could create random markings
|
|
38
|
-
next if topic.virtual_partitioner?
|
|
38
|
+
consume_job(message)
|
|
39
39
|
|
|
40
|
+
# We can always mark because of the virtual offset management that we have in VPs
|
|
40
41
|
mark_as_consumed(message)
|
|
41
42
|
end
|
|
42
43
|
end
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# This Karafka component is a Pro component.
|
|
3
|
+
# This Karafka component is a Pro component under a commercial license.
|
|
4
|
+
# This Karafka component is NOT licensed under LGPL.
|
|
5
|
+
#
|
|
4
6
|
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
5
7
|
# repository and their usage requires commercial license agreement.
|
|
6
8
|
#
|
|
@@ -21,6 +23,7 @@ module Karafka
|
|
|
21
23
|
# They can be updated by using `#karafka_options` on the job
|
|
22
24
|
DEFAULTS = {
|
|
23
25
|
dispatch_method: :produce_async,
|
|
26
|
+
dispatch_many_method: :produce_many_async,
|
|
24
27
|
# We don't create a dummy proc based partitioner as we would have to evaluate it with
|
|
25
28
|
# each job.
|
|
26
29
|
partitioner: nil,
|
|
@@ -31,16 +34,38 @@ module Karafka
|
|
|
31
34
|
private_constant :DEFAULTS
|
|
32
35
|
|
|
33
36
|
# @param job [ActiveJob::Base] job
|
|
34
|
-
def
|
|
37
|
+
def dispatch(job)
|
|
35
38
|
::Karafka.producer.public_send(
|
|
36
39
|
fetch_option(job, :dispatch_method, DEFAULTS),
|
|
37
40
|
dispatch_details(job).merge!(
|
|
38
41
|
topic: job.queue_name,
|
|
39
|
-
payload: ::ActiveSupport::JSON.encode(job
|
|
42
|
+
payload: ::ActiveSupport::JSON.encode(serialize_job(job))
|
|
40
43
|
)
|
|
41
44
|
)
|
|
42
45
|
end
|
|
43
46
|
|
|
47
|
+
# Bulk dispatches multiple jobs using the Rails 7.1+ API
|
|
48
|
+
# @param jobs [Array<ActiveJob::Base>] jobs we want to dispatch
|
|
49
|
+
def dispatch_many(jobs)
|
|
50
|
+
dispatches = Hash.new { |hash, key| hash[key] = [] }
|
|
51
|
+
|
|
52
|
+
jobs.each do |job|
|
|
53
|
+
d_method = fetch_option(job, :dispatch_many_method, DEFAULTS)
|
|
54
|
+
|
|
55
|
+
dispatches[d_method] << dispatch_details(job).merge!(
|
|
56
|
+
topic: job.queue_name,
|
|
57
|
+
payload: ::ActiveSupport::JSON.encode(serialize_job(job))
|
|
58
|
+
)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
dispatches.each do |type, messages|
|
|
62
|
+
::Karafka.producer.public_send(
|
|
63
|
+
type,
|
|
64
|
+
messages
|
|
65
|
+
)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
44
69
|
private
|
|
45
70
|
|
|
46
71
|
# @param job [ActiveJob::Base] job instance
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# This Karafka component is a Pro component.
|
|
3
|
+
# This Karafka component is a Pro component under a commercial license.
|
|
4
|
+
# This Karafka component is NOT licensed under LGPL.
|
|
5
|
+
#
|
|
4
6
|
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
5
7
|
# repository and their usage requires commercial license agreement.
|
|
6
8
|
#
|
|
@@ -18,14 +20,25 @@ module Karafka
|
|
|
18
20
|
configure do |config|
|
|
19
21
|
config.error_messages = YAML.safe_load(
|
|
20
22
|
File.read(
|
|
21
|
-
File.join(Karafka.gem_root, 'config', 'errors.yml')
|
|
23
|
+
File.join(Karafka.gem_root, 'config', 'locales', 'errors.yml')
|
|
22
24
|
)
|
|
23
25
|
).fetch('en').fetch('validations').fetch('job_options')
|
|
24
26
|
end
|
|
25
27
|
|
|
26
|
-
optional(:dispatch_method) { |val| %i[produce_async produce_sync].include?(val) }
|
|
27
28
|
optional(:partitioner) { |val| val.respond_to?(:call) }
|
|
28
29
|
optional(:partition_key_type) { |val| %i[key partition_key].include?(val) }
|
|
30
|
+
optional(:dispatch_method) do |val|
|
|
31
|
+
%i[
|
|
32
|
+
produce_async
|
|
33
|
+
produce_sync
|
|
34
|
+
].include?(val)
|
|
35
|
+
end
|
|
36
|
+
optional(:dispatch_many_method) do |val|
|
|
37
|
+
%i[
|
|
38
|
+
produce_many_async
|
|
39
|
+
produce_many_sync
|
|
40
|
+
].include?(val)
|
|
41
|
+
end
|
|
29
42
|
end
|
|
30
43
|
end
|
|
31
44
|
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This Karafka component is a Pro component under a commercial license.
|
|
4
|
+
# This Karafka component is NOT licensed under LGPL.
|
|
5
|
+
#
|
|
6
|
+
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
7
|
+
# repository and their usage requires commercial license agreement.
|
|
8
|
+
#
|
|
9
|
+
# Karafka has also commercial-friendly license, commercial support and commercial components.
|
|
10
|
+
#
|
|
11
|
+
# By sending a pull request to the pro components, you are agreeing to transfer the copyright of
|
|
12
|
+
# your code to Maciej Mensfeld.
|
|
13
|
+
|
|
14
|
+
module Karafka
|
|
15
|
+
module Pro
|
|
16
|
+
module Encryption
|
|
17
|
+
# Cipher for encrypting and decrypting data
|
|
18
|
+
class Cipher
|
|
19
|
+
def initialize
|
|
20
|
+
@private_pems = {}
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Encrypts given string content with the public key
|
|
24
|
+
# @param content [String]
|
|
25
|
+
# @return [String]
|
|
26
|
+
def encrypt(content)
|
|
27
|
+
public_pem.public_encrypt(content)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Decrypts provided content using `version` key
|
|
31
|
+
# @param version [String] encryption version
|
|
32
|
+
# @param content [String] encrypted content
|
|
33
|
+
# @return [String] decrypted content
|
|
34
|
+
def decrypt(version, content)
|
|
35
|
+
private_pem(version).private_decrypt(content)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
# @return [::OpenSSL::PKey::RSA] rsa public key
|
|
41
|
+
def public_pem
|
|
42
|
+
@public_pem ||= ::OpenSSL::PKey::RSA.new(::Karafka::App.config.encryption.public_key)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# @param version [String] version for which we want to get the rsa key
|
|
46
|
+
# @return [::OpenSSL::PKey::RSA] rsa private key
|
|
47
|
+
def private_pem(version)
|
|
48
|
+
return @private_pems[version] if @private_pems.key?(version)
|
|
49
|
+
|
|
50
|
+
key_string = ::Karafka::App.config.encryption.private_keys[version]
|
|
51
|
+
key_string || raise(Errors::PrivateKeyNotFound, version)
|
|
52
|
+
|
|
53
|
+
@private_pems[version] = ::OpenSSL::PKey::RSA.new(key_string)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This Karafka component is a Pro component under a commercial license.
|
|
4
|
+
# This Karafka component is NOT licensed under LGPL.
|
|
5
|
+
#
|
|
6
|
+
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
7
|
+
# repository and their usage requires commercial license agreement.
|
|
8
|
+
#
|
|
9
|
+
# Karafka has also commercial-friendly license, commercial support and commercial components.
|
|
10
|
+
#
|
|
11
|
+
# By sending a pull request to the pro components, you are agreeing to transfer the copyright of
|
|
12
|
+
# your code to Maciej Mensfeld.
|
|
13
|
+
|
|
14
|
+
module Karafka
|
|
15
|
+
module Pro
|
|
16
|
+
module Encryption
|
|
17
|
+
# Encryption related contracts
|
|
18
|
+
module Contracts
|
|
19
|
+
# Makes sure, all the expected config is defined as it should be
|
|
20
|
+
class Config < ::Karafka::Contracts::Base
|
|
21
|
+
configure do |config|
|
|
22
|
+
config.error_messages = YAML.safe_load(
|
|
23
|
+
File.read(
|
|
24
|
+
File.join(Karafka.gem_root, 'config', 'locales', 'pro_errors.yml')
|
|
25
|
+
)
|
|
26
|
+
).fetch('en').fetch('validations').fetch('config')
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
nested(:encryption) do
|
|
30
|
+
required(:active) { |val| [true, false].include?(val) }
|
|
31
|
+
required(:version) { |val| val.is_a?(String) && !val.empty? }
|
|
32
|
+
required(:public_key) { |val| val.is_a?(String) }
|
|
33
|
+
|
|
34
|
+
required(:private_keys) do |val|
|
|
35
|
+
val.is_a?(Hash) &&
|
|
36
|
+
val.keys.all? { |key| key.is_a?(String) } &&
|
|
37
|
+
val.values.all? { |key| key.is_a?(String) }
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Public key validation
|
|
42
|
+
virtual do |data, errors|
|
|
43
|
+
next unless errors.empty?
|
|
44
|
+
next unless data.fetch(:encryption).fetch(:active)
|
|
45
|
+
|
|
46
|
+
key = OpenSSL::PKey::RSA.new(data.fetch(:encryption).fetch(:public_key))
|
|
47
|
+
|
|
48
|
+
next unless key.private?
|
|
49
|
+
|
|
50
|
+
[[%i[encryption public_key], :needs_to_be_public]]
|
|
51
|
+
rescue OpenSSL::PKey::RSAError
|
|
52
|
+
[[%i[encryption public_key], :invalid]]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Private keys validation
|
|
56
|
+
virtual do |data, errors|
|
|
57
|
+
next unless errors.empty?
|
|
58
|
+
next unless data.fetch(:encryption).fetch(:active)
|
|
59
|
+
|
|
60
|
+
private_keys = data.fetch(:encryption).fetch(:private_keys)
|
|
61
|
+
|
|
62
|
+
# Keys may be empty for production only envs
|
|
63
|
+
next if private_keys.empty?
|
|
64
|
+
|
|
65
|
+
keys = private_keys.each_value.map do |key|
|
|
66
|
+
OpenSSL::PKey::RSA.new(key)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
next if keys.all?(&:private?)
|
|
70
|
+
|
|
71
|
+
[[%i[encryption private_keys], :need_to_be_private]]
|
|
72
|
+
rescue OpenSSL::PKey::RSAError
|
|
73
|
+
[[%i[encryption private_keys], :invalid]]
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This Karafka component is a Pro component under a commercial license.
|
|
4
|
+
# This Karafka component is NOT licensed under LGPL.
|
|
5
|
+
#
|
|
6
|
+
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
7
|
+
# repository and their usage requires commercial license agreement.
|
|
8
|
+
#
|
|
9
|
+
# Karafka has also commercial-friendly license, commercial support and commercial components.
|
|
10
|
+
#
|
|
11
|
+
# By sending a pull request to the pro components, you are agreeing to transfer the copyright of
|
|
12
|
+
# your code to Maciej Mensfeld.
|
|
13
|
+
|
|
14
|
+
module Karafka
|
|
15
|
+
module Pro
|
|
16
|
+
module Encryption
|
|
17
|
+
# Encryption related errors
|
|
18
|
+
module Errors
|
|
19
|
+
# Raised when we have encountered encryption key with version we do not have
|
|
20
|
+
PrivateKeyNotFound = Class.new(::Karafka::Errors::BaseError)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|