feat: 网元直连接口补充AMF/SMF/MME/IMS
This commit is contained in:
@@ -15,6 +15,7 @@ import (
|
||||
"be.ems/src/framework/vo/result"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
neDataService "be.ems/src/modules/network_data/service"
|
||||
neFetchlink "be.ems/src/modules/network_element/fetch_link"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
sysService "be.ems/src/modules/system/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -206,3 +207,36 @@ func (s *AMFController) UEExport(c *gin.Context) {
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
|
||||
// 接入基站信息列表
|
||||
//
|
||||
// GET /nb/list
|
||||
func (s *AMFController) NbInfoList(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
NeId string `form:"neId" binding:"required"`
|
||||
NbId string `form:"nbId"`
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("AMF", query.NeId)
|
||||
if neInfo.NeId != query.NeId || neInfo.IP == "" {
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
data, err := neFetchlink.AMFNbInfoList(neInfo, map[string]string{
|
||||
"nbId": query.NbId,
|
||||
})
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, result.OkData(data))
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"be.ems/src/framework/vo/result"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
neDataService "be.ems/src/modules/network_data/service"
|
||||
neFetchlink "be.ems/src/modules/network_element/fetch_link"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
sysService "be.ems/src/modules/system/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -215,3 +216,68 @@ func (s *IMSController) CDRExport(c *gin.Context) {
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
|
||||
// 在线会话用户数量
|
||||
//
|
||||
// GET /session/num
|
||||
func (s *IMSController) UeSessionNum(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
NeId string `form:"neId" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("IMS", query.NeId)
|
||||
if neInfo.NeId != query.NeId || neInfo.IP == "" {
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
num, err := neFetchlink.IMSUeSessionNum(neInfo)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, result.OkData(num))
|
||||
}
|
||||
|
||||
// 在线会话用户列表信息
|
||||
//
|
||||
// GET /session/list
|
||||
func (s *IMSController) UeSessionList(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
NeId string `form:"neId" binding:"required"`
|
||||
IMSI string `form:"imsi"`
|
||||
MSISDN string `form:"msisdn"`
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("IMS", query.NeId)
|
||||
if neInfo.NeId != query.NeId || neInfo.IP == "" {
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
data, err := neFetchlink.IMSUeSessionList(neInfo, map[string]string{
|
||||
"imsi": query.IMSI,
|
||||
"msisdn": query.MSISDN,
|
||||
})
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, result.OkData(data))
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"be.ems/src/framework/vo/result"
|
||||
"be.ems/src/modules/network_data/model"
|
||||
neDataService "be.ems/src/modules/network_data/service"
|
||||
neFetchlink "be.ems/src/modules/network_element/fetch_link"
|
||||
neService "be.ems/src/modules/network_element/service"
|
||||
sysService "be.ems/src/modules/system/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -196,3 +197,36 @@ func (s *MMEController) UEExport(c *gin.Context) {
|
||||
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
|
||||
// 接入基站信息列表
|
||||
//
|
||||
// GET /nb/list
|
||||
func (s *MMEController) NbInfoList(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
NeId string `form:"neId" binding:"required"`
|
||||
NbId string `form:"nbId"`
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("MME", query.NeId)
|
||||
if neInfo.NeId != query.NeId || neInfo.IP == "" {
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
data, err := neFetchlink.MMENbInfoList(neInfo, map[string]string{
|
||||
"nbId": query.NbId,
|
||||
})
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, result.OkData(data))
|
||||
}
|
||||
|
||||
@@ -317,9 +317,39 @@ func (s *SMFController) CDRExport(c *gin.Context) {
|
||||
c.FileAttachment(saveFilePath, fileName)
|
||||
}
|
||||
|
||||
// 在线订阅用户数量
|
||||
//
|
||||
// GET /sub/num
|
||||
func (s *SMFController) SubUserNum(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
NeId string `form:"neId" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("SMF", query.NeId)
|
||||
if neInfo.NeId != query.NeId || neInfo.IP == "" {
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
// 网元直连
|
||||
num, err := neFetchlink.SMFSubNum(neInfo)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, result.OkData(num))
|
||||
}
|
||||
|
||||
// 在线订阅用户列表信息
|
||||
//
|
||||
// GET /subscribers
|
||||
// GET /sub/list
|
||||
func (s *SMFController) SubUserList(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var query struct {
|
||||
@@ -334,7 +364,7 @@ func (s *SMFController) SubUserList(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元信息 rmUID
|
||||
// 查询网元信息
|
||||
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("SMF", query.NeId)
|
||||
if neInfo.NeId != query.NeId || neInfo.IP == "" {
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
|
||||
@@ -59,6 +59,14 @@ func Setup(router *gin.Engine) {
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.imsCDR", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||
controller.NewIMS.CDRExport,
|
||||
)
|
||||
imsGroup.GET("/session/num",
|
||||
middleware.PreAuthorize(nil),
|
||||
controller.NewIMS.UeSessionNum,
|
||||
)
|
||||
imsGroup.GET("/session/list",
|
||||
middleware.PreAuthorize(nil),
|
||||
controller.NewIMS.UeSessionList,
|
||||
)
|
||||
}
|
||||
|
||||
// 网元SMSC
|
||||
@@ -97,7 +105,11 @@ func Setup(router *gin.Engine) {
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.smfCDR", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||
controller.NewSMF.CDRExport,
|
||||
)
|
||||
smfGroup.GET("/subscribers",
|
||||
smfGroup.GET("/sub/num",
|
||||
middleware.PreAuthorize(nil),
|
||||
controller.NewSMF.SubUserNum,
|
||||
)
|
||||
smfGroup.GET("/sub/list",
|
||||
middleware.PreAuthorize(nil),
|
||||
controller.NewSMF.SubUserList,
|
||||
)
|
||||
@@ -120,6 +132,10 @@ func Setup(router *gin.Engine) {
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.amfUE", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||
controller.NewAMF.UEExport,
|
||||
)
|
||||
amfGroup.GET("/nb/list",
|
||||
middleware.PreAuthorize(nil),
|
||||
controller.NewAMF.NbInfoList,
|
||||
)
|
||||
}
|
||||
|
||||
// 网元UPF
|
||||
@@ -256,5 +272,9 @@ func Setup(router *gin.Engine) {
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.mmeUE", collectlogs.BUSINESS_TYPE_EXPORT)),
|
||||
controller.NewMME.UEExport,
|
||||
)
|
||||
mmeGroup.GET("/nb/list",
|
||||
middleware.PreAuthorize(nil),
|
||||
controller.NewMME.NbInfoList,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
50
src/modules/network_element/fetch_link/amf.go
Normal file
50
src/modules/network_element/fetch_link/amf.go
Normal file
@@ -0,0 +1,50 @@
|
||||
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"
|
||||
)
|
||||
|
||||
// AMFNbInfoList AMF基站信息
|
||||
//
|
||||
// 查询参数 {"nbId":"7"}
|
||||
//
|
||||
// 返回结果 []
|
||||
func AMFNbInfoList(neInfo model.NeInfo, data map[string]string) ([]map[string]any, error) {
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/amf/objectType/nbInfo", neInfo.IP, neInfo.Port)
|
||||
// 查询参数拼接
|
||||
query := []string{}
|
||||
if v, ok := data["nbId"]; ok && v != "" {
|
||||
query = append(query, fmt.Sprintf("nbId=%s", v))
|
||||
}
|
||||
if len(query) > 0 {
|
||||
neUrl = fmt.Sprintf("%s?%s", neUrl, strings.Join(query, "&"))
|
||||
}
|
||||
|
||||
var resData map[string]any
|
||||
resBytes, err := fetch.Get(neUrl, nil, 60_000)
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
logger.Warnf("AMFNbInfoList Get \"%s\"", neUrl)
|
||||
logger.Errorf("AMFNbInfoList %s", errStr)
|
||||
return nil, fmt.Errorf("NeService AMF API Error")
|
||||
}
|
||||
|
||||
// 序列化结果 {"data":[{"id":"7","name":"NR-SA-GNB","address":"192.168.5.100:60110","ueNum":0}]}
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("AMFNbInfoList Unmarshal %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 固定返回字段,方便前端解析
|
||||
if v, ok := resData["data"]; ok && v != nil {
|
||||
return v.([]map[string]any), nil
|
||||
}
|
||||
return []map[string]any{}, nil
|
||||
}
|
||||
94
src/modules/network_element/fetch_link/ims.go
Normal file
94
src/modules/network_element/fetch_link/ims.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package fetchlink
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/fetch"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/modules/network_element/model"
|
||||
)
|
||||
|
||||
// IMSUeSessionNum IMS会话数量
|
||||
//
|
||||
// 返回结果 0
|
||||
func IMSUeSessionNum(neInfo model.NeInfo) (int64, error) {
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/ims/objectType/ueNum", neInfo.IP, neInfo.Port)
|
||||
resBytes, err := fetch.Get(neUrl, nil, 60_000)
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
logger.Warnf("IMSUeSessionNum Get \"%s\"", neUrl)
|
||||
logger.Errorf("IMSUeSessionNum %s", errStr)
|
||||
return 0, fmt.Errorf("NeService IMS API Error")
|
||||
}
|
||||
// 序列化结果 {"data":{"ueNum":0}}
|
||||
var resData map[string]any
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("IMSUeSessionNum Unmarshal %s", err.Error())
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 固定返回字段,方便前端解析
|
||||
var ueNum int64 = 0
|
||||
if v, ok := resData["data"]; ok && v != nil {
|
||||
if num := v.(map[string]any)["ueNum"]; num != nil {
|
||||
ueNum = parse.Number(num)
|
||||
}
|
||||
}
|
||||
return ueNum, nil
|
||||
}
|
||||
|
||||
// IMSUeSessionList IMS会话列表
|
||||
//
|
||||
// 查询参数 {"imsi":"460001230000002","msisdn":"12307551232"}
|
||||
//
|
||||
// 返回结果 []
|
||||
func IMSUeSessionList(neInfo model.NeInfo, data map[string]string) ([]map[string]any, error) {
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/ims/objectType/ueInfo", neInfo.IP, neInfo.Port)
|
||||
// 查询参数拼接
|
||||
query := []string{}
|
||||
if v, ok := data["imsi"]; ok && v != "" {
|
||||
query = append(query, fmt.Sprintf("imsi=%s", v))
|
||||
}
|
||||
if v, ok := data["msisdn"]; ok && v != "" {
|
||||
query = append(query, fmt.Sprintf("msisdn=%s", v))
|
||||
}
|
||||
if len(query) > 0 {
|
||||
neUrl = fmt.Sprintf("%s?%s", neUrl, strings.Join(query, "&"))
|
||||
}
|
||||
|
||||
resBytes, err := fetch.Get(neUrl, nil, 60_000)
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
logger.Warnf("IMSUeSessionList Get \"%s\"", neUrl)
|
||||
logger.Errorf("IMSUeSessionList %s", errStr)
|
||||
return nil, fmt.Errorf("NeService IMS API Error")
|
||||
}
|
||||
|
||||
// 序列化结果
|
||||
// { "data":[
|
||||
// {
|
||||
// "activeTime": "2023-11-29 17:04:54",
|
||||
// "barring": 0,
|
||||
// "impu": "sip:12307551232@ims.mnc000.mcc460.3gppnetwork.org",
|
||||
// "imsi": "460001230000002",
|
||||
// "msisdn": "12307551232",
|
||||
// "regState": 1
|
||||
// }
|
||||
// ] }
|
||||
var resData map[string]any
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("IMSUeSessionList Unmarshal %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 固定返回字段,方便前端解析
|
||||
if v, ok := resData["data"]; ok && v != nil {
|
||||
return v.([]map[string]any), nil
|
||||
}
|
||||
return []map[string]any{}, nil
|
||||
}
|
||||
50
src/modules/network_element/fetch_link/mme.go
Normal file
50
src/modules/network_element/fetch_link/mme.go
Normal file
@@ -0,0 +1,50 @@
|
||||
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"
|
||||
)
|
||||
|
||||
// MMENbInfoList AMF基站信息
|
||||
//
|
||||
// 查询参数 {"nbId":"7"}
|
||||
//
|
||||
// 返回结果 []
|
||||
func MMENbInfoList(neInfo model.NeInfo, data map[string]string) ([]map[string]any, error) {
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/mme/objectType/nbInfo", neInfo.IP, neInfo.Port)
|
||||
// 查询参数拼接
|
||||
query := []string{}
|
||||
if v, ok := data["nbId"]; ok && v != "" {
|
||||
query = append(query, fmt.Sprintf("nbId=%s", v))
|
||||
}
|
||||
if len(query) > 0 {
|
||||
neUrl = fmt.Sprintf("%s?%s", neUrl, strings.Join(query, "&"))
|
||||
}
|
||||
|
||||
var resData map[string]any
|
||||
resBytes, err := fetch.Get(neUrl, nil, 60_000)
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
logger.Warnf("MMENbInfoList Get \"%s\"", neUrl)
|
||||
logger.Errorf("MMENbInfoList %s", errStr)
|
||||
return nil, fmt.Errorf("NeService AMF API Error")
|
||||
}
|
||||
|
||||
// 序列化结果 {"data":[{"id":"7","name":"NR-SA-GNB","address":"192.168.5.100:60110","ueNum":0}]}
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("MMENbInfoList Unmarshal %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 固定返回字段,方便前端解析
|
||||
if v, ok := resData["data"]; ok && v != nil {
|
||||
return v.([]map[string]any), nil
|
||||
}
|
||||
return []map[string]any{}, nil
|
||||
}
|
||||
@@ -7,9 +7,40 @@ import (
|
||||
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/fetch"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/modules/network_element/model"
|
||||
)
|
||||
|
||||
// SMFSubNum SMF在线订阅用户数量 只含5G用户数据
|
||||
//
|
||||
// 返回结果 0
|
||||
func SMFSubNum(neInfo model.NeInfo) (int64, error) {
|
||||
neUrl := fmt.Sprintf("http://%s:%d/api/rest/ueManagement/v1/elementType/smf/objectType/ueNum", neInfo.IP, neInfo.Port)
|
||||
resBytes, err := fetch.Get(neUrl, nil, 60_000)
|
||||
if err != nil {
|
||||
errStr := err.Error()
|
||||
logger.Warnf("SMFSubNum Get \"%s\"", neUrl)
|
||||
logger.Errorf("SMFSubNum %s", errStr)
|
||||
return 0, fmt.Errorf("NeService SMF API Error")
|
||||
}
|
||||
// 序列化结果 {"data":{"ueNum":0}}
|
||||
var resData map[string]any
|
||||
err = json.Unmarshal(resBytes, &resData)
|
||||
if err != nil {
|
||||
logger.Errorf("IMSUeSession Unmarshal %s", err.Error())
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 固定返回字段,方便前端解析
|
||||
var ueNum int64 = 0
|
||||
if v, ok := resData["data"]; ok && v != nil {
|
||||
if num := v.(map[string]any)["ueNum"]; num != nil {
|
||||
ueNum = parse.Number(num)
|
||||
}
|
||||
}
|
||||
return ueNum, nil
|
||||
}
|
||||
|
||||
// SMFSubInfoList SMF在线订阅用户列表信息
|
||||
//
|
||||
// 查询参数 {"imsi":"360000100000130","msisdn":"8612300000130","upstate":"Inactive","pageNum":"1"}
|
||||
|
||||
Reference in New Issue
Block a user