Skip to content

Commit 0959590

Browse files
artembilanspring-builds
authored andcommitted
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 91de12c)
1 parent c80e47d commit 0959590

File tree

2 files changed

+64
-51
lines changed
  • spring-integration-smb/src

2 files changed

+64
-51
lines changed

spring-integration-smb/src/main/java/org/springframework/integration/smb/session/SmbSession.java

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@
2323
import java.io.InputStream;
2424
import java.io.OutputStream;
2525
import java.net.URL;
26+
import java.nio.file.FileSystems;
2627
import java.util.Arrays;
2728

2829
import jcifs.smb.SmbException;
@@ -39,10 +40,10 @@
3940
* Implementation of the {@link Session} interface for Server Message Block (SMB)
4041
* also known as Common Internet File System (CIFS). The Samba project set out to
4142
* create non-Windows implementations of SMB. Often Samba is thus used synonymously to SMB.
42-
*
43+
* <p>
4344
* SMB is an application-layer network protocol that manages shared access to files, printers
4445
* and other networked resources.
45-
*
46+
* <p>
4647
* See <a href="https://en.wikipedia.org/wiki/Server_Message_Block">Server Message Block</a>
4748
* for more details.
4849
*
@@ -60,7 +61,7 @@ public class SmbSession implements Session<SmbFile> {
6061

6162
private static final LogAccessor logger = new LogAccessor(SmbSession.class);
6263

63-
private static final String FILE_SEPARATOR = System.getProperty("file.separator");
64+
private static final String FILE_SEPARATOR = FileSystems.getDefault().getSeparator();
6465

6566
private static final String SMB_FILE_SEPARATOR = "/";
6667

@@ -120,31 +121,42 @@ public boolean remove(String _path) throws IOException {
120121
/**
121122
* Return the contents of the specified SMB resource as an array of SmbFile objects.
122123
* In case the remote resource does not exist, an empty array is returned.
123-
* @param _path path to a remote directory
124+
* @param remotePath path to a remote directory or remote file path
124125
* @return array of SmbFile objects
125126
* @throws IOException on error conditions returned by a CIFS server or if the remote resource is not a directory.
126127
*/
127128
@Override
128-
public SmbFile[] list(String _path) throws IOException {
129-
try {
130-
SmbFile smbDir = createSmbDirectoryObject(_path);
131-
if (!smbDir.exists()) {
132-
logger.warn(() -> "Remote directory [" + _path + "] does not exist. Cannot list resources.");
133-
return new SmbFile[0];
134-
}
135-
else if (!smbDir.isDirectory()) {
136-
throw new IOException("[" + _path + "] is not a directory. Cannot list resources.");
129+
public SmbFile[] list(String remotePath) throws IOException {
130+
SmbFile[] files;
131+
int lastIndex = StringUtils.hasText(remotePath) ? remotePath.lastIndexOf('/') : 0;
132+
String remoteFileName = lastIndex > 0 ? remotePath.substring(lastIndex + 1) : null;
133+
if (StringUtils.hasText(remoteFileName)) {
134+
SmbFile remoteFile = createSmbFileObject(remotePath);
135+
if (!remoteFile.isFile()) {
136+
throw new IOException("[" + remotePath + "] is not a file.");
137137
}
138-
139-
SmbFile[] files = smbDir.listFiles();
140-
141-
logListedFiles(_path, files);
142-
143-
return files;
138+
files = new SmbFile[] {remoteFile};
144139
}
145-
catch (SmbException _ex) {
146-
throw new IOException("Failed to list in [" + _path + "].", _ex);
140+
else {
141+
try {
142+
SmbFile smbDir = createSmbDirectoryObject(remotePath);
143+
if (!smbDir.exists()) {
144+
logger.warn(() -> "Remote directory [" + remotePath + "] does not exist. Cannot list resources.");
145+
return new SmbFile[0];
146+
}
147+
else if (!smbDir.isDirectory()) {
148+
throw new IOException("[" + remotePath + "] is not a directory. Cannot list resources.");
149+
}
150+
151+
files = smbDir.listFiles();
152+
}
153+
catch (SmbException _ex) {
154+
throw new IOException("Failed to list in [" + remotePath + "].", _ex);
155+
}
147156
}
157+
logListedFiles(remotePath, files);
158+
159+
return files;
148160
}
149161

150162
/**

spring-integration-smb/src/test/java/org/springframework/integration/smb/dsl/SmbTests.java

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022-2023 the original author or authors.
2+
* Copyright 2022-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -164,7 +164,7 @@ public void testSmbInboundStreamFlow() throws Exception {
164164
}
165165

166166
@Test
167-
public void testSmbOutboundFlow() {
167+
public void testSmbOutboundFlow() throws SmbException {
168168
IntegrationFlow flow = f -> f
169169
.handle(Smb.outboundAdapter(sessionFactory(), FileExistsMode.REPLACE)
170170
.useTemporaryFileName(false)
@@ -181,18 +181,13 @@ public void testSmbOutboundFlow() {
181181
SmbFile[] files = template.execute(session ->
182182
session.list(getTargetRemoteDirectory().getName()));
183183
assertThat(files).hasSize(1);
184-
try {
185-
assertThat(files[0].length()).isEqualTo(3);
186-
}
187-
catch (SmbException se) {
188-
se.printStackTrace();
189-
}
184+
assertThat(files[0].length()).isEqualTo(3);
190185

191186
registration.destroy();
192187
}
193188

194189
@Test
195-
public void testSmbOutboundFlowWithSmbRemoteTemplate() {
190+
public void testSmbOutboundFlowWithSmbRemoteTemplate() throws SmbException {
196191
SmbRemoteFileTemplate smbTemplate = new SmbRemoteFileTemplate(sessionFactory());
197192
IntegrationFlow flow = f -> f
198193
.handle(Smb.outboundAdapter(smbTemplate)
@@ -209,18 +204,13 @@ public void testSmbOutboundFlowWithSmbRemoteTemplate() {
209204
SmbFile[] files = smbTemplate.execute(session ->
210205
session.list(getTargetRemoteDirectory().getName()));
211206
assertThat(files).hasSize(1);
212-
try {
213-
assertThat(files[0].length()).isEqualTo(3);
214-
}
215-
catch (SmbException se) {
216-
se.printStackTrace();
217-
}
207+
assertThat(files[0].length()).isEqualTo(3);
218208

219209
registration.destroy();
220210
}
221211

222212
@Test
223-
public void testSmbOutboundFlowWithSmbRemoteTemplateAndMode() {
213+
public void testSmbOutboundFlowWithSmbRemoteTemplateAndMode() throws SmbException {
224214
SmbRemoteFileTemplate smbTemplate = new SmbRemoteFileTemplate(sessionFactory());
225215
IntegrationFlow flow = f -> f
226216
.handle(Smb.outboundAdapter(smbTemplate, FileExistsMode.APPEND)
@@ -242,18 +232,33 @@ public void testSmbOutboundFlowWithSmbRemoteTemplateAndMode() {
242232
SmbFile[] files = smbTemplate.execute(session ->
243233
session.list(getTargetRemoteDirectory().getName()));
244234
assertThat(files).hasSize(1);
245-
try {
246-
assertThat(files[0].length()).isEqualTo(9);
247-
}
248-
catch (SmbException se) {
249-
se.printStackTrace();
250-
}
235+
assertThat(files[0].length()).isEqualTo(9);
251236

252237
registration.destroy();
253238
}
254239

255240
@Test
256241
public void testSmbGetFlow() {
242+
QueueChannel out = new QueueChannel();
243+
IntegrationFlow flow = f -> f
244+
.handle(
245+
Smb.outboundGateway(sessionFactory(), AbstractRemoteFileOutboundGateway.Command.GET, "payload")
246+
.localDirectoryExpression("'" + getTargetLocalDirectoryName() + "'"))
247+
.channel(out);
248+
IntegrationFlowRegistration registration = this.flowContext.registration(flow).register();
249+
String fileName = "smbSource/subSmbSource/subSmbSource2.txt";
250+
registration.getInputChannel().send(new GenericMessage<>(fileName));
251+
Message<?> result = out.receive(10_000);
252+
assertThat(result).isNotNull();
253+
254+
File sfis = (File) result.getPayload();
255+
assertThat(sfis).hasFileName("subSmbSource2.txt");
256+
257+
registration.destroy();
258+
}
259+
260+
@Test
261+
public void testSmbGetStreamFlow() throws IOException {
257262
QueueChannel out = new QueueChannel();
258263
IntegrationFlow flow = f -> f
259264
.handle(
@@ -271,14 +276,10 @@ public void testSmbGetFlow() {
271276
Message<?> result = out.receive(10_000);
272277
assertThat(result).isNotNull();
273278

274-
SmbFileInputStream sfis = (SmbFileInputStream) result.getPayload();
275-
assertThat(sfis).isNotNull();
276-
277-
try {
278-
sfis.close();
279-
}
280-
catch (IOException ioe) {
279+
try (SmbFileInputStream sfis = (SmbFileInputStream) result.getPayload()) {
280+
assertThat(sfis).isNotNull();
281281
}
282+
282283
registration.destroy();
283284
}
284285

0 commit comments

Comments
 (0)