This is an automated email from the ASF dual-hosted git repository.

yasith pushed a commit to branch resource-mgmt-rest-api
in repository https://gitbox.apache.org/repos/asf/airavata.git

commit 38b218a0347bb49d9c8249a1a9b5e5d0ffe9327c
Author: lahiruj <[email protected]>
AuthorDate: Wed Oct 29 20:05:04 2025 -0400

    Add support for inputStorageId for experiments and removed the 
storageResourceId
---
 .../init/04-expcatalog-migrations.sql              |   4 +
 .../airavata/helix/impl/task/TaskContext.java      |  55 +++++++++--
 .../helix/impl/task/staging/ArchiveTask.java       |   6 +-
 .../helix/impl/task/staging/DataStagingTask.java   | 102 ++++++++++++++-------
 .../impl/task/staging/InputDataStagingTask.java    |   4 +-
 .../airavata/model/util/ExperimentModelUtil.java   |   2 +-
 .../core/entities/expcatalog/ProcessEntity.java    |  34 +++----
 .../expcatalog/UserConfigurationDataEntity.java    |  34 +++----
 .../expcatalog/ExperimentRepositoryTest.java       |   6 +-
 .../service/handlers/AgentManagementHandler.java   |   4 +-
 .../service/models/AgentLaunchRequest.java         |  19 ++++
 .../data-models/experiment_model.thrift            |  12 +--
 .../data-models/process_model.thrift               |  18 ++--
 13 files changed, 200 insertions(+), 100 deletions(-)

diff --git a/.devcontainer/database_scripts/init/04-expcatalog-migrations.sql 
b/.devcontainer/database_scripts/init/04-expcatalog-migrations.sql
index 198f57d6d6..678d272869 100644
--- a/.devcontainer/database_scripts/init/04-expcatalog-migrations.sql
+++ b/.devcontainer/database_scripts/init/04-expcatalog-migrations.sql
@@ -32,6 +32,10 @@ CREATE TABLE IF NOT EXISTS COMPUTE_RESOURCE_SCHEDULING (
        FOREIGN KEY (EXPERIMENT_ID) REFERENCES EXPERIMENT(EXPERIMENT_ID) ON 
DELETE CASCADE
 )ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
+-- Rename storage resource ID to input storage resource ID
+ALTER TABLE USER_CONFIGURATION_DATA CHANGE COLUMN STORAGE_RESOURCE_ID 
INPUT_STORAGE_RESOURCE_ID VARCHAR(255) DEFAULT NULL;
+ALTER TABLE PROCESS CHANGE COLUMN STORAGE_RESOURCE_ID 
INPUT_STORAGE_RESOURCE_ID VARCHAR(255) DEFAULT NULL;
+
 -- Add output storage resource ID columns
 ALTER TABLE USER_CONFIGURATION_DATA ADD COLUMN IF NOT EXISTS 
OUTPUT_STORAGE_RESOURCE_ID VARCHAR(255) DEFAULT NULL;
 ALTER TABLE PROCESS ADD COLUMN IF NOT EXISTS OUTPUT_STORAGE_RESOURCE_ID 
VARCHAR(255) DEFAULT NULL;
\ No newline at end of file
diff --git 
a/airavata-api/src/main/java/org/apache/airavata/helix/impl/task/TaskContext.java
 
b/airavata-api/src/main/java/org/apache/airavata/helix/impl/task/TaskContext.java
index a5d148ab5b..24e01bf606 100644
--- 
a/airavata-api/src/main/java/org/apache/airavata/helix/impl/task/TaskContext.java
+++ 
b/airavata-api/src/main/java/org/apache/airavata/helix/impl/task/TaskContext.java
@@ -327,17 +327,41 @@ public class TaskContext {
         this.userStoragePreference = userStoragePreference;
     }
 
+    /**
+     * Returns the default storage preference for the gateway.
+     * Prefers gateway-specific storage (ID starting with gatewayId), 
otherwise uses the first available preference.
+     * 
+     * @deprecated Use {@link #getInputGatewayStorageResourcePreference()} for 
input staging operations
+     *             or {@link #getOutputGatewayStorageResourcePreference()} for 
output staging operations.
+     */
+    @Deprecated
     public StoragePreference getGatewayStorageResourcePreference() throws 
