/* * Copyright 2013 Rackspace * * 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 com.rackspacecloud.blueflood.outputs.utils; import com.rackspacecloud.blueflood.exceptions.InvalidRequestException; import com.rackspacecloud.blueflood.outputs.serializers.BasicRollupsOutputSerializer; import com.rackspacecloud.blueflood.types.Resolution; import java.util.*; public class PlotRequestParser { public static final Set<BasicRollupsOutputSerializer.MetricStat> DEFAULT_STATS = new HashSet<BasicRollupsOutputSerializer.MetricStat>(); public static final Set<BasicRollupsOutputSerializer.MetricStat> DEFAULT_BASIC; public static final Set<BasicRollupsOutputSerializer.MetricStat> DEFAULT_COUNTER; public static final Set<BasicRollupsOutputSerializer.MetricStat> DEFAULT_GAUGE; public static final Set<BasicRollupsOutputSerializer.MetricStat> DEFAULT_SET; public static final Set<BasicRollupsOutputSerializer.MetricStat> DEFAULT_TIMER; static { // EnumSet is so crappy for making me do this instead of using an anonymous subclass. DEFAULT_BASIC = EnumSet.noneOf(BasicRollupsOutputSerializer.MetricStat.class); DEFAULT_COUNTER = EnumSet.noneOf(BasicRollupsOutputSerializer.MetricStat.class); DEFAULT_GAUGE = EnumSet.noneOf(BasicRollupsOutputSerializer.MetricStat.class); DEFAULT_SET = EnumSet.noneOf(BasicRollupsOutputSerializer.MetricStat.class); DEFAULT_TIMER = EnumSet.noneOf(BasicRollupsOutputSerializer.MetricStat.class); DEFAULT_BASIC.add(BasicRollupsOutputSerializer.MetricStat.AVERAGE); DEFAULT_BASIC.add(BasicRollupsOutputSerializer.MetricStat.NUM_POINTS); DEFAULT_BASIC.add(BasicRollupsOutputSerializer.MetricStat.SUM); DEFAULT_COUNTER.add(BasicRollupsOutputSerializer.MetricStat.NUM_POINTS); DEFAULT_COUNTER.add(BasicRollupsOutputSerializer.MetricStat.SUM); DEFAULT_GAUGE.add(BasicRollupsOutputSerializer.MetricStat.NUM_POINTS); DEFAULT_GAUGE.add(BasicRollupsOutputSerializer.MetricStat.LATEST); DEFAULT_SET.add(BasicRollupsOutputSerializer.MetricStat.NUM_POINTS); DEFAULT_TIMER.add(BasicRollupsOutputSerializer.MetricStat.RATE); DEFAULT_TIMER.add(BasicRollupsOutputSerializer.MetricStat.NUM_POINTS); DEFAULT_TIMER.add(BasicRollupsOutputSerializer.MetricStat.AVERAGE); DEFAULT_STATS.add(BasicRollupsOutputSerializer.MetricStat.AVERAGE); DEFAULT_STATS.add(BasicRollupsOutputSerializer.MetricStat.NUM_POINTS); } public static RollupsQueryParams parseParams(Map<String, List<String>> params) throws InvalidRequestException { if (params == null || params.isEmpty()) { throw new InvalidRequestException("No query parameters present."); } List<String> points = params.get("points"); List<String> res = params.get("resolution"); List<String> from = params.get("from"); List<String> to = params.get("to"); List<String> select = params.get("select"); if (points == null && res == null) { throw new InvalidRequestException("Either 'points' or 'resolution' is required."); } if (points != null && points.size() != 1) { throw new InvalidRequestException("Invalid parameter: points=" + points); } else if (res != null && res.size() != 1) { throw new InvalidRequestException("Invalid parameter: resolution=" + res); } else if (from == null || from.size() != 1) { throw new InvalidRequestException("Invalid parameter: from=" + from); } else if (to == null || to.size() != 1) { throw new InvalidRequestException("Invalid parameter: to="+ to); } long fromTime; try { fromTime = Long.parseLong(from.get(0)); } catch (NumberFormatException e) { throw new InvalidRequestException("parameter 'from' must be a valid long"); } long toTime; try { toTime = Long.parseLong(to.get(0)); } catch (NumberFormatException e) { throw new InvalidRequestException("parameter 'to' must be a valid long"); } if (toTime <= fromTime) { throw new InvalidRequestException("parameter 'to' must be greater than 'from'"); } Set<BasicRollupsOutputSerializer.MetricStat> stats = getStatsToFilter(select); if (points != null) { try { return new RollupsQueryParams(fromTime, toTime, Integer.parseInt(points.get(0)), stats); } catch (NumberFormatException ex) { throw new InvalidRequestException("parameter 'points' must be a valid integer"); } } else { Resolution resolution; try { resolution = Resolution.fromString(res.get(0)); } catch (IllegalArgumentException e) { throw new InvalidRequestException("parameter 'resolution' is not valid. Allowed values ['FULL', 'MIN5', 'MIN20', 'MIN60', 'MIN240', 'MIN1440']"); } return new RollupsQueryParams(fromTime, toTime, resolution, stats); } } public static Set<BasicRollupsOutputSerializer.MetricStat> getStatsToFilter(List<String> select) { if (select == null || select.isEmpty()) { return DEFAULT_STATS; } else { Set<BasicRollupsOutputSerializer.MetricStat> filters = new HashSet<BasicRollupsOutputSerializer.MetricStat>(); // handle case when someone does select=average,min instead of select=average&select=min for (String stat : select) { if (stat.contains(",")) { List<String> nestedStats = Arrays.asList(stat.split(",")); filters.addAll(BasicRollupsOutputSerializer.MetricStat.fromStringList(nestedStats)); } else { BasicRollupsOutputSerializer.MetricStat possibleStat = BasicRollupsOutputSerializer.MetricStat.fromString(stat); if (possibleStat != null) filters.add(possibleStat); } } return filters; } } }