Переглянути джерело

AMBARI-12463. Decrease initial application load time. (jaimin)

Jaimin Jetly 10 роки тому
батько
коміт
a6c86eec9b
63 змінених файлів з 843 додано та 915 видалено
  1. 79 179
      ambari-web/app/controllers/global/cluster_controller.js
  2. 2 2
      ambari-web/app/controllers/global/update_controller.js
  3. 27 0
      ambari-web/app/controllers/main.js
  4. 1 1
      ambari-web/app/controllers/main/admin/highAvailability/nameNode/step5_controller.js
  5. 0 5
      ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
  6. 1 1
      ambari-web/app/controllers/main/admin/kerberos/wizard_controller.js
  7. 0 7
      ambari-web/app/controllers/main/alert_definitions_controller.js
  8. 0 1
      ambari-web/app/controllers/main/host/details.js
  9. 2 2
      ambari-web/app/controllers/main/service.js
  10. 2 2
      ambari-web/app/controllers/main/service/add_controller.js
  11. 2 2
      ambari-web/app/controllers/main/service/info/configs.js
  12. 0 1
      ambari-web/app/controllers/main/service/item.js
  13. 1 1
      ambari-web/app/controllers/main/service/reassign/step4_controller.js
  14. 0 62
      ambari-web/app/controllers/main/service/reassign_controller.js
  15. 6 5
      ambari-web/app/controllers/wizard/step7_controller.js
  16. 10 12
      ambari-web/app/controllers/wizard/step8_controller.js
  17. 0 4
      ambari-web/app/mappers/alert_definition_summary_mapper.js
  18. 0 3
      ambari-web/app/mappers/alert_definitions_mapper.js
  19. 2 3
      ambari-web/app/mappers/cluster_mapper.js
  20. 20 14
      ambari-web/app/mappers/components_state_mapper.js
  21. 0 5
      ambari-web/app/mappers/racks_mapper.js
  22. 2 0
      ambari-web/app/mappers/service_mapper.js
  23. 1 1
      ambari-web/app/messages.js
  24. 1 1
      ambari-web/app/mixins/common/serverValidator.js
  25. 1 1
      ambari-web/app/mixins/wizard/addSecurityConfigs.js
  26. 1 1
      ambari-web/app/mixins/wizard/wizardProgressPageController.js
  27. 1 0
      ambari-web/app/models.js
  28. 8 14
      ambari-web/app/models/cluster.js
  29. 28 0
      ambari-web/app/models/master_component.js
  30. 8 0
      ambari-web/app/models/service.js
  31. 33 24
      ambari-web/app/router.js
  32. 90 77
      ambari-web/app/routes/add_service_routes.js
  33. 16 11
      ambari-web/app/routes/main.js
  34. 8 6
      ambari-web/app/templates/application.hbs
  35. 59 46
      ambari-web/app/templates/main/alerts.hbs
  36. 42 36
      ambari-web/app/templates/main/host/host_alerts.hbs
  37. 40 34
      ambari-web/app/templates/main/service/services/hbase.hbs
  38. 75 57
      ambari-web/app/templates/main/service/services/hdfs.hbs
  39. 52 47
      ambari-web/app/templates/main/service/services/storm.hbs
  40. 41 36
      ambari-web/app/templates/main/service/services/yarn.hbs
  41. 1 1
      ambari-web/app/utils/ajax/ajax.js
  42. 23 6
      ambari-web/app/utils/components.js
  43. 1 1
      ambari-web/app/utils/http_client.js
  44. 1 1
      ambari-web/app/utils/updater.js
  45. 21 5
      ambari-web/app/views/main/dashboard/widgets/datanode_live.js
  46. 6 2
      ambari-web/app/views/main/dashboard/widgets/node_managers_live.js
  47. 6 2
      ambari-web/app/views/main/dashboard/widgets/supervisor_live.js
  48. 16 6
      ambari-web/app/views/main/host/details/host_component_view.js
  49. 16 12
      ambari-web/app/views/main/host/summary.js
  50. 4 1
      ambari-web/app/views/main/service/info/configs.js
  51. 2 2
      ambari-web/app/views/main/service/reassign/step5_view.js
  52. 0 117
      ambari-web/test/controllers/global/cluster_controller_test.js
  53. 5 5
      ambari-web/test/controllers/main/admin/kerberos/step4_controller_test.js
  54. 22 1
      ambari-web/test/controllers/main/host/details_test.js
  55. 2 2
      ambari-web/test/controllers/main/service/add_controller_test.js
  56. 0 3
      ambari-web/test/controllers/main/service/item_test.js
  57. 14 10
      ambari-web/test/controllers/main/service/reassign/step4_controller_test.js
  58. 1 1
      ambari-web/test/controllers/main/service_test.js
  59. 5 1
      ambari-web/test/controllers/wizard/step8_test.js
  60. 10 1
      ambari-web/test/mixins/wizard/wizardProgressPageController_test.js
  61. 11 13
      ambari-web/test/router_test.js
  62. 9 1
      ambari-web/test/views/main/dashboard/widgets/node_managers_live_test.js
  63. 5 17
      ambari-web/test/views/main/host/details/host_component_view_test.js

+ 79 - 179
ambari-web/app/controllers/global/cluster_controller.js

