Merge remote-tracking branch 'upstream/master' into 4.0.0-WIP
Conflicts: spring-integration-core/src/main/java/org/springframework/integration/gateway/MessagingGatewaySupport.java spring-integration-core/src/main/java/org/springframework/integration/support/channel/BeanFactoryChannelResolver.java spring-integration-core/src/main/java/org/springframework/integration/util/MessagingMethodInvokerHelper.java spring-integration-core/src/test/java/org/springframework/integration/config/AggregatorParserTests.java spring-integration-core/src/test/java/org/springframework/integration/config/annotation/AggregatorAnnotationTests.java spring-integration-core/src/test/java/org/springframework/integration/config/xml/ControlBusTests.java spring-integration-file/src/main/java/org/springframework/integration/file/DefaultFileNameGenerator.java spring-integration-file/src/main/java/org/springframework/integration/file/remote/handler/FileTransferringMessageHandler.java spring-integration-file/src/test/java/org/springframework/integration/file/remote/gateway/RemoteFileOutboundGatewayTests.java spring-integration-ftp/src/test/java/org/springframework/integration/ftp/config/FtpOutboundGatewayParserTests.java spring-integration-ftp/src/test/java/org/springframework/integration/ftp/inbound/FtpInboundRemoteFileSystemSynchronizerTests.java spring-integration-ftp/src/test/java/org/springframework/integration/ftp/outbound/FtpServerOutboundTests.java spring-integration-groovy/src/main/java/org/springframework/integration/groovy/GroovyScriptExecutingMessageProcessor.java spring-integration-http/src/test/java/org/springframework/integration/http/outbound/UriVariableExpressionTests.java spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/connection/HelloWorldInterceptor.java spring-integration-jpa/src/test/java/org/springframework/integration/jpa/outbound/JpaOutboundGatewayIntegrationTests.java spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/store/MongoDbMessageGroupStoreTests.java spring-integration-mongodb/src/test/java/org/springframework/integration/mongodb/store/MongoDbMessageStoreTests.java spring-integration-redis/src/test/java/org/springframework/integration/redis/config/RedisOutboundChannelAdapterParserTests.java spring-integration-sftp/src/test/java/org/springframework/integration/sftp/config/SftpOutboundGatewayParserTests.java spring-integration-sftp/src/test/java/org/springframework/integration/sftp/inbound/SftpInboundRemoteFileSystemSynchronizerTests.java spring-integration-sftp/src/test/java/org/springframework/integration/sftp/outbound/SftpServerOutboundTests.java Resolved.
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* 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.ftp.filters;
|
||||
|
||||
|
||||
import org.apache.commons.net.ftp.FTPFile;
|
||||
|
||||
import org.springframework.integration.file.filters.AbstractPersistentAcceptOnceFileListFilter;
|
||||
import org.springframework.integration.metadata.MetadataStore;
|
||||
|
||||
/**
|
||||
* Since the super class deems files as 'not seen' if the timestamp is different, remote file
|
||||
* users should use the adapter's preserve-timestamp option. Otherwise if a file is re-fetched
|
||||
* it will have a new timestamp.
|
||||
*
|
||||
* @author Gary Russell
|
||||
* @since 3.0
|
||||
*
|
||||
*/
|
||||
public class FtpPersistentAcceptOnceFileListFilter extends AbstractPersistentAcceptOnceFileListFilter<FTPFile> {
|
||||
|
||||
public FtpPersistentAcceptOnceFileListFilter(MetadataStore store, String prefix) {
|
||||
super(store, prefix);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long modified(FTPFile file) {
|
||||
return file.getTimestamp().getTimeInMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String fileName(FTPFile file) {
|
||||
return file.getName();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import java.util.List;
|
||||
import org.apache.commons.net.ftp.FTPFile;
|
||||
|
||||
import org.springframework.integration.file.remote.AbstractFileInfo;
|
||||
import org.springframework.integration.file.remote.RemoteFileTemplate;
|
||||
import org.springframework.integration.file.remote.gateway.AbstractRemoteFileOutboundGateway;
|
||||
import org.springframework.integration.file.remote.session.SessionFactory;
|
||||
import org.springframework.integration.ftp.session.FtpFileInfo;
|
||||
@@ -40,6 +41,11 @@ public class FtpOutboundGateway extends AbstractRemoteFileOutboundGateway<FTPFil
|
||||
super(sessionFactory, command, expression);
|
||||
}
|
||||
|
||||
private FtpOutboundGateway(RemoteFileTemplate<FTPFile> remoteFileTemplate, String command, String expression) {
|
||||
super(remoteFileTemplate, command, expression);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean isDirectory(FTPFile file) {
|
||||
return file.isDirectory();
|
||||
|
||||
@@ -26,73 +26,6 @@
|
||||
<xsd:all>
|
||||
<xsd:element name="request-handler-advice-chain" type="integration:adviceChainType" minOccurs="0" maxOccurs="1" />
|
||||
</xsd:all>
|
||||
<xsd:attribute name="remote-directory-expression"
|
||||
type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Allows you to provide a SpEL expression which
|
||||
will compute the directory
|
||||
path where the files will be transferred to
|
||||
(e.g., "headers.['remote_dir'] +
|
||||
'/myTransfers'");
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="temporary-remote-directory-expression"
|
||||
type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Allows you to provide a SpEL expression which
|
||||
will compute the temporary directory
|
||||
path where files will be transferred to before they are moved to the remote-directory
|
||||
(e.g., "headers.['remote_dir'] +
|
||||
'/temp/myTransfers'");
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="auto-create-directory" type="xsd:string"
|
||||
default="false">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Specify whether to automatically create the
|
||||
remote target directory if
|
||||
it doesn't exist.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="remote-filename-generator" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Allows you to specify a reference to
|
||||
[org.springframework.integration.file.FileNameGenerator] bean.
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type
|
||||
type="org.springframework.integration.file.FileNameGenerator" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="remote-filename-generator-expression"
|
||||
type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Allows you to provide SpEL expression which
|
||||
will compute file name of
|
||||
the remote file (e.g., assuming payload
|
||||
is java.io.File
|
||||
"payload.getName() + '.transfered'");
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="use-temporary-file-name" type="xsd:string" default="true">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Allows you to suppress using a temporary file name while writing the file.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="order" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
@@ -113,6 +46,7 @@
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attributeGroup ref="int-file:remoteOutboundAttributeGroup" />
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
@@ -268,7 +202,7 @@
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="base-adapter-type">
|
||||
<xsd:extension base="base-ftp-adapter-type">
|
||||
<xsd:all>
|
||||
<xsd:element name="request-handler-advice-chain" type="integration:adviceChainType" minOccurs="0" maxOccurs="1" />
|
||||
</xsd:all>
|
||||
@@ -379,7 +313,9 @@
|
||||
<xsd:documentation>
|
||||
Allows you to specify a reference to
|
||||
[org.springframework.integration.file.filters.FileListFilter]
|
||||
bean.
|
||||
bean. This filter acts against the remote server view when using the 'ls'
|
||||
or 'mget' commands.
|
||||
Only one of 'filter', 'filename-pattern', or 'filename-regex' is allowed.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
@@ -387,10 +323,11 @@
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Allows you to provide file name pattern to
|
||||
determine the file names retrieved by the ls command
|
||||
determine the file names retrieved by the 'ls' and 'mget' commands
|
||||
and is based
|
||||
on simple pattern matching algorithm (e.g., "*.txt, fo*.txt"
|
||||
etc.)
|
||||
Only one of 'filter', 'filename-pattern', or 'filename-regex' is allowed.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
@@ -398,9 +335,49 @@
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Allows you to provide Regular Expression to
|
||||
determine the file names retrieved by the ls command.
|
||||
determine the file names retrieved by the 'ls' and 'mget' commands.
|
||||
(e.g.,
|
||||
"f[o]+\.txt" etc.)
|
||||
Only one of 'filter', 'filename-pattern', or 'filename-regex' is allowed.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="mput-filter" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type
|
||||
type="org.springframework.integration.file.filters.FileListFilter" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
Allows you to specify a reference to
|
||||
[org.springframework.integration.file.filters.FileListFilter]
|
||||
bean. This filter acts on the local file system when using the 'mput' command.
|
||||
Only one of 'mput-filter', 'mput-pattern', or 'mput-regex' is allowed.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="mput-pattern" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Allows you to provide file name pattern to
|
||||
determine the file names sent by the 'mput' command
|
||||
and is based
|
||||
on simple pattern matching algorithm (e.g., "*.txt, fo*.txt"
|
||||
etc.)
|
||||
Only one of 'mput-filter', 'mput-pattern', or 'mput-regex' is allowed.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="mput-regex" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Allows you to provide Regular Expression to
|
||||
determine the file names sent by the 'mput' command
|
||||
(e.g.,
|
||||
"f[o]+\.txt" etc.)
|
||||
Only one of 'mput-filter', 'mput-pattern', or 'mput-regex' is allowed.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
@@ -486,6 +463,7 @@
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attributeGroup ref="int-file:remoteOutboundAttributeGroup" />
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
|
||||
@@ -101,7 +101,7 @@ public class TesFtpServer {
|
||||
fos.close();
|
||||
|
||||
targetFtpDirectory = new File(ftpRootFolder, "ftpTarget");
|
||||
targetFtpDirectory.mkdirs();
|
||||
targetFtpDirectory.mkdir();
|
||||
}
|
||||
};
|
||||
this.localFolder = new TemporaryFolder() {
|
||||
@@ -123,7 +123,7 @@ public class TesFtpServer {
|
||||
file.createNewFile();
|
||||
|
||||
targetLocalDirectory = new File(rootFolder, "localTarget");
|
||||
targetLocalDirectory.mkdirs();
|
||||
targetLocalDirectory.mkdir();
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -183,14 +183,16 @@ public class TesFtpServer {
|
||||
}
|
||||
|
||||
|
||||
public static void recursiveDelete(File file) {
|
||||
public void recursiveDelete(File file) {
|
||||
File[] files = file.listFiles();
|
||||
if (files != null) {
|
||||
for (File each : files) {
|
||||
recursiveDelete(each);
|
||||
}
|
||||
}
|
||||
file.delete();
|
||||
if (!(file.equals(this.targetFtpDirectory) || file.equals(this.targetLocalDirectory))) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ public class FtpInboundChannelAdapterParserTests {
|
||||
assertEquals("", remoteFileSeparator);
|
||||
FtpSimplePatternFileListFilter filter = (FtpSimplePatternFileListFilter) TestUtils.getPropertyValue(fisync, "filter");
|
||||
assertNotNull(filter);
|
||||
Object sessionFactory = TestUtils.getPropertyValue(fisync, "sessionFactory");
|
||||
Object sessionFactory = TestUtils.getPropertyValue(fisync, "remoteFileTemplate.sessionFactory");
|
||||
assertTrue(DefaultFtpSessionFactory.class.isAssignableFrom(sessionFactory.getClass()));
|
||||
FileListFilter<?> acceptAllFilter = ac.getBean("acceptAllFilter", FileListFilter.class);
|
||||
assertTrue(TestUtils.getPropertyValue(inbound, "fileSource.scanner.filter.fileFilters", Collection.class).contains(acceptAllFilter));
|
||||
@@ -107,7 +107,7 @@ public class FtpInboundChannelAdapterParserTests {
|
||||
ApplicationContext ac = new ClassPathXmlApplicationContext(
|
||||
"FtpInboundChannelAdapterParserTests-context.xml", this.getClass());
|
||||
SourcePollingChannelAdapter adapter = ac.getBean("simpleAdapterWithCachedSessions", SourcePollingChannelAdapter.class);
|
||||
Object sessionFactory = TestUtils.getPropertyValue(adapter, "source.synchronizer.sessionFactory");
|
||||
Object sessionFactory = TestUtils.getPropertyValue(adapter, "source.synchronizer.remoteFileTemplate.sessionFactory");
|
||||
assertEquals(CachingSessionFactory.class, sessionFactory.getClass());
|
||||
FtpInboundFileSynchronizer fisync =
|
||||
TestUtils.getPropertyValue(adapter, "source.synchronizer", FtpInboundFileSynchronizer.class);
|
||||
@@ -142,6 +142,7 @@ public class FtpInboundChannelAdapterParserTests {
|
||||
|
||||
public static class TestSessionFactoryBean implements FactoryBean<DefaultFtpSessionFactory> {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public DefaultFtpSessionFactory getObject() throws Exception {
|
||||
DefaultFtpSessionFactory factory = mock(DefaultFtpSessionFactory.class);
|
||||
@@ -150,10 +151,12 @@ public class FtpInboundChannelAdapterParserTests {
|
||||
return factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return DefaultFtpSessionFactory.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -64,15 +64,15 @@ public class FtpOutboundChannelAdapterParserTests {
|
||||
assertEquals(channel, TestUtils.getPropertyValue(consumer, "inputChannel"));
|
||||
assertEquals("ftpOutbound", ((EventDrivenConsumer)consumer).getComponentName());
|
||||
FileTransferringMessageHandler<?> handler = TestUtils.getPropertyValue(consumer, "handler", FileTransferringMessageHandler.class);
|
||||
String remoteFileSeparator = (String) TestUtils.getPropertyValue(handler, "remoteFileSeparator");
|
||||
String remoteFileSeparator = (String) TestUtils.getPropertyValue(handler, "remoteFileTemplate.remoteFileSeparator");
|
||||
assertNotNull(remoteFileSeparator);
|
||||
assertEquals(".foo", TestUtils.getPropertyValue(handler, "temporaryFileSuffix", String.class));
|
||||
assertEquals(".foo", TestUtils.getPropertyValue(handler, "remoteFileTemplate.temporaryFileSuffix", String.class));
|
||||
assertEquals("", remoteFileSeparator);
|
||||
assertEquals(ac.getBean("fileNameGenerator"), TestUtils.getPropertyValue(handler, "fileNameGenerator"));
|
||||
assertEquals("UTF-8", TestUtils.getPropertyValue(handler, "charset"));
|
||||
assertNotNull(TestUtils.getPropertyValue(handler, "directoryExpressionProcessor"));
|
||||
assertNotNull(TestUtils.getPropertyValue(handler, "temporaryDirectoryExpressionProcessor"));
|
||||
Object sfProperty = TestUtils.getPropertyValue(handler, "sessionFactory");
|
||||
assertEquals(ac.getBean("fileNameGenerator"), TestUtils.getPropertyValue(handler, "remoteFileTemplate.fileNameGenerator"));
|
||||
assertEquals("UTF-8", TestUtils.getPropertyValue(handler, "remoteFileTemplate.charset"));
|
||||
assertNotNull(TestUtils.getPropertyValue(handler, "remoteFileTemplate.directoryExpressionProcessor"));
|
||||
assertNotNull(TestUtils.getPropertyValue(handler, "remoteFileTemplate.temporaryDirectoryExpressionProcessor"));
|
||||
Object sfProperty = TestUtils.getPropertyValue(handler, "remoteFileTemplate.sessionFactory");
|
||||
assertEquals(DefaultFtpSessionFactory.class, sfProperty.getClass());
|
||||
DefaultFtpSessionFactory sessionFactory = (DefaultFtpSessionFactory) sfProperty;
|
||||
assertEquals("localhost", TestUtils.getPropertyValue(sessionFactory, "host"));
|
||||
@@ -99,7 +99,7 @@ public class FtpOutboundChannelAdapterParserTests {
|
||||
ApplicationContext ac = new ClassPathXmlApplicationContext(
|
||||
"FtpOutboundChannelAdapterParserTests-context.xml", this.getClass());
|
||||
Object adapter = ac.getBean("simpleAdapter");
|
||||
Object sfProperty = TestUtils.getPropertyValue(adapter, "handler.sessionFactory");
|
||||
Object sfProperty = TestUtils.getPropertyValue(adapter, "handler.remoteFileTemplate.sessionFactory");
|
||||
assertEquals(CachingSessionFactory.class, sfProperty.getClass());
|
||||
Object innerSfProperty = TestUtils.getPropertyValue(sfProperty, "sessionFactory");
|
||||
assertEquals(DefaultFtpSessionFactory.class, innerSfProperty.getClass());
|
||||
@@ -121,7 +121,7 @@ public class FtpOutboundChannelAdapterParserTests {
|
||||
new ClassPathXmlApplicationContext("FtpOutboundChannelAdapterParserTests-context.xml", this.getClass());
|
||||
FileTransferringMessageHandler<?> handler =
|
||||
(FileTransferringMessageHandler<?>)TestUtils.getPropertyValue(ac.getBean("ftpOutbound3"), "handler");
|
||||
assertFalse((Boolean)TestUtils.getPropertyValue(handler,"useTemporaryFileName"));
|
||||
assertFalse((Boolean)TestUtils.getPropertyValue(handler,"remoteFileTemplate.useTemporaryFileName"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -131,16 +131,16 @@ public class FtpOutboundChannelAdapterParserTests {
|
||||
Object consumer = ac.getBean("withBeanExpressions");
|
||||
FileTransferringMessageHandler<?> handler = TestUtils.getPropertyValue(consumer, "handler", FileTransferringMessageHandler.class);
|
||||
ExpressionEvaluatingMessageProcessor<?> dirExpProc = TestUtils.getPropertyValue(handler,
|
||||
"directoryExpressionProcessor", ExpressionEvaluatingMessageProcessor.class);
|
||||
"remoteFileTemplate.directoryExpressionProcessor", ExpressionEvaluatingMessageProcessor.class);
|
||||
assertNotNull(dirExpProc);
|
||||
Message<String> message = MessageBuilder.withPayload("qux").build();
|
||||
assertEquals("foo", dirExpProc.processMessage(message));
|
||||
ExpressionEvaluatingMessageProcessor<?> tempDirExpProc = TestUtils.getPropertyValue(handler,
|
||||
"temporaryDirectoryExpressionProcessor", ExpressionEvaluatingMessageProcessor.class);
|
||||
"remoteFileTemplate.temporaryDirectoryExpressionProcessor", ExpressionEvaluatingMessageProcessor.class);
|
||||
assertNotNull(tempDirExpProc);
|
||||
assertEquals("bar", tempDirExpProc.processMessage(message));
|
||||
DefaultFileNameGenerator generator = TestUtils.getPropertyValue(handler,
|
||||
"fileNameGenerator", DefaultFileNameGenerator.class);
|
||||
"remoteFileTemplate.fileNameGenerator", DefaultFileNameGenerator.class);
|
||||
assertNotNull(generator);
|
||||
assertEquals("baz", generator.generateFileName(message));
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
command-options="-1 -f"
|
||||
expression="payload"
|
||||
order="1"
|
||||
mput-regex=".*"
|
||||
/>
|
||||
|
||||
<bean id="fooString" class="java.lang.String">
|
||||
@@ -49,6 +50,7 @@
|
||||
order="2"
|
||||
requires-reply="false"
|
||||
local-filename-generator-expression="#remoteFileName.toUpperCase() + '.a' + @fooString"
|
||||
mput-pattern="*"
|
||||
>
|
||||
<int-ftp:request-handler-advice-chain>
|
||||
<bean class="org.springframework.integration.ftp.config.FtpOutboundGatewayParserTests$FooAdvice" />
|
||||
@@ -66,6 +68,26 @@
|
||||
order="1"
|
||||
/>
|
||||
|
||||
<int-ftp:outbound-gateway id="gateway4"
|
||||
session-factory="csf"
|
||||
request-channel="inbound1"
|
||||
reply-channel="outbound"
|
||||
command="mput"
|
||||
expression="payload"
|
||||
remote-directory="/foo"
|
||||
remote-file-separator="X"
|
||||
auto-create-directory="true"
|
||||
remote-filename-generator="fileNameGenerator"
|
||||
temporary-remote-directory="/bar"
|
||||
rename-expression="'foo'"
|
||||
order="1"
|
||||
mput-regex=".*"
|
||||
/>
|
||||
|
||||
<bean id="fileNameGenerator" class="org.mockito.Mockito" factory-method="mock">
|
||||
<constructor-arg value="org.springframework.integration.file.FileNameGenerator"/>
|
||||
</bean>
|
||||
|
||||
<int-ftp:outbound-gateway id="withBeanExpression"
|
||||
local-directory="local-test-dir"
|
||||
session-factory="sf"
|
||||
|
||||
@@ -18,28 +18,34 @@ package org.springframework.integration.ftp.config;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.integration.endpoint.AbstractEndpoint;
|
||||
import org.springframework.integration.file.FileNameGenerator;
|
||||
import org.springframework.integration.file.filters.RegexPatternFileListFilter;
|
||||
import org.springframework.integration.file.filters.SimplePatternFileListFilter;
|
||||
import org.springframework.integration.file.remote.gateway.AbstractRemoteFileOutboundGateway.Command;
|
||||
import org.springframework.integration.file.remote.gateway.AbstractRemoteFileOutboundGateway.Option;
|
||||
import org.springframework.integration.file.remote.session.CachingSessionFactory;
|
||||
import org.springframework.integration.ftp.gateway.FtpOutboundGateway;
|
||||
import org.springframework.integration.handler.ExpressionEvaluatingMessageProcessor;
|
||||
import org.springframework.integration.handler.advice.AbstractRequestHandlerAdvice;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
@@ -65,17 +71,23 @@ public class FtpOutboundGatewayParserTests {
|
||||
@Autowired
|
||||
AbstractEndpoint gateway3;
|
||||
|
||||
@Autowired
|
||||
AbstractEndpoint gateway4;
|
||||
|
||||
@Autowired
|
||||
AbstractEndpoint withBeanExpression;
|
||||
|
||||
@Autowired
|
||||
FileNameGenerator generator;
|
||||
|
||||
private static volatile int adviceCalled;
|
||||
|
||||
@Test
|
||||
public void testGateway1() {
|
||||
FtpOutboundGateway gateway = TestUtils.getPropertyValue(gateway1,
|
||||
"handler", FtpOutboundGateway.class);
|
||||
assertEquals("X", TestUtils.getPropertyValue(gateway, "remoteFileSeparator"));
|
||||
assertNotNull(TestUtils.getPropertyValue(gateway, "sessionFactory"));
|
||||
assertEquals("X", TestUtils.getPropertyValue(gateway, "remoteFileTemplate.remoteFileSeparator"));
|
||||
assertNotNull(TestUtils.getPropertyValue(gateway, "remoteFileTemplate.sessionFactory"));
|
||||
assertNotNull(TestUtils.getPropertyValue(gateway, "outputChannel"));
|
||||
assertEquals("local-test-dir", TestUtils.getPropertyValue(gateway, "localDirectoryExpression.literalValue"));
|
||||
assertFalse((Boolean) TestUtils.getPropertyValue(gateway, "autoCreateLocalDirectory"));
|
||||
@@ -90,15 +102,16 @@ public class FtpOutboundGatewayParserTests {
|
||||
Long sendTimeout = TestUtils.getPropertyValue(gateway, "messagingTemplate.sendTimeout", Long.class);
|
||||
assertEquals(Long.valueOf(777), sendTimeout);
|
||||
assertTrue(TestUtils.getPropertyValue(gateway, "requiresReply", Boolean.class));
|
||||
assertThat(TestUtils.getPropertyValue(gateway, "mputFilter"), Matchers.instanceOf(RegexPatternFileListFilter.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGateway2() throws Exception {
|
||||
FtpOutboundGateway gateway = TestUtils.getPropertyValue(gateway2,
|
||||
"handler", FtpOutboundGateway.class);
|
||||
assertEquals("X", TestUtils.getPropertyValue(gateway, "remoteFileSeparator"));
|
||||
assertNotNull(TestUtils.getPropertyValue(gateway, "sessionFactory"));
|
||||
assertTrue(TestUtils.getPropertyValue(gateway, "sessionFactory") instanceof CachingSessionFactory);
|
||||
assertEquals("X", TestUtils.getPropertyValue(gateway, "remoteFileTemplate.remoteFileSeparator"));
|
||||
assertNotNull(TestUtils.getPropertyValue(gateway, "remoteFileTemplate.sessionFactory"));
|
||||
assertTrue(TestUtils.getPropertyValue(gateway, "remoteFileTemplate.sessionFactory") instanceof CachingSessionFactory);
|
||||
assertNotNull(TestUtils.getPropertyValue(gateway, "outputChannel"));
|
||||
assertEquals("local-test-dir", TestUtils.getPropertyValue(gateway, "localDirectoryExpression.literalValue"));
|
||||
assertFalse((Boolean) TestUtils.getPropertyValue(gateway, "autoCreateLocalDirectory"));
|
||||
@@ -124,18 +137,37 @@ public class FtpOutboundGatewayParserTests {
|
||||
}
|
||||
});
|
||||
assertEquals("FOO.afoo", genMethod.get().invoke(gateway, new GenericMessage<String>(""), "foo"));
|
||||
assertThat(TestUtils.getPropertyValue(gateway, "mputFilter"), Matchers.instanceOf(SimplePatternFileListFilter.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGatewayMv() {
|
||||
FtpOutboundGateway gateway = TestUtils.getPropertyValue(gateway3,
|
||||
"handler", FtpOutboundGateway.class);
|
||||
assertNotNull(TestUtils.getPropertyValue(gateway, "sessionFactory"));
|
||||
assertNotNull(TestUtils.getPropertyValue(gateway, "remoteFileTemplate.sessionFactory"));
|
||||
assertNotNull(TestUtils.getPropertyValue(gateway, "outputChannel"));
|
||||
assertEquals(Command.MV, TestUtils.getPropertyValue(gateway, "command"));
|
||||
assertEquals("'foo'", TestUtils.getPropertyValue(gateway, "renameProcessor.expression.expression"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGatewayMPut() {
|
||||
FtpOutboundGateway gateway = TestUtils.getPropertyValue(gateway4,
|
||||
"handler", FtpOutboundGateway.class);
|
||||
assertNotNull(TestUtils.getPropertyValue(gateway, "remoteFileTemplate.sessionFactory"));
|
||||
assertNotNull(TestUtils.getPropertyValue(gateway, "outputChannel"));
|
||||
assertEquals(Command.MPUT, TestUtils.getPropertyValue(gateway, "command"));
|
||||
assertEquals("'foo'", TestUtils.getPropertyValue(gateway, "renameProcessor.expression.expression"));
|
||||
assertThat(TestUtils.getPropertyValue(gateway, "mputFilter"), Matchers.instanceOf(RegexPatternFileListFilter.class));
|
||||
assertSame(generator, TestUtils.getPropertyValue(gateway, "remoteFileTemplate.fileNameGenerator"));
|
||||
assertEquals("/foo",
|
||||
TestUtils.getPropertyValue(gateway, "remoteFileTemplate.directoryExpressionProcessor.expression", Expression.class)
|
||||
.getExpressionString());
|
||||
assertEquals("/bar",
|
||||
TestUtils.getPropertyValue(gateway, "remoteFileTemplate.temporaryDirectoryExpressionProcessor.expression", Expression.class)
|
||||
.getExpressionString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithBeanExpression() {
|
||||
FtpOutboundGateway gateway = TestUtils.getPropertyValue(withBeanExpression,
|
||||
|
||||
@@ -44,9 +44,9 @@ public class FtpsOutboundChannelAdapterParserTests {
|
||||
assertEquals(ac.getBean("ftpChannel"), TestUtils.getPropertyValue(consumer, "inputChannel"));
|
||||
assertEquals("ftpOutbound", ((EventDrivenConsumer)consumer).getComponentName());
|
||||
FileTransferringMessageHandler<?> handler = TestUtils.getPropertyValue(consumer, "handler", FileTransferringMessageHandler.class);
|
||||
assertEquals(ac.getBean("fileNameGenerator"), TestUtils.getPropertyValue(handler, "fileNameGenerator"));
|
||||
assertEquals("UTF-8", TestUtils.getPropertyValue(handler, "charset"));
|
||||
DefaultFtpsSessionFactory sf = TestUtils.getPropertyValue(handler, "sessionFactory", DefaultFtpsSessionFactory.class);
|
||||
assertEquals(ac.getBean("fileNameGenerator"), TestUtils.getPropertyValue(handler, "remoteFileTemplate.fileNameGenerator"));
|
||||
assertEquals("UTF-8", TestUtils.getPropertyValue(handler, "remoteFileTemplate.charset"));
|
||||
DefaultFtpsSessionFactory sf = TestUtils.getPropertyValue(handler, "remoteFileTemplate.sessionFactory", DefaultFtpsSessionFactory.class);
|
||||
assertEquals("localhost", TestUtils.getPropertyValue(sf, "host"));
|
||||
assertEquals(22, TestUtils.getPropertyValue(sf, "port"));
|
||||
}
|
||||
|
||||
@@ -33,11 +33,14 @@ import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
|
||||
import org.apache.commons.net.ftp.FTPClient;
|
||||
import org.apache.commons.net.ftp.FTPFile;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
@@ -46,8 +49,13 @@ import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.expression.spel.SpelParserConfiguration;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.integration.expression.ExpressionUtils;
|
||||
import org.springframework.integration.file.filters.CompositeFileListFilter;
|
||||
import org.springframework.integration.file.filters.FileListFilter;
|
||||
import org.springframework.integration.ftp.filters.FtpPersistentAcceptOnceFileListFilter;
|
||||
import org.springframework.integration.ftp.filters.FtpRegexPatternFileListFilter;
|
||||
import org.springframework.integration.ftp.session.AbstractFtpSessionFactory;
|
||||
import org.springframework.integration.metadata.PropertiesPersistingMetadataStore;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.messaging.Message;
|
||||
|
||||
/**
|
||||
@@ -61,6 +69,7 @@ public class FtpInboundRemoteFileSystemSynchronizerTests {
|
||||
|
||||
private static FTPClient ftpClient = mock(FTPClient.class);
|
||||
|
||||
@Before
|
||||
@After
|
||||
public void cleanup(){
|
||||
File file = new File("test");
|
||||
@@ -86,7 +95,16 @@ public class FtpInboundRemoteFileSystemSynchronizerTests {
|
||||
synchronizer.setDeleteRemoteFiles(true);
|
||||
synchronizer.setPreserveTimestamp(true);
|
||||
synchronizer.setRemoteDirectory("remote-test-dir");
|
||||
synchronizer.setFilter(new FtpRegexPatternFileListFilter(".*\\.test$"));
|
||||
FtpRegexPatternFileListFilter patternFilter = new FtpRegexPatternFileListFilter(".*\\.test$");
|
||||
PropertiesPersistingMetadataStore store = new PropertiesPersistingMetadataStore();
|
||||
store.setBaseDirectory("test");
|
||||
FtpPersistentAcceptOnceFileListFilter persistFilter =
|
||||
new FtpPersistentAcceptOnceFileListFilter(store, "foo");
|
||||
List<FileListFilter<FTPFile>> filters = new ArrayList<FileListFilter<FTPFile>>();
|
||||
filters.add(persistFilter);
|
||||
filters.add(patternFilter);
|
||||
CompositeFileListFilter<FTPFile> filter = new CompositeFileListFilter<FTPFile>(filters);
|
||||
synchronizer.setFilter(filter);
|
||||
synchronizer.setIntegrationEvaluationContext(ExpressionUtils.createStandardEvaluationContext());
|
||||
|
||||
ExpressionParser expressionParser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
@@ -120,28 +138,49 @@ public class FtpInboundRemoteFileSystemSynchronizerTests {
|
||||
|
||||
assertTrue(new File("test/A.TEST.a").exists());
|
||||
assertTrue(new File("test/B.TEST.a").exists());
|
||||
|
||||
TestUtils.getPropertyValue(ms, "localFileListFilter.seen", Queue.class).clear();
|
||||
|
||||
new File("test/A.TEST.a").delete();
|
||||
new File("test/B.TEST.a").delete();
|
||||
// the remote filter should prevent a re-fetch
|
||||
nothing = ms.receive();
|
||||
assertNull(nothing);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static class TestFtpSessionFactory extends AbstractFtpSessionFactory<FTPClient> {
|
||||
|
||||
private final Collection<Object> ftpFiles = new ArrayList<Object>();
|
||||
|
||||
private void init() {
|
||||
String[] files = new File("remote-test-dir").list();
|
||||
for (String fileName : files) {
|
||||
FTPFile file = new FTPFile();
|
||||
file.setName(fileName);
|
||||
file.setType(FTPFile.FILE_TYPE);
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.add(Calendar.DATE, 1);
|
||||
file.setTimestamp(calendar);
|
||||
ftpFiles.add(file);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FTPClient createClientInstance() {
|
||||
if (this.ftpFiles.size() == 0) {
|
||||
this.init();
|
||||
}
|
||||
|
||||
try {
|
||||
when(ftpClient.getReplyCode()).thenReturn(250);
|
||||
when(ftpClient.login("kermit", "frog")).thenReturn(true);
|
||||
when(ftpClient.changeWorkingDirectory(Mockito.anyString())).thenReturn(true);
|
||||
|
||||
String[] files = new File("remote-test-dir").list();
|
||||
Collection<Object> ftpFiles = new ArrayList<Object>();
|
||||
for (String fileName : files) {
|
||||
FTPFile file = new FTPFile();
|
||||
file.setName(fileName);
|
||||
file.setType(FTPFile.FILE_TYPE);
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.add(Calendar.DATE, 1);
|
||||
file.setTimestamp(calendar);
|
||||
ftpFiles.add(file);
|
||||
when(ftpClient.retrieveFile(Mockito.eq("remote-test-dir/" + fileName) , Mockito.any(OutputStream.class))).thenReturn(true);
|
||||
}
|
||||
when(ftpClient.listFiles("remote-test-dir")).thenReturn(ftpFiles.toArray(new FTPFile[]{}));
|
||||
|
||||
@@ -56,6 +56,7 @@ import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.PollableChannel;
|
||||
import org.springframework.integration.file.FileNameGenerator;
|
||||
import org.springframework.integration.file.remote.FileInfo;
|
||||
import org.springframework.integration.file.remote.RemoteFileTemplate;
|
||||
import org.springframework.integration.file.remote.handler.FileTransferringMessageHandler;
|
||||
import org.springframework.integration.ftp.session.AbstractFtpSessionFactory;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
@@ -94,6 +95,7 @@ public class FtpOutboundTests {
|
||||
FileTransferringMessageHandler<FTPFile> handler = new FileTransferringMessageHandler<FTPFile>(sessionFactory);
|
||||
handler.setRemoteDirectoryExpression(new LiteralExpression("remote-target-dir"));
|
||||
handler.setFileNameGenerator(new FileNameGenerator() {
|
||||
@Override
|
||||
public String generateFileName(Message<?> message) {
|
||||
return "handlerContent.test";
|
||||
}
|
||||
@@ -117,6 +119,7 @@ public class FtpOutboundTests {
|
||||
FileTransferringMessageHandler<FTPFile> handler = new FileTransferringMessageHandler<FTPFile>(sessionFactory);
|
||||
handler.setRemoteDirectoryExpression(new LiteralExpression("remote-target-dir"));
|
||||
handler.setFileNameGenerator(new FileNameGenerator() {
|
||||
@Override
|
||||
public String generateFileName(Message<?> message) {
|
||||
return "handlerContent.test";
|
||||
}
|
||||
@@ -138,6 +141,7 @@ public class FtpOutboundTests {
|
||||
FileTransferringMessageHandler<FTPFile> handler = new FileTransferringMessageHandler<FTPFile>(sessionFactory);
|
||||
handler.setRemoteDirectoryExpression(new LiteralExpression(targetDir.getName()));
|
||||
handler.setFileNameGenerator(new FileNameGenerator() {
|
||||
@Override
|
||||
public String generateFileName(Message<?> message) {
|
||||
return ((File)message.getPayload()).getName() + ".test";
|
||||
}
|
||||
@@ -163,6 +167,7 @@ public class FtpOutboundTests {
|
||||
FileTransferringMessageHandler<FTPFile> handler = new FileTransferringMessageHandler<FTPFile>(sessionFactory);
|
||||
handler.setRemoteDirectoryExpression(new LiteralExpression(targetDir.getName()));
|
||||
handler.setFileNameGenerator(new FileNameGenerator() {
|
||||
@Override
|
||||
public String generateFileName(Message<?> message) {
|
||||
return ((File)message.getPayload()).getName() + ".test";
|
||||
}
|
||||
@@ -172,7 +177,7 @@ public class FtpOutboundTests {
|
||||
|
||||
File srcFile = new File(UUID.randomUUID() + ".txt");
|
||||
|
||||
Log logger = spy(TestUtils.getPropertyValue(handler, "logger", Log.class));
|
||||
Log logger = spy(TestUtils.getPropertyValue(handler, "remoteFileTemplate.logger", Log.class));
|
||||
when(logger.isWarnEnabled()).thenReturn(true);
|
||||
final AtomicReference<String> logged = new AtomicReference<String>();
|
||||
doAnswer(new Answer<Object>(){
|
||||
@@ -184,7 +189,8 @@ public class FtpOutboundTests {
|
||||
return null;
|
||||
}
|
||||
}).when(logger).warn(Mockito.anyString());
|
||||
new DirectFieldAccessor(handler).setPropertyValue("logger", logger);
|
||||
RemoteFileTemplate<?> template = TestUtils.getPropertyValue(handler, "remoteFileTemplate", RemoteFileTemplate.class);
|
||||
new DirectFieldAccessor(template).setPropertyValue("logger", logger);
|
||||
handler.handleMessage(new GenericMessage<File>(srcFile));
|
||||
assertNotNull(logged.get());
|
||||
assertEquals("File " + srcFile.toString() + " does not exist", logged.get());
|
||||
@@ -242,6 +248,7 @@ public class FtpOutboundTests {
|
||||
when(ftpClient.changeWorkingDirectory(Mockito.anyString())).thenReturn(true);
|
||||
when(ftpClient.printWorkingDirectory()).thenReturn("remote-target-dir");
|
||||
when(ftpClient.storeFile(Mockito.anyString(), Mockito.any(InputStream.class))).thenAnswer(new Answer<Boolean>() {
|
||||
@Override
|
||||
public Boolean answer(InvocationOnMock invocation) throws Throwable {
|
||||
String fileName = (String) invocation.getArguments()[0];
|
||||
InputStream fis = (InputStream) invocation.getArguments()[1];
|
||||
@@ -250,6 +257,7 @@ public class FtpOutboundTests {
|
||||
}
|
||||
});
|
||||
when(ftpClient.rename(Mockito.anyString(), Mockito.anyString())).thenAnswer(new Answer<Boolean>() {
|
||||
@Override
|
||||
public Boolean answer(InvocationOnMock invocation)
|
||||
throws Throwable {
|
||||
File file = new File((String) invocation.getArguments()[0]);
|
||||
|
||||
@@ -68,4 +68,40 @@
|
||||
local-filename-generator-expression="#remoteFileName.replaceFirst('ftpSource', 'localTarget')"
|
||||
reply-channel="output"/>
|
||||
|
||||
<int:channel id="inboundMPut"/>
|
||||
|
||||
<int-ftp:outbound-gateway session-factory="ftpSessionFactory"
|
||||
request-channel="inboundMPut"
|
||||
command="mput"
|
||||
auto-create-directory="true"
|
||||
filename-pattern="*.txt"
|
||||
expression="payload"
|
||||
remote-directory="ftpTarget"
|
||||
reply-channel="output"/>
|
||||
|
||||
<int:channel id="inboundMPutRecursive"/>
|
||||
|
||||
<int-ftp:outbound-gateway session-factory="ftpSessionFactory"
|
||||
request-channel="inboundMPutRecursive"
|
||||
command="mput"
|
||||
command-options="-R"
|
||||
auto-create-directory="true"
|
||||
filename-pattern="*.txt"
|
||||
expression="payload"
|
||||
remote-directory="ftpTarget"
|
||||
reply-channel="output"/>
|
||||
|
||||
<int:channel id="inboundMPutRecursiveFiltered"/>
|
||||
|
||||
<int-ftp:outbound-gateway session-factory="ftpSessionFactory"
|
||||
request-channel="inboundMPutRecursiveFiltered"
|
||||
command="mput"
|
||||
command-options="-R"
|
||||
mput-regex="(.*1.txt|sub.*)"
|
||||
auto-create-directory="true"
|
||||
filename-pattern="*.txt"
|
||||
expression="payload"
|
||||
remote-directory="ftpTarget"
|
||||
reply-channel="output"/>
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -16,24 +16,36 @@
|
||||
|
||||
package org.springframework.integration.ftp.outbound;
|
||||
|
||||
import static org.hamcrest.Matchers.anyOf;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.net.ftp.FTPFile;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.file.remote.InputStreamCallback;
|
||||
import org.springframework.integration.file.remote.RemoteFileTemplate;
|
||||
import org.springframework.integration.file.remote.session.Session;
|
||||
import org.springframework.integration.file.remote.session.SessionFactory;
|
||||
import org.springframework.integration.ftp.TesFtpServer;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.PollableChannel;
|
||||
@@ -44,6 +56,8 @@ import org.springframework.util.FileCopyUtils;
|
||||
|
||||
/**
|
||||
* @author Artem Bilan
|
||||
* @author Gary Russell
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@@ -51,7 +65,10 @@ import org.springframework.util.FileCopyUtils;
|
||||
public class FtpServerOutboundTests {
|
||||
|
||||
@Autowired
|
||||
public TesFtpServer ftpServer;
|
||||
private TesFtpServer ftpServer;
|
||||
|
||||
@Autowired
|
||||
private SessionFactory<FTPFile> ftpSessionFactory;
|
||||
|
||||
@Autowired
|
||||
private PollableChannel output;
|
||||
@@ -71,10 +88,19 @@ public class FtpServerOutboundTests {
|
||||
@Autowired
|
||||
private DirectChannel inboundMGetRecursiveFiltered;
|
||||
|
||||
@Autowired
|
||||
private DirectChannel inboundMPut;
|
||||
|
||||
@Autowired
|
||||
private DirectChannel inboundMPutRecursive;
|
||||
|
||||
@Autowired
|
||||
private DirectChannel inboundMPutRecursiveFiltered;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
TesFtpServer.recursiveDelete(ftpServer.getTargetLocalDirectory());
|
||||
TesFtpServer.recursiveDelete(ftpServer.getTargetFtpDirectory());
|
||||
this.ftpServer.recursiveDelete(ftpServer.getTargetLocalDirectory());
|
||||
this.ftpServer.recursiveDelete(ftpServer.getTargetFtpDirectory());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -176,7 +202,7 @@ public class FtpServerOutboundTests {
|
||||
|
||||
@Test
|
||||
public void testInt3100RawGET() throws Exception {
|
||||
Session<?> session = this.ftpServer.ftpSessionFactory().getSession();
|
||||
Session<?> session = this.ftpSessionFactory.getSession();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
FileCopyUtils.copy(session.readRaw("ftpSource/ftpSource1.txt"), baos);
|
||||
assertTrue(session.finalizeRaw());
|
||||
@@ -190,5 +216,90 @@ public class FtpServerOutboundTests {
|
||||
session.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRawGETWithTemplate() throws Exception {
|
||||
RemoteFileTemplate<FTPFile> template = new RemoteFileTemplate<FTPFile>(this.ftpSessionFactory);
|
||||
template.setFileNameExpression(new SpelExpressionParser().parseExpression("payload"));
|
||||
template.setBeanFactory(mock(BeanFactory.class));
|
||||
template.afterPropertiesSet();
|
||||
final ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
|
||||
assertTrue(template.get(new GenericMessage<String>("ftpSource/ftpSource1.txt"), new InputStreamCallback() {
|
||||
|
||||
@Override
|
||||
public void doWithInputStream(InputStream stream) throws IOException {
|
||||
FileCopyUtils.copy(stream, baos1);
|
||||
}
|
||||
}));
|
||||
assertEquals("source1", new String(baos1.toByteArray()));
|
||||
|
||||
final ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
|
||||
assertTrue(template.get(new GenericMessage<String>("ftpSource/ftpSource2.txt"), new InputStreamCallback() {
|
||||
|
||||
@Override
|
||||
public void doWithInputStream(InputStream stream) throws IOException {
|
||||
FileCopyUtils.copy(stream, baos2);
|
||||
}
|
||||
}));
|
||||
assertEquals("source2", new String(baos2.toByteArray()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInt3088MPutNotRecursive() {
|
||||
this.inboundMPut.send(new GenericMessage<File>(this.ftpServer.getSourceLocalDirectory()));
|
||||
@SuppressWarnings("unchecked")
|
||||
Message<List<String>> out = (Message<List<String>>) this.output.receive(1000);
|
||||
assertNotNull(out);
|
||||
assertEquals(2, out.getPayload().size());
|
||||
assertThat(out.getPayload().get(0),
|
||||
not(equalTo(out.getPayload().get(1))));
|
||||
assertThat(
|
||||
out.getPayload().get(0),
|
||||
anyOf(equalTo("ftpTarget/localSource1.txt"), equalTo("ftpTarget/localSource2.txt")));
|
||||
assertThat(
|
||||
out.getPayload().get(1),
|
||||
anyOf(equalTo("ftpTarget/localSource1.txt"), equalTo("ftpTarget/localSource2.txt")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInt3088MPutRecursive() {
|
||||
this.inboundMPutRecursive.send(new GenericMessage<File>(this.ftpServer.getSourceLocalDirectory()));
|
||||
@SuppressWarnings("unchecked")
|
||||
Message<List<String>> out = (Message<List<String>>) this.output.receive(1000);
|
||||
assertNotNull(out);
|
||||
assertEquals(3, out.getPayload().size());
|
||||
assertThat(out.getPayload().get(0),
|
||||
not(equalTo(out.getPayload().get(1))));
|
||||
assertThat(
|
||||
out.getPayload().get(0),
|
||||
anyOf(equalTo("ftpTarget/localSource1.txt"), equalTo("ftpTarget/localSource2.txt"),
|
||||
equalTo("ftpTarget/subLocalSource/subLocalSource1.txt")));
|
||||
assertThat(
|
||||
out.getPayload().get(1),
|
||||
anyOf(equalTo("ftpTarget/localSource1.txt"), equalTo("ftpTarget/localSource2.txt"),
|
||||
equalTo("ftpTarget/subLocalSource/subLocalSource1.txt")));
|
||||
assertThat(
|
||||
out.getPayload().get(2),
|
||||
anyOf(equalTo("ftpTarget/localSource1.txt"), equalTo("ftpTarget/localSource2.txt"),
|
||||
equalTo("ftpTarget/subLocalSource/subLocalSource1.txt")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInt3088MPutRecursiveFiltered() {
|
||||
this.inboundMPutRecursiveFiltered.send(new GenericMessage<File>(this.ftpServer.getSourceLocalDirectory()));
|
||||
@SuppressWarnings("unchecked")
|
||||
Message<List<String>> out = (Message<List<String>>) this.output.receive(1000);
|
||||
assertNotNull(out);
|
||||
assertEquals(2, out.getPayload().size());
|
||||
assertThat(out.getPayload().get(0),
|
||||
not(equalTo(out.getPayload().get(1))));
|
||||
assertThat(
|
||||
out.getPayload().get(0),
|
||||
anyOf(equalTo("ftpTarget/localSource1.txt"), equalTo("ftpTarget/localSource2.txt"),
|
||||
equalTo("ftpTarget/subLocalSource/subLocalSource1.txt")));
|
||||
assertThat(
|
||||
out.getPayload().get(1),
|
||||
anyOf(equalTo("ftpTarget/localSource1.txt"), equalTo("ftpTarget/localSource2.txt"),
|
||||
equalTo("ftpTarget/subLocalSource/subLocalSource1.txt")));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user