You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jo...@apache.org on 2015/03/31 14:18:10 UTC

ambari git commit: AMBARI-10285 - Storm Shows An Alert for REST_API Component After Stack Upgrade (jonathanhurley)

Repository: ambari
Updated Branches:
  refs/heads/trunk 4541b382a -> cf094a7e5


AMBARI-10285 - Storm Shows An Alert for REST_API Component After Stack Upgrade (jonathanhurley)


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

Branch: refs/heads/trunk
Commit: cf094a7e5f5dfc88c5496aa504ca895a01cb58b3
Parents: 4541b38
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Mon Mar 30 16:54:08 2015 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Tue Mar 31 08:18:02 2015 -0400

----------------------------------------------------------------------
 .../server/api/services/AmbariMetaInfo.java     | 64 +++++++++++++++++++-
 .../server/orm/dao/AlertDefinitionDAO.java      | 16 +++++
 .../orm/entities/AlertDefinitionEntity.java     |  1 +
 .../server/api/services/AmbariMetaInfoTest.java | 48 +++++++++++++--
 .../apache/ambari/server/orm/OrmTestHelper.java | 12 +++-
 .../server/orm/dao/AlertDefinitionDAOTest.java  | 21 +++++++
 6 files changed, 154 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/cf094a7e/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
index 143022e..0cb8fa4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
@@ -40,8 +40,11 @@ import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.ParentObjectNotFoundException;
 import org.apache.ambari.server.StackAccessException;
 import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.controller.RootServiceResponseFactory.Components;
+import org.apache.ambari.server.controller.RootServiceResponseFactory.Services;
 import org.apache.ambari.server.customactions.ActionDefinition;
 import org.apache.ambari.server.customactions.ActionDefinitionManager;
+import org.apache.ambari.server.events.AlertDefinitionDisabledEvent;
 import org.apache.ambari.server.events.AlertDefinitionRegistrationEvent;
 import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
 import org.apache.ambari.server.metadata.ActionMetadata;
@@ -176,6 +179,8 @@ public class AmbariMetaInfo {
    * <ul>
    * <li>{@link AlertDefinitionRegistrationEvent} when new alerts are merged
    * from the stack</li>
+   * <li>{@link AlertDefinitionDisabledEvent} when existing definitions are
+   * disabled after being removed from the current stack</li>
    * </ul>
    */
   @Inject
@@ -965,11 +970,17 @@ public class AmbariMetaInfo {
       StackInfo stackInfo = getStack(stackId.getStackName(),
           stackId.getStackVersion());
 
-      // creating a mapping between service name and service for fast lookups
+      // creating a mapping between names and service/component for fast lookups
       Collection<ServiceInfo> stackServices = stackInfo.getServices();
       Map<String, ServiceInfo> stackServiceMap = new HashMap<String, ServiceInfo>();
+      Map<String, ComponentInfo> stackComponentMap = new HashMap<String, ComponentInfo>();
       for (ServiceInfo stackService : stackServices) {
         stackServiceMap.put(stackService.getName(), stackService);
+
+        List<ComponentInfo> components = stackService.getComponents();
+        for (ComponentInfo component : components) {
+          stackComponentMap.put(component.getName(), component);
+        }
       }
 
       Map<String, Service> clusterServiceMap = cluster.getServices();
@@ -984,6 +995,7 @@ public class AmbariMetaInfo {
           continue;
         }
 
+
         // get all alerts defined on the stack for each cluster service
         Set<AlertDefinition> serviceDefinitions = getAlertDefinitions(stackService);
         stackDefinitions.addAll(serviceDefinitions);
@@ -1055,6 +1067,52 @@ public class AmbariMetaInfo {
 
         eventPublisher.publish(event);
       }
+
+      // for every definition, determine if the service and the component are
+      // still valid; if they are not, disable them - this covers the case
+      // with STORM/REST_API where that component was removed from the
+      // stack but still exists in the database - we disable the alert to
+      // preserve historical references
+      List<AlertDefinitionEntity> definitions = alertDefinitionDao.findAllEnabled(clusterId);
+      List<AlertDefinitionEntity> definitionsToDisable = new ArrayList<AlertDefinitionEntity>();
+
+      for (AlertDefinitionEntity definition : definitions) {
+        String serviceName = definition.getServiceName();
+        String componentName = definition.getComponentName();
+
+        // the AMBARI service is special, skip it here
+        if (Services.AMBARI.name().equals(serviceName)
+            && Components.AMBARI_AGENT.name().equals(componentName)) {
+          continue;
+        }
+
+        if (!stackServiceMap.containsKey(serviceName)) {
+          LOG.info(
+              "The {} service has been marked as deleted for stack {}, disabling alert {}",
+              serviceName, stackId, definition.getDefinitionName());
+
+          definitionsToDisable.add(definition);
+        } else if (null != componentName
+            && !stackComponentMap.containsKey(componentName)) {
+          LOG.info(
+              "The {} component {} has been marked as deleted for stack {}, disabling alert {}",
+              serviceName, componentName, stackId,
+              definition.getDefinitionName());
+
+          definitionsToDisable.add(definition);
+        }
+      }
+
+      // disable definitions and fire the event
+      for (AlertDefinitionEntity definition : definitionsToDisable) {
+        definition.setEnabled(false);
+        alertDefinitionDao.merge(definition);
+
+        AlertDefinitionDisabledEvent event = new AlertDefinitionDisabledEvent(
+            clusterId, definition.getDefinitionId());
+
+        eventPublisher.publish(event);
+      }
     }
   }
 
