Skip to content

Commit 88df0a4

Browse files
committed
Remove obsolete Metadata BWC for repositories
When migrating RepositoriesMetadata from cluster custom to project custom, we needed temporary BWC handling for clusters running on a version that is before this change but after the initial MP change. Such a cluster can only exist in the serverless environment which has progressed way past any applicable versions. Therefore we no longer need the BWC handling and this PR removes it. Relates: elastic#125398
1 parent 92b32b5 commit 88df0a4

File tree

4 files changed

+28
-256
lines changed

4 files changed

+28
-256
lines changed

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,6 @@ static TransportVersion def(int id) {
244244
public static final TransportVersion RESCORE_VECTOR_ALLOW_ZERO = def(9_039_0_00);
245245
public static final TransportVersion PROJECT_ID_IN_SNAPSHOT = def(9_040_0_00);
246246
public static final TransportVersion INDEX_STATS_AND_METADATA_INCLUDE_PEAK_WRITE_LOAD = def(9_041_0_00);
247-
public static final TransportVersion REPOSITORIES_METADATA_AS_PROJECT_CUSTOM = def(9_042_0_00);
248247
public static final TransportVersion BATCHED_QUERY_PHASE_VERSION = def(9_043_0_00);
249248
public static final TransportVersion REMOTE_EXCEPTION = def(9_044_0_00);
250249
public static final TransportVersion ESQL_REMOVE_AGGREGATE_TYPE = def(9_045_0_00);

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

Lines changed: 19 additions & 201 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
import org.apache.logging.log4j.LogManager;
1313
import org.apache.logging.log4j.Logger;
14-
import org.apache.lucene.util.SetOnce;
1514
import org.elasticsearch.TransportVersions;
1615
import org.elasticsearch.cluster.ClusterState;
1716
import org.elasticsearch.cluster.Diff;
@@ -55,7 +54,6 @@
5554

5655
import java.io.IOException;
5756
import java.util.ArrayList;
58-
import java.util.Collection;
5957
import java.util.Collections;
6058
import java.util.EnumSet;
6159
import java.util.HashMap;
@@ -999,12 +997,11 @@ private MetadataDiff(StreamInput in) throws IOException {
999997
multiProject = null;
1000998
} else {
1001999
fromNodeBeforeMultiProjectsSupport = false;
1002-
// Repositories metadata is sent as Metadata#customs diff from old node. We need to
1003-
// 1. Split it from the Metadata#customs diff
1004-
// 2. Merge it into the default project's ProjectMetadataDiff
1005-
final var bwcCustoms = maybeReadBwcCustoms(in);
1006-
clusterCustoms = bwcCustoms.v1();
1007-
final var defaultProjectCustoms = bwcCustoms.v2();
1000+
clusterCustoms = DiffableUtils.readImmutableOpenMapDiff(
1001+
in,
1002+
DiffableUtils.getStringKeySerializer(),
1003+
CLUSTER_CUSTOM_VALUE_SERIALIZER
1004+
);
10081005

10091006
reservedStateMetadata = DiffableUtils.readImmutableOpenMapDiff(
10101007
in,
@@ -1013,61 +1010,15 @@ private MetadataDiff(StreamInput in) throws IOException {
10131010
);
10141011

10151012
singleProject = null;
1016-
multiProject = readMultiProjectDiffs(in, defaultProjectCustoms);
1017-
}
1018-
}
1019-
1020-
private static
1021-
Tuple<
1022-
MapDiff<String, ClusterCustom, ImmutableOpenMap<String, ClusterCustom>>,
1023-
MapDiff<String, ProjectCustom, ImmutableOpenMap<String, ProjectCustom>>>
1024-
maybeReadBwcCustoms(StreamInput in) throws IOException {
1025-
if (in.getTransportVersion().before(TransportVersions.REPOSITORIES_METADATA_AS_PROJECT_CUSTOM)) {
1026-
return readBwcCustoms(in);
1027-
} else {
1028-
return new Tuple<>(
1029-
DiffableUtils.readImmutableOpenMapDiff(in, DiffableUtils.getStringKeySerializer(), CLUSTER_CUSTOM_VALUE_SERIALIZER),
1030-
null
1013+
multiProject = DiffableUtils.readJdkMapDiff(
1014+
in,
1015+
PROJECT_ID_SERIALIZER,
1016+
ProjectMetadata::readFrom,
1017+
ProjectMetadata.ProjectMetadataDiff::new
10311018
);
10321019
}
10331020
}
10341021

1035-
@SuppressWarnings("unchecked")
1036-
private static MapDiff<ProjectId, ProjectMetadata, Map<ProjectId, ProjectMetadata>> readMultiProjectDiffs(
1037-
StreamInput in,
1038-
MapDiff<String, ProjectCustom, ImmutableOpenMap<String, ProjectCustom>> defaultProjectCustoms
1039-
) throws IOException {
1040-
final var multiProject = DiffableUtils.readJdkMapDiff(
1041-
in,
1042-
PROJECT_ID_SERIALIZER,
1043-
ProjectMetadata::readFrom,
1044-
ProjectMetadata.ProjectMetadataDiff::new
1045-
);
1046-
1047-
// If the defaultProjectCustoms has content, the diff is read from an old node. We need to merge it into the
1048-
// default project's ProjectMetadataDiff
1049-
if (defaultProjectCustoms != null && defaultProjectCustoms.isEmpty() == false) {
1050-
return DiffableUtils.updateDiffsAndUpserts(multiProject, ProjectId.DEFAULT::equals, (k, v) -> {
1051-
assert ProjectId.DEFAULT.equals(k) : k;
1052-
assert v instanceof ProjectMetadata.ProjectMetadataDiff : v;
1053-
final var projectMetadataDiff = (ProjectMetadata.ProjectMetadataDiff) v;
1054-
return projectMetadataDiff.withCustoms(
1055-
DiffableUtils.merge(
1056-
projectMetadataDiff.customs(),
1057-
defaultProjectCustoms,
1058-
DiffableUtils.getStringKeySerializer(),
1059-
BWC_CUSTOM_VALUE_SERIALIZER
1060-
)
1061-
);
1062-
}, (k, v) -> {
1063-
assert ProjectId.DEFAULT.equals(k) : k;
1064-
return ProjectMetadata.builder(v).clearCustoms().customs(defaultProjectCustoms.apply(v.customs())).build();
1065-
});
1066-
} else {
1067-
return multiProject;
1068-
}
1069-
}
1070-
10711022
@SuppressWarnings("unchecked")
10721023
private static
10731024
Tuple<
@@ -1111,105 +1062,16 @@ public void writeTo(StreamOutput out) throws IOException {
11111062
buildUnifiedCustomDiff().writeTo(out);
11121063
buildUnifiedReservedStateMetadataDiff().writeTo(out);
11131064
} else {
1114-
final var multiProjectToWrite = multiProject != null
1115-
? multiProject
1116-
: DiffableUtils.singleEntryDiff(DEFAULT_PROJECT_ID, singleProject, PROJECT_ID_SERIALIZER);
1117-
1118-
if (out.getTransportVersion().before(TransportVersions.REPOSITORIES_METADATA_AS_PROJECT_CUSTOM)) {
1119-
writeDiffWithRepositoriesMetadataAsClusterCustom(out, clusterCustoms, multiProjectToWrite, reservedStateMetadata);
1065+
clusterCustoms.writeTo(out);
1066+
reservedStateMetadata.writeTo(out);
1067+
if (multiProject != null) {
1068+
multiProject.writeTo(out);
11201069
} else {
1121-
clusterCustoms.writeTo(out);
1122-
reservedStateMetadata.writeTo(out);
1123-
multiProjectToWrite.writeTo(out);
1070+
DiffableUtils.singleEntryDiff(DEFAULT_PROJECT_ID, singleProject, PROJECT_ID_SERIALIZER).writeTo(out);
11241071
}
11251072
}
11261073
}
11271074

1128-
@SuppressWarnings({ "rawtypes", "unchecked" })
1129-
private static void writeDiffWithRepositoriesMetadataAsClusterCustom(
1130-
StreamOutput out,
1131-
MapDiff<String, ClusterCustom, ImmutableOpenMap<String, ClusterCustom>> clusterCustoms,
1132-
MapDiff<ProjectId, ProjectMetadata, Map<ProjectId, ProjectMetadata>> multiProject,
1133-
MapDiff<String, ReservedStateMetadata, ImmutableOpenMap<String, ReservedStateMetadata>> reservedStateMetadata
1134-
) throws IOException {
1135-
assert out.getTransportVersion().onOrAfter(TransportVersions.MULTI_PROJECT)
1136-
&& out.getTransportVersion().before(TransportVersions.REPOSITORIES_METADATA_AS_PROJECT_CUSTOM) : out.getTransportVersion();
1137-
1138-
// For old nodes, RepositoriesMetadata needs to be sent as a cluster custom. This is possible when (a) the repositories
1139-
// are defined only for the default project or (b) no repositories at all. What we need to do are:
1140-
// 1. Iterate through the multi-project's MapDiff to extract the RepositoriesMetadata of the default project
1141-
// 2. Throws if any repositories are found for non-default projects
1142-
// 3. Merge default project's RepositoriesMetadata into Metadata#customs
1143-
final var combineClustersCustoms = new SetOnce<MapDiff<String, MetadataCustom, Map<String, MetadataCustom>>>();
1144-
final var updatedMultiProject = DiffableUtils.updateDiffsAndUpserts(multiProject, ignore -> true, (k, v) -> {
1145-
assert v instanceof ProjectMetadata.ProjectMetadataDiff : v;
1146-
final var projectMetadataDiff = (ProjectMetadata.ProjectMetadataDiff) v;
1147-
final var bwcCustoms = DiffableUtils.split(
1148-
projectMetadataDiff.customs(),
1149-
RepositoriesMetadata.TYPE::equals,
1150-
PROJECT_CUSTOM_VALUE_SERIALIZER,
1151-
type -> RepositoriesMetadata.TYPE.equals(type) == false,
1152-
PROJECT_CUSTOM_VALUE_SERIALIZER
1153-
);
1154-
// Simply return if RepositoriesMetadata is not found
1155-
if (bwcCustoms.v1().isEmpty()) {
1156-
return projectMetadataDiff;
1157-
}
1158-
// RepositoriesMetadata can only be defined for the default project. Otherwise throw exception.
1159-
if (ProjectId.DEFAULT.equals(k) == false) {
1160-
throwForVersionBeforeRepositoriesMetadataMigration(out);
1161-
}
1162-
// RepositoriesMetadata is found for the default project as a diff, merge it into the Metadata#customs
1163-
combineClustersCustoms.set(
1164-
DiffableUtils.<String, MetadataCustom, ClusterCustom, ProjectCustom, Map<String, MetadataCustom>>merge(
1165-
clusterCustoms,
1166-
bwcCustoms.v1(),
1167-
DiffableUtils.getStringKeySerializer()
1168-
)
1169-
);
1170-
return projectMetadataDiff.withCustoms(bwcCustoms.v2());
1171-
}, (k, v) -> {
1172-
final ProjectCustom projectCustom = v.customs().get(RepositoriesMetadata.TYPE);
1173-
// Simply return if RepositoriesMetadata is not found
1174-
if (projectCustom == null) {
1175-
return v;
1176-
}
1177-
// RepositoriesMetadata can only be defined for the default project. Otherwise throw exception.
1178-
if (ProjectId.DEFAULT.equals(k) == false) {
1179-
throwForVersionBeforeRepositoriesMetadataMigration(out);
1180-
}
1181-
// RepositoriesMetadata found for the default project as an upsert, package it as MapDiff and merge into Metadata#customs
1182-
combineClustersCustoms.set(
1183-
DiffableUtils.<String, MetadataCustom, ClusterCustom, ProjectCustom, Map<String, MetadataCustom>>merge(
1184-
clusterCustoms,
1185-
DiffableUtils.singleUpsertDiff(RepositoriesMetadata.TYPE, projectCustom, DiffableUtils.getStringKeySerializer()),
1186-
DiffableUtils.getStringKeySerializer()
1187-
)
1188-
);
1189-
return ProjectMetadata.builder(v).removeCustom(RepositoriesMetadata.TYPE).build();
1190-
});
1191-
1192-
if (combineClustersCustoms.get() != null) {
1193-
combineClustersCustoms.get().writeTo(out);
1194-
} else {
1195-
clusterCustoms.writeTo(out);
1196-
}
1197-
1198-
reservedStateMetadata.writeTo(out);
1199-
updatedMultiProject.writeTo(out);
1200-
}
1201-
1202-
private static void throwForVersionBeforeRepositoriesMetadataMigration(StreamOutput out) {
1203-
assert out.getTransportVersion().before(TransportVersions.REPOSITORIES_METADATA_AS_PROJECT_CUSTOM) : out.getTransportVersion();
1204-
throw new UnsupportedOperationException(
1205-
"Serialize a diff with repositories defined for multiple projects requires version on or after ["
1206-
+ TransportVersions.REPOSITORIES_METADATA_AS_PROJECT_CUSTOM
1207-
+ "], but got ["
1208-
+ out.getTransportVersion()
1209-
+ "]"
1210-
);
1211-
}
1212-
12131075
@SuppressWarnings("unchecked")
12141076
private Diff<ImmutableOpenMap<String, ?>> buildUnifiedCustomDiff() {
12151077
assert multiProject == null : "should only be used for single project metadata";
@@ -1363,34 +1225,19 @@ public static Metadata readFrom(StreamInput in) throws IOException {
13631225
builder.put(ReservedStateMetadata.readFrom(in));
13641226
}
13651227
} else {
1366-
List<ProjectCustom> defaultProjectCustoms = List.of();
1367-
if (in.getTransportVersion().before(TransportVersions.REPOSITORIES_METADATA_AS_PROJECT_CUSTOM)) {
1368-
// Extract the default project's repositories metadata from the Metadata#customs from an old node
1369-
defaultProjectCustoms = new ArrayList<>();
1370-
readBwcCustoms(in, builder, defaultProjectCustoms::add);
1371-
assert defaultProjectCustoms.size() <= 1
1372-
: "expect only a single default project custom for repository metadata, but got "
1373-
+ defaultProjectCustoms.stream().map(ProjectCustom::getWriteableName).toList();
1374-
} else {
1375-
readClusterCustoms(in, builder);
1376-
}
1228+
readClusterCustoms(in, builder);
13771229

13781230
int reservedStateSize = in.readVInt();
13791231
for (int i = 0; i < reservedStateSize; i++) {
13801232
builder.put(ReservedStateMetadata.readFrom(in));
13811233
}
13821234

13831235
builder.projectMetadata(in.readMap(ProjectId::readFrom, ProjectMetadata::readFrom));
1384-
defaultProjectCustoms.forEach(c -> builder.getProject(ProjectId.DEFAULT).putCustom(c.getWriteableName(), c));
13851236
}
13861237
return builder.build();
13871238
}
13881239

13891240
private static void readBwcCustoms(StreamInput in, Builder builder) throws IOException {
1390-
readBwcCustoms(in, builder, projectCustom -> builder.putProjectCustom(projectCustom.getWriteableName(), projectCustom));
1391-
}
1392-
1393-
private static void readBwcCustoms(StreamInput in, Builder builder, Consumer<ProjectCustom> projectCustomConsumer) throws IOException {
13941241
final Set<String> clusterScopedNames = in.namedWriteableRegistry().getReaders(ClusterCustom.class).keySet();
13951242
final Set<String> projectScopedNames = in.namedWriteableRegistry().getReaders(ProjectCustom.class).keySet();
13961243
final int count = in.readVInt();
@@ -1406,9 +1253,9 @@ private static void readBwcCustoms(StreamInput in, Builder builder, Consumer<Pro
14061253
if (custom instanceof PersistentTasksCustomMetadata persistentTasksCustomMetadata) {
14071254
final var tuple = persistentTasksCustomMetadata.split();
14081255
builder.putCustom(tuple.v1().getWriteableName(), tuple.v1());
1409-
projectCustomConsumer.accept(tuple.v2());
1256+
builder.putProjectCustom(tuple.v2().getWriteableName(), tuple.v2());
14101257
} else {
1411-
projectCustomConsumer.accept(custom);
1258+
builder.putProjectCustom(custom.getWriteableName(), custom);
14121259
}
14131260
} else {
14141261
throw new IllegalArgumentException("Unknown custom name [" + name + "]");
@@ -1475,42 +1322,13 @@ public void writeTo(StreamOutput out) throws IOException {
14751322
combinedMetadata.addAll(singleProject.reservedStateMetadata().values());
14761323
out.writeCollection(combinedMetadata);
14771324
} else {
1478-
if (out.getTransportVersion().before(TransportVersions.REPOSITORIES_METADATA_AS_PROJECT_CUSTOM)) {
1479-
if (isSingleProject() || hasNoNonDefaultProjectRepositories(projects().values())) {
1480-
// Repositories metadata must be sent as Metadata#customs for old nodes
1481-
final List<VersionedNamedWriteable> combinedCustoms = new ArrayList<>(customs.size() + 1);
1482-
combinedCustoms.addAll(customs.values());
1483-
final ProjectCustom custom = getProject(ProjectId.DEFAULT).custom(RepositoriesMetadata.TYPE);
1484-
if (custom != null) {
1485-
combinedCustoms.add(custom);
1486-
}
1487-
VersionedNamedWriteable.writeVersionedWriteables(out, combinedCustoms);
1488-
} else {
1489-
throw new UnsupportedOperationException(
1490-
"Serialize metadata with repositories defined for multiple projects requires version on or after ["
1491-
+ TransportVersions.REPOSITORIES_METADATA_AS_PROJECT_CUSTOM
1492-
+ "], but got ["
1493-
+ out.getTransportVersion()
1494-
+ "]"
1495-
);
1496-
}
1497-
} else {
1498-
VersionedNamedWriteable.writeVersionedWriteables(out, customs.values());
1499-
}
1325+
VersionedNamedWriteable.writeVersionedWriteables(out, customs.values());
15001326

15011327
out.writeCollection(reservedStateMetadata.values());
15021328
out.writeMap(projectMetadata, StreamOutput::writeWriteable, StreamOutput::writeWriteable);
15031329
}
15041330
}
15051331

1506-
/**
1507-
* @return {@code true} iff no repositories are defined for non-default-projects.
1508-
*/
1509-
private static boolean hasNoNonDefaultProjectRepositories(Collection<ProjectMetadata> projects) {
1510-
return projects.stream()
1511-
.allMatch(project -> ProjectId.DEFAULT.equals(project.id()) || project.custom(RepositoriesMetadata.TYPE) == null);
1512-
}
1513-
15141332
public static Builder builder() {
15151333
return new Builder();
15161334
}

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

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1530,11 +1530,6 @@ public Builder removeCustomIf(BiPredicate<String, ? super Metadata.ProjectCustom
15301530
return this;
15311531
}
15321532

1533-
public Builder clearCustoms() {
1534-
customs.clear();
1535-
return this;
1536-
}
1537-
15381533
public Builder customs(Map<String, Metadata.ProjectCustom> customs) {
15391534
customs.forEach((key, value) -> Objects.requireNonNull(value, key));
15401535
this.customs.putAllFromMap(customs);
@@ -2266,17 +2261,7 @@ public void writeTo(StreamOutput out) throws IOException {
22662261
indexMetadata.writeTo(out, true);
22672262
}
22682263
out.writeCollection(templates.values());
2269-
Collection<Metadata.ProjectCustom> filteredCustoms = customs.values();
2270-
if (out.getTransportVersion().before(TransportVersions.REPOSITORIES_METADATA_AS_PROJECT_CUSTOM)) {
2271-
// RepositoriesMetadata is sent as part of Metadata#customs for version before RepositoriesMetadata migration
2272-
// So we exclude it from the project level customs
2273-
if (custom(RepositoriesMetadata.TYPE) != null) {
2274-
assert ProjectId.DEFAULT.equals(id)
2275-
: "Only default project can have repositories metadata. Otherwise the code should have thrown before it reaches here";
2276-
filteredCustoms = filteredCustoms.stream().filter(custom -> custom instanceof RepositoriesMetadata == false).toList();
2277-
}
2278-
}
2279-
VersionedNamedWriteable.writeVersionedWriteables(out, filteredCustoms);
2264+
VersionedNamedWriteable.writeVersionedWriteables(out, customs.values());
22802265
out.writeCollection(reservedStateMetadata.values());
22812266

22822267
if (out.getTransportVersion().onOrAfter(TransportVersions.PROJECT_METADATA_SETTINGS)) {
@@ -2409,12 +2394,6 @@ public ProjectMetadata apply(ProjectMetadata part) {
24092394
builder.settings = settingsDiff.apply(part.settings);
24102395
return builder.build(true);
24112396
}
2412-
2413-
ProjectMetadataDiff withCustoms(
2414-
DiffableUtils.MapDiff<String, Metadata.ProjectCustom, ImmutableOpenMap<String, Metadata.ProjectCustom>> customs
2415-
) {
2416-
return new ProjectMetadataDiff(indices, templates, customs, reservedStateMetadata, settingsDiff);
2417-
}
24182397
}
24192398

24202399
@Override

0 commit comments

Comments
 (0)