use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.BlockSnapshotSessionRestoreWorkflowCompleter in project coprhd-controller by CoprHD.
the class BlockDeviceController method restoreSnapshotSession.
/**
* {@inheritDoc}
*/
@Override
public void restoreSnapshotSession(URI systemURI, URI snapSessionURI, Boolean updateStatus, String opId) {
BlockSnapshotSession snapshotSession = _dbClient.queryObject(BlockSnapshotSession.class, snapSessionURI);
TaskCompleter completer = new BlockSnapshotSessionRestoreWorkflowCompleter(snapshotSession.getId(), updateStatus, opId);
try {
// Get a new workflow to restore the snapshot session.
Workflow workflow = _workflowService.getNewWorkflow(this, RESTORE_SNAPSHOT_SESSION_WF_NAME, false, opId);
_log.info("Created new workflow to restore snapshot session {} with operation id {}", snapSessionURI, opId);
String waitFor = null;
// Check if we are dealing with a single volume or a group...
BlockObject sourceObj = null;
if (snapshotSession.hasConsistencyGroup() && NullColumnValueGetter.isNotNullValue(snapshotSession.getReplicationGroupInstance())) {
// We need a single source volume for the session.
BlockConsistencyGroup cg = _dbClient.queryObject(BlockConsistencyGroup.class, snapshotSession.getConsistencyGroup());
List<Volume> nativeVolumes = BlockConsistencyGroupUtils.getActiveNativeVolumesInCG(cg, _dbClient);
// get source group name from the session.
String sourceGroupName = snapshotSession.getReplicationGroupInstance();
for (Volume volume : nativeVolumes) {
if (sourceGroupName.equals(volume.getReplicationGroupInstance())) {
sourceObj = volume;
// get source volume which matches session's RG name
break;
}
}
} else {
sourceObj = BlockObject.fetch(_dbClient, snapshotSession.getParent().getURI());
}
if (sourceObj instanceof Volume && isNonSplitSRDFTargetVolume((Volume) sourceObj)) {
// PRIOR to Restoring R2 Device from its session, we need to
// a) SUSPEND the R1-R2 pair if the Copy Mode is ACTIVE Or
// b) SPLIT the R1-R2 pair if the Copy Mode is SYNC/ ASYNC
Volume sourceVolume = (Volume) sourceObj;
URI srdfSourceVolumeURI = sourceVolume.getSrdfParent().getURI();
Volume srdfSourceVolume = _dbClient.queryObject(Volume.class, srdfSourceVolumeURI);
URI srdfSourceStorageSystemURI = srdfSourceVolume.getStorageController();
if (Mode.ACTIVE.equals(Mode.valueOf(sourceVolume.getSrdfCopyMode()))) {
waitFor = suspendSRDFLinkWorkflowStep(waitFor, srdfSourceStorageSystemURI, srdfSourceVolumeURI, sourceObj.getId(), workflow);
} else {
// split all members the group
Workflow.Method splitMethod = srdfDeviceController.splitSRDFGroupLinkMethod(srdfSourceStorageSystemURI, srdfSourceVolumeURI, sourceObj.getId(), false);
Workflow.Method splitRollbackMethod = srdfDeviceController.resumeGroupPairsMethod(srdfSourceStorageSystemURI, srdfSourceVolumeURI, sourceObj.getId());
waitFor = workflow.createStep(SRDFDeviceController.SPLIT_SRDF_MIRRORS_STEP_GROUP, SRDFDeviceController.SPLIT_SRDF_MIRRORS_STEP_DESC, waitFor, srdfSourceStorageSystemURI, getDeviceType(srdfSourceStorageSystemURI), SRDFDeviceController.class, splitMethod, splitRollbackMethod, null);
}
} else if (sourceObj instanceof Volume && isNonSplitSRDFSourceVolume((Volume) sourceObj)) {
// PRIOR to Restoring R1 Device from its session, we need to SUSPEND the R1-R2 pair if the Copy Mode is
// ACTIVE
Volume srdfSourceVolume = (Volume) sourceObj;
URI srdfSourceStorageSystemURI = srdfSourceVolume.getStorageController();
StringSet targets = srdfSourceVolume.getSrdfTargets();
if (null != targets) {
for (String target : targets) {
if (NullColumnValueGetter.isNotNullValue(target)) {
Volume srdfTargetVolume = _dbClient.queryObject(Volume.class, URI.create(target));
if (null != srdfTargetVolume && Mode.ACTIVE.equals(Mode.valueOf(srdfTargetVolume.getSrdfCopyMode()))) {
waitFor = suspendSRDFLinkWorkflowStep(waitFor, srdfSourceStorageSystemURI, srdfSourceVolume.getId(), srdfTargetVolume.getId(), workflow);
}
break;
}
}
}
}
// Create the workflow step to restore the snapshot session.
waitFor = workflow.createStep(RESTORE_SNAPSHOT_SESSION_STEP_GROUP, String.format("Restore snapshot session %s", snapSessionURI), waitFor, systemURI, getDeviceType(systemURI), getClass(), restoreBlockSnapshotSessionMethod(systemURI, snapSessionURI), rollbackMethodNullMethod(), null);
// Execute the workflow.
workflow.executePlan(completer, "Restore block snapshot session successful");
} catch (Exception e) {
_log.error("Restore block snapshot session failed", e);
ServiceCoded serviceException = DeviceControllerException.exceptions.restoreBlockSnapshotSessionFailed(e);
completer.error(_dbClient, serviceException);
}
}
use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.BlockSnapshotSessionRestoreWorkflowCompleter in project coprhd-controller by CoprHD.
the class VPlexDeviceController method restoreSnapshotSession.
/**
* {@inheritDoc}
*/
@Override
public void restoreSnapshotSession(URI vplexURI, URI snapSessionURI, String opId) throws InternalException {
BlockSnapshotSession snapSession = getDataObject(BlockSnapshotSession.class, snapSessionURI, _dbClient);
try {
// Generate the Workflow.
Workflow workflow = _workflowService.getNewWorkflow(this, RESTORE_SNAP_SESSION_WF_NAME, false, opId);
_log.info("Created restore snapshot session workflow with operation id {}", opId);
// Get the VPLEX volume(s) to be restored.
List<Volume> vplexVolumes = new ArrayList<Volume>();
if (!snapSession.hasConsistencyGroup()) {
// If the snap session is not in a CG, the only VPLEX
// volume to restore is the VPLEX volume using the
// snap session parent.
URI parentVolumeURI = snapSession.getParent().getURI();
URIQueryResultList queryResults = new URIQueryResultList();
_dbClient.queryByConstraint(AlternateIdConstraint.Factory.getVolumeByAssociatedVolumesConstraint(parentVolumeURI.toString()), queryResults);
vplexVolumes.add(_dbClient.queryObject(Volume.class, queryResults.iterator().next()));
} else {
BlockConsistencyGroup cg = _dbClient.queryObject(BlockConsistencyGroup.class, snapSession.getConsistencyGroup());
List<Volume> allVplexVolumesInCG = BlockConsistencyGroupUtils.getActiveVplexVolumesInCG(cg, _dbClient, null);
List<BlockObject> allVplexVolumesInRG = ControllerUtils.getAllVolumesForRGInCG(allVplexVolumesInCG, snapSession.getReplicationGroupInstance(), snapSession.getStorageController(), _dbClient);
// that are RP source volumes.
for (BlockObject vplexVolume : allVplexVolumesInRG) {
// RP target and sources restore is supported
vplexVolumes.add((Volume) vplexVolume);
}
}
// Determine the backend storage system containing the native snapshot session.
Volume firstVplexVolume = vplexVolumes.get(0);
Volume firstSnapSessionParentVolume = VPlexUtil.getVPLEXBackendVolume(firstVplexVolume, true, _dbClient);
StorageSystem snapSessionSystem = getDataObject(StorageSystem.class, firstSnapSessionParentVolume.getStorageController(), _dbClient);
// Maps Vplex volume that needs to be flushed to underlying array volume
Map<Volume, Volume> vplexToArrayVolumesToFlush = new HashMap<Volume, Volume>();
for (Volume vplexVolume : vplexVolumes) {
Volume arrayVolumeToBeRestored = VPlexUtil.getVPLEXBackendVolume(vplexVolume, true, _dbClient);
vplexToArrayVolumesToFlush.put(vplexVolume, arrayVolumeToBeRestored);
}
Map<URI, String> vplexVolumeIdToDetachStep = new HashMap<URI, String>();
boolean isRP = firstVplexVolume.checkForRp();
if (null == firstVplexVolume.getAssociatedVolumes() || firstVplexVolume.getAssociatedVolumes().isEmpty()) {
_log.error("VPLEX volume {} has no backend volumes.", firstVplexVolume.forDisplay());
throw InternalServerErrorException.internalServerErrors.noAssociatedVolumesForVPLEXVolume(firstVplexVolume.forDisplay());
}
boolean isDistributed = firstVplexVolume.getAssociatedVolumes().size() > 1;
String waitFor = null;
if (isRP && isDistributed) {
ProtectionSystem rpSystem = getDataObject(ProtectionSystem.class, firstVplexVolume.getProtectionController(), _dbClient);
// Create the pre restore step which will be the first step executed
// in the workflow.
createWorkflowStepForDeleteReplicationSet(workflow, rpSystem, vplexVolumes, null);
}
// Generate pre restore steps
waitFor = addPreRestoreResyncSteps(workflow, vplexToArrayVolumesToFlush, vplexVolumeIdToDetachStep, waitFor);
// Now create a workflow step to natively restore the backend
// volume. We execute this after the invalidate cache.
createWorkflowStepForRestoreNativeSnapshotSession(workflow, snapSessionSystem, snapSessionURI, waitFor, rollbackMethodNullMethod());
// Generate post restore steps
waitFor = addPostRestoreResyncSteps(workflow, vplexToArrayVolumesToFlush, vplexVolumeIdToDetachStep, waitFor);
if (isRP && isDistributed) {
ProtectionSystem rpSystem = getDataObject(ProtectionSystem.class, firstVplexVolume.getProtectionController(), _dbClient);
// Create the post restore step, which will be the last step executed
// in the workflow after the volume shave been rebuilt.
waitFor = createWorkflowStepForRecreateReplicationSet(workflow, rpSystem, vplexVolumes, waitFor);
}
// Execute the workflow.
_log.info("Executing workflow plan");
TaskCompleter completer = new BlockSnapshotSessionRestoreWorkflowCompleter(snapSessionURI, Boolean.TRUE, opId);
String successMsg = String.format("Restore VPLEX volume(s) from snapshot session %s" + "completed successfully", snapSessionURI);
workflow.executePlan(completer, successMsg);
_log.info("Workflow plan executing");
} catch (Exception e) {
String failMsg = String.format("Restore VPLEX volume from snapshot session %s failed", snapSessionURI);
_log.error(failMsg, e);
TaskCompleter completer = new BlockSnapshotSessionRestoreWorkflowCompleter(snapSessionURI, Boolean.TRUE, opId);
ServiceError serviceError = VPlexApiException.errors.restoreVolumeFailed(snapSessionURI.toString(), e);
failStep(completer, opId, serviceError);
}
}
Aggregations