Reduce the scope of `QueryRewriteContext` (#25787)

Today we provide a lot of functionality on the `QueryRewriteContext` that
we potentially don't have ie. if we rewrite on a coordinating node or when
we percolating. This change moves most of the unnecessary shard level or
index level services and dependencies to `QueryShardContext` instead.
This commit is contained in:
Simon Willnauer 2017-07-19 12:30:38 +02:00 committed by GitHub
parent 4b18800df9
commit 9882d2b9d3
9 changed files with 63 additions and 253 deletions

View File

@ -18,15 +18,9 @@
*/
package org.elasticsearch.index.query;
import org.apache.lucene.index.IndexReader;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.script.TemplateScript;
import java.util.function.LongSupplier;
@ -34,23 +28,14 @@ import java.util.function.LongSupplier;
* Context object used to rewrite {@link QueryBuilder} instances into simplified version.
*/
public class QueryRewriteContext {
protected final MapperService mapperService;
protected final ScriptService scriptService;
protected final IndexSettings indexSettings;
private final NamedXContentRegistry xContentRegistry;
protected final Client client;
protected final IndexReader reader;
protected final LongSupplier nowInMillis;
public QueryRewriteContext(IndexSettings indexSettings, MapperService mapperService, ScriptService scriptService,
NamedXContentRegistry xContentRegistry, Client client, IndexReader reader,
LongSupplier nowInMillis) {
this.mapperService = mapperService;
this.scriptService = scriptService;
this.indexSettings = indexSettings;
public QueryRewriteContext(NamedXContentRegistry xContentRegistry, Client client, LongSupplier nowInMillis) {
this.xContentRegistry = xContentRegistry;
this.client = client;
this.reader = reader;
this.nowInMillis = nowInMillis;
}
@ -61,33 +46,6 @@ public class QueryRewriteContext {
return client;
}
/**
* Returns the index settings for this context. This might return null if the
* context has not index scope.
*/
public IndexSettings getIndexSettings() {
return indexSettings;
}
/**
* Return the MapperService.
*/
public MapperService getMapperService() {
return mapperService;
}
/** Return the script service to allow compiling scripts within queries. */
public ScriptService getScriptService() {
return scriptService;
}
/** Return the current {@link IndexReader}, or {@code null} if no index reader is available, for
* instance if we are on the coordinating node or if this rewrite context is used to index
* queries (percolation). */
public IndexReader getIndexReader() {
return reader;
}
/**
* The registry used to build new {@link XContentParser}s. Contains registered named parsers needed to parse the query.
*/
@ -99,8 +57,10 @@ public class QueryRewriteContext {
return nowInMillis.getAsLong();
}
public String getTemplateBytes(Script template) {
TemplateScript compiledTemplate = scriptService.compile(template, TemplateScript.CONTEXT).newInstance(template.getParams());
return compiledTemplate.execute();
/**
* Returns an instance of {@link QueryShardContext} if available of null otherwise
*/
public QueryShardContext convertToShardContext() {
return null;
}
}

View File

@ -50,6 +50,7 @@ import org.elasticsearch.index.query.support.NestedScope;
import org.elasticsearch.index.similarity.SimilarityService;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.script.TemplateScript;
import org.elasticsearch.search.lookup.SearchLookup;
import java.io.IOException;
@ -66,12 +67,14 @@ import static java.util.Collections.unmodifiableMap;
*/
public class QueryShardContext extends QueryRewriteContext {
private final ScriptService scriptService;
private final IndexSettings indexSettings;
private final MapperService mapperService;
private final SimilarityService similarityService;
private final BitsetFilterCache bitsetFilterCache;
private final IndexFieldDataService indexFieldDataService;
private final IndexSettings indexSettings;
private final int shardId;
private final IndexReader reader;
private String[] types = Strings.EMPTY_ARRAY;
private boolean cachable = true;
private final SetOnce<Boolean> frozen = new SetOnce<>();
@ -94,15 +97,17 @@ public class QueryShardContext extends QueryRewriteContext {
IndexFieldDataService indexFieldDataService, MapperService mapperService, SimilarityService similarityService,
ScriptService scriptService, NamedXContentRegistry xContentRegistry,
Client client, IndexReader reader, LongSupplier nowInMillis) {
super(indexSettings, mapperService, scriptService, xContentRegistry, client, reader, nowInMillis);
super(xContentRegistry, client, nowInMillis);
this.shardId = shardId;
this.indexSettings = indexSettings;
this.similarityService = similarityService;
this.mapperService = mapperService;
this.bitsetFilterCache = bitsetFilterCache;
this.indexFieldDataService = indexFieldDataService;
this.allowUnmappedFields = indexSettings.isDefaultAllowUnmappedFields();
this.nestedScope = new NestedScope();
this.scriptService = scriptService;
this.indexSettings = indexSettings;
this.reader = reader;
}
@ -315,7 +320,6 @@ public class QueryShardContext extends QueryRewriteContext {
}
/** Return the script service to allow compiling scripts. */
@Override
public final ScriptService getScriptService() {
failIfFrozen();
return scriptService;
@ -347,10 +351,10 @@ public class QueryShardContext extends QueryRewriteContext {
}
}
@Override
public final String getTemplateBytes(Script template) {
failIfFrozen();
return super.getTemplateBytes(template);
TemplateScript compiledTemplate = scriptService.compile(template, TemplateScript.CONTEXT).newInstance(template.getParams());
return compiledTemplate.execute();
}
/**
@ -382,4 +386,31 @@ public class QueryShardContext extends QueryRewriteContext {
public QueryBuilder parseInnerQueryBuilder(XContentParser parser) throws IOException {
return AbstractQueryBuilder.parseInnerQueryBuilder(parser);
}
@Override
public final QueryShardContext convertToShardContext() {
return this;
}
/**
* Returns the index settings for this context. This might return null if the
* context has not index scope.
*/
public IndexSettings getIndexSettings() {
return indexSettings;
}
/**
* Return the MapperService.
*/
public MapperService getMapperService() {
return mapperService;
}
/** Return the current {@link IndexReader}, or {@code null} if no index reader is available,
* for instance if this rewrite context is used to index queries (percolation). */
public IndexReader getIndexReader() {
return reader;
}
}

View File

@ -19,7 +19,6 @@
package org.elasticsearch.index.query;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermRangeQuery;
import org.apache.lucene.util.BytesRef;
@ -440,20 +439,20 @@ public class RangeQueryBuilder extends AbstractQueryBuilder<RangeQueryBuilder> i
// Overridable for testing only
protected MappedFieldType.Relation getRelation(QueryRewriteContext queryRewriteContext) throws IOException {
IndexReader reader = queryRewriteContext.getIndexReader();
// If the reader is null we are not on the shard and cannot
QueryShardContext shardContext = queryRewriteContext.convertToShardContext();
// If the context is null we are not on the shard and cannot
// rewrite so just pretend there is an intersection so that the rewrite is a noop
if (reader == null) {
if (shardContext == null || shardContext.getIndexReader() == null) {
return MappedFieldType.Relation.INTERSECTS;
}
final MapperService mapperService = queryRewriteContext.getMapperService();
final MapperService mapperService = shardContext.getMapperService();
final MappedFieldType fieldType = mapperService.fullName(fieldName);
if (fieldType == null) {
// no field means we have no values
return MappedFieldType.Relation.DISJOINT;
} else {
DateMathParser dateMathParser = format == null ? null : new DateMathParser(format);
return fieldType.isFieldWithinQuery(queryRewriteContext.getIndexReader(), from, to, includeLower,
return fieldType.isFieldWithinQuery(shardContext.getIndexReader(), from, to, includeLower,
includeUpper, timeZone, dateMathParser, queryRewriteContext);
}
}

View File

@ -19,15 +19,10 @@
package org.elasticsearch.search.internal;
import org.elasticsearch.Version;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.CheckedFunction;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryRewriteContext;
@ -35,8 +30,6 @@ import java.io.IOException;
import java.util.Arrays;
import java.util.Objects;
import static org.elasticsearch.index.query.AbstractQueryBuilder.parseInnerQueryBuilder;
/**
* Represents a {@link QueryBuilder} and a list of alias names that filters the builder is composed of.
*/
@ -44,45 +37,21 @@ public final class AliasFilter implements Writeable {
private final String[] aliases;
private final QueryBuilder filter;
private final boolean reparseAliases;
public static final AliasFilter EMPTY = new AliasFilter(null, Strings.EMPTY_ARRAY);
public AliasFilter(QueryBuilder filter, String... aliases) {
this.aliases = aliases == null ? Strings.EMPTY_ARRAY : aliases;
this.filter = filter;
reparseAliases = false; // no bwc here - we only do this if we parse the filter
}
public AliasFilter(StreamInput input) throws IOException {
aliases = input.readStringArray();
if (input.getVersion().onOrAfter(Version.V_5_1_1)) {
filter = input.readOptionalNamedWriteable(QueryBuilder.class);
reparseAliases = false;
} else {
reparseAliases = true; // alright we read from 5.0
filter = null;
}
}
private QueryBuilder reparseFilter(QueryRewriteContext context) {
if (reparseAliases) {
// we are processing a filter received from a 5.0 node - we need to reparse this on the executing node
final IndexMetaData indexMetaData = context.getIndexSettings().getIndexMetaData();
/* Being static, parseAliasFilter doesn't have access to whatever guts it needs to parse a query. Instead of passing in a bunch
* of dependencies we pass in a function that can perform the parsing. */
CheckedFunction<byte[], QueryBuilder, IOException> filterParser = bytes -> {
try (XContentParser parser = XContentFactory.xContent(bytes).createParser(context.getXContentRegistry(), bytes)) {
return parseInnerQueryBuilder(parser);
}
};
return ShardSearchRequest.parseAliasFilter(filterParser, indexMetaData, aliases);
}
return filter;
filter = input.readOptionalNamedWriteable(QueryBuilder.class);
}
AliasFilter rewrite(QueryRewriteContext context) throws IOException {
QueryBuilder queryBuilder = reparseFilter(context);
QueryBuilder queryBuilder = this.filter;
if (queryBuilder != null) {
return new AliasFilter(QueryBuilder.rewriteQuery(queryBuilder, context), aliases);
}
@ -92,9 +61,7 @@ public final class AliasFilter implements Writeable {
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeStringArray(aliases);
if (out.getVersion().onOrAfter(Version.V_5_1_1)) {
out.writeOptionalNamedWriteable(filter);
}
out.writeOptionalNamedWriteable(filter);
}
/**
@ -109,12 +76,6 @@ public final class AliasFilter implements Writeable {
* Returns the alias filter {@link QueryBuilder} or <code>null</code> if there is no such filter
*/
public QueryBuilder getQueryBuilder() {
if (reparseAliases) {
// this is only for BWC since 5.0 still only sends aliases so this must be rewritten on the executing node
// if we talk to an older node we also only forward/write the string array which is compatible with the consumers
// in 5.0 see ExplainRequest and QueryValidationRequest
throw new IllegalStateException("alias filter for aliases: " + Arrays.toString(aliases) + " must be rewritten first");
}
return filter;
}
@ -123,14 +84,13 @@ public final class AliasFilter implements Writeable {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AliasFilter that = (AliasFilter) o;
return reparseAliases == that.reparseAliases &&
Arrays.equals(aliases, that.aliases) &&
return Arrays.equals(aliases, that.aliases) &&
Objects.equals(filter, that.filter);
}
@Override
public int hashCode() {
return Objects.hash(reparseAliases, Arrays.hashCode(aliases), filter);
return Objects.hash(Arrays.hashCode(aliases), filter);
}
@Override
@ -138,7 +98,6 @@ public final class AliasFilter implements Writeable {
return "AliasFilter{" +
"aliases=" + Arrays.toString(aliases) +
", filter=" + filter +
", reparseAliases=" + reparseAliases +
'}';
}
}

View File

@ -18,9 +18,7 @@
*/
package org.elasticsearch.action;
import org.elasticsearch.Version;
import org.elasticsearch.action.explain.ExplainRequest;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.io.stream.NamedWriteableAwareStreamInput;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
@ -35,7 +33,6 @@ import org.elasticsearch.test.ESTestCase;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collections;
import java.util.List;
@ -74,36 +71,4 @@ public class ExplainRequestTests extends ESTestCase {
}
}
}
// BWC test for changes from #20916
public void testSerialize50Request() throws IOException {
ExplainRequest request = new ExplainRequest("index", "type", "id");
request.fetchSourceContext(new FetchSourceContext(true, new String[]{"field1.*"}, new String[] {"field2.*"}));
request.filteringAlias(new AliasFilter(QueryBuilders.termQuery("filter_field", "value"), new String[] {"alias0", "alias1"}));
request.preference("the_preference");
request.query(QueryBuilders.termQuery("field", "value"));
request.storedFields(new String[] {"field1", "field2"});
request.routing("some_routing");
BytesArray requestBytes = new BytesArray(Base64.getDecoder()
// this is a base64 encoded request generated with the same input
.decode("AAABBWluZGV4BHR5cGUCaWQBDHNvbWVfcm91dGluZwEOdGhlX3ByZWZlcmVuY2UEdGVybT" +
"+AAAAABWZpZWxkFQV2YWx1ZQIGYWxpYXMwBmFsaWFzMQECBmZpZWxkMQZmaWVsZDIBAQEIZmllbGQxLioBCGZpZWxkMi4qAA"));
try (StreamInput in = new NamedWriteableAwareStreamInput(requestBytes.streamInput(), namedWriteableRegistry)) {
in.setVersion(Version.V_5_0_0);
ExplainRequest readRequest = new ExplainRequest();
readRequest.readFrom(in);
assertEquals(0, in.available());
assertArrayEquals(request.filteringAlias().getAliases(), readRequest.filteringAlias().getAliases());
expectThrows(IllegalStateException.class, () -> readRequest.filteringAlias().getQueryBuilder());
assertArrayEquals(request.storedFields(), readRequest.storedFields());
assertEquals(request.preference(), readRequest.preference());
assertEquals(request.query(), readRequest.query());
assertEquals(request.routing(), readRequest.routing());
assertEquals(request.fetchSourceContext(), readRequest.fetchSourceContext());
BytesStreamOutput output = new BytesStreamOutput();
output.setVersion(Version.V_5_0_0);
readRequest.writeTo(output);
assertEquals(output.bytes().toBytesRef(), requestBytes.toBytesRef());
}
}
}

View File

@ -18,10 +18,8 @@
*/
package org.elasticsearch.action;
import org.elasticsearch.Version;
import org.elasticsearch.action.admin.indices.validate.query.ShardValidateQueryRequest;
import org.elasticsearch.action.admin.indices.validate.query.ValidateQueryRequest;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.io.stream.NamedWriteableAwareStreamInput;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
@ -36,7 +34,6 @@ import org.elasticsearch.test.ESTestCase;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collections;
import java.util.List;
@ -75,35 +72,4 @@ public class ShardValidateQueryRequestTests extends ESTestCase {
}
}
}
// BWC test for changes from #20916
public void testSerialize50Request() throws IOException {
ValidateQueryRequest validateQueryRequest = new ValidateQueryRequest("indices");
validateQueryRequest.query(QueryBuilders.termQuery("field", "value"));
validateQueryRequest.rewrite(true);
validateQueryRequest.explain(false);
validateQueryRequest.types("type1", "type2");
ShardValidateQueryRequest request = new ShardValidateQueryRequest(new ShardId("index", "foobar", 1),
new AliasFilter(QueryBuilders.termQuery("filter_field", "value"), new String[] {"alias0", "alias1"}), validateQueryRequest);
BytesArray requestBytes = new BytesArray(Base64.getDecoder()
// this is a base64 encoded request generated with the same input
.decode("AAVpbmRleAZmb29iYXIBAQdpbmRpY2VzBAR0ZXJtP4AAAAAFZmllbGQVBXZhbHVlAgV0eXBlMQV0eXBlMgIGYWxpYXMwBmFsaWFzMQABAA"));
try (StreamInput in = new NamedWriteableAwareStreamInput(requestBytes.streamInput(), namedWriteableRegistry)) {
in.setVersion(Version.V_5_0_0);
ShardValidateQueryRequest readRequest = new ShardValidateQueryRequest();
readRequest.readFrom(in);
assertEquals(0, in.available());
assertArrayEquals(request.filteringAliases().getAliases(), readRequest.filteringAliases().getAliases());
expectThrows(IllegalStateException.class, () -> readRequest.filteringAliases().getQueryBuilder());
assertArrayEquals(request.types(), readRequest.types());
assertEquals(request.explain(), readRequest.explain());
assertEquals(request.query(), readRequest.query());
assertEquals(request.rewrite(), readRequest.rewrite());
assertEquals(request.shardId(), readRequest.shardId());
BytesStreamOutput output = new BytesStreamOutput();
output.setVersion(Version.V_5_0_0);
readRequest.writeTo(output);
assertEquals(output.bytes().toBytesRef(), requestBytes.toBytesRef());
}
}
}

