Golang实现Cisco Callmanager AXL API查询
Golang实现Cisco Callmanager AXL API查询 我正在使用Go语言构建一个HTTP POST请求进行REST查询。我试图运行一个SQL命令,但问题可能在于请求体中丢失了查询内容。通过Postman运行时该查询可以正常工作。如果需要,我可以提供更多详细信息。希望能获得帮助来解决这个问题。
func main() {
fmt.Println("hello world")
}
不客气。很高兴能帮到你。
更多关于Golang实现Cisco Callmanager AXL API查询的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
好的。请提供更多细节,以便有人能够帮助您。
以下是代码的输出:

好的,我已经移除了额外的解引用并再次运行。这次查询成功执行并返回了我的数据。感谢您的帮助!现在是时候解析所有数据了 😊
func main() {
fmt.Println("hello world")
}
请求体中的字符串/字节并不在请求中。只有作为 http.NewRequest 最后一个参数传递的 io.Reader。你能否同时移除 body_data 中的引号转义?将 \" 替换为仅 "。
我在这里找到了这个:https://community.cisco.com/t5/unified-communications/axl-http-599-error/m-p/2294204/highlight/true#M42815。你确定你的数据库版本是11.5吗?
此外,您的body_data缺少xml标签
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns .....
也许您还应该告诉服务器请求内容是xml?通过为请求添加content-type标头。
使用curl能正常工作吗?像这个示例:https://developer.cisco.com/docs/axl/#!hello-world-with-curl/hello-world-with-curl
599是某种超时状态。https://httpstatuses.com/599
有件事我不太理解。您是否需要在body_data中转义斜杠?它们位于反引号包裹的字符串中,这种情况下应该不需要转义斜杠吧?要在论坛中发布代码,您可以将代码上传到Go playground然后在此处分享链接,或者用两行标记包裹代码。在代码前使用go,在代码后使用。
// 代码示例位置
好的,我觉得问题可能出在 body_data 变量上,但我不太确定。我是 Go 语言的新手,可能代码写得不太对。当我尝试复制粘贴代码时,论坛报错了。作为新用户,我每篇帖子只能包含 2 个链接。它可能不喜欢 http 引用,所以一直在报错。
以下是代码:

