Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

INTSAMPLES-39 Dynamic FTP Router #20

Merged
merged 3 commits into from

2 participants

@garyrussell
Collaborator

Demonstrates the use of Spring 3.1 to instantiate multiple
application contexts, each with a differently configured
ftp outbound adapter, together with a POJO Channel resolver
used to send messages to the appropriate context.

garyrussell added some commits
@garyrussell garyrussell INTSAMPLES-39 Dynamic FTP Router
Demonstrates the use of Spring 3.1 to instantiate multiple
application contexts, each with a differently configured
ftp outbound adapter, together with a POJO Channel resolver
used to send messages to the appropriate context.
be5bcb3
@garyrussell garyrussell INTSAMPLES-39 Add surefire to pom; add to Parent
Add surefire tests to pom; add module to advanced pom.
c15d2dd
advanced/dynamic-ftp/readme.txt
@@ -0,0 +1,28 @@
+This example demonstrates one technique for sending files to dynamic destinations.
@ghillert Collaborator

Would you possibly mind to provide the readme as a README.md file using Markdown? That way it looks a little bit more pleasing to the eye via GitHub.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
...tion/samples/ftp/FtpOutboundChannelAdapterSample.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2002-2010 the original author or authors.
@ghillert Collaborator

change 2010 to 2011

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@ghillert
Collaborator

Looks good otherwise - Cool Sample!

@garyrussell garyrussell INTSAMPLES-39 Polishing
Change ReadMe to Markdown; fix Copyright
6e437c0
@garyrussell
Collaborator

Both done; thanks for reviewing.

@ghillert ghillert merged commit 4e95a0f into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Dec 15, 2011
  1. @garyrussell

    INTSAMPLES-39 Dynamic FTP Router

    garyrussell authored
    Demonstrates the use of Spring 3.1 to instantiate multiple
    application contexts, each with a differently configured
    ftp outbound adapter, together with a POJO Channel resolver
    used to send messages to the appropriate context.
  2. @garyrussell

    INTSAMPLES-39 Add surefire to pom; add to Parent

    garyrussell authored
    Add surefire tests to pom; add module to advanced pom.
  3. @garyrussell

    INTSAMPLES-39 Polishing

    garyrussell authored
    Change ReadMe to Markdown; fix Copyright
