Skip to content

Commit

Permalink
Fix for zapr-oss#160 - additional aggregators
Browse files Browse the repository at this point in the history
Add
- DoubleMeanAggregator
- StdDevPostAggregator
- VarianceAggregator
  • Loading branch information
barrybecker4 committed Mar 22, 2021
1 parent 9879ce8 commit f3fab2c
Show file tree
Hide file tree
Showing 8 changed files with 579 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public class DoubleMaxAggregator extends DruidAggregator {

private static final String DOUBLE_MAX_TYPE_AGGREGATOR = "doubleMax";

private String fieldName;
private final String fieldName;
private String expression;

@Deprecated
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +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.
*/

package in.zapr.druid.druidry.aggregator;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.google.common.base.Preconditions;

import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NonNull;



@Getter
@EqualsAndHashCode(callSuper = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class DoubleMeanAggregator extends DruidAggregator {

private static final String DOUBLE_MEAN_TYPE_AGGREGATOR = "doubleMean";

private final String fieldName;
private final String expression;

@Builder
private DoubleMeanAggregator(@NonNull String name, String fieldName, String expression) {
this.type = DOUBLE_MEAN_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"
);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public class DoubleMinAggregator extends DruidAggregator {

private static final String DOUBLE_MIN_TYPE_AGGREGATOR = "doubleMin";

private String fieldName;
private final String fieldName;
private String expression;

@Deprecated
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* 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 com.google.common.base.Preconditions;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NonNull;
import lombok.Builder;



@Getter
@EqualsAndHashCode(callSuper = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class VarianceAggregator extends DruidAggregator {
private static final String VARIANCE_TYPE_AGGREGATOR = "variance";

private final String fieldName;
private final String expression;

// One of "float", "double", "long", "variance"; defaults to "float".
private final String inputType;

// Use "population" to get variance_pop rather than variance_sample, which is default.
private final String estimator;

@Builder
private VarianceAggregator(@NonNull String name, String fieldName, String expression, String inputType, String estimator) {
this.type = VARIANCE_TYPE_AGGREGATOR;
this.name = name;
this.fieldName = fieldName;
this.expression = expression;
this.inputType = inputType;
this.estimator = estimator;

Preconditions.checkArgument(
fieldName == null ^ expression == null,
"Must have a valid, non-null fieldName or expression"
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +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.postAggregator;

import com.fasterxml.jackson.annotation.JsonInclude;

import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NonNull;


@Getter
@JsonInclude(JsonInclude.Include.NON_NULL)
@EqualsAndHashCode(callSuper = true)
public class StdDevPostAggregator extends DruidPostAggregator {

private static final String STDDEV_POST_AGGREGATOR_TYPE = "stddev";
private final String fieldName;

@Builder
StdDevPostAggregator(@NonNull String name,
@NonNull String fieldName) {
this.type = STDDEV_POST_AGGREGATOR_TYPE;
this.name = name;
this.fieldName = fieldName;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/*
* 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.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class DoubleMeanAggregatorTest {

private static ObjectMapper objectMapper;

@BeforeClass
public void init() {
objectMapper = new ObjectMapper();
}

@Test
public void testAllFields() throws JsonProcessingException, JSONException {

DoubleMeanAggregator doubleMeanAggregator =
DoubleMeanAggregator.builder().name("CarpeDiem").fieldName("someField").build();

JSONObject jsonObject = new JSONObject();
jsonObject.put("type", "doubleMean");
jsonObject.put("name", "CarpeDiem");
jsonObject.put("fieldName", "someField");

String actualJSON = objectMapper.writeValueAsString(doubleMeanAggregator);
String expectedJSON = jsonObject.toString();
JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.NON_EXTENSIBLE);
}

@Test
public void testAllButFieldName() throws JSONException, JsonProcessingException {

DoubleMeanAggregator doubleMeanAggregator =
DoubleMeanAggregator.builder()
.name("CarpeDiem")
.expression("(\"foo\" / \"bar\")")
.build();

JSONObject jsonObject = new JSONObject();
jsonObject.put("type", "doubleMean");
jsonObject.put("name", "CarpeDiem");
jsonObject.put("expression", "(\"foo\" / \"bar\")");

String actualJSON = objectMapper.writeValueAsString(doubleMeanAggregator);
String expectedJSON = jsonObject.toString();
JSONAssert.assertEquals(expectedJSON, actualJSON, JSONCompareMode.NON_EXTENSIBLE);
}

@Test(expectedExceptions = NullPointerException.class)
public void testNullName() throws JsonProcessingException, JSONException {

DoubleMeanAggregator doubleMeanAggregator =
DoubleMeanAggregator.builder()
.fieldName("anotherField")
.build();
}

@Test
public void testEqualsPositive() {
DoubleMeanAggregator aggregator1 =
DoubleMeanAggregator.builder()
.name("name")
.fieldName("field")
.build();

DoubleMeanAggregator aggregator2 =
DoubleMeanAggregator.builder()
.name("name")
.fieldName("field")
.build();

DoubleMeanAggregator aggregator3 =
DoubleMeanAggregator.builder()
.name("name")
.expression("(\"foo\" / \"bar\")")
.build();

DoubleMeanAggregator aggregator4 =
DoubleMeanAggregator.builder()
.name("name")
.expression("(\"foo\" / \"bar\")")
.build();

Assert.assertEquals(aggregator1, aggregator2);
Assert.assertEquals(aggregator3, aggregator4);
}

@Test
public void testEqualsNegative() {
DoubleMeanAggregator aggregator1 =
DoubleMeanAggregator.builder()
.name("name")
.fieldName("field")
.build();

DoubleMeanAggregator aggregator2 =
DoubleMeanAggregator.builder()
.name("name1")
.fieldName("field1")
.build();

DoubleMeanAggregator aggregator3 =
DoubleMeanAggregator.builder()
.name("name")
.expression("(\"foo\" / \"bar\")")
.build();

DoubleMeanAggregator aggregator4 =
DoubleMeanAggregator.builder()
.name("name")
.expression("(\"foo\" / \"baz\")")
.build();

Assert.assertNotEquals(aggregator1, aggregator2);
Assert.assertNotEquals(aggregator3, aggregator4);
}

@Test
public void testEqualsWithAnotherSubClass() {
DoubleMeanAggregator aggregator1 =
DoubleMeanAggregator.builder()
.name("name")
.fieldName("field")
.build();

CountAggregator aggregator2 = new CountAggregator("countAgg1");

Assert.assertNotEquals(aggregator1, aggregator2);
}

}
Loading

0 comments on commit f3fab2c

Please sign in to comment.