Skip to content

Commit c823358

Browse files
authored
Add project-id to SnapshotDeletionsInProgress and RepositoryCleanupInProgress (#129462)
This PR adds project-id to both SnapshotDeletionsInProgress and RepositoryCleanupInProgress so that they become project aware. Note that making service code to configure and use the project-id accordingly will be worked on separately. Resolves: ES-11380 Relates: #125470
1 parent adf4d10 commit c823358

File tree

11 files changed

+369
-33
lines changed

11 files changed

+369
-33
lines changed

build-tools-internal/src/main/resources/forbidden/es-server-signatures.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ org.elasticsearch.cluster.ClusterFeatures#clusterHasFeature(org.elasticsearch.cl
160160

161161
@defaultMessage Do not construct this records outside the source files they are declared in
162162
org.elasticsearch.cluster.SnapshotsInProgress$ShardSnapshotStatus#<init>(java.lang.String, org.elasticsearch.cluster.SnapshotsInProgress$ShardState, org.elasticsearch.repositories.ShardGeneration, java.lang.String, org.elasticsearch.repositories.ShardSnapshotResult)
163-
org.elasticsearch.cluster.SnapshotDeletionsInProgress$Entry#<init>(java.lang.String, java.util.List, long, long, org.elasticsearch.cluster.SnapshotDeletionsInProgress$State, java.lang.String)
163+
org.elasticsearch.cluster.SnapshotDeletionsInProgress$Entry#<init>(org.elasticsearch.cluster.metadata.ProjectId, java.lang.String, java.util.List, long, long, org.elasticsearch.cluster.SnapshotDeletionsInProgress$State, java.lang.String)
164164

165165
@defaultMessage Use a Thread constructor with a name, anonymous threads are more difficult to debug
166166
java.lang.Thread#<init>(java.lang.Runnable)

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ static TransportVersion def(int id) {
300300
public static final TransportVersion PROJECT_DELETION_GLOBAL_BLOCK = def(9_098_0_00);
301301
public static final TransportVersion SECURITY_CLOUD_API_KEY_REALM_AND_TYPE = def(9_099_0_00);
302302
public static final TransportVersion STATE_PARAM_GET_SNAPSHOT = def(9_100_0_00);
303+
public static final TransportVersion PROJECT_ID_IN_SNAPSHOTS_DELETIONS_AND_REPO_CLEANUP = def(9_101_0_00);
303304

304305
/*
305306
* STOP! READ THIS FIRST! No, really,

server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/cleanup/TransportCleanupRepositoryAction.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@
2121
import org.elasticsearch.cluster.SnapshotsInProgress;
2222
import org.elasticsearch.cluster.block.ClusterBlockException;
2323
import org.elasticsearch.cluster.block.ClusterBlockLevel;
24+
import org.elasticsearch.cluster.metadata.ProjectId;
2425
import org.elasticsearch.cluster.node.DiscoveryNode;
2526
import org.elasticsearch.cluster.service.ClusterService;
2627
import org.elasticsearch.common.blobstore.DeleteResult;
2728
import org.elasticsearch.common.util.concurrent.EsExecutors;
2829
import org.elasticsearch.common.util.concurrent.ListenableFuture;
30+
import org.elasticsearch.core.FixForMultiProject;
2931
import org.elasticsearch.core.Nullable;
3032
import org.elasticsearch.core.SuppressForbidden;
3133
import org.elasticsearch.injection.guice.Inject;
@@ -198,11 +200,13 @@ public ClusterState execute(ClusterState currentState) {
198200
"Cannot cleanup [" + repositoryName + "] - a snapshot is currently running in [" + snapshots + "]"
199201
);
200202
}
203+
@FixForMultiProject
204+
final var projectId = ProjectId.DEFAULT;
201205
return ClusterState.builder(currentState)
202206
.putCustom(
203207
RepositoryCleanupInProgress.TYPE,
204208
new RepositoryCleanupInProgress(
205-
List.of(RepositoryCleanupInProgress.startedEntry(repositoryName, repositoryStateId))
209+
List.of(RepositoryCleanupInProgress.startedEntry(projectId, repositoryName, repositoryStateId))
206210
)
207211
)
208212
.build();

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

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
import org.elasticsearch.TransportVersion;
1212
import org.elasticsearch.TransportVersions;
13+
import org.elasticsearch.cluster.metadata.ProjectId;
1314
import org.elasticsearch.common.Strings;
1415
import org.elasticsearch.common.collect.Iterators;
1516
import org.elasticsearch.common.io.stream.StreamInput;
@@ -21,6 +22,9 @@
2122
import java.io.IOException;
2223
import java.util.Iterator;
2324
import java.util.List;
25+
import java.util.Objects;
26+
27+
import static org.elasticsearch.TransportVersions.PROJECT_ID_IN_SNAPSHOTS_DELETIONS_AND_REPO_CLEANUP;
2428

2529
/**
2630
* A repository cleanup request entry. Part of the cluster state.
@@ -49,8 +53,8 @@ public static NamedDiff<ClusterState.Custom> readDiffFrom(StreamInput in) throws
4953
return readDiffFrom(ClusterState.Custom.class, TYPE, in);
5054
}
5155

52-
public static Entry startedEntry(String repository, long repositoryStateId) {
53-
return new Entry(repository, repositoryStateId);
56+
public static Entry startedEntry(ProjectId projectId, String repository, long repositoryStateId) {
57+
return new Entry(projectId, repository, repositoryStateId);
5458
}
5559

5660
public boolean hasCleanupInProgress() {
@@ -86,6 +90,18 @@ public Iterator<? extends ToXContent> toXContentChunked(ToXContent.Params ignore
8690
);
8791
}
8892

93+
@Override
94+
public boolean equals(Object o) {
95+
if (o == null || getClass() != o.getClass()) return false;
96+
RepositoryCleanupInProgress that = (RepositoryCleanupInProgress) o;
97+
return Objects.equals(entries, that.entries);
98+
}
99+
100+
@Override
101+
public int hashCode() {
102+
return Objects.hashCode(entries);
103+
}
104+
89105
@Override
90106
public String toString() {
91107
return Strings.toString(this);
@@ -96,24 +112,44 @@ public TransportVersion getMinimalSupportedVersion() {
96112
return TransportVersions.ZERO;
97113
}
98114

99-
public record Entry(String repository, long repositoryStateId) implements Writeable, RepositoryOperation {
115+
public record Entry(ProjectId projectId, String repository, long repositoryStateId) implements Writeable, RepositoryOperation {
100116

101117
public static Entry readFrom(StreamInput in) throws IOException {
102-
return new Entry(in.readString(), in.readLong());
118+
final ProjectId projectId = in.getTransportVersion().onOrAfter(PROJECT_ID_IN_SNAPSHOTS_DELETIONS_AND_REPO_CLEANUP)
119+
? ProjectId.readFrom(in)
120+
: ProjectId.DEFAULT;
121+
return new Entry(projectId, in.readString(), in.readLong());
103122
}
104123

105124
@Override
106125
public long repositoryStateId() {
107126
return repositoryStateId;
108127
}
109128

129+
@Override
130+
public ProjectId projectId() {
131+
return projectId;
132+
}
133+
110134
@Override
111135
public String repository() {
112136
return repository;
113137
}
114138

115139
@Override
116140
public void writeTo(StreamOutput out) throws IOException {
141+
if (out.getTransportVersion().onOrAfter(PROJECT_ID_IN_SNAPSHOTS_DELETIONS_AND_REPO_CLEANUP)) {
142+
projectId.writeTo(out);
143+
} else {
144+
if (ProjectId.DEFAULT.equals(projectId) == false) {
145+
final var message = "Cannot write repository cleanup entry with non-default project id "
146+
+ projectId
147+
+ " to version before "
148+
+ PROJECT_ID_IN_SNAPSHOTS_DELETIONS_AND_REPO_CLEANUP;
149+
assert false : message;
150+
throw new IllegalStateException(message);
151+
}
152+
}
117153
out.writeString(repository);
118154
out.writeLong(repositoryStateId);
119155
}

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

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.elasticsearch.TransportVersion;
1313
import org.elasticsearch.TransportVersions;
1414
import org.elasticsearch.cluster.ClusterState.Custom;
15+
import org.elasticsearch.cluster.metadata.ProjectId;
1516
import org.elasticsearch.common.UUIDs;
1617
import org.elasticsearch.common.collect.Iterators;
1718
import org.elasticsearch.common.io.stream.StreamInput;
@@ -32,6 +33,8 @@
3233
import java.util.List;
3334
import java.util.Set;
3435

36+
import static org.elasticsearch.TransportVersions.PROJECT_ID_IN_SNAPSHOTS_DELETIONS_AND_REPO_CLEANUP;
37+
3538
/**
3639
* Represents the in-progress snapshot deletions in the cluster state.
3740
*/
@@ -174,6 +177,7 @@ public Iterator<? extends ToXContent> toXContentChunked(ToXContent.Params ignore
174177
Iterators.map(entries.iterator(), entry -> (builder, params) -> {
175178
builder.startObject();
176179
{
180+
builder.field("project_id", entry.projectId);
177181
builder.field("repository", entry.repository());
178182
builder.startArray("snapshots");
179183
for (SnapshotId snapshot : entry.snapshots) {
@@ -206,14 +210,26 @@ public String toString() {
206210
/**
207211
* A class representing a snapshot deletion request entry in the cluster state.
208212
*/
209-
public record Entry(String repoName, List<SnapshotId> snapshots, long startTime, long repositoryStateId, State state, String uuid)
210-
implements
211-
Writeable,
212-
RepositoryOperation {
213+
public record Entry(
214+
ProjectId projectId,
215+
String repoName,
216+
List<SnapshotId> snapshots,
217+
long startTime,
218+
long repositoryStateId,
219+
State state,
220+
String uuid
221+
) implements Writeable, RepositoryOperation {
213222

214223
@SuppressForbidden(reason = "using a private constructor within the same file")
215-
public Entry(String repoName, List<SnapshotId> snapshots, long startTime, long repositoryStateId, State state) {
216-
this(repoName, snapshots, startTime, repositoryStateId, state, UUIDs.randomBase64UUID());
224+
public Entry(
225+
ProjectId projectId,
226+
String repoName,
227+
List<SnapshotId> snapshots,
228+
long startTime,
229+
long repositoryStateId,
230+
State state
231+
) {
232+
this(projectId, repoName, snapshots, startTime, repositoryStateId, state, UUIDs.randomBase64UUID());
217233
}
218234

219235
public Entry {
@@ -222,7 +238,11 @@ public Entry(String repoName, List<SnapshotId> snapshots, long startTime, long r
222238

223239
@SuppressForbidden(reason = "using a private constructor within the same file")
224240
public static Entry readFrom(StreamInput in) throws IOException {
241+
final ProjectId projectId = in.getTransportVersion().onOrAfter(PROJECT_ID_IN_SNAPSHOTS_DELETIONS_AND_REPO_CLEANUP)
242+
? ProjectId.readFrom(in)
243+
: ProjectId.DEFAULT;
225244
return new Entry(
245+
projectId,
226246
in.readString(),
227247
in.readCollectionAsImmutableList(SnapshotId::new),
228248
in.readVLong(),
@@ -235,7 +255,7 @@ public static Entry readFrom(StreamInput in) throws IOException {
235255
@SuppressForbidden(reason = "using a private constructor within the same file")
236256
public Entry started() {
237257
assert state == State.WAITING;
238-
return new Entry(repository(), snapshots, startTime, repositoryStateId, State.STARTED, uuid);
258+
return new Entry(projectId(), repository(), snapshots, startTime, repositoryStateId, State.STARTED, uuid);
239259
}
240260

241261
@SuppressForbidden(reason = "using a private constructor within the same file")
@@ -245,21 +265,33 @@ public Entry withAddedSnapshots(Collection<SnapshotId> newSnapshots) {
245265
if (updatedSnapshots.addAll(newSnapshots) == false) {
246266
return this;
247267
}
248-
return new Entry(repository(), List.copyOf(updatedSnapshots), startTime, repositoryStateId, State.WAITING, uuid);
268+
return new Entry(projectId(), repository(), List.copyOf(updatedSnapshots), startTime, repositoryStateId, State.WAITING, uuid);
249269
}
250270

251271
@SuppressForbidden(reason = "using a private constructor within the same file")
252272
public Entry withSnapshots(Collection<SnapshotId> snapshots) {
253-
return new Entry(repository(), List.copyOf(snapshots), startTime, repositoryStateId, state, uuid);
273+
return new Entry(projectId(), repository(), List.copyOf(snapshots), startTime, repositoryStateId, state, uuid);
254274
}
255275

256276
@SuppressForbidden(reason = "using a private constructor within the same file")
257277
public Entry withRepoGen(long repoGen) {
258-
return new Entry(repository(), snapshots, startTime, repoGen, state, uuid);
278+
return new Entry(projectId(), repository(), snapshots, startTime, repoGen, state, uuid);
259279
}
260280

261281
@Override
262282
public void writeTo(StreamOutput out) throws IOException {
283+
if (out.getTransportVersion().onOrAfter(PROJECT_ID_IN_SNAPSHOTS_DELETIONS_AND_REPO_CLEANUP)) {
284+
projectId.writeTo(out);
285+
} else {
286+
if (ProjectId.DEFAULT.equals(projectId) == false) {
287+
final var message = "Cannot write snapshot deletion entry with non-default project id "
288+
+ projectId
289+
+ " to version before "
290+
+ PROJECT_ID_IN_SNAPSHOTS_DELETIONS_AND_REPO_CLEANUP;
291+
assert false : message;
292+
throw new IllegalStateException(message);
293+
}
294+
}
263295
out.writeString(repoName);
264296
out.writeCollection(snapshots);
265297
out.writeVLong(startTime);
@@ -268,6 +300,11 @@ public void writeTo(StreamOutput out) throws IOException {
268300
out.writeString(uuid);
269301
}
270302

303+
@Override
304+
public ProjectId projectId() {
305+
return projectId;
306+
}
307+
271308
@Override
272309
public String repository() {
273310
return repoName;

server/src/main/java/org/elasticsearch/repositories/RepositoryOperation.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,10 @@
99
package org.elasticsearch.repositories;
1010

1111
import org.elasticsearch.cluster.DiffableUtils;
12-
import org.elasticsearch.cluster.metadata.Metadata;
1312
import org.elasticsearch.cluster.metadata.ProjectId;
1413
import org.elasticsearch.common.io.stream.StreamInput;
1514
import org.elasticsearch.common.io.stream.StreamOutput;
1615
import org.elasticsearch.common.io.stream.Writeable;
17-
import org.elasticsearch.core.FixForMultiProject;
1816

1917
import java.io.IOException;
2018

@@ -26,10 +24,7 @@ public interface RepositoryOperation {
2624
/**
2725
* Project for which repository belongs to.
2826
*/
29-
@FixForMultiProject(description = "default implementation is temporary")
30-
default ProjectId projectId() {
31-
return Metadata.DEFAULT_PROJECT_ID;
32-
}
27+
ProjectId projectId();
3328

3429
/**
3530
* Name of the repository affected.

server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import org.elasticsearch.cluster.metadata.IndexMetadata;
4848
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
4949
import org.elasticsearch.cluster.metadata.Metadata;
50+
import org.elasticsearch.cluster.metadata.ProjectId;
5051
import org.elasticsearch.cluster.metadata.ProjectMetadata;
5152
import org.elasticsearch.cluster.metadata.RepositoriesMetadata;
5253
import org.elasticsearch.cluster.metadata.RepositoryMetadata;
@@ -2255,7 +2256,10 @@ public ClusterState execute(ClusterState currentState) {
22552256
reusedExistingDelete = true;
22562257
return currentState;
22572258
}
2259+
@FixForMultiProject
2260+
final var projectId = ProjectId.DEFAULT;
22582261
newDelete = new SnapshotDeletionsInProgress.Entry(
2262+
projectId,
22592263
repositoryName,
22602264
List.copyOf(snapshotIdsRequiringCleanup),
22612265
threadPool.absoluteTimeInMillis(),

server/src/test/java/org/elasticsearch/cluster/ClusterSnapshotStatsTests.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
package org.elasticsearch.cluster;
1111

1212
import org.elasticsearch.cluster.metadata.Metadata;
13+
import org.elasticsearch.cluster.metadata.ProjectId;
1314
import org.elasticsearch.cluster.metadata.RepositoriesMetadata;
1415
import org.elasticsearch.cluster.metadata.RepositoryMetadata;
1516
import org.elasticsearch.common.io.stream.Writeable;
@@ -434,6 +435,7 @@ public void testComputation() {
434435
SnapshotDeletionsInProgress.of(
435436
List.of(
436437
new SnapshotDeletionsInProgress.Entry(
438+
ProjectId.DEFAULT,
437439
"test-repo",
438440
List.of(new SnapshotId("deleting", "uuid")),
439441
startTimes[2],
@@ -446,7 +448,7 @@ public void testComputation() {
446448
.putCustom(
447449
RepositoryCleanupInProgress.TYPE,
448450
new RepositoryCleanupInProgress(
449-
List.of(new RepositoryCleanupInProgress.Entry("test-repo", randomNonNegativeLong()))
451+
List.of(new RepositoryCleanupInProgress.Entry(ProjectId.DEFAULT, "test-repo", randomNonNegativeLong()))
450452
)
451453
)
452454
.build(),

0 commit comments

Comments
 (0)