Search in sources :

Example 1 with RecoverPointVolumeProtectionInfo

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

the class RPDeviceController method performProtectionOperationStep.

/**
 * Workflow step to perform RP protection operation
 *
 * @param protectionSystem
 * @param cgId
 * @param volId
 * @param copyID
 * @param pointInTime
 * @param imageAccessMode
 * @param op
 * @param stepId
 * @return
 * @throws ControllerException
 */
public boolean performProtectionOperationStep(URI protectionSystem, URI cgId, URI volId, URI copyID, String pointInTime, String imageAccessMode, String op, String stepId) throws ControllerException {
    WorkflowStepCompleter.stepExecuting(stepId);
    RPHelper.setLinkStateWaitTimeOut(_coordinator);
    try {
        ProtectionSystem rpSystem = getRPSystem(protectionSystem);
        // Take out a workflow step lock on the CG
        _workflowService.getWorkflowFromStepId(stepId);
        List<String> lockKeys = new ArrayList<String>();
        lockKeys.add(ControllerLockingUtil.getConsistencyGroupStorageKey(_dbClient, cgId, rpSystem.getId()));
        boolean lockAcquired = _workflowService.acquireWorkflowStepLocks(stepId, lockKeys, LockTimeoutValue.get(LockType.RP_CG));
        if (!lockAcquired) {
            throw DeviceControllerException.exceptions.failedToAcquireLock(lockKeys.toString(), String.format("failed to get lock while restoring volumes in RP consistency group: %s", cgId.toString()));
        }
        // set the protection volume to the source volume if the copyID is null (operation is performed on all
        // copies)
        // otherwise set it to the volume referenced by the copyID (operation is performed on specifc copy)
        Volume protectionVolume = (copyID == null) ? _dbClient.queryObject(Volume.class, volId) : _dbClient.queryObject(Volume.class, copyID);
        RecoverPointClient rp = RPHelper.getRecoverPointClient(rpSystem);
        RecoverPointVolumeProtectionInfo volumeProtectionInfo = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(protectionVolume.getId(), _dbClient));
        if (op.equals(STOP)) {
            rp.disableProtection(volumeProtectionInfo);
            setProtectionSetStatus(volumeProtectionInfo, ProtectionStatus.DISABLED.toString(), rpSystem);
            _log.info("doStopProtection {} - complete", rpSystem.getId());
        } else if (op.equals(START)) {
            rp.enableProtection(volumeProtectionInfo);
            setProtectionSetStatus(volumeProtectionInfo, ProtectionStatus.ENABLED.toString(), rpSystem);
        } else if (op.equals(SYNC)) {
            Set<String> volumeWWNs = new HashSet<String>();
            volumeWWNs.add(RPHelper.getRPWWn(protectionVolume.getId(), _dbClient));
            // Create and enable a temporary bookmark for the volume associated with this volume
            CreateBookmarkRequestParams request = new CreateBookmarkRequestParams();
            request.setVolumeWWNSet(volumeWWNs);
            request.setBookmark("Sync-Snapshot");
            rp.createBookmarks(request);
        } else if (op.equals(PAUSE)) {
            rp.pauseTransfer(volumeProtectionInfo);
            setProtectionSetStatus(volumeProtectionInfo, ProtectionStatus.PAUSED.toString(), rpSystem);
        } else if (op.equals(RESUME)) {
            rp.resumeTransfer(volumeProtectionInfo);
            setProtectionSetStatus(volumeProtectionInfo, ProtectionStatus.ENABLED.toString(), rpSystem);
        } else if (op.equals(FAILOVER_TEST)) {
            RPCopyRequestParams copyParams = new RPCopyRequestParams();
            copyParams.setCopyVolumeInfo(volumeProtectionInfo);
            rp.failoverCopyTest(copyParams);
        } else if (op.equals(FAILOVER)) {
            // cancel.
            if (protectionVolume.getLinkStatus() != null && protectionVolume.getLinkStatus().equalsIgnoreCase(Volume.LinkStatus.FAILED_OVER.name())) {
                // TODO: ViPR 2.0 needs to support this.
                // TODO BEGIN: allow re-failover perform the same as a failback in 2.0 since the UI support will not
                // be there to do a
                // swap or cancel.
                // Jira CTRL-2773: Once UI adds support for /swap and /failover-cancel, we can remove this and
                // replace with an error.
                // If protectionVolume is a source, then the "source" sent in must be a target. Verify.
                Volume targetVolume = null;
                if (protectionVolume.checkPersonality(Volume.PersonalityTypes.SOURCE.toString())) {
                    targetVolume = _dbClient.queryObject(Volume.class, volId);
                } else {
                    targetVolume = protectionVolume;
                }
                // Disable the image access that is in effect.
                volumeProtectionInfo = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(targetVolume.getId(), _dbClient));
                RPCopyRequestParams copyParams = new RPCopyRequestParams();
                copyParams.setCopyVolumeInfo(volumeProtectionInfo);
                rp.failoverCopyCancel(copyParams);
                // Set the flags back to where they belong.
                updatePostFailoverCancel(targetVolume);
            // TODO END
            // Replace with this error: taskCompleter.error(_dbClient, _locker,
            // DeviceControllerErrors.recoverpoint.stepFailed("performFailoverOperation: source volume specified
            // for failover where target volume specified is not in failover state"));
            } else {
                // Standard failover case.
                RPCopyRequestParams copyParams = new RPCopyRequestParams();
                copyParams.setCopyVolumeInfo(volumeProtectionInfo);
                if (pointInTime != null) {
                    // Build a Date reference.
                    copyParams.setApitTime(TimeUtils.getDateTimestamp(pointInTime));
                }
                rp.failoverCopy(copyParams);
                updatePostFailover(protectionVolume);
            }
        } else if (op.equals(FAILOVER_CANCEL)) {
            // cancel.
            if (protectionVolume.checkPersonality(Volume.PersonalityTypes.SOURCE.name())) {
                throw DeviceControllerExceptions.recoverpoint.failoverWrongTargetSpecified();
            } else {
                if (protectionVolume.getLinkStatus() != null && protectionVolume.getLinkStatus().equalsIgnoreCase(Volume.LinkStatus.FAILED_OVER.name())) {
                    // Disable the image access that is in effect.
                    volumeProtectionInfo = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(protectionVolume.getId(), _dbClient));
                    RPCopyRequestParams copyParams = new RPCopyRequestParams();
                    copyParams.setCopyVolumeInfo(volumeProtectionInfo);
                    rp.failoverCopyCancel(copyParams);
                    // Set the flags back to where they belong.
                    updatePostFailoverCancel(protectionVolume);
                } else {
                    // failed over target.
                    throw DeviceControllerExceptions.recoverpoint.failoverWrongTargetSpecified();
                }
            }
        } else if (op.equals(SWAP)) {
            RPCopyRequestParams copyParams = new RPCopyRequestParams();
            copyParams.setCopyVolumeInfo(volumeProtectionInfo);
            rp.swapCopy(copyParams);
            protectionVolume = updatePostSwapPersonalities(protectionVolume);
            rp.setCopyAsProduction(copyParams);
            // 3. add back the standby CDP copy
            if (RPHelper.isMetroPointVolume(_dbClient, protectionVolume)) {
                // copy exists, we can skip all the CG reconstruction steps.
                if (!rp.doesStandbyProdCopyExist(volumeProtectionInfo)) {
                    _log.info(String.format("Adding back standby production copy after swap back to original VPlex Metro for Metropoint volume %s (%s)", protectionVolume.getLabel(), protectionVolume.getId().toString()));
                    List<Volume> standbyLocalCopyVols = RPHelper.getMetropointStandbyCopies(protectionVolume, _dbClient);
                    CreateCopyParams standbyLocalCopyParams = null;
                    List<CreateRSetParams> rSets = new ArrayList<CreateRSetParams>();
                    Set<URI> journalVolumes = new HashSet<URI>();
                    List<String> deletedCopies = new ArrayList<>();
                    if (!standbyLocalCopyVols.isEmpty()) {
                        for (Volume standbyCopyVol : standbyLocalCopyVols) {
                            // For case where there are multiple Rsets, we should invoke deleteCopy only once, it shall
                            // remove the related copy information from other Rsets as well. rpCopyName is same across
                            // all Rpsets, so track the delete based on rpCopyName
                            String rpCopyName = standbyCopyVol.getRpCopyName().trim();
                            if (!deletedCopies.contains(rpCopyName)) {
                                // 1. delete the standby CDP copy if it exists
                                if (rp.doesProtectionVolumeExist(RPHelper.getRPWWn(standbyCopyVol.getId(), _dbClient))) {
                                    RecoverPointVolumeProtectionInfo standbyCdpCopy = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(standbyCopyVol.getId(), _dbClient));
                                    rp.deleteCopy(standbyCdpCopy);
                                    deletedCopies.add(rpCopyName);
                                }
                            }
                            // set up volume info for the standby copy volume
                            CreateVolumeParams vol = new CreateVolumeParams();
                            vol.setWwn(RPHelper.getRPWWn(standbyCopyVol.getId(), _dbClient));
                            vol.setInternalSiteName(standbyCopyVol.getInternalSiteName());
                            vol.setProduction(false);
                            List<CreateVolumeParams> volumes = new ArrayList<CreateVolumeParams>();
                            volumes.add(vol);
                            CreateRSetParams rSet = new CreateRSetParams();
                            rSet.setName(standbyCopyVol.getRSetName());
                            rSet.setVolumes(volumes);
                            rSets.add(rSet);
                            List<Volume> standbyJournals = RPHelper.findExistingJournalsForCopy(_dbClient, standbyCopyVol.getConsistencyGroup(), standbyCopyVol.getRpCopyName());
                            // compile a unique set of journal volumes
                            for (Volume standbyJournal : standbyJournals) {
                                journalVolumes.add(standbyJournal.getId());
                            }
                        }
                        // prepare journal volumes info
                        String rpCopyName = null;
                        List<CreateVolumeParams> journalVols = new ArrayList<CreateVolumeParams>();
                        for (URI journalVolId : journalVolumes) {
                            Volume standbyLocalJournal = _dbClient.queryObject(Volume.class, journalVolId);
                            if (standbyLocalJournal != null) {
                                _log.info(String.format("Found standby local journal volume %s (%s) for metropoint volume %s (%s)", standbyLocalJournal.getLabel(), standbyLocalJournal.getId().toString(), protectionVolume.getLabel(), protectionVolume.getId().toString()));
                                rpCopyName = standbyLocalJournal.getRpCopyName();
                                CreateVolumeParams journalVolParams = new CreateVolumeParams();
                                journalVolParams.setWwn(RPHelper.getRPWWn(standbyLocalJournal.getId(), _dbClient));
                                journalVolParams.setInternalSiteName(standbyLocalJournal.getInternalSiteName());
                                journalVols.add(journalVolParams);
                            }
                        }
                        // if we found any journal volumes, add them to the local copies list
                        if (!journalVols.isEmpty()) {
                            standbyLocalCopyParams = new CreateCopyParams();
                            standbyLocalCopyParams.setName(rpCopyName);
                            standbyLocalCopyParams.setJournals(journalVols);
                        } else {
                            _log.error("no journal volumes found for standby production copy for source volume " + protectionVolume.getLabel());
                        }
                    }
                    String standbyProductionCopyName = RPHelper.getStandbyProductionCopyName(_dbClient, protectionVolume);
                    // Build standby production journal
                    if (standbyProductionCopyName != null) {
                        List<Volume> existingStandbyJournals = RPHelper.findExistingJournalsForCopy(_dbClient, protectionVolume.getConsistencyGroup(), standbyProductionCopyName);
                        // Get the first standby production journal
                        Volume standbyProdJournal = existingStandbyJournals.get(0);
                        if (standbyProdJournal != null) {
                            _log.info(String.format("Found standby production journal volume %s (%s) for metropoint volume %s (%s)", standbyProdJournal.getLabel(), standbyProdJournal.getId().toString(), protectionVolume.getLabel(), protectionVolume.getId().toString()));
                            List<CreateVolumeParams> journalVols = new ArrayList<CreateVolumeParams>();
                            CreateVolumeParams journalVolParams = new CreateVolumeParams();
                            journalVolParams.setWwn(RPHelper.getRPWWn(standbyProdJournal.getId(), _dbClient));
                            journalVolParams.setInternalSiteName(standbyProdJournal.getInternalSiteName());
                            journalVols.add(journalVolParams);
                            CreateCopyParams standbyProdCopyParams = new CreateCopyParams();
                            standbyProdCopyParams.setName(standbyProdJournal.getRpCopyName());
                            standbyProdCopyParams.setJournals(journalVols);
                            // 2. and 3. add back the standby production copy; add back the standby CDP copy
                            rp.addStandbyProductionCopy(standbyProdCopyParams, standbyLocalCopyParams, rSets, copyParams);
                        } else {
                            _log.error(String.format("Cannot add standby production copy because the standby production journal could not be found for copy %s.", standbyProductionCopyName));
                        }
                    }
                }
            }
            // copy bookmarks before we cleanup the corresponding BlockSnapshot objects from ViPR.
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            // When we perform a swap, the target swap copy will become the production copy and lose all
            // its bookmarks so we need to sync with RP.
            RPHelper.cleanupSnapshots(_dbClient, rpSystem);
        } else if (op.equals(FAILOVER_TEST_CANCEL)) {
            RPCopyRequestParams copyParams = new RPCopyRequestParams();
            copyParams.setCopyVolumeInfo(volumeProtectionInfo);
            rp.failoverCopyTestCancel(copyParams);
        } else if (op.equals(CHANGE_ACCESS_MODE)) {
            RPCopyRequestParams copyParams = new RPCopyRequestParams();
            copyParams.setCopyVolumeInfo(volumeProtectionInfo);
            copyParams.setImageAccessMode(imageAccessMode);
            if (imageAccessMode != null) {
                rp.updateImageAccessMode(copyParams);
                // BlockSnapshot objects that reference the target copy being set to direct access mode.
                if (Copy.ImageAccessMode.DIRECT_ACCESS.name().equalsIgnoreCase(imageAccessMode)) {
                    _log.info(String.format("Updated imaged access mode for copy %s at %s to DIRECT_ACCESS. Removing all bookmarks associated with that copy and site.", volumeProtectionInfo.getRpCopyName(), volumeProtectionInfo.getRpSiteName()));
                    // Wait for RP to remove copy snapshots
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                    RPHelper.cleanupSnapshots(_dbClient, rpSystem);
                }
            } else {
                throw DeviceControllerExceptions.recoverpoint.imageAccessModeNotSupported(imageAccessMode);
            }
        } else {
            throw DeviceControllerExceptions.recoverpoint.protectionOperationNotSupported(op);
        }
        _log.info("performProtectionOperation: after " + op + " operation successful");
        WorkflowStepCompleter.stepSucceded(stepId);
        return true;
    } catch (InternalException e) {
        _log.error("Operation failed with Exception: ", e);
        return stepFailed(stepId, (ServiceCoded) e, "removeProtection operation failed.");
    } catch (Exception e) {
        stepFailed(stepId, e, "removeProtection operation failed.");
        return false;
    }
}
Also used : CreateRSetParams(com.emc.storageos.recoverpoint.requests.CreateRSetParams) ArrayList(java.util.ArrayList) ProtectionSystem(com.emc.storageos.db.client.model.ProtectionSystem) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) RPCopyRequestParams(com.emc.storageos.recoverpoint.requests.RPCopyRequestParams) CreateVolumeParams(com.emc.storageos.recoverpoint.requests.CreateVolumeParams) 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) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) CreateBookmarkRequestParams(com.emc.storageos.recoverpoint.requests.CreateBookmarkRequestParams) RecoverPointVolumeProtectionInfo(com.emc.storageos.recoverpoint.responses.RecoverPointVolumeProtectionInfo) Volume(com.emc.storageos.db.client.model.Volume) ServiceCoded(com.emc.storageos.svcs.errorhandling.model.ServiceCoded) RecoverPointClient(com.emc.storageos.recoverpoint.impl.RecoverPointClient) CreateCopyParams(com.emc.storageos.recoverpoint.requests.CreateCopyParams) HashSet(java.util.HashSet)

