Skip to content
Closed
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 @@ -49,6 +49,7 @@
import org.elasticsearch.indices.InvalidIndexNameException;
import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.search.crossproject.CrossProjectModeDecider;
import org.elasticsearch.search.crossproject.CrossProjectRoutingResolver;
import org.elasticsearch.search.crossproject.NoMatchingProjectException;
import org.elasticsearch.search.crossproject.TargetProjects;
import org.elasticsearch.threadpool.ThreadPool;
Expand Down Expand Up @@ -106,6 +107,7 @@
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;

import static org.elasticsearch.action.support.ContextPreservingActionListener.wrapPreservingContext;
Expand Down Expand Up @@ -504,12 +506,35 @@ private void authorizeAction(
final SubscribableListener<TargetProjects> targetProjectListener;
if (indicesAndAliasesResolver.resolvesCrossProject(request)) {
targetProjectListener = new SubscribableListener<>();
// Get list of projects from cluster state
// Remove projects from list that user lacks permissions to access
authorizedProjectsResolver.resolveAuthorizedProjects(targetProjectListener);

// project routing resolution could go here
// regardless of location, it would look something like...
targetProjectListener.andThenApply(targetProjects -> {
// we'd inject the CrossProjectRoutingResolver
// we somehow pipe project_routing through to here,
// perhaps setting it in the SearchRequest so we can access it via RequestInfo.getRequest()
var projectRoutingInfos = new CrossProjectRoutingResolver().resolve(
"*",
targetProjects.originProject(),
targetProjects.linkedProjects()
);
var originOrNull = projectRoutingInfos.stream().filter(targetProjects.originProject()::equals).findAny().orElse(null);
var linkedProjects = projectRoutingInfos.stream()
.filter(Predicate.not(targetProjects.originProject()::equals))
.toList();
// perhaps we change the CrossProjectRoutingResolver API to accept and return TargetProjects?
return new TargetProjects(originOrNull, linkedProjects);
});
} else {
targetProjectListener = SubscribableListener.newSucceeded(TargetProjects.LOCAL_ONLY_FOR_CPS_DISABLED);
}

targetProjectListener.addListener(ActionListener.wrap(targetProjects -> {
// this will eventually rewrite the index expression based on the targetProjects,
// so filtering by project_routing should go before here
final AsyncSupplier<ResolvedIndices> resolvedIndicesAsyncSupplier = makeResolvedIndicesAsyncSupplier(
targetProjects,
requestInfo,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,7 @@ ResolvedIndices resolveIndicesAndAliases(

Set<String> remoteIndices = Collections.emptySet();
if (crossProjectModeDecider.resolvesCrossProject(replaceable)) {
// project routing resolution could go here, before the index expression is generated
remoteIndices = CrossProjectIndexExpressionsRewriter.rewriteIndexExpression(
indexExpression,
authorizedProjects.originProjectAlias(),
Expand Down