Skip to content

Commit 0aa6f0c

Browse files
fix #23 Switch to java duration iso scala finite duration
1 parent a703ce0 commit 0aa6f0c

16 files changed

+322
-250
lines changed

src/main/scala/io/waylay/kairosdb/driver/Implicits.scala

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
package io.waylay.kairosdb.driver
22

3-
import java.time.Instant
3+
import java.time.temporal.TemporalAmount
4+
import java.time.{Duration, Instant, Period}
5+
import java.util.concurrent.TimeUnit
46

57
import io.waylay.kairosdb.driver.models.KairosCompatibleType.{KNumber, KString}
68
import io.waylay.kairosdb.driver.models.KairosQuery.QueryTag
7-
import io.waylay.kairosdb.driver.models._
89
import io.waylay.kairosdb.driver.models.TimeSpan.{AbsoluteEndTime, AbsoluteStartTime, RelativeEndTime, RelativeStartTime}
10+
import io.waylay.kairosdb.driver.models._
911

10-
import scala.concurrent.duration.FiniteDuration
1112
import scala.collection.immutable.Seq
13+
import scala.concurrent.duration.FiniteDuration
1214

1315

1416
object Implicits {
@@ -66,4 +68,25 @@ object Implicits {
6668

6769
def ago = RelativeTime(fin)
6870
}
71+
72+
implicit def finiteDuration2timeRange(fin: FiniteDuration): TimeRange = fin.unit match {
73+
case TimeUnit.DAYS => TimeRange(fin.length, TimeRange.DAYS)
74+
case TimeUnit.HOURS => TimeRange(fin.length,TimeRange.HOURS)
75+
case TimeUnit.MINUTES => TimeRange(fin.length,TimeRange.MINUTES)
76+
case TimeUnit.SECONDS => TimeRange(fin.length,TimeRange.SECONDS)
77+
case TimeUnit.MILLISECONDS => TimeRange(fin.length,TimeRange.MILLISECONDS)
78+
case _ =>
79+
TimeRange(fin.toMillis, TimeRange.MILLISECONDS)
80+
}
81+
82+
implicit def timeRangeToTemporalAmount(timeRange: TimeRange) : TemporalAmount = timeRange.unit match {
83+
case TimeRange.YEARS => Period.ofYears(timeRange.amount.toInt)
84+
case TimeRange.MONTHS =>Period.ofMonths(timeRange.amount.toInt)
85+
case TimeRange.WEEKS => Period.ofWeeks(timeRange.amount.toInt)
86+
case TimeRange.DAYS => Duration.ofDays(timeRange.amount)
87+
case TimeRange.HOURS => Duration.ofHours(timeRange.amount)
88+
case TimeRange.MINUTES => Duration.ofMinutes(timeRange.amount)
89+
case TimeRange.SECONDS => Duration.ofSeconds(timeRange.amount)
90+
case TimeRange.MILLISECONDS => Duration.ofMillis(timeRange.amount)
91+
}
6992
}

src/main/scala/io/waylay/kairosdb/driver/models/Aggregator.scala

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import io.waylay.kairosdb.driver.models.Aggregator.Trim.TrimWhat
44
import io.waylay.kairosdb.driver.models.RangeAggregator.Align
55
import io.waylay.kairosdb.driver.models.TimeSpan.AbsoluteStartTime
66

7-
import scala.concurrent.duration.{FiniteDuration, TimeUnit}
87
import scala.collection.immutable.Seq
8+
import scala.concurrent.duration.TimeUnit
99

