如何将 SOAP 项目从 Mule 3.9 迁移到 4.5?

问题描述 投票:0回答:1

我们正在从 Mule 3.9.0 升级到 Mule 4.5.0(社区版)。我们有一些 Mule 连接器,它们充当我们的应用程序和 Internet 上使用 SOAP 的第三方之间的桥梁。这是我们正在尝试做的事情的一个例子:

<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081" basePath="/base" doc:name="HTTP Listener Configuration" />
<http:request-config name="HTTP_Request_Configuration" host="www.dneonline.com" port="80" doc:name="HTTP Request Configuration" />
<flow name="bridgeFlow">
    <http:listener config-ref="HTTP_Listener_Configuration" path="/app" allowedMethods="POST, GET" doc:name="Mule Listener" />
    <cxf:proxy-service namespace="http://tempuri.org/" service="Calculator" payload="envelope" wsdlLocation="bridge.wsdl" soapVersion="1.2" doc:name="CXF" />
    <http:request config-ref="HTTP_Request_Configuration" path="/calculator.asmx" method="POST" doc:name="Outside Requester" />
</flow>

在此示例中,http:listener 组件收到 SOAP 请求以添加 2 个数字。 http:request 组件将 SOAP 信封转发到外部服务,该服务对 2 个数字进行简单的数学计算。 cxf:proxy-service 允许 Mule 将其端点公开为基于 SOAP 的 Web 服务。它引用的bridge.wsdl文件是来自http://www.dneonline.com/calculator.asmx?wsdl的wsdl的副本,删除了我们不关心的内容。

在 Mule 4 中,cxf 组件已被弃用,因此没有简单的迁移路径。我一直在尝试使用 apikit-soap:router 组件来替换 cxf:proxy-service 和 wsc:consume 组件来替换 http:request。这是我到目前为止所拥有的:

<http:listener-config name="api-httpListenerConfig" basePath="/base">
    <http:listener-connection host="0.0.0.0" port="8081" />
</http:listener-config>
<apikit-soap:config name="soapkit-config" wsdlLocation="bridge.wsdl" service="Calculator" port="CalculatorSoap12" />
<wsc:config name="Web_Service_Consumer_Config">
    <wsc:connection soapVersion="SOAP12" wsdlLocation="http://www.dneonline.com/calculator.asmx?wsdl" service="Calculator" port="CalculatorSoap12" address="http://www.dneonline.com/calculator.asmx" />
</wsc:config>
<flow name="api-main">
    <http:listener config-ref="api-httpListenerConfig" path="/app" allowedMethods="POST, GET" doc:name="Mule Listener" />
    <apikit-soap:router config-ref="soapkit-config">
        <apikit-soap:attributes><![CDATA[#[%dw 2.0
            output application/java
            ---
            {
                headers: attributes.headers,
                method: attributes.method,
                queryString: attributes.queryString
            }]]]></apikit-soap:attributes>
    </apikit-soap:router>
</flow>
<flow name="Add:\soapkit-config">
    <ee:transform doc:name="Transform Message">
        <ee:message>
            <ee:set-payload><![CDATA[%dw 2.0
                output application/xml
                ns ns0 http://tempuri.org/
                ---
                {
                    ns0#Add: {
                        ns0#intA: payload.body.ns0#Add.ns0#intA default 0,
                        ns0#intB: payload.body.ns0#Add.ns0#intB default 0
                    }
                }]]></ee:set-payload>
        </ee:message>
    </ee:transform>
    <wsc:consume config-ref="Web_Service_Consumer_Config" operation="Add" doc:name="Outside Consumer" />
 </flow>

如果我在 wsc:consume 组件后面放置一个记录器,我可以看到它确实有效。外部服务被正确调用并返回正确的答案。问题是 wsc:consume 组件在有效负载中返回以下内容:

{
    body:<AddResponse xmlns="http://tempuri.org/"><AddResult>579</AddResult></AddResponse>,
    headers: [],
    attachments: []
}

...但我需要的是:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
        <AddResponse xmlns="http://tempuri.org/">
            <AddResult>579</AddResult>
        </AddResponse>
    </soap:Body>
</soap:Envelope>

另一个问题是需要 ee:transform 将 apikit-soap:router 的响应映射到 wsc:consume 组件识别的请求格式。在我们的一些 SOAP 服务中,请求正文包含数百个元素。绘制所有这些地图充其量也是乏味的。如果我能让 apikit-soap:router 组件返回 XML SOAP Envelope,我想我可以用 http:request 组件替换 wsc:consume,并且不需要任何转换。

有什么建议吗?

soap mule upgrade
1个回答
0
投票

Web 服务使用者的设计使用户不必处理 SOAP 的复杂性。它故意不提供对 SOAP 详细信息和内部结构(如 CXF)的访问。如果您需要这种级别的控制,则需要使用您选择的某些 Java SOAP 框架在 Java 中实现您自己的 Web 服务调用,并使用 Java 模块来调用它。或者,您可以使用 Mule SDK 针对您的特定用例创建自己的自定义连接器。

话虽如此,如果您只需要向消息添加基本的 SOAP 信封,则可以使用 DataWeave 转换来完成此操作:

%dw 2.0
output application/xml
ns soap http://www.w3.org/2003/05/soap-envelope
---
soap#Envelop: {
    soap#Body: read(payload.body, "application/xml")
}

我假设

payload.body
是一个包含 XML 的字符串。如果它是一个对象,则删除
read()
函数。

输出:

<?xml version='1.0' encoding='UTF-8'?>
<soap:Envelop xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
  <soap:Body>
    <AddResponse xmlns="http://tempuri.org/">
      <AddResult>579</AddResult>
    </AddResponse>
  </soap:Body>
</soap:Envelop>

如果有效负载使用其他命名空间,您可以添加它们。

© www.soinside.com 2019 - 2024. All rights reserved.