/** * 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.WizardStep8Controller = Em.Controller.extend({ name: 'wizardStep8Controller', rawContent: require('data/review_configs'), totalHosts: [], clusterInfo: [], services: [], configs: [], globals: [], configMapping: require('data/config_mapping'), slaveComponentConfig: null, isSubmitDisabled: false, selectedServices: function () { return this.get('content.services').filterProperty('isSelected', true).filterProperty('isInstalled', false); }.property('content.services').cacheable(), clearStep: function () { this.get('services').clear(); this.get('configs').clear(); this.get('globals').clear(); this.get('clusterInfo').clear(); }, loadStep: function () { console.log("TRACE: Loading step8: Review Page"); this.clearStep(); this.loadGlobals(); this.loadConfigs(); this.setCustomConfigs(); this.loadSlaveConfiguration(); this.loadClusterInfo(); this.loadServices(); }, loadGlobals: function () { var globals = this.get('content.serviceConfigProperties').filterProperty('id', 'puppet var'); if (globals.someProperty('name', 'hive_database')) { //TODO: Hive host depends on the type of db selected. Change puppet variable name if postgres is not the default db var hiveDb = globals.findProperty('name', 'hive_database'); if (hiveDb.value === 'New PostgreSQL Database') { globals.findProperty('name', 'hive_ambari_host').name = 'hive_mysql_host'; globals = globals.without(globals.findProperty('name', 'hive_existing_host')); globals = globals.without(globals.findProperty('name', 'hive_existing_database')); } else { globals.findProperty('name', 'hive_existing_host').name = 'hive_mysql_host'; globals = globals.without(globals.findProperty('name', 'hive_ambari_host')); globals = globals.without(globals.findProperty('name', 'hive_ambari_database')); } } this.set('globals', globals); }, loadConfigs: function () { var storedConfigs = this.get('content.serviceConfigProperties').filterProperty('id', 'site property').filterProperty('value'); var uiConfigs = this.loadUiSideConfigs(); this.set('configs', storedConfigs.concat(uiConfigs)); }, loadUiSideConfigs: function () { var uiConfig = []; var configs = this.get('configMapping').filterProperty('foreignKey', null); configs.forEach(function (_config) { var value = this.getGlobConfigValue(_config.templateName, _config.value); uiConfig.pushObject({ "id": "site property", "name": _config.name, "value": value, "filename": _config.filename }); }, this); var dependentConfig = this.get('configMapping').filterProperty('foreignKey'); dependentConfig.forEach(function (_config) { this.setConfigValue(uiConfig, _config); uiConfig.pushObject({ "id": "site property", "name": _config.name, "value": _config.value, "filename": _config.filename }); }, this); return uiConfig; }, getRegisteredHosts: function () { var allHosts = this.get('content.hostsInfo'); var hosts = []; for (var hostName in allHosts) { if (allHosts[hostName].bootStatus == 'REGISTERED') { allHosts[hostName].hostName = allHosts[hostName].name; hosts.pushObject(allHosts[hostName]); } } return hosts; }, /** * Set all site property that are derived from other puppet-variable */ getGlobConfigValue: function (templateName, expression) { var express = expression.match(/<(.*?)>/g); var value = expression; if (express == null) { return expression; } express.forEach(function (_express) { //console.log("The value of template is: " + _express); var index = parseInt(_express.match(/\[([\d]*)(?=\])/)[1]); if (this.get('globals').someProperty('name', templateName[index])) { //console.log("The name of the variable is: " + this.get('content.serviceConfigProperties').findProperty('name', templateName[index]).name); var globValue = this.get('globals').findProperty('name', templateName[index]).value; value = value.replace(_express, globValue); } else { /* console.log("ERROR: The variable name is: " + templateName[index]); console.log("ERROR: mapped config from configMapping file has no corresponding variable in " + "content.serviceConfigProperties. Two possible reasons for the error could be: 1) The service is not selected. " + "and/OR 2) The service_config metadata file has no corresponding global var for the site property variable"); */ value = null; } }, this); return value; }, /** * Set all site property that are derived from other site-properties */ setConfigValue: function (uiConfig, config) { var fkValue = config.value.match(/<(foreignKey.*?)>/g); if (fkValue) { fkValue.forEach(function (_fkValue) { var index = parseInt(_fkValue.match(/\[([\d]*)(?=\])/)[1]); if (uiConfig.someProperty('name', config.foreignKey[index])) { var globalValue = uiConfig.findProperty('name', config.foreignKey[index]).value; config.value = config.value.replace(_fkValue, globalValue); } else if (this.get('content.serviceConfigProperties').someProperty('name', config.foreignKey[index])) { var globalValue; if (this.get('content.serviceConfigProperties').findProperty('name', config.foreignKey[index]).value === '') { globalValue = this.get('content.serviceConfigProperties').findProperty('name', config.foreignKey[index]).defaultValue; } else { globalValue = this.get('content.serviceConfigProperties').findProperty('name', config.foreignKey[index]).value; } config.value = config.value.replace(_fkValue, globalValue); } }, this); } if (fkValue = config.name.match(/<(foreignKey.*?)>/g)) { fkValue.forEach(function (_fkValue) { var index = parseInt(_fkValue.match(/\[([\d]*)(?=\])/)[1]); if (uiConfig.someProperty('name', config.foreignKey[index])) { var globalValue = uiConfig.findProperty('name', config.foreignKey[index]).value; config.name = config.name.replace(_fkValue, globalValue); } else if (this.get('content.serviceConfigProperties').someProperty('name', config.foreignKey[index])) { var globalValue; if (this.get('content.serviceConfigProperties').findProperty('name', config.foreignKey[index]).value === '') { globalValue = this.get('content.serviceConfigProperties').findProperty('name', config.foreignKey[index]).defaultValue; } else { globalValue = this.get('content.serviceConfigProperties').findProperty('name', config.foreignKey[index]).value; } config.name = config.name.replace(_fkValue, globalValue); } }, this); } //For properties in the configMapping file having foreignKey and templateName properties. var templateValue = config.value.match(/<(templateName.*?)>/g); if (templateValue) { templateValue.forEach(function (_value) { var index = parseInt(_value.match(/\[([\d]*)(?=\])/)[1]); if (this.get('globals').someProperty('name', config.templateName[index])) { var globalValue = this.get('globals').findProperty('name', config.templateName[index]).value; config.value = config.value.replace(_value, globalValue); } }, this); } }, /** * override site properties with the entered key-value pair in *-site.xml */ setCustomConfigs: function () { var site = this.get('content.serviceConfigProperties').filterProperty('id', 'conf-site'); site.forEach(function (_site) { var keyValue = _site.value.split(/\n+/); if (keyValue) { keyValue.forEach(function (_keyValue) { console.log("The value of the keyValue is: " + _keyValue.trim()); _keyValue = _keyValue.trim(); var key = _keyValue.match(/(.+)=/); var value = _keyValue.match(/=(.*)/); if (key) { this.setSiteProperty(key[1], value[1], _site.filename); } }, this); } }, this); }, /** * Set property of the site variable */ setSiteProperty: function (key, value, filename) { if (this.get('configs').someProperty('name', key)) { this.get('configs').findProperty('name', key).value = value; } else { this.get('configs').pushObject({ "id": "site property", "name": key, "value": value, "filename": filename }); } }, loadSlaveConfiguration: function () { var slaveComponentConfig = this.convertSlaveConfig(this.get('content.slaveGroupProperties')); this.set("slaveComponentConfig", slaveComponentConfig); }, convertSlaveConfig: function (slaveContent) { var dest = { "version": "1.0", "components": [ ], "slaveHostComponents": [] }; slaveContent.forEach(function (_slaveContent) { var newComponent = {}; newComponent.componentName = _slaveContent.componentName; newComponent.serviceName = this.getServiceInfo(newComponent.componentName).name; newComponent.groups = []; var index = 2; _slaveContent.groups.forEach(function (_group) { var newGroup = {}; newGroup.groupName = _group.name; newGroup.configVersion = {config: {'global': 'version1', 'core-site': 'version1'}}; // TODO : every time a new version should be generated if (this.getServiceInfo(_slaveContent.componentName)) { newGroup.configVersion.config[this.getServiceInfo(_slaveContent.componentName).domain] = 'version' + index; newGroup.configVersion.config[this.getServiceInfo(_slaveContent.componentName).siteName] = 'version' + index; } newGroup.siteVersion = 'version' + index; newGroup.hostNames = _slaveContent.hosts.filterProperty("group", newGroup.groupName).mapProperty('hostName'); newGroup.properties = _group.properties; if (!Ember.empty(newGroup.hostNames)) { newComponent.groups.push(newGroup); } index++; }, this); dest.components.push(newComponent); }, this); var hostsInfo = this.get('content.hostsInfo'); for (var index in hostsInfo) { var hostIndex = 2; var slaveHost = {name: null, configVersion: null, slaveComponents: []}; dest.components.forEach(function (_component) { _component.groups.forEach(function (_group) { if (_group.hostNames.contains(hostsInfo[index].name)) { var slaveComponent = {}; slaveHost.name = hostsInfo[index].name; slaveComponent.componentName = _component.componentName; slaveComponent.groupName = _group.groupName; slaveComponent.properties = _group.properties; slaveHost.slaveComponents.pushObject(slaveComponent); } }, this); }, this); hostIndex++; if (!Ember.none(slaveHost.name)) { dest.slaveHostComponents.pushObject(slaveHost); } } return dest; }, getServiceInfo: function (componentName) { var serviceConfig; switch (componentName) { case 'DATANODE': serviceConfig = { name: 'HDFS', siteName: 'hdfs-site', domain: 'datanode-global' }; break; case 'TASKTRACKER': serviceConfig = { name: 'MAPREDUCE', siteName: 'mapred-site', domain: 'tasktracker-global' }; break; case 'HBASE_REGIONSERVER': serviceConfig = { name: 'HBASE', siteName: 'hbase-site', domain: 'regionserver-global' }; break; default: serviceConfig = null; } return serviceConfig; }, /** * Load all info about cluster to clusterInfo variable */ loadClusterInfo: function () { // cluster name var cluster = this.rawContent.findProperty('config_name', 'cluster'); cluster.config_value = this.get('content.cluster.name'); console.log("STEP8: the value of content cluster name: " + this.get('content.cluster.name')); this.get('clusterInfo').pushObject(Ember.Object.create(cluster)); //hosts var masterHosts = this.get('content.masterComponentHosts').mapProperty('hostName').uniq(); var slaveHosts = this.get('content.slaveComponentHosts'); var hostObj = []; slaveHosts.forEach(function (_hosts) { hostObj = hostObj.concat(_hosts.hosts); }, this); slaveHosts = hostObj.mapProperty('hostName').uniq(); var totalHosts = masterHosts.concat(slaveHosts).uniq(); this.set('totalHosts', totalHosts); var totalHostsObj = this.rawContent.findProperty('config_name', 'hosts'); totalHostsObj.config_value = totalHosts.length; this.get('clusterInfo').pushObject(Ember.Object.create(totalHostsObj)); //repo var repoOption = this.get('content.hosts.localRepo'); var repoObj = this.rawContent.findProperty('config_name', 'Repo'); if (repoOption) { repoObj.config_value = 'Yes'; } else { repoObj.config_value = 'No'; } this.get('clusterInfo').pushObject(Ember.Object.create(repoObj)); }, /** * Load all info about services to services variable */ loadServices: function () { var selectedServices = this.get('selectedServices'); this.set('services', selectedServices.mapProperty('serviceName')); selectedServices.forEach(function (_service) { console.log('INFO: step8: Name of the service from getService function: ' + _service.serviceName); var reviewService = this.rawContent.findProperty('config_name', 'services'); var serviceObj = reviewService.config_value.findProperty('service_name', _service.serviceName); if (serviceObj) { switch (serviceObj.service_name) { case 'HDFS': this.loadHDFS(serviceObj); break; case 'MAPREDUCE': this.loadMapReduce(serviceObj); break; case 'HIVE': this.loadHive(serviceObj); break; case 'HBASE': this.loadHbase(serviceObj); break; case 'ZOOKEEPER': this.loadZk(serviceObj); break; case 'OOZIE': this.loadOozie(serviceObj); break; case 'NAGIOS': this.loadNagios(serviceObj); break; case 'GANGLIA': this.loadGanglia(serviceObj); break; case 'HCATALOG': break; default: } } }, this); }, /** * load all info about HDFS service * @param hdfsObj */ loadHDFS: function (hdfsObj) { hdfsObj.get('service_components').forEach(function (_component) { switch (_component.get('display_name')) { case 'NameNode': this.loadNnValue(_component); break; case 'SecondaryNameNode': this.loadSnnValue(_component); break; case 'DataNodes': this.loadDnValue(_component); break; default: } }, this); //var this.get('services').pushObject(hdfsObj); }, loadNnValue: function (nnComponent) { var nnHostName = this.get('content.masterComponentHosts').findProperty('display_name', nnComponent.display_name); nnComponent.set('component_value', nnHostName.hostName); }, loadSnnValue: function (snnComponent) { var snnHostName = this.get('content.masterComponentHosts').findProperty('display_name', 'SNameNode'); snnComponent.set('component_value', snnHostName.hostName); }, loadDnValue: function (dnComponent) { var dnHosts = this.get('content.slaveComponentHosts').findProperty('displayName', 'DataNode'); var totalDnHosts = dnHosts.hosts.length; var totalGroups = this.get('slaveComponentConfig.components').findProperty('componentName', 'DATANODE').groups.length; var groupLabel; if (totalGroups == 1) { groupLabel = 'group'; } else { groupLabel = 'groups'; } dnComponent.set('component_value', totalDnHosts + ' hosts ' + '(' + totalGroups + ' ' + groupLabel + ')'); }, /** * Load all info about mapReduce service * @param mrObj */ loadMapReduce: function (mrObj) { mrObj.get('service_components').forEach(function (_component) { switch (_component.get('display_name')) { case 'JobTracker': this.loadJtValue(_component); break; case 'TaskTrackers': this.loadTtValue(_component); break; default: } }, this); this.get('services').pushObject(mrObj); }, loadJtValue: function (jtComponent) { var jtHostName = this.get('content.masterComponentHosts').findProperty('display_name', jtComponent.display_name); jtComponent.set('component_value', jtHostName.hostName); }, loadTtValue: function (ttComponent) { var ttHosts = this.get('content.slaveComponentHosts').findProperty('displayName', 'TaskTracker'); var totalTtHosts = ttHosts.hosts.length; var totalGroups = this.get('slaveComponentConfig.components').findProperty('componentName', 'TASKTRACKER').groups.length; var groupLabel; if (totalGroups == 1) { groupLabel = 'group'; } else { groupLabel = 'groups'; } ttComponent.set('component_value', totalTtHosts + ' hosts ' + '(' + totalGroups + ' ' + groupLabel + ')'); }, /** * Load all info about Hive service * @param hiveObj */ loadHive: function (hiveObj) { hiveObj.get('service_components').forEach(function (_component) { switch (_component.get('display_name')) { case 'Hive Metastore Server': this.loadHiveMetaStoreValue(_component); break; case 'Database': this.loadHiveDbValue(_component); break; default: } }, this); this.get('services').pushObject(hiveObj); }, loadHiveMetaStoreValue: function (metaStoreComponent) { var hiveHostName = this.get('content.masterComponentHosts').findProperty('display_name', 'Hive Metastore'); metaStoreComponent.set('component_value', hiveHostName.hostName); }, loadHiveDbValue: function (dbComponent) { var hiveDb = App.db.getServiceConfigProperties().findProperty('name', 'hive_database'); if (hiveDb.value === 'New PostgreSQL Database') { dbComponent.set('component_value', 'PostgreSQL (New Database)'); } else { var db = App.db.getServiceConfigProperties().findProperty('name', 'hive_existing_database'); dbComponent.set('component_value', db.value + ' (' + hiveDb.value + ')'); } }, /** * Load all info about Hbase * @param hbaseObj */ loadHbase: function (hbaseObj) { hbaseObj.service_components.forEach(function (_component) { switch (_component.display_name) { case 'Master': this.loadMasterValue(_component); break; case 'Region Servers': this.loadRegionServerValue(_component); break; default: } }, this); this.get('services').pushObject(hbaseObj); }, loadMasterValue: function (hbaseMaster) { var hbaseHostName = this.get('content.masterComponentHosts').findProperty('display_name', 'HBase Master'); hbaseMaster.set('component_value', hbaseHostName.hostName); }, loadRegionServerValue: function (rsComponent) { var rsHosts = this.get('content.slaveComponentHosts').findProperty('displayName', 'RegionServer'); var totalRsHosts = rsHosts.hosts.length; var totalGroups = this.get('slaveComponentConfig.components').findProperty('componentName', 'HBASE_REGIONSERVER').groups.length; var groupLabel; if (totalGroups == 1) { groupLabel = 'group'; } else { groupLabel = 'groups'; } rsComponent.set('component_value', totalRsHosts + ' hosts ' + '(' + totalGroups + ' ' + groupLabel + ')'); }, /** * Load all info about ZooKeeper service * @param zkObj */ loadZk: function (zkObj) { zkObj.get('service_components').forEach(function (_component) { switch (_component.get('display_name')) { case 'Servers': this.loadZkServerValue(_component); break; default: } }, this); this.get('services').pushObject(zkObj); }, loadZkServerValue: function (serverComponent) { var zkHostNames = this.get('content.masterComponentHosts').filterProperty('display_name', 'ZooKeeper').length; var hostSuffix; if (zkHostNames === 1) { hostSuffix = 'host'; } else { hostSuffix = 'hosts'; } serverComponent.set('component_value', zkHostNames + ' ' + hostSuffix); }, /** * Load all info about Oozie services * @param oozieObj */ loadOozie: function (oozieObj) { oozieObj.get('service_components').forEach(function (_component) { switch (_component.get('display_name')) { case 'Server': this.loadOozieServerValue(_component); break; case 'Database': // TODO: uncomment when ready to integrate with Oozie Database other than Derby // this.loadOozieDbValue(_component); break; default: } }, this); this.get('services').pushObject(oozieObj); }, loadOozieServerValue: function (oozieServer) { var oozieServerName = this.get('content.masterComponentHosts').findProperty('display_name', 'Oozie Server'); oozieServer.set('component_value', oozieServerName.hostName); }, loadOozieDbValue: function (dbComponent) { var oozieDb = App.db.getServiceConfigProperties().findProperty('name', 'oozie_database'); if (oozieDb.value === 'New PostgreSQL Database') { dbComponent.set('component_value', 'PostgreSQL (New Database)'); } else { var db = App.db.getServiceConfigProperties().findProperty('name', 'oozie_existing_database'); dbComponent.set('component_value', db.value + ' (' + oozieDb.value + ')'); } }, /** * Load all info about Nagios service * @param nagiosObj */ loadNagios: function (nagiosObj) { nagiosObj.service_components.forEach(function (_component) { switch (_component.display_name) { case 'Server': this.loadNagiosServerValue(_component); break; case 'Administrator': this.loadNagiosAdminValue(_component); break; default: } }, this); this.get('services').pushObject(nagiosObj); }, loadNagiosServerValue: function (nagiosServer) { var nagiosServerName = this.get('content.masterComponentHosts').findProperty('display_name', 'Nagios Server'); nagiosServer.set('component_value', nagiosServerName.hostName); }, loadNagiosAdminValue: function (nagiosAdmin) { var config = this.get('content.serviceConfigProperties'); var adminLoginName = config.findProperty('name', 'nagios_web_login'); var adminEmail = config.findProperty('name', 'nagios_contact'); nagiosAdmin.set('component_value', adminLoginName.value + ' / (' + adminEmail.value + ')'); }, /** * Load all info about ganglia * @param gangliaObj */ loadGanglia: function (gangliaObj) { gangliaObj.get('service_components').forEach(function (_component) { switch (_component.get('display_name')) { case 'Server': this.loadGangliaServerValue(_component); break; default: } }, this); this.get('services').pushObject(gangliaObj); }, loadGangliaServerValue: function (gangliaServer) { var gangliaServerName = this.get('content.masterComponentHosts').findProperty('display_name', 'Ganglia Collector'); gangliaServer.set('component_value', gangliaServerName.hostName); }, /** * Onclick handler for next button */ submit: function () { if (this.get('isSubmitDisabled')) { return; } this.set('isSubmitDisabled', true); if (App.testMode || !this.get('content.cluster.requestId')) { this.createCluster(); this.createSelectedServices(); this.setAmbariUIDb(); this.createConfigurations(); this.applyCreatedConfToServices(); this.createComponents(); this.registerHostsToCluster(); this.createAllHostComponents(); this.applyCreatedConfToSlaveGroups(); this.ajaxQueueFinished = function(){ console.log('everything is loaded') App.router.send('next'); }; this.doNextAjaxCall(); } else { App.router.send('next'); } }, setAmbariUIDb: function () { var dbContent = this.get('content.slaveGroupProperties'); var slaveComponentConfig = this.get("slaveComponentConfig"); this.persistKeyValues(slaveComponentConfig.version, dbContent); this.persistKeyValues('current_version',slaveComponentConfig.version); }, persistKeyValues: function (key, value) { var str = "{ '" + key + "' : '" + JSON.stringify(value) + "'}"; var obj = eval("(" + str + ")"); this.ajax({ type: "POST", url: App.apiPrefix + '/persist', data: JSON.stringify(obj), beforeSend: function () { console.log('BeforeSend: persistKeyValues', obj); } }); }, clusterName: function () { return this.get('content.cluster.name'); }.property('content.cluster.name'), /** * The following create* functions are called upon submitting Step 8. */ createCluster: function () { if (this.get('content.isWizard')) { return false; } var clusterName = this.get('clusterName'); var url = App.apiPrefix + '/clusters/' + clusterName; var stackVersion = (App.db.getSoftRepo().repoType == 'local') ? App.defaultLocalStackVersion : App.defaultStackVersion; this.ajax({ type: 'POST', url: url, data: JSON.stringify({ "Clusters": {"version": stackVersion }}), beforeSend: function () { console.log("BeforeSend: createCluster for " + clusterName); } }); }, createSelectedServices: function () { var url = App.apiPrefix + '/clusters/' + this.get('clusterName') + '/services'; var data = this.createServiceData(); var httpMethod = 'POST'; this.ajax({ type: httpMethod, url: url, data: JSON.stringify(data), beforeSend: function () { console.log('BeforeSend: createSelectedServices ', data); } }); }, createServiceData: function () { var services = this.get('selectedServices').mapProperty('serviceName'); var data = []; services.forEach(function (_service) { data.pushObject({"ServiceInfo": { "service_name": _service }}); }, this); return data; }, createComponents: function () { var serviceComponents = require('data/service_components'); var services = this.get('selectedServices').mapProperty('serviceName'); services.forEach(function (_service) { var components = serviceComponents.filterProperty('service_name', _service); var componentsData = components.map(function (_component) { return { "ServiceComponentInfo": { "component_name": _component.component_name } }; }); // Service must be specified in terms of a query for creating multiple components at the same time. // See AMBARI-1018. var url = App.apiPrefix + '/clusters/' + this.get('clusterName') + '/services?ServiceInfo/service_name=' + _service; var data = { "components": componentsData } this.ajax({ type: 'POST', url: url, data: JSON.stringify(data), beforeSend: function () { console.log('BeforeSend: createComponents for ' + _service, componentsData); } }); }, this); }, registerHostsToCluster: function () { var url = App.apiPrefix + '/clusters/' + this.get('clusterName') + '/hosts'; var data = this.createRegisterHostData(); if (data.length == 0) { return; } this.ajax({ type: 'POST', url: url, data: JSON.stringify(data), beforeSend: function () { console.log('BeforeSend: registerHostsToCluster', data); } }); }, createRegisterHostData: function () { return this.getRegisteredHosts().map(function (host) { if (!host.isInstalled) { return {"Hosts": { "host_name": host.hostName}}; } }); }, // TODO: review the code for add hosts / add services scenarios... createAllHostComponents: function () { var masterHosts = this.get('content.masterComponentHosts'); var slaveHosts = this.get('content.slaveComponentHosts'); var clients = this.get('content.clients'); var clientHosts = slaveHosts.filterProperty('componentName', "CLIENT").objectAt(0).hosts; // note: masterHosts has 'component' vs slaveHosts has 'componentName' var masterComponents = masterHosts.mapProperty('component').uniq(); masterComponents.forEach(function (component) { var hostNames = masterHosts.filterProperty('component', component).filterProperty('isInstalled', false).mapProperty('hostName'); this.registerHostsToComponent(hostNames, component); }, this); slaveHosts.forEach(function (_slave) { if (_slave.componentName !== 'CLIENT') { var hostNames = _slave.hosts.filterProperty('isInstalled', false).mapProperty('hostName'); this.registerHostsToComponent(hostNames, _slave.componentName); } else { this.get('content.clients').forEach(function (_client) { if (!_client.isInstalled) { var hostNames = clientHosts.mapProperty('hostName').splice(0); switch (_client.component_name) { case 'HDFS_CLIENT': // install HDFS_CLIENT on HBASE_MASTER and HBASE_REGIONSERVER hosts masterHosts.filterProperty('component', 'HBASE_MASTER').filterProperty('isInstalled', false).forEach(function (_masterHost) { hostNames.pushObject(_masterHost.hostName); }, this); masterHosts.filterProperty('component', 'HBASE_REGIONSERVER').filterProperty('isInstalled', false).forEach(function (_masterHost) { hostNames.pushObject(_masterHost.hostName); }, this); break; case 'MAPREDUCE_CLIENT': // install MAPREDUCE_CLIENT on HIVE_SERVER and OOZIE_SERVER hosts masterHosts.filterProperty('component', 'HIVE_SERVER').filterProperty('isInstalled', false).forEach(function (_masterHost) { hostNames.pushObject(_masterHost.hostName); }, this); masterHosts.filterProperty('component', 'OOZIE_SERVER').filterProperty('isInstalled', false).forEach(function (_masterHost) { hostNames.pushObject(_masterHost.hostName); }, this); break; } hostNames = hostNames.uniq(); this.registerHostsToComponent(hostNames, _client.component_name); } }, this); } }, this); // add Ganglia Monitor (Slave) to all hosts if Ganglia service is selected if (this.get('selectedServices').someProperty('serviceName', 'GANGLIA')) { var hosts = this.getRegisteredHosts().filterProperty('isInstalled', false); this.registerHostsToComponent(hosts.mapProperty('hostName'), 'GANGLIA_MONITOR'); } }, registerHostsToComponent: function (hostNames, componentName) { if (hostNames.length == 0) { return; } console.log('registering ' + componentName + ' to ' + JSON.stringify(hostNames)); // currently we are specifying the predicate as a query string. // this can hit a ~4000-character limit in Jetty server. // chunk to multiple calls if needed // var hostsPredicate = hostNames.map(function (hostName) { // return 'Hosts/host_name=' + hostName; // }).join('|'); var queryStrArr = []; var queryStr = ''; hostNames.forEach(function (hostName) { queryStr += 'Hosts/host_name=' + hostName + '|'; if (queryStr.length > 3500) { queryStrArr.push(queryStr.slice(0, -1)); queryStr = ''; } }); if (queryStr.length > 0) { queryStrArr.push(queryStr.slice(0, -1)); } queryStrArr.forEach(function (queryStr) { // console.log('creating host components for ' + queryStr); var url = App.apiPrefix + '/clusters/' + this.get('clusterName') + '/hosts?' + queryStr; var data = { "host_components": [ { "HostRoles": { "component_name": componentName } } ] }; this.ajax({ type: 'POST', url: url, data: JSON.stringify(data), beforeSend: function () { console.log('BeforeSend: registerHostsToComponent for ' + queryStr + ' and component ' + componentName); } }); }, this); }, createConfigurations: function () { var selectedServices = this.get('selectedServices'); if (!this.get('content.isWizard')) { this.createConfigSiteForService(this.createGlobalSiteObj()); this.createGlobalSitePerSlaveGroup(); this.createConfigSiteForService(this.createCoreSiteObj()); this.createConfigSiteForService(this.createHdfsSiteObj()); this.createHdfsSitePerSlaveGroup('HDFS'); } if (selectedServices.someProperty('serviceName', 'MAPREDUCE')) { this.createConfigSiteForService(this.createMrSiteObj()); this.createMrSitePerSlaveGroup('MAPREDUCE'); } if (selectedServices.someProperty('serviceName', 'HBASE')) { this.createConfigSiteForService(this.createHbaseSiteObj()); this.createHbaseSitePerSlaveGroup('HBASE'); } if (selectedServices.someProperty('serviceName', 'OOZIE')) { this.createConfigSiteForService(this.createOozieSiteObj('OOZIE')); } if (selectedServices.someProperty('serviceName', 'HIVE')) { this.createConfigSiteForService(this.createHiveSiteObj('HIVE')); } }, createConfigSiteForService: function (data) { console.log("Inside createConfigSiteForService"); var url = App.apiPrefix + '/clusters/' + this.get('clusterName') + '/configurations'; this.ajax({ type: 'POST', url: url, data: JSON.stringify(data), beforeSend: function () { console.log("BeforeSend: createConfigSiteForService for " + data.type); } }); }, createGlobalSiteObj: function () { var globalSiteProperties = {}; this.get('globals').filterProperty('domain', 'global').forEach(function (_globalSiteObj) { // do not pass any globals whose name ends with _host or _hosts if (!/_hosts?$/.test(_globalSiteObj.name)) { // append "m" to JVM memory options var value = null; if (/_heapsize|_newsize|_maxnewsize$/.test(_globalSiteObj.name)) { value = _globalSiteObj.value + "m"; globalSiteProperties[_globalSiteObj.name] = value; } else { globalSiteProperties[_globalSiteObj.name] = _globalSiteObj.value; } console.log("STEP8: name of the global property is: " + _globalSiteObj.name); console.log("STEP8: value of the global property is: " + _globalSiteObj.value); } }, this); return {"type": "global", "tag": "version1", "properties": globalSiteProperties}; }, createGlobalSitePerSlaveGroup: function () { this.get('slaveComponentConfig.components').forEach(function (_component) { _component.groups.forEach(function (_group) { var globalSiteProperties = {}; var properties = _group.properties; properties.forEach(function (_property) { if (!/_hosts?$/.test(_property.name)) { // append "m" to JVM memory options var value = null; if (/_heapsize|_newsize|_maxnewsize$/.test(_property.name)) { value = _property.value + "m"; globalSiteProperties[_property.name] = value; } else { globalSiteProperties[_property.name] = _property.storeValue; } console.log("STEP8: name of the global property is: " + _property.name); console.log("STEP8: value of the global property is: " + _property.storeValue); } }, this); var config = _group.configVersion.config; for (var index in config) { if (index === 'datanode-global' || index === 'tasktracker-global' || index === 'regionserver-global') { var data = {"type": index, "tag": config[index], "properties": globalSiteProperties}; this.createConfigSiteForService(data); } } }, this); }, this); }, createCoreSiteObj: function () { var coreSiteObj = this.get('configs').filterProperty('filename', 'core-site.xml'); var coreSiteProperties = {}; // hadoop.proxyuser.oozie.hosts needs to be skipped if oozie is not selected var isOozieSelected = this.get('selectedServices').someProperty('serviceName', 'OOZIE'); coreSiteObj.forEach(function (_coreSiteObj) { if (isOozieSelected || _coreSiteObj.name != 'hadoop.proxyuser.oozie.hosts') { coreSiteProperties[_coreSiteObj.name] = _coreSiteObj.value; } console.log("STEP*: name of the property is: " + _coreSiteObj.name); console.log("STEP8: value of the property is: " + _coreSiteObj.value); }, this); return {"type": "core-site", "tag": "version1", "properties": coreSiteProperties}; }, createHdfsSiteObj: function () { var hdfsSiteObj = this.get('configs').filterProperty('filename', 'hdfs-site.xml'); var hdfsProperties = {}; hdfsSiteObj.forEach(function (_configProperty) { hdfsProperties[_configProperty.name] = _configProperty.value; console.log("STEP*: name of the property is: " + _configProperty.name); console.log("STEP8: value of the property is: " + _configProperty.value); }, this); return {"type": "hdfs-site", "tag": "version1", "properties": hdfsProperties }; }, createHdfsSitePerSlaveGroup: function (serviceName) { var hdfsSite = this.createHdfsSiteObj(); var component = this.get('slaveComponentConfig.components').findProperty('serviceName', serviceName); component.groups.forEach(function (_group) { var siteProperties = hdfsSite.properties; _group.properties.forEach(function (_property) { this.get('configMapping').forEach(function (_config) { if (_config.templateName.contains(_property.name)) { this.get('globals').findProperty('name', _property.name).value = _property.storeValue; var value = this.getGlobConfigValue(_config.templateName, _config.value); if (siteProperties[_config.name]) { siteProperties[_config.name] = value; } } }, this); }, this); var data = {"type": hdfsSite.type, "tag": _group.siteVersion, "properties": siteProperties}; console.log("The value of globalConfig is: " + JSON.stringify(siteProperties)); this.createConfigSiteForService(data); }, this); }, createMrSiteObj: function () { var configs = this.get('configs').filterProperty('filename', 'mapred-site.xml'); var mrProperties = {}; configs.forEach(function (_configProperty) { mrProperties[_configProperty.name] = _configProperty.value; console.log("STEP*: name of the property is: " + _configProperty.name); console.log("STEP8: value of the property is: " + _configProperty.value); }, this); return {type: 'mapred-site', tag: 'version1', properties: mrProperties}; }, createMrSitePerSlaveGroup: function (serviceName) { var mrSite = this.createMrSiteObj(); var component = this.get('slaveComponentConfig.components').findProperty('serviceName', serviceName); component.groups.forEach(function (_group) { var siteProperties = mrSite.properties; _group.properties.forEach(function (_property) { this.get('configMapping').forEach(function (_config) { if (_config.templateName.contains(_property.name)) { this.get('globals').findProperty('name', _property.name).value = _property.storeValue; var value = this.getGlobConfigValue(_config.templateName, _config.value); if (siteProperties[_config.name]) { siteProperties[_config.name] = value; } } }, this); }, this); var data = {"type": mrSite.type, "tag": _group.siteVersion, "properties": siteProperties}; this.createConfigSiteForService(data); }, this); }, createHbaseSiteObj: function () { var configs = this.get('configs').filterProperty('filename', 'hbase-site.xml'); var hbaseProperties = {}; configs.forEach(function (_configProperty) { hbaseProperties[_configProperty.name] = _configProperty.value; }, this); var masterHosts = App.db.getMasterComponentHosts(); // TODO: should filter on "component" but that gives unexpected results var zkServers = masterHosts.filterProperty('display_name', 'ZooKeeper').mapProperty('hostName'); hbaseProperties['hbase.zookeeper.quorum'] = zkServers.join(','); return {type: 'hbase-site', tag: 'version1', properties: hbaseProperties}; }, createHbaseSitePerSlaveGroup: function (serviceName) { var hbaseSite = this.createHbaseSiteObj(); var component = this.get('slaveComponentConfig.components').findProperty('serviceName', serviceName); component.groups.forEach(function (_group) { var siteProperties = hbaseSite.properties; _group.properties.forEach(function (_property) { this.get('configMapping').forEach(function (_config) { if (_config.templateName.contains(_property.name)) { this.get('globals').findProperty('name', _property.name).value = _property.storeValue; var value = this.getGlobConfigValue(_config.templateName, _config.value); if (siteProperties[_config.name]) { siteProperties[_config.name] = value; } } }, this); }, this); var data = {"type": hbaseSite.type, "tag": _group.siteVersion, "properties": siteProperties}; this.createConfigSiteForService(data); }, this); }, createOozieSiteObj: function (serviceName) { var configs = this.get('configs').filterProperty('filename', 'oozie-site.xml'); var oozieProperties = {}; configs.forEach(function (_configProperty) { oozieProperties[_configProperty.name] = _configProperty.value; }, this); // var baseUrl = oozieProperties['oozie.base.url']; // oozieProperties = { // "oozie.service.JPAService.jdbc.password": " ", "oozie.db.schema.name": "oozie", "oozie.service.JPAService.jdbc.url": "jdbc:derby:/var/data/oozie/oozie-db;create=true", "oozie.service.JPAService.jdbc.driver": "org.apache.derby.jdbc.EmbeddedDriver", "oozie.service.WorkflowAppService.system.libpath": "/user/oozie/share/lib", "oozie.service.JPAService.jdbc.username": "sa", "oozie.service.SchemaService.wf.ext.schemas": "shell-action-0.1.xsd,email-action-0.1.xsd,hive-action-0.2.xsd,sqoop-action-0.2.xsd,ssh-action-0.1.xsd,distcp-action-0.1.xsd", "oozie.service.JPAService.create.db.schema": "false", "use.system.libpath.for.mapreduce.and.pig.jobs": "false", "oozie.service.ActionService.executor.ext.classes": "org.apache.oozie.action.email.EmailActionExecutor,org.apache.oozie.action.hadoop.HiveActionExecutor,org.apache.oozie.action.hadoop.ShellActionExecutor,org.apache.oozie.action.hadoop.SqoopActionExecutor,org.apache.oozie.action.hadoop.DistcpActionExecutor", "oozie.service.HadoopAccessorService.hadoop.configurations": "*=/etc/hadoop/conf" // }; // oozieProperties['oozie.base.url'] = baseUrl; return {type: 'oozie-site', tag: 'version1', properties: oozieProperties}; }, createHiveSiteObj: function (serviceName) { var configs = this.get('configs').filterProperty('filename', 'hive-site.xml'); var hiveProperties = {}; configs.forEach(function (_configProperty) { hiveProperties[_configProperty.name] = _configProperty.value; }, this); return {type: 'hive-site', tag: 'version1', properties: hiveProperties}; }, applyCreatedConfToServices: function () { var services = this.get('selectedServices').mapProperty('serviceName'); services.forEach(function (_service) { var data = this.getConfigForService(_service); this.applyCreatedConfToService(_service, 'PUT', data); }, this); }, applyCreatedConfToService: function (service, httpMethod, data) { console.log("Inside applyCreatedConfToService"); var url = App.apiPrefix + '/clusters/' + this.get('clusterName') + '/services/' + service; this.ajax({ type: httpMethod, url: url, data: JSON.stringify(data), beforeSend: function () { console.log("BeforeSend: applyCreatedConfToService for " + service); } }); }, applyCreatedConfToSlaveGroups: function () { this.get('slaveComponentConfig.components').forEach(function (_component) { _component.groups.forEach(function (_group) { var aggregatedHostNames = ''; _group.hostNames.forEach(function (_hostName, index) { aggregatedHostNames += 'HostRoles/host_name=' + _hostName; if (index !== _group.hostNames.length-1) { aggregatedHostNames += '|'; } }, this); console.log("The aggregated hostNames value is: " + aggregatedHostNames); this.applyCreatedConfToSlaveGroup(aggregatedHostNames, 'PUT', _group.configVersion,_group.groupName); }, this); }, this); }, applyCreatedConfToSlaveGroup: function (aggregatedHostNames, httpMethod, data, groupName) { console.log("Inside applyCreatedConfToHost"); var url = App.apiPrefix + '/clusters/' + this.get('clusterName') + '/host_components?' + aggregatedHostNames; this.ajax({ type: httpMethod, url: url, data: JSON.stringify(data), beforeSend: function () { console.log("BeforeSend: applyCreatedConfToSlaveGroup for group: " + groupName); } }); }, getConfigForService: function (serviceName) { switch (serviceName) { case 'HDFS': return {config: {'global': 'version1', 'core-site': 'version1', 'hdfs-site': 'version1'}}; case 'MAPREDUCE': return {config: {'global': 'version1', 'core-site': 'version1', 'mapred-site': 'version1'}}; case 'HBASE': return {config: {'global': 'version1', 'core-site': 'version1', 'hbase-site': 'version1'}}; case 'OOZIE': return {config: {'global': 'version1', 'core-site': 'version1', 'oozie-site': 'version1'}}; default: return {config: {'global': 'version1'}}; } }, ajaxQueue: [], ajaxQueueFinished: function () { //do something }, doNextAjaxCall: function () { if (this.get('ajaxBusy')) { return; } var queue = this.get('ajaxQueue'); if (!queue.length) { this.ajaxQueueFinished(); return; } var first = queue[0]; this.set('ajaxQueue', queue.slice(1)); this.set('ajaxBusy', true); console.log('AJAX send ' + first.url); $.ajax(first); }, /** * We need to do a lot of ajax calls(about 10 or more) async in special order. * To do this i generate array of ajax objects and then send requests step by step. * All ajax objects are stored in ajaxQueue * @param params */ ajax: function(params){ if(App.testMode) return; var self = this; params = jQuery.extend({ async: true, dataType: 'text', statusCode: require('data/statusCodes'), timeout: App.timeout, error: function (request, ajaxOptions, error) { console.log('Step8: In Error '); console.log('Step8: Error message is: ' + request.responseText); }, success: function (data) { var jsonData = jQuery.parseJSON(data); console.log("TRACE: STep8 -> In success function"); console.log("TRACE: STep8 -> value of the url is: " + params.url); console.log("TRACE: STep8 -> value of the received data is: " + jsonData); } }, params); var success = params.success; var error = params.error; params.success = function () { if (success) { success(); } ; self.set('ajaxBusy', false); self.doNextAjaxCall(); } params.error = function () { if (error) { error(); } ; self.set('ajaxBusy', false); self.doNextAjaxCall(); } this.get('ajaxQueue').pushObject(params); } })