1

你好 WSO2 社区和你好 Stackoverflow,

我从 ESB 开始对 SOA 套件的测试进展顺利:现在 ESB 识别外部服务,创建返回正确结果的正确代理。

解决了

关于这一点,我有两个问题:第一个是“尝试一下”功能引发了异常:

"Cannot find dispatch method for {http://schemas.xmlsoap.org/soap/envelope/}Envelope

[tagOpened]/soapenv:Text[tagClosed]"

当我尝试发送为代理的 Web 服务的模拟服务创建的 SOAP 封装时。

无论如何,如果我从外部客户端(在 Netbeans 上创建)尝试代理服务,它会很好用。

回答

对于第一部分,原因很可能是跨域问题,因为 try-它是通过​​浏览器的 java 脚本存根发送消息。您会注意到,当服务本身托管在 ESB 本身中时,这很有效,因为请求通过同一个域。这就是为什么,虽然它可以通过正常的客户端调用完美地工作,但它不能通过 try-it 工作。

第二个问题是我无法协调两个服务。我的目标是将第一个服务的输入发送到第二个服务,然后发送给用户。

我正在编写 Tharindu Mathew 建议的教程:现在一切对我来说都是有意义的,除了一件事:XSLT 转换。

这是教程建议您创建的输出序列:

<outSequence xmlns="http://ws.apache.org/ns/synapse">
   <switch source="get-property('STATE')">
      <case regex="PERSON_INFO_REQUEST">
         <log level="full">
            <property name="sequence" value="outSequence - STATE 01 - response from PersonInfoService" />
         </log>
         <xslt key="xslt">
            <property name="amount" expression="get-property('ORG_AMOUNT')" />
         </xslt>
         <log level="full">
            <property name="sequence" value="outSequence - STATE 01 - request for CreditService" />
         </log>
         <property name="STATE" value="CREDIT_REQUEST" />
         <send>
            <endpoint key="CreditEpr" />
         </send>
      </case>
      <case regex="CREDIT_REQUEST">
         <log level="full">
            <property name="sequence" value="outSequence - STATE 02 - response from CreditService" />
         </log>
         <send />
      </case>
   </switch>
</outSequence>

现在,关注第一个 switch 案例的 XSLT 节点,您可以看到对于 amount 属性只有一个 get。所以我认为我们有一个来自 in sequence 的 XML 来说明 ID,并且这得到了 amount 属性(我不知道它做了什么)。

本教程然后建议:

要创建对此 CrediService 的请求,我们将以下 XSLT 与 XSLT 中介一起使用。请注意,我们使用存储在此 XSLT 中的 ORG_ID 作为 XSLT 参数,并且还使用了 XSLT 中介。

这是教程中显示的 XSLT:

<xsl:stylesheet version="2.0" 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
        xmlns:fn="http://www.w3.org/2005/02/xpath-functions"
        xmlns:ns="http://samples.esb.wso2.org"
        xmlns:ax21="http://samples.esb.wso2.org/xsd"
        exclude-result-prefixes="ns fn">
<xsl:param name="amount"/>
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>

<xsl:template match="/">
  <xsl:apply-templates select="//ns:getResponse" />
</xsl:template>

<xsl:template match="ns:getResponse" xmlns:ns="http://samples.esb.wso2.org">
<sam:credit xmlns:sam="http://samples.esb.wso2.org" xmlns:xsd="http://samples.esb.wso2.org/xsd">
    <sam:info>
        <xsd:amount><xsl:value-of select="$amount"/></xsd:amount>
        <xsd:personInfo>
            <xsd:address><xsl:value-of select="ns:return/ax21:address"/></xsd:address>
            <xsd:id><xsl:value-of select="ns:return/ax21:id"/></xsd:id>
            <xsd:name><xsl:value-of select="ns:return/ax21:name"/></xsd:name>
        </xsd:personInfo>
    </sam:info>
</sam:credit>
</xsl:template>
</xsl:stylesheet>

我被要求将一个类似的文件放入 WSO2 ESB 的资源目录中,但该文件从未在教程中使用过:

将示例 zip 中的 personToCredit.xslt 复制到 WSO2 ESB 的资源目录。

---------小括号----------

声明后也没有使用 WSDL 文件:

将示例 zip 中的 CreditProxy.wsdl 复制到 WSO2 ESB 的资源目录中。

我在配置/治理注册表中找不到 WSDL 文件,也不知道如何解决它,所以我选择内联指定它。

---------小括号结束----------

这句话后面是 XSLT 文件文本。我现在的主要问题是:

我应该把这个 XSLT 放在哪里?我不知道将 XSLT 中介器放在哪里,也不知道如何构建它。我应该依赖注册表吗?

一个完美的答案可能是输出序列的代码,以及建议的与 XSLT 中介的指定连接。

OverTheBitStair

4

2 回答 2

1

嗨 OverTheBitStair(好昵称!),

对于第一部分,原因很可能是跨域问题,因为 try-它是通过​​浏览器的 java 脚本存根发送消息。您会注意到,当服务本身托管在 ESB 本身中时,这很有效,因为请求通过同一个域。这就是为什么,虽然它可以通过正常的客户端调用完美地工作,但它不能通过 try-it 工作。

对于第二部分,简短的回答是肯定的,这是可能的。就 ESB 而言,我们将其称为轻量级编排引擎,而不是作为中介引擎。这意味着对于轻量级和短期(<1 天)流程,我们可以使用 ESB 解决编排需求,而无需引入业务流程服务器。

为此,我们使用这种称为服务链的方法。它所做的是引入一种从初始服务调用中获取一些输出并在后续调用中使用它的方法。文章WSO2 ESB by example - Service Chaining应该可以帮助您了解您正在寻找的实现细节。

希望这可以帮助。

于 2012-05-22T04:45:06.280 回答
0

如果您创建一个服务链场景,其中您的代理服务调用另外两个服务并将结果返回给代理服务的调用者,它看起来像这样:

调用者 --> 代理服务 -- seq_A --> Service1 -- seq_B --> Service2 -- seq_C --> (代理服务响应) --> 调用者

在这种情况下,seq_A 将是代理服务的 in 序列,seq_C 是代理服务的 out 序列,seq_B 是另一个命名序列。

seq_A 的输入,即消息体,将是代理服务的输入。seq_A 将在末尾包含一个发送中介,并且在序列中的那个点,消息上下文将成为 Service1 的输入。发送中介还指向要为回复执行的 seq_B。

在 seq_B 开始时,消息正文包含来自 Service1 的输出。如果要在服务调用之前保留一些消息数据,则需要将其保存在上下文的属性中。在 seq_B 结束时,您将有一个发送中介;此时消息正文应包含对 Service2 的输入,如果 seq_C 是代理服务的输出序列,则发送调解器在这种情况下不需要指向显式回复序列 - 默认情况下将使用该序列。

当 seq_C 正在执行时,此时消息体是来自 Service2 的响应。同样,如果您需要在调用 Service2 之前使用/组合某些数据,则需要将其保存到属性中。

根据每个步骤所需的输入和转换的特定需求,处理起来可能相当简单或有点麻烦。还应该考虑的是在错误场景中需要发生什么,因为这可能会增加一些额外的复杂性,具体取决于要求。

于 2012-05-23T19:31:16.103 回答