-aSimplified flow configuration and enhanced documentation mechanism

This commit is contained in:
David Turanski
2011-07-08 12:44:40 -04:00
parent 8811bb397c
commit c392e19887
33 changed files with 255 additions and 577 deletions

View File

@@ -19,32 +19,27 @@
package org.springframework.integration.flow;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ChannelNamePortConfiguration extends NamedResourceConfiguration implements FlowProviderPortConfiguration {
public class ChannelNamePortConfiguration implements PortConfiguration {
private PortMetadata inputPortMetadata;
private List<PortMetadata> outputPortMetadataList;
public ChannelNamePortConfiguration(PortMetadata inputPortMetadata, List<PortMetadata> outputPortMetadataList) {
super(outputPortMetadataList);
this.outputPortMetadataList = outputPortMetadataList;
this.inputPortMetadata = inputPortMetadata;
}
@Override
public String getInputPortName() {
return this.inputPortMetadata.getName();
return this.inputPortMetadata.getPortName();
}
@Override
public String getInputChannel() {
return this.inputPortMetadata.getChannelName();
}
@Override
public String getInputPortDescription() {
return this.inputPortMetadata.getDescription();
}
@Override
@@ -59,9 +54,8 @@ public class ChannelNamePortConfiguration extends NamedResourceConfiguration imp
@Override
public List<String> getOutputPortNames() {
List<String> results = new ArrayList<String>();
for (NamedResourceMetadata resourceMetadata : getConfiguredResources()) {
PortMetadata portMetadata = (PortMetadata) resourceMetadata;
results.add(portMetadata.getName());
for (PortMetadata portMetadata : outputPortMetadataList ) {
results.add(portMetadata.getPortName());
}
/**
* consistent with ClientPortConfiguration impl.
@@ -73,12 +67,14 @@ public class ChannelNamePortConfiguration extends NamedResourceConfiguration imp
return results;
}
/* (non-Javadoc)
* @see org.springframework.integration.flow.FlowProviderPortConfiguration#getOutputPortMetadata()
*/
@Override
public List<NamedResourceMetadata> getOutputPortMetadata() {
return Collections.unmodifiableList(super.getConfiguredResources());
public PortMetadata find(String portName){
for (PortMetadata portMetadata : outputPortMetadataList ) {
if (portName.equals(portMetadata.getPortName())){
return portMetadata;
}
}
return null;
}
}

View File

@@ -49,7 +49,9 @@ public class Flow implements InitializingBean, BeanNameAware, ChannelResolver, A
private volatile Properties flowProperties;
private volatile String name;
private volatile String beanName;
private volatile String flowId;
private volatile ChannelResolver flowChannelResolver;
@@ -67,10 +69,18 @@ public class Flow implements InitializingBean, BeanNameAware, ChannelResolver, A
@Override
public void afterPropertiesSet() {
if (this.flowId == null){
this.flowId = this.beanName;
}
if (this.help) {
System.out.println(FlowUtils.getDocumentation(this.flowId));
}
if (configLocations == null) {
configLocations = new String[] { String.format(
"classpath*:META-INF/spring/integration/flows/%s-context.xml", this.name) };
"classpath:META-INF/spring/integration/flows/%s/*.xml", this.flowId) };
}
if (referencedBeanLocations != null) {
@@ -87,9 +97,7 @@ public class Flow implements InitializingBean, BeanNameAware, ChannelResolver, A
this.flowConfiguration = flowContext.getBean(FlowConfiguration.class);
Assert.notNull(flowConfiguration, "flow context does not contain a flow configuration");
if (this.help) {
System.out.println(displayFlowConfiguration());
}
validatePortMapping();
@@ -109,15 +117,19 @@ public class Flow implements InitializingBean, BeanNameAware, ChannelResolver, A
@Override
public void setBeanName(String name) {
this.name = name;
this.beanName = name;
}
public String getBeanName() {
return this.name;
return this.beanName;
}
public void setReferencedBeanLocations(String[] referencedBeanLocations) {
public void setFlowId(String flowId) {
this.flowId = flowId;
}
public void setReferencedBeanLocations(String[] referencedBeanLocations) {
this.referencedBeanLocations = referencedBeanLocations;
}
@@ -142,58 +154,12 @@ public class Flow implements InitializingBean, BeanNameAware, ChannelResolver, A
return flowChannelResolver.resolveChannelName(channelName);
}
/**
*
*/
private String displayFlowConfiguration() {
StringBuilder sb = new StringBuilder();
sb.append("\nFlow configuration for [").append(this.getBeanName()).append("]:\n");
sb.append("Port configuration:\n");
for (FlowProviderPortConfiguration portConfiguration : this.getFlowConfiguration().getPortConfigurations()) {
sb.append("\tinput port:").append(portConfiguration.getInputPortName()).append("\n\n\t")
.append(portConfiguration.getInputPortDescription()).append("\n\n").append("\toutput ports:\n");
for (NamedResourceMetadata metadata : portConfiguration.getOutputPortMetadata()) {
sb.append("\t\t").append(metadata.getName()).append("\t")
.append(metadata.getDescription()).append("\n");
}
NamedResourceConfiguration referencedBeansConfig = this.getFlowConfiguration()
.getReferencedBeansConfiguration();
if (referencedBeansConfig != null && !referencedBeansConfig.getConfiguredResources().isEmpty()) {
sb.append("\nReferenced beans:\n");
for (NamedResourceMetadata metadata : referencedBeansConfig.getConfiguredResources()) {
sb.append("\t").append(metadata).append("\n");
}
}
NamedResourceConfiguration propertiesConfig = this.getFlowConfiguration().getPropertiesConfiguration();
if (propertiesConfig != null && !propertiesConfig.getConfiguredResources().isEmpty()) {
sb.append("\nFlow properties:\n");
for (NamedResourceMetadata metadata : propertiesConfig.getConfiguredResources()) {
sb.append("\t").append(metadata).append("\n");
}
}
}
return sb.toString();
}
private void addReferencedProperties() {
if (flowProperties != null) {
PropertySource<?> propertySource = new PropertiesPropertySource("flowProperties", flowProperties);
NamedResourceConfiguration propertiesConfiguration = this.getFlowConfiguration()
.getPropertiesConfiguration();
if (propertiesConfiguration != null) {
for (NamedResourceMetadata resource : propertiesConfiguration.getRequiredResources()) {
Assert.isTrue(propertySource.containsProperty(resource.getName()), "Flow [" + this.name
+ "] is missing required property [" + resource.getName() + "]");
}
}
MutablePropertySources propertySources = flowContext.getEnvironment().getPropertySources();
propertySources.addLast(propertySource);
@@ -212,7 +178,7 @@ public class Flow implements InitializingBean, BeanNameAware, ChannelResolver, A
/*
* create a bridge for each target output port to the flow outputChannel
*/
for (FlowProviderPortConfiguration targetPortConfiguration : this.getFlowConfiguration()
for (PortConfiguration targetPortConfiguration : this.getFlowConfiguration()
.getPortConfigurations()) {
for (String outputPort : targetPortConfiguration.getOutputPortNames()) {
String targetOutputChannelName = (String) targetPortConfiguration.getOutputChannel(outputPort);

View File

@@ -24,47 +24,35 @@ import java.util.List;
*/
public class FlowConfiguration {
private final List<FlowProviderPortConfiguration> portConfigurations;
private volatile NamedResourceConfiguration propertiesConfiguration;
private volatile NamedResourceConfiguration referencedBeansConfiguration;
public FlowConfiguration(List<FlowProviderPortConfiguration> portConfigurations) {
private final List<PortConfiguration> portConfigurations;
/**
*
* @param portConfigurations
*/
public FlowConfiguration(List<PortConfiguration> portConfigurations) {
this.portConfigurations = portConfigurations;
}
public FlowProviderPortConfiguration getConfigurationForInputPort(String inputPortName) {
for (FlowProviderPortConfiguration pc : portConfigurations) {
/**
*
* @param inputPortName
* @return
*/
public PortConfiguration getConfigurationForInputPort(String inputPortName) {
for (PortConfiguration pc : portConfigurations) {
if (pc.getInputPortName().equals(inputPortName)) {
return pc;
}
}
return null;
}
public void setPropertiesConfiguration(NamedResourceConfiguration propertiesConfiguration) {
this.propertiesConfiguration = propertiesConfiguration;
}
public void setReferenceedBeansConfiguration(NamedResourceConfiguration referencedBeansConfiguration) {
this.setReferencedBeansConfiguration(referencedBeansConfiguration);
}
public List<FlowProviderPortConfiguration> getPortConfigurations() {
/**
*
* @return
*/
public List<PortConfiguration> getPortConfigurations() {
return portConfigurations;
}
public NamedResourceConfiguration getPropertiesConfiguration() {
return propertiesConfiguration;
}
public void setReferencedBeansConfiguration(NamedResourceConfiguration referencedBeansConfiguration) {
this.referencedBeansConfiguration = referencedBeansConfiguration;
}
public NamedResourceConfiguration getReferencedBeansConfiguration() {
return referencedBeansConfiguration;
}
}

View File

@@ -1,28 +0,0 @@
/*
* 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;
import java.util.List;
/**
*
* @author David Turanski
*
*/
public interface FlowProviderPortConfiguration extends PortConfiguration {
public abstract String getInputPortDescription();
public abstract List<NamedResourceMetadata> getOutputPortMetadata();
}

View File

@@ -1,65 +0,0 @@
/*
* 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;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
*
* @author David Turanski
*
*/
public class NamedResourceConfiguration {
private final List<? extends NamedResourceMetadata> resourceMetadata;
public NamedResourceConfiguration(List<? extends NamedResourceMetadata> resourceMetadata) {
this.resourceMetadata = resourceMetadata;
}
public boolean isRequired(String namedResource) {
for (NamedResourceMetadata metadata : resourceMetadata) {
if (metadata.getName().equals(namedResource)) {
return metadata.isRequired();
}
}
return false;
}
public List<NamedResourceMetadata> getConfiguredResources() {
return Collections.unmodifiableList(resourceMetadata);
}
public List<NamedResourceMetadata> getRequiredResources() {
List<NamedResourceMetadata> requiredResources = new ArrayList<NamedResourceMetadata>();
for (NamedResourceMetadata metadata : resourceMetadata) {
if (metadata.isRequired()) {
requiredResources.add(metadata);
}
}
return requiredResources;
}
public NamedResourceMetadata find(String name) {
for (NamedResourceMetadata metadata : resourceMetadata) {
if (metadata.getName().equals(name)) {
return metadata;
}
}
return null;
}
}

View File

@@ -1,60 +0,0 @@
/*
* 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;
import org.springframework.util.Assert;
/**
*
* @author David Turanski
*
*/
public class NamedResourceMetadata {
private final String name;
private final String description;
private final boolean required;
public NamedResourceMetadata(String name, String description, boolean required) {
Assert.hasText(name, "name is required");
this.name = name;
this.description = description;
this.required = required;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public boolean isRequired() {
return required;
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getName()).append("\t")
.append(required? "required" : "optional")
.append("\t")
.append(getDescription());
return sb.toString();
}
}

View File

@@ -30,5 +30,5 @@ public interface PortConfiguration {
public Collection<String> getOutputPortNames();
public Object getOutputChannel(String portName);
// TODO: Do we need error channel?
}

View File

@@ -20,20 +20,25 @@ package org.springframework.integration.flow;
* @author David Turanski
*
*/
public class PortMetadata extends NamedResourceMetadata {
public class PortMetadata {
private final String channelName;
private final String portName;
public PortMetadata(String portName, String channelName) {
this(portName, "", channelName);
this.portName = portName;
this.channelName = channelName;
}
public PortMetadata(String portName, String description, String channelName) {
super(portName, description, true);
this.channelName = channelName;
}
public String getChannelName() {
return channelName;
}
public String getChannelName() {
return channelName;
}
public String getPortName() {
return portName;
}
}

View File

@@ -23,7 +23,7 @@ import org.springframework.integration.config.AbstractSimpleMessageHandlerFactor
import org.springframework.integration.core.MessageHandler;
import org.springframework.integration.core.PollableChannel;
import org.springframework.integration.flow.Flow;
import org.springframework.integration.flow.FlowProviderPortConfiguration;
import org.springframework.integration.flow.PortConfiguration;
import org.springframework.integration.flow.handler.FlowMessageHandler;
import org.springframework.util.Assert;
@@ -45,7 +45,7 @@ public class FlowMessageHandlerFactoryBean extends AbstractSimpleMessageHandlerF
private volatile PollableChannel flowReceiveChannel;
private volatile FlowProviderPortConfiguration flowConfiguration;
private volatile PortConfiguration flowConfiguration;
@Override
protected MessageHandler createHandler() {

View File

@@ -12,6 +12,12 @@
*/
package org.springframework.integration.flow.config;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
@@ -19,41 +25,71 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.core.SubscribableChannel;
import org.springframework.integration.handler.BridgeHandler;
import org.springframework.util.ResourceUtils;
/**
* @author David Turanski
*
*
*/
public class FlowUtils {
/**
* Create a bridge
* @param inputChannel
* @param outputChannel
*/
public static void bridgeChannels(SubscribableChannel inputChannel, MessageChannel outputChannel) {
BridgeHandler bridgeHandler = new BridgeHandler();
bridgeHandler.setOutputChannel(outputChannel);
inputChannel.subscribe(bridgeHandler);
/**
* Create a bridge
*
* @param inputChannel
* @param outputChannel
*/
public static void bridgeChannels(SubscribableChannel inputChannel, MessageChannel outputChannel) {
BridgeHandler bridgeHandler = new BridgeHandler();
bridgeHandler.setOutputChannel(outputChannel);
inputChannel.subscribe(bridgeHandler);
}
/**
* Register a bean with "flow" prefix
* @param beanDefinition
* @param registry
* @return
*/
public static String registerBeanDefinition(BeanDefinition beanDefinition, BeanDefinitionRegistry registry){
String beanName = BeanDefinitionReaderUtils.generateBeanName(beanDefinition, registry);
beanName = "flow."+ beanName;
String strIndex = StringUtils.substringAfter(beanName,"#");
int index = Integer.valueOf(strIndex);
while (registry.isBeanNameInUse(beanName)){
index++;
beanName = beanName.replaceAll("#\\d$","#"+ (index));
}
registry.registerBeanDefinition(beanName, beanDefinition);
return beanName;
}
/**
* Register a bean with "flow" prefix
*
* @param beanDefinition
* @param registry
* @return
*/
public static String registerBeanDefinition(BeanDefinition beanDefinition, BeanDefinitionRegistry registry) {
String beanName = BeanDefinitionReaderUtils.generateBeanName(beanDefinition, registry);
beanName = "flow." + beanName;
String strIndex = StringUtils.substringAfter(beanName, "#");
int index = Integer.valueOf(strIndex);
while (registry.isBeanNameInUse(beanName)) {
index++;
beanName = beanName.replaceAll("#\\d$", "#" + (index));
}
registry.registerBeanDefinition(beanName, beanDefinition);
return beanName;
}
public static String getDocumentation(String flowName) {
String path = String.format("classpath:META-INF/spring/integration/flows/%s/flow.doc", flowName);
try {
File file = ResourceUtils.getFile(path);
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
StringBuilder result = new StringBuilder();
while ((line = br.readLine()) != null) {
result.append(line).append("\n");
}
br.close();
return result.toString();
} catch (FileNotFoundException e) {
return "no help available";
} catch (IOException e) {
e.printStackTrace();
return "no help available";
}
}
}

View File

@@ -16,6 +16,7 @@
package org.springframework.integration.flow.config.xml;
import java.util.List;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
@@ -24,8 +25,6 @@ import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.flow.ChannelNamePortConfiguration;
import org.springframework.integration.flow.FlowConfiguration;
import org.springframework.integration.flow.NamedResourceConfiguration;
import org.springframework.integration.flow.NamedResourceMetadata;
import org.springframework.integration.flow.PortMetadata;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
@@ -57,19 +56,8 @@ public class FlowConfigurationParser implements BeanDefinitionParser {
flowConfigurationBuilder.addConstructorArgValue(portConfigList);
BeanDefinition referencedProperties = this.buildNamedResourceConfiguration(element, "referenced-property");
flowConfigurationBuilder.addPropertyValue("propertiesConfiguration", referencedProperties);
BeanDefinition referencedBeans = this.buildNamedResourceConfiguration(element, "referenced-bean");
flowConfigurationBuilder.addPropertyValue("referencedBeansConfiguration", referencedBeans);
BeanDefinitionReaderUtils.registerWithGeneratedName(flowConfigurationBuilder.getBeanDefinition(),
parserContext.getRegistry());
parserContext.getRegistry());
return null;
}
@@ -101,38 +89,10 @@ public class FlowConfigurationParser implements BeanDefinitionParser {
return portConfigurationBuilder.getBeanDefinition();
}
private BeanDefinition buildNamedResourceConfiguration(Element parent, String elementName) {
ManagedList<Object> namedResourceList = new ManagedList<Object>();
List<Element> namedResources = DomUtils.getChildElementsByTagName(parent, elementName);
for (Element el : namedResources ) {
BeanDefinitionBuilder namedResourceBuilder = BeanDefinitionBuilder.genericBeanDefinition(NamedResourceMetadata.class);
boolean required = ("true".equals(el.getAttribute("required")));
String name = el.getAttribute("id");
String description = getChildElementText(el, "description", "");
namedResourceBuilder.addConstructorArgValue(name);
namedResourceBuilder.addConstructorArgValue(description);
namedResourceBuilder.addConstructorArgValue(required);
namedResourceList.add(namedResourceBuilder.getBeanDefinition());
}
BeanDefinitionBuilder namedResourceConfigurationBuilder = BeanDefinitionBuilder.genericBeanDefinition(NamedResourceConfiguration.class);
namedResourceConfigurationBuilder.addConstructorArgValue(namedResourceList);
return namedResourceConfigurationBuilder.getBeanDefinition();
}
private String getChildElementText(Element parent, String elementName, String defaultValue ){
String value = defaultValue;
Element child = DomUtils.getChildElementByTagName(parent, elementName);
if (child != null ) {
value = child.getTextContent();
}
return value;
}
private BeanDefinition buildPortMetadata(Element element, Element portElement) {
BeanDefinitionBuilder portMetadataBuilder = BeanDefinitionBuilder.genericBeanDefinition(PortMetadata.class);
portMetadataBuilder.addConstructorArgValue(portElement.getAttribute("name"));
String description = getChildElementText(portElement, "description", "");
portMetadataBuilder.addConstructorArgValue(description);
portMetadataBuilder.addConstructorArgValue(portElement.getAttribute("channel"));
return portMetadataBuilder.getBeanDefinition();
}

View File

@@ -29,7 +29,7 @@ public class FlowNamespaceHandler extends AbstractIntegrationNamespaceHandler {
registerBeanDefinitionParser("flow", new FlowParser());
registerBeanDefinitionParser("outbound-gateway", new FlowOutboundGatewayParser());
registerBeanDefinitionParser("flow-configuration", new FlowConfigurationParser());
registerBeanDefinitionParser("port-mapping", new FlowProviderPortConfigurationParser());
registerBeanDefinitionParser("port-mapping", new FlowPortConfigurationParser());
}
}

View File

@@ -45,6 +45,7 @@ public class FlowParser implements BeanDefinitionParser {
IntegrationNamespaceUtils.setValueIfAttributeDefined(flowBuilder, element, "referenced-bean-locations");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(flowBuilder, element, "properties");
IntegrationNamespaceUtils.setValueIfAttributeDefined(flowBuilder, element, "help");
IntegrationNamespaceUtils.setValueIfAttributeDefined(flowBuilder, element, "flow-id");
BeanDefinition beanDefinition = flowBuilder.getBeanDefinition();
parserContext.getRegistry().registerBeanDefinition(id, beanDefinition);

View File

@@ -25,7 +25,7 @@ import org.w3c.dom.Element;
* @author David Turanski
*
*/
public class FlowProviderPortConfigurationParser implements BeanDefinitionParser {
public class FlowPortConfigurationParser implements BeanDefinitionParser {
@Override
public BeanDefinition parse(Element arg0, ParserContext arg1) {

View File

@@ -84,7 +84,7 @@ public class FlowMessageHandler extends AbstractReplyProducingMessageHandler {
}
}
} catch (MessagingException me) {
log.debug("caught exception - failed message: " + me.getFailedMessage());
log.error(me.getMessage(), me);
if (conversationId.equals(me.getFailedMessage().getHeaders().get("flow.conversation.id"))) {
return new ErrorMessage(me);
}

View File

@@ -44,6 +44,14 @@
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="flow-id" type="xsd:string"
use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Flow id
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
@@ -105,8 +113,7 @@
<xsd:element name="port-mapping" type="PortMappingType" />
</xsd:choice>
<xsd:element name="referenced-bean" minOccurs="0" maxOccurs="unbounded" type="NamedResourceType"/>
<xsd:element name="referenced-property" minOccurs="0" maxOccurs="unbounded" type="NamedResourceType"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
@@ -129,52 +136,17 @@
<xsd:attribute name="channel" type="xsd:string" use="required" />
</xsd:complexType>
<xsd:complexType name="FlowPortType">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines an integration flow port binding
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexContent>
<xsd:extension base="BasePortType">
<xsd:sequence>
<xsd:element name="description" minOccurs="0"
maxOccurs="1" type="xsd:string" />
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="FlowOutputPortType">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines an integration flow output port binding
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexContent>
<xsd:extension base="FlowPortType">
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="PortMappingType">
<xsd:sequence>
<xsd:element name="input-port" minOccurs="1" maxOccurs="1"
nillable="false" type="FlowPortType">
nillable="false" type="BasePortType">
</xsd:element>
<xsd:element name="output-port" minOccurs="0" maxOccurs="unbounded" type="FlowOutputPortType"/>
<xsd:element name="output-port" minOccurs="0" maxOccurs="unbounded" type="BasePortType"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="NamedResourceType">
<xsd:sequence>
<xsd:element name="description" type="xsd:string" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="required" type="xsd:boolean" default="false">
</xsd:attribute>
<xsd:attribute name="id" use="required" type="xsd:ID">
</xsd:attribute>
</xsd:complexType>
</xsd:schema>

View File

@@ -1,43 +0,0 @@
/*
* 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
import org.junit.Test
/**
*
* @author David Turanski
*
*/
class NamedResourcesConfigurationTest {
def resourceMetadataList = [
new NamedResourceMetadata('resource1','describes resource1',true),
new NamedResourceMetadata('resource2','describes resource2',false),
new NamedResourceMetadata('resource3','describes resource3',true)
]
@Test
public void testGetRequired(){
def namedResourceConfiguration = new NamedResourceConfiguration(resourceMetadataList);
def required = namedResourceConfiguration.getRequiredResources()
assert required.size() == 2
required.each { assert it.required; assert namedResourceConfiguration.isRequired(it.name) }
}
@Test
public void testGetAll(){
def namedResourceConfiguration = new NamedResourceConfiguration(resourceMetadataList);
assert namedResourceConfiguration.getConfiguredResources().size() == 3
}
}

View File

@@ -15,13 +15,14 @@
*/
package org.springframework.integration.flow.config.xml;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
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.FlowConfiguration;
import org.springframework.integration.flow.FlowProviderPortConfiguration;
import org.springframework.integration.flow.PortConfiguration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -40,10 +41,10 @@ public class FlowConfigNamespaceTest {
public void test() {
assertNotNull(flowConfiguration.getPortConfigurations());
assertEquals(2, flowConfiguration.getPortConfigurations().size());
FlowProviderPortConfiguration pc0 = flowConfiguration.getPortConfigurations().get(0);
PortConfiguration pc0 = flowConfiguration.getPortConfigurations().get(0);
assertEquals("input", pc0.getInputPortName());
assertEquals("subflow-input", pc0.getInputChannel());
assertEquals("", pc0.getInputPortDescription());
assertEquals("subflow-output", pc0.getOutputChannel("output"));
assertEquals(1, pc0.getOutputPortNames().size());
}

View File

@@ -18,7 +18,6 @@ package org.springframework.integration.flow.config.xml;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
@@ -54,7 +53,7 @@ public class FlowWithErrorTest {
@Test
public void testDirectCallWithErrorChannel(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:/META-INF/spring/integration/flows/subflow5-context.xml");
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:/META-INF/spring/integration/flows/subflow5/subflow5-context.xml");
MessageChannel input = applicationContext.getBean("subflow-input",MessageChannel.class);
SubscribableChannel error = applicationContext.getBean("errorChannel",SubscribableChannel.class);

View File

@@ -17,10 +17,8 @@ package org.springframework.integration.flow.config.xml;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import org.junit.Test;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.Message;
@@ -50,16 +48,5 @@ public class FlowWithReferencesTest {
assertEquals("undefined",reply.getHeaders().get("property.value.2"));
}
@Test
public void testMissingPropertyReference() {
try {
new ClassPathXmlApplicationContext("classpath:/FlowWithMissingReferencesTest-context.xml");
fail("should throw exception");
} catch (BeanCreationException e) {
if(!("Flow [subflow3] is missing required property [key1]".equals(e.getCause().getMessage() ) ) ) {
e.printStackTrace();
fail(e.getMessage());
}
}
}
}

View File

@@ -1,37 +1,35 @@
<?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.0.xsd
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.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<int-flow:flow-configuration>
<int-flow:flow-configuration>
<int-flow:port-mapping>
<int-flow:input-port name="input" channel="subflow-input">
<int-flow:description></int-flow:description>
</int-flow:input-port>
<int-flow:output-port name="output" channel="subflow-output">
<int-flow:description></int-flow:description>
</int-flow:output-port>
</int-flow:port-mapping>
<int-flow:port-mapping-ref bean="portConfig1" />
<int-flow:port-mapping>
<int-flow:input-port name="input"
channel="subflow-input" />
<int-flow:port-mapping>
<int-flow:input-port name="input2" channel="subflow-input2">
<int-flow:description></int-flow:description>
</int-flow:input-port>
<int-flow:output-port name="output2" channel="subflow-output2">
<int-flow:description></int-flow:description>
</int-flow:output-port>
</int-flow:port-mapping>
<int-flow:output-port name="output"
channel="subflow-output" />
<int-flow:port-mapping-ref bean="portConfig2" />
</int-flow:port-mapping>
</int-flow:flow-configuration>
<int-flow:port-mapping-ref bean="portConfig1" />
<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: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:port-mapping-ref bean="portConfig2" />
</int-flow:flow-configuration>
<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>
</beans>

View File

@@ -1,19 +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"
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-2.0.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">
<util:properties id="flowProperties">
<prop key="key2">val1</prop>
</util:properties>
<!-- Instantiate the flow -->
<int-flow:flow id="subflow3" help="true" referenced-bean-locations="classpath:ref-bean-config.xml" properties="flowProperties"/>
</beans>

View File

@@ -11,18 +11,9 @@
<int-flow:flow-configuration>
<int-flow:port-mapping>
<int-flow:input-port name="gateway-input"
channel="subflow-input">
<int-flow:description></int-flow:description>
</int-flow:input-port>
<int-flow:output-port name="gateway-output"
channel="hello-output">
<int-flow:description></int-flow:description>
</int-flow:output-port>
<int-flow:output-port name="gateway-discard"
channel="world-output">
<int-flow:description></int-flow:description>
</int-flow:output-port>
<int-flow:input-port name="gateway-input" channel="subflow-input"/>
<int-flow:output-port name="gateway-output" channel="hello-output"/>
<int-flow:output-port name="gateway-discard" channel="world-output"/>
</int-flow:port-mapping>
</int-flow:flow-configuration>

View File

@@ -19,7 +19,6 @@
<int-flow:input-port name="input" channel="subflow-input" />
<int-flow:output-port name="output" channel="subflow-output" />
</int-flow:port-mapping>
<int-flow:referenced-bean id="refbean" required="true" />
</int-flow:flow-configuration>
<int:channel id="subflow-output" />

View File

@@ -1,37 +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:util="http://www.springframework.org/schema/util"
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"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.0.xsd
http://www.springframework.org/schema/integration/flow http://www.springframework.org/schema/integration/flow/spring-integration-flow-2.0.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.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<!-- Need to set ignore-unresolvable true or provide defaults for required properties -->
<context:property-placeholder ignore-unresolvable="true"/>
<int-flow:flow-configuration>
<int-flow:port-mapping>
<int-flow:input-port name="input" channel="subflow-input">
<int-flow:description>This optionally describes the flow</int-flow:description>
</int-flow:input-port>
<int-flow:output-port name="output" channel="subflow-output">
<int-flow:description>This describes the purpose/ necessary conditions for this output</int-flow:description>
</int-flow:output-port>
</int-flow:port-mapping>
<int-flow:referenced-property id="key1" required="true">
<int-flow:description>This is an example of a required property</int-flow:description>
</int-flow:referenced-property>
<int-flow:referenced-property id="key2" required="false">
<int-flow:description>This is an example of an optional property</int-flow:description>
</int-flow:referenced-property>
</int-flow:flow-configuration>
<int:channel id="subflow-output" />
</beans>

View File

@@ -13,12 +13,8 @@
<int-flow:flow-configuration>
<int-flow:port-mapping>
<int-flow:input-port name="input" channel="subflow-input">
<int-flow:description>This optionally describes the flow</int-flow:description>
</int-flow:input-port>
<int-flow:output-port name="output" channel="subflow-output">
<int-flow:description>This describes the purpose/ necessary conditions for this output</int-flow:description>
</int-flow:output-port>
<int-flow:input-port name="input" channel="subflow-input"/>
<int-flow:output-port name="output" channel="subflow-output"/>
</int-flow:port-mapping>
</int-flow:flow-configuration>

View File

@@ -13,16 +13,9 @@
<int-flow:flow-configuration>
<int-flow:port-mapping>
<int-flow:input-port name="input" channel="subflow-input">
<int-flow:description>This optionally describes the flow</int-flow:description>
</int-flow:input-port>
<int-flow:output-port name="output" channel="subflow-output">
<int-flow:description>This describes the purpose/ necessary conditions for this output</int-flow:description>
</int-flow:output-port>
<int-flow:output-port name="error" channel="errorChannel">
<int-flow:description>This describes the purpose/ necessary conditions for this output</int-flow:description>
</int-flow:output-port>
<int-flow:input-port name="input" channel="subflow-input"/>
<int-flow:output-port name="output" channel="subflow-output"/>
<int-flow:output-port name="error" channel="errorChannel"/>
</int-flow:port-mapping>
</int-flow:flow-configuration>

View File

@@ -16,7 +16,7 @@
</logger>
<logger name="org.springframework.integration">
<level value="debug" />
<level value="info" />
</logger>
<!-- Root Logger -->