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
@@ -50,15 +50,17 @@ module Karafka
50
50
  # @param state [Hash]
51
51
  # @param stats [Hash] hash where we will store all the aggregated data
52
52
  def fetch_topics_data(state, stats)
53
- iterate_partitions(state) do |process, consumer_group, topic, partition|
54
- cg_name = consumer_group.id
53
+ iterate_partitions(state) do |process, consumer_group, subscription_group, topic, partition|
54
+ cg_id = consumer_group.id
55
+ sg_id = subscription_group.id
55
56
  t_name = topic.name
56
57
  pt_id = partition.id
57
58
 
58
- stats[cg_name] ||= { topics: {} }
59
- stats[cg_name][:topics][t_name] ||= {}
60
- stats[cg_name][:topics][t_name][pt_id] = partition
61
- stats[cg_name][:topics][t_name][pt_id][:process] = process
59
+ stats[cg_id] ||= { topics: {} }
60
+ stats[cg_id][:topics][t_name] ||= {}
61
+ stats[cg_id][:topics][t_name][pt_id] = partition
62
+ stats[cg_id][:topics][t_name][pt_id][:process] = process
63
+ stats[cg_id][:topics][t_name][pt_id][:subscription_group_id] = sg_id
62
64
  end
63
65
  end
64
66
 
@@ -99,7 +101,7 @@ module Karafka
99
101
  consumer_group.subscription_groups.each do |subscription_group|
100
102
  subscription_group.topics.each do |topic|
101
103
  topic.partitions.each do |partition|
102
- yield(process, consumer_group, topic, partition)
104
+ yield(process, consumer_group, subscription_group, topic, partition)
103
105
  end
104
106
  end
105
107
  end
@@ -10,13 +10,21 @@ module Karafka
10
10
  extend Lib::Paginations::Paginators
11
11
 
12
12
  class << self
13
- # Looks for a message from a given topic partition
13
+ # Looks for a message from a given topic partition. When no offsets provided, will
14
+ # raise if there is no data under the given offset. If watermarks were provided, it
15
+ # will check if this is a system entry and in such cases will return nil.
16
+ # Will always raise if request is out of range.
14
17
  #
15
18
  # @param topic_id [String]
16
19
  # @param partition_id [Integer]
17
20
  # @param offset [Integer]
21
+ # @param watermark_offsets [WatermarkOffsets, false] watermark offsets for this topic
22
+ # partition or false if not provided
23
+ # @return [Karafka::Messages::Message, nil] found message or nil in case watermark
24
+ # offsets were provided and we encountered a message matching watermarks
18
25
  # @raise [::Karafka::Web::Errors::Ui::NotFoundError] when not found
