diff --git a/server/src/main/java/org/elasticsearch/action/support/IndicesOptions.java b/server/src/main/java/org/elasticsearch/action/support/IndicesOptions.java index 676112c2eb88d..d452f3d6fdaa1 100644 --- a/server/src/main/java/org/elasticsearch/action/support/IndicesOptions.java +++ b/server/src/main/java/org/elasticsearch/action/support/IndicesOptions.java @@ -20,6 +20,7 @@ import org.elasticsearch.Version; import org.elasticsearch.ElasticsearchParseException; +import org.elasticsearch.common.Nullable; import org.elasticsearch.common.ParseField; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; @@ -388,10 +389,15 @@ public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params par private static final ParseField ALLOW_NO_INDICES_FIELD = new ParseField("allow_no_indices"); public static IndicesOptions fromXContent(XContentParser parser) throws IOException { - EnumSet wildcardStates = null; - Boolean allowNoIndices = null; - Boolean ignoreUnavailable = null; - boolean ignoreThrottled = false; + return fromXContent(parser, null); + } + + public static IndicesOptions fromXContent(XContentParser parser, @Nullable IndicesOptions defaults) throws IOException { + boolean parsedWildcardStates = false; + EnumSet wildcardStates = defaults == null ? null : defaults.getExpandWildcards(); + Boolean allowNoIndices = defaults == null ? null : defaults.allowNoIndices(); + Boolean ignoreUnavailable = defaults == null ? null : defaults.ignoreUnavailable(); + boolean ignoreThrottled = defaults == null ? false : defaults.ignoreThrottled(); Token token = parser.currentToken() == Token.START_OBJECT ? parser.currentToken() : parser.nextToken(); String currentFieldName = null; if (token != Token.START_OBJECT) { @@ -402,7 +408,8 @@ public static IndicesOptions fromXContent(XContentParser parser) throws IOExcept currentFieldName = parser.currentName(); } else if (token == Token.START_ARRAY) { if (EXPAND_WILDCARDS_FIELD.match(currentFieldName, parser.getDeprecationHandler())) { - if (wildcardStates == null) { + if (parsedWildcardStates == false) { + parsedWildcardStates = true; wildcardStates = EnumSet.noneOf(WildcardStates.class); while ((token = parser.nextToken()) != Token.END_ARRAY) { if (token.isValue()) { @@ -421,7 +428,8 @@ public static IndicesOptions fromXContent(XContentParser parser) throws IOExcept } } else if (token.isValue()) { if (EXPAND_WILDCARDS_FIELD.match(currentFieldName, parser.getDeprecationHandler())) { - if (wildcardStates == null) { + if (parsedWildcardStates == false) { + parsedWildcardStates = true; wildcardStates = EnumSet.noneOf(WildcardStates.class); WildcardStates.updateSetForValue(wildcardStates, parser.text()); } else { diff --git a/server/src/test/java/org/elasticsearch/action/support/IndicesOptionsTests.java b/server/src/test/java/org/elasticsearch/action/support/IndicesOptionsTests.java index d2826a96e3d2c..63ea669e29c4a 100644 --- a/server/src/test/java/org/elasticsearch/action/support/IndicesOptionsTests.java +++ b/server/src/test/java/org/elasticsearch/action/support/IndicesOptionsTests.java @@ -42,6 +42,7 @@ import java.util.EnumSet; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.OptionalInt; @@ -420,6 +421,50 @@ public void testFromXContentWithWildcardSpecialValues() throws IOException { assertFalse(fromXContentOptions.expandWildcardsOpen()); } + public void testFromXContentWithDefaults() throws Exception { + XContentType type = randomFrom(XContentType.values()); + final IndicesOptions defaults = IndicesOptions.LENIENT_EXPAND_OPEN; + final boolean includeExpandWildcards = randomBoolean(); + final EnumSet expectedWildcardStates = includeExpandWildcards ? + WildcardStates.parseParameter(randomFrom("all", "none", Arrays.asList("open", "closed"), Arrays.asList("open", "hidden"), + Collections.singletonList("closed"), Arrays.asList("closed", "hidden")), null) : + defaults.getExpandWildcards(); + final boolean includeIgnoreUnavailable = randomBoolean(); + final boolean ignoreUnavailable = includeIgnoreUnavailable ? randomBoolean() : defaults.ignoreUnavailable(); + final boolean includeAllowNoIndices = randomBoolean(); + final boolean allowNoIndices = includeAllowNoIndices ? randomBoolean() : defaults.allowNoIndices(); + + BytesReference xContentBytes; + try (XContentBuilder builder = XContentFactory.contentBuilder(type)) { + builder.startObject(); + if (includeExpandWildcards) { + builder.startArray("expand_wildcards"); + for (WildcardStates state : expectedWildcardStates) { + builder.value(state.toString().toLowerCase(Locale.ROOT)); + } + builder.endArray(); + } + + if (includeIgnoreUnavailable) { + builder.field("ignore_unavailable", ignoreUnavailable); + } + if (includeAllowNoIndices) { + builder.field("allow_no_indices", allowNoIndices); + } + builder.endObject(); + xContentBytes = BytesReference.bytes(builder); + } + + IndicesOptions fromXContentOptions; + try (XContentParser parser = type.xContent().createParser( + NamedXContentRegistry.EMPTY, null, xContentBytes.streamInput())) { + fromXContentOptions = IndicesOptions.fromXContent(parser, defaults); + } + assertEquals(ignoreUnavailable, fromXContentOptions.ignoreUnavailable()); + assertEquals(allowNoIndices, fromXContentOptions.allowNoIndices()); + assertEquals(expectedWildcardStates, fromXContentOptions.getExpandWildcards()); + } + private BytesReference toXContentBytes(IndicesOptions indicesOptions, XContentType type) throws IOException { try (XContentBuilder builder = XContentFactory.contentBuilder(type)) { builder.startObject(); diff --git a/x-pack/docs/en/watcher/transform/search.asciidoc b/x-pack/docs/en/watcher/transform/search.asciidoc index 66ba502ea4b1e..dd722a21c2319 100644 --- a/x-pack/docs/en/watcher/transform/search.asciidoc +++ b/x-pack/docs/en/watcher/transform/search.asciidoc @@ -68,8 +68,9 @@ The following table lists all available settings for the search a REST `_search` request. The body can be static text or include `mustache` <>. -| `request.indices_options.expand_wildcards` | no | `open` | Determines how to expand indices wildcards. Can be one - of `open`, `closed`, `none` or `all` +| `request.indices_options.expand_wildcards` | no | `open` | Determines how to expand indices wildcards. An array + consisting of a combination of `open`, `closed`, + and `hidden`. Alternatively a value of `none` or `all`. (see <>) | `request.indices_options.ignore_unavailable` | no | `true` | A boolean value that determines whether the search diff --git a/x-pack/plugin/watcher/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/watcher/put_watch/92_put_watch_with_indices_options.yml b/x-pack/plugin/watcher/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/watcher/put_watch/92_put_watch_with_indices_options.yml new file mode 100644 index 0000000000000..b2258507f5155 --- /dev/null +++ b/x-pack/plugin/watcher/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/watcher/put_watch/92_put_watch_with_indices_options.yml @@ -0,0 +1,143 @@ +--- +setup: + - do: + cluster.health: + wait_for_status: yellow + +--- +"Test put watch with allow no indices": + - skip: + version: "7.10.1 - 7.10.2" + reason: "watch parsing with partial indices options was broken in 7.10.1 and 7.10.2" + - do: + watcher.put_watch: + id: "my_watch_allow_no_indices" + body: > + { + "trigger": { + "schedule" : { "cron" : "0 0 0 1 * ? 2099" } + }, + "input": { + "search" : { + "request" : { + "indices" : [ "my_test_index" ], + "rest_total_hits_as_int": false, + "body" : { + "query": { + "match_all" : {} + } + }, + "indices_options" : { + "allow_no_indices" : false + } + } + } + }, + "actions": { + "test_index": { + "index": { + "index": "test" + } + } + } + } + - match: { _id: "my_watch_allow_no_indices" } + + - do: + watcher.get_watch: + id: "my_watch_allow_no_indices" + - match: { found : true} + - match: { _id: "my_watch_allow_no_indices" } + - match: { watch.input.search.request.indices_options.allow_no_indices: false } + +--- +"Test put watch with expand wildcards": + - skip: + version: "7.10.1 - 7.99.99" + reason: "watch parsing with partial indices options was broken in 7.10.1" + - do: + watcher.put_watch: + id: "my_watch_expand_wildcards" + body: > + { + "trigger": { + "schedule" : { "cron" : "0 0 0 1 * ? 2099" } + }, + "input": { + "search" : { + "request" : { + "indices" : [ "my_test_index" ], + "rest_total_hits_as_int": false, + "body" : { + "query": { + "match_all" : {} + } + }, + "indices_options" : { + "expand_wildcards" : [ "open", "hidden" ] + } + } + } + }, + "actions": { + "test_index": { + "index": { + "index": "test" + } + } + } + } + - match: { _id: "my_watch_expand_wildcards" } + + - do: + watcher.get_watch: + id: "my_watch_expand_wildcards" + - match: { found : true} + - match: { _id: "my_watch_expand_wildcards" } + - match: { watch.input.search.request.indices_options.expand_wildcards: [ "open", "hidden" ] } + +--- +"Test put watch with ignore unavailable": + - skip: + version: "7.10.1 - 7.99.99" + reason: "watch parsing with partial indices options was broken in 7.10.1" + - do: + watcher.put_watch: + id: "my_watch_ignore_unavailable" + body: > + { + "trigger": { + "schedule" : { "cron" : "0 0 0 1 * ? 2099" } + }, + "input": { + "search" : { + "request" : { + "indices" : [ "my_test_index" ], + "rest_total_hits_as_int": false, + "body" : { + "query": { + "match_all" : {} + } + }, + "indices_options" : { + "ignore_unavailable" : false + } + } + } + }, + "actions": { + "test_index": { + "index": { + "index": "test" + } + } + } + } + - match: { _id: "my_watch_ignore_unavailable" } + + - do: + watcher.get_watch: + id: "my_watch_ignore_unavailable" + - match: { found : true} + - match: { _id: "my_watch_ignore_unavailable" } + - match: { watch.input.search.request.indices_options.ignore_unavailable: false } diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/support/search/WatcherSearchTemplateRequest.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/support/search/WatcherSearchTemplateRequest.java index 07efc45ebd9bb..ba04a20cac4c4 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/support/search/WatcherSearchTemplateRequest.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/support/search/WatcherSearchTemplateRequest.java @@ -216,7 +216,7 @@ public static WatcherSearchTemplateRequest fromXContent(XContentParser parser, S searchSource = BytesReference.bytes(builder); } } else if (INDICES_OPTIONS_FIELD.match(currentFieldName, parser.getDeprecationHandler())) { - indicesOptions = IndicesOptions.fromXContent(parser); + indicesOptions = IndicesOptions.fromXContent(parser, DEFAULT_INDICES_OPTIONS); } else if (TEMPLATE_FIELD.match(currentFieldName, parser.getDeprecationHandler())) { template = Script.parse(parser, Script.DEFAULT_TEMPLATE_LANG); } else {