karafka-web 0.10.4 → 0.11.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
- data/CHANGELOG.md +62 -176
- data/Gemfile +4 -0
- data/Gemfile.lock +88 -44
- data/LICENSE +6 -2
- data/Rakefile +4 -0
- data/bin/verify_kafka_warnings +35 -0
- data/bin/verify_topics_naming +35 -0
- data/config/locales/pro_errors.yml +1 -0
- data/config/locales/slogans.yml +1 -1
- data/docker-compose.yml +1 -1
- data/gulpfile.js +0 -2
- data/karafka-web.gemspec +2 -7
- data/lib/karafka/web/config.rb +80 -9
- data/lib/karafka/web/contracts/config.rb +44 -5
- data/lib/karafka/web/errors.rb +10 -12
- data/lib/karafka/web/management/actions/create_initial_states.rb +6 -6
- data/lib/karafka/web/management/actions/create_topics.rb +30 -64
- data/lib/karafka/web/management/actions/delete_topics.rb +5 -5
- data/lib/karafka/web/management/actions/enable.rb +5 -5
- data/lib/karafka/web/pro/commanding/commands/base.rb +37 -13
- data/lib/karafka/web/pro/commanding/commands/consumers/quiet.rb +33 -0
- data/lib/karafka/web/pro/commanding/commands/consumers/stop.rb +32 -0
- data/lib/karafka/web/pro/commanding/commands/consumers/trace.rb +37 -0
- data/lib/karafka/web/pro/commanding/commands/partitions/pause.rb +30 -0
- data/lib/karafka/web/pro/commanding/commands/partitions/resume.rb +30 -0
- data/lib/karafka/web/pro/commanding/commands/partitions/seek.rb +30 -0
- data/lib/karafka/web/pro/commanding/config.rb +6 -10
- data/lib/karafka/web/pro/commanding/contracts/config.rb +2 -10
- data/lib/karafka/web/pro/commanding/dispatcher.rb +45 -24
- data/lib/karafka/web/pro/commanding/handlers/partitions/commands/base.rb +67 -0
- data/lib/karafka/web/pro/commanding/handlers/partitions/commands/pause.rb +44 -0
- data/lib/karafka/web/pro/commanding/handlers/partitions/commands/resume.rb +29 -0
- data/lib/karafka/web/pro/commanding/handlers/partitions/commands/seek.rb +86 -0
- data/lib/karafka/web/pro/commanding/handlers/partitions/executor.rb +56 -0
- data/lib/karafka/web/pro/commanding/handlers/partitions/listener.rb +55 -0
- data/lib/karafka/web/pro/commanding/handlers/partitions/tracker.rb +62 -0
- data/lib/karafka/web/pro/commanding/listener.rb +4 -12
- data/lib/karafka/web/pro/commanding/manager.rb +36 -24
- data/lib/karafka/web/pro/commanding/matcher.rb +7 -17
- data/lib/karafka/web/pro/commanding/request.rb +39 -0
- data/lib/karafka/web/pro/commanding.rb +2 -10
- data/lib/karafka/web/pro/loader.rb +13 -10
- data/lib/karafka/web/pro/ui/app.rb +31 -390
- data/lib/karafka/web/pro/ui/controllers/base_controller.rb +8 -10
- data/lib/karafka/web/pro/ui/controllers/cluster_controller.rb +2 -10
- data/lib/karafka/web/pro/ui/controllers/consumers/base_controller.rb +21 -0
- data/lib/karafka/web/pro/ui/controllers/consumers/commanding_controller.rb +148 -0
- data/lib/karafka/web/pro/ui/controllers/consumers/commands_controller.rb +96 -0
- data/lib/karafka/web/pro/ui/controllers/consumers/consumers_controller.rb +99 -0
- data/lib/karafka/web/pro/ui/controllers/consumers/controls_controller.rb +36 -0
- data/lib/karafka/web/pro/ui/controllers/consumers/jobs_controller.rb +57 -0
- data/lib/karafka/web/pro/ui/controllers/consumers/partitions/base_controller.rb +86 -0
- data/lib/karafka/web/pro/ui/controllers/consumers/partitions/offsets_controller.rb +75 -0
- data/lib/karafka/web/pro/ui/controllers/consumers/partitions/pauses_controller.rb +110 -0
- data/lib/karafka/web/pro/ui/controllers/dashboard_controller.rb +2 -10
- data/lib/karafka/web/pro/ui/controllers/dlq_controller.rb +2 -10
- data/lib/karafka/web/pro/ui/controllers/errors_controller.rb +11 -15
- data/lib/karafka/web/pro/ui/controllers/explorer/base_controller.rb +21 -0
- data/lib/karafka/web/pro/ui/controllers/explorer/explorer_controller.rb +225 -0
- data/lib/karafka/web/pro/ui/controllers/explorer/messages_controller.rb +145 -0
- data/lib/karafka/web/pro/ui/controllers/explorer/search_controller.rb +68 -0
- data/lib/karafka/web/pro/ui/controllers/health_controller.rb +2 -10
- data/lib/karafka/web/pro/ui/controllers/jobs_controller.rb +2 -10
- data/lib/karafka/web/pro/ui/controllers/recurring_tasks_controller.rb +12 -13
- data/lib/karafka/web/pro/ui/controllers/routing_controller.rb +2 -10
- data/lib/karafka/web/pro/ui/controllers/scheduled_messages/base_controller.rb +2 -10
- data/lib/karafka/web/pro/ui/controllers/scheduled_messages/explorer_controller.rb +8 -16
- data/lib/karafka/web/pro/ui/controllers/scheduled_messages/messages_controller.rb +9 -15
- data/lib/karafka/web/pro/ui/controllers/scheduled_messages/schedules_controller.rb +2 -10
- data/lib/karafka/web/pro/ui/controllers/status_controller.rb +2 -10
- data/lib/karafka/web/pro/ui/controllers/support_controller.rb +2 -10
- data/lib/karafka/web/pro/ui/controllers/topics/base_controller.rb +21 -0
- data/lib/karafka/web/pro/ui/controllers/topics/configs_controller.rb +86 -0
- data/lib/karafka/web/pro/ui/controllers/topics/distributions_controller.rb +91 -0
- data/lib/karafka/web/pro/ui/controllers/topics/offsets_controller.rb +55 -0
- data/lib/karafka/web/pro/ui/controllers/topics/replications_controller.rb +37 -0
- data/lib/karafka/web/pro/ui/controllers/topics/topics_controller.rb +101 -0
- data/lib/karafka/web/pro/ui/controllers/ux_controller.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/branding/config.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/branding/contracts/config.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/branding.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/features.rb +53 -0
- data/lib/karafka/web/pro/ui/lib/patterns_detector.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/policies/config.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/policies/contracts/config.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/policies/messages.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/policies/requests.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/policies.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/safe_runner.rb +5 -0
- data/lib/karafka/web/pro/ui/lib/search/config.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/search/contracts/config.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/search/contracts/form.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/search/matchers/base.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/search/matchers/raw_header_includes.rb +10 -11
- data/lib/karafka/web/pro/ui/lib/search/matchers/raw_key_includes.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/search/matchers/raw_payload_includes.rb +23 -11
- data/lib/karafka/web/pro/ui/lib/search/normalizer.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/search/runner.rb +3 -11
- data/lib/karafka/web/pro/ui/lib/search.rb +2 -10
- data/lib/karafka/web/pro/ui/routes/base.rb +19 -0
- data/lib/karafka/web/pro/ui/routes/cluster.rb +37 -0
- data/lib/karafka/web/pro/ui/routes/consumers.rb +145 -0
- data/lib/karafka/web/pro/ui/routes/dashboard.rb +25 -0
- data/lib/karafka/web/pro/ui/routes/dlq.rb +24 -0
- data/lib/karafka/web/pro/ui/routes/errors.rb +39 -0
- data/lib/karafka/web/pro/ui/routes/explorer.rb +118 -0
- data/lib/karafka/web/pro/ui/routes/health.rb +47 -0
- data/lib/karafka/web/pro/ui/routes/jobs.rb +33 -0
- data/lib/karafka/web/pro/ui/routes/recurring_tasks.rb +59 -0
- data/lib/karafka/web/pro/ui/routes/routing.rb +31 -0
- data/lib/karafka/web/pro/ui/routes/scheduled_messages.rb +75 -0
- data/lib/karafka/web/pro/ui/routes/status.rb +24 -0
- data/lib/karafka/web/pro/ui/routes/support.rb +24 -0
- data/lib/karafka/web/pro/ui/routes/topics.rb +90 -0
- data/lib/karafka/web/pro/ui/routes/ux.rb +24 -0
- data/lib/karafka/web/pro/ui/views/cluster/_breadcrumbs.erb +3 -0
- data/lib/karafka/web/pro/ui/views/cluster/_broker.erb +3 -0
- data/lib/karafka/web/pro/ui/views/cluster/_config.erb +3 -0
- data/lib/karafka/web/pro/ui/views/cluster/_tabs.erb +3 -0
- data/lib/karafka/web/pro/ui/views/cluster/index.erb +4 -1
- data/lib/karafka/web/pro/ui/views/cluster/show.erb +3 -0
- data/lib/karafka/web/pro/ui/views/{commands → consumers/commands}/_backtrace.erb +3 -0
- data/lib/karafka/web/pro/ui/views/consumers/commands/_breadcrumbs.erb +24 -0
- data/lib/karafka/web/pro/ui/views/{commands → consumers/commands}/_command.erb +22 -6
- data/lib/karafka/web/pro/ui/views/consumers/commands/_command_details.erb +4 -0
- data/lib/karafka/web/pro/ui/views/consumers/commands/_empty.erb +6 -0
- data/lib/karafka/web/pro/ui/views/{commands → consumers/commands}/_incompatible_schema.erb +3 -0
- data/lib/karafka/web/pro/ui/views/{commands → consumers/commands}/_metadata.erb +4 -1
- data/lib/karafka/web/pro/ui/views/{commands → consumers/commands}/_table.erb +5 -2
- data/lib/karafka/web/pro/ui/views/{commands → consumers/commands}/index.erb +7 -4
- data/lib/karafka/web/pro/ui/views/consumers/commands/show.erb +32 -0
- data/lib/karafka/web/pro/ui/views/consumers/consumers/_breadcrumbs.erb +46 -0
- data/lib/karafka/web/pro/ui/views/consumers/{_consumer.erb → consumers/_consumer.erb} +4 -1
- data/lib/karafka/web/pro/ui/views/consumers/{_consumer_performance.erb → consumers/_consumer_performance.erb} +4 -1
- data/lib/karafka/web/pro/ui/views/consumers/consumers/_tabs.erb +38 -0
- data/lib/karafka/web/pro/ui/views/consumers/consumers/consumer/_commands.erb +80 -0
- data/lib/karafka/web/pro/ui/views/consumers/consumers/consumer/_consumer_group.erb +11 -0
- data/lib/karafka/web/pro/ui/views/consumers/{consumer → consumers/consumer}/_metrics.erb +3 -0
- data/lib/karafka/web/pro/ui/views/consumers/consumers/consumer/_no_subscriptions.erb +10 -0
- data/lib/karafka/web/pro/ui/views/consumers/{consumer → consumers/consumer}/_partition.erb +16 -0
- data/lib/karafka/web/pro/ui/views/consumers/consumers/consumer/_partition_edit_options.erb +33 -0
- data/lib/karafka/web/pro/ui/views/consumers/{consumer → consumers/consumer}/_stopped.erb +3 -0
- data/lib/karafka/web/pro/ui/views/consumers/{consumer → consumers/consumer}/_subscription_group.erb +7 -3
- data/lib/karafka/web/pro/ui/views/consumers/{consumer → consumers/consumer}/_tabs.erb +7 -4
- data/lib/karafka/web/pro/ui/views/consumers/consumers/details.erb +15 -0
- data/lib/karafka/web/pro/ui/views/consumers/{index.erb → consumers/index.erb} +6 -3
- data/lib/karafka/web/pro/ui/views/consumers/{performance.erb → consumers/performance.erb} +6 -3
- data/lib/karafka/web/pro/ui/views/consumers/consumers/subscriptions.erb +24 -0
- data/lib/karafka/web/pro/ui/views/consumers/controls/_breadcrumbs.erb +16 -0
- data/lib/karafka/web/pro/ui/views/consumers/{_consumer_controls.erb → controls/_controls.erb} +10 -7
- data/lib/karafka/web/pro/ui/views/consumers/{controls.erb → controls/index.erb} +8 -5
- data/lib/karafka/web/pro/ui/views/consumers/jobs/_breadcrumbs.erb +36 -0
- data/lib/karafka/web/pro/ui/views/consumers/{consumer → jobs}/_job.erb +4 -2
- data/lib/karafka/web/pro/ui/views/consumers/jobs/_no_jobs.erb +6 -0
- data/lib/karafka/web/pro/ui/views/consumers/{pending_jobs.erb → jobs/pending.erb} +7 -8
- data/lib/karafka/web/pro/ui/views/consumers/{running_jobs.erb → jobs/running.erb} +7 -8
- data/lib/karafka/web/pro/ui/views/consumers/partitions/offsets/_basics.erb +77 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/offsets/_breadcrumbs.erb +58 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/offsets/_form.erb +109 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/offsets/_not_running_error.erb +16 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/offsets/_running_warning.erb +15 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/offsets/edit.erb +16 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/_active_not_editable.erb +22 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/_adjusting_warning.erb +27 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/_breadcrumbs.erb +60 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/_edit_form.erb +59 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/_lrj_not_manageable.erb +24 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/_new_form.erb +78 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/_not_running.erb +16 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/edit.erb +24 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/new.erb +20 -0
- data/lib/karafka/web/pro/ui/views/dashboard/index.erb +4 -1
- data/lib/karafka/web/pro/ui/views/dlq/_breadcrumbs.erb +3 -0
- data/lib/karafka/web/pro/ui/views/dlq/_no_topics.erb +3 -0
- data/lib/karafka/web/pro/ui/views/dlq/_topic.erb +4 -1
- data/lib/karafka/web/pro/ui/views/dlq/index.erb +3 -0
- data/lib/karafka/web/pro/ui/views/errors/_breadcrumbs.erb +4 -6
- data/lib/karafka/web/pro/ui/views/errors/_error.erb +9 -1
- data/lib/karafka/web/pro/ui/views/errors/_partition_option.erb +3 -0
- data/lib/karafka/web/pro/ui/views/errors/_selector.erb +3 -0
- data/lib/karafka/web/pro/ui/views/errors/_table.erb +4 -1
- data/lib/karafka/web/pro/ui/views/errors/index.erb +6 -3
- data/lib/karafka/web/pro/ui/views/errors/partition.erb +5 -2
- data/lib/karafka/web/pro/ui/views/errors/show.erb +42 -33
- data/lib/karafka/web/pro/ui/views/explorer/{_breadcrumbs.erb → explorer/_breadcrumbs.erb} +7 -4
- data/lib/karafka/web/pro/ui/views/explorer/{_failed_deserialization.erb → explorer/_failed_deserialization.erb} +3 -0
- data/lib/karafka/web/pro/ui/views/explorer/{_filtered.erb → explorer/_filtered.erb} +3 -0
- data/lib/karafka/web/pro/ui/views/explorer/{_message.erb → explorer/_message.erb} +4 -1
- data/lib/karafka/web/pro/ui/views/explorer/explorer/_no_topics.erb +4 -0
- data/lib/karafka/web/pro/ui/views/explorer/{_partition_option.erb → explorer/_partition_option.erb} +4 -1
- data/lib/karafka/web/pro/ui/views/explorer/{_selector.erb → explorer/_selector.erb} +4 -1
- data/lib/karafka/web/pro/ui/views/explorer/explorer/_topic.erb +13 -0
- data/lib/karafka/web/pro/ui/views/explorer/explorer/index.erb +17 -0
- data/lib/karafka/web/pro/ui/views/explorer/{message → explorer/message}/_metadata.erb +10 -7
- data/lib/karafka/web/pro/ui/views/explorer/{message → explorer/message}/_payload.erb +6 -3
- data/lib/karafka/web/pro/ui/views/explorer/{message → explorer/message}/_resources_utilization.erb +7 -4
- data/lib/karafka/web/pro/ui/views/explorer/{message → explorer/message}/_too_big_to_be_displayed.erb +3 -0
- data/lib/karafka/web/pro/ui/views/explorer/{messages → explorer/messages}/_detail.erb +3 -0
- data/lib/karafka/web/pro/ui/views/explorer/explorer/messages/_headers.erb +51 -0
- data/lib/karafka/web/pro/ui/views/explorer/{messages → explorer/messages}/_key.erb +3 -0
- data/lib/karafka/web/pro/ui/views/explorer/explorer/partition/_cleaned.erb +6 -0
- data/lib/karafka/web/pro/ui/views/explorer/explorer/partition/_empty.erb +6 -0
- data/lib/karafka/web/pro/ui/views/explorer/{partition → explorer/partition}/_messages.erb +4 -1
- data/lib/karafka/web/pro/ui/views/explorer/explorer/partition/_time_selector.erb +16 -0
- data/lib/karafka/web/pro/ui/views/explorer/explorer/partition/_timestamp_selector.erb +33 -0
- data/lib/karafka/web/pro/ui/views/explorer/{partition.erb → explorer/partition.erb} +24 -17
- data/lib/karafka/web/pro/ui/views/explorer/explorer/show.erb +100 -0
- data/lib/karafka/web/pro/ui/views/explorer/{topic → explorer/topic}/_actions.erb +5 -2
- data/lib/karafka/web/pro/ui/views/explorer/explorer/topic/_empty.erb +6 -0
- data/lib/karafka/web/pro/ui/views/explorer/{topic → explorer/topic}/_limited.erb +3 -0
- data/lib/karafka/web/pro/ui/views/explorer/{topic.erb → explorer/topic.erb} +7 -4
- data/lib/karafka/web/pro/ui/views/explorer/messages/_breadcrumbs.erb +32 -0
- data/lib/karafka/web/pro/ui/views/explorer/messages/forward.erb +143 -0
- data/lib/karafka/web/pro/ui/views/explorer/search/_breadcrumbs.erb +4 -0
- data/lib/karafka/web/pro/ui/views/explorer/search/_fix_errors.erb +6 -0
- data/lib/karafka/web/pro/ui/views/{search → explorer/search}/_metadata.erb +3 -0
- data/lib/karafka/web/pro/ui/views/explorer/search/_no_results.erb +6 -0
- data/lib/karafka/web/pro/ui/views/{search → explorer/search}/_no_search_criteria.erb +3 -0
- data/lib/karafka/web/pro/ui/views/{search → explorer/search}/_search_criteria.erb +3 -0
- data/lib/karafka/web/pro/ui/views/{search → explorer/search}/_search_modal.erb +5 -2
- data/lib/karafka/web/pro/ui/views/explorer/search/_timeout.erb +6 -0
- data/lib/karafka/web/pro/ui/views/explorer/search/index.erb +32 -0
- data/lib/karafka/web/pro/ui/views/health/_breadcrumbs.erb +3 -0
- data/lib/karafka/web/pro/ui/views/health/_no_data.erb +3 -0
- data/lib/karafka/web/pro/ui/views/health/_partition.erb +16 -1
- data/lib/karafka/web/pro/ui/views/health/_partition_lags.erb +3 -0
- data/lib/karafka/web/pro/ui/views/health/_partition_offset.erb +3 -0
- data/lib/karafka/web/pro/ui/views/health/_partition_times.erb +3 -0
- data/lib/karafka/web/pro/ui/views/health/_table_metadata.erb +4 -1
- data/lib/karafka/web/pro/ui/views/health/_tabs.erb +3 -0
- data/lib/karafka/web/pro/ui/views/health/changes.erb +4 -1
- data/lib/karafka/web/pro/ui/views/health/cluster_lags.erb +3 -0
- data/lib/karafka/web/pro/ui/views/health/lags.erb +5 -2
- data/lib/karafka/web/pro/ui/views/health/offsets.erb +4 -1
- data/lib/karafka/web/pro/ui/views/health/overview.erb +8 -3
- data/lib/karafka/web/pro/ui/views/jobs/_job.erb +5 -3
- data/lib/karafka/web/pro/ui/views/jobs/_no_jobs.erb +3 -0
- data/lib/karafka/web/pro/ui/views/jobs/pending.erb +4 -1
- data/lib/karafka/web/pro/ui/views/jobs/running.erb +4 -1
- data/lib/karafka/web/pro/ui/views/recurring_tasks/_actions.erb +3 -0
- data/lib/karafka/web/pro/ui/views/recurring_tasks/_batch_actions.erb +3 -0
- data/lib/karafka/web/pro/ui/views/recurring_tasks/_breadcrumbs.erb +3 -0
- data/lib/karafka/web/pro/ui/views/recurring_tasks/_log.erb +3 -0
- data/lib/karafka/web/pro/ui/views/recurring_tasks/_not_active.erb +3 -0
- data/lib/karafka/web/pro/ui/views/recurring_tasks/_tabs.erb +3 -0
- data/lib/karafka/web/pro/ui/views/recurring_tasks/_task.erb +3 -0
- data/lib/karafka/web/pro/ui/views/recurring_tasks/logs.erb +3 -0
- data/lib/karafka/web/pro/ui/views/recurring_tasks/schedule.erb +3 -0
- data/lib/karafka/web/pro/ui/views/routing/_consumer_group.erb +3 -0
- data/lib/karafka/web/pro/ui/views/routing/_detail.erb +3 -0
- data/lib/karafka/web/pro/ui/views/routing/_topic.erb +3 -0
- data/lib/karafka/web/pro/ui/views/routing/index.erb +3 -0
- data/lib/karafka/web/pro/ui/views/routing/show.erb +3 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/_breadcrumbs.erb +6 -3
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/_key.erb +3 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/_message.erb +28 -115
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/_messages.erb +3 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/message/_cancel.erb +49 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/message/_compacted.erb +16 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/message/_schedule.erb +83 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/message/_tombstone.erb +69 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/message/_unknown.erb +26 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/partition.erb +23 -16
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/topic.erb +6 -3
- data/lib/karafka/web/pro/ui/views/scheduled_messages/schedules/_breadcrumbs.erb +3 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/schedules/_no_groups.erb +3 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/schedules/index.erb +4 -1
- data/lib/karafka/web/pro/ui/views/scheduled_messages/schedules/show.erb +17 -1
- data/lib/karafka/web/pro/ui/views/shared/_navigation.erb +25 -17
- data/lib/karafka/web/pro/ui/views/shared/_rdkafka_form_error_alert_box.erb +16 -0
- data/lib/karafka/web/pro/ui/views/shared/branding/_label.erb +3 -0
- data/lib/karafka/web/pro/ui/views/shared/branding/_notice.erb +3 -0
- data/lib/karafka/web/pro/ui/views/topics/configs/_breadcrumbs.erb +34 -0
- data/lib/karafka/web/pro/ui/views/topics/configs/_config.erb +26 -0
- data/lib/karafka/web/pro/ui/views/topics/configs/_delete_button.erb +13 -0
- data/lib/karafka/web/pro/ui/views/topics/configs/_edit_form.erb +50 -0
- data/lib/karafka/web/pro/ui/views/topics/configs/_edit_plan.erb +16 -0
- data/lib/karafka/web/pro/ui/views/topics/configs/_edit_warning.erb +12 -0
- data/lib/karafka/web/pro/ui/views/topics/configs/edit.erb +16 -0
- data/lib/karafka/web/pro/ui/views/topics/{config.erb → configs/index.erb} +9 -3
- data/lib/karafka/web/pro/ui/views/topics/distributions/_add_partitions_button.erb +13 -0
- data/lib/karafka/web/pro/ui/views/topics/{distribution → distributions}/_badges.erb +3 -0
- data/lib/karafka/web/pro/ui/views/topics/distributions/_breadcrumbs.erb +28 -0
- data/lib/karafka/web/pro/ui/views/topics/{distribution → distributions}/_chart.erb +3 -0
- data/lib/karafka/web/pro/ui/views/topics/distributions/_edit_form.erb +47 -0
- data/lib/karafka/web/pro/ui/views/topics/distributions/_edit_hints.erb +15 -0
- data/lib/karafka/web/pro/ui/views/topics/distributions/_edit_warnings.erb +14 -0
- data/lib/karafka/web/pro/ui/views/topics/distributions/_empty_partitions.erb +4 -0
- data/lib/karafka/web/pro/ui/views/topics/{distribution → distributions}/_limited.erb +3 -0
- data/lib/karafka/web/pro/ui/views/topics/distributions/_partition.erb +13 -0
- data/lib/karafka/web/pro/ui/views/topics/distributions/edit.erb +16 -0
- data/lib/karafka/web/pro/ui/views/topics/{distribution.erb → distributions/show.erb} +11 -7
- data/lib/karafka/web/pro/ui/views/topics/offsets/_breadcrumbs.erb +20 -0
- data/lib/karafka/web/pro/ui/views/topics/offsets/_partition.erb +13 -0
- data/lib/karafka/web/pro/ui/views/topics/{offsets.erb → offsets/show.erb} +6 -3
- data/lib/karafka/web/pro/ui/views/topics/replications/_breadcrumbs.erb +20 -0
- data/lib/karafka/web/pro/ui/views/topics/{_partition.erb → replications/_partition.erb} +4 -1
- data/lib/karafka/web/pro/ui/views/topics/{replication.erb → replications/show.erb} +6 -3
- data/lib/karafka/web/pro/ui/views/topics/topics/_breadcrumbs.erb +32 -0
- data/lib/karafka/web/pro/ui/views/topics/topics/_create_button.erb +13 -0
- data/lib/karafka/web/pro/ui/views/topics/topics/_create_hints.erb +15 -0
- data/lib/karafka/web/pro/ui/views/topics/topics/_delete_form.erb +36 -0
- data/lib/karafka/web/pro/ui/views/topics/topics/_delete_hints.erb +15 -0
- data/lib/karafka/web/pro/ui/views/topics/topics/_delete_warning.erb +13 -0
- data/lib/karafka/web/pro/ui/views/topics/topics/_new_form.erb +80 -0
- data/lib/karafka/web/pro/ui/views/topics/{_tabs.erb → topics/_tabs.erb} +7 -4
- data/lib/karafka/web/pro/ui/views/topics/topics/_topic.erb +12 -0
- data/lib/karafka/web/pro/ui/views/topics/topics/edit.erb +10 -0
- data/lib/karafka/web/pro/ui/views/topics/topics/index.erb +19 -0
- data/lib/karafka/web/pro/ui/views/topics/topics/new.erb +12 -0
- data/lib/karafka/web/processing/consumer.rb +7 -7
- data/lib/karafka/web/processing/consumers/aggregators/state.rb +14 -14
- data/lib/karafka/web/processing/consumers/metrics.rb +1 -1
- data/lib/karafka/web/processing/consumers/state.rb +1 -1
- data/lib/karafka/web/processing/publisher.rb +4 -4
- data/lib/karafka/web/tracking/consumers/contracts/partition.rb +1 -0
- data/lib/karafka/web/tracking/consumers/listeners/errors.rb +1 -0
- data/lib/karafka/web/tracking/consumers/listeners/pausing.rb +2 -2
- data/lib/karafka/web/tracking/consumers/listeners/transactions.rb +44 -0
- data/lib/karafka/web/tracking/consumers/reporter.rb +2 -2
- data/lib/karafka/web/tracking/consumers/sampler.rb +81 -14
- data/lib/karafka/web/tracking/helpers/sysconf.rb +33 -0
- data/lib/karafka/web/tracking/producers/reporter.rb +1 -1
- data/lib/karafka/web/ui/app.rb +19 -112
- data/lib/karafka/web/ui/base.rb +60 -3
- data/lib/karafka/web/ui/controllers/base_controller.rb +43 -1
- data/lib/karafka/web/ui/controllers/cluster_controller.rb +5 -2
- data/lib/karafka/web/ui/controllers/errors_controller.rb +13 -4
- data/lib/karafka/web/ui/controllers/requests/execution_wrapper.rb +52 -0
- data/lib/karafka/web/ui/controllers/requests/hookable.rb +99 -0
- data/lib/karafka/web/ui/controllers/requests/params.rb +39 -1
- data/lib/karafka/web/ui/controllers/responses/redirect.rb +0 -5
- data/lib/karafka/web/ui/controllers/status_controller.rb +3 -0
- data/lib/karafka/web/ui/helpers/application_helper.rb +10 -71
- data/lib/karafka/web/ui/helpers/paths_helper.rb +54 -10
- data/lib/karafka/web/ui/helpers/time_helper.rb +82 -0
- data/lib/karafka/web/ui/helpers/topics_helper.rb +156 -0
- data/lib/karafka/web/ui/lib/admin.rb +1 -1
- data/lib/karafka/web/ui/lib/cache.rb +135 -0
- data/lib/karafka/web/ui/models/broker.rb +1 -2
- data/lib/karafka/web/ui/models/cluster_info.rb +15 -21
- data/lib/karafka/web/ui/models/consumers_metrics.rb +1 -1
- data/lib/karafka/web/ui/models/consumers_state.rb +1 -1
- data/lib/karafka/web/ui/models/counters.rb +1 -1
- data/lib/karafka/web/ui/models/health.rb +9 -7
- data/lib/karafka/web/ui/models/message.rb +20 -2
- data/lib/karafka/web/ui/models/process.rb +16 -0
- data/lib/karafka/web/ui/models/processes.rb +29 -8
- data/lib/karafka/web/ui/models/recurring_tasks/schedule.rb +1 -1
- data/lib/karafka/web/ui/models/status.rb +28 -9
- data/lib/karafka/web/ui/models/topic.rb +1 -2
- data/lib/karafka/web/ui/public/javascripts/application.js +8 -98
- data/lib/karafka/web/ui/public/javascripts/application.min.js +12 -4
- 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/action_confirmation_manager.js +30 -0
- data/lib/karafka/web/ui/public/javascripts/components/alerts.js +39 -0
- data/lib/karafka/web/ui/public/javascripts/components/button_lock_manager.js +50 -0
- data/lib/karafka/web/ui/public/javascripts/components/live_poll.js +71 -19
- data/lib/karafka/web/ui/public/javascripts/components/message_republish_manager.js +50 -0
- data/lib/karafka/web/ui/public/javascripts/components/page_title_tracker.js +21 -0
- data/lib/karafka/web/ui/public/javascripts/components/partition_redirect_manager.js +21 -0
- data/lib/karafka/web/ui/public/javascripts/components/time_ago_manager.js +25 -0
- data/lib/karafka/web/ui/public/javascripts/components/timestamp_selector.js +30 -0
- data/lib/karafka/web/ui/public/javascripts/libs/datepicker.js +2 -2
- data/lib/karafka/web/ui/public/stylesheets/application.css +30 -0
- data/lib/karafka/web/ui/public/stylesheets/application.min.css +5110 -13
- 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/highlight_dark.min.css.gz +0 -0
- data/lib/karafka/web/ui/public/stylesheets/libs/highlight_light.min.css.gz +0 -0
- data/lib/karafka/web/ui/public/stylesheets/libs/tailwind.css +507 -214
- data/lib/karafka/web/ui/routes/assets.rb +53 -0
- data/lib/karafka/web/ui/routes/base.rb +36 -0
- data/lib/karafka/web/ui/routes/cluster.rb +28 -0
- data/lib/karafka/web/ui/routes/consumers.rb +35 -0
- data/lib/karafka/web/ui/routes/dashboard.rb +20 -0
- data/lib/karafka/web/ui/routes/errors.rb +30 -0
- data/lib/karafka/web/ui/routes/jobs.rb +28 -0
- data/lib/karafka/web/ui/routes/pro_only.rb +27 -0
- data/lib/karafka/web/ui/routes/routing.rb +26 -0
- data/lib/karafka/web/ui/routes/status.rb +19 -0
- data/lib/karafka/web/ui/routes/support.rb +19 -0
- data/lib/karafka/web/ui/routes/ux.rb +19 -0
- data/lib/karafka/web/ui/views/cluster/_partition.erb +2 -2
- data/lib/karafka/web/ui/views/cluster/brokers.erb +1 -1
- data/lib/karafka/web/ui/views/consumers/_assignments_badges.erb +2 -7
- data/lib/karafka/web/ui/views/consumers/_breadcrumbs.erb +7 -1
- data/lib/karafka/web/ui/views/consumers/_consumer.erb +1 -1
- data/lib/karafka/web/ui/views/consumers/_no_consumers.erb +2 -2
- data/lib/karafka/web/ui/views/consumers/_tabs.erb +4 -4
- data/lib/karafka/web/ui/views/consumers/index.erb +1 -1
- data/lib/karafka/web/ui/views/dashboard/_feature_pro.erb +1 -1
- data/lib/karafka/web/ui/views/dashboard/_not_enough_data.erb +2 -2
- data/lib/karafka/web/ui/views/dashboard/_ranges_selector.erb +1 -1
- data/lib/karafka/web/ui/views/dashboard/index.erb +6 -49
- data/lib/karafka/web/ui/views/errors/_breadcrumbs.erb +3 -8
- data/lib/karafka/web/ui/views/errors/_detail.erb +3 -3
- data/lib/karafka/web/ui/views/errors/_error.erb +6 -1
- data/lib/karafka/web/ui/views/errors/index.erb +1 -1
- data/lib/karafka/web/ui/views/errors/show.erb +39 -33
- data/lib/karafka/web/ui/views/jobs/_job.erb +2 -3
- data/lib/karafka/web/ui/views/jobs/pending.erb +1 -1
- data/lib/karafka/web/ui/views/jobs/running.erb +1 -1
- data/lib/karafka/web/ui/views/layout.erb +7 -5
- data/lib/karafka/web/ui/views/shared/_become_pro.erb +1 -1
- data/lib/karafka/web/ui/views/shared/_brand.erb +1 -1
- data/lib/karafka/web/ui/views/shared/_breadcrumbs.erb +1 -1
- data/lib/karafka/web/ui/views/shared/_compacted_message_info.erb +16 -0
- data/lib/karafka/web/ui/views/shared/_content.erb +1 -1
- data/lib/karafka/web/ui/views/shared/_controls.erb +10 -3
- data/lib/karafka/web/ui/views/shared/_custom_nav.erb +9 -0
- data/lib/karafka/web/ui/views/shared/_flashes.erb +3 -5
- data/lib/karafka/web/ui/views/shared/_header.erb +25 -2
- data/lib/karafka/web/ui/views/shared/_navigation.erb +17 -15
- data/lib/karafka/web/ui/views/shared/alerts/_error.erb +8 -0
- data/lib/karafka/web/ui/views/shared/alerts/_info.erb +8 -0
- data/lib/karafka/web/ui/views/shared/alerts/_primary.erb +8 -0
- data/lib/karafka/web/ui/views/shared/alerts/_secondary.erb +8 -0
- data/lib/karafka/web/ui/views/shared/alerts/_success.erb +8 -0
- data/lib/karafka/web/ui/views/shared/alerts/_warning.erb +8 -0
- data/lib/karafka/web/ui/views/shared/exceptions/not_allowed.erb +4 -0
- data/lib/karafka/web/ui/views/shared/exceptions/not_found.erb +5 -1
- data/lib/karafka/web/ui/views/shared/exceptions/pro_only.erb +4 -0
- data/lib/karafka/web/ui/views/shared/icons/_arrow_left.erb +3 -0
- data/lib/karafka/web/ui/views/shared/icons/_arrow_up_tray.erb +3 -0
- data/lib/karafka/web/ui/views/shared/icons/_clock.erb +3 -0
- data/lib/karafka/web/ui/views/shared/icons/_pencil.erb +3 -0
- data/lib/karafka/web/ui/views/shared/icons/_pencil_square.erb +3 -0
- data/lib/karafka/web/ui/views/shared/icons/_play_pause.erb +3 -0
- data/lib/karafka/web/ui/views/shared/icons/_plus.erb +3 -0
- data/lib/karafka/web/ui/views/shared/icons/_trash.erb +3 -0
- data/lib/karafka/web/ui/views/status/failures/_live_reporting.erb +1 -1
- data/lib/karafka/web/ui/views/status/failures/_partitions.erb +3 -3
- data/lib/karafka/web/ui/views/status/failures/_state_calculation.erb +2 -2
- data/lib/karafka/web/ui/views/status/info/_components.erb +6 -6
- data/lib/karafka/web/ui/views/status/show.erb +15 -0
- data/lib/karafka/web/ui/views/status/warnings/_consumers_schemas.erb +31 -0
- data/lib/karafka/web/ui/views/ux/_icons.erb +1 -1
- data/lib/karafka/web/version.rb +1 -1
- data/lib/karafka/web.rb +3 -0
- data/package-lock.json +868 -1255
- data/package.json +6 -7
- data/postcss.config.js +1 -2
- data/renovate.json +20 -1
- data/tailwind.config.js +0 -4
- metadata +235 -135
- checksums.yaml.gz.sig +0 -0
- data/certs/cert.pem +0 -26
- data/lib/karafka/web/pro/commanding/commands/quiet.rb +0 -34
- data/lib/karafka/web/pro/commanding/commands/stop.rb +0 -34
- data/lib/karafka/web/pro/commanding/commands/trace.rb +0 -41
- data/lib/karafka/web/pro/ui/controllers/commanding_controller.rb +0 -118
- data/lib/karafka/web/pro/ui/controllers/commands_controller.rb +0 -96
- data/lib/karafka/web/pro/ui/controllers/consumers_controller.rb +0 -138
- data/lib/karafka/web/pro/ui/controllers/explorer_controller.rb +0 -220
- data/lib/karafka/web/pro/ui/controllers/messages_controller.rb +0 -107
- data/lib/karafka/web/pro/ui/controllers/search_controller.rb +0 -73
- data/lib/karafka/web/pro/ui/controllers/topics_controller.rb +0 -130
- data/lib/karafka/web/pro/ui/views/commands/_breadcrumbs.erb +0 -21
- data/lib/karafka/web/pro/ui/views/commands/_command_details.erb +0 -1
- data/lib/karafka/web/pro/ui/views/commands/_empty.erb +0 -3
- data/lib/karafka/web/pro/ui/views/commands/show.erb +0 -33
- data/lib/karafka/web/pro/ui/views/consumers/_breadcrumbs.erb +0 -55
- data/lib/karafka/web/pro/ui/views/consumers/_tabs.erb +0 -33
- data/lib/karafka/web/pro/ui/views/consumers/consumer/_commands.erb +0 -72
- data/lib/karafka/web/pro/ui/views/consumers/consumer/_consumer_group.erb +0 -8
- data/lib/karafka/web/pro/ui/views/consumers/consumer/_no_jobs.erb +0 -7
- data/lib/karafka/web/pro/ui/views/consumers/consumer/_no_subscriptions.erb +0 -7
- data/lib/karafka/web/pro/ui/views/consumers/details.erb +0 -13
- data/lib/karafka/web/pro/ui/views/consumers/subscriptions.erb +0 -25
- data/lib/karafka/web/pro/ui/views/explorer/_no_topics.erb +0 -1
- data/lib/karafka/web/pro/ui/views/explorer/_topic.erb +0 -10
- data/lib/karafka/web/pro/ui/views/explorer/index.erb +0 -14
- data/lib/karafka/web/pro/ui/views/explorer/messages/_headers.erb +0 -33
- data/lib/karafka/web/pro/ui/views/explorer/partition/_cleaned.erb +0 -3
- data/lib/karafka/web/pro/ui/views/explorer/partition/_empty.erb +0 -3
- data/lib/karafka/web/pro/ui/views/explorer/show.erb +0 -97
- data/lib/karafka/web/pro/ui/views/explorer/topic/_empty.erb +0 -3
- data/lib/karafka/web/pro/ui/views/search/_breadcrumbs.erb +0 -1
- data/lib/karafka/web/pro/ui/views/search/_fix_errors.erb +0 -3
- data/lib/karafka/web/pro/ui/views/search/_no_results.erb +0 -3
- data/lib/karafka/web/pro/ui/views/search/_timeout.erb +0 -3
- data/lib/karafka/web/pro/ui/views/search/index.erb +0 -29
- data/lib/karafka/web/pro/ui/views/topics/_breadcrumbs.erb +0 -45
- data/lib/karafka/web/pro/ui/views/topics/_partition_offsets.erb +0 -10
- data/lib/karafka/web/pro/ui/views/topics/_topic.erb +0 -9
- data/lib/karafka/web/pro/ui/views/topics/distribution/_empty_partitions.erb +0 -1
- data/lib/karafka/web/pro/ui/views/topics/distribution/_partition.erb +0 -10
- data/lib/karafka/web/pro/ui/views/topics/index.erb +0 -14
- data/lib/karafka/web/ui/lib/ttl_cache.rb +0 -82
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -0
data/lib/karafka/web/ui/app.rb
CHANGED
@@ -11,122 +11,29 @@ module Karafka
|
|
11
11
|
|
12
12
|
instance_exec(&CONTEXT_DETAILS)
|
13
13
|
|
14
|
+
# Sub-routes for given pieces of the Web UI
|
15
|
+
SUB_ROUTES = [
|
16
|
+
Routes::Assets,
|
17
|
+
Routes::Dashboard,
|
18
|
+
Routes::Consumers,
|
19
|
+
Routes::ProOnly,
|
20
|
+
Routes::Jobs,
|
21
|
+
Routes::Routing,
|
22
|
+
Routes::Cluster,
|
23
|
+
Routes::Errors,
|
24
|
+
Routes::Status,
|
25
|
+
Routes::Support,
|
26
|
+
Routes::Ux
|
27
|
+
].freeze
|
28
|
+
|
29
|
+
private_constant :SUB_ROUTES
|
30
|
+
|
14
31
|
route do |r|
|
15
32
|
r.root { r.redirect root_path('dashboard') }
|
16
33
|
|
17
|
-
|
18
|
-
# after upgrade
|
19
|
-
r.on 'assets', Karafka::Web::VERSION do
|
20
|
-
r.public
|
21
|
-
end
|
22
|
-
|
23
|
-
r.get 'dashboard' do
|
24
|
-
@breadcrumbs = false
|
25
|
-
controller = Controllers::DashboardController.new(params)
|
26
|
-
controller.index
|
27
|
-
end
|
28
|
-
|
29
|
-
r.on 'consumers' do
|
30
|
-
%w[
|
31
|
-
performance
|
32
|
-
controls
|
33
|
-
commands
|
34
|
-
].each do |path|
|
35
|
-
r.get path do |_process_id|
|
36
|
-
raise Errors::Ui::ProOnlyError
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
r.get String, 'subscriptions' do |_process_id|
|
41
|
-
raise Errors::Ui::ProOnlyError
|
42
|
-
end
|
43
|
-
|
44
|
-
r.get do
|
45
|
-
controller = Controllers::ConsumersController.new(params)
|
46
|
-
controller.index
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
%w[
|
51
|
-
health
|
52
|
-
explorer
|
53
|
-
dlq
|
54
|
-
].each do |route|
|
55
|
-
r.get route, [String, true], [String, true] do
|
56
|
-
raise Errors::Ui::ProOnlyError
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
r.on 'jobs' do
|
61
|
-
controller = Controllers::JobsController.new(params)
|
62
|
-
|
63
|
-
r.get 'running' do
|
64
|
-
controller.running
|
65
|
-
end
|
66
|
-
|
67
|
-
r.get 'pending' do
|
68
|
-
controller.pending
|
69
|
-
end
|
70
|
-
|
71
|
-
r.redirect root_path('jobs/running')
|
72
|
-
end
|
73
|
-
|
74
|
-
r.on 'routing' do
|
75
|
-
controller = Controllers::RoutingController.new(params)
|
76
|
-
|
77
|
-
r.get String do |topic_id|
|
78
|
-
controller.show(topic_id)
|
79
|
-
end
|
80
|
-
|
81
|
-
r.get do
|
82
|
-
controller.index
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
r.on 'cluster' do
|
87
|
-
controller = Controllers::ClusterController.new(params)
|
88
|
-
|
89
|
-
r.get 'brokers' do
|
90
|
-
controller.brokers
|
91
|
-
end
|
92
|
-
|
93
|
-
r.get 'replication' do
|
94
|
-
controller.replication
|
95
|
-
end
|
96
|
-
|
97
|
-
r.redirect root_path('cluster/brokers')
|
98
|
-
end
|
99
|
-
|
100
|
-
r.on 'topics' do
|
101
|
-
raise Errors::Ui::ProOnlyError
|
102
|
-
end
|
103
|
-
|
104
|
-
r.on 'errors' do
|
105
|
-
controller = Controllers::ErrorsController.new(params)
|
106
|
-
|
107
|
-
r.get Integer do |offset|
|
108
|
-
controller.show(offset)
|
109
|
-
end
|
110
|
-
|
111
|
-
r.get do
|
112
|
-
controller.index
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
r.get 'status' do
|
117
|
-
controller = Controllers::StatusController.new(params)
|
118
|
-
controller.show
|
119
|
-
end
|
120
|
-
|
121
|
-
r.get 'ux' do
|
122
|
-
controller = Controllers::UxController.new(params)
|
123
|
-
controller.show
|
124
|
-
end
|
34
|
+
SUB_ROUTES.each { |sub_route| sub_route.bind(self, r) }
|
125
35
|
|
126
|
-
|
127
|
-
controller = Controllers::SupportController.new(params)
|
128
|
-
controller.show
|
129
|
-
end
|
36
|
+
nil
|
130
37
|
end
|
131
38
|
end
|
132
39
|
end
|
data/lib/karafka/web/ui/base.rb
CHANGED
@@ -7,6 +7,8 @@ module Karafka
|
|
7
7
|
class Base < Roda
|
8
8
|
include Helpers::PathsHelper
|
9
9
|
include Helpers::ApplicationHelper
|
10
|
+
include Helpers::TimeHelper
|
11
|
+
include Helpers::TopicsHelper
|
10
12
|
include Helpers::TailwindHelper
|
11
13
|
|
12
14
|
# Details that need to be evaluated in the context of OSS or Pro web UI.
|
@@ -40,6 +42,7 @@ module Karafka
|
|
40
42
|
plugin :capture_erb
|
41
43
|
plugin :content_for
|
42
44
|
plugin :inject_erb
|
45
|
+
plugin :all_verbs
|
43
46
|
|
44
47
|
# Based on
|
45
48
|
# https://github.com/sidekiq/sidekiq/blob/ae6ca119/lib/sidekiq/web/application.rb#L8
|
@@ -70,7 +73,16 @@ module Karafka
|
|
70
73
|
# Map redirect flashes (if any) to Roda flash messages
|
71
74
|
result.flashes.each { |key, value| flash[key] = value }
|
72
75
|
|
73
|
-
|
76
|
+
path = case result.path
|
77
|
+
when :back
|
78
|
+
session[:current_path]
|
79
|
+
when :previous
|
80
|
+
session[:previous_path]
|
81
|
+
else
|
82
|
+
root_path(result.path)
|
83
|
+
end
|
84
|
+
|
85
|
+
response.redirect path || root_path
|
74
86
|
end
|
75
87
|
|
76
88
|
handle_block_result Controllers::Responses::File do |result|
|
@@ -109,9 +121,11 @@ module Karafka
|
|
109
121
|
|
110
122
|
before do
|
111
123
|
check_csrf!
|
124
|
+
store_paths_history(request, session)
|
112
125
|
end
|
113
126
|
|
114
127
|
plugin :class_matchers
|
128
|
+
plugin :symbol_matchers
|
115
129
|
|
116
130
|
# Time matcher with optional hours, minutes and seconds
|
117
131
|
TIME_MATCHER = %r{(\d{4}-\d{2}-\d{2}/?(\d{2})?(:\d{2})?(:\d{2})?)}
|
@@ -122,12 +136,22 @@ module Karafka
|
|
122
136
|
# @note In case the date-time is invalid, raise and render 404
|
123
137
|
# @note The time component is optional as `Time#parse` will fallback to lowest time
|
124
138
|
# available, so we can build only date based lookups
|
125
|
-
class_matcher(Time, TIME_MATCHER) do
|
126
|
-
[Time.parse(datetime)]
|
139
|
+
class_matcher(Time, TIME_MATCHER) do |*datetime|
|
140
|
+
[Time.parse(datetime[0])]
|
127
141
|
rescue ArgumentError
|
128
142
|
raise Errors::Ui::NotFoundError
|
129
143
|
end
|
130
144
|
|
145
|
+
# Partitions ids cannot be bigger than 32 bit C int. We use this matcher to ensure we
|
146
|
+
# only support that big partition numbers. Otherwise librdkafka would crash.
|
147
|
+
symbol_matcher :partition_id, /(\d{1,14})/ do |value|
|
148
|
+
int_value = value.to_i
|
149
|
+
|
150
|
+
raise Errors::Ui::NotFoundError unless int_value.between?(0, 2_147_483_647)
|
151
|
+
|
152
|
+
[int_value]
|
153
|
+
end
|
154
|
+
|
131
155
|
# Allows us to build current path with additional params + it merges existing params into
|
132
156
|
# the query data. Query data takes priority over request params.
|
133
157
|
# @param query_data [Hash] query params we want to add to the current path
|
@@ -145,6 +169,14 @@ module Karafka
|
|
145
169
|
[request.path, query_string].compact.join('?')
|
146
170
|
end
|
147
171
|
|
172
|
+
# Builds a consumer instance with all needed details
|
173
|
+
# @param consumer_class [Class]
|
174
|
+
def build(consumer_class)
|
175
|
+
Controllers::Requests::ExecutionWrapper.new(
|
176
|
+
consumer_class.new(params, session)
|
177
|
+
)
|
178
|
+
end
|
179
|
+
|
148
180
|
# Sets appropriate template variables based on the response object and renders the
|
149
181
|
# expected view
|
150
182
|
# @param response [Karafka::Web::Ui::Controllers::Responses::Data] response data object
|
@@ -162,6 +194,31 @@ module Karafka
|
|
162
194
|
def params
|
163
195
|
Controllers::Requests::Params.new(request.params)
|
164
196
|
end
|
197
|
+
|
198
|
+
private
|
199
|
+
|
200
|
+
# Stores history about visited paths. Useful for redirecting users back when needed.
|
201
|
+
# @param request [Karafka::Web::Ui::App::RodaRequest]
|
202
|
+
# @param session [Object] session object (Rails or Rack)
|
203
|
+
def store_paths_history(request, session)
|
204
|
+
# Code below tracks previous paths so we can use it to redirect users back
|
205
|
+
return unless request.get?
|
206
|
+
return unless request.env['HTTP_ACCEPT']&.include?('text/html')
|
207
|
+
|
208
|
+
requested_path = request.path
|
209
|
+
|
210
|
+
if session[:current_path].nil?
|
211
|
+
session[:current_path] = requested_path
|
212
|
+
|
213
|
+
return
|
214
|
+
end
|
215
|
+
|
216
|
+
return if request.path == session[:current_path]
|
217
|
+
|
218
|
+
# When navigating to a different page
|
219
|
+
session[:previous_path] = session[:current_path]
|
220
|
+
session[:current_path] = requested_path
|
221
|
+
end
|
165
222
|
end
|
166
223
|
end
|
167
224
|
end
|
@@ -8,6 +8,9 @@ module Karafka
|
|
8
8
|
# Base controller from which all the controllers should inherit.
|
9
9
|
class BaseController
|
10
10
|
include Web::Ui::Lib::Paginations
|
11
|
+
include Requests::Hookable
|
12
|
+
|
13
|
+
attr_reader :params, :session
|
11
14
|
|
12
15
|
# Alias for easier referencing
|
13
16
|
Models = Web::Ui::Models
|
@@ -19,9 +22,31 @@ module Karafka
|
|
19
22
|
|
20
23
|
self.sortable_attributes = []
|
21
24
|
|
25
|
+
# Detect that the state of the cache has changed
|
26
|
+
before do
|
27
|
+
cache.clear_if_needed(
|
28
|
+
session[:cache_hash],
|
29
|
+
session[:cache_timestamp].to_i
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
after do
|
34
|
+
next unless cache.exist?
|
35
|
+
|
36
|
+
session[:cache_hash] = cache.hash
|
37
|
+
session[:cache_timestamp] = cache.timestamp.to_i
|
38
|
+
end
|
39
|
+
|
22
40
|
# @param params [Karafka::Web::Ui::Controllers::Requests::Params] request parameters
|
23
|
-
|
41
|
+
# @param session [Request::Session] request session (Rails or other framework)
|
42
|
+
def initialize(params, session)
|
24
43
|
@params = params
|
44
|
+
@session = session
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [Karafka::Web::Ui::Lib::Cache] per-process cache instance
|
48
|
+
def cache
|
49
|
+
Karafka::Web.config.ui.cache
|
25
50
|
end
|
26
51
|
|
27
52
|
private
|
@@ -50,6 +75,9 @@ module Karafka
|
|
50
75
|
|
51
76
|
attributes[:breadcrums_scope] = scope
|
52
77
|
|
78
|
+
@current_action_name = action.to_sym
|
79
|
+
@current_controller_name = base.join('-')
|
80
|
+
|
53
81
|
instance_variables.each do |iv|
|
54
82
|
next if iv.to_s.start_with?('@_')
|
55
83
|
next if iv.to_s.start_with?('@params')
|
@@ -72,6 +100,20 @@ module Karafka
|
|
72
100
|
Responses::Redirect.new(path, flashes)
|
73
101
|
end
|
74
102
|
|
103
|
+
# Wraps the provided arguments inside a message with a `<strong>` tag to simplify flash
|
104
|
+
# messages building.
|
105
|
+
#
|
106
|
+
# @param message [String] message with `?` to be replaced.
|
107
|
+
# @param args [Array<Object>] arguments to use to replace `?` with strong
|
108
|
+
# @return [String] formatted string
|
109
|
+
def format_flash(message, *args)
|
110
|
+
args.each do |arg|
|
111
|
+
message = message.sub('?', "<strong>#{arg}</strong>")
|
112
|
+
end
|
113
|
+
|
114
|
+
message
|
115
|
+
end
|
116
|
+
|
75
117
|
# Builds a file response object that will be used as a base to dispatch the file
|
76
118
|
#
|
77
119
|
# @param content [String] Payload we want to dispatch as a file
|
@@ -17,6 +17,9 @@ module Karafka
|
|
17
17
|
in_sync_replica_brokers
|
18
18
|
].freeze
|
19
19
|
|
20
|
+
# Cluster state should always be fresh and not from cache
|
21
|
+
before { cache.clear }
|
22
|
+
|
20
23
|
# Lists available brokers in the cluster
|
21
24
|
def brokers
|
22
25
|
@brokers = refine(cluster_info.brokers)
|
@@ -50,9 +53,9 @@ module Karafka
|
|
50
53
|
|
51
54
|
private
|
52
55
|
|
53
|
-
#
|
56
|
+
# @return [Array] whole cluster info
|
54
57
|
def cluster_info
|
55
|
-
@cluster_info ||= Models::ClusterInfo.fetch
|
58
|
+
@cluster_info ||= Models::ClusterInfo.fetch
|
56
59
|
end
|
57
60
|
|
58
61
|
# @param cluster_info [Rdkafka::Metadata] cluster metadata
|
@@ -17,7 +17,8 @@ module Karafka
|
|
17
17
|
previous_offset,
|
18
18
|
@params.current_offset,
|
19
19
|
next_offset,
|
20
|
-
|
20
|
+
# If message is an array, it means it's a compacted dummy offset representation
|
21
|
+
@error_messages.map { |message| message.is_a?(Array) ? message.last : message.offset }
|
21
22
|
)
|
22
23
|
|
23
24
|
render
|
@@ -25,12 +26,20 @@ module Karafka
|
|
25
26
|
|
26
27
|
# @param offset [Integer] given error message offset
|
27
28
|
def show(offset)
|
29
|
+
@partition_id = 0
|
30
|
+
@offset = offset
|
31
|
+
|
32
|
+
watermark_offsets = Models::WatermarkOffsets.find(errors_topic, @partition_id)
|
33
|
+
|
28
34
|
@error_message = Models::Message.find(
|
29
35
|
errors_topic,
|
30
|
-
|
31
|
-
offset
|
36
|
+
@partition_id,
|
37
|
+
offset,
|
38
|
+
watermark_offsets: watermark_offsets
|
32
39
|
)
|
33
40
|
|
41
|
+
paginate(offset, watermark_offsets.low, watermark_offsets.high)
|
42
|
+
|
34
43
|
render
|
35
44
|
end
|
36
45
|
|
@@ -49,7 +58,7 @@ module Karafka
|
|
49
58
|
|
50
59
|
# @return [String] errors topic
|
51
60
|
def errors_topic
|
52
|
-
::Karafka::Web.config.topics.errors
|
61
|
+
::Karafka::Web.config.topics.errors.name
|
53
62
|
end
|
54
63
|
end
|
55
64
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Karafka
|
4
|
+
module Web
|
5
|
+
module Ui
|
6
|
+
module Controllers
|
7
|
+
module Requests
|
8
|
+
# @note This class is used internally by the Web UI to wrap controllers
|
9
|
+
# and inject execution hooks around any method call (before/after filters).
|
10
|
+
#
|
11
|
+
# ExecutionWrapper delegates all method calls to the provided controller instance.
|
12
|
+
# Before and after each invocation, it runs the controller's registered hooks.
|
13
|
+
#
|
14
|
+
# This allows for cleaner separation of concerns and reusable hook logic.
|
15
|
+
#
|
16
|
+
# @example
|
17
|
+
# controller = SomeController.new
|
18
|
+
# wrapper = ExecutionWrapper.new(controller)
|
19
|
+
# wrapper.call # will run before(:call), call, then after(:call)
|
20
|
+
class ExecutionWrapper
|
21
|
+
# @param controller [Object] a controller instance responding to method calls
|
22
|
+
def initialize(controller)
|
23
|
+
@controller = controller
|
24
|
+
end
|
25
|
+
|
26
|
+
# Delegates any method call to the controller and wraps it with before/after hooks
|
27
|
+
#
|
28
|
+
# @param method_name [Symbol] the name of the method being called
|
29
|
+
# @param args [Array] arguments passed to the method
|
30
|
+
# @param block [Proc] optional block passed to the method
|
31
|
+
# @return [Object] the result of the delegated controller method for Roda to operate on
|
32
|
+
def method_missing(method_name, *args, &block)
|
33
|
+
@controller.run_before_hooks(method_name)
|
34
|
+
result = @controller.public_send(method_name, *args, &block)
|
35
|
+
@controller.run_after_hooks(method_name)
|
36
|
+
result
|
37
|
+
end
|
38
|
+
|
39
|
+
# Properly supports respond_to? checks by delegating to the controller
|
40
|
+
#
|
41
|
+
# @param method_name [Symbol] the method name to check
|
42
|
+
# @param include_private [Boolean] whether to include private methods
|
43
|
+
# @return [Boolean] true if controller responds to the method
|
44
|
+
def respond_to_missing?(method_name, include_private = false)
|
45
|
+
@controller.respond_to?(method_name, include_private)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Karafka
|
4
|
+
module Web
|
5
|
+
module Ui
|
6
|
+
module Controllers
|
7
|
+
module Requests
|
8
|
+
# Adds before/after hook support for controller methods.
|
9
|
+
#
|
10
|
+
# This module allows registering callbacks that run before and after
|
11
|
+
# any named method (e.g., `call`, `show`) or for all methods.
|
12
|
+
#
|
13
|
+
# Hooks are inherited from parent controllers, making it easy to
|
14
|
+
# define shared behavior across a hierarchy.
|
15
|
+
#
|
16
|
+
# @example Adding hooks to a controller
|
17
|
+
# class MyController
|
18
|
+
# include Hookable
|
19
|
+
#
|
20
|
+
# before(:call) { puts "before call" }
|
21
|
+
# after(:call) { puts "after call" }
|
22
|
+
#
|
23
|
+
# def call
|
24
|
+
# run_before_hooks(:call)
|
25
|
+
# # actual logic
|
26
|
+
# run_after_hooks(:call)
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
module Hookable
|
30
|
+
# Hook into class inclusion to extend DSL
|
31
|
+
#
|
32
|
+
# @param base [Class] the class including this module
|
33
|
+
def self.included(base)
|
34
|
+
base.extend(ClassMethods)
|
35
|
+
end
|
36
|
+
|
37
|
+
# DSL methods for defining and inheriting hooks
|
38
|
+
module ClassMethods
|
39
|
+
# Inherit parent hooks into subclass
|
40
|
+
#
|
41
|
+
# @param subclass [Class] the subclass inheriting from base controller
|
42
|
+
def inherited(subclass)
|
43
|
+
super
|
44
|
+
subclass.before_hooks.concat(before_hooks)
|
45
|
+
subclass.after_hooks.concat(after_hooks)
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [Array] accumulated before hooks
|
49
|
+
def before_hooks
|
50
|
+
@before_hooks ||= []
|
51
|
+
end
|
52
|
+
|
53
|
+
# @return [Array] accumulated after hooks
|
54
|
+
def after_hooks
|
55
|
+
@after_hooks ||= []
|
56
|
+
end
|
57
|
+
|
58
|
+
# Register a before hook
|
59
|
+
#
|
60
|
+
# @param actions [Array<Symbol>] optional action names to match (e.g., :call)
|
61
|
+
# @param block [Proc]
|
62
|
+
# @yield a block to execute before matched actions
|
63
|
+
def before(*actions, &block)
|
64
|
+
before_hooks << [actions, block]
|
65
|
+
end
|
66
|
+
|
67
|
+
# Register an after hook
|
68
|
+
#
|
69
|
+
# @param actions [Array<Symbol>] optional action names to match (e.g., :call)
|
70
|
+
# @param block [Proc]
|
71
|
+
# @yield a block to execute after matched actions
|
72
|
+
def after(*actions, &block)
|
73
|
+
after_hooks << [actions, block]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Run all before hooks matching the action
|
78
|
+
#
|
79
|
+
# @param action_name [Symbol] the method name being invoked
|
80
|
+
def run_before_hooks(action_name)
|
81
|
+
self.class.before_hooks.each do |actions, block|
|
82
|
+
instance_exec(&block) if actions.empty? || actions.include?(action_name)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Run all after hooks matching the action
|
87
|
+
#
|
88
|
+
# @param action_name [Symbol] the method name being invoked
|
89
|
+
def run_after_hooks(action_name)
|
90
|
+
self.class.after_hooks.each do |actions, block|
|
91
|
+
instance_exec(&block) if actions.empty? || actions.include?(action_name)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -17,13 +17,51 @@ module Karafka
|
|
17
17
|
days
|
18
18
|
].freeze
|
19
19
|
|
20
|
-
|
20
|
+
# What string values true can be in params
|
21
|
+
ALLOWED_BOOLEAN_TRUE = %w[
|
22
|
+
on
|
23
|
+
yes
|
24
|
+
true
|
25
|
+
].freeze
|
26
|
+
|
27
|
+
private_constant :ALLOWED_RANGES, :ALLOWED_BOOLEAN_TRUE
|
21
28
|
|
22
29
|
# @param request_params [Hash] raw hash with params
|
23
30
|
def initialize(request_params)
|
24
31
|
@request_params = request_params
|
25
32
|
end
|
26
33
|
|
34
|
+
# @param key [String, Symbol] params key
|
35
|
+
# @return [Object] value of the requested param
|
36
|
+
def [](key)
|
37
|
+
fetch(key.to_s)
|
38
|
+
end
|
39
|
+
|
40
|
+
# @param args [Symbol, Object] key we want to fetch and other args for `Hash#fetch`
|
41
|
+
# @return [Object] fetched object
|
42
|
+
def fetch(*args)
|
43
|
+
args[0] = args[0].to_s
|
44
|
+
@request_params.fetch(*args)
|
45
|
+
end
|
46
|
+
|
47
|
+
# @param key [String, Symbol] params key
|
48
|
+
# @return [Integer] integer value of the key
|
49
|
+
def int(key)
|
50
|
+
self[key].to_i
|
51
|
+
end
|
52
|
+
|
53
|
+
# @param key [String, Symbol] params key
|
54
|
+
# @return [Boolean] boolean key value
|
55
|
+
def bool(key)
|
56
|
+
ALLOWED_BOOLEAN_TRUE.include?(self[key])
|
57
|
+
end
|
58
|
+
|
59
|
+
# @param key [String, Symbol] params key
|
60
|
+
# @return [String] stringified key value
|
61
|
+
def str(key)
|
62
|
+
self[key].to_s
|
63
|
+
end
|
64
|
+
|
27
65
|
# @return [Hash] current search or empty if no search query present
|
28
66
|
def current_search
|
29
67
|
return @current_search if @current_search
|
@@ -10,6 +10,9 @@ module Karafka
|
|
10
10
|
# page where we check that everything is as expected and if not, we can provide some
|
11
11
|
# helpful instructions on how to fix the issues.
|
12
12
|
class StatusController < BaseController
|
13
|
+
# Fresh state is needed to generate always correct status
|
14
|
+
before { cache.clear }
|
15
|
+
|
13
16
|
# Displays the Web UI setup status
|
14
17
|
def show
|
15
18
|
@status = Models::Status.new
|