Is there a possibility to bypass failover strategy in Direct Channel when custom Exceptions is thrown ?
If I add custom Error Channel - error message will reach error channel after all subscribers will be exhausted( in my case all JmsOutboundGateway will fail).
In my case I would like to check what error was the first error in inputLocalChannel ( in my case in jmsOutboundGateway) and if its expected error then stop processing (failover flow - don't pass it to other subscriber) and throw error - pass it to callback -> on Error
@MessagingGateway(name = "LocalGateway" , errorChannel = "defaultErrorChannel")
public interface LocalGateway {
@Gateway(requestChannel = "inputLocalChannel")
ListenableFuture<Message<String>> sendMsg(Message<String> request);
}
@Bean
public IntegrationFlow someFlow() {
return f -> f
.routeByException(r -> r
.channelMapping(MessageTimeoutException.class, "customErrorChannel")
.defaultOutputChannel("defaultErrorChannel"));
}
@Bean
public MessageChannel defaultErrorChannel() {
DirectChannel dr = new DirectChannel();
return dr;
}
@Bean
public MessageChannel customErrorChannel() {
DirectChannel dr = new DirectChannel();
return dr;
}
@ServiceActivator(inputChannel = "defaultErrorChannel")
private void processDefaultError(ErrorMessage errMsg) {
throw errMsg.getPayload();
}
@ServiceActivator(inputChannel = "customErrorChannel")
private void processCustomError(ErrorMessage errMsg) {
// some code
}
@Bean
@ServiceActivator(inputChannel = "inputLocalChannel")
public Message<String>firstHandler(){
// some code
}
@Bean
@ServiceActivator(inputChannel = "inputLocalChannel")
public Message<String> secondHandler(){
// some code
}
@Bean
@ServiceActivator(inputChannel = "inputGateway")
public JmsOutboundGateway firstGateway(){
// some code
}
@Bean
@ServiceActivator(inputChannel = "inputGatewayBck")
public JmsOutboundGateway secondGateway(){
// some code
}
It looks like you want something what can be called as a "conditional failover".
That feature is indeed not available for
DirectChannel, and I don't it has to be.I suggest yo look into an
ErrorMessageExceptionTypeRouterinstead: https://docs.spring.io/spring-integration/reference/router/implementations.html#router-implementations-exception-router. This way you would need to have more channels, include theerrorChanneloption of the@MessagingGateway. So, when error happens on the first gateway, you handle it by thatErrorMessageExceptionTypeRouterand decide where to go next.UPDATE
This is what I thought about your "conditional failover":
So, you catch an error from the
inputLocalChannelin thatrouteErrorChannel. And there with therouteByException()you make a decision according to the exception your got. In my example you send the message into asecondInputLocalChannelwhenMessageTimeoutException. However you still need to unwrap afailedMessagefrom that exception before publishing it into thatsecondInputLocalChannel. Otherwise the wholeErrorMessageis going to be sent. SeeMessagingException.getFailedMessage()property.