From 010fd9efb9ba88898e5c3f25802b827dcb41863f Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Tue, 25 Jun 2024 15:18:48 +0800 Subject: [PATCH 1/7] =?UTF-8?q?fix:=20=E7=A7=BB=E9=99=A4ims=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=E6=89=A7=E8=A1=8C=E7=9A=84sudo=E5=89=8D=E7=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/network_element/controller/ne_action.go | 2 +- src/modules/network_element/service/ne_license.impl.go | 2 +- src/modules/network_element/service/ne_version.impl.go | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/modules/network_element/controller/ne_action.go b/src/modules/network_element/controller/ne_action.go index 1259ea98..4d597356 100644 --- a/src/modules/network_element/controller/ne_action.go +++ b/src/modules/network_element/controller/ne_action.go @@ -223,7 +223,7 @@ func (s *NeActionController) Service(c *gin.Context) { cmdStr = fmt.Sprintf("nohup sh -c \"sudo systemctl stop restagent && sleep 5s && sudo systemctl %s restagent\" > /dev/null 2>&1 &", body.Action) } else if neTypeLower == "ims" { if body.Action == "restart" { - cmdStr = "sudo ims-stop || true && sudo ims-start" + cmdStr = "ims-stop || true && ims-start" } else { cmdStr = fmt.Sprintf("sudo ims-%s", body.Action) } diff --git a/src/modules/network_element/service/ne_license.impl.go b/src/modules/network_element/service/ne_license.impl.go index 41075a15..9d11804d 100644 --- a/src/modules/network_element/service/ne_license.impl.go +++ b/src/modules/network_element/service/ne_license.impl.go @@ -181,7 +181,7 @@ func (r *NeLicenseImpl) UploadLicense(neLicense model.NeLicense) error { if neLicense.Reload { cmdStr := fmt.Sprintf("sudo service %s restart", neTypeLower) if neTypeLower == "ims" { - cmdStr = "sudo ims-stop || true && sudo ims-start" + cmdStr = "ims-stop || true && ims-start" } else if neTypeLower == "omc" { cmdStr = "sudo systemctl restart restagent" } diff --git a/src/modules/network_element/service/ne_version.impl.go b/src/modules/network_element/service/ne_version.impl.go index fc389868..dde257f5 100644 --- a/src/modules/network_element/service/ne_version.impl.go +++ b/src/modules/network_element/service/ne_version.impl.go @@ -220,9 +220,9 @@ func (r *NeVersionImpl) operateCommand(action, neType string, neFilePaths []stri cmdStrArr = append(cmdStrArr, pkgCmdStr+" \n") // 公网 PLMN地址 - cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo /usr/local/etc/ims/default/tools/modipplmn.sh %s %s %s \n", para5GData["SIP_IP"], para5GData["MCC"], para5GData["MNC"])) + cmdStrArr = append(cmdStrArr, fmt.Sprintf("/usr/local/etc/ims/default/tools/modipplmn.sh %s %s %s \n", para5GData["SIP_IP"], para5GData["MCC"], para5GData["MNC"])) // 内网 服务地址 - cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo /usr/local/etc/ims/default/tools/modintraip.sh %s \n", para5GData["IMS_IP"])) + cmdStrArr = append(cmdStrArr, fmt.Sprintf("/usr/local/etc/ims/default/tools/modintraip.sh %s \n", para5GData["IMS_IP"])) // IWF连接PCF服务 cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/172.16.5.160/%s/g\" /usr/local/etc/iwf/iwf_conf.yaml \n", para5GData["PCF_IP"])) // 设置 HOST @@ -252,13 +252,13 @@ func (r *NeVersionImpl) operateCommand(action, neType string, neFilePaths []stri cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/bind 127.0.0.1/bind %s/g\" /usr/local/etc/adb/adb.conf \n", para5GData["ADB_IP"])) cmdStrArr = append(cmdStrArr, "sudo service adb restart \n") - cmdStrArr = append(cmdStrArr, "sudo ims-stop || true && sudo ims-start \n") + cmdStrArr = append(cmdStrArr, "ims-stop || true && ims-start \n") // 30s后停止服务 // cmdStrArr = append(cmdStrArr, "nohup sh -c \"sleep 30s && sudo ims-stop\" > /dev/null 2>&1 & \n") } else { - cmdStrArr = append(cmdStrArr, "sudo ims-stop \n") + cmdStrArr = append(cmdStrArr, "ims-stop \n") cmdStrArr = append(cmdStrArr, pkgCmdStr+" \n") - cmdStrArr = append(cmdStrArr, "sudo ims-start \n") + cmdStrArr = append(cmdStrArr, "ims-start \n") } } else { if action == "install" { From d92ca5f2e409593be50ca21608e8609640147099 Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Tue, 25 Jun 2024 15:43:58 +0800 Subject: [PATCH 2/7] =?UTF-8?q?style:=20=E7=BD=91=E5=85=83=E7=9B=B4?= =?UTF-8?q?=E8=BF=9E=E5=8D=95=E7=8B=AC=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../network_element/controller/ne_info.go | 11 +-- .../network_element/controller/ne_license.go | 3 +- .../network_element/fetch_link/ne_config.go | 70 +++++++++++++++++++ .../network_element/fetch_link/ne_state.go | 56 +++++++++++++++ .../network_element/service/ne_info.impl.go | 5 +- 5 files changed, 137 insertions(+), 8 deletions(-) create mode 100644 src/modules/network_element/fetch_link/ne_config.go create mode 100644 src/modules/network_element/fetch_link/ne_state.go diff --git a/src/modules/network_element/controller/ne_info.go b/src/modules/network_element/controller/ne_info.go index 177a19b2..ea0ded6e 100644 --- a/src/modules/network_element/controller/ne_info.go +++ b/src/modules/network_element/controller/ne_info.go @@ -9,6 +9,7 @@ import ( "be.ems/src/framework/utils/ctx" "be.ems/src/framework/utils/parse" "be.ems/src/framework/vo/result" + neFetchlink "be.ems/src/modules/network_element/fetch_link" "be.ems/src/modules/network_element/model" neService "be.ems/src/modules/network_element/service" "github.com/gin-gonic/gin" @@ -60,7 +61,7 @@ func (s *NeInfoController) State(c *gin.Context) { neKey := fmt.Sprintf("%s_%s", neInfo.NeType, neInfo.NeId) // 网元直连 - resData, err := neService.NeState(neInfo) + resData, err := neFetchlink.NeState(neInfo) if err != nil { mutex.Lock() // 异常取上次缓存 @@ -287,12 +288,12 @@ func (s *NeInfoController) Add(c *gin.Context) { } // 获取网元状态是否正常 - body.ServerState, err = neService.NeState(body) + body.ServerState, err = neFetchlink.NeState(body) if err != nil { body.Status = "0" } else { // 下发网管配置信息给网元 - _, err = neService.NeConfigOMC(body) + _, err = neFetchlink.NeConfigOMC(body) if err == nil { body.Status = "1" } else { @@ -376,12 +377,12 @@ func (s *NeInfoController) Edit(c *gin.Context) { } // 获取网元状态是否正常 - body.ServerState, err = neService.NeState(body) + body.ServerState, err = neFetchlink.NeState(body) if err != nil { body.Status = "0" } else { // 下发网管配置信息给网元 - _, err = neService.NeConfigOMC(body) + _, err = neFetchlink.NeConfigOMC(body) if err == nil { body.Status = "1" } else { diff --git a/src/modules/network_element/controller/ne_license.go b/src/modules/network_element/controller/ne_license.go index fad2e0c4..3b4dd4ce 100644 --- a/src/modules/network_element/controller/ne_license.go +++ b/src/modules/network_element/controller/ne_license.go @@ -6,6 +6,7 @@ import ( "be.ems/src/framework/i18n" "be.ems/src/framework/utils/ctx" "be.ems/src/framework/vo/result" + neFetchlink "be.ems/src/modules/network_element/fetch_link" "be.ems/src/modules/network_element/model" neService "be.ems/src/modules/network_element/service" "github.com/gin-gonic/gin" @@ -198,7 +199,7 @@ func (s *NeLicenseController) State(c *gin.Context) { c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) return } - if neState, err := neService.NeState(neInfo); err == nil && neState["sn"] != nil { + if neState, err := neFetchlink.NeState(neInfo); err == nil && neState["sn"] != nil { neLicense.Status = "1" neLicense.SerialNum = fmt.Sprint(neState["sn"]) neLicense.ExpiryDate = fmt.Sprint(neState["expire"]) diff --git a/src/modules/network_element/fetch_link/ne_config.go b/src/modules/network_element/fetch_link/ne_config.go new file mode 100644 index 00000000..2b19c44e --- /dev/null +++ b/src/modules/network_element/fetch_link/ne_config.go @@ -0,0 +1,70 @@ +package fetchlink + +import ( + "encoding/json" + "fmt" + "strings" + + "be.ems/src/framework/logger" + "be.ems/src/framework/utils/fetch" + "be.ems/src/modules/network_element/model" +) + +// NeConfigOMC 网元配置对端网管信息 +func NeConfigOMC(neInfo model.NeInfo) (map[string]any, error) { + // 网元配置对端网管信息 + neUrl := fmt.Sprintf("http://%s:%d/api/rest/systemManagement/v1/elementType/%s/objectType/config/omcNeConfig", neInfo.IP, neInfo.Port, strings.ToLower(neInfo.NeType)) + resBytes, err := fetch.PutJSON(neUrl, map[string]any{ + "neId": neInfo.NeId, + "neName": neInfo.NeName, + "port": neInfo.Port, + "province": neInfo.Province, + "pvFlag": neInfo.PvFlag, + "rmUID": neInfo.RmUID, + "vendorName": neInfo.VendorName, + "dn": neInfo.Dn, + }, nil) + var resData map[string]any + if err != nil { + status := err.Error() + logger.Warnf("NeConfigOMC %s Put \"%s\"", status, neUrl) + if strings.HasPrefix(status, "201") || strings.HasPrefix(status, "204") { + return resData, nil + } + return nil, err + } + + // 200 成功无数据时 + if len(resBytes) == 0 { + return resData, nil + } + + // 序列化结果 + err = json.Unmarshal(resBytes, &resData) + if err != nil { + logger.Warnf("NeConfigOMC Unmarshal %s", err.Error()) + return nil, err + } + + return resData, nil +} + +// NeConfigInfo 网元配置信息 +func NeConfigInfo(neInfo model.NeInfo, name string) (map[string]any, error) { + // 网元配置对端网管信息 + neUrl := fmt.Sprintf("http://%s:%d/api/rest/systemManagement/v1/elementType/%s/objectType/config/%s", neInfo.IP, neInfo.Port, strings.ToLower(neInfo.NeType), name) + resBytes, err := fetch.Get(neUrl, nil, 1000) + if err != nil { + logger.Warnf("NeConfigInfo %s", err.Error()) + return nil, err + } + + // 序列化结果 + var resData map[string]any + err = json.Unmarshal(resBytes, &resData) + if err != nil { + logger.Warnf("NeConfigInfo Unmarshal %s", err.Error()) + return nil, err + } + return resData, nil +} diff --git a/src/modules/network_element/fetch_link/ne_state.go b/src/modules/network_element/fetch_link/ne_state.go new file mode 100644 index 00000000..4ed27aa3 --- /dev/null +++ b/src/modules/network_element/fetch_link/ne_state.go @@ -0,0 +1,56 @@ +package fetchlink + +import ( + "encoding/json" + "fmt" + "strings" + "time" + + "be.ems/src/framework/logger" + "be.ems/src/framework/utils/fetch" + "be.ems/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, 1000) + 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 + } + + // 检查是否有许可时间 + if v, ok := resData["expiryDate"]; ok && v != nil { + expiryDate := v.(string) + // UPF存在2000的许可时间,MME会有空字符 + if strings.HasPrefix(expiryDate, "2000") || expiryDate == "" { + logger.Warnf("NeState %s License Expiration Aanomaly. Get \"%s\"", neInfo.NeType, neUrl) + return nil, fmt.Errorf("%s License Expiration Aanomaly", neInfo.NeType) + } + } + + return map[string]any{ + "neType": neInfo.NeType, + "neId": neInfo.NeId, + "neName": neInfo.NeName, + "neIP": neInfo.IP, + "refreshTime": time.Now().UnixMilli(), // 获取时间 + "version": resData["version"], + "capability": resData["capability"], + "sn": resData["serialNum"], + "expire": resData["expiryDate"], + "cpu": resData["cpuUsage"], + "mem": resData["memUsage"], + "disk": resData["diskSpace"], + }, nil +} diff --git a/src/modules/network_element/service/ne_info.impl.go b/src/modules/network_element/service/ne_info.impl.go index c69eb183..8909a85b 100644 --- a/src/modules/network_element/service/ne_info.impl.go +++ b/src/modules/network_element/service/ne_info.impl.go @@ -14,6 +14,7 @@ import ( "be.ems/src/framework/utils/parse" "be.ems/src/framework/utils/ssh" "be.ems/src/framework/utils/telnet" + neFetchlink "be.ems/src/modules/network_element/fetch_link" "be.ems/src/modules/network_element/model" "be.ems/src/modules/network_element/repository" ) @@ -149,7 +150,7 @@ func (r *NeInfoImpl) SelectList(ne model.NeInfo, bandStatus bool, bandHost bool) func (r *NeInfoImpl) bandNeStatus(arr *[]model.NeInfo) { for i := range *arr { v := (*arr)[i] - result, err := NeState(v) + result, err := neFetchlink.NeState(v) if err != nil { (*arr)[i].ServerState = map[string]any{ "online": false, @@ -167,7 +168,7 @@ func (r *NeInfoImpl) bandNeStatus(arr *[]model.NeInfo) { // 网元状态设置为在线 if v.Status != "1" { // 下发网管配置信息给网元 - _, err = NeConfigOMC(v) + _, err = neFetchlink.NeConfigOMC(v) if err == nil { v.Status = "1" } else { From c816b64b310307e8231c8140ff1dd5d7f7d7b0bf Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Tue, 25 Jun 2024 17:03:56 +0800 Subject: [PATCH 3/7] =?UTF-8?q?feat:=20=E5=86=85=E8=BD=AC=E8=AF=B7?= =?UTF-8?q?=E6=B1=82=E7=9A=84=E7=BD=91=E5=85=83=E5=8F=82=E6=95=B0=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/param_config.go | 188 +++++++++++++ .../network_element/fetch_link/ne_config.go | 2 +- .../network_element/model/ne_config.go | 21 ++ .../network_element/model/ne_software.go | 1 - .../network_element/network_element.go | 31 +++ .../network_element/repository/ne_config.go | 24 ++ .../repository/ne_config.impl.go | 254 ++++++++++++++++++ .../network_element/service/ne_config.go | 24 ++ .../network_element/service/ne_config.impl.go | 67 +++++ 9 files changed, 610 insertions(+), 2 deletions(-) create mode 100644 src/modules/network_element/controller/param_config.go create mode 100644 src/modules/network_element/model/ne_config.go create mode 100644 src/modules/network_element/repository/ne_config.go create mode 100644 src/modules/network_element/repository/ne_config.impl.go create mode 100644 src/modules/network_element/service/ne_config.go create mode 100644 src/modules/network_element/service/ne_config.impl.go diff --git a/src/modules/network_element/controller/param_config.go b/src/modules/network_element/controller/param_config.go new file mode 100644 index 00000000..2f0d273e --- /dev/null +++ b/src/modules/network_element/controller/param_config.go @@ -0,0 +1,188 @@ +package controller + +import ( + "encoding/json" + "strings" + + "be.ems/src/framework/i18n" + "be.ems/src/framework/utils/ctx" + "be.ems/src/framework/utils/parse" + "be.ems/src/framework/vo/result" + neFetchlink "be.ems/src/modules/network_element/fetch_link" + "be.ems/src/modules/network_element/model" + neService "be.ems/src/modules/network_element/service" + "github.com/gin-gonic/gin" + "github.com/gin-gonic/gin/binding" +) + +// NewNeConfig 网元参数配置 实例化控制层 +var NewNeConfig = &NeConfigController{ + neConfigService: neService.NewNeConfigImpl, + neInfoService: neService.NewNeInfoImpl, +} + +// 网元参数配置 +// +// PATH /config +type NeConfigController struct { + // 网元参数配置可用属性值服务 + neConfigService neService.INeConfig + // 网元信息服务 + neInfoService neService.INeInfo +} + +// 网元参数配置可用属性值列表 +// +// GET /list +func (s *NeConfigController) List(c *gin.Context) { + querys := ctx.QueryMap(c) + data := s.neConfigService.SelectPage(querys) + + c.JSON(200, result.Ok(data)) +} + +// 网元参数配置可用属性值信息 +// +// GET /info/:id +func (s *NeConfigController) Info(c *gin.Context) { + language := ctx.AcceptLanguage(c) + id := c.Param("id") + if id == "" { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + data := s.neConfigService.SelectById(id) + if data.ID != id { + // 没有可访问参数配置数据! + c.JSON(200, result.ErrMsg(i18n.TKey(language, "neConfig.noData"))) + return + } + + // 将字符串转json数据 + if err := json.Unmarshal([]byte(data.ParamJSONStr), &data.ParamData); err != nil { + c.JSON(400, result.CodeMsg(400, err.Error())) + return + } + c.JSON(200, result.OkData(data)) +} + +// 网元参数配置可用属性值新增 +// +// POST / +func (s *NeConfigController) Add(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var body model.NeConfig + if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + // 将json数据转字符串存储 + paramDataByte, err := json.Marshal(body.ParamData) + if err != nil { + c.JSON(400, result.CodeMsg(400, err.Error())) + return + } + body.ParamJSONStr = string(paramDataByte) + + insertId := s.neConfigService.Insert(body) + if insertId != "" { + c.JSON(200, result.Ok(nil)) + return + } + c.JSON(200, result.Err(nil)) +} + +// 网元参数配置可用属性值修改 +// +// PUT / +func (s *NeConfigController) Edit(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var body model.NeConfig + err := c.ShouldBindBodyWith(&body, binding.JSON) + if err != nil || body.ID == "" { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + // 检查是否存在 + data := s.neConfigService.SelectById(body.ID) + if data.ID != body.ID { + // 没有可访问主机命令数据! + c.JSON(200, result.ErrMsg(i18n.TKey(language, "neConfig.noData"))) + return + } + + // 将json数据转字符串存储 + paramDataByte, err := json.Marshal(body.ParamData) + if err != nil { + c.JSON(400, result.CodeMsg(400, err.Error())) + return + } + body.ParamJSONStr = string(paramDataByte) + + rows := s.neConfigService.Update(body) + if rows > 0 { + c.JSON(200, result.Ok(nil)) + return + } + c.JSON(200, result.Err(nil)) +} + +// 网元参数配置可用属性值删除 +// +// DELETE /:ids +func (s *NeConfigController) Remove(c *gin.Context) { + language := ctx.AcceptLanguage(c) + ids := c.Param("ids") + if ids == "" { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + // 处理字符转id数组后去重 + idsArr := strings.Split(ids, ",") + uniqueIDs := parse.RemoveDuplicates(idsArr) + if len(uniqueIDs) <= 0 { + c.JSON(200, result.Err(nil)) + return + } + rows, err := s.neConfigService.DeleteByIds(uniqueIDs) + if err != nil { + c.JSON(200, result.ErrMsg(i18n.TKey(language, err.Error()))) + return + } + msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows}) + c.JSON(200, result.OkMsg(msg)) +} + +// 网元参数配置数据信息 +// +// GET /data +func (s *NeConfigController) Data(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var querys struct { + NeType string `form:"neType" binding:"required"` // 网元类型 + NeId string `form:"neId" binding:"required"` // 网元ID + TopTag string `form:"topTag" 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 := neFetchlink.NeConfigInfo(neInfo, querys.TopTag) + if err != nil { + c.JSON(200, result.ErrMsg(err.Error())) + return + } + + c.JSON(200, result.Ok(resData)) +} diff --git a/src/modules/network_element/fetch_link/ne_config.go b/src/modules/network_element/fetch_link/ne_config.go index 2b19c44e..cb93a2b2 100644 --- a/src/modules/network_element/fetch_link/ne_config.go +++ b/src/modules/network_element/fetch_link/ne_config.go @@ -55,7 +55,7 @@ func NeConfigInfo(neInfo model.NeInfo, name string) (map[string]any, error) { neUrl := fmt.Sprintf("http://%s:%d/api/rest/systemManagement/v1/elementType/%s/objectType/config/%s", neInfo.IP, neInfo.Port, strings.ToLower(neInfo.NeType), name) resBytes, err := fetch.Get(neUrl, nil, 1000) if err != nil { - logger.Warnf("NeConfigInfo %s", err.Error()) + logger.Warnf("NeConfigInfo %s Get \"%s\"", err.Error(), neUrl) return nil, err } diff --git a/src/modules/network_element/model/ne_config.go b/src/modules/network_element/model/ne_config.go new file mode 100644 index 00000000..dcc7e054 --- /dev/null +++ b/src/modules/network_element/model/ne_config.go @@ -0,0 +1,21 @@ +package model + +// NeConfig 网元参数配置可用属性值 +type NeConfig struct { + ID string `json:"id" gorm:"id"` + NeType string `json:"neType" binding:"required" gorm:"ne_type"` // 网元类型 + NeId string `json:"-" gorm:"ne_id"` + TopTag string `json:"topTag" binding:"required" gorm:"top_tag"` + TopDisplay string `json:"topDisplay" binding:"required" gorm:"top_display"` + Method string `json:"method" gorm:"method"` // 操作属性 get只读强制不可编辑删除 put可编辑 delete可删除 post可新增 + ParamJSONStr string `json:"-" gorm:"param_json"` // accesss属性控制:只读read-only/read/ro 读写read-write + + // ====== 非数据库字段属性 ====== + + ParamData map[string]any `json:"paramData,omitempty" binding:"required" gorm:"-"` // 与ParamJSONStr配合转换 +} + +// TableName 表名称 +func (*NeConfig) TableName() string { + return "param_config" +} diff --git a/src/modules/network_element/model/ne_software.go b/src/modules/network_element/model/ne_software.go index 3eaf9569..53a5321d 100644 --- a/src/modules/network_element/model/ne_software.go +++ b/src/modules/network_element/model/ne_software.go @@ -15,7 +15,6 @@ type NeSoftware struct { // ====== 非数据库字段属性 ====== - NeId string `json:"neId,omitempty" gorm:"-"` // 网元ID } // TableName 表名称 diff --git a/src/modules/network_element/network_element.go b/src/modules/network_element/network_element.go index 43cef165..49dea873 100644 --- a/src/modules/network_element/network_element.go +++ b/src/modules/network_element/network_element.go @@ -257,6 +257,37 @@ func Setup(router *gin.Engine) { ) } + // 网元参数配置 + neConfigGroup := neGroup.Group("/config") + { + neConfigGroup.GET("/list", + middleware.PreAuthorize(nil), + controller.NewNeConfig.List, + ) + neConfigGroup.GET("/info/:id", + middleware.PreAuthorize(nil), + controller.NewNeConfig.Info, + ) + neConfigGroup.POST("", + middleware.PreAuthorize(nil), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neConfig", collectlogs.BUSINESS_TYPE_INSERT)), + controller.NewNeConfig.Add, + ) + neConfigGroup.PUT("", + middleware.PreAuthorize(nil), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neConfig", collectlogs.BUSINESS_TYPE_UPDATE)), + controller.NewNeConfig.Edit, + ) + neConfigGroup.DELETE("/:ids", + middleware.PreAuthorize(nil), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neConfig", collectlogs.BUSINESS_TYPE_DELETE)), + controller.NewNeConfig.Remove, + ) + neConfigGroup.GET("/data", + middleware.PreAuthorize(nil), + controller.NewNeConfig.Data, + ) + } } // InitLoad 初始参数 diff --git a/src/modules/network_element/repository/ne_config.go b/src/modules/network_element/repository/ne_config.go new file mode 100644 index 00000000..5f555b3e --- /dev/null +++ b/src/modules/network_element/repository/ne_config.go @@ -0,0 +1,24 @@ +package repository + +import "be.ems/src/modules/network_element/model" + +// INeConfig 网元参数配置可用属性值 数据层接口 +type INeConfig interface { + // SelectPage 根据条件分页查询字典类型 + SelectPage(query map[string]any) map[string]any + + // SelectList 根据实体查询 + SelectList(param model.NeConfig) []model.NeConfig + + // SelectByIds 通过ID查询 + SelectByIds(ids []string) []model.NeConfig + + // Insert 新增信息 + Insert(param model.NeConfig) string + + // Update 修改信息 + Update(param model.NeConfig) int64 + + // DeleteByIds 批量删除信息 + DeleteByIds(ids []string) int64 +} diff --git a/src/modules/network_element/repository/ne_config.impl.go b/src/modules/network_element/repository/ne_config.impl.go new file mode 100644 index 00000000..8ea0db53 --- /dev/null +++ b/src/modules/network_element/repository/ne_config.impl.go @@ -0,0 +1,254 @@ +package repository + +import ( + "strings" + + "be.ems/src/framework/datasource" + "be.ems/src/framework/logger" + "be.ems/src/framework/utils/parse" + "be.ems/src/framework/utils/repo" + "be.ems/src/modules/network_element/model" +) + +// NewNeConfigImpl 网元参数配置可用属性值 实例化数据层 +var NewNeConfigImpl = &NeConfigImpl{ + selectSql: `select + id, ne_type, ne_id, top_tag, top_display, method, param_json + from param_config`, + + resultMap: map[string]string{ + "id": "ID", + "ne_type": "NeType", + "ne_id": "NeId", + "top_tag": "TopTag", + "top_display": "TopDisplay", + "method": "Method", + "param_json": "ParamJSONStr", + }, +} + +// NeConfigImpl 网元参数配置可用属性值 数据层处理 +type NeConfigImpl struct { + // 查询视图对象SQL + selectSql string + // 结果字段与实体映射 + resultMap map[string]string +} + +// convertResultRows 将结果记录转实体结果组 +func (r *NeConfigImpl) convertResultRows(rows []map[string]any) []model.NeConfig { + arr := make([]model.NeConfig, 0) + for _, row := range rows { + item := model.NeConfig{} + for key, value := range row { + if keyMapper, ok := r.resultMap[key]; ok { + repo.SetFieldValue(&item, keyMapper, value) + } + } + arr = append(arr, item) + } + return arr +} + +// SelectPage 根据条件分页查询字典类型 +func (r *NeConfigImpl) SelectPage(query map[string]any) map[string]any { + // 查询条件拼接 + var conditions []string + var params []any + if v, ok := query["neType"]; ok && v != "" { + conditions = append(conditions, "ne_type = ?") + params = append(params, v) + } + if v, ok := query["topTag"]; ok && v != "" { + conditions = append(conditions, "top_tag = ?") + params = append(params, v) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + result := map[string]any{ + "total": 0, + "rows": []model.NeHost{}, + } + + // 查询数量 长度为0直接返回 + totalSql := "select count(id) as 'total' from param_config" + totalRows, err := datasource.RawDB("", totalSql+whereSql, params) + if err != nil { + logger.Errorf("total err => %v", err) + return result + } + total := parse.Number(totalRows[0]["total"]) + if total == 0 { + return result + } else { + result["total"] = total + } + + // 分页 + pageNum, pageSize := repo.PageNumSize(query["pageNum"], query["pageSize"]) + pageSql := " limit ?,? " + params = append(params, pageNum*pageSize) + params = append(params, pageSize) + + // 查询数据 + querySql := r.selectSql + whereSql + pageSql + results, err := datasource.RawDB("", querySql, params) + if err != nil { + logger.Errorf("query err => %v", err) + return result + } + + // 转换实体 + result["rows"] = r.convertResultRows(results) + return result +} + +// SelectList 根据实体查询 +func (r *NeConfigImpl) SelectList(param model.NeConfig) []model.NeConfig { + // 查询条件拼接 + var conditions []string + var params []any + if param.NeType != "" { + conditions = append(conditions, "ne_type = ?") + params = append(params, param.NeType) + } + if param.TopTag != "" { + conditions = append(conditions, "top_tag = ?") + params = append(params, param.TopTag) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + // 查询数据 + querySql := r.selectSql + whereSql + " order by id asc " + results, err := datasource.RawDB("", querySql, params) + if err != nil { + logger.Errorf("query err => %v", err) + } + + // 转换实体 + return r.convertResultRows(results) +} + +// SelectByIds 通过ID查询 +func (r *NeConfigImpl) SelectByIds(ids []string) []model.NeConfig { + placeholder := repo.KeyPlaceholderByQuery(len(ids)) + querySql := r.selectSql + " where id in (" + placeholder + ")" + parameters := repo.ConvertIdsSlice(ids) + results, err := datasource.RawDB("", querySql, parameters) + if err != nil { + logger.Errorf("query err => %v", err) + return []model.NeConfig{} + } + // 转换实体 + return r.convertResultRows(results) +} + +// Insert 新增信息 +func (r *NeConfigImpl) Insert(param model.NeConfig) string { + // 参数拼接 + params := make(map[string]any) + if param.NeType != "" { + params["ne_type"] = param.NeType + } + if param.NeId != "" { + params["ne_id"] = param.NeId + } + if param.TopTag != "" { + params["top_tag"] = param.TopTag + } + if param.TopDisplay != "" { + params["top_display"] = param.TopDisplay + } + if param.Method != "" { + params["method"] = param.Method + } + if param.ParamJSONStr != "" { + params["param_json"] = param.ParamJSONStr + } + + // 构建执行语句 + keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params) + sql := "insert into param_config (" + strings.Join(keys, ",") + ")values(" + placeholder + ")" + + db := datasource.DefaultDB() + // 开启事务 + tx := db.Begin() + // 执行插入 + err := tx.Exec(sql, values...).Error + if err != nil { + logger.Errorf("insert row : %v", err.Error()) + tx.Rollback() + return "" + } + // 获取生成的自增 ID + var insertedID string + err = tx.Raw("select last_insert_id()").Row().Scan(&insertedID) + if err != nil { + logger.Errorf("insert last id : %v", err.Error()) + tx.Rollback() + return "" + } + // 提交事务 + tx.Commit() + return insertedID +} + +// Update 修改信息 +func (r *NeConfigImpl) Update(param model.NeConfig) int64 { + // 参数拼接 + params := make(map[string]any) + if param.NeType != "" { + params["ne_type"] = param.NeType + } + if param.NeId != "" { + params["ne_id"] = param.NeId + } + if param.TopTag != "" { + params["top_tag"] = param.TopTag + } + if param.TopDisplay != "" { + params["top_display"] = param.TopDisplay + } + if param.Method != "" { + params["method"] = param.Method + } + if param.ParamJSONStr != "" { + params["param_json"] = param.ParamJSONStr + } + + // 构建执行语句 + keys, values := repo.KeyValueByUpdate(params) + sql := "update param_config set " + strings.Join(keys, ",") + " where id = ?" + + // 执行更新 + values = append(values, param.ID) + rows, err := datasource.ExecDB("", sql, values) + if err != nil { + logger.Errorf("update row : %v", err.Error()) + return 0 + } + return rows +} + +// DeleteByIds 批量删除信息 +func (r *NeConfigImpl) DeleteByIds(ids []string) int64 { + placeholder := repo.KeyPlaceholderByQuery(len(ids)) + sql := "delete from param_config where id in (" + placeholder + ")" + parameters := repo.ConvertIdsSlice(ids) + results, err := datasource.ExecDB("", sql, parameters) + if err != nil { + logger.Errorf("delete err => %v", err) + return 0 + } + return results +} diff --git a/src/modules/network_element/service/ne_config.go b/src/modules/network_element/service/ne_config.go new file mode 100644 index 00000000..4b1f0eed --- /dev/null +++ b/src/modules/network_element/service/ne_config.go @@ -0,0 +1,24 @@ +package service + +import "be.ems/src/modules/network_element/model" + +// INeConfig 网元参数配置可用属性值 服务层接口 +type INeConfig interface { + // SelectPage 根据条件分页查询字典类型 + SelectPage(query map[string]any) map[string]any + + // SelectList 根据实体查询 + SelectList(param model.NeConfig) []model.NeConfig + + // SelectByIds 通过ID查询 + SelectById(id string) model.NeConfig + + // Insert 新增信息 + Insert(param model.NeConfig) string + + // Update 修改信息 + Update(param model.NeConfig) int64 + + // DeleteByIds 批量删除信息 + DeleteByIds(ids []string) (int64, error) +} diff --git a/src/modules/network_element/service/ne_config.impl.go b/src/modules/network_element/service/ne_config.impl.go new file mode 100644 index 00000000..b129fb6f --- /dev/null +++ b/src/modules/network_element/service/ne_config.impl.go @@ -0,0 +1,67 @@ +package service + +import ( + "fmt" + + "be.ems/src/modules/network_element/model" + "be.ems/src/modules/network_element/repository" +) + +// NewNeConfigImpl 网元参数配置可用属性值 实例化服务层 +var NewNeConfigImpl = &NeConfigImpl{ + neConfigRepository: repository.NewNeConfigImpl, +} + +// NeConfigImpl 网元参数配置可用属性值 服务层处理 +type NeConfigImpl struct { + // 网元参数配置可用属性值表 + neConfigRepository repository.INeConfig +} + +// SelectNeHostPage 分页查询列表数据 +func (r *NeConfigImpl) SelectPage(query map[string]any) map[string]any { + return r.neConfigRepository.SelectPage(query) +} + +// SelectConfigList 查询列表 +func (r *NeConfigImpl) SelectList(param model.NeConfig) []model.NeConfig { + return r.neConfigRepository.SelectList(param) +} + +// SelectByIds 通过ID查询 +func (r *NeConfigImpl) SelectById(id string) model.NeConfig { + if id == "" { + return model.NeConfig{} + } + neHosts := r.neConfigRepository.SelectByIds([]string{id}) + if len(neHosts) > 0 { + return neHosts[0] + } + return model.NeConfig{} +} + +// Insert 新增信息 +func (r *NeConfigImpl) Insert(param model.NeConfig) string { + return r.neConfigRepository.Insert(param) +} + +// Update 修改信息 +func (r *NeConfigImpl) Update(param model.NeConfig) int64 { + return r.neConfigRepository.Update(param) +} + +// DeleteByIds 批量删除信息 +func (r *NeConfigImpl) DeleteByIds(ids []string) (int64, error) { + // 检查是否存在 + data := r.neConfigRepository.SelectByIds(ids) + if len(data) <= 0 { + return 0, fmt.Errorf("param.noData") + } + + if len(data) == len(ids) { + rows := r.neConfigRepository.DeleteByIds(ids) + return rows, nil + } + // 删除信息失败! + return 0, fmt.Errorf("delete fail") +} From db789564cbcde433b907cb5de150bf142cbd1281 Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Tue, 25 Jun 2024 17:06:43 +0800 Subject: [PATCH 4/7] =?UTF-8?q?sql:=20=E5=8F=82=E6=95=B0=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E8=A1=A8=E5=8A=A0=E7=B4=A2=E5=BC=95=E5=92=8C=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- database/common/param_config.sql | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/database/common/param_config.sql b/database/common/param_config.sql index 67d6dee6..a1dda92b 100644 --- a/database/common/param_config.sql +++ b/database/common/param_config.sql @@ -5,17 +5,17 @@ SET FOREIGN_KEY_CHECKS = 0; -- Table structure for param_config -- ---------------------------- DROP TABLE IF EXISTS `param_config`; -CREATE TABLE `param_config` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `ne_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `ne_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `top_tag` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `top_display` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, - `method` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'method allow: \"get\", \"get,post,put\", \"delete\"', - `param_json` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL, +CREATE TABLE `param_config` ( + `id` int NOT NULL AUTO_INCREMENT, + `ne_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '网元类型', + `ne_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '', + `top_tag` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '', + `top_display` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `method` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '操作属性 get只读强制不可编辑删除 put可编辑 delete可删除 post可新增', + `param_json` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 'accesss属性控制:只读read-only/read/ro 读写read-write', PRIMARY KEY (`id`) USING BTREE, - INDEX `id`(`id`) USING BTREE -) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; + KEY `idx_type_name` (`ne_type`,`top_tag`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='网元参数配置可用属性值'; -- ---------------------------- -- Records of param_config From a594656303983bafb1073f2d20ac6a8a2434c919 Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Tue, 25 Jun 2024 17:12:24 +0800 Subject: [PATCH 5/7] =?UTF-8?q?style:=20=E7=BD=91=E5=85=83=E7=9B=B4?= =?UTF-8?q?=E8=BF=9E=E5=8D=95=E7=8B=AC=E7=9B=AE=E5=BD=95=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E5=8F=98=E6=9B=B4=E5=89=8D=E7=9A=84=E5=BC=95=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../network_element/service/ne_direct_link.go | 95 ------------------- src/modules/ws/processor/ne_state.go | 3 +- 2 files changed, 2 insertions(+), 96 deletions(-) delete mode 100644 src/modules/network_element/service/ne_direct_link.go diff --git a/src/modules/network_element/service/ne_direct_link.go b/src/modules/network_element/service/ne_direct_link.go deleted file mode 100644 index d1d58438..00000000 --- a/src/modules/network_element/service/ne_direct_link.go +++ /dev/null @@ -1,95 +0,0 @@ -package service - -import ( - "encoding/json" - "fmt" - "strings" - "time" - - "be.ems/src/framework/logger" - "be.ems/src/framework/utils/fetch" - "be.ems/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, 1000) - 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 - } - - // 检查是否有许可时间 - if v, ok := resData["expiryDate"]; ok && v != nil { - expiryDate := v.(string) - // UPF存在2000的许可时间,MME会有空字符 - if strings.HasPrefix(expiryDate, "2000") || expiryDate == "" { - logger.Warnf("NeState %s License Expiration Aanomaly. Get \"%s\"", neInfo.NeType, neUrl) - return nil, fmt.Errorf("%s License Expiration Aanomaly", neInfo.NeType) - } - } - - return map[string]any{ - "neType": neInfo.NeType, - "neId": neInfo.NeId, - "neName": neInfo.NeName, - "neIP": neInfo.IP, - "refreshTime": time.Now().UnixMilli(), // 获取时间 - "version": resData["version"], - "capability": resData["capability"], - "sn": resData["serialNum"], - "expire": resData["expiryDate"], - "cpu": resData["cpuUsage"], - "mem": resData["memUsage"], - "disk": resData["diskSpace"], - }, nil -} - -// NeConfigOMC 网元配置对端网管信息 -func NeConfigOMC(neInfo model.NeInfo) (map[string]any, error) { - // 网元配置对端网管信息 - neUrl := fmt.Sprintf("http://%s:%d/api/rest/systemManagement/v1/elementType/%s/objectType/config/omcNeConfig", neInfo.IP, neInfo.Port, strings.ToLower(neInfo.NeType)) - resBytes, err := fetch.PutJSON(neUrl, map[string]any{ - "neId": neInfo.NeId, - "neName": neInfo.NeName, - "port": neInfo.Port, - "province": neInfo.Province, - "pvFlag": neInfo.PvFlag, - "rmUID": neInfo.RmUID, - "vendorName": neInfo.VendorName, - "dn": neInfo.Dn, - }, nil) - var resData map[string]any - if err != nil { - status := err.Error() - logger.Warnf("NeConfigOMC %s Put \"%s\"", status, neUrl) - if strings.HasPrefix(status, "201") || strings.HasPrefix(status, "204") { - return resData, nil - } - return nil, err - } - - // 200 成功无数据时 - if len(resBytes) == 0 { - return resData, nil - } - - // 序列化结果 - err = json.Unmarshal(resBytes, &resData) - if err != nil { - logger.Warnf("NeConfigOMC Unmarshal %s", err.Error()) - return nil, err - } - - return resData, nil -} diff --git a/src/modules/ws/processor/ne_state.go b/src/modules/ws/processor/ne_state.go index dcf5df15..64e76e72 100644 --- a/src/modules/ws/processor/ne_state.go +++ b/src/modules/ws/processor/ne_state.go @@ -6,6 +6,7 @@ import ( "be.ems/src/framework/logger" "be.ems/src/framework/vo/result" + neFetchlink "be.ems/src/modules/network_element/fetch_link" neService "be.ems/src/modules/network_element/service" ) @@ -33,7 +34,7 @@ func GetNeState(requestID string, data any) ([]byte, error) { } // 网元直连 - resData, err := neService.NeState(neInfo) + resData, err := neFetchlink.NeState(neInfo) if err != nil { resultByte, err := json.Marshal(result.Ok(map[string]any{ "requestId": requestID, From 0b4ca287ef624b49dd97b4aa212e629f1ee8c6c3 Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Wed, 26 Jun 2024 10:16:57 +0800 Subject: [PATCH 6/7] =?UTF-8?q?style:=20=20ne=5Faction=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E9=87=8D=E5=91=BD=E5=90=8Daction=E7=BD=91=E5=85=83=E5=85=AC?= =?UTF-8?q?=E5=85=B1=E8=A1=8C=E4=B8=BA=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../network_element/controller/{ne_action.go => action.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/modules/network_element/controller/{ne_action.go => action.go} (100%) diff --git a/src/modules/network_element/controller/ne_action.go b/src/modules/network_element/controller/action.go similarity index 100% rename from src/modules/network_element/controller/ne_action.go rename to src/modules/network_element/controller/action.go From 93123fa686149e78d6ecb1def4ea4e5338bbd246 Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Wed, 26 Jun 2024 10:20:35 +0800 Subject: [PATCH 7/7] =?UTF-8?q?feat:=20=E7=BD=91=E5=85=83=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E9=85=8D=E7=BD=AE=E5=8F=AF=E7=94=A8=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E7=94=A8=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{param_config.go => ne_config.go} | 14 ++++ .../network_element/network_element.go | 7 ++ .../network_element/service/ne_config.go | 11 ++- .../network_element/service/ne_config.impl.go | 84 +++++++++++++++++++ 4 files changed, 115 insertions(+), 1 deletion(-) rename src/modules/network_element/controller/{param_config.go => ne_config.go} (92%) diff --git a/src/modules/network_element/controller/param_config.go b/src/modules/network_element/controller/ne_config.go similarity index 92% rename from src/modules/network_element/controller/param_config.go rename to src/modules/network_element/controller/ne_config.go index 2f0d273e..9c804ae7 100644 --- a/src/modules/network_element/controller/param_config.go +++ b/src/modules/network_element/controller/ne_config.go @@ -156,6 +156,20 @@ func (s *NeConfigController) Remove(c *gin.Context) { c.JSON(200, result.OkMsg(msg)) } +// 网元参数配置可用属性值列表指定网元类型全部无分页 +// +// GET /list/:neType +func (s *NeConfigController) ListByNeType(c *gin.Context) { + language := ctx.AcceptLanguage(c) + neType := c.Param("neType") + if neType == "" { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + data := s.neConfigService.SelectNeConfigByNeType(neType) + c.JSON(200, result.OkData(data)) +} + // 网元参数配置数据信息 // // GET /data diff --git a/src/modules/network_element/network_element.go b/src/modules/network_element/network_element.go index 49dea873..e6a6c61d 100644 --- a/src/modules/network_element/network_element.go +++ b/src/modules/network_element/network_element.go @@ -283,6 +283,10 @@ func Setup(router *gin.Engine) { collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neConfig", collectlogs.BUSINESS_TYPE_DELETE)), controller.NewNeConfig.Remove, ) + neConfigGroup.GET("/list/:neType", + middleware.PreAuthorize(nil), + controller.NewNeConfig.ListByNeType, + ) neConfigGroup.GET("/data", middleware.PreAuthorize(nil), controller.NewNeConfig.Data, @@ -299,4 +303,7 @@ func InitLoad() { if para5GMap, err := service.NewNeInfoImpl.NeConfPara5GRead(); para5GMap != nil && err == nil { service.NewNeInfoImpl.NeConfPara5GWirte(para5GMap, nil) } + // 启动时,清除缓存-网元参数配置可用属性值 + service.NewNeConfigImpl.ClearNeCacheByNeType("*") + service.NewNeConfigImpl.RefreshByNeTypeAndNeID("*") } diff --git a/src/modules/network_element/service/ne_config.go b/src/modules/network_element/service/ne_config.go index 4b1f0eed..fff9fe7b 100644 --- a/src/modules/network_element/service/ne_config.go +++ b/src/modules/network_element/service/ne_config.go @@ -4,7 +4,16 @@ import "be.ems/src/modules/network_element/model" // INeConfig 网元参数配置可用属性值 服务层接口 type INeConfig interface { - // SelectPage 根据条件分页查询字典类型 + // RefreshByNeType 通过ne_type刷新redis中的缓存 + RefreshByNeTypeAndNeID(neType string) []model.NeConfig + + // ClearNeCacheByNeType 清除网元类型参数配置缓存 + ClearNeCacheByNeType(neType string) bool + + // SelectNeConfigByNeType 查询网元类型参数配置 + SelectNeConfigByNeType(neType string) []model.NeConfig + + // SelectNeHostPage 分页查询列表数据 SelectPage(query map[string]any) map[string]any // SelectList 根据实体查询 diff --git a/src/modules/network_element/service/ne_config.impl.go b/src/modules/network_element/service/ne_config.impl.go index b129fb6f..6b4a4b82 100644 --- a/src/modules/network_element/service/ne_config.impl.go +++ b/src/modules/network_element/service/ne_config.impl.go @@ -1,8 +1,12 @@ package service import ( + "encoding/json" "fmt" + "strings" + "be.ems/src/framework/constants/cachekey" + "be.ems/src/framework/redis" "be.ems/src/modules/network_element/model" "be.ems/src/modules/network_element/repository" ) @@ -18,6 +22,86 @@ type NeConfigImpl struct { neConfigRepository repository.INeConfig } +// RefreshByNeType 通过ne_type刷新redis中的缓存 +func (r *NeConfigImpl) RefreshByNeTypeAndNeID(neType string) []model.NeConfig { + // 多个 + if neType == "" || neType == "*" { + neConfigList := r.neConfigRepository.SelectList(model.NeConfig{}) + if len(neConfigList) > 0 { + neConfigGroup := map[string][]model.NeConfig{} + for _, v := range neConfigList { + if item, ok := neConfigGroup[v.NeType]; ok { + neConfigGroup[v.NeType] = append(item, v) + } else { + neConfigGroup[v.NeType] = []model.NeConfig{v} + } + } + for k, v := range neConfigGroup { + key := fmt.Sprintf("%sparam_config:%s", cachekey.NE_DATA_KEY, strings.ToUpper(k)) + redis.Del("", key) + if len(v) > 0 { + for i, item := range v { + if err := json.Unmarshal([]byte(item.ParamJSONStr), &item.ParamData); err != nil { + continue + } + v[i] = item + } + values, _ := json.Marshal(v) + redis.Set("", key, string(values)) + } + } + } + return neConfigList + } + // 单个 + key := fmt.Sprintf("%sparam_config:%s", cachekey.NE_DATA_KEY, strings.ToUpper(neType)) + redis.Del("", key) + neConfigList := r.neConfigRepository.SelectList(model.NeConfig{ + NeType: neType, + }) + if len(neConfigList) > 0 { + for i, v := range neConfigList { + if err := json.Unmarshal([]byte(v.ParamJSONStr), &v.ParamData); err != nil { + continue + } + neConfigList[i] = v + } + values, _ := json.Marshal(neConfigList) + redis.Set("", key, string(values)) + } + return neConfigList +} + +// ClearNeCacheByNeType 清除网元类型参数配置缓存 +func (r *NeConfigImpl) ClearNeCacheByNeType(neType string) bool { + key := fmt.Sprintf("%sparam_config:%s", cachekey.NE_DATA_KEY, neType) + if neType == "*" { + key = fmt.Sprintf("%sparam_config:*", cachekey.NE_DATA_KEY) + } + keys, err := redis.GetKeys("", key) + if err != nil { + return false + } + delOk, _ := redis.DelKeys("", keys) + return delOk +} + +// SelectNeConfigByNeType 查询网元类型参数配置 +func (r *NeConfigImpl) SelectNeConfigByNeType(neType string) []model.NeConfig { + var neConfigList []model.NeConfig + key := fmt.Sprintf("%sparam_config:%s", cachekey.NE_DATA_KEY, strings.ToUpper(neType)) + jsonStr, _ := redis.Get("", key) + if len(jsonStr) > 7 { + err := json.Unmarshal([]byte(jsonStr), &neConfigList) + if err != nil { + neConfigList = []model.NeConfig{} + } + } else { + neConfigList = r.RefreshByNeTypeAndNeID(neType) + } + return neConfigList +} + // SelectNeHostPage 分页查询列表数据 func (r *NeConfigImpl) SelectPage(query map[string]any) map[string]any { return r.neConfigRepository.SelectPage(query)