package mml import ( "encoding/json" "fmt" "io" "net" "net/http" "regexp" "strings" "time" "be.ems/lib/dborm" "be.ems/lib/global" "be.ems/lib/log" "be.ems/lib/mmlp" "be.ems/lib/services" "be.ems/restagent/config" tokenConst "be.ems/src/framework/constants/token" "github.com/gorilla/mux" ) // const ( // //经过测试,linux下,延时需要大于100ms // TIME_DELAY_AFTER_WRITE = 200 // TIME_DEAD_LINE = 10 // ) type Response struct { Data []string `json:"data"` } type MMLRequest struct { MML []string `json:"mml"` } var ( // MML interface UriMML = config.DefaultUriPrefix + "/operationManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/mml" UriMML2 = config.DefaultUriPrefix + "/operationManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/mml2" UriMMLDiscard = config.DefaultUriPrefix + "/opeartionManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/mml" UriNeOmMml = config.DefaultUriPrefix + "/omManagement/{apiVersion}/mml/{netype}/{neid}" UriOmMmlExt = config.DefaultUriPrefix + "/{managedType}/{apiVersion}/elementType/OMC/objectType/mml" UriOmMmlInt = config.DefaultUriPrefix + "/omManagement/{apiVersion}/mml/{neType}/{neId}" CustomUriMML = config.UriPrefix + "/operationManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/mml" CustomUriMML2 = config.UriPrefix + "/operationManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/mml2" CustomUriNeOmMml = config.UriPrefix + "/omManagement/{apiVersion}/mml/{netype}/{neid}" CustomUriOmMmlExt = config.UriPrefix + "/opeartionManagement/{apiVersion}/elementType/OMC/objectType/mml" CustomUriOmMmlInt = config.UriPrefix + "/omManagement/{apiVersion}/mml/{neType}/{neId}" ) var TIME_DELAY_AFTER_WRITE time.Duration = 200 var TIME_DEAD_LINE time.Duration = 10 func init() { if config.GetYamlConfig().MML.Sleep != 0 { TIME_DELAY_AFTER_WRITE = time.Duration(config.GetYamlConfig().MML.Sleep) } if config.GetYamlConfig().MML.DeadLine != 0 { TIME_DEAD_LINE = time.Duration(config.GetYamlConfig().MML.DeadLine) } } func PostMML2ToNF(w http.ResponseWriter, r *http.Request) { log.Info("PostMML2ToNF processing... ") vars := mux.Vars(r) neType := vars["elementTypeValue"] neInfo := new(dborm.NeInfo) params := r.URL.Query() neId := params["ne_id"] neInfo, err := dborm.XormGetNeInfo(neType, neId[0]) if err != nil { log.Error("Failed to dborm.XormGetNeInfo:", err) services.ResponseInternalServerError500ProcessError(w, err) return } var buf [20 * 1024]byte //buf := make([]byte, 0) var n int var mmlResult []string port2 := 5002 if config.GetYamlConfig().MML.Port2 != 0 { port2 = config.GetYamlConfig().MML.Port2 } if neInfo != nil { hostMML := fmt.Sprintf("%s:%d", neInfo.Ip, port2) 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 } defer conn.Close() // localAddr := conn.LocalAddr() // remoteAddr := conn.RemoteAddr() // if localAddr == nil || remoteAddr == nil { // errMsg := fmt.Sprintf("connect invalid: localAddr=%v, remoteAddr=%v", localAddr, remoteAddr) // log.Error(errMsg) // mmlResult = append(mmlResult, errMsg) // response := Response{mmlResult} // services.ResponseWithJson(w, http.StatusOK, response) // return // } conn.SetDeadline(time.Now().Add(TIME_DEAD_LINE * time.Second)) loginStr := fmt.Sprintf("%s\n%s\n", config.GetYamlConfig().MML.User, config.GetYamlConfig().MML.Password) _, err = conn.Write([]byte(loginStr)) if err != nil { log.Error("Failed to write:", err) mmlResult = append(mmlResult, err.Error()) response := Response{mmlResult} services.ResponseWithJson(w, http.StatusOK, response) return } time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE) n, err = conn.Read(buf[0:]) if err != nil { log.Error("Failed to read:", err) mmlResult = append(mmlResult, err.Error()) response := Response{mmlResult} services.ResponseWithJson(w, http.StatusOK, response) return } log.Trace(string(buf[0:n])) body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen)) if err != nil { log.Error("Failed to ReadAll:", err) services.ResponseNotFound404UriNotExist(w, r) return } log.Trace("Body:", string(body)) mmlRequest := new(MMLRequest) _ = json.Unmarshal(body, mmlRequest) for _, mml := range mmlRequest.MML { mmlCommand := fmt.Sprintf("%s\n", mml) _, err = conn.Write([]byte(mmlCommand)) if err != nil { log.Error("Failed to write:", err) mmlResult = append(mmlResult, err.Error()) // response := Response{mmlResult} // services.ResponseWithJson(w, http.StatusOK, response) // return continue } time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE) n, err = conn.Read(buf[0:]) if err != nil { log.Error("Failed to read:", err) mmlResult = append(mmlResult, err.Error()) // response := Response{mmlResult} // services.ResponseWithJson(w, http.StatusOK, response) // return continue } log.Trace(string(buf[0 : n-len(neType)-2])) re1 := regexp.MustCompile(`\x1B\[[0-9;]*[a-zA-Z]`) // 匹配包含␛的控制字符 //re2 := regexp.MustCompile(`\x00`) // 匹配空字符 re2 := regexp.MustCompile(`[\x00-\x08\x0B\x0C\x0E-\x1F\x7F\x1B]`) // 匹配空字符和包含␛的控制字符 //re := regexp.MustCompile(`[\x00-\x1F\x7F]`) result := re1.ReplaceAllString(string(buf[0:n-len(neType)-2]), "") result = re2.ReplaceAllString(result, "") mmlResult = append(mmlResult, result) } } response := Response{mmlResult} services.ResponseWithJson(w, http.StatusOK, response) } func PostMMLToNF(w http.ResponseWriter, r *http.Request) { log.Debug("PostMMLToNF processing... ") // token, err := services.CheckExtValidRequest(w, r) // if err != nil { // log.Error("Request error:", err) // return // } // 经过测试,linux下,延时需要大于100ms // var TIME_DELAY_AFTER_WRITE time.Duration = 200 // var TIME_DEAD_LINE time.Duration = 10 // if config.GetYamlConfig().MML.Sleep != 0 { // TIME_DELAY_AFTER_WRITE = time.Duration(config.GetYamlConfig().MML.Sleep) // } // if config.GetYamlConfig().MML.DeadLine != 0 { // TIME_DEAD_LINE = time.Duration(config.GetYamlConfig().MML.DeadLine) // } pack := "mml" vars := mux.Vars(r) module := vars["managedType"] 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) log.Debugf("method:%s, managementType:%s dbname:%s, tbname:%s pack:%s", r.Method, module, neType, neId[0], pack) var buf [20 * 1024]byte //buf := make([]byte, 0) var n int var mmlResult []string // exist, err := services.CheckUserPermission(token, strings.ToLower(r.Method), module, neType, neId[0], pack) // if err != nil { // log.Error("Failed to get permission:", err) // errMsg := fmt.Sprintf("RetCode = -1 operation failed: do not have the operation permissions") // log.Error(errMsg) // mmlResult = append(mmlResult, errMsg) // response := Response{mmlResult} // services.ResponseWithJson(w, http.StatusOK, response) // //services.ResponseForbidden403NotPermission(w) // return // } // if !exist { // log.Error("Not permission!") // errMsg := fmt.Sprintf("RetCode = -1 operation failed: do not have the operation permissions") // log.Error(errMsg) // mmlResult = append(mmlResult, errMsg) // response := Response{mmlResult} // services.ResponseWithJson(w, http.StatusOK, response) // //services.ResponseForbidden403NotPermission(w) // return // } if strings.ToLower(neType) == "omc" { PostMMLToOMC(w, r) 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 } if neInfo != nil { switch strings.ToLower(neType) { case "xxx": 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.Trace("Body:", string(body)) mmlRequest := new(MMLRequest) _ = json.Unmarshal(body, mmlRequest) // n, err = conn.Read(buf[0:]) // if err != nil { // log.Error("Failed to read:", err) // mmlResult = append(mmlResult, err.Error()) // response := Response{mmlResult} // services.ResponseWithJson(w, http.StatusOK, response) // return // } // log.Debug(string(buf[0:n])) // 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 // } // defer conn.Close() // conn.SetDeadline(time.Now().Add(10 * time.Second)) // loginStr := fmt.Sprintf("%s\n%s\n", config.GetYamlConfig().MML.User, config.GetYamlConfig().MML.Password) // _, err = conn.Write([]byte(loginStr)) // if err != nil { // log.Error("Failed to write:", err) // mmlResult = append(mmlResult, err.Error()) // response := Response{mmlResult} // services.ResponseWithJson(w, http.StatusOK, response) // return // } // time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE) // n, err = conn.Write([]byte(config.GetYamlConfig().MML.User + "\n")) // if err != nil { // log.Error("Failed to write:", err) // mmlResult = append(mmlResult, err.Error()) // response := Response{mmlResult} // services.ResponseWithJson(w, http.StatusOK, response) // return // } // log.Debug(string(buf[0:n])) // time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE) // n, err = conn.Read(buf[0:]) // if err != nil { // log.Error("Failed to read:", err) // mmlResult = append(mmlResult, err.Error()) // response := Response{mmlResult} // services.ResponseWithJson(w, http.StatusOK, response) // return // } // log.Debug(string(buf[0:n])) // n, err = conn.Write([]byte(config.GetYamlConfig().MML.Password + "\n")) // if err != nil { // log.Error("Failed to write:", err) // mmlResult = append(mmlResult, err.Error()) // response := Response{mmlResult} // services.ResponseWithJson(w, http.StatusOK, response) // return // } // log.Debug(string(buf[0:n])) // time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE) // n, err = conn.Read(buf[0:]) // if err != nil { // log.Error("Failed to read:", err) // mmlResult = append(mmlResult, err.Error()) // response := Response{mmlResult} // services.ResponseWithJson(w, http.StatusOK, response) // return // } // log.Debug(string(buf[0:n])) for _, mml := range mmlRequest.MML { 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 } defer conn.Close() conn.SetDeadline(time.Now().Add(TIME_DEAD_LINE * time.Second)) loginStr := fmt.Sprintf("%s\n%s\n", config.GetYamlConfig().MML.User, config.GetYamlConfig().MML.Password) _, err = conn.Write([]byte(loginStr)) if err != nil { log.Error("Failed to write:", err) mmlResult = append(mmlResult, err.Error()) //response := Response{mmlResult} //services.ResponseWithJson(w, http.StatusOK, response) //return continue } time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE) mmlCommand := fmt.Sprintf("%s\n", mml) log.Debug("mml command:", mmlCommand) _, err = conn.Write([]byte(mmlCommand)) if err != nil { log.Error("Failed to write:", err) mmlResult = append(mmlResult, err.Error()) //response := Response{mmlResult} //services.ResponseWithJson(w, http.StatusOK, response) //return continue } time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE) n, err = conn.Read(buf[0:]) if err != nil { log.Error("Failed to read:", err) mmlResult = append(mmlResult, err.Error()) //response := Response{mmlResult} //services.ResponseWithJson(w, http.StatusOK, response) //return continue } log.Trace(string(buf[0 : n-len(neType)-2])) re1 := regexp.MustCompile(`\x1B\[[0-9;]*[a-zA-Z]`) // 匹配包含␛的控制字符 //re2 := regexp.MustCompile(`\x00`) // 匹配空字符 re2 := regexp.MustCompile(`[\x00-\x08\x0B\x0C\x0E-\x1F\x7F\x1B]`) // 匹配空字符和包含␛的控制字符 //re := regexp.MustCompile(`[\x00-\x1F\x7F]`) // upf telnet buffer只能读取一次,需要去掉前面的多余字符 //result := re1.ReplaceAllString(string(buf[config.GetYamlConfig().MML.UpfHeaderLength:n-len(neType)-2]), "") result := re1.ReplaceAllString(string(buf[0:n-len(neType)-2]), "") result = re2.ReplaceAllString(result, "") mmlResult = append(mmlResult, result) conn.Close() //mmlResult = append(mmlResult, string(buf[0:n-len(neType)-2])) // can't read buffer from upf telnet server, so return ok always // mmlResult = append(mmlResult, "COMMAND OK\n") } case "ims": 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 } defer conn.Close() // localAddr := conn.LocalAddr() // remoteAddr := conn.RemoteAddr() // if localAddr == nil || remoteAddr == nil { // errMsg := fmt.Sprintf("connect invalid: localAddr=%v, remoteAddr=%v", localAddr, remoteAddr) // log.Error(errMsg) // mmlResult = append(mmlResult, errMsg) // response := Response{mmlResult} // services.ResponseWithJson(w, http.StatusOK, response) // return // } conn.SetDeadline(time.Now().Add(TIME_DEAD_LINE * time.Second)) _, err = conn.Write([]byte(config.GetYamlConfig().MML.User + "\r\n")) if err != nil { log.Error("Failed to write:", err) mmlResult = append(mmlResult, err.Error()) response := Response{mmlResult} services.ResponseWithJson(w, http.StatusOK, response) return } time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE) n, err = conn.Read(buf[0:]) if err != nil { log.Error("Failed to read:", err) mmlResult = append(mmlResult, err.Error()) response := Response{mmlResult} services.ResponseWithJson(w, http.StatusOK, response) return } log.Trace(string(buf[0:n])) _, err = conn.Write([]byte(config.GetYamlConfig().MML.Password + "\r\n")) if err != nil { log.Error("Failed to write:", err) mmlResult = append(mmlResult, err.Error()) response := Response{mmlResult} services.ResponseWithJson(w, http.StatusOK, response) return } time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE) // loginStr := fmt.Sprintf("%s\r\n%s\r\n", config.GetYamlConfig().MML.User, config.GetYamlConfig().MML.Password) // _, err = conn.Write([]byte(loginStr)) // if err != nil { // log.Error("Failed to write:", err) // mmlResult = append(mmlResult, err.Error()) // response := Response{mmlResult} // services.ResponseWithJson(w, http.StatusOK, response) // return // } // time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE) n, err = conn.Read(buf[0:]) if err != nil { log.Error("Failed to read:", err) mmlResult = append(mmlResult, err.Error()) response := Response{mmlResult} services.ResponseWithJson(w, http.StatusOK, response) return } log.Trace(string(buf[0 : n-len(neType)-2])) 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.Trace("Body:", string(body)) mmlRequest := new(MMLRequest) _ = json.Unmarshal(body, mmlRequest) for _, mml := range mmlRequest.MML { mmlCommand := fmt.Sprintf("%s\r\n", mml) log.Debug("mml command:", mmlCommand) _, err = conn.Write([]byte(mmlCommand)) if err != nil { log.Error("Failed to write:", err) mmlResult = append(mmlResult, err.Error()) // response := Response{mmlResult} // services.ResponseWithJson(w, http.StatusOK, response) // return continue } time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE) n, err = conn.Read(buf[0:]) if err != nil { log.Error("Failed to read:", err) mmlResult = append(mmlResult, err.Error()) // response := Response{mmlResult} // services.ResponseWithJson(w, http.StatusOK, response) // return continue } log.Trace(string(buf[0 : n-len(neType)-2])) re1 := regexp.MustCompile(`\x1B\[[0-9;]*[a-zA-Z]`) // 匹配包含␛的控制字符 //re2 := regexp.MustCompile(`\x00`) // 匹配空字符 re2 := regexp.MustCompile(`[\x00-\x08\x0B\x0C\x0E-\x1F\x7F\x1B]`) // 匹配空字符和包含␛的控制字符 //re := regexp.MustCompile(`[\x00-\x1F\x7F]`) result := re1.ReplaceAllString(string(buf[0:n-len(neType)-2]), "") result = re2.ReplaceAllString(result, "") mmlResult = append(mmlResult, result) } default: 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 } defer conn.Close() // localAddr := conn.LocalAddr() // remoteAddr := conn.RemoteAddr() // if localAddr == nil || remoteAddr == nil { // errMsg := fmt.Sprintf("connect invalid: localAddr=%v, remoteAddr=%v", localAddr, remoteAddr) // log.Error(errMsg) // mmlResult = append(mmlResult, errMsg) // response := Response{mmlResult} // services.ResponseWithJson(w, http.StatusOK, response) // return // } conn.SetDeadline(time.Now().Add(TIME_DEAD_LINE * time.Second)) loginStr := fmt.Sprintf("%s\n%s\n", config.GetYamlConfig().MML.User, config.GetYamlConfig().MML.Password) _, err = conn.Write([]byte(loginStr)) if err != nil { log.Error("Failed to write:", err) mmlResult = append(mmlResult, err.Error()) response := Response{mmlResult} services.ResponseWithJson(w, http.StatusOK, response) return } time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE) n, err = conn.Read(buf[0:]) if err != nil { log.Error("Failed to read:", err) mmlResult = append(mmlResult, err.Error()) response := Response{mmlResult} services.ResponseWithJson(w, http.StatusOK, response) return } log.Trace(string(buf[0:n])) body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen)) if err != nil { log.Error("Failed to ReadAll:", err) services.ResponseNotFound404UriNotExist(w, r) return } log.Trace("Body:", string(body)) mmlRequest := new(MMLRequest) _ = json.Unmarshal(body, mmlRequest) for _, mml := range mmlRequest.MML { mmlCommand := fmt.Sprintf("%s\n", mml) _, err = conn.Write([]byte(mmlCommand)) if err != nil { log.Error("Failed to write:", err) mmlResult = append(mmlResult, err.Error()) // response := Response{mmlResult} // services.ResponseWithJson(w, http.StatusOK, response) // return continue } time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE) n, err = conn.Read(buf[0:]) if err != nil { log.Error("Failed to read:", err) mmlResult = append(mmlResult, err.Error()) // response := Response{mmlResult} // services.ResponseWithJson(w, http.StatusOK, response) // return continue } log.Trace(string(buf[0 : n-len(neType)-2])) re1 := regexp.MustCompile(`\x1B\[[0-9;]*[a-zA-Z]`) // 匹配包含␛的控制字符 //re2 := regexp.MustCompile(`\x00`) // 匹配空字符 re2 := regexp.MustCompile(`[\x00-\x08\x0B\x0C\x0E-\x1F\x7F\x1B]`) // 匹配空字符和包含␛的控制字符 //re := regexp.MustCompile(`[\x00-\x1F\x7F]`) result := re1.ReplaceAllString(string(buf[0:n-len(neType)-2]), "") result = re2.ReplaceAllString(result, "") mmlResult = append(mmlResult, result) } } } 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.Trace("Body:", string(body)) hostUri := fmt.Sprintf("http://%s:%s", neInfo.Ip, neInfo.Port) omcMmlVar := &mmlp.MmlVar{ Version: global.Version, Output: mmlp.DefaultFormatType, MmlHome: config.GetYamlConfig().MML.MmlHome, Limit: 50, User: "", SessionToken: "", // 旧token Authorization: r.Header.Get(tokenConst.HEADER_KEY), // 请求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) }