Skip to content

Commit d362fb3

Browse files
New per-project only settings can be defined and used by components (#127280)
This change introduces Settings to ProjectMetadata and adds project scope support for Setting. For now, project-scoped settings are independent from cluster settings and do not fall back to cluster-level settings. Also, setting update consumers do not yet work correctly for project-scoped settings. These issues will be addressed separately in future PRs.
1 parent 9f8c9c9 commit d362fb3

File tree

15 files changed

+569
-114
lines changed

15 files changed

+569
-114
lines changed

modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/GeoIpDownloaderTaskExecutor.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ public final class GeoIpDownloaderTaskExecutor extends PersistentTasksExecutor<G
7171
"ingest.geoip.downloader.enabled",
7272
ENABLED_DEFAULT,
7373
Setting.Property.Dynamic,
74-
Setting.Property.NodeScope
74+
Setting.Property.NodeScope,
75+
Setting.Property.ProjectScope
7576
);
7677
public static final Setting<TimeValue> POLL_INTERVAL_SETTING = Setting.timeSetting(
7778
"ingest.geoip.downloader.poll.interval",

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

+1
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ static TransportVersion def(int id) {
229229
public static final TransportVersion RANDOM_SAMPLER_QUERY_BUILDER = def(9_063_0_00);
230230
public static final TransportVersion SETTINGS_IN_DATA_STREAMS = def(9_064_0_00);
231231
public static final TransportVersion INTRODUCE_FAILURES_LIFECYCLE = def(9_065_0_00);
232+
public static final TransportVersion PROJECT_METADATA_SETTINGS = def(9_066_00_0);
232233

233234
/*
234235
* STOP! READ THIS FIRST! No, really,

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

+7-1
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,13 @@ 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(
954+
indices,
955+
templates,
956+
projectCustoms,
957+
DiffableUtils.emptyDiff(),
958+
Settings.EMPTY_DIFF
959+
);
954960
multiProject = null;
955961
} else {
956962
fromNodeBeforeMultiProjectsSupport = false;

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

+60-3
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,6 +225,7 @@ public ProjectMetadata withLifecycleState(Index index, LifecycleExecutionState l
221225
visibleClosedIndices,
222226
indicesLookup,
223227
mappingsByHash,
228+
settings,
224229
oldestIndexVersion
225230
);
226231
}
@@ -254,6 +259,7 @@ public ProjectMetadata withIndexSettingsUpdates(Map<Index, Settings> updates) {
254259
visibleClosedIndices,
255260
indicesLookup,
256261
mappingsByHash,
262+
settings,
257263
oldestIndexVersion
258264
);
259265
}
@@ -288,6 +294,7 @@ public ProjectMetadata withAllocationAndTermUpdatesOnly(Map<String, IndexMetadat
288294
visibleClosedIndices,
289295
indicesLookup,
290296
mappingsByHash,
297+
settings,
291298
oldestIndexVersion
292299
);
293300
}
@@ -376,6 +383,7 @@ public ProjectMetadata withAddedIndex(IndexMetadata index) {
376383
updatedVisibleClosedIndices,
377384
null,
378385
updatedMappingsByHash,
386+
settings,
379387
IndexVersion.min(index.getCompatibilityVersion(), oldestIndexVersion)
380388
);
381389
}
@@ -727,6 +735,10 @@ public Map<String, IndexTemplateMetadata> templates() {
727735
return templates;
728736
}
729737

738+
public Settings settings() {
739+
return settings;
740+
}
741+
730742
/**
731743
* Checks whether the provided index is a data stream.
732744
*/
@@ -1097,6 +1109,9 @@ public boolean isIndexManagedByILM(IndexMetadata indexMetadata) {
10971109
}
10981110

10991111
static boolean isStateEquals(ProjectMetadata project1, ProjectMetadata project2) {
1112+
if (project1.settings().equals(project2.settings()) == false) {
1113+
return false;
1114+
}
11001115
if (project1.templates().equals(project2.templates()) == false) {
11011116
return false;
11021117
}
@@ -1130,6 +1145,7 @@ public static class Builder {
11301145
private final ImmutableOpenMap.Builder<String, IndexTemplateMetadata> templates;
11311146
private final ImmutableOpenMap.Builder<String, Metadata.ProjectCustom> customs;
11321147
private final ImmutableOpenMap.Builder<String, ReservedStateMetadata> reservedStateMetadata;
1148+
private Settings settings = Settings.EMPTY;
11331149

11341150
private SortedMap<String, IndexAbstraction> previousIndicesLookup;
11351151

@@ -1147,6 +1163,7 @@ public static class Builder {
11471163
this.templates = ImmutableOpenMap.builder(projectMetadata.templates);
11481164
this.customs = ImmutableOpenMap.builder(projectMetadata.customs);
11491165
this.reservedStateMetadata = ImmutableOpenMap.builder(projectMetadata.reservedStateMetadata);
1166+
this.settings = projectMetadata.settings;
11501167
this.previousIndicesLookup = projectMetadata.indicesLookup;
11511168
this.mappingsByHash = new HashMap<>(projectMetadata.mappingsByHash);
11521169
this.checkForUnusedMappings = false;
@@ -1525,6 +1542,11 @@ public Builder removeReservedState(ReservedStateMetadata metadata) {
15251542
return this;
15261543
}
15271544

1545+
public Builder settings(Settings settings) {
1546+
this.settings = settings;
1547+
return this;
1548+
}
1549+
15281550
public Builder indexGraveyard(final IndexGraveyard indexGraveyard) {
15291551
return putCustom(IndexGraveyard.TYPE, indexGraveyard);
15301552
}
@@ -1684,6 +1706,7 @@ public ProjectMetadata build(boolean skipNameCollisionChecks) {
16841706
visibleClosedIndicesArray,
16851707
indicesLookup,
16861708
Collections.unmodifiableMap(mappingsByHash),
1709+
settings,
16871710
IndexVersion.fromId(oldestIndexVersionId)
16881711
);
16891712
}
@@ -2110,6 +2133,9 @@ public static ProjectMetadata fromXContent(XContentParser parser) throws IOExcep
21102133
projectBuilder.put(IndexTemplateMetadata.Builder.fromXContent(parser, parser.currentName()));
21112134
}
21122135
}
2136+
case "settings" -> {
2137+
projectBuilder.settings(Settings.fromXContent(parser));
2138+
}
21132139
default -> Metadata.Builder.parseCustomObject(
21142140
parser,
21152141
currentFieldName,
@@ -2155,6 +2181,11 @@ public Iterator<? extends ToXContent> toXContentChunked(ToXContent.Params p) {
21552181
),
21562182
indices,
21572183
customs,
2184+
multiProject ? Iterators.single((builder, params) -> {
2185+
builder.startObject("settings");
2186+
settings.toXContent(builder, new ToXContent.MapParams(Collections.singletonMap("flat_settings", "true")));
2187+
return builder.endObject();
2188+
}) : Collections.emptyIterator(),
21582189
multiProject
21592190
? ChunkedToXContentHelper.object("reserved_state", reservedStateMetadata().values().iterator())
21602191
: Collections.emptyIterator()
@@ -2189,6 +2220,10 @@ public static ProjectMetadata readFrom(StreamInput in) throws IOException {
21892220
builder.put(ReservedStateMetadata.readFrom(in));
21902221
}
21912222

2223+
if (in.getTransportVersion().onOrAfter(TransportVersions.PROJECT_METADATA_SETTINGS)) {
2224+
builder.settings(Settings.readSettingsFromStream(in));
2225+
}
2226+
21922227
return builder.build();
21932228
}
21942229

@@ -2229,6 +2264,10 @@ public void writeTo(StreamOutput out) throws IOException {
22292264
}
22302265
VersionedNamedWriteable.writeVersionedWriteables(out, filteredCustoms);
22312266
out.writeCollection(reservedStateMetadata.values());
2267+
2268+
if (out.getTransportVersion().onOrAfter(TransportVersions.PROJECT_METADATA_SETTINGS)) {
2269+
settings.writeTo(out);
2270+
}
22322271
}
22332272

22342273
// this needs to be package accessible for bwc serialization in Metadata.java
@@ -2248,13 +2287,15 @@ static class ProjectMetadataDiff implements Diff<ProjectMetadata> {
22482287
String,
22492288
ReservedStateMetadata,
22502289
ImmutableOpenMap<String, ReservedStateMetadata>> reservedStateMetadata;
2290+
private final Diff<Settings> settingsDiff;
22512291

22522292
private ProjectMetadataDiff(ProjectMetadata before, ProjectMetadata after) {
22532293
if (before == after) {
22542294
indices = DiffableUtils.emptyDiff();
22552295
templates = DiffableUtils.emptyDiff();
22562296
customs = DiffableUtils.emptyDiff();
22572297
reservedStateMetadata = DiffableUtils.emptyDiff();
2298+
settingsDiff = Settings.EMPTY_DIFF;
22582299
} else {
22592300
indices = DiffableUtils.diff(before.indices, after.indices, DiffableUtils.getStringKeySerializer());
22602301
templates = DiffableUtils.diff(before.templates, after.templates, DiffableUtils.getStringKeySerializer());
@@ -2269,19 +2310,22 @@ private ProjectMetadataDiff(ProjectMetadata before, ProjectMetadata after) {
22692310
after.reservedStateMetadata,
22702311
DiffableUtils.getStringKeySerializer()
22712312
);
2313+
settingsDiff = after.settings.diff(before.settings);
22722314
}
22732315
}
22742316

22752317
ProjectMetadataDiff(
22762318
DiffableUtils.MapDiff<String, IndexMetadata, ImmutableOpenMap<String, IndexMetadata>> indices,
22772319
DiffableUtils.MapDiff<String, IndexTemplateMetadata, ImmutableOpenMap<String, IndexTemplateMetadata>> templates,
22782320
DiffableUtils.MapDiff<String, Metadata.ProjectCustom, ImmutableOpenMap<String, Metadata.ProjectCustom>> customs,
2279-
DiffableUtils.MapDiff<String, ReservedStateMetadata, ImmutableOpenMap<String, ReservedStateMetadata>> reservedStateMetadata
2321+
DiffableUtils.MapDiff<String, ReservedStateMetadata, ImmutableOpenMap<String, ReservedStateMetadata>> reservedStateMetadata,
2322+
Diff<Settings> settingsDiff
22802323
) {
22812324
this.indices = indices;
22822325
this.templates = templates;
22832326
this.customs = customs;
22842327
this.reservedStateMetadata = reservedStateMetadata;
2328+
this.settingsDiff = settingsDiff;
22852329
}
22862330

22872331
ProjectMetadataDiff(StreamInput in) throws IOException {
@@ -2293,6 +2337,11 @@ private ProjectMetadataDiff(ProjectMetadata before, ProjectMetadata after) {
22932337
DiffableUtils.getStringKeySerializer(),
22942338
RESERVED_DIFF_VALUE_READER
22952339
);
2340+
if (in.getTransportVersion().onOrAfter(TransportVersions.PROJECT_METADATA_SETTINGS)) {
2341+
settingsDiff = Settings.readSettingsDiffFromStream(in);
2342+
} else {
2343+
settingsDiff = Settings.EMPTY_DIFF;
2344+
}
22962345
}
22972346

22982347
Diff<ImmutableOpenMap<String, IndexMetadata>> indices() {
@@ -2317,11 +2366,18 @@ public void writeTo(StreamOutput out) throws IOException {
23172366
templates.writeTo(out);
23182367
customs.writeTo(out);
23192368
reservedStateMetadata.writeTo(out);
2369+
if (out.getTransportVersion().onOrAfter(TransportVersions.PROJECT_METADATA_SETTINGS)) {
2370+
settingsDiff.writeTo(out);
2371+
}
23202372
}
23212373

23222374
@Override
23232375
public ProjectMetadata apply(ProjectMetadata part) {
2324-
if (indices.isEmpty() && templates.isEmpty() && customs.isEmpty() && reservedStateMetadata.isEmpty()) {
2376+
if (indices.isEmpty()
2377+
&& templates.isEmpty()
2378+
&& customs.isEmpty()
2379+
&& reservedStateMetadata.isEmpty()
2380+
&& settingsDiff == Settings.EMPTY_DIFF) {
23252381
// nothing to do
23262382
return part;
23272383
}
@@ -2336,13 +2392,14 @@ public ProjectMetadata apply(ProjectMetadata part) {
23362392
&& builder.dataStreamMetadata() == part.custom(DataStreamMetadata.TYPE, DataStreamMetadata.EMPTY)) {
23372393
builder.previousIndicesLookup = part.indicesLookup;
23382394
}
2395+
builder.settings = settingsDiff.apply(part.settings);
23392396
return builder.build(true);
23402397
}
23412398

23422399
ProjectMetadataDiff withCustoms(
23432400
DiffableUtils.MapDiff<String, Metadata.ProjectCustom, ImmutableOpenMap<String, Metadata.ProjectCustom>> customs
23442401
) {
2345-
return new ProjectMetadataDiff(indices, templates, customs, reservedStateMetadata);
2402+
return new ProjectMetadataDiff(indices, templates, customs, reservedStateMetadata, settingsDiff);
23462403
}
23472404
}
23482405

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

+37
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,12 +55,31 @@ public class ClusterService extends AbstractLifecycleComponent {
5255

5356
private final ClusterSettings clusterSettings;
5457

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

5762
public ClusterService(Settings settings, ClusterSettings clusterSettings, ThreadPool threadPool, TaskManager taskManager) {
5863
this(
5964
settings,
6065
clusterSettings,
66+
new ProjectScopedSettings(settings, Collections.emptySet()),
67+
new MasterService(settings, clusterSettings, threadPool, taskManager),
68+
new ClusterApplierService(Node.NODE_NAME_SETTING.get(settings), settings, clusterSettings, threadPool)
69+
);
70+
}
71+
72+
public ClusterService(
73+
Settings settings,
74+
ClusterSettings clusterSettings,
75+
ProjectScopedSettings projectScopedSettings,
76+
ThreadPool threadPool,
77+
TaskManager taskManager
78+
) {
79+
this(
80+
settings,
81+
clusterSettings,
82+
projectScopedSettings,
6183
new MasterService(settings, clusterSettings, threadPool, taskManager),
6284
new ClusterApplierService(Node.NODE_NAME_SETTING.get(settings), settings, clusterSettings, threadPool)
6385
);
@@ -68,10 +90,21 @@ public ClusterService(
6890
ClusterSettings clusterSettings,
6991
MasterService masterService,
7092
ClusterApplierService clusterApplierService
93+
) {
94+
this(settings, clusterSettings, new ProjectScopedSettings(settings, Collections.emptySet()), masterService, clusterApplierService);
95+
}
96+
97+
public ClusterService(
98+
Settings settings,
99+
ClusterSettings clusterSettings,
100+
ProjectScopedSettings projectScopedSettings,
101+
MasterService masterService,
102+
ClusterApplierService clusterApplierService
71103
) {
72104
this.settings = settings;
73105
this.nodeName = Node.NODE_NAME_SETTING.get(settings);
74106
this.masterService = masterService;
107+
this.projectScopedSettings = projectScopedSettings;
75108
this.operationRouting = new OperationRouting(settings, clusterSettings);
76109
this.clusterSettings = clusterSettings;
77110
this.clusterName = ClusterName.CLUSTER_NAME_SETTING.get(settings);
@@ -201,6 +234,10 @@ public ClusterSettings getClusterSettings() {
201234
return clusterSettings;
202235
}
203236

237+
public ProjectScopedSettings getProjectScopedSettings() {
238+
return projectScopedSettings;
239+
}
240+
204241
/**
205242
* The node's settings.
206243
*/

0 commit comments

Comments
 (0)