suds:数组数组的错误编组

时间:2010-08-19 08:02:57

标签: soap suds

我尝试用python:

与负载均衡器(Zeus ZXTM)交谈
a = client.factory.create('StringArrayArray')
b = client.factory.create('StringArray')
b.value = ['node01:80',]
a.value = [b,]
client.service.addDrainingNodes(['my pool'], a)

但是我收到以下错误:

  

suds.WebFault:服务器引发的错误:'不是/usr/local/zeus/zxtmadmin/lib/perl/Zeus/ZXTM/SOAPBase.pm第772行的ARRAY引用。

架构定义的摘录:     

    <types>
        <xsd:schema targetNamespace='http://soap.zeus.com/zxtm/1.0/'
            xmlns='http://www.w3.org/2001/XMLSchema'
            xmlns:SOAP-ENC='http://schemas.xmlsoap.org/soap/encoding/'
            xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'>

            <xsd:complexType name="StringArray">
                <xsd:complexContent>
                    <xsd:restriction base='SOAP-ENC:Array'>
                        <xsd:attribute ref='SOAP-ENC:arrayType' wsdl:arrayType='xsd:string[]'/>
                    </xsd:restriction>
                </xsd:complexContent>
            </xsd:complexType>

            <xsd:complexType name="StringArrayArray">
                <xsd:complexContent>
                    <xsd:restriction base='SOAP-ENC:Array'>
                        <xsd:attribute ref='SOAP-ENC:arrayType' wsdl:arrayType='zeusns:StringArray[]'/>
                    </xsd:restriction>
                </xsd:complexContent>
            </xsd:complexType>
        </xsd:schema>
    </types>

    <message name="addDrainingNodesRequest">
        <part name="names" type="zeusns:StringArray" />
        <part name="values" type="zeusns:StringArrayArray" />
    </message>

    <message name="addDrainingNodesResponse"></message>

    <portType name="PoolPort">

        <operation name="addDrainingNodes">
            <documentation>
                Add nodes to the lists of draining nodes, for each of the named pools.
            </documentation>

            <input message="zeusns:addDrainingNodesRequest"/>
            <output message="zeusns:addDrainingNodesResponse"/>
        </operation>
    </portType>
</definitions>

我也尝试过这样:     client.service.addDrainingNodes(['my pool'],[['node01:80']]) 在SOAPpy工作,但现在在泡沫中我得到:

  

suds.WebFault:服务器引发的错误:'值不是数组'

比较SOAPpy和suds发送的内容:

SOAPpy (正常):

<ns1:addDrainingNodes xmlns:ns1="http://soap.zeus.com/zxtm/1.0/Pool/" SOAP-ENC:root="1">
    <v1 SOAP-ENC:arrayType="xsd:string[1]" xsi:type="SOAP-ENC:Array">
        <item>my pool</item>
    </v1>
    <v2 SOAP-ENC:arrayType="xsd:list[1]" xsi:type="SOAP-ENC:Array">
        <item SOAP-ENC:arrayType="xsd:string[1]" xsi:type="SOAP-ENC:Array">
            <item>node01:80</item>
        </item>
    </v2>
</ns1:addDrainingNodes>

suds (不起作用):

<ns4:addDrainingNodes>
    <names xsi:type="ns0:StringArray" ns3:arrayType="ns2:string[1]">
        <item xsi:type="ns2:string">my pool</item>
    </names>
    <values xsi:type="ns0:StringArrayArray" ns3:arrayType="ns0:StringArray[1]">
        <item xsi:type="ns2:string">node01:80</item>
    </values>
</ns4:addDrainingNodes>

上下文:

  • 我是泡沫和肥皂的新手
  • 只有ZXTM loadbalancer的SOAP接口
  • 使用python2.6和suds 0.3.9
  • 我们曾经使用过ZSI的SOAPpy,但在python 2.6
  • 下使用它有问题

修改:添加了suds / SOAPpy有效负载

2 个答案:

答案 0 :(得分:1)

尝试后

  • 这个函数的不同参数
  • 来自ZSI的
  • wsdl2py

我发现suds 4.0提供插件,通过黑客攻击解决了这个问题,但是我认为这是一个肥皂泡虫:

class FixArrayPlugin(Plugin):
    def sending(self, context):
        command = context.envelope.getChild('Body').getChildren()[0].name
        if command == 'addDrainingNodes':
            context.envelope.addPrefix('xsd', 'http://www.w3.org/1999/XMLSchema')
            values = context.envelope.getChild('Body').getChild('addDrainingNodes').getChild('values')
            values.set('SOAP-ENC:arrayType', 'xsd:list[1]')
            values.set('xsi:type', 'SOAP-ENC:Array')
            item = values[0]
            item.set('SOAP-ENC:arrayType', 'xsd:list[1]')
            item.set('xsi:type', 'SOAP-ENC:Array')

client = Client(wsdl, location=location, plugins=[FixArrayPlugin()])
a = client.factory.create('StringArrayArray')
b = client.factory.create('StringArray')
b.item = ['node01:80']
a.item = [b,]
client.service.addDrainingNodes(['my pool'], a)

我期待着这个问题得到解决,IMO应该是一个单行 我正在离开这个,因为我仍然对更好的替代品感兴趣

答案 1 :(得分:0)

对我来说很奇怪的是你必须显式构造像'StringArrayArray'和'StringArray'这样的类型 - 像python这样的语言中足够聪明的SOAP客户端应该能够通过反射来解决这个问题,检查你传递给的参数服务电话。我猜它们在wsdl中被声明为类似“SOAP-ENC:Array”的东西 - 如果是这样的话它们并不打算成为对象。这也适用于错误消息“Not a ARRAY reference”。你有没有试过;

a = [ ['node01:80',], ]
client.service.addDrainingNodes(['my pool'], a)

或者也许失败了......

a = client.factory.create('StringArrayArray')
b = ['node01:80',]
a.value = [ b, ]
client.service.addDrainingNodes(['my pool'], a)
祝你好运。