INT-3082 (S)FTP Remove Deprecated 'cache-sessions'

The 'cache-sessions' attribute was deprecated in 2.1 in favor
of using a configured CachingConnectionFactory to provide more
flexibility, such as setting the cache size.

Remove the attribute from the schemas.

Update tests.

Add docs.

Update Migration Guide on the project Wiki.
This commit is contained in:
Gary Russell
2013-08-14 16:10:37 -04:00
parent 4018c30f7d
commit 4832130ef2
22 changed files with 148 additions and 126 deletions

View File

@@ -16,15 +16,15 @@
package org.springframework.integration.file.config;
import org.w3c.dom.Element;
import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.ExpressionFactoryBean;
import org.springframework.integration.config.xml.AbstractPollingInboundChannelAdapterParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.file.remote.session.SessionFactoryFactoryBean;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* Abstract base class for parsing remote file inbound channel adapters.
@@ -41,11 +41,7 @@ public abstract class AbstractRemoteFileInboundChannelAdapterParser extends Abst
BeanDefinitionBuilder synchronizerBuilder = BeanDefinitionBuilder.genericBeanDefinition(
this.getInboundFileSynchronizerClassname());
BeanDefinitionBuilder sessionFactoryBuilder = BeanDefinitionBuilder.genericBeanDefinition(SessionFactoryFactoryBean.class);
sessionFactoryBuilder.addConstructorArgReference(element.getAttribute("session-factory"));
sessionFactoryBuilder.addConstructorArgValue(element.getAttribute("cache-sessions"));
synchronizerBuilder.addConstructorArgValue(sessionFactoryBuilder.getBeanDefinition());
synchronizerBuilder.addConstructorArgReference(element.getAttribute("session-factory"));
// configure the InboundFileSynchronizer properties
IntegrationNamespaceUtils.setValueIfAttributeDefined(synchronizerBuilder, element, "remote-directory");

View File

