Skip to content

Commit

Permalink
Allow partial indices options in watches (#68139)
Browse files Browse the repository at this point in the history
Partially defined indices options have always been allowed in watches,
but the cleanup in #65332 removed this ability and made the definition
of indices options within a watch require all fields. This change fixes
this by updating the parsing to accept a default indices options and
add test coverage for this scenario.

Closes #68022
Backport of #68076
  • Loading branch information
jaymode committed Jan 28, 2021
1 parent 4e19256 commit 7542a8f
Show file tree
Hide file tree
Showing 5 changed files with 206 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -395,10 +396,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> 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> 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) {
Expand All @@ -409,7 +415,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()) {
Expand All @@ -428,7 +435,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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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<WildcardStates> 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();
Expand Down
5 changes: 3 additions & 2 deletions x-pack/docs/en/watcher/transform/search.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -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` <<templates,templates>>.

| `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 <<multi-index,multi-index support>>)

| `request.indices_options.ignore_unavailable` | no | `true` | A boolean value that determines whether the search
Expand Down
Original file line number Diff line number Diff line change
@@ -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.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_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.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_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 }
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 7542a8f

Please sign in to comment.