Skip to content

Commit aec37f7

Browse files
Move per-project settings out of ProjectMetadata
1 parent 3f03775 commit aec37f7

File tree

12 files changed

+136
-72
lines changed

12 files changed

+136
-72
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ static TransportVersion def(int id) {
285285
public static final TransportVersion ILM_ADD_SKIP_SETTING = def(9_089_0_00);
286286
public static final TransportVersion ML_INFERENCE_MISTRAL_CHAT_COMPLETION_ADDED = def(9_090_0_00);
287287
public static final TransportVersion IDP_CUSTOM_SAML_ATTRIBUTES_ALLOW_LIST = def(9_091_0_00);
288+
public static final TransportVersion CLUSTER_STATE_PROJECTS_SETTINGS = def(9_092_0_00);
288289

289290
/*
290291
* STOP! READ THIS FIRST! No, really,

server/src/main/java/org/elasticsearch/action/admin/cluster/state/TransportClusterStateAction.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ private ClusterStateResponse buildResponse(final ClusterStateRequest request, fi
201201
ClusterState.Builder builder = ClusterState.builder(currentState.getClusterName());
202202
builder.version(currentState.version());
203203
builder.stateUUID(currentState.stateUUID());
204+
builder.projectsSettings(currentState.projectsSettings());
204205

205206
if (request.nodes()) {
206207
builder.nodes(currentState.nodes());

server/src/main/java/org/elasticsearch/cluster/ClusterState.java

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import org.elasticsearch.common.io.stream.StreamOutput;
4848
import org.elasticsearch.common.io.stream.VersionedNamedWriteable;
4949
import org.elasticsearch.common.io.stream.Writeable;
50+
import org.elasticsearch.common.settings.Settings;
5051
import org.elasticsearch.common.util.Maps;
5152
import org.elasticsearch.common.xcontent.ChunkedToXContent;
5253
import org.elasticsearch.common.xcontent.ChunkedToXContentHelper;
@@ -192,6 +193,8 @@ public CompatibilityVersions read(StreamInput in, String key) throws IOException
192193

193194
private final boolean wasReadFromDiff;
194195

196+
private final Map<ProjectId, Settings> projectsSettings;
197+
195198
// built on demand
196199
private volatile RoutingNodes routingNodes;
197200

@@ -208,6 +211,7 @@ public ClusterState(long version, String stateUUID, ClusterState state) {
208211
state.blocks(),
209212
state.customs(),
210213
false,
214+
state.projectsSettings,
211215
state.routingNodes
212216
);
213217
}
@@ -224,6 +228,7 @@ public ClusterState(
224228
ClusterBlocks blocks,
225229
Map<String, Custom> customs,
226230
boolean wasReadFromDiff,
231+
Map<ProjectId, Settings> projectsSettings,
227232
@Nullable RoutingNodes routingNodes
228233
) {
229234
this.version = version;
@@ -237,6 +242,7 @@ public ClusterState(
237242
this.blocks = blocks;
238243
this.customs = customs;
239244
this.wasReadFromDiff = wasReadFromDiff;
245+
this.projectsSettings = projectsSettings;
240246
this.routingNodes = routingNodes;
241247
assert assertConsistentRoutingNodes(routingTable, nodes, routingNodes);
242248
assert assertConsistentProjectState(routingTable, metadata);
@@ -404,6 +410,14 @@ public RoutingTable routingTable(ProjectId projectId) {
404410
return routingTable.routingTable(projectId);
405411
}
406412

413+
public Settings projectSettings(ProjectId projectId) {
414+
return projectsSettings.getOrDefault(projectId, Settings.EMPTY);
415+
}
416+
417+
public Map<ProjectId, Settings> projectsSettings() {
418+
return projectsSettings;
419+
}
420+
407421
@Deprecated(forRemoval = true)
408422
public RoutingTable routingTable() {
409423
return routingTable.getRoutingTable();
@@ -672,7 +686,8 @@ public enum Metric {
672686
METADATA("metadata"),
673687
ROUTING_TABLE("routing_table"),
674688
ROUTING_NODES("routing_nodes"),
675-
CUSTOMS("customs");
689+
CUSTOMS("customs"),
690+
PROJECTS_SETTINGS("projects_settings");
676691

677692
private static final Map<String, Metric> valueToEnum;
678693

@@ -849,7 +864,22 @@ public Iterator<? extends ToXContent> toXContentChunked(ToXContent.Params outerP
849864
customs.entrySet().iterator(),
850865
e -> ChunkedToXContentHelper.object(e.getKey(), e.getValue().toXContentChunked(outerParams))
851866
)
852-
: Collections.emptyIterator()
867+
: Collections.emptyIterator(),
868+
869+
chunkedSection(
870+
multiProject && metrics.contains(Metric.PROJECTS_SETTINGS),
871+
(builder, params) -> builder.startArray("projects_settings"),
872+
projectsSettings.entrySet().iterator(),
873+
874+
entry -> Iterators.single((builder, params) -> {
875+
builder.startObject();
876+
builder.field("id", entry.getKey());
877+
builder.startObject("settings");
878+
entry.getValue().toXContent(builder, new ToXContent.MapParams(Collections.singletonMap("flat_settings", "true")));
879+
return builder.endObject().endObject();
880+
}),
881+
(builder, params) -> builder.endArray()
882+
)
853883
);
854884
}
855885

@@ -1006,6 +1036,7 @@ public static class Builder {
10061036
private final Map<String, Set<String>> nodeFeatures;
10071037
private ClusterBlocks blocks = ClusterBlocks.EMPTY_CLUSTER_BLOCK;
10081038
private final ImmutableOpenMap.Builder<String, Custom> customs;
1039+
private final ImmutableOpenMap.Builder<ProjectId, Settings> projectsSettings;
10091040
private boolean fromDiff;
10101041

10111042
public Builder(ClusterState state) {
@@ -1021,11 +1052,13 @@ public Builder(ClusterState state) {
10211052
this.blocks = state.blocks();
10221053
this.customs = ImmutableOpenMap.builder(state.customs());
10231054
this.fromDiff = false;
1055+
this.projectsSettings = ImmutableOpenMap.builder(state.projectsSettings);
10241056
}
10251057

10261058
public Builder(ClusterName clusterName) {
10271059
this.compatibilityVersions = new HashMap<>();
10281060
this.nodeFeatures = new HashMap<>();
1061+
this.projectsSettings = ImmutableOpenMap.builder();
10291062
customs = ImmutableOpenMap.builder();
10301063
this.clusterName = clusterName;
10311064
}
@@ -1130,6 +1163,16 @@ public Builder putRoutingTable(ProjectId projectId, RoutingTable routingTable) {
11301163
return routingTable(globalRoutingTableBuilder.put(projectId, routingTable).build());
11311164
}
11321165

1166+
public Builder putProjectSettings(ProjectId projectId, Settings settings) {
1167+
projectsSettings.put(projectId, settings);
1168+
return this;
1169+
}
1170+
1171+
public Builder projectsSettings(Map<ProjectId, Settings> projectsSettings) {
1172+
this.projectsSettings.putAllFromMap(projectsSettings);
1173+
return this;
1174+
}
1175+
11331176
public Builder metadata(Metadata.Builder metadataBuilder) {
11341177
return metadata(metadataBuilder.build());
11351178
}
@@ -1234,6 +1277,7 @@ public ClusterState build() {
12341277
metadata != null ? blocks.initializeProjects(metadata.projects().keySet()) : blocks,
12351278
customs.build(),
12361279
fromDiff,
1280+
projectsSettings.build(),
12371281
routingNodes
12381282
);
12391283
}
@@ -1285,6 +1329,9 @@ public static ClusterState readFrom(StreamInput in, DiscoveryNode localNode) thr
12851329
Custom customIndexMetadata = in.readNamedWriteable(Custom.class);
12861330
builder.putCustom(customIndexMetadata.getWriteableName(), customIndexMetadata);
12871331
}
1332+
if (in.getTransportVersion().onOrAfter(TransportVersions.CLUSTER_STATE_PROJECTS_SETTINGS)) {
1333+
builder.projectsSettings(in.readMap(ProjectId::readFrom, Settings::readSettingsFromStream));
1334+
}
12881335
return builder.build();
12891336
}
12901337

@@ -1306,9 +1353,23 @@ public void writeTo(StreamOutput out) throws IOException {
13061353
clusterFeatures.writeTo(out);
13071354
blocks.writeTo(out);
13081355
VersionedNamedWriteable.writeVersionedWritables(out, customs);
1356+
if (out.getTransportVersion().onOrAfter(TransportVersions.CLUSTER_STATE_PROJECTS_SETTINGS)) {
1357+
out.writeMap(projectsSettings);
1358+
}
13091359
}
13101360

13111361
private static class ClusterStateDiff implements Diff<ClusterState> {
1362+
private static final DiffableUtils.ValueSerializer<ProjectId, Settings> SETTINGS_SERIALIZER = new DiffableUtils.DiffableValueSerializer<>() {
1363+
@Override
1364+
public Settings read(StreamInput in, ProjectId key) throws IOException {
1365+
return Settings.readSettingsFromStream(in);
1366+
}
1367+
1368+
@Override
1369+
public Diff<Settings> readDiff(StreamInput in, ProjectId key) throws IOException {
1370+
return Settings.readSettingsDiffFromStream(in);
1371+
}
1372+
};
13121373

13131374
private final long toVersion;
13141375

@@ -1331,6 +1392,8 @@ private static class ClusterStateDiff implements Diff<ClusterState> {
13311392

13321393
private final Diff<Map<String, Custom>> customs;
13331394

1395+
private final DiffableUtils.MapDiff<ProjectId, Settings, Map<ProjectId, Settings>> projectsSettings;
1396+
13341397
ClusterStateDiff(ClusterState before, ClusterState after) {
13351398
fromUuid = before.stateUUID;
13361399
toUuid = after.stateUUID;
@@ -1348,6 +1411,7 @@ private static class ClusterStateDiff implements Diff<ClusterState> {
13481411
metadata = after.metadata.diff(before.metadata);
13491412
blocks = after.blocks.diff(before.blocks);
13501413
customs = DiffableUtils.diff(before.customs, after.customs, DiffableUtils.getStringKeySerializer(), CUSTOM_VALUE_SERIALIZER);
1414+
projectsSettings = DiffableUtils.diff(before.projectsSettings, after.projectsSettings, ProjectId.PROJECT_ID_SERIALIZER, SETTINGS_SERIALIZER);
13511415
}
13521416

13531417
ClusterStateDiff(StreamInput in, DiscoveryNode localNode) throws IOException {
@@ -1364,6 +1428,11 @@ private static class ClusterStateDiff implements Diff<ClusterState> {
13641428
metadata = Metadata.readDiffFrom(in);
13651429
blocks = ClusterBlocks.readDiffFrom(in);
13661430
customs = DiffableUtils.readJdkMapDiff(in, DiffableUtils.getStringKeySerializer(), CUSTOM_VALUE_SERIALIZER);
1431+
if (in.getTransportVersion().onOrAfter(TransportVersions.CLUSTER_STATE_PROJECTS_SETTINGS)) {
1432+
projectsSettings = DiffableUtils.readJdkMapDiff(in, ProjectId.PROJECT_ID_SERIALIZER, SETTINGS_SERIALIZER);
1433+
} else {
1434+
projectsSettings = DiffableUtils.emptyDiff();
1435+
}
13671436
}
13681437

13691438
@Override
@@ -1380,6 +1449,9 @@ public void writeTo(StreamOutput out) throws IOException {
13801449
metadata.writeTo(out);
13811450
blocks.writeTo(out);
13821451
customs.writeTo(out);
1452+
if (out.getTransportVersion().onOrAfter(TransportVersions.CLUSTER_STATE_PROJECTS_SETTINGS)) {
1453+
projectsSettings.writeTo(out);
1454+
}
13831455
}
13841456

13851457
@Override
@@ -1401,6 +1473,7 @@ public ClusterState apply(ClusterState state) {
14011473
builder.metadata(metadata.apply(state.metadata));
14021474
builder.blocks(blocks.apply(state.blocks));
14031475
builder.customs(customs.apply(state.customs));
1476+
builder.projectsSettings(this.projectsSettings.apply(state.projectsSettings));
14041477
builder.fromDiff(state);
14051478
return builder.build();
14061479
}

server/src/main/java/org/elasticsearch/cluster/ProjectState.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.elasticsearch.cluster.metadata.ProjectMetadata;
1515
import org.elasticsearch.cluster.routing.RoutingTable;
1616
import org.elasticsearch.common.Strings;
17+
import org.elasticsearch.common.settings.Settings;
1718

1819
import java.util.Objects;
1920
import java.util.function.Consumer;
@@ -26,6 +27,7 @@ public final class ProjectState {
2627
private final ClusterState cluster;
2728
private final ProjectId project;
2829
private final ProjectMetadata projectMetadata;
30+
private final Settings projectSettings;
2931
private final RoutingTable routingTable;
3032

3133
ProjectState(ClusterState clusterState, ProjectId projectId) {
@@ -34,6 +36,7 @@ public final class ProjectState {
3436
this.cluster = clusterState;
3537
this.project = projectId;
3638
this.projectMetadata = clusterState.metadata().getProject(projectId);
39+
this.projectSettings = clusterState.projectSettings(projectId);
3740
this.routingTable = clusterState.routingTable(projectId);
3841
}
3942

@@ -57,6 +60,10 @@ public ClusterBlocks blocks() {
5760
return cluster().blocks();
5861
}
5962

63+
public Settings settings() {
64+
return projectSettings;
65+
}
66+
6067
@Override
6168
public boolean equals(Object obj) {
6269
if (obj == this) return true;

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

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -801,10 +801,6 @@ private Iterator<? extends ToXContent> toXContentChunkedWithSingleProjectFormat(
801801
);
802802
}
803803

804-
private static final DiffableUtils.KeySerializer<ProjectId> PROJECT_ID_SERIALIZER = DiffableUtils.getWriteableKeySerializer(
805-
ProjectId.READER
806-
);
807-
808804
private static class MetadataDiff implements Diff<Metadata> {
809805

810806
private final long version;
@@ -846,7 +842,7 @@ private static class MetadataDiff implements Diff<Metadata> {
846842
multiProject = null;
847843
} else {
848844
singleProject = null;
849-
multiProject = DiffableUtils.diff(before.projectMetadata, after.projectMetadata, PROJECT_ID_SERIALIZER);
845+
multiProject = DiffableUtils.diff(before.projectMetadata, after.projectMetadata, ProjectId.PROJECT_ID_SERIALIZER);
850846
}
851847

852848
if (empty) {
@@ -955,8 +951,7 @@ private MetadataDiff(StreamInput in) throws IOException {
955951
indices,
956952
templates,
957953
projectCustoms,
958-
DiffableUtils.emptyDiff(),
959-
Settings.EMPTY_DIFF
954+
DiffableUtils.emptyDiff()
960955
);
961956
multiProject = null;
962957
} else {
@@ -1001,7 +996,7 @@ private static MapDiff<ProjectId, ProjectMetadata, Map<ProjectId, ProjectMetadat
1001996
) throws IOException {
1002997
final var multiProject = DiffableUtils.readJdkMapDiff(
1003998
in,
1004-
PROJECT_ID_SERIALIZER,
999+
ProjectId.PROJECT_ID_SERIALIZER,
10051000
ProjectMetadata::readFrom,
10061001
ProjectMetadata.ProjectMetadataDiff::new
10071002
);
@@ -1075,7 +1070,7 @@ public void writeTo(StreamOutput out) throws IOException {
10751070
} else {
10761071
final var multiProjectToWrite = multiProject != null
10771072
? multiProject
1078-
: DiffableUtils.singleEntryDiff(DEFAULT_PROJECT_ID, singleProject, PROJECT_ID_SERIALIZER);
1073+
: DiffableUtils.singleEntryDiff(DEFAULT_PROJECT_ID, singleProject, ProjectId.PROJECT_ID_SERIALIZER);
10791074

10801075
if (out.getTransportVersion().before(TransportVersions.REPOSITORIES_METADATA_AS_PROJECT_CUSTOM)) {
10811076
writeDiffWithRepositoriesMetadataAsClusterCustom(out, clusterCustoms, multiProjectToWrite, reservedStateMetadata);

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

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

1010
package org.elasticsearch.cluster.metadata;
1111

12+
import org.elasticsearch.cluster.DiffableUtils;
1213
import org.elasticsearch.common.Strings;
1314
import org.elasticsearch.common.io.stream.StreamInput;
1415
import org.elasticsearch.common.io.stream.StreamOutput;
@@ -26,6 +27,9 @@ public class ProjectId implements Writeable, ToXContent {
2627
private static final String DEFAULT_STRING = "default";
2728
public static final ProjectId DEFAULT = new ProjectId(DEFAULT_STRING);
2829
public static final Reader<ProjectId> READER = ProjectId::readFrom;
30+
public static final DiffableUtils.KeySerializer<ProjectId> PROJECT_ID_SERIALIZER = DiffableUtils.getWriteableKeySerializer(
31+
ProjectId.READER
32+
);
2933
private static final int MAX_LENGTH = 128;
3034

3135
private final String id;

0 commit comments

Comments
 (0)