Example 2 with RecoverPointVolumeProtectionInfo

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

the class RPDeviceController method constructSnapshotObjectFromBookmark.

/**
 * Amend the BlockSnapshot object based on the results of the Bookmark creation operation
 *
 * @param result
 *            result from the snapshot creation command
 * @param system
 *            protection system
 * @param snapshotList
 *            snapshot list generated
 * @param name
 *            emName
 * @param opId
 *            operation ID for task completer
 * @throws InternalException
 * @throws FunctionalAPIInternalError_Exception
 * @throws FunctionalAPIActionFailedException_Exception
 */
private void constructSnapshotObjectFromBookmark(CreateBookmarkResponse response, ProtectionSystem system, List<URI> snapshotList, String name, String opId) throws InternalException {
    ProtectionSet protectionSet = null;
    RecoverPointClient rp = RPHelper.getRecoverPointClient(system);
    // Update each snapshot object with the respective information.
    for (URI snapshotID : snapshotList) {
        // Get the snapshot and the associated volume
        BlockSnapshot snapshot = _dbClient.queryObject(BlockSnapshot.class, snapshotID);
        Volume volume = _dbClient.queryObject(Volume.class, snapshot.getParent().getURI());
        // Fetch the VPLEX volume that is created with this volume as the back-end volume.
        if (Volume.checkForVplexBackEndVolume(_dbClient, volume)) {
            volume = Volume.fetchVplexVolume(_dbClient, volume);
        }
        if (protectionSet == null || !protectionSet.getId().equals(volume.getProtectionSet().getURI())) {
            protectionSet = _dbClient.queryObject(ProtectionSet.class, volume.getProtectionSet());
        }
        // Gather the bookmark date, which is different than the snapshot date
        Date bookmarkDate = new Date();
        if (response.getVolumeWWNBookmarkDateMap() != null) {
            bookmarkDate = response.getVolumeWWNBookmarkDateMap().get(RPHelper.getRPWWn(volume.getId(), _dbClient));
        } else {
            _log.warn("Bookmark date was not filled-in.  Will use current date/time.");
        }
        snapshot.setEmName(name);
        snapshot.setInactive(false);
        snapshot.setEmBookmarkTime("" + bookmarkDate.getTime());
        snapshot.setCreationTime(Calendar.getInstance());
        snapshot.setTechnologyType(TechnologyType.RP.toString());
        Volume targetVolume = RPHelper.getRPTargetVolumeFromSource(_dbClient, volume, snapshot.getVirtualArray());
        // This section will identify and store the COPY ID associated with the bookmarks created.
        // It is critical to store this information so we can later determine which bookmarks have
        // been deleted from the RPA.
        // 
        // May be able to remove this if the protection set object is more detailed (for instance, if
        // we store the copy id with the volume)
        RecoverPointVolumeProtectionInfo protectionInfo = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(targetVolume.getId(), _dbClient));
        for (RPConsistencyGroup rpcg : response.getCgBookmarkMap().keySet()) {
            if (rpcg.getCGUID().getId() == protectionInfo.getRpVolumeGroupID()) {
                for (RPBookmark bookmark : response.getCgBookmarkMap().get(rpcg)) {
                    if (bookmark.getBookmarkName() != null && bookmark.getBookmarkName().equalsIgnoreCase(name) && bookmark.getCGGroupCopyUID().getGlobalCopyUID().getCopyUID() == protectionInfo.getRpVolumeGroupCopyID()) {
                        snapshot.setEmCGGroupCopyId(protectionInfo.getRpVolumeGroupCopyID());
                        break;
                    }
                }
            }
        }
        if (targetVolume.getId().equals(volume.getId())) {
            _log.error("The source and the target volumes are the same");
            throw DeviceControllerExceptions.recoverpoint.cannotActivateSnapshotNoTargetVolume();
        }
        snapshot.setDeviceLabel(targetVolume.getDeviceLabel());
        snapshot.setStorageController(targetVolume.getStorageController());
        snapshot.setSystemType(targetVolume.getSystemType());
        snapshot.setVirtualArray(targetVolume.getVirtualArray());
        snapshot.setNativeId(targetVolume.getNativeId());
        snapshot.setAlternateName(targetVolume.getAlternateName());
        snapshot.setNativeGuid(NativeGUIDGenerator.generateNativeGuid(system, snapshot));
        snapshot.setIsSyncActive(false);
        // Setting the WWN of the bookmark to the WWN of the volume, no functional reason for now.
        snapshot.setWWN(RPHelper.getRPWWn(targetVolume.getId(), _dbClient));
        snapshot.setProtectionController(system.getId());
        snapshot.setProtectionSet(volume.getProtectionSet().getURI());
        _log.info(String.format("Updated bookmark %1$s associated with block volume %2$s on site %3$s.", name, volume.getDeviceLabel(), snapshot.getEmInternalSiteName()));
        _dbClient.updateObject(snapshot);
        List<URI> taskSnapshotURIList = new ArrayList<URI>();
        taskSnapshotURIList.add(snapshot.getId());
        TaskCompleter completer = new BlockSnapshotCreateCompleter(taskSnapshotURIList, opId);
        completer.ready(_dbClient);
    }
    // Get information about the bookmarks created so we can get to them later.
    _log.info("Bookmark(s) created for snapshot operation");
    return;
}
Also used : ProtectionSet(com.emc.storageos.db.client.model.ProtectionSet) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) ArrayList(java.util.ArrayList) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) BlockSnapshotCreateCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.BlockSnapshotCreateCompleter) Date(java.util.Date) RPConsistencyGroup(com.emc.storageos.recoverpoint.objectmodel.RPConsistencyGroup) RecoverPointVolumeProtectionInfo(com.emc.storageos.recoverpoint.responses.RecoverPointVolumeProtectionInfo) Volume(com.emc.storageos.db.client.model.Volume) RecoverPointClient(com.emc.storageos.recoverpoint.impl.RecoverPointClient) VolumeGroupUpdateTaskCompleter(com.emc.storageos.vplexcontroller.completers.VolumeGroupUpdateTaskCompleter) TaskCompleter(com.emc.storageos.volumecontroller.TaskCompleter) VolumeVpoolChangeTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.VolumeVpoolChangeTaskCompleter) RPCGProtectionTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.RPCGProtectionTaskCompleter) RPBookmark(com.emc.storageos.recoverpoint.objectmodel.RPBookmark)

