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 1e4b2211a fix(alert): reject notification claims with stale retry 
counts (#6494)
1e4b2211a is described below

commit 1e4b2211a5a665db8c44e11787d124b938e6f26e
Author: coder999o <[email protected]>
AuthorDate: Thu Oct 15 18:12:53 2026 +0800

    fix(alert): reject notification claims with stale retry counts (#6494)
---
 .../ops/alert/NotificationOutboxService.java       |   3 +-
 .../mapper/RmqAlertNotificationOutboxMapper.java   |   5 +-
 .../NotificationOutboxMapperIntegrationTest.java   | 107 ++++++++++++++++++++-
 .../ops/alert/NotificationOutboxServiceTest.java   |  35 +++----
 .../ops/alert/NotificationWebhookEncodingTest.java |   3 +-
 5 files changed, 131 insertions(+), 22 deletions(-)

diff --git 
a/server/src/main/java/org/apache/rocketmq/studio/ops/alert/NotificationOutboxService.java
 
b/server/src/main/java/org/apache/rocketmq/studio/ops/alert/NotificationOutboxService.java
index 7e16786ff..8a94ff230 100644
--- 
a/server/src/main/java/org/apache/rocketmq/studio/ops/alert/NotificationOutboxService.java
+++ 
b/server/src/main/java/org/apache/rocketmq/studio/ops/alert/NotificationOutboxService.java
@@ -320,8 +320,9 @@ public class NotificationOutboxService {
             // each claim so a row cannot be born with an already-expired 
lease.
             LocalDateTime claimStartedAt = utcNow();
             LocalDateTime claimStaleBefore = 
claimStartedAt.minus(claimTimeout);
+            int attemptCount = row.getAttemptCount() == null ? 0 : 
row.getAttemptCount();
             if (mapper.claimForDispatch(row.getId(), claimStartedAt, 
claimStaleBefore, claimStartedAt,
-                    claimToken) != 1) {
+                    claimToken, attemptCount) != 1) {
                 continue;
             }
             send(row, claimToken);
diff --git 
a/server/src/main/java/org/apache/rocketmq/studio/persistence/mapper/RmqAlertNotificationOutboxMapper.java
 
b/server/src/main/java/org/apache/rocketmq/studio/persistence/mapper/RmqAlertNotificationOutboxMapper.java
index c59e0a24d..3374c8e17 100644
--- 
a/server/src/main/java/org/apache/rocketmq/studio/persistence/mapper/RmqAlertNotificationOutboxMapper.java
+++ 
b/server/src/main/java/org/apache/rocketmq/studio/persistence/mapper/RmqAlertNotificationOutboxMapper.java
@@ -39,11 +39,12 @@ public interface RmqAlertNotificationOutboxMapper extends 
BaseMapper<RmqAlertNot
 
     @Update("UPDATE rmq_alert_notification_outbox SET status = 'SENDING', 
sending_started_at = #{claimedAt}, "
             + "claim_token = #{claimToken}, gmt_modified = #{claimedAt} "
-            + "WHERE id = #{id} AND ((status IN ('PENDING', 'RETRY_WAIT') AND 
next_attempt_at <= #{now}) "
+            + "WHERE id = #{id} AND COALESCE(attempt_count, 0) = 
#{expectedAttemptCount} "
+            + "AND ((status IN ('PENDING', 'RETRY_WAIT') AND next_attempt_at 
<= #{now}) "
             + "OR (status = 'SENDING' AND (sending_started_at IS NULL OR 
sending_started_at <= #{staleBefore})))")
     int claimForDispatch(@Param("id") Long id, @Param("now") LocalDateTime now,
             @Param("staleBefore") LocalDateTime staleBefore, 
@Param("claimedAt") LocalDateTime claimedAt,
-            @Param("claimToken") String claimToken);
+            @Param("claimToken") String claimToken, 
@Param("expectedAttemptCount") int expectedAttemptCount);
 
     // gmt_modified is set explicitly so the caller's clock wins over the 
column's
     // ON UPDATE CURRENT_TIMESTAMP default (the database session's clock).
diff --git 
a/server/src/test/java/org/apache/rocketmq/studio/ops/alert/NotificationOutboxMapperIntegrationTest.java
 
b/server/src/test/java/org/apache/rocketmq/studio/ops/alert/NotificationOutboxMapperIntegrationTest.java
index b96f8fecc..437d9df47 100644
--- 
a/server/src/test/java/org/apache/rocketmq/studio/ops/alert/NotificationOutboxMapperIntegrationTest.java
+++ 
b/server/src/test/java/org/apache/rocketmq/studio/ops/alert/NotificationOutboxMapperIntegrationTest.java
@@ -25,14 +25,30 @@ import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.test.context.bean.override.mockito.MockitoBean;
+import org.springframework.web.client.RestTemplate;
+import org.apache.rocketmq.studio.audit.OperationAuditService;
+import org.apache.rocketmq.studio.common.domain.enums.AlertLevel;
+import org.apache.rocketmq.studio.settings.GeneralSettingsVO;
+import org.apache.rocketmq.studio.settings.SettingsRepository;
 
 import java.time.LocalDateTime;
+import java.time.ZoneOffset;
 import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
+import static org.mockito.Mockito.when;
 
 @SpringBootTest(properties = {
     "studio.auth.login-required=false",
@@ -51,6 +67,95 @@ class NotificationOutboxMapperIntegrationTest {
     @Autowired
     private JdbcTemplate jdbcTemplate;
 
+    @MockitoBean
+    private NotificationOutboxService scheduledDispatcher;
+
+    @Test
+    void staleDispatchCannotOverwriteTheRetryCountTest() {
+        Long alertId = insertAlert("Stale dispatch regression", 
"stale-dispatch-" + UUID.randomUUID());
+        List<Long> alertIds = List.of(alertId);
+        RmqAlertNotificationOutboxMapper dispatcherMapper = spy(mapper);
+        SettingsRepository settings = mock(SettingsRepository.class);
+        AlertRepository alerts = mock(AlertRepository.class);
+        OperationAuditService audit = mock(OperationAuditService.class);
+        NotificationOutboxService dispatcher = new 
NotificationOutboxService(dispatcherMapper, settings,
+                mock(AlertSilenceService.class), alerts, audit, new 
RestTemplate(), () -> {
+                    throw new IllegalStateException("Simulated email failure");
+                });
+        
when(settings.loadGeneralSettings()).thenReturn(GeneralSettingsVO.builder()
+                .emailRecipients("[email protected]").build());
+        
when(alerts.findAlertById(alertId)).thenReturn(java.util.Optional.of(SystemAlertVO.builder()
+                
.id(alertId).level(AlertLevel.warning).title("Lag").description("High 
lag").build()));
+        try {
+            Long id = insertDeliveryAt(alertId, "email", "Previous failure",
+                    LocalDateTime.now(ZoneOffset.UTC).minusMinutes(1));
+            jdbcTemplate.update("UPDATE rmq_alert_notification_outbox SET 
status = 'RETRY_WAIT', "
+                    + "attempt_count = 3, next_attempt_at = ? WHERE id = ?",
+                    
MYSQL_DATE_TIME.format(LocalDateTime.now(ZoneOffset.UTC).minusMinutes(1)), id);
+            AtomicBoolean advanceOnce = new AtomicBoolean();
+            doAnswer(invocation -> {
+                List<RmqAlertNotificationOutbox> selected = 
mapper.findDispatchable(invocation.getArgument(0),
+                        invocation.getArgument(1), invocation.getArgument(2));
+                if (advanceOnce.compareAndSet(false, true)) {
+                    
assertThat(selected).extracting(RmqAlertNotificationOutbox::getAttemptCount).contains(3);
+                    // Another replica fails its fourth attempt after this 
batch was read.
+                    jdbcTemplate.update("UPDATE rmq_alert_notification_outbox 
SET attempt_count = 4, "
+                            + "last_error = 'Other replica failure' WHERE id = 
?", id);
+                }
+                return selected;
+            
}).when(dispatcherMapper).findDispatchable(any(LocalDateTime.class), 
any(LocalDateTime.class), anyInt());
+
+            dispatcher.dispatch();
+
+            RmqAlertNotificationOutbox unchanged = mapper.selectById(id);
+            assertThat(unchanged.getStatus()).isEqualTo("RETRY_WAIT");
+            assertThat(unchanged.getAttemptCount()).isEqualTo(4);
+            assertThat(unchanged.getLastError()).isEqualTo("Other replica 
failure");
+            assertThat(unchanged.getClaimToken()).isNull();
+            assertThat(unchanged.getSendingStartedAt()).isNull();
+            verifyNoInteractions(settings, alerts, audit);
+
+            dispatcher.dispatch();
+
+            RmqAlertNotificationOutbox exhausted = mapper.selectById(id);
+            assertThat(exhausted.getAttemptCount()).isEqualTo(5);
+            assertThat(exhausted.getStatus()).isEqualTo("FAILED");
+            dispatcher.dispatch();
+            verify(settings).loadGeneralSettings();
+            verify(audit).record("FAIL_ALERT_NOTIFICATION", 
"ALERT_NOTIFICATION", String.valueOf(id), null,
+                    "alertId=" + alertId + ", channel=email", "FAILED", 
"Simulated email failure");
+        } finally {
+            dispatcher.closeHeartbeatExecutor();
+            cleanup(alertIds);
+            alertMapper.deleteById(alertId);
+        }
+    }
+
+    @Test
+    void dispatchClaimStillHonorsFreshAndExpiredLeasesTest() {
+        List<Long> alertIds = List.of(ALERT_ID_BASE + 301);
+        LocalDateTime now = LocalDateTime.of(2026, 1, 1, 12, 0);
+        LocalDateTime staleBefore = now.minusMinutes(1);
+        cleanup(alertIds);
+        try {
+            insert(alertIds.get(0), "email", NotificationOutboxStatus.SENDING, 
null, now);
+            Long id = mapper.selectList(new 
QueryWrapper<RmqAlertNotificationOutbox>()
+                    .in("alert_id", alertIds)).get(0).getId();
+            jdbcTemplate.update("UPDATE rmq_alert_notification_outbox SET 
attempt_count = 2, "
+                    + "sending_started_at = ? WHERE id = ?", 
MYSQL_DATE_TIME.format(now.minusSeconds(10)), id);
+
+            assertThat(mapper.claimForDispatch(id, now, staleBefore, now, 
"new-token", 2)).isZero();
+            jdbcTemplate.update("UPDATE rmq_alert_notification_outbox SET 
sending_started_at = ? WHERE id = ?",
+                    MYSQL_DATE_TIME.format(staleBefore.minusSeconds(1)), id);
+            assertThat(mapper.claimForDispatch(id, now, staleBefore, now, 
"stale-count-token", 1)).isZero();
+            assertThat(mapper.claimForDispatch(id, now, staleBefore, now, 
"new-token", 2)).isEqualTo(1);
+            assertThat(mapper.selectById(id).getAttemptCount()).isEqualTo(2);
+            
assertThat(mapper.selectById(id).getClaimToken()).isEqualTo("new-token");
+        } finally {
+            cleanup(alertIds);
+        }
+    }
+
     @Test
     void deliveryPageFiltersSearchAndCreationTimeWithConsistentCountTest() {
         List<Long> alertIds = new ArrayList<>();
@@ -157,7 +262,7 @@ class NotificationOutboxMapperIntegrationTest {
             // whole second, so a wall-clock "now" can fall a fraction before 
the stored value.
             LocalDateTime claimNow = LocalDateTime.now().plusMinutes(1);
             assertThat(mapper.claimForDispatch(id, claimNow, 
claimNow.minusMinutes(5),
-                    claimedAt, "token-a")).isEqualTo(1);
+                    claimedAt, "token-a", 0)).isEqualTo(1);
             
assertThat(mapper.selectById(id).getGmtModified()).isEqualTo(claimedAt);
 
             assertThat(mapper.renewClaim(id, "token-a", 
renewedAt)).isEqualTo(1);
diff --git 
a/server/src/test/java/org/apache/rocketmq/studio/ops/alert/NotificationOutboxServiceTest.java
 
b/server/src/test/java/org/apache/rocketmq/studio/ops/alert/NotificationOutboxServiceTest.java
index 2e9ca586d..f7c2d390a 100644
--- 
a/server/src/test/java/org/apache/rocketmq/studio/ops/alert/NotificationOutboxServiceTest.java
+++ 
b/server/src/test/java/org/apache/rocketmq/studio/ops/alert/NotificationOutboxServiceTest.java
@@ -40,6 +40,7 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.argThat;
@@ -173,7 +174,7 @@ class NotificationOutboxServiceTest {
             when(mapper.findDispatchable(any(LocalDateTime.class), 
any(LocalDateTime.class), any(Integer.class)))
                     .thenReturn(List.of(row));
             when(mapper.claimForDispatch(any(), any(LocalDateTime.class), 
any(LocalDateTime.class),
-                    any(LocalDateTime.class), anyString())).thenReturn(0);
+                    any(LocalDateTime.class), anyString(), 
anyInt())).thenReturn(0);
 
             new NotificationOutboxService(mapper, 
mock(SettingsRepository.class), mock(AlertSilenceService.class),
                     mock(AlertRepository.class), 
mock(OperationAuditService.class)).dispatch();
@@ -241,7 +242,7 @@ class NotificationOutboxServiceTest {
         when(mapper.findDispatchable(any(LocalDateTime.class), 
any(LocalDateTime.class), any(Integer.class)))
                 .thenReturn(List.of(row));
         when(mapper.claimForDispatch(any(), any(LocalDateTime.class), 
any(LocalDateTime.class),
-                any(LocalDateTime.class), anyString())).thenReturn(1);
+                any(LocalDateTime.class), anyString(), 
anyInt())).thenReturn(1);
         LocalDateTime silenceEndsAt = LocalDateTime.now().plusHours(1);
         
when(alerts.findAlertById(9L)).thenReturn(Optional.of(SystemAlertVO.builder().id(9L).ruleId(4L)
                 .domain(AlertDomain.BUSINESS).instanceId("local").build()));
@@ -272,7 +273,7 @@ class NotificationOutboxServiceTest {
         when(mapper.findDispatchable(any(LocalDateTime.class), 
any(LocalDateTime.class), any(Integer.class)))
                 .thenReturn(List.of(row));
         when(mapper.claimForDispatch(any(), any(LocalDateTime.class), 
any(LocalDateTime.class),
-                any(LocalDateTime.class), anyString())).thenReturn(1);
+                any(LocalDateTime.class), anyString(), 
anyInt())).thenReturn(1);
         when(mapper.update(any(), any())).thenReturn(1);
         
when(alerts.findAlertById(9L)).thenReturn(Optional.of(SystemAlertVO.builder().id(9L)
                 
.level(AlertLevel.warning).title("Lag").description("high").instanceId("local")
@@ -316,7 +317,7 @@ class NotificationOutboxServiceTest {
         when(mapper.findDispatchable(any(LocalDateTime.class), 
any(LocalDateTime.class), any(Integer.class)))
                 .thenReturn(List.of(row));
         when(mapper.claimForDispatch(any(), any(LocalDateTime.class), 
any(LocalDateTime.class),
-                any(LocalDateTime.class), anyString())).thenReturn(1);
+                any(LocalDateTime.class), anyString(), 
anyInt())).thenReturn(1);
         when(mapper.update(any(), any())).thenReturn(1);
         
when(alerts.findAlertById(9L)).thenReturn(Optional.of(SystemAlertVO.builder().id(9L)
                 
.level(AlertLevel.warning).title("Lag").description("high").instanceId("local").build()));
@@ -353,7 +354,7 @@ class NotificationOutboxServiceTest {
         when(mapper.findDispatchable(any(LocalDateTime.class), 
any(LocalDateTime.class), any(Integer.class)))
                 .thenReturn(List.of(row));
         when(mapper.claimForDispatch(any(), any(LocalDateTime.class), 
any(LocalDateTime.class),
-                any(LocalDateTime.class), anyString())).thenReturn(1);
+                any(LocalDateTime.class), anyString(), 
anyInt())).thenReturn(1);
         when(mapper.update(any(), any())).thenReturn(1);
         
when(alerts.findAlertById(9L)).thenReturn(Optional.of(SystemAlertVO.builder().id(9L)
                 
.level(AlertLevel.warning).title("Lag").description("high").instanceId("local").build()));
@@ -388,7 +389,7 @@ class NotificationOutboxServiceTest {
         when(mapper.findDispatchable(any(LocalDateTime.class), 
any(LocalDateTime.class), any(Integer.class)))
                 .thenReturn(List.of(row));
         when(mapper.claimForDispatch(any(), any(LocalDateTime.class), 
any(LocalDateTime.class),
-                any(LocalDateTime.class), anyString())).thenReturn(1);
+                any(LocalDateTime.class), anyString(), 
anyInt())).thenReturn(1);
         when(mapper.update(any(), any())).thenReturn(1);
         
when(alerts.findAlertById(9L)).thenReturn(Optional.of(SystemAlertVO.builder().id(9L)
                 
.level(AlertLevel.warning).title("Lag").description("high").instanceId("local").build()));
@@ -416,7 +417,7 @@ class NotificationOutboxServiceTest {
         when(mapper.findDispatchable(any(LocalDateTime.class), 
any(LocalDateTime.class), any(Integer.class)))
                 .thenReturn(List.of(row));
         when(mapper.claimForDispatch(any(), any(LocalDateTime.class), 
any(LocalDateTime.class),
-                any(LocalDateTime.class), anyString())).thenReturn(1);
+                any(LocalDateTime.class), anyString(), 
anyInt())).thenReturn(1);
         when(mapper.update(any(), any())).thenReturn(1);
         AlertRepository alerts = mock(AlertRepository.class);
         OperationAuditService audit = mock(OperationAuditService.class);
@@ -446,7 +447,7 @@ class NotificationOutboxServiceTest {
         when(mapper.findDispatchable(any(LocalDateTime.class), 
any(LocalDateTime.class), any(Integer.class)))
                 .thenReturn(List.of(row));
         when(mapper.claimForDispatch(any(), any(LocalDateTime.class), 
any(LocalDateTime.class),
-                any(LocalDateTime.class), anyString())).thenReturn(1);
+                any(LocalDateTime.class), anyString(), 
anyInt())).thenReturn(1);
         when(mapper.update(any(), any())).thenReturn(1);
         
when(alerts.findAlertById(9L)).thenReturn(Optional.of(SystemAlertVO.builder().id(9L)
                 
.level(AlertLevel.warning).title("Lag").description("high").instanceId("local").build()));
@@ -475,13 +476,13 @@ class NotificationOutboxServiceTest {
         when(mapper.findDispatchable(any(LocalDateTime.class), 
any(LocalDateTime.class), any(Integer.class)))
                 .thenReturn(List.of(row));
         when(mapper.claimForDispatch(any(), any(LocalDateTime.class), 
any(LocalDateTime.class),
-                any(LocalDateTime.class), anyString())).thenReturn(0);
+                any(LocalDateTime.class), anyString(), 
anyInt())).thenReturn(0);
 
         new NotificationOutboxService(mapper, mock(SettingsRepository.class), 
mock(AlertSilenceService.class),
                 mock(AlertRepository.class), 
mock(OperationAuditService.class)).dispatch();
 
         verify(mapper).claimForDispatch(org.mockito.ArgumentMatchers.eq(8L), 
any(LocalDateTime.class),
-                any(LocalDateTime.class), any(LocalDateTime.class), 
anyString());
+                any(LocalDateTime.class), any(LocalDateTime.class), 
anyString(), eq(0));
     }
 
     @Test
@@ -632,7 +633,7 @@ class NotificationOutboxServiceTest {
         when(mapper.findDispatchable(any(LocalDateTime.class), 
any(LocalDateTime.class), any(Integer.class)))
                 .thenReturn(List.of(row));
         when(mapper.claimForDispatch(any(), any(LocalDateTime.class), 
any(LocalDateTime.class),
-                any(LocalDateTime.class), anyString())).thenReturn(1);
+                any(LocalDateTime.class), anyString(), 
anyInt())).thenReturn(1);
         when(mapper.renewClaim(eq(8L), anyString(), 
any(LocalDateTime.class))).thenReturn(1);
         when(mapper.update(any(), any())).thenReturn(1);
         
