INT-1614 refactoring FTP for Session and SessionFactory

This commit is contained in:
Mark Fisher
2010-11-19 18:03:46 -05:00
parent 9596777724
commit 66e64979ef
13 changed files with 64 additions and 22 deletions

View File

@@ -33,6 +33,7 @@ import org.springframework.util.Assert;
*
* @author Josh Long
* @author Oleg Zhurakousky
* @author Mark Fisher
* @since 2.0
*/
public class CachingSessionFactory implements SessionFactory, DisposableBean {
@@ -70,7 +71,7 @@ public class CachingSessionFactory implements SessionFactory, DisposableBean {
if (null == session) {
session = sessionFactory.getSession();
}
return (session != null) ? new PooledSftpSession(session) : null;
return (session != null) ? new CachedSession(session) : null;
}
finally {
this.lock.unlock();
@@ -99,11 +100,11 @@ public class CachingSessionFactory implements SessionFactory, DisposableBean {
}
private class PooledSftpSession implements Session {
private class CachedSession implements Session {
private final Session targetSession;
private PooledSftpSession(Session targetSession) {
private CachedSession(Session targetSession) {
this.targetSession = targetSession;
}

View File

@@ -40,7 +40,7 @@ public abstract class AbstractFtpInboundChannelAdapterParser extends AbstractPol
BeanDefinitionBuilder poolBuilder =
BeanDefinitionBuilder.genericBeanDefinition("org.springframework.integration.file.remote.session.CachingSessionFactory");
poolBuilder.addConstructorArgReference(element.getAttribute("client-factory"));
poolBuilder.addConstructorArgReference(element.getAttribute("session-factory"));
BeanDefinitionBuilder synchronizerBuilder =
BeanDefinitionBuilder.genericBeanDefinition("org.springframework.integration.ftp.inbound.FtpInboundFileSynchronizer");

View File

@@ -17,11 +17,15 @@ package org.springframework.integration.ftp.config;
import org.w3c.dom.Element;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractOutboundChannelAdapterParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.util.StringUtils;
/**
* @author Oleg Zhurakousky
@@ -35,10 +39,26 @@ public abstract class AbstractFtpOutboundChannelAdapterParser extends AbstractOu
BeanDefinitionBuilder poolBuilder =
BeanDefinitionBuilder.genericBeanDefinition("org.springframework.integration.file.remote.session.CachingSessionFactory");
poolBuilder.addConstructorArgReference(element.getAttribute("client-factory"));
poolBuilder.addConstructorArgReference(element.getAttribute("session-factory"));
handlerBuilder.addConstructorArgValue(poolBuilder.getBeanDefinition());
String remoteDirectory = element.getAttribute("remote-directory");
String remoteDirectoryExpression = element.getAttribute("remote-directory-expression");
boolean hasDirectory = StringUtils.hasText(remoteDirectory);
boolean hasDirectoryExpression = StringUtils.hasText(remoteDirectoryExpression);
if (!(hasDirectory ^ hasDirectoryExpression)) {
throw new BeanDefinitionStoreException("exactly one of 'remote-directory' or 'remote-directory-expression' " +
"is required on the SFTP outbound adapter");
}
BeanDefinition expressionDef = null;
if (hasDirectory) {
expressionDef = new RootBeanDefinition("org.springframework.expression.common.LiteralExpression");
expressionDef.getConstructorArgumentValues().addGenericArgumentValue(remoteDirectory);
}
else if (hasDirectoryExpression) {
expressionDef = new RootBeanDefinition("org.springframework.integration.config.ExpressionFactoryBean");
expressionDef.getConstructorArgumentValues().addGenericArgumentValue(remoteDirectoryExpression);
}
handlerBuilder.addPropertyValue("remoteDirectoryExpression", expressionDef);
IntegrationNamespaceUtils.setValueIfAttributeDefined(handlerBuilder, element, "charset");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(handlerBuilder, element,"filename-generator", "fileNameGenerator");
return handlerBuilder.getBeanDefinition();

View File

@@ -28,6 +28,7 @@ import org.apache.commons.lang.SystemUtils;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.expression.Expression;
import org.springframework.integration.Message;
import org.springframework.integration.MessageDeliveryException;
import org.springframework.integration.file.DefaultFileNameGenerator;
@@ -35,6 +36,7 @@ import org.springframework.integration.file.FileNameGenerator;
import org.springframework.integration.file.remote.session.Session;
import org.springframework.integration.file.remote.session.SessionFactory;
import org.springframework.integration.handler.AbstractMessageHandler;
import org.springframework.integration.handler.ExpressionEvaluatingMessageProcessor;
import org.springframework.util.Assert;
import org.springframework.util.FileCopyUtils;
@@ -50,6 +52,10 @@ public class FtpSendingMessageHandler extends AbstractMessageHandler{
private static final String TEMPORARY_FILE_SUFFIX = ".writing";
private volatile ExpressionEvaluatingMessageProcessor<String> directoryExpressionProcesor;
private volatile Expression remoteDirectoryExpression;
private volatile SessionFactory sessionFactory;
private volatile FileNameGenerator fileNameGenerator = new DefaultFileNameGenerator();
@@ -73,6 +79,10 @@ public class FtpSendingMessageHandler extends AbstractMessageHandler{
this.sessionFactory = sessionFactory;
}
public void setRemoteDirectoryExpression(Expression remoteDirectoryExpression) {
this.remoteDirectoryExpression = remoteDirectoryExpression;
}
public void setTemporaryBufferFolder(Resource temporaryBufferFolder) {
this.temporaryBufferFolder = temporaryBufferFolder;
}
@@ -90,6 +100,10 @@ public class FtpSendingMessageHandler extends AbstractMessageHandler{
Assert.notNull(this.temporaryBufferFolder,
"'temporaryBufferFolder' must not be null");
this.temporaryBufferFolderFile = this.temporaryBufferFolder.getFile();
if (this.remoteDirectoryExpression != null) {
this.directoryExpressionProcesor =
new ExpressionEvaluatingMessageProcessor<String>(this.remoteDirectoryExpression, String.class);
}
}
private File handleFileMessage(File sourceFile, File tempFile, File resultFile) throws IOException {
@@ -147,7 +161,8 @@ public class FtpSendingMessageHandler extends AbstractMessageHandler{
Session session = this.sessionFactory.getSession();
boolean sentSuccesfully;
try {
sentSuccesfully = sendFile(file, session);
String targetDirectory = this.directoryExpressionProcesor.processMessage(message);
sentSuccesfully = sendFile(file, targetDirectory, session);
}
catch (FileNotFoundException e) {
throw new MessageDeliveryException(message,
@@ -180,9 +195,10 @@ public class FtpSendingMessageHandler extends AbstractMessageHandler{
}
}
private boolean sendFile(File file, Session session) throws FileNotFoundException, IOException {
private boolean sendFile(File file, String targetDirectory, Session session) throws FileNotFoundException, IOException {
FileInputStream fileInputStream = new FileInputStream(file);
session.put(fileInputStream, file.getName());
String remoteFilePath = targetDirectory + File.separatorChar + file.getName();
session.put(fileInputStream, remoteFilePath);
fileInputStream.close();
return true;
}

View File

@@ -22,6 +22,8 @@
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="base-ftp-adapter-type">
<xsd:attribute name="remote-directory" type="xsd:string"/>
<xsd:attribute name="remote-directory-expression" type="xsd:string"/>
<xsd:attribute name="filename-generator" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
@@ -73,7 +75,7 @@
<xsd:complexType name="base-ftp-adapter-type">
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="client-factory" type="xsd:string" use="required">
<xsd:attribute name="session-factory" type="xsd:string" use="required">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">

View File

@@ -21,7 +21,7 @@
</bean>
<ftp:inbound-channel-adapter id="adapterFtp"
client-factory="ftpClientFactory"
session-factory="ftpClientFactory"
channel="ftpIn"
filename-pattern="foo"
local-working-directory="file:target/foo"
@@ -33,7 +33,7 @@
<ftp:inbound-channel-adapter id="adapterFtp2"
client-factory="ftpClientFactory"
session-factory="ftpClientFactory"
channel="ftpIn"
filter="filter"
local-working-directory="file:target"

View File

@@ -22,7 +22,7 @@
<ftp:inbound-channel-adapter id="adapterFtpDontAutoCreate"
channel="ftpIn"
client-factory="ftpClientFactory"
session-factory="ftpClientFactory"
filter="filter"
local-working-directory="file:target/bar"
remote-directory="foo/bar"

View File

@@ -21,7 +21,8 @@
</bean>
<int-ftp:outbound-channel-adapter id="ftpOutboundAdapter"
client-factory="ftpClientFactory"
session-factory="ftpClientFactory"
remote-directory="foo/bar"
channel="ftpOutbound"
filename-generator="fileNameGenerator"/>

View File

@@ -13,7 +13,7 @@
<int-ftp:inbound-channel-adapter id="ftpInbound"
channel="ftpChannel"
client-factory="ftpClientFactory"
session-factory="ftpClientFactory"
charset="UTF-8"
auto-create-directories="true"
auto-delete-remote-files-on-sync="true"
@@ -25,7 +25,7 @@
<int-ftp:inbound-channel-adapter
channel="ftpChannel"
client-factory="ftpClientFactory"
session-factory="ftpClientFactory"
charset="UTF-8"
auto-create-directories="true"
auto-delete-remote-files-on-sync="true"

View File

@@ -19,7 +19,8 @@
<int-ftp:outbound-channel-adapter id="ftpOutbound"
channel="ftpChannel"
client-factory="ftpClientFactory"
session-factory="ftpClientFactory"
remote-directory="foo/bar"
charset="UTF-8"
filename-generator="fileNameGenerator"/>

View File

@@ -19,7 +19,7 @@
<int-ftp:inbound-channel-adapter id="ftpInbound"
channel="ftpChannel"
client-factory="ftpClientFactory"
session-factory="ftpClientFactory"
charset="UTF-8"
auto-create-directories="true"
auto-delete-remote-files-on-sync="true"
@@ -31,7 +31,7 @@
<int-ftp:inbound-channel-adapter
channel="ftpChannel"
client-factory="ftpClientFactory"
session-factory="ftpClientFactory"
charset="UTF-8"
auto-create-directories="true"
auto-delete-remote-files-on-sync="true"

View File

@@ -37,8 +37,9 @@
<int-ftp:outbound-channel-adapter id="ftpOutbound"
channel="ftpChannel"
client-factory="ftpClientFactory"
session-factory="ftpClientFactory"
charset="UTF-8"
remote-directory="foo/bar"
filename-generator="fileNameGenerator"/>
<int:channel id="ftpChannel"/>

View File

@@ -22,7 +22,7 @@
</bean>
<ftp:inbound-channel-adapter id="adapterFtp"
client-factory="ftpClientFactory"
session-factory="ftpClientFactory"
channel="ftpIn"
auto-create-directories="true"
local-working-directory="file:target/foo"