복붙노트

[SPRING] Apache Camel - 분할 및 집계 - 이전 Exchange는 항상 null입니다.

SPRING

Apache Camel - 분할 및 집계 - 이전 Exchange는 항상 null입니다.

나는이 질문이 여러 번 제기되었지만 어떤 게시물도 도움이되지 않았거나 결정적인 해결책이 없음을 압니다. 메시지를 분할 한 다음 Aggregator2를 사용하여 메시지를 집계합니다. oldExchange가 항상 null이므로 코드가 예외를 던지고 있습니다. 그래서 테스트하기 위해 작은 코드를 만들었습니다.

주문과 같은 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가 첫 번째 호출 이후에 어떤 값을 가져야하지만 항상 null이라는 것을 알았 기 때문에 이것이 발생했다. 나는 그것이 하나의 파일에서 모든 것을 읽고 그것을 분할하기 때문에, 오직 교환이 있다고 생각한다.

> 어떤 제안 ??

업데이트 1 : Claus 당이 문제를 해결하기 위해서만 스플리터를 사용할 수 있습니다. 나는 그것을했고 모든 메시지에 성공적으로 참여할 수있었습니다. 그러나 나는 아직도 Aggregator2를 사용하는 방법을 찾고있다. 여기 어떻게 스플리터 만 사용했는지.

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>

해결법

  1. ==============================

    1.Aggregator를 사용하여 메시지를 집계하는 방법을 알아 냈다고 생각합니다. id라는 headerName을 추가하고이를 내 상관 ID로 사용합니다.

    Aggregator를 사용하여 메시지를 집계하는 방법을 알아 냈다고 생각합니다. 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이 메시지의 다른 유형이라고 생각하는 이유는 확실하지 않습니다.

    낙타 포럼에서 CLAUS의 설명을 복사 : "귀하의 상관 관계 표현이 새로운 그룹 인 것처럼 보입니다. 각 메시지, 예를 들어 각 xpath 결과는 다릅니다. 같은 메시지를 나누고 결합하려면이 전자 메일을보십시오. http://camel.apache.org/composed-message-processor.html 그리고 스플리터 만 사용하는 예제를 참조하십시오. 그렇게하는 것이 훨씬 쉽습니다. "

    Xpath Evaluator 도구를 사용하여 Xpath 표현식을 테스트하고 coorelation expression 결과를 인쇄하여 // Order를 사용하는 모든 메시지를 동일하게 표시합니다. 전의-

    Group 1: 
    <Order>  
      <orderNum>1</orderNum>  
    </Order>  
    
    Group 2: 
    <Order>  
      <orderNum>2</orderNum>  
    </Order> 
    
  2. from https://stackoverflow.com/questions/21294160/apache-camel-split-and-aggregate-old-exchange-is-always-null by cc-by-sa and MIT license