Skip to content

Commit 7a5d446

Browse files
New per-project only settings can be defined and used by components
1 parent 99577b2 commit 7a5d446

File tree

11 files changed

+646
-25
lines changed

11 files changed

+646
-25
lines changed

server/src/main/java/org/elasticsearch/TransportVersions.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ static TransportVersion def(int id) {
225225
public static final TransportVersion COMPRESS_DELAYABLE_WRITEABLE = def(9_059_0_00);
226226
public static final TransportVersion SYNONYMS_REFRESH_PARAM = def(9_060_0_00);
227227
public static final TransportVersion DOC_FIELDS_AS_LIST = def(9_061_0_00);
228+
public static final TransportVersion PROJECT_METADATA_SETTINGS = def(9_062_00_0);
228229

229230
/*
230231
* STOP! READ THIS FIRST! No, really,

server/src/main/java/org/elasticsearch/cluster/metadata/Metadata.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,8 @@ private MetadataDiff(StreamInput in) throws IOException {
950950
RESERVED_DIFF_VALUE_READER
951951
);
952952

953-
singleProject = new ProjectMetadata.ProjectMetadataDiff(indices, templates, projectCustoms, DiffableUtils.emptyDiff());
953+
singleProject = new ProjectMetadata.ProjectMetadataDiff(indices, templates, projectCustoms,
954+
DiffableUtils.emptyDiff(), Settings.EMPTY_DIFF);
954955
multiProject = null;
955956
} else {
956957
fromNodeBeforeMultiProjectsSupport = false;

server/src/main/java/org/elasticsearch/cluster/metadata/ProjectMetadata.java

Lines changed: 61 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ public class ProjectMetadata implements Iterable<IndexMetadata>, Diffable<Projec
102102
private volatile SortedMap<String, IndexAbstraction> indicesLookup;
103103
private final Map<String, MappingMetadata> mappingsByHash;
104104

105+
private final Settings settings;
106+
105107
private final IndexVersion oldestIndexVersion;
106108

107109
@SuppressWarnings("this-escape")
@@ -122,6 +124,7 @@ private ProjectMetadata(
122124
String[] visibleClosedIndices,
123125
SortedMap<String, IndexAbstraction> indicesLookup,
124126
Map<String, MappingMetadata> mappingsByHash,
127+
Settings settings,
125128
IndexVersion oldestIndexVersion
126129
) {
127130
this.id = id;
@@ -140,6 +143,7 @@ private ProjectMetadata(
140143
this.visibleClosedIndices = visibleClosedIndices;
141144
this.indicesLookup = indicesLookup;
142145
this.mappingsByHash = mappingsByHash;
146+
this.settings = settings;
143147
this.oldestIndexVersion = oldestIndexVersion;
144148
assert assertConsistent();
145149
}
@@ -221,8 +225,8 @@ public ProjectMetadata withLifecycleState(Index index, LifecycleExecutionState l
221225
visibleClosedIndices,
222226
indicesLookup,
223227
mappingsByHash,
224-
oldestIndexVersion
225-
);
228+
settings,
229+
oldestIndexVersion);
226230
}
227231

228232
public ProjectMetadata withIndexSettingsUpdates(Map<Index, Settings> updates) {
@@ -254,8 +258,8 @@ public ProjectMetadata withIndexSettingsUpdates(Map<Index, Settings> updates) {
254258
visibleClosedIndices,
255259
indicesLookup,
256260
mappingsByHash,
257-
oldestIndexVersion
258-
);
261+
settings,
262+
oldestIndexVersion);
259263
}
260264

261265
/**
@@ -288,8 +292,8 @@ public ProjectMetadata withAllocationAndTermUpdatesOnly(Map<String, IndexMetadat
288292
visibleClosedIndices,
289293
indicesLookup,
290294
mappingsByHash,
291-
oldestIndexVersion
292-
);
295+
settings,
296+
oldestIndexVersion);
293297
}
294298

295299
/**
@@ -376,8 +380,8 @@ public ProjectMetadata withAddedIndex(IndexMetadata index) {
376380
updatedVisibleClosedIndices,
377381
null,
378382
updatedMappingsByHash,
379-
IndexVersion.min(index.getCompatibilityVersion(), oldestIndexVersion)
380-
);
383+
settings,
384+
IndexVersion.min(index.getCompatibilityVersion(), oldestIndexVersion));
381385
}
382386

383387
private ImmutableOpenMap<String, Set<Index>> aliasesAfterAddingIndex(IndexMetadata index, Map<String, AliasMetadata> aliases) {
@@ -727,6 +731,10 @@ public Map<String, IndexTemplateMetadata> templates() {
727731
return templates;
728732
}
729733

734+
public Settings settings() {
735+
return settings;
736+
}
737+
730738
/**
731739
* Checks whether the provided index is a data stream.
732740
*/
@@ -1130,6 +1138,7 @@ public static class Builder {
11301138
private final ImmutableOpenMap.Builder<String, IndexTemplateMetadata> templates;
11311139
private final ImmutableOpenMap.Builder<String, Metadata.ProjectCustom> customs;
11321140
private final ImmutableOpenMap.Builder<String, ReservedStateMetadata> reservedStateMetadata;
1141+
private Settings settings = Settings.EMPTY;
11331142

11341143
private SortedMap<String, IndexAbstraction> previousIndicesLookup;
11351144

@@ -1147,6 +1156,7 @@ public static class Builder {
11471156
this.templates = ImmutableOpenMap.builder(projectMetadata.templates);
11481157
this.customs = ImmutableOpenMap.builder(projectMetadata.customs);
11491158
this.reservedStateMetadata = ImmutableOpenMap.builder(projectMetadata.reservedStateMetadata);
1159+
this.settings = projectMetadata.settings;
11501160
this.previousIndicesLookup = projectMetadata.indicesLookup;
11511161
this.mappingsByHash = new HashMap<>(projectMetadata.mappingsByHash);
11521162
this.checkForUnusedMappings = false;
@@ -1525,6 +1535,15 @@ public Builder removeReservedState(ReservedStateMetadata metadata) {
15251535
return this;
15261536
}
15271537

1538+
public Settings settings() {
1539+
return this.settings;
1540+
}
1541+
1542+
public ProjectMetadata.Builder settings(Settings settings) {
1543+
this.settings = settings;
1544+
return this;
1545+
}
1546+
15281547
public Builder indexGraveyard(final IndexGraveyard indexGraveyard) {
15291548
return putCustom(IndexGraveyard.TYPE, indexGraveyard);
15301549
}
@@ -1684,8 +1703,8 @@ public ProjectMetadata build(boolean skipNameCollisionChecks) {
16841703
visibleClosedIndicesArray,
16851704
indicesLookup,
16861705
Collections.unmodifiableMap(mappingsByHash),
1687-
IndexVersion.fromId(oldestIndexVersionId)
1688-
);
1706+
settings,
1707+
IndexVersion.fromId(oldestIndexVersionId));
16891708
}
16901709

16911710
static void ensureNoNameCollisions(
@@ -2110,6 +2129,9 @@ public static ProjectMetadata fromXContent(XContentParser parser) throws IOExcep
21102129
projectBuilder.put(IndexTemplateMetadata.Builder.fromXContent(parser, parser.currentName()));
21112130
}
21122131
}
2132+
case "settings" -> {
2133+
projectBuilder.settings(Settings.fromXContent(parser));
2134+
}
21132135
default -> Metadata.Builder.parseCustomObject(
21142136
parser,
21152137
currentFieldName,
@@ -2157,6 +2179,9 @@ public Iterator<? extends ToXContent> toXContentChunked(ToXContent.Params p) {
21572179
customs,
21582180
multiProject
21592181
? ChunkedToXContentHelper.object("reserved_state", reservedStateMetadata().values().iterator())
2182+
: Collections.emptyIterator(),
2183+
multiProject
2184+
? ChunkedToXContentHelper.object("settings", Iterators.single(settings))
21602185
: Collections.emptyIterator()
21612186
);
21622187
}
@@ -2189,6 +2214,10 @@ public static ProjectMetadata readFrom(StreamInput in) throws IOException {
21892214
builder.put(ReservedStateMetadata.readFrom(in));
21902215
}
21912216

