use of org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.ClusterSnapshotFuture in project ignite by apache.
the class SnapshotRestoreProcess method prepare.
/**
* @param req Request to prepare cache group restore from the snapshot.
* @return Result future.
*/
private IgniteInternalFuture<SnapshotRestoreOperationResponse> prepare(SnapshotOperationRequest req) {
if (ctx.clientNode())
return new GridFinishedFuture<>();
try {
DiscoveryDataClusterState state = ctx.state().clusterState();
IgniteSnapshotManager snpMgr = ctx.cache().context().snapshotMgr();
if (state.state() != ClusterState.ACTIVE || state.transition())
throw new IgniteCheckedException(OP_REJECT_MSG + "The cluster should be active.");
if (snpMgr.isSnapshotCreating())
throw new IgniteCheckedException(OP_REJECT_MSG + "A cluster snapshot operation is in progress.");
if (ctx.encryption().isMasterKeyChangeInProgress()) {
return new GridFinishedFuture<>(new IgniteCheckedException(OP_REJECT_MSG + "Master key changing " + "process is not finished yet."));
}
if (ctx.encryption().reencryptionInProgress()) {
return new GridFinishedFuture<>(new IgniteCheckedException(OP_REJECT_MSG + "Caches re-encryption " + "process is not finished yet."));
}
for (UUID nodeId : req.nodes()) {
ClusterNode node = ctx.discovery().node(nodeId);
if (node == null || !CU.baselineNode(node, state) || !ctx.discovery().alive(node)) {
throw new IgniteCheckedException(OP_REJECT_MSG + "Required node has left the cluster [nodeId-" + nodeId + ']');
}
}
if (log.isInfoEnabled()) {
log.info("Starting local snapshot prepare restore operation" + " [reqId=" + req.requestId() + ", snapshot=" + req.snapshotName() + ", caches=" + req.groups() + ']');
}
List<SnapshotMetadata> locMetas = snpMgr.readSnapshotMetadatas(req.snapshotName());
SnapshotRestoreContext opCtx0 = prepareContext(req, locMetas);
synchronized (this) {
lastOpCtx = opCtx = opCtx0;
ClusterSnapshotFuture fut0 = fut;
if (fut0 != null)
opCtx0.errHnd.accept(fut0.interruptEx);
}
// Ensure that shared cache groups has no conflicts.
for (StoredCacheData cfg : opCtx0.cfgs.values()) {
ensureCacheAbsent(cfg.config().getName());
if (!F.isEmpty(cfg.config().getGroupName()))
ensureCacheAbsent(cfg.config().getGroupName());
}
if (ctx.isStopping())
throw new NodeStoppingException("The node is stopping: " + ctx.localNodeId());
return new GridFinishedFuture<>(new SnapshotRestoreOperationResponse(opCtx0.cfgs.values(), locMetas));
} catch (IgniteIllegalStateException | IgniteCheckedException | RejectedExecutionException e) {
log.error("Unable to restore cache group(s) from the snapshot " + "[reqId=" + req.requestId() + ", snapshot=" + req.snapshotName() + ']', e);
return new GridFinishedFuture<>(e);
}
}
use of org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.ClusterSnapshotFuture in project ignite by apache.
the class SnapshotRestoreProcess method cancel.
/**
* Cancel the currently running local restore procedure.
*
* @param reason Interruption reason.
* @param snpName Snapshot name.
* @return Future that will be finished when process the process is complete. The result of this future will be
* {@code false} if the restore process with the specified snapshot name is not running at all.
*/
public IgniteFuture<Boolean> cancel(IgniteCheckedException reason, String snpName) {
SnapshotRestoreContext opCtx0;
ClusterSnapshotFuture fut0 = null;
synchronized (this) {
opCtx0 = opCtx;
if (fut != null && fut.name.equals(snpName)) {
fut0 = fut;
fut0.interruptEx = reason;
}
}
boolean ctxStop = opCtx0 != null && opCtx0.snpName.equals(snpName);
if (ctxStop)
interrupt(opCtx0, reason);
return fut0 == null ? new IgniteFinishedFutureImpl<>(ctxStop) : new IgniteFutureImpl<>(fut0.chain(f -> true));
}
use of org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.ClusterSnapshotFuture in project ignite by apache.
the class SnapshotRestoreProcess method finishProcess.
/**
* Finish local cache group restore process.
*
* @param reqId Request ID.
* @param err Error, if any.
*/
private void finishProcess(UUID reqId, @Nullable Throwable err) {
if (err != null)
log.error(OP_FAILED_MSG + " [reqId=" + reqId + "].", err);
else if (log.isInfoEnabled())
log.info(OP_FINISHED_MSG + " [reqId=" + reqId + "].");
SnapshotRestoreContext opCtx0 = opCtx;
if (opCtx0 != null && reqId.equals(opCtx0.reqId)) {
opCtx = null;
opCtx0.endTime = U.currentTimeMillis();
}
synchronized (this) {
ClusterSnapshotFuture fut0 = fut;
if (fut0 != null && reqId.equals(fut0.rqId)) {
fut = null;
ctx.pools().getSystemExecutorService().submit(() -> fut0.onDone(null, err));
}
}
}
use of org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.ClusterSnapshotFuture in project ignite by apache.
the class SnapshotRestoreProcess method restoringSnapshotName.
/**
* Get the name of the snapshot currently being restored
*
* @return Name of the snapshot currently being restored or {@code null} if the restore process is not running.
*/
@Nullable
public String restoringSnapshotName() {
SnapshotRestoreContext opCtx0 = opCtx;
if (opCtx0 != null)
return opCtx0.snpName;
ClusterSnapshotFuture fut0 = fut;
return fut0 != null ? fut0.name : null;
}
use of org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.ClusterSnapshotFuture in project ignite by apache.
the class SnapshotRestoreProcess method start.
/**
* Start cache group restore operation.
*
* @param snpName Snapshot name.
* @param cacheGrpNames Cache groups to be restored or {@code null} to restore all cache groups from the snapshot.
* @return Future that will be completed when the restore operation is complete and the cache groups are started.
*/
public IgniteFuture<Void> start(String snpName, @Nullable Collection<String> cacheGrpNames) {
IgniteSnapshotManager snpMgr = ctx.cache().context().snapshotMgr();
ClusterSnapshotFuture fut0;
try {
if (ctx.clientNode())
throw new IgniteException(OP_REJECT_MSG + "Client and daemon nodes can not perform this operation.");
DiscoveryDataClusterState clusterState = ctx.state().clusterState();
if (clusterState.state() != ClusterState.ACTIVE || clusterState.transition())
throw new IgniteException(OP_REJECT_MSG + "The cluster should be active.");
if (!clusterState.hasBaselineTopology())
throw new IgniteException(OP_REJECT_MSG + "The baseline topology is not configured for cluster.");
if (!IgniteFeatures.allNodesSupports(ctx.grid().cluster().nodes(), SNAPSHOT_RESTORE_CACHE_GROUP))
throw new IgniteException(OP_REJECT_MSG + "Not all nodes in the cluster support restore operation.");
if (snpMgr.isSnapshotCreating())
throw new IgniteException(OP_REJECT_MSG + "A cluster snapshot operation is in progress.");
synchronized (this) {
if (restoringSnapshotName() != null)
throw new IgniteException(OP_REJECT_MSG + "The previous snapshot restore operation was not completed.");
fut = new ClusterSnapshotFuture(UUID.randomUUID(), snpName);
fut0 = fut;
}
} catch (IgniteException e) {
snpMgr.recordSnapshotEvent(snpName, OP_FAILED_MSG + ": " + e.getMessage(), EventType.EVT_CLUSTER_SNAPSHOT_RESTORE_FAILED);
return new IgniteFinishedFutureImpl<>(e);
}
fut0.listen(f -> {
if (f.error() != null) {
snpMgr.recordSnapshotEvent(snpName, OP_FAILED_MSG + ": " + f.error().getMessage() + " [reqId=" + fut0.rqId + "].", EventType.EVT_CLUSTER_SNAPSHOT_RESTORE_FAILED);
} else {
snpMgr.recordSnapshotEvent(snpName, OP_FINISHED_MSG + " [reqId=" + fut0.rqId + "].", EventType.EVT_CLUSTER_SNAPSHOT_RESTORE_FINISHED);
}
});
String msg = "Cluster-wide snapshot restore operation started [reqId=" + fut0.rqId + ", snpName=" + snpName + (cacheGrpNames == null ? "" : ", caches=" + cacheGrpNames) + ']';
if (log.isInfoEnabled())
log.info(msg);
snpMgr.recordSnapshotEvent(snpName, msg, EventType.EVT_CLUSTER_SNAPSHOT_RESTORE_STARTED);
snpMgr.checkSnapshot(snpName, cacheGrpNames, true).listen(f -> {
if (f.error() != null) {
finishProcess(fut0.rqId, f.error());
return;
}
if (!F.isEmpty(f.result().exceptions())) {
finishProcess(fut0.rqId, F.first(f.result().exceptions().values()));
return;
}
if (fut0.interruptEx != null) {
finishProcess(fut0.rqId, fut0.interruptEx);
return;
}
Set<UUID> dataNodes = new HashSet<>();
Set<String> snpBltNodes = null;
Map<ClusterNode, List<SnapshotMetadata>> metas = f.result().metas();
Map<Integer, String> reqGrpIds = cacheGrpNames == null ? Collections.emptyMap() : cacheGrpNames.stream().collect(Collectors.toMap(CU::cacheId, v -> v));
for (Map.Entry<ClusterNode, List<SnapshotMetadata>> entry : metas.entrySet()) {
dataNodes.add(entry.getKey().id());
for (SnapshotMetadata meta : entry.getValue()) {
assert meta != null : entry.getKey().id();
if (snpBltNodes == null)
snpBltNodes = new HashSet<>(meta.baselineNodes());
reqGrpIds.keySet().removeAll(meta.partitions().keySet());
}
}
if (snpBltNodes == null) {
finishProcess(fut0.rqId, new IllegalArgumentException(OP_REJECT_MSG + "No snapshot data " + "has been found [groups=" + reqGrpIds.values() + ", snapshot=" + snpName + ']'));
return;
}
if (!reqGrpIds.isEmpty()) {
finishProcess(fut0.rqId, new IllegalArgumentException(OP_REJECT_MSG + "Cache group(s) was not " + "found in the snapshot [groups=" + reqGrpIds.values() + ", snapshot=" + snpName + ']'));
return;
}
Collection<UUID> bltNodes = F.viewReadOnly(ctx.discovery().discoCache().aliveBaselineNodes(), F.node2id());
SnapshotOperationRequest req = new SnapshotOperationRequest(fut0.rqId, F.first(dataNodes), snpName, cacheGrpNames, new HashSet<>(bltNodes));
prepareRestoreProc.start(req.requestId(), req);
});
return new IgniteFutureImpl<>(fut0);
}
Aggregations