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.
Files changed (494) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +62 -176
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +88 -44
  5. data/LICENSE +6 -2
  6. data/Rakefile +4 -0
  7. data/bin/verify_kafka_warnings +35 -0
  8. data/bin/verify_topics_naming +35 -0
  9. data/config/locales/pro_errors.yml +1 -0
  10. data/config/locales/slogans.yml +1 -1
  11. data/docker-compose.yml +1 -1
  12. data/gulpfile.js +0 -2
  13. data/karafka-web.gemspec +2 -7
  14. data/lib/karafka/web/config.rb +80 -9
  15. data/lib/karafka/web/contracts/config.rb +44 -5
  16. data/lib/karafka/web/errors.rb +10 -12
  17. data/lib/karafka/web/management/actions/create_initial_states.rb +6 -6
  18. data/lib/karafka/web/management/actions/create_topics.rb +30 -64
  19. data/lib/karafka/web/management/actions/delete_topics.rb +5 -5
  20. data/lib/karafka/web/management/actions/enable.rb +5 -5
  21. data/lib/karafka/web/pro/commanding/commands/base.rb +37 -13
  22. data/lib/karafka/web/pro/commanding/commands/consumers/quiet.rb +33 -0
  23. data/lib/karafka/web/pro/commanding/commands/consumers/stop.rb +32 -0
  24. data/lib/karafka/web/pro/commanding/commands/consumers/trace.rb +37 -0
  25. data/lib/karafka/web/pro/commanding/commands/partitions/pause.rb +30 -0
  26. data/lib/karafka/web/pro/commanding/commands/partitions/resume.rb +30 -0
  27. data/lib/karafka/web/pro/commanding/commands/partitions/seek.rb +30 -0
  28. data/lib/karafka/web/pro/commanding/config.rb +6 -10
  29. data/lib/karafka/web/pro/commanding/contracts/config.rb +2 -10
  30. data/lib/karafka/web/pro/commanding/dispatcher.rb +45 -24
  31. data/lib/karafka/web/pro/commanding/handlers/partitions/commands/base.rb +67 -0
  32. data/lib/karafka/web/pro/commanding/handlers/partitions/commands/pause.rb +44 -0
  33. data/lib/karafka/web/pro/commanding/handlers/partitions/commands/resume.rb +29 -0
  34. data/lib/karafka/web/pro/commanding/handlers/partitions/commands/seek.rb +86 -0
  35. data/lib/karafka/web/pro/commanding/handlers/partitions/executor.rb +56 -0
  36. data/lib/karafka/web/pro/commanding/handlers/partitions/listener.rb +55 -0
  37. data/lib/karafka/web/pro/commanding/handlers/partitions/tracker.rb +62 -0
  38. data/lib/karafka/web/pro/commanding/listener.rb +4 -12
  39. data/lib/karafka/web/pro/commanding/manager.rb +36 -24
  40. data/lib/karafka/web/pro/commanding/matcher.rb +7 -17
  41. data/lib/karafka/web/pro/commanding/request.rb +39 -0
  42. data/lib/karafka/web/pro/commanding.rb +2 -10
  43. data/lib/karafka/web/pro/loader.rb +13 -10
  44. data/lib/karafka/web/pro/ui/app.rb +31 -390
  45. data/lib/karafka/web/pro/ui/controllers/base_controller.rb +8 -10
  46. data/lib/karafka/web/pro/ui/controllers/cluster_controller.rb +2 -10
  47. data/lib/karafka/web/pro/ui/controllers/consumers/base_controller.rb +21 -0
  48. data/lib/karafka/web/pro/ui/controllers/consumers/commanding_controller.rb +148 -0
  49. data/lib/karafka/web/pro/ui/controllers/consumers/commands_controller.rb +96 -0
  50. data/lib/karafka/web/pro/ui/controllers/consumers/consumers_controller.rb +99 -0
  51. data/lib/karafka/web/pro/ui/controllers/consumers/controls_controller.rb +36 -0
  52. data/lib/karafka/web/pro/ui/controllers/consumers/jobs_controller.rb +57 -0
  53. data/lib/karafka/web/pro/ui/controllers/consumers/partitions/base_controller.rb +86 -0
  54. data/lib/karafka/web/pro/ui/controllers/consumers/partitions/offsets_controller.rb +75 -0
  55. data/lib/karafka/web/pro/ui/controllers/consumers/partitions/pauses_controller.rb +110 -0
  56. data/lib/karafka/web/pro/ui/controllers/dashboard_controller.rb +2 -10
  57. data/lib/karafka/web/pro/ui/controllers/dlq_controller.rb +2 -10
  58. data/lib/karafka/web/pro/ui/controllers/errors_controller.rb +11 -15
  59. data/lib/karafka/web/pro/ui/controllers/explorer/base_controller.rb +21 -0
  60. data/lib/karafka/web/pro/ui/controllers/explorer/explorer_controller.rb +225 -0
  61. data/lib/karafka/web/pro/ui/controllers/explorer/messages_controller.rb +145 -0
  62. data/lib/karafka/web/pro/ui/controllers/explorer/search_controller.rb +68 -0
  63. data/lib/karafka/web/pro/ui/controllers/health_controller.rb +2 -10
  64. data/lib/karafka/web/pro/ui/controllers/jobs_controller.rb +2 -10
  65. data/lib/karafka/web/pro/ui/controllers/recurring_tasks_controller.rb +12 -13
  66. data/lib/karafka/web/pro/ui/controllers/routing_controller.rb +2 -10
  67. data/lib/karafka/web/pro/ui/controllers/scheduled_messages/base_controller.rb +2 -10
  68. data/lib/karafka/web/pro/ui/controllers/scheduled_messages/explorer_controller.rb +8 -16
  69. data/lib/karafka/web/pro/ui/controllers/scheduled_messages/messages_controller.rb +9 -15
  70. data/lib/karafka/web/pro/ui/controllers/scheduled_messages/schedules_controller.rb +2 -10
  71. data/lib/karafka/web/pro/ui/controllers/status_controller.rb +2 -10
  72. data/lib/karafka/web/pro/ui/controllers/support_controller.rb +2 -10
  73. data/lib/karafka/web/pro/ui/controllers/topics/base_controller.rb +21 -0
  74. data/lib/karafka/web/pro/ui/controllers/topics/configs_controller.rb +86 -0
  75. data/lib/karafka/web/pro/ui/controllers/topics/distributions_controller.rb +91 -0
  76. data/lib/karafka/web/pro/ui/controllers/topics/offsets_controller.rb +55 -0
  77. data/lib/karafka/web/pro/ui/controllers/topics/replications_controller.rb +37 -0
  78. data/lib/karafka/web/pro/ui/controllers/topics/topics_controller.rb +101 -0
  79. data/lib/karafka/web/pro/ui/controllers/ux_controller.rb +2 -10
  80. data/lib/karafka/web/pro/ui/lib/branding/config.rb +2 -10
  81. data/lib/karafka/web/pro/ui/lib/branding/contracts/config.rb +2 -10
  82. data/lib/karafka/web/pro/ui/lib/branding.rb +2 -10
  83. data/lib/karafka/web/pro/ui/lib/features.rb +53 -0
  84. data/lib/karafka/web/pro/ui/lib/patterns_detector.rb +2 -10
  85. data/lib/karafka/web/pro/ui/lib/policies/config.rb +2 -10
  86. data/lib/karafka/web/pro/ui/lib/policies/contracts/config.rb +2 -10
  87. data/lib/karafka/web/pro/ui/lib/policies/messages.rb +2 -10
  88. data/lib/karafka/web/pro/ui/lib/policies/requests.rb +2 -10
  89. data/lib/karafka/web/pro/ui/lib/policies.rb +2 -10
  90. data/lib/karafka/web/pro/ui/lib/safe_runner.rb +5 -0
  91. data/lib/karafka/web/pro/ui/lib/search/config.rb +2 -10
  92. data/lib/karafka/web/pro/ui/lib/search/contracts/config.rb +2 -10
  93. data/lib/karafka/web/pro/ui/lib/search/contracts/form.rb +2 -10
  94. data/lib/karafka/web/pro/ui/lib/search/matchers/base.rb +2 -10
  95. data/lib/karafka/web/pro/ui/lib/search/matchers/raw_header_includes.rb +10 -11
  96. data/lib/karafka/web/pro/ui/lib/search/matchers/raw_key_includes.rb +2 -10
  97. data/lib/karafka/web/pro/ui/lib/search/matchers/raw_payload_includes.rb +23 -11
  98. data/lib/karafka/web/pro/ui/lib/search/normalizer.rb +2 -10
  99. data/lib/karafka/web/pro/ui/lib/search/runner.rb +3 -11
  100. data/lib/karafka/web/pro/ui/lib/search.rb +2 -10
  101. data/lib/karafka/web/pro/ui/routes/base.rb +19 -0
  102. data/lib/karafka/web/pro/ui/routes/cluster.rb +37 -0
  103. data/lib/karafka/web/pro/ui/routes/consumers.rb +145 -0
  104. data/lib/karafka/web/pro/ui/routes/dashboard.rb +25 -0
  105. data/lib/karafka/web/pro/ui/routes/dlq.rb +24 -0
  106. data/lib/karafka/web/pro/ui/routes/errors.rb +39 -0
  107. data/lib/karafka/web/pro/ui/routes/explorer.rb +118 -0
  108. data/lib/karafka/web/pro/ui/routes/health.rb +47 -0
  109. data/lib/karafka/web/pro/ui/routes/jobs.rb +33 -0
  110. data/lib/karafka/web/pro/ui/routes/recurring_tasks.rb +59 -0
  111. data/lib/karafka/web/pro/ui/routes/routing.rb +31 -0
  112. data/lib/karafka/web/pro/ui/routes/scheduled_messages.rb +75 -0
  113. data/lib/karafka/web/pro/ui/routes/status.rb +24 -0
  114. data/lib/karafka/web/pro/ui/routes/support.rb +24 -0
  115. data/lib/karafka/web/pro/ui/routes/topics.rb +90 -0
  116. data/lib/karafka/web/pro/ui/routes/ux.rb +24 -0
  117. data/lib/karafka/web/pro/ui/views/cluster/_breadcrumbs.erb +3 -0
  118. data/lib/karafka/web/pro/ui/views/cluster/_broker.erb +3 -0
  119. data/lib/karafka/web/pro/ui/views/cluster/_config.erb +3 -0
  120. data/lib/karafka/web/pro/ui/views/cluster/_tabs.erb +3 -0
  121. data/lib/karafka/web/pro/ui/views/cluster/index.erb +4 -1
  122. data/lib/karafka/web/pro/ui/views/cluster/show.erb +3 -0
  123. data/lib/karafka/web/pro/ui/views/{commands → consumers/commands}/_backtrace.erb +3 -0
  124. data/lib/karafka/web/pro/ui/views/consumers/commands/_breadcrumbs.erb +24 -0
  125. data/lib/karafka/web/pro/ui/views/{commands → consumers/commands}/_command.erb +22 -6
  126. data/lib/karafka/web/pro/ui/views/consumers/commands/_command_details.erb +4 -0
  127. data/lib/karafka/web/pro/ui/views/consumers/commands/_empty.erb +6 -0
  128. data/lib/karafka/web/pro/ui/views/{commands → consumers/commands}/_incompatible_schema.erb +3 -0
  129. data/lib/karafka/web/pro/ui/views/{commands → consumers/commands}/_metadata.erb +4 -1
  130. data/lib/karafka/web/pro/ui/views/{commands → consumers/commands}/_table.erb +5 -2
  131. data/lib/karafka/web/pro/ui/views/{commands → consumers/commands}/index.erb +7 -4
  132. data/lib/karafka/web/pro/ui/views/consumers/commands/show.erb +32 -0
  133. data/lib/karafka/web/pro/ui/views/consumers/consumers/_breadcrumbs.erb +46 -0
  134. data/lib/karafka/web/pro/ui/views/consumers/{_consumer.erb → consumers/_consumer.erb} +4 -1
  135. data/lib/karafka/web/pro/ui/views/consumers/{_consumer_performance.erb → consumers/_consumer_performance.erb} +4 -1
  136. data/lib/karafka/web/pro/ui/views/consumers/consumers/_tabs.erb +38 -0
  137. data/lib/karafka/web/pro/ui/views/consumers/consumers/consumer/_commands.erb +80 -0
  138. data/lib/karafka/web/pro/ui/views/consumers/consumers/consumer/_consumer_group.erb +11 -0
  139. data/lib/karafka/web/pro/ui/views/consumers/{consumer → consumers/consumer}/_metrics.erb +3 -0
  140. data/lib/karafka/web/pro/ui/views/consumers/consumers/consumer/_no_subscriptions.erb +10 -0
  141. data/lib/karafka/web/pro/ui/views/consumers/{consumer → consumers/consumer}/_partition.erb +16 -0
  142. data/lib/karafka/web/pro/ui/views/consumers/consumers/consumer/_partition_edit_options.erb +33 -0
  143. data/lib/karafka/web/pro/ui/views/consumers/{consumer → consumers/consumer}/_stopped.erb +3 -0
  144. data/lib/karafka/web/pro/ui/views/consumers/{consumer → consumers/consumer}/_subscription_group.erb +7 -3
  145. data/lib/karafka/web/pro/ui/views/consumers/{consumer → consumers/consumer}/_tabs.erb +7 -4
  146. data/lib/karafka/web/pro/ui/views/consumers/consumers/details.erb +15 -0
  147. data/lib/karafka/web/pro/ui/views/consumers/{index.erb → consumers/index.erb} +6 -3
  148. data/lib/karafka/web/pro/ui/views/consumers/{performance.erb → consumers/performance.erb} +6 -3
  149. data/lib/karafka/web/pro/ui/views/consumers/consumers/subscriptions.erb +24 -0
  150. data/lib/karafka/web/pro/ui/views/consumers/controls/_breadcrumbs.erb +16 -0
  151. data/lib/karafka/web/pro/ui/views/consumers/{_consumer_controls.erb → controls/_controls.erb} +10 -7
  152. data/lib/karafka/web/pro/ui/views/consumers/{controls.erb → controls/index.erb} +8 -5
  153. data/lib/karafka/web/pro/ui/views/consumers/jobs/_breadcrumbs.erb +36 -0
  154. data/lib/karafka/web/pro/ui/views/consumers/{consumer → jobs}/_job.erb +4 -2
  155. data/lib/karafka/web/pro/ui/views/consumers/jobs/_no_jobs.erb +6 -0
  156. data/lib/karafka/web/pro/ui/views/consumers/{pending_jobs.erb → jobs/pending.erb} +7 -8
  157. data/lib/karafka/web/pro/ui/views/consumers/{running_jobs.erb → jobs/running.erb} +7 -8
  158. data/lib/karafka/web/pro/ui/views/consumers/partitions/offsets/_basics.erb +77 -0
  159. data/lib/karafka/web/pro/ui/views/consumers/partitions/offsets/_breadcrumbs.erb +58 -0
  160. data/lib/karafka/web/pro/ui/views/consumers/partitions/offsets/_form.erb +109 -0
  161. data/lib/karafka/web/pro/ui/views/consumers/partitions/offsets/_not_running_error.erb +16 -0
  162. data/lib/karafka/web/pro/ui/views/consumers/partitions/offsets/_running_warning.erb +15 -0
  163. data/lib/karafka/web/pro/ui/views/consumers/partitions/offsets/edit.erb +16 -0
  164. data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/_active_not_editable.erb +22 -0
  165. data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/_adjusting_warning.erb +27 -0
  166. data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/_breadcrumbs.erb +60 -0
  167. data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/_edit_form.erb +59 -0
  168. data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/_lrj_not_manageable.erb +24 -0
  169. data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/_new_form.erb +78 -0
  170. data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/_not_running.erb +16 -0
  171. data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/edit.erb +24 -0
  172. data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/new.erb +20 -0
  173. data/lib/karafka/web/pro/ui/views/dashboard/index.erb +4 -1
  174. data/lib/karafka/web/pro/ui/views/dlq/_breadcrumbs.erb +3 -0
  175. data/lib/karafka/web/pro/ui/views/dlq/_no_topics.erb +3 -0
  176. data/lib/karafka/web/pro/ui/views/dlq/_topic.erb +4 -1
  177. data/lib/karafka/web/pro/ui/views/dlq/index.erb +3 -0
  178. data/lib/karafka/web/pro/ui/views/errors/_breadcrumbs.erb +4 -6
  179. data/lib/karafka/web/pro/ui/views/errors/_error.erb +9 -1
  180. data/lib/karafka/web/pro/ui/views/errors/_partition_option.erb +3 -0
  181. data/lib/karafka/web/pro/ui/views/errors/_selector.erb +3 -0
  182. data/lib/karafka/web/pro/ui/views/errors/_table.erb +4 -1
  183. data/lib/karafka/web/pro/ui/views/errors/index.erb +6 -3
  184. data/lib/karafka/web/pro/ui/views/errors/partition.erb +5 -2
  185. data/lib/karafka/web/pro/ui/views/errors/show.erb +42 -33
  186. data/lib/karafka/web/pro/ui/views/explorer/{_breadcrumbs.erb → explorer/_breadcrumbs.erb} +7 -4
  187. data/lib/karafka/web/pro/ui/views/explorer/{_failed_deserialization.erb → explorer/_failed_deserialization.erb} +3 -0
  188. data/lib/karafka/web/pro/ui/views/explorer/{_filtered.erb → explorer/_filtered.erb} +3 -0
  189. data/lib/karafka/web/pro/ui/views/explorer/{_message.erb → explorer/_message.erb} +4 -1
  190. data/lib/karafka/web/pro/ui/views/explorer/explorer/_no_topics.erb +4 -0
  191. data/lib/karafka/web/pro/ui/views/explorer/{_partition_option.erb → explorer/_partition_option.erb} +4 -1
  192. data/lib/karafka/web/pro/ui/views/explorer/{_selector.erb → explorer/_selector.erb} +4 -1
  193. data/lib/karafka/web/pro/ui/views/explorer/explorer/_topic.erb +13 -0
  194. data/lib/karafka/web/pro/ui/views/explorer/explorer/index.erb +17 -0
  195. data/lib/karafka/web/pro/ui/views/explorer/{message → explorer/message}/_metadata.erb +10 -7
  196. data/lib/karafka/web/pro/ui/views/explorer/{message → explorer/message}/_payload.erb +6 -3
  197. data/lib/karafka/web/pro/ui/views/explorer/{message → explorer/message}/_resources_utilization.erb +7 -4
  198. data/lib/karafka/web/pro/ui/views/explorer/{message → explorer/message}/_too_big_to_be_displayed.erb +3 -0
  199. data/lib/karafka/web/pro/ui/views/explorer/{messages → explorer/messages}/_detail.erb +3 -0
  200. data/lib/karafka/web/pro/ui/views/explorer/explorer/messages/_headers.erb +51 -0
  201. data/lib/karafka/web/pro/ui/views/explorer/{messages → explorer/messages}/_key.erb +3 -0
  202. data/lib/karafka/web/pro/ui/views/explorer/explorer/partition/_cleaned.erb +6 -0
  203. data/lib/karafka/web/pro/ui/views/explorer/explorer/partition/_empty.erb +6 -0
  204. data/lib/karafka/web/pro/ui/views/explorer/{partition → explorer/partition}/_messages.erb +4 -1
  205. data/lib/karafka/web/pro/ui/views/explorer/explorer/partition/_time_selector.erb +16 -0
  206. data/lib/karafka/web/pro/ui/views/explorer/explorer/partition/_timestamp_selector.erb +33 -0
  207. data/lib/karafka/web/pro/ui/views/explorer/{partition.erb → explorer/partition.erb} +24 -17
  208. data/lib/karafka/web/pro/ui/views/explorer/explorer/show.erb +100 -0
  209. data/lib/karafka/web/pro/ui/views/explorer/{topic → explorer/topic}/_actions.erb +5 -2
  210. data/lib/karafka/web/pro/ui/views/explorer/explorer/topic/_empty.erb +6 -0
  211. data/lib/karafka/web/pro/ui/views/explorer/{topic → explorer/topic}/_limited.erb +3 -0
  212. data/lib/karafka/web/pro/ui/views/explorer/{topic.erb → explorer/topic.erb} +7 -4
  213. data/lib/karafka/web/pro/ui/views/explorer/messages/_breadcrumbs.erb +32 -0
  214. data/lib/karafka/web/pro/ui/views/explorer/messages/forward.erb +143 -0
  215. data/lib/karafka/web/pro/ui/views/explorer/search/_breadcrumbs.erb +4 -0
  216. data/lib/karafka/web/pro/ui/views/explorer/search/_fix_errors.erb +6 -0
  217. data/lib/karafka/web/pro/ui/views/{search → explorer/search}/_metadata.erb +3 -0
  218. data/lib/karafka/web/pro/ui/views/explorer/search/_no_results.erb +6 -0
  219. data/lib/karafka/web/pro/ui/views/{search → explorer/search}/_no_search_criteria.erb +3 -0
  220. data/lib/karafka/web/pro/ui/views/{search → explorer/search}/_search_criteria.erb +3 -0
  221. data/lib/karafka/web/pro/ui/views/{search → explorer/search}/_search_modal.erb +5 -2
  222. data/lib/karafka/web/pro/ui/views/explorer/search/_timeout.erb +6 -0
  223. data/lib/karafka/web/pro/ui/views/explorer/search/index.erb +32 -0
  224. data/lib/karafka/web/pro/ui/views/health/_breadcrumbs.erb +3 -0
  225. data/lib/karafka/web/pro/ui/views/health/_no_data.erb +3 -0
  226. data/lib/karafka/web/pro/ui/views/health/_partition.erb +16 -1
  227. data/lib/karafka/web/pro/ui/views/health/_partition_lags.erb +3 -0
  228. data/lib/karafka/web/pro/ui/views/health/_partition_offset.erb +3 -0
  229. data/lib/karafka/web/pro/ui/views/health/_partition_times.erb +3 -0
  230. data/lib/karafka/web/pro/ui/views/health/_table_metadata.erb +4 -1
  231. data/lib/karafka/web/pro/ui/views/health/_tabs.erb +3 -0
  232. data/lib/karafka/web/pro/ui/views/health/changes.erb +4 -1
  233. data/lib/karafka/web/pro/ui/views/health/cluster_lags.erb +3 -0
  234. data/lib/karafka/web/pro/ui/views/health/lags.erb +5 -2
  235. data/lib/karafka/web/pro/ui/views/health/offsets.erb +4 -1
  236. data/lib/karafka/web/pro/ui/views/health/overview.erb +8 -3
  237. data/lib/karafka/web/pro/ui/views/jobs/_job.erb +5 -3
  238. data/lib/karafka/web/pro/ui/views/jobs/_no_jobs.erb +3 -0
  239. data/lib/karafka/web/pro/ui/views/jobs/pending.erb +4 -1
  240. data/lib/karafka/web/pro/ui/views/jobs/running.erb +4 -1
  241. data/lib/karafka/web/pro/ui/views/recurring_tasks/_actions.erb +3 -0
  242. data/lib/karafka/web/pro/ui/views/recurring_tasks/_batch_actions.erb +3 -0
  243. data/lib/karafka/web/pro/ui/views/recurring_tasks/_breadcrumbs.erb +3 -0
  244. data/lib/karafka/web/pro/ui/views/recurring_tasks/_log.erb +3 -0
  245. data/lib/karafka/web/pro/ui/views/recurring_tasks/_not_active.erb +3 -0
  246. data/lib/karafka/web/pro/ui/views/recurring_tasks/_tabs.erb +3 -0
  247. data/lib/karafka/web/pro/ui/views/recurring_tasks/_task.erb +3 -0
  248. data/lib/karafka/web/pro/ui/views/recurring_tasks/logs.erb +3 -0
  249. data/lib/karafka/web/pro/ui/views/recurring_tasks/schedule.erb +3 -0
  250. data/lib/karafka/web/pro/ui/views/routing/_consumer_group.erb +3 -0
  251. data/lib/karafka/web/pro/ui/views/routing/_detail.erb +3 -0
  252. data/lib/karafka/web/pro/ui/views/routing/_topic.erb +3 -0
  253. data/lib/karafka/web/pro/ui/views/routing/index.erb +3 -0
  254. data/lib/karafka/web/pro/ui/views/routing/show.erb +3 -0
  255. data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/_breadcrumbs.erb +6 -3
  256. data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/_key.erb +3 -0
  257. data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/_message.erb +28 -115
  258. data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/_messages.erb +3 -0
  259. data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/message/_cancel.erb +49 -0
  260. data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/message/_compacted.erb +16 -0
  261. data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/message/_schedule.erb +83 -0
  262. data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/message/_tombstone.erb +69 -0
  263. data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/message/_unknown.erb +26 -0
  264. data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/partition.erb +23 -16
  265. data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/topic.erb +6 -3
  266. data/lib/karafka/web/pro/ui/views/scheduled_messages/schedules/_breadcrumbs.erb +3 -0
  267. data/lib/karafka/web/pro/ui/views/scheduled_messages/schedules/_no_groups.erb +3 -0
  268. data/lib/karafka/web/pro/ui/views/scheduled_messages/schedules/index.erb +4 -1
  269. data/lib/karafka/web/pro/ui/views/scheduled_messages/schedules/show.erb +17 -1
  270. data/lib/karafka/web/pro/ui/views/shared/_navigation.erb +25 -17
  271. data/lib/karafka/web/pro/ui/views/shared/_rdkafka_form_error_alert_box.erb +16 -0
  272. data/lib/karafka/web/pro/ui/views/shared/branding/_label.erb +3 -0
  273. data/lib/karafka/web/pro/ui/views/shared/branding/_notice.erb +3 -0
  274. data/lib/karafka/web/pro/ui/views/topics/configs/_breadcrumbs.erb +34 -0
  275. data/lib/karafka/web/pro/ui/views/topics/configs/_config.erb +26 -0
  276. data/lib/karafka/web/pro/ui/views/topics/configs/_delete_button.erb +13 -0
  277. data/lib/karafka/web/pro/ui/views/topics/configs/_edit_form.erb +50 -0
  278. data/lib/karafka/web/pro/ui/views/topics/configs/_edit_plan.erb +16 -0
  279. data/lib/karafka/web/pro/ui/views/topics/configs/_edit_warning.erb +12 -0
  280. data/lib/karafka/web/pro/ui/views/topics/configs/edit.erb +16 -0
  281. data/lib/karafka/web/pro/ui/views/topics/{config.erb → configs/index.erb} +9 -3
  282. data/lib/karafka/web/pro/ui/views/topics/distributions/_add_partitions_button.erb +13 -0
  283. data/lib/karafka/web/pro/ui/views/topics/{distribution → distributions}/_badges.erb +3 -0
  284. data/lib/karafka/web/pro/ui/views/topics/distributions/_breadcrumbs.erb +28 -0
  285. data/lib/karafka/web/pro/ui/views/topics/{distribution → distributions}/_chart.erb +3 -0
  286. data/lib/karafka/web/pro/ui/views/topics/distributions/_edit_form.erb +47 -0
  287. data/lib/karafka/web/pro/ui/views/topics/distributions/_edit_hints.erb +15 -0
  288. data/lib/karafka/web/pro/ui/views/topics/distributions/_edit_warnings.erb +14 -0
  289. data/lib/karafka/web/pro/ui/views/topics/distributions/_empty_partitions.erb +4 -0
  290. data/lib/karafka/web/pro/ui/views/topics/{distribution → distributions}/_limited.erb +3 -0
  291. data/lib/karafka/web/pro/ui/views/topics/distributions/_partition.erb +13 -0
  292. data/lib/karafka/web/pro/ui/views/topics/distributions/edit.erb +16 -0
  293. data/lib/karafka/web/pro/ui/views/topics/{distribution.erb → distributions/show.erb} +11 -7
  294. data/lib/karafka/web/pro/ui/views/topics/offsets/_breadcrumbs.erb +20 -0
  295. data/lib/karafka/web/pro/ui/views/topics/offsets/_partition.erb +13 -0
  296. data/lib/karafka/web/pro/ui/views/topics/{offsets.erb → offsets/show.erb} +6 -3
  297. data/lib/karafka/web/pro/ui/views/topics/replications/_breadcrumbs.erb +20 -0
  298. data/lib/karafka/web/pro/ui/views/topics/{_partition.erb → replications/_partition.erb} +4 -1
  299. data/lib/karafka/web/pro/ui/views/topics/{replication.erb → replications/show.erb} +6 -3
  300. data/lib/karafka/web/pro/ui/views/topics/topics/_breadcrumbs.erb +32 -0
  301. data/lib/karafka/web/pro/ui/views/topics/topics/_create_button.erb +13 -0
  302. data/lib/karafka/web/pro/ui/views/topics/topics/_create_hints.erb +15 -0
  303. data/lib/karafka/web/pro/ui/views/topics/topics/_delete_form.erb +36 -0
  304. data/lib/karafka/web/pro/ui/views/topics/topics/_delete_hints.erb +15 -0
  305. data/lib/karafka/web/pro/ui/views/topics/topics/_delete_warning.erb +13 -0
  306. data/lib/karafka/web/pro/ui/views/topics/topics/_new_form.erb +80 -0
  307. data/lib/karafka/web/pro/ui/views/topics/{_tabs.erb → topics/_tabs.erb} +7 -4
  308. data/lib/karafka/web/pro/ui/views/topics/topics/_topic.erb +12 -0
  309. data/lib/karafka/web/pro/ui/views/topics/topics/edit.erb +10 -0
  310. data/lib/karafka/web/pro/ui/views/topics/topics/index.erb +19 -0
  311. data/lib/karafka/web/pro/ui/views/topics/topics/new.erb +12 -0
  312. data/lib/karafka/web/processing/consumer.rb +7 -7
  313. data/lib/karafka/web/processing/consumers/aggregators/state.rb +14 -14
  314. data/lib/karafka/web/processing/consumers/metrics.rb +1 -1
  315. data/lib/karafka/web/processing/consumers/state.rb +1 -1
  316. data/lib/karafka/web/processing/publisher.rb +4 -4
  317. data/lib/karafka/web/tracking/consumers/contracts/partition.rb +1 -0
  318. data/lib/karafka/web/tracking/consumers/listeners/errors.rb +1 -0
  319. data/lib/karafka/web/tracking/consumers/listeners/pausing.rb +2 -2
  320. data/lib/karafka/web/tracking/consumers/listeners/transactions.rb +44 -0
  321. data/lib/karafka/web/tracking/consumers/reporter.rb +2 -2
  322. data/lib/karafka/web/tracking/consumers/sampler.rb +81 -14
  323. data/lib/karafka/web/tracking/helpers/sysconf.rb +33 -0
  324. data/lib/karafka/web/tracking/producers/reporter.rb +1 -1
  325. data/lib/karafka/web/ui/app.rb +19 -112
  326. data/lib/karafka/web/ui/base.rb +60 -3
  327. data/lib/karafka/web/ui/controllers/base_controller.rb +43 -1
  328. data/lib/karafka/web/ui/controllers/cluster_controller.rb +5 -2
  329. data/lib/karafka/web/ui/controllers/errors_controller.rb +13 -4
  330. data/lib/karafka/web/ui/controllers/requests/execution_wrapper.rb +52 -0
  331. data/lib/karafka/web/ui/controllers/requests/hookable.rb +99 -0
  332. data/lib/karafka/web/ui/controllers/requests/params.rb +39 -1
  333. data/lib/karafka/web/ui/controllers/responses/redirect.rb +0 -5
  334. data/lib/karafka/web/ui/controllers/status_controller.rb +3 -0
  335. data/lib/karafka/web/ui/helpers/application_helper.rb +10 -71
  336. data/lib/karafka/web/ui/helpers/paths_helper.rb +54 -10
  337. data/lib/karafka/web/ui/helpers/time_helper.rb +82 -0
  338. data/lib/karafka/web/ui/helpers/topics_helper.rb +156 -0
  339. data/lib/karafka/web/ui/lib/admin.rb +1 -1
  340. data/lib/karafka/web/ui/lib/cache.rb +135 -0
  341. data/lib/karafka/web/ui/models/broker.rb +1 -2
  342. data/lib/karafka/web/ui/models/cluster_info.rb +15 -21
  343. data/lib/karafka/web/ui/models/consumers_metrics.rb +1 -1
  344. data/lib/karafka/web/ui/models/consumers_state.rb +1 -1
  345. data/lib/karafka/web/ui/models/counters.rb +1 -1
  346. data/lib/karafka/web/ui/models/health.rb +9 -7
  347. data/lib/karafka/web/ui/models/message.rb +20 -2
  348. data/lib/karafka/web/ui/models/process.rb +16 -0
  349. data/lib/karafka/web/ui/models/processes.rb +29 -8
  350. data/lib/karafka/web/ui/models/recurring_tasks/schedule.rb +1 -1
  351. data/lib/karafka/web/ui/models/status.rb +28 -9
  352. data/lib/karafka/web/ui/models/topic.rb +1 -2
  353. data/lib/karafka/web/ui/public/javascripts/application.js +8 -98
  354. data/lib/karafka/web/ui/public/javascripts/application.min.js +12 -4
  355. data/lib/karafka/web/ui/public/javascripts/application.min.js.br +0 -0
  356. data/lib/karafka/web/ui/public/javascripts/application.min.js.gz +0 -0
  357. data/lib/karafka/web/ui/public/javascripts/components/action_confirmation_manager.js +30 -0
  358. data/lib/karafka/web/ui/public/javascripts/components/alerts.js +39 -0
  359. data/lib/karafka/web/ui/public/javascripts/components/button_lock_manager.js +50 -0
  360. data/lib/karafka/web/ui/public/javascripts/components/live_poll.js +71 -19
  361. data/lib/karafka/web/ui/public/javascripts/components/message_republish_manager.js +50 -0
  362. data/lib/karafka/web/ui/public/javascripts/components/page_title_tracker.js +21 -0
  363. data/lib/karafka/web/ui/public/javascripts/components/partition_redirect_manager.js +21 -0
  364. data/lib/karafka/web/ui/public/javascripts/components/time_ago_manager.js +25 -0
  365. data/lib/karafka/web/ui/public/javascripts/components/timestamp_selector.js +30 -0
  366. data/lib/karafka/web/ui/public/javascripts/libs/datepicker.js +2 -2
  367. data/lib/karafka/web/ui/public/stylesheets/application.css +30 -0
  368. data/lib/karafka/web/ui/public/stylesheets/application.min.css +5110 -13
  369. data/lib/karafka/web/ui/public/stylesheets/application.min.css.br +0 -0
  370. data/lib/karafka/web/ui/public/stylesheets/application.min.css.gz +0 -0
  371. data/lib/karafka/web/ui/public/stylesheets/libs/highlight_dark.min.css.gz +0 -0
  372. data/lib/karafka/web/ui/public/stylesheets/libs/highlight_light.min.css.gz +0 -0
  373. data/lib/karafka/web/ui/public/stylesheets/libs/tailwind.css +507 -214
  374. data/lib/karafka/web/ui/routes/assets.rb +53 -0
  375. data/lib/karafka/web/ui/routes/base.rb +36 -0
  376. data/lib/karafka/web/ui/routes/cluster.rb +28 -0
  377. data/lib/karafka/web/ui/routes/consumers.rb +35 -0
  378. data/lib/karafka/web/ui/routes/dashboard.rb +20 -0
  379. data/lib/karafka/web/ui/routes/errors.rb +30 -0
  380. data/lib/karafka/web/ui/routes/jobs.rb +28 -0
  381. data/lib/karafka/web/ui/routes/pro_only.rb +27 -0
  382. data/lib/karafka/web/ui/routes/routing.rb +26 -0
  383. data/lib/karafka/web/ui/routes/status.rb +19 -0
  384. data/lib/karafka/web/ui/routes/support.rb +19 -0
  385. data/lib/karafka/web/ui/routes/ux.rb +19 -0
  386. data/lib/karafka/web/ui/views/cluster/_partition.erb +2 -2
  387. data/lib/karafka/web/ui/views/cluster/brokers.erb +1 -1
  388. data/lib/karafka/web/ui/views/consumers/_assignments_badges.erb +2 -7
  389. data/lib/karafka/web/ui/views/consumers/_breadcrumbs.erb +7 -1
  390. data/lib/karafka/web/ui/views/consumers/_consumer.erb +1 -1
  391. data/lib/karafka/web/ui/views/consumers/_no_consumers.erb +2 -2
  392. data/lib/karafka/web/ui/views/consumers/_tabs.erb +4 -4
  393. data/lib/karafka/web/ui/views/consumers/index.erb +1 -1
  394. data/lib/karafka/web/ui/views/dashboard/_feature_pro.erb +1 -1
  395. data/lib/karafka/web/ui/views/dashboard/_not_enough_data.erb +2 -2
  396. data/lib/karafka/web/ui/views/dashboard/_ranges_selector.erb +1 -1
  397. data/lib/karafka/web/ui/views/dashboard/index.erb +6 -49
  398. data/lib/karafka/web/ui/views/errors/_breadcrumbs.erb +3 -8
  399. data/lib/karafka/web/ui/views/errors/_detail.erb +3 -3
  400. data/lib/karafka/web/ui/views/errors/_error.erb +6 -1
  401. data/lib/karafka/web/ui/views/errors/index.erb +1 -1
  402. data/lib/karafka/web/ui/views/errors/show.erb +39 -33
  403. data/lib/karafka/web/ui/views/jobs/_job.erb +2 -3
  404. data/lib/karafka/web/ui/views/jobs/pending.erb +1 -1
  405. data/lib/karafka/web/ui/views/jobs/running.erb +1 -1
  406. data/lib/karafka/web/ui/views/layout.erb +7 -5
  407. data/lib/karafka/web/ui/views/shared/_become_pro.erb +1 -1
  408. data/lib/karafka/web/ui/views/shared/_brand.erb +1 -1
  409. data/lib/karafka/web/ui/views/shared/_breadcrumbs.erb +1 -1
  410. data/lib/karafka/web/ui/views/shared/_compacted_message_info.erb +16 -0
  411. data/lib/karafka/web/ui/views/shared/_content.erb +1 -1
  412. data/lib/karafka/web/ui/views/shared/_controls.erb +10 -3
  413. data/lib/karafka/web/ui/views/shared/_custom_nav.erb +9 -0
  414. data/lib/karafka/web/ui/views/shared/_flashes.erb +3 -5
  415. data/lib/karafka/web/ui/views/shared/_header.erb +25 -2
  416. data/lib/karafka/web/ui/views/shared/_navigation.erb +17 -15
  417. data/lib/karafka/web/ui/views/shared/alerts/_error.erb +8 -0
  418. data/lib/karafka/web/ui/views/shared/alerts/_info.erb +8 -0
  419. data/lib/karafka/web/ui/views/shared/alerts/_primary.erb +8 -0
  420. data/lib/karafka/web/ui/views/shared/alerts/_secondary.erb +8 -0
  421. data/lib/karafka/web/ui/views/shared/alerts/_success.erb +8 -0
  422. data/lib/karafka/web/ui/views/shared/alerts/_warning.erb +8 -0
  423. data/lib/karafka/web/ui/views/shared/exceptions/not_allowed.erb +4 -0
  424. data/lib/karafka/web/ui/views/shared/exceptions/not_found.erb +5 -1
  425. data/lib/karafka/web/ui/views/shared/exceptions/pro_only.erb +4 -0
  426. data/lib/karafka/web/ui/views/shared/icons/_arrow_left.erb +3 -0
  427. data/lib/karafka/web/ui/views/shared/icons/_arrow_up_tray.erb +3 -0
  428. data/lib/karafka/web/ui/views/shared/icons/_clock.erb +3 -0
  429. data/lib/karafka/web/ui/views/shared/icons/_pencil.erb +3 -0
  430. data/lib/karafka/web/ui/views/shared/icons/_pencil_square.erb +3 -0
  431. data/lib/karafka/web/ui/views/shared/icons/_play_pause.erb +3 -0
  432. data/lib/karafka/web/ui/views/shared/icons/_plus.erb +3 -0
  433. data/lib/karafka/web/ui/views/shared/icons/_trash.erb +3 -0
  434. data/lib/karafka/web/ui/views/status/failures/_live_reporting.erb +1 -1
  435. data/lib/karafka/web/ui/views/status/failures/_partitions.erb +3 -3
  436. data/lib/karafka/web/ui/views/status/failures/_state_calculation.erb +2 -2
  437. data/lib/karafka/web/ui/views/status/info/_components.erb +6 -6
  438. data/lib/karafka/web/ui/views/status/show.erb +15 -0
  439. data/lib/karafka/web/ui/views/status/warnings/_consumers_schemas.erb +31 -0
  440. data/lib/karafka/web/ui/views/ux/_icons.erb +1 -1
  441. data/lib/karafka/web/version.rb +1 -1
  442. data/lib/karafka/web.rb +3 -0
  443. data/package-lock.json +868 -1255
  444. data/package.json +6 -7
  445. data/postcss.config.js +1 -2
  446. data/renovate.json +20 -1
  447. data/tailwind.config.js +0 -4
  448. metadata +235 -135
  449. checksums.yaml.gz.sig +0 -0
  450. data/certs/cert.pem +0 -26
  451. data/lib/karafka/web/pro/commanding/commands/quiet.rb +0 -34
  452. data/lib/karafka/web/pro/commanding/commands/stop.rb +0 -34
  453. data/lib/karafka/web/pro/commanding/commands/trace.rb +0 -41
  454. data/lib/karafka/web/pro/ui/controllers/commanding_controller.rb +0 -118
  455. data/lib/karafka/web/pro/ui/controllers/commands_controller.rb +0 -96
  456. data/lib/karafka/web/pro/ui/controllers/consumers_controller.rb +0 -138
  457. data/lib/karafka/web/pro/ui/controllers/explorer_controller.rb +0 -220
  458. data/lib/karafka/web/pro/ui/controllers/messages_controller.rb +0 -107
  459. data/lib/karafka/web/pro/ui/controllers/search_controller.rb +0 -73
  460. data/lib/karafka/web/pro/ui/controllers/topics_controller.rb +0 -130
  461. data/lib/karafka/web/pro/ui/views/commands/_breadcrumbs.erb +0 -21
  462. data/lib/karafka/web/pro/ui/views/commands/_command_details.erb +0 -1
  463. data/lib/karafka/web/pro/ui/views/commands/_empty.erb +0 -3
  464. data/lib/karafka/web/pro/ui/views/commands/show.erb +0 -33
  465. data/lib/karafka/web/pro/ui/views/consumers/_breadcrumbs.erb +0 -55
  466. data/lib/karafka/web/pro/ui/views/consumers/_tabs.erb +0 -33
  467. data/lib/karafka/web/pro/ui/views/consumers/consumer/_commands.erb +0 -72
  468. data/lib/karafka/web/pro/ui/views/consumers/consumer/_consumer_group.erb +0 -8
  469. data/lib/karafka/web/pro/ui/views/consumers/consumer/_no_jobs.erb +0 -7
  470. data/lib/karafka/web/pro/ui/views/consumers/consumer/_no_subscriptions.erb +0 -7
  471. data/lib/karafka/web/pro/ui/views/consumers/details.erb +0 -13
  472. data/lib/karafka/web/pro/ui/views/consumers/subscriptions.erb +0 -25
  473. data/lib/karafka/web/pro/ui/views/explorer/_no_topics.erb +0 -1
  474. data/lib/karafka/web/pro/ui/views/explorer/_topic.erb +0 -10
  475. data/lib/karafka/web/pro/ui/views/explorer/index.erb +0 -14
  476. data/lib/karafka/web/pro/ui/views/explorer/messages/_headers.erb +0 -33
  477. data/lib/karafka/web/pro/ui/views/explorer/partition/_cleaned.erb +0 -3
  478. data/lib/karafka/web/pro/ui/views/explorer/partition/_empty.erb +0 -3
  479. data/lib/karafka/web/pro/ui/views/explorer/show.erb +0 -97
  480. data/lib/karafka/web/pro/ui/views/explorer/topic/_empty.erb +0 -3
  481. data/lib/karafka/web/pro/ui/views/search/_breadcrumbs.erb +0 -1
  482. data/lib/karafka/web/pro/ui/views/search/_fix_errors.erb +0 -3
  483. data/lib/karafka/web/pro/ui/views/search/_no_results.erb +0 -3
  484. data/lib/karafka/web/pro/ui/views/search/_timeout.erb +0 -3
  485. data/lib/karafka/web/pro/ui/views/search/index.erb +0 -29
  486. data/lib/karafka/web/pro/ui/views/topics/_breadcrumbs.erb +0 -45
  487. data/lib/karafka/web/pro/ui/views/topics/_partition_offsets.erb +0 -10
  488. data/lib/karafka/web/pro/ui/views/topics/_topic.erb +0 -9
  489. data/lib/karafka/web/pro/ui/views/topics/distribution/_empty_partitions.erb +0 -1
  490. data/lib/karafka/web/pro/ui/views/topics/distribution/_partition.erb +0 -10
  491. data/lib/karafka/web/pro/ui/views/topics/index.erb +0 -14
  492. data/lib/karafka/web/ui/lib/ttl_cache.rb +0 -82
  493. data.tar.gz.sig +0 -0
  494. metadata.gz.sig +0 -0
