我们的代码:
public class FuseTemplateServiceRoute extends RouteBuilder {
private static final Logger LOG = Logger.getLogger("APPL." +
FuseTemplateServiceRoute.class.getName());
private static final int MAXIMUM_FAILOVER_ATTEMPTS = NUM_OF_SERVERS - 1;
private static final boolean INHERIT_ERROR_HANDLER = Boolean.TRUE;
private static final boolean ROUND_ROBIN = Boolean.TRUE;
private static final boolean STICKY = Boolean.FALSE;
@Override
public void configure() throws Exception {
for (int i = 0; i < 100; i++) {
System.out.println();
}
AtomicInteger counter = new AtomicInteger();
List<Endpoint> cxfEndpoints = URLFactory.getUrls(SERVER_PREFIX, NUM_OF_SERVERS, SERVICE_PATH).stream()//
.map(serviceAddress -> createCxfEndpoint(serviceAddress, counter))//
.collect(Collectors.toList());
onException(Exception.class)//
.handled(true)//
.process(new GenericExceptionHandler(LOG));
onException(SystemException.class)//
.handled(true)//
.process(new SystemExceptionHandler(LOG));
onException(BusinessException.class)//
.handled(true)//
.process(new BusinessExceptionHandler(LOG));
from("direct:start")//
.transacted()//
.process(new OpNameParamExtractor())//
.loadBalance()//
.failover(MAXIMUM_FAILOVER_ATTEMPTS, INHERIT_ERROR_HANDLER, ROUND_ROBIN, STICKY, SystemException.class)//
.to(cxfEndpoints);
}
private CxfEndpoint createCxfEndpoint(String serviceAddress, AtomicInteger counter) {
CxfEndpoint cxfEndpointOut = new CxfEndpoint(serviceAddress, new CxfComponent(getContext()));
cxfEndpointOut.setServiceClass(FuseTemplateFuseServicePortType.class);
cxfEndpointOut.setBeanId("FuseTemplateServiceOutbound_" +
counter.incrementAndGet());
cxfEndpointOut.setLoggingFeatureEnabled(true);
return cxfEndpointOut;
}
GenericExceptionHander:
public class GenericExceptionHandler implements Processor {
@Override
public void process(Exchange exchange) throws Exception {
Exception exception = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class);
throw new SystemException("Technischer Fehler: " + exception.getMessage(), FaultTypeHelper.createSystemFault(500));
}
}
SystemExceptionHandler:
public class SystemExceptionHandler implements Processor {
private final Logger logger;
public SystemExceptionHandler(Logger logger) {
this.logger = logger;
}
public void process(Exchange exchange) throws Exception {
SystemException exception =
exchange.getProperty(Exchange.EXCEPTION_CAUGHT, SystemException.class);
String errorMessage = "SystemException aus dem Backend erkannt, Message: [" + exception.getMessage() + "] mit ErrorCode: [" + exception.getErrorCode() + "].";
logger.error(errorMessage);
throw exception;
}
}
我们要实现的目标:
我们的服务使用者应该只收到:
用于不可恢复情况的业务异常-仅由后端Web服务实现抛出
可恢复情况下的SystemException
出于故障转移的原因,我们准备了SystemException处理-应该在放弃之前尝试所有可用的后端服务。
问题:
代表所提到的NullPointerException映射的SystemException创建的路由被路由捕获-并且所有节点都将再次尝试,尽管它们肯定会再次失败。
是否有一种方法可以告诉骆驼区分本地路由异常和后端异常? 换句话说-防止Camel处理基于路由的异常?