GH-9211: Fix SmbSession.get()
Fixes: #9211
The `AbstractRemoteFileOutboundGateway.get()` uses `Session.list()` for the provided remote file name.
The `SmbSession` does not support listing for a single file.
* Add logic into `SmbSession.list()` similar to `SftpSession.list()` to list a single remote file
on the provided path
(cherry picked from commit 91de12c786)
This commit is contained in:
committed by
Spring Builds
parent
c80e47d1e6
commit
0959590d80
@@ -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.
|
||||
*
|
||||
* <p>
|
||||
* SMB is an application-layer network protocol that manages shared access to files, printers
|
||||
* and other networked resources.
|
||||
*
|
||||
* <p>
|
||||
* See <a href="https://en.wikipedia.org/wiki/Server_Message_Block">Server Message Block</a>
|
||||
* for more details.
|
||||
*
|
||||
@@ -60,7 +61,7 @@ public class SmbSession implements Session<SmbFile> {
|
||||
|
||||
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<SmbFile> {
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user