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) {

Reply via email to