diff --git a/core/src/main/java/org/elasticsearch/index/query/IndexQueryParserModule.java b/core/src/main/java/org/elasticsearch/index/query/IndexQueryParserModule.java deleted file mode 100644 index 0953b4f04a6..00000000000 --- a/core/src/main/java/org/elasticsearch/index/query/IndexQueryParserModule.java +++ /dev/null @@ -1,134 +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.index.query; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import org.elasticsearch.common.inject.AbstractModule; -import org.elasticsearch.common.inject.Scopes; -import org.elasticsearch.common.inject.assistedinject.FactoryProvider; -import org.elasticsearch.common.inject.multibindings.MapBinder; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.index.query.support.InnerHitsQueryParserHelper; - -import java.util.LinkedList; -import java.util.Map; - -/** - * - */ -public class IndexQueryParserModule extends AbstractModule { - - /** - * A custom processor that can be extended to process and bind custom implementations of - * {@link QueryParserFactory}, and {@link FilterParser}. - */ - public static class QueryParsersProcessor { - - /** - * Extension point to bind a custom {@link QueryParserFactory}. - */ - public void processXContentQueryParsers(XContentQueryParsersBindings bindings) { - - } - - public static class XContentQueryParsersBindings { - - private final MapBinder binder; - private final Map groupSettings; - - public XContentQueryParsersBindings(MapBinder binder, Map groupSettings) { - this.binder = binder; - this.groupSettings = groupSettings; - } - - public MapBinder binder() { - return binder; - } - - public Map groupSettings() { - return groupSettings; - } - - public void processXContentQueryParser(String name, Class xcontentQueryParser) { - if (!groupSettings.containsKey(name)) { - binder.addBinding(name).toProvider(FactoryProvider.newFactory(QueryParserFactory.class, xcontentQueryParser)).in(Scopes.SINGLETON); - } - } - } - - } - - private final Settings settings; - - private final LinkedList processors = Lists.newLinkedList(); - - private final Map> queries = Maps.newHashMap(); - - public IndexQueryParserModule(Settings settings) { - this.settings = settings; - } - - /** - * Adds a custom query parser. - * - * @param name The name of the query parser - * @param queryParser the class of the query parser - */ - public void addQueryParser(String name, Class queryParser) { - queries.put(name, queryParser); - } - - public IndexQueryParserModule addProcessor(QueryParsersProcessor processor) { - processors.addFirst(processor); - return this; - } - - @Override - protected void configure() { - - bind(IndexQueryParserService.class).asEagerSingleton(); - bind(InnerHitsQueryParserHelper.class).asEagerSingleton(); - - // handle XContenQueryParsers - MapBinder queryBinder - = MapBinder.newMapBinder(binder(), String.class, QueryParserFactory.class); - Map xContentQueryParserGroups = settings.getGroups(IndexQueryParserService.Defaults.QUERY_PREFIX); - for (Map.Entry entry : xContentQueryParserGroups.entrySet()) { - String qName = entry.getKey(); - Settings qSettings = entry.getValue(); - Class type = qSettings.getAsClass("type", null); - if (type == null) { - throw new IllegalArgumentException("Query Parser [" + qName + "] must be provided with a type"); - } - queryBinder.addBinding(qName).toProvider(FactoryProvider.newFactory(QueryParserFactory.class, - qSettings.getAsClass("type", null))).in(Scopes.SINGLETON); - } - - QueryParsersProcessor.XContentQueryParsersBindings xContentQueryParsersBindings = new QueryParsersProcessor.XContentQueryParsersBindings(queryBinder, xContentQueryParserGroups); - for (QueryParsersProcessor processor : processors) { - processor.processXContentQueryParsers(xContentQueryParsersBindings); - } - - for (Map.Entry> entry : queries.entrySet()) { - queryBinder.addBinding(entry.getKey()).toProvider(FactoryProvider.newFactory(QueryParserFactory.class, entry.getValue())).in(Scopes.SINGLETON); - } - } -} diff --git a/core/src/main/java/org/elasticsearch/index/query/IndexQueryParserService.java b/core/src/main/java/org/elasticsearch/index/query/IndexQueryParserService.java index a3684d379e6..5e0caccbe79 100644 --- a/core/src/main/java/org/elasticsearch/index/query/IndexQueryParserService.java +++ b/core/src/main/java/org/elasticsearch/index/query/IndexQueryParserService.java @@ -19,8 +19,6 @@ package org.elasticsearch.index.query; -import com.google.common.collect.ImmutableMap; - import org.apache.lucene.search.Query; import org.apache.lucene.util.CloseableThreadLocal; import org.elasticsearch.Version; @@ -48,23 +46,12 @@ import org.elasticsearch.script.ScriptService; import java.io.IOException; import java.util.EnumSet; -import java.util.List; -import java.util.Map; - -import static com.google.common.collect.Lists.newArrayList; -import static com.google.common.collect.Maps.newHashMap; -import static org.elasticsearch.common.settings.Settings.Builder.EMPTY_SETTINGS; /** * */ public class IndexQueryParserService extends AbstractIndexComponent { - public static final class Defaults { - public static final String QUERY_PREFIX = "index.queryparser.query"; - public static final String FILTER_PREFIX = "index.queryparser.filter"; - } - public static final String DEFAULT_FIELD = "index.query.default_field"; public static final String QUERY_STRING_LENIENT = "index.query_string.lenient"; public static final String PARSE_STRICT = "index.query.parse.strict"; @@ -91,7 +78,7 @@ public class IndexQueryParserService extends AbstractIndexComponent { final BitsetFilterCache bitsetFilterCache; - private final Map queryParsers; + private final IndicesQueriesRegistry indicesQueriesRegistry; private String defaultField; private boolean queryStringLenient; @@ -104,8 +91,7 @@ public class IndexQueryParserService extends AbstractIndexComponent { ScriptService scriptService, AnalysisService analysisService, MapperService mapperService, IndexCache indexCache, IndexFieldDataService fieldDataService, BitsetFilterCache bitsetFilterCache, - @Nullable SimilarityService similarityService, - @Nullable Map namedQueryParsers) { + @Nullable SimilarityService similarityService) { super(index, indexSettings); this.scriptService = scriptService; this.analysisService = analysisService; @@ -119,29 +105,7 @@ public class IndexQueryParserService extends AbstractIndexComponent { this.queryStringLenient = indexSettings.getAsBoolean(QUERY_STRING_LENIENT, false); this.strict = indexSettings.getAsBoolean(PARSE_STRICT, false); this.defaultAllowUnmappedFields = indexSettings.getAsBoolean(ALLOW_UNMAPPED, true); - - List queryParsers = newArrayList(); - if (namedQueryParsers != null) { - Map queryParserGroups = indexSettings.getGroups(IndexQueryParserService.Defaults.QUERY_PREFIX); - for (Map.Entry entry : namedQueryParsers.entrySet()) { - String queryParserName = entry.getKey(); - QueryParserFactory queryParserFactory = entry.getValue(); - Settings queryParserSettings = queryParserGroups.get(queryParserName); - if (queryParserSettings == null) { - queryParserSettings = EMPTY_SETTINGS; - } - queryParsers.add(queryParserFactory.create(queryParserName, queryParserSettings)); - } - } - - Map queryParsersMap = newHashMap(); - queryParsersMap.putAll(indicesQueriesRegistry.queryParsers()); - if (queryParsers != null) { - for (QueryParser queryParser : queryParsers) { - add(queryParsersMap, queryParser); - } - } - this.queryParsers = ImmutableMap.copyOf(queryParsersMap); + this.indicesQueriesRegistry = indicesQueriesRegistry; } public void close() { @@ -157,7 +121,7 @@ public class IndexQueryParserService extends AbstractIndexComponent { } public QueryParser queryParser(String name) { - return queryParsers.get(name); + return indicesQueriesRegistry.queryParsers().get(name); } public ParsedQuery parse(QueryBuilder queryBuilder) { @@ -349,10 +313,4 @@ public class IndexQueryParserService extends AbstractIndexComponent { parseContext.reset(null); } } - - private void add(Map map, QueryParser queryParser) { - for (String name : queryParser.names()) { - map.put(name.intern(), queryParser); - } - } } diff --git a/core/src/main/java/org/elasticsearch/index/query/QueryParserFactory.java b/core/src/main/java/org/elasticsearch/index/query/QueryParserFactory.java deleted file mode 100644 index fa280ffe7fa..00000000000 --- a/core/src/main/java/org/elasticsearch/index/query/QueryParserFactory.java +++ /dev/null @@ -1,30 +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.index.query; - -import org.elasticsearch.common.settings.Settings; - -/** - * - */ -public interface QueryParserFactory { - - QueryParser create(String name, Settings settings); -} diff --git a/core/src/main/java/org/elasticsearch/indices/IndicesService.java b/core/src/main/java/org/elasticsearch/indices/IndicesService.java index 4f55237f7ca..ba0241a043d 100644 --- a/core/src/main/java/org/elasticsearch/indices/IndicesService.java +++ b/core/src/main/java/org/elasticsearch/indices/IndicesService.java @@ -57,7 +57,6 @@ import org.elasticsearch.index.indexing.IndexingStats; import org.elasticsearch.index.mapper.MapperService; import org.elasticsearch.index.mapper.MapperServiceModule; import org.elasticsearch.index.merge.MergeStats; -import org.elasticsearch.index.query.IndexQueryParserModule; import org.elasticsearch.index.query.IndexQueryParserService; import org.elasticsearch.index.recovery.RecoveryStats; import org.elasticsearch.index.refresh.RefreshStats; @@ -315,7 +314,6 @@ public class IndicesService extends AbstractLifecycleComponent i modules.add(new IndexCacheModule(indexSettings)); modules.add(new IndexFieldDataModule(indexSettings)); modules.add(new MapperServiceModule()); - modules.add(new IndexQueryParserModule(indexSettings)); modules.add(new IndexAliasesServiceModule()); modules.add(new IndexModule(indexSettings)); diff --git a/core/src/main/java/org/elasticsearch/indices/query/IndicesQueriesModule.java b/core/src/main/java/org/elasticsearch/indices/query/IndicesQueriesModule.java index 8e4ff94d87d..fb7ca1784e3 100644 --- a/core/src/main/java/org/elasticsearch/indices/query/IndicesQueriesModule.java +++ b/core/src/main/java/org/elasticsearch/indices/query/IndicesQueriesModule.java @@ -30,30 +30,21 @@ import java.util.Set; public class IndicesQueriesModule extends AbstractModule { - private Set> queryParsersClasses = Sets.newHashSet(); - private Set queryParsers = Sets.newHashSet(); + private Set> queryParsersClasses = Sets.newHashSet(); - public synchronized IndicesQueriesModule addQuery(Class queryParser) { + public synchronized IndicesQueriesModule addQuery(Class queryParser) { queryParsersClasses.add(queryParser); return this; } - public synchronized IndicesQueriesModule addQuery(QueryParser queryParser) { - queryParsers.add(queryParser); - return this; - } - @Override protected void configure() { bind(IndicesQueriesRegistry.class).asEagerSingleton(); Multibinder qpBinders = Multibinder.newSetBinder(binder(), QueryParser.class); - for (Class queryParser : queryParsersClasses) { + for (Class queryParser : queryParsersClasses) { qpBinders.addBinding().to(queryParser).asEagerSingleton(); } - for (QueryParser queryParser : queryParsers) { - qpBinders.addBinding().toInstance(queryParser); - } qpBinders.addBinding().to(MatchQueryParser.class).asEagerSingleton(); qpBinders.addBinding().to(MultiMatchQueryParser.class).asEagerSingleton(); qpBinders.addBinding().to(NestedQueryParser.class).asEagerSingleton(); diff --git a/core/src/main/java/org/elasticsearch/indices/query/IndicesQueriesRegistry.java b/core/src/main/java/org/elasticsearch/indices/query/IndicesQueriesRegistry.java index a4e3116b41a..7d13fe01975 100644 --- a/core/src/main/java/org/elasticsearch/indices/query/IndicesQueriesRegistry.java +++ b/core/src/main/java/org/elasticsearch/indices/query/IndicesQueriesRegistry.java @@ -30,9 +30,6 @@ import org.elasticsearch.index.query.QueryParser; import java.util.Map; import java.util.Set; -/** - * - */ public class IndicesQueriesRegistry extends AbstractComponent { private ImmutableMap queryParsers; @@ -42,27 +39,17 @@ public class IndicesQueriesRegistry extends AbstractComponent { super(settings); Map queryParsers = Maps.newHashMap(); for (QueryParser queryParser : injectedQueryParsers) { - addQueryParser(queryParsers, queryParser); + for (String name : queryParser.names()) { + queryParsers.put(name, queryParser); + } } this.queryParsers = ImmutableMap.copyOf(queryParsers); } /** - * Adds a global query parser. + * Returns all the registered query parsers */ - public synchronized void addQueryParser(QueryParser queryParser) { - Map queryParsers = Maps.newHashMap(this.queryParsers); - addQueryParser(queryParsers, queryParser); - this.queryParsers = ImmutableMap.copyOf(queryParsers); - } - public ImmutableMap queryParsers() { return queryParsers; } - - private void addQueryParser(Map queryParsers, QueryParser queryParser) { - for (String name : queryParser.names()) { - queryParsers.put(name, queryParser); - } - } } \ No newline at end of file diff --git a/core/src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java b/core/src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java index ad55c65938d..3b72223b46f 100644 --- a/core/src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java @@ -41,7 +41,6 @@ import org.elasticsearch.action.termvectors.*; import org.elasticsearch.common.Strings; import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.compress.CompressedXContent; -import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.lucene.search.MoreLikeThisQuery; import org.elasticsearch.common.lucene.search.Queries; import org.elasticsearch.common.lucene.search.function.BoostScoreFunction; @@ -50,12 +49,9 @@ import org.elasticsearch.common.lucene.search.function.WeightFactorFunction; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.DistanceUnit; import org.elasticsearch.common.unit.Fuzziness; -import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.index.AbstractIndexComponent; -import org.elasticsearch.index.Index; import org.elasticsearch.index.IndexService; import org.elasticsearch.index.mapper.MapperService; import org.elasticsearch.index.mapper.ParsedDocument; @@ -71,7 +67,6 @@ import org.junit.Before; import org.junit.Test; import java.io.IOException; -import java.util.Arrays; import java.util.EnumSet; import java.util.List; @@ -83,61 +78,13 @@ import static org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders. import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertBooleanSubQuery; import static org.hamcrest.Matchers.*; -/** - * - */ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { private IndexQueryParserService queryParser; - private static class DummyQuery extends Query { - - public boolean isFilter; - - @Override - public String toString(String field) { - return getClass().getSimpleName(); - } - - } - - public static class DummyQueryParser extends AbstractIndexComponent implements QueryParser { - - @Inject - public DummyQueryParser(Index index, Settings indexSettings) { - super(index, indexSettings); - } - - @Override - public String[] names() { - return new String[] {"dummy"}; - } - - @Override - public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException { - assertEquals(XContentParser.Token.END_OBJECT, parseContext.parser().nextToken()); - DummyQuery query = new DummyQuery(); - query.isFilter = parseContext.isFilter(); - return query; - } - - } - - private static class DummyQueryBuilder extends QueryBuilder { - @Override - protected void doXContent(XContentBuilder builder, Params params) throws IOException { - builder.startObject("dummy").endObject(); - } - } - - private static DummyQueryBuilder dummyQuery() { - return new DummyQueryBuilder(); - } - @Before public void setup() throws IOException { Settings settings = Settings.settingsBuilder() - .put("index.queryparser.query.dummy.type", DummyQueryParser.class) .put("index.cache.filter.type", "none") .put("name", "SimpleIndexQueryParserTests") .build(); @@ -1063,7 +1010,6 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { assertThat(clauses[3].getOccur(), equalTo(BooleanClause.Occur.SHOULD)); } - @Test public void testBoolQuery() throws IOException { IndexQueryParserService queryParser = queryParser(); @@ -1964,7 +1910,6 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { assertThat(filter.bottomRight().lon(), closeTo(-80, 0.00001)); } - @Test public void testGeoBoundingBoxFilter1() throws IOException { IndexQueryParserService queryParser = queryParser(); @@ -2464,72 +2409,11 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { public void testTermsQueryFilter() throws Exception { // TermsQuery is tricky in that it parses differently as a query or a filter IndexQueryParserService queryParser = queryParser(); - Query q = queryParser.parse(termsQuery("foo", Arrays.asList("bar"))).query(); + Query q = queryParser.parse(termsQuery("foo", "bar")).query(); assertThat(q, instanceOf(BooleanQuery.class)); - ConstantScoreQuery csq = (ConstantScoreQuery) queryParser.parse(constantScoreQuery(termsQuery("foo", Arrays.asList("bar")))).query(); + ConstantScoreQuery csq = (ConstantScoreQuery) queryParser.parse(constantScoreQuery(termsQuery("foo", "bar"))).query(); q = csq.getQuery(); assertThat(q, instanceOf(TermsQuery.class)); } - - public void testConstantScoreParsesFilter() throws Exception { - IndexQueryParserService queryParser = queryParser(); - Query q = queryParser.parse(constantScoreQuery(dummyQuery())).query(); - Query inner = ((ConstantScoreQuery) q).getQuery(); - assertThat(inner, instanceOf(DummyQuery.class)); - assertEquals(true, ((DummyQuery) inner).isFilter); - } - - public void testBooleanParsesFilter() throws Exception { - IndexQueryParserService queryParser = queryParser(); - // single clause, serialized as inner object - Query q = queryParser.parse(boolQuery() - .should(dummyQuery()) - .must(dummyQuery()) - .filter(dummyQuery()) - .mustNot(dummyQuery())).query(); - assertThat(q, instanceOf(BooleanQuery.class)); - BooleanQuery bq = (BooleanQuery) q; - assertEquals(4, bq.clauses().size()); - for (BooleanClause clause : bq.clauses()) { - DummyQuery dummy = (DummyQuery) clause.getQuery(); - switch (clause.getOccur()) { - case FILTER: - case MUST_NOT: - assertEquals(true, dummy.isFilter); - break; - case MUST: - case SHOULD: - assertEquals(false, dummy.isFilter); - break; - default: - throw new AssertionError(); - } - } - - // multiple clauses, serialized as inner arrays - q = queryParser.parse(boolQuery() - .should(dummyQuery()).should(dummyQuery()) - .must(dummyQuery()).must(dummyQuery()) - .filter(dummyQuery()).filter(dummyQuery()) - .mustNot(dummyQuery()).mustNot(dummyQuery())).query(); - assertThat(q, instanceOf(BooleanQuery.class)); - bq = (BooleanQuery) q; - assertEquals(8, bq.clauses().size()); - for (BooleanClause clause : bq.clauses()) { - DummyQuery dummy = (DummyQuery) clause.getQuery(); - switch (clause.getOccur()) { - case FILTER: - case MUST_NOT: - assertEquals(true, dummy.isFilter); - break; - case MUST: - case SHOULD: - assertEquals(false, dummy.isFilter); - break; - default: - throw new AssertionError(); - } - } - } } diff --git a/core/src/test/java/org/elasticsearch/index/query/TemplateQueryParserTest.java b/core/src/test/java/org/elasticsearch/index/query/TemplateQueryParserTest.java index 984210d7818..65174b3acea 100644 --- a/core/src/test/java/org/elasticsearch/index/query/TemplateQueryParserTest.java +++ b/core/src/test/java/org/elasticsearch/index/query/TemplateQueryParserTest.java @@ -83,7 +83,6 @@ public class TemplateQueryParserTest extends ElasticsearchTestCase { new AnalysisModule(settings), new SimilarityModule(settings), new IndexNameModule(index), - new IndexQueryParserModule(settings), new FunctionScoreModule(), new AbstractModule() { @Override diff --git a/core/src/test/java/org/elasticsearch/index/query/guice/IndexQueryParserModuleTests.java b/core/src/test/java/org/elasticsearch/index/query/guice/IndexQueryParserModuleTests.java deleted file mode 100644 index a26e233caf7..00000000000 --- a/core/src/test/java/org/elasticsearch/index/query/guice/IndexQueryParserModuleTests.java +++ /dev/null @@ -1,51 +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.index.query.guice; - -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.index.query.IndexQueryParserService; -import org.elasticsearch.test.ElasticsearchSingleNodeTest; -import org.junit.Test; - -import static org.elasticsearch.common.settings.Settings.settingsBuilder; -import static org.hamcrest.Matchers.equalTo; - -/** - * - */ -public class IndexQueryParserModuleTests extends ElasticsearchSingleNodeTest { - - @Test - public void testCustomInjection() { - Settings settings = settingsBuilder() - .put("index.queryparser.query.my.type", MyJsonQueryParser.class) - .put("index.queryparser.query.my.param1", "value1") - .put("index.cache.filter.type", "none") - .put("name", "IndexQueryParserModuleTests") - .build(); - - IndexQueryParserService indexQueryParserService = createIndex("test", settings).queryParserService(); - - MyJsonQueryParser myJsonQueryParser = (MyJsonQueryParser) indexQueryParserService.queryParser("my"); - - assertThat(myJsonQueryParser.names()[0], equalTo("my")); - assertThat(myJsonQueryParser.settings().get("param1"), equalTo("value1")); - } -} diff --git a/core/src/test/java/org/elasticsearch/index/query/guice/MyJsonQueryParser.java b/core/src/test/java/org/elasticsearch/index/query/guice/MyJsonQueryParser.java deleted file mode 100644 index 582ef1313e7..00000000000 --- a/core/src/test/java/org/elasticsearch/index/query/guice/MyJsonQueryParser.java +++ /dev/null @@ -1,64 +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.index.query.guice; - -import org.apache.lucene.search.Query; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.inject.assistedinject.Assisted; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.index.AbstractIndexComponent; -import org.elasticsearch.index.Index; -import org.elasticsearch.index.query.QueryParseContext; -import org.elasticsearch.index.query.QueryParser; -import org.elasticsearch.index.query.QueryParsingException; -import org.elasticsearch.index.settings.IndexSettings; - -import java.io.IOException; - -/** - * - */ -public class MyJsonQueryParser extends AbstractIndexComponent implements QueryParser { - - private final String name; - - private final Settings settings; - - @Inject - public MyJsonQueryParser(Index index, @IndexSettings Settings indexSettings, @Assisted String name, @Assisted Settings settings) { - super(index, indexSettings); - this.name = name; - this.settings = settings; - } - - @Override - public String[] names() { - return new String[]{this.name}; - } - - @Override - public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException { - return null; - } - - public Settings settings() { - return settings; - } -} diff --git a/core/src/test/java/org/elasticsearch/index/query/plugin/IndexQueryParserPlugin2Tests.java b/core/src/test/java/org/elasticsearch/index/query/plugin/IndexQueryParserPlugin2Tests.java deleted file mode 100644 index 4e4420ca4af..00000000000 --- a/core/src/test/java/org/elasticsearch/index/query/plugin/IndexQueryParserPlugin2Tests.java +++ /dev/null @@ -1,99 +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.index.query.plugin; - -import org.elasticsearch.Version; -import org.elasticsearch.cluster.ClusterService; -import org.elasticsearch.cluster.metadata.IndexMetaData; -import org.elasticsearch.common.inject.AbstractModule; -import org.elasticsearch.common.inject.Injector; -import org.elasticsearch.common.inject.ModulesBuilder; -import org.elasticsearch.common.inject.util.Providers; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.settings.SettingsModule; -import org.elasticsearch.env.Environment; -import org.elasticsearch.env.EnvironmentModule; -import org.elasticsearch.index.Index; -import org.elasticsearch.index.IndexNameModule; -import org.elasticsearch.index.analysis.AnalysisModule; -import org.elasticsearch.index.cache.IndexCacheModule; -import org.elasticsearch.index.query.IndexQueryParserModule; -import org.elasticsearch.index.query.IndexQueryParserService; -import org.elasticsearch.index.query.functionscore.FunctionScoreModule; -import org.elasticsearch.index.settings.IndexSettingsModule; -import org.elasticsearch.index.similarity.SimilarityModule; -import org.elasticsearch.indices.breaker.CircuitBreakerService; -import org.elasticsearch.indices.breaker.NoneCircuitBreakerService; -import org.elasticsearch.indices.query.IndicesQueriesModule; -import org.elasticsearch.script.ScriptModule; -import org.elasticsearch.test.ElasticsearchTestCase; -import org.elasticsearch.threadpool.ThreadPool; -import org.elasticsearch.threadpool.ThreadPoolModule; -import org.junit.Test; - -import static org.hamcrest.Matchers.equalTo; - -/** - * - */ -public class IndexQueryParserPlugin2Tests extends ElasticsearchTestCase { - - @Test - public void testCustomInjection() throws InterruptedException { - Settings settings = Settings.builder() - .put("name", "testCustomInjection") - .put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT) - .put("path.home", createTempDir()).build(); - - IndexQueryParserModule queryParserModule = new IndexQueryParserModule(settings); - queryParserModule.addQueryParser("my", PluginJsonQueryParser.class); - - Index index = new Index("test"); - Injector injector = new ModulesBuilder().add( - new EnvironmentModule(new Environment(settings)), - new SettingsModule(settings), - new ThreadPoolModule(new ThreadPool(settings)), - new IndicesQueriesModule(), - new ScriptModule(settings), - new IndexSettingsModule(index, settings), - new IndexCacheModule(settings), - new AnalysisModule(settings), - new SimilarityModule(settings), - queryParserModule, - new IndexNameModule(index), - new FunctionScoreModule(), - new AbstractModule() { - @Override - protected void configure() { - bind(ClusterService.class).toProvider(Providers.of((ClusterService) null)); - bind(CircuitBreakerService.class).to(NoneCircuitBreakerService.class); - } - } - ).createInjector(); - - IndexQueryParserService indexQueryParserService = injector.getInstance(IndexQueryParserService.class); - - PluginJsonQueryParser myJsonQueryParser = (PluginJsonQueryParser) indexQueryParserService.queryParser("my"); - - assertThat(myJsonQueryParser.names()[0], equalTo("my")); - - terminate(injector.getInstance(ThreadPool.class)); - } -} diff --git a/core/src/test/java/org/elasticsearch/index/query/plugin/IndexQueryParserPluginTests.java b/core/src/test/java/org/elasticsearch/index/query/plugin/IndexQueryParserPluginTests.java deleted file mode 100644 index 57a0d99741e..00000000000 --- a/core/src/test/java/org/elasticsearch/index/query/plugin/IndexQueryParserPluginTests.java +++ /dev/null @@ -1,104 +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.index.query.plugin; - -import org.elasticsearch.Version; -import org.elasticsearch.cluster.ClusterService; -import org.elasticsearch.cluster.metadata.IndexMetaData; -import org.elasticsearch.common.inject.AbstractModule; -import org.elasticsearch.common.inject.Injector; -import org.elasticsearch.common.inject.ModulesBuilder; -import org.elasticsearch.common.inject.util.Providers; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.settings.SettingsModule; -import org.elasticsearch.env.Environment; -import org.elasticsearch.env.EnvironmentModule; -import org.elasticsearch.index.Index; -import org.elasticsearch.index.IndexNameModule; -import org.elasticsearch.index.analysis.AnalysisModule; -import org.elasticsearch.index.cache.IndexCacheModule; -import org.elasticsearch.index.query.IndexQueryParserModule; -import org.elasticsearch.index.query.IndexQueryParserService; -import org.elasticsearch.index.query.functionscore.FunctionScoreModule; -import org.elasticsearch.index.settings.IndexSettingsModule; -import org.elasticsearch.index.similarity.SimilarityModule; -import org.elasticsearch.indices.breaker.CircuitBreakerService; -import org.elasticsearch.indices.breaker.NoneCircuitBreakerService; -import org.elasticsearch.indices.query.IndicesQueriesModule; -import org.elasticsearch.script.ScriptModule; -import org.elasticsearch.test.ElasticsearchTestCase; -import org.elasticsearch.threadpool.ThreadPool; -import org.elasticsearch.threadpool.ThreadPoolModule; -import org.junit.Test; - -import static org.hamcrest.Matchers.equalTo; - -/** - * - */ -public class IndexQueryParserPluginTests extends ElasticsearchTestCase { - - @Test - public void testCustomInjection() throws InterruptedException { - Settings settings = Settings.builder() - .put("name", "testCustomInjection") - .put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT) - .put("path.home", createTempDir()).build(); - - IndexQueryParserModule queryParserModule = new IndexQueryParserModule(settings); - queryParserModule.addProcessor(new IndexQueryParserModule.QueryParsersProcessor() { - @Override - public void processXContentQueryParsers(XContentQueryParsersBindings bindings) { - bindings.processXContentQueryParser("my", PluginJsonQueryParser.class); - } - }); - - Index index = new Index("test"); - Injector injector = new ModulesBuilder().add( - new EnvironmentModule(new Environment(settings)), - new SettingsModule(settings), - new ThreadPoolModule(new ThreadPool(settings)), - new IndicesQueriesModule(), - new ScriptModule(settings), - new IndexSettingsModule(index, settings), - new IndexCacheModule(settings), - new AnalysisModule(settings), - new SimilarityModule(settings), - queryParserModule, - new IndexNameModule(index), - new FunctionScoreModule(), - new AbstractModule() { - @Override - protected void configure() { - bind(ClusterService.class).toProvider(Providers.of((ClusterService) null)); - bind(CircuitBreakerService.class).to(NoneCircuitBreakerService.class); - } - } - ).createInjector(); - - IndexQueryParserService indexQueryParserService = injector.getInstance(IndexQueryParserService.class); - - PluginJsonQueryParser myJsonQueryParser = (PluginJsonQueryParser) indexQueryParserService.queryParser("my"); - - assertThat(myJsonQueryParser.names()[0], equalTo("my")); - - terminate(injector.getInstance(ThreadPool.class)); - } -} diff --git a/core/src/test/java/org/elasticsearch/index/query/plugin/PluginJsonQueryParser.java b/core/src/test/java/org/elasticsearch/index/query/plugin/PluginJsonQueryParser.java deleted file mode 100644 index d475cdfefae..00000000000 --- a/core/src/test/java/org/elasticsearch/index/query/plugin/PluginJsonQueryParser.java +++ /dev/null @@ -1,64 +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.index.query.plugin; - -import org.apache.lucene.search.Query; -import org.elasticsearch.common.inject.Inject; -import org.elasticsearch.common.inject.assistedinject.Assisted; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.index.AbstractIndexComponent; -import org.elasticsearch.index.Index; -import org.elasticsearch.index.query.QueryParseContext; -import org.elasticsearch.index.query.QueryParser; -import org.elasticsearch.index.query.QueryParsingException; -import org.elasticsearch.index.settings.IndexSettings; - -import java.io.IOException; - -/** - * - */ -public class PluginJsonQueryParser extends AbstractIndexComponent implements QueryParser { - - private final String name; - - private final Settings settings; - - @Inject - public PluginJsonQueryParser(Index index, @IndexSettings Settings indexSettings, @Assisted String name, @Assisted Settings settings) { - super(index, indexSettings); - this.name = name; - this.settings = settings; - } - - @Override - public String[] names() { - return new String[]{this.name}; - } - - @Override - public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException { - return null; - } - - public Settings settings() { - return settings; - } -} \ No newline at end of file diff --git a/docs/reference/migration/migrate_2_0.asciidoc b/docs/reference/migration/migrate_2_0.asciidoc index 6a12ac3bbbc..eff219c5887 100644 --- a/docs/reference/migration/migrate_2_0.asciidoc +++ b/docs/reference/migration/migrate_2_0.asciidoc @@ -490,6 +490,10 @@ ignored. Instead filters are always used as their own cache key and elasticsearc makes decisions by itself about whether it should cache filters based on how often they are used. +Java plugins that register custom queries can do so by using the +`IndicesQueriesModule#addQuery(Class)` method. Other +ways to register custom queries are not supported anymore. + ==== Query/filter merge Elasticsearch no longer makes a difference between queries and filters in the diff --git a/src/test/java/org/elasticsearch/index/query/plugin/CustomQueryParserTests.java b/src/test/java/org/elasticsearch/index/query/plugin/CustomQueryParserTests.java new file mode 100644 index 00000000000..9e396b7e8d1 --- /dev/null +++ b/src/test/java/org/elasticsearch/index/query/plugin/CustomQueryParserTests.java @@ -0,0 +1,138 @@ +/* + * 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.index.query.plugin; + +import org.apache.lucene.search.BooleanClause; +import org.apache.lucene.search.BooleanQuery; +import org.apache.lucene.search.ConstantScoreQuery; +import org.apache.lucene.search.Query; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.index.query.BoolQueryBuilder; +import org.elasticsearch.index.query.IndexQueryParserService; +import org.elasticsearch.indices.IndicesService; +import org.elasticsearch.test.ElasticsearchIntegrationTest; +import org.junit.Before; +import org.junit.Test; + +import static org.elasticsearch.index.query.QueryBuilders.boolQuery; +import static org.elasticsearch.index.query.QueryBuilders.constantScoreQuery; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; +import static org.hamcrest.Matchers.instanceOf; + +public class CustomQueryParserTests extends ElasticsearchIntegrationTest { + + @Override + protected Settings nodeSettings(int nodeOrdinal) { + return Settings.builder().put(super.nodeSettings(nodeOrdinal)) + .put("plugin.types", DummyQueryParserPlugin.class.getName()).build(); + } + + @Before + public void setUp() throws Exception { + super.setUp(); + createIndex("test"); + ensureGreen(); + client().prepareIndex("index", "type", "1").setSource("field", "value").get(); + refresh(); + } + + @Override + protected int numberOfShards() { + return cluster().numDataNodes(); + } + + @Test + public void testCustomDummyQuery() { + assertHitCount(client().prepareSearch("index").setQuery(new DummyQueryParserPlugin.DummyQueryBuilder()).get(), 1l); + } + + @Test + public void testCustomDummyQueryWithinBooleanQuery() { + assertHitCount(client().prepareSearch("index").setQuery(new BoolQueryBuilder().must(new DummyQueryParserPlugin.DummyQueryBuilder())).get(), 1l); + } + + private static IndexQueryParserService queryParser() { + IndicesService indicesService = internalCluster().getDataNodeInstance(IndicesService.class); + return indicesService.indexServiceSafe("index").queryParserService(); + } + + @Test //see #11120 + public void testConstantScoreParsesFilter() throws Exception { + IndexQueryParserService queryParser = queryParser(); + Query q = queryParser.parse(constantScoreQuery(new DummyQueryParserPlugin.DummyQueryBuilder())).query(); + Query inner = ((ConstantScoreQuery) q).getQuery(); + assertThat(inner, instanceOf(DummyQueryParserPlugin.DummyQuery.class)); + assertEquals(true, ((DummyQueryParserPlugin.DummyQuery) inner).isFilter); + } + + @Test //see #11120 + public void testBooleanParsesFilter() throws Exception { + IndexQueryParserService queryParser = queryParser(); + // single clause, serialized as inner object + Query q = queryParser.parse(boolQuery() + .should(new DummyQueryParserPlugin.DummyQueryBuilder()) + .must(new DummyQueryParserPlugin.DummyQueryBuilder()) + .filter(new DummyQueryParserPlugin.DummyQueryBuilder()) + .mustNot(new DummyQueryParserPlugin.DummyQueryBuilder())).query(); + assertThat(q, instanceOf(BooleanQuery.class)); + BooleanQuery bq = (BooleanQuery) q; + assertEquals(4, bq.clauses().size()); + for (BooleanClause clause : bq.clauses()) { + DummyQueryParserPlugin.DummyQuery dummy = (DummyQueryParserPlugin.DummyQuery) clause.getQuery(); + switch (clause.getOccur()) { + case FILTER: + case MUST_NOT: + assertEquals(true, dummy.isFilter); + break; + case MUST: + case SHOULD: + assertEquals(false, dummy.isFilter); + break; + default: + throw new AssertionError(); + } + } + + // multiple clauses, serialized as inner arrays + q = queryParser.parse(boolQuery() + .should(new DummyQueryParserPlugin.DummyQueryBuilder()).should(new DummyQueryParserPlugin.DummyQueryBuilder()) + .must(new DummyQueryParserPlugin.DummyQueryBuilder()).must(new DummyQueryParserPlugin.DummyQueryBuilder()) + .filter(new DummyQueryParserPlugin.DummyQueryBuilder()).filter(new DummyQueryParserPlugin.DummyQueryBuilder()) + .mustNot(new DummyQueryParserPlugin.DummyQueryBuilder()).mustNot(new DummyQueryParserPlugin.DummyQueryBuilder())).query(); + assertThat(q, instanceOf(BooleanQuery.class)); + bq = (BooleanQuery) q; + assertEquals(8, bq.clauses().size()); + for (BooleanClause clause : bq.clauses()) { + DummyQueryParserPlugin.DummyQuery dummy = (DummyQueryParserPlugin.DummyQuery) clause.getQuery(); + switch (clause.getOccur()) { + case FILTER: + case MUST_NOT: + assertEquals(true, dummy.isFilter); + break; + case MUST: + case SHOULD: + assertEquals(false, dummy.isFilter); + break; + default: + throw new AssertionError(); + } + } + } +} diff --git a/src/test/java/org/elasticsearch/index/query/plugin/DummyQueryParserPlugin.java b/src/test/java/org/elasticsearch/index/query/plugin/DummyQueryParserPlugin.java new file mode 100644 index 00000000000..b25668a06c8 --- /dev/null +++ b/src/test/java/org/elasticsearch/index/query/plugin/DummyQueryParserPlugin.java @@ -0,0 +1,102 @@ +/* + * 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.index.query.plugin; + +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.MatchAllDocsQuery; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.Weight; +import org.elasticsearch.common.inject.Module; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.index.query.QueryBuilder; +import org.elasticsearch.index.query.QueryParseContext; +import org.elasticsearch.index.query.QueryParser; +import org.elasticsearch.index.query.QueryParsingException; +import org.elasticsearch.indices.query.IndicesQueriesModule; +import org.elasticsearch.plugins.AbstractPlugin; + +import java.io.IOException; + +public class DummyQueryParserPlugin extends AbstractPlugin { + + @Override + public String name() { + return "dummy"; + } + + @Override + public String description() { + return "dummy query"; + } + + @Override + public void processModule(Module module) { + if (module instanceof IndicesQueriesModule) { + IndicesQueriesModule indicesQueriesModule = (IndicesQueriesModule) module; + indicesQueriesModule.addQuery(DummyQueryParserPlugin.DummyQueryParser.class); + } + } + + public Settings settings() { + return Settings.EMPTY; + } + + public static class DummyQueryBuilder extends QueryBuilder { + @Override + protected void doXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject("dummy").endObject(); + } + } + + public static class DummyQueryParser implements QueryParser { + @Override + public String[] names() { + return new String[]{"dummy"}; + } + + @Override + public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException { + XContentParser.Token token = parseContext.parser().nextToken(); + assert token == XContentParser.Token.END_OBJECT; + return new DummyQuery(parseContext.isFilter()); + } + } + + public static class DummyQuery extends Query { + public final boolean isFilter; + private final Query matchAllDocsQuery = new MatchAllDocsQuery(); + + private DummyQuery(boolean isFilter) { + this.isFilter = isFilter; + } + + @Override + public String toString(String field) { + return getClass().getSimpleName(); + } + + @Override + public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException { + return matchAllDocsQuery.createWeight(searcher, needsScores); + } + } +} \ No newline at end of file