Repository: ambari
Updated Branches:
  refs/heads/trunk d156c0ee9 -> b3430e705


AMBARI-6780 - SOURCE and SINK metrics not working on host-component


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

Branch: refs/heads/trunk
Commit: b3430e7050d90ce873485986f99ad29db2420c0d
Parents: d156c0e
Author: Jonathan Hurley <jhur...@hortonworks.com>
Authored: Thu Aug 7 16:29:43 2014 -0400
Committer: Jonathan Hurley <jhur...@hortonworks.com>
Committed: Fri Aug 8 09:57:18 2014 -0400

----------------------------------------------------------------------
 .../ServiceConfigVersionResourceDefinition.java |   9 +-
 .../internal/AbstractPropertyProvider.java      |  42 +++--
 .../controller/internal/BaseProvider.java       |  77 +++++---
 .../controller/utilities/PropertyHelper.java    | 121 +++++++++---
 .../controller/internal/BaseProviderTest.java   | 188 ++++++++++++-------
 .../utilities/PropertyHelperTest.java           |  22 +--
 6 files changed, 306 insertions(+), 153 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/b3430e70/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ServiceConfigVersionResourceDefinition.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ServiceConfigVersionResourceDefinition.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ServiceConfigVersionResourceDefinition.java
index a907166..f5d07f6 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ServiceConfigVersionResourceDefinition.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ServiceConfigVersionResourceDefinition.java
@@ -18,13 +18,12 @@
 
 package org.apache.ambari.server.api.resources;
 
+import java.util.List;
+
 import org.apache.ambari.server.api.services.Request;
 import org.apache.ambari.server.api.util.TreeNode;
 import org.apache.ambari.server.controller.spi.Resource;
 
-import java.util.Collections;
-import java.util.List;
-
 public class ServiceConfigVersionResourceDefinition extends 
BaseResourceDefinition {
   /**
    * Constructor.
@@ -68,7 +67,9 @@ public class ServiceConfigVersionResourceDefinition extends 
BaseResourceDefiniti
 
         String serviceName = (String) 
resultNode.getObject().getPropertyValue("service_name");
         Long version = (Long) 
resultNode.getObject().getPropertyValue("serviceconfigversion");
-        href = href.substring(0, idx) + 
"cenfigurations/serviceconfigversions?service_name=" + serviceName + 
"&serviceconfigversion=" + version;
+        href = href.substring(0, idx)
+            + "configurations/serviceconfigversions?service_name="
+            + serviceName + "&serviceconfigversion=" + version;
 
         resultNode.setProperty("href", href);
       } else {

http://git-wip-us.apache.org/repos/asf/ambari/blob/b3430e70/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractPropertyProvider.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractPropertyProvider.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractPropertyProvider.java
index 542567f..4a675c5 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractPropertyProvider.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractPropertyProvider.java
@@ -18,9 +18,6 @@
 
 package org.apache.ambari.server.controller.internal;
 
-import org.apache.ambari.server.controller.spi.PropertyProvider;
-import org.apache.ambari.server.controller.utilities.PropertyHelper;
-
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.HashMap;
@@ -31,6 +28,9 @@ import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.apache.ambari.server.controller.spi.PropertyProvider;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+
 /**
  *  Abstract property provider implementation.
  */
@@ -123,12 +123,13 @@ public abstract class AbstractPropertyProvider extends 
BaseProvider implements P
       return;
     }
 
-    String regExpKey = getRegExpKey(propertyId);
+    Map.Entry<String, Pattern> regexEntry = getRegexEntry(propertyId);
 
-    if (regExpKey != null) {
-      propertyInfo = componentMetricMap.get(regExpKey);
+    if (regexEntry != null) {
+      String regexKey = regexEntry.getKey();
+      propertyInfo = componentMetricMap.get(regexKey);
       if (propertyInfo != null) {
-        propertyInfoMap.put(regExpKey, propertyInfo);
+        propertyInfoMap.put(regexKey, propertyInfo);
         return;
       }
     }
@@ -144,14 +145,14 @@ public abstract class AbstractPropertyProvider extends 
BaseProvider implements P
       }
     }
 