Example 3 with RecoverPointVolumeProtectionInfo

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

the class RPDeviceController method upgradeRPVPlexToMetroPoint.

/**
 * Upgrades a RP+VPLEX CG to MetroPoint by adding a standby journal to the HA side.
 *
 * Prerequisite: All RSets(volumes) in the CG must have had their HA sides already exported to RP in VPLEX.
 *
 * @param sourceVolume
 *            A single source volume from the CG, we only need one.
 * @param rpSystem
 *            The rpSystem we're using
 */
private void upgradeRPVPlexToMetroPoint(Volume sourceVolume, VirtualPool newVpool, VirtualPool oldVpool, ProtectionSystem rpSystem) {
    // Grab the new standby journal from the CG
    String standbyCopyName = RPHelper.getStandbyProductionCopyName(_dbClient, sourceVolume);
    List<Volume> existingStandbyJournals = RPHelper.findExistingJournalsForCopy(_dbClient, sourceVolume.getConsistencyGroup(), standbyCopyName);
    if (existingStandbyJournals.isEmpty()) {
        _log.error(String.format("Could not find standby journal during upgrade to MetroPoint operation. " + "Expected to find a new standby journal for RP copy [%s]", standbyCopyName));
        throw RecoverPointException.exceptions.cannotFindJournal(String.format("for RP copy [%s]", standbyCopyName));
    }
    Volume standbyProdJournal = existingStandbyJournals.get(0);
    // Add new standby journal
    if (standbyProdJournal != null) {
        _log.info(String.format("Upgrade RP+VPLEX CG to MetroPoint by adding new standby journal [%s] to the CG", standbyProdJournal.getLabel()));
        RecoverPointClient rp = RPHelper.getRecoverPointClient(rpSystem);
        RecoverPointVolumeProtectionInfo protectionInfo = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(sourceVolume.getId(), _dbClient));
        _log.info(String.format("RecoverPointVolumeProtectionInfo [%s] retrieved", protectionInfo.getRpProtectionName()));
        RPCopyRequestParams copyParams = new RPCopyRequestParams();
        copyParams.setCopyVolumeInfo(protectionInfo);
        List<CreateVolumeParams> journaVols = new ArrayList<CreateVolumeParams>();
        CreateVolumeParams journalVolParams = new CreateVolumeParams();
        journalVolParams.setWwn(RPHelper.getRPWWn(standbyProdJournal.getId(), _dbClient));
        journalVolParams.setInternalSiteName(standbyProdJournal.getInternalSiteName());
        journaVols.add(journalVolParams);
        CreateCopyParams standbyProdCopyParams = new CreateCopyParams();
        standbyProdCopyParams.setName(standbyProdJournal.getRpCopyName());
        standbyProdCopyParams.setJournals(journaVols);
        _log.info(String.format("Adding standby journal [%s] to teh RP CG...", standbyProdJournal.getLabel()));
        // TODO BH - Empty, not sure why we need this
        List<CreateRSetParams> rSets = new ArrayList<CreateRSetParams>();
        rp.addStandbyProductionCopy(standbyProdCopyParams, null, rSets, copyParams);
        _log.info("Standby journal added successfully.");
        // TODO Add new Targets if they exist ??
        // Next we need to update the vpool reference of any existing related volumes
        // that were referencing the old vpool.
        // We'll start by getting all source volumes from the ViPR CG
        BlockConsistencyGroup viprCG = _dbClient.queryObject(BlockConsistencyGroup.class, sourceVolume.getConsistencyGroup());
        List<Volume> allSourceVolumesInCG = BlockConsistencyGroupUtils.getActiveVplexVolumesInCG(viprCG, _dbClient, Volume.PersonalityTypes.SOURCE);
        for (Volume sourceVol : allSourceVolumesInCG) {
            // For each source volume, we'll get all the related volumes (Targets, Journals, Backing volumes for
            // VPLEX...etc)
            Set<Volume> allRelatedVolumes = RPHelper.getAllRelatedVolumesForSource(sourceVol.getId(), _dbClient, true, true);
            // If it is, update the reference and persist the change.
            for (Volume rpRelatedVol : allRelatedVolumes) {
                if (rpRelatedVol.getVirtualPool().equals(oldVpool.getId())) {
                    rpRelatedVol.setVirtualPool(newVpool.getId());
                    _dbClient.updateObject(rpRelatedVol);
                    _log.info(String.format("Volume [%s] has had its virtual pool updated to [%s].", rpRelatedVol.getLabel(), newVpool.getLabel()));
                }
            }
        }
    }
}
Also used : CreateRSetParams(com.emc.storageos.recoverpoint.requests.CreateRSetParams) ArrayList(java.util.ArrayList) RPCopyRequestParams(com.emc.storageos.recoverpoint.requests.RPCopyRequestParams) CreateVolumeParams(com.emc.storageos.recoverpoint.requests.CreateVolumeParams) 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) CreateCopyParams(com.emc.storageos.recoverpoint.requests.CreateCopyParams)

