Skip to content

Commit d1f317c

Browse files
committed
Core: Also check if indices resolved via aliases resolution aren't closed and deal with this according to IndicesOptions.
Closes #9057
1 parent 80db20c commit d1f317c

File tree

4 files changed

+104
-13
lines changed

4 files changed

+104
-13
lines changed

docs/reference/api-conventions.asciidoc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ Controls whether to fail if a wildcard indices expressions results into no
3939
concrete indices. Either `true` or `false` can be specified. For example if
4040
the wildcard expression `foo*` is specified and no indices are available that
4141
start with `foo` then depending on this setting the request will fail. This
42-
setting is also applicable when `_all`, `*` or no index has been specified.
42+
setting is also applicable when `_all`, `*` or no index has been specified. This
43+
settings also applies for aliases, in case an alias points to a closed index.
4344

4445
`expand_wildcards`::
4546

src/main/java/org/elasticsearch/action/support/IndicesOptions.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ public boolean ignoreUnavailable() {
7272
/**
7373
* @return Whether to ignore if a wildcard expression resolves to no concrete indices.
7474
* The `_all` string or empty list of indices count as wildcard expressions too.
75+
* Also when an alias points to a closed index this option decides if no concrete indices
76+
* are allowed.
7577
*/
7678
public boolean allowNoIndices() {
7779
return (id & ALLOW_NO_INDICES) != 0;

src/main/java/org/elasticsearch/cluster/metadata/MetaData.java

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,7 @@ public String[] concreteIndices(IndicesOptions indicesOptions, String... aliases
688688

689689
// optimize for single element index (common case)
690690
if (aliasesOrIndices.length == 1) {
691-
return concreteIndices(aliasesOrIndices[0], indicesOptions, indicesOptions.allowNoIndices());
691+
return concreteIndices(aliasesOrIndices[0], indicesOptions, !indicesOptions.allowNoIndices());
692692
}
693693

694694
// check if its a possible aliased index, if not, just return the passed array
@@ -721,7 +721,7 @@ public String[] concreteIndices(IndicesOptions indicesOptions, String... aliases
721721

722722
Set<String> actualIndices = new HashSet<>();
723723
for (String aliasOrIndex : aliasesOrIndices) {
724-
String[] indices = concreteIndices(aliasOrIndex, indicesOptions, indicesOptions.ignoreUnavailable());
724+
String[] indices = concreteIndices(aliasOrIndex, indicesOptions, !indicesOptions.ignoreUnavailable());
725725
Collections.addAll(actualIndices, indices);
726726
}
727727

@@ -769,24 +769,53 @@ private String[] concreteIndices(String aliasOrIndex, IndicesOptions options, bo
769769
}
770770
// not an actual index, fetch from an alias
771771
String[] indices = aliasAndIndexToIndexMap.getOrDefault(aliasOrIndex, Strings.EMPTY_ARRAY);
772-
if (indices.length == 0 && !failNoIndices) {
772+
if (indices.length == 0 && failNoIndices) {
773773
throw new IndexMissingException(new Index(aliasOrIndex));
774774
}
775775
if (indices.length > 1 && !options.allowAliasesToMultipleIndices()) {
776776
throw new ElasticsearchIllegalArgumentException("Alias [" + aliasOrIndex + "] has more than one indices associated with it [" + Arrays.toString(indices) + "], can't execute a single index op");
777777
}
778778

779-
indexMetaData = this.indices.get(aliasOrIndex);
780-
if (indexMetaData != null && indexMetaData.getState() == IndexMetaData.State.CLOSE) {
781-
if (failClosed) {
782-
throw new IndexClosedException(new Index(aliasOrIndex));
783-
} else {
784-
if (options.forbidClosedIndices()) {
785-
return Strings.EMPTY_ARRAY;
779+
// No need to check whether indices referred by aliases are closed, because there are no closed indices.
780+
if (allClosedIndices.length == 0) {
781+
return indices;
782+
}
783+
784+
switch (indices.length) {
785+
case 0:
786+
return indices;
787+
case 1:
788+
indexMetaData = this.indices.get(indices[0]);
789+
if (indexMetaData != null && indexMetaData.getState() == IndexMetaData.State.CLOSE) {
790+
if (failClosed) {
791+
throw new IndexClosedException(new Index(indexMetaData.getIndex()));
792+
} else {
793+
if (options.forbidClosedIndices()) {
794+
return Strings.EMPTY_ARRAY;
795+
}
796+
}
786797
}
787-
}
798+
return indices;
799+
default:
800+
ObjectArrayList<String> concreteIndices = new ObjectArrayList<>();
801+
for (String index : indices) {
802+
indexMetaData = this.indices.get(index);
803+
if (indexMetaData != null) {
804+
if (indexMetaData.getState() == IndexMetaData.State.CLOSE) {
805+
if (failClosed) {
806+
throw new IndexClosedException(new Index(indexMetaData.getIndex()));
807+
} else if (!options.forbidClosedIndices()) {
808+
concreteIndices.add(index);
809+
}
810+
} else if (indexMetaData.getState() == IndexMetaData.State.OPEN) {
811+
concreteIndices.add(index);
812+
} else {
813+
throw new IllegalStateException("index state [" + indexMetaData.getState() + "] not supported");
814+
}
815+
}
816+
}
817+
return concreteIndices.toArray(String.class);
788818
}
789-
return indices;
790819
}
791820

792821
/**

src/test/java/org/elasticsearch/cluster/metadata/MetaDataTests.java

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,65 @@ public void testIsPatternMatchingAllIndices_nonMatchingTrailingWildcardAndExclus
718718
assertThat(metaData.isPatternMatchingAllIndices(indicesOrAliases, concreteIndices), equalTo(false));
719719
}
720720

721+
@Test
722+
public void testIndexOptions_failClosedIndicesAndAliases() {
723+
MetaData.Builder mdBuilder = MetaData.builder()
724+
.put(indexBuilder("foo1-closed").state(IndexMetaData.State.CLOSE).putAlias(AliasMetaData.builder("foobar1-closed")).putAlias(AliasMetaData.builder("foobar2-closed")))
725+
.put(indexBuilder("foo2-closed").state(IndexMetaData.State.CLOSE).putAlias(AliasMetaData.builder("foobar2-closed")))
726+
.put(indexBuilder("foo3").putAlias(AliasMetaData.builder("foobar2-closed")));
727+
MetaData md = mdBuilder.build();
728+
729+
IndicesOptions options = IndicesOptions.strictExpandOpenAndForbidClosed();
730+
try {
731+
md.concreteIndices(options, "foo1-closed");
732+
fail("foo1-closed should be closed, but it is open");
733+
} catch (IndexClosedException e) {
734+
// expected
735+
}
736+
737+
try {
738+
md.concreteIndices(options, "foobar1-closed");
739+
fail("foo1-closed should be closed, but it is open");
740+
} catch (IndexClosedException e) {
741+
// expected
742+
}
743+
744+
options = IndicesOptions.fromOptions(true, options.allowNoIndices(), options.expandWildcardsOpen(), options.expandWildcardsClosed(), options);
745+
String[] results = md.concreteIndices(options, "foo1-closed");
746+
assertThat(results, emptyArray());
747+
748+
results = md.concreteIndices(options, "foobar1-closed");
749+
assertThat(results, emptyArray());
750+
751+
options = IndicesOptions.lenientExpandOpen();
752+
results = md.concreteIndices(options, "foo1-closed");
753+
assertThat(results, arrayWithSize(1));
754+
assertThat(results, arrayContaining("foo1-closed"));
755+
756+
results = md.concreteIndices(options, "foobar1-closed");
757+
assertThat(results, arrayWithSize(1));
758+
assertThat(results, arrayContaining("foo1-closed"));
759+
760+
// testing an alias pointing to three indices:
761+
options = IndicesOptions.strictExpandOpenAndForbidClosed();
762+
try {
763+
md.concreteIndices(options, "foobar2-closed");
764+
fail("foo2-closed should be closed, but it is open");
765+
} catch (IndexClosedException e) {
766+
// expected
767+
}
768+
769+
options = IndicesOptions.fromOptions(true, options.allowNoIndices(), options.expandWildcardsOpen(), options.expandWildcardsClosed(), options);
770+
results = md.concreteIndices(options, "foobar2-closed");
771+
assertThat(results, arrayWithSize(1));
772+
assertThat(results, arrayContaining("foo3"));
773+
774+
options = IndicesOptions.lenientExpandOpen();
775+
results = md.concreteIndices(options, "foobar2-closed");
776+
assertThat(results, arrayWithSize(3));
777+
assertThat(results, arrayContainingInAnyOrder("foo1-closed", "foo2-closed", "foo3"));
778+
}
779+
721780
private MetaData metaDataBuilder(String... indices) {
722781
MetaData.Builder mdBuilder = MetaData.builder();
723782
for (String concreteIndex : indices) {

0 commit comments

Comments
 (0)