Skip to content

Commit

Permalink
Allow partial indices options in watches
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 elastic#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 elastic#68022
Backport of elastic#68076
  • Loading branch information
jaymode committed Jan 28, 2021
1 parent dc28cac commit ee5768f
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", List.of("open", "closed"), List.of("open", "hidden"),
List.of("closed"), List.of("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.99.99"
reason: "watch parsing with partial indices options was broken in 7.10.1"
- 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 }
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 ee5768f

Please sign in to comment.