Merge remote-tracking branch 'origin/main' into practical-training

This commit is contained in:
TsMask
2024-06-26 10:51:44 +08:00
18 changed files with 824 additions and 67 deletions

View File

@@ -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

View File

@@ -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)
}

View File

@@ -0,0 +1,202 @@
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 /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
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))
}

View File

@@ -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 {

View File

@@ -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"])

View File

@@ -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 Get \"%s\"", err.Error(), neUrl)
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
}

View File

@@ -1,4 +1,4 @@
package service
package fetchlink
import (
"encoding/json"
@@ -54,42 +54,3 @@ func NeState(neInfo model.NeInfo) (map[string]any, error) {
"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
}

View File

@@ -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"
}

View File

@@ -15,7 +15,6 @@ type NeSoftware struct {
// ====== 非数据库字段属性 ======
NeId string `json:"neId,omitempty" gorm:"-"` // 网元ID
}
// TableName 表名称

View File

@@ -257,6 +257,41 @@ 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("/list/:neType",
middleware.PreAuthorize(nil),
controller.NewNeConfig.ListByNeType,
)
neConfigGroup.GET("/data",
middleware.PreAuthorize(nil),
controller.NewNeConfig.Data,
)
}
}
// InitLoad 初始参数
@@ -268,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("*")
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -0,0 +1,33 @@
package service
import "be.ems/src/modules/network_element/model"
// INeConfig 网元参数配置可用属性值 服务层接口
type INeConfig interface {
// 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 根据实体查询
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)
}

View File

@@ -0,0 +1,151 @@
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"
)
// NewNeConfigImpl 网元参数配置可用属性值 实例化服务层
var NewNeConfigImpl = &NeConfigImpl{
neConfigRepository: repository.NewNeConfigImpl,
}
// NeConfigImpl 网元参数配置可用属性值 服务层处理
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)
}
// 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")
}

View File

@@ -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 {

View File

@@ -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"
}

View File

@@ -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" {

View File

@@ -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,