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 1dab35ae7b9..73115896f98 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 static class MonitorDTO { private String description; @Excel(name = "Labels") private Map labels; + @Excel(name = "Annotations") + private Map 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 7f1b03f04bb..59811add958 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 @@ private MonitorDTO extractMonitorDataFromRow(Row row) { 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 parseJsonMap(String value) { + if (StringUtils.isNotBlank(value)) { try { TypeReference> typeReference = new TypeReference<>() {}; - Map 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 void writeOs(List monitorList, OutputStream os) { 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 void writeOs(List monitorList, OutputStream os) { 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 void writeOs(List monitorList, OutputStream os) { 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 fe5f8fa1fc6..ac83520077f 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 @@ public void testWriteOs() throws IOException { 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 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 57c69168b56..198c89d0d3a 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 @@ void testImportConfig_shouldHandleNoHostParam() { 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 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()); + } }