快捷搜索:   nginx

利用 Apache Synapse 模拟 Web 服务(2)

  在此示例中,您使用样式表转换构建了一个合适的响应消息,该响应消息使用了从请求消息中提取的内容。如果查看此 Web 服务中的 WSDL,您可以看到在此 Web 服务中还有三种操作。此时,对于发送到此代理服务的任何请求消息类型,Synapse 都将发送同样的响应。在下面的部分中,您将执行 Web 服务的其他操作。

  完整代理服务

  现在,让我们使用样式表转换来实现一套完整的股票报价服务操作。您将测试请求消息中的操作名称元素,并用合适的响应替换它。

  使用 synapse_sample_mock4-fullservice.xml 配置启动 Synapse:./synapse.sh -sample mock4-fullservice

  如下所示运行示例客户端:ant stockquote -Dtrpurl=http://localhost:8081/soap/StockQuoteService -Dmode=quote

  将quote的值分别更改为fullquotemarketactivityplaceorder,并运行以上命令。示例客户端在每个情形中将发送不同的请求类型。Synapse 将根据发送的请求消息发送合适的响应。

  清单 6 是您使用的 Synapse 配置。

  清单 6. 完全代理服务的 Synapse 配置:synapse_sample_mock4-fullservice.xml

<definitions xmlns="http://ws.apache.org/ns/synapse">
 <localEntry key="SimpleStockQuoteService_xsl"
  src="file:repository/conf/sample/resources/mocks/SimpleStockQuoteService.xsl"/>
 <proxy name="StockQuoteService"> <target>
  <inSequence>
   <filter xpath="//ns:placeOrder"
    xmlns:ns="http://services.samples/xsd">
    <log format="full" />
    <drop />
   </filter>
   <xslt key="SimpleStockQuoteService_xsl"/>
   <property name="RESPONSE" value="true"/>
   <header name="To" action="remove"/>
   <send/>
  </inSequence>
  <outSequence/>
 </target>
 <publishWSDL
  uri="file:repository/conf/sample/resources/mocks/SimpleStockQuoteService.wsdl"/>
 </proxy>
</definitions>

  在样式表中,您将测试请求消息是什么并用合适的响应消息替换这些内容。placeOrder操作是一种例外情形,它是一种仅传入操作。这意味着placeOrder操作没有响应。您使用筛选器中介器测试了该请求是否包含使用 XPath 表达式的placeOrder元素。如果是,就已经记录了该请求并丢弃了该消息,以防出现进一步中介。这不会像预期的placeOrder操作那样将响应发送回客户端。

  清单 7 是用于完整代理服务的样式表。您将使用操作名称检查这些元素,并在发现时将该消息替换为合适的响应消息。

  清单 7. 完全代理服务的样式表:SimpleStockQuoteService.xsl

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ns="http://services.samples/xsd">
 <xsl:output method="xml"/>
 <xsl:template match="/">
  <soapenv:Envelope
   xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Body>
    <xsl:if test="ns:getQuote">
     <ns:getQuoteResponse >
      ...
     </ns:getQuoteResponse>
    </xsl:if>
    <xsl:if test="ns:getFullQuote">
     <ns:getFullQuoteResponse
      xmlns:ns="http://services.samples/xsd">
      ...
     </ns:getFullQuoteResponse>
    </xsl:if>
    <xsl:if test="ns:getMarketActivity">
     <ns:getMarketActivityResponse xmlns:ns="http://services.samples/xsd">
     ...
     </ns:getMarketActivityResponse>
    </xsl:if>
   </soapenv:Body>
  </soapenv:Envelope>
 </xsl:template>
