浏览代码

AMBARI-16277 - Alert Targets Should Be Allowed To Be Disabled Without Deleting Them (jonathanhurley)

Jonathan Hurley 9 年之前
父节点
当前提交
c39996a572
共有 16 个文件被更改,包括 188 次插入30 次删除
  1. 20 1
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProvider.java
  2. 15 4
      ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertStateChangedListener.java
  3. 26 2
      ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertTargetEntity.java
  4. 2 0
      ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertTargetEntity_.java
  5. 22 0
      ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertTarget.java
  6. 18 1
      ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java
  7. 1 0
      ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
  8. 1 0
      ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
  9. 1 0
      ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
  10. 1 0
      ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
  11. 1 0
      ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
  12. 1 0
      ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
  13. 1 0
      ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
  14. 15 19
      ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java
  15. 54 3
      ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertStateChangedEventTest.java
  16. 9 0
      ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java

+ 20 - 1
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProvider.java

@@ -42,9 +42,9 @@ import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
 import org.apache.ambari.server.controller.spi.SystemException;
 import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
-import org.apache.ambari.server.notifications.TargetConfigurationResult;
 import org.apache.ambari.server.notifications.DispatchFactory;
 import org.apache.ambari.server.notifications.NotificationDispatcher;
+import org.apache.ambari.server.notifications.TargetConfigurationResult;
 import org.apache.ambari.server.orm.dao.AlertDispatchDAO;
 import org.apache.ambari.server.orm.entities.AlertGroupEntity;
 import org.apache.ambari.server.orm.entities.AlertTargetEntity;
@@ -76,6 +76,7 @@ public class AlertTargetResourceProvider extends
   public static final String ALERT_TARGET_GROUPS = "AlertTarget/groups";
   public static final String ALERT_TARGET_STATES = "AlertTarget/alert_states";
   public static final String ALERT_TARGET_GLOBAL = "AlertTarget/global";
+  public static final String ALERT_TARGET_ENABLED = "AlertTarget/enabled";
 
   private static final Set<String> PK_PROPERTY_IDS = new HashSet<String>(
       Arrays.asList(ALERT_TARGET_ID, ALERT_TARGET_NAME));
@@ -100,6 +101,7 @@ public class AlertTargetResourceProvider extends
     PROPERTY_IDS.add(ALERT_TARGET_GROUPS);
     PROPERTY_IDS.add(ALERT_TARGET_STATES);
     PROPERTY_IDS.add(ALERT_TARGET_GLOBAL);
+    PROPERTY_IDS.add(ALERT_TARGET_ENABLED);
 
     // keys
     KEY_PROPERTY_IDS.put(Resource.Type.AlertTarget, ALERT_TARGET_ID);
@@ -270,6 +272,7 @@ public class AlertTargetResourceProvider extends
       String notificationType = (String) requestMap.get(ALERT_TARGET_NOTIFICATION_TYPE);
       Collection<String> alertStates = (Collection<String>) requestMap.get(ALERT_TARGET_STATES);
       String globalProperty = (String) requestMap.get(ALERT_TARGET_GLOBAL);
