This is an automated email from the ASF dual-hosted git repository.

lizhimins pushed a commit to branch rocketmq-studio
in repository https://gitbox.apache.org/repos/asf/rocketmq-dashboard.git


The following commit(s) were added to refs/heads/rocketmq-studio by this push:
     new a873c713 fix(alerts): use existence-checked updates for bulk rule 
toggles (#2112)
a873c713 is described below

commit a873c713cb0112f512898617f1728ebb5ecea77e
Author: lizhimins <[email protected]>
AuthorDate: Thu Aug 13 19:11:08 2026 +0800

    fix(alerts): use existence-checked updates for bulk rule toggles (#2112)
    
    bulkToggleRules previously used the upsert-style saveRule, so a rule
    deleted between the snapshot load and the update was silently
    recreated. Switch to replaceRule, which performs an existence-checked
    update and reports concurrently deleted rules as failures, and add a
    regression test covering that scenario.
---
 .../rocketmq/studio/ops/alert/AlertService.java       | 11 ++++++++---
 .../rocketmq/studio/ops/alert/AlertServiceTest.java   | 19 ++++++++++++++++---
 2 files changed, 24 insertions(+), 6 deletions(-)

diff --git 
a/server/src/main/java/org/apache/rocketmq/studio/ops/alert/AlertService.java 
b/server/src/main/java/org/apache/rocketmq/studio/ops/alert/AlertService.java
index 833531ca..79b03d12 100644
--- 
a/server/src/main/java/org/apache/rocketmq/studio/ops/alert/AlertService.java
+++ 
b/server/src/main/java/org/apache/rocketmq/studio/ops/alert/AlertService.java
@@ -160,10 +160,15 @@ public class AlertService {
             }
             try {
                 rule.setEnabled(enabled);
-                AlertRuleVO saved = alertRepository.saveRule(rule);
-                auditRule("TOGGLE_ALERT_RULE", saved, "enabled=" + enabled + 
", bulk=true");
+                // replaceRule performs an existence-checked update; a rule 
deleted between the
+                // snapshot load and this call is reported as a failure 
instead of being recreated.
+                if (!alertRepository.replaceRule(rule)) {
+                    failures.put(id, "Alert rule not found");
+                    continue;
+                }
+                auditRule("TOGGLE_ALERT_RULE", rule, "enabled=" + enabled + ", 
bulk=true");
                 succeeded.add(id);
-                updated.add(saved);
+                updated.add(rule);
             } catch (RuntimeException failure) {
                 failures.put(id, failure.getMessage() == null ? "Update 
failed" : failure.getMessage());
             }
diff --git 
a/server/src/test/java/org/apache/rocketmq/studio/ops/alert/AlertServiceTest.java
 
b/server/src/test/java/org/apache/rocketmq/studio/ops/alert/AlertServiceTest.java
index d46c8979..3c17f0c3 100644
--- 
a/server/src/test/java/org/apache/rocketmq/studio/ops/alert/AlertServiceTest.java
+++ 
b/server/src/test/java/org/apache/rocketmq/studio/ops/alert/AlertServiceTest.java
@@ -601,8 +601,7 @@ class AlertServiceTest {
     void bulkToggleShouldDeduplicateIdsAndReportMissingRules() {
         AlertRuleVO rule = AlertRuleVO.builder().id("rule-1").name("High 
CPU").enabled(false).build();
         when(alertRepository.findAllRules()).thenReturn(List.of(rule));
-        when(alertRepository.saveRule(any(AlertRuleVO.class)))
-                .thenAnswer(invocation -> invocation.getArgument(0));
+        
when(alertRepository.replaceRule(any(AlertRuleVO.class))).thenReturn(true);
 
         AlertRuleBulkResultVO result = alertService.bulkToggleRules(
                 List.of("rule-1", "missing", "rule-1"), true);
@@ -611,7 +610,21 @@ class AlertServiceTest {
         assertThat(result.getFailures()).containsEntry("missing", "Alert rule 
not found");
         assertThat(result.getUpdatedRules()).singleElement()
                 .extracting(AlertRuleVO::isEnabled).isEqualTo(true);
-        verify(alertRepository).saveRule(rule);
+        verify(alertRepository).replaceRule(rule);
+    }
+
+    @Test
+    void 
bulkToggleShouldReportRulesDeletedConcurrentlyInsteadOfRecreatingThem() {
+        AlertRuleVO rule = AlertRuleVO.builder().id("rule-1").name("High 
CPU").enabled(false).build();
+        when(alertRepository.findAllRules()).thenReturn(List.of(rule));
+        
when(alertRepository.replaceRule(any(AlertRuleVO.class))).thenReturn(false);
+
+        AlertRuleBulkResultVO result = 
alertService.bulkToggleRules(List.of("rule-1"), true);
+
+        assertThat(result.getSucceededIds()).isEmpty();
+        assertThat(result.getFailures()).containsEntry("rule-1", "Alert rule 
not found");
+        assertThat(result.getUpdatedRules()).isEmpty();
+        verify(alertRepository, never()).saveRule(any(AlertRuleVO.class));
     }
 
     @Test

Reply via email to