Expand index expressions against indices only when managing aliases (#23997)
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 which will expand to matching indices). Closes #23960
This commit is contained in:
parent
4a8759ef4c
commit
0d5f3958e7
|
@ -59,9 +59,10 @@ import static org.elasticsearch.common.xcontent.ObjectParser.fromList;
|
|||
public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesRequest> {
|
||||
private List<AliasActions> allAliasActions = new ArrayList<>();
|
||||
|
||||
//indices options that require every specified index to exist, expand wildcards only to open indices and
|
||||
//don't allow that no indices are resolved from wildcard expressions
|
||||
private static final IndicesOptions INDICES_OPTIONS = IndicesOptions.fromOptions(false, false, true, false);
|
||||
// indices options that require every specified index to exist, expand wildcards only to open
|
||||
// indices, don't allow that no indices are resolved from wildcard expressions and resolve the
|
||||
// expressions only against indices
|
||||
private static final IndicesOptions INDICES_OPTIONS = IndicesOptions.fromOptions(false, false, true, false, true, false, true);
|
||||
|
||||
public IndicesAliasesRequest() {
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.elasticsearch.action.support;
|
||||
|
||||
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.rest.RestRequest;
|
||||
|
@ -43,6 +44,7 @@ public class IndicesOptions {
|
|||
private static final byte EXPAND_WILDCARDS_CLOSED = 8;
|
||||
private static final byte FORBID_ALIASES_TO_MULTIPLE_INDICES = 16;
|
||||
private static final byte FORBID_CLOSED_INDICES = 32;
|
||||
private static final byte IGNORE_ALIASES = 64;
|
||||
|
||||
private static final byte STRICT_EXPAND_OPEN = 6;
|
||||
private static final byte LENIENT_EXPAND_OPEN = 7;
|
||||
|
@ -51,10 +53,10 @@ public class IndicesOptions {
|
|||
private static final byte STRICT_SINGLE_INDEX_NO_EXPAND_FORBID_CLOSED = 48;
|
||||
|
||||
static {
|
||||
byte max = 1 << 6;
|
||||
short max = 1 << 7;
|
||||
VALUES = new IndicesOptions[max];
|
||||
for (byte id = 0; id < max; id++) {
|
||||
VALUES[id] = new IndicesOptions(id);
|
||||
for (short id = 0; id < max; id++) {
|
||||
VALUES[id] = new IndicesOptions((byte)id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,13 +113,26 @@ public class IndicesOptions {
|
|||
return (id & FORBID_ALIASES_TO_MULTIPLE_INDICES) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether aliases should be ignored (when resolving a wildcard)
|
||||
*/
|
||||
public boolean ignoreAliases() {
|
||||
return (id & IGNORE_ALIASES) != 0;
|
||||
}
|
||||
|
||||
public void writeIndicesOptions(StreamOutput out) throws IOException {
|
||||
if (out.getVersion().onOrAfter(Version.V_6_0_0_alpha2)) {
|
||||
out.write(id);
|
||||
} else {
|
||||
// if we are talking to a node that doesn't support the newly added flag (ignoreAliases)
|
||||
// flip to 0 all the bits starting from the 7th
|
||||
out.write(id & 0x3f);
|
||||
}
|
||||
}
|
||||
|
||||
public static IndicesOptions readIndicesOptions(StreamInput in) throws IOException {
|
||||
//if we read from a node that doesn't support the newly added flag (allowAliasesToMultipleIndices)
|
||||
//we just receive the old corresponding value with the new flag set to true (default)
|
||||
//if we read from a node that doesn't support the newly added flag (ignoreAliases)
|
||||
//we just receive the old corresponding value with the new flag set to false (default)
|
||||
byte id = in.readByte();
|
||||
if (id >= VALUES.length) {
|
||||
throw new IllegalArgumentException("No valid missing index type id: " + id);
|
||||
|
@ -133,8 +148,16 @@ public class IndicesOptions {
|
|||
return fromOptions(ignoreUnavailable, allowNoIndices, expandToOpenIndices, expandToClosedIndices, defaultOptions.allowAliasesToMultipleIndices(), defaultOptions.forbidClosedIndices());
|
||||
}
|
||||
|
||||
static IndicesOptions fromOptions(boolean ignoreUnavailable, boolean allowNoIndices, boolean expandToOpenIndices, boolean expandToClosedIndices, boolean allowAliasesToMultipleIndices, boolean forbidClosedIndices) {
|
||||
byte id = toByte(ignoreUnavailable, allowNoIndices, expandToOpenIndices, expandToClosedIndices, allowAliasesToMultipleIndices, forbidClosedIndices);
|
||||
public static IndicesOptions fromOptions(boolean ignoreUnavailable, boolean allowNoIndices, boolean expandToOpenIndices,
|
||||
boolean expandToClosedIndices, boolean allowAliasesToMultipleIndices, boolean forbidClosedIndices) {
|
||||
return fromOptions(ignoreUnavailable, allowNoIndices, expandToOpenIndices, expandToClosedIndices, allowAliasesToMultipleIndices,
|
||||
forbidClosedIndices, false);
|
||||
}
|
||||
|
||||
public static IndicesOptions fromOptions(boolean ignoreUnavailable, boolean allowNoIndices, boolean expandToOpenIndices,
|
||||
boolean expandToClosedIndices, boolean allowAliasesToMultipleIndices, boolean forbidClosedIndices, boolean ignoreAliases) {
|
||||
byte id = toByte(ignoreUnavailable, allowNoIndices, expandToOpenIndices, expandToClosedIndices, allowAliasesToMultipleIndices,
|
||||
forbidClosedIndices, ignoreAliases);
|
||||
return VALUES[id];
|
||||
}
|
||||
|
||||
|
@ -246,7 +269,7 @@ public class IndicesOptions {
|
|||
}
|
||||
|
||||
private static byte toByte(boolean ignoreUnavailable, boolean allowNoIndices, boolean wildcardExpandToOpen,
|
||||
boolean wildcardExpandToClosed, boolean allowAliasesToMultipleIndices, boolean forbidClosedIndices) {
|
||||
boolean wildcardExpandToClosed, boolean allowAliasesToMultipleIndices, boolean forbidClosedIndices, boolean ignoreAliases) {
|
||||
byte id = 0;
|
||||
if (ignoreUnavailable) {
|
||||
id |= IGNORE_UNAVAILABLE;
|
||||
|
@ -268,6 +291,9 @@ public class IndicesOptions {
|
|||
if (forbidClosedIndices) {
|
||||
id |= FORBID_CLOSED_INDICES;
|
||||
}
|
||||
if (ignoreAliases) {
|
||||
id |= IGNORE_ALIASES;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
|
@ -281,6 +307,7 @@ public class IndicesOptions {
|
|||
", expand_wildcards_closed=" + expandWildcardsClosed() +
|
||||
", allow_aliases_to_multiple_indices=" + allowAliasesToMultipleIndices() +
|
||||
", forbid_closed_indices=" + forbidClosedIndices() +
|
||||
", ignore_aliases=" + ignoreAliases() +
|
||||
']';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ import java.util.List;
|
|||
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;
|
||||
|
||||
|
@ -181,7 +182,7 @@ public class IndexNameExpressionResolver extends AbstractComponent {
|
|||
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 @@ public class IndexNameExpressionResolver extends AbstractComponent {
|
|||
}
|
||||
|
||||
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 @@ public class IndexNameExpressionResolver extends AbstractComponent {
|
|||
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();
|
||||
} else if (expression.indexOf("*") == expression.length() - 1) {
|
||||
return suffixWildcard(metaData, expression);
|
||||
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 otherWildcard(metaData, expression);
|
||||
return metaData.getAliasAndIndexLookup();
|
||||
}
|
||||
} else if (expression.indexOf("*") == expression.length() - 1) {
|
||||
return suffixWildcard(context, metaData, expression);
|
||||
} else {
|
||||
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));
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ public class IndicesOptionsTests extends ESTestCase {
|
|||
int iterations = randomIntBetween(5, 20);
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
IndicesOptions indicesOptions = IndicesOptions.fromOptions(
|
||||
randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean());
|
||||
randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean());
|
||||
|
||||
BytesStreamOutput output = new BytesStreamOutput();
|
||||
Version outputVersion = randomVersion(random());
|
||||
|
@ -50,6 +50,12 @@ public class IndicesOptionsTests extends ESTestCase {
|
|||
|
||||
assertThat(indicesOptions2.forbidClosedIndices(), equalTo(indicesOptions.forbidClosedIndices()));
|
||||
assertThat(indicesOptions2.allowAliasesToMultipleIndices(), equalTo(indicesOptions.allowAliasesToMultipleIndices()));
|
||||
|
||||
if (output.getVersion().onOrAfter(Version.V_6_0_0_alpha2)) {
|
||||
assertEquals(indicesOptions2.ignoreAliases(), indicesOptions.ignoreAliases());
|
||||
} else {
|
||||
assertFalse(indicesOptions2.ignoreAliases());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,9 +68,11 @@ public class IndicesOptionsTests extends ESTestCase {
|
|||
boolean expandToClosedIndices = randomBoolean();
|
||||
boolean allowAliasesToMultipleIndices = randomBoolean();
|
||||
boolean forbidClosedIndices = randomBoolean();
|
||||
boolean ignoreAliases = randomBoolean();
|
||||
|
||||
IndicesOptions indicesOptions = IndicesOptions.fromOptions(
|
||||
ignoreUnavailable, allowNoIndices,expandToOpenIndices, expandToClosedIndices,
|
||||
allowAliasesToMultipleIndices, forbidClosedIndices
|
||||
allowAliasesToMultipleIndices, forbidClosedIndices, ignoreAliases
|
||||
);
|
||||
|
||||
assertThat(indicesOptions.ignoreUnavailable(), equalTo(ignoreUnavailable));
|
||||
|
@ -74,6 +82,7 @@ public class IndicesOptionsTests extends ESTestCase {
|
|||
assertThat(indicesOptions.allowAliasesToMultipleIndices(), equalTo(allowAliasesToMultipleIndices));
|
||||
assertThat(indicesOptions.allowAliasesToMultipleIndices(), equalTo(allowAliasesToMultipleIndices));
|
||||
assertThat(indicesOptions.forbidClosedIndices(), equalTo(forbidClosedIndices));
|
||||
assertEquals(ignoreAliases, indicesOptions.ignoreAliases());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.StopWatch;
|
|||
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_ME
|
|||
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 class IndexAliasesIT extends ESIntegTestCase {
|
|||
|
||||
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 class IndexAliasesIT extends ESIntegTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
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 class IndexAliasesIT extends ESIntegTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
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"));
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.elasticsearch.test.ESTestCase;
|
|||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import static org.elasticsearch.common.util.set.Sets.newHashSet;
|
||||
import static org.hamcrest.Matchers.arrayContaining;
|
||||
|
@ -643,6 +644,60 @@ public class IndexNameExpressionResolverTests extends ESTestCase {
|
|||
assertEquals(0, indexNames.length);
|
||||
}
|
||||
|
||||
public void testConcreteIndicesWildcardAndAliases() {
|
||||
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")));
|
||||
ClusterState state = ClusterState.builder(new ClusterName("_name")).metaData(mdBuilder).build();
|
||||
|
||||
// when ignoreAliases option is set, concreteIndexNames resolves the provided expressions
|
||||
// only against the defined indices
|
||||
IndicesOptions ignoreAliasesOptions = IndicesOptions.fromOptions(false, false, true, false, true, false, true);
|
||||
|
||||
String[] indexNamesIndexWildcard = indexNameExpressionResolver.concreteIndexNames(state, ignoreAliasesOptions, "foo*");
|
||||
|
||||
assertEquals(1, indexNamesIndexWildcard.length);
|
||||
assertEquals("foo_foo", indexNamesIndexWildcard[0]);
|
||||
|
||||
indexNamesIndexWildcard = indexNameExpressionResolver.concreteIndexNames(state, ignoreAliasesOptions, "*o");
|
||||
|
||||
assertEquals(1, indexNamesIndexWildcard.length);
|
||||
assertEquals("foo_foo", indexNamesIndexWildcard[0]);
|
||||
|
||||
indexNamesIndexWildcard = indexNameExpressionResolver.concreteIndexNames(state, ignoreAliasesOptions, "f*o");
|
||||
|
||||
assertEquals(1, indexNamesIndexWildcard.length);
|
||||
assertEquals("foo_foo", indexNamesIndexWildcard[0]);
|
||||
|
||||
IndexNotFoundException infe = expectThrows(IndexNotFoundException.class,
|
||||
() -> indexNameExpressionResolver.concreteIndexNames(state, ignoreAliasesOptions, "foo"));
|
||||
assertThat(infe.getIndex().getName(), equalTo("foo"));
|
||||
|
||||
// when ignoreAliases option is not set, concreteIndexNames resolves the provided
|
||||
// expressions against the defined indices and aliases
|
||||
IndicesOptions indicesAndAliasesOptions = IndicesOptions.fromOptions(false, false, true, false, true, false, false);
|
||||
|
||||
List<String> indexNames = Arrays.asList(indexNameExpressionResolver.concreteIndexNames(state, indicesAndAliasesOptions, "foo*"));
|
||||
assertEquals(2, indexNames.size());
|
||||
assertTrue(indexNames.contains("foo_foo"));
|
||||
assertTrue(indexNames.contains("bar_bar"));
|
||||
|
||||
indexNames = Arrays.asList(indexNameExpressionResolver.concreteIndexNames(state, indicesAndAliasesOptions, "*o"));
|
||||
assertEquals(2, indexNames.size());
|
||||
assertTrue(indexNames.contains("foo_foo"));
|
||||
assertTrue(indexNames.contains("bar_bar"));
|
||||
|
||||
indexNames = Arrays.asList(indexNameExpressionResolver.concreteIndexNames(state, indicesAndAliasesOptions, "f*o"));
|
||||
assertEquals(2, indexNames.size());
|
||||
assertTrue(indexNames.contains("foo_foo"));
|
||||
assertTrue(indexNames.contains("bar_bar"));
|
||||
|
||||
indexNames = Arrays.asList(indexNameExpressionResolver.concreteIndexNames(state, indicesAndAliasesOptions, "foo"));
|
||||
assertEquals(2, indexNames.size());
|
||||
assertTrue(indexNames.contains("foo_foo"));
|
||||
assertTrue(indexNames.contains("bar_bar"));
|
||||
}
|
||||
|
||||
/**
|
||||
* test resolving _all pattern (null, empty array or "_all") for random IndicesOptions
|
||||
*/
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.elasticsearch.Version;
|
|||
import org.elasticsearch.action.support.IndicesOptions;
|
||||
import org.elasticsearch.cluster.ClusterName;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData.State;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
@ -125,6 +126,59 @@ public class WildcardExpressionResolverTests extends ESTestCase {
|
|||
assertThat(newHashSet(resolver.resolve(context, Arrays.asList("_all"))), equalTo(newHashSet("testXXX", "testXYY", "testYYY")));
|
||||
}
|
||||
|
||||
public void testConcreteIndicesWildcardAndAliases() {
|
||||
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")));
|
||||
ClusterState state = ClusterState.builder(new ClusterName("_name")).metaData(mdBuilder).build();
|
||||
|
||||
// when ignoreAliases option is not set, WildcardExpressionResolver resolves the provided
|
||||
// expressions against the defined indices and aliases
|
||||
IndicesOptions indicesAndAliasesOptions = IndicesOptions.fromOptions(false, false, true, false, true, false, false);
|
||||
IndexNameExpressionResolver.Context indicesAndAliasesContext = new IndexNameExpressionResolver.Context(state, indicesAndAliasesOptions);
|
||||
|
||||
// ignoreAliases option is set, WildcardExpressionResolver resolves the provided expressions
|
||||
// only against the defined indices
|
||||
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()));
|
||||
}
|
||||
|
||||
private 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));
|
||||
}
|
||||
|
|
|
@ -50,3 +50,9 @@ default when a provided wildcard expression doesn't match any closed/open index.
|
|||
Delete a document from non-existing index has been modified to not create the index.
|
||||
However if an external versioning is used the index will be created and the document
|
||||
will be marked for deletion.
|
||||
|
||||
==== Indices aliases api resolves indices expressions only against indices
|
||||
|
||||
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
|
||||
which will expand to matching indices).
|
||||
|
|
Loading…
Reference in New Issue