Merge branch 'main-v2' into lite-ba
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -23,5 +23,5 @@ debug/
|
|||||||
main
|
main
|
||||||
|
|
||||||
# Build Output
|
# Build Output
|
||||||
local/*.sqlite
|
local/*.sqlite*
|
||||||
omc
|
omc
|
||||||
|
|||||||
14
CHANGELOG.md
14
CHANGELOG.md
@@ -1,5 +1,19 @@
|
|||||||
# 版本发布日志
|
# 版本发布日志
|
||||||
|
|
||||||
|
## 2.2510.3-20251018
|
||||||
|
|
||||||
|
- 优化 忽略本地调试所有sqlite文件
|
||||||
|
- 新增 添加退出信号监听功能,优雅关闭服务并输出相关信息
|
||||||
|
- 修复 sqlite模式改为wal支持并发写入临时日志
|
||||||
|
- 修复 修正删除文件路径构建方式,使用filepath.Join确保路径正确
|
||||||
|
- 优化 移除token过期日志信息输出
|
||||||
|
- 新增 网元参数配置数据支持版本区分功能,,适应mme版本配置
|
||||||
|
- 新增 使用systemctl脚本操作OMC自身
|
||||||
|
- 修复 自检告警附加信息错误最佳和触发消除操作
|
||||||
|
- 修复 数据列表搜索条件排序问题
|
||||||
|
- 修复 设置分布式锁超时1分钟解除,避免死锁
|
||||||
|
- 新增 备份网元Log文件到网管支持ftp转存
|
||||||
|
|
||||||
## 2.2510.2-20251011
|
## 2.2510.2-20251011
|
||||||
|
|
||||||
- 新增 导出udm-auth未加密数据
|
- 新增 导出udm-auth未加密数据
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -8,6 +8,8 @@ CREATE TABLE "ne_info" (
|
|||||||
"ne_id" text(32) NOT NULL,
|
"ne_id" text(32) NOT NULL,
|
||||||
"rm_uid" text(40),
|
"rm_uid" text(40),
|
||||||
"ne_name" text(64),
|
"ne_name" text(64),
|
||||||
|
"ne_version" text(12),
|
||||||
|
"schema" text(12),
|
||||||
"ip" text(128),
|
"ip" text(128),
|
||||||
"port" integer,
|
"port" integer,
|
||||||
"pv_flag" text(32),
|
"pv_flag" text(32),
|
||||||
|
|||||||
46
build/database/lite/upgrade/upg_ne_info.sql
Normal file
46
build/database/lite/upgrade/upg_ne_info.sql
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for ne_info
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS "ne_info";
|
||||||
|
CREATE TABLE "ne_info" (
|
||||||
|
"id" integer NOT NULL,
|
||||||
|
"ne_type" text(32) NOT NULL,
|
||||||
|
"ne_id" text(32) NOT NULL,
|
||||||
|
"rm_uid" text(40),
|
||||||
|
"ne_name" text(64),
|
||||||
|
"ne_version" text(12),
|
||||||
|
"schema" text(12),
|
||||||
|
"ip" text(128),
|
||||||
|
"port" integer(11),
|
||||||
|
"pv_flag" text(32),
|
||||||
|
"province" text(32),
|
||||||
|
"vendor_name" text(64),
|
||||||
|
"dn" text(255),
|
||||||
|
"ne_address" text(64),
|
||||||
|
"host_ids" text(64),
|
||||||
|
"status" integer(11),
|
||||||
|
"remark" text(255),
|
||||||
|
"create_by" text(50),
|
||||||
|
"create_time" integer(20),
|
||||||
|
"update_by" text(50),
|
||||||
|
"update_time" integer(20),
|
||||||
|
PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Indexes structure for table ne_info
|
||||||
|
-- ----------------------------
|
||||||
|
CREATE UNIQUE INDEX "ux_netype_neid"
|
||||||
|
ON "ne_info" (
|
||||||
|
"ne_type" ASC,
|
||||||
|
"ne_id" ASC
|
||||||
|
);
|
||||||
|
|
||||||
|
-- ADD COLUMN
|
||||||
|
ALTER TABLE "ne_info" ADD COLUMN "ne_version" text(12);
|
||||||
|
ALTER TABLE "ne_info" ADD COLUMN "schema" text(12);
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Records of ne_info
|
||||||
|
-- ----------------------------
|
||||||
|
UPDATE "ne_info" SET "ne_version" = '2', "schema" = 'http' WHERE "ne_version" IS NULL OR "schema" IS NULL;
|
||||||
File diff suppressed because one or more lines are too long
@@ -11,6 +11,8 @@ CREATE TABLE `ne_info` (
|
|||||||
`ne_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '网元ID',
|
`ne_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '网元ID',
|
||||||
`rm_uid` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '网元资源唯一标识',
|
`rm_uid` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '网元资源唯一标识',
|
||||||
`ne_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '网元名称',
|
`ne_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '网元名称',
|
||||||
|
`ne_version` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '2' COMMENT '网元版本',
|
||||||
|
`schema` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'http' COMMENT '网元模式 http/https',
|
||||||
`ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '网元服务IP',
|
`ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '网元服务IP',
|
||||||
`port` int DEFAULT '0' COMMENT '端口',
|
`port` int DEFAULT '0' COMMENT '端口',
|
||||||
`pv_flag` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'PNF' COMMENT '网元虚拟化标识 物理PNF 虚拟VNF',
|
`pv_flag` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'PNF' COMMENT '网元虚拟化标识 物理PNF 虚拟VNF',
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ CREATE TABLE IF NOT EXISTS `ne_info` (
|
|||||||
`ne_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '网元ID',
|
`ne_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '网元ID',
|
||||||
`rm_uid` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '网元资源唯一标识',
|
`rm_uid` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '网元资源唯一标识',
|
||||||
`ne_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '网元名称',
|
`ne_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '网元名称',
|
||||||
|
`ne_version` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '2' COMMENT '网元版本',
|
||||||
|
`schema` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'http' COMMENT '网元模式 http/https',
|
||||||
`ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '网元服务IP',
|
`ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '网元服务IP',
|
||||||
`port` int DEFAULT '0' COMMENT '端口',
|
`port` int DEFAULT '0' COMMENT '端口',
|
||||||
`pv_flag` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'PNF' COMMENT '网元虚拟化标识 物理PNF 虚拟VNF',
|
`pv_flag` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'PNF' COMMENT '网元虚拟化标识 物理PNF 虚拟VNF',
|
||||||
@@ -43,13 +45,15 @@ ALTER TABLE `ne_info` MODIFY COLUMN `vendor_name` varchar(64) CHARACTER SET utf8
|
|||||||
ALTER TABLE `ne_info` MODIFY COLUMN `dn` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '-' COMMENT '网络标识' AFTER `vendor_name`;
|
ALTER TABLE `ne_info` MODIFY COLUMN `dn` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '-' COMMENT '网络标识' AFTER `vendor_name`;
|
||||||
ALTER TABLE `ne_info` MODIFY COLUMN `host_ids` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '网元主机ID组 数据格式(ssh,telnet) UDM(ssh,telnet,redis) UPF(ssh,telnet,telnet)' AFTER `ne_address`;
|
ALTER TABLE `ne_info` MODIFY COLUMN `host_ids` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '网元主机ID组 数据格式(ssh,telnet) UDM(ssh,telnet,redis) UPF(ssh,telnet,telnet)' AFTER `ne_address`;
|
||||||
ALTER TABLE `ne_info` MODIFY COLUMN `status` int(11) NULL DEFAULT 0 COMMENT '网元状态 0离线 1在线 2配置待下发 3备用模式' AFTER `host_ids`;
|
ALTER TABLE `ne_info` MODIFY COLUMN `status` int(11) NULL DEFAULT 0 COMMENT '网元状态 0离线 1在线 2配置待下发 3备用模式' AFTER `host_ids`;
|
||||||
|
ALTER TABLE `ne_info` ADD COLUMN `ne_version` varchar(32) NULL DEFAULT '2' COMMENT '网元版本' AFTER `ne_name`;
|
||||||
|
ALTER TABLE `ne_info` ADD COLUMN `schema` varchar(12) NULL DEFAULT 'http' COMMENT '网元模式 http/https' AFTER `ne_version`;
|
||||||
ALTER TABLE `ne_info` COMMENT = '网元_基础信息表 关联对应版本、授权、主机';
|
ALTER TABLE `ne_info` COMMENT = '网元_基础信息表 关联对应版本、授权、主机';
|
||||||
ALTER TABLE `ne_info` MODIFY COLUMN `id` bigint(20) NOT NULL AUTO_INCREMENT;
|
ALTER TABLE `ne_info` MODIFY COLUMN `id` bigint(20) NOT NULL AUTO_INCREMENT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Data for ne_info
|
-- Data for ne_info
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
INSERT IGNORE INTO `ne_info` VALUES (1, 'OMC', '001', '4400HXOMC001', 'OMC_001', '127.0.0.1', 33030, 'PNF', 'AreaNet', '-', '-', '-', '1,2', 0, '', 'system', 1713928436971, '', 0);
|
UPDATE `ne_info` SET `ne_version` = '2', `schema` = 'http' WHERE `ne_version` IS NULL OR `schema` IS NULL;
|
||||||
|
|
||||||
SET FOREIGN_KEY_CHECKS=1;
|
SET FOREIGN_KEY_CHECKS=1;
|
||||||
|
|
||||||
|
|||||||
379
local/param/mme_2_param_config.yaml
Normal file
379
local/param/mme_2_param_config.yaml
Normal file
@@ -0,0 +1,379 @@
|
|||||||
|
mme:
|
||||||
|
system:
|
||||||
|
display: "System Config"
|
||||||
|
sort: 1
|
||||||
|
list:
|
||||||
|
- name: "mmeName"
|
||||||
|
type: "string"
|
||||||
|
value: "MME1"
|
||||||
|
filter: "0~32"
|
||||||
|
display: "MME Name"
|
||||||
|
- name: "networkName.full"
|
||||||
|
type: "string"
|
||||||
|
value: "EPC"
|
||||||
|
filter: "0~64"
|
||||||
|
display: "Full Network Name"
|
||||||
|
- name: "networkName.short"
|
||||||
|
type: "string"
|
||||||
|
value: "Next"
|
||||||
|
filter: "0~16"
|
||||||
|
display: "Short Network Name"
|
||||||
|
- name: "s1.mtu"
|
||||||
|
type: "int"
|
||||||
|
value: "1500"
|
||||||
|
access: "read-write"
|
||||||
|
filter: "576~9000"
|
||||||
|
display: "MTU"
|
||||||
|
comment: "Maximum Transmission Unit"
|
||||||
|
- name: "s1.address"
|
||||||
|
type: "string"
|
||||||
|
value: "192.168.8.220"
|
||||||
|
access: "read-write"
|
||||||
|
filter: "IP"
|
||||||
|
display: "S1 Local Address"
|
||||||
|
comment: "Local IP for S1 interface"
|
||||||
|
- name: "s6a.local.address"
|
||||||
|
type: "string"
|
||||||
|
value: "172.16.5.220"
|
||||||
|
access: "read-write"
|
||||||
|
filter: "IP"
|
||||||
|
display: "Local S6a IP"
|
||||||
|
comment: "Local IP for Diameter S6a"
|
||||||
|
- name: "s6a.local.host"
|
||||||
|
type: "string"
|
||||||
|
value: "mme.epc.mnc001.mcc001.3gppnetwork.org"
|
||||||
|
access: "read-write"
|
||||||
|
filter: "0~128"
|
||||||
|
display: "Local Hostname"
|
||||||
|
comment: "MME Diameter Host FQDN"
|
||||||
|
- name: "s6a.local.realm"
|
||||||
|
type: "string"
|
||||||
|
value: "epc.mnc001.mcc001.3gppnetwork.org"
|
||||||
|
access: "read-write"
|
||||||
|
filter: "0~128"
|
||||||
|
display: "Local Realm"
|
||||||
|
comment: "Diameter Realm"
|
||||||
|
- name: "s11.local.address"
|
||||||
|
type: "string"
|
||||||
|
value: "172.16.5.220"
|
||||||
|
access: "read-write"
|
||||||
|
filter: "IP"
|
||||||
|
display: "Local S11 IP"
|
||||||
|
- name: "n26.local.address"
|
||||||
|
type: "string"
|
||||||
|
value: "172.16.5.210"
|
||||||
|
access: "read-write"
|
||||||
|
filter: "IP"
|
||||||
|
display: "Local N26 IP"
|
||||||
|
- name: "t3402.value"
|
||||||
|
type: "string"
|
||||||
|
value: "12m"
|
||||||
|
filter: "1s~60m"
|
||||||
|
display: "T3402 Timer"
|
||||||
|
- name: "t3412.value"
|
||||||
|
type: "string"
|
||||||
|
value: "54m"
|
||||||
|
display: "T3412 Timer"
|
||||||
|
- name: "t3423.value"
|
||||||
|
type: "string"
|
||||||
|
value: "12m"
|
||||||
|
display: "T3423 Timer"
|
||||||
|
- name: "message.gtp.t3ResponseDuration"
|
||||||
|
type: "string"
|
||||||
|
value: "2s"
|
||||||
|
display: "GTP Response Timeout"
|
||||||
|
- name: "message.gtp.n3ResponseRcount"
|
||||||
|
type: "int"
|
||||||
|
value: "3"
|
||||||
|
display: "GTP Response Retries"
|
||||||
|
- name: "message.gtp.t3HoldingDuration"
|
||||||
|
type: "string"
|
||||||
|
value: "6s"
|
||||||
|
display: "GTP Holding Duration"
|
||||||
|
- name: "message.gtp.n3HoldingRcount"
|
||||||
|
type: "int"
|
||||||
|
value: "1"
|
||||||
|
display: "GTP Holding Retries"
|
||||||
|
- name: "message.s6a"
|
||||||
|
type: "string"
|
||||||
|
value: "3s"
|
||||||
|
display: "S6a Timeout"
|
||||||
|
- name: "handover.value"
|
||||||
|
type: "string"
|
||||||
|
value: "300ms"
|
||||||
|
display: "Handover Timeout"
|
||||||
|
- name: "s1Flex.instance"
|
||||||
|
type: "int"
|
||||||
|
value: "0"
|
||||||
|
access: "read-write"
|
||||||
|
filter: "0~2"
|
||||||
|
display: "mme instance id for s1 flex"
|
||||||
|
comment: "mme instance id for s1 flex"
|
||||||
|
- name: "redisDb.enable"
|
||||||
|
type: "bool"
|
||||||
|
value: "false"
|
||||||
|
access: "read-write"
|
||||||
|
filter: '{"0":"false","1":"true"}'
|
||||||
|
display: "Enable Redis"
|
||||||
|
comment: "true|false"
|
||||||
|
- name: "redisDb.netType"
|
||||||
|
type: "string"
|
||||||
|
value: "tcp"
|
||||||
|
access: "read-write"
|
||||||
|
filter: '{"tcp":"tcp"}'
|
||||||
|
display: "Network Type"
|
||||||
|
comment: "Network type for Redis (tcp)"
|
||||||
|
- name: "redisDb.addr"
|
||||||
|
type: "string"
|
||||||
|
value: "172.16.5.140:6379"
|
||||||
|
access: "read-write"
|
||||||
|
filter: "IP:Port"
|
||||||
|
display: "Redis Master Address"
|
||||||
|
comment: "IP:Port format"
|
||||||
|
- name: "redisDb.slaveAddrList"
|
||||||
|
type: "string"
|
||||||
|
value: "172.16.5.148:6379"
|
||||||
|
access: "read-write"
|
||||||
|
filter: "IP:Port"
|
||||||
|
display: "Redis Slave Addresses"
|
||||||
|
comment: "List of Redis slaves for replication"
|
||||||
|
- name: "redisDb.poolSize"
|
||||||
|
type: "int"
|
||||||
|
value: "10"
|
||||||
|
access: "read-write"
|
||||||
|
filter: "1~1000"
|
||||||
|
display: "Connection Pool Size"
|
||||||
|
comment: "Max Redis connection pool size"
|
||||||
|
- name: "relativeCapacity"
|
||||||
|
type: "int"
|
||||||
|
value: "255"
|
||||||
|
filter: "0~255"
|
||||||
|
display: "MME Relative Capacity"
|
||||||
|
comment: "Used for load balancing among MMEs"
|
||||||
|
- name: "logDir"
|
||||||
|
type: "string"
|
||||||
|
value: "/var/log/"
|
||||||
|
access: "read-write"
|
||||||
|
filter: "0~128"
|
||||||
|
display: "Log Directory"
|
||||||
|
comment: "Directory where log files will be stored"
|
||||||
|
- name: "logNum"
|
||||||
|
type: "int"
|
||||||
|
value: "10"
|
||||||
|
access: "read-write"
|
||||||
|
filter: "1~100"
|
||||||
|
display: "Log File Count"
|
||||||
|
comment: "Maximum number of log files to retain"
|
||||||
|
- name: "logSize"
|
||||||
|
type: "int"
|
||||||
|
value: "200"
|
||||||
|
access: "read-write"
|
||||||
|
filter: "1~10000"
|
||||||
|
display: "Log File Size (MB)"
|
||||||
|
comment: "Max size per log file"
|
||||||
|
- name: "logLevel"
|
||||||
|
type: "enum"
|
||||||
|
value: "debug"
|
||||||
|
access: "read-write"
|
||||||
|
filter: '{"debug":"debug","info":"info","warn":"warn","error":"error"}'
|
||||||
|
display: "Log Level"
|
||||||
|
comment: "debug|info|warn|error"
|
||||||
|
gummei:
|
||||||
|
display: "GUMMEI List"
|
||||||
|
sort: 3
|
||||||
|
array:
|
||||||
|
- name: "index"
|
||||||
|
type: "int"
|
||||||
|
value: "0"
|
||||||
|
access: "read"
|
||||||
|
filter: "0~15"
|
||||||
|
display: "Index"
|
||||||
|
comment: "0~15"
|
||||||
|
- name: "plmnId"
|
||||||
|
type: "regex"
|
||||||
|
value: "00101"
|
||||||
|
filter: "^[0-9]{5,6}$"
|
||||||
|
display: "PLMN ID"
|
||||||
|
- name: "mmeGid"
|
||||||
|
type: "int"
|
||||||
|
value: "2"
|
||||||
|
filter: "0~65535"
|
||||||
|
display: "MME Group ID"
|
||||||
|
- name: "mmeCode"
|
||||||
|
type: "int"
|
||||||
|
value: "1"
|
||||||
|
filter: "0~255"
|
||||||
|
display: "MME Code"
|
||||||
|
servedTai:
|
||||||
|
display: "TAI List"
|
||||||
|
sort: 4
|
||||||
|
array:
|
||||||
|
- name: "index"
|
||||||
|
type: "int"
|
||||||
|
value: "0"
|
||||||
|
access: "read"
|
||||||
|
filter: "0~15"
|
||||||
|
display: "Index"
|
||||||
|
comment: "0~15"
|
||||||
|
- name: "plmnId"
|
||||||
|
type: "regex"
|
||||||
|
value: "00101"
|
||||||
|
filter: "^[0-9]{5,6}$"
|
||||||
|
display: "PLMN ID"
|
||||||
|
- name: "tac"
|
||||||
|
type: "int"
|
||||||
|
value: "1"
|
||||||
|
filter: "0~65535"
|
||||||
|
display: "TAC"
|
||||||
|
s6a:
|
||||||
|
display: "HSS List"
|
||||||
|
sort: 5
|
||||||
|
array:
|
||||||
|
- name: "index"
|
||||||
|
type: "int"
|
||||||
|
value: "0"
|
||||||
|
access: "read"
|
||||||
|
filter: "0~15"
|
||||||
|
display: "Index"
|
||||||
|
comment: "0~15"
|
||||||
|
- name: "address"
|
||||||
|
type: "string"
|
||||||
|
value: "172.16.5.221"
|
||||||
|
filter: "IP"
|
||||||
|
display: "HSS Address"
|
||||||
|
- name: "priority"
|
||||||
|
type: "int"
|
||||||
|
value: "1"
|
||||||
|
filter: "1~10"
|
||||||
|
display: "Priority"
|
||||||
|
- name: "plmnId"
|
||||||
|
type: "string"
|
||||||
|
value: ["00101"]
|
||||||
|
filter: "^[0-9]{5,6}$"
|
||||||
|
display: "PLMN ID"
|
||||||
|
s11:
|
||||||
|
display: "SGW List"
|
||||||
|
sort: 9
|
||||||
|
array:
|
||||||
|
- name: "index"
|
||||||
|
type: "int"
|
||||||
|
value: "0"
|
||||||
|
access: "read"
|
||||||
|
filter: "0~15"
|
||||||
|
display: "Index"
|
||||||
|
comment: "0~15"
|
||||||
|
- name: "address"
|
||||||
|
type: "string"
|
||||||
|
value: "172.16.5.222"
|
||||||
|
filter: "IP"
|
||||||
|
display: "SGW Address"
|
||||||
|
- name: "priority"
|
||||||
|
type: "int"
|
||||||
|
value: "1"
|
||||||
|
filter: "1~10"
|
||||||
|
display: "Priority"
|
||||||
|
- name: "plmnId"
|
||||||
|
type: "string"
|
||||||
|
value: "00101"
|
||||||
|
filter: "^[0-9]{5,6}$"
|
||||||
|
display: "PLMN ID"
|
||||||
|
- name: "tac"
|
||||||
|
type: "int"
|
||||||
|
value: "1"
|
||||||
|
filter: "0~65535"
|
||||||
|
display: "TAC"
|
||||||
|
s5s8:
|
||||||
|
display: "PGW List"
|
||||||
|
sort: 11
|
||||||
|
array:
|
||||||
|
- name: "index"
|
||||||
|
type: "int"
|
||||||
|
value: "0"
|
||||||
|
access: "read"
|
||||||
|
filter: "0~15"
|
||||||
|
display: "Index"
|
||||||
|
comment: "0~15"
|
||||||
|
- name: "address"
|
||||||
|
type: "string"
|
||||||
|
value: "172.16.5.223"
|
||||||
|
filter: "IP"
|
||||||
|
display: "PGW Address"
|
||||||
|
- name: "priority"
|
||||||
|
type: "int"
|
||||||
|
value: "1"
|
||||||
|
filter: "1~10"
|
||||||
|
display: "Priority"
|
||||||
|
- name: "plmnId"
|
||||||
|
type: "string"
|
||||||
|
value: "00101"
|
||||||
|
filter: "^[0-9]{5,6}$"
|
||||||
|
display: "PLMN ID"
|
||||||
|
- name: "apn"
|
||||||
|
type: "string"
|
||||||
|
value: "internet"
|
||||||
|
filter: "0~128"
|
||||||
|
display: "APN"
|
||||||
|
n26:
|
||||||
|
display: "AMF List"
|
||||||
|
sort: 13
|
||||||
|
array:
|
||||||
|
- name: "index"
|
||||||
|
type: "int"
|
||||||
|
value: "0"
|
||||||
|
access: "read"
|
||||||
|
filter: "0~15"
|
||||||
|
display: "Index"
|
||||||
|
comment: "0~15"
|
||||||
|
- name: "address"
|
||||||
|
type: "string"
|
||||||
|
value: "172.16.5.224"
|
||||||
|
filter: "IP"
|
||||||
|
display: "AMF Address"
|
||||||
|
- name: "priority"
|
||||||
|
type: "int"
|
||||||
|
value: "1"
|
||||||
|
filter: "1~10"
|
||||||
|
display: "Priority"
|
||||||
|
- name: "plmnId"
|
||||||
|
type: "string"
|
||||||
|
value: "00101"
|
||||||
|
filter: "^[0-9]{5,6}$"
|
||||||
|
display: "PLMN ID"
|
||||||
|
- name: "tac"
|
||||||
|
type: "int"
|
||||||
|
value: "1"
|
||||||
|
filter: "0~65535"
|
||||||
|
display: "TAC"
|
||||||
|
enbList:
|
||||||
|
display: "Enb List Config"
|
||||||
|
sort: 19
|
||||||
|
visible: "hide"
|
||||||
|
array:
|
||||||
|
- name: "index"
|
||||||
|
type: "int"
|
||||||
|
value: "0"
|
||||||
|
access: "read-only"
|
||||||
|
filter: "0~128"
|
||||||
|
display: "Index"
|
||||||
|
comment: "0~128"
|
||||||
|
- name: "name"
|
||||||
|
type: "string"
|
||||||
|
value: ""
|
||||||
|
access: "read-write"
|
||||||
|
filter: "0~64"
|
||||||
|
display: "ENB Name"
|
||||||
|
comment: "text content length 0~64"
|
||||||
|
- name: "address"
|
||||||
|
type: "string"
|
||||||
|
value: ""
|
||||||
|
access: "read-write"
|
||||||
|
filter: "0~64"
|
||||||
|
display: "ENB Address"
|
||||||
|
comment: "text content length 0~64"
|
||||||
|
- name: "position"
|
||||||
|
type: "string"
|
||||||
|
value: ""
|
||||||
|
access: "read-write"
|
||||||
|
filter: "0~64"
|
||||||
|
display: "Position"
|
||||||
|
comment: "location description. Prohibition of spaces, length of text content 0-64"
|
||||||
@@ -611,6 +611,13 @@ smf:
|
|||||||
filter: ""
|
filter: ""
|
||||||
display: "Local IP"
|
display: "Local IP"
|
||||||
comment: ""
|
comment: ""
|
||||||
|
- name: "ntfyEnable"
|
||||||
|
type: "bool"
|
||||||
|
value: "false"
|
||||||
|
access: "read-write"
|
||||||
|
filter: ""
|
||||||
|
display: "DHCP Server Ntfy Enable"
|
||||||
|
comment: ""
|
||||||
dnnselectdhcpserver:
|
dnnselectdhcpserver:
|
||||||
display: "DNN Select DHCP Server"
|
display: "DNN Select DHCP Server"
|
||||||
sort: 23
|
sort: 23
|
||||||
@@ -644,7 +651,7 @@ smf:
|
|||||||
display: "DHCP Server IP"
|
display: "DHCP Server IP"
|
||||||
comment: "e.g. 192.168.1.1"
|
comment: "e.g. 192.168.1.1"
|
||||||
offlineChargingConfig:
|
offlineChargingConfig:
|
||||||
display: "Offline Charging Config"
|
display: "Charging Config"
|
||||||
sort: 25
|
sort: 25
|
||||||
list:
|
list:
|
||||||
- name: "cdrFileName"
|
- name: "cdrFileName"
|
||||||
@@ -682,12 +689,19 @@ smf:
|
|||||||
filter: "0~9999"
|
filter: "0~9999"
|
||||||
display: "CDR File Max Age"
|
display: "CDR File Max Age"
|
||||||
comment: "Days"
|
comment: "Days"
|
||||||
|
- name: "onlineCdrEnable"
|
||||||
|
type: "bool"
|
||||||
|
value: "false"
|
||||||
|
access: "read-write"
|
||||||
|
filter: ""
|
||||||
|
display: "Online Charging CDR Enable"
|
||||||
|
comment: ""
|
||||||
- name: "freeSubsCdrEnable"
|
- name: "freeSubsCdrEnable"
|
||||||
type: "bool"
|
type: "bool"
|
||||||
value: "false"
|
value: "false"
|
||||||
access: "read-write"
|
access: "read-write"
|
||||||
filter: ""
|
filter: ""
|
||||||
display: "Free Subscribers CDR Enable"
|
display: "Offline Charging CDR Enable"
|
||||||
comment: ""
|
comment: ""
|
||||||
- name: "timeThreshold"
|
- name: "timeThreshold"
|
||||||
type: "int"
|
type: "int"
|
||||||
|
|||||||
26
main.go
26
main.go
@@ -3,7 +3,10 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
"sync"
|
"sync"
|
||||||
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
_ "net/http/pprof"
|
_ "net/http/pprof"
|
||||||
@@ -146,6 +149,8 @@ func main() {
|
|||||||
src.ConfigurationInit()
|
src.ConfigurationInit()
|
||||||
|
|
||||||
app := src.AppEngine()
|
app := src.AppEngine()
|
||||||
|
fmt.Printf("OMC Service %s\n\n", config.Version)
|
||||||
|
|
||||||
src.DefeatConfig(app)
|
src.DefeatConfig(app)
|
||||||
|
|
||||||
loadGlobalPre(app)
|
loadGlobalPre(app)
|
||||||
@@ -156,11 +161,27 @@ func main() {
|
|||||||
|
|
||||||
loadServerWeb()
|
loadServerWeb()
|
||||||
|
|
||||||
|
stopSignal()
|
||||||
|
|
||||||
// 首次安装启动记录
|
// 首次安装启动记录
|
||||||
machine.Launch()
|
machine.Launch()
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// stopSignal 监听退出信号
|
||||||
|
func stopSignal() {
|
||||||
|
sigCh := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
<-sigCh // 等待退出信号
|
||||||
|
src.ConfigurationClose()
|
||||||
|
fmt.Println("\nStop Service... OK")
|
||||||
|
os.Exit(0)
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
// loadGlobalPre 全局预加载
|
// loadGlobalPre 全局预加载
|
||||||
func loadGlobalPre(app *gin.Engine) {
|
func loadGlobalPre(app *gin.Engine) {
|
||||||
// Swagger 接口文档
|
// Swagger 接口文档
|
||||||
@@ -185,6 +206,7 @@ func loadGlobalPre(app *gin.Engine) {
|
|||||||
go func(addr string) {
|
go func(addr string) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
for i := range maxRetries {
|
for i := range maxRetries {
|
||||||
|
fmt.Printf("pprof HTTP on %s\n", addr)
|
||||||
if err := http.ListenAndServe(addr, nil); err != nil {
|
if err := http.ListenAndServe(addr, nil); err != nil {
|
||||||
logger.Errorf("pprof run err:%v", err)
|
logger.Errorf("pprof run err:%v", err)
|
||||||
time.Sleep(retryInterval) // 重试间隔时间
|
time.Sleep(retryInterval) // 重试间隔时间
|
||||||
@@ -220,6 +242,7 @@ func loadServerRoute(app *gin.Engine) {
|
|||||||
go func(addr string, certFile string, keyFile string) {
|
go func(addr string, certFile string, keyFile string) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
for i := range maxRetries {
|
for i := range maxRetries {
|
||||||
|
fmt.Printf("API HTTPS on %s\n", addr)
|
||||||
if err := app.RunTLS(addr, certFile, keyFile); err != nil {
|
if err := app.RunTLS(addr, certFile, keyFile); err != nil {
|
||||||
logger.Errorf("routeServer run tls err:%v", err)
|
logger.Errorf("routeServer run tls err:%v", err)
|
||||||
time.Sleep(retryInterval) // 重试间隔时间
|
time.Sleep(retryInterval) // 重试间隔时间
|
||||||
@@ -233,6 +256,7 @@ func loadServerRoute(app *gin.Engine) {
|
|||||||
go func(addr string) {
|
go func(addr string) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
for i := range maxRetries {
|
for i := range maxRetries {
|
||||||
|
fmt.Printf("API HTTP on %s\n", addr)
|
||||||
if err := app.Run(addr); err != nil {
|
if err := app.Run(addr); err != nil {
|
||||||
logger.Errorf("routeServer run err:%v", err)
|
logger.Errorf("routeServer run err:%v", err)
|
||||||
time.Sleep(retryInterval) // 重试间隔时间
|
time.Sleep(retryInterval) // 重试间隔时间
|
||||||
@@ -286,6 +310,7 @@ func loadServerWeb() {
|
|||||||
go func(addr string, certFile string, keyFile string) {
|
go func(addr string, certFile string, keyFile string) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
for i := range maxRetries {
|
for i := range maxRetries {
|
||||||
|
fmt.Printf("WEB HTTPS on %s\n", addr)
|
||||||
if err := web.RunTLS(addr, certFile, keyFile); err != nil {
|
if err := web.RunTLS(addr, certFile, keyFile); err != nil {
|
||||||
logger.Errorf("webServer run tls err:%v", err)
|
logger.Errorf("webServer run tls err:%v", err)
|
||||||
time.Sleep(retryInterval) // 重试间隔时间
|
time.Sleep(retryInterval) // 重试间隔时间
|
||||||
@@ -302,6 +327,7 @@ func loadServerWeb() {
|
|||||||
go func(addr string) {
|
go func(addr string) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
for i := range maxRetries {
|
for i := range maxRetries {
|
||||||
|
fmt.Printf("WEB HTTP on %s\n", addr)
|
||||||
if err := web.Run(addr); err != nil {
|
if err := web.Run(addr); err != nil {
|
||||||
logger.Errorf("webServer run err:%v", err)
|
logger.Errorf("webServer run err:%v", err)
|
||||||
time.Sleep(retryInterval) // 重试间隔时间
|
time.Sleep(retryInterval) // 重试间隔时间
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/glebarez/sqlite"
|
"github.com/glebarez/sqlite"
|
||||||
@@ -36,7 +37,15 @@ func loadDialect() map[string]dialectInfo {
|
|||||||
// 数据库类型对应的数据库连接
|
// 数据库类型对应的数据库连接
|
||||||
switch item["type"] {
|
switch item["type"] {
|
||||||
case "sqlite":
|
case "sqlite":
|
||||||
dsn := fmt.Sprint(item["database"])
|
pragmas := []string{
|
||||||
|
"cache=shared", // Enable shared cache
|
||||||
|
"_pragma=journal_mode(WAL)", // Enable WAL mode
|
||||||
|
"_pragma=busy_timeout(5000)", // Set busy timeout 抛出 SQLITE_BUSY 错误 默认0立即,设置等待 5 秒(5000 毫秒)
|
||||||
|
"_pragma=synchronous(NORMAL)", // Set synchronous mode
|
||||||
|
"_pragma=wal_autocheckpoint(5000)", // Set WAL auto-checkpoint threshold 设置较大的自动检查点阈值
|
||||||
|
"_pragma=mmap_size(67108864)", // Set mmap size 内存映射 I/O 最大字节数为 64MB
|
||||||
|
}
|
||||||
|
dsn := fmt.Sprintf("%s?%s", item["database"], strings.Join(pragmas, "&"))
|
||||||
dialects[key] = dialectInfo{
|
dialects[key] = dialectInfo{
|
||||||
dialectic: sqlite.Open(dsn),
|
dialectic: sqlite.Open(dsn),
|
||||||
logging: parse.Boolean(item["logging"]),
|
logging: parse.Boolean(item["logging"]),
|
||||||
|
|||||||
@@ -14,12 +14,12 @@ import (
|
|||||||
|
|
||||||
// ImportSQL 导入SQL
|
// ImportSQL 导入SQL
|
||||||
func ImportSQL() {
|
func ImportSQL() {
|
||||||
sqlPath := config.Get("sqlPath").(string)
|
sqlPath, sqlPathOk := config.Get("sqlPath").(string)
|
||||||
if sqlPath == "" {
|
if !sqlPathOk || sqlPath == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sqlSource := config.Get("sqlSource").(string)
|
sqlSource, sqlSourceOk := config.Get("sqlSource").(string)
|
||||||
if sqlSource == "" {
|
if !sqlSourceOk || sqlSource == "" {
|
||||||
sqlSource = config.Get("database.defaultDataSourceName").(string)
|
sqlSource = config.Get("database.defaultDataSourceName").(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,6 +61,7 @@ func ImportSQL() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// log.Println("process success")
|
// log.Println("process success")
|
||||||
|
Close()
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +119,6 @@ func processSQLFile(db *gorm.DB, filePath string) {
|
|||||||
} else if strings.Contains(errorStr, "doesn't match") {
|
} else if strings.Contains(errorStr, "doesn't match") {
|
||||||
// 忽略列数不匹配错误
|
// 忽略列数不匹配错误
|
||||||
// Error 1136 (21S01): Column count doesn't match value count at row 1
|
// Error 1136 (21S01): Column count doesn't match value count at row 1
|
||||||
log.Println(err.Error())
|
|
||||||
} else {
|
} else {
|
||||||
// 其他错误终止程序
|
// 其他错误终止程序
|
||||||
log.Fatalln(errorStr)
|
log.Fatalln(errorStr)
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import (
|
|||||||
"be.ems/src/framework/config"
|
"be.ems/src/framework/config"
|
||||||
"be.ems/src/framework/constants"
|
"be.ems/src/framework/constants"
|
||||||
"be.ems/src/framework/database/redis"
|
"be.ems/src/framework/database/redis"
|
||||||
"be.ems/src/framework/logger"
|
|
||||||
"be.ems/src/framework/utils/parse"
|
"be.ems/src/framework/utils/parse"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -58,7 +57,6 @@ func UserTokenCreate(userId int64, deviceFingerprint, tokenType string) (string,
|
|||||||
|
|
||||||
tokenStr, err := jwtToken.SignedString([]byte(secret))
|
tokenStr, err := jwtToken.SignedString([]byte(secret))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Infof("jwt sign err : %v", err)
|
|
||||||
return "", 0
|
return "", 0
|
||||||
}
|
}
|
||||||
expSeconds := int64(exp.Sub(now).Seconds())
|
expSeconds := int64(exp.Sub(now).Seconds())
|
||||||
@@ -83,7 +81,6 @@ func UserTokenVerify(tokenStr string, tokenType string) (jwt.MapClaims, error) {
|
|||||||
return nil, jwt.ErrSignatureInvalid
|
return nil, jwt.ErrSignatureInvalid
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("Token Verify Err: %v", err)
|
|
||||||
return nil, fmt.Errorf("token invalid")
|
return nil, fmt.Errorf("token invalid")
|
||||||
}
|
}
|
||||||
// 如果解析负荷成功并通过签名校验
|
// 如果解析负荷成功并通过签名校验
|
||||||
@@ -98,7 +95,6 @@ func UserTokenVerify(tokenStr string, tokenType string) (jwt.MapClaims, error) {
|
|||||||
func UserInfoRemove(tokenStr string) (string, error) {
|
func UserInfoRemove(tokenStr string) (string, error) {
|
||||||
claims, err := UserTokenVerify(tokenStr, "access")
|
claims, err := UserTokenVerify(tokenStr, "access")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("token verify err %v", err)
|
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
info := UserInfoGet(claims)
|
info := UserInfoGet(claims)
|
||||||
@@ -165,7 +161,6 @@ func UserInfoGet(claims jwt.MapClaims) UserInfo {
|
|||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal([]byte(infoStr), &info); err != nil {
|
if err := json.Unmarshal([]byte(infoStr), &info); err != nil {
|
||||||
logger.Errorf("info json err : %v", err)
|
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ func (s *DeleteNeConfigBackupProcessor) Execute(data any) (any, error) {
|
|||||||
// deleteFile 删除本地文件
|
// deleteFile 删除本地文件
|
||||||
func (s DeleteNeConfigBackupProcessor) deleteFile(neType, neId string, oldFileDate time.Time) {
|
func (s DeleteNeConfigBackupProcessor) deleteFile(neType, neId string, oldFileDate time.Time) {
|
||||||
neTypeLower := strings.ToLower(neType)
|
neTypeLower := strings.ToLower(neType)
|
||||||
localPath := fmt.Sprintf("/usr/local/omc/backup/ne_config/%s/%s ", neTypeLower, neId)
|
localPath := filepath.Join("/usr/local/omc/backup/ne_config", neTypeLower, neId)
|
||||||
files, err := os.ReadDir(localPath)
|
files, err := os.ReadDir(localPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("logger Remove ne_config File ReadDir err: %v", err.Error())
|
logger.Errorf("logger Remove ne_config File ReadDir err: %v", err.Error())
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package ne_alarm_state_check
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/tsmask/go-oam"
|
"github.com/tsmask/go-oam"
|
||||||
@@ -20,12 +21,16 @@ import (
|
|||||||
var NewProcessor = &NeAlarmStateCheckProcessor{
|
var NewProcessor = &NeAlarmStateCheckProcessor{
|
||||||
neInfoService: neService.NewNeInfo,
|
neInfoService: neService.NewNeInfo,
|
||||||
count: 0,
|
count: 0,
|
||||||
|
triggerMax: 3,
|
||||||
|
triggerCount: sync.Map{},
|
||||||
}
|
}
|
||||||
|
|
||||||
// NeAlarmStateCheckProcessor 网元告警状态检查
|
// NeAlarmStateCheckProcessor 网元告警状态检查
|
||||||
type NeAlarmStateCheckProcessor struct {
|
type NeAlarmStateCheckProcessor struct {
|
||||||
neInfoService *neService.NeInfo // 网元信息服务
|
neInfoService *neService.NeInfo // 网元信息服务
|
||||||
count int // 执行次数
|
count int // 执行次数
|
||||||
|
triggerMax int64 // 阈值:连续触发次数大于该值才会产生告警
|
||||||
|
triggerCount sync.Map // 阈值连续触发次数,存储每个事件的触发记录
|
||||||
}
|
}
|
||||||
|
|
||||||
// alarmParams 告警参数
|
// alarmParams 告警参数
|
||||||
@@ -73,14 +78,35 @@ func (s *NeAlarmStateCheckProcessor) Execute(data any) (any, error) {
|
|||||||
|
|
||||||
// 网元在线状态
|
// 网元在线状态
|
||||||
isOnline := parse.Boolean(neInfo.ServerState["online"])
|
isOnline := parse.Boolean(neInfo.ServerState["online"])
|
||||||
|
|
||||||
|
// 告警状态
|
||||||
|
alarmStatus := oam.ALARM_STATUS_CLEAR
|
||||||
|
if !isOnline {
|
||||||
|
// 重置连续触发次数, 超过阈值才会清除告警
|
||||||
|
onlineKey := "ONLINE:" + neInfo.RmUID
|
||||||
|
if v, ok := s.triggerCount.Load(onlineKey); ok {
|
||||||
|
count := parse.Number(v)
|
||||||
|
if count < s.triggerMax {
|
||||||
|
s.triggerCount.Store(onlineKey, count+1)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
s.triggerCount.Delete(onlineKey)
|
||||||
|
} else {
|
||||||
|
s.triggerCount.Store(onlineKey, 0)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
alarmStatus = oam.ALARM_STATUS_ACTIVE
|
||||||
|
}
|
||||||
|
// 附加信息
|
||||||
|
addInfo := params.AddInfo
|
||||||
|
if addInfo != "" {
|
||||||
|
addInfo = fmt.Sprintf("%s, NE Connect Failed %s:%d", addInfo, neInfo.IP, neInfo.Port)
|
||||||
|
} else {
|
||||||
|
addInfo = fmt.Sprintf("NE Connect Failed %s:%d", neInfo.IP, neInfo.Port)
|
||||||
|
}
|
||||||
// 告警ID
|
// 告警ID
|
||||||
params.AlarmId = fmt.Sprintf("%d%d", constants.ALARM_STATE_CHECK, neInfo.CreateTime)
|
params.AlarmId = fmt.Sprintf("%d%d", constants.ALARM_STATE_CHECK, neInfo.CreateTime)
|
||||||
|
|
||||||
// 告警状态
|
|
||||||
alarmStatus := oam.ALARM_STATUS_ACTIVE
|
|
||||||
if isOnline {
|
|
||||||
alarmStatus = oam.ALARM_STATUS_CLEAR
|
|
||||||
}
|
|
||||||
// 创建告警
|
// 创建告警
|
||||||
alarm := oam.Alarm{
|
alarm := oam.Alarm{
|
||||||
NeUid: neInfo.RmUID, // 网元唯一标识
|
NeUid: neInfo.RmUID, // 网元唯一标识
|
||||||
@@ -93,7 +119,7 @@ func (s *NeAlarmStateCheckProcessor) Execute(data any) (any, error) {
|
|||||||
AlarmStatus: alarmStatus, // 告警状态
|
AlarmStatus: alarmStatus, // 告警状态
|
||||||
SpecificProblem: params.SpecificProblem, // 告警问题原因
|
SpecificProblem: params.SpecificProblem, // 告警问题原因
|
||||||
SpecificProblemID: params.SpecificProblemID, // 告警问题原因ID
|
SpecificProblemID: params.SpecificProblemID, // 告警问题原因ID
|
||||||
AddInfo: params.AddInfo, // 告警辅助信息
|
AddInfo: addInfo, // 告警辅助信息
|
||||||
LocationInfo: "NE State: Heartbeat", // 告警定位信息
|
LocationInfo: "NE State: Heartbeat", // 告警定位信息
|
||||||
}
|
}
|
||||||
if err = oamService.NewAlarm.Resolve(alarm); err == nil {
|
if err = oamService.NewAlarm.Resolve(alarm); err == nil {
|
||||||
|
|||||||
@@ -25,17 +25,13 @@ import (
|
|||||||
wsService "be.ems/src/modules/ws/service"
|
wsService "be.ems/src/modules/ws/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
triggerMax int64 = 3 // 阈值:连续触发次数大于该值才会产生告警
|
|
||||||
triggerCount sync.Map // 阈值连续触发次数,存储每个事件的触发记录
|
|
||||||
triggerWindow time.Duration = 30 * time.Second // 事件触发的时间窗口
|
|
||||||
)
|
|
||||||
|
|
||||||
var NewProcessor = &NeAlarmStateCheckCMDProcessor{
|
var NewProcessor = &NeAlarmStateCheckCMDProcessor{
|
||||||
neInfoService: neService.NewNeInfo,
|
neInfoService: neService.NewNeInfo,
|
||||||
neStateService: neDataService.NewNEState,
|
neStateService: neDataService.NewNEState,
|
||||||
wsSendService: wsService.NewWSSend,
|
wsSendService: wsService.NewWSSend,
|
||||||
count: 0,
|
count: 0,
|
||||||
|
triggerMax: 3,
|
||||||
|
triggerCount: sync.Map{},
|
||||||
}
|
}
|
||||||
|
|
||||||
// NeAlarmStateCheckCMDProcessor 网元告警内存/CPU/磁盘检查
|
// NeAlarmStateCheckCMDProcessor 网元告警内存/CPU/磁盘检查
|
||||||
@@ -44,6 +40,8 @@ type NeAlarmStateCheckCMDProcessor struct {
|
|||||||
neStateService *neDataService.NEState // 网元状态信息服务
|
neStateService *neDataService.NEState // 网元状态信息服务
|
||||||
wsSendService *wsService.WSSend // ws发送服务
|
wsSendService *wsService.WSSend // ws发送服务
|
||||||
count int // 执行次数
|
count int // 执行次数
|
||||||
|
triggerMax int64 // 阈值:连续触发次数大于该值才会产生告警
|
||||||
|
triggerCount sync.Map // 阈值连续触发次数,存储每个事件的触发记录
|
||||||
}
|
}
|
||||||
|
|
||||||
// alarmParams 告警参数
|
// alarmParams 告警参数
|
||||||
@@ -124,53 +122,61 @@ func (s *NeAlarmStateCheckCMDProcessor) Execute(data any) (any, error) {
|
|||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
if len(warnMsg) > 0 {
|
if len(warnMsg) > 0 {
|
||||||
currentTime := time.Now()
|
var count int64
|
||||||
validTimes := []time.Time{}
|
if v, ok := s.triggerCount.Load(neInfo.RmUID); ok {
|
||||||
if v, ok := triggerCount.Load(neInfo.RmUID); ok {
|
count = parse.Number(v)
|
||||||
times := v.([]time.Time)
|
s.triggerCount.Store(neInfo.RmUID, count+1)
|
||||||
// 清理过期的记录:10秒前的触发记录不再计入
|
|
||||||
for _, t := range times {
|
|
||||||
if currentTime.Sub(t) <= triggerWindow {
|
|
||||||
validTimes = append(validTimes, t)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
validTimes = append(validTimes, currentTime)
|
|
||||||
triggerCount.Store(neInfo.RmUID, validTimes)
|
|
||||||
} else {
|
} else {
|
||||||
// 事件第一次触发,初始化记录
|
s.triggerCount.Store(neInfo.RmUID, 0)
|
||||||
validTimes = append(validTimes, currentTime)
|
|
||||||
triggerCount.Store(neInfo.RmUID, validTimes)
|
|
||||||
}
|
}
|
||||||
if int64(len(validTimes)) >= triggerMax {
|
if count >= s.triggerMax {
|
||||||
|
s.triggerCount.Delete("CLEAR:" + neInfo.RmUID)
|
||||||
|
s.triggerCount.Delete(neInfo.RmUID)
|
||||||
err = fmt.Errorf("greater than %s", strings.Join(warnMsg, ", "))
|
err = fmt.Errorf("greater than %s", strings.Join(warnMsg, ", "))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查状态连续触发
|
// 告警状态
|
||||||
|
alarmStatus := oam.ALARM_STATUS_ACTIVE
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
// 重置连续触发次数, 超过阈值才会清除告警
|
||||||
|
clearKey := "CLEAR:" + neInfo.RmUID
|
||||||
|
if v, ok := s.triggerCount.Load(clearKey); ok {
|
||||||
|
count := parse.Number(v)
|
||||||
|
if count < s.triggerMax {
|
||||||
|
s.triggerCount.Store(clearKey, count+1)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
s.triggerCount.Delete(clearKey)
|
||||||
|
s.triggerCount.Delete(neInfo.RmUID)
|
||||||
|
} else {
|
||||||
|
s.triggerCount.Store(clearKey, 0)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
alarmStatus = oam.ALARM_STATUS_CLEAR
|
||||||
|
}
|
||||||
|
// 附加信息
|
||||||
addInfo := params.AddInfo
|
addInfo := params.AddInfo
|
||||||
|
if err != nil {
|
||||||
if addInfo != "" {
|
if addInfo != "" {
|
||||||
addInfo = addInfo + ", " + err.Error()
|
addInfo = addInfo + ", " + err.Error()
|
||||||
} else {
|
} else {
|
||||||
addInfo = err.Error()
|
addInfo = err.Error()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// 事件产生时间
|
|
||||||
alarmTime := time.Now().UnixMilli()
|
|
||||||
// 告警ID
|
// 告警ID
|
||||||
params.AlarmId = fmt.Sprintf("%d%d", constants.ALARM_CMD_CHECK, alarmTime)
|
params.AlarmId = fmt.Sprintf("%d%d", constants.ALARM_CMD_CHECK, neInfo.CreateTime)
|
||||||
|
|
||||||
// 创建告警
|
// 创建告警
|
||||||
alarm := oam.Alarm{
|
alarm := oam.Alarm{
|
||||||
NeUid: neInfo.RmUID, // 网元唯一标识
|
NeUid: neInfo.RmUID, // 网元唯一标识
|
||||||
AlarmTime: alarmTime, // 事件产生时间
|
AlarmTime: time.Now().UnixMilli(), // 事件产生时间
|
||||||
AlarmId: params.AlarmId, // 告警ID 唯一,清除时对应
|
AlarmId: params.AlarmId, // 告警ID 唯一,清除时对应
|
||||||
AlarmCode: constants.ALARM_CMD_CHECK, // 告警状态码
|
AlarmCode: constants.ALARM_CMD_CHECK, // 告警状态码
|
||||||
AlarmType: params.AlarmType, // 告警类型
|
AlarmType: params.AlarmType, // 告警类型
|
||||||
AlarmTitle: params.AlarmTitle, // 告警标题
|
AlarmTitle: params.AlarmTitle, // 告警标题
|
||||||
PerceivedSeverity: params.OrigSeverity, // 告警级别
|
PerceivedSeverity: params.OrigSeverity, // 告警级别
|
||||||
AlarmStatus: oam.ALARM_STATUS_ACTIVE, // 告警状态
|
AlarmStatus: alarmStatus, // 告警状态
|
||||||
SpecificProblem: params.SpecificProblem, // 告警问题原因
|
SpecificProblem: params.SpecificProblem, // 告警问题原因
|
||||||
SpecificProblemID: params.SpecificProblemID, // 告警问题原因ID
|
SpecificProblemID: params.SpecificProblemID, // 告警问题原因ID
|
||||||
AddInfo: addInfo, // 告警辅助信息
|
AddInfo: addInfo, // 告警辅助信息
|
||||||
@@ -179,7 +185,6 @@ func (s *NeAlarmStateCheckCMDProcessor) Execute(data any) (any, error) {
|
|||||||
if err = oamService.NewAlarm.Resolve(alarm); err == nil {
|
if err = oamService.NewAlarm.Resolve(alarm); err == nil {
|
||||||
result[neInfo.RmUID] = "cmd alarm"
|
result[neInfo.RmUID] = "cmd alarm"
|
||||||
}
|
}
|
||||||
triggerCount.Delete(neInfo.RmUID)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 返回结果,用于记录执行结果
|
// 返回结果,用于记录执行结果
|
||||||
@@ -187,7 +192,7 @@ func (s *NeAlarmStateCheckCMDProcessor) Execute(data any) (any, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// serverState 网元状态记录
|
// serverState 网元状态记录
|
||||||
func (s NeAlarmStateCheckCMDProcessor) serverState(state map[string]any) (float64, float64, float64) {
|
func (s *NeAlarmStateCheckCMDProcessor) serverState(state map[string]any) (float64, float64, float64) {
|
||||||
// 网元CPU使用率
|
// 网元CPU使用率
|
||||||
var nfCpuUsage float64 = 0
|
var nfCpuUsage float64 = 0
|
||||||
// CPU使用率
|
// CPU使用率
|
||||||
|
|||||||
@@ -85,18 +85,23 @@ func (s *NeAlarmStateCheckLicenseProcessor) Execute(data any) (any, error) {
|
|||||||
|
|
||||||
// 检查状态
|
// 检查状态
|
||||||
err := s.cheackState(neInfo.ServerState, params.DayLt)
|
err := s.cheackState(neInfo.ServerState, params.DayLt)
|
||||||
if err == nil {
|
// 告警状态
|
||||||
continue
|
alarmStatus := oam.ALARM_STATUS_ACTIVE
|
||||||
|
if err == nil { // 检查状态连续触发
|
||||||
|
alarmStatus = oam.ALARM_STATUS_CLEAR
|
||||||
}
|
}
|
||||||
|
// 附加信息
|
||||||
addInfo := params.AddInfo
|
addInfo := params.AddInfo
|
||||||
|
if err != nil {
|
||||||
if addInfo != "" {
|
if addInfo != "" {
|
||||||
addInfo = addInfo + ", " + err.Error()
|
addInfo = addInfo + ", " + err.Error()
|
||||||
} else {
|
} else {
|
||||||
addInfo = err.Error()
|
addInfo = err.Error()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// 告警ID
|
// 告警ID
|
||||||
params.AlarmId = fmt.Sprintf("%d%d", constants.ALARM_LICENSE_CHECK, neInfo.CreateTime)
|
params.AlarmId = fmt.Sprintf("%d%d", constants.ALARM_LICENSE_CHECK, neInfo.CreateTime)
|
||||||
|
|
||||||
// 创建告警
|
// 创建告警
|
||||||
alarm := oam.Alarm{
|
alarm := oam.Alarm{
|
||||||
NeUid: neInfo.RmUID, // 网元唯一标识
|
NeUid: neInfo.RmUID, // 网元唯一标识
|
||||||
@@ -106,7 +111,7 @@ func (s *NeAlarmStateCheckLicenseProcessor) Execute(data any) (any, error) {
|
|||||||
AlarmType: params.AlarmType, // 告警类型
|
AlarmType: params.AlarmType, // 告警类型
|
||||||
AlarmTitle: params.AlarmTitle, // 告警标题
|
AlarmTitle: params.AlarmTitle, // 告警标题
|
||||||
PerceivedSeverity: params.OrigSeverity, // 告警级别
|
PerceivedSeverity: params.OrigSeverity, // 告警级别
|
||||||
AlarmStatus: oam.ALARM_STATUS_ACTIVE, // 告警状态
|
AlarmStatus: alarmStatus, // 告警状态
|
||||||
SpecificProblem: params.SpecificProblem, // 告警问题原因
|
SpecificProblem: params.SpecificProblem, // 告警问题原因
|
||||||
SpecificProblemID: params.SpecificProblemID, // 告警问题原因ID
|
SpecificProblemID: params.SpecificProblemID, // 告警问题原因ID
|
||||||
AddInfo: addInfo, // 告警辅助信息
|
AddInfo: addInfo, // 告警辅助信息
|
||||||
|
|||||||
@@ -164,18 +164,28 @@ func (s NeConfigController) Remove(c *gin.Context) {
|
|||||||
// @Accept json
|
// @Accept json
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Param neType path string true "NE Type" Enums(IMS,AMF,AUSF,UDM,SMF,PCF,NSSF,NRF,UPF,MME,CBC,OMC,SGWC,SMSC)
|
// @Param neType path string true "NE Type" Enums(IMS,AMF,AUSF,UDM,SMF,PCF,NSSF,NRF,UPF,MME,CBC,OMC,SGWC,SMSC)
|
||||||
|
// @Param neId query string true "NE ID" default(001)
|
||||||
// @Success 200 {object} object "Response Results"
|
// @Success 200 {object} object "Response Results"
|
||||||
// @Security TokenAuth
|
// @Security TokenAuth
|
||||||
// @Summary Network Element Parameter Configuration Available Attribute Values List Specify Network Element Type All Unpaged
|
// @Summary Network Element Parameter Configuration Available Attribute Values List Specify Network Element Type All Unpaged
|
||||||
// @Description Network Element Parameter Configuration Available Attribute Values List Specify Network Element Type All Unpaged
|
// @Description Network Element Parameter Configuration Available Attribute Values List Specify Network Element Type All Unpaged
|
||||||
// @Router /ne/config/list/{neType} [get]
|
// @Router /ne/config/list/{neType} [get]
|
||||||
func (s NeConfigController) ListByNeType(c *gin.Context) {
|
func (s NeConfigController) ListByNeType(c *gin.Context) {
|
||||||
|
language := reqctx.AcceptLanguage(c)
|
||||||
|
neId := c.DefaultQuery("neId", "001")
|
||||||
neType := c.Param("neType")
|
neType := c.Param("neType")
|
||||||
if neType == "" {
|
if neType == "" {
|
||||||
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: neType is empty"))
|
c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: neType is empty"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
data := s.neConfigService.FindByNeType(neType)
|
|
||||||
|
neInfo := s.neInfoService.FindByNeTypeAndNeID(neType, neId)
|
||||||
|
if neInfo.NeId != neId || neInfo.IP == "" {
|
||||||
|
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
data := s.neConfigService.FindByNeType(neInfo.NeType, neInfo.NeVersion)
|
||||||
c.JSON(200, resp.OkData(data))
|
c.JSON(200, resp.OkData(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,8 +323,14 @@ func (s NeConfigController) DataAdd(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
neInfo := s.neInfoService.FindByNeTypeAndNeID(body.NeType, body.NeId)
|
||||||
|
if neInfo.NeId != body.NeId || neInfo.IP == "" {
|
||||||
|
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// 检查是否array
|
// 检查是否array
|
||||||
info := s.neConfigService.FindByNeTypeAndParamName(body.NeType, body.ParamName)
|
info := s.neConfigService.FindByNeTypeAndParamName(body.NeType, neInfo.NeVersion, body.ParamName)
|
||||||
if info.ParamType != "array" {
|
if info.ParamType != "array" {
|
||||||
c.JSON(200, resp.ErrMsg("this attribute does not support adding"))
|
c.JSON(200, resp.ErrMsg("this attribute does not support adding"))
|
||||||
return
|
return
|
||||||
@@ -326,12 +342,6 @@ func (s NeConfigController) DataAdd(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
neInfo := s.neInfoService.FindByNeTypeAndNeID(body.NeType, body.NeId)
|
|
||||||
if neInfo.NeId != body.NeId || neInfo.IP == "" {
|
|
||||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 网元直连
|
// 网元直连
|
||||||
resData, err := neFetchlink.NeConfigAdd(neInfo, body.ParamName, body.Loc, body.ParamData)
|
resData, err := neFetchlink.NeConfigAdd(neInfo, body.ParamName, body.Loc, body.ParamData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -371,19 +381,19 @@ func (s NeConfigController) DataRemove(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查是否array
|
|
||||||
info := s.neConfigService.FindByNeTypeAndParamName(query.NeType, query.ParamName)
|
|
||||||
if info.ParamType != "array" {
|
|
||||||
c.JSON(200, resp.ErrMsg("this attribute does not support adding"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
neInfo := s.neInfoService.FindByNeTypeAndNeID(query.NeType, query.NeId)
|
neInfo := s.neInfoService.FindByNeTypeAndNeID(query.NeType, query.NeId)
|
||||||
if neInfo.NeId != query.NeId || neInfo.IP == "" {
|
if neInfo.NeId != query.NeId || neInfo.IP == "" {
|
||||||
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查是否array
|
||||||
|
info := s.neConfigService.FindByNeTypeAndParamName(query.NeType, neInfo.NeVersion, query.ParamName)
|
||||||
|
if info.ParamType != "array" {
|
||||||
|
c.JSON(200, resp.ErrMsg("this attribute does not support adding"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// 网元直连
|
// 网元直连
|
||||||
resData, err := neFetchlink.NeConfigDelete(neInfo, query.ParamName, query.Loc)
|
resData, err := neFetchlink.NeConfigDelete(neInfo, query.ParamName, query.Loc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -395,6 +395,7 @@ func (s NeInfoController) Add(c *gin.Context) {
|
|||||||
// 已有网元可获取的信息
|
// 已有网元可获取的信息
|
||||||
if body.ServerState != nil {
|
if body.ServerState != nil {
|
||||||
if v, ok := body.ServerState["version"]; ok && v != nil {
|
if v, ok := body.ServerState["version"]; ok && v != nil {
|
||||||
|
body.NeVersion = fmt.Sprint(v)
|
||||||
neVersion.Version = fmt.Sprint(v)
|
neVersion.Version = fmt.Sprint(v)
|
||||||
}
|
}
|
||||||
if v, ok := body.ServerState["sn"]; ok && v != nil {
|
if v, ok := body.ServerState["sn"]; ok && v != nil {
|
||||||
@@ -497,6 +498,7 @@ func (s NeInfoController) Edit(c *gin.Context) {
|
|||||||
// 已有网元可获取的信息
|
// 已有网元可获取的信息
|
||||||
if body.ServerState != nil {
|
if body.ServerState != nil {
|
||||||
if v, ok := body.ServerState["version"]; ok && v != nil {
|
if v, ok := body.ServerState["version"]; ok && v != nil {
|
||||||
|
body.NeVersion = fmt.Sprint(v)
|
||||||
neVersion.Version = fmt.Sprint(v)
|
neVersion.Version = fmt.Sprint(v)
|
||||||
neVersion.UpdateBy = loginUserName
|
neVersion.UpdateBy = loginUserName
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ package model
|
|||||||
// NeConfig 网元_参数配置可用属性值
|
// NeConfig 网元_参数配置可用属性值
|
||||||
type NeConfig struct {
|
type NeConfig struct {
|
||||||
ID int64 `json:"id" gorm:"column:id;primaryKey;autoIncrement"`
|
ID int64 `json:"id" gorm:"column:id;primaryKey;autoIncrement"`
|
||||||
|
UpdateTime int64 `json:"updateTime" gorm:"column:update_time"` // 更新时间
|
||||||
NeType string `json:"neType" binding:"required" gorm:"column:ne_type"` // 网元类型
|
NeType string `json:"neType" binding:"required" gorm:"column:ne_type"` // 网元类型
|
||||||
|
NeVersion string `json:"neVersion" gorm:"column:ne_version"` // 网元版本 前缀匹配
|
||||||
ParamName string `json:"paramName" binding:"required" gorm:"column:param_name"` // 参数名
|
ParamName string `json:"paramName" binding:"required" gorm:"column:param_name"` // 参数名
|
||||||
ParamDisplay string `json:"paramDisplay" binding:"required" gorm:"column:param_display"` // 参数显示名
|
ParamDisplay string `json:"paramDisplay" binding:"required" gorm:"column:param_display"` // 参数显示名
|
||||||
ParamType string `json:"paramType" gorm:"column:param_type"` // 参数类型 list列表单层 array数组多层
|
ParamType string `json:"paramType" gorm:"column:param_type"` // 参数类型 list列表单层 array数组多层
|
||||||
@@ -11,7 +13,6 @@ type NeConfig struct {
|
|||||||
ParamSort int64 `json:"paramSort" gorm:"column:param_sort"` // 参数排序
|
ParamSort int64 `json:"paramSort" gorm:"column:param_sort"` // 参数排序
|
||||||
ParamPerms string `json:"paramPerms" gorm:"column:param_perms"` // 操作权限 get只读 put可编辑 delete可删除 post可新增
|
ParamPerms string `json:"paramPerms" gorm:"column:param_perms"` // 操作权限 get只读 put可编辑 delete可删除 post可新增
|
||||||
Visible string `json:"visible" gorm:"column:visible"` // 可见性 默认public 单独网元self
|
Visible string `json:"visible" gorm:"column:visible"` // 可见性 默认public 单独网元self
|
||||||
UpdateTime int64 `json:"updateTime" gorm:"column:update_time"` // 更新时间
|
|
||||||
|
|
||||||
// ====== 非数据库字段属性 ======
|
// ====== 非数据库字段属性 ======
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,17 @@ package model
|
|||||||
// NeInfo 网元信息对象 ne_info
|
// NeInfo 网元信息对象 ne_info
|
||||||
type NeInfo struct {
|
type NeInfo struct {
|
||||||
ID int64 `json:"id" gorm:"column:id;primaryKey;autoIncrement"`
|
ID int64 `json:"id" gorm:"column:id;primaryKey;autoIncrement"`
|
||||||
|
CreateBy string `json:"createBy" gorm:"column:create_by"` // 创建者
|
||||||
|
CreateTime int64 `json:"createTime" gorm:"column:create_time"` // 创建时间
|
||||||
|
UpdateBy string `json:"updateBy" gorm:"column:update_by"` // 更新者
|
||||||
|
UpdateTime int64 `json:"updateTime" gorm:"column:update_time"` // 更新时间
|
||||||
|
Remark string `json:"remark" gorm:"column:remark"` // 备注
|
||||||
NeType string `json:"neType" gorm:"column:ne_type" binding:"required"` // 网元类型
|
NeType string `json:"neType" gorm:"column:ne_type" binding:"required"` // 网元类型
|
||||||
NeId string `json:"neId" gorm:"column:ne_id" binding:"required"` // 网元ID
|
NeId string `json:"neId" gorm:"column:ne_id" binding:"required"` // 网元ID
|
||||||
RmUID string `json:"rmUid" gorm:"column:rm_uid"` // 网元资源唯一标识
|
|
||||||
NeName string `json:"neName" gorm:"column:ne_name"` // 网元名称
|
NeName string `json:"neName" gorm:"column:ne_name"` // 网元名称
|
||||||
|
NeVersion string `json:"neVersion" gorm:"column:ne_version"` // 网元版本
|
||||||
|
RmUID string `json:"rmUid" gorm:"column:rm_uid"` // 网元资源唯一标识
|
||||||
|
Schema string `json:"schema" gorm:"column:schema"` // 网元模式 http/https
|
||||||
IP string `json:"ip" gorm:"column:ip" binding:"required"` // 网元服务IP
|
IP string `json:"ip" gorm:"column:ip" binding:"required"` // 网元服务IP
|
||||||
Port int64 `json:"port" gorm:"column:port" binding:"required,number,max=65535,min=1"` // 端口
|
Port int64 `json:"port" gorm:"column:port" binding:"required,number,max=65535,min=1"` // 端口
|
||||||
PvFlag string `json:"pvFlag" gorm:"column:pv_flag" binding:"omitempty,oneof=PNF VNF"` // 网元虚拟化标识 物理PNF 虚拟VNF
|
PvFlag string `json:"pvFlag" gorm:"column:pv_flag" binding:"omitempty,oneof=PNF VNF"` // 网元虚拟化标识 物理PNF 虚拟VNF
|
||||||
@@ -16,11 +23,6 @@ type NeInfo struct {
|
|||||||
NeAddress string `json:"neAddress" gorm:"column:ne_address"` // MAC地址
|
NeAddress string `json:"neAddress" gorm:"column:ne_address"` // MAC地址
|
||||||
HostIDs string `json:"hostIds" gorm:"column:host_ids"` // 网元主机ID组 数据格式(ssh,telnet) UDM(ssh,telnet,redis) UPF(ssh,telnet,telnet)
|
HostIDs string `json:"hostIds" gorm:"column:host_ids"` // 网元主机ID组 数据格式(ssh,telnet) UDM(ssh,telnet,redis) UPF(ssh,telnet,telnet)
|
||||||
Status int64 `json:"status" gorm:"column:status"` // 网元状态 0离线 1在线 2配置待下发 3备用模式
|
Status int64 `json:"status" gorm:"column:status"` // 网元状态 0离线 1在线 2配置待下发 3备用模式
|
||||||
Remark string `json:"remark" gorm:"column:remark"` // 备注
|
|
||||||
CreateBy string `json:"createBy" gorm:"column:create_by"` // 创建者
|
|
||||||
CreateTime int64 `json:"createTime" gorm:"column:create_time"` // 创建时间
|
|
||||||
UpdateBy string `json:"updateBy" gorm:"column:update_by"` // 更新者
|
|
||||||
UpdateTime int64 `json:"updateTime" gorm:"column:update_time"` // 更新时间
|
|
||||||
|
|
||||||
// ====== 非数据库字段属性 ======
|
// ====== 非数据库字段属性 ======
|
||||||
|
|
||||||
|
|||||||
@@ -41,23 +41,39 @@ func TestConfig(t *testing.T) {
|
|||||||
|
|
||||||
if configParamFile == "*" {
|
if configParamFile == "*" {
|
||||||
for _, v := range fileNameList {
|
for _, v := range fileNameList {
|
||||||
params := parseData(filepath.Join(configParamDir, v))
|
filePath := filepath.Join(configParamDir, v)
|
||||||
|
version := parseVersion(filePath)
|
||||||
|
params := parseData(filePath)
|
||||||
if params == nil {
|
if params == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
saveData(params)
|
saveData(version, params)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
params := parseData(filepath.Join(configParamDir, configParamFile))
|
filePath := filepath.Join(configParamDir, configParamFile)
|
||||||
|
version := parseVersion(filePath)
|
||||||
|
params := parseData(filePath)
|
||||||
if params == nil {
|
if params == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
saveData(params)
|
saveData(version, params)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========= Main =============
|
// ========= Main =============
|
||||||
|
|
||||||
|
// 根据文件名获取版本号 mme_2_param_config.yaml -> 2
|
||||||
|
func parseVersion(filePaht string) string {
|
||||||
|
version := "2"
|
||||||
|
splits := strings.Split(filepath.Base(filePaht), "_")
|
||||||
|
if len(splits) > 0 {
|
||||||
|
if splits[2] == "param" {
|
||||||
|
version = splits[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return version
|
||||||
|
}
|
||||||
|
|
||||||
// parseData 文件转map数据
|
// parseData 文件转map数据
|
||||||
func parseData(filePaht string) []map[string]string {
|
func parseData(filePaht string) []map[string]string {
|
||||||
data, err := parseStrToMap(filePaht)
|
data, err := parseStrToMap(filePaht)
|
||||||
@@ -74,7 +90,7 @@ func parseData(filePaht string) []map[string]string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// saveData 保存数据
|
// saveData 保存数据
|
||||||
func saveData(params []map[string]string) {
|
func saveData(version string, params []map[string]string) {
|
||||||
// 定义排序函数
|
// 定义排序函数
|
||||||
sort.Slice(params, func(i, j int) bool {
|
sort.Slice(params, func(i, j int) bool {
|
||||||
paramSortI := params[i]["paramSort"]
|
paramSortI := params[i]["paramSort"]
|
||||||
@@ -109,6 +125,7 @@ func saveData(params []map[string]string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
neConfig := model.NeConfig{
|
neConfig := model.NeConfig{
|
||||||
|
NeVersion: version,
|
||||||
NeType: v["neType"],
|
NeType: v["neType"],
|
||||||
ParamName: v["paramName"],
|
ParamName: v["paramName"],
|
||||||
ParamDisplay: v["paramDisplay"],
|
ParamDisplay: v["paramDisplay"],
|
||||||
@@ -157,7 +174,7 @@ func saveDB(s model.NeConfig) int64 {
|
|||||||
db := connDB()
|
db := connDB()
|
||||||
// 检查是否存在
|
// 检查是否存在
|
||||||
var id int64
|
var id int64
|
||||||
db.Raw("SELECT id FROM ne_config WHERE ne_type = ? AND param_name = ?", s.NeType, s.ParamName).Scan(&id)
|
db.Raw("SELECT id FROM ne_config WHERE ne_type = ? AND ne_version = ? AND param_name = ?", s.NeType, s.NeVersion, s.ParamName).Scan(&id)
|
||||||
// 更新时间
|
// 更新时间
|
||||||
s.UpdateTime = time.Now().UnixMilli()
|
s.UpdateTime = time.Now().UnixMilli()
|
||||||
if id > 0 {
|
if id > 0 {
|
||||||
|
|||||||
@@ -239,3 +239,23 @@ func (r NeInfo) UpdateState(id int64, status int64) int64 {
|
|||||||
}
|
}
|
||||||
return tx.RowsAffected
|
return tx.RowsAffected
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateVersion 修改网元版本
|
||||||
|
func (r NeInfo) UpdateVersion(id int64, neVersion string) int64 {
|
||||||
|
if id <= 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
tx := db.DB("").Model(&model.NeInfo{})
|
||||||
|
// 构建查询条件
|
||||||
|
tx = tx.Where("id = ?", id)
|
||||||
|
tx.Updates(map[string]any{
|
||||||
|
"ne_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
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,59 +21,39 @@ type NeConfig struct {
|
|||||||
neConfigRepository *repository.NeConfig // 网元参数配置可用属性值表
|
neConfigRepository *repository.NeConfig // 网元参数配置可用属性值表
|
||||||
}
|
}
|
||||||
|
|
||||||
// RefreshByNeType 通过ne_type刷新redis中的缓存
|
// RefreshByNeType 通过ne_type刷新redis中的缓存 并返回分组数据
|
||||||
func (r *NeConfig) RefreshByNeTypeAndNeID(neType string) []model.NeConfig {
|
func (r *NeConfig) RefreshByNeTypeAndNeID(neType string) map[string][]model.NeConfig {
|
||||||
// 多个
|
neConfig := model.NeConfig{}
|
||||||
if neType == "" || neType == "*" {
|
if neType != "*" {
|
||||||
neConfigList := r.neConfigRepository.Select(model.NeConfig{})
|
neConfig.NeType = neType
|
||||||
if len(neConfigList) > 0 {
|
}
|
||||||
|
neConfigList := r.neConfigRepository.Select(neConfig)
|
||||||
neConfigGroup := map[string][]model.NeConfig{}
|
neConfigGroup := map[string][]model.NeConfig{}
|
||||||
for _, v := range neConfigList {
|
for _, v := range neConfigList {
|
||||||
if item, ok := neConfigGroup[v.NeType]; ok {
|
if err := json.Unmarshal([]byte(v.ParamJson), &v.ParamData); err != nil {
|
||||||
neConfigGroup[v.NeType] = append(item, v)
|
continue
|
||||||
|
}
|
||||||
|
neTypeVerKey := fmt.Sprintf("%s:%s", strings.ToUpper(v.NeType), v.NeVersion)
|
||||||
|
if item, ok := neConfigGroup[neTypeVerKey]; ok {
|
||||||
|
neConfigGroup[neTypeVerKey] = append(item, v)
|
||||||
} else {
|
} else {
|
||||||
neConfigGroup[v.NeType] = []model.NeConfig{v}
|
neConfigGroup[neTypeVerKey] = []model.NeConfig{v}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for k, v := range neConfigGroup {
|
for k, v := range neConfigGroup {
|
||||||
key := fmt.Sprintf("%s:NeConfig:%s", constants.CACHE_NE_DATA, strings.ToUpper(k))
|
key := fmt.Sprintf("%s:NeConfig:%s", constants.CACHE_NE_DATA, k)
|
||||||
redis.Del("", key)
|
redis.Del("", key)
|
||||||
if len(v) > 0 {
|
if len(v) > 0 {
|
||||||
for i, item := range v {
|
|
||||||
if err := json.Unmarshal([]byte(item.ParamJson), &item.ParamData); err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
v[i] = item
|
|
||||||
}
|
|
||||||
values, _ := json.Marshal(v)
|
values, _ := json.Marshal(v)
|
||||||
redis.Set("", key, string(values), 0)
|
redis.Set("", key, string(values), 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return neConfigGroup
|
||||||
return neConfigList
|
|
||||||
}
|
|
||||||
// 单个
|
|
||||||
key := fmt.Sprintf("%s:NeConfig:%s", constants.CACHE_NE_DATA, strings.ToUpper(neType))
|
|
||||||
redis.Del("", key)
|
|
||||||
neConfigList := r.neConfigRepository.Select(model.NeConfig{
|
|
||||||
NeType: neType,
|
|
||||||
})
|
|
||||||
if len(neConfigList) > 0 {
|
|
||||||
for i, v := range neConfigList {
|
|
||||||
if err := json.Unmarshal([]byte(v.ParamJson), &v.ParamData); err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
neConfigList[i] = v
|
|
||||||
}
|
|
||||||
values, _ := json.Marshal(neConfigList)
|
|
||||||
redis.Set("", key, string(values), 0)
|
|
||||||
}
|
|
||||||
return neConfigList
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClearNeCacheByNeType 清除网元类型参数配置缓存
|
// ClearNeCacheByNeType 清除网元类型参数配置缓存
|
||||||
func (r *NeConfig) ClearNeCacheByNeType(neType string) bool {
|
func (r *NeConfig) ClearNeCacheByNeType(neType string) bool {
|
||||||
key := fmt.Sprintf("%s:NeConfig:%s", constants.CACHE_NE_DATA, neType)
|
key := fmt.Sprintf("%s:NeConfig:%s:*", constants.CACHE_NE_DATA, neType)
|
||||||
if neType == "*" {
|
if neType == "*" {
|
||||||
key = fmt.Sprintf("%s:NeConfig:*", constants.CACHE_NE_DATA)
|
key = fmt.Sprintf("%s:NeConfig:*", constants.CACHE_NE_DATA)
|
||||||
}
|
}
|
||||||
@@ -85,27 +65,41 @@ func (r *NeConfig) ClearNeCacheByNeType(neType string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FindByNeType 查询网元类型参数配置
|
// FindByNeType 查询网元类型参数配置
|
||||||
func (r *NeConfig) FindByNeType(neType string) []model.NeConfig {
|
func (r *NeConfig) FindByNeType(neType, neVersion string) []model.NeConfig {
|
||||||
var neConfigList []model.NeConfig
|
data := make([]model.NeConfig, 0)
|
||||||
key := fmt.Sprintf("%s:NeConfig:%s", constants.CACHE_NE_DATA, strings.ToUpper(neType))
|
keys, _ := redis.GetKeys("", fmt.Sprintf("%s:NeConfig:%s:*", constants.CACHE_NE_DATA, strings.ToUpper(neType)))
|
||||||
jsonStr, _ := redis.Get("", key)
|
if len(keys) > 0 {
|
||||||
if len(jsonStr) > 7 {
|
for _, key := range keys {
|
||||||
err := json.Unmarshal([]byte(jsonStr), &neConfigList)
|
neTypeVer := strings.Split(key, ":")
|
||||||
if err != nil {
|
if len(neTypeVer) != 4 {
|
||||||
neConfigList = []model.NeConfig{}
|
continue
|
||||||
}
|
}
|
||||||
} else {
|
if strings.HasPrefix(neVersion, neTypeVer[3]) {
|
||||||
neConfigList = r.RefreshByNeTypeAndNeID(neType)
|
if jsonStr, _ := redis.Get("", key); len(jsonStr) > 7 {
|
||||||
|
json.Unmarshal([]byte(jsonStr), &data)
|
||||||
}
|
}
|
||||||
return neConfigList
|
return data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 从数据库刷新缓存
|
||||||
|
neConfigGroup := r.RefreshByNeTypeAndNeID(neType)
|
||||||
|
for k, v := range neConfigGroup {
|
||||||
|
neTypeVer := strings.Split(k, ":")
|
||||||
|
if len(neTypeVer) == 2 && strings.HasPrefix(neVersion, neTypeVer[1]) {
|
||||||
|
data = v
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindByNeTypeAndParamName 查询网元类型参数配置By参数名
|
// FindByNeTypeAndParamName 查询网元类型参数配置By参数名
|
||||||
func (r *NeConfig) FindByNeTypeAndParamName(neType, paramName string) model.NeConfig {
|
func (r *NeConfig) FindByNeTypeAndParamName(neType, neVersion, paramName string) model.NeConfig {
|
||||||
neConfigList := r.FindByNeType(neType)
|
neConfigList := r.FindByNeType(neType, neVersion)
|
||||||
var neConfig model.NeConfig
|
var neConfig model.NeConfig
|
||||||
for _, v := range neConfigList {
|
for _, v := range neConfigList {
|
||||||
if v.ParamName == paramName {
|
if strings.HasPrefix(neVersion, v.NeVersion) && v.ParamName == paramName {
|
||||||
neConfig = v
|
neConfig = v
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ func (r NeConfig) GetOMCYaml(paramName string) []map[string]any {
|
|||||||
|
|
||||||
// ModifyOMCYaml 修改OMC网元配置文件
|
// ModifyOMCYaml 修改OMC网元配置文件
|
||||||
func (r NeConfig) ModifyOMCYaml(paramName, loc string, paramData any) error {
|
func (r NeConfig) ModifyOMCYaml(paramName, loc string, paramData any) error {
|
||||||
neConfig := r.FindByNeTypeAndParamName("OMC", paramName)
|
neConfig := r.FindByNeTypeAndParamName("OMC", config.Version, paramName)
|
||||||
if neConfig.ParamType == "list" {
|
if neConfig.ParamType == "list" {
|
||||||
if paramName == "notificationEmail" {
|
if paramName == "notificationEmail" {
|
||||||
notificationEmailData := config.Get("notification.email").(map[string]any)
|
notificationEmailData := config.Get("notification.email").(map[string]any)
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"be.ems/src/framework/cmd"
|
"be.ems/src/framework/cmd"
|
||||||
"be.ems/src/framework/constants"
|
"be.ems/src/framework/constants"
|
||||||
@@ -189,7 +188,6 @@ func (r NeInfo) bandNeStatus(arr *[]model.NeInfo) {
|
|||||||
if v.Status != 0 {
|
if v.Status != 0 {
|
||||||
v.Status = 0
|
v.Status = 0
|
||||||
(*arr)[i].Status = v.Status
|
(*arr)[i].Status = v.Status
|
||||||
(*arr)[i].UpdateTime = time.Now().UnixMilli()
|
|
||||||
r.neInfoRepository.UpdateState(v.ID, v.Status)
|
r.neInfoRepository.UpdateState(v.ID, v.Status)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
@@ -207,8 +205,14 @@ func (r NeInfo) bandNeStatus(arr *[]model.NeInfo) {
|
|||||||
}
|
}
|
||||||
(*arr)[i].Status = status
|
(*arr)[i].Status = status
|
||||||
if v.Status != status {
|
if v.Status != status {
|
||||||
(*arr)[i].UpdateTime = time.Now().UnixMilli()
|
|
||||||
r.neInfoRepository.UpdateState(v.ID, status)
|
r.neInfoRepository.UpdateState(v.ID, status)
|
||||||
|
r.RefreshByNeTypeAndNeID(v.NeType, v.NeId)
|
||||||
|
}
|
||||||
|
// 网元版本设置为当前版本
|
||||||
|
version, ok := result["version"].(string)
|
||||||
|
if ok && version != v.NeVersion {
|
||||||
|
r.neInfoRepository.UpdateVersion(v.ID, version)
|
||||||
|
r.RefreshByNeTypeAndNeID(v.NeType, v.NeId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,12 +64,12 @@ func (r NeVersion) checkNeVersion(arr *[]model.NeVersion) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if v, ok := result["version"]; ok && v != nil {
|
if v, ok := result["version"]; ok && v != nil {
|
||||||
ver := v.(string)
|
ver := fmt.Sprint(v)
|
||||||
if ver == item.Version {
|
if ver == item.Version {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
item.Name = "-"
|
// item.Name = "-"
|
||||||
item.Path = "-"
|
// item.Path = "-"
|
||||||
item.Version = ver
|
item.Version = ver
|
||||||
}
|
}
|
||||||
if item.NeType != neInfo.NeType || item.NeId != neInfo.NeId {
|
if item.NeType != neInfo.NeType || item.NeId != neInfo.NeId {
|
||||||
|
|||||||
Reference in New Issue
Block a user