Merge SMB Adapter
This commit is contained in:
26
.gitignore
vendored
26
.gitignore
vendored
@@ -1,6 +1,20 @@
|
||||
*.class
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
*.msg
|
||||
*/src/main/java/META-INF
|
||||
.classpath
|
||||
.DS_Store
|
||||
.gradle
|
||||
.idea
|
||||
.project
|
||||
.settings
|
||||
bin
|
||||
build
|
||||
build.log
|
||||
derby.log
|
||||
lib
|
||||
logs
|
||||
nohup.out
|
||||
out
|
||||
target
|
||||
8
spring-integration-smb/log4j.properties
Normal file
8
spring-integration-smb/log4j.properties
Normal 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=DEBUG
|
||||
253
spring-integration-smb/pom.xml
Normal file
253
spring-integration-smb/pom.xml
Normal file
@@ -0,0 +1,253 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-smb</artifactId>
|
||||
<version>2.1.1.BUILD-SNAPSHOT</version>
|
||||
<name>Spring Integration SMB Support</name>
|
||||
|
||||
<parent>
|
||||
<!--
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration</artifactId>
|
||||
<version>2.1.1.BUILD-SNAPSHOT</version>
|
||||
-->
|
||||
|
||||
<groupId>baag</groupId>
|
||||
<artifactId>baag-maven-root</artifactId>
|
||||
<version>1.4-SNAPSHOT</version>
|
||||
<!-- The relative path of the parent pom.xml file within the check out.
|
||||
The default value is ../pom.xml which points to spring-integration
|
||||
parent POM. While we maintain the module locally at Baader,
|
||||
we must point it to parent baag-maven-root (for Nexus, Jenkins etc.) -->
|
||||
<relativePath>../../Skripte/Maven/Wurzel/</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<spring.core.version>3.0.5.RELEASE</spring.core.version>
|
||||
<spring.integration.version>2.1.1.BUILD-SNAPSHOT</spring.integration.version>
|
||||
</properties>
|
||||
|
||||
<issueManagement/>
|
||||
|
||||
<scm>
|
||||
<connection>scm:svn:https://eiche.baag/svn/3rdparty/spring-integration-smb/trunk/</connection>
|
||||
<developerConnection>scm:svn:https://eiche.baag/svn/3rdparty/spring-integration-smb/trunk/</developerConnection>
|
||||
<url>https://eiche.baag/svn/3rdparty/spring-integration-smb/trunk/</url>
|
||||
</scm>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>msp</id>
|
||||
<name>Markus Spann</name>
|
||||
<email>markus.spann@baaderbank.de</email>
|
||||
<timezone>+1</timezone>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<build>
|
||||
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/java</directory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>**/*.java</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<testResources>
|
||||
<testResource>
|
||||
<directory>src/test/java</directory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>**/*.java</exclude>
|
||||
</excludes>
|
||||
</testResource>
|
||||
|
||||
<testResource>
|
||||
<directory>src/test/resources</directory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
</testResource>
|
||||
</testResources>
|
||||
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<useSystemClassLoader>false</useSystemClassLoader>
|
||||
<forkMode>never</forkMode>
|
||||
<includes>
|
||||
<include>**/*Tests.java</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>**/*Abstract*.java</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<!-- http://maven.apache.org/plugins/maven-eclipse-plugin/ -->
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-eclipse-plugin</artifactId>
|
||||
<configuration>
|
||||
|
||||
<additionalBuildcommands combine.children="append">
|
||||
<buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
|
||||
</additionalBuildcommands>
|
||||
<additionalProjectnatures combine.children="append">
|
||||
<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
|
||||
</additionalProjectnatures>
|
||||
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<!-- http://code.google.com/p/maven-license-plugin/ -->
|
||||
<groupId>com.mycila.maven-license-plugin</groupId>
|
||||
<artifactId>maven-license-plugin</artifactId>
|
||||
<version>1.10.b1</version>
|
||||
<configuration>
|
||||
<basedir>${basedir}</basedir> <!-- base directory for the search -->
|
||||
<header>${basedir}/src/main/resources/license_header.txt</header>
|
||||
<aggregate>true</aggregate> <!-- check headers for all modules of multi-modules projects. -->
|
||||
|
||||
<includes>
|
||||
<include>src/**/*.java</include>
|
||||
</includes>
|
||||
<useDefaultExcludes>true</useDefaultExcludes>
|
||||
<properties>
|
||||
<year>${project.inceptionYear}</year>
|
||||
</properties>
|
||||
<encoding>UTF-8</encoding>
|
||||
<strictCheck>true</strictCheck>
|
||||
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.samba.jcifs</groupId>
|
||||
<artifactId>jcifs</artifactId>
|
||||
<version>1.3.17</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>${spring.core.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${spring.core.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context-support</artifactId>
|
||||
<version>${spring.core.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<version>${spring.core.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-expression</artifactId>
|
||||
<version>${spring.core.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-core</artifactId>
|
||||
<version>${spring.integration.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-file</artifactId>
|
||||
<version>${spring.integration.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-test</artifactId>
|
||||
<version>${spring.integration.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cglib</groupId>
|
||||
<artifactId>cglib-nodep</artifactId>
|
||||
<version>2.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>1.2.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.activation</groupId>
|
||||
<artifactId>activation</artifactId>
|
||||
<version>1.1.1</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>${spring.core.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<!-- Hamcrest - library of matchers for building test expressions -->
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-all</artifactId>
|
||||
<version>1.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<version>1.8.4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit-dep</artifactId>
|
||||
<version>4.8.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Copyright 2002-2012 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.smb.config;
|
||||
|
||||
import org.springframework.integration.file.config.AbstractRemoteFileInboundChannelAdapterParser;
|
||||
|
||||
/**
|
||||
* Parser for the SMB 'inbound-channel-adapter' element.
|
||||
*
|
||||
* @author Markus Spann
|
||||
* @since 2.1.1
|
||||
*/
|
||||
public class SmbInboundChannelAdapterParser extends AbstractRemoteFileInboundChannelAdapterParser {
|
||||
|
||||
private static final String BASE_PACKAGE = "org.springframework.integration.smb";
|
||||
|
||||
|
||||
@Override
|
||||
protected String getMessageSourceClassname() {
|
||||
return BASE_PACKAGE + ".inbound.SmbInboundFileSynchronizingMessageSource";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getInboundFileSynchronizerClassname() {
|
||||
return BASE_PACKAGE + ".inbound.SmbInboundFileSynchronizer";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSimplePatternFileListFilterClassname() {
|
||||
return BASE_PACKAGE + ".filters.SmbSimplePatternFileListFilter";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getRegexPatternFileListFilterClassname() {
|
||||
return BASE_PACKAGE + ".filters.SmbRegexPatternFileListFilter";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Copyright 2002-2012 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.smb.config;
|
||||
|
||||
import org.springframework.integration.config.xml.AbstractIntegrationNamespaceHandler;
|
||||
import org.springframework.integration.file.config.RemoteFileOutboundChannelAdapterParser;
|
||||
|
||||
/**
|
||||
* Provides namespace support for using SMB.
|
||||
*
|
||||
* @author Markus Spann
|
||||
* @since 2.1.1
|
||||
*/
|
||||
public class SmbNamespaceHandler extends AbstractIntegrationNamespaceHandler {
|
||||
|
||||
public void init() {
|
||||
registerBeanDefinitionParser("inbound-channel-adapter", new SmbInboundChannelAdapterParser());
|
||||
registerBeanDefinitionParser("outbound-channel-adapter", new RemoteFileOutboundChannelAdapterParser()); // TODO need implementation for SMB?
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Copyright 2002-2012 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.smb.filters;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import jcifs.smb.SmbFile;
|
||||
|
||||
import org.springframework.integration.file.filters.AbstractRegexPatternFileListFilter;
|
||||
|
||||
/**
|
||||
* Implementation of {@link AbstractRegexPatternFileListFilter} for SMB.
|
||||
*
|
||||
* @author Markus Spann
|
||||
* @since 2.1.1
|
||||
*/
|
||||
public class SmbRegexPatternFileListFilter extends AbstractRegexPatternFileListFilter<SmbFile> {
|
||||
|
||||
private final String toString;
|
||||
|
||||
public SmbRegexPatternFileListFilter(String _pattern) {
|
||||
this(Pattern.compile(_pattern));
|
||||
}
|
||||
|
||||
public SmbRegexPatternFileListFilter(Pattern _pattern) {
|
||||
super(_pattern);
|
||||
toString = getClass().getName() + "[pattern='" + _pattern + "']";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the specified SMB file's name.
|
||||
* @param _file SMB file object
|
||||
* @return file name
|
||||
* @see org.springframework.integration.file.filters.AbstractRegexPatternFileListFilter#getFilename(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
protected String getFilename(SmbFile _file) {
|
||||
return (_file != null) ? _file.getName() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Copyright 2002-2012 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.smb.filters;
|
||||
|
||||
import jcifs.smb.SmbFile;
|
||||
|
||||
import org.springframework.integration.file.filters.AbstractSimplePatternFileListFilter;
|
||||
|
||||
/**
|
||||
* Implementation of {@link AbstractSimplePatternFileListFilter} for SMB.
|
||||
*
|
||||
* @author Markus Spann
|
||||
*/
|
||||
public class SmbSimplePatternFileListFilter extends AbstractSimplePatternFileListFilter<SmbFile> {
|
||||
|
||||
private final String toString;
|
||||
|
||||
public SmbSimplePatternFileListFilter(String _pathPattern) {
|
||||
super(_pathPattern);
|
||||
toString = getClass().getName() + "[pattern='" + _pathPattern + "']";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the specified SMB file's name.
|
||||
* @param _file SMB file object
|
||||
* @return file name
|
||||
* @see org.springframework.integration.file.filters.AbstractSimplePatternFileListFilter#getFilename(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
protected String getFilename(SmbFile _file) {
|
||||
return (_file != null) ? _file.getName() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Copyright 2002-2012 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.smb.inbound;
|
||||
|
||||
import jcifs.smb.SmbFile;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.integration.file.remote.session.SessionFactory;
|
||||
import org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer;
|
||||
|
||||
/**
|
||||
* An implementation of {@link AbstractInboundFileSynchronizer} for SMB.
|
||||
*
|
||||
* @author Markus Spann
|
||||
* @since 2.1.1
|
||||
*/
|
||||
public class SmbInboundFileSynchronizer extends AbstractInboundFileSynchronizer<SmbFile> {
|
||||
|
||||
private final Log logger = LogFactory.getLog(SmbInboundFileSynchronizer.class);
|
||||
|
||||
private final String toString;
|
||||
|
||||
/**
|
||||
* Create a synchronizer with the {@link SessionFactory} used to acquire
|
||||
* {@link org.springframework.integration.file.remote.session.Session} instances.
|
||||
*/
|
||||
public SmbInboundFileSynchronizer(SessionFactory<SmbFile> _sessionFactory) {
|
||||
super(_sessionFactory);
|
||||
toString = getClass().getName() + "[sessionFactory=" + _sessionFactory + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isFile(SmbFile _file) {
|
||||
try {
|
||||
return _file != null && _file.isFile();
|
||||
} catch (Exception _ex) {
|
||||
logger.warn("Unable to get resource status [" + _file + "].", _ex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getFilename(SmbFile _file) {
|
||||
return _file != null ? _file.getName() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Copyright 2002-2012 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.smb.inbound;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Comparator;
|
||||
|
||||
import jcifs.smb.SmbFile;
|
||||
|
||||
import org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer;
|
||||
import org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizingMessageSource;
|
||||
|
||||
/**
|
||||
* A {@link org.springframework.integration.core.MessageSource} implementation for SMB.
|
||||
*
|
||||
* @author Markus Spann
|
||||
* @since 2.1.1
|
||||
*/
|
||||
public class SmbInboundFileSynchronizingMessageSource extends AbstractInboundFileSynchronizingMessageSource<SmbFile> {
|
||||
|
||||
// CHECKSTYLE:OFF
|
||||
private final static String componentType = "smb:inbound-channel-adapter";
|
||||
// CHECKSTYLE:ON
|
||||
private final String toString;
|
||||
|
||||
public SmbInboundFileSynchronizingMessageSource(AbstractInboundFileSynchronizer<SmbFile> _synchronizer) {
|
||||
this(_synchronizer, null);
|
||||
}
|
||||
|
||||
public SmbInboundFileSynchronizingMessageSource(AbstractInboundFileSynchronizer<SmbFile> _synchronizer, Comparator<File> _comparator) {
|
||||
super(_synchronizer, _comparator);
|
||||
toString = getClass().getName() + "[componentType=" + componentType + ", synchronizer=" + _synchronizer + ", comparator=" + _comparator + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getComponentType() {
|
||||
return componentType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
/**
|
||||
* Copyright 2002-2012 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.smb.session;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Data holder class for a SMB share configuration.
|
||||
*
|
||||
* SmbFile URLs syntax:
|
||||
* smb://[[[domain;]username[:password]@]server[:port]/[[share/[dir/]file]]][?[param=value[param2=value2[...]]]
|
||||
*
|
||||
* @author Markus Spann
|
||||
* @since 2.1.1
|
||||
*/
|
||||
public class SmbConfig {
|
||||
|
||||
private String host;
|
||||
private int port;
|
||||
private String domain;
|
||||
private String username;
|
||||
private String password;
|
||||
private String shareAndDir;
|
||||
|
||||
private boolean replaceFile = false;
|
||||
private boolean useTempFile = false;
|
||||
|
||||
public SmbConfig() {
|
||||
}
|
||||
|
||||
public SmbConfig(String _host, int _port, String _domain, String _username, String _password, String _shareAndDir) throws UnsupportedEncodingException {
|
||||
this();
|
||||
|
||||
setHost(_host);
|
||||
setPort(_port);
|
||||
setDomain(_domain);
|
||||
setUsername(_username);
|
||||
setPassword(_password);
|
||||
setShareAndDir(_shareAndDir);
|
||||
}
|
||||
|
||||
public void setHost(String _host) {
|
||||
Assert.hasText(_host, "host must not be empty");
|
||||
this.host = _host;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public void setPort(int _port) {
|
||||
Assert.isTrue(_port >= 0, "port must be >= 0");
|
||||
this.port = _port;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setDomain(String _domain) {
|
||||
Assert.notNull(_domain);
|
||||
this.domain = _domain;
|
||||
}
|
||||
|
||||
public String getDomain() {
|
||||
return domain;
|
||||
}
|
||||
|
||||
public void setUsername(String _username) {
|
||||
Assert.hasText(_username, "username should be a non-empty string");
|
||||
this.username = _username;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setPassword(String _password) {
|
||||
Assert.notNull(_password, "password should not be null");
|
||||
this.password = _password;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setShareAndDir(String _shareAndDir) {
|
||||
Assert.notNull(_shareAndDir, "shareAndDir should not be null");
|
||||
this.shareAndDir = _shareAndDir;
|
||||
}
|
||||
|
||||
public String getShareAndDir() {
|
||||
return shareAndDir;
|
||||
}
|
||||
|
||||
public void setReplaceFile(boolean _replaceFile) {
|
||||
this.replaceFile = _replaceFile;
|
||||
}
|
||||
|
||||
public boolean isReplaceFile() {
|
||||
return replaceFile;
|
||||
}
|
||||
|
||||
void setUseTempFile(boolean _useTempFile) {
|
||||
this.useTempFile = _useTempFile;
|
||||
}
|
||||
|
||||
public boolean isUseTempFile() {
|
||||
return useTempFile;
|
||||
}
|
||||
|
||||
String getDomainUserPass(boolean _includePassword) {
|
||||
String domainUserPass;
|
||||
String user = _includePassword ? this.username : "********";
|
||||
if (StringUtils.hasText(this.domain)) {
|
||||
domainUserPass = String.format("%s;%s", this.domain, user);
|
||||
} else {
|
||||
domainUserPass = user;
|
||||
}
|
||||
if (StringUtils.hasText(this.password)) {
|
||||
domainUserPass += ":" + this.password;
|
||||
}
|
||||
return domainUserPass;
|
||||
}
|
||||
|
||||
String getHostPort() {
|
||||
return this.host + (this.port > 0 ? String.format(":%d", this.port) : "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the object. Throws run-time exception if found to be invalid.
|
||||
* @return the object
|
||||
*/
|
||||
public final SmbConfig validate() {
|
||||
Assert.hasText(getHost(), "host must not be empty in " + this);
|
||||
Assert.isTrue(getPort() >= 0, "port must be >= 0 in " + this);
|
||||
Assert.hasText(getShareAndDir(), "share must not be empty in " + this);
|
||||
return this;
|
||||
}
|
||||
|
||||
public final String getUrl() {
|
||||
return getUrl(true);
|
||||
}
|
||||
|
||||
public final String getUrl(boolean _includePassword) {
|
||||
String domainUserPass = getDomainUserPass(_includePassword);
|
||||
if (domainUserPass != null) {
|
||||
try {
|
||||
domainUserPass = URLEncoder.encode(domainUserPass, "UTF8");
|
||||
// CHECKSTYLE:OFF
|
||||
} catch (UnsupportedEncodingException _ex) {
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
}
|
||||
return String.format("smb://%s@%s/%s", domainUserPass, getHostPort(), StringUtils.cleanPath(this.shareAndDir));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName()
|
||||
+ "[url=" + getUrl(false)
|
||||
+ ", replaceFile=" + replaceFile
|
||||
+ "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,448 @@
|
||||
/**
|
||||
* Copyright 2002-2012 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.smb.session;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
import jcifs.smb.SmbException;
|
||||
import jcifs.smb.SmbFile;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.core.NestedIOException;
|
||||
import org.springframework.integration.file.remote.session.Session;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Implementation of the {@link Session} interface for Server Message Block (SMB)
|
||||
* also known as Common Internet File System (CIFS). The Samba project set out to
|
||||
* create non-Windows implementations of SMB. Often Samba is thus used synonymously to SMB.
|
||||
*
|
||||
* SMB is an application-layer network protocol that manages shared access to files, printers
|
||||
* and other networked resources.
|
||||
*
|
||||
* See <a href="http://en.wikipedia.org/wiki/Server_Message_Block">Server Message Block</a>
|
||||
* for more details.
|
||||
*
|
||||
* Inspired by the sprint-integration-ftp implementation done by Mark Fisher and Oleg Zhurakousky.
|
||||
*
|
||||
* @author Markus Spann
|
||||
* @author Mark Fisher
|
||||
* @author Oleg Zhurakousky
|
||||
*
|
||||
* @since 2.1.1
|
||||
*/
|
||||
public class SmbSession implements Session<SmbFile> {
|
||||
|
||||
private final Log logger = LogFactory.getLog(SmbSession.class);
|
||||
private static final String FILE_SEPARATOR = System.getProperty("file.separator");
|
||||
|
||||
static {
|
||||
configureJcifs();
|
||||
}
|
||||
|
||||
private final SmbShare smbShare;
|
||||
|
||||
/**
|
||||
* Constructor for an SMB session.
|
||||
* @param _host server NetBIOS name, DNS name, or IP address, case-insensitive
|
||||
* @param _port port
|
||||
* @param _domain case-sensitive domain name
|
||||
* @param _user case-sensitive user name
|
||||
* @param _password case-sensitive password
|
||||
* @param _shareAndDir server root SMB directory
|
||||
* @param _replaceFile replace existing files if true
|
||||
* @param _useTempFile make use temporary files when writing
|
||||
* @throws IOException in case of I/O errors
|
||||
*/
|
||||
SmbSession(String _host, int _port, String _domain, String _user, String _password, String _shareAndDir, boolean _replaceFile, boolean _useTempFile) throws IOException {
|
||||
this(new SmbShare(new SmbConfig(_host, _port, _domain, _user, _password, _shareAndDir)));
|
||||
|
||||
smbShare.setReplaceFile(_replaceFile);
|
||||
smbShare.setUseTempFile(_useTempFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for an SMB session.
|
||||
* @param _smbShare SMB share resource
|
||||
*/
|
||||
public SmbSession(SmbShare _smbShare) {
|
||||
Assert.notNull(_smbShare, "smbShare must not be null");
|
||||
smbShare = _smbShare;
|
||||
logger.debug("New " + getClass().getName() + " created.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the file or directory at the specified path.
|
||||
* @param _path path to a remote file or directory
|
||||
* @return true if delete successful, false if resource is non-existent
|
||||
* @throws IOException on error conditions returned by a CIFS server
|
||||
* @see org.springframework.integration.file.remote.session.Session#remove(java.lang.String)
|
||||
*/
|
||||
public boolean remove(String _path) throws IOException {
|
||||
Assert.hasText(_path, "path must not be empty");
|
||||
|
||||
boolean removed = false;
|
||||
SmbFile removeFile = createSmbFileObject(_path);
|
||||
|
||||
if (removeFile.exists()) {
|
||||
removeFile.delete();
|
||||
removed = true;
|
||||
}
|
||||
if (!removed) {
|
||||
logger.info("Could not remove non-existing resource [" + _path + "].");
|
||||
} else if (logger.isInfoEnabled()) {
|
||||
logger.info("Successfully removed resource [" + _path + "].");
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contents of the specified SMB resource as an array of SmbFile objects.
|
||||
* In case the remote resource does not exist, an empty array is returned.
|
||||
* @param _path path to a remote directory
|
||||
* @return array of SmbFile objects
|
||||
* @throws IOException on error conditions returned by a CIFS server or if the remote resource is not a directory.
|
||||
* @see org.springframework.integration.file.remote.session.Session#list(java.lang.String)
|
||||
*/
|
||||
public SmbFile[] list(String _path) throws IOException {
|
||||
SmbFile[] files = new SmbFile[0];
|
||||
try {
|
||||
SmbFile smbDir = createSmbDirectoryObject(_path);
|
||||
if (!smbDir.exists()) {
|
||||
logger.warn("Remote directory [" + _path + "] does not exist. Cannot list resources.");
|
||||
return files;
|
||||
} else if (!smbDir.isDirectory()) {
|
||||
throw new NestedIOException("Resource [" + _path + "] is not a directory. Cannot list resources.");
|
||||
}
|
||||
|
||||
files = smbDir.listFiles();
|
||||
|
||||
} catch (SmbException _ex) {
|
||||
throw new NestedIOException("Failed to list resources in [" + _path + "].", _ex);
|
||||
}
|
||||
String msg = "Successfully listed " + files.length + " resource(s) in [" + _path + "]";
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(msg + ": " + Arrays.toString(files));
|
||||
} else {
|
||||
logger.info(msg + ".");
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the remote resource specified by path and copies its contents to the specified
|
||||
* {@link OutputStream}.
|
||||
* @param _path path to a remote file
|
||||
* @param _outputStream output stream
|
||||
* @throws IOException on error conditions returned by a CIFS server or if the remote resource is not a file.
|
||||
* @see org.springframework.integration.file.remote.session.Session#read(java.lang.String, java.io.OutputStream)
|
||||
*/
|
||||
public void read(String _path, OutputStream _outputStream) throws IOException {
|
||||
Assert.hasText(_path, "path must not be empty");
|
||||
Assert.notNull(_outputStream, "outputStream must not be null");
|
||||
|
||||
try {
|
||||
|
||||
SmbFile remoteFile = createSmbFileObject(_path);
|
||||
if (!remoteFile.isFile()) {
|
||||
throw new NestedIOException("Resource [" + _path + "] is not a file.");
|
||||
}
|
||||
FileCopyUtils.copy(remoteFile.getInputStream(), _outputStream);
|
||||
|
||||
} catch (SmbException _ex) {
|
||||
throw new NestedIOException("Failed to read resource [" + _path + "].", _ex);
|
||||
}
|
||||
logger.info("Successfully read resource [" + _path + "].");
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes contents of the specified {@link InputStream} to the remote resource
|
||||
* specified by path. Remote directories are created implicitely as required.
|
||||
* @param _inputStream input stream
|
||||
* @param _path remote path (of a file) to write to
|
||||
* @throws IOException on error conditions returned by a CIFS server
|
||||
* @see org.springframework.integration.file.remote.session.Session#write(java.io.InputStream, java.lang.String)
|
||||
*/
|
||||
public void write(InputStream _inputStream, String _path) throws IOException {
|
||||
Assert.notNull(_inputStream, "inputStream must not be empty");
|
||||
Assert.hasText(_path, "path must not be null");
|
||||
|
||||
try {
|
||||
|
||||
mkdirs(_path);
|
||||
|
||||
SmbFile targetFile = createSmbFileObject(_path);
|
||||
|
||||
if (smbShare.isUseTempFile()) {
|
||||
|
||||
String tempFileName = _path + smbShare.newTempFileSuffix();
|
||||
SmbFile tempFile = createSmbFileObject(tempFileName);
|
||||
tempFile.createNewFile();
|
||||
Assert.isTrue(tempFile.canWrite(), "Temporary file [" + tempFileName + "] is not writable.");
|
||||
|
||||
FileCopyUtils.copy(_inputStream, tempFile.getOutputStream());
|
||||
|
||||
if (targetFile.exists() && smbShare.isReplaceFile()) {
|
||||
targetFile.delete();
|
||||
}
|
||||
tempFile.renameTo(targetFile);
|
||||
|
||||
} else {
|
||||
|
||||
FileCopyUtils.copy(_inputStream, targetFile.getOutputStream());
|
||||
|
||||
}
|
||||
|
||||
} catch (SmbException _ex) {
|
||||
throw new NestedIOException("Failed to write resource [" + _path + "].", _ex);
|
||||
}
|
||||
logger.info("Successfully wrote remote file [" + _path + "].");
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to write a local file object to a remote location.
|
||||
* @see org.springframework.integration.smb.session.SmbSession.write(InputStream, String)
|
||||
*/
|
||||
public SmbFile write(File _file, String _path) throws IOException {
|
||||
return writeAndClose(new FileInputStream(_file), _path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to write a byte array to a remote location.
|
||||
* @see org.springframework.integration.smb.session.SmbSession.write(InputStream, String)
|
||||
*/
|
||||
public SmbFile write(byte[] _contents, String _path) throws IOException {
|
||||
return writeAndClose(new ByteArrayInputStream(_contents), _path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the specified remote path if not yet exists.
|
||||
* If the specified resource is a file rather than a path, creates all directories leading
|
||||
* to that file.
|
||||
* @param _path remote path to create
|
||||
* @return always true (error states are express by exceptions)
|
||||
* @throws IOException on error conditions returned by a CIFS server
|
||||
* @see org.springframework.integration.file.remote.session.Session#mkdir(java.lang.String)
|
||||
*/
|
||||
public boolean mkdir(String _path) throws IOException {
|
||||
try {
|
||||
SmbFile dir = createSmbDirectoryObject(_path);
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
logger.info("Successfully created remote directory [" + _path + "] in share [" + smbShare + "].");
|
||||
} else {
|
||||
logger.info("Remote directory [" + _path + "] exists in share [" + smbShare + "].");
|
||||
}
|
||||
return true;
|
||||
} catch (SmbException _ex) {
|
||||
throw new NestedIOException("Failed to create directory [" + _path + "].", _ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the remote resource exists.
|
||||
* @param _path remote path
|
||||
* @return true if exists, false otherwise
|
||||
* @throws IOException on error conditions returned by a CIFS server
|
||||
* @see org.springframework.integration.file.remote.session.Session#exists(java.lang.String)
|
||||
*/
|
||||
public boolean exists(String _path) throws IOException {
|
||||
return createSmbFileObject(_path).exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the remote resource is a file.
|
||||
* @param _path remote path
|
||||
* @return true if resource is a file, false otherwise
|
||||
* @throws IOException on error conditions returned by a CIFS server
|
||||
*/
|
||||
public boolean isFile(String _path) throws IOException {
|
||||
SmbFile resource = createSmbFileObject(_path);
|
||||
return resource.exists() && resource.isFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the remote resource is a directory.
|
||||
* @param _path remote path
|
||||
* @return true if resource is a directory, false otherwise
|
||||
* @throws IOException on error conditions returned by a CIFS server
|
||||
*/
|
||||
public boolean isDirectory(String _path) throws IOException {
|
||||
SmbFile resource = createSmbFileObject(_path);
|
||||
return resource.exists() && resource.isDirectory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create all directories in the given remote path reference.
|
||||
* @param _path path remote path, may be a file in which case the file name is ignored
|
||||
* @return the path created or null
|
||||
* @throws IOException on error conditions returned by a CIFS server
|
||||
*/
|
||||
String mkdirs(String _path) throws IOException {
|
||||
int idxPath = _path.lastIndexOf(FILE_SEPARATOR);
|
||||
if (idxPath > -1) {
|
||||
String path = _path.substring(0, idxPath + 1);
|
||||
mkdir(path);
|
||||
return path;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames a remote resource.
|
||||
* @param _pathFrom remote source path
|
||||
* @param _pathTo remote target path
|
||||
* @throws IOException on error conditions returned by a CIFS server
|
||||
* @see org.springframework.integration.file.remote.session.Session#rename(java.lang.String, java.lang.String)
|
||||
*/
|
||||
public void rename(String _pathFrom, String _pathTo) throws IOException {
|
||||
try {
|
||||
|
||||
SmbFile smbFileFrom = createSmbFileObject(_pathFrom);
|
||||
SmbFile smbFileTo = createSmbFileObject(_pathTo);
|
||||
if (smbShare.isReplaceFile() && smbFileTo.exists()) {
|
||||
smbFileTo.delete();
|
||||
}
|
||||
smbFileFrom.renameTo(smbFileTo);
|
||||
|
||||
} catch (SmbException _ex) {
|
||||
throw new NestedIOException("Failed to rename [" + _pathFrom + "] to [" + _pathTo + "].", _ex);
|
||||
}
|
||||
logger.info("Successfully renamed remote resource [" + _pathFrom + "] to [" + _pathTo + "].");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this SMB session.
|
||||
* @see org.springframework.integration.file.remote.session.Session#close()
|
||||
*/
|
||||
public void close() {
|
||||
smbShare.doClose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks with this SMB session is open and ready for work by attempting
|
||||
* to list remote files and checking for error conditions..
|
||||
* @return true if the session is open, false otherwise
|
||||
* @see org.springframework.integration.file.remote.session.Session#isOpen()
|
||||
*/
|
||||
public boolean isOpen() {
|
||||
if (!smbShare.isOpened()) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
smbShare.listFiles();
|
||||
} catch (Exception _ex) {
|
||||
close();
|
||||
}
|
||||
return smbShare.isOpened();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to write the specified input stream to a remote path and return
|
||||
* the path as an SMB file object.
|
||||
* @param _inputStream input stream
|
||||
* @param _path remote path (of a file) to write to
|
||||
* @return SMB file object
|
||||
* @throws IOException on error conditions returned by a CIFS server
|
||||
*/
|
||||
SmbFile writeAndClose(InputStream _inputStream, String _path) throws IOException {
|
||||
write(_inputStream, _path);
|
||||
_inputStream.close();
|
||||
return createSmbFileObject(_path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for new SmbFile objects under this session's share for the specified path.
|
||||
* @param _path remote path
|
||||
* @param _isDirectory Boolean object to indicate the path is a directory, may be null
|
||||
* @return SmbFile object for path
|
||||
* @throws IOException in case of I/O errors
|
||||
*/
|
||||
private SmbFile createSmbFileObject(String _path, Boolean _isDirectory) throws IOException {
|
||||
String path = StringUtils.cleanPath(_path);
|
||||
if (!StringUtils.hasText(path)) {
|
||||
return smbShare;
|
||||
}
|
||||
|
||||
SmbFile smbFile = new SmbFile(smbShare, path);
|
||||
|
||||
boolean appendFileSeparator = !path.endsWith(FILE_SEPARATOR);
|
||||
if (appendFileSeparator) {
|
||||
try {
|
||||
appendFileSeparator = smbFile.isDirectory() || (_isDirectory != null && _isDirectory);
|
||||
} catch (Exception _ex) {
|
||||
appendFileSeparator = false;
|
||||
}
|
||||
}
|
||||
if (appendFileSeparator) {
|
||||
smbFile = createSmbFileObject(path + FILE_SEPARATOR);
|
||||
}
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Created new " + SmbFile.class.getName() + "[" + smbFile + "] for path [" + path + "].");
|
||||
}
|
||||
return smbFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an SMB file object pointing to a remote file.
|
||||
*/
|
||||
public SmbFile createSmbFileObject(String _path) throws IOException {
|
||||
return createSmbFileObject(_path, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an SMB file object pointing to a remote directory.
|
||||
*/
|
||||
public SmbFile createSmbDirectoryObject(String _path) throws IOException {
|
||||
return createSmbFileObject(_path, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Static configuration of the JCIFS library.
|
||||
* The log level of this class is mapped to a suitable <code>jcifs.util.loglevel</code>
|
||||
*/
|
||||
static void configureJcifs() {
|
||||
// TODO jcifs.Config.setProperty("jcifs.smb.client.useExtendedSecurity", "false");
|
||||
// TODO jcifs.Config.setProperty("jcifs.smb.client.disablePlainTextPasswords", "false");
|
||||
|
||||
// set JCIFS SMB client library' log level unless already configured by system property
|
||||
final String sysPropLogLevel = "jcifs.util.loglevel";
|
||||
|
||||
if (jcifs.Config.getProperty(sysPropLogLevel) == null) {
|
||||
// set log level according to this class' logger's log level.
|
||||
Log log = LogFactory.getLog(SmbSession.class);
|
||||
if (log.isTraceEnabled()) {
|
||||
jcifs.Config.setProperty(sysPropLogLevel, "N");
|
||||
} else if (log.isDebugEnabled()) {
|
||||
jcifs.Config.setProperty(sysPropLogLevel, "3");
|
||||
} else {
|
||||
jcifs.Config.setProperty(sysPropLogLevel, "1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Copyright 2002-2012 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.smb.session;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import jcifs.smb.SmbFile;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.integration.file.remote.session.SessionFactory;
|
||||
|
||||
/**
|
||||
* The SMB session factory.
|
||||
*
|
||||
* @author Markus Spann
|
||||
* @since 2.1.1
|
||||
*/
|
||||
public class SmbSessionFactory extends SmbConfig implements SessionFactory<SmbFile> {
|
||||
|
||||
private final Log logger = LogFactory.getLog(this.getClass());
|
||||
|
||||
public SmbSessionFactory() {
|
||||
logger.debug("New " + getClass().getName() + " created.");
|
||||
}
|
||||
|
||||
public final SmbSession getSession() {
|
||||
try {
|
||||
return createSession();
|
||||
} catch (Exception _ex) {
|
||||
throw new IllegalStateException("Failed to create session.", _ex);
|
||||
}
|
||||
}
|
||||
|
||||
protected SmbSession createSession() throws IOException {
|
||||
SmbShare smbShare = new SmbShare((SmbConfig) this);
|
||||
smbShare.setReplaceFile(this.isReplaceFile());
|
||||
smbShare.setUseTempFile(this.isUseTempFile());
|
||||
|
||||
logger.info(String.format("SMB share init: %s/%s", getHostPort(), getShareAndDir()));
|
||||
|
||||
smbShare.init();
|
||||
logger.debug("SMB share initialized.");
|
||||
|
||||
return new SmbSession(smbShare);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
* Copyright 2002-2012 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.smb.session;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import jcifs.smb.SmbException;
|
||||
import jcifs.smb.SmbFile;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.core.NestedIOException;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
public class SmbShare extends SmbFile {
|
||||
|
||||
private final Log logger = LogFactory.getLog(SmbShare.class);
|
||||
|
||||
private final AtomicBoolean open = new AtomicBoolean(false);
|
||||
|
||||
private final AtomicBoolean replaceFile = new AtomicBoolean(false);
|
||||
|
||||
private final AtomicBoolean useTempFile = new AtomicBoolean(false);
|
||||
|
||||
public SmbShare(String _url) throws IOException {
|
||||
super(_url);
|
||||
}
|
||||
|
||||
public SmbShare(SmbConfig _smbConfig) throws IOException {
|
||||
this(_smbConfig.validate().getUrl());
|
||||
}
|
||||
|
||||
public void init() throws NestedIOException {
|
||||
boolean canRead = false;
|
||||
try {
|
||||
if (!exists()) {
|
||||
logger.info("SMB root directory does not exist. Creating it.");
|
||||
mkdirs();
|
||||
}
|
||||
canRead = canRead();
|
||||
} catch (SmbException _ex) {
|
||||
throw new NestedIOException("Unable to initialize share: " + this, _ex);
|
||||
}
|
||||
Assert.isTrue(canRead, "Share is not accessible " + this);
|
||||
open.set(true);
|
||||
}
|
||||
|
||||
public boolean isReplaceFile() {
|
||||
return replaceFile.get();
|
||||
}
|
||||
|
||||
public void setReplaceFile(boolean _replace) {
|
||||
this.replaceFile.set(_replace);
|
||||
}
|
||||
|
||||
public boolean isUseTempFile() {
|
||||
return useTempFile.get();
|
||||
}
|
||||
|
||||
public void setUseTempFile(boolean _useTempFile) {
|
||||
this.useTempFile.set(_useTempFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the share is accessible.
|
||||
* Note: jcifs.smb.SmbFile defines a package-protected method isOpen().
|
||||
* @return true if open
|
||||
*/
|
||||
boolean isOpened() {
|
||||
return open.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the open state to closed.
|
||||
* Note: jcifs.smb.SmbFile defines a package-protected method close().
|
||||
*/
|
||||
void doClose() {
|
||||
open.set(false);
|
||||
}
|
||||
|
||||
public String newTempFileSuffix() {
|
||||
return "-" + Long.toHexString(Double.doubleToLongBits(Math.random())) + ".tmp";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Copyright 2002-2012 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.smb.session;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.MappedByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
|
||||
public abstract class SmbUtils {
|
||||
|
||||
private SmbUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the specified file into a byte array.
|
||||
* @param _file file
|
||||
* @return byte array of file contents
|
||||
* @throws IOException
|
||||
*/
|
||||
public static byte[] readFile(File _file) throws IOException {
|
||||
FileInputStream stream = new FileInputStream(_file);
|
||||
try {
|
||||
FileChannel fc = stream.getChannel();
|
||||
MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
|
||||
return bb.array();
|
||||
|
||||
/* Instead of using default, pass in a decoder. */
|
||||
// return Charset.defaultCharset().decode(bb).toString();
|
||||
|
||||
} finally {
|
||||
stream.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
http\://www.springframework.org/schema/integration/smb=org.springframework.integration.smb.config.SmbNamespaceHandler
|
||||
@@ -0,0 +1,2 @@
|
||||
http\://www.springframework.org/schema/integration/smb/spring-integration-smb-2.0.xsd=org/springframework/integration/smb/config/spring-integration-smb-2.0.xsd
|
||||
http\://www.springframework.org/schema/integration/smb/spring-integration-smb.xsd=org/springframework/integration/smb/config/spring-integration-smb-2.0.xsd
|
||||
@@ -0,0 +1,4 @@
|
||||
# Tooling related information for the integration smb namespace
|
||||
http\://www.springframework.org/schema/integration/smb@name=integration smb Namespace
|
||||
http\://www.springframework.org/schema/integration/smb@prefix=int-smb
|
||||
http\://www.springframework.org/schema/integration/smb@icon=org/springframework/integration/smb/config/spring-integration-smb.gif
|
||||
13
spring-integration-smb/src/main/resources/license_header.txt
Normal file
13
spring-integration-smb/src/main/resources/license_header.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
Copyright 2002-2012 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.
|
||||
@@ -0,0 +1,244 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xsd:schema xmlns="http://www.springframework.org/schema/integration/smb"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:tool="http://www.springframework.org/schema/tool"
|
||||
xmlns:integration="http://www.springframework.org/schema/integration"
|
||||
targetNamespace="http://www.springframework.org/schema/integration/smb"
|
||||
elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified">
|
||||
|
||||
<xsd:import namespace="http://www.springframework.org/schema/beans"/>
|
||||
<xsd:import namespace="http://www.springframework.org/schema/tool"/>
|
||||
<xsd:import namespace="http://www.springframework.org/schema/integration"
|
||||
schemaLocation="http://www.springframework.org/schema/integration/spring-integration-2.0.xsd"/>
|
||||
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The handler for namespace 'http://www.springframework.org/schema/integration/smb' is set to
|
||||
'org.springframework.integration.smb.config.SmbNamespaceHandler' in file 'spring.handlers'.
|
||||
SmbNamespaceHandler sets the implemenation of 'inbound-channel-adapter'
|
||||
to class 'SmbInboundChannelAdapterParser' etc.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
|
||||
<xsd:element name="outbound-channel-adapter">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Builds an outbound-channel-adapter that writes files to a remote SMB endpoint.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="base-smb-adapter-type">
|
||||
<xsd:attribute name="remote-directory" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Identifies directory path (e.g., "/temp/mytransfers/") where file will be transferred to
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="remote-directory-expression" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Allows you to provide SpEL expression which will compute directory path
|
||||
where file will be transferred to (e.g., "headers.['remote_dir'] + '/myTransfers'");
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="remote-file-separator" type="xsd:string" default="/">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Allows you to provide remote file/directory separator character. DEFAULT: '/'
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="temporary-file-suffix" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Extension used when uploading files. We change it right after we know it's uploaded.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="remote-filename-generator" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Allows you to specify a reference to
|
||||
[org.springframework.integration.file.FileNameGenerator] bean.
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.integration.file.FileNameGenerator"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="remote-filename-generator-expression" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Allows you to provide SpEL expression which will compute file name of
|
||||
the remote file (e.g., assuming payload is java.io.File "payload.getName() + '.transfered'");
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="order" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Specifies the order for invocation when this endpoint is connected as a
|
||||
subscriber to a channel. This is particularly relevant when that channel
|
||||
is using a "failover" dispatching strategy, or when a failure in the delivery to one subscriber should signal that
|
||||
the message should not be sent to subscribers with a higher 'order' attribute. It has no effect when this
|
||||
endpoint itself is a Polling Consumer for a channel with a queue.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="inbound-channel-adapter">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Builds an inbound-channel-adapter that synchronizes a local directory with the contents of a remote SMB endpoint.
|
||||
The adapter requires either no or exactly one file selection pattern (may be simple pattern or regular expression).
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="base-smb-adapter-type">
|
||||
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="integration:poller" minOccurs="0" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
|
||||
<xsd:attribute name="filename-pattern" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Allows you to provide file name pattern to determine the file names that needs to be scanned
|
||||
and is based on simple pattern matching algorithm (e.g., "*.txt, fo*.txt" etc.)
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="filename-regex" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Allows you to provide Regular Expression to determine the file names that needs to be scanned.
|
||||
(e.g., "f[o]+\.txt" etc.)
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="comparator" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Specify a Comparator to be used when ordering Files. If none is provided, the
|
||||
order will be determined by the java.io.File implementation of Comparable.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="filter" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.integration.file.filters.FileListFilter"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
Allows you to specify a reference to
|
||||
[org.springframework.integration.file.filters.FileListFilter] bean.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="temporary-file-suffix" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Extension used when downloading files. We change it right after we know it's downloaded.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="remote-directory" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Identifies directory path (e.g., "/temp/mytransfers") where file will be transferred FROM.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="remote-file-separator" type="xsd:string" default="/">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Allows you to provide remote file/directory separator character. DEFAULT: '/'
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="local-directory" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Identifies directory path (e.g., "/local/mytransfers") where file will be transferred TO.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="auto-create-local-directory" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Tells this adapter if local directory must be auto-created if it doesn''t exist. Default is TRUE.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="delete-remote-files" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Specify whether to delete the remote source file after copying.
|
||||
By default, the remote files will NOT be deleted.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:complexType name="base-smb-adapter-type">
|
||||
<xsd:attribute name="id" type="xsd:string"/>
|
||||
<xsd:attribute name="session-factory" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.integration.smb.session.SmbSessionFactory"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
<xsd:documentation><![CDATA[
|
||||
Reference to a [org.springframework.integration.smb.session.SmbSessionFactory] bean.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="cache-sessions" type="xsd:string" default="true">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Specify whether the Sessions should be cached. Default is true.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="channel" use="optional" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.integration.core.MessageChannel"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
Identifies channel attached to this adapter. Depending on the type of the adapter
|
||||
this channel could be the receiving channel (e.g., outbound-channel-adapter) or channel where
|
||||
messages will be sent to by this adapter (e.g., inbound-channel-adapter).
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="charset" type="xsd:string" default="UTF-8">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
Allows you to specify Charset (e.g., US-ASCII, ISO-8859-1, UTF-8). [UTF-8] is the default.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
</xsd:schema>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 540 B |
@@ -0,0 +1,283 @@
|
||||
/**
|
||||
* Copyright 2002-2012 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.smb;
|
||||
|
||||
import static junit.framework.Assert.assertNotNull;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.TestName;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Assorted test utils for the library.
|
||||
* @author Markus Spann
|
||||
*/
|
||||
public abstract class AbstractBaseTest {
|
||||
|
||||
/** Instance logger. */
|
||||
private final Log logger = LogFactory.getLog(this.getClass());
|
||||
|
||||
protected final Log getLogger() {
|
||||
return logger;
|
||||
}
|
||||
|
||||
// CHECKSTYLE:OFF
|
||||
@Rule // requires JUnit 4.7 or later
|
||||
public final TestName testMethodName = new TestName();
|
||||
// CHECKSTYLE:ON
|
||||
|
||||
private String getTestMethodName() {
|
||||
return getClass().getSimpleName() + '.' + testMethodName.getMethodName() + "()";
|
||||
}
|
||||
|
||||
@Before
|
||||
public final void logTestBegin() {
|
||||
getLogger().info("BGN - Test " + getTestMethodName());
|
||||
}
|
||||
|
||||
@After
|
||||
public final void logTestEnd() {
|
||||
getLogger().info("END - Test " + getTestMethodName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the Spring application context XML file name from simple class name and suffix '-context.xml'.
|
||||
* @param _suffix optional suffix
|
||||
* @return application context XML file name
|
||||
*/
|
||||
protected final String getApplicationContextXmlFile(String _suffix) {
|
||||
String fn = getClass().getSimpleName();
|
||||
if (StringUtils.hasText(_suffix)) {
|
||||
fn += _suffix;
|
||||
}
|
||||
fn += "-context.xml";
|
||||
getLogger().debug("Returning application context xml file [" + fn + "] for class [" + getClass().getName() + "].");
|
||||
return fn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the Spring application context XML file name from simple class name.
|
||||
* @return application context XML file name
|
||||
*/
|
||||
protected final String getApplicationContextXmlFile() {
|
||||
return getApplicationContextXmlFile(null);
|
||||
}
|
||||
|
||||
protected final ClassPathXmlApplicationContext getApplicationContext() {
|
||||
return new ClassPathXmlApplicationContext(getApplicationContextXmlFile(), getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the specified input stream to file.
|
||||
* @param _inputStream input stream
|
||||
* @param _path output file path
|
||||
* @throws IOException in case of I/O errors
|
||||
*/
|
||||
public static void writeToFile(InputStream _inputStream, String _path) throws IOException {
|
||||
FileOutputStream fos = new FileOutputStream(_path);
|
||||
try {
|
||||
FileCopyUtils.copy(_inputStream, fos);
|
||||
} finally {
|
||||
fos.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the specified byte array to the output stream.
|
||||
* @param _bytes byte array
|
||||
* @param _outputStream output stream
|
||||
* @throws IOException in case of I/O errors
|
||||
*/
|
||||
public static void writeToFile(byte[] _bytes, OutputStream _outputStream) throws IOException {
|
||||
FileCopyUtils.copy(_bytes, _outputStream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the specified byte array to the an output file.
|
||||
* @param _bytes byte array
|
||||
* @param _fileName output file
|
||||
* @throws IOException in case of I/O errors
|
||||
*/
|
||||
public static void writeToFile(byte[] _bytes, String _fileName) throws IOException {
|
||||
FileOutputStream fos = new FileOutputStream(_fileName);
|
||||
writeToFile(_bytes, fos);
|
||||
fos.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new file of the given name.
|
||||
* If the file exists, it will be deleted.
|
||||
* The file will be deleted on exit of the JVM.
|
||||
* @param _fileName file name
|
||||
* @return file object
|
||||
*/
|
||||
protected File createNewFile(String _fileName) {
|
||||
File file = new File(_fileName);
|
||||
file.deleteOnExit();
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
|
||||
getLogger().debug("File object [" + _fileName + "] created: " + file.getAbsolutePath());
|
||||
|
||||
assertFileNotExists(file);
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes one or more files or directories.
|
||||
* @param _files file or directories
|
||||
*/
|
||||
protected void delete(String... _files) {
|
||||
for (String fileName : _files) {
|
||||
if (fileName == null) {
|
||||
continue;
|
||||
}
|
||||
File file = new File(fileName);
|
||||
if (file.exists()) {
|
||||
getLogger().debug("Deleting file [" + fileName + "].");
|
||||
if (!file.delete()) {
|
||||
file.deleteOnExit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a directory exists, if not creates it and adds it to the DeleteOnExit hook.
|
||||
* @param _dir directory
|
||||
*/
|
||||
protected void ensureExists(String _dir) {
|
||||
File dir = new File(_dir);
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
dir.deleteOnExit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves class name and method name at the specified stacktrace index.
|
||||
* @param _index stacktrace index
|
||||
* @return fully qualified method name
|
||||
*/
|
||||
private static String getStackTraceString(int _index) {
|
||||
StackTraceElement[] arrStackTraceElems = new Throwable().fillInStackTrace().getStackTrace();
|
||||
final int lIndex = Math.min(arrStackTraceElems.length - 1, Math.max(0, _index));
|
||||
return arrStackTraceElems[lIndex].getClassName() + "." + arrStackTraceElems[lIndex].getMethodName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current method name.
|
||||
* @return method name
|
||||
*/
|
||||
public static String getMethodName() {
|
||||
return getStackTraceString(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the calling method name.
|
||||
* @return method name
|
||||
*/
|
||||
public static String getCallingMethodName() {
|
||||
return getStackTraceString(3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the specified file exists.
|
||||
* @param _file file object
|
||||
* @return the file object
|
||||
*/
|
||||
public static final File assertFileExists(File _file) {
|
||||
return assertFileExists(_file, true);
|
||||
}
|
||||
|
||||
public static final File assertFileNotExists(File _file) {
|
||||
return assertFileExists(_file, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the specified file exists or does not exists.
|
||||
* @param _file file object
|
||||
* @param _exists true if should exist, false otherwise
|
||||
* @return the file object
|
||||
*/
|
||||
private static File assertFileExists(File _file, boolean _exists) {
|
||||
assertNotNull("File object is null.", _file);
|
||||
if (_exists) {
|
||||
assertTrue("File [" + _file.getAbsolutePath() + "] does not exist.", _file.exists());
|
||||
} else {
|
||||
assertTrue("File [" + _file.getAbsolutePath() + "] exists.", !_file.exists());
|
||||
}
|
||||
return _file;
|
||||
}
|
||||
|
||||
public static final File assertFileExists(String _file) {
|
||||
return assertFileExists(new File(_file));
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes one or more test methods on the specified test class.
|
||||
* Catches exceptions during test setup (using reflection) and test invocation.
|
||||
* @param _testClass test class object
|
||||
* @param _methodNames String method names to invoke in order, no parameters expected
|
||||
*/
|
||||
protected static void runTests(Class<? extends AbstractBaseTest> _testClass, String... _methodNames) {
|
||||
AbstractBaseTest test;
|
||||
Method[] methods = new Method[_methodNames.length];
|
||||
String methodName = null;
|
||||
|
||||
try {
|
||||
test = _testClass.newInstance();
|
||||
for (int i = 0; i < _methodNames.length; i++) {
|
||||
methodName = _methodNames[i];
|
||||
methods[i] = _testClass.getMethod(methodName, (Class<?>[]) null);
|
||||
}
|
||||
} catch (Exception _ex) {
|
||||
System.err.println("Test setup failed for " + _testClass + "." + methodName + "().");
|
||||
_ex.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
Method method = null;
|
||||
try {
|
||||
|
||||
for (int i = 0; i < methods.length; i++) {
|
||||
method = methods[i];
|
||||
method.invoke(test, (Object[]) null);
|
||||
}
|
||||
|
||||
} catch (Exception _ex) {
|
||||
System.err.println("Test execution failed for " + _testClass + "." + method.getName() + ".");
|
||||
_ex.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?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-smb="http://www.springframework.org/schema/integration/smb"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
|
||||
http://www.springframework.org/schema/integration/smb http://www.springframework.org/schema/integration/smb/spring-integration-smb.xsd
|
||||
">
|
||||
|
||||
<int:message-history/>
|
||||
|
||||
<bean id="smbSessionFactory" class="org.springframework.integration.smb.session.SmbSessionFactory">
|
||||
<property name="host" value="localhost"/>
|
||||
<property name="port" value="0"/>
|
||||
<property name="domain" value=""/>
|
||||
<property name="username" value="sambaguest"/>
|
||||
<property name="password" value="sambaguest"/>
|
||||
<property name="shareAndDir" value="smb-share/"/>
|
||||
<property name="replaceFile" value="true"/>
|
||||
</bean>
|
||||
|
||||
<int-smb:inbound-channel-adapter id="smbInboundChannelAdapter"
|
||||
session-factory="smbSessionFactory"
|
||||
channel="smbInboundChannel"
|
||||
auto-create-local-directory="true"
|
||||
local-directory="file:test-temp/local-5"
|
||||
remote-directory="test-temp/remote-9"
|
||||
delete-remote-files="false">
|
||||
<int:poller fixed-rate="1000"/>
|
||||
</int-smb:inbound-channel-adapter>
|
||||
|
||||
<int:channel id="smbInboundChannel">
|
||||
<int:queue/>
|
||||
</int:channel>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Copyright 2002-2012 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.smb;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
|
||||
|
||||
/**
|
||||
* @author Markus Spann
|
||||
*
|
||||
*/
|
||||
public class SmbMessageHistoryTests extends AbstractBaseTest {
|
||||
@Test
|
||||
public void testMessageHistory() throws Exception {
|
||||
SourcePollingChannelAdapter adapter = getApplicationContext().getBean("smbInboundChannelAdapter", SourcePollingChannelAdapter.class);
|
||||
assertEquals("smbInboundChannelAdapter", adapter.getComponentName());
|
||||
assertEquals("smb:inbound-channel-adapter", adapter.getComponentType());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?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-smb="http://www.springframework.org/schema/integration/smb"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/integration/smb http://www.springframework.org/schema/integration/smb/spring-integration-smb.xsd
|
||||
">
|
||||
|
||||
<bean id="smbSessionFactory" class="org.springframework.integration.smb.session.SmbSessionFactory">
|
||||
<property name="host" value="localhost"/>
|
||||
<property name="domain" value=""/>
|
||||
<property name="username" value="sambaguest"/>
|
||||
<property name="password" value="sambaguest"/>
|
||||
<property name="shareAndDir" value="smb-share/"/>
|
||||
</bean>
|
||||
|
||||
<int-smb:inbound-channel-adapter id="adapterSmb"
|
||||
session-factory="smbSessionFactory"
|
||||
cache-sessions="false"
|
||||
channel="smbIn"
|
||||
filename-pattern="foo"
|
||||
local-directory="test-temp/local-10"
|
||||
remote-directory="test-temp/remote-10"
|
||||
auto-create-local-directory="true"
|
||||
delete-remote-files="false">
|
||||
<int:poller ref="smbPoller" />
|
||||
</int-smb:inbound-channel-adapter>
|
||||
|
||||
<int-smb:inbound-channel-adapter id="adapterSmb2"
|
||||
session-factory="smbSessionFactory"
|
||||
cache-sessions="false"
|
||||
channel="smbIn"
|
||||
filter="filter"
|
||||
local-directory="test-temp"
|
||||
remote-directory="test-temp/remote-11"
|
||||
auto-create-local-directory="true"
|
||||
delete-remote-files="false">
|
||||
<int:poller ref="smbPoller" />
|
||||
</int-smb:inbound-channel-adapter>
|
||||
|
||||
<bean id="filter" class="org.mockito.Mockito" factory-method="mock">
|
||||
<constructor-arg value="org.springframework.integration.file.filters.FileListFilter"/>
|
||||
</bean>
|
||||
|
||||
<int:poller fixed-rate="3000" id="smbPoller" />
|
||||
|
||||
<int:channel id="smbIn">
|
||||
<int:queue/>
|
||||
</int:channel>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,40 @@
|
||||
<?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-smb="http://www.springframework.org/schema/integration/smb"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/integration/smb http://www.springframework.org/schema/integration/smb/spring-integration-smb.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
|
||||
">
|
||||
|
||||
<bean id="smbSessionFactory" class="org.springframework.integration.smb.session.SmbSessionFactory">
|
||||
<property name="host" value="localhost"/>
|
||||
<property name="domain" value=""/>
|
||||
<property name="username" value="sambaguest"/>
|
||||
<property name="password" value="sambaguest"/>
|
||||
<property name="shareAndDir" value="smb-share/"/>
|
||||
</bean>
|
||||
|
||||
<int-smb:inbound-channel-adapter id="adapterSmbDontAutoCreate"
|
||||
channel="smbIn"
|
||||
session-factory="smbSessionFactory"
|
||||
filter="filter"
|
||||
local-directory="file:test-temp/local-6"
|
||||
remote-directory="test-temp/remote-12"
|
||||
auto-create-local-directory="false"
|
||||
delete-remote-files="false">
|
||||
<int:poller fixed-rate="1000"/>
|
||||
</int-smb:inbound-channel-adapter>
|
||||
|
||||
<bean id="filter" class="org.mockito.Mockito" factory-method="mock">
|
||||
<constructor-arg value="org.springframework.integration.file.entries.EntryListFilter"/>
|
||||
</bean>
|
||||
|
||||
<int:channel id="smbIn">
|
||||
<int:queue/>
|
||||
</int:channel>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Copyright 2002-2012 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.smb;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
/**
|
||||
* @author Markus Spann
|
||||
*
|
||||
*/
|
||||
public class SmbParserInboundTests extends AbstractBaseTest {
|
||||
|
||||
@Before
|
||||
public void prepare() {
|
||||
ensureExists("test-temp/remote-10");
|
||||
cleanUp();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalFilesAutoCreationTrue() throws Exception {
|
||||
assertFileNotExists(new File("test-temp/local-10"));
|
||||
new ClassPathXmlApplicationContext(getApplicationContextXmlFile(), this.getClass());
|
||||
assertFileExists(new File("test-temp/local-10"));
|
||||
assertFileNotExists(new File("test-temp/local-6"));
|
||||
}
|
||||
|
||||
@Test(expected = BeanCreationException.class)
|
||||
public void testLocalFilesAutoCreationFalse() throws Exception {
|
||||
assertFileNotExists(new File("test-temp/local-6"));
|
||||
new ClassPathXmlApplicationContext(getApplicationContextXmlFile("-fail"), this.getClass());
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanUp() {
|
||||
delete("test-temp/local-10", "test-temp/local-6");
|
||||
}
|
||||
|
||||
public static void main(String[] _args) {
|
||||
new SmbParserInboundTests().cleanUp();
|
||||
runTests(SmbParserInboundTests.class, "testLocalFilesAutoCreationTrue", "testLocalFilesAutoCreationFalse");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?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:p="http://www.springframework.org/schema/p"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:int-smb="http://www.springframework.org/schema/integration/smb"
|
||||
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.xsd
|
||||
http://www.springframework.org/schema/integration/smb
|
||||
http://www.springframework.org/schema/integration/smb/spring-integration-smb.xsd
|
||||
">
|
||||
|
||||
<bean id="smbSessionFactory"
|
||||
class="org.springframework.integration.smb.config.SmbInboundChannelAdapterParserTests.TestSessionFactoryBean"/>
|
||||
|
||||
<int-smb:inbound-channel-adapter id="smbInbound"
|
||||
channel="smbChannel"
|
||||
session-factory="smbSessionFactory"
|
||||
cache-sessions="false"
|
||||
charset="UTF-8"
|
||||
auto-create-local-directory="true"
|
||||
delete-remote-files="true"
|
||||
filename-pattern="*.txt"
|
||||
local-directory="file:test-temp/local-1"
|
||||
remote-file-separator=""
|
||||
comparator="comparator"
|
||||
temporary-file-suffix=".working.tmp"
|
||||
remote-directory="test-temp/remote-1">
|
||||
<int:poller fixed-rate="1000"/>
|
||||
</int-smb:inbound-channel-adapter>
|
||||
|
||||
<bean id="comparator" class="org.mockito.Mockito" factory-method="mock">
|
||||
<constructor-arg value="java.util.Comparator"/>
|
||||
</bean>
|
||||
|
||||
<int-smb:inbound-channel-adapter
|
||||
channel="smbChannel"
|
||||
session-factory="smbSessionFactory"
|
||||
charset="UTF-8"
|
||||
auto-create-local-directory="true"
|
||||
delete-remote-files="true"
|
||||
filter="entryListFilter"
|
||||
local-directory="file:test-temp/local-2"
|
||||
remote-directory="test-temp/remote-2">
|
||||
<int:poller fixed-rate="1000"/>
|
||||
</int-smb:inbound-channel-adapter>
|
||||
|
||||
<int-smb:inbound-channel-adapter id="simpleAdapter"
|
||||
channel="smbChannel"
|
||||
session-factory="smbSessionFactory"
|
||||
local-directory="file:test-temp/local-3"
|
||||
remote-directory="test-temp/remote-3">
|
||||
<int:poller fixed-rate="1000"/>
|
||||
</int-smb:inbound-channel-adapter>
|
||||
|
||||
<int:channel id="smbChannel">
|
||||
<int:queue/>
|
||||
</int:channel>
|
||||
|
||||
<bean id="entryListFilter" class="org.mockito.Mockito" factory-method="mock">
|
||||
<constructor-arg value="org.springframework.integration.file.filters.FileListFilter"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* Copyright 2002-2012 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.smb.config;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
|
||||
import org.springframework.integration.file.remote.session.CachingSessionFactory;
|
||||
import org.springframework.integration.smb.AbstractBaseTest;
|
||||
import org.springframework.integration.smb.filters.SmbSimplePatternFileListFilter;
|
||||
import org.springframework.integration.smb.inbound.SmbInboundFileSynchronizer;
|
||||
import org.springframework.integration.smb.inbound.SmbInboundFileSynchronizingMessageSource;
|
||||
import org.springframework.integration.smb.session.SmbSession;
|
||||
import org.springframework.integration.smb.session.SmbSessionFactory;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
|
||||
/**
|
||||
* @author Markus Spann
|
||||
*/
|
||||
public class SmbInboundChannelAdapterParserTests extends AbstractBaseTest {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(timeout = 10000)
|
||||
public void testSmbInboundChannelAdapterComplete() throws Exception{
|
||||
ApplicationContext ac =
|
||||
new ClassPathXmlApplicationContext(getApplicationContextXmlFile(), this.getClass());
|
||||
SourcePollingChannelAdapter adapter = ac.getBean("smbInbound", SourcePollingChannelAdapter.class);
|
||||
Comparator<File> comparator = TestUtils.getPropertyValue(adapter, "source.fileSource.toBeReceived.q.comparator", Comparator.class);
|
||||
assertNotNull(comparator);
|
||||
assertEquals("smbInbound", adapter.getComponentName());
|
||||
assertEquals("smb:inbound-channel-adapter", adapter.getComponentType());
|
||||
assertNotNull(TestUtils.getPropertyValue(adapter, "poller"));
|
||||
assertEquals(ac.getBean("smbChannel"), TestUtils.getPropertyValue(adapter, "outputChannel"));
|
||||
SmbInboundFileSynchronizingMessageSource inbound =
|
||||
(SmbInboundFileSynchronizingMessageSource) TestUtils.getPropertyValue(adapter, "source");
|
||||
|
||||
SmbInboundFileSynchronizer fisync =
|
||||
(SmbInboundFileSynchronizer) TestUtils.getPropertyValue(inbound, "synchronizer");
|
||||
assertEquals(".working.tmp", TestUtils.getPropertyValue(fisync, "temporaryFileSuffix", String.class));
|
||||
String remoteFileSeparator = (String) TestUtils.getPropertyValue(fisync, "remoteFileSeparator");
|
||||
assertNotNull(remoteFileSeparator);
|
||||
assertEquals("", remoteFileSeparator);
|
||||
SmbSimplePatternFileListFilter filter = (SmbSimplePatternFileListFilter) TestUtils.getPropertyValue(fisync, "filter");
|
||||
assertNotNull(filter);
|
||||
Object sessionFactory = TestUtils.getPropertyValue(fisync, "sessionFactory");
|
||||
assertTrue(SmbSessionFactory.class.isAssignableFrom(sessionFactory.getClass()));
|
||||
}
|
||||
|
||||
@Test(timeout = 10000)
|
||||
public void cachingSessionFactoryByDefault() throws Exception{
|
||||
ApplicationContext ac = new ClassPathXmlApplicationContext(getApplicationContextXmlFile(), this.getClass());
|
||||
SourcePollingChannelAdapter adapter = ac.getBean("simpleAdapter", SourcePollingChannelAdapter.class);
|
||||
Object sessionFactory = TestUtils.getPropertyValue(adapter, "source.synchronizer.sessionFactory");
|
||||
assertEquals(CachingSessionFactory.class, sessionFactory.getClass());
|
||||
SmbInboundFileSynchronizer fisync =
|
||||
TestUtils.getPropertyValue(adapter, "source.synchronizer", SmbInboundFileSynchronizer.class);
|
||||
String remoteFileSeparator = (String) TestUtils.getPropertyValue(fisync, "remoteFileSeparator");
|
||||
assertNotNull(remoteFileSeparator);
|
||||
assertEquals("/", remoteFileSeparator);
|
||||
}
|
||||
|
||||
@Test(timeout = 10000)
|
||||
public void testSmbInboundChannelAdapterCompleteNoId() throws Exception{
|
||||
ApplicationContext ac =
|
||||
new ClassPathXmlApplicationContext(getApplicationContextXmlFile(), this.getClass());
|
||||
Map<String, SourcePollingChannelAdapter> spcas = ac.getBeansOfType(SourcePollingChannelAdapter.class);
|
||||
SourcePollingChannelAdapter adapter = null;
|
||||
for (String key : spcas.keySet()) {
|
||||
if (!key.equals("smbInbound") && !key.equals("simpleAdapter")){
|
||||
adapter = spcas.get(key);
|
||||
}
|
||||
}
|
||||
assertNotNull(adapter);
|
||||
}
|
||||
|
||||
|
||||
public static class TestSessionFactoryBean implements FactoryBean<SmbSessionFactory> {
|
||||
|
||||
public SmbSessionFactory getObject() throws Exception {
|
||||
SmbSessionFactory smbFactory = mock(SmbSessionFactory.class);
|
||||
SmbSession session = mock(SmbSession.class);
|
||||
when(smbFactory.getSession()).thenReturn(session);
|
||||
return smbFactory;
|
||||
}
|
||||
|
||||
public Class<?> getObjectType() {
|
||||
return SmbSessionFactory.class;
|
||||
}
|
||||
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?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:p="http://www.springframework.org/schema/p"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:int-smb="http://www.springframework.org/schema/integration/smb"
|
||||
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.xsd
|
||||
http://www.springframework.org/schema/integration/smb http://www.springframework.org/schema/integration/smb/spring-integration-smb.xsd
|
||||
">
|
||||
|
||||
<bean id="smbSessionFactory"
|
||||
class="org.springframework.integration.smb.session.SmbSessionFactory"
|
||||
p:host="localhost"
|
||||
p:port="0"
|
||||
p:domain="sambaguest"
|
||||
p:username="sambaguest"
|
||||
p:password="sambaguest"
|
||||
p:shareAndDir="smb-share/"
|
||||
p:replaceFile="false"
|
||||
/>
|
||||
|
||||
<int-smb:inbound-channel-adapter id="smbInboundChannelAdapter"
|
||||
channel="smbInboundChannel"
|
||||
session-factory="smbSessionFactory"
|
||||
cache-sessions="true"
|
||||
charset="UTF-8"
|
||||
remote-directory="test-temp/remote-4"
|
||||
remote-file-separator="/"
|
||||
filename-regex=".*\.txt$"
|
||||
delete-remote-files="true"
|
||||
temporary-file-suffix=".working.tmp"
|
||||
auto-create-local-directory="true"
|
||||
local-directory="file:test-temp/local-4">
|
||||
|
||||
<int:poller fixed-rate="5000" error-channel="nullChannel"/>
|
||||
|
||||
</int-smb:inbound-channel-adapter>
|
||||
|
||||
<int:channel id="smbInboundChannel">
|
||||
<int:queue/>
|
||||
</int:channel>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,137 @@
|
||||
/**
|
||||
* Copyright 2002-2012 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.smb.config;
|
||||
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.MessageChannel;
|
||||
import org.springframework.integration.endpoint.EventDrivenConsumer;
|
||||
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
|
||||
import org.springframework.integration.file.remote.handler.FileTransferringMessageHandler;
|
||||
import org.springframework.integration.message.GenericMessage;
|
||||
import org.springframework.integration.smb.AbstractBaseTest;
|
||||
import org.springframework.integration.smb.inbound.SmbInboundFileSynchronizingMessageSource;
|
||||
import org.springframework.integration.smb.session.SmbSession;
|
||||
import org.springframework.integration.smb.session.SmbSessionFactory;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
|
||||
/**
|
||||
* System tests that perform SMB access without any mocking.
|
||||
* These tests are annotated with '@Ignore', as they requires real SMB share configured
|
||||
* in the application context/smbClientFactory in order to succeed.
|
||||
* The test cases create directories and files autonomously and perform clean-up
|
||||
* on a best effort basis.
|
||||
*
|
||||
* @author Markus Spann
|
||||
*/
|
||||
public class SmbInboundOutboundSample extends AbstractBaseTest {
|
||||
|
||||
private static final String INBOUND_APPLICATION_CONTEXT_XML = "SmbInboundChannelAdapterSample-context.xml";
|
||||
private static final String OUTBOUND_APPLICATION_CONTEXT_XML = "SmbOutboundChannelAdapterSample-context.xml";
|
||||
|
||||
@org.junit.Ignore("Actual SMB share must be configured in file [" + INBOUND_APPLICATION_CONTEXT_XML + "].")
|
||||
@Test
|
||||
public void testSmbInboundChannelAdapter() throws Exception {
|
||||
String testLocalDir = "test-temp/local-4/";
|
||||
String testRemoteDir = "test-temp/remote-4/";
|
||||
|
||||
ApplicationContext ac = new ClassPathXmlApplicationContext(INBOUND_APPLICATION_CONTEXT_XML, this.getClass());
|
||||
|
||||
Object consumer = ac.getBean("smbInboundChannelAdapter");
|
||||
assertTrue(consumer instanceof SourcePollingChannelAdapter);
|
||||
Object messageSource = TestUtils.getPropertyValue(consumer, "source");
|
||||
assertTrue(messageSource instanceof SmbInboundFileSynchronizingMessageSource);
|
||||
|
||||
// retrieve the session factory bean to place a couple of test files remotely using a new session
|
||||
SmbSessionFactory smbSessionFactory = ac.getBean("smbSessionFactory", SmbSessionFactory.class);
|
||||
smbSessionFactory.setReplaceFile(true);
|
||||
SmbSession smbSession = smbSessionFactory.getSession();
|
||||
|
||||
// place text files onto the share
|
||||
smbSession.mkdir(testRemoteDir);
|
||||
|
||||
String[] fileNames = createTestFileNames(5);
|
||||
for (int i = 0; i < fileNames.length; i++) {
|
||||
smbSession.write(("File [" + fileNames[i] + "] written by test case [" + getMethodName() + "].").getBytes(), testRemoteDir + fileNames[i]);
|
||||
}
|
||||
|
||||
// allow time for the files to arrive locally
|
||||
Thread.sleep(5000);
|
||||
|
||||
// confirm the local presence of all test files
|
||||
for (int i = 0; i < fileNames.length; i++) {
|
||||
assertFileExists(testLocalDir + fileNames[i]).deleteOnExit();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@org.junit.Ignore("Actual SMB share must be configured in file [" + OUTBOUND_APPLICATION_CONTEXT_XML + "].")
|
||||
@Test
|
||||
public void testSmbOutboundChannelAdapter() throws Exception {
|
||||
String testRemoteDir = "test-temp/remote-8/";
|
||||
String testLocalDir = "test-temp/local-8/";
|
||||
new File(testLocalDir).mkdirs();
|
||||
|
||||
String[] fileNames = createTestFileNames(5);
|
||||
for (int i = 0; i < fileNames.length; i++) {
|
||||
writeToFile(("File [" + fileNames[i] + "] written by test case [" + getMethodName() + "].").getBytes(), testLocalDir + fileNames[i]);
|
||||
}
|
||||
|
||||
ApplicationContext ac = new ClassPathXmlApplicationContext(OUTBOUND_APPLICATION_CONTEXT_XML, this.getClass());
|
||||
|
||||
Object consumer = ac.getBean("smbOutboundChannelAdapter");
|
||||
assertTrue(consumer instanceof EventDrivenConsumer);
|
||||
Object messageSource = TestUtils.getPropertyValue(consumer, "handler");
|
||||
assertTrue(messageSource instanceof FileTransferringMessageHandler);
|
||||
|
||||
MessageChannel smbChannel = ac.getBean("smbOutboundChannel", MessageChannel.class);
|
||||
|
||||
for (int i = 0; i < fileNames.length; i++) {
|
||||
smbChannel.send(new GenericMessage<File>(new File(testLocalDir + fileNames[i])));
|
||||
}
|
||||
|
||||
Thread.sleep(3000);
|
||||
|
||||
// retrieve the session factory bean to check the test files are present in the remote location
|
||||
SmbSessionFactory smbSessionFactory = ac.getBean("smbSessionFactory", SmbSessionFactory.class);
|
||||
smbSessionFactory.setReplaceFile(false);
|
||||
SmbSession smbSession = smbSessionFactory.getSession();
|
||||
|
||||
for (int i = 0; i < fileNames.length; i++) {
|
||||
String remoteFile = testRemoteDir + fileNames[i];
|
||||
assertTrue("Remote file [" + remoteFile + "] does not exist.", smbSession.exists(remoteFile));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String[] createTestFileNames(int _nbTestFiles) {
|
||||
String[] fileNames = new String[_nbTestFiles];
|
||||
for (int i = 0; i < fileNames.length; i++) {
|
||||
fileNames[i] = "test-file-" + i + ".txt";
|
||||
}
|
||||
return fileNames;
|
||||
}
|
||||
|
||||
public static void main(String[] _args) {
|
||||
runTests(SmbInboundOutboundSample.class, "testSmbOutboundChannelAdapter", "testSmbInboundChannelAdapter");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?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-smb="http://www.springframework.org/schema/integration/smb"
|
||||
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.xsd
|
||||
http://www.springframework.org/schema/integration/smb http://www.springframework.org/schema/integration/smb/spring-integration-smb.xsd">
|
||||
|
||||
<bean id="smbSessionFactory" class="org.springframework.integration.smb.session.SmbSessionFactory">
|
||||
<property name="host" value="localhost"/>
|
||||
<property name="port" value="0"/>
|
||||
<property name="domain" value=""/>
|
||||
<property name="username" value="sambaguest"/>
|
||||
<property name="password" value="sambaguest"/>
|
||||
<property name="shareAndDir" value="smb-share/"/>
|
||||
<property name="replaceFile" value="false"/>
|
||||
</bean>
|
||||
|
||||
<int-smb:outbound-channel-adapter id="smbOutboundChannelAdapter"
|
||||
channel="smbPubSubChannel"
|
||||
session-factory="smbSessionFactory"
|
||||
cache-sessions="false"
|
||||
remote-directory="test-temp/remote-5"
|
||||
charset="UTF-8"
|
||||
remote-file-separator="."
|
||||
temporary-file-suffix=".working.tmp"
|
||||
remote-filename-generator="fileNameGenerator"
|
||||
order="23"/>
|
||||
|
||||
<int-smb:outbound-channel-adapter id="smbOutboundChannelAdapter2"
|
||||
channel="smbPubSubChannel"
|
||||
session-factory="smbSessionFactory"
|
||||
remote-directory="test-temp/remote-6"
|
||||
charset="UTF-8"
|
||||
remote-file-separator="."
|
||||
temporary-file-suffix=".working.tmp"
|
||||
remote-filename-generator="fileNameGenerator"
|
||||
order="12"/>
|
||||
|
||||
<int-smb:outbound-channel-adapter id="simpleAdapter"
|
||||
channel="smbPubSubChannel"
|
||||
session-factory="smbSessionFactory"
|
||||
remote-directory="test-temp/remote-7"/>
|
||||
|
||||
<int:publish-subscribe-channel id="smbPubSubChannel"/>
|
||||
|
||||
<bean id="fileNameGenerator" class="org.mockito.Mockito" factory-method="mock">
|
||||
<constructor-arg value="org.springframework.integration.file.FileNameGenerator"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* Copyright 2002-2012 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.smb.config;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertNotNull;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertSame;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.channel.PublishSubscribeChannel;
|
||||
import org.springframework.integration.core.MessageHandler;
|
||||
import org.springframework.integration.endpoint.EventDrivenConsumer;
|
||||
import org.springframework.integration.file.remote.session.CachingSessionFactory;
|
||||
import org.springframework.integration.smb.AbstractBaseTest;
|
||||
import org.springframework.integration.smb.session.SmbSessionFactory;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
|
||||
/**
|
||||
* @author Markus Spann
|
||||
* @since 2.1.1
|
||||
*/
|
||||
public class SmbOutboundChannelAdapterParserTests extends AbstractBaseTest {
|
||||
|
||||
@Test
|
||||
public void testSmbOutboundChannelAdapterComplete() throws Exception {
|
||||
ApplicationContext ac = getApplicationContext();
|
||||
|
||||
Object consumer = ac.getBean("smbOutboundChannelAdapter");
|
||||
assertTrue(consumer instanceof EventDrivenConsumer);
|
||||
|
||||
PublishSubscribeChannel channel = ac.getBean("smbPubSubChannel", PublishSubscribeChannel.class);
|
||||
assertEquals(channel, TestUtils.getPropertyValue(consumer, "inputChannel"));
|
||||
assertEquals("smbOutboundChannelAdapter", ((EventDrivenConsumer) consumer).getComponentName());
|
||||
|
||||
Object messageHandler = TestUtils.getPropertyValue(consumer, "handler");
|
||||
String remoteFileSeparator = (String) TestUtils.getPropertyValue(messageHandler, "remoteFileSeparator");
|
||||
assertNotNull(remoteFileSeparator);
|
||||
assertEquals(".working.tmp", TestUtils.getPropertyValue(messageHandler, "temporaryFileSuffix", String.class));
|
||||
assertEquals(".", remoteFileSeparator);
|
||||
assertEquals(ac.getBean("fileNameGenerator"), TestUtils.getPropertyValue(messageHandler, "fileNameGenerator"));
|
||||
assertEquals("UTF-8", TestUtils.getPropertyValue(messageHandler, "charset"));
|
||||
assertNotNull(TestUtils.getPropertyValue(messageHandler, "temporaryDirectory"));
|
||||
|
||||
Object sessionFactoryProp = TestUtils.getPropertyValue(messageHandler, "sessionFactory");
|
||||
assertEquals(SmbSessionFactory.class, sessionFactoryProp.getClass());
|
||||
|
||||
SmbSessionFactory smbSessionFactory = (SmbSessionFactory) sessionFactoryProp;
|
||||
assertEquals("localhost", TestUtils.getPropertyValue(smbSessionFactory, "host"));
|
||||
assertEquals(0, TestUtils.getPropertyValue(smbSessionFactory, "port"));
|
||||
assertEquals(23, TestUtils.getPropertyValue(messageHandler, "order"));
|
||||
|
||||
// verify subscription order
|
||||
@SuppressWarnings("unchecked")
|
||||
Set<MessageHandler> handlers = (Set<MessageHandler>) TestUtils.getPropertyValue(TestUtils.getPropertyValue(channel, "dispatcher"), "handlers");
|
||||
Iterator<MessageHandler> iterator = handlers.iterator();
|
||||
assertSame(TestUtils.getPropertyValue(ac.getBean("smbOutboundChannelAdapter2"), "handler"), iterator.next());
|
||||
assertSame(messageHandler, iterator.next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cachingByDefault() {
|
||||
ApplicationContext ac = new ClassPathXmlApplicationContext(getApplicationContextXmlFile(), this.getClass());
|
||||
Object adapter = ac.getBean("simpleAdapter");
|
||||
Object sfProperty = TestUtils.getPropertyValue(adapter, "handler.sessionFactory");
|
||||
assertEquals(CachingSessionFactory.class, sfProperty.getClass());
|
||||
Object innerSfProperty = TestUtils.getPropertyValue(sfProperty, "sessionFactory");
|
||||
assertEquals(SmbSessionFactory.class, innerSfProperty.getClass());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?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:p="http://www.springframework.org/schema/p"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:int-smb="http://www.springframework.org/schema/integration/smb"
|
||||
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.xsd
|
||||
http://www.springframework.org/schema/integration/smb http://www.springframework.org/schema/integration/smb/spring-integration-smb.xsd">
|
||||
|
||||
<bean id="smbSessionFactory"
|
||||
class="org.springframework.integration.smb.session.SmbSessionFactory"
|
||||
p:host="localhost"
|
||||
p:port="0"
|
||||
p:domain="sambaguest"
|
||||
p:username="sambaguest"
|
||||
p:password="sambaguest"
|
||||
p:shareAndDir="smb-share/"
|
||||
p:replaceFile="false"
|
||||
/>
|
||||
|
||||
<int:channel id="smbOutboundChannel" />
|
||||
|
||||
<int-smb:outbound-channel-adapter id="smbOutboundChannelAdapter"
|
||||
session-factory="smbSessionFactory"
|
||||
remote-directory="test-temp/remote-8"
|
||||
channel="smbOutboundChannel"/>
|
||||
</beans>
|
||||
@@ -0,0 +1,134 @@
|
||||
/**
|
||||
* Copyright 2002-2012 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.smb.inbound;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertNotNull;
|
||||
import static junit.framework.Assert.assertNull;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import jcifs.smb.SmbFile;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.smb.AbstractBaseTest;
|
||||
import org.springframework.integration.smb.filters.SmbRegexPatternFileListFilter;
|
||||
import org.springframework.integration.smb.session.SmbSession;
|
||||
import org.springframework.integration.smb.session.SmbSessionFactory;
|
||||
|
||||
/**
|
||||
* @author Markus Spann
|
||||
* @since 2.1.1
|
||||
*/
|
||||
public class SmbInboundRemoteFileSystemSynchronizerTest extends AbstractBaseTest {
|
||||
|
||||
private SmbSession smbSession;
|
||||
private SmbSessionFactory smbSessionFactory;
|
||||
private String testLocalDir = "test-temp/local-9/";
|
||||
private String testRemoteDir = "test-temp/remote-9/";
|
||||
|
||||
@Before
|
||||
public void prepare() {
|
||||
delete(testLocalDir);
|
||||
ensureExists(testRemoteDir);
|
||||
|
||||
smbSession = mock(SmbSession.class);
|
||||
smbSessionFactory = new TestSmbSessionFactory();
|
||||
smbSessionFactory.setHost("localhost");
|
||||
smbSessionFactory.setPort(0);
|
||||
smbSessionFactory.setDomain("");
|
||||
smbSessionFactory.setUsername("sambaguest");
|
||||
smbSessionFactory.setPassword("sambaguest");
|
||||
smbSessionFactory.setShareAndDir("smb-share/");
|
||||
smbSessionFactory.setReplaceFile(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopyFileToLocalDir() throws Exception {
|
||||
File localDirectoy = new File(testLocalDir);
|
||||
assertFileNotExists(localDirectoy);
|
||||
|
||||
SmbInboundFileSynchronizer synchronizer = spy(new SmbInboundFileSynchronizer(smbSessionFactory));
|
||||
synchronizer.setDeleteRemoteFiles(true);
|
||||
synchronizer.setRemoteDirectory(testRemoteDir);
|
||||
synchronizer.setFilter(new SmbRegexPatternFileListFilter(".*\\.test$"));
|
||||
|
||||
SmbInboundFileSynchronizingMessageSource messageSource = new SmbInboundFileSynchronizingMessageSource(synchronizer);
|
||||
messageSource.setAutoCreateLocalDirectory(true);
|
||||
|
||||
messageSource.setLocalDirectory(localDirectoy);
|
||||
messageSource.afterPropertiesSet();
|
||||
|
||||
String[] testFiles = new String[] {"a.test", "b.test"};
|
||||
|
||||
for (String testFile : testFiles) {
|
||||
Message<File> message = messageSource.receive();
|
||||
assertNotNull(message);
|
||||
assertEquals(testFile, message.getPayload().getName());
|
||||
assertFileExists(new File(testLocalDir + "/" + testFile));
|
||||
}
|
||||
|
||||
Message<File> nothing = messageSource.receive();
|
||||
assertNull(nothing);
|
||||
|
||||
// two times because on the third receive (above) the internal queue will be empty
|
||||
verify(synchronizer, times(2)).synchronizeToLocalDirectory(localDirectoy);
|
||||
}
|
||||
|
||||
class TestSmbSessionFactory extends SmbSessionFactory {
|
||||
|
||||
@Override
|
||||
protected SmbSession createSession() {
|
||||
try {
|
||||
List<SmbFile> smbFiles = new ArrayList<SmbFile>();
|
||||
for (String fileName : new File(testRemoteDir).list()) {
|
||||
SmbFile file = smbSession.createSmbFileObject(fileName);
|
||||
smbFiles.add(file);
|
||||
|
||||
doAnswer(new Answer<Object>() {
|
||||
public Object answer(InvocationOnMock _invocation) throws Throwable {
|
||||
String path = (String) _invocation.getArguments()[0];
|
||||
OutputStream os = (OutputStream) _invocation.getArguments()[1];
|
||||
writeToFile((this.getClass().getSimpleName() + " : TEST : " + path).getBytes(), os);
|
||||
return null;
|
||||
}
|
||||
}).when(smbSession).read(Mockito.eq(testRemoteDir + "/" + fileName), Mockito.any(OutputStream.class));
|
||||
}
|
||||
|
||||
when(smbSession.list(testRemoteDir)).thenReturn(smbFiles.toArray(new SmbFile[] {}));
|
||||
when(smbSession.remove(Mockito.anyString())).thenReturn(true);
|
||||
return smbSession;
|
||||
|
||||
} catch (Exception _ex) {
|
||||
throw new RuntimeException("Failed to create mock session.", _ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
* Copyright 2002-2012 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.smb.outbound;
|
||||
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import jcifs.smb.SmbFile;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.springframework.expression.common.LiteralExpression;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.file.FileNameGenerator;
|
||||
import org.springframework.integration.file.remote.handler.FileTransferringMessageHandler;
|
||||
import org.springframework.integration.message.GenericMessage;
|
||||
import org.springframework.integration.smb.AbstractBaseTest;
|
||||
import org.springframework.integration.smb.session.SmbSession;
|
||||
import org.springframework.integration.smb.session.SmbSessionFactory;
|
||||
|
||||
/**
|
||||
* @author Markus Spann
|
||||
*/
|
||||
public class SmbSendingMessageHandlerTest extends AbstractBaseTest {
|
||||
|
||||
private SmbSession smbSession;
|
||||
private SmbSessionFactory smbSessionFactory;
|
||||
|
||||
@Before
|
||||
public void prepare() {
|
||||
smbSession = mock(SmbSession.class);
|
||||
smbSessionFactory = new TestSmbSessionFactory();
|
||||
smbSessionFactory.setHost("localhost");
|
||||
smbSessionFactory.setPort(0);
|
||||
smbSessionFactory.setDomain("");
|
||||
smbSessionFactory.setUsername("sambaguest");
|
||||
smbSessionFactory.setPassword("sambaguest");
|
||||
smbSessionFactory.setShareAndDir("smb-share/");
|
||||
smbSessionFactory.setReplaceFile(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleFileContentMessage() throws Exception {
|
||||
File file = createNewFile("remote-target-dir/handlerContent.test");
|
||||
FileTransferringMessageHandler<?> handler = new FileTransferringMessageHandler<SmbFile>(smbSessionFactory);
|
||||
handler.setRemoteDirectoryExpression(new LiteralExpression("remote-target-dir"));
|
||||
handler.setFileNameGenerator(new FileNameGenerator() {
|
||||
public String generateFileName(Message<?> message) {
|
||||
return "handlerContent.test";
|
||||
}
|
||||
});
|
||||
handler.afterPropertiesSet();
|
||||
handler.handleMessage(new GenericMessage<String>("hello"));
|
||||
assertFileExists(file);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleFileAsByte() throws Exception {
|
||||
File file = createNewFile("remote-target-dir/handlerContent.test");
|
||||
FileTransferringMessageHandler<?> handler = new FileTransferringMessageHandler<SmbFile>(smbSessionFactory);
|
||||
handler.setRemoteDirectoryExpression(new LiteralExpression("remote-target-dir"));
|
||||
handler.setFileNameGenerator(new FileNameGenerator() {
|
||||
public String generateFileName(Message<?> message) {
|
||||
return "handlerContent.test";
|
||||
}
|
||||
});
|
||||
handler.afterPropertiesSet();
|
||||
handler.handleMessage(new GenericMessage<byte[]>("hello".getBytes()));
|
||||
assertFileExists(file);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleFileMessage() throws Exception {
|
||||
File file = createNewFile("remote-target-dir/template.mf.test");
|
||||
FileTransferringMessageHandler<?> handler = new FileTransferringMessageHandler<SmbFile>(smbSessionFactory);
|
||||
handler.setRemoteDirectoryExpression(new LiteralExpression("remote-target-dir"));
|
||||
handler.setFileNameGenerator(new FileNameGenerator() {
|
||||
public String generateFileName(Message<?> message) {
|
||||
return ((File) message.getPayload()).getName() + ".test";
|
||||
}
|
||||
});
|
||||
handler.afterPropertiesSet();
|
||||
handler.handleMessage(new GenericMessage<File>(new File("template.mf")));
|
||||
assertFileExists(file);
|
||||
}
|
||||
|
||||
class TestSmbSessionFactory extends SmbSessionFactory {
|
||||
|
||||
@Override
|
||||
protected SmbSession createSession() {
|
||||
try {
|
||||
when(smbSession.remove(Mockito.anyString())).thenReturn(true);
|
||||
when(smbSession.list(Mockito.anyString())).thenReturn(new SmbFile[0]);
|
||||
|
||||
doAnswer(new Answer<Object>() {
|
||||
public Object answer(InvocationOnMock _invocation) throws Throwable {
|
||||
String path = (String) _invocation.getArguments()[0];
|
||||
OutputStream os = (OutputStream) _invocation.getArguments()[1];
|
||||
writeToFile((this.getClass().getSimpleName() + " : TEST : " + path).getBytes(), os);
|
||||
return null;
|
||||
}
|
||||
}).when(smbSession).read(Mockito.anyString(), Mockito.any(OutputStream.class));
|
||||
|
||||
doAnswer(new Answer<Object>() {
|
||||
public Object answer(InvocationOnMock _invocation) throws Throwable {
|
||||
InputStream inputStream = (InputStream) _invocation.getArguments()[0];
|
||||
String path = (String) _invocation.getArguments()[1];
|
||||
writeToFile(inputStream, path);
|
||||
return null;
|
||||
}
|
||||
|
||||
}).when(smbSession).write(Mockito.any(InputStream.class), Mockito.anyString());
|
||||
|
||||
// when(smbSession.write(Mockito.any(byte[].class), Mockito.anyString())).thenReturn(null);
|
||||
// when(smbSession.write(Mockito.any(File.class), Mockito.anyString())).thenReturn(null);
|
||||
|
||||
doAnswer(new Answer<Object>() {
|
||||
public Object answer(InvocationOnMock _invocation) throws Throwable {
|
||||
String path = (String) _invocation.getArguments()[0];
|
||||
new File(path).mkdirs();
|
||||
return null;
|
||||
}
|
||||
}).when(smbSession).mkdir(Mockito.anyString());
|
||||
|
||||
doAnswer(new Answer<Object>() {
|
||||
public Object answer(InvocationOnMock _invocation) throws Throwable {
|
||||
String pathFrom = (String) _invocation.getArguments()[0];
|
||||
String pathTo = (String) _invocation.getArguments()[1];
|
||||
new File(pathFrom).renameTo(new File(pathTo));
|
||||
return null;
|
||||
}
|
||||
}).when(smbSession).rename(Mockito.anyString(), Mockito.anyString());
|
||||
|
||||
doNothing().when(smbSession).close();
|
||||
when(smbSession.isOpen()).thenReturn(true);
|
||||
return smbSession;
|
||||
|
||||
} catch (Exception _ex) {
|
||||
throw new RuntimeException("Failed to create mock session.", _ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Copyright 2002-2012 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.smb.session;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class MySmbSessionTest {
|
||||
|
||||
@Test
|
||||
public void testRemove() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRead() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrite() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMkdir() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRename() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClose() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsOpen() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
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=DEBUG
|
||||
log4j.category.org.springframework.integration.file=DEBUG
|
||||
16
spring-integration-smb/template.mf
Normal file
16
spring-integration-smb/template.mf
Normal file
@@ -0,0 +1,16 @@
|
||||
Bundle-SymbolicName: org.springframework.integration.smb
|
||||
Bundle-Name: Spring Integration SMB Support
|
||||
Bundle-Vendor: SpringSource
|
||||
Bundle-Version: ${version}
|
||||
Bundle-ManifestVersion: 2
|
||||
Import-Template:
|
||||
org.apache.commons.logging;version="[1.1.1, 2.0.0)",
|
||||
org.apache.commons.net.*;version="[2.0.0, 3.0.0)",
|
||||
org.springframework.integration.*;version="[2.0.5, 2.0.6)",
|
||||
org.springframework.beans.*;version="[3.0.5, 4.0.0)",
|
||||
org.springframework.context;version="[3.0.5, 4.0.0)",
|
||||
org.springframework.core.*;version="[3.0.5, 4.0.0)",
|
||||
org.springframework.scheduling.*;version="[3.0.5, 4.0.0)",
|
||||
org.springframework.util;version="[3.0.5, 4.0.0)",
|
||||
javax.*;version="0",
|
||||
org.w3c.dom.*;version="0"
|
||||
Reference in New Issue
Block a user