INT-1562 removed the sftp remote directory header, but added support for an expression on the outbound adapter
This commit is contained in:
@@ -1,27 +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.sftp;
|
||||
|
||||
/**
|
||||
* @author Josh Long
|
||||
* @since 2.0
|
||||
*/
|
||||
public abstract class SftpHeaders {
|
||||
|
||||
public static final String REMOTE_DIRECTORY = "sftp_remoteDirectory";
|
||||
|
||||
}
|
||||
@@ -17,6 +17,8 @@
|
||||
package org.springframework.integration.sftp.config;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.common.LiteralExpression;
|
||||
import org.springframework.integration.sftp.outbound.SftpSendingMessageHandler;
|
||||
import org.springframework.integration.sftp.session.QueuedSftpSessionPool;
|
||||
import org.springframework.integration.sftp.session.SftpSessionFactory;
|
||||
@@ -37,7 +39,7 @@ public class SftpMessageSendingConsumerFactoryBean implements FactoryBean<SftpSe
|
||||
|
||||
private String password;
|
||||
|
||||
private String remoteDirectory;
|
||||
private Expression remoteDirectoryExpression;
|
||||
|
||||
private String username;
|
||||
|
||||
@@ -45,6 +47,7 @@ public class SftpMessageSendingConsumerFactoryBean implements FactoryBean<SftpSe
|
||||
|
||||
private String charset;
|
||||
|
||||
|
||||
public void setCharset(String charset) {
|
||||
this.charset = charset;
|
||||
}
|
||||
@@ -61,6 +64,10 @@ public class SftpMessageSendingConsumerFactoryBean implements FactoryBean<SftpSe
|
||||
this.keyFilePassword = keyFilePassword;
|
||||
}
|
||||
|
||||
public void setUsername(final String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public void setPassword(final String password) {
|
||||
this.password = password;
|
||||
}
|
||||
@@ -69,24 +76,25 @@ public class SftpMessageSendingConsumerFactoryBean implements FactoryBean<SftpSe
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public void setRemoteDirectory(final String remoteDirectory) {
|
||||
this.remoteDirectory = remoteDirectory;
|
||||
public void setRemoteDirectory(String remoteDirectory) {
|
||||
remoteDirectory = (remoteDirectory != null) ? remoteDirectory : "";
|
||||
this.remoteDirectoryExpression = new LiteralExpression(remoteDirectory);
|
||||
}
|
||||
|
||||
public void setUsername(final String username) {
|
||||
this.username = username;
|
||||
public void setRemoteDirectoryExpression(Expression remoteDirectoryExpression) {
|
||||
this.remoteDirectoryExpression = remoteDirectoryExpression;
|
||||
}
|
||||
|
||||
public SftpSendingMessageHandler getObject() throws Exception {
|
||||
SftpSessionFactory sessionFactory = SftpSessionUtils.buildSftpSessionFactory(
|
||||
this.host, this.password, this.username, this.keyFile, this.keyFilePassword, this.port);
|
||||
QueuedSftpSessionPool queuedSFTPSessionPool = new QueuedSftpSessionPool(15, sessionFactory);
|
||||
queuedSFTPSessionPool.afterPropertiesSet();
|
||||
SftpSendingMessageHandler sftpSendingMessageHandler = new SftpSendingMessageHandler(queuedSFTPSessionPool);
|
||||
sftpSendingMessageHandler.setRemoteDirectory(this.remoteDirectory);
|
||||
sftpSendingMessageHandler.setCharset(this.charset);
|
||||
sftpSendingMessageHandler.afterPropertiesSet();
|
||||
return sftpSendingMessageHandler;
|
||||
QueuedSftpSessionPool sessionPool = new QueuedSftpSessionPool(15, sessionFactory);
|
||||
sessionPool.afterPropertiesSet();
|
||||
SftpSendingMessageHandler messageHandler = new SftpSendingMessageHandler(sessionPool);
|
||||
messageHandler.setRemoteDirectoryExpression(this.remoteDirectoryExpression);
|
||||
messageHandler.setCharset(this.charset);
|
||||
messageHandler.afterPropertiesSet();
|
||||
return messageHandler;
|
||||
}
|
||||
|
||||
public Class<? extends SftpSendingMessageHandler> getObjectType() {
|
||||
|
||||
@@ -26,12 +26,15 @@ import org.springframework.integration.config.xml.AbstractIntegrationNamespaceHa
|
||||
import org.springframework.integration.config.xml.AbstractOutboundChannelAdapterParser;
|
||||
import org.springframework.integration.config.xml.AbstractPollingInboundChannelAdapterParser;
|
||||
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides namespace support for using SFTP.
|
||||
* This is largely based on the FTP support by Iwein Fuld.
|
||||
*
|
||||
* @author Josh Long
|
||||
* @author Mark Fisher
|
||||
* @since 2.0
|
||||
*/
|
||||
public class SftpNamespaceHandler extends AbstractIntegrationNamespaceHandler {
|
||||
|
||||
@@ -49,9 +52,27 @@ public class SftpNamespaceHandler extends AbstractIntegrationNamespaceHandler {
|
||||
@Override
|
||||
protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(SftpMessageSendingConsumerFactoryBean.class.getName());
|
||||
for (String p : "auto-create-directories,username,password,host,port,key-file,key-file-password,remote-directory,charset".split(",")) {
|
||||
for (String p : "auto-create-directories,username,password,host,port,key-file,key-file-password,charset".split(",")) {
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, p);
|
||||
}
|
||||
String remoteDirectory = element.getAttribute("remote-directory");
|
||||
String remoteDirectoryExpression = element.getAttribute("remote-directory-expression");
|
||||
boolean hasLiteralRemoteDirectory = StringUtils.hasText(remoteDirectory);
|
||||
boolean hasRemoteDirectoryExpression = StringUtils.hasText(remoteDirectoryExpression);
|
||||
if (hasLiteralRemoteDirectory ^ hasRemoteDirectoryExpression) {
|
||||
if (hasLiteralRemoteDirectory) {
|
||||
builder.addPropertyValue("remoteDirectory", remoteDirectory);
|
||||
}
|
||||
else {
|
||||
BeanDefinitionBuilder expressionDefBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
"org.springframework.integration.config.ExpressionFactoryBean");
|
||||
expressionDefBuilder.addConstructorArgValue(remoteDirectoryExpression);
|
||||
builder.addPropertyValue("remoteDirectoryExpression", expressionDefBuilder.getBeanDefinition());
|
||||
}
|
||||
}
|
||||
else {
|
||||
parserContext.getReaderContext().error("exactly one of 'remote-directory' or 'remote-directory-expression' is required", element);
|
||||
}
|
||||
return builder.getBeanDefinition();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,16 +31,16 @@ import org.apache.commons.lang.SystemUtils;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
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.MessageHeaders;
|
||||
import org.springframework.integration.MessagingException;
|
||||
import org.springframework.integration.core.MessageHandler;
|
||||
import org.springframework.integration.file.DefaultFileNameGenerator;
|
||||
import org.springframework.integration.file.FileNameGenerator;
|
||||
import org.springframework.integration.sftp.SftpHeaders;
|
||||
import org.springframework.integration.sftp.session.SftpSession;
|
||||
import org.springframework.integration.sftp.session.SftpSessionPool;
|
||||
import org.springframework.integration.util.AbstractExpressionEvaluator;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
@@ -53,14 +53,14 @@ import com.jcraft.jsch.ChannelSftp;
|
||||
* @author Josh Long
|
||||
* @since 2.0
|
||||
*/
|
||||
public class SftpSendingMessageHandler implements MessageHandler, InitializingBean {
|
||||
public class SftpSendingMessageHandler extends AbstractExpressionEvaluator implements MessageHandler, InitializingBean {
|
||||
|
||||
private static final String TEMPORARY_FILE_SUFFIX = ".writing";
|
||||
|
||||
|
||||
private volatile SftpSessionPool pool;
|
||||
|
||||
private volatile String remoteDirectory;
|
||||
private volatile Expression remoteDirectoryExpression;
|
||||
|
||||
private volatile FileNameGenerator fileNameGenerator = new DefaultFileNameGenerator();
|
||||
|
||||
@@ -68,8 +68,6 @@ public class SftpSendingMessageHandler implements MessageHandler, InitializingBe
|
||||
|
||||
private volatile Resource temporaryBufferFolder = new FileSystemResource(SystemUtils.getJavaIoTmpDir());
|
||||
|
||||
private volatile boolean initialized;
|
||||
|
||||
private volatile String charset = Charset.defaultCharset().name();
|
||||
|
||||
|
||||
@@ -86,12 +84,8 @@ public class SftpSendingMessageHandler implements MessageHandler, InitializingBe
|
||||
this.fileNameGenerator = fileNameGenerator;
|
||||
}
|
||||
|
||||
public void setRemoteDirectory(final String remoteDirectory) {
|
||||
this.remoteDirectory = remoteDirectory;
|
||||
}
|
||||
|
||||
public String getRemoteDirectory() {
|
||||
return this.remoteDirectory;
|
||||
public void setRemoteDirectoryExpression(Expression remoteDirectoryExpression) {
|
||||
this.remoteDirectoryExpression = remoteDirectoryExpression;
|
||||
}
|
||||
|
||||
public void setCharset(String charset) {
|
||||
@@ -101,12 +95,6 @@ public class SftpSendingMessageHandler implements MessageHandler, InitializingBe
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(this.pool, "the pool must not be null");
|
||||
this.temporaryBufferFolderFile = this.temporaryBufferFolder.getFile();
|
||||
if (!this.initialized) {
|
||||
if (StringUtils.isEmpty(this.remoteDirectory)) {
|
||||
this.remoteDirectory = null;
|
||||
}
|
||||
this.initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
private File handleFileMessage(File sourceFile, File tempFile, File resultFile) throws IOException {
|
||||
@@ -182,16 +170,11 @@ public class SftpSendingMessageHandler implements MessageHandler, InitializingBe
|
||||
InputStream fileInputStream = null;
|
||||
try {
|
||||
fileInputStream = new FileInputStream(file);
|
||||
String baseOfRemotePath = StringUtils.isEmpty(this.remoteDirectory) ? StringUtils.EMPTY : remoteDirectory; // the safe default
|
||||
String dynRd = null;
|
||||
MessageHeaders messageHeaders = null;
|
||||
if (message != null) {
|
||||
messageHeaders = message.getHeaders();
|
||||
if ((messageHeaders != null) && messageHeaders.containsKey(SftpHeaders.REMOTE_DIRECTORY)) {
|
||||
dynRd = (String) messageHeaders.get(SftpHeaders.REMOTE_DIRECTORY);
|
||||
if (!StringUtils.isEmpty(dynRd)) {
|
||||
baseOfRemotePath = dynRd;
|
||||
}
|
||||
String baseOfRemotePath = "";
|
||||
if (this.remoteDirectoryExpression != null) {
|
||||
String result = this.evaluateExpression(this.remoteDirectoryExpression, message, String.class);
|
||||
if (result != null) {
|
||||
baseOfRemotePath = result;
|
||||
}
|
||||
}
|
||||
if (!StringUtils.defaultString(baseOfRemotePath).endsWith("/")) {
|
||||
|
||||
@@ -33,9 +33,7 @@
|
||||
<xsd:element name="outbound-channel-adapter">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
|
||||
Builds an outbound-channel-adapter that writes files to a remote SFTP endpoint.
|
||||
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
@@ -49,16 +47,14 @@
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
|
||||
<xsd:attribute name="username" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="remote-directory" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="remote-directory" type="xsd:string"/>
|
||||
<xsd:attribute name="remote-directory-expression" type="xsd:string"/>
|
||||
<xsd:attribute name="host" type="xsd:string" use="required"/>
|
||||
|
||||
<xsd:attribute name="password" type="xsd:string"/>
|
||||
<xsd:attribute name="port" type="xsd:int" default="22"/>
|
||||
<xsd:attribute name="key-file" type="xsd:string"/>
|
||||
<xsd:attribute name="key-file-password" type="xsd:string"/>
|
||||
|
||||
<xsd:attribute name="charset" type="xsd:string"/>
|
||||
<xsd:attribute name="auto-create-directories" type="xsd:boolean"/>
|
||||
</xsd:complexType>
|
||||
@@ -67,14 +63,13 @@
|
||||
<xsd:element name="inbound-channel-adapter">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
|
||||
Builds an inbound-channel-adapter that synchronizes with a remote SFTP endpoint.
|
||||
You may configure a <code>poller</code> element to determine at what frequency to scan the remote directory.
|
||||
There is support for automatically deleting remote files upon synchornization. This adapter supports two connectivity options:
|
||||
|
||||
<ol>
|
||||
<li> Password authentication: using this opton, authentication is done using a username and a password.</li>
|
||||
<li> Key-based authentication: using this option, you may specify a key that will be used to authenticate. If they key itself is encrypted and requires a password, you may specify that, as well.</li>
|
||||
<li> Key-based authentication: using this option, you may specify a key that will be used to authenticate.
|
||||
If they key itself is encrypted and requires a password, you may specify that, as well.</li>
|
||||
</ol>
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
@@ -92,7 +87,6 @@
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
|
||||
<xsd:attribute name="filter" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
@@ -102,26 +96,18 @@
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
|
||||
<xsd:attribute name="filename-pattern" type="xsd:string"/>
|
||||
|
||||
<xsd:attribute name="username" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="remote-directory" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="local-directory-path" type="xsd:string"/>
|
||||
<xsd:attribute name="host" type="xsd:string" use="required"/>
|
||||
|
||||
<xsd:attribute name="password" type="xsd:string"/>
|
||||
<xsd:attribute name="port" type="xsd:int" default="22"/>
|
||||
<xsd:attribute name="key-file" type="xsd:string"/>
|
||||
<xsd:attribute name="key-file-password" type="xsd:string"/>
|
||||
|
||||
|
||||
<xsd:attribute name="auto-create-directories" type="xsd:boolean"/>
|
||||
<xsd:attribute name="auto-delete-remote-files-on-sync" type="xsd:boolean"/>
|
||||
|
||||
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
|
||||
</xsd:schema>
|
||||
|
||||
Reference in New Issue
Block a user