from("hazelcast:seda:someQueue")
.id("someQueueID")
.onException(CustomException.class)
.handled(true)
.log(LoggingLevel.WARN, "custom exception noticed")
.end()
.onException(IOException.class, FileNotFoundException.class)
.asyncDelayedRedelivery()
.redeliveryDelay(3*1000*60) // 3 Minutes
.maximumRedeliveries(3)
.log(LoggingLevel.WARN, "io exception noticed")
.end()
.onException(Exception.class)
.log(LoggingLevel.WARN, "general exception noticed")
.end()
.log("Starting route")
.bean(TestBean.class)
.log("Finished route");
public class TestBean
{
@Handler
public void checkData(@Headers final Map<String, Object> headers)
throws CustomException, IOException, Exception
{
Integer testVal = (Integer)headers.get("TestValue");
if (0 == testVal)
throw new CustomException("CustomException");
else if (1 == testVal)
throw new IOException("IOException");
else
throw new Exception("Exception");
}
}
由于这个测试设置只是一个较大项目的一小部分,所以像这里这样做可能听起来很傻,但核心意图是在测试时修改redeliveryDelay,因为“强制”IOException不需要等待3分钟,因此,为了加快单元测试的速度,可以将redeliveryDelay减少到大约10毫秒。
为了实现这一点,my test-method执行以下操作:
@ContextConfiguration(classes = OnExceptionRouteTest.ContextConfig.class, loader = AnnotationConfigContextLoader.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class OnExceptionRouteTest extends CamelSpringTestSupport
{
@Override
protected AbstractApplicationContext createApplicationContext()
{
return new AnnotationConfigApplicationContext(ContextConfig.class)
}
@Configuration
public static class ContextConfig extends CamelConfiguration
{
@Override
protected void setupCamelContext(CamelContext camelContext) throws Exception
{
super.setupCamelContext(camelContext);
camelContext.addComponent("hazelcast", new StubComponent());
// some other unnecessary stuff
}
@Override
public List<RouteBuilder> routes()
{
final List<RouteBuilder> list = new ArrayList<>();
list.add(new OnExceptionRoute());
return list;
}
}
@Override
public boolean isUseAdviceWith()
{
return true;
}
@Test
public void testIOException()
{
context.getRouteDefinition("someQueueID")
.adviceWith(context, new AdviceWithRouteBuilder()
{
@Override
public void configure() throws Exception
{
this.weaveByType(OnExceptionDefinition.class)
.selectIndex(1)
.replace()
.onException(IOException.class, FileNotFound.class)
.asyncDelayedRedelivery()
.redeliveryDelay(10)
.maximumRedeliveries(3)
.log("modified io exception noticed")
.to("mock:ioError")
.end();
...
mockEndpoints();
}
});
context.start();
MockEndpoint ioErrorEndpoint = getMockEndpoint("mock:ioError");
...
ioErrorEndpoint.setExpectedMessageCount(1);
...
Map<String, Object> headers = new HashMap<>();
headers.put("TestValue", new Integer(1));
template.sendBodyAndHeaders("hazelcast:seda:someQueue", new Object(), headers);
...
ioErrorEndpoint.assertIsSatisfied();
...
}
}
这里,测试只是替换了IOException的onException段,以首先将重传递延迟从3分钟减少到10毫秒,并在最后添加了一个模拟endpoint。但是,当我尝试运行单元测试时,我将得到以下异常:
java.lang.IllegalArgumentException: The output must be added as top-level on the route. Try moving OnException[[class java.io.IOException, class java.io.FileNotFoundException] -> []] to the top of route.
因此,任何关于修改onException块或单元测试的redeliveryDelay的提示都非常受欢迎。
@edit:我现在还尝试将onException声明移到路由定义(从(...)
)之上,这也是Camel异常示例中的首选情况。但是,在这样做时,所有测试(即使是工作的测试)都失败了,因为context.getRouteDefinition(“somequeueid”).adviceWith(context,new AdviceWithRouteBuilder(){...});
上出现NullPointerException
,因为显然再也找不到路由本身了。我怀疑这是IntelliJ的问题,因为两个类都在同一个项目中,因此对路由的修改应该对测试类可见。
使用中的Camel版本:2.13.0,IntelliJ IDEA 13.1.2
@edit2:由于某种原因,context.getRouteDefinitions(“somequeueid”)
返回null,如果OnException元素是在from
块之外定义的,而一般的路由可以通过context.getRouteDefinitions().get(0)
获得-不过,声明OnException部分需要作为顶级元素添加的异常仍然存在。
在使用Java DSL时,路由的id是使用.routeID()
方法设置的,而不是像上面所编码的那样使用.id()
。这可能有助于解决对
的担忧。
与其硬编码重试延迟,更好的方法是使用属性来配置延迟。请查看CamelSpringTestSupport
类中有关方法UseOverridePropertiesWithPropertiesComponent()
的文档。
编辑
import org.apache.camel.builder.AdviceWithRouteBuilder;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.test.junit4.CamelTestSupport;
public class DummyTest extends CamelTestSupport{
@Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder(){
@Override
public void configure() throws Exception {
from("direct://start")
.routeId("myroute")
.onException(Exception.class)
.id("myException")
.continued(true)
.end()
.throwException(new Exception())
.to("mock:end");
}
};
}
@org.junit.Test
public void doTest() throws Exception{
context.getRouteDefinition("myroute").adviceWith(context, new AdviceWithRouteBuilder(){
@Override
public void configure() throws Exception {
context.getRouteDefinition("myroute")
.onException(Exception.class).setBody(constant("adviceWith")).continued(true);
}});
context.start();
template.sendBody("direct://start", "original");
String bodyAtEndOfExchange = getMockEndpoint("mock:end")
.getExchanges().get(0).getIn().getBody(String.class);
assertEquals("adviceWith", bodyAtEndOfExchange);
context.stop();
}
@Override
public boolean isUseAdviceWith() {
return true;
}
}
我目前正试图用Apache Camel测试一条现有的路线,但我不确定我做得对不对,因为我不完全理解Camel背后的所有概念。 话虽如此,以下是我想做的,关于以下示例路线: 这里的要点就是获取一个ImportDocumentProcess,并创建一个依赖于前一个对象的ImportDocumentTraItem。ImportDocument过程是通过exchange进行的。 以下是处理器代码: 我已经
我在做一些关于Camel-CXf集成的研究,对下面的场景感到困惑。 所以我实现了一个Restendpoint 实现如下 } 路线 将其路由到实现中。但是由于实现返回一个响应对象,我不知道如何绕过这个对象构建路由。 一旦调用进入实现,我如何执行其他路由并发送回响应?在这种情况下,实现返回一个自定义对象。 其他路由如何附加到 CXF 路由? 我的 CXF 实现是否应该始终返回无效类型?如我所见,要访问
我一直试图使用2.12.1-snapshot中的RabbitMQComponent版本让camel进行路由。这样做,我可以很容易地消费,但在路由到另一个队列时会遇到ad问题。 在这篇文章中,我已经验证了指定的交换机是否配置了适当的路由密钥。我注意到,我能够大量消费,但不能生产到out.queue。 以下是对处理消息的RabbitMQProducer的唯一引用。 我花了很多时间研究了RabbitMQ
在一条骆驼路线中,我有两个url调用,调用两个不同的应用程序。 两者都能够抛出。因此,如果URL1抛出我必须处理的异常并将交换体设置为“数据源1不可用”,并且如果URL2抛出相同的异常,我想显示不同的消息。 如何使用onException处理此问题
我有没有温和的方式说骆驼应该跳过这个(没有“camelerrorhandlerhandle”属性删除)? 谢谢
我正在尝试使用angular与主播合作,我已经做了我的研究,但没有成功,所以我正在联系你们。 我有 3 个组件 {导航栏组件, 红色组件, 蓝色组件} 导航栏组件有 2 个锚点。我希望当我单击其中一个时,它实际上会将我引导到正确的组件 导航栏组件.ts 红色. component.ts blue.component.ts app.component.html 应用程序模块