39 Commits

Author SHA1 Message Date
b74d0059b8 fix: upg 2023-12-29 20:42:30 +08:00
TsMask
bb8d367967 fix: 修改角色状态导致菜单管理删除问题 2023-12-29 20:01:13 +08:00
TsMask
ef89bb4038 chore: 更新说明 2023-12-29 18:43:36 +08:00
7facc301c4 fix: change log for 2.2312.10-20231229 2023-12-29 18:35:52 +08:00
1433964be1 add: nssf menu and topology menu 2023-12-29 17:22:33 +08:00
845720a705 fix: remove some debug of generate ne state alarm 2023-12-29 14:31:55 +08:00
49c3e8ce6d fix: script 2023-12-29 12:13:12 +08:00
e1e10fba00 fix: parameter for genNeStateAlarm 2023-12-29 11:47:44 +08:00
29d4458267 fix: udm parameter config yaml 2023-12-29 11:26:16 +08:00
5de91843a8 fix: changelog 2023-12-29 10:34:08 +08:00
28e3dff6b8 fix: change to 2.2312.10 2023-12-29 10:28:00 +08:00
f26a1d79e5 fix: generate ne state alarm 2023-12-29 10:21:31 +08:00
a10f8c2a43 fix: telnet port 2023-12-28 17:59:44 +08:00
7f37df1337 fix:mml_amp 2023-12-28 17:59:26 +08:00
0a243a5089 fix: ims telnet issue 2023-12-28 16:42:29 +08:00
c0046f421d Merge branch 'main' of http://192.168.2.166:3180/OMC/ems_backend 2023-12-28 16:31:16 +08:00
e9c125f632 add: sys job 2023-12-28 16:31:14 +08:00
TsMask
9c37c7ff91 docs: 字典数据补充 2023-12-28 15:19:30 +08:00
TsMask
8e83397d2d feat: 白名单/systemState 2023-12-28 15:19:08 +08:00
daa42b0182 add: 3 scheuled tasks 2023-12-28 11:56:21 +08:00
079a697dd8 fix: ne info status 2023-12-28 11:47:33 +08:00
7f3d376715 add: genNeStateAlarm dict data 2023-12-28 11:47:12 +08:00
93d5ed2d61 fix: ne sync flag 2023-12-28 11:13:46 +08:00
6462710d63 fix: generate ne state alarm 2023-12-28 10:54:37 +08:00
d6b07f89d0 fix: abnormal NE state alarm gen task 2023-12-28 09:25:44 +08:00
7c09325bf7 fix: inactive task handshake to NF 2023-12-27 18:03:29 +08:00
38ae580d6f fix: sys job get state and delete ne_state 2023-12-27 17:51:24 +08:00
0590566eae fix: job dict data 2023-12-27 17:50:29 +08:00
TsMask
55893741ef fix: kpi指标数据查询支持根据字段排序 2023-12-27 17:30:46 +08:00
TsMask
cc9f779957 fix: 调度任务日志查询重复,移除多语言处理 2023-12-27 17:29:29 +08:00
2b3785361a fix: sync to ne 2023-12-27 12:11:48 +08:00
c708ea4215 fix: offline state version 2023-12-27 10:37:08 +08:00
491456caa0 fix: sync2ne flag 2023-12-26 17:58:16 +08:00
374fb9b8f3 fix: sn fixed 2023-12-26 11:44:30 +08:00
562244d0db fix: serial number of NE license 2023-12-26 10:59:47 +08:00
a066bb3692 fix: yaml conig 2023-12-26 10:59:10 +08:00
524c316da4 fix: ims parameter config 2023-12-26 10:58:52 +08:00
TsMask
6a32def83e fix: UDM用户数据删除多个imsi 2023-12-25 20:57:55 +08:00
4a4c2a97c9 fix: sn change to "-" 2023-12-25 17:55:15 +08:00
44 changed files with 2236 additions and 1531 deletions

View File

@@ -1,5 +1,19 @@
# 版本发布日志
## 2.2312.10-20231229
- 增加 OMC 与 NSSF 的 Available AMFs 和 Subscription 的查询接口代码, NSSF 的代码未完成,暂未联调,菜单未开放
- 确定序列号(SN)方案,增加网元状态在异常情况下可显示序列号和版本号(通过保存在 ne_state 的网元状态信息获取,且 ne_state 表中必须有 3 天内的网元状态数据)
- 调整优化获取网元状态命令的超时时长,优化网元状态主页的等待时间
- BA 需求:增加网元在新增和修改时配置数据同步至网元的开关功能
- 增加调度任务:删除过期网元状态信息
- 移植调度任务:原有 crontask 的周期获取网元状态信息
- 移植调度任务:原有 crontask 的检测网元状态异常并产生和消除告警的定时任务
- 开放 IMS 的 MML 命令
- 移除 installOMC.sh 脚本
- 新增 支持 UDM 用户数据删除多个 imsi
- 修复 调度任务日志查询记录数据重复问题
## 2.2312.9-20231222
- 新增 性能 KPI 统计数据获取接口
@@ -11,6 +25,6 @@
- 优化 UDM 用户数据同步信息及时更新
- 优化 获取网元状态接口请求耗时过长
- 优化 用户管理导入支持预先分别角色权限
- 增加setomc.sh脚本命令行格式setomc.sh -m {install/upgrade/upgvue3} -c {BA/...}, -m参数调用了importdb.sh, -c参数加"BA"表示设置BA的定制化OMC配置, 默认不执行定制化过程
- 暂时屏蔽IMS网元的MML命令
- UDM签约用户数据增加/批量增加MML的字段4G static IP改为非必选
- 增加 setomc.sh 脚本命令行格式setomc.sh -m {install/upgrade/upgvue3} -c {BA/...}, -m 参数调用了 importdb.sh, -c 参数加"BA"表示设置 BA 的定制化 OMC 配置, 默认不执行定制化过程
- 暂时屏蔽 IMS 网元的 MML 命令
- UDM 签约用户数据增加/批量增加 MML 的字段 4G static IP 改为非必选

View File

@@ -1,7 +1,7 @@
# Makefile for rest agent project
PROJECT = OMC
VERSION = 2.2312.9
VERSION = 2.2312.10
PLATFORM = amd64
ARMPLATFORM = aarch64
BUILDDIR = ../../build

View File

@@ -93,7 +93,7 @@ omc:
vendor: ""
dn: 4600
chk2ne: false
sn: 13750650
sn: "-"
checksign: false
rootDir: /usr/local/omc
binDir: /usr/local/omc/bin
@@ -128,7 +128,7 @@ alarm:
signName: XXX SMSC
templateCode: 1000
#User authorized information
# User authorized information
# crypt: mysql/md5/bcrypt
# token: true/false to check accessToken
# expires for session, unit: second

View File

@@ -89,7 +89,7 @@ tasks:
at: 00:30:00
do: TaskDBBackupCSVGetBySQL
- name: handshake to NF
status: Active
status: Inactive
uri: /api/rest/systemManagement/v1/elementType/%s/objectType/systemState
params:
interval: 10
@@ -128,7 +128,7 @@ tasks:
at: 00:30
do: TaskGenLicenseAlarm
- name: Task of Generate NE system state alarm
status: Active
status: Inactive
uri: /api/rest/faultManagement/v1/elementType/%s/objectType/alarms
params: 10000
interval: 5

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -5,5 +5,5 @@ ims:
- operation: "help"
object: ""
display: "List IMS MML CMD"
status: "Inactive"
status: "Active"
params:

View File

