diff --git a/.vscode/launch.json b/.vscode/launch.json index 409bd74f..b34eea44 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,7 +11,7 @@ "mode": "debug", "program": "./restagent/restagent.go", "console": "integratedTerminal", - "args": ["--env", "local"] // 走开发配置 + "args": ["--env", "local", "-c", "./etc/restconf.yaml"] // 走开发配置 }, { "name": "DEBUG restagent", diff --git a/config/etc/default/restconf.yaml b/config/etc/default/restconf.yaml index ad327e14..7c83f168 100644 --- a/config/etc/default/restconf.yaml +++ b/config/etc/default/restconf.yaml @@ -70,11 +70,12 @@ mml: bufferSize: 65535 mmlHome: ./mmlhome -# Tracking configuration +# track configuration for NE signaling trace +# host fill in the specific IP address trace: - enabled: false - host: "172.16.5.100" # Fill in the specific IP address - port: 33033 + enabled: false # trace enabled, default false + host: "172.16.5.100" # trace host, default 127.0.0.1 + port: 33033 # trace port, default 33033 # NE config ne: diff --git a/database/common/ne_config.sql b/database/common/ne_config.sql index f27c341c..94b8287d 100644 --- a/database/common/ne_config.sql +++ b/database/common/ne_config.sql @@ -133,6 +133,7 @@ INSERT INTO `ne_config` VALUES (242, 'CBC', 'mmeProfile', 'MME Profile', 'array' -- OMC parameter config INSERT INTO `ne_config` VALUES (260, 'OMC', 'alarmEmailForward', 'Alarm Email Forward Interface', 'list', '[{\"access\":\"rw\",\"comment\":\"Is it enabled forward alarm with Email interface\",\"display\":\"Enable\",\"filter\":\"true;false\",\"name\":\"enable\",\"type\":\"bool\",\"value\":\"true\"},{\"access\":\"rw\",\"comment\":\"\",\"display\":\"Email List\",\"filter\":\"\",\"name\":\"emailList\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"Email SMTP server\",\"display\":\"SMTP Server\",\"filter\":\"\",\"name\":\"smtp\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"\",\"display\":\"Port\",\"filter\":\"0~65535\",\"name\":\"port\",\"type\":\"int\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"\",\"display\":\"User\",\"filter\":\"\",\"name\":\"user\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"\",\"display\":\"Password\",\"filter\":\"\",\"name\":\"password\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"If skip TLS verify (true/false)\",\"display\":\"TLS Skip Verify\",\"filter\":\"true;false\",\"name\":\"tlsSkipVerify\",\"type\":\"bool\",\"value\":\"true\"}]', 3, '', 1725505025649, 'public'); INSERT INTO `ne_config` VALUES (261, 'OMC', 'alarmSMSForward', 'Alarm SMS Forward Interface', 'list', '[{\"access\":\"rw\",\"comment\":\"Is it enabled forward alarm with SMS interface\",\"display\":\"Enable\",\"filter\":\"true;false\",\"name\":\"enable\",\"type\":\"bool\",\"value\":\"true\"},{\"access\":\"rw\",\"comment\":\"Multiple mobile separated by commas\",\"display\":\"Mobile List\",\"filter\":\"\",\"name\":\"mobileList\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"The SMSC SMPP Address\",\"display\":\"SMSC Address\",\"filter\":\"\",\"name\":\"smscAddr\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"\",\"display\":\"System ID\",\"filter\":\"\",\"name\":\"systemID\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"\",\"display\":\"Password\",\"filter\":\"\",\"name\":\"password\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"\",\"display\":\"System Type\",\"filter\":\"\",\"name\":\"systemType\",\"type\":\"string\",\"value\":\"\"},{\"access\":\"rw\",\"comment\":\"Short message coding type\",\"display\":\"Data Coding\",\"filter\":\"{\\\"0\\\":\\\"GSM7BIT\\\",\\\"1\\\":\\\"ASCII\\\",\\\"2\\\":\\\"BINARY8BIT1\\\",\\\"3\\\":\\\"LATIN1\\\",\\\"4\\\":\\\"BINARY8BIT2\\\",\\\"6\\\":\\\"CYRILLIC\\\",\\\"7\\\":\\\"HEBREW\\\",\\\"8\\\":\\\"UCS2\\\"}\",\"name\":\"dataCoding\",\"type\":\"enum\",\"value\":\"GSM7BIT\"},{\"access\":\"rw\",\"comment\":\"It is the source address, the length is between 3 and 20\",\"display\":\"Service Number\",\"filter\":\"3~20\",\"name\":\"serviceNumber\",\"type\":\"string\",\"value\":\"OMC\"}]', 4, '', 1727664057261, 'public'); +INSERT INTO `ne_config` VALUES (262, 'OMC', 'trace', 'NE Signaling Trace', 'list', '[{\"access\":\"read-write\",\"comment\":\"enable or disable NE signaling trace creation\",\"display\":\"Enable\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"enabled\",\"type\":\"bool\",\"value\":\"false\"},{\"access\":\"read-write\",\"comment\":\"NE signaling trace host address\",\"display\":\"Host\",\"filter\":\"0~128\",\"name\":\"host\",\"type\":\"ipv4\",\"value\":\"172.16.5.100\"},{\"access\":\"read-write\",\"comment\":\"NE signaling trace port\",\"display\":\"Port\",\"filter\":\"3000~65530\",\"name\":\"port\",\"type\":\"int\",\"value\":\"33033\"}]', 1, '', 1748570559170, 'public'); -- 更新 SMSC 配置 2025521 INSERT INTO `ne_config` VALUES (280, 'SMSC', 'system', 'System', 'list', '[{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"CDR Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"cdrFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"SM Validity\",\"filter\":\"0-2147483647\",\"name\":\"smValidity\",\"type\":\"int\",\"value\":\"259200\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Log Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"logFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"Enable or disable resend pending SMS to unattainable local users.\",\"display\":\"Local Polling Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"localPollingFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"Enable or disable resend pending SMS to unattainable outbound roaming users.\",\"display\":\"Local Roaming Out Polling Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"localRoamingOutPollingFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"Enable or disable resend pending SMS to unattainable inbound roaming users.\",\"display\":\"Visitor Roaming In Polling Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"visitorRoamingInPollingFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"Enable or disable resend pending SMS to other unattainable users.\",\"display\":\"Other Polling Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"otherPollingFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"Define the maximum port number that the queue of pending SMS may grow to.\",\"display\":\"Polling Number\",\"filter\":\"0-64\",\"name\":\"pollingNumber\",\"type\":\"int\",\"value\":\"64\"},{\"access\":\"read-write\",\"comment\":\"Specify the priority parameter of SM_RP_PRI. true = High; false = Low.\",\"display\":\"Priority Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"priorityFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"Enable or disable TP-Reply-Path parameter in the SMS-DELIVER data unit.\",\"display\":\"TP Reply Path Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"tpReplyPathFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"SMSC Number\",\"filter\":\"0~32\",\"name\":\"smscNumber\",\"type\":\"string\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"SMSC Domain\",\"filter\":\"0~16\",\"name\":\"smscDomain\",\"type\":\"string\",\"value\":\"0.0.0.0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"CSFB VoLTE Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"csfbVolteFlag\",\"type\":\"bool\",\"value\":\"1\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Camel Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"camelFlag\",\"type\":\"bool\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"SCF Address\",\"filter\":\"0~16\",\"name\":\"scfAddress\",\"type\":\"string\",\"value\":\"0.0.0.0\"},{\"access\":\"read-write\",\"comment\":\"If add plus then set false\",\"display\":\"MT Id Format Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"mtIdFormatFlag\",\"type\":\"bool\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"enable mcast sms\",\"display\":\"Mcast Flag\",\"filter\":\"{\\\"0\\\":\\\"false\\\",\\\"1\\\":\\\"true\\\"}\",\"name\":\"mcastFlag\",\"type\":\"bool\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Log Level\",\"filter\":\"{\\\"0\\\":\\\"none\\\",\\\"1\\\":\\\"error\\\",\\\"2\\\":\\\"debug\\\"}\",\"name\":\"logLevel\",\"type\":\"enum\",\"value\":\"0\"},{\"access\":\"read-write\",\"comment\":\"The MB sizeof log file\",\"display\":\"Log Size\",\"filter\":\"1-1000\",\"name\":\"logSize\",\"type\":\"int\",\"value\":\"200\"},{\"access\":\"read-write\",\"comment\":\"The number of log file\",\"display\":\"Log Number\",\"filter\":\"1-20\",\"name\":\"logNum\",\"type\":\"int\",\"value\":\"10\"},{\"access\":\"read-write\",\"comment\":\"\",\"display\":\"Log Directory\",\"filter\":\"0~128\",\"name\":\"logDir\",\"type\":\"string\",\"value\":\"/var/log/\"}]', 1, '', 1747799255683, 'public'); diff --git a/src/framework/config/config.go b/src/framework/config/config.go index 4b53516d..9c382d6c 100644 --- a/src/framework/config/config.go +++ b/src/framework/config/config.go @@ -30,7 +30,7 @@ func initFlag() { pflag.String("env", "prod", "Specify Run Environment Configuration local or prod") // --c /etc/restconf.yaml // -c /etc/restconf.yaml - pflag.StringP("config", "c", "./etc/restconf.yaml", "Specify Configuration File") + pflag.StringP("config", "c", "/usr/local/omc/etc/restconf.yaml", "Specify Configuration File") // --version // -V pVersion := pflag.BoolP("version", "V", false, "Output program version") @@ -171,6 +171,13 @@ func Get(key string) any { return cfg.Get(key) } +// Set 设置配置信息 +// +// Set("redis.defaultDataSourceName", "std") +func Set(key string, value any) { + cfg.Set(key, value) +} + // GetAssetsDirFS 访问程序内全局资源访问 func GetAssetsDirFS() embed.FS { return cfg.Get("AssetsDir").(embed.FS) diff --git a/src/modules/network_element/controller/ne_config.go b/src/modules/network_element/controller/ne_config.go index 1badb9f0..d0d0ecb4 100644 --- a/src/modules/network_element/controller/ne_config.go +++ b/src/modules/network_element/controller/ne_config.go @@ -2,18 +2,19 @@ package controller import ( "encoding/json" - "strings" + "fmt" cm_omc "be.ems/features/cm/omc" "be.ems/src/framework/i18n" - "be.ems/src/framework/utils/ctx" + "be.ems/src/framework/reqctx" + "be.ems/src/framework/resp" "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" + traceService "be.ems/src/modules/trace/service" + "github.com/gin-gonic/gin" - "github.com/gin-gonic/gin/binding" ) // NewNeConfig 网元参数配置 实例化控制层 @@ -33,74 +34,74 @@ type NeConfigController struct { // 网元参数配置可用属性值列表 // // GET /list -func (s *NeConfigController) List(c *gin.Context) { - querys := ctx.QueryMapString(c) - rows, total := s.neConfigService.SelectPage(querys) - c.JSON(200, result.Ok(map[string]any{"total": total, "rows": rows})) +func (s NeConfigController) List(c *gin.Context) { + query := reqctx.QueryMap(c) + rows, total := s.neConfigService.SelectPage(query) + c.JSON(200, resp.OkData(map[string]any{"total": total, "rows": rows})) } // 网元参数配置可用属性值信息 // // GET /info/:id -func (s *NeConfigController) Info(c *gin.Context) { - language := ctx.AcceptLanguage(c) - id := c.Param("id") +func (s NeConfigController) Info(c *gin.Context) { + language := reqctx.AcceptLanguage(c) + id := c.Query("id") if id == "" { - c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: id is empty")) return } data := s.neConfigService.SelectById(id) if data.ID != id { // 没有可访问参数配置数据! - c.JSON(200, result.ErrMsg(i18n.TKey(language, "neConfig.noData"))) + c.JSON(200, resp.ErrMsg(i18n.TKey(language, "neConfig.noData"))) return } // 将字符串转json数据 if err := json.Unmarshal([]byte(data.ParamJson), &data.ParamData); err != nil { - c.JSON(400, result.CodeMsg(400, err.Error())) + c.JSON(400, resp.CodeMsg(400, err.Error())) return } - c.JSON(200, result.OkData(data)) + c.JSON(200, resp.OkData(data)) } // 网元参数配置可用属性值新增 // // POST / -func (s *NeConfigController) Add(c *gin.Context) { - language := ctx.AcceptLanguage(c) +func (s NeConfigController) Add(c *gin.Context) { 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"))) + if err := c.ShouldBindBodyWithJSON(&body); err != nil { + errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err)) + c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs)) return } // 将json数据转字符串存储 paramDataByte, err := json.Marshal(body.ParamData) if err != nil { - c.JSON(400, result.CodeMsg(400, err.Error())) + c.JSON(200, resp.ErrMsg(err.Error())) return } body.ParamJson = string(paramDataByte) insertId := s.neConfigService.Insert(body) if insertId != "" { - c.JSON(200, result.Ok(nil)) + c.JSON(200, resp.Ok(nil)) return } - c.JSON(200, result.Err(nil)) + c.JSON(200, resp.Err(nil)) } // 网元参数配置可用属性值修改 // // PUT / -func (s *NeConfigController) Edit(c *gin.Context) { - language := ctx.AcceptLanguage(c) +func (s NeConfigController) Edit(c *gin.Context) { + language := reqctx.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"))) + if err := c.ShouldBindBodyWithJSON(&body); err != nil { + errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err)) + c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs)) return } @@ -108,50 +109,50 @@ func (s *NeConfigController) Edit(c *gin.Context) { data := s.neConfigService.SelectById(body.ID) if data.ID != body.ID { // 没有可访问主机命令数据! - c.JSON(200, result.ErrMsg(i18n.TKey(language, "neConfig.noData"))) + c.JSON(200, resp.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())) + c.JSON(200, resp.ErrMsg(err.Error())) return } body.ParamJson = string(paramDataByte) rows := s.neConfigService.Update(body) if rows > 0 { - c.JSON(200, result.Ok(nil)) + c.JSON(200, resp.Ok(nil)) return } - c.JSON(200, result.Err(nil)) + c.JSON(200, resp.Err(nil)) } // 网元参数配置可用属性值删除 // // DELETE / -func (s *NeConfigController) Remove(c *gin.Context) { - language := ctx.AcceptLanguage(c) - id, okId := c.GetQuery("id") - if id == "" || !okId { - c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) +func (s NeConfigController) Remove(c *gin.Context) { + language := reqctx.AcceptLanguage(c) + id := c.Query("id") + if id == "" { + c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: id is empty")) return } + // 处理字符转id数组后去重 - idsArr := strings.Split(id, ",") - uniqueIDs := parse.RemoveDuplicates(idsArr) + uniqueIDs := parse.RemoveDuplicatesToArray(id, ",") if len(uniqueIDs) <= 0 { - c.JSON(200, result.Err(nil)) + c.JSON(200, resp.Err(nil)) return } rows, err := s.neConfigService.DeleteByIds(uniqueIDs) if err != nil { - c.JSON(200, result.ErrMsg(i18n.TKey(language, err.Error()))) + c.JSON(200, resp.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)) + c.JSON(200, resp.OkMsg(msg)) } // 网元参数配置可用属性值列表指定网元类型全部无分页 @@ -161,21 +162,20 @@ func (s *NeConfigController) Remove(c *gin.Context) { // @Tags network_element/config // @Accept json // @Produce json -// @Param neType path string true "NE Type" Enums(IMS,AMF,AUSF,UDM,SMF,PCF,NSSF,NRF,UPF,MME,CBC,OMC,SGWC) +// @Param neType path string true "NE Type" Enums(IMS,AMF,AUSF,UDM,SMF,PCF,NSSF,NRF,UPF,MME,CBC,OMC,SGWC,SMSC) // @Success 200 {object} object "Response Results" // @Security TokenAuth // @Summary Network Element Parameter Configuration Available Attribute Values List Specify Network Element Type All Unpaged // @Description Network Element Parameter Configuration Available Attribute Values List Specify Network Element Type All Unpaged // @Router /ne/config/list/{neType} [get] -func (s *NeConfigController) ListByNeType(c *gin.Context) { - language := ctx.AcceptLanguage(c) +func (s NeConfigController) ListByNeType(c *gin.Context) { neType := c.Param("neType") if neType == "" { - c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: neType is empty")) return } data := s.neConfigService.SelectNeConfigByNeType(neType) - c.JSON(200, result.OkData(data)) + c.JSON(200, resp.OkData(data)) } // 网元参数配置数据信息 @@ -185,7 +185,7 @@ func (s *NeConfigController) ListByNeType(c *gin.Context) { // @Tags network_element/config // @Accept json // @Produce json -// @Param neType query string true "NE Type" Enums(IMS,AMF,AUSF,UDM,SMF,PCF,NSSF,NRF,UPF,MME,CBC,OMC,SGWC) +// @Param neType query string true "NE Type" Enums(IMS,AMF,AUSF,UDM,SMF,PCF,NSSF,NRF,UPF,MME,CBC,OMC,SGWC,SMSC) // @Param neId query string true "NE ID" default(001) // @Param paramName query string true "Available attributes, based on querying the list of attributes" // @Success 200 {object} object "Response Results" @@ -193,43 +193,49 @@ func (s *NeConfigController) ListByNeType(c *gin.Context) { // @Summary Network Element Parameter Configuration Data Information // @Description Network Element Parameter Configuration Data Information // @Router /ne/config/data [get] -func (s *NeConfigController) DataInfo(c *gin.Context) { - language := ctx.AcceptLanguage(c) +func (s NeConfigController) DataInfo(c *gin.Context) { + language := reqctx.AcceptLanguage(c) var query struct { NeType string `form:"neType" binding:"required"` // 网元类型 NeId string `form:"neId" binding:"required"` // 网元ID ParamName string `form:"paramName" binding:"required"` // 可用属性 } if err := c.ShouldBindQuery(&query); err != nil { - c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err)) + c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs)) return } - neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(query.NeType, query.NeId) + neInfo := s.neInfoService.FindByNeTypeAndNeID(query.NeType, query.NeId) if neInfo.NeId != query.NeId || neInfo.IP == "" { - c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) + c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) return } if query.NeType == "OMC" { - var o *cm_omc.ConfigOMC - resData, err := o.Query(query.ParamName) - if err != nil { - c.JSON(200, result.ErrMsg(err.Error())) + if query.ParamName == "alarmEmailForward" || query.ParamName == "alarmSMSForward" { + var o *cm_omc.ConfigOMC + resData, err := o.Query(query.ParamName) + if err != nil { + c.JSON(200, resp.ErrMsg(err.Error())) + return + } + c.JSON(200, resp.OkData(resData)) return } - c.JSON(200, result.OkData(resData)) + resData := s.neConfigService.GetOMCYaml(query.ParamName) + c.JSON(200, resp.OkData(resData)) return } // 网元直连 resData, err := neFetchlink.NeConfigInfo(neInfo, query.ParamName) if err != nil { - c.JSON(200, result.ErrMsg(err.Error())) + c.JSON(200, resp.ErrMsg(err.Error())) return } - c.JSON(200, result.Ok(resData)) + c.JSON(200, resp.Ok(resData)) } // 网元参数配置数据修改 @@ -245,8 +251,8 @@ func (s *NeConfigController) DataInfo(c *gin.Context) { // @Summary Network element parameter configuration data modification // @Description Network element parameter configuration data modification // @Router /ne/config/data [put] -func (s *NeConfigController) DataEdit(c *gin.Context) { - language := ctx.AcceptLanguage(c) +func (s NeConfigController) DataEdit(c *gin.Context) { + language := reqctx.AcceptLanguage(c) var body struct { NeType string `json:"neType" binding:"required"` // 网元类型 NeId string `json:"neId" binding:"required"` // 网元ID @@ -254,34 +260,48 @@ func (s *NeConfigController) DataEdit(c *gin.Context) { ParamData map[string]any `json:"paramData" binding:"required"` Loc string `json:"loc"` // 仅array使用与数据对象内index一致,有多层时划分嵌套层(index/subParamName/index) } - if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil { - c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + if err := c.ShouldBindBodyWithJSON(&body); err != nil { + errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err)) + c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs)) return } - neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(body.NeType, body.NeId) + neInfo := s.neInfoService.FindByNeTypeAndNeID(body.NeType, body.NeId) if neInfo.NeId != body.NeId || neInfo.IP == "" { - c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) + c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) return } if body.NeType == "OMC" { - var o *cm_omc.ConfigOMC - resData, err := o.Modify(body.ParamName, body.ParamData) - if err != nil { - c.JSON(200, result.ErrMsg(err.Error())) + if body.ParamName == "alarmEmailForward" || body.ParamName == "alarmSMSForward" { + var o *cm_omc.ConfigOMC + resData, err := o.Modify(body.ParamName, body.ParamData) + if err != nil { + c.JSON(200, resp.ErrMsg(err.Error())) + return + } + c.JSON(200, resp.OkData(resData)) return } - c.JSON(200, result.OkData(resData)) + err := s.neConfigService.ModifyOMCYaml(body.ParamName, body.Loc, body.ParamData) + if err != nil { + c.JSON(200, resp.ErrMsg(err.Error())) + return + } + // 重开跟踪任务信令数据通道UDP + if body.ParamName == "trace" { + traceService.NewTraceTask.CreateUDP(true) + } + c.JSON(200, resp.Ok(nil)) return } // 网元直连 resData, err := neFetchlink.NeConfigUpdate(neInfo, body.ParamName, body.Loc, body.ParamData) if err != nil { - c.JSON(200, result.ErrMsg(err.Error())) + c.JSON(200, resp.ErrMsg(err.Error())) return } - c.JSON(200, result.OkData(resData)) + c.JSON(200, resp.OkData(resData)) } // 网元参数配置数据新增(array) @@ -297,8 +317,8 @@ func (s *NeConfigController) DataEdit(c *gin.Context) { // @Summary Network element parameter configuration data added (array) // @Description Network element parameter configuration data added (array) // @Router /ne/config/data [post] -func (s *NeConfigController) DataAdd(c *gin.Context) { - language := ctx.AcceptLanguage(c) +func (s NeConfigController) DataAdd(c *gin.Context) { + language := reqctx.AcceptLanguage(c) var body struct { NeType string `json:"neType" binding:"required"` // 网元类型 NeId string `json:"neId" binding:"required"` // 网元ID @@ -306,37 +326,38 @@ func (s *NeConfigController) DataAdd(c *gin.Context) { ParamData map[string]any `json:"paramData" binding:"required"` // 数据对象 Loc string `json:"loc" binding:"required"` // 与数据对象内index一致,有多层时划分嵌套层(index/subParamName/index) } - if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil { - c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + if err := c.ShouldBindBodyWithJSON(&body); err != nil { + errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err)) + c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs)) return } // 检查是否array info := s.neConfigService.SelectNeConfigByNeTypeAndParamName(body.NeType, body.ParamName) if info.ParamType != "array" { - c.JSON(400, result.CodeMsg(400, "this attribute does not support adding")) + c.JSON(200, resp.ErrMsg("this attribute does not support adding")) return } // 必须含有index _, idxOk := body.ParamData["index"] if info.ParamType == "array" && !idxOk { - c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + c.JSON(200, resp.ErrMsg("array data must contain index")) return } - neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(body.NeType, body.NeId) + neInfo := s.neInfoService.FindByNeTypeAndNeID(body.NeType, body.NeId) if neInfo.NeId != body.NeId || neInfo.IP == "" { - c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) + c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) return } // 网元直连 resData, err := neFetchlink.NeConfigInstall(neInfo, body.ParamName, body.Loc, body.ParamData) if err != nil { - c.JSON(200, result.ErrMsg(err.Error())) + c.JSON(200, resp.ErrMsg(err.Error())) return } - c.JSON(200, result.OkData(resData)) + c.JSON(200, resp.OkData(resData)) } // 网元参数配置数据删除(array) @@ -346,7 +367,7 @@ func (s *NeConfigController) DataAdd(c *gin.Context) { // @Tags network_element/config // @Accept json // @Produce json -// @Param neType query string true "NE Type" Enums(IMS,AMF,AUSF,UDM,SMF,PCF,NSSF,NRF,UPF,MME,CBC,OMC,SGWC) +// @Param neType query string true "NE Type" Enums(IMS,AMF,AUSF,UDM,SMF,PCF,NSSF,NRF,UPF,MME,CBC,OMC,SGWC,SMSC) // @Param neId query string true "NE ID" default(001) // @Param paramName query string true "Available attributes, based on querying the list of attributes" // @Param loc query string true "Array index" @@ -355,8 +376,8 @@ func (s *NeConfigController) DataAdd(c *gin.Context) { // @Summary Network element parameter configuration data deletion (array) // @Description Network element parameter configuration data deletion (array) // @Router /ne/config/data [delete] -func (s *NeConfigController) DataRemove(c *gin.Context) { - language := ctx.AcceptLanguage(c) +func (s NeConfigController) DataRemove(c *gin.Context) { + language := reqctx.AcceptLanguage(c) var query struct { NeType string `form:"neType" binding:"required"` // 网元类型 NeId string `form:"neId" binding:"required"` // 网元ID @@ -364,28 +385,29 @@ func (s *NeConfigController) DataRemove(c *gin.Context) { Loc string `form:"loc" binding:"required"` // 与数据对象内index一致,有多层时划分嵌套层(index/subParamName/index) } if err := c.ShouldBindQuery(&query); err != nil { - c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err)) + c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs)) return } // 检查是否array info := s.neConfigService.SelectNeConfigByNeTypeAndParamName(query.NeType, query.ParamName) if info.ParamType != "array" { - c.JSON(400, result.CodeMsg(400, "this attribute does not support adding")) + c.JSON(200, resp.ErrMsg("this attribute does not support adding")) return } - neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(query.NeType, query.NeId) + neInfo := s.neInfoService.FindByNeTypeAndNeID(query.NeType, query.NeId) if neInfo.NeId != query.NeId || neInfo.IP == "" { - c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) + c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) return } // 网元直连 resData, err := neFetchlink.NeConfigDelete(neInfo, query.ParamName, query.Loc) if err != nil { - c.JSON(200, result.ErrMsg(err.Error())) + c.JSON(200, resp.ErrMsg(err.Error())) return } - c.JSON(200, result.OkData(resData)) + c.JSON(200, resp.OkData(resData)) } diff --git a/src/modules/network_element/service/ne_config_omc.go b/src/modules/network_element/service/ne_config_omc.go new file mode 100644 index 00000000..61a2cb5e --- /dev/null +++ b/src/modules/network_element/service/ne_config_omc.go @@ -0,0 +1,56 @@ +package service + +import ( + "fmt" + "runtime" + "strings" + + "be.ems/src/framework/cmd" + "be.ems/src/framework/config" +) + +// GetOMCYaml 获取OMC网元配置文件 /usr/local/etc/omc/omc.yaml +func (r NeConfig) GetOMCYaml(paramName string) []map[string]any { + if paramName == "trace" { + traceData := config.Get("trace").(map[string]any) + return []map[string]any{traceData} + } + return []map[string]any{} +} + +// ModifyOMCYaml 修改OMC网元配置文件 /usr/local/etc/omc/omc.yaml +func (r NeConfig) ModifyOMCYaml(paramName, loc string, paramData any) error { + neConfig := r.SelectNeConfigByNeTypeAndParamName("OMC", paramName) + if neConfig.ParamType == "list" { + if paramName == "trace" { + configPath := fmt.Sprint(config.Get("config")) // 获取配置文件路径 + paramDataMap := paramData.(map[string]any) + for k, v := range paramDataMap { + config.Set(fmt.Sprintf("trace.%s", strings.ToLower(k)), v) + if runtime.GOOS == "windows" { + continue // Windows系统不支持sed命令 + } + // 修改参数较少,直接命令改文件内容 + if k == "enabled" { + // sed 's/enabled: \(true\|false\) # trace enabled/enabled: true # trace enabled/' /usr/local/etc/omc/omc.yaml + cmd.Execf("sed -i 's/enabled: \\(true\\|false\\) # trace enabled/enabled: %v # trace enabled/' %s", v, configPath) + } + if k == "host" { + // sed 's/host: ".*" # trace host/host: "127.2.2.2" # trace host/' /usr/local/etc/omc/omc.yaml + cmd.Execf("sed -i 's/host: \".*\" # trace host/host: \"%v\" # trace host/' %s", v, configPath) + } + if k == "port" { + // sed 's/port: [0-9]\+ # trace port/port: 6964 # trace port/' /usr/local/etc/omc/omc.yaml + cmd.Execf("sed -i 's/port: [0-9]\\+ # trace port/port: %v # trace port/' %s", v, configPath) + } + } + // 重开跟踪任务信令数据通道UDP + // service.NewTraceTask.CreateUDP(true) 方法导致循环引用,抛给上层调用 + return nil + } + } + if neConfig.ParamType == "array" { + // TODO + } + return fmt.Errorf("not found method paramName") +}