19
- def find(topic_id, partition_id, offset)
26
+ # @note If no watermark offsets provided will always raise if no message with data
27
+ def find(topic_id, partition_id, offset, watermark_offsets: false)
20
28
  message = Lib::Admin.read_topic(
21
29
  topic_id,
22
30
  partition_id,
@@ -26,6 +34,16 @@ module Karafka
26
34
 
27
35
  return message if message
28
36
 
37
+ # Not found can also occur for system entries and compacted messages.
38
+ # Since we want to know about this in some cases we handle this case and check if the
39
+ # requested offset is within the range and if so, it means it has been cleaned or
40
+ # is a system entry. In such cases we do display user an info message.
41
+ return nil if watermark_offsets &&
42
+ offset >= watermark_offsets.low &&
43
+ offset < watermark_offsets.high
44
+
45
+ # If beyond the watermark offsets, we raise 404 as user should not reach such
46
+ # non-existent messages as we cannot reason about them
29
47
  raise(
30
48
  ::Karafka::Web::Errors::Ui::NotFoundError,
31
49
  [topic_id, partition_id, offset].join(', ')
@@ -12,6 +12,8 @@ module Karafka
12
12
  # @param process_id [String] id of the process we are looking for
13
13
  # @return [Process] selected process or error raised
14
14
  # @raise [::Karafka::Web::Errors::Ui::NotFoundError] raised if process not found
15
+ # @note Keep in mind, that this search is looking only within processes with a
16
+ # compatible schema, as it uses `#active` under the hood.
15
17
  def find(state, process_id)
16
18
  found_process = Processes.active(state).find { |process| process.id == process_id }
17
19
  found_process || raise(::Karafka::Web::Errors::Ui::NotFoundError, process_id)
@@ -74,6 +76,20 @@ module Karafka
74
76
  .flat_map(&:partitions)
75
77
  .count
76
78
  end
79
+
80
+ # @return [Boolean] consumer process data is only compatible if the version of its schema
81
+ # matches the Web UI version of the schema. Some users have gradual deployment where
82
+ # they slowly rollout new versions of consumers and for this time, we want to indicate
83
+ # which instances have incompatible schema. This will allow us to show those processes
84
+ # to indicate they exist, so users are not confused with them missing, but will also
85
+ # block all capabilities until the full update of all components.
86
+ #
87
+ # @note We do not differentiate between reporting older or newer against Web UI Puma
88
+ # instance. Any incompatibility will cause reporting of incompatible. That's for the
89
+ # sake of simplicity as the long term goal for user is anyhow to align those.
90
+ def schema_compatible?
91
+ self[:schema_version] == ::Karafka::Web::Tracking::Consumers::Sampler::SCHEMA_VERSION
92
+ end
77
93
  end
78
94
  end
79
95
  end
@@ -11,22 +11,30 @@ module Karafka
11
11
  class << self
12
12
  include ::Karafka::Core::Helpers::Time
13
13
 
14
- # Returns the active processes in an array and alongside of that the current state of
15
- # the system. We use those together in the UI and it would be expensive to pick it up
16
- # while we've already had it.
17
- #
14
+ # Returns processes that are running or recently shutdown. It may also return processes
15
+ # with incompatible schema.
18
16
  # @param state [State] current system state from which we can get processes metadata
19
17
  # @return [Array<Process>]
20
- def active(state)
18
+ def all(state)
21
19
  messages = fetch_reports(state)
22
20
  messages = squash_processes_data(messages)
23
21
  processes = messages.map(&:payload)
24
22
  evict_expired_processes(processes)
25
23
  processes = sort_processes(processes)
26
-
27
24
  processes.map { |process_hash| Process.new(process_hash) }
28
25
  end
29
26
 
27
+ # Returns the active processes in an array and alongside of that the current state of
28
+ # the system. We use those together in the UI and it would be expensive to pick it up
29
+ # while we've already had it. Active means it is running (or recently shutdown) and
30
+ # it has current schema. Basically any process about which we can reason
31
+ #
32
+ # @param state [State] current system state from which we can get processes metadata
33
+ # @return [Array<Process>]
34
+ def active(state)
35
+ all(state).delete_if { |process| !process.schema_compatible? }
36
+ end
37
+
30
38
  private
31
39
 
32
40
  # Fetches the relevant processes reports from the reports topic
@@ -45,7 +53,7 @@ module Karafka
45
53
  .sort
46
54
 
47
55
  Lib::Admin.read_topic(
48
- ::Karafka::Web.config.topics.consumers.reports,
56
+ ::Karafka::Web.config.topics.consumers.reports.name,
49
57
  0,
50
58
  # We set 10k here because we start from the latest offset of the reports, hence
51
59
  # we will never get this much. Do do not know however exactly how many reports
@@ -79,11 +87,24 @@ module Karafka
79
87
  end
80
88
  end
81
89
 
90
+ # Removes processes that have schema different than the one supported by the Web UI
91
+ # We support incompatible schema processes reporting in the status page so users know
92
+ # what and how to update. For other processes we do not display them or their data
93
+ # as it would be too complex to support
94
+ #
95
+ # @param processes [Array<Hash>]
96
+ # @return [Array<Hash>] only data about processes running current schema
97
+ def evict_incompatible_processes(processes)
98
+ processes.delete_if do |details|
99
+ details[:schema_version] != Tracking::Consumers::Sampler::SCHEMA_VERSION
100
+ end
101
+ end
102
+
82
103
  # Ensures that we always return processes sorted by their id
83
104
  # @param processes [Array<Hash>]
84
105
  # @return [Array<Hash>] sorted processes data
85
106
  def sort_processes(processes)
86
- processes.sort_by { |consumer| consumer[:process][:id] }
107
+ processes.sort_by { |consumer| consumer[:process].fetch(:id) }
87
108
  end
88
109
  end
89
110
  end
@@ -22,7 +22,7 @@ module Karafka
22
22
  # get it because requested topic/partition does not exist or nothing was present
23
23
  def current
24
24
  messages = Karafka::Admin.read_topic(
25
- config.topics.schedules,
25
+ config.topics.schedules.name,
26
26
  0,
27
27
  # We work here with the assumption that users won't click so fast to load
28
28
  # more than 20 commands prior to a state flush. If that happens, this will
@@ -16,7 +16,7 @@ module Karafka
16
16
  Step = Struct.new(:status, :details) do
17
17
  # @return [Boolean] is the given step successfully configured and working
18
18
  def success?
19
- status == :success || status == :warning
19
+ %i[success warning].include?(status)
20
20
  end
21
21
 
22
22
  # @return [String] local namespace for partial of a given type
@@ -183,7 +183,7 @@ module Karafka
183
183
  # @return [Status::Step] could we read and operate on the current processes data (if any)
184
184
  def consumers_reports
185
185
  if initial_consumers_metrics.success?
186
- @processes ||= Models::Processes.active(@current_state)
186
+ @processes ||= Models::Processes.all(@current_state)
187
187
  status = :success
188
188
  else
189
189
  status = :halted
@@ -209,6 +209,27 @@ module Karafka
209
209
  )
210
210
  end
211
211
 
212
+ # @return [Status::Step] are there any consumer processes with incompatible schema that
213
+ # does not match exactly the one used by the Web UI.
214
+ #
215
+ # @note It issues a warning, not an error.
216
+ def consumers_schemas
217
+ details = { incompatible: [] }
218
+
219
+ status = if consumers_reports.success?
220
+ incompatible = @processes.reject(&:schema_compatible?)
221
+ details[:incompatible] = incompatible
222
+ incompatible.empty? ? :success : :warning
223
+ else
224
+ :halted
225
+ end
226
+
227
+ Step.new(
228
+ status,
229
+ details
230
+ )
231
+ end
232
+
212
233
  # @return [Status::Step] Is there a significant lag in the reporting of aggregated data
213
234
  # back to the Kafka. If yes, it means that the results in the Web UI will be delayed
214
235
  # against the reality. Often it means, that there is over-saturation on the consumer
@@ -307,22 +328,22 @@ module Karafka
307
328
 
308
329
  # @return [String] consumers states topic name
309
330
  def topics_consumers_states
310
- ::Karafka::Web.config.topics.consumers.states.to_s
331
+ ::Karafka::Web.config.topics.consumers.states.name.to_s
311
332
  end
312
333
 
313
334
  # @return [String] consumers reports topic name
314
335
  def topics_consumers_reports
315
- ::Karafka::Web.config.topics.consumers.reports.to_s
336
+ ::Karafka::Web.config.topics.consumers.reports.name.to_s
316
337
  end
317
338
 
318
339
  # @return [String] consumers metrics topic name
319
340
  def topics_consumers_metrics
320
- ::Karafka::Web.config.topics.consumers.metrics.to_s
341
+ ::Karafka::Web.config.topics.consumers.metrics.name.to_s
321
342
  end
322
343
 
323
344
  # @return [String] errors topic name
324
345
  def topics_errors
325
- ::Karafka::Web.config.topics.errors
346
+ ::Karafka::Web.config.topics.errors.name
326
347
  end
327
348
 
328
349
  # @return [Hash] hash with topics with which we work details (even if don't exist)
@@ -355,9 +376,7 @@ module Karafka
355
376
  # @note If fails, `connection_time` will be 1_000_000
356
377
  def connect
357
378
  started = Time.now.to_f
358
- # For status we always need uncached data, otherwise status could cache outdated
359
- # info
360
- @cluster_info = Models::ClusterInfo.fetch(cached: false)
379
+ @cluster_info = Models::ClusterInfo.fetch
361
380
  @connection_time = (Time.now.to_f - started) * 1_000
362
381
  rescue ::Rdkafka::RdkafkaError
363
382
  @connection_time = 1_000_000
@@ -20,7 +20,7 @@ module Karafka
20
20
  # @return [Topic]
21
21
  # @raise [::Karafka::Web::Errors::Ui::NotFoundError]
22
22
  def find(topic_name)
23
- found = all.find { |topic| topic.topic_name == topic_name }
23
+ found = ClusterInfo.topic(topic_name)
24
24
 
25
25
  return found if found
26
26
 
@@ -56,7 +56,6 @@ module Karafka
56
56
  # aggregated statistics and then the second value is an array with per partition data
57
57
  def distribution(partitions)
58
58
  sum = 0.0
59
- avg = 0.0
60
59
 
61
60
  counts = partitions.map do |partition_id|
62
61
  offsets = Admin.read_watermark_offsets(topic_name, partition_id)
@@ -1,121 +1,31 @@
1
- // Nicer display of time distance from a given event
2
- function updateTimeAgo() {
3
- var selection = document.querySelectorAll('time');
4
-
5
- if (selection.length != 0) {
6
- timeago.render(selection);
7
- timeago.cancel()
8
- }
9
-
10
- var selection = document.getElementsByClassName('time-title')
11
- var title = null
12
-
13
- for (var i = 0; i < selection.length; i++) {
14
- let element = selection[i]
15
-
16
- title = element.getAttribute('title')
17
- element.setAttribute('title', timeago.format(title))
18
- }
19
- }
20
-
21
- // Cheap way to do breadcrumbs
22
- function refreshTitle() {
23
- const breadcrumbs = document.querySelectorAll('.breadcrumbs a');
24
- let breadcrumbTexts = Array.from(breadcrumbs).slice(1).map(crumb => crumb.textContent.trim());
25
-
26
- if (breadcrumbTexts.length > 0) {
27
- document.title = breadcrumbTexts.join(' > ') + ' - Karafka Web UI';
28
- } else {
29
- document.title = 'Karafka Web UI';
30
- }
31
- }
32
-
33
- // When using explorer, we can select the desired partition. This code redirects without having
34
- // to press a button after a select
35
- function redirectToPartition() {
36
- var selector = document.getElementById('current-partition');
37
-
38
- if (selector == null) { return }
39
-
40
- selector.addEventListener('change', function(){
41
- Turbo.visit(this.value);
42
- });
43
- }
44
-
45
- // Binds to links and forms to make sure action is what user wants
46
- function bindActionsConfirmations() {
47
- var elements = document.getElementsByClassName('confirm-action')
48
- var confirmation = 'Are you sure?'
49
-
50
- for (var i = 0; i < elements.length; i++) {
51
- let element = elements[i]
52
- let action = 'click'
53
-
54
- if (element.nodeName === 'FORM') {
55
- action = 'submit'
56
- }
57
-
58
- element.addEventListener(action, function(event) {
59
- if (!window.confirm(confirmation)) {
60
- event.preventDefault();
61
- }
62
- })
63
- }
64
- }
65
-
66
- function bindLockableButtons() {
67
- document.querySelectorAll('.btn-lockable').forEach(function(button) {
68
- button.addEventListener('click', function(event) {
69
- // Find the form element the button is within
70
- const form = button.closest('form');
71
-
72
- // If the button is part of a form, add a submit event listener to the form
73
- if (form) {
74
- form.addEventListener('submit', function() {
75
- button.disabled = true;
76
- button.textContent += '...';
77
- // also lock any modal that is open as the form is submitted
78
- var modals = document.querySelectorAll('.modal');
79
-
80
- // Add 'modal-locked' class to each modal
81
- modals.forEach(function (modal) {
82
- modal.classList.add('modal-locked');
83
- });
84
- }, { once: true });
85
- } else {
86
- // If the button is not part of a form, disable it immediately
87
- button.disabled = true;
88
- button.textContent += '...';
89
- }
90
- });
91
- });
92
- }
93
-
94
1
  function addListeners() {
95
2
  initLivePolling();
96
3
  bindPollingButtonClick();
97
- bindLockableButtons();
98
4
  setLivePollButton();
99
5
  setPollingListener();
100
6
 
101
7
  hljs.highlightAll();
102
- updateTimeAgo();
103
- redirectToPartition();
8
+ new TimeAgoManager();
9
+ new PartitionRedirectManager();
104
10
 
105
11
  const tabsManager = new TabsManager();
106
12
  tabsManager.manageTabs();
107
13
 
108
14
  manageCharts();
109
- bindActionsConfirmations();
110
15
  loadOffsetLookupDatePicker();
111
16
 
112
17
  new BtnToggleManager();
113
18
  new BtnToggleManager('.btn-toggle-nav-collapsed', 'collapsed');
114
19
  new ThemeManager();
115
20
 
116
- refreshTitle()
21
+ new ButtonLockManager();
22
+ new ActionConfirmationManager();
23
+ new PageTitleTracker();
117
24
  new SearchMetadataVisibilityManager();
118
25
  new SearchModalManager();
26
+ new TimestampSelector();
27
+ new AlertsManager();
28
+ new MessageRepublishManager();
119
29
  }
120
30
 
121
31
  document.addEventListener('turbo:load', addListeners);