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 <[email protected]> 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, +};
