Replace AggregatorParsers with namedObject (#22397)
Removes `AggregatorParsers`, replacing all of its functionality with `XContentParser#namedObject`. This is the third bit of payoff from #22003, one less thing to pass around the entire application.
This commit is contained in:
parent
f75ef7adfd
commit
e3f77b4795
|
@ -90,8 +90,7 @@ public class RestMultiSearchAction extends BaseRestHandler {
|
||||||
parseMultiLineRequest(restRequest, multiRequest.indicesOptions(), allowExplicitIndex, (searchRequest, parser) -> {
|
parseMultiLineRequest(restRequest, multiRequest.indicesOptions(), allowExplicitIndex, (searchRequest, parser) -> {
|
||||||
try {
|
try {
|
||||||
final QueryParseContext queryParseContext = new QueryParseContext(parser, parseFieldMatcher);
|
final QueryParseContext queryParseContext = new QueryParseContext(parser, parseFieldMatcher);
|
||||||
searchRequest.source(SearchSourceBuilder.fromXContent(queryParseContext,
|
searchRequest.source(SearchSourceBuilder.fromXContent(queryParseContext, searchRequestParsers.suggesters));
|
||||||
searchRequestParsers.aggParsers, searchRequestParsers.suggesters));
|
|
||||||
multiRequest.add(searchRequest);
|
multiRequest.add(searchRequest);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new ElasticsearchParseException("Exception when parsing search request", e);
|
throw new ElasticsearchParseException("Exception when parsing search request", e);
|
||||||
|
|
|
@ -93,7 +93,7 @@ public class RestSearchAction extends BaseRestHandler {
|
||||||
searchRequest.indices(Strings.splitStringByCommaToArray(request.param("index")));
|
searchRequest.indices(Strings.splitStringByCommaToArray(request.param("index")));
|
||||||
if (requestContentParser != null) {
|
if (requestContentParser != null) {
|
||||||
QueryParseContext context = new QueryParseContext(requestContentParser, parseFieldMatcher);
|
QueryParseContext context = new QueryParseContext(requestContentParser, parseFieldMatcher);
|
||||||
searchRequest.source().parseXContent(context, searchRequestParsers.aggParsers, searchRequestParsers.suggesters);
|
searchRequest.source().parseXContent(context, searchRequestParsers.suggesters);
|
||||||
}
|
}
|
||||||
|
|
||||||
// do not allow 'query_and_fetch' or 'dfs_query_and_fetch' search types
|
// do not allow 'query_and_fetch' or 'dfs_query_and_fetch' search types
|
||||||
|
|
|
@ -94,8 +94,8 @@ import org.elasticsearch.plugins.SearchPlugin.ScoreFunctionSpec;
|
||||||
import org.elasticsearch.plugins.SearchPlugin.SearchExtSpec;
|
import org.elasticsearch.plugins.SearchPlugin.SearchExtSpec;
|
||||||
import org.elasticsearch.plugins.SearchPlugin.SearchExtensionSpec;
|
import org.elasticsearch.plugins.SearchPlugin.SearchExtensionSpec;
|
||||||
import org.elasticsearch.search.aggregations.AggregationBuilder;
|
import org.elasticsearch.search.aggregations.AggregationBuilder;
|
||||||
import org.elasticsearch.search.aggregations.Aggregator;
|
import org.elasticsearch.search.aggregations.AggregatorFactories;
|
||||||
import org.elasticsearch.search.aggregations.AggregatorParsers;
|
import org.elasticsearch.search.aggregations.BaseAggregationBuilder;
|
||||||
import org.elasticsearch.search.aggregations.InternalAggregation;
|
import org.elasticsearch.search.aggregations.InternalAggregation;
|
||||||
import org.elasticsearch.search.aggregations.PipelineAggregationBuilder;
|
import org.elasticsearch.search.aggregations.PipelineAggregationBuilder;
|
||||||
import org.elasticsearch.search.aggregations.bucket.children.ChildrenAggregationBuilder;
|
import org.elasticsearch.search.aggregations.bucket.children.ChildrenAggregationBuilder;
|
||||||
|
@ -268,10 +268,6 @@ public class SearchModule {
|
||||||
private final boolean transportClient;
|
private final boolean transportClient;
|
||||||
private final Map<String, Highlighter> highlighters;
|
private final Map<String, Highlighter> highlighters;
|
||||||
private final Map<String, Suggester<?>> suggesters;
|
private final Map<String, Suggester<?>> suggesters;
|
||||||
private final ParseFieldRegistry<Aggregator.Parser> aggregationParserRegistry = new ParseFieldRegistry<>("aggregation");
|
|
||||||
private final ParseFieldRegistry<PipelineAggregator.Parser> pipelineAggregationParserRegistry = new ParseFieldRegistry<>(
|
|
||||||
"pipline_aggregation");
|
|
||||||
private final AggregatorParsers aggregatorParsers = new AggregatorParsers(aggregationParserRegistry, pipelineAggregationParserRegistry);
|
|
||||||
private final ParseFieldRegistry<SignificanceHeuristicParser> significanceHeuristicParserRegistry = new ParseFieldRegistry<>(
|
private final ParseFieldRegistry<SignificanceHeuristicParser> significanceHeuristicParserRegistry = new ParseFieldRegistry<>(
|
||||||
"significance_heuristic");
|
"significance_heuristic");
|
||||||
private final ParseFieldRegistry<MovAvgModel.AbstractModelParser> movingAverageModelParserRegistry = new ParseFieldRegistry<>(
|
private final ParseFieldRegistry<MovAvgModel.AbstractModelParser> movingAverageModelParserRegistry = new ParseFieldRegistry<>(
|
||||||
|
@ -301,7 +297,7 @@ public class SearchModule {
|
||||||
registerFetchSubPhases(plugins);
|
registerFetchSubPhases(plugins);
|
||||||
registerSearchExts(plugins);
|
registerSearchExts(plugins);
|
||||||
registerShapes();
|
registerShapes();
|
||||||
searchRequestParsers = new SearchRequestParsers(aggregatorParsers, getSuggesters());
|
searchRequestParsers = new SearchRequestParsers(getSuggesters());
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<NamedWriteableRegistry.Entry> getNamedWriteables() {
|
public List<NamedWriteableRegistry.Entry> getNamedWriteables() {
|
||||||
|
@ -341,13 +337,6 @@ public class SearchModule {
|
||||||
return movingAverageModelParserRegistry;
|
return movingAverageModelParserRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Parsers for {@link AggregationBuilder}s and {@link PipelineAggregationBuilder}s.
|
|
||||||
*/
|
|
||||||
public AggregatorParsers getAggregatorParsers() {
|
|
||||||
return aggregatorParsers;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerAggregations(List<SearchPlugin> plugins) {
|
private void registerAggregations(List<SearchPlugin> plugins) {
|
||||||
registerAggregation(new AggregationSpec(AvgAggregationBuilder.NAME, AvgAggregationBuilder::new, AvgAggregationBuilder::parse)
|
registerAggregation(new AggregationSpec(AvgAggregationBuilder.NAME, AvgAggregationBuilder::new, AvgAggregationBuilder::parse)
|
||||||
.addResultReader(InternalAvg::new));
|
.addResultReader(InternalAvg::new));
|
||||||
|
@ -433,7 +422,10 @@ public class SearchModule {
|
||||||
|
|
||||||
private void registerAggregation(AggregationSpec spec) {
|
private void registerAggregation(AggregationSpec spec) {
|
||||||
if (false == transportClient) {
|
if (false == transportClient) {
|
||||||
aggregationParserRegistry.register(spec.getParser(), spec.getName());
|
namedXContents.add(new NamedXContentRegistry.Entry(BaseAggregationBuilder.class, spec.getName(), (p, c) -> {
|
||||||
|
AggregatorFactories.AggParseContext context = (AggregatorFactories.AggParseContext) c;
|
||||||
|
return spec.getParser().parse(context.name, context.queryParseContext);
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
namedWriteables.add(
|
namedWriteables.add(
|
||||||
new NamedWriteableRegistry.Entry(AggregationBuilder.class, spec.getName().getPreferredName(), spec.getReader()));
|
new NamedWriteableRegistry.Entry(AggregationBuilder.class, spec.getName().getPreferredName(), spec.getReader()));
|
||||||
|
@ -527,7 +519,10 @@ public class SearchModule {
|
||||||
|
|
||||||
private void registerPipelineAggregation(PipelineAggregationSpec spec) {
|
private void registerPipelineAggregation(PipelineAggregationSpec spec) {
|
||||||
if (false == transportClient) {
|
if (false == transportClient) {
|
||||||
pipelineAggregationParserRegistry.register(spec.getParser(), spec.getName());
|
namedXContents.add(new NamedXContentRegistry.Entry(BaseAggregationBuilder.class, spec.getName(), (p, c) -> {
|
||||||
|
AggregatorFactories.AggParseContext context = (AggregatorFactories.AggParseContext) c;
|
||||||
|
return spec.getParser().parse(context.name, context.queryParseContext);
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
namedWriteables.add(
|
namedWriteables.add(
|
||||||
new NamedWriteableRegistry.Entry(PipelineAggregationBuilder.class, spec.getName().getPreferredName(), spec.getReader()));
|
new NamedWriteableRegistry.Entry(PipelineAggregationBuilder.class, spec.getName().getPreferredName(), spec.getReader()));
|
||||||
|
|
|
@ -19,8 +19,6 @@
|
||||||
|
|
||||||
package org.elasticsearch.search;
|
package org.elasticsearch.search;
|
||||||
|
|
||||||
import org.elasticsearch.index.query.QueryParseContext;
|
|
||||||
import org.elasticsearch.search.aggregations.AggregatorParsers;
|
|
||||||
import org.elasticsearch.search.suggest.Suggesters;
|
import org.elasticsearch.search.suggest.Suggesters;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,25 +30,14 @@ public class SearchRequestParsers {
|
||||||
// methods split across RestSearchAction and SearchSourceBuilder should be moved here
|
// methods split across RestSearchAction and SearchSourceBuilder should be moved here
|
||||||
// TODO: make all members private once parsing functions are moved here
|
// TODO: make all members private once parsing functions are moved here
|
||||||
|
|
||||||
// TODO: AggregatorParsers should be removed and the underlying maps of agg
|
|
||||||
// and pipeline agg parsers should be here
|
|
||||||
/**
|
|
||||||
* Agg and pipeline agg parsers that may be used in search requests.
|
|
||||||
* @see org.elasticsearch.search.builder.SearchSourceBuilder#fromXContent(QueryParseContext, AggregatorParsers,
|
|
||||||
* Suggesters)
|
|
||||||
*/
|
|
||||||
public final AggregatorParsers aggParsers;
|
|
||||||
|
|
||||||
// TODO: Suggesters should be removed and the underlying map moved here
|
// TODO: Suggesters should be removed and the underlying map moved here
|
||||||
/**
|
/**
|
||||||
* Suggesters that may be used in search requests.
|
* Suggesters that may be used in search requests.
|
||||||
* @see org.elasticsearch.search.builder.SearchSourceBuilder#fromXContent(QueryParseContext, AggregatorParsers,
|
* @see org.elasticsearch.search.builder.SearchSourceBuilder#fromXContent(QueryParseContext, Suggesters)
|
||||||
* Suggesters)
|
|
||||||
*/
|
*/
|
||||||
public final Suggesters suggesters;
|
public final Suggesters suggesters;
|
||||||
|
|
||||||
public SearchRequestParsers(AggregatorParsers aggParsers, Suggesters suggesters) {
|
public SearchRequestParsers(Suggesters suggesters) {
|
||||||
this.aggParsers = aggParsers;
|
|
||||||
this.suggesters = suggesters;
|
this.suggesters = suggesters;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,6 +117,7 @@ public abstract class AbstractAggregationBuilder<AB extends AbstractAggregationB
|
||||||
return (AB) this;
|
return (AB) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return type.name();
|
return type.name();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.elasticsearch.action.support.ToXContentToBytes;
|
||||||
import org.elasticsearch.common.ParseField;
|
import org.elasticsearch.common.ParseField;
|
||||||
import org.elasticsearch.common.io.stream.NamedWriteable;
|
import org.elasticsearch.common.io.stream.NamedWriteable;
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
|
import org.elasticsearch.index.query.QueryParseContext;
|
||||||
import org.elasticsearch.search.aggregations.InternalAggregation.Type;
|
import org.elasticsearch.search.aggregations.InternalAggregation.Type;
|
||||||
import org.elasticsearch.search.internal.SearchContext;
|
import org.elasticsearch.search.internal.SearchContext;
|
||||||
|
|
||||||
|
@ -34,7 +35,7 @@ import java.util.Map;
|
||||||
*/
|
*/
|
||||||
public abstract class AggregationBuilder
|
public abstract class AggregationBuilder
|
||||||
extends ToXContentToBytes
|
extends ToXContentToBytes
|
||||||
implements NamedWriteable, ToXContent {
|
implements NamedWriteable, ToXContent, BaseAggregationBuilder {
|
||||||
|
|
||||||
protected final String name;
|
protected final String name;
|
||||||
protected final Type type;
|
protected final Type type;
|
||||||
|
@ -66,6 +67,7 @@ public abstract class AggregationBuilder
|
||||||
protected abstract AggregatorFactory<?> build(SearchContext context, AggregatorFactory<?> parent) throws IOException;
|
protected abstract AggregatorFactory<?> build(SearchContext context, AggregatorFactory<?> parent) throws IOException;
|
||||||
|
|
||||||
/** Associate metadata with this {@link AggregationBuilder}. */
|
/** Associate metadata with this {@link AggregationBuilder}. */
|
||||||
|
@Override
|
||||||
public abstract AggregationBuilder setMetaData(Map<String, Object> metaData);
|
public abstract AggregationBuilder setMetaData(Map<String, Object> metaData);
|
||||||
|
|
||||||
/** Add a sub aggregation to this builder. */
|
/** Add a sub aggregation to this builder. */
|
||||||
|
@ -77,13 +79,14 @@ public abstract class AggregationBuilder
|
||||||
/**
|
/**
|
||||||
* Internal: Registers sub-factories with this factory. The sub-factory will be
|
* Internal: Registers sub-factories with this factory. The sub-factory will be
|
||||||
* responsible for the creation of sub-aggregators under the aggregator
|
* responsible for the creation of sub-aggregators under the aggregator
|
||||||
* created by this factory. This is only for use by {@link AggregatorParsers}.
|
* created by this factory. This is only for use by {@link AggregatorFactories#parseAggregators(QueryParseContext)}.
|
||||||
*
|
*
|
||||||
* @param subFactories
|
* @param subFactories
|
||||||
* The sub-factories
|
* The sub-factories
|
||||||
* @return this factory (fluent interface)
|
* @return this factory (fluent interface)
|
||||||
*/
|
*/
|
||||||
protected abstract AggregationBuilder subAggregations(AggregatorFactories.Builder subFactories);
|
@Override
|
||||||
|
public abstract AggregationBuilder subAggregations(AggregatorFactories.Builder subFactories);
|
||||||
|
|
||||||
/** Common xcontent fields shared among aggregator builders */
|
/** Common xcontent fields shared among aggregator builders */
|
||||||
public static final class CommonFields extends ParseField.CommonFields {
|
public static final class CommonFields extends ParseField.CommonFields {
|
||||||
|
|
|
@ -19,10 +19,13 @@
|
||||||
package org.elasticsearch.search.aggregations;
|
package org.elasticsearch.search.aggregations;
|
||||||
|
|
||||||
import org.elasticsearch.action.support.ToXContentToBytes;
|
import org.elasticsearch.action.support.ToXContentToBytes;
|
||||||
|
import org.elasticsearch.common.ParsingException;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.io.stream.Writeable;
|
import org.elasticsearch.common.io.stream.Writeable;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.index.query.QueryParseContext;
|
||||||
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
|
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
|
||||||
import org.elasticsearch.search.aggregations.support.AggregationPath;
|
import org.elasticsearch.search.aggregations.support.AggregationPath;
|
||||||
import org.elasticsearch.search.aggregations.support.AggregationPath.PathElement;
|
import org.elasticsearch.search.aggregations.support.AggregationPath.PathElement;
|
||||||
|
@ -40,8 +43,126 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class AggregatorFactories {
|
public class AggregatorFactories {
|
||||||
|
public static final Pattern VALID_AGG_NAME = Pattern.compile("[^\\[\\]>]+");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the aggregation request recursively generating aggregator factories in turn.
|
||||||
|
*
|
||||||
|
* @param parseContext The parse context.
|
||||||
|
*
|
||||||
|
* @return The parsed aggregator factories.
|
||||||
|
*
|
||||||
|
* @throws IOException When parsing fails for unknown reasons.
|
||||||
|
*/
|
||||||
|
public static AggregatorFactories.Builder parseAggregators(QueryParseContext parseContext) throws IOException {
|
||||||
|
return parseAggregators(parseContext, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AggregatorFactories.Builder parseAggregators(QueryParseContext parseContext, int level) throws IOException {
|
||||||
|
Matcher validAggMatcher = VALID_AGG_NAME.matcher("");
|
||||||
|
AggregatorFactories.Builder factories = new AggregatorFactories.Builder();
|
||||||
|
|
||||||
|
XContentParser.Token token = null;
|
||||||
|
XContentParser parser = parseContext.parser();
|
||||||
|
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||||
|
if (token != XContentParser.Token.FIELD_NAME) {
|
||||||
|
throw new ParsingException(parser.getTokenLocation(),
|
||||||
|
"Unexpected token " + token + " in [aggs]: aggregations definitions must start with the name of the aggregation.");
|
||||||
|
}
|
||||||
|
final String aggregationName = parser.currentName();
|
||||||
|
if (!validAggMatcher.reset(aggregationName).matches()) {
|
||||||
|
throw new ParsingException(parser.getTokenLocation(), "Invalid aggregation name [" + aggregationName
|
||||||
|
+ "]. Aggregation names must be alpha-numeric and can only contain '_' and '-'");
|
||||||
|
}
|
||||||
|
|
||||||
|
token = parser.nextToken();
|
||||||
|
if (token != XContentParser.Token.START_OBJECT) {
|
||||||
|
throw new ParsingException(parser.getTokenLocation(), "Aggregation definition for [" + aggregationName + " starts with a ["
|
||||||
|
+ token + "], expected a [" + XContentParser.Token.START_OBJECT + "].");
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseAggregationBuilder aggBuilder = null;
|
||||||
|
AggregatorFactories.Builder subFactories = null;
|
||||||
|
|
||||||
|
Map<String, Object> metaData = null;
|
||||||
|
|
||||||
|
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||||
|
if (token != XContentParser.Token.FIELD_NAME) {
|
||||||
|
throw new ParsingException(
|
||||||
|
parser.getTokenLocation(), "Expected [" + XContentParser.Token.FIELD_NAME + "] under a ["
|
||||||
|
+ XContentParser.Token.START_OBJECT + "], but got a [" + token + "] in [" + aggregationName + "]",
|
||||||
|
parser.getTokenLocation());
|
||||||
|
}
|
||||||
|
final String fieldName = parser.currentName();
|
||||||
|
|
||||||
|
token = parser.nextToken();
|
||||||
|
if (token == XContentParser.Token.START_OBJECT) {
|
||||||
|
switch (fieldName) {
|
||||||
|
case "meta":
|
||||||
|
metaData = parser.map();
|
||||||
|
break;
|
||||||
|
case "aggregations":
|
||||||
|
case "aggs":
|
||||||
|
if (subFactories != null) {
|
||||||
|
throw new ParsingException(parser.getTokenLocation(),
|
||||||
|
"Found two sub aggregation definitions under [" + aggregationName + "]");
|
||||||
|
}
|
||||||
|
subFactories = parseAggregators(parseContext, level + 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (aggBuilder != null) {
|
||||||
|
throw new ParsingException(parser.getTokenLocation(), "Found two aggregation type definitions in ["
|
||||||
|
+ aggregationName + "]: [" + aggBuilder.getType() + "] and [" + fieldName + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
aggBuilder = parser.namedObject(BaseAggregationBuilder.class, fieldName,
|
||||||
|
new AggParseContext(aggregationName, parseContext));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new ParsingException(parser.getTokenLocation(), "Expected [" + XContentParser.Token.START_OBJECT + "] under ["
|
||||||
|
+ fieldName + "], but got a [" + token + "] in [" + aggregationName + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aggBuilder == null) {
|
||||||
|
throw new ParsingException(parser.getTokenLocation(), "Missing definition for aggregation [" + aggregationName + "]",
|
||||||
|
parser.getTokenLocation());
|
||||||
|
} else {
|
||||||
|
if (metaData != null) {
|
||||||
|
aggBuilder.setMetaData(metaData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subFactories != null) {
|
||||||
|
aggBuilder.subAggregations(subFactories);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aggBuilder instanceof AggregationBuilder) {
|
||||||
|
factories.addAggregator((AggregationBuilder) aggBuilder);
|
||||||
|
} else {
|
||||||
|
factories.addPipelineAggregator((PipelineAggregationBuilder) aggBuilder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return factories;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Context to parse and aggregation. This should eventually be removed and replaced with a String.
|
||||||
|
*/
|
||||||
|
public static final class AggParseContext {
|
||||||
|
public final String name;
|
||||||
|
public final QueryParseContext queryParseContext;
|
||||||
|
|
||||||
|
public AggParseContext(String name, QueryParseContext queryParseContext) {
|
||||||
|
this.name = name;
|
||||||
|
this.queryParseContext = queryParseContext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static final AggregatorFactories EMPTY = new AggregatorFactories(null, new AggregatorFactory<?>[0],
|
public static final AggregatorFactories EMPTY = new AggregatorFactories(null, new AggregatorFactory<?>[0],
|
||||||
new ArrayList<PipelineAggregationBuilder>());
|
new ArrayList<PipelineAggregationBuilder>());
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* 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.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface shared by {@link AggregationBuilder} and {@link PipelineAggregationBuilder} so they can conveniently share the same namespace
|
||||||
|
* for {@link XContentParser#namedObject(Class, String, Object)}.
|
||||||
|
*/
|
||||||
|
public interface BaseAggregationBuilder {
|
||||||
|
/**
|
||||||
|
* The name of the type of aggregation built by this builder.
|
||||||
|
*/
|
||||||
|
String getType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the aggregation's metadata. Returns {@code this} for chaining.
|
||||||
|
*/
|
||||||
|
BaseAggregationBuilder setMetaData(Map<String, Object> metaData);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the sub aggregations if this aggregation supports sub aggregations. Returns {@code this} for chaining.
|
||||||
|
*/
|
||||||
|
BaseAggregationBuilder subAggregations(Builder subFactories);
|
||||||
|
}
|
|
@ -20,7 +20,7 @@ package org.elasticsearch.search.aggregations;
|
||||||
|
|
||||||
import org.elasticsearch.action.support.ToXContentToBytes;
|
import org.elasticsearch.action.support.ToXContentToBytes;
|
||||||
import org.elasticsearch.common.io.stream.NamedWriteable;
|
import org.elasticsearch.common.io.stream.NamedWriteable;
|
||||||
import org.elasticsearch.search.aggregations.AggregatorFactory;
|
import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
|
||||||
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
|
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -32,7 +32,7 @@ import java.util.Map;
|
||||||
* specific type.
|
* specific type.
|
||||||
*/
|
*/
|
||||||
public abstract class PipelineAggregationBuilder extends ToXContentToBytes
|
public abstract class PipelineAggregationBuilder extends ToXContentToBytes
|
||||||
implements NamedWriteable {
|
implements NamedWriteable, BaseAggregationBuilder {
|
||||||
|
|
||||||
protected final String name;
|
protected final String name;
|
||||||
protected final String[] bucketsPaths;
|
protected final String[] bucketsPaths;
|
||||||
|
@ -79,6 +79,11 @@ public abstract class PipelineAggregationBuilder extends ToXContentToBytes
|
||||||
protected abstract PipelineAggregator create() throws IOException;
|
protected abstract PipelineAggregator create() throws IOException;
|
||||||
|
|
||||||
/** Associate metadata with this {@link PipelineAggregationBuilder}. */
|
/** Associate metadata with this {@link PipelineAggregationBuilder}. */
|
||||||
|
@Override
|
||||||
public abstract PipelineAggregationBuilder setMetaData(Map<String, Object> metaData);
|
public abstract PipelineAggregationBuilder setMetaData(Map<String, Object> metaData);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PipelineAggregationBuilder subAggregations(Builder subFactories) {
|
||||||
|
throw new IllegalArgumentException("Aggregation [" + name + "] cannot define sub-aggregations");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,4 +171,8 @@ public abstract class AbstractPipelineAggregationBuilder<PAB extends AbstractPip
|
||||||
|
|
||||||
protected abstract boolean doEquals(Object obj);
|
protected abstract boolean doEquals(Object obj);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,6 @@ import org.elasticsearch.script.Script;
|
||||||
import org.elasticsearch.search.SearchExtBuilder;
|
import org.elasticsearch.search.SearchExtBuilder;
|
||||||
import org.elasticsearch.search.aggregations.AggregationBuilder;
|
import org.elasticsearch.search.aggregations.AggregationBuilder;
|
||||||
import org.elasticsearch.search.aggregations.AggregatorFactories;
|
import org.elasticsearch.search.aggregations.AggregatorFactories;
|
||||||
import org.elasticsearch.search.aggregations.AggregatorParsers;
|
|
||||||
import org.elasticsearch.search.aggregations.PipelineAggregationBuilder;
|
import org.elasticsearch.search.aggregations.PipelineAggregationBuilder;
|
||||||
import org.elasticsearch.search.fetch.StoredFieldsContext;
|
import org.elasticsearch.search.fetch.StoredFieldsContext;
|
||||||
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
|
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
|
||||||
|
@ -104,10 +103,9 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
|
||||||
public static final ParseField SLICE = new ParseField("slice");
|
public static final ParseField SLICE = new ParseField("slice");
|
||||||
public static final ParseField ALL_FIELDS_FIELDS = new ParseField("all_fields");
|
public static final ParseField ALL_FIELDS_FIELDS = new ParseField("all_fields");
|
||||||
|
|
||||||
public static SearchSourceBuilder fromXContent(QueryParseContext context, AggregatorParsers aggParsers,
|
public static SearchSourceBuilder fromXContent(QueryParseContext context, Suggesters suggesters) throws IOException {
|
||||||
Suggesters suggesters) throws IOException {
|
|
||||||
SearchSourceBuilder builder = new SearchSourceBuilder();
|
SearchSourceBuilder builder = new SearchSourceBuilder();
|
||||||
builder.parseXContent(context, aggParsers, suggesters);
|
builder.parseXContent(context, suggesters);
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -912,12 +910,9 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
|
||||||
/**
|
/**
|
||||||
* Parse some xContent into this SearchSourceBuilder, overwriting any values specified in the xContent. Use this if you need to set up
|
* Parse some xContent into this SearchSourceBuilder, overwriting any values specified in the xContent. Use this if you need to set up
|
||||||
* different defaults than a regular SearchSourceBuilder would have and use
|
* different defaults than a regular SearchSourceBuilder would have and use
|
||||||
* {@link #fromXContent(QueryParseContext, AggregatorParsers, Suggesters)} if you have normal defaults.
|
* {@link #fromXContent(QueryParseContext, Suggesters)} if you have normal defaults.
|
||||||
*/
|
*/
|
||||||
public void parseXContent(QueryParseContext context, AggregatorParsers aggParsers,
|
public void parseXContent(QueryParseContext context, Suggesters suggesters) throws IOException {
|
||||||
Suggesters suggesters)
|
|
||||||
throws IOException {
|
|
||||||
|
|
||||||
XContentParser parser = context.parser();
|
XContentParser parser = context.parser();
|
||||||
XContentParser.Token token = parser.currentToken();
|
XContentParser.Token token = parser.currentToken();
|
||||||
String currentFieldName = null;
|
String currentFieldName = null;
|
||||||
|
@ -989,7 +984,7 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
|
||||||
}
|
}
|
||||||
} else if (AGGREGATIONS_FIELD.match(currentFieldName)
|
} else if (AGGREGATIONS_FIELD.match(currentFieldName)
|
||||||
|| AGGS_FIELD.match(currentFieldName)) {
|
|| AGGS_FIELD.match(currentFieldName)) {
|
||||||
aggregations = aggParsers.parseAggregators(context);
|
aggregations = AggregatorFactories.parseAggregators(context);
|
||||||
} else if (HIGHLIGHT_FIELD.match(currentFieldName)) {
|
} else if (HIGHLIGHT_FIELD.match(currentFieldName)) {
|
||||||
highlightBuilder = HighlightBuilder.fromXContent(context);
|
highlightBuilder = HighlightBuilder.fromXContent(context);
|
||||||
} else if (SUGGEST_FIELD.match(currentFieldName)) {
|
} else if (SUGGEST_FIELD.match(currentFieldName)) {
|
||||||
|
|
|
@ -163,7 +163,7 @@ public class MultiSearchRequestTests extends ESTestCase {
|
||||||
private MultiSearchRequest parseMultiSearchRequest(String sample) throws IOException {
|
private MultiSearchRequest parseMultiSearchRequest(String sample) throws IOException {
|
||||||
byte[] data = StreamsUtils.copyToBytesFromClasspath(sample);
|
byte[] data = StreamsUtils.copyToBytesFromClasspath(sample);
|
||||||
RestRequest restRequest = new FakeRestRequest.Builder(xContentRegistry()).withContent(new BytesArray(data)).build();
|
RestRequest restRequest = new FakeRestRequest.Builder(xContentRegistry()).withContent(new BytesArray(data)).build();
|
||||||
return RestMultiSearchAction.parseRequest(restRequest, true, new SearchRequestParsers(null, null), ParseFieldMatcher.EMPTY);
|
return RestMultiSearchAction.parseRequest(restRequest, true, new SearchRequestParsers(null), ParseFieldMatcher.EMPTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -32,6 +32,7 @@ import org.elasticsearch.plugins.SearchPlugin;
|
||||||
import org.elasticsearch.search.aggregations.AggregationBuilder;
|
import org.elasticsearch.search.aggregations.AggregationBuilder;
|
||||||
import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
|
import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
|
||||||
import org.elasticsearch.search.aggregations.AggregatorFactory;
|
import org.elasticsearch.search.aggregations.AggregatorFactory;
|
||||||
|
import org.elasticsearch.search.aggregations.BaseAggregationBuilder;
|
||||||
import org.elasticsearch.search.aggregations.InternalAggregation;
|
import org.elasticsearch.search.aggregations.InternalAggregation;
|
||||||
import org.elasticsearch.search.aggregations.InternalAggregation.ReduceContext;
|
import org.elasticsearch.search.aggregations.InternalAggregation.ReduceContext;
|
||||||
import org.elasticsearch.search.aggregations.bucket.significant.heuristics.ChiSquare;
|
import org.elasticsearch.search.aggregations.bucket.significant.heuristics.ChiSquare;
|
||||||
|
@ -74,8 +75,10 @@ import java.util.Set;
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
import static java.util.Collections.singletonList;
|
import static java.util.Collections.singletonList;
|
||||||
import static java.util.Collections.singletonMap;
|
import static java.util.Collections.singletonMap;
|
||||||
|
import static java.util.stream.Collectors.toList;
|
||||||
import static java.util.stream.Collectors.toSet;
|
import static java.util.stream.Collectors.toSet;
|
||||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
|
import static org.hamcrest.Matchers.hasSize;
|
||||||
|
|
||||||
public class SearchModuleTests extends ModuleTestCase {
|
public class SearchModuleTests extends ModuleTestCase {
|
||||||
|
|
||||||
|
@ -149,8 +152,8 @@ public class SearchModuleTests extends ModuleTestCase {
|
||||||
TermsAggregationBuilder::parse));
|
TermsAggregationBuilder::parse));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
expectThrows(IllegalArgumentException.class, () -> new SearchModule(Settings.EMPTY, false,
|
expectThrows(IllegalArgumentException.class, () -> new NamedXContentRegistry(new SearchModule(Settings.EMPTY, false,
|
||||||
singletonList(registersDupeAggregation)));
|
singletonList(registersDupeAggregation)).getNamedXContents()));
|
||||||
|
|
||||||
SearchPlugin registersDupePipelineAggregation = new SearchPlugin() {
|
SearchPlugin registersDupePipelineAggregation = new SearchPlugin() {
|
||||||
public List<PipelineAggregationSpec> getPipelineAggregations() {
|
public List<PipelineAggregationSpec> getPipelineAggregations() {
|
||||||
|
@ -162,8 +165,8 @@ public class SearchModuleTests extends ModuleTestCase {
|
||||||
.addResultReader(InternalDerivative::new));
|
.addResultReader(InternalDerivative::new));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
expectThrows(IllegalArgumentException.class, () -> new SearchModule(Settings.EMPTY, false,
|
expectThrows(IllegalArgumentException.class, () -> new NamedXContentRegistry(new SearchModule(Settings.EMPTY, false,
|
||||||
singletonList(registersDupePipelineAggregation)));
|
singletonList(registersDupePipelineAggregation)).getNamedXContents()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRegisterSuggester() {
|
public void testRegisterSuggester() {
|
||||||
|
@ -221,7 +224,11 @@ public class SearchModuleTests extends ModuleTestCase {
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
assertNotNull(module.getAggregatorParsers().parser("test"));
|
assertThat(
|
||||||
|
module.getNamedXContents().stream()
|
||||||
|
.filter(entry -> entry.categoryClass.equals(BaseAggregationBuilder.class) && entry.name.match("test"))
|
||||||
|
.collect(toList()),
|
||||||
|
hasSize(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRegisterPipelineAggregation() {
|
public void testRegisterPipelineAggregation() {
|
||||||
|
@ -232,7 +239,11 @@ public class SearchModuleTests extends ModuleTestCase {
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
assertNotNull(module.getAggregatorParsers().pipelineParser("test"));
|
assertThat(
|
||||||
|
module.getNamedXContents().stream()
|
||||||
|
.filter(entry -> entry.categoryClass.equals(BaseAggregationBuilder.class) && entry.name.match("test"))
|
||||||
|
.collect(toList()),
|
||||||
|
hasSize(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] NON_DEPRECATED_QUERIES = new String[] {
|
private static final String[] NON_DEPRECATED_QUERIES = new String[] {
|
||||||
|
|
|
@ -24,7 +24,6 @@ import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||||
import org.elasticsearch.index.IndexService;
|
import org.elasticsearch.index.IndexService;
|
||||||
import org.elasticsearch.index.query.QueryParseContext;
|
import org.elasticsearch.index.query.QueryParseContext;
|
||||||
import org.elasticsearch.search.SearchRequestParsers;
|
|
||||||
import org.elasticsearch.search.internal.SearchContext;
|
import org.elasticsearch.search.internal.SearchContext;
|
||||||
import org.elasticsearch.test.ESSingleNodeTestCase;
|
import org.elasticsearch.test.ESSingleNodeTestCase;
|
||||||
|
|
||||||
|
@ -59,12 +58,11 @@ public class AggregationCollectorTests extends ESSingleNodeTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean needsScores(IndexService index, String agg) throws IOException {
|
private boolean needsScores(IndexService index, String agg) throws IOException {
|
||||||
AggregatorParsers parser = getInstanceFromNode(SearchRequestParsers.class).aggParsers;
|
|
||||||
XContentParser aggParser = createParser(JsonXContent.jsonXContent, agg);
|
XContentParser aggParser = createParser(JsonXContent.jsonXContent, agg);
|
||||||
QueryParseContext parseContext = new QueryParseContext(aggParser, ParseFieldMatcher.STRICT);
|
QueryParseContext parseContext = new QueryParseContext(aggParser, ParseFieldMatcher.STRICT);
|
||||||
aggParser.nextToken();
|
aggParser.nextToken();
|
||||||
SearchContext context = createSearchContext(index);
|
SearchContext context = createSearchContext(index);
|
||||||
final AggregatorFactories factories = parser.parseAggregators(parseContext).build(context, null);
|
final AggregatorFactories factories = AggregatorFactories.parseAggregators(parseContext).build(context, null);
|
||||||
final Aggregator[] aggregators = factories.createTopLevelAggregators();
|
final Aggregator[] aggregators = factories.createTopLevelAggregators();
|
||||||
assertEquals(1, aggregators.length);
|
assertEquals(1, aggregators.length);
|
||||||
return aggregators[0].needsScores();
|
return aggregators[0].needsScores();
|
||||||
|
|
|
@ -18,14 +18,56 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.search.aggregations;
|
package org.elasticsearch.search.aggregations;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.ParseFieldMatcher;
|
||||||
|
import org.elasticsearch.common.ParsingException;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
||||||
|
import org.elasticsearch.common.xcontent.XContent;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||||
|
import org.elasticsearch.env.Environment;
|
||||||
|
import org.elasticsearch.index.query.QueryParseContext;
|
||||||
|
import org.elasticsearch.script.ScriptService;
|
||||||
|
import org.elasticsearch.search.SearchModule;
|
||||||
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilders;
|
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilders;
|
||||||
|
import org.elasticsearch.test.AbstractQueryTestCase;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import static java.util.Collections.emptyList;
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
public class AggregatorFactoriesTests extends ESTestCase {
|
public class AggregatorFactoriesTests extends ESTestCase {
|
||||||
|
private String[] currentTypes;
|
||||||
|
|
||||||
|
private NamedXContentRegistry xContentRegistry;
|
||||||
|
protected ParseFieldMatcher parseFieldMatcher;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
// we have to prefer CURRENT since with the range of versions we support
|
||||||
|
// it's rather unlikely to get the current actually.
|
||||||
|
Settings settings = Settings.builder().put("node.name", AbstractQueryTestCase.class.toString())
|
||||||
|
.put(Environment.PATH_HOME_SETTING.getKey(), createTempDir())
|
||||||
|
.put(ScriptService.SCRIPT_AUTO_RELOAD_ENABLED_SETTING.getKey(), false).build();
|
||||||
|
// create some random type with some default field, those types will
|
||||||
|
// stick around for all of the subclasses
|
||||||
|
currentTypes = new String[randomIntBetween(0, 5)];
|
||||||
|
for (int i = 0; i < currentTypes.length; i++) {
|
||||||
|
String type = randomAsciiOfLengthBetween(1, 10);
|
||||||
|
currentTypes[i] = type;
|
||||||
|
}
|
||||||
|
xContentRegistry = new NamedXContentRegistry(new SearchModule(settings, false, emptyList()).getNamedXContents());
|
||||||
|
parseFieldMatcher = ParseFieldMatcher.STRICT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void testGetAggregatorFactories_returnsUnmodifiableList() {
|
public void testGetAggregatorFactories_returnsUnmodifiableList() {
|
||||||
AggregatorFactories.Builder builder = new AggregatorFactories.Builder().addAggregator(AggregationBuilders.avg("foo"));
|
AggregatorFactories.Builder builder = new AggregatorFactories.Builder().addAggregator(AggregationBuilders.avg("foo"));
|
||||||
|
@ -42,4 +84,175 @@ public class AggregatorFactoriesTests extends ESTestCase {
|
||||||
expectThrows(UnsupportedOperationException.class,
|
expectThrows(UnsupportedOperationException.class,
|
||||||
() -> pipelineAggregatorFactories.add(PipelineAggregatorBuilders.avgBucket("bar", "path2")));
|
() -> pipelineAggregatorFactories.add(PipelineAggregatorBuilders.avgBucket("bar", "path2")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testTwoTypes() throws Exception {
|
||||||
|
XContentBuilder source = JsonXContent.contentBuilder()
|
||||||
|
.startObject()
|
||||||
|
.startObject("in_stock")
|
||||||
|
.startObject("filter")
|
||||||
|
.startObject("range")
|
||||||
|
.startObject("stock")
|
||||||
|
.field("gt", 0)
|
||||||
|
.endObject()
|
||||||
|
.endObject()
|
||||||
|
.endObject()
|
||||||
|
.startObject("terms")
|
||||||
|
.field("field", "stock")
|
||||||
|
.endObject()
|
||||||
|
.endObject()
|
||||||
|
.endObject();
|
||||||
|
XContentParser parser = createParser(source);
|
||||||
|
QueryParseContext parseContext = new QueryParseContext(parser, parseFieldMatcher);
|
||||||
|
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
|
||||||
|
Exception e = expectThrows(ParsingException.class, () -> AggregatorFactories.parseAggregators(parseContext));
|
||||||
|
assertThat(e.toString(), containsString("Found two aggregation type definitions in [in_stock]: [filter] and [terms]"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testTwoAggs() throws Exception {
|
||||||
|
assumeFalse("Test only makes sense if XContent parser doesn't have strict duplicate checks enabled",
|
||||||
|
XContent.isStrictDuplicateDetectionEnabled());
|
||||||
|
XContentBuilder source = JsonXContent.contentBuilder()
|
||||||
|
.startObject()
|
||||||
|
.startObject("by_date")
|
||||||
|
.startObject("date_histogram")
|
||||||
|
.field("field", "timestamp")
|
||||||
|
.field("interval", "month")
|
||||||
|
.endObject()
|
||||||
|
.startObject("aggs")
|
||||||
|
.startObject("tag_count")
|
||||||
|
.startObject("cardinality")
|
||||||
|
.field("field", "tag")
|
||||||
|
.endObject()
|
||||||
|
.endObject()
|
||||||
|
.endObject()
|
||||||
|
.startObject("aggs") // 2nd "aggs": illegal
|
||||||
|
.startObject("tag_count2")
|
||||||
|
.startObject("cardinality")
|
||||||
|
.field("field", "tag")
|
||||||
|
.endObject()
|
||||||
|
.endObject()
|
||||||
|
.endObject()
|
||||||
|
.endObject()
|
||||||
|
.endObject();
|
||||||
|
XContentParser parser = createParser(source);
|
||||||
|
QueryParseContext parseContext = new QueryParseContext(parser, parseFieldMatcher);
|
||||||
|
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
|
||||||
|
Exception e = expectThrows(ParsingException.class, () -> AggregatorFactories.parseAggregators(parseContext));
|
||||||
|
assertThat(e.toString(), containsString("Found two sub aggregation definitions under [by_date]"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testInvalidAggregationName() throws Exception {
|
||||||
|
Matcher matcher = Pattern.compile("[^\\[\\]>]+").matcher("");
|
||||||
|
String name;
|
||||||
|
Random rand = random();
|
||||||
|
int len = randomIntBetween(1, 5);
|
||||||
|
char[] word = new char[len];
|
||||||
|
while (true) {
|
||||||
|
for (int i = 0; i < word.length; i++) {
|
||||||
|
word[i] = (char) rand.nextInt(127);
|
||||||
|
}
|
||||||
|
name = String.valueOf(word);
|
||||||
|
if (!matcher.reset(name).matches()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XContentBuilder source = JsonXContent.contentBuilder()
|
||||||
|
.startObject()
|
||||||
|
.startObject(name)
|
||||||
|
.startObject("filter")
|
||||||
|
.startObject("range")
|
||||||
|
.startObject("stock")
|
||||||
|
.field("gt", 0)
|
||||||
|
.endObject()
|
||||||
|
.endObject()
|
||||||
|
.endObject()
|
||||||
|
.endObject()
|
||||||
|
.endObject();
|
||||||
|
XContentParser parser = createParser(source);
|
||||||
|
QueryParseContext parseContext = new QueryParseContext(parser, parseFieldMatcher);
|
||||||
|
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
|
||||||
|
Exception e = expectThrows(ParsingException.class, () -> AggregatorFactories.parseAggregators(parseContext));
|
||||||
|
assertThat(e.toString(), containsString("Invalid aggregation name [" + name + "]"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSameAggregationName() throws Exception {
|
||||||
|
assumeFalse("Test only makes sense if XContent parser doesn't have strict duplicate checks enabled",
|
||||||
|
XContent.isStrictDuplicateDetectionEnabled());
|
||||||
|
final String name = randomAsciiOfLengthBetween(1, 10);
|
||||||
|
XContentBuilder source = JsonXContent.contentBuilder()
|
||||||
|
.startObject()
|
||||||
|
.startObject(name)
|
||||||
|
.startObject("terms")
|
||||||
|
.field("field", "a")
|
||||||
|
.endObject()
|
||||||
|
.endObject()
|
||||||
|
.startObject(name)
|
||||||
|
.startObject("terms")
|
||||||
|
.field("field", "b")
|
||||||
|
.endObject()
|
||||||
|
.endObject()
|
||||||
|
.endObject();
|
||||||
|
XContentParser parser = createParser(source);
|
||||||
|
QueryParseContext parseContext = new QueryParseContext(parser, parseFieldMatcher);
|
||||||
|
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
|
||||||
|
Exception e = expectThrows(ParsingException.class, () -> AggregatorFactories.parseAggregators(parseContext));
|
||||||
|
assertThat(e.toString(), containsString("Two sibling aggregations cannot have the same name: [" + name + "]"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMissingName() throws Exception {
|
||||||
|
XContentBuilder source = JsonXContent.contentBuilder()
|
||||||
|
.startObject()
|
||||||
|
.startObject("by_date")
|
||||||
|
.startObject("date_histogram")
|
||||||
|
.field("field", "timestamp")
|
||||||
|
.field("interval", "month")
|
||||||
|
.endObject()
|
||||||
|
.startObject("aggs")
|
||||||
|
// the aggregation name is missing
|
||||||
|
//.startObject("tag_count")
|
||||||
|
.startObject("cardinality")
|
||||||
|
.field("field", "tag")
|
||||||
|
.endObject()
|
||||||
|
//.endObject()
|
||||||
|
.endObject()
|
||||||
|
.endObject()
|
||||||
|
.endObject();
|
||||||
|
XContentParser parser = createParser(source);
|
||||||
|
QueryParseContext parseContext = new QueryParseContext(parser, parseFieldMatcher);
|
||||||
|
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
|
||||||
|
Exception e = expectThrows(ParsingException.class, () -> AggregatorFactories.parseAggregators(parseContext));
|
||||||
|
assertThat(e.toString(), containsString("Expected [START_OBJECT] under [field], but got a [VALUE_STRING] in [cardinality]"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMissingType() throws Exception {
|
||||||
|
XContentBuilder source = JsonXContent.contentBuilder()
|
||||||
|
.startObject()
|
||||||
|
.startObject("by_date")
|
||||||
|
.startObject("date_histogram")
|
||||||
|
.field("field", "timestamp")
|
||||||
|
.field("interval", "month")
|
||||||
|
.endObject()
|
||||||
|
.startObject("aggs")
|
||||||
|
.startObject("tag_count")
|
||||||
|
// the aggregation type is missing
|
||||||
|
//.startObject("cardinality")
|
||||||
|
.field("field", "tag")
|
||||||
|
//.endObject()
|
||||||
|
.endObject()
|
||||||
|
.endObject()
|
||||||
|
.endObject()
|
||||||
|
.endObject();
|
||||||
|
XContentParser parser = createParser(source);
|
||||||
|
QueryParseContext parseContext = new QueryParseContext(parser, parseFieldMatcher);
|
||||||
|
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
|
||||||
|
Exception e = expectThrows(ParsingException.class, () -> AggregatorFactories.parseAggregators(parseContext));
|
||||||
|
assertThat(e.toString(), containsString("Expected [START_OBJECT] under [field], but got a [VALUE_STRING] in [tag_count]"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NamedXContentRegistry xContentRegistry() {
|
||||||
|
return xContentRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,273 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.ParseFieldMatcher;
|
|
||||||
import org.elasticsearch.common.ParsingException;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
|
||||||
import org.elasticsearch.common.xcontent.XContent;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
|
||||||
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
|
||||||
import org.elasticsearch.env.Environment;
|
|
||||||
import org.elasticsearch.index.query.QueryParseContext;
|
|
||||||
import org.elasticsearch.script.ScriptService;
|
|
||||||
import org.elasticsearch.search.SearchModule;
|
|
||||||
import org.elasticsearch.test.AbstractQueryTestCase;
|
|
||||||
import org.elasticsearch.test.ESTestCase;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
|
||||||
import static org.hamcrest.Matchers.containsString;
|
|
||||||
|
|
||||||
public class AggregatorParsingTests extends ESTestCase {
|
|
||||||
|
|
||||||
private String[] currentTypes;
|
|
||||||
|
|
||||||
protected String[] getCurrentTypes() {
|
|
||||||
return currentTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected AggregatorParsers aggParsers;
|
|
||||||
private NamedXContentRegistry xContentRegistry;
|
|
||||||
protected ParseFieldMatcher parseFieldMatcher;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Setup for the whole base test class.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
// we have to prefer CURRENT since with the range of versions we support
|
|
||||||
// it's rather unlikely to get the current actually.
|
|
||||||
Settings settings = Settings.builder().put("node.name", AbstractQueryTestCase.class.toString())
|
|
||||||
.put(Environment.PATH_HOME_SETTING.getKey(), createTempDir())
|
|
||||||
.put(ScriptService.SCRIPT_AUTO_RELOAD_ENABLED_SETTING.getKey(), false).build();
|
|
||||||
SearchModule searchModule = new SearchModule(settings, false, emptyList());
|
|
||||||
aggParsers = searchModule.getSearchRequestParsers().aggParsers;
|
|
||||||
// create some random type with some default field, those types will
|
|
||||||
// stick around for all of the subclasses
|
|
||||||
currentTypes = new String[randomIntBetween(0, 5)];
|
|
||||||
for (int i = 0; i < currentTypes.length; i++) {
|
|
||||||
String type = randomAsciiOfLengthBetween(1, 10);
|
|
||||||
currentTypes[i] = type;
|
|
||||||
}
|
|
||||||
xContentRegistry = new NamedXContentRegistry(searchModule.getNamedXContents());
|
|
||||||
parseFieldMatcher = ParseFieldMatcher.STRICT;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testTwoTypes() throws Exception {
|
|
||||||
XContentBuilder source = JsonXContent.contentBuilder()
|
|
||||||
.startObject()
|
|
||||||
.startObject("in_stock")
|
|
||||||
.startObject("filter")
|
|
||||||
.startObject("range")
|
|
||||||
.startObject("stock")
|
|
||||||
.field("gt", 0)
|
|
||||||
.endObject()
|
|
||||||
.endObject()
|
|
||||||
.endObject()
|
|
||||||
.startObject("terms")
|
|
||||||
.field("field", "stock")
|
|
||||||
.endObject()
|
|
||||||
.endObject()
|
|
||||||
.endObject();
|
|
||||||
try {
|
|
||||||
XContentParser parser = createParser(source);
|
|
||||||
QueryParseContext parseContext = new QueryParseContext(parser, parseFieldMatcher);
|
|
||||||
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
|
|
||||||
aggParsers.parseAggregators(parseContext);
|
|
||||||
fail();
|
|
||||||
} catch (ParsingException e) {
|
|
||||||
assertThat(e.toString(), containsString("Found two aggregation type definitions in [in_stock]: [filter] and [terms]"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testTwoAggs() throws Exception {
|
|
||||||
assumeFalse("Test only makes sense if XContent parser doesn't have strict duplicate checks enabled",
|
|
||||||
XContent.isStrictDuplicateDetectionEnabled());
|
|
||||||
XContentBuilder source = JsonXContent.contentBuilder()
|
|
||||||
.startObject()
|
|
||||||
.startObject("by_date")
|
|
||||||
.startObject("date_histogram")
|
|
||||||
.field("field", "timestamp")
|
|
||||||
.field("interval", "month")
|
|
||||||
.endObject()
|
|
||||||
.startObject("aggs")
|
|
||||||
.startObject("tag_count")
|
|
||||||
.startObject("cardinality")
|
|
||||||
.field("field", "tag")
|
|
||||||
.endObject()
|
|
||||||
.endObject()
|
|
||||||
.endObject()
|
|
||||||
.startObject("aggs") // 2nd "aggs": illegal
|
|
||||||
.startObject("tag_count2")
|
|
||||||
.startObject("cardinality")
|
|
||||||
.field("field", "tag")
|
|
||||||
.endObject()
|
|
||||||
.endObject()
|
|
||||||
.endObject()
|
|
||||||
.endObject()
|
|
||||||
.endObject();
|
|
||||||
try {
|
|
||||||
XContentParser parser = createParser(source);
|
|
||||||
QueryParseContext parseContext = new QueryParseContext(parser, parseFieldMatcher);
|
|
||||||
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
|
|
||||||
aggParsers.parseAggregators(parseContext);
|
|
||||||
fail();
|
|
||||||
} catch (ParsingException e) {
|
|
||||||
assertThat(e.toString(), containsString("Found two sub aggregation definitions under [by_date]"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testInvalidAggregationName() throws Exception {
|
|
||||||
Matcher matcher = Pattern.compile("[^\\[\\]>]+").matcher("");
|
|
||||||
String name;
|
|
||||||
Random rand = random();
|
|
||||||
int len = randomIntBetween(1, 5);
|
|
||||||
char[] word = new char[len];
|
|
||||||
while (true) {
|
|
||||||
for (int i = 0; i < word.length; i++) {
|
|
||||||
word[i] = (char) rand.nextInt(127);
|
|
||||||
}
|
|
||||||
name = String.valueOf(word);
|
|
||||||
if (!matcher.reset(name).matches()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
XContentBuilder source = JsonXContent.contentBuilder()
|
|
||||||
.startObject()
|
|
||||||
.startObject(name)
|
|
||||||
.startObject("filter")
|
|
||||||
.startObject("range")
|
|
||||||
.startObject("stock")
|
|
||||||
.field("gt", 0)
|
|
||||||
.endObject()
|
|
||||||
.endObject()
|
|
||||||
.endObject()
|
|
||||||
.endObject()
|
|
||||||
.endObject();
|
|
||||||
try {
|
|
||||||
XContentParser parser = createParser(source);
|
|
||||||
QueryParseContext parseContext = new QueryParseContext(parser, parseFieldMatcher);
|
|
||||||
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
|
|
||||||
aggParsers.parseAggregators(parseContext);
|
|
||||||
fail();
|
|
||||||
} catch (ParsingException e) {
|
|
||||||
assertThat(e.toString(), containsString("Invalid aggregation name [" + name + "]"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSameAggregationName() throws Exception {
|
|
||||||
assumeFalse("Test only makes sense if XContent parser doesn't have strict duplicate checks enabled",
|
|
||||||
XContent.isStrictDuplicateDetectionEnabled());
|
|
||||||
final String name = randomAsciiOfLengthBetween(1, 10);
|
|
||||||
XContentBuilder source = JsonXContent.contentBuilder()
|
|
||||||
.startObject()
|
|
||||||
.startObject(name)
|
|
||||||
.startObject("terms")
|
|
||||||
.field("field", "a")
|
|
||||||
.endObject()
|
|
||||||
.endObject()
|
|
||||||
.startObject(name)
|
|
||||||
.startObject("terms")
|
|
||||||
.field("field", "b")
|
|
||||||
.endObject()
|
|
||||||
.endObject()
|
|
||||||
.endObject();
|
|
||||||
try {
|
|
||||||
XContentParser parser = createParser(source);
|
|
||||||
QueryParseContext parseContext = new QueryParseContext(parser, parseFieldMatcher);
|
|
||||||
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
|
|
||||||
aggParsers.parseAggregators(parseContext);
|
|
||||||
fail();
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
assertThat(e.toString(), containsString("Two sibling aggregations cannot have the same name: [" + name + "]"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testMissingName() throws Exception {
|
|
||||||
XContentBuilder source = JsonXContent.contentBuilder()
|
|
||||||
.startObject()
|
|
||||||
.startObject("by_date")
|
|
||||||
.startObject("date_histogram")
|
|
||||||
.field("field", "timestamp")
|
|
||||||
.field("interval", "month")
|
|
||||||
.endObject()
|
|
||||||
.startObject("aggs")
|
|
||||||
// the aggregation name is missing
|
|
||||||
//.startObject("tag_count")
|
|
||||||
.startObject("cardinality")
|
|
||||||
.field("field", "tag")
|
|
||||||
.endObject()
|
|
||||||
//.endObject()
|
|
||||||
.endObject()
|
|
||||||
.endObject()
|
|
||||||
.endObject();
|
|
||||||
try {
|
|
||||||
XContentParser parser = createParser(source);
|
|
||||||
QueryParseContext parseContext = new QueryParseContext(parser, parseFieldMatcher);
|
|
||||||
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
|
|
||||||
aggParsers.parseAggregators(parseContext);
|
|
||||||
fail();
|
|
||||||
} catch (ParsingException e) {
|
|
||||||
// All Good
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testMissingType() throws Exception {
|
|
||||||
XContentBuilder source = JsonXContent.contentBuilder()
|
|
||||||
.startObject()
|
|
||||||
.startObject("by_date")
|
|
||||||
.startObject("date_histogram")
|
|
||||||
.field("field", "timestamp")
|
|
||||||
.field("interval", "month")
|
|
||||||
.endObject()
|
|
||||||
.startObject("aggs")
|
|
||||||
.startObject("tag_count")
|
|
||||||
// the aggregation type is missing
|
|
||||||
//.startObject("cardinality")
|
|
||||||
.field("field", "tag")
|
|
||||||
//.endObject()
|
|
||||||
.endObject()
|
|
||||||
.endObject()
|
|
||||||
.endObject()
|
|
||||||
.endObject();
|
|
||||||
try {
|
|
||||||
XContentParser parser = createParser(source);
|
|
||||||
QueryParseContext parseContext = new QueryParseContext(parser, parseFieldMatcher);
|
|
||||||
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
|
|
||||||
aggParsers.parseAggregators(parseContext);
|
|
||||||
fail();
|
|
||||||
} catch (ParsingException e) {
|
|
||||||
// All Good
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected NamedXContentRegistry xContentRegistry() {
|
|
||||||
return xContentRegistry;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -45,6 +45,7 @@ import java.util.List;
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
import static org.elasticsearch.test.EqualsHashCodeTestUtils.checkEqualsAndHashCode;
|
import static org.elasticsearch.test.EqualsHashCodeTestUtils.checkEqualsAndHashCode;
|
||||||
|
import static org.hamcrest.Matchers.hasSize;
|
||||||
|
|
||||||
public abstract class BaseAggregationTestCase<AB extends AbstractAggregationBuilder<AB>> extends ESTestCase {
|
public abstract class BaseAggregationTestCase<AB extends AbstractAggregationBuilder<AB>> extends ESTestCase {
|
||||||
|
|
||||||
|
@ -62,8 +63,6 @@ public abstract class BaseAggregationTestCase<AB extends AbstractAggregationBuil
|
||||||
}
|
}
|
||||||
|
|
||||||
private NamedWriteableRegistry namedWriteableRegistry;
|
private NamedWriteableRegistry namedWriteableRegistry;
|
||||||
|
|
||||||
protected AggregatorParsers aggParsers;
|
|
||||||
private NamedXContentRegistry xContentRegistry;
|
private NamedXContentRegistry xContentRegistry;
|
||||||
protected ParseFieldMatcher parseFieldMatcher;
|
protected ParseFieldMatcher parseFieldMatcher;
|
||||||
|
|
||||||
|
@ -86,7 +85,6 @@ public abstract class BaseAggregationTestCase<AB extends AbstractAggregationBuil
|
||||||
entries.addAll(searchModule.getNamedWriteables());
|
entries.addAll(searchModule.getNamedWriteables());
|
||||||
namedWriteableRegistry = new NamedWriteableRegistry(entries);
|
namedWriteableRegistry = new NamedWriteableRegistry(entries);
|
||||||
xContentRegistry = new NamedXContentRegistry(searchModule.getNamedXContents());
|
xContentRegistry = new NamedXContentRegistry(searchModule.getNamedXContents());
|
||||||
aggParsers = searchModule.getSearchRequestParsers().aggParsers;
|
|
||||||
//create some random type with some default field, those types will stick around for all of the subclasses
|
//create some random type with some default field, those types will stick around for all of the subclasses
|
||||||
currentTypes = new String[randomIntBetween(0, 5)];
|
currentTypes = new String[randomIntBetween(0, 5)];
|
||||||
for (int i = 0; i < currentTypes.length; i++) {
|
for (int i = 0; i < currentTypes.length; i++) {
|
||||||
|
@ -116,29 +114,27 @@ public abstract class BaseAggregationTestCase<AB extends AbstractAggregationBuil
|
||||||
factoriesBuilder.toXContent(builder, ToXContent.EMPTY_PARAMS);
|
factoriesBuilder.toXContent(builder, ToXContent.EMPTY_PARAMS);
|
||||||
XContentBuilder shuffled = shuffleXContent(builder);
|
XContentBuilder shuffled = shuffleXContent(builder);
|
||||||
XContentParser parser = createParser(shuffled);
|
XContentParser parser = createParser(shuffled);
|
||||||
QueryParseContext parseContext = new QueryParseContext(parser, parseFieldMatcher);
|
AggregationBuilder newAgg = parse(parser);
|
||||||
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
|
|
||||||
assertSame(XContentParser.Token.FIELD_NAME, parser.nextToken());
|
|
||||||
assertEquals(testAgg.name, parser.currentName());
|
|
||||||
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
|
|
||||||
assertSame(XContentParser.Token.FIELD_NAME, parser.nextToken());
|
|
||||||
assertEquals(testAgg.type.name(), parser.currentName());
|
|
||||||
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
|
|
||||||
AggregationBuilder newAgg = aggParsers.parser(testAgg.getType()).parse(testAgg.name, parseContext);
|
|
||||||
assertSame(XContentParser.Token.END_OBJECT, parser.currentToken());
|
|
||||||
assertSame(XContentParser.Token.END_OBJECT, parser.nextToken());
|
|
||||||
assertSame(XContentParser.Token.END_OBJECT, parser.nextToken());
|
|
||||||
assertNull(parser.nextToken());
|
|
||||||
assertNotNull(newAgg);
|
|
||||||
assertNotSame(newAgg, testAgg);
|
assertNotSame(newAgg, testAgg);
|
||||||
assertEquals(testAgg, newAgg);
|
assertEquals(testAgg, newAgg);
|
||||||
assertEquals(testAgg.hashCode(), newAgg.hashCode());
|
assertEquals(testAgg.hashCode(), newAgg.hashCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected AggregationBuilder parse(XContentParser parser) throws IOException {
|
||||||
|
QueryParseContext parseContext = new QueryParseContext(parser, parseFieldMatcher);
|
||||||
|
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
|
||||||
|
AggregatorFactories.Builder parsed = AggregatorFactories.parseAggregators(parseContext);
|
||||||
|
assertThat(parsed.getAggregatorFactories(), hasSize(1));
|
||||||
|
assertThat(parsed.getPipelineAggregatorFactories(), hasSize(0));
|
||||||
|
AggregationBuilder newAgg = parsed.getAggregatorFactories().get(0);
|
||||||
|
assertNull(parser.nextToken());
|
||||||
|
assertNotNull(newAgg);
|
||||||
|
return newAgg;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test serialization and deserialization of the test AggregatorFactory.
|
* Test serialization and deserialization of the test AggregatorFactory.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public void testSerialization() throws IOException {
|
public void testSerialization() throws IOException {
|
||||||
AB testAgg = createTestAggregatorBuilder();
|
AB testAgg = createTestAggregatorBuilder();
|
||||||
try (BytesStreamOutput output = new BytesStreamOutput()) {
|
try (BytesStreamOutput output = new BytesStreamOutput()) {
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.elasticsearch.common.io.stream.NamedWriteableAwareStreamInput;
|
||||||
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
|
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||||
|
@ -46,6 +47,7 @@ import java.util.List;
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
import static org.elasticsearch.test.EqualsHashCodeTestUtils.checkEqualsAndHashCode;
|
import static org.elasticsearch.test.EqualsHashCodeTestUtils.checkEqualsAndHashCode;
|
||||||
|
import static org.hamcrest.Matchers.hasSize;
|
||||||
|
|
||||||
public abstract class BasePipelineAggregationTestCase<AF extends AbstractPipelineAggregationBuilder<AF>> extends ESTestCase {
|
public abstract class BasePipelineAggregationTestCase<AF extends AbstractPipelineAggregationBuilder<AF>> extends ESTestCase {
|
||||||
|
|
||||||
|
@ -62,8 +64,8 @@ public abstract class BasePipelineAggregationTestCase<AF extends AbstractPipelin
|
||||||
}
|
}
|
||||||
|
|
||||||
private NamedWriteableRegistry namedWriteableRegistry;
|
private NamedWriteableRegistry namedWriteableRegistry;
|
||||||
|
private NamedXContentRegistry xContentRegistry;
|
||||||
|
|
||||||
protected AggregatorParsers aggParsers;
|
|
||||||
protected ParseFieldMatcher parseFieldMatcher;
|
protected ParseFieldMatcher parseFieldMatcher;
|
||||||
|
|
||||||
protected abstract AF createTestAggregatorFactory();
|
protected abstract AF createTestAggregatorFactory();
|
||||||
|
@ -84,7 +86,7 @@ public abstract class BasePipelineAggregationTestCase<AF extends AbstractPipelin
|
||||||
entries.addAll(indicesModule.getNamedWriteables());
|
entries.addAll(indicesModule.getNamedWriteables());
|
||||||
entries.addAll(searchModule.getNamedWriteables());
|
entries.addAll(searchModule.getNamedWriteables());
|
||||||
namedWriteableRegistry = new NamedWriteableRegistry(entries);
|
namedWriteableRegistry = new NamedWriteableRegistry(entries);
|
||||||
aggParsers = searchModule.getSearchRequestParsers().aggParsers;
|
xContentRegistry = new NamedXContentRegistry(searchModule.getNamedXContents());
|
||||||
//create some random type with some default field, those types will stick around for all of the subclasses
|
//create some random type with some default field, those types will stick around for all of the subclasses
|
||||||
currentTypes = new String[randomIntBetween(0, 5)];
|
currentTypes = new String[randomIntBetween(0, 5)];
|
||||||
for (int i = 0; i < currentTypes.length; i++) {
|
for (int i = 0; i < currentTypes.length; i++) {
|
||||||
|
@ -110,32 +112,29 @@ public abstract class BasePipelineAggregationTestCase<AF extends AbstractPipelin
|
||||||
factoriesBuilder.toXContent(builder, ToXContent.EMPTY_PARAMS);
|
factoriesBuilder.toXContent(builder, ToXContent.EMPTY_PARAMS);
|
||||||
XContentBuilder shuffled = shuffleXContent(builder);
|
XContentBuilder shuffled = shuffleXContent(builder);
|
||||||
XContentParser parser = createParser(shuffled);
|
XContentParser parser = createParser(shuffled);
|
||||||
QueryParseContext parseContext = new QueryParseContext(parser, parseFieldMatcher);
|
|
||||||
String contentString = factoriesBuilder.toString();
|
String contentString = factoriesBuilder.toString();
|
||||||
logger.info("Content string: {}", contentString);
|
logger.info("Content string: {}", contentString);
|
||||||
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
|
PipelineAggregationBuilder newAgg = parse(parser);
|
||||||
assertSame(XContentParser.Token.FIELD_NAME, parser.nextToken());
|
|
||||||
assertEquals(testAgg.getName(), parser.currentName());
|
|
||||||
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
|
|
||||||
assertSame(XContentParser.Token.FIELD_NAME, parser.nextToken());
|
|
||||||
assertEquals(testAgg.type(), parser.currentName());
|
|
||||||
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
|
|
||||||
PipelineAggregationBuilder newAgg = aggParsers.pipelineParser(testAgg.getWriteableName())
|
|
||||||
.parse(testAgg.getName(), parseContext);
|
|
||||||
assertSame(XContentParser.Token.END_OBJECT, parser.currentToken());
|
|
||||||
assertSame(XContentParser.Token.END_OBJECT, parser.nextToken());
|
|
||||||
assertSame(XContentParser.Token.END_OBJECT, parser.nextToken());
|
|
||||||
assertNull(parser.nextToken());
|
|
||||||
assertNotNull(newAgg);
|
|
||||||
assertNotSame(newAgg, testAgg);
|
assertNotSame(newAgg, testAgg);
|
||||||
assertEquals(testAgg, newAgg);
|
assertEquals(testAgg, newAgg);
|
||||||
assertEquals(testAgg.hashCode(), newAgg.hashCode());
|
assertEquals(testAgg.hashCode(), newAgg.hashCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected PipelineAggregationBuilder parse(XContentParser parser) throws IOException {
|
||||||
|
QueryParseContext parseContext = new QueryParseContext(parser, parseFieldMatcher);
|
||||||
|
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
|
||||||
|
AggregatorFactories.Builder parsed = AggregatorFactories.parseAggregators(parseContext);
|
||||||
|
assertThat(parsed.getAggregatorFactories(), hasSize(0));
|
||||||
|
assertThat(parsed.getPipelineAggregatorFactories(), hasSize(1));
|
||||||
|
PipelineAggregationBuilder newAgg = parsed.getPipelineAggregatorFactories().get(0);
|
||||||
|
assertNull(parser.nextToken());
|
||||||
|
assertNotNull(newAgg);
|
||||||
|
return newAgg;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test serialization and deserialization of the test AggregatorFactory.
|
* Test serialization and deserialization of the test AggregatorFactory.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public void testSerialization() throws IOException {
|
public void testSerialization() throws IOException {
|
||||||
AF testAgg = createTestAggregatorFactory();
|
AF testAgg = createTestAggregatorFactory();
|
||||||
try (BytesStreamOutput output = new BytesStreamOutput()) {
|
try (BytesStreamOutput output = new BytesStreamOutput()) {
|
||||||
|
@ -199,4 +198,9 @@ public abstract class BasePipelineAggregationTestCase<AF extends AbstractPipelin
|
||||||
return INT_FIELD_NAME;
|
return INT_FIELD_NAME;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NamedXContentRegistry xContentRegistry() {
|
||||||
|
return xContentRegistry;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||||
import org.elasticsearch.index.query.QueryParseContext;
|
import org.elasticsearch.index.query.QueryParseContext;
|
||||||
import org.elasticsearch.script.Script;
|
import org.elasticsearch.script.Script;
|
||||||
import org.elasticsearch.search.aggregations.AggregationInitializationException;
|
import org.elasticsearch.search.aggregations.AggregationInitializationException;
|
||||||
|
import org.elasticsearch.search.aggregations.AggregatorFactories;
|
||||||
import org.elasticsearch.search.aggregations.BaseAggregationTestCase;
|
import org.elasticsearch.search.aggregations.BaseAggregationTestCase;
|
||||||
import org.elasticsearch.search.aggregations.metrics.tophits.TopHitsAggregationBuilder;
|
import org.elasticsearch.search.aggregations.metrics.tophits.TopHitsAggregationBuilder;
|
||||||
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
|
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
|
||||||
|
@ -185,15 +186,11 @@ public class TopHitsTests extends BaseAggregationTestCase<TopHitsAggregationBuil
|
||||||
" }\n" +
|
" }\n" +
|
||||||
" }\n" +
|
" }\n" +
|
||||||
"}";
|
"}";
|
||||||
try {
|
|
||||||
XContentParser parser = createParser(JsonXContent.jsonXContent, source);
|
XContentParser parser = createParser(JsonXContent.jsonXContent, source);
|
||||||
QueryParseContext parseContext = new QueryParseContext(parser, parseFieldMatcher);
|
QueryParseContext parseContext = new QueryParseContext(parser, parseFieldMatcher);
|
||||||
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
|
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
|
||||||
aggParsers.parseAggregators(parseContext);
|
Exception e = expectThrows(AggregationInitializationException.class, () -> AggregatorFactories.parseAggregators(parseContext));
|
||||||
fail();
|
|
||||||
} catch (AggregationInitializationException e) {
|
|
||||||
assertThat(e.toString(), containsString("Aggregator [top_tags_hits] of type [top_hits] cannot accept sub-aggregations"));
|
assertThat(e.toString(), containsString("Aggregator [top_tags_hits] of type [top_hits] cannot accept sub-aggregations"));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,8 @@
|
||||||
|
|
||||||
package org.elasticsearch.search.aggregations.pipeline.bucketmetrics;
|
package org.elasticsearch.search.aggregations.pipeline.bucketmetrics;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
|
||||||
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
|
||||||
import org.elasticsearch.index.query.QueryParseContext;
|
|
||||||
import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.stats.extended.ExtendedStatsBucketPipelineAggregationBuilder;
|
import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.stats.extended.ExtendedStatsBucketPipelineAggregationBuilder;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
@ -39,20 +37,18 @@ public class ExtendedStatsBucketTests extends AbstractBucketMetricsTestCase<Exte
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSigmaFromInt() throws Exception {
|
public void testSigmaFromInt() throws Exception {
|
||||||
String content = XContentFactory.jsonBuilder()
|
XContentBuilder content = XContentFactory.jsonBuilder()
|
||||||
.startObject()
|
.startObject()
|
||||||
|
.startObject("name")
|
||||||
|
.startObject("extended_stats_bucket")
|
||||||
.field("sigma", 5)
|
.field("sigma", 5)
|
||||||
.field("buckets_path", "test")
|
.field("buckets_path", "test")
|
||||||
.endObject()
|
.endObject()
|
||||||
.string();
|
.endObject()
|
||||||
|
.endObject();
|
||||||
|
|
||||||
XContentParser parser = createParser(JsonXContent.jsonXContent, content);
|
ExtendedStatsBucketPipelineAggregationBuilder builder = (ExtendedStatsBucketPipelineAggregationBuilder) parse(
|
||||||
QueryParseContext parseContext = new QueryParseContext(parser, parseFieldMatcher);
|
createParser(content));
|
||||||
parser.nextToken(); // skip object start
|
|
||||||
|
|
||||||
ExtendedStatsBucketPipelineAggregationBuilder builder = (ExtendedStatsBucketPipelineAggregationBuilder) aggParsers
|
|
||||||
.pipelineParser(ExtendedStatsBucketPipelineAggregationBuilder.NAME)
|
|
||||||
.parse("test", parseContext);
|
|
||||||
|
|
||||||
assertThat(builder.sigma(), equalTo(5.0));
|
assertThat(builder.sigma(), equalTo(5.0));
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,8 @@
|
||||||
|
|
||||||
package org.elasticsearch.search.aggregations.pipeline.bucketmetrics;
|
package org.elasticsearch.search.aggregations.pipeline.bucketmetrics;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
|
||||||
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
|
||||||
import org.elasticsearch.index.query.QueryParseContext;
|
|
||||||
import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.percentile.PercentilesBucketPipelineAggregationBuilder;
|
import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.percentile.PercentilesBucketPipelineAggregationBuilder;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
@ -44,20 +42,17 @@ public class PercentilesBucketTests extends AbstractBucketMetricsTestCase<Percen
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPercentsFromMixedArray() throws Exception {
|
public void testPercentsFromMixedArray() throws Exception {
|
||||||
String content = XContentFactory.jsonBuilder()
|
XContentBuilder content = XContentFactory.jsonBuilder()
|
||||||
.startObject()
|
.startObject()
|
||||||
|
.startObject("name")
|
||||||
|
.startObject("percentiles_bucket")
|
||||||
.field("buckets_path", "test")
|
.field("buckets_path", "test")
|
||||||
.array("percents", 0, 20.0, 50, 75.99)
|
.array("percents", 0, 20.0, 50, 75.99)
|
||||||
.endObject()
|
.endObject()
|
||||||
.string();
|
.endObject()
|
||||||
|
.endObject();
|
||||||
|
|
||||||
XContentParser parser = createParser(JsonXContent.jsonXContent, content);
|
PercentilesBucketPipelineAggregationBuilder builder = (PercentilesBucketPipelineAggregationBuilder) parse(createParser(content));
|
||||||
QueryParseContext parseContext = new QueryParseContext(parser, parseFieldMatcher);
|
|
||||||
parser.nextToken(); // skip object start
|
|
||||||
|
|
||||||
PercentilesBucketPipelineAggregationBuilder builder = (PercentilesBucketPipelineAggregationBuilder) aggParsers
|
|
||||||
.pipelineParser(PercentilesBucketPipelineAggregationBuilder.NAME)
|
|
||||||
.parse("test", parseContext);
|
|
||||||
|
|
||||||
assertThat(builder.percents(), equalTo(new double[]{0.0, 20.0, 50.0, 75.99}));
|
assertThat(builder.percents(), equalTo(new double[]{0.0, 20.0, 50.0, 75.99}));
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,9 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.search.aggregations.pipeline.moving.avg;
|
package org.elasticsearch.search.aggregations.pipeline.moving.avg;
|
||||||
|
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
|
||||||
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||||
import org.elasticsearch.index.query.QueryParseContext;
|
|
||||||
import org.elasticsearch.search.aggregations.BasePipelineAggregationTestCase;
|
import org.elasticsearch.search.aggregations.BasePipelineAggregationTestCase;
|
||||||
import org.elasticsearch.search.aggregations.PipelineAggregationBuilder;
|
import org.elasticsearch.search.aggregations.PipelineAggregationBuilder;
|
||||||
import org.elasticsearch.search.aggregations.pipeline.BucketHelpers.GapPolicy;
|
import org.elasticsearch.search.aggregations.pipeline.BucketHelpers.GapPolicy;
|
||||||
|
@ -33,8 +31,6 @@ import org.elasticsearch.search.aggregations.pipeline.movavg.models.HoltWintersM
|
||||||
import org.elasticsearch.search.aggregations.pipeline.movavg.models.LinearModel;
|
import org.elasticsearch.search.aggregations.pipeline.movavg.models.LinearModel;
|
||||||
import org.elasticsearch.search.aggregations.pipeline.movavg.models.SimpleModel;
|
import org.elasticsearch.search.aggregations.pipeline.movavg.models.SimpleModel;
|
||||||
|
|
||||||
;
|
|
||||||
|
|
||||||
public class MovAvgTests extends BasePipelineAggregationTestCase<MovAvgPipelineAggregationBuilder> {
|
public class MovAvgTests extends BasePipelineAggregationTestCase<MovAvgPipelineAggregationBuilder> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -107,21 +103,7 @@ public class MovAvgTests extends BasePipelineAggregationTestCase<MovAvgPipelineA
|
||||||
" }" +
|
" }" +
|
||||||
" }" +
|
" }" +
|
||||||
"}";
|
"}";
|
||||||
XContentParser parser = createParser(JsonXContent.jsonXContent, json);
|
PipelineAggregationBuilder newAgg = parse(createParser(JsonXContent.jsonXContent, json));
|
||||||
QueryParseContext parseContext = new QueryParseContext(parser, parseFieldMatcher);
|
|
||||||
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
|
|
||||||
assertSame(XContentParser.Token.FIELD_NAME, parser.nextToken());
|
|
||||||
assertEquals(expected.getName(), parser.currentName());
|
|
||||||
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
|
|
||||||
assertSame(XContentParser.Token.FIELD_NAME, parser.nextToken());
|
|
||||||
assertEquals(expected.type(), parser.currentName());
|
|
||||||
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
|
|
||||||
PipelineAggregationBuilder newAgg = aggParsers.pipelineParser(expected.getWriteableName()).parse(expected.getName(), parseContext);
|
|
||||||
assertSame(XContentParser.Token.END_OBJECT, parser.currentToken());
|
|
||||||
assertSame(XContentParser.Token.END_OBJECT, parser.nextToken());
|
|
||||||
assertSame(XContentParser.Token.END_OBJECT, parser.nextToken());
|
|
||||||
assertNull(parser.nextToken());
|
|
||||||
assertNotNull(newAgg);
|
|
||||||
assertNotSame(newAgg, expected);
|
assertNotSame(newAgg, expected);
|
||||||
assertEquals(expected, newAgg);
|
assertEquals(expected, newAgg);
|
||||||
assertEquals(expected.hashCode(), newAgg.hashCode());
|
assertEquals(expected.hashCode(), newAgg.hashCode());
|
||||||
|
|
|
@ -75,8 +75,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase {
|
||||||
parser.nextToken(); // sometimes we move it on the START_OBJECT to
|
parser.nextToken(); // sometimes we move it on the START_OBJECT to
|
||||||
// test the embedded case
|
// test the embedded case
|
||||||
}
|
}
|
||||||
SearchSourceBuilder newBuilder = SearchSourceBuilder.fromXContent(parseContext, searchRequestParsers.aggParsers,
|
SearchSourceBuilder newBuilder = SearchSourceBuilder.fromXContent(parseContext, searchRequestParsers.suggesters);
|
||||||
searchRequestParsers.suggesters);
|
|
||||||
assertNull(parser.nextToken());
|
assertNull(parser.nextToken());
|
||||||
assertEquals(testBuilder, newBuilder);
|
assertEquals(testBuilder, newBuilder);
|
||||||
assertEquals(testBuilder.hashCode(), newBuilder.hashCode());
|
assertEquals(testBuilder.hashCode(), newBuilder.hashCode());
|
||||||
|
@ -114,7 +113,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase {
|
||||||
String restContent = " { \"_source\": { \"includes\": \"include\", \"excludes\": \"*.field2\"}}";
|
String restContent = " { \"_source\": { \"includes\": \"include\", \"excludes\": \"*.field2\"}}";
|
||||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) {
|
try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) {
|
||||||
SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser),
|
SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser),
|
||||||
searchRequestParsers.aggParsers, searchRequestParsers.suggesters);
|
searchRequestParsers.suggesters);
|
||||||
assertArrayEquals(new String[]{"*.field2"}, searchSourceBuilder.fetchSource().excludes());
|
assertArrayEquals(new String[]{"*.field2"}, searchSourceBuilder.fetchSource().excludes());
|
||||||
assertArrayEquals(new String[]{"include"}, searchSourceBuilder.fetchSource().includes());
|
assertArrayEquals(new String[]{"include"}, searchSourceBuilder.fetchSource().includes());
|
||||||
}
|
}
|
||||||
|
@ -123,7 +122,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase {
|
||||||
String restContent = " { \"_source\": false}";
|
String restContent = " { \"_source\": false}";
|
||||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) {
|
try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) {
|
||||||
SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser),
|
SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser),
|
||||||
searchRequestParsers.aggParsers, searchRequestParsers.suggesters);
|
searchRequestParsers.suggesters);
|
||||||
assertArrayEquals(new String[]{}, searchSourceBuilder.fetchSource().excludes());
|
assertArrayEquals(new String[]{}, searchSourceBuilder.fetchSource().excludes());
|
||||||
assertArrayEquals(new String[]{}, searchSourceBuilder.fetchSource().includes());
|
assertArrayEquals(new String[]{}, searchSourceBuilder.fetchSource().includes());
|
||||||
assertFalse(searchSourceBuilder.fetchSource().fetchSource());
|
assertFalse(searchSourceBuilder.fetchSource().fetchSource());
|
||||||
|
@ -146,7 +145,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase {
|
||||||
" } }";
|
" } }";
|
||||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) {
|
try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) {
|
||||||
ParsingException e = expectThrows(ParsingException.class, () -> SearchSourceBuilder.fromXContent(createParseContext(parser),
|
ParsingException e = expectThrows(ParsingException.class, () -> SearchSourceBuilder.fromXContent(createParseContext(parser),
|
||||||
searchRequestParsers.aggParsers, searchRequestParsers.suggesters));
|
searchRequestParsers.suggesters));
|
||||||
assertEquals("[multi_match] malformed query, expected [END_OBJECT] but found [FIELD_NAME]", e.getMessage());
|
assertEquals("[multi_match] malformed query, expected [END_OBJECT] but found [FIELD_NAME]", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,7 +155,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase {
|
||||||
String restContent = " { \"sort\": \"foo\"}";
|
String restContent = " { \"sort\": \"foo\"}";
|
||||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) {
|
try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) {
|
||||||
SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser),
|
SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser),
|
||||||
searchRequestParsers.aggParsers, searchRequestParsers.suggesters);
|
searchRequestParsers.suggesters);
|
||||||
assertEquals(1, searchSourceBuilder.sorts().size());
|
assertEquals(1, searchSourceBuilder.sorts().size());
|
||||||
assertEquals(new FieldSortBuilder("foo"), searchSourceBuilder.sorts().get(0));
|
assertEquals(new FieldSortBuilder("foo"), searchSourceBuilder.sorts().get(0));
|
||||||
}
|
}
|
||||||
|
@ -172,7 +171,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase {
|
||||||
" ]}";
|
" ]}";
|
||||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) {
|
try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) {
|
||||||
SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser),
|
SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser),
|
||||||
searchRequestParsers.aggParsers, searchRequestParsers.suggesters);
|
searchRequestParsers.suggesters);
|
||||||
assertEquals(5, searchSourceBuilder.sorts().size());
|
assertEquals(5, searchSourceBuilder.sorts().size());
|
||||||
assertEquals(new FieldSortBuilder("post_date"), searchSourceBuilder.sorts().get(0));
|
assertEquals(new FieldSortBuilder("post_date"), searchSourceBuilder.sorts().get(0));
|
||||||
assertEquals(new FieldSortBuilder("user"), searchSourceBuilder.sorts().get(1));
|
assertEquals(new FieldSortBuilder("user"), searchSourceBuilder.sorts().get(1));
|
||||||
|
@ -196,7 +195,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase {
|
||||||
"}\n";
|
"}\n";
|
||||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) {
|
try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) {
|
||||||
SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser),
|
SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser),
|
||||||
searchRequestParsers.aggParsers, searchRequestParsers.suggesters);
|
searchRequestParsers.suggesters);
|
||||||
assertEquals(1, searchSourceBuilder.aggregations().count());
|
assertEquals(1, searchSourceBuilder.aggregations().count());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,7 +211,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase {
|
||||||
"}\n";
|
"}\n";
|
||||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) {
|
try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) {
|
||||||
SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser),
|
SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser),
|
||||||
searchRequestParsers.aggParsers, searchRequestParsers.suggesters);
|
searchRequestParsers.suggesters);
|
||||||
assertEquals(1, searchSourceBuilder.aggregations().count());
|
assertEquals(1, searchSourceBuilder.aggregations().count());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,7 +237,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase {
|
||||||
"}\n";
|
"}\n";
|
||||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) {
|
try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) {
|
||||||
SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser),
|
SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser),
|
||||||
searchRequestParsers.aggParsers, searchRequestParsers.suggesters);
|
searchRequestParsers.suggesters);
|
||||||
assertEquals(1, searchSourceBuilder.rescores().size());
|
assertEquals(1, searchSourceBuilder.rescores().size());
|
||||||
assertEquals(new QueryRescorerBuilder(QueryBuilders.matchQuery("content", "baz")).windowSize(50),
|
assertEquals(new QueryRescorerBuilder(QueryBuilders.matchQuery("content", "baz")).windowSize(50),
|
||||||
searchSourceBuilder.rescores().get(0));
|
searchSourceBuilder.rescores().get(0));
|
||||||
|
@ -261,7 +260,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase {
|
||||||
"}\n";
|
"}\n";
|
||||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) {
|
try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) {
|
||||||
SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser),
|
SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser),
|
||||||
searchRequestParsers.aggParsers, searchRequestParsers.suggesters);
|
searchRequestParsers.suggesters);
|
||||||
assertEquals(1, searchSourceBuilder.rescores().size());
|
assertEquals(1, searchSourceBuilder.rescores().size());
|
||||||
assertEquals(new QueryRescorerBuilder(QueryBuilders.matchQuery("content", "baz")).windowSize(50),
|
assertEquals(new QueryRescorerBuilder(QueryBuilders.matchQuery("content", "baz")).windowSize(50),
|
||||||
searchSourceBuilder.rescores().get(0));
|
searchSourceBuilder.rescores().get(0));
|
||||||
|
@ -274,7 +273,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase {
|
||||||
final String query = "{ \"query\": { \"match_all\": {}}, \"timeout\": \"" + timeout + "\"}";
|
final String query = "{ \"query\": { \"match_all\": {}}, \"timeout\": \"" + timeout + "\"}";
|
||||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, query)) {
|
try (XContentParser parser = createParser(JsonXContent.jsonXContent, query)) {
|
||||||
final SearchSourceBuilder builder = SearchSourceBuilder.fromXContent(createParseContext(parser),
|
final SearchSourceBuilder builder = SearchSourceBuilder.fromXContent(createParseContext(parser),
|
||||||
searchRequestParsers.aggParsers, searchRequestParsers.suggesters);
|
searchRequestParsers.suggesters);
|
||||||
assertThat(builder.timeout(), equalTo(TimeValue.parseTimeValue(timeout, null, "timeout")));
|
assertThat(builder.timeout(), equalTo(TimeValue.parseTimeValue(timeout, null, "timeout")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -283,11 +282,8 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase {
|
||||||
final int timeout = randomIntBetween(1, 1024);
|
final int timeout = randomIntBetween(1, 1024);
|
||||||
final String query = "{ \"query\": { \"match_all\": {}}, \"timeout\": \"" + timeout + "\"}";
|
final String query = "{ \"query\": { \"match_all\": {}}, \"timeout\": \"" + timeout + "\"}";
|
||||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, query)) {
|
try (XContentParser parser = createParser(JsonXContent.jsonXContent, query)) {
|
||||||
final ElasticsearchParseException e =
|
final ElasticsearchParseException e = expectThrows(ElasticsearchParseException.class, () -> SearchSourceBuilder.fromXContent(
|
||||||
expectThrows(
|
createParseContext(parser), searchRequestParsers.suggesters));
|
||||||
ElasticsearchParseException.class,
|
|
||||||
() -> SearchSourceBuilder.fromXContent(createParseContext(parser),
|
|
||||||
searchRequestParsers.aggParsers, searchRequestParsers.suggesters));
|
|
||||||
assertThat(e, hasToString(containsString("unit is missing or unrecognized")));
|
assertThat(e, hasToString(containsString("unit is missing or unrecognized")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -320,7 +316,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase {
|
||||||
String restContent = " { \"indices_boost\": {\"foo\": 1.0, \"bar\": 2.0}}";
|
String restContent = " { \"indices_boost\": {\"foo\": 1.0, \"bar\": 2.0}}";
|
||||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) {
|
try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) {
|
||||||
SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser),
|
SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser),
|
||||||
searchRequestParsers.aggParsers, searchRequestParsers.suggesters);
|
searchRequestParsers.suggesters);
|
||||||
assertEquals(2, searchSourceBuilder.indexBoosts().size());
|
assertEquals(2, searchSourceBuilder.indexBoosts().size());
|
||||||
assertEquals(new SearchSourceBuilder.IndexBoost("foo", 1.0f), searchSourceBuilder.indexBoosts().get(0));
|
assertEquals(new SearchSourceBuilder.IndexBoost("foo", 1.0f), searchSourceBuilder.indexBoosts().get(0));
|
||||||
assertEquals(new SearchSourceBuilder.IndexBoost("bar", 2.0f), searchSourceBuilder.indexBoosts().get(1));
|
assertEquals(new SearchSourceBuilder.IndexBoost("bar", 2.0f), searchSourceBuilder.indexBoosts().get(1));
|
||||||
|
@ -337,7 +333,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase {
|
||||||
" ]}";
|
" ]}";
|
||||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) {
|
try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) {
|
||||||
SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser),
|
SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser),
|
||||||
searchRequestParsers.aggParsers, searchRequestParsers.suggesters);
|
searchRequestParsers.suggesters);
|
||||||
assertEquals(3, searchSourceBuilder.indexBoosts().size());
|
assertEquals(3, searchSourceBuilder.indexBoosts().size());
|
||||||
assertEquals(new SearchSourceBuilder.IndexBoost("foo", 1.0f), searchSourceBuilder.indexBoosts().get(0));
|
assertEquals(new SearchSourceBuilder.IndexBoost("foo", 1.0f), searchSourceBuilder.indexBoosts().get(0));
|
||||||
assertEquals(new SearchSourceBuilder.IndexBoost("bar", 2.0f), searchSourceBuilder.indexBoosts().get(1));
|
assertEquals(new SearchSourceBuilder.IndexBoost("bar", 2.0f), searchSourceBuilder.indexBoosts().get(1));
|
||||||
|
@ -385,7 +381,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase {
|
||||||
private void assertIndicesBoostParseErrorMessage(String restContent, String expectedErrorMessage) throws IOException {
|
private void assertIndicesBoostParseErrorMessage(String restContent, String expectedErrorMessage) throws IOException {
|
||||||
try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) {
|
try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) {
|
||||||
ParsingException e = expectThrows(ParsingException.class, () -> SearchSourceBuilder.fromXContent(createParseContext(parser),
|
ParsingException e = expectThrows(ParsingException.class, () -> SearchSourceBuilder.fromXContent(createParseContext(parser),
|
||||||
searchRequestParsers.aggParsers, searchRequestParsers.suggesters));
|
searchRequestParsers.suggesters));
|
||||||
assertEquals(expectedErrorMessage, e.getMessage());
|
assertEquals(expectedErrorMessage, e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,8 +88,7 @@ public class TransportSearchTemplateAction extends HandledTransportAction<Search
|
||||||
|
|
||||||
try (XContentParser parser = XContentFactory.xContent(source).createParser(xContentRegistry, source)) {
|
try (XContentParser parser = XContentFactory.xContent(source).createParser(xContentRegistry, source)) {
|
||||||
SearchSourceBuilder builder = SearchSourceBuilder.searchSource();
|
SearchSourceBuilder builder = SearchSourceBuilder.searchSource();
|
||||||
builder.parseXContent(new QueryParseContext(parser, parseFieldMatcher),
|
builder.parseXContent(new QueryParseContext(parser, parseFieldMatcher), searchRequestParsers.suggesters);
|
||||||
searchRequestParsers.aggParsers, searchRequestParsers.suggesters);
|
|
||||||
builder.explain(request.isExplain());
|
builder.explain(request.isExplain());
|
||||||
builder.profile(request.isProfile());
|
builder.profile(request.isProfile());
|
||||||
searchRequest.source(builder);
|
searchRequest.source(builder);
|
||||||
|
|
|
@ -156,9 +156,8 @@ public class TransportMultiPercolateAction extends HandledTransportAction<MultiP
|
||||||
PercolateRequest percolateRequest = multiPercolateRequest.requests().get(i);
|
PercolateRequest percolateRequest = multiPercolateRequest.requests().get(i);
|
||||||
BytesReference docSource = getResponseSources.get(i);
|
BytesReference docSource = getResponseSources.get(i);
|
||||||
try {
|
try {
|
||||||
SearchRequest searchRequest = TransportPercolateAction.createSearchRequest(
|
SearchRequest searchRequest = TransportPercolateAction.createSearchRequest(percolateRequest, docSource, xContentRegistry,
|
||||||
percolateRequest, docSource,
|
parseFieldMatcher);
|
||||||
searchRequestParsers.aggParsers, xContentRegistry, parseFieldMatcher);
|
|
||||||
multiSearchRequest.add(searchRequest);
|
multiSearchRequest.add(searchRequest);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
preFailures.put(i, new MultiPercolateResponse.Item(e));
|
preFailures.put(i, new MultiPercolateResponse.Item(e));
|
||||||
|
|
|
@ -48,7 +48,6 @@ import org.elasticsearch.index.query.QueryParseContext;
|
||||||
import org.elasticsearch.search.SearchHit;
|
import org.elasticsearch.search.SearchHit;
|
||||||
import org.elasticsearch.search.SearchHits;
|
import org.elasticsearch.search.SearchHits;
|
||||||
import org.elasticsearch.search.SearchRequestParsers;
|
import org.elasticsearch.search.SearchRequestParsers;
|
||||||
import org.elasticsearch.search.aggregations.AggregatorParsers;
|
|
||||||
import org.elasticsearch.search.aggregations.InternalAggregations;
|
import org.elasticsearch.search.aggregations.InternalAggregations;
|
||||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
|
@ -103,8 +102,7 @@ public class TransportPercolateAction extends HandledTransportAction<PercolateRe
|
||||||
private void innerDoExecute(PercolateRequest request, BytesReference docSource, ActionListener<PercolateResponse> listener) {
|
private void innerDoExecute(PercolateRequest request, BytesReference docSource, ActionListener<PercolateResponse> listener) {
|
||||||
SearchRequest searchRequest;
|
SearchRequest searchRequest;
|
||||||
try {
|
try {
|
||||||
searchRequest = createSearchRequest(request, docSource,
|
searchRequest = createSearchRequest(request, docSource, xContentRegistry, parseFieldMatcher);
|
||||||
searchRequestParsers.aggParsers, xContentRegistry, parseFieldMatcher);
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
listener.onFailure(e);
|
listener.onFailure(e);
|
||||||
return;
|
return;
|
||||||
|
@ -127,7 +125,6 @@ public class TransportPercolateAction extends HandledTransportAction<PercolateRe
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SearchRequest createSearchRequest(PercolateRequest percolateRequest, BytesReference documentSource,
|
public static SearchRequest createSearchRequest(PercolateRequest percolateRequest, BytesReference documentSource,
|
||||||
AggregatorParsers aggParsers,
|
|
||||||
NamedXContentRegistry xContentRegistry,
|
NamedXContentRegistry xContentRegistry,
|
||||||
ParseFieldMatcher parseFieldMatcher)
|
ParseFieldMatcher parseFieldMatcher)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
@ -229,7 +226,7 @@ public class TransportPercolateAction extends HandledTransportAction<PercolateRe
|
||||||
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
|
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
|
||||||
try (XContentParser parser = XContentFactory.xContent(XContentType.JSON).createParser(xContentRegistry, source)) {
|
try (XContentParser parser = XContentFactory.xContent(XContentType.JSON).createParser(xContentRegistry, source)) {
|
||||||
QueryParseContext context = new QueryParseContext(parser, parseFieldMatcher);
|
QueryParseContext context = new QueryParseContext(parser, parseFieldMatcher);
|
||||||
searchSourceBuilder.parseXContent(context, aggParsers, null);
|
searchSourceBuilder.parseXContent(context, null);
|
||||||
searchRequest.source(searchSourceBuilder);
|
searchRequest.source(searchSourceBuilder);
|
||||||
return searchRequest;
|
return searchRequest;
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ public class RestReindexAction extends AbstractBaseReindexRestHandler<ReindexReq
|
||||||
builder.map(source);
|
builder.map(source);
|
||||||
try (XContentParser innerParser = parser.contentType().xContent().createParser(parser.getXContentRegistry(), builder.bytes())) {
|
try (XContentParser innerParser = parser.contentType().xContent().createParser(parser.getXContentRegistry(), builder.bytes())) {
|
||||||
request.getSearchRequest().source().parseXContent(context.queryParseContext(innerParser),
|
request.getSearchRequest().source().parseXContent(context.queryParseContext(innerParser),
|
||||||
context.searchRequestParsers.aggParsers, context.searchRequestParsers.suggesters);
|
context.searchRequestParsers.suggesters);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,7 @@ public class RestReindexActionTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
try (XContentParser p = createParser(JsonXContent.jsonXContent, request)) {
|
try (XContentParser p = createParser(JsonXContent.jsonXContent, request)) {
|
||||||
ReindexRequest r = new ReindexRequest(new SearchRequest(), new IndexRequest());
|
ReindexRequest r = new ReindexRequest(new SearchRequest(), new IndexRequest());
|
||||||
SearchRequestParsers searchParsers = new SearchRequestParsers(null, null);
|
SearchRequestParsers searchParsers = new SearchRequestParsers(null);
|
||||||
RestReindexAction.PARSER.parse(p, r, new ReindexParseContext(searchParsers, ParseFieldMatcher.STRICT));
|
RestReindexAction.PARSER.parse(p, r, new ReindexParseContext(searchParsers, ParseFieldMatcher.STRICT));
|
||||||
assertEquals("localhost", r.getRemoteInfo().getHost());
|
assertEquals("localhost", r.getRemoteInfo().getHost());
|
||||||
assertArrayEquals(new String[] {"source"}, r.getSearchRequest().indices());
|
assertArrayEquals(new String[] {"source"}, r.getSearchRequest().indices());
|
||||||
|
@ -132,7 +132,7 @@ public class RestReindexActionTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPipelineQueryParameterIsError() throws IOException {
|
public void testPipelineQueryParameterIsError() throws IOException {
|
||||||
SearchRequestParsers parsers = new SearchRequestParsers(null, null);
|
SearchRequestParsers parsers = new SearchRequestParsers(null);
|
||||||
RestReindexAction action = new RestReindexAction(Settings.EMPTY, mock(RestController.class), parsers, null);
|
RestReindexAction action = new RestReindexAction(Settings.EMPTY, mock(RestController.class), parsers, null);
|
||||||
|
|
||||||
FakeRestRequest.Builder request = new FakeRestRequest.Builder(xContentRegistry());
|
FakeRestRequest.Builder request = new FakeRestRequest.Builder(xContentRegistry());
|
||||||
|
|
Loading…
Reference in New Issue