Browse Source

AMBARI-8377 - Alerts UI: Alert Definition API should provide a 'description' field (jonathanhurley)

Jonathan Hurley 10 năm trước cách đây
mục cha
commit
a098ddd496
19 tập tin đã thay đổi với 153 bổ sung4 xóa
  1. 18 0
      ambari-server/src/main/java/org/apache/ambari/server/controller/AlertDefinitionResponse.java
  2. 8 0
      ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java
  3. 24 0
      ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
  4. 24 0
      ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinition.java
  5. 2 0
      ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionFactory.java
  6. 3 0
      ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog200.java
  7. 1 0
      ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
  8. 1 0
      ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
  9. 1 0
      ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
  10. 1 0
      ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
  11. 1 0
      ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
  12. 18 0
      ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/alerts.json
  13. 3 0
      ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
  14. 17 1
      ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProviderTest.java
  15. 2 0
      ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java
  16. 1 0
      ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertDefinitionEqualityTest.java
  17. 1 0
      ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
  18. 21 3
      ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog200Test.java
  19. 6 0
      ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HDFS/alerts.json

+ 18 - 0
ambari-server/src/main/java/org/apache/ambari/server/controller/AlertDefinitionResponse.java

@@ -33,6 +33,7 @@ public class AlertDefinitionResponse {
   private String componentName = null;
   private String name = null;
   private String label = null;
+  private String description = null;
   private Long definitionId;
   private boolean enabled = true;
   private SourceType sourceType;
@@ -117,6 +118,22 @@ public class AlertDefinitionResponse {
     label = definitionLabel;
   }
 
+  /**
+   * @return the description for the definition or {@code null} if none.
+   */
+  @JsonProperty("description")
+  public String getDescription() {
+    return description;
+  }
+
+  /**
+   * Sets the description for this definition.
+   *
+   * @param definitionDescription
+   */
+  public void setDescription(String definitionDescription) {
+    description = definitionDescription;
+  }
 
   /**
    * Gets whether this definition is enabled.
@@ -179,6 +196,7 @@ public class AlertDefinitionResponse {
     response.setDefinitionId(entity.getDefinitionId());
     response.setComponentName(entity.getComponentName());
     response.setLabel(entity.getLabel());
+    response.setDescription(entity.getDescription());
     response.setName(entity.getDefinitionName());
     response.setServiceName(entity.getServiceName());
     response.setEnabled(entity.getEnabled());

+ 8 - 0
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java

@@ -72,6 +72,7 @@ public class AlertDefinitionResourceProvider extends AbstractControllerResourceP
   protected static final String ALERT_DEF_ID = "AlertDefinition/id";
   protected static final String ALERT_DEF_NAME = "AlertDefinition/name";
   protected static final String ALERT_DEF_LABEL = "AlertDefinition/label";
+  protected static final String ALERT_DEF_DESCRIPTION = "AlertDefinition/description";
   protected static final String ALERT_DEF_INTERVAL = "AlertDefinition/interval";
   protected static final String ALERT_DEF_SERVICE_NAME = "AlertDefinition/service_name";
   protected static final String ALERT_DEF_COMPONENT_NAME = "AlertDefinition/component_name";
@@ -127,6 +128,7 @@ public class AlertDefinitionResourceProvider extends AbstractControllerResourceP
     PROPERTY_IDS.add(ALERT_DEF_ID);
     PROPERTY_IDS.add(ALERT_DEF_NAME);
     PROPERTY_IDS.add(ALERT_DEF_LABEL);
+    PROPERTY_IDS.add(ALERT_DEF_DESCRIPTION);
     PROPERTY_IDS.add(ALERT_DEF_INTERVAL);
     PROPERTY_IDS.add(ALERT_DEF_ENABLED);
     PROPERTY_IDS.add(ALERT_DEF_SCOPE);
@@ -376,6 +378,7 @@ public class AlertDefinitionResourceProvider extends AbstractControllerResourceP
     String componentName = (String) requestMap.get(ALERT_DEF_COMPONENT_NAME);
     String type = (String) requestMap.get(ALERT_DEF_SOURCE_TYPE);
     String label = (String) requestMap.get(ALERT_DEF_LABEL);
+    String description = (String) requestMap.get(ALERT_DEF_DESCRIPTION);
     String desiredScope = (String) requestMap.get(ALERT_DEF_SCOPE);
 
     Integer interval = null;
@@ -498,6 +501,10 @@ public class AlertDefinitionResourceProvider extends AbstractControllerResourceP
       entity.setLabel(label);
     }
 
+    if (null != description) {
+      entity.setDescription(description);
+    }
+
     if (null != enabled) {
       entity.setEnabled(enabled.booleanValue());
     }
@@ -606,6 +613,7 @@ public class AlertDefinitionResourceProvider extends AbstractControllerResourceP
     resource.setProperty(ALERT_DEF_NAME, entity.getDefinitionName());
     resource.setProperty(ALERT_DEF_LABEL, entity.getLabel());
 
+    setResourceProperty(resource, ALERT_DEF_DESCRIPTION, entity.getDescription(), requestedIds);
     setResourceProperty(resource, ALERT_DEF_INTERVAL, entity.getScheduleInterval(), requestedIds);
     setResourceProperty(resource, ALERT_DEF_SERVICE_NAME, entity.getServiceName(), requestedIds);
     setResourceProperty(resource, ALERT_DEF_COMPONENT_NAME, entity.getComponentName(), requestedIds);

+ 24 - 0
ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java

@@ -92,6 +92,11 @@ public class AlertDefinitionEntity {
   @Column(name = "label", nullable = true, length = 255)
   private String label;
 
+  @Lob
+  @Basic
+  @Column(name = "description", nullable = true, length = 32672)
+  private String description;
+
   @Column(name = "scope", length = 255)
   @Enumerated(value = EnumType.STRING)
   private Scope scope;
@@ -434,6 +439,25 @@ public class AlertDefinitionEntity {
     return label;
   }
 
+  /**
+   * Gets the optional description for this alert definition.
+   *
+   * @return the description, or {@code null} if none.
+   */
+  public String getDescription() {
+    return description;
+  }
+
+  /**
+   * Gets the optional description for this alert definition.
+   *
+   * @param description
+   *          the description to set or {@code null} for none.
+   */
+  public void setDescription(String description) {
+    this.description = description;
+  }
+
   /**
    * Adds the specified alert group to the groups that this definition is
    * associated with. This is used to complement the JPA bidirectional

+ 24 - 0
ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinition.java

@@ -46,6 +46,7 @@ public class AlertDefinition {
   private boolean enabled = true;
   private Source source = null;
   private String label = null;
+  private String description = null;
   private String uuid = null;
 
   @SerializedName("ignore_host")
@@ -185,6 +186,21 @@ public class AlertDefinition {
     label = definitionLabel;
   }
 
+  /**
+   * @return the description
+   */
+  public String getDescription() {
+    return description;
+  }
+
+  /**
+   * @param description
+   *          the description to set
+   */
+  public void setDescription(String description) {
+    this.description = description;
+  }
+
   /**
    * Sets the UUID of the definition
    *
@@ -253,6 +269,14 @@ public class AlertDefinition {
       return false;
     }
 
+    if (description == null) {
+      if (other.description != null) {
+        return false;
+      }
+    } else if (!description.equals(other.description)) {
+      return false;
+    }
+
     if (name == null) {
       if (other.name != null) {
         return false;

+ 2 - 0
ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionFactory.java

@@ -186,6 +186,7 @@ public class AlertDefinitionFactory {
     definition.setScope(entity.getScope());
     definition.setServiceName(entity.getServiceName());
     definition.setLabel(entity.getLabel());
+    definition.setDescription(entity.getDescription());
     definition.setUuid(entity.getHash());
 
     try{
@@ -248,6 +249,7 @@ public class AlertDefinitionFactory {
     entity.setHostIgnored(definition.isHostIgnored());
     entity.setHash(UUID.randomUUID().toString());
     entity.setLabel(definition.getLabel());
+    entity.setDescription(definition.getDescription());
     entity.setScheduleInterval(definition.getInterval());
     entity.setServiceName(definition.getServiceName());
 

+ 3 - 0
ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog200.java

@@ -89,6 +89,9 @@ public class UpgradeCatalog200 extends AbstractUpgradeCatalog {
     dbAccessor.addColumn(ALERT_DEFINITION_TABLE, new DBColumnInfo(
         "ignore_host", Short.class, 1, 0, false));
 
+    dbAccessor.addColumn(ALERT_DEFINITION_TABLE, new DBColumnInfo(
+        "description", char[].class, 32672, null, true));
+
     // create alert_target_states table
     ArrayList<DBColumnInfo> columns = new ArrayList<DBColumnInfo>();
     columns.add(new DBColumnInfo("target_id", Long.class, null, null, false));

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

@@ -591,6 +591,7 @@ CREATE TABLE alert_definition (
   component_name VARCHAR(255),
   scope VARCHAR(255) DEFAULT 'ANY' NOT NULL,
   label VARCHAR(255),
+  description TEXT,
   enabled SMALLINT DEFAULT 1 NOT NULL,
   schedule_interval INTEGER NOT NULL,
   source_type VARCHAR(255) NOT NULL,

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

@@ -581,6 +581,7 @@ CREATE TABLE alert_definition (
   component_name VARCHAR2(255),
   scope VARCHAR2(255) DEFAULT 'ANY' NOT NULL,
   label VARCHAR2(255),
+  description CLOB,
   enabled NUMBER(1) DEFAULT 1 NOT NULL,
   schedule_interval NUMBER(10) NOT NULL,
   source_type VARCHAR2(255) NOT NULL,

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

@@ -578,6 +578,7 @@ CREATE TABLE alert_definition (
   component_name VARCHAR(255),
   scope VARCHAR(255) DEFAULT 'ANY' NOT NULL,
   label VARCHAR(255),
+  description TEXT,
   enabled SMALLINT DEFAULT 1 NOT NULL,
   schedule_interval INTEGER NOT NULL,
   source_type VARCHAR(255) NOT NULL,

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

@@ -651,6 +651,7 @@ CREATE TABLE ambari.alert_definition (
   component_name VARCHAR(255),
   scope VARCHAR(255) DEFAULT 'ANY' NOT NULL,
   label VARCHAR(255),
+  description TEXT,
   enabled SMALLINT DEFAULT 1 NOT NULL,
   schedule_interval INTEGER NOT NULL,
   source_type VARCHAR(255) NOT NULL,

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

@@ -162,6 +162,7 @@ CREATE TABLE alert_definition (
   component_name VARCHAR(255),
   scope VARCHAR(255) DEFAULT 'ANY' NOT NULL,
   label VARCHAR(255),
+  description TEXT,
   enabled SMALLINT DEFAULT 1 NOT NULL,
   schedule_interval INTEGER NOT NULL,
   source_type VARCHAR(255) NOT NULL,

+ 18 - 0
ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/alerts.json

@@ -4,6 +4,7 @@
       {
         "name": "datanode_process_percent",
         "label": "Percent DataNodes Available",
+        "description": "The percentage of DataNodes that are responding to the process check compared to those that are not.",
         "interval": 1,
         "scope": "SERVICE",
         "enabled": true,
@@ -28,6 +29,7 @@
       {
         "name": "datanode_storage_percent",
         "label": "Percent DataNodes With Available Space",
+        "description": "The percentage of DataNodes that report they have sufficient space compared to those that are not.",
         "interval": 1,
         "scope": "SERVICE",
         "enabled": true,
@@ -52,6 +54,7 @@
       {
         "name": "journalnode_process_percent",
         "label": "Percent JournalNodes Available",
+        "description": "The percentage of JournalNodes that are responding to the process check compared to those that are not.",
         "interval": 1,
         "scope": "SERVICE",
         "enabled": true,
@@ -78,6 +81,7 @@
       {
         "name": "namenode_webui",
         "label": "NameNode Web UI",
+        "description": "An HTTP-style request to the NameNode webpage to verify that it can be accessed.",
         "interval": 1,
         "scope": "ANY",
         "enabled": true,
@@ -105,6 +109,7 @@
       {
         "name": "namenode_cpu",
         "label": "NameNode Host CPU Utilization",
+        "description": "Checks that the CPU of the NameNode is below a certain load percentage.",
         "interval": 5,
         "scope": "ANY",
         "enabled": true,
@@ -141,6 +146,7 @@
       {
         "name": "namenode_hdfs_blocks_health",
         "label": "NameNode Blocks Health",
+        "description": "Checks to see if the NameNode is reporting any blocks as missing.",
         "interval": 2,
         "scope": "ANY",
         "enabled": true,
@@ -177,6 +183,7 @@
       {
         "name": "namenode_hdfs_capacity_utilization",
         "label": "HDFS Capacity Utilization",
+        "description": "Checks the overall capacity remaining reported by the NameNode and triggers if it falls between a certain threshold",
         "interval": 2,
         "scope": "ANY",
         "enabled": true,
@@ -213,6 +220,7 @@
       {
         "name": "namenode_rpc_latency",
         "label": "NameNode RPC Latency",
+        "description": "Check the TCP latency reported by the NameNode.",
         "interval": 2,
         "scope": "ANY",
         "enabled": true,
@@ -249,6 +257,7 @@
       {
         "name": "namenode_directory_status",
         "label": "NameNode Directory Status",
+        "description": "Checks the NameNode's NameDirStatuses metric to see if any directories report a failure.",
         "interval": 1,
         "scope": "ANY",
         "enabled": true,
@@ -284,6 +293,7 @@
       {
         "name": "namenode_process",
         "label": "NameNode Process",
+        "description": "Checks that the NameNode process responds to a TCP port request.",
         "interval": 1,
         "scope": "ANY",
         "enabled": true,
@@ -304,6 +314,7 @@
       {
         "name": "namenode_last_checkpoint",
         "label": "NameNode Last Checkpoint",
+        "description": "Checks the last time that the NameNode performed a checkpoint. This script will also check for the number of uncommitted transactions.",
         "interval": 1,
         "scope": "ANY",
         "enabled": true,
@@ -315,6 +326,7 @@
       {
         "name": "namenode_ha_health",
         "label": "NameNode High Availability Health",
+        "description": "When running in HA mode, this will check the states of both the Active and Standby NameNode to ensure that there is exactly 1 of each.",
         "interval": 1,
         "scope": "ANY",
         "enabled": true,
@@ -329,6 +341,7 @@
       {
         "name": "secondary_namenode_process",
         "label": "Secondary NameNode Process",
+        "description": "Checks that the Secondary NameNode process responds to a TCP port request.",
         "interval": 1,
         "scope": "ANY",
         "enabled": true,
@@ -351,6 +364,7 @@
       {
         "name": "journalnode_process",
         "label": "JournalNode Process",
+        "description": "Checks that the JournalNode process responds to a TCP port request.",
         "interval": 1,
         "scope": "HOST",
         "enabled": true,
@@ -373,6 +387,7 @@
       {
         "name": "datanode_process",
         "label": "DateNode Process",
+        "description": "Checks that the DateNode process responds to a TCP port request.",
         "interval": 1,
         "scope": "HOST",
         "enabled": true,
@@ -393,6 +408,7 @@
       {
         "name": "datanode_webui",
         "label": "DataNode Web UI",
+        "description": "An HTTP-style request to the DataNode webpage to verify that it can be accessed.",
         "interval": 1,
         "scope": "HOST",
         "enabled": true,
@@ -420,6 +436,7 @@
       {
         "name": "datanode_storage",
         "label": "DataNode Storage",
+        "description": "Checks the capacity remaining on a DataNode and triggers if below a certain percentage.",
         "interval": 2,
         "scope": "HOST",
         "enabled": true,
@@ -458,6 +475,7 @@
       {
         "name": "hdfs_zookeeper_failover_controller_process",
         "label": "ZooKeeper Failover Controller Process",
+        "description": "Checks that the ZooKeeper Failover Controller process responds to a TCP port request.",
         "interval": 1,
         "scope": "ANY",
         "enabled": true,

+ 3 - 0
ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java

@@ -1489,6 +1489,7 @@ public class AmbariMetaInfoTest {
 
     // test namenode_process
     assertFalse(nameNodeProcess.isHostIgnored());
+    assertEquals("A description of namenode_process", nameNodeProcess.getDescription());
     Source source = nameNodeProcess.getSource();
     assertNotNull(source);
     assertNotNull(((PortSource) source).getPort());
@@ -1504,6 +1505,7 @@ public class AmbariMetaInfoTest {
 
     // test namenode_cpu
     assertFalse(nameNodeCpu.isHostIgnored());
+    assertEquals("A description of namenode_cpu", nameNodeCpu.getDescription());
     source = nameNodeCpu.getSource();
     assertNotNull(source);
     reporting = source.getReporting();
@@ -1520,6 +1522,7 @@ public class AmbariMetaInfoTest {
 
     // test a metric alert
     assertNotNull(datanodeStorage);
+    assertEquals("A description of datanode_storage", datanodeStorage.getDescription());
     assertFalse(datanodeStorage.isHostIgnored());
     MetricSource metricSource = (MetricSource) datanodeStorage.getSource();
     assertNotNull( metricSource.getUri() );

+ 17 - 1
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProviderTest.java

@@ -160,6 +160,7 @@ public class AlertDefinitionResourceProviderTest {
         AlertDefinitionResourceProvider.ALERT_DEF_ID,
         AlertDefinitionResourceProvider.ALERT_DEF_NAME,
         AlertDefinitionResourceProvider.ALERT_DEF_LABEL,
+        AlertDefinitionResourceProvider.ALERT_DEF_DESCRIPTION,
         AlertDefinitionResourceProvider.ALERT_DEF_IGNORE_HOST,
         AlertDefinitionResourceProvider.ALERT_DEF_SOURCE,
         AlertDefinitionResourceProvider.ALERT_DEF_SOURCE_TYPE);
@@ -201,6 +202,10 @@ public class AlertDefinitionResourceProviderTest {
     Assert.assertEquals("Mock Label",
         r.getPropertyValue(AlertDefinitionResourceProvider.ALERT_DEF_LABEL));
 
+    Assert.assertEquals(
+        "Mock Description",
+        r.getPropertyValue(AlertDefinitionResourceProvider.ALERT_DEF_DESCRIPTION));
+
     Assert.assertEquals(
         Boolean.FALSE,
         r.getPropertyValue(AlertDefinitionResourceProvider.ALERT_DEF_IGNORE_HOST));
@@ -221,6 +226,7 @@ public class AlertDefinitionResourceProviderTest {
         AlertDefinitionResourceProvider.ALERT_DEF_ID,
         AlertDefinitionResourceProvider.ALERT_DEF_NAME,
         AlertDefinitionResourceProvider.ALERT_DEF_LABEL,
+        AlertDefinitionResourceProvider.ALERT_DEF_DESCRIPTION,
         AlertDefinitionResourceProvider.ALERT_DEF_SOURCE_TYPE);
 
     AmbariManagementController amc = createMock(AmbariManagementController.class);
@@ -311,6 +317,9 @@ public class AlertDefinitionResourceProviderTest {
     requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_LABEL,
         "Mock Label (Create)");
 
+    requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_DESCRIPTION,
+        "Mock Description (Create)");
+
     requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_SOURCE_TYPE,
         SourceType.METRIC.name());
 
@@ -360,6 +369,7 @@ public class AlertDefinitionResourceProviderTest {
     Assert.assertEquals("HDFS", entity.getServiceName());
     Assert.assertEquals(SourceType.METRIC, entity.getSourceType());
     Assert.assertEquals("Mock Label (Create)", entity.getLabel());
+    Assert.assertEquals("Mock Description (Create)", entity.getDescription());
     Assert.assertEquals(false, entity.isHostIgnored());
 
     // verify Source
@@ -422,6 +432,7 @@ public class AlertDefinitionResourceProviderTest {
     requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_INTERVAL, "1");
     requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_NAME, "my_def");
     requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_LABEL, "Label");
+    requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_DESCRIPTION,"Description");
     requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_SERVICE_NAME, "HDFS");
     requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_SOURCE_TYPE, "METRIC");
 
@@ -456,7 +467,8 @@ public class AlertDefinitionResourceProviderTest {
     requestProps.put("AlertDefinition/source/reporting/warning/value",
         source.getReporting().getWarning().getValue());
 
-    Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
+    Request request = PropertyHelper.getCreateRequest(
+        Collections.singleton(requestProps), null);
 
     AlertDefinitionResourceProvider provider = createProvider(amc);
 
@@ -479,6 +491,7 @@ public class AlertDefinitionResourceProviderTest {
     boolean oldEnabled = entity.getEnabled();
     boolean oldHostIgnore = entity.isHostIgnored();
     String oldSource = entity.getSource();
+    String oldDescription = entity.getDescription();
 
     resetToStrict(dao);
     expect(dao.findById(1L)).andReturn(entity).anyTimes();
@@ -491,6 +504,7 @@ public class AlertDefinitionResourceProviderTest {
     requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_INTERVAL, "2");
     requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_NAME, "my_def2");
     requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_LABEL, "Label 2");
+    requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_DESCRIPTION,"Description 2");
     requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_SERVICE_NAME, "HDFS");
     requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_SOURCE_TYPE, "METRIC");
 
@@ -516,6 +530,7 @@ public class AlertDefinitionResourceProviderTest {
 
     Assert.assertFalse(oldHash.equals(entity.getHash()));
     Assert.assertFalse(oldName.equals(entity.getDefinitionName()));
+    Assert.assertFalse(oldDescription.equals(entity.getDescription()));
     Assert.assertFalse(oldInterval.equals(entity.getScheduleInterval()));
     Assert.assertFalse(oldEnabled == entity.getEnabled());
     Assert.assertFalse(oldHostIgnore == entity.isHostIgnored());
@@ -606,6 +621,7 @@ public class AlertDefinitionResourceProviderTest {
     entity.setDefinitionId(Long.valueOf(1L));
     entity.setDefinitionName("my_def");
     entity.setLabel("Mock Label");
+    entity.setDescription("Mock Description");
     entity.setEnabled(true);
     entity.setHash(DEFINITION_UUID);
     entity.setScheduleInterval(Integer.valueOf(2));

+ 2 - 0
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java

@@ -88,6 +88,7 @@ public class AlertGroupResourceProviderTest {
   private static final Long ALERT_DEF_ID = Long.valueOf(10);
   private static final String ALERT_DEF_NAME = "Mock Definition";
   private static final String ALERT_DEF_LABEL = "Mock Label";
+  private static final String ALERT_DEF_DESCRIPTION = "Mock Description";
 
   private static String DEFINITION_UUID = UUID.randomUUID().toString();
 
@@ -631,6 +632,7 @@ public class AlertGroupResourceProviderTest {
     entity.setDefinitionId(ALERT_DEF_ID);
     entity.setDefinitionName(ALERT_DEF_NAME);
     entity.setLabel(ALERT_DEF_LABEL);
+    entity.setDescription(ALERT_DEF_DESCRIPTION);
     entity.setEnabled(true);
     entity.setHash(DEFINITION_UUID);
     entity.setScheduleInterval(Integer.valueOf(2));

+ 1 - 0
ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertDefinitionEqualityTest.java

@@ -80,6 +80,7 @@ public class AlertDefinitionEqualityTest extends TestCase {
     definition.setScope(Scope.ANY);
     definition.setServiceName("ServiceName");
     definition.setLabel("Label");
+    definition.setDescription("Description");
     definition.setSource(getSource(sourceType));
 
     return definition;

+ 1 - 0
ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java

@@ -285,6 +285,7 @@ public class AlertDataManagerTest {
     AlertDefinitionEntity definition = new AlertDefinitionEntity();
     definition.setDefinitionName("to_aggregate");
     definition.setLabel("My Label");
+    definition.setLabel("My Description");
     definition.setServiceName("SERVICE");
     definition.setComponentName(null);
     definition.setClusterId(clusterId);

+ 21 - 3
ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog200Test.java

@@ -88,6 +88,7 @@ public class UpgradeCatalog200Test {
     expect(configuration.getDatabaseUrl()).andReturn(Configuration.JDBC_IN_MEMORY_URL).anyTimes();
 
     Capture<DBAccessor.DBColumnInfo> alertDefinitionIgnoreColumnCapture = new Capture<DBAccessor.DBColumnInfo>();
+    Capture<DBAccessor.DBColumnInfo> alertDefinitionDescriptionColumnCapture = new Capture<DBAccessor.DBColumnInfo>();
     Capture<DBAccessor.DBColumnInfo> hostComponentStateColumnCapture = new Capture<DBAccessor.DBColumnInfo>();
     Capture<List<DBAccessor.DBColumnInfo>> clusterVersionCapture = new Capture<List<DBAccessor.DBColumnInfo>>();
     Capture<List<DBAccessor.DBColumnInfo>> hostVersionCapture = new Capture<List<DBAccessor.DBColumnInfo>>();
@@ -102,6 +103,9 @@ public class UpgradeCatalog200Test {
     dbAccessor.addColumn(eq("alert_definition"),
         capture(alertDefinitionIgnoreColumnCapture));
 
+    dbAccessor.addColumn(eq("alert_definition"),
+        capture(alertDefinitionDescriptionColumnCapture));
+
     dbAccessor.createTable(eq("alert_target_states"),
         capture(alertTargetStatesCapture), eq("target_id"));
 
@@ -119,10 +123,10 @@ public class UpgradeCatalog200Test {
 
     // Upgrade
     dbAccessor.createTable(eq("upgrade"), capture(upgradeCapture), eq("upgrade_id"));
+
     // Upgrade item
     dbAccessor.createTable(eq("upgrade_item"), capture(upgradeItemCapture), eq("upgrade_item_id"));
 
-
     setViewInstancePropertyExpectations(dbAccessor, valueColumnCapture);
     setViewInstanceDataExpectations(dbAccessor, dataValueColumnCapture);
 
@@ -137,8 +141,9 @@ public class UpgradeCatalog200Test {
     upgradeCatalog.executeDDLUpdates();
     verify(dbAccessor, configuration, resultSet);
 
-    // verify ignore column for alert_definition
+    // verify columns for alert_definition
     verifyAlertDefinitionIgnoreColumn(alertDefinitionIgnoreColumnCapture);
+    verifyAlertDefinitionDescriptionColumn(alertDefinitionDescriptionColumnCapture);
 
     // verify new table for alert target states
     verifyAlertTargetStatesTable(alertTargetStatesCapture);
@@ -183,7 +188,7 @@ public class UpgradeCatalog200Test {
   }
 
   /**
-   * Verifies new ignore column.
+   * Verifies new ignore column for alert definition.
    *
    * @param alertDefinitionIgnoreColumnCapture
    */
@@ -196,6 +201,19 @@ public class UpgradeCatalog200Test {
     Assert.assertEquals("ignore_host", column.getName());
   }
 
+  /**
+   * Verifies new description column for alert definition.
+   *
+   * @param alertDefinitionIgnoreColumnCapture
+   */
+  private void verifyAlertDefinitionDescriptionColumn(
+      Capture<DBAccessor.DBColumnInfo> alertDefinitionDescriptionColumnCapture) {
+    DBColumnInfo column = alertDefinitionDescriptionColumnCapture.getValue();
+    Assert.assertEquals(null, column.getDefaultValue());
+    Assert.assertEquals(char[].class, column.getType());
+    Assert.assertEquals("description", column.getName());
+  }
+
   /**
    * Verifies alert_target_states table.
    *

+ 6 - 0
ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HDFS/alerts.json

@@ -6,6 +6,7 @@
       {
         "name": "namenode_cpu",
         "label": "NameNode Host CPU Utilization",
+        "description": "A description of namenode_cpu",
         "interval": 2,
         "scope": "ANY",
         "enabled": true,
@@ -42,6 +43,7 @@
       {
         "name": "namenode_process",
         "label": "NameNode process",
+        "description": "A description of namenode_process",
         "interval": 1,
         "scope": "ANY",
         "source": {
@@ -61,6 +63,7 @@
       {
         "name": "hdfs_last_checkpoint",
         "label": "Last Checkpoint Time",
+        "description": "A description of hdfs_last_checkpoint",
         "interval": 1,
         "scope": "SERVICE",
         "enabled": false,
@@ -72,6 +75,7 @@
       {
         "name": "hdfs_ignore_host_test",
         "label": "Ignore Host Test",
+        "description": "A description of hdfs_ignore_host_test",
         "interval": 1,
         "scope": "SERVICE",
         "enabled": true,
@@ -86,6 +90,7 @@
       {
         "name": "secondary_namenode_process",
         "label": "Secondary NameNode process",
+        "description": "A description of secondary_namenode_process",
         "interval": 1,
         "scope": "ANY",
         "source": {
@@ -99,6 +104,7 @@
       {
         "name": "datanode_storage",
         "label": "DataNode Storage",
+        "description": "A description of datanode_storage",
         "interval": 2,
         "scope": "HOST",
         "enabled": true,