ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jonathanhur...@apache.org
Subject git commit: AMBARI-8035 - Alerts: Creating WEB Alert Definitions via REST API Drops URI (jonathanhurley)
Date Thu, 30 Oct 2014 12:22:15 GMT
Repository: ambari
Updated Branches:
  refs/heads/trunk 6e4c89bb0 -> f65a5af6c


AMBARI-8035 - Alerts: Creating WEB Alert Definitions via REST API Drops URI (jonathanhurley)


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

Branch: refs/heads/trunk
Commit: f65a5af6c62c14c8442e7c3c6a88e07ac2a4a76e
Parents: 6e4c89b
Author: Jonathan Hurley <jhurley@hortonworks.com>
Authored: Wed Oct 29 23:25:53 2014 -0400
Committer: Jonathan Hurley <jhurley@hortonworks.com>
Committed: Thu Oct 30 08:22:06 2014 -0400

----------------------------------------------------------------------
 .../python/ambari_agent/alerts/metric_alert.py  |   8 +-
 .../python/ambari_agent/alerts/web_alert.py     |   5 +-
 .../AlertDefinitionResourceProvider.java        | 149 +++++++++++++------
 .../AlertDefinitionResourceProviderTest.java    | 115 ++++++++++----
 4 files changed, 200 insertions(+), 77 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/f65a5af6/ambari-agent/src/main/python/ambari_agent/alerts/metric_alert.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/alerts/metric_alert.py b/ambari-agent/src/main/python/ambari_agent/alerts/metric_alert.py
index e569bca..f43ad53 100644
--- a/ambari-agent/src/main/python/ambari_agent/alerts/metric_alert.py
+++ b/ambari-agent/src/main/python/ambari_agent/alerts/metric_alert.py
@@ -39,8 +39,12 @@ class MetricAlert(BaseAlert):
       self.metric_info = JmxMetric(alert_source_meta['jmx'])
 
     # extract any lookup keys from the URI structure
-    self.uri_property_keys = self._lookup_uri_property_keys(alert_source_meta['uri'])
-      
+    self.uri_property_keys = None
+    if 'uri' in alert_source_meta:
+      uri = alert_source_meta['uri']
+      self.uri_property_keys = self._lookup_uri_property_keys(uri)
+
+
   def _collect(self):
     if self.metric_info is None:
       raise Exception("Could not determine result. Specific metric collector is not defined.")

http://git-wip-us.apache.org/repos/asf/ambari/blob/f65a5af6/ambari-agent/src/main/python/ambari_agent/alerts/web_alert.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/alerts/web_alert.py b/ambari-agent/src/main/python/ambari_agent/alerts/web_alert.py
index 03f2566..c967c8e 100644
--- a/ambari-agent/src/main/python/ambari_agent/alerts/web_alert.py
+++ b/ambari-agent/src/main/python/ambari_agent/alerts/web_alert.py
@@ -33,7 +33,10 @@ class WebAlert(BaseAlert):
     super(WebAlert, self).__init__(alert_meta, alert_source_meta)
     
     # extract any lookup keys from the URI structure
-    self.uri_property_keys = self._lookup_uri_property_keys(alert_source_meta['uri'])
+    self.uri_property_keys = None
+    if 'uri' in alert_source_meta:
+      uri = alert_source_meta['uri']
+      self.uri_property_keys = self._lookup_uri_property_keys(uri)
 
       
   def _collect(self):

http://git-wip-us.apache.org/repos/asf/ambari/blob/f65a5af6/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java
index e1c0082..86e7b7e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java
@@ -19,6 +19,7 @@ package org.apache.ambari.server.controller.internal;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -54,6 +55,7 @@ import org.apache.ambari.server.state.alert.SourceType;
 import org.apache.commons.lang.StringUtils;
 
 import com.google.gson.Gson;
+import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
 import com.google.inject.Inject;
 import com.google.inject.Injector;
@@ -77,10 +79,6 @@ public class AlertDefinitionResourceProvider extends AbstractControllerResourceP
 
   protected static final String ALERT_DEF_SOURCE = "AlertDefinition/source";
   protected static final String ALERT_DEF_SOURCE_TYPE = "AlertDefinition/source/type";
