You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by at...@apache.org on 2015/08/11 10:00:20 UTC

ambari git commit: AMBARI-12669 Optimize Manage Config Groups dialog loading time. (atkach)

Repository: ambari
Updated Branches:
  refs/heads/branch-2.1 c5dbabc29 -> 6257802b3


AMBARI-12669 Optimize Manage Config Groups dialog loading time. (atkach)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/6257802b
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/6257802b
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/6257802b

Branch: refs/heads/branch-2.1
Commit: 6257802b3debd5d605b731dfad442a8e8ebf38fb
Parents: c5dbabc
Author: Andrii Tkach <at...@hortonworks.com>
Authored: Mon Aug 10 17:11:20 2015 +0300
Committer: Andrii Tkach <at...@hortonworks.com>
Committed: Tue Aug 11 10:50:39 2015 +0300

----------------------------------------------------------------------
 .../service/manage_config_groups_controller.js  | 62 ++++++++++++--------
 .../app/mappers/configs/config_groups_mapper.js | 29 +++++----
 ambari-web/app/models/config_group.js           |  2 +-
 ambari-web/app/models/configs/config_group.js   | 41 +++++++------
 ambari-web/app/utils/helper.js                  | 30 ++++++----
 .../main/service/manage_config_groups_view.js   |  5 ++
 ambari-web/test/utils/helper_test.js            | 27 ++++++++-
 7 files changed, 129 insertions(+), 67 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/6257802b/ambari-web/app/controllers/main/service/manage_config_groups_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/manage_config_groups_controller.js b/ambari-web/app/controllers/main/service/manage_config_groups_controller.js
