You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by ma...@apache.org on 2021/07/30 18:35:38 UTC

[airavata-django-portal] 02/06: AIRAVATA-3491 Utility method for constructing simple Experiment object

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

machristie pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/airavata-django-portal.git

commit 0dabd4b08faa58a9ddc0687f36b83f2125617709
Author: Marcus Christie <ma...@apache.org>
AuthorDate: Wed Jul 28 11:54:54 2021 -0400

    AIRAVATA-3491 Utility method for constructing simple Experiment object
---
 django_airavata/apps/api/package.json              |   4 +-
 .../api/static/django_airavata_api/js/index.js     |   2 +
 .../js/models/ApplicationInterfaceDefinition.js    |  10 ++
 .../js/utils/ExperimentUtils.js                    | 151 +++++++++++++++++++++
 4 files changed, 165 insertions(+), 2 deletions(-)

diff --git a/django_airavata/apps/api/package.json b/django_airavata/apps/api/package.json
index 5cc5385..8533c3d 100644
--- a/django_airavata/apps/api/package.json
+++ b/django_airavata/apps/api/package.json
@@ -43,8 +43,8 @@
     "root": true,
     "extends": "eslint:recommended",
     "parserOptions": {
-      "ecmaVersion": 6,
-      "sourceType": "module"
+      "sourceType": "module",
+      "ecmaVersion": 2017
     },
     "env": {
       "browser": true,
diff --git a/django_airavata/apps/api/static/django_airavata_api/js/index.js b/django_airavata/apps/api/static/django_airavata_api/js/index.js
index 59421a4..7728bea 100644
--- a/django_airavata/apps/api/static/django_airavata_api/js/index.js
+++ b/django_airavata/apps/api/static/django_airavata_api/js/index.js
@@ -51,6 +51,7 @@ import ServiceFactory from "./services/ServiceFactory";
 
 import Session from "./session/Session";
 
+import ExperimentUtils from "./utils/ExperimentUtils";
 import FetchUtils from "./utils/FetchUtils";
 import PaginationIterator from "./utils/PaginationIterator";
 import StringUtils from "./utils/StringUtils";
@@ -155,6 +156,7 @@ const session = {
 };
 
 const utils = {
+  ExperimentUtils,
   FetchUtils,
   PaginationIterator,
   StringUtils,
diff --git a/django_airavata/apps/api/static/django_airavata_api/js/models/ApplicationInterfaceDefinition.js b/django_airavata/apps/api/static/django_airavata_api/js/models/ApplicationInterfaceDefinition.js
index 5fe19cb..ee919d4 100644
--- a/django_airavata/apps/api/static/django_airavata_api/js/models/ApplicationInterfaceDefinition.js
+++ b/django_airavata/apps/api/static/django_airavata_api/js/models/ApplicationInterfaceDefinition.js
@@ -78,4 +78,14 @@ export default class ApplicationInterfaceDefinition extends BaseModel {
     experiment.executionId = this.applicationInterfaceId;
     return experiment;
   }
+
+  get applicationModuleId() {
+    if (!this.applicationModules || this.applicationModules.length > 1) {
+      throw new Error(
+        `No unique application module exists for interface
+        ${this.applicationName}: modules=${this.applicationModules}`
+      );
+    }
+    return this.applicationModules[0];
+  }
 }
diff --git a/django_airavata/apps/api/static/django_airavata_api/js/utils/ExperimentUtils.js b/django_airavata/apps/api/static/django_airavata_api/js/utils/ExperimentUtils.js
new file mode 100644
index 0000000..613e868
--- /dev/null
+++ b/django_airavata/apps/api/static/django_airavata_api/js/utils/ExperimentUtils.js
@@ -0,0 +1,151 @@
+import { services } from "../index";
+
+const createExperiment = async function ({
+  applicationName, // name of the application interface (usually the same as the application module)
+  computeResourceName,
+  experimentName,
+  experimentInputs,
+} = {}) {
+  let applicationInterface = null;
+  if (applicationName) {
+    applicationInterface = await loadApplicationInterfaceByName(
+      applicationName
+    );
+  } else {
+    throw new Error("applicationName is required");
+  }
+  const applicationModuleId = applicationInterface.applicationModuleId;
+  let computeResourceId = null;
+  if (computeResourceName) {
+    computeResourceId = await loadComputeResourceIdByName(computeResourceName);
+  } else {
+    throw new Error("computeResourceName is required");
+  }
+  let groupResourceProfile = await loadGroupResourceProfile(computeResourceId);
+  let deployments = await loadApplicationDeployments(
+    applicationModuleId,
+    groupResourceProfile
+  );
+  const deployment = deployments.find(
+    (d) => d.computeHostId === computeResourceId
+  );
+  if (!deployment) {
+    throw new Error(
+      `Couldn't find a deployment for compute resource ${computeResourceId}`
+    );
+  }
+  let queueDescription = await loadQueue(deployment);
+  let workspacePreferences = await loadWorkspacePreferences();
+  const projectId = workspacePreferences.most_recent_project_id;
+
+  const experiment = applicationInterface.createExperiment();
+  if (experimentName) {
+    experiment.experimentName = experimentName;
+  } else {
+    experiment.experimentName = `${
+      applicationInterface.applicationName
+    } on ${new Date().toLocaleString([], {
+      dateStyle: "medium",
+      timeStyle: "short",
+    })}`;
+  }
+  experiment.projectId = projectId;
+  experiment.userConfigurationData.groupResourceProfileId =
+    groupResourceProfile.groupResourceProfileId;
+  experiment.userConfigurationData.computationalResourceScheduling.resourceHostId = computeResourceId;
+  experiment.userConfigurationData.computationalResourceScheduling.totalCPUCount =
+    queueDescription.defaultCPUCount;
+  experiment.userConfigurationData.computationalResourceScheduling.nodeCount =
+    queueDescription.defaultNodeCount;
+  experiment.userConfigurationData.computationalResourceScheduling.wallTimeLimit =
+    queueDescription.defaultWalltime;
+  experiment.userConfigurationData.computationalResourceScheduling.queueName =
+    queueDescription.queueName;
+
+  if (experimentInputs) {
+    for (let input of experiment.experimentInputs) {
+      if (input.name in experimentInputs) {
+        input.value = experimentInputs[input.name];
+      }
+    }
+  }
+  return experiment;
+};
+
+const loadApplicationInterfaceByName = async function (applicationName) {
+  const applicationInterfaces = await services.ApplicationInterfaceService.list();
+  const applicationInterface = applicationInterfaces.find(
+    (ai) => ai.applicationName === applicationName
+  );
+  if (!applicationInterface) {
+    throw new Error(
+      `Could not find application with interface named ${applicationName}`
+    );
+  }
+  return applicationInterface;
+};
+
+const loadComputeResourceIdByName = async function (computeResourceName) {
+  const computeResourceNames = await services.ComputeResourceService.names();
+  for (const computeResourceId in computeResourceNames) {
+    if (
+      computeResourceNames.hasOwnProperty(computeResourceId) &&
+      computeResourceNames[computeResourceId] === computeResourceName
+    ) {
+      return computeResourceId;
+    }
+  }
+  throw new Error(
+    `Could not find compute resource with name ${computeResourceName}`
+  );
+};
+
+const loadGroupResourceProfile = async function (computeResourceId) {
+  const groupResourceProfiles = await services.GroupResourceProfileService.list();
+  const groupResourceProfile = groupResourceProfiles.find((grp) => {
+    for (let computePref of grp.computePreferences) {
+      if (computePref.computeResourceId === computeResourceId) {
+        return true;
+      }
+    }
+    return false;
+  });
+  if (!groupResourceProfile) {
+    throw new Error(
+      `Couldn't find a group resource profile for compute resource ${computeResourceId}`
+    );
+  }
+  return groupResourceProfile;
+};
+
+const loadApplicationDeployments = async function (
+  applicationModuleId,
+  groupResourceProfile
+) {
+  return await services.ApplicationDeploymentService.list({
+    appModuleId: applicationModuleId,
+    groupResourceProfileId: groupResourceProfile.groupResourceProfileId,
+  });
+};
+
+const loadQueue = async function (applicationDeployment) {
+  const queues = await services.ApplicationDeploymentService.getQueues({
+    lookup: applicationDeployment.appDeploymentId,
+  });
+  const queue = queues.find((q) => q.isDefaultQueue);
+  if (!queue) {
+    throw new Error(
+      "Couldn't find a default queue for deployment " +
+        applicationDeployment.appDeploymentId
+    );
+  }
+  return queue;
+};
+
+const loadWorkspacePreferences = async function () {
+  return await services.WorkspacePreferencesService.get();
+};
+
+export default {
+  createExperiment,
+};