|
@@ -16,10 +16,13 @@ import org.elasticsearch.cluster.ClusterStateListener;
|
|
|
import org.elasticsearch.cluster.RestoreInProgress;
|
|
|
import org.elasticsearch.cluster.service.ClusterService;
|
|
|
import org.elasticsearch.common.collect.ImmutableOpenMap;
|
|
|
+import org.elasticsearch.common.util.concurrent.ThreadContext;
|
|
|
import org.elasticsearch.index.shard.ShardId;
|
|
|
import org.elasticsearch.snapshots.RestoreInfo;
|
|
|
import org.elasticsearch.snapshots.RestoreService;
|
|
|
|
|
|
+import java.util.function.Supplier;
|
|
|
+
|
|
|
import static org.elasticsearch.snapshots.RestoreService.restoreInProgress;
|
|
|
|
|
|
public class RestoreClusterStateListener implements ClusterStateListener {
|
|
@@ -29,43 +32,48 @@ public class RestoreClusterStateListener implements ClusterStateListener {
|
|
|
private final ClusterService clusterService;
|
|
|
private final String uuid;
|
|
|
private final ActionListener<RestoreSnapshotResponse> listener;
|
|
|
+ private final Supplier<ThreadContext.StoredContext> contextSupplier;
|
|
|
|
|
|
private RestoreClusterStateListener(
|
|
|
ClusterService clusterService,
|
|
|
RestoreService.RestoreCompletionResponse response,
|
|
|
- ActionListener<RestoreSnapshotResponse> listener
|
|
|
+ ActionListener<RestoreSnapshotResponse> listener,
|
|
|
+ Supplier<ThreadContext.StoredContext> contextSupplier
|
|
|
) {
|
|
|
this.clusterService = clusterService;
|
|
|
this.uuid = response.getUuid();
|
|
|
this.listener = listener;
|
|
|
+ this.contextSupplier = contextSupplier;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public void clusterChanged(ClusterChangedEvent changedEvent) {
|
|
|
- final RestoreInProgress.Entry prevEntry = restoreInProgress(changedEvent.previousState(), uuid);
|
|
|
- final RestoreInProgress.Entry newEntry = restoreInProgress(changedEvent.state(), uuid);
|
|
|
- if (prevEntry == null) {
|
|
|
- // When there is a master failure after a restore has been started, this listener might not be registered
|
|
|
- // on the current master and as such it might miss some intermediary cluster states due to batching.
|
|
|
- // Clean up listener in that case and acknowledge completion of restore operation to client.
|
|
|
- clusterService.removeListener(this);
|
|
|
- listener.onResponse(new RestoreSnapshotResponse((RestoreInfo) null));
|
|
|
- } else if (newEntry == null) {
|
|
|
- clusterService.removeListener(this);
|
|
|
- ImmutableOpenMap<ShardId, RestoreInProgress.ShardRestoreStatus> shards = prevEntry.shards();
|
|
|
- assert prevEntry.state().completed() : "expected completed snapshot state but was " + prevEntry.state();
|
|
|
- assert RestoreService.completed(shards) : "expected all restore entries to be completed";
|
|
|
- RestoreInfo ri = new RestoreInfo(
|
|
|
- prevEntry.snapshot().getSnapshotId().getName(),
|
|
|
- prevEntry.indices(),
|
|
|
- shards.size(),
|
|
|
- shards.size() - RestoreService.failedShards(shards)
|
|
|
- );
|
|
|
- RestoreSnapshotResponse response = new RestoreSnapshotResponse(ri);
|
|
|
- logger.debug("restore of [{}] completed", prevEntry.snapshot().getSnapshotId());
|
|
|
- listener.onResponse(response);
|
|
|
- } else {
|
|
|
- // restore not completed yet, wait for next cluster state update
|
|
|
+ try (ThreadContext.StoredContext stored = contextSupplier.get()) {
|
|
|
+ final RestoreInProgress.Entry prevEntry = restoreInProgress(changedEvent.previousState(), uuid);
|
|
|
+ final RestoreInProgress.Entry newEntry = restoreInProgress(changedEvent.state(), uuid);
|
|
|
+ if (prevEntry == null) {
|
|
|
+ // When there is a master failure after a restore has been started, this listener might not be registered
|
|
|
+ // on the current master and as such it might miss some intermediary cluster states due to batching.
|
|
|
+ // Clean up listener in that case and acknowledge completion of restore operation to client.
|
|
|
+ clusterService.removeListener(this);
|
|
|
+ listener.onResponse(new RestoreSnapshotResponse((RestoreInfo) null));
|
|
|
+ } else if (newEntry == null) {
|
|
|
+ clusterService.removeListener(this);
|
|
|
+ ImmutableOpenMap<ShardId, RestoreInProgress.ShardRestoreStatus> shards = prevEntry.shards();
|
|
|
+ assert prevEntry.state().completed() : "expected completed snapshot state but was " + prevEntry.state();
|
|
|
+ assert RestoreService.completed(shards) : "expected all restore entries to be completed";
|
|
|
+ RestoreInfo ri = new RestoreInfo(
|
|
|
+ prevEntry.snapshot().getSnapshotId().getName(),
|
|
|
+ prevEntry.indices(),
|
|
|
+ shards.size(),
|
|
|
+ shards.size() - RestoreService.failedShards(shards)
|
|
|
+ );
|
|
|
+ RestoreSnapshotResponse response = new RestoreSnapshotResponse(ri);
|
|
|
+ logger.debug("restore of [{}] completed", prevEntry.snapshot().getSnapshotId());
|
|
|
+ listener.onResponse(response);
|
|
|
+ } else {
|
|
|
+ // restore not completed yet, wait for next cluster state update
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -76,8 +84,11 @@ public class RestoreClusterStateListener implements ClusterStateListener {
|
|
|
public static void createAndRegisterListener(
|
|
|
ClusterService clusterService,
|
|
|
RestoreService.RestoreCompletionResponse response,
|
|
|
- ActionListener<RestoreSnapshotResponse> listener
|
|
|
+ ActionListener<RestoreSnapshotResponse> listener,
|
|
|
+ ThreadContext threadContext
|
|
|
) {
|
|
|
- clusterService.addListener(new RestoreClusterStateListener(clusterService, response, listener));
|
|
|
+ clusterService.addListener(
|
|
|
+ new RestoreClusterStateListener(clusterService, response, listener, threadContext.newRestorableContext(true))
|
|
|
+ );
|
|
|
}
|
|
|
}
|