1
0

marge: 合并代码

This commit is contained in:
TsMask
2023-12-29 20:22:43 +08:00
parent 615ab2eb2e
commit 3c5c77b881
39 changed files with 1571 additions and 289 deletions

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

@@ -225,7 +225,7 @@ func UploadSoftwareMultiFile(w http.ResponseWriter, r *http.Request) {
//fileName, err := services.HandleUploadFile(r, softwarePath, "")
// 解析multipart/form-data请求
err = r.ParseMultipartForm(200 << 20) // 200MB
err = r.ParseMultipartForm(1000 << 20) // 1000MB
if err != nil {
log.Error("Faile to ParseMultipartForm:", err)
services.ResponseInternalServerError500ProcessError(w, err)

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 {
@@ -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 {
@@ -342,7 +358,7 @@ func GetAllLicenseInfoFromNF(w http.ResponseWriter, r *http.Request) {
}
log.Debug("requestURI2NF:", requestURI2NF)
resp, err := client.R().
resp, err := client.SetTimeout(time.Duration(1 * time.Second)).R().
EnableTrace().
SetHeaders(map[string]string{tokenConst.HEADER_KEY: r.Header.Get(tokenConst.HEADER_KEY)}).
SetHeaders(map[string]string{"accessToken": token}).
@@ -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 {
@@ -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 {
@@ -596,7 +629,7 @@ func GetAllSysinfoFromNF(w http.ResponseWriter, r *http.Request) {
}
log.Debug("requestURI2NF:", requestURI2NF)
resp, err := client.R().
resp, err := client.SetTimeout(time.Duration(1 * time.Second)).R().
EnableTrace().
SetHeaders(map[string]string{tokenConst.HEADER_KEY: r.Header.Get(tokenConst.HEADER_KEY)}).
SetHeaders(map[string]string{"accessToken": token}).
@@ -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)
@@ -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

@@ -5,6 +5,7 @@ import (
"fmt"
"io"
"net/http"
"strings"
"time"
"ems.agt/lib/dborm"
@@ -79,6 +80,8 @@ var (
UriPCFUserM = config.DefaultUriPrefix + "/ueManagement/{apiVersion}/elementType/pcf/objectType/ueInfo/batch/{number}"
UriPCFUserFileImport = config.DefaultUriPrefix + "/ueManagement/{apiVersion}/elementType/pcf/objectType/ueInfo/file/import"
UriPCFUserFileExport = config.DefaultUriPrefix + "/ueManagement/{apiVersion}/elementType/pcf/objectType/ueInfo/file/export"
UriNSSFAvailableAMFs = config.DefaultUriPrefix + "/ueManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/availableAMFs"
UriNSSFSubscriptions = config.DefaultUriPrefix + "/ueManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/subscriptions"
CustomUriNBInfo = config.UriPrefix + "/ueManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/nbInfo"
CustomUriUEInfo = config.UriPrefix + "/ueManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/ueInfo"
@@ -87,6 +90,8 @@ var (
CustomUriPCFUserM = config.UriPrefix + "/ueManagement/{apiVersion}/elementType/pcf/objectType/ueInfo/batch/{number}"
CustomUriPCFUserFileImport = config.UriPrefix + "/ueManagement/{apiVersion}/elementType/pcf/objectType/ueInfo/file/import"
CustomUriPCFUserFileExport = config.UriPrefix + "/ueManagement/{apiVersion}/elementType/pcf/objectType/ueInfo/file/export"
CustomUriNSSFAvailableAMFs = config.UriPrefix + "/ueManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/availableAMFs"
CustomUriNSSFSubscriptions = config.UriPrefix + "/ueManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/subscriptions"
)
var client = resty.New()
@@ -105,6 +110,134 @@ func init() {
client.SetTimeout(3 * time.Second)
}
// Get AvailableAMFs from NSSF
func GetAvailableAMFsFromNSSF(w http.ResponseWriter, r *http.Request) {
log.Info("GetAvailableAMFsFromNSSF processing... ")
vars := mux.Vars(r)
neType := vars["elementTypeValue"]
if strings.ToLower(neType) != "nssf" {
services.ResponseNotFound404UriNotExist(w, r)
return
}
//neTypeLower := strings.ToLower(neType)
var neId string
neIds := services.GetParamsArrByName("neId", r)
if len(neIds) == 1 {
neId = neIds[0]
} else {
services.ResponseNotFound404UriNotExist(w, r)
return
}
token, err := services.CheckFrontValidRequest(w, r)
if err != nil {
log.Error("Request error:", err)
return
}
log.Debug("token:", token)
neInfo, err := dborm.XormGetNeInfo(neType, neId)
if err != nil {
log.Error("Failed to XormGetNeInfo:", err)
services.ResponseInternalServerError500ProcessError(w, err)
return
} else if neInfo == nil {
err := global.ErrCMNotFoundTargetNE
log.Error(global.ErrCMNotFoundTargetNE)
services.ResponseInternalServerError500ProcessError(w, err)
return
}
log.Trace("neInfo:", neInfo)
hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
requestURI2NF := fmt.Sprintf("%s%s", hostUri, r.RequestURI)
log.Debug("requestURI2NF:", requestURI2NF)
resp, err := client.R().
EnableTrace().
SetHeaders(map[string]string{tokenConst.HEADER_KEY: r.Header.Get(tokenConst.HEADER_KEY)}).
SetHeaders(map[string]string{"accessToken": token}).
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
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)
services.ResponseInternalServerError500ProcessError(w, err)
return
} else {
var response services.MapResponse
_ = json.Unmarshal(resp.Body(), &response)
services.ResponseWithJson(w, resp.StatusCode(), response)
return
}
}
// Get Subscriptions from NSSF
func GetSubscriptionsFromNSSF(w http.ResponseWriter, r *http.Request) {
log.Info("GetSubscriptionsFromNSSF processing... ")
vars := mux.Vars(r)
neType := vars["elementTypeValue"]
if strings.ToLower(neType) != "nssf" {
services.ResponseNotFound404UriNotExist(w, r)
return
}
//neTypeLower := strings.ToLower(neType)
var neId string
neIds := services.GetParamsArrByName("neId", r)
if len(neIds) == 1 {
neId = neIds[0]
} else {
services.ResponseNotFound404UriNotExist(w, r)
return
}
token, err := services.CheckFrontValidRequest(w, r)
if err != nil {
log.Error("Request error:", err)
return
}
log.Debug("token:", token)
neInfo, err := dborm.XormGetNeInfo(neType, neId)
if err != nil {
log.Error("Failed to XormGetNeInfo:", err)
services.ResponseInternalServerError500ProcessError(w, err)
return
} else if neInfo == nil {
err := global.ErrCMNotFoundTargetNE
log.Error(global.ErrCMNotFoundTargetNE)
services.ResponseInternalServerError500ProcessError(w, err)
return
}
log.Trace("neInfo:", neInfo)
hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
requestURI2NF := fmt.Sprintf("%s%s", hostUri, r.RequestURI)
log.Debug("requestURI2NF:", requestURI2NF)
resp, err := client.R().
EnableTrace().
SetHeaders(map[string]string{tokenConst.HEADER_KEY: r.Header.Get(tokenConst.HEADER_KEY)}).
SetHeaders(map[string]string{"accessToken": token}).
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
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)
services.ResponseInternalServerError500ProcessError(w, err)
return
} else {
var response services.MapResponse
_ = json.Unmarshal(resp.Body(), &response)
services.ResponseWithJson(w, resp.StatusCode(), response)
return
}
}
// Get UEInfo from NF/NFs
func GetUEInfoFromNF(w http.ResponseWriter, r *http.Request) {
log.Info("GetUEInfoFromNF processing... ")

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

@@ -287,6 +287,14 @@ func init() {
Register("GET", ue.UriNBInfo, ue.GetNBInfoFromNF, nil)
Register("GET", ue.CustomUriNBInfo, ue.GetNBInfoFromNF, nil)
// NSSF AvailableAMFs
Register("GET", ue.UriNSSFAvailableAMFs, ue.GetAvailableAMFsFromNSSF, nil)
Register("GET", ue.CustomUriNSSFAvailableAMFs, ue.GetAvailableAMFsFromNSSF, nil)
// NSSF Subscriptions
Register("GET", ue.UriNSSFSubscriptions, ue.GetSubscriptionsFromNSSF, nil)
Register("GET", ue.CustomUriNSSFSubscriptions, ue.GetSubscriptionsFromNSSF, nil)
// 进程网络
Register("GET", psnet.UriWs, psnet.ProcessWs, nil)
Register("POST", psnet.UriStop, psnet.StopProcess, nil)

View File

@@ -38,7 +38,7 @@ database:
type: mysql
user: root
# password: "1000omc@kp!"
# host: "192.168.5.57"
# host: "192.168.2.166"
# port: 33066
# name: omc_db
backup: d:/local.git/ems.agt/restagent/database
@@ -62,7 +62,7 @@ redis:
password: ""
db: 0 # Redis db_num
# 多个数据源时可以用这个指定默认的数据源
defaultDataSourceName: "default"
defaultDataSourceName: "default"
# upfHeaderLength: spare upf buffer, must destroy
mml:
@@ -76,7 +76,7 @@ mml:
# NE config
ne:
user: agtuser
user: root
etcdir: /usr/local/etc
bindir: /usr/local/bin
omcdir: /usr/local/omc
@@ -97,7 +97,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.8
VERSION = 2.2312.10
PLATFORM = amd64
ARMPLATFORM = aarch64
BUILDDIR = ../../build

View File

@@ -197,7 +197,15 @@ func main() {
} else {
go HttpListen(listen, app)
}
}
if rest.IPv4 != "0.0.0.0" {
// 默认启动localhost侦听
listenLocal := "127.0.0.1" + ":" + strconv.Itoa(int(rest.Port))
if strings.ToLower(rest.Scheme) == "https" {
go HttpListenTLS(listenLocal, rest.CaFile, rest.CertFile, rest.KeyFile, app)
} else {
go HttpListen(listenLocal, app)
}
}
// ipv6 goroutines
if rest.IPv6 != "" {
@@ -208,6 +216,16 @@ func main() {
go HttpListen(listenv6, app)
}
}
// if rest.IPv6 != "::" {
// // 默认启动localhost侦听
// listenv6Local := "[" + "::1" + "]" + ":" + strconv.Itoa(int(rest.Port))
// if strings.ToLower(rest.Scheme) == "https" {
// go HttpListenTLS(listenv6Local, rest.CaFile, rest.CertFile, rest.KeyFile, app)
// } else {
// go HttpListen(listenv6Local, app)
// }
// }
}
if conf.WebServer.Enabled {

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,243 @@
package fetch
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"mime/multipart"
"net/http"
"net/url"
"os"
"strings"
"time"
)
// Get 发送 GET 请求
// timeout 超时时间(秒)
func Get(url string, headers map[string]string, timeout uint8) ([]byte, error) {
if timeout < 1 || timeout > 180 {
timeout = 1
}
client := &http.Client{
Timeout: time.Duration(timeout) * time.Second, // 设置超时时间为 5 秒
}
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, err
}
for key, value := range headers {
req.Header.Set(key, value)
}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, errors.New(resp.Status)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return body, nil
}
// Post 发送 POST 请求
func Post(url string, data url.Values, headers map[string]string) ([]byte, error) {
client := &http.Client{}
req, err := http.NewRequest("POST", url, strings.NewReader(data.Encode()))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
for key, value := range headers {
req.Header.Set(key, value)
}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, errors.New(resp.Status)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return body, nil
}
// PostJSON 发送 POST 请求,并将请求体序列化为 JSON 格式
func PostJSON(url string, data any, headers map[string]string) ([]byte, error) {
client := &http.Client{}
jsonData, err := json.Marshal(data)
if err != nil {
return nil, err
}
req, err := http.NewRequest("POST", url, bytes.NewReader(jsonData))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
for key, value := range headers {
req.Header.Set(key, value)
}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, errors.New(resp.Status)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return body, nil
}
// UploadFile 上传文件函数,接收 URL 地址、表单参数和文件对象,返回响应内容或错误信息
func PostUploadFile(url string, params map[string]string, file *os.File) ([]byte, error) {
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
part, err := writer.CreateFormFile("file", file.Name())
if err != nil {
return nil, fmt.Errorf("failed to create form file: %v", err)
}
_, err = io.Copy(part, file)
if err != nil {
return nil, fmt.Errorf("failed to copy file content: %v", err)
}
for key, value := range params {
err = writer.WriteField(key, value)
if err != nil {
return nil, fmt.Errorf("failed to write form field: %v", err)
}
}
err = writer.Close()
if err != nil {
return nil, fmt.Errorf("failed to close writer: %v", err)
}
req, err := http.NewRequest("POST", url, body)
if err != nil {
return nil, fmt.Errorf("failed to create HTTP request: %v", err)
}
req.Header.Set("Content-Type", writer.FormDataContentType())
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("HTTP request failed: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("HTTP request returned status: %s", resp.Status)
}
responseBody, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to read response body: %v", err)
}
return responseBody, nil
}
// PutJSON 发送 PUT 请求,并将请求体序列化为 JSON 格式
func PutJSON(url string, data any, headers map[string]string) ([]byte, error) {
client := &http.Client{}
jsonData, err := json.Marshal(data)
if err != nil {
return nil, err
}
req, err := http.NewRequest("PUT", url, bytes.NewReader(jsonData))
if err != nil {
return nil, err
}
for key, value := range headers {
req.Header.Set(key, value)
}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, errors.New(resp.Status)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return body, nil
}
// Delete 发送 DELETE 请求
func Delete(url string, headers map[string]string) ([]byte, error) {
client := &http.Client{}
req, err := http.NewRequest("DELETE", url, nil)
if err != nil {
return nil, err
}
for key, value := range headers {
req.Header.Set(key, value)
}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, errors.New(resp.Status)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return body, nil
}

View File

@@ -1,6 +1,10 @@
package service
import (
"fmt"
"ems.agt/lib/global"
"ems.agt/src/framework/config"
systemService "ems.agt/src/modules/system/service"
)
@@ -21,6 +25,12 @@ type CommontImpl struct {
// SystemConfigInfo 系统配置信息
func (s *CommontImpl) SystemConfigInfo() map[string]string {
infoMap := map[string]string{}
// 获取打包注入的全局变量信息
infoMap["version"] = global.Version
infoMap["buildTime"] = global.BuildTime
infoMap["goVer"] = global.GoVer
// 序列号
infoMap["serialNum"] = fmt.Sprint(config.Get("omc.sn"))
// 获取LOGO类型
logoType := s.sysConfigService.SelectConfigValueByKey("sys.logo.type")
infoMap["logoType"] = logoType

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,22 +43,9 @@ func (s *SysJobLogController) List(c *gin.Context) {
querys := ctx.QueryMap(c)
data := s.sysJobLogService.SelectJobLogPage(querys)
language := ctx.AcceptLanguage(c)
// 反查多语言key
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

@@ -3,7 +3,9 @@ package controller
import (
"ems.agt/src/framework/i18n"
"ems.agt/src/framework/utils/ctx"
"ems.agt/src/framework/utils/parse"
"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"
)
@@ -21,22 +23,86 @@ type NeInfoController struct {
neInfoService neService.INeInfo
}
// 网元状态
//
// GET /state
func (s *NeInfoController) NeState(c *gin.Context) {
language := ctx.AcceptLanguage(c)
var querys struct {
NeType string `form:"neType" binding:"required"`
NeID string `form:"neId" binding:"required"`
}
if err := c.ShouldBindQuery(&querys); err != nil {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(querys.NeType, querys.NeID)
if neInfo.NeId != querys.NeID || neInfo.IP == "" {
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
return
}
// 网元直连
resData, err := neService.NeState(neInfo)
if err != nil {
c.JSON(200, result.ErrMsg("connection failure"))
return
}
c.JSON(200, result.OkData(resData))
}
// 网元neType和neID查询
//
// GET /info
func (s *NeInfoController) NeTypeAndID(c *gin.Context) {
language := ctx.AcceptLanguage(c)
neType := c.Query("neType")
neId := c.Query("neId")
if neType == "" || neId == "" {
var querys struct {
NeType string `form:"neType" binding:"required"`
NeID string `form:"neId" binding:"required"`
}
if err := c.ShouldBindQuery(&querys); err != nil {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(neType, neId)
if neInfo.NeId != neId || neInfo.IP == "" {
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(querys.NeType, querys.NeID)
if neInfo.NeId != querys.NeID || neInfo.IP == "" {
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
return
}
c.JSON(200, result.OkData(neInfo))
}
// 网元列表
//
// GET /list
func (s *NeInfoController) NeList(c *gin.Context) {
language := ctx.AcceptLanguage(c)
var querys struct {
NeType string `form:"neType"`
NeId string `form:"neId"`
BandStatus string `form:"bandStatus"`
}
if err := c.ShouldBindQuery(&querys); err != nil {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
// 查询实体参数
ne := model.NeInfo{}
if querys.NeType != "" {
ne.NeType = querys.NeType
}
if querys.NeId != "" {
ne.NeId = querys.NeId
}
bandStatus := parse.Boolean(querys.BandStatus)
neList := s.neInfoService.SelectNeList(ne, bandStatus)
if len(neList) == 0 {
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
return
}
c.JSON(200, result.OkData(neList))
}

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"
@@ -89,6 +90,11 @@ func (s *UDMAuthController) Info(c *gin.Context) {
return
}
if len(data) == 0 {
c.JSON(200, result.ErrMsg("No Auth Data"))
return
}
// 查询数据库是否存在并存入
neId = ""
var userInfo model.UDMAuth
@@ -265,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 == "" {
@@ -272,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鉴权用户-批量删除
@@ -342,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"
@@ -90,6 +91,11 @@ func (s *UDMSubController) Info(c *gin.Context) {
return
}
if len(data) == 0 {
c.JSON(200, result.ErrMsg("No Subs Data"))
return
}
// 解析返回的数据
cnType, _ := strconv.ParseInt(data["CNType"][:4], 0, 64)
rat, _ := strconv.ParseInt(data["RAT"][:4], 0, 64)
@@ -341,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 == "" {
@@ -348,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签约用户-批量删除
@@ -418,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

@@ -16,4 +16,9 @@ type NeInfo struct {
NeAddress string `json:"neAddress"`
Status string `json:"status"` // 0: 在线 1: 下线 2: 备用 3: 工程
UpdateTime string `json:"updateTime"`
// ====== 非数据库字段属性 ======
// 服务状态
ServerState map[string]any `json:"serverState,omitempty"`
}

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

@@ -20,6 +20,14 @@ func Setup(router *gin.Engine) {
middleware.PreAuthorize(nil),
controller.NewNeInfo.NeTypeAndID,
)
neGroup.GET("/state",
middleware.PreAuthorize(nil),
controller.NewNeInfo.NeState,
)
neGroup.GET("/list",
middleware.PreAuthorize(nil),
controller.NewNeInfo.NeList,
)
}
// 网元处理

View File

@@ -8,4 +8,7 @@ import (
type INeInfo interface {
// SelectNeInfoByNeTypeAndNeID 通过ne_type和ne_id查询网元信息
SelectNeInfoByNeTypeAndNeID(neType, neID string) model.NeInfo
// SelectNeList 查询网元列表
SelectNeList(ne model.NeInfo) []model.NeInfo
}

View File

@@ -1,12 +1,33 @@
package repository
import (
"sort"
"strings"
"ems.agt/src/framework/datasource"
"ems.agt/src/framework/logger"
"ems.agt/src/framework/utils/repo"
"ems.agt/src/modules/network_element/model"
)
// neListSort 网元列表预设排序
var neListSort = []string{
"OMC",
"MME",
"AMF",
"AUSF",
"UDM",
"SMF",
"PCF",
"UPF",
"NRF",
"NSSF",
"IMS",
"N3IWF",
"NEF",
"LMF",
}
// 实例化数据层 NeInfoImpl 结构体
var NewNeInfoImpl = &NeInfoImpl{
selectSql: `select id, ne_type, ne_id, rm_uid, ne_name, ip, port, pv_flag, province, vendor_name, dn, ne_address, status, update_time from ne_info`,
@@ -49,6 +70,31 @@ func (r *NeInfoImpl) convertResultRows(rows []map[string]any) []model.NeInfo {
}
arr = append(arr, item)
}
// 排序
sort.Slice(arr, func(i, j int) bool {
// 前一个
after := arr[i]
afterIndex := 0
for i, v := range neListSort {
if after.NeType == v {
afterIndex = i
break
}
}
// 后一个
befter := arr[j]
befterIndex := 0
for i, v := range neListSort {
if befter.NeType == v {
befterIndex = i
break
}
}
// 升序
return afterIndex < befterIndex
})
return arr
}
@@ -67,3 +113,34 @@ func (r *NeInfoImpl) SelectNeInfoByNeTypeAndNeID(neType, neID string) model.NeIn
}
return model.NeInfo{}
}
// SelectNeList 查询网元列表
func (r *NeInfoImpl) SelectNeList(ne model.NeInfo) []model.NeInfo {
// 查询条件拼接
var conditions []string
var params []any
if ne.NeType != "" {
conditions = append(conditions, "ne_type = ?")
params = append(params, ne.NeType)
}
if ne.NeId != "" {
conditions = append(conditions, "ne_id = ?")
params = append(params, ne.NeId)
}
// 构建查询条件语句
whereSql := ""
if len(conditions) > 0 {
whereSql += " where " + strings.Join(conditions, " and ")
}
// 查询数据
querySql := r.selectSql + whereSql + " order by ne_type asc "
results, err := datasource.RawDB("", querySql, params)
if err != nil {
logger.Errorf("query err => %v", err)
}
// 转换实体
return r.convertResultRows(results)
}

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

@@ -0,0 +1,44 @@
package service
import (
"encoding/json"
"fmt"
"strings"
"time"
"ems.agt/src/framework/logger"
"ems.agt/src/framework/utils/fetch"
"ems.agt/src/modules/network_element/model"
)
// NeState 获取网元端服务状态
func NeState(neInfo model.NeInfo) (map[string]any, error) {
// 网元直连
neUrl := fmt.Sprintf("http://%s:%d/api/rest/systemManagement/v1/elementType/%s/objectType/systemState", neInfo.IP, neInfo.Port, strings.ToLower(neInfo.NeType))
resBytes, err := fetch.Get(neUrl, nil, 1)
if err != nil {
logger.Warnf("NeState %s", err.Error())
return nil, err
}
// 序列化结果
var resData map[string]any
err = json.Unmarshal(resBytes, &resData)
if err != nil {
logger.Warnf("NeState Unmarshal %s", err.Error())
return nil, err
}
return map[string]any{
"neType": neInfo.NeType,
"neId": neInfo.NeId,
"neName": neInfo.NeName,
"refreshTime": time.Now().UnixMilli(), // 获取时间
"version": resData["version"],
"capability": resData["capability"],
"sn": resData["serialNum"],
"expire": resData["expiryDate"],
"cpu": resData["cpuUsage"],
"mem": resData["memUsage"],
}, nil
}

View File

@@ -6,4 +6,7 @@ import "ems.agt/src/modules/network_element/model"
type INeInfo interface {
// SelectNeInfoByNeTypeAndNeID 通过ne_type和ne_id查询网元信息
SelectNeInfoByNeTypeAndNeID(neType, neID string) model.NeInfo
// SelectNeList 查询网元列表
SelectNeList(ne model.NeInfo, bandStatus bool) []model.NeInfo
}

View File

@@ -20,3 +20,24 @@ type NeInfoImpl struct {
func (r *NeInfoImpl) SelectNeInfoByNeTypeAndNeID(neType, neID string) model.NeInfo {
return r.NeInfoRepository.SelectNeInfoByNeTypeAndNeID(neType, neID)
}
// SelectNeList 查询网元列表
func (r *NeInfoImpl) SelectNeList(ne model.NeInfo, bandStatus bool) []model.NeInfo {
list := r.NeInfoRepository.SelectNeList(ne)
// 网元直连读取网元服务状态
if bandStatus {
neList := &list
for i := range *neList {
v := (*neList)[i]
result, err := NeState(v)
if err != nil {
(*neList)[i].ServerState = map[string]any{}
continue
}
(*neList)[i].ServerState = result
}
}
return list
}

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

@@ -62,12 +62,8 @@ func (r *UDMAuthImpl) authDataByRedis(imsi, neID string) []model.UDMAuth {
// Save UDM鉴权用户-获取redis全部保存数据库
func (r *UDMAuthImpl) Save(neID string) int64 {
var num int64 = 0
authArr := r.authDataByRedis("*", neID)
// 数据清空
if len(authArr) == 0 {
return num
}
// 数据清空后添加
go r.udmAuthRepository.ClearAndInsert(neID, authArr)
return int64(len(authArr))
}

View File

@@ -78,12 +78,8 @@ func (r *UDMSubImpl) subDataByRedis(imsi, neID string) []model.UDMSub {
// Save UDM签约用户-获取redis全部保存数据库
func (r *UDMSubImpl) Save(neID string) int64 {
var num int64 = 0
subArr := r.subDataByRedis("*", neID)
// 数据清空
if len(subArr) == 0 {
return num
}
// 数据清空后添加
go r.udmSubRepository.ClearAndInsert(neID, subArr)
return int64(len(subArr))
}

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
}