</xsl:stylesheet>

  您已经使用了一个简单的样式表在 Synapse 中成功模拟了完整的 Web 服务操作。在接下来的部分中,您要将其他虚拟 Web 服务添加到现有配置中。

  服务组

  在本步骤中,您将添加另一项虚拟 Web 服务 LBService1。LBService1 是另一个 Web 服务,它随 Synapse 中绑定的示例服务器提供,用于演示负载平衡和故障切换示例。这里您仅在 Synapse 中进行模拟。

  使用 synapse_sample_mock5-twoproxy.xml 配置启动 Synapse:./synapse.sh -sample mock5-twoproxy

  如下所示运行示例客户端:ant loadbalancefailover -Dtrpurl=http://localhost:8081/soap/LBService1 -Di=10

  示例客户端发送请求序列并打印 Synapse 中模拟响应的输出。还提供了前面的股票报价服务。您可以尝试前面的示例请求,以便能够根据需要实现尽可能多的服务,并可以自定义每项服务应该如何响应。

  您可以在http://localhost:8080/soap/LBService1?wsdl中看到新模拟服务的 WSDL。

  清单 8 显示了您使用的 Synapse 配置。

  清单 8. 用于服务组的 Synapse 配置:synapse_sample_mock5-twoproxy.xml

<definitions xmlns="http://ws.apache.org/ns/synapse">
 <localEntry key="SimpleStockQuoteService_xsl"
  src="file:repository/conf/sample/resources/mocks/SimpleStockQuoteService.xsl"/>
 <localEntry key="CustomSampleOperation_xsl"
  src="file:repository/conf/sample/resources/mocks/CustomSampleOperation.xsl"/>
 <proxy name="StockQuoteService">
  ...
 </proxy>
 <proxy name="LBService1">
  <target>
   <inSequence>
    <script language="js">
     <![CDATA[
      var node = mc.getPayloadXML().toString();
      mc.setPayloadXML(
       <ser:sampleOperation xmlns:ser="http://services.samples">
        <ser:param>{node}</ser:param>
        Response from anonymous server
       </ser:sampleOperation>);
     ]]>
    </script>
    <property name="RESPONSE" value="true"/>
    <header name="To" action="remove"/>
    <send/>
   </inSequence>
   <outSequence/>
  </target>
  <publishWSDL uri="file:repository/conf/sample/resources/mocks/LBService1.wsdl"/>
 </proxy>
</definitions>

  对于 LBService1(而不是 XSLT 中介器),您使用了脚本中介器。该脚本中介器可使用 JavaScript、Groovy、Ruby、Python 或脚本引擎支持的其他脚本语言执行脚本。您可以使用脚本来处理该消息。在本例中,我已经在 JavaScript 中编写了简单的代码片段,将消息有效负载替换为新的响应。您甚至还可以使用脚本验证请求的内容,并像真实的模拟 Web 服务那样在请求无效时返回错误。

  这样,您可以创建一组模拟 Web 服务。可以保留这些不同的配置,并使用像组织示例那样的方法来组织它们。这样,下一次您测试销售自动化系统时,就可以启动 Synapse 配置文件(该文件包括该应用程序所需的模拟 Web 服务请求),然后开始测试。

  模拟中介器

  到现在为止,您已经使用现有的 Synapse 工具模拟了 Web 服务。使用自定义中介和任务(如模拟中介器),您可以扩展 Synapse 以支持您特定的请求。

  如清单 9 中所示,该模拟中介器使用一个配置文件。它列出了要在传入消息中查找的正则表达式模式和模式集匹配时返回的文件。如果没有匹配项,您还可以提供缺省的文件名称。此配置文件将定期从文件系统中重新加载,因此,您可以修改此文件,而无需重新启动 Synapse。使用此中介器,您可以指示 Synapse 查找请求消息中给定的模式并发回特定的响应。例如,您可以在该请求具有getQuoteABC文本模式时命令 Synapse 发送一个响应,并在请求包含getQuoteDEF文本模式时发送一条错误消息。使用属性payload-only,您可以要求中介器替换整个消息,或仅替换正文内容。清单 9 是一个示例模拟中介器配置。

  清单 9. 模拟中介器配置

<simulate-config>
 <match file='abc.xml'>
  <pattern>urn:getQuote</pattern>
  <pattern>ABC</pattern>
 </match>
 <match file='fault.xml' payload-only='true'>
  <pattern>urn:getQuote</pattern>
  <pattern>[Cc]on</pattern>
 </match>
 <default-file>default.xml</default-file>
