Files
be.ems/lib/mmlp/parse.go

1059 lines
31 KiB
Go

package mmlp
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"math"
"net/http"
"regexp"
"strconv"
"strings"
"be.ems/lib/dborm"
"be.ems/lib/global"
"be.ems/lib/log"
"be.ems/lib/run"
tokenConst "be.ems/src/framework/constants/token"
"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"`
MmlHome string `json:"mmlHome"`
Limit int `json:"limit"`
User string `json:"user"`
SessionToken string `josn:"sessionToken"`
Authorization string `josn:"authorization"`
HttpUri string `json:"httpUri"`
UserAgent string `json:"userAgent"`
TagNE string `json:"tagNE"`
}
// 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)(?<!\{[^{}]*),(?![^{}]*\})|(?<!\"[^\"]*),(?![^\"]*\")|(?<!\[[^\[\]]*),(?![^\[\]]*\])`)
//reg = regexp.MustCompile(`,[^'"\(\)]+`)
//params := reg.Split(ms[1], -1)
params := splitByComma(strings.Trim(ms[1], " "))
//params := strings.Split(ms[1], ",")
for _, p := range params {
log.Trace("p:", p)
if p == "" {
continue
}
mc.PaList = append(mc.PaList, p)
reg = regexp.MustCompile(`\s*=\s*`)
pvs := reg.Split(p, -1)
log.Trace("pvs:", pvs)
if len(pvs) == 2 {
mc.Params = append(mc.Params, Param{Name: pvs[0], Value: pvs[1]})
} else {
err := global.ErrMmlInvalidCommandFormat
log.Error(err)
return err
}
}
} else if len(ms) == 1 {
cmd := 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
}
} else {
err := global.ErrMmlInvalidCommandFormat
log.Error(err)
return err
}
err := ParseMMLAlias(mc)
if err != nil {
err := global.ErrMmlInvalidCommandFormat
log.Error(err)
return err
}
*mmlComms = append(*mmlComms, *mc)
}
return nil
}
func ParseMMLAlias(mml *MmlCommand) error {
where := fmt.Sprintf("operation='%s' AND object='%s'", mml.Operation, mml.Object)
mc, err := dborm.XormGetMmlCommand("mml_command", where)
if err != nil {
log.Error("Failed to XormGetMmlCommand: ", err)
return err
}
if mc == nil {
err := errors.New("Not found mml map")
log.Error(err)
return err
}
log.Debug("mml command: ", mc)
aaMap := make(map[string]interface{})
naMap := make(map[string]interface{})
for _, pn := range mml.Params {
log.Trace("pn: ", pn)
for _, param := range mc.ParamJson {
log.Trace("param: ", param)
var pv string
if pn.Name == param.Name {
if param.Apostr == "true" {
pv = fmt.Sprintf("'%v'", pn.Value)
} else {
pv = fmt.Sprintf("%v", pn.Value)
}
var aa, av string
if param.Alias != "" {
aa = fmt.Sprintf("%s=%v", param.Alias, pv)
av = fmt.Sprintf("%v", pv)
switch param.Type {
case "int":
aaMap[param.Alias] = pn.Value
naMap[param.Alias] = pn.Value
default:
aaMap[param.Alias] = pv
naMap[param.Alias] = fmt.Sprintf("%v", pn.Value)
}
} else {
aa = fmt.Sprintf("%s=%v", param.Name, pv)
av = fmt.Sprintf("%v", pv)
switch param.Type {
case "int":
aaMap[param.Name] = pn.Value
naMap[param.Name] = pn.Value
default:
aaMap[param.Name] = pv
naMap[param.Name] = fmt.Sprintf("%v", pn.Value)
}
}
if param.Loc == "" || param.Loc == "true" {
mml.AaLoc = append(mml.AaLoc, aa)
mml.AaUri = append(mml.AaUri, av)
}
//mml.AaMap = append(mml.AaMap, aaMap)
mml.AaList = append(mml.AaList, aa)
break
}
}
}
mml.AaMap = aaMap
mml.NaMap = naMap
log.Trace("mml.AaMap: ", mml.AaMap)
log.Trace("mml.NaMap: ", mml.NaMap)
log.Trace("mml.AaList: ", mml.AaList)
return nil
}
func ParseMMLParams(mmlComms *[]MmlCommand) error {
for _, mml := range *mmlComms {
where := fmt.Sprintf("operation='%s' AND object='%s'", mml.Operation, mml.Object)
mc, err := dborm.XormGetMmlCommand("mml_command", where)
if err != nil {
log.Error("Failed to XormGetMmlCommand: ", err)
return err
}
if mc == nil {
err := errors.New("Not found mml map")
log.Error(err)
return err
}
log.Debug("mml command: ", mc)
for _, pn := range mml.Params {
log.Trace("pn: ", pn)
for _, param := range mc.ParamJson {
log.Trace("param: ", param)
var pv string
if pn.Name == param.Name {
if param.Apostr == "true" {
pv = fmt.Sprintf("'%v'", pn.Value)
} else {
pv = fmt.Sprintf("%v", pn.Value)
}
var aa string
aaMap := make(map[string]interface{})
if param.Alias != "" {
aa = fmt.Sprintf("%s=%v", param.Alias, pv)
switch param.Type {
case "int":
aaMap[param.Alias] = pn.Value
case "string":
aaMap[param.Alias] = pv
}
} else {
aa = fmt.Sprintf("%s=%v", param.Name, pv)
switch param.Type {
case "int":
aaMap[param.Name] = pn.Value
case "string":
aaMap[param.Name] = pv
}
}
//mml.AaMap = append(mml.AaMap, aaMap)
mml.AaList = append(mml.AaList, aa)
break
}
}
}
log.Trace("mml.AaMap: ", mml.AaMap)
log.Trace("mml.AaList: ", mml.AaList)
*mmlComms = append(*mmlComms, mml)
}
return nil
}
func parseRequestUri(httpUri string, mmlMap *dborm.MmlHttpMap, mml *MmlCommand) string {
requestURI := fmt.Sprintf("%s%s", httpUri, mmlMap.URI)
if mmlMap.ExtUri != "" && len(mml.AaUri) > 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 DeploymentLicense(mml *MmlCommand, omcMmlVar *MmlVar, outputJson *dborm.MmlOutput) *[]byte {
var output []byte
log.Debug("mml:", mml)
var srcNeType, srcNeid, dstNeType, dstNeId, value string
for _, Param := range mml.Params {
switch Param.Name {
case "srcnetype":
srcNeType = Param.Value
case "srcneid":
srcNeid = Param.Value
case "dstnetype":
dstNeType = Param.Value
case "dstneid":
dstNeId = Param.Value
case "number":
value = Param.Value
}
}
intValue, _ := strconv.Atoi(value)
log.Debugf("srcNeType:%s, srcNeid:%s dstNeType:%s dstNeId:%s intValue:%d", srcNeType, srcNeid, dstNeType, dstNeId, intValue)
a1, err := dborm.XormAdjustmentNeLicense(srcNeType, srcNeid, intValue)
if err != nil {
log.Error("Failed to Put:", err)
}
a2, err := dborm.XormAdjustmentNeLicense(dstNeType, dstNeId, -intValue)
if err != nil {
log.Error("Failed to Put:", err)
output = *ParseErrorOutput(err)
} else {
//response := &resty.Response{StatusCode: http.StatusOK}
//output = ParseOutputResponse(omcMmlVar, outputJson, response.)
str := fmt.Sprintf("RetCode = 0 operation succeeded\n\nAffected rows = %d \n\n", a1+a2)
output = []byte(str)
}
return &output
}
func AdjustmentLicense(mml *MmlCommand, omcMmlVar *MmlVar, outputJson *dborm.MmlOutput) *[]byte {
var output []byte
log.Debug("mml:", mml)
var neType, neid, number string
for _, Param := range mml.Params {
switch Param.Name {
case "netype":
neType = Param.Value
case "neid":
neid = Param.Value
case "number":
number = Param.Value
}
}
intValue, _ := strconv.Atoi(number)
log.Debugf("neType:%s, neid:%s intValue:%d", neType, neid, intValue)
affected, err := dborm.XormAdjustmentNeLicense(neType, neid, intValue)
if err != nil {
log.Error("Failed to XormAdjustmentNeLicense:", err)
output = *ParseErrorOutput(err)
} else {
str := fmt.Sprintf("RetCode = 0 operation succeeded\n\nAffected rows = %d \n\n", affected)
output = []byte(str)
}
return &output
}
func InstallLicense(mml *MmlCommand, omcMmlVar *MmlVar, outputJson *dborm.MmlOutput) *[]byte {
var output []byte
log.Debug("mml:", mml)
var neType, neid, number string
for _, Param := range mml.Params {
switch Param.Name {
case "netype":
neType = Param.Value
case "neid":
neid = Param.Value
case "number":
number = Param.Value
}
}
intValue, _ := strconv.Atoi(number)
log.Debugf("neType:%s, neid:%s intValue:%d", neType, neid, intValue)
affected, err := dborm.XormUpdateNeLicense(neType, neid, intValue)
if err != nil {
log.Error("Failed to XormUpdateNeLicense:", err)
output = *ParseErrorOutput(err)
} else {
str := fmt.Sprintf("RetCode = 0 operation succeeded\n\nAffected rows = %d \n\n", affected)
output = []byte(str)
}
return &output
}
func RunShellCommand(mml *MmlCommand, omcMmlVar *MmlVar, outputJson *dborm.MmlOutput) *[]byte {
var output []byte
log.Debug("mml:", mml)
var command string
for _, Param := range mml.Params {
switch Param.Name {
case "cmd":
command = Param.Value
default:
}
}
out, err := run.ExecCmd(command, omcMmlVar.MmlHome)
//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)
str := fmt.Sprintf("Command: %s output:\n\n%v\n", command, string(out))
//output = *ParseErrorOutput(err)
output = []byte(str)
//return &output
} else {
str := fmt.Sprintf("Command: %s output:\n\n%v\n", command, string(out))
output = []byte(str)
}
return &output
}
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{tokenConst.HEADER_KEY: omcMmlVar.Authorization}).
// 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{tokenConst.HEADER_KEY: omcMmlVar.Authorization}).
// 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":
switch inputJson.CallFunc {
case "DeploymentLicense":
output = DeploymentLicense(mml, omcMmlVar, outputJson)
return output, nil
case "AdjustmentLicense":
output = AdjustmentLicense(mml, omcMmlVar, outputJson)
return output, nil
case "InstallLicense":
output = InstallLicense(mml, omcMmlVar, outputJson)
return output, nil
case "RunShellCommand":
output = RunShellCommand(mml, omcMmlVar, outputJson)
return output, nil
default:
}
requestURI = parseRequestUri(omcMmlVar.HttpUri, mmlMap, mml)
log.Debugf("method: Put requestURI: %s", requestURI)
body := ParseInputBody(inputJson, mml)
response, err := client.R().
EnableTrace().
SetHeaders(map[string]string{tokenConst.HEADER_KEY: omcMmlVar.Authorization}).
// 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{tokenConst.HEADER_KEY: omcMmlVar.Authorization}).
// 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{tokenConst.HEADER_KEY: omcMmlVar.Authorization}).
// 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)
if v, ok := mapResults["error"]; ok {
vMap := v.(map[string]interface{})
if len(vMap) > 0 {
errCode, _ := strconv.Atoi(fmt.Sprintf("%v", vMap["errorCode"]))
errorInfo := vMap["errorInfo"]
output = []byte(fmt.Sprintf(outputJson.ErrMsg, errCode, errorInfo))
}
} else if v, ok := mapResults["code"]; ok {
errCode, _ := strconv.Atoi(fmt.Sprintf("%v", v))
errorInfo := mapResults["msg"]
output = []byte(fmt.Sprintf(outputJson.ErrMsg, errCode, errorInfo))
} else {
output = []byte(fmt.Sprintf("%v", mapResults))
}
}
}
}
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() {
}