@@ -1,220 +0,0 @@
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
- # Data explorer controller
20
- class ExplorerController < BaseController
21
- # Lists all the topics we can explore
22
- def index
23
- @topics = Models::ClusterInfo
24
- .topics
25
- .sort_by { |topic| topic[:topic_name] }
26
-
27
- unless ::Karafka::Web.config.ui.visibility.internal_topics
28
- @topics.reject! { |topic| topic[:topic_name].start_with?('__') }
29
- end
30
-
31
- render
32
- end
33
-
34
- # Displays aggregated messages from (potentially) all partitions of a topic
35
- #
36
- # @param topic_id [String]
37
- #
38
- # @note This view may not be 100% accurate because we merge multiple partitions data
39
- # into a single view and this is never accurate. It can be used however to quickly
40
- # look at most recent data flowing, etc, hence it is still useful for aggregated
41
- # metrics information
42
- #
43
- # @note We cannot use offset references here because each of the partitions may have
44
- # completely different values
45
- def topic(topic_id)
46
- @visibility_filter = ::Karafka::Web.config.ui.policies.messages
47
-
48
- @topic_id = topic_id
49
- @partitions_count = Models::ClusterInfo.partitions_count(topic_id)
50
-
51
- @active_partitions, materialized_page, @limited = Paginators::Partitions.call(
52
- @partitions_count, @params.current_page
53
- )
54
-
55
- @messages, next_page = Models::Message.topic_page(
56
- topic_id, @active_partitions, materialized_page
57
- )
58
-
59
- paginate(@params.current_page, next_page)
60
-
61
- render
62
- end
63
-
64
- # Shows messages available in a given partition
65
- #
66
- # @param topic_id [String]
67
- # @param partition_id [Integer]
68
- def partition(topic_id, partition_id)
69
- @visibility_filter = ::Karafka::Web.config.ui.policies.messages
70
- @topic_id = topic_id
71
- @partition_id = partition_id
72
- @watermark_offsets = Models::WatermarkOffsets.find(topic_id, partition_id)
73
- @partitions_count = Models::ClusterInfo.partitions_count(topic_id)
74
-
75
- previous_offset, @messages, next_offset = current_partition_data
76
-
77
- paginate(
78
- previous_offset,
79
- @params.current_offset,
80
- next_offset,
81
- # If message is an array, it means it's a compacted dummy offset representation
82
- @messages.map { |message| message.is_a?(Array) ? message.last : message.offset }
83
- )
84
-
85
- render
86
- end
87
-
88
- # Displays given message
89
- #
90
- # @param topic_id [String]
91
- # @param partition_id [Integer]
92
- # @param offset [Integer] offset of the message we want to display
93
- # @param paginate [Boolean] do we want to have pagination
94
- def show(topic_id, partition_id, offset, paginate: true)
95
- Lib::PatternsDetector.new.call
96
-
97
- @visibility_filter = ::Karafka::Web.config.ui.policies.messages
98
- @topic_id = topic_id
99
- @partition_id = partition_id
100
- @offset = offset
101
- @message = Models::Message.find(@topic_id, @partition_id, @offset)
102
-
103
- @safe_key = Web::Pro::Ui::Lib::SafeRunner.new { @message.key }.tap(&:call)
104
- @safe_headers = Web::Pro::Ui::Lib::SafeRunner.new { @message.headers }.tap(&:call)
105
- @safe_payload = Web::Pro::Ui::Lib::SafeRunner.new { @message.payload }.tap(&:call)
106
-
107
- # This may be off for certain views like recent view where we are interested only
108
- # in the most recent all the time. It does not make any sense to display pagination
109
- # there
110
- if paginate
111
- # We need watermark offsets to decide if we can paginate left and right
112
- watermark_offsets = Models::WatermarkOffsets.find(topic_id, partition_id)
113
- paginate(offset, watermark_offsets.low, watermark_offsets.high)
114
- end
115
-
116
- render
117
- end
118
-
119
- # Displays the most recent message on a topic/partition
120
- #
121
- # @param topic_id [String]
122
- # @param partition_id [Integer, nil] partition we're interested in or nil if we are
123
- # interested in the most recent message from all the partitions
124
- def recent(topic_id, partition_id)
125
- if partition_id
126
- active_partitions = [partition_id]
127
- else
128
- partitions_count = Models::ClusterInfo.partitions_count(topic_id)
129
- active_partitions, = Paginators::Partitions.call(partitions_count, 1)
130
- end
131
-
132
- recent = nil
133
-
134
- # This selects first pages with most recent messages and moves to next if first
135
- # contains only compacted data, etc.
136
- #
137
- # We do it until we find a message we could refer to (if doable) within first
138
- # ten pages
139
- 10.times do |page|
140
- messages, = Models::Message.topic_page(topic_id, active_partitions, page + 1)
141
-
142
- # Selects newest out of all partitions
143
- # Reject compacted messages and transaction-related once
144
- recent = messages.reject { |message| message.is_a?(Array) }.max_by(&:timestamp)
145
-
146
- break if recent
147
- end
148
-
149
- recent || not_found!
150
-
151
- show(topic_id, recent.partition, recent.offset, paginate: false)
152
- end
153
-
154
- # Computes a page on which the given offset is in the middle of the page (if possible)
155
- # Useful often when debugging to be able to quickly jump to the historical location
156
- # of message and its surrounding to understand failure
157
- #
158
- # @param topic_id [String]
159
- # @param partition_id [Integer]
160
- # @param offset [Integer] offset of the message we want to display
161
- def surrounding(topic_id, partition_id, offset)
162
- watermark_offsets = Models::WatermarkOffsets.find(topic_id, partition_id)
163
-
164
- not_found! if offset < watermark_offsets.low
165
- not_found! if offset >= watermark_offsets.high
166
-
167
- # Assume we start from this offset
168
- shift = 0
169
- elements = 0
170
-
171
- # Position the offset as close to the middle of offset based page as possible
172
- ::Karafka::Web.config.ui.per_page.times do
173
- break if elements >= ::Karafka::Web.config.ui.per_page
174
-
175
- elements += 1 if offset + shift < watermark_offsets.high
176
-
177
- if offset - shift > watermark_offsets.low
178
- shift += 1
179
- elements += 1
180
- end
181
- end
182
-
183
- target = offset - shift
184
-
185
- redirect("explorer/#{topic_id}/#{partition_id}?offset=#{target}")
186
- end
187
-
188
- # Finds the closest offset matching the requested time and redirects to this location
189
- # Note, that it redirects to closest but always younger.
190
- #
191
- # @param topic_id [String]
192
- # @param partition_id [Integer]
193
- # @param time [Time] time of the message
194
- def closest(topic_id, partition_id, time)
195
- target = Web::Ui::Lib::Admin.read_topic(topic_id, partition_id, 1, time).first
196
-
197
- partition_path = "explorer/#{topic_id}/#{partition_id}"
198
- partition_path += "?offset=#{target.offset}" if target
199
-
200
- redirect(partition_path)
201
- end
202
-
203
- private
204
-
205
- # Fetches current page data
206
- # @return [Array] fetched data with pagination information for the requested partition
207
- def current_partition_data
208
- Models::Message.offset_page(
209
- @topic_id,
210
- @partition_id,
211
- @params.current_offset,
212
- @watermark_offsets
213
- )
214
- end
215
- end
216
- end
217
- end
218
- end
219
- end
220
- end
@@ -1,107 +0,0 @@
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
- # Controller for working with messages
20
- # While part of messages operations is done via explorer (exploring), this controller
21
- # handles other cases not related to viewing data
22
- class MessagesController < BaseController
23
- # Takes a requested message content and republishes it again
24
- #
25
- # @param topic_id [String]
26
- # @param partition_id [Integer]
27
- # @param offset [Integer] offset of the message we want to republish
28
- def republish(topic_id, partition_id, offset)
29
- message = Models::Message.find(topic_id, partition_id, offset)
30
-
31
- deny! unless visibility_filter.republish?(message)
32
-
33
- delivery = ::Karafka::Web.producer.produce_sync(
34
- topic: topic_id,
35
- partition: partition_id,
36
- payload: message.raw_payload,
37
- headers: message.headers,
38
- key: message.key
39
- )
40
-
41
- redirect(
42
- :back,
43
- success: reproduced(message, delivery)
44
- )
45
- end
46
-
47
- # Dispatches the message raw payload to the browser as a file
48
- #
49
- # @param topic_id [String]
50
- # @param partition_id [Integer]
51
- # @param offset [Integer] offset of the message we want to download
52
- def download(topic_id, partition_id, offset)
53
- message = Models::Message.find(topic_id, partition_id, offset)
54
-
55
- deny! unless visibility_filter.download?(message)
56
-
57
- file(
58
- message.raw_payload,
59
- "#{topic_id}_#{partition_id}_#{offset}_payload.msg"
60
- )
61
- end
62
-
63
- # Dispatches the message payload first deserialized and then serialized to JSON
64
- # It differs from the raw payload in cases where raw payload is compressed or binary
65
- # or contains data that the Web UI user should not see that was altered on the Web UI
66
- # with the visibility filter.
67
- #
68
- # @param topic_id [String]
69
- # @param partition_id [Integer]
70
- # @param offset [Integer] offset of the message we want to export
71
- def export(topic_id, partition_id, offset)
72
- Lib::PatternsDetector.new.call
73
-
74
- message = Models::Message.find(topic_id, partition_id, offset)
75
-
76
- # Check if exports are allowed
77
- deny! unless visibility_filter.export?(message)
78
-
79
- file(
80
- message.payload.to_json,
81
- "#{topic_id}_#{partition_id}_#{offset}_payload.json"
82
- )
83
- end
84
-
85
- private
86
-
87
- # @param message [Karafka::Messages::Message]
88
- # @param delivery [Rdkafka::Producer::DeliveryReport]
89
- # @return [String] flash message about message reproducing
90
- def reproduced(message, delivery)
91
- <<~MSG
92
- Message with offset #{message.offset}
93
- has been sent again to #{message.topic}##{message.partition}
94
- and received offset #{delivery.offset}.
95
- MSG
96
- end
97
-
98
- # @return [Object] visibility filter. Either default or user-based
99
- def visibility_filter
100
- ::Karafka::Web.config.ui.policies.messages
101
- end
102
- end
103
- end
104
- end
105
- end
106
- end
107
- end
@@ -1,73 +0,0 @@
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
- # Handles the search requests
20
- # We present this as a part of explorer scope but we use a separate controller not to
21
- # mix data exploring with searching.
22
- class SearchController < Web::Ui::Controllers::ClusterController
23
- # Runs the search if search parameters are provided
24
- # If no parameters provided, displays the search modal and info to provide search data
25
- # If invalid search parameters provided, modal contains errors
26
- #
27
- # @param topic_id [String] topic we're interested in
28
- # @note In theory search can be used to detect pieces of information within messages.
29
- # Since we allow for custom search strategies, this is not an issue because users
30
- # that need to provide only granular search can do so.
31
- def index(topic_id)
32
- @topic_id = topic_id
33
- @partitions_count = Models::ClusterInfo.partitions_count(topic_id)
34
- # Select only matchers that should be available in the context of the current topic
35
- @matchers = Web.config.ui.search.matchers.select { |match| match.active?(@topic_id) }
36
- @search_criteria = !@params.current_search.empty?
37
- @current_search = Lib::Search::Normalizer.call(@params.current_search)
38
- # Needed when rendering found messages rows. We should always filter the messages
39
- # details with the visibility filter
40
- @visibility_filter = ::Karafka::Web.config.ui.policies.messages
41
- @limits = ::Karafka::Web.config.ui.search.limits.sort
42
-
43
- # If there is search form filled, we validate it to make sure there are no errors
44
- @errors = if @search_criteria
45
- Lib::Search::Contracts::Form.new.call(@current_search).errors
46
- else
47
- {}
48
- end
49
-
50
- # If all good we run the search
51
- if @search_criteria && @errors.empty?
52
- found, @search_details = Lib::Search::Runner.new(
53
- @topic_id,
54
- @partitions_count,
55
- @current_search
56
- ).call
57
-
58
- @messages, last_page = Paginators::Arrays.call(
59
- found,
60
- @params.current_page
61
- )
62
-
63
- paginate(@params.current_page, !last_page)
64
- end
65
-
66
- render
67
- end
68
- end
69
- end
70
- end
71
- end
72
- end
73
- end
@@ -1,130 +0,0 @@
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
- # Topics management controller
20
- # Allows for exploration of settings and replication details
21
- class TopicsController < BaseController
22
- self.sortable_attributes = %w[
23
- name
24
- value
25
- default?
26
- read_only?
27
- synonym?
28
- sensitive?
29
- partition_id
30
- leader
31
- replica_count
32
- in_sync_replica_brokers
33
- count
34
- share
35
- diff
36
- low
37
- high
38
- ].freeze
39
-
40
- # Lists available topics in the cluster
41
- def index
42
- @topics = Models::Topic.all.sort_by(&:topic_name)
43
-
44
- unless ::Karafka::Web.config.ui.visibility.internal_topics
45
- @topics.delete_if { |topic| topic[:topic_name].start_with?('__') }
46
- end
47
-
48
- render
49
- end
50
-
51
- # Displays requested topic config details
52
- #
53
- # @param topic_name [String] topic we're interested in
54
- def config(topic_name)
55
- @topic = Models::Topic.find(topic_name)
56
-
57
- @configs = refine(@topic.configs)
58
-
59
- render
60
- end
61
-
62
- # Displays requested topic replication details
63
- #
64
- # @param topic_name [String] topic we're interested in
65
- def replication(topic_name)
66
- @topic = Models::Topic.find(topic_name)
67
-
68
- @partitions = refine(@topic[:partitions])
69
-
70
- render
71
- end
72
-
73
- # Displays the messages distribution across various partitions
74
- #
75
- # @param topic_name [String] topic we're interested in
76
- #
77
- # @note Because computing distribution is fairly expensive, we paginate this. While
78
- # because of that results may not be exact, this allows us to support topics with
79
- # many partitions.
80
- def distribution(topic_name)
81
- @topic = Models::Topic.find(topic_name)
82
-
83
- @active_partitions, _materialized_page, @limited = Paginators::Partitions.call(
84
- @topic.partition_count, @params.current_page
85
- )
86
-
87
- @aggregated, distribution = @topic.distribution(@active_partitions)
88
-
89
- @distribution = refine(distribution)
90
-
91
- next_page = @active_partitions.last < @topic.partition_count - 1
92
- paginate(@params.current_page, next_page)
93
-
94
- render
95
- end
96
-
97
- # Displays high and low offsets for given topic
98
- #
99
- # @param topic_name [String] topic we're interested in
100
- def offsets(topic_name)
101
- @topic = Models::Topic.find(topic_name)
102
-
103
- @active_partitions, _materialized_page, @limited = Paginators::Partitions.call(
104
- @topic.partition_count, @params.current_page
105
- )
106
-
107
- offsets = @active_partitions.map do |partition_id|
108
- part_offsets = Admin.read_watermark_offsets(topic_name, partition_id)
109
-
110
- {
111
- partition_id: partition_id,
112
- low: part_offsets.first,
113
- high: part_offsets.last,
114
- diff: part_offsets.last - part_offsets.first
115
- }
116
- end
117
-
118
- @offsets = refine(offsets)
119
-
120
- next_page = @active_partitions.last < @topic.partition_count - 1
121
- paginate(@params.current_page, next_page)
122
-
123
- render
124
- end
125
- end
126
- end
127
- end
128
- end
129
- end
130
- end
@@ -1,21 +0,0 @@
1
- <li>
2
- <a href="<%= root_path('consumers/overview') %>">
3
- Consumers
4
- </a>
5
- </li>
6
-
7
- <% if current_path.include?('/commands') %>
8
- <li>
9
- <a href="<%= root_path('commands') %>">
10
- Commands
11
- </a>
12
- </li>
13
- <% end %>
14
-
15
- <% if @command_message %>
16
- <li>
17
- <a href="<%= root_path('commands', @command_message.offset) %>">
18
- <%= @command_message.offset %>
19
- </a>
20
- </li>
21
- <% end %>
@@ -1 +0,0 @@
1
- <pre class="code"><code class="json"><%= JSON.pretty_generate command %></code></pre>
@@ -1,3 +0,0 @@
1
- <%==
2
- alert_info('No commands found.')
3
- %>
@@ -1,33 +0,0 @@
1
- <% command = @command_message.payload %>
2
-
3
- <div class="col-span-12">
4
- <% if command[:schema_version] == @schema_version %>
5
- <% view_title "#{command[:command][:name]} #{command[:type]} #{@command_message.key}" %>
6
-
7
- <%== partial 'consumers/tabs' %>
8
-
9
- <%== partial 'commands/metadata', locals: { command: command } %>
10
-
11
- <h2 class="h2">
12
- <% if command[:type] == 'command' %>
13
- Details
14
- <% else %>
15
- Backtraces
16
- <% end %>
17
- </h2>
18
-
19
- <% if command[:type] == 'command' %>
20
- <%== partial 'commands/command_details', locals: { command: command } %>
21
- <% else %>
22
- <% command[:result].each_value do |backtrace| %>
23
- <%== partial 'commands/backtrace', locals: { backtrace: backtrace } %>
24
- <% end %>
25
- <% end %>
26
- <% else %>
27
- <% view_title 'Incompatible Command Schema' %>
28
-
29
- <%== partial 'consumers/tabs' %>
30
-
31
- <%== partial 'commands/incompatible_schema' %>
32
- <% end %>
33
- </div>
@@ -1,55 +0,0 @@
1
- <li>
2
- <a href="<%= root_path('consumers/overview') %>">
3
- Consumers
4
- </a>
5
- </li>
6
-
7
- <% if current_path.include?('/performance') %>
8
- <li>
9
- <a href="<%= root_path('consumers', 'performance') %>">
10
- Performance
11
- </a>
12
- </li>
13
- <% end %>
14
-
15
- <% if current_path.include?('/controls') %>
16
- <li>
17
- <a href="<%= root_path('consumers', 'controls') %>">
18
- Controls
19
- </a>
20
- </li>
21
- <% end %>
22
-
23
- <% if @process %>
24
- <li>
25
- <a href="<%= root_path('consumers', @process.id, 'subscriptions') %>">
26
- <%== truncate(@process.id, strategy: :middle) %>
27
- </a>
28
- </li>
29
-
30
- <% if current_path.include?('/jobs') %>
31
- <li>
32
- <a href="<%= root_path('consumers', @process.id, 'jobs') %>">
33
- Jobs
34
- </a>
35
- </li>
36
-
37
- <li>
38
- <a href="<%= root_path('consumers', @process.id, 'jobs') %>">
39
- Running
40
- </a>
41
- </li>
42
- <% elsif current_path.include?('/subscriptions') %>
43
- <li>
44
- <a href="<%= root_path('consumers', @process.id, 'subscriptions') %>">
45
- Subscriptions
46
- </a>
47
- </li>
48
- <% else %>
49
- <li>
50
- <a href="<%= root_path('consumers', @process.id, 'details') %>">
51
- Details
52
- </a>
53
- </li>
54
- <% end %>
55
- <% end %>
@@ -1,33 +0,0 @@
1
- <div class="tab-container-wrapper">
2
- <div class="tab-container">
3
- <a
4
- href="<%= root_path('consumers', 'overview') %>"
5
- class="custom-tab <%= nav_class(include: 'overview') %>"
6
- >
7
- Overview
8
- </a>
9
-
10
- <a
11
- href="<%= root_path('consumers', 'performance') %>"
12
- class="custom-tab <%= nav_class(include: 'performance') %>"
13
- >
14
- Performance
15
- </a>
16
-
17
- <% if Karafka::Web.config.commanding.active %>
18
- <a
19
- href="<%= root_path('consumers', 'controls') %>"
20
- class="custom-tab <%= nav_class(include: 'controls') %>"
21
- >
22
- Controls
23
- </a>
24
-
25
- <a
26
- href="<%= root_path('commands') %>"
27
- class="custom-tab <%= nav_class(include: 'commands') %>"
28
- >
29
- Commands
30
- </a>
31
- <% end %>
32
- </div>
33
- </div>