Apache camel 驼峰:发生异常时如何保留聚合结果?

Apache 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

我有一条多播到两个地方的路线。如果在调用位置1时发生异常,我将无法保留聚合结果。在OneException的处理器中,我在聚合期间创建的映射不在那里。我使用骆驼2.25

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个处理器。请参阅我的示例代码