package controller import ( "fmt" "sync" "be.ems/src/framework/i18n" "be.ems/src/framework/reqctx" "be.ems/src/framework/resp" "be.ems/src/framework/utils/parse" "be.ems/src/modules/ne/model" "be.ems/src/modules/ne/service" coreService "be.ems/src/modules/ne_core/service" neFetchlink "be.ems/src/modules/ne_data_nf/fetch_link" "github.com/gin-gonic/gin" ) // 实例化控制层 NeInfoController 结构体 var NewNeInfo = &NeInfoController{ neInfoService: service.NewNeInfo, coreInfoService: coreService.NewCoreInfo, } // 网元信息请求 // // PATH /info type NeInfoController struct { neInfoService *service.NeInfo // 网元信息服务 coreInfoService *coreService.CoreInfo } // neStateCacheMap 网元状态缓存最后一次成功的信息 var neStateCacheMap sync.Map var mutex sync.Mutex // 网元信息状态 // // GET /state // // @Tags network_element/info // @Accept json // @Produce json // @Param neUid query string true "NE UID" default(8I73Y01Z)// @Success 200 {object} object "Response Results" // @Security TokenAuth // @Summary Network element information state // @Description Network element information state // @Router /ne/info/state [get] func (s NeInfoController) State(c *gin.Context) { language := reqctx.AcceptLanguage(c) var query struct { NeUID string `form:"neUid" binding:"required"` // 网元唯一标识 } if err := c.ShouldBindQuery(&query); 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.FindByNeUid(query.NeUID) if neInfo.ID == 0 || neInfo.NeUid != query.NeUID { c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) return } neKey := fmt.Sprintf("%s_%s", neInfo.NeUid, neInfo.NeType) // 网元直连 resData, err := neFetchlink.NeState(neInfo) if err != nil { mutex.Lock() // 异常取上次缓存 resDataCache, ok := neStateCacheMap.Load(neKey) if ok && resDataCache != nil { resDataCache.(map[string]any)["online"] = false } else { resDataCache = map[string]any{ "online": false, "coreId": neInfo.CoreId, "neId": neInfo.ID, "neUid": neInfo.NeUid, "neType": neInfo.NeType, "neName": neInfo.NeName, "ipAddr": neInfo.IpAddr, } } neStateCacheMap.Store(neKey, resDataCache) mutex.Unlock() c.JSON(200, resp.OkData(resDataCache)) return } // 存入缓存 resData["online"] = true mutex.Lock() neStateCacheMap.Store(neKey, resData) mutex.Unlock() c.JSON(200, resp.OkData(resData)) } // 网元信息查询 // // GET /nf // // @Tags network_element/info // @Accept json // @Produce json // @Param neUid query string true "NE UID" default(8I73Y01Z)// @Success 200 {object} object "Response Results" // @Security TokenAuth // @Summary Network element neType and neID queries // @Description Network element neType and neID queries // @Router /ne/info/nf [get] func (s NeInfoController) Nf(c *gin.Context) { language := reqctx.AcceptLanguage(c) var query struct { NeUID string `form:"neUid" binding:"required"` // 网元唯一标识 } if err := c.ShouldBindQuery(&query); 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.FindByNeUid(query.NeUID) if neInfo.ID == 0 || neInfo.NeUid != query.NeUID { c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) return } // 关联核心网信息 coreInfo := s.coreInfoService.FindByCoreId(neInfo.CoreId) if coreInfo.ID == neInfo.CoreId { neInfo.CoreName = coreInfo.CoreName neInfo.CoreUid = coreInfo.CoreUid } c.JSON(200, resp.OkData(neInfo)) } // 网元信息列表全部无分页 // // GET /list/all // // @Tags network_element/info // @Accept json // @Produce json // @Param neUid query string true "NE UID" default(8I73Y01Z)// @Param neType query string true "NE Type" // @Param bandStatus query boolean true "With status information" // @Param bandHost query boolean true "With host information" // @Success 200 {object} object "Response Results" // @Security TokenAuth // @Summary The list of network element information is all unpaginated // @Description The list of network element information is all unpaginated // @Router /ne/info/list/all [get] func (s NeInfoController) ListAll(c *gin.Context) { language := reqctx.AcceptLanguage(c) var querys struct { CoreUid string `form:"coreUid"` // 核心网唯一标识 NeUid string `form:"neUid"` // 网元唯一标识 NeType string `form:"neType"` BandStatus bool `form:"bandStatus"` BandHost bool `form:"bandHost"` } if err := c.ShouldBindQuery(&querys); err != nil { errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err)) c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs)) return } // 查询实体参数 ne := model.NeInfo{} if querys.CoreUid != "" { // 检查是否存在 coreInfo := s.coreInfoService.FindByCoreUid(querys.CoreUid) if coreInfo.ID == 0 || coreInfo.CoreUid != querys.CoreUid { c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noCoreInfo"))) return } ne.CoreId = coreInfo.ID } if querys.NeUid != "" { ne.NeUid = querys.NeUid } if querys.NeType != "" { ne.NeType = querys.NeType } neList := s.neInfoService.Find(ne, querys.BandStatus, querys.BandHost) if len(neList) == 0 { c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) return } // 过滤处理 arr := &neList for i := range *arr { // 关联核心网信息 coreId := (*arr)[i].CoreId coreInfo := s.coreInfoService.FindByCoreId(coreId) if coreInfo.ID == coreId { (*arr)[i].CoreName = coreInfo.CoreName (*arr)[i].CoreUid = coreInfo.CoreUid } // 过滤屏蔽授权文件 (*arr)[i].ActivationRequestCode = "-" (*arr)[i].LicensePath = "-" } c.JSON(200, resp.OkData(neList)) } // 网元授权激活授权申请码 // // GET /license/code // // @Tags network_element/license // @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,SMSC) // @Param neId query string true "NE ID" default(001) // @Success 200 {object} object "Response Results" // @Security TokenAuth // @Summary Network Element License Activation License Application Code // @Description Network Element License Activation License Application Code // @Router /ne/info/license/code [get] func (s NeInfoController) LicenseCode(c *gin.Context) { language := reqctx.AcceptLanguage(c) var query struct { NeUID string `form:"neUid" binding:"required"` // 网元唯一标识 } if err := c.ShouldBindQuery(&query); err != nil { errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err)) c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs)) return } // 查询网元获取IP neInfo := s.neInfoService.FindByNeUid(query.NeUID) if neInfo.ID == 0 || neInfo.NeUid != query.NeUID { c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) return } // 读取授权码 code, licensePath := s.neInfoService.NeConfLicenseRead(neInfo) // 更新授权码 if code != "" && licensePath != "" && neInfo.ActivationRequestCode != code { // 检查是否存在 neInfo = s.neInfoService.FindById(neInfo.ID, false) if neInfo.ID == 0 || neInfo.NeUid == "" { // 没有可访问网元信息数据! c.JSON(200, resp.ErrMsg(i18n.TKey(language, "neInfo.noData"))) return } neInfo.ActivationRequestCode = code neInfo.LicensePath = licensePath neInfo.UpdateBy = reqctx.LoginUserToUserName(c) s.neInfoService.Update(neInfo) } c.JSON(200, resp.OkData(code)) } // 网元授权激活授权文件替换 // // POST /license/update // // @Tags network_element/license // @Accept json // @Produce json // @Param data body object true "Request Param" // @Success 200 {object} object "Response Results" // @Security TokenAuth // @Summary Network element authorization activation status // @Description Network element authorization activation status // @Router /ne/license/update [post] func (s NeInfoController) LicenseUpdate(c *gin.Context) { language := reqctx.AcceptLanguage(c) var body struct { NeUID string `json:"neUid" binding:"required"` // 网元唯一标识 LicensePath string `json:"licensePath"` // 上传的文件路径 Reload bool `json:"reload"` // 刷新重启网元 } 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 } // 查询网元获取IP neInfo := s.neInfoService.FindByNeUid(body.NeUID) if neInfo.ID == 0 || neInfo.NeUid != body.NeUID { c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) return } // 进行上传替换 neInfo.LicensePath = body.LicensePath err := s.neInfoService.NeConfLicenseUpload(neInfo, body.Reload) if err != nil { c.JSON(200, resp.ErrMsg(err.Error())) return } // 检查是否存在 neInfo = s.neInfoService.FindById(neInfo.ID, false) if neInfo.ID == 0 || neInfo.NeUid == "" { // 没有可访问网元信息数据! c.JSON(200, resp.ErrMsg(i18n.TKey(language, "neInfo.noData"))) return } neInfo.LicensePath = body.LicensePath neInfo.UpdateBy = reqctx.LoginUserToUserName(c) s.neInfoService.Update(neInfo) c.JSON(200, resp.Ok(nil)) } // 网元端Para5G配置文件读取 // // GET /file/para5g func (s NeInfoController) Para5GFileRead(c *gin.Context) { data, err := s.neInfoService.NeConfPara5GRead() if err != nil { c.JSON(200, resp.ErrMsg(err.Error())) return } c.JSON(200, resp.OkData(data)) } // 网元端Para5G配置文件写入 // // PUT /file/para5g func (s NeInfoController) Para5GFileWrite(c *gin.Context) { var body struct { Content map[string]any `json:"content" binding:"required"` // 内容 SyncNE []string `json:"syncNe"` // 同步到网元neUid,neUid网元唯一标识 } 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 } err := s.neInfoService.NeConfPara5GWirte(body.Content, body.SyncNE) if err != nil { c.JSON(200, resp.ErrMsg(err.Error())) return } c.JSON(200, resp.Ok(nil)) } // 网元端OAM配置文件读取 // // GET /file/oam func (s NeInfoController) OAMFileRead(c *gin.Context) { language := reqctx.AcceptLanguage(c) var query struct { NeUID string `form:"neUid" binding:"required"` // 网元唯一标识 } if err := c.ShouldBindQuery(&query); err != nil { errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err)) c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs)) return } // 查询网元获取IP neInfo := s.neInfoService.FindByNeUid(query.NeUID) if neInfo.ID == 0 || neInfo.NeUid != query.NeUID { c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) return } data, err := s.neInfoService.NeConfOAMReadSync(neInfo) if err != nil { c.JSON(200, resp.ErrMsg(err.Error())) return } c.JSON(200, resp.OkData(data)) } // 网元端OAM配置文件写入 // // PUT /file/oam func (s NeInfoController) OAMFileWrite(c *gin.Context) { language := reqctx.AcceptLanguage(c) var body struct { NeUID string `form:"neUid" binding:"required"` // 网元唯一标识 Content map[string]any `json:"content" binding:"required"` // 内容 Sync bool `json:"sync"` // 同步到网元 } 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 } // 查询网元获取IP neInfo := s.neInfoService.FindByNeUid(body.NeUID) if neInfo.ID == 0 || neInfo.NeUid != body.NeUID { c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) return } err := s.neInfoService.NeConfOAMWirteSync(neInfo, body.Content, body.Sync) if err != nil { c.JSON(200, resp.ErrMsg(err.Error())) return } c.JSON(200, resp.Ok(nil)) } // 网元信息列表 // // GET /list // // @Tags network_element/info // @Accept json // @Produce json // @Param bandStatus query boolean false "The result carries the state of the network element" // @Param neId query string false "NE ID" // @Param neType query string false "Ne Type" // @Param pageNum query number true "pageNum" default(1) // @Param pageSize query number true "pageSize" default(10) // @Success 200 {object} object "Response Results" // @Security TokenAuth // @Summary Network element information list // @Description Network element information list // @Router /ne/info/list [get] func (s NeInfoController) List(c *gin.Context) { query := reqctx.QueryMap(c) bandStatus := false if v, ok := query["bandStatus"]; ok { bandStatus = parse.Boolean(v) } if v, ok := query["coreUid"]; ok { // 检查是否存在 coreInfo := s.coreInfoService.FindByCoreUid(v) if coreInfo.ID != 0 && coreInfo.CoreUid == v { query["coreId"] = fmt.Sprint(coreInfo.ID) } } rows, total := s.neInfoService.FindByPage(query, bandStatus) // 过滤处理 arr := &rows for i := range *arr { // 关联核心网信息 coreId := (*arr)[i].CoreId coreInfo := s.coreInfoService.FindByCoreId(coreId) if coreInfo.ID == coreId { (*arr)[i].CoreName = coreInfo.CoreName (*arr)[i].CoreUid = coreInfo.CoreUid } // 过滤屏蔽授权文件 (*arr)[i].ActivationRequestCode = "-" (*arr)[i].LicensePath = "-" } c.JSON(200, resp.OkData(map[string]any{"rows": rows, "total": total})) } // 网元信息 // // GET / // // @Tags network_element/info // @Accept json // @Produce json // @Param value path string true "Row ID" // @Success 200 {object} object "Response Results" // @Security TokenAuth // @Summary Network element information // @Description Network element information // @Router /ne/info [get] func (s NeInfoController) Info(c *gin.Context) { language := reqctx.AcceptLanguage(c) var query struct { ID int64 `form:"id" binding:"required"` // ID } if err := c.ShouldBindQuery(&query); err != nil { errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err)) c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs)) return } info := s.neInfoService.FindById(query.ID, true) if info.ID != query.ID { // 没有可访问网元信息数据! c.JSON(200, resp.ErrMsg(i18n.TKey(language, "neInfo.noData"))) return } c.JSON(200, resp.OkData(info)) } // 网元信息新增 // // POST / // // @Tags network_element/info // @Accept json // @Produce json // @Param data body object true "Request Param" // @Success 200 {object} object "Response Results" // @Security TokenAuth // @Summary Network element information addition // @Description Network element information addition // @Router /ne/info [post] func (s NeInfoController) Add(c *gin.Context) { var body model.NeInfo err := c.ShouldBindBodyWithJSON(&body) if err != nil { errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err)) c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs)) return } if body.ID != 0 { c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: id not is empty")) return } body.CreateBy = reqctx.LoginUserToUserName(c) insertId := s.neInfoService.Insert(body) if insertId > 0 { c.JSON(200, resp.OkData(insertId)) return } c.JSON(200, resp.Err(nil)) } // 网元信息修改 // // PUT / // // @Tags network_element/info // @Accept json // @Produce json // @Param data body object true "Request Param" // @Success 200 {object} object "Response Results" // @Security TokenAuth // @Summary Network element information modification // @Description Network element information modification // @Router /ne/info [put] func (s NeInfoController) Edit(c *gin.Context) { language := reqctx.AcceptLanguage(c) var body model.NeInfo err := c.ShouldBindBodyWithJSON(&body) if err != nil { errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err)) c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs)) return } if body.ID <= 0 { c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: id is empty")) return } // 检查是否存在 neInfo := s.neInfoService.FindById(body.ID, false) if neInfo.ID != body.ID { // 没有可访问网元信息数据! c.JSON(200, resp.ErrMsg(i18n.TKey(language, "neInfo.noData"))) return } body.UpdateBy = reqctx.LoginUserToUserName(c) rows := s.neInfoService.Update(body) if rows > 0 { c.JSON(200, resp.Ok(nil)) return } c.JSON(200, resp.Err(nil)) } // 网元信息删除 // // DELETE / // // @Tags network_element/info // @Accept json // @Produce json // @Param value path string true "Row ID" // @Success 200 {object} object "Response Results" // @Security TokenAuth // @Summary Network element information deletion // @Description Network element information deletion // @Router /ne/info [delete] func (s NeInfoController) Remove(c *gin.Context) { language := reqctx.AcceptLanguage(c) var query struct { ID string `form:"id" binding:"required"` // 记录ID 批量多个逗号分隔 } if err := c.ShouldBindQuery(&query); err != nil { errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err)) c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs)) return } // 处理字符转id数组后去重 uniqueIDs := parse.RemoveDuplicatesToArray(query.ID, ",") // 转换成int64数组类型 ids := make([]int64, 0) for _, v := range uniqueIDs { ids = append(ids, parse.Number(v)) } rows, err := s.neInfoService.DeleteByIds(ids) if err != nil { 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, resp.OkMsg(msg)) } // 网元信息关联核心网 // // PUT / // // @Tags network_element/info // @Accept json // @Produce json // @Param data body object true "Request Param" // @Success 200 {object} object "Response Results" // @Security TokenAuth // @Summary Network element information modification // @Description Network element information modification // @Router /ne/info/core [put] func (s NeInfoController) Core(c *gin.Context) { language := reqctx.AcceptLanguage(c) var body struct { NeUID string `json:"neUid" binding:"required"` // 网元唯一标识 CoreUID string `json:"coreUid" binding:"required"` // 核心网唯一标识 } err := c.ShouldBindBodyWithJSON(&body) if err != nil { errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err)) c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs)) return } // 查询网元获取IP neInfo := s.neInfoService.FindByNeUid(body.NeUID) if neInfo.ID == 0 || neInfo.NeUid != body.NeUID { c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) return } // 查询核心网ID var coreId int64 = 0 if len(body.CoreUID) == 8 { // 检查是否存在 coreInfo := s.coreInfoService.FindByCoreUid(body.CoreUID) if coreInfo.ID == 0 || coreInfo.CoreUid != body.CoreUID { c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noCoreInfo"))) return } coreId = coreInfo.ID } rows := s.neInfoService.UpdateCoreId(neInfo.ID, coreId) if rows > 0 { c.JSON(200, resp.Ok(nil)) return } c.JSON(200, resp.Err(nil)) }