-    if (regExpKey != null) {
-      if (!regExpKey.endsWith("/")){
-        regExpKey += "/";
-      }
+    if (regexEntry != null) {
+      // in the event that a category is being requested, the pattern must
+      // match all child properties; append \S* for this
+      String regexPattern = regexEntry.getValue().pattern();
+      regexPattern += "(\\S*)";
 
-      
       for (Map.Entry<String, PropertyInfo> entry : 
componentMetricMap.entrySet()) {
-        if (entry.getKey().startsWith(regExpKey)) {
+        if (entry.getKey().matches(regexPattern)) {
           propertyInfoMap.put(entry.getKey(), entry.getValue());
         }
       }
@@ -278,15 +279,18 @@ public abstract class AbstractPropertyProvider extends 
BaseProvider implements P
   protected void updateComponentMetricMap(
     Map<String, PropertyInfo> componentMetricMap, String propertyId) {
 
-    String regExpKey = getRegExpKey(propertyId);
-
+    String regexKey = null;
+    Map.Entry<String, Pattern> regexEntry = getRegexEntry(propertyId);
+    if (null != regexEntry) {
+      regexKey = regexEntry.getKey();
+    }
 
-    if (!componentMetricMap.containsKey(propertyId) && regExpKey != null &&
-      !regExpKey.equals(propertyId)) {
+    if (!componentMetricMap.containsKey(propertyId) && regexKey != null
+        && !regexKey.equals(propertyId)) {
 
-      PropertyInfo propertyInfo = componentMetricMap.get(regExpKey);
+      PropertyInfo propertyInfo = componentMetricMap.get(regexKey);
       if (propertyInfo != null) {
-        List<String> regexGroups = getRegexGroups(regExpKey, propertyId);
+        List<String> regexGroups = getRegexGroups(regexKey, propertyId);
         String key = propertyInfo.getPropertyId();
         for (String regexGroup : regexGroups) {
           regexGroup = regexGroup.replace("/", ".");

http://git-wip-us.apache.org/repos/asf/ambari/blob/b3430e70/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseProvider.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseProvider.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseProvider.java
index f31ed7a..b4d582a 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseProvider.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseProvider.java
@@ -18,6 +18,16 @@
 
 package org.apache.ambari.server.controller.internal;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import org.apache.ambari.server.controller.spi.Predicate;
 import org.apache.ambari.server.controller.spi.Request;
 import org.apache.ambari.server.controller.spi.Resource;
@@ -26,10 +36,6 @@ import 
org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.*;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
 /**
  * Base provider implementation for both property and resource providers.
  */
@@ -61,6 +67,19 @@ public abstract class BaseProvider {
   protected final static Logger LOG =
       LoggerFactory.getLogger(BaseProvider.class);
 
+  /**
+   * The regex pattern that will match on all $1, $2.method(0), and
+   * $3.method(\"/\",\"///\") and properly substitute. For example, it can turn
+   * <p/>
+   * {@code
+   * 
metrics/yarn/Queue/$1.replaceAll(\"([.])\",\"/\")/AppsCompleted/$2.substring(0)/foo/$3/bar/$4
+   * }
+   * <p/>
+   * into
+   * <p/>
+   * {@code metrics/yarn/Queue/-/AppsCompleted/-/foo/-/bar/-}
+   */
+  private static final Pattern METRIC_ARGUMENT_METHOD_REPLACEMENT = 
Pattern.compile("\\$\\d+(\\.\\w+(\\(\\\\\"\\S+\\\\\"\\)|\\(\\d+\\)))*");
 
   // ----- Constructors ------------------------------------------------------
 
@@ -71,13 +90,17 @@ public abstract class BaseProvider {
    */
   public BaseProvider(Set<String> propertyIds) {
     this.propertyIds = new HashSet<String>(propertyIds);
-    this.categoryIds = PropertyHelper.getCategories(propertyIds);
-    this.combinedIds = new HashSet<String>(propertyIds);
-    this.combinedIds.addAll(this.categoryIds);
-    this.patterns = new HashMap<String, Pattern>();
-    for (String id : this.combinedIds) {
+    categoryIds = PropertyHelper.getCategories(propertyIds);
+    combinedIds = new HashSet<String>(propertyIds);
+    combinedIds.addAll(categoryIds);
+    patterns = new HashMap<String, Pattern>();
+
+    // convert the argumented metric as it's defined in the JSON file to regex
+    for (String id : combinedIds) {
       if (containsArguments(id)) {
-        String pattern = id.replaceAll("\\$\\d+(\\.\\S+\\(\\S+\\))*", 
"(\\\\S+)");
+        String pattern = 
METRIC_ARGUMENT_METHOD_REPLACEMENT.matcher(id).replaceAll(
+            "(\\\\S*)");
+
         patterns.put(id, Pattern.compile(pattern));
       }
     }
@@ -93,15 +116,17 @@ public abstract class BaseProvider {
    */
   protected Set<String> checkConfigPropertyIds(Set<String> base, String 
configCategory) {
 
-    if (0 == base.size())
+    if (0 == base.size()) {
       return base;
+    }
 
     Set<String> unsupported = new HashSet<String>();
 
     for (String propertyId : base)
     {
-      if (!propertyId.startsWith(configCategory + "/desired_config"))
+      if (!propertyId.startsWith(configCategory + "/desired_config")) {
         unsupported.add(propertyId);
+      }
     }
 
     return unsupported;
@@ -110,7 +135,7 @@ public abstract class BaseProvider {
   public Set<String> checkPropertyIds(Set<String> propertyIds) {
     if (!this.propertyIds.containsAll(propertyIds)) {
       Set<String> unsupportedPropertyIds = new HashSet<String>(propertyIds);
-      unsupportedPropertyIds.removeAll(this.combinedIds);
+      unsupportedPropertyIds.removeAll(combinedIds);
 
       // If the property id is not in the set of known property ids we may 
still allow it if
       // its parent category is a known property. This allows for Map type 
properties where
@@ -150,17 +175,17 @@ public abstract class BaseProvider {
       propertyIds.addAll(PredicateHelper.getPropertyIds(predicate));
     }
 
-    if (!this.combinedIds.containsAll(propertyIds)) {
+    if (!combinedIds.containsAll(propertyIds)) {
       Set<String> keepers = new HashSet<String>();
       Set<String> unsupportedPropertyIds = new HashSet<String>(propertyIds);
-      unsupportedPropertyIds.removeAll(this.combinedIds);
+      unsupportedPropertyIds.removeAll(combinedIds);
 
       for (String unsupportedPropertyId : unsupportedPropertyIds) {
         if (checkCategory(unsupportedPropertyId) || 
checkRegExp(unsupportedPropertyId)) {
           keepers.add(unsupportedPropertyId);
         }
       }
-      propertyIds.retainAll(this.combinedIds);
+      propertyIds.retainAll(combinedIds);
       propertyIds.addAll(keepers);
     }
     return propertyIds;
@@ -173,7 +198,7 @@ public abstract class BaseProvider {
   protected boolean checkCategory(String unsupportedPropertyId) {
     String category = 
PropertyHelper.getPropertyCategory(unsupportedPropertyId);
     while (category != null) {
-      if(this.propertyIds.contains(category)) {
+      if(propertyIds.contains(category)) {
         return true;
       }
       category = PropertyHelper.getPropertyCategory(category);
@@ -191,20 +216,28 @@ public abstract class BaseProvider {
     return false;
   }
 
-  protected String getRegExpKey(String id) {
-    String regExpKey = null;
+  /**
+   * Gets the key/value mapping between a metric string in the JSON files and
+   * the Java regular expression pattern that matches it.
+   *
+   * @param id
+   * @return the entry, or {@code null} if none match the ID.
+   */
+  protected Map.Entry<String, Pattern> getRegexEntry(String id) {
+    Map.Entry<String, Pattern> regexEntry = null;
+
     for (Map.Entry<String, Pattern> entry : patterns.entrySet()) {
       Pattern pattern = entry.getValue();
       Matcher matcher = pattern.matcher(id);
 
       if (matcher.matches()) {
         String key = entry.getKey();
-        if (regExpKey == null || key.startsWith(regExpKey)) {
-          regExpKey = entry.getKey();
+        if (regexEntry == null || key.startsWith(regexEntry.getKey())) {
+          regexEntry = entry;
         }
       }
     }
-    return regExpKey;
+    return regexEntry;
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/b3430e70/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PropertyHelper.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PropertyHelper.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PropertyHelper.java
index 00efa1a..c02fdd4 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PropertyHelper.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PropertyHelper.java
@@ -17,14 +17,6 @@
  */
 package org.apache.ambari.server.controller.utilities;
 
-import org.apache.ambari.server.controller.internal.PropertyInfo;
-import org.apache.ambari.server.controller.internal.RequestImpl;
-import org.apache.ambari.server.controller.spi.Request;
-import org.apache.ambari.server.controller.spi.Resource;
-import org.apache.ambari.server.controller.spi.TemporalInfo;
-import org.codehaus.jackson.map.ObjectMapper;
-import org.codehaus.jackson.type.TypeReference;
-
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collections;
@@ -35,6 +27,14 @@ import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.apache.ambari.server.controller.internal.PropertyInfo;
+import org.apache.ambari.server.controller.internal.RequestImpl;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.TemporalInfo;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.type.TypeReference;
+
 /**
  * Utility class that provides Property helper methods.
  */
@@ -56,6 +56,26 @@ public class PropertyHelper {
    */
   private static final Pattern CHECK_FOR_METRIC_ARGUMENTS_REGEX = 
Pattern.compile(".*\\$\\d+.*");
 
+  /**
+   * This regular expression will match on every {@code /} in a given string
+   * that is not inside of quotes. The following string would be tokenized like
+   * so:
+   * <p/>
+   * {@code foo/$1.substring(5)/bar/$2.replaceAll(\"/a/b//c///\")/baz}
+   * <ul>
+   * <li>foo</li>
+   * <li>$1.substring(5)</li>
+   * <li>bar</li>
+   * <li>$2.replaceAll(\"/a/b//c///\")</li>
+   * <li>baz</li>
+   * </ul>
+   *
+   * This is necessary to be able to properly tokenize a property with {@code 
/}
+   * while also ensuring we don't match on {@code /} that appears inside of
+   * quotes.
+   */
+  private static final Pattern METRIC_CATEGORY_TOKENIZE_REGEX = 
Pattern.compile("/+(?=([^\"\\\\\\\\]*(\\\\\\\\.|\"([^\"\\\\\\\\]*\\\\\\\\.)*[^\"\\\\\\\\]*\"))*[^\"]*$)");
+
   public static String getPropertyId(String category, String name) {
     String propertyId =  (category == null || category.isEmpty())? name :
         (name == null || name.isEmpty()) ? category : category + 
EXTERNAL_PATH_SEP + name;
@@ -114,29 +134,82 @@ public class PropertyHelper {
   }
 
   /**
-   * Helper to get a property category from a string.
+   * Gets the parent category from a given property string. This method is used
+   * in many places by many different consumers. In general, it will check to
+   * see if the property contains arguments. If not, then a simple
+   * {@link String#substring(int, int)} is used along with
+   * {@link #EXTERNAL_PATH_SEP}.
+   * <p/>
+   * In the event that a property contains a $d parameter, it will attempt to
+   * strip out any embedded methods in the various tokens. For example, if a
+   * property of {@code foo/$1.substring(5)/bar/$2.substring(1)/baz} is given,
+   * the expected recursive categories would be:
+   * <ul>
+   * <li>foo</li>
+   * <li>foo/$1</li>
+   * <li>foo/$1/bar</li>
+   * <li>foo/$1/bar</li>
+   * <li>foo/$1/bar/$2</li>
+   * </ul>
    *
-   * @param absProperty  the fully qualified property
+   * {@code foo/$1.substring(5)/bar} is incorrect as a category.
+   *
+   * @param property
+   *          the fully qualified property
    *
    * @return the property category; null if there is no category
    */
-  public static String getPropertyCategory(String absProperty) {
-
-    int lastPathSep;
-    if (containsArguments(absProperty)) {
-      boolean inString = false;
-      for (lastPathSep = absProperty.length() - 1; lastPathSep > 0; 
--lastPathSep) {
-        char c = absProperty.charAt(lastPathSep);
-        if (c == '"') {
-          inString = !inString;
-        } else if (c == EXTERNAL_PATH_SEP && !inString) {
-          break;
+  public static String getPropertyCategory(String property) {
+    int lastPathSep = -1;
+
+    if( !containsArguments(property) ){
+      lastPathSep = property.lastIndexOf(EXTERNAL_PATH_SEP);
+      return lastPathSep == -1 ? null : property.substring(0, lastPathSep);
+    }
+
+    // attempt to split the property into its parts
+    String[] tokens = METRIC_CATEGORY_TOKENIZE_REGEX.split(property);
+    if (null == tokens || tokens.length == 0) {
+      return null;
+    }
+
+    StringBuilder categoryBuilder = new StringBuilder();
+    for (int i = 0; i < tokens.length - 1; i++) {
+      String token = tokens[i];
+
+      // if the token contains arguments, turn $1.method() into $1,
+      if (containsArguments(token)) {
+        int methodIndex = token.indexOf('.');
+
+        if (methodIndex != -1) {
+          // normally knowing where $1.method() is would be enough, but some
+          // properties may omit the / (like FLUME) so the property would look
+          // like /$1.method()FailureCount instead of /$1.method()/FailureCount
+          int parensIndex = token.lastIndexOf(')');
+          if (parensIndex < token.length() - 1) {
+            // cut out $1
+            String temp = token.substring(0, methodIndex);
+
+            // append FailureCount
+            temp += token.substring(parensIndex + 1);
+
+            // $1.method()FailureCount -> $1FailureCount
+            token = temp;
+          } else {
+            token = token.substring(0, methodIndex);
+          }
         }
       }
-    } else {
-      lastPathSep = absProperty.lastIndexOf(EXTERNAL_PATH_SEP);
+
+      // only append a / if this is not the last part of the parent category
+      categoryBuilder.append(token);
+      if (i < tokens.length - 2) {
+        categoryBuilder.append('/');
+      }
     }
-    return lastPathSep == -1 ? null : absProperty.substring(0, lastPathSep);
+
+    String category = categoryBuilder.toString();
+    return category;
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/b3430e70/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BaseProviderTest.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BaseProviderTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BaseProviderTest.java
index c8fcf70..fc8acd0 100644
--- 
a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BaseProviderTest.java
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BaseProviderTest.java
@@ -18,17 +18,23 @@
 
 package org.apache.ambari.server.controller.internal;
 
-import org.apache.ambari.server.controller.spi.Request;
-import org.apache.ambari.server.controller.spi.Resource;
-import org.apache.ambari.server.controller.utilities.PropertyHelper;
-import org.junit.Assert;
-import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
+import java.util.regex.Pattern;
+
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.junit.Test;
 
 /**
  * Base provider tests.
@@ -46,7 +52,7 @@ public class BaseProviderTest {
     BaseProvider provider = new TestProvider(propertyIds);
 
     Set<String> supportedPropertyIds = provider.getPropertyIds();
-    Assert.assertTrue(supportedPropertyIds.containsAll(propertyIds));
+    assertTrue(supportedPropertyIds.containsAll(propertyIds));
   }
 
   @Test
@@ -61,26 +67,28 @@ public class BaseProviderTest {
 
     BaseProvider provider = new TestProvider(propertyIds);
 
-    Assert.assertTrue(provider.checkPropertyIds(propertyIds).isEmpty());
+    assertTrue(provider.checkPropertyIds(propertyIds).isEmpty());
 
-    
Assert.assertTrue(provider.checkPropertyIds(Collections.singleton("cat1")).isEmpty());
-    
Assert.assertTrue(provider.checkPropertyIds(Collections.singleton("cat2")).isEmpty());
-    
Assert.assertTrue(provider.checkPropertyIds(Collections.singleton("cat3")).isEmpty());
-    
Assert.assertTrue(provider.checkPropertyIds(Collections.singleton("cat3/subcat3")).isEmpty());
-    
Assert.assertTrue(provider.checkPropertyIds(Collections.singleton("cat4/subcat4/map")).isEmpty());
+    
assertTrue(provider.checkPropertyIds(Collections.singleton("cat1")).isEmpty());
+    
assertTrue(provider.checkPropertyIds(Collections.singleton("cat2")).isEmpty());
+    
assertTrue(provider.checkPropertyIds(Collections.singleton("cat3")).isEmpty());
+    
assertTrue(provider.checkPropertyIds(Collections.singleton("cat3/subcat3")).isEmpty());
+    assertTrue(provider.checkPropertyIds(
+        Collections.singleton("cat4/subcat4/map")).isEmpty());
 
     // note that key is not in the set of known property ids.  We allow it if 
its parent is a known property.
     // this allows for Map type properties where we want to treat the entries 
as individual properties
-    
Assert.assertTrue(provider.checkPropertyIds(Collections.singleton("cat4/subcat4/map/key")).isEmpty());
+    assertTrue(provider.checkPropertyIds(
+        Collections.singleton("cat4/subcat4/map/key")).isEmpty());
 
     propertyIds.add("badprop");
     propertyIds.add("badcat");
 
     Set<String> unsupportedPropertyIds = 
provider.checkPropertyIds(propertyIds);
-    Assert.assertFalse(unsupportedPropertyIds.isEmpty());
-    Assert.assertEquals(2, unsupportedPropertyIds.size());
-    Assert.assertTrue(unsupportedPropertyIds.contains("badprop"));
-    Assert.assertTrue(unsupportedPropertyIds.contains("badcat"));
+    assertFalse(unsupportedPropertyIds.isEmpty());
+    assertEquals(2, unsupportedPropertyIds.size());
+    assertTrue(unsupportedPropertyIds.contains("badprop"));
+    assertTrue(unsupportedPropertyIds.contains("badcat"));
   }
 
   @Test
@@ -96,24 +104,24 @@ public class BaseProviderTest {
 
     Set<String> requestedPropertyIds = provider.getRequestPropertyIds(request, 
null);
 
-    Assert.assertEquals(1, requestedPropertyIds.size());
-    Assert.assertTrue(requestedPropertyIds.contains("foo"));
+    assertEquals(1, requestedPropertyIds.size());
+    assertTrue(requestedPropertyIds.contains("foo"));
 
     request = PropertyHelper.getReadRequest("foo", "bar");
 
     requestedPropertyIds = provider.getRequestPropertyIds(request, null);
 
-    Assert.assertEquals(2, requestedPropertyIds.size());
-    Assert.assertTrue(requestedPropertyIds.contains("foo"));
-    Assert.assertTrue(requestedPropertyIds.contains("bar"));
+    assertEquals(2, requestedPropertyIds.size());
+    assertTrue(requestedPropertyIds.contains("foo"));
+    assertTrue(requestedPropertyIds.contains("bar"));
 
     request = PropertyHelper.getReadRequest("foo", "baz", "bar", "cat", 
"cat1/prop1");
 
     requestedPropertyIds = provider.getRequestPropertyIds(request, null);
 
-    Assert.assertEquals(2, requestedPropertyIds.size());
-    Assert.assertTrue(requestedPropertyIds.contains("foo"));
-    Assert.assertTrue(requestedPropertyIds.contains("bar"));
+    assertEquals(2, requestedPropertyIds.size());
+    assertTrue(requestedPropertyIds.contains("foo"));
+    assertTrue(requestedPropertyIds.contains("bar"));
 
     // ask for a property that isn't specified as supported, but its category 
is... the property
     // should end up in the returned set for the case where the category is a 
Map property
@@ -121,9 +129,9 @@ public class BaseProviderTest {
 
     requestedPropertyIds = provider.getRequestPropertyIds(request, null);
 
-    Assert.assertEquals(2, requestedPropertyIds.size());
-    Assert.assertTrue(requestedPropertyIds.contains("foo"));
-    Assert.assertTrue(requestedPropertyIds.contains("cat1/sub1/prop1"));
+    assertEquals(2, requestedPropertyIds.size());
+    assertTrue(requestedPropertyIds.contains("foo"));
+    assertTrue(requestedPropertyIds.contains("cat1/sub1/prop1"));
   }
 
   @Test
@@ -140,26 +148,26 @@ public class BaseProviderTest {
 
     Resource resource = new ResourceImpl(Resource.Type.Service);
 
-    Assert.assertNull(resource.getPropertyValue("foo"));
+    assertNull(resource.getPropertyValue("foo"));
 
     BaseProvider.setResourceProperty(resource, "foo", "value1", propertyIds);
-    Assert.assertEquals("value1", resource.getPropertyValue("foo"));
+    assertEquals("value1", resource.getPropertyValue("foo"));
 
     BaseProvider.setResourceProperty(resource, "cat2/bar", "value2", 
propertyIds);
-    Assert.assertEquals("value2", resource.getPropertyValue("cat2/bar"));
+    assertEquals("value2", resource.getPropertyValue("cat2/bar"));
 
-    Assert.assertNull(resource.getPropertyValue("unsupported"));
+    assertNull(resource.getPropertyValue("unsupported"));
     BaseProvider.setResourceProperty(resource, "unsupported", "valueX", 
propertyIds);
-    Assert.assertNull(resource.getPropertyValue("unsupported"));
+    assertNull(resource.getPropertyValue("unsupported"));
 
     // we should allow anything under the category cat5/sub5
     BaseProvider.setResourceProperty(resource, "cat5/sub5/prop5", "value5", 
propertyIds);
-    Assert.assertEquals("value5", 
resource.getPropertyValue("cat5/sub5/prop5"));
+    assertEquals("value5", resource.getPropertyValue("cat5/sub5/prop5"));
     BaseProvider.setResourceProperty(resource, "cat5/sub5/sub5a/prop5a", 
"value5", propertyIds);
-    Assert.assertEquals("value5", 
resource.getPropertyValue("cat5/sub5/sub5a/prop5a"));
+    assertEquals("value5", 
resource.getPropertyValue("cat5/sub5/sub5a/prop5a"));
     // we shouldn't allow anything under the category cat5/sub7
     BaseProvider.setResourceProperty(resource, "cat5/sub7/unsupported", 
"valueX", propertyIds);
-    Assert.assertNull(resource.getPropertyValue("cat5/sub7/unsupported"));
+    assertNull(resource.getPropertyValue("cat5/sub7/unsupported"));
   }
 
   @Test
@@ -177,7 +185,7 @@ public class BaseProviderTest {
     // Adding an empty Map as a property should add the actual Map as a 
property
     Map<String, String> emptyMapProperty = new HashMap<String, String>();
     BaseProvider.setResourceProperty(resource, "cat1/emptyMapProperty", 
emptyMapProperty, propertyIds);
-    
Assert.assertTrue(resource.getPropertiesMap().containsKey("cat1/emptyMapProperty"));
+    
assertTrue(resource.getPropertiesMap().containsKey("cat1/emptyMapProperty"));
 
     Map<String, String> mapProperty = new HashMap<String, String>();
     mapProperty.put("key1", "value1");
@@ -187,10 +195,10 @@ public class BaseProviderTest {
     // Adding a property of type Map should add all of its keys as sub 
properties
     // if the map property was requested
     BaseProvider.setResourceProperty(resource, "cat1/mapProperty", 
mapProperty, propertyIds);
-    Assert.assertNull(resource.getPropertyValue("cat1/mapProperty"));
-    Assert.assertEquals("value1", 
resource.getPropertyValue("cat1/mapProperty/key1"));
-    Assert.assertEquals("value2", 
resource.getPropertyValue("cat1/mapProperty/key2"));
-    Assert.assertEquals("value3", 
resource.getPropertyValue("cat1/mapProperty/key3"));
+    assertNull(resource.getPropertyValue("cat1/mapProperty"));
+    assertEquals("value1", resource.getPropertyValue("cat1/mapProperty/key1"));
+    assertEquals("value2", resource.getPropertyValue("cat1/mapProperty/key2"));
+    assertEquals("value3", resource.getPropertyValue("cat1/mapProperty/key3"));
 
     Map<String, Map<String, String>> mapMapProperty = new HashMap<String, 
Map<String, String>>();
     Map<String, String> mapSubProperty1 = new HashMap<String, String>();
@@ -209,16 +217,23 @@ public class BaseProviderTest {
     // Map of maps ... adding a property of type Map should add all of its 
keys as sub properties
     // if the map property was requested
     BaseProvider.setResourceProperty(resource, "cat2/mapMapProperty", 
mapMapProperty, propertyIds);
-    Assert.assertNull(resource.getPropertyValue("cat2/mapMapProperty"));
-    
Assert.assertNull(resource.getPropertyValue("cat2/mapMapProperty/subMap1"));
-    
Assert.assertNull(resource.getPropertyValue("cat2/mapMapProperty/subMap2"));
-    
Assert.assertTrue(resource.getPropertiesMap().containsKey("cat2/mapMapProperty/subMap3"));
-    Assert.assertEquals("value11", 
resource.getPropertyValue("cat2/mapMapProperty/subMap1/key1"));
-    Assert.assertEquals("value12", 
resource.getPropertyValue("cat2/mapMapProperty/subMap1/key2"));
-    Assert.assertEquals("value13", 
resource.getPropertyValue("cat2/mapMapProperty/subMap1/key3"));
-    Assert.assertEquals("value21", 
resource.getPropertyValue("cat2/mapMapProperty/subMap2/key1"));
-    Assert.assertEquals("value22", 
resource.getPropertyValue("cat2/mapMapProperty/subMap2/key2"));
-    Assert.assertEquals("value23", 
resource.getPropertyValue("cat2/mapMapProperty/subMap2/key3"));
+    assertNull(resource.getPropertyValue("cat2/mapMapProperty"));
+    assertNull(resource.getPropertyValue("cat2/mapMapProperty/subMap1"));
+    assertNull(resource.getPropertyValue("cat2/mapMapProperty/subMap2"));
+    assertTrue(resource.getPropertiesMap().containsKey(
+        "cat2/mapMapProperty/subMap3"));
+    assertEquals("value11",
+        resource.getPropertyValue("cat2/mapMapProperty/subMap1/key1"));
+    assertEquals("value12",
+        resource.getPropertyValue("cat2/mapMapProperty/subMap1/key2"));
+    assertEquals("value13",
+        resource.getPropertyValue("cat2/mapMapProperty/subMap1/key3"));
+    assertEquals("value21",
+        resource.getPropertyValue("cat2/mapMapProperty/subMap2/key1"));
+    assertEquals("value22",
+        resource.getPropertyValue("cat2/mapMapProperty/subMap2/key2"));
+    assertEquals("value23",
+        resource.getPropertyValue("cat2/mapMapProperty/subMap2/key3"));
 
     Map<String, String> mapProperty3 = new HashMap<String, String>();
     mapProperty3.put("key1", "value1");
@@ -229,10 +244,10 @@ public class BaseProviderTest {
     // should only add requested keys as sub properties ...
     // only "cat3/mapProperty3/key2" was requested
     BaseProvider.setResourceProperty(resource, "cat3/mapProperty3", 
mapProperty3, propertyIds);
-    Assert.assertNull(resource.getPropertyValue("cat3/mapProperty3"));
-    Assert.assertNull(resource.getPropertyValue("cat3/mapProperty3/key1"));
-    Assert.assertEquals("value2", 
resource.getPropertyValue("cat3/mapProperty3/key2"));
-    Assert.assertNull(resource.getPropertyValue("cat3/mapProperty3/key3"));
+    assertNull(resource.getPropertyValue("cat3/mapProperty3"));
+    assertNull(resource.getPropertyValue("cat3/mapProperty3/key1"));
+    assertEquals("value2", 
resource.getPropertyValue("cat3/mapProperty3/key2"));
+    assertNull(resource.getPropertyValue("cat3/mapProperty3/key3"));
 
     Map<String, Map<String, String>> mapMapProperty4 = new HashMap<String, 
Map<String, String>>();
     mapMapProperty4.put("subMap1", mapSubProperty1);
@@ -241,15 +256,19 @@ public class BaseProviderTest {
     // should only add requested keys as sub properties ...
     // only "cat4/mapMapProperty4/subMap1/key3" and 
"cat4/mapMapProperty4/subMap2" are requested
     BaseProvider.setResourceProperty(resource, "cat4/mapMapProperty4", 
mapMapProperty4, propertyIds);
-    Assert.assertNull(resource.getPropertyValue("cat4/mapMapProperty4"));
-    
Assert.assertNull(resource.getPropertyValue("cat4/mapMapProperty4/subMap1"));
-    
Assert.assertNull(resource.getPropertyValue("cat4/mapMapProperty4/subMap2"));
-    
Assert.assertNull(resource.getPropertyValue("cat4/mapMapProperty4/subMap1/key1"));
-    
Assert.assertNull(resource.getPropertyValue("cat4/mapMapProperty4/subMap1/key2"));
-    Assert.assertEquals("value13", 
resource.getPropertyValue("cat4/mapMapProperty4/subMap1/key3"));
-    Assert.assertEquals("value21", 
resource.getPropertyValue("cat4/mapMapProperty4/subMap2/key1"));
-    Assert.assertEquals("value22", 
resource.getPropertyValue("cat4/mapMapProperty4/subMap2/key2"));
-    Assert.assertEquals("value23", 
resource.getPropertyValue("cat4/mapMapProperty4/subMap2/key3"));
+    assertNull(resource.getPropertyValue("cat4/mapMapProperty4"));
+    assertNull(resource.getPropertyValue("cat4/mapMapProperty4/subMap1"));
+    assertNull(resource.getPropertyValue("cat4/mapMapProperty4/subMap2"));
+    assertNull(resource.getPropertyValue("cat4/mapMapProperty4/subMap1/key1"));
+    assertNull(resource.getPropertyValue("cat4/mapMapProperty4/subMap1/key2"));
+    assertEquals("value13",
+        resource.getPropertyValue("cat4/mapMapProperty4/subMap1/key3"));
+    assertEquals("value21",
+        resource.getPropertyValue("cat4/mapMapProperty4/subMap2/key1"));
+    assertEquals("value22",
+        resource.getPropertyValue("cat4/mapMapProperty4/subMap2/key2"));
+    assertEquals("value23",
+        resource.getPropertyValue("cat4/mapMapProperty4/subMap2/key3"));
   }
 
   @Test
@@ -265,15 +284,44 @@ public class BaseProviderTest {
     propertyIds.add(regexp2);
 
     BaseProvider provider = new TestProvider(propertyIds);
-    Assert.assertEquals(regexp, provider.getRegExpKey(propertyId));
-    Assert.assertNull(provider.getRegExpKey(incorrectPropertyId));
-    Assert.assertEquals("sub", provider.getRegexGroups(regexp, 
propertyId).get(0));
-    Assert.assertEquals("sub2", provider.getRegexGroups(regexp2, 
propertyId2).get(1));
-    Assert.assertTrue(provider.getRegexGroups(regexp, 
incorrectPropertyId).isEmpty());
+    Map.Entry<String, Pattern> regexEntry = provider.getRegexEntry(propertyId);
+
+    assertEquals(regexp, regexEntry.getKey());
+    assertNull(provider.getRegexEntry(incorrectPropertyId));
+    assertEquals("sub", provider.getRegexGroups(regexp, propertyId).get(0));
+    assertEquals("sub2", provider.getRegexGroups(regexp2, propertyId2).get(1));
+    assertTrue(provider.getRegexGroups(regexp, incorrectPropertyId).isEmpty());
   }
 
-  static class TestProvider extends BaseProvider {
+  @Test
+  public void testComplexMetricParsing() {
+    Set<String> propertyIds = new HashSet<String>();
+    
propertyIds.add("metrics/flume/$1.substring(0)/CHANNEL/$2.replaceAll(\"[^-]+\",\"\")EventPutSuccessCount/rate/sum");
+    
propertyIds.add("metrics/yarn/Queue/$1.replaceAll(\"([.])\",\"/\")/AppsCompleted");
+
+    TestProvider provider = new TestProvider(propertyIds);
+    Entry<String, Pattern> entry = 
provider.getRegexEntry("metrics/flume/flume");
+    assertEquals("metrics/flume/$1", entry.getKey());
+    assertEquals("metrics/flume/(\\S*)", entry.getValue().pattern());
+
+    entry = provider.getRegexEntry("metrics/flume/flume/CHANNEL");
+    assertEquals("metrics/flume/$1/CHANNEL", entry.getKey());
+    assertEquals("metrics/flume/(\\S*)/CHANNEL", entry.getValue().pattern());
+
+    entry = 
provider.getRegexEntry("metrics/flume/flume/CHANNEL/EventPutSuccessCount");
+    assertEquals("metrics/flume/$1/CHANNEL/$2EventPutSuccessCount", 
entry.getKey());
+    assertEquals("metrics/flume/(\\S*)/CHANNEL/(\\S*)EventPutSuccessCount",
+        entry.getValue().pattern());
+
+    entry = 
provider.getRegexEntry("metrics/flume/flume/CHANNEL/EventPutSuccessCount/rate");
+    assertEquals("metrics/flume/$1/CHANNEL/$2EventPutSuccessCount/rate",
+        entry.getKey());
+    assertEquals(
+        "metrics/flume/(\\S*)/CHANNEL/(\\S*)EventPutSuccessCount/rate",
+        entry.getValue().pattern());
+  }
 
+  static class TestProvider extends BaseProvider {
     public TestProvider(Set<String> propertyIds) {
       super(propertyIds);
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/b3430e70/ambari-server/src/test/java/org/apache/ambari/server/controller/utilities/PropertyHelperTest.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/controller/utilities/PropertyHelperTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/controller/utilities/PropertyHelperTest.java
index 6380d4e..5ad5510 100644
--- 
a/ambari-server/src/test/java/org/apache/ambari/server/controller/utilities/PropertyHelperTest.java
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/controller/utilities/PropertyHelperTest.java
@@ -17,11 +17,6 @@
  */
 package org.apache.ambari.server.controller.utilities;
 
-import org.apache.ambari.server.controller.internal.PropertyInfo;
-import org.apache.ambari.server.controller.spi.Resource;
-import org.junit.Assert;
-import org.junit.Test;
-
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -29,6 +24,11 @@ import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
 
+import org.apache.ambari.server.controller.internal.PropertyInfo;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.junit.Assert;
+import org.junit.Test;
+
 
 /**
  * Property helper tests.
@@ -68,25 +68,19 @@ public class PropertyHelperTest {
   @Test
   public void testGetPropertyCategory() {
     String propertyId = 
"metrics/yarn/Queue/$1.replaceAll(\",q(\\d+)=\",\"/\").substring(1)/AppsRunning";
-
     String category = PropertyHelper.getPropertyCategory(propertyId);
-
-    
Assert.assertEquals("metrics/yarn/Queue/$1.replaceAll(\",q(\\d+)=\",\"/\").substring(1)",
 category);
+    Assert.assertEquals("metrics/yarn/Queue/$1", category);
 
     category = PropertyHelper.getPropertyCategory(category);
-
     Assert.assertEquals("metrics/yarn/Queue", category);
 
     category = PropertyHelper.getPropertyCategory(category);
-
     Assert.assertEquals("metrics/yarn", category);
 
     category = PropertyHelper.getPropertyCategory(category);
-
     Assert.assertEquals("metrics", category);
 
     category = PropertyHelper.getPropertyCategory(category);
-
     Assert.assertNull(category);
   }
 
@@ -96,7 +90,7 @@ public class PropertyHelperTest {
 
     Set<String> categories = 
PropertyHelper.getCategories(Collections.singleton(propertyId));
 
-    
Assert.assertTrue(categories.contains("metrics/yarn/Queue/$1.replaceAll(\",q(\\d+)=\",\"/\").substring(1)"));
+    Assert.assertTrue(categories.contains("metrics/yarn/Queue/$1"));
     Assert.assertTrue(categories.contains("metrics/yarn/Queue"));
     Assert.assertTrue(categories.contains("metrics/yarn"));
     Assert.assertTrue(categories.contains("metrics"));
@@ -108,7 +102,7 @@ public class PropertyHelperTest {
 
     categories = PropertyHelper.getCategories(propertyIds);
 
-    
Assert.assertTrue(categories.contains("metrics/yarn/Queue/$1.replaceAll(\",q(\\d+)=\",\"/\").substring(1)"));
+    Assert.assertTrue(categories.contains("metrics/yarn/Queue/$1"));
     Assert.assertTrue(categories.contains("metrics/yarn/Queue"));
     Assert.assertTrue(categories.contains("metrics/yarn"));
     Assert.assertTrue(categories.contains("metrics"));

Reply via email to