/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var App = require('app'); App.WizardStep5Controller = Em.Controller.extend({ name:"wizardStep5Controller", title: function () { if (this.get('content.controllerName') == 'reassignMasterController') { return Em.I18n.t('installer.step5.reassign.header'); } return Em.I18n.t('installer.step5.header'); }.property('content.controllerName'), isReassignWizard: function () { return this.get('content.controllerName') == 'reassignMasterController'; }.property(), isReassignHive: function () { return this.get('servicesMasters').objectAt(0) && this.get('servicesMasters').objectAt(0).component_name == 'HIVE_SERVER' && this.get('isReassignWizard'); }.property('isReassignWizard', 'servicesMasters'), hosts:[], servicesMasters:[], selectedServicesMasters:[], components:require('data/service_components'), clearStep:function () { this.set('hosts', []); this.set('selectedServicesMasters', []); this.set('servicesMasters', []); }, loadStep:function () { console.log("WizardStep5Controller: Loading step5: Assign Masters"); this.clearStep(); this.renderHostInfo(); this.renderComponents(this.loadComponents()); this.updateComponent('ZOOKEEPER_SERVER'); this.updateComponent('HBASE_MASTER'); if (!this.get("selectedServicesMasters").filterProperty('isInstalled', false).length) { console.log('no master components to add'); App.router.send('next'); } }, /** * Used to set showAddControl flag for ZOOKEEPER_SERVER and HBASE_SERVER */ updateComponent: function(componentName){ var component = this.last(componentName); var services = this.get('content.services').filterProperty('isInstalled', true).mapProperty('serviceName'); var currentService = componentName.split('_')[0]; var showControl = !services.contains(currentService); if (component) { if(showControl){ if (this.get("selectedServicesMasters").filterProperty("component_name", componentName).length < this.get("hosts.length") && !this.get('isReassignWizard')) { component.set('showAddControl', true); } else { component.set('showRemoveControl', false); } } this.rebalanceComponentHosts(componentName); } }, /** * Load active host list to hosts variable */ renderHostInfo:function () { var hostInfo = this.get('content.hosts'); var result = []; for (var index in hostInfo) { var _host = hostInfo[index]; if (_host.bootStatus === 'REGISTERED') { result.push(Ember.Object.create({ host_name:_host.name, cpu:_host.cpu, memory:_host.memory, disk_info:_host.disk_info, host_info: Em.I18n.t('installer.step5.hostInfo').fmt(_host.name, (_host.memory * 1024).bytesToSize(1, 'parseFloat'), _host.cpu) })); } } this.set("hosts", result); }, /** * Load services info to appropriate variable and return masterComponentHosts * @return Array */ loadComponents:function () { var services = this.get('content.services') .filterProperty('isSelected', true).mapProperty('serviceName'); //list of shown services var masterComponents = this.get('components').filterProperty('isMaster', true); //get full list from mock data var masterHosts = this.get('content.masterComponentHosts'); //saved to local storage info var resultComponents = []; var servicesLength = services.length; for (var index = 0; index < servicesLength; index++) { var componentInfo = masterComponents.filterProperty('service_name', services[index]); componentInfo.forEach(function (_componentInfo) { if (_componentInfo.component_name == 'ZOOKEEPER_SERVER' || _componentInfo.component_name == 'HBASE_MASTER') { var savedComponents = masterHosts.filterProperty('component', _componentInfo.component_name); if (savedComponents.length) { savedComponents.forEach(function (item) { var zooKeeperHost = {}; 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; resultComponents.push(zooKeeperHost); }) } else { var zooHosts = this.selectHost(_componentInfo.component_name); zooHosts.forEach(function (_host) { var zooKeeperHost = {}; 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; resultComponents.push(zooKeeperHost); }); } } else { var savedComponent = masterHosts.findProperty('component', _componentInfo.component_name); var componentObj = {}; componentObj.component_name = _componentInfo.component_name; componentObj.display_name = _componentInfo.display_name; 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 : App.HostComponent.find().someProperty('componentName', _componentInfo.component_name); componentObj.serviceId = services[index]; componentObj.availableHosts = []; componentObj.isHiveCoHost = ['HIVE_METASTORE', 'WEBHCAT_SERVER'].contains(_componentInfo.component_name) && !this.get('isReassignWizard'); resultComponents.push(componentObj); } }, this); } return resultComponents; }, /** * Put master components to selectedServicesMasters, which will be automatically rendered in template * @param masterComponents */ renderComponents:function (masterComponents) { var services = this.get('content.services') .filterProperty('isInstalled', true).mapProperty('serviceName'); //list of shown services 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; var hid = 1; var result = []; masterComponents.forEach(function (item) { var componentObj = Ember.Object.create(item); console.log("TRACE: render master component name is: " + item.component_name); if (item.display_name === "ZooKeeper") { componentObj.set('zId', zid++); componentObj.set("showRemoveControl", showRemoveControlZk); } else if(item.component_name === "HBASE_MASTER"){ componentObj.set('zId', hid++); componentObj.set("showRemoveControl", showRemoveControlHb); } componentObj.set("availableHosts", this.get("hosts")); result.push(componentObj); }, this); this.set("selectedServicesMasters", result); if (this.get('isReassignWizard')) { var components = result.filterProperty('component_name', this.get('content.reassign.component_name')); components.setEach('isInstalled', false); this.set('servicesMasters', components); } else { this.set('servicesMasters', result); } }, hasHiveServer: function () { return !!this.get('selectedServicesMasters').findProperty('component_name', 'HIVE_SERVER') && !this.get('isReassignWizard'); }.property('selectedServicesMasters'), updateHiveCoHosts: function () { var hiveServer = this.get('selectedServicesMasters').findProperty('component_name', 'HIVE_SERVER'); var hiveMetastore = this.get('selectedServicesMasters').findProperty('component_name', 'HIVE_METASTORE'); var webHCatServer = this.get('selectedServicesMasters').findProperty('component_name', 'WEBHCAT_SERVER'); if (hiveServer && hiveMetastore && webHCatServer) { if (!this.get('isReassignHive') && this.get('servicesMasters').objectAt(0) && !this.get('servicesMasters').objectAt(0).component_name == 'HIVE_METASTORE') { this.get('selectedServicesMasters').findProperty('component_name', 'HIVE_METASTORE').set('selectedHost', hiveServer.get('selectedHost')) } this.get('selectedServicesMasters').findProperty('component_name', 'WEBHCAT_SERVER').set('selectedHost', hiveServer.get('selectedHost')); } }.observes('selectedServicesMasters.@each.selectedHost'), getKerberosServer:function (noOfHosts) { var hosts = this.get('hosts'); if (noOfHosts === 1) { return hosts[0]; } else if (noOfHosts < 3) { return hosts[1]; } else if (noOfHosts <= 5) { return hosts[1]; } else if (noOfHosts <= 30) { return hosts[3]; } else { return hosts[5]; } }, getNameNode:function (noOfHosts) { var hosts = this.get('hosts'); return hosts[0]; }, getSNameNode:function (noOfHosts) { var hosts = this.get('hosts'); if (noOfHosts === 1) { return hosts[0]; } else { return hosts[1]; } }, getJobTracker:function (noOfHosts) { var hosts = this.get('hosts'); if (noOfHosts === 1) { return hosts[0]; } else if (noOfHosts < 3) { return hosts[1]; } else if (noOfHosts <= 5) { return hosts[1]; } else if (noOfHosts <= 30) { return hosts[1]; } else { return hosts[2]; } }, getHBaseMaster:function (noOfHosts) { var hosts = this.get('hosts'); if (noOfHosts === 1) { return hosts[0]; } else if (noOfHosts < 3) { return hosts[0]; } else if (noOfHosts <= 5) { return hosts[0]; } else if (noOfHosts <= 30) { return hosts[2]; } else { return hosts[3]; } }, getOozieServer:function (noOfHosts) { var hosts = this.get('hosts'); if (noOfHosts === 1) { return hosts[0]; } else if (noOfHosts < 3) { return hosts[1]; } else if (noOfHosts <= 5) { return hosts[1]; } else if (noOfHosts <= 30) { return hosts[2]; } else { return hosts[3]; } }, getHiveServer:function (noOfHosts) { var hosts = this.get('hosts'); if (noOfHosts === 1) { return hosts[0]; } else if (noOfHosts < 3) { return hosts[1]; } else if (noOfHosts <= 5) { return hosts[1]; } else if (noOfHosts <= 30) { return hosts[2]; } else { return hosts[4]; } }, getHueServer:function (noOfHosts) { var hosts = this.get('hosts'); var hostnames = []; var inc = 0; hosts.forEach(function (_hostname) { hostnames[inc] = _hostname.host_name; inc++; }); var hostExcAmbari = hostnames.without(location.hostname); if (noOfHosts > 1) { return hostExcAmbari[0]; } else { return hostnames[0]; } }, getHiveMetastore:function (noOfHosts) { return this.getHiveServer(noOfHosts); }, getWebHCatServer:function (noOfHosts) { return this.getHiveServer(noOfHosts); }, getZooKeeperServer:function (noOfHosts) { var hosts = this.get('hosts'); if (noOfHosts < 3) { return [hosts[0].host_name]; } else { return [hosts[0].host_name, hosts[1].host_name, hosts[2].host_name]; } }, getGangliaServer:function (noOfHosts) { var hosts = this.get('hosts'); var hostnames = []; var inc = 0; hosts.forEach(function (_hostname) { hostnames[inc] = _hostname.host_name; inc++; }); var hostExcAmbari = hostnames.without(location.hostname); if (noOfHosts > 1) { return hostExcAmbari[0]; } else { return hostnames[0]; } }, getNagiosServer:function (noOfHosts) { var hosts = this.get('hosts'); var hostnames = []; var inc = 0; hosts.forEach(function (_hostname) { hostnames[inc] = _hostname.host_name; inc++; }); var hostExcAmbari = hostnames.without(location.hostname); if (noOfHosts > 1) { return hostExcAmbari[0]; } else { return hostnames[0]; } }, /** * Return hostName of masterNode for specified service * @param componentName * @return {*} */ selectHost:function (componentName) { var noOfHosts = this.get('hosts').length; switch (componentName) { case 'KERBEROS_SERVER': return this.getKerberosServer(noOfHosts).host_name; case 'NAMENODE': return this.getNameNode(noOfHosts).host_name; case 'SECONDARY_NAMENODE': return this.getSNameNode(noOfHosts).host_name; case 'JOBTRACKER': return this.getJobTracker(noOfHosts).host_name; case 'HBASE_MASTER': return [this.getHBaseMaster(noOfHosts).host_name]; case 'OOZIE_SERVER': return this.getOozieServer(noOfHosts).host_name; case 'HIVE_SERVER': return this.getHiveServer(noOfHosts).host_name; case 'HIVE_METASTORE': return this.getHiveMetastore(noOfHosts).host_name; case 'WEBHCAT_SERVER': return this.getWebHCatServer(noOfHosts).host_name; case 'ZOOKEEPER_SERVER': return this.getZooKeeperServer(noOfHosts); case 'GANGLIA_SERVER': return this.getGangliaServer(noOfHosts); case 'NAGIOS_SERVER': return this.getNagiosServer(noOfHosts); case 'HUE_SERVER': return this.getHueServer(noOfHosts); } }, masterHostMapping:function () { var mapping = [], mappingObject, self = this, mappedHosts, hostObj, hostInfo; //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); console.log("Name of the host is: " + hostObj.host_name); mappingObject = Ember.Object.create({ host_name:item, hostInfo:hostObj.host_info, masterServices:self.get("selectedServicesMasters").filterProperty("selectedHost", item) }); mapping.pushObject(mappingObject); }, this); mapping.sort(this.sortHostsByName); return mapping; }.property("selectedServicesMasters.@each.selectedHost"), remainingHosts:function () { return (this.get("hosts.length") - this.get("masterHostMapping.length")); }.property("selectedServicesMasters.@each.selectedHost"), //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 * @param componentName * @param selectedHost * @param zId */ assignHostToMaster:function (componentName, selectedHost, zId) { 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); } } }, /** * Returns last component of selected type * @param componentName * @return {*} */ last: function(componentName){ return this.get("selectedServicesMasters").filterProperty("component_name", componentName).get("lastObject"); }, /** * Add new component to ZooKeeper Server and Hbase master * @param componentName * @return {Boolean} */ addComponent:function (componentName) { /* *Logic: If ZooKeeper service is selected then there can be * minimum 1 ZooKeeper master in total, and * maximum 1 ZooKeeper on every host */ var maxNumZooKeepers = this.get("hosts.length"), currentZooKeepers = this.get("selectedServicesMasters").filterProperty("component_name", componentName), newZookeeper = null, zookeeperHosts = null, suggestedHost = null, i = 0, lastZoo = null; if (!currentZooKeepers.length) { console.log('ALERT: Zookeeper service was not selected'); return false; } if (currentZooKeepers.get("length") < maxNumZooKeepers) { currentZooKeepers.set("lastObject.showAddControl", false); currentZooKeepers.set("lastObject.showRemoveControl", true); //create a new zookeeper based on an existing one newZookeeper = Ember.Object.create({}); lastZoo = currentZooKeepers.get("lastObject"); newZookeeper.set("display_name", lastZoo.get("display_name")); newZookeeper.set("component_name", lastZoo.get("component_name")); newZookeeper.set("selectedHost", lastZoo.get("selectedHost")); newZookeeper.set("availableHosts", this.getAvailableHosts(componentName)); if (currentZooKeepers.get("length") === (maxNumZooKeepers - 1)) { newZookeeper.set("showAddControl", false); } else { newZookeeper.set("showAddControl", true); } newZookeeper.set("showRemoveControl", true); //get recommended host for the new Zookeeper server zookeeperHosts = currentZooKeepers.mapProperty("selectedHost").uniq(); for (i = 0; i < this.get("hosts.length"); i++) { if (!(zookeeperHosts.contains(this.get("hosts")[i].get("host_name")))) { suggestedHost = this.get("hosts")[i].get("host_name"); break; } } newZookeeper.set("selectedHost", suggestedHost); newZookeeper.set("zId", (currentZooKeepers.get("lastObject.zId") + 1)); this.get("selectedServicesMasters").insertAt(this.get("selectedServicesMasters").indexOf(lastZoo) + 1, newZookeeper); if(componentName == 'ZOOKEEPER_SERVER' || componentName == 'HBASE_MASTER'){ this.rebalanceComponentHosts(componentName); } return true; } return false;//if no more zookeepers can be added }, /** * Remove component from ZooKeeper server or Hbase Master * @param componentName * @param zId * @return {Boolean} */ removeComponent:function (componentName, zId) { var currentZooKeepers = this.get("selectedServicesMasters").filterProperty("component_name", componentName) //work only if the Zookeeper service is selected in previous step if (!currentZooKeepers.length) { return false; } if (currentZooKeepers.get("length") > 1) { this.get("selectedServicesMasters").removeAt(this.get("selectedServicesMasters").indexOf(currentZooKeepers.findProperty("zId", zId))); currentZooKeepers = this.get("selectedServicesMasters").filterProperty("component_name", componentName); if (currentZooKeepers.get("length") < this.get("hosts.length")) { currentZooKeepers.set("lastObject.showAddControl", true); } if (currentZooKeepers.get("length") === 1) { currentZooKeepers.set("lastObject.showRemoveControl", false); } if(componentName == 'ZOOKEEPER_SERVER' || componentName == 'HBASE_MASTER'){ this.rebalanceComponentHosts(componentName); } return true; } return false; }, 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; } } });