Browse Source

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

Jaimin Jetly 10 năm trước cách đây
mục cha
commit
a6c86eec9b
63 tập tin đã thay đổi với 843 bổ sung915 xóa
  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();
     });
   });