This page is out of date. Refresh to see the latest.
View
28 advanced/dynamic-ftp/README.md
@@ -0,0 +1,28 @@
+This example demonstrates one technique for sending files to dynamic destinations.
+
+See DynamicFtpChannelResolver. The resolve() method maps a customer to a
+channel, where the channel is defined in a separate application context
+for each customer. The application context property placeholders are configured
+using the Spring 3.1 Environment management by supplying a custom property
+source.
+
+A real implementation would provide these properties based on the customer; this
+sample simply uses the customer as part of the host name.
+
+The application context is loaded from the file in src/main/resources/...
+
+DynamicFtpChannelResolverTests is a simple JUnit test case that verifies
+the same channel is used for the same customer each time, and that a
+different channel is used for a different customer.
+
+FtpOutboundChannelAdapterSample shows how messages sent with a different customer
+header are routed to a different ftp adapter. It simply verifies that the
+correct UnknownHostException is returned.
+
+Notice in the config file how an expression-based router is used to invoke
+the DynamicFtpChannelResolver to obtain a reference to the appropriate
+channel for the customer. Notice that the channel resolver is a simple
+POJO, invoked using SpEL...
+
+ <int:router input-channel="toDynRouter"
+ expression="@channelResolver.resolve(headers['customer'])"/>
View
92 advanced/dynamic-ftp/pom.xml
@@ -0,0 +1,92 @@
+<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/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.springframework.integration.samples</groupId>
+ <artifactId>dynamic-ftp</artifactId>
+ <version>2.1.0</version>
+ <name>Dynamic FTP Demo</name>
+ <packaging>jar</packaging>
+ <properties>
+ <spring.framework.version>3.1.0.RELEASE</spring.framework.version>
+ <spring.integration.version>2.1.0.RC1</spring.integration.version>
+ <log4j.version>1.2.16</log4j.version>
+ <junit.version>4.7</junit.version>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ <version>${spring.framework.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.integration</groupId>
+ <artifactId>spring-integration-ftp</artifactId>
+ <version>${spring.integration.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>${log4j.version}</version>
+ </dependency>
+ <!-- test-scoped dependencies -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${junit.version}</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <testResources>
+ <testResource>
+ <directory>src/test/java</directory>
+ <includes>
+ <include>**/*</include>
+ </includes>
+ </testResource>
+ <testResource>
+ <directory>src/test/resources</directory>
+ <includes>
+ <include>**/*</include>
+ </includes>
+ </testResource>
+ </testResources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ <compilerArgument>-Xlint:all</compilerArgument>
+ <showWarnings>true</showWarnings>
+ <showDeprecation>false</showDeprecation>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>**/*Tests.java</include>
+ <include>**/*Sample.java</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <repositories>
+ <repository>
+ <id>repository.springframework.maven.release</id>
+ <name>Spring Framework Maven Release Repository</name>
+ <url>http://maven.springframework.org/release</url>
+ </repository>
+ <repository>
+ <id>repository.springframework.maven.milestone</id>
+ <name>Spring Framework Maven Milestone Repository</name>
+ <url>http://maven.springframework.org/milestone</url>
+ </repository>
+ <repository>
+ <id>repository.springframework.maven.snapshot</id>
+ <name>Spring Framework Maven Snapshot Repository</name>
+ <url>http://maven.springframework.org/snapshot</url>
+ </repository>
+ </repositories>
+</project>
View
82 ...ced/dynamic-ftp/src/main/java/org/springframework/integration/samples/ftp/DynamicFtpChannelResolver.java
@@ -0,0 +1,82 @@
+/*
+ * 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.samples.ftp;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.core.env.PropertiesPropertySource;
+import org.springframework.core.env.StandardEnvironment;
+import org.springframework.integration.MessageChannel;
+
+/**
+ * Demonstrates how a dynamic Spring Integration flow snippet can be used
+ * to send files to dynamic destinations.
+ *
+ * @author Gary Russell
+ * @since 2.1
+ *
+ */
+public class DynamicFtpChannelResolver {
+
+ private final Map<String, MessageChannel> channels = new HashMap<String, MessageChannel>();
+
+ /**
+ * Resolve a customer to a channel, where each customer gets a private
+ * application context and the channel is the inbound channel to that
+ * application context.
+ *
+ * @param customer
+ * @return a channel
+ */
+ public MessageChannel resolve(String customer) {
+ MessageChannel channel = this.channels.get(customer);
+ if (channel == null) {
+ ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext(
+ new String[] { "/META-INF/spring/integration/dynamic-ftp-outbound-adapter-context.xml" },
+ false);
+ this.setEnvironmentForCustomer(ctx, customer);
+ ctx.refresh();
+ channel = ctx.getBean("toFtpChannel", MessageChannel.class);
+ this.channels.put(customer, channel);
+ }
+ return channel;
+ }
+
+ /**
+ * Use Spring 3.1. environment support to set properties for the
+ * customer-specific application context.
+ *
+ * @param ctx
+ * @param customer
+ */
+ private void setEnvironmentForCustomer(ConfigurableApplicationContext ctx,
+ String customer) {
+ StandardEnvironment env = new StandardEnvironment();
+ Properties props = new Properties();
+ // populate properties for customer
+ props.setProperty("host", "host.for." + customer);
+ props.setProperty("user", "user");
+ props.setProperty("password", "password");
+ props.setProperty("remote.directory", "/tmp");
+ PropertiesPropertySource pps = new PropertiesPropertySource("ftpprops", props);
+ env.getPropertySources().addLast(pps);
+ ctx.setEnvironment(env);
+ }
+}
View
27 ...nced/dynamic-ftp/src/main/resources/META-INF/spring/integration/dynamic-ftp-outbound-adapter-context.xml
@@ -0,0 +1,27 @@
+<?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-ftp="http://www.springframework.org/schema/integration/ftp"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
+ http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.1.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
+ http://www.springframework.org/schema/integration/ftp http://www.springframework.org/schema/integration/ftp/spring-integration-ftp-2.1.xsd">
+
+ <context:property-placeholder />
+
+ <bean id="ftpClientFactory" class="org.springframework.integration.ftp.session.DefaultFtpSessionFactory">
+ <property name="host" value="${host}"/>
+ <property name="username" value="${user}"/>
+ <property name="password" value="${password}"/>
+ </bean>
+
+ <int:channel id="toFtpChannel"/>
+
+ <int-ftp:outbound-channel-adapter id="ftpOutbound"
+ channel="toFtpChannel"
+ remote-directory="${remote.directory}"
+ session-factory="ftpClientFactory"/>
+
+</beans>
View
45 ...ynamic-ftp/src/test/java/org/springframework/integration/samples/ftp/DynamicFtpChannelResolverTests.java
@@ -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.samples.ftp;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+import org.springframework.integration.MessageChannel;
+
+/**
+ * @author Gary Russell
+ * @since 2.1
+ *
+ */
+public class DynamicFtpChannelResolverTests {
+
+ /**
+ * Test method for {@link org.springframework.integration.samples.ftp.DynamicFtpChannelResolver#resolve(java.lang.String)}.
+ */
+ @Test
+ public void testResolve() {
+ DynamicFtpChannelResolver dynamicFtpChannelResolver = new DynamicFtpChannelResolver();
+ MessageChannel channel1 = dynamicFtpChannelResolver.resolve("customer1");
+ assertNotNull(channel1);
+ MessageChannel channel2 = dynamicFtpChannelResolver.resolve("customer2");
+ assertNotNull(channel2);
+ assertNotSame(channel1, channel2);
+ MessageChannel channel1a = dynamicFtpChannelResolver.resolve("customer1");
+ assertSame(channel1, channel1a);
+ }
+
+}
View
70 ...namic-ftp/src/test/java/org/springframework/integration/samples/ftp/FtpOutboundChannelAdapterSample.java
@@ -0,0 +1,70 @@
+/*
+ * 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.samples.ftp;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.net.UnknownHostException;
+
+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.MessageHandlingException;
+import org.springframework.integration.support.MessageBuilder;
+
+/**
+ * @author Gary Russell
+ *
+ */
+public class FtpOutboundChannelAdapterSample {
+
+ @Test
+ public void runDemo() throws Exception{
+ ApplicationContext ctx =
+ new ClassPathXmlApplicationContext("META-INF/spring/integration/DynamicFtpOutboundChannelAdapterSample-context.xml");
+ MessageChannel channel = ctx.getBean("toDynRouter", MessageChannel.class);
+ File file = File.createTempFile("temp", "txt");
+ Message<File> message = MessageBuilder.withPayload(file)
+ .setHeader("customer", "cust1")
+ .build();
+ try {
+ channel.send(message);
+ } catch (MessageHandlingException e) {
+ assertTrue(e.getCause().getCause() instanceof UnknownHostException);
+ assertEquals("host.for.cust1", e.getCause().getCause().getMessage());
+ }
+ // send another so we can see in the log we don't create the ac again.
+ try {
+ channel.send(message);
+ } catch (MessageHandlingException e) {
+ assertTrue(e.getCause().getCause() instanceof UnknownHostException);
+ assertEquals("host.for.cust1", e.getCause().getCause().getMessage());
+ }
+ // send to a different customer; again, check the log to see a new ac is built
+ message = MessageBuilder.withPayload(file)
+ .setHeader("customer", "cust2").build();
+ try {
+ channel.send(message);
+ } catch (MessageHandlingException e) {
+ assertTrue(e.getCause().getCause() instanceof UnknownHostException);
+ assertEquals("host.for.cust2", e.getCause().getCause().getMessage());
+ }
+ }
+}
View
17 ...ic-ftp/src/test/resources/META-INF/spring/integration/DynamicFtpOutboundChannelAdapterSample-context.xml
@@ -0,0 +1,17 @@
+<?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:context="http://www.springframework.org/schema/context"
+ xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.1.xsd
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
+
+ <bean id="channelResolver" class="org.springframework.integration.samples.ftp.DynamicFtpChannelResolver" />
+
+ <int:channel id="toDynRouter" />
+
+ <int:router input-channel="toDynRouter"
+ expression="@channelResolver.resolve(headers['customer'])"/>
+
+</beans>
View
8 advanced/dynamic-ftp/src/test/resources/log4j.properties
@@ -0,0 +1,8 @@
+log4j.rootCategory=WARN, stdout
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %t %c{2}:%L - %m%n
+
+log4j.category.org.springframework=WARN
+log4j.category.org.springframework.integration=DEBUG
View
1  advanced/pom.xml
@@ -11,6 +11,7 @@
<modules>
<module>advanced-testing-examples</module>
+ <module>dynamic-ftp</module>
</modules>
</project>
Something went wrong with that request. Please try again.