Skip to content

Commit 0e83b19

Browse files
authored
Remove obsolete Metadata BWC for repositories (elastic#129685)
When migrating RepositoriesMetadata from cluster custom to project custom (elastic#125398), 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 4ce06d1 commit 0e83b19

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;
@@ -53,7 +52,6 @@
5352

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

10071004
reservedStateMetadata = DiffableUtils.readImmutableOpenMapDiff(
10081005
in,
@@ -1011,61 +1008,15 @@ private MetadataDiff(StreamInput in) throws IOException {
10111008
);
10121009

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

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

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

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

13811233
builder.projectMetadata(in.readMap(ProjectId::readFrom, ProjectMetadata::readFrom));
1382-
defaultProjectCustoms.forEach(c -> builder.getProject(ProjectId.DEFAULT).putCustom(c.getWriteableName(), c));
13831234
}
13841235
return builder.build();
13851236
}
13861237

13871238
private static void readBwcCustoms(StreamInput in, Builder builder) throws IOException {
1388-
readBwcCustoms(in, builder, projectCustom -> builder.putProjectCustom(projectCustom.getWriteableName(), projectCustom));
1389-
}
1390-
1391-
private static void readBwcCustoms(StreamInput in, Builder builder, Consumer<ProjectCustom> projectCustomConsumer) throws IOException {
13921239
final Set<String> clusterScopedNames = in.namedWriteableRegistry().getReaders(ClusterCustom.class).keySet();
13931240
final Set<String> projectScopedNames = in.namedWriteableRegistry().getReaders(ProjectCustom.class).keySet();
13941241
final int count = in.readVInt();
@@ -1404,9 +1251,9 @@ private static void readBwcCustoms(StreamInput in, Builder builder, Consumer<Pro
14041251
if (custom instanceof PersistentTasksCustomMetadata persistentTasksCustomMetadata) {
14051252
final var tuple = persistentTasksCustomMetadata.split();
14061253
builder.putCustom(tuple.v1().getWriteableName(), tuple.v1());
1407-
projectCustomConsumer.accept(tuple.v2());
1254+
builder.putProjectCustom(tuple.v2().getWriteableName(), tuple.v2());
14081255
} else {
1409-
projectCustomConsumer.accept(custom);
1256+
builder.putProjectCustom(custom.getWriteableName(), custom);
14101257
}
14111258
} else {
14121259
throw new IllegalArgumentException("Unknown custom name [" + name + "]");
@@ -1473,42 +1320,13 @@ public void writeTo(StreamOutput out) throws IOException {
14731320
combinedMetadata.addAll(singleProject.reservedStateMetadata().values());
14741321
out.writeCollection(combinedMetadata);
14751322
} else {
1476-
if (out.getTransportVersion().before(TransportVersions.REPOSITORIES_METADATA_AS_PROJECT_CUSTOM)) {
1477-
if (isSingleProject() || hasNoNonDefaultProjectRepositories(projects().values())) {
1478-
// Repositories metadata must be sent as Metadata#customs for old nodes
1479-
final List<VersionedNamedWriteable> combinedCustoms = new ArrayList<>(customs.size() + 1);
1480-
combinedCustoms.addAll(customs.values());
1481-
final ProjectCustom custom = getProject(ProjectId.DEFAULT).custom(RepositoriesMetadata.TYPE);
1482-
if (custom != null) {
1483-
combinedCustoms.add(custom);
1484-
}
1485-
VersionedNamedWriteable.writeVersionedWriteables(out, combinedCustoms);
1486-
} else {
1487-
throw new UnsupportedOperationException(
1488-
"Serialize metadata with repositories defined for multiple projects requires version on or after ["
1489-
+ TransportVersions.REPOSITORIES_METADATA_AS_PROJECT_CUSTOM
1490-
+ "], but got ["
1491-
+ out.getTransportVersion()
1492-
+ "]"
1493-
);
1494-
}
1495-
} else {
1496-
VersionedNamedWriteable.writeVersionedWriteables(out, customs.values());
1497-
}
1323+
VersionedNamedWriteable.writeVersionedWriteables(out, customs.values());
14981324

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

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

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)