diff --git a/spring-integration-smb/src/main/java/org/springframework/integration/smb/config/SmbNamespaceHandler.java b/spring-integration-smb/src/main/java/org/springframework/integration/smb/config/SmbNamespaceHandler.java
index fd28a2e826..ff9348f5dd 100644
--- a/spring-integration-smb/src/main/java/org/springframework/integration/smb/config/SmbNamespaceHandler.java
+++ b/spring-integration-smb/src/main/java/org/springframework/integration/smb/config/SmbNamespaceHandler.java
@@ -23,6 +23,7 @@ import org.springframework.integration.config.xml.AbstractIntegrationNamespaceHa
*
* @author Markus Spann
* @author Artem Bilan
+ * @author Gregory Bragg
*
* @since 6.0
*/
@@ -30,7 +31,9 @@ public class SmbNamespaceHandler extends AbstractIntegrationNamespaceHandler {
public void init() {
registerBeanDefinitionParser("inbound-channel-adapter", new SmbInboundChannelAdapterParser());
+ registerBeanDefinitionParser("inbound-streaming-channel-adapter", new SmbStreamingInboundChannelAdapterParser());
registerBeanDefinitionParser("outbound-channel-adapter", new SmbOutboundChannelAdapterParser());
+ registerBeanDefinitionParser("outbound-gateway", new SmbOutboundGatewayParser());
}
}
diff --git a/spring-integration-smb/src/main/java/org/springframework/integration/smb/config/SmbOutboundGatewayParser.java b/spring-integration-smb/src/main/java/org/springframework/integration/smb/config/SmbOutboundGatewayParser.java
new file mode 100644
index 0000000000..be69e637f8
--- /dev/null
+++ b/spring-integration-smb/src/main/java/org/springframework/integration/smb/config/SmbOutboundGatewayParser.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2022 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
+ *
+ * https://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.AbstractRemoteFileOutboundGatewayParser;
+import org.springframework.integration.file.remote.RemoteFileOperations;
+import org.springframework.integration.smb.filters.SmbRegexPatternFileListFilter;
+import org.springframework.integration.smb.filters.SmbSimplePatternFileListFilter;
+import org.springframework.integration.smb.outbound.SmbOutboundGateway;
+import org.springframework.integration.smb.session.SmbRemoteFileTemplate;
+
+/**
+ * Parser for the SMB 'outbound-gateway' element.
+ *
+ * @author Gregory Bragg
+ *
+ * @since 6.0
+ */
+public class SmbOutboundGatewayParser extends AbstractRemoteFileOutboundGatewayParser {
+
+ @Override
+ public String getGatewayClassName() {
+ return SmbOutboundGateway.class.getName();
+ }
+
+ @Override
+ protected String getSimplePatternFileListFilterClassName() {
+ return SmbSimplePatternFileListFilter.class.getName();
+ }
+
+ @Override
+ protected String getRegexPatternFileListFilterClassName() {
+ return SmbRegexPatternFileListFilter.class.getName();
+ }
+
+ @Override
+ protected Class extends RemoteFileOperations>> getTemplateClass() {
+ return SmbRemoteFileTemplate.class;
+ }
+
+}
diff --git a/spring-integration-smb/src/main/java/org/springframework/integration/smb/config/SmbStreamingInboundChannelAdapterParser.java b/spring-integration-smb/src/main/java/org/springframework/integration/smb/config/SmbStreamingInboundChannelAdapterParser.java
new file mode 100644
index 0000000000..03472b2cdd
--- /dev/null
+++ b/spring-integration-smb/src/main/java/org/springframework/integration/smb/config/SmbStreamingInboundChannelAdapterParser.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2022 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
+ *
+ * https://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.core.MessageSource;
+import org.springframework.integration.file.config.AbstractRemoteFileStreamingInboundChannelAdapterParser;
+import org.springframework.integration.file.filters.AbstractPersistentAcceptOnceFileListFilter;
+import org.springframework.integration.file.filters.FileListFilter;
+import org.springframework.integration.file.remote.RemoteFileOperations;
+import org.springframework.integration.smb.filters.SmbPersistentAcceptOnceFileListFilter;
+import org.springframework.integration.smb.filters.SmbRegexPatternFileListFilter;
+import org.springframework.integration.smb.filters.SmbSimplePatternFileListFilter;
+import org.springframework.integration.smb.inbound.SmbStreamingMessageSource;
+import org.springframework.integration.smb.session.SmbRemoteFileTemplate;
+
+/**
+ * Parser for the SMB 'inbound-streaming-channel-adapter' element.
+ *
+ * @author Gregory Bragg
+ *
+ * @since 6.0
+ */
+public class SmbStreamingInboundChannelAdapterParser extends AbstractRemoteFileStreamingInboundChannelAdapterParser {
+
+ @Override
+ protected Class extends RemoteFileOperations>> getTemplateClass() {
+ return SmbRemoteFileTemplate.class;
+ }
+
+ @Override
+ protected Class extends MessageSource>> getMessageSourceClass() {
+ return SmbStreamingMessageSource.class;
+ }
+
+ @Override
+ protected Class extends FileListFilter>> getSimplePatternFileListFilterClass() {
+ return SmbSimplePatternFileListFilter.class;
+ }
+
+ @Override
+ protected Class extends FileListFilter>> getRegexPatternFileListFilterClass() {
+ return SmbRegexPatternFileListFilter.class;
+ }
+
+ @Override
+ protected Class extends AbstractPersistentAcceptOnceFileListFilter>> getPersistentAcceptOnceFileListFilterClass() {
+ return SmbPersistentAcceptOnceFileListFilter.class;
+ }
+
+}
diff --git a/spring-integration-smb/src/main/resources/org/springframework/integration/smb/config/spring-integration-smb.xsd b/spring-integration-smb/src/main/resources/org/springframework/integration/smb/config/spring-integration-smb.xsd
index 6a85beab96..7a4b257edf 100644
--- a/spring-integration-smb/src/main/resources/org/springframework/integration/smb/config/spring-integration-smb.xsd
+++ b/spring-integration-smb/src/main/resources/org/springframework/integration/smb/config/spring-integration-smb.xsd
@@ -3,77 +3,49 @@
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:tool="http://www.springframework.org/schema/tool"
xmlns:integration="http://www.springframework.org/schema/integration"
+ xmlns:int-file="http://www.springframework.org/schema/integration/file"
targetNamespace="http://www.springframework.org/schema/integration/smb"
- elementFormDefault="qualified"
- attributeFormDefault="unqualified">
+ elementFormDefault="qualified">
+ schemaLocation="https://www.springframework.org/schema/integration/spring-integration.xsd"/>
+
-
-
+
-
+
-
+
-
+
-
-
+
+
-
-
-
- Identifies directory path (e.g., "/temp/mytransfers/")
- where file will be transferred to.
-
-
-
-
-
-
- Allows you to provide SpEL expression which will
- compute directory path where file will be
- transferred to (e.g., "headers.['remote_dir'] + '/myTransfers'");
-
-
-
-
-
-
- Allows you to provide remote file/directory separator
- character. DEFAULT: '/'
-
-
-
-
-
-
- Extension used when uploading files. We change
- it right after we know it's uploaded.
-
-
-
Allows you to specify a reference to a
- [org.springframework.integration.file.FileNameGenerator] bean.
+ 'org.springframework.integration.file.FileNameGenerator' bean.
@@ -87,7 +59,7 @@
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'");
+ payload is java.io.File "payload.getName() + '.transferred'");
@@ -106,6 +78,14 @@
+
+
+
+ Allows you to specify Charset (e.g., US-ASCII, ISO-8859-1, UTF-8).
+ [UTF-8] is the default.
+
+
+
@@ -116,36 +96,17 @@
-
-
+
-
+
-
-
-
-
- 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.)
-
-
-
-
-
-
- Allows you to provide Regular Expression to determine
- the file names that needs to be scanned. (e.g., "f[o]+\.txt" etc.)
-
-
-
-
-
-
-
-
-
-
-
- Allows you to specify a reference to
- [org.springframework.integration.file.filters.FileListFilter] bean.
-
-
-
-
-
-
- Extension used when downloading files. We change
- it right after we know it's downloaded.
-
-
-
-
-
-
- Identifies directory path (e.g., "/temp/mytransfers")
- where file will be transferred FROM.
-
-
-
-
-
-
- Allows you to provide remote file/directory separator
- character. DEFAULT: '/'
-
-
-
+ type="org.springframework.integration.file.filters.FileListFilter"/>
@@ -229,7 +153,7 @@
-
+
Specify whether to delete the remote source file after copying.
@@ -237,33 +161,476 @@
+
+
+
+ Allows you to specify Charset (e.g., US-ASCII, ISO-8859-1, UTF-8).
+ [UTF-8] is the default.
+
+
+
+
-
+
+
+
+ Configures a 'SourcePollingChannelAdapter' Endpoint for the
+ 'org.springframework.integration.smb.inbound.SmbInboundStreamingMessageSource'.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Configures a Consumer Endpoint for the
+ 'org.springframework.integration.smb.outbound.SmbOutboundGateway'
+ used to issue SMB commands.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SMB command.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The 'MessageSessionCallback' bean reference to perform custom operation(s) on 'Session'
+ with 'requestMessage'.
+
+
+
+
+
+
+ SMB command options; for ls, -1 means just
+ return the file names
+ (otherwise file
+ metadata is returned, -dirs
+ means include directories (not included by
+ default),
+ -links means
+ include links (not included by default); for get, -P means
+ preserve
+ timestamp from remote file.
+
+
+
+
+
+
+ SpEL expression representing the path in the
+ command (e.g. ls path to list the files in directory path).
+
+
+
+
+
+
+ SpEL expression representing the path for the
+ new filename when using the 'mv' command.
+ Defaults to "headers.['file_renameTo']".
+
+
+
+
+
+
+
+
+
+
+
+ Identifies the request channel attached to this gateway.
+
+
+
+
+
+
+
+
+
+
+
+ Identifies the reply channel attached to this gateway.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Allows you to specify a reference to
+ [org.springframework.integration.file.filters.FileListFilter]
+ bean. This filter acts against the remote server view when using the 'ls'
+ or 'mget' commands.
+ Only one of 'filter', 'filename-pattern', or 'filename-regex' is allowed.
+
+
+
+
+
+
+
+
+
+
+
+ Allows you to provide file name pattern to
+ determine the file names retrieved by the 'ls' and 'mget' commands
+ and is based on simple pattern matching algorithm (e.g., "*.txt, fo*.txt" etc.)
+ Only one of 'filter', 'filename-pattern', or 'filename-regex' is allowed.
+
+
+
+
+
+
+ Allows you to provide Regular Expression to
+ determine the file names retrieved by the 'ls' and 'mget' commands.
+ (e.g., "f[o]+\.txt" etc.)
+ Only one of 'filter', 'filename-pattern', or 'filename-regex' is allowed.
+
+
+
+
+
+
+
+
+
+
+
+ Allows you to specify a reference to
+ [org.springframework.integration.file.filters.FileListFilter]
+ bean. This filter acts on the local file system when using the 'mput' command.
+ Only one of 'mput-filter', 'mput-pattern', or 'mput-regex' is allowed.
+
+
+
+
+
+
+
+
+
+
+
+ Allows you to provide file name pattern to
+ determine the file names sent by the 'mput' command
+ and is based on simple pattern matching algorithm (e.g., "*.txt, fo*.txt" etc.)
+ Only one of 'mput-filter', 'mput-pattern', or 'mput-regex' is allowed.
+
+
+
+
+
+
+ Allows you to provide Regular Expression to
+ determine the file names sent by the 'mput' command (e.g., "f[o]+\.txt" etc.)
+ Only one of 'mput-filter', 'mput-pattern', or 'mput-regex' is allowed.
+
+
+
+
+
+
+ Allows you to provide a SpEL expression to
+ generate the file name of the local (transferred) file.
+ The root object of the SpEL
+ evaluation is the request Message, but the name of the original
+ remote file is also provided as the 'remoteFileName' variable.
+ For example, a valid expression would be:
+ "#remoteFileName.toUpperCase() + headers.foo".
+ Only used with 'get' and 'mget' commands.
+
+
+
+
+
+
+ Identifies directory path (e.g., "/local/mytransfers") where file will be
+ transferred TO.
+ This attribute is mutually exclusive with 'local-directory-expression'.
+
+
+
+
+
+
+ Specifies SpEL expression to
+ generate the directory path where file will be
+ transferred TO, when using 'get' and 'mget' commands.
+ The root object of the SpEL evaluation is the request Message,
+ but the name of the source
+ remote directory is also provided as the 'remoteDirectory' variable.
+ For example, a valid expression might be:
+ "'/local/' + #remoteDirectory.toUpperCase() + headers.foo".
+ Only used with 'get' and 'mget' commands.
+ This attribute is mutually exclusive with 'local-directory'.
+
+
+
+
+
+
+ Tells this adapter if local directory must be auto-created if it doesn't exist.
+ Default is TRUE.
+
+
+
+
+
+
+ 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.
+
+
+
+
+
+
+ Specify whether this outbound gateway must return a non-null value. This value is
+ 'true' by default, and a ReplyRequiredException will be thrown when
+ the underlying service returns a null value.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Identifies channel attached to this adapter.
+ The channel to which messages will be sent by this adapter.
+
+
+
+
+
+
+ Allows you to provide a file name pattern to
+ determine the file names that need to be scanned.
+ This is based on simple pattern matching (e.g., "*.txt, fo*.txt" etc.)
+
+
+
+
+
+
+ Allows you to provide a Regular Expression to
+ determine the file names that need to be scanned (e.g., "f[o]+\.txt" etc.)
+
+
+
+
+
+
+
+
+
+
+
+ Allows you to specify a reference to a
+ [org.springframework.integration.file.filters.FileListFilter]
+ bean. This filter is applied to files on the remote server and
+ only files that pass the filter are retrieved.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Identifies channel attached to this adapter.
+ The channel to which messages will be sent by this adapter.
+
+
+
+
+
+
+ Identifies the remote temporary directory path (e.g., "/remote/temp/mytransfers")
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
- Allows you to specify Charset (e.g., US-ASCII, ISO-8859-1, UTF-8).
- [UTF-8] is the default.
+ Allows you to provide remote file/directory separator character. DEFAULT: '/'
-
+
+
+
+ Identifies the remote directory path (e.g., "/remote/mytransfers")
+ Mutually exclusive with 'remote-directory-expression'.
+
+
+
+
+
+
+ Specify a SpEL expression which
+ will be used to evaluate the directory
+ path to where the files will be transferred
+ (e.g., "headers.['remote_dir'] + '/myTransfers'" for outbound endpoints)
+ There is no root object (message) for inbound endpoints
+ (e.g., "@someBean.fetchDirectory");
+
+
+
+
+
+
+
+
+ Extension used when downloading files. We change it right after we know it's downloaded.
+
+
+
+
+
diff --git a/spring-integration-smb/src/test/java/org/springframework/integration/smb/config/SmbOutboundGatewayParserTests-context.xml b/spring-integration-smb/src/test/java/org/springframework/integration/smb/config/SmbOutboundGatewayParserTests-context.xml
new file mode 100644
index 0000000000..6652cee18d
--- /dev/null
+++ b/spring-integration-smb/src/test/java/org/springframework/integration/smb/config/SmbOutboundGatewayParserTests-context.xml
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-smb/src/test/java/org/springframework/integration/smb/config/SmbOutboundGatewayParserTests.java b/spring-integration-smb/src/test/java/org/springframework/integration/smb/config/SmbOutboundGatewayParserTests.java
new file mode 100644
index 0000000000..18fab7a55e
--- /dev/null
+++ b/spring-integration-smb/src/test/java/org/springframework/integration/smb/config/SmbOutboundGatewayParserTests.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2002-2022 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
+ *
+ * https://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 org.assertj.core.api.Assertions.assertThat;
+
+import java.lang.reflect.Method;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.junit.jupiter.api.Test;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.expression.Expression;
+import org.springframework.integration.endpoint.AbstractEndpoint;
+import org.springframework.integration.file.FileNameGenerator;
+import org.springframework.integration.file.filters.RegexPatternFileListFilter;
+import org.springframework.integration.file.filters.SimplePatternFileListFilter;
+import org.springframework.integration.file.remote.gateway.AbstractRemoteFileOutboundGateway.Command;
+import org.springframework.integration.file.remote.gateway.AbstractRemoteFileOutboundGateway.Option;
+import org.springframework.integration.file.remote.session.CachingSessionFactory;
+import org.springframework.integration.handler.advice.AbstractRequestHandlerAdvice;
+import org.springframework.integration.smb.outbound.SmbOutboundGateway;
+import org.springframework.integration.test.util.TestUtils;
+import org.springframework.messaging.Message;
+import org.springframework.messaging.support.GenericMessage;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
+import org.springframework.util.ReflectionUtils;
+
+/**
+ * Unit tests follow original logic for testing SFTP module,
+ * adapted for SMB module.
+ *
+ * @author Gary Russell
+ * @author Gunnar Hillert
+ * @author Artem Bilan
+ * @author Gregory Bragg
+ *
+ * @since 6.0
+ */
+@SpringJUnitConfig
+@DirtiesContext
+public class SmbOutboundGatewayParserTests {
+
+ @Autowired
+ AbstractEndpoint gateway1;
+
+ @Autowired
+ AbstractEndpoint gateway2;
+
+ @Autowired
+ AbstractEndpoint gateway3;
+
+ @Autowired
+ AbstractEndpoint gateway4;
+
+ @Autowired
+ AbstractEndpoint advised;
+
+ @Autowired
+ AbstractEndpoint noExpressionLS;
+
+ @Autowired
+ AbstractEndpoint noExpressionPUT;
+
+ @Autowired
+ AbstractEndpoint noExpressionGET;
+
+ @Autowired
+ FileNameGenerator generator;
+
+ private static volatile int adviceCalled;
+
+ @Test
+ public void testGateway1() {
+ SmbOutboundGateway gateway = TestUtils.getPropertyValue(gateway1,
+ "handler", SmbOutboundGateway.class);
+ assertThat(TestUtils.getPropertyValue(gateway, "remoteFileTemplate.remoteFileSeparator")).isEqualTo("X");
+ assertThat(TestUtils.getPropertyValue(gateway, "remoteFileTemplate.sessionFactory")).isNotNull();
+ assertThat(TestUtils.getPropertyValue(gateway, "outputChannel")).isNotNull();
+ assertThat(TestUtils.getPropertyValue(gateway, "localDirectoryExpression.literalValue"))
+ .isEqualTo("local-test-dir");
+ assertThat((Boolean) TestUtils.getPropertyValue(gateway, "autoCreateLocalDirectory")).isFalse();
+ assertThat(TestUtils.getPropertyValue(gateway, "requiresReply", Boolean.class)).isTrue();
+ assertThat(TestUtils.getPropertyValue(gateway, "filter")).isNotNull();
+ assertThat(TestUtils.getPropertyValue(gateway, "command")).isEqualTo(Command.LS);
+ @SuppressWarnings("unchecked")
+ Set