Repository: ambari Updated Branches: refs/heads/trunk fd1264e62 -> 0d33d14dc
AMBARI-4743 Improve loading of Assign Masters step of wizard. (atkach) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/0d33d14d Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/0d33d14d Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/0d33d14d Branch: refs/heads/trunk Commit: 0d33d14dc38b4ccbc8eb36af7cb3f2e4569e2cab Parents: fd1264e Author: atkach <[email protected]> Authored: Wed Feb 19 20:42:11 2014 +0200 Committer: atkach <[email protected]> Committed: Wed Feb 19 20:42:11 2014 +0200 ---------------------------------------------------------------------- .../admin/highAvailability/step2_controller.js | 10 +- .../main/service/reassign/step2_controller.js | 6 +- .../app/controllers/wizard/step5_controller.js | 103 +++---------------- ambari-web/app/templates/wizard/step5.hbs | 1 - ambari-web/app/utils/helper.js | 17 +++ ambari-web/app/views/wizard/step5_view.js | 76 ++++++++++++-- 6 files changed, 109 insertions(+), 104 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/0d33d14d/ambari-web/app/controllers/main/admin/highAvailability/step2_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/admin/highAvailability/step2_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/step2_controller.js index 0db1711..b729100 100644 --- a/ambari-web/app/controllers/main/admin/highAvailability/step2_controller.js +++ b/ambari-web/app/controllers/main/admin/highAvailability/step2_controller.js @@ -58,7 +58,7 @@ App.HighAvailabilityWizardStep2Controller = App.WizardStep5Controller.extend({ mapping.pushObject(mappingObject); }, this); - mapping.sort(this.sortHostsByName); + mapping.sortBy('host_name'); return mapping; @@ -82,7 +82,6 @@ App.HighAvailabilityWizardStep2Controller = App.WizardStep5Controller.extend({ for (var index = 0; index < 3; index++) { masterComponents.push( { - availableHosts: [], component_name: "JOURNALNODE", display_name: "JournalNode", isHiveCoHost: false, @@ -96,7 +95,6 @@ App.HighAvailabilityWizardStep2Controller = App.WizardStep5Controller.extend({ //Create Additional NameNode masterComponents.push( { - availableHosts: [], component_name: "NAMENODE", display_name: "NameNode", isHiveCoHost: false, @@ -120,8 +118,10 @@ App.HighAvailabilityWizardStep2Controller = App.WizardStep5Controller.extend({ components.push.apply(components, result.filterProperty('component_name',"JOURNALNODE")); this.set('servicesMasters', components); - this.rebalanceComponentHosts("NAMENODE"); - this.rebalanceComponentHosts("JOURNALNODE"); + this.set('componentToRebalance', "NAMENODE"); + this.incrementProperty('rebalanceComponentHostsCounter'); + this.set('componentToRebalance', "JOURNALNODE"); + this.incrementProperty('rebalanceComponentHostsCounter'); } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/0d33d14d/ambari-web/app/controllers/main/service/reassign/step2_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/service/reassign/step2_controller.js b/ambari-web/app/controllers/main/service/reassign/step2_controller.js index 2c62f17..da91b05 100644 --- a/ambari-web/app/controllers/main/service/reassign/step2_controller.js +++ b/ambari-web/app/controllers/main/service/reassign/step2_controller.js @@ -27,7 +27,8 @@ App.ReassignMasterWizardStep2Controller = App.WizardStep5Controller.extend({ this._super(); if(this.get('content.reassign.component_name') == "NAMENODE" && !this.get('content.masterComponentHosts').findProperty('component', "SECONDARY_NAMENODE")){ this.set('showCurrentHost', false); - this.rebalanceComponentHosts('NAMENODE'); + this.set('componentToRebalance', 'NAMENODE'); + this.incrementProperty('rebalanceComponentHostsCounter'); }else{ this.set('showCurrentHost', true); this.rebalanceSingleComponentHosts(this.get('content.reassign.component_name')); @@ -51,7 +52,6 @@ App.ReassignMasterWizardStep2Controller = App.WizardStep5Controller.extend({ selectedHost: master.hostName, isInstalled: true, serviceId: App.HostComponent.find().findProperty('componentName', master.component).get('serviceName'), - availableHosts: [], isHiveCoHost: ['HIVE_METASTORE', 'WEBHCAT_SERVER'].contains(master.component), color: color }); @@ -77,7 +77,7 @@ App.ReassignMasterWizardStep2Controller = App.WizardStep5Controller.extend({ if (item.get('selectedHost') == this.get('currentHostId') && item.get('component_name') == this.get('content.reassign.component_name')) { item.set('selectedHost', preparedAvailableHosts.objectAt(0).host_name); } - preparedAvailableHosts.sort(this.sortHostsByName, this); + preparedAvailableHosts.sortBy('host_name'); item.set("availableHosts", preparedAvailableHosts); }, this); } http://git-wip-us.apache.org/repos/asf/ambari/blob/0d33d14d/ambari-web/app/controllers/wizard/step5_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/wizard/step5_controller.js b/ambari-web/app/controllers/wizard/step5_controller.js index 48a3628..91264b1 100644 --- a/ambari-web/app/controllers/wizard/step5_controller.js +++ b/ambari-web/app/controllers/wizard/step5_controller.js @@ -60,7 +60,9 @@ App.WizardStep5Controller = Em.Controller.extend({ }.property('[email protected]'), hosts:[], - isLazyLoading: false, + + componentToRebalance: null, + rebalanceComponentHostsCounter: 0, servicesMasters:[], selectedServicesMasters:[], @@ -108,7 +110,6 @@ App.WizardStep5Controller = Em.Controller.extend({ component.set('showRemoveControl', false); } } - this.rebalanceComponentHosts(componentName); } }, @@ -177,7 +178,6 @@ App.WizardStep5Controller = Em.Controller.extend({ zooKeeperHost.display_name = _componentInfo.display_name; zooKeeperHost.component_name = _componentInfo.component_name; zooKeeperHost.selectedHost = item.hostName; - zooKeeperHost.availableHosts = []; zooKeeperHost.serviceId = services[index]; zooKeeperHost.isInstalled = item.isInstalled; zooKeeperHost.isHiveCoHost = false; @@ -192,7 +192,6 @@ App.WizardStep5Controller = Em.Controller.extend({ zooKeeperHost.display_name = _componentInfo.display_name; zooKeeperHost.component_name = _componentInfo.component_name; zooKeeperHost.selectedHost = _host; - zooKeeperHost.availableHosts = []; zooKeeperHost.serviceId = services[index]; zooKeeperHost.isInstalled = false; zooKeeperHost.isHiveCoHost = false; @@ -208,7 +207,6 @@ App.WizardStep5Controller = Em.Controller.extend({ componentObj.selectedHost = savedComponent ? savedComponent.hostName : this.selectHost(_componentInfo.component_name); // call the method that plays selectNode algorithm or fetches from server componentObj.isInstalled = savedComponent ? savedComponent.isInstalled : false; componentObj.serviceId = services[index]; - componentObj.availableHosts = []; componentObj.isHiveCoHost = ['HIVE_METASTORE', 'WEBHCAT_SERVER'].contains(_componentInfo.component_name) && !this.get('isReassignWizard'); resultComponents.push(componentObj); } @@ -226,10 +224,6 @@ App.WizardStep5Controller = Em.Controller.extend({ var self = this; var services = this.get('content.services') .filterProperty('isInstalled', true).mapProperty('serviceName'); //list of shown services - var hosts = this.get('hosts'); - //The lazy loading for select elements supported only by Firefox and Chrome - var isBrowserSupported = $.browser.mozilla || ($.browser.safari && navigator.userAgent.indexOf('Chrome') !== -1); - var isLazyLoading = isBrowserSupported && hosts.length > 100; var showRemoveControlZk = !services.contains('ZOOKEEPER') && masterComponents.filterProperty('display_name', 'ZooKeeper').length > 1; var showRemoveControlHb = !services.contains('HBASE') && masterComponents.filterProperty('component_name', 'HBASE_MASTER').length > 1; var zid = 1; @@ -237,8 +231,6 @@ App.WizardStep5Controller = Em.Controller.extend({ var nid = 1; var result = []; - this.set('isLazyLoading', isLazyLoading); - masterComponents.forEach(function (item) { if (item.component_name == 'SECONDARY_NAMENODE') { @@ -261,16 +253,6 @@ App.WizardStep5Controller = Em.Controller.extend({ } else if (item.component_name === "NAMENODE") { componentObj.set('zId', nid++); } - if(isLazyLoading){ - //select need at least 30 hosts to have scrollbar - var initialHosts = hosts.slice(0, 30); - if(!initialHosts.someProperty('host_name', item.selectedHost)){ - initialHosts.push(hosts.findProperty('host_name', item.selectedHost)); - } - componentObj.set("availableHosts", initialHosts); - } else { - componentObj.set("availableHosts", hosts); - } result.push(componentObj); }, this); @@ -466,42 +448,32 @@ App.WizardStep5Controller = Em.Controller.extend({ } }, - masterHostMapping:function () { - var mapping = [], mappingObject, self = this, mappedHosts, hostObj, hostInfo; + masterHostMapping: function () { + var mapping = [], mappingObject, mappedHosts, hostObj; //get the unique assigned hosts and find the master services assigned to them mappedHosts = this.get("selectedServicesMasters").mapProperty("selectedHost").uniq(); mappedHosts.forEach(function (item) { - hostObj = self.get("hosts").findProperty("host_name", item); + hostObj = this.get("hosts").findProperty("host_name", item); mappingObject = Ember.Object.create({ - host_name:item, - hostInfo:hostObj.host_info, - masterServices:self.get("selectedServicesMasters").filterProperty("selectedHost", item) + host_name: item, + hostInfo: hostObj.host_info, + masterServices: this.get("selectedServicesMasters").filterProperty("selectedHost", item) }); mapping.pushObject(mappingObject); }, this); - mapping.sort(this.sortHostsByName); + mapping.sortBy('host_name'); return mapping; - }.property("[email protected]"), remainingHosts:function () { return (this.get("hosts.length") - this.get("masterHostMapping.length")); }.property("[email protected]"), - //methods - getAvailableHosts:function (componentName) { - var selectedHosts = this.get("selectedServicesMasters").filterProperty("component_name", componentName).mapProperty("selectedHost").uniq(); - - return this.get('hosts').filter(function(item){ - return !selectedHosts.contains(item.get("host_name")); - }); - - }, /** * On change callback for selects @@ -513,11 +485,9 @@ App.WizardStep5Controller = Em.Controller.extend({ if (selectedHost && componentName) { if (zId) { this.get('selectedServicesMasters').filterProperty('component_name', componentName).findProperty("zId", zId).set("selectedHost", selectedHost); - this.rebalanceComponentHosts(componentName); } else { this.get('selectedServicesMasters').findProperty("component_name", componentName).set("selectedHost", selectedHost); } - } }, @@ -566,7 +536,6 @@ App.WizardStep5Controller = Em.Controller.extend({ newMaster.set("display_name", lastMaster.get("display_name")); newMaster.set("component_name", lastMaster.get("component_name")); newMaster.set("selectedHost", lastMaster.get("selectedHost")); - newMaster.set("availableHosts", this.getAvailableHosts(componentName)); newMaster.set("isInstalled", false); if (currentMasters.get("length") === (maxNumMasters - 1)) { @@ -591,9 +560,8 @@ App.WizardStep5Controller = Em.Controller.extend({ this.get("selectedServicesMasters").insertAt(this.get("selectedServicesMasters").indexOf(lastMaster) + 1, newMaster); - if(componentName == 'ZOOKEEPER_SERVER' || componentName == 'HBASE_MASTER'){ - this.rebalanceComponentHosts(componentName); - } + this.set('componentToRebalance', componentName); + this.incrementProperty('rebalanceComponentHostsCounter'); return true; } @@ -625,9 +593,9 @@ App.WizardStep5Controller = Em.Controller.extend({ if (currentMasters.get("length") === 1) { currentMasters.set("lastObject.showRemoveControl", false); } - if(componentName == 'ZOOKEEPER_SERVER' || componentName == 'HBASE_MASTER'){ - this.rebalanceComponentHosts(componentName); - } + + this.set('componentToRebalance', componentName); + this.incrementProperty('rebalanceComponentHostsCounter'); return true; } @@ -636,47 +604,6 @@ App.WizardStep5Controller = Em.Controller.extend({ }, - rebalanceComponentHosts:function (componentName) { - //for a zookeeper and hbase update the available hosts for the other zookeepers and hbases - var currentComponents = this.get("selectedServicesMasters").filterProperty("component_name", componentName), - componentHosts = currentComponents.mapProperty("selectedHost"), - availableComponentHosts = [], - preparedAvailableHosts = null; - - //get all hosts available for zookeepers - this.get("hosts").forEach(function (item) { - if (!componentHosts.contains(item.get("host_name"))) { - availableComponentHosts.pushObject(item); - } - }, this); - - currentComponents.forEach(function (item) { - preparedAvailableHosts = availableComponentHosts.slice(0); - preparedAvailableHosts.pushObject(this.get("hosts").findProperty("host_name", item.get("selectedHost"))); - preparedAvailableHosts.sort(this.sortHostsByConfig, this); - item.set("availableHosts", preparedAvailableHosts); - }, this); - }, - - sortHostsByConfig:function (a, b) { - //currently handling only total memory on the host - if (a.memory < b.memory) { - return 1; - } - else { - return -1; - } - }, - - sortHostsByName:function (a, b) { - if (a.host_name > b.host_name) { - return 1; - } - else { - return -1; - } - }, - submit: function () { if (!this.get('isSubmitDisabled')){ App.router.send('next'); http://git-wip-us.apache.org/repos/asf/ambari/blob/0d33d14d/ambari-web/app/templates/wizard/step5.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/wizard/step5.hbs b/ambari-web/app/templates/wizard/step5.hbs index b66d268..49a4611 100644 --- a/ambari-web/app/templates/wizard/step5.hbs +++ b/ambari-web/app/templates/wizard/step5.hbs @@ -58,7 +58,6 @@ <label class="host-name">{{selectedHost}}<i class="icon-asterisks">✵</i></label> {{else}} {{view App.SelectHostView - contentBinding="availableHosts" optionValuePath="content.host_name" optionLabelPath="content.host_info" selectedHostBinding="selectedHost" http://git-wip-us.apache.org/repos/asf/ambari/blob/0d33d14d/ambari-web/app/utils/helper.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/helper.js b/ambari-web/app/utils/helper.js index 3b9abf7..553341b 100644 --- a/ambari-web/app/utils/helper.js +++ b/ambari-web/app/utils/helper.js @@ -79,6 +79,23 @@ Number.prototype.toDaysHoursMinutes = function () { return formatted; }; +/** + * sort array of objects by property; + * by default sorting has ascending order + * if @desc - true, then descending order + * @param property + * @param desc + */ +Array.prototype.sortBy = function(property, desc) { + this.sort(function (a, b) { + if (a[property] > b[property]) + return (desc) ? -1 : 1; + else + return (desc) ? 1 : -1; + }); + return this; +}; + Em.CoreObject.reopen({ t:function (key, attrs) { return Em.I18n.t(key, attrs) http://git-wip-us.apache.org/repos/asf/ambari/blob/0d33d14d/ambari-web/app/views/wizard/step5_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/wizard/step5_view.js b/ambari-web/app/views/wizard/step5_view.js index ee3d4f5..fb19b74 100644 --- a/ambari-web/app/views/wizard/step5_view.js +++ b/ambari-web/app/views/wizard/step5_view.js @@ -39,19 +39,58 @@ App.SelectHostView = Em.Select.extend({ componentName:null, attributeBindings:['disabled'], isLoaded: false, + isLazyLoading: false, - change:function () { + change: function () { this.get('controller').assignHostToMaster(this.get("componentName"), this.get("value"), this.get("zId")); + this.get('controller').set('componentToRebalance', this.get("componentName")); + this.get('controller').incrementProperty('rebalanceComponentHostsCounter'); }, + + /** + * recalculate available hosts + */ + rebalanceComponentHosts: function () { + if (this.get('componentName') === this.get('controller.componentToRebalance')) { + this.get('content').clear(); + this.set('isLoaded', false); + this.initContent(); + } + }.observes('controller.rebalanceComponentHostsCounter'), + + /** + * get available hosts + * Since ZOOKEEPER_SERVER or HBASE_MASTER component can be assigned to multiple hosts, + * shared hosts among the same component should be filtered out + * @return {*} + */ + getAvailableHosts: function () { + var hosts = this.get('controller.hosts').slice(); + var componentName = this.get('componentName'); + var occupiedHosts = this.get('controller.selectedServicesMasters') + .filterProperty('component_name', componentName) + .mapProperty('selectedHost').without(this.get('selectedHost')); + if (componentName == 'ZOOKEEPER_SERVER' || componentName == 'HBASE_MASTER') { + return hosts.filter(function (host) { + return !occupiedHosts.contains(host.get('host_name')); + }, this); + } + return hosts; + }, + /** + * on click start lazy loading + */ click: function () { var source = []; + var componentName = this.get('componentName'); + var availableHosts = this.getAvailableHosts(); var selectedHost = this.get('selectedHost'); - var content = this.get('content'); - if (!this.get('isLoaded') && this.get('controller.isLazyLoading')) { + + if (!this.get('isLoaded') && this.get('isLazyLoading')) { //filter out hosts, which already pushed in select - source = this.get('controller.hosts').filter(function(_host){ - return !content.someProperty('host_name', _host.host_name); - }, this); + source = availableHosts.filter(function(_host){ + return !this.get('content').someProperty('host_name', _host.host_name); + }, this).slice(); lazyloading.run({ destination: this.get('content'), source: source, @@ -63,8 +102,31 @@ App.SelectHostView = Em.Select.extend({ } }, - didInsertElement:function () { + didInsertElement: function () { + //The lazy loading for select elements supported only by Firefox and Chrome + var isBrowserSupported = $.browser.mozilla || ($.browser.safari && navigator.userAgent.indexOf('Chrome') !== -1); + var isLazyLoading = isBrowserSupported && this.get('controller.hosts').length > 100; + this.set('isLazyLoading', isLazyLoading); + this.initContent(); this.set("value", this.get("selectedHost")); + }, + /** + * extract hosts from controller, + * filter out available to selection and + * push them into Em.Select content + */ + initContent: function () { + var hosts = this.getAvailableHosts(); + if (this.get('isLazyLoading')) { + //select need at least 30 hosts to have scrollbar + var initialHosts = hosts.slice(0, 30); + if (!initialHosts.someProperty('host_name', this.get('selectedHost'))) { + initialHosts.unshift(hosts.findProperty('host_name', this.get('selectedHost'))); + } + this.set("content", initialHosts); + } else { + this.set("content", hosts); + } } });
