/* * 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.apache.lucene.search.MatchAllDocsQuery; import org.apache.lucene.search.Query; 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.multibindings.Multibinder; import org.elasticsearch.common.inject.util.Providers; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; 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.functionscore.ScoreFunctionParser; import org.elasticsearch.index.settings.IndexSettingsModule; import org.elasticsearch.index.similarity.SimilarityModule; import org.elasticsearch.indices.IndicesModule; import org.elasticsearch.indices.analysis.IndicesAnalysisService; import org.elasticsearch.indices.breaker.CircuitBreakerService; import org.elasticsearch.indices.breaker.NoneCircuitBreakerService; import org.elasticsearch.indices.fielddata.cache.IndicesFieldDataCache; import org.elasticsearch.indices.mapper.MapperRegistry; import org.elasticsearch.indices.query.IndicesQueriesRegistry; import org.elasticsearch.script.ScriptModule; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPoolModule; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.io.IOException; /** * Test parsing and executing a template request. */ // NOTE: this can't be migrated to ESSingleNodeTestCase because of the custom path.conf public class TemplateQueryParserTests extends ESTestCase { private Injector injector; private QueryParseContext context; @Before public void setup() throws IOException { Settings settings = Settings.settingsBuilder() .put("path.home", createTempDir().toString()) .put("path.conf", this.getDataPath("config")) .put("name", getClass().getName()) .put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT) .build(); Index index = new Index("test"); injector = new ModulesBuilder().add( new EnvironmentModule(new Environment(settings)), new SettingsModule(settings), new ThreadPoolModule(new ThreadPool(settings)), new IndicesModule() { @Override public void configure() { // skip services bindQueryParsersExtension(); bindMapperExtension(); } }, new ScriptModule(settings), new IndexSettingsModule(index, settings), new IndexCacheModule(settings), new AnalysisModule(settings, new IndicesAnalysisService(settings)), new SimilarityModule(settings), new IndexNameModule(index), new AbstractModule() { @Override protected void configure() { Multibinder.newSetBinder(binder(), ScoreFunctionParser.class); bind(ClusterService.class).toProvider(Providers.of((ClusterService) null)); bind(CircuitBreakerService.class).to(NoneCircuitBreakerService.class); } } ).createInjector(); IndexQueryParserService queryParserService = injector.getInstance(IndexQueryParserService.class); context = new QueryParseContext(index, queryParserService); } @Override @After public void tearDown() throws Exception { super.tearDown(); terminate(injector.getInstance(ThreadPool.class)); } @Test public void testParser() throws IOException { String templateString = "{" + "\"query\":{\"match_{{template}}\": {}}," + "\"params\":{\"template\":\"all\"}" + "}"; XContentParser templateSourceParser = XContentFactory.xContent(templateString).createParser(templateString); context.reset(templateSourceParser); templateSourceParser.nextToken(); TemplateQueryParser parser = injector.getInstance(TemplateQueryParser.class); Query query = parser.parse(context); assertTrue("Parsing template query failed.", query instanceof MatchAllDocsQuery); } @Test public void testParseTemplateAsSingleStringWithConditionalClause() throws IOException { String templateString = "{" + " \"inline\" : \"{ \\\"match_{{#use_it}}{{template}}{{/use_it}}\\\":{} }\"," + " \"params\":{" + " \"template\":\"all\"," + " \"use_it\": true" + " }" + "}"; XContentParser templateSourceParser = XContentFactory.xContent(templateString).createParser(templateString); context.reset(templateSourceParser); TemplateQueryParser parser = injector.getInstance(TemplateQueryParser.class); Query query = parser.parse(context); assertTrue("Parsing template query failed.", query instanceof MatchAllDocsQuery); } /** * Test that the template query parser can parse and evaluate template * expressed as a single string but still it expects only the query * specification (thus this test should fail with specific exception). */ @Test(expected = QueryParsingException.class) public void testParseTemplateFailsToParseCompleteQueryAsSingleString() throws IOException { String templateString = "{" + " \"inline\" : \"{ \\\"size\\\": \\\"{{size}}\\\", \\\"query\\\":{\\\"match_all\\\":{}}}\"," + " \"params\":{" + " \"size\":2" + " }\n" + "}"; XContentParser templateSourceParser = XContentFactory.xContent(templateString).createParser(templateString); context.reset(templateSourceParser); TemplateQueryParser parser = injector.getInstance(TemplateQueryParser.class); parser.parse(context); } @Test public void testParserCanExtractTemplateNames() throws Exception { String templateString = "{ \"file\": \"storedTemplate\" ,\"params\":{\"template\":\"all\" } } "; XContentParser templateSourceParser = XContentFactory.xContent(templateString).createParser(templateString); context.reset(templateSourceParser); templateSourceParser.nextToken(); TemplateQueryParser parser = injector.getInstance(TemplateQueryParser.class); Query query = parser.parse(context); assertTrue("Parsing template query failed.", query instanceof MatchAllDocsQuery); } }