You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by yu...@apache.org on 2013/04/06 03:55:47 UTC

svn commit: r1465166 [8/15] - in /incubator/ambari/trunk: ./ ambari-web/app/ ambari-web/app/assets/data/background_operations/ ambari-web/app/assets/data/clusters/ ambari-web/app/assets/data/configurations/ ambari-web/app/assets/data/dashboard/ ambari-...

Modified: incubator/ambari/trunk/ambari-web/app/controllers/main/service/item.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/controllers/main/service/item.js?rev=1465166&r1=1465165&r2=1465166&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/controllers/main/service/item.js (original)
+++ incubator/ambari/trunk/ambari-web/app/controllers/main/service/item.js Sat Apr  6 01:55:42 2013
@@ -49,7 +49,7 @@ App.MainServiceItemController = Em.Contr
    */
   ajaxSuccess: function(data, ajaxOptions) {
     if(data && data.Requests) {
-      this.ajaxCallBack(data.Requests.id, (JSON.parse(ajaxOptions.data)).ServiceInfo.state);
+      this.ajaxCallBack(data.Requests.id, (JSON.parse(ajaxOptions.data)).Body.ServiceInfo.state);
     }
     else {
       console.log('cannot get request id from ', data);
@@ -74,16 +74,6 @@ App.MainServiceItemController = Em.Contr
     }
     else {
       App.router.get('clusterController').loadUpdatedStatusDelayed(500);// @todo check working without param 500
-      App.router.get('backgroundOperationsController.eventsArray').push({
-        "when": function (controller) {
-          var result = (controller.getOperationsForRequestId(requestId).length == 0);
-          console.log(config.s + 'Service.when = ', result)
-          return result;
-        },
-        "do": function () {
-          App.router.get('clusterController').loadUpdatedStatus();
-        }
-      });
     }
     App.router.get('backgroundOperationsController').showPopup();
   },
@@ -103,11 +93,19 @@ App.MainServiceItemController = Em.Contr
   },
 
   startStopPopupPrimary: function(serviceHealth) {
+    var requestInfo = "";
+    if(serviceHealth == "STARTED"){
+      requestInfo = 'Start service ' + this.get('content.serviceName').toUpperCase() ;
+    }else{
+      requestInfo = 'Stop service ' + this.get('content.serviceName').toUpperCase() ;
+    }
+
     App.ajax.send({
       'name': 'service.item.start_stop',
       'sender': this,
       'success': 'ajaxSuccess',
       'data': {
+        'requestInfo':requestInfo,
         'serviceName': this.get('content.serviceName').toUpperCase(),
         'state': serviceHealth
       }

Modified: incubator/ambari/trunk/ambari-web/app/controllers/main/service/reassign_controller.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/controllers/main/service/reassign_controller.js?rev=1465166&r1=1465165&r2=1465166&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/controllers/main/service/reassign_controller.js (original)
+++ incubator/ambari/trunk/ambari-web/app/controllers/main/service/reassign_controller.js Sat Apr  6 01:55:42 2013
@@ -54,6 +54,10 @@ App.ReassignMasterController = App.Wizar
     reassign: null
   }),
 
+  skipStep3: function () {
+    return this.get('content.reassign.service_id') == 'GANGLIA';
+  }.property('content.reassign.service_id'),
+
   /**
    * return new object extended from clusterStatusTemplate
    * @return Object
@@ -126,6 +130,33 @@ App.ReassignMasterController = App.Wizar
   },
 
   /**
+   * Load tasks statuses for step5 of Reassign Master Wizard to restore installation
+   */
+  loadTasksStatuses: function(){
+    var statuses = App.db.getReassignTasksStatuses();
+    this.set('content.tasksStatuses', statuses);
+    console.log('ReassignMasterController.loadTasksStatuses: loaded statuses', statuses);
+  },
+
+  /**
+   * save status of the cluster.
+   * @param clusterStatus object with status,requestId fields.
+   */
+  saveClusterStatus: function (clusterStatus) {
+    var oldStatus = this.toObject(this.get('content.cluster'));
+    clusterStatus = jQuery.extend(oldStatus, clusterStatus);
+    if (clusterStatus.requestId) {
+      clusterStatus.requestId.forEach(function (requestId) {
+        if (clusterStatus.oldRequestsId.indexOf(requestId) === -1) {
+          clusterStatus.oldRequestsId.push(requestId)
+        }
+      }, this);
+    }
+    this.set('content.cluster', clusterStatus);
+    this.save('cluster');
+  },
+
+  /**
    * Save Master Component Hosts data to Main Controller
    * @param stepController App.WizardStep5Controller
    */
@@ -162,36 +193,10 @@ App.ReassignMasterController = App.Wizar
     };
     App.db.setMasterToReassign(component);
   },
-
-  /**
-   * Save config properties
-   * @param stepController Step7WizardController
-   */
-  saveServiceConfigProperties: function (stepController) {
-    var serviceConfigProperties = [];
-    stepController.get('stepConfigs').forEach(function (_content) {
-      _content.get('configs').forEach(function (_configProperties) {
-        var displayType = _configProperties.get('displayType');
-        if (displayType === 'directories' || displayType === 'directory') {
-          var value = _configProperties.get('value').trim().split(/\s+/g).join(',');
-          _configProperties.set('value', value);
-        }
-        var configProperty = {
-          id: _configProperties.get('id'),
-          name: _configProperties.get('name'),
-          value: _configProperties.get('value'),
-          defaultValue: _configProperties.get('defaultValue'),
-          service: _configProperties.get('serviceName'),
-          domain:  _configProperties.get('domain'),
-          filename: _configProperties.get('filename')
-        };
-        serviceConfigProperties.push(configProperty);
-      }, this);
-
-    }, this);
-
-    App.db.setServiceConfigProperties(serviceConfigProperties);
-    this.set('content.serviceConfigProperties', serviceConfigProperties);
+  saveTasksStatuses: function(statuses){
+    App.db.setReassignTasksStatuses(statuses);
+    this.set('content.tasksStatuses', statuses);
+    console.log('ReassignMasterController.saveTasksStatuses: saved statuses', statuses);
   },
 
   /**
@@ -202,8 +207,10 @@ App.ReassignMasterController = App.Wizar
     switch (step) {
       case '6':
       case '5':
+        this.loadTasksStatuses();
       case '4':
       case '3':
+        this.loadServiceConfigProperties();
       case '2':
         this.loadServicesFromServer();
         this.loadMasterComponentHosts();

Modified: incubator/ambari/trunk/ambari-web/app/controllers/wizard.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/controllers/wizard.js?rev=1465166&r1=1465165&r2=1465166&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/controllers/wizard.js (original)
+++ incubator/ambari/trunk/ambari-web/app/controllers/wizard.js Sat Apr  6 01:55:42 2013
@@ -262,21 +262,20 @@ App.WizardController = Em.Controller.ext
     switch (this.get('content.controllerName')) {
       case 'addHostController':
         if (isRetry) {
-          url = App.apiPrefix + '/clusters/' + clusterName + '/host_components?HostRoles/state!=INSTALLED';
-          data = '{"HostRoles": {"state": "INSTALLED"}}';
+          url = App.apiPrefix + '/clusters/' + clusterName + '/host_components?HostRoles/state=INSTALLED';
         } else {
           url = App.apiPrefix + '/clusters/' + clusterName + '/host_components?HostRoles/state=INIT';
-          data = '{"HostRoles": {"state": "INSTALLED"}}';
         }
+        data = '{"RequestInfo": {"context" :"'+ Em.I18n.t('requestInfo.installComponents') +'"}, "Body": {"HostRoles": {"state": "INSTALLED"}}}';
         break;
       case 'installerController':
       default:
         if (isRetry) {
           url = (App.testMode) ? '/data/wizard/deploy/2_hosts/poll_1.json' : App.apiPrefix + '/clusters/' + clusterName + '/host_components?HostRoles/state!=INSTALLED';
-          data = '{"HostRoles": {"state": "INSTALLED"}}';
+          data = '{"RequestInfo": {"context" :"'+ Em.I18n.t('requestInfo.installComponents') +'"}, "Body": {"HostRoles": {"state": "INSTALLED"}}}';
         } else {
           url = (App.testMode) ? '/data/wizard/deploy/2_hosts/poll_1.json' : App.apiPrefix + '/clusters/' + clusterName + '/services?ServiceInfo/state=INIT';
-          data = '{"ServiceInfo": {"state": "INSTALLED"}}';
+          data = '{"RequestInfo": {"context" :"'+ Em.I18n.t('requestInfo.installServices') +'"}, "Body": {"ServiceInfo": {"state": "INSTALLED"}}}';
         }
         break;
     }
@@ -431,7 +430,7 @@ App.WizardController = Em.Controller.ext
   loadServiceComponents: function (displayOrderConfig, apiUrl) {
     var result = null;
     var method = 'GET';
-    var testUrl = '/data/wizard/stack/hdp/version/1.2.0.json';
+    var testUrl = '/data/wizard/stack/hdp/version/1.3.0.json';
     var url = (App.testMode) ? testUrl : App.apiPrefix + apiUrl;
     $.ajax({
       type: method,
@@ -460,19 +459,23 @@ App.WizardController = Em.Controller.ext
         // loop through all the service components
         for (var i = 0; i < displayOrderConfig.length; i++) {
           var entry = jsonData.services.findProperty("name", displayOrderConfig[i].serviceName);
-
-          var myService = Service.create({
-            serviceName: entry.name,
-            displayName: displayOrderConfig[i].displayName,
-            isDisabled: i === 0,
-            isSelected: true,
-            isInstalled: false,
-            isHidden: displayOrderConfig[i].isHidden,
-            description: entry.comment,
-            version: entry.version
-          });
-
-          data.push(myService);
+          if (entry) {
+            var myService = Service.create({
+              serviceName: entry.name,
+              displayName: displayOrderConfig[i].displayName,
+              isDisabled: i === 0,
+              isSelected: true,
+              isInstalled: false,
+              isHidden: displayOrderConfig[i].isHidden,
+              description: entry.comment,
+              version: entry.version
+            });
+
+            data.push(myService);
+          }
+          else {
+            console.warn('Service not found - ', displayOrderConfig[i].serviceName);
+          }
         }
 
         result = data;
@@ -585,7 +588,7 @@ App.WizardController = Em.Controller.ext
           formattedHosts.get(header.get('name')).push({
             hostName: host.hostName,
             group: 'Default',
-            isInstalled: cb.get('installed')
+            isInstalled: cb.get('isInstalled')
           });
         }
       });
@@ -624,6 +627,83 @@ App.WizardController = Em.Controller.ext
       },50);
     }
     return dfd.promise();
-  }
+  },
+
+  /**
+   * Save cluster status before going to deploy step
+   * @param name cluster state. Unique for every wizard
+   */
+  saveClusterState: function(name){
+    App.clusterStatus.setClusterStatus({
+      clusterName: this.get('content.cluster.name'),
+      clusterState: name,
+      wizardControllerName: this.get('content.controllerName'),
+      localdb: App.db.data
+    });
+  },
 
+  /**
+   * load advanced configs from server
+   */
+  loadAdvancedConfigs: function () {
+    var configs = (App.db.getAdvancedServiceConfig()) ? App.db.getAdvancedServiceConfig() : [];
+    this.get('content.services').filterProperty('isSelected', true).mapProperty('serviceName').forEach(function (_serviceName) {
+      var serviceComponents = App.config.loadAdvancedConfig(_serviceName);
+      if(serviceComponents){
+        configs = configs.concat(serviceComponents);
+      }
+    }, this);
+    this.set('content.advancedServiceConfig', configs);
+    App.db.setAdvancedServiceConfig(configs);
+  },
+  /**
+   * Load serviceConfigProperties to model
+   */
+  loadServiceConfigProperties: function () {
+    var serviceConfigProperties = App.db.getServiceConfigProperties();
+    this.set('content.serviceConfigProperties', serviceConfigProperties);
+    console.log("AddHostController.loadServiceConfigProperties: loaded config ", serviceConfigProperties);
+  },
+  /**
+   * Save config properties
+   * @param stepController Step7WizardController
+   */
+  saveServiceConfigProperties: function (stepController) {
+    var serviceConfigProperties = [];
+    stepController.get('stepConfigs').forEach(function (_content) {
+      _content.get('configs').forEach(function (_configProperties) {
+        var displayType = _configProperties.get('displayType');
+        if (displayType === 'directories' || displayType === 'directory') {
+          var value = _configProperties.get('value').trim().split(/\s+/g).join(',');
+          _configProperties.set('value', value);
+        }
+        var overrides = _configProperties.get('overrides');
+        var overridesArray = [];
+        if(overrides!=null){
+          overrides.forEach(function(override){
+            var overrideEntry = {
+              value: override.get('value'),
+              hosts: []
+            };
+            override.get('selectedHostOptions').forEach(function(host){
+              overrideEntry.hosts.push(host);
+            });
+            overridesArray.push(overrideEntry);
+          });
+        }
+        var configProperty = {
+          id: _configProperties.get('id'),
+          name: _configProperties.get('name'),
+          value: _configProperties.get('value'),
+          defaultValue: _configProperties.get('defaultValue'),
+          serviceName: _configProperties.get('serviceName'),
+          domain:  _configProperties.get('domain'),
+          filename: _configProperties.get('filename')
+        };
+        serviceConfigProperties.push(configProperty);
+      }, this);
+    }, this);
+    App.db.setServiceConfigProperties(serviceConfigProperties);
+    this.set('content.serviceConfigProperties', serviceConfigProperties);
+  }
 })

