Introduce projectClient method on Client (#129174)

We originally defined the `projectClient` method on `ProjectResolver` as
a convenience method to execute API calls for specific projects. That
method requires a reference to both a `ProjectResolver` and a `Client`.

We now introduce the same method directly on the `Client` interface and
inject a `ProjectResolver` there, removing the need for a
`ProjectResolver` reference in places that just want to execute API
requests on a specific project.

To reduce the number of changes, this change solely focuses on
introducing the new method. Future changes will migrate the uses of the
original method to the new one and remove the original altogether.
This commit is contained in:
Niels Bauman 2025-06-12 15:19:16 -03:00 committed by GitHub
parent 80aa17ee11
commit 87c6fa7e9b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
44 changed files with 156 additions and 60 deletions

View file

@ -16,6 +16,7 @@ import org.elasticsearch.action.ActionType;
import org.elasticsearch.client.internal.Client;
import org.elasticsearch.client.internal.support.AbstractClient;
import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.cluster.project.TestProjectResolvers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment;
import org.elasticsearch.env.TestEnvironment;
@ -96,7 +97,7 @@ public class PredicateTokenScriptFilterTests extends ESTokenStreamTestCase {
private static class MockClient extends AbstractClient {
MockClient(Settings settings, ThreadPool threadPool) {
super(settings, threadPool);
super(settings, threadPool, TestProjectResolvers.alwaysThrow());
}
@Override

View file

@ -16,6 +16,7 @@ import org.elasticsearch.action.ActionType;
import org.elasticsearch.client.internal.Client;
import org.elasticsearch.client.internal.support.AbstractClient;
import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.cluster.project.TestProjectResolvers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment;
import org.elasticsearch.env.TestEnvironment;
@ -96,7 +97,7 @@ public class ScriptedConditionTokenFilterTests extends ESTokenStreamTestCase {
private class MockClient extends AbstractClient {
MockClient(Settings settings, ThreadPool threadPool) {
super(settings, threadPool);
super(settings, threadPool, TestProjectResolvers.alwaysThrow());
}
@Override

View file

@ -16,6 +16,7 @@ import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.client.internal.node.NodeClient;
import org.elasticsearch.cluster.project.TestProjectResolvers;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment;
@ -68,7 +69,7 @@ public final class TransportRankEvalActionTests extends ESTestCase {
);
rankEvalRequest.indicesOptions(expectedIndicesOptions);
NodeClient client = new NodeClient(settings, null) {
NodeClient client = new NodeClient(settings, null, TestProjectResolvers.alwaysThrow()) {
@Override
public void multiSearch(MultiSearchRequest request, ActionListener<MultiSearchResponse> listener) {
assertEquals(1, request.requests().size());

View file

@ -21,6 +21,7 @@ import org.elasticsearch.action.search.TransportSearchAction;
import org.elasticsearch.action.search.TransportSearchScrollAction;
import org.elasticsearch.client.internal.ParentTaskAssigningClient;
import org.elasticsearch.client.internal.support.AbstractClient;
import org.elasticsearch.cluster.project.TestProjectResolvers;
import org.elasticsearch.common.BackoffPolicy;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.settings.Settings;
@ -214,7 +215,7 @@ public class ClientScrollableHitSourceTests extends ESTestCase {
private ExecuteRequest<?, ?> executeRequest;
MockClient(ThreadPool threadPool) {
super(Settings.EMPTY, threadPool);
super(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow());
}
@Override

View file

@ -52,6 +52,8 @@ import org.elasticsearch.action.termvectors.TermVectorsResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateRequestBuilder;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.cluster.metadata.ProjectId;
import org.elasticsearch.cluster.project.ProjectResolver;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.transport.RemoteClusterService;
@ -399,6 +401,16 @@ public interface Client extends ElasticsearchClient {
*/
Client filterWithHeader(Map<String, String> headers);
/**
* Returns a client that executes every request in the context of the given project.
*/
Client projectClient(ProjectId projectId);
/**
* Returns this client's project resolver.
*/
ProjectResolver projectResolver();
/**
* Returns a client to a remote cluster with the given cluster alias.
*

View file

@ -13,6 +13,7 @@ import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.action.ActionType;
import org.elasticsearch.client.internal.support.AbstractClient;
import org.elasticsearch.cluster.project.ProjectResolver;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.RemoteClusterService;
@ -35,15 +36,15 @@ public abstract class FilterClient extends AbstractClient {
* @see #in()
*/
public FilterClient(Client in) {
this(in.settings(), in.threadPool(), in);
this(in.settings(), in.threadPool(), in.projectResolver(), in);
}
/**
* A Constructor that allows to pass settings and threadpool separately. This is useful if the
* client is a proxy and not yet fully constructed ie. both dependencies are not available yet.
*/
protected FilterClient(Settings settings, ThreadPool threadPool, Client in) {
super(settings, threadPool);
protected FilterClient(Settings settings, ThreadPool threadPool, ProjectResolver projectResolver, Client in) {
super(settings, threadPool, projectResolver);
this.in = in;
}

View file

@ -18,6 +18,7 @@ import org.elasticsearch.client.internal.Client;
import org.elasticsearch.client.internal.RemoteClusterClient;
import org.elasticsearch.client.internal.support.AbstractClient;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.project.ProjectResolver;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.tasks.Task;
import org.elasticsearch.tasks.TaskCancelledException;
@ -48,8 +49,8 @@ public class NodeClient extends AbstractClient {
private Transport.Connection localConnection;
private RemoteClusterService remoteClusterService;
public NodeClient(Settings settings, ThreadPool threadPool) {
super(settings, threadPool);
public NodeClient(Settings settings, ThreadPool threadPool, ProjectResolver projectResolver) {
super(settings, threadPool, projectResolver);
}
public void initialize(

View file

@ -76,6 +76,8 @@ import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.internal.AdminClient;
import org.elasticsearch.client.internal.Client;
import org.elasticsearch.client.internal.FilterClient;
import org.elasticsearch.cluster.metadata.ProjectId;
import org.elasticsearch.cluster.project.ProjectResolver;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.core.Nullable;
@ -92,12 +94,14 @@ public abstract class AbstractClient implements Client {
protected final Settings settings;
private final ThreadPool threadPool;
private final ProjectResolver projectResolver;
private final AdminClient admin;
@SuppressWarnings("this-escape")
public AbstractClient(Settings settings, ThreadPool threadPool) {
public AbstractClient(Settings settings, ThreadPool threadPool, ProjectResolver projectResolver) {
this.settings = settings;
this.threadPool = threadPool;
this.projectResolver = projectResolver;
this.admin = new AdminClient(this);
this.logger = LogManager.getLogger(this.getClass());
}
@ -112,6 +116,11 @@ public abstract class AbstractClient implements Client {
return this.threadPool;
}
@Override
public ProjectResolver projectResolver() {
return projectResolver;
}
@Override
public final AdminClient admin() {
return admin;
@ -407,6 +416,32 @@ public abstract class AbstractClient implements Client {
};
}
@Override
public Client projectClient(ProjectId projectId) {
// We only take the shortcut when the given project ID matches the "current" project ID. If it doesn't, we'll let #executeOnProject
// take care of error handling.
if (projectResolver.supportsMultipleProjects() == false && projectId.equals(projectResolver.getProjectId())) {
return this;
}
return new FilterClient(this) {
@Override
protected <Request extends ActionRequest, Response extends ActionResponse> void doExecute(
ActionType<Response> action,
Request request,
ActionListener<Response> listener
) {
projectResolver.executeOnProject(projectId, () -> super.doExecute(action, request, listener));
}
@Override
public Client projectClient(ProjectId projectId) {
throw new IllegalStateException(
"Unable to create a project client for project [" + projectId + "], nested project client creation is not supported"
);
}
};
}
/**
* Same as {@link PlainActionFuture} but for use with {@link RefCounted} result types. Unlike {@code PlainActionFuture} this future
* acquires a reference to its result. This means that the result reference must be released by a call to {@link RefCounted#decRef()}

View file

@ -287,9 +287,15 @@ class NodeConstruction {
// places they shouldn't. Best to explicitly drop them now to protect against such leakage.
settingsModule = constructor.validateSettings(initialEnvironment.settings(), settings, threadPool);
}
// serverless deployments plug-in the multi-project resolver factory
ProjectResolver projectResolver = constructor.pluginsService.loadSingletonServiceProvider(
ProjectResolverFactory.class,
() -> ProjectResolverFactory.DEFAULT
).create();
constructor.modules.bindToInstance(ProjectResolver.class, projectResolver);
SearchModule searchModule = constructor.createSearchModule(settingsModule.getSettings(), threadPool, telemetryProvider);
constructor.createClientAndRegistries(settingsModule.getSettings(), threadPool, searchModule);
constructor.createClientAndRegistries(settingsModule.getSettings(), threadPool, searchModule, projectResolver);
DocumentParsingProvider documentParsingProvider = constructor.getDocumentParsingProvider();
ScriptService scriptService = constructor.createScriptService(settingsModule, threadPool, serviceProvider);
@ -305,7 +311,8 @@ class NodeConstruction {
serviceProvider,
forbidPrivateIndexSettings,
telemetryProvider,
documentParsingProvider
documentParsingProvider,
projectResolver
);
return constructor;
@ -562,8 +569,13 @@ class NodeConstruction {
/**
* Create various objects that are stored as member variables. This is so they are accessible as soon as possible.
*/
private void createClientAndRegistries(Settings settings, ThreadPool threadPool, SearchModule searchModule) {
client = new NodeClient(settings, threadPool);
private void createClientAndRegistries(
Settings settings,
ThreadPool threadPool,
SearchModule searchModule,
ProjectResolver projectResolver
) {
client = new NodeClient(settings, threadPool, projectResolver);
modules.add(b -> {
b.bind(Client.class).toInstance(client);
b.bind(NodeClient.class).toInstance(client);
@ -664,7 +676,8 @@ class NodeConstruction {
NodeServiceProvider serviceProvider,
boolean forbidPrivateIndexSettings,
TelemetryProvider telemetryProvider,
DocumentParsingProvider documentParsingProvider
DocumentParsingProvider documentParsingProvider,
ProjectResolver projectResolver
) throws IOException {
Settings settings = settingsModule.getSettings();
@ -681,12 +694,6 @@ class NodeConstruction {
telemetryProvider.getTracer()
);
// serverless deployments plug-in the multi-project resolver factory
ProjectResolver projectResolver = pluginsService.loadSingletonServiceProvider(
ProjectResolverFactory.class,
() -> ProjectResolverFactory.DEFAULT
).create();
modules.bindToInstance(ProjectResolver.class, projectResolver);
ClusterService clusterService = createClusterService(settingsModule, threadPool, taskManager);
clusterService.addStateApplier(scriptService);

View file

@ -73,7 +73,7 @@ public class TransportGetTaskActionTests extends ESTestCase {
var transportService = mock(TransportService.class);
var clusterService = mock(ClusterService.class);
var nodeId = "node1";
NodeClient client = new NodeClient(Settings.EMPTY, threadPool) {
NodeClient client = new NodeClient(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow()) {
@Override
@SuppressWarnings("unchecked")
public <Request extends ActionRequest, Response extends ActionResponse> void doExecute(

View file

@ -26,6 +26,7 @@ import org.elasticsearch.client.internal.support.AbstractClient;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.node.DiscoveryNodeUtils;
import org.elasticsearch.cluster.project.TestProjectResolvers;
import org.elasticsearch.cluster.version.CompatibilityVersions;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.BoundTransportAddress;
@ -109,7 +110,7 @@ public class RemoteClusterNodesActionTests extends ESTestCase {
final RemoteClusterNodesAction.TransportAction action = new RemoteClusterNodesAction.TransportAction(
mock(TransportService.class),
new ActionFilters(Set.of()),
new AbstractClient(Settings.EMPTY, threadPool) {
new AbstractClient(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow()) {
@SuppressWarnings("unchecked")
@Override
protected <Request extends ActionRequest, Response extends ActionResponse> void doExecute(
@ -187,7 +188,7 @@ public class RemoteClusterNodesActionTests extends ESTestCase {
final RemoteClusterNodesAction.TransportAction action = new RemoteClusterNodesAction.TransportAction(
mock(TransportService.class),
new ActionFilters(Set.of()),
new AbstractClient(Settings.EMPTY, threadPool) {
new AbstractClient(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow()) {
@SuppressWarnings("unchecked")
@Override
protected <Request extends ActionRequest, Response extends ActionResponse> void doExecute(

View file

@ -16,6 +16,7 @@ import org.elasticsearch.client.internal.node.NodeClient;
import org.elasticsearch.cluster.SnapshotsInProgress;
import org.elasticsearch.cluster.metadata.ProjectId;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.project.TestProjectResolvers;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.unit.ByteSizeValue;
@ -65,7 +66,7 @@ public class TransportSnapshotsStatusActionTests extends ESTestCase {
clusterService.getClusterSettings(),
Set.of()
);
final var nodeClient = new NodeClient(clusterService.getSettings(), threadPool);
final var nodeClient = new NodeClient(clusterService.getSettings(), threadPool, TestProjectResolvers.alwaysThrow());
repositoriesService = new RepositoriesService(
clusterService.getSettings(),
clusterService,

View file

@ -160,7 +160,7 @@ public class TransportBulkActionIngestTests extends ESTestCase {
transportService,
TransportBulkActionIngestTests.this.clusterService,
ingestService,
new NodeClient(Settings.EMPTY, TransportBulkActionIngestTests.this.threadPool),
new NodeClient(Settings.EMPTY, TransportBulkActionIngestTests.this.threadPool, TestProjectResolvers.alwaysThrow()),
new ActionFilters(Collections.emptySet()),
TestIndexNameExpressionResolver.newInstance(),
new IndexingPressure(SETTINGS),

View file

@ -43,6 +43,7 @@ import org.elasticsearch.cluster.metadata.Template;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.node.DiscoveryNodeUtils;
import org.elasticsearch.cluster.project.ProjectResolver;
import org.elasticsearch.cluster.project.TestProjectResolvers;
import org.elasticsearch.cluster.routing.GlobalRoutingTableTestHelper;
import org.elasticsearch.cluster.routing.RoutingTable;
import org.elasticsearch.cluster.service.ClusterService;
@ -121,7 +122,7 @@ public class TransportBulkActionTests extends ESTestCase {
transportService,
TransportBulkActionTests.this.clusterService,
null,
new NodeClient(Settings.EMPTY, TransportBulkActionTests.this.threadPool),
new NodeClient(Settings.EMPTY, TransportBulkActionTests.this.threadPool, TestProjectResolvers.alwaysThrow()),
new ActionFilters(Collections.emptySet()),
new Resolver(),
new IndexingPressure(Settings.EMPTY),

View file

@ -117,7 +117,7 @@ public class TransportBulkActionTookTests extends ESTestCase {
IndexNameExpressionResolver resolver = new Resolver();
ActionFilters actionFilters = new ActionFilters(new HashSet<>());
NodeClient client = new NodeClient(Settings.EMPTY, threadPool) {
NodeClient client = new NodeClient(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow()) {
@Override
@SuppressWarnings("unchecked")
public <Request extends ActionRequest, Response extends ActionResponse> void doExecute(

View file

@ -185,7 +185,7 @@ public class TransportMultiGetActionTests extends ESTestCase {
public void testTransportMultiGetAction() {
final Task task = createTask();
final NodeClient client = new NodeClient(Settings.EMPTY, threadPool);
final NodeClient client = new NodeClient(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow());
final MultiGetRequestBuilder request = new MultiGetRequestBuilder(client);
request.add(new MultiGetRequest.Item("index1", "1"));
request.add(new MultiGetRequest.Item("index1", "2"));
@ -219,7 +219,7 @@ public class TransportMultiGetActionTests extends ESTestCase {
public void testTransportMultiGetAction_withMissingRouting() {
final Task task = createTask();
final NodeClient client = new NodeClient(Settings.EMPTY, threadPool);
final NodeClient client = new NodeClient(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow());
final MultiGetRequestBuilder request = new MultiGetRequestBuilder(client);
request.add(new MultiGetRequest.Item("index2", "1").routing("1"));
request.add(new MultiGetRequest.Item("index2", "2"));

View file

@ -15,6 +15,7 @@ import org.elasticsearch.client.internal.node.NodeClient;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.node.DiscoveryNodeUtils;
import org.elasticsearch.cluster.project.TestProjectResolvers;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.UUIDs;
import org.elasticsearch.common.settings.Settings;
@ -137,7 +138,7 @@ public class MultiSearchActionTookTests extends ESTestCase {
final Executor commonExecutor = randomExecutor(threadPool);
final Set<SearchRequest> requests = Collections.newSetFromMap(Collections.synchronizedMap(new IdentityHashMap<>()));
NodeClient client = new NodeClient(settings, threadPool) {
NodeClient client = new NodeClient(settings, threadPool, TestProjectResolvers.alwaysThrow()) {
@Override
public void search(final SearchRequest request, final ActionListener<SearchResponse> listener) {
requests.add(request);

View file

@ -20,6 +20,7 @@ import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.node.DiscoveryNodeRole;
import org.elasticsearch.cluster.node.DiscoveryNodeUtils;
import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.cluster.project.TestProjectResolvers;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.Randomness;
import org.elasticsearch.common.UUIDs;
@ -81,7 +82,7 @@ public class TransportMultiSearchActionTests extends ESTestCase {
}
AtomicInteger counter = new AtomicInteger(0);
Task task = multiSearchRequest.createTask(randomLong(), "type", "action", null, Collections.emptyMap());
NodeClient client = new NodeClient(settings, threadPool) {
NodeClient client = new NodeClient(settings, threadPool, TestProjectResolvers.alwaysThrow()) {
@Override
public void search(final SearchRequest request, final ActionListener<SearchResponse> listener) {
assertEquals(task.getId(), request.getParentTask().getId());
@ -150,7 +151,7 @@ public class TransportMultiSearchActionTests extends ESTestCase {
final Executor commonExecutor = executorServices.get(0);
final Executor rarelyExecutor = executorServices.get(1);
final Set<SearchRequest> requests = Collections.newSetFromMap(Collections.synchronizedMap(new IdentityHashMap<>()));
NodeClient client = new NodeClient(settings, threadPool) {
NodeClient client = new NodeClient(settings, threadPool, TestProjectResolvers.alwaysThrow()) {
@Override
public void search(final SearchRequest request, final ActionListener<SearchResponse> listener) {
requests.add(request);

View file

@ -1754,7 +1754,7 @@ public class TransportSearchActionTests extends ESTestCase {
throw new IllegalArgumentException("Not serializable to " + transportVersion);
}
}));
NodeClient client = new NodeClient(settings, threadPool);
NodeClient client = new NodeClient(settings, threadPool, TestProjectResolvers.alwaysThrow());
SearchService searchService = mock(SearchService.class);
when(searchService.getRewriteContext(any(), any(), any(), anyBoolean())).thenReturn(

View file

@ -182,7 +182,7 @@ public class TransportMultiTermVectorsActionTests extends ESTestCase {
public void testTransportMultiGetAction() {
final Task task = createTask();
final NodeClient client = new NodeClient(Settings.EMPTY, threadPool);
final NodeClient client = new NodeClient(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow());
final MultiTermVectorsRequestBuilder request = new MultiTermVectorsRequestBuilder(client);
request.add(new TermVectorsRequest("index1", "1"));
request.add(new TermVectorsRequest("index2", "2"));
@ -215,7 +215,7 @@ public class TransportMultiTermVectorsActionTests extends ESTestCase {
public void testTransportMultiGetAction_withMissingRouting() {
final Task task = createTask();
final NodeClient client = new NodeClient(Settings.EMPTY, threadPool);
final NodeClient client = new NodeClient(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow());
final MultiTermVectorsRequestBuilder request = new MultiTermVectorsRequestBuilder(client);
request.add(new TermVectorsRequest("index2", "1").routing("1"));
request.add(new TermVectorsRequest("index2", "2"));

View file

@ -17,6 +17,7 @@ import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.TransportAction;
import org.elasticsearch.client.internal.AbstractClientHeadersTestCase;
import org.elasticsearch.client.internal.Client;
import org.elasticsearch.cluster.project.TestProjectResolvers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.EsExecutors;
import org.elasticsearch.tasks.Task;
@ -41,7 +42,7 @@ public class NodeClientHeadersTests extends AbstractClientHeadersTestCase {
TaskManager taskManager = new TaskManager(settings, threadPool, Collections.emptySet());
Map<ActionType<?>, TransportAction<?, ?>> actions = Stream.of(testedActions)
.collect(Collectors.toMap(Function.identity(), a -> new InternalTransportAction(a.name(), taskManager)));
NodeClient client = new NodeClient(settings, threadPool);
NodeClient client = new NodeClient(settings, threadPool, TestProjectResolvers.alwaysThrow());
client.initialize(actions, taskManager, () -> "test", mock(Transport.Connection.class), null);
return client;
}

View file

@ -263,7 +263,7 @@ public class ClusterStateChanges {
return indexMetadata;
}
};
NodeClient client = new NodeClient(Settings.EMPTY, threadPool);
NodeClient client = new NodeClient(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow());
Map<ActionType<?>, TransportAction<?, ?>> actions = new HashMap<>();
actions.put(
TransportVerifyShardBeforeCloseAction.TYPE,

View file

@ -28,6 +28,7 @@ import org.elasticsearch.cluster.metadata.RepositoryMetadata;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.node.DiscoveryNodeRole;
import org.elasticsearch.cluster.node.DiscoveryNodeUtils;
import org.elasticsearch.cluster.project.TestProjectResolvers;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.UUIDs;
@ -95,7 +96,7 @@ public class RepositoriesServiceTests extends ESTestCase {
clusterService = ClusterServiceUtils.createClusterService(threadPool);
DiscoveryNode localNode = DiscoveryNodeUtils.builder("local").name("local").roles(Set.of(DiscoveryNodeRole.MASTER_ROLE)).build();
NodeClient client = new NodeClient(Settings.EMPTY, threadPool);
NodeClient client = new NodeClient(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow());
var actionFilters = new ActionFilters(Set.of());
client.initialize(
Map.of(

View file

@ -10,6 +10,7 @@
package org.elasticsearch.rest;
import org.elasticsearch.client.internal.node.NodeClient;
import org.elasticsearch.cluster.project.TestProjectResolvers;
import org.elasticsearch.common.Table;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.settings.Settings;
@ -40,7 +41,7 @@ public class BaseRestHandlerTests extends ESTestCase {
public void setUp() throws Exception {
super.setUp();
threadPool = new TestThreadPool(this.getClass().getSimpleName() + "ThreadPool");
mockClient = new NodeClient(Settings.EMPTY, threadPool);
mockClient = new NodeClient(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow());
}
@Override

View file

@ -21,6 +21,7 @@ import org.elasticsearch.action.search.TransportSearchAction;
import org.elasticsearch.action.support.PlainActionFuture;
import org.elasticsearch.action.support.SubscribableListener;
import org.elasticsearch.client.internal.node.NodeClient;
import org.elasticsearch.cluster.project.TestProjectResolvers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.set.Sets;
import org.elasticsearch.http.HttpChannel;
@ -193,7 +194,7 @@ public class RestCancellableNodeClientTests extends ESTestCase {
private final boolean timeout;
TestClient(Settings settings, ThreadPool threadPool, boolean timeout) {
super(settings, threadPool);
super(settings, threadPool, TestProjectResolvers.mustExecuteFirst());
this.timeout = timeout;
}

View file

@ -16,6 +16,7 @@ import org.elasticsearch.action.admin.indices.validate.query.ValidateQueryAction
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.TransportAction;
import org.elasticsearch.client.internal.node.NodeClient;
import org.elasticsearch.cluster.project.TestProjectResolvers;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.EsExecutors;
@ -48,7 +49,7 @@ import static org.mockito.Mockito.mock;
public class RestValidateQueryActionTests extends AbstractSearchTestCase {
private ThreadPool threadPool = new TestThreadPool(RestValidateQueryActionTests.class.getName());
private NodeClient client = new NodeClient(Settings.EMPTY, threadPool);
private NodeClient client = new NodeClient(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow());
private UsageService usageService = new UsageService();
private RestController controller = new RestController(

View file

@ -2303,7 +2303,7 @@ public class SnapshotResiliencyTests extends ESTestCase {
threadPool = deterministicTaskQueue.getThreadPool(runnable -> DeterministicTaskQueue.onNodeLog(node, runnable));
masterService = new FakeThreadPoolMasterService(node.getName(), threadPool, deterministicTaskQueue::scheduleNow);
final Settings settings = environment.settings();
client = new NodeClient(settings, threadPool);
client = new NodeClient(settings, threadPool, TestProjectResolvers.alwaysThrow());
this.usageService = new UsageService();
final ClusterSettings clusterSettings = new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS);
clusterService = new ClusterService(

View file

@ -38,6 +38,7 @@ import org.elasticsearch.cluster.metadata.Metadata;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.node.DiscoveryNodeRole;
import org.elasticsearch.cluster.node.DiscoveryNodeUtils;
import org.elasticsearch.cluster.project.TestProjectResolvers;
import org.elasticsearch.cluster.routing.BatchedRerouteService;
import org.elasticsearch.cluster.routing.allocation.AllocationService;
import org.elasticsearch.cluster.service.ClusterApplierService;
@ -1140,7 +1141,7 @@ public class AbstractCoordinatorTestCase extends ESTestCase {
(dn, cs) -> extraJoinValidators.forEach(validator -> validator.accept(dn, cs))
);
final AllocationService allocationService = ESAllocationTestCase.createAllocationService(Settings.EMPTY);
final NodeClient client = new NodeClient(Settings.EMPTY, threadPool);
final NodeClient client = new NodeClient(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow());
final var coordinationServices = coordinatorStrategy.getCoordinationServices(
threadPool,
settings,

View file

@ -14,6 +14,7 @@ import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.action.ActionType;
import org.elasticsearch.client.internal.support.AbstractClient;
import org.elasticsearch.cluster.project.TestProjectResolvers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.threadpool.ThreadPool;
@ -26,7 +27,7 @@ import org.elasticsearch.threadpool.ThreadPool;
public class NoOpClient extends AbstractClient {
public NoOpClient(ThreadPool threadPool) {
super(Settings.EMPTY, threadPool);
super(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow());
}
@Override

View file

@ -16,6 +16,7 @@ import org.elasticsearch.action.ActionType;
import org.elasticsearch.action.support.TransportAction;
import org.elasticsearch.client.internal.RemoteClusterClient;
import org.elasticsearch.client.internal.node.NodeClient;
import org.elasticsearch.cluster.project.TestProjectResolvers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.tasks.Task;
import org.elasticsearch.tasks.TaskManager;
@ -39,7 +40,7 @@ public class NoOpNodeClient extends NodeClient {
private final AtomicLong executionCount = new AtomicLong(0);
public NoOpNodeClient(ThreadPool threadPool) {
super(Settings.EMPTY, threadPool);
super(Settings.EMPTY, threadPool, TestProjectResolvers.mustExecuteFirst());
}
@Override

View file

@ -33,7 +33,7 @@ public class LifecyclePolicySecurityClient extends AbstractClient {
private final String origin;
public LifecyclePolicySecurityClient(Client client, String origin, Map<String, String> headers) {
super(client.settings(), client.threadPool());
super(client.settings(), client.threadPool(), client.projectResolver());
this.client = client;
this.origin = origin;
this.headers = headers;

View file

@ -13,6 +13,7 @@ import org.elasticsearch.action.ActionType;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.TransportAction;
import org.elasticsearch.client.internal.node.NodeClient;
import org.elasticsearch.cluster.project.TestProjectResolvers;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.EsExecutors;
@ -48,7 +49,7 @@ import static org.mockito.Mockito.mock;
public class RestTermsEnumActionTests extends ESTestCase {
private static ThreadPool threadPool = new TestThreadPool(RestTermsEnumActionTests.class.getName());
private static NodeClient client = new NodeClient(Settings.EMPTY, threadPool);
private static NodeClient client = new NodeClient(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow());
private static UsageService usageService = new UsageService();
private static RestController controller = new RestController(

View file

@ -114,6 +114,7 @@ public class CancellationTests extends ESTestCase {
countDownLatch.await();
verify(client, times(1)).settings();
verify(client, times(1)).threadPool();
verify(client, times(1)).projectResolver();
verifyNoMoreInteractions(client);
}
@ -175,6 +176,7 @@ public class CancellationTests extends ESTestCase {
verify(client).fieldCaps(any(), any());
verify(client, times(1)).settings();
verify(client, times(1)).threadPool();
verify(client, times(1)).projectResolver();
verifyNoMoreInteractions(client);
}
@ -244,6 +246,7 @@ public class CancellationTests extends ESTestCase {
verify(client).execute(any(), any(), any());
verify(client, times(1)).settings();
verify(client, times(1)).threadPool();
verify(client, times(1)).projectResolver();
verifyNoMoreInteractions(client);
}

View file

@ -160,6 +160,7 @@ public class MlAnomaliesIndexUpdateTests extends ESTestCase {
// everything up to date so no action for the client
verify(client).settings();
verify(client).threadPool();
verify(client).projectResolver();
verifyNoMoreInteractions(client);
}
@ -179,6 +180,7 @@ public class MlAnomaliesIndexUpdateTests extends ESTestCase {
updater.runUpdate(csBuilder.build());
verify(client).settings();
verify(client, times(7)).threadPool();
verify(client).projectResolver();
verify(client, times(2)).execute(same(TransportIndicesAliasesAction.TYPE), any(), any()); // create rollover alias and update
verify(client).execute(same(RolloverAction.INSTANCE), any(), any()); // index rolled over
verifyNoMoreInteractions(client);

View file

@ -151,6 +151,7 @@ public class MlIndexRolloverTests extends ESTestCase {
rollover.runUpdate(csBuilder.build());
verify(client).settings();
verify(client).threadPool();
verify(client).projectResolver();
verifyNoMoreInteractions(client);
}
@ -183,6 +184,7 @@ public class MlIndexRolloverTests extends ESTestCase {
// everything up to date so no action for the client
verify(client).settings();
verify(client).threadPool();
verify(client).projectResolver();
verifyNoMoreInteractions(client);
}
@ -214,6 +216,7 @@ public class MlIndexRolloverTests extends ESTestCase {
rollover.runUpdate(csBuilder.build());
verify(client).settings();
verify(client, times(3)).threadPool();
verify(client).projectResolver();
verify(client).execute(same(RolloverAction.INSTANCE), any(), any()); // index rolled over
verifyNoMoreInteractions(client);
}
@ -246,6 +249,7 @@ public class MlIndexRolloverTests extends ESTestCase {
rollover.runUpdate(csBuilder.build());
verify(client).settings();
verify(client, times(5)).threadPool();
verify(client).projectResolver();
verify(client).execute(same(TransportIndicesAliasesAction.TYPE), any(), any()); // alias created
verify(client).execute(same(RolloverAction.INSTANCE), any(), any()); // index rolled over
verifyNoMoreInteractions(client);

View file

@ -318,6 +318,7 @@ public class DataFrameAnalyticsTaskTests extends ESTestCase {
verify(analyticsManager).isNodeShuttingDown();
verify(client, atLeastOnce()).settings();
verify(client, atLeastOnce()).threadPool();
verify(client, atLeastOnce()).projectResolver();
if (nodeShuttingDown == false) {
// Verify progress was persisted

View file

@ -234,6 +234,7 @@ public class JobResultsPersisterTests extends ESTestCase {
InOrder inOrder = inOrder(client);
inOrder.verify(client).settings();
inOrder.verify(client, times(3)).threadPool();
verify(client).projectResolver();
inOrder.verify(client).execute(eq(TransportBulkAction.TYPE), bulkRequestCaptor.capture(), any());
verifyNoMoreInteractions(client);
}
@ -253,6 +254,7 @@ public class JobResultsPersisterTests extends ESTestCase {
InOrder inOrder = inOrder(client);
inOrder.verify(client).settings();
inOrder.verify(client, times(3)).threadPool();
verify(client).projectResolver();
inOrder.verify(client).execute(eq(TransportBulkAction.TYPE), bulkRequestCaptor.capture(), any());
verifyNoMoreInteractions(client);
@ -303,6 +305,7 @@ public class JobResultsPersisterTests extends ESTestCase {
InOrder inOrder = inOrder(client);
inOrder.verify(client).settings();
inOrder.verify(client, times(3)).threadPool();
verify(client).projectResolver();
inOrder.verify(client).execute(eq(TransportBulkAction.TYPE), bulkRequestCaptor.capture(), any());
verifyNoMoreInteractions(client);

View file

@ -68,6 +68,7 @@ public class EmptyStateIndexRemoverTests extends ESTestCase {
public void verifyNoOtherInteractionsWithMocks() {
verify(client).settings();
verify(client, atLeastOnce()).threadPool();
verify(client).projectResolver();
verify(listener, Mockito.atLeast(0)).delegateFailureAndWrap(any());
verifyNoMoreInteractions(client, listener);
}

View file

@ -14,6 +14,7 @@ import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.action.ActionType;
import org.elasticsearch.client.internal.node.NodeClient;
import org.elasticsearch.cluster.project.TestProjectResolvers;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.settings.SecureString;
import org.elasticsearch.common.settings.Settings;
@ -89,7 +90,7 @@ public class RestCreateApiKeyActionTests extends ESTestCase {
Instant.now().plus(Duration.ofHours(5))
);
final var client = new NodeClient(Settings.EMPTY, threadPool) {
final var client = new NodeClient(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow()) {
@Override
public <Request extends ActionRequest, Response extends ActionResponse> void doExecute(
ActionType<Response> action,

View file

@ -15,6 +15,7 @@ import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.action.ActionType;
import org.elasticsearch.client.internal.node.NodeClient;
import org.elasticsearch.cluster.project.TestProjectResolvers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment;
import org.elasticsearch.license.XPackLicenseState;
@ -101,7 +102,7 @@ public class RestGetApiKeyActionTests extends ESTestCase {
final ApiKey apiKey = randomApiKeyInfo(withLimitedBy);
final GetApiKeyResponse getApiKeyResponseExpected = new GetApiKeyResponse(List.of(apiKey), profileUids);
final var client = new NodeClient(Settings.EMPTY, threadPool) {
final var client = new NodeClient(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow()) {
@SuppressWarnings("unchecked")
@Override
public <Request extends ActionRequest, Response extends ActionResponse> void doExecute(
@ -167,7 +168,7 @@ public class RestGetApiKeyActionTests extends ESTestCase {
};
final ApiKey apiKey1 = randomApiKeyInfo(randomBoolean());
final List<String> profileUids1 = randomSize1ProfileUidsList();
final var client = new NodeClient(Settings.EMPTY, threadPool) {
final var client = new NodeClient(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow()) {
@SuppressWarnings("unchecked")
@Override
public <Request extends ActionRequest, Response extends ActionResponse> void doExecute(
@ -241,7 +242,7 @@ public class RestGetApiKeyActionTests extends ESTestCase {
profileUids2
);
final var client = new NodeClient(Settings.EMPTY, threadPool) {
final var client = new NodeClient(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow()) {
@SuppressWarnings("unchecked")
@Override
public <Request extends ActionRequest, Response extends ActionResponse> void doExecute(

View file

@ -15,6 +15,7 @@ import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.action.ActionType;
import org.elasticsearch.client.internal.node.NodeClient;
import org.elasticsearch.cluster.project.TestProjectResolvers;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment;
@ -90,7 +91,7 @@ public class RestInvalidateApiKeyActionTests extends ESTestCase {
null
);
final var client = new NodeClient(Settings.EMPTY, threadPool) {
final var client = new NodeClient(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow()) {
@Override
@SuppressWarnings("unchecked")
public <Request extends ActionRequest, Response extends ActionResponse> void doExecute(
@ -162,7 +163,7 @@ public class RestInvalidateApiKeyActionTests extends ESTestCase {
null
);
final var client = new NodeClient(Settings.EMPTY, threadPool) {
final var client = new NodeClient(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow()) {
@SuppressWarnings("unchecked")
@Override
public <Request extends ActionRequest, Response extends ActionResponse> void doExecute(

View file

@ -13,6 +13,7 @@ import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.action.ActionType;
import org.elasticsearch.client.internal.node.NodeClient;
import org.elasticsearch.cluster.project.TestProjectResolvers;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.settings.Settings;
@ -117,7 +118,7 @@ public class RestQueryApiKeyActionTests extends ESTestCase {
}
};
final var client = new NodeClient(Settings.EMPTY, threadPool) {
final var client = new NodeClient(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow()) {
@SuppressWarnings("unchecked")
@Override
public <Request extends ActionRequest, Response extends ActionResponse> void doExecute(
@ -190,7 +191,7 @@ public class RestQueryApiKeyActionTests extends ESTestCase {
responseSetOnce.set(restResponse);
}
};
final var client = new NodeClient(Settings.EMPTY, threadPool) {
final var client = new NodeClient(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow()) {
@SuppressWarnings("unchecked")
@Override
public <Request extends ActionRequest, Response extends ActionResponse> void doExecute(
@ -237,7 +238,7 @@ public class RestQueryApiKeyActionTests extends ESTestCase {
}
};
final var client = new NodeClient(Settings.EMPTY, threadPool) {
final var client = new NodeClient(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow()) {
@SuppressWarnings("unchecked")
@Override
public <Request extends ActionRequest, Response extends ActionResponse> void doExecute(
@ -323,7 +324,7 @@ public class RestQueryApiKeyActionTests extends ESTestCase {
profileUids = new ArrayList<>(1);
profileUids.add(randomAlphaOfLength(8));
}
var client = new NodeClient(Settings.EMPTY, threadPool) {
var client = new NodeClient(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow()) {
@Override
public <Request extends ActionRequest, Response extends ActionResponse> void doExecute(
ActionType<Response> action,

View file

@ -13,6 +13,7 @@ import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.action.ActionType;
import org.elasticsearch.client.internal.node.NodeClient;
import org.elasticsearch.cluster.project.TestProjectResolvers;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.query.BoolQueryBuilder;
@ -81,7 +82,7 @@ public class RestQueryUserActionTests extends ESTestCase {
};
try (var threadPool = createThreadPool()) {
final var client = new NodeClient(Settings.EMPTY, threadPool) {
final var client = new NodeClient(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow()) {
@SuppressWarnings("unchecked")
@Override
public <Request extends ActionRequest, Response extends ActionResponse> void doExecute(
@ -140,7 +141,7 @@ public class RestQueryUserActionTests extends ESTestCase {
};
try (var threadPool = createThreadPool()) {
final var client = new NodeClient(Settings.EMPTY, threadPool) {
final var client = new NodeClient(Settings.EMPTY, threadPool, TestProjectResolvers.alwaysThrow()) {
@SuppressWarnings("unchecked")
@Override
public <Request extends ActionRequest, Response extends ActionResponse> void doExecute(

View file

@ -90,6 +90,7 @@ public class CancellationTests extends ESTestCase {
countDownLatch.await();
verify(client, times(1)).settings();
verify(client, times(1)).threadPool();
verify(client, times(1)).projectResolver();
verifyNoMoreInteractions(client);
}
@ -144,6 +145,7 @@ public class CancellationTests extends ESTestCase {
verify(client, times(1)).fieldCaps(any(), any());
verify(client, times(1)).settings();
verify(client, times(1)).threadPool();
verify(client, times(1)).projectResolver();
verifyNoMoreInteractions(client);
}
@ -237,6 +239,7 @@ public class CancellationTests extends ESTestCase {
verify(client, times(1)).execute(eq(TransportClosePointInTimeAction.TYPE), any(), any());
verify(client, times(1)).settings();
verify(client, times(1)).threadPool();
verify(client, times(1)).projectResolver();
verifyNoMoreInteractions(client);
}