-  protected static final String ALERT_DEF_SOURCE_REPORTING = "AlertDefinition/source/reporting";
-  protected static final String ALERT_DEF_SOURCE_REPORTING_OK = "AlertDefinition/source/reporting/ok";
-  protected static final String ALERT_DEF_SOURCE_REPORTING_WARNING = "AlertDefinition/source/reporting/warning";
-  protected static final String ALERT_DEF_SOURCE_REPORTING_CRITICAL = "AlertDefinition/source/reporting/critical";
 
   protected static final String ALERT_DEF_ACTION_RUN_NOW = "AlertDefinition/run_now";
 
@@ -429,67 +427,51 @@ public class AlertDefinitionResourceProvider extends AbstractControllerResourceP
       throw new IllegalArgumentException("Service name must be specified");
     }
 
+    // on creation, source type is required
     if (bCreate && null == sourceType) {
       throw new IllegalArgumentException(String.format(
           "Source type must be specified and one of %s",
           EnumSet.allOf(SourceType.class)));
     }
 
-    // !!! Alert structures contain nested objects; reconstruct a valid
-    // JSON from the flat, exploded properties so that a Source instance can
-    // be properly persisted
-    JsonObject source = new JsonObject();
-    JsonObject reporting = new JsonObject();
-    JsonObject reportingOk = new JsonObject();
-    JsonObject reportingWarning = new JsonObject();
-    JsonObject reportingCritical = new JsonObject();
+    // !!! The AlertDefinition "Source" field is a nested JSON object;
+    // build a JSON representation from the flat properties and then
+    // serialize that JSON object as a string
+    Map<String,JsonObject> jsonObjectMapping = new HashMap<String, JsonObject>();
 
