/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.cluster.metadata;
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.common.Strings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.indices.IndexClosedException;
import org.elasticsearch.test.ESTestCase;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.function.Predicate;
import static org.elasticsearch.common.util.set.Sets.newHashSet;
import static org.hamcrest.Matchers.arrayContaining;
import static org.hamcrest.Matchers.arrayContainingInAnyOrder;
import static org.hamcrest.Matchers.arrayWithSize;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.emptyArray;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
public class IndexNameExpressionResolverTests extends ESTestCase {
private final IndexNameExpressionResolver indexNameExpressionResolver = new IndexNameExpressionResolver(Settings.EMPTY);
public void testIndexOptionsStrict() {
MetaData.Builder mdBuilder = MetaData.builder()
.put(indexBuilder("foo").putAlias(AliasMetaData.builder("foofoobar")))
.put(indexBuilder("foobar").putAlias(AliasMetaData.builder("foofoobar")))
.put(indexBuilder("foofoo-closed").state(IndexMetaData.State.CLOSE))
.put(indexBuilder("foofoo").putAlias(AliasMetaData.builder("barbaz")));
ClusterState state = ClusterState.builder(new ClusterName("_name")).metaData(mdBuilder).build();
IndicesOptions[] indicesOptions = new IndicesOptions[]{ IndicesOptions.strictExpandOpen(), IndicesOptions.strictExpand()};
for (IndicesOptions options : indicesOptions) {
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, options);
String[] results = indexNameExpressionResolver.concreteIndexNames(context, "foo");
assertEquals(1, results.length);
assertEquals("foo", results[0]);
try {
indexNameExpressionResolver.concreteIndexNames(context, "bar");
fail();
} catch (IndexNotFoundException e) {
assertThat(e.getIndex().getName(), equalTo("bar"));
}
results = indexNameExpressionResolver.concreteIndexNames(context, "foofoo", "foobar");
assertEquals(2, results.length);
assertThat(results, arrayContainingInAnyOrder("foofoo", "foobar"));
results = indexNameExpressionResolver.concreteIndexNames(context, "foofoobar");
assertEquals(new HashSet<>(Arrays.asList("foo", "foobar")),
new HashSet<>(Arrays.asList(results)));
try {
indexNameExpressionResolver.concreteIndexNames(context, "bar");
fail();
} catch (IndexNotFoundException e) {
assertThat(e.getIndex().getName(), equalTo("bar"));
}
try {
indexNameExpressionResolver.concreteIndexNames(context, "foo", "bar");
fail();
} catch (IndexNotFoundException e) {
assertThat(e.getIndex().getName(), equalTo("bar"));
}
results = indexNameExpressionResolver.concreteIndexNames(context, "barbaz", "foobar");
assertEquals(2, results.length);
assertThat(results, arrayContainingInAnyOrder("foofoo", "foobar"));
try {
indexNameExpressionResolver.concreteIndexNames(context, "barbaz", "bar");
fail();
} catch (IndexNotFoundException e) {
assertThat(e.getIndex().getName(), equalTo("bar"));
}
results = indexNameExpressionResolver.concreteIndexNames(context, "baz*");
assertThat(results, emptyArray());
results = indexNameExpressionResolver.concreteIndexNames(context, "foo", "baz*");
assertEquals(1, results.length);
assertEquals("foo", results[0]);
}
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, IndicesOptions.strictExpandOpen());
String[] results = indexNameExpressionResolver.concreteIndexNames(context, Strings.EMPTY_ARRAY);
assertEquals(3, results.length);
results = indexNameExpressionResolver.concreteIndexNames(context, (String[])null);
assertEquals(3, results.length);
context = new IndexNameExpressionResolver.Context(state, IndicesOptions.strictExpand());
results = indexNameExpressionResolver.concreteIndexNames(context, Strings.EMPTY_ARRAY);
assertEquals(4, results.length);
results = indexNameExpressionResolver.concreteIndexNames(context, (String[])null);
assertEquals(4, results.length);
context = new IndexNameExpressionResolver.Context(state, IndicesOptions.strictExpandOpen());
results = indexNameExpressionResolver.concreteIndexNames(context, "foofoo*");
assertEquals(3, results.length);
assertThat(results, arrayContainingInAnyOrder("foo", "foobar", "foofoo"));
context = new IndexNameExpressionResolver.Context(state, IndicesOptions.strictExpand());
results = indexNameExpressionResolver.concreteIndexNames(context, "foofoo*");
assertEquals(4, results.length);
assertThat(results, arrayContainingInAnyOrder("foo", "foobar", "foofoo", "foofoo-closed"));
}
public void testIndexOptionsLenient() {
MetaData.Builder mdBuilder = MetaData.builder()
.put(indexBuilder("foo").putAlias(AliasMetaData.builder("foofoobar")))
.put(indexBuilder("foobar").putAlias(AliasMetaData.builder("foofoobar")))
.put(indexBuilder("foofoo-closed").state(IndexMetaData.State.CLOSE))
.put(indexBuilder("foofoo").putAlias(AliasMetaData.builder("barbaz")));
ClusterState state = ClusterState.builder(new ClusterName("_name")).metaData(mdBuilder).build();
IndicesOptions lenientExpand = IndicesOptions.fromOptions(true, true, true, true);
IndicesOptions[] indicesOptions = new IndicesOptions[]{ IndicesOptions.lenientExpandOpen(), lenientExpand};
for (IndicesOptions options : indicesOptions) {
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, options);
String[] results = indexNameExpressionResolver.concreteIndexNames(context, "foo");
assertEquals(1, results.length);
assertEquals("foo", results[0]);
results = indexNameExpressionResolver.concreteIndexNames(context, "bar");
assertThat(results, emptyArray());
results = indexNameExpressionResolver.concreteIndexNames(context, "foofoo", "foobar");
assertEquals(2, results.length);
assertThat(results, arrayContainingInAnyOrder("foofoo", "foobar"));
results = indexNameExpressionResolver.concreteIndexNames(context, "foofoobar");
assertEquals(2, results.length);
assertEquals(new HashSet<>(Arrays.asList("foo", "foobar")),
new HashSet<>(Arrays.asList(results)));
results = indexNameExpressionResolver.concreteIndexNames(context, "foo", "bar");
assertEquals(1, results.length);
assertThat(results, arrayContainingInAnyOrder("foo"));
results = indexNameExpressionResolver.concreteIndexNames(context, "barbaz", "foobar");
assertEquals(2, results.length);
assertThat(results, arrayContainingInAnyOrder("foofoo", "foobar"));
results = indexNameExpressionResolver.concreteIndexNames(context, "barbaz", "bar");
assertEquals(1, results.length);
assertThat(results, arrayContainingInAnyOrder("foofoo"));
results = indexNameExpressionResolver.concreteIndexNames(context, "baz*");
assertThat(results, emptyArray());
results = indexNameExpressionResolver.concreteIndexNames(context, "foo", "baz*");
assertEquals(1, results.length);
assertEquals("foo", results[0]);
}
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, IndicesOptions.lenientExpandOpen());
String[] results = indexNameExpressionResolver.concreteIndexNames(context, Strings.EMPTY_ARRAY);
assertEquals(3, results.length);
context = new IndexNameExpressionResolver.Context(state, lenientExpand);
results = indexNameExpressionResolver.concreteIndexNames(context, Strings.EMPTY_ARRAY);
assertEquals(Arrays.toString(results), 4, results.length);
context = new IndexNameExpressionResolver.Context(state, IndicesOptions.lenientExpandOpen());
results = indexNameExpressionResolver.concreteIndexNames(context, "foofoo*");
assertEquals(3, results.length);
assertThat(results, arrayContainingInAnyOrder("foo", "foobar", "foofoo"));
context = new IndexNameExpressionResolver.Context(state, lenientExpand);
results = indexNameExpressionResolver.concreteIndexNames(context, "foofoo*");
assertEquals(4, results.length);
assertThat(results, arrayContainingInAnyOrder("foo", "foobar", "foofoo", "foofoo-closed"));
}
public void testIndexOptionsAllowUnavailableDisallowEmpty() {
MetaData.Builder mdBuilder = MetaData.builder()
.put(indexBuilder("foo"))
.put(indexBuilder("foobar"))
.put(indexBuilder("foofoo-closed").state(IndexMetaData.State.CLOSE))
.put(indexBuilder("foofoo").putAlias(AliasMetaData.builder("barbaz")));
ClusterState state = ClusterState.builder(new ClusterName("_name")).metaData(mdBuilder).build();
IndicesOptions expandOpen = IndicesOptions.fromOptions(true, false, true, false);
IndicesOptions expand = IndicesOptions.fromOptions(true, false, true, true);
IndicesOptions[] indicesOptions = new IndicesOptions[]{expandOpen, expand};
for (IndicesOptions options : indicesOptions) {
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, options);
String[] results = indexNameExpressionResolver.concreteIndexNames(context, "foo");
assertEquals(1, results.length);
assertEquals("foo", results[0]);
try {
indexNameExpressionResolver.concreteIndexNames(context, "bar");
fail();
} catch(IndexNotFoundException e) {
assertThat(e.getIndex().getName(), equalTo("bar"));
}
try {
indexNameExpressionResolver.concreteIndexNames(context, "baz*");
fail();
} catch (IndexNotFoundException e) {
assertThat(e.getIndex().getName(), equalTo("baz*"));
}
try {
indexNameExpressionResolver.concreteIndexNames(context, "foo", "baz*");
fail();
} catch (IndexNotFoundException e) {
assertThat(e.getIndex().getName(), equalTo("baz*"));
}
}
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, expandOpen);
String[] results = indexNameExpressionResolver.concreteIndexNames(context, Strings.EMPTY_ARRAY);
assertEquals(3, results.length);
context = new IndexNameExpressionResolver.Context(state, expand);
results = indexNameExpressionResolver.concreteIndexNames(context, Strings.EMPTY_ARRAY);
assertEquals(4, results.length);
}
public void testIndexOptionsWildcardExpansion() {
MetaData.Builder mdBuilder = MetaData.builder()
.put(indexBuilder("foo").state(IndexMetaData.State.CLOSE))
.put(indexBuilder("bar"))
.put(indexBuilder("foobar").putAlias(AliasMetaData.builder("barbaz")));
ClusterState state = ClusterState.builder(new ClusterName("_name")).metaData(mdBuilder).build();
// Only closed
IndicesOptions options = IndicesOptions.fromOptions(false, true, false, true);
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, options);
String[] results = indexNameExpressionResolver.concreteIndexNames(context, Strings.EMPTY_ARRAY);
assertEquals(1, results.length);
assertEquals("foo", results[0]);
results = indexNameExpressionResolver.concreteIndexNames(context, "foo*");
assertEquals(1, results.length);
assertEquals("foo", results[0]);
// no wildcards, so wildcard expansion don't apply
results = indexNameExpressionResolver.concreteIndexNames(context, "bar");
assertEquals(1, results.length);
assertEquals("bar", results[0]);
// Only open
options = IndicesOptions.fromOptions(false, true, true, false);
context = new IndexNameExpressionResolver.Context(state, options);
results = indexNameExpressionResolver.concreteIndexNames(context, Strings.EMPTY_ARRAY);
assertEquals(2, results.length);
assertThat(results, arrayContainingInAnyOrder("bar", "foobar"));
results = indexNameExpressionResolver.concreteIndexNames(context, "foo*");
assertEquals(1, results.length);
assertEquals("foobar", results[0]);
results = indexNameExpressionResolver.concreteIndexNames(context, "bar");
assertEquals(1, results.length);
assertEquals("bar", results[0]);
// Open and closed
options = IndicesOptions.fromOptions(false, true, true, true);
context = new IndexNameExpressionResolver.Context(state, options);
results = indexNameExpressionResolver.concreteIndexNames(context, Strings.EMPTY_ARRAY);
assertEquals(3, results.length);
assertThat(results, arrayContainingInAnyOrder("bar", "foobar", "foo"));
results = indexNameExpressionResolver.concreteIndexNames(context, "foo*");
assertEquals(2, results.length);
assertThat(results, arrayContainingInAnyOrder("foobar", "foo"));
results = indexNameExpressionResolver.concreteIndexNames(context, "bar");
assertEquals(1, results.length);
assertEquals("bar", results[0]);
results = indexNameExpressionResolver.concreteIndexNames(context, "*", "-foo*");
assertEquals(1, results.length);
assertEquals("bar", results[0]);
results = indexNameExpressionResolver.concreteIndexNames(context, "-*");
assertEquals(0, results.length);
options = IndicesOptions.fromOptions(false, false, true, true);
context = new IndexNameExpressionResolver.Context(state, options);
try {
indexNameExpressionResolver.concreteIndexNames(context, "-*");
fail();
} catch (IndexNotFoundException e) {
assertThat(e.getResourceId().toString(), equalTo("[-*]"));
}
}
public void testIndexOptionsNoExpandWildcards() {
MetaData.Builder mdBuilder = MetaData.builder()
.put(indexBuilder("foo").putAlias(AliasMetaData.builder("foofoobar")))
.put(indexBuilder("foobar").putAlias(AliasMetaData.builder("foofoobar")))
.put(indexBuilder("foofoo-closed").state(IndexMetaData.State.CLOSE))
.put(indexBuilder("foofoo").putAlias(AliasMetaData.builder("barbaz")));
ClusterState state = ClusterState.builder(new ClusterName("_name")).metaData(mdBuilder).build();
//ignore unavailable and allow no indices
{
IndicesOptions noExpandLenient = IndicesOptions.fromOptions(true, true, false, false);
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, noExpandLenient);
String[] results = indexNameExpressionResolver.concreteIndexNames(context, "baz*");
assertThat(results, emptyArray());
results = indexNameExpressionResolver.concreteIndexNames(context, "foo", "baz*");
assertEquals(1, results.length);
assertEquals("foo", results[0]);
results = indexNameExpressionResolver.concreteIndexNames(context, "foofoobar");
assertEquals(2, results.length);
assertThat(results, arrayContainingInAnyOrder("foo", "foobar"));
results = indexNameExpressionResolver.concreteIndexNames(context, (String[])null);
assertEquals(0, results.length);
results = indexNameExpressionResolver.concreteIndexNames(context, Strings.EMPTY_ARRAY);
assertEquals(0, results.length);
}
//ignore unavailable but don't allow no indices
{
IndicesOptions noExpandDisallowEmpty = IndicesOptions.fromOptions(true, false, false, false);
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, noExpandDisallowEmpty);
try {
indexNameExpressionResolver.concreteIndexNames(context, "baz*");
fail();
} catch (IndexNotFoundException e) {
assertThat(e.getIndex().getName(), equalTo("baz*"));
}
String[] results = indexNameExpressionResolver.concreteIndexNames(context, "foo", "baz*");
assertEquals(1, results.length);
assertEquals("foo", results[0]);
results = indexNameExpressionResolver.concreteIndexNames(context, "foofoobar");
assertEquals(2, results.length);
assertThat(results, arrayContainingInAnyOrder("foo", "foobar"));
}
//error on unavailable but allow no indices
{
IndicesOptions noExpandErrorUnavailable = IndicesOptions.fromOptions(false, true, false, false);
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, noExpandErrorUnavailable);
String[] results = indexNameExpressionResolver.concreteIndexNames(context, "baz*");
assertThat(results, emptyArray());
try {
indexNameExpressionResolver.concreteIndexNames(context, "foo", "baz*");
fail();
} catch (IndexNotFoundException e) {
assertThat(e.getIndex().getName(), equalTo("baz*"));
}
results = indexNameExpressionResolver.concreteIndexNames(context, "foofoobar");
assertEquals(2, results.length);
assertThat(results, arrayContainingInAnyOrder("foo", "foobar"));
}
//error on both unavailable and no indices
{
IndicesOptions noExpandStrict = IndicesOptions.fromOptions(false, false, false, false);
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, noExpandStrict);
try {
indexNameExpressionResolver.concreteIndexNames(context, "baz*");
fail();
} catch (IndexNotFoundException e) {
assertThat(e.getIndex().getName(), equalTo("baz*"));
}
try {
indexNameExpressionResolver.concreteIndexNames(context, "foo", "baz*");
fail();
} catch (IndexNotFoundException e) {
assertThat(e.getIndex().getName(), equalTo("baz*"));
}
String[] results = indexNameExpressionResolver.concreteIndexNames(context, "foofoobar");
assertEquals(2, results.length);
assertThat(results, arrayContainingInAnyOrder("foo", "foobar"));
}
}
public void testIndexOptionsSingleIndexNoExpandWildcards() {
MetaData.Builder mdBuilder = MetaData.builder()
.put(indexBuilder("foo").putAlias(AliasMetaData.builder("foofoobar")))
.put(indexBuilder("foobar").putAlias(AliasMetaData.builder("foofoobar")))
.put(indexBuilder("foofoo-closed").state(IndexMetaData.State.CLOSE))
.put(indexBuilder("foofoo").putAlias(AliasMetaData.builder("barbaz")));
ClusterState state = ClusterState.builder(new ClusterName("_name")).metaData(mdBuilder).build();
//error on both unavailable and no indices + every alias needs to expand to a single index
try {
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, IndicesOptions.strictSingleIndexNoExpandForbidClosed());
indexNameExpressionResolver.concreteIndexNames(context, "baz*");
fail();
} catch (IndexNotFoundException e) {
assertThat(e.getIndex().getName(), equalTo("baz*"));
}
try {
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, IndicesOptions.strictSingleIndexNoExpandForbidClosed());
indexNameExpressionResolver.concreteIndexNames(context, "foo", "baz*");
fail();
} catch (IndexNotFoundException e) {
assertThat(e.getIndex().getName(), equalTo("baz*"));
}
try {
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, IndicesOptions.strictSingleIndexNoExpandForbidClosed());
indexNameExpressionResolver.concreteIndexNames(context, "foofoobar");
fail();
} catch(IllegalArgumentException e) {
assertThat(e.getMessage(), containsString("Alias [foofoobar] has more than one indices associated with it"));
}
try {
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, IndicesOptions.strictSingleIndexNoExpandForbidClosed());
indexNameExpressionResolver.concreteIndexNames(context, "foo", "foofoobar");
fail();
} catch(IllegalArgumentException e) {
assertThat(e.getMessage(), containsString("Alias [foofoobar] has more than one indices associated with it"));
}
try {
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, IndicesOptions.strictSingleIndexNoExpandForbidClosed());
indexNameExpressionResolver.concreteIndexNames(context, "foofoo-closed", "foofoobar");
fail();
} catch(IndexClosedException e) {
assertThat(e.getMessage(), equalTo("closed"));
assertEquals(e.getIndex().getName(), "foofoo-closed");
}
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, IndicesOptions.strictSingleIndexNoExpandForbidClosed());
String[] results = indexNameExpressionResolver.concreteIndexNames(context, "foo", "barbaz");
assertEquals(2, results.length);
assertThat(results, arrayContainingInAnyOrder("foo", "foofoo"));
}
public void testIndexOptionsEmptyCluster() {
ClusterState state = ClusterState.builder(new ClusterName("_name")).metaData(MetaData.builder().build()).build();
IndicesOptions options = IndicesOptions.strictExpandOpen();
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, options);
String[] results = indexNameExpressionResolver.concreteIndexNames(context, Strings.EMPTY_ARRAY);
assertThat(results, emptyArray());
try {
indexNameExpressionResolver.concreteIndexNames(context, "foo");
fail();
} catch (IndexNotFoundException e) {
assertThat(e.getIndex().getName(), equalTo("foo"));
}
results = indexNameExpressionResolver.concreteIndexNames(context, "foo*");
assertThat(results, emptyArray());
try {
indexNameExpressionResolver.concreteIndexNames(context, "foo*", "bar");
fail();
} catch (IndexNotFoundException e) {
assertThat(e.getIndex().getName(), equalTo("bar"));
}
context = new IndexNameExpressionResolver.Context(state, IndicesOptions.lenientExpandOpen());
results = indexNameExpressionResolver.concreteIndexNames(context, Strings.EMPTY_ARRAY);
assertThat(results, emptyArray());
results = indexNameExpressionResolver.concreteIndexNames(context, "foo");
assertThat(results, emptyArray());
results = indexNameExpressionResolver.concreteIndexNames(context, "foo*");
assertThat(results, emptyArray());
results = indexNameExpressionResolver.concreteIndexNames(context, "foo*", "bar");
assertThat(results, emptyArray());
context = new IndexNameExpressionResolver.Context(state, IndicesOptions.fromOptions(true, false, true, false));
try {
indexNameExpressionResolver.concreteIndexNames(context, Strings.EMPTY_ARRAY);
} catch (IndexNotFoundException e) {
assertThat(e.getResourceId().toString(), equalTo("[_all]"));
}
}
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));
}
public void testConcreteIndicesIgnoreIndicesOneMissingIndex() {
MetaData.Builder mdBuilder = MetaData.builder()
.put(indexBuilder("testXXX"))
.put(indexBuilder("kuku"));
ClusterState state = ClusterState.builder(new ClusterName("_name")).metaData(mdBuilder).build();
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, IndicesOptions.strictExpandOpen());
try {
indexNameExpressionResolver.concreteIndexNames(context, "testZZZ");
fail("Expected IndexNotFoundException");
} catch(IndexNotFoundException e) {
assertThat(e.getMessage(), is("no such index"));
}
}
public void testConcreteIndicesIgnoreIndicesOneMissingIndexOtherFound() {
MetaData.Builder mdBuilder = MetaData.builder()
.put(indexBuilder("testXXX"))
.put(indexBuilder("kuku"));
ClusterState state = ClusterState.builder(new ClusterName("_name")).metaData(mdBuilder).build();
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, IndicesOptions.lenientExpandOpen());
assertThat(newHashSet(indexNameExpressionResolver.concreteIndexNames(context, "testXXX", "testZZZ")), equalTo(newHashSet("testXXX")));
}
public void testConcreteIndicesIgnoreIndicesAllMissing() {
MetaData.Builder mdBuilder = MetaData.builder()
.put(indexBuilder("testXXX"))
.put(indexBuilder("kuku"));
ClusterState state = ClusterState.builder(new ClusterName("_name")).metaData(mdBuilder).build();
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, IndicesOptions.strictExpandOpen());
try {
indexNameExpressionResolver.concreteIndexNames(context, "testMo", "testMahdy");
fail("Expected IndexNotFoundException");
} catch(IndexNotFoundException e) {
assertThat(e.getMessage(), is("no such index"));
}
}
public void testConcreteIndicesIgnoreIndicesEmptyRequest() {
MetaData.Builder mdBuilder = MetaData.builder()
.put(indexBuilder("testXXX"))
.put(indexBuilder("kuku"));
ClusterState state = ClusterState.builder(new ClusterName("_name")).metaData(mdBuilder).build();
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, IndicesOptions.lenientExpandOpen());
assertThat(newHashSet(indexNameExpressionResolver.concreteIndexNames(context, new String[]{})), equalTo(newHashSet("kuku", "testXXX")));
}
public void testConcreteIndicesWildcardExpansion() {
MetaData.Builder mdBuilder = MetaData.builder()
.put(indexBuilder("testXXX").state(State.OPEN))
.put(indexBuilder("testXXY").state(State.OPEN))
.put(indexBuilder("testXYY").state(State.CLOSE))
.put(indexBuilder("testYYY").state(State.OPEN))
.put(indexBuilder("testYYX").state(State.OPEN));
ClusterState state = ClusterState.builder(new ClusterName("_name")).metaData(mdBuilder).build();
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, IndicesOptions.fromOptions(true, true, false, false));
assertThat(newHashSet(indexNameExpressionResolver.concreteIndexNames(context, "testX*")), equalTo(new HashSet<String>()));
context = new IndexNameExpressionResolver.Context(state, IndicesOptions.fromOptions(true, true, true, false));
assertThat(newHashSet(indexNameExpressionResolver.concreteIndexNames(context, "testX*")), equalTo(newHashSet("testXXX", "testXXY")));
context = new IndexNameExpressionResolver.Context(state, IndicesOptions.fromOptions(true, true, false, true));
assertThat(newHashSet(indexNameExpressionResolver.concreteIndexNames(context, "testX*")), equalTo(newHashSet("testXYY")));
context = new IndexNameExpressionResolver.Context(state, IndicesOptions.fromOptions(true, true, true, true));
assertThat(newHashSet(indexNameExpressionResolver.concreteIndexNames(context, "testX*")), equalTo(newHashSet("testXXX", "testXXY", "testXYY")));
}
public void testConcreteIndicesWildcardWithNegation() {
MetaData.Builder mdBuilder = MetaData.builder()
.put(indexBuilder("testXXX").state(State.OPEN))
.put(indexBuilder("testXXY").state(State.OPEN))
.put(indexBuilder("testXYY").state(State.OPEN))
.put(indexBuilder("-testXYZ").state(State.OPEN))
.put(indexBuilder("-testXZZ").state(State.OPEN))
.put(indexBuilder("-testYYY").state(State.OPEN))
.put(indexBuilder("testYYY").state(State.OPEN))
.put(indexBuilder("testYYX").state(State.OPEN));
ClusterState state = ClusterState.builder(new ClusterName("_name")).metaData(mdBuilder).build();
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state,
IndicesOptions.fromOptions(true, true, true, true));
assertThat(newHashSet(indexNameExpressionResolver.concreteIndexNames(context, "testX*")),
equalTo(newHashSet("testXXX", "testXXY", "testXYY")));
assertThat(newHashSet(indexNameExpressionResolver.concreteIndexNames(context, "test*", "-testX*")),
equalTo(newHashSet("testYYY", "testYYX")));
assertThat(newHashSet(indexNameExpressionResolver.concreteIndexNames(context, "-testX*")),
equalTo(newHashSet("-testXYZ", "-testXZZ")));
assertThat(newHashSet(indexNameExpressionResolver.concreteIndexNames(context, "testXXY", "-testX*")),
equalTo(newHashSet("testXXY", "-testXYZ", "-testXZZ")));
assertThat(newHashSet(indexNameExpressionResolver.concreteIndexNames(context, "*", "--testX*")),
equalTo(newHashSet("testXXX", "testXXY", "testXYY", "testYYX", "testYYY", "-testYYY")));
assertThat(newHashSet(indexNameExpressionResolver.concreteIndexNames(context, "-testXXX", "test*")),
equalTo(newHashSet("testYYX", "testXXX", "testXYY", "testYYY", "testXXY")));
assertThat(newHashSet(indexNameExpressionResolver.concreteIndexNames(context, "test*", "-testXXX")),
equalTo(newHashSet("testYYX", "testXYY", "testYYY", "testXXY")));
assertThat(newHashSet(indexNameExpressionResolver.concreteIndexNames(context, "+testXXX", "+testXXY", "+testYYY", "-testYYY")),
equalTo(newHashSet("testXXX", "testXXY", "testYYY", "-testYYY")));
assertThat(newHashSet(indexNameExpressionResolver.concreteIndexNames(context, "testYYY", "testYYX", "testX*", "-testXXX")),
equalTo(newHashSet("testYYY", "testYYX", "testXXY", "testXYY")));
assertThat(newHashSet(indexNameExpressionResolver.concreteIndexNames(context, "-testXXX", "*testY*", "-testYYY")),
equalTo(newHashSet("testYYX", "testYYY", "-testYYY")));
String[] indexNames = indexNameExpressionResolver.concreteIndexNames(state, IndicesOptions.lenientExpandOpen(), "-doesnotexist");
assertEquals(0, indexNames.length);
assertThat(newHashSet(indexNameExpressionResolver.concreteIndexNames(state, IndicesOptions.lenientExpandOpen(), "-*")),
equalTo(newHashSet("-testXYZ", "-testXZZ", "-testYYY")));
assertThat(newHashSet(indexNameExpressionResolver.concreteIndexNames(state, IndicesOptions.lenientExpandOpen(),
"+testXXX", "+testXXY", "+testXYY", "-testXXY")),
equalTo(newHashSet("testXXX", "testXYY", "testXXY")));
indexNames = indexNameExpressionResolver.concreteIndexNames(state, IndicesOptions.lenientExpandOpen(), "*", "-*");
assertEquals(0, indexNames.length);
}
/**
* test resolving _all pattern (null, empty array or "_all") for random IndicesOptions
*/
public void testConcreteIndicesAllPatternRandom() {
for (int i = 0; i < 10; i++) {
String[] allIndices = null;
switch (randomIntBetween(0, 2)) {
case 0:
break;
case 1:
allIndices = new String[0];
break;
case 2:
allIndices = new String[] { MetaData.ALL };
break;
}
IndicesOptions indicesOptions = IndicesOptions.fromOptions(randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean());
ClusterState state = ClusterState.builder(new ClusterName("_name")).metaData(MetaData.builder().build()).build();
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, indicesOptions);
// with no indices, asking for all indices should return empty list or exception, depending on indices options
if (indicesOptions.allowNoIndices()) {
String[] concreteIndices = indexNameExpressionResolver.concreteIndexNames(context, allIndices);
assertThat(concreteIndices, notNullValue());
assertThat(concreteIndices.length, equalTo(0));
} else {
checkCorrectException(indexNameExpressionResolver, context, allIndices);
}
// with existing indices, asking for all indices should return all open/closed indices depending on options
MetaData.Builder mdBuilder = MetaData.builder()
.put(indexBuilder("aaa").state(State.OPEN).putAlias(AliasMetaData.builder("aaa_alias1")))
.put(indexBuilder("bbb").state(State.OPEN).putAlias(AliasMetaData.builder("bbb_alias1")))
.put(indexBuilder("ccc").state(State.CLOSE).putAlias(AliasMetaData.builder("ccc_alias1")));
state = ClusterState.builder(new ClusterName("_name")).metaData(mdBuilder).build();
context = new IndexNameExpressionResolver.Context(state, indicesOptions);
if (indicesOptions.expandWildcardsOpen() || indicesOptions.expandWildcardsClosed() || indicesOptions.allowNoIndices()) {
String[] concreteIndices = indexNameExpressionResolver.concreteIndexNames(context, allIndices);
assertThat(concreteIndices, notNullValue());
int expectedNumberOfIndices = 0;
if (indicesOptions.expandWildcardsOpen()) {
expectedNumberOfIndices += 2;
}
if (indicesOptions.expandWildcardsClosed()) {
expectedNumberOfIndices += 1;
}
assertThat(concreteIndices.length, equalTo(expectedNumberOfIndices));
} else {
checkCorrectException(indexNameExpressionResolver, context, allIndices);
}
}
}
/**
* check for correct exception type depending on indicesOptions and provided index name list
*/
private void checkCorrectException(IndexNameExpressionResolver indexNameExpressionResolver, IndexNameExpressionResolver.Context context, String[] allIndices) {
try {
indexNameExpressionResolver.concreteIndexNames(context, allIndices);
fail("wildcard expansion on should trigger IndexMissingException");
} catch (IndexNotFoundException e) {
// expected
}
}
/**
* test resolving wildcard pattern that matches no index of alias for random IndicesOptions
*/
public void testConcreteIndicesWildcardNoMatch() {
for (int i = 0; i < 10; i++) {
IndicesOptions indicesOptions = IndicesOptions.fromOptions(randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean());
MetaData.Builder mdBuilder = MetaData.builder()
.put(indexBuilder("aaa").state(State.OPEN).putAlias(AliasMetaData.builder("aaa_alias1")))
.put(indexBuilder("bbb").state(State.OPEN).putAlias(AliasMetaData.builder("bbb_alias1")))
.put(indexBuilder("ccc").state(State.CLOSE).putAlias(AliasMetaData.builder("ccc_alias1")));
ClusterState state = ClusterState.builder(new ClusterName("_name")).metaData(mdBuilder).build();
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, indicesOptions);
// asking for non existing wildcard pattern should return empty list or exception
if (indicesOptions.allowNoIndices()) {
String[] concreteIndices = indexNameExpressionResolver.concreteIndexNames(context, "Foo*");
assertThat(concreteIndices, notNullValue());
assertThat(concreteIndices.length, equalTo(0));
} else {
try {
indexNameExpressionResolver.concreteIndexNames(context, "Foo*");
fail("expecting exception when result empty and allowNoIndicec=false");
} catch (IndexNotFoundException e) {
// expected exception
}
}
}
}
public void testIsAllIndicesNull() throws Exception {
assertThat(IndexNameExpressionResolver.isAllIndices(null), equalTo(true));
}
public void testIsAllIndicesEmpty() throws Exception {
assertThat(IndexNameExpressionResolver.isAllIndices(Collections.<String>emptyList()), equalTo(true));
}
public void testIsAllIndicesExplicitAll() throws Exception {
assertThat(IndexNameExpressionResolver.isAllIndices(Arrays.asList("_all")), equalTo(true));
}
public void testIsAllIndicesExplicitAllPlusOther() throws Exception {
assertThat(IndexNameExpressionResolver.isAllIndices(Arrays.asList("_all", "other")), equalTo(false));
}
public void testIsAllIndicesNormalIndexes() throws Exception {
assertThat(IndexNameExpressionResolver.isAllIndices(Arrays.asList("index1", "index2", "index3")), equalTo(false));
}
public void testIsAllIndicesWildcard() throws Exception {
assertThat(IndexNameExpressionResolver.isAllIndices(Arrays.asList("*")), equalTo(false));
}
public void testIsExplicitAllIndicesNull() throws Exception {
assertThat(IndexNameExpressionResolver.isExplicitAllPattern(null), equalTo(false));
}
public void testIsExplicitAllIndicesEmpty() throws Exception {
assertThat(IndexNameExpressionResolver.isExplicitAllPattern(Collections.<String>emptyList()), equalTo(false));
}
public void testIsExplicitAllIndicesExplicitAll() throws Exception {
assertThat(IndexNameExpressionResolver.isExplicitAllPattern(Arrays.asList("_all")), equalTo(true));
}
public void testIsExplicitAllIndicesExplicitAllPlusOther() throws Exception {
assertThat(IndexNameExpressionResolver.isExplicitAllPattern(Arrays.asList("_all", "other")), equalTo(false));
}
public void testIsExplicitAllIndicesNormalIndexes() throws Exception {
assertThat(IndexNameExpressionResolver.isExplicitAllPattern(Arrays.asList("index1", "index2", "index3")), equalTo(false));
}
public void testIsExplicitAllIndicesWildcard() throws Exception {
assertThat(IndexNameExpressionResolver.isExplicitAllPattern(Arrays.asList("*")), equalTo(false));
}
public void testIsPatternMatchingAllIndicesExplicitList() throws Exception {
//even though it does identify all indices, it's not a pattern but just an explicit list of them
String[] concreteIndices = new String[]{"index1", "index2", "index3"};
MetaData metaData = metaDataBuilder(concreteIndices);
assertThat(indexNameExpressionResolver.isPatternMatchingAllIndices(metaData, concreteIndices, concreteIndices), equalTo(false));
}
public void testIsPatternMatchingAllIndicesOnlyWildcard() throws Exception {
String[] indicesOrAliases = new String[]{"*"};
String[] concreteIndices = new String[]{"index1", "index2", "index3"};
MetaData metaData = metaDataBuilder(concreteIndices);
assertThat(indexNameExpressionResolver.isPatternMatchingAllIndices(metaData, indicesOrAliases, concreteIndices), equalTo(true));
}
public void testIsPatternMatchingAllIndicesMatchingTrailingWildcard() throws Exception {
String[] indicesOrAliases = new String[]{"index*"};
String[] concreteIndices = new String[]{"index1", "index2", "index3"};
MetaData metaData = metaDataBuilder(concreteIndices);
assertThat(indexNameExpressionResolver.isPatternMatchingAllIndices(metaData, indicesOrAliases, concreteIndices), equalTo(true));
}
public void testIsPatternMatchingAllIndicesNonMatchingTrailingWildcard() throws Exception {
String[] indicesOrAliases = new String[]{"index*"};
String[] concreteIndices = new String[]{"index1", "index2", "index3"};
String[] allConcreteIndices = new String[]{"index1", "index2", "index3", "a", "b"};
MetaData metaData = metaDataBuilder(allConcreteIndices);
assertThat(indexNameExpressionResolver.isPatternMatchingAllIndices(metaData, indicesOrAliases, concreteIndices), equalTo(false));
}
public void testIsPatternMatchingAllIndicesMatchingSingleExclusion() throws Exception {
String[] indicesOrAliases = new String[]{"-index1", "+index1"};
String[] concreteIndices = new String[]{"index1", "index2", "index3"};
MetaData metaData = metaDataBuilder(concreteIndices);
assertThat(indexNameExpressionResolver.isPatternMatchingAllIndices(metaData, indicesOrAliases, concreteIndices), equalTo(true));
}
public void testIsPatternMatchingAllIndicesNonMatchingSingleExclusion() throws Exception {
String[] indicesOrAliases = new String[]{"-index1"};
String[] concreteIndices = new String[]{"index2", "index3"};
String[] allConcreteIndices = new String[]{"index1", "index2", "index3"};
MetaData metaData = metaDataBuilder(allConcreteIndices);
assertThat(indexNameExpressionResolver.isPatternMatchingAllIndices(metaData, indicesOrAliases, concreteIndices), equalTo(false));
}
public void testIsPatternMatchingAllIndicesMatchingTrailingWildcardAndExclusion() throws Exception {
String[] indicesOrAliases = new String[]{"index*", "-index1", "+index1"};
String[] concreteIndices = new String[]{"index1", "index2", "index3"};
MetaData metaData = metaDataBuilder(concreteIndices);
assertThat(indexNameExpressionResolver.isPatternMatchingAllIndices(metaData, indicesOrAliases, concreteIndices), equalTo(true));
}
public void testIsPatternMatchingAllIndicesNonMatchingTrailingWildcardAndExclusion() throws Exception {
String[] indicesOrAliases = new String[]{"index*", "-index1"};
String[] concreteIndices = new String[]{"index2", "index3"};
String[] allConcreteIndices = new String[]{"index1", "index2", "index3"};
MetaData metaData = metaDataBuilder(allConcreteIndices);
assertThat(indexNameExpressionResolver.isPatternMatchingAllIndices(metaData, indicesOrAliases, concreteIndices), equalTo(false));
}
public void testIndexOptionsFailClosedIndicesAndAliases() {
MetaData.Builder mdBuilder = MetaData.builder()
.put(indexBuilder("foo1-closed").state(IndexMetaData.State.CLOSE).putAlias(AliasMetaData.builder("foobar1-closed")).putAlias(AliasMetaData.builder("foobar2-closed")))
.put(indexBuilder("foo2-closed").state(IndexMetaData.State.CLOSE).putAlias(AliasMetaData.builder("foobar2-closed")))
.put(indexBuilder("foo3").putAlias(AliasMetaData.builder("foobar2-closed")));
ClusterState state = ClusterState.builder(new ClusterName("_name")).metaData(mdBuilder).build();
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, IndicesOptions.strictExpandOpenAndForbidClosed());
try {
indexNameExpressionResolver.concreteIndexNames(context, "foo1-closed");
fail("foo1-closed should be closed, but it is open");
} catch (IndexClosedException e) {
// expected
}
try {
indexNameExpressionResolver.concreteIndexNames(context, "foobar1-closed");
fail("foo1-closed should be closed, but it is open");
} catch (IndexClosedException e) {
// expected
}
context = new IndexNameExpressionResolver.Context(state, IndicesOptions.fromOptions(true, context.getOptions().allowNoIndices(), context.getOptions().expandWildcardsOpen(), context.getOptions().expandWildcardsClosed(), context.getOptions()));
String[] results = indexNameExpressionResolver.concreteIndexNames(context, "foo1-closed");
assertThat(results, emptyArray());
results = indexNameExpressionResolver.concreteIndexNames(context, "foobar1-closed");
assertThat(results, emptyArray());
context = new IndexNameExpressionResolver.Context(state, IndicesOptions.lenientExpandOpen());
results = indexNameExpressionResolver.concreteIndexNames(context, "foo1-closed");
assertThat(results, arrayWithSize(1));
assertThat(results, arrayContaining("foo1-closed"));
results = indexNameExpressionResolver.concreteIndexNames(context, "foobar1-closed");
assertThat(results, arrayWithSize(1));
assertThat(results, arrayContaining("foo1-closed"));
// testing an alias pointing to three indices:
context = new IndexNameExpressionResolver.Context(state, IndicesOptions.strictExpandOpenAndForbidClosed());
try {
indexNameExpressionResolver.concreteIndexNames(context, "foobar2-closed");
fail("foo2-closed should be closed, but it is open");
} catch (IndexClosedException e) {
// expected
}
context = new IndexNameExpressionResolver.Context(state, IndicesOptions.fromOptions(true, context.getOptions().allowNoIndices(), context.getOptions().expandWildcardsOpen(), context.getOptions().expandWildcardsClosed(), context.getOptions()));
results = indexNameExpressionResolver.concreteIndexNames(context, "foobar2-closed");
assertThat(results, arrayWithSize(1));
assertThat(results, arrayContaining("foo3"));
context = new IndexNameExpressionResolver.Context(state, IndicesOptions.lenientExpandOpen());
results = indexNameExpressionResolver.concreteIndexNames(context, "foobar2-closed");
assertThat(results, arrayWithSize(3));
assertThat(results, arrayContainingInAnyOrder("foo1-closed", "foo2-closed", "foo3"));
}
public void testDedupConcreteIndices() {
MetaData.Builder mdBuilder = MetaData.builder()
.put(indexBuilder("index1").putAlias(AliasMetaData.builder("alias1")));
ClusterState state = ClusterState.builder(new ClusterName("_name")).metaData(mdBuilder).build();
IndicesOptions[] indicesOptions = new IndicesOptions[]{ IndicesOptions.strictExpandOpen(), IndicesOptions.strictExpand(),
IndicesOptions.lenientExpandOpen(), IndicesOptions.strictExpandOpenAndForbidClosed()};
for (IndicesOptions options : indicesOptions) {
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, options);
String[] results = indexNameExpressionResolver.concreteIndexNames(context, "index1", "index1", "alias1");
assertThat(results, equalTo(new String[]{"index1"}));
}
}
private MetaData metaDataBuilder(String... indices) {
MetaData.Builder mdBuilder = MetaData.builder();
for (String concreteIndex : indices) {
mdBuilder.put(indexBuilder(concreteIndex));
}
return mdBuilder.build();
}
public void testFilterClosedIndicesOnAliases() {
MetaData.Builder mdBuilder = MetaData.builder()
.put(indexBuilder("test-0").state(State.OPEN).putAlias(AliasMetaData.builder("alias-0")))
.put(indexBuilder("test-1").state(IndexMetaData.State.CLOSE).putAlias(AliasMetaData.builder("alias-1")));
ClusterState state = ClusterState.builder(new ClusterName("_name")).metaData(mdBuilder).build();
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(state, IndicesOptions.lenientExpandOpen());
String[] strings = indexNameExpressionResolver.concreteIndexNames(context, "alias-*");
assertArrayEquals(new String[] {"test-0"}, strings);
context = new IndexNameExpressionResolver.Context(state, IndicesOptions.strictExpandOpen());
strings = indexNameExpressionResolver.concreteIndexNames(context, "alias-*");
assertArrayEquals(new String[] {"test-0"}, strings);
}
public void testFilteringAliases() {
MetaData.Builder mdBuilder = MetaData.builder()
.put(indexBuilder("test-0").state(State.OPEN).putAlias(AliasMetaData.builder("alias-0").filter("{ \"term\": \"foo\"}")))
.put(indexBuilder("test-1").state(State.OPEN).putAlias(AliasMetaData.builder("alias-1")));
ClusterState state = ClusterState.builder(new ClusterName("_name")).metaData(mdBuilder).build();
String[] strings = indexNameExpressionResolver.filteringAliases(state, "test-0", "alias-*");
assertArrayEquals(new String[] {"alias-0"}, strings);
// concrete index supersedes filtering alias
strings = indexNameExpressionResolver.filteringAliases(state, "test-0", "test-0,alias-*");
assertNull(strings);
strings = indexNameExpressionResolver.filteringAliases(state, "test-0", "test-*,alias-*");
assertNull(strings);
}
public void testIndexAliases() {
MetaData.Builder mdBuilder = MetaData.builder()
.put(indexBuilder("test-0").state(State.OPEN)
.putAlias(AliasMetaData.builder("test-alias-0").filter("{ \"term\": \"foo\"}"))
.putAlias(AliasMetaData.builder("test-alias-1").filter("{ \"term\": \"foo\"}"))
.putAlias(AliasMetaData.builder("test-alias-non-filtering"))
);
ClusterState state = ClusterState.builder(new ClusterName("_name")).metaData(mdBuilder).build();
String[] strings = indexNameExpressionResolver.indexAliases(state, "test-0", x -> true, true, "test-*");
Arrays.sort(strings);
assertArrayEquals(new String[] {"test-alias-0", "test-alias-1", "test-alias-non-filtering"}, strings);
}
}