Search in sources :

Example 21 with RecoverPointVolumeProtectionInfo

use of com.emc.storageos.recoverpoint.responses.RecoverPointVolumeProtectionInfo in project coprhd-controller by CoprHD.

the class RPDeviceController method cgDeleteStep.

/**
 * The step that deletes the CG from the RecoverPoint appliance if all of the volumeIDs are in the request,
 * otherwise delete replication sets and associated journals.
 *
 * @param rpSystem
 *            protection system
 * @param volumeIDs
 *            volume IDs
 * @param journalVolumeIDs
 *            Volume IDs of journals
 * @param token
 *            task ID
 * @return true if successful
 * @throws ControllerException
 */
public boolean cgDeleteStep(URI rpSystem, List<URI> volumeIDs, List<URI> journalVolumeIDs, String token) throws ControllerException {
    WorkflowStepCompleter.stepExecuting(token);
    _log.info("cgDeleteStep is running");
    boolean lockException = false;
    try {
        // Validate input arguments
        if (rpSystem == null) {
            _log.error("Protection system not sent into cgDeleteStep");
            throw DeviceControllerExceptions.recoverpoint.cgDeleteStepInvalidParam("protection system URI");
        }
        ProtectionSystem system = _dbClient.queryObject(ProtectionSystem.class, rpSystem);
        if (system == null) {
            _log.error("Protection system not in database");
            throw DeviceControllerExceptions.recoverpoint.cgDeleteStepInvalidParam("protection system null");
        }
        if (system.getInactive()) {
            _log.error("Protection system set to be deleted");
            throw DeviceControllerExceptions.recoverpoint.cgDeleteStepInvalidParam("protection system deleted");
        }
        if (volumeIDs == null) {
            _log.error("Volume IDs list is null");
            throw DeviceControllerExceptions.recoverpoint.cgDeleteStepInvalidParam("volume IDs null");
        }
        if (volumeIDs.isEmpty()) {
            _log.error("Volume IDs list is empty");
            throw DeviceControllerExceptions.recoverpoint.cgDeleteStepInvalidParam("volume IDs empty");
        }
        List<Volume> volumes = _dbClient.queryObject(Volume.class, volumeIDs);
        if (volumes.isEmpty()) {
            _log.info("All volumes already deleted. Not performing RP CG operation");
            WorkflowStepCompleter.stepSucceded(token);
            return true;
        }
        BlockConsistencyGroup cg = _dbClient.queryObject(BlockConsistencyGroup.class, volumes.get(0).getConsistencyGroup());
        // lock around create and delete operations on the same CG
        List<String> lockKeys = new ArrayList<String>();
        lockKeys.add(ControllerLockingUtil.getConsistencyGroupStorageKey(_dbClient, cg.getId(), system.getId()));
        boolean lockAcquired = _workflowService.acquireWorkflowLocks(_workflowService.getWorkflowFromStepId(token), lockKeys, LockTimeoutValue.get(LockType.RP_CG));
        if (!lockAcquired) {
            lockException = true;
            throw DeviceControllerException.exceptions.failedToAcquireLock(lockKeys.toString(), String.format("Delete or remove volumes from RP consistency group %s", cg.getCgNameOnStorageSystem(rpSystem)));
        }
        // Validate that all volumes belong to the same BlockConsistencyGroup
        for (Volume volume : volumes) {
            if (!volume.getConsistencyGroup().equals(cg.getId())) {
                _log.error("Not all volumes belong to the same consistency group.");
                throw DeviceControllerExceptions.recoverpoint.cgDeleteStepInvalidParam("volumes from different consistency groups");
            }
        }
        // Find a valid protection set reference so we can cleanup the protection set later.
        ProtectionSet protectionSet = null;
        for (Volume volume : volumes) {
            if (!NullColumnValueGetter.isNullNamedURI(volume.getProtectionSet())) {
                protectionSet = _dbClient.queryObject(ProtectionSet.class, volume.getProtectionSet());
                break;
            }
        }
        RecoverPointClient rp = RPHelper.getRecoverPointClient(system);
        // Validate that we found the protection info for each volume.
        RecoverPointVolumeProtectionInfo volumeProtectionInfo = null;
        for (Volume volume : volumes) {
            try {
                if (volumeProtectionInfo == null) {
                    volumeProtectionInfo = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(volume.getId(), _dbClient));
                    VirtualPool virtualPool = _dbClient.queryObject(VirtualPool.class, volume.getVirtualPool());
                    volumeProtectionInfo.setMetroPoint(VirtualPool.vPoolSpecifiesMetroPoint(virtualPool));
                }
            } catch (Exception e) {
                // Do nothing. If we cannot find volume protection info for a volume, we do not want that
                // exception preventing us from trying to find it for other volumes being deleted.
                _log.warn("Looks like the volume(s) we're trying to remove from the RP appliance are no longer associated with a RP CG, continuing delete process.");
            }
        }
        // is nothing in RP we need to cleanup.
        if (volumeProtectionInfo == null) {
            _log.warn("Looks like the volume(s) we're trying to remove from the RP appliance are no longer associated with a RP CG, continuing delete process.");
            WorkflowStepCompleter.stepSucceded(token);
            return true;
        }
        if (RPHelper.cgSourceVolumesContainsAll(_dbClient, cg.getId(), volumeIDs)) {
            // We are deleting all source volumes in the consistency group so we can delete the
            // RecoverPoint CG as well.
            rp.deleteCG(volumeProtectionInfo);
            // We want to reflect the CG being deleted in the BlockConsistencyGroup
            if (volumeIDs != null && !volumeIDs.isEmpty()) {
                // Get the CG URI from the first volume
                Volume vol = _dbClient.queryObject(Volume.class, volumeIDs.get(0));
                if (vol.getConsistencyGroup() != null) {
                    cleanUpRPCG(system.getId(), vol.getConsistencyGroup());
                }
                if (protectionSet == null || protectionSet.getInactive() || protectionSet.getVolumes() == null || protectionSet.getVolumes().isEmpty()) {
                    _log.info("Cleanup unnecessary as protection set in ViPR is empty or has already been marked for deletion.");
                } else {
                    _log.info("Removing all volume from protection set: " + protectionSet.getLabel());
                    // Remove all volumes in the ProtectionSet and mark for deletion
                    List<String> removeVolumeIDs = new ArrayList<String>(protectionSet.getVolumes());
                    cleanupProtectionSetVolumes(protectionSet, removeVolumeIDs, true);
                }
            }
            setProtectionSetStatus(volumeProtectionInfo, ProtectionStatus.DISABLED.toString(), system);
        } else {
            List<RecoverPointVolumeProtectionInfo> replicationSetsToRemove = new ArrayList<RecoverPointVolumeProtectionInfo>();
            List<String> removeVolumeIDs = new ArrayList<String>();
            for (Volume volume : volumes) {
                _log.info(String.format("Volume [%s] (%s) needs to have its replication set removed from RP", volume.getLabel(), volume.getId()));
                // Delete the replication set if there are more volumes (other replication sets).
                // If there are no other replications sets we will simply delete the CG instead.
                volumeProtectionInfo = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(volume.getId(), _dbClient));
                // Volume Info to give RP to clean up the RSets
                replicationSetsToRemove.add(volumeProtectionInfo);
                // Source volume to be removed from Protection Set
                if (!NullColumnValueGetter.isNullURI(volume.getId())) {
                    removeVolumeIDs.add(volume.getId().toString());
                }
                // All Target volumes to be removed from Protection Set
                List<Volume> targetVolumes = RPHelper.getTargetVolumes(volume, _dbClient);
                for (Volume targetVol : targetVolumes) {
                    removeVolumeIDs.add(targetVol.getId().toString());
                }
            }
            // Remove the Replication Sets from RP.
            // Wait for a min before attempting to delete the rsets.
            // RP has not yet synced up with the fact that new rsets were added and we attempted to delete them
            // because the rollback
            // started.
            // This delay helps in RP catching up before we issue another command.
            _log.info("waiting for 1 min before deleting replication sets");
            Thread.sleep(1000 * 60);
            rp.deleteReplicationSets(replicationSetsToRemove);
            // Remove any journal volumes that were added in this operation. Otherwise CG ends up in a weird state.
            if (journalVolumeIDs.isEmpty()) {
                _log.info("There are no journal volumes to be deleted");
            } else {
                List<Volume> journalVolumes = _dbClient.queryObject(Volume.class, journalVolumeIDs);
                for (Volume journalVolume : journalVolumes) {
                    String journalWWN = RPHelper.getRPWWn(journalVolume.getId(), _dbClient);
                    _log.info(String.format("Removing Journal volume - %s : WWN - %s", journalVolume.getLabel(), journalWWN));
                    volumeProtectionInfo = rp.getProtectionInfoForVolume(journalWWN);
                    rp.deleteJournalFromCopy(volumeProtectionInfo, journalWWN);
                    removeVolumeIDs.add(journalVolume.getId().toString());
                }
            }
            // Cleanup the ViPR Protection Set
            cleanupProtectionSetVolumes(protectionSet, removeVolumeIDs, false);
        }
        WorkflowStepCompleter.stepSucceded(token);
        _log.info("cgDeleteStep is complete");
        // collect and update the protection system statistics to account for
        // the CG that has been removed
        _log.info("Collection RP statistics post CG delete.");
        // Collect stats, even if we didn't delete the CG, because the volume count in the CG will go down.
        collectRPStatistics(system);
    } catch (Exception e) {
        if (lockException) {
            ServiceError serviceError = DeviceControllerException.errors.deleteVolumesAborted(volumeIDs.toString(), e);
            return stepFailed(token, serviceError, "cgDeleteStep");
        } else {
            return stepFailed(token, e, "cgDeleteStep");
        }
    }
    return true;
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) ArrayList(java.util.ArrayList) ProtectionSet(com.emc.storageos.db.client.model.ProtectionSet) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) ProtectionSystem(com.emc.storageos.db.client.model.ProtectionSystem) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) InternalServerErrorException(com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) LockRetryException(com.emc.storageos.locking.LockRetryException) FunctionalAPIActionFailedException_Exception(com.emc.fapiclient.ws.FunctionalAPIActionFailedException_Exception) URISyntaxException(java.net.URISyntaxException) WorkflowException(com.emc.storageos.workflow.WorkflowException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) FunctionalAPIInternalError_Exception(com.emc.fapiclient.ws.FunctionalAPIInternalError_Exception) CoordinatorException(com.emc.storageos.coordinator.exceptions.CoordinatorException) RecoverPointException(com.emc.storageos.recoverpoint.exceptions.RecoverPointException) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) RecoverPointVolumeProtectionInfo(com.emc.storageos.recoverpoint.responses.RecoverPointVolumeProtectionInfo) Volume(com.emc.storageos.db.client.model.Volume) RecoverPointClient(com.emc.storageos.recoverpoint.impl.RecoverPointClient)