@@ -15,13 +15,13 @@
*/
package org.springframework.integration.file.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.AbstractConsumerEndpointParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.file.remote.session.SessionFactoryFactoryBean;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* @author Gary Russell
@@ -41,12 +41,7 @@ public abstract class AbstractRemoteFileOutboundGatewayParser extends AbstractCo
protected BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(getGatewayClassName());
// build the SessionFactory and provide it as a constructor argument
BeanDefinitionBuilder sessionFactoryBuilder = BeanDefinitionBuilder.genericBeanDefinition(SessionFactoryFactoryBean.class);
sessionFactoryBuilder.addConstructorArgReference(element.getAttribute("session-factory"));
sessionFactoryBuilder.addConstructorArgValue(element.getAttribute("cache-sessions"));
builder.addConstructorArgValue(sessionFactoryBuilder.getBeanDefinition());
builder.addConstructorArgReference(element.getAttribute("session-factory"));
builder.addConstructorArgValue(element.getAttribute("command"));
builder.addConstructorArgValue(element.getAttribute(EXPRESSION_ATTRIBUTE));

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-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.
@@ -30,26 +30,22 @@ import org.springframework.integration.config.xml.AbstractOutboundChannelAdapter
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.file.DefaultFileNameGenerator;
import org.springframework.integration.file.remote.handler.FileTransferringMessageHandler;
import org.springframework.integration.file.remote.session.SessionFactoryFactoryBean;
import org.springframework.util.StringUtils;
/**
* @author Oleg Zhurakousky
* @author Mark Fisher
* @author David Turanski
* @author Gary Russell
* @since 2.0
*/
public class RemoteFileOutboundChannelAdapterParser extends AbstractOutboundChannelAdapterParser {
@Override
protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) {
BeanDefinitionBuilder handlerBuilder = BeanDefinitionBuilder.genericBeanDefinition(FileTransferringMessageHandler.class);
BeanDefinitionBuilder sessionFactoryBuilder = BeanDefinitionBuilder.genericBeanDefinition(SessionFactoryFactoryBean.class);
sessionFactoryBuilder.addConstructorArgReference(element.getAttribute("session-factory"));
sessionFactoryBuilder.addConstructorArgValue(element.getAttribute("cache-sessions"));
handlerBuilder.addConstructorArgValue(sessionFactoryBuilder.getBeanDefinition());
handlerBuilder.addConstructorArgReference(element.getAttribute("session-factory"));
// configure MessageHandler properties
IntegrationNamespaceUtils.setValueIfAttributeDefined(handlerBuilder, element, "temporary-file-suffix");
@@ -82,14 +78,14 @@ public class RemoteFileOutboundChannelAdapterParser extends AbstractOutboundChan
handlerBuilder.addPropertyValue("remoteFileSeparator", element.getAttribute("remote-file-separator"));
return handlerBuilder.getBeanDefinition();
}
private void configureRemoteDirectories(Element element, BeanDefinitionBuilder handlerBuilder){
this.doConfigureRemoteDirectory(element, handlerBuilder, "remote-directory", "remote-directory-expression", "remoteDirectoryExpression", true);
this.doConfigureRemoteDirectory(element, handlerBuilder, "temporary-remote-directory", "temporary-remote-directory-expression", "temporaryRemoteDirectoryExpression", false);
}
private void doConfigureRemoteDirectory(Element element, BeanDefinitionBuilder handlerBuilder,
String directoryAttribute, String directoryExpressionAttribute,
private void doConfigureRemoteDirectory(Element element, BeanDefinitionBuilder handlerBuilder,
String directoryAttribute, String directoryExpressionAttribute,
String directoryExpressionPropertyName, boolean atLeastOneRequired){
String remoteDirectory = element.getAttribute(directoryAttribute);
String remoteDirectoryExpression = element.getAttribute(directoryExpressionAttribute);
@@ -101,14 +97,14 @@ public class RemoteFileOutboundChannelAdapterParser extends AbstractOutboundChan
"is required on a remote file outbound adapter");
}
}
BeanDefinition remoteDirectoryExpressionDefinition = null;
if (hasRemoteDirectory) {
remoteDirectoryExpressionDefinition = new RootBeanDefinition(LiteralExpression.class);
remoteDirectoryExpressionDefinition.getConstructorArgumentValues().addGenericArgumentValue(remoteDirectory);
}
else if (hasRemoteDirectoryExpression) {
remoteDirectoryExpressionDefinition = new RootBeanDefinition(ExpressionFactoryBean.class);
remoteDirectoryExpressionDefinition = new RootBeanDefinition(ExpressionFactoryBean.class);
remoteDirectoryExpressionDefinition.getConstructorArgumentValues().addGenericArgumentValue(remoteDirectoryExpression);
}
if (remoteDirectoryExpressionDefinition != null){

View File

@@ -22,6 +22,7 @@ import java.io.OutputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.integration.util.SimplePool;
@@ -44,10 +45,23 @@ public class CachingSessionFactory<F> implements SessionFactory<F>, DisposableBe
private final SimplePool<Session<F>> pool;
/**
* Create a CachingSessionFactory with an unlimited number of sessions.
* @param sessionFactory the underlying session factory.
*/
public CachingSessionFactory(SessionFactory<F> sessionFactory) {
this(sessionFactory, 0);
}
/**
* Create a CachingSessionFactory with the specified session limit. By default, if
* no sessions are available in the cache, and the size limit has been reached,
* calling threads will block until a session is available.
* @see #setSessionWaitTimeout(long)
* @see #setPoolSize(int)
* @param sessionFactory the underlying session factory.
* @param sessionCacheSize the maximum cache size.
*/
public CachingSessionFactory(SessionFactory<F> sessionFactory, int sessionCacheSize) {
this.sessionFactory = sessionFactory;
this.pool = new SimplePool<Session<F>>(sessionCacheSize, new SimplePool.PoolItemCallback<Session<F>>() {
@@ -75,14 +89,24 @@ public class CachingSessionFactory<F> implements SessionFactory<F>, DisposableBe
this.pool.setWaitTimeout(sessionWaitTimeout);
}
/**
* Modify the target session pool size; the actual pool size will adjust up/down
* to this size as and when sessions are requested or retrieved.
*/
public void setPoolSize(int poolSize) {
this.pool.setPoolSize(poolSize);
}
/**
* Get a session from the pool (or block if none available).
*/
public Session<F> getSession() {
return new CachedSession(this.pool.getItem());
}
/**
* Remove (close) any unused sessions in the pool.
*/
public void destroy() {
this.pool.removeAllIdleItems();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-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.
@@ -15,21 +15,37 @@
*/
package org.springframework.integration.file.remote.session;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.FactoryBean;
/**
* Temporary factory bean to manage SessionFactory until deprecated 'cache-sessions' attribute
* is removed.
*
*
* The attribute is now removed so we deprecate this class and log a message in case someone
* is using it directly. It is no longer used by the framework.
*
* @author Oleg Zhurakousky
* @author Gary Russell
* @since 2.1
*
* @deprecated
*/
@Deprecated
public class SessionFactoryFactoryBean<T> implements FactoryBean<SessionFactory<T>> {
Log logger = LogFactory.getLog(this.getClass());
private final SessionFactory<T> sessionFactory;
public SessionFactoryFactoryBean(SessionFactory<T> sessionFactory, boolean cacheSessions){
if (logger.isWarnEnabled()) {
logger.warn("Do not use this factory bean; "
+ "instantiate the session factory directly; "
+ "if cached sessions are required, wrap it in a CachingSessionFactory.");
}
if (cacheSessions && !(sessionFactory instanceof CachingSessionFactory)){
this.sessionFactory = new CachingSessionFactory<T>(sessionFactory);
}
@@ -42,7 +58,7 @@ public class SessionFactoryFactoryBean<T> implements FactoryBean<SessionFactory<
return this.sessionFactory;
}
public Class<?> getObjectType() {
return this.sessionFactory.getClass();
}

View File

@@ -521,14 +521,6 @@
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="cache-sessions" type="xsd:string"
default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
[DEPRECATED] Consider wrapping your SessionFactory in an instance of org.springframework.integration.file.remote.session.CachingSessionFactory.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="auto-startup" type="xsd:string"
default="true">
<xsd:annotation>

View File

@@ -10,10 +10,13 @@
<bean id="ftpSessionFactory"
class="org.springframework.integration.ftp.config.FtpInboundChannelAdapterParserTests.TestSessionFactoryBean"/>
<bean id="csf" class="org.springframework.integration.file.remote.session.CachingSessionFactory">
<constructor-arg ref="ftpSessionFactory"/>
</bean>
<int-ftp:inbound-channel-adapter id="ftpInbound"
channel="ftpChannel"
session-factory="ftpSessionFactory"
cache-sessions="false"
charset="UTF-8"
auto-create-local-directory="true"
auto-startup="false"
@@ -58,9 +61,9 @@
<int:poller fixed-rate="1000"/>
</int-ftp:inbound-channel-adapter>
<int-ftp:inbound-channel-adapter id="simpleAdapter"
<int-ftp:inbound-channel-adapter id="simpleAdapterWithCachedSessions"
channel="ftpChannel"
session-factory="ftpSessionFactory"
session-factory="csf"
local-directory="."
remote-directory="foo/bar">
<int:poller fixed-rate="1000"/>

View File

@@ -30,6 +30,7 @@ import java.util.Map;
import java.util.concurrent.PriorityBlockingQueue;
import org.junit.Test;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
@@ -84,10 +85,10 @@ public class FtpInboundChannelAdapterParserTests {
}
@Test
public void cachingSessionFactoryByDefault() throws Exception{
public void cachingSessionFactory() throws Exception{
ApplicationContext ac = new ClassPathXmlApplicationContext(
"FtpInboundChannelAdapterParserTests-context.xml", this.getClass());
SourcePollingChannelAdapter adapter = ac.getBean("simpleAdapter", SourcePollingChannelAdapter.class);
SourcePollingChannelAdapter adapter = ac.getBean("simpleAdapterWithCachedSessions", SourcePollingChannelAdapter.class);
Object sessionFactory = TestUtils.getPropertyValue(adapter, "source.synchronizer.sessionFactory");
assertEquals(CachingSessionFactory.class, sessionFactory.getClass());
FtpInboundFileSynchronizer fisync =

View File

@@ -25,7 +25,6 @@
<int-ftp:outbound-channel-adapter id="ftpOutbound"
channel="ftpChannel"
session-factory="ftpSessionFactory"
cache-sessions="false"
remote-directory="foo/bar"
temporary-remote-directory="baz/abc"
charset="UTF-8"

View File

@@ -19,7 +19,6 @@
<int-ftp:outbound-channel-adapter id="ftpOutbound"
channel="ftpChannel"
session-factory="ftpSessionFactory"
cache-sessions="false"
remote-directory="foo/bar"
temporary-remote-directory="baz/abc"
charset="UTF-8"

View File

@@ -11,6 +11,10 @@
<constructor-arg value="org.springframework.integration.file.remote.session.SessionFactory"/>
</bean>
<bean id="csf" class="org.springframework.integration.file.remote.session.CachingSessionFactory">
<constructor-arg ref="sf"/>
</bean>
<int-ftp:outbound-gateway id="gateway1"
local-directory="local-test-dir"
session-factory="sf"
@@ -19,7 +23,6 @@
reply-timeout="777"
auto-create-local-directory="false"
auto-startup="false"
cache-sessions="false"
filename-pattern="*"
remote-file-separator="X"
command="ls"
@@ -30,12 +33,11 @@
<int-ftp:outbound-gateway id="gateway2"
local-directory="local-test-dir"
session-factory="sf"
session-factory="csf"
request-channel="inbound2"
reply-channel="outbound"
auto-create-local-directory="false"
auto-startup="false"
cache-sessions="true"
remote-file-separator="X"
command="get"
command-options="-P"
@@ -64,7 +66,6 @@
request-channel="inbound3"
reply-channel="outbound"
auto-startup="false"
cache-sessions="false"
filename-pattern="*"
remote-file-separator="X"
command="ls"

View File

@@ -26,13 +26,13 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.endpoint.EventDrivenConsumer;
import org.springframework.integration.file.remote.handler.FileTransferringMessageHandler;
import org.springframework.integration.file.remote.session.CachingSessionFactory;
import org.springframework.integration.ftp.session.DefaultFtpsSessionFactory;
import org.springframework.integration.test.util.TestUtils;
/**
* @author Oleg Zhurakousky
* @author Gunnar Hillert
* @author Gary Russell
* @since 2.0
*/
public class FtpsOutboundChannelAdapterParserTests {
@@ -48,8 +48,7 @@ public class FtpsOutboundChannelAdapterParserTests {
assertEquals(ac.getBean("fileNameGenerator"), TestUtils.getPropertyValue(handler, "fileNameGenerator"));
assertEquals("UTF-8", TestUtils.getPropertyValue(handler, "charset"));
assertNotNull(TestUtils.getPropertyValue(handler, "temporaryDirectory"));
CachingSessionFactory<?> cacheSf = TestUtils.getPropertyValue(handler, "sessionFactory", CachingSessionFactory.class);
DefaultFtpsSessionFactory sf = TestUtils.getPropertyValue(cacheSf, "sessionFactory", DefaultFtpsSessionFactory.class);
DefaultFtpsSessionFactory sf = TestUtils.getPropertyValue(handler, "sessionFactory", DefaultFtpsSessionFactory.class);
assertEquals("localhost", TestUtils.getPropertyValue(sf, "host"));
assertEquals(22, TestUtils.getPropertyValue(sf, "port"));
}

View File

@@ -527,14 +527,6 @@
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="cache-sessions" type="xsd:string"
default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
[DEPRECATED] Consider wrapping your SessionFactory in an instance of org.springframework.integration.file.remote.session.CachingSessionFactory.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="auto-startup" type="xsd:string"
default="true">
<xsd:annotation>

View File

@@ -32,21 +32,16 @@
<beans:property name="sessionConfig" ref="sessionConfig"/>
</beans:bean>
<beans:bean id="csf" class="org.springframework.integration.file.remote.session.CachingSessionFactory">
<beans:constructor-arg ref="sftpSessionFactory"/>
</beans:bean>
<util:properties id="sessionConfig">
<beans:prop key="StrictHostKeyChecking">no</beans:prop>
</util:properties>
<sftp:inbound-channel-adapter id="defaultAdapter"
session-factory="sftpSessionFactory"
channel="requestChannel"
remote-directory="/foo"
local-directory="file:local-test-dir"
auto-startup="false">
<poller fixed-rate="1000"/>
</sftp:inbound-channel-adapter>
<sftp:inbound-channel-adapter id="cachingAdapter"
session-factory="sftpSessionFactory"
cache-sessions="true"
session-factory="csf"
channel="requestChannel"
remote-directory="/foo"
local-directory="file:local-test-dir"
@@ -56,7 +51,6 @@
<sftp:inbound-channel-adapter id="nonCachingAdapter"
session-factory="sftpSessionFactory"
cache-sessions="false"
channel="requestChannel"
remote-directory="/foo"
local-directory="file:local-test-dir"

View File

@@ -16,8 +16,8 @@
package org.springframework.integration.sftp.config;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.Properties;
@@ -34,31 +34,23 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Mark Fisher
* @author Gunnar Hillert
* @author Gary Russell
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class InboundChannelAdapterParserCachingTests {
@Autowired private Object defaultAdapter;
@Autowired private Object cachingAdapter;
@Autowired private Object nonCachingAdapter;
@Test
public void defaultAdapter() {
Object sessionFactory = TestUtils.getPropertyValue(defaultAdapter, "source.synchronizer.sessionFactory");
assertEquals(CachingSessionFactory.class, sessionFactory.getClass());
Properties sessionConfig = TestUtils.getPropertyValue(sessionFactory, "sessionFactory.sessionConfig", Properties.class);
assertNotNull(sessionConfig);
assertEquals("no", sessionConfig.getProperty("StrictHostKeyChecking"));
}
@Test
public void cachingAdapter() {
Object sessionFactory = TestUtils.getPropertyValue(cachingAdapter, "source.synchronizer.sessionFactory");
assertEquals(CachingSessionFactory.class, sessionFactory.getClass());
Properties sessionConfig = TestUtils.getPropertyValue(sessionFactory, "sessionFactory.sessionConfig", Properties.class);
assertNotNull(sessionConfig);
assertEquals("no", sessionConfig.getProperty("StrictHostKeyChecking"));
}
@Test

View File

@@ -17,22 +17,19 @@
<property name="user" value="oleg"/>
</bean>
<bean id="csf" class="org.springframework.integration.file.remote.session.CachingSessionFactory">
<constructor-arg ref="sftpSessionFactory"/>
</bean>
<int:publish-subscribe-channel id="inputChannel"/>
<int-sftp:outbound-channel-adapter id="defaultAdapter"
session-factory="sftpSessionFactory"
channel="inputChannel"
remote-directory="foo/bar"/>
<int-sftp:outbound-channel-adapter id="cachingAdapter"
session-factory="sftpSessionFactory"
cache-sessions="true"
session-factory="csf"
channel="inputChannel"
remote-directory="foo/bar"/>
<int-sftp:outbound-channel-adapter id="nonCachingAdapter"
session-factory="sftpSessionFactory"
cache-sessions="false"
channel="inputChannel"
remote-directory="foo/bar"/>

View File

@@ -20,6 +20,7 @@ import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.file.remote.session.CachingSessionFactory;
import org.springframework.integration.sftp.session.DefaultSftpSessionFactory;
@@ -30,24 +31,17 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Mark Fisher
* @author Gunnar Hillert
* @author Gary Russell
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class OutboundChannelAdapterParserCachingTests {
@Autowired private Object defaultAdapter;
@Autowired private Object cachingAdapter;
@Autowired private Object nonCachingAdapter;
@Test
public void defaultAdapter() {
Object sessionFactory = TestUtils.getPropertyValue(defaultAdapter, "handler.sessionFactory");
assertEquals(CachingSessionFactory.class, sessionFactory.getClass());
}
@Test
public void cachingAdapter() {
Object sessionFactory = TestUtils.getPropertyValue(cachingAdapter, "handler.sessionFactory");

View File

@@ -17,10 +17,14 @@
<property name="user" value="oleg"/>
</bean>
<bean id="csf" class="org.springframework.integration.file.remote.session.CachingSessionFactory">
<constructor-arg ref="sftpSessionFactory"/>
</bean>
<int:publish-subscribe-channel id="inputChannel"/>
<int-sftp:outbound-channel-adapter id="sftpOutboundAdapter"
session-factory="sftpSessionFactory"
session-factory="csf"
channel="inputChannel"
charset="UTF-8"
remote-filename-generator="fileNameGenerator"

View File

@@ -11,6 +11,10 @@
<constructor-arg value="org.springframework.integration.file.remote.session.SessionFactory"/>
</bean>
<bean id="csf" class="org.springframework.integration.file.remote.session.CachingSessionFactory">
<constructor-arg ref="sf"/>
</bean>
<int-sftp:outbound-gateway id="gateway1"
local-directory="local-test-dir"
session-factory="sf"
@@ -19,7 +23,6 @@
reply-timeout="777"
auto-create-local-directory="false"
auto-startup="false"
cache-sessions="false"
filename-pattern="*"
remote-file-separator="X"
command="ls"
@@ -30,12 +33,11 @@
<int-sftp:outbound-gateway id="gateway2"
local-directory="local-test-dir"
session-factory="sf"
session-factory="csf"
request-channel="inbound2"
reply-channel="outbound"
auto-create-local-directory="false"
auto-startup="false"
cache-sessions="true"
remote-file-separator="X"
command="get"
command-options="-P"
@@ -44,7 +46,7 @@
/>
<int-sftp:outbound-gateway id="gateway3"
session-factory="sf"
session-factory="csf"
request-channel="inbound1"
reply-channel="outbound"
command="mv"
@@ -60,7 +62,6 @@
reply-channel="outbound"
auto-create-local-directory="false"
auto-startup="false"
cache-sessions="true"
remote-file-separator="X"
command="get"
command-options="-P"

View File

@@ -35,6 +35,9 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/ftp
<section id="ftp-session-factory">
<title>FTP Session Factory</title>
<important>
Starting with version 3.0, sessions are no longer cached by default. See <xref linkend="ftp-session-caching"/>.
</important>
<para>
Before configuring FTP adapters you must configure an <emphasis>FTP Session Factory</emphasis>. You can configure
the <emphasis>FTP Session Factory</emphasis> with a regular bean definition where the implementation class is <classname>org.springframework.integration.ftp.session.DefaultFtpSessionFactory</classname>:
@@ -446,14 +449,17 @@ protected void postProcessClientBeforeConnect(T client) throws IOException {
</section>
<section id="ftp-session-caching">
<title>FTP Session Caching</title>
<important>
Starting with version 3.0, sessions are no longer cached by default; the <code>cache-sessions</code> attribute
is no longer supported on endpoints. You must now use a <classname>CachingSessionFactory</classname> (see below) if you
wish to cache sessions.
</important>
<para>
As of version 2.1 we've exposed more flexibility with regard to session management for remote file adapters (e.g., FTP, SFTP etc).
In previous versions the sessions were cached automatically by default. We did expose a <code>cache-sessions</code> attribute for
disabling the auto caching, but that solution did not provide a way to configure other session caching attributes. For example, one
of the requested features was to support a limit on the number of sessions created since a remote server may impose a limit on the
number of client connections. To support that requirement and other configuration options, we decided to promote explicit definition
of the <classname>CachingSessionFactory</classname> instance. That provides the <code>sessionCacheSize</code> and <code>sessionWaitTimeout</code>
properties. As its name suggests, the <code>sessionCacheSize</code> property controls how many active sessions this adapter will
In versions prior to 3.0, the sessions were cached automatically by default. A <code>cache-sessions</code> attribute was available for
disabling the auto caching, but that solution did not provide a way to configure other session caching attributes. For example,
you could not limit on the number of sessions created. To support that requirement and other configuration options, a
<classname>CachingSessionFactory</classname> was provided. It provides <code>sessionCacheSize</code> and <code>sessionWaitTimeout</code>
properties. As its name suggests, the <code>sessionCacheSize</code> property controls how many active sessions the factory will
maintain in its cache (the DEFAULT is unbounded). If the <code>sessionCacheSize</code> threshold has been reached, any attempt to
acquire another session will block until either one of the cached sessions becomes available or until the wait time for a Session
expires (the DEFAULT wait time is Integer.MAX_VALUE). The <code>sessionWaitTimeout</code> property enables configuration of that value.

View File

@@ -31,6 +31,9 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/sftp
<section id="sftp-session-factory">
<title>SFTP Session Factory</title>
<important>
Starting with version 3.0, sessions are no longer cached by default. See <xref linkend="sftp-session-caching"/>.
</important>
<para>
Before configuring SFTP adapters, you must configure an <emphasis>SFTP Session
Factory</emphasis>. You can configure the <emphasis>SFTP Session
@@ -179,14 +182,17 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/sftp
<section id="sftp-session-caching">
<title>SFTP Session Caching</title>
<important>
Starting with version 3.0, sessions are no longer cached by default; the <code>cache-sessions</code> attribute
is no longer supported on endpoints. You must now use a <classname>CachingSessionFactory</classname> (see below) if you
wish to cache sessions.
</important>
<para>
As of version 2.1 we've exposed more flexibility with regard to session management for remote file adapters (e.g., FTP, SFTP etc).
In previous versions the sessions were cached automatically by default. We did expose a <code>cache-sessions</code> attribute for
disabling the auto caching, but that solution did not provide a way to configure other session caching attributes. For example, one
of the requested features was to support a limit on the number of sessions created since a remote server may impose a limit on the
number of client connections. To support that requirement and other configuration options, we decided to promote explicit definition
of the <classname>CachingSessionFactory</classname> instance. That provides the <code>sessionCacheSize</code> and <code>sessionWaitTimeout</code>
properties. As its name suggests, the <code>sessionCacheSize</code> property controls how many active sessions this adapter will
In versions prior to 3.0, the sessions were cached automatically by default. A <code>cache-sessions</code> attribute was available for
disabling the auto caching, but that solution did not provide a way to configure other session caching attributes. For example,
you could not limit on the number of sessions created. To support that requirement and other configuration options, a
<classname>CachingSessionFactory</classname> was provided. It provides <code>sessionCacheSize</code> and <code>sessionWaitTimeout</code>
properties. As its name suggests, the <code>sessionCacheSize</code> property controls how many active sessions the factory will
maintain in its cache (the DEFAULT is unbounded). If the <code>sessionCacheSize</code> threshold has been reached, any attempt to
acquire another session will block until either one of the cached sessions becomes available or until the wait time for a Session
expires (the DEFAULT wait time is Integer.MAX_VALUE). The <code>sessionWaitTimeout</code> property enables configuration of that value.

View File

@@ -106,8 +106,23 @@
URI-schemes supported by Spring Web Services. For more information see <xref linkend="outbound-uri"/>.
</para>
</section>
<section id="3.0-ftp-cache-changes">
<title>FTP, SFTP and FTPS Cached Sessions</title>
<para>
The FTP, SFTP and FTPS endpoints no longer cache sessions by default.
</para>
<para>
The deprecated <code>cached-sessions</code> attribute has been removed from all endpoints.
Previously, the embedded caching mechanism controlled by this attribute's value didn't
provide a way to limit the size of the cache, which could
grow indefinitely. The <classname>CachingConnectionFactory</classname> was introduced in
release 2.1 and it became the preferred (and is now the only) way to cache sessions.
For more information, see
<xref linkend="ftp-session-caching"/> and <xref linkend="sftp-session-caching"/>.
</para>
</section>
<section id="3.0-xFTP-ib">
<title>(S)FTP(S) Inbound Adapters</title>
<title>FTP, SFTP and FTPS Inbound Adapters</title>
<para>
Previously, there was no way to override the default filter used to process files retrieved
from a remote server. The <code>filter</code> attribute determines which files are retrieved
@@ -128,7 +143,7 @@
</para>
</section>
<section id="3.0-xFTP-gw">
<title>(S)FTP(S) Gateways</title>
<title>FTP, SFTP and FTPS Gateways</title>
<para>
The gateways now support the <code>mv</code> command, enabling the renaming of remote
files.