INT-1631 added remote-file-generator attribute to te outbound adapter, final polishing 76.4% coverage

This commit is contained in:
Oleg Zhurakousky
2010-11-18 01:24:29 -05:00
parent e69342510f
commit 37b967cc14
9 changed files with 92 additions and 58 deletions

View File

@@ -44,11 +44,14 @@ public class SftpInboundChannelAdapterParser extends AbstractPollingInboundChann
String filter = element.getAttribute("filter");
boolean hasFileNamePattern = StringUtils.hasText(fileNamePattern);
boolean hasFilter = StringUtils.hasText(filter);
if (!(hasFileNamePattern ^ hasFilter)) {
throw new BeanDefinitionStoreException("exactly one of 'filename-pattern' or 'filter' " +
"is allowed on SFTP inbound adapter");
}
if (hasFileNamePattern | hasFilter){
if (!(hasFileNamePattern ^ hasFilter)) {
throw new BeanDefinitionStoreException("exactly one of 'filename-pattern' or 'filter' " +
"is allowed on SFTP inbound adapter");
}
}
BeanDefinitionBuilder sessionPollBuilder =
BeanDefinitionBuilder.genericBeanDefinition("org.springframework.integration.sftp.session.QueuedSftpSessionPool");
sessionPollBuilder.addConstructorArgReference(sessionFactoryName);

View File

@@ -21,6 +21,7 @@ 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.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractOutboundChannelAdapterParser;
@@ -39,10 +40,13 @@ public class SftpOutboundChannelAdapterParser extends AbstractOutboundChannelAda
BeanDefinitionBuilder sessionPollBuilder =
BeanDefinitionBuilder.genericBeanDefinition("org.springframework.integration.sftp.session.QueuedSftpSessionPool");
sessionPollBuilder.addConstructorArgReference(element.getAttribute("session-factory"));
String sessionPollName =
BeanDefinitionReaderUtils.registerWithGeneratedName(sessionPollBuilder.getBeanDefinition(), parserContext.getRegistry());
BeanDefinitionBuilder handlerBuilder =
BeanDefinitionBuilder.genericBeanDefinition("org.springframework.integration.sftp.outbound.SftpSendingMessageHandler");
handlerBuilder.addConstructorArgValue(sessionPollBuilder.getBeanDefinition());
handlerBuilder.addConstructorArgReference(sessionPollName);
IntegrationNamespaceUtils.setValueIfAttributeDefined(handlerBuilder, element, "charset");
String remoteDirectory = element.getAttribute("remote-directory");
@@ -63,7 +67,25 @@ public class SftpOutboundChannelAdapterParser extends AbstractOutboundChannelAda
expressionDef.getConstructorArgumentValues().addGenericArgumentValue(remoteDirectoryExpression);
}
handlerBuilder.addPropertyValue("remoteDirectoryExpression", expressionDef);
String remoteFileExpression = element.getAttribute("remote-file-expression");
String fileNameGenerator = element.getAttribute("filename-generator");
boolean hasRemoteFileExp = StringUtils.hasText(remoteFileExpression);
boolean hasFileNameGener = StringUtils.hasText(fileNameGenerator);
if (hasRemoteFileExp | hasFileNameGener){
if (!(hasRemoteFileExp ^ hasFileNameGener)) {
throw new BeanDefinitionStoreException("exactly one of 'remote-file-expression' or 'filename-generator' " +
"is allowed on SFTP outbound adapter");
}
if (StringUtils.hasText(remoteFileExpression)){
BeanDefinitionBuilder fNameGenerBuilder =
BeanDefinitionBuilder.genericBeanDefinition("org.springframework.integration.file.DefaultFileNameGenerator");
fNameGenerBuilder.addPropertyValue("expression", remoteFileExpression);
handlerBuilder.addPropertyValue("filenameGenerator", fNameGenerBuilder.getBeanDefinition());
}
}
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(handlerBuilder, element, "filename-generator");
return handlerBuilder.getBeanDefinition();
}