Example 22 with RecoverPointVolumeProtectionInfo

use of com.emc.storageos.recoverpoint.responses.RecoverPointVolumeProtectionInfo in project coprhd-controller by CoprHD.

the class RPDeviceController method getReplicationSettings.

/**
 * Gets the replication settings from RP for a given volume.
 *
 * @param rpSystem
 *            the RecoverPoint system.
 * @param volumeId
 *            the volume ID.
 * @return the replication set params to perform a recreate operation
 * @throws RecoverPointException
 */
public RecreateReplicationSetRequestParams getReplicationSettings(ProtectionSystem rpSystem, URI volumeId) throws RecoverPointException {
    RecoverPointClient rp = RPHelper.getRecoverPointClient(rpSystem);
    Volume volume = _dbClient.queryObject(Volume.class, volumeId);
    RecoverPointVolumeProtectionInfo volumeProtectionInfo = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(volume.getId(), _dbClient));
    return rp.getReplicationSet(volumeProtectionInfo);
}
Also used : RecoverPointVolumeProtectionInfo(com.emc.storageos.recoverpoint.responses.RecoverPointVolumeProtectionInfo) Volume(com.emc.storageos.db.client.model.Volume) RecoverPointClient(com.emc.storageos.recoverpoint.impl.RecoverPointClient)

Aggregations

RecoverPointVolumeProtectionInfo (com.emc.storageos.recoverpoint.responses.RecoverPointVolumeProtectionInfo)22 RecoverPointException (com.emc.storageos.recoverpoint.exceptions.RecoverPointException)15 Volume (com.emc.storageos.db.client.model.Volume)7 RecoverPointClient (com.emc.storageos.recoverpoint.impl.RecoverPointClient)7 ArrayList (java.util.ArrayList)7 FunctionalAPIActionFailedException_Exception (com.emc.fapiclient.ws.FunctionalAPIActionFailedException_Exception)5 FunctionalAPIInternalError_Exception (com.emc.fapiclient.ws.FunctionalAPIInternalError_Exception)5 RPCopyRequestParams (com.emc.storageos.recoverpoint.requests.RPCopyRequestParams)5 URISyntaxException (java.net.URISyntaxException)5 CoordinatorException (com.emc.storageos.coordinator.exceptions.CoordinatorException)3 NamedURI (com.emc.storageos.db.client.model.NamedURI)3 ProtectionSet (com.emc.storageos.db.client.model.ProtectionSet)3 ProtectionSystem (com.emc.storageos.db.client.model.ProtectionSystem)3 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)3 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)3 LockRetryException (com.emc.storageos.locking.LockRetryException)3 RecoverPointImageManagementUtils (com.emc.storageos.recoverpoint.utils.RecoverPointImageManagementUtils)3 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)3 URI (java.net.URI)3 ConsistencyGroupCopyUID (com.emc.fapiclient.ws.ConsistencyGroupCopyUID)2