Skip to content
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

Return error when remote indices are locally resolved (7.x) #74762

Merged
merged 2 commits into from
Jul 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,13 @@ void indexSingleDocumentWithStringFieldsGeneratedFromText(boolean stored, boolea
index("test", "_doc", "1", doc);
}

public void testGetRemoteIndex() {
IllegalArgumentException iae = expectThrows(IllegalArgumentException.class,
() -> client().prepareGet("cluster:index", "_doc", "id").get());
assertEquals("Cross-cluster calls are not supported in this context but remote indices were requested: [cluster:index]",
iae.getMessage());
}

private void assertGetFieldsAlwaysWorks(String index, String type, String docId, String[] fields) {
assertGetFieldsAlwaysWorks(index, type, docId, fields, null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public Index[] concreteIndices(ClusterState state, IndicesRequest request) {
* provided indices options in the context don't allow such a case, or if the final result of the indices resolution
* contains no indices and the indices options in the context don't allow such a case.
* @throws IllegalArgumentException if one of the aliases resolve to multiple indices and the provided
* indices options in the context don't allow such a case.
* indices options in the context don't allow such a case; if a remote index is requested.
*/
public String[] concreteIndexNames(ClusterState state, IndicesOptions options, String... indexExpressions) {
Context context = new Context(state, options, getSystemIndexAccessLevel(),
Expand Down Expand Up @@ -168,7 +168,7 @@ public List<String> dataStreamNames(ClusterState state, IndicesOptions options,
* provided indices options in the context don't allow such a case, or if the final result of the indices resolution
* contains no indices and the indices options in the context don't allow such a case.
* @throws IllegalArgumentException if one of the aliases resolve to multiple indices and the provided
* indices options in the context don't allow such a case.
* indices options in the context don't allow such a case; if a remote index is requested.
*/
public Index[] concreteIndices(ClusterState state, IndicesOptions options, String... indexExpressions) {
return concreteIndices(state, options, false, indexExpressions);
Expand All @@ -190,7 +190,7 @@ public Index[] concreteIndices(ClusterState state, IndicesOptions options, boole
* provided indices options in the context don't allow such a case, or if the final result of the indices resolution
* contains no indices and the indices options in the context don't allow such a case.
* @throws IllegalArgumentException if one of the aliases resolve to multiple indices and the provided
* indices options in the context don't allow such a case.
* indices options in the context don't allow such a case; if a remote index is requested.
*/
public Index[] concreteIndices(ClusterState state, IndicesRequest request, long startTime) {
Context context = new Context(state, request.indicesOptions(), startTime, false, false, request.includeDataStreams(), false,
Expand All @@ -208,11 +208,45 @@ String[] concreteIndexNames(Context context, String... indexExpressions) {
}

Index[] concreteIndices(Context context, String... indexExpressions) {
Metadata metadata = context.getState().metadata();
IndicesOptions options = context.getOptions();
if (indexExpressions == null || indexExpressions.length == 0) {
indexExpressions = new String[]{Metadata.ALL};
} else {
if (options.ignoreUnavailable() == false) {
Set<String> crossClusterIndices = new HashSet<>();
for (String indexExpression : indexExpressions) {
if (indexExpression.contains(":")) {
List<String> resolved;
try {
resolved = wildcardExpressionResolver.resolve(context, Collections.singletonList(indexExpression));
} catch(IndexNotFoundException e) {
resolved = Collections.emptyList();
}
if (resolved.isEmpty()) {
crossClusterIndices.add(indexExpression);
} else {
boolean found = false;
for (String index : resolved) {
if (metadata.getIndicesLookup().containsKey(index)) {
found = true;
break;
}
}
if (found == false) {
crossClusterIndices.add(indexExpression);
}
}

}
}
if (crossClusterIndices.size() > 0) {
throw new IllegalArgumentException("Cross-cluster calls are not supported in this context but remote indices " +
"were requested: " + crossClusterIndices);
}
}
}
Metadata metadata = context.getState().metadata();
IndicesOptions options = context.getOptions();

// If only one index is specified then whether we fail a request if an index is missing depends on the allow_no_indices
// option. At some point we should change this, because there shouldn't be a reason why whether a single index
// or multiple indices are specified yield different behaviour.
Expand Down Expand Up @@ -397,7 +431,7 @@ private static IllegalArgumentException aliasesNotSupportedException(String expr
* @param state the cluster state containing all the data to resolve to expression to a concrete index
* @param request The request that defines how the an alias or an index need to be resolved to a concrete index
* and the expression that can be resolved to an alias or an index name.
* @throws IllegalArgumentException if the index resolution lead to more than one index
* @throws IllegalArgumentException if the index resolution returns more than one index; if a remote index is requested.
* @return the concrete index obtained as a result of the index resolution
*/
public Index concreteSingleIndex(ClusterState state, IndicesRequest request) {
Expand All @@ -416,7 +450,8 @@ public Index concreteSingleIndex(ClusterState state, IndicesRequest request) {
* @param state the cluster state containing all the data to resolve to expression to a concrete index
* @param request The request that defines how the an alias or an index need to be resolved to a concrete index
* and the expression that can be resolved to an alias or an index name.
* @throws IllegalArgumentException if the index resolution does not lead to an index, or leads to more than one index
* @throws IllegalArgumentException if the index resolution does not lead to an index, or leads to more than one index, as well as
* if a remote index is requested.
* @return the write index obtained as a result of the index resolution
*/
public Index concreteWriteIndex(ClusterState state, IndicesRequest request) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2441,6 +2441,118 @@ private ClusterState systemIndexTestClusterState() {
return ClusterState.builder(new ClusterName("_name")).metadata(mdBuilder).build();
}

public void testRemoteIndex() {
Metadata.Builder mdBuilder = Metadata.builder();
ClusterState state = ClusterState.builder(new ClusterName("_name")).metadata(mdBuilder).build();

{
IndicesOptions options = IndicesOptions.fromOptions(false, randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean());
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(
state, options, SystemIndexAccessLevel.NONE);
IllegalArgumentException iae = expectThrows(IllegalArgumentException.class,
() -> indexNameExpressionResolver.concreteIndexNames(context, "cluster:index", "local"));
assertEquals("Cross-cluster calls are not supported in this context but remote indices were requested: [cluster:index]",
iae.getMessage());
}
{
IndicesOptions options = IndicesOptions.fromOptions(false, randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean());
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(
state, options, SystemIndexAccessLevel.NONE);
IllegalArgumentException iae = expectThrows(IllegalArgumentException.class,
() -> indexNameExpressionResolver.concreteIndexNames(context, "cluster:*", "local"));
assertEquals("Cross-cluster calls are not supported in this context but remote indices were requested: [cluster:*]",
iae.getMessage());
}
{
IndicesOptions options = IndicesOptions.fromOptions(false, randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean());
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(
state, options, SystemIndexAccessLevel.NONE);
IllegalArgumentException iae = expectThrows(IllegalArgumentException.class,
() -> indexNameExpressionResolver.concreteIndexNames(context, "cluster:i*", "local"));
assertEquals("Cross-cluster calls are not supported in this context but remote indices were requested: [cluster:i*]",
iae.getMessage());
}
{
IndicesOptions options = IndicesOptions.fromOptions(true, true, randomBoolean(), randomBoolean(), randomBoolean());
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(
state, options, SystemIndexAccessLevel.NONE);
String[] indexNames = indexNameExpressionResolver.concreteIndexNames(context, "cluster:index", "local");
assertEquals(0, indexNames.length);
}
{
IndicesOptions options = IndicesOptions.fromOptions(true, true, randomBoolean(), randomBoolean(), randomBoolean());
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(
state, options, SystemIndexAccessLevel.NONE);
String[] indexNames = indexNameExpressionResolver.concreteIndexNames(context, "cluster:i*", "local");
assertEquals(0, indexNames.length);
}
}

public void testColonWithinIndexName() {
Settings settings = Settings.builder().build();
Metadata.Builder mdBuilder = Metadata.builder()
.put(indexBuilder("cluster:index", settings).state(State.OPEN));
ClusterState state = ClusterState.builder(new ClusterName("_name")).metadata(mdBuilder).build();

{
IndicesOptions options = IndicesOptions.fromOptions(randomBoolean(), randomBoolean(),
randomBoolean(), randomBoolean(), randomBoolean());
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(
state, options, SystemIndexAccessLevel.NONE);
String[] indexNames = indexNameExpressionResolver.concreteIndexNames(context, "cluster:index");
assertThat(indexNames, arrayContaining("cluster:index"));
}
//Using wildcards, expand wildcards to open indices: true -> index locally resolved
{
IndicesOptions options = IndicesOptions.fromOptions(randomBoolean(), randomBoolean(), true, randomBoolean(), randomBoolean());
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(
state, options, SystemIndexAccessLevel.NONE);
String[] indexNames = indexNameExpressionResolver.concreteIndexNames(context, "cluster:*");
assertThat(indexNames, arrayContaining("cluster:index"));
}
{
IndicesOptions options = IndicesOptions.fromOptions(randomBoolean(), randomBoolean(), true, randomBoolean(), randomBoolean());
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(
state, options, SystemIndexAccessLevel.NONE);
String[] indexNames = indexNameExpressionResolver.concreteIndexNames(context, "cluster:in*");
assertThat(indexNames, arrayContaining("cluster:index"));
}
//With wildcards, ignore_unavailable: false, expand wildcards to open indices: false -> error about cross cluster indices
{
IndicesOptions options = IndicesOptions.fromOptions(false, randomBoolean(), false, randomBoolean(), randomBoolean());
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(
state, options, SystemIndexAccessLevel.NONE);
IllegalArgumentException iae = expectThrows(IllegalArgumentException.class,
() -> indexNameExpressionResolver.concreteIndexNames(context, "cluster:*"));
assertEquals("Cross-cluster calls are not supported in this context but remote indices were requested: [cluster:*]",
iae.getMessage());
}
{
IndicesOptions options = IndicesOptions.fromOptions(false, randomBoolean(), false, randomBoolean(), randomBoolean());
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(
state, options, SystemIndexAccessLevel.NONE);
IllegalArgumentException iae = expectThrows(IllegalArgumentException.class,
() -> indexNameExpressionResolver.concreteIndexNames(context, "cluster:in*"));
assertEquals("Cross-cluster calls are not supported in this context but remote indices were requested: [cluster:in*]",
iae.getMessage());
}
//With wildcards: ignore_unavailable: true, allow_no_indices: true, expand wildcards to open indices: false -> empty list of indices
{
IndicesOptions options = IndicesOptions.fromOptions(true, true, false, randomBoolean(), randomBoolean());
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(
state, options, SystemIndexAccessLevel.NONE);
String[] indexNames = indexNameExpressionResolver.concreteIndexNames(context, "cluster:*");
assertEquals(0, indexNames.length);
}
{
IndicesOptions options = IndicesOptions.fromOptions(true, true, false, randomBoolean(), randomBoolean());
IndexNameExpressionResolver.Context context = new IndexNameExpressionResolver.Context(
state, options, SystemIndexAccessLevel.NONE);
String[] indexNames = indexNameExpressionResolver.concreteIndexNames(context, "cluster:in*");
assertEquals(0, indexNames.length);
}
}

private List<String> resolveConcreteIndexNameList(ClusterState state, SearchRequest request) {
return Arrays
.stream(indexNameExpressionResolver.concreteIndices(state, request))
Expand Down