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 9a2987c8e0 Fix SDK-launched experiment output listing and clone 
creation-time (#662)
9a2987c8e0 is described below

commit 9a2987c8e0dc10fa143e090f6e18c2311570b43d
Author: Yasith Jayawardana <[email protected]>
AuthorDate: Sat Jun 13 00:18:15 2026 -0400

    Fix SDK-launched experiment output listing and clone creation-time (#662)
    
    Two experiment-data fixes surfaced via the portal:
    
    - "No files" for SDK-launched experiment output: the SDK persists an 
absolute
      experiment_data_dir ("/project/experiment"). The staging write side
      (DataStagingTask.buildDestinationFilePath) strips the leading "/" and 
anchors
      the dir under the storage root, but resolve_user_storage_path honored it
      as-is, so list_dir/dir_exists resolved against the SFTP chroot root 
(outside
      the storage root) and listed nothing. Strip the leading "/" and anchor 
under
      "~/", matching the write side and the bare-relative dirs the portal UI 
sets.
    
    - Clone shows creation time as "56 years ago" (epoch 0): the clone re-sends 
the
      full experiment via update_experiment with creation_time cleared, but
      saveExperiment only stamped creation_time on insert, so the update nulled 
the
      column. Make creation_time set-once: on update, carry the stored value 
forward.
---
 .../airavata/research/repository/ExperimentRepository.java    | 11 +++++++++++
 airavata-python-sdk/airavata_sdk/helpers/storage_resources.py |  8 ++++++--
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git 
a/airavata-api/research-service/src/main/java/org/apache/airavata/research/repository/ExperimentRepository.java
 
b/airavata-api/research-service/src/main/java/org/apache/airavata/research/repository/ExperimentRepository.java
index 0476cdfe8c..50c46f2a9e 100644
--- 
a/airavata-api/research-service/src/main/java/org/apache/airavata/research/repository/ExperimentRepository.java
+++ 
b/airavata-api/research-service/src/main/java/org/apache/airavata/research/repository/ExperimentRepository.java
@@ -101,6 +101,17 @@ public class ExperimentRepository extends 
AbstractRepository<ExperimentModel, Ex
             experimentModel = experimentModel.toBuilder()
                     .setCreationTime(System.currentTimeMillis())
                     .build();
+        } else {
+            // creation_time is immutable after create. This update path 
persists the full model, and
+            // callers may resend it with creation_time cleared — a clone, for 
instance, re-sends the
+            // experiment via update_experiment with an unset creation_time. 
longToTimestamp maps 0 to a
+            // NULL column that reads back as epoch 1970 ("56 years ago"). 
Carry the stored value forward.
+            long existingCreationTime = 
getExperiment(experimentId).getCreationTime();
+            if (existingCreationTime > 0) {
+                experimentModel = experimentModel.toBuilder()
+                        .setCreationTime(existingCreationTime)
+                        .build();
+            }
         }
         ExperimentEntity experimentEntity = 
ResearchMapper.INSTANCE.experimentToEntity(experimentModel);
 
diff --git a/airavata-python-sdk/airavata_sdk/helpers/storage_resources.py 
b/airavata-python-sdk/airavata_sdk/helpers/storage_resources.py
index dd90037e74..2197559ad1 100644
--- a/airavata-python-sdk/airavata_sdk/helpers/storage_resources.py
+++ b/airavata-python-sdk/airavata_sdk/helpers/storage_resources.py
@@ -84,9 +84,13 @@ def resolve_user_storage_path(
             if experiment.HasField("user_configuration_data")
             else None
         ) or ""
-        base = data_dir.rstrip("/")
+        # The experiment data dir is user-storage-relative. The SDK launch 
persists it with a
+        # leading '/' that the staging write side 
(DataStagingTask.buildDestinationFilePath) strips
+        # and anchors under the storage root; strip it here too and anchor 
under '~/' — otherwise
+        # list_dir/dir_exists resolve against the SFTP chroot root (outside 
it) and show "no files".
+        base = data_dir.strip("/")
         full = base + ("/" + rel if rel else "")
-        if full.startswith("/") or full.startswith("~/"):
+        if full.startswith("~/"):
             return full
         return "~/" + full
     if rel.startswith("~"):

Reply via email to