blueflood-elasticsearch/src/main/java/com/rackspacecloud/blueflood/io/AbstractElasticIO.java
public List<MetricName> getMetricNames(final String tenant, final String query) throws Exception {

        Timer.Context esMetricNamesQueryTimerCtx = esMetricNamesQueryTimer.time();
        String response;

        try {
            String regexString = regexToGrabCurrentAndNextLevel(query);
            // replace one '\' char with two '\\'
            regexString = regexString.replaceAll("\\\\", "\\\\\\\\");
            response = getMetricNamesFromES(tenant, regexString);
        } finally {
            esMetricNamesQueryTimerCtx.stop();
        }

        // For example, if query = foo.bar.*, base level is 3 which is equal to the number of tokens in the query.
        int baseLevel = getTotalTokens(query);
        MetricIndexData metricIndexData = getMetricIndexData(response, baseLevel);

        List<MetricName> metricNames = new ArrayList<>();

        //Metric Names matching query which have next level
        metricNames.addAll(metricIndexData.getMetricNamesWithNextLevel()
                .stream()
                .map(x -> new MetricName(x, false))
                .collect(toSet()));

        //complete metric names matching query
        metricNames.addAll(metricIndexData.getCompleteMetricNamesAtBaseLevel()
                .stream()
                .map(x -> new MetricName(x, true))
                .collect(toSet()));

        return metricNames;
    }
public List<MetricName> getMetricNames(final String tenant, final String query) throws Exception {

        Timer.Context esMetricNamesQueryTimerCtx = esMetricNamesQueryTimer.time();
        String response;

        try {
            String regexString = regexToGrabCurrentAndNextLevel(query);
            // replace one '\' char with two '\\'
            regexString = regexString.replaceAll("\\\\", "\\\\\\\\");
            response = getMetricNamesFromES(tenant, regexString);
        } finally {
            esMetricNamesQueryTimerCtx.stop();
        }

        // For example, if query = foo.bar.*, base level is 3 which is equal to the number of tokens in the query.
        int baseLevel = getTotalTokens(query);
        MetricIndexData metricIndexData = getMetricIndexData(response, baseLevel);

        List<MetricName> metricNames = new ArrayList<>();

        //Metric Names matching query which have next level
        metricNames.addAll(metricIndexData.getMetricNamesWithNextLevel()
                .stream()
                .map(x -> new MetricName(x, false))
                .collect(toSet()));

        //complete metric names matching query
        metricNames.addAll(metricIndexData.getCompleteMetricNamesAtBaseLevel()
                .stream()
                .map(x -> new MetricName(x, true))
                .collect(toSet()));

        return metricNames;
    }
This method returns a list of {@link MetricName}'s matching the given glob query.

for metrics: foo.bar.xxx,
foo.bar.baz.qux,

for query=foo.bar.*, returns the below list of metric names

new MetricName("foo.bar.xxx", true)   <- From metric foo.bar.xxx
new MetricName("foo.bar.baz", false)  <- From metric foo.bar.baz.qux

@param tenant
@param query is glob representation of hierarchical levels of token. Ex: foo.bar.*
@return
@throws Exception