Merge pull request #57 from ghillert/INT-2053

Refactor/Standardize Router XSD Schema Attributes
This commit is contained in:
Mark Fisher
2011-09-20 12:53:44 -04:00
16 changed files with 1410 additions and 614 deletions

View File

@@ -1,8 +1,242 @@
<?xml version="1.0" encoding="UTF-8"?>
<section xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="router"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Router</title>
<title>Routers</title>
<section id="router-overview">
<title>Overview</title>
<para>
Routers are a crucial element in many messaging architectures. They consume
Messages from a Message Channel and forward each consumed message to one or
more different Message Channel depending on a set of conditions.
</para>
<para>
Spring Integration provides the following routers out-of-the-box:
</para>
<itemizedlist>
<listitem>
<para><emphasis>(Generic) Router</emphasis></para>
</listitem>
<listitem>
<para><emphasis>Header Value Router</emphasis></para>
</listitem>
<listitem>
<para><emphasis>XPath Router (Part of the XML Module)</emphasis></para>
</listitem>
<listitem>
<para><emphasis>Payload Type Router</emphasis></para>
</listitem>
<listitem>
<para><emphasis>Recipient List Router</emphasis></para>
</listitem>
<listitem>
<para><emphasis>Error Message Exception Type Router</emphasis></para>
</listitem>
</itemizedlist>
<para>
Router implementations share many configuration parameters. Yet, certain differences
exist between routers. Furthermore, the availability of configuration parameters
depends on whether Routers are used inside or outside of a chain. In order to
provide a quick overview, all available attributes are listed in the 2 tables
below.
</para>
<table><title>Routers Outside a Chain</title>
<tgroup cols="7">
<colspec colnum="1" colname="col01" colwidth="3*"/>
<colspec colnum="2" colname="col02" colwidth="1*" align="center"/>
<colspec colnum="3" colname="col03" colwidth="1*" align="center"/>
<colspec colnum="4" colname="col04" colwidth="1*" align="center"/>
<colspec colnum="5" colname="col05" colwidth="1*" align="center"/>
<colspec colnum="6" colname="col06" colwidth="1*" align="center"/>
<colspec colnum="7" colname="col07" colwidth="1*" align="center"/>
<thead>
<row>
<entry>Attribute</entry>
<entry>router</entry>
<entry>header value router</entry>
<entry>xpath router</entry>
<entry>payload type router</entry>
<entry>recipient list router</entry>
<entry>exception type router</entry>
</row>
</thead>
<tbody>
<row>
<entry>apply-sequence</entry>
<entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry>x<entry>x</entry><entry>x</entry>
</row>
<row>
<entry>default-output-channel</entry>
<entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry>
</row>
<row>
<entry>resolution-required</entry>
<entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry>
</row>
<row>
<entry>ignore-send-failures</entry>
<entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry>
</row>
<row>
<entry>timeout</entry>
<entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry>
</row>
<row>
<entry>id</entry>
<entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry>
</row>
<row>
<entry>auto-startup</entry>
<entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry>
</row>
<row>
<entry>input-channel</entry>
<entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry>
</row>
<row>
<entry>order</entry>
<entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry>
</row>
<row>
<entry>channel-resolver</entry>
<entry>x</entry><entry></entry><entry></entry><entry></entry><entry></entry><entry></entry>
</row>
<row>
<entry>method</entry>
<entry>x</entry><entry></entry><entry></entry><entry></entry><entry></entry><entry></entry>
</row>
<row>
<entry>ref</entry>
<entry>x</entry><entry></entry><entry></entry><entry></entry><entry></entry><entry></entry>
</row>
<row>
<entry>expression</entry>
<entry>x</entry><entry></entry><entry></entry><entry></entry><entry></entry><entry></entry>
</row>
<row>
<entry>header-name</entry>
<entry></entry><entry>x</entry><entry></entry><entry></entry><entry></entry><entry></entry>
</row>
<row>
<entry>evaluate-as-string</entry>
<entry></entry><entry></entry><entry>x</entry><entry></entry><entry></entry><entry></entry>
</row>
<row>
<entry>xpath-expression-ref</entry>
<entry></entry><entry></entry><entry>x</entry><entry></entry><entry></entry><entry></entry>
</row>
</tbody>
</tgroup>
</table>
<table><title>Routers Inside a Chain</title>
<tgroup cols="7">
<colspec colnum="1" colname="col01" colwidth="3*"/>
<colspec colnum="2" colname="col02" colwidth="1*" align="center"/>
<colspec colnum="3" colname="col03" colwidth="1*" align="center"/>
<colspec colnum="4" colname="col04" colwidth="1*" align="center"/>
<colspec colnum="5" colname="col05" colwidth="1*" align="center"/>
<colspec colnum="6" colname="col06" colwidth="1*" align="center"/>
<colspec colnum="7" colname="col07" colwidth="1*" align="center"/>
<thead>
<row>
<entry>Attribute</entry>
<entry>router</entry>
<entry>header value router</entry>
<entry>xpath router</entry>
<entry>payload type router</entry>
<entry>recipient list router</entry>
<entry>exception type router</entry>
</row>
</thead>
<tbody>
<row>
<entry>apply-sequence</entry>
<entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry>x<entry>x</entry><entry>x</entry>
</row>
<row>
<entry>default-output-channel</entry>
<entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry>
</row>
<row>
<entry>resolution-required</entry>
<entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry>
</row>
<row>
<entry>ignore-send-failures</entry>
<entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry>
</row>
<row>
<entry>timeout</entry>
<entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry><entry>x</entry>
</row>
<row>
<entry>id</entry>
<entry></entry><entry></entry><entry></entry><entry></entry><entry></entry><entry></entry>
</row>
<row>
<entry>auto-startup</entry>
<entry></entry><entry></entry><entry></entry><entry></entry><entry></entry><entry></entry>
</row>
<row>
<entry>input-channel</entry>
<entry></entry><entry></entry><entry></entry><entry></entry><entry></entry><entry></entry>
</row>
<row>
<entry>order</entry>
<entry></entry><entry></entry><entry></entry><entry></entry><entry></entry><entry></entry>
</row>
<row>
<entry>channel-resolver</entry>
<entry>x</entry><entry></entry><entry></entry><entry></entry><entry></entry><entry></entry>
</row>
<row>
<entry>method</entry>
<entry>x</entry><entry></entry><entry></entry><entry></entry><entry></entry><entry></entry>
</row>
<row>
<entry>ref</entry>
<entry>x</entry><entry></entry><entry></entry><entry></entry><entry></entry><entry></entry>
</row>
<row>
<entry>expression</entry>
<entry>x</entry><entry></entry><entry></entry><entry></entry><entry></entry><entry></entry>
</row>
<row>
<entry>header-name</entry>
<entry></entry><entry>x</entry><entry></entry><entry></entry><entry></entry><entry></entry>
</row>
<row>
<entry>evaluate-as-string</entry>
<entry></entry><entry></entry><entry>x</entry><entry></entry><entry></entry><entry></entry>
</row>
<row>
<entry>xpath-expression-ref</entry>
<entry></entry><entry></entry><entry>x</entry><entry></entry><entry></entry><entry></entry>
</row>
</tbody>
</tgroup>
</table>
<note>
Router parameters have been more standardized across all router implementations
in Spring Integration 2.1. Consequently, there are a few minor changes that
leave the possibility of breaking older Spring Integration based applications.
</note>
<important>
Since Spring Integration 2.1 the "ignore-channel-name-resolution-failures"
attribute was 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 dropped silently when no channel was resolved and
no "default-output-channel" was set.
The new behavior will require at least one resolved channel and by default
will throw an Exception if no channel was determined (or an attempt to send
was not successful).
If you do desire to drop messages silently simply set "default-output-channel='nullChannel'".
</important>
</section>
<section id="router-implementations">
<title>Router Implementations</title>
<para>