when(alerts.findAlertById(9L)).thenReturn(Optional.of(SystemAlertVO.builder().id(9L)
@@ -702,7 +703,7 @@ class NotificationOutboxServiceTest {
         when(mapper.findDispatchable(any(LocalDateTime.class), 
any(LocalDateTime.class), any(Integer.class)))
                 .thenReturn(List.of(row));
         when(mapper.claimForDispatch(any(), any(LocalDateTime.class), 
any(LocalDateTime.class),
-                any(LocalDateTime.class), anyString())).thenReturn(1);
+                any(LocalDateTime.class), anyString(), 
anyInt())).thenReturn(1);
         when(mapper.update(any(), any())).thenReturn(1);
         
when(alerts.findAlertById(9L)).thenReturn(Optional.of(SystemAlertVO.builder().id(9L)
                 
.level(AlertLevel.warning).title("Lag").description("high").instanceId("local").build()));
@@ -753,7 +754,7 @@ class NotificationOutboxServiceTest {
         when(mapper.findDispatchable(any(LocalDateTime.class), 
any(LocalDateTime.class), any(Integer.class)))
                 .thenReturn(List.of(row));
         when(mapper.claimForDispatch(any(), any(LocalDateTime.class), 
any(LocalDateTime.class),
-                any(LocalDateTime.class), anyString())).thenReturn(1);
+                any(LocalDateTime.class), anyString(), 
anyInt())).thenReturn(1);
         when(mapper.renewClaim(eq(8L), anyString(), 
any(LocalDateTime.class))).thenReturn(0);
         
