Skip to content

Commit ff1c9b7

Browse files
authored
Make IndexTemplateRegistry project-aware (#126986)
Ensures the `IndexTemplatesRegistry` installs resources in every project in the cluster. ES-10055
1 parent 7b95ec4 commit ff1c9b7

File tree

55 files changed

+549
-289
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+549
-289
lines changed

server/src/main/java/org/elasticsearch/cluster/project/ProjectResolver.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.elasticsearch.cluster.metadata.ProjectId;
2222
import org.elasticsearch.cluster.metadata.ProjectMetadata;
2323
import org.elasticsearch.core.CheckedRunnable;
24+
import org.elasticsearch.core.FixForMultiProject;
2425

2526
import java.util.Collection;
2627
import java.util.Objects;
@@ -94,6 +95,7 @@ default Collection<ProjectId> getProjectIds(ClusterState clusterState) {
9495
/**
9596
* Returns a client that executes every request in the context of the given project.
9697
*/
98+
@FixForMultiProject(description = "This recreates a client on every invocation. We should optimize this to be less wasteful")
9799
default Client projectClient(Client baseClient, ProjectId projectId) {
98100
// We only take the shortcut when the given project ID matches the "current" project ID. If it doesn't, we'll let #executeOnProject
99101
// take care of error handling.

test/framework/src/main/java/org/elasticsearch/cluster/project/TestProjectResolvers.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public boolean supportsMultipleProjects() {
6262
public static ProjectResolver mustExecuteFirst() {
6363
return new ProjectResolver() {
6464

65-
private ProjectId enforceProjectId = null;
65+
private volatile ProjectId enforceProjectId = null;
6666

6767
@Override
6868
public ProjectId getProjectId() {
@@ -81,14 +81,16 @@ public Collection<ProjectId> getProjectIds(ClusterState clusterState) {
8181

8282
@Override
8383
public <E extends Exception> void executeOnProject(ProjectId projectId, CheckedRunnable<E> body) throws E {
84-
if (enforceProjectId != null) {
85-
throw new IllegalStateException("Cannot nest calls to executeOnProject");
86-
}
87-
try {
88-
enforceProjectId = projectId;
89-
body.run();
90-
} finally {
91-
enforceProjectId = null;
84+
synchronized (this) {
85+
if (enforceProjectId != null) {
86+
throw new IllegalStateException("Cannot nest calls to executeOnProject");
87+
}
88+
try {
89+
enforceProjectId = projectId;
90+
body.run();
91+
} finally {
92+
enforceProjectId = null;
93+
}
9294
}
9395
}
9496

test/framework/src/main/java/org/elasticsearch/test/rest/ESRestTestCase.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2817,16 +2817,12 @@ protected void assertEmptyProject(String projectId) throws IOException {
28172817
if (indexTemplates != null) {
28182818
var templateNames = indexTemplates.keySet().stream().filter(name -> isXPackTemplate(name) == false).toList();
28192819
assertThat("Project [" + projectId + "] should not have index templates", templateNames, empty());
2820-
} else if (projectId.equals(Metadata.DEFAULT_PROJECT_ID.id())) {
2821-
fail("Expected default project to have standard templates, but was null");
28222820
}
28232821

28242822
final Map<String, Object> componentTemplates = state.evaluate("metadata.component_template.component_template");
28252823
if (componentTemplates != null) {
28262824
var templateNames = componentTemplates.keySet().stream().filter(name -> isXPackTemplate(name) == false).toList();
28272825
assertThat("Project [" + projectId + "] should not have component templates", templateNames, empty());
2828-
} else if (projectId.equals(Metadata.DEFAULT_PROJECT_ID.id())) {
2829-
fail("Expected default project to have standard component templates, but was null");
28302826
}
28312827

28322828
final List<Map<String, ?>> pipelines = state.evaluate("metadata.ingest.pipeline");
@@ -2836,8 +2832,6 @@ protected void assertEmptyProject(String projectId) throws IOException {
28362832
.filter(id -> isXPackIngestPipeline(id) == false)
28372833
.toList();
28382834
assertThat("Project [" + projectId + "] should not have ingest pipelines", pipelineNames, empty());
2839-
} else if (projectId.equals(Metadata.DEFAULT_PROJECT_ID.id())) {
2840-
fail("Expected default project to have standard ingest pipelines, but was null");
28412835
}
28422836

28432837
if (has(ProductFeature.ILM)) {
@@ -2846,8 +2840,6 @@ protected void assertEmptyProject(String projectId) throws IOException {
28462840
var policyNames = new HashSet<>(ilmPolicies.keySet());
28472841
policyNames.removeAll(preserveILMPolicyIds());
28482842
assertThat("Project [" + projectId + "] should not have ILM Policies", policyNames, empty());
2849-
} else if (projectId.equals(Metadata.DEFAULT_PROJECT_ID.id())) {
2850-
fail("Expected default project to have standard ILM policies, but was null");
28512843
}
28522844
}
28532845
}

x-pack/plugin/apm-data/src/main/java/org/elasticsearch/xpack/apmdata/APMIndexTemplateRegistry.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
package org.elasticsearch.xpack.apmdata;
99

1010
import org.elasticsearch.client.internal.Client;
11+
import org.elasticsearch.cluster.project.ProjectResolver;
1112
import org.elasticsearch.cluster.service.ClusterService;
1213
import org.elasticsearch.common.settings.Settings;
1314
import org.elasticsearch.threadpool.ThreadPool;
@@ -32,15 +33,17 @@ public APMIndexTemplateRegistry(
3233
ClusterService clusterService,
3334
ThreadPool threadPool,
3435
Client client,
35-
NamedXContentRegistry xContentRegistry
36+
NamedXContentRegistry xContentRegistry,
37+
ProjectResolver projectResolver
3638
) {
3739
super(
3840
nodeSettings,
3941
clusterService,
4042
threadPool,
4143
client,
4244
xContentRegistry,
43-
templateFilter(isDataStreamsLifecycleOnlyMode(clusterService.getSettings()))
45+
templateFilter(isDataStreamsLifecycleOnlyMode(clusterService.getSettings())),
46+
projectResolver
4447
);
4548
}
4649

x-pack/plugin/apm-data/src/main/java/org/elasticsearch/xpack/apmdata/APMPlugin.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,14 @@ public Collection<?> createComponents(PluginServices services) {
4848
Settings settings = services.environment().settings();
4949
ClusterService clusterService = services.clusterService();
5050
registry.set(
51-
new APMIndexTemplateRegistry(settings, clusterService, services.threadPool(), services.client(), services.xContentRegistry())
51+
new APMIndexTemplateRegistry(
52+
settings,
53+
clusterService,
54+
services.threadPool(),
55+
services.client(),
56+
services.xContentRegistry(),
57+
services.projectResolver()
58+
)
5259
);
5360
if (enabled) {
5461
APMIndexTemplateRegistry registryInstance = registry.get();

x-pack/plugin/apm-data/src/test/java/org/elasticsearch/xpack/apmdata/APMDSLOnlyTests.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.elasticsearch.cluster.metadata.DataStreamLifecycle;
1212
import org.elasticsearch.cluster.node.DiscoveryNode;
1313
import org.elasticsearch.cluster.node.DiscoveryNodeUtils;
14+
import org.elasticsearch.cluster.project.TestProjectResolvers;
1415
import org.elasticsearch.cluster.service.ClusterService;
1516
import org.elasticsearch.common.settings.ClusterSettings;
1617
import org.elasticsearch.common.settings.Settings;
@@ -59,7 +60,8 @@ public void createRegistryAndClient() {
5960
clusterService,
6061
threadPool,
6162
client,
62-
NamedXContentRegistry.EMPTY
63+
NamedXContentRegistry.EMPTY,
64+
TestProjectResolvers.mustExecuteFirst()
6365
);
6466
apmIndexTemplateRegistry.setEnabled(true);
6567
}

x-pack/plugin/apm-data/src/test/java/org/elasticsearch/xpack/apmdata/APMIndexTemplateRegistryTests.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import org.elasticsearch.cluster.node.DiscoveryNode;
2727
import org.elasticsearch.cluster.node.DiscoveryNodeUtils;
2828
import org.elasticsearch.cluster.node.DiscoveryNodes;
29+
import org.elasticsearch.cluster.project.ProjectResolver;
30+
import org.elasticsearch.cluster.project.TestProjectResolvers;
2931
import org.elasticsearch.cluster.service.ClusterService;
3032
import org.elasticsearch.common.settings.ClusterSettings;
3133
import org.elasticsearch.common.settings.Settings;
@@ -89,16 +91,18 @@ public void createRegistryAndClient() {
8991
threadPool = new TestThreadPool(this.getClass().getName());
9092
client = new VerifyingClient(threadPool);
9193
ClusterService clusterService = ClusterServiceUtils.createClusterService(threadPool, clusterSettings);
94+
ProjectResolver projectResolver = TestProjectResolvers.mustExecuteFirst();
9295
stackTemplateRegistryAccessor = new StackTemplateRegistryAccessor(
93-
new StackTemplateRegistry(Settings.EMPTY, clusterService, threadPool, client, NamedXContentRegistry.EMPTY)
96+
new StackTemplateRegistry(Settings.EMPTY, clusterService, threadPool, client, NamedXContentRegistry.EMPTY, projectResolver)
9497
);
9598

9699
apmIndexTemplateRegistry = new APMIndexTemplateRegistry(
97100
Settings.EMPTY,
98101
clusterService,
99102
threadPool,
100103
client,
101-
NamedXContentRegistry.EMPTY
104+
NamedXContentRegistry.EMPTY,
105+
projectResolver
102106
);
103107
apmIndexTemplateRegistry.setEnabled(true);
104108
}

x-pack/plugin/core/src/internalClusterTest/java/org/elasticsearch/xpack/core/template/IndexTemplateRegistryRolloverIT.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import org.elasticsearch.cluster.ClusterChangedEvent;
1818
import org.elasticsearch.cluster.ClusterState;
1919
import org.elasticsearch.cluster.metadata.DataStream;
20+
import org.elasticsearch.cluster.project.TestProjectResolvers;
2021
import org.elasticsearch.cluster.service.ClusterService;
2122
import org.elasticsearch.datastreams.DataStreamsPlugin;
2223
import org.elasticsearch.index.mapper.DateFieldMapper;
@@ -58,7 +59,8 @@ public void setup() {
5859
clusterService.threadPool(),
5960
client,
6061
xContentRegistry(),
61-
3L
62+
3L,
63+
TestProjectResolvers.mustExecuteFirst()
6264
);
6365
registry.initialize();
6466
ensureGreen();

x-pack/plugin/core/src/internalClusterTest/java/org/elasticsearch/xpack/core/template/RolloverEnabledTestTemplateRegistry.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import org.elasticsearch.client.internal.Client;
1111
import org.elasticsearch.cluster.metadata.ComposableIndexTemplate;
12+
import org.elasticsearch.cluster.project.ProjectResolver;
1213
import org.elasticsearch.cluster.service.ClusterService;
1314
import org.elasticsearch.common.settings.Settings;
1415
import org.elasticsearch.threadpool.ThreadPool;
@@ -28,9 +29,10 @@ public RolloverEnabledTestTemplateRegistry(
2829
ThreadPool threadPool,
2930
Client client,
3031
NamedXContentRegistry xContentRegistry,
31-
long version
32+
long version,
33+
ProjectResolver projectResolver
3234
) {
33-
super(nodeSettings, clusterService, threadPool, client, xContentRegistry);
35+
super(nodeSettings, clusterService, threadPool, client, xContentRegistry, projectResolver);
3436
this.version = version;
3537
}
3638

0 commit comments

Comments
 (0)