@@ -212,14 +212,7 @@
{
"name": "orig_severity",
"display": "Original severity",
"length": 11,
"alias": [
"Critical",
"Major",
"Minor",
"Warning",
"Event"
]
"length": 11
},
{
"name": "pv_flag",
@@ -239,7 +232,7 @@
"retFmt": "GetDB",
"retMsg": "RetCode = %d operation succeeded\n\n",
"errMsg": "ErrorCode = %d operation failed: %s\n\n",
"title": "Alarm Information",
"title": "Performance Task Information",
"singleList": true,
"sepSpaceNum": 2,
"alignmentM": "Left",

View File

@@ -114,6 +114,20 @@ ims:
filter: ''
display: "Dispatch System IPv4"
comment: ""
- name: "internalSMSInd"
type: "bool"
value: 'false'
access: "read-write"
filter: 'false;true;'
display: "Internal SMS Indicator"
comment: ""
- name: "pcfIP"
type: "ipv4"
value: "172.16.5.140"
access: "read-write"
filter: ''
display: "PCF IP Address"
comment: ""

View File

@@ -97,17 +97,17 @@ udm:
display: "Name"
comment: "1~32"
- name: "uplink"
type: "string"
type: "regex"
value: '1Gbps'
access: "read-write"
filter: '^\d+(\.\d+)?( ?)(bps|Kbps|Mbps|Gbps|Tbps)$'
filter: '^\d+(\.\d+)?( )(bps|Kbps|Mbps|Gbps|Tbps)$'
display: "Uplink"
comment: ""
- name: "downlink"
type: "string"
type: "regex"
value: '2Gbps'
access: "read-write"
filter: '^\d+(\.\d+)?( ?)(bps|Kbps|Mbps|Gbps|Tbps)$'
filter: '^\d+(\.\d+)?( )(bps|Kbps|Mbps|Gbps|Tbps)$'
display: "Downlink"
comment: ""
subsNssais:

View File

@@ -95,7 +95,7 @@ func XormGetNeInfoByType(neType string, nes *[]NeInfo) (*[]NeInfo, error) {
log.Debug("XormGetNeInfoByType processing... ")
ne := new(NeInfo)
rows, err := dbClient.xEngine.Table("ne_info").Where("status=0 and ne_type =?", neType).Rows(ne)
rows, err := dbClient.xEngine.Table("ne_info").Where("status in ('0','3') and ne_type =?", neType).Rows(ne)
if err != nil {
log.Error("Failed to get table ne_info from database:", err)
return nil, err
@@ -139,7 +139,7 @@ type NeState struct {
Id int `json:"id" xorm:"pk 'id' autoincr"`
NeType string `json:"neType" xorm:"ne_type"`
NeId string `json:"neId" xorm:"ne_id"`
Version string `json:"version" xorm:"version"`
Version string `json:"version" xorm:"column 'version' VARCHAR(16)"`
Capability uint32 `json:"capability" xorm:"capability"`
SerialNum string `json:"serialNum" xorm:"serial_num"`
ExpiryDate string `json:"expiryDate" xorm:"expiry_date"`
@@ -157,7 +157,13 @@ func XormInsertNeState(neState *NeState) (int64, error) {
session := dbClient.xEngine.NewSession()
defer session.Close()
affected, err := session.InsertOne(neState)
session.Commit()
if err != nil {
return 0, err
}
err = session.Commit()
if err != nil {
return 0, err
}
return affected, err
}

View File

@@ -101,7 +101,7 @@ tasks:
at: 00:30:00
do: TaskDBBackupCSVGetBySQL
- name: handshake to NF
status: Active
status: Inactive
uri: /api/rest/systemManagement/v1/elementType/%s/objectType/systemState
params:
interval: 10

View File

@@ -1,7 +1,7 @@
# Makefile for OMC-OMC-crontask project
PROJECT = OMC
VERSION = 2.2312.9
VERSION = 2.2312.10
LIBDIR = ems.agt/lib
BINNAME = crontask

View File

@@ -1,7 +1,7 @@
# Makefile for rest agent project
PROJECT = OMC
VERSION = 2.2312.9
VERSION = 2.2312.10
RelDate = `date +%Y%m%d`
Release = $(RelDate)
RelVer = $(VERSION)-$(RelDate)

View File

@@ -227,4 +227,112 @@ VALUES (
'job.backupEtcFromNERemark'
);
REPLACE INTO
`omc_db`.`sys_job` (
`job_id`,
`job_name`,
`job_group`,
`invoke_target`,
`target_params`,
`cron_expression`,
`misfire_policy`,
`concurrent`,
`status`,
`save_log`,
`create_by`,
`create_time`,
`update_by`,
`update_time`,
`remark`
)
VALUES (
8,
'job.deleteExpiredNeStateRecord',
'SYSTEM',
'deleteExpiredRecord',
'{\"duration\":3,\"tableName\":\"ne_state\",\"colName\":\"timestamp\"}',
'0 25 0 * * ?',
'3',
'0',
'1',
'1',
'supervisor',
1698478134842,
'admin',
1703668901929,
'job.deleteExpiredNeStateRecordRemark'
);
REPLACE INTO
`omc_db`.`sys_job` (
`job_id`,
`job_name`,
`job_group`,
`invoke_target`,
`target_params`,
`cron_expression`,
`misfire_policy`,
`concurrent`,
`status`,
`save_log`,
`create_by`,
`create_time`,
`update_by`,
`update_time`,
`remark`
)
VALUES (
9,
'job.getStateFromNE',
'SYSTEM',
'getStateFromNE',
'',
'0/10 * * * * ?',
'3',
'0',
'1',
'0',
'supervisor',
1698478134842,
'admin',
1703669877919,
'job.getStateFromNERemark'
);
REPLACE INTO
`omc_db`.`sys_job` (
`job_id`,
`job_name`,
`job_group`,
`invoke_target`,
`target_params`,
`cron_expression`,
`misfire_policy`,
`concurrent`,
`status`,
`save_log`,
`create_by`,
`create_time`,
`update_by`,
`update_time`,
`remark`
)
VALUES (
10,
'job.genNeStateAlarm',
'SYSTEM',
'genNeStateAlarm',
'{\"AlarmID\":\"HXEMSSM10000\",\"alarmCode\":\"10000\",\"alarmTitle\":\"The system state is abnormal\",\"neType\":\"OMC\",\"alarmType\":\"EquipmentAlarm\",\"origSeverity\": \"Major\",\"objectName\":\"EMS;SystemManagement;Heartbeat\",\"objectType\":\"SystemState\",\"specificProblem\":\"Alarm cause: the system state of target NE has not been received for {threshold} seconds\", \"specificProblemID\":\"AC10000\",\"threshold\":30}',
'0/5 * * * * ?',
'3',
'0',
'1',
'0',
'supervisor',
1698478134842,
'admin',
1703768623188,
'Health status inspection of network elements, generating alarms in case of abnormalities.'
);
SET FOREIGN_KEY_CHECKS = 1;

View File

@@ -323,7 +323,112 @@ WHERE
`job_id` = 7
AND `job_group` = 'SYSTEM';
-- 调度任务记录日志字段
UPDATE `omc_db`.`sys_job` SET `save_log` = '1';
REPLACE
INTO `omc_db`.`sys_job` (
`job_id`,
`job_name`,
`job_group`,
`invoke_target`,
`target_params`,
`cron_expression`,
`misfire_policy`,
`concurrent`,
`status`,
`save_log`,
`create_by`,
`create_time`,
`update_by`,
`update_time`,
`remark`
)
VALUES (
8,
'job.deleteExpiredNeStateRecord',
'SYSTEM',
'deleteExpiredRecord',
'{\"duration\":3,\"tableName\":\"ne_state\",\"colName\":\"timestamp\"}',
'0 25 0 * * ?',
'3',
'0',
'1',
'1',
'supervisor',
1698478134842,
'admin',
1703668901929,
'job.deleteExpiredNeStateRecordRemark'
);
REPLACE
INTO `omc_db`.`sys_job` (
`job_id`,
`job_name`,
`job_group`,
`invoke_target`,
`target_params`,
`cron_expression`,
`misfire_policy`,
`concurrent`,
`status`,
`save_log`,
`create_by`,
`create_time`,
`update_by`,
`update_time`,
`remark`
)
VALUES (
9,
'job.getStateFromNE',
'SYSTEM',
'getStateFromNE',
'',
'0/10 * * * * ?',
'3',
'0',
'1',
'0',
'supervisor',
1698478134842,
'admin',
1703669877919,
'job.getStateFromNERemark'
);
REPLACE
INTO `omc_db`.`sys_job` (
`job_id`,
`job_name`,
`job_group`,
`invoke_target`,
`target_params`,
`cron_expression`,
`misfire_policy`,
`concurrent`,
`status`,
`save_log`,
`create_by`,
`create_time`,
`update_by`,
`update_time`,
`remark`
)
VALUES (
10,
'job.genNeStateAlarm',
'SYSTEM',
'genNeStateAlarm',
'{\"AlarmID\":\"HXEMSSM10000\",\"alarmCode\":\"10000\",\"alarmTitle\":\"The system state is abnormal\",\"neType\":\"OMC\",\"alarmType\":\"EquipmentAlarm\",\"origSeverity\": \"Major\",\"objectName\":\"EMS;SystemManagement;Heartbeat\",\"objectType\":\"SystemState\",\"specificProblem\":\"Alarm cause: the system state of target NE has not been received for {threshold} seconds\", \"specificProblemID\":\"AC10000\",\"threshold\":30}',
'0/5 * * * * ?',
'3',
'0',
'1',
'0',
'supervisor',
1698478134842,
'admin',
1703768623188,
'Health status inspection of network elements, generating alarms in case of abnormalities.'
);
SET FOREIGN_KEY_CHECKS = 1;

View File

@@ -43,8 +43,28 @@ var (
CustomUriNeInstance = config.UriPrefix + "/systemManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/instance/{action}"
)
func init() {
const (
NEStatusActive = 0
NEStatusOffline = 1
NEStatusStandby = 2
NEStatusMaintain = 3
)
var client = resty.New()
func init() {
/*
client.
SetTimeout(10 * time.Second).
SetRetryCount(1).
SetRetryWaitTime(1 * time.Second).
SetRetryMaxWaitTime(2 * time.Second).
SetRetryAfter(func(client *resty.Client, resp *resty.Response) (time.Duration, error) {
return 0, errors.New("quota exceeded")
})
*/
client.
SetTimeout(time.Duration(1 * time.Second))
}
func GetNeInfo(w http.ResponseWriter, r *http.Request) {
@@ -69,7 +89,7 @@ func GetNeInfo(w http.ResponseWriter, r *http.Request) {
neInfo, err := dborm.XormGetNeInfo(neType, neId)
if err != nil {
log.Error("dborm.XormGetNeInfo is failed:", err)
services.ResponseInternalServerError500DatabaseOperationFailed(w)
services.ResponseInternalServerError500ProcessError(w, err)
return
}
@@ -105,9 +125,10 @@ func PostNeInfo(w http.ResponseWriter, r *http.Request) {
services.ResponseNotFound404UriNotExist(w, r)
return
}
syncFlag := services.GetUriParamString(r, "sync2ne", ",", false, false)
body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
if err != nil {
log.Error("io.ReadAll is failed:", err)
log.Error("Failed to o.ReadAll:", err)
services.ResponseNotFound404UriNotExist(w, r)
return
}
@@ -123,41 +144,13 @@ func PostNeInfo(w http.ResponseWriter, r *http.Request) {
neInfo.UpdateTime = time.Now().Format(time.DateTime)
log.Debug("NE info:", neInfo)
hostUri := global.CombineHostUri(neInfo.Ip, neInfo.Port)
//hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
apiUri := fmt.Sprintf(UriParamOmcNeConfig, strings.ToLower(neInfo.NeType))
requestURI2NF := fmt.Sprintf("%s%s", hostUri, apiUri)
log.Debug("requestURI2NF:", requestURI2NF)
omcNeConfig := &OmcNeConfig{
NeId: neInfo.NeId,
RmUID: neInfo.RmUID,
NeName: neInfo.NeName,
PvFlag: neInfo.PvFlag,
Province: neInfo.Province,
VendorName: neInfo.VendorName,
Dn: neInfo.Dn,
}
body, _ = json.Marshal(omcNeConfig)
client := resty.New()
response, err := client.R().
EnableTrace().
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
SetBody(body).
Put(requestURI2NF)
if err != nil {
log.Error("Failed to Put:", err)
services.ResponseInternalServerError500NFConnectRefused(w)
return
}
log.Info("StatusCode: ", response.StatusCode())
if !config.GetYamlConfig().OMC.Chk2Ne {
//if !config.GetYamlConfig().OMC.Chk2Ne {
if syncFlag == "false" {
neInfo.Status = NEStatusMaintain
affected, err := dborm.XormInsertNeInfo(neInfo)
if err != nil {
log.Error("Failed to insert Ne info:", err)
services.ResponseInternalServerError500DatabaseOperationFailed(w)
services.ResponseInternalServerError500ProcessError(w, err)
return
}
@@ -167,13 +160,43 @@ func PostNeInfo(w http.ResponseWriter, r *http.Request) {
services.ResponseWithJson(w, http.StatusOK, mapRow)
return
} else {
hostUri := global.CombineHostUri(neInfo.Ip, neInfo.Port)
//hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
apiUri := fmt.Sprintf(UriParamOmcNeConfig, strings.ToLower(neInfo.NeType))
requestURI2NF := fmt.Sprintf("%s%s", hostUri, apiUri)
log.Debug("requestURI2NF:", requestURI2NF)
omcNeConfig := &OmcNeConfig{
NeId: neInfo.NeId,
RmUID: neInfo.RmUID,
NeName: neInfo.NeName,
PvFlag: neInfo.PvFlag,
Province: neInfo.Province,
VendorName: neInfo.VendorName,
Dn: neInfo.Dn,
}
body, _ = json.Marshal(omcNeConfig)
response, err := client.R().
EnableTrace().
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
SetBody(body).
Put(requestURI2NF)
if err != nil {
log.Error("Failed to Put:", err)
services.ResponseInternalServerError500ProcessError(w, err)
return
}
log.Info("StatusCode: ", response.StatusCode())
respMsg := make(map[string]interface{})
switch response.StatusCode() {
case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
neInfo.Status = NEStatusActive
affected, err := dborm.XormInsertNeInfo(neInfo)
if err != nil {
log.Error("Failed to dborm.XormInsertNeInfo:", err)
services.ResponseInternalServerError500DatabaseOperationFailed(w)
services.ResponseInternalServerError500ProcessError(w, err)
return
} else if affected <= 0 {
log.Infof("Not record affected to insert ne_info")
@@ -208,9 +231,10 @@ func PutNeInfo(w http.ResponseWriter, r *http.Request) {
services.ResponseNotFound404UriNotExist(w, r)
return
}
syncFlag := services.GetUriParamString(r, "sync2ne", ",", false, false)
body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
if err != nil {
log.Error("io.ReadAll is failed:", err)
log.Error("Failed to io.ReadAll:", err)
services.ResponseNotFound404UriNotExist(w, r)
return
}
@@ -221,41 +245,13 @@ func PutNeInfo(w http.ResponseWriter, r *http.Request) {
neInfo.UpdateTime = time.Now().Format(time.DateTime)
log.Debug("NE info:", neInfo)
hostUri := global.CombineHostUri(neInfo.Ip, neInfo.Port)
//hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
apiUri := fmt.Sprintf(UriParamOmcNeConfig, strings.ToLower(neType))
requestURI2NF := fmt.Sprintf("%s%s", hostUri, apiUri)
log.Debug("requestURI2NF:", requestURI2NF)
omcNeConfig := &OmcNeConfig{
NeId: neInfo.NeId,
RmUID: neInfo.RmUID,
NeName: neInfo.NeName,
PvFlag: neInfo.PvFlag,
Province: neInfo.Province,
VendorName: neInfo.VendorName,
Dn: neInfo.Dn,
}
body, _ = json.Marshal(omcNeConfig)
client := resty.New()
response, err := client.R().
EnableTrace().
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
SetBody(body).
Put(requestURI2NF)
if err != nil {
log.Error("Failed to Put:", err)
services.ResponseInternalServerError500NFConnectRefused(w)
return
}
log.Info("StatusCode: ", response.StatusCode())
if !config.GetYamlConfig().OMC.Chk2Ne {
//if !config.GetYamlConfig().OMC.Chk2Ne {
if syncFlag == "false" {
neInfo.Status = NEStatusMaintain
affected, err := dborm.XormUpdateNeInfo(neInfo)
if err != nil {
log.Error("Failed to update Ne info:", err)
services.ResponseInternalServerError500DatabaseOperationFailed(w)
services.ResponseInternalServerError500ProcessError(w, err)
return
}
@@ -265,13 +261,43 @@ func PutNeInfo(w http.ResponseWriter, r *http.Request) {
services.ResponseWithJson(w, http.StatusOK, mapRow)
return
} else {
hostUri := global.CombineHostUri(neInfo.Ip, neInfo.Port)
//hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
apiUri := fmt.Sprintf(UriParamOmcNeConfig, strings.ToLower(neType))
requestURI2NF := fmt.Sprintf("%s%s", hostUri, apiUri)
log.Debug("requestURI2NF:", requestURI2NF)
omcNeConfig := &OmcNeConfig{
NeId: neInfo.NeId,
RmUID: neInfo.RmUID,
NeName: neInfo.NeName,
PvFlag: neInfo.PvFlag,
Province: neInfo.Province,
VendorName: neInfo.VendorName,
Dn: neInfo.Dn,
}
body, _ = json.Marshal(omcNeConfig)
response, err := client.R().
EnableTrace().
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
SetBody(body).
Put(requestURI2NF)
if err != nil {
log.Error("Failed to Put:", err)
services.ResponseInternalServerError500ProcessError(w, err)
return
}
log.Info("StatusCode: ", response.StatusCode())
respMsg := make(map[string]interface{})
switch response.StatusCode() {
case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
neInfo.Status = NEStatusActive
affected, err := dborm.XormUpdateNeInfo(neInfo)
if err != nil {
log.Error("Failed to dborm.XormUpdateNeInfo:", err)
services.ResponseInternalServerError500DatabaseOperationFailed(w)
services.ResponseInternalServerError500ProcessError(w, err)
return
} else if affected <= 0 {
log.Infof("Not record affected to insert ne_info")
@@ -321,7 +347,7 @@ func DeleteNeInfo(w http.ResponseWriter, r *http.Request) {
neInfo, err = dborm.XormGetNeInfo(neInfo.NeType, neInfo.NeId)
if err != nil || neInfo == nil {
log.Error("Failed to delete Ne info:", err)
services.ResponseInternalServerError500DatabaseOperationFailed(w)
services.ResponseInternalServerError500ProcessError(w, err)
return
}
log.Debug("NE info:", neInfo)
@@ -331,7 +357,7 @@ func DeleteNeInfo(w http.ResponseWriter, r *http.Request) {
affected, err := dborm.XormDeleteNeInfo(neInfo)
if err != nil {
log.Error("Failed to delete Ne info:", err)
services.ResponseInternalServerError500DatabaseOperationFailed(w)
services.ResponseInternalServerError500ProcessError(w, err)
return
}
@@ -353,7 +379,6 @@ func IsActiveNF(neInfo *dborm.NeInfo) bool {
requestURI := fmt.Sprintf(config.UriPrefix+"/systemManagement/v1/elementType/%s/objectType/systemState",
strings.ToLower(neInfo.NeType))
client := resty.New()
response, err := client.R().
EnableTrace().
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
@@ -361,6 +386,7 @@ func IsActiveNF(neInfo *dborm.NeInfo) bool {
Get(hostUri + requestURI)
if err != nil {
log.Error("Failed to Get:", err)
return false
}
switch response.StatusCode() {
@@ -395,7 +421,7 @@ func ExportCmFromNF(w http.ResponseWriter, r *http.Request) {
neInfo, err := dborm.XormGetNeInfo(neType, neId)
if err != nil {
log.Errorf("Failed to get ne_info:", err)
services.ResponseInternalServerError500DatabaseOperationFailed(w)
services.ResponseInternalServerError500ProcessError(w, err)
return
}
log.Debug("neInfo:", neInfo)
@@ -561,7 +587,7 @@ func ImportCmToNF(w http.ResponseWriter, r *http.Request) {
neInfo, err := dborm.XormGetNeInfo(neType, neId)
if err != nil {
log.Errorf("Failed to get ne_info:", err)
services.ResponseInternalServerError500DatabaseOperationFailed(w)
services.ResponseInternalServerError500ProcessError(w, err)
return
}
log.Debug("neInfo:", neInfo)
@@ -802,7 +828,7 @@ func PostNeServiceAction(w http.ResponseWriter, r *http.Request) {
neInfo, err := dborm.XormGetNeInfo(neType, neId)
if err != nil {
log.Error("Failed to get ne_info:", err)
services.ResponseInternalServerError500DatabaseOperationFailed(w)
services.ResponseInternalServerError500ProcessError(w, err)
return
}
log.Debug("neInfo:", neInfo)
@@ -888,7 +914,7 @@ func PostNeInstanceAction(w http.ResponseWriter, r *http.Request) {
neInfo, err := dborm.XormGetNeInfo(neType, neId)
if err != nil {
log.Errorf("Failed to get ne_info:", err)
services.ResponseInternalServerError500DatabaseOperationFailed(w)
services.ResponseInternalServerError500ProcessError(w, err)
return
}
log.Debug("neInfo:", neInfo)

View File

@@ -23,8 +23,10 @@ import (
)
const (
AlarmStatusClear = 0
AlarmStatusActive = 1
AlarmStatusClear = 0
AlarmStatusActive = 1
AlarmStatusClearString = "0"
AlarmStatusActiveString = "1"
)
const (

View File

@@ -264,6 +264,80 @@ func PostMMLToNF(w http.ResponseWriter, r *http.Request) {
// mmlResult = append(mmlResult, "COMMAND OK\n")
}
case "ims":
hostMML := fmt.Sprintf("%s:%d", neInfo.Ip, config.GetYamlConfig().MML.Port)
conn, err := net.Dial("tcp", hostMML)
if err != nil {
errMsg := fmt.Sprintf("Failed to dial %s: %v", hostMML, err)
log.Error(errMsg)
mmlResult = append(mmlResult, errMsg)
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
defer conn.Close()
// localAddr := conn.LocalAddr()
// remoteAddr := conn.RemoteAddr()
// if localAddr == nil || remoteAddr == nil {
// errMsg := fmt.Sprintf("connect invalid: localAddr=%v, remoteAddr=%v", localAddr, remoteAddr)
// log.Error(errMsg)
// mmlResult = append(mmlResult, errMsg)
// response := Response{mmlResult}
// services.ResponseWithJson(w, http.StatusOK, response)
// return
// }
conn.SetDeadline(time.Now().Add(10 * time.Second))
_, err = conn.Write([]byte(config.GetYamlConfig().MML.User + "\r\n"))
if err != nil {
log.Error("Failed to write:", err)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
n, err = conn.Read(buf[0:])
if err != nil {
log.Error("Failed to read:", err)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
log.Debug(string(buf[0:n]))
_, err = conn.Write([]byte(config.GetYamlConfig().MML.Password + "\r\n"))
if err != nil {
log.Error("Failed to write:", err)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
// loginStr := fmt.Sprintf("%s\r\n%s\r\n", config.GetYamlConfig().MML.User, config.GetYamlConfig().MML.Password)
// _, err = conn.Write([]byte(loginStr))
// if err != nil {
// log.Error("Failed to write:", err)
// mmlResult = append(mmlResult, err.Error())
// response := Response{mmlResult}
// services.ResponseWithJson(w, http.StatusOK, response)
// return
// }
// time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
n, err = conn.Read(buf[0:])
if err != nil {
log.Error("Failed to read:", err)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
log.Trace(string(buf[0 : n-len(neType)-2]))
body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
if err != nil {
log.Error("io.ReadAll is failed:", err)
@@ -276,81 +350,7 @@ func PostMMLToNF(w http.ResponseWriter, r *http.Request) {
_ = json.Unmarshal(body, mmlRequest)
for _, mml := range mmlRequest.MML {
hostMML := fmt.Sprintf("%s:%d", neInfo.Ip, config.GetYamlConfig().MML.Port)
conn, err := net.Dial("tcp", hostMML)
if err != nil {
errMsg := fmt.Sprintf("Failed to dial %s: %v", hostMML, err)
log.Error(errMsg)
mmlResult = append(mmlResult, errMsg)
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
defer conn.Close()
// localAddr := conn.LocalAddr()
// remoteAddr := conn.RemoteAddr()
// if localAddr == nil || remoteAddr == nil {
// errMsg := fmt.Sprintf("connect invalid: localAddr=%v, remoteAddr=%v", localAddr, remoteAddr)
// log.Error(errMsg)
// mmlResult = append(mmlResult, errMsg)
// response := Response{mmlResult}
// services.ResponseWithJson(w, http.StatusOK, response)
// return
// }
conn.SetDeadline(time.Now().Add(10 * time.Second))
_, err = conn.Write([]byte(config.GetYamlConfig().MML.User + "\n"))
if err != nil {
log.Error("Failed to write:", err)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
n, err = conn.Read(buf[0:])
if err != nil {
log.Error("Failed to read:", err)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
log.Debug(string(buf[0:n]))
_, err = conn.Write([]byte(config.GetYamlConfig().MML.Password + "\n"))
if err != nil {
log.Error("Failed to write:", err)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
// loginStr := fmt.Sprintf("%s\n%s\n", config.GetYamlConfig().MML.User, config.GetYamlConfig().MML.Password)
// _, err = conn.Write([]byte(loginStr))
// if err != nil {
// log.Error("Failed to write:", err)
// mmlResult = append(mmlResult, err.Error())
// response := Response{mmlResult}
// services.ResponseWithJson(w, http.StatusOK, response)
// return
// }
n, err = conn.Read(buf[0:])
if err != nil {
log.Error("Failed to read:", err)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
log.Trace(string(buf[0 : n-len(neType)-2]))
mmlCommand := fmt.Sprintf("%s\n", mml)
mmlCommand := fmt.Sprintf("%s\r\n", mml)
log.Debug("mml command:", mmlCommand)
_, err = conn.Write([]byte(mmlCommand))
if err != nil {
@@ -377,11 +377,9 @@ func PostMMLToNF(w http.ResponseWriter, r *http.Request) {
re2 := regexp.MustCompile(`[\x00-\x08\x0B\x0C\x0E-\x1F\x7F\x1B]`) // 匹配空字符和包含␛的控制字符
//re := regexp.MustCompile(`[\x00-\x1F\x7F]`)
// upf telnet buffer只能读取一次需要去掉前面的多余字符
//result := re1.ReplaceAllString(string(buf[0:n-len(neType)-2]), "")
result := re1.ReplaceAllString(string(buf[0:]), "")
result := re1.ReplaceAllString(string(buf[0:n-len(neType)-2]), "")
result = re2.ReplaceAllString(result, "")
mmlResult = append(mmlResult, result)
conn.Close()
}
default:
hostMML := fmt.Sprintf("%s:%d", neInfo.Ip, config.GetYamlConfig().MML.Port)

View File

@@ -154,7 +154,12 @@ func init() {
return 0, errors.New("quota exceeded")
})
*/
client.SetTimeout(3 * time.Second)
client.
SetTimeout(time.Duration(400 * time.Millisecond))
// SetRetryCount(1).
// SetRetryWaitTime(time.Duration(1 * time.Second)).
// SetRetryMaxWaitTime(time.Duration(2 * time.Second))
//client.SetTimeout(2 * time.Second)
}
func NeStatusEnumToStr(intStatus int) string {
@@ -216,7 +221,7 @@ func GetOneLicenseInfoFromNF(w http.ResponseWriter, r *http.Request) {
if neType != omcNeTypeLower {
log.Debugf("r.RemoteAddr: %s omcNeTypeLower: %s", r.RemoteAddr, omcNeTypeLower)
var requestURI2NF string
if config.GetYamlConfig().OMC.TestMode == true && strings.ToLower(neType) != "udm" {
if config.GetYamlConfig().OMC.TestMode && strings.ToLower(neType) != "udm" {
var udmNEs []dborm.NeInfo
err := dborm.XormGetNeInfoByNeType("UDM", &udmNEs)
if err != nil {
@@ -237,7 +242,7 @@ func GetOneLicenseInfoFromNF(w http.ResponseWriter, r *http.Request) {
}
log.Debug("requestURI2NF:", requestURI2NF)
resp, err := client.SetTimeout(time.Duration(1 * time.Second)).R().
resp, err := client.R().
EnableTrace().
SetHeaders(map[string]string{tokenConst.HEADER_KEY: r.Header.Get(tokenConst.HEADER_KEY)}).
SetHeaders(map[string]string{"accessToken": token}).
@@ -245,7 +250,7 @@ func GetOneLicenseInfoFromNF(w http.ResponseWriter, r *http.Request) {
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
Get(requestURI2NF)
if err != nil {
log.Error("Get system state from NF is failed:", err)
log.Error("Failed to get system state:", err)
services.ResponseInternalServerError500ProcessError(w, err)
return
} else {
@@ -266,6 +271,9 @@ func GetOneLicenseInfoFromNF(w http.ResponseWriter, r *http.Request) {
}
//neItem := strings.ToUpper(neType) + "/" + neId
result, err = global.ToMap(*licenseInfo, "json")
if err != nil {
log.Warn("Failed to map:", err)
}
}
} else {
systemState := GetEMSState(neInfo.Ip)
@@ -279,6 +287,9 @@ func GetOneLicenseInfoFromNF(w http.ResponseWriter, r *http.Request) {
ExpiryDate: systemState.ExpiryDate,
}
result, err = global.ToMap(*licenseInfo, "json")
if err != nil {
log.Warn("Failed to map:", err)
}
// neItem := strings.ToUpper(neType) + "/" + neId
// result[neItem] = sysInfo
}
@@ -306,6 +317,11 @@ func GetAllLicenseInfoFromNF(w http.ResponseWriter, r *http.Request) {
var neList []dborm.NeInfo
_, err = dborm.XormGetAllNeInfo(&neList)
if err != nil {
log.Error("Failed to XormGetAllNeInfo:", err)
services.ResponseInternalServerError500ProcessError(w, err)
return
}
omcNeTypeLower := "omc"
if config.GetYamlConfig().OMC.NeType != "" {
omcNeTypeLower = strings.ToLower(config.GetYamlConfig().OMC.NeType)
@@ -321,7 +337,7 @@ func GetAllLicenseInfoFromNF(w http.ResponseWriter, r *http.Request) {
// requestURI2NF := fmt.Sprintf("%s/api/rest/systemManagement/v1/elementType/%s/objectType/systemState",
// hostUri, strings.ToLower(ne.NeType))
var requestURI2NF string
if config.GetYamlConfig().OMC.TestMode == true && strings.ToLower(ne.NeType) != "udm" {
if config.GetYamlConfig().OMC.TestMode && strings.ToLower(ne.NeType) != "udm" {
var udmNEs []dborm.NeInfo
err := dborm.XormGetNeInfoByNeType("UDM", &udmNEs)
if err != nil {
@@ -369,6 +385,9 @@ func GetAllLicenseInfoFromNF(w http.ResponseWriter, r *http.Request) {
ExpiryDate: systemState.ExpiryDate,
}
result, err = global.ToMap(*licenseInfo, "json")
if err != nil {
log.Warn("Failed to map:", err)
}
// neItem := strings.ToUpper(ne.NeType) + "/" + ne.NeId
// result[neItem] = sysInfo
}
@@ -384,6 +403,9 @@ func GetAllLicenseInfoFromNF(w http.ResponseWriter, r *http.Request) {
ExpiryDate: systemState.ExpiryDate,
}
result, err = global.ToMap(*licenseInfo, "json")
if err != nil {
log.Warn("Failed to map:", err)
}
// neItem := strings.ToUpper(ne.NeType) + "/" + ne.NeId
// result[neItem] = sysInfo
}
@@ -441,7 +463,7 @@ func GetOneSysinfoFromNF(w http.ResponseWriter, r *http.Request) {
if neType != omcNeTypeLower {
log.Debugf("r.RemoteAddr: %s omcNeTypeLower: %s", r.RemoteAddr, omcNeTypeLower)
var requestURI2NF string
if config.GetYamlConfig().OMC.TestMode == true && strings.ToLower(neType) != "udm" {
if config.GetYamlConfig().OMC.TestMode && strings.ToLower(neType) != "udm" {
var udmNEs []dborm.NeInfo
err := dborm.XormGetNeInfoByNeType("UDM", &udmNEs)
if err != nil {
@@ -462,7 +484,7 @@ func GetOneSysinfoFromNF(w http.ResponseWriter, r *http.Request) {
}
log.Debug("requestURI2NF:", requestURI2NF)
resp, err := client.SetTimeout(time.Duration(1 * time.Second)).R().
resp, err := client.R().
EnableTrace().
SetHeaders(map[string]string{tokenConst.HEADER_KEY: r.Header.Get(tokenConst.HEADER_KEY)}).
SetHeaders(map[string]string{"accessToken": token}).
@@ -515,6 +537,9 @@ func GetOneSysinfoFromNF(w http.ResponseWriter, r *http.Request) {
}
//neItem := strings.ToUpper(neType) + "/" + neId
result, err = global.ToMap(*sysInfo, "json")
if err != nil {
log.Warn("Failed to map:", err)
}
}
} else {
systemState := GetEMSState(neInfo.Ip)
@@ -533,6 +558,9 @@ func GetOneSysinfoFromNF(w http.ResponseWriter, r *http.Request) {
Status: NeStatusEnumToStr(neInfo.Status),
}
result, err = global.ToMap(*sysInfo, "json")
if err != nil {
log.Warn("Failed to map:", err)
}
// neItem := strings.ToUpper(neType) + "/" + neId
// result[neItem] = sysInfo
}
@@ -560,6 +588,11 @@ func GetAllSysinfoFromNF(w http.ResponseWriter, r *http.Request) {
var neList []dborm.NeInfo
_, err = dborm.XormGetAllNeInfo(&neList)
if err != nil {
log.Error("Failed to XormGetAllNeInfo:", err)
services.ResponseInternalServerError500ProcessError(w, err)
return
}
omcNeTypeLower := "omc"
if config.GetYamlConfig().OMC.NeType != "" {
omcNeTypeLower = strings.ToLower(config.GetYamlConfig().OMC.NeType)
@@ -575,7 +608,7 @@ func GetAllSysinfoFromNF(w http.ResponseWriter, r *http.Request) {
// requestURI2NF := fmt.Sprintf("%s/api/rest/systemManagement/v1/elementType/%s/objectType/systemState",
// hostUri, strings.ToLower(ne.NeType))
var requestURI2NF string
if config.GetYamlConfig().OMC.TestMode == true && strings.ToLower(ne.NeType) != "udm" {
if config.GetYamlConfig().OMC.TestMode && strings.ToLower(ne.NeType) != "udm" {
var udmNEs []dborm.NeInfo
err := dborm.XormGetNeInfoByNeType("UDM", &udmNEs)
if err != nil {
@@ -651,6 +684,9 @@ func GetAllSysinfoFromNF(w http.ResponseWriter, r *http.Request) {
// neItem := strings.ToUpper(ne.NeType) + "/" + ne.NeId
// result[neItem] = sysInfo
result, err = global.ToMap(*sysInfo, "json")
if err != nil {
log.Warn("Failed to map:", err)
}
}
} else {
port, _ := strconv.Atoi(ne.Port)
@@ -672,6 +708,9 @@ func GetAllSysinfoFromNF(w http.ResponseWriter, r *http.Request) {
// neItem := strings.ToUpper(ne.NeType) + "/" + ne.NeId
// result[neItem] = sysInfo
result, err = global.ToMap(*sysInfo, "json")
if err != nil {
log.Warn("Failed to map:", err)
}
}
data = append(data, result)
@@ -772,7 +811,7 @@ func GetStateFromNF(w http.ResponseWriter, r *http.Request) {
log.Debug("requestURI2NF:", requestURI2NF)
result["ipAddress"] = ne.Ip
resp, err := client.SetTimeout(time.Duration(1 * time.Second)).R().
resp, err := client.R().
EnableTrace().
SetHeaders(map[string]string{tokenConst.HEADER_KEY: r.Header.Get(tokenConst.HEADER_KEY)}).
SetHeaders(map[string]string{"accessToken": token}).
@@ -785,6 +824,9 @@ func GetStateFromNF(w http.ResponseWriter, r *http.Request) {
ErrorCode: "1", ErrorInfo: "Internal server error, NF connnect refused",
}
result["error"] = errorMessage
SN, Version, _ := dborm.XormGetNEStateInfo(ne.NeType, ne.NeId)
result["serialNum"] = SN
result["version"] = Version
} else {
systemState := make(map[string]interface{})
_ = json.Unmarshal(resp.Body(), &systemState)

View File

@@ -200,12 +200,12 @@ func XormGetNeInfo(neType string, neId string) (*NeInfo, error) {
log.Debug("XormGetNeInfo processing... ")
neInfo := new(NeInfo)
has, err := xEngine.Where("status='0' and ne_type=? and ne_id=?", strings.ToUpper(neType), neId).Get(neInfo)
has, err := xEngine.Where("status in ('0','3') and ne_type=? and ne_id=?", strings.ToUpper(neType), neId).Get(neInfo)
if err != nil {
log.Error("Failed to get table ne_info from database:", err)
return nil, err
} else if has == false {
log.Infof("Not found ne_info from database, status='0', neType=%s, neId=%s", neType, neId)
} else if !has {
log.Infof("Not found ne_info from database, status in ('0','3'), neType=%s, neId=%s", neType, neId)
return nil, nil
}
@@ -217,11 +217,11 @@ func XormGetNeInfoByRmUID(neType string, rmUID string) (*NeInfo, error) {
log.Debug("XormGetNeInfoByRmUID processing... ")
neInfo := new(NeInfo)
has, err := xEngine.Where("status='0' and ne_type=? and rm_uid=?", strings.ToUpper(neType), rmUID).Get(neInfo)
has, err := xEngine.Where("status in ('0','3') and ne_type=? and rm_uid=?", strings.ToUpper(neType), rmUID).Get(neInfo)
if err != nil {
log.Error("Failed to get table ne_info from database:", err)
return nil, err
} else if has == false {
} else if !has {
log.Infof("Not found ne_info from database, status='0', neType=%s, neId=%s", neType, rmUID)
return nil, nil
}
@@ -234,7 +234,7 @@ func XormGetAllNeInfo(nes *[]NeInfo) (*[]NeInfo, error) {
log.Debug("XormGetAllNeInfo processing... ")
ne := new(NeInfo)
rows, err := xEngine.Table("ne_info").Where("status='0'").Rows(ne)
rows, err := xEngine.Table("ne_info").Where("status in ('0','3')").Rows(ne)
if err != nil {
log.Error("Failed to get table ne_info from database:", err)
return nil, err
@@ -256,7 +256,7 @@ func XormGetNeInfoByNeType(neType string, nes *[]NeInfo) error {
log.Debug("XormGetNeInfoByNeType processing... ")
ne := new(NeInfo)
rows, err := xEngine.Table("ne_info").Where("status='0' and ne_type=?", neType).Rows(ne)
rows, err := xEngine.Table("ne_info").Where("status in ('0','3') and ne_type=?", neType).Rows(ne)
if err != nil {
log.Error("Failed to get table ne_info from database:", err)
return err
@@ -283,7 +283,7 @@ func XormInsertNeInfo(neInfo *NeInfo) (int64, error) {
xSession := xEngine.NewSession()
defer xSession.Close()
ex, _ := xEngine.Table("ne_info").Where("status = '1' and ne_type = ? and ne_id = ?", neInfo.NeType, neInfo.NeId).Exist()
if ex == true {
if ex {
neInfo.Status = 0
affected, err = xSession.Where("ne_type = ? and ne_id = ?", neInfo.NeType, neInfo.NeId).Update(neInfo)
} else {
@@ -298,7 +298,7 @@ func XormUpdateNeInfo(neInfo *NeInfo) (int64, error) {
xSession := xEngine.NewSession()
defer xSession.Close()
affected, err := xSession.ID(neInfo.Id).Update(neInfo)
affected, err := xSession.ID(neInfo.Id).MustCols("status").Update(neInfo)
xSession.Commit()
return affected, err
}
@@ -1124,7 +1124,9 @@ type Alarm struct {
PVFlag string `json:"pvFlag" xorm:"pv_flag"`
NeName string `json:"neName"`
NeType string `json:"neType"`
ObjectUid string `json:"objectUid" xorm:"object_uid"`
ObjectName string `json:"objectName" xorm:"object_name"`
ObjectType string `json:"objectType" xorm:"object_type"`
LocationInfo string `json:"locationInfo"`
Province string `json:"province"`
AlarmStatus int `json:"alarmStatus"`
@@ -1820,3 +1822,80 @@ func XormGetTraceRawMsg(id int) (int64, []byte, error) {
return timestamp, rawMsg, nil
}
func XormGetNEStateInfo(neType, neID string) (string, string, error) {
SN := "-"
Version := "-"
_, err := xEngine.Table("ne_state").
Where("ne_type=? and ne_id=?", neType, neID).
Desc("timestamp").
Cols("serial_num", "version").
Limit(1).
Get(&SN, &Version)
return SN, Version, err
}
type NeState struct {
Id int `json:"id" xorm:"pk 'id' autoincr"`
NeType string `json:"neType" xorm:"ne_type"`
NeId string `json:"neId" xorm:"ne_id"`
Version string `json:"version" xorm:"column 'version' VARCHAR(16)"`
Capability uint32 `json:"capability" xorm:"capability"`
SerialNum string `json:"serialNum" xorm:"serial_num"`
ExpiryDate string `json:"expiryDate" xorm:"expiry_date"`
CpuUsage string `json:"cpuUsage" xorm:"cpu_usage"`
MemUsage string `json:"memUsage" xorm:"mem_usage"`
DiskSpace string `json:"diskSpace" xorm:"disk_space"`
Timestamp string `json:"timestamp" xorm:"-" `
}
func XormInsertNeState(neState *NeState) (int64, error) {
log.Debug("XormInsertNeState processing... ")
var affected int64 = 0
session := xEngine.NewSession()
defer session.Close()
affected, err := session.InsertOne(neState)
if err != nil {
return 0, err
}
err = session.Commit()
if err != nil {
return 0, err
}
return affected, err
}
type AlarmDefine struct {
AlarmId string `json:"alarmId" xorm:"alarm_id"`
AlarmCode int `json:"alarmCode" xorm:"alarm_code"`
AlarmTitle string `json:"alarmTitle" xorm:"alarm_title"`
NeType string `json:"neType" xorm:"ne_type"`
AlarmType string `json:"alarmType" xorm:"alarm_type"`
OrigSeverity string `json:"origSeverity" xorm:"orig_severity"`
ObjectUid string `json:"objectUid" xorm:"object_uid"`
ObjectName string `json:"objectName" xorm:"object_name"`
ObjectType string `json:"objectType" xorm:"object_type"`
LocationInfo string `json:"locationInfo"`
SpecificProblem string `json:"specificProblem"`
SpecificProblemId string `json:"specificProblemId" xorm:"specific_problem_id"`
AddInfo string `json:"addInfo" xorm:"add_info"`
Threshold int64 `json:"threshold" xorm:"threshold"`
Status string `json:"status" xorm:"status"`
}
func XormGetAlarmDefine(alarmCode string) (*AlarmDefine, error) {
log.Debug("XormGetAlarmDefine processing... ")
alarmDefine := new(AlarmDefine)
_, err := xEngine.
Where("alarm_code=? and status='Active'", alarmCode).
Get(alarmDefine)
if err != nil {
log.Error("Failed to get table alarm_define from database:", err)
return nil, err
}
return alarmDefine, nil
}

View File

@@ -3,7 +3,7 @@
ProjectL = omc
ProjectU = OMC
PROJECT = $(ProjectL)
VERSION = 2.2312.9
VERSION = 2.2312.10
RelDate = `date +%Y%m%d`
Release = $(RelDate)
RelVer = $(VERSION)-$(RelDate)

View File

@@ -1,191 +0,0 @@
#!/bin/bash
echo "-------------------please input-------------------"
#please input the new nf ip
read -p "please input your OMC IP: " OMCIP
echo "-----------------please continue to enter-----------------"
read -p "please input your IMS IP: " IMSIP
echo "-----------------please continue to enter-----------------"
read -p "please input your AMF IP: " AMFIP
echo "-----------------please continue to enter-----------------"
read -p "please input your AUSF IP: " AUSFIP
echo "-----------------please continue to enter-----------------"
read -p "please input your UDM IP: " UDMIP
echo "-----------------please continue to enter-----------------"
read -p "please input your SMF IP: " SMFIP
echo "-----------------please continue to enter-----------------"
read -p "please input your PCF IP: " PCFIP
echo "-----------------please continue to enter-----------------"
read -p "please input your NSSF IP: " NSSFIP
echo "-----------------please continue to enter-----------------"
read -p "please input your NRF IP: " NRFIP
echo "-----------------please continue to enter-----------------"
read -p "please input your UPF IP: " UPFIP
echo "-----------------please continue to enter-----------------"
read -p "please input your MME IP: " MMEIP
echo "------------please continue to enter Vm account-------------"
read -p "please input your username: " username
echo "------------please continue to enter Vm password-------------"
read -p "please input your passwd: " passwd
cd /home/agtuser
#Creating a local source
tar -xzvf omcpkg*.tar.gz
mv /etc/apt/sources.list /etc/apt/sources.list-bak
echo "deb [trusted=yes] file:/home/agtuser/omcpkg archives/" > /etc/apt/sources.list
sleep 1
apt update
sleep 1
#Database installation
apt install -y net-tools software-properties-common
sleep 1
apt-key add mariadb_release_signing_key.asc
apt install -y mariadb-server
systemctl start mariadb
mysql --version
sudo mysql_secure_installation <<-EOF
1000omc@kp!
y
n
y
y
y
y
EOF
#You need to enter the password manually1000omc@kp!
systemctl enable mariadb
systemctl restart mariadb
#Modify mysql datebase root password
#You need to run the following command
mysql -u root <<-EOF
use mysql
ALTER USER root@'localhost' IDENTIFIED VIA mysql_native_password USING PASSWORD("1000omc@kp!");
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '1000omc@kp!';
flush privileges;
quit
EOF
sleep 5
echo "port=33066" >> /etc/mysql/mariadb.conf.d/50-server.cnf
sed -i "s/127.0.0.1/0.0.0.0/g" /etc/mysql/mariadb.conf.d/50-server.cnf
systemctl restart mariadb
#Install WEB server
apt update
apt install -y nginx
systemctl enable nginx
systemctl daemon-reload
systemctl start nginx
#Install and config OMC
dpkg -i omc*.deb
cp /usr/local/omc/htdocs/front/default/config.js /usr/local/omc/htdocs/front/
sed -i "s/192.168.8.100/${OMCIP}/g" /usr/local/omc/htdocs/front/config.js
cp /usr/local/omc/etc/default/* /usr/local/omc/etc
sed -i "76s/user: root/user: ${username}/" /usr/local/omc/etc/restconf.yaml
#Database configuration
/usr/local/omc/bin/importdb.sh <<-EOF
Install
EOF
#Configure the trusted gateway of the managed NE
apt install -y expect
echo "${OMCIP} ${username} ${passwd}" > /usr/local/omc/bin/nehosts
echo "${IMSIP} ${username} ${passwd}" >> /usr/local/omc/bin/nehosts
echo "${AMFIP} ${username} ${passwd}" >> /usr/local/omc/bin/nehosts
echo "${AUSFIP} ${username} ${passwd}" >> /usr/local/omc/bin/nehosts
echo "${UDMIP} ${username} ${passwd}" >> /usr/local/omc/bin/nehosts
echo "${SMFIP} ${username} ${passwd}" >> /usr/local/omc/bin/nehosts
echo "${PCFIP} ${username} ${passwd}" >> /usr/local/omc/bin/nehosts
echo "${NSSFIP} ${username} ${passwd}" >> /usr/local/omc/bin/nehosts
echo "${NRFIP} ${username} ${passwd}" >> /usr/local/omc/bin/nehosts
echo "${UPFIP} ${username} ${passwd}" >> /usr/local/omc/bin/nehosts
echo "${MMEIP} ${username} ${passwd}" >> /usr/local/omc/bin/nehosts
sleep 1
cd /usr/local/omc/bin
/usr/local/omc/bin/cpsshkey.sh
cd /home/agtuser
sleep 5
#adb server configuration
cp /usr/local/db/bin/conf/default/redis.conf /usr/local/db/bin/conf/redis.conf
sed -i "s/172.16.5.140/${UDMIP}/g" /usr/local/db/bin/conf/redis.conf
#Modifying User Rights
sudo echo "agtuser ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers
sudo echo "agtuser ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
sudo scp /etc/sudoers ${username}@${IMSIP}:/home/agtuser
sudo scp /etc/sudoers ${username}@${AMFIP}:/home/agtuser
sudo scp /etc/sudoers ${username}@${AUSFIP}:/home/agtuser
sudo scp /etc/sudoers ${username}@${UDMIP}:/home/agtuser
sudo scp /etc/sudoers ${username}@${SMFIP}:/home/agtuser
sudo scp /etc/sudoers ${username}@${PCFIP}:/home/agtuser
sudo scp /etc/sudoers ${username}@${NSSFIP}:/home/agtuser
sudo scp /etc/sudoers ${username}@${NRFIP}:/home/agtuser
sudo scp /etc/sudoers ${username}@${UPFIP}:/home/agtuser
sudo scp /etc/sudoers ${username}@${MMEIP}:/home/agtuser
#Run the following commands on each NE VM
#cp sudoers /etc/sudoers
sleep 5
#Service initiation
systemctl enable restagent.service
systemctl enable crontask.service
systemctl daemon-reload
/usr/local/omc/bin//omcsvc.sh restart
systemctl restart nginx
echo "-----------------config complete------------"

View File

@@ -2,7 +2,7 @@
ProcList="restagent crontask sshsvc captrace data2html"
ProjectL=omc
VERSION=2.2312.9
VERSION=2.2312.10
RelDate=`date +%Y%m%d`
Release=${RelDate}
RelVer=${VERSION}-${RelDate}

View File

@@ -94,7 +94,7 @@ omc:
vendor: ""
dn: 4600
chk2ne: false
sn: 13750650
sn: "-"
checksign: false
rootDir: ./
binDir: ./bin

View File

@@ -1,7 +1,7 @@
# Makefile for rest agent project
PROJECT = OMC
VERSION = 2.2312.9
VERSION = 2.2312.10
PLATFORM = amd64
ARMPLATFORM = aarch64
BUILDDIR = ../../build

View File

@@ -1,7 +1,7 @@
# 项目信息
framework:
name: "CN EMS"
version: "2.2312.9"
version: "2.2312.10"
# 应用服务配置
server:

View File

@@ -14,7 +14,7 @@ import (
)
/**无Token可访问白名单 */
var URL_WHITE_LIST = []string{"/performanceManagement", "/faultManagement"}
var URL_WHITE_LIST = []string{"/performanceManagement", "/faultManagement", "/systemState"}
// PreAuthorize 用户身份授权认证校验
//

View File

@@ -0,0 +1,309 @@
package genNeStateAlarm
import (
"encoding/json"
"fmt"
"net/http"
"strconv"
"strings"
"time"
"ems.agt/features/fm"
"ems.agt/lib/dborm"
"ems.agt/lib/global"
"ems.agt/lib/log"
"ems.agt/restagent/config"
"ems.agt/src/framework/cron"
"github.com/go-resty/resty/v2"
)
var NewProcessor = &BarProcessor{
progress: 0,
count: 0,
}
// bar 队列任务处理
type BarProcessor struct {
// 任务进度
progress int
// 执行次数
count int
}
type BarParams struct {
AlarmID string `json:"alarmID"`
AlarmCode int `json:"alarmCode"`
AlarmTitle string `json:"alarmTitle"`
AlarmType string `json:"alarmType"`
OrigSeverity string `json:"origSeverity"`
ObjectUID string `json:"objectUID"`
ObjectName string `json:"objectName"`
ObjectType string `json:"objectType"`
SpecificProblem string `json:"specificProblem"`
SpecificProblemID string `json:"specificProblemID"`
AddInfo string `json:"AddInfo"`
Threshold int64 `json:"threshold"`
}
// type BarParams struct {
// Duration int `json:"duration"`
// }
type Alarm struct {
Id int `json:"-" xorm:"pk 'id' autoincr"`
AlarmSeq int `json:"alarmSeq"`
AlarmId string `json:"alarmId" xorm:"alarm_id"`
NeId string `json:"neId"`
AlarmCode int `json:"alarmCode"`
AlarmTitle string `json:"alarmTitle"`
EventTime string `json:"eventTime"`
AlarmType string `json:"alarmType"`
OrigSeverity string `json:"origSeverity"`
PerceivedSeverity string `json:"perceivedSeverity"`
PVFlag string `json:"pvFlag" xorm:"pv_flag"`
NeName string `json:"neName"`
NeType string `json:"neType"`
ObjectUid string `json:"objectUid" xorm:"object_uid"`
ObjectName string `json:"objectName" xorm:"object_name"`
ObjectType string `json:"objectType" xorm:"object_type"`
LocationInfo string `json:"locationInfo"`
Province string `json:"province"`
AlarmStatus int `json:"alarmStatus" xorm:"alarm_status"`
SpecificProblem string `json:"specificProblem"`
SpecificProblemID string `json:"specificProblemID" xorm:"specific_problem_id"`
AddInfo string `json:"addInfo"`
// ClearType int `json:"-" xorm:"clear_type"` // 0: Unclear, 1: Auto clear, 2: Manual clear
// ClearTime sql.NullTime `json:"-" xorm:"clear_time"`
}
var client = resty.New()
func init() {
client.
SetTimeout(time.Duration(400 * time.Millisecond))
}
func (s *BarProcessor) Execute(data any) (any, error) {
var err error
s.count++
options := data.(cron.JobData)
sysJob := options.SysJob
var alarmDefine BarParams
err = json.Unmarshal([]byte(sysJob.TargetParams), &alarmDefine)
if err == nil {
log.Error("Failed to Unmarshal:", err)
return nil, err
}
var nes []dborm.NeInfo
_, err = dborm.XormGetAllNeInfo(&nes)
if err != nil {
log.Error("Failed to get all ne info:", err)
return nil, err
}
succActiveAlarmNum := 0
failActiveAlarmNum := 0
succClearAlarmNum := 0
failClearAlarmNum := 0
for _, ne := range nes {
//log.Debug("ne:", ne)
sql := fmt.Sprintf("select * from ne_state where ne_type = '%s' and ne_id = '%s' order by timestamp desc limit 1", ne.NeType, ne.NeId)
neState, err := dborm.XormGetDataBySQL(sql)
if err != nil {
log.Error("Failed to get ne_state:", err)
continue
}
if len(*neState) == 0 {
log.Warn("Not found record in ne_state:")
continue
}
//log.Debug("neState:", *neState)
// params := "10000"
// alarmDefine, err := dborm.XormGetAlarmDefine(params)
// if err != nil {
// log.Error("Failed to get alarm_define:", err)
// continue
// } else if alarmDefine == nil {
// log.Error("Not found data from alarm_define")
// continue
// }
// log.Debug("alarmDefine:", alarmDefine)
sql = fmt.Sprintf("select * from alarm where alarm_id = '%s' and ne_type='%s' and ne_id = '%s' order by event_time desc limit 1",
alarmDefine.AlarmID, ne.NeType, ne.RmUID)
alarm, err := dborm.XormGetDataBySQL(sql)
if err != nil {
log.Error("Failed to get alarm:", err)
continue
}
//log.Debug("alarm:", *alarm)
var timestamp string
if len(*neState) == 0 {
log.Infof("Not found ne_state neType:%s, neId:%s", ne.NeType, ne.NeId)
timestamp = ne.UpdateTime
} else {
timestamp = (*neState)[0]["timestamp"]
}
// 解析日期时间字符串为时间对象
seconds, err := global.GetSecondsSinceDatetime(timestamp)
if err != nil {
log.Error("Failed to GetSecondsSinceDatetime:", err)
continue
}
log.Debugf("timestamp:%s seconds:%d", timestamp, seconds)
if seconds <= alarmDefine.Threshold {
if len(*alarm) == 0 || (*alarm)[0]["alarm_status"] == fm.AlarmStatusClearString {
continue
}
// clear alarm, todo
var alarmSeq int = 1
threshold := strconv.FormatInt(alarmDefine.Threshold, 10)
SpecificProblem := strings.ReplaceAll(alarmDefine.SpecificProblem, "{threshold}", threshold)
locationInfo := fmt.Sprintf("SystemManagement.State: NE heartbeat timestamp=%sthreshold=%v", timestamp, alarmDefine.Threshold)
alarmData := &Alarm{
AlarmSeq: alarmSeq,
AlarmId: alarmDefine.AlarmID,
NeId: ne.RmUID,
NeType: ne.NeType,
NeName: ne.NeName,
Province: ne.Province,
PVFlag: ne.PvFlag,
AlarmCode: alarmDefine.AlarmCode,
AlarmTitle: alarmDefine.AlarmTitle,
AlarmType: alarmDefine.AlarmType,
AlarmStatus: fm.AlarmStatusClear,
OrigSeverity: alarmDefine.OrigSeverity,
ObjectUid: alarmDefine.ObjectUID,
ObjectName: alarmDefine.ObjectName,
ObjectType: alarmDefine.ObjectType,
LocationInfo: locationInfo,
SpecificProblem: SpecificProblem,
SpecificProblemID: alarmDefine.SpecificProblemID,
AddInfo: alarmDefine.AddInfo,
EventTime: time.Now().Local().Format(time.RFC3339),
}
alarmArray := &[]Alarm{*alarmData}
body, _ := json.Marshal(alarmArray)
//log.Debug("body: ", string(body))
var response *resty.Response
requestURI := fmt.Sprintf("/api/rest/faultManagement/v1/elementType/%s/objectType/alarms", ne.NeType)
restHost := fmt.Sprintf("http://127.0.0.1:%d", config.GetYamlConfig().Rest[0].Port)
requestURL := fmt.Sprintf("%s%s", restHost, requestURI)
log.Debug("requestURL: POST ", requestURL)
response, err = client.R().
EnableTrace().
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
SetBody(body).
Post(requestURL)
if err != nil {
log.Error("Failed to post:", err)
failClearAlarmNum++
continue
}
log.Debug("StatusCode: ", response.StatusCode())
switch response.StatusCode() {
case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
log.Debug("response body:", string(response.Body()))
body := new(map[string]interface{})
_ = json.Unmarshal(response.Body(), &body)
succClearAlarmNum++
default:
log.Debug("response body:", string(response.Body()))
body := new(map[string]interface{})
_ = json.Unmarshal(response.Body(), &body)
failClearAlarmNum++
}
} else {
var alarmSeq int = 1
if len(*alarm) > 0 && (*alarm)[0]["alarm_status"] == fm.AlarmStatusActiveString {
log.Info("System state alarm has exist")
continue
}
threshold := strconv.FormatInt(alarmDefine.Threshold, 10)
SpecificProblem := strings.ReplaceAll(alarmDefine.SpecificProblem, "{threshold}", threshold)
locationInfo := fmt.Sprintf("SystemManagement.State: NE heartbeat timestamp=%sthreshold=%v", timestamp, alarmDefine.Threshold)
alarmData := &Alarm{
AlarmSeq: alarmSeq,
AlarmId: alarmDefine.AlarmID,
NeId: ne.RmUID,
NeType: ne.NeType,
NeName: ne.NeName,
Province: ne.Province,
PVFlag: ne.PvFlag,
AlarmCode: alarmDefine.AlarmCode,
AlarmTitle: alarmDefine.AlarmTitle,
AlarmType: alarmDefine.AlarmType,
AlarmStatus: fm.AlarmStatusActive,
OrigSeverity: alarmDefine.OrigSeverity,
ObjectUid: alarmDefine.ObjectUID,
ObjectName: alarmDefine.ObjectName,
ObjectType: alarmDefine.ObjectType,
LocationInfo: locationInfo,
SpecificProblem: SpecificProblem,
SpecificProblemID: alarmDefine.SpecificProblemID,
AddInfo: alarmDefine.AddInfo,
EventTime: time.Now().Local().Format(time.RFC3339),
}
alarmArray := &[]Alarm{*alarmData}
body, _ := json.Marshal(alarmArray)
//log.Debug("body: ", string(body))
var response *resty.Response
requestURI := fmt.Sprintf("/api/rest/faultManagement/v1/elementType/%s/objectType/alarms", ne.NeType)
restHost := fmt.Sprintf("http://127.0.0.1:%d", config.GetYamlConfig().Rest[0].Port)
requestURL := fmt.Sprintf("%s%s", restHost, requestURI)
log.Debug("requestURL: POST ", requestURL)
response, err = client.R().
EnableTrace().
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
SetBody(body).
Post(requestURL)
if err != nil {
log.Error("Failed to post:", err)
failActiveAlarmNum++
continue
}
log.Debug("StatusCode: ", response.StatusCode())
switch response.StatusCode() {
case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
log.Debug("response body:", string(response.Body()))
body := new(map[string]interface{})
_ = json.Unmarshal(response.Body(), &body)
succActiveAlarmNum++
default:
log.Debug("response body:", string(response.Body()))
body := new(map[string]interface{})
_ = json.Unmarshal(response.Body(), &body)
failActiveAlarmNum++
}
}
}
// 返回结果,用于记录执行结果
return map[string]any{
"succActiveAlarmNum": succActiveAlarmNum,
"failActiveAlarmNum": failActiveAlarmNum,
"succClearAlarmNum": succClearAlarmNum,
"failClearAlarmNum": failClearAlarmNum,
}, nil
}

View File

@@ -0,0 +1,167 @@
package getStateFromNE
import (
"encoding/json"
"fmt"
"net/http"
"strings"
"time"
"ems.agt/lib/dborm"
"ems.agt/lib/log"
"ems.agt/restagent/config"
"github.com/go-resty/resty/v2"
)
var NewProcessor = &BarProcessor{
progress: 0,
count: 0,
}
// bar 队列任务处理
type BarProcessor struct {
// 任务进度
progress int
// 执行次数
count int
}
type BarParams struct {
Duration int `json:"duration"`
}
type CpuUsage struct {
NfCpuUsage uint16 `json:"nfCpuUsage"`
SysCpuUsage uint16 `json:"sysCpuUsage"`
}
type MemUsage struct {
TotalMem uint32 `json:"totalMem"`
NfUsedMem uint32 `json:"nfUsedMem"`
SysMemUsage uint16 `json:"sysMemUsage"`
}
type PartitionInfo struct {
Total uint32 `json:"total"` // MB
Used uint32 `json:"used"` // MB
}
type DiskSpace struct {
PartitionNum uint8 `json:"partitionNum"`
PartitionInfo []PartitionInfo `json:"partitionInfo"`
}
type SystemState struct {
Version string `json:"version"`
Capability uint32 `json:"capability"`
SerialNum string `json:"serialNum"`
ExpiryDate string `json:"expiryDate"`
//Timestamp string `json:"timestamp"`
CpuUsage CpuUsage `json:"cpuUsage"`
MemUsage MemUsage `json:"memUsage"`
DiskSpace DiskSpace `json:"diskSpace"`
}
var client = resty.New()
func init() {
/*
client.
SetTimeout(10 * time.Second).
SetRetryCount(1).
SetRetryWaitTime(1 * time.Second).
SetRetryMaxWaitTime(2 * time.Second).
SetRetryAfter(func(client *resty.Client, resp *resty.Response) (time.Duration, error) {
return 0, errors.New("quota exceeded")
})
*/
client.
SetTimeout(time.Duration(400 * time.Millisecond))
// SetRetryCount(1).
// SetRetryWaitTime(time.Duration(1 * time.Second)).
// SetRetryMaxWaitTime(time.Duration(2 * time.Second))
//client.SetTimeout(2 * time.Second)
}
func (s *BarProcessor) Execute(data any) (any, error) {
var err error
s.count++
// options := data.(cron.JobData)
// // sysJob := options.SysJob
// // var params BarParams
// // // err := json.Unmarshal([]byte(sysJob.TargetParams), &params)
// // // if err == nil {
// // // duration = params.Duration
// // // }
var nes []dborm.NeInfo
_, err = dborm.XormGetAllNeInfo(&nes)
if err != nil {
log.Error("Failed to get all ne info:", err)
return nil, err
}
failNum := 0
succNum := 0
for _, ne := range nes {
requestURI := fmt.Sprintf("/api/rest/systemManagement/v1/elementType/%s/objectType/systemState", strings.ToLower(ne.NeType))
requestURL := fmt.Sprintf("http://%s:%s%s", ne.Ip, ne.Port, requestURI)
log.Debug("requestURL: Get", requestURL)
client := resty.New()
response, err := client.R().
EnableTrace().
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
Get(requestURL)
if err != nil {
log.Error("Failed to Get:", err)
failNum++
continue
}
log.Debug("StatusCode: ", response.StatusCode())
switch response.StatusCode() {
case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
log.Debug("response body:", string(response.Body()))
state := new(SystemState)
_ = json.Unmarshal(response.Body(), &state)
neState := new(dborm.NeState)
neState.NeType = ne.NeType
neState.NeId = ne.NeId
neState.Version = state.Version
neState.Capability = state.Capability
neState.SerialNum = state.SerialNum
neState.ExpiryDate = state.ExpiryDate
cu, _ := json.Marshal(state.CpuUsage)
neState.CpuUsage = string(cu)
mu, _ := json.Marshal(state.MemUsage)
neState.MemUsage = string(mu)
ds, _ := json.Marshal(state.DiskSpace)
neState.DiskSpace = string(ds)
log.Debug("neState:", neState)
_, err := dborm.XormInsertNeState(neState)
if err != nil {
log.Error("Failed to insert ne_state:", err)
failNum++
continue
}
succNum++
default:
log.Debug("response body:", string(response.Body()))
body := new(map[string]interface{})
_ = json.Unmarshal(response.Body(), &body)
failNum++
}
}
// 返回结果,用于记录执行结果
return map[string]any{
"succNum": succNum,
"failNum": failNum,
}, nil
}

View File

@@ -5,6 +5,8 @@ import (
"ems.agt/src/modules/crontask/processor/backupEtcFromNE"
"ems.agt/src/modules/crontask/processor/delExpiredNeBackup"
"ems.agt/src/modules/crontask/processor/deleteExpiredRecord"
"ems.agt/src/modules/crontask/processor/genNeStateAlarm"
"ems.agt/src/modules/crontask/processor/getStateFromNE"
monitorsysresource "ems.agt/src/modules/crontask/processor/monitor_sys_resource"
)
@@ -16,4 +18,6 @@ func InitCronQueue() {
cron.CreateQueue("delExpiredNeBackup", delExpiredNeBackup.NewProcessor)
cron.CreateQueue("deleteExpiredRecord", deleteExpiredRecord.NewProcessor)
cron.CreateQueue("backupEtcFromNE", backupEtcFromNE.NewProcessor)
cron.CreateQueue("getStateFromNE", getStateFromNE.NewProcessor)
cron.CreateQueue("genNeStateAlarm", genNeStateAlarm.NewProcessor)
}

View File

@@ -43,25 +43,9 @@ func (s *SysJobLogController) List(c *gin.Context) {
querys := ctx.QueryMap(c)
data := s.sysJobLogService.SelectJobLogPage(querys)
language := ctx.AcceptLanguage(c)
// 反查多语言key
if v, ok := querys["jobName"]; ok && v != "" {
querys["jobName"] = i18n.ValueKey(language, querys["jobName"].(string))
}
dataI18n := s.sysJobLogService.SelectJobLogPage(querys)
totalI18n := parse.Number(dataI18n["total"])
if totalI18n != 0 {
rows := data["rows"].([]model.SysJobLog)
total := parse.Number(data["total"])
rowsI18n := dataI18n["rows"].([]model.SysJobLog)
data["rows"] = append(rows, rowsI18n...)
data["total"] = total + totalI18n
}
rows := data["rows"].([]model.SysJobLog)
// 闭包函数处理多语言
language := ctx.AcceptLanguage(c)
converI18n := func(language string, arr *[]model.SysJobLog) {
for i := range *arr {
(*arr)[i].JobName = i18n.TKey(language, (*arr)[i].JobName)

View File

@@ -234,9 +234,7 @@ func (r *SysJobImpl) InsertJob(sysJob model.SysJob) string {
if sysJob.InvokeTarget != "" {
params["invoke_target"] = sysJob.InvokeTarget
}
if sysJob.TargetParams != "" {
params["target_params"] = sysJob.TargetParams
}
params["target_params"] = sysJob.TargetParams
if sysJob.CronExpression != "" {
params["cron_expression"] = sysJob.CronExpression
}
@@ -252,9 +250,7 @@ func (r *SysJobImpl) InsertJob(sysJob model.SysJob) string {
if sysJob.SaveLog != "" {
params["save_log"] = sysJob.SaveLog
}
if sysJob.Remark != "" {
params["remark"] = sysJob.Remark
}
params["remark"] = sysJob.Remark
if sysJob.CreateBy != "" {
params["create_by"] = sysJob.CreateBy
params["create_time"] = time.Now().UnixMilli()
@@ -300,9 +296,7 @@ func (r *SysJobImpl) UpdateJob(sysJob model.SysJob) int64 {
if sysJob.InvokeTarget != "" {
params["invoke_target"] = sysJob.InvokeTarget
}
if sysJob.TargetParams != "" {
params["target_params"] = sysJob.TargetParams
}
params["target_params"] = sysJob.TargetParams
if sysJob.CronExpression != "" {
params["cron_expression"] = sysJob.CronExpression
}
@@ -318,9 +312,7 @@ func (r *SysJobImpl) UpdateJob(sysJob model.SysJob) int64 {
if sysJob.SaveLog != "" {
params["save_log"] = sysJob.SaveLog
}
if sysJob.Remark != "" {
params["remark"] = sysJob.Remark
}
params["remark"] = sysJob.Remark
if sysJob.UpdateBy != "" {
params["update_by"] = sysJob.UpdateBy
params["update_time"] = time.Now().UnixMilli()

View File

@@ -5,6 +5,7 @@ import (
"ems.agt/src/framework/i18n"
"ems.agt/src/framework/utils/ctx"
"ems.agt/src/framework/vo/result"
"ems.agt/src/modules/network_element/model"
neService "ems.agt/src/modules/network_element/service"
"github.com/gin-gonic/gin"
)
@@ -30,13 +31,7 @@ type PerfKPIController struct {
// GET /data
func (s *PerfKPIController) GoldKPI(c *gin.Context) {
language := ctx.AcceptLanguage(c)
var querys struct {
NeType string `form:"neType" binding:"required"`
NeID string `form:"neId" binding:"required"`
StartTime string `form:"startTime" binding:"required"`
EndTime string `form:"endTime" binding:"required"`
Interval int64 `form:"interval" binding:"required"`
}
var querys model.GoldKPIQuery
if err := c.ShouldBindQuery(&querys); err != nil {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
@@ -47,12 +42,10 @@ func (s *PerfKPIController) GoldKPI(c *gin.Context) {
if startTime.IsZero() {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
}
startTimeStr := startTime.Format(date.YYYY_MM_DD_HH_MM_SS)
endTime := date.ParseStrToDate(querys.EndTime, date.YYYY_MM_DD_HH_MM_SS)
if startTime.IsZero() {
if endTime.IsZero() {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
}
endTimeStr := endTime.Format(date.YYYY_MM_DD_HH_MM_SS)
// 查询网元获取IP
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(querys.NeType, querys.NeID)
@@ -60,16 +53,10 @@ func (s *PerfKPIController) GoldKPI(c *gin.Context) {
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
return
}
// 获取数据指标id
var kpiIds []string
kpiTitles := s.perfKPIService.SelectGoldKPITitle(neInfo.NeType)
for _, kpiId := range kpiTitles {
kpiIds = append(kpiIds, kpiId.KPIID)
}
querys.RmUID = neInfo.RmUID
// 查询数据
kpiData := s.perfKPIService.SelectGoldKPI(neInfo.RmUID, neInfo.NeType, startTimeStr, endTimeStr, kpiIds, querys.Interval)
kpiData := s.perfKPIService.SelectGoldKPI(querys)
c.JSON(200, result.OkData(kpiData))
}

View File

@@ -11,6 +11,7 @@ import (
"ems.agt/src/framework/i18n"
"ems.agt/src/framework/utils/ctx"
"ems.agt/src/framework/utils/file"
"ems.agt/src/framework/utils/parse"
"ems.agt/src/framework/utils/ssh"
"ems.agt/src/framework/vo/result"
"ems.agt/src/modules/network_element/model"
@@ -270,6 +271,14 @@ func (s *UDMAuthController) Remove(c *gin.Context) {
return
}
// 处理字符转id数组后去重
imsiArr := strings.Split(imsi, ",")
uniqueIDs := parse.RemoveDuplicates(imsiArr)
if len(uniqueIDs) <= 0 {
c.JSON(200, result.Err(nil))
return
}
// 查询网元获取IP
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("UDM", neId)
if neInfo.NeId != neId || neInfo.IP == "" {
@@ -277,21 +286,24 @@ func (s *UDMAuthController) Remove(c *gin.Context) {
return
}
msg := fmt.Sprintf("del authdat:imsi=%s", imsi)
resultData := map[string]string{}
for _, imsi := range uniqueIDs {
msg := fmt.Sprintf("del authdat:imsi=%s", imsi)
// 发送MML
data, err := mmlclient.MMLSendMsgToString(neInfo.IP, msg)
if err != nil {
c.JSON(200, result.ErrMsg(err.Error()))
return
// 发送MML
data, err := mmlclient.MMLSendMsgToString(neInfo.IP, msg)
if err != nil {
resultData[imsi] = err.Error()
}
// 命令ok时
if strings.Contains(data, "ok") {
neId = ""
s.udmAuthService.Delete(neId, imsi)
resultData[imsi] = data
}
}
// 命令ok时
if strings.Contains(data, "ok") {
neId = ""
s.udmAuthService.Delete(neId, imsi)
}
c.JSON(200, result.OkData(data))
c.JSON(200, result.OkData(resultData))
}
// UDM鉴权用户-批量删除
@@ -347,7 +359,7 @@ func (s *UDMAuthController) Export(c *gin.Context) {
}
if !(body.Type == "csv" || body.Type == "txt") {
c.JSON(200, result.ErrMsg(i18n.TKey(language, "ne.udm.errImportFileFormat")))
c.JSON(200, result.ErrMsg(i18n.TKey(language, "ne.udm.errImportUserAuthFileFormat")))
return
}

View File

@@ -12,6 +12,7 @@ import (
"ems.agt/src/framework/i18n"
"ems.agt/src/framework/utils/ctx"
"ems.agt/src/framework/utils/file"
"ems.agt/src/framework/utils/parse"
"ems.agt/src/framework/utils/ssh"
"ems.agt/src/framework/vo/result"
"ems.agt/src/modules/network_element/model"
@@ -346,6 +347,14 @@ func (s *UDMSubController) Remove(c *gin.Context) {
return
}
// 处理字符转id数组后去重
imsiArr := strings.Split(imsi, ",")
uniqueIDs := parse.RemoveDuplicates(imsiArr)
if len(uniqueIDs) <= 0 {
c.JSON(200, result.Err(nil))
return
}
// 查询网元获取IP
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("UDM", neId)
if neInfo.NeId != neId || neInfo.IP == "" {
@@ -353,21 +362,24 @@ func (s *UDMSubController) Remove(c *gin.Context) {
return
}
msg := fmt.Sprintf("del udmuser:imsi=%s", imsi)
resultData := map[string]string{}
for _, imsi := range uniqueIDs {
msg := fmt.Sprintf("del udmuser:imsi=%s", imsi)
// 发送MML
data, err := mmlclient.MMLSendMsgToString(neInfo.IP, msg)
if err != nil {
c.JSON(200, result.ErrMsg(err.Error()))
return
// 发送MML
data, err := mmlclient.MMLSendMsgToString(neInfo.IP, msg)
if err != nil {
resultData[imsi] = err.Error()
}
// 命令ok时
if strings.Contains(data, "ok") {
neId = ""
s.udmSubService.Delete(neId, imsi)
resultData[imsi] = data
}
}
// 命令ok时
if strings.Contains(data, "ok") {
neId = ""
s.udmSubService.Delete(neId, imsi)
}
c.JSON(200, result.OkData(data))
c.JSON(200, result.OkData(resultData))
}
// UDM签约用户-批量删除
@@ -423,7 +435,7 @@ func (s *UDMSubController) Export(c *gin.Context) {
}
if !(body.Type == "csv" || body.Type == "txt") {
c.JSON(200, result.ErrMsg(i18n.TKey(language, "ne.udm.errImportFileFormat")))
c.JSON(200, result.ErrMsg(i18n.TKey(language, "ne.udm.errImportUserSubFileFormat")))
return
}

View File

@@ -9,3 +9,15 @@ type GoldKPITitle struct {
CnTitle string `json:"cnTitle" gorm:"column:cn_title"`
EnTitle string `json:"enTitle" gorm:"column:en_title"`
}
// GoldKPIQuery 黄金指标查询参数结构体
type GoldKPIQuery struct {
NeType string `form:"neType" binding:"required"`
NeID string `form:"neId" binding:"required"`
StartTime string `form:"startTime" binding:"required"`
EndTime string `form:"endTime" binding:"required"`
Interval int64 `form:"interval" binding:"required"`
RmUID string `form:"rmUID"`
SortField string `form:"sortField" binding:"omitempty,oneof=timeGroup"`
SortOrder string `form:"sortOrder" binding:"omitempty,oneof=asc desc"`
}

View File

@@ -4,8 +4,8 @@ import "ems.agt/src/modules/network_element/model"
// 性能统计 数据层接口
type IPerfKPI interface {
// SelectGoldKPI 通过ne_type和ne_id查询网元信息
SelectGoldKPI(rmUID, neType string, startTime, endTime string, kpiIds []string, interval int64) []map[string]any
// SelectGoldKPI 通过网元指标数据信息
SelectGoldKPI(query model.GoldKPIQuery, kpiIds []string) []map[string]any
// SelectGoldKPITitle
SelectGoldKPITitle(neType string) []model.GoldKPITitle

View File

@@ -16,25 +16,25 @@ var NewPerfKPIImpl = &PerfKPIImpl{}
type PerfKPIImpl struct{}
// SelectGoldKPI 通过网元指标数据信息
func (r *PerfKPIImpl) SelectGoldKPI(rmUID, neType string, startTime, endTime string, kpiIds []string, interval int64) []map[string]any {
func (r *PerfKPIImpl) SelectGoldKPI(query model.GoldKPIQuery, kpiIds []string) []map[string]any {
// 查询条件拼接
var conditions []string
var params []any
if rmUID != "" {
if query.RmUID != "" {
conditions = append(conditions, "gk.rm_uid = ?")
params = append(params, rmUID)
params = append(params, query.RmUID)
}
if neType != "" {
if query.NeType != "" {
conditions = append(conditions, "gk.ne_type = ?")
params = append(params, neType)
params = append(params, query.NeType)
}
if startTime != "" {
if query.StartTime != "" {
conditions = append(conditions, "gk.start_time >= ?")
params = append(params, startTime)
params = append(params, query.StartTime)
}
if endTime != "" {
if query.EndTime != "" {
conditions = append(conditions, "gk.start_time <= ?")
params = append(params, endTime)
params = append(params, query.EndTime)
}
// 构建查询条件语句
whereSql := ""
@@ -44,7 +44,7 @@ func (r *PerfKPIImpl) SelectGoldKPI(rmUID, neType string, startTime, endTime str
// 查询字段列
timeFormat := "DATE_FORMAT(gk.start_time, '%Y-%m-%d %H:')"
minuteGroup := fmt.Sprintf("LPAD(FLOOR(MINUTE(gk.start_time) / %d) * %d, 2, '0')", interval, interval)
minuteGroup := fmt.Sprintf("LPAD(FLOOR(MINUTE(gk.start_time) / %d) * %d, 2, '0')", query.Interval, query.Interval)
groupByField := fmt.Sprintf("CONCAT( %s, %s ) AS timeGroup", timeFormat, minuteGroup)
var fields = []string{
groupByField,
@@ -58,7 +58,14 @@ func (r *PerfKPIImpl) SelectGoldKPI(rmUID, neType string, startTime, endTime str
fieldsSql := strings.Join(fields, ",")
// 查询数据
querySql := fmt.Sprintf("SELECT %s FROM gold_kpi gk %s GROUP BY timeGroup", fieldsSql, whereSql)
if query.SortField == "" {
query.SortField = "timeGroup"
}
if query.SortOrder == "" {
query.SortOrder = "desc"
}
orderSql := fmt.Sprintf(" order by %s %s", query.SortField, query.SortOrder)
querySql := fmt.Sprintf("SELECT %s FROM gold_kpi gk %s GROUP BY timeGroup %s", fieldsSql, whereSql, orderSql)
results, err := datasource.RawDB("", querySql, params)
if err != nil {
logger.Errorf("query err => %v", err)

View File

@@ -4,8 +4,8 @@ import "ems.agt/src/modules/network_element/model"
// 性能统计 数据层接口
type IPerfKPI interface {
// SelectGoldKPI 通过ne_type和ne_id查询网元信息
SelectGoldKPI(rmUID, neType string, startTime, endTime string, kpiIds []string, interval int64) []map[string]any
// SelectGoldKPI 通过网元指标数据信息
SelectGoldKPI(query model.GoldKPIQuery) []map[string]any
// SelectGoldKPITitle
SelectGoldKPITitle(neType string) []model.GoldKPITitle

View File

@@ -17,8 +17,15 @@ type PerfKPIImpl struct {
}
// SelectGoldKPI 通过网元指标数据信息
func (r *PerfKPIImpl) SelectGoldKPI(rmUID, neType string, startTime, endTime string, kpiIds []string, interval int64) []map[string]any {
data := r.perfKPIRepository.SelectGoldKPI(rmUID, neType, startTime, endTime, kpiIds, interval)
func (r *PerfKPIImpl) SelectGoldKPI(query model.GoldKPIQuery) []map[string]any {
// 获取数据指标id
var kpiIds []string
kpiTitles := r.perfKPIRepository.SelectGoldKPITitle(query.NeType)
for _, kpiId := range kpiTitles {
kpiIds = append(kpiIds, kpiId.KPIID)
}
data := r.perfKPIRepository.SelectGoldKPI(query, kpiIds)
if data == nil {
return []map[string]any{}
}

View File

@@ -57,12 +57,10 @@ func (r *SysRoleImpl) SelectRoleById(roleId string) model.SysRole {
// UpdateRole 修改角色信息
func (r *SysRoleImpl) UpdateRole(sysRole model.SysRole) int64 {
rows := r.sysRoleRepository.UpdateRole(sysRole)
if rows > 0 {
if rows > 0 && len(sysRole.MenuIds) > 0 {
// 删除角色与菜单关联
r.sysRoleMenuRepository.DeleteRoleMenu([]string{sysRole.RoleID})
if len(sysRole.MenuIds) > 0 {
r.insertRoleMenu(sysRole.RoleID, sysRole.MenuIds)
}
r.insertRoleMenu(sysRole.RoleID, sysRole.MenuIds)
}
return rows
}

View File

@@ -1,7 +1,7 @@
# Makefile for OMC-OMC-crontask project
PROJECT = OMC
VERSION = 2.2312.9
VERSION = 2.2312.10
LIBDIR = ems.agt/lib
BINNAME = sshsvc