+    // for every property in the request, if it's a source property, then
+    // add it to the JSON model
     for (Entry<String, Object> entry : requestMap.entrySet()) {
-      String propCat = PropertyHelper.getPropertyCategory(entry.getKey());
-      String propName = PropertyHelper.getPropertyName(entry.getKey());
+      String propertyKey = entry.getKey();
 
-      if (propCat.equals(ALERT_DEF) && "source".equals(propName)) {
-        source.addProperty(propName, entry.getValue().toString());
+      // only handle "source" subproperties
+      if (!propertyKey.startsWith(ALERT_DEF_SOURCE)) {
+        continue;
       }
 
-      if (propCat.equals(ALERT_DEF_SOURCE)) {
-        source.addProperty(propName, entry.getValue().toString());
-      }
+      // gets a JSON object to add the property to; this will create the
+      // property and all of its parent properties recursively if necessary
+      JsonObject jsonObject = getJsonObjectMapping(ALERT_DEF_SOURCE,
+          jsonObjectMapping, propertyKey);
 
-      if (propCat.equals(ALERT_DEF_SOURCE_REPORTING)) {
-        reporting.addProperty(propName, entry.getValue().toString());
-      }
+      String propertyName = PropertyHelper.getPropertyName(propertyKey);
+      Object entryValue = entry.getValue();
 
-      if (propCat.equals(ALERT_DEF_SOURCE_REPORTING_OK)) {
-        reportingOk.addProperty(propName, entry.getValue().toString());
-      }
-
-      if (propCat.equals(ALERT_DEF_SOURCE_REPORTING_WARNING)) {
-        reportingWarning.addProperty(propName, entry.getValue().toString());
-      }
-
-      if (propCat.equals(ALERT_DEF_SOURCE_REPORTING_CRITICAL)) {
-        reportingCritical.addProperty(propName, entry.getValue().toString());
+      if( entryValue instanceof Collection<?> ){
+        JsonElement jsonElement = gson.toJsonTree(entryValue);
+        jsonObject.add(propertyName, jsonElement);
+      } else {
+        if (entryValue instanceof Number) {
+          jsonObject.addProperty(propertyName, (Number) entryValue);
+        } else {
+          jsonObject.addProperty(propertyName, entryValue.toString());
+        }
       }
     }
 
-    if (reportingOk.entrySet().size() > 0) {
-      reporting.add("ok", reportingOk);
-    }
-
-    if (reportingWarning.entrySet().size() > 0) {
-      reporting.add("warning", reportingWarning);
-    }
-
-    if (reportingCritical.entrySet().size() > 0) {
-      reporting.add("critical", reportingCritical);
-    }
-
-    if (reporting.entrySet().size() > 0) {
-      source.add("reporting", reporting);
-    }
-
-    if (bCreate && 0 == source.entrySet().size()) {
+    // "source" must be filled in when creating
+    JsonObject source = jsonObjectMapping.get(ALERT_DEF_SOURCE);
+    if (bCreate && (null == source || 0 == source.entrySet().size())) {
       throw new IllegalArgumentException("Source must be specified");
     }
 
@@ -540,6 +522,75 @@ public class AlertDefinitionResourceProvider extends AbstractControllerResourceP
     entity.setHash(UUID.randomUUID().toString());
   }
 
+  /**
+   * Gets a {@link JsonObject} that the specified flattened property should be
+   * set on, creating all parent {@link JsonObject} instances as needed. This
+   * will turn {code AlertDefinition/source/reporting/critical/text} into
+   *
+   * <pre>
+   * AlertDefinition/source: {
+   *   reporting: {
+   *     critical: {
+   *       text
+   *     }
+   *   }
+   * }
+   * </pre>
+   *
+   * Where the the following {@link JsonObject} instances are created:
+   *
+   * <pre>
+   * AlertDefinition/source
+   *   Reporting
+   *     Critical
+   *       property 'text',
+   *       property 'value',
+   *       etc
+   * </pre>
+   *
+   * @param root
+   *          the flattened property which will be considered the root.
+   * @param jsonObjectMapping
+   *          a mapping of flattened property to {@link JsonObject}.
+   * @param propertyKey
+   *          the key to get the {@link JsonObject} for.
+   * @return the {@link JsonObject} that cooresponds to the specified key.
+   */
+  private JsonObject getJsonObjectMapping(String root,
+      Map<String, JsonObject> jsonObjectMapping, String propertyKey) {
+
+    // if there is already a mapping for the key, return the mapping
+    if (jsonObjectMapping.containsKey(propertyKey)) {
+      return jsonObjectMapping.get(propertyKey);
+    }
+
+    if (root.equals(propertyKey)) {
+      JsonObject jsonRoot = jsonObjectMapping.get(root);
+      if (null == jsonRoot) {
+        jsonRoot = new JsonObject();
+        jsonObjectMapping.put(root, jsonRoot);
+      }
+
+      return jsonRoot;
+    }
+
+    String propertyCategory = PropertyHelper.getPropertyCategory(propertyKey);
+    JsonObject categoryJson = jsonObjectMapping.get(propertyCategory);
+
+    if (null == categoryJson) {
+      JsonObject parent = getJsonObjectMapping(root, jsonObjectMapping,
+          propertyCategory);
+
+      categoryJson = new JsonObject();
+      jsonObjectMapping.put(propertyCategory, categoryJson);
+
+      String categoryName = PropertyHelper.getPropertyName(propertyCategory);
+      parent.add(categoryName, categoryJson);
+    }
+
+    return categoryJson;
+  }
+
   private Resource toResource(boolean isCollection, String clusterName,
       AlertDefinitionEntity entity, Set<String> requestedIds) {
     Resource resource = new ResourceImpl(Resource.Type.AlertDefinition);

http://git-wip-us.apache.org/repos/asf/ambari/blob/f65a5af6/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProviderTest.java
b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProviderTest.java
index a82e8c4..7823994 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProviderTest.java
@@ -55,6 +55,7 @@ import org.apache.ambari.server.state.Clusters;
 import org.apache.ambari.server.state.alert.AlertDefinition;
 import org.apache.ambari.server.state.alert.AlertDefinitionFactory;
 import org.apache.ambari.server.state.alert.AlertDefinitionHash;
+import org.apache.ambari.server.state.alert.MetricSource;
 import org.apache.ambari.server.state.alert.Scope;
 import org.apache.ambari.server.state.alert.Source;
 import org.apache.ambari.server.state.alert.SourceType;
@@ -193,7 +194,7 @@ public class AlertDefinitionResourceProviderTest {
 
     Source source = getMockSource();
     String okJson = source.getReporting().getOk().getText();
-    Object reporting = r.getPropertyValue(AlertDefinitionResourceProvider.ALERT_DEF_SOURCE_REPORTING);
+    Object reporting = r.getPropertyValue("AlertDefinition/source/reporting");
 
     Assert.assertTrue(reporting.toString().contains(okJson));
 
@@ -242,7 +243,7 @@ public class AlertDefinitionResourceProviderTest {
     Assert.assertEquals("my_def",
         resource.getPropertyValue(AlertDefinitionResourceProvider.ALERT_DEF_NAME));
 
-    Map<String, String> reporting = (Map<String, String>) resource.getPropertyValue(AlertDefinitionResourceProvider.ALERT_DEF_SOURCE_REPORTING);
+    Map<String, String> reporting = (Map<String, String>) resource.getPropertyValue("AlertDefinition/source/reporting");
 
     Assert.assertTrue(reporting.containsKey("ok"));
     Assert.assertTrue(reporting.containsKey("critical"));
@@ -263,7 +264,8 @@ public class AlertDefinitionResourceProviderTest {
         "my_def",
         resource.getPropertyValue(AlertDefinitionResourceProvider.ALERT_DEF_NAME));
 
-    reporting = (Map<String, String>) resource.getPropertyValue(AlertDefinitionResourceProvider.ALERT_DEF_SOURCE_REPORTING);
+    reporting = (Map<String, String>) resource.getPropertyValue("AlertDefinition/source/reporting");
+
     Assert.assertNull(reporting);
   }
 
@@ -291,8 +293,7 @@ public class AlertDefinitionResourceProviderTest {
     replay(amc, clusters, cluster, dao, definitionHash);
 
     Gson gson = m_factory.getGson();
-    Source source = getMockSource();
-    String sourceJson = gson.toJson(source);
+    MetricSource source = (MetricSource)getMockSource();
     AlertDefinitionResourceProvider provider = createProvider(amc);
 
     Map<String, Object> requestProps = new HashMap<String, Object>();
@@ -303,17 +304,42 @@ public class AlertDefinitionResourceProviderTest {
     requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_SERVICE_NAME,
         "HDFS");
 
-    requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_SOURCE,
-        sourceJson);
+    requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_LABEL,
+        "Mock Label (Create)");
 
     requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_SOURCE_TYPE,
         SourceType.METRIC.name());
 
-    requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_LABEL,
-        "Mock Label (Create)");
+    // JMX
+    requestProps.put("AlertDefinition/source/jmx/value",
+        source.getJmxInfo().getValue());
+    requestProps.put("AlertDefinition/source/jmx/property_list",
+        source.getJmxInfo().getPropertyList());
+
+    // URI
+    requestProps.put("AlertDefinition/source/uri/http",
+        source.getUri().getHttpUri());
+    requestProps.put("AlertDefinition/source/uri/https",
+        source.getUri().getHttpsUri());
+    requestProps.put("AlertDefinition/source/uri/https_property",
+        source.getUri().getHttpsProperty());
+    requestProps.put("AlertDefinition/source/uri/https_property_value",
+        source.getUri().getHttpsPropertyValue());
+
+    // reporting
+    requestProps.put("AlertDefinition/source/reporting/critical/text",
+        source.getReporting().getCritical().getText());
+    requestProps.put("AlertDefinition/source/reporting/critical/value",
+        source.getReporting().getCritical().getValue());
+    requestProps.put("AlertDefinition/source/reporting/ok/text",
+        source.getReporting().getOk().getText());
+    requestProps.put("AlertDefinition/source/reporting/warning/text",
+        source.getReporting().getWarning().getText());
+    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);
     provider.createResources(request);
 
     Assert.assertTrue(entityCapture.hasCaptured());
