Skip to content

[ISSUE #6264]Add updateBrokerConfig admin command#6330

Merged
mxsm merged 1 commit intomxsm:mainfrom
willwang-io:issue-6264
Feb 16, 2026
Merged

[ISSUE #6264]Add updateBrokerConfig admin command#6330
mxsm merged 1 commit intomxsm:mainfrom
willwang-io:issue-6264

Conversation

@willwang-io
Copy link
Contributor

@willwang-io willwang-io commented Feb 14, 2026

Which Issue(s) This PR Fixes(Closes)

Brief Description

Introduce a broker admin subcommand for updating broker configuration on one broker or across an entire cluster.

Allow either a single key/value pair or multiple KEY=VALUE entries so operators can apply related config changes in one operation.

Validate inputs before applying updates, including empty-value checks and compatibility checks against existing value types, to reduce avoidable misconfiguration risk.

Show old and new values per broker before execution for safer change confirmation, and add rollback support for partial failures to preserve cluster consistency.

How Did You Test This Change?

Current test coverage includes:

  • Parse single update with -b/-k/-v and verify parsed entries.
  • Parse multiple updates with --clusterName + repeated --property.
  • Enforce required target args (reject missing --brokerAddr/--clusterName).
  • Reject invalid --property format (missing KEY=VALUE).
  • Reject conflicting duplicate keys with different values.
  • Validate boolean compatibility against existing values.
  • Validate numeric compatibility against existing values.

Summary by CodeRabbit

  • New Features
    • Added updateBrokerConfig CLI subcommand to modify broker configurations by broker address or cluster.
    • Supports single or multiple key/value updates with validation and conflict detection.
    • Dry-run mode showing per-broker planned changes and old/new diffs.
    • Interactive confirmation and optional no-rollback mode.
    • Automatic rollback on partial failures with per-broker status reporting.
    • Warnings for newly added keys that cannot be rolled back.

@rocketmq-rust-bot
Copy link
Collaborator

🔊@willwang-io 🚀Thanks for your contribution🎉!

💡CodeRabbit(AI) will review your code first🔥!

Note

🚨The code review suggestions from CodeRabbit are to be used as a reference only, and the PR submitter can decide whether to make changes based on their own judgment. Ultimately, the project management personnel will conduct the final code review💥.

@rocketmq-rust-robot rocketmq-rust-robot added Difficulty level/Moderate Moderate difficult ISSUE feature🚀 Suggest an idea for this project. labels Feb 14, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 14, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds a new CLI subcommand UpdateBrokerConfigSubCommand that parses update entries, resolves broker or cluster targets, snapshots per-broker configs, computes per-broker change plans with diffs, supports dry-run and confirmation, applies updates, and performs rollback on partial failures.

Changes

Cohort / File(s) Summary
Changelog & Registry
CHANGELOG.md, rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands.rs
Documented and registered the updateBrokerConfig CLI entry in the classification table.
Broker Commands Integration
rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/broker_commands.rs
Imported and wired UpdateBrokerConfigSubCommand; added BrokerCommands::UpdateBrokerConfigSubCommand variant and dispatch logic.
UpdateBrokerConfig Implementation
rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/broker_commands/update_broker_config_sub_command.rs
New comprehensive subcommand implementing argument parsing (broker/cluster, key/values, properties, flags), entry parsing/validation, target resolution, per-broker snapshotting, update-plan generation (ConfigChange, BrokerUpdatePlan), dry-run/print diffs, confirmation prompt, apply logic producing AppliedBrokerUpdate with rollback data, rollback behavior, helper functions, error handling, and unit tests.

Sequence Diagram(s)

sequenceDiagram
    participant User as User/CLI
    participant Cmd as UpdateBrokerConfigCmd
    participant Admin as MQAdminExt
    participant Cluster as ClusterInfo
    participant Broker as Broker(s)

    User->>Cmd: invoke (broker|cluster, key=val or properties, flags)
    Cmd->>Cmd: parse_update_entries() & validate entries
    Cmd->>Admin: resolve_targets(cluster|broker)
    Admin->>Cluster: fetch cluster info
    Cluster-->>Admin: broker list
    Admin-->>Cmd: targets

    loop per target broker
        Cmd->>Broker: fetch_broker_config_snapshot()
        Broker-->>Cmd: current config
        Cmd->>Cmd: build_update_plan(diff old vs new)
    end

    alt dry-run
        Cmd->>User: print_update_plan()
    else apply
        loop per broker plan
            Cmd->>Broker: apply updates
            Broker-->>Cmd: success + previous values
            Cmd->>Cmd: record rollback_properties
        end

        alt failure and rollback enabled
            loop applied brokers
                Cmd->>Broker: rollback_applied_updates()
                Broker-->>Cmd: restored
            end
        end
    end

    Cmd-->>User: summary, diffs, warnings
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Poem

🐰 I nibble keys and values bright,

I map the diffs beneath the night,
I hop to brokers, plans in paw,
Apply with care and rollback law,
Configs tuned — I do a joyful hop.

🚥 Pre-merge checks | ✅ 5 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding an updateBrokerConfig admin command, directly matching the primary feature in this PR.
Linked Issues check ✅ Passed The PR implements all key coding objectives from issue #6264: UpdateBrokerConfigSubCommand module, value validation, target resolution, dry-run/rollback support, and comprehensive tests.
Out of Scope Changes check ✅ Passed All changes directly support the feature: new command registration, broker_commands module integration, and UpdateBrokerConfigSubCommand implementation with no unrelated modifications.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In
`@rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/broker_commands/update_broker_config_sub_command.rs`:
- Around line 424-440: The current validation in UpdateBrokerConfigSubCommand
uses old_value.parse::<u64>() before old_value.parse::<i64>(), which causes
positive old values to be treated as unsigned and wrongly reject valid signed
new_value like "-1"; change the integer validation order to try parse::<i64>()
first (treat integers as signed by default) and only if that fails then try
parse::<u64>() (or alternatively attempt i64 for both old and new and only
enforce u64 if the old value is too large for i64), updating the branches that
call old_value.parse::<u64>() and old_value.parse::<i64>() so that
parse::<i64>() is evaluated before parse::<u64>() when deciding whether to error
on new_value.
- Around line 306-351: After printing the plan in
UpdateBrokerConfigSubCommand::execute (print_update_plan(&plans)), add an
interactive confirmation step that asks the operator to proceed (unless
self.dry_run is true or a skip-confirmation flag is set); if the user declines,
return early without calling apply_update_plans(&default_mqadmin_ext, &plans).
Implement the prompt by reading from stdin (or checking an existing skip/yes
boolean field on the struct) and only call apply_update_plans when the response
is an affirmative answer; ensure the prompt and early-return logic live between
the print_update_plan and apply_update_plans calls so changes are applied only
after explicit confirmation.
🧹 Nitpick comments (3)
CHANGELOG.md (1)

13-13: Missing issue reference in changelog entry.

Other entries in the changelog link to their tracking issue (e.g., (#5650)). Consider appending ([#6264](https://github.com/mxsm/rocketmq-rust/issues/6264)) for traceability.

rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/broker_commands/update_broker_config_sub_command.rs (2)

543-645: Good test coverage for parsing and validation.

Tests cover single/multi parsing, missing target rejection, invalid property format, conflicting duplicates, and type compatibility checks. Consider adding edge-case tests for:

  • Empty value ("key=")
  • Whitespace-only value ("key= ")
  • Keys with whitespace

319-325: Consider logging the start error's original cause.

The map_err wraps the original error e via format!, which relies on the error's Display impl. This is fine, but if e has a chain of causes, they may be lost. This is consistent with other error handling in this file, so no action needed unless there's a project-wide strategy for structured errors.

Copy link
Collaborator

@rocketmq-rust-bot rocketmq-rust-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - All CI checks passed ✅

Copy link
Collaborator

@rocketmq-rust-bot rocketmq-rust-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - All CI checks passed ✅

Copy link
Owner

@mxsm mxsm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@willwang-io pls fix conflicts

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In
`@rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/broker_commands/update_broker_config_sub_command.rs`:
- Around line 204-225: The validation error from validate_update_value inside
the per-broker mapping is propagated without broker context; change the call so
any Err is wrapped with the broker address before returning from the closure (so
callers know which broker caused the failure). Concretely, in the closure that
builds BrokerUpdatePlan (iterating targets.zip(config) and using
update_entries/current), replace the plain validate_update_value(...) ?
propagation with an error wrap that includes broker_addr (e.g., using
Result::map_err or anyhow::Context) so the returned Err contains a message like
"broker <broker_addr>: <original error>" while leaving the rest of the
change-collection logic (ConfigChange, BrokerUpdatePlan) intact.
🧹 Nitpick comments (1)
rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/broker_commands/update_broker_config_sub_command.rs (1)

279-306: Minor: "rollback succeeded for 0 brokers" message when the first broker fails.

If the very first broker in the plan fails, applied_updates is empty. The rollback returns no failures, so line 294 fires with the message "Automatic rollback succeeded for 0 previously updated broker(s)." — technically correct but potentially confusing. Consider skipping the rollback message when there's nothing to roll back.

Suggested fix
+                    if applied_updates.is_empty() {
+                        return Err(RocketMQError::Internal(base_error));
+                    }
+
                     let rollback_failures = rollback_applied_updates(admin_ext, &applied_updates).await;

@willwang-io willwang-io force-pushed the issue-6264 branch 2 times, most recently from 3fd1604 to bae016a Compare February 15, 2026 02:19
@codecov
Copy link

codecov bot commented Feb 15, 2026

Codecov Report

❌ Patch coverage is 37.31020% with 289 lines in your changes missing coverage. Please review.
✅ Project coverage is 42.42%. Comparing base (1f8ec58) to head (c4c4050).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...roker_commands/update_broker_config_sub_command.rs 37.80% 283 Missing ⚠️
...rocketmq-admin/rocketmq-admin-core/src/commands.rs 0.00% 5 Missing ⚠️
...ocketmq-admin-core/src/commands/broker_commands.rs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6330      +/-   ##
==========================================
- Coverage   42.44%   42.42%   -0.03%     
==========================================
  Files         917      918       +1     
  Lines      128579   129040     +461     
==========================================
+ Hits        54577    54746     +169     
- Misses      74002    74294     +292     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@mxsm mxsm changed the title ISSUE #6264: Add updateBrokerConfig admin command [ISSUE #6264]Add updateBrokerConfig admin command Feb 15, 2026
Copy link
Owner

@mxsm mxsm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@willwang-io pls fix conflicts,

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In
`@rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/broker_commands/update_broker_config_sub_command.rs`:
- Around line 424-453: The current validate_update_value function allows
replacing a float config with a non-numeric string because it only checks i64
integer compatibility; update validate_update_value so after checking
parse_bool(old_value) you also attempt to parse old_value as i64 first and if
that fails attempt parse as f64 (e.g., old_value.parse::<f64>()), and if
old_value is a float but new_value.parse::<f64>() fails then return the same
RocketMQError::IllegalArgument describing the type mismatch; reference the
validate_update_value function and the existing parse_bool and
old_value.parse::<i64>() checks and insert the f64 compatibility branch to
enforce numeric (float) type safety.
🧹 Nitpick comments (1)
rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/broker_commands/update_broker_config_sub_command.rs (1)

569-692: Good test coverage — consider adding a few edge cases.

The existing tests cover the core parsing and validation scenarios well. A couple of additional cases worth considering:

  • A property with an = in the value portion (e.g., --property "key=val=ue") to verify split_once('=') handles it correctly (it should, since split_once splits on the first =).
  • A test for validate_update_value with a float old value to document expected behavior.

These are optional additions.

Comment on lines 424 to 453
fn validate_update_value(key: &str, new_value: &str, old_value: Option<&str>) -> RocketMQResult<()> {
if new_value.trim().is_empty() {
return Err(RocketMQError::IllegalArgument(format!(
"UpdateBrokerConfigSubCommand: Config value for key '{}' cannot be empty",
key
)));
}
if new_value.contains('\n') || new_value.contains('\r') {
return Err(RocketMQError::IllegalArgument(format!(
"UpdateBrokerConfigSubCommand: Config value for key '{}' cannot contain line breaks",
key
)));
}

if let Some(old_value) = old_value {
if parse_bool(old_value).is_some() && parse_bool(new_value).is_none() {
return Err(RocketMQError::IllegalArgument(format!(
"UpdateBrokerConfigSubCommand: Config key '{}' expects boolean value, old='{}', new='{}'",
key, old_value, new_value
)));
} else if old_value.parse::<i64>().is_ok() && new_value.parse::<i64>().is_err() {
return Err(RocketMQError::IllegalArgument(format!(
"UpdateBrokerConfigSubCommand: Config key '{}' expects integer, old='{}', new='{}'",
key, old_value, new_value
)));
}
}

Ok(())
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Type compatibility check doesn't cover floating-point config values.

If a broker config key currently holds a float (e.g., "0.95"), the i64 parse of old_value will fail, so the numeric guard is skipped entirely. A user could then set it to "hello" without a type-mismatch error.

This is a minor gap since most broker configs are booleans, integers, or strings, but adding an f64 fallback would make the validation more robust.

Suggested enhancement
         } else if old_value.parse::<i64>().is_ok() && new_value.parse::<i64>().is_err() {
             return Err(RocketMQError::IllegalArgument(format!(
                 "UpdateBrokerConfigSubCommand: Config key '{}' expects integer, old='{}', new='{}'",
                 key, old_value, new_value
             )));
+        } else if old_value.parse::<f64>().is_ok() && new_value.parse::<f64>().is_err() {
+            return Err(RocketMQError::IllegalArgument(format!(
+                "UpdateBrokerConfigSubCommand: Config key '{}' expects numeric value, old='{}', new='{}'",
+                key, old_value, new_value
+            )));
         }
🤖 Prompt for AI Agents
In
`@rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/commands/broker_commands/update_broker_config_sub_command.rs`
around lines 424 - 453, The current validate_update_value function allows
replacing a float config with a non-numeric string because it only checks i64
integer compatibility; update validate_update_value so after checking
parse_bool(old_value) you also attempt to parse old_value as i64 first and if
that fails attempt parse as f64 (e.g., old_value.parse::<f64>()), and if
old_value is a float but new_value.parse::<f64>() fails then return the same
RocketMQError::IllegalArgument describing the type mismatch; reference the
validate_update_value function and the existing parse_bool and
old_value.parse::<i64>() checks and insert the f64 compatibility branch to
enforce numeric (float) type safety.

Introduce a broker admin subcommand for updating broker
configuration on one broker or across an entire cluster.

Allow either a single key/value pair or multiple KEY=VALUE
entries so operators can apply related config changes in one
operation.

Validate inputs before applying updates, including empty-value
checks and compatibility checks against existing value types,
to reduce avoidable misconfiguration risk.

Show old and new values per broker before execution for safer
change confirmation, and add rollback support for partial
failures to preserve cluster consistency.
Copy link
Collaborator

@rocketmq-rust-bot rocketmq-rust-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - All CI checks passed ✅

@mxsm
Copy link
Owner

mxsm commented Feb 16, 2026

@willwang-io Thank you for your continued contributions to the RocketMQ-Rust project. Wishing you and your family a healthy and prosperous Year of the Horse this Lunar New Year's Eve! May all your endeavors be wildly successful!

Copy link
Owner

@mxsm mxsm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@mxsm mxsm merged commit db04a6a into mxsm:main Feb 16, 2026
8 of 13 checks passed
@rocketmq-rust-bot rocketmq-rust-bot added approved PR has approved and removed ready to review waiting-review waiting review this PR labels Feb 16, 2026
@willwang-io willwang-io deleted the issue-6264 branch February 16, 2026 05:52
@willwang-io
Copy link
Contributor Author

@mxsm Thank you! I'm happy to help. Wishing you a wonderful Lunar New Year and a very successful Year of the Horse!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI review first Ai review pr first approved PR has approved auto merge Difficulty level/Moderate Moderate difficult ISSUE feature🚀 Suggest an idea for this project.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature🚀] Implement UpdateBrokerConfig command in rocketmq-admin-core

4 participants