INT-3203 Introduce RemoteFileTemplate

Begin by refactoring `FileTransferringMessageHandler` to use
a `send` operation on RemoteFileTemplate.

Effectively transfer all properties from the adapter to the
template.

This will allow reuse of the send logic from the adapter in
the outbound gateway for `put` and `mput`.

JIRA: https://jira.springsource.org/browse/INT-3203
This commit is contained in:
Gary Russell
2013-11-11 17:53:50 -05:00
parent 72dd39bccf
commit d662e7ee42
8 changed files with 395 additions and 247 deletions

View File

@@ -0,0 +1,29 @@
/*
* 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.file.remote;
import org.springframework.integration.Message;
/**
* @author Gary Russell
* @since 3.0
*
*/
public interface RemoteFileOperations {
public abstract void send(Message<?> message) throws Exception;
}

View File

@@ -0,0 +1,311 @@
/*
* 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.file.remote;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.expression.Expression;
import org.springframework.integration.Message;
import org.springframework.integration.MessageDeliveryException;
import org.springframework.integration.MessagingException;
import org.springframework.integration.file.DefaultFileNameGenerator;
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.ExpressionEvaluatingMessageProcessor;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* @author Iwein Fuld
* @author Mark Fisher
* @author Josh Long
* @author Oleg Zhurakousky
* @author David Turanski
* @author Gary Russell
* @since 3.0
*
*/
public class RemoteFileTemplate<F> implements RemoteFileOperations, InitializingBean, BeanFactoryAware {
private final Log logger = LogFactory.getLog(this.getClass());
private final SessionFactory<F> sessionFactory;
private volatile String temporaryFileSuffix =".writing";
private volatile boolean autoCreateDirectory = false;
private volatile boolean useTemporaryFileName = true;
private volatile ExpressionEvaluatingMessageProcessor<String> directoryExpressionProcessor;
private volatile ExpressionEvaluatingMessageProcessor<String> temporaryDirectoryExpressionProcessor;
private volatile FileNameGenerator fileNameGenerator = new DefaultFileNameGenerator();
private volatile boolean fileNameGeneratorSet;
private volatile String charset = "UTF-8";
private volatile String remoteFileSeparator = "/";
private volatile boolean hasExplicitlySetSuffix;
private volatile BeanFactory beanFactory;
public RemoteFileTemplate(SessionFactory<F> sessionFactory) {
Assert.notNull(sessionFactory, "sessionFactory must not be null");
this.sessionFactory = sessionFactory;
}
public void setAutoCreateDirectory(boolean autoCreateDirectory) {
this.autoCreateDirectory = autoCreateDirectory;
}
public void setRemoteFileSeparator(String remoteFileSeparator) {
Assert.notNull(remoteFileSeparator, "'remoteFileSeparator' must not be null");
this.remoteFileSeparator = remoteFileSeparator;
}
public void setRemoteDirectoryExpression(Expression remoteDirectoryExpression) {
Assert.notNull(remoteDirectoryExpression, "remoteDirectoryExpression must not be null");
this.directoryExpressionProcessor = new ExpressionEvaluatingMessageProcessor<String>(remoteDirectoryExpression, String.class);
}
public void setTemporaryRemoteDirectoryExpression(Expression temporaryRemoteDirectoryExpression) {
Assert.notNull(temporaryRemoteDirectoryExpression, "temporaryRemoteDirectoryExpression must not be null");
this.temporaryDirectoryExpressionProcessor = new ExpressionEvaluatingMessageProcessor<String>(temporaryRemoteDirectoryExpression, String.class);
}
public String getTemporaryFileSuffix() {
return this.temporaryFileSuffix;
}
public boolean isUseTemporaryFileName() {
return useTemporaryFileName;
}
public void setUseTemporaryFileName(boolean useTemporaryFileName) {
this.useTemporaryFileName = useTemporaryFileName;
}
public void setFileNameGenerator(FileNameGenerator fileNameGenerator) {
this.fileNameGenerator = (fileNameGenerator != null) ? fileNameGenerator : new DefaultFileNameGenerator();
this.fileNameGeneratorSet = fileNameGenerator != null;
}
public void setCharset(String charset) {
this.charset = charset;
}
public void setTemporaryFileSuffix(String temporaryFileSuffix) {
Assert.notNull(temporaryFileSuffix, "'temporaryFileSuffix' must not be null");
this.hasExplicitlySetSuffix = true;
this.temporaryFileSuffix = temporaryFileSuffix;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
@Override
public void afterPropertiesSet() throws Exception {
Assert.notNull(this.directoryExpressionProcessor, "remoteDirectoryExpression is required");
BeanFactory beanFactory = this.beanFactory;
if (beanFactory != null) {
this.directoryExpressionProcessor.setBeanFactory(beanFactory);
if (this.temporaryDirectoryExpressionProcessor != null) {
this.temporaryDirectoryExpressionProcessor.setBeanFactory(beanFactory);
}
if (!this.fileNameGeneratorSet && this.fileNameGenerator instanceof BeanFactoryAware) {
((BeanFactoryAware) this.fileNameGenerator).setBeanFactory(beanFactory);
}
}
if (this.autoCreateDirectory){
Assert.hasText(this.remoteFileSeparator, "'remoteFileSeparator' must not be empty when 'autoCreateDirectory' is set to 'true'");
}
if (hasExplicitlySetSuffix && !useTemporaryFileName){
this.logger.warn("Since 'use-temporary-file-name' is set to 'false' the value of 'temporary-file-suffix' has no effect");
}
}
@Override
public void send(Message<?> message) throws Exception {
StreamHolder inputStreamHolder = this.payloadToInputStream(message);
if (inputStreamHolder != null) {
Session<F> session = this.sessionFactory.getSession();
String fileName = inputStreamHolder.getName();
try {
String remoteDirectory = this.directoryExpressionProcessor.processMessage(message);
String temporaryRemoteDirectory = remoteDirectory;
if (this.temporaryDirectoryExpressionProcessor != null){
temporaryRemoteDirectory = this.temporaryDirectoryExpressionProcessor.processMessage(message);
}
fileName = this.fileNameGenerator.generateFileName(message);
this.sendFileToRemoteDirectory(inputStreamHolder.getStream(), temporaryRemoteDirectory, remoteDirectory, fileName, session);
}
catch (FileNotFoundException e) {
throw new MessageDeliveryException(message,
"File [" + inputStreamHolder.getName() + "] not found in local working directory; it was moved or deleted unexpectedly.", e);
}
catch (IOException e) {
throw new MessageDeliveryException(message,
"Failed to transfer file [" + inputStreamHolder.getName() + " -> " + fileName + "] from local directory to remote directory.", e);
}
catch (Exception e) {
throw new MessageDeliveryException(message,
"Error handling message for file [" + inputStreamHolder.getName() + " -> " + fileName + "]", e);
}
finally {
if (session != null) {
session.close();
}
}
}
else {
// A null holder means a File payload that does not exist.
if (logger.isWarnEnabled()) {
logger.warn("File " + message.getPayload() + " does not exist");
}
}
}
private StreamHolder payloadToInputStream(Message<?> message) throws MessageDeliveryException {
try {
Object payload = message.getPayload();
InputStream dataInputStream = null;
String name = null;
if (payload instanceof File) {
File inputFile = (File) payload;
if (inputFile.exists()) {
dataInputStream = new BufferedInputStream(new FileInputStream(inputFile));
name = inputFile.getAbsolutePath();
}
}
else if (payload instanceof byte[] || payload instanceof String) {
byte[] bytes = null;
if (payload instanceof String) {
bytes = ((String) payload).getBytes(this.charset);
name = "String payload";
}
else {
bytes = (byte[]) payload;
name = "byte[] payload";
}
dataInputStream = new ByteArrayInputStream(bytes);
}
else {
throw new IllegalArgumentException("Unsupported payload type. The only supported payloads are " +
"java.io.File, java.lang.String, and byte[]");
}
if (dataInputStream == null) {
return null;
}
else {
return new StreamHolder(dataInputStream, name);
}
}
catch (Exception e) {
throw new MessageDeliveryException(message, "Failed to create sendable file.", e);
}
}
private void sendFileToRemoteDirectory(InputStream inputStream, String temporaryRemoteDirectory,
String remoteDirectory, String fileName, Session<F> session) throws FileNotFoundException, IOException {
remoteDirectory = this.normalizeDirectoryPath(remoteDirectory);
temporaryRemoteDirectory = this.normalizeDirectoryPath(temporaryRemoteDirectory);
String remoteFilePath = remoteDirectory + fileName;
String tempRemoteFilePath = temporaryRemoteDirectory + fileName;
// write remote file first with temporary file extension if enabled
String tempFilePath = tempRemoteFilePath + (useTemporaryFileName ? this.temporaryFileSuffix : "");
if (this.autoCreateDirectory) {
try {
RemoteFileUtils.makeDirectories(remoteDirectory, session, this.remoteFileSeparator, this.logger);
}
catch (IllegalStateException e) {
// Revert to old FTP behavior if recursive mkdir fails, for backwards compatibility
session.mkdir(remoteDirectory);
}
}
try {
session.write(inputStream, tempFilePath);
// then rename it to its final name if necessary
if (useTemporaryFileName){
session.rename(tempFilePath, remoteFilePath);
}
}
catch (Exception e) {
throw new MessagingException("Failed to write to '" + tempFilePath + "' while uploading the file", e);
}
finally {
inputStream.close();
}
}
private String normalizeDirectoryPath(String directoryPath){
if (!StringUtils.hasText(directoryPath)) {
directoryPath = "";
}
else if (!directoryPath.endsWith(this.remoteFileSeparator)) {
directoryPath += this.remoteFileSeparator;
}
return directoryPath;
}
private class StreamHolder {
private final InputStream stream;
private final String name;
private StreamHolder(InputStream stream, String name) {
this.stream = stream;
this.name = name;
}
public InputStream getStream() {
return stream;
}
public String getName() {
return name;
}
}
}

View File

@@ -16,29 +16,15 @@
package org.springframework.integration.file.remote.handler;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.expression.Expression;
import org.springframework.integration.Message;
import org.springframework.integration.MessageDeliveryException;
import org.springframework.integration.MessagingException;
import org.springframework.integration.file.DefaultFileNameGenerator;
import org.springframework.integration.file.FileNameGenerator;
import org.springframework.integration.file.remote.RemoteFileUtils;
import org.springframework.integration.file.remote.session.Session;
import org.springframework.integration.file.remote.RemoteFileTemplate;
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.StringUtils;
/**
* A {@link org.springframework.integration.core.MessageHandler} implementation that transfers files to a remote server.
@@ -53,56 +39,32 @@ import org.springframework.util.StringUtils;
*/
public class FileTransferringMessageHandler<F> extends AbstractMessageHandler {
private volatile String temporaryFileSuffix =".writing";
private final SessionFactory<F> sessionFactory;
private volatile boolean autoCreateDirectory = false;
private volatile boolean useTemporaryFileName = true;
private volatile ExpressionEvaluatingMessageProcessor<String> directoryExpressionProcessor;
private volatile ExpressionEvaluatingMessageProcessor<String> temporaryDirectoryExpressionProcessor;
private volatile FileNameGenerator fileNameGenerator = new DefaultFileNameGenerator();
private volatile boolean fileNameGeneratorSet;
private volatile String charset = "UTF-8";
private volatile String remoteFileSeparator = "/";
private volatile boolean hasExplicitlySetSuffix;
private final RemoteFileTemplate<F> remoteFileTemplate;
public FileTransferringMessageHandler(SessionFactory<F> sessionFactory) {
Assert.notNull(sessionFactory, "sessionFactory must not be null");
this.sessionFactory = sessionFactory;
this.remoteFileTemplate = new RemoteFileTemplate<F>(sessionFactory);
}
public void setAutoCreateDirectory(boolean autoCreateDirectory) {
this.autoCreateDirectory = autoCreateDirectory;
this.remoteFileTemplate.setAutoCreateDirectory(autoCreateDirectory);
}
public void setRemoteFileSeparator(String remoteFileSeparator) {
Assert.notNull(remoteFileSeparator, "'remoteFileSeparator' must not be null");
this.remoteFileSeparator = remoteFileSeparator;
this.remoteFileTemplate.setRemoteFileSeparator(remoteFileSeparator);
}
public void setRemoteDirectoryExpression(Expression remoteDirectoryExpression) {
Assert.notNull(remoteDirectoryExpression, "remoteDirectoryExpression must not be null");
this.directoryExpressionProcessor = new ExpressionEvaluatingMessageProcessor<String>(remoteDirectoryExpression, String.class);
this.remoteFileTemplate.setRemoteDirectoryExpression(remoteDirectoryExpression);
}
public void setTemporaryRemoteDirectoryExpression(Expression temporaryRemoteDirectoryExpression) {
Assert.notNull(temporaryRemoteDirectoryExpression, "temporaryRemoteDirectoryExpression must not be null");
this.temporaryDirectoryExpressionProcessor = new ExpressionEvaluatingMessageProcessor<String>(temporaryRemoteDirectoryExpression, String.class);
this.remoteFileTemplate.setTemporaryRemoteDirectoryExpression(temporaryRemoteDirectoryExpression);
}
protected String getTemporaryFileSuffix() {
return this.temporaryFileSuffix;
return this.remoteFileTemplate.getTemporaryFileSuffix();
}
/**
@@ -113,198 +75,36 @@ public class FileTransferringMessageHandler<F> extends AbstractMessageHandler {
}
protected boolean isUseTemporaryFileName() {
return useTemporaryFileName;
return this.remoteFileTemplate.isUseTemporaryFileName();
}
public void setUseTemporaryFileName(boolean useTemporaryFileName) {
this.useTemporaryFileName = useTemporaryFileName;
this.remoteFileTemplate.setUseTemporaryFileName(useTemporaryFileName);
}
public void setFileNameGenerator(FileNameGenerator fileNameGenerator) {
this.fileNameGenerator = (fileNameGenerator != null) ? fileNameGenerator : new DefaultFileNameGenerator();
this.fileNameGeneratorSet = fileNameGenerator != null;
this.remoteFileTemplate.setFileNameGenerator(fileNameGenerator);
}
public void setCharset(String charset) {
this.charset = charset;
this.remoteFileTemplate.setCharset(charset);
}
public void setTemporaryFileSuffix(String temporaryFileSuffix) {
Assert.notNull(temporaryFileSuffix, "'temporaryFileSuffix' must not be null");
this.hasExplicitlySetSuffix = true;
this.temporaryFileSuffix = temporaryFileSuffix;
this.remoteFileTemplate.setTemporaryFileSuffix(temporaryFileSuffix);
}
@Override
protected void onInit() throws Exception {
Assert.notNull(this.directoryExpressionProcessor, "remoteDirectoryExpression is required");
BeanFactory beanFactory = this.getBeanFactory();
if (beanFactory != null) {
this.directoryExpressionProcessor.setBeanFactory(beanFactory);
if (this.temporaryDirectoryExpressionProcessor != null) {
this.temporaryDirectoryExpressionProcessor.setBeanFactory(beanFactory);
}
if (!this.fileNameGeneratorSet && this.fileNameGenerator instanceof BeanFactoryAware) {
((BeanFactoryAware) this.fileNameGenerator).setBeanFactory(beanFactory);
}
}
if (this.autoCreateDirectory){
Assert.hasText(this.remoteFileSeparator, "'remoteFileSeparator' must not be empty when 'autoCreateDirectory' is set to 'true'");
}
if (hasExplicitlySetSuffix && !useTemporaryFileName){
this.logger.warn("Since 'use-temporary-file-name' is set to 'false' the value of 'temporary-file-suffix' has no effect");
}
this.remoteFileTemplate.setBeanFactory(this.getBeanFactory());
this.remoteFileTemplate.afterPropertiesSet();
}
@Override
protected void handleMessageInternal(Message<?> message) throws Exception {
StreamHolder inputStreamHolder = this.payloadToInputStream(message);
if (inputStreamHolder != null) {
Session<F> session = this.sessionFactory.getSession();
String fileName = inputStreamHolder.getName();
try {
String remoteDirectory = this.directoryExpressionProcessor.processMessage(message);
String temporaryRemoteDirectory = remoteDirectory;
if (this.temporaryDirectoryExpressionProcessor != null){
temporaryRemoteDirectory = this.temporaryDirectoryExpressionProcessor.processMessage(message);
}
fileName = this.fileNameGenerator.generateFileName(message);
this.sendFileToRemoteDirectory(inputStreamHolder.getStream(), temporaryRemoteDirectory, remoteDirectory, fileName, session);
}
catch (FileNotFoundException e) {
throw new MessageDeliveryException(message,
"File [" + inputStreamHolder.getName() + "] not found in local working directory; it was moved or deleted unexpectedly.", e);
}
catch (IOException e) {
throw new MessageDeliveryException(message,
"Failed to transfer file [" + inputStreamHolder.getName() + " -> " + fileName + "] from local directory to remote directory.", e);
}
catch (Exception e) {
throw new MessageDeliveryException(message,
"Error handling message for file [" + inputStreamHolder.getName() + " -> " + fileName + "]", e);
}
finally {
if (session != null) {
session.close();
}
}
}
else {
// A null holder means a File payload that does not exist.
if (logger.isWarnEnabled()) {
logger.warn("File " + message.getPayload() + " does not exist");
}
}
}
private StreamHolder payloadToInputStream(Message<?> message) throws MessageDeliveryException {
try {
Object payload = message.getPayload();
InputStream dataInputStream = null;
String name = null;
if (payload instanceof File) {
File inputFile = (File) payload;
if (inputFile.exists()) {
dataInputStream = new BufferedInputStream(new FileInputStream(inputFile));
name = inputFile.getAbsolutePath();
}
}
else if (payload instanceof byte[] || payload instanceof String) {
byte[] bytes = null;
if (payload instanceof String) {
bytes = ((String) payload).getBytes(this.charset);
name = "String payload";
}
else {
bytes = (byte[]) payload;
name = "byte[] payload";
}
dataInputStream = new ByteArrayInputStream(bytes);
}
else {
throw new IllegalArgumentException("Unsupported payload type. The only supported payloads are " +
"java.io.File, java.lang.String, and byte[]");
}
if (dataInputStream == null) {
return null;
}
else {
return new StreamHolder(dataInputStream, name);
}
}
catch (Exception e) {
throw new MessageDeliveryException(message, "Failed to create sendable file.", e);
}
}
private void sendFileToRemoteDirectory(InputStream inputStream, String temporaryRemoteDirectory,
String remoteDirectory, String fileName, Session<F> session) throws FileNotFoundException, IOException {
remoteDirectory = this.normalizeDirectoryPath(remoteDirectory);
temporaryRemoteDirectory = this.normalizeDirectoryPath(temporaryRemoteDirectory);
String remoteFilePath = remoteDirectory + fileName;
String tempRemoteFilePath = temporaryRemoteDirectory + fileName;
// write remote file first with temporary file extension if enabled
String tempFilePath = tempRemoteFilePath + (useTemporaryFileName ? this.temporaryFileSuffix : "");
if (this.autoCreateDirectory) {
try {
RemoteFileUtils.makeDirectories(remoteDirectory, session, this.remoteFileSeparator, this.logger);
}
catch (IllegalStateException e) {
// Revert to old FTP behavior if recursive mkdir fails, for backwards compatibility
session.mkdir(remoteDirectory);
}
}
try {
session.write(inputStream, tempFilePath);
// then rename it to its final name if necessary
if (useTemporaryFileName){
session.rename(tempFilePath, remoteFilePath);
}
}
catch (Exception e) {
throw new MessagingException("Failed to write to '" + tempFilePath + "' while uploading the file", e);
}
finally {
inputStream.close();
}
}
private String normalizeDirectoryPath(String directoryPath){
if (!StringUtils.hasText(directoryPath)) {
directoryPath = "";
}
else if (!directoryPath.endsWith(this.remoteFileSeparator)) {
directoryPath += this.remoteFileSeparator;
}
return directoryPath;
}
private class StreamHolder {
private final InputStream stream;
private final String name;
private StreamHolder(InputStream stream, String name) {
this.stream = stream;
this.name = name;
}
public InputStream getStream() {
return stream;
}
public String getName() {
return name;
}
this.remoteFileTemplate.send(message);
}
}

View File

@@ -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));
}

View File

@@ -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"));
}

View File

@@ -56,6 +56,7 @@ import org.springframework.integration.MessageChannel;
import org.springframework.integration.core.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.integration.message.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]);

View File

@@ -44,13 +44,13 @@ public class OutboundChannelAdapterParserCachingTests {
@Test
public void cachingAdapter() {
Object sessionFactory = TestUtils.getPropertyValue(cachingAdapter, "handler.sessionFactory");
Object sessionFactory = TestUtils.getPropertyValue(cachingAdapter, "handler.remoteFileTemplate.sessionFactory");
assertEquals(CachingSessionFactory.class, sessionFactory.getClass());
}
@Test
public void nonCachingAdapter() {
Object sessionFactory = TestUtils.getPropertyValue(nonCachingAdapter, "handler.sessionFactory");
Object sessionFactory = TestUtils.getPropertyValue(nonCachingAdapter, "handler.remoteFileTemplate.sessionFactory");
assertEquals(DefaultSftpSessionFactory.class, sessionFactory.getClass());
}

View File

@@ -66,17 +66,17 @@ public class OutboundChannelAdapterParserTests {
assertEquals(channel, TestUtils.getPropertyValue(consumer, "inputChannel"));
assertEquals("sftpOutboundAdapter", ((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(".", remoteFileSeparator);
assertEquals(".bar", TestUtils.getPropertyValue(handler, "temporaryFileSuffix", String.class));
Expression remoteDirectoryExpression = (Expression) TestUtils.getPropertyValue(handler, "directoryExpressionProcessor.expression");
assertEquals(".bar", TestUtils.getPropertyValue(handler, "remoteFileTemplate.temporaryFileSuffix", String.class));
Expression remoteDirectoryExpression = (Expression) TestUtils.getPropertyValue(handler, "remoteFileTemplate.directoryExpressionProcessor.expression");
assertNotNull(remoteDirectoryExpression);
assertTrue(remoteDirectoryExpression instanceof LiteralExpression);
assertNotNull(TestUtils.getPropertyValue(handler, "temporaryDirectoryExpressionProcessor"));
assertEquals(context.getBean("fileNameGenerator"), TestUtils.getPropertyValue(handler, "fileNameGenerator"));
assertEquals("UTF-8", TestUtils.getPropertyValue(handler, "charset"));
CachingSessionFactory<?> sessionFactory = TestUtils.getPropertyValue(handler, "sessionFactory", CachingSessionFactory.class);
assertNotNull(TestUtils.getPropertyValue(handler, "remoteFileTemplate.temporaryDirectoryExpressionProcessor"));
assertEquals(context.getBean("fileNameGenerator"), TestUtils.getPropertyValue(handler, "remoteFileTemplate.fileNameGenerator"));
assertEquals("UTF-8", TestUtils.getPropertyValue(handler, "remoteFileTemplate.charset"));
CachingSessionFactory<?> sessionFactory = TestUtils.getPropertyValue(handler, "remoteFileTemplate.sessionFactory", CachingSessionFactory.class);
DefaultSftpSessionFactory clientFactory = TestUtils.getPropertyValue(sessionFactory, "sessionFactory", DefaultSftpSessionFactory.class);
assertEquals("localhost", TestUtils.getPropertyValue(clientFactory, "host"));
assertEquals(2222, TestUtils.getPropertyValue(clientFactory, "port"));
@@ -101,14 +101,14 @@ public class OutboundChannelAdapterParserTests {
assertEquals(context.getBean("inputChannel"), TestUtils.getPropertyValue(consumer, "inputChannel"));
assertEquals("sftpOutboundAdapterWithExpression", ((EventDrivenConsumer)consumer).getComponentName());
FileTransferringMessageHandler<?> handler = TestUtils.getPropertyValue(consumer, "handler", FileTransferringMessageHandler.class);
SpelExpression remoteDirectoryExpression = (SpelExpression) TestUtils.getPropertyValue(handler, "directoryExpressionProcessor.expression");
SpelExpression remoteDirectoryExpression = (SpelExpression) TestUtils.getPropertyValue(handler, "remoteFileTemplate.directoryExpressionProcessor.expression");
assertNotNull(remoteDirectoryExpression);
assertEquals("'foo' + '/' + 'bar'", remoteDirectoryExpression.getExpressionString());
FileNameGenerator generator = (FileNameGenerator) TestUtils.getPropertyValue(handler, "fileNameGenerator");
FileNameGenerator generator = (FileNameGenerator) TestUtils.getPropertyValue(handler, "remoteFileTemplate.fileNameGenerator");
String fileNameGeneratorExpression = (String) TestUtils.getPropertyValue(generator, "expression");
assertEquals("payload.getName() + '-foo'", fileNameGeneratorExpression);
assertEquals("UTF-8", TestUtils.getPropertyValue(handler, "charset"));
assertNull(TestUtils.getPropertyValue(handler, "temporaryDirectoryExpressionProcessor"));
assertEquals("UTF-8", TestUtils.getPropertyValue(handler, "remoteFileTemplate.charset"));
assertNull(TestUtils.getPropertyValue(handler, "remoteFileTemplate.temporaryDirectoryExpressionProcessor"));
}
@@ -118,7 +118,7 @@ public class OutboundChannelAdapterParserTests {
new ClassPathXmlApplicationContext("OutboundChannelAdapterParserTests-context.xml", this.getClass());
Object consumer = context.getBean("sftpOutboundAdapterWithNoTemporaryFileName");
FileTransferringMessageHandler<?> handler = TestUtils.getPropertyValue(consumer, "handler", FileTransferringMessageHandler.class);
assertFalse((Boolean)TestUtils.getPropertyValue(handler,"useTemporaryFileName"));
assertFalse((Boolean)TestUtils.getPropertyValue(handler,"remoteFileTemplate.useTemporaryFileName"));
}
@Test