Apache camel 驼峰:发生异常时如何保留聚合结果?
我有一条多播到两个地方的路线。如果在调用位置1时发生异常,我将无法保留聚合结果。在OneException的处理器中,我在聚合期间创建的映射不在那里。我使用骆驼2.25Apache camel 驼峰:发生异常时如何保留聚合结果?,apache-camel,multicast,onexception,Apache Camel,Multicast,Onexception,我有一条多播到两个地方的路线。如果在调用位置1时发生异常,我将无法保留聚合结果。在OneException的处理器中,我在聚合期间创建的映射不在那里。我使用骆驼2.25 onException(RuntimeException.class) .process(new Processor() { @Override public void process(Exchange exchange) throws Exception { Ma
onException(RuntimeException.class)
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
Map<String, String> results = exchange.getProperty(SimpleAggregationStrategy.RESULTS, Map.class);
System.out.println(results);
}
});
from(DIRECT_FIRST)
.log("First route")
.setBody(constant("FIRST TEXT"));
from(DIRECT_SECOND)
.log("Second route")
.setBody(constant("SECOND TEXT"))
.throwException(new RuntimeException("Dummy Exception"));
from(DIRECT_ENTRY)
.multicast().stopOnException().aggregationStrategy(new AggregationStrategy() {
public static final String RESULTS = "RESULTS";
@Override
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
System.out.println("INSIDE SimpleAggregationStrategy !!!!!!!!!!!!!!!!");
Map<String, String> results;
if (oldExchange != null) {
results = oldExchange.getProperty(RESULTS, Map.class);
} else {
results = new HashMap<>();
}
results.put(newExchange.getIn().getBody(String.class), newExchange.getIn().getBody(String.class));
return newExchange;
}
})
.to(DIRECT_FIRST, DIRECT_SECOND);
onException(RuntimeException.class)
.进程(新处理器(){
@凌驾
公共作废进程(Exchange)引发异常{
Map results=exchange.getProperty(SimpleAggregationStrategy.results,Map.class);
系统输出打印项次(结果);
}
});
from(直接优先)
.log(“第一条路线”)
.setBody(常量(“第一个文本”);
从(直接秒)
.log(“第二条路线”)
.setBody(常量(“第二个文本”))
.ThroweException(新的运行时异常(“伪异常”));
from(直接输入)
.multicast().StopOneException().aggregationStrategy(新的aggregationStrategy()){
公共静态最终字符串RESULTS=“RESULTS”;
@凌驾
公共交换聚合(交换旧交换、交换新交换){
System.out.println(“内部SimpleAggregationStrategy!!!!!!!!!!!!!!!!!!!”;
地图结果;
if(oldExchange!=null){
结果=oldExchange.getProperty(结果,Map.class);
}否则{
结果=新HashMap();
}
put(newExchange.getIn().getBody(String.class)、newExchange.getIn().getBody(String.class));
返回newExchange;
}
})
.至(先导后导);
我假设聚合器由于StopOneException()
而中止处理,因此不会返回(不完整的)结果
您可以尝试将聚合策略放入上下文管理的bean中,并使映射成为可通过getter方法访问的实例变量
如果出现异常,您可以尝试从bean获取不完整的映射。但是我不知道它是否仍然保存数据,或者在处理中止时它是否被清空。解决方案比我想象的要简单。我们只需要在多播步骤之前创建exchangeProperty。这样,即使在执行多播时出现异常,exchange属性也可以存储聚合结果
onException(RuntimeException.class)
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
Map<String, String> results = exchange.getProperty("RESULTS", Map.class);
System.out.println(results);
}
});
from(DIRECT_FIRST)
.log("First route")
.setBody(constant("FIRST TEXT"));
from(DIRECT_SECOND)
.log("Second route")
.setBody(constant("SECOND TEXT"))
.throwException(new RuntimeException("Dummy Exception"));
from(DIRECT_ENTRY)
.process(exch -> {
exch.setProperty("RESULTS", new HashMap<String, String>())
})
.multicast().stopOnException().aggregationStrategy(new AggregationStrategy() {
public static final String RESULTS = "RESULTS";
@Override
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
Map<String, String> results;
if (oldExchange != null) {
results = oldExchange.getProperty(RESULTS, Map.class);
} else {
results = new HashMap<>();
}
results.put(newExchange.getIn().getBody(String.class), newExchange.getIn().getBody(String.class));
return newExchange;
}
})
.to(DIRECT_FIRST, DIRECT_SECOND);
onException(RuntimeException.class)
.进程(新处理器(){
@凌驾
公共作废进程(Exchange)引发异常{
映射结果=exchange.getProperty(“结果”,Map.class);
系统输出打印项次(结果);
}
});
from(直接优先)
.log(“第一条路线”)
.setBody(常量(“第一个文本”);
从(直接秒)
.log(“第二条路线”)
.setBody(常量(“第二个文本”))
.ThroweException(新的运行时异常(“伪异常”));
from(直接输入)
.过程(exch->{
setProperty(“结果”,新的HashMap())
})
.multicast().StopOneException().aggregationStrategy(新的aggregationStrategy()){
公共静态最终字符串RESULTS=“RESULTS”;
@凌驾
公共交换聚合(交换旧交换、交换新交换){
地图结果;
if(oldExchange!=null){
结果=oldExchange.getProperty(结果,Map.class);
}否则{
结果=新HashMap();
}
put(newExchange.getIn().getBody(String.class)、newExchange.getIn().getBody(String.class));
返回newExchange;
}
})
.至(先导后导);
Hi@esca tran你能把代码分享给我看看你在哪里添加了exchange吗property@prashanth-g、 我在多播步骤之前添加了1个处理器。请参阅我的示例代码