Java tutorial
/* * Copyright 2011 Facebook, 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. */ /* Copyright 2013 Kevin Ortman * * 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.tsquery; import net.opentsdb.graph.Plot; import net.tsquery.model.MetricQuery; import net.opentsdb.core.Aggregator; import net.opentsdb.core.DataPoint; import net.opentsdb.core.DataPoints; import net.opentsdb.core.Query; import net.opentsdb.tsd.TsdApi; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.JSONValue; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.util.*; public class LastEndpoint extends TsdbServlet { private static final long serialVersionUID = 1L; private static final HashMap<String, Aggregator> _aggregators = new HashMap<>(5); static { _aggregators.put("sum", net.opentsdb.core.Aggregators.SUM); _aggregators.put("min", net.opentsdb.core.Aggregators.MIN); _aggregators.put("max", net.opentsdb.core.Aggregators.MAX); _aggregators.put("avg", net.opentsdb.core.Aggregators.AVG); _aggregators.put("dev", net.opentsdb.core.Aggregators.DEV); } @Override @SuppressWarnings("unchecked") public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("application/json"); TsdApi api = new TsdApi(); PrintWriter out = response.getWriter(); try { JSONObject responseObj = new JSONObject(); // decode parameters String jsonParams = request.getParameter("params"); if (jsonParams == null) { throw new IllegalArgumentException("Required parameter 'params' not specified"); } int topN = this.getTopN(request, -1); JSONObject jsonParamsObj = (JSONObject) JSONValue.parse(jsonParams); if (jsonParamsObj == null) { throw new IllegalArgumentException("Required parameter 'params' is not a valid JSON object"); } long tsFrom = this.getRequiredTimeStamp(jsonParamsObj, "tsFrom"); long tsTo = this.getRequiredTimeStamp(jsonParamsObj, "tsTo"); JSONArray metricsArray = (JSONArray) jsonParamsObj.get("metrics"); if (metricsArray == null || metricsArray.size() == 0) { throw new IllegalArgumentException("Required parameter 'metrics' array not specified or empty"); } Query[] queries = new Query[metricsArray.size()]; for (int i = 0; i < metricsArray.size(); i++) { MetricQuery metricQuery = MetricQuery.fromJSONObject((JSONObject) metricsArray.get(i)); queries[i] = _tsdb.newQuery(); queries[i].setTimeSeries(metricQuery.name, metricQuery.tags, _aggregators.get(metricQuery.aggregator), metricQuery.rate); if (metricQuery.downsample > 0) queries[i].downsample(metricQuery.downsample, _aggregators.get(metricQuery.aggregator)); } long ts = System.currentTimeMillis(); net.opentsdb.graph.Plot plot = api.Query(_tsdb, tsFrom, tsTo, queries, TimeZone.getDefault(), false); responseObj.put("loadtime", System.currentTimeMillis() - ts); ts = System.currentTimeMillis(); responseObj.put("series", PlotToStandardJSON(plot, tsFrom, tsTo, topN)); responseObj.put("serializationtime", System.currentTimeMillis() - ts); doSendResponse(request, out, responseObj.toJSONString()); } catch (Exception e) { out.println(getErrorResponse(request, e)); } out.close(); } private int getTopN(HttpServletRequest request, int defaultValue) { String strval = request.getParameter("topN"); int value = defaultValue; if (strval != null) { try { value = Integer.parseInt(strval); } catch (NumberFormatException ignored) { } } return value; } private double getValue(DataPoint point) { double value; if (point.isInteger()) { value = (double) point.longValue(); } else { final double doubleValue = point.doubleValue(); if (doubleValue != doubleValue || Double.isInfinite(doubleValue)) { throw new IllegalStateException("invalid datapoint found"); } value = doubleValue; } return value; } @SuppressWarnings("unchecked") private JSONObject PlotToStandardJSON(Plot plot, long tsFrom, long tsTo, int topN) { final JSONObject plotObject = new JSONObject(); JSONArray seriesArray = new JSONArray(); final TreeMap<Double, JSONObject> weightMap = new TreeMap<>(Collections.reverseOrder()); for (DataPoints dataPoints : plot.getDataPoints()) { double weight = 0; JSONArray dataArray = new JSONArray(); StringBuilder nameBuilder = new StringBuilder(); nameBuilder.append(dataPoints.metricName()).append(": "); Map<String, String> tags = dataPoints.getTags(); for (String s : tags.keySet()) { nameBuilder.append(String.format("%s=%s, ", s, tags.get(s))); } nameBuilder.setLength(nameBuilder.length() - 2); JSONArray values = null; long latestTimestamp = 0; for (DataPoint point : dataPoints) { long timestamp = point.timestamp(); if (!(timestamp < tsFrom || timestamp > tsTo) && timestamp > latestTimestamp) { latestTimestamp = timestamp; double dpValue = getValue(point); values = new JSONArray(); values.add(timestamp * 1000); values.add(dpValue); } } dataArray.add(values); JSONObject series = new JSONObject(); series.put("name", nameBuilder.toString()); series.put("data", dataArray); while (weightMap.containsKey(weight)) weight -= 0.00000001; weightMap.put(weight, series); } int counter = 0; for (Map.Entry<Double, JSONObject> entry : weightMap.entrySet()) { seriesArray.add(entry.getValue()); ++counter; if ((topN > 0) && (counter >= topN)) break; } plotObject.put("plot", seriesArray); return plotObject; } }