You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by on...@apache.org on 2015/03/13 20:39:42 UTC

ambari git commit: AMBARI-10062. Ambari Web Client Makes Request For All Alerts On Specific Alert Page (onechiporenko)

Repository: ambari
Updated Branches:
  refs/heads/branch-2.0.0 7bc07c381 -> 4c8b6b10d


AMBARI-10062. Ambari Web Client Makes Request For All Alerts On Specific Alert Page (onechiporenko)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/4c8b6b10
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/4c8b6b10
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/4c8b6b10

Branch: refs/heads/branch-2.0.0
Commit: 4c8b6b10dce8181a9a797b4a7f09d4e09bbb826a
Parents: 7bc07c3
Author: Oleg Nechiporenko <on...@apache.org>
Authored: Fri Mar 13 21:38:14 2015 +0200
Committer: Oleg Nechiporenko <on...@apache.org>
Committed: Fri Mar 13 21:38:14 2015 +0200

----------------------------------------------------------------------
 .../app/controllers/global/update_controller.js |  12 +-
 .../main/alert_definitions_controller.js        | 147 +++------------
 .../main/alerts/alert_instances_controller.js   | 181 +++++++++++++++++++
 .../app/mixins/common/table_server_mixin.js     |   6 +-
 ambari-web/app/models/service.js                |   4 +-
 ambari-web/app/styles/application.less          |   9 -
 ambari-web/app/styles/common.less               |   8 +
 ambari-web/app/templates/application.hbs        |  18 +-
 .../common/modal_popups/alerts_popup.hbs        |   5 +
 .../main/alerts/definition_details.hbs          |   2 +-
 ambari-web/app/templates/main/host.hbs          |   2 +-
 ambari-web/app/utils/ajax/ajax.js               |  14 +-
 ambari-web/app/utils/ember_reopen.js            |  13 ++
 .../main/alerts/definition_details_view.js      |   5 +-
 ambari-web/app/views/main/host.js               |   2 +-
 .../main/alert_definitions_controller_test.js   |  32 ----
 .../alerts/alert_instances_controller_test.js   |  33 ++++
 17 files changed, 301 insertions(+), 192 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/4c8b6b10/ambari-web/app/controllers/global/update_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/global/update_controller.js b/ambari-web/app/controllers/global/update_controller.js
