首页 文章

Apache Synapse / WSO2 API无回复

提问于
浏览
1

我想向数据库发送一个查询,并使用WSO2 rest api将结果返回给客户端 . 这是synapse配置:

<api xmlns="http://ws.apache.org/ns/synapse" name="RestDBLookup" context="/dblookup">
   <resource methods="POST GET" uri-template="/channel/{name}" protocol="http">
      <inSequence>
         <dblookup>
            <connection>
               <pool>
                  <password>pass</password>
                  <driver>oracle.jdbc.driver.OracleDriver</driver>
                  <url>jdbc:oracle:thin:@localhost:1521:ORCL</url>
                  <user>user</user>
               </pool>
            </connection>
            <statement>
               <sql>SELECT ID, CHANNEL_NAME FROM CHANNEL where CHANNEL_NAME = ?</sql>
               <parameter expression="get-property('uri.var.name')" type="VARCHAR"/>
               <result name="channel_id" column="ID"/>
            </statement>
         </dblookup>
         <log level="custom">
            <property name="ID" expression="get-property('channel_id')"/>
            <property name="State" value="after db"/>
         </log>
      </inSequence>
      <outSequence>
         <property name="messageType" value="application/json" scope="axis2" type="STRING"/>
         <log level="full"/>
         <send/>
      </outSequence>
      <faultSequence/>
   </resource>
</api>

当我用rest客户端调用url http://localhost:8280/dblookup/channel/someChannel 时,我会在dblookup之后获取日志

LogMediator ID = 40810162, State = after db

但是 outSequence 没有执行,我只在没有正文的其他客户端上获得状态202接受 .

所以问题是如何构建一些响应(例如以JSON格式)并将其发送到客户端?

2 回答

  • 1

    Synapse中介有三个流程:

    • inSequence - 处理即将到来的请求,并定义在发送到目标 endpoints 之前应如何处理(中介)请求

    • outSequence - 处理从 endpoints 返回的响应,并定义在发送给客户端之前应如何处理响应(中介)

    • faultSequence - 如果在服务调解期间发生错误,则故障消息将切换到故障序列 . 您可以根据您的要求(日志错误,丢弃消息和发送回故障)记录故障序列中的逻辑 .

    现在让我们看看你的用例 . 你要做的是在inSequence中查询数据库 . 你也得到了结果 . 但问题是结果不会发回客户端 . 这里的问题是您在seSece中写入的调解没有调用outSequence . 因此outSequence没有被击中 . 例如,如果在inSequence中调用后端服务,则响应命中outSequence . 在你的情况下,响应回到inSequence . 因此,我们可以执行以下任一选项:

    • 在inSequence中的 </log> mediator之后添加 <loopback/> 介体 . 这会将消息从inSequence移动到outSequence .

    • 将outSequence中写入的逻辑移到inSequence中 . 然后在inSequence的末尾添加 <respond/> . 这会将当前消息发送回客户端 . 所以你可能不需要outSequence .

    希望以上答案有帮助 .

    干杯!

  • 3

    由于Indika建议我使用 <respond/> 并最终使用此配置:

    <api context="/dblookup" name="RestDBLookup" xmlns="http://ws.apache.org/ns/synapse">
      <resource methods="POST GET" protocol="http" uri-template="/channel/{name}">
        <inSequence>
          <dblookup>
            <connection>
              <pool>
                <password>pass</password>
                <driver>oracle.jdbc.driver.OracleDriver</driver>
                <url>jdbc:oracle:thin:@localhost:1521:ORCL</url>
                <user>user</user>
              </pool>
            </connection>
            <statement>
              <sql><![CDATA[SELECT ID, CHANNEL_NAME FROM CHANNEL where CHANNEL_NAME = ?]]></sql>
              <parameter expression="get-property('uri.var.name')" type="VARCHAR"/>
              <result column="ID" name="channel_id"/>
            </statement>
          </dblookup>
          <log level="custom">
            <property expression="get-property('channel_id')" name="ID"/>
            <property name="State" value="after db"/>
          </log>
          <payloadFactory media-type="json">
            <format>
                   {
                      "channelId":"$1"
                   }
                </format>
            <args>
              <arg evaluator="xml" expression="get-property('channel_id')"/>
            </args>
          </payloadFactory>
          <property action="remove" name="NO_ENTITY_BODY" scope="axis2"/>
          <property name="messageType" scope="axis2" type="STRING" value="application/json"/>
          <respond/>
        </inSequence>
        <outSequence/>
        <faultSequence/>
      </resource>
    </api>
    

相关问题