ref: 重构网元状态,提升加载网元列表带状态速度
Refactor network element state management - Removed the NE state endpoint and related service logic from the network_data module. - Introduced a new NEStateController to handle network element state records. - Implemented NEState service and repository for managing state records in the database. - Updated NEInfo and NeLicense controllers to utilize the new NEState service for fetching and saving state information. - Enhanced state handling in the websocket processor to reflect the latest state of network elements. - Added caching logic for network element states using Redis. - Improved error handling and response formatting for state queries.
This commit is contained in:
@@ -6,16 +6,20 @@ CREATE TABLE "ne_state" (
|
||||
"id" integer NOT NULL,
|
||||
"ne_type" text(16),
|
||||
"ne_id" text(32),
|
||||
"version" text(16),
|
||||
"capability" integer,
|
||||
"ne_version" text(16),
|
||||
"standby" integer,
|
||||
"nb_number" integer,
|
||||
"ue_number" integer,
|
||||
"serial_num" text(16),
|
||||
"expiry_date" text(10),
|
||||
"hostname" text(32),
|
||||
"os" text(196),
|
||||
"sys_cpu_usage" integer,
|
||||
"sys_mem_usage" integer,
|
||||
"sys_disk_usage" integer,
|
||||
"nf_cpu_usage" integer,
|
||||
"nf_mem_used" integer,
|
||||
"create_time" integer,
|
||||
"refresh_time" integer,
|
||||
PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
@@ -26,7 +30,7 @@ CREATE INDEX "idx_type_id_time"
|
||||
ON "ne_state" (
|
||||
"ne_type" ASC,
|
||||
"ne_id" ASC,
|
||||
"create_time" ASC
|
||||
"refresh_time" ASC
|
||||
);
|
||||
|
||||
-- ----------------------------
|
||||
|
||||
38
build/database/lite/upgrade/upg_ne_state.sql
Normal file
38
build/database/lite/upgrade/upg_ne_state.sql
Normal file
@@ -0,0 +1,38 @@
|
||||
-- ----------------------------
|
||||
-- Table structure for ne_state
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS "ne_state";
|
||||
CREATE TABLE "ne_state" (
|
||||
"id" integer NOT NULL,
|
||||
"ne_type" text(16),
|
||||
"ne_id" text(32),
|
||||
"ne_version" text(16),
|
||||
"standby" integer,
|
||||
"nb_number" integer,
|
||||
"ue_number" integer,
|
||||
"serial_num" text(16),
|
||||
"expiry_date" text(10),
|
||||
"hostname" text(32),
|
||||
"os" text(196),
|
||||
"sys_cpu_usage" integer,
|
||||
"sys_mem_usage" integer,
|
||||
"sys_disk_usage" integer,
|
||||
"nf_cpu_usage" integer,
|
||||
"nf_mem_used" integer,
|
||||
"refresh_time" integer,
|
||||
PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- ----------------------------
|
||||
-- Indexes structure for table ne_state
|
||||
-- ----------------------------
|
||||
CREATE INDEX IF NOT EXISTS "idx_type_id_time"
|
||||
ON "ne_state" (
|
||||
"ne_type" ASC,
|
||||
"ne_id" ASC,
|
||||
"refresh_time" ASC
|
||||
);
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of ne_state
|
||||
-- ----------------------------
|
||||
@@ -7,20 +7,24 @@ SET FOREIGN_KEY_CHECKS = 0;
|
||||
DROP TABLE IF EXISTS `ne_state`;
|
||||
CREATE TABLE `ne_state` (
|
||||
`id` int NOT NULL AUTO_INCREMENT,
|
||||
`ne_type` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '',
|
||||
`ne_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '',
|
||||
`version` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '版本',
|
||||
`capability` bigint DEFAULT '0' COMMENT '用户容量',
|
||||
`ne_type` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '网元类型',
|
||||
`ne_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '网元ID',
|
||||
`ne_version` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '网元版本',
|
||||
`standby` int DEFAULT '0' COMMENT '主备状态 0-主 1-备',
|
||||
`nb_number` int DEFAULT '0' COMMENT '基站容量',
|
||||
`ue_number` int DEFAULT '0' COMMENT '用户容量',
|
||||
`serial_num` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '序列号',
|
||||
`expiry_date` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '许可证到期日期',
|
||||
`hostname` varchar(32) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '主机名 hostname',
|
||||
`os` varchar(196) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '操作系统 uname',
|
||||
`sys_cpu_usage` float DEFAULT '0' COMMENT 'cpu使用率-sys',
|
||||
`sys_mem_usage` float DEFAULT '0' COMMENT '内存使用率-sys',
|
||||
`sys_disk_usage` float DEFAULT '0' COMMENT '磁盘使用率-sys',
|
||||
`nf_cpu_usage` float DEFAULT '0' COMMENT 'cpu使用率-nf',
|
||||
`nf_mem_used` bigint DEFAULT '0' COMMENT '内存使用KB-nf',
|
||||
`create_time` bigint DEFAULT '0' COMMENT '创建时间',
|
||||
`refresh_time` bigint DEFAULT '0' COMMENT '刷新时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
KEY `idx_type_id_time` (`ne_type`,`ne_id`,`create_time`) USING BTREE COMMENT 'idx_state_ne_type_id_at'
|
||||
KEY `idx_type_id_time` (`ne_type`,`ne_id`,`refresh_time`) USING BTREE COMMENT 'idx_state_ne_type_id_at'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='网元_状态记录内存/CPU/磁盘';
|
||||
|
||||
SET FOREIGN_KEY_CHECKS=1;
|
||||
|
||||
@@ -1,49 +1,29 @@
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
--
|
||||
-- Table structure for table `ne_state`
|
||||
--
|
||||
CREATE TABLE IF NOT EXISTS `ne_state` (
|
||||
DROP TABLE IF EXISTS `ne_state`;
|
||||
CREATE TABLE `ne_state` (
|
||||
`id` int NOT NULL AUTO_INCREMENT,
|
||||
`ne_type` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '',
|
||||
`ne_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '',
|
||||
`version` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '版本',
|
||||
`capability` bigint DEFAULT '0' COMMENT '用户容量',
|
||||
`ne_type` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '网元类型',
|
||||
`ne_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '网元ID',
|
||||
`ne_version` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '网元版本',
|
||||
`standby` int DEFAULT '0' COMMENT '主备状态 0-主 1-备',
|
||||
`nb_number` int DEFAULT '0' COMMENT '基站容量',
|
||||
`ue_number` int DEFAULT '0' COMMENT '用户容量',
|
||||
`serial_num` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '序列号',
|
||||
`expiry_date` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '许可证到期日期',
|
||||
`hostname` varchar(32) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '主机名 hostname',
|
||||
`os` varchar(196) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '操作系统 uname',
|
||||
`sys_cpu_usage` float DEFAULT '0' COMMENT 'cpu使用率-sys',
|
||||
`sys_mem_usage` float DEFAULT '0' COMMENT '内存使用率-sys',
|
||||
`sys_disk_usage` float DEFAULT '0' COMMENT '磁盘使用率-sys',
|
||||
`nf_cpu_usage` float DEFAULT '0' COMMENT 'cpu使用率-nf',
|
||||
`nf_mem_used` bigint DEFAULT '0' COMMENT '内存使用KB-nf',
|
||||
`create_time` bigint DEFAULT '0' COMMENT '创建时间',
|
||||
`refresh_time` bigint DEFAULT '0' COMMENT '刷新时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
KEY `idx_type_id_time` (`ne_type`,`ne_id`,`create_time`) USING BTREE COMMENT 'idx_state_ne_type_id_at'
|
||||
KEY `idx_type_id_time` (`ne_type`,`ne_id`,`refresh_time`) USING BTREE COMMENT 'idx_state_ne_type_id_at'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='网元_状态记录内存/CPU/磁盘';
|
||||
|
||||
-- ----------------------------
|
||||
-- COLUMN for ne_state
|
||||
-- ----------------------------
|
||||
ALTER TABLE `ne_state` DROP COLUMN `cpu_usage`;
|
||||
ALTER TABLE `ne_state` DROP COLUMN `mem_usage`;
|
||||
ALTER TABLE `ne_state` DROP COLUMN `disk_space`;
|
||||
ALTER TABLE `ne_state` DROP COLUMN `timestamp`;
|
||||
ALTER TABLE `ne_state` DROP INDEX `idx_ne_type_id`;
|
||||
ALTER TABLE `ne_state` DROP INDEX `idx_timestamp`;
|
||||
ALTER TABLE `ne_state` MODIFY COLUMN `ne_type` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' AFTER `id`;
|
||||
ALTER TABLE `ne_state` MODIFY COLUMN `ne_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' AFTER `ne_type`;
|
||||
ALTER TABLE `ne_state` MODIFY COLUMN `version` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '版本' AFTER `ne_id`;
|
||||
ALTER TABLE `ne_state` MODIFY COLUMN `capability` bigint(20) NULL DEFAULT 0 COMMENT '用户容量' AFTER `version`;
|
||||
ALTER TABLE `ne_state` MODIFY COLUMN `serial_num` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '序列号' AFTER `capability`;
|
||||
ALTER TABLE `ne_state` MODIFY COLUMN `expiry_date` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '许可证到期日期' AFTER `serial_num`;
|
||||
ALTER TABLE `ne_state` ADD COLUMN `sys_cpu_usage` float NULL DEFAULT 0 COMMENT 'cpu使用率-sys' AFTER `expiry_date`;
|
||||
ALTER TABLE `ne_state` ADD COLUMN `sys_mem_usage` float NULL DEFAULT 0 COMMENT '内存使用率-sys' AFTER `sys_cpu_usage`;
|
||||
ALTER TABLE `ne_state` ADD COLUMN `sys_disk_usage` float NULL DEFAULT 0 COMMENT '磁盘使用率-sys' AFTER `sys_mem_usage`;
|
||||
ALTER TABLE `ne_state` ADD COLUMN `nf_cpu_usage` float NULL DEFAULT 0 COMMENT 'cpu使用率-nf' AFTER `sys_disk_usage`;
|
||||
ALTER TABLE `ne_state` ADD COLUMN `nf_mem_used` bigint(20) NULL DEFAULT 0 COMMENT '内存使用KB-nf' AFTER `nf_cpu_usage`;
|
||||
ALTER TABLE `ne_state` ADD COLUMN `create_time` bigint(20) NULL DEFAULT 0 COMMENT '创建时间' AFTER `nf_mem_used`;
|
||||
ALTER TABLE `ne_state` ADD INDEX `idx_type_id_time`(`ne_type`, `ne_id`, `create_time`) USING BTREE COMMENT 'idx_state_ne_type_id_at';
|
||||
ALTER TABLE `ne_state` COMMENT = '网元_状态记录内存/CPU/磁盘';
|
||||
|
||||
SET FOREIGN_KEY_CHECKS=1;
|
||||
|
||||
@@ -4,8 +4,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -17,8 +15,7 @@ import (
|
||||
"be.ems/src/framework/database/redis"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
neDataModel "be.ems/src/modules/network_data/model"
|
||||
neDataService "be.ems/src/modules/network_data/service"
|
||||
neFetchlink "be.ems/src/modules/network_element/fetch_link"
|
||||
neModel "be.ems/src/modules/network_element/model"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
oamService "be.ems/src/modules/oam/service"
|
||||
@@ -27,7 +24,7 @@ import (
|
||||
|
||||
var NewProcessor = &NeAlarmStateCheckCMDProcessor{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
neStateService: neDataService.NewNEState,
|
||||
neStateService: neService.NewNEState,
|
||||
wsSendService: wsService.NewWSSend,
|
||||
count: 0,
|
||||
triggerMax: 3,
|
||||
@@ -36,12 +33,12 @@ var NewProcessor = &NeAlarmStateCheckCMDProcessor{
|
||||
|
||||
// NeAlarmStateCheckCMDProcessor 网元告警内存/CPU/磁盘检查
|
||||
type NeAlarmStateCheckCMDProcessor struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
neStateService *neDataService.NEState // 网元状态信息服务
|
||||
wsSendService *wsService.WSSend // ws发送服务
|
||||
count int // 执行次数
|
||||
triggerMax int64 // 阈值:连续触发次数大于该值才会产生告警
|
||||
triggerCount sync.Map // 阈值连续触发次数,存储每个事件的触发记录
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
neStateService *neService.NEState // 网元状态信息服务
|
||||
wsSendService *wsService.WSSend // ws发送服务
|
||||
count int // 执行次数
|
||||
triggerMax int64 // 阈值:连续触发次数大于该值才会产生告警
|
||||
triggerCount sync.Map // 阈值连续触发次数,存储每个事件的触发记录
|
||||
}
|
||||
|
||||
// alarmParams 告警参数
|
||||
@@ -95,20 +92,23 @@ func (s *NeAlarmStateCheckCMDProcessor) Execute(data any) (any, error) {
|
||||
return nil, fmt.Errorf("diskUseGt must be between 0 and 100")
|
||||
}
|
||||
|
||||
neList := s.neInfoService.Find(neModel.NeInfo{}, true, false)
|
||||
neList := s.neInfoService.Find(neModel.NeInfo{}, false, false)
|
||||
for _, neInfo := range neList {
|
||||
if neInfo.CreateTime == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// 网元在线状态
|
||||
isOnline := parse.Boolean(neInfo.ServerState["online"])
|
||||
if !isOnline {
|
||||
key := fmt.Sprintf("%s:%s:%s_status", constants.CACHE_NE_INFO, neInfo.NeType, neInfo.NeId)
|
||||
state, stateErr := neFetchlink.NeState(neInfo)
|
||||
if stateErr != nil {
|
||||
redis.Del("", key)
|
||||
continue
|
||||
}
|
||||
redis.Set("", key, neInfo.RmUID, 0)
|
||||
|
||||
// 检查状态
|
||||
sysCpuUsage, sysMemUsage, sysDiskUsage := s.serverState(neInfo.ServerState)
|
||||
sysCpuUsage, sysMemUsage, sysDiskUsage := s.serverState(state)
|
||||
// 检查CPU/Memory/Disk使用率
|
||||
warnMsg := []string{}
|
||||
if int64(sysCpuUsage) >= params.CPUUseGt {
|
||||
@@ -193,68 +193,17 @@ func (s *NeAlarmStateCheckCMDProcessor) Execute(data any) (any, error) {
|
||||
|
||||
// serverState 网元状态记录
|
||||
func (s *NeAlarmStateCheckCMDProcessor) serverState(state map[string]any) (float64, float64, float64) {
|
||||
// 网元CPU使用率
|
||||
var nfCpuUsage float64 = 0
|
||||
// CPU使用率
|
||||
var sysCpuUsage float64 = 0
|
||||
if state["cpu"] != nil {
|
||||
cpu := state["cpu"].(map[string]any)
|
||||
v := parse.Number(cpu["sysCpuUsage"])
|
||||
sysCpuUsage = float64(v) / 100
|
||||
nfv := parse.Number(cpu["nfCpuUsage"])
|
||||
nfCpuUsage = float64(nfv) / 100
|
||||
neState := s.neStateService.SaveState(state)
|
||||
if neState.ID <= 0 {
|
||||
return 0, 0, 0
|
||||
}
|
||||
|
||||
// 网元内存使用KB
|
||||
var nfMemUsed int64 = 0
|
||||
// 内存使用率
|
||||
var sysMemUsage float64 = 0
|
||||
if state["mem"] != nil {
|
||||
mem := state["mem"].(map[string]any)
|
||||
v := parse.Number(mem["sysMemUsage"])
|
||||
sysMemUsage = float64(v) / 100
|
||||
nfMemUsed = parse.Number(mem["nfUsedMem"])
|
||||
}
|
||||
|
||||
// 磁盘使用率
|
||||
var sysDiskUsage float64 = 0
|
||||
if state["disk"] != nil {
|
||||
mem := state["disk"].(map[string]any)
|
||||
disks := mem["partitionInfo"].([]any)
|
||||
sort.Slice(disks, func(i, j int) bool {
|
||||
iUsed := parse.Number(disks[i].(map[string]any)["used"])
|
||||
jUsed := parse.Number(disks[j].(map[string]any)["used"])
|
||||
return iUsed > jUsed
|
||||
})
|
||||
disk := disks[0].(map[string]any)
|
||||
total := parse.Number(disk["total"])
|
||||
used := parse.Number(disk["used"])
|
||||
sysDiskUsage = (float64(used) / float64(total)) * 100
|
||||
sysDiskUsage, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", sysDiskUsage), 64)
|
||||
}
|
||||
|
||||
// 插入网元状态记录
|
||||
neState := neDataModel.NEState{
|
||||
NeType: fmt.Sprint(state["neType"]),
|
||||
NeId: fmt.Sprint(state["neId"]),
|
||||
Version: fmt.Sprint(state["version"]),
|
||||
Capability: parse.Number(state["capability"]),
|
||||
SerialNum: fmt.Sprint(state["sn"]),
|
||||
ExpiryDate: fmt.Sprint(state["expire"]),
|
||||
SysCpuUsage: sysCpuUsage,
|
||||
SysMemUsage: sysMemUsage,
|
||||
SysDiskUsage: sysDiskUsage,
|
||||
NfCpuUsage: nfCpuUsage,
|
||||
NfMemUsed: nfMemUsed,
|
||||
CreateTime: parse.Number(state["refreshTime"]),
|
||||
}
|
||||
s.neStateService.Insert(neState)
|
||||
// 删除网元状态记录7天前
|
||||
ltTime := time.Now().AddDate(0, 0, -7).UnixMilli()
|
||||
s.neStateService.DeleteByTime(ltTime)
|
||||
s.neStateService.DeleteByTime(neState.NeType, neState.NeId, ltTime)
|
||||
// 推送ws消息
|
||||
groupID := fmt.Sprintf("%s_%s_%s", wsService.GROUP_NE_STATE, neState.NeType, neState.NeId)
|
||||
s.wsSendService.ByGroupID(groupID, neState)
|
||||
|
||||
return sysCpuUsage, sysMemUsage, sysDiskUsage
|
||||
return neState.SysCpuUsage, neState.SysMemUsage, neState.SysDiskUsage
|
||||
}
|
||||
|
||||
@@ -137,15 +137,6 @@ func Setup(router *gin.Engine) {
|
||||
)
|
||||
}
|
||||
|
||||
// 网元状态记录信息
|
||||
neStateGroup := neDataGroup.Group("/ne-state")
|
||||
{
|
||||
neStateGroup.GET("/list",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewNEState.List,
|
||||
)
|
||||
}
|
||||
|
||||
// 基站状态历史记录信息 含AMF/MME
|
||||
nbStateGroup := neDataGroup.Group("/nb-state")
|
||||
{
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"be.ems/src/modules/network_data/model"
|
||||
"be.ems/src/modules/network_data/repository"
|
||||
)
|
||||
|
||||
// 实例化数据层 NEState 结构体
|
||||
var NewNEState = &NEState{
|
||||
neStateRepository: repository.NewNEState,
|
||||
}
|
||||
|
||||
// NEState 网元状态记录表 服务层处理
|
||||
type NEState struct {
|
||||
neStateRepository *repository.NEState // 网元状态记录信息
|
||||
}
|
||||
|
||||
// FindByPage 根据条件分页查询
|
||||
func (r NEState) FindByPage(query model.NEStateQuery) ([]model.NEState, int64) {
|
||||
return r.neStateRepository.SelectByPage(query)
|
||||
}
|
||||
|
||||
// Insert 插入数据
|
||||
func (r NEState) Insert(item model.NEState) int64 {
|
||||
return r.neStateRepository.Insert(item)
|
||||
}
|
||||
|
||||
// DeleteByTime 删除数据
|
||||
func (r NEState) DeleteByTime(ltTime int64) int64 {
|
||||
return r.neStateRepository.DeleteByTime(ltTime)
|
||||
}
|
||||
@@ -3,8 +3,9 @@ package controller
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/database/redis"
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
@@ -21,6 +22,7 @@ var NewNeInfo = &NeInfoController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
neLicenseService: neService.NewNeLicense,
|
||||
neVersionService: neService.NewNeVersion,
|
||||
neStateService: neService.NewNEState,
|
||||
}
|
||||
|
||||
// 网元信息请求
|
||||
@@ -30,12 +32,9 @@ type NeInfoController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
neLicenseService *neService.NeLicense // 网元授权激活信息服务
|
||||
neVersionService *neService.NeVersion // 网元版本信息服务
|
||||
neStateService *neService.NEState // 网元状态服务
|
||||
}
|
||||
|
||||
// neStateCacheMap 网元状态缓存最后一次成功的信息
|
||||
var neStateCacheMap sync.Map
|
||||
var mutex sync.Mutex
|
||||
|
||||
// 网元信息状态
|
||||
//
|
||||
// GET /state
|
||||
@@ -67,37 +66,18 @@ func (s NeInfoController) State(c *gin.Context) {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
neKey := fmt.Sprintf("%s_%s", neInfo.NeType, neInfo.NeId)
|
||||
state := s.neStateService.Last(neInfo.NeType, neInfo.NeId)
|
||||
result := s.neStateService.ParseState(neInfo, state)
|
||||
|
||||
// 网元直连
|
||||
resData, err := neFetchlink.NeState(neInfo)
|
||||
if err != nil {
|
||||
mutex.Lock()
|
||||
// 异常取上次缓存
|
||||
resDataCache, ok := neStateCacheMap.Load(neKey)
|
||||
if ok && resDataCache != nil {
|
||||
resDataCache.(map[string]any)["online"] = false
|
||||
} else {
|
||||
resDataCache = map[string]any{
|
||||
"online": false,
|
||||
"neId": neInfo.NeId,
|
||||
"neName": neInfo.NeName,
|
||||
"neType": neInfo.NeType,
|
||||
"neIP": neInfo.IP,
|
||||
}
|
||||
}
|
||||
neStateCacheMap.Store(neKey, resDataCache)
|
||||
mutex.Unlock()
|
||||
c.JSON(200, resp.OkData(resDataCache))
|
||||
return
|
||||
// 没状态标记,视为离线
|
||||
key := fmt.Sprintf("%s:%s:%s_status", constants.CACHE_NE_INFO, neInfo.NeType, neInfo.NeId)
|
||||
keyNum, err := redis.Has("", key)
|
||||
if keyNum == 0 || err != nil {
|
||||
result["online"] = false
|
||||
} else {
|
||||
result["online"] = true
|
||||
}
|
||||
|
||||
// 存入缓存
|
||||
resData["online"] = true
|
||||
mutex.Lock()
|
||||
neStateCacheMap.Store(neKey, resData)
|
||||
mutex.Unlock()
|
||||
c.JSON(200, resp.OkData(resData))
|
||||
c.JSON(200, resp.OkData(result))
|
||||
}
|
||||
|
||||
// 网元neType和neID查询
|
||||
@@ -362,22 +342,6 @@ func (s NeInfoController) Add(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// 获取网元状态是否正常
|
||||
body.ServerState, err = neFetchlink.NeState(body)
|
||||
if err != nil {
|
||||
body.Status = 0
|
||||
} else {
|
||||
// 网元状态设置为在线
|
||||
body.Status = 1
|
||||
if parse.Boolean(body.ServerState["standby"]) {
|
||||
body.Status = 3
|
||||
}
|
||||
// 下发网管配置信息给网元
|
||||
if _, err = neFetchlink.NeConfigOMC(body); err != nil {
|
||||
body.Status = 2
|
||||
}
|
||||
}
|
||||
|
||||
loginUserName := reqctx.LoginUserToUserName(c)
|
||||
// 新增Version信息
|
||||
neVersion := model.NeVersion{
|
||||
@@ -392,24 +356,34 @@ func (s NeInfoController) Add(c *gin.Context) {
|
||||
CreateBy: loginUserName,
|
||||
}
|
||||
|
||||
// 已有网元可获取的信息
|
||||
if body.ServerState != nil {
|
||||
if v, ok := body.ServerState["version"]; ok && v != nil {
|
||||
body.NeVersion = fmt.Sprint(v)
|
||||
neVersion.Version = fmt.Sprint(v)
|
||||
// 获取网元状态是否正常
|
||||
key := fmt.Sprintf("%s:%s:%s_status", constants.CACHE_NE_INFO, body.NeType, body.NeId)
|
||||
state, err := neFetchlink.NeState(body)
|
||||
if err != nil {
|
||||
redis.Del("", key)
|
||||
body.Status = 0
|
||||
} else {
|
||||
redis.Set("", key, body.RmUID, 0)
|
||||
// 网元状态设置为在线
|
||||
body.Status = 1
|
||||
if parse.Boolean(state["standby"]) {
|
||||
body.Status = 3
|
||||
}
|
||||
if v, ok := body.ServerState["sn"]; ok && v != nil {
|
||||
neLicense.SerialNum = fmt.Sprint(v)
|
||||
// 下发网管配置信息给网元
|
||||
if _, err = neFetchlink.NeConfigOMC(body); err != nil {
|
||||
body.Status = 2
|
||||
}
|
||||
if v, ok := body.ServerState["expire"]; ok && v != nil {
|
||||
neLicense.ExpiryDate = fmt.Sprint(v)
|
||||
// 网元状态记录
|
||||
neState := s.neStateService.SaveState(state)
|
||||
body.ServerState = s.neStateService.ParseState(body, neState)
|
||||
if neState.ID > 0 {
|
||||
body.NeVersion = neState.NeVersion
|
||||
neVersion.Version = neState.NeVersion
|
||||
neLicense.SerialNum = neState.SerialNum
|
||||
neLicense.ExpiryDate = neState.ExpiryDate
|
||||
neLicense.Status = "1"
|
||||
}
|
||||
if v, ok := body.ServerState["ueNumber"]; ok && v != nil {
|
||||
neLicense.UeNumber = parse.Number(v)
|
||||
}
|
||||
if v, ok := body.ServerState["nbNumber"]; ok && v != nil {
|
||||
neLicense.NbNumber = parse.Number(v)
|
||||
neLicense.UeNumber = neState.UENumber
|
||||
neLicense.NbNumber = neState.NbNumber
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,62 +449,41 @@ func (s NeInfoController) Edit(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
loginUserName := reqctx.LoginUserToUserName(c)
|
||||
neLicense := s.neLicenseService.FindByNeTypeAndNeID(neInfo.NeType, neInfo.NeId)
|
||||
neVersion := s.neVersionService.FindByNeTypeAndNeID(neInfo.NeType, neInfo.NeId)
|
||||
|
||||
// 获取网元状态是否正常
|
||||
body.ServerState, err = neFetchlink.NeState(neInfo)
|
||||
key := fmt.Sprintf("%s:%s:%s_status", constants.CACHE_NE_INFO, body.NeType, body.NeId)
|
||||
state, err := neFetchlink.NeState(body)
|
||||
if err != nil {
|
||||
redis.Del("", key)
|
||||
body.Status = 0
|
||||
} else {
|
||||
redis.Set("", key, body.RmUID, 0)
|
||||
// 网元状态设置为在线
|
||||
body.Status = 1
|
||||
if parse.Boolean(body.ServerState["standby"]) {
|
||||
if parse.Boolean(state["standby"]) {
|
||||
body.Status = 3
|
||||
}
|
||||
// 下发网管配置信息给网元
|
||||
if _, err = neFetchlink.NeConfigOMC(body); err != nil {
|
||||
body.Status = 2
|
||||
}
|
||||
}
|
||||
|
||||
loginUserName := reqctx.LoginUserToUserName(c)
|
||||
neLicense := s.neLicenseService.FindByNeTypeAndNeID(neInfo.NeType, neInfo.NeId)
|
||||
neVersion := s.neVersionService.FindByNeTypeAndNeID(neInfo.NeType, neInfo.NeId)
|
||||
|
||||
// 已有网元可获取的信息
|
||||
if body.ServerState != nil {
|
||||
if v, ok := body.ServerState["version"]; ok && v != nil {
|
||||
body.NeVersion = fmt.Sprint(v)
|
||||
neVersion.Version = fmt.Sprint(v)
|
||||
neVersion.UpdateBy = loginUserName
|
||||
}
|
||||
if v, ok := body.ServerState["sn"]; ok && v != nil {
|
||||
neLicense.SerialNum = fmt.Sprint(v)
|
||||
}
|
||||
if v, ok := body.ServerState["expire"]; ok && v != nil {
|
||||
neLicense.ExpiryDate = fmt.Sprint(v)
|
||||
// 网元状态记录
|
||||
neState := s.neStateService.SaveState(state)
|
||||
body.ServerState = s.neStateService.ParseState(body, neState)
|
||||
if neState.ID > 0 {
|
||||
body.NeVersion = neState.NeVersion
|
||||
neVersion.Version = neState.NeVersion
|
||||
s.neVersionService.Update(neVersion)
|
||||
neLicense.SerialNum = neState.SerialNum
|
||||
neLicense.ExpiryDate = neState.ExpiryDate
|
||||
neLicense.Status = "1"
|
||||
neLicense.UpdateBy = loginUserName
|
||||
neLicense.UeNumber = neState.UENumber
|
||||
neLicense.NbNumber = neState.NbNumber
|
||||
s.neLicenseService.Update(neLicense)
|
||||
}
|
||||
if v, ok := body.ServerState["ueNumber"]; ok && v != nil {
|
||||
neLicense.UeNumber = parse.Number(v)
|
||||
}
|
||||
if v, ok := body.ServerState["nbNumber"]; ok && v != nil {
|
||||
neLicense.NbNumber = parse.Number(v)
|
||||
}
|
||||
}
|
||||
|
||||
if neVersion.ID <= 0 {
|
||||
if neVersion.NeType != body.NeType || neVersion.NeId != body.NeId {
|
||||
neVersion.NeType = body.NeType
|
||||
neVersion.NeId = body.NeId
|
||||
}
|
||||
s.neVersionService.Update(neVersion)
|
||||
}
|
||||
if neLicense.ID <= 0 {
|
||||
if neLicense.NeType != body.NeType || neLicense.NeId != body.NeId {
|
||||
neLicense.NeType = body.NeType
|
||||
neLicense.NeId = body.NeId
|
||||
}
|
||||
s.neLicenseService.Update(neLicense)
|
||||
}
|
||||
|
||||
body.UpdateBy = loginUserName
|
||||
|
||||
@@ -6,11 +6,12 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/database/redis"
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/reqctx"
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
neFetchlink "be.ems/src/modules/network_element/fetch_link"
|
||||
"be.ems/src/modules/network_element/model"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
)
|
||||
@@ -19,6 +20,7 @@ import (
|
||||
var NewNeLicense = &NeLicenseController{
|
||||
neLicenseService: neService.NewNeLicense,
|
||||
neInfoService: neService.NewNeInfo,
|
||||
neStateService: neService.NewNEState,
|
||||
}
|
||||
|
||||
// 网元授权激活请求
|
||||
@@ -27,6 +29,7 @@ var NewNeLicense = &NeLicenseController{
|
||||
type NeLicenseController struct {
|
||||
neLicenseService *neService.NeLicense // 网元授权激活服务
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
neStateService *neService.NEState // 网元状态服务
|
||||
}
|
||||
|
||||
// 网元授权激活列表
|
||||
@@ -260,15 +263,21 @@ func (s *NeLicenseController) State(c *gin.Context) {
|
||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
if neState, err := neFetchlink.NeState(neInfo); err == nil && neState["sn"] != nil {
|
||||
neLicense.Status = "1"
|
||||
neLicense.SerialNum = fmt.Sprint(neState["sn"])
|
||||
neLicense.ExpiryDate = fmt.Sprint(neState["expire"])
|
||||
neLicense.UeNumber = parse.Number(neState["ueNumber"])
|
||||
neLicense.NbNumber = parse.Number(neState["nbNumber"])
|
||||
} else {
|
||||
|
||||
// 没状态标记,视为离线
|
||||
key := fmt.Sprintf("%s:%s:%s_status", constants.CACHE_NE_INFO, neInfo.NeType, neInfo.NeId)
|
||||
keyNum, err := redis.Has("", key)
|
||||
if keyNum == 0 || err != nil {
|
||||
neLicense.Status = "0"
|
||||
} else {
|
||||
state := s.neStateService.Last(neInfo.NeType, neInfo.NeId)
|
||||
neLicense.Status = "1"
|
||||
neLicense.SerialNum = state.SerialNum
|
||||
neLicense.ExpiryDate = state.ExpiryDate
|
||||
neLicense.UeNumber = state.UENumber
|
||||
neLicense.NbNumber = state.NbNumber
|
||||
}
|
||||
|
||||
// 更新授权码
|
||||
if neLicense.ActivationRequestCode == "" || strings.HasPrefix(neLicense.ActivationRequestCode, "SN") || neLicense.Status == "0" {
|
||||
code, licensePath := s.neLicenseService.ReadLicenseInfo(neLicense)
|
||||
|
||||
@@ -6,23 +6,22 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"be.ems/src/framework/resp"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
neDataService "be.ems/src/modules/network_data/service"
|
||||
"be.ems/src/modules/network_element/model"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
)
|
||||
|
||||
// 实例化控制层 NEStateController 结构体
|
||||
var NewNEState = &NEStateController{
|
||||
neInfoService: neService.NewNeInfo,
|
||||
neStateService: neDataService.NewNEState,
|
||||
neStateService: neService.NewNEState,
|
||||
}
|
||||
|
||||
// 网元状态记录
|
||||
//
|
||||
// PATH /ne-state
|
||||
// PATH /ne/state
|
||||
type NEStateController struct {
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
neStateService *neDataService.NEState // 网元状态服务
|
||||
neInfoService *neService.NeInfo // 网元信息服务
|
||||
neStateService *neService.NEState // 网元状态服务
|
||||
}
|
||||
|
||||
// 网元状态记录-内存/CPU/磁盘列表
|
||||
@@ -44,7 +43,7 @@ type NEStateController struct {
|
||||
// @Security TokenAuth
|
||||
// @Summary NE Status Record - Memory/CPU/Disk List
|
||||
// @Description NE Status Record - Memory/CPU/Disk List
|
||||
// @Router /ne-state/list [get]
|
||||
// @Router /ne/state/list [get]
|
||||
func (s NEStateController) List(c *gin.Context) {
|
||||
var query model.NEStateQuery
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
@@ -3,18 +3,22 @@ package model
|
||||
// NEState 网元状态记录表 ne_state
|
||||
type NEState struct {
|
||||
ID int64 `json:"id" gorm:"column:id;primaryKey;autoIncrement"`
|
||||
NeType string `json:"neType" gorm:"column:ne_type"`
|
||||
NeId string `json:"neId" gorm:"column:ne_id"`
|
||||
Version string `json:"version" gorm:"column:version"` // 版本
|
||||
Capability int64 `json:"capability" gorm:"column:capability"` // 用户容量
|
||||
NeType string `json:"neType" gorm:"column:ne_type"` // 网元类型
|
||||
NeId string `json:"neId" gorm:"column:ne_id"` // 网元ID
|
||||
NeVersion string `json:"neVersion" gorm:"column:ne_version"` // 网元版本
|
||||
Standby int64 `json:"standby" gorm:"column:standby"` // 主备状态 0-主 1-备
|
||||
NbNumber int64 `json:"nbNumber" gorm:"column:nb_number"` // 基站容量
|
||||
UENumber int64 `json:"ueNumber" gorm:"column:ue_number"` // 用户容量
|
||||
SerialNum string `json:"serialNum" gorm:"column:serial_num"` // 序列号
|
||||
ExpiryDate string `json:"expiryDate" gorm:"column:expiry_date"` // 许可证到期日期
|
||||
HostName string `json:"hostname" gorm:"column:hostname"` // 主机名 hostname
|
||||
OS string `json:"os" gorm:"column:os"` // 操作系统 uname
|
||||
SysCpuUsage float64 `json:"sysCpuUsage" gorm:"column:sys_cpu_usage"` // cpu使用率-sys
|
||||
SysMemUsage float64 `json:"sysMemUsage" gorm:"column:sys_mem_usage"` // 内存使用率-sys
|
||||
SysDiskUsage float64 `json:"sysDiskUsage" gorm:"column:sys_disk_usage"` // 磁盘使用率-sys
|
||||
NfCpuUsage float64 `json:"nfCpuUsage" gorm:"column:nf_cpu_usage"` // cpu使用率-nf
|
||||
NfMemUsed int64 `json:"nfMemUsed" gorm:"column:nf_mem_used"` // 内存使用KB-nf
|
||||
CreateTime int64 `json:"createTime" gorm:"column:create_time"` // 创建时间
|
||||
RefreshTime int64 `json:"refreshTime" gorm:"column:refresh_time"` // 刷新时间
|
||||
}
|
||||
|
||||
// TableName 表名称
|
||||
@@ -48,6 +48,15 @@ func Setup(router *gin.Engine) {
|
||||
)
|
||||
}
|
||||
|
||||
// 网元状态记录信息
|
||||
neStateGroup := router.Group("/ne/state")
|
||||
{
|
||||
neStateGroup.GET("/list",
|
||||
middleware.AuthorizeUser(nil),
|
||||
controller.NewNEState.List,
|
||||
)
|
||||
}
|
||||
|
||||
// 网元信息
|
||||
neInfoGroup := router.Group("/ne/info")
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
|
||||
"be.ems/src/framework/database/db"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
"be.ems/src/modules/network_element/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 NEState 结构体
|
||||
@@ -25,18 +25,10 @@ func (r NEState) SelectByPage(query model.NEStateQuery) ([]model.NEState, int64)
|
||||
tx = tx.Where("ne_id = ?", query.NeID)
|
||||
}
|
||||
if query.BeginTime != "" {
|
||||
startTime := query.BeginTime
|
||||
if len(startTime) == 10 {
|
||||
startTime = startTime + "000"
|
||||
}
|
||||
tx = tx.Where("create_time >= ?", startTime)
|
||||
tx = tx.Where("refresh_time >= ?", query.BeginTime)
|
||||
}
|
||||
if query.EndTime != "" {
|
||||
endTime := query.EndTime
|
||||
if len(endTime) == 10 {
|
||||
endTime = endTime + "999"
|
||||
}
|
||||
tx = tx.Where("create_time <= ?", endTime)
|
||||
tx = tx.Where("refresh_time <= ?", query.EndTime)
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
@@ -85,12 +77,30 @@ func (r NEState) SelectByIds(ids []string) []model.NEState {
|
||||
return rows
|
||||
}
|
||||
|
||||
// SelectByLast 查询最新状态
|
||||
func (r NEState) SelectByLast(neType, neId string) model.NEState {
|
||||
item := model.NEState{}
|
||||
if neType == "" || neId == "" {
|
||||
return item
|
||||
}
|
||||
tx := db.DB("").Model(item)
|
||||
// 构建查询条件
|
||||
tx = tx.Where("ne_type = ? and ne_id = ?", neType, neId)
|
||||
tx = tx.Order("refresh_time desc")
|
||||
// 查询数据
|
||||
if err := tx.Limit(1).Find(&item).Error; err != nil {
|
||||
logger.Errorf("query find err => %v", err.Error())
|
||||
return item
|
||||
}
|
||||
return item
|
||||
}
|
||||
|
||||
// DeleteByTime 删除信息
|
||||
func (r NEState) DeleteByTime(ltTime int64) int64 {
|
||||
func (r NEState) DeleteByTime(neType, neId string, ltTime int64) int64 {
|
||||
if ltTime <= 0 {
|
||||
return 0
|
||||
}
|
||||
tx := db.DB("").Where("create_time < ?", ltTime)
|
||||
tx := db.DB("").Where("ne_type = ? and ne_id = ? and refresh_time < ?", neType, neId, ltTime)
|
||||
if err := tx.Delete(&model.NEState{}).Error; err != nil {
|
||||
logger.Errorf("delete err => %v", err.Error())
|
||||
return 0
|
||||
@@ -100,7 +110,9 @@ func (r NEState) DeleteByTime(ltTime int64) int64 {
|
||||
|
||||
// Insert 新增信息
|
||||
func (r NEState) Insert(param model.NEState) int64 {
|
||||
param.CreateTime = time.Now().UnixMilli()
|
||||
if param.RefreshTime <= 0 {
|
||||
param.RefreshTime = time.Now().UnixMilli()
|
||||
}
|
||||
// 执行插入
|
||||
if err := db.DB("").Create(¶m).Error; err != nil {
|
||||
logger.Errorf("insert err => %v", err.Error())
|
||||
@@ -147,3 +147,23 @@ func (r NeVersion) DeleteByIds(ids []int64) int64 {
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
|
||||
// UpdateVersion 修改网元版本
|
||||
func (r NeVersion) UpdateVersion(id int64, neVersion string) int64 {
|
||||
if id <= 0 {
|
||||
return 0
|
||||
}
|
||||
tx := db.DB("").Model(&model.NeVersion{})
|
||||
// 构建查询条件
|
||||
tx = tx.Where("id = ?", id)
|
||||
tx.Updates(map[string]any{
|
||||
"version": neVersion,
|
||||
"update_time": time.Now().UnixMilli(),
|
||||
})
|
||||
// 执行更新
|
||||
if err := tx.Error; err != nil {
|
||||
logger.Errorf("update err => %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return tx.RowsAffected
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
var NewNeInfo = &NeInfo{
|
||||
neInfoRepository: repository.NewNeInfo,
|
||||
neHostService: NewNeHost,
|
||||
neStateService: NewNEState,
|
||||
Para5GData: map[string]string{},
|
||||
}
|
||||
|
||||
@@ -31,6 +32,7 @@ var NewNeInfo = &NeInfo{
|
||||
type NeInfo struct {
|
||||
neInfoRepository *repository.NeInfo // 网元信息数据信息
|
||||
neHostService *NeHost // 网元主机连接服务
|
||||
neStateService *NEState // 网元状态服务
|
||||
Para5GData map[string]string
|
||||
}
|
||||
|
||||
@@ -127,10 +129,22 @@ func (r NeInfo) FindByRmuid(rmUid string) model.NeInfo {
|
||||
} else {
|
||||
neInfos := r.Find(neInfo, false, false)
|
||||
for _, v := range neInfos {
|
||||
key := fmt.Sprintf("%s:%s:%s", constants.CACHE_NE_INFO, strings.ToUpper(v.NeType), v.NeId)
|
||||
neType := strings.ToUpper(v.NeType)
|
||||
// 网元信息
|
||||
key := fmt.Sprintf("%s:%s:%s", constants.CACHE_NE_INFO, neType, v.NeId)
|
||||
redis.Del("", key)
|
||||
values, _ := json.Marshal(v)
|
||||
redis.Set("", key, string(values), 0)
|
||||
// 网元在线状态
|
||||
stateKey := fmt.Sprintf("%s:%s:%s_status", constants.CACHE_NE_INFO, neType, v.NeId)
|
||||
state, stateErr := neFetchlink.NeState(v)
|
||||
if stateErr != nil {
|
||||
redis.Del("", stateKey)
|
||||
} else {
|
||||
redis.Set("", stateKey, neInfo.RmUID, 0)
|
||||
r.neStateService.SaveState(state)
|
||||
}
|
||||
|
||||
if v.RmUID == rmUid {
|
||||
neInfo = v
|
||||
}
|
||||
@@ -177,11 +191,15 @@ func (r NeInfo) Find(ne model.NeInfo, bandStatus bool, bandHost bool) []model.Ne
|
||||
func (r NeInfo) bandNeStatus(arr *[]model.NeInfo) {
|
||||
for i := range *arr {
|
||||
v := (*arr)[i]
|
||||
result, err := neFetchlink.NeState(v)
|
||||
if err != nil {
|
||||
(*arr)[i].ServerState = map[string]any{
|
||||
"online": false,
|
||||
}
|
||||
state := r.neStateService.Last(v.NeType, v.NeId)
|
||||
result := r.neStateService.ParseState(v, state)
|
||||
|
||||
// 没状态标记,视为离线
|
||||
key := fmt.Sprintf("%s:%s:%s_status", constants.CACHE_NE_INFO, v.NeType, v.NeId)
|
||||
keyNum, err := redis.Has("", key)
|
||||
if keyNum == 0 || err != nil {
|
||||
result["online"] = false
|
||||
(*arr)[i].ServerState = result
|
||||
// 网元状态设置为离线
|
||||
if v.Status != 0 {
|
||||
v.Status = 0
|
||||
@@ -190,17 +208,23 @@ func (r NeInfo) bandNeStatus(arr *[]model.NeInfo) {
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
result["online"] = true
|
||||
(*arr)[i].ServerState = result
|
||||
// 网元状态设置为在线
|
||||
var status int64 = 1
|
||||
status := v.Status
|
||||
if status == 0 || status == 2 {
|
||||
// 下发网管配置信息给网元
|
||||
_, err := neFetchlink.NeConfigOMC(v)
|
||||
if err != nil {
|
||||
status = 2
|
||||
} else {
|
||||
// 网元状态设置为在线
|
||||
status = 1
|
||||
}
|
||||
}
|
||||
if parse.Boolean(result["standby"]) {
|
||||
status = 3
|
||||
}
|
||||
// 下发网管配置信息给网元
|
||||
if _, err = neFetchlink.NeConfigOMC(v); err != nil {
|
||||
status = 2
|
||||
}
|
||||
(*arr)[i].Status = status
|
||||
if v.Status != status {
|
||||
r.neInfoRepository.UpdateState(v.ID, status)
|
||||
|
||||
137
src/modules/network_element/service/ne_state.go
Normal file
137
src/modules/network_element/service/ne_state.go
Normal file
@@ -0,0 +1,137 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
"be.ems/src/modules/network_element/model"
|
||||
"be.ems/src/modules/network_element/repository"
|
||||
"github.com/tsmask/go-oam/framework/utils/parse"
|
||||
)
|
||||
|
||||
// 实例化数据层 NEState 结构体
|
||||
var NewNEState = &NEState{
|
||||
neStateRepository: repository.NewNEState,
|
||||
}
|
||||
|
||||
// NEState 网元状态记录表 服务层处理
|
||||
type NEState struct {
|
||||
neStateRepository *repository.NEState // 网元状态记录信息
|
||||
}
|
||||
|
||||
// FindByPage 根据条件分页查询
|
||||
func (r NEState) FindByPage(query model.NEStateQuery) ([]model.NEState, int64) {
|
||||
return r.neStateRepository.SelectByPage(query)
|
||||
}
|
||||
|
||||
// Insert 插入数据
|
||||
func (r NEState) Insert(item model.NEState) int64 {
|
||||
return r.neStateRepository.Insert(item)
|
||||
}
|
||||
|
||||
// DeleteByTime 删除数据
|
||||
func (r NEState) DeleteByTime(neType, neId string, ltTime int64) int64 {
|
||||
return r.neStateRepository.DeleteByTime(neType, neId, ltTime)
|
||||
}
|
||||
|
||||
// Last 查询最新状态
|
||||
func (r NEState) Last(neType, neId string) model.NEState {
|
||||
return r.neStateRepository.SelectByLast(neType, neId)
|
||||
}
|
||||
|
||||
// ParseState 解析状态数据
|
||||
func (r NEState) ParseState(neInfo model.NeInfo, state model.NEState) map[string]any {
|
||||
if state.ID == 0 {
|
||||
return map[string]any{}
|
||||
}
|
||||
return map[string]any{
|
||||
"neId": neInfo.NeId,
|
||||
"neName": neInfo.NeName,
|
||||
"neType": neInfo.NeType,
|
||||
"neIP": neInfo.IP,
|
||||
"standby": state.Standby,
|
||||
"version": state.NeVersion,
|
||||
"sn": state.SerialNum,
|
||||
"expire": state.ExpiryDate,
|
||||
"refreshTime": state.RefreshTime,
|
||||
"ueNumber": state.UENumber,
|
||||
"nbNumber": state.NbNumber,
|
||||
"hostname": state.HostName,
|
||||
"os": state.OS,
|
||||
"sysCpuUsage": state.SysCpuUsage,
|
||||
"sysMemUsage": state.SysMemUsage,
|
||||
"sysDiskUsage": state.SysDiskUsage,
|
||||
"nfCpuUsage": state.NfCpuUsage,
|
||||
"nfMemUsed": state.NfMemUsed,
|
||||
}
|
||||
}
|
||||
|
||||
// SaveState 网元直连返回的状态数据保存
|
||||
func (r NEState) SaveState(state map[string]any) model.NEState {
|
||||
// 网元CPU使用率
|
||||
var nfCpuUsage float64 = 0
|
||||
// CPU使用率
|
||||
var sysCpuUsage float64 = 0
|
||||
if state["cpu"] != nil {
|
||||
cpu := state["cpu"].(map[string]any)
|
||||
v := parse.Number(cpu["sysCpuUsage"])
|
||||
sysCpuUsage = float64(v) / 100
|
||||
nfv := parse.Number(cpu["nfCpuUsage"])
|
||||
nfCpuUsage = float64(nfv) / 100
|
||||
}
|
||||
|
||||
// 网元内存使用KB
|
||||
var nfMemUsed int64 = 0
|
||||
// 内存使用率
|
||||
var sysMemUsage float64 = 0
|
||||
if state["mem"] != nil {
|
||||
mem := state["mem"].(map[string]any)
|
||||
v := parse.Number(mem["sysMemUsage"])
|
||||
sysMemUsage = float64(v) / 100
|
||||
nfMemUsed = parse.Number(mem["nfUsedMem"])
|
||||
}
|
||||
|
||||
// 磁盘使用率
|
||||
var sysDiskUsage float64 = 0
|
||||
if state["disk"] != nil {
|
||||
mem := state["disk"].(map[string]any)
|
||||
disks := mem["partitionInfo"].([]any)
|
||||
sort.Slice(disks, func(i, j int) bool {
|
||||
iUsed := parse.Number(disks[i].(map[string]any)["used"])
|
||||
jUsed := parse.Number(disks[j].(map[string]any)["used"])
|
||||
return iUsed > jUsed
|
||||
})
|
||||
disk := disks[0].(map[string]any)
|
||||
total := parse.Number(disk["total"])
|
||||
used := parse.Number(disk["used"])
|
||||
sysDiskUsage = (float64(used) / float64(total)) * 100
|
||||
sysDiskUsage, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", sysDiskUsage), 64)
|
||||
}
|
||||
|
||||
// 插入网元状态记录
|
||||
neState := model.NEState{
|
||||
NeType: fmt.Sprint(state["neType"]),
|
||||
NeId: fmt.Sprint(state["neId"]),
|
||||
NeVersion: fmt.Sprint(state["version"]),
|
||||
Standby: parse.Number(state["standby"]),
|
||||
UENumber: parse.Number(state["ueNumber"]),
|
||||
NbNumber: parse.Number(state["nbNumber"]),
|
||||
SerialNum: fmt.Sprint(state["sn"]),
|
||||
ExpiryDate: fmt.Sprint(state["expire"]),
|
||||
HostName: fmt.Sprint(state["hostname"]),
|
||||
OS: fmt.Sprint(state["os"]),
|
||||
SysCpuUsage: sysCpuUsage,
|
||||
SysMemUsage: sysMemUsage,
|
||||
SysDiskUsage: sysDiskUsage,
|
||||
NfCpuUsage: nfCpuUsage,
|
||||
NfMemUsed: nfMemUsed,
|
||||
RefreshTime: parse.Number(state["refreshTime"]),
|
||||
}
|
||||
|
||||
insertId := r.neStateRepository.Insert(neState)
|
||||
if insertId > 0 {
|
||||
neState.ID = insertId
|
||||
}
|
||||
return neState
|
||||
}
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
|
||||
"be.ems/src/framework/ssh"
|
||||
"be.ems/src/framework/utils/file"
|
||||
neFetchlink "be.ems/src/modules/network_element/fetch_link"
|
||||
"be.ems/src/modules/network_element/model"
|
||||
"be.ems/src/modules/network_element/repository"
|
||||
)
|
||||
@@ -18,12 +17,14 @@ import (
|
||||
var NewNeVersion = &NeVersion{
|
||||
neVersionRepository: repository.NewNeVersion,
|
||||
neInfoService: NewNeInfo,
|
||||
neStateService: NewNEState,
|
||||
}
|
||||
|
||||
// NeVersion 网元版本信息 服务层处理
|
||||
type NeVersion struct {
|
||||
neVersionRepository *repository.NeVersion // 网元版本信息表
|
||||
neInfoService *NeInfo // 网元信息数据信息
|
||||
neStateService *NEState // 网元状态服务
|
||||
}
|
||||
|
||||
// FindByPage 分页查询列表数据
|
||||
@@ -54,29 +55,15 @@ func (r NeVersion) Find(neVersion model.NeVersion, checkVersion bool) []model.Ne
|
||||
func (r NeVersion) checkNeVersion(arr *[]model.NeVersion) {
|
||||
for i := range *arr {
|
||||
item := (*arr)[i]
|
||||
// 查询网元获取IP
|
||||
neInfo := r.neInfoService.FindByNeTypeAndNeID(item.NeType, item.NeId)
|
||||
if neInfo.NeId != item.NeId || neInfo.IP == "" {
|
||||
state := r.neStateService.Last(item.NeType, item.NeId)
|
||||
if state.RefreshTime <= 0 {
|
||||
continue
|
||||
}
|
||||
result, err := neFetchlink.NeState(neInfo)
|
||||
if err != nil {
|
||||
if state.NeVersion == item.Version {
|
||||
continue
|
||||
}
|
||||
if v, ok := result["version"]; ok && v != nil {
|
||||
ver := fmt.Sprint(v)
|
||||
if ver == item.Version {
|
||||
continue
|
||||
}
|
||||
// item.Name = "-"
|
||||
// item.Path = "-"
|
||||
item.Version = ver
|
||||
}
|
||||
if item.NeType != neInfo.NeType || item.NeId != neInfo.NeId {
|
||||
item.NeType = neInfo.NeType
|
||||
item.NeId = neInfo.NeId
|
||||
}
|
||||
r.Update(item)
|
||||
item.Version = state.NeVersion
|
||||
r.neVersionRepository.UpdateVersion(item.ID, item.Version)
|
||||
(*arr)[i] = item
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,10 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"be.ems/src/framework/constants"
|
||||
"be.ems/src/framework/database/redis"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/resp"
|
||||
neFetchlink "be.ems/src/modules/network_element/fetch_link"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
)
|
||||
|
||||
@@ -33,26 +34,21 @@ func GetNeState(requestID string, data any) ([]byte, error) {
|
||||
return nil, fmt.Errorf("no matching network element information found")
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
resData, err := neFetchlink.NeState(neInfo)
|
||||
if err != nil {
|
||||
resultByte, err := json.Marshal(resp.Ok(map[string]any{
|
||||
"requestId": requestID,
|
||||
"data": map[string]any{
|
||||
"online": false,
|
||||
"neId": neInfo.NeId,
|
||||
"neName": neInfo.NeName,
|
||||
"neType": neInfo.NeType,
|
||||
"neIP": neInfo.IP,
|
||||
},
|
||||
}))
|
||||
return resultByte, err
|
||||
state := neService.NewNEState.Last(neInfo.NeType, neInfo.NeId)
|
||||
result := neService.NewNEState.ParseState(neInfo, state)
|
||||
|
||||
// 没状态标记,视为离线
|
||||
key := fmt.Sprintf("%s:%s:%s_status", constants.CACHE_NE_INFO, neInfo.NeType, neInfo.NeId)
|
||||
keyNum, err := redis.Has("", key)
|
||||
if keyNum == 0 || err != nil {
|
||||
result["online"] = false
|
||||
} else {
|
||||
result["online"] = true
|
||||
}
|
||||
|
||||
resData["online"] = true
|
||||
resultByte, err := json.Marshal(resp.Ok(map[string]any{
|
||||
"requestId": requestID,
|
||||
"data": resData,
|
||||
"data": result,
|
||||
}))
|
||||
return resultByte, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user