Skip to content

Commit

Permalink
support routing patterns discovery in web-ui
Browse files Browse the repository at this point in the history
  • Loading branch information
mensfeld committed Sep 1, 2023
1 parent 7ea6898 commit f7761cf
Show file tree
Hide file tree
Showing 10 changed files with 170 additions and 6 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- **[Feature]** Introduce `bundle exec karafka-web migrate` that can be used to bootstrap the proper topics and initial data in environments where Karafka Web-UI should be used but is missing the initial setup.
- **[Feature]** Replace `decrypt` with a pluggable API for deciding which topics data to display.
- **[Feature]** Make sure, that the karafka server process that is materializing UI states is not processing any data having unsupported (newer) schemas. This state will be also visible in the status page.
- [Improvement] Support pattern subscriptions details in the routing view both by displaying the pattern as well as expanded routing details.
- [Improvement] Collect total number of threads per process for the process details view.
- [Improvement] Normalize naming of metrics to better reflect what they do (in reports and in the Web UI).
- [Improvement] Link error reported first and last offset to the explorer.
Expand Down Expand Up @@ -59,7 +60,7 @@
- [Refactor] Limit usage of UI models for data intense computation to speed up states materialization under load.
- [Refactor] Reorganize pagination engine to support offset based pagination.
- [Refactor] Use Roda `custom_block_results` plugin for controllers results handling.
- [Maintenance] Require `karafka` `2.1.8` due to fixes in the Iterator API and routing API extensions.
- [Maintenance] Require `karafka` `2.2.0` due to fixes in the Iterator API and routing API extensions.

### Upgrade Notes

Expand Down
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ PATH
specs:
karafka-web (0.7.0)
erubi (~> 1.4)
karafka (>= 2.1.13, < 3.0.0)
karafka (>= 2.2.0, < 3.0.0)
karafka-core (>= 2.0.13, < 3.0.0)
roda (~> 3.68, >= 3.69)
tilt (~> 2.0)
Expand All @@ -26,7 +26,7 @@ GEM
ffi (1.15.5)
i18n (1.14.1)
concurrent-ruby (~> 1.0)
karafka (2.1.13)
karafka (2.2.0)
karafka-core (>= 2.1.1, < 2.2.0)
thor (>= 0.20)
waterdrop (>= 2.6.6, < 3.0.0)
Expand Down
2 changes: 1 addition & 1 deletion karafka-web.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
spec.licenses = %w[LGPL-3.0 Commercial]

spec.add_dependency 'erubi', '~> 1.4'
spec.add_dependency 'karafka', '>= 2.1.13', '< 3.0.0'
spec.add_dependency 'karafka', '>= 2.2.0', '< 3.0.0'
spec.add_dependency 'karafka-core', '>= 2.0.13', '< 3.0.0'
spec.add_dependency 'roda', '~> 3.68', '>= 3.69'
spec.add_dependency 'tilt', '~> 2.0'
Expand Down
44 changes: 44 additions & 0 deletions lib/karafka/web/ui/pro/controllers/routing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,50 @@ module Pro
module Controllers
# Routing details - same as in OSS
class Routing < Ui::Controllers::Routing
# Routing list
def index
detect_patterns_routes

@routes = Karafka::App.routes

respond
end

# Given route details
#
# @param topic_id [String] topic id
def show(topic_id)
detect_patterns_routes

@topic = Karafka::Routing::Router.find_by(id: topic_id)

@topic || raise(::Karafka::Web::Errors::Ui::NotFoundError, topic_id)

respond
end

private

# Checks list of topics and tries to match them against the available patterns
# Uses the Pro detector to expand routes in the Web-UI so we include topics that are
# or will be matched using our regular expressions
def detect_patterns_routes
detector = ::Karafka::Pro::Routing::Features::Patterns::Detector.new
topics_names = Models::ClusterInfo.topics.map(&:topic_name)

