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/11/16 22:00:14 UTC
[airavata-django-portal] 02/06: AIRAVATA-2907 Add new storage
preference UI
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 523600110cf81f7cf1033c0380e5886439de3dca
Author: Marcus Christie <ma...@iu.edu>
AuthorDate: Thu Nov 15 12:11:36 2018 -0500
AIRAVATA-2907 Add new storage preference UI
---
.../GatewayResourceProfileEditorContainer.vue | 9 +++-
.../gatewayprofile/StoragePreferenceList.vue | 62 ++++++++++++++++++++--
.../gatewayprofile/StoragePreferenceListItem.vue | 10 ----
django_airavata/apps/api/serializers.py | 17 ++++++
.../api/static/django_airavata_api/js/index.js | 2 +
.../js/models/StorageResourceDescription.js | 17 ++++++
.../django_airavata_api/js/service_config.js | 21 ++++++++
django_airavata/apps/api/urls.py | 5 ++
django_airavata/apps/api/views.py | 52 ++++++++++++++++++
.../static/common/js/layouts/ListLayout.vue | 5 ++
10 files changed, 184 insertions(+), 16 deletions(-)
diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/components/gatewayprofile/GatewayResourceProfileEditorContainer.vue b/django_airavata/apps/admin/static/django_airavata_admin/src/components/gatewayprofile/GatewayResourceProfileEditorContainer.vue
index f6aee83..303ab56 100644
--- a/django_airavata/apps/admin/static/django_airavata_admin/src/components/gatewayprofile/GatewayResourceProfileEditorContainer.vue
+++ b/django_airavata/apps/admin/static/django_airavata_admin/src/components/gatewayprofile/GatewayResourceProfileEditorContainer.vue
@@ -14,7 +14,7 @@
<div class="card">
<div class="card-body">
<storage-preference-list v-if="gatewayResourceProfile" :storagePreferences="gatewayResourceProfile.storagePreferences"
- @updated="updatedStoragePreference" />
+ @updated="updatedStoragePreference" @added="addedStoragePreference" />
</div>
</div>
</div>
@@ -80,6 +80,13 @@ export default {
1,
updatedStoragePreference
);
+ },
+ addedStoragePreference(newStoragePreference) {
+ services.StoragePreferenceService.create({
+ data: newStoragePreference
+ }).then(sp => {
+ this.gatewayResourceProfile.storagePreferences.push(sp);
+ });
}
}
};
diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/components/gatewayprofile/StoragePreferenceList.vue b/django_airavata/apps/admin/static/django_airavata_admin/src/components/gatewayprofile/StoragePreferenceList.vue
index 5a8a4d5..fd66c04 100644
--- a/django_airavata/apps/admin/static/django_airavata_admin/src/components/gatewayprofile/StoragePreferenceList.vue
+++ b/django_airavata/apps/admin/static/django_airavata_admin/src/components/gatewayprofile/StoragePreferenceList.vue
@@ -1,6 +1,24 @@
<template>
- <list-layout @add-new-item="newStoragePreference" :items="decoratedStoragePreferences" title="Storage Preferences"
+ <list-layout @add-new-item="addNewStoragePreference" :items="decoratedStoragePreferences" title="Storage Preferences"
new-item-button-text="New Storage Preference">
+ <template slot="new-item-editor">
+ <b-card v-if="showNewItemEditor" title="New Storage Preference">
+ <b-form-group label="Storage Resource" label-for="storage-resource">
+ <b-form-select id="storage-resource" v-model="newStoragePreference.storageResourceId" :options="storageResourceOptions" />
+ </b-form-group>
+ <storage-preference-editor v-model="newStoragePreference" />
+ <div class="row">
+ <div class="col">
+ <b-button variant="primary" @click="saveNewStoragePreference">
+ Save
+ </b-button>
+ <b-button variant="secondary" @click="cancelNewStoragePreference">
+ Cancel
+ </b-button>
+ </div>
+ </div>
+ </b-card>
+ </template>
<template slot="item-list" slot-scope="slotProps">
<b-table striped hover :fields="fields" :items="slotProps.items" sort-by="storageResourceId">
@@ -22,7 +40,7 @@
</template>
<script>
-import { models } from "django-airavata-api";
+import { models, services, utils } from "django-airavata-api";
import { layouts } from "django-airavata-common-ui";
import StoragePreferenceEditor from "./StoragePreferenceEditor.vue";
@@ -41,7 +59,10 @@ export default {
data() {
return {
showingDetails: {},
- }
+ showNewItemEditor: false,
+ newStoragePreference: null,
+ storageResourceNames: null
+ };
},
computed: {
fields() {
@@ -78,8 +99,26 @@ export default {
spClone._showDetails = this.showingDetails[spClone.storageResourceId];
return spClone;
});
+ },
+ storageResourceOptions() {
+ const options = [];
+ for (const key in this.storageResourceNames) {
+ if (this.storageResourceNames.hasOwnProperty(key)) {
+ const name = this.storageResourceNames[key];
+ options.push({
+ value: key,
+ text: name
+ });
+ }
+ }
+ return utils.StringUtils.sortIgnoreCase(options, a => a.text);
}
},
+ created() {
+ services.StorageResourceService.names().then(names => {
+ this.storageResourceNames = names;
+ });
+ },
methods: {
getStorageResourceName(storageResourceId) {
// TODO: fetch storage resources
@@ -94,11 +133,24 @@ export default {
return fileSystemRootLocation;
},
updatedStoragePreference(newValue) {
- this.$emit('updated', newValue);
+ this.$emit("updated", newValue);
},
toggleDetails(row) {
row.toggleDetails();
- this.showingDetails[row.item.storageResourceId] = !this.showingDetails[row.item.storageResourceId];
+ this.showingDetails[row.item.storageResourceId] = !this.showingDetails[
+ row.item.storageResourceId
+ ];
+ },
+ addNewStoragePreference() {
+ this.newStoragePreference = new models.StoragePreference();
+ this.showNewItemEditor = true;
+ },
+ saveNewStoragePreference() {
+ this.$emit("added", this.newStoragePreference);
+ this.showNewItemEditor = false;
+ },
+ cancelNewStoragePreference() {
+ this.showNewItemEditor = false;
}
}
};
diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/components/gatewayprofile/StoragePreferenceListItem.vue b/django_airavata/apps/admin/static/django_airavata_admin/src/components/gatewayprofile/StoragePreferenceListItem.vue
deleted file mode 100644
index 13818a9..0000000
--- a/django_airavata/apps/admin/static/django_airavata_admin/src/components/gatewayprofile/StoragePreferenceListItem.vue
+++ /dev/null
@@ -1,10 +0,0 @@
-<template>
-
-</template>
-
-<script>
-export default {
- name: "storage-preference-list-item"
-};
-</script>
-
diff --git a/django_airavata/apps/api/serializers.py b/django_airavata/apps/api/serializers.py
index e9bb617..d1bf697 100644
--- a/django_airavata/apps/api/serializers.py
+++ b/django_airavata/apps/api/serializers.py
@@ -29,6 +29,9 @@ from airavata.model.appcatalog.gatewayprofile.ttypes import (
from airavata.model.appcatalog.groupresourceprofile.ttypes import (
GroupResourceProfile
)
+from airavata.model.appcatalog.storageresource.ttypes import (
+ StorageResourceDescription
+)
from airavata.model.application.io.ttypes import InputDataObjectType
from airavata.model.credential.store.ttypes import (
CredentialSummary,
@@ -688,6 +691,10 @@ class CredentialSummarySerializer(
class StoragePreferenceSerializer(
thrift_utils.create_serializer_class(StoragePreference)):
+ url = FullyEncodedHyperlinkedIdentityField(
+ view_name='django_airavata_api:storage-preference-detail',
+ lookup_field='storageResourceId',
+ lookup_url_kwarg='storage_resource_id')
def to_representation(self, instance):
ret = super().to_representation(instance)
@@ -704,3 +711,13 @@ class GatewayResourceProfileSerializer(
lookup_field='gatewayID',
lookup_url_kwarg='gateway_id')
storagePreferences = StoragePreferenceSerializer(many=True)
+
+
+class StorageResourceSerializer(
+ thrift_utils.create_serializer_class(StorageResourceDescription)):
+ url = FullyEncodedHyperlinkedIdentityField(
+ view_name='django_airavata_api:storage-resource-detail',
+ lookup_field='storageResourceId',
+ lookup_url_kwarg='storage_resource_id')
+ creationTime = UTCPosixTimestampDateTimeField()
+ updateTime = UTCPosixTimestampDateTimeField()
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 1ec0d71..9184f0e 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
@@ -108,6 +108,8 @@ exports.services = {
ServiceFactory,
SharedEntityService: ServiceFactory.service("SharedEntities"),
SshJobSubmissionService,
+ StoragePreferenceService: ServiceFactory.service("StoragePreferences"),
+ StorageResourceService: ServiceFactory.service("StorageResources"),
UnicoreDataMovementService,
UnicoreJobSubmissionService,
UserProfileService
diff --git a/django_airavata/apps/api/static/django_airavata_api/js/models/StorageResourceDescription.js b/django_airavata/apps/api/static/django_airavata_api/js/models/StorageResourceDescription.js
new file mode 100644
index 0000000..554c543
--- /dev/null
+++ b/django_airavata/apps/api/static/django_airavata_api/js/models/StorageResourceDescription.js
@@ -0,0 +1,17 @@
+import BaseModel from "./BaseModel";
+
+const FIELDS = [
+ "storageResourceId",
+ "hostName",
+ "storageResourceDescription",
+ "enabled",
+ "dataMovementInterfaces",
+ "creationTime",
+ "updateTime"
+];
+
+export default class StorageResourceDescription extends BaseModel {
+ constructor(data = {}) {
+ super(FIELDS, data);
+ }
+}
diff --git a/django_airavata/apps/api/static/django_airavata_api/js/service_config.js b/django_airavata/apps/api/static/django_airavata_api/js/service_config.js
index 7f22e29..138c870 100644
--- a/django_airavata/apps/api/static/django_airavata_api/js/service_config.js
+++ b/django_airavata/apps/api/static/django_airavata_api/js/service_config.js
@@ -6,6 +6,8 @@ import GatewayResourceProfile from "./models/GatewayResourceProfile";
import Group from "./models/Group";
import GroupResourceProfile from "./models/GroupResourceProfile";
import SharedEntity from "./models/SharedEntity";
+import StoragePreference from "./models/StoragePreference";
+import StorageResourceDescription from "./models/StorageResourceDescription";
import UserProfile from "./models/UserProfile";
import ApplicationInterfaceDefinition from "./models/ApplicationInterfaceDefinition";
import BatchQueue from "./models/BatchQueue";
@@ -239,6 +241,25 @@ export default {
],
modelClass: SharedEntity
},
+ StoragePreferences: {
+ url: "/api/storage-preferences/",
+ viewSet: true,
+ modelClass: StoragePreference
+ },
+ StorageResources: {
+ url: "/api/storage-resources",
+ viewSet: [
+ {
+ name: "retrieve"
+ },
+ {
+ name: "names",
+ url: "/api/storage-resources/all_names/",
+ requestType: "get"
+ }
+ ],
+ modelClass: StorageResourceDescription
+ },
UserProfiles: {
url: "/api/user-profiles",
viewSet: [
diff --git a/django_airavata/apps/api/urls.py b/django_airavata/apps/api/urls.py
index b610aba..a8d6a8b 100644
--- a/django_airavata/apps/api/urls.py
+++ b/django_airavata/apps/api/urls.py
@@ -30,11 +30,16 @@ router.register(r'shared-entities', views.SharedEntityViewSet,
base_name='shared-entity')
router.register(r'compute-resources', views.ComputeResourceViewSet,
base_name='compute-resource')
+router.register(r'storage-resources', views.StorageResourceViewSet,
+ base_name='storage-resource')
router.register(r'credential-summaries', views.CredentialSummaryViewSet,
base_name='credential-summary')
router.register(r'gateway-resource-profiles',
views.GatewayResourceProfileViewSet,
base_name='gateway-resource-profile')
+router.register(r'storage-preferences',
+ views.StoragePreferenceViewSet,
+ base_name='storage-preference')
app_name = 'django_airavata_api'
urlpatterns = [
diff --git a/django_airavata/apps/api/views.py b/django_airavata/apps/api/views.py
index 625667f..16c2ed0 100644
--- a/django_airavata/apps/api/views.py
+++ b/django_airavata/apps/api/views.py
@@ -955,3 +955,55 @@ class GetCurrentGatewayResourceProfile(APIView):
serializer = serializers.GatewayResourceProfileSerializer(
gateway_resource_profile, context={'request': request})
return Response(serializer.data)
+
+
+class StorageResourceViewSet(mixins.RetrieveModelMixin,
+ GenericAPIBackedViewSet):
+ serializer_class = serializers.StorageResourceSerializer
+ lookup_field = 'storage_resource_id'
+ lookup_value_regex = '[^/]+'
+
+ def get_instance(self, lookup_value, format=None):
+ return self.request.airavata_client.getStorageResource(
+ self.authz_token, lookup_value)
+
+ @list_route()
+ def all_names(self, request, format=None):
+ """Return a map of compute resource names keyed by resource id."""
+ return Response(
+ request.airavata_client.getAllStorageResourceNames(
+ request.authz_token))
+
+
+class StoragePreferenceViewSet(APIBackedViewSet):
+ serializer_class = serializers.StoragePreferenceSerializer
+ lookup_field = 'storage_resource_id'
+ lookup_value_regex = '[^/]+'
+
+ def get_list(self):
+ return self.request.airavata_client.getAllGatewayStoragePreferences(
+ self.authz_token, settings.GATEWAY_ID)
+
+ def get_instance(self, lookup_value):
+ return self.request.airavata_client.getGatewayStoragePreference(
+ self.authz_token, settings.GATEWAY_ID, lookup_value)
+
+ def perform_create(self, serializer):
+ storage_preference = serializer.save()
+ self.request.airavata_client.addGatewayStoragePreference(
+ self.authz_token,
+ settings.GATEWAY_ID,
+ storage_preference.storageResourceId,
+ storage_preference)
+
+ def perform_update(self, serializer):
+ storage_preference = serializer.save()
+ self.request.airavata_client.updateGatewayStoragePreference(
+ self.authz_token,
+ settings.GATEWAY_ID,
+ storage_preference.storageResourceId,
+ storage_preference)
+
+ def perform_destroy(self, instance):
+ self.request.airavata_client.deleteGatewayStoragePreference(
+ self.authz_token, settings.GATEWAY_ID, instance.storageResourceId)
diff --git a/django_airavata/static/common/js/layouts/ListLayout.vue b/django_airavata/static/common/js/layouts/ListLayout.vue
index 3a28b7d..ec27700 100644
--- a/django_airavata/static/common/js/layouts/ListLayout.vue
+++ b/django_airavata/static/common/js/layouts/ListLayout.vue
@@ -22,6 +22,11 @@
</div>
<div class="row">
<div class="col">
+ <slot name="new-item-editor"></slot>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col">
<slot name="item-list" :items="itemsList">Item List goes here</slot>
<pager v-if="itemsPaginator" :paginator="itemsPaginator" next="nextItems" v-on:previous="previousItems"></pager>
</div>