This is an automated email from the ASF dual-hosted git repository. avijayan pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/ambari-metrics.git
The following commit(s) were added to refs/heads/master by this push: new f8f7c50 [AMBARI-24723] Support wild cards in AppId and InstanceId fields in AMS GET API. (#5) f8f7c50 is described below commit f8f7c50239975d10fe6cd63829c02515d6d6d7a8 Author: avijayanhwx <avija...@hortonworks.com> AuthorDate: Thu Oct 4 22:42:09 2018 -0700 [AMBARI-24723] Support wild cards in AppId and InstanceId fields in AMS GET API. (#5) * [AMBARI-24723] Support wild cards in AppId and InstanceId fields in AMS GET API. * [AMBARI-24723] Support wild cards in AppId and InstanceId fields in AMS GET API. (2) * [AMBARI-24723] Support wild cards in AppId and InstanceId fields in AMS GET API. (3) --- .../core/timeline/PhoenixHBaseAccessor.java | 101 ++++++++++++++++ .../discovery/TimelineMetricMetadataManager.java | 128 +++++++++++++-------- .../core/timeline/query/DefaultCondition.java | 1 - .../timeline/query/MetadataQueryCondition.java | 77 +++++++++++++ .../core/timeline/query/PhoenixTransactSQL.java | 50 ++++++++ .../timeline/query/TransientMetricCondition.java | 27 ++++- .../timeline/discovery/TestMetadataManager.java | 82 ++++++++++++- 7 files changed, 413 insertions(+), 53 deletions(-) diff --git a/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/PhoenixHBaseAccessor.java b/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/PhoenixHBaseAccessor.java index c0427e7..b6ff202 100644 --- a/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/PhoenixHBaseAccessor.java +++ b/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/PhoenixHBaseAccessor.java @@ -121,6 +121,7 @@ import org.apache.ambari.metrics.core.timeline.discovery.TimelineMetricMetadataK import org.apache.ambari.metrics.core.timeline.discovery.TimelineMetricMetadataManager; import org.apache.ambari.metrics.core.timeline.query.Condition; import org.apache.ambari.metrics.core.timeline.query.DefaultPhoenixDataSource; +import org.apache.ambari.metrics.core.timeline.query.MetadataQueryCondition; import org.apache.ambari.metrics.core.timeline.query.PhoenixConnectionProvider; import org.apache.ambari.metrics.core.timeline.query.PhoenixTransactSQL; import org.apache.ambari.metrics.core.timeline.query.SplitByMetricNamesCondition; @@ -1990,6 +1991,106 @@ public class PhoenixHBaseAccessor { return metadataMap; } + public List<TimelineMetricMetadata> scanMetricMetadataForWildCardRequest(Collection<String> metricNames, + String appId, + String instanceId) throws SQLException { + List<TimelineMetricMetadata> metadataList = new ArrayList<>(); + Connection conn = getConnection(); + PreparedStatement stmt = null; + ResultSet rs = null; + + MetadataQueryCondition metadataQueryCondition = new MetadataQueryCondition(new ArrayList<>(metricNames), appId, instanceId); + stmt = PhoenixTransactSQL.prepareScanMetricMetadataSqlStmt(conn, metadataQueryCondition); + try { + if (stmt != null) { + rs = stmt.executeQuery(); + while (rs.next()) { + TimelineMetricMetadata metadata = new TimelineMetricMetadata( + rs.getString("METRIC_NAME"), + rs.getString("APP_ID"), + rs.getString("INSTANCE_ID"), + null, + null, + null, + false, + true + ); + + metadata.setUuid(rs.getBytes("UUID")); + metadataList.add(metadata); + } + } + } finally { + if (rs != null) { + try { + rs.close(); + } catch (SQLException e) { + // Ignore + } + } + if (stmt != null) { + try { + stmt.close(); + } catch (SQLException e) { + // Ignore + } + } + if (conn != null) { + try { + conn.close(); + } catch (SQLException sql) { + // Ignore + } + } + } + + return metadataList; + } + + public List<byte[]> scanHostMetadataForWildCardRequest(List<String> hostnames) throws SQLException { + List<byte[]> uuidList = new ArrayList<>(); + Connection conn = getConnection(); + PreparedStatement stmt; + ResultSet rs = null; + + MetadataQueryCondition metadataQueryCondition = new MetadataQueryCondition(hostnames); + stmt = PhoenixTransactSQL.prepareScanMetricMetadataSqlStmt(conn, metadataQueryCondition); + try { + if (stmt != null) { + rs = stmt.executeQuery(); + while (rs.next()) { + byte[] uuid = rs.getBytes("UUID"); + if (uuid != null) { + uuidList.add(uuid); + } + } + } + } finally { + if (rs != null) { + try { + rs.close(); + } catch (SQLException e) { + // Ignore + } + } + if (stmt != null) { + try { + stmt.close(); + } catch (SQLException e) { + // Ignore + } + } + if (conn != null) { + try { + conn.close(); + } catch (SQLException sql) { + // Ignore + } + } + } + return uuidList; + } + // No filter criteria support for now. public Map<TimelineMetricMetadataKey, TimelineMetricMetadata> getTimelineMetricMetadataV1() throws SQLException { Map<TimelineMetricMetadataKey, TimelineMetricMetadata> metadataMap = new HashMap<>(); 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 2dedd77..7c6fce5 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 @@ -39,11 +39,11 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; import org.apache.ambari.metrics.core.timeline.MetricsSystemInitializationException; import org.apache.ambari.metrics.core.timeline.TimelineMetricConfiguration; import org.apache.ambari.metrics.core.timeline.uuid.MetricUuidGenStrategy; -import org.apache.ambari.metrics.core.timeline.uuid.MD5UuidGenStrategy; import org.apache.ambari.metrics.core.timeline.uuid.Murmur3HashUuidGenStrategy; import org.apache.ambari.metrics.core.timeline.uuid.TimelineMetricUuid; import org.apache.commons.collections.CollectionUtils; @@ -64,7 +64,6 @@ import static org.apache.ambari.metrics.core.timeline.TimelineMetricConfiguratio import static org.apache.ambari.metrics.core.timeline.TimelineMetricConfiguration.TRANSIENT_METRIC_PATTERNS; import static org.apache.ambari.metrics.core.timeline.TimelineMetricConfiguration.METRICS_METADATA_SYNC_INIT_DELAY; 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.query.PhoenixTransactSQL.CREATE_HOSTED_APPS_METADATA_TABLE_SQL; import static org.apache.ambari.metrics.core.timeline.query.PhoenixTransactSQL.CREATE_INSTANCE_HOST_TABLE_SQL; @@ -361,7 +360,8 @@ public class TimelineMetricMetadataManager { } boolean isDistributedModeEnabled() { - return metricsConf.get("timeline.metrics.service.operation.mode").equals("distributed"); + String mode = metricsConf.get("timeline.metrics.service.operation.mode"); + return (mode != null) && mode.equals("distributed"); } /** @@ -629,75 +629,99 @@ public class TimelineMetricMetadataManager { String instanceId, List<String> transientMetricNames) { - Collection<String> sanitizedMetricNames = new HashSet<>(); List<byte[]> uuids = new ArrayList<>(); + boolean metricNameHasWildcard = false; for (String metricName : metricNames) { - if (metricName.contains("%")) { - String metricRegEx = getJavaRegexFromSqlRegex(metricName); - for (TimelineMetricMetadataKey key : METADATA_CACHE.keySet()) { - String metricNameFromMetadata = key.getMetricName(); - if (metricNameFromMetadata.matches(metricRegEx)) { - sanitizedMetricNames.add(metricNameFromMetadata); - } - } - } else { - sanitizedMetricNames.add(metricName); + if (hasWildCard(metricName)) { + metricNameHasWildcard = true; + break; } } - if(sanitizedMetricNames.isEmpty()) { - return uuids; + boolean hostNameHasWildcard = false; + if (CollectionUtils.isNotEmpty(hostnames)) { + for (String hostname : hostnames) { + if (hasWildCard(hostname)) { + hostNameHasWildcard = true; + break; + } + } } - Set<String> sanitizedHostNames = getSanitizedHostnames(hostnames); - if ( StringUtils.isNotEmpty(appId) && !(appId.equals("HOST") || appId.equals("FLUME_HANDLER"))) { //HACK.. Why?? appId = appId.toLowerCase(); } - if (CollectionUtils.isNotEmpty(sanitizedHostNames)) { - if (CollectionUtils.isNotEmpty(sanitizedMetricNames)) { - //Skip getting UUID if it is a transient metric. - //An attempt to get it will also be OK as we don't add null UUIDs. - for (String metricName : sanitizedMetricNames) { - if (isTransientMetric(metricName, appId)) { - transientMetricNames.add(metricName); - continue; + if (hasWildCard(instanceId) || hasWildCard(appId) || hostNameHasWildcard || metricNameHasWildcard) { + try { + List<TimelineMetricMetadata> metricMetadataFromStore = hBaseAccessor.scanMetricMetadataForWildCardRequest(metricNames, + appId, instanceId); + List<byte[]> hostUuidsFromStore = hBaseAccessor.scanHostMetadataForWildCardRequest(hostnames); + + for (TimelineMetricMetadata matchedEntry : metricMetadataFromStore) { + if (matchedEntry.getUuid() != null) { + if (CollectionUtils.isNotEmpty(hostnames)) { + for (byte[] hostUuidEntry : hostUuidsFromStore) { + uuids.add(ArrayUtils.addAll(matchedEntry.getUuid(), hostUuidEntry)); + } + } else { + uuids.add(matchedEntry.getUuid()); + } + } else if (isTransientMetric(matchedEntry.getMetricName(), matchedEntry.getAppId())) { + transientMetricNames.add(matchedEntry.getMetricName()); } - TimelineMetric metric = new TimelineMetric(); - metric.setMetricName(metricName); - metric.setAppId(appId); - metric.setInstanceId(instanceId); - for (String hostname : sanitizedHostNames) { - metric.setHostName(hostname); - byte[] uuid = getUuid(metric, false); + } + return uuids; + } catch (SQLException e) { + LOG.error("Unable to query metadata table to check satisfying metric keys for wildcard request : " + e); + return uuids; + } + } else { + + if (CollectionUtils.isNotEmpty(hostnames)) { + if (CollectionUtils.isNotEmpty(metricNames)) { + //Skip getting UUID if it is a transient metric. + //An attempt to get it will also be OK as we don't add null UUIDs. + for (String metricName : metricNames) { + if (isTransientMetric(metricName, appId)) { + transientMetricNames.add(metricName); + continue; + } + TimelineMetric metric = new TimelineMetric(); + metric.setMetricName(metricName); + metric.setAppId(appId); + metric.setInstanceId(instanceId); + for (String hostname : hostnames) { + metric.setHostName(hostname); + byte[] uuid = getUuid(metric, false); + if (uuid != null) { + uuids.add(uuid); + } + } + } + } else { + for (String hostname : hostnames) { + byte[] uuid = getUuidForHostname(hostname, false); if (uuid != null) { uuids.add(uuid); } } } } else { - for (String hostname : sanitizedHostNames) { - byte[] uuid = getUuidForHostname(hostname, false); + for (String metricName : metricNames) { + //Skip getting UUID if it is a transient metric. An attempt to get it will also be OK as we don't add null UUIDs. + if (isTransientMetric(metricName, appId)) { + transientMetricNames.add(metricName); + continue; + } + TimelineClusterMetric metric = new TimelineClusterMetric(metricName, appId, instanceId, -1l); + byte[] uuid = getUuid(metric, false); if (uuid != null) { uuids.add(uuid); } } } - } else { - for (String metricName : sanitizedMetricNames) { - //Skip getting UUID if it is a transient metric. An attempt to get it will also be OK as we don't add null UUIDs. - if (isTransientMetric(metricName, appId)) { - transientMetricNames.add(metricName); - continue; - } - TimelineClusterMetric metric = new TimelineClusterMetric(metricName, appId, instanceId, -1l); - byte[] uuid = getUuid(metric, false); - if (uuid != null) { - uuids.add(uuid); - } - } } return uuids; @@ -833,6 +857,9 @@ public class TimelineMetricMetadataManager { * Run TimelineMetricMetadataSync once */ public void forceMetricsMetadataSync() { + if (metricMetadataSync == null) { + metricMetadataSync = new TimelineMetricMetadataSync(this); + } metricMetadataSync.run(); } @@ -860,4 +887,9 @@ public class TimelineMetricMetadataManager { } } } + + private boolean hasWildCard(String key) { + return StringUtils.isNotEmpty(key) && key.contains("%"); + } + } diff --git a/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/query/DefaultCondition.java b/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/query/DefaultCondition.java index 7f72187..46204fc 100644 --- a/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/query/DefaultCondition.java +++ b/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/query/DefaultCondition.java @@ -28,7 +28,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.metrics2.sink.timeline.Precision; import org.apache.ambari.metrics.core.timeline.PhoenixHBaseAccessor; -import org.apache.ambari.metrics.core.timeline.discovery.TimelineMetricMetadataManager; public class DefaultCondition implements Condition { List<String> metricNames; diff --git a/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/query/MetadataQueryCondition.java b/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/query/MetadataQueryCondition.java new file mode 100644 index 0000000..f6e8c6a --- /dev/null +++ b/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/query/MetadataQueryCondition.java @@ -0,0 +1,77 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ambari.metrics.core.timeline.query; + +import java.util.Collections; +import java.util.List; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.StringUtils; + +public class MetadataQueryCondition extends TransientMetricCondition { + + private boolean isMetricMetadataCondition = true; + + public MetadataQueryCondition(List<String> metricNames, String appId, String instanceId) { + super(metricNames, Collections.EMPTY_LIST, appId, instanceId, null, null, null , null, true, null); + this.hostnames = Collections.EMPTY_LIST; + } + + public MetadataQueryCondition(List<String> hostnames) { + super(Collections.EMPTY_LIST, hostnames, StringUtils.EMPTY, StringUtils.EMPTY, null, null, null , null, true, null); + isMetricMetadataCondition = false; + } + + public StringBuilder getConditionClause() { + StringBuilder sb = new StringBuilder(); + + boolean appendConjunction = false; + if (CollectionUtils.isNotEmpty(metricNames)) { + appendConjunction = appendMetricNameClause(sb); + } + + if (CollectionUtils.isNotEmpty(hostnames)) { + appendConjunction = appendHostnameClause(sb, appendConjunction); + } + + String appId = getAppId(); + if (StringUtils.isNotEmpty(appId)) { + if (appId.contains("%")) { + appendConjunction = append(sb, appendConjunction, appId, " APP_ID LIKE ?"); + } else { + appendConjunction = append(sb, appendConjunction, appId, " APP_ID = ?"); + } + } + + String instanceId = getInstanceId(); + if (StringUtils.isNotEmpty(instanceId)) { + if (instanceId.contains("%")) { + appendConjunction = append(sb, appendConjunction, instanceId, " INSTANCE_ID LIKE ?"); + } else { + appendConjunction = append(sb, appendConjunction, instanceId, " INSTANCE_ID = ?"); + } + } + + return sb; + } + + public boolean isMetricMetadataCondition() { + return isMetricMetadataCondition; + } +} diff --git a/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/query/PhoenixTransactSQL.java b/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/query/PhoenixTransactSQL.java index 6a1d03f..ee50051 100644 --- a/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/query/PhoenixTransactSQL.java +++ b/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/query/PhoenixTransactSQL.java @@ -377,6 +377,10 @@ public class PhoenixTransactSQL { public static final String GET_INSTANCE_HOST_METADATA_SQL = "SELECT " + "INSTANCE_ID, HOSTNAME FROM INSTANCE_HOST_METADATA"; + public static final String SCAN_METRIC_METADATA_SQL = "SELECT METRIC_NAME, APP_ID, INSTANCE_ID, UUID FROM %s"; + + public static final String SCAN_HOST_METADATA_SQL = "SELECT HOSTNAME, UUID FROM %s"; + /** * Aggregate host metrics using a GROUP BY clause to take advantage of * N - way parallel scan where N = number of regions. @@ -462,6 +466,12 @@ public class PhoenixTransactSQL { public static final String METRICS_CLUSTER_AGGREGATE_DAILY_TABLE_NAME = "METRIC_AGGREGATE_DAILY_UUID"; + public static final String METRICS_METADATA_TABLE_NAME = + "METRICS_METADATA_UUID"; + + public static final String HOST_METADATA_TABLE_NAME = + "HOSTED_APPS_METADATA_UUID"; + public static final Pattern PHOENIX_TABLES_REGEX_PATTERN = Pattern.compile("METRIC_.*"); public static final String[] PHOENIX_TABLES = { @@ -980,6 +990,46 @@ public class PhoenixTransactSQL { } + public static PreparedStatement prepareScanMetricMetadataSqlStmt(Connection connection, MetadataQueryCondition condition) + throws SQLException { + + String stmtStr; + if (condition.isMetricMetadataCondition()) { + stmtStr = String.format(SCAN_METRIC_METADATA_SQL, METRICS_METADATA_TABLE_NAME); + } else { + stmtStr = String.format(SCAN_HOST_METADATA_SQL, HOST_METADATA_TABLE_NAME); + } + + StringBuilder sb = new StringBuilder(stmtStr); + + sb.append(" WHERE "); + sb.append(condition.getConditionClause()); + + if (LOG.isDebugEnabled()) { + LOG.debug("SQL: " + sb.toString() + ", condition: " + condition); + } + + PreparedStatement stmt = null; + try { + stmt = connection.prepareStatement(sb.toString()); + int pos = 1; + if (condition.isMetricMetadataCondition()) { + pos = addMetricNames(condition, pos, stmt); + pos = addAppId(condition, pos, stmt); + pos = addInstanceId(condition, pos, stmt); + } else { + pos = addHostNames(condition, pos, stmt); + } + + } catch (SQLException e) { + if (stmt != null) { + stmt.close(); + } + throw e; + } + return stmt; + } + public static String getTargetTableUsingPrecision(Precision precision, boolean withHosts) { String inputTable = null; diff --git a/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/query/TransientMetricCondition.java b/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/query/TransientMetricCondition.java index c26d18d..b0f526c 100644 --- a/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/query/TransientMetricCondition.java +++ b/ambari-metrics-timelineservice/src/main/java/org/apache/ambari/metrics/core/timeline/query/TransientMetricCondition.java @@ -42,6 +42,16 @@ public class TransientMetricCondition extends DefaultCondition { } } + public TransientMetricCondition(List<String> metricNames, List<String> hostnames, String appId, + String instanceId, Long startTime, Long endTime, Precision precision, + Integer limit, boolean grouped, List<String> transientMetricNames) { + super(metricNames, hostnames, appId, instanceId, startTime, endTime, precision, limit, grouped); + this.transientMetricNames = transientMetricNames; + if (CollectionUtils.isEmpty(hostnames)) { + this.hostnames = Collections.singletonList("%"); + } + } + public StringBuilder getTransientConditionClause() { StringBuilder sb = new StringBuilder(); @@ -49,15 +59,26 @@ public class TransientMetricCondition extends DefaultCondition { appendConjunction = appendHostnameClause(sb, appendConjunction); - appendConjunction = append(sb, appendConjunction, getAppId(), " APP_ID = ?"); - appendConjunction = append(sb, appendConjunction, getInstanceId(), " INSTANCE_ID = ?"); + String appId = getAppId(); + if (appId.contains("%")) { + appendConjunction = append(sb, appendConjunction, getAppId(), " APP_ID LIKE ?"); + } else { + appendConjunction = append(sb, appendConjunction, getAppId(), " APP_ID = ?"); + } + + String instanceId = getInstanceId(); + if (instanceId.contains("%")) { + appendConjunction = append(sb, appendConjunction, getInstanceId(), " INSTANCE_ID LIKE ?"); + } else { + appendConjunction = append(sb, appendConjunction, getInstanceId(), " INSTANCE_ID = ?"); + } appendConjunction = append(sb, appendConjunction, getStartTime(), " SERVER_TIME >= ?"); append(sb, appendConjunction, getEndTime(), " SERVER_TIME < ?"); return sb; } - private boolean appendMetricNameClause(StringBuilder sb) { + protected boolean appendMetricNameClause(StringBuilder sb) { boolean appendConjunction = false; List<String> metricsLike = new ArrayList<>(); List<String> metricsIn = new ArrayList<>(); 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 90def86..90a5d10 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 @@ -181,7 +181,7 @@ public class TestMetadataManager extends AbstractMiniHBaseClusterTest { } @Test - public void testWildcardSanitization() throws IOException, SQLException, URISyntaxException { + public void testMetricHostWildcardSanitization() throws IOException, SQLException, URISyntaxException { // Initialize new manager metadataManager = new TimelineMetricMetadataManager(new Configuration(), hdb); hdb.setMetadataInstance(metadataManager); @@ -234,6 +234,7 @@ public class TestMetadataManager extends AbstractMiniHBaseClusterTest { replay(configuration); hdb.insertMetricRecordsWithMetadata(metadataManager, timelineMetrics, true); + metadataManager.forceMetricsMetadataSync(); List<byte[]> uuids = metadataManager.getUuidsForGetMetricQuery(Collections.singletonList("dummy_m%"), Collections.singletonList("dummy_host2"), "dummy_app1", null); @@ -255,6 +256,85 @@ public class TestMetadataManager extends AbstractMiniHBaseClusterTest { } @Test + public void testAppInstanceWildcardSanitization() throws IOException, SQLException, URISyntaxException { + // Initialize new manager + metadataManager = new TimelineMetricMetadataManager(new Configuration(), hdb); + hdb.setMetadataInstance(metadataManager); + final long now = System.currentTimeMillis(); + + TimelineMetrics timelineMetrics = new TimelineMetrics(); + + TimelineMetric metric1 = new TimelineMetric(); + metric1.setMetricName("dummy_m1"); + metric1.setHostName("dummy_host1"); + metric1.setStartTime(now - 1000); + metric1.setAppId("dummy_app1"); + metric1.setInstanceId("dummy_i1"); + metric1.setType("Integer"); + metric1.setMetricValues(new TreeMap<Long, Double>() {{ + put(now - 100, 1.0); + put(now - 200, 2.0); + put(now - 300, 3.0); + }}); + timelineMetrics.getMetrics().add(metric1); + + TimelineMetric metric2 = new TimelineMetric(); + metric2.setMetricName("dummy_m2"); + metric2.setHostName("dummy_host2"); + metric2.setStartTime(now - 1000); + metric2.setAppId("dummy_app2"); + metric2.setInstanceId("dummy_i2"); + metric2.setType("Integer"); + metric2.setMetricValues(new TreeMap<Long, Double>() {{ + put(now - 100, 1.0); + put(now - 200, 2.0); + put(now - 300, 3.0); + }}); + timelineMetrics.getMetrics().add(metric2); + + TimelineMetric metric3 = new TimelineMetric(); + metric3.setMetricName("dummy_3"); + metric3.setHostName("gummy_3h"); + metric3.setStartTime(now - 1000); + metric3.setAppId("gummy_app3"); + metric3.setType("Integer"); + metric3.setMetricValues(new TreeMap<Long, Double>() {{ + put(now - 100, 1.0); + put(now - 200, 2.0); + put(now - 300, 3.0); + }}); + timelineMetrics.getMetrics().add(metric3); + + Configuration metricsConf = new Configuration(); + TimelineMetricConfiguration configuration = EasyMock.createNiceMock(TimelineMetricConfiguration.class); + expect(configuration.getMetricsConf()).andReturn(metricsConf).once(); + replay(configuration); + + hdb.insertMetricRecordsWithMetadata(metadataManager, timelineMetrics, true); + metadataManager.forceMetricsMetadataSync(); + + List<byte[]> uuids = metadataManager.getUuidsForGetMetricQuery(Collections.singletonList("dummy_m%"), + Collections.singletonList("dummy_host%"), "dummy_app%", "dummy_i%"); + Assert.assertTrue(uuids.size() == 4); + + uuids = metadataManager.getUuidsForGetMetricQuery(Collections.singletonList("dummy_m1"), + Collections.singletonList("dummy_host1"), "dummy_app1", "%"); + Assert.assertTrue(uuids.size() == 1); + + uuids = metadataManager.getUuidsForGetMetricQuery(Collections.singletonList("dummy_m1"), + Collections.singletonList("dummy_host1"), "dummy_app1", "dummy_i%"); + Assert.assertTrue(uuids.size() == 1); + + uuids = metadataManager.getUuidsForGetMetricQuery(Collections.singletonList("dummy_m1"), + Collections.singletonList("dummy_host1"), "dummy_app1", "dummy_i2"); + Assert.assertTrue(uuids.size() == 0); + + uuids = metadataManager.getUuidsForGetMetricQuery(Collections.singletonList("%"), + Collections.singletonList("%"), "%", "%"); + Assert.assertTrue(uuids.size() == 6); + } + + @Test public void testTransientMetricPatterns() { long now = System.currentTimeMillis();