From 8bbbdaa0dbe456f62031ad3020396c8329fc787b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20B=C3=BCscher?= Date: Mon, 10 Apr 2017 15:42:37 +0200 Subject: [PATCH 1/3] Add parsing for all SingleBucketAggregation implementations --- .../aggregations/ParsedAggregation.java | 2 +- .../bucket/ParsedSingleBucketAggregation.java | 91 +++++++++++++++++++ .../bucket/children/ParsedChildren.java | 36 ++++++++ .../bucket/filter/ParsedFilter.java | 36 ++++++++ .../bucket/global/ParsedGlobal.java | 36 ++++++++ .../bucket/missing/ParsedMissing.java | 36 ++++++++ .../bucket/nested/ParsedNested.java | 36 ++++++++ .../bucket/nested/ParsedReverseNested.java | 36 ++++++++ .../bucket/sampler/InternalSampler.java | 2 +- .../bucket/sampler/ParsedSampler.java | 36 ++++++++ ...ternalSingleBucketAggregationTestCase.java | 32 +++++++ .../children/InternalChildrenTests.java | 5 + .../bucket/filter/InternalFilterTests.java | 6 ++ .../bucket/global/InternalGlobalTests.java | 5 + .../bucket/missing/InternalMissingTests.java | 5 + .../bucket/nested/InternalNestedTests.java | 6 ++ .../nested/InternalReverseNestedTests.java | 6 ++ .../bucket/sampler/InternalSamplerTests.java | 6 ++ .../test/InternalAggregationTestCase.java | 21 +++++ 19 files changed, 437 insertions(+), 2 deletions(-) create mode 100644 core/src/main/java/org/elasticsearch/search/aggregations/bucket/ParsedSingleBucketAggregation.java create mode 100644 core/src/main/java/org/elasticsearch/search/aggregations/bucket/children/ParsedChildren.java create mode 100644 core/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/ParsedFilter.java create mode 100644 core/src/main/java/org/elasticsearch/search/aggregations/bucket/global/ParsedGlobal.java create mode 100644 core/src/main/java/org/elasticsearch/search/aggregations/bucket/missing/ParsedMissing.java create mode 100644 core/src/main/java/org/elasticsearch/search/aggregations/bucket/nested/ParsedNested.java create mode 100644 core/src/main/java/org/elasticsearch/search/aggregations/bucket/nested/ParsedReverseNested.java create mode 100644 core/src/main/java/org/elasticsearch/search/aggregations/bucket/sampler/ParsedSampler.java diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/ParsedAggregation.java b/core/src/main/java/org/elasticsearch/search/aggregations/ParsedAggregation.java index 3ff91d8d36d70..97f27043124ae 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/ParsedAggregation.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/ParsedAggregation.java @@ -41,7 +41,7 @@ protected static void declareAggregationFields(ObjectParser metadata; + protected Map metadata; @Override public final String getName() { diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/ParsedSingleBucketAggregation.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/ParsedSingleBucketAggregation.java new file mode 100644 index 0000000000000..9082295bbcce2 --- /dev/null +++ b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/ParsedSingleBucketAggregation.java @@ -0,0 +1,91 @@ +/* + * 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.bucket; + +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentParserUtils; +import org.elasticsearch.search.aggregations.Aggregation; +import org.elasticsearch.search.aggregations.Aggregations; +import org.elasticsearch.search.aggregations.ParsedAggregation; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken; + +/** + * A base class for all the single bucket aggregations. + */ +public abstract class ParsedSingleBucketAggregation extends ParsedAggregation implements SingleBucketAggregation { + + private long docCount; + protected Aggregations aggregations = new Aggregations(Collections.emptyList()); + + @Override + public long getDocCount() { + return docCount; + } + + protected void setDocCount(long docCount) { + this.docCount = docCount; + } + + @Override + public Aggregations getAggregations() { + return aggregations; + } + + @Override + public XContentBuilder doXContentBody(XContentBuilder builder, Params params) throws IOException { + builder.field(CommonFields.DOC_COUNT.getPreferredName(), docCount); + aggregations.toXContentInternal(builder, params); + return builder; + } + + protected static T parseXContent(final XContentParser parser, T aggregation, String name) + throws IOException { + aggregation.setName(name); + XContentParser.Token token = parser.currentToken(); + String currentFieldName = parser.currentName(); + ensureExpectedToken(XContentParser.Token.FIELD_NAME, token, parser::getTokenLocation); + ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser::getTokenLocation); + + List aggregations = new ArrayList<>(); + while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { + if (token == XContentParser.Token.FIELD_NAME) { + currentFieldName = parser.currentName(); + } else if (token.isValue()) { + if (CommonFields.DOC_COUNT.getPreferredName().equals(currentFieldName)) { + aggregation.setDocCount(parser.longValue()); + } + } else if (token == XContentParser.Token.START_OBJECT) { + if (CommonFields.META.getPreferredName().equals(currentFieldName)) { + aggregation.metadata = parser.map(); + } else { + aggregations.add(XContentParserUtils.parseTypedKeysObject(parser, Aggregation.TYPED_KEYS_DELIMITER, Aggregation.class)); + } + } + } + aggregation.aggregations = new Aggregations(aggregations); + return aggregation; + } +} diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/children/ParsedChildren.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/children/ParsedChildren.java new file mode 100644 index 0000000000000..9ce6661923e4b --- /dev/null +++ b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/children/ParsedChildren.java @@ -0,0 +1,36 @@ +/* + * 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.bucket.children; + +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.search.aggregations.bucket.ParsedSingleBucketAggregation; + +import java.io.IOException; + +public class ParsedChildren extends ParsedSingleBucketAggregation implements Children { + + @Override + public String getType() { + return ChildrenAggregationBuilder.NAME; + } + + public static ParsedChildren fromXContent(XContentParser parser, final String name) throws IOException { + return parseXContent(parser, new ParsedChildren(), name); + } +} diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/ParsedFilter.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/ParsedFilter.java new file mode 100644 index 0000000000000..5f5cf104498e8 --- /dev/null +++ b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/ParsedFilter.java @@ -0,0 +1,36 @@ +/* + * 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.bucket.filter; + +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.search.aggregations.bucket.ParsedSingleBucketAggregation; + +import java.io.IOException; + +public class ParsedFilter extends ParsedSingleBucketAggregation implements Filter { + + @Override + public String getType() { + return FilterAggregationBuilder.NAME; + } + + public static ParsedFilter fromXContent(XContentParser parser, final String name) throws IOException { + return parseXContent(parser, new ParsedFilter(), name); + } +} diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/global/ParsedGlobal.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/global/ParsedGlobal.java new file mode 100644 index 0000000000000..062752805b1c8 --- /dev/null +++ b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/global/ParsedGlobal.java @@ -0,0 +1,36 @@ +/* + * 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.bucket.global; + +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.search.aggregations.bucket.ParsedSingleBucketAggregation; + +import java.io.IOException; + +public class ParsedGlobal extends ParsedSingleBucketAggregation implements Global { + + @Override + public String getType() { + return GlobalAggregationBuilder.NAME; + } + + public static ParsedGlobal fromXContent(XContentParser parser, final String name) throws IOException { + return parseXContent(parser, new ParsedGlobal(), name); + } +} diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/missing/ParsedMissing.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/missing/ParsedMissing.java new file mode 100644 index 0000000000000..2897372df8954 --- /dev/null +++ b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/missing/ParsedMissing.java @@ -0,0 +1,36 @@ +/* + * 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.bucket.missing; + +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.search.aggregations.bucket.ParsedSingleBucketAggregation; + +import java.io.IOException; + +public class ParsedMissing extends ParsedSingleBucketAggregation implements Missing { + + @Override + public String getType() { + return MissingAggregationBuilder.NAME; + } + + public static ParsedMissing fromXContent(XContentParser parser, final String name) throws IOException { + return parseXContent(parser, new ParsedMissing(), name); + } +} diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/nested/ParsedNested.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/nested/ParsedNested.java new file mode 100644 index 0000000000000..f241675678cfe --- /dev/null +++ b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/nested/ParsedNested.java @@ -0,0 +1,36 @@ +/* + * 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.bucket.nested; + +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.search.aggregations.bucket.ParsedSingleBucketAggregation; + +import java.io.IOException; + +public class ParsedNested extends ParsedSingleBucketAggregation implements Nested { + + @Override + public String getType() { + return NestedAggregationBuilder.NAME; + } + + public static ParsedNested fromXContent(XContentParser parser, final String name) throws IOException { + return parseXContent(parser, new ParsedNested(), name); + } +} diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/nested/ParsedReverseNested.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/nested/ParsedReverseNested.java new file mode 100644 index 0000000000000..dec15c3eded10 --- /dev/null +++ b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/nested/ParsedReverseNested.java @@ -0,0 +1,36 @@ +/* + * 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.bucket.nested; + +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.search.aggregations.bucket.ParsedSingleBucketAggregation; + +import java.io.IOException; + +public class ParsedReverseNested extends ParsedSingleBucketAggregation implements Nested { + + @Override + public String getType() { + return ReverseNestedAggregationBuilder.NAME; + } + + public static ParsedReverseNested fromXContent(XContentParser parser, final String name) throws IOException { + return parseXContent(parser, new ParsedReverseNested(), name); + } +} diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/sampler/InternalSampler.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/sampler/InternalSampler.java index 3b5b42d59fdd5..5d7e19ccad511 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/sampler/InternalSampler.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/sampler/InternalSampler.java @@ -49,7 +49,7 @@ public String getWriteableName() { @Override public String getType() { - return "sampler"; + return NAME; } @Override diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/sampler/ParsedSampler.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/sampler/ParsedSampler.java new file mode 100644 index 0000000000000..5e1c4d77b79cc --- /dev/null +++ b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/sampler/ParsedSampler.java @@ -0,0 +1,36 @@ +/* + * 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.bucket.sampler; + +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.search.aggregations.bucket.ParsedSingleBucketAggregation; + +import java.io.IOException; + +public class ParsedSampler extends ParsedSingleBucketAggregation implements Sampler { + + @Override + public String getType() { + return InternalSampler.NAME; + } + + public static ParsedSampler fromXContent(XContentParser parser, final String name) throws IOException { + return parseXContent(parser, new ParsedSampler(), name); + } +} diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/InternalSingleBucketAggregationTestCase.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/InternalSingleBucketAggregationTestCase.java index f84a364ab1da4..6fd3859d805cf 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/InternalSingleBucketAggregationTestCase.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/InternalSingleBucketAggregationTestCase.java @@ -19,14 +19,17 @@ package org.elasticsearch.search.aggregations.bucket; +import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.InternalAggregation; import org.elasticsearch.search.aggregations.InternalAggregations; +import org.elasticsearch.search.aggregations.ParsedAggregation; import org.elasticsearch.search.aggregations.metrics.max.InternalMax; import org.elasticsearch.search.aggregations.metrics.min.InternalMin; import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator; import org.elasticsearch.test.InternalAggregationTestCase; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Supplier; @@ -89,4 +92,33 @@ protected final void assertReduced(T reduced, List inputs) { } extraAssertReduced(reduced, inputs); } + + @Override + protected void assertFromXContent(T aggregation, ParsedAggregation parsedAggregation) { + assertTrue(parsedAggregation instanceof ParsedSingleBucketAggregation); + ParsedSingleBucketAggregation parsed = (ParsedSingleBucketAggregation) parsedAggregation; + + assertEquals(aggregation.getDocCount(), parsed.getDocCount()); + InternalAggregations aggregations = aggregation.getAggregations(); + Map expectedAggregations = new HashMap<>(); + int expectedNumberOfAggregations = 0; + for (Aggregation expectedAggregation : aggregations) { + // since we shuffle xContent, we cannot rely on the order of the original inner aggregations for comparison + assertTrue(expectedAggregation instanceof InternalAggregation); + expectedAggregations.put(expectedAggregation.getName(), expectedAggregation); + expectedNumberOfAggregations++; + } + int parsedNumberOfAggregations = 0; + for (Aggregation parsedAgg : parsed.getAggregations()) { + assertTrue(parsedAgg instanceof ParsedAggregation); + assertTrue(expectedAggregations.keySet().contains(parsedAgg.getName())); + // TODO check aggregation equality, e.g. same xContent + parsedNumberOfAggregations++; + } + assertEquals(expectedNumberOfAggregations, parsedNumberOfAggregations); + Class parsedClass = implementationClass(); + assertTrue(parsedClass != null && parsedClass.isInstance(parsedAggregation)); + } + + protected abstract Class implementationClass(); } diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/children/InternalChildrenTests.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/children/InternalChildrenTests.java index b248d5ed98117..285837c6e47ae 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/children/InternalChildrenTests.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/children/InternalChildrenTests.java @@ -22,6 +22,7 @@ import org.elasticsearch.common.io.stream.Writeable.Reader; import org.elasticsearch.search.aggregations.InternalAggregations; import org.elasticsearch.search.aggregations.bucket.InternalSingleBucketAggregationTestCase; +import org.elasticsearch.search.aggregations.bucket.ParsedSingleBucketAggregation; import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator; import java.util.List; @@ -44,4 +45,8 @@ protected Reader instanceReader() { return InternalChildren::new; } + @Override + protected Class implementationClass() { + return ParsedChildren.class; + } } diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/filter/InternalFilterTests.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/filter/InternalFilterTests.java index 3e74b9c21877e..8f888e13afe48 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/filter/InternalFilterTests.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/filter/InternalFilterTests.java @@ -22,6 +22,7 @@ import org.elasticsearch.common.io.stream.Writeable.Reader; import org.elasticsearch.search.aggregations.InternalAggregations; import org.elasticsearch.search.aggregations.bucket.InternalSingleBucketAggregationTestCase; +import org.elasticsearch.search.aggregations.bucket.ParsedSingleBucketAggregation; import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator; import java.util.List; @@ -43,4 +44,9 @@ protected void extraAssertReduced(InternalFilter reduced, List i protected Reader instanceReader() { return InternalFilter::new; } + + @Override + protected Class implementationClass() { + return ParsedFilter.class; + } } diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/global/InternalGlobalTests.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/global/InternalGlobalTests.java index 9092c3e028079..392f88b4d4e62 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/global/InternalGlobalTests.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/global/InternalGlobalTests.java @@ -22,6 +22,7 @@ import org.elasticsearch.common.io.stream.Writeable.Reader; import org.elasticsearch.search.aggregations.InternalAggregations; import org.elasticsearch.search.aggregations.bucket.InternalSingleBucketAggregationTestCase; +import org.elasticsearch.search.aggregations.bucket.ParsedSingleBucketAggregation; import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator; import java.util.List; @@ -44,4 +45,8 @@ protected Reader instanceReader() { return InternalGlobal::new; } + @Override + protected Class implementationClass() { + return ParsedGlobal.class; + } } diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/missing/InternalMissingTests.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/missing/InternalMissingTests.java index f3e151721bf30..75a28e87cefe7 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/missing/InternalMissingTests.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/missing/InternalMissingTests.java @@ -22,6 +22,7 @@ import org.elasticsearch.common.io.stream.Writeable.Reader; import org.elasticsearch.search.aggregations.InternalAggregations; import org.elasticsearch.search.aggregations.bucket.InternalSingleBucketAggregationTestCase; +import org.elasticsearch.search.aggregations.bucket.ParsedSingleBucketAggregation; import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator; import java.util.List; @@ -44,4 +45,8 @@ protected Reader instanceReader() { return InternalMissing::new; } + @Override + protected Class implementationClass() { + return ParsedMissing.class; + } } diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/nested/InternalNestedTests.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/nested/InternalNestedTests.java index 7b410723666d4..f6299ebf7bb25 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/nested/InternalNestedTests.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/nested/InternalNestedTests.java @@ -22,6 +22,7 @@ import org.elasticsearch.common.io.stream.Writeable.Reader; import org.elasticsearch.search.aggregations.InternalAggregations; import org.elasticsearch.search.aggregations.bucket.InternalSingleBucketAggregationTestCase; +import org.elasticsearch.search.aggregations.bucket.ParsedSingleBucketAggregation; import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator; import java.util.List; @@ -43,4 +44,9 @@ protected void extraAssertReduced(InternalNested reduced, List i protected Reader instanceReader() { return InternalNested::new; } + + @Override + protected Class implementationClass() { + return ParsedNested.class; + } } diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/nested/InternalReverseNestedTests.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/nested/InternalReverseNestedTests.java index f918024733e3a..08940fcd3aefe 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/nested/InternalReverseNestedTests.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/nested/InternalReverseNestedTests.java @@ -22,6 +22,7 @@ import org.elasticsearch.common.io.stream.Writeable.Reader; import org.elasticsearch.search.aggregations.InternalAggregations; import org.elasticsearch.search.aggregations.bucket.InternalSingleBucketAggregationTestCase; +import org.elasticsearch.search.aggregations.bucket.ParsedSingleBucketAggregation; import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator; import java.util.List; @@ -43,4 +44,9 @@ protected void extraAssertReduced(InternalReverseNested reduced, List instanceReader() { return InternalReverseNested::new; } + + @Override + protected Class implementationClass() { + return ParsedReverseNested.class; + } } diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/sampler/InternalSamplerTests.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/sampler/InternalSamplerTests.java index 1c4fb6d2a65f7..06319080923c2 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/sampler/InternalSamplerTests.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/sampler/InternalSamplerTests.java @@ -21,6 +21,7 @@ import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.search.aggregations.InternalAggregations; import org.elasticsearch.search.aggregations.bucket.InternalSingleBucketAggregationTestCase; +import org.elasticsearch.search.aggregations.bucket.ParsedSingleBucketAggregation; import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator; import java.util.List; @@ -42,4 +43,9 @@ protected void extraAssertReduced(InternalSampler reduced, List protected Writeable.Reader instanceReader() { return InternalSampler::new; } + + @Override + protected Class implementationClass() { + return ParsedSampler.class; + } } \ No newline at end of file diff --git a/test/framework/src/main/java/org/elasticsearch/test/InternalAggregationTestCase.java b/test/framework/src/main/java/org/elasticsearch/test/InternalAggregationTestCase.java index 64b09a0245ff5..de85c9a040cea 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/InternalAggregationTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/test/InternalAggregationTestCase.java @@ -38,10 +38,24 @@ import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.InternalAggregation; import org.elasticsearch.search.aggregations.ParsedAggregation; +import org.elasticsearch.search.aggregations.bucket.children.ChildrenAggregationBuilder; +import org.elasticsearch.search.aggregations.bucket.children.ParsedChildren; +import org.elasticsearch.search.aggregations.bucket.filter.FilterAggregationBuilder; +import org.elasticsearch.search.aggregations.bucket.filter.ParsedFilter; +import org.elasticsearch.search.aggregations.bucket.global.GlobalAggregationBuilder; +import org.elasticsearch.search.aggregations.bucket.global.ParsedGlobal; import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramAggregationBuilder; import org.elasticsearch.search.aggregations.bucket.histogram.HistogramAggregationBuilder; import org.elasticsearch.search.aggregations.bucket.histogram.ParsedDateHistogram; import org.elasticsearch.search.aggregations.bucket.histogram.ParsedHistogram; +import org.elasticsearch.search.aggregations.bucket.missing.MissingAggregationBuilder; +import org.elasticsearch.search.aggregations.bucket.missing.ParsedMissing; +import org.elasticsearch.search.aggregations.bucket.nested.NestedAggregationBuilder; +import org.elasticsearch.search.aggregations.bucket.nested.ParsedNested; +import org.elasticsearch.search.aggregations.bucket.nested.ParsedReverseNested; +import org.elasticsearch.search.aggregations.bucket.nested.ReverseNestedAggregationBuilder; +import org.elasticsearch.search.aggregations.bucket.sampler.InternalSampler; +import org.elasticsearch.search.aggregations.bucket.sampler.ParsedSampler; import org.elasticsearch.search.aggregations.bucket.terms.DoubleTerms; import org.elasticsearch.search.aggregations.bucket.terms.LongTerms; import org.elasticsearch.search.aggregations.bucket.terms.ParsedDoubleTerms; @@ -139,6 +153,13 @@ public static List getNamedXContents() { namedXContents.put(StringTerms.NAME, (p, c) -> ParsedStringTerms.fromXContent(p, (String) c)); namedXContents.put(LongTerms.NAME, (p, c) -> ParsedLongTerms.fromXContent(p, (String) c)); namedXContents.put(DoubleTerms.NAME, (p, c) -> ParsedDoubleTerms.fromXContent(p, (String) c)); + namedXContents.put(MissingAggregationBuilder.NAME, (p, c) -> ParsedMissing.fromXContent(p, (String) c)); + namedXContents.put(NestedAggregationBuilder.NAME, (p, c) -> ParsedNested.fromXContent(p, (String) c)); + namedXContents.put(ReverseNestedAggregationBuilder.NAME, (p, c) -> ParsedReverseNested.fromXContent(p, (String) c)); + namedXContents.put(ChildrenAggregationBuilder.NAME, (p, c) -> ParsedChildren.fromXContent(p, (String) c)); + namedXContents.put(GlobalAggregationBuilder.NAME, (p, c) -> ParsedGlobal.fromXContent(p, (String) c)); + namedXContents.put(FilterAggregationBuilder.NAME, (p, c) -> ParsedFilter.fromXContent(p, (String) c)); + namedXContents.put(InternalSampler.NAME, (p, c) -> ParsedSampler.fromXContent(p, (String) c)); return namedXContents.entrySet().stream() .map(entry -> new NamedXContentRegistry.Entry(Aggregation.class, new ParseField(entry.getKey()), entry.getValue())) From 7ff2839d48558ba5711b5bdfb00d52e40e6d6186 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20B=C3=BCscher?= Date: Wed, 10 May 2017 14:22:31 +0200 Subject: [PATCH 2/3] Adding test for inner aggregation xContent equality --- ...InternalSingleBucketAggregationTestCase.java | 17 +++++++++++++++-- .../test/InternalAggregationTestCase.java | 2 +- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/InternalSingleBucketAggregationTestCase.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/InternalSingleBucketAggregationTestCase.java index 6fd3859d805cf..b943a210c9321 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/InternalSingleBucketAggregationTestCase.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/InternalSingleBucketAggregationTestCase.java @@ -19,6 +19,10 @@ package org.elasticsearch.search.aggregations.bucket; +import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.XContentType; +import org.elasticsearch.rest.action.search.RestSearchAction; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.InternalAggregation; import org.elasticsearch.search.aggregations.InternalAggregations; @@ -28,6 +32,7 @@ import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator; import org.elasticsearch.test.InternalAggregationTestCase; +import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -36,6 +41,9 @@ import static java.util.Collections.emptyList; import static java.util.Collections.emptyMap; +import static java.util.Collections.singletonMap; +import static org.elasticsearch.common.xcontent.XContentHelper.toXContent; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertToXContentEquivalent; public abstract class InternalSingleBucketAggregationTestCase extends InternalAggregationTestCase { @@ -94,7 +102,7 @@ protected final void assertReduced(T reduced, List inputs) { } @Override - protected void assertFromXContent(T aggregation, ParsedAggregation parsedAggregation) { + protected void assertFromXContent(T aggregation, ParsedAggregation parsedAggregation) throws IOException { assertTrue(parsedAggregation instanceof ParsedSingleBucketAggregation); ParsedSingleBucketAggregation parsed = (ParsedSingleBucketAggregation) parsedAggregation; @@ -112,7 +120,12 @@ protected void assertFromXContent(T aggregation, ParsedAggregation parsedAggrega for (Aggregation parsedAgg : parsed.getAggregations()) { assertTrue(parsedAgg instanceof ParsedAggregation); assertTrue(expectedAggregations.keySet().contains(parsedAgg.getName())); - // TODO check aggregation equality, e.g. same xContent + Aggregation expectedInternalAggregation = expectedAggregations.get(parsedAgg.getName()); + final XContentType xContentType = randomFrom(XContentType.values()); + final ToXContent.Params params = new ToXContent.MapParams(singletonMap(RestSearchAction.TYPED_KEYS_PARAM, "true")); + BytesReference expectedBytes = toXContent(expectedInternalAggregation, xContentType, params, false); + BytesReference actualBytes = toXContent(parsedAgg, xContentType, params, false); + assertToXContentEquivalent(expectedBytes, actualBytes, xContentType); parsedNumberOfAggregations++; } assertEquals(expectedNumberOfAggregations, parsedNumberOfAggregations); diff --git a/test/framework/src/main/java/org/elasticsearch/test/InternalAggregationTestCase.java b/test/framework/src/main/java/org/elasticsearch/test/InternalAggregationTestCase.java index de85c9a040cea..99cf71f65e4e3 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/InternalAggregationTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/test/InternalAggregationTestCase.java @@ -269,7 +269,7 @@ public final void testFromXContent() throws IOException { } //norelease TODO make abstract - protected void assertFromXContent(T aggregation, ParsedAggregation parsedAggregation) { + protected void assertFromXContent(T aggregation, ParsedAggregation parsedAggregation) throws IOException { } @SuppressWarnings("unchecked") From 035f23801f782f1e9043f1854bd28e3da106cd7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20B=C3=BCscher?= Date: Wed, 10 May 2017 15:12:03 +0200 Subject: [PATCH 3/3] Fixing some tests after rebasing --- .../bucket/ParsedSingleBucketAggregation.java | 6 ++++-- .../search/aggregations/AggregationsTests.java | 14 ++++++++++++++ .../InternalSingleBucketAggregationTestCase.java | 6 ++++-- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/ParsedSingleBucketAggregation.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/ParsedSingleBucketAggregation.java index 9082295bbcce2..99d9bfa1955ad 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/ParsedSingleBucketAggregation.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/ParsedSingleBucketAggregation.java @@ -66,8 +66,10 @@ protected static T parseXContent(final aggregation.setName(name); XContentParser.Token token = parser.currentToken(); String currentFieldName = parser.currentName(); - ensureExpectedToken(XContentParser.Token.FIELD_NAME, token, parser::getTokenLocation); - ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser::getTokenLocation); + if (token == XContentParser.Token.FIELD_NAME) { + token = parser.nextToken(); + } + ensureExpectedToken(XContentParser.Token.START_OBJECT, token, parser::getTokenLocation); List aggregations = new ArrayList<>(); while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/AggregationsTests.java b/core/src/test/java/org/elasticsearch/search/aggregations/AggregationsTests.java index 78df82c550319..a338c8ec9ac54 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/AggregationsTests.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/AggregationsTests.java @@ -27,8 +27,15 @@ import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.rest.action.search.RestSearchAction; import org.elasticsearch.search.aggregations.bucket.InternalSingleBucketAggregationTestCase; +import org.elasticsearch.search.aggregations.bucket.children.InternalChildrenTests; +import org.elasticsearch.search.aggregations.bucket.filter.InternalFilterTests; +import org.elasticsearch.search.aggregations.bucket.global.InternalGlobalTests; import org.elasticsearch.search.aggregations.bucket.histogram.InternalDateHistogramTests; import org.elasticsearch.search.aggregations.bucket.histogram.InternalHistogramTests; +import org.elasticsearch.search.aggregations.bucket.missing.InternalMissingTests; +import org.elasticsearch.search.aggregations.bucket.nested.InternalNestedTests; +import org.elasticsearch.search.aggregations.bucket.nested.InternalReverseNestedTests; +import org.elasticsearch.search.aggregations.bucket.sampler.InternalSamplerTests; import org.elasticsearch.search.aggregations.bucket.terms.DoubleTermsTests; import org.elasticsearch.search.aggregations.bucket.terms.LongTermsTests; import org.elasticsearch.search.aggregations.bucket.terms.StringTermsTests; @@ -103,6 +110,13 @@ private static List getAggsTests() { aggsTests.add(new LongTermsTests()); aggsTests.add(new DoubleTermsTests()); aggsTests.add(new StringTermsTests()); + aggsTests.add(new InternalMissingTests()); + aggsTests.add(new InternalNestedTests()); + aggsTests.add(new InternalReverseNestedTests()); + aggsTests.add(new InternalChildrenTests()); + aggsTests.add(new InternalGlobalTests()); + aggsTests.add(new InternalFilterTests()); + aggsTests.add(new InternalSamplerTests()); return Collections.unmodifiableList(aggsTests); } diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/InternalSingleBucketAggregationTestCase.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/InternalSingleBucketAggregationTestCase.java index b943a210c9321..cae34768ecd2d 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/InternalSingleBucketAggregationTestCase.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/InternalSingleBucketAggregationTestCase.java @@ -48,14 +48,16 @@ public abstract class InternalSingleBucketAggregationTestCase extends InternalAggregationTestCase { - private final boolean hasInternalMax = randomBoolean(); - private final boolean hasInternalMin = randomBoolean(); + private boolean hasInternalMax; + private boolean hasInternalMin; public Supplier subAggregationsSupplier; @Override public void setUp() throws Exception { super.setUp(); + hasInternalMax = randomBoolean(); + hasInternalMin = randomBoolean(); subAggregationsSupplier = () -> { List aggs = new ArrayList<>(); if (hasInternalMax) {