diff --git a/server/src/main/java/org/elasticsearch/cluster/project/ProjectResolver.java b/server/src/main/java/org/elasticsearch/cluster/project/ProjectResolver.java index cf054ecf6fb6..dd6de4215906 100644 --- a/server/src/main/java/org/elasticsearch/cluster/project/ProjectResolver.java +++ b/server/src/main/java/org/elasticsearch/cluster/project/ProjectResolver.java @@ -21,6 +21,7 @@ import org.elasticsearch.cluster.metadata.Metadata; import org.elasticsearch.cluster.metadata.ProjectId; import org.elasticsearch.cluster.metadata.ProjectMetadata; import org.elasticsearch.core.CheckedRunnable; +import org.elasticsearch.core.FixForMultiProject; import java.util.Collection; import java.util.Objects; @@ -94,6 +95,7 @@ public interface ProjectResolver extends ProjectIdResolver { /** * Returns a client that executes every request in the context of the given project. */ + @FixForMultiProject(description = "This recreates a client on every invocation. We should optimize this to be less wasteful") default Client projectClient(Client baseClient, 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. diff --git a/test/framework/src/main/java/org/elasticsearch/cluster/project/TestProjectResolvers.java b/test/framework/src/main/java/org/elasticsearch/cluster/project/TestProjectResolvers.java index c66df541f6f7..34a25e6d9b23 100644 --- a/test/framework/src/main/java/org/elasticsearch/cluster/project/TestProjectResolvers.java +++ b/test/framework/src/main/java/org/elasticsearch/cluster/project/TestProjectResolvers.java @@ -62,7 +62,7 @@ public final class TestProjectResolvers { public static ProjectResolver mustExecuteFirst() { return new ProjectResolver() { - private ProjectId enforceProjectId = null; + private volatile ProjectId enforceProjectId = null; @Override public ProjectId getProjectId() { @@ -81,14 +81,16 @@ public final class TestProjectResolvers { @Override public void executeOnProject(ProjectId projectId, CheckedRunnable body) throws E { - if (enforceProjectId != null) { - throw new IllegalStateException("Cannot nest calls to executeOnProject"); - } - try { - enforceProjectId = projectId; - body.run(); - } finally { - enforceProjectId = null; + synchronized (this) { + if (enforceProjectId != null) { + throw new IllegalStateException("Cannot nest calls to executeOnProject"); + } + try { + enforceProjectId = projectId; + body.run(); + } finally { + enforceProjectId = null; + } } } diff --git a/test/framework/src/main/java/org/elasticsearch/test/rest/ESRestTestCase.java b/test/framework/src/main/java/org/elasticsearch/test/rest/ESRestTestCase.java index 3fdcd07123be..fe3820606032 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/rest/ESRestTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/test/rest/ESRestTestCase.java @@ -2817,16 +2817,12 @@ public abstract class ESRestTestCase extends ESTestCase { if (indexTemplates != null) { var templateNames = indexTemplates.keySet().stream().filter(name -> isXPackTemplate(name) == false).toList(); assertThat("Project [" + projectId + "] should not have index templates", templateNames, empty()); - } else if (projectId.equals(Metadata.DEFAULT_PROJECT_ID.id())) { - fail("Expected default project to have standard templates, but was null"); } final Map componentTemplates = state.evaluate("metadata.component_template.component_template"); if (componentTemplates != null) { var templateNames = componentTemplates.keySet().stream().filter(name -> isXPackTemplate(name) == false).toList(); assertThat("Project [" + projectId + "] should not have component templates", templateNames, empty()); - } else if (projectId.equals(Metadata.DEFAULT_PROJECT_ID.id())) { - fail("Expected default project to have standard component templates, but was null"); } final List> pipelines = state.evaluate("metadata.ingest.pipeline"); @@ -2836,8 +2832,6 @@ public abstract class ESRestTestCase extends ESTestCase { .filter(id -> isXPackIngestPipeline(id) == false) .toList(); assertThat("Project [" + projectId + "] should not have ingest pipelines", pipelineNames, empty()); - } else if (projectId.equals(Metadata.DEFAULT_PROJECT_ID.id())) { - fail("Expected default project to have standard ingest pipelines, but was null"); } if (has(ProductFeature.ILM)) { @@ -2846,8 +2840,6 @@ public abstract class ESRestTestCase extends ESTestCase { var policyNames = new HashSet<>(ilmPolicies.keySet()); policyNames.removeAll(preserveILMPolicyIds()); assertThat("Project [" + projectId + "] should not have ILM Policies", policyNames, empty()); - } else if (projectId.equals(Metadata.DEFAULT_PROJECT_ID.id())) { - fail("Expected default project to have standard ILM policies, but was null"); } } } diff --git a/x-pack/plugin/apm-data/src/main/java/org/elasticsearch/xpack/apmdata/APMIndexTemplateRegistry.java b/x-pack/plugin/apm-data/src/main/java/org/elasticsearch/xpack/apmdata/APMIndexTemplateRegistry.java index 228ac401b96b..8ab9e1e72df2 100644 --- a/x-pack/plugin/apm-data/src/main/java/org/elasticsearch/xpack/apmdata/APMIndexTemplateRegistry.java +++ b/x-pack/plugin/apm-data/src/main/java/org/elasticsearch/xpack/apmdata/APMIndexTemplateRegistry.java @@ -8,6 +8,7 @@ package org.elasticsearch.xpack.apmdata; import org.elasticsearch.client.internal.Client; +import org.elasticsearch.cluster.project.ProjectResolver; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.threadpool.ThreadPool; @@ -32,7 +33,8 @@ public class APMIndexTemplateRegistry extends YamlTemplateRegistry { ClusterService clusterService, ThreadPool threadPool, Client client, - NamedXContentRegistry xContentRegistry + NamedXContentRegistry xContentRegistry, + ProjectResolver projectResolver ) { super( nodeSettings, @@ -40,7 +42,8 @@ public class APMIndexTemplateRegistry extends YamlTemplateRegistry { threadPool, client, xContentRegistry, - templateFilter(isDataStreamsLifecycleOnlyMode(clusterService.getSettings())) + templateFilter(isDataStreamsLifecycleOnlyMode(clusterService.getSettings())), + projectResolver ); } diff --git a/x-pack/plugin/apm-data/src/main/java/org/elasticsearch/xpack/apmdata/APMPlugin.java b/x-pack/plugin/apm-data/src/main/java/org/elasticsearch/xpack/apmdata/APMPlugin.java index 0be95c337838..53e3dd90231c 100644 --- a/x-pack/plugin/apm-data/src/main/java/org/elasticsearch/xpack/apmdata/APMPlugin.java +++ b/x-pack/plugin/apm-data/src/main/java/org/elasticsearch/xpack/apmdata/APMPlugin.java @@ -48,7 +48,14 @@ public class APMPlugin extends Plugin implements ActionPlugin { Settings settings = services.environment().settings(); ClusterService clusterService = services.clusterService(); registry.set( - new APMIndexTemplateRegistry(settings, clusterService, services.threadPool(), services.client(), services.xContentRegistry()) + new APMIndexTemplateRegistry( + settings, + clusterService, + services.threadPool(), + services.client(), + services.xContentRegistry(), + services.projectResolver() + ) ); if (enabled) { APMIndexTemplateRegistry registryInstance = registry.get(); diff --git a/x-pack/plugin/apm-data/src/test/java/org/elasticsearch/xpack/apmdata/APMDSLOnlyTests.java b/x-pack/plugin/apm-data/src/test/java/org/elasticsearch/xpack/apmdata/APMDSLOnlyTests.java index b18e95b55dde..2d84d1e11c92 100644 --- a/x-pack/plugin/apm-data/src/test/java/org/elasticsearch/xpack/apmdata/APMDSLOnlyTests.java +++ b/x-pack/plugin/apm-data/src/test/java/org/elasticsearch/xpack/apmdata/APMDSLOnlyTests.java @@ -11,6 +11,7 @@ import org.elasticsearch.cluster.metadata.ComponentTemplate; import org.elasticsearch.cluster.metadata.DataStreamLifecycle; import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.node.DiscoveryNodeUtils; +import org.elasticsearch.cluster.project.TestProjectResolvers; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Settings; @@ -59,7 +60,8 @@ public class APMDSLOnlyTests extends ESTestCase { clusterService, threadPool, client, - NamedXContentRegistry.EMPTY + NamedXContentRegistry.EMPTY, + TestProjectResolvers.mustExecuteFirst() ); apmIndexTemplateRegistry.setEnabled(true); } diff --git a/x-pack/plugin/apm-data/src/test/java/org/elasticsearch/xpack/apmdata/APMIndexTemplateRegistryTests.java b/x-pack/plugin/apm-data/src/test/java/org/elasticsearch/xpack/apmdata/APMIndexTemplateRegistryTests.java index 32e7c2225e19..2338bad220c4 100644 --- a/x-pack/plugin/apm-data/src/test/java/org/elasticsearch/xpack/apmdata/APMIndexTemplateRegistryTests.java +++ b/x-pack/plugin/apm-data/src/test/java/org/elasticsearch/xpack/apmdata/APMIndexTemplateRegistryTests.java @@ -26,6 +26,8 @@ import org.elasticsearch.cluster.metadata.Metadata; import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.node.DiscoveryNodeUtils; import org.elasticsearch.cluster.node.DiscoveryNodes; +import org.elasticsearch.cluster.project.ProjectResolver; +import org.elasticsearch.cluster.project.TestProjectResolvers; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.Settings; @@ -89,8 +91,9 @@ public class APMIndexTemplateRegistryTests extends ESTestCase { threadPool = new TestThreadPool(this.getClass().getName()); client = new VerifyingClient(threadPool); ClusterService clusterService = ClusterServiceUtils.createClusterService(threadPool, clusterSettings); + ProjectResolver projectResolver = TestProjectResolvers.mustExecuteFirst(); stackTemplateRegistryAccessor = new StackTemplateRegistryAccessor( - new StackTemplateRegistry(Settings.EMPTY, clusterService, threadPool, client, NamedXContentRegistry.EMPTY) + new StackTemplateRegistry(Settings.EMPTY, clusterService, threadPool, client, NamedXContentRegistry.EMPTY, projectResolver) ); apmIndexTemplateRegistry = new APMIndexTemplateRegistry( @@ -98,7 +101,8 @@ public class APMIndexTemplateRegistryTests extends ESTestCase { clusterService, threadPool, client, - NamedXContentRegistry.EMPTY + NamedXContentRegistry.EMPTY, + projectResolver ); apmIndexTemplateRegistry.setEnabled(true); } diff --git a/x-pack/plugin/core/src/internalClusterTest/java/org/elasticsearch/xpack/core/template/IndexTemplateRegistryRolloverIT.java b/x-pack/plugin/core/src/internalClusterTest/java/org/elasticsearch/xpack/core/template/IndexTemplateRegistryRolloverIT.java index 4c9f8f191408..c377578faf81 100644 --- a/x-pack/plugin/core/src/internalClusterTest/java/org/elasticsearch/xpack/core/template/IndexTemplateRegistryRolloverIT.java +++ b/x-pack/plugin/core/src/internalClusterTest/java/org/elasticsearch/xpack/core/template/IndexTemplateRegistryRolloverIT.java @@ -17,6 +17,7 @@ import org.elasticsearch.client.internal.Client; import org.elasticsearch.cluster.ClusterChangedEvent; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.DataStream; +import org.elasticsearch.cluster.project.TestProjectResolvers; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.datastreams.DataStreamsPlugin; import org.elasticsearch.index.mapper.DateFieldMapper; @@ -58,7 +59,8 @@ public class IndexTemplateRegistryRolloverIT extends ESIntegTestCase { clusterService.threadPool(), client, xContentRegistry(), - 3L + 3L, + TestProjectResolvers.mustExecuteFirst() ); registry.initialize(); ensureGreen(); diff --git a/x-pack/plugin/core/src/internalClusterTest/java/org/elasticsearch/xpack/core/template/RolloverEnabledTestTemplateRegistry.java b/x-pack/plugin/core/src/internalClusterTest/java/org/elasticsearch/xpack/core/template/RolloverEnabledTestTemplateRegistry.java index 442ad9a68dfc..b340070c704a 100644 --- a/x-pack/plugin/core/src/internalClusterTest/java/org/elasticsearch/xpack/core/template/RolloverEnabledTestTemplateRegistry.java +++ b/x-pack/plugin/core/src/internalClusterTest/java/org/elasticsearch/xpack/core/template/RolloverEnabledTestTemplateRegistry.java @@ -9,6 +9,7 @@ package org.elasticsearch.xpack.core.template; import org.elasticsearch.client.internal.Client; import org.elasticsearch.cluster.metadata.ComposableIndexTemplate; +import org.elasticsearch.cluster.project.ProjectResolver; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.threadpool.ThreadPool; @@ -28,9 +29,10 @@ public class RolloverEnabledTestTemplateRegistry extends IndexTemplateRegistry { ThreadPool threadPool, Client client, NamedXContentRegistry xContentRegistry, - long version + long version, + ProjectResolver projectResolver ) { - super(nodeSettings, clusterService, threadPool, client, xContentRegistry); + super(nodeSettings, clusterService, threadPool, client, xContentRegistry, projectResolver); this.version = version; } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/template/IndexTemplateRegistry.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/template/IndexTemplateRegistry.java index fb06cfb90838..8c0080e67d75 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/template/IndexTemplateRegistry.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/template/IndexTemplateRegistry.java @@ -30,9 +30,11 @@ import org.elasticsearch.cluster.metadata.ComposableIndexTemplate; import org.elasticsearch.cluster.metadata.DataStream; import org.elasticsearch.cluster.metadata.IndexTemplateMetadata; import org.elasticsearch.cluster.metadata.MetadataIndexTemplateService; +import org.elasticsearch.cluster.metadata.ProjectId; import org.elasticsearch.cluster.metadata.ProjectMetadata; import org.elasticsearch.cluster.metadata.Template; import org.elasticsearch.cluster.node.DiscoveryNode; +import org.elasticsearch.cluster.project.ProjectResolver; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.Strings; import org.elasticsearch.common.regex.Regex; @@ -85,10 +87,14 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { protected final ThreadPool threadPool; protected final NamedXContentRegistry xContentRegistry; protected final ClusterService clusterService; - protected final ConcurrentMap templateCreationsInProgress = new ConcurrentHashMap<>(); - protected final ConcurrentMap policyCreationsInProgress = new ConcurrentHashMap<>(); - protected final ConcurrentMap pipelineCreationsInProgress = new ConcurrentHashMap<>(); + protected final ConcurrentMap> templateCreationsInProgress = + new ConcurrentHashMap<>(); + protected final ConcurrentMap> policyCreationsInProgress = + new ConcurrentHashMap<>(); + protected final ConcurrentMap> pipelineCreationsInProgress = + new ConcurrentHashMap<>(); protected final List lifecyclePolicies; + protected final ProjectResolver projectResolver; @SuppressWarnings("this-escape") public IndexTemplateRegistry( @@ -96,13 +102,15 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { ClusterService clusterService, ThreadPool threadPool, Client client, - NamedXContentRegistry xContentRegistry + NamedXContentRegistry xContentRegistry, + ProjectResolver projectResolver ) { this.settings = nodeSettings; this.client = client; this.threadPool = threadPool; this.xContentRegistry = xContentRegistry; this.clusterService = clusterService; + this.projectResolver = projectResolver; if (isDataStreamsLifecycleOnlyMode(clusterService.getSettings()) == false) { this.lifecyclePolicies = getLifecycleConfigs().stream() .map(config -> config.load(LifecyclePolicyConfig.DEFAULT_X_CONTENT_REGISTRY)) @@ -235,10 +243,13 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { DiscoveryNode localNode = event.state().getNodes().getLocalNode(); boolean localNodeVersionAfterMaster = localNode.getVersion().after(masterNode.getVersion()); - if (event.localNodeMaster() || localNodeVersionAfterMaster) { - addIngestPipelinesIfMissing(state); - addTemplatesIfMissing(state); - addIndexLifecyclePoliciesIfMissing(state); + if (event.localNodeMaster() == false && localNodeVersionAfterMaster == false) { + return; + } + for (ProjectMetadata project : event.state().metadata().projects().values()) { + addIngestPipelinesIfMissing(project); + addTemplatesIfMissing(project); + addIndexLifecyclePoliciesIfMissing(project); } } @@ -259,13 +270,13 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { return false; } - private void addTemplatesIfMissing(ClusterState state) { - addLegacyTemplatesIfMissing(state); - addComponentTemplatesIfMissing(state); - addComposableTemplatesIfMissing(state.metadata().getProject()); + private void addTemplatesIfMissing(ProjectMetadata project) { + addLegacyTemplatesIfMissing(project); + addComponentTemplatesIfMissing(project); + addComposableTemplatesIfMissing(project); } - private void addLegacyTemplatesIfMissing(ClusterState state) { + private void addLegacyTemplatesIfMissing(ProjectMetadata project) { if (isDataStreamsLifecycleOnlyMode(clusterService.getSettings())) { // data stream lifecycle cannot be configured via legacy templates return; @@ -273,12 +284,13 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { final List indexTemplates = getLegacyTemplateConfigs(); for (IndexTemplateConfig newTemplate : indexTemplates) { final String templateName = newTemplate.getTemplateName(); - final AtomicBoolean creationCheck = templateCreationsInProgress.computeIfAbsent(templateName, key -> new AtomicBoolean(false)); + final AtomicBoolean creationCheck = templateCreationsInProgress.computeIfAbsent(project.id(), key -> new ConcurrentHashMap<>()) + .computeIfAbsent(templateName, key -> new AtomicBoolean(false)); if (creationCheck.compareAndSet(false, true)) { - IndexTemplateMetadata currentTemplate = state.metadata().getProject().templates().get(templateName); + IndexTemplateMetadata currentTemplate = project.templates().get(templateName); if (Objects.isNull(currentTemplate)) { logger.debug("adding legacy template [{}] for [{}], because it doesn't exist", templateName, getOrigin()); - putLegacyTemplate(newTemplate, creationCheck); + putLegacyTemplate(project.id(), newTemplate, creationCheck); } else if (Objects.isNull(currentTemplate.getVersion()) || newTemplate.getVersion() > currentTemplate.getVersion()) { // IndexTemplateConfig now enforces templates contain a `version` property, so if the template doesn't have one we can // safely assume it's an old version of the template. @@ -289,7 +301,7 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { currentTemplate.getVersion(), newTemplate.getVersion() ); - putLegacyTemplate(newTemplate, creationCheck); + putLegacyTemplate(project.id(), newTemplate, creationCheck); } else { creationCheck.set(false); logger.trace( @@ -309,14 +321,15 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { } } - private void addComponentTemplatesIfMissing(ClusterState state) { + private void addComponentTemplatesIfMissing(ProjectMetadata project) { final Map indexTemplates = getComponentTemplateConfigs(); for (Map.Entry newTemplate : indexTemplates.entrySet()) { final String templateName = newTemplate.getKey(); - final AtomicBoolean creationCheck = templateCreationsInProgress.computeIfAbsent(templateName, key -> new AtomicBoolean(false)); + final AtomicBoolean creationCheck = templateCreationsInProgress.computeIfAbsent(project.id(), key -> new ConcurrentHashMap<>()) + .computeIfAbsent(templateName, key -> new AtomicBoolean(false)); if (creationCheck.compareAndSet(false, true)) { - ComponentTemplate currentTemplate = state.metadata().getProject().componentTemplates().get(templateName); - if (templateDependenciesSatisfied(state, newTemplate.getValue()) == false) { + ComponentTemplate currentTemplate = project.componentTemplates().get(templateName); + if (templateDependenciesSatisfied(project, newTemplate.getValue()) == false) { creationCheck.set(false); logger.trace( "not adding index template [{}] for [{}] because its required dependencies do not exist", @@ -325,7 +338,7 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { ); } else if (Objects.isNull(currentTemplate)) { logger.debug("adding component template [{}] for [{}], because it doesn't exist", templateName, getOrigin()); - putComponentTemplate(templateName, newTemplate.getValue(), creationCheck); + putComponentTemplate(project.id(), templateName, newTemplate.getValue(), creationCheck); } else if (Objects.isNull(currentTemplate.version()) || newTemplate.getValue().version() > currentTemplate.version()) { // IndexTemplateConfig now enforces templates contain a `version` property, so if the template doesn't have one we can // safely assume it's an old version of the template. @@ -336,7 +349,7 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { currentTemplate.version(), newTemplate.getValue().version() ); - putComponentTemplate(templateName, newTemplate.getValue(), creationCheck); + putComponentTemplate(project.id(), templateName, newTemplate.getValue(), creationCheck); } else { creationCheck.set(false); logger.trace( @@ -359,7 +372,7 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { /** * Returns true if the cluster state contains all of the dependencies required by the provided component template */ - private static boolean templateDependenciesSatisfied(ClusterState state, ComponentTemplate indexTemplate) { + private static boolean templateDependenciesSatisfied(ProjectMetadata project, ComponentTemplate indexTemplate) { Template template = indexTemplate.template(); if (template == null) { return true; @@ -368,7 +381,7 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { if (settings == null) { return true; } - IngestMetadata ingestMetadata = state.metadata().getProject().custom(IngestMetadata.TYPE); + IngestMetadata ingestMetadata = project.custom(IngestMetadata.TYPE); String defaultPipeline = settings.get("index.default_pipeline"); if (defaultPipeline != null) { if (ingestMetadata == null || ingestMetadata.getPipelines().containsKey(defaultPipeline) == false) { @@ -382,14 +395,15 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { return true; } - private void addComposableTemplatesIfMissing(ProjectMetadata projectMetadata) { + private void addComposableTemplatesIfMissing(ProjectMetadata project) { final Map indexTemplates = getComposableTemplateConfigs(); for (Map.Entry newTemplate : indexTemplates.entrySet()) { final String templateName = newTemplate.getKey(); - final AtomicBoolean creationCheck = templateCreationsInProgress.computeIfAbsent(templateName, key -> new AtomicBoolean(false)); + final AtomicBoolean creationCheck = templateCreationsInProgress.computeIfAbsent(project.id(), key -> new ConcurrentHashMap<>()) + .computeIfAbsent(templateName, key -> new AtomicBoolean(false)); if (creationCheck.compareAndSet(false, true)) { - ComposableIndexTemplate currentTemplate = projectMetadata.templatesV2().get(templateName); - boolean componentTemplatesAvailable = componentTemplatesInstalled(projectMetadata, newTemplate.getValue()); + ComposableIndexTemplate currentTemplate = project.templatesV2().get(templateName); + boolean componentTemplatesAvailable = componentTemplatesInstalled(project, newTemplate.getValue()); if (componentTemplatesAvailable == false) { creationCheck.set(false); if (logger.isTraceEnabled()) { @@ -402,7 +416,7 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { } } else if (Objects.isNull(currentTemplate)) { logger.debug("adding composable template [{}] for [{}], because it doesn't exist", templateName, getOrigin()); - putComposableTemplate(projectMetadata, templateName, newTemplate.getValue(), creationCheck); + putComposableTemplate(project, templateName, newTemplate.getValue(), creationCheck); } else if (Objects.isNull(currentTemplate.version()) || newTemplate.getValue().version() > currentTemplate.version()) { // IndexTemplateConfig now enforces templates contain a `version` property, so if the template doesn't have one we can // safely assume it's an old version of the template. @@ -413,7 +427,7 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { currentTemplate.version(), newTemplate.getValue().version() ); - putComposableTemplate(projectMetadata, templateName, newTemplate.getValue(), creationCheck); + putComposableTemplate(project, templateName, newTemplate.getValue(), creationCheck); } else { creationCheck.set(false); logger.trace( @@ -438,14 +452,14 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { * requires automatic rollover after index template upgrades (see {@link #applyRolloverAfterTemplateV2Update()}), this method also * verifies that the installed components templates are of the right version. */ - private boolean componentTemplatesInstalled(ProjectMetadata projectMetadata, ComposableIndexTemplate indexTemplate) { + private boolean componentTemplatesInstalled(ProjectMetadata project, ComposableIndexTemplate indexTemplate) { if (applyRolloverAfterTemplateV2Update() == false) { // component templates and index templates can be updated independently, we only need to know that the required component // templates are available - return projectMetadata.componentTemplates().keySet().containsAll(indexTemplate.getRequiredComponentTemplates()); + return project.componentTemplates().keySet().containsAll(indexTemplate.getRequiredComponentTemplates()); } Map componentTemplateConfigs = getComponentTemplateConfigs(); - Map installedTemplates = projectMetadata.componentTemplates(); + Map installedTemplates = project.componentTemplates(); for (String templateName : indexTemplate.getRequiredComponentTemplates()) { ComponentTemplate installedTemplate = installedTemplates.get(templateName); // if a required component templates is not installed - the current cluster state cannot allow this index template yet @@ -463,7 +477,7 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { return true; } - private void putLegacyTemplate(final IndexTemplateConfig config, final AtomicBoolean creationCheck) { + private void putLegacyTemplate(final ProjectId projectId, final IndexTemplateConfig config, final AtomicBoolean creationCheck) { final Executor executor = threadPool.generic(); executor.execute(() -> { final String templateName = config.getTemplateName(); @@ -493,12 +507,17 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { onPutTemplateFailure(templateName, e); } }, - client.admin().indices()::putTemplate + projectResolver.projectClient(client, projectId).admin().indices()::putTemplate ); }); } - private void putComponentTemplate(final String templateName, final ComponentTemplate template, final AtomicBoolean creationCheck) { + private void putComponentTemplate( + final ProjectId projectId, + final String templateName, + final ComponentTemplate template, + final AtomicBoolean creationCheck + ) { final Executor executor = threadPool.generic(); executor.execute(() -> { PutComponentTemplateAction.Request request = new PutComponentTemplateAction.Request(templateName).componentTemplate(template); @@ -526,13 +545,14 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { onPutTemplateFailure(templateName, e); } }, - (req, listener) -> client.execute(PutComponentTemplateAction.INSTANCE, req, listener) + (req, listener) -> projectResolver.projectClient(client, projectId) + .execute(PutComponentTemplateAction.INSTANCE, req, listener) ); }); } private void putComposableTemplate( - ProjectMetadata projectMetadata, + final ProjectMetadata project, final String templateName, final ComposableIndexTemplate indexTemplate, final AtomicBoolean creationCheck @@ -551,7 +571,7 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { public void onResponse(AcknowledgedResponse response) { if (response.isAcknowledged()) { if (applyRolloverAfterTemplateV2Update()) { - invokeRollover(projectMetadata, templateName, indexTemplate, () -> creationCheck.set((false))); + invokeRollover(project, templateName, indexTemplate, () -> creationCheck.set((false))); } else { creationCheck.set(false); } @@ -571,32 +591,30 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { onPutTemplateFailure(templateName, e); } }, - (req, listener) -> client.execute(TransportPutComposableIndexTemplateAction.TYPE, req, listener) + (req, listener) -> projectResolver.projectClient(client, project.id()) + .execute(TransportPutComposableIndexTemplateAction.TYPE, req, listener) ); }); } - private void addIndexLifecyclePoliciesIfMissing(ClusterState state) { + private void addIndexLifecyclePoliciesIfMissing(ProjectMetadata project) { if (isDataStreamsLifecycleOnlyMode(clusterService.getSettings())) { logger.trace("running in data stream lifecycle only mode. skipping the installation of ILM policies."); return; } - final IndexLifecycleMetadata metadata = state.metadata().getProject().custom(IndexLifecycleMetadata.TYPE); + final IndexLifecycleMetadata metadata = project.custom(IndexLifecycleMetadata.TYPE); final Map policies = metadata != null ? metadata.getPolicies() : Map.of(); - for (LifecyclePolicy policy : getLifecyclePolicies()) { - final AtomicBoolean creationCheck = policyCreationsInProgress.computeIfAbsent( - policy.getName(), - key -> new AtomicBoolean(false) - ); + final AtomicBoolean creationCheck = policyCreationsInProgress.computeIfAbsent(project.id(), key -> new ConcurrentHashMap<>()) + .computeIfAbsent(policy.getName(), key -> new AtomicBoolean(false)); if (creationCheck.compareAndSet(false, true)) { final LifecyclePolicy currentPolicy = policies.get(policy.getName()); if (Objects.isNull(currentPolicy)) { logger.debug("adding lifecycle policy [{}] for [{}], because it doesn't exist", policy.getName(), getOrigin()); - putPolicy(policy, creationCheck); + putPolicy(project.id(), policy, creationCheck); } else if (isUpgradeRequired(currentPolicy, policy)) { logger.info("upgrading lifecycle policy [{}] for [{}]", policy.getName(), getOrigin()); - putPolicy(policy, creationCheck); + putPolicy(project.id(), policy, creationCheck); } else { logger.trace("not adding lifecycle policy [{}] for [{}], because it already exists", policy.getName(), getOrigin()); creationCheck.set(false); @@ -616,7 +634,7 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { return false; } - private void putPolicy(final LifecyclePolicy policy, final AtomicBoolean creationCheck) { + private void putPolicy(ProjectId projectId, final LifecyclePolicy policy, final AtomicBoolean creationCheck) { final Executor executor = threadPool.generic(); executor.execute(() -> { PutLifecycleRequest request = new PutLifecycleRequest(REGISTRY_ACTION_TIMEOUT, REGISTRY_ACTION_TIMEOUT, policy); @@ -644,7 +662,7 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { onPutPolicyFailure(policy, e); } }, - (req, listener) -> client.execute(ILMActions.PUT, req, listener) + (req, listener) -> projectResolver.projectClient(client, projectId).execute(ILMActions.PUT, req, listener) ); }); } @@ -659,16 +677,14 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { })); } - private void addIngestPipelinesIfMissing(ClusterState state) { + private void addIngestPipelinesIfMissing(ProjectMetadata project) { for (IngestPipelineConfig requiredPipeline : getIngestPipelines()) { - final AtomicBoolean creationCheck = pipelineCreationsInProgress.computeIfAbsent( - requiredPipeline.getId(), - key -> new AtomicBoolean(false) - ); + final AtomicBoolean creationCheck = pipelineCreationsInProgress.computeIfAbsent(project.id(), key -> new ConcurrentHashMap<>()) + .computeIfAbsent(requiredPipeline.getId(), key -> new AtomicBoolean(false)); if (creationCheck.compareAndSet(false, true)) { List pipelineDependencies = requiredPipeline.getPipelineDependencies(); - if (pipelineDependencies != null && pipelineDependenciesExist(state, pipelineDependencies) == false) { + if (pipelineDependencies != null && pipelineDependenciesExist(project, pipelineDependencies) == false) { creationCheck.set(false); logger.trace( "not adding ingest pipeline [{}] for [{}] because its dependencies do not exist", @@ -676,7 +692,7 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { getOrigin() ); } else { - PipelineConfiguration existingPipeline = findInstalledPipeline(state, requiredPipeline.getId()); + PipelineConfiguration existingPipeline = findInstalledPipeline(project, requiredPipeline.getId()); if (existingPipeline != null) { Integer existingPipelineVersion = existingPipeline.getVersion(); if (existingPipelineVersion == null || existingPipelineVersion < requiredPipeline.getVersion()) { @@ -687,7 +703,7 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { existingPipelineVersion, requiredPipeline.getVersion() ); - putIngestPipeline(requiredPipeline, creationCheck); + putIngestPipeline(project.id(), requiredPipeline, creationCheck); } else { creationCheck.set(false); logger.debug( @@ -702,16 +718,16 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { requiredPipeline.getId(), getOrigin() ); - putIngestPipeline(requiredPipeline, creationCheck); + putIngestPipeline(project.id(), requiredPipeline, creationCheck); } } } } } - private static boolean pipelineDependenciesExist(ClusterState state, List dependencies) { + private static boolean pipelineDependenciesExist(ProjectMetadata project, List dependencies) { for (String dependency : dependencies) { - if (findInstalledPipeline(state, dependency) == null) { + if (findInstalledPipeline(project, dependency) == null) { return false; } } @@ -719,12 +735,12 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { } @Nullable - private static PipelineConfiguration findInstalledPipeline(ClusterState state, String pipelineId) { - Optional maybeMeta = Optional.ofNullable(state.metadata().getProject().custom(IngestMetadata.TYPE)); + private static PipelineConfiguration findInstalledPipeline(ProjectMetadata project, String pipelineId) { + Optional maybeMeta = Optional.ofNullable(project.custom(IngestMetadata.TYPE)); return maybeMeta.map(ingestMetadata -> ingestMetadata.getPipelines().get(pipelineId)).orElse(null); } - private void putIngestPipeline(final IngestPipelineConfig pipelineConfig, final AtomicBoolean creationCheck) { + private void putIngestPipeline(ProjectId projectId, final IngestPipelineConfig pipelineConfig, final AtomicBoolean creationCheck) { final Executor executor = threadPool.generic(); executor.execute(() -> { PutPipelineRequest request = new PutPipelineRequest( @@ -760,7 +776,7 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { onPutPipelineFailure(pipelineConfig.getId(), e); } }, - (req, listener) -> client.execute(PutPipelineTransportAction.TYPE, req, listener) + (req, listener) -> projectResolver.projectClient(client, projectId).execute(PutPipelineTransportAction.TYPE, req, listener) ); }); } @@ -792,14 +808,14 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { * and then invokes runAfter. */ private void invokeRollover( - final ProjectMetadata projectMetadata, + final ProjectMetadata project, final String templateName, final ComposableIndexTemplate indexTemplate, final Runnable runAfter ) { final Executor executor = threadPool.generic(); executor.execute(() -> { - List rolloverTargets = findRolloverTargetDataStreams(projectMetadata, templateName, indexTemplate); + List rolloverTargets = findRolloverTargetDataStreams(project, templateName, indexTemplate); if (rolloverTargets.isEmpty()) { runAfter.run(); return; @@ -810,13 +826,13 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { @Override public void onResponse(Collection rolloverResponses) { runAfter.run(); - onRolloversBulkResponse(rolloverResponses); + onRolloversBulkResponse(project.id(), rolloverResponses); } @Override public void onFailure(Exception e) { runAfter.run(); - onRolloverFailure(e); + onRolloverFailure(project.id(), e); } } ); @@ -835,23 +851,28 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { getOrigin(), request, groupedActionListener, - (req, listener) -> client.execute(RolloverAction.INSTANCE, req, listener) + (req, listener) -> projectResolver.projectClient(client, project.id()).execute(RolloverAction.INSTANCE, req, listener) ); } }); } - void onRolloversBulkResponse(Collection rolloverResponses) { + void onRolloversBulkResponse(ProjectId projectId, Collection rolloverResponses) { for (RolloverResponse rolloverResponse : rolloverResponses) { assert rolloverResponse.isLazy() && rolloverResponse.isRolledOver() == false - : Strings.format("Expected rollover of the [%s] index [%s] to be lazy", getOrigin(), rolloverResponse.getOldIndex()); + : Strings.format( + "Expected rollover of the [%s] index [%s] in project [%s] to be lazy", + getOrigin(), + projectId, + rolloverResponse.getOldIndex() + ); } } - void onRolloverFailure(Exception e) { - logger.error(String.format(Locale.ROOT, "[%s] related rollover failed", getOrigin()), e); + void onRolloverFailure(ProjectId projectId, Exception e) { + logger.error(String.format(Locale.ROOT, "[%s] related rollover failed in project [%s]", getOrigin(), projectId), e); for (Throwable throwable : e.getSuppressed()) { - logger.error(String.format(Locale.ROOT, "[%s] related rollover failed", getOrigin()), throwable); + logger.error(String.format(Locale.ROOT, "[%s] related rollover failed in project [%s]", getOrigin(), projectId), throwable); } } @@ -863,23 +884,19 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { * as argument * * - * @param projectMetadata the project metadata from the cluster state + * @param project the project metadata from the cluster state * @param templateName the ID by which the provided index template is being registered * @param indexTemplate the index template for which a data stream is looked up as rollover target * @return the list of rollover targets matching the provided index template */ - static List findRolloverTargetDataStreams( - ProjectMetadata projectMetadata, - String templateName, - ComposableIndexTemplate indexTemplate - ) { - return projectMetadata.dataStreams() + static List findRolloverTargetDataStreams(ProjectMetadata project, String templateName, ComposableIndexTemplate indexTemplate) { + return project.dataStreams() .values() .stream() // Limit to checking data streams that match any of the index template's index patterns .filter(ds -> indexTemplate.indexPatterns().stream().anyMatch(pattern -> Regex.simpleMatch(pattern, ds.getName()))) .filter(ds -> { - final String dsTemplateName = MetadataIndexTemplateService.findV2Template(projectMetadata, ds.getName(), ds.isHidden()); + final String dsTemplateName = MetadataIndexTemplateService.findV2Template(project, ds.getName(), ds.isHidden()); if (templateName.equals(dsTemplateName)) { return true; } @@ -890,7 +907,7 @@ public abstract class IndexTemplateRegistry implements ClusterStateListener { // // Because of the second case, we must check if indexTemplate's priority is greater than the matching // index template, in case it would take precedence after installation/update. - final ComposableIndexTemplate dsTemplate = projectMetadata.templatesV2().get(dsTemplateName); + final ComposableIndexTemplate dsTemplate = project.templatesV2().get(dsTemplateName); return dsTemplate == null || indexTemplate.priorityOrZero() > dsTemplate.priorityOrZero(); }) .map(DataStream::getName) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/template/YamlTemplateRegistry.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/template/YamlTemplateRegistry.java index cf0a73963f86..5fd7acf03951 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/template/YamlTemplateRegistry.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/template/YamlTemplateRegistry.java @@ -13,6 +13,7 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.client.internal.Client; import org.elasticsearch.cluster.metadata.ComponentTemplate; import org.elasticsearch.cluster.metadata.ComposableIndexTemplate; +import org.elasticsearch.cluster.project.ProjectResolver; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentHelper; @@ -54,9 +55,10 @@ public abstract class YamlTemplateRegistry extends IndexTemplateRegistry { ClusterService clusterService, ThreadPool threadPool, Client client, - NamedXContentRegistry xContentRegistry + NamedXContentRegistry xContentRegistry, + ProjectResolver projectResolver ) { - this(nodeSettings, clusterService, threadPool, client, xContentRegistry, ignored -> true); + this(nodeSettings, clusterService, threadPool, client, xContentRegistry, ignored -> true, projectResolver); } @SuppressWarnings({ "unchecked", "this-escape" }) @@ -66,9 +68,10 @@ public abstract class YamlTemplateRegistry extends IndexTemplateRegistry { ThreadPool threadPool, Client client, NamedXContentRegistry xContentRegistry, - Predicate templateFilter + Predicate templateFilter, + ProjectResolver projectResolver ) { - super(nodeSettings, clusterService, threadPool, client, xContentRegistry); + super(nodeSettings, clusterService, threadPool, client, xContentRegistry, projectResolver); try { final Map resources = XContentHelper.convertToMap( YamlXContent.yamlXContent, diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/template/IndexTemplateRegistryTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/template/IndexTemplateRegistryTests.java index 7c43084c618d..7d4757cb2e55 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/template/IndexTemplateRegistryTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/template/IndexTemplateRegistryTests.java @@ -13,7 +13,6 @@ import org.elasticsearch.action.ActionResponse; import org.elasticsearch.action.ActionType; import org.elasticsearch.action.admin.indices.rollover.RolloverAction; import org.elasticsearch.action.admin.indices.rollover.RolloverRequest; -import org.elasticsearch.action.admin.indices.rollover.RolloverResponse; import org.elasticsearch.action.admin.indices.template.put.PutComponentTemplateAction; import org.elasticsearch.action.admin.indices.template.put.TransportPutComposableIndexTemplateAction; import org.elasticsearch.action.ingest.PutPipelineRequest; @@ -27,17 +26,20 @@ import org.elasticsearch.cluster.metadata.ComponentTemplate; import org.elasticsearch.cluster.metadata.ComposableIndexTemplate; import org.elasticsearch.cluster.metadata.DataStreamTestHelper; import org.elasticsearch.cluster.metadata.Metadata; +import org.elasticsearch.cluster.metadata.ProjectId; +import org.elasticsearch.cluster.metadata.ProjectMetadata; import org.elasticsearch.cluster.node.DiscoveryNode; 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.TriFunction; import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.core.Strings; import org.elasticsearch.index.Index; import org.elasticsearch.ingest.IngestMetadata; import org.elasticsearch.ingest.PipelineConfiguration; +import org.elasticsearch.tasks.Task; import org.elasticsearch.test.ClusterServiceUtils; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.client.NoOpClient; @@ -60,14 +62,13 @@ import org.junit.After; import org.junit.Before; import java.io.IOException; -import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Objects; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import static org.hamcrest.Matchers.contains; @@ -83,6 +84,9 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; public class IndexTemplateRegistryTests extends ESTestCase { + + private final ProjectId projectId = randomProjectIdOrDefault(); + private TestRegistryWithCustomPlugin registry; private ClusterService clusterService; private ThreadPool threadPool; @@ -93,7 +97,14 @@ public class IndexTemplateRegistryTests extends ESTestCase { threadPool = new TestThreadPool(this.getClass().getName()); client = new VerifyingClient(threadPool); clusterService = ClusterServiceUtils.createClusterService(threadPool); - registry = new TestRegistryWithCustomPlugin(Settings.EMPTY, clusterService, threadPool, client, NamedXContentRegistry.EMPTY); + registry = new TestRegistryWithCustomPlugin( + Settings.EMPTY, + clusterService, + threadPool, + client, + NamedXContentRegistry.EMPTY, + TestProjectResolvers.usingRequestHeader(threadPool.getThreadContext()) + ); } @After @@ -107,9 +118,10 @@ public class IndexTemplateRegistryTests extends ESTestCase { DiscoveryNode node = DiscoveryNodeUtils.create("node"); DiscoveryNodes nodes = DiscoveryNodes.builder().localNodeId("node").masterNodeId("node").add(node).build(); - AtomicInteger calledTimes = new AtomicInteger(0); - client.setVerifier((action, request, listener) -> { + Map calledTimesMap = new ConcurrentHashMap<>(); + client.setVerifier((projectId, action, request, listener) -> { if (action == PutPipelineTransportAction.TYPE) { + final var calledTimes = calledTimesMap.computeIfAbsent(projectId, k -> new AtomicInteger(0)); assertPutPipelineAction(calledTimes, action, request, listener, "custom-plugin-final_pipeline"); return AcknowledgedResponse.TRUE; } else if (action == ILMActions.PUT) { @@ -125,16 +137,17 @@ public class IndexTemplateRegistryTests extends ESTestCase { ClusterChangedEvent event = createClusterChangedEvent(Collections.emptyMap(), nodes); registry.clusterChanged(event); - assertBusy(() -> assertThat(calledTimes.get(), equalTo(1))); + assertCalledTimes(calledTimesMap, event, 1); } public void testThatDependentPipelinesAreAddedIfDependenciesExist() throws Exception { DiscoveryNode node = DiscoveryNodeUtils.create("node"); DiscoveryNodes nodes = DiscoveryNodes.builder().localNodeId("node").masterNodeId("node").add(node).build(); - AtomicInteger calledTimes = new AtomicInteger(0); - client.setVerifier((action, request, listener) -> { + Map calledTimesMap = new ConcurrentHashMap<>(); + client.setVerifier((projectId, action, request, listener) -> { if (action == PutPipelineTransportAction.TYPE) { + final var calledTimes = calledTimesMap.computeIfAbsent(projectId, k -> new AtomicInteger(0)); assertPutPipelineAction(calledTimes, action, request, listener, "custom-plugin-default_pipeline"); return AcknowledgedResponse.TRUE; } else if (action == ILMActions.PUT) { @@ -155,16 +168,17 @@ public class IndexTemplateRegistryTests extends ESTestCase { nodes ); registry.clusterChanged(event); - assertBusy(() -> assertThat(calledTimes.get(), equalTo(1))); + assertCalledTimes(calledTimesMap, event, 1); } public void testThatTemplateIsAddedIfAllDependenciesExist() throws Exception { DiscoveryNode node = DiscoveryNodeUtils.create("node"); DiscoveryNodes nodes = DiscoveryNodes.builder().localNodeId("node").masterNodeId("node").add(node).build(); - AtomicInteger calledTimes = new AtomicInteger(0); - client.setVerifier((action, request, listener) -> { + Map calledTimesMap = new ConcurrentHashMap<>(); + client.setVerifier((projectId, action, request, listener) -> { if (action instanceof PutComponentTemplateAction) { + final var calledTimes = calledTimesMap.computeIfAbsent(projectId, k -> new AtomicInteger(0)); assertPutComponentTemplate(calledTimes, action, request, listener); return AcknowledgedResponse.TRUE; } else if (action == ILMActions.PUT) { @@ -184,16 +198,17 @@ public class IndexTemplateRegistryTests extends ESTestCase { nodes ); registry.clusterChanged(event); - assertBusy(() -> assertThat(calledTimes.get(), equalTo(1))); + assertCalledTimes(calledTimesMap, event, 1); } public void testThatTemplateIsNotAddedIfNotAllDependenciesExist() throws Exception { DiscoveryNode node = DiscoveryNodeUtils.create("node"); DiscoveryNodes nodes = DiscoveryNodes.builder().localNodeId("node").masterNodeId("node").add(node).build(); - AtomicInteger calledTimes = new AtomicInteger(0); - client.setVerifier((action, request, listener) -> { + Map calledTimesMap = new ConcurrentHashMap<>(); + client.setVerifier((projectId, action, request, listener) -> { if (action == PutPipelineTransportAction.TYPE) { + final var calledTimes = calledTimesMap.computeIfAbsent(projectId, k -> new AtomicInteger(0)); assertPutPipelineAction(calledTimes, action, request, listener, "custom-plugin-default_pipeline"); return AcknowledgedResponse.TRUE; } else if (action == ILMActions.PUT) { @@ -213,16 +228,17 @@ public class IndexTemplateRegistryTests extends ESTestCase { nodes ); registry.clusterChanged(event); - assertBusy(() -> assertThat(calledTimes.get(), equalTo(1))); + assertCalledTimes(calledTimesMap, event, 1); } public void testThatComposableTemplateIsAddedIfDependenciesExist() throws Exception { DiscoveryNode node = DiscoveryNodeUtils.create("node"); DiscoveryNodes nodes = DiscoveryNodes.builder().localNodeId("node").masterNodeId("node").add(node).build(); - AtomicInteger calledTimes = new AtomicInteger(0); - client.setVerifier((action, request, listener) -> { + Map calledTimesMap = new ConcurrentHashMap<>(); + client.setVerifier((projectId, action, request, listener) -> { if (action == TransportPutComposableIndexTemplateAction.TYPE) { + final var calledTimes = calledTimesMap.computeIfAbsent(projectId, k -> new AtomicInteger(0)); assertPutComposableIndexTemplateAction(calledTimes, action, request, listener); return AcknowledgedResponse.TRUE; } else if (action == ILMActions.PUT) { @@ -240,16 +256,17 @@ public class IndexTemplateRegistryTests extends ESTestCase { ClusterChangedEvent event = createClusterChangedEvent(Collections.singletonMap("custom-plugin-settings", 3), nodes); registry.clusterChanged(event); - assertBusy(() -> assertThat(calledTimes.get(), equalTo(1))); + assertCalledTimes(calledTimesMap, event, 1); } public void testThatComposableTemplateIsAddedIfDependenciesHaveRightVersion() throws Exception { DiscoveryNode node = DiscoveryNodeUtils.create("node"); DiscoveryNodes nodes = DiscoveryNodes.builder().localNodeId("node").masterNodeId("node").add(node).build(); - AtomicInteger calledTimes = new AtomicInteger(0); - client.setVerifier((action, request, listener) -> { + Map calledTimesMap = new ConcurrentHashMap<>(); + client.setVerifier((projectId, action, request, listener) -> { if (action == TransportPutComposableIndexTemplateAction.TYPE) { + final var calledTimes = calledTimesMap.computeIfAbsent(projectId, k -> new AtomicInteger(0)); assertPutComposableIndexTemplateAction(calledTimes, action, request, listener); return AcknowledgedResponse.TRUE; } else if (action instanceof PutComponentTemplateAction) { @@ -272,26 +289,27 @@ public class IndexTemplateRegistryTests extends ESTestCase { // to their version ClusterChangedEvent event = createClusterChangedEvent(Collections.singletonMap("custom-plugin-settings", 2), nodes); registry.clusterChanged(event); - assertBusy(() -> assertThat(calledTimes.get(), equalTo(1))); + assertCalledTimes(calledTimesMap, event, 1); // when a registry requires rollovers after index template updates, the upgrade should occur only if the dependencies are have // the required version registry.setApplyRollover(true); - calledTimes.set(0); + calledTimesMap.values().forEach(calledTimes -> calledTimes.set(0)); registry.clusterChanged(event); Thread.sleep(100L); - assertThat(calledTimes.get(), equalTo(0)); + assertCalledTimes(calledTimesMap, event, 0); event = createClusterChangedEvent(Collections.singletonMap("custom-plugin-settings", 3), nodes); registry.clusterChanged(event); - assertBusy(() -> assertThat(calledTimes.get(), equalTo(1))); + assertCalledTimes(calledTimesMap, event, 1); } public void testThatTemplatesAreUpgradedWhenNeeded() throws Exception { DiscoveryNode node = DiscoveryNodeUtils.create("node"); DiscoveryNodes nodes = DiscoveryNodes.builder().localNodeId("node").masterNodeId("node").add(node).build(); - AtomicInteger calledTimes = new AtomicInteger(0); - client.setVerifier((action, request, listener) -> { + Map calledTimesMap = new ConcurrentHashMap<>(); + client.setVerifier((projectId, action, request, listener) -> { + final var calledTimes = calledTimesMap.computeIfAbsent(projectId, k -> new AtomicInteger(0)); if (action == PutPipelineTransportAction.TYPE) { assertPutPipelineAction( calledTimes, @@ -324,7 +342,7 @@ public class IndexTemplateRegistryTests extends ESTestCase { nodes ); registry.clusterChanged(event); - assertBusy(() -> assertThat(calledTimes.get(), equalTo(4))); + assertCalledTimes(calledTimesMap, event, 4); } public void testAutomaticRollover() throws Exception { @@ -338,11 +356,12 @@ public class IndexTemplateRegistryTests extends ESTestCase { nodes ); Map composableTemplateConfigs = registry.getComposableTemplateConfigs(); + final var metadataBuilder = Metadata.builder(state.metadata()); for (Map.Entry entry : composableTemplateConfigs.entrySet()) { ComposableIndexTemplate template = entry.getValue(); - state = ClusterState.builder(state) - .metadata( - Metadata.builder(Objects.requireNonNull(state).metadata()) + for (var project : state.metadata().projects().values()) { + metadataBuilder.put( + metadataBuilder.getProject(project.id()) .put( entry.getKey(), ComposableIndexTemplate.builder() @@ -355,84 +374,100 @@ public class IndexTemplateRegistryTests extends ESTestCase { .dataStreamTemplate(template.getDataStreamTemplate()) .build() ) - ) - .build(); + ); + } } - state = ClusterState.builder(state) - .metadata( - Metadata.builder(Objects.requireNonNull(state).metadata()) + for (var project : state.metadata().projects().values()) { + metadataBuilder.put( + metadataBuilder.getProject(project.id()) .put(DataStreamTestHelper.newInstance("logs-my_app-1", Collections.singletonList(new Index(".ds-ds1-000001", "ds1i")))) .put(DataStreamTestHelper.newInstance("logs-my_app-2", Collections.singletonList(new Index(".ds-ds2-000001", "ds2i")))) .put( DataStreamTestHelper.newInstance("traces-my_app-1", Collections.singletonList(new Index(".ds-ds3-000001", "ds3i"))) ) - ) - .build(); + ); + } + state = ClusterState.builder(state).metadata(metadataBuilder).build(); ClusterChangedEvent event = createClusterChangedEvent(nodes, state); - AtomicInteger rolloverCounter = new AtomicInteger(0); - AtomicInteger putIndexTemplateCounter = new AtomicInteger(0); - client.setVerifier((action, request, listener) -> { + Map rolloverCounterMap = new ConcurrentHashMap<>(); + Map putIndexTemplateCounterMap = new ConcurrentHashMap<>(); + client.setVerifier((projectId, action, request, listener) -> { if (action instanceof RolloverAction) { + final var rolloverCounter = rolloverCounterMap.computeIfAbsent(projectId, k -> new AtomicInteger(0)); rolloverCounter.incrementAndGet(); RolloverRequest rolloverRequest = ((RolloverRequest) request); assertThat(rolloverRequest.getRolloverTarget(), startsWith("logs-my_app-")); assertThat(rolloverRequest.isLazy(), equalTo(true)); } else if (action == TransportPutComposableIndexTemplateAction.TYPE) { + final var putIndexTemplateCounter = putIndexTemplateCounterMap.computeIfAbsent(projectId, k -> new AtomicInteger(0)); putIndexTemplateCounter.incrementAndGet(); } return AcknowledgedResponse.TRUE; }); registry.clusterChanged(event); - assertBusy(() -> assertThat(putIndexTemplateCounter.get(), equalTo(1))); + assertCalledTimes(putIndexTemplateCounterMap, event, 1); // no rollover on upgrade because the test registry doesn't support automatic rollover by default Thread.sleep(100L); - assertThat(rolloverCounter.get(), equalTo(0)); + assertCalledTimes(rolloverCounterMap, event, 0); // test successful rollovers registry.setApplyRollover(true); - putIndexTemplateCounter.set(0); + putIndexTemplateCounterMap.values().forEach(calledTimes -> calledTimes.set(0)); registry.clusterChanged(event); - assertBusy(() -> assertThat(putIndexTemplateCounter.get(), equalTo(1))); - assertBusy(() -> assertThat(rolloverCounter.get(), equalTo(2))); - AtomicReference> rolloverResponsesRef = registry.getRolloverResponses(); - assertBusy(() -> assertNotNull(rolloverResponsesRef.get())); - assertThat(rolloverResponsesRef.get(), hasSize(2)); + assertCalledTimes(putIndexTemplateCounterMap, event, 1); + assertCalledTimes(rolloverCounterMap, event, 2); + var rolloverResponsesRef = registry.getRolloverResponses(); + var projectIds = state.metadata().projects().keySet(); + assertBusy(() -> { + assertThat(rolloverResponsesRef.keySet(), equalTo(projectIds)); + for (var rolloverResponses : rolloverResponsesRef.values()) { + assertNotNull(rolloverResponses.get()); + assertThat(rolloverResponses.get(), hasSize(2)); + } + }); // test again, to verify that the per-index-template creation lock gets released for reuse - putIndexTemplateCounter.set(0); - rolloverCounter.set(0); - rolloverResponsesRef.set(Collections.emptySet()); + putIndexTemplateCounterMap.values().forEach(calledTimes -> calledTimes.set(0)); + rolloverCounterMap.values().forEach(calledTimes -> calledTimes.set(0)); + rolloverResponsesRef.values().forEach(v -> v.set(Set.of())); registry.clusterChanged(event); - assertBusy(() -> assertThat(putIndexTemplateCounter.get(), equalTo(1))); - assertBusy(() -> assertThat(rolloverCounter.get(), equalTo(2))); - assertBusy(() -> assertThat(rolloverResponsesRef.get(), hasSize(2))); + assertCalledTimes(putIndexTemplateCounterMap, event, 1); + assertCalledTimes(rolloverCounterMap, event, 2); + assertBusy(() -> rolloverResponsesRef.values().forEach(v -> assertThat(v.get(), hasSize(2)))); // test rollover failures - putIndexTemplateCounter.set(0); - rolloverCounter.set(0); - client.setVerifier((action, request, listener) -> { + putIndexTemplateCounterMap.values().forEach(calledTimes -> calledTimes.set(0)); + rolloverCounterMap.values().forEach(calledTimes -> calledTimes.set(0)); + client.setVerifier((projectId, action, request, listener) -> { if (action instanceof RolloverAction) { + final var rolloverCounter = rolloverCounterMap.computeIfAbsent(projectId, k -> new AtomicInteger(0)); rolloverCounter.incrementAndGet(); RolloverRequest rolloverRequest = ((RolloverRequest) request); assertThat(rolloverRequest.getRolloverTarget(), startsWith("logs-my_app-")); throw new RuntimeException("Failed to rollover " + rolloverRequest.getRolloverTarget()); } else if (action == TransportPutComposableIndexTemplateAction.TYPE) { + final var putIndexTemplateCounter = putIndexTemplateCounterMap.computeIfAbsent(projectId, k -> new AtomicInteger(0)); putIndexTemplateCounter.incrementAndGet(); } return AcknowledgedResponse.TRUE; }); registry.clusterChanged(event); - assertBusy(() -> assertThat(putIndexTemplateCounter.get(), equalTo(1))); - assertBusy(() -> assertThat(rolloverCounter.get(), equalTo(2))); - AtomicReference rolloverFailureRef = registry.getRolloverFailure(); - assertBusy(() -> assertNotNull(rolloverFailureRef.get())); - Exception rolloverFailure = rolloverFailureRef.get(); - assertThat(rolloverFailure.getMessage(), startsWith("Failed to rollover logs-my_app-")); - Throwable[] suppressed = rolloverFailure.getSuppressed(); - assertThat(suppressed.length, equalTo(1)); - assertThat(suppressed[0].getMessage(), startsWith("Failed to rollover logs-my_app-")); + assertCalledTimes(putIndexTemplateCounterMap, event, 1); + assertCalledTimes(rolloverCounterMap, event, 2); + var rolloverFailureRefMap = registry.getRolloverFailure(); + assertBusy(() -> { + assertThat(rolloverFailureRefMap.keySet(), equalTo(projectIds)); + rolloverFailureRefMap.values().forEach(rolloverFailureRef -> { + assertNotNull(rolloverFailureRef.get()); + Exception rolloverFailure = rolloverFailureRef.get(); + assertThat(rolloverFailure.getMessage(), startsWith("Failed to rollover logs-my_app-")); + Throwable[] suppressed = rolloverFailure.getSuppressed(); + assertThat(suppressed.length, equalTo(1)); + assertThat(suppressed[0].getMessage(), startsWith("Failed to rollover logs-my_app-")); + }); + }); } public void testRolloverForFreshInstalledIndexTemplate() throws Exception { @@ -445,26 +480,30 @@ public class IndexTemplateRegistryTests extends ESTestCase { Map.of("custom-plugin-default_pipeline", 3, "custom-plugin-final_pipeline", 3), nodes ); - state = ClusterState.builder(state) - .metadata( - Metadata.builder(Objects.requireNonNull(state).metadata()) + final var metadataBuilder = Metadata.builder(state.metadata()); + for (var project : state.metadata().projects().values()) { + metadataBuilder.put( + metadataBuilder.getProject(project.id()) .put(DataStreamTestHelper.newInstance("logs-my_app-1", Collections.singletonList(new Index(".ds-ds1-000001", "ds1i")))) .put(DataStreamTestHelper.newInstance("logs-my_app-2", Collections.singletonList(new Index(".ds-ds2-000001", "ds2i")))) .put( DataStreamTestHelper.newInstance("traces-my_app-1", Collections.singletonList(new Index(".ds-ds3-000001", "ds3i"))) ) - ) - .build(); + ); + } + state = ClusterState.builder(state).metadata(metadataBuilder).build(); ClusterChangedEvent event = createClusterChangedEvent(nodes, state); - AtomicInteger rolloverCounter = new AtomicInteger(0); - AtomicInteger putIndexTemplateCounter = new AtomicInteger(0); - client.setVerifier((action, request, listener) -> { + Map rolloverCounterMap = new ConcurrentHashMap<>(); + Map putIndexTemplateCounterMap = new ConcurrentHashMap<>(); + client.setVerifier((projectId, action, request, listener) -> { if (action instanceof RolloverAction) { + final var rolloverCounter = rolloverCounterMap.computeIfAbsent(projectId, k -> new AtomicInteger(0)); rolloverCounter.incrementAndGet(); RolloverRequest rolloverRequest = ((RolloverRequest) request); assertThat(rolloverRequest.getRolloverTarget(), startsWith("logs-my_app-")); } else if (action == TransportPutComposableIndexTemplateAction.TYPE) { + final var putIndexTemplateCounter = putIndexTemplateCounterMap.computeIfAbsent(projectId, k -> new AtomicInteger(0)); putIndexTemplateCounter.incrementAndGet(); } return AcknowledgedResponse.TRUE; @@ -472,18 +511,18 @@ public class IndexTemplateRegistryTests extends ESTestCase { registry.setApplyRollover(true); registry.clusterChanged(event); - assertBusy(() -> assertThat(putIndexTemplateCounter.get(), equalTo(1))); + assertCalledTimes(putIndexTemplateCounterMap, event, 1); // rollover should be triggered even for the first installation, since the template // may now take precedence over a data stream's existing index template - assertBusy(() -> assertThat(rolloverCounter.get(), equalTo(2))); + assertCalledTimes(rolloverCounterMap, event, 2); } public void testThatTemplatesAreNotUpgradedWhenNotNeeded() throws Exception { DiscoveryNode node = DiscoveryNodeUtils.create("node"); DiscoveryNodes nodes = DiscoveryNodes.builder().localNodeId("node").masterNodeId("node").add(node).build(); - AtomicInteger calledTimes = new AtomicInteger(0); - client.setVerifier((action, request, listener) -> { + Map calledTimesMap = new ConcurrentHashMap<>(); + client.setVerifier((projectId, action, request, listener) -> { if (action == TransportPutComposableIndexTemplateAction.TYPE) { // ignore this return AcknowledgedResponse.TRUE; @@ -503,19 +542,20 @@ public class IndexTemplateRegistryTests extends ESTestCase { nodes ); registry.clusterChanged(event); - assertBusy(() -> assertThat(calledTimes.get(), equalTo(0))); + assertCalledTimes(calledTimesMap, event, 0); } public void testThatNonExistingPoliciesAreAddedImmediately() throws Exception { DiscoveryNode node = DiscoveryNodeUtils.create("node"); DiscoveryNodes nodes = DiscoveryNodes.builder().localNodeId("node").masterNodeId("node").add(node).build(); - AtomicInteger calledTimes = new AtomicInteger(0); - client.setVerifier((action, request, listener) -> { + Map calledTimesMap = new ConcurrentHashMap<>(); + client.setVerifier((projectId, action, request, listener) -> { if (action == TransportPutComposableIndexTemplateAction.TYPE) { // ignore this return AcknowledgedResponse.TRUE; } else if (action == ILMActions.PUT) { + final var calledTimes = calledTimesMap.computeIfAbsent(projectId, k -> new AtomicInteger(0)); assertPutLifecycleAction(calledTimes, action, request, listener); return AcknowledgedResponse.TRUE; } else { @@ -531,7 +571,7 @@ public class IndexTemplateRegistryTests extends ESTestCase { nodes ); registry.clusterChanged(event); - assertBusy(() -> assertThat(calledTimes.get(), equalTo(registry.getLifecyclePolicies().size()))); + assertCalledTimes(calledTimesMap, event, registry.getLifecyclePolicies().size()); } public void testPolicyAlreadyExists() { @@ -543,7 +583,7 @@ public class IndexTemplateRegistryTests extends ESTestCase { assertThat(policies, hasSize(1)); policies.forEach(p -> policyMap.put(p.getName(), p)); - client.setVerifier((action, request, listener) -> { + client.setVerifier((projectId, action, request, listener) -> { if (action == TransportPutComposableIndexTemplateAction.TYPE) { // ignore this return AcknowledgedResponse.TRUE; @@ -575,7 +615,7 @@ public class IndexTemplateRegistryTests extends ESTestCase { assertThat(policies, hasSize(1)); policies.forEach(p -> policyMap.put(p.getName(), p)); - client.setVerifier((action, request, listener) -> { + client.setVerifier((projectId, action, request, listener) -> { if (action == TransportPutComposableIndexTemplateAction.TYPE) { // ignore this return AcknowledgedResponse.TRUE; @@ -627,12 +667,13 @@ public class IndexTemplateRegistryTests extends ESTestCase { assertThat(policies, hasSize(1)); policies.forEach(p -> policyMap.put(p.getName(), p)); - AtomicInteger calledTimes = new AtomicInteger(0); - client.setVerifier((action, request, listener) -> { + Map calledTimesMap = new ConcurrentHashMap<>(); + client.setVerifier((projectId, action, request, listener) -> { if (action == TransportPutComposableIndexTemplateAction.TYPE) { // ignore this return AcknowledgedResponse.TRUE; } else if (action == ILMActions.PUT) { + final var calledTimes = calledTimesMap.computeIfAbsent(projectId, k -> new AtomicInteger(0)); assertPutLifecycleAction(calledTimes, action, request, listener); return AcknowledgedResponse.TRUE; @@ -669,7 +710,7 @@ public class IndexTemplateRegistryTests extends ESTestCase { ); registry.clusterChanged(event); // we've changed one policy that should be upgraded - assertBusy(() -> assertThat(calledTimes.get(), equalTo(1))); + assertCalledTimes(calledTimesMap, event, 1); } } @@ -749,6 +790,18 @@ public class IndexTemplateRegistryTests extends ESTestCase { calledTimes.incrementAndGet(); } + private static void assertCalledTimes(Map calledTimesMap, ClusterChangedEvent event, int expectedTimes) + throws Exception { + assertBusy(() -> { + if (expectedTimes > 0) { + assertThat(calledTimesMap.keySet(), equalTo(event.state().metadata().projects().keySet())); + } + for (var calledTimes : calledTimesMap.values()) { + assertThat(calledTimes.get(), equalTo(expectedTimes)); + } + }); + } + private ClusterChangedEvent createClusterChangedEvent(Map existingTemplates, DiscoveryNodes nodes) { return createClusterChangedEvent(existingTemplates, Collections.emptyMap(), Collections.emptyMap(), nodes); } @@ -810,10 +863,21 @@ public class IndexTemplateRegistryTests extends ESTestCase { return ClusterState.builder(new ClusterName("test")) .metadata( Metadata.builder() - .componentTemplates(componentTemplates) .transientSettings(Settings.EMPTY) - .putCustom(IndexLifecycleMetadata.TYPE, ilmMeta) - .putCustom(IngestMetadata.TYPE, ingestMetadata) + .put( + ProjectMetadata.builder(Metadata.DEFAULT_PROJECT_ID) + .componentTemplates(componentTemplates) + .putCustom(IndexLifecycleMetadata.TYPE, ilmMeta) + .putCustom(IngestMetadata.TYPE, ingestMetadata) + .build() + ) + .put( + ProjectMetadata.builder(projectId) + .componentTemplates(componentTemplates) + .putCustom(IndexLifecycleMetadata.TYPE, ilmMeta) + .putCustom(IngestMetadata.TYPE, ingestMetadata) + .build() + ) .build() ) .blocks(new ClusterBlocks.Builder().build()) @@ -872,7 +936,7 @@ public class IndexTemplateRegistryTests extends ESTestCase { */ public static class VerifyingClient extends NoOpClient { - private TriFunction, ActionRequest, ActionListener, ActionResponse> verifier = (a, r, l) -> { + private Verifier verifier = (p, a, r, l) -> { fail("verifier not set"); return null; }; @@ -889,15 +953,22 @@ public class IndexTemplateRegistryTests extends ESTestCase { ActionListener listener ) { try { - listener.onResponse((Response) verifier.apply(action, request, listener)); + final ProjectId projectId = ProjectId.fromId( + threadPool().getThreadContext().getHeader(Task.X_ELASTIC_PROJECT_ID_HTTP_HEADER) + ); + listener.onResponse((Response) verifier.verify(projectId, action, request, listener)); } catch (Exception e) { listener.onFailure(e); } } - public VerifyingClient setVerifier(TriFunction, ActionRequest, ActionListener, ActionResponse> verifier) { + public VerifyingClient setVerifier(Verifier verifier) { this.verifier = verifier; return this; } } + + private interface Verifier { + ActionResponse verify(ProjectId projectId, ActionType action, ActionRequest request, ActionListener listener); + } } diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/template/TestRegistryWithCustomPlugin.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/template/TestRegistryWithCustomPlugin.java index 2ef0c7f5301e..bc3ea9ed445a 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/template/TestRegistryWithCustomPlugin.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/template/TestRegistryWithCustomPlugin.java @@ -11,6 +11,8 @@ import org.elasticsearch.action.admin.indices.rollover.RolloverResponse; import org.elasticsearch.client.internal.Client; import org.elasticsearch.cluster.metadata.ComponentTemplate; import org.elasticsearch.cluster.metadata.ComposableIndexTemplate; +import org.elasticsearch.cluster.metadata.ProjectId; +import org.elasticsearch.cluster.project.ProjectResolver; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.threadpool.ThreadPool; @@ -24,6 +26,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; @@ -35,17 +38,21 @@ class TestRegistryWithCustomPlugin extends IndexTemplateRegistry { private final AtomicBoolean policyUpgradeRequired = new AtomicBoolean(false); private final AtomicBoolean applyRollover = new AtomicBoolean(false); - private final AtomicReference> rolloverResponses = new AtomicReference<>(); - private final AtomicReference rolloverFailure = new AtomicReference<>(); + private final Map>> rolloverResponses = new ConcurrentHashMap<>(); + private final Map> rolloverFailure = new ConcurrentHashMap<>(); + + private final ThreadPool threadPool; TestRegistryWithCustomPlugin( Settings nodeSettings, ClusterService clusterService, ThreadPool threadPool, Client client, - NamedXContentRegistry xContentRegistry + NamedXContentRegistry xContentRegistry, + ProjectResolver projectResolver ) { - super(nodeSettings, clusterService, threadPool, client, xContentRegistry); + super(nodeSettings, clusterService, threadPool, client, xContentRegistry, projectResolver); + this.threadPool = threadPool; } @Override @@ -127,20 +134,20 @@ class TestRegistryWithCustomPlugin extends IndexTemplateRegistry { } @Override - void onRolloversBulkResponse(Collection rolloverResponses) { - this.rolloverResponses.set(rolloverResponses); + void onRolloversBulkResponse(ProjectId projectId, Collection rolloverResponses) { + this.rolloverResponses.computeIfAbsent(projectId, k -> new AtomicReference<>()).set(rolloverResponses); } - public AtomicReference> getRolloverResponses() { + public Map>> getRolloverResponses() { return rolloverResponses; } @Override - void onRolloverFailure(Exception e) { - rolloverFailure.set(e); + void onRolloverFailure(ProjectId projectId, Exception e) { + rolloverFailure.computeIfAbsent(projectId, k -> new AtomicReference<>()).set(e); } - public AtomicReference getRolloverFailure() { + public Map> getRolloverFailure() { return rolloverFailure; } diff --git a/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/Deprecation.java b/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/Deprecation.java index fc289553296a..36312964dc65 100644 --- a/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/Deprecation.java +++ b/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/Deprecation.java @@ -85,7 +85,8 @@ public class Deprecation extends Plugin implements ActionPlugin { services.clusterService(), services.threadPool(), services.client(), - services.xContentRegistry() + services.xContentRegistry(), + services.projectResolver() ); templateRegistry.initialize(); diff --git a/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/logging/DeprecationIndexingTemplateRegistry.java b/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/logging/DeprecationIndexingTemplateRegistry.java index 4e5f75461316..ae995aca06c0 100644 --- a/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/logging/DeprecationIndexingTemplateRegistry.java +++ b/x-pack/plugin/deprecation/src/main/java/org/elasticsearch/xpack/deprecation/logging/DeprecationIndexingTemplateRegistry.java @@ -10,6 +10,7 @@ package org.elasticsearch.xpack.deprecation.logging; import org.elasticsearch.client.internal.Client; import org.elasticsearch.cluster.metadata.ComponentTemplate; import org.elasticsearch.cluster.metadata.ComposableIndexTemplate; +import org.elasticsearch.cluster.project.ProjectResolver; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.threadpool.ThreadPool; @@ -49,9 +50,10 @@ public class DeprecationIndexingTemplateRegistry extends IndexTemplateRegistry { ClusterService clusterService, ThreadPool threadPool, Client client, - NamedXContentRegistry xContentRegistry + NamedXContentRegistry xContentRegistry, + ProjectResolver projectResolver ) { - super(nodeSettings, clusterService, threadPool, client, xContentRegistry); + super(nodeSettings, clusterService, threadPool, client, xContentRegistry, projectResolver); } private static final Map COMPONENT_TEMPLATE_CONFIGS; diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/EnterpriseSearch.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/EnterpriseSearch.java index ced2fd600a26..0a96672aa2a3 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/EnterpriseSearch.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/EnterpriseSearch.java @@ -469,7 +469,8 @@ public class EnterpriseSearch extends Plugin implements ActionPlugin, SystemInde services.clusterService(), services.threadPool(), services.client(), - services.xContentRegistry() + services.xContentRegistry(), + services.projectResolver() ); analyticsTemplateRegistry.initialize(); @@ -478,7 +479,8 @@ public class EnterpriseSearch extends Plugin implements ActionPlugin, SystemInde services.clusterService(), services.threadPool(), services.client(), - services.xContentRegistry() + services.xContentRegistry(), + services.projectResolver() ); connectorTemplateRegistry.initialize(); diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/analytics/AnalyticsTemplateRegistry.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/analytics/AnalyticsTemplateRegistry.java index 18a335378efb..1ef2846f86d5 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/analytics/AnalyticsTemplateRegistry.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/analytics/AnalyticsTemplateRegistry.java @@ -9,6 +9,7 @@ package org.elasticsearch.xpack.application.analytics; import org.elasticsearch.client.internal.Client; import org.elasticsearch.cluster.metadata.ComponentTemplate; import org.elasticsearch.cluster.metadata.ComposableIndexTemplate; +import org.elasticsearch.cluster.project.ProjectResolver; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.core.UpdateForV10; @@ -105,9 +106,10 @@ public class AnalyticsTemplateRegistry extends IndexTemplateRegistry { ClusterService clusterService, ThreadPool threadPool, Client client, - NamedXContentRegistry xContentRegistry + NamedXContentRegistry xContentRegistry, + ProjectResolver projectResolver ) { - super(Settings.EMPTY, clusterService, threadPool, client, xContentRegistry); + super(Settings.EMPTY, clusterService, threadPool, client, xContentRegistry, projectResolver); } @Override diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorTemplateRegistry.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorTemplateRegistry.java index fd35acc89db5..771507fb6990 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorTemplateRegistry.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorTemplateRegistry.java @@ -10,6 +10,7 @@ package org.elasticsearch.xpack.application.connector; import org.elasticsearch.client.internal.Client; import org.elasticsearch.cluster.metadata.ComponentTemplate; import org.elasticsearch.cluster.metadata.ComposableIndexTemplate; +import org.elasticsearch.cluster.project.ProjectResolver; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.threadpool.ThreadPool; @@ -144,9 +145,10 @@ public class ConnectorTemplateRegistry extends IndexTemplateRegistry { ClusterService clusterService, ThreadPool threadPool, Client client, - NamedXContentRegistry xContentRegistry + NamedXContentRegistry xContentRegistry, + ProjectResolver projectResolver ) { - super(Settings.EMPTY, clusterService, threadPool, client, xContentRegistry); + super(Settings.EMPTY, clusterService, threadPool, client, xContentRegistry, projectResolver); } @Override diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/analytics/AnalyticsTemplateRegistryTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/analytics/AnalyticsTemplateRegistryTests.java index fb2fb11c7460..8a1fc5e79bf6 100644 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/analytics/AnalyticsTemplateRegistryTests.java +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/analytics/AnalyticsTemplateRegistryTests.java @@ -25,6 +25,7 @@ import org.elasticsearch.cluster.metadata.Metadata; import org.elasticsearch.cluster.node.DiscoveryNode; 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.TriFunction; import org.elasticsearch.common.bytes.BytesArray; @@ -75,7 +76,13 @@ public class AnalyticsTemplateRegistryTests extends ESTestCase { threadPool = new TestThreadPool(this.getClass().getName()); client = new VerifyingClient(threadPool); ClusterService clusterService = ClusterServiceUtils.createClusterService(threadPool); - registry = new AnalyticsTemplateRegistry(clusterService, threadPool, client, NamedXContentRegistry.EMPTY); + registry = new AnalyticsTemplateRegistry( + clusterService, + threadPool, + client, + NamedXContentRegistry.EMPTY, + TestProjectResolvers.mustExecuteFirst() + ); } @After diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorTemplateRegistryTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorTemplateRegistryTests.java index 068b99626af9..b45c1fbd8f6b 100644 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorTemplateRegistryTests.java +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorTemplateRegistryTests.java @@ -25,6 +25,7 @@ import org.elasticsearch.cluster.metadata.Metadata; import org.elasticsearch.cluster.node.DiscoveryNode; 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.TriFunction; import org.elasticsearch.common.bytes.BytesArray; @@ -78,7 +79,13 @@ public class ConnectorTemplateRegistryTests extends ESTestCase { threadPool = new TestThreadPool(this.getClass().getName()); client = new VerifyingClient(threadPool); ClusterService clusterService = ClusterServiceUtils.createClusterService(threadPool); - registry = new ConnectorTemplateRegistry(clusterService, threadPool, client, NamedXContentRegistry.EMPTY); + registry = new ConnectorTemplateRegistry( + clusterService, + threadPool, + client, + NamedXContentRegistry.EMPTY, + TestProjectResolvers.mustExecuteFirst() + ); } @After diff --git a/x-pack/plugin/fleet/src/main/java/org/elasticsearch/xpack/fleet/Fleet.java b/x-pack/plugin/fleet/src/main/java/org/elasticsearch/xpack/fleet/Fleet.java index c2a5fe1ebb78..ea95cbca1104 100644 --- a/x-pack/plugin/fleet/src/main/java/org/elasticsearch/xpack/fleet/Fleet.java +++ b/x-pack/plugin/fleet/src/main/java/org/elasticsearch/xpack/fleet/Fleet.java @@ -95,7 +95,8 @@ public class Fleet extends Plugin implements SystemIndexPlugin { services.clusterService(), services.threadPool(), services.client(), - services.xContentRegistry() + services.xContentRegistry(), + services.projectResolver() ); registry.initialize(); return List.of(); diff --git a/x-pack/plugin/fleet/src/main/java/org/elasticsearch/xpack/fleet/FleetTemplateRegistry.java b/x-pack/plugin/fleet/src/main/java/org/elasticsearch/xpack/fleet/FleetTemplateRegistry.java index 6585553a1bd9..9e197e991edb 100644 --- a/x-pack/plugin/fleet/src/main/java/org/elasticsearch/xpack/fleet/FleetTemplateRegistry.java +++ b/x-pack/plugin/fleet/src/main/java/org/elasticsearch/xpack/fleet/FleetTemplateRegistry.java @@ -9,6 +9,7 @@ package org.elasticsearch.xpack.fleet; import org.elasticsearch.client.internal.Client; import org.elasticsearch.cluster.metadata.ComposableIndexTemplate; +import org.elasticsearch.cluster.project.ProjectResolver; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.threadpool.ThreadPool; @@ -67,9 +68,10 @@ public class FleetTemplateRegistry extends IndexTemplateRegistry { ClusterService clusterService, ThreadPool threadPool, Client client, - NamedXContentRegistry xContentRegistry + NamedXContentRegistry xContentRegistry, + ProjectResolver projectResolver ) { - super(nodeSettings, clusterService, threadPool, client, xContentRegistry); + super(nodeSettings, clusterService, threadPool, client, xContentRegistry, projectResolver); } @Override diff --git a/x-pack/plugin/identity-provider/src/internalClusterTest/java/org/elasticsearch/xpack/idp/saml/sp/SamlServiceProviderIndexTests.java b/x-pack/plugin/identity-provider/src/internalClusterTest/java/org/elasticsearch/xpack/idp/saml/sp/SamlServiceProviderIndexTests.java index 75c5c21db1bd..14445848a3b9 100644 --- a/x-pack/plugin/identity-provider/src/internalClusterTest/java/org/elasticsearch/xpack/idp/saml/sp/SamlServiceProviderIndexTests.java +++ b/x-pack/plugin/identity-provider/src/internalClusterTest/java/org/elasticsearch/xpack/idp/saml/sp/SamlServiceProviderIndexTests.java @@ -235,7 +235,8 @@ public class SamlServiceProviderIndexTests extends ESSingleNodeTestCase { services.clusterService(), services.threadPool(), services.client(), - services.xContentRegistry() + services.xContentRegistry(), + services.projectResolver() ); indexTemplateRegistry.initialize(); return List.of(indexTemplateRegistry); diff --git a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/IdentityProviderPlugin.java b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/IdentityProviderPlugin.java index 348d531c09d8..8f006fabc2d4 100644 --- a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/IdentityProviderPlugin.java +++ b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/IdentityProviderPlugin.java @@ -84,7 +84,8 @@ public class IdentityProviderPlugin extends Plugin implements ActionPlugin { services.clusterService(), services.threadPool(), services.client(), - services.xContentRegistry() + services.xContentRegistry(), + services.projectResolver() ); indexTemplateRegistry.initialize(); diff --git a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/sp/SamlServiceProviderIndexTemplateRegistry.java b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/sp/SamlServiceProviderIndexTemplateRegistry.java index bd6bdbabbd4f..1e51750a279f 100644 --- a/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/sp/SamlServiceProviderIndexTemplateRegistry.java +++ b/x-pack/plugin/identity-provider/src/main/java/org/elasticsearch/xpack/idp/saml/sp/SamlServiceProviderIndexTemplateRegistry.java @@ -8,6 +8,7 @@ package org.elasticsearch.xpack.idp.saml.sp; import org.elasticsearch.client.internal.Client; +import org.elasticsearch.cluster.project.ProjectResolver; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.threadpool.ThreadPool; @@ -31,9 +32,10 @@ public class SamlServiceProviderIndexTemplateRegistry extends IndexTemplateRegis ClusterService clusterService, ThreadPool threadPool, Client client, - NamedXContentRegistry xContentRegistry + NamedXContentRegistry xContentRegistry, + ProjectResolver projectResolver ) { - super(nodeSettings, clusterService, threadPool, client, xContentRegistry); + super(nodeSettings, clusterService, threadPool, client, xContentRegistry, projectResolver); } @Override diff --git a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycle.java b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycle.java index 6ab321057a05..4561bf6fe6a7 100644 --- a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycle.java +++ b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycle.java @@ -146,7 +146,8 @@ public class IndexLifecycle extends Plugin implements ActionPlugin, HealthPlugin services.clusterService(), services.threadPool(), services.client(), - services.xContentRegistry() + services.xContentRegistry(), + services.projectResolver() ); ilmTemplateRegistry.initialize(); ilmHistoryStore.set( diff --git a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/history/ILMHistoryTemplateRegistry.java b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/history/ILMHistoryTemplateRegistry.java index 5633033e6faa..6411d13bad86 100644 --- a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/history/ILMHistoryTemplateRegistry.java +++ b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/history/ILMHistoryTemplateRegistry.java @@ -9,6 +9,7 @@ package org.elasticsearch.xpack.ilm.history; import org.elasticsearch.client.internal.Client; import org.elasticsearch.cluster.metadata.ComposableIndexTemplate; +import org.elasticsearch.cluster.project.ProjectResolver; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.threadpool.ThreadPool; @@ -55,9 +56,10 @@ public class ILMHistoryTemplateRegistry extends IndexTemplateRegistry { ClusterService clusterService, ThreadPool threadPool, Client client, - NamedXContentRegistry xContentRegistry + NamedXContentRegistry xContentRegistry, + ProjectResolver projectResolver ) { - super(nodeSettings, clusterService, threadPool, client, xContentRegistry); + super(nodeSettings, clusterService, threadPool, client, xContentRegistry, projectResolver); this.ilmHistoryEnabled = LifecycleSettings.LIFECYCLE_HISTORY_INDEX_ENABLED_SETTING.get(nodeSettings); } diff --git a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/history/ILMHistoryStoreTests.java b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/history/ILMHistoryStoreTests.java index 1797f6b10f3c..ffa05403345f 100644 --- a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/history/ILMHistoryStoreTests.java +++ b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/history/ILMHistoryStoreTests.java @@ -25,6 +25,7 @@ import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.LifecycleExecutionState; import org.elasticsearch.cluster.metadata.Metadata; +import org.elasticsearch.cluster.project.TestProjectResolvers; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.TriFunction; import org.elasticsearch.common.settings.ClusterSettings; @@ -80,7 +81,8 @@ public class ILMHistoryStoreTests extends ESTestCase { clusterService, threadPool, client, - NamedXContentRegistry.EMPTY + NamedXContentRegistry.EMPTY, + TestProjectResolvers.mustExecuteFirst() ); ClusterState state = clusterService.state(); ClusterServiceUtils.setState( diff --git a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/MigratePlugin.java b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/MigratePlugin.java index 6d5172756f55..50ee8885ed11 100644 --- a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/MigratePlugin.java +++ b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/MigratePlugin.java @@ -89,7 +89,8 @@ public class MigratePlugin extends Plugin implements ActionPlugin, PersistentTas services.clusterService(), services.threadPool(), services.client(), - services.xContentRegistry() + services.xContentRegistry(), + services.projectResolver() ); registry.initialize(); return List.of(registry); diff --git a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/MigrateTemplateRegistry.java b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/MigrateTemplateRegistry.java index 2a9dc97e1635..752404461df0 100644 --- a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/MigrateTemplateRegistry.java +++ b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/MigrateTemplateRegistry.java @@ -7,6 +7,7 @@ package org.elasticsearch.xpack.migrate; import org.elasticsearch.client.internal.Client; +import org.elasticsearch.cluster.project.ProjectResolver; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.threadpool.ThreadPool; @@ -31,9 +32,10 @@ public class MigrateTemplateRegistry extends IndexTemplateRegistry { ClusterService clusterService, ThreadPool threadPool, Client client, - NamedXContentRegistry xContentRegistry + NamedXContentRegistry xContentRegistry, + ProjectResolver projectResolver ) { - super(nodeSettings, clusterService, threadPool, client, xContentRegistry); + super(nodeSettings, clusterService, threadPool, client, xContentRegistry, projectResolver); } @Override diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/MachineLearning.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/MachineLearning.java index d1992c30dea7..e51146367a6c 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/MachineLearning.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/MachineLearning.java @@ -937,7 +937,8 @@ public class MachineLearning extends Plugin threadPool, client, machineLearningExtension.get().useIlm(), - xContentRegistry + xContentRegistry, + services.projectResolver() ); registry.initialize(); diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/MlIndexTemplateRegistry.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/MlIndexTemplateRegistry.java index 02fcc2b4465f..3ddb7074adb1 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/MlIndexTemplateRegistry.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/MlIndexTemplateRegistry.java @@ -8,6 +8,7 @@ package org.elasticsearch.xpack.ml; import org.elasticsearch.client.internal.Client; import org.elasticsearch.cluster.metadata.ComposableIndexTemplate; +import org.elasticsearch.cluster.project.ProjectResolver; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.threadpool.ThreadPool; @@ -126,9 +127,10 @@ public class MlIndexTemplateRegistry extends IndexTemplateRegistry { ThreadPool threadPool, Client client, boolean useIlm, - NamedXContentRegistry xContentRegistry + NamedXContentRegistry xContentRegistry, + ProjectResolver projectResolver ) { - super(nodeSettings, clusterService, threadPool, client, xContentRegistry); + super(nodeSettings, clusterService, threadPool, client, xContentRegistry, projectResolver); this.useIlm = useIlm; this.composableIndexTemplateConfigs = parseComposableTemplates( anomalyDetectionResultsTemplate(), diff --git a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/MlIndexTemplateRegistryTests.java b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/MlIndexTemplateRegistryTests.java index eafe568d09da..bd5c72fb789f 100644 --- a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/MlIndexTemplateRegistryTests.java +++ b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/MlIndexTemplateRegistryTests.java @@ -20,6 +20,7 @@ import org.elasticsearch.cluster.metadata.ComposableIndexTemplate; import org.elasticsearch.cluster.node.DiscoveryNode; 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.settings.Settings; import org.elasticsearch.common.util.CollectionUtils; @@ -91,7 +92,8 @@ public class MlIndexTemplateRegistryTests extends ESTestCase { threadPool, client, true, - xContentRegistry + xContentRegistry, + TestProjectResolvers.mustExecuteFirst() ); registry.clusterChanged(createClusterChangedEvent(nodes)); @@ -119,7 +121,8 @@ public class MlIndexTemplateRegistryTests extends ESTestCase { threadPool, client, false, - xContentRegistry + xContentRegistry, + TestProjectResolvers.mustExecuteFirst() ); registry.clusterChanged(createClusterChangedEvent(nodes)); diff --git a/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/Monitoring.java b/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/Monitoring.java index 179955b3722f..4a5257f44f5f 100644 --- a/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/Monitoring.java +++ b/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/Monitoring.java @@ -162,7 +162,8 @@ public class Monitoring extends Plugin implements ActionPlugin, ReloadablePlugin clusterService, threadPool, client, - services.xContentRegistry() + services.xContentRegistry(), + services.projectResolver() ); templateRegistry.initialize(); diff --git a/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringTemplateRegistry.java b/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringTemplateRegistry.java index 6a76d6749489..0c8bce6096c5 100644 --- a/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringTemplateRegistry.java +++ b/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringTemplateRegistry.java @@ -11,6 +11,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.elasticsearch.client.internal.Client; import org.elasticsearch.cluster.metadata.ComposableIndexTemplate; +import org.elasticsearch.cluster.project.ProjectResolver; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Settings; @@ -243,9 +244,10 @@ public class MonitoringTemplateRegistry extends IndexTemplateRegistry { ClusterService clusterService, ThreadPool threadPool, Client client, - NamedXContentRegistry xContentRegistry + NamedXContentRegistry xContentRegistry, + ProjectResolver projectResolver ) { - super(nodeSettings, clusterService, threadPool, client, xContentRegistry); + super(nodeSettings, clusterService, threadPool, client, xContentRegistry, projectResolver); this.clusterService = clusterService; this.monitoringTemplatesEnabled = MONITORING_TEMPLATES_ENABLED.get(nodeSettings); } diff --git a/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/MonitoringTemplateRegistryTests.java b/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/MonitoringTemplateRegistryTests.java index 962f76b9e580..97ddfee77c99 100644 --- a/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/MonitoringTemplateRegistryTests.java +++ b/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/MonitoringTemplateRegistryTests.java @@ -24,6 +24,7 @@ import org.elasticsearch.cluster.metadata.Metadata; import org.elasticsearch.cluster.node.DiscoveryNode; 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.TriFunction; import org.elasticsearch.common.settings.Setting; @@ -82,7 +83,14 @@ public class MonitoringTemplateRegistryTests extends ESTestCase { threadPool = new TestThreadPool(this.getClass().getName()); client = new VerifyingClient(threadPool); clusterService = ClusterServiceUtils.createClusterService(threadPool); - registry = new MonitoringTemplateRegistry(Settings.EMPTY, clusterService, threadPool, client, NamedXContentRegistry.EMPTY); + registry = new MonitoringTemplateRegistry( + Settings.EMPTY, + clusterService, + threadPool, + client, + NamedXContentRegistry.EMPTY, + TestProjectResolvers.mustExecuteFirst() + ); } @After @@ -115,7 +123,8 @@ public class MonitoringTemplateRegistryTests extends ESTestCase { clusterService, threadPool, client, - NamedXContentRegistry.EMPTY + NamedXContentRegistry.EMPTY, + TestProjectResolvers.mustExecuteFirst() ); assertThat(disabledRegistry.getLegacyTemplateConfigs(), is(empty())); assertThat(disabledRegistry.getComposableTemplateConfigs(), anEmptyMap()); @@ -194,7 +203,8 @@ public class MonitoringTemplateRegistryTests extends ESTestCase { clusterService, threadPool, client, - NamedXContentRegistry.EMPTY + NamedXContentRegistry.EMPTY, + TestProjectResolvers.mustExecuteFirst() ); testRegistry.clusterChanged(event); } else { diff --git a/x-pack/plugin/otel-data/src/main/java/org/elasticsearch/xpack/oteldata/OTelIndexTemplateRegistry.java b/x-pack/plugin/otel-data/src/main/java/org/elasticsearch/xpack/oteldata/OTelIndexTemplateRegistry.java index ca52db9331cf..2ac4e2c4b54d 100644 --- a/x-pack/plugin/otel-data/src/main/java/org/elasticsearch/xpack/oteldata/OTelIndexTemplateRegistry.java +++ b/x-pack/plugin/otel-data/src/main/java/org/elasticsearch/xpack/oteldata/OTelIndexTemplateRegistry.java @@ -8,6 +8,7 @@ package org.elasticsearch.xpack.oteldata; import org.elasticsearch.client.internal.Client; +import org.elasticsearch.cluster.project.ProjectResolver; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.threadpool.ThreadPool; @@ -26,9 +27,10 @@ public class OTelIndexTemplateRegistry extends YamlTemplateRegistry { ClusterService clusterService, ThreadPool threadPool, Client client, - NamedXContentRegistry xContentRegistry + NamedXContentRegistry xContentRegistry, + ProjectResolver projectResolver ) { - super(nodeSettings, clusterService, threadPool, client, xContentRegistry); + super(nodeSettings, clusterService, threadPool, client, xContentRegistry, projectResolver); } @Override diff --git a/x-pack/plugin/otel-data/src/main/java/org/elasticsearch/xpack/oteldata/OTelPlugin.java b/x-pack/plugin/otel-data/src/main/java/org/elasticsearch/xpack/oteldata/OTelPlugin.java index 67bd8c4e002d..26531f766977 100644 --- a/x-pack/plugin/otel-data/src/main/java/org/elasticsearch/xpack/oteldata/OTelPlugin.java +++ b/x-pack/plugin/otel-data/src/main/java/org/elasticsearch/xpack/oteldata/OTelPlugin.java @@ -48,7 +48,14 @@ public class OTelPlugin extends Plugin implements ActionPlugin { Settings settings = services.environment().settings(); ClusterService clusterService = services.clusterService(); registry.set( - new OTelIndexTemplateRegistry(settings, clusterService, services.threadPool(), services.client(), services.xContentRegistry()) + new OTelIndexTemplateRegistry( + settings, + clusterService, + services.threadPool(), + services.client(), + services.xContentRegistry(), + services.projectResolver() + ) ); if (enabled) { OTelIndexTemplateRegistry registryInstance = registry.get(); diff --git a/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/ProfilingPlugin.java b/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/ProfilingPlugin.java index 4c02c802f18d..c44332d4068b 100644 --- a/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/ProfilingPlugin.java +++ b/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/ProfilingPlugin.java @@ -97,7 +97,16 @@ public class ProfilingPlugin extends Plugin implements ActionPlugin { ThreadPool threadPool = services.threadPool(); logger.info("Profiling is {}", enabled ? "enabled" : "disabled"); - registry.set(new ProfilingIndexTemplateRegistry(settings, clusterService, threadPool, client, services.xContentRegistry())); + registry.set( + new ProfilingIndexTemplateRegistry( + settings, + clusterService, + threadPool, + client, + services.xContentRegistry(), + services.projectResolver() + ) + ); indexStateResolver.set(new IndexStateResolver(PROFILING_CHECK_OUTDATED_INDICES.get(settings))); clusterService.getClusterSettings().addSettingsUpdateConsumer(PROFILING_CHECK_OUTDATED_INDICES, this::updateCheckOutdatedIndices); diff --git a/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/persistence/ProfilingIndexTemplateRegistry.java b/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/persistence/ProfilingIndexTemplateRegistry.java index 76e5720552d3..f30fe205d2eb 100644 --- a/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/persistence/ProfilingIndexTemplateRegistry.java +++ b/x-pack/plugin/profiling/src/main/java/org/elasticsearch/xpack/profiling/persistence/ProfilingIndexTemplateRegistry.java @@ -13,6 +13,7 @@ import org.elasticsearch.client.internal.Client; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.ComponentTemplate; import org.elasticsearch.cluster.metadata.ComposableIndexTemplate; +import org.elasticsearch.cluster.project.ProjectResolver; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.threadpool.ThreadPool; @@ -79,9 +80,10 @@ public class ProfilingIndexTemplateRegistry extends IndexTemplateRegistry { ClusterService clusterService, ThreadPool threadPool, Client client, - NamedXContentRegistry xContentRegistry + NamedXContentRegistry xContentRegistry, + ProjectResolver projectResolver ) { - super(nodeSettings, clusterService, threadPool, client, xContentRegistry); + super(nodeSettings, clusterService, threadPool, client, xContentRegistry, projectResolver); } public void setTemplatesEnabled(boolean templatesEnabled) { diff --git a/x-pack/plugin/profiling/src/test/java/org/elasticsearch/xpack/profiling/persistence/ProfilingIndexTemplateRegistryTests.java b/x-pack/plugin/profiling/src/test/java/org/elasticsearch/xpack/profiling/persistence/ProfilingIndexTemplateRegistryTests.java index 81d6ed15804b..3224c2e3a1d0 100644 --- a/x-pack/plugin/profiling/src/test/java/org/elasticsearch/xpack/profiling/persistence/ProfilingIndexTemplateRegistryTests.java +++ b/x-pack/plugin/profiling/src/test/java/org/elasticsearch/xpack/profiling/persistence/ProfilingIndexTemplateRegistryTests.java @@ -25,6 +25,7 @@ import org.elasticsearch.cluster.metadata.Metadata; import org.elasticsearch.cluster.node.DiscoveryNode; 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.settings.Settings; import org.elasticsearch.test.ClusterServiceUtils; @@ -76,7 +77,14 @@ public class ProfilingIndexTemplateRegistryTests extends ESTestCase { threadPool = new TestThreadPool(this.getClass().getName()); client = new VerifyingClient(threadPool); clusterService = ClusterServiceUtils.createClusterService(threadPool); - registry = new ProfilingIndexTemplateRegistry(Settings.EMPTY, clusterService, threadPool, client, NamedXContentRegistry.EMPTY); + registry = new ProfilingIndexTemplateRegistry( + Settings.EMPTY, + clusterService, + threadPool, + client, + NamedXContentRegistry.EMPTY, + TestProjectResolvers.mustExecuteFirst() + ); registry.setTemplatesEnabled(true); } diff --git a/x-pack/plugin/slm/src/main/java/org/elasticsearch/xpack/slm/SnapshotLifecycle.java b/x-pack/plugin/slm/src/main/java/org/elasticsearch/xpack/slm/SnapshotLifecycle.java index cd09696e1934..cf7bf2c85cfd 100644 --- a/x-pack/plugin/slm/src/main/java/org/elasticsearch/xpack/slm/SnapshotLifecycle.java +++ b/x-pack/plugin/slm/src/main/java/org/elasticsearch/xpack/slm/SnapshotLifecycle.java @@ -128,7 +128,8 @@ public class SnapshotLifecycle extends Plugin implements ActionPlugin, HealthPlu clusterService, threadPool, client, - services.xContentRegistry() + services.xContentRegistry(), + services.projectResolver() ); templateRegistry.initialize(); snapshotHistoryStore.set(new SnapshotHistoryStore(new OriginSettingClient(client, INDEX_LIFECYCLE_ORIGIN), clusterService)); diff --git a/x-pack/plugin/slm/src/main/java/org/elasticsearch/xpack/slm/history/SnapshotLifecycleTemplateRegistry.java b/x-pack/plugin/slm/src/main/java/org/elasticsearch/xpack/slm/history/SnapshotLifecycleTemplateRegistry.java index 9757b0c55db7..caca0b198a07 100644 --- a/x-pack/plugin/slm/src/main/java/org/elasticsearch/xpack/slm/history/SnapshotLifecycleTemplateRegistry.java +++ b/x-pack/plugin/slm/src/main/java/org/elasticsearch/xpack/slm/history/SnapshotLifecycleTemplateRegistry.java @@ -10,6 +10,7 @@ package org.elasticsearch.xpack.slm.history; import org.elasticsearch.client.internal.Client; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.ComposableIndexTemplate; +import org.elasticsearch.cluster.project.ProjectResolver; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.threadpool.ThreadPool; @@ -62,9 +63,10 @@ public class SnapshotLifecycleTemplateRegistry extends IndexTemplateRegistry { ClusterService clusterService, ThreadPool threadPool, Client client, - NamedXContentRegistry xContentRegistry + NamedXContentRegistry xContentRegistry, + ProjectResolver projectResolver ) { - super(nodeSettings, clusterService, threadPool, client, xContentRegistry); + super(nodeSettings, clusterService, threadPool, client, xContentRegistry, projectResolver); slmHistoryEnabled = SLM_HISTORY_INDEX_ENABLED_SETTING.get(nodeSettings); } diff --git a/x-pack/plugin/slm/src/test/java/org/elasticsearch/xpack/slm/history/SnapshotLifecycleTemplateRegistryTests.java b/x-pack/plugin/slm/src/test/java/org/elasticsearch/xpack/slm/history/SnapshotLifecycleTemplateRegistryTests.java index 8f25a4e70388..8f0ad858f77c 100644 --- a/x-pack/plugin/slm/src/test/java/org/elasticsearch/xpack/slm/history/SnapshotLifecycleTemplateRegistryTests.java +++ b/x-pack/plugin/slm/src/test/java/org/elasticsearch/xpack/slm/history/SnapshotLifecycleTemplateRegistryTests.java @@ -23,6 +23,7 @@ import org.elasticsearch.cluster.metadata.Metadata; import org.elasticsearch.cluster.node.DiscoveryNode; 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.TriFunction; import org.elasticsearch.common.settings.Settings; @@ -100,7 +101,14 @@ public class SnapshotLifecycleTemplateRegistryTests extends ESTestCase { ) ); xContentRegistry = new NamedXContentRegistry(entries); - registry = new SnapshotLifecycleTemplateRegistry(Settings.EMPTY, clusterService, threadPool, client, xContentRegistry); + registry = new SnapshotLifecycleTemplateRegistry( + Settings.EMPTY, + clusterService, + threadPool, + client, + xContentRegistry, + TestProjectResolvers.mustExecuteFirst() + ); } @After @@ -117,7 +125,8 @@ public class SnapshotLifecycleTemplateRegistryTests extends ESTestCase { clusterService, threadPool, client, - xContentRegistry + xContentRegistry, + TestProjectResolvers.mustExecuteFirst() ); assertThat(disabledRegistry.getComposableTemplateConfigs(), anEmptyMap()); assertThat(disabledRegistry.getLifecyclePolicies(), hasSize(0)); diff --git a/x-pack/plugin/stack/build.gradle b/x-pack/plugin/stack/build.gradle index 58e08ecea07f..f0af1e618cac 100644 --- a/x-pack/plugin/stack/build.gradle +++ b/x-pack/plugin/stack/build.gradle @@ -49,3 +49,15 @@ tasks.named("yamlRestCompatTestTransform") { task -> task.skipTest("stack/10_basic/Test kibana reporting index auto creation", "warning does not exist for compatibility") task.skipTest("cat.shards/10_basic/Help", "sync_id is removed in 9.0") } + +configurations { + basicRestSpecs { + attributes { + attribute(ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE, ArtifactTypeDefinition.DIRECTORY_TYPE) + } + } +} + +artifacts { + basicRestSpecs(new File(projectDir, "src/yamlRestTest/resources/rest-api-spec/test")) +} diff --git a/x-pack/plugin/stack/src/main/java/org/elasticsearch/xpack/stack/LegacyStackTemplateRegistry.java b/x-pack/plugin/stack/src/main/java/org/elasticsearch/xpack/stack/LegacyStackTemplateRegistry.java index c89a8237d40b..5404199299ea 100644 --- a/x-pack/plugin/stack/src/main/java/org/elasticsearch/xpack/stack/LegacyStackTemplateRegistry.java +++ b/x-pack/plugin/stack/src/main/java/org/elasticsearch/xpack/stack/LegacyStackTemplateRegistry.java @@ -12,6 +12,7 @@ import org.apache.logging.log4j.Logger; import org.elasticsearch.client.internal.Client; import org.elasticsearch.cluster.metadata.ComponentTemplate; import org.elasticsearch.cluster.metadata.ComposableIndexTemplate; +import org.elasticsearch.cluster.project.ProjectResolver; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.threadpool.ThreadPool; @@ -91,9 +92,10 @@ public class LegacyStackTemplateRegistry extends IndexTemplateRegistry { ClusterService clusterService, ThreadPool threadPool, Client client, - NamedXContentRegistry xContentRegistry + NamedXContentRegistry xContentRegistry, + ProjectResolver projectResolver ) { - super(nodeSettings, clusterService, threadPool, client, xContentRegistry); + super(nodeSettings, clusterService, threadPool, client, xContentRegistry, projectResolver); this.clusterService = clusterService; this.stackTemplateEnabled = STACK_TEMPLATES_ENABLED.get(nodeSettings); } diff --git a/x-pack/plugin/stack/src/main/java/org/elasticsearch/xpack/stack/StackPlugin.java b/x-pack/plugin/stack/src/main/java/org/elasticsearch/xpack/stack/StackPlugin.java index 73c18a3cc261..3abe06165c22 100644 --- a/x-pack/plugin/stack/src/main/java/org/elasticsearch/xpack/stack/StackPlugin.java +++ b/x-pack/plugin/stack/src/main/java/org/elasticsearch/xpack/stack/StackPlugin.java @@ -33,7 +33,8 @@ public class StackPlugin extends Plugin implements ActionPlugin { services.clusterService(), services.threadPool(), services.client(), - services.xContentRegistry() + services.xContentRegistry(), + services.projectResolver() ); legacyStackTemplateRegistry.initialize(); StackTemplateRegistry stackTemplateRegistry = new StackTemplateRegistry( @@ -41,7 +42,8 @@ public class StackPlugin extends Plugin implements ActionPlugin { services.clusterService(), services.threadPool(), services.client(), - services.xContentRegistry() + services.xContentRegistry(), + services.projectResolver() ); stackTemplateRegistry.initialize(); return List.of(legacyStackTemplateRegistry, stackTemplateRegistry); diff --git a/x-pack/plugin/stack/src/main/java/org/elasticsearch/xpack/stack/StackTemplateRegistry.java b/x-pack/plugin/stack/src/main/java/org/elasticsearch/xpack/stack/StackTemplateRegistry.java index 55d10c38f964..4e6b6c549be2 100644 --- a/x-pack/plugin/stack/src/main/java/org/elasticsearch/xpack/stack/StackTemplateRegistry.java +++ b/x-pack/plugin/stack/src/main/java/org/elasticsearch/xpack/stack/StackTemplateRegistry.java @@ -12,6 +12,7 @@ import org.apache.logging.log4j.Logger; import org.elasticsearch.client.internal.Client; import org.elasticsearch.cluster.metadata.ComponentTemplate; import org.elasticsearch.cluster.metadata.ComposableIndexTemplate; +import org.elasticsearch.cluster.project.ProjectResolver; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Settings; @@ -118,9 +119,10 @@ public class StackTemplateRegistry extends IndexTemplateRegistry { ClusterService clusterService, ThreadPool threadPool, Client client, - NamedXContentRegistry xContentRegistry + NamedXContentRegistry xContentRegistry, + ProjectResolver projectResolver ) { - super(nodeSettings, clusterService, threadPool, client, xContentRegistry); + super(nodeSettings, clusterService, threadPool, client, xContentRegistry, projectResolver); this.clusterService = clusterService; this.stackTemplateEnabled = STACK_TEMPLATES_ENABLED.get(nodeSettings); this.componentTemplateConfigs = loadComponentTemplateConfigs(); diff --git a/x-pack/plugin/stack/src/test/java/org/elasticsearch/xpack/stack/LegacyStackTemplateRegistryTests.java b/x-pack/plugin/stack/src/test/java/org/elasticsearch/xpack/stack/LegacyStackTemplateRegistryTests.java index 654cf494e0e6..5e0b2b321a20 100644 --- a/x-pack/plugin/stack/src/test/java/org/elasticsearch/xpack/stack/LegacyStackTemplateRegistryTests.java +++ b/x-pack/plugin/stack/src/test/java/org/elasticsearch/xpack/stack/LegacyStackTemplateRegistryTests.java @@ -10,6 +10,7 @@ package org.elasticsearch.xpack.stack; import org.elasticsearch.client.internal.Client; import org.elasticsearch.cluster.metadata.ComponentTemplate; import org.elasticsearch.cluster.metadata.ComposableIndexTemplate; +import org.elasticsearch.cluster.project.TestProjectResolvers; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.ingest.PipelineConfiguration; @@ -33,7 +34,14 @@ public class LegacyStackTemplateRegistryTests extends ESTestCase { threadPool = new TestThreadPool(this.getClass().getName()); Client client = new NoOpClient(threadPool); ClusterService clusterService = ClusterServiceUtils.createClusterService(threadPool); - registry = new LegacyStackTemplateRegistry(Settings.EMPTY, clusterService, threadPool, client, NamedXContentRegistry.EMPTY); + registry = new LegacyStackTemplateRegistry( + Settings.EMPTY, + clusterService, + threadPool, + client, + NamedXContentRegistry.EMPTY, + TestProjectResolvers.mustExecuteFirst() + ); } @After diff --git a/x-pack/plugin/stack/src/test/java/org/elasticsearch/xpack/stack/StackRegistryWithNonRequiredTemplates.java b/x-pack/plugin/stack/src/test/java/org/elasticsearch/xpack/stack/StackRegistryWithNonRequiredTemplates.java index 7f674e24658d..553b7ad80f43 100644 --- a/x-pack/plugin/stack/src/test/java/org/elasticsearch/xpack/stack/StackRegistryWithNonRequiredTemplates.java +++ b/x-pack/plugin/stack/src/test/java/org/elasticsearch/xpack/stack/StackRegistryWithNonRequiredTemplates.java @@ -9,6 +9,7 @@ package org.elasticsearch.xpack.stack; import org.elasticsearch.client.internal.Client; import org.elasticsearch.cluster.metadata.ComposableIndexTemplate; +import org.elasticsearch.cluster.project.ProjectResolver; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.threadpool.ThreadPool; @@ -23,9 +24,10 @@ class StackRegistryWithNonRequiredTemplates extends StackTemplateRegistry { ClusterService clusterService, ThreadPool threadPool, Client client, - NamedXContentRegistry xContentRegistry + NamedXContentRegistry xContentRegistry, + ProjectResolver projectResolver ) { - super(nodeSettings, clusterService, threadPool, client, xContentRegistry); + super(nodeSettings, clusterService, threadPool, client, xContentRegistry, projectResolver); } @Override diff --git a/x-pack/plugin/stack/src/test/java/org/elasticsearch/xpack/stack/StackTemplateRegistryTests.java b/x-pack/plugin/stack/src/test/java/org/elasticsearch/xpack/stack/StackTemplateRegistryTests.java index 600c1ccba8ca..313b8d24bd34 100644 --- a/x-pack/plugin/stack/src/test/java/org/elasticsearch/xpack/stack/StackTemplateRegistryTests.java +++ b/x-pack/plugin/stack/src/test/java/org/elasticsearch/xpack/stack/StackTemplateRegistryTests.java @@ -25,6 +25,7 @@ import org.elasticsearch.cluster.metadata.Metadata; import org.elasticsearch.cluster.node.DiscoveryNode; 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.TriFunction; import org.elasticsearch.common.settings.Settings; @@ -84,7 +85,14 @@ public class StackTemplateRegistryTests extends ESTestCase { threadPool = new TestThreadPool(this.getClass().getName()); client = new VerifyingClient(threadPool); clusterService = ClusterServiceUtils.createClusterService(threadPool); - registry = new StackTemplateRegistry(Settings.EMPTY, clusterService, threadPool, client, NamedXContentRegistry.EMPTY); + registry = new StackTemplateRegistry( + Settings.EMPTY, + clusterService, + threadPool, + client, + NamedXContentRegistry.EMPTY, + TestProjectResolvers.mustExecuteFirst() + ); } @After @@ -101,7 +109,8 @@ public class StackTemplateRegistryTests extends ESTestCase { clusterService, threadPool, client, - NamedXContentRegistry.EMPTY + NamedXContentRegistry.EMPTY, + TestProjectResolvers.mustExecuteFirst() ); assertThat(disabledRegistry.getComposableTemplateConfigs(), anEmptyMap()); } @@ -113,7 +122,8 @@ public class StackTemplateRegistryTests extends ESTestCase { clusterService, threadPool, client, - NamedXContentRegistry.EMPTY + NamedXContentRegistry.EMPTY, + TestProjectResolvers.mustExecuteFirst() ); assertThat(disabledRegistry.getComponentTemplateConfigs(), not(anEmptyMap())); assertThat( @@ -357,7 +367,8 @@ public class StackTemplateRegistryTests extends ESTestCase { clusterService, threadPool, client, - NamedXContentRegistry.EMPTY + NamedXContentRegistry.EMPTY, + TestProjectResolvers.mustExecuteFirst() ); DiscoveryNode node = DiscoveryNodeUtils.create("node"); diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java index 68cf0984d380..f6b2370239c5 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java @@ -342,7 +342,8 @@ public class Watcher extends Plugin implements SystemIndexPlugin, ScriptPlugin, clusterService, threadPool, client, - xContentRegistry + xContentRegistry, + services.projectResolver() ); templateRegistry.initialize(); diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/support/WatcherIndexTemplateRegistry.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/support/WatcherIndexTemplateRegistry.java index dca1f2bbc56c..5dd7c242dc36 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/support/WatcherIndexTemplateRegistry.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/support/WatcherIndexTemplateRegistry.java @@ -9,6 +9,7 @@ package org.elasticsearch.xpack.watcher.support; import org.elasticsearch.client.internal.Client; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.ComposableIndexTemplate; +import org.elasticsearch.cluster.project.ProjectResolver; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.threadpool.ThreadPool; @@ -37,9 +38,10 @@ public class WatcherIndexTemplateRegistry extends IndexTemplateRegistry { ClusterService clusterService, ThreadPool threadPool, Client client, - NamedXContentRegistry xContentRegistry + NamedXContentRegistry xContentRegistry, + ProjectResolver projectResolver ) { - super(nodeSettings, clusterService, threadPool, client, xContentRegistry); + super(nodeSettings, clusterService, threadPool, client, xContentRegistry, projectResolver); ilmManagementEnabled = Watcher.USE_ILM_INDEX_MANAGEMENT.get(nodeSettings); } diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/support/WatcherIndexTemplateRegistryTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/support/WatcherIndexTemplateRegistryTests.java index 6d740bc5c5e4..581704036740 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/support/WatcherIndexTemplateRegistryTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/support/WatcherIndexTemplateRegistryTests.java @@ -24,6 +24,8 @@ import org.elasticsearch.cluster.metadata.Metadata; import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.node.DiscoveryNodeUtils; import org.elasticsearch.cluster.node.DiscoveryNodes; +import org.elasticsearch.cluster.project.ProjectResolver; +import org.elasticsearch.cluster.project.TestProjectResolvers; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.concurrent.EsExecutors; @@ -80,6 +82,7 @@ public class WatcherIndexTemplateRegistryTests extends ESTestCase { private ClusterService clusterService; private ThreadPool threadPool; private Client client; + private ProjectResolver projectResolver; @SuppressWarnings("unchecked") @Before @@ -114,7 +117,8 @@ public class WatcherIndexTemplateRegistryTests extends ESTestCase { ) ); xContentRegistry = new NamedXContentRegistry(entries); - registry = new WatcherIndexTemplateRegistry(Settings.EMPTY, clusterService, threadPool, client, xContentRegistry); + projectResolver = TestProjectResolvers.mustExecuteFirst(); + registry = new WatcherIndexTemplateRegistry(Settings.EMPTY, clusterService, threadPool, client, xContentRegistry, projectResolver); } public void testThatNonExistingTemplatesAreAddedImmediately() { @@ -152,7 +156,8 @@ public class WatcherIndexTemplateRegistryTests extends ESTestCase { clusterService, threadPool, client, - xContentRegistry + xContentRegistry, + projectResolver ); ClusterChangedEvent event = createClusterChangedEvent(Settings.EMPTY, Collections.emptyMap(), Collections.emptyMap(), nodes); registry.clusterChanged(event); @@ -204,7 +209,8 @@ public class WatcherIndexTemplateRegistryTests extends ESTestCase { clusterService, threadPool, client, - xContentRegistry + xContentRegistry, + projectResolver ); ClusterChangedEvent event = createClusterChangedEvent(Settings.EMPTY, Collections.emptyMap(), Collections.emptyMap(), nodes); registry.clusterChanged(event); diff --git a/x-pack/qa/multi-project/xpack-rest-tests-with-multiple-projects/build.gradle b/x-pack/qa/multi-project/xpack-rest-tests-with-multiple-projects/build.gradle index 7ec46b747282..44f308946bc0 100644 --- a/x-pack/qa/multi-project/xpack-rest-tests-with-multiple-projects/build.gradle +++ b/x-pack/qa/multi-project/xpack-rest-tests-with-multiple-projects/build.gradle @@ -10,6 +10,7 @@ dependencies { testImplementation(testArtifact(project(":x-pack:plugin:security:qa:service-account"), "javaRestTest")) restXpackTestConfig project(path: ':x-pack:plugin:ilm:qa:rest', configuration: "basicRestSpecs") restXpackTestConfig project(path: ':x-pack:plugin:downsample:qa:rest', configuration: "basicRestSpecs") + restXpackTestConfig project(path: ':x-pack:plugin:stack', configuration: "basicRestSpecs") } // let the yamlRestTests see the classpath of test