Johan,
我能再请教一个问题吗?能否帮我看看这个解析和结构体的部分?
以下是返回结果的起始部分:
<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><ns:executeSQLQueryResponse xmlns:ns="http://www.cisco.com/AXL/API/11.5"><return><row><pkid>01056b15-1b8e-748d-bd5b-a790637904fd</pkid><fkroutepartition>e0b331fb-a429-7ca2-deb3-d4629573e923</fkroutepartition>
以下是我正在调试的结构体:
XMLName xml.Name `xml:"return"`
MyRows []MyRow `xml:"row"`
}
type MyRow struct {
pkid string `xml:"ns:executeSQLQueryResponse:row:pkid"`
dnorpattern string `xml:"dnorpattern"`
}
我还在学习这个部分,所以还没有完全理解。我知道需要一个结构体来容纳行的数组结构。这个结构正确吗?
以下是我尝试进行反序列化的代码段:
data, _ := ioutil.ReadAll(response.Body)
fmt.Println(string(data))
/*
err := xml.Unmarshal([]byte(data), &MyRows)
if err != nil {
fmt.Printf("error: %v", err)
return
}
fmt.Printf("pkid:%s",MyRows.pkid)
*/
我对反序列化本身还不太理解。有什么建议吗?
谢谢, Kevin
嗨 Johan,
好的,我去掉了多余的引号,但仍然收到599错误。我已经确认11.5是正确的版本。当我打印请求时,看不到请求体的文本内容。我该如何查看它以确认格式正确?另外,虽然我是远程连接到服务器所在的环境,但我已确认可以ping通服务器,所以网络连接看起来没问题。
package main
import (
"fmt"
"io/ioutil"
"net/http"
"strings"
"crypto/tls"
"encoding/base64"
)
const myUser = "admin"
const myPass = "pass123"
func basicAuth(username, password string) string {
auth := username + ":" + password
return base64.StdEncoding.EncodeToString([]byte(auth))
}
func redirectPolicyFunc(req *http.Request, via []*http.Request) error{
req.Header.Add("Authorization","Basic " + basicAuth(myUser,myPass))
return nil
}
func main() {
fmt.Printf("Starting POST\n")
body_data := `<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.cisco.com/AXL/API/11.5">
<soapenv:Header/>
<soapenv:Body>
<ns:executeSQLQuery>
<sql>
SELECT * from numplan
</sql>
</ns:executeSQLQuery>
</soapenv:Body>
</soapenv:Envelope>`
request, httpErr := http.NewRequest("POST", "https://10.75.115.20:8443/axl/", strings.NewReader(body_data))
request.Header.Set("SOAPAction", "CUCM:DB=11.5 executeSQLQuery")
request.Header.Add("Authorization","Basic " + basicAuth(myUser,myPass))
if httpErr != nil {
fmt.Printf("The HTTP request creation failed with error %s\n", httpErr)
}
// ignore certs during data collection
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr}
response, err := client.Do(request)
if err != nil {
fmt.Printf("The HTTP request failed with error %s\n", err)
} else {
data, _ := ioutil.ReadAll(response.Body)
fmt.Println(string(data))
}
fmt.Println("\n\nRequest:")
fmt.Println(request)
}
在Go语言中实现Cisco CallManager AXL API查询时,请求体格式不正确是常见问题。AXL API使用SOAP协议,需要正确的XML格式和SOAP头部。以下是完整的示例代码:
package main
import (
"bytes"
"crypto/tls"
"fmt"
"io/ioutil"
"net/http"
"text/template"
)
const soapTemplate = `<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns="http://www.cisco.com/AXL/API/{{.Version}}">
<soapenv:Header/>
<soapenv:Body>
<ns:executeSQLQuery>
<sql>{{.SQLQuery}}</sql>
</ns:executeSQLQuery>
</soapenv:Body>
</soapenv:Envelope>`
type SOAPRequest struct {
Version string
SQLQuery string
}
func main() {
// AXL API配置
url := "https://your-cucm-server:8443/axl/"
username := "your-username"
password := "your-password"
// SQL查询语句
sqlQuery := "SELECT name, description FROM device"
// 构建SOAP请求
requestData := SOAPRequest{
Version: "12.5", // 根据你的CUCM版本调整
SQLQuery: sqlQuery,
}
// 解析模板
tmpl, err := template.New("soap").Parse(soapTemplate)
if err != nil {
fmt.Printf("模板解析错误: %v\n", err)
return
}
// 生成SOAP请求体
var soapBody bytes.Buffer
err = tmpl.Execute(&soapBody, requestData)
if err != nil {
fmt.Printf("模板执行错误: %v\n", err)
return
}
// 创建HTTP客户端(跳过证书验证,生产环境应使用有效证书)
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
}
// 创建HTTP请求
req, err := http.NewRequest("POST", url, &soapBody)
if err != nil {
fmt.Printf("请求创建错误: %v\n", err)
return
}
// 设置请求头
req.Header.Set("Content-Type", "text/xml; charset=utf-8")
req.Header.Set("SOAPAction", `CUCM:DB ver=12.5 executeSQLQuery`)
req.SetBasicAuth(username, password)
// 发送请求
resp, err := client.Do(req)
if err != nil {
fmt.Printf("请求发送错误: %v\n", err)
return
}
defer resp.Body.Close()
// 读取响应
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Printf("响应读取错误: %v\n", err)
return
}
fmt.Printf("响应状态: %d\n", resp.StatusCode)
fmt.Printf("响应内容: %s\n", string(body))
}
关键要点:
- AXL API使用SOAP协议而非纯REST,需要正确的XML格式
- 必须设置
SOAPAction头部和Content-Type: text/xml - 使用基本认证(Basic Auth)
- 根据你的CUCM版本调整API版本号(示例中使用12.5)
- SQL查询需要包含在
<ns:executeSQLQuery>标签中
如果你的查询仍然不工作,请检查:
- CUCM服务器地址和端口是否正确
- 用户名密码是否有AXL权限
- SQL语法是否符合CUCM数据库结构
- 防火墙和网络连接是否正常