@@ -1107,10 +1165,10 @@ public class AmbariMetaInfo {
           throw new AmbariException(String.format("Failed to parse kerberos descriptor file %s",
               file.getAbsolutePath()), e);
         }
-      }
-      else
+      } else {
         throw new AmbariException(String.format("Unable to read kerberos descriptor file %s",
             file.getAbsolutePath()));
+      }
     }
 
     if (kerberosDescriptor == null) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/cf094a7e/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
index 659fb21..d838d25 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
@@ -159,6 +159,22 @@ public class AlertDefinitionDAO {
   }
 
   /**
+   * Gets all enabled alert definitions stored in the database for the specified
+   * cluster.
+   *
+   * @return all enabled alert definitions or empty list if none exist (never
+   *         {@code null}).
+   */
+  public List<AlertDefinitionEntity> findAllEnabled(long clusterId) {
+    TypedQuery<AlertDefinitionEntity> query = entityManagerProvider.get().createNamedQuery(
+        "AlertDefinitionEntity.findAllEnabledInCluster",
+        AlertDefinitionEntity.class);
+
+    query.setParameter("clusterId", clusterId);
+    return daoUtils.selectList(query);
+  }
+
+  /**
    * Gets all of the alert definitions for the list of IDs given.
    *
    * @param definitionIds

http://git-wip-us.apache.org/repos/asf/ambari/blob/cf094a7e/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
index cd06e23..6838983 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
@@ -59,6 +59,7 @@ import org.apache.ambari.server.state.alert.SourceType;
 @NamedQueries({
     @NamedQuery(name = "AlertDefinitionEntity.findAll", query = "SELECT ad FROM AlertDefinitionEntity ad"),
     @NamedQuery(name = "AlertDefinitionEntity.findAllInCluster", query = "SELECT ad FROM AlertDefinitionEntity ad WHERE ad.clusterId = :clusterId"),
+    @NamedQuery(name = "AlertDefinitionEntity.findAllEnabledInCluster", query = "SELECT ad FROM AlertDefinitionEntity ad WHERE ad.clusterId = :clusterId AND ad.enabled = 1"),
     @NamedQuery(name = "AlertDefinitionEntity.findByName", query = "SELECT ad FROM AlertDefinitionEntity ad WHERE ad.definitionName = :definitionName AND ad.clusterId = :clusterId"),
     @NamedQuery(name = "AlertDefinitionEntity.findByService", query = "SELECT ad FROM AlertDefinitionEntity ad WHERE ad.serviceName = :serviceName AND ad.clusterId = :clusterId"),
     @NamedQuery(name = "AlertDefinitionEntity.findByServiceAndComponent", query = "SELECT ad FROM AlertDefinitionEntity ad WHERE ad.serviceName = :serviceName AND ad.componentName = :componentName AND ad.clusterId = :clusterId"),

http://git-wip-us.apache.org/repos/asf/ambari/blob/cf094a7e/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
index 96e7ff2..051cf54 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
@@ -38,6 +38,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.UUID;
 
 import javax.persistence.EntityManager;
 
@@ -76,6 +77,7 @@ import org.apache.ambari.server.state.alert.MetricSource;
 import org.apache.ambari.server.state.alert.PortSource;
 import org.apache.ambari.server.state.alert.Reporting;
 import org.apache.ambari.server.state.alert.Source;
+import org.apache.ambari.server.state.alert.SourceType;
 import org.apache.ambari.server.state.kerberos.KerberosDescriptor;
 import org.apache.ambari.server.state.kerberos.KerberosDescriptorFactory;
 import org.apache.ambari.server.state.kerberos.KerberosServiceDescriptorFactory;
@@ -101,7 +103,6 @@ import com.google.inject.util.Modules;
 public class AmbariMetaInfoTest {
 
   private static final String STACK_NAME_HDP = "HDP";
-  private static final String STACK_NAME_XYZ = "XYZ";
   private static final String STACK_VERSION_HDP = "0.1";
   private static final String EXT_STACK_NAME = "2.0.6";
   private static final String STACK_VERSION_HDP_02 = "0.2";
@@ -1705,7 +1706,8 @@ public class AmbariMetaInfoTest {
 
     injector.getInstance(GuiceJpaInitializer.class);
     injector.getInstance(EntityManager.class);
-    injector.getInstance(OrmTestHelper.class).createCluster();
+    long clusterId = injector.getInstance(OrmTestHelper.class).createCluster(
+        "cluster" + System.currentTimeMillis());
 
     metaInfo.alertDefinitionDao = injector.getInstance(AlertDefinitionDAO.class);
     Class<?> c = metaInfo.getClass().getSuperclass();
@@ -1714,7 +1716,7 @@ public class AmbariMetaInfoTest {
     f.set(metaInfo, injector.getInstance(AgentAlertDefinitions.class));
 
     Clusters clusters = injector.getInstance(Clusters.class);
-    Cluster cluster = clusters.getClusterById(1);
+    Cluster cluster = clusters.getClusterById(clusterId);
     cluster.setDesiredStackVersion(
         new StackId(STACK_NAME_HDP, "2.0.6"));
 
@@ -1723,7 +1725,7 @@ public class AmbariMetaInfoTest {
     metaInfo.reconcileAlertDefinitions(clusters);
 
     AlertDefinitionDAO dao = injector.getInstance(AlertDefinitionDAO.class);
-    List<AlertDefinitionEntity> definitions = dao.findAll();
+    List<AlertDefinitionEntity> definitions = dao.findAll(clusterId);
     assertEquals(7, definitions.size());
 
     // figure out how many of these alerts were merged into from the
@@ -1752,6 +1754,44 @@ public class AmbariMetaInfoTest {
     for (AlertDefinitionEntity definition : definitions) {
       assertEquals(28, definition.getScheduleInterval().intValue());
     }
+
+    // find all enabled for the cluster should find 6 (the ones from HDFS;
+    // it will not find the agent alert since it's not bound to the cluster)
+    definitions = dao.findAllEnabled(cluster.getClusterId());
+    assertEquals(6, definitions.size());
+
+    // create new definition
+    AlertDefinitionEntity entity = new AlertDefinitionEntity();
+    entity.setClusterId(clusterId);
+    entity.setDefinitionName("bad_hdfs_alert");
+    entity.setLabel("Bad HDFS Alert");
+    entity.setDescription("A way to fake a component being removed");
+    entity.setEnabled(true);
+    entity.setHash(UUID.randomUUID().toString());
+    entity.setScheduleInterval(1);
+    entity.setServiceName("HDFS");
+    entity.setComponentName("BAD_COMPONENT");
+    entity.setSourceType(SourceType.METRIC);
+    entity.setSource("{\"type\" : \"METRIC\"}");
+    dao.create(entity);
+
+    // verify the new definition is found (6 HDFS + 1 new one)
+    definitions = dao.findAllEnabled(cluster.getClusterId());
+    assertEquals(7, definitions.size());
+
+    // reconcile, which should disable our bad definition
+    metaInfo.reconcileAlertDefinitions(clusters);
+
+    // find all enabled for the cluster should find 6
+    definitions = dao.findAllEnabled(cluster.getClusterId());
+    assertEquals(6, definitions.size());
+
+    // find all should find 6 HDFS + 1 disabled + 1 agent alert
+    definitions = dao.findAll();
+    assertEquals(8, definitions.size());
+
+    entity = dao.findById(entity.getDefinitionId());
+    assertFalse(entity.getEnabled());
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/ambari/blob/cf094a7e/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java
index b9fc424..6041066 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java
@@ -296,6 +296,16 @@ public class OrmTestHelper {
    */
   @Transactional
   public Long createCluster() {
+    return createCluster("test_cluster1");
+  }
+
+  /**
+   * Creates an empty cluster with an ID using the specified cluster name.
+   *
+   * @return the cluster ID.
+   */
+  @Transactional
+  public Long createCluster(String clusterName) {
     ResourceTypeDAO resourceTypeDAO = injector.getInstance(ResourceTypeDAO.class);
 
     ResourceTypeEntity resourceTypeEntity =  new ResourceTypeEntity();
@@ -309,7 +319,7 @@ public class OrmTestHelper {
     ClusterDAO clusterDAO = injector.getInstance(ClusterDAO.class);
 
     ClusterEntity clusterEntity = new ClusterEntity();
-    clusterEntity.setClusterName("test_cluster1");
+    clusterEntity.setClusterName(clusterName);
     clusterEntity.setClusterInfo("test_cluster_info1");
     clusterEntity.setResource(resourceEntity);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/cf094a7e/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
index acf25d2..2e0f238 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
@@ -185,6 +185,27 @@ public class AlertDefinitionDAOTest {
   }
 
   /**
+  *
+  */
+  @Test
+  public void testFindAllEnabled() {
+    List<AlertDefinitionEntity> definitions = dao.findAll();
+    assertNotNull(definitions);
+    assertEquals(15, definitions.size());
+
+    List<AlertDefinitionEntity> enabledDefinitions = dao.findAllEnabled(clusterId);
+    assertNotNull(enabledDefinitions);
+    assertEquals(definitions.size(), enabledDefinitions.size());
+
+    enabledDefinitions.get(0).setEnabled(false);
+    dao.merge(enabledDefinitions.get(0));
+
+    enabledDefinitions = dao.findAllEnabled(clusterId);
+    assertNotNull(enabledDefinitions);
+    assertEquals(definitions.size() - 1, enabledDefinitions.size());
+  }
+
+  /**
    *
    */
   @Test