1010
sealed trait Aggregator {
1111
val name: String
@@ -32,7 +32,7 @@ object RangeAggregator {
3232
/** Many of the aggregators inherit from the range aggregator */
3333
trait RangeAggregator extends Aggregator {
3434
/** Sampling is the length of the interval on which to aggregate data */
35-
val sampling: FiniteDuration
35+
val sampling: TimeRange
3636
val align: Option[Align]
3737
/** Start time to calculate the ranges from. Typically this is the start of the query. */
3838
val startTime: Option[AbsoluteStartTime]
@@ -44,53 +44,53 @@ object Aggregator {
4444

4545
// TODO why did we not use java.time.Duration instead of scala.concurrent.duration.Duration? We could introduce an implicit conversion
4646

47-
case class Average(sampling: FiniteDuration, startTime: Option[AbsoluteStartTime] = None, align: Option[Align] = None, timeZone: Option[String] = None)
47+
case class Average(sampling: TimeRange, startTime: Option[AbsoluteStartTime] = None, align: Option[Align] = None, timeZone: Option[String] = None)
4848
extends RangeAggregator {
4949
override val name = "avg"
5050
}
5151

5252
/** Computes standard deviation */
53-
case class StandardDeviation(sampling: FiniteDuration, startTime: Option[AbsoluteStartTime] = None, align: Option[Align] = None, timeZone: Option[String] = None)
53+
case class StandardDeviation(sampling: TimeRange, startTime: Option[AbsoluteStartTime] = None, align: Option[Align] = None, timeZone: Option[String] = None)
5454
extends RangeAggregator {
5555
override val name = "dev"
5656
}
5757

5858
/** Counts the number of data points */
59-
case class Count(sampling: FiniteDuration, startTime: Option[AbsoluteStartTime] = None, align: Option[Align] = None, timeZone: Option[String] = None)
59+
case class Count(sampling: TimeRange, startTime: Option[AbsoluteStartTime] = None, align: Option[Align] = None, timeZone: Option[String] = None)
6060
extends RangeAggregator {
6161
override val name = "count"
6262
}
6363

6464
/** Returns the first data point for the interval */
65-
case class First(sampling: FiniteDuration, startTime: Option[AbsoluteStartTime] = None, align: Option[Align] = None, timeZone: Option[String] = None)
65+
case class First(sampling: TimeRange, startTime: Option[AbsoluteStartTime] = None, align: Option[Align] = None, timeZone: Option[String] = None)
6666
extends RangeAggregator {
6767
override val name = "first"
6868
}
6969

7070
/** Marks gaps in data according to sampling rate with a null data point */
71-
case class Gaps(sampling: FiniteDuration, startTime: Option[AbsoluteStartTime] = None, align: Option[Align] = None, timeZone: Option[String] = None)
71+
case class Gaps(sampling: TimeRange, startTime: Option[AbsoluteStartTime] = None, align: Option[Align] = None, timeZone: Option[String] = None)
7272
extends RangeAggregator {
7373
override val name = "gaps"
7474
}
7575

7676
/** Returns the last data point for the interval */
77-
case class Last(sampling: FiniteDuration, startTime: Option[AbsoluteStartTime] = None, align: Option[Align] = None, timeZone: Option[String] = None)
77+
case class Last(sampling: TimeRange, startTime: Option[AbsoluteStartTime] = None, align: Option[Align] = None, timeZone: Option[String] = None)
7878
extends RangeAggregator {
7979
override val name = "last"
8080
}
8181

8282
/* Returns two points for the range which represent the best fit line through the set of points */
83-
case class LeastSquares(sampling: FiniteDuration, startTime: Option[AbsoluteStartTime] = None, align: Option[Align] = None, timeZone: Option[String] = None)
83+
case class LeastSquares(sampling: TimeRange, startTime: Option[AbsoluteStartTime] = None, align: Option[Align] = None, timeZone: Option[String] = None)
8484
extends RangeAggregator {
8585
override val name = "least_squares"
8686
}
8787

88-
case class Max(sampling: FiniteDuration, startTime: Option[AbsoluteStartTime] = None, align: Option[Align] = None, timeZone: Option[String] = None)
88+
case class Max(sampling: TimeRange, startTime: Option[AbsoluteStartTime] = None, align: Option[Align] = None, timeZone: Option[String] = None)
8989
extends RangeAggregator {
9090
override val name = "max"
9191
}
9292

93-
case class Min(sampling: FiniteDuration, startTime: Option[AbsoluteStartTime] = None, align: Option[Align] = None, timeZone: Option[String] = None)
93+
case class Min(sampling: TimeRange, startTime: Option[AbsoluteStartTime] = None, align: Option[Align] = None, timeZone: Option[String] = None)
9494
extends RangeAggregator {
9595
override val name = "min"
9696
}
@@ -100,13 +100,13 @@ object Aggregator {
100100
*
101101
* @param percentile Defined as 0 < percentile <= 1 where .5 is 50% and 1 is 100%
102102
*/
103-
case class Percentile(percentile: Double, sampling: FiniteDuration, startTime: Option[AbsoluteStartTime] = None, align: Option[Align] = None, timeZone: Option[String] = None)
103+
case class Percentile(percentile: Double, sampling: TimeRange, startTime: Option[AbsoluteStartTime] = None, align: Option[Align] = None, timeZone: Option[String] = None)
104104
extends RangeAggregator {
105105
override val name = "percentile"
106106
}
107107

108108
/** Sums all value */
109-
case class Sum(sampling: FiniteDuration, startTime: Option[AbsoluteStartTime] = None, align: Option[Align] = None, timeZone: Option[String] = None)
109+
case class Sum(sampling: TimeRange, startTime: Option[AbsoluteStartTime] = None, align: Option[Align] = None, timeZone: Option[String] = None)
110110
extends RangeAggregator {
111111
override val name = "sum"
112112
}
@@ -122,7 +122,7 @@ object Aggregator {
122122
}
123123

124124
/** Returns the rate of change between a pair of data points. Requires a “unit” property which is the sampling duration (ie rate in seconds, milliseconds, minutes, etc...). */
125-
case class Rate(unit: TimeUnit, sampling: FiniteDuration, timezone: Option[String]) extends Aggregator {
125+
case class Rate(unit: TimeUnit, sampling: TimeRange, timezone: Option[String]) extends Aggregator {
126126
override val name = "rate"
127127
}
128128

@@ -173,7 +173,7 @@ object Aggregator {
173173
* @param tags Additional tags to set on the metrics {"tag1":"value1","tag2":"value2"}
174174
* @param ttl Sets the ttl on the newly saved metrics
175175
*/
176-
case class SaveAs(metricName: MetricName, tags: Seq[Tag], ttl: FiniteDuration) extends Aggregator { // TODO ttl should be Option?
176+
case class SaveAs(metricName: MetricName, tags: Seq[Tag], ttl: TimeRange) extends Aggregator { // TODO ttl should be Option?
177177
override val name = "save_as"
178178
}
179179

src/main/scala/io/waylay/kairosdb/driver/models/GroupBy.scala

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package io.waylay.kairosdb.driver.models
22

3-
import scala.concurrent.duration.FiniteDuration
4-
53
sealed trait GroupBy {
64
val name: String
75
}
@@ -26,7 +24,7 @@ object GroupBy {
2624
* @param groupCount The number of groups. This would typically be 7 to group by day of week. But you could set this
2725
* to 14 to group by fortnight.
2826
*/
29-
case class GroupByTime(rangeSize: FiniteDuration, groupCount: Int) extends GroupBy {
27+
case class GroupByTime(rangeSize: TimeRange, groupCount: Int) extends GroupBy {
3028
override val name = "time"
3129
}
3230

src/main/scala/io/waylay/kairosdb/driver/models/Models.scala

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import java.time.Instant
55
import io.lemonlabs.uri.{Uri, Url}
66
import io.waylay.kairosdb.driver.models.KairosQuery.{Order, QueryTag}
77
import io.waylay.kairosdb.driver.models.QueryResponse.TagResult
8+
import io.waylay.kairosdb.driver.models.TimeRange.KairosTimeUnit
89

9-
import scala.concurrent.duration.FiniteDuration
1010
import scala.collection.immutable.Seq
1111
import scala.collection.compat._
1212

@@ -16,15 +16,28 @@ import scala.collection.compat._
1616
*/
1717
case class MetricName(name: String) extends AnyVal
1818

19+
object TimeRange {
20+
sealed trait KairosTimeUnit
21+
case object MILLISECONDS extends KairosTimeUnit
22+
case object SECONDS extends KairosTimeUnit
23+
case object MINUTES extends KairosTimeUnit
24+
case object HOURS extends KairosTimeUnit
25+
case object DAYS extends KairosTimeUnit
26+
case object WEEKS extends KairosTimeUnit
27+
case object MONTHS extends KairosTimeUnit
28+
case object YEARS extends KairosTimeUnit
29+
}
30+
case class TimeRange(amount: Long, unit: KairosTimeUnit)
31+
1932
sealed trait DataPoint {
2033
val metricName: MetricName
2134
val tags: Seq[Tag]
22-
val ttl: Option[FiniteDuration]
35+
val ttl: Option[TimeRange]
2336
}
2437

2538
object DataPoint {
2639
def apply(metricName: MetricName, value: KairosCompatibleType, timestamp: Instant = Instant.now, tags: Seq[Tag],
27-
ttl: Option[FiniteDuration] = None) = DataPointWithSingleValue(metricName, value, timestamp, tags, ttl)
40+
ttl: Option[TimeRange] = None) = DataPointWithSingleValue(metricName, value, timestamp, tags, ttl)
2841
}
2942

3043
/**
@@ -34,15 +47,15 @@ object DataPoint {
3447
*
3548
*/
3649
case class DataPointWithSingleValue(metricName: MetricName, value: KairosCompatibleType, timestamp: Instant,
37-
tags: Seq[Tag], ttl: Option[FiniteDuration] = None) extends DataPoint
50+
tags: Seq[Tag], ttl: Option[TimeRange] = None) extends DataPoint
3851

3952
/**
4053
* A data point has with metric name, a single value, a timestamp, and a list of one or more tags
4154
*
4255
* @param ttl Sets the Cassandra ttl for the data points. None or Some(0.seconds) will not set a TTL
4356
*/
4457
case class DataPointWithMultipleValues(metricName: MetricName, values: Seq[(Instant, KairosCompatibleType)],
45-
tags: Seq[Tag] = Seq.empty, ttl: Option[FiniteDuration] = None) extends DataPoint
58+
tags: Seq[Tag] = Seq.empty, ttl: Option[TimeRange] = None) extends DataPoint
4659

4760

4861
/**

src/main/scala/io/waylay/kairosdb/driver/models/TimeSpan.scala

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ package io.waylay.kairosdb.driver.models
22

33
import java.time.Instant
44

5+
import io.waylay.kairosdb.driver.Implicits
56
import io.waylay.kairosdb.driver.models.TimeSpan.{EndTime, StartTime}
67

7-
import scala.concurrent.duration._
8-
98
/**
109
* @param endTime If end time is None, the current date and time is assumed
1110
*/
@@ -30,22 +29,22 @@ object TimeSpan {
3029
override val fieldName = "start_absolute"
3130
override def toMillis = startTime.toEpochMilli
3231
}
33-
case class RelativeStartTime(howLongAgo: FiniteDuration) extends StartTime {
32+
case class RelativeStartTime(howLongAgo: TimeRange) extends StartTime {
3433
override val fieldName = "start_relative"
3534
override def toMillis: Long = toMillis(Instant.now)
3635

37-
def toMillis(reference: Instant) = reference.minusMillis(howLongAgo.toMillis).toEpochMilli
36+
def toMillis(reference: Instant) = reference.minus(Implicits.timeRangeToTemporalAmount(howLongAgo)).toEpochMilli
3837
}
3938

4039

4140
case class AbsoluteEndTime(endTime: Instant) extends EndTime {
4241
override val fieldName = "end_absolute"
4342
override def toMillis = endTime.toEpochMilli
4443
}
45-
case class RelativeEndTime(howLongAgo: FiniteDuration) extends EndTime {
44+
case class RelativeEndTime(howLongAgo: TimeRange) extends EndTime {
4645
override val fieldName = "end_relative"
4746
override def toMillis = toMillis(Instant.now)
4847

49-
def toMillis(reference: Instant) = reference.minusMillis(howLongAgo.toMillis).toEpochMilli
48+
def toMillis(reference: Instant) = reference.minus(Implicits.timeRangeToTemporalAmount(howLongAgo)).toEpochMilli
5049
}
5150
}

0 commit comments

Comments
 (0)