Skip to content

Commit 8bd0bef

Browse files
authored
Make restore support multi-project (#131661)
This PR makes the restore process project aware and unmute relevant tests. The later requires TransportRecoveryAction to be project aware which is done in this PR as well. Relates: #130000 Resolves: ES-10228
1 parent 80faf64 commit 8bd0bef

File tree

19 files changed

+318
-175
lines changed

19 files changed

+318
-175
lines changed

modules/data-streams/src/internalClusterTest/java/org/elasticsearch/datastreams/DataStreamsSnapshotsIT.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import org.elasticsearch.search.SearchHit;
4848
import org.elasticsearch.snapshots.AbstractSnapshotIntegTestCase;
4949
import org.elasticsearch.snapshots.RestoreInfo;
50+
import org.elasticsearch.snapshots.Snapshot;
5051
import org.elasticsearch.snapshots.SnapshotId;
5152
import org.elasticsearch.snapshots.SnapshotInProgressException;
5253
import org.elasticsearch.snapshots.SnapshotInfo;
@@ -1394,7 +1395,7 @@ public void testWarningHeaderOnRestoreWithoutTemplates() throws Exception {
13941395
.get();
13951396

13961397
RestStatus status = createSnapshotResponse.getSnapshotInfo().status();
1397-
SnapshotId snapshotId = createSnapshotResponse.getSnapshotInfo().snapshotId();
1398+
Snapshot snapshot = createSnapshotResponse.getSnapshotInfo().snapshot();
13981399
assertEquals(RestStatus.OK, status);
13991400

14001401
assertEquals(Collections.singletonList(dsBackingIndexName), getSnapshot(REPO, SNAPSHOT).indices());
@@ -1423,7 +1424,7 @@ public void testWarningHeaderOnRestoreWithoutTemplates() throws Exception {
14231424
client,
14241425
request,
14251426
"Snapshot ["
1426-
+ snapshotId
1427+
+ snapshot
14271428
+ "] contains data stream ["
14281429
+ datastreamName
14291430
+ "] but custer does not have a matching index "

server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/restore/TransportRestoreSnapshotAction.java

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.elasticsearch.cluster.ClusterState;
1717
import org.elasticsearch.cluster.block.ClusterBlockException;
1818
import org.elasticsearch.cluster.block.ClusterBlockLevel;
19+
import org.elasticsearch.cluster.project.ProjectResolver;
1920
import org.elasticsearch.cluster.service.ClusterService;
2021
import org.elasticsearch.injection.guice.Inject;
2122
import org.elasticsearch.snapshots.RestoreService;
@@ -29,14 +30,16 @@
2930
public class TransportRestoreSnapshotAction extends TransportMasterNodeAction<RestoreSnapshotRequest, RestoreSnapshotResponse> {
3031
public static final ActionType<RestoreSnapshotResponse> TYPE = new ActionType<>("cluster:admin/snapshot/restore");
3132
private final RestoreService restoreService;
33+
private final ProjectResolver projectResolver;
3234

3335
@Inject
3436
public TransportRestoreSnapshotAction(
3537
TransportService transportService,
3638
ClusterService clusterService,
3739
ThreadPool threadPool,
3840
RestoreService restoreService,
39-
ActionFilters actionFilters
41+
ActionFilters actionFilters,
42+
ProjectResolver projectResolver
4043
) {
4144
super(
4245
TYPE.name(),
@@ -49,13 +52,15 @@ public TransportRestoreSnapshotAction(
4952
threadPool.executor(ThreadPool.Names.SNAPSHOT_META)
5053
);
5154
this.restoreService = restoreService;
55+
this.projectResolver = projectResolver;
5256
}
5357

5458
@Override
5559
protected ClusterBlockException checkBlock(RestoreSnapshotRequest request, ClusterState state) {
5660
// Restoring a snapshot might change the global state and create/change an index,
5761
// so we need to check for METADATA_WRITE and WRITE blocks
58-
ClusterBlockException blockException = state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE);
62+
ClusterBlockException blockException = state.blocks()
63+
.globalBlockedException(projectResolver.getProjectId(), ClusterBlockLevel.METADATA_WRITE);
5964
if (blockException != null) {
6065
return blockException;
6166
}
@@ -70,17 +75,21 @@ protected void masterOperation(
7075
final ClusterState state,
7176
final ActionListener<RestoreSnapshotResponse> listener
7277
) {
73-
restoreService.restoreSnapshot(request, listener.delegateFailure((delegatedListener, restoreCompletionResponse) -> {
74-
if (restoreCompletionResponse.restoreInfo() == null && request.waitForCompletion()) {
75-
RestoreClusterStateListener.createAndRegisterListener(
76-
clusterService,
77-
restoreCompletionResponse,
78-
delegatedListener,
79-
threadPool.getThreadContext()
80-
);
81-
} else {
82-
delegatedListener.onResponse(new RestoreSnapshotResponse(restoreCompletionResponse.restoreInfo()));
83-
}
84-
}));
78+
restoreService.restoreSnapshot(
79+
projectResolver.getProjectId(),
80+
request,
81+
listener.delegateFailure((delegatedListener, restoreCompletionResponse) -> {
82+
if (restoreCompletionResponse.restoreInfo() == null && request.waitForCompletion()) {
83+
RestoreClusterStateListener.createAndRegisterListener(
84+
clusterService,
85+
restoreCompletionResponse,
86+
delegatedListener,
87+
threadPool.getThreadContext()
88+
);
89+
} else {
90+
delegatedListener.onResponse(new RestoreSnapshotResponse(restoreCompletionResponse.restoreInfo()));
91+
}
92+
})
93+
);
8594
}
8695
}

server/src/main/java/org/elasticsearch/action/admin/indices/recovery/TransportRecoveryAction.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.elasticsearch.cluster.block.ClusterBlockException;
1717
import org.elasticsearch.cluster.block.ClusterBlockLevel;
1818
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
19+
import org.elasticsearch.cluster.project.ProjectResolver;
1920
import org.elasticsearch.cluster.routing.ShardRouting;
2021
import org.elasticsearch.cluster.routing.ShardsIterator;
2122
import org.elasticsearch.cluster.service.ClusterService;
@@ -43,14 +44,16 @@
4344
public class TransportRecoveryAction extends TransportBroadcastByNodeAction<RecoveryRequest, RecoveryResponse, RecoveryState> {
4445

4546
private final IndicesService indicesService;
47+
private final ProjectResolver projectResolver;
4648

4749
@Inject
4850
public TransportRecoveryAction(
4951
ClusterService clusterService,
5052
TransportService transportService,
5153
IndicesService indicesService,
5254
ActionFilters actionFilters,
53-
IndexNameExpressionResolver indexNameExpressionResolver
55+
IndexNameExpressionResolver indexNameExpressionResolver,
56+
ProjectResolver projectResolver
5457
) {
5558
super(
5659
RecoveryAction.NAME,
@@ -62,6 +65,7 @@ public TransportRecoveryAction(
6265
transportService.getThreadPool().executor(ThreadPool.Names.MANAGEMENT)
6366
);
6467
this.indicesService = indicesService;
68+
this.projectResolver = projectResolver;
6569
}
6670

6771
@Override
@@ -110,16 +114,16 @@ protected void shardOperation(RecoveryRequest request, ShardRouting shardRouting
110114

111115
@Override
112116
protected ShardsIterator shards(ClusterState state, RecoveryRequest request, String[] concreteIndices) {
113-
return state.routingTable().allShardsIncludingRelocationTargets(concreteIndices);
117+
return state.routingTable(projectResolver.getProjectId()).allShardsIncludingRelocationTargets(concreteIndices);
114118
}
115119

116120
@Override
117121
protected ClusterBlockException checkGlobalBlock(ClusterState state, RecoveryRequest request) {
118-
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_READ);
122+
return state.blocks().globalBlockedException(projectResolver.getProjectId(), ClusterBlockLevel.METADATA_READ);
119123
}
120124

121125
@Override
122126
protected ClusterBlockException checkRequestBlock(ClusterState state, RecoveryRequest request, String[] concreteIndices) {
123-
return state.blocks().indicesBlockedException(ClusterBlockLevel.METADATA_READ, concreteIndices);
127+
return state.blocks().indicesBlockedException(projectResolver.getProjectId(), ClusterBlockLevel.METADATA_READ, concreteIndices);
124128
}
125129
}

server/src/main/java/org/elasticsearch/node/NodeConstruction.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1159,7 +1159,8 @@ public Map<String, String> queryFields() {
11591159
systemIndices,
11601160
indicesService,
11611161
fileSettingsService,
1162-
threadPool
1162+
threadPool,
1163+
projectResolver.supportsMultipleProjects()
11631164
);
11641165

11651166
DiscoveryModule discoveryModule = createDiscoveryModule(

server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@
134134
import org.elasticsearch.threadpool.ThreadPool;
135135
import org.elasticsearch.transport.LeakTracker;
136136
import org.elasticsearch.xcontent.NamedXContentRegistry;
137+
import org.elasticsearch.xcontent.ToXContent;
137138
import org.elasticsearch.xcontent.XContentBuilder;
138139
import org.elasticsearch.xcontent.XContentFactory;
139140
import org.elasticsearch.xcontent.XContentParser;
@@ -377,7 +378,10 @@ public static String getRepositoryDataBlobName(long repositoryGeneration) {
377378
METADATA_NAME_FORMAT,
378379
(repoName, parser) -> ProjectMetadata.Builder.fromXContent(parser),
379380
projectMetadata -> ChunkedToXContent.wrapAsToXContent(
380-
params -> Iterators.concat(Iterators.single((builder, ignored) -> builder.field("id", projectMetadata.id())))
381+
params -> Iterators.concat(
382+
Iterators.single((ToXContent) (builder, p) -> builder.field("id", projectMetadata.id())),
383+
projectMetadata.toXContentChunked(params)
384+
)
381385
)
382386
);
383387

server/src/main/java/org/elasticsearch/reservedstate/service/FileSettingsService.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.elasticsearch.cluster.NotMasterException;
2222
import org.elasticsearch.cluster.coordination.FailedToCommitClusterStateException;
2323
import org.elasticsearch.cluster.metadata.Metadata;
24+
import org.elasticsearch.cluster.metadata.ProjectId;
2425
import org.elasticsearch.cluster.metadata.ReservedStateMetadata;
2526
import org.elasticsearch.cluster.node.DiscoveryNode;
2627
import org.elasticsearch.cluster.service.ClusterService;
@@ -126,8 +127,9 @@ public Path watchedFile() {
126127
* file based settings from the cluster state.
127128
* @param clusterState the cluster state before snapshot restore
128129
* @param mdBuilder the current metadata builder for the new cluster state
130+
* @param projectId the project associated with the restore
129131
*/
130-
public void handleSnapshotRestore(ClusterState clusterState, Metadata.Builder mdBuilder) {
132+
public void handleSnapshotRestore(ClusterState clusterState, Metadata.Builder mdBuilder, ProjectId projectId) {
131133
assert clusterState.nodes().isLocalNodeElectedMaster();
132134

133135
ReservedStateMetadata fileSettingsMetadata = clusterState.metadata().reservedStateMetadata().get(NAMESPACE);

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,10 @@ private class FetchingSnapshotShardSizeRunnable extends AbstractRunnable {
211211

212212
@Override
213213
protected void doRun() throws Exception {
214-
final Repository repository = repositoriesService.repository(snapshotShard.snapshot.getRepository());
214+
final Repository repository = repositoriesService.repository(
215+
snapshotShard.snapshot().getProjectId(),
216+
snapshotShard.snapshot.getRepository()
217+
);
215218

216219
logger.debug("fetching snapshot shard size for {}", snapshotShard);
217220
final long snapshotShardSize = repository.getShardSnapshotStatus(

0 commit comments

Comments
 (0)