From b57e887095c915fc8f76283f9beb565df4f6c0ba Mon Sep 17 00:00:00 2001 From: Brian Murphy Date: Fri, 1 May 2015 11:08:21 -0400 Subject: [PATCH] Disallow the use of SCAN search type This change disallows the SCAN search type in our search requests used by search input and search transform. Add tests for this and update the current tests to both detect SCAN and not use SCAN in valid tests. Original commit: elastic/x-pack-elasticsearch@c9d61930c8a0932033129af245a3447ff8d85ed4 --- .../watcher/support/WatcherUtils.java | 3 ++ .../input/search/SearchInputTests.java | 30 ++++++++++++++---- .../watcher/support/WatcherUtilsTests.java | 5 +-- .../watcher/test/WatcherTestUtils.java | 10 ++++++ .../search/SearchTransformTests.java | 31 ++++++++++++++----- 5 files changed, 64 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/elasticsearch/watcher/support/WatcherUtils.java b/src/main/java/org/elasticsearch/watcher/support/WatcherUtils.java index 8fba7dabc96..63b8b17c524 100644 --- a/src/main/java/org/elasticsearch/watcher/support/WatcherUtils.java +++ b/src/main/java/org/elasticsearch/watcher/support/WatcherUtils.java @@ -208,6 +208,9 @@ public final class WatcherUtils { searchRequest.types(Strings.delimitedListToStringArray(typesStr, ",", " \t")); } else if (SEARCH_TYPE_FIELD.match(currentFieldName)) { searchType = SearchType.fromString(parser.text().toLowerCase(Locale.ROOT)); + if (searchType == SearchType.SCAN){ + throw new SearchRequestParseException("could not read search request. value [" + searchType.name() + "] is not supported for field [" + SEARCH_TYPE_FIELD.getPreferredName() + "]" ); + } } else { throw new SearchRequestParseException("could not read search request. unexpected string field [" + currentFieldName + "]"); } diff --git a/src/test/java/org/elasticsearch/watcher/input/search/SearchInputTests.java b/src/test/java/org/elasticsearch/watcher/input/search/SearchInputTests.java index e618b4e72ab..229f01bb0a9 100644 --- a/src/test/java/org/elasticsearch/watcher/input/search/SearchInputTests.java +++ b/src/test/java/org/elasticsearch/watcher/input/search/SearchInputTests.java @@ -39,10 +39,7 @@ import org.elasticsearch.watcher.watch.Watch; import org.junit.Test; import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import static org.elasticsearch.common.joda.time.DateTimeZone.UTC; import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder; @@ -51,6 +48,7 @@ import static org.elasticsearch.index.query.FilterBuilders.rangeFilter; import static org.elasticsearch.index.query.QueryBuilders.filteredQuery; import static org.elasticsearch.index.query.QueryBuilders.matchQuery; import static org.elasticsearch.search.builder.SearchSourceBuilder.searchSource; +import static org.elasticsearch.watcher.test.WatcherTestUtils.getRandomSupportedSearchType; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.mockito.Mockito.mock; @@ -178,13 +176,13 @@ public class SearchInputTests extends ElasticsearchIntegrationTest { executeSearchInput(request).executedRequest(); } - @Test public void testDifferentSearchType() throws Exception { SearchSourceBuilder searchSourceBuilder = searchSource().query( filteredQuery(matchQuery("event_type", "a"), rangeFilter("_timestamp").from("{{ctx.trigger.scheduled_time}}||-30s").to("{{ctx.trigger.triggered_time}}")) ); - SearchType searchType = randomFrom(SearchType.values()); + SearchType searchType = getRandomSupportedSearchType(); + SearchRequest request = client() .prepareSearch() .setSearchType(searchType) @@ -237,6 +235,26 @@ public class SearchInputTests extends ElasticsearchIntegrationTest { assertEquals(SearchInput.TYPE, searchInput.type()); } + @Test(expected = SearchInputException.class) + public void testParser_ScanNotSupported() throws Exception { + SearchRequest request = client().prepareSearch() + .setSearchType(SearchType.SCAN) + .request() + .source(searchSource() + .query(filteredQuery(matchQuery("event_type", "a"), rangeFilter("_timestamp").from("{{ctx.trigger.scheduled_time}}||-30s").to("{{ctx.trigger.triggered_time}}")))); + + XContentBuilder builder = jsonBuilder().value(new SearchInput(request, null)); + XContentParser parser = JsonXContent.jsonXContent.createParser(builder.bytes()); + parser.nextToken(); + + SearchInputFactory factory = new SearchInputFactory(ImmutableSettings.EMPTY, + ScriptServiceProxy.of(internalCluster().getInstance(ScriptService.class)), + ClientProxy.of(client())); + + factory.parseInput("_id", parser); + fail("expected a SearchInputException as search type SCAN should not be supported"); + } + @Test(expected = SearchInputException.class) public void testParser_Invalid() throws Exception { SearchInputFactory factory = new SearchInputFactory(settingsBuilder().build(), diff --git a/src/test/java/org/elasticsearch/watcher/support/WatcherUtilsTests.java b/src/test/java/org/elasticsearch/watcher/support/WatcherUtilsTests.java index 1bc3dd944bb..76ceb022969 100644 --- a/src/test/java/org/elasticsearch/watcher/support/WatcherUtilsTests.java +++ b/src/test/java/org/elasticsearch/watcher/support/WatcherUtilsTests.java @@ -30,6 +30,7 @@ import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.watcher.support.WatcherDateUtils.formatDate; import static org.elasticsearch.watcher.support.WatcherUtils.DEFAULT_INDICES_OPTIONS; import static org.elasticsearch.watcher.support.WatcherUtils.flattenModel; +import static org.elasticsearch.watcher.test.WatcherTestUtils.getRandomSupportedSearchType; import static org.hamcrest.Matchers.*; /** @@ -96,7 +97,7 @@ public class WatcherUtilsTests extends ElasticsearchTestCase { } expectedRequest.indicesOptions(IndicesOptions.fromOptions(randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean(), WatcherUtils.DEFAULT_INDICES_OPTIONS)); - expectedRequest.searchType(randomFrom(SearchType.values())); + expectedRequest.searchType(getRandomSupportedSearchType()); SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.searchSource().query(QueryBuilders.matchAllQuery()).size(11); XContentBuilder searchSourceJsonBuilder = jsonBuilder(); @@ -173,7 +174,7 @@ public class WatcherUtilsTests extends ElasticsearchTestCase { SearchType searchType = SearchType.DEFAULT; if (randomBoolean()) { - searchType = randomFrom(SearchType.values()); + searchType = getRandomSupportedSearchType(); builder.field("search_type", randomBoolean() ? searchType.name() : searchType.name().toLowerCase(Locale.ROOT)); } diff --git a/src/test/java/org/elasticsearch/watcher/test/WatcherTestUtils.java b/src/test/java/org/elasticsearch/watcher/test/WatcherTestUtils.java index 74256c0a12e..1eee16ea110 100644 --- a/src/test/java/org/elasticsearch/watcher/test/WatcherTestUtils.java +++ b/src/test/java/org/elasticsearch/watcher/test/WatcherTestUtils.java @@ -6,6 +6,7 @@ package org.elasticsearch.watcher.test; import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.action.search.SearchType; import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.common.Strings; import org.elasticsearch.common.collect.ImmutableMap; @@ -68,6 +69,7 @@ import java.util.*; import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; import static org.elasticsearch.search.builder.SearchSourceBuilder.searchSource; +import static org.elasticsearch.test.ElasticsearchTestCase.randomFrom; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -211,4 +213,12 @@ public final class WatcherTestUtils { return ScriptServiceProxy.of(new ScriptService(settings, new Environment(), engineServiceSet, new ResourceWatcherService(settings, tp), nodeSettingsService)); } + + public static SearchType getRandomSupportedSearchType() { + Set searchTypes = new HashSet<>(); + searchTypes.addAll(Arrays.asList(SearchType.values())); + searchTypes.remove(SearchType.SCAN); + return randomFrom(searchTypes.toArray(new SearchType[searchTypes.size()])); + } + } diff --git a/src/test/java/org/elasticsearch/watcher/transform/search/SearchTransformTests.java b/src/test/java/org/elasticsearch/watcher/transform/search/SearchTransformTests.java index 19d326ad928..4b914f755d1 100644 --- a/src/test/java/org/elasticsearch/watcher/transform/search/SearchTransformTests.java +++ b/src/test/java/org/elasticsearch/watcher/transform/search/SearchTransformTests.java @@ -42,10 +42,7 @@ import org.elasticsearch.watcher.watch.Watch; import org.junit.Test; import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import static org.elasticsearch.common.joda.time.DateTimeZone.UTC; import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder; @@ -169,7 +166,7 @@ public class SearchTransformTests extends AbstractWatcherIntegrationTests { @Test public void testParser() throws Exception { String[] indices = rarely() ? null : randomBoolean() ? new String[] { "idx" } : new String[] { "idx1", "idx2" }; - SearchType searchType = randomBoolean() ? null : randomFrom(SearchType.values()); + SearchType searchType = getRandomSupportedSearchType(); String templateName = randomBoolean() ? null : "template1"; ScriptService.ScriptType templateType = templateName != null && randomBoolean() ? randomFrom(ScriptService.ScriptType.values()) : null; XContentBuilder builder = jsonBuilder().startObject(); @@ -225,6 +222,27 @@ public class SearchTransformTests extends AbstractWatcherIntegrationTests { assertThat(executable.transform().getRequest().source().toBytes(), equalTo(source.toBytes())); } + @Test(expected = SearchTransformException.class) + public void testParser_ScanNotSupported() throws Exception { + SearchRequest request = client().prepareSearch() + .setSearchType(SearchType.SCAN) + .request() + .source(searchSource() + .query(filteredQuery(matchQuery("event_type", "a"), rangeFilter("_timestamp").from("{{ctx.trigger.scheduled_time}}||-30s").to("{{ctx.trigger.triggered_time}}")))); + + XContentBuilder builder = jsonBuilder().value(new SearchTransform(request)); + XContentParser parser = JsonXContent.jsonXContent.createParser(builder.bytes()); + parser.nextToken(); + + SearchTransformFactory factory = new SearchTransformFactory(ImmutableSettings.EMPTY, + scriptService(), + ClientProxy.of(client())); + + factory.parseTransform("_id", parser); + fail("expected a SearchTransformException as search type SCAN should not be supported"); + } + + @Test public void testSearch_InlineTemplate() throws Exception { final String templateQuery = "{\"query\":{\"filtered\":{\"query\":{\"match\":{\"event_type\":{\"query\":\"a\"," + @@ -250,7 +268,6 @@ public class SearchTransformTests extends AbstractWatcherIntegrationTests { .setTemplateType(scriptType) .request(); - SearchTransform.Result executedResult = executeSearchTransform(request); assertThat(executedResult.executedRequest().source().toUtf8(), equalTo(expectedQuery)); @@ -310,7 +327,7 @@ public class SearchTransformTests extends AbstractWatcherIntegrationTests { SearchSourceBuilder searchSourceBuilder = searchSource().query( filteredQuery(matchQuery("event_type", "a"), rangeFilter("_timestamp").from("{{ctx.trigger.scheduled_time}}||-30s").to("{{ctx.trigger.triggered_time}}")) ); - SearchType searchType = randomFrom(SearchType.values()); + SearchType searchType = getRandomSupportedSearchType(); SearchRequest request = client() .prepareSearch() .setSearchType(searchType)