【问题标题】:suds: incorrect marshaling of Array of Arrayssuds:数组数组的错误编组
【发布时间】:2010-08-19 08:02:57
【问题描述】:

我尝试使用 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:服务器引发错误:'Not an ARRAY reference at /usr/local/zeus/zxtmadmin/lib/perl/Zeus/ZXTM/SOAPBase.pm line 772.

架构定义的摘录:

    <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 负载均衡器只有 SOAP 接口
  • 使用 python2.6 和 suds 0.3.9
  • 我们曾经使用 ZSI 的 SOAPpy,但在 python 2.6 下使用时遇到问题

编辑:添加了 suds/SOAPpy 有效负载

【问题讨论】:

    标签: soap suds


    【解决方案1】:

    尝试后

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

    我发现 suds 4.0 提供了插件,通过 hacking 解决了这种情况,但我认为这是一个 suds 错误:

    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 这应该是一个班轮 因为我仍然对更好的替代品感兴趣,所以我保持开放状态

    【讨论】:

      【解决方案2】:

      在我看来很奇怪的是,您必须显式地构造诸如“StringArrayArray”和“StringArray”之类的类型——像 python 这样的语言足够智能的 SOAP 客户端应该能够通过反射来解决这个问题,检查您传递给的参数服务电话。我猜它们在 wsdl 中被声明为类似于“SOAP-ENC:Array”的东西——如果是这样,它们不打算成为对象。这对于错误消息“不是数组引用”也是有意义的。你试过了吗?

      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)
      

      祝你好运。

      【讨论】:

      • hm,都没有运气。确实,suds 应该能够构造复杂的类型,但是某处失败了,现在也开了一张 trac 票:fedorahosted.org/suds/ticket/340
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 2013-02-21
      • 2017-10-03
      相关资源
      最近更新 更多