This is an automated email from the ASF dual-hosted git repository.
yasithdev pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/airavata.git
The following commit(s) were added to refs/heads/master by this push:
new ac4c7e46c6 fix(storage-service): move/symlink over SFTP instead of
shell commands (#655)
ac4c7e46c6 is described below
commit ac4c7e46c69bf9e20f41337a97179220b143da5d
Author: Yasith Jayawardana <[email protected]>
AuthorDate: Tue Jun 9 02:42:07 2026 -0400
fix(storage-service): move/symlink over SFTP instead of shell commands
(#655)
UserStorageService.moveFile and createSymlink ran "mv"/"ln -s" via
adaptor.executeCommand, which the SFTP storage adaptor does not support, so
both failed with "Command execution not supported on storage resources" (the
same class of bug just fixed for deleteFile). Add moveFile (SFTP rename) and
createSymlink (SFTP symlink) to the storage adaptor and call them.
Validated live: moving a file relocates it (source gone, destination has the
content); creating a symlink to a directory resolves through the link
(listing
the link shows the target's contents). storage + compute unit tests pass.
---
.../airavata/compute/util/SSHJStorageAdaptor.java | 18 ++++++++++++++++++
.../airavata/interfaces/StorageResourceAdaptor.java | 4 ++++
.../airavata/storage/grpc/UserStorageGrpcService.java | 4 ++--
3 files changed, 24 insertions(+), 2 deletions(-)
diff --git
a/airavata-api/compute-service/src/main/java/org/apache/airavata/compute/util/SSHJStorageAdaptor.java
b/airavata-api/compute-service/src/main/java/org/apache/airavata/compute/util/SSHJStorageAdaptor.java
index b2fe0bc6df..b0df07d5b4 100644
---
a/airavata-api/compute-service/src/main/java/org/apache/airavata/compute/util/SSHJStorageAdaptor.java
+++
b/airavata-api/compute-service/src/main/java/org/apache/airavata/compute/util/SSHJStorageAdaptor.java
@@ -203,6 +203,24 @@ public class SSHJStorageAdaptor implements
StorageResourceAdaptor {
}
}
+ @Override
+ public void moveFile(String sourcePath, String destinationPath) throws
AgentException {
+ try (SFTPClient sftp = openSftp()) {
+ sftp.rename(sourcePath, destinationPath);
+ } catch (Exception e) {
+ throw new AgentException("Failed to move file: " + sourcePath + "
-> " + destinationPath, e);
+ }
+ }
+
+ @Override
+ public void createSymlink(String targetPath, String linkPath) throws
AgentException {
+ try (SFTPClient sftp = openSftp()) {
+ sftp.symlink(linkPath, targetPath);
+ } catch (Exception e) {
+ throw new AgentException("Failed to create symlink: " + linkPath +
" -> " + targetPath, e);
+ }
+ }
+
@Override
public void uploadFile(String localFile, String remoteFile) throws
AgentException {
try (SFTPClient sftp = openSftp()) {
diff --git
a/airavata-api/src/main/java/org/apache/airavata/interfaces/StorageResourceAdaptor.java
b/airavata-api/src/main/java/org/apache/airavata/interfaces/StorageResourceAdaptor.java
index c5805d11af..8816d5ce57 100644
---
a/airavata-api/src/main/java/org/apache/airavata/interfaces/StorageResourceAdaptor.java
+++
b/airavata-api/src/main/java/org/apache/airavata/interfaces/StorageResourceAdaptor.java
@@ -45,6 +45,10 @@ public interface StorageResourceAdaptor extends AgentAdaptor
{
public void deleteFile(String path) throws AgentException;
+ public void moveFile(String sourcePath, String destinationPath) throws
AgentException;
+
+ public void createSymlink(String targetPath, String linkPath) throws
AgentException;
+
public List<String> listDirectory(String path) throws AgentException;
public Boolean doesFileExist(String filePath) throws AgentException;
diff --git
a/airavata-api/storage-service/src/main/java/org/apache/airavata/storage/grpc/UserStorageGrpcService.java
b/airavata-api/storage-service/src/main/java/org/apache/airavata/storage/grpc/UserStorageGrpcService.java
index 9c73d3d4de..c8fe08e46e 100644
---
a/airavata-api/storage-service/src/main/java/org/apache/airavata/storage/grpc/UserStorageGrpcService.java
+++
b/airavata-api/storage-service/src/main/java/org/apache/airavata/storage/grpc/UserStorageGrpcService.java
@@ -303,7 +303,7 @@ public class UserStorageGrpcService extends
UserStorageServiceGrpc.UserStorageSe
StorageResourceAdaptor adaptor =
getStorageAdaptor(request.getStorageResourceId());
String src = resolvePath(request.getSourcePath(),
request.getStorageResourceId());
String dst = resolvePath(request.getDestinationPath(),
request.getStorageResourceId());
- adaptor.executeCommand("mv " + src + " " + dst, "/");
+ adaptor.moveFile(src, dst);
DataProductModel product = DataProductModel.newBuilder()
.setProductName(Paths.get(request.getDestinationPath())
@@ -338,7 +338,7 @@ public class UserStorageGrpcService extends
UserStorageServiceGrpc.UserStorageSe
StorageResourceAdaptor adaptor =
getStorageAdaptor(request.getStorageResourceId());
String target = resolvePath(request.getTargetPath(),
request.getStorageResourceId());
String source = resolvePath(request.getSourcePath(),
request.getStorageResourceId());
- adaptor.executeCommand("ln -s " + target + " " + source, "/");
+ adaptor.createSymlink(target, source);
observer.onNext(Empty.getDefaultInstance());
observer.onCompleted();
} catch (Exception e) {