如何从 WSDL 文件构建 soap 服务器?
How can I built a soap server from WSDL file?
我正在尝试从 WSDL 文件创建一个 soap 服务器。我正在使用 Python 3 和 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 的文档对此没有帮助。
感谢您的评论
这里有一些事情要做。代码很不完整,所以做了一些假设。这与 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 localhost -d @payload -H 'SOAPAction: "receiveEvents"' -H "Content-type: text/xml; charset='UTF-8'"
这样的 curl 命令
我正在尝试从 WSDL 文件创建一个 soap 服务器。我正在使用 Python 3 和 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 的文档对此没有帮助。
感谢您的评论
这里有一些事情要做。代码很不完整,所以做了一些假设。这与 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 localhost -d @payload -H 'SOAPAction: "receiveEvents"' -H "Content-type: text/xml; charset='UTF-8'"