diff --git a/CHANGELOG.md b/CHANGELOG.md index c2756048..987cd4a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## 0.8.2 (Unreleased) - [Enhancement] Defer scheduler background thread creation until needed allowing for forks. +- [Fix] Rebalance reason can be empty on a SG when no network. ## 0.8.1 (2024-02-01) - [Enhancement] Introduce "Lags" health view. diff --git a/lib/karafka/web/tracking/consumers/contracts/subscription_group.rb b/lib/karafka/web/tracking/consumers/contracts/subscription_group.rb index f5322ddd..8a82a378 100644 --- a/lib/karafka/web/tracking/consumers/contracts/subscription_group.rb +++ b/lib/karafka/web/tracking/consumers/contracts/subscription_group.rb @@ -19,7 +19,7 @@ class SubscriptionGroup < Web::Contracts::Base required(:stateage) { |val| val.is_a?(Integer) && val >= 0 } required(:rebalance_age) { |val| val.is_a?(Integer) && val >= 0 } required(:rebalance_cnt) { |val| val.is_a?(Integer) && val >= 0 } - required(:rebalance_reason) { |val| val.is_a?(String) && !val.empty? } + required(:rebalance_reason) { |val| val.is_a?(String) } required(:poll_age) { |val| val.is_a?(Numeric) && val >= 0 } end diff --git a/lib/karafka/web/ui/pro/views/consumers/consumer/_subscription_group.erb b/lib/karafka/web/ui/pro/views/consumers/consumer/_subscription_group.erb index a3e5dde5..17ec0267 100644 --- a/lib/karafka/web/ui/pro/views/consumers/consumer/_subscription_group.erb +++ b/lib/karafka/web/ui/pro/views/consumers/consumer/_subscription_group.erb @@ -76,7 +76,13 @@ - Last rebalance reason: <%= subscription_group.rebalance_reason %> + Last rebalance reason: + + <% if subscription_group.rebalance_reason.empty? %> + Unknown + <% else %> + <%= subscription_group.rebalance_reason %> + <% end %> diff --git a/spec/lib/karafka/web/tracking/consumers/contracts/subscription_group_spec.rb b/spec/lib/karafka/web/tracking/consumers/contracts/subscription_group_spec.rb index 7501efeb..5a80bffd 100644 --- a/spec/lib/karafka/web/tracking/consumers/contracts/subscription_group_spec.rb +++ b/spec/lib/karafka/web/tracking/consumers/contracts/subscription_group_spec.rb @@ -86,10 +86,27 @@ it { expect(contract.call(subscription_group)).not_to be_success } end + context 'when rebalance_reason in state is missing' do + before { subscription_group[:state].delete(:rebalance_reason) } + + it { expect(contract.call(subscription_group)).not_to be_success } + end + + context 'when rebalance_reason is not a string' do + before { subscription_group[:state][:rebalance_reason] = rand } + + it { expect(contract.call(subscription_group)).not_to be_success } + end + + context 'when rebalance_reason is empty' do + before { subscription_group[:state][:rebalance_reason] = '' } + + it { expect(contract.call(subscription_group)).to be_success } + end + %i[ state join_state - rebalance_reason ].each do |key| context "when #{key} in state is missing" do before { subscription_group[:state].delete(key) } diff --git a/spec/lib/karafka/web/ui/pro/controllers/consumers_spec.rb b/spec/lib/karafka/web/ui/pro/controllers/consumers_spec.rb index bf4a4abe..f37871ad 100644 --- a/spec/lib/karafka/web/ui/pro/controllers/consumers_spec.rb +++ b/spec/lib/karafka/web/ui/pro/controllers/consumers_spec.rb @@ -399,6 +399,30 @@ end end + context 'when subscription has an unknown rebalance reason' do + before do + topics_config.consumers.reports = reports_topic + + report = Fixtures.consumers_reports_json(symbolize_names: true) + + sg = report[:consumer_groups][:example_app6_app][:subscription_groups][:c4ca4238a0b9_0] + sg[:state][:rebalance_reason] = '' + + produce(reports_topic, report.to_json) + + get 'consumers/1/subscriptions' + end + + it do + expect(response).to be_ok + expect(body).to include('Rebalance count:') + expect(body).to include('Unknown') + expect(body).to include('This process does not consume any') + expect(body).not_to include(pagination) + expect(body).not_to include(support_message) + end + end + context 'when subscriptions exist and was reported in a transactional fashion' do before do topics_config.consumers.states = states_topic