diff --git a/build/database/upgrade/upg_nms_cxy.sql b/build/database/upgrade/upg_nms_cxy.sql index bb8cec1..f154f99 100644 --- a/build/database/upgrade/upg_nms_cxy.sql +++ b/build/database/upgrade/upg_nms_cxy.sql @@ -1,24 +1,20 @@ -/* - Navicat Premium Data Transfer - - Source Server : local_mariadb - Source Server Type : MariaDB - Source Server Version : 100338 (10.3.38-MariaDB) - Source Host : localhost:33066 - Source Schema : omc_db - - Target Server Type : MariaDB - Target Server Version : 100338 (10.3.38-MariaDB) - File Encoding : 65001 - - Date: 25/10/2023 18:24:04 - */ SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- 创建表 -- ---------------------------- - +CREATE TABLE IF NOT EXISTS `nms_cxy_nrm_log` ( + `msg_id` bigint NOT NULL AUTO_INCREMENT COMMENT '消息序号,9位长度,递增', + `ruid` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '网络资源对象Ruid', + `user_label` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '用户标签-网元名称', + `change_time` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '资源变化时间,格式为"2022-12-15 08:34:24"', + `change_type` varchar(16) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '变化类型 add:新增 mod:修改 del:删除', + `change_oper` varchar(3000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '资源的具体属性', + `create_by` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建者', + `create_time` bigint DEFAULT NULL COMMENT '创建时间', + PRIMARY KEY (`msg_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='星网-资源数据操作日志'; + -- ---------------------------- -- 新增记录 -- ---------------------------- diff --git a/src/modules/nms_cxy/README.md b/src/modules/nms_cxy/README.md index b701624..693a560 100644 --- a/src/modules/nms_cxy/README.md +++ b/src/modules/nms_cxy/README.md @@ -1,6 +1,6 @@ ## 北向模块 - 中国星网网络创新研究院 -以网管代码为基础,模块相关配置内部处理 +以OMC网管代码为基础,模块相关配置内部处理 ### 模块配置拓展 @@ -44,15 +44,34 @@ nmsCXY: secretAccessKey: "9tDErvtCEuVox6LoQu5BOVtycQKcQjlXOGvjl1eD" ``` - ## Kafka Topic -告警数据订阅topic,名称为:专业编码-厂商编码-OMC编号-数据类别(固定为FM) -资源数据订阅topic,名称为:专业编码-厂商编码-OMC编号-网元类型-数据类别(固定为NRM)-资源对象类型简称(一般没有) +告警数据订阅 topic,名称为:专业编码-厂商编码-OMC 编号-数据类别(固定为 FM) +资源数据订阅 topic,名称为:专业编码-厂商编码-OMC 编号-网元类型-数据类别(固定为 NRM)-资源对象类型简称(一般没有) -## 数据库添加定时任务 +## 更新数据库脚本 ```sql +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; +-- ---------------------------- +-- 创建表 +-- ---------------------------- +CREATE TABLE IF NOT EXISTS `nms_cxy_nrm_log` ( + `msg_id` bigint NOT NULL AUTO_INCREMENT COMMENT '消息序号,9位长度,递增', + `ruid` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '网络资源对象Ruid', + `user_label` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '用户标签-网元名称', + `change_time` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '资源变化时间,格式为"2022-12-15 08:34:24"', + `change_type` varchar(16) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '变化类型 add:新增 mod:修改 del:删除', + `change_oper` varchar(3000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '资源的具体属性', + `create_by` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建者', + `create_time` bigint DEFAULT NULL COMMENT '创建时间', + PRIMARY KEY (`msg_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='星网-资源数据操作日志'; + +-- ---------------------------- +-- 新增记录 +-- ---------------------------- -- 性能数据文件的上报 INSERT IGNORE INTO `sys_job` VALUES (null,'job.nms_cxy.performance_upload_oss', 'SYSTEM', 'performance_upload_oss', '{\"interval\":15,\"neTypes\":[\"AMF\",\"UPF\",\"UDM\",\"SMF\",\"NSSF\"]}', '0 0/15 * * * ?', '3', '0', '1', '1', 'supervisor', 1698478134839, 'supervisor', 1710819124454, 'job.nms_cxy.performance_upload_oss_remark'); INSERT IGNORE INTO `sys_dict_data` VALUES (210, 210, 'job.nms_cxy.performance_upload_oss', '性能数据文件的上报', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); @@ -74,4 +93,5 @@ INSERT IGNORE INTO `sys_dict_data` VALUES (221, 221, 'job.nms_cxy.config_upload_ INSERT IGNORE INTO `sys_dict_data` VALUES (222, 222, 'job.nms_cxy.config_upload_oss', 'Configure data reporting interface', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); INSERT IGNORE INTO `sys_dict_data` VALUES (223, 223, 'job.nms_cxy.config_upload_oss_remark', 'Set the data reporting time to 0:00 and 12:00 every day.', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); +SET FOREIGN_KEY_CHECKS = 1; ``` diff --git a/src/modules/nms_cxy/controller/system.go b/src/modules/nms_cxy/controller/system.go index 54b583a..a70d73e 100644 --- a/src/modules/nms_cxy/controller/system.go +++ b/src/modules/nms_cxy/controller/system.go @@ -388,7 +388,8 @@ func (s *SystemController) ConfigApp(c *gin.Context) { return } - failPara := s.configService.ConfigParamModify(neInfo, body.OperType, body.OperPara) + byUsername := ctx.LoginUserToUserName(c) + failPara := s.configService.ConfigParamModify(neInfo, byUsername, body.OperType, body.OperPara) if len(failPara) > 0 { c.JSON(200, map[string]any{ "requestId": body.RequestId, diff --git a/src/modules/nms_cxy/model/nms_cxy_nrm_log.go b/src/modules/nms_cxy/model/nms_cxy_nrm_log.go new file mode 100644 index 0000000..99021b6 --- /dev/null +++ b/src/modules/nms_cxy/model/nms_cxy_nrm_log.go @@ -0,0 +1,18 @@ +package model + +// NRMLog 资源数据操作日志 nms_cxy_nrm_log +type NRMLog struct { + MsgID string `json:"MsgID" gorm:"column:msg_id"` // 消息序号,9位长度,递增 + Ruid string `json:"Ruid" gorm:"column:ruid"` // 网络资源对象Ruid + UserLabel string `json:"UserLabel" gorm:"column:user_label"` // 用户标签-网元名称 + ChangeTime string `json:"ChangeTime" gorm:"column:change_time"` // 资源变化时间,格式为"2022-12-15 08:34:24" + ChangeType string `json:"ChangeType" gorm:"column:change_type"` // 变化类型 add:新增 mod:修改 del:删除 + ChangeOper string `json:"ChangeOper" gorm:"column:change_oper"` // 资源的具体属性 + CreateBy string `json:"CreateBy" gorm:"column:create_by"` // 创建者 + CreateTime int64 `json:"CreateTime" gorm:"column:create_time"` // 创建时间 +} + +// TableName 表名称 +func (*NRMLog) TableName() string { + return "nms_cxy_nrm_log" +} diff --git a/src/modules/nms_cxy/service/config.go b/src/modules/nms_cxy/service/config.go index 697c31e..931b987 100644 --- a/src/modules/nms_cxy/service/config.go +++ b/src/modules/nms_cxy/service/config.go @@ -13,5 +13,5 @@ type IConfig interface { ConfigParamQuery(neInfo neModel.NeInfo, operPara []string) map[string]any // ConfigParamModify 配置参数修改 - ConfigParamModify(neInfo neModel.NeInfo, operType string, operPara map[string]any) []string + ConfigParamModify(neInfo neModel.NeInfo, byUsername string, operType string, operPara map[string]any) []string } diff --git a/src/modules/nms_cxy/service/config.impl.go b/src/modules/nms_cxy/service/config.impl.go index 1c03bc0..956567f 100644 --- a/src/modules/nms_cxy/service/config.impl.go +++ b/src/modules/nms_cxy/service/config.impl.go @@ -1,16 +1,17 @@ package service import ( + "encoding/json" "fmt" "nms_cxy/lib/core/utils/date" "nms_cxy/src/framework/constants/uploadsubpath" "nms_cxy/src/framework/logger" "nms_cxy/src/framework/utils/cmd" "nms_cxy/src/framework/utils/file" - "nms_cxy/src/framework/utils/generate" "nms_cxy/src/framework/utils/ssh" neModel "nms_cxy/src/modules/network_element/model" neService "nms_cxy/src/modules/network_element/service" + "nms_cxy/src/modules/nms_cxy/model" "nms_cxy/src/modules/nms_cxy/utils/common" "path/filepath" "strings" @@ -22,6 +23,7 @@ var NewConfigImpl = &ConfigImpl{ neInfoService: neService.NewNeInfoImpl, neVersionService: neService.NewNeVersionImpl, resourceService: NewResourceImpl, + nrmLogService: NewNRMLogImpl, } // 配置数据处理服务 服务层处理 @@ -32,6 +34,8 @@ type ConfigImpl struct { neVersionService neService.INeVersion // 资源数据处理服务 resourceService IResource + // 资源数据日志处理服务 + nrmLogService INRMLog } // ConfigUploadOSS 配置数据上报 @@ -296,7 +300,7 @@ func (s *ConfigImpl) ConfigParamQuery(neInfo neModel.NeInfo, operPara []string) // ConfigParamModify 配置参数修改 // operType 配置执行类型字符串 add:新增,mod:修改,del:删除 // operPara 配置参数列表对象 具体可修改参数,请参考NRM数据模型规范中类型为“RW”的参数。 -func (s *ConfigImpl) ConfigParamModify(neInfo neModel.NeInfo, operType string, operPara map[string]any) []string { +func (s *ConfigImpl) ConfigParamModify(neInfo neModel.NeInfo, byUsername string, operType string, operPara map[string]any) []string { failPara := []string{} operParaSupport := []string{ "Ruid", // 网络设备的全网唯一标识 RW @@ -449,12 +453,26 @@ func (s *ConfigImpl) ConfigParamModify(neInfo neModel.NeInfo, operType string, o // if operType == "add" {} // 操作记录推送 Kafka - pushData := operPara - pushData["MsgID"] = generate.Code(9) - pushData["Ruid"] = neInfo.RmUID - pushData["ChangeTime"] = date.ParseDateToStr(time.Now(), date.YYYY_MM_DD_HH_MM_SS) - pushData["ChangeType"] = operType - s.resourceService.KafkaPush(neInfo.NeType, "", pushData) + bytes, _ := json.Marshal(operPara) + nowTime := time.Now() + nrmLog := model.NRMLog{ + Ruid: neInfo.RmUID, + UserLabel: neInfo.NeName, + CreateBy: byUsername, + CreateTime: nowTime.UnixMilli(), + ChangeTime: date.ParseDateToStr(time.Now(), date.YYYY_MM_DD_HH_MM_SS), + ChangeType: operType, + ChangeOper: string(bytes), + } + nrmLogId := s.nrmLogService.Insert(nrmLog) + if nrmLogId != "" { + pushData := operPara + pushData["MsgID"] = nrmLogId + pushData["Ruid"] = nrmLog.Ruid + pushData["ChangeTime"] = nrmLog.ChangeTime + pushData["ChangeType"] = nrmLog.ChangeType + s.resourceService.KafkaPush(neInfo.NeType, "", pushData) + } return failPara } diff --git a/src/modules/nms_cxy/service/nms_cxy_nrm_log.go b/src/modules/nms_cxy/service/nms_cxy_nrm_log.go new file mode 100644 index 0000000..244ccbb --- /dev/null +++ b/src/modules/nms_cxy/service/nms_cxy_nrm_log.go @@ -0,0 +1,12 @@ +package service + +import "nms_cxy/src/modules/nms_cxy/model" + +// 资源数据操作日志服务 服务层接口 +type INRMLog interface { + // SelectPage 根据条件分页查询字典类型 + SelectPage(query map[string]any) map[string]any + + // Insert 新增信息 + Insert(nrmLog model.NRMLog) string +} diff --git a/src/modules/nms_cxy/service/nms_cxy_nrm_log.impl.go b/src/modules/nms_cxy/service/nms_cxy_nrm_log.impl.go new file mode 100644 index 0000000..c0e201e --- /dev/null +++ b/src/modules/nms_cxy/service/nms_cxy_nrm_log.impl.go @@ -0,0 +1,173 @@ +package service + +import ( + "strings" + "time" + + "nms_cxy/src/framework/datasource" + "nms_cxy/src/framework/logger" + "nms_cxy/src/framework/utils/parse" + "nms_cxy/src/framework/utils/repo" + "nms_cxy/src/modules/nms_cxy/model" +) + +// 实例化数据层 NewNRMLog 结构体 +var NewNRMLogImpl = &NRMLogImpl{ + selectSql: `select + msg_id, ruid, user_label, change_time, change_type, change_oper, create_by, create_time + from nms_cxy_nrm_log`, + + resultMap: map[string]string{ + "msg_id": "MsgID", + "ruid": "Ruid", + "user_label": "UserLabel", + "change_time": "ChangeTime", + "change_type": "ChangeType", + "change_oper": "ChangeOper", + "create_by": "CreateBy", + "create_time": "CreateTime", + }, +} + +// NRMLogImpl 资源数据操作日志服务 数据层处理 +type NRMLogImpl struct { + // 查询视图对象SQL + selectSql string + // 结果字段与实体映射 + resultMap map[string]string +} + +// convertResultRows 将结果记录转实体结果组 +func (r *NRMLogImpl) convertResultRows(rows []map[string]any) []model.NRMLog { + arr := make([]model.NRMLog, 0) + for _, row := range rows { + item := model.NRMLog{} + for key, value := range row { + if keyMapper, ok := r.resultMap[key]; ok { + repo.SetFieldValue(&item, keyMapper, value) + } + } + arr = append(arr, item) + } + return arr +} + +// SelectPage 根据条件分页查询字典类型 +func (r *NRMLogImpl) SelectPage(query map[string]any) map[string]any { + // 查询条件拼接 + var conditions []string + var params []any + if v, ok := query["ruid"]; ok && v != "" { + conditions = append(conditions, "ruid = ?") + params = append(params, strings.Trim(v.(string), " ")) + } + if v, ok := query["changeType"]; ok && v != "" { + conditions = append(conditions, "change_type = ?") + params = append(params, strings.Trim(v.(string), " ")) + } + if v, ok := query["startTime"]; ok && v != "" { + conditions = append(conditions, "create_time >= ?") + params = append(params, v) + } + if v, ok := query["endTime"]; ok && v != "" { + conditions = append(conditions, "create_time <= ?") + params = append(params, v) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + result := map[string]any{ + "total": 0, + "rows": []model.NRMLog{}, + } + + // 查询数量 长度为0直接返回 + totalSql := "select count(1) as 'total' from nms_cxy_nrm_log" + totalRows, err := datasource.RawDB("", totalSql+whereSql, params) + if err != nil { + logger.Errorf("total err => %v", err) + return result + } + total := parse.Number(totalRows[0]["total"]) + if total == 0 { + return result + } else { + result["total"] = total + } + + // 分页 + pageNum, pageSize := repo.PageNumSize(query["pageNum"], query["pageSize"]) + pageSql := " limit ?,? " + params = append(params, pageNum*pageSize) + params = append(params, pageSize) + + // 查询数据 + querySql := r.selectSql + whereSql + pageSql + results, err := datasource.RawDB("", querySql, params) + if err != nil { + logger.Errorf("query err => %v", err) + return result + } + + // 转换实体 + result["rows"] = r.convertResultRows(results) + return result +} + +// Insert 新增信息 +func (r *NRMLogImpl) Insert(nrmLog model.NRMLog) string { + // 参数拼接 + params := make(map[string]any) + if nrmLog.MsgID != "" { + params["msg_id"] = nrmLog.MsgID + } + if nrmLog.Ruid != "" { + params["ruid"] = nrmLog.Ruid + } + if nrmLog.UserLabel != "" { + params["user_label"] = nrmLog.UserLabel + } + if nrmLog.ChangeTime != "" { + params["change_time"] = nrmLog.ChangeTime + } + if nrmLog.ChangeType != "" { + params["change_type"] = nrmLog.ChangeType + } + if nrmLog.ChangeOper != "" { + params["change_oper"] = nrmLog.ChangeOper + } + if nrmLog.CreateBy != "" { + params["create_by"] = nrmLog.CreateBy + params["create_time"] = time.Now().UnixMilli() + } + + // 构建执行语句 + keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params) + sql := "insert into nms_cxy_nrm_log (" + strings.Join(keys, ",") + ")values(" + placeholder + ")" + + db := datasource.DefaultDB() + // 开启事务 + tx := db.Begin() + // 执行插入 + err := tx.Exec(sql, values...).Error + if err != nil { + logger.Errorf("insert row : %v", err.Error()) + tx.Rollback() + return "" + } + // 获取生成的自增 ID + var insertedID string + err = tx.Raw("select last_insert_id()").Row().Scan(&insertedID) + if err != nil { + logger.Errorf("insert last id : %v", err.Error()) + tx.Rollback() + return "" + } + // 提交事务 + tx.Commit() + return insertedID +}