View File

@@ -23,12 +23,10 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.SystemUtils;
import org.springframework.context.SmartLifecycle;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.expression.Expression;
@@ -55,11 +53,9 @@ import com.jcraft.jsch.ChannelSftp;
* @author Oleg Zhurakousky
* @since 2.0
*/
public class SftpSendingMessageHandler extends AbstractMessageHandler implements SmartLifecycle{
public class SftpSendingMessageHandler extends AbstractMessageHandler{
private static final String TEMPORARY_FILE_SUFFIX = ".writing";
private final ReentrantLock lifecycleLock = new ReentrantLock();
private final SftpSessionPool sessionPool;
@@ -75,17 +71,11 @@ public class SftpSendingMessageHandler extends AbstractMessageHandler implements
private volatile String charset = Charset.defaultCharset().name();
private volatile boolean started;
private volatile boolean autoStartup = true;
public SftpSendingMessageHandler(SftpSessionPool sessionPool) {
Assert.notNull(sessionPool, "'sessionPool' must not be null");
this.sessionPool = sessionPool;
}
public void setTemporaryBufferFolder(Resource temporaryBufferFolder) {
this.temporaryBufferFolder = temporaryBufferFolder;
}
@@ -109,42 +99,6 @@ public class SftpSendingMessageHandler extends AbstractMessageHandler implements
new ExpressionEvaluatingMessageProcessor<String>(remoteDirectoryExpression, String.class);
}
}
// Lifecycle
public void start() {
sessionPool.start();
started = true;
}
public void stop() {
sessionPool.stop();
started = false;
}
public boolean isRunning() {
return started;
}
public int getPhase() {
return 0;
}
public boolean isAutoStartup() {
return autoStartup;
}
public void stop(Runnable callback) {
this.lifecycleLock.lock();
try {
this.stop();
callback.run();
}
finally {
this.lifecycleLock.unlock();
}
}
@Override
protected void handleMessageInternal(Message<?> message) throws Exception {
@@ -215,7 +169,7 @@ public class SftpSendingMessageHandler extends AbstractMessageHandler implements
}
InputStream fileInputStream = null;
try {
//session.start();
session.start();
ChannelSftp sftp = session.getChannel();
fileInputStream = new FileInputStream(file);
String baseOfRemotePath = "";

View File

@@ -55,6 +55,7 @@
</xsd:attribute>
<xsd:attribute name="remote-directory" type="xsd:string"/>
<xsd:attribute name="remote-directory-expression" type="xsd:string"/>
<xsd:attribute name="remote-file-expression" type="xsd:string"/>
<xsd:attribute name="charset" type="xsd:string"/>
</xsd:complexType>
</xsd:element>

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-sftp="http://www.springframework.org/schema/integration/sftp"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.0.xsd
http://www.springframework.org/schema/integration/sftp http://www.springframework.org/schema/integration/sftp/spring-integration-sftp-2.0.xsd">
<bean id="sftpSessionFactory" class="org.springframework.integration.sftp.session.SftpSessionFactory">
<property name="host" value="localhost"/>
<property name="knownHosts" value="local, foo.com, bar.foo"/>
<property name="privateKey" value="classpath:org/springframework/integration/sftp/config/sftpTest"/>
<property name="privateKeyPassphrase" value="ghj"/>
<property name="password" value="hello"/>
<property name="port" value="2222"/>
<property name="user" value="oleg"/>
</bean>
<int:channel id="inputChannel"/>
<int-sftp:outbound-channel-adapter id="sftpOutboundAdapterWithExpression"
session-factory="sftpSessionFactory"
channel="inputChannel"
charset="UTF-8"
filename-generator="fileNameGenerator"
remote-directory-expression="'foo' + '/' + 'bar'"
remote-file-expression="payload.getName() + '-foo'"/>
<bean id="fileNameGenerator" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="org.springframework.integration.file.FileNameGenerator"/>
</bean>
</beans>

View File

@@ -31,8 +31,8 @@
session-factory="sftpSessionFactory"
channel="inputChannel"
charset="UTF-8"
filename-generator="fileNameGenerator"
remote-directory-expression="'foo' + '/' + 'bar'"/>
remote-directory-expression="'foo' + '/' + 'bar'"
remote-file-expression="payload.getName() + '-foo'"/>
<int-sftp:outbound-channel-adapter
session-factory="sftpSessionFactory"

View File

@@ -28,6 +28,7 @@ import org.springframework.expression.Expression;
import org.springframework.expression.common.LiteralExpression;
import org.springframework.expression.spel.standard.SpelExpression;
import org.springframework.integration.endpoint.EventDrivenConsumer;
import org.springframework.integration.file.FileNameGenerator;
import org.springframework.integration.sftp.outbound.SftpSendingMessageHandler;
import org.springframework.integration.sftp.session.QueuedSftpSessionPool;
import org.springframework.integration.sftp.session.SftpSessionFactory;
@@ -62,7 +63,7 @@ public class OutboundChannelAdapaterParserTests {
}
@Test
public void testOutboundChannelAdapaterWithWithRemoteDirectoryExopression(){
public void testOutboundChannelAdapaterWithWithRemoteDirectoryAndFileExpression(){
ApplicationContext context =
new ClassPathXmlApplicationContext("OutboundChannelAdapaterParserTests-context.xml", this.getClass());
Object consumer = context.getBean("sftpOutboundAdapterWithExpression");
@@ -73,15 +74,24 @@ public class OutboundChannelAdapaterParserTests {
SpelExpression remoteDirectoryExpression = (SpelExpression) TestUtils.getPropertyValue(handler, "remoteDirectoryExpression");
assertNotNull(remoteDirectoryExpression);
assertEquals("'foo' + '/' + 'bar'", remoteDirectoryExpression.getExpressionString());
assertEquals(context.getBean("fileNameGenerator"), TestUtils.getPropertyValue(handler, "filenameGenerator"));
FileNameGenerator generator = (FileNameGenerator) TestUtils.getPropertyValue(handler, "filenameGenerator");
String fileNameGeneratorExpression = (String) TestUtils.getPropertyValue(generator, "expression");
assertEquals("payload.getName() + '-foo'", fileNameGeneratorExpression);
assertEquals("UTF-8", TestUtils.getPropertyValue(handler, "charset"));
assertNotNull(TestUtils.getPropertyValue(handler, "temporaryBufferFolder"));
assertNotNull(TestUtils.getPropertyValue(handler, "temporaryBufferFolderFile"));
}
@Test(expected=BeanDefinitionStoreException.class)
public void testFailWithRemoteDirAndExpression(){
new ClassPathXmlApplicationContext("OutboundChannelAdapaterParserTests-context-fail.xml", this.getClass());
}
@Test(expected=BeanDefinitionStoreException.class)
public void testFailWithFileExpressionAndFileGenerator(){
new ClassPathXmlApplicationContext("OutboundChannelAdapaterParserTests-context-fail-fileFileGen.xml", this.getClass());
}
}

View File

@@ -24,6 +24,7 @@
session-factory="sftpSessionFactory"
channel="inputChannel"
charset="UTF-8"
remote-file-expression="payload.getName() + '_foo'"
remote-directory="/Users/ozhurakousky/workspace-sts-2.3.3.M2/si/spring-integration/spring-integration-sftp/remote-test-dir"/>
<!-- <int-sftp:outbound-channel-adapter id="sftpOutboundAdapterWithExpression"-->

View File

@@ -0,0 +1,8 @@
log4j.rootCategory=WARN, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %t %c{2}:%L - %m%n
log4j.category.org.springframework=WARN
log4j.category.org.springframework.integration.sftp=TRACE