AMBARI-23618 : Requesting non-existing metric (including wildcard) to AMS gets HTTP 500 error.
diff --git a/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/HBaseTimelineMetricsService.java b/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/HBaseTimelineMetricsService.java
index d21edfc..ae394e3 100644
--- a/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/HBaseTimelineMetricsService.java
+++ b/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/HBaseTimelineMetricsService.java
@@ -27,6 +27,7 @@
import java.net.UnknownHostException;
import java.sql.SQLException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -262,8 +263,15 @@
Multimap<String, List<Function>> metricFunctions =
parseMetricNamesToAggregationFunctions(metricNames);
+ TimelineMetrics metrics = new TimelineMetrics();
+
List<byte[]> uuids = metricMetadataManager.getUuids(metricFunctions.keySet(), hostnames, applicationId, instanceId);
+ if (uuids.isEmpty()) {
+ LOG.warn("No metric UUIDs generated for query : " + Arrays.asList(metricNames).toString());
+ return metrics;
+ }
+
ConditionBuilder conditionBuilder = new ConditionBuilder(new ArrayList<String>(metricFunctions.keySet()))
.hostnames(hostnames)
.appId(applicationId)
@@ -296,8 +304,6 @@
Condition condition = conditionBuilder.build();
- TimelineMetrics metrics;
-
if (hostnames == null || hostnames.isEmpty()) {
metrics = hBaseAccessor.getAggregateMetricRecords(condition, metricFunctions);
} else {
diff --git a/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/aggregators/Function.java b/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/aggregators/Function.java
index dd67b64..6929036 100644
--- a/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/aggregators/Function.java
+++ b/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/aggregators/Function.java
@@ -24,8 +24,7 @@
/**
* Is used to determine metrics aggregate table.
*
- * @see TimelineWebServices#getTimelineMetric
- * @see TimelineWebServices#getTimelineMetrics
+ * @see org.apache.ambari.metrics.webapp.TimelineWebServices#getTimelineMetrics
*/
public class Function {
public static Function DEFAULT_VALUE_FUNCTION = new Function(ReadFunction.VALUE, null);
diff --git a/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/discovery/TimelineMetricMetadataManager.java b/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/discovery/TimelineMetricMetadataManager.java
index ff24c10..e13c884 100644
--- a/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/discovery/TimelineMetricMetadataManager.java
+++ b/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/discovery/TimelineMetricMetadataManager.java
@@ -55,6 +55,7 @@
import static org.apache.ambari.metrics.core.timeline.TimelineMetricConfiguration.METRICS_METADATA_SYNC_SCHEDULE_DELAY;
import static org.apache.ambari.metrics.core.timeline.TimelineMetricConfiguration.TIMELINE_METRICS_UUID_GEN_STRATEGY;
import static org.apache.ambari.metrics.core.timeline.TimelineMetricConfiguration.TIMELINE_METRIC_METADATA_FILTERS;
+import static org.apache.ambari.metrics.core.timeline.aggregators.AggregatorUtils.getJavaRegexFromSqlRegex;
public class TimelineMetricMetadataManager {
private static final Log LOG = LogFactory.getLog(TimelineMetricMetadataManager.class);
@@ -497,19 +498,11 @@
public List<byte[]> getUuids(Collection<String> metricNames, List<String> hostnames, String appId, String instanceId) {
Collection<String> sanitizedMetricNames = new HashSet<>();
+ List<byte[]> uuids = new ArrayList<>();
for (String metricName : metricNames) {
if (metricName.contains("%")) {
- String metricRegEx;
- //Special case handling for metric name with * and __%.
- //For example, dfs.NNTopUserOpCounts.windowMs=300000.op=*.user=%.count
- // or dfs.NNTopUserOpCounts.windowMs=300000.op=__%.user=%.count
- if (metricName.contains("*") || metricName.contains("__%")) {
- String metricNameWithEscSeq = metricName.replace("*", "\\*").replace("__%", "..%");
- metricRegEx = metricNameWithEscSeq.replace("%", ".*");
- } else {
- metricRegEx = metricName.replace("%", ".*");
- }
+ String metricRegEx = getJavaRegexFromSqlRegex(metricName);
for (TimelineMetricMetadataKey key : METADATA_CACHE.keySet()) {
String metricNameFromMetadata = key.getMetricName();
if (metricNameFromMetadata.matches(metricRegEx)) {
@@ -521,6 +514,10 @@
}
}
+ if(sanitizedMetricNames.isEmpty()) {
+ return uuids;
+ }
+
Set<String> sanitizedHostNames = new HashSet<>();
if (CollectionUtils.isNotEmpty(hostnames)) {
for (String hostname : hostnames) {
@@ -538,8 +535,6 @@
}
}
- List<byte[]> uuids = new ArrayList<>();
-
if ( StringUtils.isNotEmpty(appId) && !(appId.equals("HOST") || appId.equals("FLUME_HANDLER"))) { //HACK.. Why??
appId = appId.toLowerCase();
}
diff --git a/ambari-metrics-timelineservice/src/test/java/org/apache/ambari/metrics/core/timeline/discovery/TestMetadataManager.java b/ambari-metrics-timelineservice/src/test/java/org/apache/ambari/metrics/core/timeline/discovery/TestMetadataManager.java
index 94fbb30..3604ec4 100644
--- a/ambari-metrics-timelineservice/src/test/java/org/apache/ambari/metrics/core/timeline/discovery/TestMetadataManager.java
+++ b/ambari-metrics-timelineservice/src/test/java/org/apache/ambari/metrics/core/timeline/discovery/TestMetadataManager.java
@@ -228,6 +228,11 @@
List<String> hosts = Arrays.asList("dummy_host%", "dummy_3h");
uuids = metadataManager.getUuids(metrics, hosts, "dummy_app2", null);
Assert.assertTrue(uuids.size() == 9);
+
+ metrics = Arrays.asList("abc%");
+ hosts = Arrays.asList("dummy_host");
+ uuids = metadataManager.getUuids(metrics, hosts, "dummy_app2", null);
+ Assert.assertTrue(uuids.isEmpty());
}