net.opentsdb.contrib.tsquare.web.controller.ExtendedApiController.java Source code

Java tutorial

Introduction

Here is the source code for net.opentsdb.contrib.tsquare.web.controller.ExtendedApiController.java

Source

/*
 * Copyright (C) 2013 Conductor, Inc.
 *
 * Licensed 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 net.opentsdb.contrib.tsquare.web.controller;

import java.io.IOException;
import java.io.OutputStream;

import javax.servlet.http.HttpServletResponse;

import net.opentsdb.contrib.tsquare.Metric;
import net.opentsdb.contrib.tsquare.MetricParser;
import net.opentsdb.contrib.tsquare.QueryCallback;
import net.opentsdb.contrib.tsquare.Uid;
import net.opentsdb.contrib.tsquare.UidQuery;
import net.opentsdb.contrib.tsquare.support.TsWebUtils;
import net.opentsdb.contrib.tsquare.web.AnnotatedDataQuery;
import net.opentsdb.contrib.tsquare.web.DataQueryModel;
import net.opentsdb.contrib.tsquare.web.QueryDurationParams;
import net.opentsdb.contrib.tsquare.web.view.GraphiteJsonResponseWriter;
import net.opentsdb.contrib.tsquare.web.view.HighchartsSeriesResponseWriter;
import net.opentsdb.contrib.tsquare.web.view.SummarizedJsonResponseWriter;
import net.opentsdb.core.Query;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.ModelAndView;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.io.Closeables;

/**
 * @author James Royalty (jroyalty) <i>[Jun 20, 2013]</i>
 */
@Controller
@RequestMapping("/ext")
public class ExtendedApiController extends AbstractController {
    private static final Logger log = LoggerFactory.getLogger(ExtendedApiController.class);

    @RequestMapping(value = "/grep", method = RequestMethod.GET)
    public void grep(@RequestParam(required = false, defaultValue = "") String type,
            @RequestParam(required = false, defaultValue = "wildcard") String method,
            @RequestParam(required = true) String q, final HttpServletResponse servletResponse) throws IOException {

        if (log.isInfoEnabled()) {
            log.info("Suggest {} using {} expression: {}", type, method, q);
        }

        // Do we have a valid type? Note that an empty "type" is valid.
        if (!Strings.isNullOrEmpty(type)) {
            Preconditions.checkArgument(getTsdbManager().getKnownUidKinds().contains(type), "Unknown type: %s",
                    type);
        }

        // We can only query hbase using regex, so convert a wildcard query into
        // a regex if necessary.
        final String regex;
        if ("wildcard".equalsIgnoreCase(method)) {
            regex = TsWebUtils.wildcardToRegex(q);
            log.debug("Converted wildcard expression {} to regex: {}", q, regex);
        } else {
            regex = q;
        }

        final UidQuery query = getTsdbManager().newUidQuery();
        query.setRegex(regex);

        if (Strings.isNullOrEmpty(type)) {
            query.includeAllKinds();
        } else {
            query.includeKind(type);
        }

        servletResponse.setContentType("application/json");
        final OutputStream stream = servletResponse.getOutputStream();
        final JsonGenerator json = new JsonFactory().createJsonGenerator(stream);

        try {
            json.writeStartArray();

            query.run(new QueryCallback<Uid>() {
                @Override
                public boolean onResult(final Uid resultObject) {
                    try {
                        json.writeString(resultObject.getName());
                        return true;
                    } catch (IOException e) {
                        throw new IllegalArgumentException("Unable to serialize " + resultObject + " to JSON", e);
                    }
                }
            });

            json.writeEndArray();
            json.flush();
        } finally {
            Closeables.close(stream, false);
        }
    }

    @RequestMapping(value = "/kinds", method = RequestMethod.GET)
    public ModelAndView kinds() throws IOException {
        return jsonSingleObjectView(getTsdbManager().getKnownUidKinds());
    }

    @RequestMapping(value = "/q", method = RequestMethod.GET)
    public ModelAndView query(@RequestParam(required = true) String start,
            @RequestParam(required = false) String end,
            @RequestParam(required = false, defaultValue = "false") boolean summarize,
            @RequestParam(required = false, defaultValue = "ts") String format,
            @RequestParam(required = false, defaultValue = "false") boolean ms, // millisecond resolution?
            final WebRequest webRequest) throws IOException {

        final String[] inputMetricNames = webRequest.getParameterValues("m");
        Preconditions.checkArgument(inputMetricNames != null && inputMetricNames.length > 0,
                "Input metric names are required.");

        final QueryDurationParams durationParams = parseDurations(start, end);
        if (log.isInfoEnabled()) {
            log.info("{}", durationParams);
        }

        // Prepare queries...
        final MetricParser parser = getTsdbManager().newMetricParser();

        final DataQueryModel model = new DataQueryModel();

        for (final String t : inputMetricNames) {
            final Query q = getTsdbManager().newMetricsQuery();
            durationParams.contributeToQuery(q);

            final Metric metric = parser.parseMetric(t);
            if (summarize) {
                Preconditions.checkState(metric.getAggregator() != null,
                        "A metric-level aggregator is required when 'summarize' is enabled.  Metric: {}", t);
            }

            metric.contributeToQuery(q);
            model.addQuery(new AnnotatedDataQuery(metric, q));
            if (summarize) {
                log.info("Added {} to query (w/ summary) ", metric);
            } else {
                log.info("Added {} to query ", metric);
            }
        }

        if (summarize) {
            model.setResponseWriter(new SummarizedJsonResponseWriter(ms));
        } else if ("highcharts".equalsIgnoreCase(format)) {
            model.setResponseWriter(new HighchartsSeriesResponseWriter(ms));
        } else {
            final GraphiteJsonResponseWriter writer = new GraphiteJsonResponseWriter(ms)
                    .setIncludeAggregatedTags(true).setIncludeAllTags(true).setSummarize(false);

            model.setResponseWriter(writer);
        }

        return model.toModelAndView();
    }
}