2217+
if (in.getTransportVersion().onOrAfter(TransportVersions.PROJECT_METADATA_SETTINGS)) {
2218+
builder.settings(Settings.readSettingsFromStream(in));
2219+
}
2220+
21922221
return builder.build();
21932222
}
21942223

@@ -2229,6 +2258,10 @@ public void writeTo(StreamOutput out) throws IOException {
22292258
}
22302259
VersionedNamedWriteable.writeVersionedWriteables(out, filteredCustoms);
22312260
out.writeCollection(reservedStateMetadata.values());
2261+
2262+
if (out.getTransportVersion().onOrAfter(TransportVersions.PROJECT_METADATA_SETTINGS)) {
2263+
settings.writeTo(out);
2264+
}
22322265
}
22332266

22342267
// this needs to be package accessible for bwc serialization in Metadata.java
@@ -2248,13 +2281,15 @@ static class ProjectMetadataDiff implements Diff<ProjectMetadata> {
22482281
String,
22492282
ReservedStateMetadata,
22502283
ImmutableOpenMap<String, ReservedStateMetadata>> reservedStateMetadata;
2284+
private final Diff<Settings> settingsDiff;
22512285

22522286
private ProjectMetadataDiff(ProjectMetadata before, ProjectMetadata after) {
22532287
if (before == after) {
22542288
indices = DiffableUtils.emptyDiff();
22552289
templates = DiffableUtils.emptyDiff();
22562290
customs = DiffableUtils.emptyDiff();
22572291
reservedStateMetadata = DiffableUtils.emptyDiff();
2292+
settingsDiff = Settings.EMPTY_DIFF;
22582293
} else {
22592294
indices = DiffableUtils.diff(before.indices, after.indices, DiffableUtils.getStringKeySerializer());
22602295
templates = DiffableUtils.diff(before.templates, after.templates, DiffableUtils.getStringKeySerializer());
@@ -2269,19 +2304,22 @@ private ProjectMetadataDiff(ProjectMetadata before, ProjectMetadata after) {
22692304
after.reservedStateMetadata,
22702305
DiffableUtils.getStringKeySerializer()
22712306
);
2307+
settingsDiff = after.settings.diff(before.settings);
22722308
}
22732309
}
22742310

22752311
ProjectMetadataDiff(
22762312
DiffableUtils.MapDiff<String, IndexMetadata, ImmutableOpenMap<String, IndexMetadata>> indices,
22772313
DiffableUtils.MapDiff<String, IndexTemplateMetadata, ImmutableOpenMap<String, IndexTemplateMetadata>> templates,
22782314
DiffableUtils.MapDiff<String, Metadata.ProjectCustom, ImmutableOpenMap<String, Metadata.ProjectCustom>> customs,
2279-
DiffableUtils.MapDiff<String, ReservedStateMetadata, ImmutableOpenMap<String, ReservedStateMetadata>> reservedStateMetadata
2315+
DiffableUtils.MapDiff<String, ReservedStateMetadata, ImmutableOpenMap<String, ReservedStateMetadata>> reservedStateMetadata,
2316+
Diff<Settings> settingsDiff
22802317
) {
22812318
this.indices = indices;
22822319
this.templates = templates;
22832320
this.customs = customs;
22842321
this.reservedStateMetadata = reservedStateMetadata;
2322+
this.settingsDiff = settingsDiff;
22852323
}
22862324

22872325
ProjectMetadataDiff(StreamInput in) throws IOException {
@@ -2293,6 +2331,11 @@ private ProjectMetadataDiff(ProjectMetadata before, ProjectMetadata after) {
22932331
DiffableUtils.getStringKeySerializer(),
22942332
RESERVED_DIFF_VALUE_READER
22952333
);
2334+
if (in.getTransportVersion().onOrAfter(TransportVersions.PROJECT_METADATA_SETTINGS)) {
2335+
settingsDiff = Settings.readSettingsDiffFromStream(in);
2336+
} else {
2337+
settingsDiff = Settings.EMPTY_DIFF;
2338+
}
22962339
}
22972340

22982341
Diff<ImmutableOpenMap<String, IndexMetadata>> indices() {
@@ -2317,11 +2360,15 @@ public void writeTo(StreamOutput out) throws IOException {
23172360
templates.writeTo(out);
23182361
customs.writeTo(out);
23192362
reservedStateMetadata.writeTo(out);
2363+
if (out.getTransportVersion().onOrAfter(TransportVersions.PROJECT_METADATA_SETTINGS)) {
2364+
settingsDiff.writeTo(out);
2365+
}
23202366
}
23212367

23222368
@Override
23232369
public ProjectMetadata apply(ProjectMetadata part) {
2324-
if (indices.isEmpty() && templates.isEmpty() && customs.isEmpty() && reservedStateMetadata.isEmpty()) {
2370+
if (indices.isEmpty() && templates.isEmpty() && customs.isEmpty()
2371+
&& reservedStateMetadata.isEmpty() && settingsDiff == Settings.EMPTY_DIFF) {
23252372
// nothing to do
23262373
return part;
23272374
}
@@ -2336,13 +2383,14 @@ public ProjectMetadata apply(ProjectMetadata part) {
23362383
&& builder.dataStreamMetadata() == part.custom(DataStreamMetadata.TYPE, DataStreamMetadata.EMPTY)) {
23372384
builder.previousIndicesLookup = part.indicesLookup;
23382385
}
2386+
builder.settings = settingsDiff.apply(builder.settings);
23392387
return builder.build(true);
23402388
}
23412389

23422390
ProjectMetadataDiff withCustoms(
23432391
DiffableUtils.MapDiff<String, Metadata.ProjectCustom, ImmutableOpenMap<String, Metadata.ProjectCustom>> customs
23442392
) {
2345-
return new ProjectMetadataDiff(indices, templates, customs, reservedStateMetadata);
2393+
return new ProjectMetadataDiff(indices, templates, customs, reservedStateMetadata, settingsDiff);
23462394
}
23472395
}
23482396

server/src/main/java/org/elasticsearch/cluster/service/ClusterService.java

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.elasticsearch.common.Priority;
2424
import org.elasticsearch.common.component.AbstractLifecycleComponent;
2525
import org.elasticsearch.common.settings.ClusterSettings;
26+
import org.elasticsearch.common.settings.ProjectScopedSettings;
2627
import org.elasticsearch.common.settings.Setting;
2728
import org.elasticsearch.common.settings.Setting.Property;
2829
import org.elasticsearch.common.settings.Settings;
@@ -31,6 +32,8 @@
3132
import org.elasticsearch.tasks.TaskManager;
3233
import org.elasticsearch.threadpool.ThreadPool;
3334

35+
import java.util.Collections;
36+
3437
public class ClusterService extends AbstractLifecycleComponent {
3538
private final MasterService masterService;
3639

@@ -52,26 +55,57 @@ public class ClusterService extends AbstractLifecycleComponent {
5255

5356
private final ClusterSettings clusterSettings;
5457

58+
private final ProjectScopedSettings projectScopedSettings;
59+
5560
private final String nodeName;
5661

57-
public ClusterService(Settings settings, ClusterSettings clusterSettings, ThreadPool threadPool, TaskManager taskManager) {
62+
public ClusterService(Settings settings, ClusterSettings clusterSettings,
63+
ThreadPool threadPool, TaskManager taskManager) {
5864
this(
5965
settings,
6066
clusterSettings,
67+
new ProjectScopedSettings(settings, Collections.emptySet()),
6168
new MasterService(settings, clusterSettings, threadPool, taskManager),
6269
new ClusterApplierService(Node.NODE_NAME_SETTING.get(settings), settings, clusterSettings, threadPool)
6370
);
6471
}
6572

73+
public ClusterService(Settings settings, ClusterSettings clusterSettings, ProjectScopedSettings projectScopedSettings,
74+
ThreadPool threadPool, TaskManager taskManager) {
75+
this(
76+
settings,
77+
clusterSettings,
78+
projectScopedSettings, new MasterService(settings, clusterSettings, threadPool, taskManager),
79+
new ClusterApplierService(Node.NODE_NAME_SETTING.get(settings), settings, clusterSettings, threadPool)
80+
);
81+
}
82+
6683
public ClusterService(
6784
Settings settings,
6885
ClusterSettings clusterSettings,
6986
MasterService masterService,
7087
ClusterApplierService clusterApplierService
88+
) {
89+
this(
90+
settings,
91+
clusterSettings,
92+
new ProjectScopedSettings(settings, Collections.emptySet()),
93+
masterService,
94+
clusterApplierService
95+
);
96+
}
97+
98+
public ClusterService(
99+
Settings settings,
100+
ClusterSettings clusterSettings,
101+
ProjectScopedSettings projectScopedSettings,
102+
MasterService masterService,
103+
ClusterApplierService clusterApplierService
71104
) {
72105
this.settings = settings;
73106
this.nodeName = Node.NODE_NAME_SETTING.get(settings);
74107
this.masterService = masterService;
108+
this.projectScopedSettings = projectScopedSettings;
75109
this.operationRouting = new OperationRouting(settings, clusterSettings);
76110
this.clusterSettings = clusterSettings;
77111
this.clusterName = ClusterName.CLUSTER_NAME_SETTING.get(settings);
@@ -201,6 +235,10 @@ public ClusterSettings getClusterSettings() {
201235
return clusterSettings;
202236
}
203237

238+
public ProjectScopedSettings getProjectScopedSettings() {
239+
return projectScopedSettings;
240+
}
241+
204242
/**
205243
* The node's settings.
206244
*/
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.common.settings;
11+
12+
import java.util.Set;
13+
14+
public class ProjectScopedSettings extends AbstractScopedSettings {
15+
public ProjectScopedSettings(Settings settings, Set<Setting<?>> settingsSet) {
16+
super(settings, settingsSet, Setting.Property.ProjectScope);
17+
}
18+
}

server/src/main/java/org/elasticsearch/common/settings/Setting.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,12 @@ public enum Property {
179179
* All other settings will be rejected when used on a PUT request
180180
* and filtered out on a GET
181181
*/
182-
ServerlessPublic
182+
ServerlessPublic,
183+
184+
/**
185+
* Project-level file-level setting. Not an index setting.
186+
*/
187+
ProjectScope
183188
}
184189

185190
private final Key key;

server/src/main/java/org/elasticsearch/common/settings/Settings.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
public final class Settings implements ToXContentFragment, Writeable, Diffable<Settings> {
8080

8181
public static final Settings EMPTY = new Settings(Map.of(), null);
82+
public static final Diff<Settings> EMPTY_DIFF = new SettingsDiff(DiffableUtils.emptyDiff());
8283

8384
public static final String FLAT_SETTINGS_PARAM = "flat_settings";
8485

0 commit comments

Comments
 (0)