Core: Also check if indices resolved via aliases resolution aren't closed and deal with this according to IndicesOptions.
Closes #9057
This commit is contained in:
parent
b0b61ee0c3
commit
dedaf9387e
|
@ -39,7 +39,8 @@ Controls whether to fail if a wildcard indices expressions results into no
|
|||
concrete indices. Either `true` or `false` can be specified. For example if
|
||||
the wildcard expression `foo*` is specified and no indices are available that
|
||||
start with `foo` then depending on this setting the request will fail. This
|
||||
setting is also applicable when `_all`, `*` or no index has been specified.
|
||||
setting is also applicable when `_all`, `*` or no index has been specified. This
|
||||
settings also applies for aliases, in case an alias points to a closed index.
|
||||
|
||||
`expand_wildcards`::
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
package org.elasticsearch.action.support;
|
||||
|
||||
import org.elasticsearch.ElasticsearchIllegalArgumentException;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
|
@ -72,6 +71,8 @@ public class IndicesOptions {
|
|||
/**
|
||||
* @return Whether to ignore if a wildcard expression resolves to no concrete indices.
|
||||
* The `_all` string or empty list of indices count as wildcard expressions too.
|
||||
* Also when an alias points to a closed index this option decides if no concrete indices
|
||||
* are allowed.
|
||||
*/
|
||||
public boolean allowNoIndices() {
|
||||
return (id & ALLOW_NO_INDICES) != 0;
|
||||
|
|
|
@ -679,7 +679,7 @@ public class MetaData implements Iterable<IndexMetaData> {
|
|||
|
||||
// optimize for single element index (common case)
|
||||
if (aliasesOrIndices.length == 1) {
|
||||
return concreteIndices(aliasesOrIndices[0], indicesOptions, indicesOptions.allowNoIndices());
|
||||
return concreteIndices(aliasesOrIndices[0], indicesOptions, !indicesOptions.allowNoIndices());
|
||||
}
|
||||
|
||||
// check if its a possible aliased index, if not, just return the passed array
|
||||
|
@ -712,7 +712,7 @@ public class MetaData implements Iterable<IndexMetaData> {
|
|||
|
||||
Set<String> actualIndices = new HashSet<>();
|
||||
for (String aliasOrIndex : aliasesOrIndices) {
|
||||
String[] indices = concreteIndices(aliasOrIndex, indicesOptions, indicesOptions.ignoreUnavailable());
|
||||
String[] indices = concreteIndices(aliasOrIndex, indicesOptions, !indicesOptions.ignoreUnavailable());
|
||||
Collections.addAll(actualIndices, indices);
|
||||
}
|
||||
|
||||
|
@ -760,24 +760,53 @@ public class MetaData implements Iterable<IndexMetaData> {
|
|||
}
|
||||
// not an actual index, fetch from an alias
|
||||
String[] indices = aliasAndIndexToIndexMap.getOrDefault(aliasOrIndex, Strings.EMPTY_ARRAY);
|
||||
if (indices.length == 0 && !failNoIndices) {
|
||||
if (indices.length == 0 && failNoIndices) {
|
||||
throw new IndexMissingException(new Index(aliasOrIndex));
|
||||
}
|
||||
if (indices.length > 1 && !options.allowAliasesToMultipleIndices()) {
|
||||
throw new ElasticsearchIllegalArgumentException("Alias [" + aliasOrIndex + "] has more than one indices associated with it [" + Arrays.toString(indices) + "], can't execute a single index op");
|
||||
}
|
||||
|
||||
indexMetaData = this.indices.get(aliasOrIndex);
|
||||
if (indexMetaData != null && indexMetaData.getState() == IndexMetaData.State.CLOSE) {
|
||||
if (failClosed) {
|
||||
throw new IndexClosedException(new Index(aliasOrIndex));
|
||||
} else {
|
||||
if (options.forbidClosedIndices()) {
|
||||
return Strings.EMPTY_ARRAY;
|
||||
}
|
||||
}
|
||||
// No need to check whether indices referred by aliases are closed, because there are no closed indices.
|
||||
if (allClosedIndices.length == 0) {
|
||||
return indices;
|
||||
}
|
||||
|
||||
switch (indices.length) {
|
||||
case 0:
|
||||
return indices;
|
||||
case 1:
|
||||
indexMetaData = this.indices.get(indices[0]);
|
||||
if (indexMetaData != null && indexMetaData.getState() == IndexMetaData.State.CLOSE) {
|
||||
if (failClosed) {
|
||||
throw new IndexClosedException(new Index(indexMetaData.getIndex()));
|
||||
} else {
|
||||
if (options.forbidClosedIndices()) {
|
||||
return Strings.EMPTY_ARRAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
return indices;
|
||||
default:
|
||||
ObjectArrayList<String> concreteIndices = new ObjectArrayList<>();
|
||||
for (String index : indices) {
|
||||
indexMetaData = this.indices.get(index);
|
||||
if (indexMetaData != null) {
|
||||
if (indexMetaData.getState() == IndexMetaData.State.CLOSE) {
|
||||
if (failClosed) {
|
||||
throw new IndexClosedException(new Index(indexMetaData.getIndex()));
|
||||
} else if (!options.forbidClosedIndices()) {
|
||||
concreteIndices.add(index);
|
||||
}
|
||||
} else if (indexMetaData.getState() == IndexMetaData.State.OPEN) {
|
||||
concreteIndices.add(index);
|
||||
} else {
|
||||
throw new IllegalStateException("index state [" + indexMetaData.getState() + "] not supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
return concreteIndices.toArray(String.class);
|
||||
}
|
||||
return indices;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -718,6 +718,65 @@ public class MetaDataTests extends ElasticsearchTestCase {
|
|||
assertThat(metaData.isPatternMatchingAllIndices(indicesOrAliases, concreteIndices), equalTo(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndexOptions_failClosedIndicesAndAliases() {
|
||||
MetaData.Builder mdBuilder = MetaData.builder()
|
||||
.put(indexBuilder("foo1-closed").state(IndexMetaData.State.CLOSE).putAlias(AliasMetaData.builder("foobar1-closed")).putAlias(AliasMetaData.builder("foobar2-closed")))
|
||||
.put(indexBuilder("foo2-closed").state(IndexMetaData.State.CLOSE).putAlias(AliasMetaData.builder("foobar2-closed")))
|
||||
.put(indexBuilder("foo3").putAlias(AliasMetaData.builder("foobar2-closed")));
|
||||
MetaData md = mdBuilder.build();
|
||||
|
||||
IndicesOptions options = IndicesOptions.strictExpandOpenAndForbidClosed();
|
||||
try {
|
||||
md.concreteIndices(options, "foo1-closed");
|
||||
fail("foo1-closed should be closed, but it is open");
|
||||
} catch (IndexClosedException e) {
|
||||
// expected
|
||||
}
|
||||
|
||||
try {
|
||||
md.concreteIndices(options, "foobar1-closed");
|
||||
fail("foo1-closed should be closed, but it is open");
|
||||
} catch (IndexClosedException e) {
|
||||
// expected
|
||||
}
|
||||
|
||||
options = IndicesOptions.fromOptions(true, options.allowNoIndices(), options.expandWildcardsOpen(), options.expandWildcardsClosed(), options);
|
||||
String[] results = md.concreteIndices(options, "foo1-closed");
|
||||
assertThat(results, emptyArray());
|
||||
|
||||
results = md.concreteIndices(options, "foobar1-closed");
|
||||
assertThat(results, emptyArray());
|
||||
|
||||
options = IndicesOptions.lenientExpandOpen();
|
||||
results = md.concreteIndices(options, "foo1-closed");
|
||||
assertThat(results, arrayWithSize(1));
|
||||
assertThat(results, arrayContaining("foo1-closed"));
|
||||
|
||||
results = md.concreteIndices(options, "foobar1-closed");
|
||||
assertThat(results, arrayWithSize(1));
|
||||
assertThat(results, arrayContaining("foo1-closed"));
|
||||
|
||||
// testing an alias pointing to three indices:
|
||||
options = IndicesOptions.strictExpandOpenAndForbidClosed();
|
||||
try {
|
||||
md.concreteIndices(options, "foobar2-closed");
|
||||
fail("foo2-closed should be closed, but it is open");
|
||||
} catch (IndexClosedException e) {
|
||||
// expected
|
||||
}
|
||||
|
||||
options = IndicesOptions.fromOptions(true, options.allowNoIndices(), options.expandWildcardsOpen(), options.expandWildcardsClosed(), options);
|
||||
results = md.concreteIndices(options, "foobar2-closed");
|
||||
assertThat(results, arrayWithSize(1));
|
||||
assertThat(results, arrayContaining("foo3"));
|
||||
|
||||
options = IndicesOptions.lenientExpandOpen();
|
||||
results = md.concreteIndices(options, "foobar2-closed");
|
||||
assertThat(results, arrayWithSize(3));
|
||||
assertThat(results, arrayContainingInAnyOrder("foo1-closed", "foo2-closed", "foo3"));
|
||||
}
|
||||
|
||||
private MetaData metaDataBuilder(String... indices) {
|
||||
MetaData.Builder mdBuilder = MetaData.builder();
|
||||
for (String concreteIndex : indices) {
|
||||
|
|
Loading…
Reference in New Issue