diff --git a/spring-integration-smb/src/main/java/org/springframework/integration/smb/session/SmbSession.java b/spring-integration-smb/src/main/java/org/springframework/integration/smb/session/SmbSession.java
index c60a9322e0..6212d10dba 100644
--- a/spring-integration-smb/src/main/java/org/springframework/integration/smb/session/SmbSession.java
+++ b/spring-integration-smb/src/main/java/org/springframework/integration/smb/session/SmbSession.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 the original author or authors.
+ * Copyright 2012-2024 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.
@@ -23,6 +23,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
+import java.nio.file.FileSystems;
import java.util.Arrays;
import jcifs.smb.SmbException;
@@ -39,10 +40,10 @@ 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 Server Message Block
* for more details.
*
@@ -60,7 +61,7 @@ public class SmbSession implements Session {
private static final LogAccessor logger = new LogAccessor(SmbSession.class);
- private static final String FILE_SEPARATOR = System.getProperty("file.separator");
+ private static final String FILE_SEPARATOR = FileSystems.getDefault().getSeparator();
private static final String SMB_FILE_SEPARATOR = "/";
@@ -120,31 +121,42 @@ public class SmbSession implements Session {
/**
* Return 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
+ * @param remotePath path to a remote directory or remote file path
* @return array of SmbFile objects
* @throws IOException on error conditions returned by a CIFS server or if the remote resource is not a directory.
*/
@Override
- public SmbFile[] list(String _path) throws IOException {
- try {
- SmbFile smbDir = createSmbDirectoryObject(_path);
- if (!smbDir.exists()) {
- logger.warn(() -> "Remote directory [" + _path + "] does not exist. Cannot list resources.");
- return new SmbFile[0];
+ public SmbFile[] list(String remotePath) throws IOException {
+ SmbFile[] files;
+ int lastIndex = StringUtils.hasText(remotePath) ? remotePath.lastIndexOf('/') : 0;
+ String remoteFileName = lastIndex > 0 ? remotePath.substring(lastIndex + 1) : null;
+ if (StringUtils.hasText(remoteFileName)) {
+ SmbFile remoteFile = createSmbFileObject(remotePath);
+ if (!remoteFile.isFile()) {
+ throw new IOException("[" + remotePath + "] is not a file.");
}
- else if (!smbDir.isDirectory()) {
- throw new IOException("[" + _path + "] is not a directory. Cannot list resources.");
+ files = new SmbFile[] {remoteFile};
+ }
+ else {
+ try {
+ SmbFile smbDir = createSmbDirectoryObject(remotePath);
+ if (!smbDir.exists()) {
+ logger.warn(() -> "Remote directory [" + remotePath + "] does not exist. Cannot list resources.");
+ return new SmbFile[0];
+ }
+ else if (!smbDir.isDirectory()) {
+ throw new IOException("[" + remotePath + "] is not a directory. Cannot list resources.");
+ }
+
+ files = smbDir.listFiles();
+ }
+ catch (SmbException _ex) {
+ throw new IOException("Failed to list in [" + remotePath + "].", _ex);
}
-
- SmbFile[] files = smbDir.listFiles();
-
- logListedFiles(_path, files);
-
- return files;
- }
- catch (SmbException _ex) {
- throw new IOException("Failed to list in [" + _path + "].", _ex);
}
+ logListedFiles(remotePath, files);
+
+ return files;
}
/**
diff --git a/spring-integration-smb/src/test/java/org/springframework/integration/smb/dsl/SmbTests.java b/spring-integration-smb/src/test/java/org/springframework/integration/smb/dsl/SmbTests.java
index cfc4800b70..d1ea9ea548 100644
--- a/spring-integration-smb/src/test/java/org/springframework/integration/smb/dsl/SmbTests.java
+++ b/spring-integration-smb/src/test/java/org/springframework/integration/smb/dsl/SmbTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022-2023 the original author or authors.
+ * Copyright 2022-2024 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.
@@ -164,7 +164,7 @@ public class SmbTests extends SmbTestSupport {
}
@Test
- public void testSmbOutboundFlow() {
+ public void testSmbOutboundFlow() throws SmbException {
IntegrationFlow flow = f -> f
.handle(Smb.outboundAdapter(sessionFactory(), FileExistsMode.REPLACE)
.useTemporaryFileName(false)
@@ -181,18 +181,13 @@ public class SmbTests extends SmbTestSupport {
SmbFile[] files = template.execute(session ->
session.list(getTargetRemoteDirectory().getName()));
assertThat(files).hasSize(1);
- try {
- assertThat(files[0].length()).isEqualTo(3);
- }
- catch (SmbException se) {
- se.printStackTrace();
- }
+ assertThat(files[0].length()).isEqualTo(3);
registration.destroy();
}
@Test
- public void testSmbOutboundFlowWithSmbRemoteTemplate() {
+ public void testSmbOutboundFlowWithSmbRemoteTemplate() throws SmbException {
SmbRemoteFileTemplate smbTemplate = new SmbRemoteFileTemplate(sessionFactory());
IntegrationFlow flow = f -> f
.handle(Smb.outboundAdapter(smbTemplate)
@@ -209,18 +204,13 @@ public class SmbTests extends SmbTestSupport {
SmbFile[] files = smbTemplate.execute(session ->
session.list(getTargetRemoteDirectory().getName()));
assertThat(files).hasSize(1);
- try {
- assertThat(files[0].length()).isEqualTo(3);
- }
- catch (SmbException se) {
- se.printStackTrace();
- }
+ assertThat(files[0].length()).isEqualTo(3);
registration.destroy();
}
@Test
- public void testSmbOutboundFlowWithSmbRemoteTemplateAndMode() {
+ public void testSmbOutboundFlowWithSmbRemoteTemplateAndMode() throws SmbException {
SmbRemoteFileTemplate smbTemplate = new SmbRemoteFileTemplate(sessionFactory());
IntegrationFlow flow = f -> f
.handle(Smb.outboundAdapter(smbTemplate, FileExistsMode.APPEND)
@@ -242,18 +232,33 @@ public class SmbTests extends SmbTestSupport {
SmbFile[] files = smbTemplate.execute(session ->
session.list(getTargetRemoteDirectory().getName()));
assertThat(files).hasSize(1);
- try {
- assertThat(files[0].length()).isEqualTo(9);
- }
- catch (SmbException se) {
- se.printStackTrace();
- }
+ assertThat(files[0].length()).isEqualTo(9);
registration.destroy();
}
@Test
public void testSmbGetFlow() {
+ QueueChannel out = new QueueChannel();
+ IntegrationFlow flow = f -> f
+ .handle(
+ Smb.outboundGateway(sessionFactory(), AbstractRemoteFileOutboundGateway.Command.GET, "payload")
+ .localDirectoryExpression("'" + getTargetLocalDirectoryName() + "'"))
+ .channel(out);
+ IntegrationFlowRegistration registration = this.flowContext.registration(flow).register();
+ String fileName = "smbSource/subSmbSource/subSmbSource2.txt";
+ registration.getInputChannel().send(new GenericMessage<>(fileName));
+ Message> result = out.receive(10_000);
+ assertThat(result).isNotNull();
+
+ File sfis = (File) result.getPayload();
+ assertThat(sfis).hasFileName("subSmbSource2.txt");
+
+ registration.destroy();
+ }
+
+ @Test
+ public void testSmbGetStreamFlow() throws IOException {
QueueChannel out = new QueueChannel();
IntegrationFlow flow = f -> f
.handle(
@@ -271,14 +276,10 @@ public class SmbTests extends SmbTestSupport {
Message> result = out.receive(10_000);
assertThat(result).isNotNull();
- SmbFileInputStream sfis = (SmbFileInputStream) result.getPayload();
- assertThat(sfis).isNotNull();
+ try (SmbFileInputStream sfis = (SmbFileInputStream) result.getPayload()) {
+ assertThat(sfis).isNotNull();
+ }
- try {
- sfis.close();
- }
- catch (IOException ioe) {
- }
registration.destroy();
}