9

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?

3 Answers 3

10

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.

Sign up to request clarification or add additional context in comments.

1 Comment

If you're reading this for Spring Integration 2.1+, ignore-channel-name-resolution-failures has been dropped. You can get the same effect by useing resolution-required="false". See static.springsource.org/spring-integration/reference/htmlsingle/…
1

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 the resolution-required attribute. Also, the resolution-required attribute now defaults to true.

Prior to these changes, the resolution-required attribute defaulted to false, causing messages to be silently dropped when no channel was resolved and no default-output-channel was set. The new behavior requires at least one resolved channel and, by default, throws a MessageDeliveryException 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();

Comments

0

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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.