Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
@@ -0,0 +1,89 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

package org.elasticsearch.xpack.esql.session;

import org.elasticsearch.common.Strings;
import org.elasticsearch.xpack.esql.action.AbstractCrossClusterTestCase;

import java.util.Map;
import java.util.Set;

import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.hasEntry;

public class ResolvedIndexExpressionIT extends AbstractCrossClusterTestCase {

public void testLocalIndices() {
createIndex(LOCAL_CLUSTER, "index-1");

assertThat(resolveIndices("index-1"), hasEntry(LOCAL_CLUSTER, resolvedIndexExpression("index-1", "index-1")));
}

public void testLocalAlias() {
createIndex(LOCAL_CLUSTER, "index-1");
createAlias(LOCAL_CLUSTER, "alias-1", "index-1");

assertThat(resolveIndices("alias-1"), hasEntry(LOCAL_CLUSTER, resolvedIndexExpression("alias-1", "index-1")));
}

public void testLocalPattern() {
createIndex(LOCAL_CLUSTER, "index-1");
createIndex(LOCAL_CLUSTER, "index-2");

assertThat(resolveIndices("index-*"), hasEntry(LOCAL_CLUSTER, resolvedIndexExpression("index-*", "index-1,index-2")));
}

public void testLocalMultiple() {
createIndex(LOCAL_CLUSTER, "index-1");
createIndex(LOCAL_CLUSTER, "index-2");

assertThat(
resolveIndices("index-1,index-2"),
hasEntry(LOCAL_CLUSTER, resolvedIndexExpression("index-1,index-2", "index-1,index-2"))
);
}

public void testLocalAndRemote() {
createIndex(LOCAL_CLUSTER, "index-1");
createIndex(REMOTE_CLUSTER_1, "index-2");
createIndex(REMOTE_CLUSTER_2, "index-3");

assertThat(
resolveIndices("index-*,*:index-*"),
allOf(
hasEntry(LOCAL_CLUSTER, resolvedIndexExpression("index-*", "index-1")),
hasEntry(REMOTE_CLUSTER_1, resolvedIndexExpression("index-*", "index-2")),
hasEntry(REMOTE_CLUSTER_2, resolvedIndexExpression("index-*", "index-3"))
)
);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we do not support exclusions yet


private Map<String, ResolvedIndexExpression> resolveIndices(String indices) {
return ResolvedIndexExpression.from(
client(LOCAL_CLUSTER).prepareFieldCaps(Strings.splitStringByCommaToArray(indices))
.setFields("*")
.setIncludeResolvedTo(true)
.get()
);
}

private void createIndex(String clusterAlias, String index) {
client(clusterAlias).admin().indices().prepareCreate(index).get();
}

private void createAlias(String clusterAlias, String alias, String index) {
client(clusterAlias).admin().indices().prepareAliases(TEST_REQUEST_TIMEOUT, TEST_REQUEST_TIMEOUT).addAlias(index, alias).get();
}

private static ResolvedIndexExpression resolvedIndexExpression(String expression, String resolved) {
return new ResolvedIndexExpression(
Set.of(Strings.splitStringByCommaToArray(expression)),
Set.of(Strings.splitStringByCommaToArray(resolved))
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

package org.elasticsearch.xpack.esql.session;

import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse;
import org.elasticsearch.common.util.set.Sets;
import org.elasticsearch.transport.RemoteClusterAware;

import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toMap;

public record ResolvedIndexExpression(Set<String> expression, Set<String> resolved) {

private static final ResolvedIndexExpression EMPTY = new ResolvedIndexExpression(Set.of(), Set.of());

public static Map<String, ResolvedIndexExpression> from(FieldCapabilitiesResponse response) {
return Stream.concat(
Stream.of(Map.entry(RemoteClusterAware.LOCAL_CLUSTER_GROUP_KEY, response.getResolvedLocally())),
response.getResolvedRemotely().entrySet().stream()
).map(entry -> Map.entry(
entry.getKey(),
entry.getValue().expressions()
.stream()
.filter(e -> e.localExpressions().indices().isEmpty() == false)
.map(e -> new ResolvedIndexExpression(Set.of(e.original()), e.localExpressions().indices()))
.reduce(EMPTY, ResolvedIndexExpression::merge)
)).collect(toMap(Map.Entry::getKey, Map.Entry::getValue));
}

private static ResolvedIndexExpression merge(ResolvedIndexExpression a, ResolvedIndexExpression b) {
return new ResolvedIndexExpression(Sets.union(a.expression(), b.expression()), Sets.union(a.resolved(), b.resolved()));
}
}