View File

@@ -45,8 +45,6 @@ public class RouterFactoryBean extends AbstractStandardMessageHandlerFactoryBean
private volatile Boolean resolutionRequired;
private volatile Boolean ignoreChannelNameResolutionFailures;
private volatile Boolean applySequence;
private volatile Boolean ignoreSendFailures;
@@ -68,10 +66,6 @@ public class RouterFactoryBean extends AbstractStandardMessageHandlerFactoryBean
this.resolutionRequired = resolutionRequired;
}
public void setIgnoreChannelNameResolutionFailures(Boolean ignoreChannelNameResolutionFailures) {
this.ignoreChannelNameResolutionFailures = ignoreChannelNameResolutionFailures;
}
public void setApplySequence(Boolean applySequence) {
this.applySequence = applySequence;
}
@@ -128,9 +122,6 @@ public class RouterFactoryBean extends AbstractStandardMessageHandlerFactoryBean
if (this.timeout != null) {
router.setTimeout(timeout.longValue());
}
if (this.ignoreChannelNameResolutionFailures != null) {
router.setIgnoreChannelNameResolutionFailures(ignoreChannelNameResolutionFailures);
}
if (this.applySequence != null) {
router.setApplySequence(this.applySequence);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -44,7 +44,6 @@ public abstract class AbstractRouterParser extends AbstractConsumerEndpointParse
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "resolution-required");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "apply-sequence");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "ignore-send-failures");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "ignore-channel-name-resolution-failures");
BeanDefinition targetRouterBeanDefinition = this.parseRouter(element, parserContext);
builder.addPropertyValue("targetObject", targetRouterBeanDefinition);
return builder;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -78,7 +78,6 @@ public class DefaultRouterParser extends AbstractDelegatingConsumerEndpointParse
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "default-output-channel");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "timeout");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "resolution-required");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "ignore-channel-name-resolution-failures");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "apply-sequence");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "ignore-send-failures");
}

View File