Modified: incubator/ambari/trunk/ambari-web/app/controllers/wizard/stack_upgrade/step3_controller.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/controllers/wizard/stack_upgrade/step3_controller.js?rev=1465166&r1=1465165&r2=1465166&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/controllers/wizard/stack_upgrade/step3_controller.js (original)
+++ incubator/ambari/trunk/ambari-web/app/controllers/wizard/stack_upgrade/step3_controller.js Sat Apr  6 01:55:42 2013
@@ -23,63 +23,68 @@ App.StackUpgradeStep3Controller = Em.Con
 
   POLL_INTERVAL: 4000,
   isPolling: false,
-  isUpgradeStarted: false,
-  servicesOrder: [
-    'HDFS',
-    'MAPREDUCE',
-    'ZOOKEEPER',
-    'HBASE',
-    'HIVE',
-    'OOZIE',
-    'NAGIOS',
-    'GANGLIA',
-    'PIG',
-    'SQOOP'
+  /**
+   * STOP_SERVICES internal statuses:
+   * - PENDING
+   * - IN_PROGRESS
+   * - SUCCESS
+   * - FAILED
+   * UPGRADE_SERVICES internal statuses:
+   * - PENDING
+   * - IN_PROGRESS
+   * - SUCCESS
+   * - FAILED
+   * - WARNING
+   */
+  processes:[
+    Em.Object.create({
+      name: 'STOP_SERVICES',
+      displayName: Em.I18n.t('installer.stackUpgrade.step3.stop.header'),
+      progress:0,
+      status: 'PENDING',
+      message: null,
+      isRunning: false,
+      hosts: [],
+      isRetry: false
+    }),
+    Em.Object.create({
+      name: 'UPGRADE_SERVICES',
+      displayName: Em.I18n.t('installer.stackUpgrade.step3.upgrade.header'),
+      progress: 0,
+      status: 'PENDING',
+      message:'',
+      isRunning: false,
+      hosts: [],
+      isRetry: false
+    })
   ],
-
   /**
-   * overall status of Upgrade
-   * FAILED - some service is FAILED
-   * SUCCESS - every services are SUCCESS
-   * WARNING - some service is WARNING and all the rest are SUCCESS
-   * IN_PROGRESS - when all services is stopped
-   */
-  status: 'PENDING',
-  onStatus: function () {
-    var services = this.get('services');
-    var status = this.get('isServicesStopped') ? 'IN_PROGRESS' : 'PENDING';
-    var withoutWarning = [];
-    if (services.someProperty('status', 'FAILED')) {
-      this.set('isPolling', false);
-      status =  'FAILED';
-      this.setClusterStatus('STACK_UPGRADE_FAILED');
-    }
-    if (services.someProperty('status', 'WARNING')) {
-      withoutWarning = services.filter(function(service){
-        if(service.get('status') !== "WARNING"){
-          return true;
-        }
-      });
-      if(withoutWarning.everyProperty('status', 'SUCCESS')){
-        this.set('isPolling', false);
-        status = "WARNING";
-        this.setClusterStatus('STACK_UPGRADED');
-      }
-    }
-    if (services.everyProperty('status', 'SUCCESS')) {
-      this.set('isPolling', false);
-      status = 'SUCCESS';
-      this.set('content.cluster.isCompleted', true);
-      App.router.get(this.get('content.controllerName')).save('cluster');
-      this.setClusterStatus('STACK_UPGRADED');
-    }
-    this.set('status', status);
-  }.observes('services.@each.status'),
-  setClusterStatus: function(state){
+   * pass processes as services to popup
+   */
+  services: function(){
+    return this.get('processes');
+  }.property('processes'),
+  /**
+   * save current requestId and clusterState
+   * to localStorage and put it to server
+   *
+   * STOP_SERVICES cluster status:
+   * - STOPPING_SERVICES,
+   * UPGRADE_SERVICES cluster status:
+   * - STACK_UPGRADING,
+   * - STACK_UPGRADE_FAILED,
+   * - STACK_UPGRADED,
+   * - STACK_UPGRADE_COMPLETED
+   */
+  saveClusterStatus: function(clusterStatus){
+    var oldStatus = this.get('content.cluster');
+    clusterStatus = jQuery.extend(oldStatus, clusterStatus);
+    this.set('content.cluster', clusterStatus);
+    App.router.get(this.get('content.controllerName')).save('cluster');
     if(!App.testMode){
       App.clusterStatus.setClusterStatus({
         clusterName: this.get('content.cluster.name'),
-        clusterState: state,
+        clusterState: clusterStatus.status,
         wizardControllerName: 'stackUpgradeController',
         localdb: App.db.data
       });
@@ -88,267 +93,228 @@ App.StackUpgradeStep3Controller = Em.Con
   // provide binding for Host Popup data
   serviceTimestamp: null,
   /**
-   * The dependence of the status of service to status of the tasks
-   * FAILED - any task is TIMEDOUT, ABORTED, FAILED (depends on component is master)
-   * WARNING - any task is TIMEDOUT, ABORTED, FAILED (depends on component is slave or client)
-   * SUCCESS - every tasks are COMPLETED
-   * IN_PROGRESS - any task is UPGRADING(IN_PROGRESS)
-   * PENDING - every tasks are QUEUED or PENDING
-   */
-  services: [],
-  /**
-   * load services, which installed on cluster
-   */
-  loadServices: function(){
-    var installedServices = App.testMode ? this.get('mockServices') : this.get('content.servicesInfo');
-    var services = [];
-    var order = this.get('servicesOrder');
-    installedServices.sort(function(a, b){
-      return order.indexOf(a.get('serviceName')) - order.indexOf(b.get('serviceName'));
+   * load hosts for each process
+   */
+  loadHosts: function () {
+    var hosts = [];
+    var installedHosts = App.Host.find();
+    this.get('processes').forEach(function(process){
+      var hosts = [];
+      installedHosts.forEach(function (host) {
+        hosts.push(Em.Object.create({
+          name: host.get('hostName'),
+          publicName: host.get('publicHostName'),
+          logTasks: []
+        }));
+      });
+      process.set('hosts', hosts);
     });
-    installedServices.forEach(function(_service){
-      services.push(Em.Object.create({
-        name: _service.get('serviceName'),
-        displayName: _service.get('displayName'),
-        hosts: this.loadHosts(_service),
-        progress: 0,
-        message: function(){
-          switch(this.get('status')){
-            case "FAILED":
-              return Em.I18n.t('installer.stackUpgrade.step3.service.failedUpgrade').format(this.get('name'));
-              break;
-            case "WARNING":
-              return Em.I18n.t('installer.stackUpgrade.step3.service.upgraded').format(this.get('name'));
-              break;
-            case "SUCCESS":
-              return Em.I18n.t('installer.stackUpgrade.step3.service.upgraded').format(this.get('name'));
-              break;
-            case "IN_PROGRESS":
-              return Em.I18n.t('installer.stackUpgrade.step3.service.upgrading').format(this.get('name'));
-              break;
-            case "PENDING":
-            default:
-              return Em.I18n.t('installer.stackUpgrade.step3.service.pending').format(this.get('name'));
-              break;
-          }
-        }.property('status'),
-        status: "PENDING",
-        detailMessage:''
-      }));
-    }, this);
-    this.set('services', services);
   }.observes('content.servicesInfo'),
+  submitButton: null,
   /**
-   * load hosts as services property
-   * @param service
-   * @return {Array}
-   */
-  loadHosts: function(service){
-    var hostComponents = App.HostComponent.find().filterProperty('service.serviceName', service.get('serviceName'));
-    var hosts = hostComponents.mapProperty('host').uniq();
-    var result = [];
-    hosts.forEach(function(host){
-      result.push(Em.Object.create({
-        name: host.get('hostName'),
-        publicName: host.get('publicHostName'),
-        logTasks: [],
-        components: hostComponents.filterProperty('host.hostName', host.get('hostName')).mapProperty('componentName')
-      }));
-    });
-    return result;
-  },
-  /**
-   * upgrade status SUCCESS - submit button enabled with label "Done"
-   * upgrade status WARNING - submit button enabled with label "Proceed with Warning"
-   * upgrade status FAILED or IN_PROGRESS - submit button disabled
-   */
-  submitButton: function(){
-    if(this.get('status') == 'SUCCESS'){
-      return Em.I18n.t('common.done');
-    } else if(this.get('status') == 'WARNING'){
-      return Em.I18n.t('installer.stackUpgrade.step3.ProceedWithWarning');
+   * restart upgrade
+   * restart stop services
+   * @param event
+   */
+  retry: function(event){
+    var processName = event.context;
+    var process = this.get('processes').findProperty('name', processName);
+    this.resetProgress(process);
+    this.resetMockConfig();
+    if(processName == 'STOP_SERVICES'){
+      this.stopServices();
     } else {
-      return false;
+      this.set('submitButton', false);
+      this.runUpgrade();
     }
-  }.property('status'),
-  showRetry: function () {
-    return (this.get('status') === 'FAILED' || this.get('status') === 'WARNING');
-  }.property('status'),
-  isServicesStopped: function(){
-    return this.get('servicesStopProgress') === 100;
-  }.property('servicesStopProgress'),
-  isServicesStopFailed: function(){
-    return this.get('servicesStopProgress') === false;
-  }.property('servicesStopProgress'),
-  installedServices: App.Service.find(),
+  },
   /**
-   * progress of stopping services process
-   * check whether service stop fails
+   * reset progress and status to retry
+   * @param process
    */
-  servicesStopProgress: function(){
-    var services = App.testMode ? this.get('mockServices') : this.get('installedServices').toArray();
-    var progress = 0;
-    var stopFailed = false;
-    services.forEach(function(service){
-      if(!stopFailed){
-        stopFailed = service.get('hostComponents').filterProperty('isMaster').someProperty('workStatus', 'STOP_FAILED');
-      }
-    });
-    if(stopFailed){
-      return false;
-    } else {
-      progress = (services.filterProperty('workStatus', 'STOPPING').length / services.length) * 0.2;
-      return Math.round((progress + services.filterProperty('workStatus', 'INSTALLED').length / services.length) * 100);
-    }
-  }.property('installedServices.@each.workStatus', 'mockServices.@each.workStatus'),
-  retryStopService: function(){
-    App.router.get(this.get('content.controllerName')).stopServices();
+  resetProgress: function(process){
+    process.set('isRetry', false);
+    process.set('status', 'PENDING');
+    process.set('progress', 0);
+    process.get('hosts').forEach(function(host){host.get('logTasks').clear()});
   },
   /**
-   * restart upgrade if fail or warning occurred
-   * @param event
+   * run stop services
    */
-  retry: function(event){
-    this.set('isUpgradeStarted', false);
-    this.resetMockConfig(true);
-    this.loadServices();
-    this.runUpgrade();
+  stopServices: function () {
+    var clusterName = this.get('content.cluster.name');
+    var url = App.apiPrefix + '/clusters/' + clusterName + '/services?ServiceInfo/state=STARTED';
+    var data = '{"RequestInfo": {"context": "'+ Em.I18n.t("requestInfo.stopAllServices") +'"}, "Body": {"ServiceInfo": {"state": "INSTALLED"}}}';
+    var method = 'PUT';
+    var process = this.get('processes').findProperty('name', 'STOP_SERVICES');
+    var self = this;
+    process.set('isRunning', true);
+    if (App.testMode) {
+      this.startPolling();
+      this.saveClusterStatus({
+        requestId: 1,
+        status: 'STOPPING_SERVICES',
+        isCompleted: false
+      });
+    } else {
+      $.ajax({
+        type: method,
+        url: url,
+        async: false,
+        data: data,
+        dataType: 'text',
+        timeout: App.timeout,
+        success: function (data) {
+          var requestId = jQuery.parseJSON(data).Requests.id;
+          var clusterStatus = {
+            requestId: requestId,
+            status: 'STOPPING_SERVICES',
+            isCompleted: false
+          };
+          process.set('status', 'IN_PROGRESS');
+          self.saveClusterStatus(clusterStatus);
+          self.startPolling();
+          console.log('Call to stop service successful')
+        },
+        error: function () {
+          self.finishProcess(process, 'FAILED');
+          process.set('status', 'FAILED');
+          console.log("Call to stop services failed");
+        },
+        statusCode: require('data/statusCodes')
+      });
+    }
   },
   /**
    * send request to run upgrade all services
    */
-  runUpgrade: function(){
-    // call to run upgrade on server
-    var method = App.testMode ? "GET" : "PUT";
-    var url = '';
-    var data = '';
+  runUpgrade: function () {
+    var method = "PUT";
+    var url = App.apiPrefix + '/clusters/' + this.get('content.cluster.name');
     var self = this;
-    if(this.get('isServicesStopped') && !this.get('isUpgradeStarted')){
-      //TODO remove assignment isUpgradeStarted true to Ajax success callback
-      this.set('isUpgradeStarted', true);
-      /* $.ajax({
-       type: method,
-       url: url,
-       data: data,
-       async: false,
-       dataType: 'text',
-       timeout: App.timeout,
-       success: function (data) {
-
-       },
-
-       error: function (request, ajaxOptions, error) {
-
-       },
-
-       statusCode: require('data/statusCodes')
-       });*/
-      /*App.clusterStatus.setClusterStatus({
-       clusterName: this.get('clusterName'),
-       clusterState: 'UPGRADING_STACK',
-       wizardControllerName: 'stackUpgradeController',
-       localdb: App.db.data
-       });*/
+    var data = '{"Clusters": {"version" : "' + this.get('content.upgradeVersion') + '"}}';
+    var process = this.get('processes').findProperty('name', 'UPGRADE_SERVICES');
+    process.set('isRunning', true);
+    if (App.testMode) {
       this.startPolling();
+      this.saveClusterStatus({
+        requestId: 1,
+        status: 'STACK_UPGRADING',
+        isCompleted: false
+      });
+    } else {
+      $.ajax({
+        type: method,
+        url: url,
+        async: false,
+        data: data,
+        dataType: 'text',
+        timeout: App.timeout,
+        success: function (data) {
+          var jsonData = jQuery.parseJSON(data);
+          var requestId = jsonData.Requests.id;
+          var clusterStatus = {
+            status: 'STACK_UPGRADING',
+            requestId: requestId,
+            isCompleted: false
+          };
+          process.set('status', 'IN_PROGRESS');
+          self.saveClusterStatus(clusterStatus);
+          self.startPolling();
+        },
+        error: function (request, ajaxOptions, error) {
+          self.finishProcess(process, 'FAILED');
+          process.set('status', 'FAILED');
+        },
+        statusCode: require('data/statusCodes')
+      });
     }
-  }.observes('isServicesStopped'),
+  },
   /**
-   * start polling on upgrade progress
+   * start polling tasks for current process
    */
   startPolling: function(){
-    //TODO set actual URL to poll upgrade progress
-    var url = '';
     if(!this.get('isPolling')){
       this.set('isPolling', true);
       if (App.testMode) {
         this.simulatePolling();
       } else {
         //pass an interval "1" to start poll immediately first time
-        this.doPoll(url, 1);
+        this.doPoll(1);
       }
     }
   },
-
-  mockServices: [
-    Em.Object.create({
-      serviceName: 'GANGLIA',
-      displayName: 'Ganglia',
-      workStatus: 'STARTED',
-      hostComponents: []
-    }),
-    Em.Object.create({
-      serviceName: 'HDFS',
-      displayName: 'HDFS',
-      workStatus: 'STARTED',
-      hostComponents: []
-    })
-  ],
   simulateAttempt:0,
+  mockUrl:'',
   /**
    * simulate actual poll, using mock data
    */
   simulatePolling: function(){
     var simulateAttempt = this.get('simulateAttempt');
-    var URLs = [
+    var process = this.get('processes').findProperty('isRunning', true);
+    var upgradeURLs = [
       '/data/wizard/upgrade/poll_1.json',
       '/data/wizard/upgrade/poll_2.json',
       '/data/wizard/upgrade/poll_3.json',
       '/data/wizard/upgrade/poll_4.json',
       '/data/wizard/upgrade/poll_5.json'
     ];
-    if(simulateAttempt < 5){
-      this.doPoll(URLs[simulateAttempt]);
-      this.set('simulateAttempt', ++simulateAttempt);
+    var stopURLs = [
+      '/data/wizard/stop_services/poll_1.json',
+      '/data/wizard/stop_services/poll_2.json',
+      '/data/wizard/stop_services/poll_3.json',
+      '/data/wizard/stop_services/poll_4.json'
+    ];
+    if(process.get('name') == 'STOP_SERVICES'){
+      if(simulateAttempt < 4){
+        this.set('mockUrl', stopURLs[simulateAttempt]);
+        this.doPoll();
+        this.set('simulateAttempt', ++simulateAttempt);
+      }
+    } else {
+      if(simulateAttempt < 5){
+        this.set('mockUrl', upgradeURLs[simulateAttempt]);
+        this.doPoll();
+        this.set('simulateAttempt', ++simulateAttempt);
+      }
     }
   },
-  /**
-   * simulate stopping services before upgrade,
-   * using mockServices data
-   */
-  simulateStopService: function(){
-    var services = this.get('mockServices');
-    var self = this;
-    setTimeout(function(){
-      services[0].set('workStatus', 'STOPPING');
-    }, 4000);
-    setTimeout(function(){
-      services[0].set('workStatus', 'INSTALLED');
-    }, 8000);
-    setTimeout(function(){
-      services[1].set('workStatus', 'STOPPING');
-    }, 12000);
-    setTimeout(function(){
-      services[1].set('workStatus', 'INSTALLED');
-      services.setEach('workStatus', 'INSTALLED');
-    }, 16000);
+  getUrl:function(){
+    var requestId = this.get('content.cluster.requestId');
+    var clusterName = this.get('content.cluster.name');
+    if(App.testMode){
+      return this.get('mockUrl');
+    }
+    return App.apiPrefix + '/clusters/' + clusterName + '/requests/' + requestId + '?fields=tasks/*';
   },
-
   /**
-   * poll server for tasks, which contain upgrade progress data
-   * @param url
+   * poll server for tasks, which contain process progress data
    * @param interval
    */
-  doPoll: function(url, interval){
+  doPoll: function(interval){
+    var url = this.getUrl();
     var self = this;
     var pollInterval = interval || self.POLL_INTERVAL;
     if (self.get('isPolling')) {
       setTimeout(function () {
         $.ajax({
-          utype: 'GET',
+          type: 'GET',
           url: url,
           async: true,
           timeout: App.timeout,
           dataType: 'json',
           success: function (data) {
             var result = self.parseTasks(data);
-            if (App.testMode) {
-              self.simulatePolling();
-            } else {
-              self.doPoll(url);
+            if(result){
+              if (App.testMode) {
+                self.simulatePolling();
+              } else {
+                self.doPoll();
+              }
             }
           },
           error: function () {
-
+            console.log('ERROR: poll request failed')
           },
           statusCode: require('data/statusCodes')
         }).retry({times: App.maxRetries, timeout: App.timeout}).then(null,
@@ -368,114 +334,139 @@ App.StackUpgradeStep3Controller = Em.Con
    */
   parseTasks: function(data){
     var tasks = data.tasks || [];
-    this.get('services').forEach(function (service) {
-      var hosts = service.get('hosts');
-      var tasksPerService = [];
-      if(hosts.length){
-        hosts.forEach(function (host) {
-          var tasksPerHost = tasks.filter(function(task){
-            if(task.Tasks.host_name == host.name && host.get('components').contains(task.Tasks.role)){
-              return true;
-            }
-          });
-          if (tasksPerHost.length) {
-            this.setLogTasksStatePerHost(tasksPerHost, host);
-            tasksPerService = tasksPerService.concat(tasksPerHost);
-          }
-        }, this);
-        this.progressOnService(service, tasksPerService);
-        this.statusOnService(service, tasksPerService);
-      } else {
-        service.set('status', 'PENDING');
-        service.set('detailedMessage', Em.I18n.t('installer.stackUpgrade.step3.host.nothingToUpgrade'));
-        console.log('None tasks matched to service ' + service);
-      }
-    }, this);
+    var process = this.get('processes').findProperty('isRunning', true);
+    // if process was finished then it terminates next poll
+    var continuePolling = true;
+
+    this.progressOnProcess(tasks, process);
+    continuePolling = this.statusOnProcess(tasks, process);
+    if(process.get('hosts').length && tasks.length){
+      process.get('hosts').forEach(function (host) {
+        var tasksPerHost = tasks.filterProperty('Tasks.host_name', host.name);
+        if (tasksPerHost.length) {
+          this.setLogTasksStatePerHost(tasksPerHost, host);
+        }
+      }, this);
+    }
     this.set('serviceTimestamp', new Date().getTime());
-    return true;
+    return continuePolling;
+  },
+  /**
+   * calculate progress according to tasks status
+   * @param actions
+   * @param process
+   */
+  progressOnProcess: function(actions, process){
+    var progress = 0;
+    var actionsNumber = actions.length;
+    var completedActions = actions.filterProperty('Tasks.status', 'COMPLETED').length
+      + actions.filterProperty('Tasks.status', 'FAILED').length
+      + actions.filterProperty('Tasks.status', 'ABORTED').length
+      + actions.filterProperty('Tasks.status', 'TIMEDOUT').length;
+    var queuedActions = actions.filterProperty('Tasks.status', 'QUEUED').length;
+    var inProgressActions = actions.filterProperty('Tasks.status', 'IN_PROGRESS').length;
+    progress = Math.ceil(((queuedActions * 0.09) + (inProgressActions * 0.35) + completedActions ) / actionsNumber * 100);
+    console.log('INFO: progress is: ' + progress);
+    process.set('progress', progress);
   },
   /**
-   * evaluate status of service depending on the tasks
-   * also set detailMessage that show currently running process
-   * @param service
+   * evaluate status of process according to task status
    * @param actions
+   * @param process
    */
-  statusOnService: function(service, actions){
-    var status;
-    var errorActions = actions.filter(function(action){
-      if(action.Tasks.status == 'FAILED' || action.Tasks.status == 'ABORTED' || action.Tasks.status == 'TIMEDOUT'){
+  statusOnProcess: function(actions, process){
+    var status = null;
+    var message = '';
+    var continuePolling = true;
+    var errorActions = actions.filter(function (action) {
+      if (action.Tasks.status == 'FAILED' || action.Tasks.status == 'ABORTED' || action.Tasks.status == 'TIMEDOUT') {
         return true;
       }
     });
     var masterComponents = ['NAMENODE', 'SECONDARY_NAMENODE', 'SNAMENODE', 'JOBTRACKER', 'ZOOKEEPER_SERVER', 'HIVE_SERVER',
-      'HIVE_METASTORE', 'MYSQL_SERVER', 'HBASE_MASTER', 'NAGIOS_SERVER', 'GANGLIA_SERVER', 'OOZIE_SERVER','WEBHCAT_SERVER'];
+      'HIVE_METASTORE', 'MYSQL_SERVER', 'HBASE_MASTER', 'NAGIOS_SERVER', 'GANGLIA_SERVER', 'OOZIE_SERVER', 'WEBHCAT_SERVER'];
     var failedComponents = errorActions.mapProperty('Tasks.role');
-    if(failedComponents.length){
-      for(var i = 0; i < failedComponents.length; i++){
-        if(masterComponents.contains(failedComponents[i])){
+    if (failedComponents.length) {
+      for (var i = 0; i < failedComponents.length; i++) {
+        if (masterComponents.contains(failedComponents[i])) {
           status = "FAILED";
+          continuePolling = false;
+          this.finishProcess(process, status);
           break;
-        } else {
+        } else if(process.get('progress') == 100){
           status = "WARNING";
+          if(process.get('name') == 'UPGRADE_SERVICES'){
+            continuePolling = false;
+            this.finishProcess(process, status);
+          }
         }
       }
-    } else if(actions.everyProperty('Tasks.status', 'COMPLETED')){
-      status = 'SUCCESS';
-    } else {
-      var activeAction = actions.findProperty('Tasks.status', 'UPGRADING');
-      status = 'IN_PROGRESS';
-      if (activeAction === undefined || activeAction === null) {
-        activeAction = actions.findProperty('Tasks.status', 'QUEUED');
-        status = 'PENDING';
-      }
-      if (activeAction === undefined || activeAction === null) {
-        activeAction = actions.findProperty('Tasks.status', 'PENDING');
-        status = 'PENDING';
+    }
+    if(!status || ((status == 'WARNING') && (process.get('name') == 'STOP_SERVICES'))){
+      if (actions.everyProperty('Tasks.status', 'COMPLETED')) {
+        status = 'SUCCESS';
+        continuePolling = false;
+        this.finishProcess(process, status);
+      } else {
+        var activeAction = actions.findProperty('Tasks.status', 'IN_PROGRESS');
+        status = 'IN_PROGRESS';
+        if (activeAction === undefined || activeAction === null) {
+          activeAction = actions.findProperty('Tasks.status', 'QUEUED');
+          status = 'PENDING';
+        }
+        if (activeAction === undefined || activeAction === null) {
+          activeAction = actions.findProperty('Tasks.status', 'PENDING');
+          status = 'PENDING';
+        }
+        if (activeAction) {
+          message = this.displayMessage(activeAction.Tasks);
+        }
       }
-      if(activeAction){
-        service.set('detailMessage', this.displayMessage(activeAction.Tasks));
+    }
+    console.log('INFO: status is: ' + status);
+    process.set('status', status);
+    process.set('message', message);
+    return continuePolling;
+  },
+  /**
+   * complete process phase
+   * accept FAILED, SUCCESS, WARNING process status
+   * @param process
+   * @param status
+   */
+  finishProcess: function(process, status){
+    this.set('isPolling', false);
+    if(process.get('name') == 'STOP_SERVICES'){
+      if(status == 'SUCCESS'){
+        process.set('isRunning', false);
+        this.resetMockConfig();
+        this.runUpgrade();
+      } else {
+        process.set('isRetry', true);
       }
     }
-    service.set('status', status);
-  },
-  /**
-   * calculate progress of service depending on the tasks
-   * @param service
-   * @param actions
-   */
-  progressOnService: function(service, actions){
-    var progress = 0;
-    var actionsNumber = actions.length;
-    var completedActions = actions.filterProperty('Tasks.status', 'COMPLETED').length
-      + actions.filterProperty('Tasks.status', 'FAILED').length
-      + actions.filterProperty('Tasks.status', 'ABORTED').length
-      + actions.filterProperty('Tasks.status', 'TIMEDOUT').length;
-    var queuedActions = actions.filterProperty('Tasks.status', 'QUEUED').length;
-    var inProgressActions = actions.filterProperty('Tasks.status', 'UPGRADING').length;
-    progress = Math.ceil(((queuedActions * 0.09) + (inProgressActions * 0.35) + completedActions ) / actionsNumber * 100);
-    console.log('INFO: progressPerService is: ' + progress);
-    service.set('progress', progress);
-  },
-  /**
-   * determine description of current running process
-   * @param task
-   * @return {*}
-   */
-  displayMessage: function (task) {
-    var role = App.format.role(task.role);
-    // accept only default command - "UPGRADE"
-    console.log("In display message with task command value: " + task.command);
-    switch (task.status) {
-      case 'PENDING':
-        return Em.I18n.t('installer.step9.serviceStatus.upgrade.pending') + role;
-      case 'QUEUED' :
-        return Em.I18n.t('installer.step9.serviceStatus.upgrade.queued') + role;
-      case 'UPGRADING':
-        return Em.I18n.t('installer.step9.serviceStatus.upgrade.inProgress') + role;
-      case 'COMPLETED' :
-        return Em.I18n.t('installer.step9.serviceStatus.upgrade.completed') + role;
-      case 'FAILED':
-        return Em.I18n.t('installer.step9.serviceStatus.upgrade.failed') + role;
+    if(process.get('name') == 'UPGRADE_SERVICES'){
+      if(status == 'SUCCESS'){
+        this.set('submitButton', Em.I18n.t('common.done'));
+        this.saveClusterStatus({
+          status: 'STACK_UPGRADED',
+          isCompleted: true
+        })
+      } else if(status == 'FAILED') {
+        process.set('isRetry', true);
+        this.set('submitButton', false);
+        this.saveClusterStatus({
+          status: 'STACK_UPGRADE_FAILED',
+          isCompleted: false
+        })
+      } else if(status == 'WARNING'){
+        this.set('submitButton', Em.I18n.t('installer.stackUpgrade.step3.ProceedWithWarning'));
+        process.set('isRetry', true);
+        this.saveClusterStatus({
+          status: 'STACK_UPGRADED',
+          isCompleted: true
+        })
+      }
     }
   },
   /**
@@ -496,57 +487,87 @@ App.StackUpgradeStep3Controller = Em.Con
     }, this);
   },
   /**
-   * clear config and data after completion of upgrade
-   */
-  clearStep: function(){
-    this.get('services').clear();
-    this.set('isUpgradeStarted', false);
-    this.resetMockConfig(false);
-  },
-  /**
    * reset mock configs to run upgrade simulation again
    */
   resetMockConfig: function(retry){
-    if(!retry){
-      this.get('mockServices').setEach('workStatus', 'STARTED');
-    }
     this.set('simulateAttempt', 0);
   },
   /**
-   * navigate to show current process depending on cluster status
+   * resume wizard on last operation
    */
-  navigateStep: function(){
+  resumeStep: function () {
     var clusterStatus = this.get('content.cluster.status');
-    var status = 'PENDING';
-    if (this.get('content.cluster.isCompleted') === false) {
-      if (this.get('isServicesStopped')){
+    var upgrade = this.get('processes').findProperty('name', 'UPGRADE_SERVICES');
+    var stop = this.get('processes').findProperty('name', 'STOP_SERVICES');
+    if(App.testMode){
+      if(this.get('processes').everyProperty('isRunning', false)){
+        stop.set('isRunning', true);
+      }
+      clusterStatus = (this.get('processes').findProperty('name', 'UPGRADE_SERVICES').get('isRunning'))?
+       'STACK_UPGRADING':
+       'STOPPING_SERVICES';
+      upgrade.set('isRetry', false);
+      stop.set('isRetry', false);
+    }
+    if (clusterStatus == 'STOPPING_SERVICES') {
+      this.startPolling();
+      stop.set('isRunning', true);
+      upgrade.set('isRunning', false);
+    } else if(clusterStatus != 'PENDING'){
+      stop.set('status', 'SUCCESS');
+      stop.set('progress', 100);
+      stop.set('isRunning', false);
+      upgrade.set('isRunning', true);
+      if (clusterStatus == 'STACK_UPGRADING') {
+        upgrade.set('status', 'IN_PROGRESS');
         this.startPolling();
-        if (clusterStatus === 'STACK_UPGRADING'){
-          // IN_PROGRESS
-          status = 'IN_PROGRESS';
-        } else if (clusterStatus === 'STACK_UPGRADE_FAILED'){
-          // FAILED
-          status = 'FAILED';
-          // poll only one time
-          this.set('isPolling', false);
-        } else {
-          // WARNING
-          status = 'WARNING';
-          // poll only one time
-          this.set('isPolling', false);
-        }
-      } else {
-        // services are stopping yet
+      } else if (clusterStatus == 'STACK_UPGRADE_FAILED') {
+        upgrade.set('status', 'FAILED');
+        upgrade.set('isRetry', true);
+      } else if (clusterStatus == 'STACK_UPGRADED') {
+        upgrade.set('status', 'SUCCESS');
+        upgrade.set('progress', 100);
+        this.startPolling();
+        this.set('isPolling', false);
       }
-    } else {
-      status = 'SUCCESS';
     }
-    if (App.testMode) {
-      if(!this.get('isServicesStopped')){
-        this.simulateStopService();
-      }
-    } else {
-      this.set('status', status);
+  },
+  /**
+   * determine description of current running process
+   * @param task
+   * @return {*}
+   */
+  displayMessage: function (task) {
+    var role = App.format.role(task.role);
+    console.log("In display message with task command value: " + task.command);
+    switch (task.command){
+      case 'UPGRADE':
+        switch (task.status) {
+          case 'PENDING':
+            return Em.I18n.t('installer.step9.serviceStatus.upgrade.pending') + role;
+          case 'QUEUED' :
+            return Em.I18n.t('installer.step9.serviceStatus.upgrade.queued') + role;
+          case 'IN_PROGRESS':
+            return Em.I18n.t('installer.step9.serviceStatus.upgrade.inProgress') + role;
+          case 'COMPLETED' :
+            return Em.I18n.t('installer.step9.serviceStatus.upgrade.completed') + role;
+          case 'FAILED':
+            return Em.I18n.t('installer.step9.serviceStatus.upgrade.failed') + role;
+        }
+        break;
+      case 'STOP' :
+        switch (task.status) {
+          case 'PENDING':
+            return Em.I18n.t('installer.step9.serviceStatus.stop.pending') + role;
+          case 'QUEUED' :
+            return Em.I18n.t('installer.step9.serviceStatus.stop.queued') + role;
+          case 'IN_PROGRESS':
+            return Em.I18n.t('installer.step9.serviceStatus.stop.inProgress') + role;
+          case 'COMPLETED' :
+            return role + Em.I18n.t('installer.step9.serviceStatus.stop.completed');
+          case 'FAILED':
+            return role + Em.I18n.t('installer.step9.serviceStatus.stop.failed');
+        }
     }
   }
 });
\ No newline at end of file

Modified: incubator/ambari/trunk/ambari-web/app/controllers/wizard/step14_controller.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/controllers/wizard/step14_controller.js?rev=1465166&r1=1465165&r2=1465166&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/controllers/wizard/step14_controller.js (original)
+++ incubator/ambari/trunk/ambari-web/app/controllers/wizard/step14_controller.js Sat Apr  6 01:55:42 2013
@@ -20,15 +20,31 @@ var App = require('app');
 
 App.WizardStep14Controller = Em.Controller.extend({
 
-  status: function () {
+  status: 'IN_PROGRESS',
+
+  onStatusChange: function () {
     if (this.get('tasks').someProperty('status', 'FAILED')) {
-      return 'FAILED';
-    }
-    if (this.get('tasks').everyProperty('status', 'COMPLETED')) {
-      return 'COMPLETED';
+      this.set('status', 'FAILED');
+      if (this.get('tasks')[5].status == 'FAILED' || this.get('tasks')[6].status == 'FAILED') {
+        this.set('showRetry', true);
+      }
+    } else if (this.get('tasks').everyProperty('status', 'COMPLETED')) {
+      this.set('status', 'COMPLETED');
+      this.set('isSubmitDisabled', false);
+    } else {
+      this.set('status', 'IN_PROGRESS')
     }
-    return 'IN_PROGRESS';
-  }.property('tasks.@each.status'),
+    var statuses = this.get('tasks').mapProperty('status');
+    App.router.get(this.get('content.controllerName')).saveTasksStatuses(statuses);
+    App.clusterStatus.setClusterStatus({
+      clusterName: this.get('content.cluster.name'),
+      clusterState: 'REASSIGN_MASTER_INSTALLING',
+      wizardControllerName: this.get('content.controllerName'),
+      localdb: App.db.data
+    });
+    this.setTasksMessages();
+    this.navigateStep();
+  },
 
   tasks: [],
 
@@ -38,6 +54,10 @@ App.WizardStep14Controller = Em.Controll
   setTasksMessages: function () {
     var service = this.get('service.displayName');
     var master = this.get('masterComponent.display_name');
+    if (this.get('isCohosted')) {
+      service = 'Hive, WebHCat';
+      master = Em.I18n.t('installer.step5.hiveGroup');
+    }
     for (i = 0; i < this.get('tasks').length; i++) {
       var status = this.get('tasks')[i].status.toLowerCase().replace('initialize', 'pending').replace('_', ' ');
       if (i == 0 || i == 6) {
@@ -46,18 +66,20 @@ App.WizardStep14Controller = Em.Controll
         this.get('tasks')[i].set('message', Em.I18n.t('installer.step14.task' + i).format(master) + ' ' + status);
       }
     }
-  }.observes('tasks.@each.status'),
+  },
 
   configs: [],
   globals: [],
-  configMapping: require('data/config_mapping'),
+  configMapping: require('data/config_mapping').all(),
   newConfigsTag: null,
   createdConfigs: [],
 
-  currentRequestId: null,
+  currentRequestId: [],
 
   isSubmitDisabled: true,
 
+  showRetry: false,
+
   service: function () {
     return App.Service.find().findProperty('serviceName', this.get('masterComponent.service_id'));
   }.property('masterComponent'),
@@ -66,13 +88,20 @@ App.WizardStep14Controller = Em.Controll
     return this.get('content.reassign');
   }.property('content.reassign'),
 
+  isCohosted: function () {
+    return this.get('masterComponent.component_name') == 'HIVE_SERVER';
+  }.property('masterComponent'),
+
   loadStep: function () {
     this.clearStep();
     this.loadTasks();
-    this.navigateStep();
+    this.addObserver('tasks.@each.status', this, 'onStatusChange');
+    this.onStatusChange();
   },
 
   clearStep: function () {
+    this.removeObserver('tasks.@each.status', this, 'onStatusChange');
+    this.removeObserver('createdConfigs.length', this, 'onCreateConfigsCompleted');
     var tasks = [];
     for (var i = 0; i < 8; i++) {
       tasks.pushObject(Ember.Object.create({
@@ -83,6 +112,10 @@ App.WizardStep14Controller = Em.Controll
       }));
     }
     this.set('tasks', tasks);
+    this.set('createdConfigsCount', 0);
+    this.set('queueTasksCompleted', 0);
+    this.set('dataPollCounter', 1);
+    this.set('showRetry', false);
     this.set('isSubmitDisabled', true);
     this.get('configs').clear();
     this.get('globals').clear();
@@ -90,7 +123,17 @@ App.WizardStep14Controller = Em.Controll
   },
 
   loadTasks: function () {
-
+    var statuses = this.get('content.tasksStatuses');
+    if (statuses) {
+      statuses.forEach(function (status, index) {
+        this.get('tasks')[index].status = status;
+      }, this)
+    }
+    var statusesForRequestId = ['PENDING', 'QUEUED', 'IN_PROGRESS'];
+    if (statusesForRequestId.contains(statuses[0]) || statusesForRequestId.contains(statuses[5]) || statusesForRequestId.contains(statuses[6])) {
+      this.set('currentRequestId', this.get('content.cluster.requestId'));
+      this.getLogsByRequest();
+    }
   },
 
   /**
@@ -121,7 +164,7 @@ App.WizardStep14Controller = Em.Controll
     else if (this.taskIsReady(7)) {
       this.removeComponent();
     }
-  }.observes('tasks.@each.status'),
+  },
 
   /**
    * Determine preparedness to run task
@@ -129,151 +172,182 @@ App.WizardStep14Controller = Em.Controll
    * @return {Boolean}
    */
   taskIsReady: function (task) {
-    var startIndex = (task == 5) ? 0 : 1;
+    if (this.get('tasks')[task].status != 'INITIALIZE') {
+      return false;
+    }
+    var startIndex = (task == 4) ? 0 : 1;
     var tempArr = this.get('tasks').mapProperty('status').slice(startIndex, task).uniq();
-    return this.get('tasks')[task].status == 'INITIALIZE' && tempArr.length == 1 && tempArr[0] == 'COMPLETED';
+    return tempArr.length == 1 && tempArr[0] == 'COMPLETED';
   },
 
+  queueTasksCompleted: 0,
+
   /**
    * Change status of the task
    * @param task
    * @param status
    */
   setTasksStatus: function (task, status) {
-    this.get('tasks')[task].set('status', status);
+    if (status == 'COMPLETED' && this.get('isCohosted') && [1, 4, 7].contains(task) && this.get('queueTasksCompleted') < 2) {
+      this.set('queueTasksCompleted', this.get('queueTasksCompleted') + 1);
+    } else {
+      this.get('tasks')[task].set('status', status);
+    }
   },
 
-  stopService: function () {
-    var self = this;
-    var clusterName = this.get('content.cluster.name');
-    var serviceName = this.get('masterComponent.service_id');
-    var url = App.apiPrefix + '/clusters/' + clusterName + '/services/' + serviceName;
-    var data = '{"ServiceInfo": {"state": "INSTALLED"}}';
-    var method = 'PUT';
-    $.ajax({
-      type: method,
-      url: url,
-      data: data,
-      dataType: 'text',
-      timeout: App.timeout,
+  saveClusterStatus: function (requestId, status) {
+    var clusterStatus = {
+      status: status,
+      requestId: requestId
+    };
+    App.router.get(this.get('content.controllerName')).saveClusterStatus(clusterStatus);
+  },
 
-      beforeSend: function () {
-        self.setTasksStatus(0, 'PENDING');
-      },
+  stopService: function () {
+    this.set('currentRequestId', []);
+    var serviceNames = [this.get('masterComponent.service_id')];
+    if (this.get('isCohosted')) {
+      serviceNames = ['HIVE', 'WEBHCAT'];
+    }
+    serviceNames.forEach(function (serviceName) {
+      App.ajax.send({
+        name: 'reassign.stop_service',
+        sender: this,
+        data: {
+          serviceName: serviceName
+        },
+        beforeSend: 'onStopServiceBeforeSend',
+        success: 'onStopServiceSuccess',
+        error: 'onStopServiceError'
+      });
+    }, this);
+  },
 
-      success: function (data) {
-        if (jQuery.parseJSON(data)) {
-          self.set('currentRequestId', jQuery.parseJSON(data).Requests.id);
-          self.getLogsByRequest();
-        } else {
-          self.setTasksStatus(0, 'FAILED');
-        }
-      },
+  onStopServiceBeforeSend: function () {
+    this.setTasksStatus(0, 'PENDING');
+  },
 
-      error: function () {
-        self.setTasksStatus(0, 'FAILED');
-      },
+  onStopServiceSuccess: function (data) {
+    if (data) {
+      var requestId = data.Requests.id;
+      this.get('currentRequestId').push(requestId);
+      this.saveClusterStatus(this.get('currentRequestId'), 'PENDING');
+      if ((this.get('isCohosted') && this.get('currentRequestId.length') == 2) || !this.get('isCohosted')) {
+        this.getLogsByRequest();
+      }
+    } else {
+      this.setTasksStatus(0, 'FAILED');
+    }
+  },
 
-      statusCode: require('data/statusCodes')
-    });
+  onStopServiceError: function () {
+    this.setTasksStatus(0, 'FAILED');
   },
 
   createMasterComponent: function () {
-    var self = this;
-    var clusterName = this.get('content.cluster.name');
     var hostName = this.get('content.masterComponentHosts').findProperty('component', this.get('content.reassign.component_name')).hostName;
-    var componentName = this.get('masterComponent.component_name');
-    var url = App.apiPrefix + '/clusters/' + clusterName + '/hosts?Hosts/host_name=' + hostName;
-    var data = {
-      "host_components": [
-        {
-          "HostRoles": {
-            "component_name": componentName
-          }
-        }
-      ]
-    };
-    var method = 'POST';
-    $.ajax({
-      type: method,
-      url: url,
-      data: JSON.stringify(data),
-      dataType: 'text',
-      timeout: App.timeout,
-
-      beforeSend: function () {
-        self.setTasksStatus(1, 'PENDING');
-      },
-
-      success: function () {
-        self.setTasksStatus(1, 'COMPLETED');
-      },
+    var componentNames = [this.get('masterComponent.component_name')];
+    if (this.get('isCohosted')) {
+      this.set('queueTasksCompleted', 0);
+      componentNames = ['HIVE_SERVER', 'WEBHCAT_SERVER', 'MYSQL_SERVER'];
+    }
+    componentNames.forEach(function (componentName) {
+      if (App.testMode) {
+        this.setTasksStatus(1, 'COMPLETED');
+      } else {
+        App.ajax.send({
+          name: 'reassign.create_master',
+          sender: this,
+          data: {
+            hostName: hostName,
+            componentName: componentName
+          },
+          beforeSend: 'onCreateMasterComponentBeforeSend',
+          success: 'onCreateMasterComponentSuccess',
+          error: 'onCreateMasterComponentError'
+        });
+      }
+    }, this);
+  },
 
-      error: function () {
-        self.setTasksStatus(1, 'FAILED');
-      },
+  onCreateMasterComponentBeforeSend: function () {
+    this.setTasksStatus(1, 'PENDING');
+  },
 
-      statusCode: require('data/statusCodes')
-    });
+  onCreateMasterComponentSuccess: function () {
+    this.setTasksStatus(1, 'COMPLETED');
+  },
 
+  onCreateMasterComponentError: function () {
+    this.setTasksStatus(1, 'FAILED');
   },
 
   createConfigs: function () {
-    this.loadGlobals();
-    this.loadConfigs();
-    this.set('newConfigsTag', 'version' + (new Date).getTime());
-    var serviceName = this.get('service.serviceName');
-    this.createConfigSite(this.createGlobalSiteObj());
-    this.createConfigSite(this.createCoreSiteObj());
-    if (serviceName == 'HDFS') {
-      this.createConfigSite(this.createHdfsSiteObj());
-    }
-    if (serviceName == 'MAPREDUCE') {
-      this.createConfigSite(this.createMrSiteObj());
-    }
-    if (serviceName == 'HBASE') {
-      this.createConfigSite(this.createHbaseSiteObj());
-    }
-    if (serviceName == 'OOZIE') {
-      this.createConfigSite(this.createOozieSiteObj());
-    }
-    if (serviceName == 'HIVE') {
-      this.createConfigSite(this.createHiveSiteObj());
-    }
-    if (serviceName == 'WEBHCAT') {
-      this.createConfigSite(this.createWebHCatSiteObj());
-    }
-    if (this.get('tasks')[2].status !== 'FAILED') {
+    if (this.get('service.serviceName') == 'GANGLIA' || App.testMode) {
       this.setTasksStatus(2, 'COMPLETED');
+    } else {
+      this.setTasksStatus(2, 'PENDING');
+      this.loadGlobals();
+      this.loadConfigs();
+      this.set('newConfigsTag', 'version' + (new Date).getTime());
+      var serviceName = this.get('service.serviceName');
+      this.createConfigSite(this.createGlobalSiteObj());
+      this.createConfigSite(this.createCoreSiteObj());
+      if (serviceName == 'HDFS') {
+        this.createConfigSite(this.createSiteObj('hdfs-site'));
+      }
+      if (serviceName == 'MAPREDUCE') {
+        this.createConfigSite(this.createSiteObj('mapred-site'));
+      }
+      if (serviceName == 'HBASE') {
+        this.createConfigSite(this.createSiteObj('hbase-site'));
+      }
+      if (serviceName == 'OOZIE') {
+        this.createConfigSite(this.createSiteObj('oozie-site'));
+      }
+      if (serviceName == 'HIVE' || this.get('isCohosted')) {
+        this.createConfigSite(this.createSiteObj('hive-site'));
+      }
+      if (serviceName == 'WEBHCAT' || this.get('isCohosted')) {
+        this.createConfigSite(this.createSiteObj('webhcat-site'));
+      }
+      this.addObserver('createdConfigs.length', this, 'onCreateConfigsCompleted');
+      this.onCreateConfigsCompleted();
     }
   },
 
-  createConfigSite: function (data) {
-    var self = this;
-    data.tag = this.get('newConfigsTag');
-    var clusterName = this.get('content.cluster.name');
-    var url = App.apiPrefix + '/clusters/' + clusterName + '/configurations';
-    $.ajax({
-      type: 'POST',
-      url: url,
-      data: JSON.stringify(data),
-      dataType: 'text',
-      timeout: 5000,
+  createConfigSite: function (configs) {
+    configs.tag = this.get('newConfigsTag');
+    App.ajax.send({
+      name: 'reassign.create_configs',
+      sender: this,
+      data: {
+        configs: configs
+      },
+      beforeSend: 'onCreateConfigsBeforeSend',
+      success: 'onCreateConfigsSuccess',
+      error: 'onCreateConfigsError'
+    });
+  },
 
-      beforeSend: function () {
-        self.setTasksStatus(2, 'PENDING');
-      },
+  onCreateConfigsBeforeSend: function () {
+    this.set('createdConfigsCount', this.get('createdConfigsCount') + 1);
+  },
 
-      success: function () {
-        self.get('createdConfigs').push(data.type);
-      },
+  onCreateConfigsSuccess: function (data, opts) {
+    this.get('createdConfigs').pushObject(opts.configs.type);
+  },
 
-      error: function () {
-        self.setTasksStatus(2, 'FAILED');
-      },
+  onCreateConfigsError: function () {
+    this.setTasksStatus(2, 'FAILED');
+  },
 
-      statusCode: require('data/statusCodes')
-    });
+  createdConfigsCount: 0,
+
+  onCreateConfigsCompleted: function () {
+    if (this.get('createdConfigs.length') == this.get('createdConfigsCount')) {
+      this.setTasksStatus(2, 'COMPLETED');
+    }
   },
 
   loadGlobals: function () {
@@ -334,10 +408,8 @@ App.WizardStep14Controller = Em.Controll
       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;
         // Hack for templeton.zookeeper.hosts
         if (value !== null) {   // if the property depends on more than one template name like <templateName[0]>/<templateName[1]> then don't proceed to the next if the prior is null or not found in the global configs
@@ -357,12 +429,6 @@ App.WizardStep14Controller = Em.Controll
           }
         }
       } 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);
@@ -426,32 +492,6 @@ App.WizardStep14Controller = Em.Controll
     }
   },
 
-
-  /**
-   * 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) {
-          _keyValue = _keyValue.trim();
-          console.log("The value of the keyValue is: " + _keyValue);
-          // split on the first = encountered (the value may contain ='s)
-          var matches = _keyValue.match(/^([^=]+)=(.*)$/);
-          if (matches) {
-            var key = matches[1];
-            var value = matches[2];
-            if (key) {
-              this.setSiteProperty(key, value, _site.name + '.xml');
-            }
-          }
-        }, this);
-      }
-    }, this);
-  },
-
   /**
    * Set property of the site variable
    */
@@ -476,8 +516,6 @@ App.WizardStep14Controller = Em.Controll
         } 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", "properties": globalSiteProperties};
@@ -498,93 +536,39 @@ App.WizardStep14Controller = Em.Controll
       if ((isOozieSelected || (_coreSiteObj.name != 'hadoop.proxyuser.' + oozieUser + '.hosts' && _coreSiteObj.name != 'hadoop.proxyuser.' + oozieUser + '.groups')) && (isHiveSelected || (_coreSiteObj.name != 'hadoop.proxyuser.' + hiveUser + '.hosts' && _coreSiteObj.name != 'hadoop.proxyuser.' + hiveUser + '.groups')) && (isHcatSelected || (_coreSiteObj.name != 'hadoop.proxyuser.' + hcatUser + '.hosts' && _coreSiteObj.name != 'hadoop.proxyuser.' + hcatUser + '.groups'))) {
         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", "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", "properties": hdfsProperties };
-  },
-
-  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', properties: mrProperties};
-  },
-
-  createHbaseSiteObj: function () {
-    var configs = this.get('configs').filterProperty('filename', 'hbase-site.xml');
-    var hbaseProperties = {};
-    configs.forEach(function (_configProperty) {
-      hbaseProperties[_configProperty.name] = _configProperty.value;
-    }, this);
-    return {type: 'hbase-site', properties: hbaseProperties};
-  },
-
-  createOozieSiteObj: function () {
-    var configs = this.get('configs').filterProperty('filename', 'oozie-site.xml');
-    var oozieProperties = {};
-    configs.forEach(function (_configProperty) {
-      oozieProperties[_configProperty.name] = _configProperty.value;
-    }, this);
-    return {type: 'oozie-site', properties: oozieProperties};
-  },
-
-  createHiveSiteObj: function () {
-    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', properties: hiveProperties};
-  },
-
-  createWebHCatSiteObj: function () {
-    var configs = this.get('configs').filterProperty('filename', 'webhcat-site.xml');
-    var webHCatProperties = {};
+  createSiteObj: function (name) {
+    var fileName = name + '.xml';
+    var configs = this.get('configs').filterProperty('filename', fileName);
+    var properties = {};
     configs.forEach(function (_configProperty) {
-      webHCatProperties[_configProperty.name] = _configProperty.value;
+      properties[_configProperty.name] = _configProperty.value;
     }, this);
-    return {type: 'webhcat-site', properties: webHCatProperties};
+    return {type: name, properties: properties};
   },
 
   applyConfigs: function () {
-    var self = this;
-    var configTags;
-    var clusterName = this.get('content.cluster.name');
-    var url = App.apiPrefix + '/clusters/' + clusterName + '/services/' + this.get('service.serviceName');
-    $.ajax({
-      type: 'GET',
-      url: url,
-      async: false,
-      timeout: 10000,
-      dataType: 'text',
-      success: function (data) {
-        var jsonData = jQuery.parseJSON(data);
-        configTags = jsonData.ServiceInfo.desired_configs;
-      },
-
-      error: function () {
-        self.setTasksStatus(3, 'FAILED');
-      },
-
-      statusCode: require('data/statusCodes')
-    });
+    if (this.get('service.serviceName') == 'GANGLIA' || App.testMode) {
+      this.setTasksStatus(3, 'COMPLETED');
+    } else {
+      var serviceName = this.get('service.serviceName');
+      App.ajax.send({
+        name: 'reassign.check_configs',
+        sender: this,
+        data: {
+          serviceName: serviceName
+        },
+        success: 'onCheckConfigsSuccess',
+        error: 'onCheckConfigsError'
+      });
+    }
+  },
 
+  onCheckConfigsSuccess: function (configs) {
+    var configTags = configs.ServiceInfo.desired_configs;
     if (!configTags) {
       this.setTasksStatus(0, 'FAILED');
       return;
@@ -596,100 +580,156 @@ App.WizardStep14Controller = Em.Controll
       }
     }
     var data = {config: configTags};
+    var serviceName = this.get('service.serviceName');
+    App.ajax.send({
+      name: 'reassign.apply_configs',
+      sender: this,
+      data: {
+        serviceName: serviceName,
+        configs: data
+      },
+      beforeSend: 'onApplyConfigsBeforeSend',
+      success: 'onApplyConfigsSuccess',
+      error: 'onApplyConfigsError'
+    });
+  },
 
-    $.ajax({
-      type: 'PUT',
-      url: url,
-      dataType: 'text',
-      data: JSON.stringify(data),
-      timeout: 5000,
-
-      beforeSend: function () {
-        self.setTasksStatus(3, 'PENDING');
-      },
+  onCheckConfigsError: function () {
+    this.setTasksStatus(3, 'FAILED');
+  },
 
-      success: function () {
-        self.setTasksStatus(3, 'COMPLETED');
-      },
+  onApplyConfigsBeforeSend: function () {
+    this.setTasksStatus(3, 'PENDING');
+  },
 
-      error: function () {
-        self.setTasksStatus(3, 'FAILED');
-      },
+  onApplyConfigsSuccess: function () {
+    this.setTasksStatus(3, 'COMPLETED');
+  },
 
-      statusCode: require('data/statusCodes')
-    });
+  onApplyConfigsError: function () {
+    this.setTasksStatus(3, 'FAILED');
   },
 
   putInMaintenanceMode: function () {
-    //todo after API providing
+    if (App.testMode) {
+      this.setTasksStatus(4, 'COMPLETED');
+    } else {
+      var hostName = this.get('content.reassign.host_id');
+      var componentNames = [this.get('masterComponent.component_name')];
+      if (this.get('isCohosted')) {
+        componentNames = ['HIVE_SERVER', 'WEBHCAT_SERVER', 'MYSQL_SERVER'];
+        this.set('queueTasksCompleted', 0);
+      }
+      componentNames.forEach(function (componentName) {
+        App.ajax.send({
+          name: 'reassign.maintenance_mode',
+          sender: this,
+          data: {
+            hostName: hostName,
+            componentName: componentName
+          },
+          beforeSend: 'onPutInMaintenanceModeBeforeSend',
+          success: 'onPutInMaintenanceModeSuccess',
+          error: 'onPutInMaintenanceModeError'
+        });
+      }, this);
+    }
+  },
+
+  onPutInMaintenanceModeBeforeSend: function () {
+    this.setTasksStatus(4, 'PENDING');
+  },
+
+  onPutInMaintenanceModeSuccess: function () {
     this.setTasksStatus(4, 'COMPLETED');
   },
 
-  installComponent: function () {
-    var self = this;
-    var clusterName = this.get('content.cluster.name');
-    var url = App.apiPrefix + '/clusters/' + clusterName + '/host_components?HostRoles/state=INIT';
-    var data = '{"HostRoles": {"state": "INSTALLED"}}';
-    var method = 'PUT';
-    $.ajax({
-      type: method,
-      url: url,
-      data: data,
-      dataType: 'text',
-      timeout: App.timeout,
+  onPutInMaintenanceModeError: function () {
+    this.setTasksStatus(4, 'FAILED');
+  },
 
-      beforeSend: function () {
-        self.setTasksStatus(5, 'PENDING');
-      },
+  installComponent: function () {
+    this.set('currentRequestId', []);
+    var componentNames = [this.get('masterComponent.component_name')];
+    if (this.get('isCohosted')) {
+      componentNames = ['HIVE_SERVER', 'WEBHCAT_SERVER', 'MYSQL_SERVER'];
+    }
+    var hostName = this.get('content.masterComponentHosts').findProperty('component', this.get('content.reassign.component_name')).hostName;
+    componentNames.forEach(function (componentName) {
+      App.ajax.send({
+        name: 'reassign.install_component',
+        sender: this,
+        data: {
+          hostName: hostName,
+          componentName: componentName
+        },
+        beforeSend: 'onInstallComponentBeforeSend',
+        success: 'onInstallComponentSuccess',
+        error: 'onInstallComponentError'
+      });
+    }, this);
+  },
 
-      success: function (data) {
-        if (jQuery.parseJSON(data)) {
-          self.set('currentRequestId', jQuery.parseJSON(data).Requests.id);
-          self.getLogsByRequest();
-        } else {
-          self.setTasksStatus(5, 'FAILED');
-        }
-      },
+  onInstallComponentBeforeSend: function () {
+    this.setTasksStatus(5, 'PENDING');
+  },
 
-      error: function () {
-        self.setTasksStatus(5, 'FAILED');
-      },
+  onInstallComponentSuccess: function (data) {
+    if (data) {
+      var requestId = data.Requests.id;
+      this.get('currentRequestId').push(requestId);
+      this.saveClusterStatus(this.get('currentRequestId'), 'PENDING');
+      if ((this.get('isCohosted') && this.get('currentRequestId.length') == 3) || !this.get('isCohosted')) {
+        this.getLogsByRequest();
+      }
+    } else {
+      this.setTasksStatus(5, 'FAILED');
+    }
+  },
 
-      statusCode: require('data/statusCodes')
-    });
+  onInstallComponentError: function () {
+    this.setTasksStatus(5, 'FAILED');
   },
 
   startComponents: function () {
-    var self = this;
-    var clusterName = this.get('content.cluster.name');
-    var serviceName = this.get('masterComponent.service_id');
-    var url = App.apiPrefix + '/clusters/' + clusterName + '/services/' + serviceName;
-    var data = '{"ServiceInfo": {"state": "STARTED"}}';
-    var method = 'PUT';
-    $.ajax({
-      type: method,
-      url: url,
-      data: data,
-      dataType: 'text',
-      timeout: App.timeout,
-
-      beforeSend: function () {
-        self.setTasksStatus(6, 'PENDING');
-      },
+    this.set('currentRequestId', []);
+    var serviceNames = [this.get('masterComponent.service_id')];
+    if (this.get('isCohosted')) {
+      serviceNames = ['HIVE', 'WEBHCAT'];
+    }
+    serviceNames.forEach(function (serviceName) {
+      App.ajax.send({
+        name: 'reassign.start_components',
+        sender: this,
+        data: {
+          serviceName: serviceName
+        },
+        beforeSend: 'onStartComponentsBeforeSend',
+        success: 'onStartComponentsSuccess',
+        error: 'onStartComponentsError'
+      });
+    }, this);
+  },
 
-      success: function (data) {
-        if (jQuery.parseJSON(data)) {
-          self.set('currentRequestId', jQuery.parseJSON(data).Requests.id);
-          self.getLogsByRequest();
-        }
-      },
+  onStartComponentsBeforeSend: function () {
+    this.setTasksStatus(6, 'PENDING');
+  },
 
-      error: function () {
-        self.setTasksStatus(6, 'FAILED');
-      },
+  onStartComponentsSuccess: function (data) {
+    if (data) {
+      var requestId = data.Requests.id;
+      this.get('currentRequestId').push(requestId);
+      this.saveClusterStatus(this.get('currentRequestId'), 'PENDING');
+      if ((this.get('isCohosted') && this.get('currentRequestId.length') == 2) || !this.get('isCohosted')) {
+        this.getLogsByRequest();
+      }
+    } else {
+      this.setTasksStatus(6, 'FAILED');
+    }
+  },
 
-      statusCode: require('data/statusCodes')
-    });
+  onStartComponentsError: function () {
+    this.setTasksStatus(6, 'FAILED');
   },
 
   /**
@@ -700,94 +740,222 @@ App.WizardStep14Controller = Em.Controll
     var self = this;
     var task;
     var stopPolling = false;
-    var starting = false;
-    var polledData = logs.tasks;
-    var status;
-    if ((this.get('tasks')[5].status != 'COMPLETED' && this.get('tasks')[6].status != 'COMPLETED' && this.get('tasks')[0].status != 'COMPLETED') ||
-        ((this.get('tasks')[5].status == 'COMPLETED') && this.get('tasks')[0].status == 'COMPLETED' && this.get('tasks')[6].status != 'COMPLETED')) {
-      //stopping or starting components
-      if (this.get('tasks')[0].status == 'COMPLETED') {
-        task = 6;
-        starting = true;
+    var polledData = [];
+    logs.forEach(function (item) {
+      polledData = polledData.concat(item.tasks);
+    }, this);
+    if (this.get('tasks')[0].status == 'COMPLETED') {
+      task = this.get('tasks')[5].status == 'COMPLETED' ? 6 : 5;
+    } else {
+      task = 0;
+    }
+    if (!polledData.someProperty('Tasks.status', 'PENDING') && !polledData.someProperty('Tasks.status', 'QUEUED') && !polledData.someProperty('Tasks.status', 'IN_PROGRESS')) {
+      if (polledData.someProperty('Tasks.status', 'FAILED')) {
+        this.setTasksStatus(task, 'FAILED');
       } else {
-        task = 0;
+        this.setTasksStatus(task, 'COMPLETED');
       }
-      if (!polledData.someProperty('Tasks.status', 'PENDING') && !polledData.someProperty('Tasks.status', 'QUEUED') && !polledData.someProperty('Tasks.status', 'IN_PROGRESS')) {
-        if (polledData.someProperty('Tasks.status', 'FAILED')) {
-          this.setTasksStatus(task, 'FAILED');
-          status = 'FAILED'
-        } else {
-          this.setTasksStatus(task, 'COMPLETED');
-          status = 'COMPLETED';
-        }
-        stopPolling = true;
-      } else if (polledData.someProperty('Tasks.status', 'IN_PROGRESS')) {
+      stopPolling = true;
+    } else if (polledData.someProperty('Tasks.status', 'IN_PROGRESS')) {
+      if (task == 5) {
+        this.get('tasks')[5].set('progress', 50);
+      } else {
         var progress = polledData.filterProperty('Tasks.status', 'COMPLETED').length / polledData.length * 100;
-        this.setTasksStatus(task, 'IN_PROGRESS');
         this.get('tasks')[task].set('progress', Math.round(progress));
       }
-    } else {
-      //installing component
-      status = polledData[0].Tasks.status;
-      this.setTasksStatus(5, status);
-      if (status == 'IN_PROGRESS') {
-        this.get('tasks')[5].set('progress', '50');
-      }
-      if (status == 'COMPLETED' || status == 'FAILED') {
-        stopPolling = true;
-      }
+      this.setTasksStatus(task, 'IN_PROGRESS');
     }
     if (!stopPolling) {
       window.setTimeout(function () {
         self.getLogsByRequest()
       }, self.POLL_INTERVAL);
-    } else {
-      if (status == 'FAILED') {
-        //todo show retry
-      }
-      if (starting && status == 'COMPLETED') {
-        this.set('isSubmitDisabled', false);
-      }
     }
   },
 
   POLL_INTERVAL: 4000,
+  dataPollCounter: 1,
 
   getLogsByRequest: function () {
-    var self = this;
-    var clusterName = this.get('content.cluster.name');
-    var requestId = this.get('currentRequestId');
-    var url = App.apiPrefix + '/clusters/' + clusterName + '/requests/' + requestId + '?fields=tasks/*';
-    $.ajax({
-      type: 'GET',
-      url: url,
-      timeout: App.timeout,
-      dataType: 'text',
-      success: function (data) {
-        self.parseLogs(jQuery.parseJSON(data));
-      },
+    this.set('logs', []);
+    if (App.testMode) {
+      var data = require('data/mock/step14PolledData/tasks_poll' + this.get('dataPollCounter'));
+      this.set('dataPollCounter', this.get('dataPollCounter') + 1);
+      if (this.get('dataPollCounter') == 6) {
+        this.set('dataPollCounter', 1);
+      }
+      this.onGetLogsByRequestSuccess(data);
+    } else {
+      var requestIds = this.get('currentRequestId');
+      requestIds.forEach(function (requestId) {
+        App.ajax.send({
+          name: 'reassign.get_logs',
+          sender: this,
+          data: {
+            requestId: requestId
+          },
+          success: 'onGetLogsByRequestSuccess',
+          error: 'onGetLogsByRequestError'
+        });
+      }, this);
+    }
+  },
 
-      error: function () {
-        this.set('status', 'FAILED');
-      },
+  logs: [],
 
-      statusCode: require('data/statusCodes')
-    }).retry({times: App.maxRetries, timeout: App.timeout}).then(null,
-        function () {
-          App.showReloadPopup();
-          console.log('Install services all retries FAILED');
-        }
-    );
+  onGetLogsByRequestSuccess: function (data) {
+    this.get('logs').push(data);
+    if (this.get('logs.length') == this.get('currentRequestId.length') || App.testMode) {
+      this.parseLogs(this.get('logs'))
+    }
+  },
+
+  onGetLogsByRequestError: function () {
+    this.set('status', 'FAILED');
   },
 
   removeComponent: function () {
-    //todo after API providing
+    if (App.testMode) {
+      this.setTasksStatus(7, 'COMPLETED');
+    } else {
+      var hostName = this.get('content.reassign.host_id');
+      var componentNames = [this.get('masterComponent.component_name')];
+      if (this.get('isCohosted')) {
+        componentNames = ['HIVE_SERVER', 'WEBHCAT_SERVER', 'MYSQL_SERVER'];
+        this.set('queueTasksCompleted', 0);
+      }
+      componentNames.forEach(function (componentName) {
+        App.ajax.send({
+          name: 'reassign.remove_component',
+          sender: this,
+          data: {
+            hostName: hostName,
+            componentName: componentName
+          },
+          beforeSend: 'onRemoveComponentBeforeSend',
+          success: 'onRemoveComponentSuccess',
+          error: 'onRemoveComponentError'
+        });
+      }, this);
+    }
+  },
+
+  onRemoveComponentBeforeSend: function () {
+    this.setTasksStatus(7, 'PENDING');
+  },
+
+  onRemoveComponentSuccess: function () {
     this.setTasksStatus(7, 'COMPLETED');
   },
 
-  submit: function () {
-    if (!this.get('isSubmitDisabled')) {
-      App.router.send('next');
+  onRemoveComponentError: function () {
+    this.setTasksStatus(7, 'FAILED');
+  },
+
+  retry: function () {
+    if (this.get('tasks')[5].status == 'FAILED') {
+      this.installComponent();
+    } else {
+      this.startComponents();
+    }
+    this.set('showRetry', false);
+  },
+
+  abort: function () {
+    var hostName = this.get('content.masterComponentHosts').findProperty('component', this.get('content.reassign.component_name')).hostName;
+    var componentNames = [this.get('masterComponent.component_name')];
+    if (this.get('isCohosted')) {
+      componentNames = ['HIVE_SERVER', 'WEBHCAT_SERVER', 'MYSQL_SERVER'];
+      this.set('queueTasksCompleted', 0);
+    }
+    componentNames.forEach(function (componentName) {
+      App.ajax.send({
+        name: 'reassign.maintenance_mode',
+        sender: this,
+        data: {
+          hostName: hostName,
+          componentName: componentName
+        },
+        success: 'onAbortMaintenance',
+        error: 'onAbortError'
+      });
+    }, this);
+  },
+
+
+  onAbortMaintenance: function () {
+    if (this.get('isCohosted') && this.get('queueTasksCompleted') < 2) {
+      this.set('queueTasksCompleted', this.get('queueTasksCompleted') + 1);
+    } else {
+      var hostName = this.get('content.masterComponentHosts').findProperty('component', this.get('content.reassign.component_name')).hostName;
+      var componentNames = [this.get('masterComponent.component_name')];
+      if (this.get('isCohosted')) {
+        componentNames = ['HIVE_SERVER', 'WEBHCAT_SERVER', 'MYSQL_SERVER'];
+        this.set('queueTasksCompleted', 0);
+      }
+      componentNames.forEach(function (componentName) {
+        App.ajax.send({
+          name: 'reassign.remove_component',
+          sender: this,
+          data: {
+            hostName: hostName,
+            componentName: componentName
+          },
+          success: 'onAbortRemoveComponent',
+          error: 'onAbortError'
+        });
+      }, this);
     }
+  },
+
+  onAbortRemoveComponent: function () {
+    if (this.get('isCohosted') && this.get('queueTasksCompleted') < 2) {
+      this.set('queueTasksCompleted', this.get('queueTasksCompleted') + 1);
+    } else {
+      var hostName = this.get('content.reassign.host_id');
+      var componentNames = [this.get('masterComponent.component_name')];
+      if (this.get('isCohosted')) {
+        componentNames = ['HIVE_SERVER', 'WEBHCAT_SERVER', 'MYSQL_SERVER'];
+        this.set('queueTasksCompleted', 0);
+      }
+      componentNames.forEach(function (componentName) {
+        App.ajax.send({
+          name: 'reassign.install_component',
+          sender: this,
+          data: {
+            hostName: hostName,
+            componentName: componentName
+          },
+          success: 'onAbortCompleted',
+          error: 'onAbortError'
+        });
+      }, this);
+    }
+  },
+
+  onAbortCompleted: function () {
+    if (this.get('isCohosted') && this.get('queueTasksCompleted') < 2) {
+      this.set('queueTasksCompleted', this.get('queueTasksCompleted') + 1);
+    } else {
+      App.clusterStatus.setClusterStatus({
+        clusterName: this.get('content.cluster.name'),
+        clusterState: 'REASSIGN_MASTER_ABORTED',
+        wizardControllerName: this.get('content.controllerName'),
+        localdb: App.db.data
+      });
+      App.router.send('back');
+    }
+  },
+
+  onAbortError: function () {
+    App.ModalPopup.show({
+      header: Em.I18n.translations['common.error'],
+      secondary: false,
+      onPrimary: function () {
+        this.hide();
+      },
+      bodyClass: Ember.View.extend({
+        template: Ember.Handlebars.compile('<p>{{t installer.step14.abortError}}</p>')
+      })
+    });
   }
 })