From 538b2fe72211e930c6bbcc7e0a8775ece00b6d38 Mon Sep 17 00:00:00 2001 From: mrzhao Date: Sun, 19 Jan 2020 20:07:11 +0800 Subject: [PATCH 01/25] InvertedMetric Implementation --- .../druidry/topNMetric/InvertedMetric.java | 34 +++++++++++++ .../druidry/topNMetric/SimpleMetric.java | 2 + .../druid/druidry/topNMetric/TopNMetric.java | 5 ++ .../topNMetric/InvertedMetricTest.java | 50 +++++++++++++++++++ 4 files changed, 91 insertions(+) create mode 100644 src/main/java/in/zapr/druid/druidry/topNMetric/InvertedMetric.java create mode 100644 src/test/java/in/zapr/druid/druidry/topNMetric/InvertedMetricTest.java diff --git a/src/main/java/in/zapr/druid/druidry/topNMetric/InvertedMetric.java b/src/main/java/in/zapr/druid/druidry/topNMetric/InvertedMetric.java new file mode 100644 index 00000000..4edf3a9e --- /dev/null +++ b/src/main/java/in/zapr/druid/druidry/topNMetric/InvertedMetric.java @@ -0,0 +1,34 @@ +/* + * Copyright 2018-present Red Brick Lane Marketing Solutions Pvt. Ltd. + * + * 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 in.zapr.druid.druidry.topNMetric; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NonNull; + +@Getter +@EqualsAndHashCode(callSuper = true) +public class InvertedMetric extends TopNMetric { + private static String INVERTED_METRIC_TYPE = "inverted"; + + private TopNMetric metric; + private String type = INVERTED_METRIC_TYPE; + + public InvertedMetric(@NonNull TopNMetric topNMetric) { + this.metric = topNMetric; + } +} \ No newline at end of file diff --git a/src/main/java/in/zapr/druid/druidry/topNMetric/SimpleMetric.java b/src/main/java/in/zapr/druid/druidry/topNMetric/SimpleMetric.java index 2d95b9d3..3dc5efb2 100644 --- a/src/main/java/in/zapr/druid/druidry/topNMetric/SimpleMetric.java +++ b/src/main/java/in/zapr/druid/druidry/topNMetric/SimpleMetric.java @@ -17,7 +17,9 @@ package in.zapr.druid.druidry.topNMetric; import com.fasterxml.jackson.annotation.JsonValue; +import lombok.EqualsAndHashCode; +@EqualsAndHashCode(callSuper = true) public class SimpleMetric extends TopNMetric { private String metric; diff --git a/src/main/java/in/zapr/druid/druidry/topNMetric/TopNMetric.java b/src/main/java/in/zapr/druid/druidry/topNMetric/TopNMetric.java index d09490aa..7c59f9ac 100644 --- a/src/main/java/in/zapr/druid/druidry/topNMetric/TopNMetric.java +++ b/src/main/java/in/zapr/druid/druidry/topNMetric/TopNMetric.java @@ -16,5 +16,10 @@ package in.zapr.druid.druidry.topNMetric; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +@Getter +@EqualsAndHashCode public abstract class TopNMetric { } diff --git a/src/test/java/in/zapr/druid/druidry/topNMetric/InvertedMetricTest.java b/src/test/java/in/zapr/druid/druidry/topNMetric/InvertedMetricTest.java new file mode 100644 index 00000000..c3d33900 --- /dev/null +++ b/src/test/java/in/zapr/druid/druidry/topNMetric/InvertedMetricTest.java @@ -0,0 +1,50 @@ +package in.zapr.druid.druidry.topNMetric; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.json.JSONException; +import org.skyscreamer.jsonassert.JSONAssert; +import org.skyscreamer.jsonassert.JSONCompareMode; +import org.testng.Assert; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +@Slf4j +public class InvertedMetricTest { + private static ObjectMapper objectMapper; + + @BeforeClass + public void init() { + objectMapper = new ObjectMapper(); + } + + @Test + public void testAllFields() throws JsonProcessingException, JSONException { + InvertedMetric invertedMetric = new InvertedMetric(new SimpleMetric("count")); + String actualJSON = objectMapper.writeValueAsString(invertedMetric); + String expectedJson = "{\"metric\":\"count\",\"type\":\"inverted\"}"; + JSONAssert.assertEquals(expectedJson, actualJSON, JSONCompareMode.NON_EXTENSIBLE); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testMetricMissingFields() { + new InvertedMetric(null); + } + + @Test + public void testEqualsPositive() { + InvertedMetric invertedMetric1 = new InvertedMetric(new SimpleMetric("count")); + InvertedMetric invertedMetric2 = new InvertedMetric(new SimpleMetric("count")); + + Assert.assertEquals(invertedMetric1, invertedMetric2); + } + + @Test + public void testEqualsNegative() { + InvertedMetric invertedMetric1 = new InvertedMetric(new SimpleMetric("sum")); + InvertedMetric invertedMetric2 = new InvertedMetric(new SimpleMetric("count")); + + Assert.assertNotEquals(invertedMetric1, invertedMetric2); + } +} From 72f438c38ece8f1a6f9b79cac9643497ecc0130e Mon Sep 17 00:00:00 2001 From: Jonasz Czerepko Date: Fri, 28 Feb 2020 06:22:28 +0100 Subject: [PATCH 02/25] Added deprecation of select query, since it has been removed in Druid version 0.17.0. https://druid.apache.org/docs/latest/querying/select-query.html --- src/main/java/in/zapr/druid/druidry/query/QueryType.java | 1 + .../in/zapr/druid/druidry/query/select/DruidSelectQuery.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/main/java/in/zapr/druid/druidry/query/QueryType.java b/src/main/java/in/zapr/druid/druidry/query/QueryType.java index 1e844a78..5950b2b0 100644 --- a/src/main/java/in/zapr/druid/druidry/query/QueryType.java +++ b/src/main/java/in/zapr/druid/druidry/query/QueryType.java @@ -28,6 +28,7 @@ public enum QueryType { DATASOURCE_METADATA("dataSourceMetadata"), SEARCH("search"), SCAN("scan"), + @Deprecated SELECT("select"); private String value; diff --git a/src/main/java/in/zapr/druid/druidry/query/select/DruidSelectQuery.java b/src/main/java/in/zapr/druid/druidry/query/select/DruidSelectQuery.java index 1b57c000..60390ef8 100644 --- a/src/main/java/in/zapr/druid/druidry/query/select/DruidSelectQuery.java +++ b/src/main/java/in/zapr/druid/druidry/query/select/DruidSelectQuery.java @@ -39,6 +39,7 @@ @Getter @JsonInclude(JsonInclude.Include.NON_NULL) @EqualsAndHashCode(callSuper = true) +@Deprecated public class DruidSelectQuery extends DruidQuery { private List intervals; private List virtualColumns; From 8007fc7f0bdc8264b49aa0becf943347612c1eac Mon Sep 17 00:00:00 2001 From: Abhi <43852557+abhi-zapr@users.noreply.github.com> Date: Sat, 29 Feb 2020 18:41:17 +0530 Subject: [PATCH 03/25] Preparing for next release 3.1-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6b56d2ae..e442e540 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ in.zapr.druid druidry - 3.0 + 3.1-SNAPSHOT Druidry - Druid Java Client Druidry is an open-source Java based utility library which supports creating From c60b2b8681824a825985d4f8a2c88bf71b21a584 Mon Sep 17 00:00:00 2001 From: Abhi <43852557+abhi-zapr@users.noreply.github.com> Date: Sat, 29 Feb 2020 18:55:28 +0530 Subject: [PATCH 04/25] Adding Javadoc badge --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6fba2a59..2372a688 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ Welcome to project Druidry! ======================================= -![build_status](https://api.travis-ci.org/zapr-oss/druidry.svg?branch=master) [![License: Apache License 2](https://img.shields.io/badge/license-Apache%202-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0.txt) +![build_status](https://api.travis-ci.org/zapr-oss/druidry.svg?branch=master) [![License: Apache License 2](https://img.shields.io/badge/license-Apache%202-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0.txt) [![javadoc](https://javadoc.io/badge2/in.zapr.druid/druidry/javadoc.svg)](https://javadoc.io/doc/in.zapr.druid/druidry) -Druid is an extremely popular tool to perform OLAP queries on event data. Druid drives real-time dashboards in most of the organisations right now. We@Zapr love Druid! Therefore we want to contribute towards making Druid, even more, friendlier to the ever expanding community. +Druid is an extremely popular tool to perform OLAP queries on event data. Druid drives real-time dashboards in most of the organisations right now. We@Zapr love Druid! Therefore we want to contribute towards making Druid, even more, friendlier to the ever expanding community. We want to make the process of deep meaningful conversations with Druid little easier. What do we mean is that we don’t want developers to write big, scary JSON anymore but instead use a simple Java-based query generator to help with the querying. @@ -269,4 +269,4 @@ Contact For any features or bugs, please raise it in issues section -If anything else, get in touch with us at [opensource@zapr.in](opensource@zapr.in) \ No newline at end of file +If anything else, get in touch with us at [opensource@zapr.in](opensource@zapr.in) From b6254a3361d8207572c66dbc41e84f105950c340 Mon Sep 17 00:00:00 2001 From: Jonasz Czerepko Date: Sun, 1 Mar 2020 08:18:37 +0100 Subject: [PATCH 05/25] Added support for automatic resource management for Client - it implements AutoCloseable now. --- .../druid/druidry/client/DruidClient.java | 2 +- .../druid/druidry/client/DruidClientTest.java | 48 +++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 src/test/java/in/zapr/druid/druidry/client/DruidClientTest.java diff --git a/src/main/java/in/zapr/druid/druidry/client/DruidClient.java b/src/main/java/in/zapr/druid/druidry/client/DruidClient.java index b91f4899..430638fe 100644 --- a/src/main/java/in/zapr/druid/druidry/client/DruidClient.java +++ b/src/main/java/in/zapr/druid/druidry/client/DruidClient.java @@ -22,7 +22,7 @@ import in.zapr.druid.druidry.client.exception.QueryException; import in.zapr.druid.druidry.query.DruidQuery; -public interface DruidClient { +public interface DruidClient extends AutoCloseable { /** * Connects with Druid diff --git a/src/test/java/in/zapr/druid/druidry/client/DruidClientTest.java b/src/test/java/in/zapr/druid/druidry/client/DruidClientTest.java new file mode 100644 index 00000000..118dd800 --- /dev/null +++ b/src/test/java/in/zapr/druid/druidry/client/DruidClientTest.java @@ -0,0 +1,48 @@ +package in.zapr.druid.druidry.client; + +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +import in.zapr.druid.druidry.query.DruidQuery; +import org.testng.annotations.Test; + +import java.util.List; + +public class DruidClientTest { + + private boolean wasClientClosed; + + @Test + public void testAutoClosing() { + assertFalse(wasClientClosed, "Client closing indicator is not initialized properly"); + try (TestDruidClient client = new TestDruidClient()) { + client.connect(); + } + assertTrue(wasClientClosed, "Close method has not been called"); + } + + private class TestDruidClient implements DruidClient { + + @Override + public void connect() { + + } + + @Override + public void close() { + wasClientClosed = true; + } + + @Override + public String query(DruidQuery druidQuery) { + return null; + } + + @Override + public List query(DruidQuery druidQuery, Class className) { + return null; + } + + } + +} From 82ccc02190b2557321bece619e73b02edca2ed33 Mon Sep 17 00:00:00 2001 From: Jonasz Czerepko Date: Fri, 28 Feb 2020 06:11:06 +0100 Subject: [PATCH 06/25] Added support for movingAverage query: https://druid.apache.org/docs/latest/development/extensions-contrib/moving-average-query.html --- .../druidry/averager/DoubleMaxAverager.java | 21 +++ .../druidry/averager/DoubleMeanAverager.java | 21 +++ .../averager/DoubleMeanNoNullsAverager.java | 21 +++ .../druidry/averager/DoubleMinAverager.java | 21 +++ .../druidry/averager/DoubleSumAverager.java | 21 +++ .../druid/druidry/averager/DruidAverager.java | 25 +++ .../druidry/averager/LongMaxAverager.java | 21 +++ .../druidry/averager/LongMeanAverager.java | 21 +++ .../averager/LongMeanNoNullsAverager.java | 21 +++ .../druidry/averager/LongMinAverager.java | 21 +++ .../druidry/averager/LongSumAverager.java | 21 +++ .../zapr/druid/druidry/query/QueryType.java | 3 +- .../aggregation/DruidMovingAverageQuery.java | 63 +++++++ .../query/aggregation/MovingAverageTest.java | 168 ++++++++++++++++++ .../aggregation/moving_average/allFields.json | 64 +++++++ .../averager_type/doubleMax.json | 26 +++ .../averager_type/doubleMean.json | 26 +++ .../averager_type/doubleMeanNoNulls.json | 26 +++ .../averager_type/doubleMin.json | 26 +++ .../averager_type/doubleSum.json | 26 +++ .../moving_average/averager_type/longMax.json | 26 +++ .../averager_type/longMean.json | 26 +++ .../averager_type/longMeanNoNulls.json | 26 +++ .../moving_average/averager_type/longMin.json | 26 +++ .../moving_average/averager_type/longSum.json | 26 +++ .../aggregation/moving_average/simple.json | 26 +++ 26 files changed, 818 insertions(+), 1 deletion(-) create mode 100644 src/main/java/in/zapr/druid/druidry/averager/DoubleMaxAverager.java create mode 100644 src/main/java/in/zapr/druid/druidry/averager/DoubleMeanAverager.java create mode 100644 src/main/java/in/zapr/druid/druidry/averager/DoubleMeanNoNullsAverager.java create mode 100644 src/main/java/in/zapr/druid/druidry/averager/DoubleMinAverager.java create mode 100644 src/main/java/in/zapr/druid/druidry/averager/DoubleSumAverager.java create mode 100644 src/main/java/in/zapr/druid/druidry/averager/DruidAverager.java create mode 100644 src/main/java/in/zapr/druid/druidry/averager/LongMaxAverager.java create mode 100644 src/main/java/in/zapr/druid/druidry/averager/LongMeanAverager.java create mode 100644 src/main/java/in/zapr/druid/druidry/averager/LongMeanNoNullsAverager.java create mode 100644 src/main/java/in/zapr/druid/druidry/averager/LongMinAverager.java create mode 100644 src/main/java/in/zapr/druid/druidry/averager/LongSumAverager.java create mode 100644 src/main/java/in/zapr/druid/druidry/query/aggregation/DruidMovingAverageQuery.java create mode 100644 src/test/java/in/zapr/druid/druidry/query/aggregation/MovingAverageTest.java create mode 100644 src/test/resources/query/aggregation/moving_average/allFields.json create mode 100644 src/test/resources/query/aggregation/moving_average/averager_type/doubleMax.json create mode 100644 src/test/resources/query/aggregation/moving_average/averager_type/doubleMean.json create mode 100644 src/test/resources/query/aggregation/moving_average/averager_type/doubleMeanNoNulls.json create mode 100644 src/test/resources/query/aggregation/moving_average/averager_type/doubleMin.json create mode 100644 src/test/resources/query/aggregation/moving_average/averager_type/doubleSum.json create mode 100644 src/test/resources/query/aggregation/moving_average/averager_type/longMax.json create mode 100644 src/test/resources/query/aggregation/moving_average/averager_type/longMean.json create mode 100644 src/test/resources/query/aggregation/moving_average/averager_type/longMeanNoNulls.json create mode 100644 src/test/resources/query/aggregation/moving_average/averager_type/longMin.json create mode 100644 src/test/resources/query/aggregation/moving_average/averager_type/longSum.json create mode 100644 src/test/resources/query/aggregation/moving_average/simple.json diff --git a/src/main/java/in/zapr/druid/druidry/averager/DoubleMaxAverager.java b/src/main/java/in/zapr/druid/druidry/averager/DoubleMaxAverager.java new file mode 100644 index 00000000..9e90f626 --- /dev/null +++ b/src/main/java/in/zapr/druid/druidry/averager/DoubleMaxAverager.java @@ -0,0 +1,21 @@ +package in.zapr.druid.druidry.averager; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NonNull; + +@Getter +@EqualsAndHashCode(callSuper = true) +public class DoubleMaxAverager extends DruidAverager { + + private static final String DOUBLE_MAX_AVERAGER = "doubleMax"; + + public DoubleMaxAverager(@NonNull String name, @NonNull String fieldName, @NonNull Integer buckets) { + this(name, fieldName, buckets, null); + } + + public DoubleMaxAverager(String name, String fieldName, Integer buckets, Integer cycleSize) { + super(DOUBLE_MAX_AVERAGER, name, fieldName, buckets, cycleSize); + } + +} diff --git a/src/main/java/in/zapr/druid/druidry/averager/DoubleMeanAverager.java b/src/main/java/in/zapr/druid/druidry/averager/DoubleMeanAverager.java new file mode 100644 index 00000000..e2f5cd48 --- /dev/null +++ b/src/main/java/in/zapr/druid/druidry/averager/DoubleMeanAverager.java @@ -0,0 +1,21 @@ +package in.zapr.druid.druidry.averager; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NonNull; + +@Getter +@EqualsAndHashCode(callSuper = true) +public class DoubleMeanAverager extends DruidAverager { + + private static final String DOUBLE_MEAN_AVERAGER = "doubleMean"; + + public DoubleMeanAverager(@NonNull String name, @NonNull String fieldName, @NonNull Integer buckets) { + this(name, fieldName, buckets, null); + } + + public DoubleMeanAverager(String name, String fieldName, Integer buckets, Integer cycleSize) { + super(DOUBLE_MEAN_AVERAGER, name, fieldName, buckets, cycleSize); + } + +} diff --git a/src/main/java/in/zapr/druid/druidry/averager/DoubleMeanNoNullsAverager.java b/src/main/java/in/zapr/druid/druidry/averager/DoubleMeanNoNullsAverager.java new file mode 100644 index 00000000..de26216e --- /dev/null +++ b/src/main/java/in/zapr/druid/druidry/averager/DoubleMeanNoNullsAverager.java @@ -0,0 +1,21 @@ +package in.zapr.druid.druidry.averager; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NonNull; + +@Getter +@EqualsAndHashCode(callSuper = true) +public class DoubleMeanNoNullsAverager extends DruidAverager { + + private static final String DOUBLE_MEAN_NO_NULLS_AVERAGER = "doubleMeanNoNulls"; + + public DoubleMeanNoNullsAverager(@NonNull String name, @NonNull String fieldName, @NonNull Integer buckets) { + this(name, fieldName, buckets, null); + } + + public DoubleMeanNoNullsAverager(String name, String fieldName, Integer buckets, Integer cycleSize) { + super(DOUBLE_MEAN_NO_NULLS_AVERAGER, name, fieldName, buckets, cycleSize); + } + +} diff --git a/src/main/java/in/zapr/druid/druidry/averager/DoubleMinAverager.java b/src/main/java/in/zapr/druid/druidry/averager/DoubleMinAverager.java new file mode 100644 index 00000000..70ac3457 --- /dev/null +++ b/src/main/java/in/zapr/druid/druidry/averager/DoubleMinAverager.java @@ -0,0 +1,21 @@ +package in.zapr.druid.druidry.averager; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NonNull; + +@Getter +@EqualsAndHashCode(callSuper = true) +public class DoubleMinAverager extends DruidAverager { + + private static final String DOUBLE_MIN_AVERAGER = "doubleMin"; + + public DoubleMinAverager(@NonNull String name, @NonNull String fieldName, @NonNull Integer buckets) { + this(name, fieldName, buckets, null); + } + + public DoubleMinAverager(String name, String fieldName, Integer buckets, Integer cycleSize) { + super(DOUBLE_MIN_AVERAGER, name, fieldName, buckets, cycleSize); + } + +} diff --git a/src/main/java/in/zapr/druid/druidry/averager/DoubleSumAverager.java b/src/main/java/in/zapr/druid/druidry/averager/DoubleSumAverager.java new file mode 100644 index 00000000..50696f71 --- /dev/null +++ b/src/main/java/in/zapr/druid/druidry/averager/DoubleSumAverager.java @@ -0,0 +1,21 @@ +package in.zapr.druid.druidry.averager; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NonNull; + +@Getter +@EqualsAndHashCode(callSuper = true) +public class DoubleSumAverager extends DruidAverager { + + private static final String DOUBLE_SUM_AVERAGER = "doubleSum"; + + public DoubleSumAverager(@NonNull String name, @NonNull String fieldName, @NonNull Integer buckets) { + this(name, fieldName, buckets, null); + } + + public DoubleSumAverager(String name, String fieldName, Integer buckets, Integer cycleSize) { + super(DOUBLE_SUM_AVERAGER, name, fieldName, buckets, cycleSize); + } + +} diff --git a/src/main/java/in/zapr/druid/druidry/averager/DruidAverager.java b/src/main/java/in/zapr/druid/druidry/averager/DruidAverager.java new file mode 100644 index 00000000..cda43315 --- /dev/null +++ b/src/main/java/in/zapr/druid/druidry/averager/DruidAverager.java @@ -0,0 +1,25 @@ +package in.zapr.druid.druidry.averager; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NonNull; + +@Getter +@EqualsAndHashCode +@AllArgsConstructor +public abstract class DruidAverager { + + @NonNull + String type; + @NonNull + String name; + @NonNull + String fieldName; + @NonNull + Integer buckets; + @JsonInclude(JsonInclude.Include.NON_NULL) + Integer cycleSize; + +} diff --git a/src/main/java/in/zapr/druid/druidry/averager/LongMaxAverager.java b/src/main/java/in/zapr/druid/druidry/averager/LongMaxAverager.java new file mode 100644 index 00000000..37574086 --- /dev/null +++ b/src/main/java/in/zapr/druid/druidry/averager/LongMaxAverager.java @@ -0,0 +1,21 @@ +package in.zapr.druid.druidry.averager; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NonNull; + +@Getter +@EqualsAndHashCode(callSuper = true) +public class LongMaxAverager extends DruidAverager { + + private static final String LONG_MAX_AVERAGER = "longMax"; + + public LongMaxAverager(@NonNull String name, @NonNull String fieldName, @NonNull Integer buckets) { + this(name, fieldName, buckets, null); + } + + public LongMaxAverager(String name, String fieldName, Integer buckets, Integer cycleSize) { + super(LONG_MAX_AVERAGER, name, fieldName, buckets, cycleSize); + } + +} diff --git a/src/main/java/in/zapr/druid/druidry/averager/LongMeanAverager.java b/src/main/java/in/zapr/druid/druidry/averager/LongMeanAverager.java new file mode 100644 index 00000000..d23bf8db --- /dev/null +++ b/src/main/java/in/zapr/druid/druidry/averager/LongMeanAverager.java @@ -0,0 +1,21 @@ +package in.zapr.druid.druidry.averager; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NonNull; + +@Getter +@EqualsAndHashCode(callSuper = true) +public class LongMeanAverager extends DruidAverager { + + private static final String LONG_MEAN_AVERAGER = "longMean"; + + public LongMeanAverager(@NonNull String name, @NonNull String fieldName, @NonNull Integer buckets) { + this(name, fieldName, buckets, null); + } + + public LongMeanAverager(String name, String fieldName, Integer buckets, Integer cycleSize) { + super(LONG_MEAN_AVERAGER, name, fieldName, buckets, cycleSize); + } + +} diff --git a/src/main/java/in/zapr/druid/druidry/averager/LongMeanNoNullsAverager.java b/src/main/java/in/zapr/druid/druidry/averager/LongMeanNoNullsAverager.java new file mode 100644 index 00000000..be9fb7f2 --- /dev/null +++ b/src/main/java/in/zapr/druid/druidry/averager/LongMeanNoNullsAverager.java @@ -0,0 +1,21 @@ +package in.zapr.druid.druidry.averager; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NonNull; + +@Getter +@EqualsAndHashCode(callSuper = true) +public class LongMeanNoNullsAverager extends DruidAverager { + + private static final String LONG_MEAN_NO_NULLS_AVERAGER = "longMeanNoNulls"; + + public LongMeanNoNullsAverager(@NonNull String name, @NonNull String fieldName, @NonNull Integer buckets) { + this(name, fieldName, buckets, null); + } + + public LongMeanNoNullsAverager(String name, String fieldName, Integer buckets, Integer cycleSize) { + super(LONG_MEAN_NO_NULLS_AVERAGER, name, fieldName, buckets, cycleSize); + } + +} diff --git a/src/main/java/in/zapr/druid/druidry/averager/LongMinAverager.java b/src/main/java/in/zapr/druid/druidry/averager/LongMinAverager.java new file mode 100644 index 00000000..05d2faad --- /dev/null +++ b/src/main/java/in/zapr/druid/druidry/averager/LongMinAverager.java @@ -0,0 +1,21 @@ +package in.zapr.druid.druidry.averager; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NonNull; + +@Getter +@EqualsAndHashCode(callSuper = true) +public class LongMinAverager extends DruidAverager { + + private static final String LONG_MIN_AVERAGER = "longMin"; + + public LongMinAverager(@NonNull String name, @NonNull String fieldName, @NonNull Integer buckets) { + this(name, fieldName, buckets, null); + } + + public LongMinAverager(String name, String fieldName, Integer buckets, Integer cycleSize) { + super(LONG_MIN_AVERAGER, name, fieldName, buckets, cycleSize); + } + +} diff --git a/src/main/java/in/zapr/druid/druidry/averager/LongSumAverager.java b/src/main/java/in/zapr/druid/druidry/averager/LongSumAverager.java new file mode 100644 index 00000000..bbad0abd --- /dev/null +++ b/src/main/java/in/zapr/druid/druidry/averager/LongSumAverager.java @@ -0,0 +1,21 @@ +package in.zapr.druid.druidry.averager; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NonNull; + +@Getter +@EqualsAndHashCode(callSuper = true) +public class LongSumAverager extends DruidAverager { + + private static final String LONG_SUM_AVERAGER = "longSum"; + + public LongSumAverager(@NonNull String name, @NonNull String fieldName, @NonNull Integer buckets) { + this(name, fieldName, buckets, null); + } + + public LongSumAverager(String name, String fieldName, Integer buckets, Integer cycleSize) { + super(LONG_SUM_AVERAGER, name, fieldName, buckets, cycleSize); + } + +} diff --git a/src/main/java/in/zapr/druid/druidry/query/QueryType.java b/src/main/java/in/zapr/druid/druidry/query/QueryType.java index 1e844a78..6cb64ac0 100644 --- a/src/main/java/in/zapr/druid/druidry/query/QueryType.java +++ b/src/main/java/in/zapr/druid/druidry/query/QueryType.java @@ -28,7 +28,8 @@ public enum QueryType { DATASOURCE_METADATA("dataSourceMetadata"), SEARCH("search"), SCAN("scan"), - SELECT("select"); + SELECT("select"), + MOVING_AVERAGE("movingAverage"); private String value; diff --git a/src/main/java/in/zapr/druid/druidry/query/aggregation/DruidMovingAverageQuery.java b/src/main/java/in/zapr/druid/druidry/query/aggregation/DruidMovingAverageQuery.java new file mode 100644 index 00000000..246994b1 --- /dev/null +++ b/src/main/java/in/zapr/druid/druidry/query/aggregation/DruidMovingAverageQuery.java @@ -0,0 +1,63 @@ +package in.zapr.druid.druidry.query.aggregation; + +import com.fasterxml.jackson.annotation.JsonInclude; +import in.zapr.druid.druidry.aggregator.DruidAggregator; +import in.zapr.druid.druidry.averager.DruidAverager; +import in.zapr.druid.druidry.dataSource.DataSource; +import in.zapr.druid.druidry.dimension.DruidDimension; +import in.zapr.druid.druidry.filter.DruidFilter; +import in.zapr.druid.druidry.filter.havingSpec.HavingSpec; +import in.zapr.druid.druidry.granularity.Granularity; +import in.zapr.druid.druidry.limitSpec.DefaultLimitSpec; +import in.zapr.druid.druidry.postAggregator.DruidPostAggregator; +import in.zapr.druid.druidry.query.QueryType; +import in.zapr.druid.druidry.query.config.Context; +import in.zapr.druid.druidry.query.config.Interval; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NonNull; + +import java.util.List; + +@Getter +@JsonInclude(JsonInclude.Include.NON_NULL) +@EqualsAndHashCode(callSuper = true) +public class DruidMovingAverageQuery extends DruidAggregationQuery { + + private List dimensions; + private DefaultLimitSpec limitSpec; + private HavingSpec having; + private List averagers; + private List postAveragers; + + @Builder + private DruidMovingAverageQuery(@NonNull DataSource dataSource, + List dimensions, + DefaultLimitSpec limitSpec, + @NonNull Granularity granularity, + DruidFilter filter, + @NonNull List aggregations, + List postAggregations, + HavingSpec having, + @NonNull List intervals, + Context context, + @NonNull List averagers, + List postAveragers) { + + queryType = QueryType.MOVING_AVERAGE; + this.dataSource = dataSource; + this.dimensions = dimensions; + this.limitSpec = limitSpec; + this.having = having; + this.granularity = granularity; + this.filter = filter; + this.aggregations = aggregations; + this.postAggregations = postAggregations; + this.intervals = intervals; + this.context = context; + this.averagers = averagers; + this.postAveragers = postAveragers; + } + +} diff --git a/src/test/java/in/zapr/druid/druidry/query/aggregation/MovingAverageTest.java b/src/test/java/in/zapr/druid/druidry/query/aggregation/MovingAverageTest.java new file mode 100644 index 00000000..ba8e3975 --- /dev/null +++ b/src/test/java/in/zapr/druid/druidry/query/aggregation/MovingAverageTest.java @@ -0,0 +1,168 @@ +package in.zapr.druid.druidry.query.aggregation; + +import static com.google.common.collect.ImmutableList.of; +import static java.util.Collections.singletonList; +import static org.testng.Assert.assertTrue; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.io.Resources; +import in.zapr.druid.druidry.aggregator.DoubleSumAggregator; +import in.zapr.druid.druidry.aggregator.DruidAggregator; +import in.zapr.druid.druidry.averager.DoubleMaxAverager; +import in.zapr.druid.druidry.averager.DoubleMeanAverager; +import in.zapr.druid.druidry.averager.DoubleMeanNoNullsAverager; +import in.zapr.druid.druidry.averager.DoubleMinAverager; +import in.zapr.druid.druidry.averager.DoubleSumAverager; +import in.zapr.druid.druidry.averager.DruidAverager; +import in.zapr.druid.druidry.averager.LongMaxAverager; +import in.zapr.druid.druidry.averager.LongMeanAverager; +import in.zapr.druid.druidry.averager.LongMeanNoNullsAverager; +import in.zapr.druid.druidry.averager.LongMinAverager; +import in.zapr.druid.druidry.averager.LongSumAverager; +import in.zapr.druid.druidry.dataSource.TableDataSource; +import in.zapr.druid.druidry.dimension.DruidDimension; +import in.zapr.druid.druidry.dimension.SimpleDimension; +import in.zapr.druid.druidry.filter.SelectorFilter; +import in.zapr.druid.druidry.filter.havingSpec.EqualToHaving; +import in.zapr.druid.druidry.granularity.PredefinedGranularity; +import in.zapr.druid.druidry.granularity.SimpleGranularity; +import in.zapr.druid.druidry.limitSpec.DefaultLimitSpec; +import in.zapr.druid.druidry.limitSpec.orderByColumnSpec.OrderByColumnSpecString; +import in.zapr.druid.druidry.postAggregator.DruidPostAggregator; +import in.zapr.druid.druidry.postAggregator.FieldAccessPostAggregator; +import in.zapr.druid.druidry.query.config.Context; +import in.zapr.druid.druidry.query.config.Interval; +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.skyscreamer.jsonassert.JSONAssert; +import org.skyscreamer.jsonassert.JSONCompareMode; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.testng.reporters.Files; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +public class MovingAverageTest { + + private static ObjectMapper objectMapper; + + @BeforeClass + public void init() { + objectMapper = new ObjectMapper(); + } + + @Test + public void testSimpleQuery() throws Exception { + String expectedJson = loadExpectedJson("simple.json"); + + DruidMovingAverageQuery query = simpleQuery(DoubleMeanAverager::new); + + String actualJson = objectMapper.writeValueAsString(query); + JSONAssert.assertEquals(actualJson, expectedJson, JSONCompareMode.NON_EXTENSIBLE); + } + + @Test + public void testAllFieldsQuery() throws Exception { + String expectedJson = loadExpectedJson("allFields.json"); + DruidDimension druidDimension1 = new SimpleDimension("dimension_1"); + DruidDimension druidDimension2 = new SimpleDimension("dimension_2"); + DefaultLimitSpec limitSpec = new DefaultLimitSpec(5000, of(new OrderByColumnSpecString("column_1"), + new OrderByColumnSpecString("column_2"))); + DateTime startTime = new DateTime(2020, 2, 1, 0, 0, 0, DateTimeZone.UTC); + DateTime endTime = new DateTime(2020, 3, 31, 23, 59, 59, DateTimeZone.UTC); + Interval interval = new Interval(startTime, endTime); + String averagedName = "averagedName"; + DruidAggregator aggregator = new DoubleSumAggregator(averagedName, "aggregatedFieldName"); + DruidPostAggregator postAggregator = new FieldAccessPostAggregator("postAggregatedFieldName"); + Context context = Context.builder().useCache(true).build(); + DruidAverager averager = new DoubleMeanAverager("averagingResult", averagedName, 60, 5); + DruidPostAggregator postAverager = new FieldAccessPostAggregator("postAveragedFieldName"); + + DruidMovingAverageQuery query = DruidMovingAverageQuery.builder() + .dataSource(new TableDataSource("allFieldsDataSource")) + .dimensions(of(druidDimension1, druidDimension2)) + .limitSpec(limitSpec) + .having(new EqualToHaving("havingField", 5)) + .granularity(new SimpleGranularity(PredefinedGranularity.FIFTEEN_MINUTE)) + .filter(new SelectorFilter("selectorField", "selectorValue")) + .aggregations(singletonList(aggregator)) + .postAggregations(singletonList(postAggregator)) + .intervals(singletonList(interval)) + .context(context) + .averagers(singletonList(averager)) + .postAveragers(singletonList(postAverager)) + .build(); + + String actualJson = objectMapper.writeValueAsString(query); + JSONAssert.assertEquals(actualJson, expectedJson, JSONCompareMode.NON_EXTENSIBLE); + } + + @Test(dataProvider = "averagerTypesProvider") + public void testAllAveragerTypes(String averagerName, TriFunction averagerCreator) + throws Exception { + String expectedJson = loadExpectedJsonForType(averagerName); + + DruidMovingAverageQuery query = simpleQuery(averagerCreator); + + String actualJson = objectMapper.writeValueAsString(query); + JSONAssert.assertEquals(actualJson, expectedJson, JSONCompareMode.NON_EXTENSIBLE); + } + + @DataProvider(name = "averagerTypesProvider") + private static Object[][] averagerTypesProvider() { + return new Object[][] { + { "doubleMax", (TriFunction) DoubleMaxAverager::new }, + { "doubleMean", (TriFunction) DoubleMeanAverager::new }, + { "doubleMeanNoNulls", (TriFunction) DoubleMeanNoNullsAverager::new }, + { "doubleMin", (TriFunction) DoubleMinAverager::new }, + { "doubleSum", (TriFunction) DoubleSumAverager::new }, + { "longMax", (TriFunction) LongMaxAverager::new }, + { "longMean", (TriFunction) LongMeanAverager::new }, + { "longMeanNoNulls", (TriFunction) LongMeanNoNullsAverager::new }, + { "longMin", (TriFunction) LongMinAverager::new }, + { "longSum", (TriFunction) LongSumAverager::new } + }; + } + + private String loadExpectedJsonForType(String type) throws IOException, URISyntaxException { + String json = loadExpectedJson("averager_type/" + type + ".json"); + assertTrue(json.contains(String.format("\"type\": \"%s\"", type))); + return json; + } + + @SuppressWarnings("UnstableApiUsage") + private String loadExpectedJson(String fileName) throws IOException, URISyntaxException { + URI jsonUri = Resources.getResource("query/aggregation/moving_average/" + fileName).toURI(); + File jsonFile = new File(jsonUri); + return Files.readFile(jsonFile); + } + + private static DruidMovingAverageQuery simpleQuery(TriFunction averagerCreator) { + DateTime startTime = new DateTime(2020, 1, 1, 0, 0, 0, DateTimeZone.UTC); + DateTime endTime = new DateTime(2020, 2, 29, 23, 59, 59, DateTimeZone.UTC); + Interval interval = new Interval(startTime, endTime); + String averagedName = "averagedName"; + DruidAggregator aggregator = new DoubleSumAggregator(averagedName, "aggregatedFieldName"); + DruidAverager averager = averagerCreator.apply("averagingResult", averagedName, 31); + + return DruidMovingAverageQuery.builder() + .dataSource(new TableDataSource("simpleDataSource")) + .granularity(new SimpleGranularity(PredefinedGranularity.DAY)) + .aggregations(singletonList(aggregator)) + .intervals(singletonList(interval)) + .averagers(singletonList(averager)) + .build(); + } + + @FunctionalInterface + private interface TriFunction { + + T apply(V1 v1, V2 v2, V3 v3); + + } + +} diff --git a/src/test/resources/query/aggregation/moving_average/allFields.json b/src/test/resources/query/aggregation/moving_average/allFields.json new file mode 100644 index 00000000..1581ffc7 --- /dev/null +++ b/src/test/resources/query/aggregation/moving_average/allFields.json @@ -0,0 +1,64 @@ +{ + "queryType": "movingAverage", + "dataSource": { + "type": "table", + "name": "allFieldsDataSource" + }, + "dimensions": [ + "dimension_1", + "dimension_2" + ], + "limitSpec": { + "type": "default", + "limit": 5000, + "columns": [ + "column_1", + "column_2" + ] + }, + "having": { + "type": "equalTo", + "aggregation": "havingField", + "value": 5 + }, + "granularity": "fifteen_minute", + "filter": { + "type": "selector", + "dimension": "selectorField", + "value": "selectorValue" + }, + "aggregations": [ + { + "type": "doubleSum", + "name": "averagedName", + "fieldName": "aggregatedFieldName" + } + ], + "postAggregations": [ + { + "type": "fieldAccess", + "fieldName": "postAggregatedFieldName" + } + ], + "intervals": [ + "2020-02-01T00:00:00.000Z/2020-03-31T23:59:59.000Z" + ], + "context": { + "useCache": true + }, + "averagers": [ + { + "type": "doubleMean", + "name": "averagingResult", + "fieldName": "averagedName", + "buckets": 60, + "cycleSize": 5 + } + ], + "postAveragers": [ + { + "type": "fieldAccess", + "fieldName": "postAveragedFieldName" + } + ] +} \ No newline at end of file diff --git a/src/test/resources/query/aggregation/moving_average/averager_type/doubleMax.json b/src/test/resources/query/aggregation/moving_average/averager_type/doubleMax.json new file mode 100644 index 00000000..45cc1d92 --- /dev/null +++ b/src/test/resources/query/aggregation/moving_average/averager_type/doubleMax.json @@ -0,0 +1,26 @@ +{ + "queryType": "movingAverage", + "dataSource": { + "type": "table", + "name": "simpleDataSource" + }, + "granularity": "day", + "intervals": [ + "2020-01-01T00:00:00.000Z/2020-02-29T23:59:59.000Z" + ], + "aggregations": [ + { + "name": "averagedName", + "fieldName": "aggregatedFieldName", + "type": "doubleSum" + } + ], + "averagers": [ + { + "name": "averagingResult", + "fieldName": "averagedName", + "type": "doubleMax", + "buckets": 31 + } + ] +} \ No newline at end of file diff --git a/src/test/resources/query/aggregation/moving_average/averager_type/doubleMean.json b/src/test/resources/query/aggregation/moving_average/averager_type/doubleMean.json new file mode 100644 index 00000000..05732725 --- /dev/null +++ b/src/test/resources/query/aggregation/moving_average/averager_type/doubleMean.json @@ -0,0 +1,26 @@ +{ + "queryType": "movingAverage", + "dataSource": { + "type": "table", + "name": "simpleDataSource" + }, + "granularity": "day", + "intervals": [ + "2020-01-01T00:00:00.000Z/2020-02-29T23:59:59.000Z" + ], + "aggregations": [ + { + "name": "averagedName", + "fieldName": "aggregatedFieldName", + "type": "doubleSum" + } + ], + "averagers": [ + { + "name": "averagingResult", + "fieldName": "averagedName", + "type": "doubleMean", + "buckets": 31 + } + ] +} \ No newline at end of file diff --git a/src/test/resources/query/aggregation/moving_average/averager_type/doubleMeanNoNulls.json b/src/test/resources/query/aggregation/moving_average/averager_type/doubleMeanNoNulls.json new file mode 100644 index 00000000..6b8f4e6c --- /dev/null +++ b/src/test/resources/query/aggregation/moving_average/averager_type/doubleMeanNoNulls.json @@ -0,0 +1,26 @@ +{ + "queryType": "movingAverage", + "dataSource": { + "type": "table", + "name": "simpleDataSource" + }, + "granularity": "day", + "intervals": [ + "2020-01-01T00:00:00.000Z/2020-02-29T23:59:59.000Z" + ], + "aggregations": [ + { + "name": "averagedName", + "fieldName": "aggregatedFieldName", + "type": "doubleSum" + } + ], + "averagers": [ + { + "name": "averagingResult", + "fieldName": "averagedName", + "type": "doubleMeanNoNulls", + "buckets": 31 + } + ] +} \ No newline at end of file diff --git a/src/test/resources/query/aggregation/moving_average/averager_type/doubleMin.json b/src/test/resources/query/aggregation/moving_average/averager_type/doubleMin.json new file mode 100644 index 00000000..a9b271f0 --- /dev/null +++ b/src/test/resources/query/aggregation/moving_average/averager_type/doubleMin.json @@ -0,0 +1,26 @@ +{ + "queryType": "movingAverage", + "dataSource": { + "type": "table", + "name": "simpleDataSource" + }, + "granularity": "day", + "intervals": [ + "2020-01-01T00:00:00.000Z/2020-02-29T23:59:59.000Z" + ], + "aggregations": [ + { + "name": "averagedName", + "fieldName": "aggregatedFieldName", + "type": "doubleSum" + } + ], + "averagers": [ + { + "name": "averagingResult", + "fieldName": "averagedName", + "type": "doubleMin", + "buckets": 31 + } + ] +} \ No newline at end of file diff --git a/src/test/resources/query/aggregation/moving_average/averager_type/doubleSum.json b/src/test/resources/query/aggregation/moving_average/averager_type/doubleSum.json new file mode 100644 index 00000000..d831ddf9 --- /dev/null +++ b/src/test/resources/query/aggregation/moving_average/averager_type/doubleSum.json @@ -0,0 +1,26 @@ +{ + "queryType": "movingAverage", + "dataSource": { + "type": "table", + "name": "simpleDataSource" + }, + "granularity": "day", + "intervals": [ + "2020-01-01T00:00:00.000Z/2020-02-29T23:59:59.000Z" + ], + "aggregations": [ + { + "name": "averagedName", + "fieldName": "aggregatedFieldName", + "type": "doubleSum" + } + ], + "averagers": [ + { + "name": "averagingResult", + "fieldName": "averagedName", + "type": "doubleSum", + "buckets": 31 + } + ] +} \ No newline at end of file diff --git a/src/test/resources/query/aggregation/moving_average/averager_type/longMax.json b/src/test/resources/query/aggregation/moving_average/averager_type/longMax.json new file mode 100644 index 00000000..748cc883 --- /dev/null +++ b/src/test/resources/query/aggregation/moving_average/averager_type/longMax.json @@ -0,0 +1,26 @@ +{ + "queryType": "movingAverage", + "dataSource": { + "type": "table", + "name": "simpleDataSource" + }, + "granularity": "day", + "intervals": [ + "2020-01-01T00:00:00.000Z/2020-02-29T23:59:59.000Z" + ], + "aggregations": [ + { + "name": "averagedName", + "fieldName": "aggregatedFieldName", + "type": "doubleSum" + } + ], + "averagers": [ + { + "name": "averagingResult", + "fieldName": "averagedName", + "type": "longMax", + "buckets": 31 + } + ] +} \ No newline at end of file diff --git a/src/test/resources/query/aggregation/moving_average/averager_type/longMean.json b/src/test/resources/query/aggregation/moving_average/averager_type/longMean.json new file mode 100644 index 00000000..0d32146d --- /dev/null +++ b/src/test/resources/query/aggregation/moving_average/averager_type/longMean.json @@ -0,0 +1,26 @@ +{ + "queryType": "movingAverage", + "dataSource": { + "type": "table", + "name": "simpleDataSource" + }, + "granularity": "day", + "intervals": [ + "2020-01-01T00:00:00.000Z/2020-02-29T23:59:59.000Z" + ], + "aggregations": [ + { + "name": "averagedName", + "fieldName": "aggregatedFieldName", + "type": "doubleSum" + } + ], + "averagers": [ + { + "name": "averagingResult", + "fieldName": "averagedName", + "type": "longMean", + "buckets": 31 + } + ] +} \ No newline at end of file diff --git a/src/test/resources/query/aggregation/moving_average/averager_type/longMeanNoNulls.json b/src/test/resources/query/aggregation/moving_average/averager_type/longMeanNoNulls.json new file mode 100644 index 00000000..582797d0 --- /dev/null +++ b/src/test/resources/query/aggregation/moving_average/averager_type/longMeanNoNulls.json @@ -0,0 +1,26 @@ +{ + "queryType": "movingAverage", + "dataSource": { + "type": "table", + "name": "simpleDataSource" + }, + "granularity": "day", + "intervals": [ + "2020-01-01T00:00:00.000Z/2020-02-29T23:59:59.000Z" + ], + "aggregations": [ + { + "name": "averagedName", + "fieldName": "aggregatedFieldName", + "type": "doubleSum" + } + ], + "averagers": [ + { + "name": "averagingResult", + "fieldName": "averagedName", + "type": "longMeanNoNulls", + "buckets": 31 + } + ] +} \ No newline at end of file diff --git a/src/test/resources/query/aggregation/moving_average/averager_type/longMin.json b/src/test/resources/query/aggregation/moving_average/averager_type/longMin.json new file mode 100644 index 00000000..db638088 --- /dev/null +++ b/src/test/resources/query/aggregation/moving_average/averager_type/longMin.json @@ -0,0 +1,26 @@ +{ + "queryType": "movingAverage", + "dataSource": { + "type": "table", + "name": "simpleDataSource" + }, + "granularity": "day", + "intervals": [ + "2020-01-01T00:00:00.000Z/2020-02-29T23:59:59.000Z" + ], + "aggregations": [ + { + "name": "averagedName", + "fieldName": "aggregatedFieldName", + "type": "doubleSum" + } + ], + "averagers": [ + { + "name": "averagingResult", + "fieldName": "averagedName", + "type": "longMin", + "buckets": 31 + } + ] +} \ No newline at end of file diff --git a/src/test/resources/query/aggregation/moving_average/averager_type/longSum.json b/src/test/resources/query/aggregation/moving_average/averager_type/longSum.json new file mode 100644 index 00000000..9762214c --- /dev/null +++ b/src/test/resources/query/aggregation/moving_average/averager_type/longSum.json @@ -0,0 +1,26 @@ +{ + "queryType": "movingAverage", + "dataSource": { + "type": "table", + "name": "simpleDataSource" + }, + "granularity": "day", + "intervals": [ + "2020-01-01T00:00:00.000Z/2020-02-29T23:59:59.000Z" + ], + "aggregations": [ + { + "name": "averagedName", + "fieldName": "aggregatedFieldName", + "type": "doubleSum" + } + ], + "averagers": [ + { + "name": "averagingResult", + "fieldName": "averagedName", + "type": "longSum", + "buckets": 31 + } + ] +} \ No newline at end of file diff --git a/src/test/resources/query/aggregation/moving_average/simple.json b/src/test/resources/query/aggregation/moving_average/simple.json new file mode 100644 index 00000000..05732725 --- /dev/null +++ b/src/test/resources/query/aggregation/moving_average/simple.json @@ -0,0 +1,26 @@ +{ + "queryType": "movingAverage", + "dataSource": { + "type": "table", + "name": "simpleDataSource" + }, + "granularity": "day", + "intervals": [ + "2020-01-01T00:00:00.000Z/2020-02-29T23:59:59.000Z" + ], + "aggregations": [ + { + "name": "averagedName", + "fieldName": "aggregatedFieldName", + "type": "doubleSum" + } + ], + "averagers": [ + { + "name": "averagingResult", + "fieldName": "averagedName", + "type": "doubleMean", + "buckets": 31 + } + ] +} \ No newline at end of file From fa958117c64cbcdf475cd4b32b9419027f421fc2 Mon Sep 17 00:00:00 2001 From: Alper Kanat Date: Mon, 2 Mar 2020 14:55:20 +0300 Subject: [PATCH 07/25] Added expression support to some aggregators --- .../aggregator/DoubleMaxAggregator.java | 13 ++++++++++- .../aggregator/DoubleMinAggregator.java | 13 ++++++++++- .../aggregator/DoubleSumAggregator.java | 13 ++++++++++- .../druidry/aggregator/LongMaxAggregator.java | 12 ++++++++++ .../druidry/aggregator/LongMinAggregator.java | 13 ++++++++++- .../druidry/aggregator/LongSumAggregator.java | 11 +++++++++ .../aggregator/DoubleMaxAggregatorTest.java | 23 ++++++++++++++++++- .../aggregator/DoubleMinAggregatorTest.java | 23 ++++++++++++++++++- .../aggregator/DoubleSumAggregatorTest.java | 23 ++++++++++++++++++- .../aggregator/LongMaxAggregatorTest.java | 23 ++++++++++++++++++- .../aggregator/LongMinAggregatorTest.java | 23 ++++++++++++++++++- .../aggregator/LongSumAggregatorTest.java | 23 ++++++++++++++++++- .../query/aggregation/GroupByTest.java | 6 ++--- .../query/aggregation/TimeSeriesTest.java | 6 ++--- .../query/aggregation/TopNQueryTest.java | 10 ++++---- 15 files changed, 215 insertions(+), 20 deletions(-) diff --git a/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregator.java b/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregator.java index a59a6d97..91d3e4ea 100644 --- a/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregator.java +++ b/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregator.java @@ -19,17 +19,28 @@ import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; +import lombok.Setter; @Getter @EqualsAndHashCode(callSuper = true) public class DoubleMaxAggregator extends DruidAggregator { private static final String DOUBLE_MAX_TYPE_AGGREGATOR = "doubleMax"; + private String fieldName; + @Setter + private String expression; + + public DoubleMaxAggregator(@NonNull String name) { + this.type = DOUBLE_MAX_TYPE_AGGREGATOR; + this.name = name; + } + public DoubleMaxAggregator(@NonNull String name, @NonNull String fieldName) { this.type = DOUBLE_MAX_TYPE_AGGREGATOR; this.name = name; this.fieldName = fieldName; } -} \ No newline at end of file + +} diff --git a/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMinAggregator.java b/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMinAggregator.java index d950cb53..d2ed1a77 100644 --- a/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMinAggregator.java +++ b/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMinAggregator.java @@ -19,17 +19,28 @@ import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; +import lombok.Setter; @Getter @EqualsAndHashCode(callSuper = true) public class DoubleMinAggregator extends DruidAggregator { private static final String DOUBLE_MIN_TYPE_AGGREGATOR = "doubleMin"; + private String fieldName; + @Setter + private String expression; + + public DoubleMinAggregator(@NonNull String name) { + this.type = DOUBLE_MIN_TYPE_AGGREGATOR; + this.name = name; + } + public DoubleMinAggregator(@NonNull String name, @NonNull String fieldName) { this.type = DOUBLE_MIN_TYPE_AGGREGATOR; this.name = name; this.fieldName = fieldName; } -} \ No newline at end of file + +} diff --git a/src/main/java/in/zapr/druid/druidry/aggregator/DoubleSumAggregator.java b/src/main/java/in/zapr/druid/druidry/aggregator/DoubleSumAggregator.java index 1a28b9b0..6665d265 100644 --- a/src/main/java/in/zapr/druid/druidry/aggregator/DoubleSumAggregator.java +++ b/src/main/java/in/zapr/druid/druidry/aggregator/DoubleSumAggregator.java @@ -19,17 +19,28 @@ import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; +import lombok.Setter; @Getter @EqualsAndHashCode(callSuper = true) public class DoubleSumAggregator extends DruidAggregator { private static final String DOUBLE_SUM_TYPE_AGGREGATOR = "doubleSum"; + private String fieldName; + @Setter + private String expression; + + public DoubleSumAggregator(@NonNull String name) { + this.type = DOUBLE_SUM_TYPE_AGGREGATOR; + this.name = name; + } + public DoubleSumAggregator(@NonNull String name, @NonNull String fieldName) { this.type = DOUBLE_SUM_TYPE_AGGREGATOR; this.name = name; this.fieldName = fieldName; } -} \ No newline at end of file + +} diff --git a/src/main/java/in/zapr/druid/druidry/aggregator/LongMaxAggregator.java b/src/main/java/in/zapr/druid/druidry/aggregator/LongMaxAggregator.java index 5c58675f..1a8c1f60 100644 --- a/src/main/java/in/zapr/druid/druidry/aggregator/LongMaxAggregator.java +++ b/src/main/java/in/zapr/druid/druidry/aggregator/LongMaxAggregator.java @@ -19,16 +19,28 @@ import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; +import lombok.Setter; @Getter @EqualsAndHashCode(callSuper = true) public class LongMaxAggregator extends DruidAggregator { + private static final String LONG_MAX_TYPE_AGGREGATOR = "longMax"; + private String fieldName; + @Setter + private String expression; + + public LongMaxAggregator(@NonNull String name) { + this.type = LONG_MAX_TYPE_AGGREGATOR; + this.name = name; + } + public LongMaxAggregator(@NonNull String name, @NonNull String fieldName) { this.type = LONG_MAX_TYPE_AGGREGATOR; this.name = name; this.fieldName = fieldName; } + } diff --git a/src/main/java/in/zapr/druid/druidry/aggregator/LongMinAggregator.java b/src/main/java/in/zapr/druid/druidry/aggregator/LongMinAggregator.java index edb16725..80227fbd 100644 --- a/src/main/java/in/zapr/druid/druidry/aggregator/LongMinAggregator.java +++ b/src/main/java/in/zapr/druid/druidry/aggregator/LongMinAggregator.java @@ -19,17 +19,28 @@ import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; +import lombok.Setter; @Getter @EqualsAndHashCode(callSuper = true) public class LongMinAggregator extends DruidAggregator { private static final String LONG_MIN_TYPE_AGGREGATOR = "longMin"; + private String fieldName; + @Setter + private String expression; + + public LongMinAggregator(@NonNull String name) { + this.type = LONG_MIN_TYPE_AGGREGATOR; + this.name = name; + } + public LongMinAggregator(@NonNull String name, @NonNull String fieldName) { this.type = LONG_MIN_TYPE_AGGREGATOR; this.name = name; this.fieldName = fieldName; } -} \ No newline at end of file + +} diff --git a/src/main/java/in/zapr/druid/druidry/aggregator/LongSumAggregator.java b/src/main/java/in/zapr/druid/druidry/aggregator/LongSumAggregator.java index 874e6b7c..65e5b261 100644 --- a/src/main/java/in/zapr/druid/druidry/aggregator/LongSumAggregator.java +++ b/src/main/java/in/zapr/druid/druidry/aggregator/LongSumAggregator.java @@ -19,17 +19,28 @@ import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; +import lombok.Setter; @Getter @EqualsAndHashCode(callSuper = true) public class LongSumAggregator extends DruidAggregator { private static final String LONGSUM_TYPE_AGGREGATOR = "longSum"; + private String fieldName; + @Setter + private String expression; + + public LongSumAggregator(@NonNull String name) { + this.type = LONGSUM_TYPE_AGGREGATOR; + this.name = name; + } + public LongSumAggregator(@NonNull String name, @NonNull String fieldName) { this.type = LONGSUM_TYPE_AGGREGATOR; this.name = name; this.fieldName = fieldName; } + } diff --git a/src/test/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregatorTest.java b/src/test/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregatorTest.java index 74d8245f..a3f654e1 100644 --- a/src/test/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregatorTest.java +++ b/src/test/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregatorTest.java @@ -45,10 +45,13 @@ public void testAllFields() throws JsonProcessingException, JSONException { DoubleMaxAggregator doubleMaxAggregator = new DoubleMaxAggregator("CarpeDiem", "Hey"); + doubleMaxAggregator.setExpression("(\"foo\" / \"bar\")"); + JSONObject jsonObject = new JSONObject(); jsonObject.put("type", "doubleMax"); jsonObject.put("name", "CarpeDiem"); jsonObject.put("fieldName", "Hey"); + jsonObject.put("expression", "(\"foo\" / \"bar\")"); String actualJSON = objectMapper.writeValueAsString(doubleMaxAggregator); String expectedJSON = jsonObject.toString(); @@ -72,7 +75,16 @@ public void testEqualsPositive() { DoubleMaxAggregator aggregator1 = new DoubleMaxAggregator("name", "field"); DoubleMaxAggregator aggregator2 = new DoubleMaxAggregator("name", "field"); + DoubleMaxAggregator aggregator3 = new DoubleMaxAggregator("name", "field"); + + aggregator3.setExpression("(\"foo\" / \"bar\")"); + + DoubleMaxAggregator aggregator4 = new DoubleMaxAggregator("name", "field"); + + aggregator4.setExpression("(\"foo\" / \"bar\")"); + Assert.assertEquals(aggregator1, aggregator2); + Assert.assertEquals(aggregator3, aggregator4); } @Test @@ -80,7 +92,16 @@ public void testEqualsNegative() { DoubleMaxAggregator aggregator1 = new DoubleMaxAggregator("name", "field"); DoubleMaxAggregator aggregator2 = new DoubleMaxAggregator("name1", "field1"); + DoubleMaxAggregator aggregator3 = new DoubleMaxAggregator("name", "field"); + + aggregator3.setExpression("(\"foo\" / \"bar\")"); + + DoubleMaxAggregator aggregator4 = new DoubleMaxAggregator("name", "field"); + + aggregator4.setExpression("(\"foo\" / \"baz\")"); + Assert.assertNotEquals(aggregator1, aggregator2); + Assert.assertNotEquals(aggregator3, aggregator4); } @Test @@ -90,4 +111,4 @@ public void testEqualsWithAnotherSubClass() { Assert.assertNotEquals(aggregator1, aggregator2); } -} \ No newline at end of file +} diff --git a/src/test/java/in/zapr/druid/druidry/aggregator/DoubleMinAggregatorTest.java b/src/test/java/in/zapr/druid/druidry/aggregator/DoubleMinAggregatorTest.java index e84b2782..7435efaa 100644 --- a/src/test/java/in/zapr/druid/druidry/aggregator/DoubleMinAggregatorTest.java +++ b/src/test/java/in/zapr/druid/druidry/aggregator/DoubleMinAggregatorTest.java @@ -45,10 +45,13 @@ public void testAllFields() throws JsonProcessingException, JSONException { DoubleMinAggregator doubleMinAggregator = new DoubleMinAggregator("CarpeDiem", "Hey"); + doubleMinAggregator.setExpression("(\"foo\" / \"bar\")"); + JSONObject jsonObject = new JSONObject(); jsonObject.put("type", "doubleMin"); jsonObject.put("name", "CarpeDiem"); jsonObject.put("fieldName", "Hey"); + jsonObject.put("expression", "(\"foo\" / \"bar\")"); String actualJSON = objectMapper.writeValueAsString(doubleMinAggregator); String expectedJSON = jsonObject.toString(); @@ -72,7 +75,16 @@ public void testEqualsPositive() { DoubleMinAggregator aggregator1 = new DoubleMinAggregator("name", "field"); DoubleMinAggregator aggregator2 = new DoubleMinAggregator("name", "field"); + DoubleMinAggregator aggregator3 = new DoubleMinAggregator("name", "field"); + + aggregator3.setExpression("(\"foo\" / \"bar\")"); + + DoubleMinAggregator aggregator4 = new DoubleMinAggregator("name", "field"); + + aggregator4.setExpression("(\"foo\" / \"bar\")"); + Assert.assertEquals(aggregator1, aggregator2); + Assert.assertEquals(aggregator3, aggregator4); } @Test @@ -80,7 +92,16 @@ public void testEqualsNegative() { DoubleMinAggregator aggregator1 = new DoubleMinAggregator("name", "field"); DoubleMinAggregator aggregator2 = new DoubleMinAggregator("name1", "field1"); + DoubleMinAggregator aggregator3 = new DoubleMinAggregator("name", "field"); + + aggregator3.setExpression("(\"foo\" / \"bar\")"); + + DoubleMinAggregator aggregator4 = new DoubleMinAggregator("name", "field"); + + aggregator4.setExpression("(\"foo\" / \"baz\")"); + Assert.assertNotEquals(aggregator1, aggregator2); + Assert.assertNotEquals(aggregator3, aggregator4); } @Test @@ -90,4 +111,4 @@ public void testEqualsWithAnotherSubClass() { Assert.assertNotEquals(aggregator1, aggregator2); } -} \ No newline at end of file +} diff --git a/src/test/java/in/zapr/druid/druidry/aggregator/DoubleSumAggregatorTest.java b/src/test/java/in/zapr/druid/druidry/aggregator/DoubleSumAggregatorTest.java index f3b0ff75..08b27b2b 100644 --- a/src/test/java/in/zapr/druid/druidry/aggregator/DoubleSumAggregatorTest.java +++ b/src/test/java/in/zapr/druid/druidry/aggregator/DoubleSumAggregatorTest.java @@ -45,10 +45,13 @@ public void testAllFields() throws JsonProcessingException, JSONException { DoubleSumAggregator doubleSumAggregator = new DoubleSumAggregator("CarpeDiem", "Hey"); + doubleSumAggregator.setExpression("(\"foo\" / \"bar\")"); + JSONObject jsonObject = new JSONObject(); jsonObject.put("type", "doubleSum"); jsonObject.put("name", "CarpeDiem"); jsonObject.put("fieldName", "Hey"); + jsonObject.put("expression", "(\"foo\" / \"bar\")"); String actualJSON = objectMapper.writeValueAsString(doubleSumAggregator); String expectedJSON = jsonObject.toString(); @@ -72,7 +75,16 @@ public void testEqualsPositive() { DoubleSumAggregator aggregator1 = new DoubleSumAggregator("name", "field"); DoubleSumAggregator aggregator2 = new DoubleSumAggregator("name", "field"); + DoubleSumAggregator aggregator3 = new DoubleSumAggregator("name", "field"); + + aggregator3.setExpression("(\"foo\" / \"bar\")"); + + DoubleSumAggregator aggregator4 = new DoubleSumAggregator("name", "field"); + + aggregator4.setExpression("(\"foo\" / \"bar\")"); + Assert.assertEquals(aggregator1, aggregator2); + Assert.assertEquals(aggregator3, aggregator4); } @Test @@ -80,7 +92,16 @@ public void testEqualsNegative() { DoubleSumAggregator aggregator1 = new DoubleSumAggregator("name", "field"); DoubleSumAggregator aggregator2 = new DoubleSumAggregator("name1", "field1"); + DoubleSumAggregator aggregator3 = new DoubleSumAggregator("name", "field"); + + aggregator3.setExpression("(\"foo\" / \"bar\")"); + + DoubleSumAggregator aggregator4 = new DoubleSumAggregator("name", "field"); + + aggregator4.setExpression("(\"foo\" / \"baz\")"); + Assert.assertNotEquals(aggregator1, aggregator2); + Assert.assertNotEquals(aggregator3, aggregator4); } @Test @@ -90,4 +111,4 @@ public void testEqualsWithAnotherSubClass() { Assert.assertNotEquals(aggregator1, aggregator2); } -} \ No newline at end of file +} diff --git a/src/test/java/in/zapr/druid/druidry/aggregator/LongMaxAggregatorTest.java b/src/test/java/in/zapr/druid/druidry/aggregator/LongMaxAggregatorTest.java index cd3aefa3..f316acc6 100644 --- a/src/test/java/in/zapr/druid/druidry/aggregator/LongMaxAggregatorTest.java +++ b/src/test/java/in/zapr/druid/druidry/aggregator/LongMaxAggregatorTest.java @@ -45,10 +45,13 @@ public void testAllFields() throws JsonProcessingException, JSONException { LongMaxAggregator countAggregator = new LongMaxAggregator("CarpeDiem", "Hey"); + countAggregator.setExpression("(\"foo\" / \"bar\")"); + JSONObject jsonObject = new JSONObject(); jsonObject.put("type", "longMax"); jsonObject.put("name", "CarpeDiem"); jsonObject.put("fieldName", "Hey"); + jsonObject.put("expression", "(\"foo\" / \"bar\")"); String actualJSON = objectMapper.writeValueAsString(countAggregator); String expectedJSON = jsonObject.toString(); @@ -72,7 +75,16 @@ public void testEqualsPositive() { LongMaxAggregator aggregator1 = new LongMaxAggregator("name", "field"); LongMaxAggregator aggregator2 = new LongMaxAggregator("name", "field"); + LongMaxAggregator aggregator3 = new LongMaxAggregator("name", "field"); + + aggregator3.setExpression("(\"foo\" / \"bar\")"); + + LongMaxAggregator aggregator4 = new LongMaxAggregator("name", "field"); + + aggregator4.setExpression("(\"foo\" / \"bar\")"); + Assert.assertEquals(aggregator1, aggregator2); + Assert.assertEquals(aggregator3, aggregator4); } @Test @@ -80,7 +92,16 @@ public void testEqualsNegative() { LongMaxAggregator aggregator1 = new LongMaxAggregator("name", "field"); LongMaxAggregator aggregator2 = new LongMaxAggregator("name1", "field1"); + LongMaxAggregator aggregator3 = new LongMaxAggregator("name", "field"); + + aggregator3.setExpression("(\"foo\" / \"bar\")"); + + LongMaxAggregator aggregator4 = new LongMaxAggregator("name", "field"); + + aggregator4.setExpression("(\"foo\" / \"baz\")"); + Assert.assertNotEquals(aggregator1, aggregator2); + Assert.assertNotEquals(aggregator3, aggregator4); } @Test @@ -90,4 +111,4 @@ public void testEqualsWithAnotherSubClass() { Assert.assertNotEquals(aggregator1, aggregator2); } -} \ No newline at end of file +} diff --git a/src/test/java/in/zapr/druid/druidry/aggregator/LongMinAggregatorTest.java b/src/test/java/in/zapr/druid/druidry/aggregator/LongMinAggregatorTest.java index 1a60f8c5..cd9346f4 100644 --- a/src/test/java/in/zapr/druid/druidry/aggregator/LongMinAggregatorTest.java +++ b/src/test/java/in/zapr/druid/druidry/aggregator/LongMinAggregatorTest.java @@ -45,10 +45,13 @@ public void testAllFields() throws JsonProcessingException, JSONException { LongMinAggregator longMinAggregator = new LongMinAggregator("CarpeDiem", "Hey"); + longMinAggregator.setExpression("(\"foo\" / \"bar\")"); + JSONObject jsonObject = new JSONObject(); jsonObject.put("type", "longMin"); jsonObject.put("name", "CarpeDiem"); jsonObject.put("fieldName", "Hey"); + jsonObject.put("expression", "(\"foo\" / \"bar\")"); String actualJSON = objectMapper.writeValueAsString(longMinAggregator); String expectedJSON = jsonObject.toString(); @@ -72,7 +75,16 @@ public void testEqualsPositive() { LongMinAggregator aggregator1 = new LongMinAggregator("name", "field"); LongMinAggregator aggregator2 = new LongMinAggregator("name", "field"); + LongMinAggregator aggregator3 = new LongMinAggregator("name", "field"); + + aggregator3.setExpression("(\"foo\" / \"bar\")"); + + LongMinAggregator aggregator4 = new LongMinAggregator("name", "field"); + + aggregator4.setExpression("(\"foo\" / \"bar\")"); + Assert.assertEquals(aggregator1, aggregator2); + Assert.assertEquals(aggregator3, aggregator4); } @Test @@ -80,7 +92,16 @@ public void testEqualsNegative() { LongMinAggregator aggregator1 = new LongMinAggregator("name", "field"); LongMinAggregator aggregator2 = new LongMinAggregator("name1", "field1"); + LongMinAggregator aggregator3 = new LongMinAggregator("name", "field"); + + aggregator3.setExpression("(\"foo\" / \"bar\")"); + + LongMinAggregator aggregator4 = new LongMinAggregator("name", "field"); + + aggregator4.setExpression("(\"foo\" / \"baz\")"); + Assert.assertNotEquals(aggregator1, aggregator2); + Assert.assertNotEquals(aggregator3, aggregator4); } @Test @@ -90,4 +111,4 @@ public void testEqualsWithAnotherSubClass() { Assert.assertNotEquals(aggregator1, aggregator2); } -} \ No newline at end of file +} diff --git a/src/test/java/in/zapr/druid/druidry/aggregator/LongSumAggregatorTest.java b/src/test/java/in/zapr/druid/druidry/aggregator/LongSumAggregatorTest.java index 5e4d1b13..660c5ae6 100644 --- a/src/test/java/in/zapr/druid/druidry/aggregator/LongSumAggregatorTest.java +++ b/src/test/java/in/zapr/druid/druidry/aggregator/LongSumAggregatorTest.java @@ -45,10 +45,13 @@ public void testAllFields() throws JsonProcessingException, JSONException { LongSumAggregator longSumAggregator = new LongSumAggregator("CarpeDiem", "Hey"); + longSumAggregator.setExpression("(\"foo\" / \"bar\")"); + JSONObject jsonObject = new JSONObject(); jsonObject.put("type", "longSum"); jsonObject.put("name", "CarpeDiem"); jsonObject.put("fieldName", "Hey"); + jsonObject.put("expression", "(\"foo\" / \"bar\")"); String actualJSON = objectMapper.writeValueAsString(longSumAggregator); String expectedJSON = jsonObject.toString(); @@ -72,7 +75,16 @@ public void testEqualsPositive() { LongSumAggregator aggregator1 = new LongSumAggregator("name", "field"); LongSumAggregator aggregator2 = new LongSumAggregator("name", "field"); + LongSumAggregator aggregator3 = new LongSumAggregator("name", "field"); + + aggregator3.setExpression("(\"foo\" / \"bar\")"); + + LongSumAggregator aggregator4 = new LongSumAggregator("name", "field"); + + aggregator4.setExpression("(\"foo\" / \"bar\")"); + Assert.assertEquals(aggregator1, aggregator2); + Assert.assertEquals(aggregator3, aggregator4); } @Test @@ -80,7 +92,16 @@ public void testEqualsNegative() { LongSumAggregator aggregator1 = new LongSumAggregator("name", "field"); LongSumAggregator aggregator2 = new LongSumAggregator("name1", "field1"); + LongSumAggregator aggregator3 = new LongSumAggregator("name", "field"); + + aggregator3.setExpression("(\"foo\" / \"bar\")"); + + LongSumAggregator aggregator4 = new LongSumAggregator("name", "field"); + + aggregator4.setExpression("(\"foo\" / \"baz\")"); + Assert.assertNotEquals(aggregator1, aggregator2); + Assert.assertNotEquals(aggregator3, aggregator4); } @Test @@ -90,4 +111,4 @@ public void testEqualsWithAnotherSubClass() { Assert.assertNotEquals(aggregator1, aggregator2); } -} \ No newline at end of file +} diff --git a/src/test/java/in/zapr/druid/druidry/query/aggregation/GroupByTest.java b/src/test/java/in/zapr/druid/druidry/query/aggregation/GroupByTest.java index 51ae1ecd..7213b9ab 100644 --- a/src/test/java/in/zapr/druid/druidry/query/aggregation/GroupByTest.java +++ b/src/test/java/in/zapr/druid/druidry/query/aggregation/GroupByTest.java @@ -92,8 +92,8 @@ public void testSampleQuery() throws JsonProcessingException, JSONException { " ]\n" + " },\n" + " \"aggregations\": [\n" + - " { \"type\": \"longSum\", \"name\": \"total_usage\", \"fieldName\": \"user_count\" },\n" + - " { \"type\": \"doubleSum\", \"name\": \"data_transfer\", \"fieldName\": \"data_transfer\" }\n" + + " { \"type\": \"longSum\", \"name\": \"total_usage\", \"fieldName\": \"user_count\", \"expression\": null },\n" + + " { \"type\": \"doubleSum\", \"name\": \"data_transfer\", \"fieldName\": \"data_transfer\", \"expression\": null }\n" + " ],\n" + "\"having\": {\n" + " \"type\": \"greaterThan\",\n" + @@ -275,4 +275,4 @@ public void testAllFields() throws JSONException, JsonProcessingException { JSONAssert.assertEquals(actualJson, expectedQuery, JSONCompareMode.NON_EXTENSIBLE); } -} \ No newline at end of file +} diff --git a/src/test/java/in/zapr/druid/druidry/query/aggregation/TimeSeriesTest.java b/src/test/java/in/zapr/druid/druidry/query/aggregation/TimeSeriesTest.java index fbf732d6..ae7f4875 100644 --- a/src/test/java/in/zapr/druid/druidry/query/aggregation/TimeSeriesTest.java +++ b/src/test/java/in/zapr/druid/druidry/query/aggregation/TimeSeriesTest.java @@ -136,8 +136,8 @@ public void testSampleQuery() throws JsonProcessingException, JSONException { " ]\n" + " },\n" + " \"aggregations\": [\n" + - " { \"type\": \"longSum\", \"name\": \"sample_name1\", \"fieldName\": \"sample_fieldName1\" },\n" + - " { \"type\": \"doubleSum\", \"name\": \"sample_name2\", \"fieldName\": \"sample_fieldName2\" }\n" + + " { \"type\": \"longSum\", \"name\": \"sample_name1\", \"fieldName\": \"sample_fieldName1\", \"expression\": null },\n" + + " { \"type\": \"doubleSum\", \"name\": \"sample_name2\", \"fieldName\": \"sample_fieldName2\", \"expression\": null }\n" + " ],\n" + " \"postAggregations\": [\n" + " { \"type\": \"arithmetic\",\n" + @@ -248,4 +248,4 @@ public void testAllFields() throws JSONException, JsonProcessingException { String actualJson = objectMapper.writeValueAsString(seriesQuery); JSONAssert.assertEquals(actualJson, expectedQuery, JSONCompareMode.NON_EXTENSIBLE); } -} \ No newline at end of file +} diff --git a/src/test/java/in/zapr/druid/druidry/query/aggregation/TopNQueryTest.java b/src/test/java/in/zapr/druid/druidry/query/aggregation/TopNQueryTest.java index 5169baf0..8d1a2f51 100644 --- a/src/test/java/in/zapr/druid/druidry/query/aggregation/TopNQueryTest.java +++ b/src/test/java/in/zapr/druid/druidry/query/aggregation/TopNQueryTest.java @@ -137,12 +137,14 @@ public void testSampleQuery() throws JsonProcessingException, JSONException { " {\n" + " \"type\": \"longSum\",\n" + " \"name\": \"count\",\n" + - " \"fieldName\": \"count\"\n" + + " \"fieldName\": \"count\",\n" + + " \"expression\": null\n" + " },\n" + " {\n" + " \"type\": \"doubleSum\",\n" + " \"name\": \"some_metric\",\n" + - " \"fieldName\": \"some_metric\"\n" + + " \"fieldName\": \"some_metric\",\n" + + " \"expression\": null\n" + " }\n" + " ],\n" + " \"postAggregations\": [\n" + @@ -170,7 +172,7 @@ public void testSampleQuery() throws JsonProcessingException, JSONException { "}"; String actualJson = objectMapper.writeValueAsString(query); - JSONAssert.assertEquals(actualJson, expectedJsonAsString, JSONCompareMode.NON_EXTENSIBLE); + JSONAssert.assertEquals(expectedJsonAsString, actualJson, JSONCompareMode.NON_EXTENSIBLE); } @Test @@ -411,4 +413,4 @@ public void preconditionCheck() { .context(context) .build(); } -} \ No newline at end of file +} From 55f5835b470a93f7b76cae1d88faa8dd6c853858 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Mar 2020 21:43:28 +0000 Subject: [PATCH 08/25] Bump jackson-databind from 2.9.10.1 to 2.9.10.3 Bumps [jackson-databind](https://github.com/FasterXML/jackson) from 2.9.10.1 to 2.9.10.3. - [Release notes](https://github.com/FasterXML/jackson/releases) - [Commits](https://github.com/FasterXML/jackson/commits) Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e442e540..17487b0e 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ UTF-8 - 2.9.10.1 + 2.9.10.3 2.9.9 2.9.7 1.18.10 From 15b8bbbbff0ec5afc3728cd9d808c250d4bc3cbd Mon Sep 17 00:00:00 2001 From: Jonasz Czerepko Date: Tue, 10 Mar 2020 14:13:56 +0100 Subject: [PATCH 09/25] Added limit field to the TimeSeries Query (present in Druid since version 0.16.0-incubating: https://druid.apache.org/docs/0.16.0-incubating/querying/timeseriesquery.html). --- .../druid/druidry/query/aggregation/DruidTimeSeriesQuery.java | 4 +++- .../zapr/druid/druidry/query/aggregation/TimeSeriesTest.java | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/in/zapr/druid/druidry/query/aggregation/DruidTimeSeriesQuery.java b/src/main/java/in/zapr/druid/druidry/query/aggregation/DruidTimeSeriesQuery.java index 54900291..78745460 100644 --- a/src/main/java/in/zapr/druid/druidry/query/aggregation/DruidTimeSeriesQuery.java +++ b/src/main/java/in/zapr/druid/druidry/query/aggregation/DruidTimeSeriesQuery.java @@ -40,13 +40,14 @@ public class DruidTimeSeriesQuery extends DruidAggregationQuery { // TODO: String or Boolean?? private Boolean descending; + private Integer limit; @Builder private DruidTimeSeriesQuery(@NonNull DataSource dataSource, Boolean descending, @NonNull List intervals, @NonNull Granularity granularity, List virtualColumns, DruidFilter filter, List aggregators, - List postAggregators, Context context) { + List postAggregators, Integer limit, Context context) { this.queryType = QueryType.TIMESERIES; this.dataSource = dataSource; @@ -57,6 +58,7 @@ private DruidTimeSeriesQuery(@NonNull DataSource dataSource, Boolean descending, this.filter = filter; this.aggregations = aggregators; this.postAggregations = postAggregators; + this.limit = limit; this.context = context; } } diff --git a/src/test/java/in/zapr/druid/druidry/query/aggregation/TimeSeriesTest.java b/src/test/java/in/zapr/druid/druidry/query/aggregation/TimeSeriesTest.java index fbf732d6..291f9d6d 100644 --- a/src/test/java/in/zapr/druid/druidry/query/aggregation/TimeSeriesTest.java +++ b/src/test/java/in/zapr/druid/druidry/query/aggregation/TimeSeriesTest.java @@ -209,6 +209,7 @@ public void testAllFields() throws JSONException, JsonProcessingException { .filter(filter) .aggregators(Collections.singletonList(aggregator)) .postAggregators(Collections.singletonList(postAggregator)) + .limit(5) .context(context) .build(); @@ -239,6 +240,7 @@ public void testAllFields() throws JSONException, JsonProcessingException { expectedQuery.put("intervals", new JSONArray(Collections .singletonList("2013-07-14T00:00:00.000Z/2013-11-16T00:00:00.000Z"))); expectedQuery.put("granularity", "day"); + expectedQuery.put("limit", 5); expectedQuery.put("aggregations", new JSONArray(Collections.singletonList(expectedAggregator))); expectedQuery.put("postAggregations", new JSONArray(Collections.singletonList(expectedPostAggregator))); expectedQuery.put("filter", expectedFilter); From d78fe853d942b397c4676742dc2b6a32eaefcf8a Mon Sep 17 00:00:00 2001 From: Jonasz Czerepko Date: Tue, 10 Mar 2020 20:09:02 +0100 Subject: [PATCH 10/25] Applied code formatter recommended by Druidry repository owners. Added license docs to each new file. Modified the code accordingly to the PR comment (averager constructors changed to builders, other minor changes). --- .../druidry/averager/DoubleMaxAverager.java | 25 ++- .../druidry/averager/DoubleMeanAverager.java | 25 ++- .../averager/DoubleMeanNoNullsAverager.java | 25 ++- .../druidry/averager/DoubleMinAverager.java | 25 ++- .../druidry/averager/DoubleSumAverager.java | 25 ++- .../druid/druidry/averager/DruidAverager.java | 49 ++++-- .../druidry/averager/LongMaxAverager.java | 25 ++- .../druidry/averager/LongMeanAverager.java | 25 ++- .../averager/LongMeanNoNullsAverager.java | 25 ++- .../druidry/averager/LongMinAverager.java | 25 ++- .../druidry/averager/LongSumAverager.java | 25 ++- .../aggregation/DruidMovingAverageQuery.java | 21 ++- .../aggregation/MovingAverageCreators.java | 124 +++++++++++++++ .../query/aggregation/MovingAverageTest.java | 147 ++++++++++-------- 14 files changed, 460 insertions(+), 131 deletions(-) create mode 100644 src/test/java/in/zapr/druid/druidry/query/aggregation/MovingAverageCreators.java diff --git a/src/main/java/in/zapr/druid/druidry/averager/DoubleMaxAverager.java b/src/main/java/in/zapr/druid/druidry/averager/DoubleMaxAverager.java index 9e90f626..cb56d36f 100644 --- a/src/main/java/in/zapr/druid/druidry/averager/DoubleMaxAverager.java +++ b/src/main/java/in/zapr/druid/druidry/averager/DoubleMaxAverager.java @@ -1,5 +1,22 @@ +/* + * Copyright 2018-present Red Brick Lane Marketing Solutions Pvt. Ltd. + * + * 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 in.zapr.druid.druidry.averager; +import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; @@ -10,11 +27,9 @@ public class DoubleMaxAverager extends DruidAverager { private static final String DOUBLE_MAX_AVERAGER = "doubleMax"; - public DoubleMaxAverager(@NonNull String name, @NonNull String fieldName, @NonNull Integer buckets) { - this(name, fieldName, buckets, null); - } - - public DoubleMaxAverager(String name, String fieldName, Integer buckets, Integer cycleSize) { + @Builder + private DoubleMaxAverager(@NonNull String name, @NonNull String fieldName, + @NonNull Integer buckets, Integer cycleSize) { super(DOUBLE_MAX_AVERAGER, name, fieldName, buckets, cycleSize); } diff --git a/src/main/java/in/zapr/druid/druidry/averager/DoubleMeanAverager.java b/src/main/java/in/zapr/druid/druidry/averager/DoubleMeanAverager.java index e2f5cd48..d5b31a69 100644 --- a/src/main/java/in/zapr/druid/druidry/averager/DoubleMeanAverager.java +++ b/src/main/java/in/zapr/druid/druidry/averager/DoubleMeanAverager.java @@ -1,5 +1,22 @@ +/* + * Copyright 2018-present Red Brick Lane Marketing Solutions Pvt. Ltd. + * + * 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 in.zapr.druid.druidry.averager; +import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; @@ -10,11 +27,9 @@ public class DoubleMeanAverager extends DruidAverager { private static final String DOUBLE_MEAN_AVERAGER = "doubleMean"; - public DoubleMeanAverager(@NonNull String name, @NonNull String fieldName, @NonNull Integer buckets) { - this(name, fieldName, buckets, null); - } - - public DoubleMeanAverager(String name, String fieldName, Integer buckets, Integer cycleSize) { + @Builder + private DoubleMeanAverager(@NonNull String name, @NonNull String fieldName, + @NonNull Integer buckets, Integer cycleSize) { super(DOUBLE_MEAN_AVERAGER, name, fieldName, buckets, cycleSize); } diff --git a/src/main/java/in/zapr/druid/druidry/averager/DoubleMeanNoNullsAverager.java b/src/main/java/in/zapr/druid/druidry/averager/DoubleMeanNoNullsAverager.java index de26216e..b3f90bd2 100644 --- a/src/main/java/in/zapr/druid/druidry/averager/DoubleMeanNoNullsAverager.java +++ b/src/main/java/in/zapr/druid/druidry/averager/DoubleMeanNoNullsAverager.java @@ -1,5 +1,22 @@ +/* + * Copyright 2018-present Red Brick Lane Marketing Solutions Pvt. Ltd. + * + * 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 in.zapr.druid.druidry.averager; +import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; @@ -10,11 +27,9 @@ public class DoubleMeanNoNullsAverager extends DruidAverager { private static final String DOUBLE_MEAN_NO_NULLS_AVERAGER = "doubleMeanNoNulls"; - public DoubleMeanNoNullsAverager(@NonNull String name, @NonNull String fieldName, @NonNull Integer buckets) { - this(name, fieldName, buckets, null); - } - - public DoubleMeanNoNullsAverager(String name, String fieldName, Integer buckets, Integer cycleSize) { + @Builder + private DoubleMeanNoNullsAverager(@NonNull String name, @NonNull String fieldName, + @NonNull Integer buckets, Integer cycleSize) { super(DOUBLE_MEAN_NO_NULLS_AVERAGER, name, fieldName, buckets, cycleSize); } diff --git a/src/main/java/in/zapr/druid/druidry/averager/DoubleMinAverager.java b/src/main/java/in/zapr/druid/druidry/averager/DoubleMinAverager.java index 70ac3457..a5e3e257 100644 --- a/src/main/java/in/zapr/druid/druidry/averager/DoubleMinAverager.java +++ b/src/main/java/in/zapr/druid/druidry/averager/DoubleMinAverager.java @@ -1,5 +1,22 @@ +/* + * Copyright 2018-present Red Brick Lane Marketing Solutions Pvt. Ltd. + * + * 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 in.zapr.druid.druidry.averager; +import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; @@ -10,11 +27,9 @@ public class DoubleMinAverager extends DruidAverager { private static final String DOUBLE_MIN_AVERAGER = "doubleMin"; - public DoubleMinAverager(@NonNull String name, @NonNull String fieldName, @NonNull Integer buckets) { - this(name, fieldName, buckets, null); - } - - public DoubleMinAverager(String name, String fieldName, Integer buckets, Integer cycleSize) { + @Builder + private DoubleMinAverager(@NonNull String name, @NonNull String fieldName, + @NonNull Integer buckets, Integer cycleSize) { super(DOUBLE_MIN_AVERAGER, name, fieldName, buckets, cycleSize); } diff --git a/src/main/java/in/zapr/druid/druidry/averager/DoubleSumAverager.java b/src/main/java/in/zapr/druid/druidry/averager/DoubleSumAverager.java index 50696f71..be76ceee 100644 --- a/src/main/java/in/zapr/druid/druidry/averager/DoubleSumAverager.java +++ b/src/main/java/in/zapr/druid/druidry/averager/DoubleSumAverager.java @@ -1,5 +1,22 @@ +/* + * Copyright 2018-present Red Brick Lane Marketing Solutions Pvt. Ltd. + * + * 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 in.zapr.druid.druidry.averager; +import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; @@ -10,11 +27,9 @@ public class DoubleSumAverager extends DruidAverager { private static final String DOUBLE_SUM_AVERAGER = "doubleSum"; - public DoubleSumAverager(@NonNull String name, @NonNull String fieldName, @NonNull Integer buckets) { - this(name, fieldName, buckets, null); - } - - public DoubleSumAverager(String name, String fieldName, Integer buckets, Integer cycleSize) { + @Builder + private DoubleSumAverager(@NonNull String name, @NonNull String fieldName, + @NonNull Integer buckets, Integer cycleSize) { super(DOUBLE_SUM_AVERAGER, name, fieldName, buckets, cycleSize); } diff --git a/src/main/java/in/zapr/druid/druidry/averager/DruidAverager.java b/src/main/java/in/zapr/druid/druidry/averager/DruidAverager.java index cda43315..d810ebb8 100644 --- a/src/main/java/in/zapr/druid/druidry/averager/DruidAverager.java +++ b/src/main/java/in/zapr/druid/druidry/averager/DruidAverager.java @@ -1,25 +1,52 @@ +/* + * Copyright 2018-present Red Brick Lane Marketing Solutions Pvt. Ltd. + * + * 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 2018-present Red Brick Lane Marketing Solutions Pvt. Ltd. + * + * 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 in.zapr.druid.druidry.averager; import com.fasterxml.jackson.annotation.JsonInclude; import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; import lombok.Getter; -import lombok.NonNull; @Getter @EqualsAndHashCode @AllArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) public abstract class DruidAverager { - @NonNull - String type; - @NonNull - String name; - @NonNull - String fieldName; - @NonNull - Integer buckets; - @JsonInclude(JsonInclude.Include.NON_NULL) - Integer cycleSize; + protected String type; + protected String name; + protected String fieldName; + protected Integer buckets; + protected Integer cycleSize; } diff --git a/src/main/java/in/zapr/druid/druidry/averager/LongMaxAverager.java b/src/main/java/in/zapr/druid/druidry/averager/LongMaxAverager.java index 37574086..d52075b3 100644 --- a/src/main/java/in/zapr/druid/druidry/averager/LongMaxAverager.java +++ b/src/main/java/in/zapr/druid/druidry/averager/LongMaxAverager.java @@ -1,5 +1,22 @@ +/* + * Copyright 2018-present Red Brick Lane Marketing Solutions Pvt. Ltd. + * + * 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 in.zapr.druid.druidry.averager; +import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; @@ -10,11 +27,9 @@ public class LongMaxAverager extends DruidAverager { private static final String LONG_MAX_AVERAGER = "longMax"; - public LongMaxAverager(@NonNull String name, @NonNull String fieldName, @NonNull Integer buckets) { - this(name, fieldName, buckets, null); - } - - public LongMaxAverager(String name, String fieldName, Integer buckets, Integer cycleSize) { + @Builder + private LongMaxAverager(@NonNull String name, @NonNull String fieldName, + @NonNull Integer buckets, Integer cycleSize) { super(LONG_MAX_AVERAGER, name, fieldName, buckets, cycleSize); } diff --git a/src/main/java/in/zapr/druid/druidry/averager/LongMeanAverager.java b/src/main/java/in/zapr/druid/druidry/averager/LongMeanAverager.java index d23bf8db..40d98114 100644 --- a/src/main/java/in/zapr/druid/druidry/averager/LongMeanAverager.java +++ b/src/main/java/in/zapr/druid/druidry/averager/LongMeanAverager.java @@ -1,5 +1,22 @@ +/* + * Copyright 2018-present Red Brick Lane Marketing Solutions Pvt. Ltd. + * + * 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 in.zapr.druid.druidry.averager; +import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; @@ -10,11 +27,9 @@ public class LongMeanAverager extends DruidAverager { private static final String LONG_MEAN_AVERAGER = "longMean"; - public LongMeanAverager(@NonNull String name, @NonNull String fieldName, @NonNull Integer buckets) { - this(name, fieldName, buckets, null); - } - - public LongMeanAverager(String name, String fieldName, Integer buckets, Integer cycleSize) { + @Builder + private LongMeanAverager(@NonNull String name, @NonNull String fieldName, + @NonNull Integer buckets, Integer cycleSize) { super(LONG_MEAN_AVERAGER, name, fieldName, buckets, cycleSize); } diff --git a/src/main/java/in/zapr/druid/druidry/averager/LongMeanNoNullsAverager.java b/src/main/java/in/zapr/druid/druidry/averager/LongMeanNoNullsAverager.java index be9fb7f2..65d24112 100644 --- a/src/main/java/in/zapr/druid/druidry/averager/LongMeanNoNullsAverager.java +++ b/src/main/java/in/zapr/druid/druidry/averager/LongMeanNoNullsAverager.java @@ -1,5 +1,22 @@ +/* + * Copyright 2018-present Red Brick Lane Marketing Solutions Pvt. Ltd. + * + * 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 in.zapr.druid.druidry.averager; +import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; @@ -10,11 +27,9 @@ public class LongMeanNoNullsAverager extends DruidAverager { private static final String LONG_MEAN_NO_NULLS_AVERAGER = "longMeanNoNulls"; - public LongMeanNoNullsAverager(@NonNull String name, @NonNull String fieldName, @NonNull Integer buckets) { - this(name, fieldName, buckets, null); - } - - public LongMeanNoNullsAverager(String name, String fieldName, Integer buckets, Integer cycleSize) { + @Builder + private LongMeanNoNullsAverager(@NonNull String name, @NonNull String fieldName, + @NonNull Integer buckets, Integer cycleSize) { super(LONG_MEAN_NO_NULLS_AVERAGER, name, fieldName, buckets, cycleSize); } diff --git a/src/main/java/in/zapr/druid/druidry/averager/LongMinAverager.java b/src/main/java/in/zapr/druid/druidry/averager/LongMinAverager.java index 05d2faad..bc5903dd 100644 --- a/src/main/java/in/zapr/druid/druidry/averager/LongMinAverager.java +++ b/src/main/java/in/zapr/druid/druidry/averager/LongMinAverager.java @@ -1,5 +1,22 @@ +/* + * Copyright 2018-present Red Brick Lane Marketing Solutions Pvt. Ltd. + * + * 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 in.zapr.druid.druidry.averager; +import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; @@ -10,11 +27,9 @@ public class LongMinAverager extends DruidAverager { private static final String LONG_MIN_AVERAGER = "longMin"; - public LongMinAverager(@NonNull String name, @NonNull String fieldName, @NonNull Integer buckets) { - this(name, fieldName, buckets, null); - } - - public LongMinAverager(String name, String fieldName, Integer buckets, Integer cycleSize) { + @Builder + private LongMinAverager(@NonNull String name, @NonNull String fieldName, + @NonNull Integer buckets, Integer cycleSize) { super(LONG_MIN_AVERAGER, name, fieldName, buckets, cycleSize); } diff --git a/src/main/java/in/zapr/druid/druidry/averager/LongSumAverager.java b/src/main/java/in/zapr/druid/druidry/averager/LongSumAverager.java index bbad0abd..047d0f0c 100644 --- a/src/main/java/in/zapr/druid/druidry/averager/LongSumAverager.java +++ b/src/main/java/in/zapr/druid/druidry/averager/LongSumAverager.java @@ -1,5 +1,22 @@ +/* + * Copyright 2018-present Red Brick Lane Marketing Solutions Pvt. Ltd. + * + * 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 in.zapr.druid.druidry.averager; +import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; @@ -10,11 +27,9 @@ public class LongSumAverager extends DruidAverager { private static final String LONG_SUM_AVERAGER = "longSum"; - public LongSumAverager(@NonNull String name, @NonNull String fieldName, @NonNull Integer buckets) { - this(name, fieldName, buckets, null); - } - - public LongSumAverager(String name, String fieldName, Integer buckets, Integer cycleSize) { + @Builder + private LongSumAverager(@NonNull String name, @NonNull String fieldName, + @NonNull Integer buckets, Integer cycleSize) { super(LONG_SUM_AVERAGER, name, fieldName, buckets, cycleSize); } diff --git a/src/main/java/in/zapr/druid/druidry/query/aggregation/DruidMovingAverageQuery.java b/src/main/java/in/zapr/druid/druidry/query/aggregation/DruidMovingAverageQuery.java index 246994b1..3effde1c 100644 --- a/src/main/java/in/zapr/druid/druidry/query/aggregation/DruidMovingAverageQuery.java +++ b/src/main/java/in/zapr/druid/druidry/query/aggregation/DruidMovingAverageQuery.java @@ -1,6 +1,25 @@ +/* + * Copyright 2018-present Red Brick Lane Marketing Solutions Pvt. Ltd. + * + * 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 in.zapr.druid.druidry.query.aggregation; import com.fasterxml.jackson.annotation.JsonInclude; + +import java.util.List; + import in.zapr.druid.druidry.aggregator.DruidAggregator; import in.zapr.druid.druidry.averager.DruidAverager; import in.zapr.druid.druidry.dataSource.DataSource; @@ -18,8 +37,6 @@ import lombok.Getter; import lombok.NonNull; -import java.util.List; - @Getter @JsonInclude(JsonInclude.Include.NON_NULL) @EqualsAndHashCode(callSuper = true) diff --git a/src/test/java/in/zapr/druid/druidry/query/aggregation/MovingAverageCreators.java b/src/test/java/in/zapr/druid/druidry/query/aggregation/MovingAverageCreators.java new file mode 100644 index 00000000..659b1c68 --- /dev/null +++ b/src/test/java/in/zapr/druid/druidry/query/aggregation/MovingAverageCreators.java @@ -0,0 +1,124 @@ +/* + * Copyright 2018-present Red Brick Lane Marketing Solutions Pvt. Ltd. + * + * 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 in.zapr.druid.druidry.query.aggregation; + +import in.zapr.druid.druidry.averager.DoubleMaxAverager; +import in.zapr.druid.druidry.averager.DoubleMeanAverager; +import in.zapr.druid.druidry.averager.DoubleMeanNoNullsAverager; +import in.zapr.druid.druidry.averager.DoubleMinAverager; +import in.zapr.druid.druidry.averager.DoubleSumAverager; +import in.zapr.druid.druidry.averager.DruidAverager; +import in.zapr.druid.druidry.averager.LongMaxAverager; +import in.zapr.druid.druidry.averager.LongMeanAverager; +import in.zapr.druid.druidry.averager.LongMeanNoNullsAverager; +import in.zapr.druid.druidry.averager.LongMinAverager; +import in.zapr.druid.druidry.averager.LongSumAverager; + +class MovingAverageCreators { + + private MovingAverageCreators() { + + } + + static DruidAverager doubleMax(String name, String fieldName, int buckets) { + return DoubleMaxAverager.builder() + .name(name) + .fieldName(fieldName) + .buckets(buckets) + .build(); + } + + public static DruidAverager doubleMean(String name, String fieldName, int buckets) { + return DoubleMeanAverager.builder() + .name(name) + .fieldName(fieldName) + .buckets(buckets) + .build(); + } + + public static DruidAverager doubleMeanNoNulls(String name, String fieldName, int buckets) { + return DoubleMeanNoNullsAverager.builder() + .name(name) + .fieldName(fieldName) + .buckets(buckets) + .build(); + } + + public static DruidAverager doubleMin(String name, String fieldName, int buckets) { + return DoubleMinAverager.builder() + .name(name) + .fieldName(fieldName) + .buckets(buckets) + .build(); + } + + public static DruidAverager doubleSum(String name, String fieldName, int buckets) { + return DoubleSumAverager.builder() + .name(name) + .fieldName(fieldName) + .buckets(buckets) + .build(); + } + + public static DruidAverager longMax(String name, String fieldName, int buckets) { + return LongMaxAverager.builder() + .name(name) + .fieldName(fieldName) + .buckets(buckets) + .build(); + } + + public static DruidAverager longMean(String name, String fieldName, int buckets) { + return LongMeanAverager.builder() + .name(name) + .fieldName(fieldName) + .buckets(buckets) + .build(); + } + + public static DruidAverager longMeanNoNulls(String name, String fieldName, int buckets) { + return LongMeanNoNullsAverager.builder() + .name(name) + .fieldName(fieldName) + .buckets(buckets) + .build(); + } + + public static DruidAverager longMin(String name, String fieldName, int buckets) { + return LongMinAverager.builder() + .name(name) + .fieldName(fieldName) + .buckets(buckets) + .build(); + } + + public static DruidAverager longSum(String name, String fieldName, int buckets) { + return LongSumAverager.builder() + .name(name) + .fieldName(fieldName) + .buckets(buckets) + .build(); + } + + @FunctionalInterface + interface Creator { + + DruidAverager apply(String name, String fieldName, int buckets); + + } + +} diff --git a/src/test/java/in/zapr/druid/druidry/query/aggregation/MovingAverageTest.java b/src/test/java/in/zapr/druid/druidry/query/aggregation/MovingAverageTest.java index ba8e3975..9a6caa12 100644 --- a/src/test/java/in/zapr/druid/druidry/query/aggregation/MovingAverageTest.java +++ b/src/test/java/in/zapr/druid/druidry/query/aggregation/MovingAverageTest.java @@ -1,24 +1,43 @@ +/* + * Copyright 2018-present Red Brick Lane Marketing Solutions Pvt. Ltd. + * + * 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 in.zapr.druid.druidry.query.aggregation; -import static com.google.common.collect.ImmutableList.of; -import static java.util.Collections.singletonList; -import static org.testng.Assert.assertTrue; +import com.google.common.io.Resources; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.io.Resources; + +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.skyscreamer.jsonassert.JSONAssert; +import org.skyscreamer.jsonassert.JSONCompareMode; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.testng.reporters.Files; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + import in.zapr.druid.druidry.aggregator.DoubleSumAggregator; import in.zapr.druid.druidry.aggregator.DruidAggregator; -import in.zapr.druid.druidry.averager.DoubleMaxAverager; import in.zapr.druid.druidry.averager.DoubleMeanAverager; -import in.zapr.druid.druidry.averager.DoubleMeanNoNullsAverager; -import in.zapr.druid.druidry.averager.DoubleMinAverager; -import in.zapr.druid.druidry.averager.DoubleSumAverager; import in.zapr.druid.druidry.averager.DruidAverager; -import in.zapr.druid.druidry.averager.LongMaxAverager; -import in.zapr.druid.druidry.averager.LongMeanAverager; -import in.zapr.druid.druidry.averager.LongMeanNoNullsAverager; -import in.zapr.druid.druidry.averager.LongMinAverager; -import in.zapr.druid.druidry.averager.LongSumAverager; import in.zapr.druid.druidry.dataSource.TableDataSource; import in.zapr.druid.druidry.dimension.DruidDimension; import in.zapr.druid.druidry.dimension.SimpleDimension; @@ -32,19 +51,10 @@ import in.zapr.druid.druidry.postAggregator.FieldAccessPostAggregator; import in.zapr.druid.druidry.query.config.Context; import in.zapr.druid.druidry.query.config.Interval; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.skyscreamer.jsonassert.JSONAssert; -import org.skyscreamer.jsonassert.JSONCompareMode; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; -import org.testng.reporters.Files; -import java.io.File; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; +import static com.google.common.collect.ImmutableList.of; +import static java.util.Collections.singletonList; +import static org.testng.Assert.assertTrue; public class MovingAverageTest { @@ -59,7 +69,7 @@ public void init() { public void testSimpleQuery() throws Exception { String expectedJson = loadExpectedJson("simple.json"); - DruidMovingAverageQuery query = simpleQuery(DoubleMeanAverager::new); + DruidMovingAverageQuery query = simpleQuery(MovingAverageCreators::doubleMean); String actualJson = objectMapper.writeValueAsString(query); JSONAssert.assertEquals(actualJson, expectedJson, JSONCompareMode.NON_EXTENSIBLE); @@ -70,8 +80,9 @@ public void testAllFieldsQuery() throws Exception { String expectedJson = loadExpectedJson("allFields.json"); DruidDimension druidDimension1 = new SimpleDimension("dimension_1"); DruidDimension druidDimension2 = new SimpleDimension("dimension_2"); - DefaultLimitSpec limitSpec = new DefaultLimitSpec(5000, of(new OrderByColumnSpecString("column_1"), - new OrderByColumnSpecString("column_2"))); + DefaultLimitSpec limitSpec = + new DefaultLimitSpec(5000, of(new OrderByColumnSpecString("column_1"), + new OrderByColumnSpecString("column_2"))); DateTime startTime = new DateTime(2020, 2, 1, 0, 0, 0, DateTimeZone.UTC); DateTime endTime = new DateTime(2020, 3, 31, 23, 59, 59, DateTimeZone.UTC); Interval interval = new Interval(startTime, endTime); @@ -79,30 +90,36 @@ public void testAllFieldsQuery() throws Exception { DruidAggregator aggregator = new DoubleSumAggregator(averagedName, "aggregatedFieldName"); DruidPostAggregator postAggregator = new FieldAccessPostAggregator("postAggregatedFieldName"); Context context = Context.builder().useCache(true).build(); - DruidAverager averager = new DoubleMeanAverager("averagingResult", averagedName, 60, 5); + DruidAverager averager = DoubleMeanAverager.builder() + .name("averagingResult") + .fieldName(averagedName) + .buckets(60) + .cycleSize(5) + .build(); DruidPostAggregator postAverager = new FieldAccessPostAggregator("postAveragedFieldName"); DruidMovingAverageQuery query = DruidMovingAverageQuery.builder() - .dataSource(new TableDataSource("allFieldsDataSource")) - .dimensions(of(druidDimension1, druidDimension2)) - .limitSpec(limitSpec) - .having(new EqualToHaving("havingField", 5)) - .granularity(new SimpleGranularity(PredefinedGranularity.FIFTEEN_MINUTE)) - .filter(new SelectorFilter("selectorField", "selectorValue")) - .aggregations(singletonList(aggregator)) - .postAggregations(singletonList(postAggregator)) - .intervals(singletonList(interval)) - .context(context) - .averagers(singletonList(averager)) - .postAveragers(singletonList(postAverager)) - .build(); + .dataSource(new TableDataSource("allFieldsDataSource")) + .dimensions(of(druidDimension1, druidDimension2)) + .limitSpec(limitSpec) + .having(new EqualToHaving("havingField", 5)) + .granularity(new SimpleGranularity(PredefinedGranularity.FIFTEEN_MINUTE)) + .filter(new SelectorFilter("selectorField", "selectorValue")) + .aggregations(singletonList(aggregator)) + .postAggregations(singletonList(postAggregator)) + .intervals(singletonList(interval)) + .context(context) + .averagers(singletonList(averager)) + .postAveragers(singletonList(postAverager)) + .build(); String actualJson = objectMapper.writeValueAsString(query); JSONAssert.assertEquals(actualJson, expectedJson, JSONCompareMode.NON_EXTENSIBLE); } @Test(dataProvider = "averagerTypesProvider") - public void testAllAveragerTypes(String averagerName, TriFunction averagerCreator) + public void testAllAveragerTypes(String averagerName, + MovingAverageCreators.Creator averagerCreator) throws Exception { String expectedJson = loadExpectedJsonForType(averagerName); @@ -114,17 +131,17 @@ public void testAllAveragerTypes(String averagerName, TriFunction) DoubleMaxAverager::new }, - { "doubleMean", (TriFunction) DoubleMeanAverager::new }, - { "doubleMeanNoNulls", (TriFunction) DoubleMeanNoNullsAverager::new }, - { "doubleMin", (TriFunction) DoubleMinAverager::new }, - { "doubleSum", (TriFunction) DoubleSumAverager::new }, - { "longMax", (TriFunction) LongMaxAverager::new }, - { "longMean", (TriFunction) LongMeanAverager::new }, - { "longMeanNoNulls", (TriFunction) LongMeanNoNullsAverager::new }, - { "longMin", (TriFunction) LongMinAverager::new }, - { "longSum", (TriFunction) LongSumAverager::new } + return new Object[][]{ + {"doubleMax", (MovingAverageCreators.Creator) MovingAverageCreators::doubleMax}, + {"doubleMean", (MovingAverageCreators.Creator) MovingAverageCreators::doubleMean}, + {"doubleMeanNoNulls", (MovingAverageCreators.Creator) MovingAverageCreators::doubleMeanNoNulls}, + {"doubleMin", (MovingAverageCreators.Creator) MovingAverageCreators::doubleMin}, + {"doubleSum", (MovingAverageCreators.Creator) MovingAverageCreators::doubleSum}, + {"longMax", (MovingAverageCreators.Creator) MovingAverageCreators::longMax}, + {"longMean", (MovingAverageCreators.Creator) MovingAverageCreators::longMean}, + {"longMeanNoNulls", (MovingAverageCreators.Creator) MovingAverageCreators::longMeanNoNulls}, + {"longMin", (MovingAverageCreators.Creator) MovingAverageCreators::longMin}, + {"longSum", (MovingAverageCreators.Creator) MovingAverageCreators::longSum} }; } @@ -141,7 +158,8 @@ private String loadExpectedJson(String fileName) throws IOException, URISyntaxEx return Files.readFile(jsonFile); } - private static DruidMovingAverageQuery simpleQuery(TriFunction averagerCreator) { + private static DruidMovingAverageQuery simpleQuery( + MovingAverageCreators.Creator averagerCreator) { DateTime startTime = new DateTime(2020, 1, 1, 0, 0, 0, DateTimeZone.UTC); DateTime endTime = new DateTime(2020, 2, 29, 23, 59, 59, DateTimeZone.UTC); Interval interval = new Interval(startTime, endTime); @@ -150,19 +168,12 @@ private static DruidMovingAverageQuery simpleQuery(TriFunction { - - T apply(V1 v1, V2 v2, V3 v3); - + .dataSource(new TableDataSource("simpleDataSource")) + .granularity(new SimpleGranularity(PredefinedGranularity.DAY)) + .aggregations(singletonList(aggregator)) + .intervals(singletonList(interval)) + .averagers(singletonList(averager)) + .build(); } } From ee8c2753692dc7f0baff0cb64b6dc09e32d47e3b Mon Sep 17 00:00:00 2001 From: Jonasz Czerepko Date: Thu, 12 Mar 2020 09:21:21 +0100 Subject: [PATCH 11/25] Added stringFirst and stringLast aggregators. https://druid.apache.org/docs/latest/querying/aggregations.html#stringfirst-aggregator --- .../druidry/aggregator/StringAggregator.java | 41 ++++++++++ .../aggregator/StringFirstAggregator.java | 34 ++++++++ .../aggregator/StringLastAggregator.java | 34 ++++++++ .../aggregator/StringFirstAggregatorTest.java | 81 +++++++++++++++++++ .../aggregator/StringLastAggregatorTest.java | 81 +++++++++++++++++++ 5 files changed, 271 insertions(+) create mode 100644 src/main/java/in/zapr/druid/druidry/aggregator/StringAggregator.java create mode 100644 src/main/java/in/zapr/druid/druidry/aggregator/StringFirstAggregator.java create mode 100644 src/main/java/in/zapr/druid/druidry/aggregator/StringLastAggregator.java create mode 100644 src/test/java/in/zapr/druid/druidry/aggregator/StringFirstAggregatorTest.java create mode 100644 src/test/java/in/zapr/druid/druidry/aggregator/StringLastAggregatorTest.java diff --git a/src/main/java/in/zapr/druid/druidry/aggregator/StringAggregator.java b/src/main/java/in/zapr/druid/druidry/aggregator/StringAggregator.java new file mode 100644 index 00000000..36e500e0 --- /dev/null +++ b/src/main/java/in/zapr/druid/druidry/aggregator/StringAggregator.java @@ -0,0 +1,41 @@ +/* + * Copyright 2018-present Red Brick Lane Marketing Solutions Pvt. Ltd. + * + * 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 in.zapr.druid.druidry.aggregator; + +import com.fasterxml.jackson.annotation.JsonInclude; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NonNull; + +@Getter +@EqualsAndHashCode(callSuper = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +abstract class StringAggregator extends DruidAggregator { + + private String fieldName; + private Integer maxStringBytes; + + StringAggregator(@NonNull String type, @NonNull String name, @NonNull String fieldName, + Integer maxStringBytes) { + this.type = type; + this.name = name; + this.fieldName = fieldName; + this.maxStringBytes = maxStringBytes; + } + +} diff --git a/src/main/java/in/zapr/druid/druidry/aggregator/StringFirstAggregator.java b/src/main/java/in/zapr/druid/druidry/aggregator/StringFirstAggregator.java new file mode 100644 index 00000000..c28014a3 --- /dev/null +++ b/src/main/java/in/zapr/druid/druidry/aggregator/StringFirstAggregator.java @@ -0,0 +1,34 @@ +/* + * Copyright 2018-present Red Brick Lane Marketing Solutions Pvt. Ltd. + * + * 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 in.zapr.druid.druidry.aggregator; + +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.NonNull; + +@EqualsAndHashCode(callSuper = true) +public class StringFirstAggregator extends StringAggregator { + + public static final String STRING_FIRST_TYPE = "stringFirst"; + + @Builder + private StringFirstAggregator(@NonNull String name, @NonNull String fieldName, + Integer maxStringBytes) { + super(STRING_FIRST_TYPE, name, fieldName, maxStringBytes); + } + +} diff --git a/src/main/java/in/zapr/druid/druidry/aggregator/StringLastAggregator.java b/src/main/java/in/zapr/druid/druidry/aggregator/StringLastAggregator.java new file mode 100644 index 00000000..191042df --- /dev/null +++ b/src/main/java/in/zapr/druid/druidry/aggregator/StringLastAggregator.java @@ -0,0 +1,34 @@ +/* + * Copyright 2018-present Red Brick Lane Marketing Solutions Pvt. Ltd. + * + * 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 in.zapr.druid.druidry.aggregator; + +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.NonNull; + +@EqualsAndHashCode(callSuper = true) +public class StringLastAggregator extends StringAggregator { + + public static final String STRING_LAST_TYPE = "stringLast"; + + @Builder + private StringLastAggregator(@NonNull String name, @NonNull String fieldName, + Integer maxStringBytes) { + super(STRING_LAST_TYPE, name, fieldName, maxStringBytes); + } + +} diff --git a/src/test/java/in/zapr/druid/druidry/aggregator/StringFirstAggregatorTest.java b/src/test/java/in/zapr/druid/druidry/aggregator/StringFirstAggregatorTest.java new file mode 100644 index 00000000..ac30bf17 --- /dev/null +++ b/src/test/java/in/zapr/druid/druidry/aggregator/StringFirstAggregatorTest.java @@ -0,0 +1,81 @@ +/* + * Copyright 2018-present Red Brick Lane Marketing Solutions Pvt. Ltd. + * + * 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 in.zapr.druid.druidry.aggregator; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.json.JSONException; +import org.json.JSONObject; +import org.skyscreamer.jsonassert.JSONAssert; +import org.skyscreamer.jsonassert.JSONCompareMode; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +public class StringFirstAggregatorTest { + + private static ObjectMapper objectMapper; + + @BeforeClass + public void init() { + objectMapper = new ObjectMapper(); + } + + @Test + public void testRequiredFields() throws JsonProcessingException, JSONException { + String name = "stringFirstNameRequired"; + String fieldName = "stringFirstFieldNameRequired"; + + DruidAggregator stringFirstAggregator = StringFirstAggregator.builder() + .name(name) + .fieldName(fieldName) + .build(); + + JSONObject jsonObject = new JSONObject(); + jsonObject.put("type", "stringFirst"); + jsonObject.put("name", name); + jsonObject.put("fieldName", fieldName); + + String actualJSON = objectMapper.writeValueAsString(stringFirstAggregator); + String expectedJSON = jsonObject.toString(); + JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.NON_EXTENSIBLE); + } + + @Test + public void testAllFields() throws JsonProcessingException, JSONException { + String name = "stringFirstNameAll"; + String fieldName = "stringFirstFieldNameAll"; + int maxStringBytes = 300; + + DruidAggregator stringFirstAggregator = StringFirstAggregator.builder() + .name(name) + .fieldName(fieldName) + .maxStringBytes(maxStringBytes) + .build(); + + JSONObject jsonObject = new JSONObject(); + jsonObject.put("type", "stringFirst"); + jsonObject.put("name", name); + jsonObject.put("fieldName", fieldName); + jsonObject.put("maxStringBytes", maxStringBytes); + + String actualJSON = objectMapper.writeValueAsString(stringFirstAggregator); + String expectedJSON = jsonObject.toString(); + JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.NON_EXTENSIBLE); + } + +} diff --git a/src/test/java/in/zapr/druid/druidry/aggregator/StringLastAggregatorTest.java b/src/test/java/in/zapr/druid/druidry/aggregator/StringLastAggregatorTest.java new file mode 100644 index 00000000..4a5b93ab --- /dev/null +++ b/src/test/java/in/zapr/druid/druidry/aggregator/StringLastAggregatorTest.java @@ -0,0 +1,81 @@ +/* + * Copyright 2018-present Red Brick Lane Marketing Solutions Pvt. Ltd. + * + * 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 in.zapr.druid.druidry.aggregator; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.json.JSONException; +import org.json.JSONObject; +import org.skyscreamer.jsonassert.JSONAssert; +import org.skyscreamer.jsonassert.JSONCompareMode; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +public class StringLastAggregatorTest { + + private static ObjectMapper objectMapper; + + @BeforeClass + public void init() { + objectMapper = new ObjectMapper(); + } + + @Test + public void testRequiredFields() throws JsonProcessingException, JSONException { + String name = "stringLastNameRequired"; + String fieldName = "stringLastFieldNameRequired"; + + DruidAggregator stringLastAggregator = StringLastAggregator.builder() + .name(name) + .fieldName(fieldName) + .build(); + + JSONObject jsonObject = new JSONObject(); + jsonObject.put("type", "stringLast"); + jsonObject.put("name", name); + jsonObject.put("fieldName", fieldName); + + String actualJSON = objectMapper.writeValueAsString(stringLastAggregator); + String expectedJSON = jsonObject.toString(); + JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.NON_EXTENSIBLE); + } + + @Test + public void testAllFields() throws JsonProcessingException, JSONException { + String name = "stringLastNameAll"; + String fieldName = "stringLastFieldNameAll"; + int maxStringBytes = 300; + + DruidAggregator stringLastAggregator = StringLastAggregator.builder() + .name(name) + .fieldName(fieldName) + .maxStringBytes(maxStringBytes) + .build(); + + JSONObject jsonObject = new JSONObject(); + jsonObject.put("type", "stringLast"); + jsonObject.put("name", name); + jsonObject.put("fieldName", fieldName); + jsonObject.put("maxStringBytes", maxStringBytes); + + String actualJSON = objectMapper.writeValueAsString(stringLastAggregator); + String expectedJSON = jsonObject.toString(); + JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.NON_EXTENSIBLE); + } + +} From 0541b6cbfcda90a0a588754dcbcbcb44315ccce4 Mon Sep 17 00:00:00 2001 From: Jonasz Czerepko Date: Mon, 16 Mar 2020 07:43:06 +0100 Subject: [PATCH 12/25] Added tests for trying to build moving average query without required params. --- .../query/aggregation/MovingAverageTest.java | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/src/test/java/in/zapr/druid/druidry/query/aggregation/MovingAverageTest.java b/src/test/java/in/zapr/druid/druidry/query/aggregation/MovingAverageTest.java index 9a6caa12..dff9864d 100644 --- a/src/test/java/in/zapr/druid/druidry/query/aggregation/MovingAverageTest.java +++ b/src/test/java/in/zapr/druid/druidry/query/aggregation/MovingAverageTest.java @@ -117,6 +117,101 @@ public void testAllFieldsQuery() throws Exception { JSONAssert.assertEquals(actualJson, expectedJson, JSONCompareMode.NON_EXTENSIBLE); } + @Test(expectedExceptions = NullPointerException.class) + public void tryToBuildWithoutDataSource() { + DateTime startTime = new DateTime(2020, 2, 1, 0, 0, 0, DateTimeZone.UTC); + DateTime endTime = new DateTime(2020, 3, 31, 23, 59, 59, DateTimeZone.UTC); + Interval interval = new Interval(startTime, endTime); + DruidAggregator aggregator = new DoubleSumAggregator("name", "fieldName"); + DruidAverager averager = DoubleMeanAverager.builder() + .name("name") + .fieldName("fieldName") + .buckets(60) + .cycleSize(5) + .build(); + + DruidMovingAverageQuery.builder() + .granularity(new SimpleGranularity(PredefinedGranularity.FIFTEEN_MINUTE)) + .intervals(singletonList(interval)) + .aggregations(singletonList(aggregator)) + .averagers(singletonList(averager)) + .build(); + } + + @Test(expectedExceptions = NullPointerException.class) + public void tryToBuildWithoutGranularity() { + DateTime startTime = new DateTime(2020, 2, 1, 0, 0, 0, DateTimeZone.UTC); + DateTime endTime = new DateTime(2020, 3, 31, 23, 59, 59, DateTimeZone.UTC); + Interval interval = new Interval(startTime, endTime); + DruidAggregator aggregator = new DoubleSumAggregator("name", "fieldName"); + DruidAverager averager = DoubleMeanAverager.builder() + .name("name") + .fieldName("fieldName") + .buckets(60) + .cycleSize(5) + .build(); + + DruidMovingAverageQuery.builder() + .dataSource(new TableDataSource("dataSource")) + .intervals(singletonList(interval)) + .aggregations(singletonList(aggregator)) + .averagers(singletonList(averager)) + .build(); + } + + @Test(expectedExceptions = NullPointerException.class) + public void tryToBuildWithoutAggregations() { + DateTime startTime = new DateTime(2020, 2, 1, 0, 0, 0, DateTimeZone.UTC); + DateTime endTime = new DateTime(2020, 3, 31, 23, 59, 59, DateTimeZone.UTC); + Interval interval = new Interval(startTime, endTime); + DruidAverager averager = DoubleMeanAverager.builder() + .name("name") + .fieldName("fieldName") + .buckets(60) + .cycleSize(5) + .build(); + + DruidMovingAverageQuery.builder() + .dataSource(new TableDataSource("dataSource")) + .granularity(new SimpleGranularity(PredefinedGranularity.FIFTEEN_MINUTE)) + .intervals(singletonList(interval)) + .averagers(singletonList(averager)) + .build(); + } + + @Test(expectedExceptions = NullPointerException.class) + public void tryToBuildWithoutIntervals() { + DruidAggregator aggregator = new DoubleSumAggregator("name", "fieldName"); + DruidAverager averager = DoubleMeanAverager.builder() + .name("name") + .fieldName("fieldName") + .buckets(60) + .cycleSize(5) + .build(); + + DruidMovingAverageQuery.builder() + .dataSource(new TableDataSource("dataSource")) + .granularity(new SimpleGranularity(PredefinedGranularity.FIFTEEN_MINUTE)) + .aggregations(singletonList(aggregator)) + .averagers(singletonList(averager)) + .build(); + } + + @Test(expectedExceptions = NullPointerException.class) + public void tryToBuildWithoutAveragers() { + DateTime startTime = new DateTime(2020, 2, 1, 0, 0, 0, DateTimeZone.UTC); + DateTime endTime = new DateTime(2020, 3, 31, 23, 59, 59, DateTimeZone.UTC); + Interval interval = new Interval(startTime, endTime); + DruidAggregator aggregator = new DoubleSumAggregator("name", "fieldName"); + + DruidMovingAverageQuery.builder() + .dataSource(new TableDataSource("dataSource")) + .granularity(new SimpleGranularity(PredefinedGranularity.FIFTEEN_MINUTE)) + .intervals(singletonList(interval)) + .aggregations(singletonList(aggregator)) + .build(); + } + @Test(dataProvider = "averagerTypesProvider") public void testAllAveragerTypes(String averagerName, MovingAverageCreators.Creator averagerCreator) From 973221ec788182cf05e6b615dbd05ed33157a9e0 Mon Sep 17 00:00:00 2001 From: Jonasz Czerepko Date: Mon, 16 Mar 2020 07:50:51 +0100 Subject: [PATCH 13/25] Removed abstract StringAggregator class. Added tests for trying to build string aggregators without required fields. --- .../druidry/aggregator/StringAggregator.java | 41 ------------------- .../aggregator/StringFirstAggregator.java | 19 +++++++-- .../aggregator/StringLastAggregator.java | 17 ++++++-- .../aggregator/StringFirstAggregatorTest.java | 14 +++++++ .../aggregator/StringLastAggregatorTest.java | 14 +++++++ 5 files changed, 57 insertions(+), 48 deletions(-) delete mode 100644 src/main/java/in/zapr/druid/druidry/aggregator/StringAggregator.java diff --git a/src/main/java/in/zapr/druid/druidry/aggregator/StringAggregator.java b/src/main/java/in/zapr/druid/druidry/aggregator/StringAggregator.java deleted file mode 100644 index 36e500e0..00000000 --- a/src/main/java/in/zapr/druid/druidry/aggregator/StringAggregator.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2018-present Red Brick Lane Marketing Solutions Pvt. Ltd. - * - * 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 in.zapr.druid.druidry.aggregator; - -import com.fasterxml.jackson.annotation.JsonInclude; - -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NonNull; - -@Getter -@EqualsAndHashCode(callSuper = true) -@JsonInclude(JsonInclude.Include.NON_NULL) -abstract class StringAggregator extends DruidAggregator { - - private String fieldName; - private Integer maxStringBytes; - - StringAggregator(@NonNull String type, @NonNull String name, @NonNull String fieldName, - Integer maxStringBytes) { - this.type = type; - this.name = name; - this.fieldName = fieldName; - this.maxStringBytes = maxStringBytes; - } - -} diff --git a/src/main/java/in/zapr/druid/druidry/aggregator/StringFirstAggregator.java b/src/main/java/in/zapr/druid/druidry/aggregator/StringFirstAggregator.java index c28014a3..d3c35c69 100644 --- a/src/main/java/in/zapr/druid/druidry/aggregator/StringFirstAggregator.java +++ b/src/main/java/in/zapr/druid/druidry/aggregator/StringFirstAggregator.java @@ -16,19 +16,30 @@ package in.zapr.druid.druidry.aggregator; +import com.fasterxml.jackson.annotation.JsonInclude; + import lombok.Builder; import lombok.EqualsAndHashCode; +import lombok.Getter; import lombok.NonNull; +@Getter @EqualsAndHashCode(callSuper = true) -public class StringFirstAggregator extends StringAggregator { +@JsonInclude(JsonInclude.Include.NON_NULL) +public class StringFirstAggregator extends DruidAggregator { + + private static final String STRING_FIRST_TYPE = "stringFirst"; - public static final String STRING_FIRST_TYPE = "stringFirst"; + private String fieldName; + private Integer maxStringBytes; @Builder private StringFirstAggregator(@NonNull String name, @NonNull String fieldName, - Integer maxStringBytes) { - super(STRING_FIRST_TYPE, name, fieldName, maxStringBytes); + Integer maxStringBytes) { + this.type = STRING_FIRST_TYPE; + this.name = name; + this.fieldName = fieldName; + this.maxStringBytes = maxStringBytes; } } diff --git a/src/main/java/in/zapr/druid/druidry/aggregator/StringLastAggregator.java b/src/main/java/in/zapr/druid/druidry/aggregator/StringLastAggregator.java index 191042df..4260c478 100644 --- a/src/main/java/in/zapr/druid/druidry/aggregator/StringLastAggregator.java +++ b/src/main/java/in/zapr/druid/druidry/aggregator/StringLastAggregator.java @@ -16,19 +16,30 @@ package in.zapr.druid.druidry.aggregator; +import com.fasterxml.jackson.annotation.JsonInclude; + import lombok.Builder; import lombok.EqualsAndHashCode; +import lombok.Getter; import lombok.NonNull; +@Getter @EqualsAndHashCode(callSuper = true) -public class StringLastAggregator extends StringAggregator { +@JsonInclude(JsonInclude.Include.NON_NULL) +public class StringLastAggregator extends DruidAggregator { + + private static final String STRING_LAST_TYPE = "stringLast"; - public static final String STRING_LAST_TYPE = "stringLast"; + private String fieldName; + private Integer maxStringBytes; @Builder private StringLastAggregator(@NonNull String name, @NonNull String fieldName, Integer maxStringBytes) { - super(STRING_LAST_TYPE, name, fieldName, maxStringBytes); + this.type = STRING_LAST_TYPE; + this.name = name; + this.fieldName = fieldName; + this.maxStringBytes = maxStringBytes; } } diff --git a/src/test/java/in/zapr/druid/druidry/aggregator/StringFirstAggregatorTest.java b/src/test/java/in/zapr/druid/druidry/aggregator/StringFirstAggregatorTest.java index ac30bf17..6e6b3b61 100644 --- a/src/test/java/in/zapr/druid/druidry/aggregator/StringFirstAggregatorTest.java +++ b/src/test/java/in/zapr/druid/druidry/aggregator/StringFirstAggregatorTest.java @@ -78,4 +78,18 @@ public void testAllFields() throws JsonProcessingException, JSONException { JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.NON_EXTENSIBLE); } + @Test(expectedExceptions = NullPointerException.class) + public void tryToCreateWithoutName() { + StringFirstAggregator.builder() + .fieldName("fieldName") + .build(); + } + + @Test(expectedExceptions = NullPointerException.class) + public void tryToCreateWithoutFieldName() { + StringFirstAggregator.builder() + .name("name") + .build(); + } + } diff --git a/src/test/java/in/zapr/druid/druidry/aggregator/StringLastAggregatorTest.java b/src/test/java/in/zapr/druid/druidry/aggregator/StringLastAggregatorTest.java index 4a5b93ab..19d98be1 100644 --- a/src/test/java/in/zapr/druid/druidry/aggregator/StringLastAggregatorTest.java +++ b/src/test/java/in/zapr/druid/druidry/aggregator/StringLastAggregatorTest.java @@ -78,4 +78,18 @@ public void testAllFields() throws JsonProcessingException, JSONException { JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.NON_EXTENSIBLE); } + @Test(expectedExceptions = NullPointerException.class) + public void tryToCreateWithoutName() { + StringLastAggregator.builder() + .fieldName("fieldName") + .build(); + } + + @Test(expectedExceptions = NullPointerException.class) + public void tryToCreateWithoutFieldName() { + StringLastAggregator.builder() + .name("name") + .build(); + } + } From 1f35e4b068e7fbc005a2d5973087558b30994aa1 Mon Sep 17 00:00:00 2001 From: Alper Kanat Date: Wed, 18 Mar 2020 00:02:32 +0200 Subject: [PATCH 14/25] Update src/main/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregator.java Co-Authored-By: Abhi <43852557+abhi-zapr@users.noreply.github.com> --- .../druidry/aggregator/DoubleMaxAggregator.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregator.java b/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregator.java index 91d3e4ea..60dcef10 100644 --- a/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregator.java +++ b/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregator.java @@ -42,5 +42,17 @@ public DoubleMaxAggregator(@NonNull String name, @NonNull String fieldName) { this.name = name; this.fieldName = fieldName; } + @Builder + private DoubleMaxAggregator(@NonNull String name, String fieldName, String expression) { + this.type = DOUBLE_MAX_TYPE_AGGREGATOR; + this.name = name; + this.fieldName = fieldName; + this.expression = expression; + + Preconditions.checkArgument( + fieldName == null ^ expression == null, + "Must have a valid, non-null fieldName or expression" + ); + } } From 64186afe8dd4be90c738bdd49aaa7bf245631bd7 Mon Sep 17 00:00:00 2001 From: Alper Kanat Date: Wed, 18 Mar 2020 00:02:59 +0200 Subject: [PATCH 15/25] Update src/main/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregator.java Co-Authored-By: Abhi <43852557+abhi-zapr@users.noreply.github.com> --- .../in/zapr/druid/druidry/aggregator/DoubleMaxAggregator.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregator.java b/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregator.java index 60dcef10..0e05647b 100644 --- a/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregator.java +++ b/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregator.java @@ -23,6 +23,7 @@ @Getter @EqualsAndHashCode(callSuper = true) +@JsonInclude(JsonInclude.Include.NON_NULL) public class DoubleMaxAggregator extends DruidAggregator { private static final String DOUBLE_MAX_TYPE_AGGREGATOR = "doubleMax"; From 7ad4fee45680d22eae84e5a88b6f1f7545967da5 Mon Sep 17 00:00:00 2001 From: Alper Kanat Date: Wed, 18 Mar 2020 00:03:12 +0200 Subject: [PATCH 16/25] Update src/main/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregator.java Co-Authored-By: Abhi <43852557+abhi-zapr@users.noreply.github.com> --- .../in/zapr/druid/druidry/aggregator/DoubleMaxAggregator.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregator.java b/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregator.java index 0e05647b..b91b5a5d 100644 --- a/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregator.java +++ b/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregator.java @@ -38,6 +38,7 @@ public DoubleMaxAggregator(@NonNull String name) { this.name = name; } + @Deprecated public DoubleMaxAggregator(@NonNull String name, @NonNull String fieldName) { this.type = DOUBLE_MAX_TYPE_AGGREGATOR; this.name = name; From 3babe3f213eb65cfffda577e09d1f6d5f2da4bd4 Mon Sep 17 00:00:00 2001 From: Alper Kanat Date: Wed, 18 Mar 2020 02:15:46 +0300 Subject: [PATCH 17/25] Updated aggregators with builder pattern, corrected tests * Also fixed indentation & style of some classes using GoogleStyle --- .../aggregator/DoubleMaxAggregator.java | 20 +- .../aggregator/DoubleMinAggregator.java | 22 +- .../aggregator/DoubleSumAggregator.java | 22 +- .../druidry/aggregator/LongMaxAggregator.java | 22 +- .../druidry/aggregator/LongMinAggregator.java | 22 +- .../druidry/aggregator/LongSumAggregator.java | 22 +- .../aggregator/DoubleMaxAggregatorTest.java | 112 ++++-- .../aggregator/DoubleMinAggregatorTest.java | 112 ++++-- .../aggregator/DoubleSumAggregatorTest.java | 112 ++++-- .../aggregator/LongMaxAggregatorTest.java | 112 ++++-- .../aggregator/LongMinAggregatorTest.java | 112 ++++-- .../aggregator/LongSumAggregatorTest.java | 112 ++++-- .../query/aggregation/GroupByTest.java | 169 ++++----- .../query/aggregation/TimeSeriesTest.java | 163 ++++----- .../query/aggregation/TopNQueryTest.java | 331 +++++++++--------- 15 files changed, 917 insertions(+), 548 deletions(-) diff --git a/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregator.java b/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregator.java index b91b5a5d..cf9532aa 100644 --- a/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregator.java +++ b/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregator.java @@ -16,10 +16,14 @@ package in.zapr.druid.druidry.aggregator; +import com.google.common.base.Preconditions; + +import com.fasterxml.jackson.annotation.JsonInclude; + +import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; -import lombok.Setter; @Getter @EqualsAndHashCode(callSuper = true) @@ -29,32 +33,26 @@ public class DoubleMaxAggregator extends DruidAggregator { private static final String DOUBLE_MAX_TYPE_AGGREGATOR = "doubleMax"; private String fieldName; - - @Setter private String expression; - public DoubleMaxAggregator(@NonNull String name) { - this.type = DOUBLE_MAX_TYPE_AGGREGATOR; - this.name = name; - } - @Deprecated public DoubleMaxAggregator(@NonNull String name, @NonNull String fieldName) { this.type = DOUBLE_MAX_TYPE_AGGREGATOR; this.name = name; this.fieldName = fieldName; } + @Builder private DoubleMaxAggregator(@NonNull String name, String fieldName, String expression) { - this.type = DOUBLE_MAX_TYPE_AGGREGATOR; this.name = name; this.fieldName = fieldName; this.expression = expression; Preconditions.checkArgument( - fieldName == null ^ expression == null, - "Must have a valid, non-null fieldName or expression" + fieldName == null ^ expression == null, + "Must have a valid, non-null fieldName or expression" ); } + } diff --git a/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMinAggregator.java b/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMinAggregator.java index d2ed1a77..11f0c82e 100644 --- a/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMinAggregator.java +++ b/src/main/java/in/zapr/druid/druidry/aggregator/DoubleMinAggregator.java @@ -16,31 +16,43 @@ package in.zapr.druid.druidry.aggregator; +import com.google.common.base.Preconditions; + +import com.fasterxml.jackson.annotation.JsonInclude; + +import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; -import lombok.Setter; @Getter @EqualsAndHashCode(callSuper = true) +@JsonInclude(JsonInclude.Include.NON_NULL) public class DoubleMinAggregator extends DruidAggregator { private static final String DOUBLE_MIN_TYPE_AGGREGATOR = "doubleMin"; private String fieldName; - - @Setter private String expression; - public DoubleMinAggregator(@NonNull String name) { + @Deprecated + public DoubleMinAggregator(@NonNull String name, @NonNull String fieldName) { this.type = DOUBLE_MIN_TYPE_AGGREGATOR; this.name = name; + this.fieldName = fieldName; } - public DoubleMinAggregator(@NonNull String name, @NonNull String fieldName) { + @Builder + private DoubleMinAggregator(@NonNull String name, String fieldName, String expression) { this.type = DOUBLE_MIN_TYPE_AGGREGATOR; this.name = name; this.fieldName = fieldName; + this.expression = expression; + + Preconditions.checkArgument( + fieldName == null ^ expression == null, + "Must have a valid, non-null fieldName or expression" + ); } } diff --git a/src/main/java/in/zapr/druid/druidry/aggregator/DoubleSumAggregator.java b/src/main/java/in/zapr/druid/druidry/aggregator/DoubleSumAggregator.java index 6665d265..3633d253 100644 --- a/src/main/java/in/zapr/druid/druidry/aggregator/DoubleSumAggregator.java +++ b/src/main/java/in/zapr/druid/druidry/aggregator/DoubleSumAggregator.java @@ -16,31 +16,43 @@ package in.zapr.druid.druidry.aggregator; +import com.google.common.base.Preconditions; + +import com.fasterxml.jackson.annotation.JsonInclude; + +import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; -import lombok.Setter; @Getter @EqualsAndHashCode(callSuper = true) +@JsonInclude(JsonInclude.Include.NON_NULL) public class DoubleSumAggregator extends DruidAggregator { private static final String DOUBLE_SUM_TYPE_AGGREGATOR = "doubleSum"; private String fieldName; - - @Setter private String expression; - public DoubleSumAggregator(@NonNull String name) { + @Deprecated + public DoubleSumAggregator(@NonNull String name, @NonNull String fieldName) { this.type = DOUBLE_SUM_TYPE_AGGREGATOR; this.name = name; + this.fieldName = fieldName; } - public DoubleSumAggregator(@NonNull String name, @NonNull String fieldName) { + @Builder + private DoubleSumAggregator(@NonNull String name, String fieldName, String expression) { this.type = DOUBLE_SUM_TYPE_AGGREGATOR; this.name = name; this.fieldName = fieldName; + this.expression = expression; + + Preconditions.checkArgument( + fieldName == null ^ expression == null, + "Must have a valid, non-null fieldName or expression" + ); } } diff --git a/src/main/java/in/zapr/druid/druidry/aggregator/LongMaxAggregator.java b/src/main/java/in/zapr/druid/druidry/aggregator/LongMaxAggregator.java index 1a8c1f60..98e6b6cc 100644 --- a/src/main/java/in/zapr/druid/druidry/aggregator/LongMaxAggregator.java +++ b/src/main/java/in/zapr/druid/druidry/aggregator/LongMaxAggregator.java @@ -16,31 +16,43 @@ package in.zapr.druid.druidry.aggregator; +import com.google.common.base.Preconditions; + +import com.fasterxml.jackson.annotation.JsonInclude; + +import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; -import lombok.Setter; @Getter @EqualsAndHashCode(callSuper = true) +@JsonInclude(JsonInclude.Include.NON_NULL) public class LongMaxAggregator extends DruidAggregator { private static final String LONG_MAX_TYPE_AGGREGATOR = "longMax"; private String fieldName; - - @Setter private String expression; - public LongMaxAggregator(@NonNull String name) { + @Deprecated + public LongMaxAggregator(@NonNull String name, @NonNull String fieldName) { this.type = LONG_MAX_TYPE_AGGREGATOR; this.name = name; + this.fieldName = fieldName; } - public LongMaxAggregator(@NonNull String name, @NonNull String fieldName) { + @Builder + private LongMaxAggregator(@NonNull String name, String fieldName, String expression) { this.type = LONG_MAX_TYPE_AGGREGATOR; this.name = name; this.fieldName = fieldName; + this.expression = expression; + + Preconditions.checkArgument( + fieldName == null ^ expression == null, + "Must have a valid, non-null fieldName or expression" + ); } } diff --git a/src/main/java/in/zapr/druid/druidry/aggregator/LongMinAggregator.java b/src/main/java/in/zapr/druid/druidry/aggregator/LongMinAggregator.java index 80227fbd..3c569846 100644 --- a/src/main/java/in/zapr/druid/druidry/aggregator/LongMinAggregator.java +++ b/src/main/java/in/zapr/druid/druidry/aggregator/LongMinAggregator.java @@ -16,31 +16,43 @@ package in.zapr.druid.druidry.aggregator; +import com.google.common.base.Preconditions; + +import com.fasterxml.jackson.annotation.JsonInclude; + +import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; -import lombok.Setter; @Getter @EqualsAndHashCode(callSuper = true) +@JsonInclude(JsonInclude.Include.NON_NULL) public class LongMinAggregator extends DruidAggregator { private static final String LONG_MIN_TYPE_AGGREGATOR = "longMin"; private String fieldName; - - @Setter private String expression; - public LongMinAggregator(@NonNull String name) { + @Deprecated + public LongMinAggregator(@NonNull String name, @NonNull String fieldName) { this.type = LONG_MIN_TYPE_AGGREGATOR; this.name = name; + this.fieldName = fieldName; } - public LongMinAggregator(@NonNull String name, @NonNull String fieldName) { + @Builder + private LongMinAggregator(@NonNull String name, String fieldName, String expression) { this.type = LONG_MIN_TYPE_AGGREGATOR; this.name = name; this.fieldName = fieldName; + this.expression = expression; + + Preconditions.checkArgument( + fieldName == null ^ expression == null, + "Must have a valid, non-null fieldName or expression" + ); } } diff --git a/src/main/java/in/zapr/druid/druidry/aggregator/LongSumAggregator.java b/src/main/java/in/zapr/druid/druidry/aggregator/LongSumAggregator.java index 65e5b261..ee5c8204 100644 --- a/src/main/java/in/zapr/druid/druidry/aggregator/LongSumAggregator.java +++ b/src/main/java/in/zapr/druid/druidry/aggregator/LongSumAggregator.java @@ -16,31 +16,43 @@ package in.zapr.druid.druidry.aggregator; +import com.google.common.base.Preconditions; + +import com.fasterxml.jackson.annotation.JsonInclude; + +import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; -import lombok.Setter; @Getter @EqualsAndHashCode(callSuper = true) +@JsonInclude(JsonInclude.Include.NON_NULL) public class LongSumAggregator extends DruidAggregator { private static final String LONGSUM_TYPE_AGGREGATOR = "longSum"; private String fieldName; - - @Setter private String expression; - public LongSumAggregator(@NonNull String name) { + @Deprecated + public LongSumAggregator(@NonNull String name, @NonNull String fieldName) { this.type = LONGSUM_TYPE_AGGREGATOR; this.name = name; + this.fieldName = fieldName; } - public LongSumAggregator(@NonNull String name, @NonNull String fieldName) { + @Builder + private LongSumAggregator(@NonNull String name, String fieldName, String expression) { this.type = LONGSUM_TYPE_AGGREGATOR; this.name = name; this.fieldName = fieldName; + this.expression = expression; + + Preconditions.checkArgument( + fieldName == null ^ expression == null, + "Must have a valid, non-null fieldName or expression" + ); } } diff --git a/src/test/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregatorTest.java b/src/test/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregatorTest.java index a3f654e1..9b694c55 100644 --- a/src/test/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregatorTest.java +++ b/src/test/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregatorTest.java @@ -40,48 +40,77 @@ public void init() { } @Test - public void testAllFields() throws JsonProcessingException, JSONException { + public void testAllButExpression() throws JSONException, JsonProcessingException { - DoubleMaxAggregator doubleMaxAggregator = new DoubleMaxAggregator("CarpeDiem", - "Hey"); - - doubleMaxAggregator.setExpression("(\"foo\" / \"bar\")"); + DoubleMaxAggregator doubleMaxAggregator = + DoubleMaxAggregator.builder() + .name("CarpeDiem") + .fieldName("Hey") + .build(); JSONObject jsonObject = new JSONObject(); jsonObject.put("type", "doubleMax"); jsonObject.put("name", "CarpeDiem"); jsonObject.put("fieldName", "Hey"); - jsonObject.put("expression", "(\"foo\" / \"bar\")"); String actualJSON = objectMapper.writeValueAsString(doubleMaxAggregator); String expectedJSON = jsonObject.toString(); JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.NON_EXTENSIBLE); } - @Test(expectedExceptions = NullPointerException.class) - public void testNullName() throws JsonProcessingException, JSONException { + @Test + public void testAllButFieldName() throws JSONException, JsonProcessingException { + + DoubleMaxAggregator doubleMaxAggregator = + DoubleMaxAggregator.builder() + .name("CarpeDiem") + .expression("(\"foo\" / \"bar\")") + .build(); - DoubleMaxAggregator doubleMaxAggregator = new DoubleMaxAggregator(null, "Haha"); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("type", "doubleMax"); + jsonObject.put("name", "CarpeDiem"); + jsonObject.put("expression", "(\"foo\" / \"bar\")"); + + String actualJSON = objectMapper.writeValueAsString(doubleMaxAggregator); + String expectedJSON = jsonObject.toString(); + JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.NON_EXTENSIBLE); } @Test(expectedExceptions = NullPointerException.class) - public void testNullFieldName() throws JsonProcessingException, JSONException { + public void testNullName() throws JsonProcessingException, JSONException { - DoubleMaxAggregator doubleMaxAggregator = new DoubleMaxAggregator("Name", null); + DoubleMaxAggregator doubleMaxAggregator = + DoubleMaxAggregator.builder() + .fieldName("Haha") + .build(); } @Test public void testEqualsPositive() { - DoubleMaxAggregator aggregator1 = new DoubleMaxAggregator("name", "field"); - DoubleMaxAggregator aggregator2 = new DoubleMaxAggregator("name", "field"); - - DoubleMaxAggregator aggregator3 = new DoubleMaxAggregator("name", "field"); - - aggregator3.setExpression("(\"foo\" / \"bar\")"); - - DoubleMaxAggregator aggregator4 = new DoubleMaxAggregator("name", "field"); - - aggregator4.setExpression("(\"foo\" / \"bar\")"); + DoubleMaxAggregator aggregator1 = + DoubleMaxAggregator.builder() + .name("name") + .fieldName("field") + .build(); + + DoubleMaxAggregator aggregator2 = + DoubleMaxAggregator.builder() + .name("name") + .fieldName("field") + .build(); + + DoubleMaxAggregator aggregator3 = + DoubleMaxAggregator.builder() + .name("name") + .expression("(\"foo\" / \"bar\")") + .build(); + + DoubleMaxAggregator aggregator4 = + DoubleMaxAggregator.builder() + .name("name") + .expression("(\"foo\" / \"bar\")") + .build(); Assert.assertEquals(aggregator1, aggregator2); Assert.assertEquals(aggregator3, aggregator4); @@ -89,16 +118,29 @@ public void testEqualsPositive() { @Test public void testEqualsNegative() { - DoubleMaxAggregator aggregator1 = new DoubleMaxAggregator("name", "field"); - DoubleMaxAggregator aggregator2 = new DoubleMaxAggregator("name1", "field1"); - - DoubleMaxAggregator aggregator3 = new DoubleMaxAggregator("name", "field"); - - aggregator3.setExpression("(\"foo\" / \"bar\")"); - - DoubleMaxAggregator aggregator4 = new DoubleMaxAggregator("name", "field"); - - aggregator4.setExpression("(\"foo\" / \"baz\")"); + DoubleMaxAggregator aggregator1 = + DoubleMaxAggregator.builder() + .name("name") + .fieldName("field") + .build(); + + DoubleMaxAggregator aggregator2 = + DoubleMaxAggregator.builder() + .name("name1") + .fieldName("field1") + .build(); + + DoubleMaxAggregator aggregator3 = + DoubleMaxAggregator.builder() + .name("name") + .expression("(\"foo\" / \"bar\")") + .build(); + + DoubleMaxAggregator aggregator4 = + DoubleMaxAggregator.builder() + .name("name") + .expression("(\"foo\" / \"baz\")") + .build(); Assert.assertNotEquals(aggregator1, aggregator2); Assert.assertNotEquals(aggregator3, aggregator4); @@ -106,9 +148,15 @@ public void testEqualsNegative() { @Test public void testEqualsWithAnotherSubClass() { - DoubleMaxAggregator aggregator1 = new DoubleMaxAggregator("name", "field"); + DoubleMaxAggregator aggregator1 = + DoubleMaxAggregator.builder() + .name("name") + .fieldName("field") + .build(); + CountAggregator aggregator2 = new CountAggregator("countAgg1"); Assert.assertNotEquals(aggregator1, aggregator2); } + } diff --git a/src/test/java/in/zapr/druid/druidry/aggregator/DoubleMinAggregatorTest.java b/src/test/java/in/zapr/druid/druidry/aggregator/DoubleMinAggregatorTest.java index 7435efaa..ece08f84 100644 --- a/src/test/java/in/zapr/druid/druidry/aggregator/DoubleMinAggregatorTest.java +++ b/src/test/java/in/zapr/druid/druidry/aggregator/DoubleMinAggregatorTest.java @@ -40,48 +40,77 @@ public void init() { } @Test - public void testAllFields() throws JsonProcessingException, JSONException { + public void testAllFieldsButExpression() throws JSONException, JsonProcessingException { - DoubleMinAggregator doubleMinAggregator = new DoubleMinAggregator("CarpeDiem", - "Hey"); - - doubleMinAggregator.setExpression("(\"foo\" / \"bar\")"); + DoubleMinAggregator doubleMinAggregator = + DoubleMinAggregator.builder() + .name("CarpeDiem") + .fieldName("Hey") + .build(); JSONObject jsonObject = new JSONObject(); jsonObject.put("type", "doubleMin"); jsonObject.put("name", "CarpeDiem"); jsonObject.put("fieldName", "Hey"); - jsonObject.put("expression", "(\"foo\" / \"bar\")"); String actualJSON = objectMapper.writeValueAsString(doubleMinAggregator); String expectedJSON = jsonObject.toString(); JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.NON_EXTENSIBLE); } - @Test(expectedExceptions = NullPointerException.class) - public void testNullName() throws JsonProcessingException, JSONException { + @Test + public void testAllFieldsButFieldName() throws JSONException, JsonProcessingException { + + DoubleMinAggregator doubleMinAggregator = + DoubleMinAggregator.builder() + .name("CarpeDiem") + .expression("(\"foo\" / \"bar\")") + .build(); - DoubleMinAggregator doubleMinAggregator = new DoubleMinAggregator(null, "Haha"); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("type", "doubleMin"); + jsonObject.put("name", "CarpeDiem"); + jsonObject.put("expression", "(\"foo\" / \"bar\")"); + + String actualJSON = objectMapper.writeValueAsString(doubleMinAggregator); + String expectedJSON = jsonObject.toString(); + JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.NON_EXTENSIBLE); } @Test(expectedExceptions = NullPointerException.class) - public void testNullFieldName() throws JsonProcessingException, JSONException { + public void testNullName() throws JsonProcessingException, JSONException { - DoubleMinAggregator doubleMinAggregator = new DoubleMinAggregator("Name", null); + DoubleMinAggregator doubleMinAggregator = + DoubleMinAggregator.builder() + .fieldName("Haha") + .build(); } @Test public void testEqualsPositive() { - DoubleMinAggregator aggregator1 = new DoubleMinAggregator("name", "field"); - DoubleMinAggregator aggregator2 = new DoubleMinAggregator("name", "field"); - - DoubleMinAggregator aggregator3 = new DoubleMinAggregator("name", "field"); - - aggregator3.setExpression("(\"foo\" / \"bar\")"); - - DoubleMinAggregator aggregator4 = new DoubleMinAggregator("name", "field"); - - aggregator4.setExpression("(\"foo\" / \"bar\")"); + DoubleMinAggregator aggregator1 = + DoubleMinAggregator.builder() + .name("name") + .fieldName("field") + .build(); + + DoubleMinAggregator aggregator2 = + DoubleMinAggregator.builder() + .name("name") + .fieldName("field") + .build(); + + DoubleMinAggregator aggregator3 = + DoubleMinAggregator.builder() + .name("name") + .expression("(\"foo\" / \"bar\")") + .build(); + + DoubleMinAggregator aggregator4 = + DoubleMinAggregator.builder() + .name("name") + .expression("(\"foo\" / \"bar\")") + .build(); Assert.assertEquals(aggregator1, aggregator2); Assert.assertEquals(aggregator3, aggregator4); @@ -89,16 +118,29 @@ public void testEqualsPositive() { @Test public void testEqualsNegative() { - DoubleMinAggregator aggregator1 = new DoubleMinAggregator("name", "field"); - DoubleMinAggregator aggregator2 = new DoubleMinAggregator("name1", "field1"); - - DoubleMinAggregator aggregator3 = new DoubleMinAggregator("name", "field"); - - aggregator3.setExpression("(\"foo\" / \"bar\")"); - - DoubleMinAggregator aggregator4 = new DoubleMinAggregator("name", "field"); - - aggregator4.setExpression("(\"foo\" / \"baz\")"); + DoubleMinAggregator aggregator1 = + DoubleMinAggregator.builder() + .name("name") + .fieldName("field") + .build(); + + DoubleMinAggregator aggregator2 = + DoubleMinAggregator.builder() + .name("name1") + .fieldName("field1") + .build(); + + DoubleMinAggregator aggregator3 = + DoubleMinAggregator.builder() + .name("name") + .expression("(\"foo\" / \"bar\")") + .build(); + + DoubleMinAggregator aggregator4 = + DoubleMinAggregator.builder() + .name("name") + .expression("(\"foo\" / \"baz\")") + .build(); Assert.assertNotEquals(aggregator1, aggregator2); Assert.assertNotEquals(aggregator3, aggregator4); @@ -106,9 +148,15 @@ public void testEqualsNegative() { @Test public void testEqualsWithAnotherSubClass() { - DoubleMinAggregator aggregator1 = new DoubleMinAggregator("name", "field"); + DoubleMinAggregator aggregator1 = + DoubleMinAggregator.builder() + .name("name") + .fieldName("field") + .build(); + CountAggregator aggregator2 = new CountAggregator("countAgg1"); Assert.assertNotEquals(aggregator1, aggregator2); } + } diff --git a/src/test/java/in/zapr/druid/druidry/aggregator/DoubleSumAggregatorTest.java b/src/test/java/in/zapr/druid/druidry/aggregator/DoubleSumAggregatorTest.java index 08b27b2b..586c5fd1 100644 --- a/src/test/java/in/zapr/druid/druidry/aggregator/DoubleSumAggregatorTest.java +++ b/src/test/java/in/zapr/druid/druidry/aggregator/DoubleSumAggregatorTest.java @@ -40,48 +40,77 @@ public void init() { } @Test - public void testAllFields() throws JsonProcessingException, JSONException { + public void testAllFieldsButExpression() throws JsonProcessingException, JSONException { - DoubleSumAggregator doubleSumAggregator = new DoubleSumAggregator("CarpeDiem", - "Hey"); - - doubleSumAggregator.setExpression("(\"foo\" / \"bar\")"); + DoubleSumAggregator doubleSumAggregator = + DoubleSumAggregator.builder() + .name("CarpeDiem") + .fieldName("Hey") + .build(); JSONObject jsonObject = new JSONObject(); jsonObject.put("type", "doubleSum"); jsonObject.put("name", "CarpeDiem"); jsonObject.put("fieldName", "Hey"); - jsonObject.put("expression", "(\"foo\" / \"bar\")"); String actualJSON = objectMapper.writeValueAsString(doubleSumAggregator); String expectedJSON = jsonObject.toString(); JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.NON_EXTENSIBLE); } - @Test(expectedExceptions = NullPointerException.class) - public void testNullName() throws JsonProcessingException, JSONException { + @Test + public void testAllFieldsButFieldName() throws JsonProcessingException, JSONException { + + DoubleSumAggregator doubleSumAggregator = + DoubleSumAggregator.builder() + .name("CarpeDiem") + .expression("(\"foo\" / \"bar\")") + .build(); - DoubleSumAggregator doubleSumAggregator = new DoubleSumAggregator(null, "Haha"); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("type", "doubleSum"); + jsonObject.put("name", "CarpeDiem"); + jsonObject.put("expression", "(\"foo\" / \"bar\")"); + + String actualJSON = objectMapper.writeValueAsString(doubleSumAggregator); + String expectedJSON = jsonObject.toString(); + JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.NON_EXTENSIBLE); } @Test(expectedExceptions = NullPointerException.class) - public void testNullFieldName() throws JsonProcessingException, JSONException { + public void testNullName() throws JsonProcessingException, JSONException { - DoubleSumAggregator doubleSumAggregator = new DoubleSumAggregator("Name", null); + DoubleSumAggregator doubleSumAggregator = + DoubleSumAggregator.builder() + .fieldName("Haha") + .build(); } @Test public void testEqualsPositive() { - DoubleSumAggregator aggregator1 = new DoubleSumAggregator("name", "field"); - DoubleSumAggregator aggregator2 = new DoubleSumAggregator("name", "field"); - - DoubleSumAggregator aggregator3 = new DoubleSumAggregator("name", "field"); - - aggregator3.setExpression("(\"foo\" / \"bar\")"); - - DoubleSumAggregator aggregator4 = new DoubleSumAggregator("name", "field"); - - aggregator4.setExpression("(\"foo\" / \"bar\")"); + DoubleSumAggregator aggregator1 = + DoubleSumAggregator.builder() + .name("name") + .fieldName("field") + .build(); + + DoubleSumAggregator aggregator2 = + DoubleSumAggregator.builder() + .name("name") + .fieldName("field") + .build(); + + DoubleSumAggregator aggregator3 = + DoubleSumAggregator.builder() + .name("name") + .expression("(\"foo\" / \"bar\")") + .build(); + + DoubleSumAggregator aggregator4 = + DoubleSumAggregator.builder() + .name("name") + .expression("(\"foo\" / \"bar\")") + .build(); Assert.assertEquals(aggregator1, aggregator2); Assert.assertEquals(aggregator3, aggregator4); @@ -89,16 +118,29 @@ public void testEqualsPositive() { @Test public void testEqualsNegative() { - DoubleSumAggregator aggregator1 = new DoubleSumAggregator("name", "field"); - DoubleSumAggregator aggregator2 = new DoubleSumAggregator("name1", "field1"); - - DoubleSumAggregator aggregator3 = new DoubleSumAggregator("name", "field"); - - aggregator3.setExpression("(\"foo\" / \"bar\")"); - - DoubleSumAggregator aggregator4 = new DoubleSumAggregator("name", "field"); - - aggregator4.setExpression("(\"foo\" / \"baz\")"); + DoubleSumAggregator aggregator1 = + DoubleSumAggregator.builder() + .name("name") + .fieldName("field") + .build(); + + DoubleSumAggregator aggregator2 = + DoubleSumAggregator.builder() + .name("name1") + .fieldName("field1") + .build(); + + DoubleSumAggregator aggregator3 = + DoubleSumAggregator.builder() + .name("name") + .expression("(\"foo\" / \"bar\")") + .build(); + + DoubleSumAggregator aggregator4 = + DoubleSumAggregator.builder() + .name("name") + .expression("(\"foo\" / \"baz\")") + .build(); Assert.assertNotEquals(aggregator1, aggregator2); Assert.assertNotEquals(aggregator3, aggregator4); @@ -106,9 +148,15 @@ public void testEqualsNegative() { @Test public void testEqualsWithAnotherSubClass() { - DoubleSumAggregator aggregator1 = new DoubleSumAggregator("name", "field"); + DoubleSumAggregator aggregator1 = + DoubleSumAggregator.builder() + .name("name") + .fieldName("field") + .build(); + CountAggregator aggregator2 = new CountAggregator("countAgg1"); Assert.assertNotEquals(aggregator1, aggregator2); } + } diff --git a/src/test/java/in/zapr/druid/druidry/aggregator/LongMaxAggregatorTest.java b/src/test/java/in/zapr/druid/druidry/aggregator/LongMaxAggregatorTest.java index f316acc6..c64c4f85 100644 --- a/src/test/java/in/zapr/druid/druidry/aggregator/LongMaxAggregatorTest.java +++ b/src/test/java/in/zapr/druid/druidry/aggregator/LongMaxAggregatorTest.java @@ -40,48 +40,77 @@ public void init() { } @Test - public void testAllFields() throws JsonProcessingException, JSONException { + public void testAllFieldsButExpression() throws JsonProcessingException, JSONException { - LongMaxAggregator countAggregator = new LongMaxAggregator("CarpeDiem", - "Hey"); - - countAggregator.setExpression("(\"foo\" / \"bar\")"); + LongMaxAggregator countAggregator = + LongMaxAggregator.builder() + .name("CarpeDiem") + .fieldName("Hey") + .build(); JSONObject jsonObject = new JSONObject(); jsonObject.put("type", "longMax"); jsonObject.put("name", "CarpeDiem"); jsonObject.put("fieldName", "Hey"); - jsonObject.put("expression", "(\"foo\" / \"bar\")"); String actualJSON = objectMapper.writeValueAsString(countAggregator); String expectedJSON = jsonObject.toString(); JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.NON_EXTENSIBLE); } - @Test(expectedExceptions = NullPointerException.class) - public void testNullName() throws JsonProcessingException, JSONException { + @Test + public void testAllFieldsButFieldName() throws JsonProcessingException, JSONException { + + LongMaxAggregator countAggregator = + LongMaxAggregator.builder() + .name("CarpeDiem") + .expression("(\"foo\" / \"bar\")") + .build(); - LongMaxAggregator longMaxAggregator = new LongMaxAggregator(null, "Haha"); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("type", "longMax"); + jsonObject.put("name", "CarpeDiem"); + jsonObject.put("expression", "(\"foo\" / \"bar\")"); + + String actualJSON = objectMapper.writeValueAsString(countAggregator); + String expectedJSON = jsonObject.toString(); + JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.NON_EXTENSIBLE); } @Test(expectedExceptions = NullPointerException.class) - public void testNullFieldName() throws JsonProcessingException, JSONException { + public void testNullName() throws JsonProcessingException, JSONException { - LongMaxAggregator longMaxAggregator = new LongMaxAggregator("Name", null); + LongMaxAggregator longMaxAggregator = + LongMaxAggregator.builder() + .fieldName("Haha") + .build(); } @Test public void testEqualsPositive() { - LongMaxAggregator aggregator1 = new LongMaxAggregator("name", "field"); - LongMaxAggregator aggregator2 = new LongMaxAggregator("name", "field"); - - LongMaxAggregator aggregator3 = new LongMaxAggregator("name", "field"); - - aggregator3.setExpression("(\"foo\" / \"bar\")"); - - LongMaxAggregator aggregator4 = new LongMaxAggregator("name", "field"); - - aggregator4.setExpression("(\"foo\" / \"bar\")"); + LongMaxAggregator aggregator1 = + LongMaxAggregator.builder() + .name("name") + .fieldName("field") + .build(); + + LongMaxAggregator aggregator2 = + LongMaxAggregator.builder() + .name("name") + .fieldName("field") + .build(); + + LongMaxAggregator aggregator3 = + LongMaxAggregator.builder() + .name("name") + .expression("(\"foo\" / \"bar\")") + .build(); + + LongMaxAggregator aggregator4 = + LongMaxAggregator.builder() + .name("name") + .expression("(\"foo\" / \"bar\")") + .build(); Assert.assertEquals(aggregator1, aggregator2); Assert.assertEquals(aggregator3, aggregator4); @@ -89,16 +118,29 @@ public void testEqualsPositive() { @Test public void testEqualsNegative() { - LongMaxAggregator aggregator1 = new LongMaxAggregator("name", "field"); - LongMaxAggregator aggregator2 = new LongMaxAggregator("name1", "field1"); - - LongMaxAggregator aggregator3 = new LongMaxAggregator("name", "field"); - - aggregator3.setExpression("(\"foo\" / \"bar\")"); - - LongMaxAggregator aggregator4 = new LongMaxAggregator("name", "field"); - - aggregator4.setExpression("(\"foo\" / \"baz\")"); + LongMaxAggregator aggregator1 = + LongMaxAggregator.builder() + .name("name") + .fieldName("field") + .build(); + + LongMaxAggregator aggregator2 = + LongMaxAggregator.builder() + .name("name1") + .fieldName("field1") + .build(); + + LongMaxAggregator aggregator3 = + LongMaxAggregator.builder() + .name("name") + .expression("(\"foo\" / \"bar\")") + .build(); + + LongMaxAggregator aggregator4 = + LongMaxAggregator.builder() + .name("name") + .expression("(\"foo\" / \"baz\")") + .build(); Assert.assertNotEquals(aggregator1, aggregator2); Assert.assertNotEquals(aggregator3, aggregator4); @@ -106,9 +148,15 @@ public void testEqualsNegative() { @Test public void testEqualsWithAnotherSubClass() { - LongMaxAggregator aggregator1 = new LongMaxAggregator("name", "field"); + LongMaxAggregator aggregator1 = + LongMaxAggregator.builder() + .name("name") + .fieldName("field") + .build(); + CountAggregator aggregator2 = new CountAggregator("countAgg1"); Assert.assertNotEquals(aggregator1, aggregator2); } + } diff --git a/src/test/java/in/zapr/druid/druidry/aggregator/LongMinAggregatorTest.java b/src/test/java/in/zapr/druid/druidry/aggregator/LongMinAggregatorTest.java index cd9346f4..37840dda 100644 --- a/src/test/java/in/zapr/druid/druidry/aggregator/LongMinAggregatorTest.java +++ b/src/test/java/in/zapr/druid/druidry/aggregator/LongMinAggregatorTest.java @@ -40,48 +40,77 @@ public void init() { } @Test - public void testAllFields() throws JsonProcessingException, JSONException { + public void testAllFieldsButExpression() throws JsonProcessingException, JSONException { - LongMinAggregator longMinAggregator = new LongMinAggregator("CarpeDiem", - "Hey"); - - longMinAggregator.setExpression("(\"foo\" / \"bar\")"); + LongMinAggregator longMinAggregator = + LongMinAggregator.builder() + .name("CarpeDiem") + .fieldName("Hey") + .build(); JSONObject jsonObject = new JSONObject(); jsonObject.put("type", "longMin"); jsonObject.put("name", "CarpeDiem"); jsonObject.put("fieldName", "Hey"); - jsonObject.put("expression", "(\"foo\" / \"bar\")"); String actualJSON = objectMapper.writeValueAsString(longMinAggregator); String expectedJSON = jsonObject.toString(); JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.NON_EXTENSIBLE); } - @Test(expectedExceptions = NullPointerException.class) - public void testNullName() throws JsonProcessingException, JSONException { + @Test + public void testAllFieldsButFieldName() throws JsonProcessingException, JSONException { + + LongMinAggregator longMinAggregator = + LongMinAggregator.builder() + .name("CarpeDiem") + .expression("(\"foo\" / \"bar\")") + .build(); - LongMinAggregator longMinAggregator = new LongMinAggregator(null, "Haha"); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("type", "longMin"); + jsonObject.put("name", "CarpeDiem"); + jsonObject.put("expression", "(\"foo\" / \"bar\")"); + + String actualJSON = objectMapper.writeValueAsString(longMinAggregator); + String expectedJSON = jsonObject.toString(); + JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.NON_EXTENSIBLE); } @Test(expectedExceptions = NullPointerException.class) - public void testNullFieldName() throws JsonProcessingException, JSONException { + public void testNullName() throws JsonProcessingException, JSONException { - LongMinAggregator longMinAggregator = new LongMinAggregator("Name", null); + LongMinAggregator longMinAggregator = + LongMinAggregator.builder() + .fieldName("Haha") + .build(); } @Test public void testEqualsPositive() { - LongMinAggregator aggregator1 = new LongMinAggregator("name", "field"); - LongMinAggregator aggregator2 = new LongMinAggregator("name", "field"); - - LongMinAggregator aggregator3 = new LongMinAggregator("name", "field"); - - aggregator3.setExpression("(\"foo\" / \"bar\")"); - - LongMinAggregator aggregator4 = new LongMinAggregator("name", "field"); - - aggregator4.setExpression("(\"foo\" / \"bar\")"); + LongMinAggregator aggregator1 = + LongMinAggregator.builder() + .name("name") + .fieldName("field") + .build(); + + LongMinAggregator aggregator2 = + LongMinAggregator.builder() + .name("name") + .fieldName("field") + .build(); + + LongMinAggregator aggregator3 = + LongMinAggregator.builder() + .name("name") + .expression("(\"foo\" / \"bar\")") + .build(); + + LongMinAggregator aggregator4 = + LongMinAggregator.builder() + .name("name") + .expression("(\"foo\" / \"bar\")") + .build(); Assert.assertEquals(aggregator1, aggregator2); Assert.assertEquals(aggregator3, aggregator4); @@ -89,16 +118,29 @@ public void testEqualsPositive() { @Test public void testEqualsNegative() { - LongMinAggregator aggregator1 = new LongMinAggregator("name", "field"); - LongMinAggregator aggregator2 = new LongMinAggregator("name1", "field1"); - - LongMinAggregator aggregator3 = new LongMinAggregator("name", "field"); - - aggregator3.setExpression("(\"foo\" / \"bar\")"); - - LongMinAggregator aggregator4 = new LongMinAggregator("name", "field"); - - aggregator4.setExpression("(\"foo\" / \"baz\")"); + LongMinAggregator aggregator1 = + LongMinAggregator.builder() + .name("name") + .fieldName("field") + .build(); + + LongMinAggregator aggregator2 = + LongMinAggregator.builder() + .name("name1") + .fieldName("field1") + .build(); + + LongMinAggregator aggregator3 = + LongMinAggregator.builder() + .name("name") + .expression("(\"foo\" / \"bar\")") + .build(); + + LongMinAggregator aggregator4 = + LongMinAggregator.builder() + .name("name") + .expression("(\"foo\" / \"baz\")") + .build(); Assert.assertNotEquals(aggregator1, aggregator2); Assert.assertNotEquals(aggregator3, aggregator4); @@ -106,9 +148,15 @@ public void testEqualsNegative() { @Test public void testEqualsWithAnotherSubClass() { - LongMinAggregator aggregator1 = new LongMinAggregator("name", "field"); + LongMinAggregator aggregator1 = + LongMinAggregator.builder() + .name("name") + .fieldName("field") + .build(); + CountAggregator aggregator2 = new CountAggregator("countAgg1"); Assert.assertNotEquals(aggregator1, aggregator2); } + } diff --git a/src/test/java/in/zapr/druid/druidry/aggregator/LongSumAggregatorTest.java b/src/test/java/in/zapr/druid/druidry/aggregator/LongSumAggregatorTest.java index 660c5ae6..7a4a8983 100644 --- a/src/test/java/in/zapr/druid/druidry/aggregator/LongSumAggregatorTest.java +++ b/src/test/java/in/zapr/druid/druidry/aggregator/LongSumAggregatorTest.java @@ -40,48 +40,77 @@ public void init() { } @Test - public void testAllFields() throws JsonProcessingException, JSONException { + public void testAllFieldsButExpression() throws JsonProcessingException, JSONException { - LongSumAggregator longSumAggregator = new LongSumAggregator("CarpeDiem", - "Hey"); - - longSumAggregator.setExpression("(\"foo\" / \"bar\")"); + LongSumAggregator longSumAggregator = + LongSumAggregator.builder() + .name("CarpeDiem") + .fieldName("Hey") + .build(); JSONObject jsonObject = new JSONObject(); jsonObject.put("type", "longSum"); jsonObject.put("name", "CarpeDiem"); jsonObject.put("fieldName", "Hey"); - jsonObject.put("expression", "(\"foo\" / \"bar\")"); String actualJSON = objectMapper.writeValueAsString(longSumAggregator); String expectedJSON = jsonObject.toString(); JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.NON_EXTENSIBLE); } - @Test(expectedExceptions = NullPointerException.class) - public void testNullName() throws JsonProcessingException, JSONException { + @Test + public void testAllFieldsButFieldName() throws JsonProcessingException, JSONException { + + LongSumAggregator longSumAggregator = + LongSumAggregator.builder() + .name("CarpeDiem") + .expression("(\"foo\" / \"bar\")") + .build(); - LongSumAggregator longSumAggregator = new LongSumAggregator(null, "Haha"); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("type", "longSum"); + jsonObject.put("name", "CarpeDiem"); + jsonObject.put("expression", "(\"foo\" / \"bar\")"); + + String actualJSON = objectMapper.writeValueAsString(longSumAggregator); + String expectedJSON = jsonObject.toString(); + JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.NON_EXTENSIBLE); } @Test(expectedExceptions = NullPointerException.class) - public void testNullFieldName() throws JsonProcessingException, JSONException { + public void testNullName() throws JsonProcessingException, JSONException { - LongSumAggregator longSumAggregator = new LongSumAggregator("Name", null); + LongSumAggregator longSumAggregator = + LongSumAggregator.builder() + .fieldName("Haha") + .build(); } @Test public void testEqualsPositive() { - LongSumAggregator aggregator1 = new LongSumAggregator("name", "field"); - LongSumAggregator aggregator2 = new LongSumAggregator("name", "field"); - - LongSumAggregator aggregator3 = new LongSumAggregator("name", "field"); - - aggregator3.setExpression("(\"foo\" / \"bar\")"); - - LongSumAggregator aggregator4 = new LongSumAggregator("name", "field"); - - aggregator4.setExpression("(\"foo\" / \"bar\")"); + LongSumAggregator aggregator1 = + LongSumAggregator.builder() + .name("name") + .fieldName("field") + .build(); + + LongSumAggregator aggregator2 = + LongSumAggregator.builder() + .name("name") + .fieldName("field") + .build(); + + LongSumAggregator aggregator3 = + LongSumAggregator.builder() + .name("name") + .expression("(\"foo\" / \"bar\")") + .build(); + + LongSumAggregator aggregator4 = + LongSumAggregator.builder() + .name("name") + .expression("(\"foo\" / \"bar\")") + .build(); Assert.assertEquals(aggregator1, aggregator2); Assert.assertEquals(aggregator3, aggregator4); @@ -89,16 +118,29 @@ public void testEqualsPositive() { @Test public void testEqualsNegative() { - LongSumAggregator aggregator1 = new LongSumAggregator("name", "field"); - LongSumAggregator aggregator2 = new LongSumAggregator("name1", "field1"); - - LongSumAggregator aggregator3 = new LongSumAggregator("name", "field"); - - aggregator3.setExpression("(\"foo\" / \"bar\")"); - - LongSumAggregator aggregator4 = new LongSumAggregator("name", "field"); - - aggregator4.setExpression("(\"foo\" / \"baz\")"); + LongSumAggregator aggregator1 = + LongSumAggregator.builder() + .name("name") + .fieldName("field") + .build(); + + LongSumAggregator aggregator2 = + LongSumAggregator.builder() + .name("name1") + .fieldName("field1") + .build(); + + LongSumAggregator aggregator3 = + LongSumAggregator.builder() + .name("name") + .expression("(\"foo\" / \"bar\")") + .build(); + + LongSumAggregator aggregator4 = + LongSumAggregator.builder() + .name("name") + .expression("(\"foo\" / \"baz\")") + .build(); Assert.assertNotEquals(aggregator1, aggregator2); Assert.assertNotEquals(aggregator3, aggregator4); @@ -106,9 +148,15 @@ public void testEqualsNegative() { @Test public void testEqualsWithAnotherSubClass() { - LongSumAggregator aggregator1 = new LongSumAggregator("name", "field"); + LongSumAggregator aggregator1 = + LongSumAggregator.builder() + .name("name") + .fieldName("field") + .build(); + CountAggregator aggregator2 = new CountAggregator("countAgg1"); Assert.assertNotEquals(aggregator1, aggregator2); } + } diff --git a/src/test/java/in/zapr/druid/druidry/query/aggregation/GroupByTest.java b/src/test/java/in/zapr/druid/druidry/query/aggregation/GroupByTest.java index 7213b9ab..81f234e2 100644 --- a/src/test/java/in/zapr/druid/druidry/query/aggregation/GroupByTest.java +++ b/src/test/java/in/zapr/druid/druidry/query/aggregation/GroupByTest.java @@ -19,8 +19,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import in.zapr.druid.druidry.filter.havingSpec.HavingSpec; -import in.zapr.druid.druidry.filter.havingSpec.GreaterThanHaving; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.json.JSONArray; @@ -35,8 +33,6 @@ import java.util.Collections; import java.util.List; -import in.zapr.druid.druidry.query.config.Context; -import in.zapr.druid.druidry.query.config.Interval; import in.zapr.druid.druidry.aggregator.CountAggregator; import in.zapr.druid.druidry.aggregator.DoubleSumAggregator; import in.zapr.druid.druidry.aggregator.DruidAggregator; @@ -48,6 +44,8 @@ import in.zapr.druid.druidry.filter.DruidFilter; import in.zapr.druid.druidry.filter.OrFilter; import in.zapr.druid.druidry.filter.SelectorFilter; +import in.zapr.druid.druidry.filter.havingSpec.GreaterThanHaving; +import in.zapr.druid.druidry.filter.havingSpec.HavingSpec; import in.zapr.druid.druidry.granularity.Granularity; import in.zapr.druid.druidry.granularity.PredefinedGranularity; import in.zapr.druid.druidry.granularity.SimpleGranularity; @@ -59,6 +57,8 @@ import in.zapr.druid.druidry.postAggregator.ConstantPostAggregator; import in.zapr.druid.druidry.postAggregator.DruidPostAggregator; import in.zapr.druid.druidry.postAggregator.FieldAccessPostAggregator; +import in.zapr.druid.druidry.query.config.Context; +import in.zapr.druid.druidry.query.config.Interval; public class GroupByTest { private static ObjectMapper objectMapper; @@ -71,47 +71,47 @@ public void init() { @Test public void testSampleQuery() throws JsonProcessingException, JSONException { String expectedJsonAsString = "{\n" + - " \"queryType\": \"groupBy\",\n" + - " \"dataSource\": {\n" + - " \"type\": \"table\",\n" + - " \"name\": \"sample_datasource\"\n" + - " },\n" + - " \"granularity\": \"day\",\n" + - " \"dimensions\": [\"country\", \"device\"],\n" + - " \"limitSpec\": { \"type\": \"default\", \"limit\": 5000, \"columns\": [\"country\", \"data_transfer\"] },\n" + - " \"filter\": {\n" + - " \"type\": \"and\",\n" + - " \"fields\": [\n" + - " { \"type\": \"selector\", \"dimension\": \"carrier\", \"value\": \"AT&T\" },\n" + - " { \"type\": \"or\", \n" + - " \"fields\": [\n" + - " { \"type\": \"selector\", \"dimension\": \"make\", \"value\": \"Apple\" },\n" + - " { \"type\": \"selector\", \"dimension\": \"make\", \"value\": \"Samsung\" }\n" + - " ]\n" + - " }\n" + - " ]\n" + - " },\n" + - " \"aggregations\": [\n" + - " { \"type\": \"longSum\", \"name\": \"total_usage\", \"fieldName\": \"user_count\", \"expression\": null },\n" + - " { \"type\": \"doubleSum\", \"name\": \"data_transfer\", \"fieldName\": \"data_transfer\", \"expression\": null }\n" + - " ],\n" + - "\"having\": {\n" + - " \"type\": \"greaterThan\",\n" + - " \"aggregation\": \"total_usage\",\n" + - " \"value\": 2\n" + - " }," + - " \"postAggregations\": [\n" + - " { \"type\": \"arithmetic\",\n" + - " \"name\": \"avg_usage\",\n" + - " \"fn\": \"/\",\n" + - " \"fields\": [\n" + - " { \"type\": \"fieldAccess\", \"fieldName\": \"data_transfer\" },\n" + - " { \"type\": \"fieldAccess\", \"fieldName\": \"total_usage\" }\n" + - " ]\n" + - " }\n" + - " ],\n" + - " \"intervals\": [ \"2012-01-01T00:00:00.000Z/2012-01-03T00:00:00.000Z\" ]\n" + - "}\n"; + " \"queryType\": \"groupBy\",\n" + + " \"dataSource\": {\n" + + " \"type\": \"table\",\n" + + " \"name\": \"sample_datasource\"\n" + + " },\n" + + " \"granularity\": \"day\",\n" + + " \"dimensions\": [\"country\", \"device\"],\n" + + " \"limitSpec\": { \"type\": \"default\", \"limit\": 5000, \"columns\": [\"country\", \"data_transfer\"] },\n" + + " \"filter\": {\n" + + " \"type\": \"and\",\n" + + " \"fields\": [\n" + + " { \"type\": \"selector\", \"dimension\": \"carrier\", \"value\": \"AT&T\" },\n" + + " { \"type\": \"or\", \n" + + " \"fields\": [\n" + + " { \"type\": \"selector\", \"dimension\": \"make\", \"value\": \"Apple\" },\n" + + " { \"type\": \"selector\", \"dimension\": \"make\", \"value\": \"Samsung\" }\n" + + " ]\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"aggregations\": [\n" + + " { \"type\": \"longSum\", \"name\": \"total_usage\", \"fieldName\": \"user_count\" },\n" + + " { \"type\": \"doubleSum\", \"name\": \"data_transfer\", \"fieldName\": \"data_transfer\" }\n" + + " ],\n" + + "\"having\": {\n" + + " \"type\": \"greaterThan\",\n" + + " \"aggregation\": \"total_usage\",\n" + + " \"value\": 2\n" + + " }," + + " \"postAggregations\": [\n" + + " { \"type\": \"arithmetic\",\n" + + " \"name\": \"avg_usage\",\n" + + " \"fn\": \"/\",\n" + + " \"fields\": [\n" + + " { \"type\": \"fieldAccess\", \"fieldName\": \"data_transfer\" },\n" + + " { \"type\": \"fieldAccess\", \"fieldName\": \"total_usage\" }\n" + + " ]\n" + + " }\n" + + " ],\n" + + " \"intervals\": [ \"2012-01-01T00:00:00.000Z/2012-01-03T00:00:00.000Z\" ]\n" + + "}\n"; // Druid dimensions DruidDimension druidDimension1 = new SimpleDimension("country"); @@ -119,8 +119,8 @@ public void testSampleQuery() throws JsonProcessingException, JSONException { // Limit Spec List orderByColumnSpecs - = Arrays.asList(new OrderByColumnSpecString("country"), - new OrderByColumnSpecString("data_transfer")); + = Arrays.asList(new OrderByColumnSpecString("country"), + new OrderByColumnSpecString("data_transfer")); DefaultLimitSpec limitSpec = new DefaultLimitSpec(5000, orderByColumnSpecs); // Filters @@ -132,8 +132,17 @@ public void testSampleQuery() throws JsonProcessingException, JSONException { DruidFilter filter = new AndFilter(Arrays.asList(carrierFilter, makeFilter)); // Aggregations - DruidAggregator usageAggregator = new LongSumAggregator("total_usage", "user_count"); - DruidAggregator transferAggregator = new DoubleSumAggregator("data_transfer", "data_transfer"); + DruidAggregator usageAggregator = + LongSumAggregator.builder() + .name("total_usage") + .fieldName("user_count") + .build(); + + DruidAggregator transferAggregator = + DoubleSumAggregator.builder() + .name("data_transfer") + .fieldName("data_transfer") + .build(); // Having HavingSpec countHaving = new GreaterThanHaving("total_usage", 2); @@ -143,10 +152,10 @@ public void testSampleQuery() throws JsonProcessingException, JSONException { DruidPostAggregator usagePostAggregator = new FieldAccessPostAggregator("data_transfer"); DruidPostAggregator postAggregator = ArithmeticPostAggregator.builder() - .name("avg_usage") - .function(ArithmeticFunction.DIVIDE) - .fields(Arrays.asList(transferPostAggregator, usagePostAggregator)) - .build(); + .name("avg_usage") + .function(ArithmeticFunction.DIVIDE) + .fields(Arrays.asList(transferPostAggregator, usagePostAggregator)) + .build(); // Interval DateTime startTime = new DateTime(2012, 1, 1, 0, 0, 0, DateTimeZone.UTC); @@ -154,16 +163,16 @@ public void testSampleQuery() throws JsonProcessingException, JSONException { Interval interval = new Interval(startTime, endTime); DruidGroupByQuery query = DruidGroupByQuery.builder() - .dataSource(new TableDataSource("sample_datasource")) - .granularity(new SimpleGranularity(PredefinedGranularity.DAY)) - .dimensions(Arrays.asList(druidDimension1, druidDimension2)) - .limitSpec(limitSpec) - .filter(filter) - .having(countHaving) - .aggregators(Arrays.asList(usageAggregator, transferAggregator)) - .postAggregators(Collections.singletonList(postAggregator)) - .intervals(Collections.singletonList(interval)) - .build(); + .dataSource(new TableDataSource("sample_datasource")) + .granularity(new SimpleGranularity(PredefinedGranularity.DAY)) + .dimensions(Arrays.asList(druidDimension1, druidDimension2)) + .limitSpec(limitSpec) + .filter(filter) + .having(countHaving) + .aggregators(Arrays.asList(usageAggregator, transferAggregator)) + .postAggregators(Collections.singletonList(postAggregator)) + .intervals(Collections.singletonList(interval)) + .build(); String actualJson = objectMapper.writeValueAsString(query); JSONAssert.assertEquals(actualJson, expectedJsonAsString, JSONCompareMode.NON_EXTENSIBLE); @@ -181,11 +190,11 @@ public void testRequiredFields() throws JSONException, JsonProcessingException { Interval interval = new Interval(startTime, endTime); DruidGroupByQuery druidGroupByQuery = DruidGroupByQuery.builder() - .dataSource(new TableDataSource("sample_datasource")) - .dimensions(Arrays.asList(druidDimension1, druidDimension2)) - .granularity(granularity) - .intervals(Collections.singletonList(interval)) - .build(); + .dataSource(new TableDataSource("sample_datasource")) + .dimensions(Arrays.asList(druidDimension1, druidDimension2)) + .granularity(granularity) + .intervals(Collections.singletonList(interval)) + .build(); String actualJson = objectMapper.writeValueAsString(druidGroupByQuery); @@ -221,19 +230,19 @@ public void testAllFields() throws JSONException, JsonProcessingException { DruidAggregator aggregator = new CountAggregator("Chill"); DruidPostAggregator postAggregator = new ConstantPostAggregator("Keep", 16.11); Context context = Context.builder() - .populateCache(true) - .build(); + .populateCache(true) + .build(); DruidGroupByQuery druidGroupByQuery = DruidGroupByQuery.builder() - .dataSource(new TableDataSource("sample_datasource")) - .dimensions(Arrays.asList(druidDimension1, druidDimension2)) - .granularity(granularity) - .filter(filter) - .aggregators(Collections.singletonList(aggregator)) - .postAggregators(Collections.singletonList(postAggregator)) - .intervals(Collections.singletonList(interval)) - .context(context) - .build(); + .dataSource(new TableDataSource("sample_datasource")) + .dimensions(Arrays.asList(druidDimension1, druidDimension2)) + .granularity(granularity) + .filter(filter) + .aggregators(Collections.singletonList(aggregator)) + .postAggregators(Collections.singletonList(postAggregator)) + .intervals(Collections.singletonList(interval)) + .context(context) + .build(); String actualJson = objectMapper.writeValueAsString(druidGroupByQuery); @@ -255,7 +264,7 @@ public void testAllFields() throws JSONException, JsonProcessingException { expectedContext.put("populateCache", true); JSONArray intervalArray = new JSONArray(Collections.singletonList("2012-01-01T00:00:00.000Z/" + - "2012-01-03T00:00:00.000Z")); + "2012-01-03T00:00:00.000Z")); JSONArray dimensionArray = new JSONArray(Arrays.asList("dim1", "dim2")); JSONObject dataSource = new JSONObject(); diff --git a/src/test/java/in/zapr/druid/druidry/query/aggregation/TimeSeriesTest.java b/src/test/java/in/zapr/druid/druidry/query/aggregation/TimeSeriesTest.java index ae7f4875..668d5452 100644 --- a/src/test/java/in/zapr/druid/druidry/query/aggregation/TimeSeriesTest.java +++ b/src/test/java/in/zapr/druid/druidry/query/aggregation/TimeSeriesTest.java @@ -33,8 +33,6 @@ import java.util.Arrays; import java.util.Collections; -import in.zapr.druid.druidry.query.config.Context; -import in.zapr.druid.druidry.query.config.Interval; import in.zapr.druid.druidry.aggregator.CountAggregator; import in.zapr.druid.druidry.aggregator.DoubleSumAggregator; import in.zapr.druid.druidry.aggregator.DruidAggregator; @@ -52,6 +50,8 @@ import in.zapr.druid.druidry.postAggregator.ConstantPostAggregator; import in.zapr.druid.druidry.postAggregator.DruidPostAggregator; import in.zapr.druid.druidry.postAggregator.FieldAccessPostAggregator; +import in.zapr.druid.druidry.query.config.Context; +import in.zapr.druid.druidry.query.config.Interval; public class TimeSeriesTest { private static ObjectMapper objectMapper; @@ -61,42 +61,49 @@ public void init() { objectMapper = new ObjectMapper(); objectMapper.registerModule(new JodaModule()); objectMapper.configure(com.fasterxml.jackson.databind.SerializationFeature. - WRITE_DATES_AS_TIMESTAMPS, false); + WRITE_DATES_AS_TIMESTAMPS, false); } @Test public void testSampleQuery() throws JsonProcessingException, JSONException { SelectorFilter selectorFilter2 = new SelectorFilter("sample_dimension2", - "sample_value2"); + "sample_value2"); SelectorFilter selectorFilter3 = new SelectorFilter("sample_dimension3", - "sample_value3"); + "sample_value3"); OrFilter orfilter = new OrFilter(Arrays.asList(selectorFilter2, selectorFilter3)); SelectorFilter selectorFilter1 = new SelectorFilter("sample_dimension1", - "sample_value1"); + "sample_value1"); AndFilter andFilter = new AndFilter(Arrays.asList(selectorFilter1, orfilter)); - DruidAggregator aggregator1 = new LongSumAggregator("sample_name1", - "sample_fieldName1"); - DruidAggregator aggregator2 = new DoubleSumAggregator("sample_name2", - "sample_fieldName2"); + DruidAggregator aggregator1 = + LongSumAggregator.builder() + .name("sample_name1") + .fieldName("sample_fieldName1") + .build(); + + DruidAggregator aggregator2 = + DoubleSumAggregator.builder() + .name("sample_name2") + .fieldName("sample_fieldName2") + .build(); FieldAccessPostAggregator fieldAccessPostAggregator1 - = new FieldAccessPostAggregator("postAgg__sample_name1", - "sample_name1"); + = new FieldAccessPostAggregator("postAgg__sample_name1", + "sample_name1"); FieldAccessPostAggregator fieldAccessPostAggregator2 - = new FieldAccessPostAggregator("postAgg__sample_name2", - "sample_name2"); + = new FieldAccessPostAggregator("postAgg__sample_name2", + "sample_name2"); DruidPostAggregator postAggregator = ArithmeticPostAggregator.builder() - .name("sample_divide") - .function(ArithmeticFunction.DIVIDE) - .fields(Arrays.asList(fieldAccessPostAggregator1, fieldAccessPostAggregator2)) - .build(); + .name("sample_divide") + .function(ArithmeticFunction.DIVIDE) + .fields(Arrays.asList(fieldAccessPostAggregator1, fieldAccessPostAggregator2)) + .build(); //2013-08-31T00:00:00.000/2013-09-03T00:00:00.000" DateTime startTime = new DateTime(2012, 1, 1, 0, 0, 0, DateTimeZone.UTC); @@ -106,51 +113,51 @@ public void testSampleQuery() throws JsonProcessingException, JSONException { Granularity granularity = new SimpleGranularity(PredefinedGranularity.DAY); DruidTimeSeriesQuery query = DruidTimeSeriesQuery.builder() - .dataSource(new TableDataSource("sample_datasource")) - .granularity(granularity) - .descending(true) - .filter(andFilter) - .aggregators(Arrays.asList(aggregator1, aggregator2)) - .postAggregators(Collections.singletonList(postAggregator)) - .intervals(Collections.singletonList(interval)) - .build(); + .dataSource(new TableDataSource("sample_datasource")) + .granularity(granularity) + .descending(true) + .filter(andFilter) + .aggregators(Arrays.asList(aggregator1, aggregator2)) + .postAggregators(Collections.singletonList(postAggregator)) + .intervals(Collections.singletonList(interval)) + .build(); String expectedJsonAsString = "{\n" + - " \"queryType\": \"timeseries\",\n" + - " \"dataSource\": {\n" + - " \"type\": \"table\",\n" + - " \"name\": \"sample_datasource\"\n" + - " },\n" + - " \"granularity\": \"day\",\n" + - " \"descending\": true,\n" + - " \"filter\": {\n" + - " \"type\": \"and\",\n" + - " \"fields\": [\n" + - " { \"type\": \"selector\", \"dimension\": \"sample_dimension1\", \"value\": \"sample_value1\" },\n" + - " { \"type\": \"or\",\n" + - " \"fields\": [\n" + - " { \"type\": \"selector\", \"dimension\": \"sample_dimension2\", \"value\": \"sample_value2\" },\n" + - " { \"type\": \"selector\", \"dimension\": \"sample_dimension3\", \"value\": \"sample_value3\" }\n" + - " ]\n" + - " }\n" + - " ]\n" + - " },\n" + - " \"aggregations\": [\n" + - " { \"type\": \"longSum\", \"name\": \"sample_name1\", \"fieldName\": \"sample_fieldName1\", \"expression\": null },\n" + - " { \"type\": \"doubleSum\", \"name\": \"sample_name2\", \"fieldName\": \"sample_fieldName2\", \"expression\": null }\n" + - " ],\n" + - " \"postAggregations\": [\n" + - " { \"type\": \"arithmetic\",\n" + - " \"name\": \"sample_divide\",\n" + - " \"fn\": \"/\",\n" + - " \"fields\": [\n" + - " { \"type\": \"fieldAccess\", \"name\": \"postAgg__sample_name1\", \"fieldName\": \"sample_name1\" },\n" + - " { \"type\": \"fieldAccess\", \"name\": \"postAgg__sample_name2\", \"fieldName\": \"sample_name2\" }\n" + - " ]\n" + - " }\n" + - " ],\n" + - " \"intervals\": [ \"2012-01-01T00:00:00.000Z/2012-01-03T00:00:00.000Z\" ]\n" + - "}"; + " \"queryType\": \"timeseries\",\n" + + " \"dataSource\": {\n" + + " \"type\": \"table\",\n" + + " \"name\": \"sample_datasource\"\n" + + " },\n" + + " \"granularity\": \"day\",\n" + + " \"descending\": true,\n" + + " \"filter\": {\n" + + " \"type\": \"and\",\n" + + " \"fields\": [\n" + + " { \"type\": \"selector\", \"dimension\": \"sample_dimension1\", \"value\": \"sample_value1\" },\n" + + " { \"type\": \"or\",\n" + + " \"fields\": [\n" + + " { \"type\": \"selector\", \"dimension\": \"sample_dimension2\", \"value\": \"sample_value2\" },\n" + + " { \"type\": \"selector\", \"dimension\": \"sample_dimension3\", \"value\": \"sample_value3\" }\n" + + " ]\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"aggregations\": [\n" + + " { \"type\": \"longSum\", \"name\": \"sample_name1\", \"fieldName\": \"sample_fieldName1\" },\n" + + " { \"type\": \"doubleSum\", \"name\": \"sample_name2\", \"fieldName\": \"sample_fieldName2\" }\n" + + " ],\n" + + " \"postAggregations\": [\n" + + " { \"type\": \"arithmetic\",\n" + + " \"name\": \"sample_divide\",\n" + + " \"fn\": \"/\",\n" + + " \"fields\": [\n" + + " { \"type\": \"fieldAccess\", \"name\": \"postAgg__sample_name1\", \"fieldName\": \"sample_name1\" },\n" + + " { \"type\": \"fieldAccess\", \"name\": \"postAgg__sample_name2\", \"fieldName\": \"sample_name2\" }\n" + + " ]\n" + + " }\n" + + " ],\n" + + " \"intervals\": [ \"2012-01-01T00:00:00.000Z/2012-01-03T00:00:00.000Z\" ]\n" + + "}"; String actualJson = objectMapper.writeValueAsString(query); JSONAssert.assertEquals(actualJson, expectedJsonAsString, JSONCompareMode.NON_EXTENSIBLE); @@ -165,10 +172,10 @@ public void testRequiredFields() throws JsonProcessingException, JSONException { Granularity granularity = new SimpleGranularity(PredefinedGranularity.DAY); DruidTimeSeriesQuery seriesQuery = DruidTimeSeriesQuery.builder() - .dataSource(new TableDataSource("Matrix")) - .intervals(Collections.singletonList(interval)) - .granularity(granularity) - .build(); + .dataSource(new TableDataSource("Matrix")) + .intervals(Collections.singletonList(interval)) + .granularity(granularity) + .build(); JSONObject dataSource = new JSONObject(); dataSource.put("type", "table"); @@ -178,7 +185,7 @@ public void testRequiredFields() throws JsonProcessingException, JSONException { expectedQuery.put("queryType", "timeseries"); expectedQuery.put("dataSource", dataSource); expectedQuery.put("intervals", new JSONArray(Collections - .singletonList("2013-07-14T00:00:00.000Z/2013-11-16T00:00:00.000Z"))); + .singletonList("2013-07-14T00:00:00.000Z/2013-11-16T00:00:00.000Z"))); expectedQuery.put("granularity", "day"); String actualJson = objectMapper.writeValueAsString(seriesQuery); @@ -194,23 +201,23 @@ public void testAllFields() throws JSONException, JsonProcessingException { Granularity granularity = new SimpleGranularity(PredefinedGranularity.DAY); Context context = Context.builder() - .useCache(true) - .build(); + .useCache(true) + .build(); DruidFilter filter = new SelectorFilter("Spread", "Peace"); DruidAggregator aggregator = new CountAggregator("Chill"); DruidPostAggregator postAggregator = new ConstantPostAggregator("Keep", 10.47); DruidTimeSeriesQuery seriesQuery = DruidTimeSeriesQuery.builder() - .dataSource(new TableDataSource("Matrix")) - .descending(true) - .intervals(Collections.singletonList(interval)) - .granularity(granularity) - .filter(filter) - .aggregators(Collections.singletonList(aggregator)) - .postAggregators(Collections.singletonList(postAggregator)) - .context(context) - .build(); + .dataSource(new TableDataSource("Matrix")) + .descending(true) + .intervals(Collections.singletonList(interval)) + .granularity(granularity) + .filter(filter) + .aggregators(Collections.singletonList(aggregator)) + .postAggregators(Collections.singletonList(postAggregator)) + .context(context) + .build(); JSONObject expectedFilter = new JSONObject(); expectedFilter.put("type", "selector"); @@ -237,7 +244,7 @@ public void testAllFields() throws JSONException, JsonProcessingException { expectedQuery.put("queryType", "timeseries"); expectedQuery.put("dataSource", dataSource); expectedQuery.put("intervals", new JSONArray(Collections - .singletonList("2013-07-14T00:00:00.000Z/2013-11-16T00:00:00.000Z"))); + .singletonList("2013-07-14T00:00:00.000Z/2013-11-16T00:00:00.000Z"))); expectedQuery.put("granularity", "day"); expectedQuery.put("aggregations", new JSONArray(Collections.singletonList(expectedAggregator))); expectedQuery.put("postAggregations", new JSONArray(Collections.singletonList(expectedPostAggregator))); diff --git a/src/test/java/in/zapr/druid/druidry/query/aggregation/TopNQueryTest.java b/src/test/java/in/zapr/druid/druidry/query/aggregation/TopNQueryTest.java index 8d1a2f51..2002ee10 100644 --- a/src/test/java/in/zapr/druid/druidry/query/aggregation/TopNQueryTest.java +++ b/src/test/java/in/zapr/druid/druidry/query/aggregation/TopNQueryTest.java @@ -33,8 +33,6 @@ import java.util.Arrays; import java.util.Collections; -import in.zapr.druid.druidry.query.config.Context; -import in.zapr.druid.druidry.query.config.Interval; import in.zapr.druid.druidry.aggregator.CountAggregator; import in.zapr.druid.druidry.aggregator.DoubleSumAggregator; import in.zapr.druid.druidry.aggregator.DruidAggregator; @@ -53,6 +51,8 @@ import in.zapr.druid.druidry.postAggregator.ConstantPostAggregator; import in.zapr.druid.druidry.postAggregator.DruidPostAggregator; import in.zapr.druid.druidry.postAggregator.FieldAccessPostAggregator; +import in.zapr.druid.druidry.query.config.Context; +import in.zapr.druid.druidry.query.config.Interval; import in.zapr.druid.druidry.topNMetric.SimpleMetric; import in.zapr.druid.druidry.topNMetric.TopNMetric; @@ -72,20 +72,29 @@ public void testSampleQuery() throws JsonProcessingException, JSONException { AndFilter filter = new AndFilter(Arrays.asList(selectorFilter1, selectorFilter2)); - DruidAggregator aggregator1 = new LongSumAggregator("count", "count"); - DruidAggregator aggregator2 = new DoubleSumAggregator("some_metric", "some_metric"); + DruidAggregator aggregator1 = + LongSumAggregator.builder() + .name("count") + .fieldName("count") + .build(); + + DruidAggregator aggregator2 = + DoubleSumAggregator.builder() + .name("some_metric") + .fieldName("some_metric") + .build(); FieldAccessPostAggregator fieldAccessPostAggregator1 - = new FieldAccessPostAggregator("some_metric", "some_metric"); + = new FieldAccessPostAggregator("some_metric", "some_metric"); FieldAccessPostAggregator fieldAccessPostAggregator2 - = new FieldAccessPostAggregator("count", "count"); + = new FieldAccessPostAggregator("count", "count"); DruidPostAggregator postAggregator = ArithmeticPostAggregator.builder() - .name("sample_divide") - .function(ArithmeticFunction.DIVIDE) - .fields(Arrays.asList(fieldAccessPostAggregator1, fieldAccessPostAggregator2)) - .build(); + .name("sample_divide") + .function(ArithmeticFunction.DIVIDE) + .fields(Arrays.asList(fieldAccessPostAggregator1, fieldAccessPostAggregator2)) + .build(); DateTime startTime = new DateTime(2013, 8, 31, 0, 0, 0, DateTimeZone.UTC); DateTime endTime = new DateTime(2013, 9, 3, 0, 0, 0, DateTimeZone.UTC); @@ -97,79 +106,77 @@ public void testSampleQuery() throws JsonProcessingException, JSONException { TopNMetric metric = new SimpleMetric("count"); DruidTopNQuery query = DruidTopNQuery.builder() - .dataSource(new TableDataSource("sample_data")) - .dimension(dimension) - .threshold(5) - .topNMetric(metric) - .granularity(granularity) - .filter(filter) - .aggregators(Arrays.asList(aggregator1, aggregator2)) - .postAggregators(Collections.singletonList(postAggregator)) - .intervals(Collections.singletonList(interval)) - .build(); + .dataSource(new TableDataSource("sample_data")) + .dimension(dimension) + .threshold(5) + .topNMetric(metric) + .granularity(granularity) + .filter(filter) + .aggregators(Arrays.asList(aggregator1, aggregator2)) + .postAggregators(Collections.singletonList(postAggregator)) + .intervals(Collections.singletonList(interval)) + .build(); String expectedJsonAsString = "{\n" + - " \"queryType\": \"topN\",\n" + - " \"dataSource\": {\n" + - " \"type\": \"table\",\n" + - " \"name\": \"sample_data\"\n" + - " },\n" + - " \"dimension\": \"sample_dim\",\n" + - " \"threshold\": 5,\n" + - " \"metric\": \"count\",\n" + - " \"granularity\": \"all\",\n" + - " \"filter\": {\n" + - " \"type\": \"and\",\n" + - " \"fields\": [\n" + - " {\n" + - " \"type\": \"selector\",\n" + - " \"dimension\": \"dim1\",\n" + - " \"value\": \"some_value\"\n" + - " },\n" + - " {\n" + - " \"type\": \"selector\",\n" + - " \"dimension\": \"dim2\",\n" + - " \"value\": \"some_other_val\"\n" + - " }\n" + - " ]\n" + - " },\n" + - " \"aggregations\": [\n" + - " {\n" + - " \"type\": \"longSum\",\n" + - " \"name\": \"count\",\n" + - " \"fieldName\": \"count\",\n" + - " \"expression\": null\n" + - " },\n" + - " {\n" + - " \"type\": \"doubleSum\",\n" + - " \"name\": \"some_metric\",\n" + - " \"fieldName\": \"some_metric\",\n" + - " \"expression\": null\n" + - " }\n" + - " ],\n" + - " \"postAggregations\": [\n" + - " {\n" + - " \"type\": \"arithmetic\",\n" + - " \"name\": \"sample_divide\",\n" + - " \"fn\": \"/\",\n" + - " \"fields\": [\n" + - " {\n" + - " \"type\": \"fieldAccess\",\n" + - " \"name\": \"some_metric\",\n" + - " \"fieldName\": \"some_metric\"\n" + - " },\n" + - " {\n" + - " \"type\": \"fieldAccess\",\n" + - " \"name\": \"count\",\n" + - " \"fieldName\": \"count\"\n" + - " }\n" + - " ]\n" + - " }\n" + - " ],\n" + - " \"intervals\": [\n" + - " \"2013-08-31T00:00:00.000Z/2013-09-03T00:00:00.000Z\"\n" + - " ]\n" + - "}"; + " \"queryType\": \"topN\",\n" + + " \"dataSource\": {\n" + + " \"type\": \"table\",\n" + + " \"name\": \"sample_data\"\n" + + " },\n" + + " \"dimension\": \"sample_dim\",\n" + + " \"threshold\": 5,\n" + + " \"metric\": \"count\",\n" + + " \"granularity\": \"all\",\n" + + " \"filter\": {\n" + + " \"type\": \"and\",\n" + + " \"fields\": [\n" + + " {\n" + + " \"type\": \"selector\",\n" + + " \"dimension\": \"dim1\",\n" + + " \"value\": \"some_value\"\n" + + " },\n" + + " {\n" + + " \"type\": \"selector\",\n" + + " \"dimension\": \"dim2\",\n" + + " \"value\": \"some_other_val\"\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"aggregations\": [\n" + + " {\n" + + " \"type\": \"longSum\",\n" + + " \"name\": \"count\",\n" + + " \"fieldName\": \"count\"\n" + + " },\n" + + " {\n" + + " \"type\": \"doubleSum\",\n" + + " \"name\": \"some_metric\",\n" + + " \"fieldName\": \"some_metric\"\n" + + " }\n" + + " ],\n" + + " \"postAggregations\": [\n" + + " {\n" + + " \"type\": \"arithmetic\",\n" + + " \"name\": \"sample_divide\",\n" + + " \"fn\": \"/\",\n" + + " \"fields\": [\n" + + " {\n" + + " \"type\": \"fieldAccess\",\n" + + " \"name\": \"some_metric\",\n" + + " \"fieldName\": \"some_metric\"\n" + + " },\n" + + " {\n" + + " \"type\": \"fieldAccess\",\n" + + " \"name\": \"count\",\n" + + " \"fieldName\": \"count\"\n" + + " }\n" + + " ]\n" + + " }\n" + + " ],\n" + + " \"intervals\": [\n" + + " \"2013-08-31T00:00:00.000Z/2013-09-03T00:00:00.000Z\"\n" + + " ]\n" + + "}"; String actualJson = objectMapper.writeValueAsString(query); JSONAssert.assertEquals(expectedJsonAsString, actualJson, JSONCompareMode.NON_EXTENSIBLE); @@ -188,13 +195,13 @@ public void testRequiredFields() throws JsonProcessingException, JSONException { Granularity granularity = new SimpleGranularity(PredefinedGranularity.DAY); DruidTopNQuery query = DruidTopNQuery.builder() - .dataSource(new TableDataSource("sample_data")) - .intervals(Collections.singletonList(interval)) - .granularity(granularity) - .dimension(dimension) - .threshold(7) - .topNMetric(metric) - .build(); + .dataSource(new TableDataSource("sample_data")) + .intervals(Collections.singletonList(interval)) + .granularity(granularity) + .dimension(dimension) + .threshold(7) + .topNMetric(metric) + .build(); String actualJson = objectMapper.writeValueAsString(query); @@ -231,21 +238,21 @@ public void testAllFields() throws JSONException, JsonProcessingException { DruidAggregator aggregator = new CountAggregator("Chill"); DruidPostAggregator postAggregator = new ConstantPostAggregator("Keep", 16.11); Context context = Context.builder() - .populateCache(true) - .build(); + .populateCache(true) + .build(); DruidTopNQuery query = DruidTopNQuery.builder() - .dataSource(new TableDataSource("sample_data")) - .intervals(Collections.singletonList(interval)) - .granularity(granularity) - .filter(filter) - .aggregators(Collections.singletonList(aggregator)) - .postAggregators(Collections.singletonList(postAggregator)) - .dimension(dimension) - .threshold(7) - .topNMetric(metric) - .context(context) - .build(); + .dataSource(new TableDataSource("sample_data")) + .intervals(Collections.singletonList(interval)) + .granularity(granularity) + .filter(filter) + .aggregators(Collections.singletonList(aggregator)) + .postAggregators(Collections.singletonList(postAggregator)) + .dimension(dimension) + .threshold(7) + .topNMetric(metric) + .context(context) + .build(); String actualJson = objectMapper.writeValueAsString(query); @@ -303,34 +310,34 @@ public void testEquals() { DruidAggregator aggregator = new CountAggregator("Chill"); DruidPostAggregator postAggregator = new ConstantPostAggregator("Keep", 16.11); Context context = Context.builder() - .populateCache(true) - .build(); + .populateCache(true) + .build(); DruidTopNQuery query1 = DruidTopNQuery.builder() - .dataSource(new TableDataSource("sample_data")) - .intervals(Collections.singletonList(interval)) - .granularity(granularity) - .filter(filter) - .aggregators(Collections.singletonList(aggregator)) - .postAggregators(Collections.singletonList(postAggregator)) - .dimension(dimension) - .threshold(7) - .topNMetric(metric) - .context(context) - .build(); + .dataSource(new TableDataSource("sample_data")) + .intervals(Collections.singletonList(interval)) + .granularity(granularity) + .filter(filter) + .aggregators(Collections.singletonList(aggregator)) + .postAggregators(Collections.singletonList(postAggregator)) + .dimension(dimension) + .threshold(7) + .topNMetric(metric) + .context(context) + .build(); DruidTopNQuery query2 = DruidTopNQuery.builder() - .dataSource(new TableDataSource("sample_data")) - .intervals(Collections.singletonList(interval)) - .granularity(granularity) - .filter(filter) - .aggregators(Collections.singletonList(aggregator)) - .postAggregators(Collections.singletonList(postAggregator)) - .dimension(dimension) - .threshold(7) - .topNMetric(metric) - .context(context) - .build(); + .dataSource(new TableDataSource("sample_data")) + .intervals(Collections.singletonList(interval)) + .granularity(granularity) + .filter(filter) + .aggregators(Collections.singletonList(aggregator)) + .postAggregators(Collections.singletonList(postAggregator)) + .dimension(dimension) + .threshold(7) + .topNMetric(metric) + .context(context) + .build(); Assert.assertEquals(query1, query2); } @@ -350,34 +357,34 @@ public void testUnequals() { DruidAggregator aggregator = new CountAggregator("Chill"); DruidPostAggregator postAggregator = new ConstantPostAggregator("Keep", 16.11); Context context = Context.builder() - .populateCache(true) - .build(); + .populateCache(true) + .build(); DruidTopNQuery query1 = DruidTopNQuery.builder() - .dataSource(new TableDataSource("sample_data")) - .intervals(Collections.singletonList(interval)) - .granularity(granularity) - .filter(filter) - .aggregators(Collections.singletonList(aggregator)) - .postAggregators(Collections.singletonList(postAggregator)) - .dimension(dimension) - .threshold(7) - .topNMetric(metric) - .context(context) - .build(); + .dataSource(new TableDataSource("sample_data")) + .intervals(Collections.singletonList(interval)) + .granularity(granularity) + .filter(filter) + .aggregators(Collections.singletonList(aggregator)) + .postAggregators(Collections.singletonList(postAggregator)) + .dimension(dimension) + .threshold(7) + .topNMetric(metric) + .context(context) + .build(); DruidTopNQuery query2 = DruidTopNQuery.builder() - .dataSource(new TableDataSource("sample_data")) - .intervals(Collections.singletonList(interval)) - .granularity(granularity) - .filter(filter) - .aggregators(Collections.singletonList(aggregator)) - .postAggregators(Collections.singletonList(postAggregator)) - .dimension(dimension) - .threshold(314) - .topNMetric(metric) - .context(context) - .build(); + .dataSource(new TableDataSource("sample_data")) + .intervals(Collections.singletonList(interval)) + .granularity(granularity) + .filter(filter) + .aggregators(Collections.singletonList(aggregator)) + .postAggregators(Collections.singletonList(postAggregator)) + .dimension(dimension) + .threshold(314) + .topNMetric(metric) + .context(context) + .build(); Assert.assertNotEquals(query1, query2); } @@ -397,20 +404,20 @@ public void preconditionCheck() { DruidAggregator aggregator = new CountAggregator("Chill"); DruidPostAggregator postAggregator = new ConstantPostAggregator("Keep", 16.11); Context context = Context.builder() - .populateCache(true) - .build(); + .populateCache(true) + .build(); DruidTopNQuery query1 = DruidTopNQuery.builder() - .dataSource(new TableDataSource("sample_data")) - .intervals(Collections.singletonList(interval)) - .granularity(granularity) - .filter(filter) - .aggregators(Collections.singletonList(aggregator)) - .postAggregators(Collections.singletonList(postAggregator)) - .dimension(dimension) - .threshold(-5) - .topNMetric(metric) - .context(context) - .build(); + .dataSource(new TableDataSource("sample_data")) + .intervals(Collections.singletonList(interval)) + .granularity(granularity) + .filter(filter) + .aggregators(Collections.singletonList(aggregator)) + .postAggregators(Collections.singletonList(postAggregator)) + .dimension(dimension) + .threshold(-5) + .topNMetric(metric) + .context(context) + .build(); } } From fde16473f142e209d38158a65ad71a27245de1f1 Mon Sep 17 00:00:00 2001 From: Alper Kanat Date: Sat, 21 Mar 2020 23:42:01 +0300 Subject: [PATCH 18/25] Added back tests for old constructor, reverted some changes in tests --- .../aggregator/DoubleMaxAggregatorTest.java | 9 +- .../aggregator/DoubleMinAggregatorTest.java | 9 +- .../aggregator/DoubleSumAggregatorTest.java | 9 +- .../aggregator/LongMaxAggregatorTest.java | 9 +- .../aggregator/LongMinAggregatorTest.java | 9 +- .../aggregator/LongSumAggregatorTest.java | 9 +- .../query/aggregation/GroupByTest.java | 169 +++++---- .../query/aggregation/TimeSeriesTest.java | 163 +++++---- .../query/aggregation/TopNQueryTest.java | 329 +++++++++--------- 9 files changed, 336 insertions(+), 379 deletions(-) diff --git a/src/test/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregatorTest.java b/src/test/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregatorTest.java index 9b694c55..12d10918 100644 --- a/src/test/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregatorTest.java +++ b/src/test/java/in/zapr/druid/druidry/aggregator/DoubleMaxAggregatorTest.java @@ -40,13 +40,10 @@ public void init() { } @Test - public void testAllButExpression() throws JSONException, JsonProcessingException { + public void testAllFields() throws JsonProcessingException, JSONException { - DoubleMaxAggregator doubleMaxAggregator = - DoubleMaxAggregator.builder() - .name("CarpeDiem") - .fieldName("Hey") - .build(); + DoubleMaxAggregator doubleMaxAggregator = new DoubleMaxAggregator("CarpeDiem", + "Hey"); JSONObject jsonObject = new JSONObject(); jsonObject.put("type", "doubleMax"); diff --git a/src/test/java/in/zapr/druid/druidry/aggregator/DoubleMinAggregatorTest.java b/src/test/java/in/zapr/druid/druidry/aggregator/DoubleMinAggregatorTest.java index ece08f84..57868c52 100644 --- a/src/test/java/in/zapr/druid/druidry/aggregator/DoubleMinAggregatorTest.java +++ b/src/test/java/in/zapr/druid/druidry/aggregator/DoubleMinAggregatorTest.java @@ -40,13 +40,10 @@ public void init() { } @Test - public void testAllFieldsButExpression() throws JSONException, JsonProcessingException { + public void testAllFields() throws JsonProcessingException, JSONException { - DoubleMinAggregator doubleMinAggregator = - DoubleMinAggregator.builder() - .name("CarpeDiem") - .fieldName("Hey") - .build(); + DoubleMinAggregator doubleMinAggregator = new DoubleMinAggregator("CarpeDiem", + "Hey"); JSONObject jsonObject = new JSONObject(); jsonObject.put("type", "doubleMin"); diff --git a/src/test/java/in/zapr/druid/druidry/aggregator/DoubleSumAggregatorTest.java b/src/test/java/in/zapr/druid/druidry/aggregator/DoubleSumAggregatorTest.java index 586c5fd1..2278b415 100644 --- a/src/test/java/in/zapr/druid/druidry/aggregator/DoubleSumAggregatorTest.java +++ b/src/test/java/in/zapr/druid/druidry/aggregator/DoubleSumAggregatorTest.java @@ -40,13 +40,10 @@ public void init() { } @Test - public void testAllFieldsButExpression() throws JsonProcessingException, JSONException { + public void testAllFields() throws JsonProcessingException, JSONException { - DoubleSumAggregator doubleSumAggregator = - DoubleSumAggregator.builder() - .name("CarpeDiem") - .fieldName("Hey") - .build(); + DoubleSumAggregator doubleSumAggregator = new DoubleSumAggregator("CarpeDiem", + "Hey"); JSONObject jsonObject = new JSONObject(); jsonObject.put("type", "doubleSum"); diff --git a/src/test/java/in/zapr/druid/druidry/aggregator/LongMaxAggregatorTest.java b/src/test/java/in/zapr/druid/druidry/aggregator/LongMaxAggregatorTest.java index c64c4f85..dffff4de 100644 --- a/src/test/java/in/zapr/druid/druidry/aggregator/LongMaxAggregatorTest.java +++ b/src/test/java/in/zapr/druid/druidry/aggregator/LongMaxAggregatorTest.java @@ -40,13 +40,10 @@ public void init() { } @Test - public void testAllFieldsButExpression() throws JsonProcessingException, JSONException { + public void testAllFields() throws JsonProcessingException, JSONException { - LongMaxAggregator countAggregator = - LongMaxAggregator.builder() - .name("CarpeDiem") - .fieldName("Hey") - .build(); + LongMaxAggregator countAggregator = new LongMaxAggregator("CarpeDiem", + "Hey"); JSONObject jsonObject = new JSONObject(); jsonObject.put("type", "longMax"); diff --git a/src/test/java/in/zapr/druid/druidry/aggregator/LongMinAggregatorTest.java b/src/test/java/in/zapr/druid/druidry/aggregator/LongMinAggregatorTest.java index 37840dda..0c5ac86c 100644 --- a/src/test/java/in/zapr/druid/druidry/aggregator/LongMinAggregatorTest.java +++ b/src/test/java/in/zapr/druid/druidry/aggregator/LongMinAggregatorTest.java @@ -40,13 +40,10 @@ public void init() { } @Test - public void testAllFieldsButExpression() throws JsonProcessingException, JSONException { + public void testAllFields() throws JsonProcessingException, JSONException { - LongMinAggregator longMinAggregator = - LongMinAggregator.builder() - .name("CarpeDiem") - .fieldName("Hey") - .build(); + LongMinAggregator longMinAggregator = new LongMinAggregator("CarpeDiem", + "Hey"); JSONObject jsonObject = new JSONObject(); jsonObject.put("type", "longMin"); diff --git a/src/test/java/in/zapr/druid/druidry/aggregator/LongSumAggregatorTest.java b/src/test/java/in/zapr/druid/druidry/aggregator/LongSumAggregatorTest.java index 7a4a8983..c0ad62ae 100644 --- a/src/test/java/in/zapr/druid/druidry/aggregator/LongSumAggregatorTest.java +++ b/src/test/java/in/zapr/druid/druidry/aggregator/LongSumAggregatorTest.java @@ -40,13 +40,10 @@ public void init() { } @Test - public void testAllFieldsButExpression() throws JsonProcessingException, JSONException { + public void testAllFields() throws JsonProcessingException, JSONException { - LongSumAggregator longSumAggregator = - LongSumAggregator.builder() - .name("CarpeDiem") - .fieldName("Hey") - .build(); + LongSumAggregator longSumAggregator = new LongSumAggregator("CarpeDiem", + "Hey"); JSONObject jsonObject = new JSONObject(); jsonObject.put("type", "longSum"); diff --git a/src/test/java/in/zapr/druid/druidry/query/aggregation/GroupByTest.java b/src/test/java/in/zapr/druid/druidry/query/aggregation/GroupByTest.java index 81f234e2..37f1c68d 100644 --- a/src/test/java/in/zapr/druid/druidry/query/aggregation/GroupByTest.java +++ b/src/test/java/in/zapr/druid/druidry/query/aggregation/GroupByTest.java @@ -19,6 +19,8 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import in.zapr.druid.druidry.filter.havingSpec.HavingSpec; +import in.zapr.druid.druidry.filter.havingSpec.GreaterThanHaving; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.json.JSONArray; @@ -33,6 +35,8 @@ import java.util.Collections; import java.util.List; +import in.zapr.druid.druidry.query.config.Context; +import in.zapr.druid.druidry.query.config.Interval; import in.zapr.druid.druidry.aggregator.CountAggregator; import in.zapr.druid.druidry.aggregator.DoubleSumAggregator; import in.zapr.druid.druidry.aggregator.DruidAggregator; @@ -44,8 +48,6 @@ import in.zapr.druid.druidry.filter.DruidFilter; import in.zapr.druid.druidry.filter.OrFilter; import in.zapr.druid.druidry.filter.SelectorFilter; -import in.zapr.druid.druidry.filter.havingSpec.GreaterThanHaving; -import in.zapr.druid.druidry.filter.havingSpec.HavingSpec; import in.zapr.druid.druidry.granularity.Granularity; import in.zapr.druid.druidry.granularity.PredefinedGranularity; import in.zapr.druid.druidry.granularity.SimpleGranularity; @@ -57,8 +59,6 @@ import in.zapr.druid.druidry.postAggregator.ConstantPostAggregator; import in.zapr.druid.druidry.postAggregator.DruidPostAggregator; import in.zapr.druid.druidry.postAggregator.FieldAccessPostAggregator; -import in.zapr.druid.druidry.query.config.Context; -import in.zapr.druid.druidry.query.config.Interval; public class GroupByTest { private static ObjectMapper objectMapper; @@ -71,47 +71,47 @@ public void init() { @Test public void testSampleQuery() throws JsonProcessingException, JSONException { String expectedJsonAsString = "{\n" + - " \"queryType\": \"groupBy\",\n" + - " \"dataSource\": {\n" + - " \"type\": \"table\",\n" + - " \"name\": \"sample_datasource\"\n" + - " },\n" + - " \"granularity\": \"day\",\n" + - " \"dimensions\": [\"country\", \"device\"],\n" + - " \"limitSpec\": { \"type\": \"default\", \"limit\": 5000, \"columns\": [\"country\", \"data_transfer\"] },\n" + - " \"filter\": {\n" + - " \"type\": \"and\",\n" + - " \"fields\": [\n" + - " { \"type\": \"selector\", \"dimension\": \"carrier\", \"value\": \"AT&T\" },\n" + - " { \"type\": \"or\", \n" + - " \"fields\": [\n" + - " { \"type\": \"selector\", \"dimension\": \"make\", \"value\": \"Apple\" },\n" + - " { \"type\": \"selector\", \"dimension\": \"make\", \"value\": \"Samsung\" }\n" + - " ]\n" + - " }\n" + - " ]\n" + - " },\n" + - " \"aggregations\": [\n" + - " { \"type\": \"longSum\", \"name\": \"total_usage\", \"fieldName\": \"user_count\" },\n" + - " { \"type\": \"doubleSum\", \"name\": \"data_transfer\", \"fieldName\": \"data_transfer\" }\n" + - " ],\n" + - "\"having\": {\n" + - " \"type\": \"greaterThan\",\n" + - " \"aggregation\": \"total_usage\",\n" + - " \"value\": 2\n" + - " }," + - " \"postAggregations\": [\n" + - " { \"type\": \"arithmetic\",\n" + - " \"name\": \"avg_usage\",\n" + - " \"fn\": \"/\",\n" + - " \"fields\": [\n" + - " { \"type\": \"fieldAccess\", \"fieldName\": \"data_transfer\" },\n" + - " { \"type\": \"fieldAccess\", \"fieldName\": \"total_usage\" }\n" + - " ]\n" + - " }\n" + - " ],\n" + - " \"intervals\": [ \"2012-01-01T00:00:00.000Z/2012-01-03T00:00:00.000Z\" ]\n" + - "}\n"; + " \"queryType\": \"groupBy\",\n" + + " \"dataSource\": {\n" + + " \"type\": \"table\",\n" + + " \"name\": \"sample_datasource\"\n" + + " },\n" + + " \"granularity\": \"day\",\n" + + " \"dimensions\": [\"country\", \"device\"],\n" + + " \"limitSpec\": { \"type\": \"default\", \"limit\": 5000, \"columns\": [\"country\", \"data_transfer\"] },\n" + + " \"filter\": {\n" + + " \"type\": \"and\",\n" + + " \"fields\": [\n" + + " { \"type\": \"selector\", \"dimension\": \"carrier\", \"value\": \"AT&T\" },\n" + + " { \"type\": \"or\", \n" + + " \"fields\": [\n" + + " { \"type\": \"selector\", \"dimension\": \"make\", \"value\": \"Apple\" },\n" + + " { \"type\": \"selector\", \"dimension\": \"make\", \"value\": \"Samsung\" }\n" + + " ]\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"aggregations\": [\n" + + " { \"type\": \"longSum\", \"name\": \"total_usage\", \"fieldName\": \"user_count\" },\n" + + " { \"type\": \"doubleSum\", \"name\": \"data_transfer\", \"fieldName\": \"data_transfer\" }\n" + + " ],\n" + + "\"having\": {\n" + + " \"type\": \"greaterThan\",\n" + + " \"aggregation\": \"total_usage\",\n" + + " \"value\": 2\n" + + " }," + + " \"postAggregations\": [\n" + + " { \"type\": \"arithmetic\",\n" + + " \"name\": \"avg_usage\",\n" + + " \"fn\": \"/\",\n" + + " \"fields\": [\n" + + " { \"type\": \"fieldAccess\", \"fieldName\": \"data_transfer\" },\n" + + " { \"type\": \"fieldAccess\", \"fieldName\": \"total_usage\" }\n" + + " ]\n" + + " }\n" + + " ],\n" + + " \"intervals\": [ \"2012-01-01T00:00:00.000Z/2012-01-03T00:00:00.000Z\" ]\n" + + "}\n"; // Druid dimensions DruidDimension druidDimension1 = new SimpleDimension("country"); @@ -119,8 +119,8 @@ public void testSampleQuery() throws JsonProcessingException, JSONException { // Limit Spec List orderByColumnSpecs - = Arrays.asList(new OrderByColumnSpecString("country"), - new OrderByColumnSpecString("data_transfer")); + = Arrays.asList(new OrderByColumnSpecString("country"), + new OrderByColumnSpecString("data_transfer")); DefaultLimitSpec limitSpec = new DefaultLimitSpec(5000, orderByColumnSpecs); // Filters @@ -132,17 +132,8 @@ public void testSampleQuery() throws JsonProcessingException, JSONException { DruidFilter filter = new AndFilter(Arrays.asList(carrierFilter, makeFilter)); // Aggregations - DruidAggregator usageAggregator = - LongSumAggregator.builder() - .name("total_usage") - .fieldName("user_count") - .build(); - - DruidAggregator transferAggregator = - DoubleSumAggregator.builder() - .name("data_transfer") - .fieldName("data_transfer") - .build(); + DruidAggregator usageAggregator = new LongSumAggregator("total_usage", "user_count"); + DruidAggregator transferAggregator = new DoubleSumAggregator("data_transfer", "data_transfer"); // Having HavingSpec countHaving = new GreaterThanHaving("total_usage", 2); @@ -152,10 +143,10 @@ public void testSampleQuery() throws JsonProcessingException, JSONException { DruidPostAggregator usagePostAggregator = new FieldAccessPostAggregator("data_transfer"); DruidPostAggregator postAggregator = ArithmeticPostAggregator.builder() - .name("avg_usage") - .function(ArithmeticFunction.DIVIDE) - .fields(Arrays.asList(transferPostAggregator, usagePostAggregator)) - .build(); + .name("avg_usage") + .function(ArithmeticFunction.DIVIDE) + .fields(Arrays.asList(transferPostAggregator, usagePostAggregator)) + .build(); // Interval DateTime startTime = new DateTime(2012, 1, 1, 0, 0, 0, DateTimeZone.UTC); @@ -163,16 +154,16 @@ public void testSampleQuery() throws JsonProcessingException, JSONException { Interval interval = new Interval(startTime, endTime); DruidGroupByQuery query = DruidGroupByQuery.builder() - .dataSource(new TableDataSource("sample_datasource")) - .granularity(new SimpleGranularity(PredefinedGranularity.DAY)) - .dimensions(Arrays.asList(druidDimension1, druidDimension2)) - .limitSpec(limitSpec) - .filter(filter) - .having(countHaving) - .aggregators(Arrays.asList(usageAggregator, transferAggregator)) - .postAggregators(Collections.singletonList(postAggregator)) - .intervals(Collections.singletonList(interval)) - .build(); + .dataSource(new TableDataSource("sample_datasource")) + .granularity(new SimpleGranularity(PredefinedGranularity.DAY)) + .dimensions(Arrays.asList(druidDimension1, druidDimension2)) + .limitSpec(limitSpec) + .filter(filter) + .having(countHaving) + .aggregators(Arrays.asList(usageAggregator, transferAggregator)) + .postAggregators(Collections.singletonList(postAggregator)) + .intervals(Collections.singletonList(interval)) + .build(); String actualJson = objectMapper.writeValueAsString(query); JSONAssert.assertEquals(actualJson, expectedJsonAsString, JSONCompareMode.NON_EXTENSIBLE); @@ -190,11 +181,11 @@ public void testRequiredFields() throws JSONException, JsonProcessingException { Interval interval = new Interval(startTime, endTime); DruidGroupByQuery druidGroupByQuery = DruidGroupByQuery.builder() - .dataSource(new TableDataSource("sample_datasource")) - .dimensions(Arrays.asList(druidDimension1, druidDimension2)) - .granularity(granularity) - .intervals(Collections.singletonList(interval)) - .build(); + .dataSource(new TableDataSource("sample_datasource")) + .dimensions(Arrays.asList(druidDimension1, druidDimension2)) + .granularity(granularity) + .intervals(Collections.singletonList(interval)) + .build(); String actualJson = objectMapper.writeValueAsString(druidGroupByQuery); @@ -230,19 +221,19 @@ public void testAllFields() throws JSONException, JsonProcessingException { DruidAggregator aggregator = new CountAggregator("Chill"); DruidPostAggregator postAggregator = new ConstantPostAggregator("Keep", 16.11); Context context = Context.builder() - .populateCache(true) - .build(); + .populateCache(true) + .build(); DruidGroupByQuery druidGroupByQuery = DruidGroupByQuery.builder() - .dataSource(new TableDataSource("sample_datasource")) - .dimensions(Arrays.asList(druidDimension1, druidDimension2)) - .granularity(granularity) - .filter(filter) - .aggregators(Collections.singletonList(aggregator)) - .postAggregators(Collections.singletonList(postAggregator)) - .intervals(Collections.singletonList(interval)) - .context(context) - .build(); + .dataSource(new TableDataSource("sample_datasource")) + .dimensions(Arrays.asList(druidDimension1, druidDimension2)) + .granularity(granularity) + .filter(filter) + .aggregators(Collections.singletonList(aggregator)) + .postAggregators(Collections.singletonList(postAggregator)) + .intervals(Collections.singletonList(interval)) + .context(context) + .build(); String actualJson = objectMapper.writeValueAsString(druidGroupByQuery); @@ -264,7 +255,7 @@ public void testAllFields() throws JSONException, JsonProcessingException { expectedContext.put("populateCache", true); JSONArray intervalArray = new JSONArray(Collections.singletonList("2012-01-01T00:00:00.000Z/" + - "2012-01-03T00:00:00.000Z")); + "2012-01-03T00:00:00.000Z")); JSONArray dimensionArray = new JSONArray(Arrays.asList("dim1", "dim2")); JSONObject dataSource = new JSONObject(); diff --git a/src/test/java/in/zapr/druid/druidry/query/aggregation/TimeSeriesTest.java b/src/test/java/in/zapr/druid/druidry/query/aggregation/TimeSeriesTest.java index 668d5452..d97f6c16 100644 --- a/src/test/java/in/zapr/druid/druidry/query/aggregation/TimeSeriesTest.java +++ b/src/test/java/in/zapr/druid/druidry/query/aggregation/TimeSeriesTest.java @@ -33,6 +33,8 @@ import java.util.Arrays; import java.util.Collections; +import in.zapr.druid.druidry.query.config.Context; +import in.zapr.druid.druidry.query.config.Interval; import in.zapr.druid.druidry.aggregator.CountAggregator; import in.zapr.druid.druidry.aggregator.DoubleSumAggregator; import in.zapr.druid.druidry.aggregator.DruidAggregator; @@ -50,8 +52,6 @@ import in.zapr.druid.druidry.postAggregator.ConstantPostAggregator; import in.zapr.druid.druidry.postAggregator.DruidPostAggregator; import in.zapr.druid.druidry.postAggregator.FieldAccessPostAggregator; -import in.zapr.druid.druidry.query.config.Context; -import in.zapr.druid.druidry.query.config.Interval; public class TimeSeriesTest { private static ObjectMapper objectMapper; @@ -61,49 +61,42 @@ public void init() { objectMapper = new ObjectMapper(); objectMapper.registerModule(new JodaModule()); objectMapper.configure(com.fasterxml.jackson.databind.SerializationFeature. - WRITE_DATES_AS_TIMESTAMPS, false); + WRITE_DATES_AS_TIMESTAMPS, false); } @Test public void testSampleQuery() throws JsonProcessingException, JSONException { SelectorFilter selectorFilter2 = new SelectorFilter("sample_dimension2", - "sample_value2"); + "sample_value2"); SelectorFilter selectorFilter3 = new SelectorFilter("sample_dimension3", - "sample_value3"); + "sample_value3"); OrFilter orfilter = new OrFilter(Arrays.asList(selectorFilter2, selectorFilter3)); SelectorFilter selectorFilter1 = new SelectorFilter("sample_dimension1", - "sample_value1"); + "sample_value1"); AndFilter andFilter = new AndFilter(Arrays.asList(selectorFilter1, orfilter)); - DruidAggregator aggregator1 = - LongSumAggregator.builder() - .name("sample_name1") - .fieldName("sample_fieldName1") - .build(); - - DruidAggregator aggregator2 = - DoubleSumAggregator.builder() - .name("sample_name2") - .fieldName("sample_fieldName2") - .build(); + DruidAggregator aggregator1 = new LongSumAggregator("sample_name1", + "sample_fieldName1"); + DruidAggregator aggregator2 = new DoubleSumAggregator("sample_name2", + "sample_fieldName2"); FieldAccessPostAggregator fieldAccessPostAggregator1 - = new FieldAccessPostAggregator("postAgg__sample_name1", - "sample_name1"); + = new FieldAccessPostAggregator("postAgg__sample_name1", + "sample_name1"); FieldAccessPostAggregator fieldAccessPostAggregator2 - = new FieldAccessPostAggregator("postAgg__sample_name2", - "sample_name2"); + = new FieldAccessPostAggregator("postAgg__sample_name2", + "sample_name2"); DruidPostAggregator postAggregator = ArithmeticPostAggregator.builder() - .name("sample_divide") - .function(ArithmeticFunction.DIVIDE) - .fields(Arrays.asList(fieldAccessPostAggregator1, fieldAccessPostAggregator2)) - .build(); + .name("sample_divide") + .function(ArithmeticFunction.DIVIDE) + .fields(Arrays.asList(fieldAccessPostAggregator1, fieldAccessPostAggregator2)) + .build(); //2013-08-31T00:00:00.000/2013-09-03T00:00:00.000" DateTime startTime = new DateTime(2012, 1, 1, 0, 0, 0, DateTimeZone.UTC); @@ -113,51 +106,51 @@ public void testSampleQuery() throws JsonProcessingException, JSONException { Granularity granularity = new SimpleGranularity(PredefinedGranularity.DAY); DruidTimeSeriesQuery query = DruidTimeSeriesQuery.builder() - .dataSource(new TableDataSource("sample_datasource")) - .granularity(granularity) - .descending(true) - .filter(andFilter) - .aggregators(Arrays.asList(aggregator1, aggregator2)) - .postAggregators(Collections.singletonList(postAggregator)) - .intervals(Collections.singletonList(interval)) - .build(); + .dataSource(new TableDataSource("sample_datasource")) + .granularity(granularity) + .descending(true) + .filter(andFilter) + .aggregators(Arrays.asList(aggregator1, aggregator2)) + .postAggregators(Collections.singletonList(postAggregator)) + .intervals(Collections.singletonList(interval)) + .build(); String expectedJsonAsString = "{\n" + - " \"queryType\": \"timeseries\",\n" + - " \"dataSource\": {\n" + - " \"type\": \"table\",\n" + - " \"name\": \"sample_datasource\"\n" + - " },\n" + - " \"granularity\": \"day\",\n" + - " \"descending\": true,\n" + - " \"filter\": {\n" + - " \"type\": \"and\",\n" + - " \"fields\": [\n" + - " { \"type\": \"selector\", \"dimension\": \"sample_dimension1\", \"value\": \"sample_value1\" },\n" + - " { \"type\": \"or\",\n" + - " \"fields\": [\n" + - " { \"type\": \"selector\", \"dimension\": \"sample_dimension2\", \"value\": \"sample_value2\" },\n" + - " { \"type\": \"selector\", \"dimension\": \"sample_dimension3\", \"value\": \"sample_value3\" }\n" + - " ]\n" + - " }\n" + - " ]\n" + - " },\n" + - " \"aggregations\": [\n" + - " { \"type\": \"longSum\", \"name\": \"sample_name1\", \"fieldName\": \"sample_fieldName1\" },\n" + - " { \"type\": \"doubleSum\", \"name\": \"sample_name2\", \"fieldName\": \"sample_fieldName2\" }\n" + - " ],\n" + - " \"postAggregations\": [\n" + - " { \"type\": \"arithmetic\",\n" + - " \"name\": \"sample_divide\",\n" + - " \"fn\": \"/\",\n" + - " \"fields\": [\n" + - " { \"type\": \"fieldAccess\", \"name\": \"postAgg__sample_name1\", \"fieldName\": \"sample_name1\" },\n" + - " { \"type\": \"fieldAccess\", \"name\": \"postAgg__sample_name2\", \"fieldName\": \"sample_name2\" }\n" + - " ]\n" + - " }\n" + - " ],\n" + - " \"intervals\": [ \"2012-01-01T00:00:00.000Z/2012-01-03T00:00:00.000Z\" ]\n" + - "}"; + " \"queryType\": \"timeseries\",\n" + + " \"dataSource\": {\n" + + " \"type\": \"table\",\n" + + " \"name\": \"sample_datasource\"\n" + + " },\n" + + " \"granularity\": \"day\",\n" + + " \"descending\": true,\n" + + " \"filter\": {\n" + + " \"type\": \"and\",\n" + + " \"fields\": [\n" + + " { \"type\": \"selector\", \"dimension\": \"sample_dimension1\", \"value\": \"sample_value1\" },\n" + + " { \"type\": \"or\",\n" + + " \"fields\": [\n" + + " { \"type\": \"selector\", \"dimension\": \"sample_dimension2\", \"value\": \"sample_value2\" },\n" + + " { \"type\": \"selector\", \"dimension\": \"sample_dimension3\", \"value\": \"sample_value3\" }\n" + + " ]\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"aggregations\": [\n" + + " { \"type\": \"longSum\", \"name\": \"sample_name1\", \"fieldName\": \"sample_fieldName1\" },\n" + + " { \"type\": \"doubleSum\", \"name\": \"sample_name2\", \"fieldName\": \"sample_fieldName2\" }\n" + + " ],\n" + + " \"postAggregations\": [\n" + + " { \"type\": \"arithmetic\",\n" + + " \"name\": \"sample_divide\",\n" + + " \"fn\": \"/\",\n" + + " \"fields\": [\n" + + " { \"type\": \"fieldAccess\", \"name\": \"postAgg__sample_name1\", \"fieldName\": \"sample_name1\" },\n" + + " { \"type\": \"fieldAccess\", \"name\": \"postAgg__sample_name2\", \"fieldName\": \"sample_name2\" }\n" + + " ]\n" + + " }\n" + + " ],\n" + + " \"intervals\": [ \"2012-01-01T00:00:00.000Z/2012-01-03T00:00:00.000Z\" ]\n" + + "}"; String actualJson = objectMapper.writeValueAsString(query); JSONAssert.assertEquals(actualJson, expectedJsonAsString, JSONCompareMode.NON_EXTENSIBLE); @@ -172,10 +165,10 @@ public void testRequiredFields() throws JsonProcessingException, JSONException { Granularity granularity = new SimpleGranularity(PredefinedGranularity.DAY); DruidTimeSeriesQuery seriesQuery = DruidTimeSeriesQuery.builder() - .dataSource(new TableDataSource("Matrix")) - .intervals(Collections.singletonList(interval)) - .granularity(granularity) - .build(); + .dataSource(new TableDataSource("Matrix")) + .intervals(Collections.singletonList(interval)) + .granularity(granularity) + .build(); JSONObject dataSource = new JSONObject(); dataSource.put("type", "table"); @@ -185,7 +178,7 @@ public void testRequiredFields() throws JsonProcessingException, JSONException { expectedQuery.put("queryType", "timeseries"); expectedQuery.put("dataSource", dataSource); expectedQuery.put("intervals", new JSONArray(Collections - .singletonList("2013-07-14T00:00:00.000Z/2013-11-16T00:00:00.000Z"))); + .singletonList("2013-07-14T00:00:00.000Z/2013-11-16T00:00:00.000Z"))); expectedQuery.put("granularity", "day"); String actualJson = objectMapper.writeValueAsString(seriesQuery); @@ -201,23 +194,23 @@ public void testAllFields() throws JSONException, JsonProcessingException { Granularity granularity = new SimpleGranularity(PredefinedGranularity.DAY); Context context = Context.builder() - .useCache(true) - .build(); + .useCache(true) + .build(); DruidFilter filter = new SelectorFilter("Spread", "Peace"); DruidAggregator aggregator = new CountAggregator("Chill"); DruidPostAggregator postAggregator = new ConstantPostAggregator("Keep", 10.47); DruidTimeSeriesQuery seriesQuery = DruidTimeSeriesQuery.builder() - .dataSource(new TableDataSource("Matrix")) - .descending(true) - .intervals(Collections.singletonList(interval)) - .granularity(granularity) - .filter(filter) - .aggregators(Collections.singletonList(aggregator)) - .postAggregators(Collections.singletonList(postAggregator)) - .context(context) - .build(); + .dataSource(new TableDataSource("Matrix")) + .descending(true) + .intervals(Collections.singletonList(interval)) + .granularity(granularity) + .filter(filter) + .aggregators(Collections.singletonList(aggregator)) + .postAggregators(Collections.singletonList(postAggregator)) + .context(context) + .build(); JSONObject expectedFilter = new JSONObject(); expectedFilter.put("type", "selector"); @@ -244,7 +237,7 @@ public void testAllFields() throws JSONException, JsonProcessingException { expectedQuery.put("queryType", "timeseries"); expectedQuery.put("dataSource", dataSource); expectedQuery.put("intervals", new JSONArray(Collections - .singletonList("2013-07-14T00:00:00.000Z/2013-11-16T00:00:00.000Z"))); + .singletonList("2013-07-14T00:00:00.000Z/2013-11-16T00:00:00.000Z"))); expectedQuery.put("granularity", "day"); expectedQuery.put("aggregations", new JSONArray(Collections.singletonList(expectedAggregator))); expectedQuery.put("postAggregations", new JSONArray(Collections.singletonList(expectedPostAggregator))); diff --git a/src/test/java/in/zapr/druid/druidry/query/aggregation/TopNQueryTest.java b/src/test/java/in/zapr/druid/druidry/query/aggregation/TopNQueryTest.java index 2002ee10..d8f0a441 100644 --- a/src/test/java/in/zapr/druid/druidry/query/aggregation/TopNQueryTest.java +++ b/src/test/java/in/zapr/druid/druidry/query/aggregation/TopNQueryTest.java @@ -33,6 +33,8 @@ import java.util.Arrays; import java.util.Collections; +import in.zapr.druid.druidry.query.config.Context; +import in.zapr.druid.druidry.query.config.Interval; import in.zapr.druid.druidry.aggregator.CountAggregator; import in.zapr.druid.druidry.aggregator.DoubleSumAggregator; import in.zapr.druid.druidry.aggregator.DruidAggregator; @@ -51,8 +53,6 @@ import in.zapr.druid.druidry.postAggregator.ConstantPostAggregator; import in.zapr.druid.druidry.postAggregator.DruidPostAggregator; import in.zapr.druid.druidry.postAggregator.FieldAccessPostAggregator; -import in.zapr.druid.druidry.query.config.Context; -import in.zapr.druid.druidry.query.config.Interval; import in.zapr.druid.druidry.topNMetric.SimpleMetric; import in.zapr.druid.druidry.topNMetric.TopNMetric; @@ -72,29 +72,20 @@ public void testSampleQuery() throws JsonProcessingException, JSONException { AndFilter filter = new AndFilter(Arrays.asList(selectorFilter1, selectorFilter2)); - DruidAggregator aggregator1 = - LongSumAggregator.builder() - .name("count") - .fieldName("count") - .build(); - - DruidAggregator aggregator2 = - DoubleSumAggregator.builder() - .name("some_metric") - .fieldName("some_metric") - .build(); + DruidAggregator aggregator1 = new LongSumAggregator("count", "count"); + DruidAggregator aggregator2 = new DoubleSumAggregator("some_metric", "some_metric"); FieldAccessPostAggregator fieldAccessPostAggregator1 - = new FieldAccessPostAggregator("some_metric", "some_metric"); + = new FieldAccessPostAggregator("some_metric", "some_metric"); FieldAccessPostAggregator fieldAccessPostAggregator2 - = new FieldAccessPostAggregator("count", "count"); + = new FieldAccessPostAggregator("count", "count"); DruidPostAggregator postAggregator = ArithmeticPostAggregator.builder() - .name("sample_divide") - .function(ArithmeticFunction.DIVIDE) - .fields(Arrays.asList(fieldAccessPostAggregator1, fieldAccessPostAggregator2)) - .build(); + .name("sample_divide") + .function(ArithmeticFunction.DIVIDE) + .fields(Arrays.asList(fieldAccessPostAggregator1, fieldAccessPostAggregator2)) + .build(); DateTime startTime = new DateTime(2013, 8, 31, 0, 0, 0, DateTimeZone.UTC); DateTime endTime = new DateTime(2013, 9, 3, 0, 0, 0, DateTimeZone.UTC); @@ -106,77 +97,77 @@ public void testSampleQuery() throws JsonProcessingException, JSONException { TopNMetric metric = new SimpleMetric("count"); DruidTopNQuery query = DruidTopNQuery.builder() - .dataSource(new TableDataSource("sample_data")) - .dimension(dimension) - .threshold(5) - .topNMetric(metric) - .granularity(granularity) - .filter(filter) - .aggregators(Arrays.asList(aggregator1, aggregator2)) - .postAggregators(Collections.singletonList(postAggregator)) - .intervals(Collections.singletonList(interval)) - .build(); + .dataSource(new TableDataSource("sample_data")) + .dimension(dimension) + .threshold(5) + .topNMetric(metric) + .granularity(granularity) + .filter(filter) + .aggregators(Arrays.asList(aggregator1, aggregator2)) + .postAggregators(Collections.singletonList(postAggregator)) + .intervals(Collections.singletonList(interval)) + .build(); String expectedJsonAsString = "{\n" + - " \"queryType\": \"topN\",\n" + - " \"dataSource\": {\n" + - " \"type\": \"table\",\n" + - " \"name\": \"sample_data\"\n" + - " },\n" + - " \"dimension\": \"sample_dim\",\n" + - " \"threshold\": 5,\n" + - " \"metric\": \"count\",\n" + - " \"granularity\": \"all\",\n" + - " \"filter\": {\n" + - " \"type\": \"and\",\n" + - " \"fields\": [\n" + - " {\n" + - " \"type\": \"selector\",\n" + - " \"dimension\": \"dim1\",\n" + - " \"value\": \"some_value\"\n" + - " },\n" + - " {\n" + - " \"type\": \"selector\",\n" + - " \"dimension\": \"dim2\",\n" + - " \"value\": \"some_other_val\"\n" + - " }\n" + - " ]\n" + - " },\n" + - " \"aggregations\": [\n" + - " {\n" + - " \"type\": \"longSum\",\n" + - " \"name\": \"count\",\n" + - " \"fieldName\": \"count\"\n" + - " },\n" + - " {\n" + - " \"type\": \"doubleSum\",\n" + - " \"name\": \"some_metric\",\n" + - " \"fieldName\": \"some_metric\"\n" + - " }\n" + - " ],\n" + - " \"postAggregations\": [\n" + - " {\n" + - " \"type\": \"arithmetic\",\n" + - " \"name\": \"sample_divide\",\n" + - " \"fn\": \"/\",\n" + - " \"fields\": [\n" + - " {\n" + - " \"type\": \"fieldAccess\",\n" + - " \"name\": \"some_metric\",\n" + - " \"fieldName\": \"some_metric\"\n" + - " },\n" + - " {\n" + - " \"type\": \"fieldAccess\",\n" + - " \"name\": \"count\",\n" + - " \"fieldName\": \"count\"\n" + - " }\n" + - " ]\n" + - " }\n" + - " ],\n" + - " \"intervals\": [\n" + - " \"2013-08-31T00:00:00.000Z/2013-09-03T00:00:00.000Z\"\n" + - " ]\n" + - "}"; + " \"queryType\": \"topN\",\n" + + " \"dataSource\": {\n" + + " \"type\": \"table\",\n" + + " \"name\": \"sample_data\"\n" + + " },\n" + + " \"dimension\": \"sample_dim\",\n" + + " \"threshold\": 5,\n" + + " \"metric\": \"count\",\n" + + " \"granularity\": \"all\",\n" + + " \"filter\": {\n" + + " \"type\": \"and\",\n" + + " \"fields\": [\n" + + " {\n" + + " \"type\": \"selector\",\n" + + " \"dimension\": \"dim1\",\n" + + " \"value\": \"some_value\"\n" + + " },\n" + + " {\n" + + " \"type\": \"selector\",\n" + + " \"dimension\": \"dim2\",\n" + + " \"value\": \"some_other_val\"\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"aggregations\": [\n" + + " {\n" + + " \"type\": \"longSum\",\n" + + " \"name\": \"count\",\n" + + " \"fieldName\": \"count\"\n" + + " },\n" + + " {\n" + + " \"type\": \"doubleSum\",\n" + + " \"name\": \"some_metric\",\n" + + " \"fieldName\": \"some_metric\"\n" + + " }\n" + + " ],\n" + + " \"postAggregations\": [\n" + + " {\n" + + " \"type\": \"arithmetic\",\n" + + " \"name\": \"sample_divide\",\n" + + " \"fn\": \"/\",\n" + + " \"fields\": [\n" + + " {\n" + + " \"type\": \"fieldAccess\",\n" + + " \"name\": \"some_metric\",\n" + + " \"fieldName\": \"some_metric\"\n" + + " },\n" + + " {\n" + + " \"type\": \"fieldAccess\",\n" + + " \"name\": \"count\",\n" + + " \"fieldName\": \"count\"\n" + + " }\n" + + " ]\n" + + " }\n" + + " ],\n" + + " \"intervals\": [\n" + + " \"2013-08-31T00:00:00.000Z/2013-09-03T00:00:00.000Z\"\n" + + " ]\n" + + "}"; String actualJson = objectMapper.writeValueAsString(query); JSONAssert.assertEquals(expectedJsonAsString, actualJson, JSONCompareMode.NON_EXTENSIBLE); @@ -195,13 +186,13 @@ public void testRequiredFields() throws JsonProcessingException, JSONException { Granularity granularity = new SimpleGranularity(PredefinedGranularity.DAY); DruidTopNQuery query = DruidTopNQuery.builder() - .dataSource(new TableDataSource("sample_data")) - .intervals(Collections.singletonList(interval)) - .granularity(granularity) - .dimension(dimension) - .threshold(7) - .topNMetric(metric) - .build(); + .dataSource(new TableDataSource("sample_data")) + .intervals(Collections.singletonList(interval)) + .granularity(granularity) + .dimension(dimension) + .threshold(7) + .topNMetric(metric) + .build(); String actualJson = objectMapper.writeValueAsString(query); @@ -238,21 +229,21 @@ public void testAllFields() throws JSONException, JsonProcessingException { DruidAggregator aggregator = new CountAggregator("Chill"); DruidPostAggregator postAggregator = new ConstantPostAggregator("Keep", 16.11); Context context = Context.builder() - .populateCache(true) - .build(); + .populateCache(true) + .build(); DruidTopNQuery query = DruidTopNQuery.builder() - .dataSource(new TableDataSource("sample_data")) - .intervals(Collections.singletonList(interval)) - .granularity(granularity) - .filter(filter) - .aggregators(Collections.singletonList(aggregator)) - .postAggregators(Collections.singletonList(postAggregator)) - .dimension(dimension) - .threshold(7) - .topNMetric(metric) - .context(context) - .build(); + .dataSource(new TableDataSource("sample_data")) + .intervals(Collections.singletonList(interval)) + .granularity(granularity) + .filter(filter) + .aggregators(Collections.singletonList(aggregator)) + .postAggregators(Collections.singletonList(postAggregator)) + .dimension(dimension) + .threshold(7) + .topNMetric(metric) + .context(context) + .build(); String actualJson = objectMapper.writeValueAsString(query); @@ -310,34 +301,34 @@ public void testEquals() { DruidAggregator aggregator = new CountAggregator("Chill"); DruidPostAggregator postAggregator = new ConstantPostAggregator("Keep", 16.11); Context context = Context.builder() - .populateCache(true) - .build(); + .populateCache(true) + .build(); DruidTopNQuery query1 = DruidTopNQuery.builder() - .dataSource(new TableDataSource("sample_data")) - .intervals(Collections.singletonList(interval)) - .granularity(granularity) - .filter(filter) - .aggregators(Collections.singletonList(aggregator)) - .postAggregators(Collections.singletonList(postAggregator)) - .dimension(dimension) - .threshold(7) - .topNMetric(metric) - .context(context) - .build(); + .dataSource(new TableDataSource("sample_data")) + .intervals(Collections.singletonList(interval)) + .granularity(granularity) + .filter(filter) + .aggregators(Collections.singletonList(aggregator)) + .postAggregators(Collections.singletonList(postAggregator)) + .dimension(dimension) + .threshold(7) + .topNMetric(metric) + .context(context) + .build(); DruidTopNQuery query2 = DruidTopNQuery.builder() - .dataSource(new TableDataSource("sample_data")) - .intervals(Collections.singletonList(interval)) - .granularity(granularity) - .filter(filter) - .aggregators(Collections.singletonList(aggregator)) - .postAggregators(Collections.singletonList(postAggregator)) - .dimension(dimension) - .threshold(7) - .topNMetric(metric) - .context(context) - .build(); + .dataSource(new TableDataSource("sample_data")) + .intervals(Collections.singletonList(interval)) + .granularity(granularity) + .filter(filter) + .aggregators(Collections.singletonList(aggregator)) + .postAggregators(Collections.singletonList(postAggregator)) + .dimension(dimension) + .threshold(7) + .topNMetric(metric) + .context(context) + .build(); Assert.assertEquals(query1, query2); } @@ -357,34 +348,34 @@ public void testUnequals() { DruidAggregator aggregator = new CountAggregator("Chill"); DruidPostAggregator postAggregator = new ConstantPostAggregator("Keep", 16.11); Context context = Context.builder() - .populateCache(true) - .build(); + .populateCache(true) + .build(); DruidTopNQuery query1 = DruidTopNQuery.builder() - .dataSource(new TableDataSource("sample_data")) - .intervals(Collections.singletonList(interval)) - .granularity(granularity) - .filter(filter) - .aggregators(Collections.singletonList(aggregator)) - .postAggregators(Collections.singletonList(postAggregator)) - .dimension(dimension) - .threshold(7) - .topNMetric(metric) - .context(context) - .build(); + .dataSource(new TableDataSource("sample_data")) + .intervals(Collections.singletonList(interval)) + .granularity(granularity) + .filter(filter) + .aggregators(Collections.singletonList(aggregator)) + .postAggregators(Collections.singletonList(postAggregator)) + .dimension(dimension) + .threshold(7) + .topNMetric(metric) + .context(context) + .build(); DruidTopNQuery query2 = DruidTopNQuery.builder() - .dataSource(new TableDataSource("sample_data")) - .intervals(Collections.singletonList(interval)) - .granularity(granularity) - .filter(filter) - .aggregators(Collections.singletonList(aggregator)) - .postAggregators(Collections.singletonList(postAggregator)) - .dimension(dimension) - .threshold(314) - .topNMetric(metric) - .context(context) - .build(); + .dataSource(new TableDataSource("sample_data")) + .intervals(Collections.singletonList(interval)) + .granularity(granularity) + .filter(filter) + .aggregators(Collections.singletonList(aggregator)) + .postAggregators(Collections.singletonList(postAggregator)) + .dimension(dimension) + .threshold(314) + .topNMetric(metric) + .context(context) + .build(); Assert.assertNotEquals(query1, query2); } @@ -404,20 +395,20 @@ public void preconditionCheck() { DruidAggregator aggregator = new CountAggregator("Chill"); DruidPostAggregator postAggregator = new ConstantPostAggregator("Keep", 16.11); Context context = Context.builder() - .populateCache(true) - .build(); + .populateCache(true) + .build(); DruidTopNQuery query1 = DruidTopNQuery.builder() - .dataSource(new TableDataSource("sample_data")) - .intervals(Collections.singletonList(interval)) - .granularity(granularity) - .filter(filter) - .aggregators(Collections.singletonList(aggregator)) - .postAggregators(Collections.singletonList(postAggregator)) - .dimension(dimension) - .threshold(-5) - .topNMetric(metric) - .context(context) - .build(); + .dataSource(new TableDataSource("sample_data")) + .intervals(Collections.singletonList(interval)) + .granularity(granularity) + .filter(filter) + .aggregators(Collections.singletonList(aggregator)) + .postAggregators(Collections.singletonList(postAggregator)) + .dimension(dimension) + .threshold(-5) + .topNMetric(metric) + .context(context) + .build(); } } From 94fd41f83757ba6ace77ad9f6d000a178eadd3dc Mon Sep 17 00:00:00 2001 From: Abhi Sapariya Date: Sun, 29 Mar 2020 19:51:33 +0530 Subject: [PATCH 19/25] numeric & dimension topNmetric spec implementation and refactoring --- .../druidry/topNMetric/DimensionMetric.java | 44 ++++++++ .../druidry/topNMetric/InvertedMetric.java | 6 +- .../druidry/topNMetric/NumericMetric.java | 37 +++++++ .../topNMetric/DimensionMetricTest.java | 101 ++++++++++++++++++ .../topNMetric/InvertedMetricTest.java | 22 +++- .../druidry/topNMetric/NumericMetricTest.java | 82 ++++++++++++++ 6 files changed, 287 insertions(+), 5 deletions(-) create mode 100644 src/main/java/in/zapr/druid/druidry/topNMetric/DimensionMetric.java create mode 100644 src/main/java/in/zapr/druid/druidry/topNMetric/NumericMetric.java create mode 100644 src/test/java/in/zapr/druid/druidry/topNMetric/DimensionMetricTest.java create mode 100644 src/test/java/in/zapr/druid/druidry/topNMetric/NumericMetricTest.java diff --git a/src/main/java/in/zapr/druid/druidry/topNMetric/DimensionMetric.java b/src/main/java/in/zapr/druid/druidry/topNMetric/DimensionMetric.java new file mode 100644 index 00000000..2404ef1a --- /dev/null +++ b/src/main/java/in/zapr/druid/druidry/topNMetric/DimensionMetric.java @@ -0,0 +1,44 @@ +/* + * Copyright 2018-present Red Brick Lane Marketing Solutions Pvt. Ltd. + * + * 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 in.zapr.druid.druidry.topNMetric; + +import com.fasterxml.jackson.annotation.JsonInclude; + +import in.zapr.druid.druidry.query.config.SortingOrder; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +@Getter +@EqualsAndHashCode(callSuper = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class DimensionMetric extends TopNMetric { + + private static final String DIMENSION_METRIC_TYPE = "dimension"; + + private String type; + private SortingOrder ordering; + private String previousStop; + + @Builder + private DimensionMetric(SortingOrder ordering, String previousStop) { + this.type = DIMENSION_METRIC_TYPE; + this.ordering = ordering; + this.previousStop = previousStop; + } + +} diff --git a/src/main/java/in/zapr/druid/druidry/topNMetric/InvertedMetric.java b/src/main/java/in/zapr/druid/druidry/topNMetric/InvertedMetric.java index 4edf3a9e..44f4e0e1 100644 --- a/src/main/java/in/zapr/druid/druidry/topNMetric/InvertedMetric.java +++ b/src/main/java/in/zapr/druid/druidry/topNMetric/InvertedMetric.java @@ -23,12 +23,14 @@ @Getter @EqualsAndHashCode(callSuper = true) public class InvertedMetric extends TopNMetric { - private static String INVERTED_METRIC_TYPE = "inverted"; + private static final String INVERTED_METRIC_TYPE = "inverted"; + + private String type; private TopNMetric metric; - private String type = INVERTED_METRIC_TYPE; public InvertedMetric(@NonNull TopNMetric topNMetric) { + this.type = INVERTED_METRIC_TYPE; this.metric = topNMetric; } } \ No newline at end of file diff --git a/src/main/java/in/zapr/druid/druidry/topNMetric/NumericMetric.java b/src/main/java/in/zapr/druid/druidry/topNMetric/NumericMetric.java new file mode 100644 index 00000000..5e8625ab --- /dev/null +++ b/src/main/java/in/zapr/druid/druidry/topNMetric/NumericMetric.java @@ -0,0 +1,37 @@ +/* + * Copyright 2018-present Red Brick Lane Marketing Solutions Pvt. Ltd. + * + * 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 in.zapr.druid.druidry.topNMetric; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NonNull; + +@Getter +@EqualsAndHashCode(callSuper = true) +public class NumericMetric extends TopNMetric { + + private static final String NUMERIC_METRIC_TYPE = "numeric"; + + private String type; + private TopNMetric metric; + + public NumericMetric(@NonNull TopNMetric topNMetric) { + this.type = NUMERIC_METRIC_TYPE; + this.metric = topNMetric; + } + +} diff --git a/src/test/java/in/zapr/druid/druidry/topNMetric/DimensionMetricTest.java b/src/test/java/in/zapr/druid/druidry/topNMetric/DimensionMetricTest.java new file mode 100644 index 00000000..71cb386b --- /dev/null +++ b/src/test/java/in/zapr/druid/druidry/topNMetric/DimensionMetricTest.java @@ -0,0 +1,101 @@ +/* + * Copyright 2018-present Red Brick Lane Marketing Solutions Pvt. Ltd. + * + * 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 in.zapr.druid.druidry.topNMetric; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.json.JSONException; +import org.json.JSONObject; +import org.skyscreamer.jsonassert.JSONAssert; +import org.skyscreamer.jsonassert.JSONCompareMode; +import org.testng.Assert; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import in.zapr.druid.druidry.query.config.SortingOrder; + +public class DimensionMetricTest { + + private static ObjectMapper objectMapper; + + @BeforeClass + public void init() { + objectMapper = new ObjectMapper(); + } + + private JSONObject getDimensionMetricJSON() throws JSONException { + + JSONObject jsonObject = new JSONObject(); + jsonObject.put("type", "dimension"); + return jsonObject; + } + + @Test + public void testAllFields() throws JsonProcessingException, JSONException { + + DimensionMetric dimensionMetric = DimensionMetric.builder() + .ordering(SortingOrder.LEXICOGRAPHIC) + .previousStop("x") + .build(); + + JSONObject jsonObject = getDimensionMetricJSON(); + jsonObject.put("ordering", "lexicographic"); + jsonObject.put("previousStop", "x"); + + String actualJSON = objectMapper.writeValueAsString(dimensionMetric); + String expectedJSON = jsonObject.toString(); + JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.NON_EXTENSIBLE); + } + + @Test + public void testRequiredFields() throws JsonProcessingException, JSONException { + + DimensionMetric dimensionMetric = DimensionMetric.builder() + .build(); + + JSONObject jsonObject = getDimensionMetricJSON(); + + String actualJSON = objectMapper.writeValueAsString(dimensionMetric); + String expectedJSON = jsonObject.toString(); + JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.NON_EXTENSIBLE); + } + + @Test + public void testEqualsPositive() { + DimensionMetric dimensionMetric1 = DimensionMetric.builder() + .ordering(SortingOrder.STRLEN) + .build(); + DimensionMetric dimensionMetric2 = DimensionMetric.builder() + .ordering(SortingOrder.STRLEN) + .build(); + + Assert.assertEquals(dimensionMetric1, dimensionMetric2); + } + + @Test + public void testEqualsNegative() { + DimensionMetric dimensionMetric1 = DimensionMetric.builder() + .ordering(SortingOrder.STRLEN) + .build(); + DimensionMetric dimensionMetric2 = DimensionMetric.builder() + .ordering(SortingOrder.ALPHANUMERIC) + .build(); + + Assert.assertNotEquals(dimensionMetric1, dimensionMetric2); + } +} \ No newline at end of file diff --git a/src/test/java/in/zapr/druid/druidry/topNMetric/InvertedMetricTest.java b/src/test/java/in/zapr/druid/druidry/topNMetric/InvertedMetricTest.java index c3d33900..93bf5a75 100644 --- a/src/test/java/in/zapr/druid/druidry/topNMetric/InvertedMetricTest.java +++ b/src/test/java/in/zapr/druid/druidry/topNMetric/InvertedMetricTest.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.json.JSONException; +import org.json.JSONObject; import org.skyscreamer.jsonassert.JSONAssert; import org.skyscreamer.jsonassert.JSONCompareMode; import org.testng.Assert; @@ -19,21 +20,35 @@ public void init() { objectMapper = new ObjectMapper(); } + private JSONObject getInvertedMetricJSON() throws JSONException { + + JSONObject jsonObject = new JSONObject(); + jsonObject.put("type", "inverted"); + jsonObject.put("metric", "count"); + return jsonObject; + } + @Test public void testAllFields() throws JsonProcessingException, JSONException { + InvertedMetric invertedMetric = new InvertedMetric(new SimpleMetric("count")); + + JSONObject jsonObject = getInvertedMetricJSON(); + String actualJSON = objectMapper.writeValueAsString(invertedMetric); - String expectedJson = "{\"metric\":\"count\",\"type\":\"inverted\"}"; - JSONAssert.assertEquals(expectedJson, actualJSON, JSONCompareMode.NON_EXTENSIBLE); + String expectedJSON = jsonObject.toString(); + JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.NON_EXTENSIBLE);; } @Test(expectedExceptions = NullPointerException.class) public void testMetricMissingFields() { - new InvertedMetric(null); + + InvertedMetric invertedMetric = new InvertedMetric(null); } @Test public void testEqualsPositive() { + InvertedMetric invertedMetric1 = new InvertedMetric(new SimpleMetric("count")); InvertedMetric invertedMetric2 = new InvertedMetric(new SimpleMetric("count")); @@ -42,6 +57,7 @@ public void testEqualsPositive() { @Test public void testEqualsNegative() { + InvertedMetric invertedMetric1 = new InvertedMetric(new SimpleMetric("sum")); InvertedMetric invertedMetric2 = new InvertedMetric(new SimpleMetric("count")); diff --git a/src/test/java/in/zapr/druid/druidry/topNMetric/NumericMetricTest.java b/src/test/java/in/zapr/druid/druidry/topNMetric/NumericMetricTest.java new file mode 100644 index 00000000..6c43c93e --- /dev/null +++ b/src/test/java/in/zapr/druid/druidry/topNMetric/NumericMetricTest.java @@ -0,0 +1,82 @@ +/* + * Copyright 2018-present Red Brick Lane Marketing Solutions Pvt. Ltd. + * + * 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 in.zapr.druid.druidry.topNMetric; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.json.JSONException; +import org.json.JSONObject; +import org.skyscreamer.jsonassert.JSONAssert; +import org.skyscreamer.jsonassert.JSONCompareMode; +import org.testng.Assert; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +public class NumericMetricTest { + + private static ObjectMapper objectMapper; + + @BeforeClass + public void init() { + objectMapper = new ObjectMapper(); + } + + private JSONObject getNumericMetricJSON() throws JSONException { + + JSONObject jsonObject = new JSONObject(); + jsonObject.put("type", "numeric"); + jsonObject.put("metric", "events"); + return jsonObject; + } + + @Test + public void testAllFields() throws JsonProcessingException, JSONException { + + NumericMetric numericMetric = new NumericMetric(new SimpleMetric("events")); + + JSONObject jsonObject = getNumericMetricJSON(); + + String actualJSON = objectMapper.writeValueAsString(numericMetric); + String expectedJSON = jsonObject.toString(); + JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.NON_EXTENSIBLE); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testNullField1() { + + NumericMetric numericMetric = new NumericMetric(null); + } + + @Test + public void testEqualsPositive() { + + NumericMetric numericMetric1 = new NumericMetric(new SimpleMetric("events")); + NumericMetric numericMetric2 = new NumericMetric(new SimpleMetric("events")); + + Assert.assertEquals(numericMetric1, numericMetric2); + } + + @Test + public void testEqualsNegative() { + + NumericMetric numericMetric1 = new NumericMetric(new SimpleMetric("events1")); + NumericMetric numericMetric2 = new NumericMetric(new SimpleMetric("events2")); + + Assert.assertNotEquals(numericMetric1, numericMetric2); + } +} \ No newline at end of file From 98f3a888ba6499b5ed544e3e893ae6411c87822b Mon Sep 17 00:00:00 2001 From: Abhi Sapariya Date: Sun, 29 Mar 2020 20:23:02 +0530 Subject: [PATCH 20/25] hyperUnique missing props(isInputHyperUnique & round) impl --- .../aggregator/HyperUniqueAggregator.java | 17 +++++ .../aggregator/HyperUniqueAggregatorTest.java | 76 +++++++++++++++---- 2 files changed, 80 insertions(+), 13 deletions(-) diff --git a/src/main/java/in/zapr/druid/druidry/aggregator/HyperUniqueAggregator.java b/src/main/java/in/zapr/druid/druidry/aggregator/HyperUniqueAggregator.java index e1bd4509..0eb902ec 100644 --- a/src/main/java/in/zapr/druid/druidry/aggregator/HyperUniqueAggregator.java +++ b/src/main/java/in/zapr/druid/druidry/aggregator/HyperUniqueAggregator.java @@ -16,20 +16,37 @@ package in.zapr.druid.druidry.aggregator; +import com.fasterxml.jackson.annotation.JsonInclude; + +import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; @Getter @EqualsAndHashCode(callSuper = true) +@JsonInclude(JsonInclude.Include.NON_NULL) public class HyperUniqueAggregator extends DruidAggregator { private static final String HYPER_UNIQUE_TYPE_AGGREGATOR = "hyperUnique"; private String fieldName; + private Boolean isInputHyperUnique; + private Boolean round; + @Deprecated public HyperUniqueAggregator(@NonNull String name, @NonNull String fieldName) { this.type = HYPER_UNIQUE_TYPE_AGGREGATOR; this.name = name; this.fieldName = fieldName; } + + @Builder + private HyperUniqueAggregator(@NonNull String name, @NonNull String fieldName, + Boolean isInputHyperUnique, Boolean round) { + this.type = HYPER_UNIQUE_TYPE_AGGREGATOR; + this.name = name; + this.fieldName = fieldName; + this.isInputHyperUnique = isInputHyperUnique; + this.round = round; + } } \ No newline at end of file diff --git a/src/test/java/in/zapr/druid/druidry/aggregator/HyperUniqueAggregatorTest.java b/src/test/java/in/zapr/druid/druidry/aggregator/HyperUniqueAggregatorTest.java index f590f901..71458912 100644 --- a/src/test/java/in/zapr/druid/druidry/aggregator/HyperUniqueAggregatorTest.java +++ b/src/test/java/in/zapr/druid/druidry/aggregator/HyperUniqueAggregatorTest.java @@ -39,53 +39,103 @@ public void init() { objectMapper = new ObjectMapper(); } - @Test - public void testAllFields() throws JsonProcessingException, JSONException { - - HyperUniqueAggregator hyperUniqueAggregator = new HyperUniqueAggregator("CarpeDiem", - "Hey"); - + private JSONObject getHyperUniqueAggregatorJSON() throws JSONException { JSONObject jsonObject = new JSONObject(); jsonObject.put("type", "hyperUnique"); jsonObject.put("name", "CarpeDiem"); jsonObject.put("fieldName", "Hey"); + return jsonObject; + } + + @Test + public void testAllFields() throws JsonProcessingException, JSONException { + + HyperUniqueAggregator hyperUniqueAggregator = HyperUniqueAggregator.builder() + .name("CarpeDiem") + .fieldName("Hey") + .isInputHyperUnique(true) + .round(true) + .build(); + + JSONObject jsonObject = getHyperUniqueAggregatorJSON(); + jsonObject.put("isInputHyperUnique" , true); + jsonObject.put("round", true); + + String actualJSON = objectMapper.writeValueAsString(hyperUniqueAggregator); + String expectedJSON = jsonObject.toString(); + JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.NON_EXTENSIBLE); + } + + @Test + public void testRequiredFields() throws JsonProcessingException, JSONException { + + HyperUniqueAggregator hyperUniqueAggregator = HyperUniqueAggregator.builder() + .name("CarpeDiem") + .fieldName("Hey") + .build(); + + JSONObject jsonObject = getHyperUniqueAggregatorJSON(); + String actualJSON = objectMapper.writeValueAsString(hyperUniqueAggregator); String expectedJSON = jsonObject.toString(); JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.NON_EXTENSIBLE); + } @Test(expectedExceptions = NullPointerException.class) public void testNullName() throws JsonProcessingException, JSONException { - HyperUniqueAggregator hyperUniqueAggregator = new HyperUniqueAggregator(null, "Haha"); + HyperUniqueAggregator hyperUniqueAggregator = HyperUniqueAggregator.builder() + .fieldName("Haha") + .build(); } @Test(expectedExceptions = NullPointerException.class) public void testNullFieldName() throws JsonProcessingException, JSONException { - HyperUniqueAggregator hyperUniqueAggregator = new HyperUniqueAggregator("Name", null); + HyperUniqueAggregator hyperUniqueAggregator = HyperUniqueAggregator.builder() + .name("Name") + .build(); } @Test public void testEqualsPositive() { - HyperUniqueAggregator aggregator1 = new HyperUniqueAggregator("name", "field"); - HyperUniqueAggregator aggregator2 = new HyperUniqueAggregator("name", "field"); + + HyperUniqueAggregator aggregator1 = HyperUniqueAggregator.builder() + .name("name") + .fieldName("field") + .build(); + HyperUniqueAggregator aggregator2 = HyperUniqueAggregator.builder() + .name("name") + .fieldName("field") + .build(); Assert.assertEquals(aggregator1, aggregator2); } @Test public void testEqualsNegative() { - HyperUniqueAggregator aggregator1 = new HyperUniqueAggregator("name", "field"); - HyperUniqueAggregator aggregator2 = new HyperUniqueAggregator("name1", "field1"); + + HyperUniqueAggregator aggregator1 = HyperUniqueAggregator.builder() + .name("name1") + .fieldName("field1") + .build(); + HyperUniqueAggregator aggregator2 = HyperUniqueAggregator.builder() + .name("name2") + .fieldName("field2") + .build(); Assert.assertNotEquals(aggregator1, aggregator2); } @Test public void testEqualsWithAnotherSubClass() { - HyperUniqueAggregator aggregator1 = new HyperUniqueAggregator("name", "field"); + + HyperUniqueAggregator aggregator1 = HyperUniqueAggregator.builder() + .name("name") + .fieldName("field") + .build(); CountAggregator aggregator2 = new CountAggregator("countAgg1"); Assert.assertNotEquals(aggregator1, aggregator2); From 3ef7805aadb8db2c5443a84d5738a2877aba9e4b Mon Sep 17 00:00:00 2001 From: Abhi Sapariya Date: Sun, 19 Apr 2020 17:00:24 +0530 Subject: [PATCH 21/25] remmoved isInputHyperUnique as its ingestion only config --- .../zapr/druid/druidry/aggregator/HyperUniqueAggregator.java | 5 +---- .../druid/druidry/aggregator/HyperUniqueAggregatorTest.java | 2 -- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/main/java/in/zapr/druid/druidry/aggregator/HyperUniqueAggregator.java b/src/main/java/in/zapr/druid/druidry/aggregator/HyperUniqueAggregator.java index 0eb902ec..2e3fc800 100644 --- a/src/main/java/in/zapr/druid/druidry/aggregator/HyperUniqueAggregator.java +++ b/src/main/java/in/zapr/druid/druidry/aggregator/HyperUniqueAggregator.java @@ -30,7 +30,6 @@ public class HyperUniqueAggregator extends DruidAggregator { private static final String HYPER_UNIQUE_TYPE_AGGREGATOR = "hyperUnique"; private String fieldName; - private Boolean isInputHyperUnique; private Boolean round; @Deprecated @@ -41,12 +40,10 @@ public HyperUniqueAggregator(@NonNull String name, @NonNull String fieldName) { } @Builder - private HyperUniqueAggregator(@NonNull String name, @NonNull String fieldName, - Boolean isInputHyperUnique, Boolean round) { + private HyperUniqueAggregator(@NonNull String name, @NonNull String fieldName, Boolean round) { this.type = HYPER_UNIQUE_TYPE_AGGREGATOR; this.name = name; this.fieldName = fieldName; - this.isInputHyperUnique = isInputHyperUnique; this.round = round; } } \ No newline at end of file diff --git a/src/test/java/in/zapr/druid/druidry/aggregator/HyperUniqueAggregatorTest.java b/src/test/java/in/zapr/druid/druidry/aggregator/HyperUniqueAggregatorTest.java index 71458912..bd8721ce 100644 --- a/src/test/java/in/zapr/druid/druidry/aggregator/HyperUniqueAggregatorTest.java +++ b/src/test/java/in/zapr/druid/druidry/aggregator/HyperUniqueAggregatorTest.java @@ -54,12 +54,10 @@ public void testAllFields() throws JsonProcessingException, JSONException { HyperUniqueAggregator hyperUniqueAggregator = HyperUniqueAggregator.builder() .name("CarpeDiem") .fieldName("Hey") - .isInputHyperUnique(true) .round(true) .build(); JSONObject jsonObject = getHyperUniqueAggregatorJSON(); - jsonObject.put("isInputHyperUnique" , true); jsonObject.put("round", true); String actualJSON = objectMapper.writeValueAsString(hyperUniqueAggregator); From 9805f4dc9859d2d9580241d3469a4ee9e4030df9 Mon Sep 17 00:00:00 2001 From: Abhi Sapariya Date: Sun, 19 Apr 2020 17:18:44 +0530 Subject: [PATCH 22/25] changing NumericMetric's metric datatype to string as per incubator-druid --- .../zapr/druid/druidry/topNMetric/NumericMetric.java | 6 +++--- .../druid/druidry/topNMetric/NumericMetricTest.java | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/in/zapr/druid/druidry/topNMetric/NumericMetric.java b/src/main/java/in/zapr/druid/druidry/topNMetric/NumericMetric.java index 5e8625ab..49bba3d9 100644 --- a/src/main/java/in/zapr/druid/druidry/topNMetric/NumericMetric.java +++ b/src/main/java/in/zapr/druid/druidry/topNMetric/NumericMetric.java @@ -27,11 +27,11 @@ public class NumericMetric extends TopNMetric { private static final String NUMERIC_METRIC_TYPE = "numeric"; private String type; - private TopNMetric metric; + private String metric; - public NumericMetric(@NonNull TopNMetric topNMetric) { + public NumericMetric(@NonNull String metric) { this.type = NUMERIC_METRIC_TYPE; - this.metric = topNMetric; + this.metric = metric; } } diff --git a/src/test/java/in/zapr/druid/druidry/topNMetric/NumericMetricTest.java b/src/test/java/in/zapr/druid/druidry/topNMetric/NumericMetricTest.java index 6c43c93e..2ad809e5 100644 --- a/src/test/java/in/zapr/druid/druidry/topNMetric/NumericMetricTest.java +++ b/src/test/java/in/zapr/druid/druidry/topNMetric/NumericMetricTest.java @@ -47,7 +47,7 @@ private JSONObject getNumericMetricJSON() throws JSONException { @Test public void testAllFields() throws JsonProcessingException, JSONException { - NumericMetric numericMetric = new NumericMetric(new SimpleMetric("events")); + NumericMetric numericMetric = new NumericMetric("events"); JSONObject jsonObject = getNumericMetricJSON(); @@ -65,8 +65,8 @@ public void testNullField1() { @Test public void testEqualsPositive() { - NumericMetric numericMetric1 = new NumericMetric(new SimpleMetric("events")); - NumericMetric numericMetric2 = new NumericMetric(new SimpleMetric("events")); + NumericMetric numericMetric1 = new NumericMetric("events"); + NumericMetric numericMetric2 = new NumericMetric("events"); Assert.assertEquals(numericMetric1, numericMetric2); } @@ -74,8 +74,8 @@ public void testEqualsPositive() { @Test public void testEqualsNegative() { - NumericMetric numericMetric1 = new NumericMetric(new SimpleMetric("events1")); - NumericMetric numericMetric2 = new NumericMetric(new SimpleMetric("events2")); + NumericMetric numericMetric1 = new NumericMetric("events1"); + NumericMetric numericMetric2 = new NumericMetric("events2"); Assert.assertNotEquals(numericMetric1, numericMetric2); } From bd457eb7943591a27fc8894b4349d47a9efeea5a Mon Sep 17 00:00:00 2001 From: Abhi <43852557+abhi-zapr@users.noreply.github.com> Date: Sun, 19 Apr 2020 17:29:38 +0530 Subject: [PATCH 23/25] naming refactor --- .../in/zapr/druid/druidry/topNMetric/NumericMetricTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/in/zapr/druid/druidry/topNMetric/NumericMetricTest.java b/src/test/java/in/zapr/druid/druidry/topNMetric/NumericMetricTest.java index 2ad809e5..9b1a4056 100644 --- a/src/test/java/in/zapr/druid/druidry/topNMetric/NumericMetricTest.java +++ b/src/test/java/in/zapr/druid/druidry/topNMetric/NumericMetricTest.java @@ -57,7 +57,7 @@ public void testAllFields() throws JsonProcessingException, JSONException { } @Test(expectedExceptions = NullPointerException.class) - public void testNullField1() { + public void testNullField() { NumericMetric numericMetric = new NumericMetric(null); } @@ -79,4 +79,4 @@ public void testEqualsNegative() { Assert.assertNotEquals(numericMetric1, numericMetric2); } -} \ No newline at end of file +} From 8222fef9e5a8df064298c87c1f362da907943d6d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Apr 2020 16:41:41 +0000 Subject: [PATCH 24/25] Bump jackson-databind from 2.9.10.3 to 2.9.10.4 Bumps [jackson-databind](https://github.com/FasterXML/jackson) from 2.9.10.3 to 2.9.10.4. - [Release notes](https://github.com/FasterXML/jackson/releases) - [Commits](https://github.com/FasterXML/jackson/commits) Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 17487b0e..67346a0f 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ UTF-8 - 2.9.10.3 + 2.9.10.4 2.9.9 2.9.7 1.18.10 From 21e1fd6f04e99eedc3089908f7000cf73266d71e Mon Sep 17 00:00:00 2001 From: Abhi <43852557+abhi-zapr@users.noreply.github.com> Date: Sat, 25 Apr 2020 18:31:32 +0530 Subject: [PATCH 25/25] version bump to 3.1 for release --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 67346a0f..b961f0b2 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ in.zapr.druid druidry - 3.1-SNAPSHOT + 3.1 Druidry - Druid Java Client Druidry is an open-source Java based utility library which supports creating