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

Aias00 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 87062df97d [fix] fix monitor import/export losing annotations and cron 
schedule … (#4166)
87062df97d is described below

commit 87062df97d01d14ea857b76936e97f4385cf609e
Author: Duansg <[email protected]>
AuthorDate: Sun Jun 28 07:36:55 2026 +0800

    [fix] fix monitor import/export losing annotations and cron schedule … 
(#4166)
    
    Co-authored-by: aias00 <[email protected]>
---
 .../service/impl/AbstractImExportServiceImpl.java  |  6 +++
 .../service/impl/ExcelImExportServiceImpl.java     | 55 ++++++++++++++--------
 .../manager/service/ExcelImExportServiceTest.java  | 42 +++++++++++++++++
 .../manager/service/JsonImExportServiceTest.java   | 21 +++++++++
 4 files changed, 105 insertions(+), 19 deletions(-)

diff --git 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/AbstractImExportServiceImpl.java
 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/AbstractImExportServiceImpl.java
index 1dab35ae7b..73115896f9 100644
--- 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/AbstractImExportServiceImpl.java
+++ 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/AbstractImExportServiceImpl.java
@@ -197,6 +197,12 @@ public abstract class AbstractImExportServiceImpl 
implements ImExportService {
         private String description;
         @Excel(name = "Labels")
         private Map<String, String> labels;
+        @Excel(name = "Annotations")
+        private Map<String, String> annotations;
+        @Excel(name = "ScheduleType")
+        private String scheduleType;
+        @Excel(name = "CronExpression")
+        private String cronExpression;
         @Excel(name = "Collector")
         private String collector;
     }
diff --git 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/ExcelImExportServiceImpl.java
 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/ExcelImExportServiceImpl.java
index 7f1b03f04b..59811add95 100644
--- 
a/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/ExcelImExportServiceImpl.java
+++ 
b/hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/service/impl/ExcelImExportServiceImpl.java
@@ -135,25 +135,31 @@ public class ExcelImExportServiceImpl extends 
AbstractImExportServiceImpl{
         monitor.setStatus(getCellValueAsByte(row.getCell(4)));
         monitor.setDescription(getCellValueAsString(row.getCell(5)));
 
-        String labelsString = getCellValueAsString(row.getCell(6));
-        if (StringUtils.isNotBlank(labelsString)) {
+        monitor.setLabels(parseJsonMap(getCellValueAsString(row.getCell(6))));
+        
monitor.setAnnotations(parseJsonMap(getCellValueAsString(row.getCell(7))));
+        monitor.setScheduleType(getCellValueAsString(row.getCell(8)));
+        monitor.setCronExpression(getCellValueAsString(row.getCell(9)));
+        monitor.setCollector(getCellValueAsString(row.getCell(10)));
+        return monitor;
+    }
+
+    private Map<String, String> parseJsonMap(String value) {
+        if (StringUtils.isNotBlank(value)) {
             try {
                 TypeReference<Map<String, String>> typeReference = new 
TypeReference<>() {};
-                Map<String, String> labels = JsonUtil.fromJson(labelsString, 
typeReference);
-                monitor.setLabels(labels);
+                return JsonUtil.fromJson(value, typeReference);
             } catch (Exception ignored) {}
         }
-        monitor.setCollector(getCellValueAsString(row.getCell(7)));
-        return monitor;
+        return null;
     }
 
     private ParamDTO extractParamDataFromRow(Row row) {
-        String fieldName = getCellValueAsString(row.getCell(8));
+        String fieldName = getCellValueAsString(row.getCell(11));
         if (StringUtils.isNotBlank(fieldName)) {
             ParamDTO param = new ParamDTO();
             param.setField(fieldName);
-            param.setType(getCellValueAsByte(row.getCell(9)));
-            param.setValue(getCellValueAsString(row.getCell(10)));
+            param.setType(getCellValueAsByte(row.getCell(12)));
+            param.setValue(getCellValueAsString(row.getCell(13)));
             return param;
         }
         return null;
@@ -214,7 +220,8 @@ public class ExcelImExportServiceImpl extends 
AbstractImExportServiceImpl{
             Sheet sheet = workbook.createSheet(sheetName);
             sheet.setDefaultColumnWidth(20);
             sheet.setColumnWidth(6, 40 * 256);
-            sheet.setColumnWidth(10, 40 * 256);
+            sheet.setColumnWidth(7, 40 * 256);
+            sheet.setColumnWidth(13, 40 * 256);
             // set header style
             CellStyle headerCellStyle = workbook.createCellStyle();
             Font headerFont = workbook.createFont();
@@ -225,7 +232,8 @@ public class ExcelImExportServiceImpl extends 
AbstractImExportServiceImpl{
             CellStyle cellStyle = workbook.createCellStyle();
             cellStyle.setAlignment(HorizontalAlignment.CENTER);
             // set header
-            String[] headers = { "Name", "App", "Host", "Intervals", "Status", 
"Description", "Labels", "Collector", "Param-Field", "Param-Type", 
"Param-Value" };
+            String[] headers = { "Name", "App", "Host", "Intervals", "Status", 
"Description", "Labels", "Annotations",
+                "ScheduleType", "CronExpression", "Collector", "Param-Field", 
"Param-Type", "Param-Value" };
             Row headerRow = sheet.createRow(0);
             for (int i = 0; i < headers.length; i++) {
                 Cell cell = headerRow.createCell(i);
@@ -266,29 +274,38 @@ public class ExcelImExportServiceImpl extends 
AbstractImExportServiceImpl{
                         Cell labelsCell = row.createCell(6);
                         
labelsCell.setCellValue(JsonUtil.toJson(monitorDTO.getLabels()));
                         labelsCell.setCellStyle(cellStyle);
-                        Cell collectorCell = row.createCell(7);
+                        Cell annotationsCell = row.createCell(7);
+                        
annotationsCell.setCellValue(JsonUtil.toJson(monitorDTO.getAnnotations()));
+                        annotationsCell.setCellStyle(cellStyle);
+                        Cell scheduleTypeCell = row.createCell(8);
+                        
scheduleTypeCell.setCellValue(monitorDTO.getScheduleType());
+                        scheduleTypeCell.setCellStyle(cellStyle);
+                        Cell cronExpressionCell = row.createCell(9);
+                        
cronExpressionCell.setCellValue(monitorDTO.getCronExpression());
+                        cronExpressionCell.setCellStyle(cellStyle);
+                        Cell collectorCell = row.createCell(10);
                         collectorCell.setCellValue(monitorDTO.getCollector());
                         collectorCell.setCellStyle(cellStyle);
                     }
                     // Fill in parameter information
                     if (i < paramList.size()) {
                         ParamDTO paramDTO = paramList.get(i);
-                        Cell fieldCell = row.createCell(8);
+                        Cell fieldCell = row.createCell(11);
                         fieldCell.setCellValue(paramDTO.getField());
                         fieldCell.setCellStyle(cellStyle);
-                        Cell typeCell = row.createCell(9);
+                        Cell typeCell = row.createCell(12);
                         typeCell.setCellValue(paramDTO.getType());
                         typeCell.setCellStyle(cellStyle);
-                        Cell valueCell = row.createCell(10);
+                        Cell valueCell = row.createCell(13);
                         valueCell.setCellValue(paramDTO.getValue());
                         valueCell.setCellStyle(cellStyle);
                     }
                 }
                 if (CollectionUtils.isNotEmpty(paramList)) {
-                    RegionUtil.setBorderTop(BorderStyle.THICK, new 
CellRangeAddress(rowIndex - paramList.size(), rowIndex - 1, 0, 10), sheet);
-                    RegionUtil.setBorderBottom(BorderStyle.THICK, new 
CellRangeAddress(rowIndex - paramList.size(), rowIndex - 1, 0, 10), sheet);
-                    RegionUtil.setBorderLeft(BorderStyle.THICK, new 
CellRangeAddress(rowIndex - paramList.size(), rowIndex - 1, 0, 10), sheet);
-                    RegionUtil.setBorderRight(BorderStyle.THICK, new 
CellRangeAddress(rowIndex - paramList.size(), rowIndex - 1, 0, 10), sheet);
+                    RegionUtil.setBorderTop(BorderStyle.THICK, new 
CellRangeAddress(rowIndex - paramList.size(), rowIndex - 1, 0, 13), sheet);
+                    RegionUtil.setBorderBottom(BorderStyle.THICK, new 
CellRangeAddress(rowIndex - paramList.size(), rowIndex - 1, 0, 13), sheet);
+                    RegionUtil.setBorderLeft(BorderStyle.THICK, new 
CellRangeAddress(rowIndex - paramList.size(), rowIndex - 1, 0, 13), sheet);
+                    RegionUtil.setBorderRight(BorderStyle.THICK, new 
CellRangeAddress(rowIndex - paramList.size(), rowIndex - 1, 0, 13), sheet);
                 }
             }
             workbook.write(os);
diff --git 
a/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/service/ExcelImExportServiceTest.java
 
b/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/service/ExcelImExportServiceTest.java
index fe5f8fa1fc..ac83520077 100644
--- 
a/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/service/ExcelImExportServiceTest.java
+++ 
b/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/service/ExcelImExportServiceTest.java
@@ -108,4 +108,46 @@ class ExcelImExportServiceTest {
         assertEquals("Host1", dataRow.getCell(2).getStringCellValue());
     }
 
+    @Test
+    public void testWriteThenParsePreservesAllFields() throws IOException {
+
+        AbstractImExportServiceImpl.MonitorDTO monitorDTO = new 
AbstractImExportServiceImpl.MonitorDTO();
+        monitorDTO.setName("Monitor1");
+        monitorDTO.setApp("linux");
+        monitorDTO.setHost("Host1");
+        monitorDTO.setIntervals(10);
+        monitorDTO.setStatus((byte) 1);
+        monitorDTO.setLabels(Map.of("env", "prod"));
+        monitorDTO.setAnnotations(Map.of("owner", "ops"));
+        monitorDTO.setScheduleType("cron");
+        monitorDTO.setCronExpression("0 0/5 * * * ?");
+
+        AbstractImExportServiceImpl.ParamDTO paramDTO = new 
AbstractImExportServiceImpl.ParamDTO();
+        paramDTO.setField("host");
+        paramDTO.setValue("192.168.1.1");
+        paramDTO.setType((byte) 1);
+
+        AbstractImExportServiceImpl.ExportMonitorDTO exportMonitorDTO = new 
AbstractImExportServiceImpl.ExportMonitorDTO();
+        exportMonitorDTO.setMonitor(monitorDTO);
+        exportMonitorDTO.setParams(List.of(paramDTO));
+
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        excelImExportService.writeOs(List.of(exportMonitorDTO), bos);
+
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        List<AbstractImExportServiceImpl.ExportMonitorDTO> result = 
excelImExportService.parseImport(bis);
+
+        assertNotNull(result);
+        assertEquals(1, result.size());
+        AbstractImExportServiceImpl.MonitorDTO parsed = 
result.get(0).getMonitor();
+        assertEquals("prod", parsed.getLabels().get("env"));
+        assertEquals("ops", parsed.getAnnotations().get("owner"));
+        assertEquals("cron", parsed.getScheduleType());
+        assertEquals("0 0/5 * * * ?", parsed.getCronExpression());
+        // verify the shifted param columns still round-trip correctly
+        assertEquals(1, result.get(0).getParams().size());
+        assertEquals("host", result.get(0).getParams().get(0).getField());
+        assertEquals("192.168.1.1", 
result.get(0).getParams().get(0).getValue());
+    }
+
 }
diff --git 
a/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/service/JsonImExportServiceTest.java
 
b/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/service/JsonImExportServiceTest.java
index 57c69168b5..198c89d0d3 100644
--- 
a/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/service/JsonImExportServiceTest.java
+++ 
b/hertzbeat-manager/src/test/java/org/apache/hertzbeat/manager/service/JsonImExportServiceTest.java
@@ -165,4 +165,25 @@ class JsonImExportServiceTest {
         Monitor captured = monitorCaptor.getValue();
         assertEquals(null, captured.getInstance());
     }
+
+    @Test
+    void testImportConfig_shouldPreserveAnnotationsAndSchedule() {
+        String json = 
"[{\"monitor\":{\"name\":\"test\",\"app\":\"linux\",\"intervals\":6000,\"status\":1,"
+                + 
"\"labels\":{\"env\":\"prod\"},\"annotations\":{\"owner\":\"ops\"},"
+                + "\"scheduleType\":\"cron\",\"cronExpression\":\"0 0/5 * * * 
?\"},"
+                + 
"\"params\":[{\"field\":\"host\",\"type\":1,\"value\":\"192.168.1.1\"}]}]";
+
+        ArgumentCaptor<Monitor> monitorCaptor = 
ArgumentCaptor.forClass(Monitor.class);
+        doNothing().when(monitorService).addMonitor(monitorCaptor.capture(),
+                org.mockito.Mockito.any(), org.mockito.Mockito.any(), 
org.mockito.Mockito.any());
+
+        ByteArrayInputStream bis = new 
ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8));
+        jsonImExportService.importConfig("test.json", bis);
+
+        Monitor captured = monitorCaptor.getValue();
+        assertEquals("prod", captured.getLabels().get("env"));
+        assertEquals("ops", captured.getAnnotations().get("owner"));
+        assertEquals("cron", captured.getScheduleType());
+        assertEquals("0 0/5 * * * ?", captured.getCronExpression());
+    }
 }


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

Reply via email to