summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshizhendong <[email protected]>2021-03-19 17:07:37 +0800
committershizhendong <[email protected]>2021-03-19 17:07:37 +0800
commit060925e8b27669d39d89a13c5eea46e35388ca49 (patch)
treeb0c293e968c611ec931b6293c9b2ea54af7f9b7b
parentb6a868d8285e02d597725bbe4eefbee16a7a8772 (diff)
NEZ-514 feat: project module endpoint 接口重构
-rw-r--r--nz-admin/src/main/java/com/nis/common/utils/Constant.java3
-rw-r--r--nz-admin/src/main/java/com/nis/common/utils/ExcelUtils.java22
-rw-r--r--nz-admin/src/main/java/com/nis/modules/asset/entity/Asset.java2
-rw-r--r--nz-admin/src/main/java/com/nis/modules/endpoint/controller/MonitorEndpointController.java131
-rw-r--r--nz-admin/src/main/java/com/nis/modules/endpoint/dao/MonitorEndpointDao.java17
-rw-r--r--nz-admin/src/main/java/com/nis/modules/endpoint/entity/MonitorEndpoint.java90
-rw-r--r--nz-admin/src/main/java/com/nis/modules/endpoint/service/MonitorEndpointService.java32
-rw-r--r--nz-admin/src/main/java/com/nis/modules/endpoint/service/impl/MonitorEndpointServiceImpl.java613
-rw-r--r--nz-admin/src/main/java/com/nis/modules/module/controller/MonitorModuleController.java99
-rw-r--r--nz-admin/src/main/java/com/nis/modules/module/dao/MonitorModuleDao.java19
-rw-r--r--nz-admin/src/main/java/com/nis/modules/module/entity/MonitorModule.java85
-rw-r--r--nz-admin/src/main/java/com/nis/modules/module/service/MonitorModuleService.java24
-rw-r--r--nz-admin/src/main/java/com/nis/modules/module/service/impl/MonitorModuleServiceImpl.java313
-rw-r--r--nz-admin/src/main/java/com/nis/modules/panel/service/ExpreTmplService.java2
-rw-r--r--nz-admin/src/main/java/com/nis/modules/panel/service/impl/ExpreTmplServiceImpl.java32
-rw-r--r--nz-admin/src/main/java/com/nis/modules/project/controller/MonitorProjectController.java253
-rw-r--r--nz-admin/src/main/java/com/nis/modules/project/dao/MonitorProjectDao.java10
-rw-r--r--nz-admin/src/main/java/com/nis/modules/project/entity/MonitorProject.java51
-rw-r--r--nz-admin/src/main/java/com/nis/modules/project/service/MonitorProjectService.java22
-rw-r--r--nz-admin/src/main/java/com/nis/modules/project/service/TopoIconService.java2
-rw-r--r--nz-admin/src/main/java/com/nis/modules/project/service/TopoService.java5
-rw-r--r--nz-admin/src/main/java/com/nis/modules/project/service/impl/MonitorProjectServiceImpl.java206
-rw-r--r--nz-admin/src/main/java/com/nis/modules/project/service/impl/TopoIconServiceImpl.java13
-rw-r--r--nz-admin/src/main/java/com/nis/modules/project/service/impl/TopoServiceImpl.java39
-rw-r--r--nz-admin/src/main/resources/db/V2021.03.19__Insert monitor_project, monitor_module and monitor_endpoint table.sql65
-rw-r--r--nz-admin/src/main/resources/mapper/endpoint/MonitorEndpointDao.xml101
-rw-r--r--nz-admin/src/main/resources/mapper/module/MonitorModuleDao.xml56
-rw-r--r--nz-admin/src/main/resources/mapper/terminal/TerminalSessionDao.xml2
-rw-r--r--nz-common/src/main/java/com/nis/common/utils/RCode.java26
29 files changed, 2306 insertions, 29 deletions
diff --git a/nz-admin/src/main/java/com/nis/common/utils/Constant.java b/nz-admin/src/main/java/com/nis/common/utils/Constant.java
index 2fb003da..9ac93e0f 100644
--- a/nz-admin/src/main/java/com/nis/common/utils/Constant.java
+++ b/nz-admin/src/main/java/com/nis/common/utils/Constant.java
@@ -588,6 +588,9 @@ public class Constant {
// endpoint 导入表头
public static final String SYSCONFIG_KEY_ENDPOINT_EXPORT_HEADER = "endpoint_export_header";
+ // endpoint 导入表头
+ public static final String SYSCONFIG_KEY_MONITORENDPOINT_EXPORT_HEADER = "monitor_endpoint_export_header";
+
// expression template 导入表头
public static final String SYSCONFIG_KEY_EXPRETMPL_EXPORT_HEADER = "expretmpl_export_header";
diff --git a/nz-admin/src/main/java/com/nis/common/utils/ExcelUtils.java b/nz-admin/src/main/java/com/nis/common/utils/ExcelUtils.java
index 21bfeb0d..43da8d03 100644
--- a/nz-admin/src/main/java/com/nis/common/utils/ExcelUtils.java
+++ b/nz-admin/src/main/java/com/nis/common/utils/ExcelUtils.java
@@ -4,7 +4,9 @@ package com.nis.common.utils;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
+import com.nis.common.exception.NZException;
import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.io.IOUtils;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
@@ -13,6 +15,7 @@ import org.apache.poi.util.Units;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
@@ -261,4 +264,23 @@ public class ExcelUtils {
}
return headerFlag;
}
+
+ public static Workbook getWorkBookFromMultipartFile(MultipartFile excelFile) {
+ if (!ExcelUtils.validateFileType(excelFile.getOriginalFilename())) {
+ throw new NZException(RCode.IMPORT_EXCELFILE_TYPE);
+ }
+
+ Workbook work = null;
+ try {
+ work = ExcelUtils.getWork(excelFile.getOriginalFilename(), excelFile.getInputStream());
+ } catch (IOException e) {
+ throw new NZException(RCode.IMPORT_EXCELFILE_PARSE_ERROR);
+ } finally {
+ if (work != null) {
+ IOUtils.closeQuietly(work);
+ }
+ }
+ return work;
+ }
+
}
diff --git a/nz-admin/src/main/java/com/nis/modules/asset/entity/Asset.java b/nz-admin/src/main/java/com/nis/modules/asset/entity/Asset.java
index 9cc86128..1debce6c 100644
--- a/nz-admin/src/main/java/com/nis/modules/asset/entity/Asset.java
+++ b/nz-admin/src/main/java/com/nis/modules/asset/entity/Asset.java
@@ -211,4 +211,6 @@ public class Asset implements Serializable {
private Integer typeId;
private Integer brandId;
+
+ private String name;
}
diff --git a/nz-admin/src/main/java/com/nis/modules/endpoint/controller/MonitorEndpointController.java b/nz-admin/src/main/java/com/nis/modules/endpoint/controller/MonitorEndpointController.java
new file mode 100644
index 00000000..2e669469
--- /dev/null
+++ b/nz-admin/src/main/java/com/nis/modules/endpoint/controller/MonitorEndpointController.java
@@ -0,0 +1,131 @@
+package com.nis.modules.endpoint.controller;
+
+import com.nis.common.annotation.SysLog;
+import com.nis.common.exception.NZException;
+import com.nis.common.smartvalidate.ValidateUtils;
+import com.nis.common.utils.*;
+import com.nis.modules.endpoint.entity.MonitorEndpoint;
+import com.nis.modules.endpoint.service.MonitorEndpointService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+@RestController
+@RequestMapping("/monitor")
+public class MonitorEndpointController {
+
+ @Autowired
+ private MonitorEndpointService monitorEndpointService;
+
+ /**
+ * 详情
+ *
+ * @param id
+ * @return
+ */
+ @GetMapping("/endpoint/{id}")
+ @SysLog(operation = OperationEnum.QUERY, type = TypeEnum.ENDPOINT)
+ public R queryEndpointEntity(@PathVariable("id") Integer id) {
+ return R.ok(monitorEndpointService.queryEndpointEntity(id));
+ }
+
+ @GetMapping("/endpoint")
+ @SysLog(operation = OperationEnum.QUERY, type = TypeEnum.ENDPOINT)
+ public R queryEndpointPage(@RequestParam Map<String, Object> params) {
+ PageUtils page = monitorEndpointService.queryPage(params);
+ return R.ok(page);
+ }
+
+ /**
+ * endpoint tree 三级列表 project -> module -> endpoint
+ *
+ * @param name
+ * @return
+ */
+ @GetMapping("/endpoint/tree")
+ @SysLog(operation = OperationEnum.QUERY, type = TypeEnum.ENDPOINT)
+ public R queryEndpointTree(String name) {
+ Map map = new HashMap(2);
+ map.put("list", monitorEndpointService.queryEndpointTree(name));
+ return R.ok(map);
+ }
+
+ @PostMapping("/endpoint")
+ @SysLog(operation = OperationEnum.ADD, type = TypeEnum.ENDPOINT)
+ public R saveEndpoint(@RequestBody List<MonitorEndpoint> endpointList) {
+ monitorEndpointService.saveOrUpdateBatchEndpointList(endpointList);
+ return R.ok();
+ }
+
+ @PutMapping("/endpoint")
+ @SysLog(operation = OperationEnum.UPDATE, type = TypeEnum.ENDPOINT)
+ public R modify(@RequestBody List<MonitorEndpoint> endpointList) {
+ for (MonitorEndpoint endpointEntity : endpointList) {
+ ValidateUtils.is(endpointEntity.getId()).notNull(RCode.ENDPOINT_ID_ISNULL);
+ }
+ monitorEndpointService.saveOrUpdateBatchEndpointList(endpointList);
+ return R.ok();
+ }
+
+ @DeleteMapping("/endpoint")
+ @SysLog(operation = OperationEnum.DELETE, type = TypeEnum.ENDPOINT)
+ public R remove(@RequestParam Integer... ids) {
+ ValidateUtils.is(ids).notNull(RCode.ENDPOINT_ID_ISNULL);
+
+ monitorEndpointService.deleteEndpointByIds(Arrays.asList(ids));
+ return R.ok();
+ }
+
+ @GetMapping("/endpoint/template")
+ public void getExportTemplateByLanguage(HttpServletResponse response, String language) {
+ if (ToolUtil.isEmpty(language)) throw new NZException(RCode.ENDPOINT_EXPORT_HEADER_LANGUAGE_ISNULL);
+
+ monitorEndpointService.getExportTemplateByLanguage(response, language);
+ }
+
+ /**
+ * 撤销导入操作
+ *
+ * @param seq
+ * @return
+ */
+ @DeleteMapping("/endpoint/cancelImport")
+ @SysLog(operation = OperationEnum.DELETE, type = TypeEnum.ENDPOINT)
+ public R cancelImport(String seq) {
+ ValidateUtils.is(seq).notNull(RCode.ENDPOINT_CANCELIMPORTSEQ_ISNULL);
+
+ monitorEndpointService.cancelImport(seq);
+ return R.ok();
+ }
+
+ @PostMapping("/endpoint/import")
+ @SysLog(operation = OperationEnum.IMPORT, type = TypeEnum.ENDPOINT)
+ public R importEndpoint(MultipartFile excelFile, String language) {
+ ValidateUtils.is(excelFile).notNull(RCode.ENDPOINT_IMPORT_FILE_ISNULL)
+ .and(language).notNull(RCode.ENDPOINT_EXPORT_HEADER_LANGUAGE_ISNULL);
+
+ Map map = monitorEndpointService.importEndpoint(excelFile, language);
+ return R.ok(map);
+ }
+
+ /**
+ * 批量导出endpoint
+ *
+ * @param response
+ * @param params
+ */
+ @GetMapping("/endpoint/export")
+ @SysLog(operation = OperationEnum.EXPORT, type = TypeEnum.ENDPOINT)
+ public void exportEndpointsFromExcel(HttpServletResponse response, @RequestParam Map<String, Object> params) {
+ monitorEndpointService.export(response, params);
+ }
+
+}
+
diff --git a/nz-admin/src/main/java/com/nis/modules/endpoint/dao/MonitorEndpointDao.java b/nz-admin/src/main/java/com/nis/modules/endpoint/dao/MonitorEndpointDao.java
new file mode 100644
index 00000000..469e21b9
--- /dev/null
+++ b/nz-admin/src/main/java/com/nis/modules/endpoint/dao/MonitorEndpointDao.java
@@ -0,0 +1,17 @@
+package com.nis.modules.endpoint.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.nis.modules.endpoint.entity.MonitorEndpoint;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+@Mapper
+public interface MonitorEndpointDao extends BaseMapper<MonitorEndpoint> {
+
+ List<MonitorEndpoint> queryPage(IPage<MonitorEndpoint> page, @Param("params") Map<String, Object> params);
+
+}
diff --git a/nz-admin/src/main/java/com/nis/modules/endpoint/entity/MonitorEndpoint.java b/nz-admin/src/main/java/com/nis/modules/endpoint/entity/MonitorEndpoint.java
new file mode 100644
index 00000000..1727fe6b
--- /dev/null
+++ b/nz-admin/src/main/java/com/nis/modules/endpoint/entity/MonitorEndpoint.java
@@ -0,0 +1,90 @@
+package com.nis.modules.endpoint.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.nis.modules.asset.entity.Asset;
+import com.nis.modules.module.entity.MonitorModule;
+import com.nis.modules.project.entity.MonitorProject;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+@TableName("monitor_endpoint")
+public class MonitorEndpoint implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键
+ */
+ @TableId(type = IdType.AUTO)
+ private Integer id;
+
+ /**
+ * 名称
+ */
+ private String name;
+
+ /**
+ * 组件id
+ */
+ private Integer moduleId;
+
+ /**
+ * 资产id
+ */
+ private Integer assetId;
+
+
+ /**
+ * exporter地址
+ */
+ private String host;
+
+ /**
+ * export端口
+ */
+ private Integer port;
+
+ /**
+ * 配置参数 当type=HTTP,默认为 module.configs
+ */
+ private String configs;
+
+ /**
+ * 计算 moduleId + assetId + host + port + configs 的hash值,用于确保相同配置不重复
+ */
+ private String hash;
+
+ /**
+ * 是否启用 可选值
+ * 0:停用
+ * 1:启用
+ */
+ private Integer enabled;
+
+ private String seq;
+
+ @TableField(exist = false)
+ private Integer state;
+
+ @TableField(exist = false)
+ private MonitorModule module;
+
+ @TableField(exist = false)
+ private Asset asset;
+
+ @TableField(exist = false)
+ private MonitorProject project;
+
+ @TableField(exist = false)
+ private StateInfo stateInfo;
+
+ @TableField(exist = false)
+ private EndpointState endpointState;
+
+ @TableField(exist = false)
+ private Integer alertNum;
+}
diff --git a/nz-admin/src/main/java/com/nis/modules/endpoint/service/MonitorEndpointService.java b/nz-admin/src/main/java/com/nis/modules/endpoint/service/MonitorEndpointService.java
new file mode 100644
index 00000000..226e37af
--- /dev/null
+++ b/nz-admin/src/main/java/com/nis/modules/endpoint/service/MonitorEndpointService.java
@@ -0,0 +1,32 @@
+package com.nis.modules.endpoint.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.nis.common.utils.PageUtils;
+import com.nis.modules.endpoint.entity.MonitorEndpoint;
+import com.nis.modules.project.entity.MonitorProject;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+import java.util.Map;
+
+public interface MonitorEndpointService extends IService<MonitorEndpoint> {
+
+ MonitorEndpoint queryEndpointEntity(Integer id);
+
+ PageUtils queryPage(Map<String, Object> params);
+
+ List<MonitorProject> queryEndpointTree(String name);
+
+ void saveOrUpdateBatchEndpointList(List<MonitorEndpoint> endpointList);
+
+ void deleteEndpointByIds(List<Integer> ids);
+
+ void getExportTemplateByLanguage(HttpServletResponse response, String language);
+
+ void cancelImport(String seq);
+
+ Map importEndpoint(MultipartFile excelFile, String language);
+
+ void export(HttpServletResponse response, Map<String, Object> params);
+}
diff --git a/nz-admin/src/main/java/com/nis/modules/endpoint/service/impl/MonitorEndpointServiceImpl.java b/nz-admin/src/main/java/com/nis/modules/endpoint/service/impl/MonitorEndpointServiceImpl.java
new file mode 100644
index 00000000..015eb59c
--- /dev/null
+++ b/nz-admin/src/main/java/com/nis/modules/endpoint/service/impl/MonitorEndpointServiceImpl.java
@@ -0,0 +1,613 @@
+package com.nis.modules.endpoint.service.impl;
+
+import cn.hutool.log.Log;
+import com.alibaba.fastjson.JSONException;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.parser.Feature;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.nis.common.exception.NZException;
+import com.nis.common.smartvalidate.ValidateUtils;
+import com.nis.common.utils.*;
+import com.nis.modules.alert.dao.AlertMessageDao;
+import com.nis.modules.alert.entity.AlertMessageEntity;
+import com.nis.modules.asset.entity.Asset;
+import com.nis.modules.asset.service.AssetService;
+import com.nis.modules.endpoint.dao.MonitorEndpointDao;
+import com.nis.modules.endpoint.entity.MonitorEndpoint;
+import com.nis.modules.endpoint.service.MonitorEndpointService;
+import com.nis.modules.module.entity.MonitorModule;
+import com.nis.modules.module.service.MonitorModuleService;
+import com.nis.modules.panel.service.ExpreTmplService;
+import com.nis.modules.project.entity.MonitorProject;
+import com.nis.modules.project.service.MonitorProjectService;
+import com.nis.modules.sys.dao.SysConfigDao;
+import com.nis.modules.sys.entity.SysConfigEntity;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.streaming.SXSSFSheet;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.DigestUtils;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+@Service
+public class MonitorEndpointServiceImpl extends ServiceImpl<MonitorEndpointDao, MonitorEndpoint> implements MonitorEndpointService {
+
+ private static Log log = Log.get();
+
+ @Autowired
+ private AssetService assetService;
+
+ @Autowired
+ private SysConfigDao sysConfigDao;
+
+ @Autowired
+ private AlertMessageDao alertMessageDao;
+
+ @Autowired
+ private MonitorEndpointDao monitorEndpointDao;
+
+ @Autowired
+ private MonitorModuleService monitorModuleService;
+
+ @Autowired
+ private MonitorProjectService monitorProjectService;
+
+ @Autowired
+ private ExpreTmplService expreTmplService;
+
+ @Override
+ public MonitorEndpoint queryEndpointEntity(Integer id) {
+ MonitorEndpoint endpoint = this.getById(id);
+ if (ToolUtil.isEmpty(endpoint)) {
+ throw new NZException(RCode.ENDPOINT_NOTFOUND);
+ }
+ MonitorModule module = monitorModuleService.getById(endpoint.getModuleId());
+ endpoint.setModule(module);
+ MonitorProject project = monitorProjectService.getById(module.getProjectId());
+ endpoint.setProject(project);
+ Asset asset = assetService.getById(endpoint.getAssetId());
+ endpoint.setAsset(asset);
+
+ List<AlertMessageEntity> alerts = alertMessageDao.getAlertsStatColumn();
+ alerts = alerts.stream().filter(alert -> ToolUtil.isNotEmpty(alert.getEndpointId())).collect(Collectors.toList());
+ Map<Integer, List<AlertMessageEntity>> endpointIdAndAlersMap = alerts.stream().collect(Collectors.groupingBy(AlertMessageEntity::getEndpointId));
+
+ List<AlertMessageEntity> tempAlert = endpointIdAndAlersMap.get(endpoint.getId());
+ if (CollectionUtils.isEmpty(tempAlert)) {
+ endpoint.setAlertNum(0);
+ } else {
+ endpoint.setAlertNum(tempAlert.size());
+ }
+ return endpoint;
+ }
+
+ private void handleEndpointsAlertNum(List<MonitorEndpoint> endpointList) {
+ if (CollectionUtils.isEmpty(endpointList)) return;
+
+ List<AlertMessageEntity> alerts = alertMessageDao.getAlertsStatColumn();
+ alerts = alerts.stream().filter(alert -> ToolUtil.isNotEmpty(alert.getEndpointId())).collect(Collectors.toList());
+ Map<Integer, List<AlertMessageEntity>> endpointIdAndAlersMap = alerts.stream().collect(Collectors.groupingBy(AlertMessageEntity::getEndpointId));
+
+ List<AlertMessageEntity> tempAlert;
+ for (MonitorEndpoint endpoint : endpointList) {
+ tempAlert = endpointIdAndAlersMap.get(endpoint.getId());
+ if (CollectionUtils.isEmpty(tempAlert)) {
+ endpoint.setAlertNum(0);
+ } else {
+ endpoint.setAlertNum(tempAlert.size());
+ }
+ }
+ }
+
+ @Override
+ public PageUtils queryPage(Map<String, Object> params) {
+ IPage<MonitorEndpoint> page = new Query<MonitorEndpoint>().getPage(params);
+ List<MonitorEndpoint> datas = monitorEndpointDao.queryPage(page, params);
+
+ // endpoint 告警数量
+ this.handleEndpointsAlertNum(datas);
+
+ page.setRecords(datas);
+ return new PageUtils(page);
+ }
+
+ @Override
+ public List<MonitorProject> queryEndpointTree(String name) {
+ List<MonitorEndpoint> endpointList = this.list(new LambdaQueryWrapper<MonitorEndpoint>().like(StringUtils.isNotEmpty(name), MonitorEndpoint::getName, name));
+ if (CollectionUtils.isEmpty(endpointList)) {
+ return Collections.emptyList();
+ }
+ List<Integer> moduleIdList = endpointList.stream().map(MonitorEndpoint::getModuleId).distinct().collect(Collectors.toList());
+ List<MonitorModule> moduleList = monitorModuleService.list(new LambdaQueryWrapper<MonitorModule>().in(MonitorModule::getId, moduleIdList));
+
+ List<Integer> projectIdList = moduleList.stream().map(MonitorModule::getProjectId).distinct().collect(Collectors.toList());
+ List<MonitorProject> projectList = monitorProjectService.list(new LambdaQueryWrapper<MonitorProject>().in(MonitorProject::getId, projectIdList));
+
+
+ for (MonitorProject project : projectList) {
+ List<MonitorModule> projectModules = new ArrayList<>();
+
+ for (MonitorModule module : moduleList) {
+ List<MonitorEndpoint> moduleEndpoints = new ArrayList();
+ for (MonitorEndpoint endpoint : endpointList) {
+ if (endpoint.getModuleId().equals(module.getId())) {
+ moduleEndpoints.add(endpoint);
+ }
+ }
+ module.setChildren(moduleEndpoints);
+
+ if (module.getProjectId().equals(project.getId())) {
+ projectModules.add(module);
+ }
+ }
+
+ project.setChildren(projectModules);
+ }
+ return projectList;
+ }
+
+ private void validateParam(List<MonitorEndpoint> endpointList) {
+ List<MonitorModule> moduleList = monitorModuleService.list();
+ List<Integer> moduleIdList = moduleList.stream().map(MonitorModule::getId).collect(Collectors.toList());
+
+ List<Asset> assetList = assetService.list();
+ List<Integer> assetIdList = assetList.stream().map(Asset::getId).collect(Collectors.toList());
+
+ List<Integer> enabledList = Arrays.asList(new Integer[]{1, 0});
+ //String name;
+ Integer moduleId, assetId, enabled;
+ for (MonitorEndpoint endpoint : endpointList) {
+ moduleId = endpoint.getModuleId();
+ assetId = endpoint.getAssetId();
+
+ // 1. 非空校验
+ ValidateUtils.is(moduleId).notNull(RCode.ENDPOINT_MODULEID_ISNULL)
+ .and(assetId).notNull(RCode.ENDPOINT_ASSETID_ISNULL)
+ .and(endpoint.getPort()).notNull(RCode.ENDPOINT_PORT_ISNULL);
+
+ // 2. module 是否存在
+ if (!moduleIdList.contains(moduleId)) {
+ throw new NZException(RCode.MODULE_NOTFOUND);
+ }
+
+ // 3. asset 是否存在
+ if (!assetIdList.contains(assetId)) {
+ throw new NZException(RCode.ASSET_NOT_EXIST);
+ }
+
+ // 4. enabled 值是否有误
+ enabled = endpoint.getEnabled();
+ if (enabled != null && !enabledList.contains(enabled)) {
+ throw new NZException(RCode.ENDPOINT_ENABLED_INVALIDE);
+ }
+
+ // 5. port 校验
+ if (endpoint.getPort() != null) {
+ boolean flag = CommonUtils.checkPort(endpoint.getPort().toString());
+ if (!flag) {
+ throw new NZException(RCode.ENDPOINT_PORT_ERROR);
+ }
+ }
+
+ // 6. configs 校验
+ if (endpoint.getConfigs() != null) {
+ try {
+ JSONObject.parseObject(endpoint.getConfigs(), Map.class);
+ } catch (JSONException e) {
+ throw new NZException(RCode.ENDPOINT_CONFIGS_FORMAT);
+ }
+ }
+ }
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void saveOrUpdateBatchEndpointList(List<MonitorEndpoint> endpointList) {
+ // 校验
+ this.validateParam(endpointList);
+
+ List<MonitorModule> moduleList = monitorModuleService.list();
+ Map<Integer, MonitorModule> moduleIdAndModuleInfoMap = moduleList.stream().collect(Collectors.toMap(MonitorModule::getId, Function.identity()));
+
+ List<Asset> assetList = assetService.list();
+ Map<Integer, String> assetIdAndHostMap = assetList.stream().collect(Collectors.toMap(Asset::getId, Asset::getHost));
+
+ List<MonitorEndpoint> endpoints = this.list();
+ Map<Integer, List<MonitorEndpoint>> moduleIdAndEndpointsMap = new HashMap<>();
+ for (MonitorModule module : moduleList) {
+ List<MonitorEndpoint> moduleEndpoints = endpoints.stream().filter(endpoint -> endpoint.getModuleId().equals(module.getId())).collect(Collectors.toList());
+ moduleIdAndEndpointsMap.put(module.getId(), ToolUtil.isEmpty(moduleEndpoints) ? new ArrayList<>() : moduleEndpoints);
+ }
+
+ MonitorModule module;
+ for (MonitorEndpoint endpoint : endpointList) {
+ module = moduleIdAndModuleInfoMap.get(endpoint.getModuleId());
+ if (ToolUtil.isEmpty(endpoint.getPort())) {
+ endpoint.setPort(module.getPort());
+ }
+ if (ToolUtil.isEmpty(endpoint.getHost())) {
+ endpoint.setHost(assetIdAndHostMap.get(endpoint.getAssetId()));
+ }
+ if (ToolUtil.isEmpty(endpoint.getEnabled())) {
+ endpoint.setEnabled(1);
+ }
+ if (ToolUtil.isEmpty(endpoint.getConfigs())) {
+ endpoint.setConfigs(module.getConfigs());
+ }
+ // 名称为空 则按照 module endpoint 名称模板生成对应名称
+ if (ToolUtil.isEmpty(endpoint.getName())) {
+ String endpointNameTmpl = module.getEndpointNameTmpl();
+ Map varsVal = new HashMap(4);
+ varsVal.put("asset.host", assetIdAndHostMap.get(endpoint.getAssetId()));
+ varsVal.put("module.name", module.getName());
+ String generateEndpointName = expreTmplService.renderExpression(endpointNameTmpl, varsVal);
+ endpoint.setName(generateEndpointName);
+ }
+
+ // 校验名称是否重复
+ List<MonitorEndpoint> monitorEndpointList = moduleIdAndEndpointsMap.get(endpoint.getModuleId());
+ MonitorEndpoint monitorEndpoint = monitorEndpointList.stream().filter(entity -> entity.getName().equals(endpoint.getName()) && !entity.getId().equals(endpoint.getId())).findAny().orElse(null);
+ if (ToolUtil.isNotEmpty(monitorEndpoint)) {
+ throw new NZException(RCode.ENDPOINT_NAME_DUPLICATE);
+ }
+ monitorEndpointList.add(endpoint);
+ moduleIdAndEndpointsMap.put(endpoint.getModuleId(), monitorEndpointList);
+
+ String hash = endpoint.getModuleId() + endpoint.getAssetId() + endpoint.getHost() + endpoint.getPort() + endpoint.getConfigs();
+ endpoint.setHash(DigestUtils.md5DigestAsHex(hash.getBytes()));
+
+ // 保存 endpoint
+ this.saveOrUpdate(endpoint);
+ }
+ }
+
+ @Override
+ public void deleteEndpointByIds(List<Integer> ids) {
+ // 删除 endpoint
+ this.removeByIds(ids);
+ }
+
+ @Override
+ public void getExportTemplateByLanguage(HttpServletResponse response, String language) {
+ SysConfigEntity configEntity = sysConfigDao.selectOne(new LambdaQueryWrapper<SysConfigEntity>().eq(SysConfigEntity::getParamKey, Constant.SYSCONFIG_KEY_MONITORENDPOINT_EXPORT_HEADER));
+ Map map = JSONObject.parseObject(configEntity.getParamValue(), Map.class, Feature.OrderedField);
+ Map<String, String> exportHeaderMap;
+ if (map.get(language) != null) {
+ exportHeaderMap = (Map) map.get(language);
+ } else {
+ throw new NZException(RCode.ENDPOINT_EXPORT_HEADER_LANGUAGE_ERROR);
+ }
+ SXSSFWorkbook workbook = null;
+ try {
+ workbook = ExcelUtils.createExcel07(exportHeaderMap, "Endpoint", true);
+ String fileName = "EndpointExportTemplate.xlsx";
+ response.setContentType("application/excel");
+ response.setHeader("Content-disposition", "attachment;filename=" + fileName + ";filename*=utf-8''" + URLEncoder.encode(fileName, "UTF-8"));
+ workbook.write(response.getOutputStream());
+ } catch (IOException e) {
+ log.error("endpoint 模板生成失败,错误信息是:" + e);
+ } catch (Exception e) {
+ log.error("获取 endpoint 导入模板失败,表头语言是:" + language + " ,错误信息是:" + e);
+ } finally {
+ if (workbook != null) {
+ IOUtils.closeQuietly(workbook);
+ }
+ }
+ }
+
+ @Override
+ public void cancelImport(String seq) {
+ // 撤销导入
+ this.remove(new LambdaQueryWrapper<MonitorEndpoint>().eq(MonitorEndpoint::getSeq, seq));
+ }
+
+ @Override
+ public Map importEndpoint(MultipartFile excelFile, String language) {
+ Workbook work = ExcelUtils.getWorkBookFromMultipartFile(excelFile);
+
+ Sheet sheet = work.getSheetAt(0);
+
+ // 表头校验
+ SysConfigEntity config = sysConfigDao.selectOne(new QueryWrapper<SysConfigEntity>().lambda().eq(SysConfigEntity::getParamKey, Constant.SYSCONFIG_KEY_MONITORENDPOINT_EXPORT_HEADER));
+ HashMap<String, Object> map = JSONObject.parseObject(config.getParamValue(), HashMap.class, Feature.OrderedField);
+ boolean headerFlag = ExcelUtils.validateExcelHeader(sheet, sheet.getFirstRowNum(), map.values());
+ if (!headerFlag) {
+ throw new NZException(RCode.IMPORT_EXCELFILE_HEADER_TEMPLATE_ERROR);
+ }
+
+ Map<String, String> exportHeader = (Map) map.get(language);
+ List<String> headerInfos = new ArrayList(exportHeader.keySet());
+ // 预先查询出校验数据 避免循环查表
+ List<Map> failDetails = new ArrayList<>();
+ String seqUUID = UUID.randomUUID().toString();
+
+ int successNum = this.saveTmplsDataFromSheet(sheet, failDetails, headerInfos, seqUUID);
+ int totalNum = sheet.getLastRowNum() - sheet.getFirstRowNum();
+
+ Map resultMap = new HashMap(8);
+ resultMap.put("seq", seqUUID);
+ resultMap.put("totalNum", totalNum);
+ resultMap.put("successNum", successNum);
+ resultMap.put("failNum", totalNum - successNum);
+ resultMap.put("failDetail", CommonUtils.handleImportFailDetails(failDetails));
+ return resultMap;
+ }
+
+ @Override
+ public void export(HttpServletResponse response, Map<String, Object> params) {
+ IPage<MonitorEndpoint> page = new Query<MonitorEndpoint>().getPage(params);
+ List<MonitorEndpoint> list = monitorEndpointDao.queryPage(page, params);
+
+ SXSSFWorkbook workbook = null;
+ try {
+ int rowNum = 0;
+ SysConfigEntity configEntity = sysConfigDao.selectOne(new LambdaQueryWrapper<SysConfigEntity>().eq(SysConfigEntity::getParamKey, Constant.SYSCONFIG_KEY_MONITORENDPOINT_EXPORT_HEADER));
+ Map map = JSONObject.parseObject(configEntity.getParamValue(), Map.class, Feature.OrderedField);
+
+ // 添加标题行 默认语言 en
+ String language = (String) params.get("language");
+ language = ToolUtil.isEmpty(language) ? "en" : language;
+ Map<String, String> exportHeader = (Map) map.get(language);
+
+ String sheetName = "Endpoints";
+ workbook = ExcelUtils.createExcel07(exportHeader, sheetName, false);
+ SXSSFSheet sheet = workbook.getSheet(sheetName);
+ CellStyle dataStyle = ExcelUtils.createCellStyle(workbook, (short) 13, false);
+
+ // 添加数据
+ Row row1;
+ for (MonitorEndpoint endpoint : list) {
+ row1 = sheet.createRow(++rowNum);
+
+ MonitorProject project = endpoint.getProject();
+ MonitorModule module = endpoint.getModule();
+ Asset asset = endpoint.getAsset();
+
+ // project name
+ row1.createCell(0).setCellValue(project.getName());
+ // module name
+ row1.createCell(1).setCellValue(module.getName());
+ // name
+ row1.createCell(2).setCellValue(endpoint.getName());
+ // asset name
+ row1.createCell(3).setCellValue(asset.getName());
+ // port
+ row1.createCell(4).setCellValue(endpoint.getPort());
+ // config
+ row1.createCell(5).setCellValue(endpoint.getConfigs());
+ // host
+ row1.createCell(6).setCellValue(endpoint.getHost());
+ // enabled
+ row1.createCell(7).setCellValue(endpoint.getEnabled());
+
+ // 设置单元格样式
+ ExcelUtils.setDataCellStyle(dataStyle, row1, 7);
+ }
+
+ // 响应为流
+ String fileName = "EndpointsExport.xlsx"; // 默认名称
+ response.setContentType("application/excel");
+ response.setHeader("Content-disposition", "attachment;filename=" + fileName + ";filename*=utf-8''" + URLEncoder.encode(fileName, "UTF-8"));
+ workbook.write(response.getOutputStream());
+ } catch (IOException e) {
+ log.error(e);
+ } catch (Exception e) {
+ log.error(e);
+ } finally {
+ if (workbook != null) {
+ IOUtils.closeQuietly(workbook);
+ }
+ }
+ }
+
+ private int saveTmplsDataFromSheet(Sheet sheet, List<Map> failDetails, List<String> headerInfos, String seqUUID) {
+ List<MonitorProject> projectList = monitorProjectService.list();
+ Map<String, Integer> projectNameAndIdMap = projectList.stream().collect(Collectors.toMap(MonitorProject::getName, MonitorProject::getId));
+
+ List<MonitorModule> moduleList = monitorModuleService.list();
+ Map<String, MonitorModule> monitorModuleMap = moduleList.stream().collect(Collectors.toMap(MonitorModule::getName, Function.identity()));
+
+ List<MonitorEndpoint> endpoints = this.list();
+ Map<Integer, List<String>> moduleIdAndEndpointNamesMap = new HashMap<>();
+ for (MonitorModule module : moduleList) {
+ List<String> endpointNames = endpoints.stream().filter(endpoint -> endpoint.getModuleId().equals(module.getId())).map(MonitorEndpoint::getName).collect(Collectors.toList());
+ moduleIdAndEndpointNamesMap.put(module.getId(), ToolUtil.isEmpty(endpointNames) ? new ArrayList<>() : endpointNames);
+ }
+
+ List<Asset> assets = assetService.list();
+ Map<String, Integer> assetHostAndIdMap = assets.stream().collect(Collectors.toMap(Asset::getHost, Asset::getId));
+ Map<String, Integer> assetNameAndIdMap = assets.stream().collect(Collectors.toMap(Asset::getName, Asset::getId));
+ Map<Integer, String> assetIdAndHostMap = assets.stream().collect(Collectors.toMap(Asset::getId, Asset::getHost));
+
+
+ int successNum = 0;
+ Row row;
+ for (int i = sheet.getFirstRowNum() + 1; i <= sheet.getLastRowNum(); i++) {
+ row = sheet.getRow(i);
+ if (row == null) continue;
+
+ int dataFromExcelRowNum = i + 1;
+ boolean saveFlag = true;
+ Integer projectId = null;
+ String projectName = ExcelUtils.getCellValue(row.getCell(0));
+ if (StringUtils.isEmpty(projectName)) {
+ saveFlag = false;
+ this.addFailDetail(dataFromExcelRowNum, failDetails, headerInfos.get(0), RCode.PROJECT_NAME_ISNULL.getMsg());
+ } else {
+ projectId = projectNameAndIdMap.get(projectName);
+ if (projectId == null) {
+ saveFlag = false;
+ this.addFailDetail(dataFromExcelRowNum, failDetails, headerInfos.get(0), RCode.PROJECT_NOTFOUND.getMsg());
+ }
+ }
+ MonitorModule module = null;
+ String moduleName = ExcelUtils.getCellValue(row.getCell(1));
+ if (StringUtils.isEmpty(moduleName)) {
+ saveFlag = false;
+ this.addFailDetail(dataFromExcelRowNum, failDetails, headerInfos.get(1), RCode.MODULE_NAME_ISNULL.getMsg());
+ } else {
+ module = monitorModuleMap.get(moduleName);
+ if (module == null) {
+ saveFlag = false;
+ this.addFailDetail(dataFromExcelRowNum, failDetails, headerInfos.get(1), RCode.MODULE_NOTFOUND.getMsg());
+ } else {
+ if (projectId != null && !module.getProjectId().equals(projectId)) {
+ module = null;
+ saveFlag = false;
+ this.addFailDetail(dataFromExcelRowNum, failDetails, headerInfos.get(1), RCode.MODULE_NOTEXIS_PROJECT.getMsg());
+ }
+ }
+ }
+
+ String assetName = ExcelUtils.getCellValue(row.getCell(3));
+ String host = ExcelUtils.getCellValue(row.getCell(6));
+ // asset name \ host 不可同时为空
+ if (StringUtils.isEmpty(assetName) && StringUtils.isEmpty(host)) {
+ saveFlag = false;
+ this.addFailDetail(dataFromExcelRowNum, failDetails, headerInfos.get(3), RCode.ENDPOINT_ASSET_NAME_HOST_ISNULL.getMsg());
+ } else if (StringUtils.isNotEmpty(assetName) && StringUtils.isNotEmpty(host)) {
+ // 都不为空 校验 name 是否可以找到 asset , host 格式是否正确
+ if (!CommonUtils.checkIp(host)) {
+ saveFlag = false;
+ this.addFailDetail(dataFromExcelRowNum, failDetails, headerInfos.get(6), RCode.ASSET_HOST_FORMAT.getMsg());
+ }
+ if (ToolUtil.isEmpty(assetNameAndIdMap.get(assetName))) {
+ saveFlag = false;
+ this.addFailDetail(dataFromExcelRowNum, failDetails, headerInfos.get(3), RCode.ASSET_NOT_EXIST.getMsg());
+ }
+ } else if (StringUtils.isNotEmpty(assetName) && StringUtils.isEmpty(host)) {
+ if (ToolUtil.isEmpty(assetNameAndIdMap.get(assetName))) {
+ saveFlag = false;
+ this.addFailDetail(dataFromExcelRowNum, failDetails, headerInfos.get(3), RCode.ASSET_NOT_EXIST.getMsg());
+ }
+ } else if (StringUtils.isEmpty(assetName) && StringUtils.isNotEmpty(host)) {
+ if (!CommonUtils.checkIp(host)) {
+ saveFlag = false;
+ this.addFailDetail(dataFromExcelRowNum, failDetails, headerInfos.get(6), RCode.ASSET_HOST_FORMAT.getMsg());
+ }
+ if (ToolUtil.isEmpty(assetHostAndIdMap.get(host))) {
+ saveFlag = false;
+ this.addFailDetail(dataFromExcelRowNum, failDetails, headerInfos.get(6), RCode.ASSET_NOT_EXIST.getMsg());
+ }
+ }
+
+ String port = ExcelUtils.getCellValue(row.getCell(4));
+ if (StringUtils.isNotEmpty(port)) {
+ try {
+ Double aDouble = Double.valueOf(port);
+ if (!CommonUtils.checkPort(String.valueOf(aDouble.intValue()))) {
+ saveFlag = false;
+ this.addFailDetail(dataFromExcelRowNum, failDetails, headerInfos.get(4), RCode.MODULE_PORT_ERROR.getMsg());
+ }
+ } catch (NumberFormatException e) {
+ saveFlag = false;
+ this.addFailDetail(dataFromExcelRowNum, failDetails, headerInfos.get(4), RCode.MODULE_PORT_ERROR.getMsg());
+ }
+ }
+ String configs = ExcelUtils.getCellValue(row.getCell(5));
+ if (StringUtils.isNotEmpty(configs)) {
+ try {
+ JSONObject.parseObject(configs, Map.class);
+ } catch (JSONException e) {
+ saveFlag = false;
+ this.addFailDetail(dataFromExcelRowNum, failDetails, headerInfos.get(4), RCode.ENDPOINT_CONFIGS_FORMAT.getMsg());
+ }
+ }
+
+ String enabled = ExcelUtils.getCellValue(row.getCell(7));
+ if (StringUtils.isNotEmpty(enabled)) {
+ if (!"1".equals(enabled) && !"0".equals(enabled)) {
+ saveFlag = false;
+ this.addFailDetail(dataFromExcelRowNum, failDetails, headerInfos.get(7), RCode.ENDPOINT_ENABLED_INVALIDE.getMsg());
+ }
+ }
+
+ if (saveFlag) {
+ Integer assetIdByName = assetNameAndIdMap.get(assetName);
+ Integer assetIdByHost = assetHostAndIdMap.get(host);
+
+ MonitorEndpoint monitorEndpoint = new MonitorEndpoint();
+
+ // endpoint asset_id endpoint_host
+ if (StringUtils.isNotEmpty(assetName) && StringUtils.isNotEmpty(host)) {
+ monitorEndpoint.setAssetId(assetIdByName);
+ monitorEndpoint.setHost(host);
+ } else if (StringUtils.isNotEmpty(assetName) && StringUtils.isEmpty(host)) {
+ monitorEndpoint.setAssetId(assetIdByName);
+ monitorEndpoint.setHost(assetIdAndHostMap.get(assetIdByName));
+ } else if (StringUtils.isEmpty(assetName) && StringUtils.isNotEmpty(host)) {
+ monitorEndpoint.setAssetId(assetIdByHost);
+ monitorEndpoint.setHost(assetIdAndHostMap.get(assetIdByHost));
+ }
+
+ String name = ExcelUtils.getCellValue(row.getCell(2));
+ if (StringUtils.isEmpty(name)) {
+ String endpointNameTmpl = module.getEndpointNameTmpl();
+ Map varsVal = new HashMap(4);
+ varsVal.put("asset.host", assetIdAndHostMap.get(monitorEndpoint.getAssetId()));
+ varsVal.put("module.name", module.getName());
+ name = expreTmplService.renderExpression(endpointNameTmpl, varsVal);
+ }
+
+ List<String> monitorEndpointNameList = moduleIdAndEndpointNamesMap.get(module.getId());
+ String tempName = name;
+ String monitorEndpointName = monitorEndpointNameList.stream().filter(s -> s.equals(tempName)).findAny().orElse(null);
+ if (ToolUtil.isNotEmpty(monitorEndpointName)) {
+ this.addFailDetail(dataFromExcelRowNum, failDetails, headerInfos.get(2), RCode.ENDPOINT_NAME_DUPLICATE.getMsg());
+ continue;
+ }
+
+
+ if (StringUtils.isEmpty(configs)) {
+ configs = module.getConfigs();
+ }
+
+ monitorEndpoint.setName(name);
+ monitorEndpoint.setConfigs(configs);
+ monitorEndpoint.setModuleId(module.getId());
+ monitorEndpoint.setPort(ToolUtil.isEmpty(port) ? module.getPort() : Double.valueOf(port).intValue());
+ monitorEndpoint.setEnabled(ToolUtil.isEmpty(enabled) ? 1 : Double.valueOf(enabled).intValue());
+ monitorEndpoint.setSeq(seqUUID);
+
+ String hash = module.getId() + monitorEndpoint.getAssetId() + monitorEndpoint.getHost() + monitorEndpoint.getPort() + monitorEndpoint.getConfigs();
+ monitorEndpoint.setHash(DigestUtils.md5DigestAsHex(hash.getBytes()));
+
+ try {
+ this.save(monitorEndpoint);
+ successNum++;
+
+ monitorEndpointNameList.add(name);
+ moduleIdAndEndpointNamesMap.put(module.getId(), monitorEndpointNameList);
+ } catch (Exception e) {
+ log.error(String.format("endpoint 导入保存失败,表达式信息是:%s,错误信息是:%s", monitorEndpoint.toString(), e));
+ this.addFailDetail(dataFromExcelRowNum, failDetails, "System", RCode.ENDPOINT_IMPORT_ERROR.getMsg());
+ }
+ }
+ }
+ return successNum;
+ }
+
+ private void addFailDetail(int i, List<Map> failDetails, String headerInfo, String msg) {
+ Map failDetail = new HashMap(4);
+ failDetail.put("lineNo", i);
+ failDetail.put("errorMsg", headerInfo + ": " + msg);
+ failDetails.add(failDetail);
+ }
+}
diff --git a/nz-admin/src/main/java/com/nis/modules/module/controller/MonitorModuleController.java b/nz-admin/src/main/java/com/nis/modules/module/controller/MonitorModuleController.java
new file mode 100644
index 00000000..823846d0
--- /dev/null
+++ b/nz-admin/src/main/java/com/nis/modules/module/controller/MonitorModuleController.java
@@ -0,0 +1,99 @@
+package com.nis.modules.module.controller;
+
+import com.nis.common.annotation.SysLog;
+import com.nis.common.smartvalidate.ValidateUtils;
+import com.nis.common.utils.*;
+import com.nis.modules.module.entity.MonitorModule;
+import com.nis.modules.module.service.MonitorModuleService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/monitor")
+public class MonitorModuleController {
+
+ @Autowired
+ private MonitorModuleService monitorModuleService;
+
+ /**
+ * 详情
+ *
+ * @param id
+ * @return
+ */
+ @GetMapping("/module/{id}")
+ @SysLog(operation = OperationEnum.QUERY, type = TypeEnum.MODULE)
+ public R queryModuleEntity(@PathVariable("id") Integer id) {
+ return R.ok(monitorModuleService.queryModuleEntity(id));
+ }
+
+ /**
+ * 列表
+ *
+ * @param params
+ * @return
+ */
+ @GetMapping("/module")
+ @SysLog(operation = OperationEnum.QUERY, type = TypeEnum.MODULE)
+ public R queryModulePage(@RequestParam Map<String, Object> params) {
+ PageUtils page = monitorModuleService.queryPage(params);
+ return R.ok(page);
+ }
+
+ /**
+ * module tree 两级列表 project -> module
+ *
+ * @param name
+ * @return
+ */
+ @GetMapping("/module/tree")
+ @SysLog(operation = OperationEnum.QUERY, type = TypeEnum.MODULE)
+ public R queryModuleTree(String name) {
+ Map map = new HashMap(2);
+ map.put("list", monitorModuleService.queryModuleTree(name));
+ return R.ok(map);
+ }
+
+ @PostMapping("/module")
+ @SysLog(operation = OperationEnum.ADD, type = TypeEnum.MODULE)
+ public R saveModule(@RequestBody MonitorModule module) {
+ ValidateUtils.is(module.getProjectId()).notNull(RCode.MODULE_PROJECTID_ISNULL)
+ .and(module.getName()).notNull(RCode.MODULE_NAME_ISNULL)
+ .and(module.getEndpointNameTmpl()).notNull(RCode.MODULE_ENDPOINTNAMETMPL_ISNULL)
+ .and(module.getType()).notNull(RCode.MODULE_TYPE_ISNULL)
+ .and(module.getConfigs()).notNull(RCode.MODULE_CONFIGS_ISNULL);
+
+ Map map = new HashMap(2);
+ map.put("id", monitorModuleService.saveModule(module));
+ return R.ok(map);
+ }
+
+ @PutMapping("/module")
+ @SysLog(operation = OperationEnum.UPDATE, type = TypeEnum.MODULE)
+ public R editModule(@RequestBody MonitorModule module) {
+ ValidateUtils.is(module.getId()).notNull(RCode.MODULE_ID_ISNULL)
+ .and(module.getProjectId()).notNull(RCode.MODULE_PROJECTID_ISNULL)
+ .and(module.getName()).notNull(RCode.MODULE_NAME_ISNULL)
+ .and(module.getEndpointNameTmpl()).notNull(RCode.MODULE_ENDPOINTNAMETMPL_ISNULL)
+ .and(module.getType()).notNull(RCode.MODULE_TYPE_ISNULL)
+ .and(module.getConfigs()).notNull(RCode.MODULE_CONFIGS_ISNULL);
+
+ Map map = new HashMap(2);
+ map.put("id", monitorModuleService.updateModule(module));
+ return R.ok(map);
+ }
+
+
+ @DeleteMapping("/module")
+ @SysLog(operation = OperationEnum.DELETE, type = TypeEnum.MODULE)
+ public R remove(@RequestParam Integer... ids) {
+ ValidateUtils.is(ids).notNull(RCode.MODULE_ID_ISNULL);
+ monitorModuleService.removeModules(ids);
+ return R.ok();
+ }
+
+
+}
diff --git a/nz-admin/src/main/java/com/nis/modules/module/dao/MonitorModuleDao.java b/nz-admin/src/main/java/com/nis/modules/module/dao/MonitorModuleDao.java
new file mode 100644
index 00000000..22ba3887
--- /dev/null
+++ b/nz-admin/src/main/java/com/nis/modules/module/dao/MonitorModuleDao.java
@@ -0,0 +1,19 @@
+package com.nis.modules.module.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.nis.modules.module.entity.MonitorModule;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import java.util.Map;
+
+@Mapper
+@Repository
+public interface MonitorModuleDao extends BaseMapper<MonitorModule> {
+
+ List<MonitorModule> queryPage(IPage<MonitorModule> page, @Param("params") Map<String, Object> params);
+
+}
diff --git a/nz-admin/src/main/java/com/nis/modules/module/entity/MonitorModule.java b/nz-admin/src/main/java/com/nis/modules/module/entity/MonitorModule.java
new file mode 100644
index 00000000..0348266d
--- /dev/null
+++ b/nz-admin/src/main/java/com/nis/modules/module/entity/MonitorModule.java
@@ -0,0 +1,85 @@
+package com.nis.modules.module.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.nis.modules.endpoint.entity.MonitorEndpoint;
+import com.nis.modules.project.entity.MonitorProject;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+@TableName("monitor_module")
+public class MonitorModule implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键
+ */
+ @TableId(type = IdType.AUTO)
+ private Integer id;
+
+ /**
+ * 组件名称
+ */
+ private String name;
+
+ /**
+ * 业务系统id
+ */
+ private Integer projectId;
+
+ /**
+ * modulle 类型 可选值 : http 、snmp
+ */
+ private String type;
+
+ /**
+ * endpoint name模板
+ * 支持 {{}} 变量替换,asset,module
+ * 例:{{asset.name}}-{{module.name}}
+ * 最终endpoint的name为: 192.168.40.1-mysql
+ */
+ private String endpointNameTmpl;
+
+ /**
+ * 端口
+ */
+ private Integer port;
+
+
+ /**
+ * 描述
+ */
+ private String remark;
+
+ /**
+ * 配置参数
+ */
+ private String configs;
+
+
+ /**
+ * snmp_exporter需要的配置部分, 由web端根据snmp_param生成
+ */
+ private String snmpYml;
+
+ /**
+ * 是否内置 1:内置,0:非内置,默认:0 内置数据不允许删除
+ */
+ private Integer buildIn;
+
+ private String seq;
+
+ @TableField(exist = false)
+ private MonitorProject project;
+
+ /**
+ * endpoint 列表
+ */
+ @TableField(exist = false)
+ private List<MonitorEndpoint> children;
+}
diff --git a/nz-admin/src/main/java/com/nis/modules/module/service/MonitorModuleService.java b/nz-admin/src/main/java/com/nis/modules/module/service/MonitorModuleService.java
new file mode 100644
index 00000000..bfea6e9b
--- /dev/null
+++ b/nz-admin/src/main/java/com/nis/modules/module/service/MonitorModuleService.java
@@ -0,0 +1,24 @@
+package com.nis.modules.module.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.nis.common.utils.PageUtils;
+import com.nis.modules.module.entity.MonitorModule;
+import com.nis.modules.project.entity.MonitorProject;
+
+import java.util.List;
+import java.util.Map;
+
+public interface MonitorModuleService extends IService<MonitorModule> {
+
+ MonitorModule queryModuleEntity(Integer id);
+
+ PageUtils queryPage(Map<String, Object> params);
+
+ List<MonitorProject> queryModuleTree(String name);
+
+ Integer saveModule(MonitorModule module);
+
+ Integer updateModule(MonitorModule module);
+
+ void removeModules(Integer... ids);
+}
diff --git a/nz-admin/src/main/java/com/nis/modules/module/service/impl/MonitorModuleServiceImpl.java b/nz-admin/src/main/java/com/nis/modules/module/service/impl/MonitorModuleServiceImpl.java
new file mode 100644
index 00000000..0f37ab98
--- /dev/null
+++ b/nz-admin/src/main/java/com/nis/modules/module/service/impl/MonitorModuleServiceImpl.java
@@ -0,0 +1,313 @@
+package com.nis.modules.module.service.impl;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.log.Log;
+import com.alibaba.fastjson.JSONException;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.nis.common.exception.NZException;
+import com.nis.common.utils.*;
+import com.nis.modules.endpoint.entity.MonitorEndpoint;
+import com.nis.modules.endpoint.service.MonitorEndpointService;
+import com.nis.modules.module.dao.MonitorModuleDao;
+import com.nis.modules.module.entity.MonitorModule;
+import com.nis.modules.module.service.MonitorModuleService;
+import com.nis.modules.project.entity.MonitorProject;
+import com.nis.modules.project.service.MonitorProjectService;
+import com.nis.modules.project.service.TopoService;
+import com.nis.modules.sys.entity.SysConfigEntity;
+import com.nis.modules.sys.service.SysConfigService;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.io.IOUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.io.*;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Service
+public class MonitorModuleServiceImpl extends ServiceImpl<MonitorModuleDao, MonitorModule> implements MonitorModuleService {
+
+ protected Log log = Log.get();
+
+ @Autowired
+ private YamlUtil yamlUtil;
+
+ @Autowired
+ private TopoService topoService;
+
+ @Autowired
+ private MonitorModuleDao monitorModuleDao;
+
+ @Autowired
+ private SysConfigService sysConfigService;
+
+ @Autowired
+ private MonitorProjectService monitorProjectService;
+
+ @Autowired
+ private MonitorEndpointService monitorEndpointService;
+
+
+ @Override
+ public MonitorModule queryModuleEntity(Integer id) {
+ MonitorModule module = this.getById(id);
+ if (ToolUtil.isEmpty(module)) {
+ throw new NZException(RCode.MODULE_NOTFOUND);
+ }
+ MonitorProject project = monitorProjectService.getById(module.getProjectId());
+ module.setProject(project);
+ return module;
+ }
+
+ @Override
+ public PageUtils queryPage(Map<String, Object> params) {
+ IPage<MonitorModule> page = new Query<MonitorModule>().getPage(params);
+ List<MonitorModule> datas = monitorModuleDao.queryPage(page, params);
+ page.setRecords(datas);
+ return new PageUtils(page);
+ }
+
+ @Override
+ public List<MonitorProject> queryModuleTree(String name) {
+ List<MonitorModule> moduleList = this.list(new LambdaQueryWrapper<MonitorModule>().like(StringUtils.isNotEmpty(name), MonitorModule::getName, name));
+ if (CollectionUtils.isEmpty(moduleList)) {
+ return Collections.emptyList();
+ }
+
+ List<Integer> projectIdList = moduleList.stream().map(MonitorModule::getProjectId).distinct().collect(Collectors.toList());
+ List<MonitorProject> projectList = monitorProjectService.list(new LambdaQueryWrapper<MonitorProject>().in(MonitorProject::getId, projectIdList));
+
+ List<MonitorModule> projectModules;
+ for (MonitorProject project : projectList) {
+ projectModules = new ArrayList<>();
+ for (MonitorModule module : moduleList) {
+ if (project.getId().equals(module.getProjectId())) {
+ projectModules.add(module);
+ }
+ }
+ project.setChildren(projectModules);
+ }
+ return projectList;
+ }
+
+ private void validateModuleInfo(MonitorModule module) {
+ // 1. 校验 project 是否存在
+ MonitorProject project = monitorProjectService.getById(module.getProjectId());
+ if (ToolUtil.isEmpty(project)) {
+ throw new NZException(RCode.PROJECT_NOTFOUND);
+ }
+
+ // 2. 名称不能重复
+ List<MonitorModule> list = this.list(new QueryWrapper<MonitorModule>().lambda().eq(MonitorModule::getName, module.getName()));
+ boolean flag = false;
+ // 当只有一个结果并且这个结果是自身时,或没有结果时,说明名称不重复
+ if ((list == null || list.size() == 0) ||
+ (list != null && list.size() == 1 && list.get(0).getId().equals(module.getId()))) {
+ flag = true;
+ }
+
+ if (!flag) {
+ throw new NZException(RCode.MODULE_NAME_DUPLICATE);
+ }
+
+ // 3.校验 type 类型是否在枚举范围内
+ String type = module.getType();
+ if (!StrUtil.equals(Constant.MODULE_TYPE_HTTP, type) && !StrUtil.equals(Constant.MODULE_TYPE_SNMP, type)) {
+ throw new NZException(RCode.MODULE_TYPE_INVALID);
+ }
+
+ // 4. 端口校验
+ if (module.getPort() != null) {
+ flag = CommonUtils.checkPort(module.getPort().toString());
+ if (!flag) {
+ throw new NZException(RCode.MODULE_PORT_ERROR);
+ }
+ }
+
+ // 5. config 格式校验
+ Map configMap;
+ try {
+ configMap = JSONObject.parseObject(module.getConfigs(), Map.class);
+ } catch (JSONException e) {
+ throw new NZException(RCode.MODULE_CONFIGS_FORMAT);
+ }
+
+ // snmp 类型校验 config
+ if (StrUtil.equals(Constant.MODULE_TYPE_SNMP, type)) {
+ // 注: snmp version 实际版本 为 1,2,3 ,此处只做 2,3 版本限制
+ Integer version = (Integer) configMap.get("version");
+ if (version != null) {
+ if (version < 2 || version > 3) {
+ // 版本不在可选范围内
+ throw new NZException(RCode.MODULE_SNMPVERSION_INVALID);
+ }
+
+ if (version.equals(3)) {
+ SnmpUtil.ValidateAuthForSnmpV3((Map<String, String>) configMap.get("auth"));
+ }
+ }
+ }
+ }
+
+ @Override
+ public Integer saveModule(MonitorModule module) {
+ // 1. 校验
+ this.validateModuleInfo(module);
+
+ // 2. snmp 类型处理
+ if (StrUtil.equals(Constant.MODULE_TYPE_SNMP, module.getType())) {
+ // port 缺省值
+ if (ToolUtil.isEmpty(module.getPort())) {
+ module.setPort(Constant.SNMP_DEFAULT_PORT);
+ }
+
+ // 处理snmYml字段
+ String configs = module.getConfigs();
+ String snmpYml = this.generateYmlFromSnmpParam(JSONObject.parseObject(configs, Map.class), module);
+ module.setSnmpYml(snmpYml);
+ }
+
+ // 3. endpointNameTmpl
+ if (ToolUtil.isEmpty(module.getEndpointNameTmpl())) {
+ module.setEndpointNameTmpl("{{asse.host}}-{{module.name}}");
+ }
+
+ // 保存
+ this.save(module);
+ return module.getId();
+ }
+
+ @Override
+ public Integer updateModule(MonitorModule moduleEntity) {
+ // 1. 内置 moduel 不允许修改
+ MonitorModule oldModule = this.getById(moduleEntity.getId());
+ if (ToolUtil.isEmpty(oldModule)) {
+ throw new NZException(RCode.MODULE_NOTFOUND);
+ }
+
+ if (oldModule.getBuildIn().equals(1)) {
+ throw new NZException(RCode.MODULE_BUILDIN_CAN_NOT_REMOVE);
+ }
+
+ // 2. 校验
+ this.validateModuleInfo(moduleEntity);
+
+ // 3. snmp 类型 , 处理 snmpYml 字段 , 如果 module 名称发生改动
+ if (StrUtil.equals(Constant.MODULE_TYPE_SNMP, moduleEntity.getType())) {
+ String snmpYml = this.generateYmlFromSnmpParam(JSONObject.parseObject(moduleEntity.getConfigs(), Map.class), moduleEntity);
+ moduleEntity.setSnmpYml(snmpYml);
+ }else{
+ moduleEntity.setSnmpYml("{}");
+ }
+
+ // 4. 修改了 project , 修改 topo config
+ if (!oldModule.getProjectId().equals(moduleEntity.getProjectId())) {
+ List<MonitorModule> modules = new ArrayList();
+ modules.add(oldModule);
+ topoService.removeTopoConfigNodeAndLineByModules(modules);
+ }
+
+ // 保存
+ this.updateById(moduleEntity);
+ return moduleEntity.getId();
+ }
+
+ @Override
+ public void removeModules(Integer... ids) {
+ List<MonitorModule> list = this.list();
+
+ // 1. 内置的 配置不允许删除
+ List<Integer> buildInIdList = list.stream().filter(assetTypeConf -> assetTypeConf.getBuildIn().equals(1)).map(MonitorModule::getId).collect(Collectors.toList());
+ buildInIdList.retainAll(Arrays.asList(ids));
+ if (CollectionUtils.isNotEmpty(buildInIdList)) {
+ throw new NZException("These modules are built-in and cannot be deleted. Details: " + buildInIdList.toString(), RCode.MODULE_BUILDIN_CAN_NOT_REMOVE.getCode());
+ }
+
+ // 2. 含有 endpoint 的 module 不允许删除
+ List<MonitorEndpoint> monitorEndpointList = monitorEndpointService.list();
+ List<Integer> userModuleIdList = monitorEndpointList.stream().map(MonitorEndpoint::getModuleId).distinct().collect(Collectors.toList());
+ userModuleIdList.retainAll(Arrays.asList(ids));
+ if (CollectionUtils.isNotEmpty(userModuleIdList)) {
+ throw new NZException("These modules have been used by endpoints and cannot be deleted. Details: " + userModuleIdList.toString(), RCode.MODULE_REMOVE_ERROR.getCode());
+ }
+
+ // 删除
+ this.removeByIds(Arrays.asList(ids));
+ }
+
+ public String generateYmlFromSnmpParam(Map snmpParam, MonitorModule moduleEntity) {
+ // 取出generator路径
+ SysConfigEntity entity = sysConfigService.getOne(new QueryWrapper<SysConfigEntity>().lambda().eq(SysConfigEntity::getParamKey, Constant.SYSCONFIG_KEY_GENERATOR_PATH));
+ String generatorPath = entity.getParamValue();
+
+ Map modules = new HashMap();
+
+ Map module = new HashMap();
+ module.put(moduleEntity.getName(), snmpParam);
+
+ modules.put("modules", module);
+
+ try {
+ log.debug("开始将 snmp参数写入 generator.yml 文件");
+
+ // 将json写入到generator.yml文件中
+ yamlUtil.createYaml(generatorPath + File.separator + "generator.yml", JSONObject.toJSONString(modules));
+
+ log.debug("将 snmp参数成功写入 generator.yml 文件");
+ } catch (JsonProcessingException e) {
+ log.error("将 snmp参数写入 generator.yml 文件失败,参数信息是:" + JSONObject.toJSONString(modules), e);
+ } catch (IOException e) {
+ log.error("将 snmp参数写入 generator.yml 文件失败,参数信息是:" + JSONObject.toJSONString(modules), e);
+ }
+
+ StringReader result = null;
+ StringWriter sw = null;
+ try {
+ log.debug("开始生成 snmp.yml 文件");
+
+ // 先设置环境变量 然后 赋可执行权限 最后 执行生成命令
+ String[] envp = {"MIBDIRS=" + generatorPath + File.separator + "mibs"};
+ String generatorFile = generatorPath + File.separator + "generator";
+ String[] chmodCommand = {"chmod", "+x", generatorFile};
+ String[] generateCommand = {generatorFile, "generate"};
+ result = RuntimeUtil.run(envp, new File(generatorPath), chmodCommand, generateCommand);
+
+ sw = new StringWriter();
+ char[] buf = new char[1024];
+ while (result.read(buf) != -1) {
+ sw.write(buf);
+ }
+
+ log.debug("成功生成 snmp.yml 文件 {}", sw.toString());
+ } catch (Exception e) {
+ log.error("生成 snmp.yml 文件失败", e);
+ } finally {
+ if (sw != null) {
+ IOUtils.closeQuietly(sw);
+ }
+ if (result != null) {
+ IOUtils.closeQuietly(result);
+ }
+ }
+
+ String snmpYml = null;
+
+ try {
+ // 读取生成之后的snmp.yml 并以json格式
+ snmpYml = yamlUtil.yamlToJson(generatorPath + File.separator + "snmp.yml");
+ log.debug("读取 snmp.yml 文件的内容成功");
+ } catch (FileNotFoundException e) {
+ log.error("无法读取snmp.yml文件的内容,找不到 snmp.yml 文件", e);
+ } catch (Exception e) {
+ log.error("无法读取snmp.yml文件的内容", e);
+ }
+ return snmpYml;
+ }
+
+}
diff --git a/nz-admin/src/main/java/com/nis/modules/panel/service/ExpreTmplService.java b/nz-admin/src/main/java/com/nis/modules/panel/service/ExpreTmplService.java
index 639d69ca..fd2f752a 100644
--- a/nz-admin/src/main/java/com/nis/modules/panel/service/ExpreTmplService.java
+++ b/nz-admin/src/main/java/com/nis/modules/panel/service/ExpreTmplService.java
@@ -31,6 +31,8 @@ public interface ExpreTmplService extends IService<ExpressionTmpl> {
String renderExpression(ExpressionTmpl tmpl);
+ String renderExpression(String expression, Map varsVal);
+
void getExportTemplateByLanguage(HttpServletResponse response, String language);
Map importExpreTmplsFromExcel(MultipartFile excelFile, String language);
diff --git a/nz-admin/src/main/java/com/nis/modules/panel/service/impl/ExpreTmplServiceImpl.java b/nz-admin/src/main/java/com/nis/modules/panel/service/impl/ExpreTmplServiceImpl.java
index f39b87d0..c753c179 100644
--- a/nz-admin/src/main/java/com/nis/modules/panel/service/impl/ExpreTmplServiceImpl.java
+++ b/nz-admin/src/main/java/com/nis/modules/panel/service/impl/ExpreTmplServiceImpl.java
@@ -162,6 +162,17 @@ public class ExpreTmplServiceImpl extends ServiceImpl<ExpreTmplDao, ExpressionTm
String expression = tmpl.getExpression();
Map varsVal = tmpl.getVarsVal();
+ expression = this.generateExpression(expression, varsVal);
+ return expression;
+ }
+
+ @Override
+ public String renderExpression(String expression, Map varsVal) {
+ expression = this.generateExpression(expression, varsVal);
+ return expression;
+ }
+
+ private String generateExpression(String expression, Map varsVal) {
String[] vars = this.parseExpre(expression);
for (int i = 0; i < vars.length; i++) {
Object o = varsVal.get(vars[i]);
@@ -207,28 +218,9 @@ public class ExpreTmplServiceImpl extends ServiceImpl<ExpreTmplDao, ExpressionTm
}
}
- private Workbook getWorkBookFromFile(MultipartFile excelFile) {
- if (!ExcelUtils.validateFileType(excelFile.getOriginalFilename())) {
- throw new NZException(RCode.EXPRETMPL_IMPORTFILE_TYPE);
- }
-
- Workbook work = null;
- try {
- work = ExcelUtils.getWork(excelFile.getOriginalFilename(), excelFile.getInputStream());
- } catch (IOException e) {
- logger.error("解析导入表达式模板文件格式有误", e);
- throw new NZException(RCode.EXPRETMPL_IMPORTFILE_FAILED);
- } finally {
- if (work != null) {
- IOUtils.closeQuietly(work);
- }
- }
- return work;
- }
-
@Override
public Map importExpreTmplsFromExcel(MultipartFile excelFile, String language) {
- Workbook work = this.getWorkBookFromFile(excelFile);
+ Workbook work = ExcelUtils.getWorkBookFromMultipartFile(excelFile);
Sheet sheet = work.getSheetAt(0);
diff --git a/nz-admin/src/main/java/com/nis/modules/project/controller/MonitorProjectController.java b/nz-admin/src/main/java/com/nis/modules/project/controller/MonitorProjectController.java
new file mode 100644
index 00000000..b28d56c1
--- /dev/null
+++ b/nz-admin/src/main/java/com/nis/modules/project/controller/MonitorProjectController.java
@@ -0,0 +1,253 @@
+package com.nis.modules.project.controller;
+
+import com.nis.common.annotation.SysLog;
+import com.nis.common.smartvalidate.ValidateUtils;
+import com.nis.common.utils.*;
+import com.nis.modules.project.entity.MonitorProject;
+import com.nis.modules.project.entity.TopoIcon;
+import com.nis.modules.project.service.MonitorProjectService;
+import com.nis.modules.project.service.TopoIconService;
+import com.nis.modules.project.service.TopoService;
+import com.nis.modules.sys.controller.AbstractController;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/monitor")
+public class MonitorProjectController extends AbstractController {
+
+ @Autowired
+ private TopoService topoService;
+
+ @Autowired
+ private TopoIconService topoIconService;
+
+ @Autowired
+ private MonitorProjectService monitorProjectService;
+
+ /**
+ * 详情
+ *
+ * @param id
+ * @return
+ */
+ @GetMapping("/project/{id}")
+ @SysLog(operation = OperationEnum.QUERY, type = TypeEnum.PROJECT)
+ public R queryProjectEntity(@PathVariable("id") Integer id) {
+ return R.ok(monitorProjectService.queryProjectEntity(id));
+ }
+
+ /**
+ * project 查询
+ *
+ * @param params
+ * @return
+ */
+ @GetMapping("/project")
+ @SysLog(operation = OperationEnum.QUERY, type = TypeEnum.PROJECT)
+ public R queryProjectPage(@RequestParam Map<String, Object> params) {
+ PageUtils page = monitorProjectService.queryPage(params);
+ return R.ok(page);
+ }
+
+ /**
+ * 新增 project
+ *
+ * @param project
+ * @return
+ */
+ @PostMapping("/project")
+ @SysLog(operation = OperationEnum.ADD, type = TypeEnum.PROJECT)
+ public R saveProject(@RequestBody MonitorProject project) {
+ ValidateUtils.is(project.getName()).notNull(RCode.PROJECT_NAME_ISNULL);
+
+ Map map = new HashMap(2);
+ map.put("id", monitorProjectService.saveProject(project));
+ return R.ok(map);
+ }
+
+ /**
+ * 修改 project
+ *
+ * @param project
+ * @return
+ */
+ @PutMapping("/project")
+ @SysLog(operation = OperationEnum.UPDATE, type = TypeEnum.PROJECT)
+ public R editProject(@RequestBody MonitorProject project) {
+ ValidateUtils.is(project.getId()).notNull(RCode.PROJECT_ID_ISNULL)
+ .and(project.getName()).notNull(RCode.PROJECT_NAME_ISNULL);
+
+ Map map = new HashMap(2);
+ map.put("id", monitorProjectService.updateProject(project));
+ return R.ok(map);
+ }
+
+ /**
+ * project 删除
+ * @param ids
+ * @return
+ */
+ @DeleteMapping("/project")
+ @SysLog(operation = OperationEnum.DELETE, type = TypeEnum.PROJECT)
+ public R deleteProjects(@RequestParam Integer... ids) {
+ ValidateUtils.is(ids).notNull(RCode.PROJECT_ID_ISNULL);
+
+ monitorProjectService.delete(ids);
+ return R.ok();
+ }
+
+ /**
+ * project 详情,包含统计数据
+ * @param id
+ * @return
+ */
+ @GetMapping("/project/info")
+ @SysLog(operation = OperationEnum.QUERY, type = TypeEnum.PROJECT)
+ public R queryProjectInfo(@RequestParam Integer id) {
+ ValidateUtils.is(id).notNull(RCode.PROJECT_ID_ISNULL);
+
+ Map<String, Object> result = monitorProjectService.queryProjectInfo(id);
+ return R.ok(result);
+ }
+
+
+ /**
+ * icon unit 查询
+ */
+ @GetMapping("/project/topo/iconUnit")
+ @SysLog(operation = OperationEnum.QUERY, type = TypeEnum.TOPO)
+ public R queryTopoUnit(String name) {
+ List<String> result = topoIconService.queryTopoIconUnitName(name);
+ return R.ok(result);
+ }
+
+ /**
+ * topo icon unit 删除
+ *
+ * @param unit
+ * @return
+ */
+ @DeleteMapping("/project/topo/iconUnit")
+ @SysLog(operation = OperationEnum.QUERY, type = TypeEnum.TOPO)
+ public R deleteTopoUnit(String unit) {
+ ValidateUtils.is(unit).notNull(RCode.PROJECT_TOPOICON_UNIT_ISNULL);
+
+ topoIconService.deleteTopoIconByUnit(unit);
+ return R.ok();
+ }
+
+
+ /**
+ * topo icon查询
+ *
+ * @param params
+ * @return
+ */
+ @GetMapping("/project/topo/icon")
+ @SysLog(operation = OperationEnum.QUERY, type = TypeEnum.PROJECT)
+ public R queryIconList(@RequestParam Map<String, Object> params) {
+ Map result = new HashMap(2);
+ List<TopoIcon> topoIcons = topoIconService.queryIconList(params);
+ result.put("list", topoIcons);
+ return R.ok(result);
+ }
+
+ /**
+ * topo icon新增
+ *
+ * @param name
+ * @param file
+ * @return
+ */
+ @PostMapping("/project/topo/icon")
+ @SysLog(operation = OperationEnum.ADD, type = TypeEnum.PROJECT)
+ public R save(String name, @RequestParam(value = "file", required = false) MultipartFile file, String unit) {
+ ValidateUtils.is(name).notNull(RCode.PROJECT_TOPOICON_NAME_ISNULL)
+ .and(unit).notNull(RCode.PROJECT_TOPOICON_UNIT_ISNULL)
+ .and(file).notNull(RCode.PROJECT_TOPOICON_FILE_ISNULL);
+
+
+ try {
+ Integer iconId = topoIconService.saveTopoIcon(name, file, unit);
+ Map result = new HashMap(2);
+ result.put("id", iconId);
+ return R.ok(result);
+ } catch (IOException e) {
+ logger.error("拓朴图图标保存失败,错误信息是:" + e);
+ return R.error(RCode.ERROR);
+ }
+ }
+
+
+ /**
+ * topo icon删除
+ *
+ * @param ids
+ * @return
+ */
+ @DeleteMapping("/project/topo/icon")
+ @SysLog(operation = OperationEnum.DELETE, type = TypeEnum.PROJECT)
+ public R removeIcons(@RequestParam Integer... ids) {
+ ValidateUtils.is(ids).notNull(RCode.PROJECT_ID_ISNULL);
+
+ topoIconService.removeIcons(ids);
+ return R.ok();
+ }
+
+ /**
+ * icon图标预览
+ *
+ * @param id
+ * @param response
+ */
+ @GetMapping("/project/topo/icon/{id}")
+ public void downloadIconFile(@PathVariable("id") Integer id, HttpServletResponse response) {
+ ValidateUtils.is(id).notNull(RCode.PROJECT_ICONID_ISNULL);
+
+ topoIconService.downloadIconFileById(id, response);
+ }
+
+
+ /**
+ * 系统topo查询
+ *
+ * @param projectId
+ */
+ @GetMapping("/project/topo")
+ @SysLog(operation = OperationEnum.QUERY, type = TypeEnum.TOPO)
+ public R queryTopo(Integer projectId) {
+ ValidateUtils.is(projectId).notNull(RCode.PROJECT_ID_ISNULL);
+
+ Map result = new HashMap(2);
+ result.put("topo", topoService.queryTopoByProjectId(projectId));
+ return R.ok(result);
+ }
+
+ /**
+ * 系统topo编辑
+ *
+ * @param params
+ * @return
+ */
+ @PutMapping("/project/topo")
+ @SysLog(operation = OperationEnum.UPDATE, type = TypeEnum.TOPO)
+ public R updateProjectTopo(@RequestBody Map<String, Object> params) {
+ Integer projectId = (Integer) params.get("projectId");
+ String topoConfig = (String) params.get("topo");
+
+ ValidateUtils.is(projectId).notNull(RCode.PROJECT_ID_ISNULL)
+ .and(topoConfig).notNull(RCode.PROJECT_TOPOCONFIG_ISNULL);
+
+ topoService.updateProjectTopo(projectId, topoConfig);
+ return R.ok();
+ }
+
+}
diff --git a/nz-admin/src/main/java/com/nis/modules/project/dao/MonitorProjectDao.java b/nz-admin/src/main/java/com/nis/modules/project/dao/MonitorProjectDao.java
new file mode 100644
index 00000000..aa274230
--- /dev/null
+++ b/nz-admin/src/main/java/com/nis/modules/project/dao/MonitorProjectDao.java
@@ -0,0 +1,10 @@
+package com.nis.modules.project.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.nis.modules.project.entity.MonitorProject;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface MonitorProjectDao extends BaseMapper<MonitorProject> {
+
+}
diff --git a/nz-admin/src/main/java/com/nis/modules/project/entity/MonitorProject.java b/nz-admin/src/main/java/com/nis/modules/project/entity/MonitorProject.java
new file mode 100644
index 00000000..0bfd5d67
--- /dev/null
+++ b/nz-admin/src/main/java/com/nis/modules/project/entity/MonitorProject.java
@@ -0,0 +1,51 @@
+package com.nis.modules.project.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.nis.modules.module.entity.MonitorModule;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+@TableName("monitor_project")
+public class MonitorProject implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键
+ */
+ @TableId(type = IdType.AUTO)
+ private Integer id;
+
+ /**
+ * 应用名称
+ */
+ private String name;
+
+ /**
+ * 描述
+ */
+ private String remark;
+
+ /**
+ * 是否内置 1:内置,0:非内置,默认:0 内置数据不允许删除
+ */
+ private Integer buildIn;
+
+ private String seq;
+
+ @TableField(exist = false)
+ private List<Integer> alertStat = new ArrayList<Integer>();
+
+ /**
+ * module 列表
+ */
+ @TableField(exist = false)
+ private List<MonitorModule> children;
+
+}
diff --git a/nz-admin/src/main/java/com/nis/modules/project/service/MonitorProjectService.java b/nz-admin/src/main/java/com/nis/modules/project/service/MonitorProjectService.java
new file mode 100644
index 00000000..5ca7aa3f
--- /dev/null
+++ b/nz-admin/src/main/java/com/nis/modules/project/service/MonitorProjectService.java
@@ -0,0 +1,22 @@
+package com.nis.modules.project.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.nis.common.utils.PageUtils;
+import com.nis.modules.project.entity.MonitorProject;
+
+import java.util.Map;
+
+public interface MonitorProjectService extends IService<MonitorProject> {
+
+ MonitorProject queryProjectEntity(Integer id);
+
+ PageUtils queryPage(Map<String, Object> params);
+
+ Integer saveProject(MonitorProject project);
+
+ Integer updateProject(MonitorProject project);
+
+ void delete(Integer... ids);
+
+ Map<String, Object> queryProjectInfo(Integer id);
+}
diff --git a/nz-admin/src/main/java/com/nis/modules/project/service/TopoIconService.java b/nz-admin/src/main/java/com/nis/modules/project/service/TopoIconService.java
index ac7524b5..ba41c83f 100644
--- a/nz-admin/src/main/java/com/nis/modules/project/service/TopoIconService.java
+++ b/nz-admin/src/main/java/com/nis/modules/project/service/TopoIconService.java
@@ -20,4 +20,6 @@ public interface TopoIconService extends IService<TopoIcon> {
void downloadIconFileById(Integer id, HttpServletResponse response);
List<String> queryTopoIconUnitName(String name);
+
+ void deleteTopoIconByUnit(String unit);
}
diff --git a/nz-admin/src/main/java/com/nis/modules/project/service/TopoService.java b/nz-admin/src/main/java/com/nis/modules/project/service/TopoService.java
index 88b0a0ec..db494649 100644
--- a/nz-admin/src/main/java/com/nis/modules/project/service/TopoService.java
+++ b/nz-admin/src/main/java/com/nis/modules/project/service/TopoService.java
@@ -2,6 +2,7 @@ package com.nis.modules.project.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.nis.modules.module.entity.Module;
+import com.nis.modules.module.entity.MonitorModule;
import com.nis.modules.project.entity.Topo;
import java.util.List;
@@ -14,4 +15,6 @@ public interface TopoService extends IService<Topo> {
void updateProjectTopo(Integer projectId, String topoConfig);
void removeNodeAndLineByModules(List<Module> modules);
-} \ No newline at end of file
+
+ void removeTopoConfigNodeAndLineByModules(List<MonitorModule> modules);
+}
diff --git a/nz-admin/src/main/java/com/nis/modules/project/service/impl/MonitorProjectServiceImpl.java b/nz-admin/src/main/java/com/nis/modules/project/service/impl/MonitorProjectServiceImpl.java
new file mode 100644
index 00000000..daff6fec
--- /dev/null
+++ b/nz-admin/src/main/java/com/nis/modules/project/service/impl/MonitorProjectServiceImpl.java
@@ -0,0 +1,206 @@
+package com.nis.modules.project.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.nis.common.exception.NZException;
+import com.nis.common.utils.*;
+import com.nis.modules.alert.entity.AlertMessageEntity;
+import com.nis.modules.alert.service.AlertMessageService;
+import com.nis.modules.endpoint.dao.EndpointDao;
+import com.nis.modules.endpoint.entity.Endpoint;
+import com.nis.modules.endpoint.service.EndpointService;
+import com.nis.modules.module.entity.Module;
+import com.nis.modules.module.entity.MonitorModule;
+import com.nis.modules.module.service.ModuleService;
+import com.nis.modules.module.service.MonitorModuleService;
+import com.nis.modules.overview.service.OverviewService;
+import com.nis.modules.project.dao.MonitorProjectDao;
+import com.nis.modules.project.dao.ProjectDao;
+import com.nis.modules.project.entity.MonitorProject;
+import com.nis.modules.project.entity.Project;
+import com.nis.modules.project.service.MonitorProjectService;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Service
+public class MonitorProjectServiceImpl extends ServiceImpl<MonitorProjectDao, MonitorProject> implements MonitorProjectService {
+
+ @Autowired
+ private AlertMessageService alertMessageService;
+
+ @Autowired
+ private MonitorModuleService monitorModuleService;
+
+ @Autowired
+ private ProjectDao projectDao;
+
+ @Autowired
+ private ModuleService moduleService;
+
+ @Autowired
+ private OverviewService overviewService;
+
+ @Autowired
+ private EndpointService endpointService;
+
+ @Autowired
+ private EndpointDao endpointDao;
+
+ @Override
+ public MonitorProject queryProjectEntity(Integer id) {
+ MonitorProject project = this.getById(id);
+ if (ToolUtil.isEmpty(project)) {
+ throw new NZException(RCode.PROJECT_NOTFOUND);
+ }
+ return project;
+ }
+
+ @Override
+ public PageUtils queryPage(Map<String, Object> params) {
+ LambdaQueryWrapper<MonitorProject> queryWrapper = new LambdaQueryWrapper<MonitorProject>()
+ .eq(ToolUtil.isNotEmpty(params.get("id")), MonitorProject::getId, params.get("id"))
+ .like(ToolUtil.isNotEmpty(params.get("name")), MonitorProject::getName, params.get("name"))
+ .like(ToolUtil.isNotEmpty(params.get("remark")), MonitorProject::getRemark, params.get("remark"));
+
+ IPage<MonitorProject> page = this.page(new Query<MonitorProject>().getPage(params), queryWrapper);
+ return new PageUtils(page);
+ }
+
+ private void validateProjectInfo(MonitorProject project) {
+ // 1. 名称重复
+ List<MonitorProject> list = this.list(new LambdaQueryWrapper<MonitorProject>().eq(MonitorProject::getName, project.getName()));
+ boolean flag = false;
+ // 当只有一个结果并且这个结果是自身时,或没有结果时,说明名称不重复
+ if ((list == null || list.size() == 0) || (list != null && list.size() == 1 && list.get(0).getId().equals(project.getId()))) {
+ flag = true;
+ }
+
+ if (!flag) {
+ throw new NZException(RCode.PROJECT_NAME_DUPLICATE);
+ }
+ }
+
+ @Override
+ public Integer saveProject(MonitorProject project) {
+ // 1. 校验
+ this.validateProjectInfo(project);
+
+ // 保存
+ this.save(project);
+ return project.getId();
+ }
+
+ @Override
+ public Integer updateProject(MonitorProject project) {
+ // 内置 project 不能编辑
+ MonitorProject monitorProject = this.getById(project.getId());
+ if(monitorProject.getBuildIn().equals(1)){
+ throw new NZException(RCode.PROJECT_BUILDIN_CAN_NOT_EDIT);
+ }
+
+ // 参数校验
+ this.validateProjectInfo(project);
+
+ // 保存
+ this.updateById(project);
+ return project.getId();
+ }
+
+ @Override
+ public void delete(Integer... ids) {
+ List<MonitorProject> list = this.list();
+
+ // 1. 内置的 配置不允许删除
+ List<Integer> buildInIdList = list.stream().filter(assetTypeConf -> assetTypeConf.getBuildIn().equals(1)).map(MonitorProject::getId).collect(Collectors.toList());
+ buildInIdList.retainAll(Arrays.asList(ids));
+ if (CollectionUtils.isNotEmpty(buildInIdList)) {
+ throw new NZException("These projects are built-in and cannot be deleted. Details: " + buildInIdList.toString(), RCode.PROJECT_BUILDIN_CAN_NOT_REMOVE.getCode());
+ }
+
+ // 2. 包含 module 不允许删除
+ List<MonitorModule> moduleList = monitorModuleService.list();
+ List<Integer> usedProjectIdList = moduleList.stream().map(MonitorModule::getProjectId).distinct().collect(Collectors.toList());
+ usedProjectIdList.retainAll(Arrays.asList(ids));
+ if (CollectionUtils.isNotEmpty(usedProjectIdList)) {
+ throw new NZException("These projects have been used by modules and cannot be deleted. Details: " + usedProjectIdList.toString(), RCode.PROJECT_REMOVE_ERROR.getCode());
+ }
+
+ // 删除
+ this.removeByIds(Arrays.asList(ids));
+ }
+
+ @Override
+ public Map<String,Object> queryProjectInfo(Integer id) {
+ Map<String,Object> result = new HashMap<String,Object>();
+ Project project = projectDao.selectById(id);
+ if(ObjectUtils.isNotEmpty(project)) {
+
+ // project高中低alert message数据
+ List<Map<String, Object>> maps = alertMessageService.listMaps(new QueryWrapper<AlertMessageEntity>().eq("project_id", id).eq("state",1).groupBy("severity").select("severity","count(*) as count"));
+ Map projectAlertMessageInfos =new HashMap();
+ List<Integer> alertStat = project.getAlertStat();
+ for(Map<String,Object> map:maps) {
+ projectAlertMessageInfos.put(map.get("severity"),((Long)map.get("count")).intValue());
+ }
+
+ alertStat.add(ObjectUtils.isEmpty(projectAlertMessageInfos.get(Constant.ALERT_SEVERITY_HIGH))?0:(int) projectAlertMessageInfos.get(Constant.ALERT_SEVERITY_HIGH));
+ alertStat.add(ObjectUtils.isEmpty(projectAlertMessageInfos.get(Constant.ALERT_SEVERITY_MEDIUM))?0:(int) projectAlertMessageInfos.get(Constant.ALERT_SEVERITY_MEDIUM));
+ alertStat.add(ObjectUtils.isEmpty(projectAlertMessageInfos.get(Constant.ALERT_SEVERITY_LOW))?0:(int) projectAlertMessageInfos.get(Constant.ALERT_SEVERITY_LOW));
+
+ List<Module> modules = moduleService.list(new LambdaQueryWrapper<Module>().eq(Module::getProjectId, id));
+ if(ObjectUtils.isEmpty(modules)) {
+ modules=new ArrayList<Module>();
+ }
+ // 根据 asset 停用状态 获取对应 endpoint ids
+ List<Integer> suspendedEndpointIds = endpointDao.getSuspendedEndpointIdsByAssetState();
+ // 停用的 endpoint ids
+ List<Integer> disabledEndpointIds = endpointDao.getDisabledEndpointIds();
+ suspendedEndpointIds.addAll(disabledEndpointIds);
+ suspendedEndpointIds = suspendedEndpointIds.stream().distinct().collect(Collectors.toList());
+
+ Set<Integer> endpointUpIds = overviewService.getUpStatusEndpointIds(suspendedEndpointIds);
+
+ for(Module module : modules) {
+ //module高中低alert message数据
+ List<Map<String, Object>> moduleMaps = alertMessageService.listMaps(new QueryWrapper<AlertMessageEntity>().eq("module_id", module.getId()).eq("state",1).groupBy("severity").select("severity","count(*) as count"));
+ Map moduleAlertMessageInfos = new HashMap();
+ for(Map<String,Object> moduleMap : moduleMaps) {
+ moduleAlertMessageInfos.put(moduleMap.get("severity"),((Long)moduleMap.get("count")).intValue());
+ }
+ List<Integer> moduleAlertStat = module.getAlertStat();
+ moduleAlertStat.add(ObjectUtils.isEmpty(moduleAlertMessageInfos.get(Constant.ALERT_SEVERITY_HIGH))?0:(int) moduleAlertMessageInfos.get(Constant.ALERT_SEVERITY_HIGH));
+ moduleAlertStat.add(ObjectUtils.isEmpty(moduleAlertMessageInfos.get(Constant.ALERT_SEVERITY_MEDIUM))?0:(int) moduleAlertMessageInfos.get(Constant.ALERT_SEVERITY_MEDIUM));
+ moduleAlertStat.add(ObjectUtils.isEmpty(moduleAlertMessageInfos.get(Constant.ALERT_SEVERITY_LOW))?0:(int) moduleAlertMessageInfos.get(Constant.ALERT_SEVERITY_LOW));
+ //组件endpoint up down统计
+ if(ObjectUtils.isNotEmpty(endpointUpIds)) {
+ List<Integer> endpointStat = module.getEndpointStat();
+ // 初始化endpoint up down suspended 状态
+ endpointStat.add(0);
+ endpointStat.add(0);
+ endpointStat.add(0);
+ List<Endpoint> endpoints = endpointService.list(new QueryWrapper<Endpoint>().eq("module_id", module.getId()));
+ for(Endpoint endpoint : endpoints) {
+ if (endpointUpIds.contains(endpoint.getId())) {
+ endpointStat.set(0, (endpointStat.get(0) + 1));
+ } else if (suspendedEndpointIds.contains(endpoint.getId())) {
+ endpointStat.set(2, (endpointStat.get(2) + 1));
+ } else {
+ endpointStat.set(1, (endpointStat.get(1) + 1));
+ }
+ }
+ }
+ }
+ result.put("basic", project);
+ result.put("module", modules);
+ }
+ return result;
+ }
+
+}
diff --git a/nz-admin/src/main/java/com/nis/modules/project/service/impl/TopoIconServiceImpl.java b/nz-admin/src/main/java/com/nis/modules/project/service/impl/TopoIconServiceImpl.java
index 8e87312a..8da02450 100644
--- a/nz-admin/src/main/java/com/nis/modules/project/service/impl/TopoIconServiceImpl.java
+++ b/nz-admin/src/main/java/com/nis/modules/project/service/impl/TopoIconServiceImpl.java
@@ -1,5 +1,6 @@
package com.nis.modules.project.service.impl;
+import cn.hutool.log.Log;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nis.common.exception.NZException;
@@ -8,7 +9,6 @@ import com.nis.common.utils.ToolUtil;
import com.nis.modules.project.dao.TopoIconDao;
import com.nis.modules.project.entity.TopoIcon;
import com.nis.modules.project.service.TopoIconService;
-import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
@@ -23,11 +23,11 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
-
-@Slf4j
@Service("topoIconService")
public class TopoIconServiceImpl extends ServiceImpl<TopoIconDao, TopoIcon> implements TopoIconService {
+ private static Log log = Log.get();
+
@Autowired
private TopoIconDao topoIconDao;
@@ -104,4 +104,9 @@ public class TopoIconServiceImpl extends ServiceImpl<TopoIconDao, TopoIcon> impl
List<String> result = topoIcons.stream().map(TopoIcon::getUnit).collect(Collectors.toList());
return result;
}
-} \ No newline at end of file
+
+ @Override
+ public void deleteTopoIconByUnit(String unit) {
+ this.remove(new LambdaQueryWrapper<TopoIcon>().eq(TopoIcon::getUnit, unit));
+ }
+}
diff --git a/nz-admin/src/main/java/com/nis/modules/project/service/impl/TopoServiceImpl.java b/nz-admin/src/main/java/com/nis/modules/project/service/impl/TopoServiceImpl.java
index 35350442..1f379786 100644
--- a/nz-admin/src/main/java/com/nis/modules/project/service/impl/TopoServiceImpl.java
+++ b/nz-admin/src/main/java/com/nis/modules/project/service/impl/TopoServiceImpl.java
@@ -9,6 +9,7 @@ import com.nis.common.utils.DateUtil;
import com.nis.common.utils.RCode;
import com.nis.common.utils.ToolUtil;
import com.nis.modules.module.entity.Module;
+import com.nis.modules.module.entity.MonitorModule;
import com.nis.modules.project.dao.TopoDao;
import com.nis.modules.project.entity.Project;
import com.nis.modules.project.entity.Topo;
@@ -94,6 +95,44 @@ public class TopoServiceImpl extends ServiceImpl<TopoDao, Topo> implements TopoS
this.saveOrUpdateBatch(topos);
}
+ @Override
+ public void removeTopoConfigNodeAndLineByModules(List<MonitorModule> modules) {
+ Set<Integer> projectIds = modules.stream().map(MonitorModule::getProjectId).collect(Collectors.toSet());
+ List<Topo> topos = this.list(new QueryWrapper<Topo>().lambda().in(Topo::getProjectId, projectIds));
+ if (CollectionUtils.isEmpty(topos)) {
+ return;
+ }
+ Map<Integer, Object> topoProjectIdAndConfigMap = topos.stream().collect(Collectors.toMap(Topo::getProjectId, Topo::getTopo));
+
+ // module 是批量删除,删除的或许不属于同一个 project
+ Map<Integer, List<MonitorModule>> projectIdAndMoudles = modules.stream().collect(Collectors.groupingBy(MonitorModule::getProjectId));
+
+ Object topoConfig;
+ Map<String, JSONArray> configMap;
+ List<Integer> moduleIds;
+ for (Map.Entry<Integer, List<MonitorModule>> entry : projectIdAndMoudles.entrySet()) {
+ topoConfig = topoProjectIdAndConfigMap.get(entry.getKey());
+ if (ToolUtil.isEmpty(topoConfig)) {
+ continue;
+ }
+
+ moduleIds = entry.getValue().stream().map(MonitorModule::getId).collect(Collectors.toList());
+ configMap = JSONObject.parseObject(topoConfig.toString(), Map.class);
+ configMap.put("pens", this.removeModuleEntity(configMap.get("pens"), moduleIds));
+ topoProjectIdAndConfigMap.put(entry.getKey(), JSONObject.toJSONString(configMap));
+ }
+
+ Date now = DateUtil.getUTCTimeByConfigTimeZone();
+ Integer userId = ShiroUtils.getUserId().intValue();
+ for (Topo topo : topos) {
+ topo.setTopo(topoProjectIdAndConfigMap.get(topo.getProjectId()).toString());
+ topo.setUpdateBy(userId);
+ topo.setUpdateAt(now);
+ }
+ this.saveOrUpdateBatch(topos);
+ }
+
+
private JSONArray removeModuleEntity(JSONArray pens, List<Integer> moduleIds) {
Map<String, Object> node, nodeData;
Integer moduleId, type;
diff --git a/nz-admin/src/main/resources/db/V2021.03.19__Insert monitor_project, monitor_module and monitor_endpoint table.sql b/nz-admin/src/main/resources/db/V2021.03.19__Insert monitor_project, monitor_module and monitor_endpoint table.sql
new file mode 100644
index 00000000..c6c441da
--- /dev/null
+++ b/nz-admin/src/main/resources/db/V2021.03.19__Insert monitor_project, monitor_module and monitor_endpoint table.sql
@@ -0,0 +1,65 @@
+
+/**
+ * 1. insert monitor_project monitor_module monitor_endpoint tables
+ * 2. update common role remark content
+ * 3. sys_config 表新增 monitor_exdpoint 导入导出表头
+ */
+SET NAMES utf8mb4;
+SET FOREIGN_KEY_CHECKS = 0;
+
+-- ----------------------------
+-- Table structure for monitor_project
+-- ----------------------------
+DROP TABLE IF EXISTS `monitor_project`;
+CREATE TABLE `monitor_project` (
+ `id` int(10) NOT NULL AUTO_INCREMENT,
+ `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '应用名称',
+ `remark` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '描述信息',
+ `build_in` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '是否内置 1:内置,0:非内置,默认:0',
+ `seq` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for monitor_module
+-- ----------------------------
+DROP TABLE IF EXISTS `monitor_module`;
+CREATE TABLE `monitor_module` (
+ `id` int(10) NOT NULL AUTO_INCREMENT,
+ `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '组件名称 唯一索引,表内不重复',
+ `project_id` int(10) NOT NULL,
+ `type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '可选值http snmp',
+ `endpoint_name_tmpl` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'endpoint name模板 支持 {{}} 变量替换,asset,module\r\n\r\n例:{{asset.name}}-{{module.name}}\r\n\r\n最终endpoint的name为: 192.168.40.1-mysql',
+ `port` int(10) NOT NULL COMMENT '默认端口 type=snmp时,默认 161',
+ `remark` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
+ `configs` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '配置参数 ',
+ `snmp_yml` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT 'snmp_exporter需要的配置部分',
+ `build_in` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0',
+ `seq` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for monitor_endpoint
+-- ----------------------------
+DROP TABLE IF EXISTS `monitor_endpoint`;
+CREATE TABLE `monitor_endpoint` (
+ `id` int(10) NOT NULL AUTO_INCREMENT,
+ `name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '名称',
+ `module_id` int(10) NOT NULL,
+ `asset_id` int(10) NOT NULL,
+ `host` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'exporter地址,默认:asset.host',
+ `port` int(10) NULL DEFAULT NULL COMMENT 'export端口,默认为 module.port',
+ `configs` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
+ `hash` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '计算 moduleId + assetId + host + port + configs 的hash值,用于确保相同配置不重复',
+ `enabled` int(4) NOT NULL COMMENT '是否启用 可选值\r\n\r\n0:停用\r\n\r\n1:启用',
+ `seq` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
+
+SET FOREIGN_KEY_CHECKS = 1;
+
+
+update sys_role set remark = 'The system built-in common user role' where name = 'common';
+
+INSERT INTO `sys_config`(`id`, `param_key`, `param_value`, `status`, `remark`) VALUES (NULL, 'monitor_endpoint_export_header', '{\r\n \"cn\": {\r\n \"*系统\": \"系统名称(必填) \\n示例: Nezha\",\r\n \"*组件\": \"组件名称(必填) \\n示例: node_exporter\",\r\n \"名称\": \"实例名称 \\n示例: node_exporter\",\r\n \"资产名称\": \"资产名称(非必填) 与 主机地址 不能同时为空 \\n示例: A0420200101\",\r\n \"端口号\": \"端口号 范围0-65535 \\n示例: 9100\",\r\n \"配置\": \"实例配置,JSON格式, \\n示例: {\\\"key\\\":\\\"value\\\"}\",\r\n \"主机地址\": \"主机地址(非必填) 与 资产名称 不能同时为空 \\n示例: 127.0.0.1\",\r\n \"启用\": \"启用状态(非必填) 可选 0:停用 1:启用,为空时默认为1 \\n示例: 1\"\r\n },\r\n \"en\": {\r\n \"*Project Name\": \"Project Name(Required) \\nExample: Nezha\",\r\n \"*Module Name\": \"Module Name(Required) \\nExample: node_exporter\",\r\n \"Name\": \"Endpoint name \\nExample: node_exporter\",\r\n \"Asset Name\": \"Asset name(Not required) And host address cannot be empty at the same time \\n示例: A0420200101\",\r\n \"Port\": \"Port number range 0-65535 \\nExample: 9100\",\r\n \"Configs\": \"Endpoint Configs,JSON format, \\nExample: {\\\"key\\\":\\\"value\\\"}\",\r\n \"Host\": \"Host address (not required) and asset name cannot be empty at the same time \\nExample: 127.0.0.1\",\r\n \"Enabled\": \"Enable state (not required) Optional values 0: Disable 1: Enable, when empty, the default is 1 \\nExample: 1\"\r\n }\r\n}', 1, 'monitor endpoint 导入表头');
diff --git a/nz-admin/src/main/resources/mapper/endpoint/MonitorEndpointDao.xml b/nz-admin/src/main/resources/mapper/endpoint/MonitorEndpointDao.xml
new file mode 100644
index 00000000..87df65f1
--- /dev/null
+++ b/nz-admin/src/main/resources/mapper/endpoint/MonitorEndpointDao.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.nis.modules.endpoint.dao.MonitorEndpointDao">
+
+ <resultMap type="com.nis.modules.endpoint.entity.MonitorEndpoint" id="endpoint">
+ <result property="id" column="id"/>
+ <result property="name" column="name"/>
+ <result property="moduleId" column="module_id"/>
+ <result property="assetId" column="asset_id"/>
+ <result property="host" column="host"/>
+ <result property="port" column="port"/>
+ <result property="hash" column="hash"/>
+ <result property="enabled" column="enabled"/>
+ <result property="configs" column="configs"/>
+
+ <association columnPrefix="es_" property="endpointState" javaType="com.nis.modules.endpoint.entity.EndpointState">
+ <id column="endpoint_id" property="endpointId"/>
+ <result column="create_time" property="createTime"/>
+ <result column="state" property="state"/>
+ </association>
+
+ <association columnPrefix="m_" property="module" javaType="com.nis.modules.module.entity.MonitorModule">
+ <id column="id" property="id"/>
+ <result column="name" property="name"/>
+ </association>
+
+ <association columnPrefix="p_" property="project" javaType="com.nis.modules.project.entity.MonitorProject">
+ <id column="id" property="id"/>
+ <result column="name" property="name"/>
+ </association>
+
+ <association columnPrefix="a_" property="asset" javaType="com.nis.modules.asset.entity.Asset">
+ <id column="id" property="id"/>
+ <result column="host" property="host"/>
+ <result column="sn" property="sn"/>
+ <result column="cabinet_id" property="cabinetId"/>
+ <result column="state" property="state"/>
+ <result column="purchase_date" property="purchaseDate"/>
+ <result column="idc_id" property="idcId"/>
+ <result column="model_id" property="modelId"/>
+ <result column="name" property="name"/>
+ </association>
+ </resultMap>
+
+ <select id="queryPage" resultMap="endpoint">
+ SELECT e.*,
+ m.id AS m_id,
+ m.name AS m_name,
+
+ a.id AS a_id,
+ a.host AS a_host,
+ a.sn AS a_sn,
+ a.state AS a_state,
+ a.purchase_date AS a_purchase_date,
+ a.idc_id AS a_idc_id,
+ a.model_id AS a_model_id,
+ a.cabinet_id AS a_cabinet_id,
+ a.name AS a_name,
+
+ p.id AS p_id,
+ p.name AS p_name,
+
+ es.state AS es_state,
+ es.create_time AS es_create_time,
+ es.endpoint_id AS es_endpoint_id
+ FROM monitor_endpoint e
+ left join monitor_module m on e.module_id=m.id
+ left join monitor_project p on m.project_id=p.id
+ left join asset a on e.asset_id=a.id
+ left join endpoint_state es on e.id = es.endpoint_id
+ <where>
+ <if test="params.id != null and params.id != ''">
+ e.id = #{params.id}
+ </if>
+
+ <if test="params.name != null and params.name != ''">
+ AND e.name like CONCAT('%', #{params.name}, '%')
+ </if>
+
+ <if test="params.host != null and params.host != ''">
+ AND e.host like CONCAT('%', #{params.host}, '%')
+ </if>
+
+ <if test="params.projectId != null and params.projectId != ''">
+ AND p.id = #{params.projectId}
+ </if>
+
+ <if test="params.assetId != null and params.assetId != ''">
+ AND e.asset_id = #{params.assetId}
+ </if>
+
+ <if test="params.moduleId != null and params.moduleId != ''">
+ AND e.module_id = #{params.moduleId}
+ </if>
+
+ <if test="params.state != null and params.state != ''">
+ AND es.state = #{params.state}
+ </if>
+ </where>
+ </select>
+</mapper>
diff --git a/nz-admin/src/main/resources/mapper/module/MonitorModuleDao.xml b/nz-admin/src/main/resources/mapper/module/MonitorModuleDao.xml
new file mode 100644
index 00000000..590b335c
--- /dev/null
+++ b/nz-admin/src/main/resources/mapper/module/MonitorModuleDao.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.nis.modules.module.dao.MonitorModuleDao">
+
+ <resultMap type="com.nis.modules.module.entity.MonitorModule" id="module">
+ <result property="id" column="id"/>
+ <result property="projectId" column="project_id"/>
+ <result property="name" column="name"/>
+ <result property="endpointNameTmpl" column="endpoint_name_tmpl"/>
+ <result property="port" column="port"/>
+ <result property="type" column="type"/>
+ <result property="remark" column="remark"/>
+ <result property="buildIn" column="build_in"/>
+ <result property="configs" column="configs"/>
+
+ <association property="project" columnPrefix="p_" javaType="com.nis.modules.project.entity.MonitorProject">
+ <id column="id" property="id"/>
+ <result column="name" property="name"/>
+ <result column="remark" property="remark"/>
+ </association>
+ </resultMap>
+
+ <select id="queryPage" resultMap="module">
+ SELECT
+ m.*,
+ p.id AS p_id,
+ p.name AS p_name,
+ p.remark AS p_remark
+ FROM
+ monitor_module m
+ LEFT JOIN monitor_project p ON m.project_id = p.id
+ <where>
+ <if test="params.id != null and params.id != ''">
+ m.id = #{params.id}
+ </if>
+
+ <if test="params.projectId != null and params.projectId != ''">
+ AND m.project_id = #{params.projectId}
+ </if>
+
+ <if test="params.name != null and params.name != ''">
+ AND m.name LIKE CONCAT('%', #{params.name}, '%')
+ </if>
+
+ <if test="params.type != null and params.type != ''">
+ AND m.type = #{params.type}
+ </if>
+
+ <if test="params.port != null and params.port != ''">
+ AND m.port = #{params.port}
+ </if>
+ </where>
+ </select>
+
+
+</mapper>
diff --git a/nz-admin/src/main/resources/mapper/terminal/TerminalSessionDao.xml b/nz-admin/src/main/resources/mapper/terminal/TerminalSessionDao.xml
index 3cf7c2f3..19de2fae 100644
--- a/nz-admin/src/main/resources/mapper/terminal/TerminalSessionDao.xml
+++ b/nz-admin/src/main/resources/mapper/terminal/TerminalSessionDao.xml
@@ -39,4 +39,4 @@
ORDER BY ts.status ASC,ts.id DESC
</if>
</select>
-</mapper> \ No newline at end of file
+</mapper>
diff --git a/nz-common/src/main/java/com/nis/common/utils/RCode.java b/nz-common/src/main/java/com/nis/common/utils/RCode.java
index 8a47e072..7bac5e23 100644
--- a/nz-common/src/main/java/com/nis/common/utils/RCode.java
+++ b/nz-common/src/main/java/com/nis/common/utils/RCode.java
@@ -134,13 +134,14 @@ public enum RCode {
PROJECT_TOPOCONFIG_ISNULL(211012, "Project topo is null"),
PROJECT_NOTFOUND(216013, "Project not found"),
PROJECT_TOPOICON_UNIT_ISNULL(211014,"Topo icon unit is null"),
-
+ PROJECT_BUILDIN_CAN_NOT_EDIT(217015, "The built-in project does not allow editing"),
+
MODULE_ID_ISNULL(221000, "Module id can not be empty"),
MODULE_PROJECTID_ISNULL(221001, "Project id can not be empty"),
MODULE_NAME_ISNULL(221002, "Module name info can not be empty"),
MODULE_PORT_ISNULL(221003, "Module port info can not be empty"),
MODULE_PATH_ISNULL(221004, "Module path info can not be empty"),
- MODULE_PORT_ERROR(221005, "Module port is incorrect"),
+ MODULE_PORT_ERROR(221005, "Module port is incorrect"),
MODULE_BUILDIN_CAN_NOT_REMOVE(227006, "This module is built-in and cannot be deleted"),
MODULE_NAME_TOO_LONG(223007, "Module name too long"),
MODULE_REMARK_TOO_LONG(223008, "Module remark too long"),
@@ -162,6 +163,9 @@ public enum RCode {
MODULE_SNMP_NOTEXIST(226024, "SNMP type module must exist"),
MODULE_LABELS_FORMAT(223025,"Module labels must be JSON format"),
MODULE_LABELS_KEY_FORMAT(223026,"Module labels key format is incorrect"),
+ MODULE_ENDPOINTNAMETMPL_ISNULL(221027, "Module endpoint name template can not be empty"),
+ MODULE_CONFIGS_ISNULL(221028, "Module configs can not be empty"),
+ MODULE_CONFIGS_FORMAT(223029,"Module configs must be JSON format"),
ENDPOINT_ID_ISNULL(231000, "Endpoint id can not be empty"),
ENDPOINT_MODULEID_ISNULL(231001, "Module Id can not be empty"),
@@ -187,6 +191,14 @@ public enum RCode {
ENDPOINT_LABELS_KEY_FORMAT(233021,"Endpoint labels key format is incorrect"),
ENDPOINT_TIMEOUT_UPDATE(233022,"Data has not been updated for more than multiple cycles"),
ENDPOINT_ENABLED_INVALIDE(234023, "Endpoint enabled must be 0 or 1"),
+ ENDPOINT_NOTFOUND(236024, "Endpoint not found"),
+ ENDPOINT_NAME_ISNULL(231025, "Endpoint name can not be empty"),
+ ENDPOINT_NAME_DUPLICATE(232026, "Endpoint name duplicate"),
+ ENDPOINT_PORT_ERROR(231027, "Endpoint port is incorrect"),
+ ENDPOINT_ASSET_NAME_HOST_ISNULL(231028, "Asset name and host cannot be empty at the same time"),
+ ENDPOINT_IMPORT_ERROR(233029, "Endpoint template import error"),
+ ENDPOINT_CONFIGS_FORMAT(233030,"Endpoint configs must be JSON format"),
+
/**
* assets菜单项相关
*/
@@ -653,7 +665,15 @@ public enum RCode {
TERMINAL_ISNULL(611004, "Error,Terminal is null"),
TERMINAL_TELNET_TRANSFER(610005,"Telnet does not allow upload and download"),
TERMINAL_QUERYSIZE_INVALIDED(613006, "Terminal query size cannot be less than 1"),
-
+
+
+ /**
+ * 导入相关
+ */
+ IMPORT_EXCELFILE_TYPE(900, "Only support import XLS or XLSX file"),
+ IMPORT_EXCELFILE_PARSE_ERROR(901, "Import file resolution failed"),
+ IMPORT_EXCELFILE_HEADER_TEMPLATE_ERROR(902,"The header row of the excel import template is inconsistent with the system template"),
+
NOT_NULL_ERROR(990, "not null error"), //not null错误
NOT_NUMBER_ERROR(991, "not number error"), //not number错误
/**