-
Notifications
You must be signed in to change notification settings - Fork 25.7k
Wrong behavior deleting alias #23997
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
78d0c53
2bc39bb
bfddcd7
f733cb0
3cc0deb
b913036
5d60f4d
45f83a5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -50,6 +50,7 @@ | |
| import java.util.Locale; | ||
| import java.util.Map; | ||
| import java.util.Set; | ||
| import java.util.SortedMap; | ||
| import java.util.function.Predicate; | ||
| import java.util.stream.Collectors; | ||
|
|
||
|
|
@@ -104,7 +105,7 @@ public String[] concreteIndexNames(ClusterState state, IndicesOptions options, S | |
| return concreteIndexNames(context, indexExpressions); | ||
| } | ||
|
|
||
| /** | ||
| /** | ||
| * Translates the provided index expression into actual concrete indices, properly deduplicated. | ||
| * | ||
| * @param state the cluster state containing all the data to resolve to expressions to concrete indices | ||
|
|
@@ -181,7 +182,7 @@ Index[] concreteIndices(Context context, String... indexExpressions) { | |
| final Set<Index> concreteIndices = new HashSet<>(expressions.size()); | ||
| for (String expression : expressions) { | ||
| AliasOrIndex aliasOrIndex = metaData.getAliasAndIndexLookup().get(expression); | ||
| if (aliasOrIndex == null) { | ||
| if (aliasOrIndex == null || (aliasOrIndex.isAlias() && context.getOptions().ignoreAliases())) { | ||
| if (failNoIndices) { | ||
| IndexNotFoundException infe = new IndexNotFoundException(expression); | ||
| infe.setResources("index_expression", expression); | ||
|
|
@@ -638,7 +639,7 @@ private Set<String> innerResolve(Context context, List<String> expressions, Indi | |
| } | ||
|
|
||
| final IndexMetaData.State excludeState = excludeState(options); | ||
| final Map<String, AliasOrIndex> matches = matches(metaData, expression); | ||
| final Map<String, AliasOrIndex> matches = matches(context, metaData, expression); | ||
|
||
| Set<String> expand = expand(context, excludeState, matches); | ||
| if (add) { | ||
| result.addAll(expand); | ||
|
|
@@ -693,31 +694,44 @@ private static IndexMetaData.State excludeState(IndicesOptions options) { | |
| return excludeState; | ||
| } | ||
|
|
||
| private static Map<String, AliasOrIndex> matches(MetaData metaData, String expression) { | ||
| public static Map<String, AliasOrIndex> matches(Context context, MetaData metaData, String expression) { | ||
|
||
| if (Regex.isMatchAllPattern(expression)) { | ||
| // Can only happen if the expressions was initially: '-*' | ||
| return metaData.getAliasAndIndexLookup(); | ||
| if (context.getOptions().ignoreAliases()) { | ||
| return metaData.getAliasAndIndexLookup().entrySet().stream() | ||
| .filter(e -> e.getValue().isAlias() == false) | ||
| .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); | ||
| } else { | ||
| return metaData.getAliasAndIndexLookup(); | ||
| } | ||
| } else if (expression.indexOf("*") == expression.length() - 1) { | ||
| return suffixWildcard(metaData, expression); | ||
| return suffixWildcard(context, metaData, expression); | ||
| } else { | ||
| return otherWildcard(metaData, expression); | ||
| return otherWildcard(context, metaData, expression); | ||
| } | ||
| } | ||
|
|
||
| private static Map<String, AliasOrIndex> suffixWildcard(MetaData metaData, String expression) { | ||
| private static Map<String, AliasOrIndex> suffixWildcard(Context context, MetaData metaData, String expression) { | ||
| assert expression.length() >= 2 : "expression [" + expression + "] should have at least a length of 2"; | ||
| String fromPrefix = expression.substring(0, expression.length() - 1); | ||
| char[] toPrefixCharArr = fromPrefix.toCharArray(); | ||
| toPrefixCharArr[toPrefixCharArr.length - 1]++; | ||
| String toPrefix = new String(toPrefixCharArr); | ||
| return metaData.getAliasAndIndexLookup().subMap(fromPrefix, toPrefix); | ||
| SortedMap<String,AliasOrIndex> subMap = metaData.getAliasAndIndexLookup().subMap(fromPrefix, toPrefix); | ||
| if (context.getOptions().ignoreAliases()) { | ||
| return subMap.entrySet().stream() | ||
| .filter(entry -> entry.getValue().isAlias() == false) | ||
| .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); | ||
| } | ||
| return subMap; | ||
| } | ||
|
|
||
| private static Map<String, AliasOrIndex> otherWildcard(MetaData metaData, String expression) { | ||
| private static Map<String, AliasOrIndex> otherWildcard(Context context, MetaData metaData, String expression) { | ||
| final String pattern = expression; | ||
| return metaData.getAliasAndIndexLookup() | ||
| .entrySet() | ||
| .stream() | ||
| .filter(e -> context.getOptions().ignoreAliases() == false || e.getValue().isAlias() == false) | ||
| .filter(e -> Regex.simpleMatch(pattern, e.getKey())) | ||
| .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,7 +19,6 @@ | |
|
|
||
| package org.elasticsearch.aliases; | ||
|
|
||
| import org.apache.lucene.search.join.ScoreMode; | ||
| import org.elasticsearch.action.admin.indices.alias.Alias; | ||
| import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions; | ||
| import org.elasticsearch.action.admin.indices.alias.exists.AliasesExistResponse; | ||
|
|
@@ -36,6 +35,7 @@ | |
| 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; | ||
|
|
@@ -63,7 +63,6 @@ | |
| import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_BLOCKS_READ; | ||
| import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_BLOCKS_WRITE; | ||
| import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_READ_ONLY; | ||
| import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; | ||
| import static org.elasticsearch.index.query.QueryBuilders.rangeQuery; | ||
| import static org.elasticsearch.index.query.QueryBuilders.termQuery; | ||
| import static org.elasticsearch.test.hamcrest.CollectionAssertions.hasKey; | ||
|
|
@@ -425,6 +424,23 @@ public void testDeleteAliases() throws Exception { | |
|
|
||
| AliasesExistResponse response = admin().indices().prepareAliasesExist(aliases).get(); | ||
| assertThat(response.exists(), equalTo(false)); | ||
|
|
||
| logger.info("--> creating index [foo_foo] and [bar_bar]"); | ||
| assertAcked(prepareCreate("foo_foo")); | ||
| assertAcked(prepareCreate("bar_bar")); | ||
| ensureGreen(); | ||
|
|
||
| logger.info("--> adding [foo] alias to [foo_foo] and [bar_bar]"); | ||
| assertAcked(admin().indices().prepareAliases().addAlias("foo_foo", "foo")); | ||
| assertAcked(admin().indices().prepareAliases().addAlias("bar_bar", "foo")); | ||
|
|
||
| assertAcked(admin().indices().prepareAliases().addAliasAction(AliasActions.remove().index("foo*").alias("foo")).execute().get()); | ||
|
||
|
|
||
| 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() | ||
| .addAliasAction(AliasActions.remove().index("foo").alias("foo")).execute().actionGet()); | ||
| } | ||
|
|
||
| public void testWaitForAliasCreationMultipleShards() throws Exception { | ||
|
|
@@ -785,6 +801,21 @@ public void testCreateIndexWithAliasesFilterNotValid() { | |
| } | ||
| } | ||
|
|
||
| public void testAliasesCanBeAddedToIndicesOnly() throws Exception { | ||
| logger.info("--> creating index [2017-05-20]"); | ||
| assertAcked(prepareCreate("2017-05-20")); | ||
| ensureGreen(); | ||
|
|
||
| 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() | ||
| .addAliasAction(AliasActions.add().index("week_20").alias("tmp")).execute().actionGet()); | ||
| assertEquals("week_20", infe.getIndex().getName()); | ||
|
|
||
| assertAcked(admin().indices().prepareAliases().addAliasAction(AliasActions.add().index("2017-05-20").alias("tmp")).execute().get()); | ||
| } | ||
|
|
||
| // Before 2.0 alias filters were parsed at alias creation time, in order | ||
| // for filters to work correctly ES required that fields mentioned in those | ||
| // filters exist in the mapping. | ||
|
|
@@ -864,6 +895,26 @@ public void testAliasesWithBlocks() { | |
| } | ||
| } | ||
|
|
||
| public void testAliasActionRemoveIndex() throws InterruptedException, ExecutionException { | ||
| assertAcked(prepareCreate("foo_foo")); | ||
| assertAcked(prepareCreate("bar_bar")); | ||
| assertAcked(admin().indices().prepareAliases().addAlias("foo_foo", "foo")); | ||
| assertAcked(admin().indices().prepareAliases().addAlias("bar_bar", "foo")); | ||
|
|
||
| expectThrows(IndexNotFoundException.class, | ||
| () -> client().admin().indices().prepareAliases().removeIndex("foo").execute().actionGet()); | ||
|
|
||
| assertAcked(client().admin().indices().prepareAliases().removeIndex("foo*").execute().get()); | ||
| assertFalse(client().admin().indices().prepareExists("foo_foo").execute().actionGet().isExists()); | ||
| assertTrue(admin().indices().prepareAliasesExist("foo").get().exists()); | ||
| assertTrue(client().admin().indices().prepareExists("bar_bar").execute().actionGet().isExists()); | ||
| assertTrue(admin().indices().prepareAliasesExist("foo").setIndices("bar_bar").get().exists()); | ||
|
|
||
| assertAcked(client().admin().indices().prepareAliases().removeIndex("bar_bar")); | ||
| assertFalse(admin().indices().prepareAliasesExist("foo").get().exists()); | ||
| assertFalse(client().admin().indices().prepareExists("bar_bar").execute().actionGet().isExists()); | ||
| } | ||
|
|
||
| public void testRemoveIndexAndReplaceWithAlias() throws InterruptedException, ExecutionException { | ||
| assertAcked(client().admin().indices().prepareCreate("test")); | ||
| indexRandom(true, client().prepareIndex("test_2", "test", "test").setSource("test", "test")); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you expand IndicesOptionsTests#testFromOptions using and testing this new flag too?