karafka-web 0.10.1 → 0.10.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +2 -1
- data/CHANGELOG.md +15 -1
- data/Gemfile.lock +13 -11
- data/config/locales/pro_errors.yml +7 -1
- data/docker-compose.yml +1 -1
- data/karafka-web.gemspec +10 -2
- data/lib/karafka/web/pro/commanding/commands/{probe.rb → trace.rb} +3 -3
- data/lib/karafka/web/pro/commanding/listener.rb +1 -1
- data/lib/karafka/web/pro/commanding/manager.rb +2 -2
- data/lib/karafka/web/pro/commanding.rb +1 -1
- data/lib/karafka/web/pro/loader.rb +4 -2
- data/lib/karafka/web/pro/ui/app.rb +47 -2
- data/lib/karafka/web/pro/ui/controllers/commanding_controller.rb +4 -4
- data/lib/karafka/web/pro/ui/controllers/routing_controller.rb +18 -1
- data/lib/karafka/web/pro/ui/controllers/scheduled_messages/base_controller.rb +29 -0
- data/lib/karafka/web/pro/ui/controllers/scheduled_messages/explorer_controller.rb +65 -0
- data/lib/karafka/web/pro/ui/controllers/scheduled_messages/messages_controller.rb +60 -0
- data/lib/karafka/web/pro/ui/controllers/scheduled_messages/schedules_controller.rb +84 -0
- data/lib/karafka/web/pro/ui/lib/branding/config.rb +40 -0
- data/lib/karafka/web/pro/ui/lib/branding/contracts/config.rb +56 -0
- data/lib/karafka/web/pro/ui/lib/branding.rb +36 -0
- data/lib/karafka/web/pro/ui/views/commands/_command.erb +1 -1
- data/lib/karafka/web/pro/ui/views/consumers/_consumer_controls.erb +3 -3
- data/lib/karafka/web/pro/ui/views/consumers/consumer/_commands.erb +4 -4
- data/lib/karafka/web/pro/ui/views/explorer/_partition_option.erb +10 -2
- data/lib/karafka/web/pro/ui/views/recurring_tasks/_actions.erb +2 -2
- data/lib/karafka/web/pro/ui/views/recurring_tasks/_not_active.erb +1 -1
- data/lib/karafka/web/pro/ui/views/routing/_consumer_group.erb +2 -0
- data/lib/karafka/web/pro/ui/views/routing/_topic.erb +10 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/_breadcrumbs.erb +30 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/_key.erb +9 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/_message.erb +122 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/_messages.erb +28 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/partition.erb +72 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/topic.erb +33 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/schedules/_breadcrumbs.erb +21 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/schedules/_no_groups.erb +11 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/schedules/index.erb +38 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/schedules/show.erb +48 -0
- data/lib/karafka/web/pro/ui/views/search/_breadcrumbs.erb +1 -0
- data/lib/karafka/web/pro/ui/views/shared/_navigation.erb +29 -14
- data/lib/karafka/web/pro/ui/views/shared/branding/_label.erb +20 -0
- data/lib/karafka/web/pro/ui/views/shared/branding/_notice.erb +13 -0
- data/lib/karafka/web/tracking/consumers/listeners/errors.rb +3 -1
- data/lib/karafka/web/ui/base.rb +1 -1
- data/lib/karafka/web/ui/controllers/base_controller.rb +18 -3
- data/lib/karafka/web/ui/helpers/application_helper.rb +21 -7
- data/lib/karafka/web/ui/helpers/paths_helper.rb +18 -0
- data/lib/karafka/web/ui/helpers/tailwind_helper.rb +5 -4
- data/lib/karafka/web/ui/models/recurring_tasks/log.rb +0 -11
- data/lib/karafka/web/ui/models/recurring_tasks/schedule.rb +0 -11
- data/lib/karafka/web/ui/models/recurring_tasks/task.rb +0 -11
- data/lib/karafka/web/ui/public/javascripts/application.js +1 -0
- data/lib/karafka/web/ui/public/javascripts/application.min.js +3 -3
- data/lib/karafka/web/ui/public/javascripts/application.min.js.br +0 -0
- data/lib/karafka/web/ui/public/javascripts/application.min.js.gz +0 -0
- data/lib/karafka/web/ui/public/javascripts/components/btn_toggle_manager.js +16 -6
- data/lib/karafka/web/ui/public/javascripts/components/live_poll.js +15 -0
- data/lib/karafka/web/ui/public/stylesheets/application.css +21 -0
- data/lib/karafka/web/ui/public/stylesheets/application.min.css +1 -1
- data/lib/karafka/web/ui/public/stylesheets/application.min.css.br +0 -0
- data/lib/karafka/web/ui/public/stylesheets/application.min.css.gz +0 -0
- data/lib/karafka/web/ui/public/stylesheets/libs/tailwind.css +70 -3
- data/lib/karafka/web/ui/views/layout.erb +5 -2
- data/lib/karafka/web/ui/views/shared/_brand.erb +3 -2
- data/lib/karafka/web/ui/views/shared/_breadcrumbs.erb +1 -1
- data/lib/karafka/web/ui/views/shared/_navigation.erb +28 -14
- data/lib/karafka/web/ui/views/shared/alerts/_error.erb +3 -1
- data/lib/karafka/web/ui/views/shared/alerts/_info.erb +1 -1
- data/lib/karafka/web/ui/views/shared/alerts/_primary.erb +3 -1
- data/lib/karafka/web/ui/views/shared/alerts/_secondary.erb +3 -1
- data/lib/karafka/web/ui/views/shared/alerts/_success.erb +3 -1
- data/lib/karafka/web/ui/views/shared/alerts/_warning.erb +3 -1
- data/lib/karafka/web/ui/views/shared/icons/_calendar.erb +3 -0
- data/lib/karafka/web/ui/views/shared/icons/_chevron.erb +4 -0
- data/lib/karafka/web/version.rb +1 -1
- data/package-lock.json +3 -3
- data.tar.gz.sig +0 -0
- metadata +28 -16
- metadata.gz.sig +0 -0
- data/.coditsu/ci.yml +0 -3
- data/.diffend.yml +0 -3
- data/.github/FUNDING.yml +0 -1
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -50
- data/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
- data/.github/workflows/ci.yml +0 -133
- data/.gitignore +0 -71
- data/.rspec +0 -1
- data/.ruby-gemset +0 -1
- data/.ruby-version +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5790e7352a06e0a780810c40aac53e9b5c878a84990c70b28bdc4d49d3ab921d
|
4
|
+
data.tar.gz: e5ef8e226602ad0388b138b676d705f9dbda06363a0001b2c5e483abab9f2bed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a645ae9fbbe73c045562b38f744e923e3bb4ac7be47f5c49dd664a1b61513ab07706348461ef7858d3c5518a0c70c5f31addf66e146cd76e91579590e7baa268
|
7
|
+
data.tar.gz: 4e5a11cd6d5333b1dff7f95856818cbe14a7a7fa172dc5cbf6d4a1409883b862dc97dc9a4799cf247023e12fdaecbae749e2d44647783af770ce3ca0cd95e51c
|
checksums.yaml.gz.sig
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
|
1
|
+
�Mwi��kT�
|
2
|
+
�͙^�Y� ������$��n��$�"�S����0N���@���e�r�<���xCԟ4&�ݬ#I5����Y��0�Ɓ�
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,20 @@
|
|
1
1
|
# Karafka Web Changelog
|
2
2
|
|
3
|
-
## 0.10.
|
3
|
+
## 0.10.3 (2024-09-17)
|
4
|
+
- **[Feature]** Introduce ability to brand Web UI with environment (Pro).
|
5
|
+
- [Enhancement] Provide assignment status in the routing (Pro).
|
6
|
+
- [Enhancement] Support schedule cancellation via Web UI.
|
7
|
+
- [Enhancement] Rename "probing" to "tracing" to better reflect what this commanding option does.
|
8
|
+
- [Fix] Fix not working primary and secondary alert styles.
|
9
|
+
|
10
|
+
## 0.10.2 (2024-09-03)
|
11
|
+
- **[Feature]** Support Future Messages management (Pro).
|
12
|
+
- [Enhancement] Do not live-reload when form active.
|
13
|
+
- [Fix] Undefined method `deep_merge` for an instance of Hash.
|
14
|
+
- [Fix] Prevent live-polling on elements wrapped in a button.
|
15
|
+
- [Fix] Fix errors extractor failure on first message-less tick / eofed
|
16
|
+
|
17
|
+
## 0.10.1 (2024-08-23)
|
4
18
|
- **[Feature]** Support Recurring Tasks management (Pro).
|
5
19
|
- [Enhancement] Optimize command buttons so they occupy less space.
|
6
20
|
- [Enhancement] Improve tables headers capitalization.
|
data/Gemfile.lock
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
karafka-web (0.10.
|
4
|
+
karafka-web (0.10.3)
|
5
5
|
erubi (~> 1.4)
|
6
|
-
karafka (>= 2.4.
|
6
|
+
karafka (>= 2.4.10, < 2.5.0)
|
7
7
|
karafka-core (>= 2.4.0, < 2.5.0)
|
8
8
|
roda (~> 3.68, >= 3.69)
|
9
9
|
tilt (~> 2.0)
|
@@ -11,20 +11,21 @@ PATH
|
|
11
11
|
GEM
|
12
12
|
remote: https://rubygems.org/
|
13
13
|
specs:
|
14
|
-
activesupport (7.1
|
14
|
+
activesupport (7.2.1)
|
15
15
|
base64
|
16
16
|
bigdecimal
|
17
|
-
concurrent-ruby (~> 1.0, >= 1.
|
17
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
18
18
|
connection_pool (>= 2.2.5)
|
19
19
|
drb
|
20
20
|
i18n (>= 1.6, < 2)
|
21
|
+
logger (>= 1.4.2)
|
21
22
|
minitest (>= 5.1)
|
22
|
-
|
23
|
-
tzinfo (~> 2.0)
|
23
|
+
securerandom (>= 0.3)
|
24
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
24
25
|
base64 (0.2.0)
|
25
26
|
bigdecimal (3.1.8)
|
26
27
|
byebug (11.1.3)
|
27
|
-
concurrent-ruby (1.3.
|
28
|
+
concurrent-ruby (1.3.4)
|
28
29
|
connection_pool (2.4.1)
|
29
30
|
diff-lcs (1.5.1)
|
30
31
|
docile (1.4.0)
|
@@ -32,7 +33,7 @@ GEM
|
|
32
33
|
erubi (1.13.0)
|
33
34
|
et-orbi (1.2.11)
|
34
35
|
tzinfo
|
35
|
-
factory_bot (6.
|
36
|
+
factory_bot (6.5.0)
|
36
37
|
activesupport (>= 5.0.0)
|
37
38
|
ffi (1.17.0)
|
38
39
|
fugit (1.11.1)
|
@@ -40,7 +41,7 @@ GEM
|
|
40
41
|
raabro (~> 1.4)
|
41
42
|
i18n (1.14.5)
|
42
43
|
concurrent-ruby (~> 1.0)
|
43
|
-
karafka (2.4.
|
44
|
+
karafka (2.4.10)
|
44
45
|
base64 (~> 0.2)
|
45
46
|
karafka-core (>= 2.4.3, < 2.5.0)
|
46
47
|
karafka-rdkafka (>= 0.17.2)
|
@@ -52,9 +53,9 @@ GEM
|
|
52
53
|
ffi (~> 1.15)
|
53
54
|
mini_portile2 (~> 2.6)
|
54
55
|
rake (> 12)
|
56
|
+
logger (1.6.1)
|
55
57
|
mini_portile2 (2.8.7)
|
56
|
-
minitest (5.
|
57
|
-
mutex_m (0.2.0)
|
58
|
+
minitest (5.25.1)
|
58
59
|
ostruct (0.6.0)
|
59
60
|
raabro (1.4.0)
|
60
61
|
rack (3.1.4)
|
@@ -79,6 +80,7 @@ GEM
|
|
79
80
|
diff-lcs (>= 1.2.0, < 2.0)
|
80
81
|
rspec-support (~> 3.13.0)
|
81
82
|
rspec-support (3.13.1)
|
83
|
+
securerandom (0.3.1)
|
82
84
|
simplecov (0.22.0)
|
83
85
|
docile (~> 1.1)
|
84
86
|
simplecov-html (~> 0.11)
|
@@ -2,21 +2,27 @@ en:
|
|
2
2
|
validations:
|
3
3
|
config:
|
4
4
|
missing: needs to be present
|
5
|
+
key_must_be_a_symbol: All keys under the kafka settings scope need to be symbols
|
5
6
|
|
6
7
|
commanding.active_format: needs to be either true or false
|
7
8
|
commanding.consumer_group_format: 'needs to be a string with a Kafka accepted format'
|
8
9
|
commanding.max_wait_time_format: needs to be an integer bigger than 0
|
9
10
|
commanding.pause_timeout_format: needs to be an integer bigger than 0
|
10
|
-
key_must_be_a_symbol: All keys under the kafka settings scope need to be symbols
|
11
11
|
commanding.kafka_format: needs to be a filled hash
|
12
|
+
|
12
13
|
ui.search.matchers_must_have_name_and_call: 'must respond to #name and its instance to #call'
|
13
14
|
ui.search.matchers_format: must be an array with matchers
|
14
15
|
ui.search.matchers_name_must_be_valid: all matchers names must be non-empty strings
|
15
16
|
ui.search.limits_format: all limits need to be integers bigger than 0
|
16
17
|
ui.search.timeout_format: must be at least 1 ms
|
18
|
+
|
17
19
|
ui.policies.messages_format: cannot be nil
|
18
20
|
ui.policies.requests_format: cannot be nil
|
19
21
|
|
22
|
+
ui.branding.type_format: 'must be :info, :error, :warning, :success, :primary or :secondary'
|
23
|
+
ui.branding.label_format: must be false or non-empty string
|
24
|
+
ui.branding.notice_format: must be false or non-empty string
|
25
|
+
|
20
26
|
search_form:
|
21
27
|
missing: needs to be present
|
22
28
|
timestamp_key_must_be_large_enough: 'must be a Kafka message timestamp with ms precision'
|
data/docker-compose.yml
CHANGED
data/karafka-web.gemspec
CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.licenses = %w[LGPL-3.0-only Commercial]
|
18
18
|
|
19
19
|
spec.add_dependency 'erubi', '~> 1.4'
|
20
|
-
spec.add_dependency 'karafka', '>= 2.4.
|
20
|
+
spec.add_dependency 'karafka', '>= 2.4.10', '< 2.5.0'
|
21
21
|
spec.add_dependency 'karafka-core', '>= 2.4.0', '< 2.5.0'
|
22
22
|
spec.add_dependency 'roda', '~> 3.68', '>= 3.69'
|
23
23
|
spec.add_dependency 'tilt', '~> 2.0'
|
@@ -31,10 +31,18 @@ Gem::Specification.new do |spec|
|
|
31
31
|
end
|
32
32
|
|
33
33
|
spec.cert_chain = %w[certs/cert.pem]
|
34
|
-
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec)/}) }
|
35
34
|
spec.executables = %w[karafka-web]
|
36
35
|
spec.require_paths = %w[lib]
|
37
36
|
|
37
|
+
spec.files = `git ls-files -z`
|
38
|
+
.split("\x0")
|
39
|
+
.reject { |f| f.match(%r{^(spec)/}) }
|
40
|
+
.reject { |f| f.include?('.github') }
|
41
|
+
.reject { |f| f.start_with?('.') }
|
42
|
+
.reject { |f| f.end_with?('.map') }
|
43
|
+
|
44
|
+
p spec.files.select { |a| a.include?('.map')}
|
45
|
+
|
38
46
|
spec.metadata = {
|
39
47
|
'funding_uri' => 'https://karafka.io/#become-pro',
|
40
48
|
'homepage_uri' => 'https://karafka.io',
|
@@ -19,8 +19,8 @@ module Karafka
|
|
19
19
|
module Commands
|
20
20
|
# Collects all backtraces from the available Ruby threads and publishes their details
|
21
21
|
# back to Kafka for debug.
|
22
|
-
class
|
23
|
-
# Runs
|
22
|
+
class Trace < Base
|
23
|
+
# Runs tracing and publishes result back to Kafka
|
24
24
|
def call
|
25
25
|
threads = {}
|
26
26
|
|
@@ -31,7 +31,7 @@ module Karafka
|
|
31
31
|
t_d[:backtrace] = (thread.backtrace || ['<no backtrace available>']).join("\n")
|
32
32
|
end
|
33
33
|
|
34
|
-
Dispatcher.result(threads, process_id, '
|
34
|
+
Dispatcher.result(threads, process_id, 'trace')
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -16,7 +16,7 @@ module Karafka
|
|
16
16
|
module Pro
|
17
17
|
# Namespace for things related to consumers commanding (management)
|
18
18
|
#
|
19
|
-
# This feature allows for basic of consumers. They can be stopped, moved to quiet or
|
19
|
+
# This feature allows for basic of consumers. They can be stopped, moved to quiet or traced
|
20
20
|
# via the Web UI
|
21
21
|
module Commanding
|
22
22
|
# Wrapper around the Pro Iterator that yields messages with commands when needed for
|
@@ -16,7 +16,7 @@ module Karafka
|
|
16
16
|
module Pro
|
17
17
|
# Namespace for things related to consumers commanding (management)
|
18
18
|
#
|
19
|
-
# This feature allows for basic of consumers. They can be stopped, moved to quiet or
|
19
|
+
# This feature allows for basic of consumers. They can be stopped, moved to quiet or traced
|
20
20
|
# via the Web UI
|
21
21
|
module Commanding
|
22
22
|
class << self
|
@@ -28,8 +28,9 @@ module Karafka
|
|
28
28
|
|
29
29
|
# Expand UI config with extra search capabilities settings
|
30
30
|
config.ui.instance_eval do
|
31
|
-
setting(:
|
31
|
+
setting(:branding, default: Ui::Lib::Branding::Config.config)
|
32
32
|
setting(:policies, default: Ui::Lib::Policies::Config.config)
|
33
|
+
setting(:search, default: Ui::Lib::Search::Config.config)
|
33
34
|
end
|
34
35
|
end
|
35
36
|
|
@@ -38,8 +39,9 @@ module Karafka
|
|
38
39
|
# @param config [Karafka::Core::Configurable::Node]
|
39
40
|
def post_setup_all(config)
|
40
41
|
Commanding.post_setup(config)
|
41
|
-
Ui::Lib::
|
42
|
+
Ui::Lib::Branding.post_setup(config)
|
42
43
|
Ui::Lib::Policies.post_setup(config)
|
44
|
+
Ui::Lib::Search.post_setup(config)
|
43
45
|
end
|
44
46
|
end
|
45
47
|
end
|
@@ -126,8 +126,8 @@ module Karafka
|
|
126
126
|
end
|
127
127
|
|
128
128
|
r.on String do |process_id|
|
129
|
-
r.post '
|
130
|
-
controller.
|
129
|
+
r.post 'trace' do
|
130
|
+
controller.trace(process_id)
|
131
131
|
end
|
132
132
|
|
133
133
|
r.post 'quiet' do
|
@@ -272,6 +272,51 @@ module Karafka
|
|
272
272
|
end
|
273
273
|
end
|
274
274
|
|
275
|
+
r.on 'scheduled_messages' do
|
276
|
+
r.on 'schedules' do
|
277
|
+
controller = Controllers::ScheduledMessages::SchedulesController.new(params)
|
278
|
+
|
279
|
+
r.get String do |topic_id|
|
280
|
+
controller.show(topic_id)
|
281
|
+
end
|
282
|
+
|
283
|
+
r.get do
|
284
|
+
controller.index
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
r.on 'explorer' do
|
289
|
+
controller = Controllers::ScheduledMessages::ExplorerController.new(params)
|
290
|
+
|
291
|
+
r.get String do |topic_id|
|
292
|
+
controller.topic(topic_id)
|
293
|
+
end
|
294
|
+
|
295
|
+
r.get String, Integer do |topic_id, partition_id|
|
296
|
+
controller.partition(topic_id, partition_id)
|
297
|
+
end
|
298
|
+
|
299
|
+
# Jumps to offset matching the expected time
|
300
|
+
r.get String, Integer, Time do |topic_id, partition_id, time|
|
301
|
+
controller.closest(topic_id, partition_id, time)
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
r.on 'messages' do
|
306
|
+
controller = Controllers::ScheduledMessages::MessagesController.new(params)
|
307
|
+
|
308
|
+
r.post(
|
309
|
+
String, Integer, Integer, 'cancel'
|
310
|
+
) do |topic_id, partition_id, message_offset|
|
311
|
+
controller.cancel(topic_id, partition_id, message_offset)
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
r.get do
|
316
|
+
r.redirect root_path('scheduled_messages/schedules')
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
275
320
|
r.on 'health' do
|
276
321
|
controller = Controllers::HealthController.new(params)
|
277
322
|
|
@@ -19,15 +19,15 @@ module Karafka
|
|
19
19
|
# Controller responsible for handling requests that should trigger some action on the
|
20
20
|
# consumers.
|
21
21
|
class CommandingController < BaseController
|
22
|
-
# Dispatches the
|
22
|
+
# Dispatches the trace request to a given process
|
23
23
|
#
|
24
24
|
# @param process_id [String]
|
25
|
-
def
|
26
|
-
command(:
|
25
|
+
def trace(process_id)
|
26
|
+
command(:trace, process_id)
|
27
27
|
|
28
28
|
redirect(
|
29
29
|
:back,
|
30
|
-
success: dispatched_to_one(:
|
30
|
+
success: dispatched_to_one(:trace, process_id)
|
31
31
|
)
|
32
32
|
end
|
33
33
|
|
@@ -28,11 +28,28 @@ module Karafka
|
|
28
28
|
detect_patterns_routes
|
29
29
|
|
30
30
|
@routes = Karafka::App.routes
|
31
|
-
|
32
31
|
@routes.each do |consumer_group|
|
33
32
|
refine(consumer_group.topics)
|
34
33
|
end
|
35
34
|
|
35
|
+
current_state = Models::ConsumersState.current
|
36
|
+
@assigned = Hash.new { |h, k| h[k] = Set.new }
|
37
|
+
|
38
|
+
# If there are active processes, we can use their data to mark certain topics as
|
39
|
+
# assigned. This does not cover the full scope as some partitions may be assigned
|
40
|
+
# and some not, but provides general overview
|
41
|
+
if current_state
|
42
|
+
Models::Processes.active(current_state).each do |process|
|
43
|
+
process.consumer_groups.each do |consumer_group|
|
44
|
+
consumer_group.subscription_groups.each do |subscription_group|
|
45
|
+
subscription_group.topics.each do |topic|
|
46
|
+
@assigned[consumer_group.id.to_s] << topic.name
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
36
53
|
render
|
37
54
|
end
|
38
55
|
|
@@ -0,0 +1,29 @@
|
|
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 Web
|
16
|
+
module Pro
|
17
|
+
module Ui
|
18
|
+
module Controllers
|
19
|
+
# Namespace for all controllers related to scheduled messages
|
20
|
+
module ScheduledMessages
|
21
|
+
# Base Pro controller for scheduled messages
|
22
|
+
class BaseController < Controllers::BaseController
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,65 @@
|
|
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 Web
|
16
|
+
module Pro
|
17
|
+
module Ui
|
18
|
+
module Controllers
|
19
|
+
module ScheduledMessages
|
20
|
+
# Allows for exploration of dispatch messages in a less generic form that via the
|
21
|
+
# explorer as different details are present
|
22
|
+
class ExplorerController < BaseController
|
23
|
+
# Displays aggregated messages from (potentially) all partitions of a topic
|
24
|
+
#
|
25
|
+
# @param topic_id [String]
|
26
|
+
def topic(topic_id)
|
27
|
+
response = Controllers::ExplorerController
|
28
|
+
.new(@params)
|
29
|
+
.topic(topic_id)
|
30
|
+
|
31
|
+
render(attributes: response.attributes)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Shows messages available in a given partition
|
35
|
+
#
|
36
|
+
# @param topic_id [String]
|
37
|
+
# @param partition_id [Integer]
|
38
|
+
def partition(topic_id, partition_id)
|
39
|
+
response = Controllers::ExplorerController
|
40
|
+
.new(@params)
|
41
|
+
.partition(topic_id, partition_id)
|
42
|
+
|
43
|
+
render(attributes: response.attributes)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Finds the closest offset matching the requested time and redirects to this location
|
47
|
+
# Note, that it redirects to closest but always younger.
|
48
|
+
#
|
49
|
+
# @param topic_id [String]
|
50
|
+
# @param partition_id [Integer]
|
51
|
+
# @param time [Time] time of the message
|
52
|
+
def closest(topic_id, partition_id, time)
|
53
|
+
response = Controllers::ExplorerController
|
54
|
+
.new(@params)
|
55
|
+
.closest(topic_id, partition_id, time)
|
56
|
+
|
57
|
+
redirect("scheduled_messages/#{response.path}")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,60 @@
|
|
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 Web
|
16
|
+
module Pro
|
17
|
+
module Ui
|
18
|
+
module Controllers
|
19
|
+
module ScheduledMessages
|
20
|
+
# Provides management of schedules related messages
|
21
|
+
class MessagesController < BaseController
|
22
|
+
# Generates a cancel request for a given schedule message
|
23
|
+
# @param topic_id [String]
|
24
|
+
# @param partition_id [Integer]
|
25
|
+
# @param message_offset [Integer]
|
26
|
+
def cancel(topic_id, partition_id, message_offset)
|
27
|
+
# Fetches the message we want to cancel to get its key
|
28
|
+
scheduled_message = Karafka::Admin.read_topic(
|
29
|
+
topic_id,
|
30
|
+
partition_id,
|
31
|
+
1,
|
32
|
+
message_offset
|
33
|
+
).first
|
34
|
+
|
35
|
+
cancel_message = ::Karafka::Pro::ScheduledMessages.cancel(
|
36
|
+
key: scheduled_message.key,
|
37
|
+
envelope: {
|
38
|
+
topic: topic_id,
|
39
|
+
partition: partition_id
|
40
|
+
}
|
41
|
+
)
|
42
|
+
|
43
|
+
Karafka::Web.producer.produce_sync(cancel_message)
|
44
|
+
|
45
|
+
redirect(
|
46
|
+
:back,
|
47
|
+
success: <<~MESSAGE
|
48
|
+
A scheduled message with offset #{message_offset}
|
49
|
+
from #{topic_id} partition #{partition_id}
|
50
|
+
had a cancel request message successfully created.
|
51
|
+
MESSAGE
|
52
|
+
)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,84 @@
|
|
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 Web
|
16
|
+
module Pro
|
17
|
+
module Ui
|
18
|
+
module Controllers
|
19
|
+
# Namespace for all controllers related to scheduled messages
|
20
|
+
module ScheduledMessages
|
21
|
+
# Controller to display list of schedules (groups) and details about each
|
22
|
+
class SchedulesController < BaseController
|
23
|
+
# Displays list of groups
|
24
|
+
def index
|
25
|
+
topics = Models::Topic.all
|
26
|
+
|
27
|
+
# Names of scheduled messages topics defined in the routing
|
28
|
+
# They may not exist (yet) so we filter them based on the existing topics in the
|
29
|
+
# cluster
|
30
|
+
candidates = Karafka::App
|
31
|
+
.routes
|
32
|
+
.map(&:topics)
|
33
|
+
.map(&:to_a)
|
34
|
+
.flatten
|
35
|
+
.select(&:scheduled_messages?)
|
36
|
+
.reject { |topic| topic.name.end_with?(states_postfix) }
|
37
|
+
.map(&:name)
|
38
|
+
.sort
|
39
|
+
|
40
|
+
@topics = topics.select { |topic| candidates.include?(topic.topic_name) }
|
41
|
+
|
42
|
+
render
|
43
|
+
end
|
44
|
+
|
45
|
+
# Displays all partitions statistics (if any) with number of messages to dispatch
|
46
|
+
# @param schedule_name [String] name of the schedules messages topic
|
47
|
+
def show(schedule_name)
|
48
|
+
@schedule_name = schedule_name
|
49
|
+
@stats_topic_name = "#{schedule_name}#{states_postfix}"
|
50
|
+
@stats_info = Karafka::Admin.topic_info(@stats_topic_name)
|
51
|
+
|
52
|
+
@states = {}
|
53
|
+
@stats_info[:partition_count].times { |i| @states[i] = false }
|
54
|
+
|
55
|
+
Karafka::Pro::Iterator.new({ @stats_topic_name => -1 }).each do |message|
|
56
|
+
@states[message.partition] = message.payload
|
57
|
+
end
|
58
|
+
|
59
|
+
# Sort by partition id
|
60
|
+
@states = @states.sort_by { |key, _| key.to_s }.to_h
|
61
|
+
# Sort daily from closest date
|
62
|
+
@states.each_value do |details|
|
63
|
+
# Skip false predefined values from sorting
|
64
|
+
next unless details
|
65
|
+
|
66
|
+
details[:daily] = details[:daily].sort_by { |key, _| key.to_s }.to_h
|
67
|
+
end
|
68
|
+
|
69
|
+
render
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
# @return [String] states topic postfix
|
75
|
+
def states_postfix
|
76
|
+
@states_postfix ||= Karafka::App.config.scheduled_messages.states_postfix
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,40 @@
|
|
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 Web
|
16
|
+
module Pro
|
17
|
+
module Ui
|
18
|
+
module Lib
|
19
|
+
module Branding
|
20
|
+
# Extra configuration for pro UI branding feature
|
21
|
+
class Config
|
22
|
+
extend ::Karafka::Core::Configurable
|
23
|
+
|
24
|
+
# Type of styling aligned with Daisy. info, error, warning, success, primary
|
25
|
+
setting :type, default: :info
|
26
|
+
|
27
|
+
# String label with env name. Will be displayed below the logo
|
28
|
+
setting :label, default: false
|
29
|
+
|
30
|
+
# Additional wide alert notice to highlight extra details. Nothing if false
|
31
|
+
setting :notice, default: false
|
32
|
+
|
33
|
+
configure
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|