INT-2893: fix chain -> router -> bean or script
* add XSD element for nested router type * add tests on the matter * polishing for RouterParserTests JIRA: https://jira.springsource.org/browse/INT-2893 INT-2893: Polishing INT-2893: after rebasing to 3.0 XSD changes reverted from 2.2 and moved to 3.0 INT-2893 Polishing Factor out common elements; fixing missing documentation for `expression` within a `router` within a `chain`.
This commit is contained in:
committed by
Gary Russell
parent
90c54c5f74
commit
dc59207df2
@@ -34,24 +34,24 @@
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
|
||||
<xsd:element name="transaction-synchronization-factory">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Allows you to configure org.springframework.integration.transaction.DefaultTransactionSynchronizationFactory
|
||||
This implementation of org.springframework.integration.transaction.TransactionSynchronizationFactory
|
||||
allows you to configure SpEL expressions, with their execution being coordinated (synchronized) with a
|
||||
transaction - see {TransactionSynchronization}. Expressions for before-commit, after.-commit, and after-rollback
|
||||
allows you to configure SpEL expressions, with their execution being coordinated (synchronized) with a
|
||||
transaction - see {TransactionSynchronization}. Expressions for before-commit, after.-commit, and after-rollback
|
||||
are supported, together with a channel for each where the evaluation result (if any) will be sent.
|
||||
For each sub-element you can specify 'expression' and/or 'channel' attributes.
|
||||
If only the 'channel' attribute is present the received Message will be sent there as part of a particular synchronization scenario.
|
||||
If only the 'expression' attribute is present and the result of an expression is a non-Null value, a Message with the
|
||||
result as the payload will be generated and sent to a default channel (NullChannel) and will appear in the logs.
|
||||
If you want the evaluation result to go to a specific channel add a 'channel' attribute. If the result of an expression is null
|
||||
If only the 'expression' attribute is present and the result of an expression is a non-Null value, a Message with the
|
||||
result as the payload will be generated and sent to a default channel (NullChannel) and will appear in the logs.
|
||||
If you want the evaluation result to go to a specific channel add a 'channel' attribute. If the result of an expression is null
|
||||
or void, no Message will be generated.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="before-commit" minOccurs="0" maxOccurs="1">
|
||||
<xsd:complexType>
|
||||
@@ -72,7 +72,7 @@
|
||||
<xsd:attribute name="id" type="xsd:string" use="required"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
|
||||
<xsd:attributeGroup name="synchronizationAttributeGroup">
|
||||
<xsd:attribute name="expression" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
@@ -3459,7 +3459,7 @@ is provided, the return value is expected to match a channel name exactly.
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Reference to an instance of org.springframework.integration.transaction.TransactionSynchronizationFactory
|
||||
which will return an instance of org.springframework.transaction.support.TransactionSynchronization via its create(..) method.
|
||||
which will return an instance of org.springframework.transaction.support.TransactionSynchronization via its create(..) method.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
@@ -3497,7 +3497,7 @@ is provided, the return value is expected to match a channel name exactly.
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Reference to an instance of org.springframework.integration.transaction.TransactionSynchronizationFactory
|
||||
which will return an instance of org.springframework.transaction.support.TransactionSynchronization via its create(..) method.
|
||||
which will return an instance of org.springframework.transaction.support.TransactionSynchronization via its create(..) method.
|
||||
Setting of this attribute will only have an affect if a Transaction advice is present in the chain.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
|
||||
@@ -2555,34 +2555,7 @@
|
||||
<xsd:extension base="commonRouterType">
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="poller" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="expression" type="innerExpressionType" minOccurs="0" maxOccurs="1">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
You can use SpEL Expressions to implement simple
|
||||
computations. Generally a SpEL expression is evaluated
|
||||
and the result is either a channel name or
|
||||
alternatively the result can be mapped to a channel using the
|
||||
'mapping' sub-element.
|
||||
|
||||
The SpEL expression can return a Collection,
|
||||
effectively making this Router a Dynamic Recipient List
|
||||
Router. Whenever the expression returns multiple
|
||||
channel values the Message will be forwarded to
|
||||
each channel.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="mapping" type="mappingValueChannelType" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Defines mapping rules for this router
|
||||
(e.g., mapping value='foo' channel='myChannel')
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:any namespace="##other" processContents="strict" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:group ref="routerCommonGroup" />
|
||||
</xsd:sequence>
|
||||
<xsd:attributeGroup ref="topLevelRouterAttributeGroup"/>
|
||||
</xsd:extension>
|
||||
@@ -2593,21 +2566,45 @@
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="commonRouterType">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="expression" type="innerExpressionType" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="mapping" type="mappingValueChannelType" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Defines mapping rules for this router
|
||||
(e.g., mapping value='foo' channel='myChannel')
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:group ref="routerCommonGroup" />
|
||||
</xsd:sequence>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:group name="routerCommonGroup">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="expression" type="innerExpressionType" minOccurs="0" maxOccurs="1">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
You can use SpEL Expressions to implement simple
|
||||
computations. Generally a SpEL expression is evaluated
|
||||
and the result is either a channel name or
|
||||
alternatively the result can be mapped to a channel using the
|
||||
'mapping' sub-element.
|
||||
|
||||
The SpEL expression can return a Collection,
|
||||
effectively making this Router a Dynamic Recipient List
|
||||
Router. Whenever the expression returns multiple
|
||||
channel values the Message will be forwarded to
|
||||
each channel.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="mapping" type="mappingValueChannelType" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Defines mapping rules for this router
|
||||
(e.g., mapping value='foo' channel='myChannel')
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:any namespace="##other" processContents="strict" minOccurs="0" maxOccurs="1" />
|
||||
</xsd:sequence>
|
||||
</xsd:group>
|
||||
|
||||
<!-- Type definitions used by the Header Value Router -->
|
||||
|
||||
<xsd:complexType name="commonHeaderValueRouterType" abstract="true">
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
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.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" resolution-required="false">
|
||||
<bean class="org.springframework.integration.router.config.RouterParserTests.NonExistingChannelRouter"/>
|
||||
</int:router>
|
||||
|
||||
</beans>
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="input"/>
|
||||
|
||||
@@ -68,18 +68,33 @@
|
||||
<beans:bean id="annotated" class="org.springframework.integration.router.config.RouterParserTests$AnnotatedTestRouterBean">
|
||||
<beans:constructor-arg ref="output4"/>
|
||||
</beans:bean>
|
||||
|
||||
|
||||
<channel id="inputForRouterRequiringResolution"/>
|
||||
|
||||
|
||||
<router id="resolutionRequiredRouter" ref="pojo" method="route" input-channel="inputForRouterRequiringResolution" resolution-required="true" />
|
||||
|
||||
<channel id="resolutionRequiredIsTrueInput"/>
|
||||
|
||||
<beans:bean id="payloadAsChannelNameRouter" class="org.springframework.integration.router.config.RouterParserTests$ReturnStringPassedInAsChannelNameRouter" />
|
||||
<router id="resolutionRequiredFalseRouter" ref="payloadAsChannelNameRouter" input-channel="resolutionRequiredIsTrueInput" resolution-required="false" />
|
||||
|
||||
<router id="resolutionRequiredFalseRouter" ref="payloadAsChannelNameRouter" input-channel="resolutionRequiredIsFalseInput" resolution-required="false" />
|
||||
|
||||
<channel id="timeoutRouterChannel"/>
|
||||
|
||||
<router id="routerWithTimeout" ref="payloadAsChannelNameRouter" timeout="1234" input-channel="timeoutRouterChannel"/>
|
||||
|
||||
<router input-channel="routerNestedBeanChannel" method="route">
|
||||
<beans:bean class="org.springframework.integration.router.config.TestRouter"/>
|
||||
</router>
|
||||
|
||||
<chain input-channel="chainRouterNestedBeanChannel">
|
||||
<router method="route">
|
||||
<beans:bean class="org.springframework.integration.router.config.TestRouter"/>
|
||||
</router>
|
||||
</chain>
|
||||
|
||||
<router input-channel="routerAndErrorChannelInputChannel" default-output-channel="errorChannel" resolution-required="false">
|
||||
<beans:bean class="org.springframework.integration.router.config.RouterParserTests.NonExistingChannelRouter"/>
|
||||
</router>
|
||||
|
||||
<beans:bean id="testChannelResolver"
|
||||
class="org.springframework.integration.router.config.RouterParserTests$TestChannelResover"/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
* Copyright 2002-2013 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.config;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -27,15 +28,16 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.MessageChannel;
|
||||
import org.springframework.integration.MessageDeliveryException;
|
||||
import org.springframework.integration.annotation.Router;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.core.MessageHandler;
|
||||
import org.springframework.integration.core.MessagingTemplate;
|
||||
import org.springframework.integration.core.PollableChannel;
|
||||
@@ -43,118 +45,149 @@ import org.springframework.integration.core.SubscribableChannel;
|
||||
import org.springframework.integration.message.GenericMessage;
|
||||
import org.springframework.integration.router.AbstractMappingMessageRouter;
|
||||
import org.springframework.integration.router.MethodInvokingRouter;
|
||||
import org.springframework.integration.support.channel.ChannelResolutionException;
|
||||
import org.springframework.integration.support.channel.ChannelResolver;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Jonas Partner
|
||||
* @author Gunnar Hillert
|
||||
* @author Artem Bilan
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class RouterParserTests {
|
||||
|
||||
@Autowired
|
||||
private PollableChannel output1;
|
||||
|
||||
@Autowired
|
||||
private PollableChannel output2;
|
||||
@Autowired
|
||||
private MessageChannel input;
|
||||
|
||||
@Autowired
|
||||
private MessageChannel inputForRouterWithDefaultOutput;
|
||||
|
||||
@Autowired
|
||||
private PollableChannel defaultOutput;
|
||||
|
||||
@Autowired
|
||||
private MessageChannel inputForAbstractMessageRouterImplementation;
|
||||
|
||||
@Autowired
|
||||
private PollableChannel output3;
|
||||
|
||||
@Autowired
|
||||
private MessageChannel inputForAnnotatedRouter;
|
||||
|
||||
@Autowired
|
||||
private PollableChannel output4;
|
||||
|
||||
@Autowired
|
||||
private MessageChannel inputForRouterRequiringResolution;
|
||||
|
||||
@Autowired
|
||||
private MessageChannel resolutionRequiredIsFalseInput;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("routerWithTimeout.handler")
|
||||
private MessageHandler routerWithTimeout;
|
||||
|
||||
@Autowired
|
||||
private MessageChannel sequenceRouter;
|
||||
|
||||
@Autowired
|
||||
private PollableChannel sequenceOut1;
|
||||
|
||||
@Autowired
|
||||
private PollableChannel sequenceOut2;
|
||||
|
||||
@Autowired
|
||||
private PollableChannel sequenceOut3;
|
||||
|
||||
@Autowired
|
||||
private MessageChannel routerNestedBeanChannel;
|
||||
|
||||
@Autowired
|
||||
private MessageChannel chainRouterNestedBeanChannel;
|
||||
|
||||
@Autowired
|
||||
private MessageChannel routerAndErrorChannelInputChannel;
|
||||
|
||||
@Autowired
|
||||
private SubscribableChannel errorChannel;
|
||||
|
||||
@Test
|
||||
public void testRouter() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"routerParserTests.xml", this.getClass());
|
||||
context.start();
|
||||
MessageChannel input = (MessageChannel) context.getBean("input");
|
||||
PollableChannel output1 = (PollableChannel) context.getBean("output1");
|
||||
PollableChannel output2 = (PollableChannel) context.getBean("output2");
|
||||
input.send(new GenericMessage<String>("1"));
|
||||
Message<?> result1 = output1.receive(1000);
|
||||
this.input.send(new GenericMessage<String>("1"));
|
||||
Message<?> result1 = this.output1.receive(1000);
|
||||
assertEquals("1", result1.getPayload());
|
||||
assertNull(output2.receive(0));
|
||||
input.send(new GenericMessage<String>("2"));
|
||||
Message<?> result2 = output2.receive(1000);
|
||||
Message<?> result2 = this.output2.receive(1000);
|
||||
assertEquals("2", result2.getPayload());
|
||||
assertNull(output1.receive(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRouterWithDefaultOutputChannel() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"routerParserTests.xml", this.getClass());
|
||||
context.start();
|
||||
MessageChannel input = (MessageChannel) context.getBean("inputForRouterWithDefaultOutput");
|
||||
PollableChannel output1 = (PollableChannel) context.getBean("output1");
|
||||
PollableChannel output2 = (PollableChannel) context.getBean("output2");
|
||||
PollableChannel defaultOutput = (PollableChannel) context.getBean("defaultOutput");
|
||||
input.send(new GenericMessage<String>("99"));
|
||||
assertNull(output1.receive(0));
|
||||
assertNull(output2.receive(0));
|
||||
Message<?> result = defaultOutput.receive(0);
|
||||
this.inputForRouterWithDefaultOutput.send(new GenericMessage<String>("99"));
|
||||
assertNull(this.output1.receive(0));
|
||||
assertNull(this.output2.receive(0));
|
||||
Message<?> result = this.defaultOutput.receive(0);
|
||||
assertEquals("99", result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refOnlyForAbstractMessageRouterImplementation() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"routerParserTests.xml", this.getClass());
|
||||
context.start();
|
||||
MessageChannel input = (MessageChannel) context.getBean("inputForAbstractMessageRouterImplementation");
|
||||
PollableChannel output = (PollableChannel) context.getBean("output3");
|
||||
input.send(new GenericMessage<String>("test-implementation"));
|
||||
Message<?> result = output.receive(0);
|
||||
this.inputForAbstractMessageRouterImplementation.send(new GenericMessage<String>("test-implementation"));
|
||||
Message<?> result = this.output3.receive(1000);
|
||||
assertNotNull(result);
|
||||
assertEquals("test-implementation", result.getPayload());
|
||||
assertEquals("test-implementation", result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refOnlyForAnnotatedObject() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"routerParserTests.xml", this.getClass());
|
||||
context.start();
|
||||
MessageChannel input = (MessageChannel) context.getBean("inputForAnnotatedRouter");
|
||||
PollableChannel output = (PollableChannel) context.getBean("output4");
|
||||
input.send(new GenericMessage<String>("test-annotation"));
|
||||
Message<?> result = output.receive(0);
|
||||
this.inputForAnnotatedRouter.send(new GenericMessage<String>("test-annotation"));
|
||||
Message<?> result = this.output4.receive(1000);
|
||||
assertNotNull(result);
|
||||
assertEquals("test-annotation", result.getPayload());
|
||||
}
|
||||
|
||||
@Test(expected=MessageDeliveryException.class)
|
||||
public void testResolutionRequired() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"routerParserTests.xml", this.getClass());
|
||||
context.start();
|
||||
MessageChannel input = (MessageChannel) context.getBean("inputForRouterRequiringResolution");
|
||||
input.send(new GenericMessage<Integer>(3));
|
||||
assertEquals("test-annotation", result.getPayload());
|
||||
}
|
||||
|
||||
public void testResolutionRequiredIsTrue() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"routerParserTests.xml", this.getClass());
|
||||
context.start();
|
||||
MessageChannel input = (MessageChannel) context.getBean("resolutionRequiredIsTrueInput");
|
||||
input.send(new GenericMessage<String>("channelThatDoesNotExist"));
|
||||
@Test
|
||||
public void testResolutionRequired() {
|
||||
try {
|
||||
this.inputForRouterRequiringResolution.send(new GenericMessage<Integer>(3));
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertTrue(e.getCause() instanceof ChannelResolutionException);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected=MessageDeliveryException.class)
|
||||
public void testResolutionRequiredIsFalse() {
|
||||
this.resolutionRequiredIsFalseInput.send(new GenericMessage<String>("channelThatDoesNotExist"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void timeoutValueConfigured() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"routerParserTests.xml", this.getClass());
|
||||
Object endpoint = context.getBean("routerWithTimeout");
|
||||
MethodInvokingRouter router = TestUtils.getPropertyValue(endpoint, "handler", MethodInvokingRouter.class);
|
||||
MessagingTemplate template = (MessagingTemplate)
|
||||
new DirectFieldAccessor(router).getPropertyValue("messagingTemplate");
|
||||
Long timeout = (Long) new DirectFieldAccessor(template).getPropertyValue("sendTimeout");
|
||||
assertTrue(this.routerWithTimeout instanceof MethodInvokingRouter);
|
||||
MessagingTemplate template = TestUtils.getPropertyValue(this.routerWithTimeout, "messagingTemplate", MessagingTemplate.class);
|
||||
Long timeout = TestUtils.getPropertyValue(template, "sendTimeout", Long.class);
|
||||
assertEquals(new Long(1234), timeout);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sequence() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"routerParserTests.xml", this.getClass());
|
||||
MessageChannel input = context.getBean("sequenceRouter", MessageChannel.class);
|
||||
PollableChannel out1 = context.getBean("sequenceOut1", PollableChannel.class);
|
||||
PollableChannel out2 = context.getBean("sequenceOut2", PollableChannel.class);
|
||||
PollableChannel out3 = context.getBean("sequenceOut3", PollableChannel.class);
|
||||
Message<?> originalMessage = new GenericMessage<String>("test");
|
||||
input.send(originalMessage);
|
||||
Message<?> message1 = out1.receive(0);
|
||||
Message<?> message2 = out2.receive(0);
|
||||
Message<?> message3 = out3.receive(0);
|
||||
this.sequenceRouter.send(originalMessage);
|
||||
Message<?> message1 = this.sequenceOut1.receive(1000);
|
||||
Message<?> message2 = this.sequenceOut2.receive(1000);
|
||||
Message<?> message3 = this.sequenceOut3.receive(1000);
|
||||
assertEquals(originalMessage.getHeaders().getId(), message1.getHeaders().getCorrelationId());
|
||||
assertEquals(originalMessage.getHeaders().getId(), message2.getHeaders().getCorrelationId());
|
||||
assertEquals(originalMessage.getHeaders().getId(), message3.getHeaders().getCorrelationId());
|
||||
@@ -166,23 +199,44 @@ public class RouterParserTests {
|
||||
assertEquals(new Integer(3), message3.getHeaders().getSequenceSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInt2893RouterNestedBean() {
|
||||
this.routerNestedBeanChannel.send(new GenericMessage<String>("1"));
|
||||
Message<?> result1 = this.output1.receive(1000);
|
||||
assertEquals("1", result1.getPayload());
|
||||
assertNull(this.output2.receive(0));
|
||||
this.routerNestedBeanChannel.send(new GenericMessage<String>("2"));
|
||||
Message<?> result2 = this.output2.receive(1000);
|
||||
assertEquals("2", result2.getPayload());
|
||||
assertNull(this.output1.receive(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInt2893RouterNestedBeanWithinChain() {
|
||||
this.chainRouterNestedBeanChannel.send(new GenericMessage<String>("1"));
|
||||
Message<?> result1 = this.output1.receive(1000);
|
||||
assertEquals("1", result1.getPayload());
|
||||
assertNull(this.output2.receive(0));
|
||||
this.chainRouterNestedBeanChannel.send(new GenericMessage<String>("2"));
|
||||
Message<?> result2 = this.output2.receive(1000);
|
||||
assertEquals("2", result2.getPayload());
|
||||
assertNull(this.output1.receive(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testErrorChannel(){
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"ErrorChannelRoutingTests-context.xml", this.getClass());
|
||||
MessageHandler handler = mock(MessageHandler.class);
|
||||
DirectChannel inputChannel = context.getBean("inputChannel", DirectChannel.class);
|
||||
SubscribableChannel errorChannel = context.getBean("errorChannel", SubscribableChannel.class);
|
||||
errorChannel.subscribe(handler);
|
||||
inputChannel.send(new GenericMessage<String>("fail"));
|
||||
this.errorChannel.subscribe(handler);
|
||||
this.routerAndErrorChannelInputChannel.send(new GenericMessage<String>("fail"));
|
||||
verify(handler, times(1)).handleMessage(Mockito.any(Message.class));
|
||||
}
|
||||
|
||||
|
||||
@Test // should not fail
|
||||
public void routerFactoryBeanTest(){
|
||||
new ClassPathXmlApplicationContext("rfb-fix-config.xml", this.getClass());
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class NonExistingChannelRouter{
|
||||
public String route(String payload){
|
||||
return "foo";
|
||||
@@ -218,7 +272,7 @@ public class RouterParserTests {
|
||||
return this.channel;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class ReturnStringPassedInAsChannelNameRouter {
|
||||
|
||||
@Router
|
||||
@@ -226,7 +280,7 @@ public class RouterParserTests {
|
||||
return (String)message.getPayload();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -28,6 +28,9 @@ public class TestRouter {
|
||||
if (input == 2) {
|
||||
return "output2";
|
||||
}
|
||||
if (input == 3) {
|
||||
return "channelDoesNotExist";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,10 +23,21 @@
|
||||
|
||||
<router input-channel="inlineScriptInput">
|
||||
<int-script:script lang="javascript"><![CDATA[
|
||||
(function(){
|
||||
return payload.length > 5 ? "longStrings" : "shortStrings";
|
||||
})();
|
||||
(function(){
|
||||
return payload.length > 5 ? "longStrings" : "shortStrings";
|
||||
})();
|
||||
]]></int-script:script>
|
||||
</router>
|
||||
|
||||
<chain input-channel="scriptRouterWithinChainInput">
|
||||
<router>
|
||||
<int-script:script lang="javascript"><![CDATA[
|
||||
(function(){
|
||||
return payload.length > 5 ? "longStrings" : "shortStrings";
|
||||
})();
|
||||
]]></int-script:script>
|
||||
</router>
|
||||
</chain>
|
||||
|
||||
|
||||
</beans:beans>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -33,6 +33,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author David Turanski
|
||||
* @author Artem Bilan
|
||||
* @since 2.1
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@@ -45,6 +46,9 @@ public class Jsr223RouterTests {
|
||||
@Autowired
|
||||
private MessageChannel inlineScriptInput;
|
||||
|
||||
@Autowired
|
||||
private MessageChannel scriptRouterWithinChainInput;
|
||||
|
||||
@Autowired
|
||||
private PollableChannel longStrings;
|
||||
|
||||
@@ -94,4 +98,25 @@ public class Jsr223RouterTests {
|
||||
assertNull(longStrings.receive(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInt2893ScriptRouterWithinChain() {
|
||||
Message<?> message1 = new GenericMessage<String>("aardvark");
|
||||
Message<?> message2 = new GenericMessage<String>("bear");
|
||||
Message<?> message3 = new GenericMessage<String>("cat");
|
||||
Message<?> message4 = new GenericMessage<String>("dog");
|
||||
Message<?> message5 = new GenericMessage<String>("elephant");
|
||||
this.scriptRouterWithinChainInput.send(message1);
|
||||
this.scriptRouterWithinChainInput.send(message2);
|
||||
this.scriptRouterWithinChainInput.send(message3);
|
||||
this.scriptRouterWithinChainInput.send(message4);
|
||||
this.scriptRouterWithinChainInput.send(message5);
|
||||
assertEquals("bear", shortStrings.receive(0).getPayload());
|
||||
assertEquals("cat", shortStrings.receive(0).getPayload());
|
||||
assertEquals("dog", shortStrings.receive(0).getPayload());
|
||||
assertEquals("aardvark", longStrings.receive(0).getPayload());
|
||||
assertEquals("elephant", longStrings.receive(0).getPayload());
|
||||
assertNull(shortStrings.receive(0));
|
||||
assertNull(longStrings.receive(0));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user