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;
}
}
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;
}
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()));
}
}
}
}
}
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);
}
}
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);
}
Aggregations