Error handling 聚合失败后发送时回滚单个输入文件

Error handling 聚合失败后发送时回滚单个输入文件,error-handling,apache-camel,camel-file,Error Handling,Apache Camel,Camel File,我目前正在尝试将一些遗留代码/系统迁移到Camel。当前系统正在处理大量队列文件夹,并按顺序处理这些队列中的所有消息,而不是在开始处理下一条消息之前完全处理消息的完整流。我们想摆脱这种情况,这似乎是可能的与骆驼(我已经新的,由于以前的经验与骆驼)。只有一个“问题”,我似乎无法得到简单的流定义。在简化形式的文本中,流程如下 轮询某个文件夹中的文件 有些文件需要聚合,有些可以直接发送(当前基于文件名,但将来可能基于内容) 根据内容中的特定字段聚合文件 将文件发送到远程系统 这在“快乐时光”场景中

我目前正在尝试将一些遗留代码/系统迁移到Camel。当前系统正在处理大量队列文件夹,并按顺序处理这些队列中的所有消息,而不是在开始处理下一条消息之前完全处理消息的完整流。我们想摆脱这种情况,这似乎是可能的与骆驼(我已经新的,由于以前的经验与骆驼)。只有一个“问题”,我似乎无法得到简单的流定义。在简化形式的文本中,流程如下

  • 轮询某个文件夹中的文件
  • 有些文件需要聚合,有些可以直接发送(当前基于文件名,但将来可能基于内容)
  • 根据内容中的特定字段聚合文件
  • 将文件发送到远程系统
这在“快乐时光”场景中非常有效。下一步是添加错误处理。为此,我们有一个重要的要求。输入文件夹中可能已聚合但在重定时后未发送的单个文件,应视为单个文件最终位于错误文件夹中

这就是问题所在,至少在保持流程简单方面是如此。我之所以提到“至少保持流程简单”,是因为有了(很多)额外的节点和步骤,我可以实现我想要的(因为这不是我想要的“建议”的内容,所以我不会发布这个示例)。我正在处理的流程是:

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:camel="http://camel.apache.org/schema/spring"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring https://camel.apache.org/schema/spring/camel-spring-3.4.0.xsd">

    <bean class="org.apache.camel.processor.aggregate.StringAggregationStrategy" id="myAggregationStrategy">
    
    <camelContext>
        <route>
            <from uri="file://c:/data/store/merge/?moveFailed=.error"/>
                           
            <setHeader headerName="MyGroupingID" id="_setHeader1">
                <simple resultType="int">${header.CamelFileName.split('_|\.')[0]}</simple>
            </setHeader>
            <aggregate  strategyRef="myAggregationStrategy">
                <correlationExpression>
                    <header>MyGroupingID</header>
                </correlationExpression>
                <completionTimeout>
                    <constant>5000</constant>
                </completionTimeout>
                <choice id="_choice1">
                    <when id="_when1">
                        <simple>${exchange.properties['CamelAggregatedCorrelationKey']} == 1</simple>
                        <throwException exceptionType="java.lang.Exception" id="_throwException1" message="Group 1 has an error"/>
                    </when>
                    <otherwise id="_otherwise1">
                        <log id="processMessage" message="Processed exchange: [${exchange}] body: [${body}] headers: [${headers}]."/>
                    </otherwise>
                </choice>
            </aggregate>
        </route>
    </contextx>
</beans>
使用Camel 3.6.0(但尝试了2.25.2以及所有相关(返回)更改,相同的问题,因此它不是某种回归;-)

我不是在寻找代码中的完整解决方案,关于可能性或不可能性(无法解决的问题)的提示也会被找到(尽管如果有简单的解决方案,我不介意被引用或作为答案;-)

间接相关的帖子我读到:

@RunWith(CamelSpringJUnit4ClassRunner.class)
@ContextConfiguration({"/META-INF/spring/applicationContext.xml"})
@DisableJmx(true)
@UseAdviceWith(true)
public class MessageGroupingTest {

  private static final Logger log = LoggerFactory.getLogger(MessageGroupingTest.class);

  @Autowired
  private CamelContext camelContext;
  
  private final AtomicBoolean adviced = new AtomicBoolean(false);

  @Produce(uri = "file://c:/data/store/merge/")
  private ProducerTemplate producer;

  @EndpointInject(uri = "mock:semiStreamingGrouping")
  private MockEndpoint mock;

  @Before
  public void adviceGroupingRoute() throws Exception {
    if (!adviced.get()) {
        ModelCamelContext mcc = camelContext.adapt(ModelCamelContext.class);
        RouteReifier.adviceWith(mcc.getRouteDefinition("_route1"), mcc, new AdviceWithRouteBuilder() {
          @Override
        public void configure() throws Exception {
            weaveById("processMessage")
            .after()
            .to(mock);
            
        }
        });
      camelContext.start();
      adviced.set(true);
    }
  }
  
  @Test
  public void testGroupingMessages() throws Exception {
    String message = "Hello world!";
    
      Map<String, Object> headers = new HashMap<>();

      headers.put("MyGroupingID", 1);
  
      headers.put("CamelFileName", "1_2_1.txt");
      producer.sendBodyAndHeaders(message, headers);
      
      headers.put("CamelFileName", "1_2_2.txt");
      producer.sendBodyAndHeaders(message, headers);

      headers.put("CamelFileName", "2_1_1.txt");
      producer.sendBodyAndHeaders(message, headers);


    mock.expectedMessageCount(1);
    Thread.sleep(5000);
    mock.assertIsSatisfied(300000L);
  }
}