Repository: ambari
Updated Branches:
  refs/heads/trunk d99abd01f -> ef9a456a7


AMBARI-11699 - Removing A Host Does Not Recalculate Aggregate Alerts 
(jonathanhurley)


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

Branch: refs/heads/trunk
Commit: ef9a456a7687d0478ba49cc4e50b1877704be304
Parents: d99abd0
Author: Jonathan Hurley <jhur...@hortonworks.com>
Authored: Thu Jun 4 15:44:54 2015 -0400
Committer: Jonathan Hurley <jhur...@hortonworks.com>
Committed: Thu Jun 4 20:12:55 2015 -0400

----------------------------------------------------------------------
 .../events/AggregateAlertRecalculateEvent.java  |  47 +++++
 .../alerts/AlertAggregateListener.java          |  49 ++++-
 .../alerts/AlertDefinitionDisabledListener.java |   9 +
 .../alerts/AlertHashInvalidationListener.java   |   5 +-
 .../alerts/AlertLifecycleListener.java          |   6 +
 .../alerts/AlertMaintenanceModeListener.java    |   2 +
 .../AlertServiceComponentHostListener.java      |  11 +-
 .../alerts/AlertServiceStateListener.java       |  11 +-
 .../alerts/AlertStateChangedListener.java       |   2 +
 .../apache/ambari/server/orm/dao/AlertsDAO.java | 179 ++++++++++++-------
 .../state/alert/AggregateDefinitionMapping.java |  35 ++++
 .../ambari/server/orm/dao/AlertsDAOTest.java    |   8 +-
 .../alerts/AlertStateChangedEventTest.java      |  28 ++-
 .../state/cluster/AlertDataManagerTest.java     |  13 +-
 14 files changed, 319 insertions(+), 86 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/ef9a456a/ambari-server/src/main/java/org/apache/ambari/server/events/AggregateAlertRecalculateEvent.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/events/AggregateAlertRecalculateEvent.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/events/AggregateAlertRecalculateEvent.java