+      String enabledProperty = (String) requestMap.get(ALERT_TARGET_ENABLED);
 
       if (StringUtils.isEmpty(name)) {
         throw new IllegalArgumentException(
@@ -306,6 +309,12 @@ public class AlertTargetResourceProvider extends
         isGlobal = Boolean.parseBoolean(globalProperty);
       }
 
+      // enabled not required
+      boolean isEnabled = true;
+      if (null != enabledProperty) {
+        isEnabled = Boolean.parseBoolean(enabledProperty);
+      }
+
       // set the states that this alert target cares about
       final Set<AlertState> alertStateSet;
       if (null != alertStates) {
@@ -344,6 +353,7 @@ public class AlertTargetResourceProvider extends
       entity.setTargetName(name);
       entity.setAlertStates(alertStateSet);
       entity.setGlobal(isGlobal);
+      entity.setEnabled(isEnabled);
 
       if (null == entity.getTargetId() || 0 == entity.getTargetId()) {
         s_dao.create(entity);
@@ -381,9 +391,16 @@ public class AlertTargetResourceProvider extends
     Collection<String> alertStates = (Collection<String>) requestMap.get(ALERT_TARGET_STATES);
     Collection<Long> groupIds = (Collection<Long>) requestMap.get(ALERT_TARGET_GROUPS);
     String isGlobal = (String) requestMap.get(ALERT_TARGET_GLOBAL);
+    String isEnabled = (String) requestMap.get(ALERT_TARGET_ENABLED);
+
     if(null != isGlobal){
       entity.setGlobal(Boolean.parseBoolean(isGlobal));
     }
+
+    if (null != isEnabled) {
+      entity.setEnabled(Boolean.parseBoolean(isEnabled));
+    }
+
     if (!StringUtils.isBlank(name)) {
       entity.setTargetName(name);
     }
@@ -459,6 +476,8 @@ public class AlertTargetResourceProvider extends
     resource.setProperty(ALERT_TARGET_NOTIFICATION_TYPE,
         entity.getNotificationType());
 
+    resource.setProperty(ALERT_TARGET_ENABLED, entity.isEnabled());
+
     // these are expensive to deserialize; only do it if asked for
     if (requestedIds.contains(ALERT_TARGET_PROPERTIES)) {
       String properties = entity.getProperties();

+ 15 - 4
ambari-server/src/main/java/org/apache/ambari/server/events/listeners/alerts/AlertStateChangedListener.java

@@ -141,6 +141,7 @@ public class AlertStateChangedListener {
 
     List<AlertGroupEntity> groups = m_alertsDispatchDao.findGroupsByDefinition(definition);
     List<AlertNoticeEntity> notices = new LinkedList<AlertNoticeEntity>();
+
     // for each group, determine if there are any targets that need to receive
     // a notification about the alert state change event
     for (AlertGroupEntity group : groups) {
@@ -150,7 +151,7 @@ public class AlertStateChangedListener {
       }
 
       for (AlertTargetEntity target : targets) {
-        if (!isAlertTargetInterested(target, history)) {
+        if (!isAlertTargetInterestedAndEnabled(target, history)) {
           continue;
         }
 
@@ -163,12 +164,16 @@ public class AlertStateChangedListener {
       }
     }
 
-    m_alertsDispatchDao.createNotices(notices);
+    // create notices if there are any to create
+    if (!notices.isEmpty()) {
+      m_alertsDispatchDao.createNotices(notices);
+    }
   }
 
   /**
    * Gets whether the {@link AlertTargetEntity} is interested in receiving a
-   * notification about the {@link AlertHistoryEntity}'s state change.
+   * notification about the {@link AlertHistoryEntity}'s state change. If an
+   * alert target is disabled, then this will return {@code false}.
    *
    * @param target
    *          the target (not {@code null}).
@@ -178,8 +183,14 @@ public class AlertStateChangedListener {
    * @return {@code true} if the target cares about this state change,
    *         {@code false} otherwise.
    */
-  private boolean isAlertTargetInterested(AlertTargetEntity target,
+  private boolean isAlertTargetInterestedAndEnabled(AlertTargetEntity target,
       AlertHistoryEntity history) {
+
+    // disable alert targets should be skipped
+    if (!target.isEnabled()) {
+      return false;
+    }
+
     Set<AlertState> alertStates = target.getAlertStates();
     if (null != alertStates && alertStates.size() > 0) {
       if (!alertStates.contains(history.getAlertState())) {

+ 26 - 2
ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertTargetEntity.java

@@ -84,7 +84,10 @@ public class AlertTargetEntity {
   private String targetName;
 
   @Column(name = "is_global", nullable = false, length = 1)
-  private Integer isGlobal = Integer.valueOf(0);
+  private Short isGlobal = Short.valueOf((short) 0);
+
+  @Column(name = "is_enabled", nullable = false, length = 1)
+  private Short isEnabled = Short.valueOf((short) 1);
 
   /**
    * Bi-directional many-to-many association to {@link AlertGroupEntity}
@@ -203,7 +206,28 @@ public class AlertTargetEntity {
    *          {@code} if the target is global.
    */
   public void setGlobal(boolean isGlobal) {
-    this.isGlobal = isGlobal ? 1 : 0;
+    this.isGlobal = isGlobal ? (short) 1 : (short) 0;
+  }
+
+  /**
+   * Gets whether the alert target is enabled. Targets which are not enabled
+   * will not receive notifications.
+   *
+   * @return the {@code true} if the target is enabled.
+   */
+  public boolean isEnabled() {
+    return isEnabled == 0 ? false : true;
+  }
+
+  /**
+   * Sets whether the alert target is enabled. Targets which are not enabled
+   * will not receive notifications.
+   *
+   * @param isEnabled
+   *          {@code} if the target is enabled.
+   */
+  public void setEnabled(boolean isEnabled) {
+    this.isEnabled = isEnabled ? (short) 1 : (short) 0;
   }
 
   /**

+ 2 - 0
ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertTargetEntity_.java

@@ -35,5 +35,7 @@ public class AlertTargetEntity_ {
   public static volatile SingularAttribute<AlertTargetEntity, String> notificationType;
   public static volatile SingularAttribute<AlertTargetEntity, String> properties;
   public static volatile SingularAttribute<AlertTargetEntity, String> targetName;
+  public static volatile SingularAttribute<AlertTargetEntity, Short> isGlobal;
+  public static volatile SingularAttribute<AlertTargetEntity, Short> isEnabled;
   public static volatile SetAttribute<AlertTargetEntity, AlertGroupEntity> alertGroups;
 }

+ 22 - 0
ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertTarget.java

@@ -35,6 +35,7 @@ public class AlertTarget {
   private String m_notificationType;
   private Map<String, String> m_properties;
   private boolean m_isGlobal;
+  private boolean m_isEnabled;
 
   /**
    * @return the id
@@ -136,6 +137,26 @@ public class AlertTarget {
     m_isGlobal = isGlobal;
   }
 
+  /**
+   * Gets whether the alert target is enabled.
+   *
+   * @return {@code true} if enabled.
+   */
+  @JsonProperty("enabled")
+  public boolean isEnabled() {
+    return m_isEnabled;
+  }
+
+  /**
+   * Sets whether the alert target is enabled.
+   *
+   * @param isEnabled
+   *          {@code true} if the alert target is enabled.
+   */
+  public void setEnabled(boolean isEnabled) {
+    m_isEnabled = isEnabled;
+  }
+
   /**
    * @param entity
    * @return
@@ -147,6 +168,7 @@ public class AlertTarget {
     target.setName(entity.getTargetName());
     target.setNotificationType(entity.getNotificationType());
     target.setGlobal(entity.isGlobal());
+    target.setEnabled(entity.isEnabled());
     return target;
   }
 }

+ 18 - 1
ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java

@@ -87,6 +87,8 @@ public class UpgradeCatalog240 extends AbstractUpgradeCatalog {
   protected static final String ADMIN_PERMISSION_TABLE = "adminpermission";
   protected static final String PRINCIPAL_ID_COL = "principal_id";
   protected static final String ALERT_DEFINITION_TABLE = "alert_definition";
+  protected static final String ALERT_TARGET_TABLE = "alert_target";
+  protected static final String ALERT_TARGET_ENABLED_COLUMN = "is_enabled";
   protected static final String ALERT_CURRENT_TABLE = "alert_current";
   protected static final String ALERT_CURRENT_OCCURRENCES_COLUMN = "occurrences";
   protected static final String ALERT_CURRENT_FIRMNESS_COLUMN = "firmness";
@@ -216,6 +218,7 @@ public class UpgradeCatalog240 extends AbstractUpgradeCatalog {
     updateClusterTableDDL();
     updateAlertDefinitionTable();
     updateAlertCurrentTable();
+    updateAlertTargetTable();
     createBlueprintSettingTable();
     updateHostRoleCommandTableDDL();
     createViewUrlTableDDL();
@@ -1111,6 +1114,19 @@ public class UpgradeCatalog240 extends AbstractUpgradeCatalog {
       String.class, 255, AlertFirmness.HARD.name(), false));
   }
 
+  /**
+   * Updates the {@value #ALERT_TARGET_TABLE} in the following ways:
+   * <ul>
+   * <li>Creates the {@value #ALERT_TARGET_ENABLED_COLUMN} column</li>
+   * </ul>
+   *
+   * @throws SQLException
+   */
+  protected void updateAlertTargetTable() throws SQLException {
+    dbAccessor.addColumn(ALERT_TARGET_TABLE,
+        new DBColumnInfo(ALERT_TARGET_ENABLED_COLUMN, Short.class, null, 1, false));
+  }
+
   protected void setRoleSortOrder() throws SQLException {
     String updateStatement = "UPDATE " + ADMIN_PERMISSION_TABLE + " SET " + SORT_ORDER_COL + "=%d WHERE " + PERMISSION_ID_COL + "='%s'";
 
@@ -1468,8 +1484,9 @@ public class UpgradeCatalog240 extends AbstractUpgradeCatalog {
 
               Config hiveEnv = cluster.getDesiredConfigByType("hive-env");
               if(hiveEnv != null){
-                if(acid_enabled)
+                if(acid_enabled) {
                   updateConfigurationProperties("hive-env", Collections.singletonMap("hive_txn_acid", "on"), true, false);
+                }
               }
             }
           }

+ 1 - 0
ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql

@@ -951,6 +951,7 @@ CREATE TABLE alert_target (
   properties VARCHAR(3000),
   description VARCHAR(1024),
   is_global SMALLINT NOT NULL DEFAULT 0,
+  is_enabled SMALLINT NOT NULL DEFAULT 1,
   CONSTRAINT PK_alert_target PRIMARY KEY (target_id)
 );
 

+ 1 - 0
ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql

@@ -959,6 +959,7 @@ CREATE TABLE alert_target (
   properties TEXT,
   description VARCHAR(1024),
   is_global SMALLINT NOT NULL DEFAULT 0,
+  is_enabled SMALLINT NOT NULL DEFAULT 1,
   CONSTRAINT PK_alert_target PRIMARY KEY (target_id)
 );
 

+ 1 - 0
ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql

@@ -949,6 +949,7 @@ CREATE TABLE alert_target (
   properties CLOB,
   description VARCHAR2(1024),
   is_global NUMBER(1) DEFAULT 0 NOT NULL,
+  is_enabled NUMBER(1) DEFAULT 1 NOT NULL,
   CONSTRAINT PK_alert_target PRIMARY KEY (target_id)
 );
 

+ 1 - 0
ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql

@@ -948,6 +948,7 @@ CREATE TABLE alert_target (
   properties TEXT,
   description VARCHAR(1024),
   is_global SMALLINT NOT NULL DEFAULT 0,
+  is_enabled SMALLINT NOT NULL DEFAULT 1,
   CONSTRAINT PK_alert_target PRIMARY KEY (target_id)
 );
 

+ 1 - 0
ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql

@@ -1096,6 +1096,7 @@ CREATE TABLE ambari.alert_target (
   properties TEXT,
   description VARCHAR(1024),
   is_global SMALLINT NOT NULL DEFAULT 0,
+  is_enabled SMALLINT NOT NULL DEFAULT 1,
   CONSTRAINT PK_alert_target PRIMARY KEY (target_id)
 );
 

+ 1 - 0
ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql

@@ -949,6 +949,7 @@ CREATE TABLE alert_target (
   properties TEXT,
   description VARCHAR(1024),
   is_global SMALLINT NOT NULL DEFAULT 0,
+  is_enabled SMALLINT NOT NULL DEFAULT 1,
   CONSTRAINT PK_alert_target PRIMARY KEY (target_id)
 );
 

+ 1 - 0
ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql

@@ -972,6 +972,7 @@ CREATE TABLE alert_target (
   properties TEXT,
   description VARCHAR(1024),
   is_global SMALLINT NOT NULL DEFAULT 0,
+  is_enabled SMALLINT NOT NULL DEFAULT 1,
   CONSTRAINT PK_alert_target PRIMARY KEY CLUSTERED (target_id)
 );
 

+ 15 - 19
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java

@@ -67,14 +67,14 @@ import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
 
 import com.google.inject.Binder;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Module;
 import com.google.inject.util.Modules;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
 
 /**
  * {@link AlertTargetResourceProvider} tests.
@@ -366,7 +366,7 @@ public class AlertTargetResourceProviderTest {
     groups.addAll(Arrays.asList(group1, group2, group3));
     expect(m_dao.findGroupsById(groupIds)).andReturn(groups).once();
 
-    Capture<AlertTargetEntity> targetCapture = new Capture<AlertTargetEntity>();
+    Capture<AlertTargetEntity> targetCapture = EasyMock.newCapture();
     m_dao.create(capture(targetCapture));
     expectLastCall();
 
@@ -431,7 +431,7 @@ public class AlertTargetResourceProviderTest {
    * @throws Exception
    */
   private void testCreateGlobalTarget(Authentication authentication) throws Exception {
-    Capture<AlertTargetEntity> targetCapture = new Capture<AlertTargetEntity>();
+    Capture<AlertTargetEntity> targetCapture = EasyMock.newCapture();
     m_dao.create(capture(targetCapture));
     expectLastCall();
 
@@ -497,7 +497,7 @@ public class AlertTargetResourceProviderTest {
    * @throws Exception
    */
   private void testCreateResourceWithRecipientArray(Authentication  authentication) throws Exception {
-    Capture<AlertTargetEntity> targetCapture = new Capture<AlertTargetEntity>();
+    Capture<AlertTargetEntity> targetCapture = EasyMock.newCapture();
     m_dao.create(capture(targetCapture));
     expectLastCall();
 
@@ -560,9 +560,8 @@ public class AlertTargetResourceProviderTest {
   /**
    * @throws Exception
    */
-  @SuppressWarnings("unchecked")
   private void testCreateResourceWithAlertStates(Authentication authentication) throws Exception {
-    Capture<AlertTargetEntity> targetCapture = new Capture<AlertTargetEntity>();
+    Capture<AlertTargetEntity> targetCapture = EasyMock.newCapture();
     m_dao.create(capture(targetCapture));
     expectLastCall();
 
@@ -574,7 +573,7 @@ public class AlertTargetResourceProviderTest {
     Map<String, Object> requestProps = getCreationProperties();
     requestProps.put(
         AlertTargetResourceProvider.ALERT_TARGET_STATES,
-        new ArrayList(Arrays.asList(AlertState.OK.name(),
+        new ArrayList<String>(Arrays.asList(AlertState.OK.name(),
             AlertState.UNKNOWN.name())));
 
     Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
@@ -628,9 +627,8 @@ public class AlertTargetResourceProviderTest {
   /**
    * @throws Exception
    */
-  @SuppressWarnings("unchecked")
   private void testUpdateResources(Authentication authentication) throws Exception {
-    Capture<AlertTargetEntity> entityCapture = new Capture<AlertTargetEntity>();
+    Capture<AlertTargetEntity> entityCapture = EasyMock.newCapture();
     m_dao.create(capture(entityCapture));
     expectLastCall().times(1);
 
@@ -704,9 +702,8 @@ public class AlertTargetResourceProviderTest {
   /**
    * @throws Exception
    */
-  @SuppressWarnings("unchecked")
   private void testUpdateResourcesWithGroups(Authentication authentication) throws Exception {
-    Capture<AlertTargetEntity> entityCapture = new Capture<AlertTargetEntity>();
+    Capture<AlertTargetEntity> entityCapture = EasyMock.newCapture();
     m_dao.create(capture(entityCapture));
     expectLastCall().times(1);
 
@@ -788,7 +785,7 @@ public class AlertTargetResourceProviderTest {
    * @throws Exception
    */
   private void testDeleteResources(Authentication authentication) throws Exception {
-    Capture<AlertTargetEntity> entityCapture = new Capture<AlertTargetEntity>();
+    Capture<AlertTargetEntity> entityCapture = EasyMock.newCapture();
     m_dao.create(capture(entityCapture));
     expectLastCall().times(1);
 
@@ -856,7 +853,7 @@ public class AlertTargetResourceProviderTest {
     // mock out returning an existing entity
     AlertTargetEntity entity = getMockEntities().get(0);
     expect(m_dao.findTargetByName(ALERT_TARGET_NAME)).andReturn(entity).atLeastOnce();
-    Capture<AlertTargetEntity> targetCapture = new Capture<AlertTargetEntity>();
+    Capture<AlertTargetEntity> targetCapture = EasyMock.newCapture();
     expect(m_dao.merge(capture(targetCapture))).andReturn(entity).once();
 
     replay(m_amc, m_dao);
@@ -896,14 +893,14 @@ public class AlertTargetResourceProviderTest {
 
   @Test
   public void testUpdateAlertTargetsWithCustomGroups() throws Exception{
-    Capture<AlertTargetEntity> entityCapture = new Capture<AlertTargetEntity>();
+    Capture<AlertTargetEntity> entityCapture = EasyMock.newCapture();
     m_dao.create(capture(entityCapture));
     expectLastCall().times(1);
 
     AlertTargetEntity target = new AlertTargetEntity();
     expect(m_dao.findTargetById(ALERT_TARGET_ID)).andReturn(target).once();
 
-    Capture<AlertGroupEntity> groupEntityCapture = new Capture<AlertGroupEntity>();
+    Capture<AlertGroupEntity> groupEntityCapture = EasyMock.newCapture();
 
     //All Groups in the Database with CLuster ID = 1L
     List<AlertGroupEntity> groups = getMockGroupEntities();
@@ -957,14 +954,14 @@ public class AlertTargetResourceProviderTest {
 
   @Test
   public void testUpdateAlertTargetsWithAllGroups() throws Exception{
-    Capture<AlertTargetEntity> entityCapture = new Capture<AlertTargetEntity>();
+    Capture<AlertTargetEntity> entityCapture = EasyMock.newCapture();
     m_dao.create(capture(entityCapture));
     expectLastCall().times(1);
 
     AlertTargetEntity target = new AlertTargetEntity();
     expect(m_dao.findTargetById(ALERT_TARGET_ID)).andReturn(target).once();
 
-    Capture<AlertGroupEntity> groupEntityCapture = new Capture<AlertGroupEntity>();
+    Capture<AlertGroupEntity> groupEntityCapture = EasyMock.newCapture();
 
     //All Groups in the Database with CLuster ID = 1L
     List<AlertGroupEntity> groups = getMockGroupEntities();
@@ -1098,7 +1095,6 @@ public class AlertTargetResourceProviderTest {
   /**
    * @return
    */
-  @SuppressWarnings({ "rawtypes", "unchecked" })
   private List<AlertGroupEntity> getMockGroupEntities() throws Exception {
     AlertGroupEntity group1 = new AlertGroupEntity();
     AlertGroupEntity group2 = new AlertGroupEntity();

+ 54 - 3
ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertStateChangedEventTest.java

@@ -116,6 +116,7 @@ public class AlertStateChangedEventTest {
     groups.add(alertGroup);
 
     EasyMock.expect(alertGroup.getAlertTargets()).andReturn(targets).once();
+    EasyMock.expect(alertTarget.isEnabled()).andReturn(Boolean.TRUE).atLeastOnce();
     EasyMock.expect(alertTarget.getAlertStates()).andReturn(
         EnumSet.of(AlertState.OK, AlertState.CRITICAL)).atLeastOnce();
 
@@ -149,7 +150,7 @@ public class AlertStateChangedEventTest {
 
     // async publishing
     eventPublisher.publish(event);
-    EasyMock.verify(dispatchDao, current, history, event);
+    EasyMock.verify(dispatchDao, alertTarget, current, history, event);
   }
 
   /**
@@ -169,6 +170,7 @@ public class AlertStateChangedEventTest {
     groups.add(alertGroup);
 
     EasyMock.expect(alertGroup.getAlertTargets()).andReturn(targets).once();
+    EasyMock.expect(alertTarget.isEnabled()).andReturn(Boolean.TRUE).atLeastOnce();
     EasyMock.expect(alertTarget.getAlertStates()).andReturn(
         EnumSet.of(AlertState.OK, AlertState.CRITICAL)).atLeastOnce();
 
@@ -176,8 +178,6 @@ public class AlertStateChangedEventTest {
         dispatchDao.findGroupsByDefinition(EasyMock.anyObject(AlertDefinitionEntity.class))).andReturn(
         groups).once();
 
-    dispatchDao.createNotices(EasyMock.<List<AlertNoticeEntity>>anyObject());
-
     // dispatchDao should be strict enough to throw an exception on verify
     // that the create alert notice method was not called
     EasyMock.replay(alertTarget, alertGroup, dispatchDao);
@@ -210,6 +210,57 @@ public class AlertStateChangedEventTest {
     EasyMock.verify(dispatchDao, current, history, event);
   }
 
+  /**
+   * Tests that an {@link AlertNoticeEntity} is not created for a target that
+   * has been disabled.
+   *
+   * @throws Exception
+   */
+  @Test
+  public void testAlertNoticeSkippedForDisabledTarget() throws Exception {
+    AlertTargetEntity alertTarget = EasyMock.createMock(AlertTargetEntity.class);
+    AlertGroupEntity alertGroup = EasyMock.createMock(AlertGroupEntity.class);
+    List<AlertGroupEntity> groups = new ArrayList<AlertGroupEntity>();
+    Set<AlertTargetEntity> targets = new HashSet<AlertTargetEntity>();
+
+    targets.add(alertTarget);
+    groups.add(alertGroup);
+
+    EasyMock.expect(alertGroup.getAlertTargets()).andReturn(targets).once();
+    EasyMock.expect(alertTarget.isEnabled()).andReturn(Boolean.FALSE).atLeastOnce();
+
+    EasyMock.expect(dispatchDao.findGroupsByDefinition(
+        EasyMock.anyObject(AlertDefinitionEntity.class))).andReturn(groups).once();
+
+    // dispatchDao should be strict enough to throw an exception on verify
+    // that the create alert notice method was not called
+    EasyMock.replay(alertTarget, alertGroup, dispatchDao);
+
+    AlertDefinitionEntity definition = getMockAlertDefinition();
+
+    AlertCurrentEntity current = getMockedAlertCurrentEntity();
+    AlertHistoryEntity history = EasyMock.createNiceMock(AlertHistoryEntity.class);
+    AlertStateChangeEvent event = EasyMock.createNiceMock(AlertStateChangeEvent.class);
+    Alert alert = EasyMock.createNiceMock(Alert.class);
+
+    EasyMock.expect(current.getAlertHistory()).andReturn(history).anyTimes();
+    EasyMock.expect(current.getFirmness()).andReturn(AlertFirmness.HARD).atLeastOnce();
+    EasyMock.expect(history.getAlertState()).andReturn(AlertState.OK).atLeastOnce();
+
+    EasyMock.expect(history.getAlertDefinition()).andReturn(definition).atLeastOnce();
+    EasyMock.expect(alert.getText()).andReturn("The HDFS Foo Alert Is Not Good").atLeastOnce();
+    EasyMock.expect(alert.getState()).andReturn(AlertState.WARNING).atLeastOnce();
+    EasyMock.expect(event.getCurrentAlert()).andReturn(current).atLeastOnce();
+    EasyMock.expect(event.getNewHistoricalEntry()).andReturn(history).atLeastOnce();
+    EasyMock.expect(event.getAlert()).andReturn(alert).atLeastOnce();
+
+    EasyMock.replay(definition, current, history, event, alert);
+
+    // async publishing
+    eventPublisher.publish(event);
+    EasyMock.verify(dispatchDao, alertTarget, current, history, event);
+  }
+
   /**
    * Tests that an alert with a firmness of {@link AlertFirmness#SOFT} does not
    * trigger any notifications.

+ 9 - 0
ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java

@@ -197,12 +197,14 @@ public class UpgradeCatalog240Test {
     Capture<DBAccessor.DBColumnInfo> capturedRepeatToleranceEnabledColumnInfo = newCapture();
     Capture<DBAccessor.DBColumnInfo> capturedOccurrencesColumnInfo = newCapture();
     Capture<DBAccessor.DBColumnInfo> capturedFirmnessColumnInfo = newCapture();
+    Capture<DBAccessor.DBColumnInfo> capturedTargetEnabledColumnInfo = newCapture();
 
     dbAccessor.addColumn(eq(UpgradeCatalog240.ALERT_DEFINITION_TABLE), capture(capturedHelpURLColumnInfo));
     dbAccessor.addColumn(eq(UpgradeCatalog240.ALERT_DEFINITION_TABLE), capture(capturedRepeatToleranceColumnInfo));
     dbAccessor.addColumn(eq(UpgradeCatalog240.ALERT_DEFINITION_TABLE), capture(capturedRepeatToleranceEnabledColumnInfo));
     dbAccessor.addColumn(eq(UpgradeCatalog240.ALERT_CURRENT_TABLE), capture(capturedOccurrencesColumnInfo));
     dbAccessor.addColumn(eq(UpgradeCatalog240.ALERT_CURRENT_TABLE), capture(capturedFirmnessColumnInfo));
+    dbAccessor.addColumn(eq(UpgradeCatalog240.ALERT_TARGET_TABLE), capture(capturedTargetEnabledColumnInfo));
 
     // Test creation of blueprint_setting table
     Capture<List<DBAccessor.DBColumnInfo>> capturedBlueprintSettingColumns = EasyMock.newCapture();
@@ -353,6 +355,13 @@ public class UpgradeCatalog240Test {
     Assert.assertEquals(AlertFirmness.HARD.name(), columnFirmnessInfo.getDefaultValue());
     Assert.assertEquals(false, columnFirmnessInfo.isNullable());
 
+    DBAccessor.DBColumnInfo targetEnabledColumnInfo = capturedTargetEnabledColumnInfo.getValue();
+    Assert.assertNotNull(targetEnabledColumnInfo);
+    Assert.assertEquals(UpgradeCatalog240.ALERT_TARGET_ENABLED_COLUMN, targetEnabledColumnInfo.getName());
+    Assert.assertEquals(Short.class, targetEnabledColumnInfo.getType());
+    Assert.assertEquals(1, targetEnabledColumnInfo.getDefaultValue());
+    Assert.assertEquals(false, targetEnabledColumnInfo.isNullable());    
+    
     assertEquals(expectedCaptures, actualCaptures);
 
     // Verify blueprint_setting columns