我创建了一个读取xml的camel路由,并在ActiveMQ-Queue中为xml中的每个元素放置一条消息。一切正常,但错误处理不起作用。这是路线:
@Override
public void configure() throws Exception {
from(fileIn)
.routeId(IN_ROUTE_ID)
.onCompletion()
.to(CommonRoutes.ENDPOINT_DIRECT_LOGGING)
.end()
.onException(UncategorizedJmsException.class)
.maximumRedeliveries(maxRetries)
.backOffMultiplier(multiplier)
.redeliveryDelay(initialDelay)
.end()
.unmarshal(jaxbDataFormat)
.process(fileProcessor)
.split(body()).stopOnException().shareUnitOfWork()
.process(domainWrapProcessor)
.to(ACTIVE_MQ_OUT + ":queue:" + checkNotNull(queueName))
.end()
;
}
这里是FileEndpoint的配置:
public void init(){
this.setAutoCreate(false);
this.setFile(new File(checkNotNull(csvFolder)));
this.setCamelContext(checkNotNull(context));
this.setAntInclude(ANT_INCLUDE);
this.setMove(doneFolder);
this.setMoveFailed(errorFolder);
}
目的是在每个异常上将文件移动到moveFailed文件夹,并且在JMSException(ActiveMQ离线)的情况下,camel应该重试,如果最终失败也会移动到moveFailed。
我已经为这两种情况创建了单元测试。这是任何例外的测试:
@Test
public void testException throws InterruptedException {
amqMmock.setExpectedMessageCount(3);
amqMock.whenAnyExchangeReceived((e) -> {
throw new RuntimeException("");
});
assertMockEndpointsSatisfied();
Thread.sleep(1000);
errorContainsFile(true);
}
此测试是将文件传递到错误文件夹集中。但是,如果我真实地运行这条路线(保险丝上的骆驼蓝图),这是行不通的:
问题是在任何(不是UncategorizedJmsException)异常上,文件只是保持锁定(创建.camelLock文件)。 (感谢stopOnException,JMSExceptions所需的行为正在运行) 那么如何让camel将文件移动到moveFailed文件夹上的任何异常?
答案 0 :(得分:0)
据我所知,如果文件组件本身出现问题({至少我经历过的话),moveFailed
实际上只会将文件移动到error-dir。这可以解释为什么在遇到异常时你的文件没有被移动到error-dir。
你可以尝试做的事情可能是这样的:
.onException(UncategorizedJmsException.class)
.maximumRedeliveries(maxRetries)
.backOffMultiplier(multiplier)
.redeliveryDelay(initialDelay)
.to(errorFolder)
.end()
以下是我如何使用蓝图与XML而不是Java DSL建立您的路线(嗯,粗略地说,只是为了得到它的要点):
<!-- Redelivery Policy -->
<bean id="redeliveryPolicyConfig" class="org.apache.camel.processor.RedeliveryPolicy">
<property name="maximumRedeliveries" value="${redelivery.max.attempts}" />
<property name="redeliveryDelay" value="${redelivery.delay.ms}" />
<property name="logRetryAttempted" value="${redelivery.log.attempts}" />
</bean>
<!-- Error Handler -->
<bean id="errorHandler" class="org.apache.camel.builder.DeadLetterChannelBuilder">
<property name="deadLetterUri" value="direct:error" />
<property name="useOriginalMessage" value="true" />
<property name="redeliveryPolicy" ref="redeliveryPolicyConfig" />
</bean>
<camelContext>
<route id="IN_ROUTE_ID">
<from uri="file://{{fileIn}}?move={{doneFolder}}&moveFailed={{errorFolder}}" />
...
<to uri="activemq:queue:{{queueName}}" />
</route>
<route id="error-route">
<from uri="direct:error" />
<to uri="file://{{errorFolder}}" />
</route>
</camelContext>