new file mode 100644
index 0000000..4c9641d
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/events/AggregateAlertRecalculateEvent.java
@@ -0,0 +1,47 @@
+/**
+ * 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.
+ */
+package org.apache.ambari.server.events;
+
+
+/**
+ * The {@link AggregateAlertRecalculateEvent} is used to trigger the
+ * recalculation of all aggregate alerts.
+ */
+public class AggregateAlertRecalculateEvent extends AlertEvent {
+
+  /**
+   * Constructor.
+   *
+   * @param clusterId
+   *          the ID of the cluster to recalculate aggregate alerts for.
+   */
+  public AggregateAlertRecalculateEvent(long clusterId) {
+    super(clusterId, null);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String toString() {
+    StringBuilder buffer = new StringBuilder("AggregateAlertRecalculateEvent{ 
");
+    buffer.append("cluserId=").append(m_clusterId);
+    buffer.append("}");
+    return buffer.toString();
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/ef9a456a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertAggregateListener.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertAggregateListener.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertAggregateListener.java
index 99542ef..4d2add1 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertAggregateListener.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertAggregateListener.java
@@ -18,8 +18,10 @@
 package org.apache.ambari.server.events.listeners.alerts;
 
 import java.text.MessageFormat;
+import java.util.List;
 
 import org.apache.ambari.server.EagerSingleton;
+import org.apache.ambari.server.events.AggregateAlertRecalculateEvent;
 import org.apache.ambari.server.events.AlertReceivedEvent;
 import org.apache.ambari.server.events.AlertStateChangeEvent;
 import org.apache.ambari.server.events.InitialAlertEvent;
@@ -33,6 +35,8 @@ import org.apache.ambari.server.state.alert.AggregateSource;
 import org.apache.ambari.server.state.alert.AlertDefinition;
 import org.apache.ambari.server.state.alert.Reporting;
 import org.apache.ambari.server.state.alert.SourceType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.eventbus.Subscribe;
 import com.google.inject.Inject;
@@ -51,6 +55,11 @@ import com.google.inject.Singleton;
 @EagerSingleton
 public class AlertAggregateListener {
 
+  /**
+   * Logger.
+   */
+  private final static Logger LOG = 
LoggerFactory.getLogger(AlertAggregateListener.class);
+
   @Inject
   private AlertsDAO m_alertsDao = null;
 
@@ -77,7 +86,9 @@ public class AlertAggregateListener {
    */
   @Subscribe
   public void onInitialAlertEvent(InitialAlertEvent event) {
-    onAlertEvent(event.getClusterId(), event.getAlert());
+    LOG.debug("Received event {}", event);
+
+    onAlertEvent(event.getClusterId(), event.getAlert().getName());
   }
 
   /**
@@ -85,15 +96,41 @@ public class AlertAggregateListener {
    */
   @Subscribe
   public void onAlertStateChangeEvent(AlertStateChangeEvent event) {
-    onAlertEvent(event.getClusterId(), event.getAlert());
+    LOG.debug("Received event {}", event);
+
+    onAlertEvent(event.getClusterId(), event.getAlert().getName());
+  }
+
+  /**
+   * Consumes an {@link AggregateAlertRecalculateEvent}. When a component is
+   * removed, there may be alerts that were removed which have aggregate alerts
+   * associated with this. This will ensure that all aggregates recalculate. It
+   * can also be used at any point to recalculate all of the aggregates for a
+   * cluster.
+   *
+   */
+  @Subscribe
+  public void onAlertStateChangeEvent(AggregateAlertRecalculateEvent event) {
+    LOG.debug("Received event {}", event);
+
+    List<String> alertNames = 
m_aggregateMapping.getAlertsWithAggregates(event.getClusterId());
+    for (String alertName : alertNames) {
+      onAlertEvent(event.getClusterId(), alertName);
+    }
   }
 
   /**
-   * Calculates the aggregate alert state for the aggregated alert specified.
+   * Calculates the aggregate alert state if there is an aggregate alert for 
the
+   * specified alert.
+   *
+   * @param clusterId
+   *          the ID of the cluster.
+   * @param alertName
+   *          the name of the alert to use when looking up the aggregate.
    */
-  private void onAlertEvent(long clusterId, Alert alert) {
-    AlertDefinition aggregateDefinition = 
m_aggregateMapping.getAggregateDefinition(
-        clusterId, alert.getName());
+  private void onAlertEvent(long clusterId, String alertName) {
+    AlertDefinition aggregateDefinition = 
m_aggregateMapping.getAggregateDefinition(clusterId,
+        alertName);
 
     if (null == aggregateDefinition || null == m_alertsDao) {
       return;

http://git-wip-us.apache.org/repos/asf/ambari/blob/ef9a456a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertDefinitionDisabledListener.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertDefinitionDisabledListener.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertDefinitionDisabledListener.java
index 010526b..fb9d669 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertDefinitionDisabledListener.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertDefinitionDisabledListener.java
@@ -22,6 +22,8 @@ import 
org.apache.ambari.server.events.AlertDefinitionDisabledEvent;
 import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
 import org.apache.ambari.server.orm.dao.AlertsDAO;
 import org.apache.ambari.server.orm.entities.AlertCurrentEntity;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.eventbus.AllowConcurrentEvents;
 import com.google.common.eventbus.Subscribe;
@@ -34,6 +36,11 @@ import com.google.inject.Inject;
 @EagerSingleton
 public class AlertDefinitionDisabledListener {
   /**
+   * Logger.
+   */
+  private final static Logger LOG = 
LoggerFactory.getLogger(AlertDefinitionDisabledListener.class);
+
+  /**
    * Used for deleting the alert notices when a definition is disabled.
    */
   @Inject
@@ -57,6 +64,8 @@ public class AlertDefinitionDisabledListener {
   @Subscribe
   @AllowConcurrentEvents
   public void onEvent(AlertDefinitionDisabledEvent event) {
+    LOG.debug("Received event {}", event);
+
     m_alertsDao.removeCurrentDisabledAlerts();
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ef9a456a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertHashInvalidationListener.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertHashInvalidationListener.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertHashInvalidationListener.java
index 655352f..b5f351e 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertHashInvalidationListener.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertHashInvalidationListener.java
@@ -80,8 +80,7 @@ public class AlertHashInvalidationListener {
   @Subscribe
   @AllowConcurrentEvents
   public void onAmbariEvent(AlertHashInvalidationEvent event) {
-    LOG.debug("An alert definition hash invalidation event was received: {}",
-        event);
+    LOG.debug("Received event {}", event);
 
     Collection<String> hosts = event.getHosts();
     long clusterId = event.getClusterId();
@@ -106,6 +105,8 @@ public class AlertHashInvalidationListener {
   @Subscribe
   @AllowConcurrentEvents
   public void onEvent(ServiceComponentUninstalledEvent event) {
+    LOG.debug("Received event {}", event);
+
     long clusterId = event.getClusterId();
     String hostName = event.getHostName();
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/ef9a456a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertLifecycleListener.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertLifecycleListener.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertLifecycleListener.java
index 780de84..ad50fdd 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertLifecycleListener.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertLifecycleListener.java
@@ -103,6 +103,8 @@ public class AlertLifecycleListener {
   @Subscribe
   @AllowConcurrentEvents
   public void onAmbariEvent(AlertDefinitionRegistrationEvent event) {
+    LOG.debug("Received event {}", event);
+
     AlertDefinition definition = event.getDefinition();
 
     LOG.debug("Registering alert definition {}", definition);
@@ -126,6 +128,8 @@ public class AlertLifecycleListener {
   @Subscribe
   @AllowConcurrentEvents
   public void onAmbariEvent(AlertDefinitionChangedEvent event) {
+    LOG.debug("Received event {}", event);
+
     AlertDefinition definition = event.getDefinition();
 
     LOG.debug("Updating alert definition {}", definition);
@@ -161,6 +165,8 @@ public class AlertLifecycleListener {
   @Subscribe
   @AllowConcurrentEvents
   public void onAmbariEvent(AlertDefinitionDeleteEvent event) {
+    LOG.debug("Received event {}", event);
+
     AlertDefinition definition = event.getDefinition();
 
     LOG.debug("Removing alert definition {}", definition);

http://git-wip-us.apache.org/repos/asf/ambari/blob/ef9a456a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertMaintenanceModeListener.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertMaintenanceModeListener.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertMaintenanceModeListener.java
index e0e1d4b..847a207 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertMaintenanceModeListener.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertMaintenanceModeListener.java
@@ -79,6 +79,8 @@ public class AlertMaintenanceModeListener {
   @Subscribe
   @AllowConcurrentEvents
   public void onEvent(MaintenanceModeEvent event) {
+    LOG.debug("Received event {}", event);
+
     List<AlertCurrentEntity> currentAlerts = m_alertsDao.findCurrent();
 
     MaintenanceState newMaintenanceState = MaintenanceState.OFF;

http://git-wip-us.apache.org/repos/asf/ambari/blob/ef9a456a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertServiceComponentHostListener.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertServiceComponentHostListener.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertServiceComponentHostListener.java
index 92008e3..b7e5108 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertServiceComponentHostListener.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertServiceComponentHostListener.java
@@ -22,6 +22,8 @@ import 
org.apache.ambari.server.events.ServiceComponentUninstalledEvent;
 import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
 import org.apache.ambari.server.orm.dao.AlertsDAO;
 import org.apache.ambari.server.orm.entities.AlertCurrentEntity;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.eventbus.AllowConcurrentEvents;
 import com.google.common.eventbus.Subscribe;
@@ -33,6 +35,10 @@ import com.google.inject.Inject;
  */
 @EagerSingleton
 public class AlertServiceComponentHostListener {
+  /**
+   * Logger.
+   */
+  private static Logger LOG = 
LoggerFactory.getLogger(AlertServiceComponentHostListener.class);
 
   /**
    * Used for deleting the alert notices when a definition is disabled.
@@ -57,11 +63,14 @@ public class AlertServiceComponentHostListener {
   @Subscribe
   @AllowConcurrentEvents
   public void onEvent(ServiceComponentUninstalledEvent event) {
+    LOG.debug("Received event {}", event);
+
+    long clusterId = event.getClusterId();
     String serviceName = event.getServiceName();
     String componentName = event.getComponentName();
     String hostName = event.getHostName();
 
-    m_alertsDao.removeCurrentByServiceComponentHost(serviceName, componentName,
+    m_alertsDao.removeCurrentByServiceComponentHost(clusterId, serviceName, 
componentName,
         hostName);
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ef9a456a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertServiceStateListener.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertServiceStateListener.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertServiceStateListener.java
index e8e0579..44f9b50 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertServiceStateListener.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertServiceStateListener.java
@@ -32,7 +32,6 @@ import 
org.apache.ambari.server.events.publishers.AmbariEventPublisher;
 import org.apache.ambari.server.orm.GuiceJpaInitializer;
 import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
 import org.apache.ambari.server.orm.dao.AlertDispatchDAO;
-import org.apache.ambari.server.orm.dao.AlertsDAO;
 import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
 import org.apache.ambari.server.orm.entities.AlertGroupEntity;
 import org.apache.ambari.server.state.alert.AlertDefinition;
@@ -91,12 +90,6 @@ public class AlertServiceStateListener {
   private AlertDefinitionDAO m_definitionDao;
 
   /**
-   * Used for removing current alerts when a service is removed.
-   */
-  @Inject
-  private AlertsDAO m_alertsDao;
-
-  /**
    * Constructor.
    *
    * @param publisher
@@ -117,7 +110,7 @@ public class AlertServiceStateListener {
   @Subscribe
   @AllowConcurrentEvents
   public void onAmbariEvent(ServiceInstalledEvent event) {
-    LOG.debug("{} received {}", AlertServiceStateListener.class, event);
+    LOG.debug("Received event {}", event);
 
     long clusterId = event.getClusterId();
     String stackName = event.getStackName();
@@ -166,7 +159,7 @@ public class AlertServiceStateListener {
   @Subscribe
   @AllowConcurrentEvents
   public void onAmbariEvent(ServiceRemovedEvent event) {
-    LOG.debug("{} received {}", AlertServiceStateListener.class, event);
+    LOG.debug("Received event {}", event);
 
     List<AlertDefinitionEntity> definitions = 
m_definitionDao.findByService(event.getClusterId(),
         event.getServiceName());

http://git-wip-us.apache.org/repos/asf/ambari/blob/ef9a456a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertStateChangedListener.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertStateChangedListener.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertStateChangedListener.java
index bd08b90..08563e3 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertStateChangedListener.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertStateChangedListener.java
@@ -97,6 +97,8 @@ public class AlertStateChangedListener {
   @Subscribe
   @AllowConcurrentEvents
   public void onAlertEvent(AlertStateChangeEvent event) {
+    LOG.debug("Received event {}", event);
+
     Alert alert = event.getAlert();
     AlertHistoryEntity history = event.getNewHistoricalEntry();
     AlertDefinitionEntity definition = history.getAlertDefinition();

http://git-wip-us.apache.org/repos/asf/ambari/blob/ef9a456a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java 
b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
index ef0430e..adcc710 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
@@ -21,6 +21,7 @@ import java.util.Collections;
 import java.util.Date;
 import java.util.EnumSet;
 import java.util.List;
+import java.util.Map;
 
 import javax.persistence.EntityManager;
 import javax.persistence.TypedQuery;
@@ -34,16 +35,20 @@ import 
org.apache.ambari.server.controller.AlertCurrentRequest;
 import org.apache.ambari.server.controller.AlertHistoryRequest;
 import org.apache.ambari.server.controller.spi.Predicate;
 import org.apache.ambari.server.controller.utilities.PredicateHelper;
+import org.apache.ambari.server.events.AggregateAlertRecalculateEvent;
+import org.apache.ambari.server.events.publishers.AlertEventPublisher;
 import org.apache.ambari.server.orm.RequiresSession;
 import org.apache.ambari.server.orm.entities.AlertCurrentEntity;
 import org.apache.ambari.server.orm.entities.AlertCurrentEntity_;
 import org.apache.ambari.server.orm.entities.AlertHistoryEntity;
 import org.apache.ambari.server.orm.entities.AlertHistoryEntity_;
 import org.apache.ambari.server.state.AlertState;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.MaintenanceState;
 import org.apache.ambari.server.state.alert.Scope;
-import org.eclipse.persistence.config.HintValues;
-import org.eclipse.persistence.config.QueryHints;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.inject.Inject;
 import com.google.inject.Provider;
@@ -58,6 +63,11 @@ import com.google.inject.persist.Transactional;
 @Singleton
 public class AlertsDAO {
   /**
+   * Logger.
+   */
+  private static final Logger LOG = LoggerFactory.getLogger(AlertsDAO.class);
+
+  /**
    * A template of JPQL for getting the number of hosts in various states.
    */
   private static final String HOST_COUNT_SQL_TEMPLATE = "SELECT MAX("
@@ -80,13 +90,25 @@ public class AlertsDAO {
    * JPA entity manager
    */
   @Inject
-  private Provider<EntityManager> entityManagerProvider;
+  private Provider<EntityManager> m_entityManagerProvider;
 
   /**
    * DAO utilities for dealing mostly with {@link TypedQuery} results.
    */
   @Inject
-  private DaoUtils daoUtils;
+  private DaoUtils m_daoUtils;
+
+  /**
+   * Publishes alert events when particular DAO methods are called.
+   */
+  @Inject
+  private AlertEventPublisher m_alertEventPublisher;
+
+  /**
+   * Used to lookup clusters.
+   */
+  @Inject
+  private Provider<Clusters> m_clusters;
 
   /**
    * Gets an alert with the specified ID.
@@ -97,7 +119,7 @@ public class AlertsDAO {
    */
   @RequiresSession
   public AlertHistoryEntity findById(long alertId) {
-    return entityManagerProvider.get().find(AlertHistoryEntity.class, alertId);
+    return m_entityManagerProvider.get().find(AlertHistoryEntity.class, 
alertId);
   }
 
   /**
@@ -107,10 +129,10 @@ public class AlertsDAO {
    */
   @RequiresSession
   public List<AlertHistoryEntity> findAll() {
-    TypedQuery<AlertHistoryEntity> query = 
entityManagerProvider.get().createNamedQuery(
+    TypedQuery<AlertHistoryEntity> query = 
m_entityManagerProvider.get().createNamedQuery(
         "AlertHistoryEntity.findAll", AlertHistoryEntity.class);
 
-    return daoUtils.selectList(query);
+    return m_daoUtils.selectList(query);
   }
 
   /**
@@ -123,12 +145,12 @@ public class AlertsDAO {
    */
   @RequiresSession
   public List<AlertHistoryEntity> findAll(long clusterId) {
-    TypedQuery<AlertHistoryEntity> query = 
entityManagerProvider.get().createNamedQuery(
+    TypedQuery<AlertHistoryEntity> query = 
m_entityManagerProvider.get().createNamedQuery(
         "AlertHistoryEntity.findAllInCluster", AlertHistoryEntity.class);
 
     query.setParameter("clusterId", clusterId);
 
-    return daoUtils.selectList(query);
+    return m_daoUtils.selectList(query);
   }
 
   /**
@@ -149,14 +171,14 @@ public class AlertsDAO {
       return Collections.emptyList();
     }
 
-    TypedQuery<AlertHistoryEntity> query = 
entityManagerProvider.get().createNamedQuery(
+    TypedQuery<AlertHistoryEntity> query = 
m_entityManagerProvider.get().createNamedQuery(
         "AlertHistoryEntity.findAllInClusterWithState",
         AlertHistoryEntity.class);
 
     query.setParameter("clusterId", clusterId);
     query.setParameter("alertStates", alertStates);
 
-    return daoUtils.selectList(query);
+    return m_daoUtils.selectList(query);
   }
 
   /**
@@ -190,7 +212,7 @@ public class AlertsDAO {
         return Collections.emptyList();
       }
 
-      query = entityManagerProvider.get().createNamedQuery(
+      query = m_entityManagerProvider.get().createNamedQuery(
           "AlertHistoryEntity.findAllInClusterBetweenDates",
           AlertHistoryEntity.class);
 
@@ -198,14 +220,14 @@ public class AlertsDAO {
       query.setParameter("startDate", startDate.getTime());
       query.setParameter("endDate", endDate.getTime());
     } else if (null != startDate) {
-      query = entityManagerProvider.get().createNamedQuery(
+      query = m_entityManagerProvider.get().createNamedQuery(
           "AlertHistoryEntity.findAllInClusterAfterDate",
           AlertHistoryEntity.class);
 
       query.setParameter("clusterId", clusterId);
       query.setParameter("afterDate", startDate.getTime());
     } else if (null != endDate) {
-      query = entityManagerProvider.get().createNamedQuery(
+      query = m_entityManagerProvider.get().createNamedQuery(
           "AlertHistoryEntity.findAllInClusterBeforeDate",
           AlertHistoryEntity.class);
 
@@ -217,7 +239,7 @@ public class AlertsDAO {
       return Collections.emptyList();
     }
 
-    return daoUtils.selectList(query);
+    return m_daoUtils.selectList(query);
   }
 
   /**
@@ -230,7 +252,7 @@ public class AlertsDAO {
    */
   @RequiresSession
   public List<AlertHistoryEntity> findAll(AlertHistoryRequest request) {
-    EntityManager entityManager = entityManagerProvider.get();
+    EntityManager entityManager = m_entityManagerProvider.get();
 
     // convert the Ambari predicate into a JPA predicate
     HistoryPredicateVisitor visitor = new HistoryPredicateVisitor();
@@ -255,7 +277,7 @@ public class AlertsDAO {
       typedQuery.setMaxResults(request.Pagination.getPageSize());
     }
 
-    return daoUtils.selectList(typedQuery);
+    return m_daoUtils.selectList(typedQuery);
   }
 
   /**
@@ -268,7 +290,7 @@ public class AlertsDAO {
    */
   @Transactional
   public List<AlertCurrentEntity> findAll(AlertCurrentRequest request) {
-    EntityManager entityManager = entityManagerProvider.get();
+    EntityManager entityManager = m_entityManagerProvider.get();
 
     // convert the Ambari predicate into a JPA predicate
     CurrentPredicateVisitor visitor = new CurrentPredicateVisitor();
@@ -299,7 +321,7 @@ public class AlertsDAO {
       typedQuery.setMaxResults(request.Pagination.getPageSize());
     }
 
-    return daoUtils.selectList(typedQuery);
+    return m_daoUtils.selectList(typedQuery);
   }
 
   /**
@@ -322,10 +344,10 @@ public class AlertsDAO {
    */
   @RequiresSession
   public List<AlertCurrentEntity> findCurrent() {
-    TypedQuery<AlertCurrentEntity> query = 
entityManagerProvider.get().createNamedQuery(
+    TypedQuery<AlertCurrentEntity> query = 
m_entityManagerProvider.get().createNamedQuery(
         "AlertCurrentEntity.findAll", AlertCurrentEntity.class);
 
-    return daoUtils.selectList(query);
+    return m_daoUtils.selectList(query);
   }
 
   /**
@@ -337,7 +359,7 @@ public class AlertsDAO {
    */
   @RequiresSession
   public AlertCurrentEntity findCurrentById(long alertId) {
-    return entityManagerProvider.get().find(AlertCurrentEntity.class, alertId);
+    return m_entityManagerProvider.get().find(AlertCurrentEntity.class, 
alertId);
   }
 
   /**
@@ -350,12 +372,12 @@ public class AlertsDAO {
    */
   @RequiresSession
   public List<AlertCurrentEntity> findCurrentByDefinitionId(long definitionId) 
{
-    TypedQuery<AlertCurrentEntity> query = 
entityManagerProvider.get().createNamedQuery(
+    TypedQuery<AlertCurrentEntity> query = 
m_entityManagerProvider.get().createNamedQuery(
         "AlertCurrentEntity.findByDefinitionId", AlertCurrentEntity.class);
 
     query.setParameter("definitionId", Long.valueOf(definitionId));
 
-    return daoUtils.selectList(query);
+    return m_daoUtils.selectList(query);
   }
 
   /**
@@ -366,12 +388,12 @@ public class AlertsDAO {
    */
   @RequiresSession
   public List<AlertCurrentEntity> findCurrentByCluster(long clusterId) {
-    TypedQuery<AlertCurrentEntity> query = 
entityManagerProvider.get().createNamedQuery(
+    TypedQuery<AlertCurrentEntity> query = 
m_entityManagerProvider.get().createNamedQuery(
         "AlertCurrentEntity.findByCluster", AlertCurrentEntity.class);
 
     query.setParameter("clusterId", Long.valueOf(clusterId));
 
-    return daoUtils.selectList(query);
+    return m_daoUtils.selectList(query);
   }
 
   /**
@@ -401,7 +423,7 @@ public class AlertsDAO {
       sb.append(" AND history.hostName = :hostName");
     }
 
-    TypedQuery<AlertSummaryDTO> query = 
entityManagerProvider.get().createQuery(
+    TypedQuery<AlertSummaryDTO> query = 
m_entityManagerProvider.get().createQuery(
         sb.toString(), AlertSummaryDTO.class);
 
     query.setParameter("clusterId", Long.valueOf(clusterId));
@@ -419,7 +441,7 @@ public class AlertsDAO {
       query.setParameter("hostName", hostName);
     }
 
-    return daoUtils.selectSingle(query);
+    return m_daoUtils.selectSingle(query);
   }
 
   /**
@@ -436,7 +458,7 @@ public class AlertsDAO {
   public AlertHostSummaryDTO findCurrentHostCounts(long clusterId) {
     // use Number here since some databases like MySQL return Long and some
     // return Integer and we don't want a class cast exception
-    TypedQuery<Number> query = entityManagerProvider.get().createQuery(
+    TypedQuery<Number> query = m_entityManagerProvider.get().createQuery(
         HOST_COUNT_SQL_TEMPLATE, Number.class);
 
     query.setParameter("clusterId", Long.valueOf(clusterId));
@@ -450,7 +472,7 @@ public class AlertsDAO {
     int criticalCount = 0;
     int unknownCount = 0;
 
-    List<Number> hostStateValues = daoUtils.selectList(query);
+    List<Number> hostStateValues = m_daoUtils.selectList(query);
     for (Number hostStateValue : hostStateValues) {
       if (null == hostStateValue) {
         continue;
@@ -489,28 +511,28 @@ public class AlertsDAO {
   @RequiresSession
   public List<AlertCurrentEntity> findCurrentByService(long clusterId,
       String serviceName) {
-    TypedQuery<AlertCurrentEntity> query = 
entityManagerProvider.get().createNamedQuery(
+    TypedQuery<AlertCurrentEntity> query = 
m_entityManagerProvider.get().createNamedQuery(
         "AlertCurrentEntity.findByService", AlertCurrentEntity.class);
 
     query.setParameter("clusterId", clusterId);
     query.setParameter("serviceName", serviceName);
     query.setParameter("inlist", EnumSet.of(Scope.ANY, Scope.SERVICE));
 
-    return daoUtils.selectList(query);
+    return m_daoUtils.selectList(query);
   }
 
   @RequiresSession
   public AlertCurrentEntity findCurrentByHostAndName(long clusterId, String 
hostName,
       String alertName) {
 
-    TypedQuery<AlertCurrentEntity> query = 
entityManagerProvider.get().createNamedQuery(
+    TypedQuery<AlertCurrentEntity> query = 
m_entityManagerProvider.get().createNamedQuery(
         "AlertCurrentEntity.findByHostAndName", AlertCurrentEntity.class);
 
     query.setParameter("clusterId", Long.valueOf(clusterId));
     query.setParameter("hostName", hostName);
     query.setParameter("definitionName", alertName);
 
-    return daoUtils.selectOne(query);
+    return m_daoUtils.selectOne(query);
   }
 
   /**
@@ -523,7 +545,7 @@ public class AlertsDAO {
    */
   @Transactional
   public void removeByDefinitionId(long definitionId) {
-    EntityManager entityManager = entityManagerProvider.get();
+    EntityManager entityManager = m_entityManagerProvider.get();
     TypedQuery<AlertCurrentEntity> currentQuery = 
entityManager.createNamedQuery(
         "AlertCurrentEntity.removeByDefinitionId", AlertCurrentEntity.class);
 
@@ -547,7 +569,7 @@ public class AlertsDAO {
    */
   @Transactional
   public int removeCurrentByHistoryId(long historyId) {
-    TypedQuery<AlertCurrentEntity> query = 
entityManagerProvider.get().createNamedQuery(
+    TypedQuery<AlertCurrentEntity> query = 
m_entityManagerProvider.get().createNamedQuery(
         "AlertCurrentEntity.removeByHistoryId", AlertCurrentEntity.class);
 
     query.setParameter("historyId", historyId);
@@ -561,7 +583,7 @@ public class AlertsDAO {
    */
   @Transactional
   public int removeCurrentDisabledAlerts() {
-    TypedQuery<AlertCurrentEntity> query = 
entityManagerProvider.get().createNamedQuery(
+    TypedQuery<AlertCurrentEntity> query = 
m_entityManagerProvider.get().createNamedQuery(
         "AlertCurrentEntity.removeDisabled", AlertCurrentEntity.class);
 
     return query.executeUpdate();
@@ -570,25 +592,37 @@ public class AlertsDAO {
   /**
    * Remove the current alert that matches the given service. This is used in
    * cases where the service was removed from the cluster.
+   * <p>
+   * This method will also fire an {@link AggregateAlertRecalculateEvent} in
+   * order to recalculate all aggregates.
    *
+   * @param clusterId
+   *          the ID of the cluster.
    * @param serviceName
    *          the name of the service that the current alerts are being removed
    *          for (not {@code null}).
    * @return the number of alerts removed.
    */
   @Transactional
-  public int removeCurrentByService(String serviceName) {
-
-    TypedQuery<AlertCurrentEntity> query = 
entityManagerProvider.get().createNamedQuery(
+  public int removeCurrentByService(long clusterId, String serviceName) {
+    TypedQuery<AlertCurrentEntity> query = 
m_entityManagerProvider.get().createNamedQuery(
         "AlertCurrentEntity.removeByService", AlertCurrentEntity.class);
 
     query.setParameter("serviceName", serviceName);
-    return query.executeUpdate();
+
+    int removedItems = query.executeUpdate();
+
+    // publish the event to recalculate aggregates
+    m_alertEventPublisher.publish(new 
AggregateAlertRecalculateEvent(clusterId));
+    return removedItems;
   }
 
   /**
    * Remove the current alert that matches the given host. This is used in 
cases
    * where the host was removed from the cluster.
+   * <p>
+   * This method will also fire an {@link AggregateAlertRecalculateEvent} in
+   * order to recalculate all aggregates.
    *
    * @param hostName
    *          the name of the host that the current alerts are being removed 
for
@@ -597,18 +631,36 @@ public class AlertsDAO {
    */
   @Transactional
   public int removeCurrentByHost(String hostName) {
-
-    TypedQuery<AlertCurrentEntity> query = 
entityManagerProvider.get().createNamedQuery(
+    TypedQuery<AlertCurrentEntity> query = 
m_entityManagerProvider.get().createNamedQuery(
         "AlertCurrentEntity.removeByHost", AlertCurrentEntity.class);
 
     query.setParameter("hostName", hostName);
-    return query.executeUpdate();
+    int removedItems = query.executeUpdate();
+
+    // publish the event to recalculate aggregates for every cluster since a 
host could potentially have several clusters
+    try {
+      Map<String, Cluster> clusters = m_clusters.get().getClusters();
+      for (Map.Entry<String, Cluster> entry : clusters.entrySet()) {
+        m_alertEventPublisher.publish(new AggregateAlertRecalculateEvent(
+            entry.getValue().getClusterId()));
+      }
+
+    } catch (Exception ambariException) {
+      LOG.warn("Unable to recalcuate aggregate alerts after removing host {}", 
hostName);
+    }
+
+    return removedItems;
   }
 
   /**
    * Remove the current alert that matches the given service, component and
    * host. This is used in cases where the component was removed from the host.
+   * <p>
+   * This method will also fire an {@link AggregateAlertRecalculateEvent} in
+   * order to recalculate all aggregates.
    *
+   * @param clusterId
+   *          the ID of the cluster.
    * @param serviceName
    *          the name of the service that the current alerts are being removed
    *          for (not {@code null}).
@@ -621,17 +673,22 @@ public class AlertsDAO {
    * @return the number of alerts removed.
    */
   @Transactional
-  public int removeCurrentByServiceComponentHost(String serviceName,
+  public int removeCurrentByServiceComponentHost(long clusterId, String 
serviceName,
       String componentName, String hostName) {
 
-    TypedQuery<AlertCurrentEntity> query = 
entityManagerProvider.get().createNamedQuery(
+    TypedQuery<AlertCurrentEntity> query = 
m_entityManagerProvider.get().createNamedQuery(
         "AlertCurrentEntity.removeByHostComponent", AlertCurrentEntity.class);
 
     query.setParameter("serviceName", serviceName);
     query.setParameter("componentName", componentName);
     query.setParameter("hostName", hostName);
 
-    return query.executeUpdate();
+    int removedItems = query.executeUpdate();
+
+    // publish the event to recalculate aggregates
+    m_alertEventPublisher.publish(new 
AggregateAlertRecalculateEvent(clusterId));
+
+    return removedItems;
   }
 
   /**
@@ -642,7 +699,7 @@ public class AlertsDAO {
    */
   @Transactional
   public void create(AlertHistoryEntity alert) {
-    entityManagerProvider.get().persist(alert);
+    m_entityManagerProvider.get().persist(alert);
   }
 
   /**
@@ -653,7 +710,7 @@ public class AlertsDAO {
    */
   @Transactional
   public void refresh(AlertHistoryEntity alert) {
-    entityManagerProvider.get().refresh(alert);
+    m_entityManagerProvider.get().refresh(alert);
   }
 
   /**
@@ -665,7 +722,7 @@ public class AlertsDAO {
    */
   @Transactional
   public AlertHistoryEntity merge(AlertHistoryEntity alert) {
-    return entityManagerProvider.get().merge(alert);
+    return m_entityManagerProvider.get().merge(alert);
   }
 
   /**
@@ -679,7 +736,7 @@ public class AlertsDAO {
     alert = merge(alert);
 
     removeCurrentByHistoryId(alert.getAlertId());
-    entityManagerProvider.get().remove(alert);
+    m_entityManagerProvider.get().remove(alert);
   }
 
   /**
@@ -690,7 +747,7 @@ public class AlertsDAO {
    */
   @Transactional
   public void create(AlertCurrentEntity alert) {
-    entityManagerProvider.get().persist(alert);
+    m_entityManagerProvider.get().persist(alert);
   }
 
   /**
@@ -701,7 +758,7 @@ public class AlertsDAO {
    */
   @Transactional
   public void refresh(AlertCurrentEntity alert) {
-    entityManagerProvider.get().refresh(alert);
+    m_entityManagerProvider.get().refresh(alert);
   }
 
   /**
@@ -713,7 +770,7 @@ public class AlertsDAO {
    */
   @Transactional
   public AlertCurrentEntity merge(AlertCurrentEntity alert) {
-    return entityManagerProvider.get().merge(alert);
+    return m_entityManagerProvider.get().merge(alert);
   }
 
   /**
@@ -745,7 +802,7 @@ public class AlertsDAO {
    */
   @Transactional
   public void remove(AlertCurrentEntity alert) {
-    entityManagerProvider.get().remove(merge(alert));
+    m_entityManagerProvider.get().remove(merge(alert));
   }
 
   /**
@@ -762,7 +819,7 @@ public class AlertsDAO {
     StringBuilder buffer = new StringBuilder(sql);
     buffer.append(" AND history.alertDefinition.definitionName = 
:definitionName");
 
-    TypedQuery<AlertSummaryDTO> query = 
entityManagerProvider.get().createQuery(
+    TypedQuery<AlertSummaryDTO> query = 
m_entityManagerProvider.get().createQuery(
         buffer.toString(), AlertSummaryDTO.class);
 
     query.setParameter("clusterId", Long.valueOf(clusterId));
@@ -773,7 +830,7 @@ public class AlertsDAO {
     query.setParameter("maintenanceStateOff", MaintenanceState.OFF);
     query.setParameter("definitionName", alertName);
 
-    return daoUtils.selectSingle(query);
+    return m_daoUtils.selectSingle(query);
   }
 
   /**
@@ -785,13 +842,13 @@ public class AlertsDAO {
    */
   @RequiresSession
   public AlertCurrentEntity findCurrentByNameNoHost(long clusterId, String 
alertName) {
-    TypedQuery<AlertCurrentEntity> query = 
entityManagerProvider.get().createNamedQuery(
+    TypedQuery<AlertCurrentEntity> query = 
m_entityManagerProvider.get().createNamedQuery(
         "AlertCurrentEntity.findByNameAndNoHost", AlertCurrentEntity.class);
 
     query.setParameter("clusterId", Long.valueOf(clusterId));
     query.setParameter("definitionName", alertName);
 
-    return daoUtils.selectOne(query);
+    return m_daoUtils.selectOne(query);
   }
 
   /**
@@ -806,7 +863,7 @@ public class AlertsDAO {
      *
      */
     public HistoryPredicateVisitor() {
-      super(entityManagerProvider.get(), AlertHistoryEntity.class);
+      super(m_entityManagerProvider.get(), AlertHistoryEntity.class);
     }
 
     /**
@@ -839,7 +896,7 @@ public class AlertsDAO {
      *
      */
     public CurrentPredicateVisitor() {
-      super(entityManagerProvider.get(), AlertCurrentEntity.class);
+      super(m_entityManagerProvider.get(), AlertCurrentEntity.class);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/ef9a456a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AggregateDefinitionMapping.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AggregateDefinitionMapping.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AggregateDefinitionMapping.java
index c63c0d4..104ebef 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AggregateDefinitionMapping.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AggregateDefinitionMapping.java
@@ -17,7 +17,10 @@
  */
 package org.apache.ambari.server.state.alert;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -108,4 +111,36 @@ public final class AggregateDefinitionMapping {
     Map<String, AlertDefinition> map = m_aggregateMap.get(id);
     map.remove(aggregatedDefinitonName);
   }
+
+  /**
+   * Gets a copy of all of the aggregate definitions for the specified cluster.
+   *
+   * @param clusterId
+   *          the cluster ID
+   * @return the list of all aggregate definitions
+   */
+  public List<AlertDefinition> getAggregateDefinitions(long clusterId) {
+    if (!m_aggregateMap.containsKey(clusterId)) {
+      return Collections.emptyList();
+    }
+
+    Map<String, AlertDefinition> map = m_aggregateMap.get(clusterId);
+    return new ArrayList<AlertDefinition>(map.values());
+  }
+
+  /**
+   * Gets a copy of all of the alerts that have aggregates defined for them.
+   *
+   * @param clusterId
+   *          the cluster ID
+   * @return the list of all alerts with aggregate definitions
+   */
+  public List<String> getAlertsWithAggregates(long clusterId) {
+    if (!m_aggregateMap.containsKey(clusterId)) {
+      return Collections.emptyList();
+    }
+
+    Map<String, AlertDefinition> map = m_aggregateMap.get(clusterId);
+    return new ArrayList<String>(map.keySet());
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/ef9a456a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
index 6bf808d..f267544 100644
--- 
a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
@@ -32,7 +32,6 @@ import java.util.List;
 import java.util.TimeZone;
 import java.util.UUID;
 
-import com.google.inject.persist.UnitOfWork;
 import org.apache.ambari.server.controller.AlertCurrentRequest;
 import org.apache.ambari.server.controller.AlertHistoryRequest;
 import 
org.apache.ambari.server.controller.internal.AlertHistoryResourceProvider;
@@ -72,6 +71,7 @@ import org.junit.Test;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.persist.PersistService;
+import com.google.inject.persist.UnitOfWork;
 
 /**
  * Tests {@link AlertsDAO}.
@@ -1289,11 +1289,11 @@ public class AlertsDAOTest {
     assertEquals(5, currentAlerts.size());
 
     // assert none removed for HDFS
-    m_dao.removeCurrentByService("HDFS");
+    m_dao.removeCurrentByService(m_cluster.getClusterId(), "HDFS");
     currentAlerts = m_dao.findCurrent();
     assertEquals(5, currentAlerts.size());
 
-    m_dao.removeCurrentByService("YARN");
+    m_dao.removeCurrentByService(m_cluster.getClusterId(), "YARN");
     currentAlerts = m_dao.findCurrent();
     assertEquals(0, currentAlerts.size());
   }
@@ -1326,7 +1326,7 @@ public class AlertsDAOTest {
 
     assertNotNull(entity);
 
-    m_dao.removeCurrentByServiceComponentHost(
+    m_dao.removeCurrentByServiceComponentHost(m_cluster.getClusterId(),
         entity.getAlertHistory().getServiceName(),
         entity.getAlertHistory().getComponentName(),
         entity.getAlertHistory().getHostName());

http://git-wip-us.apache.org/repos/asf/ambari/blob/ef9a456a/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertStateChangedEventTest.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertStateChangedEventTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertStateChangedEventTest.java
index e37f0cb..e42e1a7 100644
--- 
a/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertStateChangedEventTest.java
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertStateChangedEventTest.java
@@ -23,11 +23,17 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import junit.framework.Assert;
+
+import org.apache.ambari.server.events.AggregateAlertRecalculateEvent;
+import org.apache.ambari.server.events.AlertEvent;
 import org.apache.ambari.server.events.AlertStateChangeEvent;
+import org.apache.ambari.server.events.MockEventListener;
 import org.apache.ambari.server.events.publishers.AlertEventPublisher;
 import org.apache.ambari.server.orm.GuiceJpaInitializer;
 import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
 import org.apache.ambari.server.orm.dao.AlertDispatchDAO;
+import org.apache.ambari.server.orm.dao.AlertsDAO;
 import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
 import org.apache.ambari.server.orm.entities.AlertGroupEntity;
 import org.apache.ambari.server.orm.entities.AlertHistoryEntity;
@@ -57,6 +63,7 @@ public class AlertStateChangedEventTest {
   private AlertEventPublisher eventPublisher;
   private AlertDispatchDAO dispatchDao;
   private Injector injector;
+  private MockEventListener m_listener;
 
   /**
    *
@@ -67,12 +74,13 @@ public class AlertStateChangedEventTest {
         new InMemoryDefaultTestModule()).with(new MockModule()));
 
     injector.getInstance(GuiceJpaInitializer.class);
+    m_listener = injector.getInstance(MockEventListener.class);
 
     dispatchDao = injector.getInstance(AlertDispatchDAO.class);
 
     // !!! need a synchronous op for testing
-    EventBusSynchronizer.synchronizeAlertEventPublisher(injector);
-    EventBusSynchronizer.synchronizeAmbariEventPublisher(injector);
+    
EventBusSynchronizer.synchronizeAlertEventPublisher(injector).register(m_listener);
+    
EventBusSynchronizer.synchronizeAmbariEventPublisher(injector).register(m_listener);
 
     eventPublisher = injector.getInstance(AlertEventPublisher.class);
   }
@@ -197,6 +205,22 @@ public class AlertStateChangedEventTest {
   }
 
   /**
+   * Tests that {@link AggregateAlertRecalculateEvent}s are fired correctly.
+   *
+   * @throws Exception
+   */
+  @Test
+  public void testAggregateAlertRecalculateEvent() throws Exception {
+    Class<? extends AlertEvent> eventClass = 
AggregateAlertRecalculateEvent.class;
+
+    Assert.assertFalse(m_listener.isAlertEventReceived(eventClass));
+    AlertsDAO dao = injector.getInstance(AlertsDAO.class);
+    dao.removeCurrentByServiceComponentHost(1, "HDFS", "DATANODE", "c6401");
+    Assert.assertTrue(m_listener.isAlertEventReceived(eventClass));
+    Assert.assertEquals(1, m_listener.getAlertEventReceivedCount(eventClass));
+  }
+
+  /**
    *
    */
   private class MockModule implements Module {

http://git-wip-us.apache.org/repos/asf/ambari/blob/ef9a456a/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
index 67c08ba..6093dd7 100644
--- 
a/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
@@ -29,7 +29,8 @@ import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.atomic.AtomicReference;
 
-import com.google.inject.persist.UnitOfWork;
+import junit.framework.Assert;
+
 import org.apache.ambari.server.events.AlertEvent;
 import org.apache.ambari.server.events.AlertReceivedEvent;
 import org.apache.ambari.server.events.AlertStateChangeEvent;
@@ -76,6 +77,7 @@ import com.google.gson.Gson;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.persist.PersistService;
+import com.google.inject.persist.UnitOfWork;
 
 
 /**
@@ -415,12 +417,21 @@ public class AlertDataManagerTest {
 
     AlertAggregateListener listener = 
m_injector.getInstance(AlertAggregateListener.class);
     AlertDefinitionFactory factory = new AlertDefinitionFactory();
+
+    // get the aggregate cache and test it a little bit
     AggregateDefinitionMapping aggregateMapping = 
m_injector.getInstance(AggregateDefinitionMapping.class);
 
     AlertDefinition aggregateDefinition = factory.coerce(aggDef);
     aggregateMapping.registerAggregate(m_cluster.getClusterId(),
         aggregateDefinition );
 
+    // make sure the aggregate has the correct associations
+    Assert.assertEquals(aggregateDefinition,
+        
aggregateMapping.getAggregateDefinitions(m_cluster.getClusterId()).get(0));
+
+    Assert.assertEquals(definition.getDefinitionName(),
+        
aggregateMapping.getAlertsWithAggregates(m_cluster.getClusterId()).get(0));
+
     AggregateSource as = (AggregateSource) aggregateDefinition.getSource();
     AlertDefinition aggregatedDefinition = 
aggregateMapping.getAggregateDefinition(
         m_cluster.getClusterId(), as.getAlertName());

Reply via email to