Example 4 with RecoverPointVolumeProtectionInfo

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

the class RPCommunicationInterface method discoverProtectionSet.

/**
 * Discover a single protection set.
 *
 * @param protectionSystem protection system
 * @param protectionSetId protection set
 * @throws RecoverPointException
 */
private void discoverProtectionSet(ProtectionSystem protectionSystem, URI protectionSetId) throws RecoverPointException {
    ProtectionSet protectionSet = _dbClient.queryObject(ProtectionSet.class, protectionSetId);
    if (protectionSet == null || protectionSet.getInactive()) {
        return;
    }
    List<String> staleVolumes = new ArrayList<String>();
    StringSet protectionVolumes = protectionSet.getVolumes();
    RecoverPointVolumeProtectionInfo protectionVolume = null;
    RecoverPointClient rp = RPHelper.getRecoverPointClient(protectionSystem);
    boolean changed = false;
    _log.info("ProtectionSet discover in the RPDeviceController called for protection set: " + protectionSet.getLabel());
    for (String volume : protectionVolumes) {
        Volume protectionVolumeWWN = _dbClient.queryObject(Volume.class, URI.create(volume));
        if (protectionVolumeWWN == null || protectionVolumeWWN.getInactive()) {
            staleVolumes.add(volume);
            continue;
        }
        try {
            protectionVolume = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(protectionVolumeWWN.getId(), _dbClient));
        } catch (RecoverPointException re) {
            StringBuffer errMsgBuilder = new StringBuffer();
            String msg = "Discovery of protection set failed. Protection system: " + protectionSystem.getId() + ", ";
            errMsgBuilder.append(msg);
            errMsgBuilder.append(re.getMessage());
            _log.warn(errMsgBuilder.toString());
        }
        if (protectionVolume == null) {
            continue;
        }
        // If the volume is a source volume, let's check to see if the personality changed.
        if ((!changed) && (((protectionVolume.getRpVolumeCurrentProtectionStatus() == RecoverPointVolumeProtectionInfo.volumeProtectionStatus.PROTECTED_SOURCE) && (protectionVolumeWWN.getPersonality().equalsIgnoreCase(Volume.PersonalityTypes.TARGET.toString())))) || ((protectionVolume.getRpVolumeCurrentProtectionStatus() == RecoverPointVolumeProtectionInfo.volumeProtectionStatus.PROTECTED_TARGET) && (protectionVolumeWWN.getPersonality().equalsIgnoreCase(Volume.PersonalityTypes.SOURCE.toString())))) {
            _log.info("Changing personality of volume {} due to RP condition on consistency group", protectionVolumeWWN.getLabel());
            updatePostFailoverPersonalities(protectionVolumeWWN);
            changed = true;
        }
        if (protectionVolume.getRpVolumeCurrentProtectionStatus() == RecoverPointVolumeProtectionInfo.volumeProtectionStatus.PROTECTED_SOURCE) {
            switch(rp.getCGState(protectionVolume)) {
                case DELETED:
                    protectionSet.setProtectionStatus(ProtectionStatus.DELETED.toString());
                    break;
                case STOPPED:
                    protectionSet.setProtectionStatus(ProtectionStatus.DISABLED.toString());
                    break;
                case PAUSED:
                    protectionSet.setProtectionStatus(ProtectionStatus.PAUSED.toString());
                    break;
                case MIXED:
                    protectionSet.setProtectionStatus(ProtectionStatus.MIXED.toString());
                    break;
                case READY:
                    protectionSet.setProtectionStatus(ProtectionStatus.ENABLED.toString());
                    break;
            }
            _dbClient.updateObject(protectionSet);
            break;
        }
    }
    // remove stale entries from protection set
    if (!staleVolumes.isEmpty()) {
        _log.info(String.format("ProtectionSet %s references at least one volume id that no longer exist in the database. Removing all stale volume references: %s", protectionSet.getLabel(), String.join(",", staleVolumes)));
        protectionSet.getVolumes().removeAll(staleVolumes);
        _dbClient.updateObject(protectionSet);
    }
}
Also used : RecoverPointVolumeProtectionInfo(com.emc.storageos.recoverpoint.responses.RecoverPointVolumeProtectionInfo) Volume(com.emc.storageos.db.client.model.Volume) RecoverPointClient(com.emc.storageos.recoverpoint.impl.RecoverPointClient) RecoverPointException(com.emc.storageos.recoverpoint.exceptions.RecoverPointException) ProtectionSet(com.emc.storageos.db.client.model.ProtectionSet) ArrayList(java.util.ArrayList) StringSet(com.emc.storageos.db.client.model.StringSet)

