Reputation: 4239
I'd like use Spring Integration to implement a content based router that uses a default output channel if the expression value doesn't match any of the mappings. Here's my bean definition:
<int:router input-channel="channel_in" default-output-channel="channel_default" expression="payload.name">
<int:mapping value="foo" channel="channel_one" />
<int:mapping value="bar" channel="channel_two" />
However, it seems the default output channel is never used. If the expression evaluates to e.g. 'baz', the router seems to be looking for a channel named 'baz', instead of routing to the 'channel_default' channel:
org.springframework.integration.MessagingException: failed to resolve channel name 'baz'
Caused by: org.springframework.integration.support.channel.ChannelResolutionException:
failed to look up MessageChannel bean with name 'baz'
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
No bean named 'baz' is defined
Is what I want at all possible using the XML namespace, or do I need to code up my own implementation?
Upvotes: 9
Views: 15591
Reputation: 361
As mentioned in reference docs:
As of Spring Integration 2.1, router parameters have been more standardized across all router implementations. Consequently, a few minor changes may break older Spring Integration based applications.
Since Spring Integration 2.1, the
ignore-channel-name-resolution-failures
attribute is removed in favor of consolidating its behavior with theresolution-required
attribute. Also, the resolution-required attribute now defaults totrue
.Prior to these changes, the
resolution-required
attribute defaulted tofalse
, causing messages to be silently dropped when no channel was resolved and nodefault-output-channel
was set. The new behavior requires at least one resolved channel and, by default, throws aMessageDeliveryException
if no channel was determined (or an attempt to send was not successful).If you do desire to drop messages silently, you can set
default-output-channel="nullChannel"
.
And if you are using Java DSL, the configuration may looks like this:
IntegrationFlows.from("process")
.<JobExecution, String>route(m -> m.getExitStatus().getExitCode(),
m -> m.channelMapping(ExitStatus.COMPLETED.getExitCode(), "succeed")
.defaultOutputChannel("failed")
.resolutionRequired(false))
.get();
Upvotes: 1
Reputation: 63
if you are using for Spring boot 2.1.2.RELEASE
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
then resolution-required="false" is required instead of ignore-channel-name-resolution-failures.
<int:router input-channel="channel_in" default-output-channel="channel_default"
expression="payload.name" resolution-required="false">
<int:mapping value="foo" channel="channel_one" />
<int:mapping value="bar" channel="channel_two" />
</int:router>
Upvotes: 0
Reputation: 4239
Turns out that all I had to to to make this work was to set the router's ignore-channel-name-resolution-failures attribute to false:
<int:router input-channel="channel_in" default-output-channel="channel_default"
expression="payload.name" ignore-channel-name-resolution-failures="true">
<int:mapping value="foo" channel="channel_one" />
<int:mapping value="bar" channel="channel_two" />
</int:router>
I thought I had tried that before, but I seems I didn't.
Upvotes: 10