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/08/14 19:51:48 UTC

[airavata-django-portal] 06/13: AIRAVATA-2727 Implement update of group compute pref

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 b57d9da95db8f947660f200f99ddf18873cab9cf
Author: Marcus Christie <ma...@iu.edu>
AuthorDate: Mon Aug 13 13:05:13 2018 -0400

    AIRAVATA-2727 Implement update of group compute pref
---
 .../ComputePreference.vue                          | 135 +++++++--------------
 .../GroupComputeResourcePreference.vue             |   1 +
 django_airavata/apps/api/serializers.py            |  16 +++
 .../js/models/GroupResourceProfile.js              |  37 ++++++
 django_airavata/apps/api/views.py                  |  10 +-
 .../static/common/js/layouts/ListLayout.vue        |  10 +-
 6 files changed, 112 insertions(+), 97 deletions(-)

diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/ComputePreference.vue b/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/ComputePreference.vue
index c83863c..35ad166 100644
--- a/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/ComputePreference.vue
+++ b/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/ComputePreference.vue
@@ -50,6 +50,11 @@
         </div>
       </div>
     </div>
+    <div class="row">
+        <div class="col d-flex justify-content-end">
+            <b-button variant="primary" @click="save">Save</b-button>
+        </div>
+    </div>
   </div>
 </template>
 
@@ -73,6 +78,9 @@
       host_id: {
         type: String,
       },
+      groupResourceProfile: {
+        type: models.GroupResourceProfile,
+      },
       computeResourcePolicy: {
         type: models.ComputeResourcePolicy
       },
@@ -98,50 +106,6 @@
         selectedComputeResourceIndex: null,
         localComputeResourcePolicy: this.computeResourcePolicy ? this.computeResourcePolicy.clone() : null,
         localBatchQueueResourcePolicies: this.batchQueueResourcePolicies ? this.batchQueueResourcePolicies.map(pol => pol.clone()) : [],
-        dataMovementProtocols: [{
-          name: "LOCAL",
-          enabled: false,
-          value: 0
-        }, {
-          name: "SCP",
-          enabled: false,
-          value: 1
-        }, {
-          name: "GridFTP",
-          enabled: false,
-          value: 2
-        }, {
-          name: "UNICORE_STORAGE_SERVICE",
-          enabled: false,
-          value: 3
-        },],
-        jobSubmissionProtocols: [
-          {
-            name: "Local",
-            enabled: false,
-            value: 0
-          },
-          {
-            name: "SSH",
-            enabled: false,
-            value: 1
-          },
-          {
-            name: "GLOBUS",
-            enabled: false,
-            value: 2
-          },
-          {
-            name: "UNICORE",
-            enabled: false,
-            value: 3
-          },
-          {
-            name: "Cloud",
-            enabled: false,
-            value: 4
-          },
-        ],
         computeResource: {
           batchQueues: [],
           jobSubmissionInterfaces: []
@@ -153,15 +117,6 @@
       fetchComputeResources: function () {
         return DjangoAiravataAPI.utils.FetchUtils.get('/api/compute-resources/all_names_list').then((value) => this.computeResources = value);
       },
-      createComputeResourcePolicy: function () {
-        return {
-          allowedBatchQueues: [],
-          batchQueueResourcePolicies: [],
-          computeResourceId: null,
-          groupResourceProfileId: null,
-          resourcePolicyId: null
-        }
-      },
       batchQueueChecked: function(batchQueue, checked) {
         if (checked) {
           this.localComputeResourcePolicy.allowedBatchQueues.push(batchQueue.queueName);
@@ -182,6 +137,9 @@
           if (existingPolicy) {
             Object.assign(existingPolicy, batchQueueResourcePolicy);
           } else {
+            // For new BatchQueueResourcePolicy instances, set the parent ids
+            batchQueueResourcePolicy.groupResourceProfileId = this.id;
+            batchQueueResourcePolicy.computeResourceId = this.host_id;
             this.localBatchQueueResourcePolicies.push(batchQueueResourcePolicy);
           }
         } else {
@@ -191,46 +149,47 @@
           }
         }
       },