when(alerts.findAlertById(9L)).thenReturn(Optional.of(SystemAlertVO.builder().id(9L)
                 
.level(AlertLevel.warning).title("Lag").description("high").instanceId("local").build()));
@@ -810,7 +811,7 @@ class NotificationOutboxServiceTest {
         when(mapper.findDispatchable(any(LocalDateTime.class), 
any(LocalDateTime.class), any(Integer.class)))
                 .thenReturn(List.of(row));
         when(mapper.claimForDispatch(any(), any(LocalDateTime.class), 
any(LocalDateTime.class),
-                any(LocalDateTime.class), anyString())).thenReturn(1);
+                any(LocalDateTime.class), anyString(), 
anyInt())).thenReturn(1);
         when(mapper.update(any(), any())).thenReturn(1);
         
when(alerts.findAlertById(9L)).thenReturn(Optional.of(SystemAlertVO.builder().id(9L)
                 
.level(AlertLevel.warning).title("Lag").description("high").instanceId("local").build()));
@@ -852,7 +853,7 @@ class NotificationOutboxServiceTest {
         when(mapper.findDispatchable(any(LocalDateTime.class), 
any(LocalDateTime.class), any(Integer.class)))
                 .thenReturn(List.of(row));
         when(mapper.claimForDispatch(any(), any(LocalDateTime.class), 
any(LocalDateTime.class),
-                any(LocalDateTime.class), anyString())).thenReturn(1);
+                any(LocalDateTime.class), anyString(), 
anyInt())).thenReturn(1);
         when(mapper.update(any(), any())).thenThrow(new 
IllegalStateException("outbox database unavailable"));
         
