Delete index API to work only against concrete indices (#25268)
With #23997 we have introduced a new internal index option that allows to resolve index expressions only against concrete indices while ignoring aliases. Such index option was applied to IndicesAliasesRequest, so that the index part of alias actions would only be resolved against concrete indices. Same is done in this commit with delete index request. Deleting aliases has always been confusing as some users expect it to only remove the alias from the index (which has its own specific API). Even worse, in case of filtered aliases, deleting an alias may leave users with the expectation that only the documents that match the filter are deleted, which was never the case. To address all this confusion, delete index api works now only against concrete indices. WIldcard expressions will be only resolved against concrete index, as if aliases didn't exist. If one tries to delete against an alias, an IndexNotFoundException will be thrown regardless of whether the alias exists or not, as a concrete index with such a name doesn't exist. Closes #2318
This commit is contained in:
parent
9c65073852
commit
b5cea6980b
|
@ -38,7 +38,7 @@ public class DeleteIndexRequest extends AcknowledgedRequest<DeleteIndexRequest>
|
||||||
|
|
||||||
private String[] indices;
|
private String[] indices;
|
||||||
// Delete index should work by default on both open and closed indices.
|
// Delete index should work by default on both open and closed indices.
|
||||||
private IndicesOptions indicesOptions = IndicesOptions.fromOptions(false, true, true, true);
|
private IndicesOptions indicesOptions = IndicesOptions.fromOptions(false, true, true, true, false, false, true);
|
||||||
|
|
||||||
public DeleteIndexRequest() {
|
public DeleteIndexRequest() {
|
||||||
}
|
}
|
||||||
|
|
|
@ -644,12 +644,8 @@ public class IndicesRequestIT extends ESIntegTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String[] randomUniqueIndicesOrAliases() {
|
private String[] randomUniqueIndicesOrAliases() {
|
||||||
Set<String> uniqueIndices = new HashSet<>();
|
String[] uniqueIndices = randomUniqueIndices();
|
||||||
int count = randomIntBetween(1, this.indices.size());
|
String[] indices = new String[uniqueIndices.length];
|
||||||
while (uniqueIndices.size() < count) {
|
|
||||||
uniqueIndices.add(randomFrom(this.indices));
|
|
||||||
}
|
|
||||||
String[] indices = new String[count];
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (String index : uniqueIndices) {
|
for (String index : uniqueIndices) {
|
||||||
indices[i++] = randomBoolean() ? index + "-alias" : index;
|
indices[i++] = randomBoolean() ? index + "-alias" : index;
|
||||||
|
@ -657,6 +653,15 @@ public class IndicesRequestIT extends ESIntegTestCase {
|
||||||
return indices;
|
return indices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String[] randomUniqueIndices() {
|
||||||
|
Set<String> uniqueIndices = new HashSet<>();
|
||||||
|
int count = randomIntBetween(1, this.indices.size());
|
||||||
|
while (uniqueIndices.size() < count) {
|
||||||
|
uniqueIndices.add(randomFrom(this.indices));
|
||||||
|
}
|
||||||
|
return uniqueIndices.toArray(new String[uniqueIndices.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
private static void assertAllRequestsHaveBeenConsumed() {
|
private static void assertAllRequestsHaveBeenConsumed() {
|
||||||
Iterable<PluginsService> pluginsServices = internalCluster().getInstances(PluginsService.class);
|
Iterable<PluginsService> pluginsServices = internalCluster().getInstances(PluginsService.class);
|
||||||
for (PluginsService pluginsService : pluginsServices) {
|
for (PluginsService pluginsService : pluginsServices) {
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
package org.elasticsearch.cluster.metadata;
|
package org.elasticsearch.cluster.metadata;
|
||||||
|
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
|
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
|
||||||
|
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
|
||||||
import org.elasticsearch.action.support.IndicesOptions;
|
import org.elasticsearch.action.support.IndicesOptions;
|
||||||
import org.elasticsearch.cluster.ClusterName;
|
import org.elasticsearch.cluster.ClusterName;
|
||||||
import org.elasticsearch.cluster.ClusterState;
|
import org.elasticsearch.cluster.ClusterState;
|
||||||
|
@ -1042,4 +1044,100 @@ public class IndexNameExpressionResolverTests extends ESTestCase {
|
||||||
equalTo(newHashSet("testXXX", "testXXY", "testYYY")));
|
equalTo(newHashSet("testXXX", "testXXY", "testYYY")));
|
||||||
assertWarnings("support for '+' as part of index expressions is deprecated");
|
assertWarnings("support for '+' as part of index expressions is deprecated");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testDeleteIndexIgnoresAliases() {
|
||||||
|
MetaData.Builder mdBuilder = MetaData.builder()
|
||||||
|
.put(indexBuilder("test-index").state(State.OPEN)
|
||||||
|
.putAlias(AliasMetaData.builder("test-alias")))
|
||||||
|
.put(indexBuilder("index").state(State.OPEN)
|
||||||
|
.putAlias(AliasMetaData.builder("test-alias2")));
|
||||||
|
ClusterState state = ClusterState.builder(new ClusterName("_name")).metaData(mdBuilder).build();
|
||||||
|
{
|
||||||
|
String[] indices = indexNameExpressionResolver.concreteIndexNames(state, new DeleteIndexRequest("test-alias"));
|
||||||
|
assertEquals(0, indices.length);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
String[] indices = indexNameExpressionResolver.concreteIndexNames(state, new DeleteIndexRequest("test-a*"));
|
||||||
|
assertEquals(0, indices.length);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
String[] indices = indexNameExpressionResolver.concreteIndexNames(state, new DeleteIndexRequest("test-index"));
|
||||||
|
assertEquals(1, indices.length);
|
||||||
|
assertEquals("test-index", indices[0]);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
String[] indices = indexNameExpressionResolver.concreteIndexNames(state, new DeleteIndexRequest("test-*"));
|
||||||
|
assertEquals(1, indices.length);
|
||||||
|
assertEquals("test-index", indices[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testIndicesAliasesRequestIgnoresAliases() {
|
||||||
|
MetaData.Builder mdBuilder = MetaData.builder()
|
||||||
|
.put(indexBuilder("test-index").state(State.OPEN)
|
||||||
|
.putAlias(AliasMetaData.builder("test-alias")))
|
||||||
|
.put(indexBuilder("index").state(State.OPEN)
|
||||||
|
.putAlias(AliasMetaData.builder("test-alias2")));
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
IndicesAliasesRequest.AliasActions aliasActions = IndicesAliasesRequest.AliasActions.add().index("test-a*");
|
||||||
|
expectThrows(IndexNotFoundException.class, () -> indexNameExpressionResolver.concreteIndexNames(state, aliasActions));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
IndicesAliasesRequest.AliasActions aliasActions = IndicesAliasesRequest.AliasActions.add().index("test-index");
|
||||||
|
String[] indices = indexNameExpressionResolver.concreteIndexNames(state, aliasActions);
|
||||||
|
assertEquals(1, indices.length);
|
||||||
|
assertEquals("test-index", indices[0]);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
IndicesAliasesRequest.AliasActions aliasActions = IndicesAliasesRequest.AliasActions.add().index("test-*");
|
||||||
|
String[] indices = indexNameExpressionResolver.concreteIndexNames(state, aliasActions);
|
||||||
|
assertEquals(1, indices.length);
|
||||||
|
assertEquals("test-index", indices[0]);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
IndicesAliasesRequest.AliasActions aliasActions = IndicesAliasesRequest.AliasActions.remove().index("test-alias");
|
||||||
|
expectThrows(IndexNotFoundException.class, () -> indexNameExpressionResolver.concreteIndexNames(state, aliasActions));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
IndicesAliasesRequest.AliasActions aliasActions = IndicesAliasesRequest.AliasActions.remove().index("test-a*");
|
||||||
|
expectThrows(IndexNotFoundException.class, () -> indexNameExpressionResolver.concreteIndexNames(state, aliasActions));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
IndicesAliasesRequest.AliasActions aliasActions = IndicesAliasesRequest.AliasActions.remove().index("test-index");
|
||||||
|
String[] indices = indexNameExpressionResolver.concreteIndexNames(state, aliasActions);
|
||||||
|
assertEquals(1, indices.length);
|
||||||
|
assertEquals("test-index", indices[0]);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
IndicesAliasesRequest.AliasActions aliasActions = IndicesAliasesRequest.AliasActions.remove().index("test-*");
|
||||||
|
String[] indices = indexNameExpressionResolver.concreteIndexNames(state, aliasActions);
|
||||||
|
assertEquals(1, indices.length);
|
||||||
|
assertEquals("test-index", indices[0]);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
IndicesAliasesRequest.AliasActions aliasActions = IndicesAliasesRequest.AliasActions.removeIndex().index("test-alias");
|
||||||
|
expectThrows(IndexNotFoundException.class, () -> indexNameExpressionResolver.concreteIndexNames(state, aliasActions));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
IndicesAliasesRequest.AliasActions aliasActions = IndicesAliasesRequest.AliasActions.removeIndex().index("test-a*");
|
||||||
|
expectThrows(IndexNotFoundException.class, () -> indexNameExpressionResolver.concreteIndexNames(state, aliasActions));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
IndicesAliasesRequest.AliasActions aliasActions = IndicesAliasesRequest.AliasActions.removeIndex().index("test-index");
|
||||||
|
String[] indices = indexNameExpressionResolver.concreteIndexNames(state, aliasActions);
|
||||||
|
assertEquals(1, indices.length);
|
||||||
|
assertEquals("test-index", indices[0]);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
IndicesAliasesRequest.AliasActions aliasActions = IndicesAliasesRequest.AliasActions.removeIndex().index("test-*");
|
||||||
|
String[] indices = indexNameExpressionResolver.concreteIndexNames(state, aliasActions);
|
||||||
|
assertEquals(1, indices.length);
|
||||||
|
assertEquals("test-index", indices[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,3 +56,9 @@ will be marked for deletion.
|
||||||
The index parameter in the update-aliases, put-alias, and delete-alias APIs no
|
The index parameter in the update-aliases, put-alias, and delete-alias APIs no
|
||||||
longer accepts alias names. Instead, it accepts only index names (or wildcards
|
longer accepts alias names. Instead, it accepts only index names (or wildcards
|
||||||
which will expand to matching indices).
|
which will expand to matching indices).
|
||||||
|
|
||||||
|
==== Delete index api resolves indices expressions only against indices
|
||||||
|
|
||||||
|
The index parameter in the delete index API no longer accepts alias names.
|
||||||
|
Instead, it accepts only index names (or wildcards which will expand to
|
||||||
|
matching indices).
|
||||||
|
|
Loading…
Reference in New Issue