如何从WSDL文件构建soap服务器?

2024-04-18 23:53:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试从WSDL文件创建soap服务器。我使用Python3和Spyne来生成它。 此服务器需要是特定的,因为客户端已经存在。 我需要我的WSDL请求如下所示

   <soapenv:Body>
      <pus:receiveEvents>
         <!--Optional:-->
         <eventQueryResult>
            <!--Optional:-->
            <queryId>?</queryId>
            <!--Optional:-->
            <queryStatus>?</queryStatus>
            <!--Zero or more repetitions:-->
            <events>
               <!--Optional:-->
               <eid>?</eid>
               <!--Optional:-->
               <eventMessage>?</eventMessage>
               <!--Optional:-->
               <eventSeverity>?</eventSeverity>
               <!--Optional:-->
               <eventTime>?</eventTime>
               <!--Optional:-->
               <eventTypeName>?</eventTypeName>
               <!--Optional:-->
               <meterId>?</meterId>
            </events>
            <subscriptionId>?</subscriptionId>
         </eventQueryResult>
      </pus:receiveEvents>
   </soapenv:Body>

但是,这是我的WSDL请求:

   <soapenv:Body>
      <pus:receiveEvents>
         <!--Optional:-->
         <pus:eventQueryResult>
            <!--Optional:-->
            <pus:queryId>?</pus:queryId>
            <!--Optional:-->
            <pus:queryStatus>?</pus:queryStatus>
         </pus:eventQueryResult>
         <!--Optional:-->
         <pus:events>
            <!--Optional:-->
            <pus:eid>?</pus:eid>
            <!--Optional:-->
            <pus:eventMessage>?</pus:eventMessage>
            <!--Optional:-->
            <pus:eventSeverity>?</pus:eventSeverity>
            <!--Optional:-->
            <pus:eventTime>?</pus:eventTime>
            <!--Optional:-->
            <pus:eventTypeName>?</pus:eventTypeName>
            <!--Optional:-->
            <pus:meterId>?</pus:meterId>
         </pus:events>
         <pus:subscriptionId>
            <!--Optional:-->
            <pus:subscriptionId>?</pus:subscriptionId>
         </pus:subscriptionId>
      </pus:receiveEvents>
   </soapenv:Body>

这是我写的代码

    class eventQueryResult(ComplexModel):
    __namespace__ = 'http://pushevent.nbapi.cgms.cisco.com/'

    queryId = String
    queryStatus = String

class events(ComplexModel):
    __namespace__ = 'http://pushevent.nbapi.cgms.cisco.com/'   

    eid = String
    eventMessage = String 
    eventSeverity = String
    eventTime = Long
    eventTypeName = String
    meterId = String

class subscriptionId(ComplexModel):
    __namespace__ = 'http://pushevent.nbapi.cgms.cisco.com/'

    subscriptionId = Long

class EventPushService(ServiceBase):
    __tns__ = 'http://pushevent.nbapi.cgms.cisco.com/'
    __wsdl__ = 'http://schemas.xmlsoap.org/wsdl/'

    @rpc(eventQueryResult.customize(min_occurs=0), events.customize(min_occurs=0), subscriptionId.customize(min_occurs=1,nillable = True), _returns=ResponseData)
    def receiveEvents(ctx, eventQueryResult, events, subscriptionId):
        eid = events.eid

        return print(eid)

我需要eventQueryResult包含事件,但我不知道如何。 Spyne的文档对我没有帮助

谢谢你的评论


Tags: stringeventsoptionaleidmeterideventtimeeventmessagesubscriptionid
1条回答
网友
1楼 · 发布于 2024-04-18 23:53:04

这里有几件事要做。代码相当不完整,因此进行了一些假设。这与spyne示例应用程序非常接近,与您发布的代码片段相匹配

创建类以对数据建模时,希望eventQueryResult包含事件。数组是文档here。该代码看起来更像:

class events(ComplexModel):
    eid = String
    eventMessage = String
    eventSeverity = String
    eventTime = Long
    eventTypeName = String
    meterId = String

class eventQueryResult(ComplexModel):
    queryId = String
    queryStatus = String
    events = Array(events)

当您指定RPC时,函数的名称是soapAction,第一个是客户端将发送给您的对象的模型。这里,将整个有效负载建模为一个对象。Bare意味着有效负载不会被包装在一个数组中。根据客户的不同,这可能需要改变

    @rpc(eventQueryResult, _body_style='bare', _returns=someResponse)

someResponse是要发送回客户端的响应的模型。我真的不知道你们想要什么,一系列被接受的活动怎么样?整个脚本如下所示:

import logging
from spyne import Application, rpc, ServiceBase, \
    String, Long
from spyne.protocol.soap import Soap11
from spyne.server.wsgi import WsgiApplication
from spyne.model.complex import ComplexModel, Array

logging.basicConfig(level="WARNING")

class event(ComplexModel):
    eid = String
    eventMessage = String
    eventSeverity = String
    eventTime = Long
    eventTypeName = String
    meterId = String

class eventQueryResult(ComplexModel):
    queryId = String
    queryStatus = String
    events = Array(event)

class someResponse(ComplexModel):
    eventIds = Array(String)

class EventPushService(ServiceBase):
    @rpc(eventQueryResult, _body_style='bare', _returns=someResponse)
    def receiveEvents(ctx, req):
        print(req)

        return someResponse(eventIds = [ i.eid for i in req.events ] )

application = Application([EventPushService],
    tns='http://pushevent.nbapi.cgms.cisco.com/',
    in_protocol=Soap11(validator='lxml'),
    out_protocol=Soap11()
)

if __name__ == '__main__':
    # You can use any Wsgi server. Here, we chose
    # Python's built-in wsgi server but you're not
    # supposed to use it in production.

    from wsgiref.simple_server import make_server
    wsgi_app = WsgiApplication(application)
    server = make_server('0.0.0.0', 80, wsgi_app)
    server.serve_forever()

我用一个看起来像

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://pushevent.nbapi.cgms.cisco.com/">
  <soapenv:Header/>
  <soapenv:Body>
    <tns:receiveEvents>
      <tns:queryId>100</tns:queryId>
      <tns:queryStatus>Success</tns:queryStatus>
      <tns:events>
        <tns:event>
          <tns:eid>someId</tns:eid>
          <tns:eventMessage>someEventMessage</tns:eventMessage>
          <tns:eventSeverity>someEventSeverity</tns:eventSeverity>
          <tns:eventTime>1614974343</tns:eventTime>
          <tns:eventTypeName>eventType</tns:eventTypeName>
          <tns:meterId>meterStayOnTheMeter</tns:meterId>
        </tns:event>
        <tns:event>
          <tns:eid>someId2</tns:eid>
          <tns:eventMessage>someEventMessage2</tns:eventMessage>
          <tns:eventSeverity>someEventSeverity2</tns:eventSeverity>
          <tns:eventTime>1614974344</tns:eventTime>
          <tns:eventTypeName>eventType2</tns:eventTypeName>
          <tns:meterId>meterStayOnTheMeter2</tns:meterId>
        </tns:event>
      </tns:events>
    </tns:receiveEvents>
  </soapenv:Body>
</soapenv:Envelope>

我使用了一个curl命令,比如curl localhost -d @payload -H 'SOAPAction: "receiveEvents"' -H "Content-type: text/xml; charset='UTF-8'"

相关问题 更多 >