我遇到了Camel 2.19.1的问题。和具有路由范围的onCompletion
处理程序。运行时是Java 8,Karaf 4.0.9。 Camel上下文是使用Blueprint构建的。
我已经使用onCompletion处理程序定义了3条路线:
<onCompletion mode="BeforeConsumer" parallelProcessing="false" onCompleteOnly="true" useOriginalMessage="false">
<log message="<route_name> Success." loggingLevel="INFO" logName="policy-repository-adapter" />
</onCompletion>
这三条路由通过direct
端点相互呼叫,如下所示:
pra-soap-endpoint -> direct:xacml-policy-query -> direct:send-to-pas-endpoint
顶级路由pra-soap-endpoint
看起来像这样(显然是伪代码):
route pra-soap-endpoint
process
log "route checkpoint 1"
to direct:xacml-policy-query
log "route checkpoint 2"
process
end route
顶级路由和onCompletion处理程序的日志输出如下所示:
route checkpoint 1
send-to-pas-endpoint Success.
xacml-policy-query Success.
pra-soap-endpoint Success.
route checkpoint 2
send-to-pas-endpoint Success.
xacml-policy-query Success.
pra-soap-endpoint Success.
send-to-pas-endpoint Success.
xacml-policy-query Success.
pra-soap-endpoint Success.
请注意,onCompletion处理程序会多次触发。除此之外,在路由实际完成之前触发顶级路由的onCompletion处理程序(在日志语句pra-soap-endpoint Success.
之前记录语句route checkpoint 2
)。
我的期望是:
route checkpoint 1
send-to-pas-endpoint Success.
xacml-policy-query Success.
route checkpoint 2
pra-soap-endpoint Success.
这是Camel中的错误还是我对onCompletion
处理程序如何工作的误解?
答案 0 :(得分:1)
此行为正确。您在mode="BeforeConsumer"
定义上指定了onCompletion
,这改变了Camel的行为(自2.14开始)。
来自the docs:
来自 Camel 2.14 :已修改onCompletion以支持以同步或异步模式(使用线程池)运行完成任务,以及是否在路由使用者完成之前或之后运行。原因是提供更多的灵活性。例如,指定在路由使用者完成之前运行同步,这允许在使用者将任何响应写回被调用者之前修改交换。您可以使用它来添加客户标头,或发送到日志以记录响应消息等。
再次,在其自己的部分:
onCompletion支持两种模式
AfterConsumer - 在消费者完成后运行的默认模式 BeforeConsumer - 在消费者完成之前,以及消费者将响应写回被叫方之前运行。
AfterConsumer模式是默认模式,与旧版Camel版本的行为相同 新的BeforeConsumer模式用于在消费者将其响应写回被叫方之前运行onCompletion(如果处于InOut模式)。这允许onCompletion修改Exchange,例如添加特殊标头,或将Exchange记录为响应记录器等。
作为解决方案,请使用AfterConsumer
模式或将模式设置为InOnly
。