</simulate-config>

  清单 10 显示了 Synapse 配置,该配置演示了正在操作中的模拟中介器。这类似于前面的示例。不过,此模拟中介器不是转换消息,而是使用通过评估前面列出的模拟中介器配置所选的文件替换该消息。

  清单 10. 用于使用模拟中介器的 Synapse 配置

<definitions xmlns="http://ws.apache.org/ns/synapse">
 <in>
  <simulate>
   <simulate-config>
    repository/conf/sample/resources/simulate/simulate-config.xml</simulate-config>
   <file-path>repository/conf/sample/resources/simulate/</file-path>
  </simulate>
  <property name="RESPONSE" value="true"/>
  <header name="To" action="remove"/>
  <send />
 </in>
</definitions>

  发送请求

  在不访问服务器端的情况下开发和测试客户端是一个难点。在以前的所有场景中,您是模拟了该操作。但是,构建服务器端组件情况会如何?您可能使用过像 curl 这样的工具向端点发送请求有效负载,或者编写一个自定义客户端程序来调用您在开发的新的 Web 服务。您也可以使用 Apache Synapse 模拟该操作。

  清单 11 是 Apache Synapse 分发版中的示例 254,只是稍有修改(请参阅参考资料以获取相关链接)。您已经完全删除了 WSDL 项并且同时将该端点指定给您的测试服务。请创建这些请求消息,并将它们复制到 in 目录中。Apache Synapse 将从 in 目录中选取它们,将它们发送到目标服务,并将该响应保存在 out 目录中。在本例中,Synapse 相当于一个发球员,它从 in 目录中挑选出文件,然后发送到给定的端点,并将响应保存在 out 目录中。

  清单 11. 用于发送请求的 Synapse 配置

<definitions xmlns="http://ws.apache.org/ns/synapse">
 <proxy name="StockQuoteProxy" transports="vfs">
  <parameter
   name="transport.vfs.FileURI">file:///home/upul/test/in</parameter>
  <parameter name="transport.vfs.ContentType">text/xml</parameter>
  <parameter name="transport.vfs.FileNamePattern">.*.xml</parameter>
  <parameter name="transport.PollInterval">2</parameter>
  <parameter name="transport.vfs.MoveAfterProcess">
   file:///home/upul/test/original</parameter>
  <parameter name="transport.vfs.MoveAfterFailure">
   file:///home/upul/test/original</parameter>
  <parameter name="transport.vfs.ActionAfterProcess">MOVE</parameter>
  <parameter name="transport.vfs.ActionAfterFailure">MOVE</parameter>
  <target>
   <endpoint>
    <address format="soap12"
     uri="http://localhost:9000/soap/TestService"/>
   </endpoint>
   <outSequence>
    <property name="transport.vfs.ReplyFileName"
     expression="fn:concat(fn:substring-after(get-property('MessageID'),
     'urn:uuid:'), '.xml')" scope="transport"/>
    <send>
     <endpoint>
      <address uri="vfs:file:///home/upul/test/out"/>
     </endpoint>
    </send>
   </outSequence>
  </target>
 </proxy>
</definitions>

  结束语

  Apache Synapse 是一个简单的轻量级多用途 ESB,除企业集成开发之外,您还可以将其用于更多方面。在本教程中,您学习了如何仅通过转换、操作和重定向请求消息来使用它模拟 Web 服务。

  对于利用这一多用途工具可以做什么而言,我只是介绍了一些最基本的内容。您可以编写自定义中介器和任务来扩展 Apache Synapse 功能。(请参阅参考资料部分中的文章,以了解如何编写自定义中介器和任务以满足您的具体要求。)如果您有使用 Apache Synapse 解决大型企业集成问题或您个人的一次性任务的新思路和新方法,请与 Apache Synapse ESB 社区分享它们。

  本文示例源代码或素材下载

顶(2)
踩(0)

您可能还会对下面的文章感兴趣:

最新评论