代码之家  ›  专栏  ›  技术社区  ›  hansaplast

SUDS:数组的排列不正确

  •  1
  • hansaplast  · 技术社区  · 15 年前

    我试着用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行的数组引用。”

    模式定义的提取:

        <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']) 它在肥皂剧中起作用,但现在在肥皂剧中我得到:

    suds.webfault:服务器引发错误:“值不是数组”

    肥皂水和肥皂水的比较:

    肥皂水 (作品):

    <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>
    

    肥皂水 (不起作用):

    <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有效负载

    2 回复  |  直到 15 年前
        1
  •  1
  •   hansaplast    15 年前

    试过之后

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

    我发现suds 4.0提供了插件,通过黑客解决了这个问题,但尽管如此,我还是认为这是一个suds bug:

    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)
    

    我期待这个问题得到解决,我认为这应该是一条单行线 因为我仍然对更好的选择感兴趣,所以我要把这件事公开。

        2
  •  0
  •   HarryF    15 年前

    我觉得奇怪的是,您必须显式地构造类似于“StringArrayRay”和“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)
    

    祝你好运。