/** * 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.AddServiceController = Em.Controller.extend({ name: 'addServiceController', /** * All wizards data will be stored in this variable * * cluster - cluster name * hosts - hosts, ssh key, repo info, etc. * services - services list * hostsInfo - list of selected hosts * slaveComponentHosts, - info about slave hosts * masterComponentHosts - info about master hosts * config??? - to be described later */ content: Em.Object.create({ cluster: null, hosts: null, services: null, hostsInfo: null, slaveComponentHosts: null, masterComponentHosts: null, serviceConfigProperties: null, advancedServiceConfig: null, controllerName: 'addServiceController', isWizard: true }), /** * Used for hiding back button in wizard */ hideBackButton: true, isStepDisabled: [], totalSteps: 9, init: function () { this.isStepDisabled.pushObject(Ember.Object.create({ step: 1, value: false })); for (var i = 2; i <= this.totalSteps; i++) { this.isStepDisabled.pushObject(Ember.Object.create({ step: i, value: true })); } }, setStepsEnable: function () { for (var i = 2; i <= this.totalSteps; i++) { var step = this.get('isStepDisabled').findProperty('step', i); if (i <= this.get('currentStep')) { step.set('value', false); } else { step.set('value', true); } } }.observes('currentStep'), /** * Return current step of Add Host Wizard */ currentStep: function () { return App.get('router').getWizardCurrentStep('addService'); }.property(), clusters: null, /** * Set current step to new value. * Method moved from App.router.setInstallerCurrentStep * @param currentStep * @param completed */ setCurrentStep: function (currentStep, completed) { App.db.setWizardCurrentStep('addService', currentStep, completed); this.set('currentStep', currentStep); }, isStep1: function () { return this.get('currentStep') == 1; }.property('currentStep'), isStep2: function () { return this.get('currentStep') == 2; }.property('currentStep'), isStep3: function () { return this.get('currentStep') == 3; }.property('currentStep'), isStep4: function () { return this.get('currentStep') == 4; }.property('currentStep'), isStep5: function () { return this.get('currentStep') == 5; }.property('currentStep'), isStep6: function () { return this.get('currentStep') == 6; }.property('currentStep'), isStep7: function () { return this.get('currentStep') == 7; }.property('currentStep'), gotoStep: function (step) { if (this.get('isStepDisabled').findProperty('step', step).get('value') === false) { App.router.send('gotoStep' + step); } }, gotoStep1: function () { this.gotoStep(1); }, gotoStep2: function () { this.gotoStep(2); }, gotoStep3: function () { this.gotoStep(3); }, gotoStep4: function () { this.gotoStep(4); }, gotoStep5: function () { this.gotoStep(5); }, gotoStep6: function () { this.gotoStep(6); }, gotoStep7: function () { this.gotoStep(7); }, /** * Load clusterInfo(step1) to model */ loadClusterInfo: function(){ var cluster = App.db.getClusterStatus(); if(!cluster){ cluster = { name: App.router.getClusterName(), status: "", isCompleted: false }; App.db.setClusterStatus(cluster); } this.set('content.cluster', cluster); console.log("AddServiceController:loadClusterInfo: loaded data ", cluster); }, /** * save status of the cluster. This is called from step8 and step9 to persist install and start requestId * @param clusterStatus object with status, isCompleted, requestId, isInstallError and isStartError field. */ saveClusterStatus: function (clusterStatus) { clusterStatus.name = this.get('content.cluster.name'); this.set('content.cluster', clusterStatus); console.log('called saveClusterStatus ' + JSON.stringify(clusterStatus)); App.db.setClusterStatus(clusterStatus); }, /** * Temporary function for wizardStep9, before back-end integration */ setInfoForStep9: function () { var hostInfo = App.db.getHosts(); for (var index in hostInfo) { hostInfo[index].status = "pending"; hostInfo[index].message = 'Information'; hostInfo[index].progress = '0'; } App.db.setHosts(hostInfo); }, /** * Load confirmed hosts. * Will be used at Assign Masters(step5) step */ loadConfirmedHosts: function(){ var hosts = App.db.getHosts(); if(!hosts){ var hosts = {}; App.Host.find().forEach(function(item){ hosts[item.get('id')] = { name: item.get('id'), cpu: item.get('cpu'), memory: item.get('memory'), bootStatus: "success", isInstalled: true }; }); } this.set('content.hostsInfo', hosts); console.log('AddServiceController.loadConfirmedHosts: loaded hosts', hosts); }, /** * Save data after installation to main controller * @param stepController App.WizardStep9Controller */ saveInstalledHosts: function (stepController) { var hosts = stepController.get('hosts'); var hostInfo = App.db.getHosts(); for (var index in hostInfo) { hostInfo[index].status = "pending"; var host = hosts.findProperty('name', hostInfo[index].name); if (host) { hostInfo[index].status = host.status; hostInfo[index].message = host.message; hostInfo[index].progress = host.progress; } } App.db.setHosts(hostInfo); this.set('content.hostsInfo', hostInfo); console.log('AddServiceController:saveInstalledHosts: save hosts ', hostInfo); }, /** * Remove all data for hosts */ clearHosts: function () { var hosts = this.get('content').get('hosts'); if (hosts) { hosts.hostNames = ''; hosts.manualInstall = false; hosts.localRepo = ''; hosts.localRepopath = ''; hosts.sshKey = ''; hosts.passphrase = ''; hosts.confirmPassphrase = ''; } App.db.setHosts(null); App.db.setAllHostNames(null); }, /** * Load services data. Will be used at Select services(step4) step */ loadServices: function () { var servicesInfo = App.db.getService(); if(!servicesInfo || !servicesInfo.length){ servicesInfo = require('data/mock/services').slice(0); servicesInfo.forEach(function(item, index){ servicesInfo[index].isSelected = App.Service.find().someProperty('id', item.serviceName); servicesInfo[index].isDisabled = servicesInfo[index].isSelected; servicesInfo[index].isInstalled = servicesInfo[index].isSelected; }); } servicesInfo.forEach(function (item, index) { servicesInfo[index] = Em.Object.create(item); }); this.set('content.services', servicesInfo); console.log('AddServiceController.loadServices: loaded data ', servicesInfo); var serviceNames = servicesInfo.filterProperty('isSelected', true).filterProperty('isDisabled', false).mapProperty('serviceName'); console.log('selected services ', serviceNames); this.set('content.missSlavesStep', !serviceNames.contains('MAPREDUCE') && !serviceNames.contains('HBASE')); }, /** * Save data to model * @param stepController App.WizardStep4Controller */ saveServices: function (stepController) { var serviceNames = []; App.db.setService(stepController.get('content')); console.log('AddServiceController.saveServices: saved data', stepController.get('content')); stepController.filterProperty('isSelected', true).filterProperty('isInstalled', false).forEach(function (item) { serviceNames.push(item.serviceName); }); this.set('content.selectedServiceNames', serviceNames); App.db.setSelectedServiceNames(serviceNames); console.log('AddServiceController.selectedServiceNames:', serviceNames); this.set('content.missSlavesStep', !serviceNames.contains('MAPREDUCE') && !serviceNames.contains('HBASE')); }, /** * Save Master Component Hosts data to Main Controller * @param stepController App.WizardStep5Controller */ saveMasterComponentHosts: function (stepController) { var obj = stepController.get('selectedServicesMasters'); var masterComponentHosts = []; var installedComponents = App.Component.find(); obj.forEach(function (_component) { masterComponentHosts.push({ display_name: _component.display_name, component: _component.component_name, hostName: _component.selectedHost, serviceId: _component.serviceId, isInstalled: installedComponents.someProperty('componentName', _component.component_name) }); }); console.log("AddServiceController.saveMasterComponentHosts: saved hosts ", masterComponentHosts); App.db.setMasterComponentHosts(masterComponentHosts); this.set('content.masterComponentHosts', masterComponentHosts); this.set('content.missMasterStep', this.get('content.masterComponentHosts').everyProperty('isInstalled', true)); }, /** * Load master component hosts data for using in required step controllers */ loadMasterComponentHosts: function () { var masterComponentHosts = App.db.getMasterComponentHosts(); if(!masterComponentHosts){ masterComponentHosts = []; App.Component.find().filterProperty('isMaster', true).forEach(function(item){ masterComponentHosts.push({ component: item.get('componentName'), hostName: item.get('host.hostName'), isInstalled: true }) }); } this.set("content.masterComponentHosts", masterComponentHosts); console.log("AddServiceController.loadMasterComponentHosts: loaded hosts ", masterComponentHosts); this.set('content.missMasterStep', this.get('content.masterComponentHosts').everyProperty('isInstalled', true)); }, /** * Save slaveHostComponents to main controller * @param stepController */ saveSlaveComponentHosts: function (stepController) { var hosts = stepController.get('hosts'); var isMrSelected = stepController.get('isMrSelected'); var isHbSelected = stepController.get('isHbSelected'); var dataNodeHosts = []; var taskTrackerHosts = []; var regionServerHosts = []; var clientHosts = []; hosts.forEach(function (host) { if (host.get('isDataNode')) { dataNodeHosts.push({ hostName: host.hostName, group: 'Default', isInstalled: host.get('isDataNodeInstalled') }); } if (isMrSelected && host.get('isTaskTracker')) { taskTrackerHosts.push({ hostName: host.hostName, group: 'Default', isInstalled: host.get('isTaskTrackerInstalled') }); } if (isHbSelected && host.get('isRegionServer')) { regionServerHosts.push({ hostName: host.hostName, group: 'Default', isInstalled: host.get('isRegionServerInstalled') }); } if (host.get('isClient')) { clientHosts.pushObject({ hostName: host.hostName, group: 'Default', isInstalled: host.get('isClientInstalled') }); } }, this); var slaveComponentHosts = []; slaveComponentHosts.push({ componentName: 'DATANODE', displayName: 'DataNode', hosts: dataNodeHosts }); if (isMrSelected) { slaveComponentHosts.push({ componentName: 'TASKTRACKER', displayName: 'TaskTracker', hosts: taskTrackerHosts }); } if (isHbSelected) { slaveComponentHosts.push({ componentName: 'HBASE_REGIONSERVER', displayName: 'RegionServer', hosts: regionServerHosts }); } slaveComponentHosts.pushObject({ componentName: 'CLIENT', displayName: 'client', hosts: clientHosts }); App.db.setSlaveComponentHosts(slaveComponentHosts); console.log('addServiceController.slaveComponentHosts: saved hosts', slaveComponentHosts); this.set('content.slaveComponentHosts', slaveComponentHosts); }, /** * return slaveComponents bound to hosts * @return {Array} */ getSlaveComponentHosts: function () { var components = [{ name : 'DATANODE', service : 'HDFS' }, { name: 'TASKTRACKER', service: 'MAPREDUCE' },{ name: 'HBASE_REGIONSERVER', service: 'HBASE' }]; var result = []; var services = App.Service.find(); var selectedServices = this.get('content.services').filterProperty('isSelected', true).mapProperty('serviceName'); for(var index=0; index < components.length; index++){ var comp = components[index]; if(!selectedServices.contains(comp.service)){ continue; } var service = services.findProperty('id', comp.service); var hosts = []; if(!service){ service = services.findProperty('id', 'HDFS'); service.get('hostComponents').filterProperty('componentName', 'DATANODE').forEach(function (host_component) { hosts.push({ group: "Default", hostName: host_component.get('host.id'), isInstalled: false }); }, this); } else { service.get('hostComponents').filterProperty('componentName', comp.name).forEach(function (host_component) { hosts.push({ group: "Default", hostName: host_component.get('host.id'), isInstalled: true }); }, this); } result.push({ componentName: comp.name, displayName: App.format.role(comp.name), hosts: hosts }) } var clientsHosts = App.HostComponent.find().filterProperty('componentName', 'HDFS_CLIENT'); var hosts = []; clientsHosts.forEach(function (host_component) { hosts.push({ group: "Default", hostName: host_component.get('host.id'), isInstalled: true }); }, this); result.push({ componentName: 'CLIENT', displayName: 'client', hosts: hosts }) return result; }, /** * Load master component hosts data for using in required step controllers */ loadSlaveComponentHosts: function () { var slaveComponentHosts = App.db.getSlaveComponentHosts(); if(!slaveComponentHosts){ slaveComponentHosts = this.getSlaveComponentHosts(); } this.set("content.slaveComponentHosts", slaveComponentHosts); console.log("AddServiceController.loadSlaveComponentHosts: loaded hosts ", slaveComponentHosts); }, /** * Save config properties * @param stepController Step7WizardController */ saveServiceConfigProperties: function (stepController) { var serviceConfigProperties = []; stepController.get('stepConfigs').forEach(function (_content) { _content.get('configs').forEach(function (_configProperties) { var configProperty = { name: _configProperties.get('name'), value: _configProperties.get('value'), service: _configProperties.get('serviceName') }; serviceConfigProperties.push(configProperty); }, this); }, this); App.db.setServiceConfigProperties(serviceConfigProperties); this.set('content.serviceConfigProperties', serviceConfigProperties); }, /** * Load serviceConfigProperties to model */ loadServiceConfigProperties: function () { var serviceConfigProperties = App.db.getServiceConfigProperties(); this.set('content.serviceConfigProperties', serviceConfigProperties); console.log("AddServiceController.loadServiceConfigProperties: loaded config ", serviceConfigProperties); }, /** * Load information about hosts with clients components */ loadClients: function(){ var clients = App.db.getClientsForSelectedServices(); this.set('content.clients', clients); console.log("AddServiceController.loadClients: loaded list ", clients); }, dataLoading: function(){ var dfd = $.Deferred(); this.connectOutlet('loading'); if (App.router.get('clusterController.isLoaded')){ dfd.resolve(); } else{ var interval = setInterval(function(){ if (App.router.get('clusterController.isLoaded')){ dfd.resolve(); clearInterval(interval); } },50); } return dfd.promise(); }, /** * Generate clients list for selected services and save it to model * @param stepController step4WizardController */ saveClients: function(stepController){ var clients = []; var serviceComponents = require('data/service_components'); var hostComponents = App.HostComponent.find(); stepController.get('content').filterProperty('isSelected',true).forEach(function (_service) { var client = serviceComponents.filterProperty('service_name', _service.serviceName).findProperty('isClient', true); if (client) { clients.pushObject({ component_name: client.component_name, display_name: client.display_name, isInstalled: hostComponents.filterProperty('componentName', client.component_name).length > 0 }); } }, this); App.db.setClientsForSelectedServices(clients); this.set('content.clients', clients); console.log("AddServiceController.saveClients: saved list ", clients); }, /** * Load data for all steps until current step */ loadAllPriorSteps: function () { var step = this.get('currentStep'); switch (step) { case '7': case '6': case '5': this.loadClusterInfo(); case '4': this.loadServiceConfigProperties(); case '3': this.loadServices(); this.loadClients(); this.loadSlaveComponentHosts();//depends on loadServices case '2': this.loadMasterComponentHosts(); this.loadConfirmedHosts(); case '1': this.loadServices(); } }, loadAdvancedConfigs: function () { App.db.getSelectedServiceNames().forEach(function (_serviceName) { this.loadAdvancedConfig(_serviceName); }, this); }, /** * Generate serviceProperties save it to localdata * called form stepController step6WizardController */ loadAdvancedConfig: function (serviceName) { var self = this; var url = (App.testMode) ? '/data/wizard/stack/hdp/version01/' + serviceName + '.json' : App.apiPrefix + '/stacks/HDP/version/1.2.0/services/' + serviceName; // TODO: get this url from the stack selected by the user in Install Options page var method = 'GET'; $.ajax({ type: method, url: url, async: false, dataType: 'text', timeout: App.timeout, success: function (data) { var jsonData = jQuery.parseJSON(data); console.log("TRACE: Step6 submit -> In success function for the loadAdvancedConfig call"); console.log("TRACE: Step6 submit -> value of the url is: " + url); var serviceComponents = jsonData.properties; serviceComponents.setEach('serviceName', serviceName); var configs; if (App.db.getAdvancedServiceConfig()) { configs = App.db.getAdvancedServiceConfig(); } else { configs = []; } configs = configs.concat(serviceComponents); self.set('content.advancedServiceConfig', configs); App.db.setAdvancedServiceConfig(configs); console.log('TRACE: servicename: ' + serviceName); }, error: function (request, ajaxOptions, error) { console.log("TRACE: STep6 submit -> In error function for the loadAdvancedConfig call"); console.log("TRACE: STep6 submit-> value of the url is: " + url); console.log("TRACE: STep6 submit-> error code status is: " + request.status); console.log('Step6 submit: Error message is: ' + request.responseText); }, statusCode: require('data/statusCodes') }); }, /** * Generate clients list for selected services and save it to model * @param stepController step8WizardController or step9WizardController */ installServices: function (isRetry) { if(!isRetry && this.get('content.cluster.requestId')){ return; } var self = this; var clusterName = this.get('content.cluster.name'); var url = (App.testMode) ? '/data/wizard/deploy/poll_1.json' : App.apiPrefix + '/clusters/' + clusterName + '/services?state=INIT'; var method = (App.testMode) ? 'GET' : 'PUT'; var data = '{"ServiceInfo": {"state": "INSTALLED"}}'; $.ajax({ type: method, url: url, data: data, async: false, dataType: 'text', timeout: App.timeout, success: function (data) { var jsonData = jQuery.parseJSON(data); var installSartTime = new Date().getTime(); console.log("TRACE: STep8 -> In success function for the installService call"); console.log("TRACE: STep8 -> value of the url is: " + url); if (jsonData) { var requestId = jsonData.href.match(/.*\/(.*)$/)[1]; console.log('requestId is: ' + requestId); var clusterStatus = { status: 'PENDING', requestId: requestId, isInstallError: false, isCompleted: false, installStartTime: installSartTime }; self.saveClusterStatus(clusterStatus); } else { console.log('ERROR: Error occurred in parsing JSON data'); } }, error: function (request, ajaxOptions, error) { console.log("TRACE: STep8 -> In error function for the installService call"); console.log("TRACE: STep8 -> value of the url is: " + url); console.log("TRACE: STep8 -> error code status is: " + request.status); console.log('Step8: Error message is: ' + request.responseText); var clusterStatus = { status: 'PENDING', isInstallError: true, isCompleted: false }; self.saveClusterStatus(clusterStatus); }, statusCode: require('data/statusCodes') }); }, /** * Remove all loaded data. * Created as copy for App.router.clearAllSteps */ clearAllSteps: function () { this.clearHosts(); //todo it) }, /** * Clear all temporary data */ finish: function(){ this.setCurrentStep('1', false); App.db.setService(undefined); //not to use this data at AddService page App.db.setHosts(undefined); App.db.setMasterComponentHosts(undefined); App.db.setSlaveComponentHosts(undefined); App.db.setClusterStatus(undefined); App.db.setAllHostNames(undefined); } });