-      createGroupSSHAccountProvisionerConfigs: function () {
-        this.data.groupSSHAccountProvisionerConfigs.push({
-          resourceId: this.data.computeResourceId,
-          groupResourceProfileId: this.data.groupResourceProfileId,
-          configName: null,
-          configValue: null
+      fetchComputeResource: function (id) {
+        DjangoAiravataAPI.utils.FetchUtils.get("/api/compute-resources/" + encodeURIComponent(id) + "/").then(value => {
+          this.computeResource = value;
         });
       },
-      fetchComputeResource: function (id) {
-        console.log("Fetching compute Resource", id);
-        if (id) {
-          DjangoAiravataAPI.utils.FetchUtils.get("/api/compute-resources/" + encodeURIComponent(id) + "/").then(value => {
-            console.log("Compute  Resource", value);
-            this.computeResource = value;
-            this.computeResource.jobSubmissionInterfaces.forEach((jobSubmissionInterface) => {
-              this.jobSubmissionProtocols[jobSubmissionInterface.jobSubmissionProtocol].enabled = true;
+      save: function() {
+        let groupResourceProfile = this.groupResourceProfile.clone();
+        groupResourceProfile.mergeComputeResourcePreference(this.data, this.localComputeResourcePolicy, this.localBatchQueueResourcePolicies);
+        // TODO: success and error handling are the same so we can just combine those
+        if (groupResourceProfile.groupResourceProfileId) {
+          DjangoAiravataAPI.services.ServiceFactory.service("GroupResourceProfiles").update({data: groupResourceProfile, lookup: groupResourceProfile.groupResourceProfileId})
+            .then(groupResourceProfile => {
+              // Navigate back to GroupResourceProfile with success message
+              this.$router.push({
+                name: 'group_resource_preference', params: {
+                  value: groupResourceProfile,
+                  id: groupResourceProfile.groupResourceProfileId
+                }
+              });
+            })
+            .catch(error => {
+              // TODO: handle error
+              console.log("Error occurred", error);
             });
-            this.computeResource.dataMovementInterfaces.forEach((dataMovementInterface) => {
-              this.dataMovementProtocols[dataMovementInterface.dataMovementProtocol].enabled = true;
+        } else {
+          DjangoAiravataAPI.services.ServiceFactory.service("GroupResourceProfiles").create({data: groupResourceProfile})
+            .then(groupResourceProfile => {
+              // Navigate back to GroupResourceProfile with success message
+              this.$router.push({
+                name: 'group_resource_preference', params: {
+                  value: groupResourceProfile,
+                  id: groupResourceProfile.groupResourceProfileId
+                }
+              });
+            })
+            .catch(error => {
+              // TODO: handle error
+              console.log("Error occurred", error);
             });
-          });
-        }
-      },
-      continueHandler: function () {
-        this.enablePopup = false;
-        if (this.computeResources && this.computeResources.length > 0) {
-          this.fetchComputeResource(this.computeResources[this.selectedComputeResourceIndex].host_id);
         }
       }
     },
-    watch: {}
-  }
-</script>
-
-<style scoped>
-  .batch-queue {
-    margin-top: 10px;
-  }
-
-  .popup-select {
-    height: 100%;
   }
-</style>
+</script>
\ No newline at end of file
diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/GroupComputeResourcePreference.vue b/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/GroupComputeResourcePreference.vue
index f6065c0..fd98a6e 100644
--- a/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/GroupComputeResourcePreference.vue
+++ b/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/GroupComputeResourcePreference.vue
@@ -112,6 +112,7 @@
             value: computeResourcePreference,
             id: this.data.groupResourceProfileId,
             host_id: computeResourceId,
+            groupResourceProfile: this.data,
             computeResourcePolicy: computeResourcePolicy,
             batchQueueResourcePolicies: batchQueueResourcePolicies,
           }
diff --git a/django_airavata/apps/api/serializers.py b/django_airavata/apps/api/serializers.py
index 020ade4..ec8cee8 100644
--- a/django_airavata/apps/api/serializers.py
+++ b/django_airavata/apps/api/serializers.py
@@ -451,6 +451,22 @@ class GroupResourceProfileSerializer(
     updatedTime = UTCPosixTimestampDateTimeField(allow_null=True)
     userHasWriteAccess = serializers.SerializerMethodField()
 
+    def update(self, instance, validated_data):
+        result = super().update(instance, validated_data)
+        result._removed_batch_queue_resource_policies = []
+        # Find all batch queue resource policies that were removed
+        for batch_queue_resource_policy in instance.batchQueueResourcePolicies:
+            existing_batch_queue_resource_policy_for_update = next(
+                (bq for bq in result.batchQueueResourcePolicies
+                 if bq.computeResourceId ==
+                    batch_queue_resource_policy.computeResourceId
+                    and bq.queuename == batch_queue_resource_policy.queuename),
+                None)
+            if not existing_batch_queue_resource_policy_for_update:
+                result._removed_batch_queue_resource_policies.append(
+                    batch_queue_resource_policy)
+        return result
+
     def get_userHasWriteAccess(self, groupResourceProfile):
         request = self.context['request']
         return request.airavata_client.userHasAccess(
diff --git a/django_airavata/apps/api/static/django_airavata_api/js/models/GroupResourceProfile.js b/django_airavata/apps/api/static/django_airavata_api/js/models/GroupResourceProfile.js
index e24045a..259cfcf 100644
--- a/django_airavata/apps/api/static/django_airavata_api/js/models/GroupResourceProfile.js
+++ b/django_airavata/apps/api/static/django_airavata_api/js/models/GroupResourceProfile.js
@@ -66,4 +66,41 @@ export default class GroupResourceProfile extends BaseModel {
             }
         }
     }
+
+    mergeComputeResourcePreference(computeResourcePreference, computeResourcePolicy, batchQueueResourcePolicies) {
+        // merge/add computeResourcePreference and computeResourcePolicy
+        const existingComputeResourcePreference = this.computePreferences.find(pref => pref.computeResourceId === computeResourcePreference.computeResourceId);
+        if (existingComputeResourcePreference) {
+            Object.assign(existingComputeResourcePreference, computeResourcePreference);
+        } else {
+            this.computePreferences.push(computeResourcePreference);
+        }
+        const existingComputeResourcePolicy = this.computeResourcePolicies.find(pol => pol.computeResourceId === computeResourcePolicy.computeResourceId);
+        if (existingComputeResourcePolicy) {
+            Object.assign(existingComputeResourcePolicy, computeResourcePolicy);
+        } else {
+            this.computeResourcePolicies.push(computeResourcePolicy);
+        }
+        // merge/add/remove batchQueueResourcePolicies
+        const existingBatchQueueResourcePolicies = this.batchQueueResourcePolicies.filter(pol => pol.computeResourceId === computeResourcePreference.computeResourceId);
+        for (const batchQueueResourcePolicy of batchQueueResourcePolicies) {
+            const existingBatchQueueResourcePolicy = existingBatchQueueResourcePolicies.find(pol => pol.queuename === batchQueueResourcePolicy.queuename);
+            if (existingBatchQueueResourcePolicy) {
+                Object.assign(existingBatchQueueResourcePolicy, batchQueueResourcePolicy);
+                const existingBatchQueueResourcePolicyIndex = existingBatchQueueResourcePolicies.findIndex(pol => pol.queuename === batchQueueResourcePolicy.queuename);
+                if (existingBatchQueueResourcePolicyIndex >= 0) {
+                    existingBatchQueueResourcePolicies.splice(existingBatchQueueResourcePolicyIndex, 1);
+                }
+            } else {
+                this.batchQueueResourcePolicies.push(batchQueueResourcePolicy);
+            }
+        }
+        for (const existingBatchQueueResourcePolicy of existingBatchQueueResourcePolicies) {
+            const existingBatchQueueResourcePolicyIndex = this.batchQueueResourcePolicies.findIndex(
+                pol => pol.computeResourceId === existingBatchQueueResourcePolicy.computeResourceId && pol.queuename === existingBatchQueueResourcePolicy.queuename);
+            if (existingBatchQueueResourcePolicyIndex >= 0) {
+                this.batchQueueResourcePolicies.splice(existingBatchQueueResourcePolicyIndex, 1);
+            }
+        }
+    }
 }
diff --git a/django_airavata/apps/api/views.py b/django_airavata/apps/api/views.py
index c40bf7f..2ad5ec5 100644
--- a/django_airavata/apps/api/views.py
+++ b/django_airavata/apps/api/views.py
@@ -698,7 +698,15 @@ class GroupResourceProfileViewSet(APIBackedViewSet):
         serializer.instance = group_resource_profile
 
     def perform_update(self, serializer):
-        self.request.airavata_client.updateGroupResourceProfile(self.authz_token, serializer.save())
+        grp = serializer.save()
+        for removed_batch_queue_resource_policy \
+                in grp._removed_batch_queue_resource_policies:
+            self.request.airavata_client.removeGroupBatchQueueResourcePolicy(
+                self.authz_token,
+                removed_batch_queue_resource_policy.resourcePolicyId)
+        log.debug("batch queue res policies: {}".format(grp.batchQueueResourcePolicies))
+        self.request.airavata_client.updateGroupResourceProfile(
+            self.authz_token, grp)
 
 
 class SharedEntityGroups(APIBackedViewSet):
diff --git a/django_airavata/static/common/js/layouts/ListLayout.vue b/django_airavata/static/common/js/layouts/ListLayout.vue
index 8ab1af8..a947934 100644
--- a/django_airavata/static/common/js/layouts/ListLayout.vue
+++ b/django_airavata/static/common/js/layouts/ListLayout.vue
@@ -6,7 +6,7 @@
                     <h1 class="h4 mb-4">{{ title }}</h1>
                 </slot>
             </div>
-            <div id="col-new-item" class="col">
+            <div class="col d-flex justify-content-end align-items-baseline">
                 <slot name="new-item-button">
                     <b-btn variant="primary" @click="addNewItem">
                         {{ newItemButtonText }} <i class="fa fa-plus" aria-hidden="true"></i>
@@ -71,10 +71,4 @@ export default {
         },
     },
 }
-</script>
-
-<style>
-#col-new-item {
-    text-align: right;
-}
-</style>
+</script>
\ No newline at end of file