Fix AggregationFactories.Builder equality and hash regarding order ()

Fixes the equals and hash function to ignore the order of aggregations to ensure equality after serialization
and deserialization. This ensures storing configs with aggregation works properly.

This also addresses a potential issue in caching when the same query contains aggregations but in 
different order. 1st it will not hit in the cache, 2nd cache objects which shall be equal might end up twice in 
the cache.
This commit is contained in:
Hendrik Muhs 2018-09-28 13:30:50 +02:00 committed by GitHub
parent c4b831645c
commit e2f310b56c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
49 changed files with 401 additions and 146 deletions
server/src
test/framework/src/main/java/org/elasticsearch/search/aggregations
x-pack/plugin
core/src/main/java/org/elasticsearch/xpack/core/ml/datafeed
rollup/src/test/java/org/elasticsearch/xpack/rollup
sql/src
main/java/org/elasticsearch/xpack/sql/execution/search
test/java/org/elasticsearch/xpack/sql/execution/search

@ -28,7 +28,7 @@ import org.elasticsearch.index.query.QueryRewriteContext;
import org.elasticsearch.search.internal.SearchContext;
import java.io.IOException;
import java.util.List;
import java.util.Collection;
import java.util.Map;
/**
@ -79,12 +79,12 @@ public abstract class AggregationBuilder
public abstract AggregationBuilder subAggregation(PipelineAggregationBuilder aggregation);
/** Return the configured set of subaggregations **/
public List<AggregationBuilder> getSubAggregations() {
public Collection<AggregationBuilder> getSubAggregations() {
return factoriesBuilder.getAggregatorFactories();
}
/** Return the configured set of pipeline aggregations **/
public List<PipelineAggregationBuilder> getPipelineAggregations() {
public Collection<PipelineAggregationBuilder> getPipelineAggregations() {
return factoriesBuilder.getPipelineAggregatorFactories();
}

@ -38,9 +38,11 @@ import org.elasticsearch.search.profile.aggregation.ProfilingAggregator;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@ -237,8 +239,11 @@ public class AggregatorFactories {
public static class Builder implements Writeable, ToXContentObject {
private final Set<String> names = new HashSet<>();
private final List<AggregationBuilder> aggregationBuilders = new ArrayList<>();
private final List<PipelineAggregationBuilder> pipelineAggregatorBuilders = new ArrayList<>();
// Using LinkedHashSets to preserve the order of insertion, that makes the results
// ordered nicely, although technically order does not matter
private final Collection<AggregationBuilder> aggregationBuilders = new LinkedHashSet<>();
private final Collection<PipelineAggregationBuilder> pipelineAggregatorBuilders = new LinkedHashSet<>();
private boolean skipResolveOrder;
/**
@ -322,29 +327,32 @@ public class AggregatorFactories {
parent);
}
AggregatorFactory<?>[] aggFactories = new AggregatorFactory<?>[aggregationBuilders.size()];
for (int i = 0; i < aggregationBuilders.size(); i++) {
aggFactories[i] = aggregationBuilders.get(i).build(context, parent);
int i = 0;
for (AggregationBuilder agg : aggregationBuilders) {
aggFactories[i] = agg.build(context, parent);
++i;
}
return new AggregatorFactories(aggFactories, orderedpipelineAggregators);
}
private List<PipelineAggregationBuilder> resolvePipelineAggregatorOrder(
List<PipelineAggregationBuilder> pipelineAggregatorBuilders, List<AggregationBuilder> aggBuilders,
Collection<PipelineAggregationBuilder> pipelineAggregatorBuilders, Collection<AggregationBuilder> aggregationBuilders,
AggregatorFactory<?> parent) {
Map<String, PipelineAggregationBuilder> pipelineAggregatorBuildersMap = new HashMap<>();
for (PipelineAggregationBuilder builder : pipelineAggregatorBuilders) {
pipelineAggregatorBuildersMap.put(builder.getName(), builder);
}
Map<String, AggregationBuilder> aggBuildersMap = new HashMap<>();
for (AggregationBuilder aggBuilder : aggBuilders) {
for (AggregationBuilder aggBuilder : aggregationBuilders) {
aggBuildersMap.put(aggBuilder.name, aggBuilder);
}
List<PipelineAggregationBuilder> orderedPipelineAggregatorrs = new LinkedList<>();
List<PipelineAggregationBuilder> unmarkedBuilders = new ArrayList<>(pipelineAggregatorBuilders);
Set<PipelineAggregationBuilder> temporarilyMarked = new HashSet<>();
Collection<PipelineAggregationBuilder> temporarilyMarked = new HashSet<>();
while (!unmarkedBuilders.isEmpty()) {
PipelineAggregationBuilder builder = unmarkedBuilders.get(0);
builder.validate(parent, aggBuilders, pipelineAggregatorBuilders);
builder.validate(parent, aggregationBuilders, pipelineAggregatorBuilders);
resolvePipelineAggregatorOrder(aggBuildersMap, pipelineAggregatorBuildersMap, orderedPipelineAggregatorrs, unmarkedBuilders,
temporarilyMarked, builder);
}
@ -354,7 +362,7 @@ public class AggregatorFactories {
private void resolvePipelineAggregatorOrder(Map<String, AggregationBuilder> aggBuildersMap,
Map<String, PipelineAggregationBuilder> pipelineAggregatorBuildersMap,
List<PipelineAggregationBuilder> orderedPipelineAggregators, List<PipelineAggregationBuilder> unmarkedBuilders,
Set<PipelineAggregationBuilder> temporarilyMarked, PipelineAggregationBuilder builder) {
Collection<PipelineAggregationBuilder> temporarilyMarked, PipelineAggregationBuilder builder) {
if (temporarilyMarked.contains(builder)) {
throw new IllegalArgumentException("Cyclical dependency found with pipeline aggregator [" + builder.getName() + "]");
} else if (unmarkedBuilders.contains(builder)) {
@ -375,7 +383,7 @@ public class AggregatorFactories {
} else {
// Check the non-pipeline sub-aggregator
// factories
List<AggregationBuilder> subBuilders = aggBuilder.factoriesBuilder.aggregationBuilders;
Collection<AggregationBuilder> subBuilders = aggBuilder.factoriesBuilder.aggregationBuilders;
boolean foundSubBuilder = false;
for (AggregationBuilder subBuilder : subBuilders) {
if (aggName.equals(subBuilder.name)) {
@ -386,7 +394,7 @@ public class AggregatorFactories {
}
// Check the pipeline sub-aggregator factories
if (!foundSubBuilder && (i == bucketsPathElements.size() - 1)) {
List<PipelineAggregationBuilder> subPipelineBuilders = aggBuilder.factoriesBuilder.pipelineAggregatorBuilders;
Collection<PipelineAggregationBuilder> subPipelineBuilders = aggBuilder.factoriesBuilder.pipelineAggregatorBuilders;
for (PipelineAggregationBuilder subFactory : subPipelineBuilders) {
if (aggName.equals(subFactory.getName())) {
foundSubBuilder = true;
@ -417,12 +425,12 @@ public class AggregatorFactories {
}
}
public List<AggregationBuilder> getAggregatorFactories() {
return Collections.unmodifiableList(aggregationBuilders);
public Collection<AggregationBuilder> getAggregatorFactories() {
return Collections.unmodifiableCollection(aggregationBuilders);
}
public List<PipelineAggregationBuilder> getPipelineAggregatorFactories() {
return Collections.unmodifiableList(pipelineAggregatorBuilders);
public Collection<PipelineAggregationBuilder> getPipelineAggregatorFactories() {
return Collections.unmodifiableCollection(pipelineAggregatorBuilders);
}
public int count() {
@ -463,6 +471,7 @@ public class AggregatorFactories {
if (getClass() != obj.getClass())
return false;
Builder other = (Builder) obj;
if (!Objects.equals(aggregationBuilders, other.aggregationBuilders))
return false;
if (!Objects.equals(pipelineAggregatorBuilders, other.pipelineAggregatorBuilders))

@ -25,7 +25,7 @@ import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
import java.io.IOException;
import java.util.List;
import java.util.Collection;
import java.util.Map;
/**
@ -68,8 +68,8 @@ public abstract class PipelineAggregationBuilder implements NamedWriteable, Base
* Internal: Validates the state of this factory (makes sure the factory is properly
* configured)
*/
protected abstract void validate(AggregatorFactory<?> parent, List<AggregationBuilder> factories,
List<PipelineAggregationBuilder> pipelineAggregatorFactories);
protected abstract void validate(AggregatorFactory<?> parent, Collection<AggregationBuilder> aggregationBuilders,
Collection<PipelineAggregationBuilder> pipelineAggregatorBuilders);
/**
* Creates the pipeline aggregator

@ -28,7 +28,7 @@ import org.elasticsearch.search.aggregations.PipelineAggregationBuilder;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
@ -81,8 +81,8 @@ public abstract class AbstractPipelineAggregationBuilder<PAB extends AbstractPip
* configured)
*/
@Override
public final void validate(AggregatorFactory<?> parent, List<AggregationBuilder> factories,
List<PipelineAggregationBuilder> pipelineAggregatorFactories) {
public final void validate(AggregatorFactory<?> parent, Collection<AggregationBuilder> factories,
Collection<PipelineAggregationBuilder> pipelineAggregatorFactories) {
doValidate(parent, factories, pipelineAggregatorFactories);
}
@ -99,8 +99,8 @@ public abstract class AbstractPipelineAggregationBuilder<PAB extends AbstractPip
return aggregator;
}
public void doValidate(AggregatorFactory<?> parent, List<AggregationBuilder> factories,
List<PipelineAggregationBuilder> pipelineAggregatorFactories) {
public void doValidate(AggregatorFactory<?> parent, Collection<AggregationBuilder> factories,
Collection<PipelineAggregationBuilder> pipelineAggregatorFactories) {
}
@SuppressWarnings("unchecked")

@ -32,7 +32,7 @@ import org.elasticsearch.search.aggregations.pipeline.BucketHelpers.GapPolicy;
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
import java.io.IOException;
import java.util.List;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
@ -109,8 +109,8 @@ public abstract class BucketMetricsPipelineAggregationBuilder<AF extends BucketM
protected abstract PipelineAggregator createInternal(Map<String, Object> metaData) throws IOException;
@Override
public void doValidate(AggregatorFactory<?> parent, List<AggregationBuilder> aggBuilders,
List<PipelineAggregationBuilder> pipelineAggregatorFactories) {
public void doValidate(AggregatorFactory<?> parent, Collection<AggregationBuilder> aggBuilders,
Collection<PipelineAggregationBuilder> pipelineAggregatorFactories) {
if (bucketsPaths.length != 1) {
throw new IllegalStateException(PipelineAggregator.Parser.BUCKETS_PATH.getPreferredName()
+ " must contain a single entry for aggregation [" + name + "]");

@ -35,7 +35,7 @@ import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.BucketMetric
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
@ -95,8 +95,8 @@ public class PercentilesBucketPipelineAggregationBuilder
}
@Override
public void doValidate(AggregatorFactory<?> parent, List<AggregationBuilder> aggFactories,
List<PipelineAggregationBuilder> pipelineAggregatorFactories) {
public void doValidate(AggregatorFactory<?> parent, Collection<AggregationBuilder> aggFactories,
Collection<PipelineAggregationBuilder> pipelineAggregatorFactories) {
super.doValidate(parent, aggFactories, pipelineAggregatorFactories);
for (Double p : percents) {

@ -29,7 +29,7 @@ import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.BucketMetricsPipelineAggregationBuilder;
import java.io.IOException;
import java.util.List;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
@ -82,8 +82,8 @@ public class ExtendedStatsBucketPipelineAggregationBuilder
}
@Override
public void doValidate(AggregatorFactory<?> parent, List<AggregationBuilder> aggBuilders,
List<PipelineAggregationBuilder> pipelineAggregatorFactories) {
public void doValidate(AggregatorFactory<?> parent, Collection<AggregationBuilder> aggBuilders,
Collection<PipelineAggregationBuilder> pipelineAggregatorFactories) {
super.doValidate(parent, aggBuilders, pipelineAggregatorFactories);
if (sigma < 0.0 ) {

@ -38,6 +38,7 @@ import org.elasticsearch.search.sort.SortBuilder;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
@ -145,8 +146,8 @@ public class BucketSortPipelineAggregationBuilder extends AbstractPipelineAggreg
}
@Override
public void doValidate(AggregatorFactory<?> parent, List<AggregationBuilder> aggFactories,
List<PipelineAggregationBuilder> pipelineAggregatoractories) {
public void doValidate(AggregatorFactory<?> parent, Collection<AggregationBuilder> aggFactories,
Collection<PipelineAggregationBuilder> pipelineAggregatoractories) {
if (sorts.isEmpty() && size == null && from == 0) {
throw new IllegalStateException("[" + name + "] is configured to perform nothing. Please set either of "
+ Arrays.asList(SearchSourceBuilder.SORT_FIELD.getPreferredName(), SIZE.getPreferredName(), FROM.getPreferredName())

@ -36,6 +36,7 @@ import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.BucketMetric
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@ -97,8 +98,8 @@ public class CumulativeSumPipelineAggregationBuilder extends AbstractPipelineAgg
}
@Override
public void doValidate(AggregatorFactory<?> parent, List<AggregationBuilder> aggFactories,
List<PipelineAggregationBuilder> pipelineAggregatorFactories) {
public void doValidate(AggregatorFactory<?> parent, Collection<AggregationBuilder> aggFactories,
Collection<PipelineAggregationBuilder> pipelineAggregatorFactories) {
if (bucketsPaths.length != 1) {
throw new IllegalStateException(BUCKETS_PATH.getPreferredName()
+ " must contain a single entry for aggregation [" + name + "]");

@ -42,6 +42,7 @@ import org.joda.time.DateTimeZone;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@ -156,8 +157,8 @@ public class DerivativePipelineAggregationBuilder extends AbstractPipelineAggreg
}
@Override
public void doValidate(AggregatorFactory<?> parent, List<AggregationBuilder> aggFactories,
List<PipelineAggregationBuilder> pipelineAggregatoractories) {
public void doValidate(AggregatorFactory<?> parent, Collection<AggregationBuilder> aggFactories,
Collection<PipelineAggregationBuilder> pipelineAggregatoractories) {
if (bucketsPaths.length != 1) {
throw new IllegalStateException(PipelineAggregator.Parser.BUCKETS_PATH.getPreferredName()
+ " must contain a single entry for aggregation [" + name + "]");

@ -44,6 +44,7 @@ import org.elasticsearch.search.aggregations.pipeline.movavg.models.SimpleModel;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@ -260,8 +261,8 @@ public class MovAvgPipelineAggregationBuilder extends AbstractPipelineAggregatio
}
@Override
public void doValidate(AggregatorFactory<?> parent, List<AggregationBuilder> aggFactories,
List<PipelineAggregationBuilder> pipelineAggregatoractories) {
public void doValidate(AggregatorFactory<?> parent, Collection<AggregationBuilder> aggFactories,
Collection<PipelineAggregationBuilder> pipelineAggregatoractories) {
if (minimize != null && minimize && !model.canBeMinimized()) {
// If the user asks to minimize, but this model doesn't support
// it, throw exception

@ -39,7 +39,7 @@ import org.elasticsearch.search.aggregations.pipeline.BucketHelpers.GapPolicy;
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
import java.io.IOException;
import java.util.List;
import java.util.Collection;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
@ -173,8 +173,8 @@ public class MovFnPipelineAggregationBuilder extends AbstractPipelineAggregation
}
@Override
public void doValidate(AggregatorFactory<?> parent, List<AggregationBuilder> aggFactories,
List<PipelineAggregationBuilder> pipelineAggregatoractories) {
public void doValidate(AggregatorFactory<?> parent, Collection<AggregationBuilder> aggFactories,
Collection<PipelineAggregationBuilder> pipelineAggregatoractories) {
if (window <= 0) {
throw new IllegalArgumentException("[" + WINDOW.getPreferredName() + "] must be a positive, non-zero integer.");
}

@ -0,0 +1,162 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you 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 org.elasticsearch.search.aggregations;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import org.elasticsearch.common.io.stream.Writeable.Reader;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.search.SearchModule;
import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
import org.elasticsearch.search.aggregations.pipeline.cumulativesum.CumulativeSumPipelineAggregationBuilder;
import org.elasticsearch.test.AbstractSerializingTestCase;
import org.junit.Before;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static java.util.Collections.emptyList;
import static org.hamcrest.Matchers.equalTo;
public class AggregatorFactoriesBuilderTests extends AbstractSerializingTestCase<AggregatorFactories.Builder> {
private NamedWriteableRegistry namedWriteableRegistry;
private NamedXContentRegistry namedXContentRegistry;
@Before
public void setUp() throws Exception {
super.setUp();
// register aggregations as NamedWriteable
SearchModule searchModule = new SearchModule(Settings.EMPTY, false, emptyList());
namedWriteableRegistry = new NamedWriteableRegistry(searchModule.getNamedWriteables());
namedXContentRegistry = new NamedXContentRegistry(searchModule.getNamedXContents());
}
@Override
protected NamedWriteableRegistry getNamedWriteableRegistry() {
return namedWriteableRegistry;
}
@Override
protected NamedXContentRegistry xContentRegistry() {
return namedXContentRegistry;
}
@Override
protected Builder doParseInstance(XContentParser parser) throws IOException {
// parseAggregators expects to be already inside the xcontent object
assertThat(parser.nextToken(), equalTo(XContentParser.Token.START_OBJECT));
AggregatorFactories.Builder builder = AggregatorFactories.parseAggregators(parser);
return builder;
}
@Override
protected Builder createTestInstance() {
AggregatorFactories.Builder builder = new AggregatorFactories.Builder();
// ensure that the unlikely does not happen: 2 aggs share the same name
Set<String> names = new HashSet<>();
for (int i = 0; i < randomIntBetween(1, 20); ++i) {
AggregationBuilder aggBuilder = getRandomAggregation();
if (names.add(aggBuilder.getName())) {
builder.addAggregator(aggBuilder);
}
}
for (int i = 0; i < randomIntBetween(0, 20); ++i) {
PipelineAggregationBuilder aggBuilder = getRandomPipelineAggregation();
if (names.add(aggBuilder.getName())) {
builder.addPipelineAggregator(aggBuilder);
}
}
return builder;
}
@Override
protected Reader<Builder> instanceReader() {
return AggregatorFactories.Builder::new;
}
public void testUnorderedEqualsSubSet() {
Set<String> names = new HashSet<>();
List<AggregationBuilder> aggBuilders = new ArrayList<>();
while (names.size() < 2) {
AggregationBuilder aggBuilder = getRandomAggregation();
if (names.add(aggBuilder.getName())) {
aggBuilders.add(aggBuilder);
}
}
AggregatorFactories.Builder builder1 = new AggregatorFactories.Builder();
AggregatorFactories.Builder builder2 = new AggregatorFactories.Builder();
builder1.addAggregator(aggBuilders.get(0));
builder1.addAggregator(aggBuilders.get(1));
builder2.addAggregator(aggBuilders.get(1));
assertFalse(builder1.equals(builder2));
assertFalse(builder2.equals(builder1));
assertNotEquals(builder1.hashCode(), builder2.hashCode());
builder2.addAggregator(aggBuilders.get(0));
assertTrue(builder1.equals(builder2));
assertTrue(builder2.equals(builder1));
assertEquals(builder1.hashCode(), builder2.hashCode());
builder1.addPipelineAggregator(getRandomPipelineAggregation());
assertFalse(builder1.equals(builder2));
assertFalse(builder2.equals(builder1));
assertNotEquals(builder1.hashCode(), builder2.hashCode());
}
private static AggregationBuilder getRandomAggregation() {
// just a couple of aggregations, sufficient for the purpose of this test
final int randomAggregatorPoolSize = 4;
switch (randomIntBetween(1, randomAggregatorPoolSize)) {
case 1:
return AggregationBuilders.avg(randomAlphaOfLengthBetween(3, 10));
case 2:
return AggregationBuilders.min(randomAlphaOfLengthBetween(3, 10));
case 3:
return AggregationBuilders.max(randomAlphaOfLengthBetween(3, 10));
case 4:
return AggregationBuilders.sum(randomAlphaOfLengthBetween(3, 10));
}
// never reached
return null;
}
private static PipelineAggregationBuilder getRandomPipelineAggregation() {
// just 1 type of pipeline agg, sufficient for the purpose of this test
String name = randomAlphaOfLengthBetween(3, 20);
String bucketsPath = randomAlphaOfLengthBetween(3, 20);
PipelineAggregationBuilder builder = new CumulativeSumPipelineAggregationBuilder(name, bucketsPath);
return builder;
}
}

@ -41,7 +41,7 @@ import org.elasticsearch.search.aggregations.pipeline.bucketscript.BucketScriptP
import org.elasticsearch.test.AbstractQueryTestCase;
import org.elasticsearch.test.ESTestCase;
import java.util.List;
import java.util.Collection;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -74,7 +74,7 @@ public class AggregatorFactoriesTests extends ESTestCase {
public void testGetAggregatorFactories_returnsUnmodifiableList() {
AggregatorFactories.Builder builder = new AggregatorFactories.Builder().addAggregator(AggregationBuilders.avg("foo"));
List<AggregationBuilder> aggregatorFactories = builder.getAggregatorFactories();
Collection<AggregationBuilder> aggregatorFactories = builder.getAggregatorFactories();
assertThat(aggregatorFactories.size(), equalTo(1));
expectThrows(UnsupportedOperationException.class, () -> aggregatorFactories.add(AggregationBuilders.avg("bar")));
}
@ -82,7 +82,7 @@ public class AggregatorFactoriesTests extends ESTestCase {
public void testGetPipelineAggregatorFactories_returnsUnmodifiableList() {
AggregatorFactories.Builder builder = new AggregatorFactories.Builder().addPipelineAggregator(
PipelineAggregatorBuilders.avgBucket("foo", "path1"));
List<PipelineAggregationBuilder> pipelineAggregatorFactories = builder.getPipelineAggregatorFactories();
Collection<PipelineAggregationBuilder> pipelineAggregatorFactories = builder.getPipelineAggregatorFactories();
assertThat(pipelineAggregatorFactories.size(), equalTo(1));
expectThrows(UnsupportedOperationException.class,
() -> pipelineAggregatorFactories.add(PipelineAggregatorBuilders.avgBucket("bar", "path2")));
@ -269,10 +269,10 @@ public class AggregatorFactoriesTests extends ESTestCase {
AggregatorFactories.Builder rewritten = builder
.rewrite(new QueryRewriteContext(xContentRegistry, null, null, () -> 0L));
assertNotSame(builder, rewritten);
List<AggregationBuilder> aggregatorFactories = rewritten.getAggregatorFactories();
Collection<AggregationBuilder> aggregatorFactories = rewritten.getAggregatorFactories();
assertEquals(1, aggregatorFactories.size());
assertThat(aggregatorFactories.get(0), instanceOf(FilterAggregationBuilder.class));
FilterAggregationBuilder rewrittenFilterAggBuilder = (FilterAggregationBuilder) aggregatorFactories.get(0);
assertThat(aggregatorFactories.iterator().next(), instanceOf(FilterAggregationBuilder.class));
FilterAggregationBuilder rewrittenFilterAggBuilder = (FilterAggregationBuilder) aggregatorFactories.iterator().next();
assertNotSame(filterAggBuilder, rewrittenFilterAggBuilder);
assertNotEquals(filterAggBuilder, rewrittenFilterAggBuilder);
// Check the filter was rewritten from a wrapper query to a terms query

@ -121,7 +121,7 @@ public abstract class BasePipelineAggregationTestCase<AF extends AbstractPipelin
AggregatorFactories.Builder parsed = AggregatorFactories.parseAggregators(parser);
assertThat(parsed.getAggregatorFactories(), hasSize(0));
assertThat(parsed.getPipelineAggregatorFactories(), hasSize(1));
PipelineAggregationBuilder newAgg = parsed.getPipelineAggregatorFactories().get(0);
PipelineAggregationBuilder newAgg = parsed.getPipelineAggregatorFactories().iterator().next();
assertNull(parser.nextToken());
assertNotNull(newAgg);
return newAgg;

@ -36,7 +36,7 @@ public class DateRangeTests extends BaseAggregationTestCase<DateRangeAggregation
@Override
protected DateRangeAggregationBuilder createTestAggregatorBuilder() {
int numRanges = randomIntBetween(1, 10);
DateRangeAggregationBuilder factory = new DateRangeAggregationBuilder("foo");
DateRangeAggregationBuilder factory = new DateRangeAggregationBuilder(randomAlphaOfLengthBetween(3, 10));
for (int i = 0; i < numRanges; i++) {
String key = null;
if (randomBoolean()) {

@ -171,9 +171,9 @@ public class FiltersTests extends BaseAggregationTestCase<FiltersAggregationBuil
assertNotEquals(original, rewritten);
assertThat(rewritten, instanceOf(TermsAggregationBuilder.class));
assertThat(rewritten.getSubAggregations().size(), equalTo(1));
AggregationBuilder subAgg = rewritten.getSubAggregations().get(0);
AggregationBuilder subAgg = rewritten.getSubAggregations().iterator().next();
assertThat(subAgg, instanceOf(FiltersAggregationBuilder.class));
assertNotSame(original.getSubAggregations().get(0), subAgg);
assertNotSame(original.getSubAggregations().iterator().next(), subAgg);
assertEquals("my-agg", subAgg.getName());
assertSame(rewritten,
rewritten.rewrite(new QueryRewriteContext(xContentRegistry(), null, null, () -> 0L)));

@ -41,7 +41,7 @@ public class GeoDistanceRangeTests extends BaseAggregationTestCase<GeoDistanceAg
protected GeoDistanceAggregationBuilder createTestAggregatorBuilder() {
int numRanges = randomIntBetween(1, 10);
GeoPoint origin = RandomShapeGenerator.randomPoint(random());
GeoDistanceAggregationBuilder factory = new GeoDistanceAggregationBuilder("foo", origin);
GeoDistanceAggregationBuilder factory = new GeoDistanceAggregationBuilder(randomAlphaOfLengthBetween(3, 10), origin);
for (int i = 0; i < numRanges; i++) {
String key = null;
if (randomBoolean()) {

@ -33,7 +33,7 @@ public class HistogramTests extends BaseAggregationTestCase<HistogramAggregation
@Override
protected HistogramAggregationBuilder createTestAggregatorBuilder() {
HistogramAggregationBuilder factory = new HistogramAggregationBuilder("foo");
HistogramAggregationBuilder factory = new HistogramAggregationBuilder(randomAlphaOfLengthBetween(3, 10));
factory.field(INT_FIELD_NAME);
factory.interval(randomDouble() * 1000);
if (randomBoolean()) {

@ -47,7 +47,7 @@ public class IpRangeTests extends BaseAggregationTestCase<IpRangeAggregationBuil
@Override
protected IpRangeAggregationBuilder createTestAggregatorBuilder() {
int numRanges = randomIntBetween(1, 10);
IpRangeAggregationBuilder factory = new IpRangeAggregationBuilder("foo");
IpRangeAggregationBuilder factory = new IpRangeAggregationBuilder(randomAlphaOfLengthBetween(3, 10));
for (int i = 0; i < numRanges; i++) {
String key = null;
if (randomBoolean()) {

@ -26,7 +26,7 @@ public class MissingTests extends BaseAggregationTestCase<MissingAggregationBuil
@Override
protected final MissingAggregationBuilder createTestAggregatorBuilder() {
MissingAggregationBuilder factory = new MissingAggregationBuilder("foo", null);
MissingAggregationBuilder factory = new MissingAggregationBuilder(randomAlphaOfLengthBetween(3, 10), null);
String field = randomNumericField();
randomFieldOrScript(factory, field);
return factory;

@ -36,7 +36,7 @@ public class RangeTests extends BaseAggregationTestCase<RangeAggregationBuilder>
@Override
protected RangeAggregationBuilder createTestAggregatorBuilder() {
int numRanges = randomIntBetween(1, 10);
RangeAggregationBuilder factory = new RangeAggregationBuilder("foo");
RangeAggregationBuilder factory = new RangeAggregationBuilder(randomAlphaOfLengthBetween(3, 10));
for (int i = 0; i < numRanges; i++) {
String key = null;
if (randomBoolean()) {

@ -26,7 +26,7 @@ public class SamplerTests extends BaseAggregationTestCase<SamplerAggregationBuil
@Override
protected final SamplerAggregationBuilder createTestAggregatorBuilder() {
SamplerAggregationBuilder factory = new SamplerAggregationBuilder("foo");
SamplerAggregationBuilder factory = new SamplerAggregationBuilder(randomAlphaOfLengthBetween(3, 10));
if (randomBoolean()) {
factory.shardSize(randomIntBetween(1, 1000));
}

@ -41,7 +41,7 @@ public class DateHistogramTests extends BaseAggregationTestCase<DateHistogramAgg
@Override
protected DateHistogramAggregationBuilder createTestAggregatorBuilder() {
DateHistogramAggregationBuilder factory = new DateHistogramAggregationBuilder("foo");
DateHistogramAggregationBuilder factory = new DateHistogramAggregationBuilder(randomAlphaOfLengthBetween(3, 10));
factory.field(INT_FIELD_NAME);
if (randomBoolean()) {
factory.interval(randomIntBetween(1, 100000));

@ -26,7 +26,7 @@ public class DiversifiedAggregationBuilderTests extends BaseAggregationTestCase<
@Override
protected final DiversifiedAggregationBuilder createTestAggregatorBuilder() {
DiversifiedAggregationBuilder factory = new DiversifiedAggregationBuilder("foo");
DiversifiedAggregationBuilder factory = new DiversifiedAggregationBuilder(randomAlphaOfLengthBetween(3, 10));
String field = randomNumericField();
randomFieldOrScript(factory, field);
if (randomBoolean()) {

@ -23,7 +23,7 @@ public class AvgTests extends AbstractNumericMetricTestCase<AvgAggregationBuilde
@Override
protected AvgAggregationBuilder doCreateTestAggregatorFactory() {
return new AvgAggregationBuilder("foo");
return new AvgAggregationBuilder(randomAlphaOfLengthBetween(3, 10));
}
}

@ -26,7 +26,7 @@ public class CardinalityTests extends BaseAggregationTestCase<CardinalityAggrega
@Override
protected final CardinalityAggregationBuilder createTestAggregatorBuilder() {
CardinalityAggregationBuilder factory = new CardinalityAggregationBuilder("foo", null);
CardinalityAggregationBuilder factory = new CardinalityAggregationBuilder(randomAlphaOfLengthBetween(3, 10), null);
String field = randomNumericField();
randomFieldOrScript(factory, field);
if (randomBoolean()) {

@ -23,7 +23,7 @@ public class ExtendedStatsTests extends AbstractNumericMetricTestCase<ExtendedSt
@Override
protected ExtendedStatsAggregationBuilder doCreateTestAggregatorFactory() {
ExtendedStatsAggregationBuilder factory = new ExtendedStatsAggregationBuilder("foo");
ExtendedStatsAggregationBuilder factory = new ExtendedStatsAggregationBuilder(randomAlphaOfLengthBetween(3, 10));
if (randomBoolean()) {
factory.sigma(randomDoubleBetween(0.0, 10.0, true));
}

@ -23,7 +23,7 @@ public class MaxTests extends AbstractNumericMetricTestCase<MaxAggregationBuilde
@Override
protected MaxAggregationBuilder doCreateTestAggregatorFactory() {
return new MaxAggregationBuilder("foo");
return new MaxAggregationBuilder(randomAlphaOfLengthBetween(3, 10));
}
}

@ -23,7 +23,7 @@ public class MinTests extends AbstractNumericMetricTestCase<MinAggregationBuilde
@Override
protected MinAggregationBuilder doCreateTestAggregatorFactory() {
return new MinAggregationBuilder("foo");
return new MinAggregationBuilder(randomAlphaOfLengthBetween(3, 10));
}
}

@ -23,7 +23,7 @@ public class StatsTests extends AbstractNumericMetricTestCase<StatsAggregationBu
@Override
protected StatsAggregationBuilder doCreateTestAggregatorFactory() {
return new StatsAggregationBuilder("foo");
return new StatsAggregationBuilder(randomAlphaOfLengthBetween(3, 10));
}
}

@ -23,7 +23,7 @@ public class SumTests extends AbstractNumericMetricTestCase<SumAggregationBuilde
@Override
protected SumAggregationBuilder doCreateTestAggregatorFactory() {
return new SumAggregationBuilder("foo");
return new SumAggregationBuilder(randomAlphaOfLengthBetween(3, 10));
}
}

@ -41,7 +41,7 @@ public class TopHitsTests extends BaseAggregationTestCase<TopHitsAggregationBuil
@Override
protected final TopHitsAggregationBuilder createTestAggregatorBuilder() {
TopHitsAggregationBuilder factory = new TopHitsAggregationBuilder("foo");
TopHitsAggregationBuilder factory = new TopHitsAggregationBuilder(randomAlphaOfLengthBetween(3, 10));
if (randomBoolean()) {
factory.from(randomIntBetween(0, 10000));
}

@ -25,7 +25,7 @@ public class ValueCountTests extends BaseAggregationTestCase<ValueCountAggregati
@Override
protected final ValueCountAggregationBuilder createTestAggregatorBuilder() {
ValueCountAggregationBuilder factory = new ValueCountAggregationBuilder("foo", null);
ValueCountAggregationBuilder factory = new ValueCountAggregationBuilder(randomAlphaOfLengthBetween(3, 10), null);
String field = randomNumericField();
randomFieldOrScript(factory, field);
if (randomBoolean()) {

@ -26,9 +26,9 @@ import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.avg.AvgBucketPipelineAggregationBuilder;
import org.elasticsearch.search.aggregations.support.ValueType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.HashSet;
import java.util.Set;
public class AvgBucketTests extends AbstractBucketMetricsTestCase<AvgBucketPipelineAggregationBuilder> {
@ -40,27 +40,27 @@ public class AvgBucketTests extends AbstractBucketMetricsTestCase<AvgBucketPipel
public void testValidate() {
AggregationBuilder singleBucketAgg = new GlobalAggregationBuilder("global");
AggregationBuilder multiBucketAgg = new TermsAggregationBuilder("terms", ValueType.STRING);
final List<AggregationBuilder> aggBuilders = new ArrayList<>();
final Set<AggregationBuilder> aggBuilders = new HashSet<>();
aggBuilders.add(singleBucketAgg);
aggBuilders.add(multiBucketAgg);
// First try to point to a non-existent agg
final AvgBucketPipelineAggregationBuilder builder = new AvgBucketPipelineAggregationBuilder("name", "invalid_agg>metric");
IllegalArgumentException ex = expectThrows(IllegalArgumentException.class,
() -> builder.validate(null, aggBuilders, Collections.emptyList()));
() -> builder.validate(null, aggBuilders, Collections.emptySet()));
assertEquals(PipelineAggregator.Parser.BUCKETS_PATH.getPreferredName()
+ " aggregation does not exist for aggregation [name]: invalid_agg>metric", ex.getMessage());
// Now try to point to a single bucket agg
AvgBucketPipelineAggregationBuilder builder2 = new AvgBucketPipelineAggregationBuilder("name", "global>metric");
ex = expectThrows(IllegalArgumentException.class, () -> builder2.validate(null, aggBuilders, Collections.emptyList()));
ex = expectThrows(IllegalArgumentException.class, () -> builder2.validate(null, aggBuilders, Collections.emptySet()));
assertEquals("The first aggregation in " + PipelineAggregator.Parser.BUCKETS_PATH.getPreferredName()
+ " must be a multi-bucket aggregation for aggregation [name] found :" + GlobalAggregationBuilder.class.getName()
+ " for buckets path: global>metric", ex.getMessage());
// Now try to point to a valid multi-bucket agg (no exception should be thrown)
AvgBucketPipelineAggregationBuilder builder3 = new AvgBucketPipelineAggregationBuilder("name", "terms>metric");
builder3.validate(null, aggBuilders, Collections.emptyList());
builder3.validate(null, aggBuilders, Collections.emptySet());
}

@ -28,9 +28,9 @@ import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.stats.extended.ExtendedStatsBucketPipelineAggregationBuilder;
import org.elasticsearch.search.aggregations.support.ValueType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.HashSet;
import java.util.Set;
import static org.hamcrest.Matchers.equalTo;
@ -65,7 +65,7 @@ public class ExtendedStatsBucketTests extends AbstractBucketMetricsTestCase<Exte
public void testValidate() {
AggregationBuilder singleBucketAgg = new GlobalAggregationBuilder("global");
AggregationBuilder multiBucketAgg = new TermsAggregationBuilder("terms", ValueType.STRING);
final List<AggregationBuilder> aggBuilders = new ArrayList<>();
final Set<AggregationBuilder> aggBuilders = new HashSet<>();
aggBuilders.add(singleBucketAgg);
aggBuilders.add(multiBucketAgg);
@ -73,13 +73,13 @@ public class ExtendedStatsBucketTests extends AbstractBucketMetricsTestCase<Exte
final ExtendedStatsBucketPipelineAggregationBuilder builder = new ExtendedStatsBucketPipelineAggregationBuilder("name",
"invalid_agg>metric");
IllegalArgumentException ex = expectThrows(IllegalArgumentException.class,
() -> builder.validate(null, aggBuilders, Collections.emptyList()));
() -> builder.validate(null, aggBuilders, Collections.emptySet()));
assertEquals(PipelineAggregator.Parser.BUCKETS_PATH.getPreferredName()
+ " aggregation does not exist for aggregation [name]: invalid_agg>metric", ex.getMessage());
// Now try to point to a single bucket agg
ExtendedStatsBucketPipelineAggregationBuilder builder2 = new ExtendedStatsBucketPipelineAggregationBuilder("name", "global>metric");
ex = expectThrows(IllegalArgumentException.class, () -> builder2.validate(null, aggBuilders, Collections.emptyList()));
ex = expectThrows(IllegalArgumentException.class, () -> builder2.validate(null, aggBuilders, Collections.emptySet()));
assertEquals("The first aggregation in " + PipelineAggregator.Parser.BUCKETS_PATH.getPreferredName()
+ " must be a multi-bucket aggregation for aggregation [name] found :" + GlobalAggregationBuilder.class.getName()
+ " for buckets path: global>metric", ex.getMessage());
@ -87,6 +87,6 @@ public class ExtendedStatsBucketTests extends AbstractBucketMetricsTestCase<Exte
// Now try to point to a valid multi-bucket agg (no exception should be
// thrown)
ExtendedStatsBucketPipelineAggregationBuilder builder3 = new ExtendedStatsBucketPipelineAggregationBuilder("name", "terms>metric");
builder3.validate(null, aggBuilders, Collections.emptyList());
builder3.validate(null, aggBuilders, Collections.emptySet());
}
}

@ -26,9 +26,9 @@ import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.max.MaxBucketPipelineAggregationBuilder;
import org.elasticsearch.search.aggregations.support.ValueType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.HashSet;
import java.util.Set;
public class MaxBucketTests extends AbstractBucketMetricsTestCase<MaxBucketPipelineAggregationBuilder> {
@ -40,20 +40,20 @@ public class MaxBucketTests extends AbstractBucketMetricsTestCase<MaxBucketPipel
public void testValidate() {
AggregationBuilder singleBucketAgg = new GlobalAggregationBuilder("global");
AggregationBuilder multiBucketAgg = new TermsAggregationBuilder("terms", ValueType.STRING);
final List<AggregationBuilder> aggBuilders = new ArrayList<>();
final Set<AggregationBuilder> aggBuilders = new HashSet<>();
aggBuilders.add(singleBucketAgg);
aggBuilders.add(multiBucketAgg);
// First try to point to a non-existent agg
final MaxBucketPipelineAggregationBuilder builder = new MaxBucketPipelineAggregationBuilder("name", "invalid_agg>metric");
IllegalArgumentException ex = expectThrows(IllegalArgumentException.class,
() -> builder.validate(null, aggBuilders, Collections.emptyList()));
() -> builder.validate(null, aggBuilders, Collections.emptySet()));
assertEquals(PipelineAggregator.Parser.BUCKETS_PATH.getPreferredName()
+ " aggregation does not exist for aggregation [name]: invalid_agg>metric", ex.getMessage());
// Now try to point to a single bucket agg
MaxBucketPipelineAggregationBuilder builder2 = new MaxBucketPipelineAggregationBuilder("name", "global>metric");
ex = expectThrows(IllegalArgumentException.class, () -> builder2.validate(null, aggBuilders, Collections.emptyList()));
ex = expectThrows(IllegalArgumentException.class, () -> builder2.validate(null, aggBuilders, Collections.emptySet()));
assertEquals("The first aggregation in " + PipelineAggregator.Parser.BUCKETS_PATH.getPreferredName()
+ " must be a multi-bucket aggregation for aggregation [name] found :" + GlobalAggregationBuilder.class.getName()
+ " for buckets path: global>metric", ex.getMessage());
@ -61,7 +61,7 @@ public class MaxBucketTests extends AbstractBucketMetricsTestCase<MaxBucketPipel
// Now try to point to a valid multi-bucket agg (no exception should be
// thrown)
MaxBucketPipelineAggregationBuilder builder3 = new MaxBucketPipelineAggregationBuilder("name", "terms>metric");
builder3.validate(null, aggBuilders, Collections.emptyList());
builder3.validate(null, aggBuilders, Collections.emptySet());
}
}

@ -26,9 +26,9 @@ import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.min.MinBucketPipelineAggregationBuilder;
import org.elasticsearch.search.aggregations.support.ValueType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.HashSet;
import java.util.Set;
public class MinBucketTests extends AbstractBucketMetricsTestCase<MinBucketPipelineAggregationBuilder> {
@ -40,20 +40,20 @@ public class MinBucketTests extends AbstractBucketMetricsTestCase<MinBucketPipel
public void testValidate() {
AggregationBuilder singleBucketAgg = new GlobalAggregationBuilder("global");
AggregationBuilder multiBucketAgg = new TermsAggregationBuilder("terms", ValueType.STRING);
final List<AggregationBuilder> aggBuilders = new ArrayList<>();
final Set<AggregationBuilder> aggBuilders = new HashSet<>();
aggBuilders.add(singleBucketAgg);
aggBuilders.add(multiBucketAgg);
// First try to point to a non-existent agg
final MinBucketPipelineAggregationBuilder builder = new MinBucketPipelineAggregationBuilder("name", "invalid_agg>metric");
IllegalArgumentException ex = expectThrows(IllegalArgumentException.class,
() -> builder.validate(null, aggBuilders, Collections.emptyList()));
() -> builder.validate(null, aggBuilders, Collections.emptySet()));
assertEquals(PipelineAggregator.Parser.BUCKETS_PATH.getPreferredName()
+ " aggregation does not exist for aggregation [name]: invalid_agg>metric", ex.getMessage());
// Now try to point to a single bucket agg
MinBucketPipelineAggregationBuilder builder2 = new MinBucketPipelineAggregationBuilder("name", "global>metric");
ex = expectThrows(IllegalArgumentException.class, () -> builder2.validate(null, aggBuilders, Collections.emptyList()));
ex = expectThrows(IllegalArgumentException.class, () -> builder2.validate(null, aggBuilders, Collections.emptySet()));
assertEquals("The first aggregation in " + PipelineAggregator.Parser.BUCKETS_PATH.getPreferredName()
+ " must be a multi-bucket aggregation for aggregation [name] found :" + GlobalAggregationBuilder.class.getName()
+ " for buckets path: global>metric", ex.getMessage());
@ -61,7 +61,7 @@ public class MinBucketTests extends AbstractBucketMetricsTestCase<MinBucketPipel
// Now try to point to a valid multi-bucket agg (no exception should be
// thrown)
MinBucketPipelineAggregationBuilder builder3 = new MinBucketPipelineAggregationBuilder("name", "terms>metric");
builder3.validate(null, aggBuilders, Collections.emptyList());
builder3.validate(null, aggBuilders, Collections.emptySet());
}
}

@ -28,9 +28,9 @@ import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.percentile.PercentilesBucketPipelineAggregationBuilder;
import org.elasticsearch.search.aggregations.support.ValueType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.HashSet;
import java.util.Set;
import static org.hamcrest.Matchers.equalTo;
@ -69,7 +69,7 @@ public class PercentilesBucketTests extends AbstractBucketMetricsTestCase<Percen
public void testValidate() {
AggregationBuilder singleBucketAgg = new GlobalAggregationBuilder("global");
AggregationBuilder multiBucketAgg = new TermsAggregationBuilder("terms", ValueType.STRING);
final List<AggregationBuilder> aggBuilders = new ArrayList<>();
final Set<AggregationBuilder> aggBuilders = new HashSet<>();
aggBuilders.add(singleBucketAgg);
aggBuilders.add(multiBucketAgg);
@ -77,13 +77,13 @@ public class PercentilesBucketTests extends AbstractBucketMetricsTestCase<Percen
final PercentilesBucketPipelineAggregationBuilder builder = new PercentilesBucketPipelineAggregationBuilder("name",
"invalid_agg>metric");
IllegalArgumentException ex = expectThrows(IllegalArgumentException.class,
() -> builder.validate(null, aggBuilders, Collections.emptyList()));
() -> builder.validate(null, aggBuilders, Collections.emptySet()));
assertEquals(PipelineAggregator.Parser.BUCKETS_PATH.getPreferredName()
+ " aggregation does not exist for aggregation [name]: invalid_agg>metric", ex.getMessage());
// Now try to point to a single bucket agg
PercentilesBucketPipelineAggregationBuilder builder2 = new PercentilesBucketPipelineAggregationBuilder("name", "global>metric");
ex = expectThrows(IllegalArgumentException.class, () -> builder2.validate(null, aggBuilders, Collections.emptyList()));
ex = expectThrows(IllegalArgumentException.class, () -> builder2.validate(null, aggBuilders, Collections.emptySet()));
assertEquals("The first aggregation in " + PipelineAggregator.Parser.BUCKETS_PATH.getPreferredName()
+ " must be a multi-bucket aggregation for aggregation [name] found :" + GlobalAggregationBuilder.class.getName()
+ " for buckets path: global>metric", ex.getMessage());
@ -91,6 +91,6 @@ public class PercentilesBucketTests extends AbstractBucketMetricsTestCase<Percen
// Now try to point to a valid multi-bucket agg (no exception should be
// thrown)
PercentilesBucketPipelineAggregationBuilder builder3 = new PercentilesBucketPipelineAggregationBuilder("name", "terms>metric");
builder3.validate(null, aggBuilders, Collections.emptyList());
builder3.validate(null, aggBuilders, Collections.emptySet());
}
}

@ -26,9 +26,9 @@ import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.stats.StatsBucketPipelineAggregationBuilder;
import org.elasticsearch.search.aggregations.support.ValueType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.HashSet;
import java.util.Set;
public class StatsBucketTests extends AbstractBucketMetricsTestCase<StatsBucketPipelineAggregationBuilder> {
@ -41,20 +41,20 @@ public class StatsBucketTests extends AbstractBucketMetricsTestCase<StatsBucketP
public void testValidate() {
AggregationBuilder singleBucketAgg = new GlobalAggregationBuilder("global");
AggregationBuilder multiBucketAgg = new TermsAggregationBuilder("terms", ValueType.STRING);
final List<AggregationBuilder> aggBuilders = new ArrayList<>();
final Set<AggregationBuilder> aggBuilders = new HashSet<>();
aggBuilders.add(singleBucketAgg);
aggBuilders.add(multiBucketAgg);
// First try to point to a non-existent agg
final StatsBucketPipelineAggregationBuilder builder = new StatsBucketPipelineAggregationBuilder("name", "invalid_agg>metric");
IllegalArgumentException ex = expectThrows(IllegalArgumentException.class,
() -> builder.validate(null, aggBuilders, Collections.emptyList()));
() -> builder.validate(null, aggBuilders, Collections.emptySet()));
assertEquals(PipelineAggregator.Parser.BUCKETS_PATH.getPreferredName()
+ " aggregation does not exist for aggregation [name]: invalid_agg>metric", ex.getMessage());
// Now try to point to a single bucket agg
StatsBucketPipelineAggregationBuilder builder2 = new StatsBucketPipelineAggregationBuilder("name", "global>metric");
ex = expectThrows(IllegalArgumentException.class, () -> builder2.validate(null, aggBuilders, Collections.emptyList()));
ex = expectThrows(IllegalArgumentException.class, () -> builder2.validate(null, aggBuilders, Collections.emptySet()));
assertEquals("The first aggregation in " + PipelineAggregator.Parser.BUCKETS_PATH.getPreferredName()
+ " must be a multi-bucket aggregation for aggregation [name] found :" + GlobalAggregationBuilder.class.getName()
+ " for buckets path: global>metric", ex.getMessage());
@ -62,7 +62,7 @@ public class StatsBucketTests extends AbstractBucketMetricsTestCase<StatsBucketP
// Now try to point to a valid multi-bucket agg (no exception should be
// thrown)
StatsBucketPipelineAggregationBuilder builder3 = new StatsBucketPipelineAggregationBuilder("name", "terms>metric");
builder3.validate(null, aggBuilders, Collections.emptyList());
builder3.validate(null, aggBuilders, Collections.emptySet());
}
}

@ -26,9 +26,9 @@ import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.sum.SumBucketPipelineAggregationBuilder;
import org.elasticsearch.search.aggregations.support.ValueType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.HashSet;
import java.util.Set;
public class SumBucketTests extends AbstractBucketMetricsTestCase<SumBucketPipelineAggregationBuilder> {
@ -40,20 +40,20 @@ public class SumBucketTests extends AbstractBucketMetricsTestCase<SumBucketPipel
public void testValidate() {
AggregationBuilder singleBucketAgg = new GlobalAggregationBuilder("global");
AggregationBuilder multiBucketAgg = new TermsAggregationBuilder("terms", ValueType.STRING);
final List<AggregationBuilder> aggBuilders = new ArrayList<>();
final Set<AggregationBuilder> aggBuilders = new HashSet<>();
aggBuilders.add(singleBucketAgg);
aggBuilders.add(multiBucketAgg);
// First try to point to a non-existent agg
final SumBucketPipelineAggregationBuilder builder = new SumBucketPipelineAggregationBuilder("name", "invalid_agg>metric");
IllegalArgumentException ex = expectThrows(IllegalArgumentException.class,
() -> builder.validate(null, aggBuilders, Collections.emptyList()));
() -> builder.validate(null, aggBuilders, Collections.emptySet()));
assertEquals(PipelineAggregator.Parser.BUCKETS_PATH.getPreferredName()
+ " aggregation does not exist for aggregation [name]: invalid_agg>metric", ex.getMessage());
// Now try to point to a single bucket agg
SumBucketPipelineAggregationBuilder builder2 = new SumBucketPipelineAggregationBuilder("name", "global>metric");
ex = expectThrows(IllegalArgumentException.class, () -> builder2.validate(null, aggBuilders, Collections.emptyList()));
ex = expectThrows(IllegalArgumentException.class, () -> builder2.validate(null, aggBuilders, Collections.emptySet()));
assertEquals("The first aggregation in " + PipelineAggregator.Parser.BUCKETS_PATH.getPreferredName()
+ " must be a multi-bucket aggregation for aggregation [name] found :" + GlobalAggregationBuilder.class.getName()
+ " for buckets path: global>metric", ex.getMessage());
@ -61,7 +61,7 @@ public class SumBucketTests extends AbstractBucketMetricsTestCase<SumBucketPipel
// Now try to point to a valid multi-bucket agg (no exception should be
// thrown)
SumBucketPipelineAggregationBuilder builder3 = new SumBucketPipelineAggregationBuilder("name", "terms>metric");
builder3.validate(null, aggBuilders, Collections.emptyList());
builder3.validate(null, aggBuilders, Collections.emptySet());
}
}

@ -31,6 +31,7 @@ import org.elasticsearch.test.ESIntegTestCase;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
@ -360,10 +361,12 @@ public class AggregationProfilerIT extends ESIntegTestCase {
assertThat(histoBreakdown.get(AggregationTimingType.REDUCE.toString()), equalTo(0L));
assertThat(histoAggResult.getProfiledChildren().size(), equalTo(2));
ProfileResult tagsAggResult = histoAggResult.getProfiledChildren().get(0);
Map<String, ProfileResult> histoAggResultSubAggregations = histoAggResult.getProfiledChildren().stream()
.collect(Collectors.toMap(ProfileResult::getLuceneDescription, s -> s));
ProfileResult tagsAggResult = histoAggResultSubAggregations.get("tags");
assertThat(tagsAggResult, notNullValue());
assertThat(tagsAggResult.getQueryName(), equalTo(GlobalOrdinalsStringTermsAggregator.class.getSimpleName()));
assertThat(tagsAggResult.getLuceneDescription(), equalTo("tags"));
assertThat(tagsAggResult.getTime(), greaterThan(0L));
Map<String, Long> tagsBreakdown = tagsAggResult.getTimeBreakdown();
assertThat(tagsBreakdown, notNullValue());
@ -377,10 +380,12 @@ public class AggregationProfilerIT extends ESIntegTestCase {
assertThat(tagsBreakdown.get(AggregationTimingType.REDUCE.toString()), equalTo(0L));
assertThat(tagsAggResult.getProfiledChildren().size(), equalTo(2));
ProfileResult avgAggResult = tagsAggResult.getProfiledChildren().get(0);
Map<String, ProfileResult> tagsAggResultSubAggregations = tagsAggResult.getProfiledChildren().stream()
.collect(Collectors.toMap(ProfileResult::getLuceneDescription, s -> s));
ProfileResult avgAggResult = tagsAggResultSubAggregations.get("avg");
assertThat(avgAggResult, notNullValue());
assertThat(avgAggResult.getQueryName(), equalTo("AvgAggregator"));
assertThat(avgAggResult.getLuceneDescription(), equalTo("avg"));
assertThat(avgAggResult.getTime(), greaterThan(0L));
Map<String, Long> avgBreakdown = tagsAggResult.getTimeBreakdown();
assertThat(avgBreakdown, notNullValue());
@ -394,10 +399,9 @@ public class AggregationProfilerIT extends ESIntegTestCase {
assertThat(avgBreakdown.get(AggregationTimingType.REDUCE.toString()), equalTo(0L));
assertThat(avgAggResult.getProfiledChildren().size(), equalTo(0));
ProfileResult maxAggResult = tagsAggResult.getProfiledChildren().get(1);
ProfileResult maxAggResult = tagsAggResultSubAggregations.get("max");
assertThat(maxAggResult, notNullValue());
assertThat(maxAggResult.getQueryName(), equalTo("MaxAggregator"));
assertThat(maxAggResult.getLuceneDescription(), equalTo("max"));
assertThat(maxAggResult.getTime(), greaterThan(0L));
Map<String, Long> maxBreakdown = tagsAggResult.getTimeBreakdown();
assertThat(maxBreakdown, notNullValue());
@ -411,10 +415,9 @@ public class AggregationProfilerIT extends ESIntegTestCase {
assertThat(maxBreakdown.get(AggregationTimingType.REDUCE.toString()), equalTo(0L));
assertThat(maxAggResult.getProfiledChildren().size(), equalTo(0));
ProfileResult stringsAggResult = histoAggResult.getProfiledChildren().get(1);
ProfileResult stringsAggResult = histoAggResultSubAggregations.get("strings");
assertThat(stringsAggResult, notNullValue());
assertThat(stringsAggResult.getQueryName(), equalTo(GlobalOrdinalsStringTermsAggregator.class.getSimpleName()));
assertThat(stringsAggResult.getLuceneDescription(), equalTo("strings"));
assertThat(stringsAggResult.getTime(), greaterThan(0L));
Map<String, Long> stringsBreakdown = stringsAggResult.getTimeBreakdown();
assertThat(stringsBreakdown, notNullValue());
@ -428,10 +431,12 @@ public class AggregationProfilerIT extends ESIntegTestCase {
assertThat(stringsBreakdown.get(AggregationTimingType.REDUCE.toString()), equalTo(0L));
assertThat(stringsAggResult.getProfiledChildren().size(), equalTo(3));
avgAggResult = stringsAggResult.getProfiledChildren().get(0);
Map<String, ProfileResult> stringsAggResultSubAggregations = stringsAggResult.getProfiledChildren().stream()
.collect(Collectors.toMap(ProfileResult::getLuceneDescription, s -> s));
avgAggResult = stringsAggResultSubAggregations.get("avg");
assertThat(avgAggResult, notNullValue());
assertThat(avgAggResult.getQueryName(), equalTo("AvgAggregator"));
assertThat(avgAggResult.getLuceneDescription(), equalTo("avg"));
assertThat(avgAggResult.getTime(), greaterThan(0L));
avgBreakdown = stringsAggResult.getTimeBreakdown();
assertThat(avgBreakdown, notNullValue());
@ -445,10 +450,9 @@ public class AggregationProfilerIT extends ESIntegTestCase {
assertThat(avgBreakdown.get(AggregationTimingType.REDUCE.toString()), equalTo(0L));
assertThat(avgAggResult.getProfiledChildren().size(), equalTo(0));
maxAggResult = stringsAggResult.getProfiledChildren().get(1);
maxAggResult = stringsAggResultSubAggregations.get("max");
assertThat(maxAggResult, notNullValue());
assertThat(maxAggResult.getQueryName(), equalTo("MaxAggregator"));
assertThat(maxAggResult.getLuceneDescription(), equalTo("max"));
assertThat(maxAggResult.getTime(), greaterThan(0L));
maxBreakdown = stringsAggResult.getTimeBreakdown();
assertThat(maxBreakdown, notNullValue());
@ -462,7 +466,7 @@ public class AggregationProfilerIT extends ESIntegTestCase {
assertThat(maxBreakdown.get(AggregationTimingType.REDUCE.toString()), equalTo(0L));
assertThat(maxAggResult.getProfiledChildren().size(), equalTo(0));
tagsAggResult = stringsAggResult.getProfiledChildren().get(2);
tagsAggResult = stringsAggResultSubAggregations.get("tags");
assertThat(tagsAggResult, notNullValue());
assertThat(tagsAggResult.getQueryName(), equalTo(GlobalOrdinalsStringTermsAggregator.class.getSimpleName()));
assertThat(tagsAggResult.getLuceneDescription(), equalTo("tags"));
@ -479,10 +483,12 @@ public class AggregationProfilerIT extends ESIntegTestCase {
assertThat(tagsBreakdown.get(AggregationTimingType.REDUCE.toString()), equalTo(0L));
assertThat(tagsAggResult.getProfiledChildren().size(), equalTo(2));
avgAggResult = tagsAggResult.getProfiledChildren().get(0);
tagsAggResultSubAggregations = tagsAggResult.getProfiledChildren().stream()
.collect(Collectors.toMap(ProfileResult::getLuceneDescription, s -> s));
avgAggResult = tagsAggResultSubAggregations.get("avg");
assertThat(avgAggResult, notNullValue());
assertThat(avgAggResult.getQueryName(), equalTo("AvgAggregator"));
assertThat(avgAggResult.getLuceneDescription(), equalTo("avg"));
assertThat(avgAggResult.getTime(), greaterThan(0L));
avgBreakdown = tagsAggResult.getTimeBreakdown();
assertThat(avgBreakdown, notNullValue());
@ -496,10 +502,9 @@ public class AggregationProfilerIT extends ESIntegTestCase {
assertThat(avgBreakdown.get(AggregationTimingType.REDUCE.toString()), equalTo(0L));
assertThat(avgAggResult.getProfiledChildren().size(), equalTo(0));
maxAggResult = tagsAggResult.getProfiledChildren().get(1);
maxAggResult = tagsAggResultSubAggregations.get("max");
assertThat(maxAggResult, notNullValue());
assertThat(maxAggResult.getQueryName(), equalTo("MaxAggregator"));
assertThat(maxAggResult.getLuceneDescription(), equalTo("max"));
assertThat(maxAggResult.getTime(), greaterThan(0L));
maxBreakdown = tagsAggResult.getTimeBreakdown();
assertThat(maxBreakdown, notNullValue());

@ -32,6 +32,10 @@ import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuil
import org.elasticsearch.test.AbstractBuilderTestCase;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static org.elasticsearch.test.EqualsHashCodeTestUtils.checkEqualsAndHashCode;
import static org.hamcrest.Matchers.hasSize;
@ -63,6 +67,58 @@ public abstract class BaseAggregationTestCase<AB extends AbstractAggregationBuil
assertEquals(testAgg.hashCode(), newAgg.hashCode());
}
/**
* Create at least 2 aggregations and test equality and hash
*/
public void testFromXContentMulti() throws IOException {
AggregatorFactories.Builder factoriesBuilder = AggregatorFactories.builder();
List<AB> testAggs = createTestAggregatorBuilders();
for (AB testAgg : testAggs) {
factoriesBuilder.addAggregator(testAgg);
}
XContentBuilder builder = XContentFactory.contentBuilder(randomFrom(XContentType.values()));
if (randomBoolean()) {
builder.prettyPrint();
}
factoriesBuilder.toXContent(builder, ToXContent.EMPTY_PARAMS);
XContentBuilder shuffled = shuffleXContent(builder);
XContentParser parser = createParser(shuffled);
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
AggregatorFactories.Builder parsed = AggregatorFactories.parseAggregators(parser);
assertThat(parsed.getAggregatorFactories(), hasSize(testAggs.size()));
assertThat(parsed.getPipelineAggregatorFactories(), hasSize(0));
assertEquals(factoriesBuilder, parsed);
assertEquals(factoriesBuilder.hashCode(), parsed.hashCode());
}
/**
* Create at least 2 aggregations and test equality and hash
*/
public void testSerializationMulti() throws IOException {
AggregatorFactories.Builder builder = AggregatorFactories.builder();
List<AB> testAggs = createTestAggregatorBuilders();
for (AB testAgg : testAggs) {
builder.addAggregator(testAgg);
}
try (BytesStreamOutput output = new BytesStreamOutput()) {
builder.writeTo(output);
try (StreamInput in = new NamedWriteableAwareStreamInput(output.bytes().streamInput(), namedWriteableRegistry())) {
AggregatorFactories.Builder newBuilder = new AggregatorFactories.Builder(in);
assertEquals(builder, newBuilder);
assertEquals(builder.hashCode(), newBuilder.hashCode());
assertNotSame(builder, newBuilder);
}
}
}
/**
* Generic test that checks that the toString method renders the XContent
* correctly.
@ -82,7 +138,7 @@ public abstract class BaseAggregationTestCase<AB extends AbstractAggregationBuil
AggregatorFactories.Builder parsed = AggregatorFactories.parseAggregators(parser);
assertThat(parsed.getAggregatorFactories(), hasSize(1));
assertThat(parsed.getPipelineAggregatorFactories(), hasSize(0));
AggregationBuilder newAgg = parsed.getAggregatorFactories().get(0);
AggregationBuilder newAgg = parsed.getAggregatorFactories().iterator().next();
assertNull(parser.nextToken());
assertNotNull(newAgg);
return newAgg;
@ -160,4 +216,21 @@ public abstract class BaseAggregationTestCase<AB extends AbstractAggregationBuil
throw new AssertionError("Unknow random operation [" + choice + "]");
}
}
private List<AB> createTestAggregatorBuilders() {
int numberOfAggregatorBuilders = randomIntBetween(2, 10);
// ensure that we do not create 2 aggregations with the same name
Set<String> names = new HashSet<>();
List<AB> aggBuilders = new ArrayList<>();
while (names.size() < numberOfAggregatorBuilders) {
AB aggBuilder = createTestAggregatorBuilder();
if (names.add(aggBuilder.getName())) {
aggBuilders.add(aggBuilder);
}
}
return aggBuilders;
}
}

@ -35,6 +35,7 @@ import org.elasticsearch.xpack.core.ml.utils.time.TimeUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@ -549,7 +550,7 @@ public class DatafeedConfig extends AbstractDiffable<DatafeedConfig> implements
throw ExceptionsHelper.badRequestException(
Messages.getMessage(Messages.DATAFEED_CONFIG_CANNOT_USE_SCRIPT_FIELDS_WITH_AGGS));
}
List<AggregationBuilder> aggregatorFactories = aggregations.getAggregatorFactories();
Collection<AggregationBuilder> aggregatorFactories = aggregations.getAggregatorFactories();
if (aggregatorFactories.isEmpty()) {
throw ExceptionsHelper.badRequestException(Messages.DATAFEED_AGGREGATIONS_REQUIRES_DATE_HISTOGRAM);
}
@ -560,7 +561,7 @@ public class DatafeedConfig extends AbstractDiffable<DatafeedConfig> implements
checkHistogramIntervalIsPositive(histogramAggregation);
}
private static void checkNoMoreHistogramAggregations(List<AggregationBuilder> aggregations) {
private static void checkNoMoreHistogramAggregations(Collection<AggregationBuilder> aggregations) {
for (AggregationBuilder agg : aggregations) {
if (ExtractorUtils.isHistogram(agg)) {
throw ExceptionsHelper.badRequestException(Messages.DATAFEED_AGGREGATIONS_MAX_ONE_DATE_HISTOGRAM);

@ -26,7 +26,7 @@ import org.joda.time.DateTimeZone;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Collection;
import java.util.concurrent.TimeUnit;
/**
@ -83,7 +83,7 @@ public final class ExtractorUtils {
* @param aggregations List of aggregations
* @return A {@link HistogramAggregationBuilder} or a {@link DateHistogramAggregationBuilder}
*/
public static AggregationBuilder getHistogramAggregation(List<AggregationBuilder> aggregations) {
public static AggregationBuilder getHistogramAggregation(Collection<AggregationBuilder> aggregations) {
if (aggregations.isEmpty()) {
throw ExceptionsHelper.badRequestException(Messages.getMessage(Messages.DATAFEED_AGGREGATIONS_REQUIRES_DATE_HISTOGRAM));
}
@ -91,7 +91,7 @@ public final class ExtractorUtils {
throw ExceptionsHelper.badRequestException(Messages.DATAFEED_AGGREGATIONS_REQUIRES_DATE_HISTOGRAM_NO_SIBLINGS);
}
AggregationBuilder agg = aggregations.get(0);
AggregationBuilder agg = aggregations.iterator().next();
if (isHistogram(agg)) {
return agg;
} else {

@ -385,7 +385,7 @@ public class SearchActionTests extends ESTestCase {
SearchRequest rollup = msearch.requests().get(1);
assertThat(rollup.indices().length, equalTo(1));
assertThat(rollup.indices()[0], equalTo(rollupIndices[0]));
assert(rollup.source().aggregations().getAggregatorFactories().get(0) instanceof FilterAggregationBuilder);
assert(rollup.source().aggregations().getAggregatorFactories().iterator().next() instanceof FilterAggregationBuilder);
}
public void testGoodButNullQuery() {
@ -418,7 +418,7 @@ public class SearchActionTests extends ESTestCase {
SearchRequest rollup = msearch.requests().get(1);
assertThat(rollup.indices().length, equalTo(1));
assertThat(rollup.indices()[0], equalTo(rollupIndices[0]));
assert(rollup.source().aggregations().getAggregatorFactories().get(0) instanceof FilterAggregationBuilder);
assert(rollup.source().aggregations().getAggregatorFactories().iterator().next() instanceof FilterAggregationBuilder);
}
public void testTwoMatchingJobs() {
@ -461,7 +461,7 @@ public class SearchActionTests extends ESTestCase {
SearchRequest rollup = msearch.requests().get(1);
assertThat(rollup.indices().length, equalTo(1));
assertThat(rollup.indices()[0], equalTo(rollupIndices[0]));
assert(rollup.source().aggregations().getAggregatorFactories().get(0) instanceof FilterAggregationBuilder);
assert(rollup.source().aggregations().getAggregatorFactories().iterator().next() instanceof FilterAggregationBuilder);
assertThat(msearch.requests().size(), equalTo(2));
}
@ -508,7 +508,7 @@ public class SearchActionTests extends ESTestCase {
SearchRequest rollup = msearch.requests().get(1);
assertThat(rollup.indices().length, equalTo(1));
assertThat(rollup.indices()[0], equalTo(rollupIndices[0]));
assert(rollup.source().aggregations().getAggregatorFactories().get(0) instanceof FilterAggregationBuilder);
assert(rollup.source().aggregations().getAggregatorFactories().iterator().next() instanceof FilterAggregationBuilder);
// The executed query should match the first job ("foo") because the second job contained a histo and the first didn't,

@ -604,9 +604,10 @@ public class RollupIndexerIndexingTests extends AggregatorTestCase {
// extract composite agg
assertThat(request.source().aggregations().getAggregatorFactories().size(), equalTo(1));
assertThat(request.source().aggregations().getAggregatorFactories().get(0), instanceOf(CompositeAggregationBuilder.class));
assertThat(request.source().aggregations().getAggregatorFactories().iterator().next(),
instanceOf(CompositeAggregationBuilder.class));
CompositeAggregationBuilder aggBuilder =
(CompositeAggregationBuilder) request.source().aggregations().getAggregatorFactories().get(0);
(CompositeAggregationBuilder) request.source().aggregations().getAggregatorFactories().iterator().next();
CompositeAggregation result = null;
try {

@ -168,7 +168,7 @@ public class CompositeAggregationCursor implements Cursor {
Map<String, Object> afterKey = composite.afterKey();
// a null after-key means done
if (afterKey != null) {
AggregationBuilder aggBuilder = next.aggregations().getAggregatorFactories().get(0);
AggregationBuilder aggBuilder = next.aggregations().getAggregatorFactories().iterator().next();
// update after-key with the new value
if (aggBuilder instanceof CompositeAggregationBuilder) {
CompositeAggregationBuilder comp = (CompositeAggregationBuilder) aggBuilder;

@ -65,7 +65,7 @@ public class SourceGeneratorTests extends ESTestCase {
SearchSourceBuilder sourceBuilder = SourceGenerator.sourceBuilder(container, null, size);
Builder aggBuilder = sourceBuilder.aggregations();
assertEquals(1, aggBuilder.count());
CompositeAggregationBuilder composite = (CompositeAggregationBuilder) aggBuilder.getAggregatorFactories().get(0);
CompositeAggregationBuilder composite = (CompositeAggregationBuilder) aggBuilder.getAggregatorFactories().iterator().next();
assertEquals(size, composite.size());
}