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 67a621916 fix(alert): normalize native metric rule inputs (#3050)
67a621916 is described below
commit 67a6219169f9992e3fff6e46d17b08519d1108ef
Author: xdz997 <[email protected]>
AuthorDate: Fri Sep 4 15:44:57 2026 +0800
fix(alert): normalize native metric rule inputs (#3050)
---
.../studio/ops/alert/AlertRuleRequestDTO.java | 3 ++-
.../studio/ops/alert/AlertRuleTransferService.java | 3 +++
.../ops/alert/NativeAlertRuleTestService.java | 20 ++++++++++++++++++
.../studio/ops/alert/AlertRuleRequestDTOTest.java | 9 ++++++++
.../ops/alert/NativeAlertRuleTestServiceTest.java | 24 ++++++++++++++++++++++
5 files changed, 58 insertions(+), 1 deletion(-)
diff --git
a/server/src/main/java/org/apache/rocketmq/studio/ops/alert/AlertRuleRequestDTO.java
b/server/src/main/java/org/apache/rocketmq/studio/ops/alert/AlertRuleRequestDTO.java
index 6d8f5a997..fb82f66f8 100644
---
a/server/src/main/java/org/apache/rocketmq/studio/ops/alert/AlertRuleRequestDTO.java
+++
b/server/src/main/java/org/apache/rocketmq/studio/ops/alert/AlertRuleRequestDTO.java
@@ -64,10 +64,11 @@ public class AlertRuleRequestDTO {
private String notificationTemplate;
public AlertRuleVO toAlertRuleVO() {
+ String normalizedMetric = metric == null ? null : metric.trim();
return AlertRuleVO.builder()
.id(id)
.name(name)
- .metric(metric)
+ .metric(normalizedMetric)
.operator(operator)
.threshold(threshold)
.thresholdUnit(thresholdUnit)
diff --git
a/server/src/main/java/org/apache/rocketmq/studio/ops/alert/AlertRuleTransferService.java
b/server/src/main/java/org/apache/rocketmq/studio/ops/alert/AlertRuleTransferService.java
index c40549154..6c5579958 100644
---
a/server/src/main/java/org/apache/rocketmq/studio/ops/alert/AlertRuleTransferService.java
+++
b/server/src/main/java/org/apache/rocketmq/studio/ops/alert/AlertRuleTransferService.java
@@ -36,6 +36,9 @@ public class AlertRuleTransferService {
AlertRuleVO candidate = request.toAlertRuleVO();
candidate.setId(null);
candidate.setDomain(domain);
+ if (candidate.getMetric() != null) {
+ candidate.setMetric(candidate.getMetric().trim());
+ }
metricCatalogService.validate(candidate);
return candidate;
}).toList();
diff --git
a/server/src/main/java/org/apache/rocketmq/studio/ops/alert/NativeAlertRuleTestService.java
b/server/src/main/java/org/apache/rocketmq/studio/ops/alert/NativeAlertRuleTestService.java
index c4cc20933..8c3095a41 100644
---
a/server/src/main/java/org/apache/rocketmq/studio/ops/alert/NativeAlertRuleTestService.java
+++
b/server/src/main/java/org/apache/rocketmq/studio/ops/alert/NativeAlertRuleTestService.java
@@ -40,6 +40,7 @@ public class NativeAlertRuleTestService {
private final AlertRuleEvaluator evaluator;
public AlertRuleTestResultVO test(AlertRuleVO rule) {
+ normalizeRule(rule);
NativeAlertRulePolicy.validate(rule);
InstanceVO instance =
instanceRepository.findByIdentifier(rule.getInstanceId())
.orElseThrow(() -> new BusinessException(404, "Instance not
found: " + rule.getInstanceId()));
@@ -79,4 +80,23 @@ public class NativeAlertRuleTestService {
}).toList()).build();
}
+ /**
+ * Normalizes the fields used for exact native metric matching before
policy validation and
+ * sample filtering. Existing callers may pass stored rules copied from
older deployments.
+ */
+ private static void normalizeRule(AlertRuleVO rule) {
+ if (rule == null) {
+ return;
+ }
+ if (rule.getMetric() != null) {
+ rule.setMetric(rule.getMetric().trim());
+ }
+ if (rule.getInstanceId() != null) {
+ rule.setInstanceId(rule.getInstanceId().trim());
+ }
+ if (rule.getOperator() != null) {
+ rule.setOperator(rule.getOperator().trim());
+ }
+ }
+
}
diff --git
a/server/src/test/java/org/apache/rocketmq/studio/ops/alert/AlertRuleRequestDTOTest.java
b/server/src/test/java/org/apache/rocketmq/studio/ops/alert/AlertRuleRequestDTOTest.java
index 8dc37df09..27b3be64d 100644
---
a/server/src/test/java/org/apache/rocketmq/studio/ops/alert/AlertRuleRequestDTOTest.java
+++
b/server/src/test/java/org/apache/rocketmq/studio/ops/alert/AlertRuleRequestDTOTest.java
@@ -58,4 +58,13 @@ class AlertRuleRequestDTOTest {
assertThat(request.toAlertRuleVO().getChannels()).containsExactly("email",
"sms");
}
+
+ @Test
+ void toAlertRuleVOShouldNormalizeTheNativeMetricKeyTest() {
+ AlertRuleRequestDTO request = new AlertRuleRequestDTO();
+ request.setName("High Lag");
+ request.setMetric(" consumer.lag.total ");
+
+
assertThat(request.toAlertRuleVO().getMetric()).isEqualTo("consumer.lag.total");
+ }
}
diff --git
a/server/src/test/java/org/apache/rocketmq/studio/ops/alert/NativeAlertRuleTestServiceTest.java
b/server/src/test/java/org/apache/rocketmq/studio/ops/alert/NativeAlertRuleTestServiceTest.java
index 1edf22952..49a1f4559 100644
---
a/server/src/test/java/org/apache/rocketmq/studio/ops/alert/NativeAlertRuleTestServiceTest.java
+++
b/server/src/test/java/org/apache/rocketmq/studio/ops/alert/NativeAlertRuleTestServiceTest.java
@@ -78,6 +78,30 @@ class NativeAlertRuleTestServiceTest {
});
}
+ @Test
+ void normalizesTheMetricKeyBeforePolicyAndSampleFilteringTest() {
+ InstanceRepository instances = mock(InstanceRepository.class);
+ BusinessMetricsCollector collector =
mock(BusinessMetricsCollector.class);
+ InstanceVO instance = InstanceVO.builder().name("local").build();
+
when(instances.findByIdentifier("local")).thenReturn(Optional.of(instance));
+ when(collector.supports(instance)).thenReturn(true);
+ when(collector.collect(instance)).thenReturn(List.of(sample("orders",
20)));
+ AlertRuleVO rule = AlertRuleVO.builder().domain(AlertDomain.BUSINESS)
+ .metric(" consumer.lag.total ")
+ .instanceId(" local ")
+ .operator(" > ")
+ .threshold(10)
+ .build();
+
+ AlertRuleTestResultVO result = new
NativeAlertRuleTestService(instances, List.of(), List.of(collector),
+ new AlertRuleEvaluator()).test(rule);
+
+ assertThat(result.samples()).singleElement().satisfies(sample -> {
+ assertThat(sample.currentValue()).isEqualTo(20);
+ assertThat(sample.conditionMet()).isTrue();
+ });
+ }
+
@Test
void keepsResultsFromHealthyCollectorsWhenAnotherCollectorFailsTest() {
InstanceRepository instances = mock(InstanceRepository.class);