Alex
Alex

Reputation: 7521

How to ignore ChannelResolutionException in a Spring Integration router?

The Spring Integration router is specified as follows in the XML config:

<int:chain id="integrationFrontDoorQueueChain" input-channel="integrationFrontDoorQueueChannel">
    <int:transformer ref="integrationJsonPayloadTransformer" method="transformMessagePayload"/>
    <int:service-activator ref="firstScanInventoryService" method="sendMessage"/>
    <int:router ref="integrationRouterImpl" method="route" default-output-channel="nullChannel"/> 
</int:chain>

In the Java code for integrationRouterImpl we find the list of channels.

@Component("integrationRouterImpl")
public class IntegrationRouterImpl {
    private final IntegrationReferenceDataLoader integrationReferenceDataLoader;

    @Autowired
    public IntegrationRouterImpl(IntegrationReferenceDataLoader integrationReferenceDataLoader) {
         this.integrationReferenceDataLoader = integrationReferenceDataLoader;
    }

    public List<String> route(IntegrationPayload integrationPayload) {
        final List<String> channelList = new ArrayList<String>();
        for (Long productId : integrationPayload.getProductIds()) {
            final Set<String> channels = integrationReferenceDataLoader.findChannelsForProduct(productId, integrationPayload.getAction().name());
            if (channels != null) {
                channelList.addAll(channels);
            }
        }
        return channelList;
    }
}

It appeared that if the first channel in the channelList is not configured at all then the 2nd one is not invoked either. There is the exception:

[org.springframework.integration.support.channel.ChannelResolutionException: failed to look up MessageChannel bean with name 'seaActivationChannel'.  

However, I do not see a way to catch this exception and move to the next channel

The stack flow after leaving the method route in the router is as follows:

2015-12-18 15:06:30,297 [SimpleAsyncTaskExecutor-1] DEBUG org.springframework.integration.handler.LoggingHandler:67 - (inner bean)#8 received message: [Payload=org.springframework.integration.MessagingException: failed to resolve channel name 'seaActivationChannel'][Headers={timestamp=1450469190297, id=60c2f22b-55a0-4512-7d5c-f798ef67c8ca}]
2015-12-18 15:06:30,299 [SimpleAsyncTaskExecutor-1] ERROR org.springframework.integration.handler.LoggingHandler:140 - org.springframework.integration.MessagingException: failed to resolve channel name 'seaActivationChannel'
    at org.springframework.integration.router.AbstractMappingMessageRouter.resolveChannelForName(AbstractMappingMessageRouter.java:168)
    at org.springframework.integration.router.AbstractMappingMessageRouter.addChannelFromString(AbstractMappingMessageRouter.java:197)
    at org.springframework.integration.router.AbstractMappingMessageRouter.addToCollection(AbstractMappingMessageRouter.java:218)

……………

Caused by: org.springframework.integration.support.channel.ChannelResolutionException: failed to look up MessageChannel bean with name 'seaActivationChannel'
    at org.springframework.integration.support.channel.BeanFactoryChannelResolver.resolveChannelName(BeanFactoryChannelResolver.java:102)
    at org.springframework.integration.router.AbstractMappingMessageRouter.resolveChannelForName(AbstractMappingMessageRouter.java:164)
    ... 74 more

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'seaActivationChannel' is defined
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:568)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1102)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:278)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
    at org.springframework.integration.support.channel.BeanFactoryChannelResolver.resolveChannelName(BeanFactoryChannelResolver.java:93)

Upvotes: 2

Views: 860

Answers (1)

Artem Bilan
Artem Bilan

Reputation: 121542

First of all looks like you use Spring Integration 3.0.x or above. The ChannelResolutionException has been changed from Spring Integration 4.0 to the DestinationResolutionException. Although it doesn't matter.

Not sure why you haven't seen, but <router> supports an option which you need:

   <xsd:attribute name="resolution-required">
            <xsd:annotation>
                <xsd:documentation>
                    Specify whether channel names must always be successfully resolved
                    to existing channel instances.

                    If set to 'true', a MessagingException will be raised in case
                    the channel cannot be resolved. Setting this attribute to 'false',
                    will cause any unresovable channels to be ignored.

                    If not explicitly set, 'resolution-required' will
                    default to 'true'.
                </xsd:documentation>
            </xsd:annotation>
            <xsd:simpleType>
                <xsd:union memberTypes="xsd:boolean xsd:string" />
            </xsd:simpleType>
        </xsd:attribute>
    </xsd:complexType>

Upvotes: 2

Related Questions