@@ -333,20 +359,30 @@ public class AlertDefinitionResourceProviderTest {
 
     // verify Source
     Assert.assertNotNull(entity.getSource());
-    Source actualSource = gson.fromJson(entity.getSource(), Source.class);
+    MetricSource actualSource = gson.fromJson(entity.getSource(),
+        MetricSource.class);
+
     Assert.assertNotNull(actualSource);
 
     assertEquals(source.getReporting().getOk().getText(),
-        source.getReporting().getOk().getText());
+        actualSource.getReporting().getOk().getText());
 
     assertEquals(source.getReporting().getWarning().getText(),
-        source.getReporting().getWarning().getText());
+        actualSource.getReporting().getWarning().getText());
 
     assertEquals(source.getReporting().getCritical().getText(),
-        source.getReporting().getCritical().getText());
+        actualSource.getReporting().getCritical().getText());
 
-    verify(amc, clusters, cluster, dao);
+    Assert.assertNotNull(source.getUri().getHttpUri());
+    Assert.assertNotNull(source.getUri().getHttpsUri());
+
+    assertEquals(source.getUri().getHttpUri(),
+        actualSource.getUri().getHttpUri());
+
+    assertEquals(source.getUri().getHttpsUri(),
+        actualSource.getUri().getHttpsUri());
 