when(alerts.findAlertById(9L)).thenReturn(Optional.of(SystemAlertVO.builder().id(9L)
                 
.level(AlertLevel.warning).title("Lag").description("high").instanceId("local").build()));
@@ -950,7 +951,7 @@ class NotificationOutboxServiceTest {
             when(mapper.findDispatchable(any(LocalDateTime.class), 
any(LocalDateTime.class), any(Integer.class)))
                     .thenReturn(List.of(row));
             when(mapper.claimForDispatch(any(), any(LocalDateTime.class), 
any(LocalDateTime.class),
-                    any(LocalDateTime.class), anyString())).thenReturn(1);
+                    any(LocalDateTime.class), anyString(), 
anyInt())).thenReturn(1);
             when(mapper.update(any(), any())).thenReturn(1);
             
when(alerts.findAlertById(9L)).thenReturn(Optional.of(SystemAlertVO.builder().id(9L)
                     
.level(AlertLevel.warning).title("Lag").description("high").instanceId("local")
@@ -987,7 +988,7 @@ class NotificationOutboxServiceTest {
             when(mapper.findDispatchable(any(LocalDateTime.class), 
any(LocalDateTime.class), any(Integer.class)))
                     .thenReturn(List.of(row));
             when(mapper.claimForDispatch(any(), any(LocalDateTime.class), 
any(LocalDateTime.class),
-                    any(LocalDateTime.class), anyString())).thenReturn(1);
+                    any(LocalDateTime.class), anyString(), 
anyInt())).thenReturn(1);
             when(mapper.update(any(), any())).thenReturn(1);
             AlertRepository alerts = mock(AlertRepository.class);
             
when(alerts.findAlertById(9L)).thenReturn(Optional.of(SystemAlertVO.builder().id(9L).build()));
diff --git 
a/server/src/test/java/org/apache/rocketmq/studio/ops/alert/NotificationWebhookEncodingTest.java
 
b/server/src/test/java/org/apache/rocketmq/studio/ops/alert/NotificationWebhookEncodingTest.java
index 2fb21e751..b40939eda 100644
--- 
a/server/src/test/java/org/apache/rocketmq/studio/ops/alert/NotificationWebhookEncodingTest.java
+++ 
b/server/src/test/java/org/apache/rocketmq/studio/ops/alert/NotificationWebhookEncodingTest.java
@@ -50,6 +50,7 @@ import org.springframework.web.client.RestTemplate;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
@@ -109,7 +110,7 @@ class NotificationWebhookEncodingTest {
         when(mapper.findDispatchable(any(LocalDateTime.class), 
any(LocalDateTime.class), any(Integer.class)))
                 .thenReturn(List.of(row));
         when(mapper.claimForDispatch(any(), any(LocalDateTime.class), 
any(LocalDateTime.class),
-                any(LocalDateTime.class), anyString())).thenReturn(1);
+                any(LocalDateTime.class), anyString(), 
anyInt())).thenReturn(1);
         when(mapper.update(any(), any())).thenReturn(1);
         
when(alerts.findAlertById(9L)).thenReturn(Optional.of(SystemAlertVO.builder().id(9L)
                 
.level(AlertLevel.warning).title("Lag").description("high").instanceId("local").build()));

Reply via email to