Skip to content

Commit b1f5888

Browse files
iverasealexey-ivanov-es
authored andcommitted
Handle with illegalArgumentExceptions negative values in HDR percentile aggregations (elastic#116174)
This commit changes to an illegalArgumentException which translate in a bad request (400).
1 parent eaffa1c commit b1f5888

File tree

6 files changed

+57
-3
lines changed

6 files changed

+57
-3
lines changed

docs/changelog/116174.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
pr: 116174
2+
summary: Handle with `illegalArgumentExceptions` negative values in HDR percentile
3+
aggregations
4+
area: Aggregations
5+
type: bug
6+
issues:
7+
- 115777

modules/aggregations/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,5 @@ dependencies {
4949
tasks.named("yamlRestCompatTestTransform").configure({ task ->
5050
task.skipTest("aggregations/date_agg_per_day_of_week/Date aggregartion per day of week", "week-date behaviour has changed")
5151
task.skipTest("aggregations/time_series/Configure with no synthetic source", "temporary until backport")
52+
task.skipTest("aggregations/percentiles_hdr_metric/Negative values test", "returned exception has changed")
5253
})

modules/aggregations/src/yamlRestTest/resources/rest-api-spec/test/aggregations/percentiles_hdr_metric.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,4 +446,4 @@ setup:
446446
- match: { aggregations.percentiles_int.values.75\.0: 101.0615234375 }
447447
- match: { aggregations.percentiles_int.values.95\.0: 151.1240234375 }
448448
- match: { aggregations.percentiles_int.values.99\.0: 151.1240234375 }
449-
- match: { _shards.failures.0.reason.type: array_index_out_of_bounds_exception }
449+
- match: { _shards.failures.0.reason.type: illegal_argument_exception }

server/src/main/java/org/elasticsearch/search/aggregations/metrics/AbstractHDRPercentilesAggregator.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,11 @@ public void collect(int doc, long bucket) throws IOException {
6161
if (values.advanceExact(doc)) {
6262
final DoubleHistogram state = getExistingOrNewHistogram(bigArrays(), bucket);
6363
for (int i = 0; i < values.docValueCount(); i++) {
64-
state.recordValue(values.nextValue());
64+
final double value = values.nextValue();
65+
if (value < 0) {
66+
throw new IllegalArgumentException("Negative values are not supported by HDR aggregation");
67+
}
68+
state.recordValue(value);
6569
}
6670
}
6771
}
@@ -74,8 +78,12 @@ protected LeafBucketCollector getLeafCollector(NumericDoubleValues values, LeafB
7478
@Override
7579
public void collect(int doc, long bucket) throws IOException {
7680
if (values.advanceExact(doc)) {
81+
final double value = values.doubleValue();
82+
if (value < 0) {
83+
throw new IllegalArgumentException("Negative values are not supported by HDR aggregation");
84+
}
7785
final DoubleHistogram state = getExistingOrNewHistogram(bigArrays(), bucket);
78-
state.recordValue(values.doubleValue());
86+
state.recordValue(value);
7987
}
8088
}
8189
};

server/src/test/java/org/elasticsearch/search/aggregations/metrics/HDRPercentileRanksAggregatorTests.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
package org.elasticsearch.search.aggregations.metrics;
1111

1212
import org.apache.lucene.document.Document;
13+
import org.apache.lucene.document.NumericDocValuesField;
1314
import org.apache.lucene.document.SortedNumericDocValuesField;
1415
import org.apache.lucene.index.IndexReader;
1516
import org.apache.lucene.index.MultiReader;
@@ -29,6 +30,9 @@
2930
import java.util.Iterator;
3031
import java.util.List;
3132

33+
import static java.util.Collections.singleton;
34+
import static org.hamcrest.Matchers.equalTo;
35+
3236
public class HDRPercentileRanksAggregatorTests extends AggregatorTestCase {
3337

3438
@Override
@@ -100,4 +104,26 @@ public void testEmptyValues() throws IOException {
100104

101105
assertThat(e.getMessage(), Matchers.equalTo("[values] must not be an empty array: [my_agg]"));
102106
}
107+
108+
public void testInvalidNegativeNumber() throws IOException {
109+
try (Directory dir = newDirectory(); RandomIndexWriter iw = new RandomIndexWriter(random(), dir)) {
110+
iw.addDocument(singleton(new NumericDocValuesField("number", 60)));
111+
iw.addDocument(singleton(new NumericDocValuesField("number", 40)));
112+
iw.addDocument(singleton(new NumericDocValuesField("number", -20)));
113+
iw.addDocument(singleton(new NumericDocValuesField("number", 10)));
114+
iw.commit();
115+
116+
PercentileRanksAggregationBuilder aggBuilder = new PercentileRanksAggregationBuilder("my_agg", new double[] { 0.1, 0.5, 12 })
117+
.field("number")
118+
.method(PercentilesMethod.HDR);
119+
MappedFieldType fieldType = new NumberFieldMapper.NumberFieldType("number", NumberFieldMapper.NumberType.LONG);
120+
try (IndexReader reader = iw.getReader()) {
121+
IllegalArgumentException e = expectThrows(
122+
IllegalArgumentException.class,
123+
() -> searchAndReduce(reader, new AggTestConfig(aggBuilder, fieldType))
124+
);
125+
assertThat(e.getMessage(), equalTo("Negative values are not supported by HDR aggregation"));
126+
}
127+
}
128+
}
103129
}

server/src/test/java/org/elasticsearch/search/aggregations/metrics/HDRPercentilesAggregatorTests.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,18 @@ public void testHdrThenTdigestSettings() throws Exception {
164164
assertThat(e.getMessage(), equalTo("Cannot set [compression] because the method has already been configured for HDRHistogram"));
165165
}
166166

167+
public void testInvalidNegativeNumber() {
168+
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> {
169+
testCase(new MatchAllDocsQuery(), iw -> {
170+
iw.addDocument(singleton(new NumericDocValuesField("number", 60)));
171+
iw.addDocument(singleton(new NumericDocValuesField("number", 40)));
172+
iw.addDocument(singleton(new NumericDocValuesField("number", -20)));
173+
iw.addDocument(singleton(new NumericDocValuesField("number", 10)));
174+
}, hdr -> { fail("Aggregation should have failed due to negative value"); });
175+
});
176+
assertThat(e.getMessage(), equalTo("Negative values are not supported by HDR aggregation"));
177+
}
178+
167179
private void testCase(Query query, CheckedConsumer<RandomIndexWriter, IOException> buildIndex, Consumer<InternalHDRPercentiles> verify)
168180
throws IOException {
169181
MappedFieldType fieldType = new NumberFieldMapper.NumberFieldType("number", NumberFieldMapper.NumberType.LONG);

0 commit comments

Comments
 (0)