Merged FlowMessageHandler

This commit is contained in:
David Turanski
2011-12-07 12:30:13 -05:00
40 changed files with 1399 additions and 424 deletions

397
pom.xml
View File

@@ -1,212 +1,187 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<!-- This POM is generated by the maven archetype cic-component-archetype.
It includes a comprehensive set of dependencies for developing a CIC component.
Please remove any dependencies that you do not need. If you require additional
dependencies, the approved version should be inherited from the cic-parent
POM. DO NOT DECLARE explicit dependency versions here. -->
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-flow</artifactId>
<version>2.1.0.M1</version>
<name>Spring Integration Flow Support</name>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<properties>
<project.build.sourceEncoding>UTF8</project.build.sourceEncoding>
<spring.framework.version>3.1.0.RC1</spring.framework.version>
<spring.integration.version>2.1.0.M2</spring.integration.version>
<maven.test.search.classdir>true</maven.test.search.classdir>
</properties>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-test</artifactId>
<version>${spring.integration.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.framework.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${spring.framework.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.framework.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-scripting</artifactId>
<version>${spring.integration.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
<version>${spring.integration.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-jmx</artifactId>
<version>${spring.integration.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.framework.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.framework.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.framework.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-asm</artifactId>
<version>${spring.framework.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.framework.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-xml</artifactId>
<version>${spring.integration.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.framework.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>xmlunit</groupId>
<artifactId>xmlunit</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Generate JAXB classes from schema into target -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<configuration>
<tasks>
<taskdef name="groovyc" classname="org.codehaus.groovy.ant.Groovyc">
<classpath refid="maven.test.classpath" />
</taskdef>
<groovyc destdir="${project.build.testOutputDirectory}"
srcdir="${basedir}/src/test/java/" listfiles="true">
<classpath refid="maven.test.classpath" />
</groovyc>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>maven_springframework_milestone</id>
<url>http://maven.springframework.org/milestone</url>
</repository>
<repository>
<id>maven_springframework_snapshot</id>
<url>http://maven.springframework.org/snapshot</url>
</repository>
</repositories>
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-flow</artifactId>
<version>2.1.0.M1</version>
<name>Spring Integration Flow Support</name>
<properties>
<spring.version>3.1.0.RC1</spring.version>
<spring.integration.version>2.1.0.M2</spring.integration.version>
<project.build.sourceEncoding>UTF8</project.build.sourceEncoding>
</properties>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*</include>
</includes>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>
<testResources>
<testResource>
<directory>src/test/java</directory>
<includes>
<include>**/*</include>
</includes>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</testResource>
<testResource>
<directory>src/test/resources</directory>
<includes>
<include>**/*</include>
</includes>
</testResource>
</testResources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<includes>
<include>**/*Tests.java</include>
</includes>
<excludes>
<exclude>**/*Abstract*.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>SpringSource External Bundle Repository</id>
<url>http://repository.springsource.com/maven/bundles/external/</url>
</repository>
<repository>
<id>SpringSource Milestone Repository</id>
<url>http://maven.springframework.org/milestone/</url>
</repository>
<repository>
<id>SpringSource Release Bundle Repository</id>
<url>http://repository.springsource.com/maven/bundles/release/</url>
</repository>
<repository>
<id>SpringSource Release Repository</id>
<url>http://maven.springframework.org/release/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-test</artifactId>
<version>${spring.integration.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>2.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
<version>${spring.integration.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>2.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymockclassextension</artifactId>
<version>2.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-groovy</artifactId>
<version>${spring.integration.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.8.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-jmx</artifactId>
<version>${spring.integration.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit-dep</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -21,81 +21,81 @@ package org.springframework.integration.flow;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Container for {@link Flow} {@link PortConfiguration} metadata
* @author David Turanski
*
*
*/
public class ChannelNamePortConfiguration implements PortConfiguration {
private PortMetadata inputPortMetadata;
private List<PortMetadata> outputPortMetadataList;
/**
* Generic configuration
* @param inputPortMetadata metadata defining the input message port
* @param outputPortMetadataList a list of metadata defining multiple output message ports
*/
public ChannelNamePortConfiguration(PortMetadata inputPortMetadata, List<PortMetadata> outputPortMetadataList) {
this.outputPortMetadataList = outputPortMetadataList;
this.inputPortMetadata = inputPortMetadata;
}
private PortMetadata inputPortMetadata;
/**
* A simple configuration for a flow with one input and one output port
* @param inputChannelName
* @param outputChannelName
*/
public ChannelNamePortConfiguration(String inputChannelName, String outputChannelName) {
this.inputPortMetadata = new PortMetadata("input", inputChannelName);
private List<PortMetadata> outputPortMetadataList;
if (outputChannelName != null) {
PortMetadata outputPortMetadata = new PortMetadata("output", outputChannelName);
this.outputPortMetadataList = Collections.singletonList(outputPortMetadata);
} else {
// this.outputPortMetadataList = new ArrayList<PortMetadata>();
}
}
/**
* Generic configuration
* @param inputPortMetadata metadata defining the input message port
* @param outputPortMetadataList a list of metadata defining multiple output
* message ports
*/
public ChannelNamePortConfiguration(PortMetadata inputPortMetadata, List<PortMetadata> outputPortMetadataList) {
this.outputPortMetadataList = outputPortMetadataList;
this.inputPortMetadata = inputPortMetadata;
}
@Override
public String getInputPortName() {
return this.inputPortMetadata.getPortName();
}
/**
* A simple configuration for a flow with one input and one output port
* @param inputChannelName
* @param outputChannelName
*/
public ChannelNamePortConfiguration(String inputChannelName, String outputChannelName) {
this.inputPortMetadata = new PortMetadata("input", inputChannelName);
@Override
public String getInputChannel() {
return this.inputPortMetadata.getChannelName();
}
if (outputChannelName != null) {
PortMetadata outputPortMetadata = new PortMetadata("output", outputChannelName);
this.outputPortMetadataList = Collections.singletonList(outputPortMetadata);
}
else {
// this.outputPortMetadataList = new ArrayList<PortMetadata>();
}
}
@Override
public String getOutputChannel(String portName) {
PortMetadata portMetadata = (PortMetadata) findOutputPort(portName);
if (portMetadata != null) {
return portMetadata.getChannelName();
}
return null;
}
public String getInputPortName() {
return this.inputPortMetadata.getPortName();
}
@Override
public List<String> getOutputPortNames() {
List<String> results = new ArrayList<String>();
if (outputPortMetadataList != null) {
for (PortMetadata portMetadata : outputPortMetadataList) {
results.add(portMetadata.getPortName());
}
}
return results;
}
public String getInputChannel() {
return this.inputPortMetadata.getChannelName();
}
private PortMetadata findOutputPort(String portName) {
if (outputPortMetadataList != null) {
for (PortMetadata portMetadata : outputPortMetadataList) {
if (portName.equals(portMetadata.getPortName())) {
return portMetadata;
}
}
}
return null;
}
public String getOutputChannel(String portName) {
PortMetadata portMetadata = findOutputPort(portName);
if (portMetadata != null) {
return portMetadata.getChannelName();
}
return null;
}
public List<String> getOutputPortNames() {
List<String> results = new ArrayList<String>();
if (outputPortMetadataList != null) {
for (PortMetadata portMetadata : outputPortMetadataList) {
results.add(portMetadata.getPortName());
}
}
return results;
}
private PortMetadata findOutputPort(String portName) {
if (outputPortMetadataList != null) {
for (PortMetadata portMetadata : outputPortMetadataList) {
if (portName.equals(portMetadata.getPortName())) {
return portMetadata;
}
}
}
return null;
}
}

View File

@@ -12,16 +12,13 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.beans.factory.support.BeanDefinitionValidationException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.channel.AbstractMessageChannel;
import org.springframework.integration.channel.PublishSubscribeChannel;
import org.springframework.integration.core.SubscribableChannel;
import org.springframework.integration.flow.config.FlowUtils;
import org.springframework.integration.flow.interceptor.FlowInterceptor;
@@ -101,7 +98,6 @@ public class Flow implements InitializingBean, BeanNameAware, ChannelResolver, A
this.configLocations = configLocations;
}
@Override
public void afterPropertiesSet() {
if (this.flowId == null) {
@@ -157,7 +153,6 @@ public class Flow implements InitializingBean, BeanNameAware, ChannelResolver, A
return this.flowConfiguration;
}
@Override
public void setBeanName(String name) {
this.beanName = name;
@@ -221,20 +216,18 @@ public class Flow implements InitializingBean, BeanNameAware, ChannelResolver, A
* @param the publish-subscribe channel
*/
public void setFlowOutputChannel(SubscribableChannel flowOutputChannel) {
this.flowOutputChannel = flowOutputChannel;
this.flowOutputChannel = flowOutputChannel;
}
@Override
public MessageChannel resolveChannelName(String channelName) {
return flowChannelResolver.resolveChannelName(channelName);
}
private void addReferencedProperties() {
if (flowProperties != null) {
PropertySource<?> propertySource = new PropertiesPropertySource("flowProperties", flowProperties);
MutablePropertySources propertySources = flowContext.getEnvironment().getPropertySources();
propertySources.addLast(propertySource);
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
ppc.setProperties(flowProperties);
flowContext.addBeanFactoryPostProcessor(ppc);
}
}
@@ -284,7 +277,6 @@ public class Flow implements InitializingBean, BeanNameAware, ChannelResolver, A
}
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}

View File

@@ -23,11 +23,6 @@ public interface FlowConstants {
*/
public static final String FLOW_OUTPUT_PORT_HEADER = "flow.output.port";
/**
* Message header used to correlate port input and output messages
*/
public static final String FLOW_CONVERSATION_ID_HEADER = "flow.conversation.id";
/**
* FLOW_OUTPUT_PORT_HEADER value if FlowHandler catches an exception
*/

View File

@@ -20,7 +20,6 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.config.AbstractSimpleMessageHandlerFactoryBean;
import org.springframework.integration.core.MessageHandler;
import org.springframework.integration.flow.Flow;
import org.springframework.integration.flow.PortConfiguration;
import org.springframework.integration.flow.handler.FlowMessageHandler;
@@ -31,33 +30,34 @@ import org.springframework.util.Assert;
* @author David Turanski
*
*/
public class FlowMessageHandlerFactoryBean extends AbstractSimpleMessageHandlerFactoryBean implements
InitializingBean {
public class FlowMessageHandlerFactoryBean extends AbstractSimpleMessageHandlerFactoryBean
implements InitializingBean {
@SuppressWarnings("unused")
@SuppressWarnings("unused")
private static Log logger = LogFactory.getLog(FlowMessageHandlerFactoryBean.class);
private volatile Flow flow;
private volatile String inputPortName;
private volatile MessageChannel errorChannel;
private volatile long timeout;
//private volatile DirectChannel flowOutputChannel;
private volatile PortConfiguration flowConfiguration;
// private volatile DirectChannel flowOutputChannel;
private volatile PortConfiguration flowConfiguration;
@Override
protected MessageHandler createHandler() {
protected FlowMessageHandler createHandler() {
MessageChannel flowInputChannel = flow.resolveChannelName((String) flowConfiguration.getInputChannel());
FlowMessageHandler flowMessageHandler = new FlowMessageHandler(flowInputChannel, flow.getFlowOutputChannel(), timeout);
FlowMessageHandler flowMessageHandler = new FlowMessageHandler(flowInputChannel, flow.getFlowOutputChannel(),
timeout);
flowMessageHandler.setErrorChannel(this.errorChannel);
return flowMessageHandler;
}
@@ -71,8 +71,9 @@ public class FlowMessageHandlerFactoryBean extends AbstractSimpleMessageHandlerF
/**
*
* @param inputPortName the flow input port associated with the handler. If not set
* and the flow defines only one input port, that will be used by default.
* @param inputPortName the flow input port associated with the handler. If
* not set and the flow defines only one input port, that will be used by
* default.
*/
public void setInputPortName(String inputPortName) {
this.inputPortName = inputPortName;
@@ -85,7 +86,7 @@ public class FlowMessageHandlerFactoryBean extends AbstractSimpleMessageHandlerF
public void setTimeout(long timeout) {
this.timeout = timeout;
}
/**
*
* @param errorChannel
@@ -94,21 +95,19 @@ public class FlowMessageHandlerFactoryBean extends AbstractSimpleMessageHandlerF
this.errorChannel = errorChannel;
}
@Override
public void afterPropertiesSet() throws Exception {
this.flowConfiguration = null;
if (this.inputPortName == null){
Assert.isTrue(!(this.flow.getFlowConfiguration().getPortConfigurations().size() > 1),
"flow [" + this.flow.getBeanName() +"] exposes multiple port configurations. Must specify an input port");
this.flowConfiguration = this.flow.getFlowConfiguration().getPortConfigurations().get(0);
this.inputPortName = this.flowConfiguration.getInputPortName();
}
else {
this.flowConfiguration = this.flow.getFlowConfiguration().getConfigurationForInputPort(
this.inputPortName);
}
}
public void afterPropertiesSet() throws Exception {
this.flowConfiguration = null;
if (this.inputPortName == null) {
Assert.isTrue(!(this.flow.getFlowConfiguration().getPortConfigurations().size() > 1),
"flow [" + this.flow.getBeanName()
+ "] exposes multiple port configurations. Must specify an input port");
this.flowConfiguration = this.flow.getFlowConfiguration().getPortConfigurations().get(0);
this.inputPortName = this.flowConfiguration.getInputPortName();
}
else {
this.flowConfiguration = this.flow.getFlowConfiguration().getConfigurationForInputPort(this.inputPortName);
}
}
}

View File

@@ -37,66 +37,63 @@ import org.w3c.dom.Element;
*/
public class FlowConfigurationParser implements BeanDefinitionParser {
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
List<Element> portMappings = DomUtils.getChildElementsByTagName(element, "port-mapping");
BeanDefinitionBuilder flowConfigurationBuilder = BeanDefinitionBuilder
.genericBeanDefinition(FlowConfiguration.class);
ManagedList<Object> portConfigList = new ManagedList<Object>();
for (Element el : portMappings) {
if (!DomUtils.getChildElements(el).isEmpty()){
if (el.hasAttribute("input-channel") || el.hasAttribute("output-channel")){
parserContext.getReaderContext().error(
"port-mapping cannot include both channel attributes and child elements",
flowConfigurationBuilder);
}
BeanDefinition portConfiguration = buildFlowProviderPortConfiguration(el, parserContext);
portConfigList.add(portConfiguration);
}
else
{
// A default port configuration
if (!(el.hasAttribute("input-channel"))){
parserContext.getReaderContext().error(
"port-mapping with no child elements must include an 'input-channel' attribute",
flowConfigurationBuilder);
}
BeanDefinitionBuilder portConfigurationBuilder = BeanDefinitionBuilder
.genericBeanDefinition(ChannelNamePortConfiguration.class);
portConfigurationBuilder.addConstructorArgValue(el.getAttribute("input-channel"));
if (el.hasAttribute("output-channel")){
portConfigurationBuilder.addConstructorArgValue(el.getAttribute("output-channel"));
} else {
portConfigurationBuilder.addConstructorArgValue(null);
}
portConfigList.add(portConfigurationBuilder.getBeanDefinition());
}
if (!DomUtils.getChildElements(el).isEmpty()) {
if (el.hasAttribute("input-channel") || el.hasAttribute("output-channel")) {
parserContext.getReaderContext().error(
"port-mapping cannot include both channel attributes and child elements",
flowConfigurationBuilder);
}
BeanDefinition portConfiguration = buildFlowProviderPortConfiguration(el, parserContext);
portConfigList.add(portConfiguration);
}
else {
// A default port configuration
if (!(el.hasAttribute("input-channel"))) {
parserContext.getReaderContext().error(
"port-mapping with no child elements must include an 'input-channel' attribute",
flowConfigurationBuilder);
}
BeanDefinitionBuilder portConfigurationBuilder = BeanDefinitionBuilder
.genericBeanDefinition(ChannelNamePortConfiguration.class);
portConfigurationBuilder.addConstructorArgValue(el.getAttribute("input-channel"));
if (el.hasAttribute("output-channel")) {
portConfigurationBuilder.addConstructorArgValue(el.getAttribute("output-channel"));
}
else {
portConfigurationBuilder.addConstructorArgValue(null);
}
portConfigList.add(portConfigurationBuilder.getBeanDefinition());
}
}
flowConfigurationBuilder.addConstructorArgValue(portConfigList);
BeanDefinitionReaderUtils.registerWithGeneratedName(flowConfigurationBuilder.getBeanDefinition(),
parserContext.getRegistry());
parserContext.getRegistry());
return null;
}
private BeanDefinition buildFlowProviderPortConfiguration(Element el, ParserContext parserContext) {
Element inputPortEl = DomUtils.getChildElementByTagName(el, "input-port");
BeanDefinitionBuilder portConfigurationBuilder = BeanDefinitionBuilder
.genericBeanDefinition(ChannelNamePortConfiguration.class);
BeanDefinition portMetadata = this.buildPortMetadata(el, inputPortEl);
portConfigurationBuilder.addConstructorArgValue(portMetadata);
List<Element> outputPortElements = DomUtils.getChildElementsByTagName(el, "output-port");
@@ -115,11 +112,10 @@ public class FlowConfigurationParser implements BeanDefinitionParser {
return portConfigurationBuilder.getBeanDefinition();
}
private BeanDefinition buildPortMetadata(Element element, Element portElement) {
BeanDefinitionBuilder portMetadataBuilder = BeanDefinitionBuilder.genericBeanDefinition(PortMetadata.class);
portMetadataBuilder.addConstructorArgValue(portElement.getAttribute("name"));
portMetadataBuilder.addConstructorArgValue(portElement.getAttribute("name"));
portMetadataBuilder.addConstructorArgValue(portElement.getAttribute("channel"));
return portMetadataBuilder.getBeanDefinition();
}

View File

@@ -24,11 +24,10 @@ import org.springframework.integration.config.xml.AbstractIntegrationNamespaceHa
*/
public class FlowNamespaceHandler extends AbstractIntegrationNamespaceHandler {
@Override
public void init() {
registerBeanDefinitionParser("flow", new FlowParser());
registerBeanDefinitionParser("outbound-gateway", new FlowOutboundGatewayParser());
registerBeanDefinitionParser("flow-configuration", new FlowConfigurationParser());
}
}
}

View File

@@ -33,18 +33,15 @@ import org.w3c.dom.Element;
*/
public class FlowParser implements BeanDefinitionParser {
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
Element props = DomUtils.getChildElementByTagName(element,"props");
if(element.hasAttribute("properties") && props !=null) {
parserContext.getReaderContext().error(
"Element cannot have both 'properties' attribute and inner 'props' element",element);
}
Element props = DomUtils.getChildElementByTagName(element, "props");
if (element.hasAttribute("properties") && props != null) {
parserContext.getReaderContext().error(
"Element cannot have both 'properties' attribute and inner 'props' element", element);
}
BeanDefinitionBuilder flowBuilder = BeanDefinitionBuilder.genericBeanDefinition(Flow.class);
String id = element.getAttribute("id");
BeanDefinitionBuilder flowOutputChannelBuilder = BeanDefinitionBuilder
@@ -52,20 +49,18 @@ public class FlowParser implements BeanDefinitionParser {
String beanName = FlowUtils.registerBeanDefinition(flowOutputChannelBuilder.getBeanDefinition(),
parserContext.getRegistry());
flowBuilder.addPropertyReference("flowOutputChannel", beanName);
IntegrationNamespaceUtils.setValueIfAttributeDefined(flowBuilder, element, "referenced-bean-locations");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(flowBuilder, element, "properties");
IntegrationNamespaceUtils.setValueIfAttributeDefined(flowBuilder, element, "help");
IntegrationNamespaceUtils.setValueIfAttributeDefined(flowBuilder, element, "flow-id");
if (props != null) {
flowBuilder.addPropertyValue("properties",parserContext.getDelegate().parsePropsElement(props));
if (props != null) {
flowBuilder.addPropertyValue("properties", parserContext.getDelegate().parsePropsElement(props));
}
BeanDefinition beanDefinition = flowBuilder.getBeanDefinition();
parserContext.getRegistry().registerBeanDefinition(id, beanDefinition);
return beanDefinition;
}

View File

@@ -16,7 +16,6 @@
package org.springframework.integration.flow.handler;
import java.util.Collections;
import java.util.Map;
import java.util.UUID;
import org.apache.commons.logging.Log;
@@ -85,14 +84,9 @@ public class FlowMessageHandler extends AbstractReplyProducingMessageHandler {
@Override
protected Object handleRequestMessage(Message<?> requestMessage) {
String conversationId = this.toString();
Map<String, String> flowConversationIdHeader = Collections.singletonMap(
FlowConstants.FLOW_CONVERSATION_ID_HEADER, this.toString());
Message<?> message = MessageBuilder.fromMessage(requestMessage).copyHeaders(flowConversationIdHeader)
.build();
UUID conversationId = requestMessage.getHeaders().getId();
Message<?> message = MessageBuilder.fromMessage(requestMessage).pushSequenceDetails(conversationId, 0, 0)
.build();
try {
ResponseMessageHandler responseMessageHandler = new ResponseMessageHandler(conversationId);
@@ -103,15 +97,16 @@ public class FlowMessageHandler extends AbstractReplyProducingMessageHandler {
}
catch (MessagingException me) {
log.error(me.getMessage(), me);
if (conversationId
.equals(me.getFailedMessage().getHeaders().get(FlowConstants.FLOW_CONVERSATION_ID_HEADER))) {
if (conversationId.equals(me.getFailedMessage().getHeaders().getCorrelationId())) {
if (errorChannel != null) {
errorChannel.send(new ErrorMessage(me, Collections.singletonMap(
FlowConstants.FLOW_OUTPUT_PORT_HEADER,
(Object) FlowConstants.FLOW_HANDLER_EXCEPTION_HEADER_VALUE)));
}
} else {
}
else {
throw me;
}
}
@@ -122,11 +117,11 @@ public class FlowMessageHandler extends AbstractReplyProducingMessageHandler {
* Internal MessageHandler for the flow response
*/
private static class ResponseMessageHandler implements MessageHandler {
private final String conversationId;
private final UUID conversationId;
private volatile Message<?> response;
public ResponseMessageHandler(String conversationId) {
public ResponseMessageHandler(UUID conversationId) {
this.conversationId = conversationId;
}
@@ -137,20 +132,27 @@ public class FlowMessageHandler extends AbstractReplyProducingMessageHandler {
* org.springframework.integration.core.MessageHandler#handleMessage
* (org.springframework.integration.Message)
*/
@Override
public void handleMessage(Message<?> message) throws MessagingException {
if (conversationId.equals(message.getHeaders().get(FlowConstants.FLOW_CONVERSATION_ID_HEADER))) {
this.response = message;
if (log.isDebugEnabled()) {
log.debug("handling flow response message with conversation Id "
+ message.getHeaders().getCorrelationId() + ". Target conversation Id = " + this.conversationId
+ " match = " + conversationId.equals(message.getHeaders().getCorrelationId()));
}
if (conversationId.equals(message.getHeaders().getCorrelationId())) {
this.response = MessageBuilder.fromMessage(message).popSequenceDetails().build();
if (log.isDebugEnabled()) {
log.debug("set flow response message " + this.response);
}
}
else {
/*
* Response from flow's ErrorChannel which is mapped to an output port.
* Response from flow's ErrorChannel which is mapped to an
* output port.
*/
if (message instanceof ErrorMessage) {
MessagingException me = (MessagingException) message.getPayload();
if (conversationId.equals(me.getFailedMessage().getHeaders()
.get(FlowConstants.FLOW_CONVERSATION_ID_HEADER))) {
if (conversationId.equals(me.getFailedMessage().getHeaders().getCorrelationId())) {
this.response = message;
}
}

View File

@@ -30,7 +30,7 @@ import org.springframework.integration.support.MessageBuilder;
/**
* A ChannelInterceptor to set the Flow output port header
* @see FlowUtils
*
*
* @author David Turanski
*
*/
@@ -39,7 +39,7 @@ public class FlowInterceptor extends ChannelInterceptorAdapter {
private final String portName;
/**
/**
* @param portName the value of the message header
*/
public FlowInterceptor(String portName) {
@@ -48,11 +48,13 @@ public class FlowInterceptor extends ChannelInterceptorAdapter {
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
log.debug("flow interceptor " + this.hashCode() + " received a message from port " + portName + " on channel "
+ channel);
Map<String, Object> headersToCopy = Collections.singletonMap(FlowConstants.FLOW_OUTPUT_PORT_HEADER, (Object) portName);
return MessageBuilder.fromMessage(message).copyHeadersIfAbsent(headersToCopy).build();
if (log.isDebugEnabled()) {
log.debug(this + " received a message from port " + portName + " on channel " + channel);
}
Map<String, Object> headersToCopy = Collections.singletonMap(FlowConstants.FLOW_OUTPUT_PORT_HEADER,
(Object) portName);
return MessageBuilder.fromMessage(message).copyHeaders(headersToCopy).build();
}
}

View File

@@ -0,0 +1,40 @@
package org.springframework.integration.flow;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import org.junit.Test;
import org.springframework.integration.Message;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.PublishSubscribeChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.core.PollableChannel;
import org.springframework.integration.core.SubscribableChannel;
import org.springframework.integration.flow.config.FlowUtils;
import org.springframework.integration.message.GenericMessage;
/**
*
* @author David Turanski
*
*/
public class FlowUtilsTests {
@Test
public void buildBridge(){
SubscribableChannel inputChannel = new DirectChannel();
SubscribableChannel outputChannel = new PublishSubscribeChannel();
PollableChannel receiveChannel = new QueueChannel();
FlowUtils.bridgeChannels(inputChannel, outputChannel);
FlowUtils.bridgeChannels(outputChannel, receiveChannel);
Message<?> message = new GenericMessage<String>("hello");
inputChannel.send(message);
Message<?> result = receiveChannel.receive(100);
assertNotNull(result);
assertSame(message, result);
}
}

View File

@@ -30,7 +30,6 @@ public class TransactionalServiceActivator implements RequestReplyExchanger {
/* (non-Javadoc)
* @see org.springframework.integration.gateway.RequestReplyExchanger#exchange(org.springframework.integration.Message)
*/
@Override
public Message<?> exchange(Message<?> request) {
return gateway.exchange(request);
}

View File

@@ -4,19 +4,16 @@ import org.springframework.beans.factory.FactoryBean;
public class BarFactory implements FactoryBean<Bar> {
@Override
public Bar getObject() throws Exception {
// TODO Auto-generated method stub
return new Bar();
}
@Override
public Class getObjectType() {
public Class<?> getObjectType() {
// TODO Auto-generated method stub
return Bar.class;
}
@Override
public boolean isSingleton() {
// TODO Auto-generated method stub
return true;

View File

@@ -0,0 +1,42 @@
<?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"
xmlns:int-flow="http://www.springframework.org/schema/integration/flow"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/flow http://www.springframework.org/schema/integration/flow/spring-integration-flow.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<!-- Instantiate the flow (folded into its own application context) -->
<int-flow:flow id="subflow1" />
<int-flow:outbound-gateway flow="subflow1"
input-channel="inputC1" output-channel="outputC1" input-port="gateway-input" />
<int:chain input-channel="inputC2" output-channel="outputC2">
<int-flow:outbound-gateway flow="subflow1"
input-port="gateway-input" />
</int:chain>
<int:channel id="outputC1">
<int:queue />
</int:channel>
<int:channel id="outputC2">
<int:queue />
</int:channel>
<int-flow:flow id="flowWithProps" flow-id="subflow1">
<props>
<prop key="key1">val1</prop>
</props>
</int-flow:flow>
</beans>

View File

@@ -0,0 +1,91 @@
/*
* 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. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.springframework.integration.flow.config.xml;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.integration.Message;
import org.springframework.integration.flow.Flow;
import org.springframework.integration.test.support.AbstractRequestResponseScenarioTest;
import org.springframework.integration.test.support.MessageValidator;
import org.springframework.integration.test.support.RequestResponseScenario;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
*
* @author David Turanski
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class FlowClientNamespaceTests extends AbstractRequestResponseScenarioTest {
@Autowired
@Qualifier("flowWithProps")
Flow flowWithProps;
@Test
public void testFlowWithInnerProps() {
assertEquals("val1", flowWithProps.getProperties().getProperty("key1"));
}
/*
* (non-Javadoc)
*
* @see org.springframework.integration.test.support.
* AbstractRequestResponseScenarioTest#defineRequestResponseScenarios()
*/
@Override
protected List<RequestResponseScenario> defineRequestResponseScenarios() {
List<RequestResponseScenario> scenarios = new ArrayList<RequestResponseScenario>();
RequestResponseScenario scenario1 = new RequestResponseScenario("inputC1", "outputC1")
.setName("gateway-response-scenario").setPayload("hello").setResponseValidator(new MessageValidator() {
@Override
protected void validateMessage(Message<?> message) {
assertNotNull(message);
}
});
scenarios.add(scenario1);
RequestResponseScenario scenario2 = new RequestResponseScenario("inputC2", "outputC2")
.setName("gateway-discard-scenario").setPayload("world").setResponseValidator(new MessageValidator() {
@Override
protected void validateMessage(Message<?> reply) {
assertEquals("gateway-discard", reply.getHeaders().get("flow.output.port"));
assertEquals("yeah!", reply.getHeaders().get("gateway"));
}
});
scenarios.add(scenario2);
return scenarios;
}
}

View File

@@ -0,0 +1,25 @@
<?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-flow="http://www.springframework.org/schema/integration/flow"
xmlns:int="http://www.springframework.org/schema/integration"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.1.xsd
http://www.springframework.org/schema/integration/flow http://www.springframework.org/schema/integration/flow/spring-integration-flow.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<int-flow:flow-configuration>
<int-flow:port-mapping>
<int-flow:input-port name="input" channel="subflow-input" />
<int-flow:output-port name="output" channel="subflow-output" />
</int-flow:port-mapping>
<int-flow:port-mapping>
<int-flow:input-port name="input2" channel="subflow-input2" />
<int-flow:output-port name="output2" channel="subflow-output2" />
</int-flow:port-mapping>
</int-flow:flow-configuration>
<int-flow:flow-configuration>
<int-flow:port-mapping input-channel="inputChannel"
output-channel="outputChannel" />
</int-flow:flow-configuration>
</beans>

View File

@@ -0,0 +1,65 @@
/*
* 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. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.springframework.integration.flow.config.xml;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.Iterator;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.integration.flow.FlowConfiguration;
import org.springframework.integration.flow.PortConfiguration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
*
* @author David Turanski
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class FlowConfigNamespaceTests {
@Autowired
ApplicationContext applicationContext;
@Test
public void test() {
Map<String,FlowConfiguration> flowConfigurations = applicationContext.getBeansOfType(FlowConfiguration.class);
Iterator<FlowConfiguration> iterator = flowConfigurations.values().iterator();
FlowConfiguration flowConfiguration = iterator.next();
assertNotNull(flowConfiguration.getPortConfigurations());
assertEquals(2, flowConfiguration.getPortConfigurations().size());
PortConfiguration pc0 = flowConfiguration.getPortConfigurations().get(0);
assertEquals("input", pc0.getInputPortName());
assertEquals("subflow-input", pc0.getInputChannel());
assertEquals("subflow-output", pc0.getOutputChannel("output"));
assertEquals(1, pc0.getOutputPortNames().size());
flowConfiguration = iterator.next();
assertNotNull(flowConfiguration.getPortConfigurations());
assertEquals (1, flowConfiguration.getPortConfigurations().size());
}
}

View File

@@ -0,0 +1,22 @@
<?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"
xmlns:int-flow="http://www.springframework.org/schema/integration/flow"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/flow http://www.springframework.org/schema/integration/flow/spring-integration-flow.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Instantiate the flow -->
<int-flow:flow id="subflow" flow-id="flow-with-channel-conflict"/>
<!-- input port not required if only one -->
<int-flow:outbound-gateway flow="subflow"
input-channel="inputC"
output-channel="outputC"
/>
<int:channel id="outputC"/>
</beans>

View File

@@ -0,0 +1,22 @@
<?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"
xmlns:int-flow="http://www.springframework.org/schema/integration/flow"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:int-jmx="http://www.springframework.org/schema/integration/jmx"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/jmx http://www.springframework.org/schema/integration/jmx/spring-integration-jmx.xsd
http://www.springframework.org/schema/integration/flow http://www.springframework.org/schema/integration/flow/spring-integration-flow.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:mbean-server/>
<int-jmx:mbean-export />
<!-- Instantiate the flow -->
<int-flow:flow id="subflow1" />
</beans>

View File

@@ -0,0 +1,45 @@
/*
* 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. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.springframework.integration.flow.config.xml;
import org.junit.Test;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author David Turanski
*
*/
public class FlowContextTests {
@Test(expected=BeanCreationException.class)
public void testChannelConflictShouldThrowException() {
try {
new ClassPathXmlApplicationContext(
"/org/springframework/integration/flow/config/xml/FlowContextTests-context.xml");
} catch (BeanCreationException e) {
System.out.println(e.getCause().getMessage());
throw e;
}
}
@Test
public void testFlowWithJMX() {
new ClassPathXmlApplicationContext(
"/org/springframework/integration/flow/config/xml/FlowContextTests-jmx-context.xml");
}
}

View File

@@ -0,0 +1,10 @@
<?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-flow="http://www.springframework.org/schema/integration/flow"
xsi:schemaLocation="http://www.springframework.org/schema/integration/flow http://www.springframework.org/schema/integration/flow/spring-integration-flow-2.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<int-flow:flow id="autowired"
referenced-bean-locations="/org/springframework/integration/flow/config/xml/autowired-referenced-beans.xml"/>
</beans>

View File

@@ -0,0 +1,22 @@
package org.springframework.integration.flow.config.xml;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.flow.Flow;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class FlowWithAutowireTests {
@Autowired
Flow flow;
@Test
public void test() {
Foo foo = flow.getFlowContext().getBean(Foo.class);
assertNotNull(foo.bar);
}
}

View File

@@ -0,0 +1,39 @@
<?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"
xmlns:int-flow="http://www.springframework.org/schema/integration/flow"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/flow http://www.springframework.org/schema/integration/flow/spring-integration-flow.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd">
<int-flow:flow id="subflow4"/>
<int-flow:flow id="subflow5"/>
<int-flow:outbound-gateway
flow="subflow4"
input-port="input"
input-channel="inputC"
output-channel="outputC"
error-channel="errorChannel"/>
<int-flow:outbound-gateway
flow="subflow5"
input-port="input"
input-channel="inputC1"
output-channel="outputC1"/>
<int:channel id="outputC">
<int:queue/>
</int:channel>
<int:channel id="outputC1">
<int:queue/>
</int:channel>
</beans>

View File

@@ -0,0 +1,106 @@
/*
* 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. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.springframework.integration.flow.config.xml;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.MessagingException;
import org.springframework.integration.core.MessageHandler;
import org.springframework.integration.core.PollableChannel;
import org.springframework.integration.core.SubscribableChannel;
import org.springframework.integration.message.GenericMessage;
/**
*
* @author David Turanski
*
*/
public class FlowWithErrorTests {
@Test
public void testFlowThrowsExceptionWithGatewayErrorChannel() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"/org/springframework/integration/flow/config/xml/FlowWithErrorTests-context.xml");
MessageChannel inputChannel = applicationContext.getBean("inputC", MessageChannel.class);
SubscribableChannel errorChannel = applicationContext.getBean("errorChannel", SubscribableChannel.class);
Message<String> msg = new GenericMessage<String>("hello");
Handler handler = new Handler();
errorChannel.subscribe(handler);
inputChannel.send(msg);
assertTrue(handler.gotResponse);
}
@Test
public void testDirectCallWithErrorChannel() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"classpath:/META-INF/spring/integration/flows/subflow5/subflow5-context.xml");
MessageChannel inputChannel = applicationContext.getBean("subflow-input", MessageChannel.class);
SubscribableChannel errorChannel = applicationContext.getBean("errorChannel", SubscribableChannel.class);
errorChannel.subscribe(new MessageHandler() {
public void handleMessage(Message<?> message) throws MessagingException {
assertTrue(message.getPayload() instanceof MessagingException);
}
});
Message<String> msg = new GenericMessage<String>("hello");
assertTrue(inputChannel.send(msg));
}
@Test
public void testWithErrorChannel() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"/org/springframework/integration/flow/config/xml/FlowWithErrorTests-context.xml");
MessageChannel inputChannel = applicationContext.getBean("inputC1", MessageChannel.class);
PollableChannel output = applicationContext.getBean("outputC1", PollableChannel.class);
Message<String> msg = new GenericMessage<String>("hello");
inputChannel.send(msg);
Message<?> reply = output.receive(100);
assertNotNull(reply);
assertTrue(reply.getPayload() instanceof MessagingException);
}
private static class Handler implements MessageHandler {
public boolean gotResponse;
@SuppressWarnings("unused")
public Message<?> message;
/*
* (non-Javadoc)
*
* @see
* org.springframework.integration.core.MessageHandler#handleMessage
* (org.springframework.integration.Message)
*/
public void handleMessage(Message<?> message) throws MessagingException {
this.gotResponse = true;
this.message = message;
}
}
}

View File

@@ -0,0 +1,24 @@
<?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"
xmlns:int-flow="http://www.springframework.org/schema/integration/flow"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/flow http://www.springframework.org/schema/integration/flow/spring-integration-flow.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd">
<!-- Instantiate the flow -->
<int-flow:flow id="no-response"/>
<int-flow:flow id="optional-response"/>
<int-flow:outbound-gateway
flow="no-response" input-channel="inputC"/>
<int-flow:outbound-gateway
flow="optional-response" input-channel="inputCO" output-channel="outputC"/>
<int:channel id="outputC"/>
</beans>

View File

@@ -0,0 +1,60 @@
package org.springframework.integration.flow.config.xml;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.MessagingException;
import org.springframework.integration.core.MessageHandler;
import org.springframework.integration.core.SubscribableChannel;
import org.springframework.integration.message.GenericMessage;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class FlowWithOptionalResponseTests {
@Autowired
@Qualifier("inputC")
MessageChannel input;
@Autowired
@Qualifier("inputCO")
MessageChannel inputForOptionalResponse;
@Autowired
@Qualifier("outputC")
SubscribableChannel output;
@Test
public void testOneWay() {
input.send(new GenericMessage<String>("hello"));
}
@Test
public void testOptionResponse() {
TestMessageHandler counter = new TestMessageHandler();
output.subscribe(counter);
for (int i = 0; i < 100; i++) {
inputForOptionalResponse.send(new GenericMessage<String>("hello"));
}
assertTrue(String.valueOf(counter.count), counter.count > 1 && counter.count < 100);
}
static class TestMessageHandler implements MessageHandler {
int count = 0;
public void handleMessage(Message<?> message) throws MessagingException {
count++;
}
}
}

View File

@@ -0,0 +1,29 @@
<?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"
xmlns:int-flow="http://www.springframework.org/schema/integration/flow"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/flow http://www.springframework.org/schema/integration/flow/spring-integration-flow.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Instantiate the flow -->
<int-flow:flow id="subflow2" referenced-bean-locations=
"/org/springframework/integration/flow/config/xml/ref-bean-config.xml">
<props>
<prop key="key1">val1</prop>
</props>
</int-flow:flow>
<!-- input port not required if only one -->
<int-flow:outbound-gateway flow="subflow2"
input-channel="inputC"
output-channel="outputC"/>
<int:channel id="outputC">
<int:queue/>
</int:channel>
</beans>

View File

@@ -0,0 +1,58 @@
/*
* 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. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.springframework.integration.flow.config.xml;
import static org.junit.Assert.assertEquals;
import org.junit.runner.RunWith;
import org.springframework.integration.Message;
import org.springframework.integration.test.support.MessageValidator;
import org.springframework.integration.test.support.RequestResponseScenario;
import org.springframework.integration.test.support.SingleRequestResponseScenarioTest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
*
* @author David Turanski
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class FlowWithReferencesTests extends SingleRequestResponseScenarioTest {
/* (non-Javadoc)
* @see org.springframework.integration.test.support.SingleRequestResponseScenarioTest#defineRequestResponseScenario()
*/
@Override
protected RequestResponseScenario defineRequestResponseScenario() {
RequestResponseScenario scenario =
new RequestResponseScenario("inputC","outputC")
.setPayload("hello")
.setResponseValidator(new MessageValidator() {
@Override
protected void validateMessage(Message<?> reply) {
assertEquals("it works!",reply.getHeaders().get("refbean.value"));
assertEquals("val1",reply.getHeaders().get("property.value.1"));
assertEquals("undefined",reply.getHeaders().get("property.value.2"));
}}
);
return scenario;
}
}

View File

@@ -6,7 +6,7 @@ public class FooFactory implements FactoryBean<Foo>{
@Autowired
Bar bar;
@Override
public Foo getObject() throws Exception {
// TODO Auto-generated method stub
Foo foo = new Foo();
@@ -14,13 +14,13 @@ public class FooFactory implements FactoryBean<Foo>{
return foo;
}
@Override
public Class<?> getObjectType() {
// TODO Auto-generated method stub
return Foo.class;
}
@Override
public boolean isSingleton() {
// TODO Auto-generated method stub
return true;

View File

@@ -0,0 +1,21 @@
<?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"
xmlns:int-flow="http://www.springframework.org/schema/integration/flow"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/flow http://www.springframework.org/schema/integration/flow/spring-integration-flow.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<int-flow:flow id="nested"/>
<int-flow:outbound-gateway flow="nested"
input-channel="inputChannel"
output-channel="outputChannel"
/>
<int:channel id="outputChannel"/>
</beans>

View File

@@ -0,0 +1,62 @@
package org.springframework.integration.flow.config.xml;
import static org.junit.Assert.assertEquals;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.MessagingException;
import org.springframework.integration.core.MessageHandler;
import org.springframework.integration.core.SubscribableChannel;
import org.springframework.integration.message.GenericMessage;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class NestedFlowTests {
@Autowired
MessageChannel inputChannel;
@Autowired
SubscribableChannel outputChannel;
@Test
@DirtiesContext
public void testNestedFlowOneExecution() {
final AtomicInteger count = new AtomicInteger();
outputChannel.subscribe(new MessageHandler() {
public void handleMessage(Message<?> message) throws MessagingException {
count.getAndIncrement();
}});
inputChannel.send(new GenericMessage<String>("hello"));
assertEquals(1,count.get());
}
@Test
@DirtiesContext
public void testNestedFlowMultipleExecutions() {
final AtomicInteger count = new AtomicInteger();
outputChannel.subscribe(new MessageHandler() {
public void handleMessage(Message<?> message) throws MessagingException {
count.getAndIncrement();
}});
for (int i=0; i<2; i++) {
inputChannel.send(new GenericMessage<String>("hello"));
}
assertEquals(2,count.get());
}
}

View File

@@ -0,0 +1,18 @@
<?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-flow="http://www.springframework.org/schema/integration/flow"
xmlns:int="http://www.springframework.org/schema/integration"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.1.xsd
http://www.springframework.org/schema/integration/flow http://www.springframework.org/schema/integration/flow/spring-integration-flow-2.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<int-flow:flow id="transactional-flow"/>
<int-flow:outbound-gateway flow="transactional-flow"
input-channel="inputC" output-channel="outputC"
error-channel="errorChannel"/>
<int:channel id="outputC"/>
</beans>

View File

@@ -0,0 +1,132 @@
/*
* 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. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.springframework.integration.flow.config.xml;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.MessagingException;
import org.springframework.integration.core.MessageHandler;
import org.springframework.integration.core.SubscribableChannel;
import org.springframework.integration.flow.FlowConstants;
import org.springframework.integration.flow.Transaction.StubTransactionManager;
import org.springframework.integration.message.ErrorMessage;
import org.springframework.integration.message.GenericMessage;
/**
* @author David Turanski
*
*/
public class TransactionalFlowTests {
@Test
public void testFlowDirectCommit() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"/META-INF/spring/integration/flows/transactional-flow/flow-context.xml",
"/org/springframework/integration/flow/config/xml/txmanager-config.xml");
MessageChannel inputChannel = applicationContext.getBean("inputChannel", MessageChannel.class);
SubscribableChannel outputChannel = applicationContext.getBean("outputChannel", SubscribableChannel.class);
StubTransactionManager transactionManager = applicationContext.getBean(StubTransactionManager.class);
Handler handler = new Handler();
outputChannel.subscribe(handler);
inputChannel.send(new GenericMessage<String>("hello"));
assertTrue(handler.messageReceived);
assertTrue(transactionManager.committed);
assertFalse(transactionManager.rolledback);
}
@Test
public void testFlowDirectRollback() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"/META-INF/spring/integration/flows/transactional-flow/flow-context.xml",
"/org/springframework/integration/flow/config/xml/txmanager-config.xml");
MessageChannel inputChannel = applicationContext.getBean("inputChannel", MessageChannel.class);
SubscribableChannel outputChannel = applicationContext.getBean("outputChannel", SubscribableChannel.class);
StubTransactionManager transactionManager = applicationContext.getBean(StubTransactionManager.class);
Handler handler = new Handler();
outputChannel.subscribe(handler);
try {
inputChannel.send(new GenericMessage<String>("rollback"));
fail("should throw exception");
}
catch (Exception e) {
assertFalse(handler.messageReceived);
assertTrue(transactionManager.rolledback);
assertFalse(transactionManager.committed);
}
}
@Test
public void testFlowCommit() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"/org/springframework/integration/flow/config/xml/TransactionalFlowTests-context.xml",
"/org/springframework/integration/flow/config/xml/txmanager-config.xml");
MessageChannel inputChannel = applicationContext.getBean("inputC", MessageChannel.class);
SubscribableChannel outputChannel = applicationContext.getBean("outputC", SubscribableChannel.class);
StubTransactionManager transactionManager = applicationContext.getBean(StubTransactionManager.class);
Handler handler = new Handler();
outputChannel.subscribe(handler);
inputChannel.send(new GenericMessage<String>("hello"));
assertTrue(handler.messageReceived);
assertTrue(transactionManager.committed);
assertFalse(transactionManager.rolledback);
}
@Test
public void testFlowRollbackWithGatewayErrorChannel() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"/org/springframework/integration/flow/config/xml/TransactionalFlowTests-context.xml",
"/org/springframework/integration/flow/config/xml/txmanager-config.xml");
MessageChannel inputChannel = applicationContext.getBean("inputC", MessageChannel.class);
SubscribableChannel errorChannel = applicationContext.getBean("errorChannel", SubscribableChannel.class);
StubTransactionManager transactionManager = applicationContext.getBean(StubTransactionManager.class);
Handler handler = new Handler();
errorChannel.subscribe(handler);
inputChannel.send(new GenericMessage<String>("rollback"));
assertTrue(handler.messageReceived);
assertTrue(handler.message instanceof ErrorMessage);
assertEquals(FlowConstants.FLOW_HANDLER_EXCEPTION_HEADER_VALUE,
handler.message.getHeaders().get(FlowConstants.FLOW_OUTPUT_PORT_HEADER));
assertTrue(transactionManager.rolledback);
assertFalse(transactionManager.committed);
}
private static class Handler implements MessageHandler {
public boolean messageReceived;
public Message<?> message;
/*
* (non-Javadoc)
*
* @see
* org.springframework.integration.core.MessageHandler#handleMessage
* (org.springframework.integration.Message)
*/
public void handleMessage(Message<?> message) throws MessagingException {
this.messageReceived = true;
this.message = message;
}
}
}

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="org.springframework.integration.flow.config.xml.FooFactory"/>
<bean class="org.springframework.integration.flow.config.xml.Bar"/>
</beans>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="refbean" class="org.springframework.integration.flow.config.xml.RefBean">
<property name="value" value="it works!"/>
</bean>
</beans>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="transactionManager" class="org.springframework.integration.flow.Transaction.StubTransactionManager"/>
</beans>

View File

@@ -0,0 +1,19 @@
<?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-flow="http://www.springframework.org/schema/integration/flow"
xmlns:int="http://www.springframework.org/schema/integration"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.1.xsd
http://www.springframework.org/schema/integration/flow http://www.springframework.org/schema/integration/flow/spring-integration-flow-2.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<int-flow:flow-configuration>
<int-flow:port-mapping input-channel="basic1.inputChannel" output-channel="basic1.outputChannel"/>
</int-flow:flow-configuration>
<int:bridge input-channel="basic1.inputChannel" output-channel="basic1.outputChannel"/>
<int:channel id="basic1.outputChannel"/>
<int:channel id="basic1.inputChannel"/>
</beans>

View File

@@ -0,0 +1,18 @@
<?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-flow="http://www.springframework.org/schema/integration/flow"
xmlns:int="http://www.springframework.org/schema/integration"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.1.xsd
http://www.springframework.org/schema/integration/flow http://www.springframework.org/schema/integration/flow/spring-integration-flow-2.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<int-flow:flow-configuration>
<int-flow:port-mapping input-channel="basic2.inputChannel" output-channel="basic2.outputChannel"/>
</int-flow:flow-configuration>
<int:bridge input-channel="basic2.inputChannel" output-channel="basic2.outputChannel"/>
<int:channel id="basic2.outputChannel"/>
<int:channel id="basic2.inputChannel"/>
</beans>

View File

@@ -0,0 +1,25 @@
<?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-flow="http://www.springframework.org/schema/integration/flow"
xmlns:int="http://www.springframework.org/schema/integration"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.1.xsd
http://www.springframework.org/schema/integration/flow http://www.springframework.org/schema/integration/flow/spring-integration-flow-2.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<int-flow:flow-configuration>
<int-flow:port-mapping input-channel="nested.inputChannel" output-channel="nested.outputChannel"/>
</int-flow:flow-configuration>
<int-flow:flow id="basic1"/>
<int-flow:flow id="basic2"/>
<int-flow:outbound-gateway flow="basic1" input-channel="nested.inputChannel"
output-channel="basic2.in"/>
<int-flow:outbound-gateway flow="basic2" input-channel="basic2.in"
output-channel="nested.outputChannel"/>
<int:channel id="nested.outputChannel"/>
</beans>

View File

@@ -16,8 +16,12 @@
</logger>
<logger name="org.springframework.integration">
<level value="warn" />
<level value="info" />
</logger>
<logger name="org.springframework.integration.flow">
<level value="info" />
</logger>
<!-- Root Logger -->
<root>