Example 5 with RecoverPointVolumeProtectionInfo

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

the class RecoverPointClient method failoverCopyTest.

/**
 * Perform a failover test to the consistency group copy specified by the input request params.
 *
 * @param RPCopyRequestParams copyToFailoverTo - Volume info for the CG to perform a failover test to. Also contains bookmark and APIT
 *            info. If no bookmark or APIT specified, failover test to most recent image.
 *
 * @return void
 *
 * @throws RecoverPointException
 */
public void failoverCopyTest(RPCopyRequestParams copyToFailoverTo) throws RecoverPointException {
    // Check the params
    // If bookmark != null, enable the bookmark on the copy, and failover to that copy
    // If APITTime != null, enable the specified APIT on the copy, and failover to that copy
    // If both are null, enable the most recent imagem, and failover to that copy
    String bookmarkName = copyToFailoverTo.getBookmarkName();
    Date apitTime = copyToFailoverTo.getApitTime();
    if (bookmarkName != null) {
        logger.info("Failver copy to bookmark : " + bookmarkName);
    } else if (apitTime != null) {
        logger.info("Failover copy to APIT : " + apitTime.toString());
    } else {
        logger.info("Failover copy to most recent image");
    }
    RecoverPointImageManagementUtils imageManager = new RecoverPointImageManagementUtils();
    imageManager.enableCopyImage(functionalAPI, copyToFailoverTo, false);
    // RecoverPointUtils.mapRPVolumeProtectionInfoToCGCopyUID(copyToFailoverTo.getCopyVolumeInfo());
    RecoverPointVolumeProtectionInfo failoverCopyInfo = copyToFailoverTo.getCopyVolumeInfo();
    pauseTransfer(failoverCopyInfo);
}
Also used : RecoverPointVolumeProtectionInfo(com.emc.storageos.recoverpoint.responses.RecoverPointVolumeProtectionInfo) Date(java.util.Date) RecoverPointImageManagementUtils(com.emc.storageos.recoverpoint.utils.RecoverPointImageManagementUtils)

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