@@ -25,15 +25,21 @@ App.ClusterController = Em.Controller.extend({
   ambariProperties: null,
   clusterDataLoadedPercent: 'width:0', // 0 to 1
 
-  isGangliaUrlLoaded: false,
+  isClusterNameLoaded: false,
 
-  /**
-   * Provides the URL to use for Ganglia server. This URL
-   * is helpful in populating links in UI.
-   *
-   * If null is returned, it means GANGLIA service is not installed.
-   */
-  gangliaUrl: null,
+  isAlertsLoaded: false,
+
+  isComponentsStateLoaded: false,
+
+  isHostsLoaded: false,
+
+  isConfigsPropertiesLoaded: false,
+
+  isStackConfigsLoaded: false,
+
+  isHostContentLoaded: function () {
+    return this.get('isHostsLoaded') && this.get('isComponentsStateLoaded');
+  }.property('isHostsLoaded', 'isComponentsStateLoaded'),
 
   clusterName: function () {
     return App.get('clusterName');
@@ -62,18 +68,9 @@ App.ClusterController = Em.Controller.extend({
   },
 
   dataLoadList: Em.Object.create({
-    'hosts': false,
     'serviceMetrics': false,
     'stackComponents': false,
-    'services': false,
-    'cluster': false,
-    'clusterStatus': false,
-    'racks': false,
-    'componentConfigs': false,
-    'componentsState': false,
-    'rootService': false,
-    'alertDefinitions': false,
-    'securityStatus': false
+    'services': false
   }),
 
   /**
@@ -84,6 +81,7 @@ App.ClusterController = Em.Controller.extend({
 
     if (App.get('clusterName') && !reload) {
       App.set('clusterName', this.get('clusterName'));
+      this.set('isClusterNameLoaded', true);
       dfd.resolve();
     } else {
       App.ajax.send({
@@ -105,6 +103,8 @@ App.ClusterController = Em.Controller.extend({
     if (data.items && data.items.length > 0) {
       App.set('clusterName', data.items[0].Clusters.cluster_name);
       App.set('currentStackVersion', data.items[0].Clusters.version);
+      this.set('isClusterNameLoaded', true);
+      App.set('isKerberosEnabled', data.items[0].Clusters.security_type === 'KERBEROS');
     }
   },
 
@@ -151,51 +151,6 @@ App.ClusterController = Em.Controller.extend({
     return (App.get('testMode')) ? testUrl : App.get('apiPrefix') + '/clusters/' + App.get('clusterName') + url;
   },
 
-  setGangliaUrl: function () {
-    if (App.get('testMode')) {
-      this.set('gangliaUrl', 'http://gangliaserver/ganglia/?t=yes');
-      this.set('isGangliaUrlLoaded', true);
-    } else {
-      // We want live data here
-      var gangliaServer = App.HostComponent.find().findProperty('componentName', 'GANGLIA_SERVER');
-      if (this.get('isLoaded') && gangliaServer) {
-        this.set('isGangliaUrlLoaded', false);
-        App.ajax.send({
-          name: 'hosts.for_quick_links',
-          sender: this,
-          data: {
-            clusterName: App.get('clusterName'),
-            masterHosts: gangliaServer.get('hostName'),
-            urlParams: ''
-          },
-          success: 'setGangliaUrlSuccessCallback'
-        });
-      }
-    }
-  }.observes('App.router.updateController.isUpdated', 'dataLoadList.hosts', 'gangliaWebProtocol', 'isLoaded'),
-
-  setGangliaUrlSuccessCallback: function (response) {
-    var url = null;
-    if (response.items.length > 0) {
-      url = this.get('gangliaWebProtocol') + "://" + (App.singleNodeInstall ? App.singleNodeAlias + ":42080" : response.items[0].Hosts.public_host_name) + "/ganglia";
-    }
-    this.set('gangliaUrl', url);
-    this.set('isGangliaUrlLoaded', true);
-  },
-
-  gangliaWebProtocol: function () {
-    var properties = this.get('ambariProperties');
-    if (properties && properties.hasOwnProperty('ganglia.https') && properties['ganglia.https']) {
-      return "https";
-    } else {
-      return "http";
-    }
-  }.property('ambariProperties'),
-
-  isGangliaInstalled: function () {
-    return !!App.Service.find().findProperty('serviceName', 'GANGLIA');
-  }.property('App.router.updateController.isUpdated', 'dataLoadList.serviceMetrics'),
-
   /**
    *  load all data and update load status
    */
@@ -213,113 +168,88 @@ App.ClusterController = Em.Controller.extend({
     }
 
     var clusterUrl = this.getUrl('/data/clusters/cluster.json', '?fields=Clusters');
-    var racksUrl = "/data/racks/racks.json";
-
-
     var hostsController = App.router.get('mainHostController');
     hostsController.set('isCountersUpdating', true);
     hostsController.updateStatusCounters();
 
-    App.HttpClient.get(racksUrl, App.racksMapper, {
-      complete: function (jqXHR, textStatus) {
-        self.updateLoadStatus('racks');
-      }
-    }, function (jqXHR, textStatus) {
-      self.updateLoadStatus('racks');
-    });
-
     App.HttpClient.get(clusterUrl, App.clusterMapper, {
       complete: function (jqXHR, textStatus) {
-        self.updateLoadStatus('cluster');
       }
     }, function (jqXHR, textStatus) {
-      self.updateLoadStatus('cluster');
     });
 
-    if (App.get('testMode')) {
-      self.updateLoadStatus('clusterStatus');
-    } else {
-      App.clusterStatus.updateFromServer().complete(function () {
-        self.updateLoadStatus('clusterStatus');
-        if (App.get('supports.stackUpgrade')) {
-          self.restoreUpgradeState();
-        }
-      });
+
+    if (App.get('supports.stackUpgrade')) {
+      self.restoreUpgradeState();
     }
 
+
+    var updater = App.router.get('updateController');
+
     /**
      * Order of loading:
      * 1. load all created service components
-     * 2. request for service components supported by stack
-     * 3. load stack components to model
-     * 4. request for services
-     * 5. put services in cache
-     * 6. request for hosts and host-components (single call)
-     * 7. request for service metrics
-     * 8. load host-components to model
-     * 9. load hosts to model
-     * 10. load services from cache with metrics to model
-     * 11. update stale_configs of host-components (depends on App.supports.hostOverrides)
-     * 12. load root service (Ambari)
-     * 13. load alert definitions to model
-     * 14. load unhealthy alert instances
-     * 15. load security status
+     * 1. request for service components supported by stack
+     * 2. load stack components to model
+     * 3. request for services
+     * 4. put services in cache
+     * 5. request for hosts and host-components (single call)
+     * 6. request for service metrics
+     * 7. load host-components to model
+     * 8. load services from cache with metrics to model
      */
-    self.loadServiceComponents(function () {
-      self.loadStackServiceComponents(function (data) {
-        data.items.forEach(function (service) {
-          service.StackServices.is_selected = true;
-          service.StackServices.is_installed = false;
-        }, self);
-        App.stackServiceMapper.mapStackServices(data);
-        App.config.setPreDefinedServiceConfigs(true);
-        var updater = App.router.get('updateController');
-        self.updateLoadStatus('stackComponents');
-        updater.updateServices(function () {
-          self.updateLoadStatus('services');
-          //force clear filters  for hosts page to load all data
-          App.db.setFilterConditions('mainHostController', null);
-
-          updater.updateHost(function () {
-            self.updateLoadStatus('hosts');
+    self.loadStackServiceComponents(function (data) {
+      data.items.forEach(function (service) {
+        service.StackServices.is_selected = true;
+        service.StackServices.is_installed = false;
+      }, self);
+      App.stackServiceMapper.mapStackServices(data);
+      App.config.setPreDefinedServiceConfigs(true);
+      self.updateLoadStatus('stackComponents');
+      updater.updateServices(function () {
+        self.updateLoadStatus('services');
+        updater.updateServiceMetric(function () {
+          self.updateLoadStatus('serviceMetrics');
+          App.config.loadConfigsFromStack(App.Service.find().mapProperty('serviceName')).complete(function () {
+            self.set('isConfigsPropertiesLoaded', true);
           });
+        });
+      });
+    });
+
+    //force clear filters  for hosts page to load all data
+    App.db.setFilterConditions('mainHostController', null);
+
+    // hosts loading doesn't affect overall progress
+    updater.updateHost(function () {
+      self.set('isHostsLoaded', true);
+    });
 
-          updater.updateServiceMetric(function () {
-            App.config.loadClusterConfigsFromStack();
-            App.config.loadConfigsFromStack(App.Service.find().mapProperty('serviceName')).complete(function () {
-              updater.updateComponentConfig(function () {
-                self.updateLoadStatus('componentConfigs');
-              });
-
-              updater.updateComponentsState(function () {
-                self.updateLoadStatus('componentsState');
-              });
-              self.updateLoadStatus('serviceMetrics');
-
-              updater.updateAlertGroups(function () {
-                updater.updateAlertDefinitions(function () {
-                  updater.updateAlertDefinitionSummary(function () {
-                    updater.updateUnhealthyAlertInstances(function () {
-                      self.updateLoadStatus('alertGroups');
-                      self.updateLoadStatus('alertDefinitions');
-                      self.updateLoadStatus('alertInstancesUnhealthy');
-                    });
-                  });
-                });
-              });
-            });
+    // alerts loading doesn't affect overall progress
+    updater.updateAlertGroups(function () {
+      updater.updateAlertDefinitions(function () {
+        updater.updateAlertDefinitionSummary(function () {
+          updater.updateUnhealthyAlertInstances(function () {
+            self.set('isAlertsLoaded', true);
           });
         });
-        self.loadRootService().done(function (data) {
-          App.rootServiceMapper.map(data);
-          self.updateLoadStatus('rootService');
-        });
-        // load security status
-        App.router.get('mainAdminKerberosController').getSecurityStatus().always(function () {
-          self.updateLoadStatus('securityStatus');
-        });
       });
     });
+    // components state and config loading doesn't affect overall progress
+    updater.updateComponentConfig(Em.K);
+    updater.updateComponentsState(function () {
+      self.set('isComponentsStateLoaded', true);
+    });
+
+    /*  Root service mapper maps all the data exposed under Ambari root service which includes ambari configurations i.e ambari-properties
+     ** This is useful information but its not being used in the code anywhere as of now
+
+     self.loadRootService().done(function (data) {
+     App.rootServiceMapper.map(data);
+     self.updateLoadStatus('rootService');
+     });
+
+     */
   },
 
   /**
@@ -327,7 +257,7 @@ App.ClusterController = Em.Controller.extend({
    * and make call to get latest status from server
    */
   restoreUpgradeState: function () {
-    this.getAllUpgrades().done(function (data) {
+    return this.getAllUpgrades().done(function (data) {
       var upgradeController = App.router.get('mainAdminStackAndUpgradeController');
       var lastUpgradeData = data.items.sortProperty('Upgrade.request_id').pop();
       var dbUpgradeState = App.db.get('MainAdminStackAndUpgrade', 'upgradeState');
@@ -370,36 +300,6 @@ App.ClusterController = Em.Controller.extend({
     }, callback)
   },
 
-  /**
-   * Load data about created service components
-   * @param callback
-   */
-  loadServiceComponents: function (callback) {
-    App.ajax.send({
-      name: 'service.components.load',
-      sender: this,
-      data: {
-        callback: callback
-      },
-      success: 'loadStackServiceComponentsSuccess'
-    });
-  },
-
-  /**
-   * Callback for load service components request
-   * @param data
-   * @param request
-   * @param params
-   */
-  loadStackServiceComponentsSuccess: function (data, request, params) {
-    var serviceComponents = [];
-    data.items.forEach(function (service) {
-      serviceComponents = serviceComponents.concat(service.components.mapProperty('ServiceComponentInfo.component_name'));
-    });
-    App.serviceComponents = serviceComponents;
-    params.callback();
-  },
-
   /**
    *
    * @param callback

+ 2 - 2
ambari-web/app/controllers/global/update_controller.js

@@ -496,7 +496,7 @@ App.UpdateController = Em.Controller.extend({
   },
   updateServices: function (callback) {
     var testUrl = '/data/services/HDP2/services.json';
-    var componentConfigUrl = this.getUrl(testUrl, '/services?fields=ServiceInfo/state,ServiceInfo/maintenance_state&minimal_response=true');
+    var componentConfigUrl = this.getUrl(testUrl, '/services?fields=ServiceInfo/state,ServiceInfo/maintenance_state,components/ServiceComponentInfo/component_name&minimal_response=true');
     App.HttpClient.get(componentConfigUrl, App.serviceMapper, {
       complete: callback
     });
@@ -510,7 +510,7 @@ App.UpdateController = Em.Controller.extend({
   },
   updateComponentsState: function (callback) {
     var testUrl = '/data/services/HDP2/components_state.json';
-    var realUrl = '/components/?ServiceComponentInfo/category.in(SLAVE,CLIENT)&fields=ServiceComponentInfo/service_name,' +
+    var realUrl = '/components/?fields=ServiceComponentInfo/service_name,' +
       'ServiceComponentInfo/category,ServiceComponentInfo/installed_count,ServiceComponentInfo/started_count,ServiceComponentInfo/total_count,host_components/HostRoles/host_name&minimal_response=true';
     var url = this.getUrl(testUrl, realUrl);
 

+ 27 - 0
ambari-web/app/controllers/main.js

@@ -64,6 +64,33 @@ App.MainController = Em.Controller.extend({
     return dfd.promise();
   },
 
+  /**
+   *
+   * @param isLoaded {Boolean}
+   * @param opts {Object}
+   * {
+   *   period {Number}
+   * }
+   * @return {*|{then}}
+   */
+  isLoading: function(isLoaded, opts) {
+    var dfd = $.Deferred();
+    var self = this;
+    opts = opts || {};
+    var period =  opts.period || 20;
+    if (this.get(isLoaded)) {
+      dfd.resolve();
+    } else {
+      var interval = setInterval(function () {
+        if (self.get(isLoaded)) {
+          dfd.resolve();
+          clearInterval(interval);
+        }
+      }, period);
+    }
+    return dfd.promise();
+  },
+
   startPolling: function () {
     if (App.router.get('applicationController.isExistingClusterDataLoaded')) {
       App.router.get('updateController').set('isWorking', true);

+ 1 - 1
ambari-web/app/controllers/main/admin/highAvailability/nameNode/step5_controller.js

@@ -59,7 +59,7 @@ App.HighAvailabilityWizardStep5Controller = App.HighAvailabilityProgressPageCont
 
   reconfigureHDFS: function () {
     var data = this.get('content.serviceConfigProperties');
-    if (App.router.get('mainAdminKerberosController.securityEnabled')) {
+    if (App.get('isKerberosEnabled')) {
       this.reconfigureSecureHDFS();
     } else {
       this.updateConfigProperties(data);

+ 0 - 5
ambari-web/app/controllers/main/admin/kerberos/step2_controller.js

@@ -134,15 +134,10 @@ App.KerberosWizardStep2Controller = App.WizardStep7Controller.extend({
     this.set('isSubmitDisabled', true);
     var self = this;
     this.deleteKerberosService().always(function (data) {
-      self.removeLocalKerberosComponentData();
       self.configureKerberos();
     });
   },
 
-  removeLocalKerberosComponentData: function () {
-    App.serviceComponents.removeObject('KERBEROS_CLIENT');
-  },
-
   configureKerberos: function () {
     var self = this;
     var wizardController = App.router.get(this.get('content.controllerName'));

+ 1 - 1
ambari-web/app/controllers/main/admin/kerberos/wizard_controller.js

@@ -190,7 +190,7 @@ App.KerberosWizardController = App.WizardController.extend({
   createKerberosResources: function (callback) {
     var self = this;
     this.createKerberosService().done(function () {
-      componentsUtils.createServiceComponent('KERBEROS_CLIENT').done(function () {
+      componentsUtils.updateAndCreateServiceComponent('KERBEROS_CLIENT').done(function () {
         self.createKerberosHostComponents().done(callback);
       });
     });

+ 0 - 7
ambari-web/app/controllers/main/alert_definitions_controller.js

@@ -22,13 +22,6 @@ App.MainAlertDefinitionsController = Em.ArrayController.extend({
 
   name: 'mainAlertDefinitionsController',
 
-  /**
-   * Timestamp when <code>App.alertDefinitionsMapper</code> run last time
-   * Current <code>content</code> is updated on when it changed
-   * @type {number|null}
-   */
-  mapperTimestamp: null,
-
   /**
    * Define whether restore filter conditions from local db
    * @type {Boolean}

+ 0 - 1
ambari-web/app/controllers/main/host/details.js

@@ -2122,7 +2122,6 @@ App.MainHostDetailsController = Em.Controller.extend({
       var component = event.context;
       var reassignMasterController = App.router.get('reassignMasterController');
       reassignMasterController.saveComponentToReassign(component);
-      reassignMasterController.getSecurityStatus();
       reassignMasterController.setCurrentStep('1');
       App.router.transitionTo('reassign');
     });

+ 2 - 2
ambari-web/app/controllers/main/service.js

@@ -37,11 +37,11 @@ App.MainServiceController = Em.ArrayController.extend({
    * @type {Ember.Object}
    */
   cluster: function () {
-    if (!App.router.get('clusterController.isLoaded')) {
+    if (!App.router.get('clusterController.isClusterDataLoaded')) {
       return null;
     }
     return App.Cluster.find().objectAt(0);
-  }.property('App.router.clusterController.isLoaded'),
+  }.property('App.router.clusterController.isClusterDataLoaded'),
 
   /**
    * Check if all services are installed

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

@@ -297,7 +297,7 @@ App.AddServiceController = App.WizardController.extend(App.AddSecurityConfigs, {
   loadKerberosDescriptorConfigs: function() {
     var self = this,
         dfd = $.Deferred();
-    if (App.router.get('mainAdminKerberosController.securityEnabled')) {
+    if (App.get('isKerberosEnabled')) {
       this.getDescriptorConfigs().then(function(properties) {
         self.set('kerberosDescriptorConfigs', properties);
       }).always(function(){
@@ -589,7 +589,7 @@ App.AddServiceController = App.WizardController.extend(App.AddSecurityConfigs, {
   },
 
   checkSecurityStatus: function() {
-    if (!App.router.get('mainAdminKerberosController.securityEnabled')) {
+    if (!App.get('isKerberosEnabled')) {
       this.set('skipConfigureIdentitiesStep', true);
       this.get('isStepDisabled').findProperty('step', 5).set('value', true);
     }

+ 2 - 2
ambari-web/app/controllers/main/service/info/configs.js

@@ -113,7 +113,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
     return App.StackConfigProperty.find().filter(function(scp) {
       return this.get('servicesToLoad').contains(scp.get('serviceName'));
     }, this);
-  }.property('content.serviceName'),
+  }.property('content.serviceName', 'App.router.clusterController.isStackConfigsLoaded'),
 
   /**
    * @type {boolean}
@@ -542,7 +542,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
   onLoadOverrides: function (allConfigs) {
     this.get('servicesToLoad').forEach(function(serviceName) {
       var configGroups = serviceName == this.get('content.serviceName') ? this.get('configGroups') : this.get('dependentConfigGroups').filterProperty('serviceName', serviceName);
-      var serviceNames = [ serviceName ]
+      var serviceNames = [ serviceName ];
       if(serviceName === 'OOZIE') {
         // For Oozie, also add ELService properties which are marked as FALCON properties.
         serviceNames.push('FALCON')

+ 0 - 1
ambari-web/app/controllers/main/service/item.js

@@ -575,7 +575,6 @@ App.MainServiceItemController = Em.Controller.extend({
     if (component) {
       var reassignMasterController = App.router.get('reassignMasterController');
       reassignMasterController.saveComponentToReassign(component);
-      reassignMasterController.getSecurityStatus();
       reassignMasterController.setCurrentStep('1');
       App.router.transitionTo('reassign');
     }

+ 1 - 1
ambari-web/app/controllers/main/service/reassign/step4_controller.js

@@ -757,7 +757,7 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
    * @return {Boolean}
    */
   setSecureConfigs: function (secureConfigs, configs, componentName) {
-    var securityEnabled = this.get('content.securityEnabled');
+    var securityEnabled = App.get('isKerberosEnabled');
     var component = this.get('secureConfigsMap').findProperty('componentName', componentName);
     if (Em.isNone(component) || !securityEnabled) return false;
 

+ 0 - 62
ambari-web/app/controllers/main/service/reassign_controller.js

@@ -59,7 +59,6 @@ App.ReassignMasterController = App.WizardController.extend({
     hasManualSteps: false,
     hasCheckDBStep: false,
     componentsWithCheckDBStep: ['HIVE_METASTORE', 'HIVE_SERVER', 'OOZIE_SERVER'],
-    securityEnabled: false,
     componentsWithoutSecurityConfigs: ['MYSQL_SERVER']
   }),
 
@@ -73,7 +72,6 @@ App.ReassignMasterController = App.WizardController.extend({
     'masterComponentHosts',
     'serviceComponents',
     'masterComponent',
-    'securityEnabled',
     'currentStep',
     'reassignHosts',
     'tasksStatuses',
@@ -89,55 +87,6 @@ App.ReassignMasterController = App.WizardController.extend({
     this.set('content.hasCheckDBStep', this.get('content.componentsWithCheckDBStep').contains(this.get('content.reassign.component_name')));
   }.observes('content.reassign.component_name'),
 
-  getSecurityStatus: function () {
-    if (App.get('testMode')) {
-      this.set('securityEnabled', !App.get('testEnableSecurity'));
-    } else {
-      //get Security Status From Server
-      App.ajax.send({
-        name: 'config.tags',
-        sender: this,
-        success: 'getSecurityStatusSuccessCallback',
-        error: 'errorCallback'
-      });
-    }
-  },
-
-  errorCallback: function () {
-    console.error('Cannot get security status from server');
-  },
-
-  getSecurityStatusSuccessCallback: function (data) {
-    var configs = data.Clusters.desired_configs;
-    if ('cluster-env' in configs) {
-      this.getServiceConfigsFromServer(configs['cluster-env'].tag);
-    }
-    else {
-      console.error('Cannot get security status from server');
-    }
-  },
-
-  getServiceConfigsFromServer: function (tag) {
-    var self = this;
-    var tags = [
-      {
-        siteName: "cluster-env",
-        tagName: tag
-      }
-    ];
-    App.router.get('configurationController').getConfigsByTags(tags).done(function (data) {
-      var configs = data.findProperty('tag', tag).properties;
-      var result = configs && (configs['security_enabled'] === 'true' || configs['security_enabled'] === true);
-      self.saveSecurityEnabled(result);
-      App.clusterStatus.setClusterStatus({
-        clusterName: self.get('content.cluster.name'),
-        clusterState: 'DEFAULT',
-        wizardControllerName: 'reassignMasterController',
-        localdb: App.db.data
-      });
-    });
-  },
-
   /**
    * Load tasks statuses for step5 of Reassign Master Wizard to restore installation
    */
@@ -250,17 +199,6 @@ App.ReassignMasterController = App.WizardController.extend({
     this.set('content.reassignHosts', reassignHosts);
   },
 
-
-  saveSecurityEnabled: function (securityEnabled) {
-    this.setDBProperty('securityEnabled', securityEnabled);
-    this.set('content.securityEnabled', securityEnabled);
-  },
-
-  loadSecurityEnabled: function () {
-    var securityEnabled = this.getDBProperty('securityEnabled');
-    this.set('content.securityEnabled', securityEnabled);
-  },
-
   saveSecureConfigs: function (secureConfigs) {
     this.setDBProperty('secureConfigs', secureConfigs);
     this.set('content.secureConfigs', secureConfigs);

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

@@ -58,11 +58,12 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
   secureConfigs: require('data/HDP2/secure_mapping'),
 
   /**
-   * uses for add service - find out is security is enabled
+   * config categories with secure properties
+   * use only for add service wizard when security is enabled;
    */
-  securityEnabled: function () {
-    return App.router.get('mainAdminKerberosController.securityEnabled');
-  }.property('App.router.mainAdminKerberosController.securityEnabled'),
+  secureServices: function () {
+    return $.extend(true, [], require('data/HDP2/secure_configs'));
+  }.property(),
 
   /**
    * If configChangeObserver Modal is shown
@@ -653,7 +654,7 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
       }
     }, this);
     //STEP 6: Distribute configs by service and wrap each one in App.ServiceConfigProperty (configs -> serviceConfigs)
-    if (this.get('securityEnabled') && this.get('wizardController.name') == 'addServiceController') {
+    if (App.get('isKerberosEnabled') && this.get('wizardController.name') == 'addServiceController') {
       this.addKerberosDescriptorConfigs(configs, this.get('wizardController.kerberosDescriptorConfigs') || []);
     }
     this.setStepConfigs(configs, storedConfigs);

+ 10 - 12
ambari-web/app/controllers/wizard/step8_controller.js

@@ -120,14 +120,6 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz
    */
   serviceConfigTags: [],
 
-  /**
-   * Is cluster security enabled
-   * @type {bool}
-   */
-  securityEnabled: function () {
-    return App.router.get('mainAdminKerberosController.securityEnabled');
-  }.property('App.router.mainAdminKerberosController.securityEnabled'),
-
   /**
    * Selected config group
    * @type {Object}
@@ -742,7 +734,7 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz
       this.set('isSubmitDisabled', true);
       this.set('isBackBtnDisabled', true);
       wizardController.setLowerStepsDisable(wizardController.get('currentStep'));
-      if (this.get('content.controllerName') != 'installerController' && this.get('securityEnabled') && !this.get('isManualKerberos')) {
+      if (this.get('content.controllerName') != 'installerController' && App.get('isKerberosEnabled') && !this.get('isManualKerberos')) {
         App.get('router.mainAdminKerberosController').getKDCSessionState(this.submitProceed.bind(this), function () {
           self.set('isSubmitDisabled', false);
           self.set('isBackBtnDisabled', false);
@@ -990,7 +982,7 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz
     if (this.get('content.controllerName') !== 'addHostController') {
       if (this.get('content.controllerName') === 'addServiceController') {
         // for manually enabled Kerberos descriptor was updated on transition to this step
-        if (this.get('securityEnabled') && !this.get('isManualKerberos')) {
+        if (App.get('isKerberosEnabled') && !this.get('isManualKerberos')) {
           this.updateKerberosDescriptor();
         }
       }
@@ -1090,8 +1082,14 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz
     }, this);
 
     if (this.get('content.controllerName') === 'addHostController') {
+      var allServiceComponents = [];
+      var services = App.Service.find().mapProperty('serviceName');
+      services.forEach(function(_service){
+        var _serviceComponents = App.Service.find(_service).get('serviceComponents');
+        allServiceComponents = allServiceComponents.concat(_serviceComponents);
+      }, this);
       this.get('content.slaveComponentHosts').forEach(function (component) {
-        if (component.componentName !== 'CLIENT' && !App.serviceComponents.contains(component.componentName)) {
+        if (component.componentName !== 'CLIENT' && !allServiceComponents.contains(component.componentName)) {
           this.addRequestToCreateComponent(
               [{"ServiceComponentInfo": {"component_name": component.componentName}}],
               App.StackServiceComponent.find().findProperty('componentName', component.componentName).get('serviceName')
@@ -1099,7 +1097,7 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz
         }
       }, this);
       this.get('content.clients').forEach(function (component) {
-        if (!App.serviceComponents.contains(component.component_name)) {
+        if (!allServiceComponents.contains(component.component_name)) {
           this.addRequestToCreateComponent(
               [{"ServiceComponentInfo": {"component_name": component.component_name}}],
               App.StackServiceComponent.find().findProperty('componentName', component.component_name).get('serviceName')

+ 0 - 4
ambari-web/app/mappers/alert_definition_summary_mapper.js

@@ -55,9 +55,5 @@ App.alertDefinitionSummaryMapper = App.QuickDataMapper.create({
       }
     });
 
-    if (App.router.get('mainAlertDefinitionsController')) {
-      App.router.set('mainAlertDefinitionsController.mapperTimestamp', (new Date()).getTime());
-    }
-
   }
 });

+ 0 - 3
ambari-web/app/mappers/alert_definitions_mapper.js

@@ -189,9 +189,6 @@ App.alertDefinitionsMapper = App.QuickDataMapper.create({
       App.store.loadMany(this.get('metricsUriModel'), alertMetricsUriDefinitions);
       App.store.loadMany(this.get('model'), alertDefinitions);
       this.setAlertDefinitionsRawSourceData(rawSourceData);
-      if (App.router.get('mainAlertDefinitionsController')) {
-        App.router.set('mainAlertDefinitionsController.mapperTimestamp', (new Date()).getTime());
-      }
       App.store.commit();
     }
   },

+ 2 - 3
ambari-web/app/mappers/cluster_mapper.js

@@ -56,8 +56,7 @@ App.clusterMapper = App.QuickDataMapper.create({
       cluster_name: 'Clusters.cluster_name',
       stack_name: 'Clusters.stack_name',
       version: 'Clusters.version',
-      //$hosts: [1, 2, 3, 4],
-      $racks: [1],
-      max_hosts_per_rack: 'Clusters.max_hosts_per_rack'
+      security_type: 'Clusters.security_type',
+      total_hosts: 'Clusters.total_hosts'
     }
 });

+ 20 - 14
ambari-web/app/mappers/components_state_mapper.js

@@ -36,6 +36,7 @@ App.componentsStateMapper = App.QuickDataMapper.create({
   },
 
   slaveModel: App.SlaveComponent,
+  masterModel: App.MasterComponent,
 
   paths: {
     INSTALLED_PATH: 'ServiceComponentInfo.installed_count',
@@ -146,6 +147,7 @@ App.componentsStateMapper = App.QuickDataMapper.create({
 
     var clients = [];
     var slaves = [];
+    var masters = [];
 
     if (json.items) {
       json.items.forEach(function (item) {
@@ -158,29 +160,33 @@ App.componentsStateMapper = App.QuickDataMapper.create({
         if (item.ServiceComponentInfo.category === 'CLIENT') {
           item.host_names = item.host_components.mapProperty('HostRoles.host_name');
           clients.push(this.parseIt(item, this.clientMap));
-        }
-        if (item.ServiceComponentInfo.category === 'SLAVE') {
+        } else if (item.ServiceComponentInfo.category === 'SLAVE') {
           // for now map for slaves and clients are equal but it may vary in future.
           item.host_names = item.host_components.mapProperty('HostRoles.host_name');
           slaves.push(this.parseIt(item, this.clientMap));
+        } else if (item.ServiceComponentInfo.category === 'MASTER') {
+          item.host_names = item.host_components.mapProperty('HostRoles.host_name');
+          masters.push(this.parseIt(item, this.clientMap));
         }
+         if (cacheService) {
+           cacheService.client_components = clients.filterProperty('service_name', cacheService.ServiceInfo.service_name).mapProperty('component_name');
+           cacheService.slave_components = slaves.filterProperty('service_name', cacheService.ServiceInfo.service_name).mapProperty('component_name');
 
-        cacheService.client_components = clients.filterProperty('service_name', cacheService.ServiceInfo.service_name).mapProperty('component_name');
-        cacheService.slave_components = slaves.filterProperty('service_name', cacheService.ServiceInfo.service_name).mapProperty('component_name');
-
-        for (var i in parsedItem) {
-          if (service.get('isLoaded')) {
-            cacheService[i] = parsedItem[i];
-            service.set(stringUtils.underScoreToCamelCase(i), parsedItem[i]);
-            if (extendedModel) {
-              extendedModel.set(stringUtils.underScoreToCamelCase(i), parsedItem[i]);
-            }
-          }
-        }
+           for (var i in parsedItem) {
+             if (service.get('isLoaded')) {
+               cacheService[i] = parsedItem[i];
+               service.set(stringUtils.underScoreToCamelCase(i), parsedItem[i]);
+               if (extendedModel) {
+                 extendedModel.set(stringUtils.underScoreToCamelCase(i), parsedItem[i]);
+               }
+             }
+           }
+         }
       }, this)
     }
     App.store.loadMany(this.clientModel, clients);
     App.store.loadMany(this.slaveModel, slaves);
+    App.store.loadMany(this.masterModel, masters);
 
     console.timeEnd('App.componentsStateMapper execution time');
   }

+ 0 - 5
ambari-web/app/mappers/racks_mapper.js

@@ -21,10 +21,5 @@ App.racksMapper = App.QuickDataMapper.create({
   config: {
     id: "Racks.id",
     name: "Racks.name"
-    //$hosts: ["host01", "host06", "host05"],
-    //status: "Racks.status",
-    //live_hosts_count: "Racks.live_hosts_count",
-    //critical_hosts_count: "Racks.critical_hosts_count",
-    //dead_hosts_count: "Racks.dead_hosts_count"
   }
 });

+ 2 - 0
ambari-web/app/mappers/service_mapper.js

@@ -21,6 +21,8 @@ App.serviceMapper = App.QuickDataMapper.create({
   map: function (json) {
     console.time("App.serviceMapper execution time");
 
+    App.serviceComponents = [].concat.apply([], json.items.mapProperty('components').invoke('getEach', 'ServiceComponentInfo.component_name'));
+
     json.items.forEach(function (service) {
       var cachedService = App.cache['services'].findProperty('ServiceInfo.service_name', service.ServiceInfo.service_name);
       if (cachedService) {

+ 1 - 1
ambari-web/app/messages.js

@@ -269,6 +269,7 @@ Em.I18n.translations = {
   'common.clone': 'Clone',
   'common.removed': 'Removed',
   'common.testing': 'Testing',
+  'common.noData': 'No Data',
 
   'models.alert_instance.tiggered.verbose': "Occurred on {0} <br> Checked on {1}",
   'models.alert_definition.triggered.verbose': "Occurred on {0}",
@@ -1471,7 +1472,6 @@ Em.I18n.translations = {
   'services.service.summary.viewHost':'View Host',
   'services.service.summary.viewHosts':'View Hosts',
   'services.service.summary.clientOnlyService.ToolTip':'Client-only service',
-  'services.service.summary.DataNodesLive':'DataNodes Live',
   'services.service.summary.JournalNodesLive':'JournalNodes Live',
   'services.service.summary.mapreduce2.client':'MapReduce2 Client',
   'services.service.summary.mapreduce2.clients':'MapReduce2 Clients',

+ 1 - 1
ambari-web/app/mixins/common/serverValidator.js

@@ -310,7 +310,7 @@ App.ServerValidatorMixin = Em.Mixin.create({
 
   /**
    * warn user if some errors or warning were
-   * in seting up configs otherwise go to the nex operation
+   * in setting up configs otherwise go to the nex operation
    * @param deferred
    * @returns {*}
    */

+ 1 - 1
ambari-web/app/mixins/wizard/addSecurityConfigs.js

@@ -360,7 +360,7 @@ App.AddSecurityConfigs = Em.Mixin.create({
    * @returns {Boolean}
    */
   shouldLoadClusterDescriptor: function() {
-    return App.router.get('mainAdminKerberosController.securityEnabled') && !App.router.get('mainAdminKerberosController.defaultKerberosLoaded');
+    return App.get('isKerberosEnabled') && !App.router.get('mainAdminKerberosController.defaultKerberosLoaded');
   }.property('App.router.mainAdminKerberosController.securityEnabled', 'App.router.mainAdminKerberosController.defaultKerberosLoaded'),
 
   /**

+ 1 - 1
ambari-web/app/mixins/wizard/wizardProgressPageController.js

@@ -515,7 +515,7 @@ App.wizardProgressPageControllerMixin = Em.Mixin.create({
         }
       };
       if (!!hostsWithoutComponents.length) {
-        componentsUtils.createServiceComponent(componentName).done(function () {
+        componentsUtils.updateAndCreateServiceComponent(componentName).done(function () {
           App.ajax.send({
             name: 'wizard.step8.register_host_to_component',
             sender: self,

+ 1 - 0
ambari-web/app/models.js

@@ -55,6 +55,7 @@ require('models/client_component');
 require('models/host_component');
 require('models/target_cluster');
 require('models/slave_component');
+require('models/master_component');
 require('models/config_group');
 require('models/host_stack_version');
 require('models/root_service');

+ 8 - 14
ambari-web/app/models/cluster.js

@@ -23,23 +23,17 @@ App.Cluster = DS.Model.extend({
   clusterName: DS.attr('string'),
   stackName: DS.attr('string'),
   version: DS.attr('string'),
-  hosts: DS.hasMany('App.Host'),
-  racks: DS.hasMany('App.Rack'),
-  maxHostsPerRack: DS.attr('number'),
+  totalHosts:DS.attr('number'),
+  securityType: DS.attr('string'),
   /**
    * Array containing desired configs. New array
    * should be set by instances of class.
    */
-  desiredConfigs: null
+  desiredConfigs: null,
+
+  isKerberosEnabled: function() {
+    return this.get('securityType') === 'KERBEROS';
+  }.property('securityType')
 });
 
-App.Cluster.FIXTURES = [/*
-  {
-    id: 1,
-    cluster_name: 'cluster1',
-    stack_name: 'HDP',
-    hosts: [1, 2, 3, 4],
-    racks: [1, 2, 3, 4, 5, 6],
-    max_hosts_per_rack: 10
-  }*/
-];
+App.Cluster.FIXTURES = [];

+ 28 - 0
ambari-web/app/models/master_component.js

@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+var stringUtils = require('utils/string_utils');
+
+App.MasterComponent = App.ClientComponent.extend({
+  displayNamePluralized: function() {
+    return stringUtils.pluralize(this.get('startedCount'), this.get('displayName'));
+  }.property('startedCount')
+});
+
+App.MasterComponent.FIXTURES = [];

+ 8 - 0
ambari-web/app/models/service.js

@@ -40,6 +40,7 @@ App.Service = DS.Model.extend({
 
   clientComponents: DS.hasMany('App.ClientComponent'),
   slaveComponents: DS.hasMany('App.SlaveComponent'),
+  masterComponents: DS.hasMany('App.MasterComponent'),
 
   /**
    * @type {bool}
@@ -48,6 +49,13 @@ App.Service = DS.Model.extend({
     return this.get('passiveState') === "ON";
   }.property('passiveState'),
 
+  serviceComponents: function() {
+    var clientComponents = this.get('clientComponents').mapProperty('componentName');
+    var slaveComponents = this.get('slaveComponents').mapProperty('componentName');
+    var masterComponents = this.get('masterComponents').mapProperty('componentName');
+    return clientComponents.concat(slaveComponents).concat(masterComponents);
+  }.property('clientComponents.@each', 'slaveComponents.@each','masterComponents.@each'),
+
   // Instead of making healthStatus a computed property that listens on hostComponents.@each.workStatus,
   // we are creating a separate observer _updateHealthStatus.  This is so that healthStatus is updated
   // only once after the run loop.  This is because Ember invokes the computed property every time

+ 33 - 24
ambari-web/app/router.js

@@ -165,8 +165,15 @@ App.Router = Em.Router.extend({
     return dfd.promise();
   },
 
+  /**
+   * Response for <code>/clusters?fields=Clusters/provisioning_state</code>
+   * @type {null|object}
+   */
+  clusterData: null,
+
   onAuthenticationSuccess: function (data) {
     if (App.db.getAuthenticated() === true) {
+      this.set('clusterData', data);
       this.setAuthenticated(true);
       if (data.items.length) {
         this.setClusterInstalled(data);
@@ -265,17 +272,22 @@ App.Router = Em.Router.extend({
     console.log('login success');
     App.usersMapper.map({"items": [data]});
     this.setUserLoggedIn(decodeURIComponent(params.loginName));
-    App.router.get('mainViewsController').loadAmbariViews();
-    App.ajax.send({
-      name: 'router.login.clusters',
-      sender: this,
-      data: {
-        loginName: params.loginName,
-        loginData: data
-      },
-      success: 'loginGetClustersSuccessCallback',
-      error: 'loginGetClustersErrorCallback'
-    });
+    var requestData = {
+      loginName: params.loginName,
+      loginData: data
+    };
+    // no need to load cluster data if it's already loaded
+    if (this.get('clusterData')) {
+      this.loginGetClustersSuccessCallback(this.get('clusterData'), {}, requestData);
+    }
+    else {
+      App.ajax.send({
+        name: 'router.login.clusters',
+        sender: this,
+        data: requestData,
+        success: 'loginGetClustersSuccessCallback'
+      });
+    }
   },
 
   loginErrorCallback: function(request, ajaxOptions, error, opt) {
@@ -311,8 +323,7 @@ App.Router = Em.Router.extend({
           App.ajax.send({
             name: 'ambari.service.load_server_version',
             sender: this,
-            success: 'adminViewInfoSuccessCallback',
-            error: 'adminViewInfoErrorCallback'
+            success: 'adminViewInfoSuccessCallback'
           });
         }
       } else {
@@ -345,6 +356,7 @@ App.Router = Em.Router.extend({
           });
         }
       } else {
+        App.router.get('mainViewsController').loadAmbariViews();
         router.transitionTo('main.views.index');
         loginController.postLogin(true,true);
       }
@@ -363,14 +375,6 @@ App.Router = Em.Router.extend({
     }
   },
 
-  adminViewInfoErrorCallback: function (req) {
-    console.log("Get admin view version error: " + req.statusCode);
-  },
-
-  loginGetClustersErrorCallback: function (req) {
-    console.log("Get clusters error: " + req.statusCode);
-  },
-
   getSection: function (callback) {
     if (App.get('testMode')) {
       if (App.alwaysGoToInstaller) {
@@ -390,7 +394,13 @@ App.Router = Em.Router.extend({
               route =  wizardControllerRoute.route;
             }
           }
-          callback(route);
+          if (wizardControllerRoute && wizardControllerRoute.wizardControllerName === 'mainAdminStackAndUpgradeController')  {
+            App.router.get('clusterController').restoreUpgradeState().done(function(){
+              callback(route);
+            });
+          } else {
+            callback(route);
+          }
         });
       } else {
         callback('installer');
@@ -534,8 +544,7 @@ App.Router = Em.Router.extend({
           App.ajax.send({
             name: 'ambari.service.load_server_version',
             sender: router,
-            success: 'adminViewInfoSuccessCallback',
-            error: 'adminViewInfoErrorCallback'
+            success: 'adminViewInfoSuccessCallback'
           });
         }
       }

+ 90 - 77
ambari-web/app/routes/add_service_routes.js

@@ -25,63 +25,74 @@ module.exports = App.WizardRoute.extend({
   enter: function (router) {
     console.log('in /service/add:enter');
     if (App.isAccessible('ADMIN')) {
-      Em.run.next(function () {
-        var addServiceController = router.get('addServiceController');
-        App.router.get('updateController').set('isWorking', false);
-        var popup = App.ModalPopup.show({
-          classNames: ['full-width-modal', 'add-service-wizard-modal'],
-          header:Em.I18n.t('services.add.header'),
-          bodyClass:  App.AddServiceView.extend({
-            controllerBinding: 'App.router.addServiceController'
-          }),
-          primary:Em.I18n.t('form.cancel'),
-          showFooter: false,
-          secondary: null,
+      // `getSecurityStatus` call is required to retrieve information related to kerberos type: Manual or automated kerberos
+      router.get('mainController').isLoading.call(router.get('clusterController'),'isClusterNameLoaded').done(function () {
+        App.router.get('mainAdminKerberosController').getSecurityStatus().always(function () {
+          Em.run.next(function () {
+            var addServiceController = router.get('addServiceController');
+            App.router.get('updateController').set('isWorking', false);
+            var popup = App.ModalPopup.show({
+              classNames: ['full-width-modal', 'add-service-wizard-modal'],
+              header: Em.I18n.t('services.add.header'),
+              bodyClass: App.AddServiceView.extend({
+                controllerBinding: 'App.router.addServiceController'
+              }),
+              primary: Em.I18n.t('form.cancel'),
+              showFooter: false,
+              secondary: null,
+
+              onPrimary: function () {
+                this.hide();
+                App.router.transitionTo('main.services.index');
+              },
+              onClose: function () {
+                this.set('showCloseButton', false); // prevent user to click "Close" many times
+                App.router.get('updateController').set('isWorking', true);
+                var self = this;
+                App.router.get('updateController').updateServices(function () {
+                  App.router.get('updateController').updateServiceMetric();
+                });
+                var exitPath = addServiceController.getDBProperty('onClosePath') || 'main.services.index';
+                addServiceController.finish();
+                // We need to do recovery based on whether we are in Add Host or Installer wizard
+                App.clusterStatus.setClusterStatus({
+                  clusterName: App.router.get('content.cluster.name'),
+                  clusterState: 'DEFAULT'
+                }, {
+                  alwaysCallback: function () {
+                    self.hide();
+                    App.router.transitionTo(exitPath);
+                    location.reload();
+                  }
+                });
 
-          onPrimary:function () {
-            this.hide();
-            App.router.transitionTo('main.services.index');
-          },
-          onClose: function() {
-            this.set('showCloseButton', false); // prevent user to click "Close" many times
-            App.router.get('updateController').set('isWorking', true);
-            var self = this;
-            App.router.get('updateController').updateServices(function(){
-              App.router.get('updateController').updateServiceMetric();
+              },
+              didInsertElement: function () {
+                this.fitHeight();
+              }
             });
-            var exitPath = addServiceController.getDBProperty('onClosePath') || 'main.services.index';
-            addServiceController.finish();
-            // We need to do recovery based on whether we are in Add Host or Installer wizard
-            App.clusterStatus.setClusterStatus({
-              clusterName: App.router.get('content.cluster.name'),
-              clusterState: 'DEFAULT'
-            }, {alwaysCallback: function() {self.hide();App.router.transitionTo(exitPath);location.reload();}});
+            addServiceController.set('popup', popup);
+            var currentClusterStatus = App.clusterStatus.get('value');
+            if (currentClusterStatus) {
+              switch (currentClusterStatus.clusterState) {
+                case 'ADD_SERVICES_DEPLOY_PREP_2' :
+                  addServiceController.setCurrentStep('5');
+                  break;
+                case 'ADD_SERVICES_INSTALLING_3' :
+                case 'SERVICE_STARTING_3' :
+                  addServiceController.setCurrentStep('6');
+                  break;
+                case 'ADD_SERVICES_INSTALLED_4' :
+                  addServiceController.setCurrentStep('7');
+                  break;
+                default:
+                  break;
+              }
+            }
 
-          },
-          didInsertElement: function(){
-            this.fitHeight();
-          }
+            router.transitionTo('step' + addServiceController.get('currentStep'));
+          });
         });
-        addServiceController.set('popup',popup);
-        var currentClusterStatus = App.clusterStatus.get('value');
-        if (currentClusterStatus) {
-          switch (currentClusterStatus.clusterState) {
-            case 'ADD_SERVICES_DEPLOY_PREP_2' :
-              addServiceController.setCurrentStep('5');
-              break;
-            case 'ADD_SERVICES_INSTALLING_3' :
-            case 'SERVICE_STARTING_3' :
-              addServiceController.setCurrentStep('6');
-              break;
-            case 'ADD_SERVICES_INSTALLED_4' :
-              addServiceController.setCurrentStep('7');
-              break;
-            default:
-              break;
-          }
-        }
-
-        router.transitionTo('step' + addServiceController.get('currentStep'));
       });
     } else {
       Em.run.next(function () {
@@ -92,9 +103,9 @@ module.exports = App.WizardRoute.extend({
   },
 
   /*connectOutlets: function (router) {
-    console.log('in /service/add:connectOutlets');
-    router.get('mainController').connectOutlet('addService');
-  },*/
+   console.log('in /service/add:connectOutlets');
+   router.get('mainController').connectOutlet('addService');
+   },*/
 
   step1: Em.Route.extend({
     route: '/step1',
@@ -166,9 +177,9 @@ module.exports = App.WizardRoute.extend({
         });
       });
     },
-    back: function(router){
+    back: function (router) {
       var controller = router.get('addServiceController');
-      if(!controller.get('content.skipMasterStep')){
+      if (!controller.get('content.skipMasterStep')) {
         router.transitionTo('step2');
       } else {
         router.transitionTo('step1');
@@ -178,8 +189,8 @@ module.exports = App.WizardRoute.extend({
       var addServiceController = router.get('addServiceController');
       var wizardStep6Controller = router.get('wizardStep6Controller');
 
-      wizardStep6Controller.callValidation(function() {
-        wizardStep6Controller.showValidationIssuesAcceptBox(function() {
+      wizardStep6Controller.callValidation(function () {
+        wizardStep6Controller.showValidationIssuesAcceptBox(function () {
           addServiceController.saveSlaveComponentHosts(wizardStep6Controller);
           addServiceController.get('content').set('serviceConfigProperties', null);
           addServiceController.setDBProperty('serviceConfigProperties', null);
@@ -204,16 +215,18 @@ module.exports = App.WizardRoute.extend({
           wizardStep7Controller.getConfigTags();
           wizardStep7Controller.set('wizardController', controller);
           controller.usersLoading().done(function () {
-            controller.connectOutlet('wizardStep7', controller.get('content'));
+            router.get('mainController').isLoading.call(router.get('clusterController'), 'isClusterNameLoaded').done(function () {
+              controller.connectOutlet('wizardStep7', controller.get('content'));
+            });
           });
         });
       });
     },
-    back: function(router){
+    back: function (router) {
       var controller = router.get('addServiceController');
-      if(!controller.get('content.skipSlavesStep')){
+      if (!controller.get('content.skipSlavesStep')) {
         router.transitionTo('step3');
-      } else if(!controller.get('content.skipMasterStep')) {
+      } else if (!controller.get('content.skipMasterStep')) {
         router.transitionTo('step2');
       } else {
         router.transitionTo('step1');
@@ -224,7 +237,7 @@ module.exports = App.WizardRoute.extend({
       var wizardStep7Controller = router.get('wizardStep7Controller');
       addServiceController.saveServiceConfigProperties(wizardStep7Controller);
       addServiceController.saveServiceConfigGroups(wizardStep7Controller, true);
-      if (router.get('mainAdminKerberosController.securityEnabled')) {
+      if (App.get('isKerberosEnabled')) {
         addServiceController.clearCachedStepConfigValues(router.get('kerberosWizardStep4Controller'));
         router.transitionTo('step5');
         return;
@@ -246,17 +259,17 @@ module.exports = App.WizardRoute.extend({
         });
       });
     },
-    back: function(router){
+    back: function (router) {
       var controller = router.get('addServiceController');
-      if(!controller.get('content.skipConfigStep')) {
+      if (!controller.get('content.skipConfigStep')) {
         router.transitionTo('step4');
       }
       else {
-        if(!controller.get('content.skipSlavesStep')) {
+        if (!controller.get('content.skipSlavesStep')) {
           router.transitionTo('step3');
         }
         else {
-          if(!controller.get('content.skipMasterStep')) {
+          if (!controller.get('content.skipMasterStep')) {
             router.transitionTo('step2');
           }
           else {
@@ -266,7 +279,7 @@ module.exports = App.WizardRoute.extend({
       }
     },
     next: function (router) {
-      if (router.get('mainAdminKerberosController.securityEnabled')) {
+      if (App.Cluster.find().objectAt(0).get('isKerberosEnabled')) {
         if (router.get('mainAdminKerberosController.isManualKerberos')) {
           router.get('wizardStep8Controller').updateKerberosDescriptor(true);
         } else {
@@ -292,21 +305,21 @@ module.exports = App.WizardRoute.extend({
         });
       });
     },
-    back: function(router){
+    back: function (router) {
       var controller = router.get('addServiceController');
-      if (router.get('mainAdminKerberosController.securityEnabled')) {
+      if (App.get('isKerberosEnabled')) {
         router.transitionTo('step5');
         return;
       }
-      if(!controller.get('content.skipConfigStep')) {
+      if (!controller.get('content.skipConfigStep')) {
         router.transitionTo('step4');
       }
       else {
-        if(!controller.get('content.skipSlavesStep')) {
+        if (!controller.get('content.skipSlavesStep')) {
           router.transitionTo('step3');
         }
         else {
-          if(!controller.get('content.skipMasterStep')) {
+          if (!controller.get('content.skipMasterStep')) {
             router.transitionTo('step2');
           }
           else {
@@ -344,7 +357,7 @@ module.exports = App.WizardRoute.extend({
       });
     },
     back: Em.Router.transitionTo('step6'),
-    retry: function(router,context) {
+    retry: function (router, context) {
       var addServiceController = router.get('addServiceController');
       var wizardStep9Controller = router.get('wizardStep9Controller');
       if (wizardStep9Controller.get('showRetry')) {
@@ -361,7 +374,7 @@ module.exports = App.WizardRoute.extend({
         }
       }
     },
-    unroutePath: function() {
+    unroutePath: function () {
       return false;
     },
     next: function (router) {

+ 16 - 11
ambari-web/app/routes/main.js

@@ -47,7 +47,7 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
                   App.clusterStatus.updateFromServer().complete(function () {
                     var currentClusterStatus = App.clusterStatus.get('value');
                     if (router.get('currentState.parentState.name') !== 'views'
-                        && currentClusterStatus && self.get('installerStatuses').contains(currentClusterStatus.clusterState)) {
+                      && currentClusterStatus && self.get('installerStatuses').contains(currentClusterStatus.clusterState)) {
                       if (App.isAccessible('ADMIN')) {
                         self.redirectToInstaller(router, currentClusterStatus, false);
                       } else {
@@ -181,7 +181,13 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
     index: Ember.Route.extend({
       route: '/',
       connectOutlets: function (router, context) {
-        router.get('mainController').connectOutlet('mainHost');
+        router.get('mainController').connectOutlet('loading');
+        router.get('mainController').isLoading.call(router.get('clusterController'), 'isClusterNameLoaded').done(function () {
+          // `getSecurityStatus` call is required to retrieve information related to kerberos type: Manual or automated kerberos
+          router.get('mainAdminKerberosController').getSecurityStatus().always(function () {
+            router.get('mainController').connectOutlet('mainHost');
+          });
+        });
       }
     }),
 
@@ -207,7 +213,7 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
               controller.isOozieConfigLoaded.always(function () {
                 controller.connectOutlet('mainHostSummary');
               });
-            }else {
+            } else {
               controller.connectOutlet('mainHostSummary');
             }
           });
@@ -217,7 +223,10 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
       configs: Em.Route.extend({
         route: '/configs',
         connectOutlets: function (router, context) {
-          router.get('mainHostDetailsController').connectOutlet('mainHostConfigs');
+          router.get('mainHostDetailsController').connectOutlet('loading');
+          router.get('mainController').isLoading.call(router.get('clusterController'), 'isConfigsPropertiesLoaded').done(function () {
+            router.get('mainHostDetailsController').connectOutlet('mainHostConfigs');
+          });
         }
       }),
 
@@ -340,10 +349,6 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
     },
 
     index: Em.Route.extend({
-      /* enter: function(router, transition){
-       var controller = router.get('mainAdminController');
-       router.transitionTo('admin' + controller.get('category').capitalize());
-       }, */
       route: '/',
       redirectsTo: 'stackAndUpgrade.index'
     }),
@@ -371,7 +376,7 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
         route: '/disableSecurity',
         enter: function (router) {
           App.router.get('updateController').set('isWorking', false);
-          router.get('mainController').dataLoading().done(function() {
+          router.get('mainController').dataLoading().done(function () {
             App.ModalPopup.show({
               classNames: ['full-width-modal'],
               header: Em.I18n.t('admin.removeSecurity.header'),
@@ -419,7 +424,7 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
                   clusterState: 'DEFAULT',
                   localdb: App.db.data
                 }, {
-                  alwaysCallback: function() {
+                  alwaysCallback: function () {
                     self.hide();
                     router.transitionTo('adminKerberos.index');
                     location.reload();
@@ -649,7 +654,7 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
           var item = router.get('mainServiceItemController.content');
           if (item.get('isLoaded')) {
             router.get('mainController').dataLoading().done(function () {
-              router.get('mainServiceInfoHeatmapController').loadRacks().done(function(data) {
+              router.get('mainServiceInfoHeatmapController').loadRacks().done(function (data) {
                 router.get('mainServiceInfoHeatmapController').loadRacksSuccessCallback(data);
                 router.get('mainServiceItemController').connectOutlet('mainServiceInfoHeatmap', item);
               });

+ 8 - 6
ambari-web/app/templates/application.hbs

@@ -38,6 +38,7 @@
                     {{allOperationsCount}} {{pluralize allOperationsCount singular="t:op" plural="t:ops"}}</span>
                 {{/if}}
               {{/with}}
+            {{#if App.router.clusterController.isAlertsLoaded}}
               {{#if App.router.mainAlertDefinitionsController.unhealthyAlertInstancesCount}}
                 <span {{bindAttr class=":label App.router.mainAlertDefinitionsController.isCriticalAlerts:alert-crit-count:alert-warn-count"}} {{action "showPopup" target="App.router.mainAlertInstancesController"}}>
                 {{App.router.mainAlertDefinitionsController.unhealthyAlertInstancesCount}} {{pluralize App.router.mainAlertDefinitionsController.unhealthyAlertInstancesCount singular="alert" plural="alerts"}}</span>
@@ -46,6 +47,7 @@
                       class="label alerts-none-count" {{action "showPopup" target="App.router.mainAlertInstancesController"}}>
                 {{App.router.mainAlertDefinitionsController.unhealthyAlertInstancesCount}} {{pluralize App.router.mainAlertDefinitionsController.unhealthyAlertInstancesCount singular="alert" plural="alerts"}}</span>
               {{/if}}
+            {{/if}}
             </a>
           {{else}}
             <a class="logo"><img src="/img/logo-white.png" alt="Apache Ambari" title="Apache Ambari"></a>
@@ -106,33 +108,33 @@
                   {{#if App.upgradeInProgress}}
                     {{#if App.router.mainAdminStackAndUpgradeController.isDowngrade}}
                       <span
-                          class="label upgrade-in-progress" {{action "openUpgradeDialog" target="App.router.mainAdminStackAndUpgradeController"}}>
+                              class="label upgrade-in-progress" {{action "openUpgradeDialog" target="App.router.mainAdminStackAndUpgradeController"}}>
                              <i class="icon-cog"></i>&nbsp;{{t admin.stackVersions.version.downgrade.running}}</span>
                     {{else}}
                       <span
-                          class="label upgrade-in-progress" {{action "openUpgradeDialog" target="App.router.mainAdminStackAndUpgradeController"}}>
+                              class="label upgrade-in-progress" {{action "openUpgradeDialog" target="App.router.mainAdminStackAndUpgradeController"}}>
                              <i class="icon-cog"></i>&nbsp;{{t admin.stackVersions.version.upgrade.running}}</span>
                     {{/if}}
                   {{/if}}
                   {{#if App.upgradeHolding}}
                     {{#if App.router.mainAdminStackAndUpgradeController.isDowngrade}}
                       <span
-                          class="label upgrade-holding" {{action "openUpgradeDialog" target="App.router.mainAdminStackAndUpgradeController"}}>
+                              class="label upgrade-holding" {{action "openUpgradeDialog" target="App.router.mainAdminStackAndUpgradeController"}}>
                           <i class="icon-pause"></i>&nbsp;{{t admin.stackVersions.version.downgrade.pause}}</span>
                     {{else}}
                       <span
-                          class="label upgrade-holding" {{action "openUpgradeDialog" target="App.router.mainAdminStackAndUpgradeController"}}>
+                              class="label upgrade-holding" {{action "openUpgradeDialog" target="App.router.mainAdminStackAndUpgradeController"}}>
                           <i class="icon-pause"></i>&nbsp;{{t admin.stackVersions.version.upgrade.pause}}</span>
                     {{/if}}
                   {{/if}}
                   {{#if App.upgradeAborted}}
                     {{#if App.router.mainAdminStackAndUpgradeController.isDowngrade}}
                       <span
-                          class="label upgrade-aborted" {{action "openUpgradeDialog" target="App.router.mainAdminStackAndUpgradeController"}}>
+                              class="label upgrade-aborted" {{action "openUpgradeDialog" target="App.router.mainAdminStackAndUpgradeController"}}>
                           <i class="icon-remove"></i>&nbsp;{{t admin.stackVersions.version.downgrade.aborted}}</span>
                     {{else}}
                       <span
-                        class="label upgrade-aborted" {{action "openUpgradeDialog" target="App.router.mainAdminStackAndUpgradeController"}}>
+                              class="label upgrade-aborted" {{action "openUpgradeDialog" target="App.router.mainAdminStackAndUpgradeController"}}>
                           <i class="icon-remove"></i>&nbsp;{{t admin.stackVersions.version.upgrade.aborted}}</span>
                     {{/if}}
                   {{/if}}

+ 59 - 46
ambari-web/app/templates/main/alerts.hbs

@@ -31,13 +31,13 @@
   </div>
   <table class="table advanced-header-table table-bordered table-striped alerts-table" id="alert-definitions-table">
     <thead>
-      {{#view view.sortView classNames="label-row" contentBinding="view.filteredContent"}}
-        {{view view.parentView.nameSort class="first name-sorting"}}
-        {{view view.parentView.statusSort class="status-sorting"}}
-        {{view view.parentView.serviceSort class="service-sorting"}}
-        {{view view.parentView.lastTriggeredSort class="last-triggred-sorting"}}
-        {{view view.parentView.enabledSort class="enabled-sorting"}}
-      {{/view}}
+    {{#view view.sortView classNames="label-row" contentBinding="view.filteredContent"}}
+      {{view view.parentView.nameSort class="first name-sorting"}}
+      {{view view.parentView.statusSort class="status-sorting"}}
+      {{view view.parentView.serviceSort class="service-sorting"}}
+      {{view view.parentView.lastTriggeredSort class="last-triggred-sorting"}}
+      {{view view.parentView.enabledSort class="enabled-sorting"}}
+    {{/view}}
     <tr class="filter-row">
       <th class="first">{{view view.nameFilterView class="name-filter"}}</th>
       <th>{{view view.stateFilterView class="status-filter"}}</th>
@@ -47,62 +47,73 @@
     </tr>
     </thead>
     <tbody>
-    {{#if view.pageContent}}
-      {{#each alertDefinition in view.pageContent}}
-        <tr>
-          <td class="first">
-            <span {{bindAttr title="alertDefinition.type"}} {{bindAttr class=":type-icon  alertDefinition.typeIconClass"}}></span>
-            <a href="#" {{action "gotoAlertDetails" alertDefinition}}>{{alertDefinition.label}}</a>
-          </td>
-          <td>{{{alertDefinition.status}}}</td>
-          <td>{{alertDefinition.serviceDisplayName}}</td>
-          <td><time class="timeago" {{bindAttr data-original-title="alertDefinition.lastTriggeredFormatted"}}>{{alertDefinition.lastTriggeredAgoFormatted}}</time></td>
-          <td class="last toggle-state-button">
-            {{#if alertDefinition.enabled}}
-              {{#isAccessible ADMIN}}
-                <a href="#" {{action "toggleState" alertDefinition target="controller"}} {{bindAttr class="alertDefinition.enabled:alert-definition-enable:alert-definition-disable"}}>
+    {{#if App.router.clusterController.isAlertsLoaded}}
+      {{#if view.pageContent}}
+        {{#each alertDefinition in view.pageContent}}
+          <tr>
+            <td class="first">
+              <span {{bindAttr title="alertDefinition.type"}} {{bindAttr class=":type-icon  alertDefinition.typeIconClass"}}></span>
+              <a href="#" {{action "gotoAlertDetails" alertDefinition}}>{{alertDefinition.label}}</a>
+            </td>
+            <td>{{{alertDefinition.status}}}</td>
+            <td>{{alertDefinition.serviceDisplayName}}</td>
+            <td>
+              <time class="timeago" {{bindAttr data-original-title="alertDefinition.lastTriggeredFormatted"}}>{{alertDefinition.lastTriggeredAgoFormatted}}</time>
+            </td>
+            <td class="last toggle-state-button">
+              {{#if alertDefinition.enabled}}
+                {{#isAccessible ADMIN}}
+                  <a href="#" {{action "toggleState" alertDefinition target="controller"}} {{bindAttr class="alertDefinition.enabled:alert-definition-enable:alert-definition-disable"}}>
                   <span class="enable-disable-button" {{bindAttr data-original-title="view.enabledTooltip"}}>
                     {{view.enabledDisplay}}
                   </span>
-                </a>
-              {{/isAccessible}}
-              {{#isAccessible NON_ADMIN}}
-                <span {{bindAttr class="alertDefinition.enabled:alert-definition-enable:alert-definition-disable"}}>
-                      {{t alerts.table.state.enabled}}
-                </span>
-              {{/isAccessible}}
-            {{else}}
-              {{#isAccessible ADMIN}}
-                <a href="#" {{action "toggleState" alertDefinition target="controller"}} {{bindAttr class="alertDefinition.enabled:alert-definition-enable:alert-definition-disable"}}>
+                  </a>
+                {{/isAccessible}}
+                {{#isAccessible NON_ADMIN}}
+                  <span {{bindAttr class="alertDefinition.enabled:alert-definition-enable:alert-definition-disable"}}>
+                    {{t alerts.table.state.enabled}}
+                  </span>
+                {{/isAccessible}}
+              {{else}}
+                {{#isAccessible ADMIN}}
+                  <a href="#" {{action "toggleState" alertDefinition target="controller"}} {{bindAttr class="alertDefinition.enabled:alert-definition-enable:alert-definition-disable"}}>
                   <span class="enable-disable-button" {{bindAttr data-original-title="view.disabledTooltip"}}>
                     {{view.disabledDisplay}}
                   </span>
-                </a>
-              {{/isAccessible}}
-              {{#isAccessible NON_ADMIN}}
-                <span {{bindAttr class="alertDefinition.enabled:alert-definition-enable:alert-definition-disable"}}>
-                      {{t alerts.table.state.disabled}}
-                </span>
-              {{/isAccessible}}
-            {{/if}}
+                  </a>
+                {{/isAccessible}}
+                {{#isAccessible NON_ADMIN}}
+                  <span {{bindAttr class="alertDefinition.enabled:alert-definition-enable:alert-definition-disable"}}>
+                    {{t alerts.table.state.disabled}}
+                  </span>
+                {{/isAccessible}}
+              {{/if}}
+            </td>
+          </tr>
+        {{/each}}
+      {{else}}
+        <tr>
+          <td class="first"></td>
+          <td colspan="4">
+            {{t alerts.table.noAlerts}}
           </td>
         </tr>
-      {{/each}}
+      {{/if}}
     {{else}}
       <tr>
         <td class="first"></td>
-        <td colspan="4">
-          {{t alerts.table.noAlerts}}
+        <td colspan="2">
+          <div class="spinner"></div>
         </td>
       </tr>
-      {{/if}}
+    {{/if}}
     </tbody>
   </table>
 
   <div class="page-bar">
     <div class="filtered-info span4">
       <label>{{view.filteredContentInfo}} - <a {{action clearFilters target="view"}}
-          href="#">{{t tableView.filters.clearAllFilters}}</a></label>
+              href="#">{{t tableView.filters.clearAllFilters}}</a></label>
     </div>
     <div class="selected-hosts-info span4">
     </div>
@@ -111,8 +122,10 @@
     </div>
     <div class="info">{{view.paginationInfo}}</div>
     <div class="paging_two_button">
-      <a {{bindAttr class="view.paginationLeftClass"}}{{action previousPage target="view"}}><i class="icon-arrow-left"></i></a>
-      <a {{bindAttr class="view.paginationRightClass"}}{{action nextPage target="view"}}><i class="icon-arrow-right"></i></a>
+      <a {{bindAttr class="view.paginationLeftClass"}}{{action previousPage target="view"}}><i
+              class="icon-arrow-left"></i></a>
+      <a {{bindAttr class="view.paginationRightClass"}}{{action nextPage target="view"}}><i
+              class="icon-arrow-right"></i></a>
     </div>
   </div>
 </div>

+ 42 - 36
ambari-web/app/templates/main/host/host_alerts.hbs

@@ -22,49 +22,53 @@
 
   {{#if App.router.mainAlertInstancesController.isLoaded}}
 
-  <table class="table advanced-header-table table-bordered table-striped alerts-table" id="host-alerts-table">
-    <thead>
+    <table class="table advanced-header-table table-bordered table-striped alerts-table" id="host-alerts-table">
+      <thead>
       {{#view view.sortView classNames="label-row" contentBinding="view.filteredContent"}}
         {{view view.parentView.serviceSort class="first service-sorting"}}
         {{view view.parentView.nameSort class="name-sorting"}}
         {{view view.parentView.statusSort class="status-sorting"}}
         {{view view.parentView.textSort class="text-sorting"}}
       {{/view}}
-    <tr class="filter-row">
-      <th class="first">{{view view.serviceFilterView class="service-filter"}}</th>
-      <th>{{view view.nameFilterView class="name-filter"}}</th>
-      <th>{{view view.stateFilterView class="status-filter"}}</th>
-      <th>{{view view.textView class="text-filter"}}</th>
-    </tr>
-    </thead>
-    <tbody>
-    {{#if view.pageContent}}
-      {{#each alertInstance in view.pageContent}}
+      <tr class="filter-row">
+        <th class="first">{{view view.serviceFilterView class="service-filter"}}</th>
+        <th>{{view view.nameFilterView class="name-filter"}}</th>
+        <th>{{view view.stateFilterView class="status-filter"}}</th>
+        <th>{{view view.textView class="text-filter"}}</th>
+      </tr>
+      </thead>
+      <tbody>
+      {{#if view.pageContent}}
+        {{#each alertInstance in view.pageContent}}
+          <tr>
+            <td class="first">
+              {{#if alertInstance.isAmbariServiceName}}
+                {{alertInstance.serviceDisplayName}}
+              {{else}}
+                <a href="#" {{action routeToService alertInstance.service}}>{{alertInstance.serviceDisplayName}}</a>
+              {{/if}}
+            </td>
+            <td>
+              <a href="#" {{action routeToAlertDefinition alertInstance.definitionId target="controller"}}>{{alertInstance.label}}</a>
+            </td>
+            <td>{{{alertInstance.status}}}
+              <time class="timeago" {{bindAttr data-original-title="alertInstance.statusChangedAndLastCheckedFormatted"}}>{{alertInstance.lastTriggeredForFormatted}}</time>
+            </td>
+            <td><span
+                    class="alert-text" {{bindAttr data-original-title="alertInstance.escapeSpecialCharactersFromTooltip"}}
+                    class="alert-text">{{alertInstance.text}}</span></td>
+          </tr>
+        {{/each}}
+      {{else}}
         <tr>
           <td class="first">
-            {{#if alertInstance.isAmbariServiceName}}
-              {{alertInstance.serviceDisplayName}}
-            {{else}}
-              <a href="#" {{action routeToService alertInstance.service}}>{{alertInstance.serviceDisplayName}}</a>
-            {{/if}}
-          </td>
-          <td>
-            <a href="#" {{action routeToAlertDefinition alertInstance.definitionId target="controller"}}>{{alertInstance.label}}</a>
+            {{t alerts.table.noAlerts}}
           </td>
-          <td>{{{alertInstance.status}}} <time class="timeago" {{bindAttr data-original-title="alertInstance.statusChangedAndLastCheckedFormatted"}}>{{alertInstance.lastTriggeredForFormatted}}</time></td>
-          <td><span class="alert-text" {{bindAttr data-original-title="alertInstance.escapeSpecialCharactersFromTooltip"}} class="alert-text">{{alertInstance.text}}</span></td>
+          <td colspan="3"></td>
         </tr>
-      {{/each}}
-    {{else}}
-      <tr>
-        <td class="first">
-          {{t alerts.table.noAlerts}}
-        </td>
-        <td colspan="3"></td>
-      </tr>
-    {{/if}}
-    </tbody>
-  </table>
+      {{/if}}
+      </tbody>
+    </table>
 
   {{else}}
     <div class="spinner"></div>
@@ -74,7 +78,7 @@
     <div class="filtered-info span4">
       {{#if view.showFilteredContent}}
         <label>{{view.filteredContentInfo}} - <a {{action clearFilters target="view"}}
-            href="#">{{t tableView.filters.clearAllFilters}}</a></label>
+                href="#">{{t tableView.filters.clearAllFilters}}</a></label>
       {{/if}}
     </div>
     <div class="selected-hosts-info span4">
@@ -84,8 +88,10 @@
     </div>
     <div class="info">{{view.paginationInfo}}</div>
     <div class="paging_two_button">
-      <a {{bindAttr class="view.paginationLeftClass"}}{{action previousPage target="view"}}><i class="icon-arrow-left"></i></a>
-      <a {{bindAttr class="view.paginationRightClass"}}{{action nextPage target="view"}}><i class="icon-arrow-right"></i></a>
+      <a {{bindAttr class="view.paginationLeftClass"}}{{action previousPage target="view"}}><i
+              class="icon-arrow-left"></i></a>
+      <a {{bindAttr class="view.paginationRightClass"}}{{action nextPage target="view"}}><i
+              class="icon-arrow-right"></i></a>
     </div>
   </div>
 </div>

+ 40 - 34
ambari-web/app/templates/main/service/services/hbase.hbs

@@ -17,33 +17,39 @@
 }}
 
 <!-- HBase Master Server -->
-  {{view view.dashboardMasterComponentView}}
+{{view view.dashboardMasterComponentView}}
 <!-- RegionServers -->
 <tr>
-  <td class="summary-label"><a href="#" {{action filterHosts view.regionServerComponent}}>{{t dashboard.services.hbase.regionServers}}</a>
+  <td class="summary-label"><a
+          href="#" {{action filterHosts view.regionServerComponent}}>{{t dashboard.services.hbase.regionServers}}</a>
   </td>
   <td>
-    <span>
-      {{#view App.ComponentLiveTextView liveComponentsBinding="view.service.regionServersStarted" totalComponentsBinding="view.service.regionServersTotal"}}
-        {{view.liveComponents}}/{{view.totalComponents}}
-      {{/view}}
-    </span>
+    {{#if App.router.clusterController.isComponentsStateLoaded}}
+      <span>
+        {{#view App.ComponentLiveTextView liveComponentsBinding="view.service.regionServersStarted" totalComponentsBinding="view.service.regionServersTotal"}}
+          {{view.liveComponents}}/{{view.totalComponents}}
+        {{/view}}
+      </span>
       {{t services.service.summary.RegionServersLIVE}}
+    {{else}}
+      {{t common.noData}}
+    {{/if}}
   </td>
 </tr>
 <!-- PhoenixServers -->
 {{#if view.showPhoenixInfo}}
   <tr>
-      <td class="summary-label"><a href="#" {{action filterHosts view.phoenixServerComponent}}>{{t dashboard.services.hbase.phoenixServers}}</a>
-      </td>
-      <td>
+    <td class="summary-label"><a
+            href="#" {{action filterHosts view.phoenixServerComponent}}>{{t dashboard.services.hbase.phoenixServers}}</a>
+    </td>
+    <td>
       <span>
         {{#view App.ComponentLiveTextView liveComponentsBinding="view.service.phoenixServersStarted" totalComponentsBinding="view.service.phoenixServersTotal"}}
           {{view.liveComponents}}/{{view.totalComponents}}
         {{/view}}
       </span>
-        {{t services.service.summary.PhoenixServersLIVE}}
-      </td>
+      {{t services.service.summary.PhoenixServersLIVE}}
+    </td>
   </tr>
 {{/if}}
 <!-- Regions in Transition -->
@@ -53,31 +59,31 @@
 </tr>
 
 <!-- Divider-- make the remaining summary info on 2nd table-->
-    </tbody>
-  </table>
+</tbody>
+</table>
 </div>
 <div class="span6">
   <table class="summary-info table no-borders table-condensed">
     <tbody>
 
-<!-- HBase Master Started Time -->
-<tr>
-  <td class="summary-label">{{t dashboard.services.hbase.masterStarted}}</td>
-  <td>{{view.masterStartedTime}}</td>
-</tr>
-<!-- HBase Master Activated Time -->
-<tr>
-  <td class="summary-label">{{t dashboard.services.hbase.masterActivated}}</td>
-  <td>{{view.masterStartedTime}}</td>
-</tr>
-<!-- Average Load -->
-<tr>
-  <td class="summary-label">{{t dashboard.services.hbase.averageLoad}}</td>
-  <td>{{view.averageLoad}}</td>
-</tr>
-<!-- Master Server Heap -->
-<tr>
-  <td class="summary-label">{{t dashboard.services.hbase.masterServerHeap}}</td>
-  <td>{{view.masterServerHeapSummary}}</td>
-</tr>
+    <!-- HBase Master Started Time -->
+    <tr>
+      <td class="summary-label">{{t dashboard.services.hbase.masterStarted}}</td>
+      <td>{{view.masterStartedTime}}</td>
+    </tr>
+    <!-- HBase Master Activated Time -->
+    <tr>
+      <td class="summary-label">{{t dashboard.services.hbase.masterActivated}}</td>
+      <td>{{view.masterStartedTime}}</td>
+    </tr>
+    <!-- Average Load -->
+    <tr>
+      <td class="summary-label">{{t dashboard.services.hbase.averageLoad}}</td>
+      <td>{{view.averageLoad}}</td>
+    </tr>
+    <!-- Master Server Heap -->
+    <tr>
+      <td class="summary-label">{{t dashboard.services.hbase.masterServerHeap}}</td>
+      <td>{{view.masterServerHeapSummary}}</td>
+    </tr>
 

+ 75 - 57
ambari-web/app/templates/main/service/services/hdfs.hbs

@@ -19,14 +19,19 @@
 {{view view.dashboardMasterComponentView}}
 <!-- Data Nodes -->
 <tr>
-  <td class="summary-label"><a href="#" {{action filterHosts view.dataNodeComponent}}>{{t dashboard.services.hdfs.datanodes}}</a></td>
+  <td class="summary-label"><a
+          href="#" {{action filterHosts view.dataNodeComponent}}>{{t dashboard.services.hdfs.datanodes}}</a></td>
   <td>
-    <span>
-      {{#view App.ComponentLiveTextView liveComponentsBinding="view.service.dataNodesStarted" totalComponentsBinding="view.service.dataNodesTotal"}}
-        {{view.liveComponents}}/{{view.totalComponents}}
-      {{/view}}
-    </span>
+    {{#if App.router.clusterController.isComponentsStateLoaded}}
+      <span>
+        {{#view App.ComponentLiveTextView liveComponentsBinding="view.service.dataNodesStarted" totalComponentsBinding="view.service.dataNodesTotal"}}
+          {{view.liveComponents}}/{{view.totalComponents}}
+        {{/view}}
+      </span>
       {{t common.started}}
+    {{else}}
+      {{t common.noData}}
+    {{/if}}
   </td>
 </tr>
 <!-- Data Node Counts -->
@@ -36,38 +41,51 @@
     <td>{{t services.service.summary.notAvailable}}</td>
   {{else}}
     <td>
-      <span {{translateAttr data-original-title="dashboard.services.hdfs.datanode.status.tooltip.live" }} rel="tooltip">{{view.service.liveDataNodes.length}} {{t dashboard.services.hdfs.nodes.live}} </span> /
-      <span {{translateAttr data-original-title="dashboard.services.hdfs.datanode.status.tooltip.dead" }} rel="tooltip">{{view.service.deadDataNodes.length}} {{t dashboard.services.hdfs.nodes.dead}} </span> /
-      <span {{translateAttr data-original-title="dashboard.services.hdfs.datanode.status.tooltip.decommission" }} rel="tooltip">{{view.service.decommissionDataNodes.length}} {{t dashboard.services.hdfs.nodes.decom}}</span>
+      <span {{translateAttr data-original-title="dashboard.services.hdfs.datanode.status.tooltip.live" }}
+              rel="tooltip">{{view.service.liveDataNodes.length}} {{t dashboard.services.hdfs.nodes.live}} </span> /
+      <span {{translateAttr data-original-title="dashboard.services.hdfs.datanode.status.tooltip.dead" }}
+              rel="tooltip">{{view.service.deadDataNodes.length}} {{t dashboard.services.hdfs.nodes.dead}} </span> /
+      <span {{translateAttr data-original-title="dashboard.services.hdfs.datanode.status.tooltip.decommission" }}
+              rel="tooltip">{{view.service.decommissionDataNodes.length}} {{t dashboard.services.hdfs.nodes.decom}}</span>
     </td>
   {{/if}}
 </tr>
 <!-- JournalNodes -->
 {{#if view.showJournalNodes}}
   <tr>
-    <td class="summary-label"><a href="#" {{action filterHosts view.journalNodeComponent}}>{{t dashboard.services.hdfs.journalnodes}}</a>
+    <td class="summary-label"><a
+            href="#" {{action filterHosts view.journalNodeComponent}}>{{t dashboard.services.hdfs.journalnodes}}</a>
     </td>
     <td>
-      <span>
-        {{#view App.ComponentLiveTextView liveComponentsBinding="view.journalNodesLive" totalComponentsBinding="view.journalNodesTotal"}}
-          {{view.liveComponents}}/{{view.totalComponents}}
-        {{/view}}
-      </span>
+      {{#if App.router.clusterController.isComponentsStateLoaded}}
+        <span>
+          {{#view App.ComponentLiveTextView liveComponentsBinding="view.journalNodesLive" totalComponentsBinding="view.journalNodesTotal"}}
+            {{view.liveComponents}}/{{view.totalComponents}}
+          {{/view}}
+        </span>
         {{t services.service.summary.JournalNodesLive}}
+      {{else}}
+        {{t common.noData}}
+      {{/if}}
     </td>
   </tr>
 {{/if}}
 <!-- NFS Gateway -->
 {{#if view.isNfsInStack}}
   <tr>
-    <td class="summary-label"><a href="#" {{action filterHosts view.nfsGatewayComponent}}>{{t dashboard.services.hdfs.nfsgateways}}</a></td>
+    <td class="summary-label"><a
+            href="#" {{action filterHosts view.nfsGatewayComponent}}>{{t dashboard.services.hdfs.nfsgateways}}</a></td>
     <td>
-      <span>
-        {{#view App.ComponentLiveTextView liveComponentsBinding="view.service.nfsGatewaysStarted" totalComponentsBinding="view.service.nfsGatewaysTotal"}}
-          {{view.liveComponents}}/{{view.totalComponents}}
-        {{/view}}
-      </span>
-      {{t common.started}}
+      {{#if App.router.clusterController.isComponentsStateLoaded}}
+        <span>
+          {{#view App.ComponentLiveTextView liveComponentsBinding="view.service.nfsGatewaysStarted" totalComponentsBinding="view.service.nfsGatewaysTotal"}}
+            {{view.liveComponents}}/{{view.totalComponents}}
+          {{/view}}
+        </span>
+        {{t common.started}}
+      {{else}}
+        {{t common.noData}}
+      {{/if}}
     </td>
   </tr>
 {{/if}}
@@ -99,38 +117,38 @@
   <table class="summary-info table no-borders table-condensed">
     <tbody>
 
-<tr>
-  <td class="summary-label">{{t dashboard.services.hdfs.capacity.remaining}}</td>
-  <td>{{view.remainingDisk}}</td>
-</tr>
-<!-- Blocks Total -->
-<tr>
-  <td class="summary-label">{{t services.service.summary.blocksTotal}}</td>
-  <td>{{view.dfsTotalBlocks}}</td>
-</tr>
-<!-- Block Errors -->
-<tr>
-  <td class="summary-label">{{t services.service.summary.blockErrors}}</td>
-  <td>
-    {{view.blockErrorsMessage}}
-  </td>
-</tr>
-<!-- Total Files And Directories -->
-<tr>
-  <td class="summary-label">{{t dashboard.services.hdfs.totalFilesAndDirs}}</td>
-  <td>{{view.dfsTotalFiles}}</td>
-</tr>
-<!-- Upgrade Status -->
-<tr>
-  <td class="summary-label">{{t services.service.summary.pendingUpgradeStatus}}</td>
-  <td>
-    <span {{bindAttr class="view.isUpgradeStatusWarning:upgrade-status-warning"}}>{{view.upgradeStatus}}</span>
-  </td>
-</tr>
-<!-- Safe Mode Status -->
-<tr>
-  <td class="summary-label">{{t services.service.summary.safeModeStatus}}</td>
-  <td>
-    {{view.safeModeStatus}}
-  </td>
-</tr>
+    <tr>
+      <td class="summary-label">{{t dashboard.services.hdfs.capacity.remaining}}</td>
+      <td>{{view.remainingDisk}}</td>
+    </tr>
+    <!-- Blocks Total -->
+    <tr>
+      <td class="summary-label">{{t services.service.summary.blocksTotal}}</td>
+      <td>{{view.dfsTotalBlocks}}</td>
+    </tr>
+    <!-- Block Errors -->
+    <tr>
+      <td class="summary-label">{{t services.service.summary.blockErrors}}</td>
+      <td>
+        {{view.blockErrorsMessage}}
+      </td>
+    </tr>
+    <!-- Total Files And Directories -->
+    <tr>
+      <td class="summary-label">{{t dashboard.services.hdfs.totalFilesAndDirs}}</td>
+      <td>{{view.dfsTotalFiles}}</td>
+    </tr>
+    <!-- Upgrade Status -->
+    <tr>
+      <td class="summary-label">{{t services.service.summary.pendingUpgradeStatus}}</td>
+      <td>
+        <span {{bindAttr class="view.isUpgradeStatusWarning:upgrade-status-warning"}}>{{view.upgradeStatus}}</span>
+      </td>
+    </tr>
+    <!-- Safe Mode Status -->
+    <tr>
+      <td class="summary-label">{{t services.service.summary.safeModeStatus}}</td>
+      <td>
+        {{view.safeModeStatus}}
+      </td>
+    </tr>

+ 52 - 47
ambari-web/app/templates/main/service/services/storm.hbs

@@ -24,61 +24,66 @@
     </a>
   </td>
   <td>
-    <span>
-      {{#view App.ComponentLiveTextView liveComponentsBinding="view.superVisorsLive" totalComponentsBinding="view.superVisorsTotal"}}
-        {{view.liveComponents}}/{{view.totalComponents}}
-      {{/view}}
-    </span> {{t services.service.summary.SupervisorsLIVE}}
+    {{#if App.router.clusterController.isComponentsStateLoaded}}
+      <span>
+        {{#view App.ComponentLiveTextView liveComponentsBinding="view.superVisorsLive" totalComponentsBinding="view.superVisorsTotal"}}
+          {{view.liveComponents}}/{{view.totalComponents}}
+        {{/view}}
+      </span> {{t services.service.summary.SupervisorsLIVE}}
+    {{else}}
+      {{t common.noData}}
+    {{/if}}
   </td>
 </tr>
 
 <!-- Divider-- make the remaining summary info on 2nd table-->
-    </tbody>
-  </table>
+</tbody>
+</table>
 </div>
 <div class="span6">
   <table class="summary-info table no-borders table-condensed">
     <tbody>
 
-<tr>
-  <td class="summary-label">
-    {{t services.service.summary.storm.freeslots}}
-  </td>
-  <td>
-    {{formatNull view.service.freeSlots}} / {{formatNull view.service.totalSlots}} ({{formatNull view.freeSlotsPercentage empty="0"}}% {{t common.free}})
-  </td>
-</tr>
-<tr>
-  <td class="summary-label">
-    {{t services.service.summary.storm.tasks}}
-  </td>
-  <td>
-    {{formatNull view.service.totalTasks}}
-  </td>
-</tr>
-<tr>
-  <td class="summary-label">
-    {{t services.service.summary.storm.executors}}
-  </td>
-  <td>
-    {{formatNull view.service.totalExecutors}}
-  </td>
-</tr>
-<tr>
-  <td class="summary-label">
-    {{t services.service.summary.storm.topologies}}
-  </td>
-  <td>
-    {{formatNull view.service.topologies}}
-  </td>
-</tr>
-<tr>
-  <td class="summary-label">
-    {{t services.service.summary.storm.nimbus.uptime}}
-  </td>
-  <td>
-    {{view.nimbusUptimeFormatted}}
-  </td>
-</tr>
+    <tr>
+      <td class="summary-label">
+        {{t services.service.summary.storm.freeslots}}
+      </td>
+      <td>
+        {{formatNull view.service.freeSlots}} / {{formatNull view.service.totalSlots}}
+        ({{formatNull view.freeSlotsPercentage empty="0"}}% {{t common.free}})
+      </td>
+    </tr>
+    <tr>
+      <td class="summary-label">
+        {{t services.service.summary.storm.tasks}}
+      </td>
+      <td>
+        {{formatNull view.service.totalTasks}}
+      </td>
+    </tr>
+    <tr>
+      <td class="summary-label">
+        {{t services.service.summary.storm.executors}}
+      </td>
+      <td>
+        {{formatNull view.service.totalExecutors}}
+      </td>
+    </tr>
+    <tr>
+      <td class="summary-label">
+        {{t services.service.summary.storm.topologies}}
+      </td>
+      <td>
+        {{formatNull view.service.topologies}}
+      </td>
+    </tr>
+    <tr>
+      <td class="summary-label">
+        {{t services.service.summary.storm.nimbus.uptime}}
+      </td>
+      <td>
+        {{view.nimbusUptimeFormatted}}
+      </td>
+    </tr>
 
 

+ 41 - 36
ambari-web/app/templates/main/service/services/yarn.hbs

@@ -19,13 +19,18 @@
 
 <!-- NodeManagers -->
 <tr>
-  <td class="summary-label"><a href="#" {{action filterHosts view.nodeManagerComponent}}>{{t dashboard.services.yarn.nodeManagers}}</a></td>
+  <td class="summary-label"><a
+          href="#" {{action filterHosts view.nodeManagerComponent}}>{{t dashboard.services.yarn.nodeManagers}}</a></td>
   <td>
-    <span>
-      {{#view App.ComponentLiveTextView liveComponentsBinding="view.service.nodeManagersStarted" totalComponentsBinding="view.service.nodeManagersTotal"}}
-        {{view.liveComponents}}/{{view.totalComponents}}
-      {{/view}}
-    </span>{{t common.started}}
+    {{#if App.router.clusterController.isComponentsStateLoaded}}
+      <span>
+        {{#view App.ComponentLiveTextView liveComponentsBinding="view.service.nodeManagersStarted" totalComponentsBinding="view.service.nodeManagersTotal"}}
+          {{view.liveComponents}}/{{view.totalComponents}}
+        {{/view}}
+      </span>{{t common.started}}
+    {{else}}
+      {{t common.noData}}
+    {{/if}}
   </td>
 </tr>
 <!-- NodeManagers status -->
@@ -36,7 +41,7 @@
 <!-- YARN Clients -->
 <tr>
   <td class="summary-label"><a {{action filterHosts view.yarnClientComponent}}
-      href="javascript:void(null)">{{pluralize view.service.installedClients singular="t:dashboard.services.yarn.client" plural="t:dashboard.services.yarn.clients"}}</a>
+          href="javascript:void(null)">{{pluralize view.service.installedClients singular="t:dashboard.services.yarn.client" plural="t:dashboard.services.yarn.clients"}}</a>
   </td>
   <td>
     <span class="green-live">{{view.service.installedClients}} </span>
@@ -50,37 +55,37 @@
 </tr>
 
 <!-- Divider-- make the remaining summary info on 2nd table-->
-    </tbody>
-  </table>
+</tbody>
+</table>
 </div>
 <div class="span6">
   <table class="summary-info table no-borders table-condensed">
     <tbody>
 
-<!-- ResourceManager Heap -->
-<tr>
-  <td class="summary-label">{{t dashboard.services.resourceManager.nodes.heap}}</td>
-  <td>{{view.nodeHeap}}</td>
-</tr>
-<!-- Containers -->
-<tr>
-  <td class="summary-label">{{t dashboard.services.yarn.containers}}</td>
-  <td>{{view.containers}}</td>
-</tr>
-<!-- Applications -->
-<tr>
-  <td class="summary-label">{{t dashboard.services.yarn.apps}}</td>
-  <td>{{view.apps}}</td>
-</tr>
-<!-- Memory -->
-<tr>
-  <td class="summary-label">{{t dashboard.services.yarn.memory}}</td>
-  <td>{{view.memory}}</td>
-</tr>
-<!-- Queues -->
-<tr>
-  <td class="summary-label">{{t dashboard.services.yarn.queues}}</td>
-  <td><span rel="queue-tooltip"
-            class="text-tooltip" {{bindAttr data-original-title="view.service.queueFormatted" }}>{{view.queues}}</span>
-  </td>
-</tr>
+    <!-- ResourceManager Heap -->
+    <tr>
+      <td class="summary-label">{{t dashboard.services.resourceManager.nodes.heap}}</td>
+      <td>{{view.nodeHeap}}</td>
+    </tr>
+    <!-- Containers -->
+    <tr>
+      <td class="summary-label">{{t dashboard.services.yarn.containers}}</td>
+      <td>{{view.containers}}</td>
+    </tr>
+    <!-- Applications -->
+    <tr>
+      <td class="summary-label">{{t dashboard.services.yarn.apps}}</td>
+      <td>{{view.apps}}</td>
+    </tr>
+    <!-- Memory -->
+    <tr>
+      <td class="summary-label">{{t dashboard.services.yarn.memory}}</td>
+      <td>{{view.memory}}</td>
+    </tr>
+    <!-- Queues -->
+    <tr>
+      <td class="summary-label">{{t dashboard.services.yarn.queues}}</td>
+      <td><span rel="queue-tooltip"
+                class="text-tooltip" {{bindAttr data-original-title="view.service.queueFormatted" }}>{{view.queues}}</span>
+      </td>
+    </tr>

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

@@ -1214,7 +1214,7 @@ var urls = {
     }
   },
   'cluster.load_cluster_name': {
-    'real': '/clusters',
+    'real': '/clusters?fields=Clusters/security_type',
     'mock': '/data/clusters/info.json'
   },
   'cluster.load_last_upgrade': {

+ 23 - 6
ambari-web/app/utils/components.js

@@ -22,7 +22,7 @@ module.exports = {
     var self = this,
         componentName = component.get('componentName'),
         displayName = component.get('displayName');
-    this.createServiceComponent(componentName).done(function () {
+    this.updateAndCreateServiceComponent(componentName).done(function () {
       App.ajax.send({
         name: 'host.host_component.add_new_component',
         sender: self,
@@ -178,9 +178,29 @@ module.exports = {
    * @param componentName
    * @returns {*}
    */
-  createServiceComponent: function (componentName) {
+  updateAndCreateServiceComponent: function (componentName) {
+    var self = this;
     var dfd = $.Deferred();
-    if (App.serviceComponents.contains(componentName)) {
+    App.router.get('updateController').updateComponentsState(function() {
+      self.createServiceComponent(componentName, dfd);
+    });
+    return dfd.promise();
+  },
+
+  /**
+   *
+   * @param componentName
+   * @param dfd
+   * @returns {*}
+   */
+  createServiceComponent: function(componentName, dfd) {
+    var allServiceComponents = [];
+    var services = App.Service.find().mapProperty('serviceName');
+    services.forEach(function(_service){
+      var _serviceComponents = App.Service.find(_service).get('serviceComponents');
+      allServiceComponents = allServiceComponents.concat(_serviceComponents);
+    }, this);
+    if (allServiceComponents.contains(componentName)) {
       dfd.resolve();
     } else {
       App.ajax.send({
@@ -192,10 +212,7 @@ module.exports = {
         }
       }).complete(function () {
         dfd.resolve();
-        App.serviceComponents.push(componentName);
       });
     }
-    return dfd.promise();
   }
-
 };

+ 1 - 1
ambari-web/app/utils/http_client.js

@@ -166,7 +166,7 @@ App.HttpClient = Em.Object.create({
    * @param {Object} data - ajax data property
    * @param {App.ServerDataMapper} mapper - json processor
    * @param {callback} errorHandler
-   * @param {number} interval - frequecy request
+   * @param {number} interval - frequency request
    */
   post: function (url, data, mapper, errorHandler, interval) {
     this.get(url, data, mapper, errorHandler, interval);

+ 1 - 1
ambari-web/app/utils/updater.js

@@ -104,7 +104,7 @@ App.updater = {
    * @param obj Object
    * @param name Method name
    * @param isWorking Property, which will be checked as a rule for working
-   * @param interval Interval between calls
+   * @param [interval] Interval between calls
    * @return {*}
    */
   run: function(obj, name, isWorking, interval){

+ 21 - 5
ambari-web/app/views/main/dashboard/widgets/datanode_live.js

@@ -42,17 +42,29 @@ App.DataNodeUpView = App.TextDashboardWidgetView.extend({
   maxValue: 100,
 
   dataNodesLive: function () {
-    return this.get('model.metricsNotAvailable') ? Em.I18n.t('services.service.summary.notAvailable') : this.get('model.liveDataNodes.length');
+    if (!Em.isNone(this.get('model.liveDataNodes')) && !this.get('model.metricsNotAvailable')) {
+      return this.get('model.liveDataNodes.length');
+    } else {
+      return   Em.I18n.t('services.service.summary.notAvailable');
+    }
   }.property('model.liveDataNodes.length'),
   dataNodesDead: function () {
-    return this.get('model.metricsNotAvailable') ? Em.I18n.t('services.service.summary.notAvailable') : this.get('model.deadDataNodes.length');
+    if (!Em.isNone(this.get('model.deadDataNodes')) && !this.get('model.metricsNotAvailable')) {
+      return this.get('model.deadDataNodes.length');
+    } else {
+      return   Em.I18n.t('services.service.summary.notAvailable');
+    }
   }.property('model.deadDataNodes.length'),
   dataNodesDecom: function () {
-    return this.get('model.metricsNotAvailable') ? Em.I18n.t('services.service.summary.notAvailable') : this.get('model.decommissionDataNodes.length');
+    if (!Em.isNone(this.get('model.decommissionDataNodes')) && !this.get('model.metricsNotAvailable')) {
+      return this.get('model.decommissionDataNodes.length');
+    } else {
+      return   Em.I18n.t('services.service.summary.notAvailable');
+    }
   }.property('model.decommissionDataNodes.length'),
 
   data: function () {
-    if (this.get('model.metricsNotAvailable')) {
+    if (Em.isNone(this.get('model.liveDataNodes')) || Em.isNone(this.get('model.dataNodesTotal')) || this.get('model.metricsNotAvailable')) {
       return null;
     } else {
       return ((this.get('dataNodesLive') / this.get('model.dataNodesTotal')).toFixed(2)) * 100;
@@ -60,7 +72,11 @@ App.DataNodeUpView = App.TextDashboardWidgetView.extend({
   }.property('model.dataNodesTotal', 'dataNodesLive'),
 
   content: function () {
-    return this.get('model.metricsNotAvailable') ? Em.I18n.t('services.service.summary.notAvailable') : this.get('dataNodesLive') + "/" + this.get('model.dataNodesTotal');
+    if (Em.isNone(this.get('model.liveDataNodes')) || Em.isNone(this.get('model.dataNodesTotal')) || this.get('model.metricsNotAvailable')) {
+      return  Em.I18n.t('services.service.summary.notAvailable');
+    } else {
+      return this.get('dataNodesLive') + "/" + this.get('model.dataNodesTotal');
+    }
   }.property('model.dataNodesTotal', 'dataNodesLive'),
 
   editWidget: function (event) {

+ 6 - 2
ambari-web/app/views/main/dashboard/widgets/node_managers_live.js

@@ -46,6 +46,10 @@ App.NodeManagersLiveView = App.TextDashboardWidgetView.extend({
   thresh2: 70,
   maxValue: 100,
 
+  isDataAvailable: function() {
+    return !this.get('model.metricsNotAvailable') &&  App.get('router.clusterController.isComponentsStateLoaded');
+  }.property('App.router.clusterController.isComponentsStateLoaded'),
+
   nodeManagersLive: function () {
     return this.get('model.nodeManagersCountActive');
   }.property('model.nodeManagersCountActive'),
@@ -53,7 +57,7 @@ App.NodeManagersLiveView = App.TextDashboardWidgetView.extend({
   data: function () {
     var nodeManagers = this.get('model.nodeManagersTotal');
     var nodeManagersLive = this.get('nodeManagersLive');
-    if (nodeManagersLive == null) {
+    if (nodeManagersLive == null || !nodeManagers) {
       return null;
     } else {
       return (nodeManagersLive / nodeManagers).toFixed(2) * 100;
@@ -61,7 +65,7 @@ App.NodeManagersLiveView = App.TextDashboardWidgetView.extend({
   }.property('model.nodeManagersTotal', 'nodeManagersLive'),
 
   content: function () {
-    return this.get('nodeManagersLive') == null ? Em.I18n.t('services.service.summary.notAvailable') : this.get('nodeManagersLive') + '/' + this.get('model.nodeManagersTotal');
+    return this.get('nodeManagersLive') == null || !this.get('model.nodeManagersTotal') ? Em.I18n.t('services.service.summary.notAvailable') : this.get('nodeManagersLive') + '/' + this.get('model.nodeManagersTotal');
   }.property('model.nodeManagersTotal', 'nodeManagersLive'),
 
   editWidget: function (event) {

+ 6 - 2
ambari-web/app/views/main/dashboard/widgets/supervisor_live.js

@@ -53,7 +53,7 @@ App.SuperVisorUpView = App.TextDashboardWidgetView.extend({
   }.property('model.superVisorsTotal'),
 
   data: function () {
-    if ( !this.get('superVisorsTotal')) {
+    if ( !this.get('superVisorsTotal') || Em.isNone(this.get('superVisorsLive'))) {
       return -1;
     } else {
       return ((this.get('superVisorsLive') / this.get('superVisorsTotal')).toFixed(2)) * 100;
@@ -61,7 +61,11 @@ App.SuperVisorUpView = App.TextDashboardWidgetView.extend({
   }.property('superVisorsTotal', 'superVisorsLive'),
 
   content: function () {
-    return this.get('superVisorsLive') + "/" + this.get('superVisorsTotal');
+    if (!Em.isNone(this.get('superVisorsTotal')) && !Em.isNone(this.get('superVisorsLive'))) {
+      return this.get('superVisorsLive') + "/" + this.get('superVisorsTotal');
+    } else {
+      return Em.I18n.t('services.service.summary.notAvailable');
+    }
   }.property('superVisorsLive', 'superVisorsTotal'),
 
   editWidget: function (event) {

+ 16 - 6
ambari-web/app/views/main/host/details/host_component_view.js

@@ -207,7 +207,7 @@ App.HostComponentView = Em.View.extend({
    */
   isDeleteComponentDisabled: function () {
     var stackComponentCount = App.StackServiceComponent.find(this.get('hostComponent.componentName')).get('minToInstall');
-    var installedCount = this.componentCounter();
+    var installedCount = this.get('componentCounter');
     return (installedCount <= stackComponentCount)
       || ![App.HostComponentStatus.stopped, App.HostComponentStatus.unknown, App.HostComponentStatus.install_failed, App.HostComponentStatus.upgrade_failed, App.HostComponentStatus.init].contains(this.get('workStatus'));
   }.property('workStatus'),
@@ -217,10 +217,20 @@ App.HostComponentView = Em.View.extend({
    * @returns {Number}
    */
   componentCounter: function() {
-    return App.StackServiceComponent.find(this.get('hostComponent.componentName')).get('isMaster')
-      ? App.HostComponent.find().filterProperty('componentName', this.get('content.componentName')).length
-      : App.SlaveComponent.find().findProperty('componentName', this.get('content.componentName')).get('totalCount');
-  },
+    var componentCounter = 0;
+    var stackServiceComponent =  App.StackServiceComponent.find(this.get('hostComponent.componentName'));
+    if (stackServiceComponent && App.get('router.clusterController.isHostContentLoaded')) {
+      if (stackServiceComponent.get('isMaster')) {
+          componentCounter = App.HostComponent.find().filterProperty('componentName', this.get('content.componentName')).length
+      } else {
+        var slaveComponent = App.SlaveComponent.find().findProperty('componentName', this.get('content.componentName'));
+        if (slaveComponent) {
+          componentCounter = slaveComponent.get('totalCount');
+        }
+      }
+    }
+    return componentCounter;
+  }.property('App.router.clusterController.isHostContentLoaded'),
 
   /**
    * Gets number of current running components that are applied to the cluster
@@ -386,7 +396,7 @@ App.HostComponentView = Em.View.extend({
 
     if (component.get('cardinality') !== '1') {
       if (!this.get('isStart')) {
-        if (this.componentCounter() > 1) {
+        if (this.get('componentCounter') > 1) {
           if (this.runningComponentCounter()) {
             return false;
           }

+ 16 - 12
ambari-web/app/views/main/host/summary.js

@@ -276,19 +276,23 @@ App.MainHostSummaryView = Em.View.extend({
   addableComponents: function () {
     var components = [];
     var self = this;
-    var installedComponents = this.get('content.hostComponents').mapProperty('componentName');
-    var addableToHostComponents = App.StackServiceComponent.find().filterProperty('isAddableToHost');
-    var installedServices = this.get('installedServices');
-
-    addableToHostComponents.forEach(function(addableComponent) {
-      if(installedServices.contains(addableComponent.get('serviceName')) && !installedComponents.contains(addableComponent.get('componentName'))) {
-        if ((addableComponent.get('componentName') === 'OOZIE_SERVER') && !App.router.get('mainHostDetailsController.isOozieServerAddable')) {
-          return;
+    if (this.get('content.hostComponents')) {
+      var installedComponents = this.get('content.hostComponents').mapProperty('componentName');
+      var addableToHostComponents = App.StackServiceComponent.find().filterProperty('isAddableToHost');
+      var installedServices = this.get('installedServices');
+
+      addableToHostComponents.forEach(function (addableComponent) {
+        if (installedServices.contains(addableComponent.get('serviceName')) && !installedComponents.contains(addableComponent.get('componentName'))) {
+          if ((addableComponent.get('componentName') === 'OOZIE_SERVER') && !App.router.get('mainHostDetailsController.isOozieServerAddable')) {
+            return;
+          }
+          components.pushObject(self.addableComponentObject.create({
+            'componentName': addableComponent.get('componentName'),
+            'serviceName': addableComponent.get('serviceName')
+          }));
         }
-        components.pushObject(self.addableComponentObject.create({'componentName': addableComponent.get('componentName'), 'serviceName': addableComponent.get('serviceName')}));
-      }
-    });
-
+      });
+    }
     return components;
   }.property('content.hostComponents.length', 'installableClientComponents', 'App.components.addableToHost.@each'),
 

+ 4 - 1
ambari-web/app/views/main/service/info/configs.js

@@ -24,7 +24,10 @@ App.MainServiceInfoConfigsView = Em.View.extend({
   templateName: require('templates/main/service/info/configs'),
 
   didInsertElement: function () {
-    this.get('controller').loadStep();
+    var self = this;
+    App.router.get('mainController').isLoading.call(App.router.get('clusterController'), 'isConfigsPropertiesLoaded').done(function () {
+      self.get('controller').loadStep();
+    });
   },
 
   /**

+ 2 - 2
ambari-web/app/views/main/service/reassign/step5_view.js

@@ -56,7 +56,7 @@ App.ReassignMasterWizardStep5View = Em.View.extend({
     if(!hasSecureConfigs) {
       secureConfigs = [];
     }
-    if (!this.get('controller.content.securityEnabled') || !secureConfigs.length) {
+    if (!App.get('isKerberosEnabled') || !secureConfigs.length) {
       return proceedMsg;
     }
     var formattedText = '<ul>';
@@ -66,5 +66,5 @@ App.ReassignMasterWizardStep5View = Em.View.extend({
     }, this);
     formattedText += '</ul>';
     return Em.I18n.t('services.reassign.step5.body.securityNotice').format(formattedText) + proceedMsg;
-  }.property('controller.content.securityEnabled', 'controller.content.secureConfigs', 'controller.content.reassignHosts.target')
+  }.property('App.isKerberosEnabled','controller.content.secureConfigs', 'controller.content.reassignHosts.target')
 });

+ 0 - 117
ambari-web/test/controllers/global/cluster_controller_test.js

@@ -201,123 +201,6 @@ describe('App.clusterController', function () {
     });
   });
 
-  describe('#setGangliaUrl()', function () {
-    beforeEach(function () {
-      controller.set('gangliaUrl', null);
-    });
-
-    it('testMode = true', function () {
-      App.testMode = true;
-      controller.setGangliaUrl();
-      expect(controller.get('gangliaUrl')).to.equal('http://gangliaserver/ganglia/?t=yes');
-      expect(controller.get('isGangliaUrlLoaded')).to.be.true;
-    });
-    it('Cluster is not loaded', function () {
-      App.testMode = false;
-      controller.set('isLoaded', false);
-      controller.setGangliaUrl();
-      expect(controller.get('gangliaUrl')).to.equal(null);
-    });
-    it('GANGLIA_SERVER component is absent', function () {
-      controller.set('isLoaded', true);
-      App.testMode = false;
-      sinon.stub(App.HostComponent, 'find', function(){
-        return [];
-      });
-      controller.setGangliaUrl();
-      expect(controller.get('gangliaUrl')).to.equal(null);
-      App.HostComponent.find.restore();
-    });
-    it('Ganglia Server host is "GANGLIA_host"', function () {
-      controller.set('isLoaded', true);
-      App.testMode = false;
-      sinon.stub(App.HostComponent, 'find', function(){
-        return [Em.Object.create({
-          componentName: 'GANGLIA_SERVER',
-          hostName: 'GANGLIA_host'
-        })];
-      });
-      sinon.spy(App.ajax, 'send');
-
-      controller.setGangliaUrl();
-      expect(App.ajax.send.calledOnce).to.be.true;
-      expect(controller.get('isGangliaUrlLoaded')).to.be.false;
-
-      App.HostComponent.find.restore();
-      App.ajax.send.restore();
-    });
-  });
-
-  describe('#gangliaWebProtocol', function () {
-    var testCases = [
-      {
-        title: 'if ambariProperties is null then gangliaWebProtocol should be "http"',
-        data: null,
-        result: 'http'
-      },
-      {
-        title: 'if ambariProperties is empty object then gangliaWebProtocol should be "http"',
-        data: {},
-        result: 'http'
-      },
-      {
-        title: 'if ganglia.https is false then gangliaWebProtocol should be "http"',
-        data: {'ganglia.https': false},
-        result: 'http'
-      },
-      {
-        title: 'if ganglia.https is true then gangliaWebProtocol should be "http"',
-        data: {'ganglia.https': true},
-        result: 'https'
-      }
-    ];
-
-    testCases.forEach(function (test) {
-      it(test.title, function () {
-        controller.set('ambariProperties', test.data);
-        expect(controller.get('gangliaWebProtocol')).to.equal(test.result);
-      });
-    });
-  });
-
-
-  describe('#setGangliaUrlSuccessCallback()', function () {
-
-    it('Query return no hosts', function () {
-      controller.setGangliaUrlSuccessCallback({items: []});
-      expect(controller.get('gangliaUrl')).to.equal(null);
-      expect(controller.get('isGangliaUrlLoaded')).to.be.true;
-    });
-    it('App.singleNodeInstall is true', function () {
-      controller.reopen({
-        gangliaWebProtocol: 'http'
-      });
-      App.set('singleNodeInstall', true);
-      App.set('singleNodeAlias', 'localhost');
-      controller.setGangliaUrlSuccessCallback({items: [{
-        Hosts: {
-          public_host_name: 'host1'
-        }
-      }]});
-      expect(controller.get('gangliaUrl')).to.equal('http://localhost:42080/ganglia');
-      expect(controller.get('isGangliaUrlLoaded')).to.be.true;
-    });
-    it('App.singleNodeInstall is false', function () {
-      controller.reopen({
-        gangliaWebProtocol: 'http'
-      });
-      App.set('singleNodeInstall', false);
-      App.set('singleNodeAlias', 'localhost');
-      controller.setGangliaUrlSuccessCallback({items: [{
-        Hosts: {
-          public_host_name: 'host1'
-        }
-      }]});
-      expect(controller.get('gangliaUrl')).to.equal('http://host1/ganglia');
-      expect(controller.get('isGangliaUrlLoaded')).to.be.true;
-    });
-  });
-
   describe("#createKerberosAdminSession()", function() {
     before(function () {
       sinon.stub(App.ajax, 'send', function() {

+ 5 - 5
ambari-web/test/controllers/main/admin/kerberos/step4_controller_test.js

@@ -284,7 +284,7 @@ describe('App.KerberosWizardStep4Controller', function() {
 
   describe('#loadStep', function() {
 
-    describe('skip "Configure Identities" step', function() {
+    describe('skip "Configure Identities" step. ', function() {
       beforeEach(function() {
         this.controller = App.KerberosWizardStep4Controller.create({});
         this.wizardController = App.AddServiceController.create({});
@@ -305,7 +305,7 @@ describe('App.KerberosWizardStep4Controller', function() {
       var tests = [
         {
           securityEnabled: true,
-          stepSkipped: false,
+          stepSkipped: false
         },
         {
           securityEnabled: false,
@@ -314,10 +314,10 @@ describe('App.KerberosWizardStep4Controller', function() {
       ];
 
       tests.forEach(function(test) {
-        it('security {0} configure identities step should be {1}'.format(!!test.securityEnabled ? 'enabled' : 'disabled', !!test.stepSkipped ? 'skipped' : 'not skipped'), function() {
-          sinon.stub(App.router, 'get').withArgs('mainAdminKerberosController.securityEnabled').returns(test.securityEnabled);
+        it('Security {0} configure identities step should be {1}'.format(!!test.securityEnabled ? 'enabled' : 'disabled', !!test.stepSkipped ? 'skipped' : 'not skipped'), function() {
+          sinon.stub(App, 'get').withArgs('isKerberosEnabled').returns(test.securityEnabled);
           this.wizardController.checkSecurityStatus();
-          App.router.get.restore();
+          App.get.restore();
           this.controller.loadStep();
           expect(App.router.send.calledWith('next')).to.be.eql(test.stepSkipped);
         });

+ 22 - 1
ambari-web/test/controllers/main/host/details_test.js

@@ -32,7 +32,8 @@ describe('App.MainHostDetailsController', function () {
 
   beforeEach(function () {
     sinon.stub(App.ajax, 'send').returns({
-      then: Em.K
+      then: Em.K,
+      complete: Em.K
     });
     controller = App.MainHostDetailsController.create({
       content: Em.Object.create()
@@ -566,6 +567,26 @@ describe('App.MainHostDetailsController', function () {
   });
 
   describe('#primary()', function () {
+    beforeEach(function () {
+      sinon.stub(App.StackServiceComponent, 'find', function () {
+        return [
+          Em.Object.create({
+            componentName: 'COMP1',
+            serviceName: 's1'
+          })
+        ]
+      });
+      sinon.stub(App.router, "get").withArgs('updateController').returns({
+        updateComponentsState: function(callback) {
+          return callback();
+        }
+      });
+    });
+    afterEach(function () {
+      App.router.get.restore();
+      App.StackServiceComponent.find.restore();
+    });
+
     it('Query should be sent', function () {
       var component = Em.Object.create({
         componentName: 'COMP1',

+ 2 - 2
ambari-web/test/controllers/main/service/add_controller_test.js

@@ -453,12 +453,12 @@ describe('App.AddServiceController', function() {
     });
 
     afterEach(function () {
-      App.router.get.restore();
+      App.get.restore();
     });
 
     cases.forEach(function (item) {
       it(item.title, function () {
-        sinon.stub(App.router, 'get').withArgs('mainAdminKerberosController.securityEnabled').returns(item.securityEnabled);
+        sinon.stub(App, 'get').withArgs('isKerberosEnabled').returns(item.securityEnabled);
         addServiceController.checkSecurityStatus();
         expect(addServiceController.get('skipConfigureIdentitiesStep')).to.equal(item.skipConfigureIdentitiesStep);
         expect(addServiceController.get('isStepDisabled').findProperty('step', 5).get('value')).to.equal(item.isStep5Disabled);

+ 0 - 3
ambari-web/test/controllers/main/service/item_test.js

@@ -146,13 +146,11 @@ describe('App.MainServiceItemController', function () {
 
       beforeEach(function () {
         sinon.stub(reassignMasterController, 'saveComponentToReassign', Em.K);
-        sinon.stub(reassignMasterController, 'getSecurityStatus', Em.K);
         sinon.stub(reassignMasterController, 'setCurrentStep', Em.K);
       });
 
       afterEach(function () {
         reassignMasterController.saveComponentToReassign.restore();
-        reassignMasterController.getSecurityStatus.restore();
         reassignMasterController.setCurrentStep.restore();
       });
 
@@ -168,7 +166,6 @@ describe('App.MainServiceItemController', function () {
         });
         mainServiceItemController.reassignMaster(test.componentName);
         expect(reassignMasterController.saveComponentToReassign.calledOnce).to.equal(test.result);
-        expect(reassignMasterController.getSecurityStatus.calledOnce).to.equal(test.result);
         expect(reassignMasterController.setCurrentStep.calledOnce).to.equal(test.result);
         App.HostComponent.find.restore();
         App.router.transitionTo.restore();

+ 14 - 10
ambari-web/test/controllers/main/service/reassign/step4_controller_test.js

@@ -897,34 +897,37 @@ describe('App.ReassignMasterWizardStep4Controller', function () {
   describe('#setSecureConfigs()', function () {
     it('undefined component and security disabled', function () {
       var secureConfigs = [];
-      controller.set('content.securityEnabled', false);
-      controller.set('secureConfigsMap', []);
-      expect(controller.setSecureConfigs(secureConfigs, {}, 'COMP1')).to.be.false;
-      expect(secureConfigs).to.eql([]);
-    });
-    it('undefined component and security enabled', function () {
-      var secureConfigs = [];
-      controller.set('content.securityEnabled', true);
+      sinon.stub(App, 'get').withArgs('isKerberosEnabled').returns(false);
       controller.set('secureConfigsMap', []);
       expect(controller.setSecureConfigs(secureConfigs, {}, 'COMP1')).to.be.false;
       expect(secureConfigs).to.eql([]);
+      App.get.restore();
     });
     it('component exist and security disabled', function () {
       var secureConfigs = [];
-      controller.set('content.securityEnabled', false);
+      sinon.stub(App, 'get').withArgs('isKerberosEnabled').returns(false);
       controller.set('secureConfigsMap', [{
         componentName: 'COMP1'
       }]);
       expect(controller.setSecureConfigs(secureConfigs, {}, 'COMP1')).to.be.false;
       expect(secureConfigs).to.eql([]);
+      App.get.restore();
+    });
+    it('undefined component and security enabled', function () {
+      var secureConfigs = [];
+      sinon.stub(App, 'get').withArgs('isKerberosEnabled').returns(true);
+      controller.set('secureConfigsMap', []);
+      expect(controller.setSecureConfigs(secureConfigs, {}, 'COMP1')).to.be.false;
+      expect(secureConfigs).to.eql([]);
+      App.get.restore();
     });
     it('component exist and security enabled', function () {
       var secureConfigs = [];
+      sinon.stub(App, 'get').withArgs('isKerberosEnabled').returns(true);
       var configs = {'s1': {
         'k1': 'kValue',
         'p1': 'pValue'
       }};
-      controller.set('content.securityEnabled', true);
       controller.set('secureConfigsMap', [{
         componentName: 'COMP1',
         configs: [{
@@ -940,6 +943,7 @@ describe('App.ReassignMasterWizardStep4Controller', function () {
           "principal": "pValue"
         }
       ]);
+      App.get.restore();
     });
   });
 

+ 1 - 1
ambari-web/test/controllers/main/service_test.js

@@ -141,7 +141,7 @@ describe('App.MainServiceController', function () {
     ]).forEach(function(test) {
         it(test.m, function() {
           sinon.stub(App.router, 'get', function(k) {
-            if ('clusterController.isLoaded' === k) return test.isLoaded;
+            if ('clusterController.isClusterDataLoaded' === k) return test.isLoaded;
             return Em.get(App.router, k);
           });
           sinon.stub(App.Cluster, 'find', function() {

+ 5 - 1
ambari-web/test/controllers/wizard/step8_test.js

@@ -1458,6 +1458,7 @@ describe('App.WizardStep8Controller', function () {
     });
     afterEach(function() {
       installerStep8Controller.submitProceed.restore();
+      App.set('isKerberosEnabled', false);
       App.get('router.mainAdminKerberosController').getKDCSessionState.restore();
     });
     Em.A([
@@ -1478,7 +1479,8 @@ describe('App.WizardStep8Controller', function () {
         }
       ]).forEach(function (test) {
         it(test.controllerName + ' Kerberos enabled - ' + test.securityEnabled.toString() + ' manual kerberos - ' + test.isManualKerberos, function () {
-          installerStep8Controller.reopen({isSubmitDisabled: false, securityEnabled: test.securityEnabled, isManualKerberos: test.isManualKerberos, content: {controllerName: test.controllerName}});
+          App.set('isKerberosEnabled', test.securityEnabled);
+          installerStep8Controller.reopen({isSubmitDisabled: false, isManualKerberos: test.isManualKerberos, content: {controllerName: test.controllerName}});
           installerStep8Controller.submit();
           if (test.securityEnabled) {
             if (test.isManualKerberos) {
@@ -2332,6 +2334,7 @@ describe('App.WizardStep8Controller', function () {
       ];
 
     beforeEach(function () {
+      sinon.stub(App, 'get').withArgs('isKerberosEnabled').returns(false);
       stubbedNames.forEach(function (name) {
         sinon.stub(installerStep8Controller, name, Em.K);
       });
@@ -2344,6 +2347,7 @@ describe('App.WizardStep8Controller', function () {
     });
 
     afterEach(function () {
+      App.get.restore();
       stubbedNames.forEach(function (name) {
         installerStep8Controller[name].restore();
       });

+ 10 - 1
ambari-web/test/mixins/wizard/wizardProgressPageController_test.js

@@ -26,7 +26,14 @@ describe('App.wizardProgressPageControllerMixin', function() {
     beforeEach(function() {
       mixedObjectInstance = mixedObject.create({});
       sinon.stub(App.ajax, 'send', function(params) {
-        return params;
+        return $.extend(params,{complete: function(callback){
+          callback();
+        }});
+      });
+      sinon.stub(require('utils/components'), "updateAndCreateServiceComponent").returns({
+        done: function(callback) {
+          return callback();
+        }
       });
       sinon.spy(mixedObjectInstance, 'onCreateComponent');
       sinon.spy(mixedObjectInstance, 'updateComponent');
@@ -63,6 +70,7 @@ describe('App.wizardProgressPageControllerMixin', function() {
     afterEach(function() {
       App.ajax.send.restore();
       App.StackServiceComponent.find.restore();
+      require('utils/components').updateAndCreateServiceComponent.restore();
       mixedObjectInstance.onCreateComponent.restore();
       mixedObjectInstance.updateComponent.restore();
       mixedObjectInstance.checkInstalledComponents.restore();
@@ -81,6 +89,7 @@ describe('App.wizardProgressPageControllerMixin', function() {
     it('no ZooKeeper Servers installed. install on host1, host2. ajax request should be called with appropriate params', function() {
       mixedObjectInstance.createComponent('ZOOKEEPER_SERVER', ['host1', 'host2'], 'ZOOKEEPER');
       var args = App.ajax.send.args[0][0];
+
       var queryObject = JSON.parse(args.data.data);
       expect(args.data.hostName).to.be.eql(['host1', 'host2']);
       expect(queryObject.RequestInfo.query).to.be.eql('Hosts/host_name=host1|Hosts/host_name=host2');

+ 11 - 13
ambari-web/test/router_test.js

@@ -24,26 +24,24 @@ describe('App.Router', function () {
   var router = App.Router.create();
 
   describe('#loginSuccessCallback()', function() {
-    it('should log in user and load views', function () {
-      var mainViewsControllerMock = Em.Object.create({
-        loadAmbariViews: sinon.stub()
-      });
-      var userName = 'test';
+
+    beforeEach(function () {
       sinon.stub(App.usersMapper, 'map');
       sinon.stub(router, 'setUserLoggedIn');
-      sinon.stub(App.router, 'get').withArgs('mainViewsController').returns(mainViewsControllerMock);
       sinon.stub(App.ajax, 'send');
+    });
 
-      router.loginSuccessCallback({},{},{loginName: userName});
-
-      expect(mainViewsControllerMock.loadAmbariViews.calledOnce).to.be.true;
-      expect(router.setUserLoggedIn.calledOnce).to.be.true;
-      expect(router.setUserLoggedIn.calledWith(userName)).to.be.true;
-
+    afterEach(function() {
       App.usersMapper.map.restore();
       router.setUserLoggedIn.restore();
-      App.router.get.restore();
       App.ajax.send.restore();
+    });
+
+    it('should log in user and load views', function () {
+      var userName = 'test';
+      router.loginSuccessCallback({},{},{loginName: userName});
+      expect(router.setUserLoggedIn.calledOnce).to.be.true;
+      expect(router.setUserLoggedIn.calledWith(userName)).to.be.true;
     })
   });
 

+ 9 - 1
ambari-web/test/views/main/dashboard/widgets/node_managers_live_test.js

@@ -25,6 +25,14 @@ require('views/main/dashboard/widgets/node_managers_live');
 
 describe('App.NodeManagersLiveView', function() {
 
+  beforeEach(function () {
+    sinon.stub(App, 'get').withArgs('router.clusterController.isComponentsStateLoaded').returns(true);
+  });
+
+  afterEach(function () {
+    App.get.restore();
+  });
+
   var tests = [
     {
       model: {
@@ -71,7 +79,7 @@ describe('App.NodeManagersLiveView', function() {
   ];
 
   tests.forEach(function(test) {
-    describe('nodeManagerNodes length - ' + test.model.nodeManagersTotal + ' | nodeManagerLiveNodes length - ' + test.model.nodeManagerLiveNodes, function() {
+    describe('nodeManagersTotal length - ' + test.model.nodeManagersTotal + ' | nodeManagerLiveNodes length - ' + test.model.nodeManagerLiveNodes, function() {
       var AppNodeManagersLiveView = App.NodeManagersLiveView.extend({nodeManagersLive: test.model.nodeManagerLiveNodes});
       var nodeManagersLiveView = AppNodeManagersLiveView.create({model_type:null, model: test.model});
       it('content', function() {

+ 5 - 17
ambari-web/test/views/main/host/details/host_component_view_test.js

@@ -36,6 +36,7 @@ describe('App.HostComponentView', function() {
       return Em.get(App.router, k);
     });
     hostComponentView = App.HostComponentView.create({
+      componentCounter: 1,
       startBlinking: function(){},
       doBlinking: function(){},
       getDesiredAdminState: function(){return $.ajax({});},
@@ -242,16 +243,12 @@ describe('App.HostComponentView', function() {
   describe('#isDeleteComponentDisabled', function() {
 
     beforeEach(function() {
-      sinon.stub(hostComponentView, 'componentCounter', function() {
-        return 1;
-      });
       sinon.stub(App.StackServiceComponent, 'find', function(component) {
         var min = component == 'comp0' ? 0 : 1;
         return Em.Object.create({minToInstall: min});
       });
     });
     afterEach(function() {
-      hostComponentView.componentCounter.restore();
       App.StackServiceComponent.find.restore();
     });
 
@@ -509,9 +506,7 @@ describe('App.HostComponentView', function() {
         });
       });
 
-      sinon.stub(hostComponentView, 'componentCounter', function() {
-        return 2;
-      });
+      hostComponentView.set('componentCounter', 2);
 
       sinon.stub(hostComponentView, 'runningComponentCounter', function () {
         return 1;
@@ -533,9 +528,7 @@ describe('App.HostComponentView', function() {
         });
       });
 
-      sinon.stub(hostComponentView, 'componentCounter', function() {
-        return 2;
-      });
+      hostComponentView.set('componentCounter', 2);
 
       sinon.stub(hostComponentView, 'runningComponentCounter', function () {
         return 0;
@@ -557,9 +550,7 @@ describe('App.HostComponentView', function() {
         });
       });
 
-      sinon.stub(hostComponentView, 'componentCounter', function() {
-        return 2;
-      });
+      hostComponentView.set('componentCounter', 2);
 
       sinon.stub(hostComponentView, 'runningComponentCounter', function () {
         return 2;
@@ -581,9 +572,7 @@ describe('App.HostComponentView', function() {
         });
       });
 
-      sinon.stub(hostComponentView, 'componentCounter', function() {
-        return 1;
-      });
+      hostComponentView.set('componentCounter', 1);
 
       sinon.stub(hostComponentView, 'runningComponentCounter', function () {
         return 1;
@@ -596,7 +585,6 @@ describe('App.HostComponentView', function() {
     afterEach(function() {
       App.HostComponentActionMap.getMap.restore();
       App.StackServiceComponent.find.restore();
-      hostComponentView.componentCounter.restore();
       hostComponentView.runningComponentCounter.restore();
     });
   });