INT-1614 more polishing, added tests, 78% code coverege

This commit is contained in:
Oleg Zhurakousky
2010-11-16 11:46:57 -05:00
parent c9a58cfc4a
commit 9390f595dd
13 changed files with 67 additions and 318 deletions

View File

@@ -35,8 +35,6 @@ public abstract class AbstractFtpOutboundChannelAdapterParser extends AbstractOu
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder,element,"charset");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder,element,"filename-generator", "fileNameGenerator");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder,element,"client-factory");
FtpNamespaceParserSupport.configureCoreFtpClient(builder, element, parserContext);
return builder.getBeanDefinition();
}

View File

@@ -53,20 +53,6 @@ class FtpInboundSynchronizingMessageSourceFactoryBean
private volatile AbstractFtpClientFactory<?> clientFactory;
//volatile String host;
//volatile String port;
//volatile String username;
//volatile String password;
//volatile String remoteDirectory;
//volatile int clientMode = FTPClient.ACTIVE_LOCAL_DATA_CONNECTION_MODE;
//volatile int fileType = FTP.BINARY_FILE_TYPE;
volatile String defaultFtpInboundFolderName = "ftpInbound";
private volatile String localWorkingDirectory;
@@ -79,27 +65,6 @@ class FtpInboundSynchronizingMessageSourceFactoryBean
private volatile String autoDeleteRemoteFilesOnSync;
// public void setHost(String host) {
// this.host = host;
// }
//
// public void setPort(String port) {
// this.port = port;
// }
//
// public void setUsername(String username) {
// this.username = username;
// }
//
// public void setPassword(String password) {
// this.password = password;
// }
//
// public void setFileType(int fileType) {
// this.fileType = fileType;
// }
public void setClientFactory(AbstractFtpClientFactory<?> clientFactory) {
this.clientFactory = clientFactory;
}
@@ -112,18 +77,10 @@ class FtpInboundSynchronizingMessageSourceFactoryBean
this.autoDeleteRemoteFilesOnSync = autoDeleteRemoteFilesOnSync;
}
// public void setRemoteDirectory(String remoteDirectory) {
// this.remoteDirectory = remoteDirectory;
// }
public void setLocalWorkingDirectory(String localWorkingDirectory) {
this.localWorkingDirectory = localWorkingDirectory;
}
// public void setClientMode(int clientMode) {
// this.clientMode = clientMode;
// }
public void setFilter(FileListFilter<FTPFile> filter) {
this.filter = filter;
}
@@ -147,19 +104,6 @@ class FtpInboundSynchronizingMessageSourceFactoryBean
return (Resource) resourceEditor.getValue();
}
// protected AbstractFtpClientFactory<?> initializeFactory(AbstractFtpClientFactory<?> factory) throws Exception {
// factory.setHost(this.host);
// if (StringUtils.hasText(this.port)) {
// factory.setPort(Integer.parseInt(this.port));
// }
// factory.setUsername(this.username);
// factory.setPassword(this.password);
// factory.setRemoteWorkingDirectory(this.remoteDirectory);
// factory.setClientMode(this.clientMode);
// factory.setFileType(this.fileType);
// return factory;
// }
@Override
protected FtpInboundRemoteFileSystemSynchronizingMessageSource createInstance() throws Exception {
boolean autoCreatDirs = Boolean.parseBoolean(this.autoCreateDirectories);

View File

@@ -16,40 +16,19 @@
package org.springframework.integration.ftp.config;
import org.apache.commons.net.ftp.FTP;
import org.springframework.integration.config.xml.AbstractIntegrationNamespaceHandler;
import java.util.HashMap;
import java.util.Map;
/**
* Provides namespace support for using FTP
* <p/>
* This is *heavily* influenced by the good work done by Iwein before.
*
* @author Josh Long
* @author Oleg Zhurakousky
* @since 2.0
*/
public class FtpNamespaceHandler extends AbstractIntegrationNamespaceHandler {
static public Map<String, Integer> FILE_TYPES = new HashMap<String, Integer>();
static public Map<String, Integer> CLIENT_MODES = new HashMap<String, Integer>();
static {
// file types
FILE_TYPES.put("ebcdic-file-type", FTP.EBCDIC_FILE_TYPE);
FILE_TYPES.put("ascii-file-type", FTP.ASCII_FILE_TYPE);
FILE_TYPES.put("binary-file-type", FTP.BINARY_FILE_TYPE);
// client modes
CLIENT_MODES.put("active-local-data-connection-mode", 0);
CLIENT_MODES.put("active-remote-data-connection-mode", 1);
CLIENT_MODES.put("passive-local-data-connection-mode", 2);
CLIENT_MODES.put("passive-remote-data-connection-mode", 3);
}
public void init() {
registerBeanDefinitionParser("inbound-channel-adapter", new FtpInboundChannelAdapterParser());
registerBeanDefinitionParser("outbound-channel-adapter", new FtpOutboundChannelAdapterParser());

View File

@@ -1,52 +0,0 @@
/*
* Copyright 2002-2010 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.config;
import org.w3c.dom.Element;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
/**
* General support for parsers in the FTP namespace.
*
* @author Josh Long
*/
public class FtpNamespaceParserSupport {
/**
* Handles values that are supported across all adapters.
* @param builder a builder
* @param element an element
* @param parserContext a parser context
*/
public static void configureCoreFtpClient(BeanDefinitionBuilder builder, Element element, ParserContext parserContext) {
for (String p : "auto-create-directories,username,port,password,host,remote-directory".split(",")) {
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, p);
}
if (element.hasAttribute("file-type")) {
int fileType = FtpNamespaceHandler.FILE_TYPES.get(element.getAttribute("file-type"));
builder.addPropertyValue("fileType", fileType);
}
if (element.hasAttribute("client-mode")) {
int clientMode = FtpNamespaceHandler.CLIENT_MODES.get(element.getAttribute("client-mode"));
builder.addPropertyValue("clientMode", clientMode);
}
}
}

View File

@@ -17,7 +17,6 @@
package org.springframework.integration.ftp.config;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.integration.file.FileNameGenerator;
import org.springframework.integration.ftp.client.AbstractFtpClientFactory;
import org.springframework.integration.ftp.client.DefaultFtpClientFactory;
@@ -35,23 +34,9 @@ import org.springframework.integration.ftp.outbound.FtpSendingMessageHandler;
*/
class FtpSendingMessageHandlerFactoryBean extends AbstractFactoryBean<FtpSendingMessageHandler> {
// protected volatile int port;
//
// protected volatile String username;
//
// protected volatile String password;
//
// protected volatile String host;
//
// protected volatile String remoteDirectory;
private volatile String charset;
// protected volatile int clientMode;
//
// private volatile int fileType;
private FileNameGenerator fileNameGenerator;
private volatile FileNameGenerator fileNameGenerator;
private volatile AbstractFtpClientFactory<?> clientFactory;
@@ -67,57 +52,17 @@ class FtpSendingMessageHandlerFactoryBean extends AbstractFactoryBean<FtpSending
this.fileNameGenerator = fileNameGenerator;
}
// public void setFileType(int fileType) {
// this.fileType = fileType;
// }
//
// public void setClientMode(int clientMode) {
// this.clientMode = clientMode;
// }
//
// public void setPort(int port) {
// this.port = port;
// }
//
// public void setUsername(String username) {
// this.username = username;
// }
//
// public void setPassword(String password) {
// this.password = password;
// }
// public void setHost(String host) {
// this.host = host;
// }
//
// public void setRemoteDirectory(String remoteDirectory) {
// this.remoteDirectory = remoteDirectory;
// }
@Override
public Class<? extends FtpSendingMessageHandler> getObjectType() {
return FtpSendingMessageHandler.class;
}
// protected AbstractFtpClientFactory<?> initializeClientFactory(AbstractFtpClientFactory<?> factory) {
// factory.setHost(this.host);
// factory.setPort(this.port);
// factory.setUsername(this.username);
// factory.setPassword(this.password);
// factory.setRemoteWorkingDirectory(this.remoteDirectory);
// factory.setClientMode(this.clientMode);
// factory.setFileType(this.fileType);
// return factory;
// }
protected AbstractFtpClientFactory<?> createClientFactory(){
return new DefaultFtpClientFactory();
}
@Override
protected FtpSendingMessageHandler createInstance() throws Exception {
//AbstractFtpClientFactory<?> defaultFtpClientFactory = this.initializeClientFactory(this.createClientFactory());
QueuedFtpClientPool queuedFtpClientPool = new QueuedFtpClientPool(15, this.clientFactory);
FtpSendingMessageHandler ftpSendingMessageHandler = new FtpSendingMessageHandler(
queuedFtpClientPool);

View File

@@ -8,13 +8,21 @@
http://www.springframework.org/schema/integration/ftp http://www.springframework.org/schema/integration/ftp/spring-integration-ftp-2.0.xsd">
<int:channel id="ftpOutbound"/>
<bean id="ftpClientFactory" class="org.springframework.integration.ftp.client.DefaultFtpsClientFactory">
<property name="host" value="localhost"/>
<property name="port" value="22"/>
<property name="username" value="oleg"/>
<property name="password" value="password"/>
<property name="clientMode" value="1"/>
<property name="fileType" value="2"/>
<property name="remoteWorkingDirectory" value="temp"/>
</bean>
<int-ftp:outbound-channel-adapter id="ftpOutboundAdapter"
username="xxxx"
password="xxxx"
client-factory="ftpClientFactory"
channel="ftpOutbound"
remote-directory="temp"
host="localhost"
filename-generator="fileNameGenerator"/>
<bean id="fileNameGenerator" class="org.mockito.Mockito" factory-method="mock">

View File

@@ -39,7 +39,6 @@ import org.springframework.integration.test.util.TestUtils;
public class FtpParserOutboundTests {
@Test
@Ignore
public void testFtpOutboundWithFileGenerator() throws Exception{
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("FtpParserOutboundTests-context.xml", this.getClass());

View File

@@ -1,34 +0,0 @@
package org.springframework.integration.ftp;
import org.apache.commons.lang.StringUtils;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.Message;
import org.springframework.integration.annotation.ServiceActivator;
import java.io.File;
/**
* Simple component to test the inbound integration
*
* @author Josh Long
*/
public class InboundFtpFileServiceActivator {
@ServiceActivator
public void onNewRemoteFTPFile(Message<File> file)
throws Throwable {
System.out.println(StringUtils.repeat("=", 100));
System.out.println("A new file has appeared: " + file.getPayload().getAbsolutePath());
for (String h : file.getHeaders().keySet())
System.out.println(String.format("%s = %s", h, file.getHeaders().get(h)));
}
public static void main(String[] args) throws Throwable {
ClassPathXmlApplicationContext classPathXmlApplicationContext =
new ClassPathXmlApplicationContext("inbound-ftp-context.xml");
classPathXmlApplicationContext.start();
}
}

View File

@@ -1,34 +0,0 @@
/*
* Copyright 2002-2010 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;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* This simple example demonstrates sending a file to a remote FTP server using the ftp:outbound-channel-adapter
* <p/>
* It reads files from a directory on your computer and systematically puts them on the remote FTP server,
*
* @author Josh Long
*/
public class OutboundFtpExample {
public static void main(String[] args) throws Throwable {
new ClassPathXmlApplicationContext("outbound-ftp-context.xml");
}
}

View File

@@ -8,15 +8,19 @@
http://www.springframework.org/schema/integration/ftp http://www.springframework.org/schema/integration/ftp/spring-integration-ftp-2.0.xsd">
<bean id="ftpClientFactory" class="org.springframework.integration.ftp.client.DefaultFtpClientFactory">
<property name="host" value="localhost"/>
<property name="port" value="22"/>
<property name="username" value="oleg"/>
<property name="password" value="password"/>
<property name="clientMode" value="1"/>
<property name="fileType" value="2"/>
<property name="remoteWorkingDirectory" value="foo/bar"/>
</bean>
<!-- <bean id="ftpClientFactory" class="org.springframework.integration.ftp.client.DefaultFtpClientFactory">-->
<!-- <property name="host" value="localhost"/>-->
<!-- <property name="port" value="22"/>-->
<!-- <property name="username" value="oleg"/>-->
<!-- <property name="password" value="password"/>-->
<!-- <property name="clientMode" value="1"/>-->
<!-- <property name="fileType" value="2"/>-->
<!-- <property name="remoteWorkingDirectory" value="foo/bar"/>-->
<!-- </bean>-->
<bean id="ftpClientFactory"
class="org.springframework.integration.ftp.config.FtpInboundChannelAdapterParserTests.TestClientFactoryBean"/>
<int-ftp:inbound-channel-adapter id="ftpInbound"
channel="ftpChannel"

View File

@@ -19,16 +19,22 @@ package org.springframework.integration.ftp.config;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.Map;
import java.util.Set;
import org.apache.commons.net.ftp.FTPClient;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
import org.springframework.integration.file.filters.CompositeFileListFilter;
import org.springframework.integration.ftp.client.DefaultFtpClientFactory;
import org.springframework.integration.ftp.client.FtpClientFactory;
import org.springframework.integration.ftp.client.FtpClientPool;
import org.springframework.integration.ftp.inbound.FtpInboundRemoteFileSystemSynchronizer;
@@ -85,4 +91,25 @@ public class FtpInboundChannelAdapterParserTests {
assertNotNull(adapter);
}
public static class TestClientFactoryBean implements FactoryBean<DefaultFtpClientFactory>{
@Override
public DefaultFtpClientFactory getObject() throws Exception {
DefaultFtpClientFactory factory = mock(DefaultFtpClientFactory.class);
FTPClient client = mock(FTPClient.class);
when(factory.getClient()).thenReturn(client);
return factory;
}
@Override
public Class<?> getObjectType() {
return DefaultFtpClientFactory.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
}

View File

@@ -31,7 +31,9 @@ import org.mockito.Mockito;
import org.springframework.core.io.FileSystemResource;
import org.springframework.integration.file.filters.FileListFilter;
import org.springframework.integration.ftp.client.FtpClientPool;
import org.springframework.integration.ftp.client.DefaultFtpClientFactory;
import org.springframework.integration.ftp.client.QueuedFtpClientPool;
import org.springframework.integration.ftp.filters.FtpPatternMatchingFileListFilter;
/**
* @author Oleg Zhurakousky
@@ -48,21 +50,24 @@ public class FtpInboundRemoteFileSystemSynchronizerTest {
}
FtpInboundRemoteFileSystemSynchronizer syncronizer = new FtpInboundRemoteFileSystemSynchronizer();
syncronizer.setLocalDirectory(new FileSystemResource(System.getProperty("java.io.tmpdir")));
FileListFilter filter = mock(FileListFilter.class);
FileListFilter filter = new FtpPatternMatchingFileListFilter("foo.txt");
//
syncronizer.setFilter(filter);
FtpClientPool clientPoll = mock(FtpClientPool.class);
DefaultFtpClientFactory factory = mock(DefaultFtpClientFactory.class);
FTPClient ftpClient = mock(FTPClient.class);
when(ftpClient.sendNoOp()).thenReturn(true);
when(factory.getClient()).thenReturn(ftpClient);
QueuedFtpClientPool clientPoll = new QueuedFtpClientPool(factory);
FTPFile f1 = mock(FTPFile.class);
when(f1.isFile()).thenReturn(true);
when(f1.getName()).thenReturn("foo.txt");
FTPFile[] files = new FTPFile[]{f1};
when(ftpClient.listFiles()).thenReturn(files);
when(clientPoll.getClient()).thenReturn(ftpClient);
when(filter.filterFiles((Object[]) Mockito.any())).thenReturn(Arrays.asList(files));
syncronizer.setClientPool(clientPoll);
syncronizer.setShouldDeleteSourceFile(true);
syncronizer.afterPropertiesSet();
@@ -71,6 +76,5 @@ public class FtpInboundRemoteFileSystemSynchronizerTest {
verify(ftpClient, times(1)).retrieveFile(Mockito.anyString(), Mockito.any(OutputStream.class));
verify(ftpClient, times(1)).deleteFile(Mockito.anyString());
verify(clientPoll, times(1)).releaseClient(ftpClient);
}
}

View File

@@ -1,39 +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:ftp="http://www.springframework.org/schema/integration/ftp"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:file="http://www.springframework.org/schema/integration/file"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/ftp http://www.springframework.org/schema/integration/ftp/spring-integration-ftp.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/integration/file http://www.springframework.org/schema/integration/file/spring-integration-file-1.0.xsd">
<context:property-placeholder
location="file://${user.home}/Desktop/ftp.properties"
ignore-unresolvable="true"/>
<file:inbound-channel-adapter channel="ftpOutbound"
filename-pattern=".*?jpg"
directory="#{systemProperties['user.home']}/Desktop/imagesToSendViaFTP"
auto-create-directory="true">
<int:poller>
<int:interval-trigger interval="1000" time-unit="MILLISECONDS"/>
</int:poller>
</file:inbound-channel-adapter>
<int:channel id="ftpOutbound"/>
<ftp:outbound-channel-adapter
remote-directory="${ftp.remotedir}"
channel="ftpOutbound"
host="${ftp.host}"
file-type="binary-file-type"
username="${ftp.username}"
password="${ftp.password}" port="2222"
client-mode="passive-local-data-connection-mode"
/>
</beans>