// This file is part of OpenTSDB. // Copyright (C) 2015 The OpenTSDB Authors. // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 2.1 of the License, or (at your // option) any later version. This program is distributed in the hope that it // will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser // General Public License for more details. You should have received a copy // of the GNU Lesser General Public License along with this program. If not, // see <http://www.gnu.org/licenses/>. package net.opentsdb.query.pojo; import java.util.NoSuchElementException; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import com.google.common.base.Objects; import net.opentsdb.core.Aggregators; import net.opentsdb.utils.DateTime; /** * Pojo builder class used for serdes of the timespan component of a query * @since 2.3 */ @JsonIgnoreProperties(ignoreUnknown = true) @JsonDeserialize(builder = Timespan.Builder.class) public class Timespan extends Validatable { /** User given start date/time, could be relative or absolute */ private String start; /** User given end date/time, could be relative, absolute or empty */ private String end; /** User's timezone used for converting absolute human readable dates */ private String timezone; /** An optional downsampler for all queries */ private Downsampler downsampler; /** The global aggregator to use */ private String aggregator; /** Whether or not to compute a rate */ private boolean rate; /** * Default ctor * @param builder The builder to pull values from */ public Timespan(Builder builder) { start = builder.start; end = builder.end; timezone = builder.timezone; downsampler = builder.downsampler; aggregator = builder.aggregator; rate = builder.rate; } /** @return user given start date/time, could be relative or absolute */ public String getStart() { return start; } /** @return user given end date/time, could be relative, absolute or empty */ public String getEnd() { return end; } /** @return user's timezone used for converting absolute human readable dates */ public String getTimezone() { return timezone; } /** @return an optional downsampler for all queries */ public Downsampler getDownsampler() { return downsampler; } /** @return the global aggregator to use */ public String getAggregator() { return aggregator; } /** @return whether or not to compute a rate */ public boolean isRate() { return rate; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Timespan timespan = (Timespan) o; return Objects.equal(timespan.downsampler, downsampler) && Objects.equal(timespan.end, end) && Objects.equal(timespan.start, start) && Objects.equal(timespan.timezone, timezone) && Objects.equal(timespan.aggregator, aggregator) && Objects.equal(timespan.rate, rate); } @Override public int hashCode() { return Objects.hashCode(start, end, timezone, downsampler, aggregator, rate); } /** @return A new builder for the downsampler */ public static Builder Builder() { return new Builder(); } /** Validates the timespan * @throws IllegalArgumentException if one or more parameters were invalid */ public void validate() { if (start == null || start.isEmpty()) { throw new IllegalArgumentException("missing or empty start"); } DateTime.parseDateTimeString(start, timezone); if (end != null && !end.isEmpty()) { DateTime.parseDateTimeString(end, timezone); } if (downsampler != null) { downsampler.validate(); } if (aggregator == null || aggregator.isEmpty()) { throw new IllegalArgumentException("Missing or empty aggregator"); } try { Aggregators.get(aggregator.toLowerCase()); } catch (final NoSuchElementException e) { throw new IllegalArgumentException("Invalid aggregator"); } } /** * A builder for the downsampler component of a query */ @JsonIgnoreProperties(ignoreUnknown = true) @JsonPOJOBuilder(buildMethodName = "build", withPrefix = "") public static final class Builder { @JsonProperty private String start; @JsonProperty private String end; @JsonProperty private String timezone; @JsonProperty private Downsampler downsampler; @JsonProperty private String aggregator; @JsonProperty private boolean rate; public Builder setStart(final String start) { this.start = start; return this; } public Builder setEnd(final String end) { this.end = end; return this; } public Builder setTimezone(final String timezone) { this.timezone = timezone; return this; } public Builder setDownsampler(final Downsampler downsample) { this.downsampler = downsample; return this; } public Builder setAggregator(final String aggregator) { this.aggregator = aggregator; return this; } public Builder setRate(final boolean rate) { this.rate = rate; return this; } public Timespan build() { return new Timespan(this); } } }