diff --git a/core/src/main/java/org/elasticsearch/cluster/metadata/IndexNameExpressionResolver.java b/core/src/main/java/org/elasticsearch/cluster/metadata/IndexNameExpressionResolver.java index 5f9bf5e370af3..17b43efdf9d85 100644 --- a/core/src/main/java/org/elasticsearch/cluster/metadata/IndexNameExpressionResolver.java +++ b/core/src/main/java/org/elasticsearch/cluster/metadata/IndexNameExpressionResolver.java @@ -175,7 +175,7 @@ Index[] concreteIndices(Context context, String... indexExpressions) { final Set concreteIndices = new HashSet<>(expressions.size()); for (String expression : expressions) { AliasOrIndex aliasOrIndex = metaData.getAliasAndIndexLookup().get(expression); - if (aliasOrIndex == null || (aliasOrIndex.isAlias() && context.getOptions().ignoreAliases())) { + if (aliasOrIndex == null ) { if (failNoIndices) { IndexNotFoundException infe = new IndexNotFoundException(expression); infe.setResources("index_expression", expression); @@ -183,6 +183,12 @@ Index[] concreteIndices(Context context, String... indexExpressions) { } else { continue; } + } else if (aliasOrIndex.isAlias() && context.getOptions().ignoreAliases()) { + if (failNoIndices) { + throw aliasesNotSupportedException(expression); + } else { + continue; + } } Collection resolvedIndices = aliasOrIndex.getIndices(); @@ -192,7 +198,8 @@ Index[] concreteIndices(Context context, String... indexExpressions) { for (IndexMetaData indexMetaData : resolvedIndices) { indexNames[i++] = indexMetaData.getIndex().getName(); } - throw new IllegalArgumentException("Alias [" + expression + "] has more than one indices associated with it [" + Arrays.toString(indexNames) + "], can't execute a single index op"); + throw new IllegalArgumentException("Alias [" + expression + "] has more than one indices associated with it [" + + Arrays.toString(indexNames) + "], can't execute a single index op"); } for (IndexMetaData index : resolvedIndices) { @@ -220,6 +227,11 @@ Index[] concreteIndices(Context context, String... indexExpressions) { return concreteIndices.toArray(new Index[concreteIndices.size()]); } + private static IllegalArgumentException aliasesNotSupportedException(String expression) { + return new IllegalArgumentException("The provided expression [" + expression + "] matches an " + + "alias, specify the corresponding concrete indices instead."); + } + /** * Utility method that allows to resolve an index expression to its corresponding single concrete index. * Callers should make sure they provide proper {@link org.elasticsearch.action.support.IndicesOptions} @@ -270,8 +282,7 @@ public String[] filteringAliases(ClusterState state, String index, String... exp } /** - * Iterates through the list of indices and selects the effective list of required aliases for the - * given index. + * Iterates through the list of indices and selects the effective list of required aliases for the given index. *

Only aliases where the given predicate tests successfully are returned. If the indices list contains a non-required reference to * the index itself - null is returned. Returns null if no filtering is required. */ @@ -588,7 +599,7 @@ private Set innerResolve(Context context, List expressions, Indi for (int i = 0; i < expressions.size(); i++) { String expression = expressions.get(i); if (Strings.isEmpty(expression)) { - throw infe(expression); + throw indexNotFoundException(expression); } if (aliasOrIndexExists(options, metaData, expression)) { if (result != null) { @@ -608,8 +619,14 @@ private Set innerResolve(Context context, List expressions, Indi result = new HashSet<>(expressions.subList(0, i)); } if (!Regex.isSimpleMatchPattern(expression)) { - if (!unavailableIgnoredOrExists(options, metaData, expression)) { - throw infe(expression); + //TODO why does wildcard resolver throw exceptions regarding non wildcarded expressions? This should not be done here. + if (options.ignoreUnavailable() == false) { + AliasOrIndex aliasOrIndex = metaData.getAliasAndIndexLookup().get(expression); + if (aliasOrIndex == null) { + throw indexNotFoundException(expression); + } else if (aliasOrIndex.isAlias() && options.ignoreAliases()) { + throw aliasesNotSupportedException(expression); + } } if (add) { result.add(expression); @@ -628,7 +645,7 @@ private Set innerResolve(Context context, List expressions, Indi result.removeAll(expand); } if (options.allowNoIndices() == false && matches.isEmpty()) { - throw infe(expression); + throw indexNotFoundException(expression); } if (Regex.isSimpleMatchPattern(expression)) { wildcardSeen = true; @@ -637,17 +654,13 @@ private Set innerResolve(Context context, List expressions, Indi return result; } - private static boolean unavailableIgnoredOrExists(IndicesOptions options, MetaData metaData, String expression) { - return options.ignoreUnavailable() || aliasOrIndexExists(options, metaData, expression); - } - private static boolean aliasOrIndexExists(IndicesOptions options, MetaData metaData, String expression) { AliasOrIndex aliasOrIndex = metaData.getAliasAndIndexLookup().get(expression); //treat aliases as unavailable indices when ignoreAliases is set to true (e.g. delete index and update aliases api) return aliasOrIndex != null && (options.ignoreAliases() == false || aliasOrIndex.isAlias() == false); } - private static IndexNotFoundException infe(String expression) { + private static IndexNotFoundException indexNotFoundException(String expression) { IndexNotFoundException infe = new IndexNotFoundException(expression); infe.setResources("index_or_alias", expression); return infe; diff --git a/core/src/test/java/org/elasticsearch/aliases/IndexAliasesIT.java b/core/src/test/java/org/elasticsearch/aliases/IndexAliasesIT.java index 9526b5b97e6eb..8bf074be551b1 100644 --- a/core/src/test/java/org/elasticsearch/aliases/IndexAliasesIT.java +++ b/core/src/test/java/org/elasticsearch/aliases/IndexAliasesIT.java @@ -33,11 +33,9 @@ import org.elasticsearch.cluster.metadata.AliasOrIndex; import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.common.StopWatch; -import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.index.IndexNotFoundException; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.rest.action.admin.indices.AliasesNotFoundException; @@ -442,8 +440,10 @@ public void testDeleteAliases() throws Exception { assertTrue(admin().indices().prepareAliasesExist("foo").get().exists()); assertFalse(admin().indices().prepareAliasesExist("foo").setIndices("foo_foo").get().exists()); assertTrue(admin().indices().prepareAliasesExist("foo").setIndices("bar_bar").get().exists()); - expectThrows(IndexNotFoundException.class, () -> admin().indices().prepareAliases() + IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, () -> admin().indices().prepareAliases() .addAliasAction(AliasActions.remove().index("foo").alias("foo")).execute().actionGet()); + assertEquals("The provided expression [foo] matches an alias, specify the corresponding concrete indices instead.", + iae.getMessage()); } public void testWaitForAliasCreationMultipleShards() throws Exception { @@ -824,10 +824,10 @@ public void testAliasesCanBeAddedToIndicesOnly() throws Exception { logger.info("--> adding [week_20] alias to [2017-05-20]"); assertAcked(admin().indices().prepareAliases().addAlias("2017-05-20", "week_20")); - IndexNotFoundException infe = expectThrows(IndexNotFoundException.class, () -> admin().indices().prepareAliases() + IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, () -> admin().indices().prepareAliases() .addAliasAction(AliasActions.add().index("week_20").alias("tmp")).execute().actionGet()); - assertEquals("week_20", infe.getIndex().getName()); - + assertEquals("The provided expression [week_20] matches an alias, specify the corresponding concrete indices instead.", + iae.getMessage()); assertAcked(admin().indices().prepareAliases().addAliasAction(AliasActions.add().index("2017-05-20").alias("tmp")).execute().get()); } @@ -916,8 +916,10 @@ public void testAliasActionRemoveIndex() throws InterruptedException, ExecutionE assertAcked(admin().indices().prepareAliases().addAlias("foo_foo", "foo")); assertAcked(admin().indices().prepareAliases().addAlias("bar_bar", "foo")); - expectThrows(IndexNotFoundException.class, + IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, () -> client().admin().indices().prepareAliases().removeIndex("foo").execute().actionGet()); + assertEquals("The provided expression [foo] matches an alias, specify the corresponding concrete indices instead.", + iae.getMessage()); assertAcked(client().admin().indices().prepareAliases().removeIndex("foo*").execute().get()); assertFalse(client().admin().indices().prepareExists("foo_foo").execute().actionGet().isExists()); diff --git a/core/src/test/java/org/elasticsearch/cluster/metadata/IndexNameExpressionResolverTests.java b/core/src/test/java/org/elasticsearch/cluster/metadata/IndexNameExpressionResolverTests.java index 0f543daa62693..5e04714552248 100644 --- a/core/src/test/java/org/elasticsearch/cluster/metadata/IndexNameExpressionResolverTests.java +++ b/core/src/test/java/org/elasticsearch/cluster/metadata/IndexNameExpressionResolverTests.java @@ -657,9 +657,10 @@ public void testConcreteIndicesWildcardAndAliases() { assertEquals(1, indexNamesIndexWildcard.length); assertEquals("foo_foo", indexNamesIndexWildcard[0]); - IndexNotFoundException infe = expectThrows(IndexNotFoundException.class, + IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, () -> indexNameExpressionResolver.concreteIndexNames(state, ignoreAliasesOptions, "foo")); - assertThat(infe.getIndex().getName(), equalTo("foo")); + assertEquals("The provided expression [foo] matches an alias, specify the corresponding concrete indices instead.", + iae.getMessage()); // when ignoreAliases option is not set, concreteIndexNames resolves the provided // expressions against the defined indices and aliases @@ -1005,11 +1006,13 @@ public void testDeleteIndexIgnoresAliases() { IndexNotFoundException infe = expectThrows(IndexNotFoundException.class, () -> indexNameExpressionResolver.concreteIndexNames(state, new DeleteIndexRequest("does_not_exist"))); assertEquals("does_not_exist", infe.getIndex().getName()); + assertEquals("no such index", infe.getMessage()); } { - IndexNotFoundException infe = expectThrows(IndexNotFoundException.class, + IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, () -> indexNameExpressionResolver.concreteIndexNames(state, new DeleteIndexRequest("test-alias"))); - assertEquals("test-alias", infe.getIndex().getName()); + assertEquals("The provided expression [test-alias] matches an alias, " + + "specify the corresponding concrete indices instead.", iae.getMessage()); } { DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("test-alias"); @@ -1049,11 +1052,16 @@ public void testIndicesAliasesRequestIgnoresAliases() { ClusterState state = ClusterState.builder(new ClusterName("_name")).metaData(mdBuilder).build(); { IndicesAliasesRequest.AliasActions aliasActions = IndicesAliasesRequest.AliasActions.add().index("test-alias"); - expectThrows(IndexNotFoundException.class, () -> indexNameExpressionResolver.concreteIndexNames(state, aliasActions)); + IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, + () -> indexNameExpressionResolver.concreteIndexNames(state, aliasActions)); + assertEquals("The provided expression [test-alias] matches an alias, " + + "specify the corresponding concrete indices instead.", iae.getMessage()); } { IndicesAliasesRequest.AliasActions aliasActions = IndicesAliasesRequest.AliasActions.add().index("test-a*"); - expectThrows(IndexNotFoundException.class, () -> indexNameExpressionResolver.concreteIndexNames(state, aliasActions)); + IndexNotFoundException infe = expectThrows(IndexNotFoundException.class, + () -> indexNameExpressionResolver.concreteIndexNames(state, aliasActions)); + assertEquals("test-a*", infe.getIndex().getName()); } { IndicesAliasesRequest.AliasActions aliasActions = IndicesAliasesRequest.AliasActions.add().index("test-index"); @@ -1069,11 +1077,16 @@ public void testIndicesAliasesRequestIgnoresAliases() { } { IndicesAliasesRequest.AliasActions aliasActions = IndicesAliasesRequest.AliasActions.remove().index("test-alias"); - expectThrows(IndexNotFoundException.class, () -> indexNameExpressionResolver.concreteIndexNames(state, aliasActions)); + IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, + () -> indexNameExpressionResolver.concreteIndexNames(state, aliasActions)); + assertEquals("The provided expression [test-alias] matches an alias, " + + "specify the corresponding concrete indices instead.", iae.getMessage()); } { IndicesAliasesRequest.AliasActions aliasActions = IndicesAliasesRequest.AliasActions.remove().index("test-a*"); - expectThrows(IndexNotFoundException.class, () -> indexNameExpressionResolver.concreteIndexNames(state, aliasActions)); + IndexNotFoundException infe = expectThrows(IndexNotFoundException.class, + () -> indexNameExpressionResolver.concreteIndexNames(state, aliasActions)); + assertEquals("test-a*", infe.getIndex().getName()); } { IndicesAliasesRequest.AliasActions aliasActions = IndicesAliasesRequest.AliasActions.remove().index("test-index"); @@ -1089,11 +1102,16 @@ public void testIndicesAliasesRequestIgnoresAliases() { } { IndicesAliasesRequest.AliasActions aliasActions = IndicesAliasesRequest.AliasActions.removeIndex().index("test-alias"); - expectThrows(IndexNotFoundException.class, () -> indexNameExpressionResolver.concreteIndexNames(state, aliasActions)); + IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, + () -> indexNameExpressionResolver.concreteIndexNames(state, aliasActions)); + assertEquals("The provided expression [test-alias] matches an alias, " + + "specify the corresponding concrete indices instead.", iae.getMessage()); } { IndicesAliasesRequest.AliasActions aliasActions = IndicesAliasesRequest.AliasActions.removeIndex().index("test-a*"); - expectThrows(IndexNotFoundException.class, () -> indexNameExpressionResolver.concreteIndexNames(state, aliasActions)); + IndexNotFoundException infe = expectThrows(IndexNotFoundException.class, + () -> indexNameExpressionResolver.concreteIndexNames(state, aliasActions)); + assertEquals("test-a*", infe.getIndex().getName()); } { IndicesAliasesRequest.AliasActions aliasActions = IndicesAliasesRequest.AliasActions.removeIndex().index("test-index"); diff --git a/core/src/test/java/org/elasticsearch/cluster/metadata/WildcardExpressionResolverTests.java b/core/src/test/java/org/elasticsearch/cluster/metadata/WildcardExpressionResolverTests.java index e918f2acd4f36..cb2913e5820e1 100644 --- a/core/src/test/java/org/elasticsearch/cluster/metadata/WildcardExpressionResolverTests.java +++ b/core/src/test/java/org/elasticsearch/cluster/metadata/WildcardExpressionResolverTests.java @@ -24,11 +24,16 @@ import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.IndexMetaData.State; +import org.elasticsearch.index.IndexNotFoundException; import org.elasticsearch.test.ESTestCase; import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Set; import static org.elasticsearch.common.util.set.Sets.newHashSet; +import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.equalTo; public class WildcardExpressionResolverTests extends ESTestCase { @@ -42,13 +47,13 @@ public void testConvertWildcardsJustIndicesTests() { IndexNameExpressionResolver.WildcardExpressionResolver resolver = new IndexNameExpressionResolver.WildcardExpressionResolver(); IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, IndicesOptions.lenientExpandOpen()); - assertThat(newHashSet(resolver.resolve(context, Arrays.asList("testXXX"))), equalTo(newHashSet("testXXX"))); + assertThat(newHashSet(resolver.resolve(context, Collections.singletonList("testXXX"))), equalTo(newHashSet("testXXX"))); assertThat(newHashSet(resolver.resolve(context, Arrays.asList("testXXX", "testYYY"))), equalTo(newHashSet("testXXX", "testYYY"))); assertThat(newHashSet(resolver.resolve(context, Arrays.asList("testXXX", "ku*"))), equalTo(newHashSet("testXXX", "kuku"))); - assertThat(newHashSet(resolver.resolve(context, Arrays.asList("test*"))), equalTo(newHashSet("testXXX", "testXYY", "testYYY"))); - assertThat(newHashSet(resolver.resolve(context, Arrays.asList("testX*"))), equalTo(newHashSet("testXXX", "testXYY"))); + assertThat(newHashSet(resolver.resolve(context, Collections.singletonList("test*"))), equalTo(newHashSet("testXXX", "testXYY", "testYYY"))); + assertThat(newHashSet(resolver.resolve(context, Collections.singletonList("testX*"))), equalTo(newHashSet("testXXX", "testXYY"))); assertThat(newHashSet(resolver.resolve(context, Arrays.asList("testX*", "kuku"))), equalTo(newHashSet("testXXX", "testXYY", "kuku"))); - assertThat(newHashSet(resolver.resolve(context, Arrays.asList("*"))), equalTo(newHashSet("testXXX", "testXYY", "testYYY", "kuku"))); + assertThat(newHashSet(resolver.resolve(context, Collections.singletonList("*"))), equalTo(newHashSet("testXXX", "testXYY", "testYYY", "kuku"))); assertThat(newHashSet(resolver.resolve(context, Arrays.asList("*", "-kuku"))), equalTo(newHashSet("testXXX", "testXYY", "testYYY"))); assertThat(newHashSet(resolver.resolve(context, Arrays.asList("testXXX", "testYYY"))), equalTo(newHashSet("testXXX", "testYYY"))); assertThat(newHashSet(resolver.resolve(context, Arrays.asList("testXXX", "-testXXX"))), equalTo(newHashSet("testXXX", "-testXXX"))); @@ -67,7 +72,7 @@ public void testConvertWildcardsTests() { IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, IndicesOptions.lenientExpandOpen()); assertThat(newHashSet(resolver.resolve(context, Arrays.asList("testYY*", "alias*"))), equalTo(newHashSet("testXXX", "testXYY", "testYYY"))); - assertThat(newHashSet(resolver.resolve(context, Arrays.asList("-kuku"))), equalTo(newHashSet("-kuku"))); + assertThat(newHashSet(resolver.resolve(context, Collections.singletonList("-kuku"))), equalTo(newHashSet("-kuku"))); assertThat(newHashSet(resolver.resolve(context, Arrays.asList("test*", "-testYYY"))), equalTo(newHashSet("testXXX", "testXYY"))); assertThat(newHashSet(resolver.resolve(context, Arrays.asList("testX*", "testYYY"))), equalTo(newHashSet("testXXX", "testXYY", "testYYY"))); assertThat(newHashSet(resolver.resolve(context, Arrays.asList("testYYY", "testX*"))), equalTo(newHashSet("testXXX", "testXYY", "testYYY"))); @@ -85,11 +90,11 @@ public void testConvertWildcardsOpenClosedIndicesTests() { IndexNameExpressionResolver.WildcardExpressionResolver resolver = new IndexNameExpressionResolver.WildcardExpressionResolver(); IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, IndicesOptions.fromOptions(true, true, true, true)); - assertThat(newHashSet(resolver.resolve(context, Arrays.asList("testX*"))), equalTo(newHashSet("testXXX", "testXXY", "testXYY"))); + assertThat(newHashSet(resolver.resolve(context, Collections.singletonList("testX*"))), equalTo(newHashSet("testXXX", "testXXY", "testXYY"))); context = new IndexNameExpressionResolver.Context(state, IndicesOptions.fromOptions(true, true, false, true)); - assertThat(newHashSet(resolver.resolve(context, Arrays.asList("testX*"))), equalTo(newHashSet("testXYY"))); + assertThat(newHashSet(resolver.resolve(context, Collections.singletonList("testX*"))), equalTo(newHashSet("testXYY"))); context = new IndexNameExpressionResolver.Context(state, IndicesOptions.fromOptions(true, true, true, false)); - assertThat(newHashSet(resolver.resolve(context, Arrays.asList("testX*"))), equalTo(newHashSet("testXXX", "testXXY"))); + assertThat(newHashSet(resolver.resolve(context, Collections.singletonList("testX*"))), equalTo(newHashSet("testXXX", "testXXY"))); } // issue #13334 @@ -106,12 +111,12 @@ public void testMultipleWildcards() { IndexNameExpressionResolver.WildcardExpressionResolver resolver = new IndexNameExpressionResolver.WildcardExpressionResolver(); IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, IndicesOptions.lenientExpandOpen()); - assertThat(newHashSet(resolver.resolve(context, Arrays.asList("test*X*"))), equalTo(newHashSet("testXXX", "testXXY", "testXYY"))); - assertThat(newHashSet(resolver.resolve(context, Arrays.asList("test*X*Y"))), equalTo(newHashSet("testXXY", "testXYY"))); - assertThat(newHashSet(resolver.resolve(context, Arrays.asList("kuku*Y*"))), equalTo(newHashSet("kukuYYY"))); - assertThat(newHashSet(resolver.resolve(context, Arrays.asList("*Y*"))), equalTo(newHashSet("testXXY", "testXYY", "testYYY", "kukuYYY"))); - assertThat(newHashSet(resolver.resolve(context, Arrays.asList("test*Y*X"))).size(), equalTo(0)); - assertThat(newHashSet(resolver.resolve(context, Arrays.asList("*Y*X"))).size(), equalTo(0)); + assertThat(newHashSet(resolver.resolve(context, Collections.singletonList("test*X*"))), equalTo(newHashSet("testXXX", "testXXY", "testXYY"))); + assertThat(newHashSet(resolver.resolve(context, Collections.singletonList("test*X*Y"))), equalTo(newHashSet("testXXY", "testXYY"))); + assertThat(newHashSet(resolver.resolve(context, Collections.singletonList("kuku*Y*"))), equalTo(newHashSet("kukuYYY"))); + assertThat(newHashSet(resolver.resolve(context, Collections.singletonList("*Y*"))), equalTo(newHashSet("testXXY", "testXYY", "testYYY", "kukuYYY"))); + assertThat(newHashSet(resolver.resolve(context, Collections.singletonList("test*Y*X"))).size(), equalTo(0)); + assertThat(newHashSet(resolver.resolve(context, Collections.singletonList("*Y*X"))).size(), equalTo(0)); } public void testAll() { @@ -123,13 +128,75 @@ public void testAll() { IndexNameExpressionResolver.WildcardExpressionResolver resolver = new IndexNameExpressionResolver.WildcardExpressionResolver(); IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, IndicesOptions.lenientExpandOpen()); - assertThat(newHashSet(resolver.resolve(context, Arrays.asList("_all"))), equalTo(newHashSet("testXXX", "testXYY", "testYYY"))); + assertThat(newHashSet(resolver.resolve(context, Collections.singletonList("_all"))), equalTo(newHashSet("testXXX", "testXYY", "testYYY"))); } - public void testConcreteIndicesWildcardAndAliases() { + public void testResolveAliases() { MetaData.Builder mdBuilder = MetaData.builder() - .put(indexBuilder("foo_foo").state(State.OPEN).putAlias(AliasMetaData.builder("foo"))) - .put(indexBuilder("bar_bar").state(State.OPEN).putAlias(AliasMetaData.builder("foo"))); + .put(indexBuilder("foo_foo").state(State.OPEN)) + .put(indexBuilder("bar_bar").state(State.OPEN)) + .put(indexBuilder("foo_index").state(State.OPEN).putAlias(AliasMetaData.builder("foo_alias"))) + .put(indexBuilder("bar_index").state(State.OPEN).putAlias(AliasMetaData.builder("foo_alias"))); + ClusterState state = ClusterState.builder(new ClusterName("_name")).metaData(mdBuilder).build(); + IndexNameExpressionResolver.WildcardExpressionResolver resolver = new IndexNameExpressionResolver.WildcardExpressionResolver(); + // when ignoreAliases option is not set, WildcardExpressionResolver resolves the provided + // expressions against the defined indices and aliases + IndicesOptions indicesAndAliasesOptions = IndicesOptions.fromOptions(randomBoolean(), randomBoolean(), true, false, true, false, false); + IndexNameExpressionResolver.Context indicesAndAliasesContext = new IndexNameExpressionResolver.Context(state, indicesAndAliasesOptions); + // ignoreAliases option is set, WildcardExpressionResolver throws error when + IndicesOptions skipAliasesIndicesOptions = IndicesOptions.fromOptions(true, true, true, false, true, false, true); + IndexNameExpressionResolver.Context skipAliasesLenientContext = new IndexNameExpressionResolver.Context(state, skipAliasesIndicesOptions); + // ignoreAliases option is set, WildcardExpressionResolver resolves the provided expressions only against the defined indices + IndicesOptions errorOnAliasIndicesOptions = IndicesOptions.fromOptions(false, false, true, false, true, false, true); + IndexNameExpressionResolver.Context skipAliasesStrictContext = new IndexNameExpressionResolver.Context(state, errorOnAliasIndicesOptions); + + { + List indices = resolver.resolve(indicesAndAliasesContext, Collections.singletonList("foo_a*")); + assertThat(indices, containsInAnyOrder("foo_index", "bar_index")); + } + { + List indices = resolver.resolve(skipAliasesLenientContext, Collections.singletonList("foo_a*")); + assertEquals(0, indices.size()); + } + { + IndexNotFoundException infe = expectThrows(IndexNotFoundException.class, + () -> resolver.resolve(skipAliasesStrictContext, Collections.singletonList("foo_a*"))); + assertEquals("foo_a*", infe.getIndex().getName()); + } + { + List indices = resolver.resolve(indicesAndAliasesContext, Collections.singletonList("foo*")); + assertThat(indices, containsInAnyOrder("foo_foo", "foo_index", "bar_index")); + } + { + List indices = resolver.resolve(skipAliasesLenientContext, Collections.singletonList("foo*")); + assertThat(indices, containsInAnyOrder("foo_foo", "foo_index")); + } + { + List indices = resolver.resolve(skipAliasesStrictContext, Collections.singletonList("foo*")); + assertThat(indices, containsInAnyOrder("foo_foo", "foo_index")); + } + { + List indices = resolver.resolve(indicesAndAliasesContext, Collections.singletonList("foo_alias")); + assertThat(indices, containsInAnyOrder("foo_alias")); + } + { + List indices = resolver.resolve(skipAliasesLenientContext, Collections.singletonList("foo_alias")); + assertThat(indices, containsInAnyOrder("foo_alias")); + } + { + IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, + () -> resolver.resolve(skipAliasesStrictContext, Collections.singletonList("foo_alias"))); + assertEquals("The provided expression [foo_alias] matches an alias, " + + "specify the corresponding concrete indices instead.", iae.getMessage()); + } + } + + public void testMatchesConcreteIndicesWildcardAndAliases() { + MetaData.Builder mdBuilder = MetaData.builder() + .put(indexBuilder("foo_foo").state(State.OPEN)) + .put(indexBuilder("bar_bar").state(State.OPEN)) + .put(indexBuilder("foo_index").state(State.OPEN).putAlias(AliasMetaData.builder("foo_alias"))) + .put(indexBuilder("bar_index").state(State.OPEN).putAlias(AliasMetaData.builder("foo_alias"))); ClusterState state = ClusterState.builder(new ClusterName("_name")).metaData(mdBuilder).build(); // when ignoreAliases option is not set, WildcardExpressionResolver resolves the provided @@ -142,44 +209,39 @@ public void testConcreteIndicesWildcardAndAliases() { IndicesOptions onlyIndicesOptions = IndicesOptions.fromOptions(false, false, true, false, true, false, true); IndexNameExpressionResolver.Context onlyIndicesContext = new IndexNameExpressionResolver.Context(state, onlyIndicesOptions); - assertThat( - IndexNameExpressionResolver.WildcardExpressionResolver - .matches(indicesAndAliasesContext, state.getMetaData(), "*").keySet(), - equalTo(newHashSet("bar_bar", "foo_foo", "foo"))); - assertThat( - IndexNameExpressionResolver.WildcardExpressionResolver - .matches(onlyIndicesContext, state.getMetaData(), "*").keySet(), - equalTo(newHashSet("bar_bar", "foo_foo"))); - - assertThat( - IndexNameExpressionResolver.WildcardExpressionResolver - .matches(indicesAndAliasesContext, state.getMetaData(), "foo*").keySet(), - equalTo(newHashSet("foo", "foo_foo"))); - assertThat( - IndexNameExpressionResolver.WildcardExpressionResolver - .matches(onlyIndicesContext, state.getMetaData(), "foo*").keySet(), - equalTo(newHashSet("foo_foo"))); - - assertThat( - IndexNameExpressionResolver.WildcardExpressionResolver - .matches(indicesAndAliasesContext, state.getMetaData(), "f*o").keySet(), - equalTo(newHashSet("foo", "foo_foo"))); - assertThat( - IndexNameExpressionResolver.WildcardExpressionResolver - .matches(onlyIndicesContext, state.getMetaData(), "f*o").keySet(), - equalTo(newHashSet("foo_foo"))); - - assertThat( - IndexNameExpressionResolver.WildcardExpressionResolver - .matches(indicesAndAliasesContext, state.getMetaData(), "foo").keySet(), - equalTo(newHashSet("foo"))); - assertThat( - IndexNameExpressionResolver.WildcardExpressionResolver - .matches(onlyIndicesContext, state.getMetaData(), "foo").keySet(), - equalTo(newHashSet())); + { + Set matches = IndexNameExpressionResolver.WildcardExpressionResolver.matches(indicesAndAliasesContext, + state.getMetaData(), "*").keySet(); + assertEquals(newHashSet("bar_bar", "foo_foo", "foo_index", "bar_index", "foo_alias"), matches); + } + { + Set matches = IndexNameExpressionResolver.WildcardExpressionResolver.matches(onlyIndicesContext, + state.getMetaData(), "*").keySet(); + assertEquals(newHashSet("bar_bar", "foo_foo", "foo_index", "bar_index"), matches); + } + { + Set matches = IndexNameExpressionResolver.WildcardExpressionResolver.matches(indicesAndAliasesContext, + state.getMetaData(), "foo*").keySet(); + assertEquals(newHashSet("foo_foo", "foo_index", "foo_alias"), matches); + } + { + Set matches = IndexNameExpressionResolver.WildcardExpressionResolver.matches(onlyIndicesContext, + state.getMetaData(), "foo*").keySet(); + assertEquals(newHashSet("foo_foo", "foo_index"), matches); + } + { + Set matches = IndexNameExpressionResolver.WildcardExpressionResolver.matches(indicesAndAliasesContext, + state.getMetaData(), "foo_alias").keySet(); + assertEquals(newHashSet("foo_alias"), matches); + } + { + Set matches = IndexNameExpressionResolver.WildcardExpressionResolver.matches(onlyIndicesContext, + state.getMetaData(), "foo_alias").keySet(); + assertEquals(newHashSet(), matches); + } } - private IndexMetaData.Builder indexBuilder(String index) { + private static IndexMetaData.Builder indexBuilder(String index) { return IndexMetaData.builder(index).settings(settings(Version.CURRENT).put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1).put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)); } } diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/indices.delete/10_basic.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/indices.delete/10_basic.yml index 29cd2e8b5d2b8..40486da9e7e76 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/test/indices.delete/10_basic.yml +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/indices.delete/10_basic.yml @@ -14,7 +14,7 @@ setup: version: " - 5.99.0" reason: delete index doesn't support aliases only from 6.0.0 on - do: - catch: missing + catch: request indices.delete: index: alias - do: @@ -42,7 +42,7 @@ setup: version: " - 5.99.0" reason: delete index doesn't support aliases only from 6.0.0 on - do: - catch: missing + catch: request indices.delete: index: alias,index2 - do: