Search in sources :

Example 1 with BlockSnapshotRestoreCompleter

use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.BlockSnapshotRestoreCompleter in project coprhd-controller by CoprHD.

the class BlockDeviceController method restoreVolumeStep.

public boolean restoreVolumeStep(URI storage, URI pool, URI volume, URI snapshot, Boolean updateOpStatus, String opId) throws ControllerException {
    TaskCompleter completer = null;
    try {
        StorageSystem storageDevice = _dbClient.queryObject(StorageSystem.class, storage);
        BlockSnapshot snapObj = _dbClient.queryObject(BlockSnapshot.class, snapshot);
        completer = new BlockSnapshotRestoreCompleter(snapObj, opId, updateOpStatus);
        getDevice(storageDevice.getSystemType()).doRestoreFromSnapshot(storageDevice, volume, snapshot, completer);
    } catch (Exception e) {
        _log.error(String.format("restoreVolume failed - storage: %s, pool: %s, volume: %s, snapshot: %s", storage.toString(), pool.toString(), volume.toString(), snapshot.toString()));
        ServiceError serviceError = DeviceControllerException.errors.jobFailed(e);
        completer.error(_dbClient, serviceError);
        doFailTask(BlockSnapshot.class, snapshot, opId, serviceError);
        WorkflowStepCompleter.stepFailed(opId, serviceError);
        return false;
    }
    return true;
}
Also used : BlockSnapshotRestoreCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.BlockSnapshotRestoreCompleter) ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) ScanTaskCompleter(com.emc.storageos.volumecontroller.impl.plugins.discovery.smis.ScanTaskCompleter) BlockSnapshotEstablishGroupTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.BlockSnapshotEstablishGroupTaskCompleter) BlockMirrorTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.BlockMirrorTaskCompleter) CloneTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.CloneTaskCompleter) ApplicationTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ApplicationTaskCompleter) SimpleTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.SimpleTaskCompleter) VolumeTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.VolumeTaskCompleter) DiscoverTaskCompleter(com.emc.storageos.volumecontroller.impl.plugins.discovery.smis.DiscoverTaskCompleter) TaskCompleter(com.emc.storageos.volumecontroller.TaskCompleter) MultiVolumeTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.MultiVolumeTaskCompleter) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) BaseCollectionException(com.emc.storageos.plugins.BaseCollectionException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) WorkflowException(com.emc.storageos.workflow.WorkflowException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) DataBindingException(javax.xml.bind.DataBindingException) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 2 with BlockSnapshotRestoreCompleter

use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.BlockSnapshotRestoreCompleter in project coprhd-controller by CoprHD.

the class VPlexDeviceController method restoreVolume.

/**
 * {@inheritDoc}
 */
@Override
public void restoreVolume(URI vplexURI, URI snapshotURI, String opId) throws InternalException {
    BlockSnapshot snapshot = getDataObject(BlockSnapshot.class, snapshotURI, _dbClient);
    try {
        // Generate the Workflow.
        Workflow workflow = _workflowService.getNewWorkflow(this, RESTORE_VOLUME_WF_NAME, false, opId);
        _log.info("Created restore volume workflow with operation id {}", opId);
        // Get some info from the snapshot we need to do the native
        // restore of the backend volume. Note that if the snapshot
        // is associated with a CG, then all backend volumes in the
        // CG will be restored using their corresponding snapshots,
        // meaning the VPLEX volumes using those backend volumes
        // will be restored.
        URI parentSystemURI = snapshot.getStorageController();
        StorageSystem parentSystem = getDataObject(StorageSystem.class, parentSystemURI, _dbClient);
        URI parentVolumeURI = snapshot.getParent().getURI();
        Volume parentVolume = getDataObject(Volume.class, parentVolumeURI, _dbClient);
        URI parentPoolURI = parentVolume.getPool();
        // Get the VPLEX system.
        StorageSystem vplexSystem = getDataObject(StorageSystem.class, vplexURI, _dbClient);
        // Get the VPLEX volume(s) to be restored.
        List<URI> vplexVolumeURIs = new ArrayList<URI>();
        URI cgURI = snapshot.getConsistencyGroup();
        if (NullColumnValueGetter.isNullURI(cgURI)) {
            // If the snapshot is not in a CG, the only VPLEX
            // volume to restore is the VPLEX volume using the
            // snapshot parent.
            URIQueryResultList queryResults = new URIQueryResultList();
            _dbClient.queryByConstraint(AlternateIdConstraint.Factory.getVolumeByAssociatedVolumesConstraint(parentVolumeURI.toString()), queryResults);
            URI vplexVolumeURI = queryResults.iterator().next();
            vplexVolumeURIs.add(vplexVolumeURI);
        } else {
            // Otherwise, get all snapshots in the snapset, get the
            // parent volume for each snapshot, and get the VLPEX
            // volume using the snapshot parent.
            List<BlockSnapshot> cgSnaps = ControllerUtils.getSnapshotsPartOfReplicationGroup(snapshot, _dbClient);
            for (BlockSnapshot cgSnapshot : cgSnaps) {
                URIQueryResultList queryResults = new URIQueryResultList();
                _dbClient.queryByConstraint(AlternateIdConstraint.Factory.getVolumeByAssociatedVolumesConstraint(cgSnapshot.getParent().getURI().toString()), queryResults);
                URI vplexVolumeURI = queryResults.iterator().next();
                vplexVolumeURIs.add(vplexVolumeURI);
            }
        }
        // The workflow depends on if the VPLEX volumes are local
        // or distributed.
        String waitFor = null;
        Volume firstVplexVolume = getDataObject(Volume.class, vplexVolumeURIs.get(0), _dbClient);
        if (null == firstVplexVolume.getAssociatedVolumes() || firstVplexVolume.getAssociatedVolumes().isEmpty()) {
            _log.error("VPLEX volume {} has no backend volumes.", firstVplexVolume.forDisplay());
            throw InternalServerErrorException.internalServerErrors.noAssociatedVolumesForVPLEXVolume(firstVplexVolume.forDisplay());
        }
        boolean isLocal = firstVplexVolume.getAssociatedVolumes().size() == 1;
        if (isLocal) {
            // VPLEX volume.
            for (URI vplexVolumeURI : vplexVolumeURIs) {
                waitFor = createWorkflowStepForInvalidateCache(workflow, vplexSystem, vplexVolumeURI, null, null);
            }
            // Now create a workflow step to natively restore the backend
            // volume from the passed snapshot. Note that if the snapshot
            // is associated with a CG, then block controller will restore
            // all backend volumes in the CG using their corresponding
            // snapshots. We execute this after the invalidate cache. We
            // could execute these in parallel for a little better efficiency,
            // but what if the invalidate cache fails, but the restore succeeds,
            // the cache now has invalid data and a cache read hit could return
            // invalid data.
            createWorkflowStepForRestoreNativeSnapshot(workflow, parentSystem, parentVolumeURI, snapshotURI, parentPoolURI, waitFor, null);
        } else {
            for (URI vplexVolumeURI : vplexVolumeURIs) {
                // For distributed volumes we take snapshots of and restore the
                // source backend volume. Before we can do the restore, we need
                // to detach the mirror of the distributed volume. So, create a
                // workflow step to detach it from the source.
                Volume vplexVolume = getDataObject(Volume.class, vplexVolumeURI, _dbClient);
                String detachStepId = workflow.createStepId();
                Workflow.Method restoreVolumeRollbackMethod = createRestoreResyncRollbackMethod(vplexURI, vplexVolumeURI, vplexVolume.getConsistencyGroup(), detachStepId);
                waitFor = createWorkflowStepForDetachMirror(workflow, vplexSystem, vplexVolume, detachStepId, null, restoreVolumeRollbackMethod);
                // We now create a step to invalidate the cache for the
                // VPLEX volume. Note that if this step fails we need to
                // rollback and reattach the mirror.
                createWorkflowStepForInvalidateCache(workflow, vplexSystem, vplexVolumeURI, waitFor, rollbackMethodNullMethod());
                // Now create a workflow step to reattach the mirror to initiate
                // a rebuild of the mirror for the distributed volume. Note that
                // these steps will not run until after the native restore, which
                // only gets executed once, not for every VPLEX volume.
                createWorkflowStepForAttachMirror(workflow, vplexSystem, vplexVolume, detachStepId, RESTORE_VOLUME_STEP, rollbackMethodNullMethod());
            }
            // Create a workflow step to native restore the backend volume
            // from the passed snapshot. This step is executed after the
            // cache has been invalidated for each VPLEX volume. Note that
            // if the snapshot is associated with a CG, then block controller
            // will restore all backend volumes in the CG using their
            // corresponding snapshots. We could execute this in parallel
            // with the restore for a little better efficiency, but what if
            // the invalidate cache fails, but the restore succeeds, the
            // cache now has invalid data and a cache read hit could return
            // invalid data. If this step fails, then again, we need to
            // be sure and rollback and reattach the mirror. There is
            // nothing to rollback for the cache invalidate step. It just
            // means there will be no read cache hits on the volume for a
            // while until the cache is repopulated.
            createWorkflowStepForRestoreNativeSnapshot(workflow, parentSystem, parentVolumeURI, snapshotURI, parentPoolURI, INVALIDATE_CACHE_STEP, rollbackMethodNullMethod());
        }
        // Execute the workflow.
        _log.info("Executing workflow plan");
        TaskCompleter completer = new BlockSnapshotRestoreCompleter(snapshot, opId);
        String successMsg = String.format("Restore VPLEX volume from snapshot %s of backend volume %s " + "completed successfully", snapshotURI, parentVolumeURI);
        workflow.executePlan(completer, successMsg);
        _log.info("Workflow plan executing");
    } catch (Exception e) {
        String failMsg = String.format("Restore VPLEX volume from snapshot %s failed", snapshotURI);
        _log.error(failMsg, e);
        TaskCompleter completer = new BlockSnapshotRestoreCompleter(snapshot, opId);
        ServiceError serviceError = VPlexApiException.errors.restoreVolumeFailed(snapshotURI.toString(), e);
        failStep(completer, opId, serviceError);
    }
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) ArrayList(java.util.ArrayList) Workflow(com.emc.storageos.workflow.Workflow) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) VPlexApiException(com.emc.storageos.vplex.api.VPlexApiException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) IOException(java.io.IOException) URISyntaxException(java.net.URISyntaxException) InternalServerErrorException(com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException) WorkflowException(com.emc.storageos.workflow.WorkflowException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) BlockSnapshotRestoreCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.BlockSnapshotRestoreCompleter) Volume(com.emc.storageos.db.client.model.Volume) MigrationTaskCompleter(com.emc.storageos.vplexcontroller.completers.MigrationTaskCompleter) VolumeGroupUpdateTaskCompleter(com.emc.storageos.vplexcontroller.completers.VolumeGroupUpdateTaskCompleter) ExportTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportTaskCompleter) CloneTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.CloneTaskCompleter) MigrationOperationTaskCompleter(com.emc.storageos.vplexcontroller.completers.MigrationOperationTaskCompleter) CacheStatusTaskCompleter(com.emc.storageos.vplexcontroller.completers.CacheStatusTaskCompleter) VplexMirrorTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.VplexMirrorTaskCompleter) VolumeTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.VolumeTaskCompleter) TaskCompleter(com.emc.storageos.volumecontroller.TaskCompleter) WorkflowTaskCompleter(com.emc.storageos.workflow.WorkflowTaskCompleter) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 3 with BlockSnapshotRestoreCompleter