View File

@ -74,8 +74,8 @@ public class DateFieldTypeTests extends FieldTypeTestCase {
}
public void testIsFieldWithinQueryEmptyReader() throws IOException {
QueryRewriteContext context = new QueryRewriteContext(null, null, null, xContentRegistry(), null, null,
() -> nowInMillis);
QueryRewriteContext context = new QueryRewriteContext(xContentRegistry(), null,
() -> nowInMillis);
IndexReader reader = new MultiReader();
DateFieldType ft = new DateFieldType();
ft.setName("my_date");
@ -85,8 +85,8 @@ public class DateFieldTypeTests extends FieldTypeTestCase {
private void doTestIsFieldWithinQuery(DateFieldType ft, DirectoryReader reader,
DateTimeZone zone, DateMathParser alternateFormat) throws IOException {
QueryRewriteContext context = new QueryRewriteContext(null, null, null, xContentRegistry(), null, null,
() -> nowInMillis);
QueryRewriteContext context = new QueryRewriteContext(xContentRegistry(), null,
() -> nowInMillis);
assertEquals(Relation.INTERSECTS, ft.isFieldWithinQuery(reader, "2015-10-09", "2016-01-02",
randomBoolean(), randomBoolean(), null, null, context));
assertEquals(Relation.INTERSECTS, ft.isFieldWithinQuery(reader, "2016-01-02", "2016-06-20",
@ -133,8 +133,8 @@ public class DateFieldTypeTests extends FieldTypeTestCase {
DateFieldType ft2 = new DateFieldType();
ft2.setName("my_date2");
QueryRewriteContext context = new QueryRewriteContext(null, null, null, xContentRegistry(), null, null,
() -> nowInMillis);
QueryRewriteContext context = new QueryRewriteContext(xContentRegistry(), null,
() -> nowInMillis);
assertEquals(Relation.DISJOINT, ft2.isFieldWithinQuery(reader, "2015-10-09", "2016-01-02", false, false, null, null, context));
IOUtils.close(reader, w, dir);
}

View File

@ -267,7 +267,7 @@ public class AggregatorFactoriesTests extends ESTestCase {
AggregatorFactories.Builder builder = new AggregatorFactories.Builder().addAggregator(filterAggBuilder)
.addPipelineAggregator(pipelineAgg);
AggregatorFactories.Builder rewritten = builder
.rewrite(new QueryRewriteContext(null, null, null, xContentRegistry, null, null, () -> 0L));
.rewrite(new QueryRewriteContext(xContentRegistry, null, () -> 0L));
assertNotSame(builder, rewritten);
List<AggregationBuilder> aggregatorFactories = rewritten.getAggregatorFactories();
assertEquals(1, aggregatorFactories.size());
@ -278,10 +278,10 @@ public class AggregatorFactoriesTests extends ESTestCase {
// Check the filter was rewritten from a wrapper query to a terms query
QueryBuilder rewrittenFilter = rewrittenFilterAggBuilder.getFilter();
assertThat(rewrittenFilter, instanceOf(TermsQueryBuilder.class));
// Check that a further rewrite returns the same aggregation factories builder
AggregatorFactories.Builder secondRewritten = rewritten
.rewrite(new QueryRewriteContext(null, null, null, xContentRegistry, null, null, () -> 0L));
.rewrite(new QueryRewriteContext(xContentRegistry, null, () -> 0L));
assertSame(rewritten, secondRewritten);
}

View File

@ -27,7 +27,6 @@ import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.CheckedFunction;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.compress.CompressedXContent;
import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.io.stream.NamedWriteableAwareStreamInput;
@ -37,17 +36,14 @@ import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.index.query.RandomQueryBuilder;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.indices.InvalidAliasNameException;
import org.elasticsearch.search.AbstractSearchTestCase;
import java.io.IOException;
import java.util.Base64;
import static org.elasticsearch.index.query.AbstractQueryBuilder.parseInnerQueryBuilder;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
@ -170,70 +166,4 @@ public class ShardSearchTransportRequestTests extends AbstractSearchTestCase {
};
return ShardSearchRequest.parseAliasFilter(filterParser, indexMetaData, aliasNames);
}
// BWC test for changes from #20916
public void testSerialize50Request() throws IOException {
BytesArray requestBytes = new BytesArray(Base64.getDecoder()
// this is a base64 encoded request generated with the same input
.decode("AAh4cXptdEhJcgdnT0d1ZldWyfL/sgQBJAHkDAMBAAIBAQ4TWlljWlZ5TkVmRU5xQnFQVHBjVBRZbUpod2pRV2dDSXVxRXpRaEdGVBRFZWFJY0plT2hn" +
"UEpISFhmSXR6Qw5XZ1hQcmFidWhWalFSQghuUWNwZ2JjQxBtZldRREJPaGF3UnlQSE56EVhQSUtRa25Iekh3bU5kbGVECWlFT2NIeEh3RgZIYXpMTWgUeGJq" +
"VU9Tdkdua3RORU5QZkNrb1EOalRyWGh5WXhvZ3plV2UUcWlXZFl2eUFUSXdPVGdMUUtYTHAJU3RKR3JxQkVJEkdEQ01xUHpnWWNaT3N3U3prSRIUeURlVFpM" +
"Q1lBZERZcWpDb3NOVWIST1NyQlZtdUNrd0F1UXRvdVRjEGp6RlVMd1dqc3VtUVNaTk0JT3N2cnpLQ3ZLBmRpS1J6cgdYbmVhZnBxBUlTUU9pEEJMcm1ERXVs" +
"eXhESlBoVkgTaWdUUmtVZGh4d0FFc2ZKRm9ZahNrb01XTnFFd2NWSVVDU3pWS2xBC3JVTWV3V2tUUWJUE3VGQU1Hd21CYUFMTmNQZkxobXUIZ3dxWHBxWXcF" +
"bmNDZUEOTFBSTEpYZVF6Z3d2eE0PV1BucUFacll6WWRxa1hCDGxkbXNMaVRzcUZXbAtSY0NsY3FNdlJQcv8BAP////8PAQAAARQAAQp5THlIcHdQeGtMAAAB" +
"AQAAAAEDbkVLAQMBCgACAAADAQABAAAAAQhIc25wRGxQbwEBQgABAAACAQMAAAEIAAAJMF9OSG9kSmh2HwABAwljRW5MVWxFbVQFemlxWG8KcXZQTkRUUGJk" +
"bgECCkpMbXVMT1dtVnkISEdUUHhsd0cBAAEJAAABA2lkcz+rKsUAAAAAAAAAAAECAQYAAgwxX0ZlRWxSQkhzQ07/////DwABAAEDCnRyYXFHR1hjVHkKTERY" +
"aE1HRWVySghuSWtzbEtXUwABCgEHSlRwQnhwdwAAAQECAgAAAAAAAQcyX3FlYmNDGQEEBklxZU9iUQdTc01Gek5YCWlMd2xuamNRQwNiVncAAUHt61kAAQR0" +
"ZXJtP4AAAAANbUtDSnpHU3lidm5KUBUMaVpqeG9vcm5QSFlvAAEBLGdtcWxuRWpWTXdvTlhMSHh0RWlFdHBnbEF1cUNmVmhoUVlwRFZxVllnWWV1A2ZvbwEA" +
"AQhwYWlubGVzc/8AALk4AAAAAAABAAAAAAAAAwpKU09PU0ZmWnhFClVqTGxMa2p3V2gKdUJwZ3R3dXFER5Hg97uT7MOmPgEADw"));
try (StreamInput in = new NamedWriteableAwareStreamInput(requestBytes.streamInput(), namedWriteableRegistry)) {
in.setVersion(Version.V_5_0_0);
ShardSearchTransportRequest readRequest = new ShardSearchTransportRequest();
readRequest.readFrom(in);
assertEquals(0, in.available());
IllegalStateException illegalStateException = expectThrows(IllegalStateException.class, () -> readRequest.filteringAliases());
assertEquals("alias filter for aliases: [JSOOSFfZxE, UjLlLkjwWh, uBpgtwuqDG] must be rewritten first",
illegalStateException.getMessage());
IndexMetaData.Builder indexMetadata = new IndexMetaData.Builder(baseMetaData)
.putAlias(AliasMetaData.newAliasMetaDataBuilder("JSOOSFfZxE").filter("{\"term\" : {\"foo\" : \"bar\"}}"))
.putAlias(AliasMetaData.newAliasMetaDataBuilder("UjLlLkjwWh").filter("{\"term\" : {\"foo\" : \"bar1\"}}"))
.putAlias(AliasMetaData.newAliasMetaDataBuilder("uBpgtwuqDG").filter("{\"term\" : {\"foo\" : \"bar2\"}}"));
IndexSettings indexSettings = new IndexSettings(indexMetadata.build(), Settings.EMPTY);
final long nowInMillis = randomNonNegativeLong();
QueryShardContext context = new QueryShardContext(
0, indexSettings, null, null, null, null, null, xContentRegistry(), null, null, () -> nowInMillis);
readRequest.rewrite(context);
QueryBuilder queryBuilder = readRequest.filteringAliases();
assertEquals(queryBuilder, QueryBuilders.boolQuery()
.should(QueryBuilders.termQuery("foo", "bar"))
.should(QueryBuilders.termQuery("foo", "bar1"))
.should(QueryBuilders.termQuery("foo", "bar2"))
);
BytesStreamOutput output = new BytesStreamOutput();
output.setVersion(Version.V_5_0_0);
readRequest.writeTo(output);
assertEquals(output.bytes().toBytesRef(), requestBytes.toBytesRef());
}
}
// BWC test for changes from #21393
public void testSerialize50RequestForIndexBoost() throws IOException {
BytesArray requestBytes = new BytesArray(Base64.getDecoder()
// this is a base64 encoded request generated with the same input
.decode("AAZpbmRleDEWTjEyM2trbHFUT21XZDY1Z2VDYlo5ZwABBAABAAIA/wD/////DwABBmluZGV4MUAAAAAAAAAAAP////8PAAAAAAAAAgAAAA" +
"AAAPa/q8mOKwIAJg=="));
try (StreamInput in = new NamedWriteableAwareStreamInput(requestBytes.streamInput(), namedWriteableRegistry)) {
in.setVersion(Version.V_5_0_0);
ShardSearchTransportRequest readRequest = new ShardSearchTransportRequest();
readRequest.readFrom(in);
assertEquals(0, in.available());
assertEquals(2.0f, readRequest.indexBoost(), 0);
BytesStreamOutput output = new BytesStreamOutput();
output.setVersion(Version.V_5_0_0);
readRequest.writeTo(output);
assertEquals(output.bytes().toBytesRef(), requestBytes.toBytesRef());
}
}
}