【问题标题】:Apache Camel - Split and aggregate - Old Exchange is always nullApache Camel - 拆分和聚合 - 旧 Exchange 始终为空
【发布时间】:2014-01-22 21:17:29
【问题描述】:

我看到这个问题已经被问过很多次了,但没有一个帖子有帮助,也没有一个决定性的解决方案。我正在拆分一条消息,然后使用 Aggregator2 对其进行聚合。代码抛出异常,因为 oldExchange 始终为空。所以为了测试我设计了一个小代码。

我读了一个订单,xml文件,看起来像这样

<Orders xmlns="http://some/schema/Order">
    <Order>
            <orderNum>1</orderNum>
    </Order>
    <Order>
            <orderNum>2</orderNum>
    </Order>
    <Order>
            <orderNum>3</orderNum>
    </Order>
    <Order>
            <orderNum>5</orderNum>
    </Order>
    <Order>
            <orderNum>6</orderNum>
    </Order>

我的骆驼上下文看起来像这样

<camel:route>
<camel:from uri="file:src/data/catask/test?noop=true"/>
<camel:log message="${body}"></camel:log>
<camel:split>
<camel:xpath>//te:Orders/*</camel:xpath>
<camel:to uri="direct:logQueries"/>
<camel:to uri="direct:aggegateQueries"/>  
</camel:split>

</camel:route>

<camel:route>
<camel:from uri="direct:logQueries"/>
<camel:log message="After the call : \n ${body}"></camel:log>  
</camel:route>

 <camel:route>
<camel:from uri="direct:aggegateQueries"/>
<camel:aggregate strategyRef="aggrTask" completionInterval="8000" >
<camel:correlationExpression>
<camel:xpath>//te:Order</camel:xpath>
</camel:correlationExpression>
<camel:to uri="file:src/data/catask/output?fileName=output.xml"/>  

</camel:aggregate>
</camel:route>  

我的聚合策略类看起来像这样

   public Exchange aggregate(Exchange oldExchange, Exchange newExchange) { 
            if (oldExchange == null) { 
            System.out.println("Returning new exchange"); 
                return newExchange; 
            } 

            String oldBody = oldExchange.getIn().getBody(String.class); 
            String newBody = newExchange.getIn().getBody(String.class); 
            oldExchange.getIn().setBody(oldBody + "+" + newBody); 
            return oldExchange; 
        } 

问题在于,当聚合结果保存在 output.xml 文件中时,它只包含从 Orders.xml 读取的最后一条记录。

<Order xmlns="http://some/schema/Order">
            <orderNum>6</orderNum>
    </Order>

我进一步调查并发现这是因为在第一次调用之后 oldExchange 应该有一些值,但事实证明它始终为空。我认为因为它是从单个文件中读取所有内容并将其拆分,所以只有交换。

>有什么建议吗?

更新 1: Per Claus 我只能使用 Splitter 来解决这个问题。我这样做了,并且能够成功加入所有消息。但是我仍在寻找一种使用 Aggregator2 的方法。这里我是如何只使用 Splitter 的。

camel:route>
<camel:from uri="file:src/data/catask/test?noop=true"/>
<camel:log message="${body}"></camel:log>
<camel:split strategyRef="aggrTask"> 
<camel:xpath>//te:Orders/*</camel:xpath>
<camel:to uri="direct:logQueries"/>
 < 
</camel:split>

</camel:route>

<camel:route>
<camel:from uri="direct:logQueries"/>
<camel:log message="After the call : \n ${body}"></camel:log>  
</camel:route>

【问题讨论】:

标签: java spring apache-camel


【解决方案1】:

我想我知道如何使用聚合器聚合消息。我添加了一个名为 id 的 headerName 并将其用作我的相关 id。

<camel:route>
  <camel:from uri="file:src/data/catask/test?noop=true"/>
  <camel:log message="${body}"></camel:log>
  <camel:split>
    <camel:xpath>//te:Orders/*</camel:xpath>
    <camel:to uri="direct:addHeaders"/>
    <camel:to uri="direct:aggegateQueries"/>
  </camel:split>
</camel:route>

<camel:route>
  <camel:from uri="direct:addHeaders"/>
  <camel:setHeader headerName="id">
    <camel:constant>order</camel:constant>
  </camel:setHeader>
</camel:route>

<camel:route>
  <camel:from uri="direct:aggegateQueries"/>
  <camel:aggregate strategyRef="aggrTask" completionInterval="8000" >
    <camel:correlationExpression>
      <simple>header.id</simple>
    </camel:correlationExpression>
    <camel:to uri="file:src/data/catask/output?fileName=output.xml"/>
    <camel:log message="MERGED:: /n ${body}"></camel:log>
  </camel:aggregate>
</camel:route>  

这会汇总我的消息。但是我仍然不确定尽管使用了正确的 XPATH,为什么 Camel 认为它是不同类型的消息?

从骆驼论坛复制克劳斯的解释: “看起来你的相关表达式是一个新的组 每个消息,例如每个 xpath 结果都是不同的。 如果您想拆分和加入相同的消息,请查看此 eip http://camel.apache.org/composed-message-processor.html 并查看仅使用拆分器的示例。这更容易做到。 "

我使用 Xpath Evaluator 工具测试了 Xpath 表达式,还打印了相关表达式结果,我的所有带有 //Order 的消息都是相同的。前-

Group 1: 
<Order>  
  <orderNum>1</orderNum>  
</Order>  

Group 2: 
<Order>  
  <orderNum>2</orderNum>  
</Order> 

【讨论】:

    【解决方案2】:
    <camel:correlationExpression>
      <simple>header.id</simple>
    </camel:correlationExpression>
    

    可以替换为:

    <!-- Required! The expression to retrieve the correlation key. When no key the constant true could be used. --> 
    <camel:correlationExpression>
      <constant>true</constant>
    </camel:correlationExpression>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-29
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多