Apache Camel:如何通过SEDA端点传输异常?

时间:2016-04-15 11:30:22

标签: java exception apache-camel

当我将Camel Context Component中的消息发送到其端点时,我必须等待带有确认的响应消息。如果在超时时间内没有收到响应,则应将异常抛回驼峰路径。

我尝试通过以下方式实现它: 我使用多播来生成超时响应,同时将原始消息发送到端点。超时响应被延迟,如果在超时后没有收到响应,则应该在路由上抛回超时异常。

所以我有以下路线:

private final String internalRespUri = "direct:internal_resp";
private final String internalRespTimeout = "seda:internaltimeout";

@Override
public void configure() {
    SendController send_controller = new SendController();
    TimeoutResponse resp = new TimeoutResponse();

    from(Endpoints.MESSAGE_IN.direct())
                    .errorHandler(noErrorHandler())
                    .routeId(Endpoints.MESSAGE_IN.atsm())
                    .log("Incoming message at segment in")
                    .process(send_controller)
                    .log("Message after send controller")
                    .multicast().parallelProcessing()
                    .log("After wiretap")
                    .to(internalRespTimeout, Endpoints.SEGMENT_OUT.direct());
    from(internalRespTimeout)
                    .errorHandler(noErrorHandler())
                    .routeId(internalRespTimeout)
                    .log("begin response route")
                    .log("timeout response route")
                    .process(resp)
                    .log("modify message to response")
                    .delay(1000)
                    .log("after delay")
                    .to(internalRespUri);
    from(Endpoints.SEGMENT_IN.seda())
                    .routeId(Endpoints.SEGMENT_IN.atsm())
                    .to(internalRespUri);
    from(internalRespUri)
                    .errorHandler(noErrorHandler())
                    .routeId(internalRespUri)
                    .log("after response gathering point")
                    .choice()
                    .when(header(HeaderKeys.TYPE.key()).isEqualTo(UserMessageType.RESP.toString()))
                    .log("process responses")
                    .process(send_controller)
                    .otherwise()
                    .log("no response")
                    .to(Endpoints.MESSAGE_OUT.direct());
}

问题是SendController中抛出的异常不会通过SEDA端点internalRespTimeout传播。 如果我使用直接端点,它可以工作,但后来我有另一个问题: 延迟会阻塞路由,而来自端点Endpoints.SEGMENT_IN.seda()的收到响应消息可能无法传输。

SEDA端点通常无法传播异常吗? 我怎样才能解决我的问题?

谢谢, 斯文

2 个答案:

答案 0 :(得分:0)

我有个主意:

我可能可以使用事务进行超时,而不是抛出异常。

这可行吗?

答案 1 :(得分:0)

我目前还不知道在camel中通过SEDA端点传播和异常的方法。错误处理的工作方式基于端点之间的通道。当您使用SEDA端点时,代码将继续处理而不是等待代码,因为它将继续处理。我在理解您想要完成的任务时遇到了一些麻烦,但我会列出一些您可以使用的类似替代方案。

- 首先是在基于SEDA的路由中使用路由级错误处理程序,并使用您稍后可以查找的唯一ID来存储异常。

- 第二个是将数据传递到Java Bean,您可以完全控制自己正在做的事情,甚至可以考虑使用Guava的Futures在执行其他任务时异步运行代码。

如果你能解释一下你想要做得更好一些,我可以提出更明确的建议。