+    verify(amc, clusters, cluster, dao);
   }
 
   /**
@@ -354,8 +390,6 @@ public class AlertDefinitionResourceProviderTest {
    */
   @Test
   public void testUpdateResources() throws Exception {
-    Gson gson = m_factory.getGson();
-
     AmbariManagementController amc = createMock(AmbariManagementController.class);
     Clusters clusters = createMock(Clusters.class);
     Cluster cluster = createMock(Cluster.class);
@@ -376,8 +410,7 @@ public class AlertDefinitionResourceProviderTest {
 
     replay(amc, clusters, cluster, dao, definitionHash);
 
-    Source source = getMockSource();
-    String sourceString = gson.toJson(source);
+    MetricSource source = (MetricSource) getMockSource();
 
     Map<String, Object> requestProps = new HashMap<String, Object>();
     requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_CLUSTER_NAME, "c1");
@@ -387,12 +420,37 @@ public class AlertDefinitionResourceProviderTest {
     requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_SERVICE_NAME, "HDFS");
     requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_SOURCE_TYPE, "METRIC");
 
-    requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_SOURCE,
-        sourceString);
-
     requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_ENABLED,
         Boolean.TRUE.toString());
 
+    // JMX
+    requestProps.put("AlertDefinition/source/jmx/value",
+        source.getJmxInfo().getValue());
+    requestProps.put("AlertDefinition/source/jmx/property_list",
+        source.getJmxInfo().getPropertyList());
+
+    // URI
+    requestProps.put("AlertDefinition/source/uri/http",
+        source.getUri().getHttpUri());
+    requestProps.put("AlertDefinition/source/uri/https",
+        source.getUri().getHttpsUri());
+    requestProps.put("AlertDefinition/source/uri/https_property",
+        source.getUri().getHttpsProperty());
+    requestProps.put("AlertDefinition/source/uri/https_property_value",
+        source.getUri().getHttpsPropertyValue());
+
+    // reporting
+    requestProps.put("AlertDefinition/source/reporting/critical/text",
+        source.getReporting().getCritical().getText());
+    requestProps.put("AlertDefinition/source/reporting/critical/value",
+        source.getReporting().getCritical().getValue());
+    requestProps.put("AlertDefinition/source/reporting/ok/text",
+        source.getReporting().getOk().getText());
+    requestProps.put("AlertDefinition/source/reporting/warning/text",
+        source.getReporting().getWarning().getText());
+    requestProps.put("AlertDefinition/source/reporting/warning/value",
+        source.getReporting().getWarning().getValue());
+
     Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps),
null);
 
     AlertDefinitionResourceProvider provider = createProvider(amc);
@@ -430,8 +488,15 @@ public class AlertDefinitionResourceProviderTest {
     requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_SERVICE_NAME, "HDFS");
     requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_SOURCE_TYPE, "METRIC");
 
-    requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_SOURCE,
-        sourceString.replaceAll("CPU", "CPU2"));
+    // new URI
+    requestProps.put("AlertDefinition/source/uri/http",
+        source.getUri().getHttpUri() + "_foobarbaz");
+    requestProps.put("AlertDefinition/source/uri/https",
+        source.getUri().getHttpsUri() + "_foobarbaz");
+    requestProps.put("AlertDefinition/source/uri/https_property",
+        source.getUri().getHttpsProperty() + "_foobarbaz");
+    requestProps.put("AlertDefinition/source/uri/https_property_value",
+        source.getUri().getHttpsPropertyValue() + "_foobarbaz");
 
     requestProps.put(AlertDefinitionResourceProvider.ALERT_DEF_ENABLED,
         Boolean.FALSE.toString());
@@ -445,7 +510,7 @@ public class AlertDefinitionResourceProviderTest {
     Assert.assertFalse(oldInterval.equals(entity.getScheduleInterval()));
     Assert.assertFalse(oldEnabled == entity.getEnabled());
     Assert.assertFalse(oldSource.equals(entity.getSource()));
-    Assert.assertTrue(entity.getSource().contains("CPU2"));
+    Assert.assertTrue(entity.getSource().contains("_foobarbaz"));
 
     verify(amc, clusters, cluster, dao);
   }


Mime
View raw message