index 41cbd10..d89e687 100644
--- a/ambari-web/app/controllers/global/update_controller.js
+++ b/ambari-web/app/controllers/global/update_controller.js
@@ -114,6 +114,15 @@ App.UpdateController = Em.Controller.extend({
   }),
 
   /**
+   * Pagination query-parameters for unhealthy alerts request
+   * @type {{from: Number, page_size: Number}}
+   */
+  queryParamsForUnhealthyAlertInstances: {
+    from: 0,
+    page_size: 10
+  },
+
+  /**
    * map describes relations between updater function and table
    */
   tableUpdaterMap: {
@@ -469,7 +478,8 @@ App.UpdateController = Em.Controller.extend({
 
   updateUnhealthyAlertInstances: function (callback) {
     var testUrl = '/data/alerts/alert_instances.json';
-    var realUrl = '/alerts?fields=*&Alert/state.in(CRITICAL,WARNING)&Alert/maintenance_state.in(OFF)';
+    var queryParams = this.get('queryParamsForUnhealthyAlertInstances');
+    var realUrl = '/alerts?fields=*&Alert/state.in(CRITICAL,WARNING)&Alert/maintenance_state.in(OFF)&from=' + queryParams.from + '&page_size=' + queryParams.page_size;
     var url = this.getUrl(testUrl, realUrl);
 
     App.HttpClient.get(url, App.alertInstanceMapper, {

http://git-wip-us.apache.org/repos/asf/ambari/blob/4c8b6b10/ambari-web/app/controllers/main/alert_definitions_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/alert_definitions_controller.js b/ambari-web/app/controllers/main/alert_definitions_controller.js
index 10563cc..f345cb7 100644
--- a/ambari-web/app/controllers/main/alert_definitions_controller.js
+++ b/ambari-web/app/controllers/main/alert_definitions_controller.js
@@ -92,19 +92,23 @@ App.MainAlertDefinitionsController = Em.ArrayController.extend({
   /**
    * Calculate critical count for each service, to show up the label on services menu
    * @method getCriticalAlertsCountForService
-   * @return {number}
+   * @return {Number}
    */
   getCriticalAlertsCountForService: function (service) {
-    return this.get('criticalAlertInstances').filterProperty('service', service).get('length');
+    return this.get('content').filterProperty('service.serviceName', service).
+      invoke('getWithDefault', 'summary.CRITICAL.count', 0).
+      reduce(Em.sum, 0);
   },
 
   /**
    * Calculate critical/warning count for each service, to show up the label on services menu
    * @method getCriticalOrWarningAlertsCountForService
-   * @return {number}
+   * @return {Number}
    */
   getCriticalOrWarningAlertsCountForService: function (service) {
-    return this.get('unhealthyAlertInstances').filterProperty('service', service).get('length');
+    return this.get('content').filterProperty('service.serviceName', service).map(function (alertDefinition) {
+      return alertDefinition.getWithDefault('summary.CRITICAL.count', 0) + alertDefinition.getWithDefault('summary.WARNING.count', 0);
+    }).reduce(Em.sum, 0);
   },
 
   /**
@@ -112,131 +116,22 @@ App.MainAlertDefinitionsController = Em.ArrayController.extend({
    */
 
   /**
-   * Alerts number to show up on top-nav bar: number of critical/warning alerts
-   * @type {number}
+   * Number of all critical and warning alert instances
+   * Calculation is based on each <code>alertDefinitions.summary</code>
+   * @type {Number}
    */
-  allAlertsCount: function () {
-    return this.get('unhealthyAlertInstances.length');
-  }.property('unhealthyAlertInstances.length'),
-
-  criticalAlertInstances: function () {
-    return App.AlertInstance.find().toArray().filterProperty('state', 'CRITICAL');
-  }.property('mapperTimestamp'),
-
-  warningAlertInstances: function () {
-    return App.AlertInstance.find().toArray().filterProperty('state', 'WARNING');
-  }.property('mapperTimestamp'),
-
-  unhealthyAlertInstances: function () {
-    return this.get('criticalAlertInstances').concat(this.get('warningAlertInstances'));
-  }.property('criticalAlertInstances', 'warningAlertInstances'),
+  unhealthyAlertInstancesCount: function () {
+    return this.get('content').map(function (alertDefinition) {
+      return alertDefinition.getWithDefault('summary.CRITICAL.count', 0) + alertDefinition.getWithDefault('summary.WARNING.count', 0);
+    }).reduce(Em.sum, 0);
+  }.property('content.@each.summary'),
 
   /**
-   * if critical alerts exist, if true, the alert badge should be red.
+   * if critical alerts exist, the alert badge should be red.
+   * @type {Boolean}
    */
   isCriticalAlerts: function () {
-    return this.get('unhealthyAlertInstances').someProperty('state', 'CRITICAL');
-  }.property('unhealthyAlertInstances.@each.state'),
-
-  /**
-   * Onclick handler for alerts number located right to bg ops number (see application.hbs)
-   * @method showPopup
-   * @return {App.ModalPopup}
-   */
-  showPopup: function () {
-
-    var self = this;
-
-    return App.ModalPopup.show({
-
-      header: function () {
-        return Em.I18n.t('alerts.fastAccess.popup.header').format(this.get('definitionsController.allAlertsCount'));
-      }.property('definitionsController.allAlertsCount'),
-
-      definitionsController: this,
-
-      classNames: ['sixty-percent-width-modal', 'alerts-popup'],
-
-      secondary: Em.I18n.t('alerts.fastAccess.popup.body.showmore'),
-
-      autoHeight: false,
-
-      isHideBodyScroll: true,
-
-      onSecondary: function () {
-        this.hide();
-        App.router.transitionTo('main.alerts.index');
-      },
-
-      bodyClass: App.TableView.extend({
-
-        templateName: require('templates/common/modal_popups/alerts_popup'),
-
-        controller: self,
-
-        isPaginate: true,
-
-        content: function () {
-          return this.get('controller.unhealthyAlertInstances');
-        }.property('controller.unhealthyAlertInstances.length', 'controller.unhealthyAlertInstances.@each.state'),
-
-        isLoaded: function () {
-          return !!this.get('controller.unhealthyAlertInstances');
-        }.property('controller.unhealthyAlertInstances'),
-
-        isAlertEmptyList: function () {
-          return !this.get('content.length');
-        }.property('content.length'),
-
-        /**
-         * No filtering for alert definitions
-         * @method filter
-         */
-        filter: function() {
-          this.set('filteredContent', this.get('content'));
-        }.observes('content.length'),
-
-        /**
-         * Router transition to alert definition details page
-         * @param event
-         */
-        gotoAlertDetails: function (event) {
-          if (event && event.context) {
-            this.get('parentView').hide();
-            var definition = this.get('controller.content').findProperty('id', event.context.get('definitionId'));
-            App.router.transitionTo('main.alerts.alertDetails', definition);
-          }
-        },
-
-        /**
-         * Router transition to service summary page
-         * @param event
-         */
-        gotoService: function (event) {
-          if (event && event.context) {
-            this.get('parentView').hide();
-            App.router.transitionTo('main.services.service.summary', event.context);
-          }
-        },
-
-        /**
-         * Router transition to host level alerts page
-         * @param event
-         */
-        goToHostAlerts: function (event) {
-          if (event && event.context) {
-            this.get('parentView').hide();
-            App.router.transitionTo('main.hosts.hostDetails.alerts', event.context);
-          }
-        },
-
-        didInsertElement: function () {
-          this.filter();
-          Em.run.next(this, function () {
-            App.tooltip($(".timeago"));
-          });
-        }
-      })
-    });
-  }
+    return !this.get('content').everyProperty('summary.CRITICAL.count', 0);
+  }.property('content.@each.summary')
+  
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/4c8b6b10/ambari-web/app/controllers/main/alerts/alert_instances_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/alerts/alert_instances_controller.js b/ambari-web/app/controllers/main/alerts/alert_instances_controller.js
index a3bf7fe..9bf91d5 100644
--- a/ambari-web/app/controllers/main/alerts/alert_instances_controller.js
+++ b/ambari-web/app/controllers/main/alerts/alert_instances_controller.js
@@ -22,6 +22,17 @@ App.MainAlertInstancesController = Em.Controller.extend({
 
   name: 'mainAlertInstancesController',
 
+  content: App.AlertInstance.find(),
+
+  /**
+   * @type {App.AlertInstance[]}
+   */
+  unhealthyAlertInstances: function () {
+    return App.AlertInstance.find().filter(function (item) {
+      return ['CRITICAL', 'WARNING'].contains(item.get('state'));
+    });
+  }.property('content.[]'),
+
   /**
    * Are alertInstances loaded
    * @type {boolean}
@@ -169,6 +180,176 @@ App.MainAlertInstancesController = Em.Controller.extend({
    */
   getAlertInstancesErrorCallback: function () {
     this.set('isLoaded', true);
+  },
+
+  /**
+   * Onclick handler for alerts number located right to bg ops number (see application.hbs)
+   * @method showPopup
+   * @return {App.ModalPopup}
+   */
+  showPopup: function () {
+
+    var self = this;
+
+    return App.ModalPopup.show({
+
+      alertsNumberBinding: 'App.router.mainAlertDefinitionsController.unhealthyAlertInstancesCount',
+
+      header: function () {
+        return Em.I18n.t('alerts.fastAccess.popup.header').format(this.get('alertsNumber'));
+      }.property('alertsNumber'),
+
+      definitionsController: this,
+
+      classNames: ['sixty-percent-width-modal', 'alerts-popup'],
+
+      secondary: Em.I18n.t('alerts.fastAccess.popup.body.showmore'),
+
+      autoHeight: false,
+
+      isHideBodyScroll: true,
+
+      onSecondary: function () {
+        this._super();
+        App.router.transitionTo('main.alerts.index');
+      },
+
+      bodyClass: App.TableView.extend(App.TableServerViewMixin, {
+
+        updaterBinding: 'App.router.updateController',
+
+        templateName: require('templates/common/modal_popups/alerts_popup'),
+
+        controller: self,
+
+        isPaginate: true,
+
+        willInsertElement: function () {
+          this._super();
+          this.updateAlertInstances();
+        },
+
+        /**
+         * Number of all critical and warning alert instances
+         * @type {Boolean}
+         */
+        filteredCount: function () {
+          return App.router.get('mainAlertDefinitionsController.unhealthyAlertInstancesCount');
+        }.property('alertsNumber'),
+
+        content: function () {
+          return this.get('controller.unhealthyAlertInstances');
+        }.property('controller.unhealthyAlertInstances.@each.state'),
+
+        isLoaded: function () {
+          return !!this.get('controller.unhealthyAlertInstances');
+        }.property('controller.unhealthyAlertInstances'),
+
+        isAlertEmptyList: function () {
+          return !this.get('content.length');
+        }.property('content.length'),
+
+        /**
+         * Update list of shown alert instances
+         * @method updateAlertInstances
+         */
+        updateAlertInstances: function () {
+          var self = this,
+            displayLength = this.get('displayLength'),
+            startIndex = this.get('startIndex');
+          if (!displayLength) return; // wait while table-info is loaded
+          this.get('updater').set('queryParamsForUnhealthyAlertInstances', {
+            from: startIndex - 1,
+            page_size: displayLength
+          });
+          this.set('filteringComplete', false);
+          this.get('updater').updateUnhealthyAlertInstances(function() {
+            self.set('filteringComplete', true);
+          });
+        }.observes('displayLength', 'startIndex'),
+
+        /**
+         * Show spinner when filter/sorting request is in processing
+         * @method overlayObserver
+         */
+        overlayObserver: function() {
+          var $tbody = this.$('#alert-info'),
+            $overlay = this.$('.table-overlay'),
+            $spinner = $($overlay).find('.spinner');
+          if (!this.get('filteringComplete')) {
+            if (!$tbody) return;
+            var tbodyPos =  $tbody.position();
+            if (!tbodyPos) return;
+            $spinner.css('display', 'block');
+            $overlay.css({
+              top: tbodyPos.top + 1,
+              left: tbodyPos.left + 1,
+              width: $tbody.width() - 1,
+              height: $tbody.height() - 1
+            });
+          }
+        },
+
+        /**
+         * No filtering for alert definitions
+         * @method filter
+         */
+        filter: function() {
+          this.set('filteredContent', this.get('content'));
+        }.observes('content.length'),
+
+        refreshTooltips: function () {
+          this.ensureTooltip();
+        }.observes('contents.[]'),
+
+        ensureTooltip: function () {
+          Em.run.next(this, function () {
+            App.tooltip($(".timeago"));
+          });
+        },
+        /**
+         * Router transition to alert definition details page
+         * @param event
+         */
+        gotoAlertDetails: function (event) {
+          if (event && event.context) {
+            this.get('parentView').hide();
+            var definition = App.AlertDefinition.find().findProperty('id', event.context.get('definitionId'));
+            App.router.transitionTo('main.alerts.alertDetails', definition);
+          }
+        },
+
+        /**
+         * Router transition to service summary page
+         * @param event
+         */
+        gotoService: function (event) {
+          if (event && event.context) {
+            this.get('parentView').hide();
+            App.router.transitionTo('main.services.service.summary', event.context);
+          }
+        },
+
+        /**
+         * Router transition to host level alerts page
+         * @param event
+         */
+        goToHostAlerts: function (event) {
+          if (event && event.context) {
+            this.get('parentView').hide();
+            App.router.transitionTo('main.hosts.hostDetails.alerts', event.context);
+          }
+        },
+
+        didInsertElement: function () {
+          this.filter();
+          this.ensureTooltip();
+          this.addObserver('filteringComplete', this, this.overlayObserver);
+          this.overlayObserver();
+          return this._super();
+        }
+      })
+    });
   }
 
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/4c8b6b10/ambari-web/app/mixins/common/table_server_mixin.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/table_server_mixin.js b/ambari-web/app/mixins/common/table_server_mixin.js
index 9c35d98..5162a02 100644
--- a/ambari-web/app/mixins/common/table_server_mixin.js
+++ b/ambari-web/app/mixins/common/table_server_mixin.js
@@ -19,10 +19,10 @@
 var App = require('app');
 var validator = require('utils/validator');
 
-//TODO integrate mixin into mainHostController to avoid code duplication
 App.TableServerMixin = Em.Mixin.create({
   queryParams: [],
   resetStartIndex: false,
+
   /**
    * filterProps support follow types of filter:
    * MATCH - match of RegExp
@@ -33,8 +33,9 @@ App.TableServerMixin = Em.Mixin.create({
    * CUSTOM - substitute values with keys "{#}" in alias
    */
   filterProps: [],
+
   /**
-   * include "from" nad "page_size"
+   * include "from" and "page_size"
    */
   paginationProps: [
     {
@@ -50,6 +51,7 @@ App.TableServerMixin = Em.Mixin.create({
       type: 'EQUAL'
     }
   ],
+
   sortProps: [],
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/4c8b6b10/ambari-web/app/models/service.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/service.js b/ambari-web/app/models/service.js
index d633ad2..a4696d1 100644
--- a/ambari-web/app/models/service.js
+++ b/ambari-web/app/models/service.js
@@ -143,12 +143,12 @@ App.Service = DS.Model.extend({
 
   hasCriticalAlerts: function () {
     var controller = App.router.get('mainAlertDefinitionsController');
-    return controller.getCriticalAlertsCountForService(this) > 0;
+    return controller.getCriticalAlertsCountForService(this.get('serviceName')) > 0;
   }.property('alertsCount'),
 
   alertsCount: function () {
     var controller = App.router.get('mainAlertDefinitionsController');
-    return controller.getCriticalOrWarningAlertsCountForService(this);
+    return controller.getCriticalOrWarningAlertsCountForService(this.get('serviceName'));
   }.property('App.router.mainAlertDefinitionsController.content.@each.isCriticalOrWarning')
 });
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/4c8b6b10/ambari-web/app/styles/application.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/application.less b/ambari-web/app/styles/application.less
index c0c43e8..3d57956 100644
--- a/ambari-web/app/styles/application.less
+++ b/ambari-web/app/styles/application.less
@@ -2865,15 +2865,6 @@ table.graphs {
     }
   }
 
-  .hosts-overlay {
-    position: absolute;
-    opacity: 0.9;
-    background-color: #fefefe;
-    .spinner {
-      display: none;
-    }
-  }
-
   .status-dot-position {
     background-position: center;
     background-repeat: no-repeat;

http://git-wip-us.apache.org/repos/asf/ambari/blob/4c8b6b10/ambari-web/app/styles/common.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/common.less b/ambari-web/app/styles/common.less
index e9e2528..fde2bd3 100644
--- a/ambari-web/app/styles/common.less
+++ b/ambari-web/app/styles/common.less
@@ -304,3 +304,11 @@
   opacity: 0;
 }
 
+.table-overlay {
+  position: absolute;
+  opacity: 0.9;
+  background-color: #fefefe;
+  .spinner {
+    display: none;
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/4c8b6b10/ambari-web/app/templates/application.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/application.hbs b/ambari-web/app/templates/application.hbs
index 8752280..346fb23 100644
--- a/ambari-web/app/templates/application.hbs
+++ b/ambari-web/app/templates/application.hbs
@@ -38,16 +38,14 @@
                     {{allOperationsCount}} {{pluralize allOperationsCount singular="t:op" plural="t:ops"}}</span>
                 {{/if}}
               {{/with}}
-              {{#with App.router.mainAlertDefinitionsController}}
-                {{#if allAlertsCount}}
-                  <span {{bindAttr class=":label isCriticalAlerts:alert-crit-count:alert-warn-count"}} {{action "showPopup" target="App.router.mainAlertDefinitionsController"}}>
-                  {{allAlertsCount}} {{pluralize allAlertsCount singular="alert" plural="alerts"}}</span>
-                {{else}}
-                  <span rel="tooltip" {{translateAttr title="titlebar.alerts.noAlerts"}}
-                        class="label alerts-none-count" {{action "showPopup" target="App.router.mainAlertDefinitionsController"}}>
-                  {{allAlertsCount}} {{pluralize allAlertsCount singular="alert" plural="alerts"}}</span>
-                {{/if}}
-              {{/with}}
+              {{#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>
+              {{else}}
+                <span rel="tooltip" {{translateAttr title="titlebar.alerts.noAlerts"}}
+                      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}}
             </a>
           {{else}}
             <a class="logo"><img src="/img/logo-white.png" alt="Apache Ambari" title="Apache Ambari"></a>

http://git-wip-us.apache.org/repos/asf/ambari/blob/4c8b6b10/ambari-web/app/templates/common/modal_popups/alerts_popup.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/common/modal_popups/alerts_popup.hbs b/ambari-web/app/templates/common/modal_popups/alerts_popup.hbs
index a0f7808..2da35ec 100644
--- a/ambari-web/app/templates/common/modal_popups/alerts_popup.hbs
+++ b/ambari-web/app/templates/common/modal_popups/alerts_popup.hbs
@@ -61,6 +61,11 @@
         {{/if}}
       </div>
     </div>
+
+    <div {{bindAttr class="view.filteringComplete:hidden :table-overlay"}}>
+      <div class="spinner"></div>
+    </div>
+
     {{#if view.isPaginate}}
       <div class="page-bar pull-right no-borders mtm">
         <div class="items-on-page">

http://git-wip-us.apache.org/repos/asf/ambari/blob/4c8b6b10/ambari-web/app/templates/main/alerts/definition_details.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/alerts/definition_details.hbs b/ambari-web/app/templates/main/alerts/definition_details.hbs
index 960cf04..ac0652d 100644
--- a/ambari-web/app/templates/main/alerts/definition_details.hbs
+++ b/ambari-web/app/templates/main/alerts/definition_details.hbs
@@ -203,7 +203,7 @@
                   <time class="timeago"
                         rel="tooltip"  {{bindAttr data-original-title="instance.statusChangedAndLastCheckedFormatted"}}>{{instance.lastTriggeredForFormatted}}</time>
                 </td>
-                <td>{{view view.parentView.lastDayCount hostBinding="instance.host"}}</td>
+                <td>{{view view.parentView.lastDayCount hostNameBinding="instance.hostName"}}</td>
                 <td><span class="alert-text" rel="tooltip" {{bindAttr data-original-title="instance.text"}}
                           class="alert-text">{{instance.text}}</span></td>
                 {{/view}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/4c8b6b10/ambari-web/app/templates/main/host.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/host.hbs b/ambari-web/app/templates/main/host.hbs
index dce28a4..cbaf49a 100644
--- a/ambari-web/app/templates/main/host.hbs
+++ b/ambari-web/app/templates/main/host.hbs
@@ -163,7 +163,7 @@
     </tbody>
   </table>
 
-  <div {{bindAttr class="view.filteringComplete:hidden :hosts-overlay"}}>
+  <div {{bindAttr class="view.filteringComplete:hidden :table-overlay"}}>
     <div class="spinner"></div>
   </div>
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/4c8b6b10/ambari-web/app/utils/ajax/ajax.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js
index 4081c2a..24e9749 100644
--- a/ambari-web/app/utils/ajax/ajax.js
+++ b/ambari-web/app/utils/ajax/ajax.js
@@ -373,20 +373,24 @@ var urls = {
     'real': '/clusters/{clusterName}/alert_definitions?fields=*',
     'mock': 'data/alerts/alertDefinitions.json'
   },
+  'alerts.notifications': {
+    'real': '/alert_targets?fields=*',
+    'mock': '/data/alerts/alertNotifications.json'
+  },
   'alerts.instances': {
     'real': '/clusters/{clusterName}/alerts?fields=*',
     'mock': '/data/alerts/alert_instances.json'
   },
-  'alerts.notifications': {
-    'real': '/alert_targets?fields=*',
-    'mock': '/data/alerts/alertNotifications.json'
+  'alerts.instances.unhealthy': {
+    'real': '/clusters/{clusterName}/alerts?fields=*&Alert/state.in(CRITICAL,WARNING)&{paginationInfo}',
+    'mock': '/data/alerts/alert_instances.json'
   },
   'alerts.instances.by_definition': {
-    'real': '/clusters/{clusterName}/alerts?fields=*&(Alert/definition_id={definitionId}|Alert/state.in(CRITICAL,WARNING))',
+    'real': '/clusters/{clusterName}/alerts?fields=*&Alert/definition_id={definitionId}',
     'mock': '/data/alerts/alert_instances.json'
   },
   'alerts.instances.by_host': {
-    'real': '/clusters/{clusterName}/alerts?fields=*&(Alert/host_name={hostName}|Alert/state.in(CRITICAL,WARNING))',
+    'real': '/clusters/{clusterName}/alerts?fields=*&Alert/host_name={hostName}',
     'mock': '/data/alerts/alert_instances.json'
   },
   'alerts.update_alert_definition': {

http://git-wip-us.apache.org/repos/asf/ambari/blob/4c8b6b10/ambari-web/app/utils/ember_reopen.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/ember_reopen.js b/ambari-web/app/utils/ember_reopen.js
index a879cde..4446f1e 100644
--- a/ambari-web/app/utils/ember_reopen.js
+++ b/ambari-web/app/utils/ember_reopen.js
@@ -115,6 +115,19 @@ Ember.isBlank = function(obj) {
 };
 
 /**
+ * Calculates sum of two numbers
+ * Use this function as a callback on <code>invoke</code> etc
+ *
+ * @method sum
+ * @param {Number} a
+ * @param {Number} b
+ * @returns {Number}
+ */
+Ember.sum = function (a, b) {
+  return a + b;
+};
+
+/**
  *
  */
 Ember.RadioButton = Ember.Checkbox.extend({

http://git-wip-us.apache.org/repos/asf/ambari/blob/4c8b6b10/ambari-web/app/views/main/alerts/definition_details_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/alerts/definition_details_view.js b/ambari-web/app/views/main/alerts/definition_details_view.js
index 28a7c9b..a5e717a 100644
--- a/ambari-web/app/views/main/alerts/definition_details_view.js
+++ b/ambari-web/app/views/main/alerts/definition_details_view.js
@@ -85,11 +85,12 @@ App.MainAlertDefinitionDetailsView = App.TableView.extend({
    * View calculates and represents count of alerts on appropriate host during last day
    */
   lastDayCount: Em.View.extend({
+    hostName: '', // binding from template
     template: Ember.Handlebars.compile('<span>{{view.count}}</span>'),
     count: function () {
       var lastDayAlertsCount = this.get('parentView.controller.lastDayAlertsCount');
-      return lastDayAlertsCount ? lastDayAlertsCount[this.get('host.hostName')] || 0 : Em.I18n.t('app.loadingPlaceholder');
-    }.property('parentView.controller.lastDayAlertsCount', 'host')
+      return lastDayAlertsCount ? lastDayAlertsCount[this.get('hostName')] || 0 : Em.I18n.t('app.loadingPlaceholder');
+    }.property('parentView.controller.lastDayAlertsCount', 'hostName')
   }),
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/4c8b6b10/ambari-web/app/views/main/host.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/host.js b/ambari-web/app/views/main/host.js
index 67f3a26..47002b3 100644
--- a/ambari-web/app/views/main/host.js
+++ b/ambari-web/app/views/main/host.js
@@ -298,7 +298,7 @@ App.MainHostView = App.TableView.extend(App.TableServerViewMixin, {
    */
   overlayObserver: function() {
     var $tbody = this.$('tbody'),
-      $overlay = this.$('.hosts-overlay'),
+      $overlay = this.$('.table-overlay'),
       $spinner = $($overlay).find('.spinner');
     if (!this.get('filteringComplete')) {
       if (!$tbody) return;

http://git-wip-us.apache.org/repos/asf/ambari/blob/4c8b6b10/ambari-web/test/controllers/main/alert_definitions_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/alert_definitions_controller_test.js b/ambari-web/test/controllers/main/alert_definitions_controller_test.js
index 103ab8e..03a4d80 100644
--- a/ambari-web/test/controllers/main/alert_definitions_controller_test.js
+++ b/ambari-web/test/controllers/main/alert_definitions_controller_test.js
@@ -53,36 +53,4 @@ describe('App.MainAlertDefinitionsController', function() {
 
   });
 
-  describe('#showPopup', function () {
-
-    describe('#bodyClass', function () {
-
-      var bodyView;
-
-      beforeEach(function () {
-        controller.reopen({unhealthyAlertInstances: [
-          App.AlertInstance.createRecord({state: 'CRITICAL'}),
-          App.AlertInstance.createRecord({state: 'WARNING'}),
-          App.AlertInstance.createRecord({state: 'WARNING'}),
-          App.AlertInstance.createRecord({state: 'CRITICAL'})
-        ]});
-        bodyView = controller.showPopup().get('bodyClass').create();
-      });
-
-      it('#content', function () {
-        expect(bodyView.get('content.length')).to.equal(4);
-      });
-
-      it('#isLoaded', function () {
-        expect(bodyView.get('isLoaded')).to.be.true;
-      });
-
-      it('#isAlertEmptyList', function () {
-        expect(bodyView.get('isAlertEmptyList')).to.be.false;
-      });
-
-    });
-
-  });
-
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/4c8b6b10/ambari-web/test/controllers/main/alerts/alert_instances_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/alerts/alert_instances_controller_test.js b/ambari-web/test/controllers/main/alerts/alert_instances_controller_test.js
index 8f24e5a..d5cda71 100644
--- a/ambari-web/test/controllers/main/alerts/alert_instances_controller_test.js
+++ b/ambari-web/test/controllers/main/alerts/alert_instances_controller_test.js
@@ -68,4 +68,37 @@ describe('App.MainAlertInstancesController', function () {
 
   });
 
+
+  describe('#showPopup', function () {
+
+    describe('#bodyClass', function () {
+
+      var bodyView;
+
+      beforeEach(function () {
+        controller.reopen({unhealthyAlertInstances: [
+          App.AlertInstance.createRecord({state: 'CRITICAL'}),
+          App.AlertInstance.createRecord({state: 'WARNING'}),
+          App.AlertInstance.createRecord({state: 'WARNING'}),
+          App.AlertInstance.createRecord({state: 'CRITICAL'})
+        ]});
+        bodyView = controller.showPopup().get('bodyClass').create();
+      });
+
+      it('#content', function () {
+        expect(bodyView.get('content.length')).to.equal(4);
+      });
+
+      it('#isLoaded', function () {
+        expect(bodyView.get('isLoaded')).to.be.true;
+      });
+
+      it('#isAlertEmptyList', function () {
+        expect(bodyView.get('isAlertEmptyList')).to.be.false;
+      });
+
+    });
+
+  });
+
 });
\ No newline at end of file