use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.BlockSnapshotRestoreCompleter in project coprhd-controller by CoprHD.

the class BlockOrchestrationDeviceController method restoreVolume.

/*
     * (non-Javadoc)
     * 
     * @see com.emc.storageos.blockorchestrationcontroller.BlockOrchestrationController#restoreVolume(java.net.URI,
     * java.net.URI,
     * java.net.URI, java.net.URI, java.lang.String)
     */
@Override
public void restoreVolume(URI storage, URI pool, URI volume, URI snapshot, String syncDirection, String taskId) throws ControllerException {
    List<URI> volUris = Arrays.asList(volume);
    BlockSnapshotRestoreCompleter completer = new BlockSnapshotRestoreCompleter(snapshot, taskId);
    try {
        // Validate the volume identities before proceeding
        validator.volumeURIs(volUris, true, true, ValCk.ID, ValCk.VPLEX);
        // Generate the Workflow.
        Workflow workflow = _workflowService.getNewWorkflow(this, RESTORE_VOLUME_FROM_SNAPSHOT_WF_NAME, true, taskId);
        // the wait for key returned by previous call
        String waitFor = null;
        // First, call the RP controller to add RP steps for volume restore from snapshot
        waitFor = _rpDeviceController.addPreRestoreVolumeSteps(workflow, storage, volume, snapshot, taskId);
        // Call the VplexDeviceController to add its steps for restore volume from snapshot
        waitFor = _vplexDeviceController.addStepsForRestoreVolume(workflow, waitFor, storage, pool, volume, snapshot, null, syncDirection, taskId, completer);
        // Call the BlockDeviceController to add its steps for restore volume from snapshot
        waitFor = _blockDeviceController.addStepsForRestoreVolume(workflow, waitFor, storage, pool, volume, snapshot, Boolean.TRUE, syncDirection, taskId, completer);
        // Call the RPDeviceController to add its steps for post restore volume from snapshot
        waitFor = _rpDeviceController.addStepsForRestoreVolume(workflow, waitFor, storage, pool, volume, snapshot, null, syncDirection, taskId, completer);
        // Call the RP controller to add RP post restore steps
        waitFor = _rpDeviceController.addPostRestoreVolumeSteps(workflow, waitFor, storage, volume, snapshot, taskId);
        // Finish up and execute the plan.
        // The Workflow will handle the TaskCompleter
        String successMessage = String.format("Restore of volume %s from %s completed successfully", volume, snapshot);
        Object[] callbackArgs = new Object[] { new ArrayList<URI>(volUris) };
        workflow.executePlan(completer, successMessage, new WorkflowCallback(), callbackArgs, null, null);
    } catch (Exception ex) {
        s_logger.error("Could not restore volume: " + volUris.toString(), ex);
        String opName = ResourceOperationTypeEnum.RESTORE_VOLUME_SNAPSHOT.getName();
        ServiceError serviceError = DeviceControllerException.errors.restoreVolumeFromSnapshotFailed(volUris.toString(), snapshot.toString(), opName, ex);
        completer.error(s_dbClient, _locker, serviceError);
    }
}
Also used : BlockSnapshotRestoreCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.BlockSnapshotRestoreCompleter) ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) ArrayList(java.util.ArrayList) Workflow(com.emc.storageos.workflow.Workflow) BlockObject(com.emc.storageos.db.client.model.BlockObject) URI(java.net.URI) WorkflowException(com.emc.storageos.workflow.WorkflowException) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) LockRetryException(com.emc.storageos.locking.LockRetryException)