Karafka::App
.routes
.flat_map(&:subscription_groups)
.each do |subscription_group|
sg_topics = subscription_group.topics

# Reject topics that are already part of routing for given subscription groups
# and then for remaining try to apply patterns and expand routes
topics_names
.reject { |t_name| sg_topics.any? { |rtopic| rtopic.name == t_name } }
.each { |t_name| detector.expand(sg_topics, t_name) }
end
end
end
end
end
Expand Down
35 changes: 35 additions & 0 deletions lib/karafka/web/ui/pro/views/routing/_consumer_group.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<div class="row mb-4">
<div class="col-sm-12">
<h4 class="mb-2">
<%= consumer_group.id %>
</h4>
<hr/>
</div>
</div>

<div class="row mb-5">
<div class="col-sm-12">
<table class="processes bg-white table table-hover table-bordered table-striped mb-0 align-middle">
<thead>
<tr class="align-middle">
<th>Subscription group</th>
<th>Topic</th>
<th>Type</th>
<th>Active</th>
<th></th>
</tr>
</thead>
<tbody>
<% consumer_group.subscription_groups.each do |subscription_group| %>
<%==
each_partial(
subscription_group.topics,
'routing/topic',
locals: { subscription_group: subscription_group }
)
%>
<% end %>
</tbody>
</table>
</div>
</div>
25 changes: 25 additions & 0 deletions lib/karafka/web/ui/pro/views/routing/_detail.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<% if v.is_a?(Hash) || v.respond_to?(:to_h) %>
<% v.to_h.each do |k2, v2| %>
<tr>
<td>
<%= "#{k}.#{k2}" %>
</td>
<td>
<% if %w[sasl ssl].any? { |scope| k2.to_s.include?(scope) } %>
***
<% else %>
<%= v2 %>
<% end %>
</td>
</tr>
<% end %>
<% else %>
<tr>
<td>
<%= k %>
</td>
<td>
<%= object_value_to_s(v) %>
</td>
</tr>
<% end %>
23 changes: 23 additions & 0 deletions lib/karafka/web/ui/pro/views/routing/_topic.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<tr>
<td>
<%= subscription_group.id %>
</td>
<td>
<%= topic.name %>
</td>
<td>
<span class="badge bg-secondary">
<%= topic.patterns.type %>
</span>
</td>
<td>
<span class="badge bg-<%= topic.active? ? 'success' : 'warning text-dark' %>">
<%= topic.active? %>
</span>
</td>
<td class="text-center">
<a href="<%= root_path('routing', topic.id) %>" class="btn btn-sm btn-secondary text-white">
Details
</a>
</td>
</tr>
10 changes: 10 additions & 0 deletions lib/karafka/web/ui/pro/views/routing/index.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<%== view_title('Routing details') %>

<div class="container mb-5">
<%==
each_partial(
@routes,
'routing/consumer_group'
)
%>
</div>
26 changes: 26 additions & 0 deletions lib/karafka/web/ui/pro/views/routing/show.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<%==
title = [@topic.consumer_group.name, @topic.subscription_group, @topic.name].join(': ')
view_title(title, hr: true)
%>

<div class="container">
<div class="row mb-5">
<div class="col-sm-12">
<table class="processes bg-white table table-hover table-bordered table-striped mb-0 align-middle">
<tbody>
<% flat_hash(@topic.to_h).each do |k, v| %>
<%==
partial(
'routing/detail',
locals: {
k: k,
v: v
}
)
%>
<% end %>
</tbody>
</table>
</div>
</div>
</div>
4 changes: 2 additions & 2 deletions lib/karafka/web/ui/views/routing/_detail.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<% if v.is_a?(Hash) %>
<% v.each do |k2, v2| %>
<% if v.is_a?(Hash) || v.respond_to?(:to_h) %>
<% v.to_h.each do |k2, v2| %>
<tr>
<td>
<%= "#{k}.#{k2}" %>
Expand Down

0 comments on commit f7761cf

Please sign in to comment.