diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 00000000..7e257db9
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": []
+}
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 00000000..b2a7dbee
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,16 @@
+{
+ // 使用 IntelliSense 了解相关属性。
+ // 悬停以查看现有属性的描述。
+ // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "调试模式",
+ "type": "go",
+ "request": "launch",
+ "mode": "debug",
+ "program": "./restagent/restagent.go",
+ "console": "integratedTerminal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 00000000..351b8eaf
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "commentTranslate.hover.enabled": true
+}
\ No newline at end of file
diff --git a/4a_agent/bin/4a_agent b/4a_agent/bin/4a_agent
new file mode 100644
index 00000000..ec45de31
Binary files /dev/null and b/4a_agent/bin/4a_agent differ
diff --git a/4a_agent/etc/4a_agent.yaml b/4a_agent/etc/4a_agent.yaml
new file mode 100644
index 00000000..4b59c630
--- /dev/null
+++ b/4a_agent/etc/4a_agent.yaml
@@ -0,0 +1,14 @@
+http:
+ ipv4: 0.0.0.0
+ ipv6: ::0
+ port: 4040
+db:
+ dbuser: "root"
+ dbpwd: "1000omc@kp!"
+ dbip: "127.0.0.1"
+ dbport: "33066"
+ dbname: "omc_db"
+logger:
+ file: /usr/local/omc/log/4a/4a_agent.log
+ level: debug
+ duration: 30
diff --git a/crontask/cm/schema/cm-schema.go b/crontask/cm/schema/cm-schema.go
new file mode 100644
index 00000000..fa899193
--- /dev/null
+++ b/crontask/cm/schema/cm-schema.go
@@ -0,0 +1,64 @@
+package cmschema
+
+// FileHeader ...
+type FileHeader struct {
+ TimeStamp string `xml:"TimeStamp"`
+ TimeZone string `xml:"TimeZone"`
+ VendorName string `xml:"VendorName"`
+ ElementType string `xml:"ElementType"`
+ CmVersion string `xml:"CmVersion"`
+}
+
+// N ...
+type N struct {
+ IAttr int `xml:"i,attr"`
+ Value string `xml:",chardata"`
+}
+
+// FieldName ...
+type FieldName struct {
+ N []N `xml:"N"`
+}
+
+// V ...
+type V struct {
+ IAttr int `xml:"i,attr"`
+ Value string `xml:",chardata"`
+}
+
+// Object ...
+type Object struct {
+ RmUIDAttr string `xml:"rmUID,attr"`
+ DnAttr string `xml:"Dn,attr,omitempty"`
+ UserLabelAttr string `xml:"UserLabel,attr,omitempty"`
+ PVFlagAttr string `xml:"PVFlag,attr"`
+ VMIDAttr string `xml:"VMID,attr,omitempty"`
+ VNFInstanceIDAttr string `xml:"VNFInstanceID,attr,omitempty"`
+ V []V `xml:"V"`
+}
+
+// FieldValue ...
+type FieldValue struct {
+ Object []Object `xml:"Object"`
+}
+
+// Objects ...
+type Objects struct {
+ ObjectType string `xml:"ObjectType"`
+ FieldName FieldName `xml:"FieldName"`
+ FieldValue FieldValue `xml:"FieldValue"`
+}
+
+// DataFile ...
+type DataFile struct {
+ FileHeader FileHeader `xml:"FileHeader"`
+ Objects []Objects `xml:"Objects"`
+ XsiAttr string `xml:"xmlns:xsi,attr"`
+ XsiLoc string `xml:"xsi:noNamespaceSchemaLocation,attr"`
+}
+
+// NRM xml file
+type NRMXmlFile struct {
+ Header string `xml:"Header"`
+ DataFile DataFile `xml:"xmlns:xsi"`
+}
diff --git a/crontask/cm/yaml/cm-yaml.go b/crontask/cm/yaml/cm-yaml.go
new file mode 100644
index 00000000..8738e12e
--- /dev/null
+++ b/crontask/cm/yaml/cm-yaml.go
@@ -0,0 +1,296 @@
+package cmyaml
+
+type UdmCm struct {
+ ManagedElement ManagedElement `yaml:"ManagedElement"`
+ UdmFunction UdmFunction `yaml:"UdmFunction"`
+ UdrFunction UdrFunction `yaml:"UdrFunction"`
+ AusfFunction AusfFunction `yaml:"AusfFunction"`
+ IPResource IPResource `yaml:"IPResource"`
+}
+
+type UdmFunction struct {
+ Id string `yaml:"Id"`
+ UserLabel string `yaml:"UserLabel"`
+ AdministrativeState string `yaml:"AdministrativeState"`
+ OperationalState string `yaml:"OperationalState"`
+ VnfInstanceId string `yaml:"VnfInstanceId"`
+ Fqdn string `yaml:"Fqdn"`
+ SbiServiceList string `yaml:"SbiServiceList"`
+}
+
+type UdrFunction struct {
+ Id string `yaml:"Id"`
+ UserLabel string `yaml:"UserLabel"`
+ AddrType string `yaml:"AddrType"`
+ IpVersion string `yaml:"IpVersion"`
+ AddrSegList string `yaml:"AddrSegList"`
+}
+
+type AusfFunction struct {
+ Id string `yaml:"Id"`
+ UserLabel string `yaml:"UserLabel"`
+ LocIpAddrList string `yaml:"LocIpAddrList"`
+ FarIpSubnetworkList string `yaml:"FarIpSubnetworkList"`
+}
+
+type IPResource struct {
+ Id string `yaml:"Id"`
+ UserLabel string `yaml:"UserLabel"`
+ InterfaceType string `yaml:"InterfaceType"`
+ LocIpV4AddrList string `yaml:"LocIpV4AddrList"`
+ LocIpV6AddrList string `yaml:"LocIpV6AddrList"`
+}
+
+type ManagedElement struct {
+ Id string `yaml:"Id"`
+ UserLabel string `yaml:"UserLabel"`
+ VendorName string `yaml:"VendorName"`
+ ManagedBy string `yaml:"ManagedBy"`
+ ManagementIpAddress string `yaml:"ManagementIpAddress"`
+ SwVersion string `yaml:"SwVersion"`
+ PatchInfo string `yaml:"PatchInfo"`
+ AdministrativeState string `yaml:"AdministrativeState"`
+ OperationalState string `yaml:"OperationalState"`
+}
+
+type AmfCm struct {
+ ManagedElement ManagedElement `yaml:"ManagedElement"`
+ AmfFunction AmfFunction `yaml:"AmfFunction"`
+ EpRpDynN8Amf EpRpDynN8Amf `yaml:"EpRpDynN8Amf"`
+ EpRpDynN11Amf EpRpDynN11Amf `yaml:"EpRpDynN11Amf"`
+ EpRpDynN12Amf EpRpDynN12Amf `yaml:"EpRpDynN12Amf"`
+ IPResource IPResource `yaml:"IPResource"`
+}
+
+type EpRpDynN11Amf struct {
+ Id string `yaml:"Id"`
+ UserLabel string `yaml:"UserLabel"`
+ LocIpAddrList string `yaml:"LocIpAddrList"`
+ FarIpSubnetworkList string `yaml:"FarIpSubnetworkList"`
+}
+
+type EpRpDynN12Amf struct {
+ Id string `yaml:"Id"`
+ UserLabel string `yaml:"UserLabel"`
+ LocIpAddrList string `yaml:"LocIpAddrList"`
+ FarIpSubnetworkList string `yaml:"FarIpSubnetworkList"`
+}
+
+type AmfFunction struct {
+ Id string `yaml:"Id"`
+ UserLabel string `yaml:"UserLabel"`
+ AdministrativeState string `yaml:"AdministrativeState"`
+ Fqdn string `yaml:"Fqdn"`
+ SbiServiceList string `yaml:"SbiServiceList"`
+ AmfGuamiList string `yaml:"AmfGuamiList"`
+ OperationalState string `yaml:"OperationalState"`
+ VnfInstanceId string `yaml:"VnfInstanceId"`
+ SnssaiList string `yaml:"SnssaiList"`
+ MaxUser string `yaml:"MaxUser"`
+ RelativeCapacity string `yaml:"RelativeCapacity"`
+ MaxGnbNum string `yaml:"MaxGnbNum"`
+}
+
+type EpRpDynN8Amf struct {
+ Id string `yaml:"Id"`
+ UserLabel string `yaml:"UserLabel"`
+ LocIpAddrList string `yaml:"LocIpAddrList"`
+ FarIpSubnetworkList string `yaml:"FarIpSubnetworkList"`
+}
+
+type SmfCm struct {
+ ManagedElement ManagedElement `yaml:"ManagedElement"`
+ SmfFunction SmfFunction `yaml:"SmfFunction"`
+ AddrPool AddrPool `yaml:"AddrPool"`
+ EpRpDynN7Smf EpRpDynN7Smf `yaml:"EpRpDynN7Smf"`
+ EpRpDynN10Smf EpRpDynN10Smf `yaml:"EpRpDynN10Smf"`
+ IPResource IPResource `yaml:"IPResource"`
+}
+
+type SmfFunction struct {
+ Id string `yaml:"Id"`
+ UserLabel string `yaml:"UserLabel"`
+ VnfInstanceId string `yaml:"VnfInstanceId"`
+ MaxQfi string `yaml:"MaxQfi"`
+ MaxPduSessions string `yaml:"MaxPduSessions"`
+ UpfList string `yaml:"UpfList"`
+ AdministrativeState string `yaml:"AdministrativeState"`
+ OperationalState string `yaml:"OperationalState"`
+ Fqdn string `yaml:"Fqdn"`
+ SbiServiceList string `yaml:"SbiServiceList"`
+}
+
+type AddrPool struct {
+ Id string `yaml:"Id"`
+ UserLabel string `yaml:"UserLabel"`
+ AddrType string `yaml:"AddrType"`
+ IpVersion string `yaml:"IpVersion"`
+ AddrSegList string `yaml:"AddrSegList"`
+}
+
+type EpRpDynN7Smf struct {
+ Id string `yaml:"Id"`
+ UserLabel string `yaml:"UserLabel"`
+ LocIpAddrList string `yaml:"LocIpAddrList"`
+ FarIpSubnetworkList string `yaml:"FarIpSubnetworkList"`
+}
+
+type EpRpDynN10Smf struct {
+ Id string `yaml:"Id"`
+ UserLabel string `yaml:"UserLabel"`
+ LocIpAddrList string `yaml:"LocIpAddrList"`
+ FarIpSubnetworkList string `yaml:"FarIpSubnetworkList"`
+}
+
+type UpfCm struct {
+ IPResource IPResource `yaml:"IPResource"`
+ InventoryUnitHost InventoryUnitHost `yaml:"InventoryUnitHost"`
+ InventoryUnitAccessory InventoryUnitAccessory `yaml:"InventoryUnitAccessory"`
+ UdrFunction UpfUdrFunction `yaml:"UdrFunction"`
+ InventoryUnitRack InventoryUnitRack `yaml:"InventoryUnitRack"`
+ EpRpDynN9Upf EpRpDynN9Upf `yaml:"EpRpDynN9Upf"`
+ AusfFunction UpfAusfFunction `yaml:"AusfFunction"`
+ SmfFunction UpfSmfFunction `yaml:"SmfFunction"`
+ InventoryUnitPack InventoryUnitPack `yaml:"InventoryUnitPack"`
+ UpfFunction UpfFunction `yaml:"UpfFunction"`
+ AmfFunction UpfAmfFunction `yaml:"AmfFunction"`
+ ManagedElement ManagedElement `yaml:"ManagedElement"`
+ InventoryUnitShelf InventoryUnitShelf `yaml:"InventoryUnitShelf"`
+ EpRpDynN3Upf EpRpDynN3Upf `yaml:"EpRpDynN3Upf"`
+}
+
+type InventoryUnitRack struct {
+ SbiServiceList string `yaml:"SbiServiceList"`
+ Fqdn string `yaml:"Fqdn"`
+ UserLabel string `yaml:"UserLabel"`
+ AdministrativeState string `yaml:"AdministrativeState"`
+ OperationalState string `yaml:"OperationalState"`
+ VnfInstanceId string `yaml:"VnfInstanceId"`
+ MaxPduSessions string `yaml:"MaxPduSessions"`
+ MaxQfi string `yaml:"MaxQfi"`
+ UpfList string `yaml:"UpfList"`
+ Id string `yaml:"Id"`
+}
+
+type UpfAusfFunction struct {
+ UserLabel string `yaml:"UserLabel"`
+ AdministrativeState string `yaml:"AdministrativeState"`
+ OperationalState string `yaml:"OperationalState"`
+ VnfInstanceId string `yaml:"VnfInstanceId"`
+ Fqdn string `yaml:"Fqdn"`
+ Id string `yaml:"Id"`
+}
+
+type EpRpDynN3Upf struct {
+ LocIpAddrList string `yaml:"LocIpAddrList"`
+ FarIpSubnetworkList string `yaml:"FarIpSubnetworkList"`
+ Id string `yaml:"Id"`
+ UserLabel string `yaml:"UserLabel"`
+}
+
+type InventoryUnitHost struct {
+ UserLabel string `yaml:"UserLabel"`
+ VendorName string `yaml:"VendorName"`
+ DateOfLastService string `yaml:"DateOfLastService"`
+ ManufacturerData string `yaml:"ManufacturerData"`
+ VendorUnitTypeNumber string `yaml:"VendorUnitTypeNumber"`
+ HostPosition string `yaml:"HostPosition"`
+ MemSize string `yaml:"MemSize"`
+ HardDiskSize string `yaml:"HardDiskSize"`
+ NumberOfCpu string `yaml:"NumberOfCpu"`
+ Id string `yaml:"Id"`
+ VendorUnitFamilyType string `yaml:"VendorUnitFamilyType"`
+ SerialNumber string `yaml:"SerialNumber"`
+ VersionNumber string `yaml:"VersionNumber"`
+ DateOfManufacture string `yaml:"DateOfManufacture"`
+}
+
+type InventoryUnitAccessory struct {
+ UserLabel string `yaml:"UserLabel"`
+ VendorName string `yaml:"VendorName"`
+ SerialNumber string `yaml:"SerialNumber"`
+ ManufacturerData string `yaml:"ManufacturerData"`
+ DateOfLastService string `yaml:"DateOfLastService"`
+ AccessoryPosition string `yaml:"AccessoryPosition"`
+ AccessoryType string `yaml:"AccessoryType"`
+ Id string `yaml:"Id"`
+ VendorUnitFamilyType string `yaml:"VendorUnitFamilyType"`
+ VendorUnitTypeNumber string `yaml:"VendorUnitTypeNumber"`
+ VersionNumber string `yaml:"VersionNumber"`
+ DateOfManufacture string `yaml:"DateOfManufacture"`
+ AddtionalInformation string `yaml:"AddtionalInformation"`
+}
+
+type EpRpDynN9Upf struct {
+ UserLabel string `yaml:"UserLabel"`
+ LocIpAddrList string `yaml:"LocIpAddrList"`
+ FarIpSubnetworkList string `yaml:"FarIpSubnetworkList"`
+ Id string `yaml:"Id"`
+}
+
+type UpfSmfFunction struct {
+ Id string `yaml:"Id"`
+ UserLabel string `yaml:"UserLabel"`
+ AdministrativeState string `yaml:"AdministrativeState"`
+ OperationalState string `yaml:"OperationalState"`
+ VnfInstanceId string `yaml:"VnfInstanceId"`
+ Fqdn string `yaml:"Fqdn"`
+}
+
+type InventoryUnitPack struct {
+ VendorUnitFamilyType string `yaml:"VendorUnitFamilyType"`
+ VendorName string `yaml:"VendorName"`
+ VersionNumber string `yaml:"VersionNumber"`
+ DateOfManufacture string `yaml:"DateOfManufacture"`
+ DateOfLastService string `yaml:"DateOfLastService"`
+ ManufacturerData string `yaml:"ManufacturerData"`
+ Id string `yaml:"Id"`
+ UserLabel string `yaml:"UserLabel"`
+ PortsInformation string `yaml:"PortsInformation"`
+ PackPosition string `yaml:"PackPosition"`
+ SlotsOccupied string `yaml:"SlotsOccupied"`
+ VendorUnitTypeNumber string `yaml:"VendorUnitTypeNumber"`
+ SerialNumber string `yaml:"SerialNumber"`
+}
+
+type UpfAmfFunction struct {
+ VnfInstanceId string `yaml:"VnfInstanceId"`
+ Fqdn string `yaml:"Fqdn"`
+ Id string `yaml:"Id"`
+ UserLabel string `yaml:"UserLabel"`
+ AdministrativeState string `yaml:"AdministrativeState"`
+ OperationalState string `yaml:"OperationalState"`
+}
+
+type InventoryUnitShelf struct {
+ ManufacturerData string `yaml:"ManufacturerData"`
+ RackPosition string `yaml:"RackPosition"`
+ SerialNumber string `yaml:"SerialNumber"`
+ VersionNumber string `yaml:"VersionNumber"`
+ VendorUnitFamilyType string `yaml:"VendorUnitFamilyType"`
+ VendorUnitTypeNumber string `yaml:"VendorUnitTypeNumber"`
+ VendorName string `yaml:"VendorName"`
+ DateOfManufacture string `yaml:"DateOfManufacture"`
+ DateOfLastService string `yaml:"DateOfLastService"`
+ Id string `yaml:"Id"`
+ UserLabel string `yaml:"UserLabel"`
+}
+
+type UpfUdrFunction struct {
+ OperationalState string `yaml:"OperationalState"`
+ VnfInstanceId string `yaml:"VnfInstanceId"`
+ Fqdn string `yaml:"Fqdn"`
+ Id string `yaml:"Id"`
+ UserLabel string `yaml:"UserLabel"`
+ AdministrativeState string `yaml:"AdministrativeState"`
+}
+
+type UpfFunction struct {
+ MaxThroughput string `yaml:"MaxThroughput"`
+ Id string `yaml:"Id"`
+ UserLabel string `yaml:"UserLabel"`
+ AdministrativeState string `yaml:"AdministrativeState"`
+ OperationalState string `yaml:"OperationalState"`
+ VnfInstanceId string `yaml:"VnfInstanceId"`
+ MaxQosFlows string `yaml:"MaxQosFlows"`
+}
diff --git a/crontask/config.go b/crontask/config.go
new file mode 100644
index 00000000..8a0a33be
--- /dev/null
+++ b/crontask/config.go
@@ -0,0 +1,186 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "os"
+ "strings"
+
+ "ems.agt/lib/global"
+ "ems.agt/lib/log"
+
+ "gopkg.in/yaml.v3"
+)
+
+// Yaml struct of config
+type YamlConfig struct {
+ Logger struct {
+ File string `yaml:"file"`
+ Level string `yaml:"level"`
+ Duration int `yaml:"duration"`
+ Count int `yaml:"count"`
+ } `yaml:"logger"`
+
+ OMC struct {
+ Name string `yaml:"name"`
+ HostUri string `yaml:"hosturi"`
+ HostNo string `yaml:"hostno"`
+ Province string `yaml:"province"`
+ NetAbbr string `yaml:"netabbr"`
+ Vendor string `yaml:"vendor"`
+ } `yaml:"omc"`
+
+ Database struct {
+ Type string `yaml:"type"`
+ User string `yaml:"user"`
+ Password string `yaml:"password"`
+ Host string `yaml:"host"`
+ Port string `yaml:"port"`
+ Name string `yaml:"name"`
+ Backup string `yaml:"backup"`
+ } `yaml:"database"`
+
+ Tasks struct {
+ File string `yaml:"file"`
+ } `yaml:"tasks"`
+
+ NBI struct {
+ CM struct {
+ CfgFileDir string `yaml:"cfgfiledir"`
+ XmlFileDir string `yaml:"xmlfiledir"`
+ Version string `yaml:"version"`
+ } `yaml:"cm"`
+ PM struct {
+ CfgFileDir string `yaml:"cfgfiledir"`
+ XmlFileDir string `yaml:"xmlfiledir"`
+ Version string `yaml:"version"`
+ } `yaml:"pm"`
+ } `yaml:"nbi"`
+}
+
+var yamlConfig YamlConfig
+
+func ReadConfig(configFile string) error {
+ yamlFile, err := os.ReadFile(configFile)
+ if err != nil {
+ fmt.Println("Read yaml config file error:", err)
+ return err
+ }
+
+ err = yaml.Unmarshal(yamlFile, &yamlConfig)
+ if err != nil {
+ fmt.Println("Unmarshal error:", err)
+ return err
+ }
+ return nil
+}
+
+func GetYamlConfig() *YamlConfig {
+ return &yamlConfig
+}
+
+func GetLogLevel() log.LogLevel {
+ var logLevel log.LogLevel
+ switch strings.ToLower(yamlConfig.Logger.Level) {
+ case "trace":
+ logLevel = log.LOG_TRACE
+ case "info":
+ logLevel = log.LOG_INFO
+ case "debug":
+ logLevel = log.LOG_DEBUG
+ case "warn":
+ logLevel = log.LOG_WARN
+ case "error":
+ logLevel = log.LOG_ERROR
+ case "fatal":
+ logLevel = log.LOG_FATAL
+ case "off":
+ logLevel = log.LOG_OFF
+ default:
+ logLevel = log.LOG_DEBUG
+ }
+ return logLevel
+}
+
+type Task struct {
+ Name string `yaml:"name"`
+ Status string `yaml:"status" default:"Active"`
+ Uri string `yaml:"uri"`
+ Params string `yaml:"params"`
+ Body string `yaml:"body"`
+ Interval uint64 `yaml:"interval"`
+ Unit string `yaml:"unit"`
+ At string `yaml:"at"`
+ From int `yaml:"from"`
+ Do string `yaml:"do"`
+}
+
+type Crontab struct {
+ Name string `yaml:"name"`
+ Status string `yaml:"status" default:"Active"`
+ Tab string `yaml:"tab"`
+ Do string `yaml:"do"`
+ Uri string `yaml:"uri"`
+ Params string `yaml:"params"`
+ Body string `yaml:"body"`
+}
+
+type Tasks struct {
+ Tasks []Task `yaml:"tasks"`
+ Crontabs []Crontab `yaml:"crontab"`
+}
+
+const (
+ TaskStatusActive = "active"
+ TaskStatusInactive = "inactive"
+)
+
+var taskSet Tasks
+
+func ReadTasksYaml(pfile string) (ret error) {
+ log.Debug("pfile:", pfile)
+ file, err := os.ReadFile(pfile)
+ if err != nil {
+ log.Error(err)
+ return err
+ }
+
+ err = yaml.Unmarshal(file, &taskSet)
+ if err != nil {
+ log.Error(err)
+ return err
+ }
+
+ log.Trace("tasks:", taskSet)
+ return nil
+}
+
+func GetDefaultUserAgent() string {
+ return "OMC-crontask/" + global.Version
+}
+
+const defaultConfigFile = "./etc/crontask.yaml"
+
+var ConfigFile *string
+
+func init() {
+ ConfigFile = flag.String("c", defaultConfigFile, "config file")
+ pv := flag.Bool("v", false, "print version")
+ ph := flag.Bool("h", false, "print help")
+
+ flag.Parse()
+ if *pv {
+ fmt.Printf("OMC crontask version: %s\n%s\n%s\n\n", global.Version, global.BuildTime, global.GoVer)
+ os.Exit(0)
+ }
+ if *ph {
+ flag.Usage()
+ os.Exit(0)
+ }
+
+ err := ReadConfig(*ConfigFile)
+ if err != nil {
+ fmt.Println("Failed to ReadConfig:", err)
+ os.Exit(3)
+ }
+}
diff --git a/crontask/config_linux.go b/crontask/config_linux.go
new file mode 100644
index 00000000..438133cb
--- /dev/null
+++ b/crontask/config_linux.go
@@ -0,0 +1,32 @@
+//go:build linux
+// +build linux
+
+package main
+
+import (
+ "os"
+ "os/signal"
+ "syscall"
+
+ "ems.agt/lib/log"
+)
+
+// 启动一个 goroutine 监听信号量
+func ReloadRoutine() {
+ sigCh := make(chan os.Signal, 1)
+
+ signal.Notify(sigCh, syscall.SIGUSR1)
+
+ for {
+ <-sigCh
+ log.Info("Received reload signal, reloading config...")
+
+ err := ReadConfig(*ConfigFile)
+ if err != nil {
+ log.Error("Failed to ReadConfig:", err)
+ continue
+ }
+
+ log.Info("Config reloaded successfully.")
+ }
+}
diff --git a/crontask/config_windows.go b/crontask/config_windows.go
new file mode 100644
index 00000000..6edcaab2
--- /dev/null
+++ b/crontask/config_windows.go
@@ -0,0 +1,34 @@
+//go:build windows
+// +build windows
+
+package main
+
+import (
+ "os"
+ "os/signal"
+ "syscall"
+
+ "ems.agt/lib/log"
+)
+
+// 启动一个 goroutine 监听信号量
+func ReloadRoutine() {
+ sigCh := make(chan os.Signal, 1)
+
+ //signal.Notify(sigCh, syscall.SIGUSR1)
+
+ signal.Notify(sigCh, syscall.SIGTRAP)
+
+ for {
+ <-sigCh
+ log.Info("Received reload signal, reloading config...")
+
+ err := ReadConfig(*ConfigFile)
+ if err != nil {
+ log.Error("Failed to ReadConfig:", err)
+ continue
+ }
+
+ log.Info("Config reloaded successfully.")
+ }
+}
diff --git a/crontask/crontask b/crontask/crontask
new file mode 100644
index 00000000..f245eb9b
Binary files /dev/null and b/crontask/crontask differ
diff --git a/crontask/crontask.go b/crontask/crontask.go
new file mode 100644
index 00000000..e375933f
--- /dev/null
+++ b/crontask/crontask.go
@@ -0,0 +1,41 @@
+package main
+
+import (
+ "fmt"
+ "os"
+
+ "ems.agt/lib/dborm"
+ "ems.agt/lib/global"
+ "ems.agt/lib/log"
+)
+
+func main() {
+
+ log.InitLogger(yamlConfig.Logger.File, yamlConfig.Logger.Duration, yamlConfig.Logger.Count, "omc:crontask", GetLogLevel())
+ fmt.Printf("OMC crontask version: %s\n", global.Version)
+ log.Infof("========================= OMC crontask startup =========================")
+ log.Infof("OMC crontask version: %s %s %s", global.Version, global.BuildTime, global.GoVer)
+
+ err := dborm.InitDbClient(yamlConfig.Database.Type, yamlConfig.Database.User, yamlConfig.Database.Password,
+ yamlConfig.Database.Host, yamlConfig.Database.Port, yamlConfig.Database.Name)
+ if err != nil {
+ fmt.Println("dborm.initDbClient err:", err)
+ os.Exit(1)
+ }
+
+ err = initDbClient()
+ if err != nil {
+ fmt.Println("initDBClient error:", err)
+ os.Exit(1)
+ }
+
+ ReadTasksYaml(yamlConfig.Tasks.File)
+
+ //go ReloadRoutine()
+
+ go initCronTasks()
+
+ go initCronTabs()
+
+ select {}
+}
diff --git a/crontask/db.go b/crontask/db.go
new file mode 100644
index 00000000..74b9debc
--- /dev/null
+++ b/crontask/db.go
@@ -0,0 +1,526 @@
+package main
+
+import (
+ "database/sql"
+ "fmt"
+ "time"
+
+ "ems.agt/lib/log"
+
+ _ "github.com/go-sql-driver/mysql"
+ "xorm.io/xorm"
+)
+
+type NullTime sql.NullTime
+
+type DBClient struct {
+ dbType string
+ dbUrl string
+ dbConnMaxLifetime time.Duration
+ dbMaxIdleConns int
+ dbMaxOpenConns int
+ IsShowSQL bool
+
+ xEngine *xorm.Engine
+}
+
+var dbClient DBClient
+
+func initDbClient() error {
+ db := yamlConfig.Database
+ dbClient.dbUrl = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8&parseTime=true&loc=Local",
+ db.User, db.Password, db.Host, db.Port, db.Name)
+ dbClient.dbType = db.Type
+ dbClient.dbConnMaxLifetime = 0
+ dbClient.dbMaxIdleConns = 0
+ dbClient.dbMaxOpenConns = 0
+ if log.GetLevel() == log.LOG_TRACE {
+ dbClient.IsShowSQL = true
+ }
+
+ var err error
+ dbClient.xEngine, err = xorm.NewEngine(dbClient.dbType, dbClient.dbUrl)
+ if err != nil {
+ log.Error("Failed to connect database:", err)
+ return err
+ }
+ //dbClient.xEngine.Ping() // 可以判断是否能连接
+ //if err != nil {
+ // log.Error("Failed to ping database:", err)
+ // return err
+ //}
+ // defer dbClient.xEngine.Close() // 退出后关闭
+
+ if dbClient.IsShowSQL == true {
+ dbClient.xEngine.ShowSQL(true)
+ }
+ dbClient.xEngine.SetConnMaxLifetime(dbClient.dbConnMaxLifetime)
+ dbClient.xEngine.SetMaxIdleConns(dbClient.dbMaxIdleConns)
+ dbClient.xEngine.SetMaxOpenConns(dbClient.dbMaxOpenConns)
+ return nil
+}
+
+var xEngine *xorm.Engine
+
+func XormConnectDatabaseWithUri(sql string) (*xorm.Engine, error) {
+ sqlStr := fmt.Sprintf("%s?charset=utf8&parseTime=true&loc=Local", sql)
+ var err error
+ xEngine, err = xorm.NewEngine("mysql", sqlStr) //1、Create xorm engine
+ if err != nil {
+ fmt.Println("Failed to connect database:", err)
+ return nil, err
+ }
+ xEngine.ShowSQL(true)
+ return xEngine, nil
+}
+
+type NeInfo struct {
+ Id int `json:"-" xorm:"pk 'id' autoincr"`
+ NeType string `json:"neType" xorm:"ne_type"`
+ NeId string `json:"neId" xorm:"ne_id"` // neUID/rmUID 网元唯一标识
+ RmUID string `json:"rmUID" xorm:"rm_uid"` // neUID/rmUID网元UID
+ NeName string `json:"neName" xorm:"ne_name"` // NeName/UserLabel 网元名称/网元设备友好名称
+ Ip string `json:"ip" xorm:"ip"`
+ Port string `json:"port" xorm:"port"`
+ PvFlag string `json:"pvFlag" xorm:"pv_flag"` // 网元虚实性标识 VNF/PNF: 虚拟/物理
+ NeAddress string `json:"neAddress" xorm:"ne_address"` // 只对PNF
+ Province string `json:"province" xorm:"province"` // 网元所在省份
+ VendorName string `json:"vendorName" xorm:"vendor_name"` // 厂商名称
+ Dn string `json:"dn" xorm:"dn"` // 网络标识
+ Status int `json:"status" xorm:"status"`
+ UpdateTime string `json:"-" xorm:"-"`
+}
+
+func XormGetNeInfoByType(neType string, nes *[]NeInfo) (*[]NeInfo, error) {
+ log.Debug("XormGetNeInfoByType processing... ")
+
+ ne := new(NeInfo)
+ rows, err := dbClient.xEngine.Table("ne_info").Where("status=0 and ne_type =?", neType).Rows(ne)
+ if err != nil {
+ log.Error("Failed to get table ne_info from database:", err)
+ return nil, err
+ }
+ defer rows.Close()
+ for rows.Next() {
+ err := rows.Scan(ne)
+ if err != nil {
+ log.Error("Failed to get table ne_info from database:", err)
+ return nil, err
+ }
+ *nes = append(*nes, *ne)
+ }
+ log.Debug("nes:", nes)
+ return nes, nil
+}
+
+func XormGetAllNeInfo(nes *[]NeInfo) (*[]NeInfo, error) {
+ log.Debug("XormGetAllNeInfo processing... ")
+
+ ne := new(NeInfo)
+ rows, err := dbClient.xEngine.Table("ne_info").Where("status='0'").Rows(ne)
+ if err != nil {
+ log.Error("Failed to get table ne_info from database:", err)
+ return nil, err
+ }
+ defer rows.Close()
+ for rows.Next() {
+ err := rows.Scan(ne)
+ if err != nil {
+ log.Error("Failed to get table ne_info from database:", err)
+ return nil, err
+ }
+ *nes = append(*nes, *ne)
+ }
+ log.Debug("nes:", nes)
+ return nes, nil
+}
+
+type NeState struct {
+ Id int `json:"id" xorm:"pk 'id' autoincr"`
+ NeType string `json:"neType" xorm:"ne_type"`
+ NeId string `json:"neId" xorm:"ne_id"`
+ Version string `json:"version" xorm:"version"`
+ Capability uint32 `json:"capability" xorm:"capability"`
+ SerialNum string `json:"serialNum" xorm:"serial_num"`
+ ExpiryDate string `json:"expiryDate" xorm:"expiry_date"`
+ CpuUsage string `json:"cpuUsage" xorm:"cpu_usage"`
+ MemUsage string `json:"memUsage" xorm:"mem_usage"`
+ DiskSpace string `json:"diskSpace" xorm:"disk_space"`
+ Timestamp string `json:"timestamp" xorm:"-" `
+}
+
+func XormInsertNeState(neState *NeState) (int64, error) {
+ log.Debug("XormInsertNeState processing... ")
+
+ var affected int64 = 0
+
+ session := dbClient.xEngine.NewSession()
+ defer session.Close()
+ affected, err := session.InsertOne(neState)
+ session.Commit()
+ return affected, err
+}
+
+type NorthboundPm struct {
+ Id int `json:"-" xorm:"pk 'id' autoincr"`
+ Date string `json:"Date" xorm:"date"`
+ Index int `json:"Index" xorm:"index"` // 1天中测量时间粒度(如15分钟)的切片索引: 0~95
+ Timestamp string `json:"-" xorm:"-"`
+ NeName string `json:"NeName" xorm:"ne_name"` // UserLabel
+ RmUID string `json:"RmUID" xorm:"rm_uid"`
+ NeType string `json:"NeType" xorm:"ne_type"` // 网元类型
+ PmVersion string `json:"PmVersion" xorm:"pm_version"` // 性能数据版本号
+ Dn string `json:"Dn" xorm:"dn"` // (???)网元标识, 如:RJN-CMZJ-TZ,SubNetwork=5GC88,ManagedElement=SMF53456,SmfFunction=53456
+ Period string `json:"Period" xorm:"period"` // 测量时间粒度选项:5/15/30/60
+ TimeZone string `json:"TimeZone" xorm:"time_zone"`
+ StartTime string `json:"StartTime" xorm:"start_time"`
+
+ Datas []struct {
+ ObjectType string `json:"ObjectType" xorm:"object_type"` // 网络资源类别名称, Pm指标项列表中为空间粒度 如:SmfFunction
+ KPIs []struct {
+ KPIID string `json:"KPIID" xorm:"pm_name"` // 指标项, 如: SMF.AttCreatePduSession._Dnn
+ KPIValues []struct {
+ Name string `json:"Name" xorm:"name"` // 单个的写"Total", 或者指标项有多个测量项,如Dnn的名称写对应的Dnn"cmnet"/"ims"
+ Value int `json:"Value" xorm:"value"`
+ } `json:"KPIValues" xorm:"sub_datas"`
+ } `json:"KPIs" xorm:"pm_datas"`
+ } `json:"Datas" xorm:"datas"`
+}
+
+func XormInsertNorthboundPm(pm *NorthboundPm) (int64, error) {
+ log.Debug("XormInsertNorthboundPm processing... ")
+
+ var affected int64 = 0
+
+ session := dbClient.xEngine.NewSession()
+ defer session.Close()
+ affected, err := session.InsertOne(pm)
+ session.Commit()
+ return affected, err
+}
+
+func XormGetNorthboundPm(date string, index int, neType string, pms *[]NorthboundPm) (*[]NorthboundPm, error) {
+ log.Debug("XormGetNorthboundPm processing... ")
+
+ pm := new(NorthboundPm)
+ rows, err := dbClient.xEngine.Table("northbound_pm").
+ Where("`ne_type` = ? AND `date` = ? AND `index` = ?", neType, date, index).
+ Rows(pm)
+ if err != nil {
+ log.Error("Failed to get table northbound_pm from database:", err)
+ return nil, err
+ }
+ defer rows.Close()
+ for rows.Next() {
+ err := rows.Scan(pm)
+ if err != nil {
+ log.Error("Failed to get table northbound_pm from database:", err)
+ return nil, err
+ }
+ *pms = append(*pms, *pm)
+ }
+ log.Debug("pms:", pms)
+ return pms, nil
+}
+
+func XormGetMeasureThreshold(tableName string, where string, datas *[]MeasureThreshold) (*[]MeasureThreshold, error) {
+ log.Debug("XormGetMeasureThreshold processing... ")
+
+ row := new(MeasureThreshold)
+ rows, err := dbClient.xEngine.Table(tableName).Where(where).Rows(row)
+ if err != nil {
+ log.Errorf("Failed to get table %s from database: %v", tableName, err)
+ return nil, err
+ }
+ defer rows.Close()
+ for rows.Next() {
+ err := rows.Scan(row)
+ if err != nil {
+ log.Error("Failed to get table measure_threshold from database:", err)
+ return nil, err
+ }
+ *datas = append(*datas, *row)
+ }
+ log.Debug("datas:", datas)
+
+ return datas, nil
+}
+
+type MeasureThreshold struct {
+ Id int `json:"id" xorm:"pk 'id' autoincr"`
+ NeType string `json:"neType" xorm:"ne_type"`
+ KpiSet string `json:"kpiSet" xorm:"kpi_set"`
+ Threshold int64 `json:"threshold" xorm:"threshold"`
+ Status string `json:"status" xorm:"Status"`
+ OrigSeverity string `json:"origSeverity" xorm:"orig_severity"`
+ AlarmId string `json:"alarmId" xorm:"alarm_id"`
+ AlarmFlag bool `json:"alarmFlag" xorm:"alarm_flag"`
+}
+
+type MeasureData struct {
+ // Id int `json:"id" xorm:"pk 'id' autoincr"`
+ Id int `json:"id" xorm:"-"`
+ Date string `json:"date" xorm:"date"`
+ TaskId int `json:"taskId"`
+ NeType string `json:"neType" xorm:"ne_type"`
+ NeName string `json:"neName" xorm:"ne_name"`
+ RmUid string `json:"rmUid" xorm:"rm_uid"`
+ GranulOption string `json:"granulOption" xorm:"granul_option"`
+ StartTime string `json:"startTime"`
+ EndTime string `json:"endTime"`
+ KpiCode string `json:"kpiCode" xorm:"kpi_code"`
+ KpiId string `json:"kpiId" xorm:"kpi_id"`
+ KpiExt string `json:"kpiExt" xorm:"kpi_ext"`
+ Value int64 `json:"value"`
+ Timestamp string `json:"timestamp"`
+}
+
+func XormGetMeasureData(where string, datas *[]MeasureData) (*[]MeasureData, error) {
+ log.Debug("XormGetMeasureData processing... ")
+
+ row := new(MeasureData)
+ rows, err := dbClient.xEngine.Where(where).Rows(row)
+ if err != nil {
+ log.Errorf("Failed to get table measure_data from database: %v", err)
+ return nil, err
+ }
+ defer rows.Close()
+ for rows.Next() {
+ err := rows.Scan(row)
+ if err != nil {
+ log.Error("Failed to get table measure_data from database:", err)
+ return nil, err
+ }
+ *datas = append(*datas, *row)
+ }
+ log.Debug("datas:", datas)
+
+ return datas, nil
+}
+
+func XormGetMeasureDataLastOne(neType, rmUID string, taskId int) (*MeasureData, error) {
+ log.Debug("XormGetMeasureDataOneByKpi processing... ")
+
+ measureData := new(MeasureData)
+ _, err := dbClient.xEngine.
+ SQL("select * from measure_data where ne_type=? and rm_uid=? and task_id=? order by start_time desc limit 1", neType, rmUID, taskId).
+ Get(measureData)
+ if err != nil {
+ log.Errorf("Failed to get measure_data: %v", err)
+ return nil, err
+ }
+
+ return measureData, nil
+}
+
+func XormGetMeasureDataOneByKpi(kpi string) (*MeasureData, error) {
+ log.Debug("XormGetMeasureDataOneByKpi processing... ")
+
+ measureData := new(MeasureData)
+ _, err := dbClient.xEngine.
+ SQL("select * from measure_data where kpi_id = ? order by timestamp desc limit 1", kpi).
+ Get(measureData)
+ if err != nil {
+ log.Errorf("Failed to get table measure_data from database: %v", err)
+ return nil, err
+ }
+
+ log.Debug("measureData:", measureData)
+
+ return measureData, nil
+}
+
+type AlarmDefine struct {
+ AlarmId string `json:"alarmId" xorm:"alarm_id"`
+ AlarmCode int `json:"alarmCode" xorm:"alarm_code"`
+ AlarmTitle string `json:"alarmTitle" xorm:"alarm_title"`
+ NeType string `json:"neType" xorm:"ne_type"`
+ AlarmType string `json:"alarmType" xorm:"alarm_type"`
+ OrigSeverity string `json:"origSeverity" xorm:"orig_severity"`
+ ObjectUid string `json:"objectUid" xorm:"object_uid"`
+ ObjectName string `json:"objectName" xorm:"object_name"`
+ ObjectType string `json:"objectType" xorm:"object_type"`
+ LocationInfo string `json:"locationInfo"`
+ SpecificProblem string `json:"specificProblem"`
+ SpecificProblemId string `json:"specificProblemId" xorm:"specific_problem_id"`
+ AddInfo string `json:"addInfo" xorm:"add_info"`
+ Threshold int64 `json:"threshold" xorm:"threshold"`
+ Status string `json:"status" xorm:"status"`
+}
+
+func XormGetAlarmDefine(alarmId string) (*AlarmDefine, error) {
+ log.Debug("XormGetAlarmDefine processing... ")
+
+ alarmDefine := new(AlarmDefine)
+ _, err := dbClient.xEngine.
+ Where("alarm_id=? and status='Active'", alarmId).
+ Get(alarmDefine)
+ if err != nil {
+ log.Error("Failed to get table alarm_define from database:", err)
+ return nil, err
+ }
+
+ return alarmDefine, nil
+}
+
+const (
+ AlarmStatusClear = 0
+ AlarmStatusActive = 1
+ AlarmStatusClearString = "0"
+ AlarmStatusActiveString = "1"
+)
+
+const (
+ ClearTypeUnclear = 0
+ ClearTypeAutoClear = 1
+ ClearTypeManualClear = 2
+)
+
+type Alarm struct {
+ Id int `json:"-" xorm:"pk 'id' autoincr"`
+ AlarmSeq int `json:"alarmSeq"`
+ AlarmId string `json:"alarmId" xorm:"alarm_id"`
+ NeId string `json:"neId"`
+ AlarmCode int `json:"alarmCode"`
+ AlarmTitle string `json:"alarmTitle"`
+ EventTime string `json:"eventTime"`
+ AlarmType string `json:"alarmType"`
+ OrigSeverity string `json:"origSeverity"`
+ PerceivedSeverity string `json:"perceivedSeverity"`
+ PVFlag string `json:"pvFlag" xorm:"pv_flag"`
+ NeName string `json:"neName"`
+ NeType string `json:"neType"`
+ ObjectUid string `json:"objectUid" xorm:"object_uid"`
+ ObjectName string `json:"objectName" xorm:"object_name"`
+ ObjectType string `json:"objectType" xorm:"object_type"`
+ LocationInfo string `json:"locationInfo"`
+ Province string `json:"province"`
+ AlarmStatus int `json:"alarmStatus" xorm:"alarm_status"`
+ SpecificProblem string `json:"specificProblem"`
+ SpecificProblemID string `json:"specificProblemID" xorm:"specific_problem_id"`
+ AddInfo string `json:"addInfo"`
+
+ // ClearType int `json:"-" xorm:"clear_type"` // 0: Unclear, 1: Auto clear, 2: Manual clear
+ // ClearTime sql.NullTime `json:"-" xorm:"clear_time"`
+}
+
+type AlarmLog struct {
+ NeType string `json:"neType" xorm:"ne_type"`
+ NeId string `json:"neId" xorm:"ne_id"`
+ AlarmSeq string `json:"alarmSeq" xorm:"alarm_seq"`
+ AlarmId string `json:"alarmId" xorm:"alarm_id"`
+ AlarmCode int `json:"alarmCode" xorm:"alarm_code"`
+ AlarmStatus int `json:"alarmStatus" xorm:"alarm_status"`
+ EventTime string `json:"eventTime" xorm:"event_time"`
+ // ClearTime sql.NullTime `json:"clearTime" xorm:"clear_time"`
+ LogTime string `json:"logTime" xorm:"-"`
+}
+
+func XormInsertAlarm(alarm *Alarm) (int64, error) {
+ log.Debug("XormInsertAlarm processing... ")
+
+ var affected int64 = 0
+
+ session := dbClient.xEngine.NewSession()
+ defer session.Close()
+ affected, err := session.InsertOne(alarm)
+ session.Commit()
+ return affected, err
+}
+
+func XormInsertTalbeOne(tbInfo interface{}) (int64, error) {
+ log.Debug("XormInsertTalbeOne processing... ")
+
+ var affected int64 = 0
+
+ session := dbClient.xEngine.NewSession()
+ defer session.Close()
+ affected, err := session.InsertOne(tbInfo)
+ session.Commit()
+ return affected, err
+}
+
+func XormGetDataBySQL(sql string) (*[]map[string]string, error) {
+ log.Debug("XormGetDataBySQL processing... ")
+
+ rows := make([]map[string]string, 0)
+ rows, err := dbClient.xEngine.QueryString(sql)
+ if err != nil {
+ log.Errorf("Failed to QueryString:", err)
+ return nil, err
+ }
+
+ return &rows, nil
+}
+
+func XormGetTableOneByWhere(where string, tableName string) (*[]interface{}, error) {
+ log.Debug("XormGetTableOneByWhere processing... ")
+
+ row := new([]interface{})
+
+ tb, err := dbClient.xEngine.TableInfo(tableName)
+ if err != nil {
+ log.Error("Failed to get TableInfo:", err)
+ return nil, err
+ }
+ columns := tb.Columns()
+ log.Debug("columns:", columns)
+ has, err := dbClient.xEngine.Table(tableName).Where(where).Get(row)
+ if err != nil {
+ log.Errorf("Failed to get table %s from database:%v", tableName, err)
+ return nil, err
+ } else if has == false {
+ log.Infof("Not found data from %s where=%s", tableName, where)
+ return nil, nil
+ }
+
+ log.Debugf("%s:%v", tableName, row)
+ return row, nil
+}
+
+func XormGetTableOneById(id int, tableName string) (*[]interface{}, error) {
+ log.Debug("XormGetTableOneById processing... ")
+
+ rows := new([]interface{})
+ has, err := dbClient.xEngine.Table(tableName).ID(id).Get(rows)
+ if err != nil {
+ log.Errorf("Failed to get table %s from database:id=%d, %v", tableName, id, err)
+ return nil, err
+ } else if has == false {
+ log.Infof("Not found table %s from database:id=%d", tableName, id)
+ return nil, nil
+ }
+
+ log.Debugf("%s:%v", tableName, rows)
+ return rows, nil
+}
+
+func XormUpdateTableById(id int, tableName string, tbInfo interface{}, cols ...string) (int64, error) {
+ log.Debug("XormUpdateTableById processing... ")
+
+ session := dbClient.xEngine.NewSession()
+ defer session.Close()
+ affected, err := session.Table(tableName).ID(id).MustCols(cols...).Update(tbInfo)
+ if err != nil {
+ log.Errorf("Failed to update table %s from database:%v", tableName, err)
+ return 0, err
+ }
+ session.Commit()
+
+ return affected, nil
+}
+
+func XormUpdateTableByWhere(where string, tableName string, tbInfo interface{}) (int64, error) {
+ log.Debug("XormUpdateTableByWhere processing... ")
+
+ session := dbClient.xEngine.NewSession()
+ defer session.Close()
+ affected, err := session.Table(tableName).Where(where).Update(tbInfo)
+ if err != nil {
+ log.Errorf("Failed to update table %s from database:%v", tableName, err)
+ return 0, err
+ }
+ session.Commit()
+
+ return affected, nil
+}
diff --git a/crontask/etc/cm/cm-amf.yaml b/crontask/etc/cm/cm-amf.yaml
new file mode 100644
index 00000000..319a85f6
--- /dev/null
+++ b/crontask/etc/cm/cm-amf.yaml
@@ -0,0 +1,49 @@
+ManagedElement:
+ Id: ""
+ UserLabel: ""
+ VendorName: ""
+ ManagedBy: ""
+ ManagementIpAddress: ""
+ SwVersion: ""
+ PatchInfo: ""
+ AdministrativeState: ""
+ OperationalState: ""
+
+AmfFunction:
+ Id: ""
+ UserLabel: ""
+ AdministrativeState: ""
+ OperationalState: ""
+ VnfInstanceId: ""
+ Fqdn: ""
+ SbiServiceList: ""
+ AmfGuamiList: ""
+ SnssaiList: ""
+ MaxUser: ""
+ RelativeCapacity: ""
+ MaxGnbNum: ""
+
+EpRpDynN8Amf:
+ Id: ""
+ UserLabel: ""
+ LocIpAddrList: ""
+ FarIpSubnetworkList: ""
+
+EpRpDynN11Amf:
+ Id: ""
+ UserLabel: ""
+ LocIpAddrList: ""
+ FarIpSubnetworkList: ""
+
+EpRpDynN12Amf:
+ Id: ""
+ UserLabel: ""
+ LocIpAddrList: ""
+ FarIpSubnetworkList: ""
+
+IPResource:
+ Id: ""
+ UserLabel: ""
+ InterfaceType: ""
+ LocIpV4AddrList: ""
+ LocIpV6AddrList: ""
diff --git a/crontask/etc/cm/cm-smf.yaml b/crontask/etc/cm/cm-smf.yaml
new file mode 100644
index 00000000..a1ad3736
--- /dev/null
+++ b/crontask/etc/cm/cm-smf.yaml
@@ -0,0 +1,48 @@
+ManagedElement:
+ Id: ""
+ UserLabel: ""
+ VendorName: ""
+ ManagedBy: ""
+ ManagementIpAddress: ""
+ SwVersion: ""
+ PatchInfo: ""
+ AdministrativeState: ""
+ OperationalState: ""
+
+SmfFunction:
+ Id: ""
+ UserLabel: ""
+ AdministrativeState: ""
+ OperationalState: ""
+ VnfInstanceId: ""
+ Fqdn: ""
+ SbiServiceList: ""
+ MaxPduSessions: ""
+ MaxQfi: ""
+ UpfList: ""
+
+AddrPool:
+ Id: ""
+ UserLabel: ""
+ AddrType: "Static"
+ IpVersion: ""
+ AddrSegList: ""
+
+EpRpDynN7Smf:
+ Id: ""
+ UserLabel: ""
+ LocIpAddrList: ""
+ FarIpSubnetworkList: ""
+
+EpRpDynN10Smf:
+ Id: ""
+ UserLabel: ""
+ LocIpAddrList: ""
+ FarIpSubnetworkList: ""
+
+IPResource:
+ Id: ""
+ UserLabel: ""
+ InterfaceType: ""
+ LocIpV4AddrList: ""
+ LocIpV6AddrList: ""
\ No newline at end of file
diff --git a/crontask/etc/cm/cm-udm.yaml b/crontask/etc/cm/cm-udm.yaml
new file mode 100644
index 00000000..5e823ae5
--- /dev/null
+++ b/crontask/etc/cm/cm-udm.yaml
@@ -0,0 +1,39 @@
+ManagedElement:
+ Id: ""
+ UserLabel: ""
+ VendorName: ""
+ ManagedBy: ""
+ ManagementIpAddress: ""
+ SwVersion: ""
+ PatchInfo: ""
+ AdministrativeState: ""
+ OperationalState: ""
+
+UdmFunction:
+ Id: ""
+ UserLabel: ""
+ AdministrativeState: ""
+ OperationalState: ""
+ VnfInstanceId: ""
+ Fqdn: ""
+ SbiServiceList: ""
+
+UdrFunction:
+ Id: ""
+ UserLabel: ""
+ AddrType: "Static"
+ IpVersion: ""
+ AddrSegList: ""
+
+AusfFunction:
+ Id: ""
+ UserLabel: ""
+ LocIpAddrList: ""
+ FarIpSubnetworkList: ""
+
+IPResource:
+ Id: ""
+ UserLabel: ""
+ InterfaceType: ""
+ LocIpV4AddrList: ""
+ LocIpV6AddrList: ""
\ No newline at end of file
diff --git a/crontask/etc/cm/cm-upf.yaml b/crontask/etc/cm/cm-upf.yaml
new file mode 100644
index 00000000..d291c686
--- /dev/null
+++ b/crontask/etc/cm/cm-upf.yaml
@@ -0,0 +1,141 @@
+ManagedElement:
+ Id: ""
+ UserLabel: ""
+ VendorName: ""
+ ManagedBy: ""
+ ManagementIpAddress: ""
+ SwVersion: ""
+ PatchInfo: ""
+ AdministrativeState: ""
+ OperationalState: ""
+
+InventoryUnitRack:
+ Id: ""
+ UserLabel: ""
+ AdministrativeState: ""
+ OperationalState: ""
+ VnfInstanceId: ""
+ Fqdn: ""
+ SbiServiceList: ""
+ MaxPduSessions: ""
+ MaxQfi: ""
+ UpfList: ""
+
+InventoryUnitShelf:
+ Id: ""
+ UserLabel: ""
+ VendorUnitFamilyType: ""
+ VendorUnitTypeNumber: ""
+ VendorName: ""
+ SerialNumber: ""
+ VersionNumber: ""
+ DateOfManufacture: ""
+ DateOfLastService: ""
+ ManufacturerData: ""
+ RackPosition: ""
+
+InventoryUnitPack:
+ Id: ""
+ UserLabel: ""
+ VendorUnitFamilyType: ""
+ VendorUnitTypeNumber: ""
+ VendorName: ""
+ SerialNumber: ""
+ VersionNumber: ""
+ DateOfManufacture: ""
+ DateOfLastService: ""
+ ManufacturerData: ""
+ PortsInformation: ""
+ PackPosition: ""
+ SlotsOccupied: ""
+
+InventoryUnitHost:
+ Id: ""
+ UserLabel: ""
+ VendorUnitFamilyType: ""
+ VendorUnitTypeNumber: ""
+ VendorName: ""
+ SerialNumber: ""
+ VersionNumber: ""
+ DateOfManufacture: ""
+ DateOfLastService: ""
+ ManufacturerData: ""
+ HostPosition: ""
+ NumberOfCpu: ""
+ MemSize: ""
+ HardDiskSize: ""
+
+InventoryUnitAccessory:
+ Id: ""
+ UserLabel: ""
+ VendorUnitFamilyType: ""
+ VendorUnitTypeNumber: ""
+ VendorName: ""
+ SerialNumber: ""
+ VersionNumber: ""
+ DateOfManufacture: ""
+ DateOfLastService: ""
+ ManufacturerData: ""
+ AccessoryPosition: ""
+ AccessoryType: ""
+ AddtionalInformation: ""
+
+UpfFunction:
+ Id: ""
+ UserLabel: ""
+ AdministrativeState: ""
+ OperationalState: ""
+ VnfInstanceId: ""
+ MaxQosFlows: ""
+ MaxThroughput: ""
+
+EpRpDynN9Upf:
+ Id: ""
+ UserLabel: ""
+ LocIpAddrList: ""
+ FarIpSubnetworkList: ""
+
+EpRpDynN3Upf:
+ Id: ""
+ UserLabel: ""
+ LocIpAddrList: ""
+ FarIpSubnetworkList: ""
+
+AmfFunction:
+ Id: ""
+ UserLabel: ""
+ AdministrativeState: ""
+ OperationalState: ""
+ VnfInstanceId: ""
+ Fqdn: ""
+
+SmfFunction:
+ Id: ""
+ UserLabel: ""
+ AdministrativeState: ""
+ OperationalState: ""
+ VnfInstanceId: ""
+ Fqdn: ""
+
+UdrFunction:
+ Id: ""
+ UserLabel: ""
+ AdministrativeState: ""
+ OperationalState: ""
+ VnfInstanceId: ""
+ Fqdn: ""
+
+AusfFunction:
+ Id: ""
+ UserLabel: ""
+ AdministrativeState: ""
+ OperationalState: ""
+ VnfInstanceId: ""
+ Fqdn: ""
+
+IPResource:
+ Id: ""
+ UserLabel: ""
+ InterfaceType: ""
+ LocIpV4AddrList: ""
+ LocIpV6AddrList: ""
diff --git a/crontask/etc/crontask.yaml b/crontask/etc/crontask.yaml
new file mode 100644
index 00000000..a8e3755d
--- /dev/null
+++ b/crontask/etc/crontask.yaml
@@ -0,0 +1,41 @@
+# file: log file name
+# level: /trace/debug/info/error/warn/error/fatal, default: debug
+# duration: saved days, default is 30 days
+logger:
+ file: d:/goprojects/ems.agt/crontask/log/crontask.log
+ level: trace
+ duration: 24
+ count: 10
+
+omc:
+ name: SZOMC1
+ hosturi: http://127.0.0.1:3040
+ hostno: S001
+ province: GD
+ netabbr: HX
+ vendor: RJ
+
+process:
+
+tasks:
+ file: ./etc/tasks.yaml
+
+database:
+ type: mysql
+ user: root
+ password: 1000omc@kp!
+ host: 127.0.0.1
+ port: 33066
+ name: omc_db
+ backup: d:/goprojects/ems.agt/restagent/database
+
+# northbound interface, cm/pm
+nbi:
+ cm:
+ cfgfiledir: ./etc/cm
+ xmlfiledir: ./ftp/cm
+ version: V1.0.1
+ pm:
+ cfgfiledir: ./etc/pm
+ xmlfiledir: ./ftp/pm
+ version: V1.0.1
diff --git a/crontask/etc/tasks.yaml b/crontask/etc/tasks.yaml
new file mode 100644
index 00000000..4ae534ca
--- /dev/null
+++ b/crontask/etc/tasks.yaml
@@ -0,0 +1,150 @@
+# example:
+# tasks:
+# - name: test # task comment
+# uri: # restful uri
+# params: # params of url
+# interval: 30 # do sometion in the interval
+# unit: Seconds #Seconds/Minutes/Hours/Days/Weeks, Monday/Tuesday/.../Sunday,
+# at: 00:10:00 # do at time such as xx:xx:xx
+# do: HelloWorldTask # (Do what: callback function)
+#
+# Attention: must restart crontask after modified this file
+#
+tasks:
+ - name: test # task comment
+ status: Active #active/inactive
+ uri: # restful uri
+ params: # params of http url
+ body: # body of http request
+ interval: 60 # do sometion in the interval
+ unit: Seconds #Seconds/Minutes/Hours/Days/Weeks, Monday/Tuesday/.../Sunday,
+ at: 00:10:00 # do at time such as xx:xx:xx when unit such as Day/Days/Mondays...
+ do: TaskHelloWorld # (Do what: callback function)
+ - name: clear expired history alarm
+ uri: /api/rest/databaseManagement/v1/omc_db/alarm
+ params: WHERE=now()+>+ADDDATE(event_time,+interval+(SELECT+`value`+FROM+config+WHERE+config_tag='historyDuration')+day)+and+alarm_status='0'
+ interval: 1
+ unit: Days
+ at: 00:10:00
+ do: TaskDeleteExpiredRecord
+ - name: clear deleted custom pm kpi
+ uri: /api/rest/databaseManagement/v1/omc_db/pm_custom_title
+ params: WHERE=now()+>+ADDDATE(update_time,+interval+(SELECT+`value`+FROM+config+WHERE+config_tag='keepPMCKpi')+day)+and+status='Deleted'
+ interval: 1
+ unit: Days
+ at: 00:15:00
+ do: TaskDeleteExpiredRecord
+ - name: update expired user session
+ uri: /api/rest/databaseManagement/v1/omc_db/session
+ params: WHERE=NOW()+>+ADDDATE(shake_time,+interval+expires+second)+and+status='online'
+ body: '{"session":{"status":"offline"}}'
+ interval: 30
+ unit: Seconds
+ at:
+ do: TaskUpdateTable
+ - name: clear expired log
+ uri:
+ params:
+ interval: 1
+ unit: Days
+ at: 00:50:00
+ do: TaskDeleteExpiredRecord
+ - name: Backup measure data
+ uri: /api/rest/databaseManagement/v1/omc_db/measure_data
+ params: SQL=select+*+into+outfile+'%s'+fields+terminated+by+','+escaped+by+''+optionally+enclosed+by+''+lines+terminated+by+'\n'+from+(select+'id','date','task_id','ne_name','rm_uid','ne_type','granul_option','kpi_code','kpi_id','kpi_ext','start_time','end_time','value','timestamp'+union+select+id,date,task_id,ne_name,rm_uid,ne_type,granul_option,kpi_code,kpi_id,kpi_ext,start_time,end_time,value,timestamp+from+measure_data)+b
+ interval: 1
+ unit: Days
+ at: 00:20:00
+ do: TaskDBBackupCSVGetBySQL
+ - name: Backup operation log
+ uri: /api/rest/databaseManagement/v1/omc_db/operation_log
+ params: SQL=select+*+into+outfile+'%s'+fields+terminated+by+','+escaped+by+''+optionally+enclosed+by+''+lines+terminated+by+'\n'+from+(select+'op_id','account_name','op_ip','subsys_tag','op_type','op_content','op_result','begin_time','end_time','vnf_flag','log_time'+union+select+op_id,account_name,op_ip,subsys_tag,op_type,op_content,op_result,begin_time,end_time,vnf_flag,log_time+from+operation_log)+b
+ interval: 1
+ unit: Days
+ at: 00:25:00
+ do: TaskDBBackupCSVGetBySQL
+ - name: handshake to NF
+ status: Active
+ uri: /api/rest/systemManagement/v1/elementType/%s/objectType/systemState
+ params:
+ interval: 10
+ unit: Seconds
+ at:
+ do: TaskHandShakeToNF
+ - name: Export CM from NF
+ uri: /api/rest/systemManagement/v1/elementType/%s/objectType/cm
+ params: ne_id=%s
+ interval: 1
+ unit: Days
+ at: 00:15
+ do: TaskExportCmFromNF
+ - name: Generate NRM xml file
+ uri:
+ params:
+ interval: 1
+ unit: Day
+ at: 00:00,06:00,12:00,18:00
+ do: GenCmXmlFile
+ - name: Task of Generate measure threshold alarm
+ status: Inactive
+ uri: /api/rest/faultManagement/v1/elementType/%s/objectType/alarms
+ params: RJHXEMSPM10200
+ interval: 10
+ unit: Seconds
+ at:
+ do: TaskGenMeasureThresholdAlarm
+ - name: Task of Generate license alarm
+ status: Inactive
+ uri: /api/rest/faultManagement/v1/elementType/%s/objectType/alarms
+ params: RJHXEMSCM10100
+ interval: 1
+ unit: Days
+ at: 20:01
+ do: TaskGenLicenseAlarm
+ - name: Task of Generate NE system state alarm
+ status: Active
+ uri: /api/rest/faultManagement/v1/elementType/%s/objectType/alarms
+ params: RJHXEMSSM10000
+ interval: 5
+ unit: Seconds
+ at:
+ do: TaskGenNeStateAlarm
+ - name: Task of Generate Measure Report Timeout
+ status: Active
+ uri: /api/rest/faultManagement/v1/elementType/%s/objectType/alarms
+ params: RJHXEMSPM10201
+ interval: 10
+ unit: Seconds
+ at:
+ do: TaskGenMeasureReportTimeoutAlarm
+ - name: Monitor proces list and write system log
+ uri: /api/rest/databaseManagement/v1/omc_db/system_log
+ params:
+ body:
+ interval: 5
+ unit: Seconds
+ at:
+ do: TaskWriteSystemLog
+# - name: Import CM to NF
+# uri: /api/rest/systemManagement/v1/elementType/udm/objectType/cm
+# params: ne_id=SZ_01
+# interval: 15
+# unit: Seconds
+# at:
+# do: TaskImportCmToNF
+crontab:
+# - name: 每隔1分钟执行
+# tab: 0 */1 * * * ? // crontab: rule like linux crontab
+# do: CronHelloWorldTask // function name to call
+# params:
+ - name: Generate PM xml file
+ status: Active
+ tab: 5,20,35,50 * * * *
+ do: GenPmXmlFile
+ uri: this is uri
+ params: Generating PM xml file
+# - name: Import CM to NF
+# tab: 0 * * * * *
+# do: TaskImportCmToNF
+# uri: /api/rest/systemManagement/v1/elementType/udm/objectType/cm
+# params: ne_id=SZ_01
\ No newline at end of file
diff --git a/crontask/export/smf-sz_01-etc-20230611001500.zip b/crontask/export/smf-sz_01-etc-20230611001500.zip
new file mode 100644
index 00000000..dedeb54e
Binary files /dev/null and b/crontask/export/smf-sz_01-etc-20230611001500.zip differ
diff --git a/crontask/export/smf-sz_01-etc-20230612001500.zip b/crontask/export/smf-sz_01-etc-20230612001500.zip
new file mode 100644
index 00000000..d5da5017
Binary files /dev/null and b/crontask/export/smf-sz_01-etc-20230612001500.zip differ
diff --git a/crontask/export/smf-sz_01-etc-20230615001500.zip b/crontask/export/smf-sz_01-etc-20230615001500.zip
new file mode 100644
index 00000000..c812977b
Binary files /dev/null and b/crontask/export/smf-sz_01-etc-20230615001500.zip differ
diff --git a/crontask/export/udm-sz_01-etc-20230611002024.zip b/crontask/export/udm-sz_01-etc-20230611002024.zip
new file mode 100644
index 00000000..4c269b94
Binary files /dev/null and b/crontask/export/udm-sz_01-etc-20230611002024.zip differ
diff --git a/crontask/export/udm-sz_01-etc-20230615001514.zip b/crontask/export/udm-sz_01-etc-20230615001514.zip
new file mode 100644
index 00000000..a0343f71
Binary files /dev/null and b/crontask/export/udm-sz_01-etc-20230615001514.zip differ
diff --git a/crontask/ftp/cm/20230806/CM-HX-AMF-16.1.1-20230806000000.xml b/crontask/ftp/cm/20230806/CM-HX-AMF-16.1.1-20230806000000.xml
new file mode 100644
index 00000000..0e8dd7f1
--- /dev/null
+++ b/crontask/ftp/cm/20230806/CM-HX-AMF-16.1.1-20230806000000.xml
@@ -0,0 +1,140 @@
+
+
+
+ 2023-08-06 00:00:00
+ UTC+8
+ Ruijie Network
+ AMF
+ 16.1.1
+
+
+ EpRpDynN8Amf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+ EpRpDynN11Amf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+ EpRpDynN12Amf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+ IPResource
+
+ Id
+ InterfaceType
+ LocIpV4AddrList
+ LocIpV6AddrList
+ UserLabel
+
+
+
+
+
+
+ ManagedElement
+
+ AdministrativeState
+ Id
+ ManagedBy
+ ManagementIpAddress
+ OperationalState
+ PatchInfo
+ SwVersion
+ UserLabel
+ VendorName
+
+
+
+
+
+
+ AmfFunction
+
+ AdministrativeState
+ AmfGuamiList
+ Fqdn
+ Id
+ MaxGnbNum
+ MaxUser
+ OperationalState
+ RelativeCapacity
+ SbiServiceList
+ SnssaiList
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
\ No newline at end of file
diff --git a/crontask/ftp/cm/20230806/CM-HX-AMF-16.1.1-20230806060000.xml b/crontask/ftp/cm/20230806/CM-HX-AMF-16.1.1-20230806060000.xml
new file mode 100644
index 00000000..8a693b99
--- /dev/null
+++ b/crontask/ftp/cm/20230806/CM-HX-AMF-16.1.1-20230806060000.xml
@@ -0,0 +1,140 @@
+
+
+
+ 2023-08-06 06:00:00
+ UTC+8
+ Ruijie Network
+ AMF
+ 16.1.1
+
+
+ EpRpDynN12Amf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+ IPResource
+
+ Id
+ InterfaceType
+ LocIpV4AddrList
+ LocIpV6AddrList
+ UserLabel
+
+
+
+
+
+
+ ManagedElement
+
+ AdministrativeState
+ Id
+ ManagedBy
+ ManagementIpAddress
+ OperationalState
+ PatchInfo
+ SwVersion
+ UserLabel
+ VendorName
+
+
+
+
+
+
+ AmfFunction
+
+ AdministrativeState
+ AmfGuamiList
+ Fqdn
+ Id
+ MaxGnbNum
+ MaxUser
+ OperationalState
+ RelativeCapacity
+ SbiServiceList
+ SnssaiList
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+ EpRpDynN8Amf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+ EpRpDynN11Amf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
\ No newline at end of file
diff --git a/crontask/ftp/cm/20230806/CM-HX-AMF-16.1.1-20230806120000.xml b/crontask/ftp/cm/20230806/CM-HX-AMF-16.1.1-20230806120000.xml
new file mode 100644
index 00000000..e8a5e6ad
--- /dev/null
+++ b/crontask/ftp/cm/20230806/CM-HX-AMF-16.1.1-20230806120000.xml
@@ -0,0 +1,140 @@
+
+
+
+ 2023-08-06 12:00:00
+ UTC+8
+ Ruijie Network
+ AMF
+ 16.1.1
+
+
+ EpRpDynN8Amf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+ EpRpDynN11Amf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+ EpRpDynN12Amf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+ IPResource
+
+ Id
+ InterfaceType
+ LocIpV4AddrList
+ LocIpV6AddrList
+ UserLabel
+
+
+
+
+
+
+ ManagedElement
+
+ AdministrativeState
+ Id
+ ManagedBy
+ ManagementIpAddress
+ OperationalState
+ PatchInfo
+ SwVersion
+ UserLabel
+ VendorName
+
+
+
+
+
+
+ AmfFunction
+
+ AdministrativeState
+ AmfGuamiList
+ Fqdn
+ Id
+ MaxGnbNum
+ MaxUser
+ OperationalState
+ RelativeCapacity
+ SbiServiceList
+ SnssaiList
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
\ No newline at end of file
diff --git a/crontask/ftp/cm/20230806/CM-HX-AMF-16.1.1-20230806180000.xml b/crontask/ftp/cm/20230806/CM-HX-AMF-16.1.1-20230806180000.xml
new file mode 100644
index 00000000..9fa354e9
--- /dev/null
+++ b/crontask/ftp/cm/20230806/CM-HX-AMF-16.1.1-20230806180000.xml
@@ -0,0 +1,140 @@
+
+
+
+ 2023-08-06 18:00:00
+ UTC+8
+ Ruijie Network
+ AMF
+ 16.1.1
+
+
+ ManagedElement
+
+ AdministrativeState
+ Id
+ ManagedBy
+ ManagementIpAddress
+ OperationalState
+ PatchInfo
+ SwVersion
+ UserLabel
+ VendorName
+
+
+
+
+
+
+ AmfFunction
+
+ AdministrativeState
+ AmfGuamiList
+ Fqdn
+ Id
+ MaxGnbNum
+ MaxUser
+ OperationalState
+ RelativeCapacity
+ SbiServiceList
+ SnssaiList
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+ EpRpDynN8Amf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+ EpRpDynN11Amf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+ EpRpDynN12Amf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+ IPResource
+
+ Id
+ InterfaceType
+ LocIpV4AddrList
+ LocIpV6AddrList
+ UserLabel
+
+
+
+
+
+
\ No newline at end of file
diff --git a/crontask/ftp/cm/20230806/CM-HX-AUSF-16.1.1-20230806000000.xml b/crontask/ftp/cm/20230806/CM-HX-AUSF-16.1.1-20230806000000.xml
new file mode 100644
index 00000000..54088172
--- /dev/null
+++ b/crontask/ftp/cm/20230806/CM-HX-AUSF-16.1.1-20230806000000.xml
@@ -0,0 +1,10 @@
+
+
+
+ 2023-08-06 00:00:00
+ UTC+8
+ Ruijie Network
+ AUSF
+ 16.1.1
+
+
\ No newline at end of file
diff --git a/crontask/ftp/cm/20230806/CM-HX-AUSF-16.1.1-20230806060000.xml b/crontask/ftp/cm/20230806/CM-HX-AUSF-16.1.1-20230806060000.xml
new file mode 100644
index 00000000..09445bf9
--- /dev/null
+++ b/crontask/ftp/cm/20230806/CM-HX-AUSF-16.1.1-20230806060000.xml
@@ -0,0 +1,10 @@
+
+
+
+ 2023-08-06 06:00:00
+ UTC+8
+ Ruijie Network
+ AUSF
+ 16.1.1
+
+
\ No newline at end of file
diff --git a/crontask/ftp/cm/20230806/CM-HX-AUSF-16.1.1-20230806120000.xml b/crontask/ftp/cm/20230806/CM-HX-AUSF-16.1.1-20230806120000.xml
new file mode 100644
index 00000000..3137aa77
--- /dev/null
+++ b/crontask/ftp/cm/20230806/CM-HX-AUSF-16.1.1-20230806120000.xml
@@ -0,0 +1,10 @@
+
+
+
+ 2023-08-06 12:00:00
+ UTC+8
+ Ruijie Network
+ AUSF
+ 16.1.1
+
+
\ No newline at end of file
diff --git a/crontask/ftp/cm/20230806/CM-HX-AUSF-16.1.1-20230806180000.xml b/crontask/ftp/cm/20230806/CM-HX-AUSF-16.1.1-20230806180000.xml
new file mode 100644
index 00000000..b879fed9
--- /dev/null
+++ b/crontask/ftp/cm/20230806/CM-HX-AUSF-16.1.1-20230806180000.xml
@@ -0,0 +1,10 @@
+
+
+
+ 2023-08-06 18:00:00
+ UTC+8
+ Ruijie Network
+ AUSF
+ 16.1.1
+
+
\ No newline at end of file
diff --git a/crontask/ftp/cm/20230806/CM-HX-SMF-16.1.1-20230806000000.xml b/crontask/ftp/cm/20230806/CM-HX-SMF-16.1.1-20230806000000.xml
new file mode 100644
index 00000000..dbc546b6
--- /dev/null
+++ b/crontask/ftp/cm/20230806/CM-HX-SMF-16.1.1-20230806000000.xml
@@ -0,0 +1,138 @@
+
+
+
+ 2023-08-06 00:00:00
+ UTC+8
+ Ruijie Network
+ SMF
+ 16.1.1
+
+
+ ManagedElement
+
+ AdministrativeState
+ Id
+ ManagedBy
+ ManagementIpAddress
+ OperationalState
+ PatchInfo
+ SwVersion
+ UserLabel
+ VendorName
+
+
+
+
+
+
+ SmfFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ MaxPduSessions
+ MaxQfi
+ OperationalState
+ SbiServiceList
+ UpfList
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+ AddrPool
+
+ AddrSegList
+ AddrType
+ Id
+ IpVersion
+ UserLabel
+
+
+
+
+
+
+ EpRpDynN7Smf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+ EpRpDynN10Smf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+ IPResource
+
+ Id
+ InterfaceType
+ LocIpV4AddrList
+ LocIpV6AddrList
+ UserLabel
+
+
+
+
+
+
\ No newline at end of file
diff --git a/crontask/ftp/cm/20230806/CM-HX-SMF-16.1.1-20230806060000.xml b/crontask/ftp/cm/20230806/CM-HX-SMF-16.1.1-20230806060000.xml
new file mode 100644
index 00000000..f073b160
--- /dev/null
+++ b/crontask/ftp/cm/20230806/CM-HX-SMF-16.1.1-20230806060000.xml
@@ -0,0 +1,138 @@
+
+
+
+ 2023-08-06 06:00:00
+ UTC+8
+ Ruijie Network
+ SMF
+ 16.1.1
+
+
+ EpRpDynN7Smf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+ EpRpDynN10Smf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+ IPResource
+
+ Id
+ InterfaceType
+ LocIpV4AddrList
+ LocIpV6AddrList
+ UserLabel
+
+
+
+
+
+
+ ManagedElement
+
+ AdministrativeState
+ Id
+ ManagedBy
+ ManagementIpAddress
+ OperationalState
+ PatchInfo
+ SwVersion
+ UserLabel
+ VendorName
+
+
+
+
+
+
+ SmfFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ MaxPduSessions
+ MaxQfi
+ OperationalState
+ SbiServiceList
+ UpfList
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+ AddrPool
+
+ AddrSegList
+ AddrType
+ Id
+ IpVersion
+ UserLabel
+
+
+
+
+
+
\ No newline at end of file
diff --git a/crontask/ftp/cm/20230806/CM-HX-SMF-16.1.1-20230806120000.xml b/crontask/ftp/cm/20230806/CM-HX-SMF-16.1.1-20230806120000.xml
new file mode 100644
index 00000000..0cccaae6
--- /dev/null
+++ b/crontask/ftp/cm/20230806/CM-HX-SMF-16.1.1-20230806120000.xml
@@ -0,0 +1,138 @@
+
+
+
+ 2023-08-06 12:00:00
+ UTC+8
+ Ruijie Network
+ SMF
+ 16.1.1
+
+
+ SmfFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ MaxPduSessions
+ MaxQfi
+ OperationalState
+ SbiServiceList
+ UpfList
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+ AddrPool
+
+ AddrSegList
+ AddrType
+ Id
+ IpVersion
+ UserLabel
+
+
+
+
+
+
+ EpRpDynN7Smf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+ EpRpDynN10Smf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+ IPResource
+
+ Id
+ InterfaceType
+ LocIpV4AddrList
+ LocIpV6AddrList
+ UserLabel
+
+
+
+
+
+
+ ManagedElement
+
+ AdministrativeState
+ Id
+ ManagedBy
+ ManagementIpAddress
+ OperationalState
+ PatchInfo
+ SwVersion
+ UserLabel
+ VendorName
+
+
+
+
+
+
\ No newline at end of file
diff --git a/crontask/ftp/cm/20230806/CM-HX-SMF-16.1.1-20230806180000.xml b/crontask/ftp/cm/20230806/CM-HX-SMF-16.1.1-20230806180000.xml
new file mode 100644
index 00000000..2676c41f
--- /dev/null
+++ b/crontask/ftp/cm/20230806/CM-HX-SMF-16.1.1-20230806180000.xml
@@ -0,0 +1,138 @@
+
+
+
+ 2023-08-06 18:00:00
+ UTC+8
+ Ruijie Network
+ SMF
+ 16.1.1
+
+
+ EpRpDynN10Smf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+ IPResource
+
+ Id
+ InterfaceType
+ LocIpV4AddrList
+ LocIpV6AddrList
+ UserLabel
+
+
+
+
+
+
+ ManagedElement
+
+ AdministrativeState
+ Id
+ ManagedBy
+ ManagementIpAddress
+ OperationalState
+ PatchInfo
+ SwVersion
+ UserLabel
+ VendorName
+
+
+
+
+
+
+ SmfFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ MaxPduSessions
+ MaxQfi
+ OperationalState
+ SbiServiceList
+ UpfList
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+ AddrPool
+
+ AddrSegList
+ AddrType
+ Id
+ IpVersion
+ UserLabel
+
+
+
+
+
+
+ EpRpDynN7Smf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
\ No newline at end of file
diff --git a/crontask/ftp/cm/20230806/CM-HX-UDM-16.1.1-20230806000000.xml b/crontask/ftp/cm/20230806/CM-HX-UDM-16.1.1-20230806000000.xml
new file mode 100644
index 00000000..a612ece8
--- /dev/null
+++ b/crontask/ftp/cm/20230806/CM-HX-UDM-16.1.1-20230806000000.xml
@@ -0,0 +1,235 @@
+
+
+
+ 2023-08-06 00:00:00
+ UTC+8
+ Ruijie Network
+ UDM
+ 16.1.1
+
+
+ UdmFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ OperationalState
+ SbiServiceList
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+
+ UdrFunction
+
+ AddrSegList
+ AddrType
+ Id
+ IpVersion
+ UserLabel
+
+
+
+
+
+
+
+
+
+ AusfFunction
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+
+
+
+ IPResource
+
+ Id
+ InterfaceType
+ LocIpV4AddrList
+ LocIpV6AddrList
+ UserLabel
+
+
+
+
+
+
+
+
+
+ ManagedElement
+
+ AdministrativeState
+ Id
+ ManagedBy
+ ManagementIpAddress
+ OperationalState
+ PatchInfo
+ SwVersion
+ UserLabel
+ VendorName
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/crontask/ftp/cm/20230806/CM-HX-UDM-16.1.1-20230806060000.xml b/crontask/ftp/cm/20230806/CM-HX-UDM-16.1.1-20230806060000.xml
new file mode 100644
index 00000000..ff6c0b7b
--- /dev/null
+++ b/crontask/ftp/cm/20230806/CM-HX-UDM-16.1.1-20230806060000.xml
@@ -0,0 +1,235 @@
+
+
+
+ 2023-08-06 06:00:00
+ UTC+8
+ Ruijie Network
+ UDM
+ 16.1.1
+
+
+ ManagedElement
+
+ AdministrativeState
+ Id
+ ManagedBy
+ ManagementIpAddress
+ OperationalState
+ PatchInfo
+ SwVersion
+ UserLabel
+ VendorName
+
+
+
+
+
+
+
+
+
+ UdmFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ OperationalState
+ SbiServiceList
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+
+ UdrFunction
+
+ AddrSegList
+ AddrType
+ Id
+ IpVersion
+ UserLabel
+
+
+
+
+
+
+
+
+
+ AusfFunction
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+
+
+
+ IPResource
+
+ Id
+ InterfaceType
+ LocIpV4AddrList
+ LocIpV6AddrList
+ UserLabel
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/crontask/ftp/cm/20230806/CM-HX-UDM-16.1.1-20230806120000.xml b/crontask/ftp/cm/20230806/CM-HX-UDM-16.1.1-20230806120000.xml
new file mode 100644
index 00000000..2f475846
--- /dev/null
+++ b/crontask/ftp/cm/20230806/CM-HX-UDM-16.1.1-20230806120000.xml
@@ -0,0 +1,235 @@
+
+
+
+ 2023-08-06 12:00:00
+ UTC+8
+ Ruijie Network
+ UDM
+ 16.1.1
+
+
+ UdrFunction
+
+ AddrSegList
+ AddrType
+ Id
+ IpVersion
+ UserLabel
+
+
+
+
+
+
+
+
+
+ AusfFunction
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+
+
+
+ IPResource
+
+ Id
+ InterfaceType
+ LocIpV4AddrList
+ LocIpV6AddrList
+ UserLabel
+
+
+
+
+
+
+
+
+
+ ManagedElement
+
+ AdministrativeState
+ Id
+ ManagedBy
+ ManagementIpAddress
+ OperationalState
+ PatchInfo
+ SwVersion
+ UserLabel
+ VendorName
+
+
+
+
+
+
+
+
+
+ UdmFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ OperationalState
+ SbiServiceList
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/crontask/ftp/cm/20230806/CM-HX-UDM-16.1.1-20230806180000.xml b/crontask/ftp/cm/20230806/CM-HX-UDM-16.1.1-20230806180000.xml
new file mode 100644
index 00000000..f1303341
--- /dev/null
+++ b/crontask/ftp/cm/20230806/CM-HX-UDM-16.1.1-20230806180000.xml
@@ -0,0 +1,235 @@
+
+
+
+ 2023-08-06 18:00:00
+ UTC+8
+ Ruijie Network
+ UDM
+ 16.1.1
+
+
+ ManagedElement
+
+ AdministrativeState
+ Id
+ ManagedBy
+ ManagementIpAddress
+ OperationalState
+ PatchInfo
+ SwVersion
+ UserLabel
+ VendorName
+
+
+
+
+
+
+
+
+
+ UdmFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ OperationalState
+ SbiServiceList
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+
+ UdrFunction
+
+ AddrSegList
+ AddrType
+ Id
+ IpVersion
+ UserLabel
+
+
+
+
+
+
+
+
+
+ AusfFunction
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+
+
+
+ IPResource
+
+ Id
+ InterfaceType
+ LocIpV4AddrList
+ LocIpV6AddrList
+ UserLabel
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/crontask/ftp/cm/20230806/CM-HX-UPF-16.1.1-20230806000000.xml b/crontask/ftp/cm/20230806/CM-HX-UPF-16.1.1-20230806000000.xml
new file mode 100644
index 00000000..c584debb
--- /dev/null
+++ b/crontask/ftp/cm/20230806/CM-HX-UPF-16.1.1-20230806000000.xml
@@ -0,0 +1,648 @@
+
+
+
+ 2023-08-06 00:00:00
+ UTC+8
+ Ruijie Network
+ UPF
+ 16.1.1
+
+
+ UpfFunction
+
+ AdministrativeState
+ Id
+ MaxQosFlows
+ MaxThroughput
+ OperationalState
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ EpRpDynN9Upf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+
+
+ InventoryUnitRack
+
+ AdministrativeState
+ Fqdn
+ Id
+ MaxPduSessions
+ MaxQfi
+ OperationalState
+ SbiServiceList
+ UpfList
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ InventoryUnitHost
+
+ DateOfLastService
+ DateOfManufacture
+ HardDiskSize
+ HostPosition
+ Id
+ ManufacturerData
+ MemSize
+ NumberOfCpu
+ SerialNumber
+ UserLabel
+ VendorName
+ VendorUnitFamilyType
+ VendorUnitTypeNumber
+ VersionNumber
+
+
+
+
+
+
+
+
+ EpRpDynN3Upf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+
+
+ AmfFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ OperationalState
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ UdrFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ OperationalState
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ InventoryUnitPack
+
+ DateOfLastService
+ DateOfManufacture
+ Id
+ ManufacturerData
+ PackPosition
+ PortsInformation
+ SerialNumber
+ SlotsOccupied
+ UserLabel
+ VendorName
+ VendorUnitFamilyType
+ VendorUnitTypeNumber
+ VersionNumber
+
+
+
+
+
+
+
+
+ InventoryUnitAccessory
+
+ AccessoryPosition
+ AccessoryType
+ AddtionalInformation
+ DateOfLastService
+ DateOfManufacture
+ Id
+ ManufacturerData
+ SerialNumber
+ UserLabel
+ VendorName
+ VendorUnitFamilyType
+ VendorUnitTypeNumber
+ VersionNumber
+
+
+
+
+
+
+
+
+ SmfFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ OperationalState
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ AusfFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ OperationalState
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ IPResource
+
+ Id
+ InterfaceType
+ LocIpV4AddrList
+ LocIpV6AddrList
+ UserLabel
+
+
+
+
+
+
+
+
+ ManagedElement
+
+ AdministrativeState
+ Id
+ ManagedBy
+ ManagementIpAddress
+ OperationalState
+ PatchInfo
+ SwVersion
+ UserLabel
+ VendorName
+
+
+
+
+
+
+
+
+ InventoryUnitShelf
+
+ DateOfLastService
+ DateOfManufacture
+ Id
+ ManufacturerData
+ RackPosition
+ SerialNumber
+ UserLabel
+ VendorName
+ VendorUnitFamilyType
+ VendorUnitTypeNumber
+ VersionNumber
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/crontask/ftp/cm/20230806/CM-HX-UPF-16.1.1-20230806060000.xml b/crontask/ftp/cm/20230806/CM-HX-UPF-16.1.1-20230806060000.xml
new file mode 100644
index 00000000..ac474053
--- /dev/null
+++ b/crontask/ftp/cm/20230806/CM-HX-UPF-16.1.1-20230806060000.xml
@@ -0,0 +1,648 @@
+
+
+
+ 2023-08-06 06:00:00
+ UTC+8
+ Ruijie Network
+ UPF
+ 16.1.1
+
+
+ UdrFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ OperationalState
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ InventoryUnitPack
+
+ DateOfLastService
+ DateOfManufacture
+ Id
+ ManufacturerData
+ PackPosition
+ PortsInformation
+ SerialNumber
+ SlotsOccupied
+ UserLabel
+ VendorName
+ VendorUnitFamilyType
+ VendorUnitTypeNumber
+ VersionNumber
+
+
+
+
+
+
+
+
+ EpRpDynN9Upf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+
+
+ SmfFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ OperationalState
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ InventoryUnitRack
+
+ AdministrativeState
+ Fqdn
+ Id
+ MaxPduSessions
+ MaxQfi
+ OperationalState
+ SbiServiceList
+ UpfList
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ EpRpDynN3Upf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+
+
+ ManagedElement
+
+ AdministrativeState
+ Id
+ ManagedBy
+ ManagementIpAddress
+ OperationalState
+ PatchInfo
+ SwVersion
+ UserLabel
+ VendorName
+
+
+
+
+
+
+
+
+ UpfFunction
+
+ AdministrativeState
+ Id
+ MaxQosFlows
+ MaxThroughput
+ OperationalState
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ AusfFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ OperationalState
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ AmfFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ OperationalState
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ IPResource
+
+ Id
+ InterfaceType
+ LocIpV4AddrList
+ LocIpV6AddrList
+ UserLabel
+
+
+
+
+
+
+
+
+ InventoryUnitShelf
+
+ DateOfLastService
+ DateOfManufacture
+ Id
+ ManufacturerData
+ RackPosition
+ SerialNumber
+ UserLabel
+ VendorName
+ VendorUnitFamilyType
+ VendorUnitTypeNumber
+ VersionNumber
+
+
+
+
+
+
+
+
+ InventoryUnitHost
+
+ DateOfLastService
+ DateOfManufacture
+ HardDiskSize
+ HostPosition
+ Id
+ ManufacturerData
+ MemSize
+ NumberOfCpu
+ SerialNumber
+ UserLabel
+ VendorName
+ VendorUnitFamilyType
+ VendorUnitTypeNumber
+ VersionNumber
+
+
+
+
+
+
+
+
+ InventoryUnitAccessory
+
+ AccessoryPosition
+ AccessoryType
+ AddtionalInformation
+ DateOfLastService
+ DateOfManufacture
+ Id
+ ManufacturerData
+ SerialNumber
+ UserLabel
+ VendorName
+ VendorUnitFamilyType
+ VendorUnitTypeNumber
+ VersionNumber
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/crontask/ftp/cm/20230806/CM-HX-UPF-16.1.1-20230806120000.xml b/crontask/ftp/cm/20230806/CM-HX-UPF-16.1.1-20230806120000.xml
new file mode 100644
index 00000000..6b7399e2
--- /dev/null
+++ b/crontask/ftp/cm/20230806/CM-HX-UPF-16.1.1-20230806120000.xml
@@ -0,0 +1,648 @@
+
+
+
+ 2023-08-06 12:00:00
+ UTC+8
+ Ruijie Network
+ UPF
+ 16.1.1
+
+
+ InventoryUnitHost
+
+ DateOfLastService
+ DateOfManufacture
+ HardDiskSize
+ HostPosition
+ Id
+ ManufacturerData
+ MemSize
+ NumberOfCpu
+ SerialNumber
+ UserLabel
+ VendorName
+ VendorUnitFamilyType
+ VendorUnitTypeNumber
+ VersionNumber
+
+
+
+
+
+
+
+
+ InventoryUnitRack
+
+ AdministrativeState
+ Fqdn
+ Id
+ MaxPduSessions
+ MaxQfi
+ OperationalState
+ SbiServiceList
+ UpfList
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ EpRpDynN9Upf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+
+
+ EpRpDynN3Upf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+
+
+ AmfFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ OperationalState
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ AusfFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ OperationalState
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ IPResource
+
+ Id
+ InterfaceType
+ LocIpV4AddrList
+ LocIpV6AddrList
+ UserLabel
+
+
+
+
+
+
+
+
+ InventoryUnitShelf
+
+ DateOfLastService
+ DateOfManufacture
+ Id
+ ManufacturerData
+ RackPosition
+ SerialNumber
+ UserLabel
+ VendorName
+ VendorUnitFamilyType
+ VendorUnitTypeNumber
+ VersionNumber
+
+
+
+
+
+
+
+
+ InventoryUnitPack
+
+ DateOfLastService
+ DateOfManufacture
+ Id
+ ManufacturerData
+ PackPosition
+ PortsInformation
+ SerialNumber
+ SlotsOccupied
+ UserLabel
+ VendorName
+ VendorUnitFamilyType
+ VendorUnitTypeNumber
+ VersionNumber
+
+
+
+
+
+
+
+
+ InventoryUnitAccessory
+
+ AccessoryPosition
+ AccessoryType
+ AddtionalInformation
+ DateOfLastService
+ DateOfManufacture
+ Id
+ ManufacturerData
+ SerialNumber
+ UserLabel
+ VendorName
+ VendorUnitFamilyType
+ VendorUnitTypeNumber
+ VersionNumber
+
+
+
+
+
+
+
+
+ UdrFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ OperationalState
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ ManagedElement
+
+ AdministrativeState
+ Id
+ ManagedBy
+ ManagementIpAddress
+ OperationalState
+ PatchInfo
+ SwVersion
+ UserLabel
+ VendorName
+
+
+
+
+
+
+
+
+ UpfFunction
+
+ AdministrativeState
+ Id
+ MaxQosFlows
+ MaxThroughput
+ OperationalState
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ SmfFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ OperationalState
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/crontask/ftp/cm/20230806/CM-HX-UPF-16.1.1-20230806180000.xml b/crontask/ftp/cm/20230806/CM-HX-UPF-16.1.1-20230806180000.xml
new file mode 100644
index 00000000..762497d2
--- /dev/null
+++ b/crontask/ftp/cm/20230806/CM-HX-UPF-16.1.1-20230806180000.xml
@@ -0,0 +1,648 @@
+
+
+
+ 2023-08-06 18:00:00
+ UTC+8
+ Ruijie Network
+ UPF
+ 16.1.1
+
+
+ IPResource
+
+ Id
+ InterfaceType
+ LocIpV4AddrList
+ LocIpV6AddrList
+ UserLabel
+
+
+
+
+
+
+
+
+ InventoryUnitRack
+
+ AdministrativeState
+ Fqdn
+ Id
+ MaxPduSessions
+ MaxQfi
+ OperationalState
+ SbiServiceList
+ UpfList
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ EpRpDynN9Upf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+
+
+ InventoryUnitPack
+
+ DateOfLastService
+ DateOfManufacture
+ Id
+ ManufacturerData
+ PackPosition
+ PortsInformation
+ SerialNumber
+ SlotsOccupied
+ UserLabel
+ VendorName
+ VendorUnitFamilyType
+ VendorUnitTypeNumber
+ VersionNumber
+
+
+
+
+
+
+
+
+ UdrFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ OperationalState
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ InventoryUnitAccessory
+
+ AccessoryPosition
+ AccessoryType
+ AddtionalInformation
+ DateOfLastService
+ DateOfManufacture
+ Id
+ ManufacturerData
+ SerialNumber
+ UserLabel
+ VendorName
+ VendorUnitFamilyType
+ VendorUnitTypeNumber
+ VersionNumber
+
+
+
+
+
+
+
+
+ UpfFunction
+
+ AdministrativeState
+ Id
+ MaxQosFlows
+ MaxThroughput
+ OperationalState
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ EpRpDynN3Upf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+
+
+ AmfFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ OperationalState
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ AusfFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ OperationalState
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ ManagedElement
+
+ AdministrativeState
+ Id
+ ManagedBy
+ ManagementIpAddress
+ OperationalState
+ PatchInfo
+ SwVersion
+ UserLabel
+ VendorName
+
+
+
+
+
+
+
+
+ InventoryUnitHost
+
+ DateOfLastService
+ DateOfManufacture
+ HardDiskSize
+ HostPosition
+ Id
+ ManufacturerData
+ MemSize
+ NumberOfCpu
+ SerialNumber
+ UserLabel
+ VendorName
+ VendorUnitFamilyType
+ VendorUnitTypeNumber
+ VersionNumber
+
+
+
+
+
+
+
+
+ InventoryUnitShelf
+
+ DateOfLastService
+ DateOfManufacture
+ Id
+ ManufacturerData
+ RackPosition
+ SerialNumber
+ UserLabel
+ VendorName
+ VendorUnitFamilyType
+ VendorUnitTypeNumber
+ VersionNumber
+
+
+
+
+
+
+
+
+ SmfFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ OperationalState
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/crontask/ftp/cm/20230810/CM-HX-AMF-16.1.1-20230810000001.xml b/crontask/ftp/cm/20230810/CM-HX-AMF-16.1.1-20230810000001.xml
new file mode 100644
index 00000000..1247fd97
--- /dev/null
+++ b/crontask/ftp/cm/20230810/CM-HX-AMF-16.1.1-20230810000001.xml
@@ -0,0 +1,140 @@
+
+
+
+ 2023-08-10 00:00:01
+ UTC+8
+ Ruijie Network
+ AMF
+ 16.1.1
+
+
+ IPResource
+
+ Id
+ InterfaceType
+ LocIpV4AddrList
+ LocIpV6AddrList
+ UserLabel
+
+
+
+
+
+
+ ManagedElement
+
+ AdministrativeState
+ Id
+ ManagedBy
+ ManagementIpAddress
+ OperationalState
+ PatchInfo
+ SwVersion
+ UserLabel
+ VendorName
+
+
+
+
+
+
+ AmfFunction
+
+ AdministrativeState
+ AmfGuamiList
+ Fqdn
+ Id
+ MaxGnbNum
+ MaxUser
+ OperationalState
+ RelativeCapacity
+ SbiServiceList
+ SnssaiList
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+ EpRpDynN8Amf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+ EpRpDynN11Amf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+ EpRpDynN12Amf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
\ No newline at end of file
diff --git a/crontask/ftp/cm/20230810/CM-HX-AUSF-16.1.1-20230810000001.xml b/crontask/ftp/cm/20230810/CM-HX-AUSF-16.1.1-20230810000001.xml
new file mode 100644
index 00000000..9632527d
--- /dev/null
+++ b/crontask/ftp/cm/20230810/CM-HX-AUSF-16.1.1-20230810000001.xml
@@ -0,0 +1,10 @@
+
+
+
+ 2023-08-10 00:00:01
+ UTC+8
+ Ruijie Network
+ AUSF
+ 16.1.1
+
+
\ No newline at end of file
diff --git a/crontask/ftp/cm/20230810/CM-HX-SMF-16.1.1-20230810000001.xml b/crontask/ftp/cm/20230810/CM-HX-SMF-16.1.1-20230810000001.xml
new file mode 100644
index 00000000..ca9753e7
--- /dev/null
+++ b/crontask/ftp/cm/20230810/CM-HX-SMF-16.1.1-20230810000001.xml
@@ -0,0 +1,138 @@
+
+
+
+ 2023-08-10 00:00:01
+ UTC+8
+ Ruijie Network
+ SMF
+ 16.1.1
+
+
+ SmfFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ MaxPduSessions
+ MaxQfi
+ OperationalState
+ SbiServiceList
+ UpfList
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+ AddrPool
+
+ AddrSegList
+ AddrType
+ Id
+ IpVersion
+ UserLabel
+
+
+
+
+
+
+ EpRpDynN7Smf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+ EpRpDynN10Smf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+ IPResource
+
+ Id
+ InterfaceType
+ LocIpV4AddrList
+ LocIpV6AddrList
+ UserLabel
+
+
+
+
+
+
+ ManagedElement
+
+ AdministrativeState
+ Id
+ ManagedBy
+ ManagementIpAddress
+ OperationalState
+ PatchInfo
+ SwVersion
+ UserLabel
+ VendorName
+
+
+
+
+
+
\ No newline at end of file
diff --git a/crontask/ftp/cm/20230810/CM-HX-UDM-16.1.1-20230810000001.xml b/crontask/ftp/cm/20230810/CM-HX-UDM-16.1.1-20230810000001.xml
new file mode 100644
index 00000000..f9866a48
--- /dev/null
+++ b/crontask/ftp/cm/20230810/CM-HX-UDM-16.1.1-20230810000001.xml
@@ -0,0 +1,235 @@
+
+
+
+ 2023-08-10 00:00:01
+ UTC+8
+ Ruijie Network
+ UDM
+ 16.1.1
+
+
+ ManagedElement
+
+ AdministrativeState
+ Id
+ ManagedBy
+ ManagementIpAddress
+ OperationalState
+ PatchInfo
+ SwVersion
+ UserLabel
+ VendorName
+
+
+
+
+
+
+
+
+
+ UdmFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ OperationalState
+ SbiServiceList
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+
+ UdrFunction
+
+ AddrSegList
+ AddrType
+ Id
+ IpVersion
+ UserLabel
+
+
+
+
+
+
+
+
+
+ AusfFunction
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+
+
+
+ IPResource
+
+ Id
+ InterfaceType
+ LocIpV4AddrList
+ LocIpV6AddrList
+ UserLabel
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/crontask/ftp/cm/20230810/CM-HX-UPF-16.1.1-20230810000001.xml b/crontask/ftp/cm/20230810/CM-HX-UPF-16.1.1-20230810000001.xml
new file mode 100644
index 00000000..bae2f5c3
--- /dev/null
+++ b/crontask/ftp/cm/20230810/CM-HX-UPF-16.1.1-20230810000001.xml
@@ -0,0 +1,648 @@
+
+
+
+ 2023-08-10 00:00:01
+ UTC+8
+ Ruijie Network
+ UPF
+ 16.1.1
+
+
+ InventoryUnitPack
+
+ DateOfLastService
+ DateOfManufacture
+ Id
+ ManufacturerData
+ PackPosition
+ PortsInformation
+ SerialNumber
+ SlotsOccupied
+ UserLabel
+ VendorName
+ VendorUnitFamilyType
+ VendorUnitTypeNumber
+ VersionNumber
+
+
+
+
+
+
+
+
+ InventoryUnitAccessory
+
+ AccessoryPosition
+ AccessoryType
+ AddtionalInformation
+ DateOfLastService
+ DateOfManufacture
+ Id
+ ManufacturerData
+ SerialNumber
+ UserLabel
+ VendorName
+ VendorUnitFamilyType
+ VendorUnitTypeNumber
+ VersionNumber
+
+
+
+
+
+
+
+
+ SmfFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ OperationalState
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ UdrFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ OperationalState
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ IPResource
+
+ Id
+ InterfaceType
+ LocIpV4AddrList
+ LocIpV6AddrList
+ UserLabel
+
+
+
+
+
+
+
+
+ EpRpDynN9Upf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+
+
+ AusfFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ OperationalState
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ ManagedElement
+
+ AdministrativeState
+ Id
+ ManagedBy
+ ManagementIpAddress
+ OperationalState
+ PatchInfo
+ SwVersion
+ UserLabel
+ VendorName
+
+
+
+
+
+
+
+
+ InventoryUnitRack
+
+ AdministrativeState
+ Fqdn
+ Id
+ MaxPduSessions
+ MaxQfi
+ OperationalState
+ SbiServiceList
+ UpfList
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ UpfFunction
+
+ AdministrativeState
+ Id
+ MaxQosFlows
+ MaxThroughput
+ OperationalState
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
+ EpRpDynN3Upf
+
+ FarIpSubnetworkList
+ Id
+ LocIpAddrList
+ UserLabel
+
+
+
+
+
+
+
+
+ InventoryUnitShelf
+
+ DateOfLastService
+ DateOfManufacture
+ Id
+ ManufacturerData
+ RackPosition
+ SerialNumber
+ UserLabel
+ VendorName
+ VendorUnitFamilyType
+ VendorUnitTypeNumber
+ VersionNumber
+
+
+
+
+
+
+
+
+ InventoryUnitHost
+
+ DateOfLastService
+ DateOfManufacture
+ HardDiskSize
+ HostPosition
+ Id
+ ManufacturerData
+ MemSize
+ NumberOfCpu
+ SerialNumber
+ UserLabel
+ VendorName
+ VendorUnitFamilyType
+ VendorUnitTypeNumber
+ VersionNumber
+
+
+
+
+
+
+
+
+ AmfFunction
+
+ AdministrativeState
+ Fqdn
+ Id
+ OperationalState
+ UserLabel
+ VnfInstanceId
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/crontask/ftp/pm/0001010100/PM-SMF-16.1.1-00010101000000-15-001.xml b/crontask/ftp/pm/0001010100/PM-SMF-16.1.1-00010101000000-15-001.xml
new file mode 100644
index 00000000..97b6b0e9
--- /dev/null
+++ b/crontask/ftp/pm/0001010100/PM-SMF-16.1.1-00010101000000-15-001.xml
@@ -0,0 +1,243 @@
+
+
+
+ 2023-08-10 02:20:00
+ UTC+8
+ 15
+ Ruijie Network
+ SMF
+ 16.1.1
+ 2023-08-10 02:00:00 +0800 CST
+
+
+ SmfFunction
+
+ SMF.FailCreatePduSession._Ns.46
+ SMF.FailCreatePduSession._Dnn.46
+ SMF.FailCreatePduSession._Dnn.82
+ SMF.AttSmfModifyPduSession._Ns
+ SMF.AttCreatePduSession._Ns
+ SMF.FailCreatePduSession.46
+ SMF.FailCreatePduSession._Ns
+ SMF.FailCreatePduSession._Ns.28
+ SMF.FailCreatePduSession._Ns.27
+ SMF.FailCreatePduSession._Ns.33
+ SMF.SuccSmfModifyPduSession._Dnn
+ SMF.SuccSmfModifyBearerResponse.Epsfb
+ SMF.SuccCreatePduSession._Ns
+ SMF.FailCreatePduSession
+ SMF.FailCreatePduSession.29
+ SMF.FailCreatePduSession._Dnn
+ SMF.FailCreatePduSession._Dnn.29
+ SMF.FailCreatePduSession._Dnn.33
+ SMF.FailCreatePduSession.68
+ SMF.FailCreatePduSession._Ns.82
+ SMF.SuccSmfModifyPduSession._Ns
+ SMF.AttSmfModifyPduSession.Epsfb
+ SMF.FailSmfModifyPduSession._Dnn
+ SMF.FailCreatePduSession._Cause
+ SMF.FailCreatePduSession.33
+ SMF.FailCreatePduSession.26
+ SMF.FailCreatePduSession._Dnn.68
+ SMF.AttCreatePduSession._Dnn
+ SMF.SuccCreatePduSession
+ SMF.FailCreatePduSession._Ns.29
+ SMF.FailCreatePduSession._Dnn.28
+ SMF.AttSmfModifyPduSession
+ SMF.FailSmfModifyPduSession
+ SMF.FailSmfModifyPduSession._Ns
+ SMF.AttCreatePduSession
+ SMF.FailCreatePduSession._Ns.68
+ SMF.AttSmfModifyPduSession._Dnn
+ SMF.SuccCreatePduSession._Dnn
+ SMF.FailCreatePduSession.82
+ SMF.FailCreatePduSession.28
+ SMF.FailCreatePduSession.27
+ SMF.SuccSmfModifyPduSession
+
+
+
+
+
+
+ EpRpDynN7Smf
+
+ SMF.SmPlcyCtrlCreateSucc
+ SMF.SmPlcyCtrlDeleteReq
+ SMF.SmPlcyCtrlUpdateReq
+ SMF.SmPlcyCtrlUpdateSucc
+ SMF.SmPlcyCtrlDeleteSucc
+ SMF.SmPlcyCtrlCreateReq
+
+
+
+
+
+
+ EpRpDynN10Smf
+
+ SMF.UecmRegFail.Unknown5GSub
+ SMF.UecmRegFail.RoamNotAllowed
+ SMF.UecmRegReq
+ SMF.UecmDeregReq
+ SMF.UecmRegFail._Cause
+ SMF.UecmRegFail.DnnNotAllowed
+ SMF.UecmDeregSucc
+ SMF.UecmRegSucc
+ SMF.UecmRegFail
+
+
+
+
+
+
+ SmfFunction
+
+ SMF.MeanPduSession
+ SMF.MeanPduSession._Ns
+ SMF.MeanPduSession._Dnn
+ SMF.MeanQf
+ SMF.MeanQf._Ns
+ SMF.MeanQf._Dnn
+
+
+
+
+
+
+ ManagedElement
+
+ ME.MeanMeLoad
+
+
+
+
+
+
+ AddrPool
+
+ SMF.MeanAllcAddr
+ SMF.MeanAllcAddr._Ns
+
+
+
+
+
+
+ SmfFunction
+
+ SMF.MaxPduSession._Dnn
+ SMF.MaxQf
+ SMF.MaxQf._Ns
+ SMF.MaxQf._Dnn
+ SMF.MaxPduSession
+ SMF.MaxPduSession._Ns
+
+
+
+
+
+
+ AddrPool
+
+ SMF.MaxAllcAddr
+ SMF.MaxAllcAddr._Ns
+
+
+
+
+
+
+ SmfFunction
+
+ SMF.PduSessionCreateTime
+
+
+
+
+
+
\ No newline at end of file
diff --git a/crontask/ftp/pm/0001010100/PM-UPF-16.1.1-00010101000000-15-001.xml b/crontask/ftp/pm/0001010100/PM-UPF-16.1.1-00010101000000-15-001.xml
new file mode 100644
index 00000000..e511bc8c
--- /dev/null
+++ b/crontask/ftp/pm/0001010100/PM-UPF-16.1.1-00010101000000-15-001.xml
@@ -0,0 +1,240 @@
+
+
+
+ 2023-08-10 02:20:00
+ UTC+8
+ 15
+ Ruijie Network
+ UPF
+ 16.1.1
+ 2023-08-10 01:45:00 +0800 CST
+
+
+ UpfFunction
+
+ upf.pfcpsessionestabreq
+ upf.pfcpsessionestabsucc
+ upf.pfcpsessionestabfail
+ upf.pfcpsessionmodifyreq
+ upf.pfcpsessionmodifysucc
+ upf.pfcpsessionmodifyfail
+ upf.meanqosflows
+ upf.maxqosflows
+ upf.n6incpkt
+ upf.n6incpktipv6
+ upf.n6incpktipv6._dnn
+ upf.n6ogpkt
+ upf.n6ogpktipv6
+ upf.n6ogpktipv6._dnn
+ upf.n6incoct
+ upf.n6incoctipv6
+ upf.n6incoctipv6._dnn
+ upf.n6ogoct
+ upf.n6ogoctipv6
+ upf.n6ogoctipv6._dnn
+ upf.n6discpkt
+ upf.n6discpktipv6
+ upf.n6discpktipv6._dnn
+
+
+
+
+
+
+ EpRpDynN3Upf
+
+ upf.n3incpkt
+ upf.n3ogpkt
+ upf.n3incoct
+ upf.n3ogoct
+ upf.n3discpkt
+
+
+
+
+
+
+ EpRpDynN9Upf
+
+ upf.n9aincpkt
+ upf.n9aogpkt
+ upf.n9aincoct
+ upf.n9aogoct
+ upf.n9adiscpkt
+ upf.n9cincpkt
+ upf.n9cogpkt
+ upf.n9cincoct
+ upf.n9cogoct
+ upf.n9cdiscpkt
+
+
+
+
+
+
+ ManagedElement
+
+ me.meanmeload
+
+
+
+
+
+
+ UpfFunction
+
+ upf.pfcpsessionestabreq
+ upf.pfcpsessionestabsucc
+ upf.pfcpsessionestabfail
+ upf.pfcpsessionmodifyreq
+ upf.pfcpsessionmodifysucc
+ upf.pfcpsessionmodifyfail
+ upf.meanqosflows
+ upf.maxqosflows
+ upf.n6incpkt
+ upf.n6incpktipv6
+ upf.n6incpktipv6._dnn
+ upf.n6ogpkt
+ upf.n6ogpktipv6
+ upf.n6ogpktipv6._dnn
+ upf.n6incoct
+ upf.n6incoctipv6
+ upf.n6incoctipv6._dnn
+ upf.n6ogoct
+ upf.n6ogoctipv6
+ upf.n6ogoctipv6._dnn
+ upf.n6discpkt
+ upf.n6discpktipv6
+ upf.n6discpktipv6._dnn
+
+
+
+
+
+
+ EpRpDynN3Upf
+
+ upf.n3incpkt
+ upf.n3ogpkt
+ upf.n3incoct
+ upf.n3ogoct
+ upf.n3discpkt
+
+
+
+
+
+
+ EpRpDynN9Upf
+
+ upf.n9aincpkt
+ upf.n9aogpkt
+ upf.n9aincoct
+ upf.n9aogoct
+ upf.n9adiscpkt
+ upf.n9cincpkt
+ upf.n9cogpkt
+ upf.n9cincoct
+ upf.n9cogoct
+ upf.n9cdiscpkt
+
+
+
+
+
+
+ ManagedElement
+
+ me.meanmeload
+
+
+
+
+
+
\ No newline at end of file
diff --git a/crontask/gencmxml.go b/crontask/gencmxml.go
new file mode 100644
index 00000000..697198c5
--- /dev/null
+++ b/crontask/gencmxml.go
@@ -0,0 +1,165 @@
+package main
+
+import (
+ "encoding/xml"
+ "fmt"
+ "os"
+ "sort"
+ "strconv"
+ "strings"
+ "time"
+
+ cmschema "ems.agt/crontask/cm/schema"
+ "ems.agt/lib/global"
+ "ems.agt/lib/log"
+
+ "gopkg.in/yaml.v3"
+)
+
+const (
+ // Header is a generic XML header suitable for use with the output of Marshal.
+ // This is not automatically added to any output of this package,
+ // it is provided as a convenience.
+ Header = `` + "\n"
+)
+
+const (
+ AdminStateLocked = "Locked"
+ AdminStateUnlocked = "Unlocked"
+ AdminStateShuttingdown = "ShuttingDown"
+ OperationStateDisabled = "Disabled"
+ OperationStateEnabled = "Enabled"
+)
+
+func (t *TaskFunc) GenCmXmlFile(uri, params, body string) {
+ log.Debug("GenCmXmlFile processing ...")
+ for _, neType := range neTypes {
+ t.GenNFXmlFile(neType)
+ }
+}
+
+func (t *TaskFunc) ReadCmYaml(cmfile string) (map[string]interface{}, error) {
+ log.Debug("cmfile:", cmfile)
+ file, err := os.ReadFile(cmfile)
+ if err != nil {
+ log.Error(err)
+ return nil, err
+ }
+ log.Debug("file:", file)
+ resultMap := make(map[string]interface{})
+ err = yaml.Unmarshal(file, resultMap)
+ if err != nil {
+ log.Error(err)
+ return nil, err
+ }
+
+ log.Debug("resultMap:", resultMap)
+ return resultMap, nil
+}
+
+func (t *TaskFunc) GenNFXmlFile(neType string) error {
+ var nes []NeInfo
+ _, err := XormGetNeInfoByType(neType, &nes)
+ if err != nil {
+ log.Error("Failed to get all ne info:", err)
+ return err
+ }
+
+ cmfile := fmt.Sprintf("%s/cm-%s.yaml", yamlConfig.NBI.CM.CfgFileDir, strings.ToLower(neType))
+
+ resultMap, _ := t.ReadCmYaml(cmfile)
+
+ ti := time.Now()
+ timestamp := ti.Format("2006-01-02 15:04:05")
+ timefile := ti.Format("20060102150405")
+ date := ti.Format("20060102")
+ _, offset := ti.Zone()
+ var tzOffset string
+ if offset >= 0 {
+ tzOffset = "UTC+" + strconv.Itoa(offset/3600)
+ } else {
+ tzOffset = "UTC" + strconv.Itoa(offset/3600)
+ }
+
+ nrmFile := new(cmschema.DataFile)
+
+ nrmFile.FileHeader = cmschema.FileHeader{
+ TimeStamp: timestamp,
+ TimeZone: tzOffset,
+ VendorName: "Ruijie Network",
+ ElementType: neType,
+ CmVersion: global.Version,
+ }
+
+ nrmFile.XsiAttr = "http://www.w3.org/2001/XMLSchema-instance"
+ nrmFile.XsiLoc = "file:///usr/loal/omc/etc/schema/cm-schema.xsd"
+
+ for k, e := range resultMap {
+ objects := cmschema.Objects{ObjectType: k}
+
+ sortResult := make(map[string]string)
+ keys := make([]string, 0)
+ for key, value := range e.(map[string]interface{}) {
+ sortResult[key] = fmt.Sprintf("%v", value)
+ keys = append(keys, key)
+ }
+
+ sort.Strings(keys)
+
+ for s, ne := range nes {
+ rmUID := fmt.Sprintf("01000HX%sBJ0D0%d", neType, s+1)
+ vmId := fmt.Sprintf("kylin10.0-00%d-%s", s+1, neType)
+ vnfInstanceID := fmt.Sprintf("2%xd55b4-%d018-41f4-af%d5-28b%d828788", s+10, s+6, s+4, s+3)
+ object := cmschema.Object{RmUIDAttr: rmUID,
+ DnAttr: "DC=www.ruijie.com.cn,SubNetwork=10001,SubNetwork=114214,ManagedElement=325",
+ UserLabelAttr: ne.NeName, PVFlagAttr: ne.PvFlag, VMIDAttr: vmId, VNFInstanceIDAttr: vnfInstanceID}
+
+ i := 1
+ for _, p := range keys {
+ if s == 0 {
+ objects.FieldName.N = append(objects.FieldName.N, cmschema.N{IAttr: i, Value: p})
+ }
+ var v string
+ switch p {
+ case "Id":
+ v = ne.NeId
+ case "UserLabel":
+ v = ne.NeName
+ case "VendorName":
+ v = "Ruijie Network"
+ case "SwVersion":
+ v = global.Version
+ case "PatchInfo":
+ v = "-"
+ case "AdministrativeState":
+ v = AdminStateUnlocked
+ case "OperationalState":
+ v = OperationStateEnabled
+ case "VnfInstanceId":
+ v = vnfInstanceID
+ default:
+ if sortResult[p] == "" {
+ v = "-"
+ } else {
+ v = fmt.Sprintf("%s", sortResult[p])
+ }
+ }
+ object.V = append(object.V, cmschema.V{IAttr: i, Value: v})
+ i++
+ }
+ objects.FieldValue.Object = append(objects.FieldValue.Object, object)
+ }
+ nrmFile.Objects = append(nrmFile.Objects, objects)
+ }
+
+ folderPath := global.CreateDir(date, yamlConfig.NBI.CM.XmlFileDir)
+ x, _ := xml.MarshalIndent(nrmFile, "", " ")
+ x = append([]byte(xml.Header), x...)
+ xmlfile := fmt.Sprintf("%s/CM-HX-%s-%s-%s.xml", folderPath, neType, global.Version, timefile)
+ err = os.WriteFile(xmlfile, x, 0664)
+ if err != nil {
+ log.Error("Failed to write xml file:", err)
+ return err
+ }
+ return nil
+}
diff --git a/crontask/genpmxml.go b/crontask/genpmxml.go
new file mode 100644
index 00000000..c295c14c
--- /dev/null
+++ b/crontask/genpmxml.go
@@ -0,0 +1,267 @@
+package main
+
+import (
+ "encoding/xml"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "regexp"
+ "strconv"
+ "strings"
+ "time"
+
+ pmschema "ems.agt/crontask/pm/schema"
+ "ems.agt/lib/global"
+ "ems.agt/lib/log"
+
+ "gopkg.in/yaml.v3"
+)
+
+var (
+ neTypes = []string{"AMF", "SMF", "UDM", "UPF", "AUSF"}
+)
+
+func (t *TaskFunc) GenPmXmlFile(uri, params, body string) {
+ for _, neType := range neTypes {
+ log.Debugf("GenPmXmlFile process %s xml file", neType)
+ t.GenNFPMXmlFile(neType)
+ }
+}
+
+func (t *TaskFunc) ReadPmYaml(cmfile string) (map[string]interface{}, error) {
+ log.Debug("cmfile:", cmfile)
+ file, err := ioutil.ReadFile(cmfile)
+ if err != nil {
+ log.Error(err)
+ return nil, err
+ }
+ log.Debug("file:", file)
+ resultMap := make(map[string]interface{})
+ err = yaml.Unmarshal(file, resultMap)
+ if err != nil {
+ log.Error(err)
+ return nil, err
+ }
+
+ log.Debug("resultMap:", resultMap)
+ return resultMap, nil
+}
+
+func (t *TaskFunc) IsPseudoSubPmName(pmName string) bool {
+ return strings.Contains(pmName, "._")
+}
+
+func (t *TaskFunc) GenNFPMXmlFile(neType string) error {
+ var nes []NeInfo
+ _, err := XormGetNeInfoByType(neType, &nes)
+ if err != nil {
+ log.Error("Failed to get all ne info:", err)
+ return err
+ }
+
+ // cfile := fmt.Sprintf("%s/pm-%s.yaml", yamlConfig.NBI.PM.CfgFileDir, strings.ToLower(neType))
+
+ // resultMap, _ := t.ReadPmYaml(cfile)
+
+ ti := time.Now()
+ var startTime string
+ timestamp := ti.Format("2006-01-02 15:04:05")
+
+ index := global.GetCurrentTimeSliceIndexByPeriod(ti, 15)
+ date := time.Now().Format("2006-01-02")
+ log.Debugf("date: %s index:%d", date, index)
+
+ _, offset := ti.Zone()
+ var tzOffset string
+ if offset >= 0 {
+ tzOffset = "UTC+" + strconv.Itoa(offset/3600)
+ } else {
+ tzOffset = "UTC" + strconv.Itoa(offset/3600)
+ }
+
+ pmFile := new(pmschema.PmFile)
+
+ var pms []NorthboundPm
+ _, err = XormGetNorthboundPm(date, index, neType, &pms)
+ if err != nil {
+ log.Error("Failed to get northbound_pm:", err)
+ return err
+ }
+
+ if len(pms) == 0 {
+ log.Errorf("%s:%v", neType, global.ErrPMNotFoundData)
+ return global.ErrPMNotFoundData
+ }
+
+ pmFile.XsAttr = "http://www.w3.org/2001/XMLSchema"
+ pmFile.XsiAttr = "http://www.w3.org/2001/XMLSchema-instance"
+ /*
+ objectTypes := make([]string, 0)
+ sortValues := make(map[string]interface{})
+ keys := make([]string, 0)
+ if len(pms) > 0 {
+ for _, data := range pms[0].Datas {
+ for _, pmData := range data.PmDatas {
+ sortValues[pmData.PmName] = pmData.SubDatas
+ keys = append(keys, pmData.PmName)
+ }
+ objectTypes = append(objectTypes, data.ObjectType)
+ }
+ sort.Strings(keys)
+ sort.Strings(objectTypes)
+ }
+ log.Debug("objectTypes:", objectTypes)
+ log.Debug("keys:", keys)
+ */
+ var measurement pmschema.Measurements
+ for _, pm := range pms {
+ for _, pdata := range pm.Datas {
+ measurement = pmschema.Measurements{ObjectType: pdata.ObjectType}
+ measurement.PmData.Object.RmUIDAttr = pm.RmUID
+ measurement.PmData.Object.DnAttr = pm.Dn
+ measurement.PmData.Object.UserLabelAttr = pm.NeName
+ startTime = pm.StartTime
+
+ i := 1
+ for _, pmData := range pdata.KPIs {
+ measurement.PmName.N = append(measurement.PmName.N, pmschema.N{IAttr: i, Value: pmData.KPIID})
+ cv := pmschema.CV{IAttr: i}
+ isPseudo := true
+ value := "0"
+ reg := regexp.MustCompile(`_\w+`)
+ //sns := strings.Split(pmData.KPIID, "_")
+ for _, v := range pmData.KPIValues {
+ if fmt.Sprintf("%v", v.Name) == "Total" {
+ isPseudo = false
+ value = fmt.Sprintf("%v", v.Value)
+ break
+ } else {
+ isPseudo = true
+ //if len(sns) > 1 {
+ // sns := strings.Split(sns[1], ".")
+ //}
+ sn := reg.ReplaceAllString(pmData.KPIID, v.Name)
+ //sn := sns[0] + v.Name
+ // cv.NV = append(cv.NV, pmschema.NV{SN: sn, SV: fmt.Sprintf("%v", v.Value)})
+ cv.SN = append(cv.SN, sn)
+ cv.SV = append(cv.SV, fmt.Sprintf("%v", v.Value))
+ }
+ }
+ if isPseudo == false {
+ measurement.PmData.Object.V = append(measurement.PmData.Object.V, pmschema.V{IAttr: i, Value: value})
+ } else {
+ measurement.PmData.Object.CV = append(measurement.PmData.Object.CV, cv)
+ }
+
+ i++
+ //measurement.PmData.Object.V = append(measurement.PmData.Object.V, pmschema.V{IAttr: i, Value: sortValues[pmName].Value})
+ //measurement.PmData.Object.CV = sortValues[pmName].Value
+ }
+ pmFile.Measurements = append(pmFile.Measurements, measurement)
+
+ }
+ }
+
+ pmFile.FileHeader = pmschema.FileHeader{
+ TimeStamp: timestamp,
+ TimeZone: tzOffset,
+ Period: 15,
+ VendorName: "Ruijie Network",
+ ElementType: neType,
+ PmVersion: global.Version,
+ StartTime: startTime,
+ }
+ /*
+ for _, obj := range objectTypes {
+ measurement := pmschema.Measurements{ObjectType: obj}
+
+ for _, pm := range pms {
+ measurement.PmData.Object.RmUIDAttr = pm.RmUID
+ measurement.PmData.Object.DnAttr = pm.Dn
+ measurement.PmData.Object.UserLabelAttr = pm.NeName
+ for _, pdata := range pm.Datas {
+ measurement := pmschema.Measurements{ObjectType: pdata.ObjectType}
+ if pdata.ObjectType == obj {
+ i := 1
+ for _, pmName := range keys {
+ measurement.PmName.N = append(measurement.PmName.N, pmschema.N{IAttr: i, Value: pmName})
+ measurement.PmData.Object.V = append(measurement.PmData.Object.V, pmschema.V{IAttr: i, Value: "1"})
+ i++
+ //measurement.PmData.Object.V = append(measurement.PmData.Object.V, pmschema.V{IAttr: i, Value: sortValues[pmName].Value})
+ //measurement.PmData.Object.CV = sortValues[pmName].Value
+ }
+ }
+ }
+ }
+ pmFile.Measurements = append(pmFile.Measurements, measurement)
+ }
+ */
+
+ /*
+ for k, pm := range pms {
+ measurement := pmschema.Measurements{ObjectType: "gold_kpi"}
+
+ for s, ne := range nes {
+ rmUID := fmt.Sprintf("01000HX%sBJ0D0%d", neType, s+1)
+ vmId := fmt.Sprintf("kylin10.0-00%d-%s", s+1, neType)
+ measurement.PmName.
+ vnfInstanceID := fmt.Sprintf("2%xd55b4-%d018-41f4-af%d5-28b%d828788", s+10, s+6, s+4, s+3)
+ object := pmschema.Object{RmUIDAttr: rmUID,
+ DnAttr: "DC=www.ruijie.com.cn,SubNetwork=10001,SubNetwork=114214,ManagedElement=325",
+ UserLabelAttr: ne.NeName, PVFlagAttr: ne.PvFlag, VMIDAttr: vmId, VNFInstanceIDAttr: vnfInstanceID}
+
+ i := 1
+ for _, p := range keys {
+ if s == 0 {
+ objects.FieldName.N = append(objects.FieldName.N, pmschema.N{IAttr: i, Value: p})
+ }
+ var v string
+ switch p {
+ case "Id":
+ v = ne.NeId
+ case "UserLabel":
+ v = ne.NeName
+ case "VendorName":
+ v = "Ruijie Network"
+ case "SwVersion":
+ v = global.Version
+ case "PatchInfo":
+ v = "-"
+ case "AdministrativeState":
+ v = AdminStateUnlocked
+ case "OperationalState":
+ v = OperationStateEnabled
+ case "VnfInstanceId":
+ v = vnfInstanceID
+ default:
+ if sortResult[p] == "" {
+ v = "-"
+ } else {
+ v = fmt.Sprintf("%s", sortResult[p])
+ }
+ }
+ object.V = append(object.V, cmschema.V{IAttr: i, Value: v})
+ i++
+ }
+ objects.FieldValue.Object = append(objects.FieldValue.Object, object)
+ }
+ pmFile.Measurements = append(pmFile.Measurements, measurement)
+ }
+ */
+
+ x, _ := xml.MarshalIndent(pmFile, "", " ")
+ x = append([]byte(xml.Header), x...)
+
+ folderName := global.GetFmtTimeString(global.DateTime, startTime, global.DateHour)
+ folderPath := global.CreateDir(folderName, yamlConfig.NBI.PM.XmlFileDir)
+ timefile := global.GetFmtTimeString(global.DateTime, startTime, global.DateData)
+ xmlfile := fmt.Sprintf("%s/PM-%s-%s-%s-15-001.xml", folderPath, neType, global.Version, timefile)
+ log.Debugf("folderPath:%s, xmlfile:%s", folderPath, xmlfile)
+ err = os.WriteFile(xmlfile, x, 0664)
+ if err != nil {
+ log.Error("Failed to write xml file:", err)
+
+ return err
+ }
+ return nil
+}
diff --git a/crontask/makefile b/crontask/makefile
new file mode 100644
index 00000000..8dbb97ab
--- /dev/null
+++ b/crontask/makefile
@@ -0,0 +1,18 @@
+# Makefile for OMC-OMC-crontask project
+
+PROJECT = OMC
+VERSION = 16.1.1
+LIBDIR = ems.agt/lib
+BINNAME = crontask
+
+.PHONY: build $(BINNAME)
+build $(BINNAME):
+ go build -o $(BINNAME) -v -ldflags "-X '$(LIBDIR)/global.Version=$(VERSION)' \
+ -X '$(LIBDIR)/global.BuildTime=`date`' \
+ -X '$(LIBDIR)/global.GoVer=`go version`'"
+
+run: $(BINNAME)
+ ./$(BINNAME)
+
+clean:
+ rm ./$(BINNAME)
diff --git a/crontask/pm/schema/pm-schema.go b/crontask/pm/schema/pm-schema.go
new file mode 100644
index 00000000..ba259097
--- /dev/null
+++ b/crontask/pm/schema/pm-schema.go
@@ -0,0 +1,77 @@
+// Code generated by xgen. DO NOT EDIT.
+
+package pmschema
+
+import "encoding/xml"
+
+// FileHeader ...
+type FileHeader struct {
+ TimeStamp string `xml:"TimeStamp"`
+ TimeZone string `xml:"TimeZone"`
+ Period int `xml:"Period"`
+ VendorName string `xml:"VendorName"`
+ ElementType string `xml:"ElementType"`
+ PmVersion string `xml:"PmVersion"`
+ StartTime string `xml:"StartTime"`
+}
+
+// N ...
+type N struct {
+ IAttr int `xml:"i,attr"`
+ Value string `xml:",chardata"`
+}
+
+// PmName ...
+type PmName struct {
+ N []N `xml:"N"`
+}
+
+// V ...
+type V struct {
+ IAttr int `xml:"i,attr"`
+ Value string `xml:",chardata"`
+}
+
+// NV ...
+type NV struct {
+ XMLName xml.Name `xml:"-"`
+ SN string `xml:"SN"`
+ SV string `xml:"SV"`
+}
+
+// CV ...
+type CV struct {
+ IAttr int `xml:"i,attr"`
+ // NV []NV `xml:"NV"`
+ SN []string `xml:"SN"`
+ SV []string `xml:"SV"`
+}
+
+// Object ...
+type Object struct {
+ RmUIDAttr string `xml:"rmUID,attr"`
+ DnAttr string `xml:"Dn,attr"`
+ UserLabelAttr string `xml:"UserLabel,attr"`
+ V []V `xml:"V"`
+ CV []CV `xml:"CV"`
+}
+
+// PmData ...
+type PmData struct {
+ Object Object `xml:"Object"`
+}
+
+// Measurements ...
+type Measurements struct {
+ ObjectType string `xml:"ObjectType"`
+ PmName PmName `xml:"PmName"`
+ PmData PmData `xml:"PmData"`
+}
+
+// PmFile ...
+type PmFile struct {
+ FileHeader FileHeader `xml:"FileHeader"`
+ Measurements []Measurements `xml:"Measurements"`
+ XsAttr string `xml:"xmlns:xs,attr"`
+ XsiAttr string `xml:"xmlns:xsi,attr"`
+}
diff --git a/crontask/pm/schema/pm-schema.go.bak b/crontask/pm/schema/pm-schema.go.bak
new file mode 100644
index 00000000..07987591
--- /dev/null
+++ b/crontask/pm/schema/pm-schema.go.bak
@@ -0,0 +1,65 @@
+// Code generated by xgen. DO NOT EDIT.
+
+package pmschema
+
+// FileHeader ...
+type FileHeader struct {
+ TimeStamp string `xml:"TimeStamp"`
+ TimeZone string `xml:"TimeZone"`
+ Period int `xml:"Period"`
+ VendorName string `xml:"VendorName"`
+ ElementType string `xml:"ElementType"`
+ PmVersion string `xml:"PmVersion"`
+ StartTime string `xml:"StartTime"`
+}
+
+// N ...
+type N struct {
+ IAttr int `xml:"i,attr"`
+ Value string `xml:",chardata"`
+}
+
+// PmName ...
+type PmName struct {
+ N *N `xml:"N"`
+}
+
+// V ...
+type V struct {
+ IAttr int `xml:"i,attr"`
+ Value string `xml:",chardata"`
+}
+
+// CV ...
+type CV struct {
+ IAttr int `xml:"i,attr"`
+ SN []string `xml:"SN"`
+ SV []string `xml:"SV"`
+}
+
+// Object ...
+type Object struct {
+ RmUIDAttr string `xml:"rmUID,attr"`
+ DnAttr string `xml:"Dn,attr"`
+ UserLabelAttr string `xml:"UserLabel,attr"`
+ V []*V `xml:"V"`
+ CV []*CV `xml:"CV"`
+}
+
+// PmData ...
+type PmData struct {
+ Object *Object `xml:"Object"`
+}
+
+// Measurements ...
+type Measurements struct {
+ ObjectType string `xml:"ObjectType"`
+ PmName *PmName `xml:"PmName"`
+ PmData *PmData `xml:"PmData"`
+}
+
+// PmFile ...
+type PmFile struct {
+ FileHeader FileHeader `xml:"FileHeader"`
+ Measurements []*Measurements `xml:"Measurements"`
+}
diff --git a/crontask/tasks.go b/crontask/tasks.go
new file mode 100644
index 00000000..b0ffaa81
--- /dev/null
+++ b/crontask/tasks.go
@@ -0,0 +1,1389 @@
+package main
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "mime/multipart"
+ "net/http"
+ "os"
+ "reflect"
+ "strings"
+ "time"
+
+ "ems.agt/lib/dborm"
+ "ems.agt/lib/global"
+ "ems.agt/lib/log"
+
+ "github.com/go-resty/resty/v2"
+ "github.com/shirou/gopsutil/process"
+
+ // cron "github.com/go-co-op/gocron"
+ "github.com/jasonlvhit/gocron"
+ "github.com/robfig/cron/v3"
+)
+
+type TaskFunc struct {
+}
+
+var Alarms []Alarm
+
+func initCronTasks() {
+ taskFuncs := TaskFunc{}
+
+ vf := reflect.ValueOf(&taskFuncs)
+
+ for _, t := range taskSet.Tasks {
+ log.Trace("Task:", t)
+
+ if strings.ToLower(t.Status) == TaskStatusInactive {
+ continue
+ }
+
+ //Call function by function name
+ taskFunc := vf.MethodByName(t.Do).Interface()
+ switch t.Unit {
+ case "Seconds":
+ gocron.Every(t.Interval).Seconds().DoSafely(taskFunc, t.Uri, t.Params, t.Body)
+ case "Minutes":
+ gocron.Every(t.Interval).Minutes().DoSafely(taskFunc, t.Uri, t.Params, t.Body)
+ case "Hour":
+ if t.At == "" {
+ gocron.Every(t.Interval).Hour().DoSafely(taskFunc, t.Uri, t.Params, t.Body)
+ } else {
+ ats := strings.Split(t.At, ",")
+ for _, at := range ats {
+ gocron.Every(t.Interval).Day().At(at).DoSafely(taskFunc, t.Uri, t.Params, t.Body)
+ }
+ }
+ case "Hours":
+ gocron.Every(t.Interval).Hours().DoSafely(taskFunc, t.Uri, t.Params, t.Body)
+ case "Days":
+ if t.At == "" {
+ gocron.Every(t.Interval).Days().DoSafely(taskFunc, t.Uri, t.Params, t.Body)
+ } else {
+ ats := strings.Split(t.At, ",")
+ for _, at := range ats {
+ gocron.Every(t.Interval).Days().At(at).DoSafely(taskFunc, t.Uri, t.Params, t.Body)
+ }
+ }
+ case "Day":
+ if t.At == "" {
+ gocron.Every(t.Interval).Day().DoSafely(taskFunc, t.Uri, t.Params, t.Body)
+ } else {
+ ats := strings.Split(t.At, ",")
+ for _, at := range ats {
+ gocron.Every(t.Interval).Day().At(at).DoSafely(taskFunc, t.Uri, t.Params, t.Body)
+ }
+ }
+ case "Weeks":
+ if t.At == "" {
+ gocron.Every(t.Interval).Weeks().DoSafely(taskFunc, t.Uri, t.Params, t.Body)
+ } else {
+ gocron.Every(t.Interval).Weeks().At(t.At).DoSafely(taskFunc, t.Uri, t.Params, t.Body)
+ }
+ case "Monday":
+ if t.At == "" {
+ gocron.Every(t.Interval).Monday().DoSafely(taskFunc, t.Uri, t.Params, t.Body)
+ } else {
+ gocron.Every(t.Interval).Monday().At(t.At).DoSafely(taskFunc, t.Uri, t.Params, t.Body)
+ }
+ case "Tuesday":
+ if t.At == "" {
+ gocron.Every(t.Interval).Tuesday().DoSafely(taskFunc, t.Uri, t.Params, t.Body)
+ } else {
+ gocron.Every(t.Interval).Tuesday().At(t.At).DoSafely(taskFunc, t.Uri, t.Params, t.Body)
+ }
+ case "Wednesday":
+ if t.At == "" {
+ gocron.Every(t.Interval).Wednesday().DoSafely(taskFunc, t.Uri, t.Params, t.Body)
+ } else {
+ gocron.Every(t.Interval).Wednesday().At(t.At).DoSafely(taskFunc, t.Uri, t.Params, t.Body)
+ }
+ case "Thursday":
+ if t.At == "" {
+ gocron.Every(t.Interval).Thursday().DoSafely(taskFunc, t.Uri, t.Params, t.Body)
+ } else {
+ gocron.Every(t.Interval).Thursday().At(t.At).DoSafely(taskFunc, t.Uri, t.Params, t.Body)
+ }
+ case "Friday":
+ if t.At == "" {
+ gocron.Every(t.Interval).Friday().DoSafely(taskFunc, t.Uri, t.Params, t.Body)
+ } else {
+ gocron.Every(t.Interval).Friday().At(t.At).DoSafely(taskFunc, t.Uri, t.Params, t.Body)
+ }
+ case "Saturday":
+ if t.At == "" {
+ gocron.Every(t.Interval).Saturday().DoSafely(taskFunc, t.Uri, t.Params, t.Body)
+ } else {
+ gocron.Every(t.Interval).Saturday().At(t.At).DoSafely(taskFunc, t.Uri, t.Params, t.Body)
+ }
+ case "Sunday":
+ if t.At == "" {
+ gocron.Every(t.Interval).Sunday().DoSafely(taskFunc, t.Uri, t.Params, t.Body)
+ } else {
+ gocron.Every(t.Interval).Sunday().At(t.At).DoSafely(taskFunc, t.Uri, t.Params, t.Body)
+ }
+ default:
+ log.Error("Error config:", t)
+ }
+ }
+
+ // remove, clear and next_rull
+ _, time := gocron.NextRun()
+ log.Info(time)
+
+ <-gocron.Start()
+}
+
+func initCronTabs() {
+ taskFuncs := TaskFunc{}
+
+ vf := reflect.ValueOf(&taskFuncs)
+ job := cron.New(
+ // cron.WithSeconds(), // 添加秒级别支持,默认支持最小粒度为分钟
+ )
+
+ for _, c := range taskSet.Crontabs {
+ log.Debug(c.Name)
+ if c.Status == TaskStatusInactive {
+ continue
+ }
+ taskFunc := vf.MethodByName(c.Do).Interface()
+ if taskFunc != nil {
+ job.AddJob(c.Tab, TaskJob{taskFunc, c.Uri, c.Params, c.Body, &taskFuncs})
+ }
+ }
+
+ job.Start()
+}
+
+type TaskJob struct {
+ Do interface{}
+ Uri string
+ Params string
+ Body string
+ T *TaskFunc
+}
+
+func (j TaskJob) Run() {
+ log.Tracef("Uri:%s, Params:%s Body:%s", j.Uri, j.Params, j.Body)
+ err := j.T.CallTaskFunc(j.Do, j.Uri, j.Params, j.Body)
+ if err != nil {
+ log.Error("call func error:", err)
+ }
+}
+
+func (t *TaskFunc) CallTaskFunc(jobFunc interface{}, params ...interface{}) error {
+ f := reflect.ValueOf(jobFunc)
+ if len(params) != f.Type().NumIn() {
+ err := global.ErrParamsNotAdapted
+ log.Fatal(err)
+ return err
+ }
+ in := make([]reflect.Value, len(params))
+ for k, param := range params {
+ in[k] = reflect.ValueOf(param)
+ }
+ f.Call(in)
+ return nil
+}
+
+func (t *TaskFunc) TaskHelloWorld(uri, params, body string) {
+ log.Infof("Hello, world! uri:%s, params:%s Date: %s", uri, params, time.Now().Format("2006-01-02"))
+}
+
+func (t *TaskFunc) TaskWithParams(a int, b string) {
+ log.Trace(a, b)
+}
+
+func (t *TaskFunc) TaskDeleteExpiredRecord(uri, params, body string) {
+ log.Debug("TaskDeleteExpiredRecord processing... ")
+
+ var response *resty.Response
+ requestURI := fmt.Sprintf("%s?%s", uri, params)
+ requestURL := fmt.Sprintf("%s%s", yamlConfig.OMC.HostUri, requestURI)
+ log.Debug("requestURL: DELETE ", requestURL)
+ client := resty.New()
+ response, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ Delete(requestURL)
+ if err != nil {
+ log.Error("Failed to delete:", err)
+ }
+
+ log.Debug("StatusCode: ", response.StatusCode())
+ switch response.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ log.Debug("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ default:
+ log.Debug("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ }
+}
+
+func (t *TaskFunc) TaskUpdateTable(uri, params, body string) {
+ log.Debug("TaskUpdateTable processing... ")
+
+ var response *resty.Response
+ requestURI := fmt.Sprintf("%s?%s", uri, params)
+ requestURL := fmt.Sprintf("%s%s", yamlConfig.OMC.HostUri, requestURI)
+ // reqBody, err := json.Marshal(body)
+ // if err != nil {
+ // log.Error("Failed to Marshal:", err)
+ // }
+ log.Debug("requestURL: Put ", requestURL)
+ log.Trace("body:", body)
+ client := resty.New()
+ response, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ SetBody(body).
+ Put(requestURL)
+ if err != nil {
+ log.Error("Failed to put:", err)
+ }
+
+ log.Debug("StatusCode: ", response.StatusCode())
+ switch response.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ log.Debug("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ default:
+ log.Debug("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ }
+}
+
+func (t *TaskFunc) GetTableNameFromUri(uri string) string {
+ sa := global.SplitString(uri, "/")
+ n := len(sa)
+ if n > 0 {
+ return sa[n-1]
+ }
+ return ""
+}
+
+func (t *TaskFunc) TaskDBBackupCSVGetBySQL(uri, params, body string) {
+ log.Debug("TaskDBBackupCSVGetBySQL processing... ")
+
+ var response *resty.Response
+ tableName := t.GetTableNameFromUri(uri)
+ filePath := fmt.Sprintf("%s/%s-%s.csv", GetYamlConfig().Database.Backup, tableName, time.Now().Local().Format(global.DateData))
+ pa := fmt.Sprintf(params, filePath)
+ requestURI := fmt.Sprintf("%s?%s", uri, pa)
+ requestURL := fmt.Sprintf("%s%s", yamlConfig.OMC.HostUri, requestURI)
+ log.Debug("requestURL: Get ", requestURL)
+ client := resty.New()
+ response, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ Get(requestURL)
+ if err != nil {
+ log.Error("Failed to Get:", err)
+ }
+
+ log.Debug("StatusCode: ", response.StatusCode())
+ switch response.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ log.Debug("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ default:
+ log.Error("response body:", string(response.Body()))
+ }
+}
+
+type CpuUsage struct {
+ NfCpuUsage uint16 `json:"nfCpuUsage"`
+ SysCpuUsage uint16 `json:"sysCpuUsage"`
+}
+
+type MemUsage struct {
+ TotalMem uint32 `json:"totalMem"`
+ NfUsedMem uint32 `json:"nfUsedMem"`
+ SysMemUsage uint16 `json:"sysMemUsage"`
+}
+
+type PartitionInfo struct {
+ Total uint32 `json:"total"` // MB
+ Used uint32 `json:"used"` // MB
+}
+
+type DiskSpace struct {
+ PartitionNum uint8 `json:"partitionNum"`
+
+ PartitionInfo []PartitionInfo `json:"partitionInfo"`
+}
+
+type SystemState struct {
+ Version string `json:"version"`
+ Capability uint32 `json:"capability"`
+ SerialNum string `json:"serialNum"`
+ ExpiryDate string `json:"expiryDate"`
+ //Timestamp string `json:"timestamp"`
+
+ CpuUsage CpuUsage `json:"cpuUsage"`
+ MemUsage MemUsage `json:"memUsage"`
+
+ DiskSpace DiskSpace `json:"diskSpace"`
+}
+
+func (t *TaskFunc) TaskHandShakeToNF(uri, params, body string) {
+ log.Debug("TaskHandShakeToNF processing... ")
+
+ var nes []NeInfo
+ _, err := XormGetAllNeInfo(&nes)
+ if err != nil {
+ log.Error("Failed to get all ne info:", err)
+ }
+
+ for _, ne := range nes {
+ requestURI := fmt.Sprintf(uri, strings.ToLower(ne.NeType))
+ if params != "" {
+ requestURI = fmt.Sprintf("%s?%s", requestURI, params)
+ }
+ requestURL := fmt.Sprintf("http://%s:%s%s", ne.Ip, ne.Port, requestURI)
+ log.Debug("requestURL: Get", requestURL)
+ client := resty.New()
+ response, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ Get(requestURL)
+ if err != nil {
+ log.Error("Failed to Get:", err)
+ }
+
+ log.Debug("StatusCode: ", response.StatusCode())
+ switch response.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ log.Debug("response body:", string(response.Body()))
+ state := new(SystemState)
+ _ = json.Unmarshal(response.Body(), &state)
+ neState := new(NeState)
+ neState.NeType = ne.NeType
+ neState.NeId = ne.NeId
+ neState.Version = state.Version
+ neState.Capability = state.Capability
+ neState.SerialNum = state.SerialNum
+ neState.ExpiryDate = state.ExpiryDate
+ cu, _ := json.Marshal(state.CpuUsage)
+ neState.CpuUsage = string(cu)
+ mu, _ := json.Marshal(state.MemUsage)
+ neState.MemUsage = string(mu)
+ ds, _ := json.Marshal(state.DiskSpace)
+ neState.DiskSpace = string(ds)
+ log.Debug("neState:", neState)
+ _, err := XormInsertNeState(neState)
+ if err != nil {
+ log.Error("Failed to insert ne_state:", err)
+ }
+ default:
+ log.Debug("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ }
+ }
+}
+
+func (t *TaskFunc) TaskExportCmFromNF(uri, params, body string) {
+ log.Debug("TaskExportCmFromNF processing... ")
+
+ var nes []NeInfo
+ _, err := XormGetAllNeInfo(&nes)
+ if err != nil {
+ log.Error("Failed to get all ne info:", err)
+ }
+
+ for _, ne := range nes {
+ requestURI := fmt.Sprintf(uri, strings.ToLower(ne.NeType))
+ if params != "" {
+ paramsUri := fmt.Sprintf(params, ne.NeId)
+ requestURI = fmt.Sprintf("%s?%s", requestURI, paramsUri)
+ }
+ requestURL := fmt.Sprintf("%s%s", yamlConfig.OMC.HostUri, requestURI)
+ log.Debug("requestURL: Get", requestURL)
+ client := resty.New()
+ response, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ // SetOutput("./export/test.zip").
+ Get(requestURL)
+ if err != nil {
+ log.Error("Failed to Get:", err)
+ }
+
+ log.Debug("StatusCode: ", response.StatusCode())
+ switch response.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ log.Debug("Export NF cm sucessfully")
+ //defer response.Body.Close()
+ //fileName := "./export/" + response.Header().Get("User-File")
+ //os.Rename("./export/test.zip", fileName)
+ default:
+ log.Error("Failed to export NF cm")
+ }
+ }
+}
+
+func (t *TaskFunc) TaskImportCmToNF(uri, params, body string) {
+ log.Debug("TaskImportCmToNF processing... ")
+
+ file, err := os.OpenFile("udm-sz_01-etc-20230612001524.zip", os.O_RDONLY, os.ModePerm)
+ if err != nil {
+ log.Error("Failed to OpenFile:", err)
+ return
+ }
+ byteBody := &bytes.Buffer{}
+ //body = new(bytes.Buffer)
+ writer := multipart.NewWriter(byteBody)
+
+ part, err := writer.CreateFormFile("file", "./temp/"+file.Name())
+ if err != nil {
+ log.Error("Failed to CreateFormFile:", err)
+ return
+ }
+
+ _, err = io.Copy(part, file) //
+ if err != nil {
+ log.Error("Failed to Copy:", err)
+ return
+ }
+
+ writer.Close()
+
+ requestURI := fmt.Sprintf("%s?%s", uri, params)
+ requestURL := fmt.Sprintf("%s%s", yamlConfig.OMC.HostUri, requestURI)
+ client := resty.New()
+ response, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": writer.FormDataContentType()}).
+ SetBody(body).
+ Post(requestURL)
+ if err != nil {
+ log.Error("Failed to Post:", err)
+ return
+ }
+ switch response.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ log.Debug("Import NF cm sucessfully")
+ default:
+ log.Error("response code:", response.StatusCode())
+ }
+ return
+}
+
+func (t *TaskFunc) TaskGenMeasureThresholdAlarm(uri, params, body string) {
+ log.Info("TaskGenMeasureThresholdAlarm processing...")
+
+ // get measurethreshold table
+ var measureThresholds []MeasureThreshold
+
+ _, err := XormGetMeasureThreshold("measure_threshold", "status='Active'", &measureThresholds)
+ if err != nil {
+ log.Error("Failed to get measure_threshold:", err)
+ return
+ }
+
+ for _, m := range measureThresholds {
+ measureData, err := XormGetMeasureDataOneByKpi(m.KpiSet)
+ if err != nil {
+ log.Error("Failed to get measure_data:", err)
+ continue
+ }
+ log.Debug("measureData:", measureData)
+
+ alarmDefine, err := XormGetAlarmDefine(m.AlarmId)
+ if err != nil {
+ log.Error("Failed to get alarm_define:", err)
+ continue
+ } else if alarmDefine == nil {
+ log.Error("Not found data from alarm_define")
+ continue
+ }
+
+ log.Debug("alarmDefine:", alarmDefine)
+
+ // sql := fmt.Sprintf("select * from alarm where alarm_id = '%s' and ne_type='%s' and ne_id = '%s' order by event_time desc limit 1",
+ // m.AlarmId, m.NeType, measureData.RmUid)
+ // alarm, err := XormGetDataBySQL(sql)
+ // if err != nil {
+ // log.Error("Failed to get alarm:", err)
+ // continue
+ // }
+ // log.Debug("alarm:", *alarm)
+
+ // kpi pm non-exceed, check if exist alarm
+ if measureData.Value <= m.Threshold && m.AlarmFlag == true {
+ // if len(*alarm) == 0 || (*alarm)[0]["alarm_status"] == AlarmStatusClearString {
+ // continue
+ // }
+
+ // clear alarm, todo
+ var alarmSeq int = 1
+ // insert alarm
+ var pvFlag string
+ sql := fmt.Sprintf("select * from ne_info where ne_type='%s' and rm_uid='%s' limit 1",
+ m.NeType, measureData.RmUid)
+ neInfo, err := XormGetDataBySQL(sql)
+ if err != nil {
+ log.Error("Failed to get ne_info:", err)
+ continue
+ }
+ log.Debug("neInfo:", neInfo)
+ if len(*neInfo) > 0 {
+ pvFlag = (*neInfo)[0]["pv_flag"]
+ }
+ if pvFlag == "" {
+ pvFlag = "VNF"
+ }
+ locationInfo := fmt.Sprintf("PM.%s: value=%v, threshold=%v", m.KpiSet, measureData.Value, m.Threshold)
+ alarmData := &Alarm{
+ AlarmSeq: alarmSeq,
+ AlarmId: m.AlarmId,
+ NeId: measureData.RmUid,
+ NeType: m.NeType,
+ NeName: measureData.NeName,
+ Province: GetYamlConfig().OMC.Province,
+ PVFlag: pvFlag,
+ AlarmCode: alarmDefine.AlarmCode,
+ AlarmTitle: alarmDefine.AlarmTitle,
+ AlarmType: alarmDefine.AlarmType,
+ AlarmStatus: AlarmStatusClear,
+ OrigSeverity: m.OrigSeverity,
+ ObjectUid: alarmDefine.ObjectUid,
+ ObjectName: alarmDefine.ObjectName,
+ ObjectType: alarmDefine.ObjectType,
+ LocationInfo: locationInfo,
+ SpecificProblem: alarmDefine.SpecificProblem,
+ SpecificProblemID: alarmDefine.SpecificProblemId,
+ AddInfo: alarmDefine.AddInfo,
+ EventTime: time.Now().Local().Format(time.RFC3339),
+ }
+
+ alarmArray := &[]Alarm{*alarmData}
+ body, _ := json.Marshal(alarmArray)
+ log.Debug("body: ", string(body))
+
+ var response *resty.Response
+ requestURI := fmt.Sprintf(uri, m.NeType)
+ requestURL := fmt.Sprintf("%s%s", yamlConfig.OMC.HostUri, requestURI)
+ log.Debug("requestURL: POST ", requestURL)
+ client := resty.New()
+ response, err = client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ SetBody(body).
+ Post(requestURL)
+ if err != nil {
+ log.Error("Failed to post:", err)
+ }
+
+ log.Debug("StatusCode: ", response.StatusCode())
+ switch response.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ log.Debug("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ // todo ... update measure_threshold set alarm_flag=false
+ m.AlarmFlag = false
+ _, err := XormUpdateTableById(m.Id, "measure_threshold", m, "alarm_flag")
+ if err != nil {
+ log.Error("Failed to update measure_threshold:", err)
+ continue
+ }
+ default:
+ log.Debug("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ }
+ } else if measureData.Value > m.Threshold && m.AlarmFlag == false {
+ var alarmSeq int = 1
+ // insert alarm
+ var pvFlag string
+ sql := fmt.Sprintf("select * from ne_info where ne_type='%s' and rm_uid='%s' limit 1", m.NeType, measureData.RmUid)
+ neInfo, err := XormGetDataBySQL(sql)
+ if err != nil {
+ log.Error("Failed to get ne_info:", err)
+ continue
+ }
+ log.Debug("neInfo:", neInfo)
+ if len(*neInfo) > 0 {
+ pvFlag = (*neInfo)[0]["pv_flag"]
+ }
+ if pvFlag == "" {
+ pvFlag = "VNF"
+ }
+ locationInfo := fmt.Sprintf("PM.%s: value=%v,threshold=%v", m.KpiSet, measureData.Value, m.Threshold)
+ alarmData := &Alarm{
+ AlarmSeq: alarmSeq,
+ AlarmId: m.AlarmId,
+ NeId: measureData.RmUid,
+ NeType: m.NeType,
+ NeName: measureData.NeName,
+ Province: GetYamlConfig().OMC.Province,
+ PVFlag: pvFlag,
+ AlarmCode: alarmDefine.AlarmCode,
+ AlarmTitle: alarmDefine.AlarmTitle,
+ AlarmType: alarmDefine.AlarmType,
+ AlarmStatus: AlarmStatusActive,
+ OrigSeverity: m.OrigSeverity,
+ ObjectUid: alarmDefine.ObjectUid,
+ ObjectName: alarmDefine.ObjectName,
+ ObjectType: alarmDefine.ObjectType,
+ LocationInfo: locationInfo,
+ SpecificProblem: alarmDefine.SpecificProblem,
+ SpecificProblemID: alarmDefine.SpecificProblemId,
+ AddInfo: alarmDefine.AddInfo,
+ EventTime: time.Now().Local().Format(time.RFC3339),
+ }
+
+ alarmArray := &[]Alarm{*alarmData}
+ body, _ := json.Marshal(alarmArray)
+ log.Debug("body: ", string(body))
+
+ var response *resty.Response
+ requestURI := fmt.Sprintf(uri, m.NeType)
+ requestURL := fmt.Sprintf("%s%s", yamlConfig.OMC.HostUri, requestURI)
+ log.Debug("requestURL: POST ", requestURL)
+ client := resty.New()
+ response, err = client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ SetBody(body).
+ Post(requestURL)
+ if err != nil {
+ log.Error("Failed to post:", err)
+ }
+
+ log.Debug("StatusCode: ", response.StatusCode())
+ switch response.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ log.Debug("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ // todo ... update measure_threshold set alarm_flag=true
+ m.AlarmFlag = true
+ _, err := XormUpdateTableById(m.Id, "measure_threshold", m, "alarm_flag")
+ if err != nil {
+ log.Error("Failed to update measure_threshold:", err)
+ continue
+ }
+
+ default:
+ log.Debug("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ }
+ }
+ }
+}
+
+func (t *TaskFunc) TaskGenMeasureReportTimeoutAlarm(uri, params, body string) {
+ log.Info("TaskGenMeasureReportTimeoutAlarm processing...")
+
+ var measureTasks []dborm.MeasureTask
+ _, err := dborm.XormGetActiveMeasureTask(&measureTasks)
+ if err != nil {
+ log.Error("Failed to GetActiveMeasureTask: ", err)
+ return
+ }
+ log.Trace("measureTasks:", measureTasks)
+
+ for _, measureTask := range measureTasks {
+ if len(measureTask.NeIds) == 0 {
+ var neInfos []dborm.NeInfo
+ err := dborm.XormGetNeInfoByNeType(measureTask.NeType, &neInfos)
+ if err != nil {
+ log.Error("Failed to dborm.XormGetNeInfoByNeType:", err)
+ continue
+ }
+ for _, neInfo := range neInfos {
+ measureTask.NeIds = append(measureTask.NeIds, neInfo.NeId)
+ }
+ }
+ log.Debug("measureTask.NeIds:", measureTask.NeIds)
+ for _, neId := range measureTask.NeIds {
+ var err error
+ neInfo, err := dborm.XormGetNeInfo(measureTask.NeType, neId)
+ if err != nil {
+ log.Error("Failed to dborm.XormGetNeInfo:", err)
+ continue
+ }
+ if neInfo == nil {
+ err := errors.New(fmt.Sprintf("not found target NE neType=%s, neId=%s", measureTask.NeType, neId))
+ log.Error(err)
+ continue
+ }
+
+ measureData, err := XormGetMeasureDataLastOne(measureTask.NeType, neInfo.RmUID, measureTask.Id)
+ if err != nil {
+ log.Error("Failed to get measure_data:", err)
+ continue
+ }
+ log.Debug("measureData:", measureData)
+
+ var alarmId string = "RJHXEMSPM10201"
+ if params != "" {
+ alarmId = params
+ }
+ alarmDefine, err := XormGetAlarmDefine(alarmId)
+ if err != nil {
+ log.Error("Failed to get alarm_define:", err)
+ continue
+ } else if alarmDefine == nil {
+ log.Error("Not found data from alarm_define")
+ continue
+ }
+ log.Debug("alarmDefine:", alarmDefine)
+ log.Debugf("measureData.StartTime:%s measureTask.StartTime:%s measureTask.CreateTime:%s", measureData.StartTime, measureTask.StartTime, measureTask.CreateTime)
+ var startTime string
+ if measureData.StartTime != "" {
+ startTime = measureData.StartTime
+ layout := "2006-01-02 15:04:05 -0700 MST"
+ startTime = global.GetFmtTimeString(layout, startTime, time.DateTime)
+ } else if measureTask.StartTime != "" {
+ startTime = measureTask.StartTime
+ } else if measureTask.CreateTime != "" {
+ startTime = measureTask.CreateTime
+ layout := "2006-01-02 15:04:05 -0700 MST"
+ startTime = global.GetFmtTimeString(layout, startTime, time.DateTime)
+ }
+ log.Debugf("original startTime:%s", startTime)
+
+ seconds, err := global.GetSecondsSinceDatetime(startTime)
+ if err != nil {
+ log.Error("Failed to GetSecondsSinceDatetime:", err)
+ continue
+ }
+ log.Debugf("startTime:%s seconds:%d", startTime, seconds)
+ var isTimeout bool = false
+ var specificProblem string
+ switch measureTask.GranulOption {
+ case "15M":
+ if seconds > ((15 + 10) * 60) {
+ isTimeout = true
+ specificProblem = fmt.Sprintf(alarmDefine.SpecificProblem, 15, 10)
+ }
+
+ case "30M":
+ if seconds > ((30 + 15) * 60) {
+ isTimeout = true
+ specificProblem = fmt.Sprintf(alarmDefine.SpecificProblem, 30, 15)
+ }
+ case "60M":
+ if seconds > ((60 + 15) * 60) {
+ isTimeout = true
+ specificProblem = fmt.Sprintf(alarmDefine.SpecificProblem, 60, 15)
+ }
+ }
+ if isTimeout {
+ // if len(*alarm) == 0 || (*alarm)[0]["alarm_status"] == AlarmStatusClearString {
+ // continue
+ // }
+
+ // todo
+ var alarmSeq int = 1
+ locationInfo := fmt.Sprintf("PM.taskId=%d: neType=%s, neId=%s", measureTask.Id, neInfo.NeType, neInfo.NeId)
+
+ alarmData := &Alarm{
+ AlarmSeq: alarmSeq,
+ AlarmId: alarmId,
+ NeId: neInfo.RmUID,
+ NeType: measureTask.NeType,
+ NeName: neInfo.NeName,
+ Province: neInfo.Province,
+ PVFlag: neInfo.PvFlag,
+ AlarmCode: alarmDefine.AlarmCode,
+ AlarmTitle: alarmDefine.AlarmTitle,
+ AlarmType: alarmDefine.AlarmType,
+ AlarmStatus: AlarmStatusActive,
+ OrigSeverity: alarmDefine.OrigSeverity,
+ ObjectUid: alarmDefine.ObjectUid,
+ ObjectName: alarmDefine.ObjectName,
+ ObjectType: alarmDefine.ObjectType,
+ LocationInfo: locationInfo,
+ SpecificProblem: specificProblem,
+ SpecificProblemID: alarmDefine.SpecificProblemId,
+ AddInfo: alarmDefine.AddInfo,
+ EventTime: time.Now().Local().Format(time.RFC3339),
+ }
+
+ alarmArray := &[]Alarm{*alarmData}
+ body, _ := json.Marshal(alarmArray)
+ log.Debug("body: ", string(body))
+
+ var response *resty.Response
+ requestURI := fmt.Sprintf(uri, neInfo.NeType)
+ requestURL := fmt.Sprintf("%s%s", yamlConfig.OMC.HostUri, requestURI)
+ log.Debug("requestURL: POST ", requestURL)
+ client := resty.New()
+ response, err = client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ SetBody(body).
+ Post(requestURL)
+ if err != nil {
+ log.Error("Failed to post:", err)
+ }
+
+ log.Debug("StatusCode: ", response.StatusCode())
+ switch response.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ log.Debug("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ // todo ... update measure_threshold set alarm_flag=false
+ default:
+ log.Debug("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ }
+ } else {
+ var alarmSeq int = 1
+ locationInfo := fmt.Sprintf("PM.taskId=%d: neType=%s, neId=%s", measureTask.Id, neInfo.NeType, neInfo.NeId)
+ alarmData := &Alarm{
+ AlarmSeq: alarmSeq,
+ AlarmId: alarmId,
+ NeId: neInfo.RmUID,
+ NeType: measureTask.NeType,
+ NeName: neInfo.NeName,
+ Province: neInfo.Province,
+ PVFlag: neInfo.PvFlag,
+ AlarmCode: alarmDefine.AlarmCode,
+ AlarmTitle: alarmDefine.AlarmTitle,
+ AlarmType: alarmDefine.AlarmType,
+ AlarmStatus: AlarmStatusClear,
+ OrigSeverity: alarmDefine.OrigSeverity,
+ ObjectUid: alarmDefine.ObjectUid,
+ ObjectName: alarmDefine.ObjectName,
+ ObjectType: alarmDefine.ObjectType,
+ LocationInfo: locationInfo,
+ SpecificProblem: specificProblem,
+ SpecificProblemID: alarmDefine.SpecificProblemId,
+ AddInfo: alarmDefine.AddInfo,
+ EventTime: time.Now().Local().Format(time.RFC3339),
+ }
+
+ alarmArray := &[]Alarm{*alarmData}
+ body, _ := json.Marshal(alarmArray)
+ log.Debug("body: ", string(body))
+
+ var response *resty.Response
+ requestURI := fmt.Sprintf(uri, neInfo.NeType)
+ requestURL := fmt.Sprintf("%s%s", yamlConfig.OMC.HostUri, requestURI)
+ log.Debug("requestURL: POST ", requestURL)
+ client := resty.New()
+ response, err = client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ SetBody(body).
+ Post(requestURL)
+ if err != nil {
+ log.Error("Failed to post:", err)
+ }
+
+ log.Debug("StatusCode: ", response.StatusCode())
+ switch response.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ log.Debug("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ // todo ... update measure_threshold set alarm_flag=false
+ default:
+ log.Debug("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ }
+ }
+ }
+ }
+}
+
+func (t *TaskFunc) TaskGenLicenseAlarm(uri, params, body string) {
+ log.Info("TaskGenLicenseAlarm processing...")
+
+ var nes []NeInfo
+ _, err := XormGetAllNeInfo(&nes)
+ if err != nil {
+ log.Error("Failed to get all ne info:", err)
+ }
+
+ for _, ne := range nes {
+ log.Debug("ne:", ne)
+
+ sql := fmt.Sprintf("select * from ne_state where ne_type = '%s' and ne_id = '%s' order by timestamp desc limit 1", ne.NeType, ne.NeId)
+ neState, err := XormGetDataBySQL(sql)
+ if err != nil {
+ log.Error("Failed to get ne_state:", err)
+ continue
+ }
+ log.Debug("neState:", *neState)
+ if len(*neState) == 0 {
+ log.Errorf("Not found ne_state neType:%s, neId:%s", ne.NeType, ne.NeId)
+ continue
+ }
+
+ if params == "" {
+ params = "RJHXEMSCM10100"
+ }
+ alarmDefine, err := XormGetAlarmDefine(params)
+ if err != nil {
+ log.Error("Failed to get alarm_define:", err)
+ continue
+ } else if alarmDefine == nil {
+ log.Error("Not found data from alarm_define")
+ continue
+ }
+
+ log.Debug("alarmDefine:", alarmDefine)
+
+ sql = fmt.Sprintf("select * from alarm where alarm_id = '%s' and ne_type='%s' and ne_id = '%s' order by event_time desc limit 1",
+ alarmDefine.AlarmId, ne.NeType, ne.RmUID)
+ alarm, err := XormGetDataBySQL(sql)
+ if err != nil {
+ log.Error("Failed to get alarm:", err)
+ continue
+ }
+ log.Debug("alarm:", *alarm)
+
+ expiryDate := (*neState)[0]["expiry_date"]
+
+ days := global.GetDayDuration(expiryDate, time.Now().Format(time.DateOnly))
+ log.Debugf("expiryDate:%s days:%d", expiryDate, days)
+
+ // kpi pm non-exceed, check if exist alarm
+ if days > int64(alarmDefine.Threshold) {
+ if len(*alarm) == 0 || (*alarm)[0]["alarm_status"] == AlarmStatusClearString {
+ continue
+ }
+ // clear alarm, todo
+ var alarmSeq int = 1
+
+ SpecificProblem := fmt.Sprintf(alarmDefine.SpecificProblem, alarmDefine.Threshold)
+ locationInfo := fmt.Sprintf("CM.License: expiry date=%s,threshold=%v", expiryDate, alarmDefine.Threshold)
+ alarmData := &Alarm{
+ AlarmSeq: alarmSeq,
+ AlarmId: params,
+ NeId: ne.RmUID,
+ NeType: ne.NeType,
+ NeName: ne.NeName,
+ Province: ne.Province,
+ PVFlag: ne.PvFlag,
+ AlarmCode: alarmDefine.AlarmCode,
+ AlarmTitle: alarmDefine.AlarmTitle,
+ AlarmType: alarmDefine.AlarmType,
+ AlarmStatus: AlarmStatusClear,
+ OrigSeverity: alarmDefine.OrigSeverity,
+ ObjectUid: alarmDefine.ObjectUid,
+ ObjectName: alarmDefine.ObjectName,
+ ObjectType: alarmDefine.ObjectType,
+ LocationInfo: locationInfo,
+ SpecificProblem: SpecificProblem,
+ SpecificProblemID: alarmDefine.SpecificProblemId,
+ AddInfo: alarmDefine.AddInfo,
+ EventTime: time.Now().Local().Format(time.RFC3339),
+ }
+
+ alarmArray := &[]Alarm{*alarmData}
+ body, _ := json.Marshal(alarmArray)
+ log.Debug("body: ", string(body))
+
+ var response *resty.Response
+ requestURI := fmt.Sprintf(uri, ne.NeType)
+ requestURL := fmt.Sprintf("%s%s", yamlConfig.OMC.HostUri, requestURI)
+ log.Debug("requestURL: POST ", requestURL)
+ client := resty.New()
+ response, err = client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ SetBody(body).
+ Post(requestURL)
+ if err != nil {
+ log.Error("Failed to post:", err)
+ }
+
+ log.Debug("StatusCode: ", response.StatusCode())
+ switch response.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ log.Debug("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ default:
+ log.Debug("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ }
+ } else {
+ var alarmSeq int = 1
+ if len(*alarm) > 0 && (*alarm)[0]["alarm_status"] == AlarmStatusActiveString {
+ log.Info("License alarm has exist")
+ continue
+ }
+
+ SpecificProblem := fmt.Sprintf(alarmDefine.SpecificProblem, alarmDefine.Threshold)
+ locationInfo := fmt.Sprintf("CM.License: expiry date=%s,threshold=%v", expiryDate, alarmDefine.Threshold)
+ alarmData := &Alarm{
+ AlarmSeq: alarmSeq,
+ AlarmId: params,
+ NeId: ne.RmUID,
+ NeType: ne.NeType,
+ NeName: ne.NeName,
+ Province: ne.Province,
+ PVFlag: ne.PvFlag,
+ AlarmCode: alarmDefine.AlarmCode,
+ AlarmTitle: alarmDefine.AlarmTitle,
+ AlarmType: alarmDefine.AlarmType,
+ AlarmStatus: AlarmStatusActive,
+ OrigSeverity: alarmDefine.OrigSeverity,
+ ObjectUid: alarmDefine.ObjectUid,
+ ObjectName: alarmDefine.ObjectName,
+ ObjectType: alarmDefine.ObjectType,
+ LocationInfo: locationInfo,
+ SpecificProblem: SpecificProblem,
+ SpecificProblemID: alarmDefine.SpecificProblemId,
+ AddInfo: alarmDefine.AddInfo,
+ EventTime: time.Now().Local().Format(time.RFC3339),
+ }
+
+ alarmArray := &[]Alarm{*alarmData}
+ body, _ := json.Marshal(alarmArray)
+ log.Debug("body: ", string(body))
+
+ var response *resty.Response
+ requestURI := fmt.Sprintf(uri, ne.NeType)
+ requestURL := fmt.Sprintf("%s%s", yamlConfig.OMC.HostUri, requestURI)
+ log.Debug("requestURL: POST ", requestURL)
+ client := resty.New()
+ response, err = client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ SetBody(body).
+ Post(requestURL)
+ if err != nil {
+ log.Error("Failed to post:", err)
+ }
+
+ log.Debug("StatusCode: ", response.StatusCode())
+ switch response.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ log.Debug("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ default:
+ log.Debug("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ }
+ }
+ }
+}
+
+func (t *TaskFunc) TaskGenNeStateAlarm(uri, params, body string) {
+ log.Info("TaskGenNeStateAlarm processing...")
+
+ var nes []NeInfo
+ _, err := XormGetAllNeInfo(&nes)
+ if err != nil {
+ log.Error("Failed to get all ne info:", err)
+ }
+
+ for _, ne := range nes {
+ log.Debug("ne:", ne)
+
+ sql := fmt.Sprintf("select * from ne_state where ne_type = '%s' and ne_id = '%s' order by timestamp desc limit 1", ne.NeType, ne.NeId)
+ neState, err := XormGetDataBySQL(sql)
+ if err != nil {
+ log.Error("Failed to get ne_state:", err)
+ continue
+ }
+ log.Debug("neState:", *neState)
+
+ if params == "" {
+ params = "RJHXEMSSM10000"
+ }
+ alarmDefine, err := XormGetAlarmDefine(params)
+ if err != nil {
+ log.Error("Failed to get alarm_define:", err)
+ continue
+ } else if alarmDefine == nil {
+ log.Error("Not found data from alarm_define")
+ continue
+ }
+
+ log.Debug("alarmDefine:", alarmDefine)
+
+ sql = fmt.Sprintf("select * from alarm where alarm_id = '%s' and ne_type='%s' and ne_id = '%s' order by event_time desc limit 1",
+ alarmDefine.AlarmId, ne.NeType, ne.RmUID)
+ alarm, err := XormGetDataBySQL(sql)
+ if err != nil {
+ log.Error("Failed to get alarm:", err)
+ continue
+ }
+ log.Debug("alarm:", *alarm)
+
+ var timestamp string
+ if len(*neState) == 0 {
+ log.Infof("Not found ne_state neType:%s, neId:%s", ne.NeType, ne.NeId)
+ timestamp = ne.UpdateTime
+ } else {
+ timestamp = (*neState)[0]["timestamp"]
+ }
+
+ // 解析日期时间字符串为时间对象
+ seconds, err := global.GetSecondsSinceDatetime(timestamp)
+ if err != nil {
+ log.Error("Failed to GetSecondsSinceDatetime:", err)
+ continue
+ }
+ log.Debugf("timestamp:%s seconds:%d", timestamp, seconds)
+
+ if seconds <= alarmDefine.Threshold {
+ if len(*alarm) == 0 || (*alarm)[0]["alarm_status"] == AlarmStatusClearString {
+ continue
+ }
+
+ // clear alarm, todo
+ var alarmSeq int = 1
+ SpecificProblem := fmt.Sprintf(alarmDefine.SpecificProblem, alarmDefine.Threshold)
+ locationInfo := fmt.Sprintf("SystemManagement.State: NE heartbeat timestamp=%s,threshold=%v", timestamp, alarmDefine.Threshold)
+ alarmData := &Alarm{
+ AlarmSeq: alarmSeq,
+ AlarmId: params,
+ NeId: ne.RmUID,
+ NeType: ne.NeType,
+ NeName: ne.NeName,
+ Province: ne.Province,
+ PVFlag: ne.PvFlag,
+ AlarmCode: alarmDefine.AlarmCode,
+ AlarmTitle: alarmDefine.AlarmTitle,
+ AlarmType: alarmDefine.AlarmType,
+ AlarmStatus: AlarmStatusClear,
+ OrigSeverity: alarmDefine.OrigSeverity,
+ ObjectUid: alarmDefine.ObjectUid,
+ ObjectName: alarmDefine.ObjectName,
+ ObjectType: alarmDefine.ObjectType,
+ LocationInfo: locationInfo,
+ SpecificProblem: SpecificProblem,
+ SpecificProblemID: alarmDefine.SpecificProblemId,
+ AddInfo: alarmDefine.AddInfo,
+ EventTime: time.Now().Local().Format(time.RFC3339),
+ }
+
+ alarmArray := &[]Alarm{*alarmData}
+ body, _ := json.Marshal(alarmArray)
+ log.Debug("body: ", string(body))
+
+ var response *resty.Response
+ requestURI := fmt.Sprintf(uri, ne.NeType)
+ requestURL := fmt.Sprintf("%s%s", yamlConfig.OMC.HostUri, requestURI)
+ log.Debug("requestURL: POST ", requestURL)
+ client := resty.New()
+ response, err = client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ SetBody(body).
+ Post(requestURL)
+ if err != nil {
+ log.Error("Failed to post:", err)
+ }
+
+ log.Debug("StatusCode: ", response.StatusCode())
+ switch response.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ log.Debug("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ default:
+ log.Debug("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ }
+ } else {
+ var alarmSeq int = 1
+ if len(*alarm) > 0 && (*alarm)[0]["alarm_status"] == AlarmStatusActiveString {
+ log.Info("System state alarm has exist")
+ continue
+ }
+
+ SpecificProblem := fmt.Sprintf(alarmDefine.SpecificProblem, alarmDefine.Threshold)
+ locationInfo := fmt.Sprintf("SystemManagement.State: NE heartbeat timestamp=%s,threshold=%v", timestamp, alarmDefine.Threshold)
+ alarmData := &Alarm{
+ AlarmSeq: alarmSeq,
+ AlarmId: params,
+ NeId: ne.RmUID,
+ NeType: ne.NeType,
+ NeName: ne.NeName,
+ Province: ne.Province,
+ PVFlag: ne.PvFlag,
+ AlarmCode: alarmDefine.AlarmCode,
+ AlarmTitle: alarmDefine.AlarmTitle,
+ AlarmType: alarmDefine.AlarmType,
+ AlarmStatus: AlarmStatusActive,
+ OrigSeverity: alarmDefine.OrigSeverity,
+ ObjectUid: alarmDefine.ObjectUid,
+ ObjectName: alarmDefine.ObjectName,
+ ObjectType: alarmDefine.ObjectType,
+ LocationInfo: locationInfo,
+ SpecificProblem: SpecificProblem,
+ SpecificProblemID: alarmDefine.SpecificProblemId,
+ AddInfo: alarmDefine.AddInfo,
+ EventTime: time.Now().Local().Format(time.RFC3339),
+ }
+
+ alarmArray := &[]Alarm{*alarmData}
+ body, _ := json.Marshal(alarmArray)
+ log.Debug("body: ", string(body))
+
+ var response *resty.Response
+ requestURI := fmt.Sprintf(uri, ne.NeType)
+ requestURL := fmt.Sprintf("%s%s", yamlConfig.OMC.HostUri, requestURI)
+ log.Debug("requestURL: POST ", requestURL)
+ client := resty.New()
+ response, err = client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ SetBody(body).
+ Post(requestURL)
+ if err != nil {
+ log.Error("Failed to post:", err)
+ }
+
+ log.Debug("StatusCode: ", response.StatusCode())
+ switch response.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ log.Debug("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ default:
+ log.Debug("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ }
+ }
+ }
+}
+
+type ProcInfo struct {
+ Name string `json:"name"`
+ Pid int32 `json:"pid"`
+ StartTime string `json:"startTime"`
+}
+
+var procList = []string{"restagent", "crontask", "4a_agent", "nbi_agent", "nbi_alarm", "mysqld"}
+var procInfos = make([]ProcInfo, len(procList))
+
+func init() {
+ for i, procName := range procList {
+ procInfo := &ProcInfo{
+ Name: procName,
+ Pid: 0,
+ StartTime: "",
+ }
+ procInfos[i] = *procInfo
+ }
+}
+
+func (t *TaskFunc) TaskWriteSystemLog(uri, params, body string) {
+
+ processes, err := process.Processes()
+ if err != nil {
+ log.Error("Failed to get processes:", err)
+ return
+ }
+
+ for _, proc := range processes {
+ name, err := proc.Name()
+ if err != nil {
+ log.Error("Failed to get process name:", err)
+ continue
+ }
+ for i, procInfo := range procInfos {
+ if name == procInfo.Name {
+ pid := proc.Pid
+ timestamp, _ := proc.CreateTime()
+ userName, _ := proc.Username()
+ startTime := time.Unix((timestamp / 1000), 0).Format(time.DateTime)
+
+ newProcInfo := &ProcInfo{
+ Name: procInfo.Name,
+ Pid: pid,
+ StartTime: startTime,
+ }
+ log.Trace("newProcInfo:", *newProcInfo)
+ log.Trace("procInfo:", procInfo)
+ if *newProcInfo != procInfo {
+ procInfos[i] = *newProcInfo
+ var operation string
+ if newProcInfo.Pid != 0 {
+ operation = "start"
+ } else {
+ operation = "stop"
+ }
+ sysLogs := &[]dborm.SystemLog{}
+ sysLog := &dborm.SystemLog{
+ User: userName,
+ ProcessName: newProcInfo.Name,
+ ProcessID: newProcInfo.Pid,
+ Operation: operation,
+ ProcessTime: newProcInfo.StartTime,
+ LogTime: time.Now().Format(time.DateTime),
+ }
+ var response *resty.Response
+ requestURI := fmt.Sprintf("%s?%s", uri, params)
+ requestURL := fmt.Sprintf("%s%s", yamlConfig.OMC.HostUri, requestURI)
+
+ *sysLogs = append(*sysLogs, *sysLog)
+ data := make(map[string]interface{})
+ data["system_log"] = *sysLogs
+ body, err := json.Marshal(data)
+ log.Trace("data:", data)
+ log.Debug("requestURL: POST ", requestURL)
+ client := resty.New()
+ response, err = client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ SetBody(body).
+ Post(requestURL)
+ if err != nil {
+ log.Error("Failed to post:", err)
+ }
+ log.Debug("StatusCode: ", response.StatusCode())
+ switch response.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ log.Debug("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ default:
+ log.Debug("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/crontask/xml.go.org b/crontask/xml.go.org
new file mode 100644
index 00000000..cf111abf
--- /dev/null
+++ b/crontask/xml.go.org
@@ -0,0 +1,129 @@
+package main
+
+import (
+ "encoding/xml"
+ "io/ioutil"
+)
+
+const (
+ // Header is a generic XML header suitable for use with the output of Marshal.
+ // This is not automatically added to any output of this package,
+ // it is provided as a convenience.
+ Header = `` + "\n"
+)
+
+type Attribute struct {
+ Text string `xml:",chardata"`
+ Name string `xml:"name,attr"`
+ Type string `xml:"type,attr"`
+ Use string `xml:"use,attr"`
+}
+
+type Schema struct {
+ XMLName xml.Name `xml:"schema"`
+ Text string `xml:",chardata"`
+ Xs string `xml:"xs,attr"`
+ Xsi string `xml:"xsi,attr"`
+ ElementFormDefault string `xml:"elementFormDefault,attr"`
+ AttributeFormDefault string `xml:"attributeFormDefault,attr"`
+ Element struct {
+ Text string `xml:",chardata"`
+ Name string `xml:"name,attr"`
+ ComplexType struct {
+ Text string `xml:",chardata"`
+ Sequence struct {
+ Text string `xml:",chardata"`
+ Element []struct {
+ Text string `xml:",chardata"`
+ Name string `xml:"name,attr"`
+ MaxOccurs string `xml:"maxOccurs,attr"`
+ ComplexType struct {
+ Text string `xml:",chardata"`
+ Sequence struct {
+ Text string `xml:",chardata"`
+ Element []struct {
+ Text string `xml:",chardata"`
+ Name string `xml:"name,attr"`
+ Type string `xml:"type,attr"`
+ MinOccurs string `xml:"minOccurs,attr"`
+ ComplexType struct {
+ Text string `xml:",chardata"`
+ Sequence struct {
+ Text string `xml:",chardata"`
+ MinOccurs string `xml:"minOccurs,attr"`
+ MaxOccurs string `xml:"maxOccurs,attr"`
+ Element struct {
+ Text string `xml:",chardata"`
+ Name string `xml:"name,attr"`
+ ComplexType struct {
+ Text string `xml:",chardata"`
+ SimpleContent struct {
+ Text string `xml:",chardata"`
+ Extension struct {
+ Text string `xml:",chardata"`
+ Base string `xml:"base,attr"`
+ Attribute struct {
+ Text string `xml:",chardata"`
+ Name string `xml:"name,attr"`
+ Type string `xml:"type,attr"`
+ Use string `xml:"use,attr"`
+ } `xml:"attribute"`
+ } `xml:"extension"`
+ } `xml:"simpleContent"`
+ Sequence struct {
+ Text string `xml:",chardata"`
+ MinOccurs string `xml:"minOccurs,attr"`
+ MaxOccurs string `xml:"maxOccurs,attr"`
+ Element struct {
+ Text string `xml:",chardata"`
+ Name string `xml:"name,attr"`
+ ComplexType struct {
+ Text string `xml:",chardata"`
+ SimpleContent struct {
+ Text string `xml:",chardata"`
+ Extension struct {
+ Text string `xml:",chardata"`
+ Base string `xml:"base,attr"`
+ Attribute struct {
+ Text string `xml:",chardata"`
+ Name string `xml:"name,attr"`
+ Type string `xml:"type,attr"`
+ Use string `xml:"use,attr"`
+ } `xml:"attribute"`
+ } `xml:"extension"`
+ } `xml:"simpleContent"`
+ } `xml:"complexType"`
+ } `xml:"element"`
+ } `xml:"sequence"`
+ Attribute []struct {
+ Text string `xml:",chardata"`
+ Name string `xml:"name,attr"`
+ Type string `xml:"type,attr"`
+ Use string `xml:"use,attr"`
+ } `xml:"attribute"`
+ } `xml:"complexType"`
+ } `xml:"element"`
+ } `xml:"sequence"`
+ } `xml:"complexType"`
+ } `xml:"element"`
+ } `xml:"sequence"`
+ } `xml:"complexType"`
+ } `xml:"element"`
+ } `xml:"sequence"`
+ } `xml:"complexType"`
+ } `xml:"element"`
+}
+
+func GenNRMXmlFile() {
+ nrmFile := Schema{
+ Xs: "http://www.w3.org/2001/XMLSchema",
+ Xsi: "http://www.w3.org/2001/XMLSchema-instance",
+ ElementFormDefault: "qualified",
+ AttributeFormDefault: "unqualified",
+ Element: struct{}{Name: "DataFile"},
+ }
+
+ b, _ := xml.MarshalIndent(nrmFile, "", " ")
+ b = append([]byte(xml.Header), b...)
+ ioutil.WriteFile("D:/nrm-demo.xml", b, 0664)
+}
diff --git a/features/aaaa/aaaa.go b/features/aaaa/aaaa.go
new file mode 100644
index 00000000..e37c5789
--- /dev/null
+++ b/features/aaaa/aaaa.go
@@ -0,0 +1,117 @@
+package aaaa
+
+import (
+ "encoding/json"
+ "fmt"
+ "net/http"
+ "strings"
+ "time"
+
+ "github.com/go-resty/resty/v2"
+
+ "ems.agt/lib/log"
+ "ems.agt/lib/services"
+ "ems.agt/restagent/config"
+)
+
+var (
+ UriAAAASSO = config.UriPrefix + "/aaaa/{apiVersion}/security/sso" // for external
+)
+
+var client = resty.New()
+
+func init() {
+ /*
+ client.
+ SetTimeout(10 * time.Second).
+ SetRetryCount(1).
+ SetRetryWaitTime(1 * time.Second).
+ SetRetryMaxWaitTime(2 * time.Second).
+ SetRetryAfter(func(client *resty.Client, resp *resty.Response) (time.Duration, error) {
+ return 0, errors.New("quota exceeded")
+ })
+ */
+ client.SetTimeout(3 * time.Second)
+}
+
+type AAAATicket struct {
+ Ticket string `json:"ticket"`
+}
+
+type SSOResult struct {
+ SSO struct {
+ Result string `json:"result"`
+ ResultMsg string `json:"result_msg"`
+ Ticket string `json:"ticket"`
+ ResultMsgcode string `json:"result_msgcode"`
+ Account []struct {
+ Accid string `json:"accid"`
+ } `json:"account"`
+ } `json:"sso"`
+}
+
+// Get system state from NF/NFs
+func GetSSOFromAAAA(w http.ResponseWriter, r *http.Request) {
+ log.Debug("GetSSOFromAAAA processing... ")
+
+ vars := r.URL.Query()
+ ticket := vars["ticket"]
+ if len(ticket) == 0 {
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ log.Debug("ticket:", ticket)
+
+ log.Debugf("r.RemoteAddr:%s r.Host: %s", r.RemoteAddr, r.Host)
+
+ var aaaaIp, omcIp string
+ addr := strings.Split(r.RemoteAddr, ":")
+ if len(addr) > 0 {
+ //aaaaIp := r.RemoteAddr[:strings.Index(r.Host, ":")]
+ aaaaIp = addr[0]
+ }
+ addr = strings.Split(r.Host, ":")
+ if len(addr) > 0 {
+ //omcIp := r.Host[:strings.Index(r.Host, ":")]
+ omcIp = addr[0]
+ }
+ log.Debugf("aaaaIp=%s omcIp=%s", aaaaIp, omcIp)
+ requestURI2NF := fmt.Sprintf("http://%s:8080/qryUserByTicket", aaaaIp)
+
+ log.Debug("requestURI2NF:", requestURI2NF)
+
+ aaaaTicket := &AAAATicket{
+ Ticket: ticket[0],
+ }
+
+ body, err := json.Marshal(aaaaTicket)
+
+ response, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ SetBody(body).
+ Post(requestURI2NF)
+ if err != nil {
+ log.Error("Get system state from NF is failed:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ log.Debug("response:", response)
+
+ switch response.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ ssoResult := new(SSOResult)
+ json.Unmarshal(response.Body(), ssoResult)
+ var accid string
+ if len(ssoResult.SSO.Account) != 0 {
+ accid = ssoResult.SSO.Account[0].Accid
+ }
+ redirectUrl := fmt.Sprintf("http://%s:8888/home.html?user=%s", omcIp, accid)
+ services.ResponseRedirect(w, redirectUrl)
+ return
+ default:
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+}
diff --git a/features/cm/exec_linux.go b/features/cm/exec_linux.go
new file mode 100644
index 00000000..3044649a
--- /dev/null
+++ b/features/cm/exec_linux.go
@@ -0,0 +1,66 @@
+//go:build linux
+// +build linux
+
+package cm
+
+import (
+ "bytes"
+ "os/exec"
+
+ "ems.agt/lib/log"
+)
+
+func ExecCmd(command string) error {
+ log.Debug("Exec command:", command)
+
+ cmd := exec.Command("/bin/bash", "-c", command)
+ out, err := cmd.CombinedOutput()
+ log.Tracef("Exec output: %v", string(out))
+ if err != nil {
+ log.Error("exe cmd error: ", err)
+ return err
+ }
+ /*
+ if err := cmd.Start(); err != nil {
+ log.Error("Start error: ", err)
+ return err
+ }
+ if err := cmd.Wait(); err != nil {
+ log.Error("Wait error: ", err)
+ return err
+ }
+ */
+ return nil
+}
+
+func ExecShell(command string) error {
+ in := bytes.NewBuffer(nil)
+ cmd := exec.Command("sh")
+ cmd.Stdin = in
+ in.WriteString(command)
+ in.WriteString("exit\n")
+ if err := cmd.Start(); err != nil {
+ return err
+ }
+ return nil
+}
+
+func ExecOsCmd(command, os string) error {
+ log.Debugf("Exec %s command:%s", os, command)
+
+ var cmd *exec.Cmd
+ switch os {
+ case "Linux":
+ cmd = exec.Command(command)
+ case "Windows":
+ cmd = exec.Command("cmd", "/C", command)
+ }
+
+ out, err := cmd.CombinedOutput()
+ log.Tracef("Exec output: %v", string(out))
+ if err != nil {
+ log.Error("exe cmd error: ", err)
+ return err
+ }
+ return nil
+}
diff --git a/features/cm/exec_windows.go b/features/cm/exec_windows.go
new file mode 100644
index 00000000..fa15045a
--- /dev/null
+++ b/features/cm/exec_windows.go
@@ -0,0 +1,53 @@
+//go:build windows
+// +build windows
+
+package cm
+
+import (
+ "os/exec"
+
+ "ems.agt/lib/log"
+)
+
+func ExecCmd(command string) error {
+ log.Debug("Exec command:", command)
+
+ cmd := exec.Command("cmd", "/C", command)
+ out, err := cmd.CombinedOutput()
+ log.Tracef("Exec output: %v", string(out))
+ if err != nil {
+ log.Error("exe cmd error: ", err)
+ return err
+ }
+ /*
+ if err := cmd.Start(); err != nil {
+ log.Error("Start error: ", err)
+ return err
+ }
+ if err := cmd.Wait(); err != nil {
+ log.Error("Wait error: ", err)
+ return err
+ }
+ */
+ return nil
+}
+
+func ExecOsCmd(command, os string) error {
+ log.Debugf("Exec %s command:%s", os, command)
+
+ var cmd *exec.Cmd
+ switch os {
+ case "Linux":
+ cmd = exec.Command(command)
+ case "Windows":
+ cmd = exec.Command("cmd", "/C", command)
+ }
+
+ out, err := cmd.CombinedOutput()
+ log.Tracef("Exec output: %v", string(out))
+ if err != nil {
+ log.Error("exe cmd error: ", err)
+ return err
+ }
+ return nil
+}
diff --git a/features/cm/license.go b/features/cm/license.go
new file mode 100644
index 00000000..1a0925e0
--- /dev/null
+++ b/features/cm/license.go
@@ -0,0 +1,148 @@
+package cm
+
+import (
+ "net/http"
+
+ "ems.agt/lib/log"
+ "ems.agt/lib/services"
+ "ems.agt/restagent/config"
+
+ "github.com/gorilla/mux"
+)
+
+var (
+ // License
+ LicenseUri = config.UriPrefix + "/systemManagement/{apiVersion}/{neType}/license"
+ NeLicenseUri = config.UriPrefix + "/systemManagement/{apiVersion}/{neType}/license/{neId}"
+)
+
+func UploadLicenseFile(w http.ResponseWriter, r *http.Request) {
+ log.Debug("UploadLicenseFile processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Http request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ neType := vars["neType"]
+ if neType == "" {
+ log.Error("neType is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ // neTypeUpper := strings.ToUpper(neType)
+ // neTypeLower := strings.ToLower(neType)
+
+ services.ResponseStatusOK204NoContent(w)
+ return
+}
+
+func DownloadLicenseFile(w http.ResponseWriter, r *http.Request) {
+ log.Debug("DownloadLicenseFile processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ neType := vars["neType"]
+ if neType == "" {
+ log.Error("neType is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ // // neTypeUpper := strings.ToUpper(neType)
+ // //neTypeLower := strings.ToLower(neType)
+
+ // version := vars["version"]
+ // if version == "" {
+ // log.Error("version is empty")
+ // services.ResponseNotFound404UriNotExist(w, r)
+ // return
+ // }
+
+ // sql := fmt.Sprintf("select * from ne_software where ne_type='%s' and version='%s'", neTypeUpper, version)
+ // neSoftware, err := dborm.XormGetDataBySQL(sql)
+ // if err != nil {
+ // log.Error("Faile to XormGetDataBySQL:", err)
+ // services.ResponseInternalServerError500ProcessError(w, err)
+ // return
+ // } else if len(*neSoftware) == 0 {
+ // err := global.ErrCMNotFoundTargetSoftware
+ // log.Error(err)
+ // services.ResponseInternalServerError500ProcessError(w, err)
+ // return
+ // }
+
+ // fileName := (*neSoftware)[0]["file_name"]
+ // path := (*neSoftware)[0]["path"]
+ // md5Sum := (*neSoftware)[0]["md5_sum"]
+
+ // services.ResponseFileWithNameAndMD5(w, http.StatusOK, fileName, path, md5Sum)
+ return
+}
+
+func DeleteLcenseFile(w http.ResponseWriter, r *http.Request) {
+ log.Debug("DeleteLcenseFile processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ neType := vars["neType"]
+ if neType == "" {
+ log.Error("neType is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ // neTypeUpper := strings.ToUpper(neType)
+ // //neTypeLower := strings.ToLower(neType)
+
+ // version := vars["version"]
+ // if version == "" {
+ // log.Error("version is empty")
+ // services.ResponseNotFound404UriNotExist(w, r)
+ // return
+ // }
+
+ // sql := fmt.Sprintf("select * from ne_software where ne_type='%s' and version='%s'", neTypeUpper, version)
+ // neSoftware, err := dborm.XormGetDataBySQL(sql)
+ // if err != nil {
+ // log.Error("Faile to XormGetDataBySQL:", err)
+ // services.ResponseInternalServerError500ProcessError(w, err)
+ // return
+ // } else if len(*neSoftware) == 0 {
+ // err := global.ErrCMNotFoundTargetSoftware
+ // log.Error(err)
+ // services.ResponseInternalServerError500ProcessError(w, err)
+ // return
+ // }
+
+ // where := fmt.Sprintf("ne_type='%s' and version='%s'", neTypeUpper, version)
+ // affected, err := dborm.XormDeleteDataByWhere(where, "ne_software")
+ // if err != nil || affected == 0 {
+ // log.Error("Faile to XormGetDataBySQL:", err)
+ // services.ResponseInternalServerError500ProcessError(w, err)
+ // return
+ // }
+
+ // fileName := (*neSoftware)[0]["file_name"]
+ // path := (*neSoftware)[0]["path"]
+ // filePath := fmt.Sprintf("%s/%s", path, fileName)
+ // err = os.Remove(filePath)
+ // if err != nil {
+ // log.Error("Faile to Remove:", err)
+ // services.ResponseInternalServerError500ProcessError(w, err)
+ // return
+ // }
+
+ services.ResponseStatusOK204NoContent(w)
+ return
+}
diff --git a/features/cm/ne.go b/features/cm/ne.go
new file mode 100644
index 00000000..3e6aa1b5
--- /dev/null
+++ b/features/cm/ne.go
@@ -0,0 +1,676 @@
+package cm
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "os"
+ "strings"
+ "time"
+
+ "ems.agt/lib/dborm"
+ "ems.agt/lib/global"
+ "ems.agt/lib/log"
+ "ems.agt/lib/services"
+ "ems.agt/restagent/config"
+
+ "github.com/go-resty/resty/v2"
+ "github.com/gorilla/mux"
+)
+
+var (
+ UriParamOmcNeConfig = config.UriPrefix + "/systemManagement/v1/elementType/%s/objectType/config/omcNeConfig"
+ // NE CM export/import
+ NeCmUri = config.UriPrefix + "/systemManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/cm"
+ // NE info
+ UriNeInfo = config.UriPrefix + "/systemManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/neInfo"
+ // NE backup file
+ UriNeCmFile = config.UriPrefix + "/systemManagement/{apiVersion}/{neType}/neBackup/{fileName}"
+)
+
+func init() {
+
+}
+
+func GetNeInfo(w http.ResponseWriter, r *http.Request) {
+ log.Debug("GetNeInfo processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ neType := vars["elementTypeValue"]
+ if neType == "" {
+ log.Error("elementTypeValue is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ neId := services.GetUriParamString(r, "ne_id", ",", false, false)
+
+ // no, _ := strconv.ParseInt(neId, 10, 64)
+ neInfo, err := dborm.XormGetNeInfo(neType, neId)
+ if err != nil {
+ log.Error("dborm.XormGetNeInfo is failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+
+ var response services.DataResponse
+ response.Data = neInfo
+ services.ResponseWithJson(w, http.StatusOK, response)
+}
+
+type OmcNeConfig struct {
+ NeId string `json:"neId" xorm:"ne_id"` // 网元标识(内部),
+ RmUID string `json:"rmUID" xorm:"rm_uid"` // rmUID 网元唯一标识
+ NeName string `json:"neName" xorm:"ne_name"` // 网元名称(内部)/友好名称(北向资源/性能等使用)
+ PvFlag string `json:"pvFlag" xorm:"pv_flag"` // 网元虚实性标识 VNF/PNF: 虚拟/物理
+ Province string `json:"province" xorm:"province"` // 网元所在省份
+ VendorName string `json:"vendorName" xorm:"vendor_name"` // 厂商名称
+ // ManagedBy string `json:"managedBy" xorm:"managed_by"` // 管理ManagedElement的ManagementNode对象类的DN值
+ Dn string `json:"dn" xorm:"dn"` // 资源里边的ManagedBy,性能的Dn,网络唯一标识
+}
+
+func PostNeInfo(w http.ResponseWriter, r *http.Request) {
+ log.Debug("PostNeInfo processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ neType := vars["elementTypeValue"]
+ if neType == "" {
+ log.Error("elementTypeValue is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
+ if err != nil {
+ log.Error("io.ReadAll is failed:", err)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ log.Debug("Body:", string(body))
+
+ neInfo := new(dborm.NeInfo)
+ _ = json.Unmarshal(body, neInfo)
+ neInfo.UpdateTime = time.Now().Format(time.DateTime)
+ log.Debug("NE info:", neInfo)
+
+ hostUri := global.CombineHostUri(neInfo.Ip, neInfo.Port)
+ //hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
+ apiUri := fmt.Sprintf(UriParamOmcNeConfig, strings.ToLower(neInfo.NeType))
+ requestURI2NF := fmt.Sprintf("%s%s", hostUri, apiUri)
+ log.Debug("requestURI2NF:", requestURI2NF)
+
+ omcNeConfig := &OmcNeConfig{
+ NeId: neInfo.NeId,
+ RmUID: neInfo.RmUID,
+ NeName: neInfo.NeName,
+ PvFlag: neInfo.PvFlag,
+ Province: neInfo.Province,
+ VendorName: neInfo.VendorName,
+ Dn: neInfo.Dn,
+ }
+ body, _ = json.Marshal(omcNeConfig)
+ client := resty.New()
+ response, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ SetBody(body).
+ Put(requestURI2NF)
+ if err != nil {
+ log.Error("Failed to Put:", err)
+ services.ResponseInternalServerError500NFConnectRefused(w)
+ return
+ }
+ log.Info("StatusCode: ", response.StatusCode())
+
+ if config.GetYamlConfig().OMC.Chk2Ne == false {
+ affected, err := dborm.XormInsertNeInfo(neInfo)
+ if err != nil {
+ log.Error("Failed to insert Ne info:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+
+ mapRow := make(map[string]interface{})
+ row := map[string]interface{}{"affectedRows": affected}
+ mapRow["data"] = row
+ services.ResponseWithJson(w, http.StatusOK, mapRow)
+ return
+ } else {
+ respMsg := make(map[string]interface{})
+ switch response.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ affected, err := dborm.XormInsertNeInfo(neInfo)
+ if err != nil {
+ log.Error("Failed to dborm.XormInsertNeInfo:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ } else if affected <= 0 {
+ log.Infof("Not record affected to insert ne_info")
+ }
+ services.ResponseStatusOK204NoContent(w)
+ return
+ default:
+ log.Info("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ respMsg["error"] = body
+ }
+
+ services.ResponseWithJson(w, response.StatusCode(), respMsg)
+ return
+ }
+}
+
+func PutNeInfo(w http.ResponseWriter, r *http.Request) {
+ log.Debug("PutNeInfo processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ neType := vars["elementTypeValue"]
+ if neType == "" {
+ log.Error("elementTypeValue is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
+ if err != nil {
+ log.Error("io.ReadAll is failed:", err)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ neInfo := new(dborm.NeInfo)
+ _ = json.Unmarshal(body, neInfo)
+ neInfo.NeType = strings.ToUpper(neType)
+ neInfo.UpdateTime = time.Now().Format(time.DateTime)
+ log.Debug("NE info:", neInfo)
+
+ hostUri := global.CombineHostUri(neInfo.Ip, neInfo.Port)
+ //hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
+ apiUri := fmt.Sprintf(UriParamOmcNeConfig, strings.ToLower(neType))
+ requestURI2NF := fmt.Sprintf("%s%s", hostUri, apiUri)
+ log.Debug("requestURI2NF:", requestURI2NF)
+
+ omcNeConfig := &OmcNeConfig{
+ NeId: neInfo.NeId,
+ RmUID: neInfo.RmUID,
+ NeName: neInfo.NeName,
+ PvFlag: neInfo.PvFlag,
+ Province: neInfo.Province,
+ VendorName: neInfo.VendorName,
+ Dn: neInfo.Dn,
+ }
+ body, _ = json.Marshal(omcNeConfig)
+ client := resty.New()
+ response, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ SetBody(body).
+ Put(requestURI2NF)
+ if err != nil {
+ log.Error("Failed to Put:", err)
+ services.ResponseInternalServerError500NFConnectRefused(w)
+ return
+ }
+ log.Info("StatusCode: ", response.StatusCode())
+
+ if config.GetYamlConfig().OMC.Chk2Ne == false {
+ affected, err := dborm.XormUpdateNeInfo(neInfo)
+ if err != nil {
+ log.Error("Failed to update Ne info:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+
+ mapRow := make(map[string]interface{})
+ row := map[string]interface{}{"affectedRows": affected}
+ mapRow["data"] = row
+ services.ResponseWithJson(w, http.StatusOK, mapRow)
+ return
+ } else {
+ respMsg := make(map[string]interface{})
+ switch response.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ affected, err := dborm.XormUpdateNeInfo(neInfo)
+ if err != nil {
+ log.Error("Failed to dborm.XormUpdateNeInfo:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ } else if affected <= 0 {
+ log.Infof("Not record affected to insert ne_info")
+ }
+ services.ResponseStatusOK204NoContent(w)
+ return
+ default:
+ log.Info("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ respMsg["error"] = body
+ }
+
+ services.ResponseWithJson(w, response.StatusCode(), respMsg)
+ return
+ }
+}
+
+func DeleteNeInfo(w http.ResponseWriter, r *http.Request) {
+ log.Debug("DeleteNeInfo processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ neType := vars["elementTypeValue"]
+ if neType == "" {
+ log.Error("elementTypeValue is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
+ if err != nil {
+ log.Error("io.ReadAll is failed:", err)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ neInfo := new(dborm.NeInfo)
+ _ = json.Unmarshal(body, neInfo)
+ neInfo.NeType = strings.ToUpper(neType)
+ neInfo.NeId = services.GetUriParamString(r, "ne_id", ",", false, false)
+ neInfo, err = dborm.XormGetNeInfo(neInfo.NeType, neInfo.NeId)
+ if err != nil || neInfo == nil {
+ log.Error("Failed to delete Ne info:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+ log.Debug("NE info:", neInfo)
+
+ // if NE in active status, can't delete NE
+ if IsActiveNF(neInfo) == false {
+ affected, err := dborm.XormDeleteNeInfo(neInfo)
+ if err != nil {
+ log.Error("Failed to delete Ne info:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+
+ mapRow := make(map[string]interface{})
+ row := map[string]interface{}{"affectedRows": affected}
+ mapRow["data"] = row
+ services.ResponseWithJson(w, http.StatusOK, mapRow)
+ return
+ }
+ err = global.ErrCMCannotDeleteActiveNE
+ log.Error(err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+}
+
+func IsActiveNF(neInfo *dborm.NeInfo) bool {
+ log.Debug("IsActiveNF processing... ")
+
+ hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
+ requestURI := fmt.Sprintf(config.UriPrefix+"/systemManagement/v1/elementType/%s/objectType/systemState",
+ strings.ToLower(neInfo.NeType))
+
+ client := resty.New()
+ response, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ Get(hostUri + requestURI)
+ if err != nil {
+ log.Error("Failed to Get:", err)
+ }
+
+ switch response.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ return true
+ }
+ return false
+}
+
+func ExportCmFromNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("ExportCmFromNF processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ neType := vars["elementTypeValue"]
+ if neType == "" {
+ log.Error("elementTypeValue is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ neTypeUpper := strings.ToUpper(neType)
+ neTypeLower := strings.ToLower(neType)
+
+ neId := services.GetUriParamString(r, "ne_id", ",", false, false)
+
+ // neInfo := new(dborm.NeInfo)
+ neInfo, err := dborm.XormGetNeInfo(neType, neId)
+ if err != nil {
+ log.Errorf("Failed to get ne_info:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+ log.Debug("neInfo:", neInfo)
+ nePath := fmt.Sprintf("%s/etc/%s", config.GetYamlConfig().OMC.Backup, neTypeLower)
+ isExist, err := global.PathExists(nePath)
+ if err != nil {
+ log.Errorf("Failed to stat:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ if isExist {
+ err = os.RemoveAll(nePath)
+ if err != nil {
+ log.Errorf("Failed to RemoveAll:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ }
+ err = os.MkdirAll(nePath, os.ModePerm)
+ if err != nil {
+ log.Errorf("Failed to MkdirAll:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ var scpCmd string
+ ipType := global.ParseIPAddr(neInfo.Ip)
+ if ipType == global.IsIPv4 {
+ scpCmd = fmt.Sprintf("scp -r %s@%s:%s/%s/*.yaml %s/etc/%s", config.GetYamlConfig().NE.User,
+ neInfo.Ip, config.GetYamlConfig().NE.EtcDir,
+ neTypeLower, config.GetYamlConfig().OMC.Backup, neTypeLower)
+ } else {
+ scpCmd = fmt.Sprintf("scp -r %s@[%s]:%s/%s/*.yaml %s/etc/%s", config.GetYamlConfig().NE.User,
+ neInfo.Ip, config.GetYamlConfig().NE.EtcDir,
+ neTypeLower, config.GetYamlConfig().OMC.Backup, neTypeLower)
+ }
+
+ zipFile := fmt.Sprintf("%s-%s-etc-%s.zip", neTypeLower, strings.ToLower(neInfo.NeId), time.Now().Format(global.DateData))
+ zipCmd := fmt.Sprintf("cd %s && zip -r %s etc/%s/*", config.GetYamlConfig().OMC.Backup, zipFile, neTypeLower)
+
+ command := fmt.Sprintf("%s&&%s", scpCmd, zipCmd)
+
+ log.Debug("command:", command)
+ err = ExecCmd(command)
+ if err != nil {
+ log.Error("Faile to exec command:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ zipFilePath := fmt.Sprintf("%s/%s", config.GetYamlConfig().OMC.Backup, zipFile)
+ md5Sum, err := global.GetFileMD5Sum(zipFilePath)
+ if err != nil {
+ log.Error("Faile to md5sum:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ //log.Debug("md5Str:", md5Sum)
+ path := config.GetYamlConfig().OMC.Backup
+ neBackup := dborm.NeBackup{NeType: neTypeUpper, NeId: neId, FileName: zipFile, Path: path, Md5Sum: md5Sum}
+ _, err = dborm.XormInsertTableOne("ne_backup", neBackup)
+ if err != nil {
+ log.Error("Faile to XormInsertTableOne:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ //services.ResponseFileWithNameAndMD5(w, http.StatusOK, zipFile, path, md5Sum)
+ services.ResponseStatusOK204NoContent(w)
+ return
+}
+
+type ImportCMJson struct {
+ FileName string `json:"fileName"`
+}
+
+func ImportCmToNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("ImportCmToNF processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ neType := vars["elementTypeValue"]
+ if neType == "" {
+ log.Error("elementTypeValue is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ neTypeUpper := strings.ToUpper(neType)
+ neTypeLower := strings.ToLower(neType)
+
+ neId := services.GetUriParamString(r, "ne_id", ",", false, false)
+
+ var fileName, path string
+ if services.IsJsonContentType(r) {
+ body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
+ if err != nil {
+ log.Error("io.ReadAll is failed:", err)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ log.Debug("Body:", string(body))
+
+ importCMJson := new(ImportCMJson)
+ _ = json.Unmarshal(body, importCMJson)
+ fileName = importCMJson.FileName
+ path = config.GetYamlConfig().OMC.Backup
+ } else {
+ path = config.GetYamlConfig().OMC.Upload
+ fileName, err = services.HandleUploadFile(r, path, "")
+ if err != nil {
+ log.Error("Faile to HandleUploadFile:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ }
+ filePath := fmt.Sprintf("%s/%s", path, fileName)
+
+ // neInfo := new(dborm.NeInfo)
+ neInfo, err := dborm.XormGetNeInfo(neType, neId)
+ if err != nil {
+ log.Errorf("Failed to get ne_info:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+ log.Debug("neInfo:", neInfo)
+
+ md5Sum, err := global.GetFileMD5Sum(filePath)
+ if err != nil {
+ log.Error("Faile to GetFileMD5Sum:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ //neBackup := dborm.NeBackup{NeType: neType, NeId: neId, Md5Sum: md5Sum}
+ //log.Debug("neBackup:", neBackup)
+ where := fmt.Sprintf("ne_type='%s' and ne_id='%s' and md5_sum='%s'", neTypeUpper, neId, md5Sum)
+ has, err := dborm.XormExistTableOne("ne_backup", where)
+ if err != nil {
+ log.Error("Faile to XormInsertTableOne:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ } else if has == false {
+ err = global.ErrCMInvalidBackupFile
+ log.Error(err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ nePath := fmt.Sprintf("%s/etc/%s", config.GetYamlConfig().OMC.Upload, neTypeLower)
+ isExist, err := global.PathExists(nePath)
+ if err != nil {
+ log.Errorf("Failed to stat:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ if isExist {
+ err = os.RemoveAll(nePath)
+ if err != nil {
+ log.Errorf("Failed to remove:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ }
+ unzipCmd := fmt.Sprintf("unzip -o %s -d %s", filePath, config.GetYamlConfig().OMC.Upload)
+
+ var scpCmd string
+ ipType := global.ParseIPAddr(neInfo.Ip)
+ if ipType == global.IsIPv4 {
+ scpCmd = fmt.Sprintf("scp -r %s/etc/%s %s@%s:%s", config.GetYamlConfig().OMC.Upload,
+ neTypeLower, config.GetYamlConfig().NE.User, neInfo.Ip, config.GetYamlConfig().NE.EtcDir)
+ } else {
+ scpCmd = fmt.Sprintf("scp -r %s/etc/%s %s@[%s]:%s", config.GetYamlConfig().OMC.Upload,
+ neTypeLower, config.GetYamlConfig().NE.User, neInfo.Ip, config.GetYamlConfig().NE.EtcDir)
+ }
+
+ err = ExecCmd(fmt.Sprintf("%s && %s", unzipCmd, scpCmd))
+ if err != nil {
+ log.Errorf("Faile to scp NF: neType=%s, neId=%s, ip=%s", neType, neId, neInfo.Ip)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ services.ResponseStatusOK204NoContent(w)
+ return
+}
+
+func DownloadNeBackupFile(w http.ResponseWriter, r *http.Request) {
+ log.Debug("DownloadNeBackupFile processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ neType := vars["neType"]
+ if neType == "" {
+ log.Error("neType is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ neTypeUpper := strings.ToUpper(neType)
+ //neTypeLower := strings.ToLower(neType)
+
+ fileName := vars["fileName"]
+ if fileName == "" {
+ log.Error("fileName is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ sql := fmt.Sprintf("select * from ne_backup where ne_type='%s' and file_name='%s'", neTypeUpper, fileName)
+ neBackup, err := dborm.XormGetDataBySQL(sql)
+ if err != nil {
+ log.Error("Faile to XormGetDataBySQL:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ } else if len(*neBackup) == 0 {
+ err := global.ErrCMNotFoundTargetBackupFile
+ log.Error(err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ path := (*neBackup)[0]["path"]
+ md5Sum := (*neBackup)[0]["md5_sum"]
+
+ services.ResponseFileWithNameAndMD5(w, http.StatusOK, fileName, path, md5Sum)
+ return
+}
+
+func DeleteNeBackupFile(w http.ResponseWriter, r *http.Request) {
+ log.Debug("DeleteNeBackupFile processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ neType := vars["neType"]
+ if neType == "" {
+ log.Error("neType is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ neTypeUpper := strings.ToUpper(neType)
+ //neTypeLower := strings.ToLower(neType)
+
+ fileName := vars["fileName"]
+ if fileName == "" {
+ log.Error("fileName is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ sql := fmt.Sprintf("select * from ne_backup where ne_type='%s' and file_name='%s'", neTypeUpper, fileName)
+ neBackup, err := dborm.XormGetDataBySQL(sql)
+ if err != nil {
+ log.Error("Faile to XormGetDataBySQL:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ } else if len(*neBackup) == 0 {
+ err := global.ErrCMNotFoundTargetBackupFile
+ log.Error(err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ where := fmt.Sprintf("ne_type='%s' and file_name='%s'", neTypeUpper, fileName)
+ affected, err := dborm.XormDeleteDataByWhere(where, "ne_backup")
+ if err != nil || affected == 0 {
+ log.Error("Faile to XormGetDataBySQL:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ path := (*neBackup)[0]["path"]
+ filePath := fmt.Sprintf("%s/%s", path, fileName)
+ err = os.Remove(filePath)
+ if err != nil {
+ log.Error("Faile to Remove:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ services.ResponseStatusOK204NoContent(w)
+ return
+}
diff --git a/features/cm/param.go b/features/cm/param.go
new file mode 100644
index 00000000..f4603a49
--- /dev/null
+++ b/features/cm/param.go
@@ -0,0 +1,241 @@
+package cm
+
+import (
+ "ems.agt/lib/dborm"
+ "ems.agt/lib/global"
+ "ems.agt/lib/log"
+ "ems.agt/lib/services"
+ "ems.agt/restagent/config"
+
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+
+ "github.com/go-resty/resty/v2"
+ "github.com/gorilla/mux"
+)
+
+var (
+ // parameter config management
+ ParamConfigUri = config.UriPrefix + "/systemManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/config/{paraName}"
+ ParamConfigUrl = config.UriPrefix + "/systemManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/config/{paraName}"
+)
+
+func GetParamConfigFromNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("GetParamConfigFromNF processing... ")
+
+ // data := make([]map[string]interface{}, 1)
+ var response services.DataResponse
+ vars := mux.Vars(r)
+ neType := vars["elementTypeValue"]
+ if neType == "" {
+ log.Error("elementTypeValue is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ token, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ restHostPort := fmt.Sprintf("http://127.0.0.1:%d", config.GetYamlConfig().Rest[0].Port)
+ getNeInfoPattern := fmt.Sprintf(config.UriPrefix+"/databaseManagement/v1/%s/ne_info", config.GetYamlConfig().Database.Name)
+ getNeInfoURI := restHostPort + getNeInfoPattern
+ neId := services.GetUriParamString(r, "ne_id", ",", true, false)
+ if neId == "" {
+ getNeInfoURI = getNeInfoURI + fmt.Sprintf("?WHERE=status='0'+and+ne_type='%s'", neType)
+ } else {
+ getNeInfoURI = getNeInfoURI + fmt.Sprintf("?WHERE=status='0'+and+ne_type='%v'+and+ne_id+in+%v", neType, neId)
+ }
+ log.Debug("getNeInfoURI:", getNeInfoURI)
+
+ client := resty.New()
+ resp, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"accessToken": token}).
+ SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ Get(getNeInfoURI)
+ if err != nil {
+ log.Error("Get from database is failure!")
+ services.ResponseInternalServerError500NFConnectRefused(w)
+ return
+ }
+ log.Debug("NE info:", string(resp.Body()))
+
+ // var neList []dborm.NeInfo
+ neList, _ := dborm.XormParseResult(resp.Body())
+
+ if len(neList) >= 1 {
+ s := neList[0]
+ requestURI2NF := fmt.Sprintf("http://%s:%v%s", s.Ip, s.Port, r.RequestURI)
+ log.Debug("requestURI2NF:", requestURI2NF)
+
+ resp, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ Get(requestURI2NF)
+ if err != nil {
+ log.Error("Get from NF is failure:", err)
+ services.ResponseInternalServerError500NFConnectRefused(w)
+ return
+ } else {
+ _ = json.Unmarshal(resp.Body(), &response)
+ }
+ log.Debug("response:", response)
+ }
+
+ services.ResponseWithJson(w, http.StatusOK, response)
+}
+
+func PostParamConfigToNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("PostParamConfigToNF processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ neType := vars["elementTypeValue"]
+ if neType == "" {
+ log.Error("elementTypeValue is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ neId := services.GetUriParamString(r, "ne_id", ",", false, false)
+
+ // no, _ := strconv.ParseInt(neId, 10, 64)
+ neInfo, err := dborm.XormGetNeInfo(neType, neId)
+ if err != nil {
+ log.Error("dborm.XormGetNeInfo is failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+
+ requestURI2NF := fmt.Sprintf("http://%s:%v%s", neInfo.Ip, neInfo.Port, r.RequestURI)
+ log.Debug("requestURI2NF: POST ", requestURI2NF)
+
+ body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen)) //io.LimitReader限制大小
+ if err != nil {
+ log.Error("io.ReadAll is failed:", err)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ client := resty.New()
+ response, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ SetBody(body).
+ Post(requestURI2NF)
+ if err != nil {
+ log.Error("Failed to POST to NF:", err)
+ services.ResponseInternalServerError500NFConnectRefused(w)
+ return
+ }
+
+ services.ResponseWithJson(w, response.StatusCode(), response)
+}
+
+func PutParamConfigToNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("PutParamConfigToNF processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ neType := vars["elementTypeValue"]
+ if neType == "" {
+ log.Error("elementTypeValue is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ neId := services.GetUriParamString(r, "ne_id", ",", false, false)
+
+ // no, _ := strconv.ParseInt(neId, 10, 64)
+ neInfo, err := dborm.XormGetNeInfo(neType, neId)
+ if err != nil {
+ log.Error("dborm.XormGetNeInfo is failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+
+ requestURI2NF := fmt.Sprintf("http://%s:%v%s", neInfo.Ip, neInfo.Port, r.RequestURI)
+ log.Debug("requestURI2NF: PUT ", requestURI2NF)
+
+ body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen)) //io.LimitReader限制大小
+ if err != nil {
+ log.Error("io.ReadAll is failed:", err)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ client := resty.New()
+ response, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ SetBody(body).
+ Put(requestURI2NF)
+ if err != nil {
+ log.Error("Put to NF failed:", err)
+ services.ResponseInternalServerError500NFConnectRefused(w)
+ return
+ }
+
+ services.ResponseWithJson(w, response.StatusCode(), response)
+}
+
+func DeleteParamConfigToNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("DeleteParamConfigToNF processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ neType := vars["elementTypeValue"]
+ if neType == "" {
+ log.Error("elementTypeValue is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ neId := services.GetUriParamString(r, "ne_id", ",", false, false)
+
+ // no, _ := strconv.ParseInt(neId, 10, 64)
+ neInfo, err := dborm.XormGetNeInfo(neType, neId)
+ if err != nil {
+ log.Error("dborm.XormGetNeInfo is failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+
+ requestURI2NF := fmt.Sprintf("http://%s:%v%s", neInfo.Ip, neInfo.Port, r.RequestURI)
+ log.Debug("requestURI2NF: DELETE ", requestURI2NF)
+
+ client := resty.New()
+ response, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ Delete(requestURI2NF)
+ if err != nil {
+ log.Error("Failed to delete parameter:", err)
+ services.ResponseInternalServerError500NFConnectRefused(w)
+ return
+ }
+
+ services.ResponseWithJson(w, response.StatusCode(), response)
+}
diff --git a/features/cm/software.go b/features/cm/software.go
new file mode 100644
index 00000000..0ed8ddee
--- /dev/null
+++ b/features/cm/software.go
@@ -0,0 +1,575 @@
+package cm
+
+import (
+ "fmt"
+ "net/http"
+ "os"
+ "os/exec"
+ "strconv"
+ "strings"
+
+ "ems.agt/lib/dborm"
+ "ems.agt/lib/global"
+ "ems.agt/lib/log"
+ "ems.agt/lib/services"
+ "ems.agt/restagent/config"
+
+ "github.com/gorilla/mux"
+)
+
+const (
+ SoftwareStatusUploaded = "Uploaded"
+ SoftwareStatusInactive = "Inactive"
+ SoftwareStatusActive = "Active"
+ DigestsSignOkString = "digests signatures OK"
+)
+
+var (
+ UriSoftware = config.UriPrefix + "/systemManagement/{apiVersion}/{neType}/software/{version}"
+ UriSoftwareNE = config.UriPrefix + "/systemManagement/{apiVersion}/{neType}/software/{version}/{neId}"
+)
+
+func UploadSoftwareFile(w http.ResponseWriter, r *http.Request) {
+ log.Debug("UploadSoftwareFile processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Http request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ neType := vars["neType"]
+ if neType == "" {
+ log.Error("neType is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ neTypeUpper := strings.ToUpper(neType)
+ neTypeLower := strings.ToLower(neType)
+
+ version := vars["version"]
+ if version == "" {
+ log.Error("version is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ md5Param := services.GetUriParamString(r, "md5Sum", ",", false, false)
+
+ // body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
+ // if err != nil {
+ // log.Error("io.ReadAll is failed:", err)
+ // services.ResponseNotFound404UriNotExist(w, r)
+ // return
+ // }
+ // neSWBody := new(dborm.NeSoftware)
+ // _ = json.Unmarshal(body, neSWBody)
+ // log.Trace("neSoftware:", neSWBody)
+
+ softwarePath := fmt.Sprintf("%s/%s", config.GetYamlConfig().OMC.Software, neTypeLower)
+ fileName, err := services.HandleUploadFile(r, softwarePath, "")
+ if err != nil {
+ log.Error("Faile to HandleUploadFile:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ filePath := fmt.Sprintf("%s/%s", softwarePath, fileName)
+ md5File, err := global.GetFileMD5Sum(filePath)
+ if err != nil {
+ log.Error("Faile to GetFileMD5Sum:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ if md5File != md5Param {
+ err = global.ErrCMNotMatchMD5File
+ log.Error(err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ if config.GetYamlConfig().OMC.CheckSign {
+ cmd := exec.Command("rpm", "-K", filePath)
+ out, err := cmd.CombinedOutput()
+ log.Debugf("Exec outpout:%s", string(out))
+ if err != nil {
+ log.Error("Failed to execute rpm:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ if !strings.Contains(string(out), DigestsSignOkString) {
+ err = global.ErrCMNotMatchSignFile
+ log.Error(err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ }
+
+ //neBackup := dborm.NeBackup{NeType: neType, NeId: neId, Md5Sum: md5Sum}
+ //log.Debug("neBackup:", neBackup)
+ where := fmt.Sprintf("ne_type='%s' and version='%s'", neTypeUpper, version)
+ has, err := dborm.XormExistTableOne("ne_software", where)
+ if err != nil {
+ log.Error("Faile to XormInsertTableOne:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ } else if has == true {
+ err = global.ErrCMExistSoftwareFile
+ log.Error(err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ neSoftware := dborm.NeSoftware{
+ NeType: neTypeUpper,
+ FileName: fileName,
+ Path: softwarePath,
+ Version: version,
+ Md5Sum: md5Param,
+ Comment: neType + " 5GC " + version,
+ //Comment: neSWBody.Comment,
+ }
+
+ _, err = dborm.XormInsertTableOne("ne_software", neSoftware)
+ if err != nil {
+ log.Error("Faile to XormInsertTableOne:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ services.ResponseStatusOK204NoContent(w)
+ return
+}
+
+func DownloadSoftwareFile(w http.ResponseWriter, r *http.Request) {
+ log.Debug("DownloadSoftwareFile processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ neType := vars["neType"]
+ if neType == "" {
+ log.Error("neType is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ neTypeUpper := strings.ToUpper(neType)
+ //neTypeLower := strings.ToLower(neType)
+
+ version := vars["version"]
+ if version == "" {
+ log.Error("version is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ sql := fmt.Sprintf("select * from ne_software where ne_type='%s' and version='%s'", neTypeUpper, version)
+ neSoftware, err := dborm.XormGetDataBySQL(sql)
+ if err != nil {
+ log.Error("Faile to XormGetDataBySQL:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ } else if len(*neSoftware) == 0 {
+ err := global.ErrCMNotFoundTargetSoftware
+ log.Error(err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ fileName := (*neSoftware)[0]["file_name"]
+ path := (*neSoftware)[0]["path"]
+ md5Sum := (*neSoftware)[0]["md5_sum"]
+
+ services.ResponseFileWithNameAndMD5(w, http.StatusOK, fileName, path, md5Sum)
+ return
+}
+
+func DeleteSoftwareFile(w http.ResponseWriter, r *http.Request) {
+ log.Debug("DeleteSoftwareFile processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ neType := vars["neType"]
+ if neType == "" {
+ log.Error("neType is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ neTypeUpper := strings.ToUpper(neType)
+ //neTypeLower := strings.ToLower(neType)
+
+ version := vars["version"]
+ if version == "" {
+ log.Error("version is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ sql := fmt.Sprintf("select * from ne_software where ne_type='%s' and version='%s'", neTypeUpper, version)
+ neSoftware, err := dborm.XormGetDataBySQL(sql)
+ if err != nil {
+ log.Error("Faile to XormGetDataBySQL:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ } else if len(*neSoftware) == 0 {
+ err := global.ErrCMNotFoundTargetSoftware
+ log.Error(err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ where := fmt.Sprintf("ne_type='%s' and version='%s'", neTypeUpper, version)
+ affected, err := dborm.XormDeleteDataByWhere(where, "ne_software")
+ if err != nil || affected == 0 {
+ log.Error("Faile to XormGetDataBySQL:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ fileName := (*neSoftware)[0]["file_name"]
+ path := (*neSoftware)[0]["path"]
+ filePath := fmt.Sprintf("%s/%s", path, fileName)
+ err = os.Remove(filePath)
+ if err != nil {
+ log.Error("Faile to Remove:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ services.ResponseStatusOK204NoContent(w)
+ return
+}
+
+func DistributeSoftwareToNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("DistributeSoftwareFile processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Http request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ neType := vars["neType"]
+ if neType == "" {
+ log.Error("neType is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ neTypeUpper := strings.ToUpper(neType)
+ neTypeLower := strings.ToLower(neType)
+
+ version := vars["version"]
+ if version == "" {
+ log.Error("version is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ neId := vars["neId"]
+ if version == "" {
+ log.Error("neId is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ neInfo, err := dborm.XormGetNeInfo(neTypeUpper, neId)
+ if err != nil {
+ log.Error("dborm.XormGetNeInfo is failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+
+ sql := fmt.Sprintf("select * from ne_software where ne_type='%s' and version='%s'", neTypeUpper, version)
+ neSoftware, err := dborm.XormGetDataBySQL(sql)
+ if err != nil {
+ log.Error("Faile to XormGetDataBySQL:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ } else if len(*neSoftware) == 0 {
+ err := global.ErrCMNotFoundTargetSoftware
+ log.Error(err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ log.Debug("neSoftware:", neSoftware)
+
+ sql = fmt.Sprintf("select * from ne_version where ne_type='%s' and ne_id='%s'", neTypeUpper, neId)
+ neVersion, err := dborm.XormGetDataBySQL(sql)
+ if err != nil {
+ log.Error("Faile to XormGetDataBySQL:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ log.Debug("neVersion:", neVersion)
+
+ sshHost := fmt.Sprintf("%s@%s", config.GetYamlConfig().NE.User, neInfo.Ip)
+ mkdirCmd := fmt.Sprintf("mkdir -p %s/software/%s", config.GetYamlConfig().NE.OmcDir, neTypeLower)
+ cmd := exec.Command("ssh", sshHost, mkdirCmd)
+ out, err := cmd.CombinedOutput()
+ log.Tracef("Exec output: %v", string(out))
+ if err != nil {
+ log.Error("Faile to exec cmd:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ fileName := (*neSoftware)[0]["file_name"]
+ path := (*neSoftware)[0]["path"]
+ srcFile := fmt.Sprintf("%s/%s", path, fileName)
+ dstDir := fmt.Sprintf("%s@%s:%s/software/%s", config.GetYamlConfig().NE.User,
+ neInfo.Ip, config.GetYamlConfig().NE.OmcDir, neTypeLower)
+ cmd = exec.Command("scp", "-r", srcFile, dstDir)
+ out, err = cmd.CombinedOutput()
+ log.Tracef("Exec output: %v", string(out))
+ if err != nil {
+ log.Errorf("Faile to scp NF: neType=%s, neId=%s, ip=%s", neType, neId, neInfo.Ip)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ if len(*neVersion) == 0 {
+ neVersionData := dborm.NeVersion{
+ NeType: neTypeUpper,
+ NeId: neInfo.NeId,
+ Version: (*neSoftware)[0]["version"],
+ FilePath: fmt.Sprintf("%s/software/%s/%s", config.GetYamlConfig().NE.OmcDir, neTypeLower, fileName),
+ PreVersion: "",
+ PreFile: "",
+ Status: SoftwareStatusInactive,
+ }
+
+ _, err = dborm.XormInsertTableOne("ne_version", neVersionData)
+ if err != nil {
+ log.Error("Faile to XormInsertTableOne:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ } else {
+ idNeVersion, err := strconv.Atoi((*neVersion)[0]["id"])
+ neVersionData := dborm.NeVersion{
+ NeType: neTypeUpper,
+ NeId: neInfo.NeId,
+ Version: (*neSoftware)[0]["version"],
+ FilePath: fmt.Sprintf("%s/software/%s/%s", config.GetYamlConfig().NE.OmcDir, neTypeLower, fileName),
+ PreVersion: (*neVersion)[0]["version"],
+ PreFile: (*neVersion)[0]["file_path"],
+ Status: SoftwareStatusInactive,
+ }
+
+ _, err = dborm.XormUpdateTableById(idNeVersion, "ne_version", neVersionData)
+ if err != nil {
+ log.Error("Faile to UpdateTableById:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ }
+
+ services.ResponseStatusOK204NoContent(w)
+ return
+}
+
+func ActiveSoftwareToNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("ActiveSoftwareToNF processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Http request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ neType := vars["neType"]
+ if neType == "" {
+ log.Error("neType is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ neTypeUpper := strings.ToUpper(neType)
+ //neTypeLower := strings.ToLower(neType)
+
+ version := vars["version"]
+ if version == "" {
+ log.Error("version is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ neId := vars["neId"]
+ if version == "" {
+ log.Error("neId is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ neInfo, err := dborm.XormGetNeInfo(neTypeUpper, neId)
+ if err != nil {
+ log.Error("dborm.XormGetNeInfo is failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+
+ sql := fmt.Sprintf("select * from ne_software where ne_type='%s' and version='%s'", neTypeUpper, version)
+ neSoftware, err := dborm.XormGetDataBySQL(sql)
+ if err != nil {
+ log.Error("Faile to XormGetDataBySQL:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ } else if len(*neSoftware) == 0 {
+ err := global.ErrCMNotFoundTargetSoftware
+ log.Error(err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ log.Debug("neVersion:", neSoftware)
+
+ sql = fmt.Sprintf("select * from ne_version where ne_type='%s' and ne_id='%s' and version='%s'", neTypeUpper, neId, version)
+ neVersion, err := dborm.XormGetDataBySQL(sql)
+ if err != nil {
+ log.Error("Faile to XormGetDataBySQL:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ } else if len(*neVersion) == 0 {
+ err := global.ErrCMNotFoundTargetNeVersion
+ log.Error(err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ log.Debug("neVersion:", neVersion)
+
+ if config.GetYamlConfig().OMC.TestMode == false {
+ filePath := (*neVersion)[0]["file_path"]
+ sshHost := fmt.Sprintf("%s@%s", config.GetYamlConfig().NE.User, neInfo.Ip)
+ rpmCmd := fmt.Sprintf("rpm -Uvh '%s'", filePath)
+ cmd := exec.Command("ssh", sshHost, rpmCmd)
+ out, err := cmd.CombinedOutput()
+ log.Tracef("Exec output: %v", string(out))
+ if err != nil {
+ log.Error("Faile to execute rpm command:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ }
+
+ idNeVersion, err := strconv.Atoi((*neVersion)[0]["id"])
+ neVersionData := dborm.NeVersion{
+ Status: SoftwareStatusActive,
+ }
+
+ _, err = dborm.XormUpdateTableById(idNeVersion, "ne_version", neVersionData)
+ if err != nil {
+ log.Error("Faile to UpdateTableById:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ services.ResponseStatusOK204NoContent(w)
+ return
+}
+
+func RollBackSoftwareToNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("ActiveSoftwareToNF processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Http request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ neType := vars["neType"]
+ if neType == "" {
+ log.Error("neType is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ neTypeUpper := strings.ToUpper(neType)
+ //neTypeLower := strings.ToLower(neType)
+
+ version := vars["version"]
+ if version == "" {
+ log.Error("version is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ neId := vars["neId"]
+ if version == "" {
+ log.Error("neId is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ neInfo, err := dborm.XormGetNeInfo(neTypeUpper, neId)
+ if err != nil {
+ log.Error("dborm.XormGetNeInfo is failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+
+ sql := fmt.Sprintf("select * from ne_version where ne_type='%s' and ne_id='%s'", neTypeUpper, neId)
+ neVersion, err := dborm.XormGetDataBySQL(sql)
+ if err != nil {
+ log.Error("Faile to XormGetDataBySQL:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ } else if len(*neVersion) == 0 {
+ err := global.ErrCMNotFoundTargetNeVersion
+ log.Error(err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ log.Debug("neVersion:", neVersion)
+
+ filePath := (*neVersion)[0]["pre_file"]
+ if filePath == "" {
+ err := global.ErrCMNotFoundRollbackNeVersion
+ log.Error(err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ if config.GetYamlConfig().OMC.TestMode == false {
+ sshHost := fmt.Sprintf("%s@%s", config.GetYamlConfig().NE.User, neInfo.Ip)
+ rpmCmd := fmt.Sprintf("rpm -Uvh --oldpackage '%s'", filePath)
+ cmd := exec.Command("ssh", sshHost, rpmCmd)
+ out, err := cmd.CombinedOutput()
+ log.Tracef("Exec output: %v", string(out))
+ if err != nil {
+ log.Error("Faile to execute rpm command:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ }
+
+ idNeVersion, err := strconv.Atoi((*neVersion)[0]["id"])
+ neVersionData := dborm.NeVersion{
+ Version: (*neVersion)[0]["pre_version"],
+ FilePath: (*neVersion)[0]["pre_file"],
+ PreVersion: "-",
+ PreFile: "-",
+ NewVersion: (*neVersion)[0]["version"],
+ NewFile: (*neVersion)[0]["file_path"],
+ Status: SoftwareStatusActive,
+ }
+
+ _, err = dborm.XormUpdateTableById(idNeVersion, "ne_version", neVersionData)
+ if err != nil {
+ log.Error("Faile to UpdateTableById:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ services.ResponseStatusOK204NoContent(w)
+ return
+}
diff --git a/features/dbrest/dbrest.go b/features/dbrest/dbrest.go
new file mode 100644
index 00000000..cf5b70a5
--- /dev/null
+++ b/features/dbrest/dbrest.go
@@ -0,0 +1,671 @@
+package dbrest
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "regexp"
+ "strings"
+ "time"
+
+ "ems.agt/lib/dborm"
+ "ems.agt/lib/global"
+ "ems.agt/lib/log"
+ "ems.agt/lib/services"
+ "ems.agt/restagent/config"
+
+ "github.com/gorilla/mux"
+ "xorm.io/xorm"
+)
+
+type XormResponse struct {
+ Data interface{} `json:"data"`
+}
+
+type XormInsertResponse struct {
+ Data interface{} `json:"data"`
+}
+
+var (
+ // database management rest pattern, discard
+ XormGetDataUri = config.UriPrefix + "/databaseManagement/{apiVersion}/elementType/{databaseName}/objectType/{tableName}"
+ XormSelectDataUri = config.UriPrefix + "/databaseManagement/{apiVersion}/select/{databaseName}/{tableName}"
+ XormInsertDataUri = config.UriPrefix + "/databaseManagement/{apiVersion}/insert/{databaseName}/{tableName}"
+ XormUpdateDataUri = config.UriPrefix + "/databaseManagement/{apiVersion}/update/{databaseName}/{tableName}"
+ XormDeleteDataUri = config.UriPrefix + "/databaseManagement/{apiVersion}/delete/{databaseName}/{tableName}"
+
+ XormCommonUri = config.UriPrefix + "/databaseManagement/{apiVersion}/{databaseName}/{tableName}" // for internal
+ XormExtDataUri = config.UriPrefix + "/dataManagement/{apiVersion}/{dataStorage}/{dataObject}" // for external
+ XormDataSQLUri = config.UriPrefix + "/dataManagement/{apiVersion}/{dataStorage}/{dataObject}" // for external
+)
+
+var xormResponse XormResponse
+
+// func init() {
+// // database management
+// routes.Register("GET", XormGetDataUri, DatabaseGetData, nil)
+// routes.Register("GET", XormSelectDataUri, DatabaseGetData, nil)
+// routes.Register("POST", XormInsertDataUri, DatabaseInsertData, nil)
+// routes.Register("PUT", XormUpdateDataUri, DatabaseUpdateData, nil)
+// routes.Register("DELETE", XormDeleteDataUri, DatabaseDeleteData, nil)
+// // corss orgin domain
+// routes.Register("OPTIONS", XormGetDataUri, routes.OptionsProc, nil)
+// routes.Register("OPTIONS", XormSelectDataUri, routes.OptionsProc, nil)
+// routes.Register("OPTIONS", XormInsertDataUri, routes.OptionsProc, nil)
+// routes.Register("OPTIONS", XormUpdateDataUri, routes.OptionsProc, nil)
+// routes.Register("OPTIONS", XormDeleteDataUri, routes.OptionsProc, nil)
+
+// routes.Register("GET", XormCommonUri, DatabaseGetData, nil)
+// routes.Register("POST", XormCommonUri, DatabaseInsertData, nil)
+// routes.Register("PUT", XormCommonUri, DatabaseUpdateData, nil)
+// routes.Register("DELETE", XormCommonUri, DatabaseDeleteData, nil)
+
+// // corss orgin domain
+// routes.Register("OPTIONS", XormInsertDataUri, routes.OptionsProc, nil)
+// routes.Register("OPTIONS", XormUpdateDataUri, routes.OptionsProc, nil)
+// routes.Register("OPTIONS", XormDeleteDataUri, routes.OptionsProc, nil)
+
+// routes.Register("OPTIONS", XormCommonUri, routes.OptionsProc, nil)
+// }
+
+var XEngine *xorm.Engine
+
+type DatabaseClient struct {
+ dbType string
+ dbUrl string
+ dbConnMaxLifetime time.Duration
+ dbMaxIdleConns int
+ dbMaxOpenConns int
+ IsShowSQL bool
+
+ XEngine *xorm.Engine
+}
+
+var DbClient DatabaseClient
+
+func InitDbClient(dbType, dbUser, dbPassword, dbHost, dbPort, dbName string) error {
+ DbClient.dbUrl = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8&parseTime=true&loc=Local",
+ dbUser, dbPassword, dbHost, dbPort, dbName)
+ DbClient.dbType = dbType
+ DbClient.dbConnMaxLifetime = 0
+ DbClient.dbMaxIdleConns = 0
+ DbClient.dbMaxOpenConns = 0
+ if log.GetLevel() == log.LOG_TRACE {
+ DbClient.IsShowSQL = true
+ }
+ log.Debugf("dbType:%s dbUrl:%s:******@tcp(%s:%s)/%s??charset=utf8&parseTime=true&loc=Local",
+ dbType, dbUser, dbHost, dbPort, dbName)
+
+ var err error
+ DbClient.XEngine, err = xorm.NewEngine(DbClient.dbType, DbClient.dbUrl)
+ if err != nil {
+ log.Error("Failed to connet database:", err)
+ return err
+ }
+ DbClient.XEngine.SetConnMaxLifetime(DbClient.dbConnMaxLifetime)
+ DbClient.XEngine.SetMaxIdleConns(DbClient.dbMaxIdleConns)
+ DbClient.XEngine.SetMaxOpenConns(DbClient.dbMaxOpenConns)
+ if DbClient.IsShowSQL {
+ DbClient.XEngine.ShowSQL(true)
+ }
+ XEngine = DbClient.XEngine
+
+ return nil
+}
+
+func GetUriSQLArray(r *http.Request) []string {
+ vars := r.URL.Query()
+ s, ok := vars["SQL"]
+ if !ok {
+ log.Info("SQL is not exist")
+ return nil
+ }
+
+ var sa []string
+ for _, r := range s {
+ if r != "" {
+ sa = append(sa, r)
+ }
+ }
+
+ log.Debug("SQL array:", sa)
+ return sa
+}
+
+// Get table name from SQL
+func GetTableNameFromSQL(s string) string {
+ ls := strings.ToLower(s)
+ i1 := strings.Index(ls, "from")
+ i2 := strings.Index(ls, "where")
+
+ var ts string
+ if i1 > 0 {
+ if i2 > 0 && i2 > i1 {
+ ts = ls[i1+4 : i2]
+ }
+ if i2 < 0 {
+ ts = ls[i1+4:]
+ }
+ }
+
+ tn := strings.Trim(ts, " ")
+ log.Debug("i1:", i1, "i2:", i2, "tn:", tn)
+ return tn
+}
+
+func GetTableName(sql string) string {
+ ls := strings.ToLower(sql)
+
+ re := regexp.MustCompile(`from\s+(\S+)`)
+ matches := re.FindStringSubmatch(ls)
+ if len(matches) < 2 {
+ return ""
+ }
+ return matches[1]
+}
+
+func IsQuerySQL(s string) bool {
+ ts := strings.Trim(strings.ToLower(s), " ")
+ if strings.Index(ts, "select") != 0 {
+ return false
+ }
+ return true
+}
+
+// xorm Get data from database
+func ExtDatabaseExecSQL(w http.ResponseWriter, r *http.Request) {
+ log.Debug("ExtDatabaseExecSQL processing... ")
+
+ var sql []string
+ var err error
+
+ _, err = services.CheckExtValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ tblName := vars["dataObject"]
+ sql = GetUriSQLArray(r)
+ // select as must, todo ...
+
+ if sql == nil {
+ wc := services.GetUriLocString(r)
+ if wc == "" {
+ sql = append(sql, fmt.Sprintf("select * from %s", tblName))
+ } else {
+ sql = append(sql, fmt.Sprintf("select * from %s where %s", tblName, wc))
+ }
+ }
+
+ ls := services.ExtGetUriPageLimitString(r)
+
+ // data := make([]map[string]interface{}, 0)
+ // xormResponse := make([]map[string]interface{}, len(sql))
+ var xormResponse XormResponse
+ data := make([]map[string]interface{}, 0)
+ for i, s := range sql {
+ log.Tracef("SQL[%d]: %s", i, sql[i])
+
+ rows := make([]map[string]interface{}, 0)
+ mapRows := make(map[string]interface{})
+
+ if s != "" {
+ // err = XEngine.SQL(s).Find(&rows)
+ // if IsQuerySQL(s) == false {
+ // services.ResponseNotAcceptable406QuerySQLError(w)
+ // return
+ // }
+
+ querySQL := s
+ if i == (len(sql) - 1) {
+ querySQL = querySQL + " " + ls
+ }
+ log.Debug("querySQL:", querySQL)
+ rows, err = DbClient.XEngine.QueryInterface(querySQL)
+ if err != nil {
+ log.Error("SQL failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+ tableName := GetTableName(s)
+ log.Debugf("s:%s tableName:%s", s, tableName)
+ mapRows[tableName] = rows
+ data = append(data, mapRows)
+ log.Trace("data:", data)
+ }
+ i++
+ }
+ xormResponse.Data = data
+
+ services.ResponseWithJson(w, http.StatusOK, xormResponse)
+}
+
+// xorm Get data from database
+func ExtDatabaseGetData(w http.ResponseWriter, r *http.Request) {
+ log.Debug("ExtDatabaseGetData processing... ")
+
+ var sql []string
+ token, err := services.CheckExtValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ dbname := vars["dataStorage"]
+ tbname := vars["dataObject"]
+
+ log.Debugf("token:%s, method:%s, dbname:%s, tbname:%s", token, r.Method, dbname, tbname)
+ exist, err := dborm.IsPermissionDeny(token, strings.ToLower(r.Method), dbname, tbname)
+ if err != nil {
+ log.Error("Failed to get permission:", err)
+ services.ResponseForbidden403NotPermission(w)
+ return
+ }
+ if !exist {
+ log.Error("Not permission!")
+ services.ResponseForbidden403NotPermission(w)
+ return
+ }
+
+ sql = GetUriSQLArray(r)
+ // select as must, todo ...
+ if sql == nil {
+ wc := services.GetUriLocString(r)
+ if wc == "" {
+ sql = append(sql, fmt.Sprintf("select * from %s", tbname))
+ } else {
+ sql = append(sql, fmt.Sprintf("select * from %s where %s", tbname, wc))
+ }
+ }
+
+ ls := services.ExtGetUriPageLimitString(r)
+
+ // data := make([]map[string]interface{}, 0)
+ // xormResponse := make([]map[string]interface{}, len(sql))
+ var xormResponse XormResponse
+ data := make([]map[string]interface{}, 0)
+ for i, s := range sql {
+ log.Tracef("SQL[%d]: %s", i, sql[i])
+
+ rows := make([]map[string]interface{}, 0)
+ mapRows := make(map[string]interface{})
+
+ if s != "" {
+ // err = XEngine.SQL(s).Find(&rows)
+ if IsQuerySQL(s) == false {
+ services.ResponseNotAcceptable406QuerySQLError(w)
+ return
+ }
+
+ querySQL := s
+ if i == (len(sql) - 1) {
+ querySQL = querySQL + " " + ls
+ }
+ log.Debug("querySQL:", querySQL)
+ rows, err = DbClient.XEngine.QueryInterface(querySQL)
+ if err != nil {
+ log.Error("SQL failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+ tableName := GetTableName(s)
+ log.Debugf("s:%s tableName:%s", s, tableName)
+ mapRows[tableName] = rows
+ data = append(data, mapRows)
+ log.Trace("data:", data)
+ }
+ i++
+ }
+ xormResponse.Data = data
+
+ services.ResponseWithJson(w, http.StatusOK, xormResponse)
+}
+
+func ExtDatabaseInsertData(w http.ResponseWriter, r *http.Request) {
+ log.Debug("ExtDatabaseInsertData processing... ")
+
+ token, err := services.CheckExtValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen)) //io.LimitReader限制大小
+ if err != nil {
+ log.Error("io.ReadAll failed:", err)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ vars := mux.Vars(r)
+ dbname := vars["dataStorage"]
+ tbname := vars["dataObject"]
+
+ log.Debugf("token:%s, method:%s, dbname:%s, tbname:%s", token, r.Method, dbname, tbname)
+ exist, err := dborm.IsPermissionDeny(token, strings.ToLower(r.Method), dbname, tbname)
+ if err != nil {
+ log.Error("Failed to get permission:", err)
+ services.ResponseForbidden403NotPermission(w)
+ return
+ }
+ if !exist {
+ log.Error("Not permission!")
+ services.ResponseForbidden403NotPermission(w)
+ return
+ }
+
+ log.Debug("Request body:", string(body), "dataObject:", tbname)
+ insertData := make(map[string]interface{})
+ _ = json.Unmarshal(body, &insertData)
+
+ tn, sql := dborm.ConstructInsertSQL(tbname, insertData)
+ log.Tracef("tn: %s sql :%s", tn, sql)
+ xSession := DbClient.XEngine.NewSession()
+ defer xSession.Close()
+ var affected int64
+ for _, s := range sql {
+ res, err := xSession.Exec(s)
+ if err != nil {
+ log.Error("Insert failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+ n, _ := res.RowsAffected()
+ affected = affected + n
+ }
+ xSession.Commit()
+ // affected, err := InsertDataWithJson(insertData)
+ mapRow := make(map[string]interface{})
+ row := map[string]interface{}{"affectedRows": affected}
+ mapRow[tn] = row
+ // xormResponse.Data = mapRow
+ services.ResponseWithJson(w, http.StatusOK, mapRow)
+}
+
+func ExtDatabaseUpdateData(w http.ResponseWriter, r *http.Request) {
+ log.Debug("ExtDatabaseUpdateData processing... ")
+
+ token, err := services.CheckExtValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ dbname := vars["dataStorage"]
+ tbname := vars["dataObject"]
+
+ log.Debugf("token:%s, method:%s, dbname:%s, tbname:%s", token, r.Method, dbname, tbname)
+ exist, err := dborm.IsPermissionDeny(token, strings.ToLower(r.Method), dbname, tbname)
+ if err != nil {
+ log.Error("Failed to get permission:", err)
+ services.ResponseForbidden403NotPermission(w)
+ return
+ }
+ if !exist {
+ log.Error("Not permission!")
+ services.ResponseForbidden403NotPermission(w)
+ return
+ }
+
+ body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
+ if err != nil {
+ log.Error("io.ReadAll is failed:", err)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ wc := services.GetUriLocString(r)
+
+ log.Debug("Request body:", string(body), "Tablename:", tbname, "wc:", wc)
+ updateData := make(map[string]interface{})
+ _ = json.Unmarshal(body, &updateData)
+
+ tn, sql := dborm.ConstructUpdateSQL(tbname, updateData, wc)
+ log.Tracef("tn: %s sql :%s", tn, sql)
+ xSession := DbClient.XEngine.NewSession()
+ defer xSession.Close()
+ var affected int64
+ for _, s := range sql {
+ res, err := xSession.Exec(s)
+ if err != nil {
+ log.Error("Update failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+ n, _ := res.RowsAffected()
+ affected = affected + n
+ }
+ xSession.Commit()
+ mapRow := make(map[string]interface{})
+ row := map[string]interface{}{"affectedRows": affected}
+ mapRow[tn] = row
+ services.ResponseWithJson(w, http.StatusOK, mapRow)
+}
+
+func ExtDatabaseDeleteData(w http.ResponseWriter, r *http.Request) {
+ log.Debug("ExtDatabaseDeleteData processing... ")
+
+ token, err := services.CheckExtValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ dbname := vars["dataStorage"]
+ tbname := vars["dataObject"]
+
+ log.Debugf("token:%s, method:%s, dbname:%s, tbname:%s", token, r.Method, dbname, tbname)
+ exist, err := dborm.IsPermissionDeny(token, strings.ToLower(r.Method), dbname, tbname)
+ if err != nil {
+ log.Error("Failed to get permission:", err)
+ services.ResponseForbidden403NotPermission(w)
+ return
+ }
+ if !exist {
+ log.Error("Not permission!")
+ services.ResponseForbidden403NotPermission(w)
+ return
+ }
+
+ wc := services.GetUriLocString(r)
+
+ log.Debug("Table name:", tbname, "wc:", wc)
+
+ sql := dborm.ConstructDeleteSQL(tbname, wc)
+ xSession := DbClient.XEngine.NewSession()
+ defer xSession.Close()
+ res, err := xSession.Exec(sql)
+ if err != nil {
+ log.Error("Update failed, err:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+ affected, _ := res.RowsAffected()
+ xSession.Commit()
+ mapRow := make(map[string]interface{})
+ row := map[string]interface{}{"affectedRows": affected}
+ mapRow["data"] = row
+ services.ResponseWithJson(w, http.StatusOK, mapRow)
+}
+
+// xorm Get data from database
+func DatabaseGetData(w http.ResponseWriter, r *http.Request) {
+ log.Debug("DatabaseGetData processing... ")
+
+ var sql []string
+ var err error
+
+ _, err = services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ tblName := vars["tableName"]
+ sql = GetUriSQLArray(r)
+ // select as must, todo ...
+
+ if sql == nil {
+ wc := services.GetUriWhereString(r)
+ if wc == "" {
+ sql = append(sql, fmt.Sprintf("select * from %s", tblName))
+ } else {
+ sql = append(sql, fmt.Sprintf("select * from %s where %s", tblName, wc))
+ }
+ }
+
+ ls := services.GetUriPageLimitString(r)
+
+ // data := make([]map[string]interface{}, 0)
+ // xormResponse := make([]map[string]interface{}, len(sql))
+ var xormResponse XormResponse
+ data := make([]map[string]interface{}, 0)
+ for i, s := range sql {
+ log.Tracef("SQL[%d]: %s", i, sql[i])
+
+ rows := make([]map[string]interface{}, 0)
+ mapRows := make(map[string]interface{})
+
+ if s != "" {
+ // err = XEngine.SQL(s).Find(&rows)
+ if IsQuerySQL(s) == false {
+ services.ResponseNotAcceptable406QuerySQLError(w)
+ return
+ }
+
+ querySQL := s
+ if i == (len(sql) - 1) {
+ querySQL = querySQL + " " + ls
+ }
+ log.Debug("querySQL:", querySQL)
+ rows, err = DbClient.XEngine.QueryInterface(querySQL)
+ if err != nil {
+ log.Error("SQL failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+ tableName := GetTableName(s)
+ log.Debugf("s:%s tableName:%s", s, tableName)
+ mapRows[tableName] = rows
+ data = append(data, mapRows)
+ log.Trace("data:", data)
+ }
+ i++
+ }
+ xormResponse.Data = data
+
+ services.ResponseWithJson(w, http.StatusOK, xormResponse)
+}
+
+func DatabaseInsertData(w http.ResponseWriter, r *http.Request) {
+ log.Debug("DatabaseInsertData processing... ")
+
+ body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen)) //io.LimitReader限制大小
+ if err != nil {
+ log.Error("io.ReadAll failed:", err)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ vars := mux.Vars(r)
+ tableName := vars["tableName"]
+ log.Debug("Request body:", string(body), "tableName:", tableName)
+ insertData := make(map[string]interface{})
+ _ = json.Unmarshal(body, &insertData)
+
+ tn, sql := dborm.ConstructInsertSQL(tableName, insertData)
+ log.Tracef("tn: %s sql :%s", tn, sql)
+ xSession := DbClient.XEngine.NewSession()
+ defer xSession.Close()
+ var affected int64
+ for _, s := range sql {
+ res, err := xSession.Exec(s)
+ if err != nil {
+ log.Error("Insert failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+ n, _ := res.RowsAffected()
+ affected = affected + n
+ }
+ xSession.Commit()
+ // affected, err := InsertDataWithJson(insertData)
+ mapRow := make(map[string]interface{})
+ row := map[string]interface{}{"affectedRows": affected}
+ mapRow[tn] = row
+ // xormResponse.Data = mapRow
+ services.ResponseWithJson(w, http.StatusOK, mapRow)
+}
+
+func DatabaseUpdateData(w http.ResponseWriter, r *http.Request) {
+ log.Debug("DatabaseUpdateData processing... ")
+
+ body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
+ if err != nil {
+ log.Error("io.ReadAll is failed:", err)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ vars := mux.Vars(r)
+ tblName := vars["tableName"]
+ wc := services.GetUriWhereString(r)
+
+ log.Debug("Request body:", string(body), "Table name:", tblName, "wc:", wc)
+ updateData := make(map[string]interface{})
+ _ = json.Unmarshal(body, &updateData)
+
+ tn, sql := dborm.ConstructUpdateSQL(tblName, updateData, wc)
+ log.Tracef("tn: %s sql :%s", tn, sql)
+ xSession := DbClient.XEngine.NewSession()
+ defer xSession.Close()
+ var affected int64
+ for _, s := range sql {
+ res, err := xSession.Exec(s)
+ if err != nil {
+ log.Error("Update failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+ n, _ := res.RowsAffected()
+ affected = affected + n
+ }
+ xSession.Commit()
+ mapRow := make(map[string]interface{})
+ row := map[string]interface{}{"affectedRows": affected}
+ mapRow[tn] = row
+ services.ResponseWithJson(w, http.StatusOK, mapRow)
+}
+
+func DatabaseDeleteData(w http.ResponseWriter, r *http.Request) {
+ log.Debug("DatabaseDeleteData processing... ")
+
+ vars := mux.Vars(r)
+ tblName := vars["tableName"]
+ wc := services.GetUriWhereString(r)
+
+ log.Debug("Table name:", tblName, "wc:", wc)
+
+ sql := dborm.ConstructDeleteSQL(tblName, wc)
+ xSession := DbClient.XEngine.NewSession()
+ defer xSession.Close()
+ res, err := xSession.Exec(sql)
+ if err != nil {
+ log.Error("Update failed, err:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+ affected, _ := res.RowsAffected()
+ xSession.Commit()
+ mapRow := make(map[string]interface{})
+ row := map[string]interface{}{"affectedRows": affected}
+ mapRow["data"] = row
+ services.ResponseWithJson(w, http.StatusOK, mapRow)
+}
diff --git a/features/file/file.go b/features/file/file.go
new file mode 100644
index 00000000..2ddc9ad2
--- /dev/null
+++ b/features/file/file.go
@@ -0,0 +1,126 @@
+package file
+
+import (
+ "net/http"
+
+ "ems.agt/lib/log"
+ "ems.agt/lib/services"
+ "ems.agt/restagent/config"
+ "github.com/gorilla/mux"
+)
+
+var (
+ // parameter config management
+ UriFile = config.UriPrefix + "/fileManagement/{apiVersion}/{location}/file"
+)
+
+// func init() {
+// routes.Register("POST", UriFile, UploadFile, nil)
+// routes.Register("GET", UriFile, DownloadFile, nil)
+// routes.Register("DELETE", UriFile, DeleteFile, nil)
+// }
+
+func UploadFile(w http.ResponseWriter, r *http.Request) {
+ log.Debug("UploadFile processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Http request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ location := vars["location"]
+ if location == "" {
+ log.Error("location is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ params := r.URL.Query()
+ rename, ok := params["rename"]
+ if !ok {
+ log.Info("rename parameter is not exist")
+ }
+ log.Debug("rename:", rename)
+
+ var path, fileName string
+ if len(rename) > 0 {
+ fileName = rename[0]
+ }
+ if location == "upload" {
+ path = config.GetYamlConfig().OMC.Upload
+ fileName, err = services.HandleUploadFile(r, path, fileName)
+ if err != nil {
+ log.Error("Faile to HandleUploadFile:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ } else {
+ path = config.GetYamlConfig().OMC.FrontUpload
+ fileName, err = services.HandleUploadFile(r, path, fileName)
+ if err != nil {
+ log.Error("Faile to HandleUploadFile:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ }
+ log.Debugf("upload file=%s to path=%s", fileName, path)
+
+ services.ResponseStatusOK204NoContent(w)
+ return
+}
+
+func DownloadFile(w http.ResponseWriter, r *http.Request) {
+ log.Debug("DownloadFile processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ location := vars["location"]
+ if location == "" {
+ log.Error("location is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ params := r.URL.Query()
+ fileNames, ok := params["loc"]
+ if !ok {
+ log.Info("loc parameter is not exist")
+ }
+ var path string
+ if location == "upload" {
+ path = config.GetYamlConfig().OMC.Upload
+ } else {
+ path = config.GetYamlConfig().OMC.FrontUpload
+ }
+ for _, fileName := range fileNames {
+ services.ResponseFileWithNameAndMD5(w, http.StatusOK, fileName, path, "")
+ }
+ return
+}
+
+func DeleteFile(w http.ResponseWriter, r *http.Request) {
+ log.Debug("DeleteFile processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ neType := vars["neType"]
+ if neType == "" {
+ log.Error("neType is empty")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ services.ResponseStatusOK204NoContent(w)
+ return
+}
diff --git a/features/fm/alarm.go b/features/fm/alarm.go
new file mode 100644
index 00000000..90e242cf
--- /dev/null
+++ b/features/fm/alarm.go
@@ -0,0 +1,669 @@
+package fm
+
+import (
+ "database/sql"
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "strconv"
+ "strings"
+ "time"
+
+ "ems.agt/lib/dborm"
+ "ems.agt/lib/global"
+ "ems.agt/lib/log"
+ "ems.agt/lib/services"
+ "ems.agt/restagent/config"
+ "xorm.io/xorm"
+
+ "github.com/go-resty/resty/v2"
+ _ "github.com/go-sql-driver/mysql"
+ "github.com/gorilla/mux"
+)
+
+const (
+ AlarmStatusClear = 0
+ AlarmStatusActive = 1
+)
+
+const (
+ ClearTypeUnclear = 0
+ ClearTypeAutoClear = 1
+ ClearTypeManualClear = 2
+)
+
+const (
+ AckStateUnacked = 0
+ AckStateAcked = 1
+)
+
+const (
+ AlarmTypeCommunicationAlarm = 1
+ AlarmTypeEquipmentAlarm = 2
+ AlarmTypeProcessingFailure = 3
+ AlarmTypeEnvironmentalAlarm = 4
+ AlarmTypeQualityOfServiceAlarm = 5
+)
+
+const (
+ AlarmPerceivedSeverityCritical = 1
+ AlarmPerceivedSeverityMajor = 2
+ AlarmPerceivedSeverityMinor = 3
+ AlarmPerceivedSeverityWarning = 4
+ AlarmPerceivedSeverityEvent = 5
+)
+
+const (
+ AlarmSeqBeginNumber = 1
+)
+
+type Response struct {
+ Data interface{} `json:"data"`
+}
+
+type Alarm struct {
+ AlarmSeq int `json:"alarmSeq"`
+ AlarmId string `json:"alarmId" xorm:"alarm_id"`
+ NeId string `json:"neId"`
+ AlarmCode int `json:"alarmCode"`
+ AlarmTitle string `json:"alarmTitle"`
+ EventTime string `json:"eventTime"`
+ AlarmType string `json:"alarmType"`
+ OrigSeverity string `json:"origSeverity"`
+ PerceivedSeverity string `json:"perceivedSeverity"`
+ PVFlag string `json:"pvFlag" xorm:"pv_flag"`
+ NeName string `json:"neName"`
+ NeType string `json:"neType"`
+ ObjectUid string `json:"objectUid" xorm:"object_uid"`
+ ObjectName string `json:"objectName" xorm:"object_name"`
+ ObjectType string `json:"objectType" xorm:"object_type"`
+ LocationInfo string `json:"locationInfo"`
+ Province string `json:"province"`
+ AlarmStatus int `json:"alarmStatus"`
+ SpecificProblem string `json:"specificProblem"`
+ SpecificProblemID string `json:"specificProblemID" xorm:"specific_problem_id"`
+ AddInfo string `json:"addInfo"`
+
+ AckState int `json:"ackState"`
+ AckTime sql.NullTime `json:"ackTime"`
+ AckUser string `json:"ackUser"`
+ ClearType int `json:"clearType"` // 0: Unclear, 1: Auto clear, 2: Manual clear
+ ClearTime sql.NullTime `json:"clearTime"`
+}
+
+type AlarmLog struct {
+ NeType string `json:"neType" xorm:"ne_type"`
+ NeId string `json:"neId" xorm:"ne_id"`
+ AlarmSeq int `json:"alarmSeq" xorm:"alarm_seq"`
+ AlarmId string `json:"alarmId" xorm:"alarm_id"`
+ AlarmCode int `json:"alarmCode" xorm:"alarm_code"`
+ AlarmStatus int `json:"alarmStatus" xorm:"alarm_status"`
+ EventTime string `json:"eventTime" xorm:"event_time"`
+ // ClearTime sql.NullTime `json:"clearTime" xorm:"clear_time"`
+ LogTime string `json:"logTime" xorm:"-"`
+}
+
+var (
+ // alarm management
+ UriAlarms = config.UriPrefix + "/faultManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/alarms"
+ UriAlarmsFmt = config.UriPrefix + "/faultManagement/v1/elementType/%s/objectType/alarms"
+)
+
+var xEngine *xorm.Engine
+
+type DatabaseClient struct {
+ dbType string
+ dbUrl string
+ dbConnMaxLifetime time.Duration
+ dbMaxIdleConns int
+ dbMaxOpenConns int
+ IsShowSQL bool
+
+ XEngine *xorm.Engine
+}
+
+var DbClient DatabaseClient
+
+func InitDbClient(dbType, dbUser, dbPassword, dbHost, dbPort, dbName string) error {
+ DbClient.dbUrl = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8&parseTime=true&loc=Local",
+ dbUser, dbPassword, dbHost, dbPort, dbName)
+ DbClient.dbType = dbType
+ DbClient.dbConnMaxLifetime = 0
+ DbClient.dbMaxIdleConns = 0
+ DbClient.dbMaxOpenConns = 0
+ if log.GetLevel() == log.LOG_TRACE {
+ DbClient.IsShowSQL = true
+ }
+ log.Debugf("dbType:%s dbUrl:%s:******@tcp(%s:%s)/%s??charset=utf8&parseTime=true&loc=Local",
+ dbType, dbUser, dbHost, dbPort, dbName)
+
+ var err error
+ DbClient.XEngine, err = xorm.NewEngine(DbClient.dbType, DbClient.dbUrl)
+ if err != nil {
+ log.Error("Failed to connet database:", err)
+ return err
+ }
+ DbClient.XEngine.SetConnMaxLifetime(DbClient.dbConnMaxLifetime)
+ DbClient.XEngine.SetMaxIdleConns(DbClient.dbMaxIdleConns)
+ DbClient.XEngine.SetMaxOpenConns(DbClient.dbMaxOpenConns)
+ if DbClient.IsShowSQL {
+ DbClient.XEngine.ShowSQL(true)
+ }
+ xEngine = DbClient.XEngine
+
+ return nil
+}
+
+func XormConnectDatabase(dbType, dbUser, dbPassword, dbHost, dbPort, dbName string) (*xorm.Engine, error) {
+ sqlStr := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8&parseTime=true&loc=Local",
+ dbUser, dbPassword, dbHost, dbPort, dbName)
+ log.Debugf("dbType:%s Connect to:%s:******@tcp(%s:%s)/%s?charset=utf8&parseTime=true&loc=Local",
+ dbType, dbUser, dbHost, dbPort, dbName)
+ var err error
+ xEngine, err = xorm.NewEngine(dbType, sqlStr) //1、Create xorm engine
+ if err != nil {
+ log.Error("Failed to connect database:", err)
+ return nil, err
+ }
+ if log.GetLevel() == log.LOG_TRACE {
+ xEngine.ShowSQL(true)
+ }
+ return xEngine, nil
+}
+
+func IsNeedToAckAlarm(valueJson *dborm.ValueJson, alarm *Alarm) bool {
+ log.Info("IsNeedToAckAlarm processing... ")
+ if valueJson != nil {
+ status, _ := strconv.Atoi(valueJson.AlarmStatus)
+ log.Tracef("alarm.AlarmStatus=%d, alarm.AlarmType=%s, alarm.OrigSeverity=%s", alarm.AlarmStatus, alarm.AlarmType, alarm.OrigSeverity)
+ log.Tracef("status=%d, valueJson.AlarmType=%s, valueJson.OrigSeverity=%s", status, valueJson.AlarmType, valueJson.OrigSeverity)
+
+ if alarm.AlarmStatus == status &&
+ alarm.AlarmType == valueJson.AlarmType &&
+ alarm.OrigSeverity == valueJson.OrigSeverity {
+ return true
+ }
+ }
+
+ return false
+}
+
+func SetAlarmAckInfo(valueJson *dborm.ValueJson, alarm *Alarm) {
+ log.Info("SetAlarmAckInfo processing... ")
+ alarm.AckState = AckStateAcked
+ alarm.AckTime.Valid = true
+ alarm.AckTime.Time = time.Now()
+ alarm.AckUser = valueJson.AckUser
+}
+
+// process alarm post message from NFs
+func PostAlarmFromNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("PostAlarmFromNF processing... ")
+
+ vars := mux.Vars(r)
+ apiVer := vars["apiVersion"]
+ if apiVer != global.ApiVersionV1 {
+ log.Error("Uri api version is invalid. apiVersion:", apiVer)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
+ if err != nil {
+ log.Error("io.ReadAll is failed:", err)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ log.Debug("Request body:", string(body))
+ alarmArray := new([]Alarm)
+
+ err = json.Unmarshal(body, &alarmArray)
+ if err != nil {
+ log.Error("Failed to Unmarshal:", err)
+ services.ResponseBadRequest400InvalidJson(w)
+ return
+ }
+
+ valueJson, err := dborm.XormGetAAConfig()
+ if err != nil {
+ log.Error("Failed to XormGetAAConfig:", err)
+ //services.ResponseInternalServerError500ProcessError(w, err)
+ //return
+ }
+ log.Debug("valueJson:", valueJson)
+ session := xEngine.NewSession()
+ defer session.Close()
+ for _, alarmData := range *alarmArray {
+ log.Debug("alarmData:", alarmData)
+ if alarmData.AlarmStatus == AlarmStatusClear {
+ alarmData.ClearType = ClearTypeAutoClear
+ alarmData.ClearTime.Valid = true
+ tm, _ := time.Parse(time.RFC3339, alarmData.EventTime)
+ log.Debugf("EventTime:%s tm:%d tm-datetime:%s", alarmData.EventTime, tm, tm.Local().Format(time.DateTime))
+ alarmData.ClearTime.Time = tm
+ if IsNeedToAckAlarm(valueJson, &alarmData) == true {
+ SetAlarmAckInfo(valueJson, &alarmData)
+ affected, err := session.Where("ne_type=? and ne_id=? and alarm_id=? and alarm_status=1", alarmData.NeType, alarmData.NeId, alarmData.AlarmId).
+ Cols("alarm_status", "clear_type", "clear_time", "ack_state", "ack_time", "ack_user").
+ Update(alarmData)
+ if err != nil && affected <= 0 {
+ log.Error("Failed to update alarm data:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ continue
+ }
+ } else {
+ affected, err := session.Where("ne_type=? and ne_id=? and alarm_id=? and alarm_status=1", alarmData.NeType, alarmData.NeId, alarmData.AlarmId).
+ Cols("alarm_status", "clear_type", "clear_time").
+ Update(alarmData)
+ if err != nil && affected <= 0 {
+ log.Error("Failed to update alarm data:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ continue
+ }
+ }
+ log.Debug("alarmData:", alarmData)
+ var currentSeq string
+ var seq int
+ has, err := xEngine.Table("alarm").
+ Where("ne_type=? and ne_id=?", alarmData.NeType, alarmData.NeId).
+ Desc("alarm_seq").
+ Cols("alarm_seq").
+ Limit(1).
+ Get(¤tSeq)
+ if err != nil {
+ log.Error("Failed to get alarm:", err)
+ continue
+ }
+ if has == true {
+ seq, _ = strconv.Atoi(currentSeq)
+ }
+
+ eventTime := global.GetFmtTimeString(time.RFC3339, alarmData.EventTime, time.DateTime)
+ alarmLog := new(AlarmLog)
+ alarmLog.NeType = alarmData.NeType
+ alarmLog.NeId = alarmData.NeId
+ alarmLog.AlarmSeq = seq
+ alarmLog.AlarmId = alarmData.AlarmId
+ alarmLog.AlarmCode = alarmData.AlarmCode
+ alarmLog.AlarmStatus = alarmData.AlarmStatus
+ alarmLog.EventTime = eventTime
+ log.Debug("alarmLog:", alarmLog)
+
+ affected, err := session.Insert(alarmLog)
+ if err != nil && affected <= 0 {
+ log.Error("Failed to insert alarm_log:", err)
+ }
+
+ // todo: PerceivedSeverity set color
+ var severity string
+ has, err = xEngine.Table("alarm").
+ Where("ne_type=? and ne_id=? and event_time=? and alarm_status=1", alarmData.NeType, alarmData.NeId, alarmData.EventTime).
+ //OrderBy("FIELD(orig_severity, 'Critical', 'Major', 'Minor', 'Warning', 'Event') ASC").
+ Asc("orig_severity").
+ Cols("orig_severity").
+ Limit(1).
+ Get(&severity)
+ if err != nil {
+ log.Error("Failed to get alarm:", err)
+ continue
+ }
+ log.Debugf("neType=%s, neId=%s, eventTime=%s, severity=%s", alarmData.NeType, alarmData.NeId, alarmData.EventTime, severity)
+
+ if has == true && severity > alarmData.OrigSeverity {
+ // update exist record
+ _, err := session.Table("alarm").
+ Where("ne_type=? and ne_id=? and event_time=? and alarm_status=1", alarmData.NeType, alarmData.NeId, alarmData.EventTime).
+ Update(&Alarm{PerceivedSeverity: severity})
+ if err != nil {
+ log.Error("Failed to update alarm:", err)
+ continue
+ }
+ }
+ // for alarm forward time format
+ alarmData.EventTime = eventTime
+ } else {
+ has, err := xEngine.Table("alarm").
+ Where("alarm_id=? and ne_type=? and ne_id=? and alarm_status=1",
+ alarmData.AlarmId, alarmData.NeType, alarmData.NeId).
+ Exist()
+ if err == nil && has == true {
+ log.Warn("Exist the same alarm")
+ continue
+ }
+
+ var currentSeq string
+ has, err = xEngine.Table("alarm").
+ Where("ne_type=? and ne_id=?", alarmData.NeType, alarmData.NeId).
+ Desc("alarm_seq").
+ Cols("alarm_seq").
+ Limit(1).
+ Get(¤tSeq)
+ if err != nil {
+ log.Error("Failed to get alarm:", err)
+ continue
+ }
+ log.Debugf("neType=%s, neId=%s, currentSeq=%s", alarmData.NeType, alarmData.NeId, currentSeq)
+
+ if has == true {
+ seq, _ := strconv.Atoi(currentSeq)
+ if seq+1 > global.MaxInt32Number {
+ alarmData.AlarmSeq = AlarmSeqBeginNumber
+ } else {
+ alarmData.AlarmSeq = seq + 1
+ }
+ } else {
+ alarmData.AlarmSeq = AlarmSeqBeginNumber
+ }
+
+ // todo: PerceivedSeverity set color
+ var severity string
+ has, err = xEngine.Table("alarm").
+ Where("ne_type=? and ne_id=? and event_time=? and alarm_status=1", alarmData.NeType, alarmData.NeId, alarmData.EventTime).
+ //OrderBy("FIELD(orig_severity, 'Critical', 'Major', 'Minor', 'Warning', 'Event') ASC").
+ Asc("orig_severity").
+ Cols("orig_severity").
+ Limit(1).
+ Get(&severity)
+ if err != nil {
+ log.Error("Failed to get alarm:", err)
+ continue
+ }
+ log.Debugf("neType=%s, neId=%s, eventTime=%s, severity=%s", alarmData.NeType, alarmData.NeId, alarmData.EventTime, severity)
+
+ if has == false || severity == alarmData.OrigSeverity {
+ alarmData.PerceivedSeverity = alarmData.OrigSeverity
+ } else if severity > alarmData.OrigSeverity {
+ alarmData.PerceivedSeverity = alarmData.OrigSeverity
+ } else {
+ alarmData.PerceivedSeverity = severity
+ // update exist record
+ _, err := session.Table("alarm").
+ Where("ne_type=? and ne_id=? and event_time=? and alarm_status=1", alarmData.NeType, alarmData.NeId, alarmData.EventTime).
+ Update(&Alarm{PerceivedSeverity: alarmData.PerceivedSeverity})
+ if err != nil {
+ log.Error("Failed to update alarm:", err)
+ continue
+ }
+ }
+ eventTime := global.GetFmtTimeString(time.RFC3339, alarmData.EventTime, time.DateTime)
+ alarmData.ObjectUid = alarmData.NeId
+ alarmData.ObjectType = "VNFM"
+ alarmData.EventTime = eventTime
+ if IsNeedToAckAlarm(valueJson, &alarmData) == true {
+ SetAlarmAckInfo(valueJson, &alarmData)
+ }
+ log.Debug("alarmData:", alarmData)
+ affected, err := session.Insert(alarmData)
+ if err != nil && affected <= 0 {
+ log.Error("Failed to insert alarm data:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ continue
+ }
+ alarmLog := new(AlarmLog)
+ alarmLog.NeType = alarmData.NeType
+ alarmLog.NeId = alarmData.NeId
+ alarmLog.AlarmSeq = alarmData.AlarmSeq
+ alarmLog.AlarmId = alarmData.AlarmId
+ alarmLog.AlarmCode = alarmData.AlarmCode
+ alarmLog.AlarmStatus = alarmData.AlarmStatus
+ alarmLog.EventTime = eventTime
+ log.Debug("alarmLog:", alarmLog)
+
+ affected, err = session.Insert(alarmLog)
+ if err != nil && affected <= 0 {
+ log.Error("Failed to insert alarm_log:", err)
+ }
+ }
+ if config.GetYamlConfig().Alarm.ForwardAlarm {
+ if err = AlarmEmailForward(&alarmData); err != nil {
+ log.Error("Failed to AlarmEmailForward:", err)
+ }
+ if err = AlarmForwardBySMS(&alarmData); err != nil {
+ log.Error("Failed to AlarmForwardBySMS:", err)
+ }
+ }
+ }
+
+ session.Commit()
+ services.ResponseStatusOK200Null(w)
+}
+
+// process alarm get from NFs
+func GetAlarmFromNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("GetAlarmFromNF processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ //var neInfo *dborm.NeInfo
+ var nes []dborm.NeInfo
+ _, err = dborm.XormGetAllNeInfo(&nes)
+ if err != nil {
+ log.Error("Failed to get all ne info:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+
+ for _, ne := range nes {
+ hostUri := fmt.Sprintf("http://%s:%v", ne.Ip, ne.Port)
+ apiUri := fmt.Sprintf(UriAlarmsFmt, strings.ToLower(ne.NeType))
+ requestURI2NF := fmt.Sprintf("%s%s", hostUri, apiUri)
+ log.Debug("requestURI2NF: Get ", requestURI2NF)
+ client := resty.New()
+ response, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ Get(requestURI2NF)
+ if err != nil {
+ log.Error("Failed to Get:", err)
+ //services.ResponseInternalServerError500ProcessError(w, err)
+ continue
+ }
+ body := response.Body()
+ log.Debug("Request body:", string(body))
+ alarmArray := new([]Alarm)
+ _ = json.Unmarshal(body, &alarmArray)
+
+ valueJson, err := dborm.XormGetAAConfig()
+ if err != nil {
+ log.Error("Failed to XormGetAAConfig:", err)
+ //services.ResponseInternalServerError500ProcessError(w, err)
+ continue
+ }
+ session := xEngine.NewSession()
+ defer session.Close()
+ for _, alarmData := range *alarmArray {
+ log.Debug("alarmData:", alarmData)
+ // todo: clear alarm ....
+ if alarmData.AlarmStatus == AlarmStatusClear {
+ exist, err := session.Table("alarm").
+ Where("ne_type=? and ne_id=? and alarm_id=? and alarm_status=1", alarmData.NeType, alarmData.NeId, alarmData.AlarmId).
+ Exist()
+ if err == nil || exist == false {
+ log.Info("Not found active alarm: ne_id=%s, alarm_id=%s", alarmData.NeId, alarmData.AlarmId)
+ continue
+ }
+ alarmData.ClearType = ClearTypeAutoClear
+ alarmData.ClearTime.Valid = true
+ tm, _ := time.Parse(time.RFC3339, alarmData.EventTime)
+ log.Debugf("EventTime:%s tm:%d tm-datetime:%s", alarmData.EventTime, tm, tm.Local().Format(time.DateTime))
+ alarmData.ClearTime.Time = tm
+ if IsNeedToAckAlarm(valueJson, &alarmData) == true {
+ SetAlarmAckInfo(valueJson, &alarmData)
+ log.Debug("alarmData:", alarmData)
+ affected, err := session.
+ Where("ne_type=? and ne_id=? and alarm_id=? and alarm_status=1", alarmData.NeType, alarmData.NeId, alarmData.AlarmId).
+ Cols("alarm_status", "clear_type", "clear_time", "ack_state", "ack_time", "ack_user").
+ Update(alarmData)
+ if err != nil && affected <= 0 {
+ log.Error("Failed to update alarm data:", err)
+ //services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ continue
+ }
+ } else {
+ affected, err := session.
+ Where("ne_type=? and ne_id=? and alarm_id=? and alarm_status=1", alarmData.NeType, alarmData.NeId, alarmData.AlarmId).
+ Cols("alarm_status", "clear_type", "clear_time").
+ Update(alarmData)
+ if err != nil && affected <= 0 {
+ log.Error("Failed to update alarm data:", err)
+ //services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ continue
+ }
+ }
+
+ eventTime := global.GetFmtTimeString(time.RFC3339, alarmData.EventTime, time.DateTime)
+ alarmLog := new(AlarmLog)
+ alarmLog.NeType = alarmData.NeType
+ alarmLog.NeId = alarmData.NeId
+ alarmLog.AlarmSeq = alarmData.AlarmSeq
+ alarmLog.AlarmId = alarmData.AlarmId
+ alarmLog.AlarmCode = alarmData.AlarmCode
+ alarmLog.AlarmStatus = alarmData.AlarmStatus
+ alarmLog.EventTime = eventTime
+ log.Debug("alarmLog:", alarmLog)
+
+ affected, err := session.Insert(alarmLog)
+ if err != nil && affected <= 0 {
+ log.Error("Failed to insert alarm_log:", err)
+ }
+
+ // todo: PerceivedSeverity set color
+ var severity string
+ has, err := xEngine.Table("alarm").
+ Where("ne_type=? and ne_id=? and event_time=? and alarm_status=1", alarmData.NeType, alarmData.NeId, alarmData.EventTime).
+ //OrderBy("FIELD(orig_severity, 'Critical', 'Major', 'Minor', 'Warning', 'Event') ASC").
+ Asc("orig_severity").
+ Cols("orig_severity").
+ Limit(1).
+ Get(&severity)
+ if err != nil {
+ log.Error("Failed to get alarm:", err)
+ continue
+ }
+ log.Debugf("neType=%s, neId=%s, eventTime=%s, severity=%s", alarmData.NeType, alarmData.NeId, alarmData.EventTime, severity)
+
+ if has == true && severity > alarmData.OrigSeverity {
+ // update exist record
+ _, err := session.Table("alarm").
+ Where("ne_type=? and ne_id=? and event_time=?", alarmData.NeType, alarmData.NeId, alarmData.EventTime).
+ Update(&Alarm{PerceivedSeverity: severity})
+ if err != nil {
+ log.Error("Failed to update alarm:", err)
+ continue
+ }
+ }
+
+ // for alarm forward time format
+ alarmData.EventTime = eventTime
+ } else {
+ has, err := xEngine.Table("alarm").
+ Where("alarm_id=? and ne_type=? and ne_id=? and alarm_status=1",
+ alarmData.AlarmId, alarmData.NeType, alarmData.NeId).
+ Exist()
+ if err == nil && has == true {
+ log.Warn("Exist the same alarm")
+ continue
+ }
+
+ var currentSeq string
+ has, err = xEngine.Table("alarm").
+ Where("ne_type=? and ne_id=?", alarmData.NeType, alarmData.NeId).
+ Desc("alarm_seq").
+ Cols("alarm_seq").
+ Limit(1).
+ Get(¤tSeq)
+ if err != nil {
+ log.Error("Failed to get alarm:", err)
+ continue
+ }
+ log.Debugf("neType=%s, neId=%s, currentSeq=%s", alarmData.NeType, alarmData.NeId, currentSeq)
+
+ if has == true {
+ seq, _ := strconv.Atoi(currentSeq)
+ if seq+1 > global.MaxInt32Number {
+ alarmData.AlarmSeq = AlarmSeqBeginNumber
+ } else {
+ alarmData.AlarmSeq = seq + 1
+ }
+ } else {
+ alarmData.AlarmSeq = AlarmSeqBeginNumber
+ }
+
+ // todo: PerceivedSeverity set color
+ var severity string
+ has, err = xEngine.Table("alarm").
+ Where("ne_type=? and ne_id=? and event_time=? and alarm_status=1", alarmData.NeType, alarmData.NeId, alarmData.EventTime).
+ //OrderBy("FIELD(orig_severity, 'Critical', 'Major', 'Minor', 'Warning', 'Event') ASC").
+ Asc("orig_severity").
+ Cols("orig_severity").
+ Limit(1).
+ Get(&severity)
+ if err != nil {
+ log.Error("Failed to get alarm:", err)
+ continue
+ }
+ log.Debugf("neType=%s, neId=%s, eventTime=%s, severity=%s", alarmData.NeType, alarmData.NeId, alarmData.EventTime, severity)
+
+ if has == false || severity == alarmData.OrigSeverity {
+ alarmData.PerceivedSeverity = alarmData.OrigSeverity
+ } else if severity > alarmData.OrigSeverity {
+ alarmData.PerceivedSeverity = alarmData.OrigSeverity
+ } else {
+ alarmData.PerceivedSeverity = severity
+ // update exist record
+ _, err := session.Table("alarm").
+ Where("ne_type=? and ne_id=? and event_time=?", alarmData.NeType, alarmData.NeId, alarmData.EventTime).
+ Update(&Alarm{PerceivedSeverity: alarmData.PerceivedSeverity})
+ if err != nil {
+ log.Error("Failed to update alarm:", err)
+ continue
+ }
+ }
+
+ alarmData.ObjectUid = alarmData.NeId
+ alarmData.ObjectType = "VNFM"
+ alarmData.EventTime = global.GetFmtTimeString(time.RFC3339, alarmData.EventTime, time.DateTime)
+ if IsNeedToAckAlarm(valueJson, &alarmData) == true {
+ SetAlarmAckInfo(valueJson, &alarmData)
+ }
+ log.Debug("alarmData:", alarmData)
+ affected, err := session.Insert(alarmData)
+ if err == nil && affected > 0 {
+ alarmLog := new(AlarmLog)
+ alarmLog.NeType = alarmData.NeType
+ alarmLog.NeId = alarmData.NeId
+ alarmLog.AlarmSeq = alarmData.AlarmSeq
+ alarmLog.AlarmId = alarmData.AlarmId
+ alarmLog.AlarmCode = alarmData.AlarmCode
+ alarmLog.AlarmStatus = alarmData.AlarmStatus
+ alarmLog.EventTime = global.GetFmtTimeString(time.RFC3339, alarmData.EventTime, time.DateTime)
+ log.Debug("alarmLog:", alarmLog)
+ affected, err = session.Insert(alarmLog)
+ if err != nil && affected <= 0 {
+ log.Error("Failed to insert data:", err)
+ //services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ continue
+ }
+ session.Commit()
+ if config.GetYamlConfig().Alarm.ForwardAlarm {
+ if err = AlarmEmailForward(&alarmData); err != nil {
+ log.Error("Failed to AlarmEmailForward:", err)
+ }
+ if err = AlarmForwardBySMS(&alarmData); err != nil {
+ log.Error("Failed to AlarmForwardBySMS:", err)
+ }
+ }
+ }
+ log.Warn("Failed to insert alarm data:", err)
+ }
+ }
+ }
+ services.ResponseStatusOK200Null(w)
+}
diff --git a/features/fm/email.go b/features/fm/email.go
new file mode 100644
index 00000000..79665a2c
--- /dev/null
+++ b/features/fm/email.go
@@ -0,0 +1,111 @@
+package fm
+
+import (
+ "crypto/tls"
+ "errors"
+ "fmt"
+ "strings"
+
+ "ems.agt/lib/dborm"
+ "ems.agt/lib/log"
+ "ems.agt/restagent/config"
+
+ "gopkg.in/gomail.v2"
+)
+
+func AlarmEmailForward(alarmData *Alarm) error {
+ log.Info("AlarmEmailForward processing... ")
+
+ message := `
+
Hello information,
+ test, test
+ Best Wishes!
+ `
+
+ // QQ 邮箱:
+ // SMTP 服务器地址:smtp.qq.com(SSL协议端口:465/994 | 非SSL协议端口:25)
+ // 163 邮箱:
+ // SMTP 服务器地址:smtp.163.com(端口:25)
+ // host := "mail.agrandtech.com"
+ // port := 25
+ // userName := "smtpext@agrandtech.com"
+ // password := "1000smtp@omc!"
+
+ host := config.GetYamlConfig().Alarm.Email.Smtp
+ port := int(config.GetYamlConfig().Alarm.Email.Port)
+ userName := config.GetYamlConfig().Alarm.Email.User
+ password := config.GetYamlConfig().Alarm.Email.Password
+
+ m := gomail.NewMessage()
+ m.SetHeader("From", userName) // 发件人
+ //m.SetHeader("From", "alias"+"<"+"aliastest"+">") // 增加发件人别名
+
+ emails, err := dborm.XormGetAlarmForward("Email")
+ if err != nil {
+ log.Error("Failed to XormGetAlarmForward:", err)
+ return err
+ } else if emails == nil || len(*emails) == 0 {
+ err := errors.New("not found forward email list")
+ log.Error(err)
+ return err
+ }
+
+ forwardLog := &dborm.AlarmForwardLog{
+ NeType: alarmData.NeType,
+ NeID: alarmData.NeId,
+ AlarmID: alarmData.AlarmId,
+ AlarmTitle: alarmData.AlarmTitle,
+ AlarmSeq: alarmData.AlarmSeq,
+ EventTime: alarmData.EventTime,
+ ToUser: strings.Join(*emails, ","),
+ }
+ for _, email := range *emails {
+ m.SetHeader("To", email) // 收件人,可以多个收件人,但必须使用相同的 SMTP 连接
+ }
+
+ //m.SetHeader("To", "zhangshuzhong@agrandtech.com", "simonzhangsz@outlook.com") // 收件人,可以多个收件人,但必须使用相同的 SMTP 连接
+ //m.SetHeader("Cc", "******@qq.com") // 抄送,可以多个
+ //m.SetHeader("Bcc", "******@qq.com") // 暗送,可以多个
+ m.SetHeader("Subject", "Alarm from OMC!") // 邮件主题
+
+ // text/html 的意思是将文件的 content-type 设置为 text/html 的形式,浏览器在获取到这种文件时会自动调用html的解析器对文件进行相应的处理。
+ // 可以通过 text/html 处理文本格式进行特殊处理,如换行、缩进、加粗等等
+ //m.SetBody("text/html", fmt.Sprintf(message, *alarm))
+ m.SetBody("text/html", message)
+
+ // text/plain的意思是将文件设置为纯文本的形式,浏览器在获取到这种文件时并不会对其进行处理
+ // m.SetBody("text/plain", "纯文本")
+ // m.Attach("test.sh") // 附件文件,可以是文件,照片,视频等等
+ // m.Attach("lolcatVideo.mp4") // 视频
+ // m.Attach("lolcat.jpg") // 照片
+
+ d := gomail.NewDialer(
+ host,
+ port,
+ userName,
+ password,
+ )
+ // 关闭SSL协议认证
+ d.TLSConfig = &tls.Config{InsecureSkipVerify: true}
+
+ if err := d.DialAndSend(m); err != nil {
+ operResult := fmt.Sprintf("Failed to DialAndSend:%v", err)
+ log.Error(operResult)
+ forwardLog.OperResult = operResult
+ affected, err := dborm.XormInsertAlarmForwardLog(forwardLog)
+ if err != nil && affected <= 0 {
+ log.Error("Failed to insert data:", err)
+ }
+ return err
+ }
+
+ operResult := fmt.Sprintf("Email sent successfully!:", err)
+ log.Error(operResult)
+ forwardLog.OperResult = operResult
+ affected, err := dborm.XormInsertAlarmForwardLog(forwardLog)
+ if err != nil && affected <= 0 {
+ log.Error("Failed to insert data:", err)
+ return err
+ }
+ return nil
+}
diff --git a/features/fm/smsforward.go b/features/fm/smsforward.go
new file mode 100644
index 00000000..c58e6e5d
--- /dev/null
+++ b/features/fm/smsforward.go
@@ -0,0 +1,103 @@
+package fm
+
+import (
+ "errors"
+ "fmt"
+ "net/http"
+ "net/url"
+
+ "ems.agt/lib/dborm"
+ "ems.agt/lib/log"
+ "ems.agt/restagent/config"
+)
+
+func AlarmForwardBySMS(alarmData *Alarm) error {
+ log.Info("AlarmForwardBySMS processing... ")
+
+ SMSFforwardconfig := config.GetYamlConfig().Alarm.SMS
+ // 阿里云短信API的请求地址
+ apiURL := SMSFforwardconfig.ApiURL
+
+ // 阿里云短信API的AccessKey ID和AccessKey Secret
+ //accessKeyID := SMSFforwardconfig.AccessKeyID
+ accessKeySecret := SMSFforwardconfig.AccessKeySecret
+
+ toUsers, err := dborm.XormGetAlarmForward("SMS")
+ if err != nil {
+ log.Error("Failed to XormGetAlarmForward:", err)
+ return err
+ } else if toUsers == nil {
+ err := errors.New("not found forward phone number")
+ log.Error(err)
+ return err
+ }
+
+ for _, toUser := range *toUsers {
+ // 短信相关参数
+ params := url.Values{}
+ params.Set("PhoneNumbers", toUser)
+ params.Set("SignName", SMSFforwardconfig.SignName)
+ params.Set("TemplateCode", SMSFforwardconfig.TemplateCode)
+ params.Set("TemplateParam", `{"message":"alarm"}`)
+
+ // 构建请求URL
+ reqURL := apiURL + "?Action=SendSms&" + params.Encode()
+
+ // 创建HTTP请求
+ req, err := http.NewRequest("GET", reqURL, nil)
+ if err != nil {
+ log.Error("Failed to create request:", err)
+ return err
+ }
+
+ // 添加请求头部
+ req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+ req.Header.Set("Authorization", "APPCODE "+accessKeySecret)
+
+ forwardLog := &dborm.AlarmForwardLog{
+ NeType: alarmData.NeType,
+ NeID: alarmData.NeId,
+ AlarmID: alarmData.AlarmId,
+ AlarmTitle: alarmData.AlarmTitle,
+ AlarmSeq: alarmData.AlarmSeq,
+ EventTime: alarmData.EventTime,
+ ToUser: toUser,
+ }
+ // 发送请求
+ client := &http.Client{}
+ resp, err := client.Do(req)
+ if err != nil {
+ operResult := fmt.Sprintf("Failed to send request:%v", err)
+ log.Error(operResult)
+ forwardLog.OperResult = operResult
+ affected, err := dborm.XormInsertAlarmForwardLog(forwardLog)
+ if err != nil && affected <= 0 {
+ log.Error("Failed to insert data:", err)
+ }
+ continue
+ }
+ defer resp.Body.Close()
+
+ // 解析响应
+ if resp.StatusCode == http.StatusOK {
+ log.Info("SMS sent successfully!")
+ operResult := fmt.Sprintf("SMS sent successfully!")
+ forwardLog.OperResult = operResult
+ affected, err := dborm.XormInsertAlarmForwardLog(forwardLog)
+ if err != nil && affected <= 0 {
+ log.Error("Failed to insert data:", err)
+ continue
+ }
+ } else {
+ operResult := fmt.Sprintf("Failed to send SMS, StatusCode=%d", resp.StatusCode)
+ log.Error(operResult)
+ forwardLog.OperResult = operResult
+ affected, err := dborm.XormInsertAlarmForwardLog(forwardLog)
+ if err != nil && affected <= 0 {
+ log.Error("Failed to insert data:", err)
+ continue
+ }
+ }
+ }
+ return nil
+}
diff --git a/features/handle/handle.go b/features/handle/handle.go
new file mode 100644
index 00000000..5c71b005
--- /dev/null
+++ b/features/handle/handle.go
@@ -0,0 +1,586 @@
+package handle
+
+import (
+ "bytes"
+ "encoding/json"
+ "io"
+ "net/http"
+ "strconv"
+ "strings"
+
+ "ems.agt/lib/dborm"
+
+ "github.com/gorilla/mux"
+ g "github.com/gosnmp/gosnmp"
+
+ "ems.agt/lib/global"
+ "ems.agt/lib/log"
+ "ems.agt/lib/oauth"
+ "ems.agt/lib/services"
+ "ems.agt/lib/session"
+ "ems.agt/restagent/config"
+)
+
+var TodoList []stTodo
+
+type stTodo struct {
+ No string
+ Item string
+ Value string
+}
+
+type ErrorOAuthResponse struct {
+ Error map[string]interface{}
+}
+
+type FailOAuthResponse struct {
+ Error struct {
+ ErrorCode string
+ ErrorInfo string
+ }
+}
+
+type ApiResponse struct {
+ ResultCode string
+ ResultMessage interface{}
+}
+
+var globalSession = session.NewSessManager("restagent")
+
+func init() {
+ conf := config.GetYamlConfig()
+ // Default is a pointer to a GoSNMP struct that contains sensible defaults
+ // eg port 161, community public, etc
+ g.Default.Target = conf.NE.Addr
+ g.Default.Port = conf.NE.Port
+ err := g.Default.Connect()
+ if err != nil {
+ log.Fatalf("Connect() err: %v", err)
+ }
+ //defer g.Default.Conn.Close()
+}
+
+/*
+func IsValidOAuthInfo(oAuthBody OAuthBody) bool {
+ log.Debug("IsValidOAuthInfo processing... ")
+
+ conf := config.GetYamlConfig()
+ for _, o := range conf.Auth {
+ if oAuthBody.GrantType == o.Type && oAuthBody.UserName == o.User && oAuthBody.Value == o.Password {
+ return true
+ }
+ }
+
+ return false
+}
+
+func IsWrongOAuthInfo(oAuthBody OAuthBody) bool {
+ log.Debug("IsWrongOAuthInfo processing... ")
+
+ if oAuthBody.GrantType == "" || strings.ToLower(oAuthBody.GrantType) != "password" || oAuthBody.UserName == "" || oAuthBody.Value == "" {
+ return true
+ }
+
+ return false
+}
+*/
+
+func IsValidOAuthUri(r *http.Request) bool {
+ vars := mux.Vars(r)
+ Uri := vars["apiCategory"] + "/" + vars["apiVersion"] // 获取Uri
+ if Uri != "securityManagement/v1" {
+ return false
+ }
+
+ return true
+}
+
+func IsVallidContentType(r *http.Request) bool {
+ log.Debug("IsVallidContentType processing ...")
+
+ ctype := r.Header["Content-Type"]
+ if len(ctype) != 0 && !strings.Contains(ctype[0], "application/json") {
+ return false
+ }
+
+ return true
+}
+
+func LoginFromOMC(w http.ResponseWriter, r *http.Request) {
+ log.Debug("LoginFromOMC processing... ")
+
+ body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen)) //io.LimitReader限制大小
+ if err != nil {
+ log.Debug(err)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ // check media type(content type) only support "application/json"
+ /* if !IsVallidContentType(r) {
+ log.Debug("Invalid Content-Type")
+ services.ResponseUnsupportedMediaType415(w)
+ return
+ }
+
+ // check extend uri, response 404
+ if !IsValidOAuthUri(r) {
+ log.Debug("Uri is invalid")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ */
+ // Error process ....
+ // response 400-7
+ if !json.Valid([]byte(body)) {
+ log.Debug("Invalid Json Format")
+ services.ResponseBadRequest400InvalidJson(w)
+ return
+ }
+
+ var oAuthBody oauth.OAuthBody
+ _ = json.Unmarshal(body, &oAuthBody) //转为json
+ log.Debug("body:", string(body), "oAuthBody:", oAuthBody)
+
+ defer r.Body.Close()
+ // response 400-5
+ if oauth.IsWrongOAuthInfo(oAuthBody) {
+ log.Debug("Wrong parameter value")
+ services.ResponseBadRequest400WrongParamValue(w)
+ return
+ }
+ /*
+ if oauth.IsValidOAuthInfo(oAuthBody) {
+ plist := config.GetPermissionFromConfig(oAuthBody.UserName, oAuthBody.GrantType)
+ log.Debug("Permission list:", plist)
+
+ token := globalSession.NewSession(w, r, plist)
+ services.ResponseStatusOK200Login(w, token)
+ } else {
+ // response 400-4
+ log.Debug("Authentication failed, mismatch user or password")
+
+ services.ResponseBadRequest400IncorrectLogin(w)
+ }
+ */
+ validUser, changePassword, _ := dborm.XormCheckLoginUser(oAuthBody.UserName,
+ oAuthBody.Value, config.GetYamlConfig().Auth.Crypt)
+ if validUser {
+ // plist := config.GetPermissionFromConfig(oAuthBody.UserName, oAuthBody.GrantType)
+ plist := []bool{true, true, true, true}
+ log.Debug("Permission list:", plist)
+
+ token := globalSession.NewSession(w, r, plist)
+ services.ResponseStatusOK200Login(w, token, changePassword)
+ } else {
+ // response 400-4
+ log.Error("Authentication failed, mismatch user or password")
+
+ services.ResponseBadRequest400IncorrectLogin(w)
+ }
+ return
+}
+
+func LogoutFromOMC(w http.ResponseWriter, r *http.Request) {
+ log.Debug("LogoutFromOMC processing... ")
+
+ // check media type(content type) only support "application/json"
+ if !IsVallidContentType(r) {
+ log.Debug("Invalid Content-Type")
+ services.ResponseUnsupportedMediaType415(w)
+ return
+ }
+
+ // check extend uri, response 404
+ if !IsValidOAuthUri(r) {
+ log.Debug("Uri is invalid")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ // error processing ...
+ // 401-1 response
+ token, ret := globalSession.IsCarriedToken(r)
+ if ret == false {
+ log.Debug("AccessToken is not carried")
+ services.ResponseUnauthorized401AccessTokenNotCarried(w)
+ return
+ }
+
+ // 401-2 response
+ if globalSession.IsValidToken(token) == false {
+ log.Debug("AccessToken fails or does not exist")
+ services.ResponseUnauthorized401AccessTokenNotExist(w)
+ return
+ }
+
+ globalSession.EndSession(w, r)
+ services.ResponseStatusOK200Null(w)
+ return
+}
+
+func HandshakeFromOMC(w http.ResponseWriter, r *http.Request) {
+ log.Debug("HandshakeFromOMC processing... ")
+
+ // check media type(content type) only support "application/json"
+ if !IsVallidContentType(r) {
+ log.Debug("Invalid Content-Type")
+ services.ResponseUnsupportedMediaType415(w)
+ return
+ }
+
+ // check extend uri, response 404
+ if !IsValidOAuthUri(r) {
+ log.Debug("Uri is invalid")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ // error processing ...
+ // 401-1 response
+ token, ret := globalSession.IsCarriedToken(r)
+ if ret == false {
+ log.Debug("AccessToken is not carried")
+ services.ResponseUnauthorized401AccessTokenNotCarried(w)
+ return
+ }
+
+ if !globalSession.ShakeSession(token) {
+ // 401-2 response
+ log.Debug("AccessToken fails or does not exist")
+ services.ResponseUnauthorized401AccessTokenNotExist(w)
+ return
+ }
+
+ // 200 response
+ services.ResponseStatusOK200Null(w)
+ return
+}
+
+var (
+ MAX_RMUID_NUM = config.GetRmUIDMaxNumFromConfig()
+ MAX_ALARMID_NUM = config.GetAlarmIDMaxNumFromConfig()
+ MAX_PMUID_NUM = config.GetPmIDMaxNumFromConfig()
+ MAX_SUBID_NUM = config.GetSubIDMaxNumFromConfig()
+ MAX_URI_LEN = config.GetUriMaxLenFromConfig()
+ RMUID_REGEXP = config.GetRmUIDRegexpFromConfig()
+)
+
+func CheckParameterName(r *http.Request) []string {
+ var errorParams []string
+ vars := r.URL.Query()
+ for k, v := range vars {
+ log.Debug("vars:", k, v)
+ if k != "rmUIDs" && k != "fields" {
+ errorParams = append(errorParams, k)
+ }
+ }
+
+ return errorParams
+}
+
+func GetRmUIDArr(r *http.Request) []string {
+ vars := r.URL.Query()
+ rmUIDs, ok := vars["rmUIDs"]
+ if !ok {
+ log.Debug("rmUIDs is not exist")
+ return nil
+ }
+
+ var rmUIDValues []string
+ for _, r := range rmUIDs {
+ if r != "" {
+ rmUIDValues = global.MergeStringArr(rmUIDValues, strings.Split(r, `,`))
+ }
+ }
+
+ return rmUIDValues
+}
+
+func GetAttrNameArr(r *http.Request) []string {
+ vars := r.URL.Query()
+ fields, ok := vars["fields"]
+ if !ok {
+ log.Debug("attributeNames does not exist")
+ return nil
+ }
+ var attrNames []string
+ for _, a := range fields {
+ if a != "" {
+ attrNames = global.MergeStringArr(attrNames, strings.Split(a, `,`))
+ }
+ }
+
+ return attrNames
+}
+
+func CheckValidRmUID(rmUIDs []string) []string {
+ log.Debug("GetLocalRmUID processing... ")
+
+ var invalidRmUIDs []string
+ for _, r := range rmUIDs {
+ if !global.MatchRmUID(RMUID_REGEXP, r) {
+ invalidRmUIDs = append(invalidRmUIDs, r)
+ }
+ }
+
+ return invalidRmUIDs
+}
+
+func CheckLocalRmUID(rmUIDs []string) string {
+ log.Debug("GetLocalRmUID processing... ")
+
+ rmUID := config.GetRmUIDFromConfig()
+ for _, r := range rmUIDs {
+ if r == rmUID {
+ return rmUID
+ }
+ }
+
+ return ""
+}
+
+func GetNRMByUri(w http.ResponseWriter, r *http.Request) {
+ log.Debug("GetNRMByUri processing... ")
+
+ // response 414-4 uri too long ? (optional)
+ // todo ... ?
+ if bytes.Count([]byte(r.RequestURI), nil) > MAX_URI_LEN {
+ log.Debug("Request Uri too long:", bytes.Count([]byte(r.RequestURI), nil))
+ services.ResponseRequestURITooLong414UriTooLong(w)
+ return
+ }
+
+ // check media type(content type) only support "application/json"
+ // response 415-1
+ if !IsVallidContentType(r) {
+ log.Debug("Invalid Content-Type")
+ services.ResponseUnsupportedMediaType415(w)
+ return
+ }
+
+ // error processing ...
+ // 401-1 response
+ token, ret := globalSession.IsCarriedToken(r)
+ if ret == false {
+ log.Debug("AccessToken is not carried")
+ services.ResponseUnauthorized401AccessTokenNotCarried(w)
+ return
+ }
+
+ // 401-2 response
+ if globalSession.IsValidToken(token) == false {
+ log.Debug("AccessToken fails or does not exist")
+ services.ResponseUnauthorized401AccessTokenNotExist(w)
+ return
+ }
+ // response 403 Forbidden, permissions deny
+ // todo...
+ plist := globalSession.GetPermissionFromSession(token)
+ log.Debug("permission list:", plist)
+ if len(plist) == 0 || plist[0] == false {
+ log.Debug("User permission deny")
+ services.ResponseForbidden403NotPermission(w)
+ return
+ }
+
+ vars := mux.Vars(r)
+ qeuryUri := vars["apiCategory"] + "/" + vars["elementTypeValue"] + "/" + vars["objectTypeValue"]
+ log.Debug("Get by Uri: ", qeuryUri)
+
+ apiVer := vars["apiVersion"]
+ if apiVer != "v1" {
+ log.Debug("Uri is invalid")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ // response 406-1
+ rmUIDValues := GetRmUIDArr(r)
+ if rmUIDValues == nil {
+ log.Debug("missing parameter: rmUIDs")
+ services.ResponseNotAcceptable406MissingParam(w)
+ return
+ }
+
+ // response 406-2
+ errorParams := CheckParameterName(r)
+ if errorParams != nil {
+ log.Debug("parameter name error: ", errorParams)
+ services.ResponseNotAcceptable406ParamError(w, errorParams)
+ return
+ }
+
+ // response 400-5
+ if len(rmUIDValues) == 0 {
+ log.Debug("rmUIDs is wrong or NULL")
+ services.ResponseBadRequest400WrongParamValue(w)
+ return
+ }
+
+ // response 414-1
+ if len(rmUIDValues) > MAX_RMUID_NUM {
+ log.Debug("rmUID greater than", MAX_RMUID_NUM)
+ services.ResponseRequestURITooLong414NRMNumExceed(w, MAX_RMUID_NUM)
+ return
+ }
+
+ // response 400-1
+ // check rmUID is valid
+ // todo ...
+ invalidRmUIDs := CheckValidRmUID(rmUIDValues)
+ if len(invalidRmUIDs) != 0 {
+ log.Debug("rmUID is invalid")
+ services.ResponseBadRequest400RmUIDsIsInvalid(w, invalidRmUIDs)
+ return
+ }
+
+ // response 404-2
+ rmUID := CheckLocalRmUID(rmUIDValues)
+ if rmUID == "" {
+ log.Debug("rmUID does not exist")
+ services.ResponseNotFound404NRMNotExist(w, rmUIDValues)
+ return
+ }
+
+ // response 404-1, uri is not exist in map
+ attrNames := GetAttrNameArr(r)
+ var Oids []string
+ Oids = *config.GetOidByFileds(qeuryUri, attrNames, &Oids)
+ if len(Oids) == 0 {
+ log.Debug("Nothing of config map")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ // response 404-1, uri is not exist in map
+ var nameOids []config.NameOid
+ nameOids = *config.GetDataOidByFields(qeuryUri, attrNames, &nameOids)
+ if len(nameOids) == 0 {
+ log.Debug("Nothing of config map")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ result, err2 := g.Default.Get(Oids) // Get() accepts up to g.MAX_OIDS
+ if err2 != nil {
+ log.Fatalf("Get() err: %v", err2)
+
+ }
+
+ // var nameValues []config.NameValue
+ var nameValue config.NameValue
+
+ nameValues := make(map[string]interface{})
+ nameValues["rmUID"] = rmUID
+ for i, variable := range result.Variables {
+ nameValue.Name = nameOids[i].Name
+ log.Debugf("%d: oid: %s name: %s\n", i, variable.Name, nameValue.Name)
+ // if nameOids[i].Oid == variable.Name && global.IsContain(attributeNames, nameValue.Name) {
+ if nameOids[i].Oid == variable.Name {
+ // the Value of each variable returned by Get() implements
+ // interface{}. You could do a type switch...
+ switch variable.Type {
+ case g.OctetString:
+ bytes := variable.Value.([]byte)
+ log.Debugf("string: %s\n", string(bytes))
+ nameValue.Value = string(bytes)
+ nameValues[nameValue.Name] = nameValue.Value
+ case g.Integer:
+ value := variable.Value.(int)
+ log.Debugf("integer: %d\n", value)
+ nameValue.Value = strconv.Itoa(value)
+ nameValues[nameValue.Name] = nameValue.Value
+ case g.IPAddress:
+ value := variable.Value.(string)
+ log.Debugf("IPAddress: %s\n", variable.Value)
+ nameValue.Value = value
+ nameValues[nameValue.Name] = nameValue.Value
+ default:
+ // ... or often you're just interested in numeric values.
+ // ToBigInt() will return the Value as a BigInt, for plugging
+ // into your calculations.
+ log.Debugf("number: %d\n", g.ToBigInt(variable.Value))
+ }
+ }
+ }
+
+ getResponse := services.DataResponse{nameValues}
+ services.ResponseWithJson(w, http.StatusOK, getResponse)
+}
+
+func RestfulPut(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ queryNo := vars["no"]
+ var targetTodo stTodo
+ for _, Todo := range TodoList {
+ if Todo.No == queryNo {
+ targetTodo = Todo
+ }
+ }
+ response := ApiResponse{"200", targetTodo}
+ services.ResponseWithJson(w, http.StatusOK, response)
+}
+
+func RestfulHead(w http.ResponseWriter, r *http.Request) {
+ var targetTodo stTodo
+
+ response := ApiResponse{"200", targetTodo}
+ services.ResponseWithJson(w, http.StatusOK, response)
+
+}
+
+func RemoveElement(TodoList []stTodo, No string) stTodo {
+ // var targetTodo stTodo
+ j := 0
+ if len(TodoList) == 0 {
+ return TodoList[j]
+ }
+
+ for i := 0; i < len(TodoList); i++ {
+ if TodoList[i].No != No {
+ if i != j {
+ TodoList[i], TodoList[j] = TodoList[j], TodoList[i]
+ }
+ j++
+ }
+ }
+ log.Debug(TodoList[j].No, TodoList[j].Item)
+ return TodoList[j]
+}
+
+func RestfulDelete(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ queryNo := vars["no"] //获取No
+
+ log.Debug("RestfulDelete processing... ")
+
+ targetTodo := RemoveElement(TodoList, queryNo)
+ response := ApiResponse{"200", targetTodo}
+ services.ResponseWithJson(w, http.StatusOK, response)
+}
+
+func RestfulOptions(w http.ResponseWriter, r *http.Request) {
+ var targetTodo stTodo
+
+ response := ApiResponse{"200", targetTodo}
+ services.ResponseWithJson(w, http.StatusOK, response)
+
+}
+
+func RestfulTrace(w http.ResponseWriter, r *http.Request) {
+ var targetTodo stTodo
+
+ response := ApiResponse{"200", targetTodo}
+ services.ResponseWithJson(w, http.StatusOK, response)
+
+}
+
+func RestfulPatch(w http.ResponseWriter, r *http.Request) {
+ var targetTodo stTodo
+
+ response := ApiResponse{"200", targetTodo}
+ services.ResponseWithJson(w, http.StatusOK, response)
+
+}
diff --git a/features/maintenance/maintenance.go b/features/maintenance/maintenance.go
new file mode 100644
index 00000000..e3be001c
--- /dev/null
+++ b/features/maintenance/maintenance.go
@@ -0,0 +1,322 @@
+package maintenance
+
+import (
+ "encoding/json"
+ "fmt"
+ "net/http"
+ "os"
+ "os/exec"
+ "path"
+ "runtime"
+ "time"
+
+ "ems.agt/lib/dborm"
+ "ems.agt/lib/log"
+ "ems.agt/lib/services"
+ "ems.agt/restagent/config"
+ "github.com/shirou/gopsutil/cpu"
+ "github.com/shirou/gopsutil/disk"
+ "github.com/shirou/gopsutil/mem"
+)
+
+// (1) OMC能够对相关的文件系统资源、内存、CPU资源、数据存储空间、数据库空间等系统指标进行监控管理;
+// 对于虚拟化部署OMC系统,能够对虚机内存、虚机CPU、虚拟存储空间、文件系统资源、数据库空间等指标进行监控,提供界面截图 ;
+
+// (2) 系统监控指标的采样时间和阈值可由用户设定,超过阈值将产生不同级别的告警,提供界面截图 ;
+
+// (3) OMC能够方便的查询数据库连接情况;并可手工干预数据库的连接,能方便的终结非法的数据库连接 ;
+
+// (4) 用户能方便的查询系统进程、应用进程等的进程名、进程类型、开始时间、运行主机等信息,提供界面截图
+// (5) 用户能方便的对系统进程、应用进程等做中断或者启动操作,提供界面截图
+
+// (6) 对于文件系统资源、内存、CPU资源、数据存储空间、数据库空间等系统指标数据,要求OMC能够保存至少3个月,提供界面截图 ;
+// (7) 用户可以按照需求自定义报表模板并生成OMC系统维护数据报表,提供界面截图 ;
+
+// (8) OMC具备自身告警管理功能,对于传统OMC系统,如:服务器单电源告警,存储硬盘告警、OMC系统软件故障等;
+// 对于虚拟化OMC系统,如虚机告警、虚拟硬盘告警等,提供界面截图 。
+
+var (
+ // parameter config management
+ Uri = config.UriPrefix + "/maintenance/{apiVersion}/zz"
+
+ // (1) OMC能够对相关的文件系统资源、内存、CPU资源、数据存储空间、数据库空间等系统指标进行监控管理;
+ UriPref = config.UriPrefix + "/maintenance/{apiVersion}/pref"
+
+ // (6) 对于文件系统资源、内存、CPU资源、数据存储空间、数据库空间等系统指标数据,要求OMC能够保存至少3个月,提供界面截图 ;
+ UriPrefLog = config.UriPrefix + "/maintenance/{apiVersion}/prefLog"
+
+ // (2) 系统监控指标的采样时间和阈值可由用户设定,超过阈值将产生不同级别的告警,提供界面截图 ;
+ UriConfig = config.UriPrefix + "/maintenance/{apiVersion}/config"
+
+ // (3) OMC能够方便的查询数据库连接情况;并可手工干预数据库的连接,能方便的终结非法的数据库连接
+ UriSqlClient = config.UriPrefix + "/maintenance/{apiVersion}/sqlClient"
+
+ // (4) 用户能方便的查询系统进程、应用进程等的进程名、进程类型、开始时间、运行主机等信息,提供界面截图
+ // (5) 用户能方便的对系统进程、应用进程等做中断或者启动操作,提供界面截图
+ UriTop = config.UriPrefix + "/maintenance/{apiVersion}/top"
+)
+
+func init() {
+ // 定時收集 TODO
+ prefLogSave("")
+}
+
+func List(w http.ResponseWriter, r *http.Request) {
+ fmt.Println("zz List")
+ services.ResponseStatusOK200Null(w)
+}
+
+// 性能指標
+func prefInfo(dirName string) map[string]any {
+ data := make(map[string]any)
+
+ // 显示文件資源目录
+ dirPath := "D://"
+ if runtime.GOOS == "linux" {
+ dirPath = "/home"
+ }
+ // 訪問下級
+ if dirName != "" {
+ dirPath = path.Join(dirPath, dirName)
+ }
+ dir_list, e := os.ReadDir(dirPath)
+ if e != nil {
+ log.Error(e)
+ }
+ list := make([]map[string]any, 0)
+ for _, v := range dir_list {
+ o, err := v.Info()
+ if err != nil {
+ continue
+ }
+ list = append(list, map[string]any{
+ "name": o.Name(),
+ "size": o.Size(),
+ "mode": o.Mode().String(),
+ "modTime": o.ModTime().Format("2006-01-02 15:04:05"),
+ "isDir": o.IsDir(),
+ })
+ }
+ data["dirList"] = list
+
+ // 文件資源使用率
+ u, _ := disk.Usage(dirPath)
+ usedGB := int(u.Used) / (1024 * 1024 * 1024 * 1)
+ data["dirUse"] = fmt.Sprintf("%d", usedGB)
+
+ // CPU使用率
+ percent, err := cpu.Percent(time.Second, false)
+ if err != nil {
+ log.Error(err)
+ }
+ data["cpuUse"] = fmt.Sprintf("%.2f", percent[0])
+
+ // 内存使用率
+ memInfo, err := mem.VirtualMemory()
+ if err != nil {
+ log.Error(err)
+ }
+ data["memUse"] = memInfo.UsedPercent
+
+ // 獲取數據庫占用空間
+ if dborm.DbClient.XEngine != nil {
+ conf := config.GetYamlConfig()
+ result, err := dborm.DbClient.XEngine.QueryString(`SELECT
+ CONCAT(TRUNCATE(SUM(data_length)/1024/1024,2),'MB') AS data_size,
+ CONCAT(TRUNCATE(SUM(max_data_length)/1024/1024,2),'MB') AS max_data_size,
+ CONCAT(TRUNCATE(SUM(data_free)/1024/1024,2),'MB') AS data_free,
+ CONCAT(TRUNCATE(SUM(index_length)/1024/1024,2),'MB') AS index_size
+ FROM information_schema.tables WHERE TABLE_SCHEMA = ?;
+ `, conf.Database.Name)
+ if err == nil {
+ data["dbInfo"] = result[0]
+ } else {
+ data["dbInfo"] = map[string]string{}
+ }
+ }
+ return data
+}
+
+// 性能指標存入數據庫
+func prefLogSave(dirName string) {
+ if dborm.DbClient.XEngine != nil {
+ data := prefInfo(dirName)
+
+ dirListByte, err := json.Marshal(data["dirList"])
+ if err != nil {
+ log.Error(err)
+ }
+ dbInfoByte, err := json.Marshal(data["dbInfo"])
+ if err != nil {
+ log.Error(err)
+ }
+ rse, err := dborm.DbClient.XEngine.Exec(`INSERT INTO sys_perf_data
+ (id, create_time, dir_used, dir_list, db_info, mem_used, cpu_used)
+ VALUES(NULL, NOW(), ?, ?, ?, ?, ?);
+ `, data["dirUse"], string(dirListByte), string(dbInfoByte), data["memUse"], data["cpuUse"])
+ if err != nil {
+ log.Error(err)
+ }
+ fmt.Println(rse.LastInsertId())
+ }
+}
+
+// GET http://192.168.21.183:3040/api/rest/maintenance/v1/pref?dir=true
+func Pref(w http.ResponseWriter, r *http.Request) {
+ // 知道下級文件資源目录
+ dirName := r.URL.Query().Get("dirName")
+ data := prefInfo(dirName)
+ services.ResponseWithJson(w, http.StatusOK, data)
+}
+
+// GET http://192.168.21.183:3040/api/rest/maintenance/v1/prefLog?pageNum=1&pageSize=10
+func PrefLog(w http.ResponseWriter, r *http.Request) {
+ pageNumb, pageSize := services.GetPageNumSize(r)
+ result, err := dborm.DbClient.XEngine.QueryString("SELECT * FROM sys_perf_data limit ?,?", (pageNumb-1)*pageSize, pageSize)
+ if err != nil {
+ services.ResponseInternalServerError500ProcessError(w, err)
+ }
+ services.ResponseWithJson(w, http.StatusOK, result)
+}
+
+// POST http://192.168.21.183:3040/api/rest/maintenance/v1/config
+func Config(w http.ResponseWriter, r *http.Request) {
+ // json 請求參數獲取
+ var bodyArgs struct {
+ Key string `json:"key"`
+ Value string `json:"value"`
+ }
+ err := services.JSONBody(r, &bodyArgs)
+ if err != nil {
+ log.Error("io.ReadAll is failed:", err)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ // 進行值更新
+ if dborm.DbClient.XEngine != nil {
+ result, err := dborm.DbClient.XEngine.QueryString("SELECT * FROM information_schema.processlist")
+ if err != nil {
+ fmt.Println(err)
+ }
+ fmt.Println(result)
+ rse, err := dborm.DbClient.XEngine.Exec("UPDATE sys_config SET value = ? where id = ?", "true", 100)
+ if err != nil {
+ fmt.Println(err)
+ }
+ fmt.Println(rse)
+ }
+
+ services.ResponseStatusOK200Null(w)
+}
+
+// http://192.168.21.183:3040/api/rest/maintenance/v1/sqlClient?type=close
+// http://192.168.21.183:3040/api/rest/maintenance/v1/sqlClient?type=connet
+// http://192.168.21.183:3040/api/rest/maintenance/v1/sqlClient?type=user
+func SqlClient(w http.ResponseWriter, r *http.Request) {
+ // 关闭
+ isClose := r.URL.Query().Get("type")
+ if isClose == "close" && dborm.DbClient.XEngine != nil {
+ dborm.DbClient.XEngine.Close()
+ }
+
+ // 重连
+ isConnet := r.URL.Query().Get("type")
+ if isConnet == "connet" && dborm.DbClient.XEngine == nil {
+ conf := config.GetYamlConfig()
+ err := dborm.InitDbClient(conf.Database.Type, conf.Database.User, conf.Database.Password,
+ conf.Database.Host, conf.Database.Port, conf.Database.Name)
+ if err != nil {
+ fmt.Println("dborm.initDbClient err:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+ }
+
+ // 查询实例
+ isUser := r.URL.Query().Get("type")
+ if isUser == "user" && dborm.DbClient.XEngine != nil {
+ result, err := dborm.DbClient.XEngine.QueryString("SELECT * FROM information_schema.processlist")
+ if err != nil {
+ fmt.Println(err)
+ }
+ fmt.Println(result)
+ rse, err := dborm.DbClient.XEngine.Exec("KILL CONNECTION CONNECTION_ID()")
+ if err != nil {
+ fmt.Println(err)
+ }
+ fmt.Println(rse)
+ }
+
+ // 进行连接测试
+ err := dborm.DbClient.XEngine.Ping()
+ if err != nil {
+ fmt.Println(err)
+ }
+ services.ResponseStatusOK200Null(w)
+}
+
+// GET http://192.168.21.183:3040/api/rest/maintenance/v1/top?grep=
+func Top(w http.ResponseWriter, r *http.Request) {
+ // 過濾命令
+ grep := r.URL.Query().Get("grep")
+ // 命令拼接
+ var cmd *exec.Cmd
+ switch runtime.GOOS {
+ case "linux":
+ command := "ps -ef "
+ if grep != "" {
+ command += grep
+ }
+ cmd = exec.Command(command)
+ case "windows":
+ command := "wmic process list brief "
+ if grep != "" {
+ command += grep
+ }
+ cmd = exec.Command("cmd", "/C", command)
+ }
+
+ out, err := cmd.CombinedOutput()
+ fmt.Println(string(out))
+ if err != nil {
+ fmt.Println(err)
+ }
+ services.ResponseWithJson(w, http.StatusOK, string(out))
+}
+
+// PATCH http://192.168.21.183:3040/api/rest/maintenance/v1/top?ops=&name=
+func TopOps(w http.ResponseWriter, r *http.Request) {
+ // json 請求參數獲取
+ var bodyArgs struct {
+ Ops string `json:"ops"`
+ Pid string `json:"pid"`
+ }
+ err := services.JSONBody(r, &bodyArgs)
+ if err != nil {
+ log.Error("io.ReadAll is failed:", err)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ // 命令拼接
+ var cmd *exec.Cmd
+ switch runtime.GOOS {
+ case "linux":
+ switch bodyArgs.Ops {
+ case "kill":
+ cmd = exec.Command("kill", "-9", bodyArgs.Pid)
+ }
+ case "windows":
+ switch bodyArgs.Ops {
+ case "kill":
+ cmd = exec.Command("cmd", "/C", "taskkill", "-PID", bodyArgs.Pid, "-F")
+ }
+ }
+
+ out, err := cmd.CombinedOutput()
+ fmt.Println(string(out))
+ if err != nil {
+ fmt.Println(err)
+ }
+ services.ResponseWithJson(w, http.StatusOK, string(out))
+}
diff --git a/features/mml/mml.go b/features/mml/mml.go
new file mode 100644
index 00000000..e7061cd9
--- /dev/null
+++ b/features/mml/mml.go
@@ -0,0 +1,213 @@
+package mml
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "net"
+ "net/http"
+ "strings"
+ "time"
+
+ "ems.agt/lib/dborm"
+ "ems.agt/lib/global"
+ "ems.agt/lib/log"
+ "ems.agt/lib/mmlp"
+ "ems.agt/lib/services"
+ "ems.agt/restagent/config"
+
+ "github.com/gorilla/mux"
+
+ _ "github.com/go-sql-driver/mysql"
+)
+
+const (
+ //经过测试,linux下,延时需要大于100ms
+ TIME_DELAY_AFTER_WRITE = 200
+)
+
+type Response struct {
+ Data []string `json:"data"`
+}
+
+type MMLRequest struct {
+ MML []string `json:"mml"`
+}
+
+var (
+ // MML interface
+ UriMML = config.UriPrefix + "/opeartionManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/mml"
+ UriNeOmMml = config.UriPrefix + "/omManagement/{apiVersion}/mml/{netype}/{neid}"
+ UriOmMmlExt = config.UriPrefix + "/opeartionManagement/{apiVersion}/elementType/OMC/objectType/mml"
+ UriOmMmlInt = config.UriPrefix + "/omManagement/{apiVersion}/mml/{neType}/{neId}"
+)
+
+func PostMMLToNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("PostMMLToNF processing... ")
+
+ vars := mux.Vars(r)
+ neType := vars["elementTypeValue"]
+ params := r.URL.Query()
+ neId := params["ne_id"]
+ if len(neId) == 0 {
+ log.Error("NOT FOUND ne_id")
+ services.ResponseBadRequest400WrongParamValue(w)
+ return
+ }
+ log.Debug("neType:", neType, "neId", neId)
+
+ if strings.ToLower(neType) == "omc" {
+ PostMMLToOMC(w, r)
+ return
+ }
+
+ _, err := services.CheckExtValidRequest(w, r)
+ if err != nil {
+ log.Error("Failed to CheckMmlValidRequest:", err)
+ return
+ }
+
+ neInfo := new(dborm.NeInfo)
+ neInfo, err = dborm.XormGetNeInfo(neType, neId[0])
+ if err != nil {
+ log.Error("dborm.XormGetNeInfo is failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+
+ var buf [8192]byte
+ var n int
+ var mmlResult []string
+
+ if neInfo != nil {
+ hostMML := fmt.Sprintf("%s:%d", neInfo.Ip, config.GetYamlConfig().MML.Port)
+ conn, err := net.Dial("tcp", hostMML)
+ if err != nil {
+ errMsg := fmt.Sprintf("Failed to dial %s: %v", hostMML, err)
+ log.Error(errMsg)
+ mmlResult = append(mmlResult, errMsg)
+ response := Response{mmlResult}
+ services.ResponseWithJson(w, http.StatusOK, response)
+ return
+ }
+
+ loginStr := fmt.Sprintf("%s\n%s\n", config.GetYamlConfig().MML.User, config.GetYamlConfig().MML.Password)
+ n, err = conn.Write([]byte(loginStr))
+ if err != nil {
+ log.Errorf("Error: %s", err.Error())
+ return
+ }
+
+ time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
+
+ n, err = conn.Read(buf[0:])
+ if err != nil {
+ log.Errorf("Error: %s", err.Error())
+ return
+ }
+ log.Debug(string(buf[0:n]))
+
+ body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
+ if err != nil {
+ log.Error("io.ReadAll is failed:", err)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ log.Debug("Body:", string(body))
+
+ mmlRequest := new(MMLRequest)
+ _ = json.Unmarshal(body, mmlRequest)
+
+ for _, mml := range mmlRequest.MML {
+ mmlCommand := fmt.Sprintf("%s\n", mml)
+ log.Debug("mml command:", mmlCommand)
+ n, err = conn.Write([]byte(mmlCommand))
+ if err != nil {
+ log.Errorf("Error: %s", err.Error())
+ return
+ }
+ time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
+
+ n, err = conn.Read(buf[0:])
+ if err != nil {
+ log.Errorf("Error: %s", err.Error())
+ return
+ }
+ log.Debug(string(buf[0 : n-len(neType)-2]))
+ mmlResult = append(mmlResult, string(buf[0:n-len(neType)-2]))
+ }
+ }
+
+ response := Response{mmlResult}
+ services.ResponseWithJson(w, http.StatusOK, response)
+}
+
+func PostMMLToOMC(w http.ResponseWriter, r *http.Request) {
+ log.Debug("PostMMLToOMC processing... ")
+
+ token, err := services.CheckExtValidRequest(w, r)
+ if err != nil {
+ log.Error("Failed to CheckMmlValidRequest:", err)
+ return
+ }
+
+ params := r.URL.Query()
+ neId := params["ne_id"]
+ if len(neId) == 0 {
+ log.Error("NOT FOUND ne_id ")
+ services.ResponseBadRequest400WrongParamValue(w)
+ return
+ }
+
+ neInfo := new(dborm.NeInfo)
+ neInfo, err = dborm.XormGetNeInfo("OMC", neId[0])
+ if err != nil {
+ log.Error("dborm.XormGetNeInfo is failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+ log.Trace("neInfo:", neInfo)
+
+ body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
+ if err != nil {
+ log.Error("io.ReadAll is failed:", err)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ log.Debug("Body:", string(body))
+
+ hostUri := fmt.Sprintf("http://%s:%s", neInfo.Ip, neInfo.Port)
+
+ omcMmlVar := &mmlp.MmlVar{
+ Version: "16.1.1",
+ Output: mmlp.DefaultFormatType,
+ Limit: 50,
+ User: "",
+ SessionToken: token,
+ HttpUri: hostUri,
+ UserAgent: config.GetDefaultUserAgent(),
+ }
+ mmlRequest := new(MMLRequest)
+ _ = json.Unmarshal(body, mmlRequest)
+
+ var mmlResult []string
+ mmlLine := strings.Join(mmlRequest.MML, ";")
+
+ var mmlCmds []mmlp.MmlCommand
+ if err = mmlp.ParseMMLCommand(mmlLine, &mmlCmds); err != nil {
+ response := fmt.Sprintf("parse command error: %v\n", err)
+ mmlResult = append(mmlResult, response)
+ }
+
+ for _, mmlCmd := range mmlCmds {
+ output, err := mmlp.TransMml2HttpReq(omcMmlVar, &mmlCmd)
+ if err != nil {
+ response := fmt.Sprintf("translate MML command error: %v]\n", err)
+ mmlResult = append(mmlResult, response)
+ }
+ mmlResult = append(mmlResult, string(*output))
+ }
+
+ response := Response{mmlResult}
+ services.ResponseWithJson(w, http.StatusOK, response)
+}
diff --git a/features/mml/parse.go.bak b/features/mml/parse.go.bak
new file mode 100644
index 00000000..1a2c99da
--- /dev/null
+++ b/features/mml/parse.go.bak
@@ -0,0 +1,890 @@
+package mml
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "math"
+ "net/http"
+ "regexp"
+ "strconv"
+ "strings"
+
+ "ems.agt/lib/dborm"
+ "ems.agt/lib/global"
+ "ems.agt/lib/log"
+ "github.com/go-resty/resty/v2"
+)
+
+type Param struct {
+ Name string `json:"name"`
+ Value string `json:"value"`
+}
+
+type MmlCommand struct {
+ Operation string `json:"operation"`
+ Object string `json:"object"`
+ Params []Param `json:"params"`
+ PaList []string `json:"paList"`
+ AaList []string `json:"aaList"`
+ AaMap map[string]interface{} `json:"aaMap"`
+ NaMap map[string]interface{} `json:"naMap"`
+ AaUri []string `json:"aaUri"`
+ AaLoc []string `json:"aaLoc"` // for loc parameter
+}
+
+type MmlVar struct {
+ Version string `json:"version"`
+ Output string `json:"output"`
+ Limit int `json:"limit"`
+}
+
+var OmcMmlVar *MmlVar
+
+func init() {
+ OmcMmlVar = &MmlVar{Version: "16.1.1", Output: DefaultFormatType, Limit: 50}
+}
+
+func SetOmcMmlVarOutput(output string) {
+ OmcMmlVar.Output = output
+}
+
+func SetOmcMmlVarLimit(limit int) {
+ OmcMmlVar.Limit = limit
+}
+
+func splitByColon(str string) []string {
+ return splitBy(str, ':')
+}
+
+func splitByComma(str string) []string {
+ return splitBy(str, ',')
+}
+
+func splitBy(str string, sep rune) []string {
+ var result []string
+ var stack []string
+ var current []rune
+ var quotes, apoFlag bool = false, false
+
+ for _, c := range str {
+ if c == '{' || c == '[' || (c == '\'' && apoFlag == false) || (c == '"' && quotes == false) { // "'"
+ apoFlag = true
+ quotes = true
+ stack = append(stack, string(c))
+ } else if c == '}' || c == ']' || (c == '\'' && apoFlag == true) || (c == '"' && quotes == true) {
+ apoFlag = false
+ quotes = false
+ if len(stack) > 0 {
+ stack = stack[:len(stack)-1]
+ }
+ }
+
+ if c == sep && len(stack) == 0 {
+ result = append(result, string(current))
+ current = []rune{}
+ } else {
+ current = append(current, c)
+ }
+ }
+
+ result = append(result, string(current))
+ return result
+}
+
+func ParseMMLCommand(mmlStr string, mmlComms *[]MmlCommand) error {
+ log.Info("ParseMMLCommand processing ...")
+ log.Debug("mmlStr: ", mmlStr)
+
+ mc := new(MmlCommand)
+ reg := regexp.MustCompile(`\s*;\s*`)
+ mmls := reg.Split(mmlStr, -1)
+ for _, mml := range mmls {
+ log.Trace("mml:", mml)
+ if len(mml) == 0 {
+ continue
+ }
+ //reg := regexp.MustCompile(`\s*:\s*`)
+ //ms := reg.Split(mml, -1)
+ ms := splitByColon(mml)
+ if len(ms) < 1 || len(ms) > 2 {
+ err := global.ErrMmlInvalidCommandFormat
+ log.Error(err)
+ return err
+ }
+ if len(ms) == 2 {
+ cmd := strings.Trim(ms[0], " ")
+ reg = regexp.MustCompile(`\s+`)
+ cs := reg.Split(cmd, -1)
+ //cs := strings.Split(cmd, " ")
+ if len(cs) == 2 {
+ mc.Operation = cs[0]
+ mc.Object = cs[1]
+ } else {
+ err := global.ErrMmlInvalidCommandFormat
+ log.Error(err)
+ return err
+ }
+ //reg = regexp.MustCompile(`\s*,\s*`)
+ //reg = regexp.MustCompile(`(?U)(? 0 {
+ extUri := strings.Join(mml.AaUri, "/")
+ requestURI = requestURI + fmt.Sprintf(mmlMap.ExtUri, extUri)
+ }
+ if mmlMap.Params != "" {
+ params := strings.Join(mml.AaLoc, "+and+")
+ params = strings.ReplaceAll(params, " ", "+") // replace " " to "+"
+ requestURI = fmt.Sprintf("%s?%s=%s", requestURI, mmlMap.Params, params)
+ }
+ return requestURI
+}
+
+func TransMml2HttpReq(httpUri, uerAgent string, mml *MmlCommand) (*[]byte, error) {
+ log.Info("TransMml2HttpReq processing ...")
+ log.Debug("mml: ", mml)
+
+ where := fmt.Sprintf("operation='%s' AND object='%s'", mml.Operation, mml.Object)
+ mmlMap, err := dborm.XormGetMmlHttpMap("mml_http_map", where)
+ if err != nil {
+ log.Error("Failed to XormGetMmlHttpMap: ", err)
+ return ParseErrorOutput(err), err
+ }
+ if mmlMap == nil {
+ err := errors.New("Not found mml map")
+ log.Error(err)
+ return ParseErrorOutput(err), err
+ }
+ log.Trace("mmlMap: ", mmlMap)
+ if mmlMap.Output == "" {
+ mmlMap.Output = "{}"
+ }
+ outputJson := new(dborm.MmlOutput)
+ err = json.Unmarshal([]byte(mmlMap.Output), outputJson)
+ if err != nil {
+ log.Error("Failed to Unmarshal:", err)
+ return ParseErrorOutput(err), err
+ }
+ log.Trace("outputJson: ", outputJson)
+ inputJson := new(dborm.MmlInput)
+ log.Trace("mmlMap.Input: ", mmlMap.Input)
+ if mmlMap.Input == "" {
+ mmlMap.Input = "{}"
+ }
+ err = json.Unmarshal([]byte(mmlMap.Input), inputJson)
+ if err != nil {
+ log.Error("Failed to Unmarshal:", err)
+ return ParseErrorOutput(err), err
+ }
+ log.Trace("inputJson: ", inputJson)
+
+ var requestURI string
+ var output *[]byte
+ client := resty.New()
+ switch strings.ToLower(mmlMap.Method) {
+ case "get":
+ requestURI = parseRequestUri(httpUri, mmlMap, mml)
+ log.Debugf("method: Get requestURI: %s", requestURI)
+ response, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": uerAgent}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ Get(requestURI)
+ if err != nil {
+ log.Error("Failed to Get:", err)
+ output = ParseErrorOutput(err)
+ } else {
+ output = ParseOutputResponse(outputJson, response)
+ }
+ case "post":
+ requestURI = parseRequestUri(httpUri, mmlMap, mml)
+ body := ParseInputBody(inputJson, mml)
+ log.Debugf("method: Post requestURI: %s", requestURI)
+ response, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": uerAgent}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ SetBody(*body).
+ Post(requestURI)
+ if err != nil {
+ log.Error("Failed to Post:", err)
+ output = ParseErrorOutput(err)
+ } else {
+ output = ParseOutputResponse(outputJson, response)
+ }
+ case "put":
+ requestURI = parseRequestUri(httpUri, mmlMap, mml)
+ body := ParseInputBody(inputJson, mml)
+ log.Debugf("method: Put requestURI: %s", requestURI)
+ response, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": uerAgent}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ SetBody(*body).
+ Put(requestURI)
+ if err != nil {
+ log.Error("Failed to Put:", err)
+ output = ParseErrorOutput(err)
+ } else {
+ output = ParseOutputResponse(outputJson, response)
+ }
+ case "delete":
+ requestURI = parseRequestUri(httpUri, mmlMap, mml)
+ log.Debugf("method: Delete requestURI: %s", requestURI)
+ response, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": uerAgent}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ Delete(requestURI)
+ if err != nil {
+ log.Error("Failed to Delete:", err)
+ output = ParseErrorOutput(err)
+ } else {
+ output = ParseOutputResponse(outputJson, response)
+ }
+ case "patch":
+ requestURI = parseRequestUri(httpUri, mmlMap, mml)
+ log.Debugf("method: patch requestURI: %s", requestURI)
+ response, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": uerAgent}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ Patch(requestURI)
+ if err != nil {
+ log.Error("Failed to Patch:", err)
+ output = ParseErrorOutput(err)
+ } else {
+ output = ParseOutputResponse(outputJson, response)
+ }
+ default:
+ err := errors.New("not found mml command")
+ log.Error(err)
+ output = ParseErrorOutput(err)
+ }
+ return output, nil
+}
+
+const (
+ MaxMmlOutputBufferSize = 1000000
+ FormatTypeJson = "json"
+ FormatTypeTable = "table"
+ DefaultFormatType = FormatTypeTable
+)
+
+const (
+ RetCodeSucceeded = 0
+ RetCodeFailed = 0
+)
+
+func ParseInputBody(inputJson *dborm.MmlInput, mml *MmlCommand) *[]byte {
+ inputBody := make(map[string]interface{})
+ log.Trace("mml.NaMap:", mml.NaMap)
+ log.Trace("mml.AaMap:", mml.AaMap)
+ if strings.ToLower(inputJson.BodyFmt) == "putdb" {
+ for _, icol := range inputJson.Cols {
+ log.Trace("icol:", icol)
+ mml.NaMap[icol.Name] = icol.Value
+ }
+ inputBody[inputJson.BodyKey] = mml.NaMap
+ } else {
+ inputParams := make([]map[string]interface{}, 0)
+ inputParams = append(inputParams, mml.NaMap)
+ inputBody[inputJson.BodyKey] = inputParams
+ }
+
+ body, err := json.Marshal(inputBody)
+ if err != nil {
+ log.Error("Failed to marshal:", err)
+ }
+
+ log.Trace("inputBody:", inputBody)
+ log.Trace("body:", string(body))
+ return &body
+}
+
+func ParseOutputResponse(outputJson *dborm.MmlOutput, response *resty.Response) *[]byte {
+ var output []byte
+ var str bytes.Buffer
+
+ switch response.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ if OmcMmlVar.Output == FormatTypeJson {
+ code := fmt.Sprintf("StatusCode = %d status %s\n\n", response.StatusCode(), response.Status())
+ title := formatTitle(outputJson.Title)
+
+ json.Indent(&str, response.Body(), "", " ")
+ log.Trace(str.String())
+
+ output = global.BytesCombine1([]byte(code), []byte(title), str.Bytes(), []byte("\n"))
+ } else {
+ log.Trace("Body:", string(response.Body()))
+ mapDatas := make(map[string]interface{}, 0)
+
+ err := json.Unmarshal(response.Body(), &mapDatas)
+ if err != nil {
+ log.Error("Failed to json.Unmarshal:", err)
+ //output = *ParseErrorOutput(err)
+ output = *ParseErrorOutput(string(response.Body()))
+ return &output
+ }
+ log.Trace("mapDatas:", mapDatas)
+ switch strings.ToLower(outputJson.RetFmt) {
+ case "getdb":
+ if len(mapDatas) > 0 {
+ var data interface{}
+ for _, data = range mapDatas {
+ log.Trace("data:", data)
+ break
+ }
+ if len(data.([]interface{})) > 0 {
+ table := (data.([]interface{}))[0]
+ log.Trace("table:", table)
+
+ code := fmt.Sprintf(outputJson.RetMsg, RetCodeSucceeded)
+ title := formatTitle(outputJson.Title)
+ fmtResults := ParseTableOutput(outputJson, table)
+ output = global.BytesCombine1([]byte(code), []byte(title), []byte(fmtResults))
+ }
+ }
+ case "deletedb":
+ var data interface{}
+ for _, data = range mapDatas {
+ log.Trace("data:", data)
+ break
+ }
+
+ if len(data.(map[string]interface{})) > 0 {
+ table := data.(map[string]interface{})
+ code := fmt.Sprintf(outputJson.RetMsg, RetCodeSucceeded)
+ fmtResults := ParseDBOperOutput(outputJson, table)
+ output = global.BytesCombine1([]byte(code), []byte(fmtResults))
+ }
+ case "postdb":
+ var data interface{}
+ for _, data = range mapDatas {
+ log.Trace("data:", data)
+ break
+ }
+
+ if len(data.(map[string]interface{})) > 0 {
+ table := data.(map[string]interface{})
+ code := fmt.Sprintf(outputJson.RetMsg, RetCodeSucceeded)
+ fmtResults := ParseDBOperOutput(outputJson, table)
+ output = global.BytesCombine1([]byte(code), []byte(fmtResults))
+ }
+ case "putdb":
+ var data interface{}
+ for _, data = range mapDatas {
+ log.Trace("data:", data)
+ break
+ }
+ if len(data.(map[string]interface{})) > 0 {
+ table := data.(map[string]interface{})
+ code := fmt.Sprintf(outputJson.RetMsg, RetCodeSucceeded)
+ fmtResults := ParseDBOperOutput(outputJson, table)
+ output = global.BytesCombine1([]byte(code), []byte(fmtResults))
+ }
+ case "getnf":
+ if len(mapDatas) > 0 {
+ var data interface{}
+ for _, data = range mapDatas {
+ log.Trace("data:", data)
+ break
+ }
+ if len(data.([]interface{})) > 0 {
+ //table := (data.([]interface{}))[0]
+ //log.Trace("table:", table)
+
+ code := fmt.Sprintf(outputJson.RetMsg, RetCodeSucceeded)
+ title := formatTitle(outputJson.Title)
+ fmtResults := ParseNFTableOutput(outputJson, data)
+ output = global.BytesCombine1([]byte(code), []byte(title), []byte(fmtResults))
+ }
+ }
+ default:
+ code := fmt.Sprintf(outputJson.RetMsg, RetCodeSucceeded)
+ output = global.BytesCombine1([]byte(code))
+ }
+
+ }
+ default:
+ if OmcMmlVar.Output == FormatTypeJson {
+ code := fmt.Sprintf("StatusCode = %d status %s\n\n", response.StatusCode(), response.Status())
+ //title := formatTitle("Network Element Information")
+
+ json.Indent(&str, response.Body(), "", " ")
+ log.Trace(str.String())
+
+ output = global.BytesCombine1([]byte(code), str.Bytes(), []byte("\n"))
+ } else {
+ log.Trace("Body:", string(response.Body()))
+ mapResults := make(map[string]interface{}, 0)
+
+ err := json.Unmarshal(response.Body(), &mapResults)
+ if err != nil {
+ log.Error("Failed to json.Unmarshal:", err)
+ output = *ParseErrorOutput(string(response.Body()))
+ } else {
+ log.Trace("mapResults:", mapResults)
+ errResult := mapResults["error"]
+ log.Trace("errResult:", errResult)
+ if len(errResult.(map[string]interface{})) > 0 {
+ errCode, _ := strconv.Atoi(fmt.Sprintf("%v", errResult.(map[string]interface{})["errorCode"]))
+ errorInfo := errResult.(map[string]interface{})["errorInfo"]
+ output = []byte(fmt.Sprintf(outputJson.ErrMsg, errCode, errorInfo))
+ }
+ }
+ }
+ }
+ return &output
+}
+
+func ParseDBOperOutput(outputJson *dborm.MmlOutput, cols any) string {
+ var colOutput []dborm.ColOutput = outputJson.Cols
+ var value, retFmtCols string
+ if len(cols.(map[string]interface{})) > 0 {
+ if len(colOutput) > 0 {
+ coln := colOutput[0].Name
+ value = fmt.Sprintf("%v", cols.(map[string]interface{})[coln])
+ log.Tracef("coln:%s value:%s", coln, value)
+ retFmtCols = colOutput[0].Display + " = " + value + "\n\n"
+ }
+ }
+
+ return retFmtCols
+}
+
+func ParseNFTableOutput(outputJson *dborm.MmlOutput, cols any) string {
+ var colOutput []dborm.ColOutput
+ var fmtColName string
+ var colName []string
+ var spaceNum int = 1
+ var alignmentM, alignmentSN, alignmentSV string = "Left", "Right", "Left"
+
+ if outputJson.SepSpaceNum != 0 {
+ spaceNum = outputJson.SepSpaceNum
+ }
+ if outputJson.AlignmentM != "" {
+ alignmentM = outputJson.AlignmentM
+ }
+ if outputJson.AlignmentSN != "" {
+ alignmentSN = outputJson.AlignmentSN
+ }
+ if outputJson.AlignmentSV != "" {
+ alignmentSV = outputJson.AlignmentSV
+ }
+
+ maxLength := math.MinInt64
+ for _, coln := range outputJson.Cols {
+ log.Trace("coln:", coln)
+
+ if len(coln.Display) > maxLength {
+ maxLength = len(coln.Display)
+ }
+ if coln.Length < len(coln.Display) {
+ coln.Length = len(coln.Display)
+ }
+
+ colName = append(colName, ParseAlignmentOutput(coln.Length, alignmentM, coln.Display))
+ colOutput = append(colOutput, coln)
+ }
+ fmtColName = formatLineBySpace(&colName, spaceNum)
+ log.Trace("fmtColName:", fmtColName)
+
+ var retFmtCols string
+ var fmtColValues []string
+ var numberResult int
+ // for _, colnvs := range cols.([]interface{}) {
+ // log.Trace("colnvs:", colnvs)
+ // if colnvs == nil {
+ // break
+ // }
+ numberResult = len(cols.([]interface{}))
+
+ if numberResult == 1 && outputJson.SingleList == true {
+ colnv := cols.([]interface{})[0]
+ log.Trace("colnv:", colnv)
+
+ var fmtNV []string
+ for _, coln := range colOutput {
+ fmtName := ParseAlignmentOutput(maxLength, alignmentSN, coln.Display)
+ log.Tracef("alignmentSN:%s fmtName:%s", alignmentSN, fmtName)
+ value := fmt.Sprintf("%v", colnv.(map[string]interface{})[coln.Name])
+ fmtValue := ParseAlignmentOutput(coln.Length, alignmentSV, value)
+ fmtNV = append(fmtNV, fmtName+": "+fmtValue)
+ }
+
+ fmtResults := strings.Join(fmtNV, "\n")
+ log.Tracef("fmtResults:\n%s", fmtResults)
+ fmtEnd := fmt.Sprintf(outputJson.End, numberResult)
+ retFmtCols = fmtResults + "\n\n" + fmtEnd
+ log.Tracef("retFmtCols:\n%s", retFmtCols)
+ return retFmtCols
+ } else {
+ for i := 0; i < numberResult; i++ {
+ colnv := cols.([]interface{})[i]
+ log.Trace("colnv:", colnv)
+ var colValues []string
+ var newVal []string
+ for _, coln := range colOutput {
+ value := fmt.Sprintf("%v", colnv.(map[string]interface{})[coln.Name])
+ if len(coln.Alias) != 0 {
+ enumVal, _ := strconv.Atoi(value)
+ value = parseEnumAlias(&(coln.Alias), enumVal)
+ }
+ newVal = append(newVal, ParseAlignmentOutput(coln.Length, alignmentM, value))
+ }
+ colValues = append(colValues, formatLineBySpace(&newVal, spaceNum))
+ log.Trace("colValues:", colValues)
+ fmtColValues = append(fmtColValues, strings.Join(colValues, "\n"))
+ log.Trace("fmtColValues:", fmtColValues)
+ }
+ fmtEnd := fmt.Sprintf(outputJson.End, numberResult)
+ retFmtCols = fmtColName + "\n\n" + strings.Join(fmtColValues, "\n") + "\n\n" + fmtEnd
+ log.Tracef("retFmtCols:\n%s", retFmtCols)
+ return retFmtCols
+ }
+ // }
+ // fmtEnd := fmt.Sprintf(outputJson.End, numberResult)
+ // retFmtCols = fmtColName + "\n" + strings.Join(fmtColValues, "\n") + "\n\n" + fmtEnd
+ // log.Tracef("retFmtCols:\n%s", retFmtCols)
+ // return retFmtCols
+}
+
+func ParseTableOutput(outputJson *dborm.MmlOutput, cols any) string {
+ var colOutput []dborm.ColOutput
+ var fmtColName string
+ var colName []string
+ var spaceNum int = 1
+ var alignmentM, alignmentSN, alignmentSV string = "Left", "Right", "Left"
+
+ if outputJson.SepSpaceNum != 0 {
+ spaceNum = outputJson.SepSpaceNum
+ }
+ if outputJson.AlignmentM != "" {
+ alignmentM = outputJson.AlignmentM
+ }
+ if outputJson.AlignmentSN != "" {
+ alignmentSN = outputJson.AlignmentSN
+ }
+ if outputJson.AlignmentSV != "" {
+ alignmentSV = outputJson.AlignmentSV
+ }
+
+ maxLength := math.MinInt64
+ for _, coln := range outputJson.Cols {
+ log.Trace("coln:", coln)
+
+ if len(coln.Display) > maxLength {
+ maxLength = len(coln.Display)
+ }
+ if coln.Length < len(coln.Display) {
+ coln.Length = len(coln.Display)
+ }
+
+ colName = append(colName, ParseAlignmentOutput(coln.Length, alignmentM, coln.Display))
+ colOutput = append(colOutput, coln)
+ }
+ fmtColName = formatLineBySpace(&colName, spaceNum)
+ log.Trace("fmtColName:", fmtColName)
+
+ var retFmtCols string
+ var fmtColValues []string
+ var numberResult int
+ for _, colnvs := range cols.(map[string]interface{}) {
+ log.Trace("colnvs:", colnvs)
+ if colnvs == nil {
+ break
+ }
+ numberResult = len(colnvs.([]interface{}))
+
+ if numberResult == 1 && outputJson.SingleList == true {
+ colnv := colnvs.([]interface{})[0]
+ log.Trace("colnv:", colnv)
+
+ var fmtNV []string
+ for _, coln := range colOutput {
+ fmtName := ParseAlignmentOutput(maxLength, alignmentSN, coln.Display)
+ log.Tracef("alignmentSN:%s fmtName:%s", alignmentSN, fmtName)
+ value := fmt.Sprintf("%v", colnv.(map[string]interface{})[coln.Name])
+ fmtValue := ParseAlignmentOutput(coln.Length, alignmentSV, value)
+ fmtNV = append(fmtNV, fmtName+": "+fmtValue)
+ }
+
+ fmtResults := strings.Join(fmtNV, "\n")
+ log.Tracef("fmtResults:\n%s", fmtResults)
+ fmtEnd := fmt.Sprintf(outputJson.End, numberResult)
+ retFmtCols = fmtResults + "\n\n" + fmtEnd
+ log.Tracef("retFmtCols:\n%s", retFmtCols)
+ return retFmtCols
+ } else {
+ for i := 0; i < numberResult; i++ {
+ colnv := colnvs.([]interface{})[i]
+ log.Trace("colnv:", colnv)
+ var colValues []string
+ var newVal []string
+ for _, coln := range colOutput {
+ value := fmt.Sprintf("%v", colnv.(map[string]interface{})[coln.Name])
+ if len(coln.Alias) != 0 {
+ enumVal, _ := strconv.Atoi(value)
+ value = parseEnumAlias(&(coln.Alias), enumVal)
+ }
+ newVal = append(newVal, ParseAlignmentOutput(coln.Length, alignmentM, value))
+ }
+ colValues = append(colValues, formatLineBySpace(&newVal, spaceNum))
+ log.Trace("colValues:", colValues)
+ fmtColValues = append(fmtColValues, strings.Join(colValues, "\n"))
+ log.Trace("fmtColValues:", fmtColValues)
+ }
+ fmtEnd := fmt.Sprintf(outputJson.End, numberResult)
+ retFmtCols = fmtColName + "\n\n" + strings.Join(fmtColValues, "\n") + "\n\n" + fmtEnd
+ log.Tracef("retFmtCols:\n%s", retFmtCols)
+ return retFmtCols
+ }
+ }
+ fmtEnd := fmt.Sprintf(outputJson.End, numberResult)
+ retFmtCols = fmtColName + "\n" + strings.Join(fmtColValues, "\n") + "\n\n" + fmtEnd
+ log.Tracef("retFmtCols:\n%s", retFmtCols)
+ return retFmtCols
+}
+
+func parseEnumAlias(alias *[]string, enumVal int) string {
+ return (*alias)[enumVal]
+}
+
+func formatLineBySpace(strArray *[]string, spaceNum int) string {
+ space := strings.Repeat(" ", spaceNum)
+ return strings.Join(*strArray, space)
+}
+
+func ParseAlignmentOutput(length int, alignment string, str string) string {
+ spaceLen := length - len(str)
+ if spaceLen < 0 {
+ log.Warnf("len(str=%s)=%d more length=%d", str, len(str), length)
+ spaceLen = 0
+ }
+ var retStr string
+ switch alignment {
+ case "Left":
+ suffix := strings.Repeat(" ", spaceLen)
+ retStr = str + suffix
+ case "Right":
+ prefix := strings.Repeat(" ", spaceLen)
+ retStr = prefix + str
+ log.Tracef("retStr:%s", retStr)
+ case "Middle":
+ prefix := strings.Repeat(" ", int(math.Ceil(float64(spaceLen)/2)))
+ suffix := strings.Repeat(" ", int(math.Floor(float64(spaceLen)/2)))
+ retStr = prefix + str + suffix
+ }
+ log.Tracef("length=%d, spaceLne=%d, alignment=%s, str=%s, retStr=%s", length, spaceLen, alignment, str, retStr)
+ return retStr
+}
+
+func ParseErrorOutput(err any) *[]byte {
+ var output []byte
+
+ var formatType string = DefaultFormatType
+ if formatType == FormatTypeJson {
+ output = []byte(fmt.Sprintf("ErrorCode = 1 Error message: %v\n\n", err))
+ } else {
+ output = []byte(fmt.Sprintf("RetCode = -1 operation failed: %v\n\n", err))
+ }
+
+ return &output
+}
+
+func formatTitle(title string) string {
+ var builder strings.Builder
+ builder.WriteString(title)
+ builder.WriteString("\n")
+ for i := 0; i < len(title); i++ {
+ builder.WriteString("-")
+ }
+ builder.WriteString("\n")
+ return builder.String()
+}
+
+func formatTableOutput() {
+
+}
diff --git a/features/monitor/process.go b/features/monitor/process.go
new file mode 100644
index 00000000..863ec866
--- /dev/null
+++ b/features/monitor/process.go
@@ -0,0 +1,51 @@
+package monitor
+
+import (
+ "net/http"
+
+ websocket2 "ems.agt/lib/websocket"
+ "ems.agt/restagent/config"
+ "github.com/gorilla/websocket"
+)
+
+var (
+ // 進程
+ UriWs = config.UriPrefix + "/monitor/{apiVersion}/process/ws"
+)
+
+var wsUpgrade = websocket.Upgrader{
+ CheckOrigin: func(r *http.Request) bool {
+ return true
+ },
+}
+
+func ProcessWs(w http.ResponseWriter, r *http.Request) {
+ ws, err := wsUpgrade.Upgrade(w, r, nil)
+ if err != nil {
+ return
+ }
+ wsClient := websocket2.NewWsClient("processClient", ws)
+ go wsClient.Read()
+ go wsClient.Write()
+}
+
+// @Tags Process
+// @Summary Stop Process
+// @Description 停止进程
+// @Param request body request.ProcessReq true "request"
+// @Success 200
+// @Security ApiKeyAuth
+// @Router /process/stop [post]
+// @x-panel-log {"bodyKeys":["PID"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"结束进程 [PID]","formatEN":"结束进程 [PID]"}
+func StopProcess(w http.ResponseWriter, r *http.Request) {
+ // var req request.ProcessReq
+ // if err := c.ShouldBindJSON(&req); err != nil {
+ // helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
+ // return
+ // }
+ // if err := processService.StopProcess(req); err != nil {
+ // helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
+ // return
+ // }
+ // helper.SuccessWithOutData(c)
+}
diff --git a/features/nbi/nbi.go b/features/nbi/nbi.go
new file mode 100644
index 00000000..8caed50b
--- /dev/null
+++ b/features/nbi/nbi.go
@@ -0,0 +1,269 @@
+package nbi
+
+import (
+ "bytes"
+ "fmt"
+ "net/http"
+ "strings"
+
+ "ems.agt/lib/dborm"
+ "github.com/go-resty/resty/v2"
+
+ "github.com/gorilla/mux"
+
+ "ems.agt/lib/global"
+ "ems.agt/lib/log"
+ "ems.agt/lib/oauth"
+ "ems.agt/lib/services"
+ "ems.agt/lib/session"
+ "ems.agt/restagent/config"
+)
+
+type ErrorOAuthResponse struct {
+ Error map[string]interface{}
+}
+
+type FailOAuthResponse struct {
+ Error struct {
+ ErrorCode string
+ ErrorInfo string
+ }
+}
+
+type ApiResponse struct {
+ ResultCode string
+ ResultMessage interface{}
+}
+
+var globalSession = session.NewSessManager("restagent")
+
+var (
+ MAX_RMUID_NUM int
+ MAX_ALARMID_NUM int
+ MAX_PMUID_NUM int
+ MAX_SUBID_NUM int
+ MAX_URI_LEN int
+ RMUID_REGEXP string
+)
+
+var (
+ // Northbound interface
+ GetNRMUri = config.UriPrefix + "/resourceManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/{objectTypeValue}"
+ NorthboundGetAlarmUri = config.UriPrefix + "/faultManagement/{apiVersion}/alarms" // ?alarmIds={alarmIdValues}
+)
+
+func CheckParameterName(r *http.Request) []string {
+ var errorParams []string
+ vars := r.URL.Query()
+ for k, v := range vars {
+ log.Debug("vars:", k, v)
+ if k != "rmUIDs" && k != "fields" {
+ errorParams = append(errorParams, k)
+ }
+ }
+
+ return errorParams
+}
+
+func GetRmUIDArr(r *http.Request) []string {
+ vars := r.URL.Query()
+ rmUIDs, ok := vars["rmUIDs"]
+ if !ok {
+ log.Debug("rmUIDs is not exist")
+ return nil
+ }
+
+ var rmUIDValues []string
+ for _, r := range rmUIDs {
+ if r != "" {
+ rmUIDValues = global.MergeStringArr(rmUIDValues, strings.Split(r, `,`))
+ }
+ }
+
+ return rmUIDValues
+}
+
+func GetAttrNameArr(r *http.Request) []string {
+ vars := r.URL.Query()
+ fields, ok := vars["fields"]
+ if !ok {
+ log.Debug("attributeNames does not exist")
+ return nil
+ }
+ var attrNames []string
+ for _, a := range fields {
+ if a != "" {
+ attrNames = global.MergeStringArr(attrNames, strings.Split(a, `,`))
+ }
+ }
+
+ return attrNames
+}
+
+func CheckValidRmUID(rmUIDs []string) []string {
+ log.Debug("CheckValidRmUID processing... ")
+
+ var invalidRmUIDs []string
+ for _, r := range rmUIDs {
+ if !global.MatchRmUID(RMUID_REGEXP, r) {
+ invalidRmUIDs = append(invalidRmUIDs, r)
+ }
+ }
+
+ return invalidRmUIDs
+}
+
+func CheckLocalRmUID(rmUIDs []string) string {
+ log.Debug("GetLocalRmUID processing... ")
+
+ rmUID := config.GetRmUIDFromConfig()
+ for _, r := range rmUIDs {
+ if r == rmUID {
+ return rmUID
+ }
+ }
+
+ return ""
+}
+
+func NBIGetNRMFromNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("NorthGetNRMFromNF processing... ")
+
+ // response 414-4 uri too long ? (optional)
+ // todo ... ?
+ if bytes.Count([]byte(r.RequestURI), nil) > config.GetUriMaxLenFromConfig() {
+ log.Error("Request Uri too long:", bytes.Count([]byte(r.RequestURI), nil), config.GetUriMaxLenFromConfig())
+ services.ResponseRequestURITooLong414UriTooLong(w)
+ return
+ }
+
+ // check media type(content type) only support "application/json"
+ // response 415-1
+ if !services.IsVallidContentType(r, config.GetYamlConfig().OMC.CheckContentType) {
+ log.Debug("Invalid Content-Type")
+ services.ResponseUnsupportedMediaType415(w)
+ return
+ }
+
+ // error processing ...
+ // 401-1 response
+ token, ret := oauth.IsCarriedToken(r)
+ if ret == false {
+ log.Error("AccessToken is not carried")
+ services.ResponseUnauthorized401AccessTokenNotCarried(w)
+ return
+ }
+
+ // 401-2 response
+ if dborm.XormExistValidToken(token, config.GetExpiresFromConfig()) == false {
+ log.Error("AccessToken fails or does not exist")
+ services.ResponseUnauthorized401AccessTokenNotExist(w)
+ return
+ }
+
+ _, err := dborm.XormUpdateSessionShakeTime(token)
+ if err != nil {
+ log.Error("Failed to update session table:", err)
+ services.ResponseUnauthorized401AccessTokenNotExist(w)
+ return
+ }
+
+ /*
+ // response 403 Forbidden, permissions deny
+ // todo...
+ plist := globalSession.GetPermissionFromSession(token)
+ log.Debug("permission list:", plist)
+ if len(plist) == 0 || plist[0] == false {
+ log.Debug("User permission deny")
+ services.ResponseForbidden403NotPermission(w)
+ return
+ }
+ */
+ vars := mux.Vars(r)
+ neType := vars["elementTypeValue"]
+
+ apiVer := vars["apiVersion"]
+ if apiVer != "v1" {
+ log.Error("Uri is invalid")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ // response 406-1
+ rmUIDValues := GetRmUIDArr(r)
+ if rmUIDValues == nil {
+ log.Error("missing parameter: rmUIDs")
+ services.ResponseNotAcceptable406MissingParam(w)
+ return
+ }
+
+ // response 406-2
+ errorParams := CheckParameterName(r)
+ if errorParams != nil {
+ log.Error("parameter name error: ", errorParams)
+ services.ResponseNotAcceptable406ParamError(w, errorParams)
+ return
+ }
+
+ // response 400-5
+ if len(rmUIDValues) == 0 {
+ log.Error("rmUIDs is wrong or NULL")
+ services.ResponseBadRequest400WrongParamValue(w)
+ return
+ }
+
+ // response 414-1
+ if len(rmUIDValues) > config.GetYamlConfig().Params.RmUIDMaxNum {
+ log.Error("rmUID greater than", config.GetYamlConfig().Params.RmUIDMaxNum)
+ services.ResponseRequestURITooLong414NRMNumExceed(w, config.GetYamlConfig().Params.RmUIDMaxNum)
+ return
+ }
+ /*
+ // response 400-1
+ // check rmUID is valid
+ // todo ...
+ invalidRmUIDs := CheckValidRmUID(rmUIDValues)
+ if len(invalidRmUIDs) != 0 {
+ log.Debug("rmUID is invalid")
+ services.ResponseBadRequest400RmUIDsIsInvalid(w, invalidRmUIDs)
+ return
+ }
+ */
+ var response *resty.Response
+ // respMsg := make(map[string]interface{})
+ for _, rmUID := range rmUIDValues {
+ neInfo, err := dborm.XormGetNeInfoByRmUID(neType, rmUID)
+ if err != nil {
+ log.Error("dborm.XormGetNeInfo is failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+
+ requestURI2NF := fmt.Sprintf("http://%s:%v%s", neInfo.Ip, neInfo.Port, r.RequestURI)
+ log.Debug("requestURI2NF: GET ", requestURI2NF)
+
+ client := resty.New()
+ response, err = client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ Get(requestURI2NF)
+ if err != nil {
+ log.Error("Failed to Get from NF:", err)
+ services.ResponseInternalServerError500NFConnectRefused(w)
+ return
+ }
+ /*
+ switch response.StatusCode() {
+ case http.StatusOK, http.StatusAccepted, http.StatusNoContent, http.StatusCreated:
+ respMsg["data"] = response
+ default:
+ if response != nil {
+ services.TransportResponse(w, response.StatusCode(), response.Body())
+ }
+ }
+ */
+ }
+
+ services.TransportResponse(w, response.StatusCode(), response.Body())
+}
diff --git a/features/nbi/snmp.go b/features/nbi/snmp.go
new file mode 100644
index 00000000..38c9c5c2
--- /dev/null
+++ b/features/nbi/snmp.go
@@ -0,0 +1,203 @@
+package nbi
+
+import (
+ "bytes"
+ "fmt"
+ "net/http"
+ "strconv"
+
+ "github.com/gorilla/mux"
+ g "github.com/gosnmp/gosnmp"
+
+ "ems.agt/lib/log"
+ "ems.agt/lib/services"
+ "ems.agt/restagent/config"
+)
+
+func init() {
+ conf := config.GetYamlConfig()
+ // Default is a pointer to a GoSNMP struct that contains sensible defaults
+ // eg port 161, community public, etc
+ g.Default.Target = conf.NE.Addr
+ g.Default.Port = conf.NE.Port
+ err := g.Default.Connect()
+ if err != nil {
+ fmt.Printf("Connect() err: %v", err)
+ }
+ //defer g.Default.Conn.Close()
+ MAX_RMUID_NUM = config.GetRmUIDMaxNumFromConfig()
+ MAX_ALARMID_NUM = config.GetAlarmIDMaxNumFromConfig()
+ MAX_PMUID_NUM = config.GetPmIDMaxNumFromConfig()
+ MAX_SUBID_NUM = config.GetSubIDMaxNumFromConfig()
+ MAX_URI_LEN = config.GetUriMaxLenFromConfig()
+ RMUID_REGEXP = config.GetRmUIDRegexpFromConfig()
+}
+
+func GetNRMByUri(w http.ResponseWriter, r *http.Request) {
+ log.Debug("GetNRMByUri processing... ")
+
+ // response 414-4 uri too long ? (optional)
+ // todo ... ?
+ if bytes.Count([]byte(r.RequestURI), nil) > MAX_URI_LEN {
+ log.Error("Request Uri too long:", bytes.Count([]byte(r.RequestURI), nil))
+ services.ResponseRequestURITooLong414UriTooLong(w)
+ return
+ }
+
+ // check media type(content type) only support "application/json"
+ // response 415-1
+ if !services.IsVallidContentType(r, config.GetYamlConfig().OMC.CheckContentType) {
+ log.Debug("Invalid Content-Type")
+ services.ResponseUnsupportedMediaType415(w)
+ return
+ }
+
+ // error processing ...
+ // 401-1 response
+ token, ret := globalSession.IsCarriedToken(r)
+ if ret == false {
+ log.Error("AccessToken is not carried")
+ services.ResponseUnauthorized401AccessTokenNotCarried(w)
+ return
+ }
+
+ // 401-2 response
+ if globalSession.IsValidToken(token) == false {
+ log.Error("AccessToken fails or does not exist")
+ services.ResponseUnauthorized401AccessTokenNotExist(w)
+ return
+ }
+ // response 403 Forbidden, permissions deny
+ // todo...
+ plist := globalSession.GetPermissionFromSession(token)
+ log.Debug("permission list:", plist)
+ if len(plist) == 0 || plist[0] == false {
+ log.Error("User permission deny")
+ services.ResponseForbidden403NotPermission(w)
+ return
+ }
+
+ vars := mux.Vars(r)
+ qeuryUri := vars["apiCategory"] + "/" + vars["elementTypeValue"] + "/" + vars["objectTypeValue"]
+ log.Debug("Get by Uri: ", qeuryUri)
+
+ apiVer := vars["apiVersion"]
+ if apiVer != "v1" {
+ log.Error("Uri is invalid")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ // response 406-1
+ rmUIDValues := GetRmUIDArr(r)
+ if rmUIDValues == nil {
+ log.Error("missing parameter: rmUIDs")
+ services.ResponseNotAcceptable406MissingParam(w)
+ return
+ }
+
+ // response 406-2
+ errorParams := CheckParameterName(r)
+ if errorParams != nil {
+ log.Error("parameter name error: ", errorParams)
+ services.ResponseNotAcceptable406ParamError(w, errorParams)
+ return
+ }
+
+ // response 400-5
+ if len(rmUIDValues) == 0 {
+ log.Error("rmUIDs is wrong or NULL")
+ services.ResponseBadRequest400WrongParamValue(w)
+ return
+ }
+
+ // response 414-1
+ if len(rmUIDValues) > MAX_RMUID_NUM {
+ log.Error("rmUID greater than", MAX_RMUID_NUM)
+ services.ResponseRequestURITooLong414NRMNumExceed(w, MAX_RMUID_NUM)
+ return
+ }
+
+ // response 400-1
+ // check rmUID is valid
+ // todo ...
+ invalidRmUIDs := CheckValidRmUID(rmUIDValues)
+ if len(invalidRmUIDs) != 0 {
+ log.Error("rmUID is invalid")
+ services.ResponseBadRequest400RmUIDsIsInvalid(w, invalidRmUIDs)
+ return
+ }
+
+ // response 404-2
+ rmUID := CheckLocalRmUID(rmUIDValues)
+ if rmUID == "" {
+ log.Error("rmUID does not exist")
+ services.ResponseNotFound404NRMNotExist(w, rmUIDValues)
+ return
+ }
+
+ // response 404-1, uri is not exist in map
+ attrNames := GetAttrNameArr(r)
+ var Oids []string
+ Oids = *config.GetOidByFileds(qeuryUri, attrNames, &Oids)
+ if len(Oids) == 0 {
+ log.Error("Nothing of config map")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ // response 404-1, uri is not exist in map
+ var nameOids []config.NameOid
+ nameOids = *config.GetDataOidByFields(qeuryUri, attrNames, &nameOids)
+ if len(nameOids) == 0 {
+ log.Error("Nothing of config map")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ result, err2 := g.Default.Get(Oids) // Get() accepts up to g.MAX_OIDS
+ if err2 != nil {
+ log.Fatalf("Get() err: %v", err2)
+
+ }
+
+ // var nameValues []config.NameValue
+ var nameValue config.NameValue
+
+ nameValues := make(map[string]interface{})
+ nameValues["rmUID"] = rmUID
+ for i, variable := range result.Variables {
+ nameValue.Name = nameOids[i].Name
+ log.Debugf("%d: oid: %s name: %s\n", i, variable.Name, nameValue.Name)
+ // if nameOids[i].Oid == variable.Name && global.IsContain(attributeNames, nameValue.Name) {
+ if nameOids[i].Oid == variable.Name {
+ // the Value of each variable returned by Get() implements
+ // interface{}. You could do a type switch...
+ switch variable.Type {
+ case g.OctetString:
+ bytes := variable.Value.([]byte)
+ log.Debugf("string: %s\n", string(bytes))
+ nameValue.Value = string(bytes)
+ nameValues[nameValue.Name] = nameValue.Value
+ case g.Integer:
+ value := variable.Value.(int)
+ log.Debugf("integer: %d\n", value)
+ nameValue.Value = strconv.Itoa(value)
+ nameValues[nameValue.Name] = nameValue.Value
+ case g.IPAddress:
+ value := variable.Value.(string)
+ log.Debugf("IPAddress: %s\n", variable.Value)
+ nameValue.Value = value
+ nameValues[nameValue.Name] = nameValue.Value
+ default:
+ // ... or often you're just interested in numeric values.
+ // ToBigInt() will return the Value as a BigInt, for plugging
+ // into your calculations.
+ log.Debugf("number: %d\n", g.ToBigInt(variable.Value))
+ }
+ }
+ }
+
+ getResponse := services.DataResponse{nameValues}
+ services.ResponseWithJson(w, http.StatusOK, getResponse)
+}
diff --git a/features/pm/performance.go b/features/pm/performance.go
new file mode 100644
index 00000000..cece86e5
--- /dev/null
+++ b/features/pm/performance.go
@@ -0,0 +1,972 @@
+package pm
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "net/http"
+ "strconv"
+ "time"
+
+ "ems.agt/lib/dborm"
+ "ems.agt/lib/global"
+ "ems.agt/lib/log"
+ "ems.agt/lib/services"
+ "ems.agt/restagent/config"
+ "xorm.io/xorm"
+
+ "github.com/go-resty/resty/v2"
+ _ "github.com/go-sql-driver/mysql"
+ "github.com/gorilla/mux"
+)
+
+type Response struct {
+ Data interface{} `json:"data"`
+}
+
+type KpiReport struct {
+ Timestamp string `json:"TimeStamp"`
+ Task struct {
+ Period struct {
+ StartTime string `json:"StartTime"`
+ EndTime string `json:"EndTime"`
+ } `json:"Period"`
+ NE struct {
+ NEName string `json:"NEName"`
+ RmUID string `json:"rmUID"`
+ NeType string `json:"NeType"`
+ KPIs []struct {
+ KPIID string `json:"KPIID"`
+ Value int `json:"Value"`
+ Err string `json:"Err"`
+ } `json:"KPIs"`
+ } `json:"NE"`
+ } `json:"Task"`
+}
+
+type GoldKpi struct {
+ // Id int `json:"-" xorm:"pk 'id' autoincr"`
+ Date string `json:"date" xorm:"date"`
+ Index int `json:"index"`
+ StartTime string `json:"startTime"`
+ EndTime string `json:"endTime"`
+ NEName string `json:"neName" xorm:"ne_name"`
+ RmUid string `json:"rmUid" xorm:"rm_uid"`
+ NEType string `json:"neType" xorm:"ne_type"`
+ KpiId string `json:"kpiId" xorm:"kpi_id"`
+ Value int `json:"value"`
+ Error string `json:"error"`
+ Timestamp string `json:"timestamp"`
+}
+
+var (
+ // performance management
+ PostPerformanceUri = config.UriPrefix + "/performanceManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/kpiReport/{index}"
+
+ // performance management
+ PostPerformancePattern = config.UriPrefix + "/performanceManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/kpiReport/{index}"
+ MeasureTaskUri = config.UriPrefix + "/performanceManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/measureTask"
+ MeasureReportUri = config.UriPrefix + "/performanceManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/measureReport"
+ MeasureReportFmt = config.UriPrefix + "/performanceManagement/v1/elementType/%s/objectType/measureReport"
+ MeasurementUri = config.UriPrefix + "/performanceManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/measurement/{index}"
+ UriMeasureTask = config.UriPrefix + "/performanceManagement/{apiVersion}/measureTask/{netype}"
+)
+
+var xEngine *xorm.Engine
+
+type DatabaseClient struct {
+ dbType string
+ dbUrl string
+ dbConnMaxLifetime time.Duration
+ dbMaxIdleConns int
+ dbMaxOpenConns int
+ IsShowSQL bool
+
+ XEngine *xorm.Engine
+}
+
+var DbClient DatabaseClient
+
+func InitDbClient(dbType, dbUser, dbPassword, dbHost, dbPort, dbName string) error {
+ DbClient.dbUrl = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8&parseTime=true&loc=Local",
+ dbUser, dbPassword, dbHost, dbPort, dbName)
+ DbClient.dbType = dbType
+ DbClient.dbConnMaxLifetime = 0
+ DbClient.dbMaxIdleConns = 0
+ DbClient.dbMaxOpenConns = 0
+ if log.GetLevel() == log.LOG_TRACE {
+ DbClient.IsShowSQL = true
+ }
+ log.Debugf("dbType:%s dbUrl:%s:******@tcp(%s:%s)/%s??charset=utf8&parseTime=true&loc=Local",
+ dbType, dbUser, dbHost, dbPort, dbName)
+
+ var err error
+ DbClient.XEngine, err = xorm.NewEngine(DbClient.dbType, DbClient.dbUrl)
+ if err != nil {
+ log.Error("Failed to connet database:", err)
+ return err
+ }
+ DbClient.XEngine.SetConnMaxLifetime(DbClient.dbConnMaxLifetime)
+ DbClient.XEngine.SetMaxIdleConns(DbClient.dbMaxIdleConns)
+ DbClient.XEngine.SetMaxOpenConns(DbClient.dbMaxOpenConns)
+ if DbClient.IsShowSQL {
+ DbClient.XEngine.ShowSQL(true)
+ }
+ xEngine = DbClient.XEngine
+
+ return nil
+}
+
+func XormConnectDatabase(dbType, dbUser, dbPassword, dbHost, dbPort, dbName string) (*xorm.Engine, error) {
+ sqlStr := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8&parseTime=true&loc=Local",
+ dbUser, dbPassword, dbHost, dbPort, dbName)
+ log.Debugf("dbType:%s Connect to:%s:******@tcp(%s:%s)/%s?charset=utf8&parseTime=true&loc=Local",
+ dbType, dbUser, dbHost, dbPort, dbName)
+ var err error
+ xEngine, err = xorm.NewEngine(dbType, sqlStr) //1、Create xorm engine
+ if err != nil {
+ log.Error("Failed to connect database:", err)
+ return nil, err
+ }
+ if log.GetLevel() == log.LOG_TRACE {
+ xEngine.ShowSQL(true)
+ }
+ return xEngine, nil
+}
+
+func GetDateFromTimeString(fmtString string, timeString string) string {
+ t, _ := time.ParseInLocation(fmtString, timeString, time.Local)
+ return t.Format("2006-01-02")
+}
+
+func GetDateTimeFromTimeString(fmtString string, timeString string) string {
+ t, _ := time.ParseInLocation(fmtString, timeString, time.Local)
+ return t.Format(global.DateTime)
+}
+
+// process alarm post message from NFs
+func PostKPIReportFromNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("PostKPIReportFromNF processing... ")
+
+ vars := mux.Vars(r)
+ apiVer := vars["apiVersion"]
+ if apiVer != global.ApiVersionV1 {
+ log.Error("Uri api version is invalid. apiVersion:", apiVer)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ // body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
+ body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
+ if err != nil {
+ log.Error("Faile to io.ReadAll: ", err)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ log.Debug("Request body:", string(body))
+ kpiReport := new(KpiReport)
+ _ = json.Unmarshal(body, &kpiReport)
+ log.Debug("kpiReport:", kpiReport)
+
+ session := xEngine.NewSession()
+ defer session.Close()
+ goldKpi := new(GoldKpi)
+ layout := time.RFC3339Nano
+ goldKpi.Date = GetDateFromTimeString(layout, kpiReport.Task.Period.StartTime)
+ goldKpi.Index, _ = strconv.Atoi(vars["index"])
+ goldKpi.StartTime = global.GetFmtTimeString(layout, kpiReport.Task.Period.StartTime, time.DateTime)
+ goldKpi.EndTime = global.GetFmtTimeString(layout, kpiReport.Task.Period.EndTime, time.DateTime)
+ goldKpi.NEName = kpiReport.Task.NE.NEName
+ goldKpi.RmUid = kpiReport.Task.NE.RmUID
+ goldKpi.NEType = kpiReport.Task.NE.NeType
+ goldKpi.Timestamp = global.GetFmtTimeString(layout, kpiReport.Timestamp, time.DateTime)
+ for _, k := range kpiReport.Task.NE.KPIs {
+ goldKpi.KpiId = k.KPIID
+ goldKpi.Value = k.Value
+ goldKpi.Error = k.Err
+ log.Trace("goldKpi:", goldKpi)
+
+ // 启动事务
+ err := session.Begin()
+ if err != nil {
+ log.Error("Failed to Begin gold_kpi:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ gkpi := &GoldKpi{}
+ _, err = session.Where("id = ?", 1).ForUpdate().Get(gkpi)
+ if err != nil {
+ // 回滚事务
+ session.Rollback()
+ log.Error("Failed to ForUpdate gold_kpi:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ affected, err := session.Insert(goldKpi)
+ if err != nil && affected <= 0 {
+ session.Rollback()
+ log.Error("Failed to insert gold_kpi:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ // 提交事务
+ err = session.Commit()
+ if err != nil {
+ log.Error("Failed to Commit gold_kpi:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ }
+
+ services.ResponseStatusOK200Null(w)
+}
+
+type MeasureTask struct {
+ Tasks []Task `json:"Tasks"`
+ NotifyUrl string `json:"NotifyUrl"` /* "http://xEngine.xEngine.xEngine.x:xxxx/api/rest/performanceManagement/v1/elementType/smf/objectType/measureReport */
+}
+
+type Task struct {
+ Id int `json:"Id"`
+
+ StartTime string `json:"StartTime"`
+ EndTime string `json:"EndTime"`
+
+ Schedule struct {
+ Type string `json:"Type"` // 计划类型:Weekly/Monthly, 如果type为"", 则任务以StartTime和EndTime为条件进行统计, 否则以Shedule方式进行
+ Days []int `json:"Days"` // Weekly: [0,1,...,5,6] 星期日为0, Monthly: [1,2,3,...,30,31]
+ Periods []dborm.Period `json:"Periods"`
+ /*
+ Periods []struct {
+ Start string `json:"Start"` // 零点或者零点加测量粒度的整数倍
+ End string `json:"End"` //零点加测量粒度的整数倍
+ } `json:"Periods"`
+ */
+ } `json:"Schedule"`
+
+ GranulOption string `json:"GranulOption"` // 测量粒度选项:15M/30M/60M/24H
+ KPISet []dborm.KpiSetJ `json:"KPISet"`
+ /*
+ KPISet []struct {
+ Code string `json:"Code"` // 统计编码 如:SMFHA01
+ KPIs []string `json:"KPIs` // 指标项集合 ["SMF.AttCreatePduSession", "SMF.AttCreatePduSession._Dnn"]
+ } `json:"KPISet"`
+ */
+}
+
+type MeasureReport struct {
+ Id int `json:"Id"`
+ TimeStamp string `json:"TimeStamp"`
+ NeName string `json:"NeName"`
+ RmUID string `json:"rmUID"`
+ NeType string `json:"NeType"`
+
+ Report struct {
+ Period struct {
+ StartTime string `json:"StartTime"`
+ EndTime string `json:"EndTime"`
+ } `json:"Period"`
+
+ Datas []struct {
+ Code string `json:"Code"` // 统计编码 如:SMFHA01
+ KPIs []struct {
+ KPIID string `json:"KPIID"` // 指标项, 如: SMF.AttCreatePduSession._Dnn
+ KPIValues []struct {
+ Name string `json:"Name"` // 单个的写"Total", 或者指标项有多个测量项,如Dnn的名称写对应的Dnn"cmnet"/"ims"
+ Value int64 `json:"Value"`
+ } `json:"KPIValues"`
+ } `json:"KPIs"`
+ } `json:"Datas"`
+ } `json:"Report"`
+}
+
+type MeasureData struct {
+ // Id int `json:"id" xorm:"pk 'id' autoincr"`
+ Id int `json:"id" xorm:"-"`
+ Date string `json:"date" xorm:"date"`
+ TaskId int `json:"taskId"`
+ NeType string `json:"neType" xorm:"ne_type"`
+ NeName string `json:"neName" xorm:"ne_name"`
+ RmUid string `json:"rmUid" xorm:"rm_uid"`
+ GranulOption string `json:"granulOption" xorm:"granul_option"`
+ StartTime string `json:"startTime"`
+ EndTime string `json:"endTime"`
+ KpiCode string `json:"kpiCode" xorm:"kpi_code"`
+ KpiId string `json:"kpiId" xorm:"kpi_id"`
+ KpiExt string `json:"kpiExt" xorm:"kpi_ext"`
+ Value int64 `json:"value"`
+ Timestamp string `json:"timestamp"`
+}
+
+// process measure report from NFs
+func PostMeasureReportFromNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("PostMeasureReportFromNF processing... ")
+
+ // vars := mux.Vars(r)
+ // neType := vars["elementTypeValue"]
+ vars := mux.Vars(r)
+ apiVer := vars["apiVersion"]
+ if apiVer != global.ApiVersionV1 {
+ log.Error("Uri api version is invalid. apiVersion:", apiVer)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ // body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
+ body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
+ if err != nil {
+ log.Error("Faile to io.ReadAll: ", err)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ log.Debug("Request body:", string(body))
+ measureReport := new(MeasureReport)
+ _ = json.Unmarshal(body, &measureReport)
+ log.Debug("measureReport:", measureReport)
+
+ session := xEngine.NewSession()
+ defer session.Close()
+ measureData := new(MeasureData)
+ layout := global.DateTime
+ measureData.Date = GetDateFromTimeString(layout, measureReport.Report.Period.StartTime)
+ measureData.TaskId = measureReport.Id
+ measureData.StartTime = measureReport.Report.Period.StartTime
+ measureData.EndTime = measureReport.Report.Period.EndTime
+ measureData.NeType = measureReport.NeType
+ measureData.NeName = measureReport.NeName
+ measureData.RmUid = measureReport.RmUID
+ measureData.GranulOption, _ = dborm.XormGetSingleCol("measure_task", "granul_option", fmt.Sprintf("id=%d", measureReport.Id))
+ t, _ := strconv.ParseInt(measureReport.TimeStamp, 10, 64)
+ timestamp := time.Unix(t, 0)
+ log.Debug("timestamp:", timestamp.Format(layout))
+ measureData.Timestamp = timestamp.Format(layout)
+ log.Debug("Datas:", measureReport.Report.Datas)
+ for _, d := range measureReport.Report.Datas {
+ measureData.KpiCode = d.Code
+
+ log.Debug("KPIs:", d.KPIs)
+ for _, k := range d.KPIs {
+ measureData.KpiId = k.KPIID
+
+ log.Debug("KPIValues:", k.KPIValues)
+ if len(k.KPIValues) != 0 {
+ for _, v := range k.KPIValues {
+ measureData.KpiExt = v.Name
+ measureData.Value = v.Value
+ log.Debug("measureData:", measureData)
+
+ affected, err := session.Insert(measureData)
+ if err != nil && affected <= 0 {
+ log.Error("Failed to insert measure_data:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+ }
+ } else {
+ measureData.Value = 0
+ log.Debug("measureData:", measureData)
+
+ affected, err := session.Insert(measureData)
+ if err != nil && affected <= 0 {
+ log.Error("Failed to insert measure_data:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+ }
+ }
+ }
+
+ services.ResponseStatusOK204NoContent(w)
+}
+
+func PostMeasureTaskToNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("PostMeasureTaskToNF processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ neType := vars["elementTypeValue"]
+ params := r.URL.Query()
+ taskIds := params["id"]
+ log.Debug("taskIds:", taskIds)
+
+ var response *resty.Response
+ client := resty.New()
+ measureTask := new(MeasureTask)
+ measureTask.Tasks = make([]Task, 1)
+ for _, taskId := range taskIds {
+ id, _ := strconv.Atoi(taskId)
+ task, err := dborm.GetMeasureTask(id)
+ if err != nil {
+ log.Error("Failed to connect database: ", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+ log.Debug("Table Task:", task)
+
+ measureTask.Tasks[0].Id = task.Id
+ measureTask.Tasks[0].StartTime = task.StartTime
+ measureTask.Tasks[0].EndTime = task.EndTime
+ // v := new(dborm.ScheduleJson)
+ // _ = json.Unmarshal(task.Schedule, v)
+ // measureTask.Task[0].Schedule.Type = v.Type
+ // measureTask.Task[0].Schedule.Days = v.Days
+ if len(task.Schedule) >= 1 {
+ measureTask.Tasks[0].Schedule.Type = task.Schedule[0].Type
+ measureTask.Tasks[0].Schedule.Days = task.Schedule[0].Days
+ }
+ //v := new(dborm.ScheduleJ)
+ //_ = json.Unmarshal(task.Schedule, v)
+ measureTask.Tasks[0].Schedule.Periods = task.Periods
+ measureTask.Tasks[0].GranulOption = task.GranulOption
+
+ measureTask.Tasks[0].KPISet = task.KpiSet
+ ips, err := global.GetIps()
+ if err != nil {
+ log.Error("Failed to get local IP:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ log.Debug("ips:", ips)
+
+ measureTask.NotifyUrl = global.SetNotifyUrl(ips[0], config.GetYamlConfig().Rest[0].Port, fmt.Sprintf(MeasureReportFmt, neType))
+ log.Debug("Measure Task to NF:", measureTask)
+
+ if len(task.NeIds) == 0 {
+ var neInfos []dborm.NeInfo
+ err := dborm.XormGetNeInfoByNeType(neType, &neInfos)
+ if err != nil {
+ log.Error("Failed to dborm.XormGetNeInfoByNeType:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ for _, neInfo := range neInfos {
+ task.NeIds = append(task.NeIds, neInfo.NeId)
+ }
+ }
+
+ for _, neId := range task.NeIds {
+ var err error
+ neInfo, err := dborm.XormGetNeInfo(neType, neId)
+ if err != nil {
+ log.Error("Failed to dborm.XormGetNeInfo:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ if neInfo == nil {
+ err := errors.New(fmt.Sprintf("not found target NE neType=%s, neId=%s", neType, neId))
+ log.Error(err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ requestURI2NF := fmt.Sprintf("http://%s:%v%s", neInfo.Ip, neInfo.Port, r.RequestURI)
+ log.Debug("requestURI2NF: POST ", requestURI2NF)
+
+ switch task.Status {
+ case dborm.MeasureTaskStatusInactive:
+ body, _ := json.Marshal(measureTask)
+ log.Debug("body: ", string(body))
+
+ log.Debug("User-Agent: ", config.GetDefaultUserAgent())
+ response, err = client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ SetBody(body).
+ SetContentLength(true).
+ Post(requestURI2NF)
+
+ if err != nil {
+ log.Error("Post to NF failed:", err)
+ services.ResponseInternalServerError500NFConnectRefused(w)
+ return
+ }
+ log.Debug("response info: ")
+ log.Debug("Status Code:", response.StatusCode())
+ log.Debug("Status:", response.Status())
+ log.Debug("Proto:", response.Proto())
+ log.Debug("Time:", response.Time())
+ log.Debug("Received At:", response.ReceivedAt())
+ log.Debug("Size:", response.Size())
+
+ case dborm.MeasureTaskStatusSuspend:
+ body, _ := json.Marshal(measureTask)
+ log.Debug("body: ", string(body))
+ response, err = client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ SetBody(body).
+ SetContentLength(true).
+ Put(requestURI2NF)
+
+ if err != nil {
+ log.Error("Put to NF failed:", err)
+ services.ResponseInternalServerError500NFConnectRefused(w)
+ return
+ }
+ default:
+ err = errors.New(fmt.Sprintf("measure task status must be inactive id=%d", id))
+ log.Error("Unable to active measure task:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ log.Debug("StatusCode: ", response.StatusCode())
+ switch response.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ taskInfo := new(dborm.MeasureTask)
+ taskInfo.Status = dborm.MeasureTaskStatusActive
+ taskInfo.CreateTime = time.Now().Format(time.DateTime)
+ affected, err := dborm.XormUpdateTableById(id, dborm.TableNameMeasureTask, taskInfo)
+ if err != nil {
+ log.Error("dborm.XormUpdateTableById is failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ } else if affected <= 0 {
+ log.Info("Not record affected in measure_task")
+ }
+ default:
+ log.Error("NF return failure to active measure task")
+ if response != nil {
+ log.Info("response body:", string(response.Body()))
+ services.TransportResponse(w, response.StatusCode(), response.Body())
+ return
+ } else {
+ err = errors.New(fmt.Sprintf("failed to active measure task, NF return error status=%v", response.Status()))
+ log.Error("Unable to active measure task:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ }
+ }
+ }
+
+ services.ResponseStatusOK204NoContent(w)
+}
+
+func PutMeasureTaskToNF(w http.ResponseWriter, r *http.Request) {
+
+ services.ResponseStatusOK200Null(w)
+}
+
+func DeleteMeasureTaskToNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("DeleteMeasureTaskToNF processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ neType := vars["elementTypeValue"]
+ params := r.URL.Query()
+ taskIds := params["id"]
+ log.Debug("taskIds:", taskIds)
+
+ var response *resty.Response
+ respMsg := make(map[string]interface{})
+ for _, taskId := range taskIds {
+ id, _ := strconv.Atoi(taskId)
+ task, err := dborm.GetMeasureTask(id)
+ if err != nil {
+ log.Error("Failed to connect database: ", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+ log.Debug("Measure Task:", task)
+
+ if len(task.NeIds) == 0 {
+ var neInfos []dborm.NeInfo
+ err := dborm.XormGetNeInfoByNeType(neType, &neInfos)
+ if err != nil {
+ log.Error("Failed to dborm.XormGetNeInfoByNeType:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ for _, neInfo := range neInfos {
+ task.NeIds = append(task.NeIds, neInfo.NeId)
+ }
+ }
+ log.Debug("neIds:", task.NeIds)
+ if len(task.NeIds) == 0 {
+ log.Warn("Not found target NE in the measure task")
+ taskInfo := new(dborm.MeasureTask)
+ taskInfo.Status = dborm.MeasureTaskStatusDeleted
+ affected, err := dborm.XormUpdateTableById(id, dborm.TableNameMeasureTask, taskInfo)
+ if err != nil {
+ log.Error("dborm.XormUpdateTableById is failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ } else if affected <= 0 {
+ log.Info("Not record affected in measure_task")
+ }
+ services.ResponseStatusOK204NoContent(w)
+ return
+ }
+
+ for _, neId := range task.NeIds {
+ var err error
+ neInfo, err := dborm.XormGetNeInfo(neType, neId)
+ if err != nil {
+ log.Error("dborm.XormGetNeInfo is failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+ if neInfo != nil {
+ requestURI2NF := fmt.Sprintf("http://%s:%v%s", neInfo.Ip, neInfo.Port, r.RequestURI)
+ log.Debug("requestURI2NF: DELETE ", requestURI2NF)
+ client := resty.New()
+ response, err = client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ Delete(requestURI2NF)
+ if err != nil {
+ // to avoid can't delete the task for abnormal NF
+ log.Error("Failed to resty delete:", err)
+ taskInfo := new(dborm.MeasureTask)
+ taskInfo.Status = dborm.MeasureTaskStatusDeleted
+ affected, err := dborm.XormUpdateTableById(id, dborm.TableNameMeasureTask, taskInfo)
+ if err != nil {
+ log.Error("dborm.XormUpdateTableById is failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ } else if affected <= 0 {
+ log.Info("Not record affected in measure_task")
+ }
+ services.ResponseStatusOK204NoContent(w)
+ return
+ }
+
+ log.Info("StatusCode: ", response.StatusCode())
+ switch response.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ taskInfo := new(dborm.MeasureTask)
+ taskInfo.Status = dborm.MeasureTaskStatusDeleted
+ affected, err := dborm.XormUpdateTableById(id, dborm.TableNameMeasureTask, taskInfo)
+ if err != nil {
+ log.Error("dborm.XormUpdateTableById is failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ } else if affected <= 0 {
+ log.Infof("Not record affected in measure_task")
+ }
+ services.ResponseStatusOK204NoContent(w)
+ return
+ default:
+ log.Info("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ respMsg["error"] = body
+ }
+ } else {
+ taskInfo := new(dborm.MeasureTask)
+ taskInfo.Status = dborm.MeasureTaskStatusDeleted
+ affected, err := dborm.XormUpdateTableById(id, dborm.TableNameMeasureTask, taskInfo)
+ if err != nil {
+ log.Error("dborm.XormUpdateTableById is failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ } else if affected <= 0 {
+ log.Info("Not record affected in measure_task")
+ }
+ services.ResponseStatusOK204NoContent(w)
+ return
+ }
+ }
+ }
+
+ services.ResponseWithJson(w, response.StatusCode(), respMsg)
+}
+
+func PatchMeasureTaskToNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("PatchMeasureTaskToNF processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ neType := vars["elementTypeValue"]
+ params := r.URL.Query()
+ taskIds := params["id"]
+ log.Debug("taskIds:", taskIds)
+
+ var response *resty.Response
+ respMsg := make(map[string]interface{})
+ for _, taskId := range taskIds {
+ id, _ := strconv.Atoi(taskId)
+ task, err := dborm.GetMeasureTask(id)
+ if err != nil {
+ log.Error("Failed to connect database: ", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+ log.Debug("Measure Task:", task)
+
+ // for neType
+ if len(task.NeIds) == 0 {
+ var neInfos []dborm.NeInfo
+ err := dborm.XormGetNeInfoByNeType(neType, &neInfos)
+ if err != nil {
+ log.Error("Failed to dborm.XormGetNeInfoByNeType:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ for _, neInfo := range neInfos {
+ task.NeIds = append(task.NeIds, neInfo.NeId)
+ }
+ }
+
+ if len(task.NeIds) == 0 {
+ taskInfo := new(dborm.MeasureTask)
+ taskInfo.Status = dborm.MeasureTaskStatusInactive
+ affected, err := dborm.XormUpdateTableById(id, dborm.TableNameMeasureTask, taskInfo)
+ if err != nil {
+ log.Error("dborm.XormUpdateTableById is failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ } else if affected <= 0 {
+ log.Info("Not record affected in measure_task")
+ }
+ services.ResponseStatusOK204NoContent(w)
+ return
+ }
+
+ for _, neId := range task.NeIds {
+ var err error
+ neInfo, err := dborm.XormGetNeInfo(neType, neId)
+ if err != nil {
+ log.Error("dborm.XormGetNeInfo is failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+ if neInfo == nil {
+ em := errors.New("Not found NE info in database")
+ log.Error(em)
+ taskInfo := new(dborm.MeasureTask)
+ taskInfo.Status = dborm.MeasureTaskStatusInactive
+ affected, err := dborm.XormUpdateTableById(id, dborm.TableNameMeasureTask, taskInfo)
+ if err != nil {
+ log.Error("dborm.XormUpdateTableById is failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ } else if affected <= 0 {
+ log.Info("Not record affected in measure_task")
+ }
+ services.ResponseStatusOK204NoContent(w)
+ //services.ResponseInternalServerError500ProcessError(w, em)
+ return
+ }
+
+ requestURI2NF := fmt.Sprintf("http://%s:%v%s", neInfo.Ip, neInfo.Port, r.RequestURI)
+ log.Debug("requestURI2NF: PATCH ", requestURI2NF)
+ client := resty.New()
+ response, err = client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ Patch(requestURI2NF)
+ if err != nil {
+ log.Error("Patch to NF failed:", err)
+ services.ResponseInternalServerError500NFConnectRefused(w)
+ return
+ }
+
+ log.Debug("StatusCode: ", response.StatusCode())
+ switch response.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ taskInfo := new(dborm.MeasureTask)
+ taskInfo.Status = dborm.MeasureTaskStatusInactive
+ affected, err := dborm.XormUpdateTableById(id, dborm.TableNameMeasureTask, taskInfo)
+ if err != nil {
+ log.Error("dborm.XormUpdateTableById is failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ } else if affected <= 0 {
+ log.Info("Not record affected in measure_task")
+ }
+ default:
+ log.Debug("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ respMsg["error"] = body
+ }
+ }
+ }
+
+ services.ResponseWithJson(w, response.StatusCode(), respMsg)
+ return
+}
+
+type Measurement struct {
+ Id int `json:"-" xorm:"pk 'id' autoincr"`
+ Date string `json:"-" xorm:"date"`
+ Index int `json:"Index"` // 1天中测量时间粒度(如15分钟)的切片索引: 0~95
+ Timestamp string `json:"TimeStamp" xorm:"-"`
+ NeName string `json:"NeName"` // UserLabel
+ RmUID string `json:"RmUID" xorm:"rm_uid"`
+ NeType string `json:"NeType"` // 网元类型
+ PmVersion string `json:"PmVersion"` // 性能数据版本号
+ Dn string `json:"Dn"` // (???)网元标识, 如:RJN-CMZJ-TZ,SubNetwork=5GC88,ManagedElement=SMF53456,SmfFunction=53456
+ Period string `json:"Period"` // 测量时间粒度选项:5/15/30/60
+ TimeZone string `json:"TimeZone"`
+ StartTime string `json:"StartTime"`
+
+ Datas []Data `json:"Datas"`
+}
+
+type KPIValue struct {
+ Name string `json:"Name"` // 单个的写"Total", 或者指标项有多个测量项,如Dnn的名称写对应的Dnn"cmnet"/"ims"
+ Value int64 `json:"Value"`
+}
+
+type KPI struct {
+ KPIID string `json:"KPIID"` // 指标项, 如: SMF.AttCreatePduSession._Dnn
+ KPIValues []KPIValue `json:"KPIValues"`
+}
+
+type Data struct {
+ ObjectType string `json:"ObjectType"` // 网络资源类别名称, Pm指标项列表中为空间粒度 如:SmfFunction
+ KPIs []KPI `json:"KPIs"` // 指标项, 如: SMF.AttCreatePduSession._Dnn
+}
+
+// process measurement post message from NFs
+func PostMeasurementFromNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("PostMeasurementFromNF processing... ")
+
+ vars := mux.Vars(r)
+ apiVer := vars["apiVersion"]
+ if apiVer != global.ApiVersionV1 {
+ log.Error("Uri api version is invalid. apiVersion:", apiVer)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
+ if err != nil {
+ log.Error("Faile to io.ReadAll: ", err)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ log.Debug("Request body:", string(body))
+ // measurement := new(dborm.NorthboundPm)
+ measurement := new(dborm.NorthboundPm)
+ _ = json.Unmarshal(body, &measurement)
+ log.Debug("measurement:", measurement)
+
+ session := dborm.DbClient.XEngine.NewSession()
+ defer session.Close()
+
+ // layout := global.DateTime
+ layout := time.RFC3339
+ measurement.Date = GetDateFromTimeString(layout, measurement.StartTime)
+ measurement.StartTime = GetDateTimeFromTimeString(layout, measurement.StartTime)
+ affected, err := session.Table("northbound_pm").Insert(measurement)
+ if err != nil && affected <= 0 {
+ log.Error("Failed to insert northbound_pm:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+
+ services.ResponseStatusOK204NoContent(w)
+}
+
+// get measurement message from NFs
+func GetMeasurementFromNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("GetMeasurementFromNF processing... ")
+
+ _, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+
+ vars := mux.Vars(r)
+ apiVer := vars["apiVersion"]
+ if apiVer != global.ApiVersionV1 {
+ log.Error("Uri api version is invalid. apiVersion:", apiVer)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ neType := vars["elementTypeValue"]
+ if neType == "" {
+ log.Error("elementTypeValue is null.")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ params := r.URL.Query()
+ neIds := params["ne_id"]
+ if len(neIds) == 0 {
+ log.Error("ne_id NOT FOUND")
+ services.ResponseBadRequest400WrongParamValue(w)
+ return
+ }
+ log.Debugf("neType: %s neId:%s", neType, neIds)
+
+ //var neInfo *dborm.NeInfo
+ neInfo := new(dborm.NeInfo)
+
+ neInfo, err = dborm.XormGetNeInfo(neType, neIds[0])
+ if err != nil {
+ log.Error("dborm.XormGetNeInfo is failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+
+ requestURI2NF := fmt.Sprintf("http://%s:%v%s", neInfo.Ip, neInfo.Port, r.RequestURI)
+ log.Debug("requestURI2NF: GET ", requestURI2NF)
+
+ client := resty.New()
+ response, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ Get(requestURI2NF)
+ if err != nil {
+ log.Error("Failed to Get from NF:", err)
+ services.ResponseInternalServerError500NFConnectRefused(w)
+ return
+ }
+
+ respMsg := make(map[string]interface{})
+ switch response.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ log.Debug("response:", response)
+ // measurement := new(dborm.NorthboundPm)
+ measurement := new(dborm.NorthboundPm)
+ _ = json.Unmarshal(response.Body(), &measurement)
+ log.Debug("measurement:", measurement)
+
+ session := dborm.DbClient.XEngine.NewSession()
+ defer session.Close()
+
+ layout := time.RFC3339
+ measurement.Date = GetDateFromTimeString(layout, measurement.StartTime)
+ measurement.StartTime = GetDateTimeFromTimeString(layout, measurement.StartTime)
+ affected, err := session.Table("northbound_pm").Insert(measurement)
+ if err != nil && affected <= 0 {
+ log.Error("Failed to insert northbound_pm:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+ default:
+ log.Debug("response body:", string(response.Body()))
+ body := new(map[string]interface{})
+ _ = json.Unmarshal(response.Body(), &body)
+ respMsg["error"] = body
+ }
+
+ services.ResponseWithJson(w, response.StatusCode(), respMsg)
+}
diff --git a/features/security/account.go b/features/security/account.go
new file mode 100644
index 00000000..2962ec6f
--- /dev/null
+++ b/features/security/account.go
@@ -0,0 +1,175 @@
+package security
+
+import (
+ "encoding/json"
+ "io"
+ "net/http"
+
+ "ems.agt/lib/dborm"
+ "ems.agt/lib/global"
+ "ems.agt/lib/log"
+ "ems.agt/lib/oauth"
+ "ems.agt/lib/services"
+ "ems.agt/restagent/config"
+)
+
+var (
+ UriOauthToken = config.UriPrefix + "/securityManagement/{apiVersion}/oauth/token"
+ UriOauthHandshake = config.UriPrefix + "/securityManagement/{apiVersion}/oauth/handshake"
+)
+
+func LoginFromOMC(w http.ResponseWriter, r *http.Request) {
+ log.Info("LoginFromOMC processing... ")
+
+ body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen)) //io.LimitReader限制大小
+ if err != nil {
+ log.Error("Failed to ReadAll:", err)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ // check media type(content type) only support "application/json"
+ if !services.IsVallidContentType(r, config.GetYamlConfig().OMC.CheckContentType) {
+ log.Debug("Invalid Content-Type")
+ services.ResponseUnsupportedMediaType415(w)
+ return
+ }
+
+ // // check extend uri, response 404
+ // if !IsValidOAuthUri(r) {
+ // log.Debug("Uri is invalid")
+ // services.ResponseNotFound404UriNotExist(w, r)
+ // return
+ // }
+
+ // Error process ....
+ // response 400-7
+ if !json.Valid([]byte(body)) {
+ log.Error("Invalid Json Format")
+ services.ResponseBadRequest400InvalidJson(w)
+ return
+ }
+
+ var oAuthBody oauth.OAuthBody
+ _ = json.Unmarshal(body, &oAuthBody) //转为json
+ //log.Debug("body:", string(body), "oAuthBody:", oAuthBody)
+
+ defer r.Body.Close()
+ // response 400-5
+ if oauth.IsWrongOAuthInfo(oAuthBody) {
+ log.Error("Wrong parameter value")
+ services.ResponseBadRequest400WrongParamValue(w)
+ return
+ }
+ /*
+ if oauth.IsValidOAuthInfo(oAuthBody) {
+ plist := config.GetPermissionFromConfig(oAuthBody.UserName, oAuthBody.GrantType)
+ log.Debug("Permission list:", plist)
+
+ token := globalSession.NewSession(w, r, plist)
+ services.ResponseStatusOK200Login(w, token)
+ } else {
+ // response 400-4
+ log.Debug("Authentication failed, mismatch user or password")
+
+ services.ResponseBadRequest400IncorrectLogin(w)
+ }
+ */
+ validUser, user, _ := dborm.XormCheckLoginUser(oAuthBody.UserName,
+ oAuthBody.Value, config.GetYamlConfig().Auth.Crypt)
+ if !validUser {
+ // response 400-4
+ log.Error("Authentication failed, mismatch user or password")
+ services.ResponseBadRequest400IncorrectLogin(w)
+ return
+ }
+
+ token := oauth.GenRandToken() // Generate new token to session ID
+ sourceAddr := r.RemoteAddr
+ affected, err := dborm.XormInsertSession(oAuthBody.UserName, sourceAddr, token,
+ config.GetExpiresFromConfig(), config.GetYamlConfig().Auth.Session)
+ if err != nil {
+ log.Error("Failed to XormInsertSession:", err)
+ if affected == -1 {
+ services.ResponseForbidden403MultiLoginNotAllowed(w)
+ } else {
+ services.ResponseBadRequest400IncorrectLogin(w)
+ }
+
+ return
+ }
+ services.ResponseStatusOK200Login(w, token, user)
+ return
+}
+
+func LogoutFromOMC(w http.ResponseWriter, r *http.Request) {
+ log.Info("LogoutFromOMC processing... ")
+
+ // check media type(content type) only support "application/json"
+ if services.IsVallidContentType(r, config.GetYamlConfig().OMC.CheckContentType) == false {
+ log.Error("Invalid Content-Type")
+ services.ResponseUnsupportedMediaType415(w)
+ return
+ }
+
+ // check extend uri, response 404
+ if !services.IsValidOAuthUri(r) {
+ log.Error("Uri is invalid")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ // error processing ...
+ // 401-1 response
+ token, ret := oauth.IsCarriedToken(r)
+ if ret == false {
+ log.Error("AccessToken is not carried")
+ services.ResponseUnauthorized401AccessTokenNotCarried(w)
+ return
+ }
+
+ _, err := dborm.XormLogoutUpdateSession(token)
+ if err != nil {
+ log.Error("Uri is invalid")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ services.ResponseStatusOK200Null(w)
+ return
+}
+
+func HandshakeFromOMC(w http.ResponseWriter, r *http.Request) {
+ log.Info("HandshakeFromOMC processing... ")
+
+ // check media type(content type) only support "application/json"
+ if !services.IsVallidContentType(r, config.GetYamlConfig().OMC.CheckContentType) {
+ log.Debug("Invalid Content-Type")
+ services.ResponseUnsupportedMediaType415(w)
+ return
+ }
+
+ // check extend uri, response 404
+ if !services.IsValidOAuthUri(r) {
+ log.Error("Uri is invalid")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ // error processing ...
+ // 401-1 response
+ token, ret := oauth.IsCarriedToken(r)
+ if ret == false {
+ log.Error("AccessToken is not carried")
+ services.ResponseUnauthorized401AccessTokenNotCarried(w)
+ return
+ }
+
+ _, err := dborm.XormUpdateSessionShakeTime(token)
+ if err != nil {
+ log.Error("Uri is invalid")
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ services.ResponseStatusOK200Null(w)
+ return
+}
diff --git a/features/sm/backup.go b/features/sm/backup.go
new file mode 100644
index 00000000..ffb70510
--- /dev/null
+++ b/features/sm/backup.go
@@ -0,0 +1,109 @@
+package sm
+
+import (
+ "database/sql"
+ "fmt"
+ "os"
+ "os/exec"
+ "time"
+
+ "ems.agt/lib/log"
+ "ems.agt/restagent/config"
+ _ "github.com/go-sql-driver/mysql"
+)
+
+var dbConfig = config.GetYamlConfig().Database
+
+func DatabaseWhoreBackup() {
+ // MySQL数据库连接信息
+ sqlStr := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8&parseTime=true&loc=Local",
+ dbConfig.User, dbConfig.Password, dbConfig.Host, dbConfig.Port, dbConfig.Name)
+ db, err := sql.Open("mysql", sqlStr)
+ if err != nil {
+ log.Error("Failed to connect to database:", err)
+ return
+ }
+ defer db.Close()
+
+ // 备份SQL文件路径
+ backupFile := dbConfig.Backup + "/" + "whore_backup_" + dbConfig.Name + ".sql"
+
+ // 执行mysqldump命令进行备份
+ cmd := exec.Command("mysqldump", "-u", dbConfig.User, "-p"+dbConfig.Password, "-h", dbConfig.Host, dbConfig.Name)
+ output, err := cmd.Output()
+ if err != nil {
+ log.Error("Failed to execute mysqldump command:", err)
+ return
+ }
+
+ // 将备份结果写入SQL文件
+ file, err := os.Create(backupFile)
+ if err != nil {
+ log.Error("Failed to create backup file:", err)
+ return
+ }
+ defer file.Close()
+
+ _, err = file.Write(output)
+ if err != nil {
+ log.Error("Failed to write backup file:", err)
+ return
+ }
+
+ log.Info("Backup completed successfully.")
+}
+
+func DatabaseIncrementalBackup() {
+ // MySQL数据库连接信息
+ sqlStr := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8&parseTime=true&loc=Local",
+ dbConfig.User, dbConfig.Password, dbConfig.Host, dbConfig.Port, dbConfig.Name)
+ db, err := sql.Open("mysql", sqlStr)
+ if err != nil {
+ log.Error("Failed to connect to database:", err)
+ return
+ }
+ defer db.Close()
+
+ // 备份SQL文件路径
+ backupFile := dbConfig.Backup + "/" + "incremental_backup_" + dbConfig.Name + ".sql"
+
+ // 上次备份的时间点
+ lastBackupTime := time.Date(2022, time.January, 1, 0, 0, 0, 0, time.Local)
+
+ // 构建增量备份SQL语句
+ query := fmt.Sprintf("SELECT * FROM table WHERE modified_at > '%s'", lastBackupTime.Format("2006-01-02 15:04:05"))
+
+ // 执行查询
+ rows, err := db.Query(query)
+ if err != nil {
+ log.Error("Failed to execute query:", err)
+ return
+ }
+ defer rows.Close()
+
+ // 创建增量备份SQL文件
+ file, err := os.Create(backupFile)
+ if err != nil {
+ log.Error("Failed to create backup file:", err)
+ return
+ }
+ defer file.Close()
+
+ // 将查询结果写入SQL文件
+ for rows.Next() {
+ var data string
+ err := rows.Scan(&data)
+ if err != nil {
+ log.Error("Failed to scan row:", err)
+ return
+ }
+
+ _, err = file.WriteString(data + "\n")
+ if err != nil {
+ log.Error("Failed to write backup file:", err)
+ return
+ }
+ }
+
+ log.Info("Incremental backup completed successfully.")
+}
diff --git a/features/state/getstate.go b/features/state/getstate.go
new file mode 100644
index 00000000..f69cfc14
--- /dev/null
+++ b/features/state/getstate.go
@@ -0,0 +1,845 @@
+package state
+
+import (
+ "encoding/json"
+ "fmt"
+ "net/http"
+ "os"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/go-resty/resty/v2"
+ "github.com/gorilla/mux"
+
+ "ems.agt/lib/dborm"
+ "ems.agt/lib/global"
+ "ems.agt/lib/log"
+ "ems.agt/lib/services"
+ "ems.agt/restagent/config"
+)
+
+type CpuUsage struct {
+ NfCpuUsage uint16 `json:"nfCpuUsage"`
+ SysCpuUsage uint16 `json:"sysCpuUsage"`
+}
+
+type MemUsage struct {
+ TotalMem uint32 `json:"totalMem"`
+ NfUsedMem uint32 `json:"nfUsedMem"`
+ SysMemUsage uint16 `json:"sysMemUsage"`
+}
+
+type PartitionInfo struct {
+ Total uint32 `json:"total"` // MB
+ Used uint32 `json:"used"` // MB
+}
+
+type DiskSpace struct {
+ PartitionNum uint8 `json:"partitionNum"`
+ PartitionInfo []PartitionInfo `json:"partitionInfo"`
+}
+
+type HardwareInfo struct {
+ CPUs int `json:"cpus"`
+ Memory int `json:"memory"`
+}
+
+type SysState struct {
+ HostName string `json:"hostName"` // linux命令: hostname
+ OsInfo string `json:"osInfo"` // linux命令: uname -a
+ DbInfo string `json:"dbInfo"` // 网元如果有db, 显示数据库名和版本信息, OMC: mysql --version
+ Version string `json:"version"` // 软件版本信息: 16.1.1
+ IpAddr []string `json:"ipAddr"` // 网管的ipv4和ipv6列表
+ Port uint16 `json:"port"` // 用于网管的port
+ Capability uint32 `json:"capability"`
+ SerialNum string `json:"serialNum"`
+ ExpiryDate string `json:"expiryDate"`
+ HardwareInfo HardwareInfo `json:"hardwareInfo"`
+ CpuUsage CpuUsage `json:"cpuUsage"`
+ MemUsage MemUsage `json:"memUsage"`
+ DiskSpace DiskSpace `json:"diskSpace"`
+ //Timestamp string `json:"timestamp"`
+}
+
+type SystemState struct {
+ HostName string `json:"hostName"` // linux命令: hostname
+ OsInfo string `json:"osInfo"` // linux命令: uname -a
+ DbInfo string `json:"dbInfo"` // 网元如果有db, 显示数据库名和版本信息, OMC: mysql --version
+ Version string `json:"version"` // 软件版本信息: 16.1.1
+ IpAddr []string `json:"ipAddr"` // 网管的ipv4和ipv6列表
+ Port uint16 `json:"port"` // 用于网管的port
+ Capability uint32 `json:"capability"`
+ SerialNum string `json:"serialNum"`
+ ExpiryDate string `json:"expiryDate"`
+ HardwareInfo struct {
+ CPUs int `json:"cpus"` // 主机(裸机/虚拟机)的cpu个数
+ Memory int `json:"memory"` // 主机(裸机/虚拟机): 配置的内存
+ } `json:"hardwareInfo"`
+ CpuUsage struct {
+ NfCpuUsage uint16 `json:"nfCpuUsage"`
+ SysCpuUsage uint16 `json:"sysCpuUsage"`
+ } `json:"cpuUsage"`
+ MemUsage struct {
+ TotalMem uint32 `json:"totalMem"`
+ NfUsedMem uint32 `json:"nfUsedMem"`
+ SysMemUsage uint16 `json:"sysMemUsage"`
+ } `json:"memUsage"`
+ DiskSpace struct {
+ PartitionNum uint8 `json:"partitionNum"`
+ PartitionInfo []struct {
+ Total uint32 `json:"total"` // MB
+ Used uint32 `json:"used"` // MB
+ } `json:"partitionInfo"`
+ } `json:"diskSpace"`
+ //Timestamp string `json:"timestamp"`
+}
+
+type SystemInfo struct {
+ NeType string `json:"neType" map:"neType, omitempty"`
+ NeId string `json:"neId" map:"neId, omitempty"`
+ HostName string `json:"hostName" map:"hostName, omitempty"` // linux命令: hostname
+ OsInfo string `json:"osInfo" map:"osInfo, omitempty"` // linux命令: uname -a
+ DbInfo string `json:"dbInfo" map:"dbInfo, omitempty"` // 网元如果有db, 显示数据库名和版本信息, OMC: mysql --version
+ Version string `json:"version" map:"version, omitempty"` // 软件版本信息: 16.1.1
+ IpAddr string `json:"ipAddr" map:"ipAddr, omitempty"` // 网管的ipv4和ipv6列表
+ Port uint16 `json:"port" map:"port, omitempty"` // 用于网管的port
+ CPUs int `json:"cpus" map:"cpus, omitempty"`
+ TotalMem int `json:"totalMem" map:"totalMem, omitempty"`
+ PvFlag string `json:"pvFlag" map:"pvFlag, omitempty"`
+ Status string `json:"status" map:"status, omitempty"`
+}
+
+type LicenseInfo struct {
+ NeType string `json:"neType"`
+ NeId string `json:"neId"`
+ SerialNum string `json:"serialNum"`
+ Capability uint32 `json:"capability"`
+ CapUsed uint32 `json:"capUsed"`
+ FeatureEnabled []string `json:"featureEnabled"`
+ ExpiryDate string `json:"expiryDate"`
+}
+
+type Response struct {
+ Data interface{} `json:"data"`
+}
+
+var (
+ UriSysState = config.UriPrefix + "/systemManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/systemState"
+ UriSysState2 = config.UriPrefix + "/systemManagement/{apiVersion}/systemState/{elementTypeValue}"
+ UriSysInfoAll = config.UriPrefix + "/systemManagement/{apiVersion}/sysInfo"
+ UriSysInfoOne = config.UriPrefix + "/systemManagement/{apiVersion}/sysInfo/{neType}/{neId}"
+ UriLicenseInfoAll = config.UriPrefix + "/systemManagement/{apiVersion}/licenseInfo"
+ UriLicenseInfoOne = config.UriPrefix + "/systemManagement/{apiVersion}/licenseInfo/{neType}/{neId}"
+)
+
+var client = resty.New()
+
+func init() {
+ /*
+ client.
+ SetTimeout(10 * time.Second).
+ SetRetryCount(1).
+ SetRetryWaitTime(1 * time.Second).
+ SetRetryMaxWaitTime(2 * time.Second).
+ SetRetryAfter(func(client *resty.Client, resp *resty.Response) (time.Duration, error) {
+ return 0, errors.New("quota exceeded")
+ })
+ */
+ client.SetTimeout(3 * time.Second)
+}
+
+func NeStatusEnumToStr(intStatus int) string {
+ switch intStatus {
+ case 0:
+ return "active"
+ case 1:
+ return "offline"
+ case 2:
+ return "standby"
+ case 3:
+ return "maintain"
+ default:
+ return "unkown"
+ }
+}
+
+// Get system state from NF/NFs
+func GetOneLicenseInfoFromNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("GetOneLicenseInfoFromNF processing... ")
+
+ data := make([]map[string]interface{}, 0)
+
+ vars := mux.Vars(r)
+ neType := vars["neType"]
+ neId := vars["neId"]
+ if neType == "" || neId == "" {
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ token, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+ log.Debug("AccessToken:", token)
+
+ neInfo, err := dborm.XormGetNeInfo(neType, neId)
+ if err != nil {
+ log.Error("Failed to XormGetNeInfo:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ } else if neInfo == nil {
+ err := global.ErrCMNotFoundTargetNE
+ log.Error(global.ErrCMNotFoundTargetNE)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ log.Trace("neInfo:", neInfo)
+
+ //systemState := make(map[string]interface{})
+ systemState := &SysState{}
+ result := make(map[string]interface{})
+ //sysInfo := &SystemInfo{}
+ omcNeTypeLower := "omc"
+ if config.GetYamlConfig().OMC.NeType != "" {
+ omcNeTypeLower = strings.ToLower(config.GetYamlConfig().OMC.NeType)
+ }
+ if neType != omcNeTypeLower {
+ log.Debugf("r.RemoteAddr: %s omcNeTypeLower: %s", r.RemoteAddr, omcNeTypeLower)
+ var requestURI2NF string
+ if config.GetYamlConfig().OMC.TestMode == true && strings.ToLower(neType) != "udm" {
+ var udmNEs []dborm.NeInfo
+ err := dborm.XormGetNeInfoByNeType("UDM", &udmNEs)
+ if err != nil {
+ log.Error("Get system state from NF is failed:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ if len(udmNEs) > 0 {
+ udmNe := udmNEs[0]
+ hostUri := fmt.Sprintf("http://%s:%v", udmNe.Ip, udmNe.Port)
+ requestURI2NF = fmt.Sprintf("%s/api/rest/systemManagement/v1/elementType/%s/objectType/systemState",
+ hostUri, strings.ToLower(udmNe.NeType))
+ }
+ } else {
+ hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
+ requestURI2NF = fmt.Sprintf("%s/api/rest/systemManagement/v1/elementType/%s/objectType/systemState",
+ hostUri, strings.ToLower(neInfo.NeType))
+ }
+ log.Debug("requestURI2NF:", requestURI2NF)
+
+ resp, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"accessToken": token}).
+ SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ Get(requestURI2NF)
+ if err != nil {
+ log.Error("Get system state from NF is failed:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ } else {
+ log.Trace("resp.Body():", string(resp.Body()))
+ _ = json.Unmarshal(resp.Body(), &systemState)
+
+ log.Trace("systemState:", systemState)
+ capUsed := config.TDatas[neInfo.NeType].CapUsed
+ log.Tracef("neInfo.NeType:%s capUsed: %v", capUsed)
+ licenseInfo := &LicenseInfo{
+ NeType: neInfo.NeType,
+ NeId: neInfo.NeId,
+ SerialNum: systemState.SerialNum,
+ Capability: systemState.Capability,
+ CapUsed: capUsed,
+ FeatureEnabled: config.TDatas[neInfo.NeType].FeatureEnabled,
+ ExpiryDate: systemState.ExpiryDate,
+ }
+ //neItem := strings.ToUpper(neType) + "/" + neId
+ result, err = global.ToMap(*licenseInfo, "json")
+ }
+ } else {
+ systemState := GetEMSState(neInfo.Ip)
+ licenseInfo := &LicenseInfo{
+ NeType: neInfo.NeType,
+ NeId: neInfo.NeId,
+ SerialNum: systemState.SerialNum,
+ Capability: systemState.Capability,
+ CapUsed: config.TDatas[neInfo.NeType].CapUsed,
+ FeatureEnabled: config.TDatas[neInfo.NeType].FeatureEnabled,
+ ExpiryDate: systemState.ExpiryDate,
+ }
+ result, err = global.ToMap(*licenseInfo, "json")
+ // neItem := strings.ToUpper(neType) + "/" + neId
+ // result[neItem] = sysInfo
+ }
+
+ data = append(data, result)
+ log.Trace("data:", data)
+
+ var response Response
+ response.Data = data
+ services.ResponseWithJson(w, http.StatusOK, response)
+}
+
+// Get system state from NF/NFs
+func GetAllLicenseInfoFromNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("GetAllLicenseInfoFromNF processing... ")
+
+ data := make([]map[string]interface{}, 0)
+
+ token, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+ log.Debug("AccessToken:", token)
+
+ var neList []dborm.NeInfo
+ _, err = dborm.XormGetAllNeInfo(&neList)
+ omcNeTypeLower := "omc"
+ if config.GetYamlConfig().OMC.NeType != "" {
+ omcNeTypeLower = strings.ToLower(config.GetYamlConfig().OMC.NeType)
+ }
+
+ for _, ne := range neList {
+ result := make(map[string]interface{})
+ log.Debugf("r.RemoteAddr: %s omcNeTypeLower: %s", r.RemoteAddr, omcNeTypeLower)
+ log.Debug("ne: ", ne)
+ //if strings.ToLower(ne.NeType) != omcNeTypeLower || !strings.Contains(r.RemoteAddr, ne.Ip) {
+ if strings.ToLower(ne.NeType) != omcNeTypeLower {
+ // hostUri := fmt.Sprintf("http://%s:%v", ne.Ip, ne.Port)
+ // requestURI2NF := fmt.Sprintf("%s/api/rest/systemManagement/v1/elementType/%s/objectType/systemState",
+ // hostUri, strings.ToLower(ne.NeType))
+ var requestURI2NF string
+ if config.GetYamlConfig().OMC.TestMode == true && strings.ToLower(ne.NeType) != "udm" {
+ var udmNEs []dborm.NeInfo
+ err := dborm.XormGetNeInfoByNeType("UDM", &udmNEs)
+ if err != nil {
+ log.Error("Get system state from NF is failed:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ if len(udmNEs) > 0 {
+ udmNe := udmNEs[0]
+ hostUri := fmt.Sprintf("http://%s:%v", udmNe.Ip, udmNe.Port)
+ requestURI2NF = fmt.Sprintf("%s/api/rest/systemManagement/v1/elementType/%s/objectType/systemState",
+ hostUri, strings.ToLower(udmNe.NeType))
+ }
+ } else {
+ hostUri := fmt.Sprintf("http://%s:%v", ne.Ip, ne.Port)
+ requestURI2NF = fmt.Sprintf("%s/api/rest/systemManagement/v1/elementType/%s/objectType/systemState",
+ hostUri, strings.ToLower(ne.NeType))
+ }
+ log.Debug("requestURI2NF:", requestURI2NF)
+
+ resp, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"accessToken": token}).
+ SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ Get(requestURI2NF)
+ if err != nil {
+ log.Error("Get system state from NF is failed:", err)
+ // errorMessage := services.ErrorMessage{
+ // ErrorCode: "1", ErrorInfo: "Internal server error, NF connnect refused",
+ // }
+ // //result["error"] = errorMessage
+ continue
+ } else {
+ systemState := &SysState{}
+ _ = json.Unmarshal(resp.Body(), &systemState)
+ licenseInfo := &LicenseInfo{
+ NeType: ne.NeType,
+ NeId: ne.NeId,
+ SerialNum: systemState.SerialNum,
+ Capability: systemState.Capability,
+ CapUsed: config.TDatas[ne.NeType].CapUsed,
+ FeatureEnabled: config.TDatas[ne.NeType].FeatureEnabled,
+ ExpiryDate: systemState.ExpiryDate,
+ }
+ result, err = global.ToMap(*licenseInfo, "json")
+ // neItem := strings.ToUpper(ne.NeType) + "/" + ne.NeId
+ // result[neItem] = sysInfo
+ }
+ } else {
+ systemState := GetEMSState(ne.Ip)
+ licenseInfo := &LicenseInfo{
+ NeType: ne.NeType,
+ NeId: ne.NeId,
+ SerialNum: systemState.SerialNum,
+ Capability: systemState.Capability,
+ CapUsed: config.TDatas[ne.NeType].CapUsed,
+ FeatureEnabled: config.TDatas[ne.NeType].FeatureEnabled,
+ ExpiryDate: systemState.ExpiryDate,
+ }
+ result, err = global.ToMap(*licenseInfo, "json")
+ // neItem := strings.ToUpper(ne.NeType) + "/" + ne.NeId
+ // result[neItem] = sysInfo
+ }
+
+ data = append(data, result)
+ log.Trace("data:", data)
+ }
+
+ var response Response
+ response.Data = data
+ services.ResponseWithJson(w, http.StatusOK, response)
+}
+
+// Get system state from NF/NFs
+func GetOneSysinfoFromNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("GetOneSysinfoFromNF processing... ")
+
+ data := make([]map[string]interface{}, 0)
+
+ vars := mux.Vars(r)
+ neType := vars["neType"]
+ neId := vars["neId"]
+ if neType == "" || neId == "" {
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ token, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+ log.Debug("AccessToken:", token)
+
+ neInfo, err := dborm.XormGetNeInfo(neType, neId)
+ if err != nil {
+ log.Error("Failed to XormGetNeInfo:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ } else if neInfo == nil {
+ err := global.ErrCMNotFoundTargetNE
+ log.Error(global.ErrCMNotFoundTargetNE)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ log.Trace("neInfo:", neInfo)
+
+ //systemState := make(map[string]interface{})
+ systemState := &SysState{}
+ result := make(map[string]interface{})
+ //sysInfo := &SystemInfo{}
+ omcNeTypeLower := "omc"
+ if config.GetYamlConfig().OMC.NeType != "" {
+ omcNeTypeLower = strings.ToLower(config.GetYamlConfig().OMC.NeType)
+ }
+ if neType != omcNeTypeLower {
+ log.Debugf("r.RemoteAddr: %s omcNeTypeLower: %s", r.RemoteAddr, omcNeTypeLower)
+ var requestURI2NF string
+ if config.GetYamlConfig().OMC.TestMode == true && strings.ToLower(neType) != "udm" {
+ var udmNEs []dborm.NeInfo
+ err := dborm.XormGetNeInfoByNeType("UDM", &udmNEs)
+ if err != nil {
+ log.Error("Get system state from NF is failed:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ if len(udmNEs) > 0 {
+ udmNe := udmNEs[0]
+ hostUri := fmt.Sprintf("http://%s:%v", udmNe.Ip, udmNe.Port)
+ requestURI2NF = fmt.Sprintf("%s/api/rest/systemManagement/v1/elementType/%s/objectType/systemState",
+ hostUri, strings.ToLower(udmNe.NeType))
+ }
+ } else {
+ hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
+ requestURI2NF = fmt.Sprintf("%s/api/rest/systemManagement/v1/elementType/%s/objectType/systemState",
+ hostUri, strings.ToLower(neInfo.NeType))
+ }
+ log.Debug("requestURI2NF:", requestURI2NF)
+
+ resp, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"accessToken": token}).
+ SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ Get(requestURI2NF)
+ if err != nil {
+ log.Error("Get system state from NF is failed:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ } else {
+ log.Trace("resp.Body():", string(resp.Body()))
+ _ = json.Unmarshal(resp.Body(), &systemState)
+
+ log.Trace("systemState:", systemState)
+ hostName := "5gc"
+ if systemState.HostName != "" {
+ hostName = systemState.HostName
+ }
+ osInfo := "Linux 5gc 4.15.0-29-generic #31-Ubuntu SMP Tue Jul 17 15:39:52 UTC 2018 x86_64 GNU/Linux"
+ if systemState.OsInfo != "" {
+ osInfo = systemState.OsInfo
+ }
+ dbInfo := "adb v1.0.1"
+ if systemState.OsInfo != "" {
+ dbInfo = systemState.DbInfo
+ }
+ port, _ := strconv.Atoi(neInfo.Port)
+ cpus := 4
+ if systemState.HardwareInfo.CPUs != 0 {
+ cpus = systemState.HardwareInfo.CPUs
+ }
+ totalMem := 34029125632
+ if systemState.HardwareInfo.Memory != 0 {
+ totalMem = systemState.HardwareInfo.Memory
+ }
+ sysInfo := &SystemInfo{
+ NeType: neInfo.NeType,
+ NeId: neInfo.NeId,
+ HostName: hostName,
+ OsInfo: osInfo,
+ DbInfo: dbInfo,
+ Version: systemState.Version,
+ IpAddr: neInfo.Ip,
+ Port: uint16(port),
+ CPUs: cpus,
+ TotalMem: totalMem,
+ PvFlag: neInfo.PvFlag,
+ Status: NeStatusEnumToStr(neInfo.Status),
+ }
+ //neItem := strings.ToUpper(neType) + "/" + neId
+ result, err = global.ToMap(*sysInfo, "json")
+ }
+ } else {
+ systemState := GetEMSState(neInfo.Ip)
+ sysInfo := &SystemInfo{
+ NeType: neInfo.NeType,
+ NeId: neInfo.NeId,
+ HostName: systemState.HostName,
+ OsInfo: systemState.OsInfo,
+ DbInfo: systemState.DbInfo,
+ Version: systemState.Version,
+ IpAddr: neInfo.Ip,
+ Port: systemState.Port,
+ CPUs: systemState.HardwareInfo.CPUs,
+ TotalMem: systemState.HardwareInfo.Memory,
+ PvFlag: neInfo.PvFlag,
+ Status: NeStatusEnumToStr(neInfo.Status),
+ }
+ result, err = global.ToMap(*sysInfo, "json")
+ // neItem := strings.ToUpper(neType) + "/" + neId
+ // result[neItem] = sysInfo
+ }
+
+ data = append(data, result)
+ log.Trace("data:", data)
+
+ var response Response
+ response.Data = data
+ services.ResponseWithJson(w, http.StatusOK, response)
+}
+
+// Get system state from NF/NFs
+func GetAllSysinfoFromNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("GetAllSysinfoFromNF processing... ")
+
+ data := make([]map[string]interface{}, 0)
+
+ token, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+ log.Debug("AccessToken:", token)
+
+ var neList []dborm.NeInfo
+ _, err = dborm.XormGetAllNeInfo(&neList)
+ omcNeTypeLower := "omc"
+ if config.GetYamlConfig().OMC.NeType != "" {
+ omcNeTypeLower = strings.ToLower(config.GetYamlConfig().OMC.NeType)
+ }
+
+ for _, ne := range neList {
+ result := make(map[string]interface{})
+ log.Debugf("r.RemoteAddr: %s omcNeTypeLower: %s", r.RemoteAddr, omcNeTypeLower)
+ log.Debug("ne: ", ne)
+ //if strings.ToLower(ne.NeType) != omcNeTypeLower || !strings.Contains(r.RemoteAddr, ne.Ip) {
+ if strings.ToLower(ne.NeType) != omcNeTypeLower {
+ // hostUri := fmt.Sprintf("http://%s:%v", ne.Ip, ne.Port)
+ // requestURI2NF := fmt.Sprintf("%s/api/rest/systemManagement/v1/elementType/%s/objectType/systemState",
+ // hostUri, strings.ToLower(ne.NeType))
+ var requestURI2NF string
+ if config.GetYamlConfig().OMC.TestMode == true && strings.ToLower(ne.NeType) != "udm" {
+ var udmNEs []dborm.NeInfo
+ err := dborm.XormGetNeInfoByNeType("UDM", &udmNEs)
+ if err != nil {
+ log.Error("Get system state from NF is failed:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ if len(udmNEs) > 0 {
+ udmNe := udmNEs[0]
+ hostUri := fmt.Sprintf("http://%s:%v", udmNe.Ip, udmNe.Port)
+ requestURI2NF = fmt.Sprintf("%s/api/rest/systemManagement/v1/elementType/%s/objectType/systemState",
+ hostUri, strings.ToLower(udmNe.NeType))
+ }
+ } else {
+ hostUri := fmt.Sprintf("http://%s:%v", ne.Ip, ne.Port)
+ requestURI2NF = fmt.Sprintf("%s/api/rest/systemManagement/v1/elementType/%s/objectType/systemState",
+ hostUri, strings.ToLower(ne.NeType))
+ }
+ log.Debug("requestURI2NF:", requestURI2NF)
+
+ resp, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"accessToken": token}).
+ SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ Get(requestURI2NF)
+ if err != nil {
+ log.Error("Get system state from NF is failed:", err)
+ // errorMessage := services.ErrorMessage{
+ // ErrorCode: "1", ErrorInfo: "Internal server error, NF connnect refused",
+ // }
+ // //result["error"] = errorMessage
+ continue
+ } else {
+ systemState := &SysState{}
+ _ = json.Unmarshal(resp.Body(), &systemState)
+ hostName := "5gc"
+ if systemState.HostName != "" {
+ hostName = systemState.HostName
+ }
+ osInfo := "Linux 5gc 4.15.0-29-generic #31-Ubuntu SMP Tue Jul 17 15:39:52 UTC 2018 x86_64 GNU/Linux"
+ if systemState.OsInfo != "" {
+ osInfo = systemState.OsInfo
+ }
+ dbInfo := "adb v1.0.1"
+ if systemState.OsInfo != "" {
+ dbInfo = systemState.DbInfo
+ }
+ port, _ := strconv.Atoi(ne.Port)
+ cpus := 4
+ if systemState.HardwareInfo.CPUs != 0 {
+ cpus = systemState.HardwareInfo.CPUs
+ }
+ totalMem := 34029125632
+ if systemState.HardwareInfo.Memory != 0 {
+ totalMem = systemState.HardwareInfo.Memory
+ }
+ sysInfo := &SystemInfo{
+ NeType: ne.NeType,
+ NeId: ne.NeId,
+ HostName: hostName,
+ OsInfo: osInfo,
+ DbInfo: dbInfo,
+ Version: systemState.Version,
+ IpAddr: ne.Ip,
+ Port: uint16(port),
+ CPUs: cpus,
+ TotalMem: totalMem,
+ PvFlag: ne.PvFlag,
+ Status: NeStatusEnumToStr(ne.Status),
+ }
+ // neItem := strings.ToUpper(ne.NeType) + "/" + ne.NeId
+ // result[neItem] = sysInfo
+ result, err = global.ToMap(*sysInfo, "json")
+ }
+ } else {
+ port, _ := strconv.Atoi(ne.Port)
+ systemState := GetEMSState(ne.Ip)
+ sysInfo := &SystemInfo{
+ NeType: ne.NeType,
+ NeId: ne.NeId,
+ HostName: systemState.HostName,
+ OsInfo: systemState.OsInfo,
+ DbInfo: systemState.DbInfo,
+ Version: systemState.Version,
+ IpAddr: ne.Ip,
+ Port: (uint16(port)),
+ CPUs: systemState.HardwareInfo.CPUs,
+ TotalMem: systemState.HardwareInfo.Memory,
+ PvFlag: ne.PvFlag,
+ Status: NeStatusEnumToStr(ne.Status),
+ }
+ // neItem := strings.ToUpper(ne.NeType) + "/" + ne.NeId
+ // result[neItem] = sysInfo
+ result, err = global.ToMap(*sysInfo, "json")
+ }
+
+ data = append(data, result)
+ log.Trace("data:", data)
+ }
+
+ var response Response
+ response.Data = data
+ services.ResponseWithJson(w, http.StatusOK, response)
+}
+
+// Get system state from NF/NFs
+func GetStateFromNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("GetStateFromNF processing... ")
+
+ data := make([]map[string]interface{}, 0)
+
+ vars := mux.Vars(r)
+ neType := vars["elementTypeValue"]
+
+ var neList []dborm.NeInfo
+ if neType == "" {
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ token, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+ log.Debug("AccessToken:", token)
+
+ switch strings.ToLower(neType) {
+ case "all":
+ // query all NFs
+ // create rest client
+ restHostPort := fmt.Sprintf("http://127.0.0.1:%d", config.GetYamlConfig().Rest[0].Port)
+ getNeInfoPattern := fmt.Sprintf(config.UriPrefix+"/databaseManagement/v1/elementType/%s/objectType/ne_info",
+ config.GetYamlConfig().Database.Name)
+ getNeInfoURI := restHostPort + getNeInfoPattern + "?WHERE=status='0'"
+ log.Debug("getNeInfoPattern:", getNeInfoPattern)
+
+ resp, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"AccessToken": token}).
+ SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ Get(getNeInfoURI)
+ if err != nil {
+ log.Error("Get ne_info from DB is failed:", err)
+ services.ResponseInternalServerError500NFConnectRefused(w)
+ return
+ }
+
+ neList, _ = dborm.XormParseResult(resp.Body())
+ default:
+ restHostPort := fmt.Sprintf("http://127.0.0.1:%d", config.GetYamlConfig().Rest[0].Port)
+ getNeInfoPattern := fmt.Sprintf(config.UriPrefix+"/databaseManagement/v1/elementType/%s/objectType/ne_info",
+ config.GetYamlConfig().Database.Name)
+ getNeInfoURI := restHostPort + getNeInfoPattern
+ neId := services.GetUriParamString(r, "ne_id", ",", true, false)
+ if neId == "" {
+ getNeInfoURI = getNeInfoURI + fmt.Sprintf("?WHERE=status='0'+and+ne_type='%s'", neType)
+ } else {
+ getNeInfoURI = getNeInfoURI + fmt.Sprintf("?WHERE=status='0'+and+ne_type='%v'+and+ne_id+in+%v", neType, neId)
+ }
+ log.Debug("getNeInfoURI:", getNeInfoURI)
+
+ resp, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"accessToken": token}).
+ SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ Get(getNeInfoURI)
+ if err != nil {
+ log.Error("Get ne_info from DB is failed:", err)
+ services.ResponseInternalServerError500NFConnectRefused(w)
+ return
+ }
+
+ neList, _ = dborm.XormParseResult(resp.Body())
+ }
+ omcNeTypeLower := "omc"
+ if config.GetYamlConfig().OMC.NeType != "" {
+ omcNeTypeLower = strings.ToLower(config.GetYamlConfig().OMC.NeType)
+ }
+ for _, ne := range neList {
+ result := make(map[string]interface{})
+ log.Debugf("r.RemoteAddr: %s omcNeTypeLower: %s", r.RemoteAddr, omcNeTypeLower)
+ log.Debug("ne: ", ne)
+ //if strings.ToLower(ne.NeType) != omcNeTypeLower || !strings.Contains(r.RemoteAddr, ne.Ip) {
+ if strings.ToLower(ne.NeType) != omcNeTypeLower {
+ hostUri := fmt.Sprintf("http://%s:%v", ne.Ip, ne.Port)
+ requestURI2NF := fmt.Sprintf("%s/api/rest/systemManagement/v1/elementType/%s/objectType/systemState",
+ hostUri, ne.NeType)
+ log.Debug("requestURI2NF:", requestURI2NF)
+
+ result["ipAddress"] = ne.Ip
+ resp, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"accessToken": token}).
+ SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ Get(requestURI2NF)
+ if err != nil {
+ log.Error("Get system state from NF is failed:", err)
+ errorMessage := services.ErrorMessage{
+ ErrorCode: "1", ErrorInfo: "Internal server error, NF connnect refused",
+ }
+ result["error"] = errorMessage
+ } else {
+ systemState := make(map[string]interface{})
+ _ = json.Unmarshal(resp.Body(), &systemState)
+ result["systemState"] = systemState
+ }
+ } else {
+ result["ipAddress"] = ne.Ip
+ emsState := GetEMSState(ne.Ip)
+ result["systemState"] = emsState
+ }
+ neItem := strings.ToUpper(ne.NeType) + "/" + ne.NeId
+ mapState := make(map[string]interface{})
+ mapState[neItem] = result
+
+ data = append(data, mapState)
+ log.Trace("data:", data)
+ }
+
+ var response Response
+ response.Data = data
+ services.ResponseWithJson(w, http.StatusOK, response)
+}
+
+func GetEMSState(ip string) *SysState {
+ log.Debug("GetEMSState processing... ")
+
+ sysInfo := new(SysInfo)
+ err := GetSysInfo(sysInfo)
+ if err != nil {
+ log.Error("Failed to GetSysInfo:", err)
+ return nil
+ }
+
+ cpuUsage := &CpuUsage{
+ NfCpuUsage: sysInfo.MyCpuPercent,
+ SysCpuUsage: sysInfo.SysCpuPercent,
+ }
+
+ memUsage := &MemUsage{
+ TotalMem: sysInfo.SysTotalRam,
+ NfUsedMem: sysInfo.MyUsedRam,
+ SysMemUsage: sysInfo.SysRamUsedPercent,
+ }
+
+ diskSpace := &DiskSpace{
+ PartitionNum: sysInfo.PartitionNum,
+ PartitionInfo: sysInfo.PartitionInfo,
+ }
+
+ version := "16.1.1"
+ if global.Version != "" {
+ version = global.Version
+ }
+ hostName, _ := os.Hostname()
+ emsState := &SysState{
+ HostName: hostName,
+ OsInfo: getUnameStr(),
+ DbInfo: "mysql Ver 15.1 Distrib 10.3.35-MariaDB, for Linux (aarch64) using readline 5.1",
+ IpAddr: []string{ip},
+ Port: 3030,
+ Version: version,
+ Capability: 9999999,
+ SerialNum: config.GetYamlConfig().OMC.Sn,
+ ExpiryDate: "-",
+ HardwareInfo: HardwareInfo{CPUs: getCpuNumber(), Memory: getTotalMemory()},
+ CpuUsage: *cpuUsage,
+ MemUsage: *memUsage,
+ DiskSpace: *diskSpace,
+ }
+
+ //getSystemInfo()
+ return emsState
+}
diff --git a/features/state/state_linux.go b/features/state/state_linux.go
new file mode 100644
index 00000000..2c9a330b
--- /dev/null
+++ b/features/state/state_linux.go
@@ -0,0 +1,243 @@
+//go:build linux
+// +build linux
+
+package state
+
+import (
+ "encoding/binary"
+ "fmt"
+ "os"
+ "runtime"
+ "syscall"
+ "time"
+
+ "ems.agt/lib/log"
+ "github.com/shirou/gopsutil/cpu"
+ "github.com/shirou/gopsutil/disk"
+ "github.com/shirou/gopsutil/mem"
+ "github.com/shirou/gopsutil/process"
+)
+
+type SysInfo struct {
+ SysCpuPercent uint16 // x%
+ MyCpuPercent uint16 // x%, CPU percent of current proccess
+
+ SysTotalRam uint32 // KB
+ MyUsedRam uint32 // RAM usage of current proccess, KB
+ SysRamUsedPercent uint16 // x%
+
+ PartitionNum byte
+ PartitionInfo []PartitionInfo // usage of each partition
+}
+
+const MAX_PARTITION_NUM byte = 32
+
+func GetSysStat() ([]byte, int) {
+ // Get sys info
+ var sysInfo SysInfo
+ err := GetSysInfo(&sysInfo)
+ if err != nil {
+ return nil, 0
+ }
+
+ //log.Tracef("current sys info: %v", sysInfo)
+
+ // build ems buffer
+ var data []byte = make([]byte, 1024)
+ var len int
+ var i byte
+ binary.BigEndian.PutUint16(data[0:], sysInfo.MyCpuPercent) //x% * 100
+ binary.BigEndian.PutUint16(data[2:], sysInfo.SysCpuPercent) //x% * 100
+ binary.BigEndian.PutUint32(data[4:], sysInfo.SysTotalRam) // KB
+ binary.BigEndian.PutUint32(data[8:], sysInfo.MyUsedRam) // KB
+ binary.BigEndian.PutUint16(data[12:], sysInfo.SysRamUsedPercent) //x% * 100
+ data[14] = sysInfo.PartitionNum
+ for i = 0; i < sysInfo.PartitionNum; i++ {
+ binary.BigEndian.PutUint32(data[15+8*(i):], sysInfo.PartitionInfo[i].Total) // MB
+ binary.BigEndian.PutUint32(data[15+8*(i)+4:], sysInfo.PartitionInfo[i].Used) // MB
+ }
+ len = int(15 + 8*sysInfo.PartitionNum)
+
+ //log.Tracef("current sys stat buf: %v, len: %d", data, len)
+
+ return data, len
+}
+
+var pProc *process.Process = nil
+
+func GetSYsCpuPercent() float64 {
+ totalPercent, err := cpu.Percent(0, false) //(2*time.Second, false)
+ if err != nil {
+ return 0.0
+ } else {
+ return totalPercent[0]
+ }
+}
+
+func GetSysInfo(sysInfo *SysInfo) error {
+ // sys cpu percent
+ totalPercent, err := cpu.Percent(0, false) //(2*time.Second, false)
+ if err != nil {
+ sysInfo.SysCpuPercent = 0
+ } else {
+ sysInfo.SysCpuPercent = uint16(totalPercent[0] * 100)
+ }
+
+ if pProc == nil {
+ checkPid := os.Getpid()
+ pProc, err = process.NewProcess(int32(checkPid))
+ if err != nil {
+ log.Tracef("get process info error %v", err)
+ return err
+ }
+ }
+
+ // self cpu percent
+ percent, err := pProc.Percent(0) //(2*time.Second)
+ if err != nil {
+ log.Tracef("get process cpu percent error %v", err)
+ sysInfo.MyCpuPercent = 0
+ } else {
+ sysInfo.MyCpuPercent = uint16(percent * 100)
+ }
+
+ // self RAM(KB)
+ myRam, err := pProc.MemoryInfo()
+ if err != nil {
+ log.Tracef("get self memory info error %v", err)
+ sysInfo.MyUsedRam = 0
+ } else {
+ sysInfo.MyUsedRam = uint32(myRam.RSS / 1024)
+ }
+
+ // system RAM(KB)
+ sysRam, err := mem.VirtualMemory()
+ if err != nil {
+ log.Tracef("gett sys memory info error %v", err)
+ sysInfo.SysTotalRam = 0
+ sysInfo.SysRamUsedPercent = 0
+ } else {
+ sysInfo.SysTotalRam = uint32(sysRam.Total / 1024)
+ sysInfo.SysRamUsedPercent = uint16(sysRam.UsedPercent * 100)
+ }
+
+ // partition usage
+ GetPartitions(sysInfo)
+ return nil
+}
+
+func getProcess() process.Process {
+ checkPid := os.Getpid()
+ ret, _ := process.NewProcess(int32(checkPid))
+ return *ret
+}
+
+func GetSystemCpuInfo() {
+ physicalCnt, _ := cpu.Counts(false)
+ logicalCnt, _ := cpu.Counts(true)
+ log.Tracef("physical count:%d logical count:%d", physicalCnt, logicalCnt)
+
+ totalPercent, _ := cpu.Percent(3*time.Second, false) // per cpu is false
+ perPercents, _ := cpu.Percent(3*time.Second, true) // per cpu is true
+ log.Tracef("total percent:%v per percents:%v", totalPercent, perPercents)
+}
+
+func GetProcessCpuPercent() {
+ p := getProcess()
+ percent, err := p.Percent(0)
+ if err != nil {
+ log.Tracef("error %v", err)
+ }
+
+ numcpu := runtime.NumCPU()
+ // if percent < 0.0 || percent > 100.0*float64(numcpu) { // TODO
+ if percent < 0.0 {
+ log.Tracef("Err CPU Percent of Process: %f, CPU num: %d", percent, numcpu)
+ } else {
+ log.Tracef("get process CPU percent: %f, CPU num: %d", percent, numcpu)
+ }
+}
+
+func GetProcessMemoryInfo() {
+ p := getProcess()
+
+ v, err := p.MemoryInfo()
+ if err != nil {
+ log.Tracef("getting memory info error %v", err)
+ }
+
+ log.Tracef("get process memory info %v", v)
+
+ info, _ := mem.VirtualMemory()
+ fmt.Println(info)
+}
+
+func GetPartitions(sysInfo *SysInfo) {
+ sysInfo.PartitionNum = 0
+ //sysInfo.PartitionInfo = make([]PartitionInfo, MAX_PARTITION_NUM, MAX_PARTITION_NUM)
+ infos, _ := disk.Partitions(true)
+ for _, info := range infos {
+ GetOnePartitionUsage(info.Mountpoint, sysInfo)
+ if sysInfo.PartitionNum >= MAX_PARTITION_NUM {
+ break
+ }
+ }
+}
+
+func GetOnePartitionUsage(path string, sysInfo *SysInfo) int {
+ info, err := disk.Usage(path)
+ if err != nil {
+ return -1
+ }
+
+ if info.Total <= 0 { // info.Used/(1024 * 1024)MB
+ return 0
+ }
+ var partition PartitionInfo
+ partition.Total = uint32(info.Total / 1024 / 1024)
+ partition.Used = uint32(info.Used / 1024 / 1024)
+ sysInfo.PartitionInfo = append(sysInfo.PartitionInfo, partition)
+ sysInfo.PartitionNum++
+
+ /*data, err := json.MarshalIndent(info, "", " ")
+ if err != nil {
+ return -1
+ }
+
+ fmt.Println(string(data))*/
+ return 1
+}
+
+func getOS() string {
+ var osname string
+ if runtime.GOOS == "linux" {
+ osname = "GNU/Linux"
+ }
+ return osname
+}
+
+func utsnameToString(unameArray [65]int8) string {
+ var byteString [65]byte
+ var indexLength int
+ for ; unameArray[indexLength] != 0 && indexLength < 65; indexLength++ {
+ byteString[indexLength] = uint8(unameArray[indexLength])
+ }
+ return string(byteString[:indexLength])
+}
+
+func getUnameStr() string {
+ var utsname = syscall.Utsname{}
+ err := syscall.Uname(&utsname)
+ if err == nil {
+ name := utsnameToString(utsname.Sysname)
+ node := utsnameToString(utsname.Nodename)
+ release := utsnameToString(utsname.Release)
+ version := utsnameToString(utsname.Version)
+ machine := utsnameToString(utsname.Machine)
+ //domain:= utsnameToString(utsname.Domainname)
+ osName := getOS()
+ return fmt.Sprintf("%s %s %s %s %s %s", name, node,
+ release, version, machine, osName)
+ }
+ return ""
+}
diff --git a/features/state/state_windows.go b/features/state/state_windows.go
new file mode 100644
index 00000000..548dbe30
--- /dev/null
+++ b/features/state/state_windows.go
@@ -0,0 +1,231 @@
+//go:build windows
+// +build windows
+
+package state
+
+import (
+ "encoding/binary"
+ "fmt"
+ "os"
+ "runtime"
+ "syscall"
+ "time"
+
+ "github.com/shirou/gopsutil/cpu"
+ "github.com/shirou/gopsutil/disk"
+ "github.com/shirou/gopsutil/mem"
+ "github.com/shirou/gopsutil/process"
+)
+
+type SysInfo struct {
+ SysCpuPercent uint16 // x%
+ MyCpuPercent uint16 // x%, CPU percent of current proccess
+
+ SysTotalRam uint32 // KB
+ MyUsedRam uint32 // RAM usage of current proccess, KB
+ SysRamUsedPercent uint16 // x%
+
+ PartitionNum byte
+ PartitionInfo []PartitionInfo // usage of each partition
+}
+
+const MAX_PARTITION_NUM byte = 32
+
+func GetSysStat() ([]byte, int) {
+ // Get sys info
+ var sysInfo SysInfo
+ err := GetSysInfo(&sysInfo)
+ if err != nil {
+ return nil, 0
+ }
+
+ //fmt.Printf("current sys info: %v", sysInfo)
+
+ // build ems buffer
+ var data []byte = make([]byte, 1024)
+ var len int
+ var i byte
+ binary.BigEndian.PutUint16(data[0:], sysInfo.MyCpuPercent) //x% * 100
+ binary.BigEndian.PutUint16(data[2:], sysInfo.SysCpuPercent) //x% * 100
+ binary.BigEndian.PutUint32(data[4:], sysInfo.SysTotalRam) // KB
+ binary.BigEndian.PutUint32(data[8:], sysInfo.MyUsedRam) // KB
+ binary.BigEndian.PutUint16(data[12:], sysInfo.SysRamUsedPercent) //x% * 100
+ data[14] = sysInfo.PartitionNum
+ for i = 0; i < sysInfo.PartitionNum; i++ {
+ binary.BigEndian.PutUint32(data[15+8*(i):], sysInfo.PartitionInfo[i].Total) // MB
+ binary.BigEndian.PutUint32(data[15+8*(i)+4:], sysInfo.PartitionInfo[i].Used) // MB
+ }
+ len = int(15 + 8*sysInfo.PartitionNum)
+
+ //fmt.Printf("current sys stat buf: %v, len: %d", data, len)
+
+ return data, len
+}
+
+var pProc *process.Process = nil
+
+func GetSYsCpuPercent() float64 {
+ totalPercent, err := cpu.Percent(0, false) //(2*time.Second, false)
+ if err != nil {
+ return 0.0
+ } else {
+ return totalPercent[0]
+ }
+}
+
+func GetSysInfo(sysInfo *SysInfo) error {
+ // sys cpu percent
+ totalPercent, err := cpu.Percent(0, false) //(2*time.Second, false)
+ if err != nil {
+ sysInfo.SysCpuPercent = 0
+ } else {
+ sysInfo.SysCpuPercent = uint16(totalPercent[0] * 100)
+ }
+
+ if pProc == nil {
+ checkPid := os.Getpid()
+ pProc, err = process.NewProcess(int32(checkPid))
+ if err != nil {
+ fmt.Printf("get process info error %v", err)
+ return err
+ }
+ }
+
+ // self cpu percent
+ percent, err := pProc.Percent(0) //(2*time.Second)
+ if err != nil {
+ fmt.Printf("get process cpu percent error %v", err)
+ sysInfo.MyCpuPercent = 0
+ } else {
+ sysInfo.MyCpuPercent = uint16(percent * 100)
+ }
+
+ // self RAM(KB)
+ myRam, err := pProc.MemoryInfo()
+ if err != nil {
+ fmt.Printf("get self memory info error %v", err)
+ sysInfo.MyUsedRam = 0
+ } else {
+ sysInfo.MyUsedRam = uint32(myRam.RSS / 1024)
+ }
+
+ // system RAM(KB)
+ sysRam, err := mem.VirtualMemory()
+ if err != nil {
+ fmt.Printf("gett sys memory info error %v", err)
+ sysInfo.SysTotalRam = 0
+ sysInfo.SysRamUsedPercent = 0
+ } else {
+ sysInfo.SysTotalRam = uint32(sysRam.Total / 1024)
+ sysInfo.SysRamUsedPercent = uint16(sysRam.UsedPercent * 100)
+ }
+
+ // partition usage
+ GetPartitions(sysInfo)
+ return nil
+}
+
+func getProcess() process.Process {
+ checkPid := os.Getpid()
+ ret, _ := process.NewProcess(int32(checkPid))
+ return *ret
+}
+
+func GetSystemCpuInfo() {
+ physicalCnt, _ := cpu.Counts(false)
+ logicalCnt, _ := cpu.Counts(true)
+ fmt.Printf("physical count:%d logical count:%d\n", physicalCnt, logicalCnt)
+
+ totalPercent, _ := cpu.Percent(3*time.Second, false) // per cpu is false
+ perPercents, _ := cpu.Percent(3*time.Second, true) // per cpu is true
+ fmt.Printf("total percent:%v per percents:%v\n", totalPercent, perPercents)
+}
+
+func GetProcessCpuPercent() {
+ p := getProcess()
+ percent, err := p.Percent(0)
+ if err != nil {
+ fmt.Printf("error %v", err)
+ }
+
+ numcpu := runtime.NumCPU()
+ // if percent < 0.0 || percent > 100.0*float64(numcpu) { // TODO
+ if percent < 0.0 {
+ fmt.Printf("Err CPU Percent of Process: %f, CPU num: %d", percent, numcpu)
+ } else {
+ fmt.Printf("get process CPU percent: %f, CPU num: %d", percent, numcpu)
+ }
+}
+
+func GetProcessMemoryInfo() {
+ p := getProcess()
+
+ v, err := p.MemoryInfo()
+ if err != nil {
+ fmt.Printf("getting memory info error %v", err)
+ }
+
+ fmt.Printf("get process memory info %v\n", v)
+
+ info, _ := mem.VirtualMemory()
+ fmt.Println(info)
+}
+
+func GetPartitions(sysInfo *SysInfo) {
+ sysInfo.PartitionNum = 0
+ //sysInfo.PartitionInfo = make([]PartitionInfo, MAX_PARTITION_NUM, MAX_PARTITION_NUM)
+ infos, _ := disk.Partitions(true)
+ for _, info := range infos {
+ GetOnePartitionUsage(info.Mountpoint, sysInfo)
+ if sysInfo.PartitionNum >= MAX_PARTITION_NUM {
+ break
+ }
+ }
+}
+
+func GetOnePartitionUsage(path string, sysInfo *SysInfo) int {
+ info, err := disk.Usage(path)
+ if err != nil {
+ return -1
+ }
+
+ if info.Total <= 0 { // info.Used/(1024 * 1024)MB
+ return 0
+ }
+ var partition PartitionInfo
+ partition.Total = uint32(info.Total / 1024 / 1024)
+ partition.Used = uint32(info.Used / 1024 / 1024)
+ sysInfo.PartitionInfo = append(sysInfo.PartitionInfo, partition)
+ sysInfo.PartitionNum++
+
+ /*data, err := json.MarshalIndent(info, "", " ")
+ if err != nil {
+ return -1
+ }
+
+ fmt.Println(string(data))*/
+ return 1
+}
+
+func getOS() string {
+ var osname string
+ if runtime.GOOS == "linux" {
+ osname = "GNU/Linux"
+ }
+ return osname
+}
+
+func utsnameToString(unameArray [65]int8) string {
+ var byteString [65]byte
+ var indexLength int
+ for ; unameArray[indexLength] != 0 && indexLength < 65; indexLength++ {
+ byteString[indexLength] = uint8(unameArray[indexLength])
+ }
+ return string(byteString[:indexLength])
+}
+
+func getUnameStr() string {
+ osInfo, _ := syscall.GetVersion()
+
+ return fmt.Sprintf("Widnows %d", osInfo)
+}
diff --git a/features/state/sysinfo.go b/features/state/sysinfo.go
new file mode 100644
index 00000000..9aa90805
--- /dev/null
+++ b/features/state/sysinfo.go
@@ -0,0 +1,74 @@
+package state
+
+import (
+ "ems.agt/lib/log"
+ "github.com/shirou/gopsutil/cpu"
+ "github.com/shirou/gopsutil/disk"
+ "github.com/shirou/gopsutil/host"
+ "github.com/shirou/gopsutil/mem"
+)
+
+func getSystemInfo() {
+ // 获取主机信息
+ hostInfo, err := host.Info()
+ if err != nil {
+ log.Errorf("Failed to get host info: %v", err)
+ return
+ }
+ log.Tracef("Host info: %+v", hostInfo)
+
+ // 获取CPU信息
+ cpuInfo, err := cpu.Info()
+ if err != nil {
+ log.Errorf("Failed to get CPU info: %v", err)
+ return
+ }
+ log.Tracef("CPU info: %+v", cpuInfo)
+
+ // 获取内存信息
+ memInfo, err := mem.VirtualMemory()
+ if err != nil {
+ log.Errorf("Failed to get memory info: %v", err)
+ return
+ }
+ log.Tracef("Memory info: %+v", memInfo)
+
+ // 获取磁盘分区信息
+ diskPartitions, err := disk.Partitions(true)
+ if err != nil {
+ log.Errorf("Failed to get disk partitions: %v", err)
+ return
+ }
+ log.Tracef("Disk partitions: %+v", diskPartitions)
+ for _, partition := range diskPartitions {
+ // 获取每个磁盘分区的使用情况
+ usage, err := disk.Usage(partition.Mountpoint)
+ if err != nil {
+ log.Errorf("Failed to get disk usage for %s: %v", partition.Mountpoint, err)
+ continue
+ }
+ log.Tracef("%s usage: %+v", partition.Mountpoint, usage)
+ }
+}
+
+func getCpuNumber() int {
+ // 获取CPU信息
+ cpuInfo, err := cpu.Info()
+ if err != nil {
+ log.Errorf("Failed to get CPU info: %v", err)
+ return 0
+ }
+ log.Tracef("CPU info: %+v", cpuInfo)
+ return len(cpuInfo)
+}
+
+func getTotalMemory() int {
+ // 获取内存信息
+ memInfo, err := mem.VirtualMemory()
+ if err != nil {
+ log.Errorf("Failed to get memory info: %v", err)
+ return 0
+ }
+ log.Tracef("Memory info: %+v", memInfo)
+ return int(memInfo.Total)
+}
diff --git a/features/trace/trace.go b/features/trace/trace.go
new file mode 100644
index 00000000..15b136b6
--- /dev/null
+++ b/features/trace/trace.go
@@ -0,0 +1,369 @@
+package trace
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "strings"
+
+ "github.com/go-resty/resty/v2"
+
+ "ems.agt/lib/dborm"
+ "ems.agt/lib/global"
+ "ems.agt/lib/log"
+ "ems.agt/lib/services"
+ "ems.agt/restagent/config"
+)
+
+var (
+ UriTraceTaskV1 = config.UriPrefix + "/traceManagement/v1/subscriptions"
+ UriTraceTask = config.UriPrefix + "/traceManagement/{apiVersion}/subscriptions"
+)
+
+type TraceTask struct {
+ Id int `json:"id" xorm:"pk 'id' autoincr"`
+ TraceType string `json:"traceType"`
+ StartTime string `json:"startTime"`
+ EndTime string `json:"endTime"`
+ Imsi string `json:"imsi"`
+ Msisdn string `json:"msisdn"`
+ SrcIp string `json:"srcIp"`
+ DstIp string `json:"dstIp"`
+ SignalPort int16 `json:"signalPort"`
+ NeType string `json:"neType"`
+ NeId string `json:"neId"`
+ UeIp string `json:"ueIp"`
+ Interfaces []string `json:"interfaces"`
+ NotifyUrl string `json:"notifyUrl" xorm:"-"`
+ Status string `json:"-" xorm:"status"`
+ SuccNEs []string `json:"-" xorm:"succ_nes"`
+ FailNEs []string `json:"-" xorm:"fail_nes"`
+ UpdateTime string `json:"-" xorm:"-"`
+}
+
+var client = resty.New()
+
+/*
+func init() {
+ client.SetTimeout(3 * time.Second)
+}
+*/
+
+// Post trace task to NF/NFs
+func PostTraceTaskToNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("PostTraceTaskToNF processing... ")
+
+ //vars := mux.Vars(r)
+
+ token, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+ log.Debug("AccessToken:", token)
+
+ body, err := io.ReadAll(io.LimitReader(r.Body, int64(config.GetYamlConfig().Params.UriMaxLen)))
+ if err != nil {
+ log.Error("io.ReadAll is failed:", err)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ log.Trace("body:", string(body))
+
+ traceTask := new(TraceTask)
+ _ = json.Unmarshal(body, traceTask)
+ log.Debug("traceTask:", traceTask)
+
+ var neTypes []string
+ // do not set device
+ if traceTask.NeType == "" {
+ // query neType by interface
+ if len(traceTask.Interfaces) > 0 {
+ err := dborm.XormGetSingleColStringArrayByIn("trace_info", "ne_type", "interface", traceTask.Interfaces, &neTypes)
+ if err != nil {
+ log.Error("Failed to dborm.XormGetSingleCol:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ }
+ } else {
+ neTypes = append(neTypes, traceTask.NeType)
+ }
+ log.Debug("neTypes:", neTypes)
+
+ traceTask.Status = "Inactive"
+ _, err = dborm.XormInsertTableOne("trace_task", traceTask)
+ if err != nil {
+ log.Error("Failed to dborm.XormInsertTableOne:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ traceTask.NotifyUrl = config.GetYamlConfig().OMC.GtpUri
+ log.Trace("traceTask:", traceTask)
+
+ for _, neType := range neTypes {
+ var neInfos []dborm.NeInfo
+ if traceTask.NeId == "" {
+ err := dborm.XormGetNeInfoByNeType(neType, &neInfos)
+ if err != nil {
+ log.Error("Failed to dborm.XormGetNeInfoByNeType:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ } else {
+ neInfo, err := dborm.XormGetNeInfo(neType, traceTask.NeId)
+ if err != nil {
+ log.Error("Failed to dborm.XormGetNeInfoByNeType:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ neInfos = append(neInfos, *neInfo)
+ }
+ for _, neInfo := range neInfos {
+ hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
+ requestURI2NF := fmt.Sprintf("%s%s", hostUri, UriTraceTaskV1)
+ log.Debug("requestURI2NF:", requestURI2NF)
+
+ body, _ := json.Marshal(traceTask)
+ log.Debug("body:", string(body))
+ resp, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ SetBody(body).
+ Post(requestURI2NF)
+ if err != nil {
+ log.Error("Failed to Post:", err)
+ failNE := fmt.Sprintf("%s.%s", neInfo.NeType, neInfo.NeId)
+ traceTask.FailNEs = append(traceTask.FailNEs, failNE)
+ } else {
+ switch resp.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ succNE := fmt.Sprintf("%s.%s", neInfo.NeType, neInfo.NeId)
+ traceTask.SuccNEs = append(traceTask.SuccNEs, succNE)
+ default:
+ log.Warn("Post return code:%d, message:%s", resp.StatusCode(), string(resp.Body()))
+ failNE := fmt.Sprintf("%s.%s", neInfo.NeType, neInfo.NeId)
+ traceTask.FailNEs = append(traceTask.FailNEs, failNE)
+ }
+ }
+ }
+ }
+
+ if len(traceTask.SuccNEs) > 0 {
+ traceTask.Status = "Active"
+ _, err = dborm.XormUpdateTableById(traceTask.Id, "trace_task", traceTask)
+ if err != nil {
+ log.Error("Failed to dborm.XormUpdateTableById:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ services.ResponseStatusOK204NoContent(w)
+ } else {
+ traceTask.Status = "Failed"
+ _, err = dborm.XormUpdateTableById(traceTask.Id, "trace_task", traceTask)
+ if err != nil {
+ log.Error("Failed to dborm.XormUpdateTableById:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ err = global.ErrTraceFailedDistributeToNEs
+ log.Error(err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+}
+
+func PutTraceTaskToNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("PutTraceTaskToNF processing... ")
+
+ //vars := mux.Vars(r)
+
+ token, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+ log.Debug("AccessToken:", token)
+
+ body, err := io.ReadAll(io.LimitReader(r.Body, int64(config.GetYamlConfig().Params.UriMaxLen)))
+ if err != nil {
+ log.Error("io.ReadAll is failed:", err)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+
+ traceTask := new(TraceTask)
+ _ = json.Unmarshal(body, traceTask)
+
+ traceTask.NotifyUrl = config.GetYamlConfig().OMC.GtpUri
+ log.Debug("traceTask:", traceTask)
+
+ var neTypes []string
+ // do not set device
+ if traceTask.NeType == "" {
+ // query neType by interface
+ if len(traceTask.Interfaces) > 0 {
+ err := dborm.XormGetSingleColStringArrayByIn("trace_info", "ne_type", "interface", traceTask.Interfaces, &neTypes)
+ if err != nil {
+ log.Error("Failed to dborm.XormGetSingleColStringArrayByIn:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ }
+ } else {
+ neTypes = append(neTypes, traceTask.NeType)
+ }
+ log.Debug("neTypes:", neTypes)
+
+ for _, neType := range neTypes {
+ var neInfos []dborm.NeInfo
+ if traceTask.NeId == "" {
+ err := dborm.XormGetNeInfoByNeType(neType, &neInfos)
+ if err != nil {
+ log.Error("Failed to dborm.XormGetNeInfoByNeType:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ } else {
+ neInfo, err := dborm.XormGetNeInfo(neType, traceTask.NeId)
+ if err != nil {
+ log.Error("Failed to dborm.XormGetNeInfoByNeType:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ neInfos = append(neInfos, *neInfo)
+ }
+ for _, neInfo := range neInfos {
+ hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
+ requestURI2NF := fmt.Sprintf("%s%s", hostUri, UriTraceTaskV1)
+ log.Debug("requestURI2NF:", requestURI2NF)
+
+ body, _ := json.Marshal(traceTask)
+ log.Debug("body:", string(body))
+ resp, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ SetBody(body).
+ Put(requestURI2NF)
+ if err != nil {
+ log.Error("Failed to Put:", err)
+ failNE := fmt.Sprintf("%s.%s", neInfo.NeType, neInfo.NeId)
+ traceTask.FailNEs = append(traceTask.FailNEs, failNE)
+ } else {
+ switch resp.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ succNE := fmt.Sprintf("%s.%s", neInfo.NeType, neInfo.NeId)
+ traceTask.SuccNEs = append(traceTask.SuccNEs, succNE)
+ default:
+ log.Warn("Post return code:%d, message:%s", resp.StatusCode(), string(resp.Body()))
+ failNE := fmt.Sprintf("%s.%s", neInfo.NeType, neInfo.NeId)
+ traceTask.FailNEs = append(traceTask.FailNEs, failNE)
+ }
+ }
+
+ }
+ }
+
+ if len(traceTask.SuccNEs) > 0 {
+ traceTask.Status = "Active"
+ _, err = dborm.XormUpdateTableById(traceTask.Id, "trace_task", traceTask)
+ if err != nil {
+ log.Error("Failed to dborm.XormUpdateTableById:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ services.ResponseStatusOK204NoContent(w)
+ } else {
+ traceTask.Status = "Failed"
+ _, err = dborm.XormUpdateTableById(traceTask.Id, "trace_task", traceTask)
+ if err != nil {
+ log.Error("Failed to dborm.XormUpdateTableById:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ err = global.ErrTraceFailedDistributeToNEs
+ log.Error(err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+}
+
+func DeleteTraceTaskToNF(w http.ResponseWriter, r *http.Request) {
+ log.Debug("DeleteTraceTaskToNF processing... ")
+
+ token, err := services.CheckFrontValidRequest(w, r)
+ if err != nil {
+ log.Error("Request error:", err)
+ return
+ }
+ log.Debug("AccessToken:", token)
+
+ vars := r.URL.Query()
+ ids, ok := vars["id"]
+ if !ok || len(ids) == 0 {
+ err = global.ErrTraceNotCarriedTaskID
+ log.Error(err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ log.Debug("ids:", ids)
+
+ for _, id := range ids {
+ log.Debug("id:", id)
+
+ var succNes []string
+ err = dborm.XormGetColStringArrayByWhere("trace_task", "succ_nes", fmt.Sprintf("id=%s", id), &succNes)
+ if err != nil {
+ log.Error("Failed to dborm.XormGetSingleColStringArrayByWhere:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ log.Debug("succNes:", succNes)
+ nes := new([]string)
+ if len(succNes) > 0 {
+ _ = json.Unmarshal([]byte(succNes[0]), nes)
+ }
+ log.Debug("nes:", nes)
+
+ for _, ne := range *nes {
+ i := strings.Index(ne, ".")
+ neType := ne[0:i]
+ neId := ne[i+1:]
+ log.Debugf("ne:%s neType:%s neId:%s", ne, neType, neId)
+ neInfo, err := dborm.XormGetNeInfo(neType, neId)
+ if err != nil {
+ log.Error("Failed to dborm.XormGetNeInfo:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
+ requestURI2NF := fmt.Sprintf("%s%s?id=%s", hostUri, UriTraceTaskV1, id)
+ log.Debug("requestURI2NF:", requestURI2NF)
+
+ _, err = client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ Delete(requestURI2NF)
+ if err != nil {
+ log.Error("Failed to Delete:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ }
+
+ _, err = dborm.XormDeleteDataByWhere(fmt.Sprintf("id=%s", id), "trace_task")
+ if err != nil {
+ log.Error("Failed to dborm.XormDeleteDataByWhere:", err)
+ services.ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ }
+ services.ResponseStatusOK204NoContent(w)
+ return
+}
diff --git a/go.mod b/go.mod
new file mode 100644
index 00000000..073863ee
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,68 @@
+module ems.agt
+
+go 1.19
+
+require (
+ github.com/dgrijalva/jwt-go v3.2.0+incompatible
+ github.com/go-resty/resty/v2 v2.7.0
+ github.com/go-sql-driver/mysql v1.7.1
+ github.com/gorilla/mux v1.8.0
+ github.com/gosnmp/gosnmp v1.35.0
+ github.com/jasonlvhit/gocron v0.0.1
+ github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f
+ github.com/robfig/cron/v3 v3.0.1
+ github.com/shirou/gopsutil v3.21.11+incompatible
+ golang.org/x/crypto v0.12.0
+ gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
+ gopkg.in/yaml.v3 v3.0.1
+ xorm.io/xorm v1.3.2
+)
+
+require (
+ github.com/cespare/xxhash/v2 v2.2.0 // indirect
+ github.com/dgraph-io/ristretto v0.1.1 // indirect
+ github.com/dustin/go-humanize v1.0.1 // indirect
+ github.com/gogo/protobuf v1.3.2 // indirect
+ github.com/golang/glog v1.1.2 // indirect
+ github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
+ github.com/golang/protobuf v1.5.3 // indirect
+ github.com/google/flatbuffers v23.5.26+incompatible // indirect
+ github.com/gorilla/websocket v1.5.0 // indirect
+ github.com/klauspost/compress v1.16.7 // indirect
+ github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a // indirect
+ github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect
+ github.com/shirou/gopsutil/v3 v3.23.7 // indirect
+ github.com/shoenig/go-m1cpu v0.1.6 // indirect
+ go.opencensus.io v0.24.0 // indirect
+ google.golang.org/protobuf v1.31.0 // indirect
+)
+
+require (
+ github.com/dgraph-io/badger/v4 v4.2.0
+ github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect
+ github.com/go-ole/go-ole v1.2.6 // indirect
+ github.com/goccy/go-json v0.10.2 // indirect
+ github.com/golang/snappy v0.0.4 // indirect
+ github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect
+ github.com/json-iterator/go v1.1.12 // indirect
+ github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570 // indirect
+ github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042 // indirect
+ github.com/mattn/go-isatty v0.0.19 // indirect
+ github.com/mattn/go-sqlite3 v1.14.15 // indirect
+ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+ github.com/modern-go/reflect2 v1.0.2 // indirect
+ github.com/onsi/ginkgo v1.16.5 // indirect
+ github.com/onsi/gomega v1.21.1 // indirect
+ github.com/pkg/errors v0.9.1 // indirect
+ github.com/stretchr/testify v1.8.4 // indirect
+ github.com/syndtr/goleveldb v1.0.0 // indirect
+ github.com/tebeka/strftime v0.1.5 // indirect
+ github.com/tklauser/go-sysconf v0.3.12 // indirect
+ github.com/tklauser/numcpus v0.6.1 // indirect
+ github.com/yusufpapurcu/wmi v1.2.3 // indirect
+ golang.org/x/net v0.14.0 // indirect
+ golang.org/x/sys v0.11.0 // indirect
+ golang.org/x/tools v0.6.0 // indirect
+ gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
+ xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978 // indirect
+)
diff --git a/go.sum b/go.sum
new file mode 100644
index 00000000..27e2d15f
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,826 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
+gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
+gitee.com/travelliu/dm v1.8.11192/go.mod h1:DHTzyhCrM843x9VdKVbZ+GKXGRbKM2sJ4LxihRxShkE=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
+github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
+github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
+github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
+github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
+github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
+github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
+github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
+github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
+github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
+github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
+github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
+github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
+github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
+github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
+github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
+github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
+github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
+github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
+github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
+github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
+github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
+github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
+github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
+github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
+github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
+github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
+github.com/dgraph-io/badger/v4 v4.2.0 h1:kJrlajbXXL9DFTNuhhu9yCx7JJa4qpYWxtE8BzuWsEs=
+github.com/dgraph-io/badger/v4 v4.2.0/go.mod h1:qfCqhPoWDFJRx1gp5QwwyGo8xk1lbHUxvK9nK0OGAak=
+github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8=
+github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
+github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
+github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
+github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
+github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
+github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
+github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
+github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
+github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
+github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
+github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
+github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
+github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 h1:Ghm4eQYC0nEPnSJdVkTrXpu9KtoVCSo1hg7mtI7G9KU=
+github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239/go.mod h1:Gdwt2ce0yfBxPvZrHkprdPPTTS3N5rwmLE8T22KBXlw=
+github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
+github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
+github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
+github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
+github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
+github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
+github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
+github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
+github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
+github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
+github.com/go-redis/redis v6.15.5+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
+github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
+github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
+github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
+github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
+github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
+github.com/goccy/go-json v0.8.1/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
+github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
+github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
+github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
+github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
+github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
+github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
+github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ=
+github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
+github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo=
+github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ=
+github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I=
+github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
+github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
+github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
+github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
+github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
+github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
+github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
+github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
+github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
+github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw=
+github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
+github.com/google/flatbuffers v23.5.26+incompatible h1:M9dgRyhJemaM4Sw8+66GHBu8ioaQmyPLg1b8VwK5WJg=
+github.com/google/flatbuffers v23.5.26+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
+github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
+github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
+github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
+github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
+github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/gosnmp/gosnmp v1.35.0 h1:EuWWNPxTCdAUx2/NbQcSa3WdNxjzpy4Phv57b4MWpJM=
+github.com/gosnmp/gosnmp v1.35.0/go.mod h1:2AvKZ3n9aEl5TJEo/fFmf/FGO4Nj4cVeEc5yuk88CYc=
+github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
+github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
+github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
+github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
+github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
+github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
+github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
+github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
+github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
+github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
+github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
+github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
+github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
+github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
+github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
+github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
+github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
+github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
+github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
+github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
+github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
+github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
+github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
+github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=
+github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=
+github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s=
+github.com/jackc/pgconn v1.4.0/go.mod h1:Y2O3ZDF0q4mMacyWV3AstPJpeHXWGEetiFttmq5lahk=
+github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI=
+github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI=
+github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
+github.com/jackc/pgconn v1.8.1/go.mod h1:JV6m6b6jhjdmzchES0drzCcYcAHS1OPD5xu3OZ/lE2g=
+github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
+github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
+github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
+github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c=
+github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
+github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
+github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
+github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
+github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
+github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
+github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
+github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
+github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
+github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
+github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
+github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
+github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
+github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
+github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0=
+github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po=
+github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ=
+github.com/jackc/pgtype v1.7.0/go.mod h1:ZnHF+rMePVqDKaOfJVI4Q8IVvAQMryDlDkZnKOI75BE=
+github.com/jackc/pgtype v1.8.0/go.mod h1:PqDKcEBtllAtk/2p6z6SHdXW5UB+MhE75tUol2OKexE=
+github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
+github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
+github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
+github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXgo+kA=
+github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o=
+github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg=
+github.com/jackc/pgx/v4 v4.11.0/go.mod h1:i62xJgdrtVDsnL3U8ekyrQXEwGNTRoG7/8r+CIdYfcc=
+github.com/jackc/pgx/v4 v4.12.0/go.mod h1:fE547h6VulLPA3kySjfnSG/e2D861g/50JlVUa/ub60=
+github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jasonlvhit/gocron v0.0.1 h1:qTt5qF3b3srDjeOIR4Le1LfeyvoYzJlYpqvG7tJX5YU=
+github.com/jasonlvhit/gocron v0.0.1/go.mod h1:k9a3TV8VcU73XZxfVHCHWMWF9SOqgoku0/QlY2yvlA4=
+github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 h1:IPJ3dvxmJ4uczJe5YQdrYB16oTJlGSC/OyZDqUk9xX4=
+github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869/go.mod h1:cJ6Cj7dQo+O6GJNiMx+Pa94qKj+TG8ONdKHgMNIyyag=
+github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
+github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
+github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
+github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
+github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
+github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
+github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
+github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/klauspost/compress v1.12.3 h1:G5AfA94pHPysR56qqrkO2pxEexdDzrpFJ6yt/VqWxVU=
+github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
+github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
+github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570 h1:0iQektZGS248WXmGIYOwRXSQhD4qn3icjMpuxwO7qlo=
+github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570/go.mod h1:BLt8L9ld7wVsvEWQbuLrUZnCMnUmLZ+CGDzKtclrTlE=
+github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f h1:sgUSP4zdTUZYZgAGGtN5Lxk92rK+JUFOwf+FT99EEI4=
+github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f/go.mod h1:UGmTpUd3rjbtfIpwAPrcfmGf/Z1HS95TATB+m57TPB8=
+github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042 h1:Bvq8AziQ5jFF4BHGAEDSqwPW1NJS3XshxbRCxtjFAZc=
+github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042/go.mod h1:TPpsiPUEh0zFL1Snz4crhMlBe60PYxRHr5oFF3rRYg0=
+github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
+github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
+github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
+github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
+github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a h1:N9zuLhTvBSRt0gWSiJswwQ2HqDmtX/ZCDJURnKUt1Ik=
+github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE=
+github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
+github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
+github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
+github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
+github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
+github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
+github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
+github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
+github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
+github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
+github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
+github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
+github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
+github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
+github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
+github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
+github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
+github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
+github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
+github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
+github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
+github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
+github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
+github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
+github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
+github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
+github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
+github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
+github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
+github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
+github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
+github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
+github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
+github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
+github.com/onsi/gomega v1.21.1 h1:OB/euWYIExnPBohllTicTHmGTrMaqJ67nIu80j0/uEM=
+github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc=
+github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
+github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
+github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
+github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
+github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
+github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
+github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
+github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
+github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
+github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
+github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
+github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
+github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
+github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
+github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
+github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
+github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
+github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b h1:0LFwY6Q3gMACTjAbMZBjXAqTOzOwFaj2Ld6cjeQ7Rig=
+github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
+github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
+github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
+github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
+github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
+github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
+github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
+github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
+github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
+github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
+github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
+github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
+github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
+github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
+github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
+github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
+github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
+github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
+github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
+github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
+github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
+github.com/shirou/gopsutil/v3 v3.23.7 h1:C+fHO8hfIppoJ1WdsVm1RoI0RwXoNdfTK7yWXV0wVj4=
+github.com/shirou/gopsutil/v3 v3.23.7/go.mod h1:c4gnmoRC0hQuaLqvxnx1//VXQ0Ms/X9UnJF8pddY5z4=
+github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
+github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
+github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
+github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
+github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
+github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
+github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
+github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
+github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
+github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
+github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
+github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
+github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
+github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
+github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
+github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
+github.com/tebeka/strftime v0.1.5 h1:1NQKN1NiQgkqd/2moD6ySP/5CoZQsKa1d3ZhJ44Jpmg=
+github.com/tebeka/strftime v0.1.5/go.mod h1:29/OidkoWHdEKZqzyDLUyC+LmgDgdHo4WAFCDT7D/Ig=
+github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
+github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
+github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
+github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
+github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
+github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4=
+github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
+github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
+github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
+github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
+github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
+github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
+github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
+github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
+github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
+go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
+go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
+go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
+go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0=
+go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
+go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
+go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
+go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
+go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
+go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
+go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
+golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
+golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
+golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
+golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
+golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
+golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
+golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
+golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
+golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
+golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
+golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
+golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
+golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
+google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
+google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
+google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
+google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
+google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
+google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
+google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
+google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
+google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
+gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
+gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
+gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
+gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
+gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
+gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
+gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
+lukechampine.com/uint128 v1.1.1 h1:pnxCASz787iMf+02ssImqk6OLt+Z5QHMoZyUXR4z6JU=
+lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
+modernc.org/cc/v3 v3.33.6/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
+modernc.org/cc/v3 v3.33.9/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
+modernc.org/cc/v3 v3.33.11/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
+modernc.org/cc/v3 v3.34.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
+modernc.org/cc/v3 v3.35.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
+modernc.org/cc/v3 v3.35.4/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
+modernc.org/cc/v3 v3.35.5/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
+modernc.org/cc/v3 v3.35.7/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
+modernc.org/cc/v3 v3.35.8/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
+modernc.org/cc/v3 v3.35.10/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
+modernc.org/cc/v3 v3.35.15/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
+modernc.org/cc/v3 v3.35.16/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
+modernc.org/cc/v3 v3.35.17/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
+modernc.org/cc/v3 v3.35.18 h1:rMZhRcWrba0y3nVmdiQ7kxAgOOSq2m2f2VzjHLgEs6U=
+modernc.org/cc/v3 v3.35.18/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
+modernc.org/ccgo/v3 v3.9.5/go.mod h1:umuo2EP2oDSBnD3ckjaVUXMrmeAw8C8OSICVa0iFf60=
+modernc.org/ccgo/v3 v3.10.0/go.mod h1:c0yBmkRFi7uW4J7fwx/JiijwOjeAeR2NoSaRVFPmjMw=
+modernc.org/ccgo/v3 v3.11.0/go.mod h1:dGNposbDp9TOZ/1KBxghxtUp/bzErD0/0QW4hhSaBMI=
+modernc.org/ccgo/v3 v3.11.1/go.mod h1:lWHxfsn13L3f7hgGsGlU28D9eUOf6y3ZYHKoPaKU0ag=
+modernc.org/ccgo/v3 v3.11.3/go.mod h1:0oHunRBMBiXOKdaglfMlRPBALQqsfrCKXgw9okQ3GEw=
+modernc.org/ccgo/v3 v3.12.4/go.mod h1:Bk+m6m2tsooJchP/Yk5ji56cClmN6R1cqc9o/YtbgBQ=
+modernc.org/ccgo/v3 v3.12.6/go.mod h1:0Ji3ruvpFPpz+yu+1m0wk68pdr/LENABhTrDkMDWH6c=
+modernc.org/ccgo/v3 v3.12.8/go.mod h1:Hq9keM4ZfjCDuDXxaHptpv9N24JhgBZmUG5q60iLgUo=
+modernc.org/ccgo/v3 v3.12.11/go.mod h1:0jVcmyDwDKDGWbcrzQ+xwJjbhZruHtouiBEvDfoIsdg=
+modernc.org/ccgo/v3 v3.12.14/go.mod h1:GhTu1k0YCpJSuWwtRAEHAol5W7g1/RRfS4/9hc9vF5I=
+modernc.org/ccgo/v3 v3.12.18/go.mod h1:jvg/xVdWWmZACSgOiAhpWpwHWylbJaSzayCqNOJKIhs=
+modernc.org/ccgo/v3 v3.12.20/go.mod h1:aKEdssiu7gVgSy/jjMastnv/q6wWGRbszbheXgWRHc8=
+modernc.org/ccgo/v3 v3.12.21/go.mod h1:ydgg2tEprnyMn159ZO/N4pLBqpL7NOkJ88GT5zNU2dE=
+modernc.org/ccgo/v3 v3.12.22/go.mod h1:nyDVFMmMWhMsgQw+5JH6B6o4MnZ+UQNw1pp52XYFPRk=
+modernc.org/ccgo/v3 v3.12.25/go.mod h1:UaLyWI26TwyIT4+ZFNjkyTbsPsY3plAEB6E7L/vZV3w=
+modernc.org/ccgo/v3 v3.12.29/go.mod h1:FXVjG7YLf9FetsS2OOYcwNhcdOLGt8S9bQ48+OP75cE=
+modernc.org/ccgo/v3 v3.12.36/go.mod h1:uP3/Fiezp/Ga8onfvMLpREq+KUjUmYMxXPO8tETHtA8=
+modernc.org/ccgo/v3 v3.12.38/go.mod h1:93O0G7baRST1vNj4wnZ49b1kLxt0xCW5Hsa2qRaZPqc=
+modernc.org/ccgo/v3 v3.12.43/go.mod h1:k+DqGXd3o7W+inNujK15S5ZYuPoWYLpF5PYougCmthU=
+modernc.org/ccgo/v3 v3.12.46/go.mod h1:UZe6EvMSqOxaJ4sznY7b23/k13R8XNlyWsO5bAmSgOE=
+modernc.org/ccgo/v3 v3.12.47/go.mod h1:m8d6p0zNps187fhBwzY/ii6gxfjob1VxWb919Nk1HUk=
+modernc.org/ccgo/v3 v3.12.50/go.mod h1:bu9YIwtg+HXQxBhsRDE+cJjQRuINuT9PUK4orOco/JI=
+modernc.org/ccgo/v3 v3.12.51/go.mod h1:gaIIlx4YpmGO2bLye04/yeblmvWEmE4BBBls4aJXFiE=
+modernc.org/ccgo/v3 v3.12.53/go.mod h1:8xWGGTFkdFEWBEsUmi+DBjwu/WLy3SSOrqEmKUjMeEg=
+modernc.org/ccgo/v3 v3.12.54/go.mod h1:yANKFTm9llTFVX1FqNKHE0aMcQb1fuPJx6p8AcUx+74=
+modernc.org/ccgo/v3 v3.12.55/go.mod h1:rsXiIyJi9psOwiBkplOaHye5L4MOOaCjHg1Fxkj7IeU=
+modernc.org/ccgo/v3 v3.12.56/go.mod h1:ljeFks3faDseCkr60JMpeDb2GSO3TKAmrzm7q9YOcMU=
+modernc.org/ccgo/v3 v3.12.57/go.mod h1:hNSF4DNVgBl8wYHpMvPqQWDQx8luqxDnNGCMM4NFNMc=
+modernc.org/ccgo/v3 v3.12.60/go.mod h1:k/Nn0zdO1xHVWjPYVshDeWKqbRWIfif5dtsIOCUVMqM=
+modernc.org/ccgo/v3 v3.12.65/go.mod h1:D6hQtKxPNZiY6wDBtehSGKFKmyXn53F8nGTpH+POmS4=
+modernc.org/ccgo/v3 v3.12.66/go.mod h1:jUuxlCFZTUZLMV08s7B1ekHX5+LIAurKTTaugUr/EhQ=
+modernc.org/ccgo/v3 v3.12.67/go.mod h1:Bll3KwKvGROizP2Xj17GEGOTrlvB1XcVaBrC90ORO84=
+modernc.org/ccgo/v3 v3.12.73/go.mod h1:hngkB+nUUqzOf3iqsM48Gf1FZhY599qzVg1iX+BT3cQ=
+modernc.org/ccgo/v3 v3.12.81/go.mod h1:p2A1duHoBBg1mFtYvnhAnQyI6vL0uw5PGYLSIgF6rYY=
+modernc.org/ccgo/v3 v3.12.82 h1:wudcnJyjLj1aQQCXF3IM9Gz2X6UNjw+afIghzdtn0v8=
+modernc.org/ccgo/v3 v3.12.82/go.mod h1:ApbflUfa5BKadjHynCficldU1ghjen84tuM5jRynB7w=
+modernc.org/ccorpus v1.11.1/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
+modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
+modernc.org/libc v1.9.8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
+modernc.org/libc v1.9.11/go.mod h1:NyF3tsA5ArIjJ83XB0JlqhjTabTCHm9aX4XMPHyQn0Q=
+modernc.org/libc v1.11.0/go.mod h1:2lOfPmj7cz+g1MrPNmX65QCzVxgNq2C5o0jdLY2gAYg=
+modernc.org/libc v1.11.2/go.mod h1:ioIyrl3ETkugDO3SGZ+6EOKvlP3zSOycUETe4XM4n8M=
+modernc.org/libc v1.11.5/go.mod h1:k3HDCP95A6U111Q5TmG3nAyUcp3kR5YFZTeDS9v8vSU=
+modernc.org/libc v1.11.6/go.mod h1:ddqmzR6p5i4jIGK1d/EiSw97LBcE3dK24QEwCFvgNgE=
+modernc.org/libc v1.11.11/go.mod h1:lXEp9QOOk4qAYOtL3BmMve99S5Owz7Qyowzvg6LiZso=
+modernc.org/libc v1.11.13/go.mod h1:ZYawJWlXIzXy2Pzghaf7YfM8OKacP3eZQI81PDLFdY8=
+modernc.org/libc v1.11.16/go.mod h1:+DJquzYi+DMRUtWI1YNxrlQO6TcA5+dRRiq8HWBWRC8=
+modernc.org/libc v1.11.19/go.mod h1:e0dgEame6mkydy19KKaVPBeEnyJB4LGNb0bBH1EtQ3I=
+modernc.org/libc v1.11.24/go.mod h1:FOSzE0UwookyT1TtCJrRkvsOrX2k38HoInhw+cSCUGk=
+modernc.org/libc v1.11.26/go.mod h1:SFjnYi9OSd2W7f4ct622o/PAYqk7KHv6GS8NZULIjKY=
+modernc.org/libc v1.11.27/go.mod h1:zmWm6kcFXt/jpzeCgfvUNswM0qke8qVwxqZrnddlDiE=
+modernc.org/libc v1.11.28/go.mod h1:Ii4V0fTFcbq3qrv3CNn+OGHAvzqMBvC7dBNyC4vHZlg=
+modernc.org/libc v1.11.31/go.mod h1:FpBncUkEAtopRNJj8aRo29qUiyx5AvAlAxzlx9GNaVM=
+modernc.org/libc v1.11.34/go.mod h1:+Tzc4hnb1iaX/SKAutJmfzES6awxfU1BPvrrJO0pYLg=
+modernc.org/libc v1.11.37/go.mod h1:dCQebOwoO1046yTrfUE5nX1f3YpGZQKNcITUYWlrAWo=
+modernc.org/libc v1.11.39/go.mod h1:mV8lJMo2S5A31uD0k1cMu7vrJbSA3J3waQJxpV4iqx8=
+modernc.org/libc v1.11.42/go.mod h1:yzrLDU+sSjLE+D4bIhS7q1L5UwXDOw99PLSX0BlZvSQ=
+modernc.org/libc v1.11.44/go.mod h1:KFq33jsma7F5WXiYelU8quMJasCCTnHK0mkri4yPHgA=
+modernc.org/libc v1.11.45/go.mod h1:Y192orvfVQQYFzCNsn+Xt0Hxt4DiO4USpLNXBlXg/tM=
+modernc.org/libc v1.11.47/go.mod h1:tPkE4PzCTW27E6AIKIR5IwHAQKCAtudEIeAV1/SiyBg=
+modernc.org/libc v1.11.49/go.mod h1:9JrJuK5WTtoTWIFQ7QjX2Mb/bagYdZdscI3xrvHbXjE=
+modernc.org/libc v1.11.51/go.mod h1:R9I8u9TS+meaWLdbfQhq2kFknTW0O3aw3kEMqDDxMaM=
+modernc.org/libc v1.11.53/go.mod h1:5ip5vWYPAoMulkQ5XlSJTy12Sz5U6blOQiYasilVPsU=
+modernc.org/libc v1.11.54/go.mod h1:S/FVnskbzVUrjfBqlGFIPA5m7UwB3n9fojHhCNfSsnw=
+modernc.org/libc v1.11.55/go.mod h1:j2A5YBRm6HjNkoSs/fzZrSxCuwWqcMYTDPLNx0URn3M=
+modernc.org/libc v1.11.56/go.mod h1:pakHkg5JdMLt2OgRadpPOTnyRXm/uzu+Yyg/LSLdi18=
+modernc.org/libc v1.11.58/go.mod h1:ns94Rxv0OWyoQrDqMFfWwka2BcaF6/61CqJRK9LP7S8=
+modernc.org/libc v1.11.70/go.mod h1:DUOmMYe+IvKi9n6Mycyx3DbjfzSKrdr/0Vgt3j7P5gw=
+modernc.org/libc v1.11.71/go.mod h1:DUOmMYe+IvKi9n6Mycyx3DbjfzSKrdr/0Vgt3j7P5gw=
+modernc.org/libc v1.11.75/go.mod h1:dGRVugT6edz361wmD9gk6ax1AbDSe0x5vji0dGJiPT0=
+modernc.org/libc v1.11.82/go.mod h1:NF+Ek1BOl2jeC7lw3a7Jj5PWyHPwWD4aq3wVKxqV1fI=
+modernc.org/libc v1.11.86/go.mod h1:ePuYgoQLmvxdNT06RpGnaDKJmDNEkV7ZPKI2jnsvZoE=
+modernc.org/libc v1.11.87 h1:PzIzOqtlzMDDcCzJ5cUP6h/Ku6Fa9iyflP2ccTY64aE=
+modernc.org/libc v1.11.87/go.mod h1:Qvd5iXTeLhI5PS0XSyqMY99282y+3euapQFxM7jYnpY=
+modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
+modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
+modernc.org/mathutil v1.4.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
+modernc.org/mathutil v1.4.1 h1:ij3fYGe8zBF4Vu+g0oT7mB06r8sqGWKuJu1yXeR4by8=
+modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
+modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc=
+modernc.org/memory v1.0.5 h1:XRch8trV7GgvTec2i7jc33YlUI0RKVDBvZ5eZ5m8y14=
+modernc.org/memory v1.0.5/go.mod h1:B7OYswTRnfGg+4tDH1t1OeUNnsy2viGTdME4tzd+IjM=
+modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A=
+modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
+modernc.org/sqlite v1.14.2 h1:ohsW2+e+Qe2To1W6GNezzKGwjXwSax6R+CrhRxVaFbE=
+modernc.org/sqlite v1.14.2/go.mod h1:yqfn85u8wVOE6ub5UT8VI9JjhrwBUUCNyTACN0h6Sx8=
+modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs=
+modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=
+modernc.org/tcl v1.8.13/go.mod h1:V+q/Ef0IJaNUSECieLU4o+8IScapxnMyFV6i/7uQlAY=
+modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk=
+modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
+modernc.org/z v1.2.19/go.mod h1:+ZpP0pc4zz97eukOzW3xagV/lS82IpPN9NGG5pNF9vY=
+sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
+sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
+xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978 h1:bvLlAPW1ZMTWA32LuZMBEGHAUOcATZjzHcotf3SWweM=
+xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
+xorm.io/xorm v1.3.2 h1:uTRRKF2jYzbZ5nsofXVUx6ncMaek+SHjWYtCXyZo1oM=
+xorm.io/xorm v1.3.2/go.mod h1:9NbjqdnjX6eyjRRhh01GHm64r6N9shTb/8Ak3YRt8Nw=
diff --git a/lib/aes/aes.go b/lib/aes/aes.go
new file mode 100644
index 00000000..5ce2fb40
--- /dev/null
+++ b/lib/aes/aes.go
@@ -0,0 +1,64 @@
+package aes
+
+import (
+ "bytes"
+ "crypto/aes"
+ "crypto/cipher"
+ "encoding/base64"
+)
+
+func AesEncrypt(orig string, key string) string {
+ // 转成字节数组
+ origData := []byte(orig)
+ k := []byte(key)
+
+ // 分组秘钥
+ block, _ := aes.NewCipher(k)
+ // 获取秘钥块的长度
+ blockSize := block.BlockSize()
+ // 补全码
+ origData = PKCS7Padding(origData, blockSize)
+ // 加密模式
+ blockMode := cipher.NewCBCEncrypter(block, k[:blockSize])
+ // 创建数组
+ cryted := make([]byte, len(origData))
+ // 加密
+ blockMode.CryptBlocks(cryted, origData)
+
+ return base64.StdEncoding.EncodeToString(cryted)
+
+}
+
+func AesDecrypt(cryted string, key string) string {
+ // 转成字节数组
+ crytedByte, _ := base64.StdEncoding.DecodeString(cryted)
+ k := []byte(key)
+
+ // 分组秘钥
+ block, _ := aes.NewCipher(k)
+ // 获取秘钥块的长度
+ blockSize := block.BlockSize()
+ // 加密模式
+ blockMode := cipher.NewCBCDecrypter(block, k[:blockSize])
+ // 创建数组
+ orig := make([]byte, len(crytedByte))
+ // 解密
+ blockMode.CryptBlocks(orig, crytedByte)
+ // 去补全码
+ orig = PKCS7UnPadding(orig)
+ return string(orig)
+}
+
+// 补码
+func PKCS7Padding(ciphertext []byte, blocksize int) []byte {
+ padding := blocksize - len(ciphertext)%blocksize
+ padtext := bytes.Repeat([]byte{byte(padding)}, padding)
+ return append(ciphertext, padtext...)
+}
+
+// 去码
+func PKCS7UnPadding(origData []byte) []byte {
+ length := len(origData)
+ unpadding := int(origData[length-1])
+ return origData[:(length - unpadding)]
+}
diff --git a/lib/cache/badger_db/badger_db.go b/lib/cache/badger_db/badger_db.go
new file mode 100644
index 00000000..c711f352
--- /dev/null
+++ b/lib/cache/badger_db/badger_db.go
@@ -0,0 +1,92 @@
+package badger_db
+
+import (
+ "fmt"
+ "time"
+
+ "github.com/dgraph-io/badger/v4"
+ "github.com/pkg/errors"
+)
+
+type Cache struct {
+ db *badger.DB
+}
+
+func NewCacheDB(db *badger.DB) *Cache {
+ return &Cache{
+ db: db,
+ }
+}
+
+func (c *Cache) SetNX(key string, value interface{}) error {
+ err := c.db.Update(func(txn *badger.Txn) error {
+ _, err := txn.Get([]byte(key))
+ if errors.Is(err, badger.ErrKeyNotFound) {
+ v := []byte(fmt.Sprintf("%v", value))
+ return txn.Set([]byte(key), v)
+ }
+ return err
+ })
+ return err
+}
+
+func (c *Cache) Set(key string, value interface{}) error {
+ err := c.db.Update(func(txn *badger.Txn) error {
+ v := []byte(fmt.Sprintf("%v", value))
+ return txn.Set([]byte(key), v)
+ })
+ return err
+}
+
+func (c *Cache) Del(key string) error {
+ err := c.db.Update(func(txn *badger.Txn) error {
+ return txn.Delete([]byte(key))
+ })
+ return err
+}
+
+func (c *Cache) Clean() error {
+ return c.db.DropAll()
+}
+
+func (c *Cache) Get(key string) ([]byte, error) {
+ var result []byte
+ err := c.db.View(func(txn *badger.Txn) error {
+ item, err := txn.Get([]byte(key))
+ if err != nil {
+ return err
+ }
+ err = item.Value(func(val []byte) error {
+ result = append([]byte{}, val...)
+ return nil
+ })
+ return err
+ })
+ return result, err
+}
+
+func (c *Cache) SetWithTTL(key string, value interface{}, duration time.Duration) error {
+ err := c.db.Update(func(txn *badger.Txn) error {
+ v := []byte(fmt.Sprintf("%v", value))
+ e := badger.NewEntry([]byte(key), v).WithTTL(duration)
+ return txn.SetEntry(e)
+ })
+ return err
+}
+
+func (c *Cache) PrefixScanKey(prefixStr string) ([]string, error) {
+ var res []string
+ err := c.db.View(func(txn *badger.Txn) error {
+ it := txn.NewIterator(badger.DefaultIteratorOptions)
+ defer it.Close()
+ prefix := []byte(prefixStr)
+ for it.Seek(prefix); it.ValidForPrefix(prefix); it.Next() {
+ item := it.Item()
+ k := item.Key()
+ res = append(res, string(k))
+ return nil
+ }
+ return nil
+ })
+ return res, err
+}
diff --git a/lib/cache/cache.go b/lib/cache/cache.go
new file mode 100644
index 00000000..005398dd
--- /dev/null
+++ b/lib/cache/cache.go
@@ -0,0 +1,55 @@
+package cache
+
+import (
+ "time"
+
+ "ems.agt/lib/cache/badger_db"
+ "ems.agt/lib/log"
+ "github.com/dgraph-io/badger/v4"
+)
+
+var CACHE *badger_db.Cache
+
+func Init() {
+ options := badger.Options{
+ Dir: "tmp/badger",
+ ValueDir: "tmp/badger",
+ ValueLogFileSize: 64 << 20,
+ ValueLogMaxEntries: 10 << 20,
+ VLogPercentile: 0.1,
+
+ MemTableSize: 32 << 20,
+ BaseTableSize: 2 << 20,
+ BaseLevelSize: 10 << 20,
+ TableSizeMultiplier: 2,
+ LevelSizeMultiplier: 10,
+ MaxLevels: 7,
+ NumGoroutines: 4,
+ MetricsEnabled: true,
+ NumCompactors: 2,
+ NumLevelZeroTables: 5,
+ NumLevelZeroTablesStall: 15,
+ NumMemtables: 1,
+ BloomFalsePositive: 0.01,
+ BlockSize: 2 * 1024,
+ SyncWrites: false,
+ NumVersionsToKeep: 1,
+ CompactL0OnClose: false,
+ VerifyValueChecksum: false,
+ BlockCacheSize: 32 << 20,
+ IndexCacheSize: 0,
+ ZSTDCompressionLevel: 1,
+ EncryptionKey: []byte{},
+ EncryptionKeyRotationDuration: 10 * 24 * time.Hour, // Default 10 days.
+ DetectConflicts: true,
+ NamespaceOffset: -1,
+ }
+
+ cache, err := badger.Open(options)
+ if err != nil {
+ log.Errorf("failed to badger init cache:", err)
+ }
+
+ CACHE = badger_db.NewCacheDB(cache)
+ log.Info("init cache successfully")
+}
diff --git a/lib/dborm/dborm.go b/lib/dborm/dborm.go
new file mode 100644
index 00000000..3aef6713
--- /dev/null
+++ b/lib/dborm/dborm.go
@@ -0,0 +1,1412 @@
+package dborm
+
+import (
+ "database/sql"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "strconv"
+ "time"
+
+ "strings"
+
+ "ems.agt/lib/log"
+ "ems.agt/lib/oauth"
+
+ _ "github.com/go-sql-driver/mysql"
+ "xorm.io/xorm"
+)
+
+const (
+ TableNameMeasureTask = "measure_task"
+ TableNameNeInfo = "ne_info"
+)
+
+type Menu struct {
+ Id int `json:"id"`
+ Title string `json:"title"`
+ Icon string `json:"icon"`
+ Href string `json:"href"`
+ ParentId int `json:"parent_id`
+ Remark int `json:"remark"`
+}
+
+type DatabaseClient struct {
+ dbType string
+ dbUrl string
+ dbConnMaxLifetime time.Duration
+ dbMaxIdleConns int
+ dbMaxOpenConns int
+ IsShowSQL bool
+
+ XEngine *xorm.Engine
+}
+
+var DbClient DatabaseClient
+
+func InitDbClient(dbType, dbUser, dbPassword, dbHost, dbPort, dbName string) error {
+ DbClient.dbUrl = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8&parseTime=true&loc=Local",
+ dbUser, dbPassword, dbHost, dbPort, dbName)
+ DbClient.dbType = dbType
+ DbClient.dbConnMaxLifetime = 0
+ DbClient.dbMaxIdleConns = 0
+ DbClient.dbMaxOpenConns = 0
+ if log.GetLevel() == log.LOG_TRACE {
+ DbClient.IsShowSQL = true
+ }
+ log.Debugf("dbType:%s dbUrl:%s:******@tcp(%s:%s)/%s??charset=utf8&parseTime=true&loc=Local",
+ dbType, dbUser, dbHost, dbPort, dbName)
+
+ var err error
+ DbClient.XEngine, err = xorm.NewEngine(DbClient.dbType, DbClient.dbUrl)
+ if err != nil {
+ log.Error("Failed to connet database:", err)
+ return err
+ }
+ DbClient.XEngine.SetConnMaxLifetime(DbClient.dbConnMaxLifetime)
+ DbClient.XEngine.SetMaxIdleConns(DbClient.dbMaxIdleConns)
+ DbClient.XEngine.SetMaxOpenConns(DbClient.dbMaxOpenConns)
+ if DbClient.IsShowSQL {
+ DbClient.XEngine.ShowSQL(true)
+ }
+ xEngine = DbClient.XEngine
+
+ return nil
+}
+
+// func InitDbClient() error {
+// db := config.GetYamlConfig().Database
+// DbClient.dbUrl = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", db.User, db.Password, db.Host, db.Port, db.Name)
+// DbClient.dbType = db.Type
+// DbClient.dbConnMaxLifetime = 0
+// DbClient.dbMaxIdleConns = 0
+// DbClient.dbMaxOpenConns = 0
+// if log.GetLevel() == log.LOG_TRACE {
+// DbClient.IsShowSQL = true
+// }
+// log.Debugf("dbType:%s dbUrl:%s:******@tcp(%s:%s)/%s", DbClient.dbType, db.User, db.Host, db.Port, db.Name)
+// var err error
+// DbClient.XEngine, err = xorm.NewEngine(DbClient.dbType, DbClient.dbUrl)
+// if err != nil {
+// log.Error("Failed to connet database:", err)
+// return err
+// }
+// DbClient.XEngine.SetConnMaxLifetime(DbClient.dbConnMaxLifetime)
+// DbClient.XEngine.SetMaxIdleConns(DbClient.dbMaxIdleConns)
+// DbClient.XEngine.SetMaxOpenConns(DbClient.dbMaxOpenConns)
+// if DbClient.IsShowSQL {
+// DbClient.XEngine.ShowSQL(true)
+// }
+// xEngine = DbClient.XEngine
+
+// return nil
+// }
+
+var xEngine *xorm.Engine
+
+func XormConnectDatabase(dbType, dbUser, dbPassword, dbHost, dbPort, dbName string) (*xorm.Engine, error) {
+ sqlStr := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8&parseTime=true&loc=Local",
+ dbUser, dbPassword, dbHost, dbPort, dbName)
+ log.Debugf("dbType:%s Connect to:%s:******@tcp(%s:%s)/%s?charset=utf8&parseTime=true&loc=Local",
+ dbType, dbUser, dbHost, dbPort, dbName)
+ var err error
+ xEngine, err = xorm.NewEngine(dbType, sqlStr) //1、Create xorm engine
+ if err != nil {
+ log.Error("Failed to connect database:", err)
+ return nil, err
+ }
+ if log.GetLevel() == log.LOG_TRACE {
+ xEngine.ShowSQL(true)
+ }
+ return xEngine, nil
+}
+
+func ConstructInsertSQL(tableName string, insertData interface{}) (string, []string) {
+ log.Debug("ConstructInsertSQL processing... ")
+ log.Debug("Request insertData:", insertData)
+
+ var sql []string
+ var dataTag string
+ for t, d := range insertData.(map[string]interface{}) {
+ log.Tracef("t: %v d: %v", t, d)
+ dataTag = t
+
+ for i, r := range d.([]interface{}) {
+ var cl, vl string
+ log.Tracef("i: %v r: %v", i, r)
+ for c, v := range r.(map[string]interface{}) {
+ log.Tracef("c: %v v: %v", c, v)
+ if cl == "" {
+ cl = fmt.Sprintf("%s", c)
+ } else {
+ cl = fmt.Sprintf("%s, %s", cl, c)
+ }
+ if vl == "" {
+ vl = fmt.Sprintf("'%v'", v)
+ } else {
+ vl = fmt.Sprintf("%s, '%v'", vl, v)
+ }
+
+ log.Tracef("cl: %s vl: %s", cl, vl)
+ }
+ sql = append(sql, "insert into "+tableName+"("+cl+")"+" values("+vl+")")
+ }
+
+ log.Debug("sql:", sql)
+ }
+
+ return dataTag, sql
+}
+
+func InsertDataWithJson(insertData interface{}) (int64, error) {
+ log.Debug("InsertDataWithJson processing... ")
+
+ var data map[string]interface{}
+ var tableName string
+ for k, v := range insertData.(map[string]interface{}) {
+ log.Tracef("k: %v v: %v", k, v)
+ tableName = k
+ data = v.(map[string]interface{})
+ }
+
+ log.Tracef("data: %v", data)
+ xSession := xEngine.NewSession()
+ defer xSession.Close()
+ affected, err := xSession.Insert(data, tableName)
+ xSession.Commit()
+
+ return affected, err
+}
+
+type NeInfo struct {
+ Id int `json:"id" xorm:"pk 'id' autoincr"`
+ NeType string `json:"neType" xorm:"ne_type"`
+ NeId string `json:"neId" xorm:"ne_id"` // neUID/rmUID 网元唯一标识
+ RmUID string `json:"rmUID" xorm:"rm_uid"` // neUID/rmUID网元UID
+ NeName string `json:"neName" xorm:"ne_name"` // NeName/UserLabel 网元名称/网元设备友好名称
+ Ip string `json:"ip" xorm:"ip"`
+ Port string `json:"port" xorm:"port"`
+ PvFlag string `json:"pvFlag" xorm:"pv_flag"` // 网元虚实性标识 VNF/PNF: 虚拟/物理
+ NeAddress string `json:"neAddress" xorm:"ne_address"` // 只对PNF
+ Province string `json:"province" xorm:"province"` // 网元所在省份
+ VendorName string `json:"vendorName" xorm:"vendor_name"` // 厂商名称
+ Dn string `json:"dn" xorm:"dn"` // 网络标识
+ Status int `json:"status" xorm:"status"`
+ UpdateTime string `json:"-" xorm:"-"`
+}
+
+func XormGetNeInfo(neType string, neId string) (*NeInfo, error) {
+ log.Debug("XormGetNeInfo processing... ")
+
+ neInfo := new(NeInfo)
+ has, err := xEngine.Where("status='0' and ne_type=? and ne_id=?", strings.ToUpper(neType), neId).Get(neInfo)
+ if err != nil {
+ log.Error("Failed to get table ne_info from database:", err)
+ return nil, err
+ } else if has == false {
+ log.Infof("Not found ne_info from database, status='0', neType=%s, neId=%s", neType, neId)
+ return nil, nil
+ }
+
+ log.Debug("NE Info:", neInfo)
+ return neInfo, nil
+}
+
+func XormGetNeInfoByRmUID(neType string, rmUID string) (*NeInfo, error) {
+ log.Debug("XormGetNeInfoByRmUID processing... ")
+
+ neInfo := new(NeInfo)
+ has, err := xEngine.Where("status='0' and ne_type=? and rm_uid=?", strings.ToUpper(neType), rmUID).Get(neInfo)
+ if err != nil {
+ log.Error("Failed to get table ne_info from database:", err)
+ return nil, err
+ } else if has == false {
+ log.Infof("Not found ne_info from database, status='0', neType=%s, neId=%s", neType, rmUID)
+ return nil, nil
+ }
+
+ log.Debug("NE Info:", neInfo)
+ return neInfo, nil
+}
+
+func XormGetAllNeInfo(nes *[]NeInfo) (*[]NeInfo, error) {
+ log.Debug("XormGetAllNeInfo processing... ")
+
+ ne := new(NeInfo)
+ rows, err := xEngine.Table("ne_info").Where("status='0'").Rows(ne)
+ if err != nil {
+ log.Error("Failed to get table ne_info from database:", err)
+ return nil, err
+ }
+ defer rows.Close()
+ for rows.Next() {
+ err := rows.Scan(ne)
+ if err != nil {
+ log.Error("Failed to get table ne_info from database:", err)
+ return nil, err
+ }
+ *nes = append(*nes, *ne)
+ }
+ log.Debug("nes:", nes)
+ return nes, nil
+}
+
+func XormGetNeInfoByNeType(neType string, nes *[]NeInfo) error {
+ log.Debug("XormGetNeInfoByNeType processing... ")
+
+ ne := new(NeInfo)
+ rows, err := xEngine.Table("ne_info").Where("status='0' and ne_type=?", neType).Rows(ne)
+ if err != nil {
+ log.Error("Failed to get table ne_info from database:", err)
+ return err
+ }
+ defer rows.Close()
+ for rows.Next() {
+ err := rows.Scan(ne)
+ if err != nil {
+ log.Error("Failed to get table ne_info from database:", err)
+ return err
+ }
+ *nes = append(*nes, *ne)
+ }
+ log.Debug("nes:", nes)
+ return nil
+}
+
+func XormInsertNeInfo(neInfo *NeInfo) (int64, error) {
+ log.Debug("XormInsertNeInfo processing... ")
+
+ var affected int64 = 0
+ var err error = nil
+
+ xSession := xEngine.NewSession()
+ defer xSession.Close()
+ ex, _ := xEngine.Table("ne_info").Where("status = '1' and ne_type = ? and ne_id = ?", neInfo.NeType, neInfo.NeId).Exist()
+ if ex == true {
+ neInfo.Status = 0
+ affected, err = xSession.Where("ne_type = ? and ne_id = ?", neInfo.NeType, neInfo.NeId).Update(neInfo)
+ } else {
+ affected, err = xSession.InsertOne(neInfo)
+ }
+ xSession.Commit()
+ return affected, err
+}
+
+func XormUpdateNeInfo(neInfo *NeInfo) (int64, error) {
+ log.Debug("XormUpdateNeInfo processing... ")
+
+ xSession := xEngine.NewSession()
+ defer xSession.Close()
+ affected, err := xSession.ID(neInfo.Id).Update(neInfo)
+ xSession.Commit()
+ return affected, err
+}
+
+func XormDeleteNeInfo(neInfo *NeInfo) (int64, error) {
+ log.Debug("XormDeleteNeInfo processing... ")
+
+ xSession := xEngine.NewSession()
+ defer xSession.Close()
+ affected, err := xSession.Where("ne_type = ? and ne_id = ?", neInfo.NeType, neInfo.NeId).Delete(neInfo)
+ xSession.Commit()
+ return affected, err
+}
+
+func XormParseResult(body []byte) ([]NeInfo, error) {
+ log.Debug("XormParseResult processing... ")
+
+ data := make(map[string]interface{})
+ err := json.Unmarshal(body, &data)
+ if err != nil {
+ return nil, err
+ }
+ var neInfo []NeInfo
+ var re interface{}
+ if data["data"] == nil {
+ return nil, errors.New("The data is Not found")
+ }
+ for _, d := range data["data"].([]interface{}) {
+ if d == nil {
+ return nil, errors.New("The data is Not found")
+ }
+ for _, re = range d.(map[string]interface{}) {
+ if re == nil {
+ return nil, errors.New("The data is Not found")
+ }
+ for _, rc := range re.([]interface{}) {
+ if rc == nil {
+ return nil, errors.New("The data is Not found")
+ }
+ var s NeInfo
+ record := rc.(map[string]interface{})
+ s.NeName = fmt.Sprintf("%v", record["ne_name"])
+ s.NeId = fmt.Sprintf("%v", record["ne_id"])
+ s.NeType = fmt.Sprintf("%v", strings.ToLower(record["ne_type"].(string)))
+ s.Ip = fmt.Sprintf("%v", record["ip"])
+ s.Port = fmt.Sprintf("%v", record["port"])
+ s.PvFlag = fmt.Sprintf("%v", record["pv_flag"])
+
+ neInfo = append(neInfo, s)
+ }
+ }
+ }
+
+ log.Debug("neInfo:", neInfo)
+ return neInfo, nil
+}
+
+type ParamConfig struct {
+ // Id int `json:"id" xorm:"pk 'id' autoincr"`
+ NeType string `json:"neType"`
+ NeId string `json:"neId"`
+ TopTag string `json:"topTag"`
+ TopDisplay string `json:"topDisplay"`
+ ParamJson string `json:"paramJson"`
+}
+
+func XormInsertParamConfig(mapJson *map[string]interface{}) (int64, error) {
+ var affected, a int64
+ var err error
+ paramConfig := new(ParamConfig)
+ for n, d := range *mapJson {
+ if d == nil {
+ break
+ }
+ log.Debugf("n: %s", n)
+
+ for t, p := range d.(map[string]interface{}) {
+ if p == nil {
+ break
+ }
+ log.Debug("t:", t)
+ log.Debug("p:", p)
+ for k, v := range p.(map[string]interface{}) {
+ log.Debug("k, v: ", k, v)
+ if k == "display" {
+ paramConfig.TopDisplay = fmt.Sprintf("%v", v)
+
+ } else {
+ pc, _ := json.Marshal(v)
+ paramConfig.ParamJson = fmt.Sprintf("{\"%v\":%v}", k, string(pc))
+ }
+ }
+
+ paramConfig.NeType = strings.ToUpper(n)
+ paramConfig.NeId = ""
+ paramConfig.TopTag = t
+ // paramConfig.TopDisplay = p["display"]
+ // paramConfig.ParamJson = p.(string)
+
+ log.Debug("paramConfig:", paramConfig)
+
+ xSession := xEngine.NewSession()
+ defer xSession.Close()
+ _, err = xSession.Table("param_config").Where("ne_type = ? and top_tag = ?", paramConfig.NeType, paramConfig.TopTag).Delete()
+ if err != nil {
+ log.Error("Failed to insert param_config:", err)
+ }
+ a, err = xSession.Insert(paramConfig)
+ if err != nil {
+ log.Error("Failed to insert param_config:", err)
+ }
+ affected += a
+ xSession.Commit()
+ }
+ }
+
+ return affected, err
+}
+
+func ConstructUpdateSQLArray(tableName string, updateData interface{}, whereCondition string) (string, []string) {
+ log.Debug("ConstructUpdateSQL processing... ")
+ log.Debug("Request updateData:", updateData)
+
+ var sql []string
+ var tblName string
+ for t, d := range updateData.(map[string]interface{}) {
+ log.Tracef("t: %v d: %v", t, d)
+ tblName = t
+
+ for i, r := range d.([]interface{}) {
+ var cv string
+ log.Tracef("i: %v r: %v", i, r)
+ for c, v := range r.(map[string]interface{}) {
+ log.Tracef("c: %v v: %v", c, v)
+ if cv == "" {
+ cv = fmt.Sprintf("`%s`='%s'", c, v)
+ } else {
+ cv = fmt.Sprintf("%s,`%s`='%s'", cv, c, v)
+ }
+
+ log.Tracef("cv: %s", cv)
+ }
+ sql = append(sql, "UPDATE "+tableName+" SET "+cv+" WHERE "+whereCondition)
+ }
+
+ log.Debug("sql:", sql)
+ }
+
+ return tblName, sql
+}
+
+func ConstructUpdateSQL(tableName string, updateData interface{}, whereCondition string) (string, []string) {
+ log.Debug("ConstructUpdateSQL processing... ")
+ log.Debug("Request updateData:", updateData)
+
+ var sql []string
+ var tblName string
+ for t, d := range updateData.(map[string]interface{}) {
+ log.Tracef("t: %v d: %v", t, d)
+ tblName = t
+
+ var cv string
+ for c, v := range d.(map[string]interface{}) {
+ log.Tracef("c: %v v: %v", c, v)
+ if cv == "" {
+ //cv = fmt.Sprintf("`%s`=%s", c, v)
+ cv = fmt.Sprintf("`%s`='%s'", c, v)
+ } else {
+ //cv = fmt.Sprintf("%s,`%s`=%s", cv, c, v)
+ cv = fmt.Sprintf("%s,`%s`='%s'", cv, c, v)
+ }
+
+ log.Tracef("cv: %s", cv)
+ }
+ sql = append(sql, "UPDATE "+tableName+" SET "+cv+" WHERE "+whereCondition)
+
+ log.Debug("sql:", sql)
+ }
+
+ return tblName, sql
+}
+
+func ConstructDeleteSQL(tableName string, whereCondition string) string {
+ log.Debug("ConstructDeleteSQL processing... ")
+
+ var sql string
+
+ sql = "DELETE from " + tableName + " WHERE " + whereCondition
+ log.Debug("sql:", sql)
+ return sql
+}
+
+type TaskStatus string
+
+const (
+ MeasureTaskStatusInactive = "Inactive"
+ MeasureTaskStatusActive = "Active"
+ MeasureTaskStatusSuspend = "Suspend"
+ MeasureTaskStatusDeleted = "Deleted"
+)
+
+type MTask struct {
+ Id int `json:"id" xorm:"pk 'id' autoincr"`
+
+ NeSet struct {
+ NEs []string `json:"nes"`
+ } `json:"neSet" xorm:"ne_set"`
+ KpiSet struct {
+ Code string `json:"Code"`
+ KPIs []string `json:"KPIs`
+ } `json:"kpiSet" xorm:"kpi_set"`
+ StartTime string `json:"startTime" xorm:"start_time"`
+ EndTime string `json:"endTime" xorm:"end_time"`
+ Periods []struct {
+ Start string `json:"start"`
+ End string `json:"end"`
+ } `json:"Periods" xorm:"periods`
+ Schedule struct {
+ Type string `json:"type"`
+ Days []int `json:"days"`
+ } `json:"schedule" xorm:"schedule"`
+ GranulOption string `json:"granulOption" xorm:"granul_option"`
+ Status string `json:"status" xorm:"status"`
+ CreateTime string `json:"createTime" xorm:"create_time"`
+ UpdateTime string `json:"updateTime" xorm:"update_time"`
+ DeleteTime string `json:"deleteTime xorm:"delete_time"`
+}
+
+type ScheduleJ struct {
+ Type string `json:"Type"`
+ Days []int `json:"Days"`
+}
+
+type Period struct {
+ Start string `json:"Start"`
+ End string `json:"End"`
+}
+
+type KpiSetJ struct {
+ Code string `json:"Code"` // 统计编码 如:SMFHA01
+ KPIs []string `json:"KPIs` // 指标项集合 ["SMF.AttCreatePduSession", "SMF.AttCreatePduSession._Dnn"]
+}
+
+type MeasureTask struct {
+ Id int `json:"id" xorm:"pk 'id' autoincr"`
+ NeType string `json:"neType" xorm:"ne_type"`
+ NeIds []string `json:"neIds" xorm:"ne_ids"`
+ KpiSet []KpiSetJ `json:"KPISet" xorm:"kpi_set"`
+ StartTime string `json:"startTime" xorm:"start_time"`
+ EndTime string `json:"endTime" xorm:"end_time"`
+ Periods []Period `json:"Periods" xorm:"periods`
+ Schedule []ScheduleJ `json:"Schedule" xorm:"schedule"`
+ GranulOption string `json:"granulOption" xorm:"granul_option"`
+ Status string `json:"status" xorm:"status"`
+ CreateTime string `json:"createTime" xorm:"create_time"`
+ UpdateTime string `json:"updateTime" xorm:"update_time"`
+ DeleteTime string `json:"deleteTime xorm:"delete_time"`
+}
+
+func GetMeasureTask(taskId int) (*MeasureTask, error) {
+ log.Debug("GetMeasureTask processing... ")
+
+ measureTask := new(MeasureTask)
+ has, err := xEngine.Table("measure_task").Where("id=?", taskId).Get(measureTask)
+ if err != nil || has == false {
+ log.Error("Failed to get table measure_task from database:", err)
+
+ return nil, err
+ }
+
+ log.Debug("Measure Task:", measureTask)
+ return measureTask, nil
+}
+
+func XormGetActiveMeasureTask(measureTasks *[]MeasureTask) (*[]MeasureTask, error) {
+ log.Debug("XormGetActiveMeasureTask processing... ")
+
+ measureTask := new(MeasureTask)
+ rows, err := xEngine.Table("measure_task").Where("status='Active'").Rows(measureTask)
+ if err != nil {
+ log.Error("Failed to get table measure_task:", err)
+ return nil, err
+ }
+ defer rows.Close()
+ for rows.Next() {
+ err := rows.Scan(measureTask)
+ if err != nil {
+ log.Error("Failed to get table measure_task from database:", err)
+ return nil, err
+ }
+ *measureTasks = append(*measureTasks, *measureTask)
+ }
+ log.Debug("measureTasks:", measureTasks)
+ return measureTasks, nil
+}
+
+func GetTableByWhere(whereCondition string, tableName string) (*[]interface{}, error) {
+ log.Debug("GetTableByWhere processing... ")
+
+ rows := new([]interface{})
+ has, err := xEngine.Table(tableName).Where(whereCondition).Get(rows)
+ if err != nil {
+ log.Errorf("Failed to get table %s from database:%v", tableName, err)
+ return nil, err
+ } else if has == false {
+ log.Infof("Not found table %s from database:where=%d", tableName, whereCondition)
+ return nil, nil
+ }
+
+ log.Debugf("%s:%v", tableName, rows)
+ return rows, nil
+}
+
+func GetTableById(id int, tableName string) (*[]interface{}, error) {
+ log.Debug("GetTableById processing... ")
+
+ rows := new([]interface{})
+ has, err := xEngine.Table(tableName).ID(id).Get(rows)
+ if err != nil {
+ log.Errorf("Failed to get table %s from database:id=%d, %v", tableName, id, err)
+ return nil, err
+ } else if has == false {
+ log.Infof("Not found table %s from database:id=%d", tableName, id)
+ return nil, nil
+ }
+
+ log.Debugf("%s:%v", tableName, rows)
+ return rows, nil
+}
+
+func XormUpdateTableById(id int, tableName string, tbInfo interface{}) (int64, error) {
+ log.Debug("XormUpdateTableById processing...id: ", id)
+
+ affected, err := xEngine.Table(tableName).ID(id).Update(tbInfo)
+ if err != nil {
+ log.Errorf("Failed to update table %s from database:%v", tableName, err)
+ return 0, err
+ }
+
+ return affected, nil
+}
+
+func XormUpdateTableByWhere(whereCondition string, tableName string, tbInfo interface{}) (int64, error) {
+ log.Debug("UpdateTableByWhere processing... ")
+
+ affected, err := xEngine.Table(tableName).Where(whereCondition).Update(tbInfo)
+ if err != nil {
+ log.Errorf("Failed to update table %s from database:%v", tableName, err)
+ return 0, err
+ }
+
+ return affected, nil
+}
+
+type User struct {
+ Id int `json:"id" xorm:"pk 'id' autoincr"`
+ AccountId string `json:"accountId"`
+ Name string `json:"name" xorm:"name"`
+ Sn string `json:"sn"`
+ Gender string `json:"gender"`
+ Description string `json:"description"`
+ TelephoneNumber string `json:"telephoneNumber" xorm:"telephone_number"`
+ Mobile string `json:"mobile"`
+ Email string `json:"email" xorm:"email"`
+ StartTime string `json:"startTime" xorm:"start_time"`
+ EndTime string `json:"endTime" xorm:"end_time"`
+ IdCardNumber string `json:"idCardNumber"`
+ EmployeeNumber string `json:"employeeNumber"`
+ Organize string `json:"organize"`
+ EmployeeType string `json:"employeeType"`
+ SupporterCorpName string `json:"supporterCorpName"`
+ RealName string `json:"realName" xorm:"real_name"`
+ Password string `json:"password" xorm:"password"`
+ PasswordSha512 string `json:"passwordSha512"`
+ ChangePasswordFlag int `json:"changePasswordFlag"`
+ PasswordExpiration string `json:"passwordExpiration"`
+ Status string `json:"status"`
+ UserExpiration string `json:"userExpiration"`
+ GroupName string `json:"groupId" xorm:"group_name"`
+ Profile string `json:"profile" xorm:"-"`
+ Phone string `json:"phone" xorm:"phone"`
+ CreateTime string `json:"createTime" xorm:"create_time"`
+ UpdateTime string `json:"updateTime" xorm:"update_time"`
+}
+
+func XormCheckLoginUser(name, password, cryptArgo string) (bool, *User, error) {
+ log.Info("XormCheckLoginUser processing... ")
+
+ user := new(User)
+ // has, err := xEngine.Table("user").Where("name='%s' and password=PASSWORD('%s')", name, password).Get(user)
+ switch cryptArgo {
+ case "mysql":
+ has, err := xEngine.SQL("select * from user where status='Active' and account_id=? and password=PASSWORD(?)", name, password).Exist()
+ if err != nil || has == false {
+ log.Error("Failed to check user from database:", err)
+
+ return false, nil, err
+ }
+ case "md5":
+ has, err := xEngine.
+ SQL("select * from user where status='Active' and account_id=? and password=MD5(?)", name, password).Exist()
+ if err != nil || has == false {
+ log.Error("Failed to check user from database:", err)
+ return false, nil, err
+ }
+ case "bcrypt":
+ has, err := xEngine.Table("user").Where("status='Active' and account_id=?", name).Get(user)
+ if err != nil || has == false {
+ log.Error("Failed to get user from database:", err)
+ return false, nil, err
+ }
+ if oauth.BcryptCompare(user.Password, password) != nil {
+ err := errors.New("Incorrect login name or password")
+ log.Error(err)
+ return false, nil, err
+ }
+ default:
+ err := errors.New("Incorrect crypt algoritmo")
+ log.Error("crypt:%s", err)
+ return false, nil, err
+ }
+
+ return true, user, nil
+}
+
+func XormGetConfigValue(moduleName, configTag string) (string, error) {
+ var value string
+ _, err := xEngine.Table("config").
+ Where("module_name=? and config_tag=?", moduleName, configTag).
+ Cols("value").
+ Get(&value)
+ if err != nil {
+ log.Error("Failed to get config:", err)
+ return "", err
+ }
+ return value, nil
+}
+
+type Session struct {
+ Id int `json:"id" xorm:"pk 'id' autoincr"`
+ AccountId string `json:"accountId" xorm:"account_id"`
+ Name string `json:"name" xorm:"name"`
+ Host string `json:"host" xorm:"host"`
+ AccessToken string `json:"accessToken" xorm:"access_token"`
+ Expires uint32 `json:"expires" xorm:"expires"`
+ Status string `json:"status" xorm:"status"`
+ LoginTime string `json:"loginTime" xorm:"-"`
+ ShakeTime sql.NullTime `son:"shakeTime" xorm:"shake_time"`
+ LogoutTime sql.NullTime `json:"logoutTime" xorm:"logout_time"`
+}
+
+// XormInsertSession create session
+func XormInsertSession(name, host, token string, expires uint32, sessionFlag string) (int64, error) {
+ log.Info("XormInsertSession processing... ")
+
+ var affected int64 = 0
+ var err error = nil
+ currentTime := time.Now()
+ timeValue := currentTime.Local()
+ nullTime := sql.NullTime{Valid: true, Time: timeValue}
+ value, err := XormGetConfigValue("Security", "sessionExpires")
+ if err != nil {
+ return affected, err
+ }
+ if value != "" {
+ intValue, _ := strconv.Atoi(value)
+ expires = uint32(intValue)
+ log.Debugf("intValue=%d, expires=%d", intValue, expires)
+ }
+
+ session := Session{AccountId: name,
+ Name: name, Host: host, AccessToken: token,
+ Status: "online", Expires: expires,
+ ShakeTime: nullTime,
+ }
+
+ //session.ShakeTime.Time
+ xSession := xEngine.NewSession()
+ defer xSession.Close()
+ if strings.ToLower(sessionFlag) == "multiple" {
+ exist, err := xEngine.Table("session").Where("status = 'online' and account_id = ? and host = ?", name, host).Exist()
+ if err != nil {
+ return affected, err
+ }
+ if exist == true {
+ affected, err = xSession.Table("session").Where("account_id = ? and host = ?", name, host).Update(session)
+ } else {
+ affected, err = xSession.InsertOne(session)
+ }
+ } else { // single session for a user
+ exist, err := xEngine.Table("session").Where("status = 'online' and account_id = ?", name).Exist()
+ if err != nil {
+ return affected, err
+ }
+ if exist == true {
+ // todo...
+ err := errors.New("user is logged in")
+ return -1, err
+ } else {
+ affected, err = xSession.InsertOne(session)
+ }
+ }
+ xSession.Commit()
+ return affected, err
+}
+
+// XormUpdateSession update session
+func XormLogoutUpdateSession(token string) (int64, error) {
+ log.Info("XormLogoutUpdateSession processing... ")
+
+ session := Session{Status: "offline", AccessToken: token}
+ session.LogoutTime.Valid = true
+ session.LogoutTime.Time = time.Now()
+
+ xSession := xEngine.NewSession()
+ defer xSession.Close()
+ affected, err := xSession.Table("session").Where("access_token = ?", token).Update(session)
+ xSession.Commit()
+ return affected, err
+}
+
+// XormUpdateSessionShakeTime create session
+func XormUpdateSessionShakeTime(token string) (int64, error) {
+ log.Debug("XormUpdateSessionShakeTime processing... ")
+
+ session := Session{AccessToken: token}
+ session.ShakeTime.Valid = true
+ session.ShakeTime.Time = time.Now()
+ xSession := xEngine.NewSession()
+ defer xSession.Close()
+ affected, err := xSession.Table("session").Where("access_token = ?", token).Update(session)
+ xSession.Commit()
+ return affected, err
+}
+
+func XormExistValidToken(token string, expires uint32) bool {
+ log.Info("XormExistValidToken processing... ")
+
+ exist, err := xEngine.Table("session").
+ Where("status = 'online' and access_token = ? and DATE_ADD(shake_time, INTERVAL expires SECOND) > NOW()", token).
+ Exist()
+ if err != nil {
+ return false
+ }
+
+ return exist
+}
+
+/*
+ type NorthboundPm struct {
+ Id int `json:"id" xorm:"pk 'id' autoincr"`
+ Date string `json:"date" xorm:"date"`
+ Index int `json:"index"`
+ StartTime string `json:"startTime" xorm:"start_time"`
+ TimeZone string `json:"timeZone" xorm:"time_zone"`
+ NEName string `json:"neName" xorm:"ne_name"`
+ PmVersion string `json:"pmVersion" xorm:"pm_version"`
+ Period string `json:"period" xorm:"pevalue"
+ RmUid string `json:"rmUid" xorm:"rm_uid"`
+ NEType string `json:"neType" xorm:"ne_type"`
+ Dn string `json:"neType" xorm:"ne_type"`
+ ObjectType string `json:"objectType" xorm:"object_type"`
+ PmName string `json:"pmName" xorm:"pm_name"`
+ PmExt string `json:"pmExt" xorm:"pm_ext"`
+ Value int `json:"value" xorm:"value"`
+ Timestamp string `json:"timestamp" xorm:"timestamp"`
+ }
+*/
+type NorthboundPm struct {
+ Id int `json:"-" xorm:"pk 'id' autoincr"`
+ Date string `json:"Date" xorm:"date"`
+ Index int `json:"Index" xorm:"index"` // 1天中测量时间粒度(如15分钟)的切片索引: 0~95
+ Timestamp string `json:"-" xorm:"-"`
+ NeName string `json:"NeName" xorm:"ne_name"` // UserLabel
+ RmUID string `json:"RmUID" xorm:"rm_uid"`
+ NeType string `json:"NeType" xorm:"ne_type"` // 网元类型
+ PmVersion string `json:"PmVersion" xorm:"pm_version"` // 性能数据版本号
+ Dn string `json:"Dn" xorm:"dn"` // (???)网元标识, 如:RJN-CMZJ-TZ,SubNetwork=5GC88,ManagedElement=SMF53456,SmfFunction=53456
+ Period string `json:"Period" xorm:"period"` // 测量时间粒度选项:5/15/30/60
+ TimeZone string `json:"TimeZone" xorm:"time_zone"`
+ StartTime string `json:"StartTime" xorm:"start_time"`
+
+ Datas []struct {
+ ObjectType string `json:"ObjectType" xorm:"object_type"` // 网络资源类别名称, Pm指标项列表中为空间粒度 如:SmfFunction
+ PmDatas []struct {
+ PmName string `json:"KPIID" xorm:"pm_name"` // 指标项, 如: SMF.AttCreatePduSession._Dnn
+ SubDatas []struct {
+ SN string `json:"Name" xorm:"sn"` // 单个的写"Total", 或者指标项有多个测量项,如Dnn的名称写对应的Dnn"cmnet"/"ims"
+ SV int64 `json:"Value" xorm:"sv"`
+ } `json:"KPIValues" xorm:"sub_datas"`
+ } `json:"KPIs" xorm:"pm_datas"`
+ } `json:"Datas" xorm:"datas"`
+}
+
+type Alarm struct {
+ AlarmSeq int `json:"alarmSeq"`
+ AlarmId string `json:"alarmId" xorm:"alarm_id"`
+ NeId string `json:"neId"`
+ AlarmCode int `json:"alarmCode"`
+ AlarmTitle string `json:"alarmTitle"`
+ EventTime string `json:"eventTime"`
+ AlarmType string `json:"alarmType"`
+ OrigSeverity string `json:"origSeverity"`
+ PVFlag string `json:"pvFlag" xorm:"pv_flag"`
+ NeName string `json:"neName"`
+ NeType string `json:"neType"`
+ ObjectName string `json:"objectName" xorm:"object_name"`
+ LocationInfo string `json:"locationInfo"`
+ Province string `json:"province"`
+ AlarmStatus int `json:"alarmStatus"`
+ SpecificProblem string `json:"specificProblem"`
+ SpecificProblemID string `json:"specificProblemID" xorm:"specific_problem_id"`
+ AddInfo string `json:"addInfo"`
+
+ // AckState int `json:"ackState" xorm:"-"`
+ // AckTime string `json:"ackTime" xorm:"-"`
+ ClearType int `json:"clearType" xorm:"-"` // 0: Unclear, 1: Auto clear, 2: Manual clear
+ ClearTime string `json:"clearTime" xorm:"-"`
+}
+
+func XormGetAlarmByAlarmId(alarmId string, alarms *[]Alarm) (*[]Alarm, error) {
+ log.Debug("XormGetAlarmByAlarmId processing... ")
+
+ alarm := new(Alarm)
+ rows, err := xEngine.Table("alarm").Where("alarm_id=?", alarmId).Rows(alarm)
+ if err != nil {
+ log.Error("Failed to get table alarm from database:", err)
+ return nil, err
+ }
+
+ defer rows.Close()
+ for rows.Next() {
+ err := rows.Scan(alarm)
+ if err != nil {
+ log.Error("Failed to get table alarm from database:", err)
+ return nil, err
+ }
+ *alarms = append(*alarms, *alarm)
+ }
+
+ log.Trace("alarms:", alarms)
+ return alarms, nil
+}
+
+func XormSQLGetStringValue(querySQL string) (string, error) {
+ log.Debug("XormSQLGetStringValue processing... ")
+
+ row := make(map[string]interface{})
+ _, err := xEngine.SQL(querySQL).Get(&row)
+ if err != nil {
+ log.Errorf("Failed to get by SQL=%s:%v", querySQL, err)
+ return "", err
+ }
+
+ for _, v := range row {
+ return fmt.Sprintf("%v", v), nil
+ }
+
+ return "", nil
+}
+
+func XormGetSingleCol(table, col, where string) (string, error) {
+ log.Debug("XormGetSingleCol processing... ")
+
+ row := make(map[string]interface{})
+ _, err := xEngine.Table(table).Where(where).Cols(col).Get(&row)
+ if err != nil {
+ log.Errorf("Failed to get %s from table %s:%v", col, table, err)
+ return "", err
+ }
+
+ for _, v := range row {
+ return fmt.Sprintf("%v", v), nil
+ }
+
+ return "", nil
+}
+
+func XormGetSingleColStringArrayByIn(table, col, incol string, conditions []string, cols *[]string) error {
+ log.Debug("XormGetSingleColStringArrayByIn processing... ")
+
+ err := xEngine.Table(table).In(incol, conditions).Cols(col).Distinct().Find(cols)
+ if err != nil {
+ log.Errorf("Failed to get %s from table %s:%v", col, table, err)
+ return err
+ }
+ return nil
+}
+
+func XormGetColStringArrayByWhere(table, coln, where string, colv *[]string) error {
+ log.Debug("XormGetColStringArrayByWhere processing... ")
+
+ _, err := xEngine.Table(table).Where(where).Cols(coln).Get(colv)
+ if err != nil {
+ log.Errorf("Failed to Get %s from table %s:%v", coln, table, err)
+ return err
+ }
+ return nil
+}
+
+func XormFindColStringArrayByWhere(table, col, where string, cols *[]string) error {
+ log.Debug("XormFindColStringArrayByWhere processing... ")
+
+ err := xEngine.Table(table).Where(where).Cols(col).Distinct().Find(cols)
+ if err != nil {
+ log.Errorf("Failed to Find %s from table %s:%v", col, table, err)
+ return err
+ }
+ return nil
+}
+
+func XormGetSingleColStringByWhere(table, col, where string) (string, error) {
+ log.Info("XormFindSingleColStringByWhere processing... ")
+
+ var colv string
+ _, err := xEngine.Table(table).Where(where).Cols(col).Get(&colv)
+ if err != nil {
+ log.Errorf("Failed to Find %s from table %s:%v", col, table, err)
+ return colv, err
+ }
+ return colv, nil
+}
+
+func XormGetSingleColStringArrayByID(table, col string, id int, cols *[]string) error {
+ log.Debug("XormGetSingleColStringArrayByID processing... ")
+
+ err := xEngine.Table(table).ID(id).Cols(col).Find(cols)
+ if err != nil {
+ log.Errorf("Failed to Find %s from table %s:%v", col, table, err)
+ return err
+ }
+ return nil
+}
+
+func XormGetStringValue(table, col string, id int) (string, error) {
+ log.Debug("XormGetStringValue processing... ")
+
+ row := make(map[string]interface{})
+ _, err := xEngine.ID(id).Table(table).Cols(col).Get(&row)
+ if err != nil {
+ log.Errorf("Failed to get %s from table %s:%v", col, table, err)
+ return "", err
+ }
+
+ for _, v := range row {
+ return fmt.Sprintf("%v", v), nil
+ }
+
+ return "", nil
+}
+
+type NeBackup struct {
+ Id int `json:"id" xorm:"pk 'id' autoincr"`
+ NeType string `json:"neType" xorm:"ne_type"`
+ NeId string `json:"neId" xorm:"ne_id"`
+ FileName string `json:"neName" xorm:"file_name"`
+ Path string `json:"path"`
+ Md5Sum string `json:"md5Sum" xorm:"md5_sum"`
+ CreateTime string `json:"createTime" xorm:"-" `
+}
+
+// XormInsertSession create session
+func XormInsertTableOne(tableName string, tbInfo interface{}) (int64, error) {
+ log.Debug("XormInsertTableOne processing... ")
+
+ var affected int64 = 0
+ var err error = nil
+
+ xSession := xEngine.NewSession()
+ defer xSession.Close()
+ affected, err = xSession.Table(tableName).InsertOne(tbInfo)
+ xSession.Commit()
+ return affected, err
+}
+
+// XormExistTableOne create session
+func XormExistTableOne(tableName string, where string) (bool, error) {
+ log.Debug("XormExistTableOne processing... ")
+
+ has, err := xEngine.Table(tableName).Where(where).Exist()
+
+ return has, err
+}
+
+func XormGetTableRows(tableName string, where string, tbInfo *[]interface{}) (*[]interface{}, error) {
+ log.Debug("XormGetTableRows processing... ")
+
+ row := make(map[string]interface{})
+ rows, err := xEngine.Table(tableName).Where(where).Rows(row)
+ if err != nil {
+ log.Errorf("Failed to Rows table %s from database: %v", tableName, err)
+ return nil, err
+ }
+ defer rows.Close()
+ for rows.Next() {
+ err := rows.Scan(row)
+ if err != nil {
+ log.Errorf("Failed to Scan table %s from database: %v", tableName, err)
+ return nil, err
+ }
+ *tbInfo = append(*tbInfo, row)
+ }
+ log.Debug("tbInfo:", tbInfo)
+ return tbInfo, nil
+}
+
+type MeasureThreshold struct {
+ Id int `json:"id" xorm:"pk 'id' autoincr"`
+ NeType string `json:"neType" xorm:"ne_type"`
+ KpiSet []string `json:"kpiSet" xorm:"kpi_set"`
+ Threshold int64 `json:"threshold"`
+ Status string `json:"md5Sum" xorm:"md5_sum"`
+ OrigSeverity string `json:"createTime" xorm:"orig_severity"`
+ AlarmId string `json:"alarmId" xorm:"alarm_id"`
+}
+
+type NeSoftware struct {
+ Id int `json:"id" xorm:"pk 'id' autoincr"`
+ NeType string `json:"neType" xorm:"ne_type"`
+ FileName string `json:"neName" xorm:"file_name"`
+ Path string `json:"path"`
+ Version string `json:"version"`
+ Md5Sum string `json:"md5Sum" xorm:"md5_sum"`
+ Comment string `json:"comment"`
+ // Status string `json:"status"`
+ UpdateTime string `json:"createTime" xorm:"-" `
+}
+
+type NeVersion struct {
+ Id int `json:"id" xorm:"pk 'id' autoincr"`
+ NeType string `json:"neType" xorm:"ne_type"`
+ NeId string `json:"neId" xorm:"ne_id"`
+ Version string `json:"version"`
+ FilePath string `json:"filePath" xorm:"file_path"`
+ NewVersion string `json:"newVersion" xorm:"new_version"`
+ NewFile string `json:"newFile" xorm:"new_file"`
+ PreVersion string `json:"preVersion" xorm:"pre_version"`
+ PreFile string `json:"preFile" xorm:"pre_file"`
+ Status string `json:"status"`
+ UpdateTime string `json:"createTime" xorm:"-" `
+}
+
+func XormGetDataBySQL(sql string) (*[]map[string]string, error) {
+ log.Debug("XormGetDataBySQL processing... ")
+
+ rows := make([]map[string]string, 0)
+ rows, err := DbClient.XEngine.QueryString(sql)
+ if err != nil {
+ log.Errorf("Failed to QueryString:", err)
+ return nil, err
+ }
+
+ return &rows, nil
+}
+
+func XormDeleteDataByWhere(where, table string) (int64, error) {
+ log.Debug("XormDeleteDataByWhere processing... ")
+
+ xSession := DbClient.XEngine.NewSession()
+ defer xSession.Close()
+ affected, err := xSession.Table(table).Where(where).Delete()
+ if err != nil {
+ log.Errorf("Failed to Delete:", err)
+ return 0, err
+ }
+ xSession.Commit()
+
+ return affected, nil
+}
+
+func XormDeleteDataById(id int, table string) (int64, error) {
+ log.Debug("XormDeleteDataByWhere processing... ")
+
+ xSession := DbClient.XEngine.NewSession()
+ defer xSession.Close()
+ affected, err := xSession.Table(table).ID(id).Delete()
+ if err != nil {
+ log.Error("Failed to Delete:", err)
+ return 0, err
+ }
+ xSession.Commit()
+
+ return affected, nil
+}
+
+type ColOutput struct {
+ Name string `json:"name"`
+ Display string `json:"display"`
+ Length int `json:"length"`
+ Alias []string `json:"Alias"`
+}
+
+type ColInput struct {
+ Name string `json:"name"`
+ Alias string `json:"Alias"`
+ Type string `json:"type"`
+ Length int `json:"length"`
+ Value any `json:"value"`
+}
+
+type MmlInput struct {
+ BodyFmt string `json:"bodyFmt"`
+ BodyKey string `json:"bodyKey"`
+
+ Cols []ColInput `json:"cols"`
+}
+
+type MmlOutput struct {
+ RetFmt string `json:"retFmt"`
+ RetMsg string `json:"retMsg"`
+ ErrMsg string `json:"errMsg"`
+ Title string `json:"title"`
+ SingleList bool `json:"singleList"`
+ SepSpaceNum int `json:"sepSpaceNum"`
+ AlignmentM string `json:"alignmentM"`
+ AlignmentSN string `json:"alignmentSN"`
+ AlignmentSV string `json:"alignmentSV"`
+ Cols []ColOutput `json:"cols"`
+ End string `json:"end"`
+}
+
+type MmlHttpMap struct {
+ ID int `json:"-" xorm:"id"`
+ NeType string `json:"neType" xorm:"ne_type"`
+ Operation string `json:"operation"`
+ Object string `json:"object"`
+ Method string `json:"method"`
+ URI string `json:"uri" xorm:"uri"`
+ ExtUri string `json:"extUri"`
+ ParamTag string `json:"paramTag"`
+ Params string `json:"params"`
+ Input string `json:"input"`
+ Output string `json:"output"`
+}
+
+func XormGetMmlHttpMap(table, where string) (*MmlHttpMap, error) {
+ mmlMap := new(MmlHttpMap)
+ _, err := DbClient.XEngine.Table(table).Where(where).Get(mmlMap)
+ if err != nil {
+ log.Error("Failed to Get:", err)
+ return nil, err
+ }
+ return mmlMap, nil
+}
+
+type MmlCommand struct {
+ ID int `json:"-" xorm:"id"`
+ NeType string `json:"neType" xorm:"ne_type"`
+ Category string `json:"category"`
+ CatDisplay string `json:"catDisplay"`
+ Operation string `json:"operation"`
+ Object string `json:"object" xorm:"object"`
+ MmlDisplay string `json:"mmlDisplay"`
+ ParamJson []struct {
+ Name string `json:"name"`
+ Alias string `json:"alias"`
+ Type string `json:"type"`
+ Optional string `json:"optional"`
+ Apostr string `json:"apostr"`
+ Loc string `json:"loc"`
+ Filter string `json:"filter"`
+ Display string `json:"display"`
+ Comment string `json:"comment"`
+ } `json:"paramJson"`
+}
+
+func XormGetMmlCommand(table, where string) (*MmlCommand, error) {
+ mmlCmd := new(MmlCommand)
+ _, err := DbClient.XEngine.Table(table).Where(where).Get(mmlCmd)
+ if err != nil {
+ log.Error("Failed to Get:", err)
+ return nil, err
+ }
+ return mmlCmd, nil
+}
+
+type AlarmOMCConfig struct {
+ ID int `json:"-" xorm:"id"`
+ ModuleName string `json:"moduleName"`
+ ConfigTag string `json:"configTag"`
+ Value string `json:"value"`
+ ValueJson string `json:"valueJson"`
+}
+
+type ValueJson struct {
+ AlarmStatus string `json:"alarm_status"`
+ AlarmType string `json:"alarm_type"`
+ OrigSeverity string `json:"orig_severity"`
+ AckUser string `json:"ack_user"`
+}
+
+type AlarmForwardToUsers struct {
+ Interface string `json:"interface"`
+ ToUser []string `json:"to_user"`
+}
+
+func XormGetAAConfig() (*ValueJson, error) {
+ aaConfig := new(AlarmOMCConfig)
+ _, err := DbClient.XEngine.Table("config").
+ Where("module_name=? and config_tag=?", "Alarm", "autoAlarmAck").
+ Cols("value", "value_json").
+ Get(aaConfig)
+ if err != nil {
+ log.Error("Failed to Get:", err)
+ return nil, err
+ }
+ log.Debug("aaConfig:", aaConfig)
+ valueJson := new(ValueJson)
+ err = json.Unmarshal([]byte(aaConfig.ValueJson), valueJson)
+ if err != nil {
+ log.Error("Failed to Unmarshal:", err)
+ return nil, err
+ }
+ log.Debug("valueJson:", valueJson)
+ return valueJson, nil
+}
+
+func XormGetAlarmForward(interfaceName string) (*[]string, error) {
+ alarmForwardConfig := new(AlarmOMCConfig)
+ _, err := DbClient.XEngine.Table("config").
+ Where("module_name=? and config_tag=?", "Alarm", "forwardAlarm").
+ Cols("value", "value_json").
+ Get(alarmForwardConfig)
+ if err != nil {
+ log.Error("Failed to Get:", err)
+ return nil, err
+ }
+ log.Debug("alarmForwardConfig:", alarmForwardConfig)
+ alarmForwardToUsers := new([]AlarmForwardToUsers)
+ err = json.Unmarshal([]byte(alarmForwardConfig.ValueJson), alarmForwardToUsers)
+ if err != nil {
+ log.Error("Failed to Unmarshal:", err)
+ return nil, err
+ }
+ log.Debug("alarmForwardToUsers:", alarmForwardToUsers)
+ for _, a := range *alarmForwardToUsers {
+ if a.Interface == interfaceName {
+ return &(a.ToUser), nil
+ }
+ }
+ return nil, nil
+}
+
+type AlarmForwardLog struct {
+ ID int `json:"-" xorm:"pk 'id' autoincr"`
+ NeType string `json:"neType" xorm:"ne_type"`
+ NeID string `json:"neID" xorm:"ne_id"`
+ AlarmID string `json:"alarmID" xorm:"alarm_id"`
+ AlarmTitle string `json:"alarmTitle" xorm:"alarm_title"`
+ AlarmSeq int `json:"alarmSeq" xorm:"alarm_seq"`
+ EventTime string `json:"eventTime" xorm:"event_time"`
+ ToUser string `json:"toUser" xorm:"to_user"`
+ OperResult string `json:"operResult" xorm:"oper_result"`
+ LogTime string `json:"-" xorm:"-"`
+}
+
+func XormInsertAlarmForwardLog(logData *AlarmForwardLog) (int64, error) {
+ log.Debug("XormInsertAlarmForwardLog processing... ")
+
+ xSession := xEngine.NewSession()
+ defer xSession.Close()
+ affected, err := xSession.Insert(logData)
+ xSession.Commit()
+
+ return affected, err
+}
+
+type SystemLog struct {
+ ID int `json:"-" xorm:"pk 'id' autoincr"`
+ User string `json:"user" xorm:"user"`
+ ProcessName string `json:"process_name" xorm:"process_name"`
+ ProcessID int32 `json:"process_id" xorm:"process_id"`
+ Operation string `json:"operation" xorm:"operation"`
+ ProcessTime string `json:"process_time" `
+ LogTime string `json:"-" xorm:"-"`
+}
+
+func XormInsertSystemLog(logData *SystemLog) (int64, error) {
+ log.Info("XormInsertSystemLog processing... ")
+
+ xSession := xEngine.NewSession()
+ defer xSession.Close()
+ affected, err := xSession.Insert(logData)
+ xSession.Commit()
+
+ return affected, err
+}
+
+type permission struct {
+ ID int `json:"-" xorm:"pk 'id' autoincr"`
+ PermissionName string `json:"permissionName"`
+ Method string `json:"method"`
+ Element string `json:"element"`
+ Object string `json:"object"`
+}
+
+func IsPermissionDeny(token, method, dbname, tbname string) (bool, error) {
+ log.Info("IsPermissionDeny processing... ")
+
+ exist, err := xEngine.Table("permission").
+ Join("INNER", "role_permission", "permission.permission_name = role_permission.p_name").
+ Join("INNER", "user_role", "role_permission.r_name = user_role.r_name").
+ Join("INNER", "session", "user_role.u_name = session.account_id and session.access_token=?", token).
+ Where("method in ('*',?) and element in ('*',?) and object in ('*',?)", method, dbname, tbname).
+ //Where("method=? and element=?", method, dbname).
+ Exist()
+ if err != nil {
+ return false, err
+ }
+
+ return exist, nil
+}
diff --git a/lib/file/file.go b/lib/file/file.go
new file mode 100644
index 00000000..7b643817
--- /dev/null
+++ b/lib/file/file.go
@@ -0,0 +1,120 @@
+package file
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "net"
+ "net/http"
+ "time"
+
+ "ems.agt/lib/dborm"
+ "ems.agt/lib/global"
+ "ems.agt/lib/log"
+ "ems.agt/lib/services"
+ "ems.agt/restagent/config"
+ "github.com/gorilla/mux"
+)
+
+const (
+ //经过测试,linux下,延时需要大于100ms
+ TIME_DELAY_AFTER_WRITE = 200
+)
+
+type Response struct {
+ Data []string `json:"data"`
+}
+
+type MMLRequest struct {
+ MML []string `json:"mml"`
+}
+
+func GetFile(w http.ResponseWriter, r *http.Request) {
+ log.Debug("PostMMLToNF processing... ")
+
+ vars := mux.Vars(r)
+ neType := vars["elementTypeValue"]
+ params := r.URL.Query()
+ neId := params["ne_id"]
+ log.Debug("neType:", neType, "neId", neId)
+
+ neInfo := new(dborm.NeInfo)
+ var err error
+ if len(neId) == 0 {
+ log.Error("ne_id NOT FOUND")
+ services.ResponseBadRequest400WrongParamValue(w)
+ return
+ }
+ neInfo, err = dborm.XormGetNeInfo(neType, neId[0])
+ if err != nil {
+ log.Error("dborm.XormGetNeInfo is failed:", err)
+ services.ResponseInternalServerError500DatabaseOperationFailed(w)
+ return
+ }
+
+ var buf [8192]byte
+ var n int
+ var mmlResult []string
+
+ if neInfo != nil {
+ hostMML := fmt.Sprintf("%s:%d", neInfo.Ip, config.GetYamlConfig().MML.Port)
+ conn, err := net.Dial("tcp", hostMML)
+ if err != nil {
+ errMsg := fmt.Sprintf("Failed to dial %s: %v", hostMML, err)
+ log.Error(errMsg)
+ mmlResult = append(mmlResult, errMsg)
+ response := Response{mmlResult}
+ services.ResponseWithJson(w, http.StatusOK, response)
+ return
+ }
+
+ loginStr := fmt.Sprintf("%s\n%s\n", config.GetYamlConfig().MML.User, config.GetYamlConfig().MML.Password)
+ n, err = conn.Write([]byte(loginStr))
+ if err != nil {
+ log.Errorf("Error: %s", err.Error())
+ return
+ }
+
+ time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
+
+ n, err = conn.Read(buf[0:])
+ if err != nil {
+ log.Errorf("Error: %s", err.Error())
+ return
+ }
+ log.Debug(string(buf[0:n]))
+
+ body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
+ if err != nil {
+ log.Error("io.ReadAll is failed:", err)
+ services.ResponseNotFound404UriNotExist(w, r)
+ return
+ }
+ log.Debug("Body:", string(body))
+
+ mmlRequest := new(MMLRequest)
+ _ = json.Unmarshal(body, mmlRequest)
+
+ for _, mml := range mmlRequest.MML {
+ mmlCommand := fmt.Sprintf("%s\n", mml)
+ log.Debug("mml command:", mmlCommand)
+ n, err = conn.Write([]byte(mmlCommand))
+ if err != nil {
+ log.Errorf("Error: %s", err.Error())
+ return
+ }
+ time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
+
+ n, err = conn.Read(buf[0:])
+ if err != nil {
+ log.Errorf("Error: %s", err.Error())
+ return
+ }
+ log.Debug(string(buf[0 : n-len(neType)-2]))
+ mmlResult = append(mmlResult, string(buf[0:n-len(neType)-2]))
+ }
+ }
+
+ response := Response{mmlResult}
+ services.ResponseWithJson(w, http.StatusOK, response)
+}
diff --git a/lib/global/global.go b/lib/global/global.go
new file mode 100644
index 00000000..4c6e455d
--- /dev/null
+++ b/lib/global/global.go
@@ -0,0 +1,58 @@
+package global
+
+import "errors"
+
+// 跨package引用的首字母大写
+const (
+ RequestBodyMaxLen = 2000000
+ ApiVersionV1 = "v1"
+ ApiVersionV2 = "v2"
+ LineBreak = "\n"
+)
+
+const (
+ DateTime = "2006-01-02 15:04:05"
+ DateData = "20060102150405"
+ DateHour = "2006010215"
+)
+
+const (
+ MaxInt32Number = 2147483647
+)
+
+const (
+ MaxLimitData = 1000
+)
+
+var (
+ Version string
+ BuildTime string
+ GoVer string
+)
+
+var (
+ ErrParamsNotAdapted = errors.New("the number of params is not adapted")
+
+ // PM module error message
+ ErrPMNotFoundData = errors.New("not found PM data")
+
+ // CM module error message
+ ErrCMNotFoundTargetNE = errors.New("not found target NE")
+ ErrCMCannotDeleteActiveNE = errors.New("can not delete an active NE")
+ ErrCMInvalidBackupFile = errors.New("invalid backup file")
+ ErrCMNotMatchMD5File = errors.New("md5 not match between file and url")
+ ErrCMNotMatchSignFile = errors.New("digests signatures not match in the file")
+ ErrCMExistSoftwareFile = errors.New("exist the same software package file")
+ ErrCMNotFoundTargetSoftware = errors.New("not found the target software package")
+ ErrCMNotFoundTargetNeVersion = errors.New("not found the target NE version")
+ ErrCMNotFoundRollbackNeVersion = errors.New("not found the rollback NE version")
+
+ ErrCMNotFoundTargetBackupFile = errors.New("not found the target NE backup")
+
+ // TRACE module error message
+ ErrTraceFailedDistributeToNEs = errors.New("failed to distribute trace task to target NEs")
+ ErrTraceNotCarriedTaskID = errors.New("not carried task id in request url")
+
+ // MML module error define
+ ErrMmlInvalidCommandFormat = errors.New("invalid mml command format")
+)
diff --git a/lib/global/kits.go b/lib/global/kits.go
new file mode 100644
index 00000000..1814ce8a
--- /dev/null
+++ b/lib/global/kits.go
@@ -0,0 +1,479 @@
+package global
+
+import (
+ "bytes"
+ "crypto/md5"
+ "encoding/hex"
+ "encoding/json"
+ "fmt"
+ "io"
+ "net"
+ "net/http"
+ "os"
+ "path/filepath"
+ "reflect"
+ "regexp"
+ "sort"
+ "strings"
+ "time"
+)
+
+const (
+ IsIPv4 = "IPv4"
+ IsIPv6 = "IPv6"
+ NonIP = "NonIp"
+)
+
+type em struct{}
+
+func GetPkgName() string {
+ return reflect.TypeOf(em{}).PkgPath()
+}
+
+// interface{} change to map[string]interface{}
+// interface{} data is []interface{}
+func ListToMap(list interface{}, key string) map[string]interface{} {
+ res := make(map[string]interface{})
+ arr := ToSlice(list)
+ for _, row := range arr {
+ immutable := reflect.ValueOf(row)
+ val := immutable.FieldByName(key).String()
+ res[val] = row
+ }
+ return res
+}
+
+// interface{} change to []interface{}
+func ToSlice(arr interface{}) []interface{} {
+ ret := make([]interface{}, 0)
+ v := reflect.ValueOf(arr)
+ if v.Kind() != reflect.Slice {
+ ret = append(ret, arr)
+ return ret
+ }
+ l := v.Len()
+ for i := 0; i < l; i++ {
+ ret = append(ret, v.Index(i).Interface())
+ }
+ return ret
+}
+
+var TodoList []Todo
+
+type Todo struct {
+ Id int64
+ Item string
+}
+
+// JSON序列化方式
+func jsonStructToMap(TodoList Todo) (map[string]interface{}, error) {
+ // 结构体转json
+ strRet, err := json.Marshal(TodoList)
+ if err != nil {
+ return nil, err
+ }
+ // json转map
+ var mRet map[string]interface{}
+ err1 := json.Unmarshal(strRet, &mRet)
+ if err1 != nil {
+ return nil, err1
+ }
+ return mRet, nil
+}
+
+func IsContain(item string, items []string) bool {
+ for _, e := range items {
+ if e == item {
+ return true
+ }
+ }
+ return false
+}
+
+func IsContainP(item string, items *[]string, size int) bool {
+ for i := 0; i < size; i++ {
+ if (*items)[i] == item {
+ return true
+ }
+ }
+ return false
+}
+
+// 将字符串 分割成 字符串数组
+// @s:分割符
+func SplitString(str string, s string) []string {
+ sa := strings.Split(str, s)
+ return sa
+}
+
+// 合并字符串数组
+func MergeStringArr(a, b []string) []string {
+ var arr []string
+ for _, i := range a {
+ arr = append(arr, i)
+ }
+ for _, j := range b {
+ arr = append(arr, j)
+ }
+ return arr
+}
+
+// 数组去重
+func UniqueStringArr(m []string) []string {
+ d := make([]string, 0)
+ tempMap := make(map[string]bool, len(m))
+ for _, v := range m { // 以值作为键名
+ if tempMap[v] == false {
+ tempMap[v] = true
+ d = append(d, v)
+ }
+ }
+ return d
+}
+
+// 合并整型数组
+func MergeArr(a, b []int) []int {
+ var arr []int
+ for _, i := range a {
+ arr = append(arr, i)
+ }
+ for _, j := range b {
+ arr = append(arr, j)
+ }
+ return arr
+}
+
+// 数组去重
+func UniqueArr(m []int) []int {
+ d := make([]int, 0)
+ tempMap := make(map[int]bool, len(m))
+ for _, v := range m { // 以值作为键名
+ if tempMap[v] == false {
+ tempMap[v] = true
+ d = append(d, v)
+ }
+ }
+ return d
+}
+
+// 升序
+func AscArr(e []int) []int {
+ sort.Ints(e[:])
+ return e
+}
+
+// 降序
+func DescArr(e []int) []int {
+ sort.Sort(sort.Reverse(sort.IntSlice(e)))
+ return e
+}
+
+func MatchRmUID(p string, s string) bool {
+ match, _ := regexp.MatchString(p, s)
+ return match
+}
+
+type OrderedMap struct {
+ Order []string
+ Map map[string]interface{}
+}
+
+func (om *OrderedMap) UnmarshalJson(b []byte) error {
+ json.Unmarshal(b, &om.Map)
+
+ index := make(map[string]int)
+ for key := range om.Map {
+ om.Order = append(om.Order, key)
+ esc, _ := json.Marshal(key) //Escape the key
+ index[key] = bytes.Index(b, esc)
+ }
+
+ sort.Slice(om.Order, func(i, j int) bool { return index[om.Order[i]] < index[om.Order[j]] })
+ return nil
+}
+
+func (om OrderedMap) MarshalJson() ([]byte, error) {
+ var b []byte
+ buf := bytes.NewBuffer(b)
+ buf.WriteRune('{')
+ l := len(om.Order)
+ for i, key := range om.Order {
+ km, err := json.Marshal(key)
+ if err != nil {
+ return nil, err
+ }
+ buf.Write(km)
+ buf.WriteRune(':')
+ vm, err := json.Marshal(om.Map[key])
+ if err != nil {
+ return nil, err
+ }
+ buf.Write(vm)
+ if i != l-1 {
+ buf.WriteRune(',')
+ }
+ fmt.Println(buf.String())
+ }
+ buf.WriteRune('}')
+ fmt.Println(buf.String())
+ return buf.Bytes(), nil
+}
+
+func GetBodyCopy(r *http.Request) (*bytes.Buffer, error) {
+ // If r.bodyBuf present, return the copy
+ // if r.bodyBuf != nil {
+ // return bytes.NewBuffer(r.bodyBuf.Bytes()), nil
+ // }
+
+ // Maybe body is `io.Reader`.
+ // Note: Resty user have to watchout for large body size of `io.Reader`
+ if r.Body != nil {
+ b, err := io.ReadAll(r.Body)
+ if err != nil {
+ return nil, err
+ }
+
+ // Restore the Body
+ // close(r.Body)
+ r.Body = io.NopCloser(bytes.NewReader(b))
+
+ // Return the Body bytes
+ return bytes.NewBuffer(b), nil
+ }
+ return nil, nil
+}
+
+func UnmarshalBody(r *http.Request, v *interface{}, maxLen int64) error {
+ body, err := io.ReadAll(io.LimitReader(r.Body, maxLen))
+ if err != nil {
+ return err
+ }
+
+ return json.Unmarshal(body, v)
+}
+
+func SetNotifyUrl(ip string, port uint16, uri string) string {
+ return fmt.Sprintf("http://%s:%d%s", ip, port, uri)
+}
+
+func GetIps() (ips []string, err error) {
+ interfaceAddr, err := net.InterfaceAddrs()
+ if err != nil {
+ return ips, err
+ }
+
+ for _, address := range interfaceAddr {
+ ipNet, isVailIpNet := address.(*net.IPNet)
+ // 检查ip地址判断是否回环地址
+ if isVailIpNet && !ipNet.IP.IsLoopback() {
+ if ipNet.IP.To4() != nil {
+ ips = append(ips, ipNet.IP.String())
+ }
+ }
+ }
+ return ips, nil
+}
+
+func GetCurrentTimeSliceIndexByPeriod(t time.Time, period int) int {
+ index := int((t.Hour()*60+t.Minute())/period) - 1
+ if index < 0 {
+ return int(24*60/period) - 1
+ }
+ return index
+}
+
+var (
+ cst *time.Location
+)
+
+// RFC3339ToDateTime convert rfc3339 value to china standard time layout
+func RFC3339ToDateTime(value string) (string, error) {
+ ts, err := time.Parse(time.RFC3339, value)
+ if err != nil {
+ return "", err
+ }
+
+ return ts.In(cst).Format("2006-01-02 15:04:05"), nil
+}
+
+// CreateTimeDir 根据当前时间格式来创建文件夹
+func CreateTimeDir(fmt string, path string) string {
+ folderName := time.Now().Format(fmt)
+ folderPath := filepath.Join(path, folderName)
+ if _, err := os.Stat(folderPath); os.IsNotExist(err) {
+ // 必须分成两步:先创建文件夹、再修改权限
+ os.Mkdir(folderPath, 0664) //0644也可以os.ModePerm
+ os.Chmod(folderPath, 0664)
+ }
+ return folderPath
+}
+
+// CreateDir 根据传入的目录名和路径来创建文件夹
+func CreateDir(folderName string, path string) string {
+ folderPath := filepath.Join(path, folderName)
+ if _, err := os.Stat(folderPath); os.IsNotExist(err) {
+ // 必须分成两步:先创建文件夹、再修改权限
+ os.Mkdir(folderPath, 0664) //0644也可以os.ModePerm
+ os.Chmod(folderPath, 0664)
+ }
+ return folderPath
+}
+
+func GetFmtTimeString(srcFmt string, timeString string, dstFmt string) string {
+ t, _ := time.ParseInLocation(srcFmt, timeString, time.Local)
+ return t.Format(dstFmt)
+}
+
+func GetFileMD5Sum(filePath string) (string, error) {
+ file, err := os.Open(filePath)
+ if err != nil {
+ return "", err
+ }
+ defer file.Close()
+ md5 := md5.New()
+ _, err = io.Copy(md5, file)
+ if err != nil {
+ return "", err
+ }
+
+ md5str := hex.EncodeToString(md5.Sum(nil))
+
+ return md5str, nil
+}
+
+// PathExists check path is exist or no
+func PathExists(path string) (bool, error) {
+ _, err := os.Stat(path)
+ if err == nil { //文件或者目录存在
+ return true, nil
+ }
+ if os.IsNotExist(err) {
+ return false, nil
+ }
+ return false, err
+}
+
+func GetDayDuration(d1, d2 string) int64 {
+ a, _ := time.Parse("2006-01-02", d1)
+ b, _ := time.Parse("2006-01-02", d2)
+ d := a.Sub(b)
+
+ return (int64)(d.Hours() / 24)
+}
+
+func GetSecondsSinceDatetime(datetimeStr string) (int64, error) {
+ loc1, _ := time.LoadLocation("Local")
+ // 解析日期时间字符串为时间对象
+ datetime, err := time.ParseInLocation(time.DateTime, datetimeStr, loc1)
+ if err != nil {
+ return 0, err
+ }
+
+ // 计算时间差
+ duration := time.Since(datetime)
+
+ // 获取时间差的秒数
+ seconds := int64(duration.Seconds())
+
+ return seconds, nil
+}
+
+// 0: invalid ip
+// 4: IPv4
+// 6: IPv6
+func ParseIP(s string) (net.IP, int) {
+ ip := net.ParseIP(s)
+ if ip == nil {
+ return nil, 0
+ }
+ for i := 0; i < len(s); i++ {
+ switch s[i] {
+ case '.':
+ return ip, 4
+ case ':':
+ return ip, 6
+ }
+ }
+ return nil, 0
+}
+
+func BytesCombine1(pBytes ...[]byte) []byte {
+ return bytes.Join(pBytes, []byte(""))
+}
+
+func BytesCombine(pBytes ...[]byte) []byte {
+ length := len(pBytes)
+ s := make([][]byte, length)
+ for index := 0; index < length; index++ {
+ s[index] = pBytes[index]
+ }
+ sep := []byte("")
+ return bytes.Join(s, sep)
+}
+
+func ParseIPAddr(ip string) string {
+ ipAddr := net.ParseIP(ip)
+
+ if ipAddr != nil {
+ if ipAddr.To4() != nil {
+ return IsIPv4
+ } else {
+ return IsIPv6
+ }
+ }
+
+ return NonIP
+}
+
+func CombineHostUri(ip string, port string) string {
+ var hostUri string = ""
+ ipType := ParseIPAddr(ip)
+ if ipType == IsIPv4 {
+ hostUri = fmt.Sprintf("http://%s:%v", ip, port)
+ } else {
+ hostUri = fmt.Sprintf("http://[%s]:%v", ip, port)
+ }
+
+ return hostUri
+}
+
+func StructToMap(obj interface{}) map[string]interface{} {
+ objValue := reflect.ValueOf(obj)
+ objType := objValue.Type()
+
+ m := make(map[string]interface{})
+
+ for i := 0; i < objValue.NumField(); i++ {
+ field := objValue.Field(i)
+ fieldName := objType.Field(i).Name
+
+ m[fieldName] = field.Interface()
+ }
+
+ return m
+}
+
+// ToMap 结构体转为Map[string]interface{}
+func ToMap(in interface{}, tagName string) (map[string]interface{}, error) {
+ out := make(map[string]interface{})
+
+ v := reflect.ValueOf(in)
+ if v.Kind() == reflect.Ptr {
+ v = v.Elem()
+ }
+
+ if v.Kind() != reflect.Struct { // 非结构体返回错误提示
+ return nil, fmt.Errorf("ToMap only accepts struct or struct pointer; got %T", v)
+ }
+
+ t := v.Type()
+ // 遍历结构体字段
+ // 指定tagName值为map中key;字段值为map中value
+ for i := 0; i < v.NumField(); i++ {
+ fi := t.Field(i)
+ if tagValue := fi.Tag.Get(tagName); tagValue != "" {
+ out[tagValue] = v.Field(i).Interface()
+ }
+ }
+ return out, nil
+}
diff --git a/lib/log/logger.go b/lib/log/logger.go
new file mode 100644
index 00000000..7a6bbe81
--- /dev/null
+++ b/lib/log/logger.go
@@ -0,0 +1,337 @@
+// logger for omc/ems
+
+package log
+
+import (
+ "fmt"
+ "io"
+ "log"
+)
+
+// LogLevel defines a log level
+type LogLevel int
+
+// enum all LogLevels
+const (
+ // following level also match syslog.Priority value
+ LOG_TRACE LogLevel = iota
+ LOG_DEBUG
+ LOG_INFO
+ LOG_WARN
+ LOG_ERROR
+ LOG_FATAL
+ LOG_OFF
+ LOG_NODEF
+)
+
+// default log options
+const (
+ DEFAULT_LOG_PREFIX = "omc"
+ DEFAULT_LOG_FLAG = log.Lshortfile | log.Ldate | log.Lmicroseconds
+ DEFAULT_LOG_LEVEL = LOG_DEBUG
+ DEFAULT_CALL_DEPTH = 3
+)
+
+// Logger is a logger interface
+type Logger interface {
+ Fatal(v ...interface{})
+ Fatalf(format string, v ...interface{})
+ Error(v ...interface{})
+ Errorf(format string, v ...interface{})
+ Warn(v ...interface{})
+ Warnf(format string, v ...interface{})
+ Info(v ...interface{})
+ Infof(format string, v ...interface{})
+ Debug(v ...interface{})
+ Debugf(format string, v ...interface{})
+ Trace(v ...interface{})
+ Tracef(format string, v ...interface{})
+
+ Level() LogLevel
+ LevelString() string
+ SetLevel(l LogLevel)
+}
+
+var _ Logger = DiscardLogger{}
+
+// DiscardLogger don't log implementation for ILogger
+type DiscardLogger struct{}
+
+// Trace empty implementation
+func (DiscardLogger) Trace(v ...interface{}) {}
+
+// Tracef empty implementation
+func (DiscardLogger) Tracef(format string, v ...interface{}) {}
+
+// Debug empty implementation
+func (DiscardLogger) Debug(v ...interface{}) {}
+
+// Debugf empty implementation
+func (DiscardLogger) Debugf(format string, v ...interface{}) {}
+
+// Info empty implementation
+func (DiscardLogger) Info(v ...interface{}) {}
+
+// Infof empty implementation
+func (DiscardLogger) Infof(format string, v ...interface{}) {}
+
+// Warn empty implementation
+func (DiscardLogger) Warn(v ...interface{}) {}
+
+// Warnf empty implementation
+func (DiscardLogger) Warnf(format string, v ...interface{}) {}
+
+// Error empty implementation
+func (DiscardLogger) Error(v ...interface{}) {}
+
+// Errorf empty implementation
+func (DiscardLogger) Errorf(format string, v ...interface{}) {}
+
+// Fatal empty implementation
+func (DiscardLogger) Fatal(v ...interface{}) {}
+
+// Fatalf empty implementation
+func (DiscardLogger) Fatalf(format string, v ...interface{}) {}
+
+// Level empty implementation
+func (DiscardLogger) Level() LogLevel {
+ return LOG_NODEF
+}
+
+// Level empty implementation
+func (DiscardLogger) LevelString() string {
+ return ""
+}
+
+// SetLevel empty implementation
+func (DiscardLogger) SetLevel(l LogLevel) {}
+
+// EmsLogger is the default implment of ILogger
+type EmsLogger struct {
+ TRACE *log.Logger
+ DEBUG *log.Logger
+ INFO *log.Logger
+ WARN *log.Logger
+ ERROR *log.Logger
+ FATAL *log.Logger
+ level LogLevel
+ levelString []string
+ depth int
+}
+
+var _ Logger = &EmsLogger{}
+
+// NewEmsLogger use a special io.Writer as logger output
+func NewEmsLogger(out io.Writer) *EmsLogger {
+ return NewEmsLogger2(out, DEFAULT_LOG_PREFIX, DEFAULT_LOG_FLAG)
+}
+
+// NewEmsLogger2 let you customrize your logger prefix and flag
+func NewEmsLogger2(out io.Writer, prefix string, flag int) *EmsLogger {
+ return NewEmsLogger3(out, prefix, flag, DEFAULT_LOG_LEVEL)
+}
+
+// NewEmsLogger3 let you customrize your logger prefix and flag and logLevel
+func NewEmsLogger3(out io.Writer, prefix string, flag int, l LogLevel) *EmsLogger {
+ return &EmsLogger{
+ TRACE: log.New(out, fmt.Sprintf("[%s] [trace] ", prefix), flag),
+ DEBUG: log.New(out, fmt.Sprintf("[%s] [debug] ", prefix), flag),
+ INFO: log.New(out, fmt.Sprintf("[%s] [info ] ", prefix), flag),
+ WARN: log.New(out, fmt.Sprintf("[%s] [warn ] ", prefix), flag),
+ ERROR: log.New(out, fmt.Sprintf("[%s] [error] ", prefix), flag),
+ FATAL: log.New(out, fmt.Sprintf("[%s] [fatal] ", prefix), flag),
+ level: l,
+ levelString: []string{"trace", "debug", "info", "warn", "error", "fatal"},
+ depth: DEFAULT_CALL_DEPTH,
+ }
+}
+
+// Trace implement ILogger
+func (s *EmsLogger) Trace(v ...interface{}) {
+ if s.level <= LOG_TRACE {
+ _ = s.TRACE.Output(s.depth, fmt.Sprintln(v...))
+ }
+}
+
+// Tracef implement ILogger
+func (s *EmsLogger) Tracef(format string, v ...interface{}) {
+ if s.level <= LOG_TRACE {
+ _ = s.TRACE.Output(s.depth, fmt.Sprintf(format, v...))
+ }
+}
+
+// Debug implement ILogger
+func (s *EmsLogger) Debug(v ...interface{}) {
+ if s.level <= LOG_DEBUG {
+ _ = s.DEBUG.Output(s.depth, fmt.Sprintln(v...))
+ }
+}
+
+// Debugf implement ILogger
+func (s *EmsLogger) Debugf(format string, v ...interface{}) {
+ if s.level <= LOG_DEBUG {
+ _ = s.DEBUG.Output(s.depth, fmt.Sprintf(format, v...))
+ }
+}
+
+// Info implement ILogger
+func (s *EmsLogger) Info(v ...interface{}) {
+ if s.level <= LOG_INFO {
+ _ = s.INFO.Output(s.depth, fmt.Sprintln(v...))
+ }
+}
+
+// Infof implement ILogger
+func (s *EmsLogger) Infof(format string, v ...interface{}) {
+ if s.level <= LOG_INFO {
+ _ = s.INFO.Output(s.depth, fmt.Sprintf(format, v...))
+ }
+}
+
+// Warn implement ILogger
+func (s *EmsLogger) Warn(v ...interface{}) {
+ if s.level <= LOG_WARN {
+ _ = s.WARN.Output(s.depth, fmt.Sprintln(v...))
+ }
+}
+
+// Warnf implement ILogger
+func (s *EmsLogger) Warnf(format string, v ...interface{}) {
+ if s.level <= LOG_WARN {
+ _ = s.WARN.Output(s.depth, fmt.Sprintf(format, v...))
+ }
+}
+
+// Error implement ILogger
+func (s *EmsLogger) Error(v ...interface{}) {
+ if s.level <= LOG_ERROR {
+ _ = s.ERROR.Output(s.depth, fmt.Sprintln(v...))
+ }
+}
+
+// Errorf implement ILogger
+func (s *EmsLogger) Errorf(format string, v ...interface{}) {
+ if s.level <= LOG_ERROR {
+ _ = s.ERROR.Output(s.depth, fmt.Sprintf(format, v...))
+ }
+}
+
+// Warn implement ILogger
+func (s *EmsLogger) Fatal(v ...interface{}) {
+ if s.level <= LOG_FATAL {
+ _ = s.FATAL.Output(s.depth, fmt.Sprintln(v...))
+ }
+}
+
+// Warnf implement ILogger
+func (s *EmsLogger) Fatalf(format string, v ...interface{}) {
+ if s.level <= LOG_FATAL {
+ _ = s.FATAL.Output(s.depth, fmt.Sprintf(format, v...))
+ }
+}
+
+// Level implement ILogger
+func (s *EmsLogger) Level() LogLevel {
+ return s.level
+}
+
+// Level implement ILogger
+func (s *EmsLogger) LevelString() string {
+ return s.levelString[s.level]
+}
+
+// SetLevel implement ILogger
+func (s *EmsLogger) SetLevel(l LogLevel) {
+ s.level = l
+}
+
+var Elogger Logger
+
+func InitLogger(logFile string, period int, count int, prefix string, logLevel LogLevel) {
+
+ /*
+ logFile, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0766)
+ if err != nil {
+ panic(err)
+ }
+ */
+
+ logWriter := getLogWriter(logFile, period, count)
+ Elogger = NewEmsLogger3(logWriter, prefix, DEFAULT_LOG_FLAG, logLevel)
+ fmt.Printf("logFile=%s, period=%d, count=%d, prefix=%s, logLevel=%s\n", logFile, period, count, prefix, GetLevelString())
+}
+
+// Trace implement ILogger
+func Trace(v ...interface{}) {
+ Elogger.Trace(v...)
+}
+
+// Tracef implement ILogger
+func Tracef(format string, v ...interface{}) {
+ Elogger.Tracef(format, v...)
+}
+
+// Debug implement ILogger
+func Debug(v ...interface{}) {
+ Elogger.Debug(v...)
+}
+
+// Debugf implement ILogger
+func Debugf(format string, v ...interface{}) {
+ Elogger.Debugf(format, v...)
+}
+
+// Info implement ILogger
+func Info(v ...interface{}) {
+ Elogger.Info(v...)
+}
+
+// Infof implement ILogger
+func Infof(format string, v ...interface{}) {
+ Elogger.Infof(format, v...)
+}
+
+// Warn implement ILogger
+func Warn(v ...interface{}) {
+ Elogger.Warn(v...)
+}
+
+// Warnf implement ILogger
+func Warnf(format string, v ...interface{}) {
+ Elogger.Warnf(format, v...)
+}
+
+// Error implement ILogger
+func Error(v ...interface{}) {
+ Elogger.Error(v...)
+}
+
+// Errorf implement ILogger
+func Errorf(format string, v ...interface{}) {
+ Elogger.Errorf(format, v...)
+}
+
+// Warn implement ILogger
+func Fatal(v ...interface{}) {
+ Elogger.Fatal(v...)
+}
+
+// Warnf implement ILogger
+func Fatalf(format string, v ...interface{}) {
+ Elogger.Fatalf(format, v...)
+}
+
+// Level implement ILogger
+func GetLevel() LogLevel {
+ return Elogger.Level()
+}
+
+// Level implement ILogger
+func GetLevelString() string {
+ return Elogger.LevelString()
+}
+
+// SetLevel implement ILogger
+func SetLevel(l LogLevel) {
+ Elogger.SetLevel(l)
+}
diff --git a/lib/log/partition.go b/lib/log/partition.go
new file mode 100644
index 00000000..5d32e583
--- /dev/null
+++ b/lib/log/partition.go
@@ -0,0 +1,71 @@
+package log
+
+import (
+ "io"
+ "time"
+
+ rotatelogs "github.com/lestrrat/go-file-rotatelogs"
+)
+
+type WriteSyncer interface {
+ io.Writer
+ Sync() error
+}
+
+// 得到LogWriter
+func getLogWriter(filePath string, period, count int) WriteSyncer {
+ warnIoWriter := getWriter(filePath, period, count)
+ return addSync(warnIoWriter)
+}
+
+// 日志文件切割
+func getWriter(filename string, period, count int) io.Writer {
+ // 保存日志count天,每period小时分割一次日志
+ duration := time.Hour * time.Duration(period)
+ var logfile string
+ if period >= 24 {
+ logfile = filename + "-%Y%m%d"
+ } else {
+ logfile = filename + "-%Y%m%d%H"
+ }
+ hook, err := rotatelogs.New(
+
+ logfile,
+ rotatelogs.WithLinkName(filename),
+ // rotatelogs.WithMaxAge(duration),
+ rotatelogs.WithRotationCount(count),
+ rotatelogs.WithRotationTime(duration),
+ rotatelogs.WithLocation(time.Local),
+ )
+
+ //保存日志30天,每1分钟分割一次日志
+ /*
+ hook, err := rotatelogs.New(
+ filename+"_%Y%m%d%H%M.log",
+ rotatelogs.WithLinkName(filename),
+ rotatelogs.WithMaxAge(time.Hour*24*30),
+ rotatelogs.WithRotationTime(time.Minute*1),
+ )
+ */
+ if err != nil {
+ panic(err)
+ }
+ return hook
+}
+
+func addSync(w io.Writer) WriteSyncer {
+ switch w := w.(type) {
+ case WriteSyncer:
+ return w
+ default:
+ return writerWrapper{w}
+ }
+}
+
+type writerWrapper struct {
+ io.Writer
+}
+
+func (w writerWrapper) Sync() error {
+ return nil
+}
diff --git a/lib/log/syslogger.go.bak b/lib/log/syslogger.go.bak
new file mode 100644
index 00000000..e5990202
--- /dev/null
+++ b/lib/log/syslogger.go.bak
@@ -0,0 +1,89 @@
+//go:build !windows && !nacl && !plan9
+// +build !windows,!nacl,!plan9
+
+package log
+
+import (
+ "fmt"
+ "log/syslog"
+)
+
+var _ Logger = &SyslogLogger{}
+
+// SyslogLogger will be depricated
+type SyslogLogger struct {
+ w *syslog.Writer
+}
+
+// NewSyslogLogger implements Logger
+func NewSyslogLogger(w *syslog.Writer) *SyslogLogger {
+ return &SyslogLogger{w: w}
+}
+
+// Trace log content as Trace
+func (s *SyslogLogger) Trace(v ...interface{}) {
+ _ = s.w.Trace(fmt.Sprint(v...))
+}
+
+// Tracef log content as Trace and format
+func (s *SyslogLogger) Tracef(format string, v ...interface{}) {
+ _ = s.w.Trace(fmt.Sprintf(format, v...))
+}
+
+// Debug log content as Debug
+func (s *SyslogLogger) Debug(v ...interface{}) {
+ _ = s.w.Debug(fmt.Sprint(v...))
+}
+
+// Debugf log content as Debug and format
+func (s *SyslogLogger) Debugf(format string, v ...interface{}) {
+ _ = s.w.Debug(fmt.Sprintf(format, v...))
+}
+
+// Error log content as Error
+func (s *SyslogLogger) Error(v ...interface{}) {
+ _ = s.w.Err(fmt.Sprint(v...))
+}
+
+// Errorf log content as Errorf and format
+func (s *SyslogLogger) Errorf(format string, v ...interface{}) {
+ _ = s.w.Err(fmt.Sprintf(format, v...))
+}
+
+// Info log content as Info
+func (s *SyslogLogger) Info(v ...interface{}) {
+ _ = s.w.Info(fmt.Sprint(v...))
+}
+
+// Infof log content as Infof and format
+func (s *SyslogLogger) Infof(format string, v ...interface{}) {
+ _ = s.w.Info(fmt.Sprintf(format, v...))
+}
+
+// Warn log content as Warn
+func (s *SyslogLogger) Warn(v ...interface{}) {
+ _ = s.w.Warn(fmt.Sprint(v...))
+}
+
+// Warnf log content as Warnf and format
+func (s *SyslogLogger) Warnf(format string, v ...interface{}) {
+ _ = s.w.Warn(fmt.Sprintf(format, v...))
+}
+
+// Fatal log content as Fatal
+func (s *SyslogLogger) Fatal(v ...interface{}) {
+ _ = s.w.Fatal(fmt.Sprint(v...))
+}
+
+// Fatalf log content as Fatalf and format
+func (s *SyslogLogger) Fatalf(format string, v ...interface{}) {
+ _ = s.w.Fatal(fmt.Sprintf(format, v...))
+}
+
+// Level shows log level
+func (s *SyslogLogger) Level() LogLevel {
+ return LOG_NODEF
+}
+
+// SetLevel always return error, as current log/syslog package doesn't allow to set priority level after syslog.Writer created
+func (s *SyslogLogger) SetLevel(l LogLevel) {}
diff --git a/lib/midware/midhandle.go b/lib/midware/midhandle.go
new file mode 100644
index 00000000..19f65627
--- /dev/null
+++ b/lib/midware/midhandle.go
@@ -0,0 +1,30 @@
+package midware
+
+import (
+ "net/http"
+
+ "ems.agt/lib/log"
+)
+
+func LoggerTraceMiddleware(next http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ // Do stuff here
+ log.Trace("Http Trace Info:")
+ log.Trace(" From Host:", r.RemoteAddr)
+ log.Trace(" To Host:", r.Host)
+ log.Debug(" RequestUri:", r.RequestURI)
+ log.Trace(" Method:", r.Method)
+ log.Trace(" Proto:", r.Proto)
+ log.Trace(" ContentLength:", r.ContentLength)
+ log.Trace(" User-Agent:", r.Header.Get("User-Agent"))
+ log.Trace(" Content-Type:", r.Header.Get("Content-Type"))
+ log.Trace(" AccessToken:", r.Header.Get("AccessToken"))
+ log.Trace("Trace End=====")
+ //body, _ := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
+ // nop-close to ready r.Body !!!
+ //r.Body = ioutil.NopCloser(bytes.NewReader(body))
+ //log.Trace("Body:", string(body))
+ // Call the next handler, which can be another middleware in the chain, or the final handler.
+ next.ServeHTTP(w, r)
+ })
+}
diff --git a/lib/mmlp/parse.go b/lib/mmlp/parse.go
new file mode 100644
index 00000000..60c96959
--- /dev/null
+++ b/lib/mmlp/parse.go
@@ -0,0 +1,900 @@
+package mmlp
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "math"
+ "net/http"
+ "regexp"
+ "strconv"
+ "strings"
+
+ "ems.agt/lib/dborm"
+ "ems.agt/lib/global"
+ "ems.agt/lib/log"
+ "github.com/go-resty/resty/v2"
+)
+
+type Param struct {
+ Name string `json:"name"`
+ Value string `json:"value"`
+}
+
+type MmlCommand struct {
+ Operation string `json:"operation"`
+ Object string `json:"object"`
+ Params []Param `json:"params"`
+ PaList []string `json:"paList"`
+ AaList []string `json:"aaList"`
+ AaMap map[string]interface{} `json:"aaMap"`
+ NaMap map[string]interface{} `json:"naMap"`
+ AaUri []string `json:"aaUri"`
+ AaLoc []string `json:"aaLoc"` // for loc parameter
+}
+
+type MmlVar struct {
+ Version string `json:"version"`
+ Output string `json:"output"`
+ Limit int `json:"limit"`
+ User string `json:"user"`
+ SessionToken string `josn:"sessionToken"`
+ HttpUri string `json:"httpUri"`
+ UserAgent string `json:"userAgent"`
+}
+
+// func init() {
+// OmcMmlVar = &MmlVar{
+// Version: "16.1.1",
+// Output: DefaultFormatType,
+// Limit: 50,
+// }
+// }
+
+// func SetOmcMmlVarOutput(output string) {
+// OmcMmlVar.Output = output
+// }
+
+// func SetOmcMmlVarLimit(limit int) {
+// OmcMmlVar.Limit = limit
+// }
+
+func splitByColon(str string) []string {
+ return splitBy(str, ':')
+}
+
+func splitByComma(str string) []string {
+ return splitBy(str, ',')
+}
+
+func splitBy(str string, sep rune) []string {
+ var result []string
+ var stack []string
+ var current []rune
+ var quotes, apoFlag bool = false, false
+
+ for _, c := range str {
+ if c == '{' || c == '[' || (c == '\'' && apoFlag == false) || (c == '"' && quotes == false) { // "'"
+ apoFlag = true
+ quotes = true
+ stack = append(stack, string(c))
+ } else if c == '}' || c == ']' || (c == '\'' && apoFlag == true) || (c == '"' && quotes == true) {
+ apoFlag = false
+ quotes = false
+ if len(stack) > 0 {
+ stack = stack[:len(stack)-1]
+ }
+ }
+
+ if c == sep && len(stack) == 0 {
+ result = append(result, string(current))
+ current = []rune{}
+ } else {
+ current = append(current, c)
+ }
+ }
+
+ result = append(result, string(current))
+ return result
+}
+
+func ParseMMLCommand(mmlStr string, mmlComms *[]MmlCommand) error {
+ log.Info("ParseMMLCommand processing ...")
+ log.Debug("mmlStr: ", mmlStr)
+
+ mc := new(MmlCommand)
+ reg := regexp.MustCompile(`\s*;\s*`)
+ mmls := reg.Split(mmlStr, -1)
+ for _, mml := range mmls {
+ log.Trace("mml:", mml)
+ if len(mml) == 0 {
+ continue
+ }
+ //reg := regexp.MustCompile(`\s*:\s*`)
+ //ms := reg.Split(mml, -1)
+ ms := splitByColon(mml)
+ if len(ms) < 1 || len(ms) > 2 {
+ err := global.ErrMmlInvalidCommandFormat
+ log.Error(err)
+ return err
+ }
+ if len(ms) == 2 {
+ cmd := strings.Trim(ms[0], " ")
+ reg = regexp.MustCompile(`\s+`)
+ cs := reg.Split(cmd, -1)
+ //cs := strings.Split(cmd, " ")
+ if len(cs) == 2 {
+ mc.Operation = cs[0]
+ mc.Object = cs[1]
+ } else {
+ err := global.ErrMmlInvalidCommandFormat
+ log.Error(err)
+ return err
+ }
+ //reg = regexp.MustCompile(`\s*,\s*`)
+ //reg = regexp.MustCompile(`(?U)(? 0 {
+ extUri := strings.Join(mml.AaUri, "/")
+ requestURI = requestURI + fmt.Sprintf(mmlMap.ExtUri, extUri)
+ }
+ if mmlMap.Params != "" {
+ params := strings.Join(mml.AaLoc, "+and+")
+ params = strings.ReplaceAll(params, " ", "+") // replace " " to "+"
+ log.Trace("params:", params)
+ if mmlMap.ParamTag == "SQL" && strings.TrimSpace(params) != "" {
+ params = "+where+" + params
+ }
+ requestURI = fmt.Sprintf("%s%s%s", requestURI, mmlMap.Params, params)
+ }
+ return requestURI
+}
+
+func TransMml2HttpReq(omcMmlVar *MmlVar, mml *MmlCommand) (*[]byte, error) {
+ log.Info("TransMml2HttpReq processing ...")
+ log.Debug("mml: ", mml)
+
+ where := fmt.Sprintf("operation='%s' AND object='%s'", mml.Operation, mml.Object)
+ mmlMap, err := dborm.XormGetMmlHttpMap("mml_http_map", where)
+ if err != nil {
+ log.Error("Failed to XormGetMmlHttpMap: ", err)
+ return ParseErrorOutput(err), err
+ }
+ if mmlMap == nil {
+ err := errors.New("Not found mml map")
+ log.Error(err)
+ return ParseErrorOutput(err), err
+ }
+ log.Trace("mmlMap: ", mmlMap)
+ if mmlMap.Output == "" {
+ mmlMap.Output = "{}"
+ }
+ outputJson := new(dborm.MmlOutput)
+ err = json.Unmarshal([]byte(mmlMap.Output), outputJson)
+ if err != nil {
+ log.Error("Failed to Unmarshal:", err)
+ return ParseErrorOutput(err), err
+ }
+ log.Trace("outputJson: ", outputJson)
+ inputJson := new(dborm.MmlInput)
+ log.Trace("mmlMap.Input: ", mmlMap.Input)
+ if mmlMap.Input == "" {
+ mmlMap.Input = "{}"
+ }
+ err = json.Unmarshal([]byte(mmlMap.Input), inputJson)
+ if err != nil {
+ log.Error("Failed to Unmarshal:", err)
+ return ParseErrorOutput(err), err
+ }
+ log.Trace("inputJson: ", inputJson)
+
+ var requestURI string
+ var output *[]byte
+ client := resty.New()
+ switch strings.ToLower(mmlMap.Method) {
+ case "get":
+ requestURI = parseRequestUri(omcMmlVar.HttpUri, mmlMap, mml)
+ log.Debugf("method: Get requestURI: %s", requestURI)
+ response, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"accessToken": omcMmlVar.SessionToken}).
+ SetHeaders(map[string]string{"User-Agent": omcMmlVar.UserAgent}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ Get(requestURI)
+ if err != nil {
+ log.Error("Failed to Get:", err)
+ output = ParseErrorOutput(err)
+ } else {
+ output = ParseOutputResponse(omcMmlVar, outputJson, response)
+ }
+ case "post":
+ requestURI = parseRequestUri(omcMmlVar.HttpUri, mmlMap, mml)
+ body := ParseInputBody(inputJson, mml)
+ log.Debugf("method: Post requestURI: %s", requestURI)
+ response, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"accessToken": omcMmlVar.SessionToken}).
+ SetHeaders(map[string]string{"User-Agent": omcMmlVar.UserAgent}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ SetBody(*body).
+ Post(requestURI)
+ if err != nil {
+ log.Error("Failed to Post:", err)
+ output = ParseErrorOutput(err)
+ } else {
+ output = ParseOutputResponse(omcMmlVar, outputJson, response)
+ }
+ case "put":
+ requestURI = parseRequestUri(omcMmlVar.HttpUri, mmlMap, mml)
+ body := ParseInputBody(inputJson, mml)
+ log.Debugf("method: Put requestURI: %s", requestURI)
+ response, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"accessToken": omcMmlVar.SessionToken}).
+ SetHeaders(map[string]string{"User-Agent": omcMmlVar.UserAgent}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ SetBody(*body).
+ Put(requestURI)
+ if err != nil {
+ log.Error("Failed to Put:", err)
+ output = ParseErrorOutput(err)
+ } else {
+ output = ParseOutputResponse(omcMmlVar, outputJson, response)
+ }
+ case "delete":
+ requestURI = parseRequestUri(omcMmlVar.HttpUri, mmlMap, mml)
+ log.Debugf("method: Delete requestURI: %s", requestURI)
+ response, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"accessToken": omcMmlVar.SessionToken}).
+ SetHeaders(map[string]string{"User-Agent": omcMmlVar.UserAgent}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ Delete(requestURI)
+ if err != nil {
+ log.Error("Failed to Delete:", err)
+ output = ParseErrorOutput(err)
+ } else {
+ output = ParseOutputResponse(omcMmlVar, outputJson, response)
+ }
+ case "patch":
+ requestURI = parseRequestUri(omcMmlVar.HttpUri, mmlMap, mml)
+ log.Debugf("method: patch requestURI: %s", requestURI)
+ response, err := client.R().
+ EnableTrace().
+ SetHeaders(map[string]string{"accessToken": omcMmlVar.SessionToken}).
+ SetHeaders(map[string]string{"User-Agent": omcMmlVar.UserAgent}).
+ SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
+ Patch(requestURI)
+ if err != nil {
+ log.Error("Failed to Patch:", err)
+ output = ParseErrorOutput(err)
+ } else {
+ output = ParseOutputResponse(omcMmlVar, outputJson, response)
+ }
+ default:
+ err := errors.New("not found mml command")
+ log.Error(err)
+ output = ParseErrorOutput(err)
+ }
+ return output, nil
+}
+
+const (
+ MaxMmlOutputBufferSize = 1000000
+ FormatTypeJson = "json"
+ FormatTypeTable = "table"
+ DefaultFormatType = FormatTypeTable
+)
+
+const (
+ RetCodeSucceeded = 0
+ RetCodeFailed = 0
+)
+
+func ParseInputBody(inputJson *dborm.MmlInput, mml *MmlCommand) *[]byte {
+ inputBody := make(map[string]interface{})
+ log.Trace("mml.NaMap:", mml.NaMap)
+ log.Trace("mml.AaMap:", mml.AaMap)
+ if strings.ToLower(inputJson.BodyFmt) == "putdb" {
+ for _, icol := range inputJson.Cols {
+ log.Trace("icol:", icol)
+ mml.NaMap[icol.Name] = icol.Value
+ }
+ inputBody[inputJson.BodyKey] = mml.NaMap
+ } else {
+ inputParams := make([]map[string]interface{}, 0)
+ inputParams = append(inputParams, mml.NaMap)
+ inputBody[inputJson.BodyKey] = inputParams
+ }
+
+ body, err := json.Marshal(inputBody)
+ if err != nil {
+ log.Error("Failed to marshal:", err)
+ }
+
+ log.Trace("inputBody:", inputBody)
+ log.Trace("body:", string(body))
+ return &body
+}
+
+func ParseOutputResponse(omcMmlVar *MmlVar, outputJson *dborm.MmlOutput, response *resty.Response) *[]byte {
+ var output []byte
+ var str bytes.Buffer
+
+ switch response.StatusCode() {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ if omcMmlVar.Output == FormatTypeJson {
+ code := fmt.Sprintf("StatusCode = %d status %s\n\n", response.StatusCode(), response.Status())
+ title := formatTitle(outputJson.Title)
+
+ json.Indent(&str, response.Body(), "", " ")
+ log.Trace(str.String())
+
+ output = global.BytesCombine1([]byte(code), []byte(title), str.Bytes(), []byte("\n"))
+ } else {
+ log.Trace("Body:", string(response.Body()))
+ mapDatas := make(map[string]interface{}, 0)
+
+ err := json.Unmarshal(response.Body(), &mapDatas)
+ if err != nil {
+ log.Error("Failed to json.Unmarshal:", err)
+ //output = *ParseErrorOutput(err)
+ output = *ParseErrorOutput(string(response.Body()))
+ return &output
+ }
+ log.Trace("mapDatas:", mapDatas)
+ switch strings.ToLower(outputJson.RetFmt) {
+ case "getdb":
+ if len(mapDatas) > 0 {
+ var data interface{}
+ for _, data = range mapDatas {
+ log.Trace("data:", data)
+ break
+ }
+ if len(data.([]interface{})) > 0 {
+ table := (data.([]interface{}))[0]
+ log.Trace("table:", table)
+
+ code := fmt.Sprintf(outputJson.RetMsg, RetCodeSucceeded)
+ title := formatTitle(outputJson.Title)
+ fmtResults := ParseTableOutput(outputJson, table)
+ output = global.BytesCombine1([]byte(code), []byte(title), []byte(fmtResults))
+ }
+ }
+ case "deletedb":
+ var data interface{}
+ for _, data = range mapDatas {
+ log.Trace("data:", data)
+ break
+ }
+
+ if len(data.(map[string]interface{})) > 0 {
+ table := data.(map[string]interface{})
+ code := fmt.Sprintf(outputJson.RetMsg, RetCodeSucceeded)
+ fmtResults := ParseDBOperOutput(outputJson, table)
+ output = global.BytesCombine1([]byte(code), []byte(fmtResults))
+ }
+ case "postdb":
+ var data interface{}
+ for _, data = range mapDatas {
+ log.Trace("data:", data)
+ break
+ }
+
+ if len(data.(map[string]interface{})) > 0 {
+ table := data.(map[string]interface{})
+ code := fmt.Sprintf(outputJson.RetMsg, RetCodeSucceeded)
+ fmtResults := ParseDBOperOutput(outputJson, table)
+ output = global.BytesCombine1([]byte(code), []byte(fmtResults))
+ }
+ case "putdb":
+ var data interface{}
+ for _, data = range mapDatas {
+ log.Trace("data:", data)
+ break
+ }
+ if len(data.(map[string]interface{})) > 0 {
+ table := data.(map[string]interface{})
+ code := fmt.Sprintf(outputJson.RetMsg, RetCodeSucceeded)
+ fmtResults := ParseDBOperOutput(outputJson, table)
+ output = global.BytesCombine1([]byte(code), []byte(fmtResults))
+ }
+ case "getnf":
+ if len(mapDatas) > 0 {
+ var data interface{}
+ for _, data = range mapDatas {
+ log.Trace("data:", data)
+ break
+ }
+ if len(data.([]interface{})) > 0 {
+ //table := (data.([]interface{}))[0]
+ //log.Trace("table:", table)
+
+ code := fmt.Sprintf(outputJson.RetMsg, RetCodeSucceeded)
+ title := formatTitle(outputJson.Title)
+ fmtResults := ParseNFTableOutput(outputJson, data)
+ output = global.BytesCombine1([]byte(code), []byte(title), []byte(fmtResults))
+ }
+ }
+ default:
+ code := fmt.Sprintf(outputJson.RetMsg, RetCodeSucceeded)
+ output = global.BytesCombine1([]byte(code))
+ }
+
+ }
+ default:
+ if omcMmlVar.Output == FormatTypeJson {
+ code := fmt.Sprintf("StatusCode = %d status %s\n\n", response.StatusCode(), response.Status())
+ //title := formatTitle("Network Element Information")
+
+ json.Indent(&str, response.Body(), "", " ")
+ log.Trace(str.String())
+
+ output = global.BytesCombine1([]byte(code), str.Bytes(), []byte("\n"))
+ } else {
+ log.Trace("Body:", string(response.Body()))
+ mapResults := make(map[string]interface{}, 0)
+
+ err := json.Unmarshal(response.Body(), &mapResults)
+ if err != nil {
+ log.Error("Failed to json.Unmarshal:", err)
+ output = *ParseErrorOutput(string(response.Body()))
+ } else {
+ log.Trace("mapResults:", mapResults)
+ errResult := mapResults["error"]
+ log.Trace("errResult:", errResult)
+ if len(errResult.(map[string]interface{})) > 0 {
+ errCode, _ := strconv.Atoi(fmt.Sprintf("%v", errResult.(map[string]interface{})["errorCode"]))
+ errorInfo := errResult.(map[string]interface{})["errorInfo"]
+ output = []byte(fmt.Sprintf(outputJson.ErrMsg, errCode, errorInfo))
+ }
+ }
+ }
+ }
+ return &output
+}
+
+func ParseDBOperOutput(outputJson *dborm.MmlOutput, cols any) string {
+ var colOutput []dborm.ColOutput = outputJson.Cols
+ var value, retFmtCols string
+ if len(cols.(map[string]interface{})) > 0 {
+ if len(colOutput) > 0 {
+ coln := colOutput[0].Name
+ value = fmt.Sprintf("%v", cols.(map[string]interface{})[coln])
+ log.Tracef("coln:%s value:%s", coln, value)
+ retFmtCols = colOutput[0].Display + " = " + value + "\n\n"
+ }
+ }
+
+ return retFmtCols
+}
+
+func ParseNFTableOutput(outputJson *dborm.MmlOutput, cols any) string {
+ var colOutput []dborm.ColOutput
+ var fmtColName string
+ var colName []string
+ var spaceNum int = 1
+ var alignmentM, alignmentSN, alignmentSV string = "Left", "Right", "Left"
+
+ if outputJson.SepSpaceNum != 0 {
+ spaceNum = outputJson.SepSpaceNum
+ }
+ if outputJson.AlignmentM != "" {
+ alignmentM = outputJson.AlignmentM
+ }
+ if outputJson.AlignmentSN != "" {
+ alignmentSN = outputJson.AlignmentSN
+ }
+ if outputJson.AlignmentSV != "" {
+ alignmentSV = outputJson.AlignmentSV
+ }
+
+ maxLength := math.MinInt64
+ for _, coln := range outputJson.Cols {
+ log.Trace("coln:", coln)
+
+ if len(coln.Display) > maxLength {
+ maxLength = len(coln.Display)
+ }
+ if coln.Length < len(coln.Display) {
+ coln.Length = len(coln.Display)
+ }
+
+ colName = append(colName, ParseAlignmentOutput(coln.Length, alignmentM, coln.Display))
+ colOutput = append(colOutput, coln)
+ }
+ fmtColName = formatLineBySpace(&colName, spaceNum)
+ log.Trace("fmtColName:", fmtColName)
+
+ var retFmtCols string
+ var fmtColValues []string
+ var numberResult int
+ // for _, colnvs := range cols.([]interface{}) {
+ // log.Trace("colnvs:", colnvs)
+ // if colnvs == nil {
+ // break
+ // }
+ numberResult = len(cols.([]interface{}))
+
+ if numberResult == 1 && outputJson.SingleList == true {
+ colnv := cols.([]interface{})[0]
+ log.Trace("colnv:", colnv)
+
+ var fmtNV []string
+ for _, coln := range colOutput {
+ fmtName := ParseAlignmentOutput(maxLength, alignmentSN, coln.Display)
+ log.Tracef("alignmentSN:%s fmtName:%s", alignmentSN, fmtName)
+ value := fmt.Sprintf("%v", colnv.(map[string]interface{})[coln.Name])
+ fmtValue := ParseAlignmentOutput(coln.Length, alignmentSV, value)
+ fmtNV = append(fmtNV, fmtName+": "+fmtValue)
+ }
+
+ fmtResults := strings.Join(fmtNV, "\n")
+ log.Tracef("fmtResults:\n%s", fmtResults)
+ fmtEnd := fmt.Sprintf(outputJson.End, numberResult)
+ retFmtCols = fmtResults + "\n\n" + fmtEnd
+ log.Tracef("retFmtCols:\n%s", retFmtCols)
+ return retFmtCols
+ } else {
+ for i := 0; i < numberResult; i++ {
+ colnv := cols.([]interface{})[i]
+ log.Trace("colnv:", colnv)
+ var colValues []string
+ var newVal []string
+ for _, coln := range colOutput {
+ value := fmt.Sprintf("%v", colnv.(map[string]interface{})[coln.Name])
+ if len(coln.Alias) != 0 {
+ enumVal, _ := strconv.Atoi(value)
+ value = parseEnumAlias(&(coln.Alias), enumVal)
+ }
+ newVal = append(newVal, ParseAlignmentOutput(coln.Length, alignmentM, value))
+ }
+ colValues = append(colValues, formatLineBySpace(&newVal, spaceNum))
+ log.Trace("colValues:", colValues)
+ fmtColValues = append(fmtColValues, strings.Join(colValues, "\n"))
+ log.Trace("fmtColValues:", fmtColValues)
+ }
+ fmtEnd := fmt.Sprintf(outputJson.End, numberResult)
+ retFmtCols = fmtColName + "\n\n" + strings.Join(fmtColValues, "\n") + "\n\n" + fmtEnd
+ log.Tracef("retFmtCols:\n%s", retFmtCols)
+ return retFmtCols
+ }
+}
+
+func ParseTableOutput(outputJson *dborm.MmlOutput, cols any) string {
+ var colOutput []dborm.ColOutput
+ var fmtColName string
+ var colName []string
+ var spaceNum int = 1
+ var alignmentM, alignmentSN, alignmentSV string = "Left", "Right", "Left"
+
+ if outputJson.SepSpaceNum != 0 {
+ spaceNum = outputJson.SepSpaceNum
+ }
+ if outputJson.AlignmentM != "" {
+ alignmentM = outputJson.AlignmentM
+ }
+ if outputJson.AlignmentSN != "" {
+ alignmentSN = outputJson.AlignmentSN
+ }
+ if outputJson.AlignmentSV != "" {
+ alignmentSV = outputJson.AlignmentSV
+ }
+
+ maxLength := math.MinInt64
+ for _, coln := range outputJson.Cols {
+ log.Trace("coln:", coln)
+
+ if len(coln.Display) > maxLength {
+ maxLength = len(coln.Display)
+ }
+ if coln.Length < len(coln.Display) {
+ coln.Length = len(coln.Display)
+ }
+
+ colName = append(colName, ParseAlignmentOutput(coln.Length, alignmentM, coln.Display))
+ colOutput = append(colOutput, coln)
+ }
+ fmtColName = formatLineBySpace(&colName, spaceNum)
+ log.Trace("fmtColName:", fmtColName)
+
+ var retFmtCols string
+ var fmtColValues []string
+ var numberResult int
+ for _, colnvs := range cols.(map[string]interface{}) {
+ log.Trace("colnvs:", colnvs)
+ if colnvs == nil {
+ break
+ }
+ numberResult = len(colnvs.([]interface{}))
+
+ if numberResult == 1 && outputJson.SingleList == true {
+ colnv := colnvs.([]interface{})[0]
+ log.Trace("colnv:", colnv)
+
+ var fmtNV []string
+ for _, coln := range colOutput {
+ fmtName := ParseAlignmentOutput(maxLength, alignmentSN, coln.Display)
+ log.Tracef("alignmentSN:%s fmtName:%s", alignmentSN, fmtName)
+ value := fmt.Sprintf("%v", colnv.(map[string]interface{})[coln.Name])
+ fmtValue := ParseAlignmentOutput(coln.Length, alignmentSV, value)
+ fmtNV = append(fmtNV, fmtName+": "+fmtValue)
+ }
+
+ fmtResults := strings.Join(fmtNV, "\n")
+ log.Tracef("fmtResults:\n%s", fmtResults)
+ fmtEnd := fmt.Sprintf(outputJson.End, numberResult)
+ retFmtCols = fmtResults + "\n\n" + fmtEnd
+ log.Tracef("retFmtCols:\n%s", retFmtCols)
+ return retFmtCols
+ } else {
+ for i := 0; i < numberResult; i++ {
+ colnv := colnvs.([]interface{})[i]
+ log.Trace("colnv:", colnv)
+ var colValues []string
+ var newVal []string
+ for _, coln := range colOutput {
+ value := fmt.Sprintf("%v", colnv.(map[string]interface{})[coln.Name])
+ if len(coln.Alias) != 0 {
+ enumVal, _ := strconv.Atoi(value)
+ value = parseEnumAlias(&(coln.Alias), enumVal)
+ }
+ newVal = append(newVal, ParseAlignmentOutput(coln.Length, alignmentM, value))
+ }
+ colValues = append(colValues, formatLineBySpace(&newVal, spaceNum))
+ log.Trace("colValues:", colValues)
+ fmtColValues = append(fmtColValues, strings.Join(colValues, "\n"))
+ log.Trace("fmtColValues:", fmtColValues)
+ }
+ fmtEnd := fmt.Sprintf(outputJson.End, numberResult)
+ retFmtCols = fmtColName + "\n\n" + strings.Join(fmtColValues, "\n") + "\n\n" + fmtEnd
+ log.Tracef("retFmtCols:\n%s", retFmtCols)
+ return retFmtCols
+ }
+ }
+ fmtEnd := fmt.Sprintf(outputJson.End, numberResult)
+ retFmtCols = fmtColName + "\n" + strings.Join(fmtColValues, "\n") + "\n\n" + fmtEnd
+ log.Tracef("retFmtCols:\n%s", retFmtCols)
+ return retFmtCols
+}
+
+func parseEnumAlias(alias *[]string, enumVal int) string {
+ return (*alias)[enumVal]
+}
+
+func formatLineBySpace(strArray *[]string, spaceNum int) string {
+ space := strings.Repeat(" ", spaceNum)
+ return strings.Join(*strArray, space)
+}
+
+func ParseAlignmentOutput(length int, alignment string, str string) string {
+ spaceLen := length - len(str)
+ if spaceLen < 0 {
+ log.Warnf("len(str=%s)=%d more length=%d", str, len(str), length)
+ spaceLen = 0
+ }
+ var retStr string
+ switch alignment {
+ case "Left":
+ suffix := strings.Repeat(" ", spaceLen)
+ retStr = str + suffix
+ case "Right":
+ prefix := strings.Repeat(" ", spaceLen)
+ retStr = prefix + str
+ log.Tracef("retStr:%s", retStr)
+ case "Middle":
+ prefix := strings.Repeat(" ", int(math.Ceil(float64(spaceLen)/2)))
+ suffix := strings.Repeat(" ", int(math.Floor(float64(spaceLen)/2)))
+ retStr = prefix + str + suffix
+ }
+ log.Tracef("length=%d, spaceLne=%d, alignment=%s, str=%s, retStr=%s", length, spaceLen, alignment, str, retStr)
+ return retStr
+}
+
+func ParseErrorOutput(err any) *[]byte {
+ var output []byte
+
+ var formatType string = DefaultFormatType
+ if formatType == FormatTypeJson {
+ output = []byte(fmt.Sprintf("ErrorCode = 1 Error message: %v\n\n", err))
+ } else {
+ output = []byte(fmt.Sprintf("RetCode = -1 operation failed: %v\n\n", err))
+ }
+
+ return &output
+}
+
+func formatTitle(title string) string {
+ var builder strings.Builder
+ builder.WriteString(title)
+ builder.WriteString("\n")
+ for i := 0; i < len(title); i++ {
+ builder.WriteString("-")
+ }
+ builder.WriteString("\n")
+ return builder.String()
+}
+
+func formatTableOutput() {
+
+}
diff --git a/lib/oauth/oauth.go b/lib/oauth/oauth.go
new file mode 100644
index 00000000..77829269
--- /dev/null
+++ b/lib/oauth/oauth.go
@@ -0,0 +1,179 @@
+package oauth
+
+import (
+ "crypto/sha256"
+ "crypto/sha512"
+ "encoding/hex"
+ "fmt"
+ "math/rand"
+ "net/http"
+ "strings"
+ "time"
+
+ "ems.agt/lib/log"
+
+ "github.com/dgrijalva/jwt-go"
+ "golang.org/x/crypto/bcrypt"
+)
+
+// GenToken 生成Token值
+func GenToken(mapClaims jwt.MapClaims) (string, error) {
+ token := jwt.NewWithClaims(jwt.SigningMethodHS256, mapClaims)
+ var nowDate = time.Now()
+ var secret = fmt.Sprintf("%v%v", nowDate, "xxxx")
+ return token.SignedString([]byte(secret))
+}
+
+// GenerateToken 生成Token值
+func GenerateToken(mapClaims jwt.MapClaims, key string) (string, error) {
+ token := jwt.NewWithClaims(jwt.SigningMethodHS256, mapClaims)
+ return token.SignedString([]byte(key))
+}
+
+// ParseToken: "解析token"
+func ParseToken(token string, secret string) (string, error) {
+ claim, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
+ return []byte(secret), nil
+ })
+ if err != nil {
+ return "", err
+ }
+ return claim.Claims.(jwt.MapClaims)["cmd"].(string), nil
+}
+
+func RandAccessToken(n int) (ret string) {
+ allString := "52661fbd-6b84-4fc2-aa1e-17879a5c6c9b"
+ ret = ""
+ for i := 0; i < n; i++ {
+ r := rand.Intn(len(allString))
+ ret = ret + allString[r:r+1]
+ }
+ return ret
+}
+
+const letterBytes = "abcdef0123456789"
+const (
+ letterIdxBits = 6 // 6 bits to represent a letter index
+ letterIdxMask = 1<= 0; {
+ if remain == 0 {
+ cache, remain = src.Int63(), letterIdxMax
+ }
+ if idx := int(cache & letterIdxMask); idx < len(letterBytes) {
+ b[i] = letterBytes[idx]
+ i--
+ }
+ cache >>= letterIdxBits
+ remain--
+ }
+
+ return string(b)
+}
+
+func GenRandToken() string {
+ return RandStringBytes(8) + "-" + RandStringBytes(4) + "-" +
+ RandStringBytes(4) + "-" + RandStringBytes(4) + "-" + RandStringBytes(12)
+}
+
+type OAuthBody struct {
+ GrantType string
+ UserName string
+ Value string
+}
+
+/*
+func IsValidOAuthInfo(oAuthBody OAuthBody) bool {
+ log.Debug("IsValidOAuthInfo processing... ")
+
+ conf := config.GetYamlConfig()
+ for _, o := range conf.Auth {
+ if oAuthBody.GrantType == o.Type && oAuthBody.UserName == o.User && oAuthBody.Value == o.Password {
+ return true
+ }
+ }
+
+ return false
+}
+*/
+
+func IsWrongOAuthInfo(oAuthBody OAuthBody) bool {
+ log.Debug("IsWrongOAuthInfo processing... ")
+
+ if oAuthBody.GrantType == "" || strings.ToLower(oAuthBody.GrantType) != "password" ||
+ oAuthBody.UserName == "" || oAuthBody.Value == "" {
+ return true
+ }
+
+ return false
+}
+
+func GetTokenFromHttpRequest(r *http.Request) string {
+ for k, v := range r.Header {
+ log.Tracef("k:%s, v:%s", k, v)
+ if strings.ToLower(k) == "accesstoken" && len(v) != 0 {
+ log.Trace("AccessToken:", v[0])
+ return v[0]
+ }
+ }
+
+ return ""
+}
+
+// IsCarriedToken check token is carried
+func IsCarriedToken(r *http.Request) (string, bool) {
+
+ token := GetTokenFromHttpRequest(r)
+ if token == "" {
+ return "", false
+ }
+ return token, true
+}
+
+// Bcrypt Encrypt 加密明文密码
+func BcryptEncrypt(password string) (string, error) {
+ hashedBytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
+ return string(hashedBytes), err
+}
+
+// Bcrypt Compare 密文校验
+func BcryptCompare(hashedPassword, password string) error {
+ return bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password))
+}
+
+// sha256 crypt
+func GetSHA256HashCode(stringMessage string) string {
+ message := []byte(stringMessage) //字符串转化字节数组
+ //创建一个基于SHA256算法的hash.Hash接口的对象
+ hash := sha256.New() //sha-256加密
+ //输入数据
+ hash.Write(message)
+ //计算哈希值
+ bytes := hash.Sum(nil)
+ //将字符串编码为16进制格式,返回字符串
+ hashCode := hex.EncodeToString(bytes)
+ //返回哈希值
+ return hashCode
+}
+
+// sha512 crypt
+func GetSHA512HashCode(stringMessage string) string {
+ message := []byte(stringMessage) //字符串转化字节数组
+ //创建一个基于SHA256算法的hash.Hash接口的对象
+ hash := sha512.New() //SHA-512加密
+ //输入数据
+ hash.Write(message)
+ //计算哈希值
+ bytes := hash.Sum(nil)
+ //将字符串编码为16进制格式,返回字符串
+ hashCode := hex.EncodeToString(bytes)
+ //返回哈希值
+ return hashCode
+}
diff --git a/lib/pair/pair.go b/lib/pair/pair.go
new file mode 100644
index 00000000..f779424f
--- /dev/null
+++ b/lib/pair/pair.go
@@ -0,0 +1,37 @@
+package pair
+
+type Pair struct {
+ Key int
+ Value int
+}
+
+type PairList []Pair
+
+type Interface interface {
+ // Len is the number of elements in the collection.
+ Len() int
+
+ // Less reports whether the element with index i
+ // must sort before the element with index j.
+ //
+ // If both Less(i, j) and Less(j, i) are false,
+ // then the elements at index i and j are considered equal.
+ // Sort may place equal elements in any order in the final result,
+ // while Stable preserves the original input order of equal elements.
+ //
+ // Less must describe a transitive ordering:
+ // - if both Less(i, j) and Less(j, k) are true, then Less(i, k) must be true as well.
+ // - if both Less(i, j) and Less(j, k) are false, then Less(i, k) must be false as well.
+ //
+ // Note that floating-point comparison (the < operator on float32 or float64 values)
+ // is not a transitive ordering when not-a-number (NaN) values are involved.
+ // See Float64Slice.Less for a correct implementation for floating-point values.
+ Less(i, j int) bool
+
+ // Swap swaps the elements with indexes i and j.
+ Swap(i, j int)
+}
+
+func (p PairList) Len() int { return len(p) }
+func (p PairList) Less(i, j int) bool { return p[i].Value < p[j].Value }
+func (p PairList) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
diff --git a/lib/routes/routes.go b/lib/routes/routes.go
new file mode 100644
index 00000000..c8378b5f
--- /dev/null
+++ b/lib/routes/routes.go
@@ -0,0 +1,252 @@
+package routes
+
+import (
+ "net/http"
+
+ // "log"
+
+ "ems.agt/features/aaaa"
+ "ems.agt/features/cm"
+ "ems.agt/features/dbrest"
+ "ems.agt/features/file"
+ "ems.agt/features/fm"
+ "ems.agt/features/maintenance"
+ "ems.agt/features/mml"
+ "ems.agt/features/nbi"
+ "ems.agt/features/pm"
+ "ems.agt/features/security"
+ "ems.agt/features/state"
+ "ems.agt/features/trace"
+ "ems.agt/lib/midware"
+ "ems.agt/lib/services"
+
+ "github.com/gorilla/mux"
+)
+
+type Router struct {
+ Method string
+ Pattern string
+ Handler http.HandlerFunc
+ Middleware mux.MiddlewareFunc
+}
+
+var routers []Router
+
+// var (
+// commonUriPattern = config.UriPrefix + "/{apiCategory}/{apiVersion}/elementType/{elementTypeValue}/objectType/{objectTypeValue}"
+
+// getUriPattern = config.UriPrefix + "/resourceManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/{objectTypeValue}"
+// getStatePattern = config.UriPrefix + "/systemManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/systemState"
+
+// // // database management rest pattern, discard
+// // XormGetDataUri = config.UriPrefix + "/databaseManagement/{apiVersion}/elementType/{databaseName}/objectType/{tableName}"
+// // XormSelectDataUri = config.UriPrefix + "/databaseManagement/{apiVersion}/select/{databaseName}/{tableName}"
+// // XormInsertDataUri = config.UriPrefix + "/databaseManagement/{apiVersion}/insert/{databaseName}/{tableName}"
+// // XormUpdateDataUri = config.UriPrefix + "/databaseManagement/{apiVersion}/update/{databaseName}/{tableName}"
+// // XormDeleteDataUri = config.UriPrefix + "/databaseManagement/{apiVersion}/delete/{databaseName}/{tableName}"
+
+// // XormCommonUri = config.UriPrefix + "/databaseManagement/{apiVersion}/{databaseName}/{tableName}"
+
+// // alarm management
+// postAlarmPattern = config.UriPrefix + "/faultManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/alarms"
+
+// // performance management
+// postPerformancePattern = config.UriPrefix + "/performanceManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/kpiReport/{index}"
+// measureTaskUri = config.UriPrefix + "/performanceManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/measureTask"
+// measureReportUri = config.UriPrefix + "/performanceManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/measureReport"
+
+// // parameter config management
+// paramConfigUri = config.UriPrefix + "/systemManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/config/{paraName}"
+
+// // NE info
+// UriNeInfo = config.UriPrefix + "/systemManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/neInfo"
+// )
+
+func init() {
+ Register("POST", security.UriOauthToken, security.LoginFromOMC, nil)
+ Register("POST", security.UriOauthHandshake, security.HandshakeFromOMC, nil)
+ Register("DELETE", security.UriOauthToken, security.LogoutFromOMC, nil)
+
+ Register("OPTIONS", security.UriOauthToken, OptionsProc, nil)
+ Register("OPTIONS", security.UriOauthHandshake, OptionsProc, nil)
+
+ // System state
+ Register("GET", state.UriSysState, state.GetStateFromNF, nil)
+ Register("OPTIONS", state.UriSysState, OptionsProc, nil)
+ Register("GET", state.UriSysState2, state.GetStateFromNF, nil)
+ Register("OPTIONS", state.UriSysState, OptionsProc, nil)
+ Register("OPTIONS", state.UriSysState2, OptionsProc, nil)
+
+ Register("GET", state.UriSysInfoAll, state.GetAllSysinfoFromNF, nil)
+ Register("GET", state.UriSysInfoOne, state.GetOneSysinfoFromNF, nil)
+ Register("OPTIONS", state.UriSysInfoAll, OptionsProc, nil)
+ Register("OPTIONS", state.UriSysInfoOne, OptionsProc, nil)
+
+ Register("GET", state.UriLicenseInfoAll, state.GetAllLicenseInfoFromNF, nil)
+ Register("GET", state.UriLicenseInfoOne, state.GetOneLicenseInfoFromNF, nil)
+ Register("OPTIONS", state.UriLicenseInfoAll, OptionsProc, nil)
+ Register("OPTIONS", state.UriLicenseInfoOne, OptionsProc, nil)
+
+ // database management
+ Register("GET", dbrest.XormGetDataUri, dbrest.DatabaseGetData, nil)
+ Register("GET", dbrest.XormSelectDataUri, dbrest.DatabaseGetData, nil)
+ Register("POST", dbrest.XormInsertDataUri, dbrest.DatabaseInsertData, nil)
+ Register("PUT", dbrest.XormUpdateDataUri, dbrest.DatabaseUpdateData, nil)
+ Register("DELETE", dbrest.XormDeleteDataUri, dbrest.DatabaseDeleteData, nil)
+ // corss orgin domain
+ Register("OPTIONS", dbrest.XormGetDataUri, OptionsProc, nil)
+ Register("OPTIONS", dbrest.XormSelectDataUri, OptionsProc, nil)
+ Register("OPTIONS", dbrest.XormInsertDataUri, OptionsProc, nil)
+ Register("OPTIONS", dbrest.XormUpdateDataUri, OptionsProc, nil)
+ Register("OPTIONS", dbrest.XormDeleteDataUri, OptionsProc, nil)
+
+ Register("GET", dbrest.XormCommonUri, dbrest.DatabaseGetData, nil)
+ Register("POST", dbrest.XormCommonUri, dbrest.DatabaseInsertData, nil)
+ Register("PUT", dbrest.XormCommonUri, dbrest.DatabaseUpdateData, nil)
+ Register("DELETE", dbrest.XormCommonUri, dbrest.DatabaseDeleteData, nil)
+
+ Register("GET", dbrest.XormExtDataUri, dbrest.ExtDatabaseGetData, nil)
+ Register("POST", dbrest.XormExtDataUri, dbrest.ExtDatabaseInsertData, nil)
+ Register("PUT", dbrest.XormExtDataUri, dbrest.ExtDatabaseUpdateData, nil)
+ Register("DELETE", dbrest.XormExtDataUri, dbrest.ExtDatabaseDeleteData, nil)
+
+ // corss orgin domain
+ Register("OPTIONS", dbrest.XormInsertDataUri, OptionsProc, nil)
+ Register("OPTIONS", dbrest.XormUpdateDataUri, OptionsProc, nil)
+ Register("OPTIONS", dbrest.XormDeleteDataUri, OptionsProc, nil)
+
+ Register("OPTIONS", dbrest.XormCommonUri, OptionsProc, nil)
+
+ // alarm restful Register
+ Register("POST", fm.UriAlarms, fm.PostAlarmFromNF, nil)
+ Register("Get", fm.UriAlarms, fm.GetAlarmFromNF, nil)
+
+ Register("OPTIONS", fm.UriAlarms, OptionsProc, nil)
+
+ // performance restful Register
+ Register("POST", pm.PostPerformancePattern, pm.PostKPIReportFromNF, nil)
+ Register("POST", pm.MeasureTaskUri, pm.PostMeasureTaskToNF, nil)
+ Register("PUT", pm.MeasureTaskUri, pm.PutMeasureTaskToNF, nil)
+ Register("DELETE", pm.MeasureTaskUri, pm.DeleteMeasureTaskToNF, nil)
+ Register("PATCH", pm.MeasureTaskUri, pm.PatchMeasureTaskToNF, nil)
+ Register("POST", pm.MeasureReportUri, pm.PostMeasureReportFromNF, nil)
+
+ Register("POST", pm.MeasurementUri, pm.PostMeasurementFromNF, nil)
+ Register("GET", pm.MeasurementUri, pm.GetMeasurementFromNF, nil)
+
+ Register("OPTIONS", pm.MeasureTaskUri, OptionsProc, nil)
+
+ // parameter config management
+ Register("GET", cm.ParamConfigUri, cm.GetParamConfigFromNF, nil)
+ Register("POST", cm.ParamConfigUri, cm.PostParamConfigToNF, nil)
+ Register("PUT", cm.ParamConfigUri, cm.PutParamConfigToNF, nil)
+ Register("DELETE", cm.ParamConfigUri, cm.DeleteParamConfigToNF, nil)
+
+ Register("OPTIONS", cm.ParamConfigUri, OptionsProc, nil)
+
+ // Get/Create/Modify/Delete NE info
+ Register("GET", cm.UriNeInfo, cm.GetNeInfo, nil)
+ Register("POST", cm.UriNeInfo, cm.PostNeInfo, nil)
+ Register("PUT", cm.UriNeInfo, cm.PutNeInfo, nil)
+ Register("DELETE", cm.UriNeInfo, cm.DeleteNeInfo, nil)
+ Register("OPTIONS", cm.UriNeInfo, OptionsProc, nil)
+
+ // Post MML command to NF
+ Register("POST", mml.UriMML, mml.PostMMLToNF, nil)
+ Register("OPTIONS", mml.UriMML, OptionsProc, nil)
+
+ Register("POST", mml.UriOmMmlExt, mml.PostMMLToOMC, nil)
+ Register("OPTIONS", mml.UriOmMmlExt, OptionsProc, nil)
+ // Northbound Get NRM
+ Register("GET", nbi.GetNRMUri, nbi.NBIGetNRMFromNF, nil)
+
+ // Import/Export NF CM
+ Register("GET", cm.NeCmUri, cm.ExportCmFromNF, nil)
+ Register("POST", cm.NeCmUri, cm.ImportCmToNF, nil)
+
+ Register("OPTIONS", cm.NeCmUri, OptionsProc, nil)
+
+ Register("GET", cm.UriNeCmFile, cm.DownloadNeBackupFile, nil)
+ Register("DELETE", cm.UriNeCmFile, cm.DeleteNeBackupFile, nil)
+
+ Register("OPTIONS", cm.UriNeCmFile, OptionsProc, nil)
+
+ // Software management
+ Register("GET", cm.UriSoftware, cm.DownloadSoftwareFile, nil)
+ Register("POST", cm.UriSoftware, cm.UploadSoftwareFile, nil)
+ Register("DELETE", cm.UriSoftware, cm.DeleteSoftwareFile, nil)
+
+ Register("OPTIONS", cm.UriSoftware, OptionsProc, nil)
+
+ Register("POST", cm.UriSoftwareNE, cm.DistributeSoftwareToNF, nil)
+ Register("PUT", cm.UriSoftwareNE, cm.ActiveSoftwareToNF, nil)
+ Register("PATCH", cm.UriSoftwareNE, cm.RollBackSoftwareToNF, nil)
+
+ Register("OPTIONS", cm.UriSoftwareNE, OptionsProc, nil)
+
+ // License management
+ Register("GET", cm.LicenseUri, cm.ExportCmFromNF, nil)
+ Register("POST", cm.LicenseUri, cm.ImportCmToNF, nil)
+ Register("DELETE", cm.LicenseUri, cm.ImportCmToNF, nil)
+
+ Register("OPTIONS", cm.LicenseUri, OptionsProc, nil)
+
+ Register("POST", cm.NeLicenseUri, cm.ExportCmFromNF, nil)
+ Register("PUT", cm.NeLicenseUri, cm.ImportCmToNF, nil)
+ Register("PATCH", cm.NeLicenseUri, cm.ImportCmToNF, nil)
+
+ Register("OPTIONS", cm.NeLicenseUri, OptionsProc, nil)
+
+ // Trace management
+ Register("POST", trace.UriTraceTask, trace.PostTraceTaskToNF, nil)
+ Register("PUT", trace.UriTraceTask, trace.PutTraceTaskToNF, nil)
+ Register("DELETE", trace.UriTraceTask, trace.DeleteTraceTaskToNF, nil)
+ Register("OPTIONS", trace.UriTraceTask, OptionsProc, nil)
+ // file management
+ Register("POST", file.UriFile, file.UploadFile, nil)
+ Register("GET", file.UriFile, file.DownloadFile, nil)
+ Register("DELETE", file.UriFile, file.DeleteFile, nil)
+ Register("OPTIONS", file.UriFile, OptionsProc, nil)
+
+ // AAAA
+ Register("GET", aaaa.UriAAAASSO, aaaa.GetSSOFromAAAA, nil)
+
+ // 系统维护
+ Register("GET", maintenance.Uri, maintenance.List, nil)
+ Register("GET", maintenance.UriPref, maintenance.Pref, nil)
+ Register("GET", maintenance.UriPrefLog, maintenance.PrefLog, nil)
+ Register("GET", maintenance.UriSqlClient, maintenance.SqlClient, nil)
+ Register("GET", maintenance.UriTop, maintenance.Top, nil)
+ Register("PATCH", maintenance.UriTop, maintenance.TopOps, nil)
+
+}
+
+// To resolv rest POST/PUT/DELETE/PATCH cross domain
+func OptionsProc(w http.ResponseWriter, r *http.Request) {
+ services.ResponseStatusOK200Null(w)
+}
+
+func NewRouter() *mux.Router {
+ r := mux.NewRouter()
+
+ // set custom handle for status 404/405
+ r.NotFoundHandler = services.CustomResponseNotFound404Handler()
+ r.MethodNotAllowedHandler = services.CustomResponseMethodNotAllowed405Handler()
+
+ r.Use(midware.LoggerTraceMiddleware)
+
+ for _, router := range routers {
+ r.Methods(router.Method).
+ Path(router.Pattern).
+ Handler(router.Handler)
+ if router.Middleware != nil {
+ r.Use(router.Middleware)
+ }
+ }
+
+ return r
+}
+
+func Register(method, pattern string, handler http.HandlerFunc, middleware mux.MiddlewareFunc) {
+ routers = append(routers, Router{method, pattern, handler, middleware})
+}
diff --git a/lib/services/file.go b/lib/services/file.go
new file mode 100644
index 00000000..d3163235
--- /dev/null
+++ b/lib/services/file.go
@@ -0,0 +1,356 @@
+package services
+
+import (
+ "bufio"
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "mime/multipart"
+ "net/http"
+ "os"
+ "strconv"
+ "strings"
+
+ "ems.agt/lib/log"
+)
+
+const (
+ RootPath = "uploads/"
+ ChunkRootPath = "uploads_tmp/"
+)
+
+var (
+ // FilesMax 限制上传文件的大小为7 MB
+ FilesMax int64 = 32 << 20
+ // ValuesMax 限制POST字段内容的大小
+ ValuesMax int64 = 512
+)
+
+func GetPostFile(w http.ResponseWriter, r *http.Request) {
+ //获取文件流,第三个返回值是错误对象
+ file, header, _ := r.FormFile("file")
+ //读取文件流为[]byte
+ b, err := ioutil.ReadAll(file)
+ if err != nil {
+ log.Error("Failed to ReadAll:", err)
+ ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ //把文件保存到指定位置
+ err = ioutil.WriteFile("./upload/test.zip", b, 0644)
+ if err != nil {
+ log.Error("Failed to WriteFile:", err)
+ ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ //输出上传时文件名
+ log.Debug("filename:", header.Filename)
+}
+
+func GetUploadFile(w http.ResponseWriter, r *http.Request) {
+ log.Debug("GetUploadFile processing...")
+
+ file, err := os.Create("./test.zip")
+ if err != nil {
+ log.Error("Failed to Create:", err)
+ ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ _, err = io.Copy(file, r.Body)
+ if err != nil {
+ log.Error("Failed to Copy:", err)
+ ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+}
+
+func GetUploadFormFile(w http.ResponseWriter, r *http.Request) {
+ // 设置最大的内存限制为32MB
+ r.ParseMultipartForm(32 << 20)
+ file, handler, err := r.FormFile("file")
+ if err != nil {
+ log.Error("Failed to FormFile:", err)
+ ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ defer file.Close()
+ log.Debug("Header:%v", handler.Header)
+ f, err := os.OpenFile("./"+handler.Filename, os.O_WRONLY|os.O_CREATE, 0666)
+ if err != nil {
+ log.Error("Failed to OpenFile:", err)
+ ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ defer f.Close()
+ _, err = io.Copy(f, file)
+ if err != nil {
+ log.Error("Failed to Copy:", err)
+ ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ log.Debug("File uploaded successfully:", handler.Filename)
+}
+
+func HandleUploadFile(r *http.Request, path, newFileName string) (string, error) {
+ var filePath, fileName string
+ reader, err := r.MultipartReader()
+ if err != nil {
+ log.Error("Failed to MultipartReader:", err)
+ return "", err
+ }
+
+ for {
+ part, err := reader.NextPart()
+ if err == io.EOF {
+ break
+ } else if err != nil {
+ log.Error("Failed to NextPart:", err)
+ return "", err
+ }
+
+ log.Debugf("FileName=[%s], FormName=[%s]", part.FileName(), part.FormName())
+ if part.FileName() == "" { // this is FormData
+ data, _ := ioutil.ReadAll(part)
+ log.Debugf("FormData=[%s]", string(data))
+ } else { // This is FileData
+
+ if newFileName != "" {
+ fileName = newFileName
+ } else {
+ fileName = part.FileName()
+ }
+
+ err := os.MkdirAll(path, os.ModePerm)
+ if err != nil {
+ log.Error("Failed to Mkdir:", err)
+ return "", err
+ }
+
+ filePath = path + "/" + fileName
+
+ file, err := os.Create(filePath)
+ if err != nil {
+ log.Error("Failed to Create:", err)
+ return "", err
+ }
+ defer file.Close()
+ _, err = io.Copy(file, part)
+ if err != nil {
+ log.Error("Failed to Copy:", err)
+ return "", err
+ }
+ }
+ }
+ return fileName, nil
+}
+
+func HandleUploadFormFile(w http.ResponseWriter, r *http.Request) {
+ r.ParseMultipartForm(32 << 20)
+ //mForm := r.MultipartForm
+
+ for k, _ := range r.MultipartForm.File {
+ // k is the key of file part
+ file, fileHeader, err := r.FormFile(k)
+ if err != nil {
+ fmt.Println("inovke FormFile error:", err)
+ return
+ }
+ defer file.Close()
+ fmt.Printf("the uploaded file: name[%s], size[%d], header[%#v]\n",
+ fileHeader.Filename, fileHeader.Size, fileHeader.Header)
+
+ // store uploaded file into local path
+ localFileName := "./upload/" + fileHeader.Filename
+ out, err := os.Create(localFileName)
+ if err != nil {
+ fmt.Printf("failed to open the file %s for writing", localFileName)
+ return
+ }
+ defer out.Close()
+ _, err = io.Copy(out, file)
+ if err != nil {
+ fmt.Printf("copy file err:%s\n", err)
+ return
+ }
+ fmt.Printf("file %s uploaded ok\n", fileHeader.Filename)
+ }
+}
+
+func PostFileHandler(w http.ResponseWriter, r *http.Request) {
+ fmt.Println("PostFileHandler processing... ")
+ if !strings.Contains(r.Header.Get("Content-Type"), "multipart/form-data") {
+ // 不支持的 Content-Type 类型
+ fmt.Println("Invalid Content-Type: ", r.Header.Get("Content-Type"))
+ http.Error(w, " 不支持的 Content-Type 类型", http.StatusBadRequest)
+ return
+ }
+
+ // 整个请求的主体大小设置为7.5Mb
+ r.Body = http.MaxBytesReader(w, r.Body, FilesMax+ValuesMax)
+ reader, err := r.MultipartReader()
+ if err != nil {
+ fmt.Println(err)
+ http.Error(w, err.Error(), http.StatusBadRequest)
+ return
+ }
+
+ for {
+ // A Part represents a single part in a multipart body.
+ part, err := reader.NextPart()
+ if err != nil {
+ if err == io.EOF {
+
+ break
+ }
+
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ fileName := part.FileName()
+ formName := part.FormName()
+ var buf = &bytes.Buffer{}
+ // 非文件字段部分大小限制验证(非文件字段,go中filename会是空)
+ if fileName == "" {
+ var limitError = "请求主体中非文件字段" + formName + "超出大小限制"
+ err = uploadSizeLimit(buf, part, ValuesMax, limitError)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusBadRequest)
+ return
+ }
+ continue
+ }
+
+ // 文件字段部分大小限制验证
+ var limitError = "请求主体中文件字段" + fileName + "超出大小限制"
+ err = uploadSizeLimit(buf, part, FilesMax, limitError)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusBadRequest)
+ return
+ }
+
+ // 文件创建部分
+ if err := uploadFileHandle(r.Header, fileName, buf); err != nil {
+ http.Error(w, err.Error(), http.StatusBadRequest)
+ return
+ }
+
+ // 非逻辑内容,仅为测试使用
+ var chunkNumber = r.Header.Get("chunk-number")
+ if chunkNumber == "" {
+ http.Error(w, "文件"+fileName+"上传成功", http.StatusOK)
+ } else {
+ http.Error(w, "分片文件"+fileName+chunkNumber+"上传成功", http.StatusOK)
+ }
+ }
+ return
+
+ http.NotFound(w, r)
+}
+
+// 上传内容大小限制
+func uploadSizeLimit(buf *bytes.Buffer, part *multipart.Part, maxLimit int64, limitError string) error {
+ n, err := io.CopyN(buf, part, maxLimit+1)
+ if err != nil && err != io.EOF {
+ fmt.Println("PostFileHandler:", err)
+ return err
+ }
+ maxLimit -= n
+ if maxLimit < 0 {
+ return errors.New(limitError)
+ }
+ return nil
+}
+
+// uploadFileHandle handle upload file
+func uploadFileHandle(header http.Header, fileName string, buf *bytes.Buffer) error {
+ var chunkNumberStr = header.Get("chunk-number")
+ // 1.普通文件上传处理
+ if chunkNumberStr == "" {
+ //创建文件并写入文件内容
+ return createFile(RootPath+fileName, buf.Bytes())
+ }
+ // 2.分片文件上传处理
+ //2.1读取分片编号
+ chunkNumber, err := strconv.Atoi(chunkNumberStr)
+ if err != nil {
+ return err
+ }
+ //2.2创建分片文件并写入分片内容
+ if err := createFile(fmt.Sprintf(ChunkRootPath+fileName+"%d.chunk", chunkNumber), buf.Bytes()); err != nil {
+ return err
+ }
+ //2.3确认是否上传完毕
+ if header.Get("chunk-final") == "true" {
+ //2.4合并文件
+ if err := mergeChunkFiles(fileName); err != nil {
+ return err
+ }
+ //2.5删除分片
+ for i := 0; ; i++ {
+ chunFileName := fmt.Sprintf(ChunkRootPath+fileName+"%d.chunk", i)
+ err := os.Remove(chunFileName)
+ if err != nil {
+ if os.IsNotExist(err) {
+ break
+ }
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+// 创建文件并写入内容
+func createFile(fileName string, res []byte) error {
+ newFile, err := os.Create(fileName)
+ if err != nil {
+ return err
+ }
+ defer func() {
+ _ = newFile.Close()
+ }()
+ bufferedWriter := bufio.NewWriter(newFile)
+ _, err = bufferedWriter.Write(res)
+ if err != nil && err != io.EOF {
+ return err
+ }
+ return bufferedWriter.Flush()
+}
+
+// 合并分片文件
+func mergeChunkFiles(fileName string) error {
+ var (
+ n int64
+ err error
+ )
+ finalFile, err := os.Create(RootPath + fileName)
+ if err != nil {
+ return err
+ }
+ defer finalFile.Close()
+ // 将分片内容写入最终文件
+ for i := 0; ; i++ {
+ chunFile, err := os.Open(fmt.Sprintf(ChunkRootPath+fileName+"%d.chunk", i))
+ if err != nil {
+ if os.IsNotExist(err) {
+ break
+ }
+ return err
+ }
+ n, err = io.Copy(finalFile, chunFile)
+ if err != nil {
+ return err
+ }
+ err = chunFile.Close()
+ if err != nil {
+ return err
+ }
+ if n < 1 {
+ break
+ }
+ }
+ return nil
+}
diff --git a/lib/services/requset.go b/lib/services/requset.go
new file mode 100644
index 00000000..0fff11f0
--- /dev/null
+++ b/lib/services/requset.go
@@ -0,0 +1,45 @@
+package services
+
+import (
+ "encoding/json"
+ "io"
+ "net/http"
+ "strconv"
+
+ "ems.agt/lib/global"
+)
+
+// 读取json请求结构团体
+func JSONBody(r *http.Request, args any) error {
+ body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
+ if err != nil {
+ return err
+ }
+ err = json.Unmarshal(body, args)
+ return err
+}
+
+// Get 查詢分頁值
+func GetPageNumSize(r *http.Request) (int, int) {
+ pageNumStr := r.URL.Query().Get("pageNum")
+ num := 1
+ if v, err := strconv.Atoi(pageNumStr); err == nil && v > 0 {
+ if v >= 100 {
+ num = 100
+ } else {
+ num = v
+ }
+ }
+
+ pageSizeStr := r.URL.Query().Get("pageSize")
+ size := 0
+ if v, err := strconv.Atoi(pageSizeStr); err == nil && v > 0 {
+ if v >= 60 {
+ size = 60
+ } else {
+ size = v
+ }
+ }
+
+ return num, size
+}
diff --git a/lib/services/services.go b/lib/services/services.go
new file mode 100644
index 00000000..7708ecf0
--- /dev/null
+++ b/lib/services/services.go
@@ -0,0 +1,936 @@
+package services
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "mime/multipart"
+ "os"
+ "path/filepath"
+
+ // "log"
+ "net/http"
+ "strconv"
+ "strings"
+
+ "ems.agt/lib/dborm"
+ "ems.agt/lib/global"
+ "ems.agt/lib/log"
+ "ems.agt/lib/oauth"
+ "ems.agt/restagent/config"
+ "github.com/gorilla/mux"
+)
+
+type NameValue struct {
+ Name string
+ Value string
+}
+
+type NameOid struct {
+ Name string
+ Oid string
+}
+
+type DataResponse struct {
+ Data interface{} `json:"data"`
+}
+
+type NullResponse struct {
+ nil interface{}
+}
+
+type ErrorResponse struct {
+ Error interface{} `json:"error"`
+}
+
+type ErrorMessage struct {
+ ErrorCode string `json:"errorCode"`
+ ErrorInfo string `json:"errorInfo"`
+}
+
+type SucceedOAuthResponse struct {
+ AccessToken string `json:"accessToken"`
+ Expires string `json:"expires"`
+ // Enum: "0": 不需要修改密码, "1": "FirstLogin",首次登录, "2": PasswordAboutToExpire, 密码即将过期
+ ChangePasswordFlag int `json:"changePasswordFlag"`
+ GroupName string `json:"groupName"`
+}
+
+type ServiceResponse struct {
+}
+
+func GetUriParamString(r *http.Request, paramName string, sep string, brackets bool, apostr bool) string {
+ vars := r.URL.Query()
+ s, ok := vars[paramName]
+ if !ok {
+ log.Infof("Parameter Name is not exist, %s", paramName)
+ return ""
+ }
+ if apostr {
+ for i := 0; i < len(s); i++ {
+ s[i] = "'" + s[i] + "'"
+ }
+ }
+ pn := strings.Join(s, sep)
+ if brackets {
+ pn = fmt.Sprintf("(%s)", pn)
+ }
+
+ return pn
+}
+
+func GetUriWhereString(r *http.Request) string {
+ return GetUriParamString(r, "WHERE", " and ", false, false)
+}
+
+func GetUriLocString(r *http.Request) string {
+ return GetUriParamString(r, "loc", " and ", false, false)
+}
+
+func GetUriPageLimitString(r *http.Request) string {
+ vars := r.URL.Query()
+ p, ok := vars["PAGE"]
+ if !ok {
+ log.Info("page param is not exist")
+ return ""
+ }
+
+ l, ok := vars["LIMIT"]
+ if !ok {
+ log.Info("limit param is not exist")
+ return ""
+ }
+ li, _ := strconv.Atoi(l[0])
+ pi, _ := strconv.Atoi(p[0])
+ ls := fmt.Sprintf("limit %d, %d", li*(pi-1), li)
+
+ log.Debug("Limit array:", ls)
+ return ls
+}
+
+func ExtGetUriPageLimitString(r *http.Request) string {
+ vars := r.URL.Query()
+ p, ok := vars["page"]
+ if !ok {
+ log.Info("page param is not exist")
+ p = append(p, "1")
+ }
+
+ l, ok := vars["limit"]
+ if !ok {
+ log.Info("limit param is not exist")
+ l = append(l, strconv.Itoa(global.MaxLimitData))
+ }
+ limit, _ := strconv.Atoi(l[0])
+ if limit > global.MaxLimitData {
+ limit = global.MaxLimitData
+ }
+ page, _ := strconv.Atoi(p[0])
+ limitStr := fmt.Sprintf("limit %d, %d", limit*(page-1), limit)
+
+ log.Debug("limitStr:", limitStr)
+ return limitStr
+}
+
+func IsJsonContentType(r *http.Request) bool {
+ if strings.Contains(r.Header.Get("Content-Type"), "application/json") {
+ return true
+ }
+ return false
+}
+
+func IsValidOAuthUri(r *http.Request) bool {
+ vars := mux.Vars(r)
+ apiVer := vars["apiVersion"] // 获取Uri
+ if apiVer != "v1" {
+ return false
+ }
+
+ return true
+}
+
+func IsVallidContentType(r *http.Request, checkFlag bool) bool {
+ log.Debug("IsVallidContentType processing ...")
+ /*
+ ctype := r.Header["Content-Type"]
+ log.Debug("ctype:", ctype)
+ if len(ctype) != 0 && !strings.Contains(ctype[0], "application/json") {
+ return false
+ }
+ */
+ if strings.Contains(r.Header.Get("Content-Type"), "application/json") || checkFlag == false {
+ return true
+ }
+ return false
+}
+
+func CheckParameterName(r *http.Request) []string {
+ var errorParams []string
+ vars := r.URL.Query()
+ for k, v := range vars {
+ log.Debug("vars:", k, v)
+ if k != "rmUIDs" && k != "fields" {
+ errorParams = append(errorParams, k)
+ }
+ }
+
+ return errorParams
+}
+
+func GetRmUIDArr(r *http.Request) []string {
+ vars := r.URL.Query()
+ rmUIDs, ok := vars["rmUIDs"]
+ if !ok {
+ log.Info("rmUIDs is not exist")
+ return nil
+ }
+
+ var rmUIDValues []string
+ for _, r := range rmUIDs {
+ if r != "" {
+ rmUIDValues = global.MergeStringArr(rmUIDValues, strings.Split(r, `,`))
+ }
+ }
+
+ return rmUIDValues
+}
+
+func GetAttrNameArr(r *http.Request) []string {
+ vars := r.URL.Query()
+ fields, ok := vars["fields"]
+ if !ok {
+ log.Info("attributeNames does not exist")
+ return nil
+ }
+ var attrNames []string
+ for _, a := range fields {
+ if a != "" {
+ attrNames = global.MergeStringArr(attrNames, strings.Split(a, `,`))
+ }
+ }
+
+ return attrNames
+}
+
+func CheckValidRmUID(rmUIDs []string) []string {
+ log.Debug("CheckValidRmUID processing... ")
+
+ var invalidRmUIDs []string
+ for _, r := range rmUIDs {
+ if !global.MatchRmUID(config.GetRmUIDRegexpFromConfig(), r) {
+ invalidRmUIDs = append(invalidRmUIDs, r)
+ }
+ }
+
+ return invalidRmUIDs
+}
+
+func CheckLocalRmUID(rmUIDs []string) string {
+ log.Debug("GetLocalRmUID processing... ")
+
+ rmUID := config.GetRmUIDFromConfig()
+ for _, r := range rmUIDs {
+ if r == rmUID {
+ return rmUID
+ }
+ }
+
+ return ""
+}
+
+func GetParamsArrByName(paramName string, r *http.Request) []string {
+ vars := r.URL.Query()
+ pns, ok := vars[paramName]
+ if !ok {
+ log.Infof("%s is not exist", paramName)
+ return nil
+ }
+
+ var pnArr []string
+ for _, pn := range pns {
+ if pn != "" {
+ pnArr = global.MergeStringArr(pnArr, strings.Split(pn, `,`))
+ }
+ }
+
+ return pnArr
+}
+
+func GetOperationTypeFromHttpRequest(r *http.Request) string {
+ for k, v := range r.Header {
+ log.Tracef("k:%s, v:%s", k, v)
+ if strings.ToLower(k) == "operationtype" && len(v) != 0 {
+ log.Trace("OperationType:", v[0])
+ return v[0]
+ }
+ }
+
+ return ""
+}
+
+func CheckNorthboundValidRequest(w http.ResponseWriter, r *http.Request) (string, error) {
+ log.Debug("CheckNorthboundValidRequest processing... ")
+
+ var token string = ""
+ var err error
+ var ret bool
+ // response 414-4 uri too long ? (optional)
+ // todo ... ?
+ if bytes.Count([]byte(r.RequestURI), nil) > config.GetUriMaxLenFromConfig() {
+ log.Error("Request Uri too long:", bytes.Count([]byte(r.RequestURI), nil), config.GetUriMaxLenFromConfig())
+ ResponseRequestURITooLong414UriTooLong(w)
+ return token, err
+ }
+
+ // check media type(content type) only support "application/json"
+ // response 415-1
+ if !IsJsonContentType(r) {
+ log.Error("Invalid Content-Type")
+ ResponseUnsupportedMediaType415(w)
+ return token, err
+ }
+
+ // error processing ...
+ // 401-1 response
+ token, ret = oauth.IsCarriedToken(r)
+ if ret == false {
+ log.Error("AccessToken is not carried")
+ ResponseUnauthorized401AccessTokenNotCarried(w)
+ return token, err
+ }
+
+ // 401-2 response
+ if dborm.XormExistValidToken(token, config.GetExpiresFromConfig()) == false {
+ log.Error("AccessToken fails or does not exist")
+ ResponseUnauthorized401AccessTokenNotExist(w)
+ return token, err
+ }
+
+ if operType := GetOperationTypeFromHttpRequest(r); operType != "auto" {
+ _, err = dborm.XormUpdateSessionShakeTime(token)
+ if err != nil {
+ log.Error("Failed to update session table:", err)
+ ResponseUnauthorized401AccessTokenNotExist(w)
+ return token, err
+ }
+ }
+
+ vars := mux.Vars(r)
+ apiVer := vars["apiVersion"]
+ if apiVer != global.ApiVersionV1 {
+ log.Error("Uri is invalid")
+ ResponseNotFound404UriNotExist(w, r)
+ return token, err
+ }
+
+ // response 406-1
+ rmUIDValues := GetRmUIDArr(r)
+ if rmUIDValues == nil {
+ log.Error("missing parameter: rmUIDs")
+ ResponseNotAcceptable406MissingParam(w)
+ return token, err
+ }
+
+ // response 406-2
+ errorParams := CheckParameterName(r)
+ if errorParams != nil {
+ log.Error("parameter name error: ", errorParams)
+ ResponseNotAcceptable406ParamError(w, errorParams)
+ return token, err
+ }
+
+ // response 400-5
+ if len(rmUIDValues) == 0 {
+ log.Error("rmUIDs is wrong or NULL")
+ ResponseBadRequest400WrongParamValue(w)
+ return token, err
+ }
+
+ // response 414-1
+ if len(rmUIDValues) > config.GetYamlConfig().Params.RmUIDMaxNum {
+ log.Error("rmUID greater than", config.GetYamlConfig().Params.RmUIDMaxNum)
+ ResponseRequestURITooLong414NRMNumExceed(w, config.GetYamlConfig().Params.RmUIDMaxNum)
+ return token, err
+ }
+
+ return token, nil
+}
+
+func CheckCommonValidRequest(w http.ResponseWriter, r *http.Request) (string, error) {
+ log.Debug("CheckCommonValidRequest processing... ")
+
+ var token string = ""
+ var err error
+ var ret bool
+ // response 414-4 uri too long ? (optional)
+ // todo ... ?
+ if bytes.Count([]byte(r.RequestURI), nil) > config.GetUriMaxLenFromConfig() {
+ log.Error("Request Uri too long:", bytes.Count([]byte(r.RequestURI), nil), config.GetUriMaxLenFromConfig())
+ ResponseRequestURITooLong414UriTooLong(w)
+ return token, err
+ }
+
+ // check media type(content type) only support "application/json"
+ // response 415-1
+ if !IsJsonContentType(r) {
+ log.Error("Invalid Content-Type")
+ ResponseUnsupportedMediaType415(w)
+ return token, err
+ }
+
+ // error processing ...
+ // 401-1 response
+ token, ret = oauth.IsCarriedToken(r)
+ if ret == false {
+ log.Error("AccessToken is not carried")
+ ResponseUnauthorized401AccessTokenNotCarried(w)
+ return token, err
+ }
+
+ // 401-2 response
+ if dborm.XormExistValidToken(token, config.GetExpiresFromConfig()) == false {
+ log.Error("AccessToken fails or does not exist")
+ ResponseUnauthorized401AccessTokenNotExist(w)
+ return token, err
+ }
+
+ if operType := GetOperationTypeFromHttpRequest(r); operType != "auto" {
+ _, err = dborm.XormUpdateSessionShakeTime(token)
+ if err != nil {
+ log.Error("Failed to update session table:", err)
+ ResponseUnauthorized401AccessTokenNotExist(w)
+ return token, err
+ }
+ }
+
+ vars := mux.Vars(r)
+ apiVer := vars["apiVersion"]
+ if apiVer != global.ApiVersionV1 {
+ log.Error("Uri is invalid")
+ ResponseNotFound404UriNotExist(w, r)
+ return token, err
+ }
+
+ return token, nil
+}
+
+func IsLocalhost(host string) bool {
+ if strings.Contains(host, "127.0.0.1") || strings.Contains(host, "::1") {
+ return true
+ }
+ return false
+}
+
+func CheckFrontValidRequest(w http.ResponseWriter, r *http.Request) (string, error) {
+ log.Debug("CheckFrontValidRequest processing... ")
+
+ var token string = ""
+ var err error
+ var ret bool
+ // response 414-4 uri too long ? (optional)
+ // todo ... ?
+ if bytes.Count([]byte(r.RequestURI), nil) > config.GetUriMaxLenFromConfig() {
+ err = errors.New("Request Uri too long")
+ log.Errorf("Request Uri too long: bytes=%d, MaxLen=%d", bytes.Count([]byte(r.RequestURI), nil), config.GetUriMaxLenFromConfig())
+ ResponseRequestURITooLong414UriTooLong(w)
+ return token, err
+ }
+
+ /*
+ // check media type(content type) only support "application/json"
+ // response 415-1
+ if !IsVallidContentType(r) {
+ err := errors.New("Invalid Content-Type")
+ log.Error(err)
+ ResponseUnsupportedMediaType415(w)
+ return err
+ }
+ */
+
+ // error processing ...
+ // 401-1 response
+ if config.GetYamlConfig().Auth.Token && IsLocalhost(r.RemoteAddr) == false {
+ token, ret = oauth.IsCarriedToken(r)
+ if ret == false {
+ err = errors.New("AccessToken is not carried")
+ log.Error(err)
+ ResponseUnauthorized401AccessTokenNotCarried(w)
+ return token, err
+ }
+
+ // 401-2 response
+ if dborm.XormExistValidToken(token, config.GetExpiresFromConfig()) == false {
+ err = errors.New("AccessToken fails or does not exist")
+ log.Error(err)
+ ResponseUnauthorized401AccessTokenNotExist(w)
+ return token, err
+ }
+
+ if operType := GetOperationTypeFromHttpRequest(r); operType != "auto" {
+ _, err = dborm.XormUpdateSessionShakeTime(token)
+ if err != nil {
+ log.Error("Failed to update session table:", err)
+ ResponseUnauthorized401AccessTokenNotExist(w)
+ return token, err
+ }
+ }
+
+ }
+
+ /*
+ // response 403 Forbidden, permissions deny
+ // todo...
+ plist := globalSession.GetPermissionFromSession(token)
+ log.Debug("permission list:", plist)
+ if len(plist) == 0 || plist[0] == false {
+ log.Debug("User permission deny")
+ ResponseForbidden403NotPermission(w)
+ return
+ }
+ */
+ vars := mux.Vars(r)
+ apiVer := vars["apiVersion"]
+ if apiVer != global.ApiVersionV1 {
+ err = errors.New("Uri is invalid")
+ log.Error(err)
+ ResponseNotFound404UriNotExist(w, r)
+ return token, err
+ }
+
+ return token, nil
+}
+
+func CheckExtValidRequest(w http.ResponseWriter, r *http.Request) (string, error) {
+ log.Debug("CheckExtValidRequest processing... ")
+
+ var token string = ""
+ var err error
+ var ret bool
+ // error processing ...
+ // 401-1 response
+ if config.GetYamlConfig().Auth.Token {
+ token, ret = oauth.IsCarriedToken(r)
+ if ret == false {
+ err = errors.New("AccessToken is not carried")
+ log.Error(err)
+ ResponseUnauthorized401AccessTokenNotCarried(w)
+ return token, err
+ }
+
+ // 401-2 response
+ if dborm.XormExistValidToken(token, config.GetExpiresFromConfig()) == false {
+ err = errors.New("AccessToken fails or does not exist")
+ log.Error(err)
+ ResponseUnauthorized401AccessTokenNotExist(w)
+ return token, err
+ }
+
+ if operType := GetOperationTypeFromHttpRequest(r); operType != "auto" {
+ _, err = dborm.XormUpdateSessionShakeTime(token)
+ if err != nil {
+ log.Error("Failed to update session table:", err)
+ ResponseUnauthorized401AccessTokenNotExist(w)
+ return token, err
+ }
+ }
+ }
+
+ vars := mux.Vars(r)
+ apiVer := vars["apiVersion"]
+ if apiVer != global.ApiVersionV1 {
+ err = errors.New("Uri is invalid")
+ log.Error(err)
+ ResponseNotFound404UriNotExist(w, r)
+ return token, err
+ }
+
+ return token, nil
+}
+
+func ResponseStatusOK200Login(w http.ResponseWriter, token string, user *dborm.User) {
+ var oAuthResponse SucceedOAuthResponse
+ oAuthResponse.AccessToken = token
+ oAuthResponse.Expires = strconv.Itoa((int)(config.GetExpiresFromConfig()))
+ oAuthResponse.ChangePasswordFlag = user.ChangePasswordFlag
+ oAuthResponse.GroupName = user.GroupName
+ ResponseWithJson(w, http.StatusOK, oAuthResponse)
+}
+
+func ResponseStatusOK200Null(w http.ResponseWriter) {
+ response := NullResponse{""}
+ ResponseWithJson(w, http.StatusOK, response)
+}
+
+func ResponseStatusOK204NoContent(w http.ResponseWriter) {
+ ResponseWithJson(w, http.StatusNoContent, "")
+}
+
+func ResponseRedirect(w http.ResponseWriter, redirectUrl string) {
+ w.Header().Set("Cache-Control", "must-revalidate, no-store")
+ w.Header().Set("Content-Type", " text/html;charset=UTF-8")
+ w.Header().Set("Location", redirectUrl) //跳转地址设置
+ w.WriteHeader(http.StatusTemporaryRedirect) //重定向!
+}
+
+func ResponseBadRequest400RmUIDsIsInvalid(w http.ResponseWriter, rmUIDs []string) {
+ errorMessage := ErrorMessage{"1", "rmUIDs is invalid:" + strings.Join(rmUIDs, ",")}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusBadRequest, errorResponse)
+}
+
+func ResponseBadRequest400DuplicateSubId(w http.ResponseWriter, SubIds string) {
+ errorMessage := ErrorMessage{"2", "Duplicate with resource subscription id:" + SubIds}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusBadRequest, errorResponse)
+}
+
+func ResponseBadRequest400DuplicateAlarmId(w http.ResponseWriter, AlarmIds string) {
+ errorMessage := ErrorMessage{"3", "Duplicate with alarm subscription id: " + AlarmIds}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusBadRequest, errorResponse)
+}
+
+func ResponseBadRequest400IncorrectLogin(w http.ResponseWriter) {
+ errorMessage := ErrorMessage{"4", "Incorrect username and password"}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusBadRequest, errorResponse)
+}
+
+func ResponseBadRequest400WrongParamValue(w http.ResponseWriter) {
+ errorMessage := ErrorMessage{"5", "Wrong parameter value"}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusBadRequest, errorResponse)
+}
+
+func ResponseBadRequest400CMCALoginError(w http.ResponseWriter) {
+ errorMessage := ErrorMessage{"6", "CMCA centralized authentication login error"}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusBadRequest, errorResponse)
+}
+
+func ResponseBadRequest400InvalidJson(w http.ResponseWriter) {
+ errorMessage := ErrorMessage{"7", "Invalid json format"}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusUnauthorized, errorResponse)
+}
+
+func ResponseUnauthorized401AccessTokenNotCarried(w http.ResponseWriter) {
+ errorMessage := ErrorMessage{"1", "AccessToken is not carried"}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusUnauthorized, errorResponse)
+}
+
+func ResponseUnauthorized401AccessTokenNotExist(w http.ResponseWriter) {
+ errorMessage := ErrorMessage{"2", "AccessToken fails or does not exist"}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusUnauthorized, errorResponse)
+}
+
+func ResponseForbidden403NotPermission(w http.ResponseWriter) {
+ errorMessage := ErrorMessage{"1", "Do not have the operation permissions"}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusForbidden, errorResponse)
+}
+
+func ResponseForbidden403MultiLoginNotAllowed(w http.ResponseWriter) {
+ errorMessage := ErrorMessage{"2", "Multiple logins are not allowed"}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusForbidden, errorResponse)
+}
+
+func ResponseNotFound404UriNotExist(w http.ResponseWriter, r *http.Request) {
+ errorMessage := ErrorMessage{"1", "The requested URI does not exist"}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusNotFound, errorResponse)
+}
+
+func ResponseNotFound404UriNotExistExt(w http.ResponseWriter) {
+ errorMessage := ErrorMessage{"1", "The requested URI does not exist"}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusNotFound, errorResponse)
+}
+
+func CustomResponseNotFound404Handler() http.Handler {
+ return http.HandlerFunc(ResponseNotFound404UriNotExist)
+}
+
+func ResponseNotFound404NRMNotExist(w http.ResponseWriter, rmUIDs []string) {
+ errorMessage := ErrorMessage{"2", "rmUIDs does not exist: " + strings.Join(rmUIDs, ",")}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusNotFound, errorResponse)
+}
+
+func ResponseNotFound404PMNotExist(w http.ResponseWriter, rmUIDs []string) {
+ errorMessage := ErrorMessage{"3", "rmUIDs does not exist: " + strings.Join(rmUIDs, ",")}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusNotFound, errorResponse)
+}
+
+func ResponseNotFound404AlarmNotExist(w http.ResponseWriter, AlarmIds []string) {
+ errorMessage := ErrorMessage{"4", "AlarmIds does not exist: " + strings.Join(AlarmIds, ",")}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusNotFound, errorResponse)
+}
+
+func ResponseNotFound404GetSubscriptionNotExist(w http.ResponseWriter, SubIds []string) {
+ errorMessage := ErrorMessage{"5", "Subscription id does not exist: " + strings.Join(SubIds, ",")}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusNotFound, errorResponse)
+}
+
+func ResponseNotFound404DeleteSubscriptionNotExist(w http.ResponseWriter, SubIds []string) {
+ errorMessage := ErrorMessage{"6", "Subscription id does not exist: " + strings.Join(SubIds, ",")}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusNotFound, errorResponse)
+}
+
+func ResponseNotFound404GetAlarmSubscriptionNotExist(w http.ResponseWriter, SubIds []string) {
+ errorMessage := ErrorMessage{"7", "Subscription id does not exist: " + strings.Join(SubIds, ",")}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusNotFound, errorResponse)
+}
+
+func ResponseNotFound404DeleteAlarmSubscriptionNotExist(w http.ResponseWriter, SubIds []string) {
+ errorMessage := ErrorMessage{"8", "Subscription id does not exist: " + strings.Join(SubIds, ",")}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusNotFound, errorResponse)
+}
+
+func ResponseMethodNotAllowed405(w http.ResponseWriter, r *http.Request) {
+ errorMessage := ErrorMessage{"1", "Method not allowed"}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusMethodNotAllowed, errorResponse)
+}
+
+func CustomResponseMethodNotAllowed405Handler() http.Handler {
+ return http.HandlerFunc(ResponseMethodNotAllowed405)
+}
+
+func ResponseNotAcceptable406MissingParam(w http.ResponseWriter) {
+ errorMessage := ErrorMessage{"1", "Missing parameter: rmUIDs"}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusNotAcceptable, errorResponse)
+}
+
+func ResponseNotAcceptable406ParamError(w http.ResponseWriter, errorParamsName []string) {
+ errorMessage := ErrorMessage{"2", "Parameter name error: " + strings.Join(errorParamsName, ",")}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusNotAcceptable, errorResponse)
+}
+
+func ResponseNotAcceptable406QuerySQLError(w http.ResponseWriter) {
+ errorMessage := ErrorMessage{"3", "Wrong or non-query SQL statement"}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusNotAcceptable, errorResponse)
+}
+
+func ResponseRequestEntityTooLarge413SubscriptionExceed(w http.ResponseWriter, num int) {
+ errorMessage := ErrorMessage{"1", "The number of subscriptions greater than " + strconv.Itoa(num)}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusRequestEntityTooLarge, errorResponse)
+}
+
+func ResponseRequestEntityTooLarge413BodyToLarge(w http.ResponseWriter) {
+ errorMessage := ErrorMessage{"2", "The request entity too large"}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusRequestEntityTooLarge, errorResponse)
+}
+
+func ResponseRequestURITooLong414NRMNumExceed(w http.ResponseWriter, num int) {
+ errorMessage := ErrorMessage{"1", "The number of NRM rmUIDs greater than " + strconv.Itoa(num)}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusRequestURITooLong, errorResponse)
+}
+
+func ResponseRequestURITooLong414AlarmNumExceed(w http.ResponseWriter, num int) {
+ errorMessage := ErrorMessage{"2", "The number of alarmIds greater than " + strconv.Itoa(num)}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusRequestURITooLong, errorResponse)
+}
+
+func ResponseRequestURITooLong414PMNumExceed(w http.ResponseWriter, num int) {
+ errorMessage := ErrorMessage{"3", "The number of PM rmUIDs greater than " + strconv.Itoa(num)}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusRequestURITooLong, errorResponse)
+}
+
+func ResponseRequestURITooLong414UriTooLong(w http.ResponseWriter) {
+ errorMessage := ErrorMessage{"3", "Request URI too long"}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusRequestURITooLong, errorResponse)
+}
+
+func ResponseUnsupportedMediaType415(w http.ResponseWriter) {
+ errorMessage := ErrorMessage{"1", "Unsupported media type"}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusUnsupportedMediaType, errorResponse)
+}
+
+func ResponseInternalServerError500NFConnectRefused(w http.ResponseWriter) {
+ errorMessage := ErrorMessage{"1", "Internal server error, NF connnect refused"}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusInternalServerError, errorResponse)
+}
+
+func ResponseInternalServerError500DatabaseOperationFailed(w http.ResponseWriter) {
+ errorMessage := ErrorMessage{"2", "Internal server error, database opration failed"}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusInternalServerError, errorResponse)
+}
+
+func ResponseInternalServerError500ProcessError(w http.ResponseWriter, err error) {
+ em := fmt.Sprintf("Internal server error: %v", err)
+ errorMessage := ErrorMessage{"3", em}
+ errorResponse := ErrorResponse{errorMessage}
+ ResponseWithJson(w, http.StatusInternalServerError, errorResponse)
+}
+
+func ResponseWithJson(w http.ResponseWriter, code int, payload interface{}) {
+ log.Trace("payload: ", payload)
+
+ response, _ := json.Marshal(payload)
+ SetResponseHeader(w)
+ w.WriteHeader(code)
+ w.Write(response)
+ log.Trace("Response Code:", code)
+ log.Trace("Response Body:", string(response))
+}
+
+func ResponseWithZip(w http.ResponseWriter, payload interface{}) {
+ response, _ := json.Marshal(payload)
+ SetResponseHeader(w)
+ w.WriteHeader(http.StatusOK)
+ w.Write(response)
+ log.Trace("Response Body:", string(response))
+}
+
+func TransportResponse(w http.ResponseWriter, code int, payload []byte) {
+ var tempBody, transBody interface{}
+ switch code {
+ case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
+ json.Unmarshal(payload, &tempBody)
+ transBody = DataResponse{tempBody}
+ default:
+ json.Unmarshal(payload, &tempBody)
+ transBody = ErrorResponse{tempBody}
+ }
+ response, _ := json.Marshal(transBody)
+ log.Trace("transBody: ", transBody)
+ SetResponseHeader(w)
+ w.WriteHeader(code)
+ w.Write(response)
+ log.Trace("response: ", string(response))
+}
+
+func ResponseWithUnsortJson(w http.ResponseWriter, code int, payload map[string]interface{}) {
+ var om global.OrderedMap
+ om.Map = payload
+ response, _ := om.MarshalJson()
+ log.Trace("payload: ", payload)
+ SetResponseHeader(w)
+ w.WriteHeader(code)
+ w.Write(response)
+ log.Trace("response: ", string(response))
+}
+
+func ResponseErrorWithJson(w http.ResponseWriter, code int, nameValue interface{}) {
+ response := make(map[string]interface{})
+ response["error"] = nameValue
+ ResponseWithJson(w, code, response)
+}
+
+func SetCommonResponseHeader(w http.ResponseWriter) {
+ // To solve cross domain issue
+ w.Header().Set("Access-Control-Allow-Origin", "*")
+ // w.Header().Set("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS")
+ w.Header().Set("Access-Control-Allow-Methods", "*")
+ w.Header().Set("Access-Control-Allow-Headers", "*")
+ // w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
+ // w.Header().Set("Access-Control-Allow-Headers", "AccessToken")
+ w.Header().Set("Access-Control-Expose-Headers", "Access-Control-Allow-Headers, Token")
+ w.Header().Set("Access-Control-Allow-Credentials", "true")
+}
+
+func SetResponseHeader(w http.ResponseWriter) {
+ w.Header().Set("Content-Type", "application/json;charset=UTF-8")
+ SetCommonResponseHeader(w)
+}
+
+// Creates a new file upload http request with optional extra params
+func ResponseUploadFile(w http.ResponseWriter, code int, params map[string]string, paramName, path string) {
+ file, err := os.Open(path)
+ if err != nil {
+ log.Errorf("Failed to open: %v", err)
+ ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ defer file.Close()
+
+ body := &bytes.Buffer{}
+ writer := multipart.NewWriter(body)
+ part, err := writer.CreateFormFile(paramName, filepath.Base(path))
+ if err != nil {
+ log.Error("Failed to CreateFormFile:", err)
+ ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ _, err = io.Copy(part, file)
+ if err != nil {
+ log.Error("Failed to Copy:", err)
+ ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ for key, val := range params {
+ _ = writer.WriteField(key, val)
+ }
+
+ err = writer.Close()
+ if err != nil {
+ log.Error("Failed to Close:", err)
+ ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+
+ SetCommonResponseHeader(w)
+ w.Header().Set("Content-Type", writer.FormDataContentType())
+ w.WriteHeader(code)
+ w.Write(body.Bytes())
+ return
+}
+
+func ResponseFile(w http.ResponseWriter, code int, filePath string) {
+ fileBytes, err := os.ReadFile(filePath)
+ if err != nil {
+ log.Error("Failed to ReadFile:", err)
+ ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ SetCommonResponseHeader(w)
+ w.Header().Set("Content-Type", "application/octet-stream")
+ w.WriteHeader(code)
+ w.Write(fileBytes)
+
+ return
+}
+
+func ResponseFileWithNameAndMD5(w http.ResponseWriter, code int, fileName, path, md5Sum string) {
+ filePath := path + "/" + fileName
+ fileBytes, err := ioutil.ReadFile(filePath)
+ if err != nil {
+ log.Error("Failed to ReadFile:", err)
+ ResponseInternalServerError500ProcessError(w, err)
+ return
+ }
+ SetCommonResponseHeader(w)
+ w.Header().Set("Content-Type", "application/octet-stream")
+ w.Header().Set("User-File", fileName)
+ w.Header().Set("MD5-Sum", md5Sum)
+ w.WriteHeader(code)
+ w.Write(fileBytes)
+
+ return
+}
diff --git a/lib/session/session.go b/lib/session/session.go
new file mode 100644
index 00000000..32d7b7b6
--- /dev/null
+++ b/lib/session/session.go
@@ -0,0 +1,169 @@
+package session
+
+import (
+ "crypto/rand"
+ "encoding/base64"
+ "errors"
+ "io"
+ "net/http"
+ "strconv"
+ "strings"
+ "sync"
+ "time"
+
+ "ems.agt/lib/log"
+ "ems.agt/lib/oauth"
+ "ems.agt/restagent/config"
+)
+
+// SessionMgr session manager
+type SessManager struct {
+ name string
+ expires int64
+ lock sync.RWMutex
+ sessions map[string]*Session
+}
+
+// Session
+type Session struct {
+ token string
+ time time.Time
+ permission []bool
+ values map[interface{}]interface{}
+}
+
+// NewSessionMgr create session manager
+func NewSessManager(name string) *SessManager {
+ smgr := &SessManager{name: name, expires: (int64)(config.GetExpiresFromConfig()), sessions: make(map[string]*Session)}
+ go smgr.SessionGC()
+ return smgr
+}
+
+// NewSession create session
+func (smgr *SessManager) NewSession(w http.ResponseWriter, r *http.Request, plist []bool) string {
+ smgr.lock.Lock()
+ defer smgr.lock.Unlock()
+ token := oauth.GenRandToken() // Generate new token to session ID
+ session := &Session{token: token, time: time.Now(), permission: plist, values: make(map[interface{}]interface{})}
+ smgr.sessions[token] = session
+
+ return token
+}
+
+// EndSession
+func (smgr *SessManager) EndSession(w http.ResponseWriter, r *http.Request) {
+ token := smgr.GetTokenFromHttpRequest(r)
+
+ smgr.lock.Lock()
+ defer smgr.lock.Unlock()
+ delete(smgr.sessions, token)
+}
+
+// Handshake session, restart session
+func (smgr *SessManager) ShakeSession(token string) bool {
+
+ smgr.lock.Lock()
+ defer smgr.lock.Unlock()
+ for _, s := range smgr.sessions {
+ if token == s.token {
+ log.Debug("session time:", s.time)
+ s.time = time.Now()
+ return true
+ }
+ }
+ return false
+}
+
+// EndSessionByID end the session by session ID
+func (smgr *SessManager) DeleteSession(token string) {
+ smgr.lock.Lock()
+ defer smgr.lock.Unlock()
+ delete(smgr.sessions, token)
+}
+
+// SetSessionValue set value fo session
+func (smgr *SessManager) SetSessionValue(token string, key interface{}, value interface{}) error {
+ smgr.lock.Lock()
+ defer smgr.lock.Unlock()
+ if session, ok := smgr.sessions[token]; ok {
+ session.values[key] = value
+ return nil
+ }
+ return errors.New("invalid session ID")
+}
+
+// GetSessionValue get value fo session
+func (smgr *SessManager) GetSessionValue(token string, key interface{}) (interface{}, error) {
+ smgr.lock.RLock()
+ defer smgr.lock.RUnlock()
+ if session, ok := smgr.sessions[token]; ok {
+ if val, ok := session.values[key]; ok {
+ return val, nil
+ }
+ }
+ return nil, errors.New("invalid session ID")
+}
+
+func (smgr *SessManager) GetTokenFromHttpRequest(r *http.Request) string {
+ for k, v := range r.Header {
+ if strings.ToLower(k) == "accesstoken" && len(v) != 0 {
+ log.Debug("AccessToken:", v[0])
+ return v[0]
+ }
+ }
+
+ return ""
+}
+
+// IsValidToken check token is valid or not
+func (smgr *SessManager) IsValidToken(token string) bool {
+
+ smgr.lock.Lock()
+ defer smgr.lock.Unlock()
+ if _, ok := smgr.sessions[token]; ok {
+ return true
+ }
+ return false
+}
+
+// IsCarriedToken check token is carried
+func (smgr *SessManager) IsCarriedToken(r *http.Request) (string, bool) {
+
+ token := smgr.GetTokenFromHttpRequest(r)
+ if token == "" {
+ return "", false
+ }
+ return token, true
+}
+
+// GetPermissionFromSession get permission from session by token
+func (smgr *SessManager) GetPermissionFromSession(token string) []bool {
+
+ if s, ok := smgr.sessions[token]; ok {
+ return s.permission
+ }
+ return nil
+}
+
+// SessionGC maintain session
+func (smgr *SessManager) SessionGC() {
+ smgr.lock.Lock()
+ defer smgr.lock.Unlock()
+ for token, session := range smgr.sessions {
+ if session.time.Unix()+smgr.expires < time.Now().Unix() {
+ delete(smgr.sessions, token)
+ }
+ }
+
+ time.AfterFunc(time.Duration(smgr.expires)*time.Second, func() { smgr.SessionGC() })
+}
+
+// NewSessionID generate unique ID
+func (smgr *SessManager) NewSessionID() string {
+ b := make([]byte, 32)
+ if _, err := io.ReadFull(rand.Reader, b); err != nil {
+ nano := time.Now().UnixNano()
+ return strconv.FormatInt(nano, 10)
+ }
+ return base64.URLEncoding.EncodeToString(b)
+}
diff --git a/lib/websocket/client.go b/lib/websocket/client.go
new file mode 100644
index 00000000..368eeeee
--- /dev/null
+++ b/lib/websocket/client.go
@@ -0,0 +1,45 @@
+package websocket
+
+import (
+ "github.com/gorilla/websocket"
+)
+
+type Client struct {
+ ID string
+ Socket *websocket.Conn
+ Msg chan []byte
+}
+
+func NewWsClient(ID string, socket *websocket.Conn) *Client {
+ return &Client{
+ ID: ID,
+ Socket: socket,
+ Msg: make(chan []byte, 100),
+ }
+}
+
+func (c *Client) Read() {
+ defer func() {
+ close(c.Msg)
+ }()
+ for {
+ _, message, err := c.Socket.ReadMessage()
+ if err != nil {
+ return
+ }
+ ProcessData(c, message)
+ }
+}
+
+func (c *Client) Write() {
+ defer func() {
+ c.Socket.Close()
+ }()
+ for {
+ message, ok := <-c.Msg
+ if !ok {
+ return
+ }
+ _ = c.Socket.WriteMessage(websocket.TextMessage, message)
+ }
+}
diff --git a/lib/websocket/process_data.go b/lib/websocket/process_data.go
new file mode 100644
index 00000000..95d17d23
--- /dev/null
+++ b/lib/websocket/process_data.go
@@ -0,0 +1,405 @@
+package websocket
+
+import (
+ "encoding/json"
+ "fmt"
+ "sort"
+ "strings"
+ "sync"
+ "time"
+
+ "ems.agt/lib/cache"
+ "ems.agt/lib/log"
+ "github.com/shirou/gopsutil/v3/host"
+ "github.com/shirou/gopsutil/v3/net"
+ "github.com/shirou/gopsutil/v3/process"
+)
+
+type WsInput struct {
+ Type string `json:"type"`
+ DownloadProgress
+ PsProcessConfig
+ SSHSessionConfig
+ NetConfig
+}
+
+type DownloadProgress struct {
+ Keys []string `json:"keys"`
+}
+
+type PsProcessConfig struct {
+ Pid int32 `json:"pid"`
+ Name string `json:"name"`
+ Username string `json:"username"`
+}
+
+type SSHSessionConfig struct {
+ LoginUser string `json:"loginUser"`
+ LoginIP string `json:"loginIP"`
+}
+
+type NetConfig struct {
+ Port uint32 `json:"port"`
+ ProcessName string `json:"processName"`
+ ProcessID int32 `json:"processID"`
+}
+
+type PsProcessData struct {
+ PID int32 `json:"PID"`
+ Name string `json:"name"`
+ PPID int32 `json:"PPID"`
+ Username string `json:"username"`
+ Status string `json:"status"`
+ StartTime string `json:"startTime"`
+ NumThreads int32 `json:"numThreads"`
+ NumConnections int `json:"numConnections"`
+ CpuPercent string `json:"cpuPercent"`
+
+ DiskRead string `json:"diskRead"`
+ DiskWrite string `json:"diskWrite"`
+ CmdLine string `json:"cmdLine"`
+
+ Rss string `json:"rss"`
+ VMS string `json:"vms"`
+ HWM string `json:"hwm"`
+ Data string `json:"data"`
+ Stack string `json:"stack"`
+ Locked string `json:"locked"`
+ Swap string `json:"swap"`
+
+ CpuValue float64 `json:"cpuValue"`
+ RssValue uint64 `json:"rssValue"`
+
+ Envs []string `json:"envs"`
+
+ OpenFiles []process.OpenFilesStat `json:"openFiles"`
+ Connects []processConnect `json:"connects"`
+}
+
+type processConnect struct {
+ Type string `json:"type"`
+ Status string `json:"status"`
+ Laddr net.Addr `json:"localaddr"`
+ Raddr net.Addr `json:"remoteaddr"`
+ PID int32 `json:"PID"`
+ Name string `json:"name"`
+}
+
+type ProcessConnects []processConnect
+
+func (p ProcessConnects) Len() int {
+ return len(p)
+}
+
+func (p ProcessConnects) Less(i, j int) bool {
+ return p[i].PID < p[j].PID
+}
+
+func (p ProcessConnects) Swap(i, j int) {
+ p[i], p[j] = p[j], p[i]
+}
+
+type sshSession struct {
+ Username string `json:"username"`
+ PID int32 `json:"PID"`
+ Terminal string `json:"terminal"`
+ Host string `json:"host"`
+ LoginTime string `json:"loginTime"`
+}
+
+func ProcessData(c *Client, inputMsg []byte) {
+ wsInput := &WsInput{}
+ err := json.Unmarshal(inputMsg, wsInput)
+ if err != nil {
+ log.Errorf("unmarshal wsInput error,err %s", err.Error())
+ return
+ }
+ switch wsInput.Type {
+ case "wget":
+ res, err := getDownloadProcess(wsInput.DownloadProgress)
+ if err != nil {
+ return
+ }
+ c.Msg <- res
+ case "ps":
+ res, err := getProcessData(wsInput.PsProcessConfig)
+ if err != nil {
+ return
+ }
+ c.Msg <- res
+ case "ssh":
+ res, err := getSSHSessions(wsInput.SSHSessionConfig)
+ if err != nil {
+ return
+ }
+ c.Msg <- res
+ case "net":
+ res, err := getNetConnections(wsInput.NetConfig)
+ if err != nil {
+ return
+ }
+ c.Msg <- res
+ }
+
+}
+
+type Process struct {
+ Total uint64 `json:"total"`
+ Written uint64 `json:"written"`
+ Percent float64 `json:"percent"`
+ Name string `json:"name"`
+}
+
+func getDownloadProcess(progress DownloadProgress) (res []byte, err error) {
+ var result []Process
+ for _, k := range progress.Keys {
+ value, err := cache.CACHE.Get(k)
+ if err != nil {
+ log.Errorf("get cache error,err %s", err.Error())
+ return nil, err
+ }
+ downloadProcess := &Process{}
+ _ = json.Unmarshal(value, downloadProcess)
+ result = append(result, *downloadProcess)
+ }
+ res, err = json.Marshal(result)
+ return
+}
+
+const (
+ b = uint64(1)
+ kb = 1024 * b
+ mb = 1024 * kb
+ gb = 1024 * mb
+)
+
+func formatBytes(bytes uint64) string {
+ switch {
+ case bytes < kb:
+ return fmt.Sprintf("%dB", bytes)
+ case bytes < mb:
+ return fmt.Sprintf("%.2fKB", float64(bytes)/float64(kb))
+ case bytes < gb:
+ return fmt.Sprintf("%.2fMB", float64(bytes)/float64(mb))
+ default:
+ return fmt.Sprintf("%.2fGB", float64(bytes)/float64(gb))
+ }
+}
+
+func getProcessData(processConfig PsProcessConfig) (res []byte, err error) {
+ var processes []*process.Process
+ processes, err = process.Processes()
+ if err != nil {
+ return
+ }
+
+ var (
+ result []PsProcessData
+ resultMutex sync.Mutex
+ wg sync.WaitGroup
+ numWorkers = 4
+ )
+
+ handleData := func(proc *process.Process) {
+ procData := PsProcessData{
+ PID: proc.Pid,
+ }
+ if processConfig.Pid > 0 && processConfig.Pid != proc.Pid {
+ return
+ }
+ if procName, err := proc.Name(); err == nil {
+ procData.Name = procName
+ } else {
+ procData.Name = ""
+ }
+ if processConfig.Name != "" && !strings.Contains(procData.Name, processConfig.Name) {
+ return
+ }
+ if username, err := proc.Username(); err == nil {
+ procData.Username = username
+ }
+ if processConfig.Username != "" && !strings.Contains(procData.Username, processConfig.Username) {
+ return
+ }
+ procData.PPID, _ = proc.Ppid()
+ statusArray, _ := proc.Status()
+ if len(statusArray) > 0 {
+ procData.Status = strings.Join(statusArray, ",")
+ }
+ createTime, procErr := proc.CreateTime()
+ if procErr == nil {
+ t := time.Unix(createTime/1000, 0)
+ procData.StartTime = t.Format("2006-1-2 15:04:05")
+ }
+ procData.NumThreads, _ = proc.NumThreads()
+ connections, procErr := proc.Connections()
+ if procErr == nil {
+ procData.NumConnections = len(connections)
+ for _, conn := range connections {
+ if conn.Laddr.IP != "" || conn.Raddr.IP != "" {
+ procData.Connects = append(procData.Connects, processConnect{
+ Status: conn.Status,
+ Laddr: conn.Laddr,
+ Raddr: conn.Raddr,
+ })
+ }
+ }
+ }
+ procData.CpuValue, _ = proc.CPUPercent()
+ procData.CpuPercent = fmt.Sprintf("%.2f", procData.CpuValue) + "%"
+ menInfo, procErr := proc.MemoryInfo()
+ if procErr == nil {
+ procData.Rss = formatBytes(menInfo.RSS)
+ procData.RssValue = menInfo.RSS
+ procData.Data = formatBytes(menInfo.Data)
+ procData.VMS = formatBytes(menInfo.VMS)
+ procData.HWM = formatBytes(menInfo.HWM)
+ procData.Stack = formatBytes(menInfo.Stack)
+ procData.Locked = formatBytes(menInfo.Locked)
+ procData.Swap = formatBytes(menInfo.Swap)
+ } else {
+ procData.Rss = "--"
+ procData.Data = "--"
+ procData.VMS = "--"
+ procData.HWM = "--"
+ procData.Stack = "--"
+ procData.Locked = "--"
+ procData.Swap = "--"
+
+ procData.RssValue = 0
+ }
+ ioStat, procErr := proc.IOCounters()
+ if procErr == nil {
+ procData.DiskWrite = formatBytes(ioStat.WriteBytes)
+ procData.DiskRead = formatBytes(ioStat.ReadBytes)
+ } else {
+ procData.DiskWrite = "--"
+ procData.DiskRead = "--"
+ }
+ procData.CmdLine, _ = proc.Cmdline()
+ procData.OpenFiles, _ = proc.OpenFiles()
+ procData.Envs, _ = proc.Environ()
+
+ resultMutex.Lock()
+ result = append(result, procData)
+ resultMutex.Unlock()
+ }
+
+ chunkSize := (len(processes) + numWorkers - 1) / numWorkers
+ for i := 0; i < numWorkers; i++ {
+ wg.Add(1)
+ start := i * chunkSize
+ end := (i + 1) * chunkSize
+ if end > len(processes) {
+ end = len(processes)
+ }
+
+ go func(start, end int) {
+ defer wg.Done()
+ for j := start; j < end; j++ {
+ handleData(processes[j])
+ }
+ }(start, end)
+ }
+
+ wg.Wait()
+
+ sort.Slice(result, func(i, j int) bool {
+ return result[i].PID < result[j].PID
+ })
+ res, err = json.Marshal(result)
+ return
+}
+
+func getSSHSessions(config SSHSessionConfig) (res []byte, err error) {
+ var (
+ result []sshSession
+ users []host.UserStat
+ processes []*process.Process
+ )
+ processes, err = process.Processes()
+ if err != nil {
+ return
+ }
+ users, err = host.Users()
+ if err != nil {
+ return
+ }
+ for _, proc := range processes {
+ name, _ := proc.Name()
+ if name != "sshd" || proc.Pid == 0 {
+ continue
+ }
+ connections, _ := proc.Connections()
+ for _, conn := range connections {
+ for _, user := range users {
+ if user.Host == "" {
+ continue
+ }
+ if conn.Raddr.IP == user.Host {
+ if config.LoginUser != "" && !strings.Contains(user.User, config.LoginUser) {
+ continue
+ }
+ if config.LoginIP != "" && !strings.Contains(user.Host, config.LoginIP) {
+ continue
+ }
+ if terminal, err := proc.Cmdline(); err == nil {
+ if strings.Contains(terminal, user.Terminal) {
+ session := sshSession{
+ Username: user.User,
+ Host: user.Host,
+ Terminal: user.Terminal,
+ PID: proc.Pid,
+ }
+ t := time.Unix(int64(user.Started), 0)
+ session.LoginTime = t.Format("2006-1-2 15:04:05")
+ result = append(result, session)
+ }
+ }
+ }
+ }
+ }
+ }
+ res, err = json.Marshal(result)
+ return
+}
+
+var netTypes = [...]string{"tcp", "udp"}
+
+func getNetConnections(config NetConfig) (res []byte, err error) {
+ var (
+ result []processConnect
+ proc *process.Process
+ )
+ for _, netType := range netTypes {
+ connections, _ := net.Connections(netType)
+ if err == nil {
+ for _, conn := range connections {
+ if config.ProcessID > 0 && config.ProcessID != conn.Pid {
+ continue
+ }
+ proc, err = process.NewProcess(conn.Pid)
+ if err == nil {
+ name, _ := proc.Name()
+ if name != "" && config.ProcessName != "" && !strings.Contains(name, config.ProcessName) {
+ continue
+ }
+ if config.Port > 0 && config.Port != conn.Laddr.Port && config.Port != conn.Raddr.Port {
+ continue
+ }
+ result = append(result, processConnect{
+ Type: netType,
+ Status: conn.Status,
+ Laddr: conn.Laddr,
+ Raddr: conn.Raddr,
+ PID: conn.Pid,
+ Name: name,
+ })
+ }
+
+ }
+ }
+ }
+ res, err = json.Marshal(result)
+ return
+}
diff --git a/makefile b/makefile
new file mode 100644
index 00000000..a9382ccd
--- /dev/null
+++ b/makefile
@@ -0,0 +1,100 @@
+# Makefile for AGrandTech EMS project
+
+PROJECT = OMC
+VERSION = 5GC16.1.1
+PLATFORM = amd64
+ARMPLATFORM = aarch64
+GOPROJECTS = $(HOME)/goprojects
+BUILDDIR = $(GOPROJECTS)/build
+DEBBUILDDIR = $(GOPROJECTS)/debbuild
+RPMBUILDDIR = $(GOPROJECTS)/rpmbuild
+INSTALLDIR = /usr/local/omc
+RELEASEDIR = $(GOPROJECTS)/release
+EMSPROJECT = $(GOPROJECTS)/ems.agt
+LIBDIR = $(EMSPROJECT)/lib
+RESTAGENT = restagent
+CRONTASK = crontask
+SshSvcBin = sshsvc
+NBI_ALARM = nbi_alarm
+NBI_AGENT = nbi_agent
+4A_AGENT = 4a_agent
+RESTAGENTDIR = $(EMSPROJECT)/$(RESTAGENT)
+CRONTASKDIR = $(EMSPROJECT)/$(CRONTASK)
+SshSvcDir = $(EMSPROJECT)/$(SshSvcBin)
+DBSQLSRCDIR = $(EMSPROJECT)/database
+MISCDIR = $(EMSPROJECT)/misc
+FrontBuildDir = $(BUILDDIR)/omc/htdocs
+FrontSrcDir = $(EMSPROJECT)/front
+ReleaseDebs = $(RELEASEDIR)/debs/$(PLATFORM)
+BinDir = $(BUILDDIR)/omc/bin
+BinDir2 = $(BUILDDIR)/omc/run
+CrontaskSize = 27788951
+RestagentSize = 29525312
+BinWriterDir = $(HOME)/bin
+
+.PHONY: all $(RESTAGENT) $(CRONTASK)
+all: $(RESTAGENT) $(CRONTASK)
+ cd $(RESTAGENTDIR)
+ go build -o $(RESTAGENT) -v -ldflags "-X 'ems.agt/lib/conifg.Version=$(VERSION)' \
+ -X '$(LIBDIR)/conifg.BuildTime=`date`' \
+ -X '$(LIBDIR)/conifg.GoVer=`go version`'"
+ cd $(CRONTASKDIR)
+ go build -o $(CRONTASK) -v -ldflags "-X '$(LIBDIR)/conifg.Version=$(VERSION)' \
+ -X '$(LIBDIR)/conifg.BuildTime=`date`' \
+ -X '$(LIBDIR)/conifg.GoVer=`go version`'"
+
+
+clean:
+ rm ./restagent/$(RESTAGENT) ./crontask/$(CRONTASK)
+
+dist:
+ tar -zvcPf $(RELEASEDIR)/$(PROJECT)-src-$(VERSION).tar.gz \
+ ../lib \
+ ../restagent \
+ ../crontask \
+ ../initems \
+ ../database \
+ ../docs \
+ ../misc \
+ ../config \
+ --exclude=../restagent/restagent \
+ --exclude=../crontask/crontask \
+ --exclude=../initems/initems
+
+deb: $(BINNAME)
+ cp -rf ./restagent/$(RESTAGENT) $(BUILDDIR)/omc/bin
+ cp -rf ./crontask/$(CRONTASK) $(BUILDDIR)/omc/bin
+ cp -rf $(MISCDIR)/* $(BUILDDIR)/omc/bin
+ cp -rf $(DBSQLSRCDIR)/*.sql $(BUILDDIR)/omc/etc/db
+ rm -rf $(FrontBuildDir)/*
+ unzip $(FrontSrcDir)/front.zip -d $(FrontBuildDir) >/dev/null
+ chmod 755 $(BUILDDIR)/omc/bin/*
+ chmod 755 $(DEBBUILDDIR)/DEBIAN/*
+ cp -rf $(BUILDDIR)/omc/* $(DEBBUILDDIR)/usr/local/omc/
+ chmod +x $(DEBBUILDDIR)/usr/local/omc/bin/*
+ cp -rf $(BUILDDIR)/nginx/* $(DEBBUILDDIR)/etc/nginx/conf.d
+ cp -rf $(BUILDDIR)/systemd/*.service $(DEBBUILDDIR)/lib/systemd/system/
+ dpkg -b $(DEBBUILDDIR) $(ReleaseDebs)/$(PROJECT)-$(VERSION).$(PLATFORM).deb
+
+rpm: $(BINNAME)
+ cp -rf ./restagent/$(RESTAGENT) $(BinDir)
+ cp -rf ./crontask/$(CRONTASK) $(BinDir)
+ cp -rf $(SshSvcDir)/$(SshSvcBin) $(BinDir2)
+ $(BinWriterDir)/binWriter $(BinDir)/$(RESTAGENT) $(RestagentSize)
+ $(BinWriterDir)/binWriter $(BinDir)/$(CRONTASK) $(CrontaskSize)
+ cp -rf $(MISCDIR)/ne-hosts $(BinDir)
+ cp -rf ./nbi/$(NBI_ALARM)/bin/$(NBI_ALARM) $(BinDir2)
+ cp -rf ./nbi/$(NBI_AGENT)/bin/$(NBI_AGENT) $(BinDir2)
+ cp -rf ./$(4A_AGENT)/bin/$(4A_AGENT) $(BinDir2)
+ cp -rf $(MISCDIR)/* $(BinDir2)
+ rm -rf $(BinDir2)/ne-hosts
+ cp -rf $(DBSQLSRCDIR)/* $(BUILDDIR)/omc/etc/db
+ rm -rf $(FrontBuildDir)/*
+ unzip $(FrontSrcDir)/front.zip -d $(FrontBuildDir) >/dev/null
+ chmod 755 $(BinDir)/*
+ chmod 755 $(BinDir2)/*
+ cp -rf $(BUILDDIR)/omc $(RPMBUILDDIR)/BUILD
+ cp -rf $(BUILDDIR)/nginx $(RPMBUILDDIR)/BUILD
+ cp -rf $(BUILDDIR)/systemd $(RPMBUILDDIR)/BUILD
+ cd $(RPMBUILDDIR)
+ rpmbuild -bb -D "_topdir $(RPMBUILDDIR)" --sign $(RPMBUILDDIR)/SPECS/omc.spec
diff --git a/misc/checkdisk.sh b/misc/checkdisk.sh
new file mode 100644
index 00000000..23587d77
--- /dev/null
+++ b/misc/checkdisk.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+threshold=99 # 设置硬盘使用率的阈值
+
+disk_usage=$(df -h | awk '$NF=="/"{print $(NF-1)}' | sed 's/%//') # 获取根目录的硬盘使用率
+
+if [ $disk_usage -gt $threshold ]; then
+ echo "Disk usage is above $threshold%. Taking action..."
+ systemctl restart keepalived
+fi
\ No newline at end of file
diff --git a/misc/checkproc.sh b/misc/checkproc.sh
new file mode 100644
index 00000000..70509991
--- /dev/null
+++ b/misc/checkproc.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+process_name="restagent"
+
+if ! pgrep -x "$process_name" >/dev/null; then
+ echo "$process_name is not running. Restarting..."
+ systemctl restart keepalived
+fi
\ No newline at end of file
diff --git a/misc/cpsshkey.sh b/misc/cpsshkey.sh
new file mode 100644
index 00000000..f83b26fc
--- /dev/null
+++ b/misc/cpsshkey.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# 判断id_rsa密钥文件是否存在
+if [ ! -f ~/.ssh/id_rsa ];then
+ ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa
+else
+ echo "id_rsa has created ..."
+fi
+
+#分发到各个节点,这里分发到ne-hosts文件中的主机中.
+while read line
+ do
+ user=`echo $line | cut -d " " -f 2`
+ ip=`echo $line | cut -d " " -f 1`
+ passwd=`echo $line | cut -d " " -f 3`
+
+ expect <omc-md5sum.txt
+ ;;
+ deb)
+ cd $EmsDir
+ make deb
+ ;;
+ *)
+ echo "mkpkg"
+ echo "Usage: $0 rpm|deb"
+ ;;
+esac
\ No newline at end of file
diff --git a/nbi/nbi_agent/bin/nbi_agent b/nbi/nbi_agent/bin/nbi_agent
new file mode 100644
index 00000000..70c67798
Binary files /dev/null and b/nbi/nbi_agent/bin/nbi_agent differ
diff --git a/nbi/nbi_agent/certs/cacert.pem b/nbi/nbi_agent/certs/cacert.pem
new file mode 100644
index 00000000..7734aeaa
--- /dev/null
+++ b/nbi/nbi_agent/certs/cacert.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDqzCCApOgAwIBAgIUDs5kTQVLnC1MdhXHj0KqYIG+nyAwDQYJKoZIhvcNAQEL
+BQAwZTELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAkdEMREwDwYDVQQHDAhzaGVuemhl
+bjEnMCUGA1UECgweaHR0cHM6Ly93d3cuYWdyYW5kdGVjaC5jb20uY24vMQ0wCwYD
+VQQDDAR0ZXN0MB4XDTIzMDcwMTA4NDQzOFoXDTMzMDYyODA4NDQzOFowZTELMAkG
+A1UEBhMCQ04xCzAJBgNVBAgMAkdEMREwDwYDVQQHDAhzaGVuemhlbjEnMCUGA1UE
+CgweaHR0cHM6Ly93d3cuYWdyYW5kdGVjaC5jb20uY24vMQ0wCwYDVQQDDAR0ZXN0
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0SMdRLkcxy3PKOSCusJ+
+AnGiJyW6AxyujqZj4xjgtIFjYIMVW5ZXVbWnY0xzRPddFddnEWgMeMLn9V3zcESV
+3tu9exm6Ijop8/KaDJ1EJAESunxkP9x/1ek3kgQvuK3YAcizTeB5ODUZ/KFJw9MP
+R/KUB+TYqCp50mr6mlIZE6lvhhvMxHz6ZmOFh2RvYg0h8oXpo5G8nmRVb4gNrlXK
+y/HZpGtbm/mfbOtxWgvSFy3PE/49V8nOYJbhDaoOXWVN06Z7w1y4KzSKbIoZfC9C
+WdWRrrhIv+Px1QLQItL17kAKqtp+vtG8lZjC5vsAgXLVAZLK71b6onv1Ir3Yuwwf
+vQIDAQABo1MwUTAdBgNVHQ4EFgQUbbMdtnhOyBmP+k1rOl6pfcsHmLowHwYDVR0j
+BBgwFoAUbbMdtnhOyBmP+k1rOl6pfcsHmLowDwYDVR0TAQH/BAUwAwEB/zANBgkq
+hkiG9w0BAQsFAAOCAQEAdGZdTglVP1hI0wcxD0rkkHu7IkfFGlaad1vFL+VfujlV
+6H3/WrDLCDhLDBZrdZ3m0LrQqpJjZriOaqc0O8LbT4ktquVuAgYtT/il6EQzLpyE
+pEW+iM4Ae2tu9rMH1F365+C8ffQWuSenvQOOjL8L9BP5N0bguVsWA+uMNprMado4
+lLuyHOt5S36WOKh4mnMlkDBuCNnBCiFS8rcQXJugk6jrOYKji5wJGNAVMoSEtRvN
+LdZh5XOkbXuFrhltPxMG/7BaPc9xS46chBKDvCQPweKGeu2eG+y6KTwCDYmakmVX
+OE8TnP4Zr0miTprzkmbWhIkUWkg/FclJs1/TcSkCGw==
+-----END CERTIFICATE-----
diff --git a/nbi/nbi_agent/certs/nbi_agent.crt b/nbi/nbi_agent/certs/nbi_agent.crt
new file mode 100644
index 00000000..1b11409a
--- /dev/null
+++ b/nbi/nbi_agent/certs/nbi_agent.crt
@@ -0,0 +1,81 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=CN, ST=GD, L=shenzhen, O=https://www.agrandtech.com.cn/, CN=test
+ Validity
+ Not Before: Jul 1 10:05:48 2023 GMT
+ Not After : Mar 27 10:05:48 2026 GMT
+ Subject: C=CN, ST=GD, O=https://www.agrandtech.com.cn/, CN=test
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public-Key: (2048 bit)
+ Modulus:
+ 00:f3:bd:e9:fe:aa:a6:c1:d9:7b:74:20:f0:d0:f3:
+ ee:7c:d0:69:84:8d:1a:37:1e:29:42:98:86:51:87:
+ fe:5d:48:2e:97:b0:c6:16:9c:46:6a:38:7b:34:54:
+ ec:76:d2:52:50:bb:31:a8:de:7d:3f:8c:c5:f8:fb:
+ e3:e3:73:37:36:10:e8:55:df:80:cf:c0:d9:40:30:
+ b7:54:49:69:e3:a8:79:49:47:d8:74:b0:07:13:dd:
+ 47:72:89:69:bd:0c:40:8b:f4:ee:49:02:cb:f4:b9:
+ c1:7a:7d:da:10:1b:b2:b1:9f:0d:70:66:d1:86:31:
+ dc:e3:d6:e5:f5:2c:e1:57:bd:72:ea:4a:1d:0c:4c:
+ 58:09:2b:2e:e5:53:40:73:55:e9:78:c3:7a:95:25:
+ b7:9d:80:ac:e4:79:c3:d7:9b:d1:c3:73:78:da:03:
+ f4:aa:68:21:81:f2:53:b8:3d:91:60:e0:91:47:2e:
+ 6d:5d:01:ae:f2:82:c0:8a:dd:06:8c:70:6e:77:7e:
+ 14:ae:61:a5:d8:e0:13:1b:2c:f7:d3:62:0c:d1:5c:
+ 48:fe:59:ca:b5:b1:2b:89:2b:2f:69:5d:40:42:05:
+ ab:76:58:4f:36:1a:36:1c:21:eb:85:1c:da:22:1b:
+ c2:60:8e:c1:7d:50:33:39:c0:40:e0:49:20:a0:f7:
+ c3:4f
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ D7:A0:3F:5F:C0:65:83:88:6F:5E:98:DB:30:3D:9F:24:6A:D0:DE:54
+ X509v3 Authority Key Identifier:
+ keyid:6D:B3:1D:B6:78:4E:C8:19:8F:FA:4D:6B:3A:5E:A9:7D:CB:07:98:BA
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 39:8a:89:a2:79:0f:c0:fd:d8:db:d5:38:d2:03:b4:38:be:a2:
+ 6e:6b:1c:28:93:0a:a6:0b:af:0a:69:6b:8b:d5:df:3d:de:76:
+ ad:24:23:98:7a:21:a1:2f:90:47:9b:98:9e:d2:b4:75:21:bd:
+ d0:38:34:6b:b1:96:3d:24:da:ac:1a:45:e4:01:1d:a2:20:c3:
+ 43:d3:ec:d9:2d:3b:d1:ee:0d:1e:21:15:e7:7f:d3:95:1c:dc:
+ fa:88:3a:05:4b:c5:08:5d:f4:40:89:29:80:fe:6b:40:b9:34:
+ 92:2e:48:94:d2:4b:0b:4d:1e:3c:64:17:cf:34:ec:36:5c:6d:
+ 3d:90:9c:74:95:d7:c8:96:a2:70:59:4a:d2:b5:e1:c1:a9:b7:
+ ad:f0:99:ff:b4:4d:89:e7:e3:9d:7d:79:36:40:05:6d:20:46:
+ 54:af:18:73:c9:07:17:26:18:86:99:cc:e2:58:27:96:84:58:
+ 18:d4:fe:dc:36:cd:8a:48:cc:e6:51:27:e5:76:81:2f:c7:9c:
+ 7b:f9:fb:19:c9:7c:e4:27:06:75:cd:16:88:74:3c:0b:23:d6:
+ 86:6b:95:41:10:cf:b2:fc:e8:1e:e0:d6:a5:8c:d1:c0:1b:d5:
+ 6e:15:8c:9a:67:5c:9d:ac:02:5a:69:17:e8:4c:42:d0:5d:88:
+ da:08:4e:c0
+-----BEGIN CERTIFICATE-----
+MIIDrTCCApWgAwIBAgIBATANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQGEwJDTjEL
+MAkGA1UECAwCR0QxETAPBgNVBAcMCHNoZW56aGVuMScwJQYDVQQKDB5odHRwczov
+L3d3dy5hZ3JhbmR0ZWNoLmNvbS5jbi8xDTALBgNVBAMMBHRlc3QwHhcNMjMwNzAx
+MTAwNTQ4WhcNMjYwMzI3MTAwNTQ4WjBSMQswCQYDVQQGEwJDTjELMAkGA1UECAwC
+R0QxJzAlBgNVBAoMHmh0dHBzOi8vd3d3LmFncmFuZHRlY2guY29tLmNuLzENMAsG
+A1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPO96f6q
+psHZe3Qg8NDz7nzQaYSNGjceKUKYhlGH/l1ILpewxhacRmo4ezRU7HbSUlC7Maje
+fT+Mxfj74+NzNzYQ6FXfgM/A2UAwt1RJaeOoeUlH2HSwBxPdR3KJab0MQIv07kkC
+y/S5wXp92hAbsrGfDXBm0YYx3OPW5fUs4Ve9cupKHQxMWAkrLuVTQHNV6XjDepUl
+t52ArOR5w9eb0cNzeNoD9KpoIYHyU7g9kWDgkUcubV0BrvKCwIrdBoxwbnd+FK5h
+pdjgExss99NiDNFcSP5ZyrWxK4krL2ldQEIFq3ZYTzYaNhwh64Uc2iIbwmCOwX1Q
+MznAQOBJIKD3w08CAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYd
+T3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFNegP1/AZYOI
+b16Y2zA9nyRq0N5UMB8GA1UdIwQYMBaAFG2zHbZ4TsgZj/pNazpeqX3LB5i6MA0G
+CSqGSIb3DQEBCwUAA4IBAQA5iomieQ/A/djb1TjSA7Q4vqJuaxwokwqmC68KaWuL
+1d893natJCOYeiGhL5BHm5ie0rR1Ib3QODRrsZY9JNqsGkXkAR2iIMND0+zZLTvR
+7g0eIRXnf9OVHNz6iDoFS8UIXfRAiSmA/mtAuTSSLkiU0ksLTR48ZBfPNOw2XG09
+kJx0ldfIlqJwWUrSteHBqbet8Jn/tE2J5+OdfXk2QAVtIEZUrxhzyQcXJhiGmczi
+WCeWhFgY1P7cNs2KSMzmUSfldoEvx5x7+fsZyXzkJwZ1zRaIdDwLI9aGa5VBEM+y
+/Oge4NaljNHAG9VuFYyaZ1ydrAJaaRfoTELQXYjaCE7A
+-----END CERTIFICATE-----
diff --git a/nbi/nbi_agent/certs/nbi_agent.key b/nbi/nbi_agent/certs/nbi_agent.key
new file mode 100644
index 00000000..94264dba
--- /dev/null
+++ b/nbi/nbi_agent/certs/nbi_agent.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEA873p/qqmwdl7dCDw0PPufNBphI0aNx4pQpiGUYf+XUgul7DG
+FpxGajh7NFTsdtJSULsxqN59P4zF+Pvj43M3NhDoVd+Az8DZQDC3VElp46h5SUfY
+dLAHE91HcolpvQxAi/TuSQLL9LnBen3aEBuysZ8NcGbRhjHc49bl9SzhV71y6kod
+DExYCSsu5VNAc1XpeMN6lSW3nYCs5HnD15vRw3N42gP0qmghgfJTuD2RYOCRRy5t
+XQGu8oLAit0GjHBud34UrmGl2OATGyz302IM0VxI/lnKtbEriSsvaV1AQgWrdlhP
+Nho2HCHrhRzaIhvCYI7BfVAzOcBA4EkgoPfDTwIDAQABAoIBAFTFQ0GABnk681XD
+Mx3pCJO+RESGcoyi38S6mVR30L6OoS2+nFY2ycKdnDPqKUd2BIzxXecWYkcc5amf
+qXVsl9Ik9TkQf5NBxg0uJESbN8mmyW/0HdMPeZauCfBK3EyUm0pRyCH6aAbYJ/M7
+HAEoMPDXmWvzRoG+i81t6xJnJoRFwI8xQfKf6DbiP4KUlU7MVRWpVFkCXzZkyoqi
+NWKyYfv7cBTZrWpeBCvyKRtUDvA9xjgfRTmR5rBfre9XCcu0hD2HwYBR8Nh0kz0g
+4/ZgEX4LYpL40r/tbzL1hlG2zaKQw/Hmb90CvUBfwwNFA/Xvhq5NYJhwVaauPhVN
+vDxIf/ECgYEA/gyooDz0B/OGSDeetBuZyQ1HjlWc7wNSCG+SBbaDb5WCLAcJCOEc
+ybCg81s3P1p4IRo1BR0II1RM8RHhMLVlL/NgYQsvpYJd/02BTxYQka7EXXOdL533
+CuKYTEKODisSSjNPF051kADHs0iL5Jc8iDT21Rb8C6E4N1J1lCEWsCkCgYEA9Zz+
+16P7UVKGZzEF6/xtOf59H+Arrty9eW9nlGH+Wjkz+xySYAVSaa/6n6LiBGOwXvKc
+GmUSMhanIgvnTXVkwpCEAl6cVufwuPR5V0Y66xnSsAtpascJqvCgVAxS9b0SVAju
+WvExxRrEquvYUlZ7kwN2a8Rnm02BjFPijy8D5rcCgYBZWApVkBoiUbp/20+s96f1
+1P29SM6QIBLRdKtd5voCXAoTgcXjoYeGRt/TtdiQJzjoK1dKHROnmRYWEbuobaLQ
+Yj8a4dw30MlN5+v57ECXe2cDlo1JGbyvz1DQQPfEc9FS1wiRob4mjp+spW7NTYK0
+RCwqdJLfZCtpCU7gcWKRQQKBgG9DB064Qgi80ZW9Z2lXmENFPXlLG37DEDIKfWmC
+Wq6Uay+96bEFuCeYSHg4WRqT7jmUvZJXZr659ExACC/WliZtQN+x7DCSMUIXvUAD
+2HzX3dFR2hc8wuxkxLxOOOaJF9xpj1AzItCfJ6gl3oCuHJykXOjEuApqOd1PwroK
+GkJRAoGBANzf7rFrVxapMa5W/Q5fGFMwzF6sKPU0xZUhYKen0jwndl4NEQakWoiI
+oWjeeFgPoKQa7LPfwfPEsCNTt3D/7ow/5kk39kTpegmICDcF+f1ij8w5ekuw4QyO
+ltQsHXNdzdulT8Mhg1+R6EabgvBGZEFyWMH2yeF3QKhg6ezRAzcV
+-----END RSA PRIVATE KEY-----
diff --git a/nbi/nbi_agent/etc/nbi_agent.json b/nbi/nbi_agent/etc/nbi_agent.json
new file mode 100644
index 00000000..dd995fb6
--- /dev/null
+++ b/nbi/nbi_agent/etc/nbi_agent.json
@@ -0,0 +1,92 @@
+{
+ "oss_info":[
+ {
+ "addr":"http://127.0.0.1",
+ "grant_type":"password",
+ "user_name":"omc",
+ "user_key":"omc@password",
+ "max_data_len":10,
+ "time_out":10
+ },
+ {
+ "addr":"http://127.0.0.1",
+ "grant_type":"password",
+ "user_name":"omc",
+ "user_key":"omc@password",
+ "max_data_len":10,
+ "time_out":10
+ }
+ ],
+ "ca":{
+ "root_cert":"/usr/local/omc/etc/certs/cacert.pem",
+ "cert":"/usr/local/omc/etc/certs/nbi_agent.crt",
+ "private_key":"/usr/local/omc/etc/certs/nbi_agent.key",
+ "check":true
+ },
+ "syslog":{
+ "facility": 16,
+ "severity": 6,
+ "vendor": "RJ",
+ "ne_name": "omc_sz_01",
+ "rm_uid": "sz_01",
+ "ne_type": "omc",
+ "log_file": [
+ {
+ "table_name": "nbi_operation_log",
+ "log_path": "/opt/omc/ftp/log/nbi/nbi_operation.log",
+ "period": 1
+ },
+ {
+ "table_name": "nbi_secure_log",
+ "log_path": "/opt/omc/ftp/log/nbi/nbi_secure.log",
+ "period": 1
+ }
+ ]
+ },
+ "mysql":"root:1000omc@kp!@tcp(192.168.0.229:33066)/omc_db?charset=utf8mb4&parseTime=True&loc=Local",
+ "log_dir":"/usr/loal/omc/log/nbi",
+ "log_file":"nbi_agent.log",
+ "mock_report_api":true,
+ "web_addr":"0.0.0.0:5050",
+ "cm":{
+ "udm":[
+ "ManagedElement",
+ "UdmFunction",
+ "UdrFunction",
+ "AusfFunction",
+ "IPResource"
+ ],
+ "upf":[
+ "ManagedElement",
+ "InventoryUnitRack",
+ "InventoryUnitShelf",
+ "InventoryUnitPack",
+ "InventoryUnitHost",
+ "InventoryUnitAccessory",
+ "UpfFunction",
+ "EpRpDynN9Upf",
+ "EpRpDynN3Upf",
+ "AmfFunction",
+ "SmfFunction",
+ "UdrFunction",
+ "AusfFunction",
+ "IPResource"
+ ],
+ "smf":[
+ "ManagedElement",
+ "SmfFunction",
+ "AddrPool",
+ "EpRpDynN7Smf",
+ "EpRpDynN10Smf",
+ "IPResource"
+ ],
+ "amf":[
+ "ManagedElement",
+ "AmfFunction",
+ "EpRpDynN8Amf",
+ "EpRpDynN11Amf",
+ "EpRpDynN12Amf",
+ "IPResource"
+ ]
+ }
+}
diff --git a/nbi/nbi_agent/readme b/nbi/nbi_agent/readme
new file mode 100644
index 00000000..33ebd639
--- /dev/null
+++ b/nbi/nbi_agent/readme
@@ -0,0 +1,47 @@
+项目交付文件:
+fpt://192.168.0.229/home/guodeng/bin/nbi_agent
+
+
+服务启动:
+./nbi_agent -c /home/guodeng/nbi_agent/conf/nbi_agent.json
+
+
+配置文件详情:
+{{
+ //oss侧配置
+ "oss_info": [
+ {
+ // oss 服务器地址
+ "addr": "http://127.0.0.1",
+ //用户认证方式
+ "grant_type": "password",
+ //用户名
+ "user_name": "test",
+ //用户认证密码/CA
+ "user_key": "test",
+ //上报的最大数据条数
+ "max_data_len": 10,
+ //上报接口的超时时间
+ "time_out": 10
+ },
+ {
+ "addr": "http://127.0.0.1",
+ "grant_type": "password",
+ "user_name": "test",
+ "user_key": "test",
+ "max_data_len": 10,
+ "time_out": 10
+ }
+ ],
+
+ // 数据库连接
+ "mysql": "root:1000omc@kp!@tcp(192.168.0.229:33066)/omc_db?charset=utf8mb4&parseTime=True&loc=Local",
+
+ //日志目录
+ "log_dir": "./nbi_log",
+ //日志文件名称
+ "log_file":"nbi_agent",
+
+ //本地web服务启动地址&端口
+ "web_addr": "0.0.0.0:80"
+ }
diff --git a/nbi/nbi_alarm/bin/nbi_alarm b/nbi/nbi_alarm/bin/nbi_alarm
new file mode 100644
index 00000000..80aca993
Binary files /dev/null and b/nbi/nbi_alarm/bin/nbi_alarm differ
diff --git a/nbi/nbi_alarm/etc/nbi_alarm.json b/nbi/nbi_alarm/etc/nbi_alarm.json
new file mode 100644
index 00000000..412cbcd1
--- /dev/null
+++ b/nbi/nbi_alarm/etc/nbi_alarm.json
@@ -0,0 +1,22 @@
+{
+ "channel": [
+ {
+ "tcp_port": 31232,
+ "bind_flag": "SMF#SZ_01",
+ "province": "BJ",
+ "device_code": "0001"
+ },
+ {
+ "tcp_port": 31233,
+ "bind_flag": "UDM#SZ_03",
+ "province": "BJ",
+ "device_code": "0002"
+ }
+ ],
+ "mysql": "root:1000omc@kp!@tcp(127.0.0.1:33066)/omc_db?charset=utf8mb4&parseTime=True&loc=Local",
+ "ftp_root": "/opt/omc/ftp/fm",
+ "mame":"nbi alarm agent",
+ "heartbeat_max": 180,
+ "log_dir": "/usr/local/omc/log/nbi_log",
+ "log_file":"nbi_alarm.log"
+}
diff --git a/nbi/nbi_alarm/readme.txt b/nbi/nbi_alarm/readme.txt
new file mode 100644
index 00000000..11f01bb5
--- /dev/null
+++ b/nbi/nbi_alarm/readme.txt
@@ -0,0 +1,43 @@
+
+项目交付文件:
+fpt://192.168.0.229/home/guodeng/bin
+
+服务启动:
+./nb_alarm_agent -c /home/guodeng/omc/conf/nb_alarm_agent.json
+
+配置文件详情:
+{
+ /* 通道配置项*/
+ "channel": [
+ {
+ "tcp_port": 31232, //通道TCP监听端口
+ "bind_flag": "SMF#SZ_01", //通道Bind网元(格式为 ne_type#ne_id)
+ "province": "BJ", //网元所在省份
+ "device_code": "0001" //网元主机编码
+ },
+ {
+ "tcp_port": 31233, //通道TCP监听端口
+ "bind_flag": "UDM#SZ_03", //通道Bind网元(格式为 ne_type#ne_id)
+ "province": "BJ", //网元所在省份
+ "device_code": "0002" //网元主机编码
+ }
+ ],
+
+ // 数据库配置
+ "mysql": "root:1000omc@kp!@tcp(192.168.0.229:33066)/omc_db?charset=utf8mb4&parseTime=True&loc=Local",
+
+ // FTP服务器根目录
+ "ftp_root": "data/ftp",
+
+ //服务名称
+ "mame":"north agent",
+
+ // 心跳保活时间, 如果服务器检查client 在超过心跳时间没有数据(心跳数据或者业务数据)发送,则断开连接
+ "heartbeat_max": 180,
+
+ // 日志存放目录
+ "log_dir": "./omc_log",
+
+ // 日志文件名称
+ "log_file":"omc.log"
+}
diff --git a/restagent/backup/smf-sz_01-etc-20230727001500.zip b/restagent/backup/smf-sz_01-etc-20230727001500.zip
new file mode 100644
index 00000000..e5959079
Binary files /dev/null and b/restagent/backup/smf-sz_01-etc-20230727001500.zip differ
diff --git a/restagent/backup/smf-sz_01-etc-20230728001500.zip b/restagent/backup/smf-sz_01-etc-20230728001500.zip
new file mode 100644
index 00000000..36a3cd00
Binary files /dev/null and b/restagent/backup/smf-sz_01-etc-20230728001500.zip differ
diff --git a/restagent/backup/smf-sz_01-etc-20230729001500.zip b/restagent/backup/smf-sz_01-etc-20230729001500.zip
new file mode 100644
index 00000000..570e7682
Binary files /dev/null and b/restagent/backup/smf-sz_01-etc-20230729001500.zip differ
diff --git a/restagent/backup/smf-sz_01-etc-20230730001500.zip b/restagent/backup/smf-sz_01-etc-20230730001500.zip
new file mode 100644
index 00000000..75d02fe2
Binary files /dev/null and b/restagent/backup/smf-sz_01-etc-20230730001500.zip differ
diff --git a/restagent/backup/smf-sz_01-etc-20230801001500.zip b/restagent/backup/smf-sz_01-etc-20230801001500.zip
new file mode 100644
index 00000000..6eb310fc
Binary files /dev/null and b/restagent/backup/smf-sz_01-etc-20230801001500.zip differ
diff --git a/restagent/backup/smf-sz_01-etc-20230802001500.zip b/restagent/backup/smf-sz_01-etc-20230802001500.zip
new file mode 100644
index 00000000..957b3fca
Binary files /dev/null and b/restagent/backup/smf-sz_01-etc-20230802001500.zip differ
diff --git a/restagent/backup/udm-sz_011-etc-20230727001500.zip b/restagent/backup/udm-sz_011-etc-20230727001500.zip
new file mode 100644
index 00000000..acd6476a
Binary files /dev/null and b/restagent/backup/udm-sz_011-etc-20230727001500.zip differ
diff --git a/restagent/backup/udm-sz_011-etc-20230728001500.zip b/restagent/backup/udm-sz_011-etc-20230728001500.zip
new file mode 100644
index 00000000..d00cd5d5
Binary files /dev/null and b/restagent/backup/udm-sz_011-etc-20230728001500.zip differ
diff --git a/restagent/backup/udm-sz_011-etc-20230729001501.zip b/restagent/backup/udm-sz_011-etc-20230729001501.zip
new file mode 100644
index 00000000..7e411d89
Binary files /dev/null and b/restagent/backup/udm-sz_011-etc-20230729001501.zip differ
diff --git a/restagent/backup/udm-sz_011-etc-20230730001500.zip b/restagent/backup/udm-sz_011-etc-20230730001500.zip
new file mode 100644
index 00000000..393b2458
Binary files /dev/null and b/restagent/backup/udm-sz_011-etc-20230730001500.zip differ
diff --git a/restagent/backup/udm-sz_011-etc-20230801001500.zip b/restagent/backup/udm-sz_011-etc-20230801001500.zip
new file mode 100644
index 00000000..9e1eb338
Binary files /dev/null and b/restagent/backup/udm-sz_011-etc-20230801001500.zip differ
diff --git a/restagent/backup/udm-sz_011-etc-20230802001501.zip b/restagent/backup/udm-sz_011-etc-20230802001501.zip
new file mode 100644
index 00000000..97d3b6fa
Binary files /dev/null and b/restagent/backup/udm-sz_011-etc-20230802001501.zip differ
diff --git a/restagent/backup/upf-sz_01-etc-20230725090619.zip b/restagent/backup/upf-sz_01-etc-20230725090619.zip
new file mode 100644
index 00000000..b29257a2
Binary files /dev/null and b/restagent/backup/upf-sz_01-etc-20230725090619.zip differ
diff --git a/restagent/backup/upf-sz_01-etc-20230727145225.zip b/restagent/backup/upf-sz_01-etc-20230727145225.zip
new file mode 100644
index 00000000..8a5052d5
Binary files /dev/null and b/restagent/backup/upf-sz_01-etc-20230727145225.zip differ
diff --git a/restagent/backup/upf-sz_01-etc-20230729104910.zip b/restagent/backup/upf-sz_01-etc-20230729104910.zip
new file mode 100644
index 00000000..9ac09e59
Binary files /dev/null and b/restagent/backup/upf-sz_01-etc-20230729104910.zip differ
diff --git a/restagent/backup/upf-sz_01-etc-20230730154754.zip b/restagent/backup/upf-sz_01-etc-20230730154754.zip
new file mode 100644
index 00000000..cb1873f9
Binary files /dev/null and b/restagent/backup/upf-sz_01-etc-20230730154754.zip differ
diff --git a/restagent/backup/upf-sz_01-etc-20230801003933.zip b/restagent/backup/upf-sz_01-etc-20230801003933.zip
new file mode 100644
index 00000000..3cc4899b
Binary files /dev/null and b/restagent/backup/upf-sz_01-etc-20230801003933.zip differ
diff --git a/restagent/backup/upf-upf_sz_rd_109-etc-20230725090625.zip b/restagent/backup/upf-upf_sz_rd_109-etc-20230725090625.zip
new file mode 100644
index 00000000..7003cfd2
Binary files /dev/null and b/restagent/backup/upf-upf_sz_rd_109-etc-20230725090625.zip differ
diff --git a/restagent/backup/upf-upf_sz_rd_109-etc-20230727145227.zip b/restagent/backup/upf-upf_sz_rd_109-etc-20230727145227.zip
new file mode 100644
index 00000000..aaf16f09
Binary files /dev/null and b/restagent/backup/upf-upf_sz_rd_109-etc-20230727145227.zip differ
diff --git a/restagent/backup/upf-upf_sz_rd_109-etc-20230729104911.zip b/restagent/backup/upf-upf_sz_rd_109-etc-20230729104911.zip
new file mode 100644
index 00000000..49741a80
Binary files /dev/null and b/restagent/backup/upf-upf_sz_rd_109-etc-20230729104911.zip differ
diff --git a/restagent/backup/upf-upf_sz_rd_109-etc-20230730154757.zip b/restagent/backup/upf-upf_sz_rd_109-etc-20230730154757.zip
new file mode 100644
index 00000000..15cb8b58
Binary files /dev/null and b/restagent/backup/upf-upf_sz_rd_109-etc-20230730154757.zip differ
diff --git a/restagent/backup/upf-upf_sz_rd_109-etc-20230801003934.zip b/restagent/backup/upf-upf_sz_rd_109-etc-20230801003934.zip
new file mode 100644
index 00000000..d8c01daa
Binary files /dev/null and b/restagent/backup/upf-upf_sz_rd_109-etc-20230801003934.zip differ
diff --git a/restagent/config/config.go b/restagent/config/config.go
new file mode 100644
index 00000000..28793faa
--- /dev/null
+++ b/restagent/config/config.go
@@ -0,0 +1,315 @@
+package config
+
+import (
+ "flag"
+ "fmt"
+ "os"
+ "strings"
+
+ "ems.agt/lib/global"
+ "ems.agt/lib/log"
+
+ "gopkg.in/yaml.v3"
+)
+
+type DbConfig struct {
+ Type string `yaml:"type"`
+ User string `yaml:"user"`
+ Password string `yaml:"password"`
+ Host string `yaml:"host"`
+ Port string `yaml:"port"`
+ Name string `yaml:"name"`
+ Backup string `yaml:"backup"`
+}
+
+// Yaml struct of config
+type YamlConfig struct {
+ Logger struct {
+ File string `yaml:"file"`
+ Level string `yaml:"level"`
+ Duration int `yaml:"duration"`
+ Count int `yaml:"count"`
+ } `yaml:"logger"`
+
+ Rest []struct {
+ IPv4 string `yaml:"ipv4"`
+ IPv6 string `yaml:"ipv6"`
+ Port uint16 `yaml:"port"`
+ } `yaml:"rest"`
+
+ Database DbConfig `yaml:"database"`
+
+ OMC struct {
+ UriPrefix string `yaml:"uriPrefix"`
+ NeType string `yaml:"neType"`
+ NeId string `yaml:"neId"`
+ RmUID string `yaml:"rmUID"`
+ NeName string `yaml:"neName"`
+ Province string `yaml:"province"`
+ Vendor string `yaml:"vendor"`
+ Dn string `yaml:"dn"`
+ Chk2Ne bool `yaml:"chk2ne"`
+ Sn string `yaml:"sn"`
+ CheckSign bool `yaml:"checksign"`
+ Backup string `yaml:"backup"`
+ Upload string `yaml:"upload"`
+ FrontUpload string `yaml:"frontUpload"`
+ Software string `yaml:"software"`
+ License string `yaml:"license"`
+ GtpUri string `yaml:"gtpUri"`
+ CheckContentType bool `yaml:"checkContentType"`
+ TestMode bool `yaml:"testMode"`
+ } `yaml:"omc"`
+
+ Alarm struct {
+ ForwardAlarm bool `yaml:"forwardAlarm"`
+ Email struct {
+ Smtp string `yaml:"smtp"`
+ Port uint16 `yaml:"port"`
+ User string `yaml:"user"`
+ Password string `yaml:"password"`
+ } `json:"email"`
+ SMS struct {
+ ApiURL string `yaml:"apiURL"`
+ AccessKeyID string `yaml:"AccessKeyID"`
+ AccessKeySecret string `yaml:"accessKeySecret"`
+ SignName string `yaml:"signName"`
+ TemplateCode string `yaml:"templateCode"`
+ } `json:"sms"`
+ } `yaml:"alarm"`
+
+ MML struct {
+ Port int `yaml:"port"`
+ Sleep int64 `yaml:"sleep"`
+ User string `yaml:"user"`
+ Password string `ymal:"password"`
+ } `yaml:"mml"`
+
+ NE struct {
+ Addr string `yaml:"addr"`
+ Port uint16 `yaml:"port"`
+ User string `yaml:"user"`
+ EtcDir string `yaml:"etcdir"`
+ BinDir string `yaml:"bindir"`
+ OmcDir string `yaml:"omcdir"`
+ LicenseDir string `yaml:"licensedir"`
+ } `yaml:"ne"`
+
+ Auth struct {
+ Crypt string `yaml:"crypt"`
+ Token bool `yaml:"token"`
+ Expires uint32 `yaml:"expires"`
+ Session string `yaml:"session"`
+ } `yaml:"auth"`
+
+ Params struct {
+ RmUIDMaxNum int `yaml:"rmuidmaxnum"`
+ AlarmIDMaxNum int `yaml:"alarmidmaxnum"`
+ PmIDMaxNum int `yaml:"pmidmaxnum"`
+ SubIDMaxNum int `yaml:"subidmaxnum"`
+ UriMaxLen int `yaml:"urimaxlen"`
+ RmUIDRegexp string `yaml:"rmuidregexp"`
+ } `yaml:"params"`
+
+ TestConfig struct {
+ Enabled bool `yaml:"enabled"`
+ File string `yaml:"file"`
+ } `yaml:"testConfig"`
+}
+
+type TestDatas struct {
+ UDM struct {
+ CapUsed uint32 `yaml:"capUsed"`
+ FeatureEnabled []string `yaml:"featureEnabled"`
+ } `yaml:"udm"`
+ AUSF struct {
+ CapUsed uint32 `yaml:"capUsed"`
+ FeatureEnabled []string `yaml:"featureEnabled"`
+ } `yaml:"ausf"`
+ AMF struct {
+ CapUsed uint32 `yaml:"capUsed"`
+ FeatureEnabled []string `yaml:"featureEnabled"`
+ } `yaml:"amf"`
+ SMF struct {
+ CapUsed uint32 `yaml:"capUsed"`
+ FeatureEnabled []string `yaml:"featureEnabled"`
+ } `yaml:"smf"`
+ UPF struct {
+ CapUsed uint32 `yaml:"capUsed"`
+ FeatureEnabled []string `yaml:"featureEnabled"`
+ } `yaml:"upf"`
+}
+
+type NeTestData struct {
+ CapUsed uint32 `yaml:"capUsed"`
+ FeatureEnabled []string `yaml:"featureEnabled"`
+}
+type TestDataMap struct {
+ NeTestDatas []map[string]NeTestData
+}
+
+var yamlConfig YamlConfig
+
+func ReadConfig(configFile string) {
+ yamlFile, err := os.ReadFile(configFile)
+ if err != nil {
+ fmt.Println("Read yaml config file error:", err)
+ os.Exit(2)
+ }
+ // fmt.Println("yamlfile:", string(yamlFile))
+
+ err = yaml.Unmarshal(yamlFile, &yamlConfig)
+ if err != nil {
+ fmt.Println("Unmarshal error:", err)
+ os.Exit(3)
+ }
+}
+
+func WriteYamlConfig(newConfigData YamlConfig, configFile string) {
+ // 将配置转换回YAML数据
+ newYamlData, err := yaml.Marshal(&newConfigData)
+ if err != nil {
+ log.Errorf("Failed to marshal YAML: %v", err)
+ }
+
+ // 将新的YAML数据写入文件
+ err = os.WriteFile(configFile, newYamlData, 0644)
+ if err != nil {
+ log.Errorf("Failed to write YAML file: %v", err)
+ }
+}
+
+var mapYaml map[string]interface{}
+
+func ReadParamConfig(fileName string) *map[string]interface{} {
+ file, err := os.ReadFile(fileName)
+ if err != nil {
+ fmt.Println("Read yaml file error:", err)
+ }
+
+ mapYaml = make(map[string]interface{})
+
+ err = yaml.Unmarshal(file, &mapYaml)
+ if err != nil {
+ fmt.Printf("yaml.Unmarshal: %v when to struct", err)
+ }
+ // fmt.Println("mapYaml:", mapYaml)
+
+ return &mapYaml
+}
+
+func GetYamlConfig() *YamlConfig {
+ return &yamlConfig
+}
+
+func GetAuthFromConfig() interface{} {
+ return yamlConfig.Auth
+}
+
+func GetExpiresFromConfig() uint32 {
+ return yamlConfig.Auth.Expires
+}
+
+func GetRmUIDFromConfig() string {
+ return yamlConfig.OMC.RmUID
+}
+
+func GetRmUIDRegexpFromConfig() string {
+ return yamlConfig.Params.RmUIDRegexp
+}
+
+func GetRmUIDMaxNumFromConfig() int {
+ return yamlConfig.Params.RmUIDMaxNum
+}
+
+func GetAlarmIDMaxNumFromConfig() int {
+ return yamlConfig.Params.AlarmIDMaxNum
+}
+
+func GetPmIDMaxNumFromConfig() int {
+ return yamlConfig.Params.PmIDMaxNum
+}
+
+func GetSubIDMaxNumFromConfig() int {
+ return yamlConfig.Params.SubIDMaxNum
+}
+
+func GetUriMaxLenFromConfig() int {
+ return yamlConfig.Params.UriMaxLen
+}
+
+func GetLogLevel() log.LogLevel {
+ var logLevel log.LogLevel
+ switch strings.ToLower(yamlConfig.Logger.Level) {
+ case "trace":
+ logLevel = log.LOG_TRACE
+ case "info":
+ logLevel = log.LOG_INFO
+ case "debug":
+ logLevel = log.LOG_DEBUG
+ case "warn":
+ logLevel = log.LOG_WARN
+ case "error":
+ logLevel = log.LOG_ERROR
+ case "fatal":
+ logLevel = log.LOG_FATAL
+ case "off":
+ logLevel = log.LOG_OFF
+ default:
+ logLevel = log.LOG_DEBUG
+ }
+ return logLevel
+}
+
+var (
+ UriPrefix string = "/api/rest"
+ //TestDataUDM []map[string]interface{}
+ TDatas map[string]NeTestData
+)
+
+func ReadTestConfigYaml(pfile string) (ret error) {
+ file, err := os.ReadFile(pfile)
+ if err != nil {
+ return err
+ }
+
+ err = yaml.Unmarshal(file, &TDatas)
+ if err != nil {
+ fmt.Println("Failed to Unmarshal:", err)
+ return err
+ }
+
+ return nil
+}
+
+func GetDefaultUserAgent() string {
+ return "OMC-restagent/" + global.Version
+}
+
+const defaultConfigFile = "./etc/restconf.yaml"
+
+func init() {
+ cfile := flag.String("c", defaultConfigFile, "config file")
+ pv := flag.Bool("v", false, "print version")
+ ph := flag.Bool("h", false, "print help")
+
+ global.BuildTime = "Wed May 31 18:24:04 CST 2023"
+ global.GoVer = "go version go1.15.7 linux/arm64"
+ flag.Parse()
+ if *pv {
+ fmt.Printf("OMC restagent version: %s\n%s\n%s\n\n", global.Version, global.BuildTime, global.GoVer)
+ os.Exit(0)
+ }
+ if *ph {
+ flag.Usage()
+ os.Exit(0)
+ }
+
+ ReadConfig(*cfile)
+ if GetYamlConfig().OMC.UriPrefix != "" {
+ UriPrefix = GetYamlConfig().OMC.UriPrefix
+ }
+ if GetYamlConfig().TestConfig.Enabled {
+ ReadTestConfigYaml(GetYamlConfig().TestConfig.File)
+ }
+}
diff --git a/restagent/config/map.go b/restagent/config/map.go
new file mode 100644
index 00000000..50a28c77
--- /dev/null
+++ b/restagent/config/map.go
@@ -0,0 +1,111 @@
+package config
+
+import (
+ "io/ioutil"
+ "log"
+
+ "gopkg.in/yaml.v3"
+
+ "ems.agt/lib/global"
+)
+
+type Uri2Object struct {
+ Uri string `yaml:"uri"`
+ Object []Object `yaml:"object"`
+}
+
+type Object struct {
+ Name string `yaml:"name"`
+ Syntax string `yaml:"syntax"`
+ Oid string `yaml:"oid"`
+}
+
+var uri2Object []Uri2Object
+
+func ReadMap(pfile string) (ret error) {
+ file, err := ioutil.ReadFile(pfile)
+ if err != nil {
+ log.Println(err)
+ return err
+ }
+
+ err = yaml.Unmarshal(file, &uri2Object)
+ if err != nil {
+ log.Println(err)
+ return err
+ }
+ /*
+ for _, v := range uri2Object {
+ log.Println(v)
+ }
+ */
+ return nil
+}
+
+func GetOid(uri string, oids *[]string) *[]string {
+ for _, v := range uri2Object {
+ if uri == v.Uri {
+ for _, o := range v.Object {
+ *oids = append(*oids, o.Oid)
+ }
+ }
+ }
+
+ return oids
+}
+
+func GetOidByFileds(uri string, fields []string, oids *[]string) *[]string {
+ for _, v := range uri2Object {
+ if uri == v.Uri {
+ for _, o := range v.Object {
+ if global.IsContain(o.Name, fields) || len(fields) == 0 {
+ *oids = append(*oids, o.Oid)
+ }
+ }
+ }
+ }
+
+ return oids
+}
+
+type NameOid struct {
+ Name string
+ Oid string
+}
+
+type NameValue struct {
+ Name string
+ Value string
+}
+
+func GetDataOid(Uri string, nameOids *[]NameOid) *[]NameOid {
+ var nameOid NameOid
+ for _, v := range uri2Object {
+ if Uri == v.Uri {
+ for _, o := range v.Object {
+ nameOid.Name = o.Name
+ nameOid.Oid = o.Oid
+ *nameOids = append(*nameOids, nameOid)
+ }
+ }
+ }
+
+ return nameOids
+}
+
+func GetDataOidByFields(uri string, fields []string, nameOids *[]NameOid) *[]NameOid {
+ var nameOid NameOid
+ for _, v := range uri2Object {
+ if uri == v.Uri {
+ for _, o := range v.Object {
+ nameOid.Name = o.Name
+ nameOid.Oid = o.Oid
+ if len(fields) == 0 || global.IsContainP(nameOid.Name, &fields, len(fields)) {
+ *nameOids = append(*nameOids, nameOid)
+ }
+ }
+ }
+ }
+
+ return nameOids
+}
diff --git a/restagent/database/measure_data-20230810002000.csv b/restagent/database/measure_data-20230810002000.csv
new file mode 100644
index 00000000..ac702dce
--- /dev/null
+++ b/restagent/database/measure_data-20230810002000.csv
@@ -0,0 +1,1188 @@
+id,date,task_id,ne_name,rm_uid,ne_type,granul_option,kpi_code,kpi_id,kpi_ext,start_time,end_time,value,timestamp
+321902,2023-07-10,40,UDM,,UDM,15M,UDMHA07,UDM.SmfUecmRegReq,total,2023-07-10 09:50:13,2023-07-10 10:06:01,5724,2023-07-10 10:06:01
+321903,2023-07-10,40,UDM,,UDM,15M,UDMHA19,UDM.SdmGetUserNotFound,total,2023-07-10 09:50:13,2023-07-10 10:06:01,0,2023-07-10 10:06:01
+321904,2023-07-10,40,UDM,,UDM,15M,UDMHA05,UDM.AmfUecmDeregReq,total,2023-07-10 09:50:13,2023-07-10 10:06:01,1985,2023-07-10 10:06:01
+321905,2023-07-10,40,UDM,,UDM,15M,UDMHA18,UDM.UecmDeregNotif,total,2023-07-10 09:50:13,2023-07-10 10:06:01,0,2023-07-10 10:06:01
+321906,2023-07-10,40,UDM,,UDM,15M,UDMHC01,Ausf.UeAuthReq,total,2023-07-10 09:50:13,2023-07-10 10:06:01,2673,2023-07-10 10:06:01
+321907,2023-07-10,40,UDM,,UDM,15M,UDMHC03,Ausf.UeAuthAnsUserNotFound,total,2023-07-10 09:50:13,2023-07-10 10:06:01,0,2023-07-10 10:06:01
+321908,2023-07-10,40,UDM,,UDM,15M,UDMHA01,UDM.AmfUecmRegReq,total,2023-07-10 09:50:13,2023-07-10 10:06:01,2676,2023-07-10 10:06:01
+321909,2023-07-10,40,UDM,,UDM,15M,UDMHA21,UDM.AmfUecmRegUserNotFound,total,2023-07-10 09:50:13,2023-07-10 10:06:01,0,2023-07-10 10:06:01
+321910,2023-07-10,40,UDM,,UDM,15M,UDMHA24,UDM.AmfUecmRegRoamNotAllowed,total,2023-07-10 09:50:13,2023-07-10 10:06:01,0,2023-07-10 10:06:01
+321911,2023-07-10,40,UDM,,UDM,15M,UDMHC02,Ausf.UeAuthAnsSucc,total,2023-07-10 09:50:13,2023-07-10 10:06:01,2673,2023-07-10 10:06:01
+321912,2023-07-10,40,UDM,,UDM,15M,UDMHB03,UDR.5gActSub,total,2023-07-10 09:50:13,2023-07-10 10:06:01,71573,2023-07-10 10:06:01
+321913,2023-07-10,40,UDM,,UDM,15M,UDMHD01,ME.MeanMeLoad,total,2023-07-10 09:50:13,2023-07-10 10:06:01,0,2023-07-10 10:06:01
+321914,2023-07-10,40,UDM,,UDM,15M,UDMHA02,UDM.AmfUecmRegSucc,total,2023-07-10 09:50:13,2023-07-10 10:06:01,2676,2023-07-10 10:06:01
+321915,2023-07-10,40,UDM,,UDM,15M,UDMHA17,UDM.SdmUnSubscrSucc,total,2023-07-10 09:50:13,2023-07-10 10:06:01,6304,2023-07-10 10:06:01
+321916,2023-07-10,40,UDM,,UDM,15M,UDMHA26,UDM.AmfUecmRegContextNotFound,total,2023-07-10 09:50:13,2023-07-10 10:06:01,0,2023-07-10 10:06:01
+321917,2023-07-10,40,UDM,,UDM,15M,UDMHA29,UDM.SmfUecmRegUnknownSub,total,2023-07-10 09:50:13,2023-07-10 10:06:01,0,2023-07-10 10:06:01
+321918,2023-07-10,40,UDM,,UDM,15M,UDMHB01,UDR.5gSupi,total,2023-07-10 09:50:13,2023-07-10 10:06:01,0,2023-07-10 10:06:01
+321919,2023-07-10,40,UDM,,UDM,15M,UDMHA27,UDM.AmfUecmRegReAuth,total,2023-07-10 09:50:13,2023-07-10 10:06:01,0,2023-07-10 10:06:01
+321920,2023-07-10,40,UDM,,UDM,15M,UDMHA03,UDM.AmfUecmRegUpdateReq,total,2023-07-10 09:50:13,2023-07-10 10:06:01,0,2023-07-10 10:06:01
+321921,2023-07-10,40,UDM,,UDM,15M,UDMHA08,UDM.SmfUecmRegSucc,total,2023-07-10 09:50:13,2023-07-10 10:06:01,5724,2023-07-10 10:06:01
+321922,2023-07-10,40,UDM,,UDM,15M,UDMHA09,UDM.SmfUecmDeregReq,total,2023-07-10 09:50:13,2023-07-10 10:06:01,4319,2023-07-10 10:06:01
+321923,2023-07-10,40,UDM,,UDM,15M,UDMHA16,UDM.SdmUnSubscrReq,total,2023-07-10 09:50:13,2023-07-10 10:06:01,6304,2023-07-10 10:06:01
+321924,2023-07-10,40,UDM,,UDM,15M,UDMHA25,UDM.AmfUecmRegRatNotAllowed,total,2023-07-10 09:50:13,2023-07-10 10:06:01,0,2023-07-10 10:06:01
+321925,2023-07-10,40,UDM,,UDM,15M,UDMHA04,UDM.AmfUecmRegUpdateSucc,total,2023-07-10 09:50:13,2023-07-10 10:06:01,0,2023-07-10 10:06:01
+321926,2023-07-10,40,UDM,,UDM,15M,UDMHA11,UDM.SdmGetReq,total,2023-07-10 09:50:13,2023-07-10 10:06:01,13752,2023-07-10 10:06:01
+321927,2023-07-10,40,UDM,,UDM,15M,UDMHA13,UDM.SdmNotif,total,2023-07-10 09:50:13,2023-07-10 10:06:01,0,2023-07-10 10:06:01
+321928,2023-07-10,40,UDM,,UDM,15M,UDMHA15,UDM.SdmSubscrSucc,total,2023-07-10 09:50:13,2023-07-10 10:06:01,8400,2023-07-10 10:06:01
+321929,2023-07-10,40,UDM,,UDM,15M,UDMHA30,UDM.SmfUecmRegRoamNotAllowed,total,2023-07-10 09:50:13,2023-07-10 10:06:01,0,2023-07-10 10:06:01
+321930,2023-07-10,40,UDM,,UDM,15M,UDMHB02,UDR.5gSub,total,2023-07-10 09:50:13,2023-07-10 10:06:01,0,2023-07-10 10:06:01
+321931,2023-07-10,40,UDM,,UDM,15M,UDMHA22,UDM.AmfUecmRegUnknownSub,total,2023-07-10 09:50:13,2023-07-10 10:06:01,0,2023-07-10 10:06:01
+321932,2023-07-10,40,UDM,,UDM,15M,UDMHA23,UDM.AmfUecmRegNoPsSub,total,2023-07-10 09:50:13,2023-07-10 10:06:01,0,2023-07-10 10:06:01
+321933,2023-07-10,40,UDM,,UDM,15M,UDMHA28,UDM.SmfUecmRegUserNotFound,total,2023-07-10 09:50:13,2023-07-10 10:06:01,0,2023-07-10 10:06:01
+321934,2023-07-10,40,UDM,,UDM,15M,UDMHA06,UDM.AmfUecmDeregSucc,total,2023-07-10 09:50:13,2023-07-10 10:06:01,1985,2023-07-10 10:06:01
+321935,2023-07-10,40,UDM,,UDM,15M,UDMHA10,UDM.SmfUecmDeregSucc,total,2023-07-10 09:50:13,2023-07-10 10:06:01,4319,2023-07-10 10:06:01
+321936,2023-07-10,40,UDM,,UDM,15M,UDMHA12,UDM.SdmGetSucc,total,2023-07-10 09:50:13,2023-07-10 10:06:01,13752,2023-07-10 10:06:01
+321937,2023-07-10,40,UDM,,UDM,15M,UDMHA14,UDM.SdmSubscrReq,total,2023-07-10 09:50:13,2023-07-10 10:06:01,8400,2023-07-10 10:06:01
+321938,2023-07-10,40,UDM,,UDM,15M,UDMHA20,UDM.SdmGetDataNotFound,total,2023-07-10 09:50:13,2023-07-10 10:06:01,0,2023-07-10 10:06:01
+321939,2023-07-10,40,UDM,,UDM,15M,UDMHA31,UDM.SmfUecmRegDnnNotAllowed,total,2023-07-10 09:50:13,2023-07-10 10:06:01,0,2023-07-10 10:06:01
+321940,2023-07-10,40,UDM,,UDM,15M,UDMHC04,Ausf.UeAuthAnsContextNotFound,total,2023-07-10 09:50:13,2023-07-10 10:06:01,0,2023-07-10 10:06:01
+321941,2023-07-10,40,UDM,,UDM,15M,UDMHB02,UDR.5gSub,total,2023-07-10 10:06:01,2023-07-10 10:21:01,0,2023-07-10 10:21:01
+321942,2023-07-10,40,UDM,,UDM,15M,UDMHA10,UDM.SmfUecmDeregSucc,total,2023-07-10 10:06:01,2023-07-10 10:21:01,4468,2023-07-10 10:21:01
+321943,2023-07-10,40,UDM,,UDM,15M,UDMHA12,UDM.SdmGetSucc,total,2023-07-10 10:06:01,2023-07-10 10:21:01,9824,2023-07-10 10:21:01
+321944,2023-07-10,40,UDM,,UDM,15M,UDMHA14,UDM.SdmSubscrReq,total,2023-07-10 10:06:01,2023-07-10 10:21:01,6250,2023-07-10 10:21:01
+321945,2023-07-10,40,UDM,,UDM,15M,UDMHA20,UDM.SdmGetDataNotFound,total,2023-07-10 10:06:01,2023-07-10 10:21:01,0,2023-07-10 10:21:01
+321946,2023-07-10,40,UDM,,UDM,15M,UDMHA22,UDM.AmfUecmRegUnknownSub,total,2023-07-10 10:06:01,2023-07-10 10:21:01,0,2023-07-10 10:21:01
+321947,2023-07-10,40,UDM,,UDM,15M,UDMHA23,UDM.AmfUecmRegNoPsSub,total,2023-07-10 10:06:01,2023-07-10 10:21:01,0,2023-07-10 10:21:01
+321948,2023-07-10,40,UDM,,UDM,15M,UDMHA28,UDM.SmfUecmRegUserNotFound,total,2023-07-10 10:06:01,2023-07-10 10:21:01,0,2023-07-10 10:21:01
+321949,2023-07-10,40,UDM,,UDM,15M,UDMHA06,UDM.AmfUecmDeregSucc,total,2023-07-10 10:06:01,2023-07-10 10:21:01,1789,2023-07-10 10:21:01
+321950,2023-07-10,40,UDM,,UDM,15M,UDMHC04,Ausf.UeAuthAnsContextNotFound,total,2023-07-10 10:06:01,2023-07-10 10:21:01,0,2023-07-10 10:21:01
+321951,2023-07-10,40,UDM,,UDM,15M,UDMHA31,UDM.SmfUecmRegDnnNotAllowed,total,2023-07-10 10:06:01,2023-07-10 10:21:01,0,2023-07-10 10:21:01
+321952,2023-07-10,40,UDM,,UDM,15M,UDMHA19,UDM.SdmGetUserNotFound,total,2023-07-10 10:06:01,2023-07-10 10:21:01,0,2023-07-10 10:21:01
+321953,2023-07-10,40,UDM,,UDM,15M,UDMHA07,UDM.SmfUecmRegReq,total,2023-07-10 10:06:01,2023-07-10 10:21:01,4463,2023-07-10 10:21:01
+321954,2023-07-10,40,UDM,,UDM,15M,UDMHA18,UDM.UecmDeregNotif,total,2023-07-10 10:06:01,2023-07-10 10:21:01,0,2023-07-10 10:21:01
+321955,2023-07-10,40,UDM,,UDM,15M,UDMHC01,Ausf.UeAuthReq,total,2023-07-10 10:06:01,2023-07-10 10:21:01,1788,2023-07-10 10:21:01
+321956,2023-07-10,40,UDM,,UDM,15M,UDMHC03,Ausf.UeAuthAnsUserNotFound,total,2023-07-10 10:06:01,2023-07-10 10:21:01,0,2023-07-10 10:21:01
+321957,2023-07-10,40,UDM,,UDM,15M,UDMHA05,UDM.AmfUecmDeregReq,total,2023-07-10 10:06:01,2023-07-10 10:21:01,1789,2023-07-10 10:21:01
+321958,2023-07-10,40,UDM,,UDM,15M,UDMHA21,UDM.AmfUecmRegUserNotFound,total,2023-07-10 10:06:01,2023-07-10 10:21:01,0,2023-07-10 10:21:01
+321959,2023-07-10,40,UDM,,UDM,15M,UDMHA24,UDM.AmfUecmRegRoamNotAllowed,total,2023-07-10 10:06:01,2023-07-10 10:21:01,0,2023-07-10 10:21:01
+321960,2023-07-10,40,UDM,,UDM,15M,UDMHC02,Ausf.UeAuthAnsSucc,total,2023-07-10 10:06:01,2023-07-10 10:21:01,1788,2023-07-10 10:21:01
+321961,2023-07-10,40,UDM,,UDM,15M,UDMHA01,UDM.AmfUecmRegReq,total,2023-07-10 10:06:01,2023-07-10 10:21:01,1787,2023-07-10 10:21:01
+321962,2023-07-10,40,UDM,,UDM,15M,UDMHA17,UDM.SdmUnSubscrSucc,total,2023-07-10 10:06:01,2023-07-10 10:21:01,6257,2023-07-10 10:21:01
+321963,2023-07-10,40,UDM,,UDM,15M,UDMHA26,UDM.AmfUecmRegContextNotFound,total,2023-07-10 10:06:01,2023-07-10 10:21:01,0,2023-07-10 10:21:01
+321964,2023-07-10,40,UDM,,UDM,15M,UDMHA29,UDM.SmfUecmRegUnknownSub,total,2023-07-10 10:06:01,2023-07-10 10:21:01,0,2023-07-10 10:21:01
+321965,2023-07-10,40,UDM,,UDM,15M,UDMHB01,UDR.5gSupi,total,2023-07-10 10:06:01,2023-07-10 10:21:01,0,2023-07-10 10:21:01
+321966,2023-07-10,40,UDM,,UDM,15M,UDMHB03,UDR.5gActSub,total,2023-07-10 10:06:01,2023-07-10 10:21:01,71571,2023-07-10 10:21:01
+321967,2023-07-10,40,UDM,,UDM,15M,UDMHD01,ME.MeanMeLoad,total,2023-07-10 10:06:01,2023-07-10 10:21:01,0,2023-07-10 10:21:01
+321968,2023-07-10,40,UDM,,UDM,15M,UDMHA02,UDM.AmfUecmRegSucc,total,2023-07-10 10:06:01,2023-07-10 10:21:01,1787,2023-07-10 10:21:01
+321969,2023-07-10,40,UDM,,UDM,15M,UDMHA08,UDM.SmfUecmRegSucc,total,2023-07-10 10:06:01,2023-07-10 10:21:01,4463,2023-07-10 10:21:01
+321970,2023-07-10,40,UDM,,UDM,15M,UDMHA09,UDM.SmfUecmDeregReq,total,2023-07-10 10:06:01,2023-07-10 10:21:01,4468,2023-07-10 10:21:01
+321971,2023-07-10,40,UDM,,UDM,15M,UDMHA16,UDM.SdmUnSubscrReq,total,2023-07-10 10:06:01,2023-07-10 10:21:01,6257,2023-07-10 10:21:01
+321972,2023-07-10,40,UDM,,UDM,15M,UDMHA25,UDM.AmfUecmRegRatNotAllowed,total,2023-07-10 10:06:01,2023-07-10 10:21:01,0,2023-07-10 10:21:01
+321973,2023-07-10,40,UDM,,UDM,15M,UDMHA27,UDM.AmfUecmRegReAuth,total,2023-07-10 10:06:01,2023-07-10 10:21:01,0,2023-07-10 10:21:01
+321974,2023-07-10,40,UDM,,UDM,15M,UDMHA03,UDM.AmfUecmRegUpdateReq,total,2023-07-10 10:06:01,2023-07-10 10:21:01,0,2023-07-10 10:21:01
+321975,2023-07-10,40,UDM,,UDM,15M,UDMHA11,UDM.SdmGetReq,total,2023-07-10 10:06:01,2023-07-10 10:21:01,9824,2023-07-10 10:21:01
+321976,2023-07-10,40,UDM,,UDM,15M,UDMHA13,UDM.SdmNotif,total,2023-07-10 10:06:01,2023-07-10 10:21:01,0,2023-07-10 10:21:01
+321977,2023-07-10,40,UDM,,UDM,15M,UDMHA15,UDM.SdmSubscrSucc,total,2023-07-10 10:06:01,2023-07-10 10:21:01,6250,2023-07-10 10:21:01
+321978,2023-07-10,40,UDM,,UDM,15M,UDMHA30,UDM.SmfUecmRegRoamNotAllowed,total,2023-07-10 10:06:01,2023-07-10 10:21:01,0,2023-07-10 10:21:01
+321979,2023-07-10,40,UDM,,UDM,15M,UDMHA04,UDM.AmfUecmRegUpdateSucc,total,2023-07-10 10:06:01,2023-07-10 10:21:01,0,2023-07-10 10:21:01
+321980,2023-07-10,40,UDM,,UDM,15M,UDMHA05,UDM.AmfUecmDeregReq,total,2023-07-10 10:21:01,2023-07-10 10:36:01,1793,2023-07-10 10:36:01
+321981,2023-07-10,40,UDM,,UDM,15M,UDMHA18,UDM.UecmDeregNotif,total,2023-07-10 10:21:01,2023-07-10 10:36:01,0,2023-07-10 10:36:01
+321982,2023-07-10,40,UDM,,UDM,15M,UDMHC01,Ausf.UeAuthReq,total,2023-07-10 10:21:01,2023-07-10 10:36:01,1792,2023-07-10 10:36:01
+321983,2023-07-10,40,UDM,,UDM,15M,UDMHC03,Ausf.UeAuthAnsUserNotFound,total,2023-07-10 10:21:01,2023-07-10 10:36:01,0,2023-07-10 10:36:01
+321984,2023-07-10,40,UDM,,UDM,15M,UDMHA01,UDM.AmfUecmRegReq,total,2023-07-10 10:21:01,2023-07-10 10:36:01,1793,2023-07-10 10:36:01
+321985,2023-07-10,40,UDM,,UDM,15M,UDMHA21,UDM.AmfUecmRegUserNotFound,total,2023-07-10 10:21:01,2023-07-10 10:36:01,0,2023-07-10 10:36:01
+321986,2023-07-10,40,UDM,,UDM,15M,UDMHA24,UDM.AmfUecmRegRoamNotAllowed,total,2023-07-10 10:21:01,2023-07-10 10:36:01,0,2023-07-10 10:36:01
+321987,2023-07-10,40,UDM,,UDM,15M,UDMHC02,Ausf.UeAuthAnsSucc,total,2023-07-10 10:21:01,2023-07-10 10:36:01,1792,2023-07-10 10:36:01
+321988,2023-07-10,40,UDM,,UDM,15M,UDMHB01,UDR.5gSupi,total,2023-07-10 10:21:01,2023-07-10 10:36:01,0,2023-07-10 10:36:01
+321989,2023-07-10,40,UDM,,UDM,15M,UDMHB03,UDR.5gActSub,total,2023-07-10 10:21:01,2023-07-10 10:36:01,71571,2023-07-10 10:36:01
+321990,2023-07-10,40,UDM,,UDM,15M,UDMHD01,ME.MeanMeLoad,total,2023-07-10 10:21:01,2023-07-10 10:36:01,0,2023-07-10 10:36:01
+321991,2023-07-10,40,UDM,,UDM,15M,UDMHA02,UDM.AmfUecmRegSucc,total,2023-07-10 10:21:01,2023-07-10 10:36:01,1793,2023-07-10 10:36:01
+321992,2023-07-10,40,UDM,,UDM,15M,UDMHA17,UDM.SdmUnSubscrSucc,total,2023-07-10 10:21:01,2023-07-10 10:36:01,6268,2023-07-10 10:36:01
+321993,2023-07-10,40,UDM,,UDM,15M,UDMHA26,UDM.AmfUecmRegContextNotFound,total,2023-07-10 10:21:01,2023-07-10 10:36:01,0,2023-07-10 10:36:01
+321994,2023-07-10,40,UDM,,UDM,15M,UDMHA29,UDM.SmfUecmRegUnknownSub,total,2023-07-10 10:21:01,2023-07-10 10:36:01,0,2023-07-10 10:36:01
+321995,2023-07-10,40,UDM,,UDM,15M,UDMHA25,UDM.AmfUecmRegRatNotAllowed,total,2023-07-10 10:21:01,2023-07-10 10:36:01,0,2023-07-10 10:36:01
+321996,2023-07-10,40,UDM,,UDM,15M,UDMHA27,UDM.AmfUecmRegReAuth,total,2023-07-10 10:21:01,2023-07-10 10:36:01,0,2023-07-10 10:36:01
+321997,2023-07-10,40,UDM,,UDM,15M,UDMHA03,UDM.AmfUecmRegUpdateReq,total,2023-07-10 10:21:01,2023-07-10 10:36:01,0,2023-07-10 10:36:01
+321998,2023-07-10,40,UDM,,UDM,15M,UDMHA08,UDM.SmfUecmRegSucc,total,2023-07-10 10:21:01,2023-07-10 10:36:01,4479,2023-07-10 10:36:01
+321999,2023-07-10,40,UDM,,UDM,15M,UDMHA09,UDM.SmfUecmDeregReq,total,2023-07-10 10:21:01,2023-07-10 10:36:01,4475,2023-07-10 10:36:01
+322000,2023-07-10,40,UDM,,UDM,15M,UDMHA16,UDM.SdmUnSubscrReq,total,2023-07-10 10:21:01,2023-07-10 10:36:01,6268,2023-07-10 10:36:01
+322001,2023-07-10,40,UDM,,UDM,15M,UDMHA30,UDM.SmfUecmRegRoamNotAllowed,total,2023-07-10 10:21:01,2023-07-10 10:36:01,0,2023-07-10 10:36:01
+322002,2023-07-10,40,UDM,,UDM,15M,UDMHA04,UDM.AmfUecmRegUpdateSucc,total,2023-07-10 10:21:01,2023-07-10 10:36:01,0,2023-07-10 10:36:01
+322003,2023-07-10,40,UDM,,UDM,15M,UDMHA11,UDM.SdmGetReq,total,2023-07-10 10:21:01,2023-07-10 10:36:01,9858,2023-07-10 10:36:01
+322004,2023-07-10,40,UDM,,UDM,15M,UDMHA13,UDM.SdmNotif,total,2023-07-10 10:21:01,2023-07-10 10:36:01,0,2023-07-10 10:36:01
+322005,2023-07-10,40,UDM,,UDM,15M,UDMHA15,UDM.SdmSubscrSucc,total,2023-07-10 10:21:01,2023-07-10 10:36:01,6272,2023-07-10 10:36:01
+322006,2023-07-10,40,UDM,,UDM,15M,UDMHB02,UDR.5gSub,total,2023-07-10 10:21:01,2023-07-10 10:36:01,0,2023-07-10 10:36:01
+322007,2023-07-10,40,UDM,,UDM,15M,UDMHA20,UDM.SdmGetDataNotFound,total,2023-07-10 10:21:01,2023-07-10 10:36:01,0,2023-07-10 10:36:01
+322008,2023-07-10,40,UDM,,UDM,15M,UDMHA22,UDM.AmfUecmRegUnknownSub,total,2023-07-10 10:21:01,2023-07-10 10:36:01,0,2023-07-10 10:36:01
+322009,2023-07-10,40,UDM,,UDM,15M,UDMHA23,UDM.AmfUecmRegNoPsSub,total,2023-07-10 10:21:01,2023-07-10 10:36:01,0,2023-07-10 10:36:01
+322010,2023-07-10,40,UDM,,UDM,15M,UDMHA28,UDM.SmfUecmRegUserNotFound,total,2023-07-10 10:21:01,2023-07-10 10:36:01,0,2023-07-10 10:36:01
+322011,2023-07-10,40,UDM,,UDM,15M,UDMHA06,UDM.AmfUecmDeregSucc,total,2023-07-10 10:21:01,2023-07-10 10:36:01,1793,2023-07-10 10:36:01
+322012,2023-07-10,40,UDM,,UDM,15M,UDMHA10,UDM.SmfUecmDeregSucc,total,2023-07-10 10:21:01,2023-07-10 10:36:01,4475,2023-07-10 10:36:01
+322013,2023-07-10,40,UDM,,UDM,15M,UDMHA12,UDM.SdmGetSucc,total,2023-07-10 10:21:01,2023-07-10 10:36:01,9858,2023-07-10 10:36:01
+322014,2023-07-10,40,UDM,,UDM,15M,UDMHA14,UDM.SdmSubscrReq,total,2023-07-10 10:21:01,2023-07-10 10:36:01,6272,2023-07-10 10:36:01
+322015,2023-07-10,40,UDM,,UDM,15M,UDMHA31,UDM.SmfUecmRegDnnNotAllowed,total,2023-07-10 10:21:01,2023-07-10 10:36:01,0,2023-07-10 10:36:01
+322016,2023-07-10,40,UDM,,UDM,15M,UDMHC04,Ausf.UeAuthAnsContextNotFound,total,2023-07-10 10:21:01,2023-07-10 10:36:01,0,2023-07-10 10:36:01
+322017,2023-07-10,40,UDM,,UDM,15M,UDMHA07,UDM.SmfUecmRegReq,total,2023-07-10 10:21:01,2023-07-10 10:36:01,4479,2023-07-10 10:36:01
+322018,2023-07-10,40,UDM,,UDM,15M,UDMHA19,UDM.SdmGetUserNotFound,total,2023-07-10 10:21:01,2023-07-10 10:36:01,0,2023-07-10 10:36:01
+322019,2023-07-10,40,UDM,,UDM,15M,UDMHA01,UDM.AmfUecmRegReq,total,2023-07-10 10:36:01,2023-07-10 10:51:01,1796,2023-07-10 10:51:01
+322020,2023-07-10,40,UDM,,UDM,15M,UDMHA21,UDM.AmfUecmRegUserNotFound,total,2023-07-10 10:36:01,2023-07-10 10:51:01,0,2023-07-10 10:51:01
+322021,2023-07-10,40,UDM,,UDM,15M,UDMHA24,UDM.AmfUecmRegRoamNotAllowed,total,2023-07-10 10:36:01,2023-07-10 10:51:01,0,2023-07-10 10:51:01
+322022,2023-07-10,40,UDM,,UDM,15M,UDMHC02,Ausf.UeAuthAnsSucc,total,2023-07-10 10:36:01,2023-07-10 10:51:01,1798,2023-07-10 10:51:01
+322023,2023-07-10,40,UDM,,UDM,15M,UDMHB01,UDR.5gSupi,total,2023-07-10 10:36:01,2023-07-10 10:51:01,0,2023-07-10 10:51:01
+322024,2023-07-10,40,UDM,,UDM,15M,UDMHB03,UDR.5gActSub,total,2023-07-10 10:36:01,2023-07-10 10:51:01,71571,2023-07-10 10:51:01
+322025,2023-07-10,40,UDM,,UDM,15M,UDMHD01,ME.MeanMeLoad,total,2023-07-10 10:36:01,2023-07-10 10:51:01,0,2023-07-10 10:51:01
+322026,2023-07-10,40,UDM,,UDM,15M,UDMHA02,UDM.AmfUecmRegSucc,total,2023-07-10 10:36:01,2023-07-10 10:51:01,1796,2023-07-10 10:51:01
+322027,2023-07-10,40,UDM,,UDM,15M,UDMHA17,UDM.SdmUnSubscrSucc,total,2023-07-10 10:36:01,2023-07-10 10:51:01,6282,2023-07-10 10:51:01
+322028,2023-07-10,40,UDM,,UDM,15M,UDMHA26,UDM.AmfUecmRegContextNotFound,total,2023-07-10 10:36:01,2023-07-10 10:51:01,0,2023-07-10 10:51:01
+322029,2023-07-10,40,UDM,,UDM,15M,UDMHA29,UDM.SmfUecmRegUnknownSub,total,2023-07-10 10:36:01,2023-07-10 10:51:01,0,2023-07-10 10:51:01
+322030,2023-07-10,40,UDM,,UDM,15M,UDMHA25,UDM.AmfUecmRegRatNotAllowed,total,2023-07-10 10:36:01,2023-07-10 10:51:01,0,2023-07-10 10:51:01
+322031,2023-07-10,40,UDM,,UDM,15M,UDMHA27,UDM.AmfUecmRegReAuth,total,2023-07-10 10:36:01,2023-07-10 10:51:01,0,2023-07-10 10:51:01
+322032,2023-07-10,40,UDM,,UDM,15M,UDMHA03,UDM.AmfUecmRegUpdateReq,total,2023-07-10 10:36:01,2023-07-10 10:51:01,0,2023-07-10 10:51:01
+322033,2023-07-10,40,UDM,,UDM,15M,UDMHA08,UDM.SmfUecmRegSucc,total,2023-07-10 10:36:01,2023-07-10 10:51:01,4484,2023-07-10 10:51:01
+322034,2023-07-10,40,UDM,,UDM,15M,UDMHA09,UDM.SmfUecmDeregReq,total,2023-07-10 10:36:01,2023-07-10 10:51:01,4486,2023-07-10 10:51:01
+322035,2023-07-10,40,UDM,,UDM,15M,UDMHA16,UDM.SdmUnSubscrReq,total,2023-07-10 10:36:01,2023-07-10 10:51:01,6282,2023-07-10 10:51:01
+322036,2023-07-10,40,UDM,,UDM,15M,UDMHA30,UDM.SmfUecmRegRoamNotAllowed,total,2023-07-10 10:36:01,2023-07-10 10:51:01,0,2023-07-10 10:51:01
+322037,2023-07-10,40,UDM,,UDM,15M,UDMHA04,UDM.AmfUecmRegUpdateSucc,total,2023-07-10 10:36:01,2023-07-10 10:51:01,0,2023-07-10 10:51:01
+322038,2023-07-10,40,UDM,,UDM,15M,UDMHA11,UDM.SdmGetReq,total,2023-07-10 10:36:01,2023-07-10 10:51:01,9872,2023-07-10 10:51:01
+322039,2023-07-10,40,UDM,,UDM,15M,UDMHA13,UDM.SdmNotif,total,2023-07-10 10:36:01,2023-07-10 10:51:01,0,2023-07-10 10:51:01
+322040,2023-07-10,40,UDM,,UDM,15M,UDMHA15,UDM.SdmSubscrSucc,total,2023-07-10 10:36:01,2023-07-10 10:51:01,6280,2023-07-10 10:51:01
+322041,2023-07-10,40,UDM,,UDM,15M,UDMHB02,UDR.5gSub,total,2023-07-10 10:36:01,2023-07-10 10:51:01,0,2023-07-10 10:51:01
+322042,2023-07-10,40,UDM,,UDM,15M,UDMHA20,UDM.SdmGetDataNotFound,total,2023-07-10 10:36:01,2023-07-10 10:51:01,0,2023-07-10 10:51:01
+322043,2023-07-10,40,UDM,,UDM,15M,UDMHA22,UDM.AmfUecmRegUnknownSub,total,2023-07-10 10:36:01,2023-07-10 10:51:01,0,2023-07-10 10:51:01
+322044,2023-07-10,40,UDM,,UDM,15M,UDMHA23,UDM.AmfUecmRegNoPsSub,total,2023-07-10 10:36:01,2023-07-10 10:51:01,0,2023-07-10 10:51:01
+322045,2023-07-10,40,UDM,,UDM,15M,UDMHA28,UDM.SmfUecmRegUserNotFound,total,2023-07-10 10:36:01,2023-07-10 10:51:01,0,2023-07-10 10:51:01
+322046,2023-07-10,40,UDM,,UDM,15M,UDMHA06,UDM.AmfUecmDeregSucc,total,2023-07-10 10:36:01,2023-07-10 10:51:01,1796,2023-07-10 10:51:01
+322047,2023-07-10,40,UDM,,UDM,15M,UDMHA10,UDM.SmfUecmDeregSucc,total,2023-07-10 10:36:01,2023-07-10 10:51:01,4486,2023-07-10 10:51:01
+322048,2023-07-10,40,UDM,,UDM,15M,UDMHA12,UDM.SdmGetSucc,total,2023-07-10 10:36:01,2023-07-10 10:51:01,9872,2023-07-10 10:51:01
+322049,2023-07-10,40,UDM,,UDM,15M,UDMHA14,UDM.SdmSubscrReq,total,2023-07-10 10:36:01,2023-07-10 10:51:01,6280,2023-07-10 10:51:01
+322050,2023-07-10,40,UDM,,UDM,15M,UDMHA31,UDM.SmfUecmRegDnnNotAllowed,total,2023-07-10 10:36:01,2023-07-10 10:51:01,0,2023-07-10 10:51:01
+322051,2023-07-10,40,UDM,,UDM,15M,UDMHC04,Ausf.UeAuthAnsContextNotFound,total,2023-07-10 10:36:01,2023-07-10 10:51:01,0,2023-07-10 10:51:01
+322052,2023-07-10,40,UDM,,UDM,15M,UDMHA07,UDM.SmfUecmRegReq,total,2023-07-10 10:36:01,2023-07-10 10:51:01,4484,2023-07-10 10:51:01
+322053,2023-07-10,40,UDM,,UDM,15M,UDMHA19,UDM.SdmGetUserNotFound,total,2023-07-10 10:36:01,2023-07-10 10:51:01,0,2023-07-10 10:51:01
+322054,2023-07-10,40,UDM,,UDM,15M,UDMHA05,UDM.AmfUecmDeregReq,total,2023-07-10 10:36:01,2023-07-10 10:51:01,1796,2023-07-10 10:51:01
+322055,2023-07-10,40,UDM,,UDM,15M,UDMHA18,UDM.UecmDeregNotif,total,2023-07-10 10:36:01,2023-07-10 10:51:01,0,2023-07-10 10:51:01
+322056,2023-07-10,40,UDM,,UDM,15M,UDMHC01,Ausf.UeAuthReq,total,2023-07-10 10:36:01,2023-07-10 10:51:01,1798,2023-07-10 10:51:01
+322057,2023-07-10,40,UDM,,UDM,15M,UDMHC03,Ausf.UeAuthAnsUserNotFound,total,2023-07-10 10:36:01,2023-07-10 10:51:01,0,2023-07-10 10:51:01
+322058,2023-07-10,40,UDM,,UDM,15M,UDMHA10,UDM.SmfUecmDeregSucc,total,2023-07-10 10:51:01,2023-07-10 11:06:01,4430,2023-07-10 11:06:01
+322059,2023-07-10,40,UDM,,UDM,15M,UDMHA12,UDM.SdmGetSucc,total,2023-07-10 10:51:01,2023-07-10 11:06:01,9754,2023-07-10 11:06:01
+322060,2023-07-10,40,UDM,,UDM,15M,UDMHA14,UDM.SdmSubscrReq,total,2023-07-10 10:51:01,2023-07-10 11:06:01,6206,2023-07-10 11:06:01
+322061,2023-07-10,40,UDM,,UDM,15M,UDMHA20,UDM.SdmGetDataNotFound,total,2023-07-10 10:51:01,2023-07-10 11:06:01,0,2023-07-10 11:06:01
+322062,2023-07-10,40,UDM,,UDM,15M,UDMHA22,UDM.AmfUecmRegUnknownSub,total,2023-07-10 10:51:01,2023-07-10 11:06:01,0,2023-07-10 11:06:01
+322063,2023-07-10,40,UDM,,UDM,15M,UDMHA23,UDM.AmfUecmRegNoPsSub,total,2023-07-10 10:51:01,2023-07-10 11:06:01,0,2023-07-10 11:06:01
+322064,2023-07-10,40,UDM,,UDM,15M,UDMHA28,UDM.SmfUecmRegUserNotFound,total,2023-07-10 10:51:01,2023-07-10 11:06:01,0,2023-07-10 11:06:01
+322065,2023-07-10,40,UDM,,UDM,15M,UDMHA06,UDM.AmfUecmDeregSucc,total,2023-07-10 10:51:01,2023-07-10 11:06:01,1774,2023-07-10 11:06:01
+322066,2023-07-10,40,UDM,,UDM,15M,UDMHC04,Ausf.UeAuthAnsContextNotFound,total,2023-07-10 10:51:01,2023-07-10 11:06:01,0,2023-07-10 11:06:01
+322067,2023-07-10,40,UDM,,UDM,15M,UDMHA31,UDM.SmfUecmRegDnnNotAllowed,total,2023-07-10 10:51:01,2023-07-10 11:06:01,0,2023-07-10 11:06:01
+322068,2023-07-10,40,UDM,,UDM,15M,UDMHA19,UDM.SdmGetUserNotFound,total,2023-07-10 10:51:01,2023-07-10 11:06:01,0,2023-07-10 11:06:01
+322069,2023-07-10,40,UDM,,UDM,15M,UDMHA07,UDM.SmfUecmRegReq,total,2023-07-10 10:51:01,2023-07-10 11:06:01,4432,2023-07-10 11:06:01
+322070,2023-07-10,40,UDM,,UDM,15M,UDMHA18,UDM.UecmDeregNotif,total,2023-07-10 10:51:01,2023-07-10 11:06:01,0,2023-07-10 11:06:01
+322071,2023-07-10,40,UDM,,UDM,15M,UDMHC01,Ausf.UeAuthReq,total,2023-07-10 10:51:01,2023-07-10 11:06:01,1774,2023-07-10 11:06:01
+322072,2023-07-10,40,UDM,,UDM,15M,UDMHC03,Ausf.UeAuthAnsUserNotFound,total,2023-07-10 10:51:01,2023-07-10 11:06:01,0,2023-07-10 11:06:01
+322073,2023-07-10,40,UDM,,UDM,15M,UDMHA05,UDM.AmfUecmDeregReq,total,2023-07-10 10:51:01,2023-07-10 11:06:01,1774,2023-07-10 11:06:01
+322074,2023-07-10,40,UDM,,UDM,15M,UDMHA21,UDM.AmfUecmRegUserNotFound,total,2023-07-10 10:51:01,2023-07-10 11:06:01,0,2023-07-10 11:06:01
+322075,2023-07-10,40,UDM,,UDM,15M,UDMHA24,UDM.AmfUecmRegRoamNotAllowed,total,2023-07-10 10:51:01,2023-07-10 11:06:01,0,2023-07-10 11:06:01
+322076,2023-07-10,40,UDM,,UDM,15M,UDMHC02,Ausf.UeAuthAnsSucc,total,2023-07-10 10:51:01,2023-07-10 11:06:01,1774,2023-07-10 11:06:01
+322077,2023-07-10,40,UDM,,UDM,15M,UDMHA01,UDM.AmfUecmRegReq,total,2023-07-10 10:51:01,2023-07-10 11:06:01,1774,2023-07-10 11:06:01
+322078,2023-07-10,40,UDM,,UDM,15M,UDMHA17,UDM.SdmUnSubscrSucc,total,2023-07-10 10:51:01,2023-07-10 11:06:01,6204,2023-07-10 11:06:01
+322079,2023-07-10,40,UDM,,UDM,15M,UDMHA26,UDM.AmfUecmRegContextNotFound,total,2023-07-10 10:51:01,2023-07-10 11:06:01,0,2023-07-10 11:06:01
+322080,2023-07-10,40,UDM,,UDM,15M,UDMHA29,UDM.SmfUecmRegUnknownSub,total,2023-07-10 10:51:01,2023-07-10 11:06:01,0,2023-07-10 11:06:01
+322081,2023-07-10,40,UDM,,UDM,15M,UDMHB01,UDR.5gSupi,total,2023-07-10 10:51:01,2023-07-10 11:06:01,0,2023-07-10 11:06:01
+322082,2023-07-10,40,UDM,,UDM,15M,UDMHB03,UDR.5gActSub,total,2023-07-10 10:51:01,2023-07-10 11:06:01,71571,2023-07-10 11:06:01
+322083,2023-07-10,40,UDM,,UDM,15M,UDMHD01,ME.MeanMeLoad,total,2023-07-10 10:51:01,2023-07-10 11:06:01,0,2023-07-10 11:06:01
+322084,2023-07-10,40,UDM,,UDM,15M,UDMHA02,UDM.AmfUecmRegSucc,total,2023-07-10 10:51:01,2023-07-10 11:06:01,1774,2023-07-10 11:06:01
+322085,2023-07-10,40,UDM,,UDM,15M,UDMHA08,UDM.SmfUecmRegSucc,total,2023-07-10 10:51:01,2023-07-10 11:06:01,4432,2023-07-10 11:06:01
+322086,2023-07-10,40,UDM,,UDM,15M,UDMHA09,UDM.SmfUecmDeregReq,total,2023-07-10 10:51:01,2023-07-10 11:06:01,4430,2023-07-10 11:06:01
+322087,2023-07-10,40,UDM,,UDM,15M,UDMHA16,UDM.SdmUnSubscrReq,total,2023-07-10 10:51:01,2023-07-10 11:06:01,6204,2023-07-10 11:06:01
+322088,2023-07-10,40,UDM,,UDM,15M,UDMHA25,UDM.AmfUecmRegRatNotAllowed,total,2023-07-10 10:51:01,2023-07-10 11:06:01,0,2023-07-10 11:06:01
+322089,2023-07-10,40,UDM,,UDM,15M,UDMHA27,UDM.AmfUecmRegReAuth,total,2023-07-10 10:51:01,2023-07-10 11:06:01,0,2023-07-10 11:06:01
+322090,2023-07-10,40,UDM,,UDM,15M,UDMHA03,UDM.AmfUecmRegUpdateReq,total,2023-07-10 10:51:01,2023-07-10 11:06:01,0,2023-07-10 11:06:01
+322091,2023-07-10,40,UDM,,UDM,15M,UDMHA11,UDM.SdmGetReq,total,2023-07-10 10:51:01,2023-07-10 11:06:01,9754,2023-07-10 11:06:01
+322092,2023-07-10,40,UDM,,UDM,15M,UDMHA13,UDM.SdmNotif,total,2023-07-10 10:51:01,2023-07-10 11:06:01,0,2023-07-10 11:06:01
+322093,2023-07-10,40,UDM,,UDM,15M,UDMHA15,UDM.SdmSubscrSucc,total,2023-07-10 10:51:01,2023-07-10 11:06:01,6206,2023-07-10 11:06:01
+322094,2023-07-10,40,UDM,,UDM,15M,UDMHA30,UDM.SmfUecmRegRoamNotAllowed,total,2023-07-10 10:51:01,2023-07-10 11:06:01,0,2023-07-10 11:06:01
+322095,2023-07-10,40,UDM,,UDM,15M,UDMHA04,UDM.AmfUecmRegUpdateSucc,total,2023-07-10 10:51:01,2023-07-10 11:06:01,0,2023-07-10 11:06:01
+322096,2023-07-10,40,UDM,,UDM,15M,UDMHB02,UDR.5gSub,total,2023-07-10 10:51:01,2023-07-10 11:06:01,0,2023-07-10 11:06:01
+322097,2023-07-10,40,UDM,,UDM,15M,UDMHA01,UDM.AmfUecmRegReq,total,2023-07-10 11:06:01,2023-07-10 11:21:01,1794,2023-07-10 11:21:01
+322098,2023-07-10,40,UDM,,UDM,15M,UDMHA21,UDM.AmfUecmRegUserNotFound,total,2023-07-10 11:06:01,2023-07-10 11:21:01,0,2023-07-10 11:21:01
+322099,2023-07-10,40,UDM,,UDM,15M,UDMHA24,UDM.AmfUecmRegRoamNotAllowed,total,2023-07-10 11:06:01,2023-07-10 11:21:01,0,2023-07-10 11:21:01
+322100,2023-07-10,40,UDM,,UDM,15M,UDMHC02,Ausf.UeAuthAnsSucc,total,2023-07-10 11:06:01,2023-07-10 11:21:01,1792,2023-07-10 11:21:01
+322101,2023-07-10,40,UDM,,UDM,15M,UDMHB01,UDR.5gSupi,total,2023-07-10 11:06:01,2023-07-10 11:21:01,0,2023-07-10 11:21:01
+322102,2023-07-10,40,UDM,,UDM,15M,UDMHB03,UDR.5gActSub,total,2023-07-10 11:06:01,2023-07-10 11:21:01,71573,2023-07-10 11:21:01
+322103,2023-07-10,40,UDM,,UDM,15M,UDMHD01,ME.MeanMeLoad,total,2023-07-10 11:06:01,2023-07-10 11:21:01,0,2023-07-10 11:21:01
+322104,2023-07-10,40,UDM,,UDM,15M,UDMHA02,UDM.AmfUecmRegSucc,total,2023-07-10 11:06:01,2023-07-10 11:21:01,1794,2023-07-10 11:21:01
+322105,2023-07-10,40,UDM,,UDM,15M,UDMHA17,UDM.SdmUnSubscrSucc,total,2023-07-10 11:06:01,2023-07-10 11:21:01,6269,2023-07-10 11:21:01
+322106,2023-07-10,40,UDM,,UDM,15M,UDMHA26,UDM.AmfUecmRegContextNotFound,total,2023-07-10 11:06:01,2023-07-10 11:21:01,0,2023-07-10 11:21:01
+322107,2023-07-10,40,UDM,,UDM,15M,UDMHA29,UDM.SmfUecmRegUnknownSub,total,2023-07-10 11:06:01,2023-07-10 11:21:01,0,2023-07-10 11:21:01
+322108,2023-07-10,40,UDM,,UDM,15M,UDMHA25,UDM.AmfUecmRegRatNotAllowed,total,2023-07-10 11:06:01,2023-07-10 11:21:01,0,2023-07-10 11:21:01
+322109,2023-07-10,40,UDM,,UDM,15M,UDMHA27,UDM.AmfUecmRegReAuth,total,2023-07-10 11:06:01,2023-07-10 11:21:01,0,2023-07-10 11:21:01
+322110,2023-07-10,40,UDM,,UDM,15M,UDMHA03,UDM.AmfUecmRegUpdateReq,total,2023-07-10 11:06:01,2023-07-10 11:21:01,0,2023-07-10 11:21:01
+322111,2023-07-10,40,UDM,,UDM,15M,UDMHA08,UDM.SmfUecmRegSucc,total,2023-07-10 11:06:01,2023-07-10 11:21:01,4477,2023-07-10 11:21:01
+322112,2023-07-10,40,UDM,,UDM,15M,UDMHA09,UDM.SmfUecmDeregReq,total,2023-07-10 11:06:01,2023-07-10 11:21:01,4477,2023-07-10 11:21:01
+322113,2023-07-10,40,UDM,,UDM,15M,UDMHA16,UDM.SdmUnSubscrReq,total,2023-07-10 11:06:01,2023-07-10 11:21:01,6269,2023-07-10 11:21:01
+322114,2023-07-10,40,UDM,,UDM,15M,UDMHA30,UDM.SmfUecmRegRoamNotAllowed,total,2023-07-10 11:06:01,2023-07-10 11:21:01,0,2023-07-10 11:21:01
+322115,2023-07-10,40,UDM,,UDM,15M,UDMHA04,UDM.AmfUecmRegUpdateSucc,total,2023-07-10 11:06:01,2023-07-10 11:21:01,0,2023-07-10 11:21:01
+322116,2023-07-10,40,UDM,,UDM,15M,UDMHA11,UDM.SdmGetReq,total,2023-07-10 11:06:01,2023-07-10 11:21:01,9859,2023-07-10 11:21:01
+322117,2023-07-10,40,UDM,,UDM,15M,UDMHA13,UDM.SdmNotif,total,2023-07-10 11:06:01,2023-07-10 11:21:01,0,2023-07-10 11:21:01
+322118,2023-07-10,40,UDM,,UDM,15M,UDMHA15,UDM.SdmSubscrSucc,total,2023-07-10 11:06:01,2023-07-10 11:21:01,6271,2023-07-10 11:21:01
+322119,2023-07-10,40,UDM,,UDM,15M,UDMHB02,UDR.5gSub,total,2023-07-10 11:06:01,2023-07-10 11:21:01,0,2023-07-10 11:21:01
+322120,2023-07-10,40,UDM,,UDM,15M,UDMHA20,UDM.SdmGetDataNotFound,total,2023-07-10 11:06:01,2023-07-10 11:21:01,0,2023-07-10 11:21:01
+322121,2023-07-10,40,UDM,,UDM,15M,UDMHA22,UDM.AmfUecmRegUnknownSub,total,2023-07-10 11:06:01,2023-07-10 11:21:01,0,2023-07-10 11:21:01
+322122,2023-07-10,40,UDM,,UDM,15M,UDMHA23,UDM.AmfUecmRegNoPsSub,total,2023-07-10 11:06:01,2023-07-10 11:21:01,0,2023-07-10 11:21:01
+322123,2023-07-10,40,UDM,,UDM,15M,UDMHA28,UDM.SmfUecmRegUserNotFound,total,2023-07-10 11:06:01,2023-07-10 11:21:01,0,2023-07-10 11:21:01
+322124,2023-07-10,40,UDM,,UDM,15M,UDMHA06,UDM.AmfUecmDeregSucc,total,2023-07-10 11:06:01,2023-07-10 11:21:01,1792,2023-07-10 11:21:01
+322125,2023-07-10,40,UDM,,UDM,15M,UDMHA10,UDM.SmfUecmDeregSucc,total,2023-07-10 11:06:01,2023-07-10 11:21:01,4477,2023-07-10 11:21:01
+322126,2023-07-10,40,UDM,,UDM,15M,UDMHA12,UDM.SdmGetSucc,total,2023-07-10 11:06:01,2023-07-10 11:21:01,9859,2023-07-10 11:21:01
+322127,2023-07-10,40,UDM,,UDM,15M,UDMHA14,UDM.SdmSubscrReq,total,2023-07-10 11:06:01,2023-07-10 11:21:01,6271,2023-07-10 11:21:01
+322128,2023-07-10,40,UDM,,UDM,15M,UDMHA31,UDM.SmfUecmRegDnnNotAllowed,total,2023-07-10 11:06:01,2023-07-10 11:21:01,0,2023-07-10 11:21:01
+322129,2023-07-10,40,UDM,,UDM,15M,UDMHC04,Ausf.UeAuthAnsContextNotFound,total,2023-07-10 11:06:01,2023-07-10 11:21:01,0,2023-07-10 11:21:01
+322130,2023-07-10,40,UDM,,UDM,15M,UDMHA07,UDM.SmfUecmRegReq,total,2023-07-10 11:06:01,2023-07-10 11:21:01,4477,2023-07-10 11:21:01
+322131,2023-07-10,40,UDM,,UDM,15M,UDMHA19,UDM.SdmGetUserNotFound,total,2023-07-10 11:06:01,2023-07-10 11:21:01,0,2023-07-10 11:21:01
+322132,2023-07-10,40,UDM,,UDM,15M,UDMHA05,UDM.AmfUecmDeregReq,total,2023-07-10 11:06:01,2023-07-10 11:21:01,1792,2023-07-10 11:21:01
+322133,2023-07-10,40,UDM,,UDM,15M,UDMHA18,UDM.UecmDeregNotif,total,2023-07-10 11:06:01,2023-07-10 11:21:01,0,2023-07-10 11:21:01
+322134,2023-07-10,40,UDM,,UDM,15M,UDMHC01,Ausf.UeAuthReq,total,2023-07-10 11:06:01,2023-07-10 11:21:01,1792,2023-07-10 11:21:01
+322135,2023-07-10,40,UDM,,UDM,15M,UDMHC03,Ausf.UeAuthAnsUserNotFound,total,2023-07-10 11:06:01,2023-07-10 11:21:01,0,2023-07-10 11:21:01
+322136,2023-07-10,40,UDM,,UDM,15M,UDMHA16,UDM.SdmUnSubscrReq,total,2023-07-10 11:21:01,2023-07-10 11:36:01,7194,2023-07-10 11:36:01
+322137,2023-07-10,40,UDM,,UDM,15M,UDMHA25,UDM.AmfUecmRegRatNotAllowed,total,2023-07-10 11:21:01,2023-07-10 11:36:01,0,2023-07-10 11:36:01
+322138,2023-07-10,40,UDM,,UDM,15M,UDMHA27,UDM.AmfUecmRegReAuth,total,2023-07-10 11:21:01,2023-07-10 11:36:01,0,2023-07-10 11:36:01
+322139,2023-07-10,40,UDM,,UDM,15M,UDMHA03,UDM.AmfUecmRegUpdateReq,total,2023-07-10 11:21:01,2023-07-10 11:36:01,0,2023-07-10 11:36:01
+322140,2023-07-10,40,UDM,,UDM,15M,UDMHA08,UDM.SmfUecmRegSucc,total,2023-07-10 11:21:01,2023-07-10 11:36:01,3715,2023-07-10 11:36:01
+322141,2023-07-10,40,UDM,,UDM,15M,UDMHA09,UDM.SmfUecmDeregReq,total,2023-07-10 11:21:01,2023-07-10 11:36:01,4917,2023-07-10 11:36:01
+322142,2023-07-10,40,UDM,,UDM,15M,UDMHA15,UDM.SdmSubscrSucc,total,2023-07-10 11:21:01,2023-07-10 11:36:01,5187,2023-07-10 11:36:01
+322143,2023-07-10,40,UDM,,UDM,15M,UDMHA30,UDM.SmfUecmRegRoamNotAllowed,total,2023-07-10 11:21:01,2023-07-10 11:36:01,0,2023-07-10 11:36:01
+322144,2023-07-10,40,UDM,,UDM,15M,UDMHA04,UDM.AmfUecmRegUpdateSucc,total,2023-07-10 11:21:01,2023-07-10 11:36:01,0,2023-07-10 11:36:01
+322145,2023-07-10,40,UDM,,UDM,15M,UDMHA11,UDM.SdmGetReq,total,2023-07-10 11:21:01,2023-07-10 11:36:01,8131,2023-07-10 11:36:01
+322146,2023-07-10,40,UDM,,UDM,15M,UDMHA13,UDM.SdmNotif,total,2023-07-10 11:21:01,2023-07-10 11:36:01,0,2023-07-10 11:36:01
+322147,2023-07-10,40,UDM,,UDM,15M,UDMHB02,UDR.5gSub,total,2023-07-10 11:21:01,2023-07-10 11:36:01,0,2023-07-10 11:36:01
+322148,2023-07-10,40,UDM,,UDM,15M,UDMHA14,UDM.SdmSubscrReq,total,2023-07-10 11:21:01,2023-07-10 11:36:01,5187,2023-07-10 11:36:01
+322149,2023-07-10,40,UDM,,UDM,15M,UDMHA20,UDM.SdmGetDataNotFound,total,2023-07-10 11:21:01,2023-07-10 11:36:01,0,2023-07-10 11:36:01
+322150,2023-07-10,40,UDM,,UDM,15M,UDMHA22,UDM.AmfUecmRegUnknownSub,total,2023-07-10 11:21:01,2023-07-10 11:36:01,0,2023-07-10 11:36:01
+322151,2023-07-10,40,UDM,,UDM,15M,UDMHA23,UDM.AmfUecmRegNoPsSub,total,2023-07-10 11:21:01,2023-07-10 11:36:01,0,2023-07-10 11:36:01
+322152,2023-07-10,40,UDM,,UDM,15M,UDMHA28,UDM.SmfUecmRegUserNotFound,total,2023-07-10 11:21:01,2023-07-10 11:36:01,0,2023-07-10 11:36:01
+322153,2023-07-10,40,UDM,,UDM,15M,UDMHA06,UDM.AmfUecmDeregSucc,total,2023-07-10 11:21:01,2023-07-10 11:36:01,2277,2023-07-10 11:36:01
+322154,2023-07-10,40,UDM,,UDM,15M,UDMHA10,UDM.SmfUecmDeregSucc,total,2023-07-10 11:21:01,2023-07-10 11:36:01,4917,2023-07-10 11:36:01
+322155,2023-07-10,40,UDM,,UDM,15M,UDMHA12,UDM.SdmGetSucc,total,2023-07-10 11:21:01,2023-07-10 11:36:01,8131,2023-07-10 11:36:01
+322156,2023-07-10,40,UDM,,UDM,15M,UDMHA31,UDM.SmfUecmRegDnnNotAllowed,total,2023-07-10 11:21:01,2023-07-10 11:36:01,0,2023-07-10 11:36:01
+322157,2023-07-10,40,UDM,,UDM,15M,UDMHC04,Ausf.UeAuthAnsContextNotFound,total,2023-07-10 11:21:01,2023-07-10 11:36:01,0,2023-07-10 11:36:01
+322158,2023-07-10,40,UDM,,UDM,15M,UDMHA07,UDM.SmfUecmRegReq,total,2023-07-10 11:21:01,2023-07-10 11:36:01,3715,2023-07-10 11:36:01
+322159,2023-07-10,40,UDM,,UDM,15M,UDMHA19,UDM.SdmGetUserNotFound,total,2023-07-10 11:21:01,2023-07-10 11:36:01,0,2023-07-10 11:36:01
+322160,2023-07-10,40,UDM,,UDM,15M,UDMHC03,Ausf.UeAuthAnsUserNotFound,total,2023-07-10 11:21:01,2023-07-10 11:36:01,0,2023-07-10 11:36:01
+322161,2023-07-10,40,UDM,,UDM,15M,UDMHA05,UDM.AmfUecmDeregReq,total,2023-07-10 11:21:01,2023-07-10 11:36:01,2277,2023-07-10 11:36:01
+322162,2023-07-10,40,UDM,,UDM,15M,UDMHA18,UDM.UecmDeregNotif,total,2023-07-10 11:21:01,2023-07-10 11:36:01,0,2023-07-10 11:36:01
+322163,2023-07-10,40,UDM,,UDM,15M,UDMHC01,Ausf.UeAuthReq,total,2023-07-10 11:21:01,2023-07-10 11:36:01,1472,2023-07-10 11:36:01
+322164,2023-07-10,40,UDM,,UDM,15M,UDMHC02,Ausf.UeAuthAnsSucc,total,2023-07-10 11:21:01,2023-07-10 11:36:01,1472,2023-07-10 11:36:01
+322165,2023-07-10,40,UDM,,UDM,15M,UDMHA01,UDM.AmfUecmRegReq,total,2023-07-10 11:21:01,2023-07-10 11:36:01,1472,2023-07-10 11:36:01
+322166,2023-07-10,40,UDM,,UDM,15M,UDMHA21,UDM.AmfUecmRegUserNotFound,total,2023-07-10 11:21:01,2023-07-10 11:36:01,0,2023-07-10 11:36:01
+322167,2023-07-10,40,UDM,,UDM,15M,UDMHA24,UDM.AmfUecmRegRoamNotAllowed,total,2023-07-10 11:21:01,2023-07-10 11:36:01,0,2023-07-10 11:36:01
+322168,2023-07-10,40,UDM,,UDM,15M,UDMHA29,UDM.SmfUecmRegUnknownSub,total,2023-07-10 11:21:01,2023-07-10 11:36:01,0,2023-07-10 11:36:01
+322169,2023-07-10,40,UDM,,UDM,15M,UDMHB01,UDR.5gSupi,total,2023-07-10 11:21:01,2023-07-10 11:36:01,0,2023-07-10 11:36:01
+322170,2023-07-10,40,UDM,,UDM,15M,UDMHB03,UDR.5gActSub,total,2023-07-10 11:21:01,2023-07-10 11:36:01,70768,2023-07-10 11:36:01
+322171,2023-07-10,40,UDM,,UDM,15M,UDMHD01,ME.MeanMeLoad,total,2023-07-10 11:21:01,2023-07-10 11:36:01,0,2023-07-10 11:36:01
+322172,2023-07-10,40,UDM,,UDM,15M,UDMHA02,UDM.AmfUecmRegSucc,total,2023-07-10 11:21:01,2023-07-10 11:36:01,1472,2023-07-10 11:36:01
+322173,2023-07-10,40,UDM,,UDM,15M,UDMHA17,UDM.SdmUnSubscrSucc,total,2023-07-10 11:21:01,2023-07-10 11:36:01,7194,2023-07-10 11:36:01
+322174,2023-07-10,40,UDM,,UDM,15M,UDMHA26,UDM.AmfUecmRegContextNotFound,total,2023-07-10 11:21:01,2023-07-10 11:36:01,0,2023-07-10 11:36:01
+322175,2023-07-10,40,UDM,,UDM,15M,UDMHA07,UDM.SmfUecmRegReq,total,2023-07-10 11:36:01,2023-07-10 11:51:01,5019,2023-07-10 11:51:01
+322176,2023-07-10,40,UDM,,UDM,15M,UDMHA19,UDM.SdmGetUserNotFound,total,2023-07-10 11:36:01,2023-07-10 11:51:01,0,2023-07-10 11:51:01
+322177,2023-07-10,40,UDM,,UDM,15M,UDMHA05,UDM.AmfUecmDeregReq,total,2023-07-10 11:36:01,2023-07-10 11:51:01,1561,2023-07-10 11:51:01
+322178,2023-07-10,40,UDM,,UDM,15M,UDMHA18,UDM.UecmDeregNotif,total,2023-07-10 11:36:01,2023-07-10 11:51:01,0,2023-07-10 11:51:01
+322179,2023-07-10,40,UDM,,UDM,15M,UDMHC01,Ausf.UeAuthReq,total,2023-07-10 11:36:01,2023-07-10 11:51:01,2408,2023-07-10 11:51:01
+322180,2023-07-10,40,UDM,,UDM,15M,UDMHC03,Ausf.UeAuthAnsUserNotFound,total,2023-07-10 11:36:01,2023-07-10 11:51:01,0,2023-07-10 11:51:01
+322181,2023-07-10,40,UDM,,UDM,15M,UDMHA01,UDM.AmfUecmRegReq,total,2023-07-10 11:36:01,2023-07-10 11:51:01,2408,2023-07-10 11:51:01
+322182,2023-07-10,40,UDM,,UDM,15M,UDMHA21,UDM.AmfUecmRegUserNotFound,total,2023-07-10 11:36:01,2023-07-10 11:51:01,0,2023-07-10 11:51:01
+322183,2023-07-10,40,UDM,,UDM,15M,UDMHA24,UDM.AmfUecmRegRoamNotAllowed,total,2023-07-10 11:36:01,2023-07-10 11:51:01,0,2023-07-10 11:51:01
+322184,2023-07-10,40,UDM,,UDM,15M,UDMHC02,Ausf.UeAuthAnsSucc,total,2023-07-10 11:36:01,2023-07-10 11:51:01,2408,2023-07-10 11:51:01
+322185,2023-07-10,40,UDM,,UDM,15M,UDMHB01,UDR.5gSupi,total,2023-07-10 11:36:01,2023-07-10 11:51:01,0,2023-07-10 11:51:01
+322186,2023-07-10,40,UDM,,UDM,15M,UDMHB03,UDR.5gActSub,total,2023-07-10 11:36:01,2023-07-10 11:51:01,71573,2023-07-10 11:51:01
+322187,2023-07-10,40,UDM,,UDM,15M,UDMHD01,ME.MeanMeLoad,total,2023-07-10 11:36:01,2023-07-10 11:51:01,0,2023-07-10 11:51:01
+322188,2023-07-10,40,UDM,,UDM,15M,UDMHA02,UDM.AmfUecmRegSucc,total,2023-07-10 11:36:01,2023-07-10 11:51:01,2408,2023-07-10 11:51:01
+322189,2023-07-10,40,UDM,,UDM,15M,UDMHA17,UDM.SdmUnSubscrSucc,total,2023-07-10 11:36:01,2023-07-10 11:51:01,5377,2023-07-10 11:51:01
+322190,2023-07-10,40,UDM,,UDM,15M,UDMHA26,UDM.AmfUecmRegContextNotFound,total,2023-07-10 11:36:01,2023-07-10 11:51:01,0,2023-07-10 11:51:01
+322191,2023-07-10,40,UDM,,UDM,15M,UDMHA29,UDM.SmfUecmRegUnknownSub,total,2023-07-10 11:36:01,2023-07-10 11:51:01,0,2023-07-10 11:51:01
+322192,2023-07-10,40,UDM,,UDM,15M,UDMHA25,UDM.AmfUecmRegRatNotAllowed,total,2023-07-10 11:36:01,2023-07-10 11:51:01,0,2023-07-10 11:51:01
+322193,2023-07-10,40,UDM,,UDM,15M,UDMHA27,UDM.AmfUecmRegReAuth,total,2023-07-10 11:36:01,2023-07-10 11:51:01,0,2023-07-10 11:51:01
+322194,2023-07-10,40,UDM,,UDM,15M,UDMHA03,UDM.AmfUecmRegUpdateReq,total,2023-07-10 11:36:01,2023-07-10 11:51:01,0,2023-07-10 11:51:01
+322195,2023-07-10,40,UDM,,UDM,15M,UDMHA08,UDM.SmfUecmRegSucc,total,2023-07-10 11:36:01,2023-07-10 11:51:01,5019,2023-07-10 11:51:01
+322196,2023-07-10,40,UDM,,UDM,15M,UDMHA09,UDM.SmfUecmDeregReq,total,2023-07-10 11:36:01,2023-07-10 11:51:01,3816,2023-07-10 11:51:01
+322197,2023-07-10,40,UDM,,UDM,15M,UDMHA16,UDM.SdmUnSubscrReq,total,2023-07-10 11:36:01,2023-07-10 11:51:01,5377,2023-07-10 11:51:01
+322198,2023-07-10,40,UDM,,UDM,15M,UDMHA30,UDM.SmfUecmRegRoamNotAllowed,total,2023-07-10 11:36:01,2023-07-10 11:51:01,0,2023-07-10 11:51:01
+322199,2023-07-10,40,UDM,,UDM,15M,UDMHA04,UDM.AmfUecmRegUpdateSucc,total,2023-07-10 11:36:01,2023-07-10 11:51:01,0,2023-07-10 11:51:01
+322200,2023-07-10,40,UDM,,UDM,15M,UDMHA11,UDM.SdmGetReq,total,2023-07-10 11:36:01,2023-07-10 11:51:01,12243,2023-07-10 11:51:01
+322201,2023-07-10,40,UDM,,UDM,15M,UDMHA13,UDM.SdmNotif,total,2023-07-10 11:36:01,2023-07-10 11:51:01,0,2023-07-10 11:51:01
+322202,2023-07-10,40,UDM,,UDM,15M,UDMHA15,UDM.SdmSubscrSucc,total,2023-07-10 11:36:01,2023-07-10 11:51:01,7427,2023-07-10 11:51:01
+322203,2023-07-10,40,UDM,,UDM,15M,UDMHB02,UDR.5gSub,total,2023-07-10 11:36:01,2023-07-10 11:51:01,0,2023-07-10 11:51:01
+322204,2023-07-10,40,UDM,,UDM,15M,UDMHA20,UDM.SdmGetDataNotFound,total,2023-07-10 11:36:01,2023-07-10 11:51:01,0,2023-07-10 11:51:01
+322205,2023-07-10,40,UDM,,UDM,15M,UDMHA22,UDM.AmfUecmRegUnknownSub,total,2023-07-10 11:36:01,2023-07-10 11:51:01,0,2023-07-10 11:51:01
+322206,2023-07-10,40,UDM,,UDM,15M,UDMHA23,UDM.AmfUecmRegNoPsSub,total,2023-07-10 11:36:01,2023-07-10 11:51:01,0,2023-07-10 11:51:01
+322207,2023-07-10,40,UDM,,UDM,15M,UDMHA28,UDM.SmfUecmRegUserNotFound,total,2023-07-10 11:36:01,2023-07-10 11:51:01,0,2023-07-10 11:51:01
+322208,2023-07-10,40,UDM,,UDM,15M,UDMHA06,UDM.AmfUecmDeregSucc,total,2023-07-10 11:36:01,2023-07-10 11:51:01,1561,2023-07-10 11:51:01
+322209,2023-07-10,40,UDM,,UDM,15M,UDMHA10,UDM.SmfUecmDeregSucc,total,2023-07-10 11:36:01,2023-07-10 11:51:01,3816,2023-07-10 11:51:01
+322210,2023-07-10,40,UDM,,UDM,15M,UDMHA12,UDM.SdmGetSucc,total,2023-07-10 11:36:01,2023-07-10 11:51:01,12243,2023-07-10 11:51:01
+322211,2023-07-10,40,UDM,,UDM,15M,UDMHA14,UDM.SdmSubscrReq,total,2023-07-10 11:36:01,2023-07-10 11:51:01,7427,2023-07-10 11:51:01
+322212,2023-07-10,40,UDM,,UDM,15M,UDMHA31,UDM.SmfUecmRegDnnNotAllowed,total,2023-07-10 11:36:01,2023-07-10 11:51:01,0,2023-07-10 11:51:01
+322213,2023-07-10,40,UDM,,UDM,15M,UDMHC04,Ausf.UeAuthAnsContextNotFound,total,2023-07-10 11:36:01,2023-07-10 11:51:01,0,2023-07-10 11:51:01
+322214,2023-07-10,40,UDM,,UDM,15M,UDMHA29,UDM.SmfUecmRegUnknownSub,,2023-07-10 11:51:01,2023-07-10 12:06:01,0,2023-07-10 12:06:01
+322215,2023-07-10,40,UDM,,UDM,15M,UDMHB01,UDR.5gSupi,total,2023-07-10 11:51:01,2023-07-10 12:06:01,0,2023-07-10 12:06:01
+322216,2023-07-10,40,UDM,,UDM,15M,UDMHB03,UDR.5gActSub,total,2023-07-10 11:51:01,2023-07-10 12:06:01,71572,2023-07-10 12:06:01
+322217,2023-07-10,40,UDM,,UDM,15M,UDMHD01,ME.MeanMeLoad,total,2023-07-10 11:51:01,2023-07-10 12:06:01,0,2023-07-10 12:06:01
+322218,2023-07-10,40,UDM,,UDM,15M,UDMHA02,UDM.AmfUecmRegSucc,total,2023-07-10 11:51:01,2023-07-10 12:06:01,1793,2023-07-10 12:06:01
+322219,2023-07-10,40,UDM,,UDM,15M,UDMHA17,UDM.SdmUnSubscrSucc,total,2023-07-10 11:51:01,2023-07-10 12:06:01,6277,2023-07-10 12:06:01
+322220,2023-07-10,40,UDM,,UDM,15M,UDMHA26,UDM.AmfUecmRegContextNotFound,total,2023-07-10 11:51:01,2023-07-10 12:06:01,0,2023-07-10 12:06:01
+322221,2023-07-10,40,UDM,,UDM,15M,UDMHA16,UDM.SdmUnSubscrReq,total,2023-07-10 11:51:01,2023-07-10 12:06:01,6277,2023-07-10 12:06:01
+322222,2023-07-10,40,UDM,,UDM,15M,UDMHA25,UDM.AmfUecmRegRatNotAllowed,total,2023-07-10 11:51:01,2023-07-10 12:06:01,0,2023-07-10 12:06:01
+322223,2023-07-10,40,UDM,,UDM,15M,UDMHA27,UDM.AmfUecmRegReAuth,total,2023-07-10 11:51:01,2023-07-10 12:06:01,0,2023-07-10 12:06:01
+322224,2023-07-10,40,UDM,,UDM,15M,UDMHA03,UDM.AmfUecmRegUpdateReq,total,2023-07-10 11:51:01,2023-07-10 12:06:01,0,2023-07-10 12:06:01
+322225,2023-07-10,40,UDM,,UDM,15M,UDMHA08,UDM.SmfUecmRegSucc,total,2023-07-10 11:51:01,2023-07-10 12:06:01,4480,2023-07-10 12:06:01
+322226,2023-07-10,40,UDM,,UDM,15M,UDMHA09,UDM.SmfUecmDeregReq,total,2023-07-10 11:51:01,2023-07-10 12:06:01,4483,2023-07-10 12:06:01
+322227,2023-07-10,40,UDM,,UDM,15M,UDMHA15,UDM.SdmSubscrSucc,total,2023-07-10 11:51:01,2023-07-10 12:06:01,6273,2023-07-10 12:06:01
+322228,2023-07-10,40,UDM,,UDM,15M,UDMHA30,UDM.SmfUecmRegRoamNotAllowed,total,2023-07-10 11:51:01,2023-07-10 12:06:01,0,2023-07-10 12:06:01
+322229,2023-07-10,40,UDM,,UDM,15M,UDMHA04,UDM.AmfUecmRegUpdateSucc,total,2023-07-10 11:51:01,2023-07-10 12:06:01,0,2023-07-10 12:06:01
+322230,2023-07-10,40,UDM,,UDM,15M,UDMHA11,UDM.SdmGetReq,total,2023-07-10 11:51:01,2023-07-10 12:06:01,9859,2023-07-10 12:06:01
+322231,2023-07-10,40,UDM,,UDM,15M,UDMHA13,UDM.SdmNotif,total,2023-07-10 11:51:01,2023-07-10 12:06:01,0,2023-07-10 12:06:01
+322232,2023-07-10,40,UDM,,UDM,15M,UDMHB02,UDR.5gSub,total,2023-07-10 11:51:01,2023-07-10 12:06:01,0,2023-07-10 12:06:01
+322233,2023-07-10,40,UDM,,UDM,15M,UDMHA14,UDM.SdmSubscrReq,total,2023-07-10 11:51:01,2023-07-10 12:06:01,6273,2023-07-10 12:06:01
+322234,2023-07-10,40,UDM,,UDM,15M,UDMHA20,UDM.SdmGetDataNotFound,total,2023-07-10 11:51:01,2023-07-10 12:06:01,0,2023-07-10 12:06:01
+322235,2023-07-10,40,UDM,,UDM,15M,UDMHA22,UDM.AmfUecmRegUnknownSub,total,2023-07-10 11:51:01,2023-07-10 12:06:01,0,2023-07-10 12:06:01
+322236,2023-07-10,40,UDM,,UDM,15M,UDMHA23,UDM.AmfUecmRegNoPsSub,total,2023-07-10 11:51:01,2023-07-10 12:06:01,0,2023-07-10 12:06:01
+322237,2023-07-10,40,UDM,,UDM,15M,UDMHA28,UDM.SmfUecmRegUserNotFound,total,2023-07-10 11:51:01,2023-07-10 12:06:01,0,2023-07-10 12:06:01
+322238,2023-07-10,40,UDM,,UDM,15M,UDMHA06,UDM.AmfUecmDeregSucc,total,2023-07-10 11:51:01,2023-07-10 12:06:01,1794,2023-07-10 12:06:01
+322239,2023-07-10,40,UDM,,UDM,15M,UDMHA10,UDM.SmfUecmDeregSucc,total,2023-07-10 11:51:01,2023-07-10 12:06:01,4483,2023-07-10 12:06:01
+322240,2023-07-10,40,UDM,,UDM,15M,UDMHA12,UDM.SdmGetSucc,total,2023-07-10 11:51:01,2023-07-10 12:06:01,9859,2023-07-10 12:06:01
+322241,2023-07-10,40,UDM,,UDM,15M,UDMHA31,UDM.SmfUecmRegDnnNotAllowed,total,2023-07-10 11:51:01,2023-07-10 12:06:01,0,2023-07-10 12:06:01
+322242,2023-07-10,40,UDM,,UDM,15M,UDMHC04,Ausf.UeAuthAnsContextNotFound,total,2023-07-10 11:51:01,2023-07-10 12:06:01,0,2023-07-10 12:06:01
+322243,2023-07-10,40,UDM,,UDM,15M,UDMHA07,UDM.SmfUecmRegReq,total,2023-07-10 11:51:01,2023-07-10 12:06:01,4480,2023-07-10 12:06:01
+322244,2023-07-10,40,UDM,,UDM,15M,UDMHA19,UDM.SdmGetUserNotFound,total,2023-07-10 11:51:01,2023-07-10 12:06:01,0,2023-07-10 12:06:01
+322245,2023-07-10,40,UDM,,UDM,15M,UDMHC03,Ausf.UeAuthAnsUserNotFound,total,2023-07-10 11:51:01,2023-07-10 12:06:01,0,2023-07-10 12:06:01
+322246,2023-07-10,40,UDM,,UDM,15M,UDMHA05,UDM.AmfUecmDeregReq,total,2023-07-10 11:51:01,2023-07-10 12:06:01,1794,2023-07-10 12:06:01
+322247,2023-07-10,40,UDM,,UDM,15M,UDMHA18,UDM.UecmDeregNotif,total,2023-07-10 11:51:01,2023-07-10 12:06:01,0,2023-07-10 12:06:01
+322248,2023-07-10,40,UDM,,UDM,15M,UDMHC01,Ausf.UeAuthReq,total,2023-07-10 11:51:01,2023-07-10 12:06:01,1794,2023-07-10 12:06:01
+322249,2023-07-10,40,UDM,,UDM,15M,UDMHC02,Ausf.UeAuthAnsSucc,total,2023-07-10 11:51:01,2023-07-10 12:06:01,1794,2023-07-10 12:06:01
+322250,2023-07-10,40,UDM,,UDM,15M,UDMHA01,UDM.AmfUecmRegReq,total,2023-07-10 11:51:01,2023-07-10 12:06:01,1793,2023-07-10 12:06:01
+322251,2023-07-10,40,UDM,,UDM,15M,UDMHA21,UDM.AmfUecmRegUserNotFound,total,2023-07-10 11:51:01,2023-07-10 12:06:01,0,2023-07-10 12:06:01
+322252,2023-07-10,40,UDM,,UDM,15M,UDMHA24,UDM.AmfUecmRegRoamNotAllowed,total,2023-07-10 11:51:01,2023-07-10 12:06:01,0,2023-07-10 12:06:01
+322253,2023-07-10,40,UDM,,UDM,15M,UDMHA29,UDM.SmfUecmRegUnknownSub,,2023-07-10 12:06:01,2023-07-10 12:21:01,0,2023-07-10 12:21:01
+322254,2023-07-10,40,UDM,,UDM,15M,UDMHB01,UDR.5gSupi,total,2023-07-10 12:06:01,2023-07-10 12:21:01,0,2023-07-10 12:21:01
+322255,2023-07-10,40,UDM,,UDM,15M,UDMHB03,UDR.5gActSub,total,2023-07-10 12:06:01,2023-07-10 12:21:01,71573,2023-07-10 12:21:01
+322256,2023-07-10,40,UDM,,UDM,15M,UDMHD01,ME.MeanMeLoad,total,2023-07-10 12:06:01,2023-07-10 12:21:01,0,2023-07-10 12:21:01
+322257,2023-07-10,40,UDM,,UDM,15M,UDMHA02,UDM.AmfUecmRegSucc,total,2023-07-10 12:06:01,2023-07-10 12:21:01,1795,2023-07-10 12:21:01
+322258,2023-07-10,40,UDM,,UDM,15M,UDMHA17,UDM.SdmUnSubscrSucc,total,2023-07-10 12:06:01,2023-07-10 12:21:01,6280,2023-07-10 12:21:01
+322259,2023-07-10,40,UDM,,UDM,15M,UDMHA26,UDM.AmfUecmRegContextNotFound,total,2023-07-10 12:06:01,2023-07-10 12:21:01,0,2023-07-10 12:21:01
+322260,2023-07-10,40,UDM,,UDM,15M,UDMHA16,UDM.SdmUnSubscrReq,total,2023-07-10 12:06:01,2023-07-10 12:21:01,6280,2023-07-10 12:21:01
+322261,2023-07-10,40,UDM,,UDM,15M,UDMHA25,UDM.AmfUecmRegRatNotAllowed,total,2023-07-10 12:06:01,2023-07-10 12:21:01,0,2023-07-10 12:21:01
+322262,2023-07-10,40,UDM,,UDM,15M,UDMHA27,UDM.AmfUecmRegReAuth,total,2023-07-10 12:06:01,2023-07-10 12:21:01,0,2023-07-10 12:21:01
+322263,2023-07-10,40,UDM,,UDM,15M,UDMHA03,UDM.AmfUecmRegUpdateReq,total,2023-07-10 12:06:01,2023-07-10 12:21:01,0,2023-07-10 12:21:01
+322264,2023-07-10,40,UDM,,UDM,15M,UDMHA08,UDM.SmfUecmRegSucc,total,2023-07-10 12:06:01,2023-07-10 12:21:01,4489,2023-07-10 12:21:01
+322265,2023-07-10,40,UDM,,UDM,15M,UDMHA09,UDM.SmfUecmDeregReq,total,2023-07-10 12:06:01,2023-07-10 12:21:01,4485,2023-07-10 12:21:01
+322266,2023-07-10,40,UDM,,UDM,15M,UDMHA15,UDM.SdmSubscrSucc,total,2023-07-10 12:06:01,2023-07-10 12:21:01,6284,2023-07-10 12:21:01
+322267,2023-07-10,40,UDM,,UDM,15M,UDMHA30,UDM.SmfUecmRegRoamNotAllowed,total,2023-07-10 12:06:01,2023-07-10 12:21:01,0,2023-07-10 12:21:01
+322268,2023-07-10,40,UDM,,UDM,15M,UDMHA04,UDM.AmfUecmRegUpdateSucc,total,2023-07-10 12:06:01,2023-07-10 12:21:01,0,2023-07-10 12:21:01
+322269,2023-07-10,40,UDM,,UDM,15M,UDMHA11,UDM.SdmGetReq,total,2023-07-10 12:06:01,2023-07-10 12:21:01,9874,2023-07-10 12:21:01
+322270,2023-07-10,40,UDM,,UDM,15M,UDMHA13,UDM.SdmNotif,total,2023-07-10 12:06:01,2023-07-10 12:21:01,0,2023-07-10 12:21:01
+322271,2023-07-10,40,UDM,,UDM,15M,UDMHB02,UDR.5gSub,total,2023-07-10 12:06:01,2023-07-10 12:21:01,0,2023-07-10 12:21:01
+322272,2023-07-10,40,UDM,,UDM,15M,UDMHA14,UDM.SdmSubscrReq,total,2023-07-10 12:06:01,2023-07-10 12:21:01,6284,2023-07-10 12:21:01
+322273,2023-07-10,40,UDM,,UDM,15M,UDMHA20,UDM.SdmGetDataNotFound,total,2023-07-10 12:06:01,2023-07-10 12:21:01,0,2023-07-10 12:21:01
+322274,2023-07-10,40,UDM,,UDM,15M,UDMHA22,UDM.AmfUecmRegUnknownSub,total,2023-07-10 12:06:01,2023-07-10 12:21:01,0,2023-07-10 12:21:01
+322275,2023-07-10,40,UDM,,UDM,15M,UDMHA23,UDM.AmfUecmRegNoPsSub,total,2023-07-10 12:06:01,2023-07-10 12:21:01,0,2023-07-10 12:21:01
+322276,2023-07-10,40,UDM,,UDM,15M,UDMHA28,UDM.SmfUecmRegUserNotFound,total,2023-07-10 12:06:01,2023-07-10 12:21:01,0,2023-07-10 12:21:01
+322277,2023-07-10,40,UDM,,UDM,15M,UDMHA06,UDM.AmfUecmDeregSucc,total,2023-07-10 12:06:01,2023-07-10 12:21:01,1794,2023-07-10 12:21:01
+322278,2023-07-10,40,UDM,,UDM,15M,UDMHA10,UDM.SmfUecmDeregSucc,total,2023-07-10 12:06:01,2023-07-10 12:21:01,4485,2023-07-10 12:21:01
+322279,2023-07-10,40,UDM,,UDM,15M,UDMHA12,UDM.SdmGetSucc,total,2023-07-10 12:06:01,2023-07-10 12:21:01,9874,2023-07-10 12:21:01
+322280,2023-07-10,40,UDM,,UDM,15M,UDMHA31,UDM.SmfUecmRegDnnNotAllowed,total,2023-07-10 12:06:01,2023-07-10 12:21:01,0,2023-07-10 12:21:01
+322281,2023-07-10,40,UDM,,UDM,15M,UDMHC04,Ausf.UeAuthAnsContextNotFound,total,2023-07-10 12:06:01,2023-07-10 12:21:01,0,2023-07-10 12:21:01
+322282,2023-07-10,40,UDM,,UDM,15M,UDMHA07,UDM.SmfUecmRegReq,total,2023-07-10 12:06:01,2023-07-10 12:21:01,4489,2023-07-10 12:21:01
+322283,2023-07-10,40,UDM,,UDM,15M,UDMHA19,UDM.SdmGetUserNotFound,total,2023-07-10 12:06:01,2023-07-10 12:21:01,0,2023-07-10 12:21:01
+322284,2023-07-10,40,UDM,,UDM,15M,UDMHC03,Ausf.UeAuthAnsUserNotFound,total,2023-07-10 12:06:01,2023-07-10 12:21:01,0,2023-07-10 12:21:01
+322285,2023-07-10,40,UDM,,UDM,15M,UDMHA05,UDM.AmfUecmDeregReq,total,2023-07-10 12:06:01,2023-07-10 12:21:01,1794,2023-07-10 12:21:01
+322286,2023-07-10,40,UDM,,UDM,15M,UDMHA18,UDM.UecmDeregNotif,total,2023-07-10 12:06:01,2023-07-10 12:21:01,0,2023-07-10 12:21:01
+322287,2023-07-10,40,UDM,,UDM,15M,UDMHC01,Ausf.UeAuthReq,total,2023-07-10 12:06:01,2023-07-10 12:21:01,1794,2023-07-10 12:21:01
+322288,2023-07-10,40,UDM,,UDM,15M,UDMHC02,Ausf.UeAuthAnsSucc,total,2023-07-10 12:06:01,2023-07-10 12:21:01,1794,2023-07-10 12:21:01
+322289,2023-07-10,40,UDM,,UDM,15M,UDMHA01,UDM.AmfUecmRegReq,total,2023-07-10 12:06:01,2023-07-10 12:21:01,1795,2023-07-10 12:21:01
+322290,2023-07-10,40,UDM,,UDM,15M,UDMHA21,UDM.AmfUecmRegUserNotFound,total,2023-07-10 12:06:01,2023-07-10 12:21:01,0,2023-07-10 12:21:01
+322291,2023-07-10,40,UDM,,UDM,15M,UDMHA24,UDM.AmfUecmRegRoamNotAllowed,total,2023-07-10 12:06:01,2023-07-10 12:21:01,0,2023-07-10 12:21:01
+322292,2023-07-10,40,UDM,,UDM,15M,UDMHA04,UDM.AmfUecmRegUpdateSucc,,2023-07-10 12:21:01,2023-07-10 12:36:01,0,2023-07-10 12:36:01
+322293,2023-07-10,40,UDM,,UDM,15M,UDMHA11,UDM.SdmGetReq,total,2023-07-10 12:21:01,2023-07-10 12:36:01,9889,2023-07-10 12:36:01
+322294,2023-07-10,40,UDM,,UDM,15M,UDMHA13,UDM.SdmNotif,total,2023-07-10 12:21:01,2023-07-10 12:36:01,0,2023-07-10 12:36:01
+322295,2023-07-10,40,UDM,,UDM,15M,UDMHA15,UDM.SdmSubscrSucc,total,2023-07-10 12:21:01,2023-07-10 12:36:01,6293,2023-07-10 12:36:01
+322296,2023-07-10,40,UDM,,UDM,15M,UDMHA30,UDM.SmfUecmRegRoamNotAllowed,total,2023-07-10 12:21:01,2023-07-10 12:36:01,0,2023-07-10 12:36:01
+322297,2023-07-10,40,UDM,,UDM,15M,UDMHB02,UDR.5gSub,total,2023-07-10 12:21:01,2023-07-10 12:36:01,0,2023-07-10 12:36:01
+322298,2023-07-10,40,UDM,,UDM,15M,UDMHA23,UDM.AmfUecmRegNoPsSub,total,2023-07-10 12:21:01,2023-07-10 12:36:01,0,2023-07-10 12:36:01
+322299,2023-07-10,40,UDM,,UDM,15M,UDMHA28,UDM.SmfUecmRegUserNotFound,total,2023-07-10 12:21:01,2023-07-10 12:36:01,0,2023-07-10 12:36:01
+322300,2023-07-10,40,UDM,,UDM,15M,UDMHA06,UDM.AmfUecmDeregSucc,total,2023-07-10 12:21:01,2023-07-10 12:36:01,1797,2023-07-10 12:36:01
+322301,2023-07-10,40,UDM,,UDM,15M,UDMHA10,UDM.SmfUecmDeregSucc,total,2023-07-10 12:21:01,2023-07-10 12:36:01,4494,2023-07-10 12:36:01
+322302,2023-07-10,40,UDM,,UDM,15M,UDMHA12,UDM.SdmGetSucc,total,2023-07-10 12:21:01,2023-07-10 12:36:01,9889,2023-07-10 12:36:01
+322303,2023-07-10,40,UDM,,UDM,15M,UDMHA14,UDM.SdmSubscrReq,total,2023-07-10 12:21:01,2023-07-10 12:36:01,6293,2023-07-10 12:36:01
+322304,2023-07-10,40,UDM,,UDM,15M,UDMHA20,UDM.SdmGetDataNotFound,total,2023-07-10 12:21:01,2023-07-10 12:36:01,0,2023-07-10 12:36:01
+322305,2023-07-10,40,UDM,,UDM,15M,UDMHA22,UDM.AmfUecmRegUnknownSub,total,2023-07-10 12:21:01,2023-07-10 12:36:01,0,2023-07-10 12:36:01
+322306,2023-07-10,40,UDM,,UDM,15M,UDMHA31,UDM.SmfUecmRegDnnNotAllowed,total,2023-07-10 12:21:01,2023-07-10 12:36:01,0,2023-07-10 12:36:01
+322307,2023-07-10,40,UDM,,UDM,15M,UDMHC04,Ausf.UeAuthAnsContextNotFound,total,2023-07-10 12:21:01,2023-07-10 12:36:01,0,2023-07-10 12:36:01
+322308,2023-07-10,40,UDM,,UDM,15M,UDMHA07,UDM.SmfUecmRegReq,total,2023-07-10 12:21:01,2023-07-10 12:36:01,4495,2023-07-10 12:36:01
+322309,2023-07-10,40,UDM,,UDM,15M,UDMHA19,UDM.SdmGetUserNotFound,total,2023-07-10 12:21:01,2023-07-10 12:36:01,0,2023-07-10 12:36:01
+322310,2023-07-10,40,UDM,,UDM,15M,UDMHA05,UDM.AmfUecmDeregReq,total,2023-07-10 12:21:01,2023-07-10 12:36:01,1797,2023-07-10 12:36:01
+322311,2023-07-10,40,UDM,,UDM,15M,UDMHA18,UDM.UecmDeregNotif,total,2023-07-10 12:21:01,2023-07-10 12:36:01,0,2023-07-10 12:36:01
+322312,2023-07-10,40,UDM,,UDM,15M,UDMHC01,Ausf.UeAuthReq,total,2023-07-10 12:21:01,2023-07-10 12:36:01,1798,2023-07-10 12:36:01
+322313,2023-07-10,40,UDM,,UDM,15M,UDMHC03,Ausf.UeAuthAnsUserNotFound,total,2023-07-10 12:21:01,2023-07-10 12:36:01,0,2023-07-10 12:36:01
+322314,2023-07-10,40,UDM,,UDM,15M,UDMHA01,UDM.AmfUecmRegReq,total,2023-07-10 12:21:01,2023-07-10 12:36:01,1798,2023-07-10 12:36:01
+322315,2023-07-10,40,UDM,,UDM,15M,UDMHA21,UDM.AmfUecmRegUserNotFound,total,2023-07-10 12:21:01,2023-07-10 12:36:01,0,2023-07-10 12:36:01
+322316,2023-07-10,40,UDM,,UDM,15M,UDMHA24,UDM.AmfUecmRegRoamNotAllowed,total,2023-07-10 12:21:01,2023-07-10 12:36:01,0,2023-07-10 12:36:01
+322317,2023-07-10,40,UDM,,UDM,15M,UDMHC02,Ausf.UeAuthAnsSucc,total,2023-07-10 12:21:01,2023-07-10 12:36:01,1798,2023-07-10 12:36:01
+322318,2023-07-10,40,UDM,,UDM,15M,UDMHD01,ME.MeanMeLoad,total,2023-07-10 12:21:01,2023-07-10 12:36:01,0,2023-07-10 12:36:01
+322319,2023-07-10,40,UDM,,UDM,15M,UDMHA02,UDM.AmfUecmRegSucc,total,2023-07-10 12:21:01,2023-07-10 12:36:01,1798,2023-07-10 12:36:01
+322320,2023-07-10,40,UDM,,UDM,15M,UDMHA17,UDM.SdmUnSubscrSucc,total,2023-07-10 12:21:01,2023-07-10 12:36:01,6291,2023-07-10 12:36:01
+322321,2023-07-10,40,UDM,,UDM,15M,UDMHA26,UDM.AmfUecmRegContextNotFound,total,2023-07-10 12:21:01,2023-07-10 12:36:01,0,2023-07-10 12:36:01
+322322,2023-07-10,40,UDM,,UDM,15M,UDMHA29,UDM.SmfUecmRegUnknownSub,total,2023-07-10 12:21:01,2023-07-10 12:36:01,0,2023-07-10 12:36:01
+322323,2023-07-10,40,UDM,,UDM,15M,UDMHB01,UDR.5gSupi,total,2023-07-10 12:21:01,2023-07-10 12:36:01,0,2023-07-10 12:36:01
+322324,2023-07-10,40,UDM,,UDM,15M,UDMHB03,UDR.5gActSub,total,2023-07-10 12:21:01,2023-07-10 12:36:01,71574,2023-07-10 12:36:01
+322325,2023-07-10,40,UDM,,UDM,15M,UDMHA03,UDM.AmfUecmRegUpdateReq,total,2023-07-10 12:21:01,2023-07-10 12:36:01,0,2023-07-10 12:36:01
+322326,2023-07-10,40,UDM,,UDM,15M,UDMHA08,UDM.SmfUecmRegSucc,total,2023-07-10 12:21:01,2023-07-10 12:36:01,4495,2023-07-10 12:36:01
+322327,2023-07-10,40,UDM,,UDM,15M,UDMHA09,UDM.SmfUecmDeregReq,total,2023-07-10 12:21:01,2023-07-10 12:36:01,4494,2023-07-10 12:36:01
+322328,2023-07-10,40,UDM,,UDM,15M,UDMHA16,UDM.SdmUnSubscrReq,total,2023-07-10 12:21:01,2023-07-10 12:36:01,6291,2023-07-10 12:36:01
+322329,2023-07-10,40,UDM,,UDM,15M,UDMHA25,UDM.AmfUecmRegRatNotAllowed,total,2023-07-10 12:21:01,2023-07-10 12:36:01,0,2023-07-10 12:36:01
+322330,2023-07-10,40,UDM,,UDM,15M,UDMHA27,UDM.AmfUecmRegReAuth,total,2023-07-10 12:21:01,2023-07-10 12:36:01,0,2023-07-10 12:36:01
+322331,2023-07-10,40,UDM,,UDM,15M,UDMHA13,UDM.SdmNotif,,2023-07-10 12:36:01,2023-07-10 12:51:01,0,2023-07-10 12:51:01
+322332,2023-07-10,40,UDM,,UDM,15M,UDMHA15,UDM.SdmSubscrSucc,total,2023-07-10 12:36:01,2023-07-10 12:51:01,6291,2023-07-10 12:51:01
+322333,2023-07-10,40,UDM,,UDM,15M,UDMHA30,UDM.SmfUecmRegRoamNotAllowed,total,2023-07-10 12:36:01,2023-07-10 12:51:01,0,2023-07-10 12:51:01
+322334,2023-07-10,40,UDM,,UDM,15M,UDMHA04,UDM.AmfUecmRegUpdateSucc,total,2023-07-10 12:36:01,2023-07-10 12:51:01,0,2023-07-10 12:51:01
+322335,2023-07-10,40,UDM,,UDM,15M,UDMHA11,UDM.SdmGetReq,total,2023-07-10 12:36:01,2023-07-10 12:51:01,9883,2023-07-10 12:51:01
+322336,2023-07-10,40,UDM,,UDM,15M,UDMHB02,UDR.5gSub,total,2023-07-10 12:36:01,2023-07-10 12:51:01,0,2023-07-10 12:51:01
+322337,2023-07-10,40,UDM,,UDM,15M,UDMHA12,UDM.SdmGetSucc,total,2023-07-10 12:36:01,2023-07-10 12:51:01,9883,2023-07-10 12:51:01
+322338,2023-07-10,40,UDM,,UDM,15M,UDMHA14,UDM.SdmSubscrReq,total,2023-07-10 12:36:01,2023-07-10 12:51:01,6291,2023-07-10 12:51:01
+322339,2023-07-10,40,UDM,,UDM,15M,UDMHA20,UDM.SdmGetDataNotFound,total,2023-07-10 12:36:01,2023-07-10 12:51:01,0,2023-07-10 12:51:01
+322340,2023-07-10,40,UDM,,UDM,15M,UDMHA22,UDM.AmfUecmRegUnknownSub,total,2023-07-10 12:36:01,2023-07-10 12:51:01,0,2023-07-10 12:51:01
+322341,2023-07-10,40,UDM,,UDM,15M,UDMHA23,UDM.AmfUecmRegNoPsSub,total,2023-07-10 12:36:01,2023-07-10 12:51:01,0,2023-07-10 12:51:01
+322342,2023-07-10,40,UDM,,UDM,15M,UDMHA28,UDM.SmfUecmRegUserNotFound,total,2023-07-10 12:36:01,2023-07-10 12:51:01,0,2023-07-10 12:51:01
+322343,2023-07-10,40,UDM,,UDM,15M,UDMHA06,UDM.AmfUecmDeregSucc,total,2023-07-10 12:36:01,2023-07-10 12:51:01,1798,2023-07-10 12:51:01
+322344,2023-07-10,40,UDM,,UDM,15M,UDMHA10,UDM.SmfUecmDeregSucc,total,2023-07-10 12:36:01,2023-07-10 12:51:01,4498,2023-07-10 12:51:01
+322345,2023-07-10,40,UDM,,UDM,15M,UDMHA31,UDM.SmfUecmRegDnnNotAllowed,total,2023-07-10 12:36:01,2023-07-10 12:51:01,0,2023-07-10 12:51:01
+322346,2023-07-10,40,UDM,,UDM,15M,UDMHC04,Ausf.UeAuthAnsContextNotFound,total,2023-07-10 12:36:01,2023-07-10 12:51:01,0,2023-07-10 12:51:01
+322347,2023-07-10,40,UDM,,UDM,15M,UDMHA07,UDM.SmfUecmRegReq,total,2023-07-10 12:36:01,2023-07-10 12:51:01,4495,2023-07-10 12:51:01
+322348,2023-07-10,40,UDM,,UDM,15M,UDMHA19,UDM.SdmGetUserNotFound,total,2023-07-10 12:36:01,2023-07-10 12:51:01,0,2023-07-10 12:51:01
+322349,2023-07-10,40,UDM,,UDM,15M,UDMHC01,Ausf.UeAuthReq,total,2023-07-10 12:36:01,2023-07-10 12:51:01,1796,2023-07-10 12:51:01
+322350,2023-07-10,40,UDM,,UDM,15M,UDMHC03,Ausf.UeAuthAnsUserNotFound,total,2023-07-10 12:36:01,2023-07-10 12:51:01,0,2023-07-10 12:51:01
+322351,2023-07-10,40,UDM,,UDM,15M,UDMHA05,UDM.AmfUecmDeregReq,total,2023-07-10 12:36:01,2023-07-10 12:51:01,1798,2023-07-10 12:51:01
+322352,2023-07-10,40,UDM,,UDM,15M,UDMHA18,UDM.UecmDeregNotif,total,2023-07-10 12:36:01,2023-07-10 12:51:01,0,2023-07-10 12:51:01
+322353,2023-07-10,40,UDM,,UDM,15M,UDMHA24,UDM.AmfUecmRegRoamNotAllowed,total,2023-07-10 12:36:01,2023-07-10 12:51:01,0,2023-07-10 12:51:01
+322354,2023-07-10,40,UDM,,UDM,15M,UDMHC02,Ausf.UeAuthAnsSucc,total,2023-07-10 12:36:01,2023-07-10 12:51:01,1796,2023-07-10 12:51:01
+322355,2023-07-10,40,UDM,,UDM,15M,UDMHA01,UDM.AmfUecmRegReq,total,2023-07-10 12:36:01,2023-07-10 12:51:01,1796,2023-07-10 12:51:01
+322356,2023-07-10,40,UDM,,UDM,15M,UDMHA21,UDM.AmfUecmRegUserNotFound,total,2023-07-10 12:36:01,2023-07-10 12:51:01,0,2023-07-10 12:51:01
+322357,2023-07-10,40,UDM,,UDM,15M,UDMHA26,UDM.AmfUecmRegContextNotFound,total,2023-07-10 12:36:01,2023-07-10 12:51:01,0,2023-07-10 12:51:01
+322358,2023-07-10,40,UDM,,UDM,15M,UDMHA29,UDM.SmfUecmRegUnknownSub,total,2023-07-10 12:36:01,2023-07-10 12:51:01,0,2023-07-10 12:51:01
+322359,2023-07-10,40,UDM,,UDM,15M,UDMHB01,UDR.5gSupi,total,2023-07-10 12:36:01,2023-07-10 12:51:01,0,2023-07-10 12:51:01
+322360,2023-07-10,40,UDM,,UDM,15M,UDMHB03,UDR.5gActSub,total,2023-07-10 12:36:01,2023-07-10 12:51:01,71572,2023-07-10 12:51:01
+322361,2023-07-10,40,UDM,,UDM,15M,UDMHD01,ME.MeanMeLoad,total,2023-07-10 12:36:01,2023-07-10 12:51:01,0,2023-07-10 12:51:01
+322362,2023-07-10,40,UDM,,UDM,15M,UDMHA02,UDM.AmfUecmRegSucc,total,2023-07-10 12:36:01,2023-07-10 12:51:01,1796,2023-07-10 12:51:01
+322363,2023-07-10,40,UDM,,UDM,15M,UDMHA17,UDM.SdmUnSubscrSucc,total,2023-07-10 12:36:01,2023-07-10 12:51:01,6296,2023-07-10 12:51:01
+322364,2023-07-10,40,UDM,,UDM,15M,UDMHA09,UDM.SmfUecmDeregReq,total,2023-07-10 12:36:01,2023-07-10 12:51:01,4498,2023-07-10 12:51:01
+322365,2023-07-10,40,UDM,,UDM,15M,UDMHA16,UDM.SdmUnSubscrReq,total,2023-07-10 12:36:01,2023-07-10 12:51:01,6296,2023-07-10 12:51:01
+322366,2023-07-10,40,UDM,,UDM,15M,UDMHA25,UDM.AmfUecmRegRatNotAllowed,total,2023-07-10 12:36:01,2023-07-10 12:51:01,0,2023-07-10 12:51:01
+322367,2023-07-10,40,UDM,,UDM,15M,UDMHA27,UDM.AmfUecmRegReAuth,total,2023-07-10 12:36:01,2023-07-10 12:51:01,0,2023-07-10 12:51:01
+322368,2023-07-10,40,UDM,,UDM,15M,UDMHA03,UDM.AmfUecmRegUpdateReq,total,2023-07-10 12:36:01,2023-07-10 12:51:01,0,2023-07-10 12:51:01
+322369,2023-07-10,40,UDM,,UDM,15M,UDMHA08,UDM.SmfUecmRegSucc,total,2023-07-10 12:36:01,2023-07-10 12:51:01,4495,2023-07-10 12:51:01
+322370,2023-07-10,40,UDM,,UDM,15M,UDMHA15,UDM.SdmSubscrSucc,total,2023-07-10 12:51:01,2023-07-10 13:06:01,6293,2023-07-10 13:06:01
+322371,2023-07-10,40,UDM,,UDM,15M,UDMHA30,UDM.SmfUecmRegRoamNotAllowed,total,2023-07-10 12:51:01,2023-07-10 13:06:01,0,2023-07-10 13:06:01
+322372,2023-07-10,40,UDM,,UDM,15M,UDMHA04,UDM.AmfUecmRegUpdateSucc,total,2023-07-10 12:51:01,2023-07-10 13:06:01,0,2023-07-10 13:06:01
+322373,2023-07-10,40,UDM,,UDM,15M,UDMHA11,UDM.SdmGetReq,total,2023-07-10 12:51:01,2023-07-10 13:06:01,9889,2023-07-10 13:06:01
+322374,2023-07-10,40,UDM,,UDM,15M,UDMHA13,UDM.SdmNotif,total,2023-07-10 12:51:01,2023-07-10 13:06:01,0,2023-07-10 13:06:01
+322375,2023-07-10,40,UDM,,UDM,15M,UDMHB02,UDR.5gSub,total,2023-07-10 12:51:01,2023-07-10 13:06:01,0,2023-07-10 13:06:01
+322376,2023-07-10,40,UDM,,UDM,15M,UDMHA14,UDM.SdmSubscrReq,total,2023-07-10 12:51:01,2023-07-10 13:06:01,6293,2023-07-10 13:06:01
+322377,2023-07-10,40,UDM,,UDM,15M,UDMHA20,UDM.SdmGetDataNotFound,total,2023-07-10 12:51:01,2023-07-10 13:06:01,0,2023-07-10 13:06:01
+322378,2023-07-10,40,UDM,,UDM,15M,UDMHA22,UDM.AmfUecmRegUnknownSub,total,2023-07-10 12:51:01,2023-07-10 13:06:01,0,2023-07-10 13:06:01
+322379,2023-07-10,40,UDM,,UDM,15M,UDMHA23,UDM.AmfUecmRegNoPsSub,total,2023-07-10 12:51:01,2023-07-10 13:06:01,0,2023-07-10 13:06:01
+322380,2023-07-10,40,UDM,,UDM,15M,UDMHA28,UDM.SmfUecmRegUserNotFound,total,2023-07-10 12:51:01,2023-07-10 13:06:01,0,2023-07-10 13:06:01
+322381,2023-07-10,40,UDM,,UDM,15M,UDMHA06,UDM.AmfUecmDeregSucc,total,2023-07-10 12:51:01,2023-07-10 13:06:01,1797,2023-07-10 13:06:01
+322382,2023-07-10,40,UDM,,UDM,15M,UDMHA10,UDM.SmfUecmDeregSucc,total,2023-07-10 12:51:01,2023-07-10 13:06:01,4493,2023-07-10 13:06:01
+322383,2023-07-10,40,UDM,,UDM,15M,UDMHA12,UDM.SdmGetSucc,total,2023-07-10 12:51:01,2023-07-10 13:06:01,9889,2023-07-10 13:06:01
+322384,2023-07-10,40,UDM,,UDM,15M,UDMHA31,UDM.SmfUecmRegDnnNotAllowed,total,2023-07-10 12:51:01,2023-07-10 13:06:01,0,2023-07-10 13:06:01
+322385,2023-07-10,40,UDM,,UDM,15M,UDMHC04,Ausf.UeAuthAnsContextNotFound,total,2023-07-10 12:51:01,2023-07-10 13:06:01,0,2023-07-10 13:06:01
+322386,2023-07-10,40,UDM,,UDM,15M,UDMHA07,UDM.SmfUecmRegReq,total,2023-07-10 12:51:01,2023-07-10 13:06:01,4495,2023-07-10 13:06:01
+322387,2023-07-10,40,UDM,,UDM,15M,UDMHA19,UDM.SdmGetUserNotFound,total,2023-07-10 12:51:01,2023-07-10 13:06:01,0,2023-07-10 13:06:01
+322388,2023-07-10,40,UDM,,UDM,15M,UDMHC03,Ausf.UeAuthAnsUserNotFound,total,2023-07-10 12:51:01,2023-07-10 13:06:01,0,2023-07-10 13:06:01
+322389,2023-07-10,40,UDM,,UDM,15M,UDMHA05,UDM.AmfUecmDeregReq,total,2023-07-10 12:51:01,2023-07-10 13:06:01,1797,2023-07-10 13:06:01
+322390,2023-07-10,40,UDM,,UDM,15M,UDMHA18,UDM.UecmDeregNotif,total,2023-07-10 12:51:01,2023-07-10 13:06:01,0,2023-07-10 13:06:01
+322391,2023-07-10,40,UDM,,UDM,15M,UDMHC01,Ausf.UeAuthReq,total,2023-07-10 12:51:01,2023-07-10 13:06:01,1798,2023-07-10 13:06:01
+322392,2023-07-10,40,UDM,,UDM,15M,UDMHC02,Ausf.UeAuthAnsSucc,total,2023-07-10 12:51:01,2023-07-10 13:06:01,1798,2023-07-10 13:06:01
+322393,2023-07-10,40,UDM,,UDM,15M,UDMHA01,UDM.AmfUecmRegReq,total,2023-07-10 12:51:01,2023-07-10 13:06:01,1798,2023-07-10 13:06:01
+322394,2023-07-10,40,UDM,,UDM,15M,UDMHA21,UDM.AmfUecmRegUserNotFound,total,2023-07-10 12:51:01,2023-07-10 13:06:01,0,2023-07-10 13:06:01
+322395,2023-07-10,40,UDM,,UDM,15M,UDMHA24,UDM.AmfUecmRegRoamNotAllowed,total,2023-07-10 12:51:01,2023-07-10 13:06:01,0,2023-07-10 13:06:01
+322396,2023-07-10,40,UDM,,UDM,15M,UDMHA29,UDM.SmfUecmRegUnknownSub,total,2023-07-10 12:51:01,2023-07-10 13:06:01,0,2023-07-10 13:06:01
+322397,2023-07-10,40,UDM,,UDM,15M,UDMHB01,UDR.5gSupi,total,2023-07-10 12:51:01,2023-07-10 13:06:01,0,2023-07-10 13:06:01
+322398,2023-07-10,40,UDM,,UDM,15M,UDMHB03,UDR.5gActSub,total,2023-07-10 12:51:01,2023-07-10 13:06:01,71573,2023-07-10 13:06:01
+322399,2023-07-10,40,UDM,,UDM,15M,UDMHD01,ME.MeanMeLoad,total,2023-07-10 12:51:01,2023-07-10 13:06:01,0,2023-07-10 13:06:01
+322400,2023-07-10,40,UDM,,UDM,15M,UDMHA02,UDM.AmfUecmRegSucc,total,2023-07-10 12:51:01,2023-07-10 13:06:01,1798,2023-07-10 13:06:01
+322401,2023-07-10,40,UDM,,UDM,15M,UDMHA17,UDM.SdmUnSubscrSucc,total,2023-07-10 12:51:01,2023-07-10 13:06:01,6291,2023-07-10 13:06:01
+322402,2023-07-10,40,UDM,,UDM,15M,UDMHA26,UDM.AmfUecmRegContextNotFound,total,2023-07-10 12:51:01,2023-07-10 13:06:01,0,2023-07-10 13:06:01
+322403,2023-07-10,40,UDM,,UDM,15M,UDMHA16,UDM.SdmUnSubscrReq,total,2023-07-10 12:51:01,2023-07-10 13:06:01,6291,2023-07-10 13:06:01
+322404,2023-07-10,40,UDM,,UDM,15M,UDMHA25,UDM.AmfUecmRegRatNotAllowed,total,2023-07-10 12:51:01,2023-07-10 13:06:01,0,2023-07-10 13:06:01
+322405,2023-07-10,40,UDM,,UDM,15M,UDMHA27,UDM.AmfUecmRegReAuth,total,2023-07-10 12:51:01,2023-07-10 13:06:01,0,2023-07-10 13:06:01
+322406,2023-07-10,40,UDM,,UDM,15M,UDMHA03,UDM.AmfUecmRegUpdateReq,total,2023-07-10 12:51:01,2023-07-10 13:06:01,0,2023-07-10 13:06:01
+322407,2023-07-10,40,UDM,,UDM,15M,UDMHA08,UDM.SmfUecmRegSucc,total,2023-07-10 12:51:01,2023-07-10 13:06:01,4495,2023-07-10 13:06:01
+322408,2023-07-10,40,UDM,,UDM,15M,UDMHA09,UDM.SmfUecmDeregReq,total,2023-07-10 12:51:01,2023-07-10 13:06:01,4493,2023-07-10 13:06:01
+322409,2023-07-10,40,UDM,,UDM,15M,UDMHB03,UDR.5gActSub,total,2023-07-10 13:06:01,2023-07-10 13:21:01,71573,2023-07-10 13:21:01
+322410,2023-07-10,40,UDM,,UDM,15M,UDMHD01,ME.MeanMeLoad,total,2023-07-10 13:06:01,2023-07-10 13:21:01,0,2023-07-10 13:21:01
+322411,2023-07-10,40,UDM,,UDM,15M,UDMHA02,UDM.AmfUecmRegSucc,total,2023-07-10 13:06:01,2023-07-10 13:21:01,1796,2023-07-10 13:21:01
+322412,2023-07-10,40,UDM,,UDM,15M,UDMHA17,UDM.SdmUnSubscrSucc,total,2023-07-10 13:06:01,2023-07-10 13:21:01,6286,2023-07-10 13:21:01
+322413,2023-07-10,40,UDM,,UDM,15M,UDMHA26,UDM.AmfUecmRegContextNotFound,total,2023-07-10 13:06:01,2023-07-10 13:21:01,0,2023-07-10 13:21:01
+322414,2023-07-10,40,UDM,,UDM,15M,UDMHA29,UDM.SmfUecmRegUnknownSub,total,2023-07-10 13:06:01,2023-07-10 13:21:01,0,2023-07-10 13:21:01
+322415,2023-07-10,40,UDM,,UDM,15M,UDMHB01,UDR.5gSupi,total,2023-07-10 13:06:01,2023-07-10 13:21:01,0,2023-07-10 13:21:01
+322416,2023-07-10,40,UDM,,UDM,15M,UDMHA27,UDM.AmfUecmRegReAuth,total,2023-07-10 13:06:01,2023-07-10 13:21:01,0,2023-07-10 13:21:01
+322417,2023-07-10,40,UDM,,UDM,15M,UDMHA03,UDM.AmfUecmRegUpdateReq,total,2023-07-10 13:06:01,2023-07-10 13:21:01,0,2023-07-10 13:21:01
+322418,2023-07-10,40,UDM,,UDM,15M,UDMHA08,UDM.SmfUecmRegSucc,total,2023-07-10 13:06:01,2023-07-10 13:21:01,4491,2023-07-10 13:21:01
+322419,2023-07-10,40,UDM,,UDM,15M,UDMHA09,UDM.SmfUecmDeregReq,total,2023-07-10 13:06:01,2023-07-10 13:21:01,4491,2023-07-10 13:21:01
+322420,2023-07-10,40,UDM,,UDM,15M,UDMHA16,UDM.SdmUnSubscrReq,total,2023-07-10 13:06:01,2023-07-10 13:21:01,6286,2023-07-10 13:21:01
+322421,2023-07-10,40,UDM,,UDM,15M,UDMHA25,UDM.AmfUecmRegRatNotAllowed,total,2023-07-10 13:06:01,2023-07-10 13:21:01,0,2023-07-10 13:21:01
+322422,2023-07-10,40,UDM,,UDM,15M,UDMHA04,UDM.AmfUecmRegUpdateSucc,total,2023-07-10 13:06:01,2023-07-10 13:21:01,0,2023-07-10 13:21:01
+322423,2023-07-10,40,UDM,,UDM,15M,UDMHA11,UDM.SdmGetReq,total,2023-07-10 13:06:01,2023-07-10 13:21:01,9879,2023-07-10 13:21:01
+322424,2023-07-10,40,UDM,,UDM,15M,UDMHA13,UDM.SdmNotif,total,2023-07-10 13:06:01,2023-07-10 13:21:01,0,2023-07-10 13:21:01
+322425,2023-07-10,40,UDM,,UDM,15M,UDMHA15,UDM.SdmSubscrSucc,total,2023-07-10 13:06:01,2023-07-10 13:21:01,6287,2023-07-10 13:21:01
+322426,2023-07-10,40,UDM,,UDM,15M,UDMHA30,UDM.SmfUecmRegRoamNotAllowed,total,2023-07-10 13:06:01,2023-07-10 13:21:01,0,2023-07-10 13:21:01
+322427,2023-07-10,40,UDM,,UDM,15M,UDMHB02,UDR.5gSub,total,2023-07-10 13:06:01,2023-07-10 13:21:01,0,2023-07-10 13:21:01
+322428,2023-07-10,40,UDM,,UDM,15M,UDMHA22,UDM.AmfUecmRegUnknownSub,total,2023-07-10 13:06:01,2023-07-10 13:21:01,0,2023-07-10 13:21:01
+322429,2023-07-10,40,UDM,,UDM,15M,UDMHA23,UDM.AmfUecmRegNoPsSub,total,2023-07-10 13:06:01,2023-07-10 13:21:01,0,2023-07-10 13:21:01
+322430,2023-07-10,40,UDM,,UDM,15M,UDMHA28,UDM.SmfUecmRegUserNotFound,total,2023-07-10 13:06:01,2023-07-10 13:21:01,0,2023-07-10 13:21:01
+322431,2023-07-10,40,UDM,,UDM,15M,UDMHA06,UDM.AmfUecmDeregSucc,total,2023-07-10 13:06:01,2023-07-10 13:21:01,1796,2023-07-10 13:21:01
+322432,2023-07-10,40,UDM,,UDM,15M,UDMHA10,UDM.SmfUecmDeregSucc,total,2023-07-10 13:06:01,2023-07-10 13:21:01,4491,2023-07-10 13:21:01
+322433,2023-07-10,40,UDM,,UDM,15M,UDMHA12,UDM.SdmGetSucc,total,2023-07-10 13:06:01,2023-07-10 13:21:01,9879,2023-07-10 13:21:01
+322434,2023-07-10,40,UDM,,UDM,15M,UDMHA14,UDM.SdmSubscrReq,total,2023-07-10 13:06:01,2023-07-10 13:21:01,6287,2023-07-10 13:21:01
+322435,2023-07-10,40,UDM,,UDM,15M,UDMHA20,UDM.SdmGetDataNotFound,total,2023-07-10 13:06:01,2023-07-10 13:21:01,0,2023-07-10 13:21:01
+322436,2023-07-10,40,UDM,,UDM,15M,UDMHA31,UDM.SmfUecmRegDnnNotAllowed,total,2023-07-10 13:06:01,2023-07-10 13:21:01,0,2023-07-10 13:21:01
+322437,2023-07-10,40,UDM,,UDM,15M,UDMHC04,Ausf.UeAuthAnsContextNotFound,total,2023-07-10 13:06:01,2023-07-10 13:21:01,0,2023-07-10 13:21:01
+322438,2023-07-10,40,UDM,,UDM,15M,UDMHA07,UDM.SmfUecmRegReq,total,2023-07-10 13:06:01,2023-07-10 13:21:01,4491,2023-07-10 13:21:01
+322439,2023-07-10,40,UDM,,UDM,15M,UDMHA19,UDM.SdmGetUserNotFound,total,2023-07-10 13:06:01,2023-07-10 13:21:01,0,2023-07-10 13:21:01
+322440,2023-07-10,40,UDM,,UDM,15M,UDMHA05,UDM.AmfUecmDeregReq,total,2023-07-10 13:06:01,2023-07-10 13:21:01,1796,2023-07-10 13:21:01
+322441,2023-07-10,40,UDM,,UDM,15M,UDMHA18,UDM.UecmDeregNotif,total,2023-07-10 13:06:01,2023-07-10 13:21:01,0,2023-07-10 13:21:01
+322442,2023-07-10,40,UDM,,UDM,15M,UDMHC01,Ausf.UeAuthReq,total,2023-07-10 13:06:01,2023-07-10 13:21:01,1796,2023-07-10 13:21:01
+322443,2023-07-10,40,UDM,,UDM,15M,UDMHC03,Ausf.UeAuthAnsUserNotFound,total,2023-07-10 13:06:01,2023-07-10 13:21:01,0,2023-07-10 13:21:01
+322444,2023-07-10,40,UDM,,UDM,15M,UDMHA01,UDM.AmfUecmRegReq,total,2023-07-10 13:06:01,2023-07-10 13:21:01,1796,2023-07-10 13:21:01
+322445,2023-07-10,40,UDM,,UDM,15M,UDMHA21,UDM.AmfUecmRegUserNotFound,total,2023-07-10 13:06:01,2023-07-10 13:21:01,0,2023-07-10 13:21:01
+322446,2023-07-10,40,UDM,,UDM,15M,UDMHA24,UDM.AmfUecmRegRoamNotAllowed,total,2023-07-10 13:06:01,2023-07-10 13:21:01,0,2023-07-10 13:21:01
+322447,2023-07-10,40,UDM,,UDM,15M,UDMHC02,Ausf.UeAuthAnsSucc,total,2023-07-10 13:06:01,2023-07-10 13:21:01,1796,2023-07-10 13:21:01
+322448,2023-07-10,40,UDM,,UDM,15M,UDMHA29,UDM.SmfUecmRegUnknownSub,,2023-07-10 13:21:01,2023-07-10 13:36:01,0,2023-07-10 13:36:01
+322449,2023-07-10,40,UDM,,UDM,15M,UDMHB01,UDR.5gSupi,total,2023-07-10 13:21:01,2023-07-10 13:36:01,0,2023-07-10 13:36:01
+322450,2023-07-10,40,UDM,,UDM,15M,UDMHB03,UDR.5gActSub,total,2023-07-10 13:21:01,2023-07-10 13:36:01,71572,2023-07-10 13:36:01
+322451,2023-07-10,40,UDM,,UDM,15M,UDMHD01,ME.MeanMeLoad,total,2023-07-10 13:21:01,2023-07-10 13:36:01,0,2023-07-10 13:36:01
+322452,2023-07-10,40,UDM,,UDM,15M,UDMHA02,UDM.AmfUecmRegSucc,total,2023-07-10 13:21:01,2023-07-10 13:36:01,1797,2023-07-10 13:36:01
+322453,2023-07-10,40,UDM,,UDM,15M,UDMHA17,UDM.SdmUnSubscrSucc,total,2023-07-10 13:21:01,2023-07-10 13:36:01,6294,2023-07-10 13:36:01
+322454,2023-07-10,40,UDM,,UDM,15M,UDMHA26,UDM.AmfUecmRegContextNotFound,total,2023-07-10 13:21:01,2023-07-10 13:36:01,0,2023-07-10 13:36:01
+322455,2023-07-10,40,UDM,,UDM,15M,UDMHA16,UDM.SdmUnSubscrReq,total,2023-07-10 13:21:01,2023-07-10 13:36:01,6294,2023-07-10 13:36:01
+322456,2023-07-10,40,UDM,,UDM,15M,UDMHA25,UDM.AmfUecmRegRatNotAllowed,total,2023-07-10 13:21:01,2023-07-10 13:36:01,0,2023-07-10 13:36:01
+322457,2023-07-10,40,UDM,,UDM,15M,UDMHA27,UDM.AmfUecmRegReAuth,total,2023-07-10 13:21:01,2023-07-10 13:36:01,0,2023-07-10 13:36:01
+322458,2023-07-10,40,UDM,,UDM,15M,UDMHA03,UDM.AmfUecmRegUpdateReq,total,2023-07-10 13:21:01,2023-07-10 13:36:01,0,2023-07-10 13:36:01
+322459,2023-07-10,40,UDM,,UDM,15M,UDMHA08,UDM.SmfUecmRegSucc,total,2023-07-10 13:21:01,2023-07-10 13:36:01,4495,2023-07-10 13:36:01
+322460,2023-07-10,40,UDM,,UDM,15M,UDMHA09,UDM.SmfUecmDeregReq,total,2023-07-10 13:21:01,2023-07-10 13:36:01,4496,2023-07-10 13:36:01
+322461,2023-07-10,40,UDM,,UDM,15M,UDMHA15,UDM.SdmSubscrSucc,total,2023-07-10 13:21:01,2023-07-10 13:36:01,6292,2023-07-10 13:36:01
+322462,2023-07-10,40,UDM,,UDM,15M,UDMHA30,UDM.SmfUecmRegRoamNotAllowed,total,2023-07-10 13:21:01,2023-07-10 13:36:01,0,2023-07-10 13:36:01
+322463,2023-07-10,40,UDM,,UDM,15M,UDMHA04,UDM.AmfUecmRegUpdateSucc,total,2023-07-10 13:21:01,2023-07-10 13:36:01,0,2023-07-10 13:36:01
+322464,2023-07-10,40,UDM,,UDM,15M,UDMHA11,UDM.SdmGetReq,total,2023-07-10 13:21:01,2023-07-10 13:36:01,9886,2023-07-10 13:36:01
+322465,2023-07-10,40,UDM,,UDM,15M,UDMHA13,UDM.SdmNotif,total,2023-07-10 13:21:01,2023-07-10 13:36:01,0,2023-07-10 13:36:01
+322466,2023-07-10,40,UDM,,UDM,15M,UDMHB02,UDR.5gSub,total,2023-07-10 13:21:01,2023-07-10 13:36:01,0,2023-07-10 13:36:01
+322467,2023-07-10,40,UDM,,UDM,15M,UDMHA14,UDM.SdmSubscrReq,total,2023-07-10 13:21:01,2023-07-10 13:36:01,6292,2023-07-10 13:36:01
+322468,2023-07-10,40,UDM,,UDM,15M,UDMHA20,UDM.SdmGetDataNotFound,total,2023-07-10 13:21:01,2023-07-10 13:36:01,0,2023-07-10 13:36:01
+322469,2023-07-10,40,UDM,,UDM,15M,UDMHA22,UDM.AmfUecmRegUnknownSub,total,2023-07-10 13:21:01,2023-07-10 13:36:01,0,2023-07-10 13:36:01
+322470,2023-07-10,40,UDM,,UDM,15M,UDMHA23,UDM.AmfUecmRegNoPsSub,total,2023-07-10 13:21:01,2023-07-10 13:36:01,0,2023-07-10 13:36:01
+322471,2023-07-10,40,UDM,,UDM,15M,UDMHA28,UDM.SmfUecmRegUserNotFound,total,2023-07-10 13:21:01,2023-07-10 13:36:01,0,2023-07-10 13:36:01
+322472,2023-07-10,40,UDM,,UDM,15M,UDMHA06,UDM.AmfUecmDeregSucc,total,2023-07-10 13:21:01,2023-07-10 13:36:01,1798,2023-07-10 13:36:01
+322473,2023-07-10,40,UDM,,UDM,15M,UDMHA10,UDM.SmfUecmDeregSucc,total,2023-07-10 13:21:01,2023-07-10 13:36:01,4496,2023-07-10 13:36:01
+322474,2023-07-10,40,UDM,,UDM,15M,UDMHA12,UDM.SdmGetSucc,total,2023-07-10 13:21:01,2023-07-10 13:36:01,9886,2023-07-10 13:36:01
+322475,2023-07-10,40,UDM,,UDM,15M,UDMHA31,UDM.SmfUecmRegDnnNotAllowed,total,2023-07-10 13:21:01,2023-07-10 13:36:01,0,2023-07-10 13:36:01
+322476,2023-07-10,40,UDM,,UDM,15M,UDMHC04,Ausf.UeAuthAnsContextNotFound,total,2023-07-10 13:21:01,2023-07-10 13:36:01,0,2023-07-10 13:36:01
+322477,2023-07-10,40,UDM,,UDM,15M,UDMHA07,UDM.SmfUecmRegReq,total,2023-07-10 13:21:01,2023-07-10 13:36:01,4495,2023-07-10 13:36:01
+322478,2023-07-10,40,UDM,,UDM,15M,UDMHA19,UDM.SdmGetUserNotFound,total,2023-07-10 13:21:01,2023-07-10 13:36:01,0,2023-07-10 13:36:01
+322479,2023-07-10,40,UDM,,UDM,15M,UDMHC03,Ausf.UeAuthAnsUserNotFound,total,2023-07-10 13:21:01,2023-07-10 13:36:01,0,2023-07-10 13:36:01
+322480,2023-07-10,40,UDM,,UDM,15M,UDMHA05,UDM.AmfUecmDeregReq,total,2023-07-10 13:21:01,2023-07-10 13:36:01,1798,2023-07-10 13:36:01
+322481,2023-07-10,40,UDM,,UDM,15M,UDMHA18,UDM.UecmDeregNotif,total,2023-07-10 13:21:01,2023-07-10 13:36:01,0,2023-07-10 13:36:01
+322482,2023-07-10,40,UDM,,UDM,15M,UDMHC01,Ausf.UeAuthReq,total,2023-07-10 13:21:01,2023-07-10 13:36:01,1798,2023-07-10 13:36:01
+322483,2023-07-10,40,UDM,,UDM,15M,UDMHC02,Ausf.UeAuthAnsSucc,total,2023-07-10 13:21:01,2023-07-10 13:36:01,1798,2023-07-10 13:36:01
+322484,2023-07-10,40,UDM,,UDM,15M,UDMHA01,UDM.AmfUecmRegReq,total,2023-07-10 13:21:01,2023-07-10 13:36:01,1797,2023-07-10 13:36:01
+322485,2023-07-10,40,UDM,,UDM,15M,UDMHA21,UDM.AmfUecmRegUserNotFound,total,2023-07-10 13:21:01,2023-07-10 13:36:01,0,2023-07-10 13:36:01
+322486,2023-07-10,40,UDM,,UDM,15M,UDMHA24,UDM.AmfUecmRegRoamNotAllowed,total,2023-07-10 13:21:01,2023-07-10 13:36:01,0,2023-07-10 13:36:01
+322487,2023-07-10,40,UDM,,UDM,15M,UDMHA07,UDM.SmfUecmRegReq,total,2023-07-10 13:36:01,2023-07-10 13:51:01,4493,2023-07-10 13:51:01
+322488,2023-07-10,40,UDM,,UDM,15M,UDMHA19,UDM.SdmGetUserNotFound,total,2023-07-10 13:36:01,2023-07-10 13:51:01,0,2023-07-10 13:51:01
+322489,2023-07-10,40,UDM,,UDM,15M,UDMHC01,Ausf.UeAuthReq,total,2023-07-10 13:36:01,2023-07-10 13:51:01,1796,2023-07-10 13:51:01
+322490,2023-07-10,40,UDM,,UDM,15M,UDMHC03,Ausf.UeAuthAnsUserNotFound,total,2023-07-10 13:36:01,2023-07-10 13:51:01,0,2023-07-10 13:51:01
+322491,2023-07-10,40,UDM,,UDM,15M,UDMHA05,UDM.AmfUecmDeregReq,total,2023-07-10 13:36:01,2023-07-10 13:51:01,1802,2023-07-10 13:51:01
+322492,2023-07-10,40,UDM,,UDM,15M,UDMHA18,UDM.UecmDeregNotif,total,2023-07-10 13:36:01,2023-07-10 13:51:01,0,2023-07-10 13:51:01
+322493,2023-07-10,40,UDM,,UDM,15M,UDMHA24,UDM.AmfUecmRegRoamNotAllowed,total,2023-07-10 13:36:01,2023-07-10 13:51:01,0,2023-07-10 13:51:01
+322494,2023-07-10,40,UDM,,UDM,15M,UDMHC02,Ausf.UeAuthAnsSucc,total,2023-07-10 13:36:01,2023-07-10 13:51:01,1796,2023-07-10 13:51:01
+322495,2023-07-10,40,UDM,,UDM,15M,UDMHA01,UDM.AmfUecmRegReq,total,2023-07-10 13:36:01,2023-07-10 13:51:01,1797,2023-07-10 13:51:01
+322496,2023-07-10,40,UDM,,UDM,15M,UDMHA21,UDM.AmfUecmRegUserNotFound,total,2023-07-10 13:36:01,2023-07-10 13:51:01,0,2023-07-10 13:51:01
+322497,2023-07-10,40,UDM,,UDM,15M,UDMHA26,UDM.AmfUecmRegContextNotFound,total,2023-07-10 13:36:01,2023-07-10 13:51:01,0,2023-07-10 13:51:01
+322498,2023-07-10,40,UDM,,UDM,15M,UDMHA29,UDM.SmfUecmRegUnknownSub,total,2023-07-10 13:36:01,2023-07-10 13:51:01,0,2023-07-10 13:51:01
+322499,2023-07-10,40,UDM,,UDM,15M,UDMHB01,UDR.5gSupi,total,2023-07-10 13:36:01,2023-07-10 13:51:01,0,2023-07-10 13:51:01
+322500,2023-07-10,40,UDM,,UDM,15M,UDMHB03,UDR.5gActSub,total,2023-07-10 13:36:01,2023-07-10 13:51:01,71570,2023-07-10 13:51:01
+322501,2023-07-10,40,UDM,,UDM,15M,UDMHD01,ME.MeanMeLoad,total,2023-07-10 13:36:01,2023-07-10 13:51:01,0,2023-07-10 13:51:01
+322502,2023-07-10,40,UDM,,UDM,15M,UDMHA02,UDM.AmfUecmRegSucc,total,2023-07-10 13:36:01,2023-07-10 13:51:01,1797,2023-07-10 13:51:01
+322503,2023-07-10,40,UDM,,UDM,15M,UDMHA17,UDM.SdmUnSubscrSucc,total,2023-07-10 13:36:01,2023-07-10 13:51:01,6301,2023-07-10 13:51:01
+322504,2023-07-10,40,UDM,,UDM,15M,UDMHA09,UDM.SmfUecmDeregReq,total,2023-07-10 13:36:01,2023-07-10 13:51:01,4498,2023-07-10 13:51:01
+322505,2023-07-10,40,UDM,,UDM,15M,UDMHA16,UDM.SdmUnSubscrReq,total,2023-07-10 13:36:01,2023-07-10 13:51:01,6301,2023-07-10 13:51:01
+322506,2023-07-10,40,UDM,,UDM,15M,UDMHA25,UDM.AmfUecmRegRatNotAllowed,total,2023-07-10 13:36:01,2023-07-10 13:51:01,0,2023-07-10 13:51:01
+322507,2023-07-10,40,UDM,,UDM,15M,UDMHA27,UDM.AmfUecmRegReAuth,total,2023-07-10 13:36:01,2023-07-10 13:51:01,0,2023-07-10 13:51:01
+322508,2023-07-10,40,UDM,,UDM,15M,UDMHA03,UDM.AmfUecmRegUpdateReq,total,2023-07-10 13:36:01,2023-07-10 13:51:01,0,2023-07-10 13:51:01
+322509,2023-07-10,40,UDM,,UDM,15M,UDMHA08,UDM.SmfUecmRegSucc,total,2023-07-10 13:36:01,2023-07-10 13:51:01,4493,2023-07-10 13:51:01
+322510,2023-07-10,40,UDM,,UDM,15M,UDMHA13,UDM.SdmNotif,total,2023-07-10 13:36:01,2023-07-10 13:51:01,0,2023-07-10 13:51:01
+322511,2023-07-10,40,UDM,,UDM,15M,UDMHA15,UDM.SdmSubscrSucc,total,2023-07-10 13:36:01,2023-07-10 13:51:01,6290,2023-07-10 13:51:01
+322512,2023-07-10,40,UDM,,UDM,15M,UDMHA30,UDM.SmfUecmRegRoamNotAllowed,total,2023-07-10 13:36:01,2023-07-10 13:51:01,0,2023-07-10 13:51:01
+322513,2023-07-10,40,UDM,,UDM,15M,UDMHA04,UDM.AmfUecmRegUpdateSucc,total,2023-07-10 13:36:01,2023-07-10 13:51:01,0,2023-07-10 13:51:01
+322514,2023-07-10,40,UDM,,UDM,15M,UDMHA11,UDM.SdmGetReq,total,2023-07-10 13:36:01,2023-07-10 13:51:01,9884,2023-07-10 13:51:01
+322515,2023-07-10,40,UDM,,UDM,15M,UDMHB02,UDR.5gSub,total,2023-07-10 13:36:01,2023-07-10 13:51:01,0,2023-07-10 13:51:01
+322516,2023-07-10,40,UDM,,UDM,15M,UDMHA12,UDM.SdmGetSucc,total,2023-07-10 13:36:01,2023-07-10 13:51:01,9884,2023-07-10 13:51:01
+322517,2023-07-10,40,UDM,,UDM,15M,UDMHA14,UDM.SdmSubscrReq,total,2023-07-10 13:36:01,2023-07-10 13:51:01,6290,2023-07-10 13:51:01
+322518,2023-07-10,40,UDM,,UDM,15M,UDMHA20,UDM.SdmGetDataNotFound,total,2023-07-10 13:36:01,2023-07-10 13:51:01,0,2023-07-10 13:51:01
+322519,2023-07-10,40,UDM,,UDM,15M,UDMHA22,UDM.AmfUecmRegUnknownSub,total,2023-07-10 13:36:01,2023-07-10 13:51:01,0,2023-07-10 13:51:01
+322520,2023-07-10,40,UDM,,UDM,15M,UDMHA23,UDM.AmfUecmRegNoPsSub,total,2023-07-10 13:36:01,2023-07-10 13:51:01,0,2023-07-10 13:51:01
+322521,2023-07-10,40,UDM,,UDM,15M,UDMHA28,UDM.SmfUecmRegUserNotFound,total,2023-07-10 13:36:01,2023-07-10 13:51:01,0,2023-07-10 13:51:01
+322522,2023-07-10,40,UDM,,UDM,15M,UDMHA06,UDM.AmfUecmDeregSucc,total,2023-07-10 13:36:01,2023-07-10 13:51:01,1802,2023-07-10 13:51:01
+322523,2023-07-10,40,UDM,,UDM,15M,UDMHA10,UDM.SmfUecmDeregSucc,total,2023-07-10 13:36:01,2023-07-10 13:51:01,4498,2023-07-10 13:51:01
+322524,2023-07-10,40,UDM,,UDM,15M,UDMHA31,UDM.SmfUecmRegDnnNotAllowed,total,2023-07-10 13:36:01,2023-07-10 13:51:01,0,2023-07-10 13:51:01
+322525,2023-07-10,40,UDM,,UDM,15M,UDMHC04,Ausf.UeAuthAnsContextNotFound,total,2023-07-10 13:36:01,2023-07-10 13:51:01,0,2023-07-10 13:51:01
+322526,2023-07-10,40,UDM,,UDM,15M,UDMHA07,UDM.SmfUecmRegReq,total,2023-07-10 13:51:01,2023-07-10 14:06:01,4496,2023-07-10 14:06:01
+322527,2023-07-10,40,UDM,,UDM,15M,UDMHA19,UDM.SdmGetUserNotFound,total,2023-07-10 13:51:01,2023-07-10 14:06:01,0,2023-07-10 14:06:01
+322528,2023-07-10,40,UDM,,UDM,15M,UDMHA05,UDM.AmfUecmDeregReq,total,2023-07-10 13:51:01,2023-07-10 14:06:01,1798,2023-07-10 14:06:01
+322529,2023-07-10,40,UDM,,UDM,15M,UDMHA18,UDM.UecmDeregNotif,total,2023-07-10 13:51:01,2023-07-10 14:06:01,0,2023-07-10 14:06:01
+322530,2023-07-10,40,UDM,,UDM,15M,UDMHC01,Ausf.UeAuthReq,total,2023-07-10 13:51:01,2023-07-10 14:06:01,1798,2023-07-10 14:06:01
+322531,2023-07-10,40,UDM,,UDM,15M,UDMHC03,Ausf.UeAuthAnsUserNotFound,total,2023-07-10 13:51:01,2023-07-10 14:06:01,0,2023-07-10 14:06:01
+322532,2023-07-10,40,UDM,,UDM,15M,UDMHA01,UDM.AmfUecmRegReq,total,2023-07-10 13:51:01,2023-07-10 14:06:01,1796,2023-07-10 14:06:01
+322533,2023-07-10,40,UDM,,UDM,15M,UDMHA21,UDM.AmfUecmRegUserNotFound,total,2023-07-10 13:51:01,2023-07-10 14:06:01,0,2023-07-10 14:06:01
+322534,2023-07-10,40,UDM,,UDM,15M,UDMHA24,UDM.AmfUecmRegRoamNotAllowed,total,2023-07-10 13:51:01,2023-07-10 14:06:01,0,2023-07-10 14:06:01
+322535,2023-07-10,40,UDM,,UDM,15M,UDMHC02,Ausf.UeAuthAnsSucc,total,2023-07-10 13:51:01,2023-07-10 14:06:01,1798,2023-07-10 14:06:01
+322536,2023-07-10,40,UDM,,UDM,15M,UDMHB03,UDR.5gActSub,total,2023-07-10 13:51:01,2023-07-10 14:06:01,71568,2023-07-10 14:06:01
+322537,2023-07-10,40,UDM,,UDM,15M,UDMHD01,ME.MeanMeLoad,total,2023-07-10 13:51:01,2023-07-10 14:06:01,0,2023-07-10 14:06:01
+322538,2023-07-10,40,UDM,,UDM,15M,UDMHA02,UDM.AmfUecmRegSucc,total,2023-07-10 13:51:01,2023-07-10 14:06:01,1796,2023-07-10 14:06:01
+322539,2023-07-10,40,UDM,,UDM,15M,UDMHA17,UDM.SdmUnSubscrSucc,total,2023-07-10 13:51:01,2023-07-10 14:06:01,6294,2023-07-10 14:06:01
+322540,2023-07-10,40,UDM,,UDM,15M,UDMHA26,UDM.AmfUecmRegContextNotFound,total,2023-07-10 13:51:01,2023-07-10 14:06:01,0,2023-07-10 14:06:01
+322541,2023-07-10,40,UDM,,UDM,15M,UDMHA29,UDM.SmfUecmRegUnknownSub,total,2023-07-10 13:51:01,2023-07-10 14:06:01,0,2023-07-10 14:06:01
+322542,2023-07-10,40,UDM,,UDM,15M,UDMHB01,UDR.5gSupi,total,2023-07-10 13:51:01,2023-07-10 14:06:01,0,2023-07-10 14:06:01
+322543,2023-07-10,40,UDM,,UDM,15M,UDMHA27,UDM.AmfUecmRegReAuth,total,2023-07-10 13:51:01,2023-07-10 14:06:01,0,2023-07-10 14:06:01
+322544,2023-07-10,40,UDM,,UDM,15M,UDMHA03,UDM.AmfUecmRegUpdateReq,total,2023-07-10 13:51:01,2023-07-10 14:06:01,0,2023-07-10 14:06:01
+322545,2023-07-10,40,UDM,,UDM,15M,UDMHA08,UDM.SmfUecmRegSucc,total,2023-07-10 13:51:01,2023-07-10 14:06:01,4496,2023-07-10 14:06:01
+322546,2023-07-10,40,UDM,,UDM,15M,UDMHA09,UDM.SmfUecmDeregReq,total,2023-07-10 13:51:01,2023-07-10 14:06:01,4496,2023-07-10 14:06:01
+322547,2023-07-10,40,UDM,,UDM,15M,UDMHA16,UDM.SdmUnSubscrReq,total,2023-07-10 13:51:01,2023-07-10 14:06:01,6294,2023-07-10 14:06:01
+322548,2023-07-10,40,UDM,,UDM,15M,UDMHA25,UDM.AmfUecmRegRatNotAllowed,total,2023-07-10 13:51:01,2023-07-10 14:06:01,0,2023-07-10 14:06:01
+322549,2023-07-10,40,UDM,,UDM,15M,UDMHA04,UDM.AmfUecmRegUpdateSucc,total,2023-07-10 13:51:01,2023-07-10 14:06:01,0,2023-07-10 14:06:01
+322550,2023-07-10,40,UDM,,UDM,15M,UDMHA11,UDM.SdmGetReq,total,2023-07-10 13:51:01,2023-07-10 14:06:01,9884,2023-07-10 14:06:01
+322551,2023-07-10,40,UDM,,UDM,15M,UDMHA13,UDM.SdmNotif,total,2023-07-10 13:51:01,2023-07-10 14:06:01,0,2023-07-10 14:06:01
+322552,2023-07-10,40,UDM,,UDM,15M,UDMHA15,UDM.SdmSubscrSucc,total,2023-07-10 13:51:01,2023-07-10 14:06:01,6292,2023-07-10 14:06:01
+322553,2023-07-10,40,UDM,,UDM,15M,UDMHA30,UDM.SmfUecmRegRoamNotAllowed,total,2023-07-10 13:51:01,2023-07-10 14:06:01,0,2023-07-10 14:06:01
+322554,2023-07-10,40,UDM,,UDM,15M,UDMHB02,UDR.5gSub,total,2023-07-10 13:51:01,2023-07-10 14:06:01,0,2023-07-10 14:06:01
+322555,2023-07-10,40,UDM,,UDM,15M,UDMHA22,UDM.AmfUecmRegUnknownSub,total,2023-07-10 13:51:01,2023-07-10 14:06:01,0,2023-07-10 14:06:01
+322556,2023-07-10,40,UDM,,UDM,15M,UDMHA23,UDM.AmfUecmRegNoPsSub,total,2023-07-10 13:51:01,2023-07-10 14:06:01,0,2023-07-10 14:06:01
+322557,2023-07-10,40,UDM,,UDM,15M,UDMHA28,UDM.SmfUecmRegUserNotFound,total,2023-07-10 13:51:01,2023-07-10 14:06:01,0,2023-07-10 14:06:01
+322558,2023-07-10,40,UDM,,UDM,15M,UDMHA06,UDM.AmfUecmDeregSucc,total,2023-07-10 13:51:01,2023-07-10 14:06:01,1798,2023-07-10 14:06:01
+322559,2023-07-10,40,UDM,,UDM,15M,UDMHA10,UDM.SmfUecmDeregSucc,total,2023-07-10 13:51:01,2023-07-10 14:06:01,4496,2023-07-10 14:06:01
+322560,2023-07-10,40,UDM,,UDM,15M,UDMHA12,UDM.SdmGetSucc,total,2023-07-10 13:51:01,2023-07-10 14:06:01,9884,2023-07-10 14:06:01
+322561,2023-07-10,40,UDM,,UDM,15M,UDMHA14,UDM.SdmSubscrReq,total,2023-07-10 13:51:01,2023-07-10 14:06:01,6292,2023-07-10 14:06:01
+322562,2023-07-10,40,UDM,,UDM,15M,UDMHA20,UDM.SdmGetDataNotFound,total,2023-07-10 13:51:01,2023-07-10 14:06:01,0,2023-07-10 14:06:01
+322563,2023-07-10,40,UDM,,UDM,15M,UDMHA31,UDM.SmfUecmRegDnnNotAllowed,total,2023-07-10 13:51:01,2023-07-10 14:06:01,0,2023-07-10 14:06:01
+322564,2023-07-10,40,UDM,,UDM,15M,UDMHC04,Ausf.UeAuthAnsContextNotFound,total,2023-07-10 13:51:01,2023-07-10 14:06:01,0,2023-07-10 14:06:01
+322565,2023-07-12,38,AMF-SZ-01,46000-01,AMF,15M,AMFHA01,AMF.AuthReq,,2023-07-12 10:36:30,1970-01-01 00:00:00,99,2023-07-12 10:37:00
+322566,2023-07-22,44,AMF_001,1100RJHX1AMF001,AMF,30M,AMFHA01,AMF.AuthReq,,2023-07-22 17:02:03,1970-01-01 00:00:00,0,2023-07-22 17:03:00
+322567,2023-07-26,54,,,,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-26 11:32:35,1970-01-01 00:00:00,0,2023-07-26 11:45:00
+322568,2023-07-26,53,,,,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-26 11:32:31,1970-01-01 00:00:00,0,2023-07-26 11:45:00
+322569,2023-07-26,54,,,,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-26 11:32:35,1970-01-01 00:00:00,0,2023-07-26 11:45:00
+322570,2023-07-26,53,,,,15M,UPFHA03,UPF.PfcpSessionEstabFail,Total,2023-07-26 11:32:31,1970-01-01 00:00:00,0,2023-07-26 11:45:00
+322571,2023-07-26,54,,,,15M,UPFHA03,UPF.PfcpSessionEstabFail,Total,2023-07-26 11:32:35,1970-01-01 00:00:00,0,2023-07-26 11:45:00
+322572,2023-07-26,53,,,,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-26 11:32:31,1970-01-01 00:00:00,0,2023-07-26 11:45:00
+322573,2023-07-26,54,,,,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-26 11:32:35,1970-01-01 00:00:00,0,2023-07-26 11:45:00
+322574,2023-07-26,53,,,,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-26 11:32:31,1970-01-01 00:00:00,0,2023-07-26 11:45:00
+322575,2023-07-26,55,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-26 21:57:30,2023-07-26 22:15:00,0,2023-07-26 22:15:00
+322576,2023-07-26,55,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Dnn,Total,2023-07-26 21:57:30,2023-07-26 22:15:00,0,2023-07-26 22:15:00
+322577,2023-07-26,55,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-26 21:57:30,2023-07-26 22:15:00,0,2023-07-26 22:15:00
+322578,2023-07-26,55,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-26 21:57:30,2023-07-26 22:15:00,0,2023-07-26 22:15:00
+322579,2023-07-26,55,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA03,UPF.PfcpSessionEstabFail,Total,2023-07-26 21:57:30,2023-07-26 22:15:00,0,2023-07-26 22:15:00
+322580,2023-07-26,55,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA03,UPF.PfcpSessionEstabFail._Cause,Total,2023-07-26 21:57:30,2023-07-26 22:15:00,0,2023-07-26 22:15:00
+322581,2023-07-26,55,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA03,UPF.PfcpSessionEstabFail._Ns,Total,2023-07-26 21:57:30,2023-07-26 22:15:00,0,2023-07-26 22:15:00
+322582,2023-07-26,55,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-26 22:15:00,2023-07-26 22:30:00,0,2023-07-26 22:30:00
+322583,2023-07-26,55,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Dnn,Total,2023-07-26 22:15:00,2023-07-26 22:30:00,0,2023-07-26 22:30:00
+322584,2023-07-26,55,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-26 22:15:00,2023-07-26 22:30:00,0,2023-07-26 22:30:00
+322585,2023-07-26,55,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-26 22:15:00,2023-07-26 22:30:00,0,2023-07-26 22:30:00
+322586,2023-07-26,55,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA03,UPF.PfcpSessionEstabFail._Ns,Total,2023-07-26 22:15:00,2023-07-26 22:30:00,0,2023-07-26 22:30:00
+322587,2023-07-26,55,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA03,UPF.PfcpSessionEstabFail,Total,2023-07-26 22:15:00,2023-07-26 22:30:00,0,2023-07-26 22:30:00
+322588,2023-07-26,55,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA03,UPF.PfcpSessionEstabFail._Cause,Total,2023-07-26 22:15:00,2023-07-26 22:30:00,0,2023-07-26 22:30:00
+322589,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA09,UDM.SmfUecmDeregReq,,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322590,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA13,UDM.SdmNotif,,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322591,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHB01,UDR.5gSupi,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322592,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA11,UDM.SdmGetReq,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322593,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA18,UDM.UecmDeregNotif,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322594,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA20,UDM.SdmGetDataNotFound,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322595,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA21,UDM.AmfUecmRegUserNotFound,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322596,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA01,UDM.AmfUecmRegReq,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322597,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA02,UDM.AmfUecmRegSucc,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322598,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA03,UDM.AmfUecmRegUpdateReq,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322599,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA04,UDM.AmfUecmRegUpdateSucc,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322600,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA25,UDM.AmfUecmRegRatNotAllowed,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322601,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA27,UDM.AmfUecmRegReAuth,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322602,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHB03,UDR.5gActSub,total,2023-07-27 14:12:44,2023-07-27 14:28:00,70867,2023-07-27 14:28:00
+322603,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC04,Ausf.UeAuthAnsContextNotFound,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322604,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA07,UDM.SmfUecmRegReq,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322605,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA14,UDM.SdmSubscrReq,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322606,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA16,UDM.SdmUnSubscrReq,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322607,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA05,UDM.AmfUecmDeregReq,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322608,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA10,UDM.SmfUecmDeregSucc,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322609,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC02,Ausf.UeAuthAnsSucc,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322610,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA30,UDM.SmfUecmRegRoamNotAllowed,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322611,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA31,UDM.SmfUecmRegDnnNotAllowed,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322612,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC01,Ausf.UeAuthReq,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322613,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC03,Ausf.UeAuthAnsUserNotFound,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322614,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA24,UDM.AmfUecmRegRoamNotAllowed,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322615,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA26,UDM.AmfUecmRegContextNotFound,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322616,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA28,UDM.SmfUecmRegUserNotFound,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322617,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHB02,UDR.5gSub,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322618,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA12,UDM.SdmGetSucc,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322619,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA22,UDM.AmfUecmRegUnknownSub,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322620,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA29,UDM.SmfUecmRegUnknownSub,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322621,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA17,UDM.SdmUnSubscrSucc,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322622,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA19,UDM.SdmGetUserNotFound,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322623,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA23,UDM.AmfUecmRegNoPsSub,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322624,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHD01,ME.MeanMeLoad,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322625,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA06,UDM.AmfUecmDeregSucc,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322626,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA08,UDM.SmfUecmRegSucc,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322627,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA15,UDM.SdmSubscrSucc,total,2023-07-27 14:12:44,2023-07-27 14:28:00,0,2023-07-27 14:28:00
+322628,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA13,UDM.SdmNotif,,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322629,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHB01,UDR.5gSupi,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322630,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA09,UDM.SmfUecmDeregReq,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322631,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA02,UDM.AmfUecmRegSucc,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322632,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA03,UDM.AmfUecmRegUpdateReq,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322633,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA11,UDM.SdmGetReq,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322634,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA18,UDM.UecmDeregNotif,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322635,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA20,UDM.SdmGetDataNotFound,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322636,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA21,UDM.AmfUecmRegUserNotFound,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322637,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA01,UDM.AmfUecmRegReq,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322638,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA25,UDM.AmfUecmRegRatNotAllowed,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322639,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA27,UDM.AmfUecmRegReAuth,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322640,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA04,UDM.AmfUecmRegUpdateSucc,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322641,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA14,UDM.SdmSubscrReq,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322642,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA16,UDM.SdmUnSubscrReq,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322643,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHB03,UDR.5gActSub,total,2023-07-27 14:28:00,2023-07-27 14:43:00,70867,2023-07-27 14:43:00
+322644,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC04,Ausf.UeAuthAnsContextNotFound,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322645,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA07,UDM.SmfUecmRegReq,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322646,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA10,UDM.SmfUecmDeregSucc,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322647,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC02,Ausf.UeAuthAnsSucc,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322648,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA05,UDM.AmfUecmDeregReq,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322649,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA26,UDM.AmfUecmRegContextNotFound,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322650,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA28,UDM.SmfUecmRegUserNotFound,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322651,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA30,UDM.SmfUecmRegRoamNotAllowed,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322652,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA31,UDM.SmfUecmRegDnnNotAllowed,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322653,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC01,Ausf.UeAuthReq,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322654,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC03,Ausf.UeAuthAnsUserNotFound,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322655,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA24,UDM.AmfUecmRegRoamNotAllowed,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322656,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA22,UDM.AmfUecmRegUnknownSub,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322657,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA29,UDM.SmfUecmRegUnknownSub,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322658,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHB02,UDR.5gSub,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322659,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA12,UDM.SdmGetSucc,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322660,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA08,UDM.SmfUecmRegSucc,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322661,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA15,UDM.SdmSubscrSucc,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322662,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA17,UDM.SdmUnSubscrSucc,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322663,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA19,UDM.SdmGetUserNotFound,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322664,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA23,UDM.AmfUecmRegNoPsSub,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322665,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHD01,ME.MeanMeLoad,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322666,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA06,UDM.AmfUecmDeregSucc,total,2023-07-27 14:28:00,2023-07-27 14:43:00,0,2023-07-27 14:43:00
+322667,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA26,UDM.AmfUecmRegContextNotFound,,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322668,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA28,UDM.SmfUecmRegUserNotFound,,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322669,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA30,UDM.SmfUecmRegRoamNotAllowed,,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322670,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA31,UDM.SmfUecmRegDnnNotAllowed,,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322671,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC01,Ausf.UeAuthReq,,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322672,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC03,Ausf.UeAuthAnsUserNotFound,,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322673,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA24,UDM.AmfUecmRegRoamNotAllowed,,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322674,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA22,UDM.AmfUecmRegUnknownSub,,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322675,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA29,UDM.SmfUecmRegUnknownSub,,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322676,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHB02,UDR.5gSub,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322677,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA12,UDM.SdmGetSucc,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322678,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA08,UDM.SmfUecmRegSucc,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322679,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA15,UDM.SdmSubscrSucc,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322680,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA17,UDM.SdmUnSubscrSucc,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322681,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA19,UDM.SdmGetUserNotFound,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322682,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA23,UDM.AmfUecmRegNoPsSub,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322683,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHD01,ME.MeanMeLoad,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322684,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA06,UDM.AmfUecmDeregSucc,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322685,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA13,UDM.SdmNotif,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322686,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHB01,UDR.5gSupi,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322687,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA09,UDM.SmfUecmDeregReq,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322688,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA02,UDM.AmfUecmRegSucc,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322689,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA03,UDM.AmfUecmRegUpdateReq,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322690,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA11,UDM.SdmGetReq,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322691,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA18,UDM.UecmDeregNotif,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322692,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA20,UDM.SdmGetDataNotFound,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322693,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA21,UDM.AmfUecmRegUserNotFound,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322694,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA01,UDM.AmfUecmRegReq,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322695,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA25,UDM.AmfUecmRegRatNotAllowed,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322696,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA27,UDM.AmfUecmRegReAuth,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322697,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA04,UDM.AmfUecmRegUpdateSucc,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322698,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA14,UDM.SdmSubscrReq,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322699,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA16,UDM.SdmUnSubscrReq,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322700,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHB03,UDR.5gActSub,total,2023-07-27 14:43:00,2023-07-27 14:58:00,70867,2023-07-27 14:58:00
+322701,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC04,Ausf.UeAuthAnsContextNotFound,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322702,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA07,UDM.SmfUecmRegReq,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322703,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA10,UDM.SmfUecmDeregSucc,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322704,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC02,Ausf.UeAuthAnsSucc,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322705,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA05,UDM.AmfUecmDeregReq,total,2023-07-27 14:43:00,2023-07-27 14:58:00,0,2023-07-27 14:58:00
+322706,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA15,UDM.SdmSubscrSucc,,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322707,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA17,UDM.SdmUnSubscrSucc,,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322708,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA19,UDM.SdmGetUserNotFound,,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322709,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA23,UDM.AmfUecmRegNoPsSub,,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322710,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHD01,ME.MeanMeLoad,,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322711,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA06,UDM.AmfUecmDeregSucc,,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322712,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA08,UDM.SmfUecmRegSucc,,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322713,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHB01,UDR.5gSupi,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322714,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA09,UDM.SmfUecmDeregReq,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322715,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA13,UDM.SdmNotif,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322716,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA03,UDM.AmfUecmRegUpdateReq,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322717,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA11,UDM.SdmGetReq,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322718,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA18,UDM.UecmDeregNotif,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322719,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA20,UDM.SdmGetDataNotFound,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322720,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA21,UDM.AmfUecmRegUserNotFound,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322721,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA01,UDM.AmfUecmRegReq,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322722,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA02,UDM.AmfUecmRegSucc,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322723,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA27,UDM.AmfUecmRegReAuth,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322724,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA04,UDM.AmfUecmRegUpdateSucc,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322725,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA25,UDM.AmfUecmRegRatNotAllowed,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322726,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA16,UDM.SdmUnSubscrReq,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322727,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHB03,UDR.5gActSub,total,2023-07-27 14:58:00,2023-07-27 15:13:00,70867,2023-07-27 15:13:00
+322728,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC04,Ausf.UeAuthAnsContextNotFound,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322729,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA07,UDM.SmfUecmRegReq,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322730,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA14,UDM.SdmSubscrReq,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322731,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC02,Ausf.UeAuthAnsSucc,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322732,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA05,UDM.AmfUecmDeregReq,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322733,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA10,UDM.SmfUecmDeregSucc,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322734,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA28,UDM.SmfUecmRegUserNotFound,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322735,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA30,UDM.SmfUecmRegRoamNotAllowed,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322736,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA31,UDM.SmfUecmRegDnnNotAllowed,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322737,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC01,Ausf.UeAuthReq,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322738,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC03,Ausf.UeAuthAnsUserNotFound,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322739,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA24,UDM.AmfUecmRegRoamNotAllowed,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322740,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA26,UDM.AmfUecmRegContextNotFound,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322741,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA29,UDM.SmfUecmRegUnknownSub,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322742,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHB02,UDR.5gSub,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322743,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA12,UDM.SdmGetSucc,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322744,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA22,UDM.AmfUecmRegUnknownSub,total,2023-07-27 14:58:00,2023-07-27 15:13:00,0,2023-07-27 15:13:00
+322745,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA09,UDM.SmfUecmDeregReq,,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322746,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA13,UDM.SdmNotif,,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322747,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHB01,UDR.5gSupi,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322748,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA01,UDM.AmfUecmRegReq,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322749,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA02,UDM.AmfUecmRegSucc,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322750,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA03,UDM.AmfUecmRegUpdateReq,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322751,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA11,UDM.SdmGetReq,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322752,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA18,UDM.UecmDeregNotif,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322753,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA20,UDM.SdmGetDataNotFound,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322754,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA21,UDM.AmfUecmRegUserNotFound,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322755,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA04,UDM.AmfUecmRegUpdateSucc,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322756,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA25,UDM.AmfUecmRegRatNotAllowed,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322757,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA27,UDM.AmfUecmRegReAuth,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322758,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA07,UDM.SmfUecmRegReq,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322759,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA14,UDM.SdmSubscrReq,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322760,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA16,UDM.SdmUnSubscrReq,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322761,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHB03,UDR.5gActSub,total,2023-07-27 15:13:00,2023-07-27 15:28:00,70867,2023-07-27 15:28:00
+322762,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC04,Ausf.UeAuthAnsContextNotFound,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322763,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA05,UDM.AmfUecmDeregReq,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322764,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA10,UDM.SmfUecmDeregSucc,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322765,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC02,Ausf.UeAuthAnsSucc,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322766,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA24,UDM.AmfUecmRegRoamNotAllowed,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322767,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA26,UDM.AmfUecmRegContextNotFound,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322768,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA28,UDM.SmfUecmRegUserNotFound,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322769,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA30,UDM.SmfUecmRegRoamNotAllowed,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322770,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA31,UDM.SmfUecmRegDnnNotAllowed,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322771,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC01,Ausf.UeAuthReq,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322772,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC03,Ausf.UeAuthAnsUserNotFound,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322773,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA12,UDM.SdmGetSucc,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322774,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA22,UDM.AmfUecmRegUnknownSub,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322775,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA29,UDM.SmfUecmRegUnknownSub,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322776,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHB02,UDR.5gSub,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322777,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA06,UDM.AmfUecmDeregSucc,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322778,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA08,UDM.SmfUecmRegSucc,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322779,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA15,UDM.SdmSubscrSucc,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322780,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA17,UDM.SdmUnSubscrSucc,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322781,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA19,UDM.SdmGetUserNotFound,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322782,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA23,UDM.AmfUecmRegNoPsSub,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322783,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHD01,ME.MeanMeLoad,total,2023-07-27 15:13:00,2023-07-27 15:28:00,0,2023-07-27 15:28:00
+322784,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC02,Ausf.UeAuthAnsSucc,,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322785,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA05,UDM.AmfUecmDeregReq,,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322786,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA10,UDM.SmfUecmDeregSucc,,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322787,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA28,UDM.SmfUecmRegUserNotFound,,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322788,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA30,UDM.SmfUecmRegRoamNotAllowed,,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322789,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA31,UDM.SmfUecmRegDnnNotAllowed,,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322790,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC01,Ausf.UeAuthReq,,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322791,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC03,Ausf.UeAuthAnsUserNotFound,,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322792,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA24,UDM.AmfUecmRegRoamNotAllowed,,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322793,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA26,UDM.AmfUecmRegContextNotFound,,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322794,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA29,UDM.SmfUecmRegUnknownSub,,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322795,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHB02,UDR.5gSub,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322796,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA12,UDM.SdmGetSucc,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322797,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA22,UDM.AmfUecmRegUnknownSub,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322798,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA15,UDM.SdmSubscrSucc,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322799,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA17,UDM.SdmUnSubscrSucc,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322800,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA19,UDM.SdmGetUserNotFound,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322801,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA23,UDM.AmfUecmRegNoPsSub,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322802,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHD01,ME.MeanMeLoad,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322803,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA06,UDM.AmfUecmDeregSucc,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322804,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA08,UDM.SmfUecmRegSucc,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322805,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHB01,UDR.5gSupi,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322806,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA09,UDM.SmfUecmDeregReq,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322807,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA13,UDM.SdmNotif,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322808,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA03,UDM.AmfUecmRegUpdateReq,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322809,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA11,UDM.SdmGetReq,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322810,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA18,UDM.UecmDeregNotif,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322811,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA20,UDM.SdmGetDataNotFound,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322812,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA21,UDM.AmfUecmRegUserNotFound,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322813,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA01,UDM.AmfUecmRegReq,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322814,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA02,UDM.AmfUecmRegSucc,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322815,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA27,UDM.AmfUecmRegReAuth,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322816,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA04,UDM.AmfUecmRegUpdateSucc,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322817,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA25,UDM.AmfUecmRegRatNotAllowed,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322818,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA16,UDM.SdmUnSubscrReq,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322819,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHB03,UDR.5gActSub,total,2023-07-27 15:28:00,2023-07-27 15:43:00,70867,2023-07-27 15:43:00
+322820,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC04,Ausf.UeAuthAnsContextNotFound,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322821,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA07,UDM.SmfUecmRegReq,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322822,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA14,UDM.SdmSubscrReq,total,2023-07-27 15:28:00,2023-07-27 15:43:00,0,2023-07-27 15:43:00
+322823,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA28,UDM.SmfUecmRegUserNotFound,,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322824,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA30,UDM.SmfUecmRegRoamNotAllowed,,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322825,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA31,UDM.SmfUecmRegDnnNotAllowed,,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322826,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC01,Ausf.UeAuthReq,,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322827,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC03,Ausf.UeAuthAnsUserNotFound,,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322828,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA24,UDM.AmfUecmRegRoamNotAllowed,,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322829,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA26,UDM.AmfUecmRegContextNotFound,,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322830,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA29,UDM.SmfUecmRegUnknownSub,,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322831,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHB02,UDR.5gSub,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322832,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA12,UDM.SdmGetSucc,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322833,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA22,UDM.AmfUecmRegUnknownSub,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322834,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA15,UDM.SdmSubscrSucc,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322835,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA17,UDM.SdmUnSubscrSucc,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322836,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA19,UDM.SdmGetUserNotFound,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322837,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA23,UDM.AmfUecmRegNoPsSub,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322838,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHD01,ME.MeanMeLoad,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322839,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA06,UDM.AmfUecmDeregSucc,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322840,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA08,UDM.SmfUecmRegSucc,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322841,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHB01,UDR.5gSupi,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322842,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA09,UDM.SmfUecmDeregReq,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322843,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA13,UDM.SdmNotif,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322844,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA03,UDM.AmfUecmRegUpdateReq,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322845,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA11,UDM.SdmGetReq,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322846,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA18,UDM.UecmDeregNotif,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322847,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA20,UDM.SdmGetDataNotFound,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322848,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA21,UDM.AmfUecmRegUserNotFound,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322849,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA01,UDM.AmfUecmRegReq,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322850,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA02,UDM.AmfUecmRegSucc,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322851,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA27,UDM.AmfUecmRegReAuth,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322852,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA04,UDM.AmfUecmRegUpdateSucc,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322853,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA25,UDM.AmfUecmRegRatNotAllowed,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322854,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA16,UDM.SdmUnSubscrReq,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322855,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHB03,UDR.5gActSub,total,2023-07-27 15:43:00,2023-07-27 15:58:00,70867,2023-07-27 15:58:00
+322856,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC04,Ausf.UeAuthAnsContextNotFound,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322857,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA07,UDM.SmfUecmRegReq,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322858,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA14,UDM.SdmSubscrReq,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322859,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHC02,Ausf.UeAuthAnsSucc,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322860,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA05,UDM.AmfUecmDeregReq,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322861,2023-07-27,56,UDM_001,1100RJHX1UDM001,UDM,15M,UDMHA10,UDM.SmfUecmDeregSucc,total,2023-07-27 15:43:00,2023-07-27 15:58:00,0,2023-07-27 15:58:00
+322862,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 16:08:59,2023-07-27 16:30:00,0,2023-07-27 16:30:00
+322863,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 16:08:59,2023-07-27 16:30:00,0,2023-07-27 16:30:00
+322864,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 16:08:59,2023-07-27 16:30:00,0,2023-07-27 16:30:00
+322865,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 16:08:59,2023-07-27 16:30:00,0,2023-07-27 16:30:00
+322866,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 16:08:59,2023-07-27 16:30:00,0,2023-07-27 16:30:00
+322867,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,Total,2023-07-27 16:08:59,2023-07-27 16:30:00,0,2023-07-27 16:30:00
+322868,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 16:30:00,2023-07-27 16:45:00,0,2023-07-27 16:45:00
+322869,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 16:30:00,2023-07-27 16:45:00,0,2023-07-27 16:45:00
+322870,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 16:30:00,2023-07-27 16:45:00,0,2023-07-27 16:45:00
+322871,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 16:30:00,2023-07-27 16:45:00,0,2023-07-27 16:45:00
+322872,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 16:30:00,2023-07-27 16:45:00,0,2023-07-27 16:45:00
+322873,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,Total,2023-07-27 16:30:00,2023-07-27 16:45:00,0,2023-07-27 16:45:00
+322874,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 16:45:00,2023-07-27 17:00:00,0,2023-07-27 17:00:00
+322875,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 16:45:00,2023-07-27 17:00:00,0,2023-07-27 17:00:00
+322876,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 16:45:00,2023-07-27 17:00:00,0,2023-07-27 17:00:00
+322877,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,Total,2023-07-27 16:45:00,2023-07-27 17:00:00,0,2023-07-27 17:00:00
+322878,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 16:45:00,2023-07-27 17:00:00,0,2023-07-27 17:00:00
+322879,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 16:45:00,2023-07-27 17:00:00,0,2023-07-27 17:00:00
+322880,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 17:00:00,2023-07-27 17:15:00,0,2023-07-27 17:15:00
+322881,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 17:00:00,2023-07-27 17:15:00,0,2023-07-27 17:15:00
+322882,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 17:00:00,2023-07-27 17:15:00,0,2023-07-27 17:15:00
+322883,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 17:00:00,2023-07-27 17:15:00,0,2023-07-27 17:15:00
+322884,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 17:00:00,2023-07-27 17:15:00,0,2023-07-27 17:15:00
+322885,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,Total,2023-07-27 17:00:00,2023-07-27 17:15:00,0,2023-07-27 17:15:00
+322886,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 17:15:00,2023-07-27 17:30:00,0,2023-07-27 17:30:00
+322887,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 17:15:00,2023-07-27 17:30:00,0,2023-07-27 17:30:00
+322888,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 17:15:00,2023-07-27 17:30:00,0,2023-07-27 17:30:00
+322889,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 17:15:00,2023-07-27 17:30:00,0,2023-07-27 17:30:00
+322890,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 17:15:00,2023-07-27 17:30:00,0,2023-07-27 17:30:00
+322891,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,Total,2023-07-27 17:15:00,2023-07-27 17:30:00,0,2023-07-27 17:30:00
+322892,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 17:30:00,2023-07-27 17:45:00,0,2023-07-27 17:45:00
+322893,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 17:30:00,2023-07-27 17:45:00,0,2023-07-27 17:45:00
+322894,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 17:30:00,2023-07-27 17:45:00,0,2023-07-27 17:45:00
+322895,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 17:30:00,2023-07-27 17:45:00,0,2023-07-27 17:45:00
+322896,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 17:30:00,2023-07-27 17:45:00,0,2023-07-27 17:45:00
+322897,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,Total,2023-07-27 17:30:00,2023-07-27 17:45:00,0,2023-07-27 17:45:00
+322898,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 17:45:00,2023-07-27 18:00:00,0,2023-07-27 18:00:00
+322899,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 17:45:00,2023-07-27 18:00:00,0,2023-07-27 18:00:00
+322900,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 17:45:00,2023-07-27 18:00:00,0,2023-07-27 18:00:00
+322901,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 17:45:00,2023-07-27 18:00:00,0,2023-07-27 18:00:00
+322902,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 17:45:00,2023-07-27 18:00:00,0,2023-07-27 18:00:00
+322903,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,Total,2023-07-27 17:45:00,2023-07-27 18:00:00,0,2023-07-27 18:00:00
+322904,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 18:00:00,2023-07-27 18:15:00,0,2023-07-27 18:15:00
+322905,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 18:00:00,2023-07-27 18:15:00,0,2023-07-27 18:15:00
+322906,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 18:00:00,2023-07-27 18:15:00,0,2023-07-27 18:15:00
+322907,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 18:00:00,2023-07-27 18:15:00,0,2023-07-27 18:15:00
+322908,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 18:00:00,2023-07-27 18:15:00,0,2023-07-27 18:15:00
+322909,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,Total,2023-07-27 18:00:00,2023-07-27 18:15:00,0,2023-07-27 18:15:00
+322910,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 18:15:00,2023-07-27 18:30:00,0,2023-07-27 18:30:00
+322911,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 18:15:00,2023-07-27 18:30:00,0,2023-07-27 18:30:00
+322912,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,Total,2023-07-27 18:15:00,2023-07-27 18:30:00,0,2023-07-27 18:30:00
+322913,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 18:15:00,2023-07-27 18:30:00,0,2023-07-27 18:30:00
+322914,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 18:15:00,2023-07-27 18:30:00,0,2023-07-27 18:30:00
+322915,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 18:15:00,2023-07-27 18:30:00,0,2023-07-27 18:30:00
+322916,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 18:30:00,2023-07-27 18:45:00,0,2023-07-27 18:45:00
+322917,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 18:30:00,2023-07-27 18:45:00,0,2023-07-27 18:45:00
+322918,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 18:30:00,2023-07-27 18:45:00,0,2023-07-27 18:45:00
+322919,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 18:30:00,2023-07-27 18:45:00,0,2023-07-27 18:45:00
+322920,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 18:30:00,2023-07-27 18:45:00,0,2023-07-27 18:45:00
+322921,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,Total,2023-07-27 18:30:00,2023-07-27 18:45:00,0,2023-07-27 18:45:00
+322922,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 18:45:00,2023-07-27 19:00:00,0,2023-07-27 19:00:00
+322923,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,Total,2023-07-27 18:45:00,2023-07-27 19:00:00,0,2023-07-27 19:00:00
+322924,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 18:45:00,2023-07-27 19:00:00,0,2023-07-27 19:00:00
+322925,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 18:45:00,2023-07-27 19:00:00,0,2023-07-27 19:00:00
+322926,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 18:45:00,2023-07-27 19:00:00,0,2023-07-27 19:00:00
+322927,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 18:45:00,2023-07-27 19:00:00,0,2023-07-27 19:00:00
+322928,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,,2023-07-27 19:00:00,2023-07-27 19:15:00,0,2023-07-27 19:15:00
+322929,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 19:00:00,2023-07-27 19:15:00,0,2023-07-27 19:15:00
+322930,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 19:00:00,2023-07-27 19:15:00,0,2023-07-27 19:15:00
+322931,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 19:00:00,2023-07-27 19:15:00,0,2023-07-27 19:15:00
+322932,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 19:00:00,2023-07-27 19:15:00,0,2023-07-27 19:15:00
+322933,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 19:00:00,2023-07-27 19:15:00,0,2023-07-27 19:15:00
+322934,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 19:15:00,2023-07-27 19:30:00,0,2023-07-27 19:30:00
+322935,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 19:15:00,2023-07-27 19:30:00,0,2023-07-27 19:30:00
+322936,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 19:15:00,2023-07-27 19:30:00,0,2023-07-27 19:30:00
+322937,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 19:15:00,2023-07-27 19:30:00,0,2023-07-27 19:30:00
+322938,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 19:15:00,2023-07-27 19:30:00,0,2023-07-27 19:30:00
+322939,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,Total,2023-07-27 19:15:00,2023-07-27 19:30:00,0,2023-07-27 19:30:00
+322940,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 19:30:00,2023-07-27 19:45:00,0,2023-07-27 19:45:00
+322941,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 19:30:00,2023-07-27 19:45:00,0,2023-07-27 19:45:00
+322942,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 19:30:00,2023-07-27 19:45:00,0,2023-07-27 19:45:00
+322943,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 19:30:00,2023-07-27 19:45:00,0,2023-07-27 19:45:00
+322944,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 19:30:00,2023-07-27 19:45:00,0,2023-07-27 19:45:00
+322945,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,Total,2023-07-27 19:30:00,2023-07-27 19:45:00,0,2023-07-27 19:45:00
+322946,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 19:45:00,2023-07-27 20:00:00,0,2023-07-27 20:00:00
+322947,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 19:45:00,2023-07-27 20:00:00,0,2023-07-27 20:00:00
+322948,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 19:45:00,2023-07-27 20:00:00,0,2023-07-27 20:00:00
+322949,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 19:45:00,2023-07-27 20:00:00,0,2023-07-27 20:00:00
+322950,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 19:45:00,2023-07-27 20:00:00,0,2023-07-27 20:00:00
+322951,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,Total,2023-07-27 19:45:00,2023-07-27 20:00:00,0,2023-07-27 20:00:00
+322952,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 20:00:00,2023-07-27 20:15:00,0,2023-07-27 20:15:00
+322953,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 20:00:00,2023-07-27 20:15:00,0,2023-07-27 20:15:00
+322954,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 20:00:00,2023-07-27 20:15:00,0,2023-07-27 20:15:00
+322955,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 20:00:00,2023-07-27 20:15:00,0,2023-07-27 20:15:00
+322956,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 20:00:00,2023-07-27 20:15:00,0,2023-07-27 20:15:00
+322957,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,Total,2023-07-27 20:00:00,2023-07-27 20:15:00,0,2023-07-27 20:15:00
+322958,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 20:15:00,2023-07-27 20:30:00,0,2023-07-27 20:30:00
+322959,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 20:15:00,2023-07-27 20:30:00,0,2023-07-27 20:30:00
+322960,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 20:15:00,2023-07-27 20:30:00,0,2023-07-27 20:30:00
+322961,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 20:15:00,2023-07-27 20:30:00,0,2023-07-27 20:30:00
+322962,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 20:15:00,2023-07-27 20:30:00,0,2023-07-27 20:30:00
+322963,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,Total,2023-07-27 20:15:00,2023-07-27 20:30:00,0,2023-07-27 20:30:00
+322964,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,,2023-07-27 20:30:00,2023-07-27 20:45:00,0,2023-07-27 20:45:00
+322965,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 20:30:00,2023-07-27 20:45:00,0,2023-07-27 20:45:00
+322966,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 20:30:00,2023-07-27 20:45:00,0,2023-07-27 20:45:00
+322967,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 20:30:00,2023-07-27 20:45:00,0,2023-07-27 20:45:00
+322968,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 20:30:00,2023-07-27 20:45:00,0,2023-07-27 20:45:00
+322969,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,Total,2023-07-27 20:30:00,2023-07-27 20:45:00,0,2023-07-27 20:45:00
+322970,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 20:45:00,2023-07-27 21:00:00,0,2023-07-27 21:00:00
+322971,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 20:45:00,2023-07-27 21:00:00,0,2023-07-27 21:00:00
+322972,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 20:45:00,2023-07-27 21:00:00,0,2023-07-27 21:00:00
+322973,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 20:45:00,2023-07-27 21:00:00,0,2023-07-27 21:00:00
+322974,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 20:45:00,2023-07-27 21:00:00,0,2023-07-27 21:00:00
+322975,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,Total,2023-07-27 20:45:00,2023-07-27 21:00:00,0,2023-07-27 21:00:00
+322976,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 21:00:00,2023-07-27 21:15:00,0,2023-07-27 21:15:00
+322977,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 21:00:00,2023-07-27 21:15:00,0,2023-07-27 21:15:00
+322978,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 21:00:00,2023-07-27 21:15:00,0,2023-07-27 21:15:00
+322979,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 21:00:00,2023-07-27 21:15:00,0,2023-07-27 21:15:00
+322980,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 21:00:00,2023-07-27 21:15:00,0,2023-07-27 21:15:00
+322981,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,Total,2023-07-27 21:00:00,2023-07-27 21:15:00,0,2023-07-27 21:15:00
+322982,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 20:51:31,2023-07-27 21:15:00,4,2023-07-27 21:15:00
+322983,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 20:51:31,2023-07-27 21:15:00,0,2023-07-27 21:15:00
+322984,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 20:51:31,2023-07-27 21:15:00,4,2023-07-27 21:15:00
+322985,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 20:51:31,2023-07-27 21:15:00,0,2023-07-27 21:15:00
+322986,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA03,UPF.PfcpSessionEstabFail._Cause,Total,2023-07-27 20:51:31,2023-07-27 21:15:00,0,2023-07-27 21:15:00
+322987,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA03,UPF.PfcpSessionEstabFail,Total,2023-07-27 20:51:31,2023-07-27 21:15:00,0,2023-07-27 21:15:00
+322988,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA06,UPF.PfcpSessionModifyFail._Ns,Total,2023-07-27 20:51:31,2023-07-27 21:15:00,0,2023-07-27 21:15:00
+322989,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA06,UPF.PfcpSessionModifyFail,Total,2023-07-27 20:51:31,2023-07-27 21:15:00,0,2023-07-27 21:15:00
+322990,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 21:15:00,2023-07-27 21:30:00,0,2023-07-27 21:30:00
+322991,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 21:15:00,2023-07-27 21:30:00,0,2023-07-27 21:30:00
+322992,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 21:15:00,2023-07-27 21:30:00,0,2023-07-27 21:30:00
+322993,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 21:15:00,2023-07-27 21:30:00,0,2023-07-27 21:30:00
+322994,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 21:15:00,2023-07-27 21:30:00,0,2023-07-27 21:30:00
+322995,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,Total,2023-07-27 21:15:00,2023-07-27 21:30:00,0,2023-07-27 21:30:00
+322996,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 21:15:00,2023-07-27 21:30:00,0,2023-07-27 21:30:00
+322997,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 21:15:00,2023-07-27 21:30:00,0,2023-07-27 21:30:00
+322998,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 21:15:00,2023-07-27 21:30:00,0,2023-07-27 21:30:00
+322999,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 21:15:00,2023-07-27 21:30:00,0,2023-07-27 21:30:00
+323000,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA03,UPF.PfcpSessionEstabFail,Total,2023-07-27 21:15:00,2023-07-27 21:30:00,0,2023-07-27 21:30:00
+323001,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA03,UPF.PfcpSessionEstabFail._Cause,Total,2023-07-27 21:15:00,2023-07-27 21:30:00,0,2023-07-27 21:30:00
+323002,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA06,UPF.PfcpSessionModifyFail._Ns,Total,2023-07-27 21:15:00,2023-07-27 21:30:00,0,2023-07-27 21:30:00
+323003,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA06,UPF.PfcpSessionModifyFail,Total,2023-07-27 21:15:00,2023-07-27 21:30:00,0,2023-07-27 21:30:00
+323004,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,,2023-07-27 21:30:00,2023-07-27 21:45:00,0,2023-07-27 21:45:00
+323005,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 21:30:00,2023-07-27 21:45:00,0,2023-07-27 21:45:00
+323006,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 21:30:00,2023-07-27 21:45:00,0,2023-07-27 21:45:00
+323007,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 21:30:00,2023-07-27 21:45:00,0,2023-07-27 21:45:00
+323008,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 21:30:00,2023-07-27 21:45:00,0,2023-07-27 21:45:00
+323009,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 21:30:00,2023-07-27 21:45:00,0,2023-07-27 21:45:00
+323010,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 21:30:00,2023-07-27 21:45:00,0,2023-07-27 21:45:00
+323011,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 21:30:00,2023-07-27 21:45:00,0,2023-07-27 21:45:00
+323012,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 21:30:00,2023-07-27 21:45:00,0,2023-07-27 21:45:00
+323013,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 21:30:00,2023-07-27 21:45:00,0,2023-07-27 21:45:00
+323014,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA03,UPF.PfcpSessionEstabFail,Total,2023-07-27 21:30:00,2023-07-27 21:45:00,0,2023-07-27 21:45:00
+323015,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA03,UPF.PfcpSessionEstabFail._Cause,Total,2023-07-27 21:30:00,2023-07-27 21:45:00,0,2023-07-27 21:45:00
+323016,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA06,UPF.PfcpSessionModifyFail._Ns,Total,2023-07-27 21:30:00,2023-07-27 21:45:00,0,2023-07-27 21:45:00
+323017,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA06,UPF.PfcpSessionModifyFail,Total,2023-07-27 21:30:00,2023-07-27 21:45:00,0,2023-07-27 21:45:00
+323018,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 21:45:00,2023-07-27 22:00:00,0,2023-07-27 22:00:00
+323019,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 21:45:00,2023-07-27 22:00:00,0,2023-07-27 22:00:00
+323020,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 21:45:00,2023-07-27 22:00:00,0,2023-07-27 22:00:00
+323021,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 21:45:00,2023-07-27 22:00:00,0,2023-07-27 22:00:00
+323022,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 21:45:00,2023-07-27 22:00:00,0,2023-07-27 22:00:00
+323023,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,Total,2023-07-27 21:45:00,2023-07-27 22:00:00,0,2023-07-27 22:00:00
+323024,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA06,UPF.PfcpSessionModifyFail._Ns,,2023-07-27 21:45:00,2023-07-27 22:00:00,0,2023-07-27 22:00:00
+323025,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA06,UPF.PfcpSessionModifyFail,Total,2023-07-27 21:45:00,2023-07-27 22:00:00,0,2023-07-27 22:00:00
+323026,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 21:45:00,2023-07-27 22:00:00,0,2023-07-27 22:00:00
+323027,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 21:45:00,2023-07-27 22:00:00,0,2023-07-27 22:00:00
+323028,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 21:45:00,2023-07-27 22:00:00,0,2023-07-27 22:00:00
+323029,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 21:45:00,2023-07-27 22:00:00,0,2023-07-27 22:00:00
+323030,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA03,UPF.PfcpSessionEstabFail,Total,2023-07-27 21:45:00,2023-07-27 22:00:00,0,2023-07-27 22:00:00
+323031,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA03,UPF.PfcpSessionEstabFail._Cause,Total,2023-07-27 21:45:00,2023-07-27 22:00:00,0,2023-07-27 22:00:00
+323032,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,,2023-07-27 22:00:00,2023-07-27 22:15:00,0,2023-07-27 22:15:00
+323033,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 22:00:00,2023-07-27 22:15:00,0,2023-07-27 22:15:00
+323034,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 22:00:00,2023-07-27 22:15:00,0,2023-07-27 22:15:00
+323035,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 22:00:00,2023-07-27 22:15:00,0,2023-07-27 22:15:00
+323036,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 22:00:00,2023-07-27 22:15:00,0,2023-07-27 22:15:00
+323037,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,Total,2023-07-27 22:00:00,2023-07-27 22:15:00,0,2023-07-27 22:15:00
+323038,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA06,UPF.PfcpSessionModifyFail._Ns,,2023-07-27 22:00:00,2023-07-27 22:15:00,0,2023-07-27 22:15:00
+323039,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA06,UPF.PfcpSessionModifyFail,Total,2023-07-27 22:00:00,2023-07-27 22:15:00,0,2023-07-27 22:15:00
+323040,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 22:00:00,2023-07-27 22:15:00,2,2023-07-27 22:15:00
+323041,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 22:00:00,2023-07-27 22:15:00,0,2023-07-27 22:15:00
+323042,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 22:00:00,2023-07-27 22:15:00,0,2023-07-27 22:15:00
+323043,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 22:00:00,2023-07-27 22:15:00,2,2023-07-27 22:15:00
+323044,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA03,UPF.PfcpSessionEstabFail,Total,2023-07-27 22:00:00,2023-07-27 22:15:00,0,2023-07-27 22:15:00
+323045,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA03,UPF.PfcpSessionEstabFail._Cause,Total,2023-07-27 22:00:00,2023-07-27 22:15:00,0,2023-07-27 22:15:00
+323046,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 22:15:00,2023-07-27 22:30:00,0,2023-07-27 22:30:00
+323047,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 22:15:00,2023-07-27 22:30:00,0,2023-07-27 22:30:00
+323048,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 22:15:00,2023-07-27 22:30:00,0,2023-07-27 22:30:00
+323049,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 22:15:00,2023-07-27 22:30:00,0,2023-07-27 22:30:00
+323050,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA03,UPF.PfcpSessionEstabFail,Total,2023-07-27 22:15:00,2023-07-27 22:30:00,0,2023-07-27 22:30:00
+323051,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA03,UPF.PfcpSessionEstabFail._Cause,Total,2023-07-27 22:15:00,2023-07-27 22:30:00,0,2023-07-27 22:30:00
+323052,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA06,UPF.PfcpSessionModifyFail._Ns,Total,2023-07-27 22:15:00,2023-07-27 22:30:00,0,2023-07-27 22:30:00
+323053,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA06,UPF.PfcpSessionModifyFail,Total,2023-07-27 22:15:00,2023-07-27 22:30:00,0,2023-07-27 22:30:00
+323054,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 22:15:00,2023-07-27 22:30:00,0,2023-07-27 22:30:00
+323055,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 22:15:00,2023-07-27 22:30:00,0,2023-07-27 22:30:00
+323056,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 22:15:00,2023-07-27 22:30:00,0,2023-07-27 22:30:00
+323057,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 22:15:00,2023-07-27 22:30:00,0,2023-07-27 22:30:00
+323058,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 22:15:00,2023-07-27 22:30:00,0,2023-07-27 22:30:00
+323059,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,Total,2023-07-27 22:15:00,2023-07-27 22:30:00,0,2023-07-27 22:30:00
+323060,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 22:30:00,2023-07-27 22:45:00,0,2023-07-27 22:45:00
+323061,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 22:30:00,2023-07-27 22:45:00,0,2023-07-27 22:45:00
+323062,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 22:30:00,2023-07-27 22:45:00,0,2023-07-27 22:45:00
+323063,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 22:30:00,2023-07-27 22:45:00,0,2023-07-27 22:45:00
+323064,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA03,UPF.PfcpSessionEstabFail,Total,2023-07-27 22:30:00,2023-07-27 22:45:00,0,2023-07-27 22:45:00
+323065,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA03,UPF.PfcpSessionEstabFail._Cause,Total,2023-07-27 22:30:00,2023-07-27 22:45:00,0,2023-07-27 22:45:00
+323066,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA06,UPF.PfcpSessionModifyFail._Ns,Total,2023-07-27 22:30:00,2023-07-27 22:45:00,0,2023-07-27 22:45:00
+323067,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA06,UPF.PfcpSessionModifyFail,Total,2023-07-27 22:30:00,2023-07-27 22:45:00,0,2023-07-27 22:45:00
+323068,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,,2023-07-27 22:30:00,2023-07-27 22:45:00,0,2023-07-27 22:45:00
+323069,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 22:30:00,2023-07-27 22:45:00,0,2023-07-27 22:45:00
+323070,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 22:30:00,2023-07-27 22:45:00,0,2023-07-27 22:45:00
+323071,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,Total,2023-07-27 22:30:00,2023-07-27 22:45:00,0,2023-07-27 22:45:00
+323072,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 22:30:00,2023-07-27 22:45:00,0,2023-07-27 22:45:00
+323073,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 22:30:00,2023-07-27 22:45:00,0,2023-07-27 22:45:00
+323074,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 22:45:00,2023-07-27 23:00:00,0,2023-07-27 23:00:00
+323075,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,Total,2023-07-27 22:45:00,2023-07-27 23:00:00,0,2023-07-27 23:00:00
+323076,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq,Total,2023-07-27 22:45:00,2023-07-27 23:00:00,0,2023-07-27 23:00:00
+323077,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA04,UPF.PfcpSessionModifyReq._Ns,Total,2023-07-27 22:45:00,2023-07-27 23:00:00,0,2023-07-27 23:00:00
+323078,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 22:45:00,2023-07-27 23:00:00,0,2023-07-27 23:00:00
+323079,2023-07-27,57,UPF_SZ_RD109,109UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 22:45:00,2023-07-27 23:00:00,0,2023-07-27 23:00:00
+323080,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc._Ns,,2023-07-27 22:45:00,2023-07-27 23:00:00,0,2023-07-27 23:00:00
+323081,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA02,UPF.PfcpSessionEstabSucc,Total,2023-07-27 22:45:00,2023-07-27 23:00:00,0,2023-07-27 23:00:00
+323082,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA03,UPF.PfcpSessionEstabFail,Total,2023-07-27 22:45:00,2023-07-27 23:00:00,0,2023-07-27 23:00:00
+323083,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA03,UPF.PfcpSessionEstabFail._Cause,Total,2023-07-27 22:45:00,2023-07-27 23:00:00,0,2023-07-27 23:00:00
+323084,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA06,UPF.PfcpSessionModifyFail._Ns,Total,2023-07-27 22:45:00,2023-07-27 23:00:00,0,2023-07-27 23:00:00
+323085,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA06,UPF.PfcpSessionModifyFail,Total,2023-07-27 22:45:00,2023-07-27 23:00:00,0,2023-07-27 23:00:00
+323086,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq,Total,2023-07-27 22:45:00,2023-07-27 23:00:00,0,2023-07-27 23:00:00
+323087,2023-07-27,58,UPF_SZ_TEST_239,239UPF,UPF,15M,UPFHA01,UPF.PfcpSessionEstabReq._Ns,Total,2023-07-27 22:45:00,2023-07-27 23:00:00,0,2023-07-27 23:00:00
+323088,2023-07-28,59,AMF_SZ_T01,1,AMF,15M,AMFHA01,AMF.AuthReq,,2023-07-28 16:02:58,2023-07-28 16:18:00,0,2023-07-28 16:18:00
diff --git a/restagent/database/operation_log-20230810002500.csv b/restagent/database/operation_log-20230810002500.csv
new file mode 100644
index 00000000..ff000f77
--- /dev/null
+++ b/restagent/database/operation_log-20230810002500.csv
@@ -0,0 +1,557 @@
+op_id,account_name,op_ip,subsys_tag,op_type,op_content,op_result,begin_time,end_time,vnf_flag,log_time
+36,user3,192.168.21.119,OMC,UPDATE,Confirm alarm,Operation failed,2023-05-15 10:23:40,2023-05-15 10:23:41,1,2023-07-26 23:24:32
+37,user3,192.168.21.119,OMC,UPDATE,Confirm alarm,Operation successful,2023-05-15 10:29:13,2023-05-15 10:29:14,1,2023-07-26 23:24:32
+38,user1,192.168.21.119,OMC,UPDATE,Cancel alarm confirmation,Operation successful,2023-05-15 10:29:27,2023-05-15 10:29:27,1,2023-07-26 23:24:32
+39,user1,192.168.30.3,,SELECT,SELECTUPF_SZ_RD109 Information,Operation successful,2023-05-16 21:40:28,2023-05-16 21:40:28,1,2023-07-26 23:24:32
+40,user1,192.168.30.3,,SELECT,SELECTUDM_SZ_01 Information,Operation successful,2023-05-16 21:52:15,2023-05-16 21:52:15,1,2023-07-26 23:24:32
+41,user3,192.168.30.3,OMC,UPDATE,Confirm alarm,Operation successful,2023-05-17 10:22:28,2023-05-17 10:22:29,1,2023-07-26 23:24:32
+42,user1,192.168.30.3,OMC,UPDATE,Cancel alarm confirmation,Operation successful,2023-05-17 10:22:32,2023-05-17 10:22:33,1,2023-07-26 23:24:32
+43,user3,192.168.30.3,OMC,UPDATE,Confirm alarm,Operation successful,2023-05-17 10:22:53,2023-05-17 10:22:54,1,2023-07-26 23:24:32
+44,user3,192.168.30.3,OMC,UPDATE,Confirm alarm,Operation successful,2023-05-17 10:23:21,2023-05-17 10:23:22,1,2023-07-26 23:24:32
+45,user1,192.168.30.3,OMC,UPDATE,DELETE alarmInfo,Operation successful,2023-05-19 09:41:28,2023-05-19 09:42:00,1,2023-07-26 23:24:32
+46,user3,192.168.21.139,OMC,UPDATE,Confirm alarm,Operation successful,2023-05-26 16:43:00,2023-05-26 16:43:01,1,2023-07-26 23:24:32
+47,user1,192.168.21.139,OMC,UPDATE,DELETE alarmInfo,Operation successful,2023-05-27 11:15:09,2023-05-27 11:15:09,1,2023-07-26 23:24:32
+48,user1,192.168.21.139,,SELECT,SELECTSMF_SZ_02 Information,Operation successful,2023-05-30 11:42:55,2023-05-30 11:42:55,1,2023-07-26 23:24:32
+49,user3,192.168.30.3,OMC,UPDATE,Confirm alarm,Operation successful,2023-06-02 10:34:25,2023-06-02 10:34:26,1,2023-07-26 23:24:32
+50,user3,192.168.30.3,OMC,UPDATE,Confirm alarm,Operation successful,2023-06-02 15:24:21,2023-06-02 15:24:22,1,2023-07-26 23:24:32
+51,user1,192.168.30.3,OMC,UPDATE,Cancel alarm confirmation,Operation successful,2023-06-02 15:24:28,2023-06-02 15:24:29,1,2023-07-26 23:24:32
+52,admin,192.168.30.3,OMC,UPDATE,Confirm alarm,Operation failed,2023-06-07 14:32:26,2023-06-07 14:32:26,1,2023-07-26 23:24:32
+53,admin,192.168.30.3,OMC,UPDATE,Confirm alarm,Operation failed,2023-06-07 14:33:16,2023-06-07 14:33:16,1,2023-07-26 23:24:32
+54,user3,192.168.30.3,OMC,UPDATE,Confirm alarm,Operation successful,2023-06-07 14:33:34,2023-06-07 14:33:34,1,2023-07-26 23:24:32
+55,admin,192.168.30.3,OMC,UPDATE,Confirm alarm,Operation failed,2023-06-07 14:34:20,2023-06-07 14:34:20,1,2023-07-26 23:24:32
+56,admin,192.168.30.3,OMC,UPDATE,Confirm alarm,Operation successful,2023-06-07 14:34:47,2023-06-07 14:34:47,1,2023-07-26 23:24:32
+57,admin,192.168.30.3,OMC,UPDATE,Confirm alarm,Operation successful,2023-06-08 11:05:02,2023-06-08 11:05:02,1,2023-07-26 23:24:32
+58,user1,192.168.30.3,OMC,UPDATE,Cancel alarm confirmation,Operation successful,2023-06-09 18:39:05,2023-06-09 18:39:07,1,2023-07-26 23:24:32
+59,user1,192.168.30.3,OMC,UPDATE,Cancel alarm confirmation,Operation successful,2023-06-09 18:41:41,2023-06-09 18:41:42,1,2023-07-26 23:24:32
+60,user1,192.168.30.3,OMC,UPDATE,Cancel alarm confirmation,Operation successful,2023-06-09 18:42:06,2023-06-09 18:42:06,1,2023-07-26 23:24:32
+61,admin,192.168.30.3,OMC,UPDATE,DELETE alarmInfo,Operation successful,2023-06-30 10:01:54,2023-06-30 10:01:55,1,2023-07-26 23:24:32
+62,user1,192.168.30.3,,SELECT,SELECTEMS_SZ_T01 Information,Operation successful,2023-07-03 14:18:46,2023-07-03 14:18:46,1,2023-07-26 23:24:32
+63,user1,192.168.30.3,,SELECT,SELECTEMS_SZ_T01 Information,Operation successful,2023-07-03 14:21:11,2023-07-03 14:21:11,1,2023-07-26 23:24:32
+64,user1,192.168.30.3,,SELECT,SELECTEMS_SZ_T01 Information,Operation successful,2023-07-03 14:22:14,2023-07-03 14:22:14,1,2023-07-26 23:24:32
+65,user1,192.168.30.3,,SELECT,SELECTEMS_SZ_T01 Information,Operation successful,2023-07-03 14:27:36,2023-07-03 14:27:36,1,2023-07-26 23:24:32
+66,user1,192.168.30.3,,SELECT,SELECTEMS_SZ_T01 Information,Operation successful,2023-07-03 14:28:34,2023-07-03 14:28:34,1,2023-07-26 23:24:32
+67,user1,192.168.30.3,,SELECT,SELECTUDM_SZ_01 Information,Operation successful,2023-07-03 14:28:57,2023-07-03 14:28:57,1,2023-07-26 23:24:32
+68,user1,192.168.30.3,,SELECT,SELECTEMS/SZ_T01 Information,Operation successful,2023-07-03 14:31:14,2023-07-03 14:31:14,1,2023-07-26 23:24:32
+69,user1,192.168.30.3,,SELECT,SELECTSMF/SZ_02 Information,Operation successful,2023-07-03 14:31:31,2023-07-03 14:31:31,1,2023-07-26 23:24:32
+70,user1,192.168.30.3,,SELECT,SELECTEMS/SZ_T01 Information,Operation successful,2023-07-03 14:31:57,2023-07-03 14:31:57,1,2023-07-26 23:24:32
+71,user1,192.168.30.3,,SELECT,SELECTEMS/SZ_T01 Information,Operation successful,2023-07-03 14:33:55,2023-07-03 14:33:55,1,2023-07-26 23:24:32
+72,user1,192.168.30.3,,SELECT,SELECTEMS/SZ_T01 Information,Operation successful,2023-07-03 14:36:20,2023-07-03 14:36:20,1,2023-07-26 23:24:32
+73,admin,192.168.30.3,OMC,DELETE,Successfully deleted the network element,Operation successful,2023-07-03 16:21:02,2023-07-03 16:21:06,1,2023-07-26 23:24:32
+74,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-05 16:15:42,2023-07-05 16:15:42,1,2023-07-26 23:24:32
+75,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-05 16:15:53,2023-07-05 16:15:53,1,2023-07-26 23:24:32
+76,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-05 16:16:17,2023-07-05 16:16:17,1,2023-07-26 23:24:32
+77,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-05 16:26:10,2023-07-05 16:26:10,1,2023-07-26 23:24:32
+78,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-05 16:26:55,2023-07-05 16:26:55,1,2023-07-26 23:24:32
+79,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-05 16:28:03,2023-07-05 16:28:03,1,2023-07-26 23:24:32
+80,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-05 16:28:16,2023-07-05 16:28:16,1,2023-07-26 23:24:32
+81,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-05 16:28:23,2023-07-05 16:28:23,1,2023-07-26 23:24:32
+82,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-05 16:29:18,2023-07-05 16:29:18,1,2023-07-26 23:24:32
+83,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-05 16:30:50,2023-07-05 16:30:50,1,2023-07-26 23:24:32
+84,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-05 16:30:57,2023-07-05 16:30:57,1,2023-07-26 23:24:32
+85,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-05 16:31:09,2023-07-05 16:31:09,1,2023-07-26 23:24:32
+86,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-05 16:31:22,2023-07-05 16:31:22,1,2023-07-26 23:24:32
+87,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-05 16:31:29,2023-07-05 16:31:29,1,2023-07-26 23:24:32
+88,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-05 16:32:59,2023-07-05 16:32:59,1,2023-07-26 23:24:32
+89,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-05 16:52:59,2023-07-05 16:52:59,1,2023-07-26 23:24:32
+90,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-05 16:56:49,2023-07-05 16:56:49,1,2023-07-26 23:24:32
+91,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-05 16:56:53,2023-07-05 16:56:53,1,2023-07-26 23:24:32
+92,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-05 16:57:22,2023-07-05 16:57:22,1,2023-07-26 23:24:32
+93,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-05 16:57:25,2023-07-05 16:57:25,1,2023-07-26 23:24:32
+94,admin,192.168.30.3,OMC,EXPORT,Number of successfully exported alarm messages:316,Operation successful,2023-07-05 17:52:43,2023-07-05 17:52:43,1,2023-07-26 23:24:32
+95,admin,192.168.30.3,OMC,EXPORT,Number of successfully exported alarm messages:1,Operation successful,2023-07-05 17:54:40,2023-07-05 17:54:40,1,2023-07-26 23:24:32
+96,admin,192.168.30.3,OMC,EXPORT,Export failed,Operation successful,2023-07-05 17:55:41,2023-07-05 17:55:41,1,2023-07-26 23:24:32
+97,admin,192.168.30.3,OMC,EXPORT,Number of successfully exported alarm messages:1,Operation successful,2023-07-05 17:55:51,2023-07-05 17:55:51,1,2023-07-26 23:24:32
+98,admin,192.168.30.3,OMC,EXPORT,Number of successfully exported alarm messages:81,Operation successful,2023-07-05 17:56:30,2023-07-05 17:56:30,1,2023-07-26 23:24:32
+99,admin,192.168.30.3,OMC,EXPORT,Number of successfully exported alarm messages:316,Operation successful,2023-07-05 17:58:13,2023-07-05 17:58:14,1,2023-07-26 23:24:32
+100,admin,192.168.30.3,OMC,EXPORT,Number of successfully exported alarm messages:74,Operation successful,2023-07-05 17:58:32,2023-07-05 17:58:32,1,2023-07-26 23:24:32
+101,admin,192.168.30.3,OMC,EXPORT,Number of successfully exported alarm messages:125,Operation successful,2023-07-05 18:01:41,2023-07-05 18:01:42,1,2023-07-26 23:24:32
+102,admin,192.168.30.3,OMC,UPDATE,Failed to modify AMF_SZ_T01,Operation failed,2023-07-06 18:51:11,2023-07-06 18:51:11,1,2023-07-26 23:24:32
+103,admin,192.168.30.3,OMC,UPDATE,Successfully modified AMF_SZ_T01,Operation successful,2023-07-06 19:34:36,2023-07-06 19:34:36,1,2023-07-26 23:24:32
+104,admin,192.168.30.3,OMC,UPDATE,Successfully modified AMF_SZ_T01,Operation successful,2023-07-06 19:35:14,2023-07-06 19:35:14,1,2023-07-26 23:24:32
+105,admin,192.168.30.3,OMC,UPDATE,Successfully modified AMF_SZ_T01,Operation successful,2023-07-06 19:35:34,2023-07-06 19:35:34,1,2023-07-26 23:24:32
+106,admin,192.168.30.3,OMC,UPDATE,Successfully modified AMF_SZ_T01,Operation successful,2023-07-06 19:41:31,2023-07-06 19:41:31,1,2023-07-26 23:24:32
+107,admin,192.168.30.3,OMC,UPDATE,Successfully modified AMF_SZ_T01,Operation successful,2023-07-06 19:42:04,2023-07-06 19:42:04,1,2023-07-26 23:24:32
+108,admin,192.168.30.3,OMC,UPDATE,Successfully modified AMF_SZ_T01,Operation successful,2023-07-06 19:42:09,2023-07-06 19:42:10,1,2023-07-26 23:24:32
+109,admin,192.168.30.3,OMC,ADD,Adding network element SMF failed,Operation failed,2023-07-06 19:42:40,2023-07-06 19:42:40,1,2023-07-26 23:24:32
+110,admin,192.168.30.3,OMC,ADD,Successfully added network element SMF,Operation successful,2023-07-06 19:43:47,2023-07-06 19:43:47,1,2023-07-26 23:24:32
+111,admin,192.168.30.3,OMC,UPDATE,Successfully modified SMF_SZ_07,Operation successful,2023-07-06 19:43:56,2023-07-06 19:43:56,1,2023-07-26 23:24:32
+112,admin,192.168.30.3,OMC,ADD,Failed to issue tracking task ,Operation successful,2023-07-06 20:17:41,2023-07-06 20:17:41,1,2023-07-26 23:24:32
+113,admin,192.168.30.3,OMC,ADD,Failed to issue tracking task ,Operation successful,2023-07-06 20:39:44,2023-07-06 20:39:44,1,2023-07-26 23:24:32
+114,admin,192.168.30.3,OMC,ADD,Failed to issue tracking task ,Operation successful,2023-07-06 20:42:08,2023-07-06 20:42:08,1,2023-07-26 23:24:32
+115,admin,192.168.30.3,OMC,ADD,Failed to issue tracking task ,Operation successful,2023-07-06 20:42:50,2023-07-06 20:42:50,1,2023-07-26 23:24:32
+116,admin,192.168.30.3,OMC,ADD,Failed to issue tracking task ,Operation successful,2023-07-06 20:42:59,2023-07-06 20:42:59,1,2023-07-26 23:24:32
+117,admin,192.168.30.3,OMC,ADD,Failed to issue tracking task ,Operation successful,2023-07-06 20:44:05,2023-07-06 20:44:05,1,2023-07-26 23:24:32
+118,admin,192.168.30.3,OMC,ADD,Failed to issue tracking task ,Operation successful,2023-07-06 20:45:03,2023-07-06 20:45:03,1,2023-07-26 23:24:32
+119,admin,192.168.30.3,OMC,ADD,Failed to issue tracking task ,Operation successful,2023-07-06 20:47:26,2023-07-06 20:47:26,1,2023-07-26 23:24:32
+120,admin,192.168.30.3,OMC,UPDATE,Successfully modified AMF_SZ_T01,Operation successful,2023-07-10 09:18:37,2023-07-10 09:18:37,1,2023-07-26 23:24:32
+121,admin,192.168.30.3,OMC,UPDATE,Successfully modified AMF_SZ_T01,Operation successful,2023-07-10 09:20:16,2023-07-10 09:20:17,1,2023-07-26 23:24:32
+122,admin,192.168.30.3,OMC,UPDATE,Failed to modify tracking task,Operation successful,2023-07-11 14:32:20,2023-07-11 14:32:25,1,2023-07-26 23:24:32
+123,admin,192.168.30.3,OMC,UPDATE,Failed to modify tracking task,Operation successful,2023-07-11 14:38:55,2023-07-11 14:39:00,1,2023-07-26 23:24:32
+124,admin,192.168.30.3,OMC,UPDATE,Failed to modify tracking task,Operation successful,2023-07-11 14:40:03,2023-07-11 14:40:07,1,2023-07-26 23:24:32
+125,admin,192.168.30.3,OMC,UPDATE,Failed to modify tracking task,Operation successful,2023-07-11 14:41:34,2023-07-11 14:41:38,1,2023-07-26 23:24:32
+126,admin,192.168.30.3,OMC,UPDATE,Failed to modify tracking task,Operation successful,2023-07-11 14:41:42,2023-07-11 14:41:47,1,2023-07-26 23:24:32
+127,admin,192.168.30.3,OMC,UPDATE,Failed to modify tracking task,Operation successful,2023-07-11 14:42:16,2023-07-11 14:42:20,1,2023-07-26 23:24:32
+128,admin,192.168.30.3,OMC,UPDATE,Failed to modify tracking task,Operation successful,2023-07-11 14:43:17,2023-07-11 14:43:21,1,2023-07-26 23:24:32
+129,admin,192.168.30.3,OMC,UPDATE,Failed to modify tracking task,Operation successful,2023-07-11 14:43:36,2023-07-11 14:43:40,1,2023-07-26 23:24:32
+130,admin,192.168.30.3,OMC,UPDATE,Failed to modify tracking task,Operation successful,2023-07-11 15:01:19,2023-07-11 15:01:24,1,2023-07-26 23:24:32
+131,admin,192.168.30.3,OMC,UPDATE,Failed to modify tracking task,Operation successful,2023-07-11 15:02:53,2023-07-11 15:02:57,1,2023-07-26 23:24:32
+132,admin,192.168.30.3,OMC,UPDATE,Failed to modify tracking task,Operation successful,2023-07-11 15:03:24,2023-07-11 15:03:29,1,2023-07-26 23:24:32
+133,admin,192.168.30.3,OMC,UPDATE,Failed to modify tracking task,Operation successful,2023-07-11 15:05:52,2023-07-11 15:05:56,1,2023-07-26 23:24:32
+134,admin,192.168.30.3,OMC,DELETE,Successfully deleted tracking task,Operation successful,2023-07-11 15:11:58,2023-07-11 15:11:58,1,2023-07-26 23:24:32
+135,admin,192.168.30.3,OMC,UPDATE,DELETE alarmInfo,Operation successful,2023-07-11 15:49:09,2023-07-11 15:49:10,1,2023-07-26 23:24:32
+136,admin,192.168.30.3,OMC,DELETE,Successfully deleted the network element,Operation successful,2023-07-11 15:51:37,2023-07-11 15:51:41,1,2023-07-26 23:24:32
+137,admin,192.168.30.3,OMC,EXPORT,Export ofUDMconfiguration file failed,Operation successful,2023-07-11 16:00:28,2023-07-11 16:00:31,1,2023-07-26 23:24:32
+138,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-11 16:10:06,2023-07-11 16:10:06,1,2023-07-26 23:24:32
+139,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-11 18:56:56,2023-07-11 18:56:56,1,2023-07-26 23:24:32
+140,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-11 18:57:00,2023-07-11 18:57:00,1,2023-07-26 23:24:32
+141,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-12 10:42:48,2023-07-12 10:42:48,1,2023-07-26 23:24:32
+142,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-12 10:45:26,2023-07-12 10:45:26,1,2023-07-26 23:24:32
+143,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-12 10:45:42,2023-07-12 10:45:42,1,2023-07-26 23:24:32
+144,user1,192.168.30.3,,SELECT,SELECTSMF/SZ_01 Information,Operation successful,2023-07-12 14:40:33,2023-07-12 14:40:33,1,2023-07-26 23:24:32
+145,user1,192.168.30.3,,SELECT,SELECTSMF/SZ_01 Information,Operation successful,2023-07-13 15:48:35,2023-07-13 15:48:35,1,2023-07-26 23:24:32
+146,user1,192.168.30.3,,SELECT,SELECTUPF/SZ_01 Information,Operation successful,2023-07-13 15:49:57,2023-07-13 15:49:57,1,2023-07-26 23:24:32
+147,user1,192.168.30.3,,SELECT,SELECTSMF/SZ_01 Information,Operation successful,2023-07-14 09:45:37,2023-07-14 09:45:37,1,2023-07-26 23:24:32
+148,admin,192.168.30.3,OMC,UPDATE,Confirm alarm,Operation successful,2023-07-14 10:36:19,2023-07-14 10:36:19,1,2023-07-26 23:24:32
+149,admin,192.168.30.3,OMC,UPDATE,Confirm alarm,Operation successful,2023-07-14 10:36:27,2023-07-14 10:36:27,1,2023-07-26 23:24:32
+150,admin,192.168.30.3,OMC,UPDATE,Confirm alarm,Operation successful,2023-07-14 10:36:38,2023-07-14 10:36:38,1,2023-07-26 23:24:32
+151,admin,192.168.30.3,OMC,UPDATE,Confirm alarm,Operation successful,2023-07-14 10:36:43,2023-07-14 10:36:43,1,2023-07-26 23:24:32
+152,admin,192.168.30.3,OMC,UPDATE,Confirm alarm,Operation successful,2023-07-14 10:36:52,2023-07-14 10:36:52,1,2023-07-26 23:24:32
+153,admin,192.168.30.3,OMC,UPDATE,Confirm alarm,Operation successful,2023-07-14 10:37:04,2023-07-14 10:37:04,1,2023-07-26 23:24:32
+154,admin,192.168.30.3,OMC,UPDATE,DELETE alarmInfo,Operation successful,2023-07-14 10:50:06,2023-07-14 10:50:07,1,2023-07-26 23:24:32
+155,admin,192.168.30.3,OMC,UPDATE,Cancel alarm confirmation,Operation successful,2023-07-14 11:20:44,2023-07-14 11:20:51,1,2023-07-26 23:24:32
+156,admin,192.168.30.3,OMC,UPDATE,Cancel alarm confirmation,Operation successful,2023-07-14 11:21:57,2023-07-14 11:21:58,1,2023-07-26 23:24:32
+157,admin,192.168.30.3,OMC,UPDATE,Cancel alarm confirmation,Operation successful,2023-07-14 11:25:10,2023-07-14 11:25:10,1,2023-07-26 23:24:32
+158,admin,192.168.30.3,OMC,UPDATE,Confirm alarm,Operation successful,2023-07-14 11:27:34,2023-07-14 11:27:34,1,2023-07-26 23:24:32
+159,admin,192.168.30.3,OMC,UPDATE,Confirm alarm,Operation successful,2023-07-14 11:32:44,2023-07-14 11:32:44,1,2023-07-26 23:24:32
+160,admin,192.168.30.3,OMC,UPDATE,Confirm alarm,Operation successful,2023-07-14 11:34:35,2023-07-14 11:34:35,1,2023-07-26 23:24:32
+161,admin,192.168.30.3,OMC,UPDATE,Confirm alarm,Operation successful,2023-07-14 11:34:41,2023-07-14 11:34:41,1,2023-07-26 23:24:32
+162,admin,192.168.30.3,OMC,UPDATE,Confirm alarm,Operation successful,2023-07-14 11:35:23,2023-07-14 11:35:23,1,2023-07-26 23:24:32
+163,admin,192.168.30.3,OMC,UPDATE,Confirm alarm,Operation successful,2023-07-14 11:35:27,2023-07-14 11:35:27,1,2023-07-26 23:24:32
+164,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-14 14:50:11,2023-07-14 14:50:11,1,2023-07-26 23:24:32
+165,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-14 15:32:22,2023-07-14 15:32:22,1,2023-07-26 23:24:32
+166,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-14 15:33:49,2023-07-14 15:33:49,1,2023-07-26 23:24:32
+167,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-14 15:33:57,2023-07-14 15:33:57,1,2023-07-26 23:24:32
+168,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-14 15:34:38,2023-07-14 15:34:38,1,2023-07-26 23:24:32
+169,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-14 15:34:59,2023-07-14 15:34:59,1,2023-07-26 23:24:32
+170,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-14 15:35:01,2023-07-14 15:35:01,1,2023-07-26 23:24:32
+171,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-14 15:35:05,2023-07-14 15:35:05,1,2023-07-26 23:24:32
+172,admin,192.168.30.3,OMC,UPDATE,DELETE alarmInfo,Operation successful,2023-07-17 16:34:07,2023-07-17 16:34:08,1,2023-07-26 23:24:32
+173,admin,192.168.30.3,OMC,UPDATE,DELETE alarmInfo,Operation successful,2023-07-17 18:03:46,2023-07-17 18:03:47,1,2023-07-26 23:24:32
+174,admin,192.168.30.3,OMC,UPDATE,DELETE alarmInfo,Operation successful,2023-07-17 19:21:50,2023-07-17 19:21:57,1,2023-07-26 23:24:32
+175,admin,192.168.30.3,OMC,UPDATE,DELETE alarmInfo,Operation successful,2023-07-18 11:34:51,2023-07-18 11:34:52,1,2023-07-26 23:24:32
+176,admin,192.168.30.3,OMC,UPDATE,DELETE alarmInfo,Operation successful,2023-07-18 11:38:47,2023-07-18 11:38:48,1,2023-07-26 23:24:32
+177,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-18 14:29:19,2023-07-18 14:29:19,1,2023-07-26 23:24:32
+178,admin,192.168.30.3,OMC,UPDATE,DELETE alarmInfo,Operation successful,2023-07-18 14:47:19,2023-07-18 14:47:26,1,2023-07-26 23:24:32
+179,admin,192.168.30.3,OMC,UPDATE,DELETE alarmInfo,Operation successful,2023-07-18 14:48:44,2023-07-18 14:48:44,1,2023-07-26 23:24:32
+180,admin,192.168.30.3,OMC,UPDATE,DELETE alarmInfo,Operation successful,2023-07-18 14:49:44,2023-07-18 14:49:47,1,2023-07-26 23:24:32
+181,admin,192.168.30.3,OMC,UPDATE,DELETE alarmInfo,Operation successful,2023-07-18 14:52:28,2023-07-18 14:52:29,1,2023-07-26 23:24:32
+182,admin,192.168.30.3,OMC,UPDATE,DELETE alarmInfo,Operation successful,2023-07-18 14:53:49,2023-07-18 14:53:50,1,2023-07-26 23:24:32
+183,admin,192.168.30.3,OMC,UPDATE,DELETE alarmInfo,Operation successful,2023-07-18 15:00:25,2023-07-18 15:00:25,1,2023-07-26 23:24:32
+184,admin,192.168.30.3,OMC,UPDATE,DELETE alarmInfo,Operation successful,2023-07-18 15:02:47,2023-07-18 15:02:47,1,2023-07-26 23:24:32
+185,admin,192.168.30.3,OMC,UPDATE,DELETE alarmInfo,Operation successful,2023-07-18 15:06:23,2023-07-18 15:06:23,1,2023-07-26 23:24:32
+186,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-18 15:07:48,2023-07-18 15:07:48,1,2023-07-26 23:24:32
+187,admin,192.168.30.3,OMC,UPDATE,DELETE alarmInfo,Operation successful,2023-07-18 15:08:20,2023-07-18 15:08:21,1,2023-07-26 23:24:32
+188,admin,192.168.30.3,OMC,UPDATE,DELETE alarmInfo,Operation successful,2023-07-18 15:08:25,2023-07-18 15:08:25,1,2023-07-26 23:24:32
+189,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-18 15:38:16,2023-07-18 15:38:16,1,2023-07-26 23:24:32
+190,admin,192.168.30.3,OMC,ADD,Adding user successful,password is ******,Operation successful,2023-07-20 14:40:30,2023-07-20 14:40:30,1,2023-07-26 23:24:32
+191,admin,192.168.30.3,OMC,DELETE,DELETE user successful,Operation successful,2023-07-20 14:46:05,2023-07-20 14:46:06,1,2023-07-26 23:24:32
+192,user1,192.168.30.3,,SELECT,SELECTSMF/SZ_01 Information,Operation successful,2023-07-20 17:10:10,2023-07-20 17:10:10,1,2023-07-26 23:24:32
+193,user1,192.168.30.3,,SELECT,SELECTSMF/SZ_01 Information,Operation successful,2023-07-20 17:10:41,2023-07-20 17:10:41,1,2023-07-26 23:24:32
+194,admin,192.168.30.3,OMC,DELETE,DELETE user successful,Operation successful,2023-07-20 17:11:30,2023-07-20 17:11:31,1,2023-07-26 23:24:32
+195,admin,192.168.30.3,OMC,DELETE,DELETE user successful,Operation successful,2023-07-20 17:11:31,2023-07-20 17:11:32,1,2023-07-26 23:24:32
+196,admin,192.168.30.3,OMC,UPDATE,Confirm alarm,Operation successful,2023-07-20 19:27:21,2023-07-20 19:27:21,1,2023-07-26 23:24:32
+197,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-20 20:40:46,2023-07-20 20:40:46,1,2023-07-26 23:24:32
+198,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-20 20:40:49,2023-07-20 20:40:49,1,2023-07-26 23:24:32
+199,user1,192.168.30.3,,SELECT,SELECTUDM/SZ_02 Information,Operation successful,2023-07-20 20:41:42,2023-07-20 20:41:42,1,2023-07-26 23:24:32
+200,admin,192.168.30.3,OMC,EXPORT,Export ofUDMconfiguration file failed,Operation successful,2023-07-21 10:53:05,2023-07-21 10:53:05,1,2023-07-26 23:24:32
+201,admin,192.168.30.3,OMC,EXPORT,Export ofUDMconfiguration file failed,Operation successful,2023-07-21 11:10:19,2023-07-21 11:10:19,1,2023-07-26 23:24:32
+202,admin,192.168.30.3,OMC,EXPORT,Export ofUDMconfiguration file failed,Operation successful,2023-07-21 11:10:44,2023-07-21 11:10:44,1,2023-07-26 23:24:32
+203,admin,192.168.30.3,OMC,EXPORT,Export ofUDMconfiguration file failed,Operation successful,2023-07-21 11:10:48,2023-07-21 11:10:48,1,2023-07-26 23:24:32
+204,admin,192.168.30.3,OMC,EXPORT,Export ofUDMconfiguration file failed,Operation successful,2023-07-21 11:10:51,2023-07-21 11:10:51,1,2023-07-26 23:24:32
+205,admin,192.168.30.3,OMC,EXPORT,Successfully exportedUDMconfiguration file,Operation successful,2023-07-21 11:13:14,2023-07-21 11:13:14,1,2023-07-26 23:24:32
+206,admin,192.168.30.3,NF,DELETE,Successfully deleted the network element configuration file ,Operation successful,2023-07-21 11:36:19,2023-07-21 11:36:21,1,2023-07-26 23:24:32
+207,user1,192.168.30.3,,SELECT,SELECTSMF/SZ_01 Information,Operation successful,2023-07-21 14:17:23,2023-07-21 14:17:23,1,2023-07-26 23:24:32
+208,admin,192.168.30.3,OMC,EXPORT,Successfully exportedSMFconfiguration file,Operation successful,2023-07-21 15:59:32,2023-07-21 15:59:32,1,2023-07-26 23:24:32
+209,admin,192.168.30.3,OMC,UPDATE,DELETE alarmInfo,Operation successful,2023-07-24 10:45:14,2023-07-24 10:45:15,1,2023-07-26 23:24:32
+210,user1,192.168.30.3,,SELECT,SELECTUPF/UPF_SZ_RD_109 Information,Operation successful,2023-07-24 11:16:52,2023-07-24 11:16:52,1,2023-07-26 23:24:32
+211,user1,192.168.30.3,,SELECT,SELECTUPF/UPF_SZ_RD_109 Information,Operation successful,2023-07-24 11:17:01,2023-07-24 11:17:01,1,2023-07-26 23:24:32
+212,user1,192.168.30.3,,SELECT,SELECTUPF/SZ_01 Information,Operation successful,2023-07-24 11:17:09,2023-07-24 11:17:09,1,2023-07-26 23:24:32
+213,admin,192.168.30.3,OMC,UPDATE,DELETE alarmInfo,Operation successful,2023-07-24 11:17:58,2023-07-24 11:17:59,1,2023-07-26 23:24:32
+214,admin,192.168.30.3,OMC,UPDATE,DELETE alarmInfo,Operation successful,2023-07-24 11:18:06,2023-07-24 11:18:07,1,2023-07-26 23:24:32
+215,admin,192.168.30.3,OMC,UPDATE,DELETE alarmInfo,Operation successful,2023-07-24 11:18:12,2023-07-24 11:18:13,1,2023-07-26 23:24:32
+216,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-24 14:30:05,2023-07-24 14:30:05,1,2023-07-26 23:24:32
+217,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-24 14:30:30,2023-07-24 14:30:30,1,2023-07-26 23:24:32
+218,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-24 14:45:28,2023-07-24 14:45:28,1,2023-07-26 23:24:32
+219,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-24 14:45:35,2023-07-24 14:45:35,1,2023-07-26 23:24:32
+220,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-24 14:45:51,2023-07-24 14:45:51,1,2023-07-26 23:24:32
+221,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-24 14:46:21,2023-07-24 14:46:21,1,2023-07-26 23:24:32
+222,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-24 15:21:56,2023-07-24 15:21:56,1,2023-07-26 23:24:32
+223,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-24 15:22:02,2023-07-24 15:22:02,1,2023-07-26 23:24:32
+224,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-24 15:22:05,2023-07-24 15:22:05,1,2023-07-26 23:24:32
+225,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-24 15:22:09,2023-07-24 15:22:09,1,2023-07-26 23:24:32
+226,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-24 15:22:14,2023-07-24 15:22:14,1,2023-07-26 23:24:32
+227,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-24 15:22:16,2023-07-24 15:22:16,1,2023-07-26 23:24:32
+228,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-24 15:22:18,2023-07-24 15:22:18,1,2023-07-26 23:24:32
+229,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-24 15:39:52,2023-07-24 15:39:52,1,2023-07-26 23:24:32
+230,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-24 15:56:50,2023-07-24 15:56:50,1,2023-07-26 23:24:32
+231,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-24 16:00:06,2023-07-24 16:00:06,1,2023-07-26 23:24:32
+232,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-24 16:01:33,2023-07-24 16:01:33,1,2023-07-26 23:24:32
+233,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-24 16:04:33,2023-07-24 16:04:33,1,2023-07-26 23:24:32
+234,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-24 16:11:41,2023-07-24 16:11:41,1,2023-07-26 23:24:32
+235,admin,192.168.30.3,OMC,EXPORT,Number of successfully exported alarm messages:312,Operation successful,2023-07-24 16:13:45,2023-07-24 16:13:45,1,2023-07-26 23:24:32
+236,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-24 16:13:53,2023-07-24 16:13:53,1,2023-07-26 23:24:32
+237,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-24 16:14:55,2023-07-24 16:14:56,1,2023-07-26 23:24:32
+238,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-24 16:16:36,2023-07-24 16:16:36,1,2023-07-26 23:24:32
+239,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-24 16:20:49,2023-07-24 16:20:49,1,2023-07-26 23:24:32
+240,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-24 16:22:39,2023-07-24 16:22:39,1,2023-07-26 23:24:32
+241,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-24 16:26:59,2023-07-24 16:26:59,1,2023-07-26 23:24:32
+242,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-24 16:32:14,2023-07-24 16:32:15,1,2023-07-26 23:24:32
+243,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-24 16:50:12,2023-07-24 16:50:12,1,2023-07-26 23:24:32
+244,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-24 16:50:31,2023-07-24 16:50:31,1,2023-07-26 23:24:32
+245,admin,192.168.30.3,OMC,UPDATE,Successfully modified SMF_SZ_01,Operation successful,2023-07-24 17:02:39,2023-07-24 17:02:39,1,2023-07-26 23:24:32
+246,admin,192.168.30.3,OMC,UPDATE,Successfully modified SMF_SZ_01,Operation successful,2023-07-24 17:03:30,2023-07-24 17:03:30,1,2023-07-26 23:24:32
+247,admin,192.168.30.3,OMC,UPDATE,Successfully modified SMF_SZ_01,Operation successful,2023-07-24 17:03:36,2023-07-24 17:03:36,1,2023-07-26 23:24:32
+248,admin,192.168.30.3,OMC,UPDATE,Successfully modified SMF_SZ_01,Operation successful,2023-07-24 17:03:43,2023-07-24 17:03:44,1,2023-07-26 23:24:32
+249,admin,192.168.30.3,OMC,UPDATE,Successfully modified SMF_SZ_01,Operation successful,2023-07-24 17:05:57,2023-07-24 17:05:57,1,2023-07-26 23:24:32
+250,admin,192.168.30.3,OMC,UPDATE,Successfully modified SMF_SZ_01,Operation successful,2023-07-24 17:06:19,2023-07-24 17:06:19,1,2023-07-26 23:24:32
+251,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-24 17:13:17,2023-07-24 17:13:17,1,2023-07-26 23:24:32
+252,admin,192.168.30.3,OMC,UPDATE,Successfully modified UDM_SZ_02,Operation successful,2023-07-24 18:18:16,2023-07-24 18:18:16,1,2023-07-26 23:24:32
+253,admin,192.168.30.3,OMC,UPDATE,Successfully modified UDM_SZ_02,Operation successful,2023-07-24 18:18:31,2023-07-24 18:18:31,1,2023-07-26 23:24:32
+254,admin,192.168.30.3,OMC,SET,Failed to set alarm color,Operation failed,2023-07-25 14:47:13,2023-07-25 14:47:13,1,2023-07-26 23:24:32
+255,admin,192.168.30.3,OMC,SET,Failed to set alarm color,Operation failed,2023-07-25 14:56:10,2023-07-25 14:56:10,1,2023-07-26 23:24:32
+256,admin,192.168.30.3,OMC,SET,Failed to set alarm color,Operation failed,2023-07-25 15:08:06,2023-07-25 15:08:06,1,2023-07-26 23:24:32
+257,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-25 17:21:25,2023-07-25 17:21:25,1,2023-07-26 23:24:32
+258,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-25 17:21:57,2023-07-25 17:21:57,1,2023-07-26 23:24:32
+259,admin,192.168.30.3,OMC,SET,Successfully set the config for the alarm ,Operation successful,2023-07-25 17:58:07,2023-07-25 17:58:07,1,2023-07-26 23:24:32
+260,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-25 18:15:53,2023-07-25 18:15:53,1,2023-07-26 23:24:32
+261,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-25 18:17:26,2023-07-25 18:17:26,1,2023-07-26 23:24:32
+262,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-25 18:19:01,2023-07-25 18:19:01,1,2023-07-26 23:24:32
+263,admin,192.168.30.3,OMC,SET,Successfully set alarm color,Operation successful,2023-07-25 18:22:50,2023-07-25 18:22:50,1,2023-07-26 23:24:32
+264,admin,192.168.30.3,OMC,UPDATE,DELETE alarmInfo,Operation successful,2023-07-25 20:58:39,2023-07-25 20:58:39,1,2023-07-26 23:24:32
+265,admin,192.168.30.3,OMC,UPDATE,DELETE alarmInfo,Operation successful,2023-07-25 21:01:33,2023-07-25 21:01:34,1,2023-07-26 23:24:32
+266,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 21:14:29,2023-07-25 21:14:29,1,2023-07-26 23:24:32
+267,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 21:29:17,2023-07-25 21:29:17,1,2023-07-26 23:24:32
+268,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 21:29:24,2023-07-25 21:29:24,1,2023-07-26 23:24:32
+269,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 21:30:25,2023-07-25 21:30:25,1,2023-07-26 23:24:32
+270,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 21:30:32,2023-07-25 21:30:32,1,2023-07-26 23:24:32
+271,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 21:30:45,2023-07-25 21:30:45,1,2023-07-26 23:24:32
+272,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 21:32:48,2023-07-25 21:32:48,1,2023-07-26 23:24:32
+273,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 21:33:42,2023-07-25 21:33:42,1,2023-07-26 23:24:32
+274,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 21:35:24,2023-07-25 21:35:24,1,2023-07-26 23:24:32
+275,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 21:35:42,2023-07-25 21:35:42,1,2023-07-26 23:24:32
+276,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 21:36:07,2023-07-25 21:36:07,1,2023-07-26 23:24:32
+277,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 21:36:18,2023-07-25 21:36:18,1,2023-07-26 23:24:32
+278,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 21:36:26,2023-07-25 21:36:26,1,2023-07-26 23:24:32
+279,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 21:38:01,2023-07-25 21:38:01,1,2023-07-26 23:24:32
+280,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 22:03:02,2023-07-25 22:03:03,1,2023-07-26 23:24:32
+281,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 22:03:11,2023-07-25 22:03:11,1,2023-07-26 23:24:32
+282,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 22:03:14,2023-07-25 22:03:14,1,2023-07-26 23:24:32
+283,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 22:03:17,2023-07-25 22:03:17,1,2023-07-26 23:24:32
+284,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 22:03:36,2023-07-25 22:03:36,1,2023-07-26 23:24:32
+285,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 22:03:38,2023-07-25 22:03:38,1,2023-07-26 23:24:32
+286,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 22:03:42,2023-07-25 22:03:42,1,2023-07-26 23:24:32
+287,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 22:03:49,2023-07-25 22:03:49,1,2023-07-26 23:24:32
+288,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 22:04:15,2023-07-25 22:04:15,1,2023-07-26 23:24:32
+289,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 22:04:36,2023-07-25 22:04:36,1,2023-07-26 23:24:32
+290,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 22:04:42,2023-07-25 22:04:42,1,2023-07-26 23:24:32
+291,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 22:04:51,2023-07-25 22:04:51,1,2023-07-26 23:24:32
+292,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 22:04:54,2023-07-25 22:04:54,1,2023-07-26 23:24:32
+293,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 22:05:00,2023-07-25 22:05:00,1,2023-07-26 23:24:32
+294,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 22:05:04,2023-07-25 22:05:04,1,2023-07-26 23:24:32
+295,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 22:05:37,2023-07-25 22:05:37,1,2023-07-26 23:24:32
+296,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 22:06:11,2023-07-25 22:06:11,1,2023-07-26 23:24:32
+297,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 22:15:30,2023-07-25 22:15:30,1,2023-07-26 23:24:32
+298,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 22:15:44,2023-07-25 22:15:44,1,2023-07-26 23:24:32
+299,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 22:16:42,2023-07-25 22:16:42,1,2023-07-26 23:24:32
+300,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-07-25 22:16:47,2023-07-25 22:16:47,1,2023-07-26 23:24:32
+301,admin,192.168.21.129,OMC,EXPORT,Number of successfully exported alarm messages:317,Operation successful,2023-07-26 09:58:22,2023-07-26 09:58:22,1,2023-07-26 23:24:32
+302,admin,192.168.21.129,OMC,EXPORT,Number of successfully exported alarm messages:318,Operation successful,2023-07-26 14:09:03,2023-07-26 14:09:04,1,2023-07-26 23:24:32
+303,admin,192.168.21.129,OMC,UPDATE,UPDATE successful,Operation successful,2023-07-26 14:57:50,2023-07-26 14:57:50,0,2023-07-26 23:24:32
+304,admin,192.168.21.129,OMC,UPDATE,UPDATE successful,Operation successful,2023-07-26 15:00:50,2023-07-26 15:00:51,0,2023-07-26 23:24:32
+305,admin,192.168.21.129,OMC,UPDATE,UPDATE successful,Operation successful,2023-07-26 15:03:59,2023-07-26 15:03:59,0,2023-07-26 23:24:32
+306,admin,192.168.21.129,OMC,UPDATE,UPDATE successful,Operation successful,2023-07-26 15:05:14,2023-07-26 15:05:14,0,2023-07-26 23:24:32
+307,admin,192.168.21.129,OMC,UPDATE,UPDATE successful,Operation successful,2023-07-26 15:07:06,2023-07-26 15:07:06,0,2023-07-26 23:24:32
+308,admin,192.168.21.129,OMC,UPDATE,UPDATE successful,Operation successful,2023-07-26 15:07:23,2023-07-26 15:07:23,0,2023-07-26 23:24:32
+309,admin,192.168.21.129,OMC,UPDATE,UPDATE successful,Operation successful,2023-07-26 15:07:37,2023-07-26 15:07:37,0,2023-07-26 23:24:32
+310,admin,192.168.21.129,OMC,UPDATE,UPDATE successful,Operation successful,2023-07-26 15:07:40,2023-07-26 15:07:40,0,2023-07-26 23:24:32
+311,admin,192.168.21.129,OMC,UPDATE,UPDATE successful,Operation successful,2023-07-26 15:07:46,2023-07-26 15:07:46,0,2023-07-26 23:24:32
+312,admin,192.168.21.129,OMC,UPDATE,UPDATE successful,Operation successful,2023-07-26 15:07:49,2023-07-26 15:07:49,0,2023-07-26 23:24:32
+313,admin,192.168.21.129,OMC,UPDATE,UPDATE successful,Operation successful,2023-07-26 15:07:54,2023-07-26 15:07:54,0,2023-07-26 23:24:32
+314,admin,192.168.21.129,OMC,UPDATE,UPDATE successful,Operation successful,2023-07-26 15:07:58,2023-07-26 15:07:58,0,2023-07-26 23:24:32
+315,admin,192.168.21.129,OMC,UPDATE,UPDATE successful,Operation successful,2023-07-26 15:08:04,2023-07-26 15:08:04,0,2023-07-26 23:24:32
+316,admin,192.168.21.129,OMC,UPDATE,UPDATE successful,Operation successful,2023-07-26 15:08:19,2023-07-26 15:08:19,0,2023-07-26 23:24:32
+317,admin,192.168.21.129,OMC,UPDATE,UPDATE successful,Operation successful,2023-07-26 15:08:28,2023-07-26 15:08:28,0,2023-07-26 23:24:32
+318,admin,192.168.21.129,OMC,UPDATE,UPDATE successful,Operation successful,2023-07-26 15:10:17,2023-07-26 15:10:17,0,2023-07-26 23:24:32
+319,admin,192.168.21.129,OMC,UPDATE,UPDATE successful,Operation successful,2023-07-26 15:10:35,2023-07-26 15:10:35,0,2023-07-26 23:24:32
+320,admin,192.168.21.129,OMC,UPDATE,UPDATE successful,Operation successful,2023-07-26 15:11:10,2023-07-26 15:11:10,0,2023-07-26 23:24:32
+321,admin,192.168.21.129,OMC,EXPORT,Number of successfully exported alarm messages:319,Operation successful,2023-07-26 15:13:59,2023-07-26 15:13:59,1,2023-07-26 23:24:32
+322,admin,192.168.21.129,OMC,UPDATE,UPDATE successful,Operation successful,2023-07-26 15:14:01,2023-07-26 15:14:01,0,2023-07-26 23:24:32
+323,admin,192.168.21.129,NF,DELETE,Failed to delete the network element,Operation failed,2023-07-26 17:48:43,2023-07-26 17:48:47,1,2023-07-26 23:24:32
+324,admin,192.168.21.129,OMC,SET,Set automatic confirmation configuration,Operation successful,2023-07-26 19:50:02,2023-07-26 19:50:02,0,2023-07-26 23:24:32
+325,admin,192.168.21.129,OMC,SET,Set automatic confirmation configuration,Operation successful,2023-07-26 19:50:15,2023-07-26 19:50:15,0,2023-07-26 23:24:32
+326,admin,192.168.21.129,OMC,SET,Set automatic confirmation configuration,Operation successful,2023-07-26 19:52:19,2023-07-26 19:52:19,0,2023-07-26 23:24:32
+327,admin,192.168.21.129,OMC,SET,Set automatic confirmation configuration,Operation successful,2023-07-26 19:52:57,2023-07-26 19:52:57,0,2023-07-26 23:24:32
+328,admin,192.168.21.129,OMC,SET,Set automatic confirmation configuration,Operation successful,2023-07-26 19:53:45,2023-07-26 19:53:45,0,2023-07-26 23:24:32
+329,admin,192.168.21.129,OMC,SET,Set automatic confirmation configuration,Operation successful,2023-07-26 19:54:10,2023-07-26 19:54:10,0,2023-07-26 23:24:32
+330,admin,192.168.21.129,OMC,SET,Set automatic confirmation configuration,Operation successful,2023-07-26 20:10:20,2023-07-26 20:10:20,0,2023-07-26 23:24:32
+331,admin,192.168.21.129,OMC,UPDATE,UPDATE successful,Operation successful,2023-07-26 20:17:38,2023-07-26 20:17:38,0,2023-07-26 23:24:32
+332,admin,192.168.21.129,OMC,UPDATE,UPDATE successful,Operation successful,2023-07-26 20:25:35,2023-07-26 20:25:35,0,2023-07-26 23:24:32
+333,admin,192.168.21.129,OMC,SET,Set automatic confirmation configuration,Operation successful,2023-07-26 21:05:58,2023-07-26 21:05:58,0,2023-07-26 23:24:32
+334,admin,192.168.21.129,OMC,SET,Set automatic confirmation configuration,Operation successful,2023-07-26 21:06:42,2023-07-26 21:06:42,0,2023-07-26 23:24:32
+335,admin,192.168.21.129,OMC,SET,Set automatic confirmation configuration,Operation successful,2023-07-26 21:06:45,2023-07-26 21:06:45,0,2023-07-26 23:24:32
+336,user1,192.168.21.129,,SELECT,SELECTUDM/SZ_011 Information,Operation successful,2023-07-26 21:57:09,2023-07-26 21:57:09,1,2023-07-26 23:24:32
+337,user1,192.168.21.129,,SELECT,SELECTUDM/SZ_02 Information,Operation successful,2023-07-26 21:57:16,2023-07-26 21:57:16,1,2023-07-26 23:24:32
+338,user1,192.168.21.129,,SELECT,SELECTUDM/SZ_011 Information,Operation successful,2023-07-26 22:13:33,2023-07-26 22:13:33,1,2023-07-26 23:24:32
+339,user1,192.168.21.129,,SELECT,SELECTUDM/SZ_011 Information,Operation successful,2023-07-26 22:13:58,2023-07-26 22:13:58,1,2023-07-26 23:24:32
+340,user1,192.168.21.129,,SELECT,SELECTUDM/SZ_02 Information,Operation successful,2023-07-26 22:15:00,2023-07-26 22:15:00,1,2023-07-26 23:24:32
+341,user1,192.168.21.129,,SELECT,SELECTUDM/SZ_02 Information,Operation successful,2023-07-26 22:18:55,2023-07-26 22:18:55,1,2023-07-26 23:24:32
+342,user1,192.168.21.129,,SELECT,SELECTUDM/SZ_02 Information,Operation successful,2023-07-26 22:21:24,2023-07-26 22:21:24,1,2023-07-26 23:24:32
+343,user1,192.168.21.129,,SELECT,SELECTUDM/SZ_02 Information,Operation successful,2023-07-26 22:23:12,2023-07-26 22:23:12,1,2023-07-26 23:24:32
+344,user1,192.168.21.129,,SELECT,SELECTUDM/SZ_02 Information,Operation successful,2023-07-26 22:23:28,2023-07-26 22:23:28,1,2023-07-26 23:24:32
+345,admin,192.168.21.129,OMC,UPDATE,UPDATE successful,Operation successful,2023-07-26 23:33:13,2023-07-26 23:33:13,0,2023-07-26 23:33:14
+346,admin,192.168.21.129,OMC,UPDATE,UPDATE successful,Operation successful,2023-07-26 23:33:30,2023-07-26 23:33:30,0,2023-07-26 23:33:30
+347,admin,192.168.21.129,OMC,UPDATE,UPDATE successful,Operation successful,2023-07-26 23:34:13,2023-07-26 23:34:13,0,2023-07-26 23:34:14
+348,user1,192.168.21.129,,SELECT,SELECTAMF/SZ_T01 Information,Operation successful,2023-07-26 23:38:01,2023-07-26 23:38:01,1,2023-07-26 23:38:01
+349,user1,192.168.21.129,,SELECT,SELECT UDM/SZ_011 Information,Operation successful,2023-07-27 09:29:16,2023-07-27 09:29:16,1,2023-07-27 09:29:16
+350,user1,192.168.21.129,,SELECT,SELECT UPF_SZ_01 Information,Operation successful,2023-07-27 09:29:40,2023-07-27 09:29:40,1,2023-07-27 09:29:41
+351,user1,192.168.21.129,,SELECT,SELECT UDM_SZ_02 Information,Operation successful,2023-07-27 09:51:26,2023-07-27 09:51:26,1,2023-07-27 09:51:27
+352,user1,192.168.21.129,,SELECT,SELECT UDM_SZ_02 Information,Operation successful,2023-07-27 10:14:23,2023-07-27 10:14:23,1,2023-07-27 10:14:24
+353,user1,192.168.21.129,,SELECT,SELECT UDM_SZ_02 Information,Operation successful,2023-07-27 10:15:22,2023-07-27 10:15:22,1,2023-07-27 10:15:23
+354,user1,192.168.21.129,,SELECT,SELECT UPF_UPF_SZ_RD_109 Information,Operation successful,2023-07-27 10:16:05,2023-07-27 10:16:05,1,2023-07-27 10:16:05
+355,user1,192.168.21.129,,SELECT,SELECT AMF_SZ_T01 Information,Operation successful,2023-07-27 10:16:34,2023-07-27 10:16:34,1,2023-07-27 10:16:34
+356,user1,192.168.21.129,,SELECT,SELECT UPF_SZ_01 Information,Operation successful,2023-07-27 10:17:07,2023-07-27 10:17:07,1,2023-07-27 10:17:07
+357,user1,192.168.21.129,,SELECT,SELECT UDM_SZ_02 Information,Operation successful,2023-07-27 10:17:22,2023-07-27 10:17:22,1,2023-07-27 10:17:22
+358,user1,192.168.21.129,,SELECT,SELECT UDM_SZ_02 Information,Operation successful,2023-07-27 10:19:19,2023-07-27 10:19:19,1,2023-07-27 10:19:20
+359,user1,192.168.21.129,,SELECT,SELECT UPF_SZ_01 Information,Operation successful,2023-07-27 10:20:25,2023-07-27 10:20:25,1,2023-07-27 10:20:26
+360,user1,192.168.21.129,,SELECT,SELECT UDM_SZ_02 Information,Operation successful,2023-07-27 10:20:54,2023-07-27 10:20:54,1,2023-07-27 10:20:54
+361,user1,192.168.21.129,,SELECT,SELECT UDM_SZ_02 Information,Operation successful,2023-07-27 10:21:13,2023-07-27 10:21:13,1,2023-07-27 10:21:14
+362,user1,192.168.21.129,,SELECT,SELECT UDM_SZ_02 Information,Operation successful,2023-07-27 10:21:20,2023-07-27 10:21:20,1,2023-07-27 10:21:21
+363,admin,192.168.21.129,,SELECT,SELECT UPF_UPF_SZ_RD_109 Information,Operation successful,2023-07-27 10:27:11,2023-07-27 10:27:11,1,2023-07-27 10:27:11
+364,admin,192.168.21.129,,SELECT,SELECT UPF_UPF_SZ_RD_109 Information,Operation successful,2023-07-27 10:27:31,2023-07-27 10:27:31,0,2023-07-27 10:27:32
+365,admin,192.168.21.129,OMC,DELETE,DELETE user successful,Operation successful,2023-07-27 11:02:52,2023-07-27 11:02:55,1,2023-07-27 11:02:56
+366,admin,192.168.21.129,OMC,ADD,Adding network element AMF failed,Operation failed,2023-07-27 22:33:41,2023-07-27 22:33:41,1,2023-07-27 22:33:42
+367,admin,192.168.21.129,OMC,ADD,Adding network element AMF failed,Operation failed,2023-07-27 22:35:44,2023-07-27 22:35:44,1,2023-07-27 22:35:45
+368,admin,192.168.21.129,OMC,ADD,Adding network element AMF failed,Operation failed,2023-07-27 22:36:01,2023-07-27 22:36:01,1,2023-07-27 22:36:02
+369,admin,192.168.21.129,OMC,ADD,Adding network element AMF failed,Operation failed,2023-07-27 22:48:02,2023-07-27 22:48:02,1,2023-07-27 22:48:03
+370,admin,192.168.21.129,OMC,ADD,Adding network element AMF failed,Operation failed,2023-07-28 10:10:03,2023-07-28 10:10:03,1,2023-07-28 10:10:03
+371,admin,192.168.21.129,OMC,ADD,Adding network element AMF failed,Operation failed,2023-07-28 10:10:08,2023-07-28 10:10:08,1,2023-07-28 10:10:08
+372,admin,192.168.21.129,OMC,ADD,Adding network element AMF failed,Operation failed,2023-07-28 10:21:03,2023-07-28 10:21:03,1,2023-07-28 10:21:03
+373,admin,192.168.21.129,OMC,ADD,Adding network element AMF failed,Operation failed,2023-07-28 10:45:38,2023-07-28 10:45:38,1,2023-07-28 10:45:38
+374,admin,192.168.21.129,OMC,ADD,Adding network element AMF failed,Operation failed,2023-07-28 10:45:49,2023-07-28 10:45:49,1,2023-07-28 10:45:49
+375,admin,192.168.21.129,OMC,ADD,Successfully added network element AMF,Operation successful,2023-07-28 16:59:53,2023-07-28 16:59:53,1,2023-07-28 16:59:53
+376,admin,192.168.21.129,OMC,DELETE,Delete custom indicator,Operation successful,2023-07-28 17:55:23,2023-07-28 17:55:27,1,2023-07-28 17:55:28
+377,admin,192.168.21.129,OMC,DELETE,Delete custom indicator,Operation successful,2023-07-28 17:57:36,2023-07-28 17:57:37,1,2023-07-28 17:57:38
+378,admin,192.168.21.129,OMC,DELETE,Delete custom indicator,Operation successful,2023-07-28 20:49:58,2023-07-28 20:50:00,1,2023-07-28 20:50:00
+379,admin,192.168.21.129,OMC,SET,Set deletion deadline,Operation successful,2023-07-29 10:14:59,2023-07-29 10:14:59,0,2023-07-29 10:15:00
+380,admin,192.168.21.129,OMC,ADD,Successfully added network element AMF,Operation successful,2023-07-29 10:18:48,2023-07-29 10:18:48,1,2023-07-29 10:18:49
+381,admin,192.168.21.129,OMC,ADD,Successfully added network element AMF,Operation successful,2023-07-29 10:19:33,2023-07-29 10:19:33,1,2023-07-29 10:19:34
+382,admin,192.168.21.129,OMC,ADD,Successfully added network element AMF,Operation successful,2023-07-29 10:29:40,2023-07-29 10:29:40,1,2023-07-29 10:29:41
+383,admin,192.168.21.129,OMC,ADD,Successfully added network element AMF,Operation successful,2023-07-29 10:40:01,2023-07-29 10:40:01,1,2023-07-29 10:40:02
+384,admin,192.168.21.129,OMC,SET,Set deletion deadline,Operation successful,2023-07-29 11:01:45,2023-07-29 11:01:45,0,2023-07-29 11:01:45
+385,admin,192.168.21.129,OMC,DELETE,Delete custom indicator,Operation successful,2023-07-29 12:12:08,2023-07-29 12:12:09,1,2023-07-29 12:12:10
+386,admin,192.168.21.129,OMC,DELETE,Delete custom indicator,Operation successful,2023-07-29 12:12:10,2023-07-29 12:12:11,1,2023-07-29 12:12:12
+387,admin,192.168.21.129,OMC,ADD,Successfully added network element AMF,Operation successful,2023-07-29 14:14:20,2023-07-29 14:14:20,1,2023-07-29 14:14:21
+388,admin,192.168.21.129,OMC,UPDATE,Update failed,Operation failed,2023-07-29 14:26:29,2023-07-29 14:26:29,1,2023-07-29 14:26:30
+389,admin,192.168.21.129,OMC,UPDATE,Update failed,Operation failed,2023-07-29 14:26:36,2023-07-29 14:26:36,1,2023-07-29 14:26:37
+390,admin,192.168.21.129,OMC,UPDATE,Update failed,Operation failed,2023-07-29 14:26:37,2023-07-29 14:26:37,1,2023-07-29 14:26:37
+391,admin,192.168.21.129,OMC,UPDATE,Update failed,Operation failed,2023-07-29 14:26:44,2023-07-29 14:26:44,1,2023-07-29 14:26:45
+392,admin,192.168.21.129,OMC,UPDATE,Update failed,Operation failed,2023-07-29 14:26:55,2023-07-29 14:26:55,1,2023-07-29 14:26:56
+393,admin,192.168.21.129,OMC,UPDATE,Successfully update,Operation successful,2023-07-29 14:27:41,2023-07-29 14:27:41,1,2023-07-29 14:27:42
+394,admin,192.168.21.129,OMC,UPDATE,Successfully update,Operation successful,2023-07-29 14:28:26,2023-07-29 14:28:26,1,2023-07-29 14:28:27
+395,admin,192.168.21.129,OMC,EXPORT,Successfully exportedUPFconfiguration file,Operation successful,2023-07-29 22:33:12,2023-07-29 22:33:12,1,2023-07-29 22:33:13
+396,admin,192.168.21.129,,SELECT,SELECT SMF_SZ_01 Information,Operation successful,2023-07-29 22:46:36,2023-07-29 22:46:36,0,2023-07-29 22:46:37
+397,admin,192.168.21.129,,SELECT,SELECT UDM_SZ_R01 Information,Operation successful,2023-07-29 22:51:06,2023-07-29 22:51:06,0,2023-07-29 22:51:07
+398,admin,192.168.21.129,,SELECT,SELECT UDM_SZ_011 Information,Operation successful,2023-07-29 22:54:02,2023-07-29 22:54:02,0,2023-07-29 22:54:03
+399,admin,192.168.21.129,,SELECT,SELECT UDM_SZ_011 Information,Operation successful,2023-07-29 22:54:57,2023-07-29 22:54:57,0,2023-07-29 22:54:58
+400,admin,192.168.21.129,,SELECT,SELECT UDM_SZ_011 Information,Operation successful,2023-07-29 22:55:30,2023-07-29 22:55:30,0,2023-07-29 22:55:31
+401,admin,192.168.21.129,,SELECT,SELECT AMF_SZ_T01 Information,Operation successful,2023-07-29 22:55:39,2023-07-29 22:55:39,0,2023-07-29 22:55:40
+402,admin,192.168.21.129,OMC,SET,Set Logout Waiting Time,Operation successful,2023-07-29 23:26:26,2023-07-29 23:26:26,0,2023-07-29 23:26:27
+403,admin,192.168.21.129,,SELECT,SELECT UPF_UPF_SZ_TEST_239 Information,Operation successful,2023-07-30 20:36:28,2023-07-30 20:36:28,0,2023-07-30 20:36:28
+404,admin,192.168.21.129,OMC,SET,Set alarm forwarding interface ,Operation successful,2023-07-30 21:20:06,2023-07-30 21:20:06,0,2023-07-30 21:20:06
+405,admin,192.168.21.129,OMC,SET,Set alarm forwarding interface ,Operation successful,2023-07-30 21:20:50,2023-07-30 21:20:50,0,2023-07-30 21:20:50
+406,admin,192.168.21.129,OMC,SET,Set Logout Waiting Time,Operation successful,2023-07-31 09:45:16,2023-07-31 09:45:16,0,2023-07-31 09:45:17
+407,admin,192.168.21.129,OMC,SET,Set alarm forwarding interface ,Operation successful,2023-07-31 10:06:11,2023-07-31 10:06:11,0,2023-07-31 10:06:12
+408,admin,192.168.21.129,OMC,SET,Set alarm forwarding interface ,Operation successful,2023-07-31 10:07:01,2023-07-31 10:07:01,0,2023-07-31 10:07:02
+409,admin,192.168.21.129,,SELECT,SELECT SMF_SZ_01 Information,Operation successful,2023-07-31 11:54:22,2023-07-31 11:54:22,0,2023-07-31 11:54:23
+410,admin,192.168.21.129,,SELECT,SELECT AUSF_SZ_01 Information,Operation successful,2023-07-31 13:14:38,2023-07-31 13:14:38,0,2023-07-31 13:14:39
+411,admin,192.168.21.129,,SELECT,SELECT UDM_SZ_011 Information,Operation successful,2023-07-31 13:14:43,2023-07-31 13:14:43,0,2023-07-31 13:14:44
+412,admin,192.168.21.129,,SELECT,SELECT AMF_SZ_T01 Information,Operation successful,2023-07-31 13:14:54,2023-07-31 13:14:54,0,2023-07-31 13:14:55
+413,admin,192.168.21.129,,SELECT,SELECT UDM_SZ_02 Information,Operation successful,2023-07-31 13:16:21,2023-07-31 13:16:21,0,2023-07-31 13:16:22
+414,admin,192.168.21.129,,SELECT,SELECT UDM_SZ_02 Information,Operation successful,2023-07-31 13:16:29,2023-07-31 13:16:29,0,2023-07-31 13:16:30
+415,admin,192.168.21.129,,SELECT,SELECT AUSF_SZ_01 Information,Operation successful,2023-07-31 13:21:01,2023-07-31 13:21:01,0,2023-07-31 13:21:02
+416,admin,192.168.21.129,,SELECT,SELECT AUSF_SZ_01 Information,Operation successful,2023-07-31 13:38:54,2023-07-31 13:38:54,0,2023-07-31 13:38:54
+417,admin,192.168.21.129,,SELECT,SELECT AUSF_SZ_01 Information,Operation successful,2023-07-31 13:39:05,2023-07-31 13:39:05,0,2023-07-31 13:39:06
+418,admin,192.168.21.129,,SELECT,SELECT AUSF_SZ_01 Information,Operation successful,2023-07-31 13:48:33,2023-07-31 13:48:33,0,2023-07-31 13:48:34
+419,admin,192.168.21.129,,SELECT,SELECT SMF_SZ_01 Information,Operation successful,2023-07-31 14:05:01,2023-07-31 14:05:01,0,2023-07-31 14:05:02
+420,admin,192.168.21.129,,SELECT,SELECT AUSF_SZ_01 Information,Operation successful,2023-07-31 14:16:40,2023-07-31 14:16:40,0,2023-07-31 14:16:41
+421,admin,192.168.21.129,,SELECT,SELECT SMF_SZ_01 Information,Operation successful,2023-07-31 14:17:39,2023-07-31 14:17:39,0,2023-07-31 14:17:40
+422,admin,192.168.21.129,,SELECT,SELECT AUSF_SZ_01 Information,Operation successful,2023-07-31 14:49:20,2023-07-31 14:49:20,0,2023-07-31 14:49:20
+423,admin,192.168.21.129,,SELECT,SELECT UDM_SZ_02 Information,Operation successful,2023-07-31 14:50:02,2023-07-31 14:50:02,0,2023-07-31 14:50:03
+424,admin,192.168.21.129,NF,SELECT,SELECT UDM_SZ_011 Information,Operation successful,2023-07-31 14:51:33,2023-07-31 14:51:33,0,2023-07-31 14:51:34
+425,admin,192.168.21.129,NF,SELECT,SELECT UDM_SZ_02 Information,Operation successful,2023-07-31 15:08:01,2023-07-31 15:08:01,0,2023-07-31 15:08:01
+426,admin,192.168.21.129,NF,SELECT,SELECT OMC_SZ_01 Information,Operation successful,2023-07-31 15:13:37,2023-07-31 15:13:38,0,2023-07-31 15:13:38
+427,admin,192.168.21.129,NF,SELECT,SELECT OMC_SZ_01 Information,Operation successful,2023-07-31 15:13:51,2023-07-31 15:13:51,0,2023-07-31 15:13:52
+428,admin,192.168.21.129,NF,UPLOAD,UPLOAD software package,Operation failed,2023-07-31 17:04:56,2023-07-31 17:04:56,0,2023-07-31 17:04:57
+429,admin,192.168.21.129,NF,UPLOAD,UPLOAD software package,Operation failed,2023-07-31 17:05:36,2023-07-31 17:05:37,0,2023-07-31 17:05:37
+430,admin,192.168.21.129,NF,UPLOAD,UPLOAD software package,Operation successful,2023-07-31 17:06:25,2023-07-31 17:07:21,0,2023-07-31 17:07:22
+431,admin,192.168.21.129,NF,UPLOAD,UPLOAD software package,Operation failed,2023-07-31 17:06:18,2023-07-31 17:07:26,0,2023-07-31 17:07:26
+432,admin,192.168.21.129,NF,DELETE,DELETE software package,Operation successful,2023-07-31 17:18:41,2023-07-31 17:18:42,0,2023-07-31 17:18:43
+433,admin,192.168.21.129,NF,UPLOAD,UPLOAD software package,Operation successful,2023-07-31 17:18:53,2023-07-31 17:19:29,0,2023-07-31 17:19:29
+434,admin,192.168.21.129,NF,UPLOAD,UPLOAD File,Operation failed,2023-07-31 17:19:39,2023-07-31 17:20:10,0,2023-07-31 17:20:11
+435,admin,192.168.21.129,NF,UPLOAD,UPLOAD File,Operation failed,2023-07-31 17:21:22,2023-07-31 17:21:53,0,2023-07-31 17:21:54
+436,admin,192.168.21.129,NF,DELETE,DELETE software package,Operation successful,2023-07-31 17:37:23,2023-07-31 17:37:23,0,2023-07-31 17:37:24
+437,admin,192.168.21.129,OMC,EXPORT,Successfully exportedUPFconfiguration file,Operation successful,2023-07-31 19:58:46,2023-07-31 19:58:46,1,2023-07-31 19:58:46
+438,admin,192.168.21.129,OMC,DELETE,Successfully deleted tracking task,Operation successful,2023-07-31 20:47:30,2023-07-31 20:47:30,1,2023-07-31 20:47:30
+439,admin,192.168.21.129,OMC,DELETE,Successfully deleted tracking task,Operation successful,2023-07-31 20:47:31,2023-07-31 20:47:31,1,2023-07-31 20:47:32
+440,admin,192.168.21.129,OMC,DELETE,Successfully deleted tracking task,Operation successful,2023-07-31 20:47:33,2023-07-31 20:47:33,1,2023-07-31 20:47:33
+441,admin,192.168.21.129,OMC,DELETE,Successfully deleted tracking task,Operation successful,2023-07-31 20:47:34,2023-07-31 20:47:34,1,2023-07-31 20:47:35
+442,admin,192.168.21.129,OMC,DELETE,Successfully deleted tracking task,Operation successful,2023-07-31 20:47:36,2023-07-31 20:47:36,1,2023-07-31 20:47:37
+443,admin,192.168.21.129,OMC,DELETE,Successfully deleted tracking task,Operation successful,2023-07-31 20:47:37,2023-07-31 20:47:37,1,2023-07-31 20:47:38
+444,admin,192.168.21.129,OMC,ADD,Failed to issue tracking task ,Operation successful,2023-07-31 20:49:06,2023-07-31 20:49:06,1,2023-07-31 20:49:07
+445,admin,192.168.21.129,OMC,ADD,Failed to issue tracking task ,Operation successful,2023-07-31 20:49:21,2023-07-31 20:49:21,1,2023-07-31 20:49:22
+446,admin,192.168.21.129,OMC,DELETE,Successfully deleted tracking task,Operation successful,2023-07-31 20:52:06,2023-07-31 20:52:06,1,2023-07-31 20:52:07
+447,admin,192.168.21.129,OMC,DELETE,Successfully deleted tracking task,Operation successful,2023-07-31 20:52:08,2023-07-31 20:52:08,1,2023-07-31 20:52:09
+448,admin,192.168.21.129,OMC,DELETE,Successfully deleted tracking task,Operation successful,2023-07-31 21:01:05,2023-07-31 21:01:05,1,2023-07-31 21:01:06
+449,admin,192.168.21.129,OMC,DELETE,Successfully deleted tracking task,Operation successful,2023-07-31 21:01:43,2023-07-31 21:01:43,1,2023-07-31 21:01:44
+450,admin,192.168.21.129,OMC,DELETE,Successfully deleted tracking task,Operation successful,2023-07-31 21:03:55,2023-07-31 21:03:55,1,2023-07-31 21:03:56
+451,admin,192.168.21.129,OMC,DELETE,Successfully deleted tracking task,Operation successful,2023-07-31 21:06:40,2023-07-31 21:06:40,1,2023-07-31 21:06:41
+452,admin,192.168.2.119,NF,UPLOAD,UPLOAD File,Operation failed,2023-07-31 23:16:16,2023-07-31 23:16:18,0,2023-07-31 23:16:18
+453,admin,192.168.2.119,NF,UPLOAD,UPLOAD File,Operation failed,2023-07-31 23:16:17,2023-07-31 23:16:18,0,2023-07-31 23:16:18
+454,admin,192.168.2.119,NF,UPLOAD,UPLOAD File,Operation failed,2023-07-31 23:19:26,2023-07-31 23:19:28,0,2023-07-31 23:19:28
+455,admin,192.168.21.129,NF,UPLOAD,UPLOAD File,Operation failed,2023-08-01 00:22:23,2023-08-01 00:27:22,0,2023-08-01 00:27:23
+456,admin,192.168.21.129,NF,UPLOAD,UPLOAD File,Operation failed,2023-08-01 00:24:42,2023-08-01 00:27:26,0,2023-08-01 00:27:27
+457,admin,192.168.21.129,NF,UPLOAD,UPLOAD software package,Operation failed,2023-08-01 00:31:39,2023-08-01 00:34:08,0,2023-08-01 00:34:09
+458,admin,192.168.21.129,NF,UPLOAD,UPLOAD File,Operation failed,2023-08-01 00:28:51,2023-08-01 00:34:14,0,2023-08-01 00:34:15
+459,admin,192.168.2.119,NF,UPLOAD,UPLOAD software package,Operation successful,2023-08-01 00:36:06,2023-08-01 00:36:06,0,2023-08-01 00:36:06
+460,admin,192.168.21.129,NF,UPLOAD,UPLOAD software package,Operation successful,2023-08-01 00:36:01,2023-08-01 00:37:17,0,2023-08-01 00:37:18
+461,admin,192.168.2.119,NF,UPLOAD,UPLOAD software package,Operation successful,2023-08-01 00:38:01,2023-08-01 00:38:04,0,2023-08-01 00:38:04
+462,admin,192.168.2.119,NF,DELETE,DELETE software package,Operation successful,2023-08-01 00:40:03,2023-08-01 00:40:05,0,2023-08-01 00:40:05
+463,admin,192.168.2.119,NF,DELETE,DELETE software package,Operation successful,2023-08-01 00:40:06,2023-08-01 00:40:07,0,2023-08-01 00:40:07
+464,admin,192.168.2.119,NF,UPLOAD,UPLOAD software package,Operation successful,2023-08-01 00:40:25,2023-08-01 00:40:27,0,2023-08-01 00:40:27
+465,admin,192.168.2.119,NF,DELETE,DELETE software package,Operation successful,2023-08-01 00:41:30,2023-08-01 00:41:31,0,2023-08-01 00:41:31
+466,admin,192.168.2.119,NF,UPLOAD,UPLOAD File,Operation failed,2023-08-01 00:41:46,2023-08-01 00:41:48,0,2023-08-01 00:41:48
+467,admin,192.168.2.119,NF,UPLOAD,UPLOAD File,Operation failed,2023-08-01 00:41:58,2023-08-01 00:42:00,0,2023-08-01 00:42:00
+468,admin,192.168.2.119,NF,UPLOAD,UPLOAD File,Operation failed,2023-08-01 00:43:29,2023-08-01 00:43:32,0,2023-08-01 00:43:32
+469,admin,192.168.2.119,NF,UPLOAD,UPLOAD File,Operation failed,2023-08-01 00:44:13,2023-08-01 00:44:15,0,2023-08-01 00:44:15
+470,admin,192.168.2.119,NF,UPLOAD,UPLOAD File,Operation failed,2023-08-01 00:44:37,2023-08-01 00:44:39,0,2023-08-01 00:44:39
+471,admin,192.168.2.119,NF,UPLOAD,UPLOAD File,Operation failed,2023-08-01 00:45:09,2023-08-01 00:45:11,0,2023-08-01 00:45:11
+472,admin,192.168.2.119,NF,UPLOAD,UPLOAD File,Operation failed,2023-08-01 00:45:46,2023-08-01 00:45:49,0,2023-08-01 00:45:49
+473,admin,192.168.2.119,NF,DELETE,DELETE software package,Operation successful,2023-08-01 00:46:32,2023-08-01 00:46:33,0,2023-08-01 00:46:33
+474,admin,192.168.2.119,NF,UPLOAD,UPLOAD File,Operation failed,2023-08-01 00:46:51,2023-08-01 00:46:52,0,2023-08-01 00:46:52
+475,admin,192.168.2.119,NF,UPLOAD,UPLOAD File,Operation failed,2023-08-01 00:48:11,2023-08-01 00:48:13,0,2023-08-01 00:48:13
+476,admin,192.168.2.119,NF,UPLOAD,UPLOAD File,Operation failed,2023-08-01 00:49:07,2023-08-01 00:49:08,0,2023-08-01 00:49:08
+477,admin,192.168.2.119,NF,UPLOAD,UPLOAD File,Operation failed,2023-08-01 00:52:45,2023-08-01 00:52:48,0,2023-08-01 00:52:48
+478,admin,192.168.2.119,NF,UPLOAD,UPLOAD software package,Operation successful,2023-08-01 00:54:58,2023-08-01 00:55:00,0,2023-08-01 00:55:00
+479,admin,192.168.2.119,NF,DELETE,DELETE software package,Operation successful,2023-08-01 00:55:09,2023-08-01 00:55:10,0,2023-08-01 00:55:10
+480,admin,192.168.2.119,NF,UPLOAD,UPLOAD software package,Operation successful,2023-08-01 00:55:22,2023-08-01 00:55:24,0,2023-08-01 00:55:24
+481,admin,192.168.2.119,NF,DELETE,DELETE software package,Operation successful,2023-08-01 01:01:40,2023-08-01 01:01:41,0,2023-08-01 01:01:41
+482,admin,192.168.2.119,NF,UPLOAD,UPLOAD software package,Operation failed,2023-08-01 01:01:55,2023-08-01 01:01:58,0,2023-08-01 01:01:58
+483,admin,192.168.2.119,NF,UPLOAD,UPLOAD software package,Operation failed,2023-08-01 01:02:04,2023-08-01 01:02:06,0,2023-08-01 01:02:06
+484,admin,192.168.2.119,NF,UPLOAD,UPLOAD software package,Operation failed,2023-08-01 01:02:37,2023-08-01 01:02:38,0,2023-08-01 01:02:38
+485,admin,192.168.2.119,NF,UPLOAD,UPLOAD software package,Operation failed,2023-08-01 01:03:30,2023-08-01 01:03:31,0,2023-08-01 01:03:31
+486,admin,192.168.2.119,NF,UPLOAD,UPLOAD software package,Operation failed,2023-08-01 01:04:17,2023-08-01 01:04:18,0,2023-08-01 01:04:18
+487,admin,192.168.30.3,OMC,SET,Successfully set the config for the alarm ,Operation successful,2023-08-01 10:47:47,2023-08-01 10:47:47,1,2023-08-01 10:47:48
+488,admin,192.168.30.3,OMC,SET,Successfully set the config for the alarm ,Operation successful,2023-08-01 10:48:27,2023-08-01 10:48:27,1,2023-08-01 10:48:27
+489,admin,192.168.30.3,OMC,SET,Successfully set the config for the alarm ,Operation successful,2023-08-01 10:57:23,2023-08-01 10:57:23,1,2023-08-01 10:57:24
+490,admin,192.168.30.3,NF,SELECT,SELECT UDM_SZ_011 Information,Operation successful,2023-08-01 14:08:02,2023-08-01 14:08:02,0,2023-08-01 14:08:02
+491,admin,192.168.2.119,NF,UPLOAD,UPLOAD software package,Operation successful,2023-08-01 20:33:51,2023-08-01 20:33:52,0,2023-08-01 20:33:52
+492,admin,192.168.2.119,NF,Distribute,Distribute version,Operation failed,2023-08-01 20:34:02,2023-08-01 20:34:04,0,2023-08-01 20:34:04
+493,admin,192.168.2.119,NF,Distribute,Distribute version,Operation failed,2023-08-01 20:34:10,2023-08-01 20:34:12,0,2023-08-01 20:34:12
+494,admin,192.168.2.119,NF,SELECT,SELECT OMC_SZ_01 Information,Operation successful,2023-08-01 20:34:28,2023-08-01 20:34:28,0,2023-08-01 20:34:28
+495,admin,192.168.2.119,OMC,ADD,Successfully added network element OMC,Operation successful,2023-08-01 22:03:28,2023-08-01 22:03:28,1,2023-08-01 22:03:28
+496,admin,192.168.30.3,OMC,SET,Successfully set the syncTaskPeriod for the alarm ,Operation successful,2023-08-01 22:33:45,2023-08-01 22:33:45,0,2023-08-01 22:33:46
+497,admin,192.168.30.3,OMC,SET,Failed to set the syncTaskPeriod for the alarm,Operation failed,2023-08-01 22:33:45,2023-08-01 22:33:45,0,2023-08-01 22:33:46
+498,admin,192.168.30.3,OMC,SET,Successfully set the syncTaskPeriod for the alarm ,Operation successful,2023-08-01 22:36:21,2023-08-01 22:36:21,0,2023-08-01 22:36:22
+499,admin,192.168.30.3,OMC,SET,Failed to set the syncTaskPeriod for the alarm,Operation failed,2023-08-01 22:36:21,2023-08-01 22:36:21,0,2023-08-01 22:36:22
+500,admin,192.168.30.3,OMC,SET,Failed to set the syncTaskPeriod for the alarm,Operation failed,2023-08-01 22:39:36,2023-08-01 22:39:36,0,2023-08-01 22:39:36
+501,admin,192.168.30.3,OMC,SET,Successfully set the syncTaskPeriod for the alarm ,Operation successful,2023-08-01 22:39:36,2023-08-01 22:39:36,0,2023-08-01 22:39:36
+502,admin,192.168.30.3,OMC,SET,Successfully set the syncTaskPeriod for the alarm ,Operation successful,2023-08-01 22:40:06,2023-08-01 22:40:06,0,2023-08-01 22:40:06
+503,admin,192.168.30.3,OMC,SET,Successfully set the syncTaskPeriod for the alarm ,Operation successful,2023-08-01 22:41:51,2023-08-01 22:41:51,0,2023-08-01 22:41:52
+504,admin,192.168.2.119,OMC,ADD,Successfully added network element OMC,Operation successful,2023-08-01 23:03:56,2023-08-01 23:03:56,1,2023-08-01 23:03:56
+505,admin,192.168.2.119,OMC,ADD,Successfully added network element OMC,Operation successful,2023-08-02 09:26:41,2023-08-02 09:26:41,0,2023-08-02 09:26:41
+506,admin,192.168.30.3,OMC,SET,Successfully activated alarm synchronization settings,Operation successful,2023-08-02 09:51:57,2023-08-02 09:51:57,0,2023-08-02 09:51:58
+507,admin,192.168.30.3,OMC,SET,Successfully activated alarm synchronization settings,Operation successful,2023-08-02 09:52:05,2023-08-02 09:52:05,0,2023-08-02 09:52:05
+508,admin,192.168.30.3,OMC,SET,Successfully activated alarm synchronization settings,Operation successful,2023-08-02 09:52:40,2023-08-02 09:52:40,0,2023-08-02 09:52:41
+509,admin,192.168.30.3,OMC,SET,Successfully activated alarm synchronization settings,Operation successful,2023-08-02 09:53:40,2023-08-02 09:53:40,0,2023-08-02 09:53:41
+510,admin,192.168.30.3,OMC,SET,Successfully set the syncTaskPeriod for the alarm ,Operation successful,2023-08-02 09:55:07,2023-08-02 09:55:07,0,2023-08-02 09:55:08
+511,admin,192.168.2.119,NF,SELECT,SELECT OMC_SZ_01 Information,Operation successful,2023-08-02 10:11:20,2023-08-02 10:11:20,0,2023-08-02 10:11:20
+512,admin,192.168.30.3,OMC,SET,Suspended successfully,Operation successful,2023-08-02 10:26:16,2023-08-02 10:26:16,0,2023-08-02 10:26:17
+513,admin,192.168.30.3,OMC,SET,Suspended successfully,Operation successful,2023-08-02 10:27:00,2023-08-02 10:27:00,0,2023-08-02 10:27:01
+514,admin,192.168.30.3,OMC,SET,Successfully activated alarm synchronization settings,Operation successful,2023-08-02 10:27:44,2023-08-02 10:27:44,0,2023-08-02 10:27:45
+515,admin,192.168.30.3,OMC,SET,Suspended successfully,Operation successful,2023-08-02 10:27:45,2023-08-02 10:27:45,0,2023-08-02 10:27:46
+516,admin,192.168.30.3,OMC,SET,Successfully activated alarm synchronization settings,Operation successful,2023-08-02 10:27:47,2023-08-02 10:27:47,0,2023-08-02 10:27:48
+517,admin,192.168.30.3,OMC,SET,Successfully set the syncTaskPeriod for the alarm ,Operation successful,2023-08-02 11:13:59,2023-08-02 11:13:59,0,2023-08-02 11:14:00
+518,admin,192.168.30.3,OMC,SET,Successfully set the syncTaskPeriod for the alarm ,Operation successful,2023-08-02 11:14:22,2023-08-02 11:14:22,0,2023-08-02 11:14:23
+519,admin,192.168.30.3,OMC,SET,Successfully set the syncTaskPeriod for the alarm ,Operation successful,2023-08-02 11:14:25,2023-08-02 11:14:25,0,2023-08-02 11:14:26
+520,admin,192.168.30.3,OMC,SET,Successfully set the syncTaskPeriod for the alarm ,Operation successful,2023-08-02 11:14:30,2023-08-02 11:14:30,0,2023-08-02 11:14:31
+521,admin,192.168.30.3,OMC,SET,Suspended successfully,Operation successful,2023-08-02 11:17:25,2023-08-02 11:17:25,0,2023-08-02 11:17:26
+522,admin,192.168.30.3,OMC,SET,Successfully set the syncTaskPeriod for the alarm ,Operation successful,2023-08-02 11:17:28,2023-08-02 11:17:28,0,2023-08-02 11:17:29
+523,admin,192.168.30.3,OMC,View,Viewing Alarm Help Documents,Operation successful,2023-08-02 11:27:48,2023-08-02 11:27:48,0,2023-08-02 11:27:49
+524,admin,192.168.2.119,NF,DELETE,DELETE software package,Operation successful,2023-08-02 14:20:31,2023-08-02 14:20:32,0,2023-08-02 14:20:32
+525,admin,192.168.2.119,NF,UPLOAD,UPLOAD software package,Operation successful,2023-08-02 14:23:31,2023-08-02 14:23:32,0,2023-08-02 14:23:32
+526,admin,192.168.2.119,NF,Distribute,Distribute version,Operation failed,2023-08-02 14:23:43,2023-08-02 14:23:45,0,2023-08-02 14:23:45
+527,admin,192.168.30.3,OMC,SET,Successfully set the config for the alarm ,Operation successful,2023-08-02 17:20:38,2023-08-02 17:20:38,0,2023-08-02 17:20:39
+528,admin,192.168.30.3,NF,SELECT,SELECT OMC_SZ_01 Information,Operation successful,2023-08-03 09:43:22,2023-08-03 09:43:22,0,2023-08-03 09:43:22
+529,admin,192.168.30.3,OMC,SET,Set alarm forwarding interface ,Operation successful,2023-08-03 11:29:48,2023-08-03 11:29:48,0,2023-08-03 11:29:48
+530,admin,192.168.30.3,OMC,SET,Set alarm forwarding interface ,Operation successful,2023-08-03 11:31:26,2023-08-03 11:31:26,0,2023-08-03 11:31:26
+531,admin,192.168.30.3,OMC,SET,Set alarm forwarding interface ,Operation successful,2023-08-03 11:42:16,2023-08-03 11:42:16,0,2023-08-03 11:42:16
+532,admin,192.168.30.3,OMC,SET,Set alarm forwarding interface ,Operation successful,2023-08-03 11:42:21,2023-08-03 11:42:21,0,2023-08-03 11:42:21
+533,admin,192.168.30.3,OMC,SET,Set alarm forwarding interface ,Operation successful,2023-08-03 14:02:49,2023-08-03 14:02:49,0,2023-08-03 14:02:49
+534,admin,192.168.30.3,NF,UPLOAD,UPLOAD software package,Operation successful,2023-08-03 14:11:35,2023-08-03 14:11:36,0,2023-08-03 14:11:36
+535,admin,192.168.30.3,NF,Activation,Activation failed,Operation failed,2023-08-03 14:11:56,2023-08-03 14:11:56,0,2023-08-03 14:11:56
+536,admin,192.168.30.3,NF,Activation,Activation failed,Operation failed,2023-08-03 14:11:58,2023-08-03 14:11:58,0,2023-08-03 14:11:58
+537,admin,192.168.30.3,NF,Activation,Activation failed,Operation failed,2023-08-03 14:11:59,2023-08-03 14:11:59,0,2023-08-03 14:11:59
+538,admin,192.168.30.3,NF,Activation,Activation failed,Operation failed,2023-08-03 14:12:12,2023-08-03 14:12:12,0,2023-08-03 14:12:12
+539,admin,192.168.30.3,OMC,SET,Set Logout Waiting Time,Operation failed,2023-08-03 19:09:51,2023-08-03 19:09:51,0,2023-08-03 19:09:51
+540,admin,192.168.30.3,OMC,SET,Set the prompt content for high-risk instructions,Operation successful,2023-08-03 19:16:32,2023-08-03 19:16:32,0,2023-08-03 19:16:32
+541,admin,192.168.2.119,NF,DELETE,Failed to delete the network element,Operation failed,2023-08-04 16:06:18,2023-08-04 16:06:19,0,2023-08-04 16:06:19
+542,admin,192.168.2.119,NF,DELETE,Failed to delete the network element,Operation failed,2023-08-04 16:06:30,2023-08-04 16:06:31,0,2023-08-04 16:06:31
+543,admin,192.168.2.119,NF,DELETE,Successfully deleted the network element,Operation successful,2023-08-04 16:06:53,2023-08-04 16:06:54,0,2023-08-04 16:06:54
+544,admin,192.168.2.119,NF,DELETE,Successfully deleted the network element,Operation successful,2023-08-04 16:06:55,2023-08-04 16:06:56,0,2023-08-04 16:06:56
+545,admin,192.168.2.119,NF,DELETE,Successfully deleted the network element,Operation successful,2023-08-04 16:06:57,2023-08-04 16:06:58,0,2023-08-04 16:06:58
+546,admin,192.168.2.119,NF,DELETE,Successfully deleted the network element,Operation successful,2023-08-04 16:06:59,2023-08-04 16:07:00,0,2023-08-04 16:07:00
+547,admin,192.168.2.119,NF,DELETE,Successfully deleted the network element,Operation successful,2023-08-04 16:07:01,2023-08-04 16:07:02,0,2023-08-04 16:07:02
+548,admin,192.168.2.119,NF,DELETE,Successfully deleted the network element,Operation successful,2023-08-04 16:07:57,2023-08-04 16:07:59,0,2023-08-04 16:07:59
+549,admin,192.168.2.119,OMC,ADD,Successfully added network element OMC,Operation successful,2023-08-04 16:10:00,2023-08-04 16:10:00,0,2023-08-04 16:10:00
+550,admin,192.168.2.119,OMC,ADD,Successfully added network element OMC,Operation successful,2023-08-04 16:10:42,2023-08-04 16:10:42,0,2023-08-04 16:10:42
+551,admin,192.168.2.119,NF,DELETE,Successfully deleted the network element,Operation successful,2023-08-04 16:10:53,2023-08-04 16:10:54,0,2023-08-04 16:10:54
+552,admin,192.168.30.3,OMC,ADD,Failed to issue tracking task ,Operation successful,2023-08-04 20:22:52,2023-08-04 20:22:52,0,2023-08-04 20:22:53
+553,admin,192.168.30.3,OMC,ADD,Failed to issue tracking task ,Operation successful,2023-08-04 20:23:48,2023-08-04 20:23:49,0,2023-08-04 20:23:49
+554,admin,192.168.30.3,OMC,ADD,Successfully created issue tracking task,Operation successful,2023-08-04 20:24:44,2023-08-04 20:24:44,0,2023-08-04 20:24:45
+555,admin,192.168.30.3,OMC,ADD,Successfully created issue tracking task,Operation successful,2023-08-04 20:25:04,2023-08-04 20:25:04,0,2023-08-04 20:25:05
+556,admin,192.168.2.119,OMC,ADD,Successfully created issue tracking task,Operation successful,2023-08-04 20:56:31,2023-08-04 20:56:31,0,2023-08-04 20:56:31
+557,admin,192.168.2.119,OMC,ADD,Failed to issue tracking task ,Operation successful,2023-08-05 16:53:02,2023-08-05 16:53:02,0,2023-08-05 16:53:02
+558,admin,192.168.2.119,OMC,ADD,Failed to issue tracking task ,Operation successful,2023-08-05 16:53:07,2023-08-05 16:53:07,0,2023-08-05 16:53:07
+559,admin,192.168.2.119,OMC,ADD,Failed to issue tracking task ,Operation successful,2023-08-05 16:53:12,2023-08-05 16:53:15,0,2023-08-05 16:53:15
+560,admin,192.168.2.119,OMC,ADD,Failed to issue tracking task ,Operation successful,2023-08-05 16:53:13,2023-08-05 16:53:15,0,2023-08-05 16:53:15
+561,admin,192.168.2.119,OMC,ADD,Failed to issue tracking task ,Operation successful,2023-08-05 16:53:18,2023-08-05 16:53:18,0,2023-08-05 16:53:18
+562,admin,192.168.2.119,OMC,ADD,Failed to issue tracking task ,Operation successful,2023-08-05 17:02:38,2023-08-05 17:02:38,0,2023-08-05 17:02:38
+563,admin,192.168.2.119,OMC,UPDATE,Failed to modify tracking task,Operation failed,2023-08-05 17:04:16,2023-08-05 17:04:16,0,2023-08-05 17:04:16
+564,admin,192.168.2.119,OMC,UPDATE,Failed to modify tracking task,Operation failed,2023-08-05 17:05:50,2023-08-05 17:05:50,0,2023-08-05 17:05:50
+565,admin,192.168.2.119,OMC,UPDATE,Failed to modify tracking task,Operation failed,2023-08-05 17:06:07,2023-08-05 17:06:07,0,2023-08-05 17:06:07
+566,admin,192.168.2.119,OMC,ADD,Successfully created issue tracking task,Operation successful,2023-08-05 17:07:45,2023-08-05 17:07:45,0,2023-08-05 17:07:45
+567,admin,192.168.2.119,OMC,UPDATE,Failed to modify tracking task,Operation failed,2023-08-05 17:24:35,2023-08-05 17:24:35,0,2023-08-05 17:24:35
+568,admin,192.168.2.119,OMC,UPDATE,Failed to modify tracking task,Operation failed,2023-08-05 17:24:39,2023-08-05 17:24:39,0,2023-08-05 17:24:39
+569,admin,192.168.2.119,OMC,UPDATE,Failed to modify tracking task,Operation failed,2023-08-05 17:24:43,2023-08-05 17:24:43,0,2023-08-05 17:24:43
+570,admin,192.168.2.119,OMC,UPDATE,Failed to modify tracking task,Operation failed,2023-08-05 17:24:44,2023-08-05 17:24:44,0,2023-08-05 17:24:44
+571,admin,192.168.2.119,OMC,UPDATE,Failed to modify tracking task,Operation failed,2023-08-05 17:24:44,2023-08-05 17:24:44,0,2023-08-05 17:24:44
+572,admin,192.168.2.119,OMC,UPDATE,Failed to modify tracking task,Operation failed,2023-08-05 17:24:44,2023-08-05 17:24:45,0,2023-08-05 17:24:45
+573,admin,192.168.2.119,OMC,UPDATE,Failed to modify tracking task,Operation failed,2023-08-05 17:24:45,2023-08-05 17:24:45,0,2023-08-05 17:24:45
+574,admin,192.168.2.119,OMC,UPDATE,Failed to modify tracking task,Operation failed,2023-08-05 17:24:45,2023-08-05 17:24:45,0,2023-08-05 17:24:45
+575,admin,192.168.2.119,OMC,UPDATE,Failed to modify tracking task,Operation failed,2023-08-05 17:24:45,2023-08-05 17:24:45,0,2023-08-05 17:24:45
+576,admin,192.168.2.119,OMC,UPDATE,Failed to modify tracking task,Operation failed,2023-08-05 17:24:45,2023-08-05 17:24:45,0,2023-08-05 17:24:45
+577,admin,192.168.2.119,OMC,UPDATE,Failed to modify tracking task,Operation failed,2023-08-05 17:24:46,2023-08-05 17:24:46,0,2023-08-05 17:24:46
+578,admin,192.168.2.119,OMC,UPDATE,Failed to modify tracking task,Operation failed,2023-08-05 17:24:46,2023-08-05 17:24:46,0,2023-08-05 17:24:46
+579,admin,192.168.2.119,OMC,UPDATE,Failed to modify tracking task,Operation failed,2023-08-05 17:24:46,2023-08-05 17:24:46,0,2023-08-05 17:24:46
+580,admin,192.168.2.119,OMC,UPDATE,Failed to modify tracking task,Operation failed,2023-08-05 17:25:52,2023-08-05 17:25:52,0,2023-08-05 17:25:52
+581,admin,192.168.2.119,OMC,ADD,Failed to issue tracking task ,Operation successful,2023-08-05 17:26:35,2023-08-05 17:26:35,0,2023-08-05 17:26:35
+582,admin,192.168.2.119,OMC,DELETE,Successfully deleted tracking task,Operation successful,2023-08-05 17:27:48,2023-08-05 17:27:48,0,2023-08-05 17:27:48
+583,admin,192.168.2.119,OMC,DELETE,Successfully deleted tracking task,Operation successful,2023-08-05 17:27:51,2023-08-05 17:27:51,0,2023-08-05 17:27:51
+584,admin,192.168.2.119,OMC,ADD,Failed to issue tracking task ,Operation successful,2023-08-05 17:28:09,2023-08-05 17:28:09,0,2023-08-05 17:28:09
+585,admin,192.168.2.119,OMC,ADD,Successfully created issue tracking task,Operation successful,2023-08-05 17:32:45,2023-08-05 17:32:45,0,2023-08-05 17:32:45
+586,admin,192.168.2.119,OMC,DELETE,Successfully deleted tracking task,Operation successful,2023-08-05 18:01:23,2023-08-05 18:01:23,0,2023-08-05 18:01:23
+587,admin,192.168.2.119,OMC,ADD,Successfully created issue tracking task,Operation successful,2023-08-05 18:01:45,2023-08-05 18:01:45,0,2023-08-05 18:01:45
+588,admin,192.168.2.119,OMC,ADD,Successfully created issue tracking task,Operation successful,2023-08-05 18:02:26,2023-08-05 18:02:26,0,2023-08-05 18:02:26
+589,admin,192.168.2.119,OMC,ADD,Successfully created issue tracking task,Operation successful,2023-08-05 18:02:47,2023-08-05 18:02:47,0,2023-08-05 18:02:47
+590,admin,192.168.2.119,NF,UPLOAD,UPLOAD software package,Operation successful,2023-08-07 21:43:06,2023-08-07 21:43:08,0,2023-08-07 21:43:08
+591,admin,192.168.2.119,NF,UPLOAD,UPLOAD software package,Operation successful,2023-08-07 21:46:54,2023-08-07 21:46:56,0,2023-08-07 21:46:56
diff --git a/restagent/etc/restconf-t.yaml b/restagent/etc/restconf-t.yaml
new file mode 100644
index 00000000..d32d8b23
--- /dev/null
+++ b/restagent/etc/restconf-t.yaml
@@ -0,0 +1,109 @@
+# file: log file name
+# level: /trace/debug/info/warn/error/fatal, default: debug
+# duration: rotation time with xx hours, example: 1/12/24 hours
+# count: rotation count of log, default is 30 rotation
+logger:
+ file: d:/goprojects/ems.agt/restagent/log/restagent-t.log
+ level: trace
+ duration: 24
+ count: 2
+
+# rest agent listen ipv4/v6 and port, support multiple routines
+# ip: 0.0.0.0 or ::0, support IPv4/v6
+rest:
+ - ipv4: 0.0.0.0
+ ipv6: fe80::f6bb:7d5f:bcb2:763b%7
+ port: 3030
+ - ipv4: 0.0.0.0
+ ipv6: fe80::f6bb:7d5f:bcb2:763b%7
+ port: 6060
+
+database:
+ type: mysql
+ user: root
+ password: 1000omc@kp!
+ host: 127.0.0.1
+ port: 33066
+ name: omc_db
+ backup: ./database
+
+mml:
+ port: 4100
+ sleep: 200
+ user: admin
+ password: admin
+
+ne:
+ user: root
+ etcdir: /usr/local/etc
+ bindir: /usr/local/bin
+ omcdir: /usr/local/omc
+ licensedir: /usr/local/etc/{neType}/license
+
+# chk2ne: true/false, if put OmcNeConfig parameters to NE
+omc:
+ uriPrefix: /api/rest
+ neType: OMC
+ neId: 001
+ rmUID: 1100RJHX1OMC001
+ neName: OMC
+ province: BJ
+ vendor: RJ
+ dn: 4600
+ chk2ne: false
+ sn: 13750650
+ checksign: false
+ backup: ./backup
+ upload: ./upload
+ frontUpload: D:/goprojects/build/omc/htdocs/front/upload
+ software: ./software
+ license: ./license
+ gtpUri: gtp:192.168.2.119:2152
+ checkContentType: false
+ testMode: true
+
+# Alarm module setting
+# Forward interface:
+# email/sms
+alarm:
+ forwardAlarm: true
+ email:
+ smtp: smtp@ruijie.com.cn
+ port: 25
+ user: smtpuser
+ password: smtpuser@omc
+ sms:
+ apiURL: http://smsc.ruijie.com.cn/
+ accessKeyID: xxxx
+ accessKeySecret: xxxx
+ signName: Ruijie SMSC
+ templateCode: 1000
+
+#User authorized information
+# crypt: mysql/md5/bcrypt
+# token: true/false to check accessToken
+# expires for session, unit: second
+# Support single/multiple session of user
+auth:
+ crypt: bcrypt
+ token: true
+ expires: 1800
+ session: multiple
+
+# Parameter for limit number
+# rmuid_maxnum: the max number of rmUID, default: 50
+# alarmid_maxnum: the max number of AlarmID, default: 50
+# pmid_maxnum: the max number of pmID, default: 50
+# subid_maxnum: the max number of subscription ID, default: 20
+# uri_maxlen: the max length of uri, default: 8192
+# rmuid_regexp: regexp pattern of rmUID
+params:
+ rmuidmaxnum: 50
+ alarmidmaxnum: 50
+ pmidmaxnum: 50
+ subidmaxnum: 20
+ urimaxlen: 2100000
+ rmuidregexp: "[0-9]{4}[A-Z]{2}[A-Z]{2}[0-9A-Z]{1}[0-9A-Z]{3}[0-9A-Z]{1,16}"
+testConfig:
+ enabled: true
+ file: ./etc/testconfig.yaml
\ No newline at end of file
diff --git a/restagent/etc/restconf.yaml b/restagent/etc/restconf.yaml
new file mode 100644
index 00000000..bfe9de1a
--- /dev/null
+++ b/restagent/etc/restconf.yaml
@@ -0,0 +1,110 @@
+# file: log file name
+# level: /trace/debug/info/warn/error/fatal, default: debug
+# duration: rotation time with xx hours, example: 1/12/24 hours
+# count: rotation count of log, default is 30 rotation
+logger:
+ file: d:/goprojects/ems.agt/restagent/log/restagent.log
+ level: trace
+ duration: 24
+ count: 2
+
+# rest agent listen ipv4/v6 and port, support multiple routines
+# ip: 0.0.0.0 or ::0, support IPv4/v6
+rest:
+ - ipv4: 0.0.0.0
+ ipv6:
+ port: 3040
+ - ipv4:
+ ipv6: ::0
+ port: 6070
+
+database:
+ type: mysql
+ user: root
+ password: 1000omc@kp!
+ host: 192.168.0.229
+ port: 33066
+ name: omc_db
+ backup: ./database
+
+mml:
+ port: 4100
+ sleep: 200
+ user: admin
+ password: admin
+
+ne:
+ user: root
+ etcdir: /usr/local/etc
+ bindir: /usr/local/bin
+ omcdir: /usr/local/omc
+ licensedir: /usr/local/etc/{neType}/license
+
+# chk2ne: true/false, if put OmcNeConfig parameters to NE
+omc:
+ uriPrefix: /api/rest
+ neType: OMC
+ neId: 001
+ rmUID: 1100RJHX1OMC001
+ neName: OMC
+ province: BJ
+ vendor: RJ
+ dn: 4600
+ chk2ne: false
+ sn: 13750650
+ checksign: false
+ backup: ./backup
+ upload: ./upload
+ frontUpload: D:/goprojects/build/omc/htdocs/front/upload
+ software: ./software
+ license: ./license
+ gtpUri: gtp:192.168.2.119:2152
+ checkContentType: false
+ testMode: true
+
+# Alarm module setting
+# Forward interface:
+# email/sms
+alarm:
+ forwardAlarm: true
+ email:
+ smtp: smtp@ruijie.com.cn
+ port: 25
+ user: smtpuser
+ password: smtpuser@omc
+ sms:
+ apiURL: http://smsc.ruijie.com.cn/
+ accessKeyID: xxxx
+ accessKeySecret: xxxx
+ signName: Ruijie SMSC
+ templateCode: 1000
+
+#User authorized information
+# crypt: mysql/md5/bcrypt
+# token: true/false to check accessToken
+# expires for session, unit: second
+# Support single/multiple session of user
+auth:
+ crypt: bcrypt
+ token: false
+ expires: 1800
+ session: multiple
+
+# Parameter for limit number
+# rmuid_maxnum: the max number of rmUID, default: 50
+# alarmid_maxnum: the max number of AlarmID, default: 50
+# pmid_maxnum: the max number of pmID, default: 50
+# subid_maxnum: the max number of subscription ID, default: 20
+# uri_maxlen: the max length of uri, default: 8192
+# rmuid_regexp: regexp pattern of rmUID
+params:
+ rmuidmaxnum: 50
+ alarmidmaxnum: 50
+ pmidmaxnum: 50
+ subidmaxnum: 20
+ urimaxlen: 2100000
+ rmuidregexp: "[0-9]{4}[A-Z]{2}[A-Z]{2}[0-9A-Z]{1}[0-9A-Z]{3}[0-9A-Z]{1,16}"
+
+testConfig:
+ enabled: true
+ file: ./etc/testconfig.yaml
\ No newline at end of file
diff --git a/restagent/etc/testconfig.yaml b/restagent/etc/testconfig.yaml
new file mode 100644
index 00000000..b0012901
--- /dev/null
+++ b/restagent/etc/testconfig.yaml
@@ -0,0 +1,19 @@
+UDM:
+ capUsed: 16
+ featureEnabled: [N8,N10,N13]
+AUSF:
+ capUsed: 16
+ featureEnabled: [N12]
+AMF:
+ capUsed: 16
+ featureEnabled: [N1,N2,N8,N11,N12,N14,N15]
+SMF:
+ capUsed: 16
+ featureEnabled: [N4,N7,N10,N11]
+UPF:
+ capUsed: 16
+ featureEnabled: [N3,N4,N6,N9]
+OMC:
+ capUsed: 0
+ featureEnabled: []
+
diff --git a/restagent/makefile b/restagent/makefile
new file mode 100644
index 00000000..201fb1e0
--- /dev/null
+++ b/restagent/makefile
@@ -0,0 +1,26 @@
+# Makefile for rest agent project
+
+PROJECT = OMC
+VERSION = 16.1.1
+PLATFORM = amd64
+ARMPLATFORM = aarch64
+BUILDDIR = ../../build
+DEBBUILDDIR = ../../debbuild
+RPMBUILDDIR = $(HOME)/goprojects/rpmbuild
+INSTALLDIR = /usr/local/omc
+RELEASEDIR = ../../release
+LIBDIR = ems.agt/lib
+BINNAME = restagent
+
+.PHONY: build $(BINNAME)
+build $(BINNAME):
+ go build -o $(BINNAME) -v -ldflags "-X '$(LIBDIR)/global.Version=$(VERSION)' \
+ -X '$(LIBDIR)/global.BuildTime=`date`' \
+ -X '$(LIBDIR)/global.GoVer=`go version`'"
+
+run: $(BINNAME)
+ ./$(BINNAME)
+
+clean:
+ rm ./$(BINNAME)
+
diff --git a/restagent/restagent b/restagent/restagent
new file mode 100644
index 00000000..a73a0805
Binary files /dev/null and b/restagent/restagent differ
diff --git a/restagent/restagent.go b/restagent/restagent.go
new file mode 100644
index 00000000..86811313
--- /dev/null
+++ b/restagent/restagent.go
@@ -0,0 +1,119 @@
+package main
+
+import (
+ "fmt"
+ "net"
+ "net/http"
+ "os"
+ "strconv"
+
+ "ems.agt/lib/dborm"
+ "ems.agt/lib/global"
+ "ems.agt/lib/log"
+ "ems.agt/lib/routes"
+
+ "ems.agt/features/dbrest"
+ "ems.agt/features/fm"
+ "ems.agt/features/pm"
+ "ems.agt/restagent/config"
+)
+
+// const defaultConfigFile = "./etc/restconf.yaml"
+
+// func init() {
+// cfile := flag.String("c", defaultConfigFile, "config file")
+// pv := flag.Bool("v", false, "print version")
+// ph := flag.Bool("h", false, "print help")
+
+// flag.Parse()
+// if *pv {
+// fmt.Printf("OMC restagent version: %s\n%s\n%s\n\n", global.Version, global.BuildTime, global.GoVer)
+// os.Exit(0)
+// }
+// if *ph {
+// flag.Usage()
+// os.Exit(0)
+// }
+
+// config.ReadConfig(*cfile)
+// config.UriPrefix = config.GetYamlConfig().OMC.UriPrefix
+// //fmt.Println(config.UriPrefix)
+// }
+
+func listenIPv6(ipv6 string, port int) {
+ //
+ addr := &net.TCPAddr{
+ IP: net.ParseIP(ipv6),
+ Port: port,
+ }
+
+ listener, err := net.ListenTCP("tcp6", addr)
+ if err != nil {
+ fmt.Println("Failed to listen:", err)
+ return
+ }
+
+ server := &http.Server{}
+ err = server.Serve(listener)
+ if err != nil {
+ fmt.Println("Failed to serve:", err)
+ }
+}
+
+func HttpListen(addr string, router http.Handler) {
+ err := http.ListenAndServe(addr, router)
+ if err != nil {
+ fmt.Println("ListenAndServe err:", err)
+ os.Exit(5)
+ }
+}
+
+func main() {
+ conf := config.GetYamlConfig()
+
+ log.InitLogger(conf.Logger.File, conf.Logger.Duration, conf.Logger.Count, "omc:restagent", config.GetLogLevel())
+ fmt.Printf("OMC restagent version: %s\n", global.Version)
+ log.Infof("========================= OMC restagent startup =========================")
+ log.Infof("OMC restagent version: %s %s %s", global.Version, global.BuildTime, global.GoVer)
+ err := dborm.InitDbClient(conf.Database.Type, conf.Database.User, conf.Database.Password,
+ conf.Database.Host, conf.Database.Port, conf.Database.Name)
+ if err != nil {
+ fmt.Println("dborm.initDbClient err:", err)
+ os.Exit(4)
+ }
+ err = fm.InitDbClient(conf.Database.Type, conf.Database.User, conf.Database.Password,
+ conf.Database.Host, conf.Database.Port, conf.Database.Name)
+ if err != nil {
+ fmt.Println("dborm.initDbClient err:", err)
+ os.Exit(4)
+ }
+ err = pm.InitDbClient(conf.Database.Type, conf.Database.User, conf.Database.Password,
+ conf.Database.Host, conf.Database.Port, conf.Database.Name)
+ if err != nil {
+ fmt.Println("dborm.initDbClient err:", err)
+ os.Exit(4)
+ }
+ err = dbrest.InitDbClient(conf.Database.Type, conf.Database.User, conf.Database.Password,
+ conf.Database.Host, conf.Database.Port, conf.Database.Name)
+ if err != nil {
+ fmt.Println("rests.initDbClient err:", err)
+ os.Exit(4)
+ }
+
+ router := routes.NewRouter()
+
+ for _, rest := range conf.Rest {
+ // ipv4 goroutines
+ if rest.IPv4 != "" {
+ listen := rest.IPv4 + ":" + strconv.Itoa(int(rest.Port))
+ go HttpListen(listen, router)
+ }
+ // ipv6 goroutines
+ if rest.IPv6 != "" {
+ listenv6 := "[" + rest.IPv6 + "]" + ":" + strconv.Itoa(int(rest.Port))
+ go HttpListen(listenv6, router)
+ }
+ }
+
+ select {}
+}
diff --git a/restagent/software/amf/AMF 5GC16.0.0.arm64.rpm b/restagent/software/amf/AMF 5GC16.0.0.arm64.rpm
new file mode 100644
index 00000000..5857b5d5
Binary files /dev/null and b/restagent/software/amf/AMF 5GC16.0.0.arm64.rpm differ
diff --git a/restagent/software/omc/OMC-5GC16.1.1.arm64.rpm b/restagent/software/omc/OMC-5GC16.1.1.arm64.rpm
new file mode 100644
index 00000000..1890fd67
Binary files /dev/null and b/restagent/software/omc/OMC-5GC16.1.1.arm64.rpm differ
diff --git a/restagent/software/udm/UDM 5GC16.1.1.arm64.rpm b/restagent/software/udm/UDM 5GC16.1.1.arm64.rpm
new file mode 100644
index 00000000..3810cc9c
Binary files /dev/null and b/restagent/software/udm/UDM 5GC16.1.1.arm64.rpm differ
diff --git a/restagent/software/udm/udm_0727_2_arm.tgz b/restagent/software/udm/udm_0727_2_arm.tgz
new file mode 100644
index 00000000..401312ff
Binary files /dev/null and b/restagent/software/udm/udm_0727_2_arm.tgz differ
diff --git a/restagent/upload/upf-sz_01-etc-20230725090619.zip b/restagent/upload/upf-sz_01-etc-20230725090619.zip
new file mode 100644
index 00000000..b29257a2
Binary files /dev/null and b/restagent/upload/upf-sz_01-etc-20230725090619.zip differ