Example 4 with BlockSnapshotRestoreCompleter

use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.BlockSnapshotRestoreCompleter in project coprhd-controller by CoprHD.

the class BlockStorageDeviceTest method testRestoreFromSnapshot.

@Test
public void testRestoreFromSnapshot() {
    List<BlockSnapshot> snapshots = getSnapshots(_storageSystem);
    BlockSnapshot snapshot = snapshots.get(0);
    URI volume = getVolumes(_storageSystem).get(0).getId();
    String token = UUID.randomUUID().toString() + UUID.randomUUID().toString();
    TaskCompleter taskCompleter = new BlockSnapshotRestoreCompleter(snapshot, token);
    _deviceController.doRestoreFromSnapshot(_storageSystem, volume, snapshot.getId(), taskCompleter);
}
Also used : BlockSnapshotRestoreCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.BlockSnapshotRestoreCompleter) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) ExportTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportTaskCompleter) VolumeTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.VolumeTaskCompleter) MultiVolumeTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.MultiVolumeTaskCompleter) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) Test(org.junit.Test)

Aggregations

BlockSnapshotRestoreCompleter (com.emc.storageos.volumecontroller.impl.block.taskcompleter.BlockSnapshotRestoreCompleter)4 BlockSnapshot (com.emc.storageos.db.client.model.BlockSnapshot)3 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)3 ServiceError (com.emc.storageos.svcs.errorhandling.model.ServiceError)3 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)3 ControllerException (com.emc.storageos.volumecontroller.ControllerException)3 VolumeTaskCompleter (com.emc.storageos.volumecontroller.impl.block.taskcompleter.VolumeTaskCompleter)3 WorkflowException (com.emc.storageos.workflow.WorkflowException)3 URI (java.net.URI)3 NamedURI (com.emc.storageos.db.client.model.NamedURI)2 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)2 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)2 TaskCompleter (com.emc.storageos.volumecontroller.TaskCompleter)2 CloneTaskCompleter (com.emc.storageos.volumecontroller.impl.block.taskcompleter.CloneTaskCompleter)2 ExportTaskCompleter (com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportTaskCompleter)2 MultiVolumeTaskCompleter (com.emc.storageos.volumecontroller.impl.block.taskcompleter.MultiVolumeTaskCompleter)2 Workflow (com.emc.storageos.workflow.Workflow)2 ArrayList (java.util.ArrayList)2 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)1 BlockObject (com.emc.storageos.db.client.model.BlockObject)1