Exception {
         if (this.gatewayStorageResourcePreference == null) {
             try {
-                this.gatewayStorageResourcePreference =
-                        registryClient.getGatewayStoragePreference(gatewayId, 
processModel.getStorageResourceId());
+                GatewayResourceProfile gatewayProfile = 
getGatewayResourceProfile();
+                List<StoragePreference> storagePreferences = 
gatewayProfile.getStoragePreferences();
+                
+                if (storagePreferences == null || 
storagePreferences.isEmpty()) {
+                    throw new Exception("No storage preferences found for 
gateway " + gatewayId);
+                }
+
+                String gatewayPrefix = gatewayId + "_";
+                this.gatewayStorageResourcePreference = 
storagePreferences.stream()
+                        .filter(pref -> {
+                            String id = pref.getStorageResourceId();
+                            return id != null && id.startsWith(gatewayPrefix);
+                        })
+                        .findFirst()
+                        .orElseGet(() -> {
+                            logger.debug("No gateway-specific storage found, 
using first available: {}", storagePreferences.get(0).getStorageResourceId());
+                            return storagePreferences.get(0);
+                        });
+
+                if 
(this.gatewayStorageResourcePreference.getStorageResourceId().startsWith(gatewayPrefix))
 {
+                    logger.debug("Using gateway-specific storage preference: 
{}", this.gatewayStorageResourcePreference.getStorageResourceId());
+                }
             } catch (TException e) {
-                logger.error(
-                        "Failed to fetch gateway storage preference for 
gateway {} and storage {}",
-                        gatewayId,
-                        processModel.getStorageResourceId(),
-                        e);
+                logger.error("Failed to fetch gateway storage preference for 
gateway {}", gatewayId, e);
                 throw e;
             }
         }
@@ -739,6 +763,23 @@ public class TaskContext {
         return getGatewayStorageResourcePreference().getStorageResourceId();
     }
 
+    public String getInputStorageResourceId() throws Exception {
+        if (processModel.getInputStorageResourceId() != null && 
!processModel.getInputStorageResourceId().trim().isEmpty()) {
+            return processModel.getInputStorageResourceId();
+        }
+        return getStorageResourceId();
+    }
+
+    public StoragePreference getInputGatewayStorageResourcePreference() throws 
Exception {
+        String inputStorageId = getInputStorageResourceId();
+        try {
+            return registryClient.getGatewayStoragePreference(gatewayId, 
inputStorageId);
+        } catch (TException e) {
+            logger.error("Failed to fetch gateway storage preference for input 
storage {} in gateway {}", inputStorageId, gatewayId, e);
+            throw e;
+        }
+    }
+
     public String getOutputStorageResourceId() throws Exception {
          if (processModel.getOutputStorageResourceId() != null && 
!processModel.getOutputStorageResourceId().trim().isEmpty()) {
              return processModel.getOutputStorageResourceId();
diff --git 
a/airavata-api/src/main/java/org/apache/airavata/helix/impl/task/staging/ArchiveTask.java
 
b/airavata-api/src/main/java/org/apache/airavata/helix/impl/task/staging/ArchiveTask.java
index e4e3336831..95cd43c6e6 100644
--- 
a/airavata-api/src/main/java/org/apache/airavata/helix/impl/task/staging/ArchiveTask.java
+++ 
b/airavata-api/src/main/java/org/apache/airavata/helix/impl/task/staging/ArchiveTask.java
@@ -68,7 +68,7 @@ public class ArchiveTask extends DataStagingTask {
                     tarDirPath = sourceURI.getPath();
                 }
 
-                String inputPath = 
getTaskContext().getStorageFileSystemRootLocation();
+                String inputPath = 
getTaskContext().getOutputGatewayStorageResourcePreference().getFileSystemRootLocation();
                 destFilePath = buildDestinationFilePath(inputPath, 
archiveFileName);
 
                 tarCreationAbsPath = tarDirPath + File.separator + 
archiveFileName;
@@ -77,8 +77,8 @@ public class ArchiveTask extends DataStagingTask {
                         "Failed to obtain source URI for archival staging task 
" + getTaskId(), true, e);
             }
 
-            // Fetch and validate storage adaptor
-            StorageResourceAdaptor storageResourceAdaptor = 
getStorageAdaptor(taskHelper.getAdaptorSupport());
+            // Fetch and validate storage adaptor (uses output storage if 
configured, otherwise default)
+            StorageResourceAdaptor storageResourceAdaptor = 
getOutputStorageAdaptor(taskHelper.getAdaptorSupport());
             // Fetch and validate compute resource adaptor
             AgentAdaptor adaptor = 
getComputeResourceAdaptor(taskHelper.getAdaptorSupport());
 
diff --git 
a/airavata-api/src/main/java/org/apache/airavata/helix/impl/task/staging/DataStagingTask.java
 
b/airavata-api/src/main/java/org/apache/airavata/helix/impl/task/staging/DataStagingTask.java
index 3116f18fda..b090619763 100644
--- 
a/airavata-api/src/main/java/org/apache/airavata/helix/impl/task/staging/DataStagingTask.java
+++ 
b/airavata-api/src/main/java/org/apache/airavata/helix/impl/task/staging/DataStagingTask.java
@@ -78,64 +78,68 @@ public abstract class DataStagingTask extends AiravataTask {
         return storageResource;
     }
 
-    @SuppressWarnings("WeakerAccess")
+    /**
+     * Gets the default storage adaptor configured for the gateway.
+     * This is the fallback storage used when input/output storage resources 
are not specifically configured.
+     */
     protected StorageResourceAdaptor getStorageAdaptor(AdaptorSupport 
adaptorSupport) throws TaskOnFailException {
         String storageId = null;
         try {
             storageId = getTaskContext().getStorageResourceId();
-            StorageResourceAdaptor storageResourceAdaptor = 
adaptorSupport.fetchStorageAdaptor(
-                    getGatewayId(),
-                    getTaskContext().getStorageResourceId(),
-                    getTaskContext().getDataMovementProtocol(),
-                    getTaskContext().getStorageResourceCredentialToken(),
-                    getTaskContext().getStorageResourceLoginUserName());
+            StoragePreference gatewayStoragePref = 
getTaskContext().getGatewayStorageResourcePreference();
+            return createStorageAdaptorFromPreference(adaptorSupport, 
storageId, gatewayStoragePref, "Default");
 
-            if (storageResourceAdaptor == null) {
-                throw new TaskOnFailException(
-                        "Storage resource adaptor for " + 
getTaskContext().getStorageResourceId() + " can not be null",
-                        true,
-                        null);
+        } catch (Exception e) {
+            logger.error("Failed to obtain adaptor for default storage 
resource {} in task {}", storageId, getTaskId(), e);
+            throw new TaskOnFailException("Failed to obtain adaptor for 
default storage resource " + storageId + " in task " + getTaskId(), false, e);
+        }
+    }
+
+    /**
+     * Gets the input storage adaptor.
+     * Use input storage resource if configured. Otherwise, falls back to 
default gateway storage.
+     */
+    protected StorageResourceAdaptor getInputStorageAdaptor(AdaptorSupport 
adaptorSupport) throws TaskOnFailException {
+        String storageId = null;
+        try {
+            storageId = getTaskContext().getInputStorageResourceId();
+
+            if (getTaskContext().getProcessModel().getInputStorageResourceId() 
!= null
+                    && 
!getTaskContext().getProcessModel().getInputStorageResourceId().trim().isEmpty())
 {
+
+                StoragePreference inputStoragePref = 
getTaskContext().getInputGatewayStorageResourcePreference();
+                return createStorageAdaptorFromPreference(adaptorSupport, 
storageId, inputStoragePref, "Input");
+            } else {
+                // Fall back to default storage resource configured
+                return getStorageAdaptor(adaptorSupport);
             }
-            return storageResourceAdaptor;
         } catch (Exception e) {
-            throw new TaskOnFailException(
-                    "Failed to obtain adaptor for storage resource " + 
storageId + " in task " + getTaskId(), false, e);
+            logger.error("Failed to obtain adaptor for input storage resource 
{} in task {}", storageId, getTaskId(), e);
+            throw new TaskOnFailException("Failed to obtain adaptor for input 
storage resource " + storageId + " in task " + getTaskId(), false, e);
         }
     }
 
-    @SuppressWarnings("WeakerAccess")
+    /**
+     * Gets the output storage adaptor.
+     * Use output storage resource if configured. Otherwise, falls back to 
default gateway storage.
+     */
     protected StorageResourceAdaptor getOutputStorageAdaptor(AdaptorSupport 
adaptorSupport) throws TaskOnFailException {
         String storageId = null;
         try {
             storageId = getTaskContext().getOutputStorageResourceId();
-            
+
             if 
(getTaskContext().getProcessModel().getOutputStorageResourceId() != null
                     && 
!getTaskContext().getProcessModel().getOutputStorageResourceId().trim().isEmpty())
 {
 
                 StoragePreference outputStoragePref = 
getTaskContext().getOutputGatewayStorageResourcePreference();
-
-                StorageResourceAdaptor storageResourceAdaptor = 
adaptorSupport.fetchStorageAdaptor(
-                        getGatewayId(),
-                        storageId,
-                        getTaskContext().getDataMovementProtocol(),
-                        
outputStoragePref.getResourceSpecificCredentialStoreToken() != null 
-                            ? 
outputStoragePref.getResourceSpecificCredentialStoreToken()
-                            : 
getTaskContext().getGatewayResourceProfile().getCredentialStoreToken(),
-                        outputStoragePref.getLoginUserName());
-
-                if (storageResourceAdaptor == null) {
-                    throw new TaskOnFailException(
-                            "Output storage resource adaptor for " + storageId 
+ " can not be null",
-                            true, null);
-                }
-                return storageResourceAdaptor;
+                return createStorageAdaptorFromPreference(adaptorSupport, 
storageId, outputStoragePref, "Output");
             } else {
                 // Fall back to default storage resource configured
                 return getStorageAdaptor(adaptorSupport);
             }
         } catch (Exception e) {
-            logger.error("Failed to obtain adaptor for output storage resource 
" + storageId + " in task " + getTaskId(), e);
-            throw new TaskOnFailException( "Failed to obtain adaptor for 
output storage resource " + storageId + " in task " + getTaskId(), false, e);
+            logger.error("Failed to obtain adaptor for output storage resource 
{} in task {}", storageId, getTaskId(), e);
+            throw new TaskOnFailException("Failed to obtain adaptor for output 
storage resource " + storageId + " in task " + getTaskId(), false, e);
         }
     }
 
@@ -451,4 +455,32 @@ public abstract class DataStagingTask extends AiravataTask 
{
             logger.warn("Failed to delete temporary file " + filePath);
         }
     }
+
+    /**
+     * Common method to create StorageResourceAdaptor from a StoragePreference.
+     */
+    private StorageResourceAdaptor 
createStorageAdaptorFromPreference(AdaptorSupport adaptorSupport, String 
storageId,
+                                                                      
StoragePreference storagePreference, String adaptorType) throws 
TaskOnFailException {
+        try {
+            String credentialToken = 
storagePreference.getResourceSpecificCredentialStoreToken() != null
+                    ? 
storagePreference.getResourceSpecificCredentialStoreToken()
+                    : 
getTaskContext().getGatewayResourceProfile().getCredentialStoreToken();
+
+            StorageResourceAdaptor storageResourceAdaptor = 
adaptorSupport.fetchStorageAdaptor(
+                    getGatewayId(),
+                    storageId,
+                    getTaskContext().getDataMovementProtocol(),
+                    credentialToken,
+                    storagePreference.getLoginUserName());
+
+            if (storageResourceAdaptor == null) {
+                throw new TaskOnFailException(adaptorType + " storage resource 
adaptor for " + storageId + " can not be null", true, null);
+            }
+            return storageResourceAdaptor;
+
+        } catch (Exception e) {
+            throw new TaskOnFailException("Failed to obtain adaptor for " + 
adaptorType.toLowerCase() + " storage resource " +
+                    storageId + " in task " + getTaskId(), false, e);
+        }
+    }
 }
diff --git 
a/airavata-api/src/main/java/org/apache/airavata/helix/impl/task/staging/InputDataStagingTask.java
 
b/airavata-api/src/main/java/org/apache/airavata/helix/impl/task/staging/InputDataStagingTask.java
index 9840ffdb15..65660152ca 100644
--- 
a/airavata-api/src/main/java/org/apache/airavata/helix/impl/task/staging/InputDataStagingTask.java
+++ 
b/airavata-api/src/main/java/org/apache/airavata/helix/impl/task/staging/InputDataStagingTask.java
@@ -82,8 +82,8 @@ public class InputDataStagingTask extends DataStagingTask {
                     sourceUrls = new String[] 
{dataStagingTaskModel.getSource()};
                 }
 
-                // Fetch and validate storage adaptor
-                StorageResourceAdaptor storageResourceAdaptor = 
getStorageAdaptor(taskHelper.getAdaptorSupport());
+                // Fetch and validate storage adaptor (uses input storage if 
configured, otherwise default)
+                StorageResourceAdaptor storageResourceAdaptor = 
getInputStorageAdaptor(taskHelper.getAdaptorSupport());
                 // Fetch and validate compute resource adaptor
                 AgentAdaptor adaptor = 
getComputeResourceAdaptor(taskHelper.getAdaptorSupport());
 
diff --git 
a/airavata-api/src/main/java/org/apache/airavata/model/util/ExperimentModelUtil.java
 
b/airavata-api/src/main/java/org/apache/airavata/model/util/ExperimentModelUtil.java
index 1f5ab72e81..8d4e3cbf68 100644
--- 
a/airavata-api/src/main/java/org/apache/airavata/model/util/ExperimentModelUtil.java
+++ 
b/airavata-api/src/main/java/org/apache/airavata/model/util/ExperimentModelUtil.java
@@ -92,7 +92,7 @@ public class ExperimentModelUtil {
 
         UserConfigurationDataModel configData = 
experiment.getUserConfigurationData();
         if (configData != null) {
-            processModel.setStorageResourceId(configData.getStorageId());
+            
processModel.setInputStorageResourceId(configData.getInputStorageResourceId());
             
processModel.setOutputStorageResourceId(configData.getOutputStorageResourceId());
             
processModel.setExperimentDataDir(configData.getExperimentDataDir());
             processModel.setGenerateCert(configData.isGenerateCert());
diff --git 
a/airavata-api/src/main/java/org/apache/airavata/registry/core/entities/expcatalog/ProcessEntity.java
 
b/airavata-api/src/main/java/org/apache/airavata/registry/core/entities/expcatalog/ProcessEntity.java
index 3c57967d20..2ec14bb6c0 100644
--- 
a/airavata-api/src/main/java/org/apache/airavata/registry/core/entities/expcatalog/ProcessEntity.java
+++ 
b/airavata-api/src/main/java/org/apache/airavata/registry/core/entities/expcatalog/ProcessEntity.java
@@ -73,8 +73,11 @@ public class ProcessEntity implements Serializable {
     @Column(name = "EMAIL_ADDRESSES")
     private String emailAddresses;
 
-    @Column(name = "STORAGE_RESOURCE_ID")
-    private String storageResourceId;
+    @Column(name = "INPUT_STORAGE_RESOURCE_ID")
+    private String inputStorageResourceId;
+
+    @Column(name = "OUTPUT_STORAGE_RESOURCE_ID")
+    private String outputStorageResourceId;
 
     @Column(name = "USER_DN")
     private String userDn;
@@ -94,9 +97,6 @@ public class ProcessEntity implements Serializable {
     @Column(name = "USE_USER_CR_PREF")
     private boolean useUserCRPref;
 
-    @Column(name = "OUTPUT_STORAGE_RESOURCE_ID")
-    private String outputStorageResourceId;
-
     @OneToMany(
             targetEntity = ProcessStatusEntity.class,
             cascade = CascadeType.ALL,
@@ -249,12 +249,20 @@ public class ProcessEntity implements Serializable {
         this.emailAddresses = emailAddresses;
     }
 
-    public String getStorageResourceId() {
-        return storageResourceId;
+    public String getInputStorageResourceId() {
+        return inputStorageResourceId;
+    }
+
+    public void setInputStorageResourceId(String inputStorageResourceId) {
+        this.inputStorageResourceId = inputStorageResourceId;
+    }
+
+    public String getOutputStorageResourceId() {
+        return outputStorageResourceId;
     }
 
-    public void setStorageResourceId(String storageResourceId) {
-        this.storageResourceId = storageResourceId;
+    public void setOutputStorageResourceId(String outputStorageResourceId) {
+        this.outputStorageResourceId = outputStorageResourceId;
     }
 
     public String getUserDn() {
@@ -368,12 +376,4 @@ public class ProcessEntity implements Serializable {
     public void setExperiment(ExperimentEntity experiment) {
         this.experiment = experiment;
     }
-
-    public String getOutputStorageResourceId() {
-        return outputStorageResourceId;
-    }
-
-    public void setOutputStorageResourceId(String outputStorageResourceId) {
-        this.outputStorageResourceId = outputStorageResourceId;
-    }
 }
diff --git 
a/airavata-api/src/main/java/org/apache/airavata/registry/core/entities/expcatalog/UserConfigurationDataEntity.java
 
b/airavata-api/src/main/java/org/apache/airavata/registry/core/entities/expcatalog/UserConfigurationDataEntity.java
index 0d06a3100c..e1e3f8ca24 100644
--- 
a/airavata-api/src/main/java/org/apache/airavata/registry/core/entities/expcatalog/UserConfigurationDataEntity.java
+++ 
b/airavata-api/src/main/java/org/apache/airavata/registry/core/entities/expcatalog/UserConfigurationDataEntity.java
@@ -86,8 +86,11 @@ public class UserConfigurationDataEntity implements 
Serializable {
     @Column(name = "OVERRIDE_ALLOCATION_PROJECT_NUMBER")
     private String overrideAllocationProjectNumber;
 
-    @Column(name = "STORAGE_RESOURCE_ID")
-    private String storageId;
+    @Column(name = "INPUT_STORAGE_RESOURCE_ID")
+    private String inputStorageResourceId;
+
+    @Column(name = "OUTPUT_STORAGE_RESOURCE_ID")
+    private String outputStorageResourceId;
 
     @Column(name = "EXPERIMENT_DATA_DIR", length = 512)
     private String experimentDataDir;
@@ -98,9 +101,6 @@ public class UserConfigurationDataEntity implements 
Serializable {
     @Column(name = "IS_USE_USER_CR_PREF")
     private boolean useUserCRPref;
 
-    @Column(name = "OUTPUT_STORAGE_RESOURCE_ID")
-    private String outputStorageResourceId;
-
     @OneToOne(targetEntity = ExperimentEntity.class, cascade = CascadeType.ALL)
     @PrimaryKeyJoinColumn(name = "EXPERIMENT_ID", referencedColumnName = 
"EXPERIMENT_ID")
     private ExperimentEntity experiment;
@@ -258,12 +258,20 @@ public class UserConfigurationDataEntity implements 
Serializable {
         this.overrideAllocationProjectNumber = overrideAllocationProjectNumber;
     }
 
-    public String getStorageId() {
-        return storageId;
+    public String getInputStorageResourceId() {
+        return inputStorageResourceId;
+    }
+
+    public void setInputStorageResourceId(String inputStorageResourceId) {
+        this.inputStorageResourceId = inputStorageResourceId;
+    }
+
+    public String getOutputStorageResourceId() {
+        return outputStorageResourceId;
     }
 
-    public void setStorageId(String storageId) {
-        this.storageId = storageId;
+    public void setOutputStorageResourceId(String outputStorageResourceId) {
+        this.outputStorageResourceId = outputStorageResourceId;
     }
 
     public String getExperimentDataDir() {
@@ -306,12 +314,4 @@ public class UserConfigurationDataEntity implements 
Serializable {
             List<ComputationalResourceSchedulingEntity> 
autoScheduledCompResourceSchedulingList) {
         this.autoScheduledCompResourceSchedulingList = 
autoScheduledCompResourceSchedulingList;
     }
-
-    public String getOutputStorageResourceId() {
-        return outputStorageResourceId;
-    }
-
-    public void setOutputStorageResourceId(String outputStorageResourceId) {
-        this.outputStorageResourceId = outputStorageResourceId;
-    }
 }
diff --git 
a/airavata-api/src/test/java/org/apache/airavata/registry/core/repositories/expcatalog/ExperimentRepositoryTest.java
 
b/airavata-api/src/test/java/org/apache/airavata/registry/core/repositories/expcatalog/ExperimentRepositoryTest.java
index 23a9b19fe8..33499575a6 100644
--- 
a/airavata-api/src/test/java/org/apache/airavata/registry/core/repositories/expcatalog/ExperimentRepositoryTest.java
+++ 
b/airavata-api/src/test/java/org/apache/airavata/registry/core/repositories/expcatalog/ExperimentRepositoryTest.java
@@ -129,12 +129,14 @@ public class ExperimentRepositoryTest extends TestBase {
         assertEquals(
                 experimentId, 
experimentRepository.addUserConfigurationData(userConfigurationDataModel, 
experimentId));
 
-        userConfigurationDataModel.setStorageId("storage2");
+        userConfigurationDataModel.setInputStorageResourceId("storage2");
+        userConfigurationDataModel.setOutputStorageResourceId("storage2");
         
experimentRepository.updateUserConfigurationData(userConfigurationDataModel, 
experimentId);
 
         final UserConfigurationDataModel retrievedUserConfigurationDataModel =
                 experimentRepository.getUserConfigurationData(experimentId);
-        assertEquals("storage2", 
retrievedUserConfigurationDataModel.getStorageId());
+        assertEquals("storage2", 
retrievedUserConfigurationDataModel.getInputStorageResourceId());
+        assertEquals("storage2", 
retrievedUserConfigurationDataModel.getOutputStorageResourceId());
         final ComputationalResourceSchedulingModel 
retrievedComputationalResourceScheduling =
                 
retrievedUserConfigurationDataModel.getComputationalResourceScheduling();
         assertNotNull(retrievedComputationalResourceScheduling);
diff --git 
a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentManagementHandler.java
 
b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentManagementHandler.java
index f6b55beb45..b528d7f86c 100644
--- 
a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentManagementHandler.java
+++ 
b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentManagementHandler.java
@@ -42,6 +42,7 @@ import 
org.apache.airavata.model.experiment.UserConfigurationDataModel;
 import org.apache.airavata.model.process.ProcessModel;
 import 
org.apache.airavata.model.scheduling.ComputationalResourceSchedulingModel;
 import org.apache.airavata.model.security.AuthzToken;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.thrift.TException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -250,7 +251,8 @@ public class AgentManagementHandler {
         
userConfigurationDataModel.setComputationalResourceScheduling(computationalResourceSchedulingModel);
         userConfigurationDataModel.setAiravataAutoSchedule(false);
         userConfigurationDataModel.setOverrideManualScheduledParams(false);
-        userConfigurationDataModel.setStorageId(storageResourceId);
+        
userConfigurationDataModel.setInputStorageResourceId(StringUtils.isNotBlank(req.getInputStorageId())
 ? req.getInputStorageId() : storageResourceId);
+        
userConfigurationDataModel.setOutputStorageResourceId(StringUtils.isNotBlank(req.getOutputStorageId())
 ? req.getInputStorageId() : storageResourceId);
         String experimentDataDir = Paths.get(storagePath, gatewayId, userName, 
projectDir, experimentName)
                 .toString();
         userConfigurationDataModel.setExperimentDataDir(experimentDataDir);
diff --git 
a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AgentLaunchRequest.java
 
b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AgentLaunchRequest.java
index a034d601fa..f073ce0403 100644
--- 
a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AgentLaunchRequest.java
+++ 
b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AgentLaunchRequest.java
@@ -39,6 +39,9 @@ public class AgentLaunchRequest {
     private int nodeCount = 1;
     private int memory = 2048;
 
+    private String inputStorageId;
+    private String outputStorageId;
+
     private JobBatchSpec jobBatchSpec;
 
     public String getExperimentName() {
@@ -141,6 +144,22 @@ public class AgentLaunchRequest {
         this.mounts = mounts;
     }
 
+    public String getInputStorageId() {
+        return inputStorageId;
+    }
+
+    public void setInputStorageId(String inputStorageId) {
+        this.inputStorageId = inputStorageId;
+    }
+
+    public String getOutputStorageId() {
+        return outputStorageId;
+    }
+
+    public void setOutputStorageId(String outputStorageId) {
+        this.outputStorageId = outputStorageId;
+    }
+
     public JobBatchSpec getJobBatchSpec() {
         return jobBatchSpec;
     }
diff --git a/thrift-interface-descriptions/data-models/experiment_model.thrift 
b/thrift-interface-descriptions/data-models/experiment_model.thrift
index 5134b8cfcb..07ec759fe1 100644
--- a/thrift-interface-descriptions/data-models/experiment_model.thrift
+++ b/thrift-interface-descriptions/data-models/experiment_model.thrift
@@ -65,12 +65,12 @@ struct UserConfigurationDataModel {
     5: optional bool throttleResources = 0,
     6: optional string userDN,
     7: optional bool generateCert = 0,
-    8: optional string storageId;
-    9: optional string experimentDataDir;
-    10: optional bool useUserCRPref;
-    11: optional string groupResourceProfileId
-    12: optional list<scheduling_model.ComputationalResourceSchedulingModel> 
autoScheduledCompResourceSchedulingList,
-    13: optional string outputStorageResourceId;
+    8: optional string inputStorageResourceId;
+    9: optional string outputStorageResourceId;
+    10: optional string experimentDataDir;
+    11: optional bool useUserCRPref;
+    12: optional string groupResourceProfileId
+    13: optional list<scheduling_model.ComputationalResourceSchedulingModel> 
autoScheduledCompResourceSchedulingList,
 }
 
 /**
diff --git a/thrift-interface-descriptions/data-models/process_model.thrift 
b/thrift-interface-descriptions/data-models/process_model.thrift
index 6006f85965..67e45735e9 100644
--- a/thrift-interface-descriptions/data-models/process_model.thrift
+++ b/thrift-interface-descriptions/data-models/process_model.thrift
@@ -65,13 +65,13 @@ struct ProcessModel {
     16: optional string gatewayExecutionId,
     17: optional bool enableEmailNotification,
     18: optional list<string> emailAddresses,
-    19: optional string storageResourceId,
-    20: optional string userDn,
-    21: optional bool generateCert = 0,
-    22: optional string experimentDataDir,
-    23: optional string userName,
-    24: optional bool useUserCRPref,
-    25: optional string groupResourceProfileId;
-    26: optional list<ProcessWorkflow> processWorkflows;
-    27: optional string outputStorageResourceId;
+    19: optional string inputStorageResourceId,
+    20: optional string outputStorageResourceId,
+    21: optional string userDn,
+    22: optional bool generateCert = 0,
+    23: optional string experimentDataDir,
+    24: optional string userName,
+    25: optional bool useUserCRPref,
+    26: optional string groupResourceProfileId;
+    27: optional list<ProcessWorkflow> processWorkflows;
 }

Reply via email to