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 2018/01/25 22:09:36 UTC
[airavata-django-portal] 03/06: AIRAVATA-2615: FullExperiment model
This is an automated email from the ASF dual-hosted git repository.
machristie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/airavata-django-portal.git
commit 664f9359735c4521a9f44f74977a5fada61cb990
Author: Marcus Christie <ma...@iu.edu>
AuthorDate: Mon Jan 22 09:23:31 2018 -0500
AIRAVATA-2615: FullExperiment model
FullExperiment includes the experiment model and other models that are
referenced in the experiment model like input and output DataProducts.
---
django_airavata/apps/api/package-lock.json | 19 +++++
django_airavata/apps/api/package.json | 4 +-
django_airavata/apps/api/serializers.py | 62 ++++++++++++++--
.../api/static/django_airavata_api/js/index.js | 8 ++-
.../js/models/ComputeResourceDescription.js | 42 +++++++++++
.../django_airavata_api/js/models/DataProduct.js | 50 +++++++++++++
.../js/models/DataReplicaLocation.js | 31 ++++++++
.../js/models/FullExperiment.js | 64 +++++++++++++++++
.../js/services/FullExperimentService.js | 18 +++++
django_airavata/apps/api/urls.py | 1 +
django_airavata/apps/api/views.py | 53 +++++++++++++-
.../js/components/experiment/ExperimentSummary.vue | 83 ++++++++++------------
.../js/containers/ViewExperimentContainer.vue | 10 +--
.../js/entry-view-experiment.js | 7 +-
.../django_airavata_workspace/view_experiment.html | 2 +-
django_airavata/apps/workspace/views.py | 8 ++-
16 files changed, 394 insertions(+), 68 deletions(-)
diff --git a/django_airavata/apps/api/package-lock.json b/django_airavata/apps/api/package-lock.json
index 1476b2f..8c52d47 100644
--- a/django_airavata/apps/api/package-lock.json
+++ b/django_airavata/apps/api/package-lock.json
@@ -2244,6 +2244,11 @@
"dev": true,
"optional": true
},
+ "querystringify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-1.0.0.tgz",
+ "integrity": "sha1-YoYkIRLFtxL6ZU5SZlK/ahP/Bcs="
+ },
"randomatic": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz",
@@ -2413,6 +2418,11 @@
"is-finite": "1.0.2"
}
},
+ "requires-port": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
+ },
"safe-buffer": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
@@ -2490,6 +2500,15 @@
"integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
"dev": true
},
+ "url-parse": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.2.0.tgz",
+ "integrity": "sha512-DT1XbYAfmQP65M/mE6OALxmXzZ/z1+e5zk2TcSKe/KiYbNGZxgtttzC0mR/sjopbpOXcbniq7eIKmocJnUWlEw==",
+ "requires": {
+ "querystringify": "1.0.0",
+ "requires-port": "1.0.0"
+ }
+ },
"user-home": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz",
diff --git a/django_airavata/apps/api/package.json b/django_airavata/apps/api/package.json
index b31e3c8..cb96262 100644
--- a/django_airavata/apps/api/package.json
+++ b/django_airavata/apps/api/package.json
@@ -9,7 +9,9 @@
"build": "babel static/django_airavata_api/js -d static/django_airavata_api/dist",
"watch": "babel static/django_airavata_api/js --watch -d static/django_airavata_api/dist"
},
- "dependencies": {},
+ "dependencies": {
+ "url-parse": "^1.2.0"
+ },
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-preset-env": "^1.5.1"
diff --git a/django_airavata/apps/api/serializers.py b/django_airavata/apps/api/serializers.py
index 511d080..a230503 100644
--- a/django_airavata/apps/api/serializers.py
+++ b/django_airavata/apps/api/serializers.py
@@ -1,13 +1,13 @@
-from airavata.model.experiment.ttypes import ExperimentModel
-from airavata.model.workspace.ttypes import Project
from airavata.model.appcatalog.appdeployment.ttypes import ApplicationModule, ApplicationDeploymentDescription,CommandObject,SetEnvPaths
from airavata.model.appcatalog.appinterface.ttypes import ApplicationInterfaceDescription
+from airavata.model.appcatalog.computeresource.ttypes import BatchQueue
from airavata.model.application.io.ttypes import InputDataObjectType, OutputDataObjectType
+from airavata.model.data.replica.ttypes import DataProductModel, DataReplicaLocationModel
from airavata.model.experiment.ttypes import ExperimentModel
+from airavata.model.status.ttypes import ExperimentStatus
from airavata.model.workspace.ttypes import Project
-from airavata.model.appcatalog.appdeployment.ttypes import ApplicationModule
-from airavata.model.appcatalog.computeresource.ttypes import BatchQueue
+
from . import thrift_utils
from django.conf import settings
@@ -231,6 +231,10 @@ class BatchQueueSerializer(thrift_utils.create_serializer_class(BatchQueue)):
pass
+class ExperimentStatusSerializer(thrift_utils.create_serializer_class(ExperimentStatus)):
+ timeOfStateChange = UTCPosixTimestampDateTimeField()
+
+
class ExperimentSerializer(
thrift_utils.create_serializer_class(ExperimentModel)):
@@ -239,7 +243,57 @@ class ExperimentSerializer(
read_only = ('experimentId',)
url = FullyEncodedHyperlinkedIdentityField(view_name='django_airavata_api:experiment-detail', lookup_field='experimentId', lookup_url_kwarg='experiment_id')
+ full_experiment = FullyEncodedHyperlinkedIdentityField(view_name='django_airavata_api:full-experiment-detail', lookup_field='experimentId', lookup_url_kwarg='experiment_id')
project = FullyEncodedHyperlinkedIdentityField(view_name='django_airavata_api:project-detail', lookup_field='projectId', lookup_url_kwarg='project_id')
userName = GatewayUsernameDefaultField()
gatewayId = GatewayIdDefaultField()
creationTime = UTCPosixTimestampDateTimeField(allow_null=True)
+ experimentStatus = ExperimentStatusSerializer(many=True)
+
+
+class DataReplicaLocationSerializer(
+ thrift_utils.create_serializer_class(DataReplicaLocationModel)):
+ creationTime = UTCPosixTimestampDateTimeField()
+ lastModifiedTime = UTCPosixTimestampDateTimeField()
+
+
+class DataProductSerializer(
+ thrift_utils.create_serializer_class(DataProductModel)):
+ creationTime = UTCPosixTimestampDateTimeField()
+ lastModifiedTime = UTCPosixTimestampDateTimeField()
+ replicaLocations = DataReplicaLocationSerializer(many=True)
+
+
+# TODO move this into airavata_sdk?
+class FullExperiment:
+ """Experiment with referenced data models."""
+
+ def __init__(self, experimentModel, project=None, outputDataProducts=None,
+ inputDataProducts=None, applicationModule=None,
+ computeResource=None):
+ self.experiment = experimentModel
+ self.experimentId = experimentModel.experimentId
+ self.project = project
+ self.outputDataProducts = outputDataProducts
+ self.inputDataProducts = inputDataProducts
+ self.applicationModule = applicationModule
+ self.computeResource = computeResource
+
+
+class FullExperimentSerializer(serializers.Serializer):
+ url = FullyEncodedHyperlinkedIdentityField(
+ view_name='django_airavata_api:full-experiment-detail',
+ lookup_field='experimentId',
+ lookup_url_kwarg='experiment_id')
+ experiment = ExperimentSerializer()
+ outputDataProducts = DataProductSerializer(many=True, read_only=True)
+ inputDataProducts = DataProductSerializer(many=True, read_only=True)
+ applicationModule = ApplicationModuleSerializer(read_only=True)
+ computeResource = ComputeResourceDescriptionSerializer(read_only=True)
+ project = ProjectSerializer(read_only=True)
+
+ def create(self, validated_data):
+ raise Exception("Not implemented")
+
+ def update(self, instance, validated_data):
+ raise Exception("Not implemented")
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 8860efb..6562ed1 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
@@ -3,13 +3,15 @@ import ApplicationInterfaceDefinition from './models/ApplicationInterfaceDefinit
import ApplicationModule from './models/ApplicationModule'
import Experiment from './models/Experiment'
import InputDataObjectType from './models/InputDataObjectType'
-import OutputDataTypeObject from './models/OutputDataTypeObject'
+import OutputDataObjectType from './models/OutputDataObjectType'
import Project from './models/Project'
+import FullExperiment from './models/FullExperiment'
import ApplicationDeploymentService from './services/ApplicationDeploymentService'
import ApplicationInterfaceService from './services/ApplicationInterfaceService'
import ApplicationModuleService from './services/ApplicationModuleService'
import ExperimentService from './services/ExperimentService'
+import FullExperimentService from './services/FullExperimentService'
import ProjectService from './services/ProjectService'
import FetchUtils from './utils/FetchUtils'
@@ -19,8 +21,9 @@ exports.models = {
ApplicationInterfaceDefinition,
ApplicationModule,
Experiment,
+ FullExperiment,
InputDataObjectType,
- OutputDataTypeObject,
+ OutputDataObjectType,
Project,
}
@@ -29,6 +32,7 @@ exports.services = {
ApplicationInterfaceService,
ApplicationModuleService,
ExperimentService,
+ FullExperimentService,
ProjectService,
}
diff --git a/django_airavata/apps/api/static/django_airavata_api/js/models/ComputeResourceDescription.js b/django_airavata/apps/api/static/django_airavata_api/js/models/ComputeResourceDescription.js
new file mode 100644
index 0000000..f59d770
--- /dev/null
+++ b/django_airavata/apps/api/static/django_airavata_api/js/models/ComputeResourceDescription.js
@@ -0,0 +1,42 @@
+import BaseModel from './BaseModel'
+import BatchQueue from './BatchQueue'
+
+const FIELDS = [
+ 'computeResourceId',
+ 'hostName',
+ {
+ name: 'hostAliases',
+ type: 'string',
+ list: true
+ },
+ {
+ name: 'ipAddresses',
+ type: 'string',
+ list: true
+ },
+ 'resourceDescription',
+ 'enabled',
+ {
+ name: 'batchQueues',
+ type: BatchQueue,
+ list: true
+ },
+ // TODO: map these
+ // 'fileSystems',
+ // 'jobSubmissionInterfaces',
+ // 'dataMovementInterfaces',
+ 'maxMemoryPerNode',
+ 'gatewayUsageReporting',
+ 'gatewayUsageModuleLoadCommand',
+ 'gatewayUsageExecutable',
+ 'cpusPerNode',
+ 'defaultNodeCount',
+ 'defaultCPUCount',
+ 'defaultWalltime',
+]
+
+export default class FullExperiment extends BaseModel {
+ constructor(data = {}) {
+ super(FIELDS, data);
+ }
+}
diff --git a/django_airavata/apps/api/static/django_airavata_api/js/models/DataProduct.js b/django_airavata/apps/api/static/django_airavata_api/js/models/DataProduct.js
new file mode 100644
index 0000000..dff0251
--- /dev/null
+++ b/django_airavata/apps/api/static/django_airavata_api/js/models/DataProduct.js
@@ -0,0 +1,50 @@
+
+import BaseModel from './BaseModel'
+import DataReplicaLocation from './DataReplicaLocation'
+
+import URL from 'url-parse'
+
+const FIELDS = [
+ 'productUri',
+ 'gatewayId',
+ 'parentProductUri',
+ 'productName',
+ 'productDescription',
+ 'ownerName',
+ 'dataProductType',
+ 'productSize',
+ {
+ name: 'creationTime',
+ type: 'date',
+ },
+ {
+ name: 'lastModifiedTime',
+ type: 'date',
+ },
+ 'productMetadata',
+ {
+ name: 'replicaLocations',
+ type: DataReplicaLocation,
+ list: true
+ },
+];
+
+const FILENAME_REGEX = /[^/]+$/;
+
+export default class DataProduct extends BaseModel {
+ constructor(data = {}) {
+ super(FIELDS, data);
+ }
+
+ get filename() {
+ if (this.replicaLocations && this.replicaLocations.length > 0) {
+ const firstReplicaLocation = this.replicaLocations[0];
+ const fileURL = new URL(firstReplicaLocation.filePath);
+ const filenameMatch = FILENAME_REGEX.exec(fileURL.pathname);
+ if (filenameMatch) {
+ return filenameMatch[0];
+ }
+ }
+ return null;
+ }
+}
diff --git a/django_airavata/apps/api/static/django_airavata_api/js/models/DataReplicaLocation.js b/django_airavata/apps/api/static/django_airavata_api/js/models/DataReplicaLocation.js
new file mode 100644
index 0000000..d0bbc07
--- /dev/null
+++ b/django_airavata/apps/api/static/django_airavata_api/js/models/DataReplicaLocation.js
@@ -0,0 +1,31 @@
+import BaseModel from './BaseModel'
+
+const FIELDS = [
+ 'replicaId',
+ 'productUri',
+ 'replicaName',
+ 'replicaDescription',
+ {
+ name: 'creationTime',
+ type: 'date',
+ },
+ {
+ name: 'lastModifiedTime',
+ type: 'date',
+ },
+ {
+ name: 'validUntilTime',
+ type: 'date',
+ },
+ 'replicaLocationCategory',
+ 'replicaPersistentType',
+ 'storageResourceId',
+ 'filePath',
+ 'replicaMetadata',
+];
+
+export default class DataReplicaLocation extends BaseModel {
+ constructor(data = {}) {
+ super(FIELDS, data);
+ }
+}
\ No newline at end of file
diff --git a/django_airavata/apps/api/static/django_airavata_api/js/models/FullExperiment.js b/django_airavata/apps/api/static/django_airavata_api/js/models/FullExperiment.js
new file mode 100644
index 0000000..34e8d65
--- /dev/null
+++ b/django_airavata/apps/api/static/django_airavata_api/js/models/FullExperiment.js
@@ -0,0 +1,64 @@
+
+import ApplicationModule from './ApplicationModule'
+import BaseModel from './BaseModel'
+import ComputeResourceDescription from './ComputeResourceDescription'
+import DataProduct from './DataProduct.js'
+import Experiment from './Experiment'
+import Project from './Project'
+
+const FIELDS = [
+ 'experimentId',
+ {
+ name: 'experiment',
+ type: Experiment,
+ },
+ {
+ name: 'project',
+ type: Project
+ },
+ {
+ name: 'applicationModule',
+ type: ApplicationModule
+ },
+ {
+ name: 'computeResource',
+ type: ComputeResourceDescription
+ },
+ {
+ name: 'outputDataProducts',
+ type: DataProduct,
+ list: true
+ },
+ {
+ name: 'inputDataProducts',
+ type: DataProduct,
+ list: true
+ }
+];
+
+export default class FullExperiment extends BaseModel {
+ constructor(data = {}) {
+ super(FIELDS, data);
+ }
+
+ get projectName() {
+ return this.project ? this.project.name : null;
+ }
+
+ get applicationName() {
+ return this.applicationModule ? this.applicationModule.appModuleName : null;
+ }
+
+ get computeHostName() {
+ return this.computeResource ? this.computeResource.hostName : null;
+ }
+
+ get experimentStatus() {
+ return this.experiment.experimentStatus && this.experiment.experimentStatus.length > 0
+ ? this.experiment.experimentStatus[0] : null;
+ }
+
+ get experimentStatusName() {
+ return this.experimentStatus ? this.experimentStatus.stateName : null;
+ }
+}
diff --git a/django_airavata/apps/api/static/django_airavata_api/js/services/FullExperimentService.js b/django_airavata/apps/api/static/django_airavata_api/js/services/FullExperimentService.js
new file mode 100644
index 0000000..90acd57
--- /dev/null
+++ b/django_airavata/apps/api/static/django_airavata_api/js/services/FullExperimentService.js
@@ -0,0 +1,18 @@
+
+import FullExperiment from '../models/FullExperiment'
+import FetchUtils from '../utils/FetchUtils'
+
+class FullExperimentService {
+ get(experimentId, data = null) {
+ if (data) {
+ return Promise.resolve(new FullExperiment(data));
+ } else {
+ return FetchUtils.get('/api/full-experiments/'
+ + encodeURIComponent(experimentId) + '/')
+ .then(result => new FullExperiment(result));
+ }
+ }
+}
+
+// Export as a singleton
+export default new FullExperimentService();
\ No newline at end of file
diff --git a/django_airavata/apps/api/urls.py b/django_airavata/apps/api/urls.py
index a9c059a..e20babf 100644
--- a/django_airavata/apps/api/urls.py
+++ b/django_airavata/apps/api/urls.py
@@ -11,6 +11,7 @@ logger = logging.getLogger(__name__)
router = routers.DefaultRouter()
router.register(r'projects', views.ProjectViewSet, base_name='project')
router.register(r'experiments', views.ExperimentViewSet, base_name='experiment')
+router.register(r'full-experiments', views.FullExperimentViewSet, base_name='full-experiment')
router.register(r'new/application/module', views.RegisterApplicationModule, base_name='register_app_module')
router.register(r'application-interfaces', views.ApplicationInterfaceViewSet, base_name='application-interface')
router.register(r'applications', views.ApplicationModuleViewSet, base_name='application')
diff --git a/django_airavata/apps/api/views.py b/django_airavata/apps/api/views.py
index 7d2f6ed..45be9db 100644
--- a/django_airavata/apps/api/views.py
+++ b/django_airavata/apps/api/views.py
@@ -24,6 +24,9 @@ from airavata.model.appcatalog.appdeployment.ttypes import ApplicationModule, Ap
from airavata.model.appcatalog.appinterface.ttypes import ApplicationInterfaceDescription
from airavata.model.appcatalog.computeresource.ttypes import ComputeResourceDescription
from airavata.model.credential.store.ttypes import CredentialOwnerType,SummaryType,CredentialSummary
+from airavata.model.application.io.ttypes import DataType
+
+from airavata_sdk.experiment import Experiment
from collections import OrderedDict
import logging
@@ -102,6 +105,7 @@ class APIBackedViewSet(mixins.CreateModelMixin,
"""
pass
+
class APIResultIterator(object):
"""
Iterable container over API results which allow limit/offset style slicing.
@@ -232,7 +236,7 @@ class ExperimentViewSet(APIBackedViewSet):
lookup_field = 'experiment_id'
def get_list(self):
- return self.request.airavata_client.getUserExperiments(self.authz_token, self.gateway_id, self.username, 1, 0)
+ return self.request.airavata_client.getUserExperiments(self.authz_token, self.gateway_id, self.username, -1, 0)
def get_instance(self, lookup_value):
return self.request.airavata_client.getExperiment(self.authz_token, lookup_value)
@@ -256,6 +260,53 @@ class ExperimentViewSet(APIBackedViewSet):
return Response({'success': False, 'errorMessage': e.message})
+class FullExperimentViewSet(mixins.RetrieveModelMixin,
+ GenericAPIBackedViewSet):
+
+ serializer_class = serializers.FullExperimentSerializer
+ lookup_field = 'experiment_id'
+
+ def get_instance(self, lookup_value):
+ """Get FullExperiment instance with resolved references."""
+ # TODO: move loading experiment and references to airavata_sdk?
+ experimentModel = self.request.airavata_client.getExperiment(
+ self.authz_token, lookup_value)
+ outputDataProducts = [
+ self.request.airavata_client.getDataProduct(self.authz_token,
+ output.value)
+ for output in experimentModel.experimentOutputs
+ if output.type in (DataType.URI, DataType.STDOUT, DataType.STDERR)]
+ inputDataProducts = [
+ self.request.airavata_client.getDataProduct(self.authz_token,
+ inp.value)
+ for inp in experimentModel.experimentInputs
+ if inp.type in (DataType.URI, DataType.STDOUT, DataType.STDERR)]
+ appInterfaceId = experimentModel.executionId
+ applicationInterface = self.request.airavata_client\
+ .getApplicationInterface(self.authz_token, appInterfaceId)
+ appModuleId = applicationInterface.applicationModules[0]
+ applicationModule = self.request.airavata_client\
+ .getApplicationModule(self.authz_token, appModuleId)
+ compute_resource_id = None
+ user_conf = experimentModel.userConfigurationData
+ if user_conf and user_conf.computationalResourceScheduling:
+ comp_res_sched = user_conf.computationalResourceScheduling
+ compute_resource_id = comp_res_sched.resourceHostId
+ compute_resource = self.request.airavata_client.getComputeResource(
+ self.authz_token, compute_resource_id)\
+ if compute_resource_id else None
+ project = self.request.airavata_client.getProject(
+ self.authz_token, experimentModel.projectId)
+ full_experiment = serializers.FullExperiment(
+ experimentModel,
+ project=project,
+ outputDataProducts=outputDataProducts,
+ inputDataProducts=inputDataProducts,
+ applicationModule=applicationModule,
+ computeResource=compute_resource)
+ return full_experiment
+
+
class ApplicationModuleViewSet(APIBackedViewSet):
serializer_class = serializers.ApplicationModuleSerializer
lookup_field = 'app_module_id'
diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/ExperimentSummary.vue b/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/ExperimentSummary.vue
index 9159b92..997759b 100644
--- a/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/ExperimentSummary.vue
+++ b/django_airavata/apps/workspace/static/django_airavata_workspace/js/components/experiment/ExperimentSummary.vue
@@ -15,20 +15,23 @@
<tbody>
<tr>
<th scope="row">Name</th>
- <td><span :title="localExperiment.experimentId">{{ localExperiment.experimentName }}</span></td>
+ <td><span :title="experiment.experimentId">{{ experiment.experimentName }}</span></td>
</tr>
<tr>
<th scope="row">Description</th>
- <td>{{ localExperiment.description }}</td>
+ <td>{{ experiment.description }}</td>
</tr>
<tr>
<th scope="row">Project</th>
- <td>{{ project && project.name || '' }}</td>
+ <td>{{ fullExperiment.projectName }}</td>
</tr>
<tr>
- <!-- TODO -->
<th scope="row">Outputs</th>
- <td></td>
+ <td>
+ <template v-for="output in fullExperiment.outputDataProducts">
+ {{ output.filename }}
+ </template>
+ </td>
</tr>
<!-- Going to leave this out for now -->
<!-- <tr>
@@ -37,56 +40,59 @@
</tr> -->
<tr>
<th scope="row">Owner</th>
- <td>{{ localExperiment.userName }}</td>
+ <td>{{ experiment.userName }}</td>
</tr>
<tr>
- <!-- TODO -->
<th scope="row">Application</th>
- <td></td>
+ <td>{{ fullExperiment.applicationName }}</td>
</tr>
<tr>
- <!-- TODO -->
<th scope="row">Compute Resource</th>
- <td></td>
+ <td>{{ fullExperiment.computeHostName }}</td>
</tr>
<tr>
<th scope="row">Experiment Status</th>
- <td>{{ experimentStatus.stateName }}</td>
+ <td>{{ fullExperiment.experimentStatusName }}</td>
</tr>
- <tr>
+ <!-- TODO: leave this out for now -->
+ <!-- <tr>
<th scope="row">Notification List</th>
- <td>{{ localExperiment.emailAddresses
- ? localExperiment.emailAddresses.join(", ")
+ <td>{{ fullExperiment.experiment.emailAddresses
+ ? fullExperiment.experiment.emailAddresses.join(", ")
: '' }}</td>
- </tr>
+ </tr> -->
<tr>
<th scope="row">Creation Time</th>
- <td><span :title="localExperiment.creationTime.toString()">{{ creationTime }}</span></td>
+ <td><span :title="experiment.creationTime.toString()">{{ creationTime }}</span></td>
</tr>
<tr>
<th scope="row">Last Modified Time</th>
- <td><span :title="experimentStatus.timeOfStateChange.toString()">{{ lastModifiedTime }}</span></td>
+ <td><span :title="fullExperiment.experimentStatus.timeOfStateChange.toString()">{{ lastModifiedTime }}</span></td>
</tr>
<tr>
<th scope="row">Wall Time Limit</th>
- <td>{{ localExperiment.userConfigurationData.computationalResourceScheduling.wallTimeLimit }} minutes</td>
+ <td>{{ experiment.userConfigurationData.computationalResourceScheduling.wallTimeLimit }} minutes</td>
</tr>
<tr>
<th scope="row">CPU Count</th>
- <td>{{ localExperiment.userConfigurationData.computationalResourceScheduling.totalCPUCount }}</td>
+ <td>{{ experiment.userConfigurationData.computationalResourceScheduling.totalCPUCount }}</td>
</tr>
<tr>
<th scope="row">Node Count</th>
- <td>{{ localExperiment.userConfigurationData.computationalResourceScheduling.nodeCount }}</td>
+ <td>{{ experiment.userConfigurationData.computationalResourceScheduling.nodeCount }}</td>
</tr>
<tr>
<th scope="row">Queue</th>
- <td>{{ localExperiment.userConfigurationData.computationalResourceScheduling.queueName }}</td>
+ <td>{{ experiment.userConfigurationData.computationalResourceScheduling.queueName }}</td>
</tr>
<tr>
<!-- TODO -->
<th scope="row">Inputs</th>
- <td></td>
+ <td>
+ <template v-for="input in fullExperiment.inputDataProducts">
+ {{ input.filename }}
+ </template>
+ </td>
</tr>
<tr>
<!-- TODO -->
@@ -111,50 +117,33 @@ import moment from 'moment';
export default {
name: 'experiment-summary',
props: {
- experiment: {
- type: models.Experiment,
+ fullExperiment: {
+ type: models.FullExperiment,
required: true
},
},
data () {
return {
- localExperiment: this.experiment.clone(),
- project: null,
+ localFullExperiment: this.fullExperiment.clone(),
}
},
components: {
},
computed: {
creationTime: function() {
- return moment(this.localExperiment.creationTime).fromNow();
- },
- experimentStatus: function() {
- return this.localExperiment.experimentStatus[0];
+ return moment(this.localFullExperiment.experiment.creationTime).fromNow();
},
lastModifiedTime: function() {
- return moment(this.experimentStatus.timeOfStateChange).fromNow();
+ return moment(this.localFullExperiment.experimentStatus.timeOfStateChange).fromNow();
+ },
+ experiment: function() {
+ return this.localFullExperiment.experiment;
}
},
methods: {
- loadProject: function() {
- services.ProjectService.get(this.experiment.projectId)
- .then(proj => this.project = proj);
- },
- loadApplication: function() {
-
- },
- loadOutputs: function() {
-
- },
- loadComputeHost: function() {
-
- },
},
watch: {
},
- mounted: function() {
- this.loadProject();
- }
}
</script>
diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/js/containers/ViewExperimentContainer.vue b/django_airavata/apps/workspace/static/django_airavata_workspace/js/containers/ViewExperimentContainer.vue
index 1bf3482..bebfffa 100644
--- a/django_airavata/apps/workspace/static/django_airavata_workspace/js/containers/ViewExperimentContainer.vue
+++ b/django_airavata/apps/workspace/static/django_airavata_workspace/js/containers/ViewExperimentContainer.vue
@@ -1,5 +1,5 @@
<template>
- <experiment-summary v-if="experiment" :experiment="experiment">
+ <experiment-summary v-if="fullExperiment" :fullExperiment="fullExperiment">
</experiment-summary>
</template>
@@ -11,13 +11,13 @@ import ExperimentSummary from '../components/experiment/ExperimentSummary.vue'
export default {
name: 'view-experiment-container',
props: {
- initialExperimentData: {
+ initialFullExperimentData: {
required: true
},
},
data () {
return {
- experiment: null,
+ fullExperiment: null,
}
},
components: {
@@ -28,8 +28,8 @@ export default {
computed: {
},
beforeMount: function () {
- services.ExperimentService.get(this.initialExperimentData.experimentId, this.initialExperimentData)
- .then(exp => this.experiment = exp);
+ services.FullExperimentService.get(this.initialFullExperimentData.experimentId, this.initialFullExperimentData)
+ .then(exp => this.fullExperiment = exp);
}
}
</script>
diff --git a/django_airavata/apps/workspace/static/django_airavata_workspace/js/entry-view-experiment.js b/django_airavata/apps/workspace/static/django_airavata_workspace/js/entry-view-experiment.js
index 6517ba8..a2c8c8b 100644
--- a/django_airavata/apps/workspace/static/django_airavata_workspace/js/entry-view-experiment.js
+++ b/django_airavata/apps/workspace/static/django_airavata_workspace/js/entry-view-experiment.js
@@ -10,17 +10,16 @@ Vue.use(BootstrapVue);
new Vue({
el: '#view-experiment',
- template: '<view-experiment-container :initial-experiment-data="experiment"></view-experiment-container>',
+ template: '<view-experiment-container :initial-full-experiment-data="fullExperimentData"></view-experiment-container>',
data () {
return {
- experiment: null,
+ fullExperimentData: null,
}
},
components: {
ViewExperimentContainer,
},
beforeMount: function () {
- console.log(this.$el.dataset.experimentData);
- this.experiment = JSON.parse(this.$el.dataset.experimentData);
+ this.fullExperimentData = JSON.parse(this.$el.dataset.fullExperimentData);
}
})
diff --git a/django_airavata/apps/workspace/templates/django_airavata_workspace/view_experiment.html b/django_airavata/apps/workspace/templates/django_airavata_workspace/view_experiment.html
index e09bf11..0f12b5e 100644
--- a/django_airavata/apps/workspace/templates/django_airavata_workspace/view_experiment.html
+++ b/django_airavata/apps/workspace/templates/django_airavata_workspace/view_experiment.html
@@ -9,7 +9,7 @@
{% block content %}
-<div id="view-experiment" data-experiment-data="{{ experiment_data }}"></div>
+<div id="view-experiment" data-full-experiment-data="{{ full_experiment_data }}"></div>
{% endblock content %}
diff --git a/django_airavata/apps/workspace/views.py b/django_airavata/apps/workspace/views.py
index 50c755d..9f78172 100644
--- a/django_airavata/apps/workspace/views.py
+++ b/django_airavata/apps/workspace/views.py
@@ -7,6 +7,7 @@ from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from django_airavata.apps.api.views import ExperimentViewSet
+from django_airavata.apps.api.views import FullExperimentViewSet
from django_airavata.apps.api.views import ProjectViewSet
logger = logging.getLogger(__name__)
@@ -41,14 +42,15 @@ def create_experiment(request, app_module_id):
'app_module_id': app_module_id
})
+
@login_required
def view_experiment(request, experiment_id):
request.active_nav_item = 'experiments'
- response = ExperimentViewSet.as_view(
+ response = FullExperimentViewSet.as_view(
{'get': 'retrieve'})(request, experiment_id=experiment_id)
- experiment_json = JSONRenderer().render(response.data)
+ full_experiment_json = JSONRenderer().render(response.data)
return render(request, 'django_airavata_workspace/view_experiment.html', {
- 'experiment_data': experiment_json
+ 'full_experiment_data': full_experiment_json
})
--
To stop receiving notification emails like this one, please contact
machristie@apache.org.