@@ -30,6 +30,7 @@ import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.MessageDeliveryException;
import org.springframework.integration.MessagingException;
import org.springframework.integration.channel.NullChannel;
import org.springframework.integration.core.MessagingTemplate;
import org.springframework.integration.handler.AbstractMessageHandler;
import org.springframework.integration.support.MessageBuilder;
@@ -47,14 +48,13 @@ import org.springframework.util.StringUtils;
*
* @author Mark Fisher
* @author Oleg Zhurakousky
* @author Gunnar Hillert
*/
@ManagedResource
public abstract class AbstractMessageRouter extends AbstractMessageHandler {
private volatile MessageChannel defaultOutputChannel;
private volatile boolean resolutionRequired;
private volatile boolean ignoreSendFailures;
private volatile boolean applySequence;
@@ -67,7 +67,7 @@ public abstract class AbstractMessageRouter extends AbstractMessageHandler {
private volatile ChannelResolver channelResolver;
private volatile boolean ignoreChannelNameResolutionFailures;
private volatile boolean resolutionRequired = true;
protected volatile Map<String, String> channelIdentifierMap = new ConcurrentHashMap<String, String>();
@@ -120,9 +120,12 @@ public abstract class AbstractMessageRouter extends AbstractMessageHandler {
}
/**
* Set the default channel where Messages should be sent if channel resolution fails to return any channels. If no
* default channel is provided, the router will either drop the Message or throw an Exception depending on the value
* of {@link #resolutionRequired}.
* Set the default channel where Messages should be sent if channel resolution
* fails to return any channels. If no default channel is provided and channel
* resolution fails to return any channels, the router will throw an
* {@link MessageDeliveryException}.
*
* If messages shall be ignored (dropped) instead, please provide a {@link NullChannel}.
*/
public void setDefaultOutputChannel(MessageChannel defaultOutputChannel) {
this.defaultOutputChannel = defaultOutputChannel;
@@ -136,21 +139,12 @@ public abstract class AbstractMessageRouter extends AbstractMessageHandler {
this.messagingTemplate.setSendTimeout(timeout);
}
/**
* Set whether this router should always be required to resolve at least one channel. The default is 'false'. To
* trigger an exception whenever the resolver returns null or an empty channel list, and this endpoint has no
* 'defaultOutputChannel' configured, set this value to 'true'.
*/
public void setResolutionRequired(boolean resolutionRequired) {
this.resolutionRequired = resolutionRequired;
}
/**
* Specify whether this router should ignore any failure to resolve a channel name to
* an actual MessageChannel instance when delegating to the ChannelResolver strategy.
*/
public void setIgnoreChannelNameResolutionFailures(boolean ignoreChannelNameResolutionFailures) {
this.ignoreChannelNameResolutionFailures = ignoreChannelNameResolutionFailures;
public void setResolutionRequired(boolean resolutionRequired) {
this.resolutionRequired = resolutionRequired;
}
/**
@@ -234,8 +228,7 @@ public abstract class AbstractMessageRouter extends AbstractMessageHandler {
if (!sent) {
if (this.defaultOutputChannel != null) {
this.messagingTemplate.send(this.defaultOutputChannel, message);
}
else if (this.resolutionRequired) {
} else {
throw new MessageDeliveryException(message,
"no channel resolved by router and no default output channel defined");
}
@@ -260,12 +253,12 @@ public abstract class AbstractMessageRouter extends AbstractMessageHandler {
channel = this.channelResolver.resolveChannelName(channelName);
}
catch (ChannelResolutionException e) {
if (!this.ignoreChannelNameResolutionFailures) {
if (this.resolutionRequired) {
throw new MessagingException(message,
"failed to resolve channel name '" + channelName + "'", e);
}
}
if (channel == null && !this.ignoreChannelNameResolutionFailures) {
if (channel == null && this.resolutionRequired) {
throw new MessagingException(message,
"failed to resolve channel name '" + channelName + "'");
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ package org.springframework.integration.router;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import java.lang.reflect.Method;
import java.util.ArrayList;
@@ -28,6 +29,7 @@ import org.junit.Test;
import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.MessageDeliveryException;
import org.springframework.integration.MessagingException;
import org.springframework.integration.annotation.Header;
import org.springframework.integration.channel.QueueChannel;
@@ -134,7 +136,15 @@ public class MethodInvokingRouterTests {
Message<?> result2 = barChannel.receive(0);
assertNotNull(result2);
assertEquals("bar", result2.getPayload());
router.handleMessage(badMessage);
try {
router.handleMessage(badMessage);
fail();
} catch (MessageDeliveryException e) {
/* Success */
}
}
@Test
@@ -171,7 +181,14 @@ public class MethodInvokingRouterTests {
Message<?> result2 = barChannel.receive(0);
assertNotNull(result2);
assertEquals("bar", result2.getPayload());
router.handleMessage(badMessage);
try {
router.handleMessage(badMessage);
fail();
} catch (MessageDeliveryException e) {
/* Success */
}
}
@Test
@@ -208,7 +225,14 @@ public class MethodInvokingRouterTests {
Message<?> result2 = barChannel.receive(0);
assertNotNull(result2);
assertEquals("bar", result2.getPayload());
router.handleMessage(badMessage);
try {
router.handleMessage(badMessage);
fail();
} catch (MessageDeliveryException e) {
/* Success */
}
}
@Test
@@ -251,7 +275,13 @@ public class MethodInvokingRouterTests {
assertEquals("bar", result2a.getPayload());
assertNotNull(result2b);
assertEquals("bar", result2b.getPayload());
router.handleMessage(badMessage);
try {
router.handleMessage(badMessage);
fail();
} catch (MessageDeliveryException e) {
/* Success */
}
}
@Test
@@ -294,7 +324,13 @@ public class MethodInvokingRouterTests {
Message<?> result2b = barChannel.receive(0);
assertNotNull(result2b);
assertEquals("bar", result2b.getPayload());
router.handleMessage(badMessage);
try {
router.handleMessage(badMessage);
fail();
} catch (MessageDeliveryException e) {
/* Success */
}
}
@Test
@@ -337,7 +373,13 @@ public class MethodInvokingRouterTests {
Message<?> result2b = barChannel.receive(0);
assertNotNull(result2b);
assertEquals("bar", result2b.getPayload());
router.handleMessage(badMessage);
try {
router.handleMessage(badMessage);
fail();
} catch (MessageDeliveryException e) {
/* Success */
}
}
@Test
@@ -380,7 +422,14 @@ public class MethodInvokingRouterTests {
assertEquals("bar", result2a.getPayload());
assertNotNull(result2b);
assertEquals("bar", result2b.getPayload());
router.handleMessage(badMessage);
try {
router.handleMessage(badMessage);
fail();
} catch (MessageDeliveryException e) {
/* Success */
}
}
@Test
@@ -423,7 +472,14 @@ public class MethodInvokingRouterTests {
assertEquals("bar", result2a.getPayload());
assertNotNull(result2b);
assertEquals("bar", result2b.getPayload());
router.handleMessage(badMessage);
try {
router.handleMessage(badMessage);
fail();
} catch (MessageDeliveryException e) {
/* Success */
}
}
@Test
@@ -466,7 +522,14 @@ public class MethodInvokingRouterTests {
assertEquals("bar", result2a.getPayload());
assertNotNull(result2b);
assertEquals("bar", result2b.getPayload());
router.handleMessage(badMessage);
try {
router.handleMessage(badMessage);
fail();
} catch (MessageDeliveryException e) {
/* Success */
}
}

View File

@@ -67,14 +67,15 @@ public class PayloadTypeRouterTests {
router.setChannelMapping(String.class.getName(), "newChannel");
assertEquals(1, router.getChannelIdentifiers(message1).size());
assertEquals("newChannel", router.getChannelIdentifiers(message1).iterator().next());
// validate exception is thrown if mappings were removed and
// channelResolutionRequires = true (which is the default)
// validate nothing happens if mappings were removed and resolutionRequires = false
router.removeChannelMapping(String.class.getName());
router.removeChannelMapping(Integer.class.getName());
router.handleMessage(message1);
// validate exception is thrown if mappings were removed and resolutionRequires = true
router.setResolutionRequired(true);
try {
router.handleMessage(message1);
fail();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@ import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.MessageDeliveryException;
import org.springframework.integration.MessagingException;
import org.springframework.integration.channel.QueueChannel;
@@ -37,11 +38,12 @@ import org.springframework.util.CollectionUtils;
/**
* @author Mark Fisher
* @author Oleg Zhurakousky
* @author Gunnar Hillert
*/
public class RouterTests {
@Test
public void nullChannelIgnoredByDefault() {
@Test(expected = MessageDeliveryException.class)
public void nullChannelRaisesMessageDeliveryExceptionByDefault() {
AbstractMessageRouter router = new AbstractMessageRouter() {
@Override
protected List<Object> getChannelIdentifiers(Message<?> message) {
@@ -53,45 +55,7 @@ public class RouterTests {
}
@Test(expected = MessageDeliveryException.class)
public void nullChannelThrowsExceptionWhenResolutionRequired() {
AbstractMessageRouter router = new AbstractMessageRouter() {
@Override
protected List<Object> getChannelIdentifiers(Message<?> message) {
return null;
}
};
router.setResolutionRequired(true);
Message<String> message = new GenericMessage<String>("test");
router.handleMessage(message);
}
@Test
public void emptyChannelListIgnoredByDefault() {
AbstractMessageRouter router = new AbstractMessageRouter() {
@Override
protected List<Object> getChannelIdentifiers(Message<?> message) {
return null;
}
};
Message<String> message = new GenericMessage<String>("test");
router.handleMessage(message);
}
@Test(expected = MessageDeliveryException.class)
public void emptyChannelListThrowsExceptionWhenResolutionRequired() {
AbstractMessageRouter router = new AbstractMessageRouter() {
@Override
protected List<Object> getChannelIdentifiers(Message<?> message) {
return null;
}
};
router.setResolutionRequired(true);
Message<String> message = new GenericMessage<String>("test");
router.handleMessage(message);
}
@Test
public void nullChannelIdentifierIgnoredByDefault() {
public void nullChannelIdentifierUsingChannelResolverRaisesMessageDeliveryExceptionByDefault() {
AbstractMessageRouter router = new AbstractMessageRouter() {
@Override
protected List<Object> getChannelIdentifiers(Message<?> message) {
@@ -104,8 +68,8 @@ public class RouterTests {
router.handleMessage(message);
}
@Test
public void nullChannelIdentifierInListIgnoredByDefault() {
@Test(expected = MessageDeliveryException.class)
public void nullChannelIdentifierInListRaisesMessageDeliveryExceptionByDefault() {
AbstractMessageRouter router = new AbstractMessageRouter() {
@Override
protected List<Object> getChannelIdentifiers(Message<?> message) {
@@ -119,35 +83,7 @@ public class RouterTests {
}
@Test(expected = MessageDeliveryException.class)
public void nullChannelIdentifierTriggersExceptionWhenResolutionRequired() {
AbstractMessageRouter router = new AbstractMessageRouter() {
protected List<Object> getChannelIdentifiers(Message<?> message) {
return null;
}
};
TestChannelResolver channelResolver = new TestChannelResolver();
router.setChannelResolver(channelResolver);
router.setResolutionRequired(true);
Message<String> message = new GenericMessage<String>("test");
router.handleMessage(message);
}
@Test(expected = MessageDeliveryException.class)
public void nullChannelIdentifierInListTriggersExceptionWhenResolutionRequired() {
AbstractMessageRouter router = new AbstractMessageRouter() {
protected List<Object> getChannelIdentifiers(Message<?> message) {
return Collections.singletonList(null);
}
};
TestChannelResolver channelResolver = new TestChannelResolver();
router.setChannelResolver(channelResolver);
router.setResolutionRequired(true);
Message<String> message = new GenericMessage<String>("test");
router.handleMessage(message);
}
@Test
public void emptyChannelNameArrayIgnoredByDefault() {
public void emptyChannelNameArrayRaisesMessageDeliveryExceptionByDefault() {
AbstractMessageRouter router = new AbstractMessageRouter() {
protected List<Object> getChannelIdentifiers(Message<?> message) {
return new ArrayList<Object>();
@@ -159,21 +95,6 @@ public class RouterTests {
router.handleMessage(message);
}
@Test(expected = MessageDeliveryException.class)
public void emptyChannelNameArrayThrowsExceptionWhenResolutionRequired() {
AbstractMessageRouter router = new AbstractMessageRouter() {
@SuppressWarnings("unchecked")
protected List<Object> getChannelIdentifiers(Message<?> message) {
return CollectionUtils.arrayToList(new String[] {});
}
};
TestChannelResolver channelResolver = new TestChannelResolver();
router.setChannelResolver(channelResolver);
router.setResolutionRequired(true);
Message<String> message = new GenericMessage<String>("test");
router.handleMessage(message);
}
@Test(expected = MessagingException.class)
public void channelMappingIsRequiredWhenResolvingChannelNames() {
AbstractMessageRouter router = new AbstractMessageRouter() {
@@ -203,4 +124,282 @@ public class RouterTests {
assertEquals("test", reply.getPayload());
}
@Test
public void beanFactoryWithRouterAndMultipleCommaSeparatedChannelNames() {
AbstractMessageRouter router = new AbstractMessageRouter() {
@SuppressWarnings("unchecked")
protected List<Object> getChannelIdentifiers(Message<?> message) {
return CollectionUtils.arrayToList(new String[] { "testChannel1,testChannel2" });
}
};
QueueChannel testChannel1 = new QueueChannel();
QueueChannel testChannel2 = new QueueChannel();
GenericApplicationContext context = new GenericApplicationContext();
context.getBeanFactory().registerSingleton("testChannel1", testChannel1);
context.getBeanFactory().registerSingleton("testChannel2", testChannel2);
router.setBeanFactory(context);
router.handleMessage(new GenericMessage<String>("test"));
Message<?> reply1 = testChannel1.receive(0);
assertEquals("test", reply1.getPayload());
Message<?> reply2 = testChannel2.receive(0);
assertEquals("test", reply2.getPayload());
}
@Test(expected = MessagingException.class)
public void channelResolutionIsRequiredByDefault() {
AbstractMessageRouter router = new AbstractMessageRouter() {
@SuppressWarnings("unchecked")
protected List<Object> getChannelIdentifiers(Message<?> message) {
return CollectionUtils.arrayToList(new String[] { "testChannelDoesNotExist", "testChannel" });
}
};
QueueChannel testChannel = new QueueChannel();
GenericApplicationContext context = new GenericApplicationContext();
context.getBeanFactory().registerSingleton("testChannel", testChannel);
router.setBeanFactory(context);
router.handleMessage(new GenericMessage<String>("test"));
}
@Test
public void unresolvableChannelIdentifierInListAreIgnoredWhenResolutionRequiredIsFalse() {
AbstractMessageRouter router = new AbstractMessageRouter() {
@SuppressWarnings("unchecked")
protected List<Object> getChannelIdentifiers(Message<?> message) {
return CollectionUtils.arrayToList(new String[] { "testChannelDoesNotExist", "testChannel" });
}
};
router.setResolutionRequired(false);
QueueChannel testChannel = new QueueChannel();
GenericApplicationContext context = new GenericApplicationContext();
context.getBeanFactory().registerSingleton("testChannel", testChannel);
router.setBeanFactory(context);
router.handleMessage(new GenericMessage<String>("test"));
Message<?> reply = testChannel.receive(0);
assertEquals("test", reply.getPayload());
}
@Test
public void beanFactoryWithRouterAndChannelPrefix() {
AbstractMessageRouter router = new AbstractMessageRouter() {
@SuppressWarnings("unchecked")
protected List<Object> getChannelIdentifiers(Message<?> message) {
return CollectionUtils.arrayToList(new String[] { "MyChannel" });
}
};
router.setPrefix("testing_");
QueueChannel testChannel = new QueueChannel();
GenericApplicationContext context = new GenericApplicationContext();
context.getBeanFactory().registerSingleton("testing_MyChannel", testChannel);
router.setBeanFactory(context);
router.handleMessage(new GenericMessage<String>("test"));
Message<?> reply = testChannel.receive(0);
assertEquals("test", reply.getPayload());
}
@Test(expected = MessagingException.class)
public void beanFactoryWithRouterAndChannelPrefixFailing() {
AbstractMessageRouter router = new AbstractMessageRouter() {
@SuppressWarnings("unchecked")
protected List<Object> getChannelIdentifiers(Message<?> message) {
return CollectionUtils.arrayToList(new String[] { "testing_MyChannel" });
}
};
router.setPrefix("testing_");
QueueChannel testChannel = new QueueChannel();
GenericApplicationContext context = new GenericApplicationContext();
context.getBeanFactory().registerSingleton("testing_MyChannel", testChannel);
router.setBeanFactory(context);
router.handleMessage(new GenericMessage<String>("test"));
}
@Test
public void beanFactoryWithRouterAndChannelSuffix() {
AbstractMessageRouter router = new AbstractMessageRouter() {
@SuppressWarnings("unchecked")
protected List<Object> getChannelIdentifiers(Message<?> message) {
return CollectionUtils.arrayToList(new String[] { "MyChannel" });
}
};
router.setSuffix("_withSuffix");
QueueChannel testChannel = new QueueChannel();
GenericApplicationContext context = new GenericApplicationContext();
context.getBeanFactory().registerSingleton("MyChannel_withSuffix", testChannel);
router.setBeanFactory(context);
router.handleMessage(new GenericMessage<String>("test"));
Message<?> reply = testChannel.receive(0);
assertEquals("test", reply.getPayload());
}
@Test(expected = MessagingException.class)
public void beanFactoryWithRouterAndChannelSuffixFailing() {
AbstractMessageRouter router = new AbstractMessageRouter() {
@SuppressWarnings("unchecked")
protected List<Object> getChannelIdentifiers(Message<?> message) {
return CollectionUtils.arrayToList(new String[] { "MyChannel_withSuffix" });
}
};
router.setSuffix("_withSuffix");
QueueChannel testChannel = new QueueChannel();
GenericApplicationContext context = new GenericApplicationContext();
context.getBeanFactory().registerSingleton("MyChannel_withSuffix", testChannel);
router.setBeanFactory(context);
router.handleMessage(new GenericMessage<String>("test"));
}
@Test
public void beanFactoryWithRouterAndChannelIdentifiersInListWithinAList() {
AbstractMessageRouter router = new AbstractMessageRouter() {
@SuppressWarnings("unchecked")
protected List<Object> getChannelIdentifiers(Message<?> message) {
List<String> channelNames1 = CollectionUtils.arrayToList(new String[] { "channel1" });
List<String> channelNames2 = CollectionUtils.arrayToList(new String[] { "channel2" });
List<Object> listWithListOfChannelNames = new ArrayList<Object>();
listWithListOfChannelNames.add(channelNames1);
listWithListOfChannelNames.add(channelNames2);
return listWithListOfChannelNames;
}
};
QueueChannel testChannel1 = new QueueChannel();
QueueChannel testChannel2 = new QueueChannel();
GenericApplicationContext context = new GenericApplicationContext();
context.getBeanFactory().registerSingleton("channel1", testChannel1);
context.getBeanFactory().registerSingleton("channel2", testChannel2);
router.setBeanFactory(context);
router.handleMessage(new GenericMessage<String>("test"));
Message<?> reply1 = testChannel1.receive(0);
assertEquals("test", reply1.getPayload());
Message<?> reply2 = testChannel2.receive(0);
assertEquals("test", reply2.getPayload());
}
@Test
public void beanFactoryWithRouterAndChannelIdentifiersInMessageChannelArrayWithinAList() {
final QueueChannel testChannel1 = new QueueChannel();
final QueueChannel testChannel2 = new QueueChannel();
AbstractMessageRouter router = new AbstractMessageRouter() {
protected List<Object> getChannelIdentifiers(Message<?> message) {
MessageChannel[] channelNames1 = new MessageChannel[] { testChannel1 };
MessageChannel[] channelNames2 = new MessageChannel[] { testChannel2 };
List<Object> listWithListOfChannelNames = new ArrayList<Object>();
listWithListOfChannelNames.add(channelNames1);
listWithListOfChannelNames.add(channelNames2);
return listWithListOfChannelNames;
}
};
GenericApplicationContext context = new GenericApplicationContext();
context.getBeanFactory().registerSingleton("channel1", testChannel1);
context.getBeanFactory().registerSingleton("channel2", testChannel2);
router.setBeanFactory(context);
router.handleMessage(new GenericMessage<String>("test"));
Message<?> reply1 = testChannel1.receive(0);
assertEquals("test", reply1.getPayload());
Message<?> reply2 = testChannel2.receive(0);
assertEquals("test", reply2.getPayload());
}
@Test
public void beanFactoryWithRouterAndRetrieveChannelIdentifiersUsingDefaultConversionService() {
final QueueChannel testChannel1 = new QueueChannel();
final QueueChannel testChannel2 = new QueueChannel();
AbstractMessageRouter router = new AbstractMessageRouter() {
@SuppressWarnings("unchecked")
protected List<Object> getChannelIdentifiers(Message<?> message) {
return CollectionUtils.arrayToList(new Integer[] { 100, 200 });
}
};
GenericApplicationContext context = new GenericApplicationContext();
context.getBeanFactory().registerSingleton("100", testChannel1);
context.getBeanFactory().registerSingleton("200", testChannel2);
router.setBeanFactory(context);
router.handleMessage(new GenericMessage<String>("test"));
Message<?> reply1 = testChannel1.receive(0);
assertEquals("test", reply1.getPayload());
Message<?> reply2 = testChannel2.receive(0);
assertEquals("test", reply2.getPayload());
}
private class CustomObjectWithChannelName {
String channel = "channel1";
public String getChannel() {
return this.channel;
}
}
@Test(expected = MessagingException.class)
public void beanFactoryWithRouterAndRetrieveChannelIdentifierUsingDefaultConversionServiceFailing() {
final QueueChannel testChannel1 = new QueueChannel();
AbstractMessageRouter router = new AbstractMessageRouter() {
@SuppressWarnings("unchecked")
protected List<Object> getChannelIdentifiers(Message<?> message) {
return CollectionUtils.arrayToList(new CustomObjectWithChannelName[] { new CustomObjectWithChannelName() });
}
};
GenericApplicationContext context = new GenericApplicationContext();
context.getBeanFactory().registerSingleton("channel1", testChannel1);
router.setBeanFactory(context);
router.handleMessage(new GenericMessage<String>("test"));
}
}

View File

@@ -3,10 +3,10 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.0.xsd">
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd">
<int:router input-channel="inputChannel" default-output-channel="errorChannel" ignore-channel-name-resolution-failures="true" >
<int:router input-channel="inputChannel" default-output-channel="errorChannel" resolution-required="false">
<bean class="org.springframework.integration.router.config.RouterParserTests.NonExistingChannelRouter"/>
</int:router>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -49,6 +49,7 @@ import org.springframework.integration.test.util.TestUtils;
/**
* @author Mark Fisher
* @author Jonas Partner
* @author Gunnar Hillert
*/
public class RouterParserTests {
@@ -121,12 +122,11 @@ public class RouterParserTests {
input.send(new GenericMessage<Integer>(3));
}
@Test
public void testIgnoreChannelNameResolutionFailures() {
public void testResolutionRequiredIsTrue() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"routerParserTests.xml", this.getClass());
context.start();
MessageChannel input = (MessageChannel) context.getBean("ignoreChannelNameResolutionFailuresInput");
MessageChannel input = (MessageChannel) context.getBean("resolutionRequiredIsTrueInput");
input.send(new GenericMessage<String>("channelThatDoesNotExist"));
}
@@ -177,7 +177,7 @@ public class RouterParserTests {
assertEquals(new Integer(3), message3.getHeaders().getSequenceNumber());
assertEquals(new Integer(3), message3.getHeaders().getSequenceSize());
}
@Test
public void testErrorChannel(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(

View File

@@ -21,7 +21,7 @@
<router id="spelRouter" input-channel="expressionRouter" expression="payload.name"
default-output-channel="defaultChannelForExpression"
ignore-channel-name-resolution-failures="true">
resolution-required="false">
<mapping value="foo" channel="fooChannelForExpression"/>
<mapping value="bar" channel="barChannelForExpression"/>
</router>
@@ -40,7 +40,7 @@
<router input-channel="pojoRouter" ref="testBean"
default-output-channel="defaultChannelForPojo"
ignore-channel-name-resolution-failures="true">
resolution-required="false">
<mapping value="foo" channel="fooChannelForPojo"/>
<mapping value="bar" channel="barChannelForPojo"/>
</router>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -69,7 +69,6 @@ public class RouterWithMappingTests {
@Autowired
private PollableChannel defaultChannelForPojo;
@Test
public void expressionRouter() {
Message<?> message1 = MessageBuilder.withPayload(new TestBean("foo")).build();
@@ -115,7 +114,6 @@ public class RouterWithMappingTests {
assertNull(barChannelForPojo.receive(0));
}
private static class TestBean {
private final String name;

View File

@@ -73,9 +73,9 @@
<router id="resolutionRequiredRouter" ref="pojo" method="route" input-channel="inputForRouterRequiringResolution" resolution-required="true" />
<channel id="ignoreChannelNameResolutionFailuresInput"/>
<channel id="resolutionRequiredIsTrueInput"/>
<beans:bean id="payloadAsChannelNameRouter" class="org.springframework.integration.router.config.RouterParserTests$ReturnStringPassedInAsChannelNameRouter" />
<router id="ignoreChannelNameResolutionFailuresRouter" ref="payloadAsChannelNameRouter" input-channel="ignoreChannelNameResolutionFailuresInput" ignore-channel-name-resolution-failures="true" />
<router id="resolutionRequiredFalseRouter" ref="payloadAsChannelNameRouter" input-channel="resolutionRequiredIsTrueInput" resolution-required="false" />
<channel id="timeoutRouterChannel"/>
<router id="routerWithTimeout" ref="payloadAsChannelNameRouter" timeout="1234" input-channel="timeoutRouterChannel"/>

View File

@@ -342,98 +342,109 @@
</xsd:attribute>
</xsd:complexType>
<xsd:element name="xpath-router">
<xsd:complexType>
<xsd:annotation>
<xsd:documentation>
Defines an XPath router.
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element ref="xpath-expression" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="integration:poller" minOccurs="0" maxOccurs="1"/>
<xsd:element name="mapping" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:attribute name="value" type="xsd:string" />
<xsd:attribute name="channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type
type="org.springframework.integration.core.MessageChannel" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="evaluate-as-string" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
By default XPath expressions are evaluated as NODESET type and then converted
to a List of channel names, thus handling single channel scenarios as well as multiple.
However certain XPath expressions may evaluate as String type from the very
beginning (e.g., 'name(./node())' - which will return the name of the root node) thus resulting in
the exception if default evaluation type (NODESET) is used. This flag will allow you to manage the
evaluation type. It is TRUE by default, however if set to FALSE, the String evaluation type will be used.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="input-channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.core.MessageChannel"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="xpath-expression-ref" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.xml.xpath.XPathExpression"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="channel-resolver" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.core.ChannelResolver"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="resolution-required" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Specify whether this router should always be required to return at least one channel or name.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="ignore-channel-name-resolution-failures" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
Specify whether a failure to resolve a channel name returned by this router should be ignored.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="default-output-channel" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type
type="org.springframework.integration.core.MessageChannel" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<!-- XPath Router definition -->
<xsd:complexType name="commonXPathRouterType" abstract="true">
<xsd:complexContent>
<xsd:extension base="integration:abstractRouterType">
<xsd:attribute name="evaluate-as-string" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
By default XPath expressions are evaluated as NODESET type and then converted
to a List of channel names, thus handling single channel scenarios as well as multiple.
However certain XPath expressions may evaluate as String type from the very
beginning (e.g., 'name(./node())' - which will return the name of the root node) thus resulting in
the exception if default evaluation type (NODESET) is used.
This flag will allow you to manage the
evaluation type. It is 'false' by default, however if
set to 'true', then String evaluation type will be used.
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:union memberTypes="xsd:boolean xsd:string" />
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="xpath-expression-ref" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation>
Reference to the XPathExpression instance to be
evaluated against the input Message's payload. Either
this or 'xpath-expression' must be provided, but not
both.
</xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.xml.xpath.XPathExpression"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="XPathRouterType">
<xsd:complexContent>
<xsd:extension base="commonXPathRouterType">
<xsd:sequence>
<xsd:element ref="integration:poller" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="xpath-expression" minOccurs="0" maxOccurs="1"/>
<xsd:element name="mapping" type="integration:mappingValueChannelType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation><![CDATA[
If the values returned by the Xpaxth Expression
do not represent the channel names itself, additional
mappings can be specified using the mapping sub-element.
For example if the '/request/responders' expression
results in two values 'responderA' and 'responderB'
but you don't want to couple the responder names
to channel names you may provide additional mappings
such as:
<int-xml:mapping value="responderA" channel="channelA"/>
<int-xml:mapping value="responderB" channel="channelB"/>
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attributeGroup ref="integration:topLevelRouterAttributeGroup"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="XPathRouterTypeChain">
<xsd:complexContent>
<xsd:extension base="commonXPathRouterType">
<xsd:sequence>
<xsd:element ref="xpath-expression" minOccurs="0" maxOccurs="1"/>
<xsd:element name="mapping" type="integration:mappingValueChannelType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation><![CDATA[
If the values returned by the Xpaxth Expression
do not represent the channel names itself, additional
mappings can be specified using the mapping sub-element.
For example if the '/request/responders' expression
results in two values 'responderA' and 'responderB'
but you don't want to couple the responder names
to channel names you may provide additional mappings
such as:
<int-xml:mapping value="responderA" channel="channelA"/>
<int-xml:mapping value="responderB" channel="channelB"/>
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="xpath-router" type="XPathRouterType"/>
<xsd:element name="xpath-selector">
<xsd:complexType>
@@ -468,12 +479,26 @@
</xsd:element>
<xsd:element name="xpath-expression">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines an XPath expression.
Internally XPath expressions will be evaluated as
NODESET type and converted to a List<String>
representing channel names. Typically such list
will contain a single channel name. However, based
on the result of an XPath Expression the XPath router
can also take on the characteristics of the
Recipient List Router if the XPath Expression
returns more then one value, thus resulting in
the List<String> containing more then one channel
name.
In that case Message will be sent to all channels
in the list.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:annotation>
<xsd:documentation>
Defines an XPath expression.
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element ref="beans:map" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>

View File

@@ -125,19 +125,6 @@ public class XPathRouterParserTests {
inputChannel.send(docMessage);
assertEquals("Wrong number of messages", 1, outputChannel.getQueueSize());
}
@Test
public void testSetChannelResolver() throws Exception {
StringBuffer contextBuffer = new StringBuffer("<si-xml:xpath-router id='router' channel-resolver='stubResolver' input-channel='test-input'><si-xml:xpath-expression expression='/name'/></si-xml:xpath-router>");
contextBuffer.append("<bean id='stubResolver' class='").append(StubChannelResolver.class.getName()).append("'/>");
EventDrivenConsumer consumer = buildContext(contextBuffer.toString());
DirectFieldAccessor accessor = new DirectFieldAccessor(consumer);
Object handler = accessor.getPropertyValue("handler");
accessor = new DirectFieldAccessor(handler);
Object resolver = accessor.getPropertyValue("channelResolver");
assertEquals("Wrong channel resolver ",StubChannelResolver.class, resolver.getClass());
}
@Test
public void testSetResolutionRequiredFalse() throws Exception {
@@ -163,32 +150,6 @@ public class XPathRouterParserTests {
assertEquals("Resolution required not set to true ", true, resolutionRequired);
}
@Test
public void testIgnoreChannelNameResolutionFailuresFalse() throws Exception {
StringBuffer contextBuffer = new StringBuffer(
"<si-xml:xpath-router id='router' ignore-channel-name-resolution-failures='false' input-channel='test-input'><si-xml:xpath-expression expression='/name'/></si-xml:xpath-router>");
EventDrivenConsumer consumer = buildContext(contextBuffer.toString());
DirectFieldAccessor accessor = new DirectFieldAccessor(consumer);
Object handler = accessor.getPropertyValue("handler");
accessor = new DirectFieldAccessor(handler);
Object ignoreChannelNameResolutionFailures = accessor.getPropertyValue("ignoreChannelNameResolutionFailures");
assertEquals("ignoreChannelNameResolutionFailures not set to false", false, ignoreChannelNameResolutionFailures);
}
@Test
public void testIgnoreChannelNameResolutionFailuresTrue() throws Exception {
StringBuffer contextBuffer = new StringBuffer(
"<si-xml:xpath-router id='router' ignore-channel-name-resolution-failures='true' input-channel='test-input'><si-xml:xpath-expression expression='/name'/></si-xml:xpath-router>");
EventDrivenConsumer consumer = buildContext(contextBuffer.toString());
DirectFieldAccessor accessor = new DirectFieldAccessor(consumer);
Object handler = accessor.getPropertyValue("handler");
accessor = new DirectFieldAccessor(handler);
Object ignoreChannelNameResolutionFailures = accessor.getPropertyValue("ignoreChannelNameResolutionFailures");
assertEquals("ignoreChannelNameResolutionFailures not set to true ", true, ignoreChannelNameResolutionFailures);
}
@Test
public void testSetDefaultOutputChannel() throws Exception {
StringBuffer contextBuffer = new StringBuffer("<si-xml:xpath-router id='router' default-output-channel='defaultOutput' input-channel='test-input'><si-xml:xpath-expression expression='/name'/></si-xml:xpath-router>");