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

gongchao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hertzbeat.git


The following commit(s) were added to refs/heads/master by this push:
     new 25a63ccb25 [improve] Improving the operation of threshold rules and 
the output of expression logs (#3780)
25a63ccb25 is described below

commit 25a63ccb255d2ec8d6ac3634677b0ea43831e108
Author: Duansg <[email protected]>
AuthorDate: Sat Sep 20 17:11:19 2025 +0800

    [improve] Improving the operation of threshold rules and the output of 
expression logs (#3780)
---
 e2e/testsuite.yaml                                 |   2 +-
 .../alert/service/impl/AlertDefineServiceImpl.java |   4 +-
 .../alert/service/impl/DataSourceServiceImpl.java  |   2 +-
 .../alert/service/AlertDefineServiceTest.java      |   6 +-
 .../controller/MetricsFavoriteControllerTest.java  |  39 ++++---
 .../manager/dao/MetricsFavoriteDaoTest.java        |  15 +--
 .../service/AlertDefineServiceIntegrationTest.java | 123 +++++++++++++++++++++
 .../manager/service/MonitorServiceTest.java        |   3 +
 8 files changed, 157 insertions(+), 37 deletions(-)

diff --git a/e2e/testsuite.yaml b/e2e/testsuite.yaml
index 7ec7407da7..25a37f8433 100644
--- a/e2e/testsuite.yaml
+++ b/e2e/testsuite.yaml
@@ -57,7 +57,7 @@ items:
         "credential": "hertzbeat"
       }
   expect:
-    statusCode: 409
+    statusCode: 500
 - name: monitorList
   request:
     api: /api/monitors?pageIndex=0&pageSize=8
diff --git 
a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/service/impl/AlertDefineServiceImpl.java
 
b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/service/impl/AlertDefineServiceImpl.java
index 8cce4294b8..14a4c9f0bf 100644
--- 
a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/service/impl/AlertDefineServiceImpl.java
+++ 
b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/service/impl/AlertDefineServiceImpl.java
@@ -106,14 +106,14 @@ public class AlertDefineServiceImpl implements 
AlertDefineService {
 
     @Override
     public void addAlertDefine(AlertDefine alertDefine) throws 
RuntimeException {
-        alertDefine = alertDefineDao.save(alertDefine);
+        alertDefine = alertDefineDao.saveAndFlush(alertDefine);
         periodicAlertRuleScheduler.updateSchedule(alertDefine);
         CacheFactory.clearAlertDefineCache();
     }
 
     @Override
     public void modifyAlertDefine(AlertDefine alertDefine) throws 
RuntimeException {
-        alertDefineDao.save(alertDefine);
+        alertDefineDao.saveAndFlush(alertDefine);
         periodicAlertRuleScheduler.updateSchedule(alertDefine);
         CacheFactory.clearAlertDefineCache();
     }
diff --git 
a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/service/impl/DataSourceServiceImpl.java
 
b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/service/impl/DataSourceServiceImpl.java
index d41c4a8671..1ac1778987 100644
--- 
a/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/service/impl/DataSourceServiceImpl.java
+++ 
b/hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/service/impl/DataSourceServiceImpl.java
@@ -87,7 +87,7 @@ public class DataSourceServiceImpl implements 
DataSourceService {
         try {
             return evaluate(expr, executor);
         } catch (AlertExpressionException ae) {
-            log.error("Calculate query parse error {}: {}", datasource, 
ae.getMessage());
+            log.error("Calculate query parse error, datasource: {}, expr: {}, 
msg: {}", datasource, expr, ae.getMessage(), ae);
             throw ae;
         } catch (Exception e) {
             log.error("Error executing query on datasource {}: {}", 
datasource, e.getMessage());
diff --git 
a/hertzbeat-alerter/src/test/java/org/apache/hertzbeat/alert/service/AlertDefineServiceTest.java
 
b/hertzbeat-alerter/src/test/java/org/apache/hertzbeat/alert/service/AlertDefineServiceTest.java
index 49ffd3120e..f5e373fc58 100644
--- 
a/hertzbeat-alerter/src/test/java/org/apache/hertzbeat/alert/service/AlertDefineServiceTest.java
+++ 
b/hertzbeat-alerter/src/test/java/org/apache/hertzbeat/alert/service/AlertDefineServiceTest.java
@@ -101,17 +101,17 @@ class AlertDefineServiceTest {
     @Test
     void addAlertDefine() {
         assertDoesNotThrow(() -> 
alertDefineService.addAlertDefine(alertDefine));
-        when(alertDefineDao.save(alertDefine)).thenThrow(new 
RuntimeException());
+        when(alertDefineDao.saveAndFlush(alertDefine)).thenThrow(new 
RuntimeException());
         assertThrows(RuntimeException.class, () -> 
alertDefineService.addAlertDefine(alertDefine));
     }
 
     @Test
     void modifyAlertDefine() {
         AlertDefine alertDefine = AlertDefine.builder().id(1L).build();
-        when(alertDefineDao.save(alertDefine)).thenReturn(alertDefine);
+        when(alertDefineDao.saveAndFlush(alertDefine)).thenReturn(alertDefine);
         assertDoesNotThrow(() -> 
alertDefineService.modifyAlertDefine(alertDefine));
         reset();
-        when(alertDefineDao.save(alertDefine)).thenThrow(new 
RuntimeException());
+        when(alertDefineDao.saveAndFlush(alertDefine)).thenThrow(new 
RuntimeException());
         assertThrows(RuntimeException.class, () -> 
alertDefineService.modifyAlertDefine(alertDefine));
     }
 
diff --git 
a/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/controller/MetricsFavoriteControllerTest.java
 
b/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/controller/MetricsFavoriteControllerTest.java
index e784f1a11d..dad6f7d245 100644
--- 
a/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/controller/MetricsFavoriteControllerTest.java
+++ 
b/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/controller/MetricsFavoriteControllerTest.java
@@ -21,6 +21,7 @@ import com.usthe.sureness.subject.SubjectSum;
 import com.usthe.sureness.util.SurenessContextHolder;
 import org.apache.hertzbeat.common.constants.CommonConstants;
 import org.apache.hertzbeat.manager.service.MetricsFavoriteService;
+import org.apache.hertzbeat.manager.support.GlobalExceptionHandler;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -34,6 +35,7 @@ import 
org.springframework.test.web.servlet.setup.MockMvcBuilders;
 
 import java.util.Set;
 
+import static 
org.apache.hertzbeat.common.constants.CommonConstants.MONITOR_CONFLICT_CODE;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.doNothing;
@@ -70,6 +72,7 @@ class MetricsFavoriteControllerTest {
     @BeforeEach
     void setUp() {
         this.mockMvc = 
MockMvcBuilders.standaloneSetup(metricsFavoriteController)
+                .setControllerAdvice(new GlobalExceptionHandler())
                 .setMessageConverters(new 
MappingJackson2HttpMessageConverter())
                 .build();
     }
@@ -80,7 +83,7 @@ class MetricsFavoriteControllerTest {
         when(subjectSum.getPrincipal()).thenReturn(testUserId);
         try (var mockedStatic = mockStatic(SurenessContextHolder.class)) {
             
mockedStatic.when(SurenessContextHolder::getBindSubject).thenReturn(subjectSum);
-        
+
             
doNothing().when(metricsFavoriteService).addMetricsFavorite(testUserId, 
testMonitorId, testMetricsName);
 
             
mockMvc.perform(post("/api/metrics/favorite/{monitorId}/{metricsName}", 
testMonitorId, testMetricsName)
@@ -99,15 +102,15 @@ class MetricsFavoriteControllerTest {
         when(subjectSum.getPrincipal()).thenReturn(testUserId);
         try (var mockedStatic = mockStatic(SurenessContextHolder.class)) {
             
mockedStatic.when(SurenessContextHolder::getBindSubject).thenReturn(subjectSum);
-        
+
             doThrow(new RuntimeException("Metrics favorite already exists: " + 
testMetricsName))
                     
.when(metricsFavoriteService).addMetricsFavorite(testUserId, testMonitorId, 
testMetricsName);
 
             
mockMvc.perform(post("/api/metrics/favorite/{monitorId}/{metricsName}", 
testMonitorId, testMetricsName)
                             .contentType(MediaType.APPLICATION_JSON))
-                    .andExpect(status().isOk())
-                    .andExpect(jsonPath("$.code").value((int) 
CommonConstants.FAIL_CODE))
-                    .andExpect(jsonPath("$.msg").value("Add failed! Metrics 
favorite already exists: " + testMetricsName));
+                    .andExpect(status().isInternalServerError())
+                    .andExpect(jsonPath("$.code").value((int) 
MONITOR_CONFLICT_CODE))
+                    .andExpect(jsonPath("$.msg").value("Metrics favorite 
already exists: " + testMetricsName));
 
             verify(metricsFavoriteService).addMetricsFavorite(testUserId, 
testMonitorId, testMetricsName);
         }
@@ -117,7 +120,7 @@ class MetricsFavoriteControllerTest {
     void testAddMetricsFavoriteMissingParameters() throws Exception {
         mockMvc.perform(post("/api/metrics/favorite")
                         .contentType(MediaType.APPLICATION_JSON))
-                .andExpect(status().isNotFound());
+                .andExpect(status().is5xxServerError());
 
         verify(metricsFavoriteService, 
never()).addMetricsFavorite(anyString(), anyLong(), anyString());
     }
@@ -128,7 +131,7 @@ class MetricsFavoriteControllerTest {
         when(subjectSum.getPrincipal()).thenReturn(testUserId);
         try (var mockedStatic = mockStatic(SurenessContextHolder.class)) {
             
mockedStatic.when(SurenessContextHolder::getBindSubject).thenReturn(subjectSum);
-        
+
             // Given
             
doNothing().when(metricsFavoriteService).removeMetricsFavorite(testUserId, 
testMonitorId, testMetricsName);
 
@@ -149,15 +152,15 @@ class MetricsFavoriteControllerTest {
         when(subjectSum.getPrincipal()).thenReturn(testUserId);
         try (var mockedStatic = mockStatic(SurenessContextHolder.class)) {
             
mockedStatic.when(SurenessContextHolder::getBindSubject).thenReturn(subjectSum);
-        
+
             doThrow(new RuntimeException("Database error"))
                     
.when(metricsFavoriteService).removeMetricsFavorite(testUserId, testMonitorId, 
testMetricsName);
 
             
mockMvc.perform(delete("/api/metrics/favorite/{monitorId}/{metricsName}", 
testMonitorId, testMetricsName)
                             .contentType(MediaType.APPLICATION_JSON))
-                    .andExpect(status().isOk())
-                    .andExpect(jsonPath("$.code").value((int) 
CommonConstants.FAIL_CODE))
-                    .andExpect(jsonPath("$.msg").value("Remove failed! 
Database error"));
+                    .andExpect(status().isInternalServerError())
+                    .andExpect(jsonPath("$.code").value((int) 
MONITOR_CONFLICT_CODE))
+                    .andExpect(jsonPath("$.msg").value("Database error"));
 
             verify(metricsFavoriteService).removeMetricsFavorite(testUserId, 
testMonitorId, testMetricsName);
         }
@@ -169,7 +172,7 @@ class MetricsFavoriteControllerTest {
         when(subjectSum.getPrincipal()).thenReturn(testUserId);
         try (var mockedStatic = mockStatic(SurenessContextHolder.class)) {
             
mockedStatic.when(SurenessContextHolder::getBindSubject).thenReturn(subjectSum);
-        
+
             Set<String> favoriteMetrics = Set.of("cpu", "memory", "disk");
             when(metricsFavoriteService.getUserFavoritedMetrics(testUserId, 
testMonitorId))
                     .thenReturn(favoriteMetrics);
@@ -191,7 +194,7 @@ class MetricsFavoriteControllerTest {
         when(subjectSum.getPrincipal()).thenReturn(testUserId);
         try (var mockedStatic = mockStatic(SurenessContextHolder.class)) {
             
mockedStatic.when(SurenessContextHolder::getBindSubject).thenReturn(subjectSum);
-        
+
             Set<String> favoriteMetrics = Set.of();
             when(metricsFavoriteService.getUserFavoritedMetrics(testUserId, 
testMonitorId))
                     .thenReturn(favoriteMetrics);
@@ -213,15 +216,15 @@ class MetricsFavoriteControllerTest {
         when(subjectSum.getPrincipal()).thenReturn(testUserId);
         try (var mockedStatic = mockStatic(SurenessContextHolder.class)) {
             
mockedStatic.when(SurenessContextHolder::getBindSubject).thenReturn(subjectSum);
-        
+
             when(metricsFavoriteService.getUserFavoritedMetrics(testUserId, 
testMonitorId))
                     .thenThrow(new RuntimeException("Service error"));
 
             mockMvc.perform(get("/api/metrics/favorite/{monitorId}", 
testMonitorId)
                             .contentType(MediaType.APPLICATION_JSON))
-                    .andExpect(status().isOk())
-                    .andExpect(jsonPath("$.code").value((int) 
CommonConstants.FAIL_CODE))
-                    .andExpect(jsonPath("$.msg").value("Failed to get 
favorited metrics!"));
+                    .andExpect(status().isInternalServerError())
+                    .andExpect(jsonPath("$.code").value((int) 
MONITOR_CONFLICT_CODE))
+                    .andExpect(jsonPath("$.msg").value("Service error"));
 
             verify(metricsFavoriteService).getUserFavoritedMetrics(testUserId, 
testMonitorId);
         }
@@ -231,7 +234,7 @@ class MetricsFavoriteControllerTest {
     void testGetUserFavoritedMetricsMissingMonitorId() throws Exception {
         mockMvc.perform(get("/api/metrics/favorite")
                         .contentType(MediaType.APPLICATION_JSON))
-                .andExpect(status().isNotFound());
+                .andExpect(status().is5xxServerError());
 
         verify(metricsFavoriteService, 
never()).getUserFavoritedMetrics(anyString(), anyLong());
     }
diff --git 
a/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/dao/MetricsFavoriteDaoTest.java
 
b/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/dao/MetricsFavoriteDaoTest.java
index 5d42dd4ada..c9a1b3bebd 100644
--- 
a/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/dao/MetricsFavoriteDaoTest.java
+++ 
b/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/dao/MetricsFavoriteDaoTest.java
@@ -20,10 +20,9 @@ package org.apache.hertzbeat.manager.dao;
 import jakarta.annotation.Resource;
 import org.apache.hertzbeat.common.entity.manager.MetricsFavorite;
 import org.apache.hertzbeat.manager.AbstractSpringIntegrationTest;
-import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.springframework.test.annotation.Rollback;
+import org.springframework.test.annotation.DirtiesContext;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.time.LocalDateTime;
@@ -42,6 +41,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
  * Test case for {@link MetricsFavoriteDao}
  */
 @Transactional
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
 class MetricsFavoriteDaoTest extends AbstractSpringIntegrationTest {
 
     @Resource
@@ -80,11 +80,6 @@ class MetricsFavoriteDaoTest extends 
AbstractSpringIntegrationTest {
                 .build();
     }
 
-    @AfterEach
-    void tearDown() {
-        metricsFavoriteDao.deleteAll();
-    }
-
     @Test
     void testSaveAndFindById() {
         MetricsFavorite saved = metricsFavoriteDao.saveAndFlush(testFavorite1);
@@ -198,7 +193,6 @@ class MetricsFavoriteDaoTest extends 
AbstractSpringIntegrationTest {
     }
 
     @Test
-    @Rollback(false)
     void testUniqueConstraint() {
         metricsFavoriteDao.saveAndFlush(testFavorite1);
 
@@ -208,11 +202,8 @@ class MetricsFavoriteDaoTest extends 
AbstractSpringIntegrationTest {
                 .metricsName(testMetricsName1)
                 .createTime(LocalDateTime.now()).build();
 
-        assertThrows(java.sql.SQLException.class, () -> {
+        assertThrows(Throwable.class, () -> {
             metricsFavoriteDao.saveAndFlush(duplicate);
         });
-        
-        // Clean up the test data
-        metricsFavoriteDao.deleteAll();
     }
 }
\ No newline at end of file
diff --git 
a/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/service/AlertDefineServiceIntegrationTest.java
 
b/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/service/AlertDefineServiceIntegrationTest.java
new file mode 100644
index 0000000000..cabde6336a
--- /dev/null
+++ 
b/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/service/AlertDefineServiceIntegrationTest.java
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hertzbeat.manager.service;
+
+import org.apache.hertzbeat.alert.dao.AlertDefineDao;
+import org.apache.hertzbeat.alert.service.AlertDefineService;
+import org.apache.hertzbeat.common.entity.alerter.AlertDefine;
+import org.apache.hertzbeat.manager.AbstractSpringIntegrationTest;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Test case for {@link AlertDefineService}
+ */
+public class AlertDefineServiceIntegrationTest extends 
AbstractSpringIntegrationTest {
+
+    @Autowired
+    private AlertDefineService alertDefineService;
+    @Autowired
+    private AlertDefineDao alertDefineDao;
+
+    private List<Long> createdIds = new ArrayList<>();
+
+    @BeforeEach
+    void setUp() {
+        createdIds.clear();
+    }
+
+    @AfterEach
+    void tearDown() {
+        for (Long id : createdIds) {
+            if (alertDefineDao.existsById(id)) {
+                alertDefineDao.deleteById(id);
+            }
+        }
+    }
+
+    @Test
+    void testAddAlertDefine() {
+        AlertDefine alertDefine = AlertDefine.builder()
+                .name("test-cpu-alert")
+                .expr("usage > 80")
+                .times(3)
+                .type("periodic")
+                .enable(true)
+                .period(10)
+                .template("CPU usage is excessively high: ${usage}%")
+                .creator("integration-test")
+                .modifier("integration-test")
+                .gmtCreate(LocalDateTime.now())
+                .gmtUpdate(LocalDateTime.now())
+                .build();
+        assertNull(alertDefine.getId());
+        assertDoesNotThrow(() -> 
alertDefineService.addAlertDefine(alertDefine));
+
+        assertNotNull(alertDefine.getId());
+        assertTrue(alertDefine.getId() > 0);
+
+        createdIds.add(alertDefine.getId());
+
+        AlertDefine savedAlertDefine = 
alertDefineDao.findById(alertDefine.getId()).orElse(null);
+        assertNotNull(savedAlertDefine);
+        assertEquals("usage > 80", savedAlertDefine.getExpr());
+        assertEquals("integration-test", savedAlertDefine.getCreator());
+    }
+
+    @Test
+    void testModifyAlertDefine() {
+        AlertDefine alertDefine = AlertDefine.builder()
+                .name("test-cpu-alert")
+                .expr("usage > 80")
+                .times(3)
+                .type("periodic")
+                .enable(true)
+                .period(10)
+                .template("CPU usage is excessively high: ${usage}%")
+                .creator("integration-test")
+                .modifier("integration-test")
+                .gmtCreate(LocalDateTime.now())
+                .gmtUpdate(LocalDateTime.now())
+                .build();
+        assertNull(alertDefine.getId());
+        assertDoesNotThrow(() -> 
alertDefineService.modifyAlertDefine(alertDefine));
+
+        assertNotNull(alertDefine.getId());
+        assertTrue(alertDefine.getId() > 0);
+
+        createdIds.add(alertDefine.getId());
+
+        AlertDefine savedAlertDefine = 
alertDefineDao.findById(alertDefine.getId()).orElse(null);
+        assertNotNull(savedAlertDefine);
+        assertEquals("usage > 80", savedAlertDefine.getExpr());
+        assertEquals("integration-test", savedAlertDefine.getCreator());
+    }
+
+}
\ No newline at end of file
diff --git 
a/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/service/MonitorServiceTest.java
 
b/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/service/MonitorServiceTest.java
index 8bad80d915..0441d45292 100644
--- 
a/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/service/MonitorServiceTest.java
+++ 
b/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/service/MonitorServiceTest.java
@@ -125,6 +125,9 @@ class MonitorServiceTest {
     @Mock
     private ApplicationContext applicationContext;
 
+    @Mock
+    private MetricsFavoriteService metricsFavoriteService;
+
     /**
      * Properties cannot be directly mock, test execution before - manual 
assignment
      */


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to