index e1d44ca..4ce4145 100644
--- a/ambari-web/app/controllers/main/service/manage_config_groups_controller.js
+++ b/ambari-web/app/controllers/main/service/manage_config_groups_controller.js
@@ -63,6 +63,21 @@ App.ManageConfigGroupsController = Em.Controller.extend(App.ConfigOverridable, {
   originalConfigGroups: [],
 
   /**
+   * map of <code>originalConfigGroups</code>
+   * @type {object}
+   */
+  originalConfigGroupsMap: function() {
+    var map = {};
+
+    this.get('originalConfigGroups').forEach(function (item) {
+      if (!item.get('isDefault')) {
+        map[item.get('id')] = item;
+      }
+    }, this);
+    return map;
+  }.property('originalConfigGroups'),
+
+  /**
    * @type {App.ConfigGroup}
    */
   selectedConfigGroup: null,
@@ -115,7 +130,7 @@ App.ManageConfigGroupsController = Em.Controller.extend(App.ConfigOverridable, {
   isDeleteHostsDisabled: function () {
     var selectedConfigGroup = this.get('selectedConfigGroup');
     if (selectedConfigGroup) {
-      return selectedConfigGroup.isDefault || this.get('selectedHosts').length === 0;
+      return selectedConfigGroup.get('isDefault') || this.get('selectedHosts').length === 0;
     }
     return true;
   }.property('selectedConfigGroup', 'selectedConfigGroup.hosts.length', 'selectedHosts.length'),
@@ -139,12 +154,14 @@ App.ManageConfigGroupsController = Em.Controller.extend(App.ConfigOverridable, {
     var groupsToCreate = [];
     var groups = this.get('configGroups');
     var originalGroups = this.get('originalConfigGroups');
+    var originalGroupsMap = this.get('originalConfigGroupsMap');
+
     // remove default group
     var originalGroupsCopy = originalGroups.without(originalGroups.findProperty('isDefault'));
     var originalGroupsIds = originalGroupsCopy.mapProperty('id');
     groups.forEach(function (group) {
       if (!group.get('isDefault')) {
-        var originalGroup = originalGroupsCopy.findProperty('id', group.get('id'));
+        var originalGroup = originalGroupsMap[group.get('id')];
         if (originalGroup) {
           if (!(JSON.stringify(group.get('hosts').slice().sort()) === JSON.stringify(originalGroup.get('hosts').sort()))) {
             groupsToClearHosts.push(group.set('id', originalGroup.get('id')));
@@ -162,7 +179,7 @@ App.ManageConfigGroupsController = Em.Controller.extend(App.ConfigOverridable, {
       }
     });
     originalGroupsIds.forEach(function (id) {
-      groupsToDelete.push(originalGroupsCopy.findProperty('id', id));
+      groupsToDelete.push(originalGroupsMap[id]);
     }, this);
     return {
       toClearHosts: groupsToClearHosts,
@@ -221,6 +238,7 @@ App.ManageConfigGroupsController = Em.Controller.extend(App.ConfigOverridable, {
     }
     else {
       this.loadHostsFromServer();
+      this.loadConfigGroups(this.get('serviceName'));
     }
   },
 
@@ -286,7 +304,6 @@ App.ManageConfigGroupsController = Em.Controller.extend(App.ConfigOverridable, {
     }, this);
 
     this.set('clusterHosts', wrappedHosts);
-    this.loadConfigGroups(this.get('serviceName'));
   },
 
   /**
@@ -297,7 +314,6 @@ App.ManageConfigGroupsController = Em.Controller.extend(App.ConfigOverridable, {
   _loadHostsFromServerErrorCallback: function () {
     console.warn('ERROR: request to fetch all hosts failed');
     this.set('clusterHosts', []);
-    this.loadConfigGroups(this.get('serviceName'));
   },
 
   /**
@@ -340,10 +356,9 @@ App.ManageConfigGroupsController = Em.Controller.extend(App.ConfigOverridable, {
     var usedHosts = [];
     var unusedHosts = [];
     var serviceName = this.get('serviceName');
-    var serviceDisplayName =  App.StackService.find().findProperty('serviceName', this.get('serviceName')).get('displayName');
     var defaultConfigGroup = App.ConfigGroup.create({
-      name: serviceDisplayName + " Default",
-      description: "Default cluster level " + this.get('serviceName') + " configuration",
+      name: App.format.role(serviceName) + " Default",
+      description: "Default cluster level " + serviceName + " configuration",
       isDefault: true,
       parentConfigGroup: null,
       service: this.get('content'),
@@ -363,27 +378,26 @@ App.ManageConfigGroupsController = Em.Controller.extend(App.ConfigOverridable, {
           description: configGroup.description,
           isDefault: false,
           parentConfigGroup: defaultConfigGroup,
-          service: App.Service.find().findProperty('serviceName', configGroup.tag),
+          service: App.Service.find(configGroup.tag),
           hosts: hostNames,
-          configSiteTags: [],
+          configSiteTags: configGroup.desired_configs.map(function (config) {
+            if (!groupToTypeToTagMap[configGroup.group_name]) {
+              groupToTypeToTagMap[configGroup.group_name] = {}
+            }
+            groupToTypeToTagMap[configGroup.group_name][config.type] = config.tag;
+
+            return App.ConfigSiteTag.create({
+              site: config.type,
+              tag: config.tag
+            });
+          }),
           properties: [],
           apiResponse: configGroup
         });
-        usedHosts = usedHosts.concat(newConfigGroup.get('hosts'));
+        usedHosts = usedHosts.concat(hostNames);
         configGroups.push(newConfigGroup);
-        var newConfigGroupSiteTags = newConfigGroup.get('configSiteTags');
-        configGroup.desired_configs.forEach(function (config) {
-          newConfigGroupSiteTags.push(App.ConfigSiteTag.create({
-            site: config.type,
-            tag: config.tag
-          }));
-          if (!groupToTypeToTagMap[configGroup.group_name]) {
-            groupToTypeToTagMap[configGroup.group_name] = {}
-          }
-          groupToTypeToTagMap[configGroup.group_name][config.type] = config.tag;
-        });
       }, this);
-      unusedHosts = this.get('clusterHosts').mapProperty('hostName');
+      unusedHosts = App.get('allHostNames').slice(0);
       usedHosts.uniq().forEach(function (host) {
         unusedHosts = unusedHosts.without(host);
       }, this);
@@ -831,7 +845,7 @@ App.ManageConfigGroupsController = Em.Controller.extend(App.ConfigOverridable, {
 
       updateConfigGroupOnServicePage: function () {
         var selectedConfigGroup = configsController.get('selectedConfigGroup');
-        var managedConfigGroups = configsController.get('configGroups');
+        var managedConfigGroups = configsController.get('configGroups').slice(0);
         if (!controller) {
           controller = App.router.get('mainServiceInfoConfigsController');
           //controller.set('configGroups', managedConfigGroups);

http://git-wip-us.apache.org/repos/asf/ambari/blob/6257802b/ambari-web/app/mappers/configs/config_groups_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/configs/config_groups_mapper.js b/ambari-web/app/mappers/configs/config_groups_mapper.js
index ae6d049..48758a7 100644
--- a/ambari-web/app/mappers/configs/config_groups_mapper.js
+++ b/ambari-web/app/mappers/configs/config_groups_mapper.js
@@ -31,7 +31,8 @@ App.configGroupsMapper = App.QuickDataMapper.create({
     service_name: 'ConfigGroup.tag',
     description: 'ConfigGroup.description',
     host_names: 'hosts',
-    service_id: 'ConfigGroup.tag'
+    service_id: 'ConfigGroup.tag',
+    desired_configs: 'ConfigGroup.desired_configs'
   },
 
   /**
@@ -48,6 +49,7 @@ App.configGroupsMapper = App.QuickDataMapper.create({
 
 
   map: function (json, mapFromVersions, serviceNames) {
+    console.time('App.configGroupsMapper');
     if (serviceNames && serviceNames.length > 0) {
       var configGroups = [];
 
@@ -59,6 +61,7 @@ App.configGroupsMapper = App.QuickDataMapper.create({
        * will not contain property for this service which mean all host belongs to default group
        */
       var hostNamesForService = {};
+      var configGroupsForService = {};
 
       if (json && json.items) {
         json.items.forEach(function (configGroup) {
@@ -75,17 +78,23 @@ App.configGroupsMapper = App.QuickDataMapper.create({
              * creating (if not exists) field in <code>hostNamesForService<code> with host names for default group
              */
             if (!hostNamesForService[configGroup.service_name]) {
-              hostNamesForService[configGroup.service_name] = $.merge([], App.get('allHostNames'));
+              hostNamesForService[configGroup.service_name] = App.get('allHostNames').slice(0);
             }
 
+            if (!configGroupsForService[configGroup.service_name]) {
+              configGroupsForService[configGroup.service_name] = [configGroup.id];
+            }
+            configGroupsForService[configGroup.service_name].push(configGroup.id);
+
             /**
              * excluding host names that belongs for current config group from default group
              */
             configGroup.hosts.forEach(function (host) {
               hostNamesForService[configGroup.service_name].splice(hostNamesForService[configGroup.service_name].indexOf(host), 1);
             });
-            var template = mapFromVersions ? this.get('config2') : this.get('config');
-            configGroups.push(this.parseIt(configGroup, template));
+            configGroup = this.parseIt(configGroup, (mapFromVersions ? this.get('config2') : this.get('config')));
+            configGroup.parent_config_group_id = configGroup.service_name + '0';
+            configGroups.push(configGroup);
           }
         }, this);
       }
@@ -94,12 +103,7 @@ App.configGroupsMapper = App.QuickDataMapper.create({
        * generating default config groups
        */
       serviceNames.forEach(function (serviceName) {
-        var defaultGroup = App.ServiceConfigGroup.find().findProperty('id', serviceName + "0");
-        if (!defaultGroup) {
-          configGroups.push(this.generateDefaultGroup(serviceName, hostNamesForService[serviceName]));
-        } else {
-          defaultGroup.set('hostNames', hostNamesForService[serviceName] || App.get('allHostNames'));
-        }
+        configGroups.push(this.generateDefaultGroup(serviceName, hostNamesForService[serviceName], configGroupsForService[serviceName]));
       }, this);
 
 
@@ -109,15 +113,17 @@ App.configGroupsMapper = App.QuickDataMapper.create({
       App.store.loadMany(this.get('model'), configGroups);
       App.store.commit();
     }
+    console.timeEnd('App.configGroupsMapper');
   },
 
   /**
    * generate mock object for default config group
    * @param {string} serviceName
    * @param {string[]} [hostNames=null]
+   * @param {Array} childConfigGroups
    * @returns {{id: string, config_group_id: string, name: string, service_name: string, description: string, host_names: [string], service_id: string}}
    */
-  generateDefaultGroup: function (serviceName, hostNames) {
+  generateDefaultGroup: function (serviceName, hostNames, childConfigGroups) {
     var displayName = App.StackService.find(serviceName).get('displayName');
     return {
       id: serviceName + '0',
@@ -126,6 +132,7 @@ App.configGroupsMapper = App.QuickDataMapper.create({
       service_name: serviceName,
       description: 'Default cluster level ' + displayName + ' configuration',
       host_names: hostNames ? hostNames : App.get('allHostNames'),
+      child_config_groups: childConfigGroups ? childConfigGroups.uniq() : [],
       service_id: serviceName
     }
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/6257802b/ambari-web/app/models/config_group.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/config_group.js b/ambari-web/app/models/config_group.js
index 8c19494..515ecee 100644
--- a/ambari-web/app/models/config_group.js
+++ b/ambari-web/app/models/config_group.js
@@ -140,7 +140,7 @@ App.ConfigGroup = Ember.Object.extend({
       }
     });
     return availableHosts;
-  }.property('isDefault', 'parentConfigGroup', 'childConfigGroups', 'parentConfigGroup.hosts.@each'),
+  }.property('isDefault', 'parentConfigGroup', 'childConfigGroups', 'parentConfigGroup.hosts.@each', 'clusterHosts'),
 
   isAddHostsDisabled: function () {
     return (this.get('isDefault') || this.get('availableHosts.length') === 0);

http://git-wip-us.apache.org/repos/asf/ambari/blob/6257802b/ambari-web/app/models/configs/config_group.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/configs/config_group.js b/ambari-web/app/models/configs/config_group.js
index 0ad49ad..be431d8 100644
--- a/ambari-web/app/models/configs/config_group.js
+++ b/ambari-web/app/models/configs/config_group.js
@@ -44,10 +44,25 @@ App.ServiceConfigGroup = DS.Model.extend({
   hostNames: DS.attr('array'),
   configVersions: DS.hasMany('App.ConfigVersion'),
   service: DS.belongsTo('App.Service'),
+  desiredConfigs: DS.attr('array'),
 
   /**
-   * same as hostNames
-   * @type {String[]}
+   * all hosts that belong to cluster
+   */
+  clusterHostsBinding: 'App.router.manageConfigGroupsController.clusterHosts',
+
+  /**
+   * Hosts on which this configuration-group
+   * is to be applied. For a service, a host can
+   * belong to only one non-default configuration-group.
+   *
+   * When {#isDefault} is false, this contains hosts
+   * for which the overrides will apply.
+   *
+   * When {#isDefault} is true, this value is empty, as
+   * it dynamically reflects hosts not belonging to other
+   * non-default groups.
+   * @type {Array}
    */
   hosts: function() {
     return this.get('hostNames');
@@ -84,21 +99,6 @@ App.ServiceConfigGroup = DS.Model.extend({
    */
   childConfigGroups: DS.hasMany('App.ServiceConfigGroup'),
 
-  /**
-   * Hosts on which this configuration-group
-   * is to be applied. For a service, a host can
-   * belong to only one non-default configuration-group.
-   *
-   * When {#isDefault} is false, this contains hosts
-   * for which the overrides will apply.
-   *
-   * When {#isDefault} is true, this value is empty, as
-   * it dynamically reflects hosts not belonging to other
-   * non-default groups.
-   *
-   */
-  properties: DS.attr('array'),
-
   hash: DS.attr('string'),
   /**
    * Provides a display friendly name. This includes trimming
@@ -143,12 +143,17 @@ App.ServiceConfigGroup = DS.Model.extend({
       }
     });
     return availableHosts;
-  }.property('isDefault', 'parentConfigGroup', 'childConfigGroups', 'parentConfigGroup.hosts.@each'),
+  }.property('isDefault', 'parentConfigGroup', 'childConfigGroups', 'parentConfigGroup.hosts.@each', 'clusterHosts'),
 
   isAddHostsDisabled: function () {
     return (this.get('isDefault') || this.get('availableHosts.length') === 0);
   }.property('availableHosts.length'),
 
+  /**
+   * @type {Array}
+   */
+  properties: [],
+
   propertiesList: function () {
     var result = '';
     this.get('properties').forEach(function (item) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/6257802b/ambari-web/app/utils/helper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/helper.js b/ambari-web/app/utils/helper.js
index 0775099..fefc703 100644
--- a/ambari-web/app/utils/helper.js
+++ b/ambari-web/app/utils/helper.js
@@ -414,6 +414,12 @@ App.format = {
   },
 
   /**
+   * cached map of service and component names
+   * @type {object}
+   */
+  stackRolesMap: {},
+
+  /**
    * convert role to readable string
    *
    * @memberof App.format
@@ -421,19 +427,21 @@ App.format = {
    * @param {string} role
    * return {string}
    */
-  role:function (role) {
-    var result;
+  role: function (role) {
     var models = [App.StackService, App.StackServiceComponent];
-    models.forEach(function(model){
-      var instance =  model.find().findProperty('id',role);
-      if (instance) {
-        result = instance.get('displayName');
-      }
-    },this);
-    if (!result)  {
-      result =  this.normalizeName(role);
+
+    if (App.isEmptyObject(this.stackRolesMap)) {
+      models.forEach(function (model) {
+        model.find().forEach(function (item) {
+          this.stackRolesMap[item.get('id')] = item.get('displayName');
+        }, this);
+      }, this);
     }
-    return result;
+
+    if (this.stackRolesMap[role]) {
+      return this.stackRolesMap[role];
+    }
+    return this.normalizeName(role);
   },
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/6257802b/ambari-web/app/views/main/service/manage_config_groups_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/service/manage_config_groups_view.js b/ambari-web/app/views/main/service/manage_config_groups_view.js
index 8b44474..8a42393 100644
--- a/ambari-web/app/views/main/service/manage_config_groups_view.js
+++ b/ambari-web/app/views/main/service/manage_config_groups_view.js
@@ -100,6 +100,11 @@ App.MainServiceManageConfigGroupView = Em.View.extend({
     App.tooltip($("[rel='button-info-dropdown']"), {placement: 'left'});
   },
 
+  willDestroyElement: function () {
+    this.get('controller.configGroups').clear();
+    this.get('controller.originalConfigGroups').clear();
+  },
+
   /**
    * Disable actions remove and rename for Default config group
    * @method buttonObserver

http://git-wip-us.apache.org/repos/asf/ambari/blob/6257802b/ambari-web/test/utils/helper_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/utils/helper_test.js b/ambari-web/test/utils/helper_test.js
index b273120..63fd59d 100644
--- a/ambari-web/test/utils/helper_test.js
+++ b/ambari-web/test/utils/helper_test.js
@@ -321,7 +321,30 @@ describe('utils/helper', function() {
           })
         });
 
-      })
+      });
+
+      describe("#role()", function() {
+        beforeEach(function () {
+          sinon.stub(App.StackService, 'find').returns([Em.Object.create({
+            id: 'S1',
+            displayName: 's1'
+          })]);
+          sinon.stub(App.StackServiceComponent, 'find').returns([Em.Object.create({
+            id: 'C1',
+            displayName: 'c1'
+          })])
+        });
+        afterEach(function () {
+          App.StackService.find.restore();
+          App.StackServiceComponent.find.restore();
+        });
+        it("", function() {
+          App.format.stackRolesMap = {};
+          expect(App.format.role('S1')).to.equal('s1');
+          expect(App.format.role('C1')).to.equal('c1');
+          expect(App.format.stackRolesMap).to.not.be.empty;
+        });
+      });
     });
   });
   describe('#App.permit()', function() {
@@ -329,7 +352,7 @@ describe('utils/helper', function() {
       a1: 'v1',
       a2: 'v2',
       a3: 'v3'
-    }
+    };
 
     var tests = [
       {