浏览代码

AMBARI-6026 Convert UI code of Add Host and Add Service Wizards to to lazily load host and host component info. (Max Shepel via atkach)

atkach 11 年之前
父节点
当前提交
587482301f

+ 50 - 17
ambari-web/app/controllers/main/host/add_controller.js

@@ -18,6 +18,7 @@
 
 
 var App = require('app');
+var lazyLoading = require('utils/lazy_loading');
 
 App.AddHostController = App.WizardController.extend({
 
@@ -128,15 +129,6 @@ App.AddHostController = App.WizardController.extend({
     console.log('selected services ', serviceNames);
   },
 
-  /**
-   * return slaveComponents bound to hosts
-   * @return {Array}
-   */
-  getSlaveComponentHosts: function () {
-    return this._super().filter(function (component) {
-      return component.isInstalled;
-    });
-  },
 
   /**
    * Load master component hosts data for using in required step controllers
@@ -144,34 +136,67 @@ App.AddHostController = App.WizardController.extend({
    */
   loadSlaveComponentHosts: function () {
     var slaveComponentHosts = this.getDBProperty('slaveComponentHosts');
+    var message = 'AddHostController.loadSlaveComponentHosts: loaded hosts ';
+    var filterFunction = function (component) {
+      return component.isInstalled;
+    };
     if (!slaveComponentHosts) {
-      slaveComponentHosts = this.getSlaveComponentHosts();
+      this.getSlaveComponentHosts(this, 'content.slaveComponentHosts', message, filterFunction);
+    } else {
+      this.set('content.slaveComponentHosts', []);
+      lazyLoading.run({
+        initSize: 20,
+        chunkSize: 50,
+        delay: 50,
+        destination: this.get('content.slaveComponentHosts'),
+        source: slaveComponentHosts,
+        context: this
+      });
+      console.log(message, slaveComponentHosts);
     }
-    this.set("content.slaveComponentHosts", slaveComponentHosts);
-    console.log("AddHostController.loadSlaveComponentHosts: loaded hosts ", slaveComponentHosts);
   },
 
   /**
    * Generate clients list for selected services and save it to model
    */
   saveClients: function () {
+
+    App.ajax.send({
+      name: 'host_components.all',
+      sender: this,
+      data: {
+        clusterName: App.get('clusterName')
+      },
+      success: 'saveClientsSuccessCallBack'
+    });
+
+  },
+
+  saveClientsSuccessCallBack: function (response) {
     var clients = [];
     var serviceComponents = App.StackServiceComponent.find();
-    var hostComponents = App.HostComponent.find();
-
     this.get('content.services').filterProperty('isSelected').forEach(function (_service) {
       var client = serviceComponents.filterProperty('serviceName', _service.serviceName).findProperty('isClient');
       if (client) {
         clients.push({
           component_name: client.get('componentName'),
           display_name: client.get('displayName'),
-          isInstalled: hostComponents.filterProperty('componentName', client.get('componentName')).length > 0
+          isInstalled: response.items.filterProperty('HostRoles.component_name', client.get('componentName')).length > 0
         });
       }
     }, this);
 
     this.setDBProperty('clientInfo', clients);
-    this.set('content.clients', clients);
+    this.set('content.clients', []);
+    lazyLoading.run({
+      initSize: 20,
+      chunkSize: 50,
+      delay: 50,
+      destination: this.get('content.clients'),
+      source: clients,
+      context: this
+    });
+
     console.log("AddHostController.saveClients: saved list ", clients);
   },
 
@@ -289,7 +314,15 @@ App.AddHostController = App.WizardController.extend({
         var service = componentServiceMap[client.component_name];
         var serviceMatch = selectedServices.findProperty('serviceId', service);
         if (serviceMatch) {
-          serviceMatch.hosts = serviceMatch.hosts.concat(selectedClientHosts).uniq();
+          lazyLoading.run({
+            initSize: 20,
+            chunkSize: 50,
+            delay: 50,
+            destination: serviceMatch.hosts,
+            source: selectedClientHosts,
+            context: Em.Object.create()
+          });
+          serviceMatch.hosts = serviceMatch.hosts.uniq();
         } else {
           var configGroups = this.get('content.configGroups').filterProperty('ConfigGroup.tag', service);
           var configGroupsNames = configGroups.mapProperty('ConfigGroup.group_name').sort();

+ 71 - 43
ambari-web/app/controllers/main/service/add_controller.js

@@ -18,6 +18,7 @@
 
 
 var App = require('app');
+var lazyLoading = require('utils/lazy_loading');
 App.AddServiceController = App.WizardController.extend({
 
   name: 'addServiceController',
@@ -78,21 +79,6 @@ App.AddServiceController = App.WizardController.extend({
    */
   loadConfirmedHosts: function(){
     var hosts = this.getDBProperty('hosts');
-    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'),
-          disk_info: item.get('diskInfo'),
-          bootStatus: "REGISTERED",
-          isInstalled: true
-        };
-      });
-      this.setDBProperty('hosts', hosts);
-    }
 
     this.set('content.hosts', hosts);
     console.log('AddServiceController.loadConfirmedHosts: loaded hosts', hosts);
@@ -161,33 +147,44 @@ App.AddServiceController = App.WizardController.extend({
    * @param stepController App.WizardStep5Controller
    */
   saveMasterComponentHosts: function (stepController) {
-    var obj = stepController.get('selectedServicesMasters');
-    var masterComponentHosts = [];
-    var installedComponents = App.HostComponent.find();
 
+    App.ajax.send({
+      name: 'host_components.all',
+      sender: this,
+      data: {
+        clusterName: App.get('clusterName'),
+        stepController: stepController
+      },
+      success: 'saveMasterComponentHostsSuccessCallback'
+    });
+
+  },
+
+  saveMasterComponentHostsSuccessCallback: function (response, request, data) {
+    var obj = data.stepController.get('selectedServicesMasters');
+    var masterComponentHosts = [];
     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)
-        });
+      masterComponentHosts.push({
+        display_name: _component.display_name,
+        component: _component.component_name,
+        hostName: _component.selectedHost,
+        serviceId: _component.serviceId,
+        isInstalled: response.items.someProperty('HostRoles.component_name', _component.component_name)
+      });
     });
 
     console.log("AddServiceController.saveMasterComponentHosts: saved hosts ", masterComponentHosts);
     this.setDBProperty('masterComponentHosts', masterComponentHosts);
-    this.set('content.masterComponentHosts', masterComponentHosts);
-
-    this.set('content.skipMasterStep', this.get('content.masterComponentHosts').everyProperty('isInstalled', true));
-    this.get('isStepDisabled').findProperty('step', 2).set('value', this.get('content.skipMasterStep'));
-  },
+    this.set('content.masterComponentHosts', []);
+    lazyLoading.run({
+      initSize: 20,
+      chunkSize: 50,
+      delay: 50,
+      destination: this.get('content.masterComponentHosts'),
+      source: masterComponentHosts,
+      context: this
+    });
 
-  /**
-   * Load master component hosts data for using in required step controllers
-   */
-  loadMasterComponentHosts: function () {
-    this._super();
     this.set('content.skipMasterStep', this.get('content.masterComponentHosts').everyProperty('isInstalled', true));
     this.get('isStepDisabled').findProperty('step', 2).set('value', this.get('content.skipMasterStep'));
   },
@@ -238,11 +235,22 @@ App.AddServiceController = App.WizardController.extend({
    */
   loadSlaveComponentHosts: function () {
     var slaveComponentHosts = this.getDBProperty('slaveComponentHosts');
+    var message = 'AddServiceController.loadSlaveComponentHosts: loaded hosts ';
+    this.set('content.slaveComponentHosts', []);
     if(!slaveComponentHosts){
-      slaveComponentHosts = this.getSlaveComponentHosts();
+      this.getSlaveComponentHosts(this, 'content.slaveComponentHosts', message);
+    } else {
+      this.set('content.slaveComponentHosts', []);
+      lazyLoading.run({
+        initSize: 20,
+        chunkSize: 50,
+        delay: 50,
+        destination: this.get('content.slaveComponentHosts'),
+        source: slaveComponentHosts,
+        context: this
+      });
+      console.log(message, slaveComponentHosts);
     }
-    this.set("content.slaveComponentHosts", slaveComponentHosts);
-    console.log("AddServiceController.loadSlaveComponentHosts: loaded hosts ", slaveComponentHosts);
   },
 
   /**
@@ -250,23 +258,43 @@ App.AddServiceController = App.WizardController.extend({
    * @param stepController step4WizardController
    */
   saveClients: function(stepController){
+
+    App.ajax.send({
+      name: 'host_components.all',
+      sender: this,
+      data: {
+        clusterName: App.get('clusterName'),
+        stepController: stepController
+      },
+      success: 'saveClientsSuccessCallback'
+    });
+
+  },
+
+  saveClientsSuccessCallback: function (response, request, data) {
     var clients = [];
     var serviceComponents = App.StackServiceComponent.find();
-    var hostComponents = App.HostComponent.find();
-
-    stepController.get('content').filterProperty('isSelected',true).forEach(function (_service) {
+    data.stepController.get('content').filterProperty('isSelected',true).forEach(function (_service) {
       var client = serviceComponents.filterProperty('serviceName', _service.serviceName).findProperty('isClient', true);
       if (client) {
         clients.pushObject({
           component_name: client.get('componentName'),
           display_name: client.get('displayName'),
-          isInstalled: hostComponents.filterProperty('componentName', client.get('componentName')).length > 0
+          isInstalled: response.items.filterProperty('HostRoles.component_name', client.get('componentName')).length > 0
         });
       }
     }, this);
 
     this.setDBProperty('clientInfo', clients);
-    this.set('content.clients', clients);
+    this.set('content.clients', []);
+    lazyLoading.run({
+      initSize: 20,
+      chunkSize: 50,
+      delay: 50,
+      destination: this.get('content.clients'),
+      source: clients,
+      context: this
+    });
     console.log("AddServiceController.saveClients: saved list ", clients);
   },
 

+ 84 - 15
ambari-web/app/controllers/wizard.js

@@ -18,6 +18,7 @@
 
 
 var App = require('app');
+var lazyLoading = require('utils/lazy_loading');
 require('models/host');
 
 App.WizardController = Em.Controller.extend(App.LocalStorage, {
@@ -58,8 +59,6 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
     return App.StackServiceComponent.find().filterProperty('isSlave',true);
   }.property('App.router.clusterController.isLoaded'),
 
-  allHosts: App.Host.find(),
-
   setStepsEnable: function () {
     for (var i = 1; i <= this.totalSteps; i++) {
       var step = this.get('isStepDisabled').findProperty('step', i);
@@ -798,18 +797,40 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
         });
         // if modified configs detected push all service's configs for update
         if (configs.length)
-          updateServiceConfigProperties = updateServiceConfigProperties.concat(serviceConfigProperties.filterProperty('serviceName',_content.get('serviceName')));
+         lazyLoading.run({
+            initSize: 20,
+            chunkSize: 50,
+            delay: 50,
+            destination: updateServiceConfigProperties,
+            source: serviceConfigProperties.filterProperty('serviceName',_content.get('serviceName')),
+            context: this
+          });
         // watch for properties that are not modified but have to be updated
         if (_content.get('configs').someProperty('forceUpdate')) {
           // check for already added modified properties
           if (!updateServiceConfigProperties.findProperty('serviceName', _content.get('serviceName'))) {
-            updateServiceConfigProperties = updateServiceConfigProperties.concat(serviceConfigProperties.filterProperty('serviceName',_content.get('serviceName')));
+            lazyLoading.run({
+              initSize: 20,
+              chunkSize: 50,
+              delay: 50,
+              destination: updateServiceConfigProperties,
+              source: serviceConfigProperties.filterProperty('serviceName',_content.get('serviceName')),
+              context: this
+            });
           }
         }
       }
     }, this);
     this.setDBProperty('serviceConfigProperties', serviceConfigProperties);
-    this.set('content.serviceConfigProperties', serviceConfigProperties);
+    this.set('content.serviceConfigProperties', []);
+    lazyLoading.run({
+      initSize: 20,
+      chunkSize: 50,
+      delay: 50,
+      destination: this.get('content.serviceConfigProperties'),
+      source: serviceConfigProperties,
+      context: this
+    });
     this.setDBProperty('configsToUpdate', updateServiceConfigProperties);
   },
   /**
@@ -847,14 +868,21 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
     }, this);
     this.setDBProperty('serviceConfigGroups', serviceConfigGroups);
     this.set('content.configGroups', serviceConfigGroups);
+    lazyLoading.run({
+      initSize: 20,
+      chunkSize: 50,
+      delay: 50,
+      destination: this.get('content.configGroups'),
+      source: serviceConfigGroups,
+      context: this
+    });
   },
   /**
    * return slaveComponents bound to hosts
    * @return {Array}
    */
-  getSlaveComponentHosts: function () {
+  getSlaveComponentHosts: function (context, property, message, filterFunction) {
     var components = this.get('slaveComponents');
-    var result = [];
     var installedServices = App.Service.find().mapProperty('serviceName');
     var selectedServices = this.get('content.services').filterProperty('isSelected', true).mapProperty('serviceName');
     var installedComponentsMap = {};
@@ -869,13 +897,33 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
     }, this);
     installedComponentsMap['HDFS_CLIENT'] = [];
 
-    App.HostComponent.find().forEach(function (hostComponent) {
-      if (installedComponentsMap[hostComponent.get('componentName')]) {
-        installedComponentsMap[hostComponent.get('componentName')].push(hostComponent.get('host.id'));
+    App.ajax.send({
+      name: 'host_components.all',
+      sender: this,
+      data: {
+        clusterName: App.get('clusterName'),
+        installedComponentsMap: installedComponentsMap,
+        uninstalledComponents: uninstalledComponents,
+        context: context,
+        property: property,
+        message: message,
+        filterFunction: filterFunction
+      },
+      success: 'getSlaveComponentHostsSuccessCallback'
+    });
+
+  },
+
+  getSlaveComponentHostsSuccessCallback: function (response, request, data) {
+    var result = [];
+
+    response.items.mapProperty('HostRoles').forEach(function (hostComponent) {
+      if (data.installedComponentsMap[hostComponent.component_name]) {
+        data.installedComponentsMap[hostComponent.component_name].push(hostComponent.host_name);
       }
     }, this);
 
-    for (var componentName in installedComponentsMap) {
+    for (var componentName in data.installedComponentsMap) {
       var name = (componentName === 'HDFS_CLIENT') ? 'CLIENT' : componentName;
       var component = {
         componentName: name,
@@ -883,7 +931,7 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
         hosts: [],
         isInstalled: true
       };
-      installedComponentsMap[componentName].forEach(function (hostName) {
+      data.installedComponentsMap[componentName].forEach(function (hostName) {
         component.hosts.push({
           group: "Default",
           hostName: hostName,
@@ -893,7 +941,7 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
       result.push(component);
     }
 
-    uninstalledComponents.forEach(function (component) {
+    data.uninstalledComponents.forEach(function (component) {
       var hosts = jQuery.extend(true, [], result.findProperty('componentName', 'DATANODE').hosts);
       hosts.setEach('isInstalled', false);
       result.push({
@@ -904,7 +952,20 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
       })
     });
 
-    return result;
+    if (data.filterFunction) {
+      result = result.filter(data.filterFunction);
+    }
+
+    data.context.set(data.property, []);
+    lazyLoading.run({
+      initSize: 20,
+      chunkSize: 50,
+      delay: 50,
+      destination: data.context.get(data.property),
+      source: result,
+      context: this
+    });
+    console.log(data.message, result);
   },
   /**
    * Load master component hosts data for using in required step controllers
@@ -931,7 +992,15 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, {
    */
   loadClients: function () {
     var clients = this.getDBProperty('clientInfo');
-    this.set('content.clients', clients);
+    this.set('content.clients', []);
+    lazyLoading.run({
+      initSize: 20,
+      chunkSize: 50,
+      delay: 50,
+      destination: this.get('content.clients'),
+      source: clients,
+      context: this
+    });
     console.log(this.get('content.controllerName') + ".loadClients: loaded list ", clients);
   }
 });

+ 43 - 14
ambari-web/app/controllers/wizard/step10_controller.js

@@ -17,6 +17,7 @@
  */
 
 var App = require('app');
+var lazyLoading = require('utils/lazy_loading');
 
 App.WizardStep10Controller = Em.Controller.extend({
 
@@ -56,16 +57,7 @@ App.WizardStep10Controller = Em.Controller.extend({
   loadStep: function () {
     console.log("TRACE: Loading step10: Summary Page");
     this.clearStep();
-    this.loadInstalledHosts(this.loadRegisteredHosts());
-    var installFlag = true;
-    var startFlag = true;
-    if (this.get('content.controllerName') == 'installerController') {
-      installFlag = this.loadMasterComponents();
-      startFlag = this.loadStartedServices();
-    }
-    if (installFlag && startFlag) {
-      this.loadInstallTime();
-    }
+    this.loadRegisteredHosts();
   },
 
   /**
@@ -74,14 +66,41 @@ App.WizardStep10Controller = Em.Controller.extend({
    * @method loadRegisteredHosts
    */
   loadRegisteredHosts: function () {
+    var clusterName = (this.get('content.controllerName') === 'installerController') ? this.get('content.cluster.name') : App.get('clusterName')
+    App.ajax.send({
+      name: 'hosts.all',
+      sender: this,
+      data: {
+        clusterName: clusterName
+      },
+      success: 'loadRegisteredHostsSuccessCallback'
+    });
+  },
+
+  loadRegisteredHostsSuccessCallback: function (response) {
     var masterHosts = this.get('content.masterComponentHosts').mapProperty('hostName').uniq();
-    var slaveHosts = this.get('content.slaveComponentHosts');
+    var slaveHosts = [];
+    lazyLoading.run({
+      initSize: 20,
+      chunkSize: 50,
+      delay: 50,
+      destination: slaveHosts,
+      source: this.get('content.slaveComponentHosts'),
+      context: Em.Object.create()
+    });
     var hostObj = [];
     slaveHosts.forEach(function (_hosts) {
-      hostObj = hostObj.concat(_hosts.hosts);
+      lazyLoading.run({
+        initSize: 20,
+        chunkSize: 50,
+        delay: 50,
+        destination: hostObj,
+        source: _hosts.hosts,
+        context: Em.Object.create()
+      });
     }, this);
     slaveHosts = hostObj.mapProperty('hostName').uniq();
-    var registeredHosts = App.Host.find().mapProperty('hostName').concat(masterHosts.concat(slaveHosts)).uniq();
+    var registeredHosts = response.items.mapProperty('Hosts.host_name').concat(masterHosts.concat(slaveHosts)).uniq();
     var registerHostsStatement = Em.I18n.t('installer.step10.hostsSummary').format(registeredHosts.length);
     var registerHostsObj = Em.Object.create({
       id: 1,
@@ -91,7 +110,17 @@ App.WizardStep10Controller = Em.Controller.extend({
     });
     this.get('clusterInfo').pushObject(registerHostsObj);
 
-    return registerHostsObj;
+    this.loadInstalledHosts();
+    var installFlag = true;
+    var startFlag = true;
+    if (this.get('content.controllerName') == 'installerController') {
+      installFlag = this.loadMasterComponents();
+      startFlag = this.loadStartedServices();
+    }
+    if (installFlag && startFlag) {
+      this.loadInstallTime();
+    }
+    this.set('isLoaded', true);
   },
 
   /**

+ 39 - 4
ambari-web/app/controllers/wizard/step2_controller.js

@@ -148,10 +148,30 @@ App.WizardStep2Controller = Em.Controller.extend({
    * @method updateHostNameArr
    */
   updateHostNameArr: function () {
-    this.set('hostNameArr', this.get('hostNames').trim().split(new RegExp("\\s+", "g")));
+    this.set('hostNameArr', []);
+    lazyloading.run({
+      initSize: 20,
+      chunkSize: 50,
+      delay: 50,
+      destination: this.get('hostNameArr'),
+      source: this.get('hostNames').trim().split(new RegExp("\\s+", "g")),
+      context: this
+    });
     this.parseHostNamesAsPatternExpression();
     this.get('inputtedAgainHostNames').clear();
-    var installedHostNames = App.Host.find().mapProperty('hostName'),
+    var requestName = (this.get('content.controllerName') == 'installerController') ? 'hosts.all.install' : 'hosts.all';
+    App.ajax.send({
+      name: requestName,
+      sender: this,
+      data: {
+        clusterName: App.get('clusterName')
+      },
+      success: 'updateHostNameArrSuccessCallback'
+    });
+  },
+
+  updateHostNameArrSuccessCallback: function (response) {
+    var installedHostNames = response.items.mapProperty('Hosts.host_name'),
       tempArr = [],
       hostNameArr = this.get('hostNameArr');
     for (var i = 0; i < hostNameArr.length; i++) {
@@ -162,7 +182,14 @@ App.WizardStep2Controller = Em.Controller.extend({
         this.get('inputtedAgainHostNames').push(hostNameArr[i]);
       }
     }
-    this.set('hostNameArr', tempArr);
+    lazyloading.run({
+      initSize: 20,
+      chunkSize: 50,
+      delay: 50,
+      destination: this.get('hostNameArr'),
+      source: tempArr,
+      context: this
+    });
   },
 
   /**
@@ -311,7 +338,15 @@ App.WizardStep2Controller = Em.Controller.extend({
         hostNames.push(a);
       }
     });
-    this.set('hostNameArr', hostNames);
+    this.set('hostNameArr', []);
+    lazyloading.run({
+      initSize: 20,
+      chunkSize: 50,
+      delay: 50,
+      destination: this.get('hostNameArr'),
+      source: hostNames,
+      context: this
+    });
   },
 
   /**

+ 89 - 13
ambari-web/app/controllers/wizard/step3_controller.js

@@ -95,9 +95,7 @@ App.WizardStep3Controller = Em.Controller.extend({
    * List of installed hostnames
    * @type {string[]}
    */
-  hostsInCluster: function () {
-    return App.Host.find().getEach('hostName');
-  }.property().volatile(),
+  hostsInCluster: [],
 
   /**
    * All hosts warnings
@@ -151,6 +149,14 @@ App.WizardStep3Controller = Em.Controller.extend({
    */
   checksUpdateStatus: null,
 
+  /**
+   * Message about other registered hosts (not included in current registration)
+   * @type {string}
+   */
+  registeredHostsMessage: '',
+
+  /**
+
   /**
    *
    * @method navigateStep
@@ -162,7 +168,15 @@ App.WizardStep3Controller = Em.Controller.extend({
           this.startBootstrap();
         }
       } else {
-        this.set('bootHosts', this.get('hosts'));
+        this.set('bootHosts', []);
+        lazyloading.run({
+          initSize: 20,
+          chunkSize: 50,
+          delay: 200,
+          destination: this.get('bootHosts'),
+          source: this.get('hosts'),
+          context: Em.Object.create()
+        });
         if (App.get('testMode')) {
           this.startHostcheck();
           this.get('bootHosts').setEach('cpu', '2');
@@ -223,8 +237,15 @@ App.WizardStep3Controller = Em.Controller.extend({
         }));
       }
     }
-    this.set('hosts', hosts);
-    this.set('isLoaded', true);
+    this.set('hosts', []);
+    lazyloading.run({
+      initSize: 20,
+      chunkSize: 50,
+      delay: 50,
+      destination: this.get('hosts'),
+      source: hosts,
+      context: this
+    });
   },
 
   /**
@@ -638,20 +659,59 @@ App.WizardStep3Controller = Em.Controller.extend({
    * @method getAllRegisteredHostsCallback
    */
   getAllRegisteredHostsCallback: function (hosts) {
-    var registeredHosts = [];
-    var hostsInCluster = this.get('hostsInCluster');
-    var addedHosts = this.get('bootHosts').getEach('name');
-    hosts.items.forEach(function (host) {
+    App.ajax.send({
+      name: 'hosts.all.install',
+      sender: this,
+      data: {
+        hosts: hosts
+      },
+      success: 'hostsInClusterSuccessCallback',
+      error: ''
+    });
+  },
+
+  hostsInClusterSuccessCallback: function (response, request, data) {
+    this.set('hostsInCluster', []);
+    lazyloading.run({
+      initSize: 20,
+      chunkSize: 50,
+      delay: 50,
+      destination: this.get('hostsInCluster'),
+      source: response.items.getEach('Hosts.host_name'),
+      context: Em.Object.create()
+    });
+    var registeredHosts = [],
+      hostsInCluster = [],
+      addedHosts = [];
+    lazyloading.run({
+      initSize: 20,
+      chunkSize: 50,
+      delay: 50,
+      destination: addedHosts,
+      source: this.get('bootHosts').getEach('name'),
+      context: Em.Object.create()
+    });
+    data.hosts.items.forEach(function (host) {
       if (!hostsInCluster.contains(host.Hosts.host_name) && !addedHosts.contains(host.Hosts.host_name)) {
         registeredHosts.push(host.Hosts.host_name);
       }
     });
     if (registeredHosts.length) {
       this.set('hasMoreRegisteredHosts', true);
-      this.set('registeredHosts', registeredHosts);
+      this.set('registeredHosts', []);
+      lazyloading.run({
+        initSize: 20,
+        chunkSize: 50,
+        delay: 50,
+        destination: this.get('registeredHosts'),
+        source: registeredHosts,
+        context: this
+      });
+      this.set('registeredHostsMessage', Em.I18n.t('installer.step3.warning.registeredHosts').format(this.get('registeredHosts').length))
     } else {
       this.set('hasMoreRegisteredHosts', false);
       this.set('registeredHosts', '');
+      this.set('isLoaded', true);
     }
   },
 
@@ -1035,13 +1095,29 @@ App.WizardStep3Controller = Em.Controller.extend({
       var self = this;
       return App.showConfirmationPopup(
         function () {
-          self.set('content.hosts', self.get('bootHosts'));
+          self.set('content.hosts', []);
+          lazyloading.run({
+            initSize: 20,
+            chunkSize: 50,
+            delay: 50,
+            destination: self.get('content.hosts'),
+            source: self.get('bootHosts'),
+            context: Em.Object.create()
+          });
           App.router.send('next');
         },
         Em.I18n.t('installer.step3.hostWarningsPopup.hostHasWarnings'));
     }
     else {
-      this.set('content.hosts', this.get('bootHosts'));
+      this.set('content.hosts', []);
+      lazyloading.run({
+        initSize: 20,
+        chunkSize: 50,
+        delay: 50,
+        destination: this.get('content.hosts'),
+        source: this.get('bootHosts'),
+        context: Em.Object.create()
+      });
       App.router.send('next');
     }
     return null;

+ 80 - 14
ambari-web/app/controllers/wizard/step5_controller.js

@@ -18,6 +18,7 @@
 
 var App = require('app');
 var numberUtils = require('utils/number_utils');
+var lazyLoading = require('utils/lazy_loading');
 
 App.WizardStep5Controller = Em.Controller.extend({
 
@@ -65,24 +66,38 @@ App.WizardStep5Controller = Em.Controller.extend({
    */
   multipleComponents: ['ZOOKEEPER_SERVER', 'HBASE_MASTER'],
 
+  submitDisabled: false,
+
   /**
    * Define state for submit button. Return true only for Reassign Master Wizard and if more than one master component was reassigned.
    * @type {bool}
    */
   isSubmitDisabled: function () {
     if (!this.get('isReassignWizard')) {
-      return false;
+      this.set('submitDisabled', false);
+    } else {
+      App.ajax.send({
+        name: 'host_components.all',
+        sender: this,
+        data: {
+          clusterName: App.get('clusterName')
+        },
+        success: 'isSubmitDisabledSuccessCallBack'
+      });
     }
+  }.observes('servicesMasters.@each.selectedHost'),
+
+  isSubmitDisabledSuccessCallBack: function (response) {
     var reassigned = 0;
-    var arr1 = App.HostComponent.find().filterProperty('componentName', this.get('content.reassign.component_name')).mapProperty('host.hostName');
+    var arr1 = response.items.mapProperty('HostRoles').filterProperty('component_name', this.get('content.reassign.component_name')).mapProperty('host_name');
     var arr2 = this.get('servicesMasters').mapProperty('selectedHost');
     arr1.forEach(function (host) {
       if (!arr2.contains(host)) {
         reassigned++;
       }
     }, this);
-    return reassigned !== 1;
-  }.property('servicesMasters.@each.selectedHost'),
+    this.set('submitDisabled', reassigned !== 1);
+  },
 
   /**
    * List of hosts
@@ -133,32 +148,73 @@ App.WizardStep5Controller = Em.Controller.extend({
    * </code>
    * @type {Ember.Enumerable}
    */
-  masterHostMapping: function () {
+  masterHostMapping: [],
+
+  isLoaded: false,
+
+  /**
+   * Check if HIVE_SERVER component exist (also checks if this is not reassign)
+   * @type {bool}
+   */
+  hasHiveServer: function () {
+    return this.get('selectedServicesMasters').someProperty('component_name', 'HIVE_SERVER') && !this.get('isReassignWizard');
+  }.property('selectedServicesMasters'),
+
+  masterHostMappingObserver: function () {
+    var requestName = this.get('content.controllerName') == 'installerController' ? 'hosts.confirmed.install' : 'hosts.confirmed'
+    App.ajax.send({
+      name: requestName,
+      sender: this,
+      data: {
+        clusterName: App.get('clusterName')
+      },
+      success: 'masterHostMappingSuccessCallback'
+    });
+  }.observes('selectedServicesMasters', 'selectedServicesMasters.@each.selectedHost'),
+
+  masterHostMappingSuccessCallback: function (response) {
     var mapping = [], mappingObject, mappedHosts, hostObj;
     //get the unique assigned hosts and find the master services assigned to them
-    mappedHosts = this.get("selectedServicesMasters").mapProperty("selectedHost").uniq();
+    mappedHosts = this.get("selectedServicesMasters").mapProperty("selectedHost").uniq().without(undefined);
     mappedHosts.forEach(function (item) {
-      hostObj = this.get("hosts").findProperty("host_name", item);
+      var host = response.items.mapProperty('Hosts').findProperty('host_name', item);
+      hostObj = {
+        name: host.host_name,
+        memory: host.total_mem,
+        cpu: host.cpu_count
+      };
 
       mappingObject = Em.Object.create({
         host_name: item,
-        hostInfo: hostObj.host_info,
+        hostInfo: Em.I18n.t('installer.step5.hostInfo').fmt(hostObj.name, numberUtils.bytesToSize(hostObj.memory, 1, 'parseFloat', 1024), hostObj.cpu),
         masterServices: this.get("selectedServicesMasters").filterProperty("selectedHost", item)
       });
 
       mapping.pushObject(mappingObject);
     }, this);
 
-    return mapping.sortProperty('host_name');
-  }.property("selectedServicesMasters.@each.selectedHost"),
+    this.set('masterHostMapping', []);
+    lazyLoading.run({
+      initSize: 20,
+      chunkSize: 50,
+      delay: 50,
+      destination: this.get('masterHostMapping'),
+      source: mapping.sortProperty('host_name'),
+      context: Em.Object.create()
+    });
+  },
 
   /**
    * Count of hosts without masters
    * @type {number}
    */
   remainingHosts: function () {
-    return (this.get("hosts.length") - this.get("masterHostMapping.length"));
-  }.property("selectedServicesMasters.@each.selectedHost"),
+    if (this.get('content.controllerName') === 'installerController') {
+     return 0;
+    } else {
+      return (this.get("hosts.length") - this.get("masterHostMapping.length"));
+    };
+  }.property('masterHostMapping.length', 'selectedServicesMasters.@each.selectedHost'),
 
   /**
    * Clear controller data (hosts, masters etc)
@@ -235,8 +291,17 @@ App.WizardStep5Controller = Em.Controller.extend({
         }));
       }
     }
-    this.set("hosts", result);
+    this.set("hosts", []);
+    lazyLoading.run({
+      initSize: 20,
+      chunkSize: 50,
+      delay: 50,
+      destination: this.get('hosts'),
+      source: result,
+      context: Em.Object.create()
+    });
     this.sortHosts(this.get('hosts'));
+    this.set('isLoaded', true);
   },
 
   /**
@@ -626,7 +691,8 @@ App.WizardStep5Controller = Em.Controller.extend({
    * @metohd submit
    */
   submit: function () {
-    if (!this.get('isSubmitDisabled')) {
+    this.isSubmitDisabled();
+    if (!this.get('submitDisabled')) {
       App.router.send('next');
     }
   }

+ 25 - 6
ambari-web/app/controllers/wizard/step6_controller.js

@@ -342,17 +342,13 @@ App.WizardStep6Controller = Em.Controller.extend({
     return hostNames;
   },
 
-  /**
-   * Load all data needed for this module. Then it automatically renders in template
-   * @method render
-   */
-  render: function () {
+  renderHostNames: function (array) {
     var hostsObj = [],
       masterHosts = [],
       headers = this.get('headers'),
       masterHostNames = this.get('content.masterComponentHosts').mapProperty('hostName').uniq();
 
-    this.getHostNames().forEach(function (_hostName) {
+    array.forEach(function (_hostName) {
       var hasMaster = masterHostNames.contains(_hostName);
 
       var obj = Em.Object.create({
@@ -392,6 +388,29 @@ App.WizardStep6Controller = Em.Controller.extend({
     this.set('isLoaded', true);
   },
 
+  /**
+   * Load all data needed for this module. Then it automatically renders in template
+   * @method render
+   */
+  render: function () {
+    if (this.get('isInstallerWizard') || this.get('isAddHostWizard')) {
+      this.renderHostNames(this.getHostNames());
+    } else {
+      App.ajax.send({
+        name: 'hosts.all',
+        sender: this,
+        data: {
+          clusterName: App.get('clusterName')
+        },
+        success: 'getHostNamesSuccessCallback'
+      });
+    }
+  },
+
+  getHostNamesSuccessCallback: function (response) {
+    this.renderHostNames(response.items.mapProperty('Hosts.host_name'));
+  },
+
   /**
    * Set checked values for slaves checkboxes
    * @param {Array} hostsObj

+ 39 - 5
ambari-web/app/controllers/wizard/step7_controller.js

@@ -18,6 +18,8 @@
 
 var App = require('app');
 var numberUtils = require('utils/number_utils');
+var lazyLoading = require('utils/lazy_loading');
+
 /**
  * By Step 7, we have the following information stored in App.db and set on this
  * controller by the router.
@@ -203,7 +205,8 @@ App.WizardStep7Controller = Em.Controller.extend({
         sender: this,
         data: {
           serviceName: serviceName,
-          serviceConfigsDef: App.config.get('preDefinedServiceConfigs').findProperty('serviceName', serviceName)
+          serviceConfigsDef: App.config.get('preDefinedServiceConfigs').findProperty('serviceName', serviceName),
+          urlParams: ',hosts'
         },
         success: 'loadServiceTagsSuccess'
       });
@@ -290,7 +293,7 @@ App.WizardStep7Controller = Em.Controller.extend({
       name: App.Service.DisplayNames[serviceName] + " Default",
       description: "Default cluster level " + serviceName + " configuration",
       isDefault: true,
-      hosts: defaultConfigGroupHosts,
+      hosts: [],
       parentConfigGroup: null,
       service: Em.Object.create({
         id: serviceName
@@ -300,9 +303,25 @@ App.WizardStep7Controller = Em.Controller.extend({
     });
     if (!selectedConfigGroup) {
       selectedConfigGroup = defaultConfigGroup;
+      lazyLoading.run({
+        initSize: 20,
+        chunkSize: 50,
+        delay: 200,
+        destination: selectedConfigGroup.get('hosts'),
+        source: defaultConfigGroupHosts,
+        context: Em.Object.create()
+      });
     }
     configGroups = configGroups.sortProperty('name');
     configGroups.unshift(defaultConfigGroup);
+    lazyLoading.run({
+      initSize: 20,
+      chunkSize: 50,
+      delay: 200,
+      destination: configGroups.objectAt(0).get('hosts'),
+      source: defaultConfigGroupHosts,
+      context: Em.Object.create()
+    });
     if (App.get('supports.hostOverrides')) {
       service.set('configGroups', configGroups);
       var loadedGroupToOverrideSiteToTagMap = {};
@@ -696,7 +715,14 @@ App.WizardStep7Controller = Em.Controller.extend({
     var installedServiceSites = [];
     this.get('serviceConfigsData').filter(function (service) {
       if (this.get('installedServiceNames').contains(service.serviceName)) {
-        installedServiceSites = installedServiceSites.concat(service.sites);
+        lazyLoading.run({
+          initSize: 20,
+          chunkSize: 50,
+          delay: 50,
+          destination: installedServiceSites,
+          source: service.sites,
+          context: Em.Object.create()
+        });
       }
     }, this);
     installedServiceSites = installedServiceSites.uniq();
@@ -781,7 +807,7 @@ App.WizardStep7Controller = Em.Controller.extend({
    */
   loadConfigGroups: function (serviceConfigGroups) {
     var services = this.get('stepConfigs');
-    var hosts = this.get('wizardController.allHosts').mapProperty('hostName');
+    var hosts = Em.keys(this.get('wizardController').getDBProperty('hosts'));
     services.forEach(function (service) {
       if (service.get('serviceName') === 'MISC') return;
       var serviceRawGroups = serviceConfigGroups.filterProperty('service.id', service.serviceName);
@@ -791,13 +817,21 @@ App.WizardStep7Controller = Em.Controller.extend({
             name: App.Service.DisplayNames[service.serviceName] + " Default",
             description: "Default cluster level " + service.serviceName + " configuration",
             isDefault: true,
-            hosts: Em.copy(hosts),
+            hosts: [],
             service: Em.Object.create({
               id: service.serviceName
             }),
             serviceName: service.serviceName
           })
         ]);
+        lazyLoading.run({
+          initSize: 20,
+          chunkSize: 50,
+          delay: 50,
+          destination: service.get('configGroups').objectAt(0).get('hosts'),
+          source: hosts,
+          context: Em.Object.create()
+        });
       }
       else {
         var defaultGroup = App.ConfigGroup.create(serviceRawGroups.findProperty('isDefault'));

+ 0 - 5
ambari-web/app/styles/application.less

@@ -756,11 +756,6 @@ h1 {
       background-color: #808080;
       opacity: 0.2;
     }
-    .spinner {
-      position: absolute;
-      margin-top: 30%;
-      margin-left: 50%;
-    }
   }
   #deploy {
     .pre-scrollable {

+ 27 - 23
ambari-web/app/templates/wizard/step10.hbs

@@ -25,29 +25,33 @@
 <div class="alert alert-info">
   {{t installer.step10.body}}
 </div>
-<div id="step10-content" class="well pre-scrollable">
-  <ul>
-    {{#each item in clusterInfo}}
-      <li>
-        <span {{bindAttr class="item.color"}}>{{item.displayStatement}}</span>
-        <ul>
-          {{#each status in item.status}}
-            <li>
-              <span {{bindAttr class="status.color"}}>{{status.displayStatement}}</span>
-              <ul>
-                {{#each statement in status.statements}}
-                  <li>
-                    <span {{bindAttr class="status.color"}}>{{statement.displayStatement}}</span>
-                  </li>
-                {{/each}}
-              </ul>
-            </li>
-          {{/each}}
-        </ul>
-      </li>
-    {{/each}}
-  </ul>
-</div>
+{{#if controller.isLoaded}}
+  <div id="step10-content" class="well pre-scrollable">
+    <ul>
+      {{#each item in clusterInfo}}
+        <li>
+          <span {{bindAttr class="item.color"}}>{{item.displayStatement}}</span>
+          <ul>
+            {{#each status in item.status}}
+              <li>
+                <span {{bindAttr class="status.color"}}>{{status.displayStatement}}</span>
+                <ul>
+                  {{#each statement in status.statements}}
+                    <li>
+                      <span {{bindAttr class="status.color"}}>{{statement.displayStatement}}</span>
+                    </li>
+                  {{/each}}
+                </ul>
+              </li>
+            {{/each}}
+          </ul>
+        </li>
+      {{/each}}
+    </ul>
+  </div>
+{{else}}
+  <div class="spinner"></div>
+{{/if}}
 <div class="btn-area">
   <a class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action complete}}>{{t common.complete}} &rarr;</a>
 </div>

+ 133 - 117
ambari-web/app/templates/wizard/step3.hbs

@@ -21,133 +21,149 @@
 
   <p class="alert alert-info">{{t installer.step3.body}}</p>
 
-  <div class="box">
-    <div class="box-header">
-      <div class="button-section">
-        <button class="btn btn-primary" {{bindAttr disabled="view.noHostsSelected"}}
-          {{action removeSelectedHosts target="controller" }}><i class="icon-trash icon-white"></i>
-          {{t installer.step3.removeSelected}}
-        </button>
-        {{#unless isRetryDisabled}}
-          <a class="btn btn-primary decommission"
-             href="#" {{action retrySelectedHosts target="view"}}><i class="icon-repeat icon-white"></i>
-            {{t installer.step3.retryFailed}}
-          </a>
-        {{/unless}}
+  {{#if view.isLoaded}}
+    {{#if controller.isLoaded}}
 
-        <div id="host-filter" class="pull-right">
-          <ul class="clearfix">
-            <li class="first">{{t common.show}}:</li>
-            {{#each category in view.categories}}
-              <li {{bindAttr class=":filter-status category.itemClass"}}>
-                <a {{action selectCategory category target="view"}} href="#">
-                  {{category.label}}
-                </a>
-              </li>
-              {{#unless category.last}}
-                <li class="divider">|</li>
-              {{/unless}}
-            {{/each}}
-          </ul>
+      <div class="box">
+        <div class="box-header">
+          <div class="button-section">
+            <button class="btn btn-primary" {{bindAttr disabled="view.noHostsSelected"}}
+              {{action removeSelectedHosts target="controller" }}><i class="icon-trash icon-white"></i>
+              {{t installer.step3.removeSelected}}
+            </button>
+            {{#unless isRetryDisabled}}
+              <a class="btn btn-primary decommission"
+                 href="#" {{action retrySelectedHosts target="view"}}><i class="icon-repeat icon-white"></i>
+                {{t installer.step3.retryFailed}}
+              </a>
+            {{/unless}}
+
+            <div id="host-filter" class="pull-right">
+              <ul class="clearfix">
+                <li class="first">{{t common.show}}:</li>
+                {{#each category in view.categories}}
+                  <li {{bindAttr class=":filter-status category.itemClass"}}>
+                    <a {{action selectCategory category target="view"}} href="#">
+                      {{category.label}}
+                    </a>
+                  </li>
+                  {{#unless category.last}}
+                    <li class="divider">|</li>
+                  {{/unless}}
+                {{/each}}
+              </ul>
+            </div>
+          </div>
         </div>
-      </div>
-    </div>
 
-    <div class="pre-scrollable" style="max-height: 440px;">
-      <table class="table table-bordered table-striped">
-        <thead>
-        <tr>
-          <th class="tinyspan">
-            {{view Ember.Checkbox checkedBinding="view.pageChecked"}}
-          </th>
-          <th class="span5">{{t common.host}}</th>
-          <!-- retrieved from local storage initially -->
-          <th class="span2">{{t common.progress}}</th>
-          <th class="span2">{{t common.status}}</th>
-          <!-- given by the parsing function that parses data from bootstrap call, dynamically assign the color -->
-          <th class="span2">{{t common.action}}</th>
-          <!-- trash icon -->
-          <!-- retry icon -->
-        </tr>
-        </thead>
-        <tbody>
-          {{#if view.pageContent}}
-            {{#each host in view.pageContent}}
-              {{#view App.WizardHostView categoryBinding="controller.category" hostInfoBinding="host"}}
-              <td>
-                {{view Ember.Checkbox checkedBinding="host.isChecked"}}
-              </td>
-              <td>
-                {{host.name}}
-              </td>
-              <td>
-                <div {{bindAttr class="host.bootBarColor host.isBootDone::progress-striped host.isBootDone::active :progress"}}>
-                  <div class="bar" style="width:100%">
-                  </div>
-                </div>
-              </td>
-              <td>
-                <a href="javascript:void(null)"
-                   data-toggle="modal" {{action hostLogPopup host target="controller"}}><span {{bindAttr class="host.bootStatusColor"}}>{{host.bootStatusForDisplay}}</span></a>
-              </td>
-              <td>
-                <a class="btn btn-mini" {{action remove target="view"}}><i class="icon-trash"></i>
-                  {{t common.remove}}</a>
-                {{#if view.isRetryable}}<a class="btn btn-mini" {{action retry target="view"}}><i
-                    class="icon-repeat"></i>
-                  {{t common.retry}}</a>{{/if}}
-              </td>
-              {{/view}}
-            {{/each}}
-          {{else}}
-          <tr>
-            <td colspan="5">
-              {{t hosts.table.noHosts}}
-            </td>
-          </tr>
-          {{/if}}
-        </tbody>
-      </table>
-    </div>
-    <div id="hosts">
-      <div class="page-bar">
-        <div class="selected-hosts-info pull-left">
-          {{#if view.selectedHostsCount}}
-            <a {{action selectedHostsPopup target="controller"}} href="#">
-              {{view.selectedHostsCount}}
-              {{pluralize view.selectedHostsCount singular="t:hosts.filters.selectedHostInfo" plural="t:hosts.filters.selectedHostsInfo"}}
-            </a>
-            -
-            <a {{action unSelectAll target="view"}} href="#">{{t hosts.filters.clearSelection}}</a>
-          {{/if}}
+        <div class="pre-scrollable" style="max-height: 440px;">
+          <table class="table table-bordered table-striped">
+            <thead>
+            <tr>
+              <th class="tinyspan">
+                {{view Ember.Checkbox checkedBinding="view.pageChecked"}}
+              </th>
+              <th class="span5">{{t common.host}}</th>
+              <!-- retrieved from local storage initially -->
+              <th class="span2">{{t common.progress}}</th>
+              <th class="span2">{{t common.status}}</th>
+              <!-- given by the parsing function that parses data from bootstrap call, dynamically assign the color -->
+              <th class="span2">{{t common.action}}</th>
+              <!-- trash icon -->
+              <!-- retry icon -->
+            </tr>
+            </thead>
+            <tbody>
+            {{#if view.pageContent}}
+              {{#each host in view.pageContent}}
+                {{#view App.WizardHostView categoryBinding="controller.category" hostInfoBinding="host"}}
+                  <td>
+                    {{view Ember.Checkbox checkedBinding="host.isChecked"}}
+                  </td>
+                  <td>
+                    {{host.name}}
+                  </td>
+                  <td>
+                    <div {{bindAttr class="host.bootBarColor host.isBootDone::progress-striped host.isBootDone::active :progress"}}>
+                      <div class="bar" style="width:100%">
+                      </div>
+                    </div>
+                  </td>
+                  <td>
+                    <a href="javascript:void(null)"
+                       data-toggle="modal" {{action hostLogPopup host target="controller"}}><span {{bindAttr class="host.bootStatusColor"}}>{{host.bootStatusForDisplay}}</span></a>
+                  </td>
+                  <td>
+                    <a class="btn btn-mini" {{action remove target="view"}}><i class="icon-trash"></i>
+                      {{t common.remove}}</a>
+                    {{#if view.isRetryable}}<a class="btn btn-mini" {{action retry target="view"}}><i
+                      class="icon-repeat"></i>
+                      {{t common.retry}}</a>{{/if}}
+                  </td>
+                {{/view}}
+              {{/each}}
+            {{else}}
+              <tr>
+                <td colspan="5">
+                  {{t hosts.table.noHosts}}
+                </td>
+              </tr>
+            {{/if}}
+            </tbody>
+          </table>
         </div>
-        <div class="items-on-page">
-          <label>{{t common.show}}: {{view view.rowsPerPageSelectView selectionBinding="view.displayLength"}}</label>
+        <div id="hosts">
+          <div class="page-bar">
+            <div class="selected-hosts-info pull-left">
+              {{#if view.selectedHostsCount}}
+                <a {{action selectedHostsPopup target="controller"}} href="#">
+                  {{view.selectedHostsCount}}
+                  {{pluralize view.selectedHostsCount singular="t:hosts.filters.selectedHostInfo" plural="t:hosts.filters.selectedHostsInfo"}}
+                </a>
+                -
+                <a {{action unSelectAll target="view"}} href="#">{{t hosts.filters.clearSelection}}</a>
+              {{/if}}
+            </div>
+            <div class="items-on-page">
+              <label>{{t common.show}}: {{view view.rowsPerPageSelectView selectionBinding="view.displayLength"}}</label>
+            </div>
+            <div class="info">{{view.paginationInfo}}</div>
+            <div class="paging_two_button">
+              {{view view.paginationFirst}}
+              {{view view.paginationLeft}}
+              {{view view.paginationRight}}
+              {{view view.paginationLast}}
+            </div>
+          </div>
         </div>
-        <div class="info">{{view.paginationInfo}}</div>
-        <div class="paging_two_button">
-          {{view view.paginationFirst}}
-          {{view view.paginationLeft}}
-          {{view view.paginationRight}}
-          {{view view.paginationLast}}
+      </div>
+      {{#if hasMoreRegisteredHosts}}
+        <div {{bindAttr class=":alert alert-warn"}}>
+          <a href="#" {{action registeredHostsPopup target="controller"}}>{{controller.registeredHostsMessage}}</a>
         </div>
+      {{/if}}
+      <div {{bindAttr class=":alert view.status isWarningsBoxVisible::hidden"}}>
+        {{view.message}}
+        <a href="#" {{action hostWarningsPopup warnings target="controller"}}>{{view.linkText}}</a>
+        {{#unless isWarningsLoaded}}
+          <div class="spinner"></div>
+        {{/unless}}
       </div>
-    </div>
-  </div>
-  {{#if hasMoreRegisteredHosts}}
-    <div {{bindAttr class=":alert alert-warn"}}>
-      <a href="#" {{action registeredHostsPopup target="controller"}}>{{view.registeredHostsMessage}}</a>
-    </div>
-  {{/if}}
-  <div {{bindAttr class=":alert view.status isWarningsBoxVisible::hidden"}}>
-    {{view.message}}
-    <a href="#" {{action hostWarningsPopup warnings target="controller"}}>{{view.linkText}}</a>
-    {{#unless isWarningsLoaded}}
+
+    {{else}}
+
       <div class="spinner"></div>
-    {{/unless}}
-  </div>
+
+    {{/if}}
+  {{else}}
+
+    <div class="spinner"></div>
+
+  {{/if}}
+
   <div class="btn-area">
     <button class="btn pull-left" {{bindAttr disabled="isRegistrationInProgress"}} {{action back}}>&larr; {{t common.back}}</button>
     <button class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action submit target="controller"}}>{{t common.next}} &rarr;</button>
   </div>
+
 </div>

+ 66 - 62
ambari-web/app/templates/wizard/step5.hbs

@@ -24,43 +24,44 @@
     {{t installer.step5.body.hive}}
   {{/if}}
 </div>
-<div class="assign-masters row-fluid">
-  <div class="select-hosts span7">
-    <div class="row-fluid">
-      {{#if showCurrentHost}}
-        <div class="span12 control-group mlc">
-          <div class="row-fluid">
-            <div class="span4"><span class="pull-right control-label">{{t services.reassign.step2.currentHost}}</span>
+{{#if controller.isLoaded}}
+  <div class="assign-masters row-fluid">
+    <div class="select-hosts span7">
+      <div class="row-fluid">
+        {{#if showCurrentHost}}
+          <div class="span12 control-group mlc">
+            <div class="row-fluid">
+              <div class="span4"><span class="pull-right control-label">{{t services.reassign.step2.currentHost}}</span>
+              </div>
+              <div class="span8"><span>{{currentHostId}}</span></div>
             </div>
-            <div class="span8"><span>{{currentHostId}}</span></div>
           </div>
-        </div>
-      {{/if}}
-      <div class="clearfix"></div>
-      <div class="row-fluid">
-        <div class="span12 control-group">
-          <form class="form-horizontal" autocomplete="off">
-            <!-- View for array controller -->
-            {{#each servicesMasters}}
-              <div class="row-fluid">
-                <div class="span4">
-                  <div class="control-group">
-                    <label class="pts pull-right">
-                      {{#if controller.isReassignHive}}
-                        {{t installer.step5.hiveGroup}}
-                      {{else}}
-                        {{display_name}}:
-                      {{/if}}
-                    </label>
-                  </div>
-                </div>
-                <div class="span8">
-                  {{#if isHiveCoHost}}
-                    <div class="hostName">
-                      {{selectedHost}}<i class="icon-asterisks">&#10037;</i>
+        {{/if}}
+        <div class="clearfix"></div>
+        <div class="row-fluid">
+          <div class="span12 control-group">
+            <form class="form-horizontal" autocomplete="off">
+              <!-- View for array controller -->
+              {{#each servicesMasters}}
+                <div class="row-fluid">
+                  <div class="span4">
+                    <div class="control-group">
+                      <label class="pts pull-right">
+                        {{#if controller.isReassignHive}}
+                          {{t installer.step5.hiveGroup}}
+                        {{else}}
+                          {{display_name}}:
+                        {{/if}}
+                      </label>
                     </div>
-                  {{else}}
-                    {{view App.SelectHostView
+                  </div>
+                  <div class="span8">
+                    {{#if isHiveCoHost}}
+                      <div class="hostName">
+                        {{selectedHost}}<i class="icon-asterisks">&#10037;</i>
+                      </div>
+                    {{else}}
+                      {{view App.SelectHostView
                       optionValuePath="content.host_name"
                       optionLabelPath="content.host_info"
                       selectedHostBinding="selectedHost"
@@ -68,41 +69,44 @@
                       class="host-select"
                       zIdBinding="zId"
                       disabledBinding="isInstalled"
-                    }}
-                    {{#if showAddControl}}
-                      {{view App.AddControlView componentNameBinding="component_name"}}
-                    {{/if}}
-                    {{#if showRemoveControl}}
-                      {{view App.RemoveControlView componentNameBinding="component_name" zIdBinding="zId"}}
+                      }}
+                      {{#if showAddControl}}
+                        {{view App.AddControlView componentNameBinding="component_name"}}
+                      {{/if}}
+                      {{#if showRemoveControl}}
+                        {{view App.RemoveControlView componentNameBinding="component_name" zIdBinding="zId"}}
+                      {{/if}}
                     {{/if}}
-                  {{/if}}
+                  </div>
                 </div>
-              </div>
-            {{/each}}
-          </form>
+              {{/each}}
+            </form>
+          </div>
         </div>
       </div>
     </div>
-  </div>
 
-  <div class="host-assignments span5">
-    {{#each masterHostMapping}}
-      <div class="mapping-box round-corners well">
-        <div class="hostString"><span>{{hostInfo}}</span></div>
-        {{#each masterServices}}
-          <span {{bindAttr class="isInstalled:assignedService:newService :round-corners"}}>{{display_name}}</span>
-        {{/each}}
-      </div>
-    {{/each}}
+    <div class="host-assignments span5">
+      {{#each masterHostMapping}}
+        <div class="mapping-box round-corners well">
+          <div class="hostString"><span>{{hostInfo}}</span></div>
+          {{#each masterServices}}
+            <span {{bindAttr class="isInstalled:assignedService:newService :round-corners"}}>{{display_name}}</span>
+          {{/each}}
+        </div>
+      {{/each}}
 
-    {{#if remainingHosts}}
-      <div class="remaining-hosts round-corners well">
-        <span><strong>{{remainingHosts}}</strong> {{t installer.step5.attention}}</span></div>
-    {{/if}}
+      {{#if remainingHosts}}
+        <div class="remaining-hosts round-corners well">
+          <span><strong>{{remainingHosts}}</strong> {{t installer.step5.attention}}</span></div>
+      {{/if}}
+    </div>
+    <div class="clearfix"></div>
   </div>
-  <div class="clearfix"></div>
-</div>
+{{else}}
+  <div class="spinner"></div>
+{{/if}}
 <div class="btn-area">
   <a class="btn pull-left" {{action back href="true"}}>&larr; {{t common.back}}</a>
-  <a class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action submit target="controller"}}>{{t common.next}} &rarr;</a>
-</div>
+  <a class="btn btn-success pull-right" {{bindAttr disabled="submitDisabled"}} {{action submit target="controller"}}>{{t common.next}} &rarr;</a>
+</div>

+ 58 - 51
ambari-web/app/templates/wizard/step6.hbs

@@ -22,62 +22,69 @@
   {{#if errorMessage}}
     <div class="alert alert-error">{{errorMessage}}</div>
   {{/if}}
+  {{#if controller.isLoaded}}
+    {{#if view.isLoaded}}
+      <div class="pre-scrollable">
+        <table class="table table-striped" id="component_assign_table">
+          <thead>
+          <tr>
+            <th>{{t common.host}}</th>
+            {{#each header in controller.headers}}
 
-  <div class="pre-scrollable">
-    <table class="table table-striped" id="component_assign_table">
-      <thead>
-        <tr>
-          <th>{{t common.host}}</th>
-          {{#each header in controller.headers}}
-
-            <th>
-              <a href="#" {{bindAttr class="header.allChecked:selected:deselected"}}
-                {{action "selectAllNodes" header target="controller"}}>{{t all}}</a>&nbsp;|&nbsp;<a href="#" {{bindAttr class="header.noChecked:selected:deselected"}}
+              <th>
+                <a href="#" {{bindAttr class="header.allChecked:selected:deselected"}}
+                  {{action "selectAllNodes" header target="controller"}}>{{t all}}</a>&nbsp;|&nbsp;<a href="#" {{bindAttr class="header.noChecked:selected:deselected"}}
                 {{action "deselectAllNodes" header target="controller"}}>{{t none}}</a>
-            </th>
+              </th>
 
-          {{/each}}
-        </tr>
-      </thead>
-      <tbody>
-        {{#if view.pageContent}}
-          {{#each host in view.pageContent}}
-            <tr>
-              {{#view App.WizardStep6HostView hostBinding="host" }}
-                {{host.hostName}}
-                {{#if host.hasMaster}}
-                  <i class=icon-asterisks>&#10037;</i>
-                {{/if}}
-              {{/view}}
-              {{#each checkbox in host.checkboxes}}
-                <td>
-                  <label class="checkbox">
-                    {{#view view.checkboxView checkboxBinding="checkbox"}}
-                      {{checkbox.title}}
-                    {{/view}}
-                  </label>
-                </td>
-              {{/each}}
-            </tr>
-          {{/each}}
-        {{/if}}
-      </tbody>
-    </table>
-  </div>
-  <div id="hosts">
-    <div class="page-bar">
-      <div class="items-on-page">
-        <label>{{t common.show}}: {{view view.rowsPerPageSelectView selectionBinding="view.displayLength"}}</label>
+            {{/each}}
+          </tr>
+          </thead>
+          <tbody>
+          {{#if view.pageContent}}
+            {{#each host in view.pageContent}}
+              <tr>
+                {{#view App.WizardStep6HostView hostBinding="host" }}
+                  {{host.hostName}}
+                  {{#if host.hasMaster}}
+                    <i class=icon-asterisks>&#10037;</i>
+                  {{/if}}
+                {{/view}}
+                {{#each checkbox in host.checkboxes}}
+                  <td>
+                    <label class="checkbox">
+                      {{#view view.checkboxView checkboxBinding="checkbox"}}
+                        {{checkbox.title}}
+                      {{/view}}
+                    </label>
+                  </td>
+                {{/each}}
+              </tr>
+            {{/each}}
+          {{/if}}
+          </tbody>
+        </table>
       </div>
-      <div class="info">{{view.paginationInfo}}</div>
-      <div class="paging_two_button">
-        {{view view.paginationFirst}}
-        {{view view.paginationLeft}}
-        {{view view.paginationRight}}
-        {{view view.paginationLast}}
+      <div id="hosts">
+        <div class="page-bar">
+          <div class="items-on-page">
+            <label>{{t common.show}}: {{view view.rowsPerPageSelectView selectionBinding="view.displayLength"}}</label>
+          </div>
+          <div class="info">{{view.paginationInfo}}</div>
+          <div class="paging_two_button">
+            {{view view.paginationFirst}}
+            {{view view.paginationLeft}}
+            {{view view.paginationRight}}
+            {{view view.paginationLast}}
+          </div>
+        </div>
       </div>
-    </div>
-  </div>
+    {{else}}
+      <div class="spinner"></div>
+    {{/if}}
+  {{else}}
+    <div class="spinner"></div>
+  {{/if}}
   <div class="btn-area">
     <a class="btn" {{action back}}>&larr; {{t common.back}}</a>
     <a class="btn btn-success pull-right" {{action next}}>{{t common.next}} &rarr;</a>

+ 117 - 109
ambari-web/app/templates/wizard/step9.hbs

@@ -22,123 +22,131 @@
 
   <p class="alert alert-info">{{t installer.step9.body}}</p>
 
-  <div id="overallProgress">
-    <div class="row-fluid">
-      <div class="span10">
-        <div {{bindAttr class="view.isStepCompleted::progress-striped view.isStepCompleted::active view.barColor :progress"}}>
-          <div class="bar" {{bindAttr style="view.barWidth"}}>
-          </div>
-        </div>
-      </div>
-      <div class="span2">{{view.progressMessage}}</div>
-    </div>
-  </div>
-
-  <div class="box">
-    <div class="box-header">
-      <div class="pull-left">
-        {{#if controller.showRetry}}
-          <a class="btn btn-primary" href="#" {{action retry}}>
-            <i class="icon-repeat icon-white"></i>
-            {{t common.retry}}
-          </a>
-        {{/if}}
-      </div>
-      <!-- filter by host level -->
-      <div id="host-filter" class="pull-right">
-        <ul class="clearfix">
-          <li class="first">{{t common.show}}:</li>
-          {{#each category in view.categories}}
-            <li {{bindAttr class=":filter-status category.itemClass"}}>
-              <a {{action selectCategory category target="view"}} href="#">
-                {{category.label}}
-              </a>
-            </li>
-            {{#unless category.last}}
-              <li class="divider">|</li>
-            {{/unless}}
-          {{/each}}
-        </ul>
-      </div>
-    </div>
-    <div class="pre-scrollable">
-      <table id="deploy-status-by-host" class="table table-bordered table-striped">
-        <thead>
-        <tr>
-          <th class="host">
-            {{t common.host}}
-          </th>
-          <th class="status">{{t common.status}}</th>
-          <!--  given by the parsing function that parses data from bootstrap call -->
-          <th class="message">{{t common.message}}</th>
-          <!-- retrieved from local storage initially -->
-        </tr>
-        </thead>
+  {{#if view.isLoaded}}
 
-        <tbody>
-          {{#if view.pageContent}}
-            {{#each host in view.pageContent}}
-              {{#view App.HostStatusView objBinding="host" controllerBinding="controller"}}
-              <td>
-                {{host.name}}
-              </td>
-              <td>
-                <div class="progress-bar pull-left">
-                  <div {{bindAttr class="view.isHostCompleted::progress-striped view.isHostCompleted::active view.barColor :progress"}}>
-                    <div class="bar" {{bindAttr style="view.barWidth"}}></div>
-                  </div>
+    <div id="overallProgress">
+        <div class="row-fluid">
+            <div class="span10">
+                <div {{bindAttr class="view.isStepCompleted::progress-striped view.isStepCompleted::active view.barColor :progress"}}>
+                    <div class="bar" {{bindAttr style="view.barWidth"}}>
+                    </div>
                 </div>
-                <div class="progress-percentage pull-left">{{host.progress}}%</div>
-              </td>
-              <td>
-                <a {{bindAttr class="view.isFailed:text-error view.isSuccess:text-success view.isWarning:text-warning"}}
-                    href="javascript:void(null)"
-                    data-toggle="modal" {{action hostLogPopup target="view"}}>{{host.message}}</a>
-              </td>
-              {{/view}}
-            {{/each}}
-          {{else}}
-          <tr>
-            <td colspan="3"><p>{{t installer.step3.hosts.noHosts}}</p></td>
-          </tr>
-          {{/if}}
-        </tbody>
-      </table>
+            </div>
+            <div class="span2">{{view.progressMessage}}</div>
+        </div>
     </div>
-    <div id="hosts">
-      <div class="page-bar">
-        <div class="selected-hosts-info pull-left">
-          {{view.filteredHostsInfo}}
-          -
-          <a {{action showAllHosts target="view"}} href="#">{{t tableView.filters.showAll}}</a>
+
+    <div class="box">
+        <div class="box-header">
+            <div class="pull-left">
+              {{#if controller.showRetry}}
+                  <a class="btn btn-primary" href="#" {{action retry}}>
+                      <i class="icon-repeat icon-white"></i>
+                    {{t common.retry}}
+                  </a>
+              {{/if}}
+            </div>
+            <!-- filter by host level -->
+            <div id="host-filter" class="pull-right">
+                <ul class="clearfix">
+                    <li class="first">{{t common.show}}:</li>
+                  {{#each category in view.categories}}
+                      <li {{bindAttr class=":filter-status category.itemClass"}}>
+                          <a {{action selectCategory category target="view"}} href="#">
+                            {{category.label}}
+                          </a>
+                      </li>
+                    {{#unless category.last}}
+                        <li class="divider">|</li>
+                    {{/unless}}
+                  {{/each}}
+                </ul>
+            </div>
         </div>
-        <div class="items-on-page">
-          <label>{{t common.show}}: {{view view.rowsPerPageSelectView selectionBinding="view.displayLength"}}</label>
+        <div class="pre-scrollable">
+            <table id="deploy-status-by-host" class="table table-bordered table-striped">
+                <thead>
+                <tr>
+                    <th class="host">
+                      {{t common.host}}
+                    </th>
+                    <th class="status">{{t common.status}}</th>
+                    <!--  given by the parsing function that parses data from bootstrap call -->
+                    <th class="message">{{t common.message}}</th>
+                    <!-- retrieved from local storage initially -->
+                </tr>
+                </thead>
+
+                <tbody>
+                {{#if view.pageContent}}
+                  {{#each host in view.pageContent}}
+                    {{#view App.HostStatusView objBinding="host" controllerBinding="controller"}}
+                        <td>
+                          {{host.name}}
+                        </td>
+                        <td>
+                            <div class="progress-bar pull-left">
+                                <div {{bindAttr class="view.isHostCompleted::progress-striped view.isHostCompleted::active view.barColor :progress"}}>
+                                    <div class="bar" {{bindAttr style="view.barWidth"}}></div>
+                                </div>
+                            </div>
+                            <div class="progress-percentage pull-left">{{host.progress}}%</div>
+                        </td>
+                        <td>
+                            <a {{bindAttr class="view.isFailed:text-error view.isSuccess:text-success view.isWarning:text-warning"}}
+                                    href="javascript:void(null)"
+                                    data-toggle="modal" {{action hostLogPopup target="view"}}>{{host.message}}</a>
+                        </td>
+                    {{/view}}
+                  {{/each}}
+                {{else}}
+                    <tr>
+                        <td colspan="3"><p>{{t installer.step3.hosts.noHosts}}</p></td>
+                    </tr>
+                {{/if}}
+                </tbody>
+            </table>
         </div>
-        <div class="info">{{view.paginationInfo}}</div>
-        <div class="paging_two_button">
-          {{view view.paginationFirst}}
-          {{view view.paginationLeft}}
-          {{view view.paginationRight}}
-          {{view view.paginationLast}}
+        <div id="hosts">
+            <div class="page-bar">
+                <div class="selected-hosts-info pull-left">
+                  {{view.filteredHostsInfo}}
+                    -
+                    <a {{action showAllHosts target="view"}} href="#">{{t tableView.filters.showAll}}</a>
+                </div>
+                <div class="items-on-page">
+                    <label>{{t common.show}}: {{view view.rowsPerPageSelectView selectionBinding="view.displayLength"}}</label>
+                </div>
+                <div class="info">{{view.paginationInfo}}</div>
+                <div class="paging_two_button">
+                  {{view view.paginationFirst}}
+                  {{view view.paginationLeft}}
+                  {{view view.paginationRight}}
+                  {{view view.paginationLast}}
+                </div>
+            </div>
         </div>
-      </div>
     </div>
-  </div>
 
-  <div>
-    {{#if view.resultMsg}}
-      <p {{bindAttr class="view.resultMsgColor :alert"}}>{{view.resultMsg}}
-        {{#if view.isHostHeartbeatLost}}
-          <a href="javascript:void(null)"
-             data-toggle="modal" {{action hostWithInstallFailed target="view"}}>{{t common.showDetails}}</a>
-        {{/if}}
-      </p>
-    {{/if}}
-    <div class="btn-area">
-      <button
-          class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action submit target="controller"}}>{{t common.next}} &rarr;</button>
+    <div>
+      {{#if view.resultMsg}}
+          <p {{bindAttr class="view.resultMsgColor :alert"}}>{{view.resultMsg}}
+            {{#if view.isHostHeartbeatLost}}
+                <a href="javascript:void(null)"
+                   data-toggle="modal" {{action hostWithInstallFailed target="view"}}>{{t common.showDetails}}</a>
+            {{/if}}
+          </p>
+      {{/if}}
+        <div class="btn-area">
+            <button
+                    class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action submit target="controller"}}>{{t common.next}} &rarr;</button>
+        </div>
     </div>
-  </div>
+
+  {{else}}
+
+    <div class="spinner"></div>
+
+  {{/if}}
 
 </div>

+ 9 - 1
ambari-web/app/utils/ajax/ajax.js

@@ -2135,8 +2135,12 @@ var urls = {
     'real': '/clusters/{clusterName}/hosts?fields=Hosts/public_host_name&minimal_response=true',
     'mock': ''
   },
+  'hosts.confirmed.install': {
+    'real': '/hosts?fields=Hosts/cpu_count,Hosts/disk_info,Hosts/total_mem&minimal_response=true',
+    'mock': ''
+  },
   'hosts.confirmed': {
-    'real': '/clusters/{clusterName}/hosts?fields=Hosts/cpu_count,Hosts/disk_info,Hosts/total_mem&minimal_response=true',
+    'real': '/clusters/{clusterName}/hosts?fields=Hosts/cpu_count,Hosts/disk_info,Hosts/total_mem,host_components&minimal_response=true',
     'mock': ''
   },
   'host_components.all': {
@@ -2147,6 +2151,10 @@ var urls = {
     'real': '/clusters/{clusterName}/host_components?fields=component/ServiceComponentInfo/service_name,HostRoles/host_name&minimal_response=true',
     'mock': ''
   },
+  'components.get_installed': {
+    'real': '/clusters/{clusterName}/components',
+    'mock': ''
+  },
   'hosts.heatmaps': {
     'real': '/clusters/{clusterName}/hosts?fields=Hosts/host_name,Hosts/maintenance_state,Hosts/public_host_name,Hosts/cpu_count,Hosts/ph_cpu_count,Hosts/total_mem,Hosts/host_status,Hosts/last_heartbeat_time,Hosts/os_arch,Hosts/os_type,Hosts/ip,host_components/HostRoles/state,host_components/HostRoles/maintenance_state,Hosts/disk_info,metrics/disk,metrics/load/load_one,metrics/cpu/cpu_system,metrics/cpu/cpu_user,metrics/memory/mem_total,metrics/memory/mem_free,alerts/summary&minimal_response=true',
     'mock': ''

+ 26 - 0
ambari-web/app/views/main/host/add_view.js

@@ -53,6 +53,32 @@ App.AddHostView = Em.View.extend({
 
  isStepDisabled: function (index) {
     return this.get('controller.isStepDisabled').findProperty('step', index).get('value');
+  },
+
+  didInsertElement: function () {
+    App.ajax.send({
+      name: 'hosts.confirmed',
+      sender: this,
+      data: {
+        clusterName: App.get('clusterName')
+      },
+      success: 'loadConfirmedHostsSuccessCallback'
+    });
+  },
+
+  loadConfirmedHostsSuccessCallback: function (response) {
+    var hosts = {};
+    response.items.mapProperty('Hosts').forEach(function(item){
+      hosts[item.host_name] = {
+        name: item.host_name,
+        cpu: item.cpu_count,
+        memory: item.total_mem,
+        disk_info: item.disk_info,
+        bootStatus: "REGISTERED",
+        isInstalled: true
+      };
+    });
+    this.get('controller').setDBProperty('hosts', hosts);
   }
 
 });

+ 26 - 0
ambari-web/app/views/main/service/add_view.js

@@ -53,6 +53,32 @@ App.AddServiceView = Em.View.extend({
 
   isStepDisabled: function (index) {
     return this.get('controller.isStepDisabled').findProperty('step', index).get('value');
+  },
+
+  didInsertElement: function () {
+    App.ajax.send({
+      name: 'hosts.confirmed',
+      sender: this,
+      data: {
+        clusterName: App.get('clusterName')
+      },
+      success: 'loadConfirmedHostsSuccessCallback'
+    });
+  },
+
+  loadConfirmedHostsSuccessCallback: function (response) {
+    var hosts = {};
+    response.items.mapProperty('Hosts').forEach(function(item){
+      hosts[item.host_name] = {
+        name: item.host_name,
+        cpu: item.cpu_count,
+        memory: item.total_mem,
+        disk_info: item.disk_info,
+        bootStatus: "REGISTERED",
+        isInstalled: true
+      };
+    });
+    this.get('controller').setDBProperty('hosts', hosts);
   }
 
 });

+ 16 - 17
ambari-web/app/views/wizard/step3_view.js

@@ -18,6 +18,7 @@
 
 
 var App = require('app');
+var lazyLoading = require('utils/lazy_loading');
 
 App.WizardStep3View = App.TableView.extend({
 
@@ -28,9 +29,19 @@ App.WizardStep3View = App.TableView.extend({
    * Same to <code>controller.hosts</code>
    * @type {Ember.Enumerable}
    */
-  content:function () {
-    return this.get('controller.hosts');
-  }.property('controller.hosts.length'),
+  content: [],
+
+  contentObserver: function() {
+    this.set('content', []);
+    lazyLoading.run({
+      initSize: 20,
+      chunkSize: 50,
+      delay: 50,
+      destination: this.get('content'),
+      source: this.get('controller.hosts'),
+      context: this
+    });
+  }.observes('controller.hosts.length'),
 
   /**
    * Message with info about registration result
@@ -58,12 +69,6 @@ App.WizardStep3View = App.TableView.extend({
     return this.get('categories').findProperty('isActive');
   }.property('categories.@each.isActive'),
 
-  /**
-   * Message about other registered hosts (not included in current registration)
-   * @type {string}
-   */
-  registeredHostsMessage: '',
-
   /**
    * Number of visible hosts on page
    * @type {string}
@@ -76,6 +81,8 @@ App.WizardStep3View = App.TableView.extend({
    */
   pageChecked: false,
 
+  isLoaded: false,
+
   /**
    * bootStatus category object
    * @type {Ember.Object}
@@ -165,14 +172,6 @@ App.WizardStep3View = App.TableView.extend({
     this.set('selectedHostsCount', selectedHostsCount);
   },
 
-  /**
-   * Update <code>registeredHostsMessage</code> according to <code>controller.registeredHots.length</code>
-   * @method setRegisteredHosts
-   */
-  setRegisteredHosts: function(){
-    this.set('registeredHostsMessage',Em.I18n.t('installer.step3.warning.registeredHosts').format(this.get('controller.registeredHosts').length));
-  }.observes('controller.registeredHosts'),
-
   /**
    * Call filters and counters one time
    * @method hostBootStatusObserver

+ 14 - 3
ambari-web/app/views/wizard/step6_view.js

@@ -18,6 +18,7 @@
 
 
 var App = require('app');
+var lazyLoading = require('utils/lazy_loading');
 
 App.WizardStep6View = App.TableView.extend({
 
@@ -35,9 +36,19 @@ App.WizardStep6View = App.TableView.extend({
    * List of hosts
    * @type {object[]}
    */
-  content: function () {
-    return this.get('controller.hosts');
-  }.property('controller.hosts'),
+  content: [],
+
+  contentObserver: function() {
+    this.set('content', []);
+    lazyLoading.run({
+      initSize: 20,
+      chunkSize: 50,
+      delay: 50,
+      destination: this.get('content'),
+      source: this.get('controller.hosts'),
+      context: this
+    });
+  }.observes('controller.hosts.length'),
 
   /**
    * Synonym to <code>content</code> in this <code>App.TableView</code>

+ 16 - 3
ambari-web/app/views/wizard/step9_view.js

@@ -18,6 +18,7 @@
 
 var App = require('app');
 var date = require('utils/date');
+var lazyLoading = require('utils/lazy_loading');
 
 App.WizardStep9View = App.TableView.extend({
 
@@ -55,13 +56,25 @@ App.WizardStep9View = App.TableView.extend({
    */
   displayLength: "25",
 
+  isLoaded: false,
+
   /**
    * Same to <code>controller.hosts</code>
    * @type {object[]}
    */
-  content: function () {
-    return this.get('controller.hosts');
-  }.property('controller.hosts'),
+  content: [],
+
+  contentObserver: function() {
+    this.set('content', []);
+    lazyLoading.run({
+      initSize: 20,
+      chunkSize: 50,
+      delay: 50,
+      destination: this.get('content'),
+      source: this.get('controller.hosts'),
+      context: this
+    });
+  }.observes('controller.hosts.length'),
 
   /**
    * Active category