use of com.emc.storageos.recoverpoint.requests.RPCopyRequestParams 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.requests.RPCopyRequestParams 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.requests.RPCopyRequestParams in project coprhd-controller by CoprHD.
the class RecoverPointClientIntegrationTest method testFailoverTestAndTestCancel.
// @Test
public void testFailoverTestAndTestCancel() {
logger.info("Testing RecoverPoint Failover Cancel For Volume");
RecoverPointVolumeProtectionInfo protectionInfo = null;
boolean foundError = false;
try {
recreateCGAndBookmark();
protectionInfo = rpClient.getProtectionInfoForVolume(BourneRPTestCRRLUN1WWN);
} catch (RecoverPointException e) {
foundError = true;
fail(e.getMessage());
}
if (protectionInfo == null) {
foundError = true;
fail("Failed to find protection info for WWN: " + BourneRPTestCRRLUN1WWN);
}
if (!foundError) {
// Verify this is a source
if (protectionInfo.getRpVolumeCurrentProtectionStatus() == RecoverPointVolumeProtectionInfo.volumeProtectionStatus.PROTECTED_TARGET) {
logger.info("Protected target volume " + BourneRPTestCRRLUN1WWN + " is on CG Name: " + protectionInfo.getRpProtectionName());
} else {
foundError = true;
fail("Volume " + BourneRPTestCRRLUN1WWN + " did not map to a protected source target");
}
}
RPCopyRequestParams failoverTestRequest = new RPCopyRequestParams();
failoverTestRequest.setCopyVolumeInfo(protectionInfo);
try {
try {
logger.info("Delete the CDP copy");
RecoverPointVolumeProtectionInfo deleteCopyInfo = null;
deleteCopyInfo = rpClient.getProtectionInfoForVolume(BourneRPTestCDPLUN1WWN);
rpClient.deleteCopy(deleteCopyInfo);
} catch (Exception e) {
logger.info("Ignore error deleting CDP copy");
}
logger.info("Failover test start");
rpClient.failoverCopyTest(failoverTestRequest);
logger.info("Sleep 15 seconds before cancel of failover test");
Thread.sleep(15000);
logger.info("Failover test cancel start");
rpClient.failoverCopyTestCancel(failoverTestRequest);
} catch (RecoverPointException e) {
foundError = true;
fail(e.getMessage());
} catch (InterruptedException e) {
foundError = true;
fail(e.getMessage());
}
if (!foundError) {
logger.info("TestFailoverTestAndTestCancel PASSED");
}
}
use of com.emc.storageos.recoverpoint.requests.RPCopyRequestParams in project coprhd-controller by CoprHD.
the class RecoverPointClientIntegrationTest method testFailoverTestAndFailoverAndFailback.
// @Test
public void testFailoverTestAndFailoverAndFailback() {
logger.info("Testing RecoverPoint Failover Cancel For Volume");
RecoverPointVolumeProtectionInfo protectionInfo = null;
RecoverPointVolumeProtectionInfo failbackProtectionInfo = null;
boolean foundError = false;
try {
recreateCGAndBookmark();
protectionInfo = rpClient.getProtectionInfoForVolume(BourneRPTestCRRLUN1WWN);
failbackProtectionInfo = rpClient.getProtectionInfoForVolume(BourneRPTestProdLUN1WWN);
} catch (RecoverPointException e) {
foundError = true;
fail(e.getMessage());
}
if (protectionInfo == null) {
foundError = true;
fail("Failed to find protection info for WWN: " + BourneRPTestCRRLUN1WWN);
}
if (failbackProtectionInfo == null) {
foundError = true;
fail("Failed to find protection info for WWN: " + BourneRPTestProdLUN1WWN);
}
if (!foundError) {
// Verify this is a target
if (protectionInfo.getRpVolumeCurrentProtectionStatus() == RecoverPointVolumeProtectionInfo.volumeProtectionStatus.PROTECTED_TARGET) {
logger.info("Protected target volume " + BourneRPTestCRRLUN1WWN + " is on CG Name: " + protectionInfo.getRpProtectionName());
} else {
foundError = true;
fail("Volume " + BourneRPTestCRRLUN1WWN + " did not map to a protected source target");
}
}
RPCopyRequestParams failoverTestRequest = new RPCopyRequestParams();
RPCopyRequestParams failbackRequest = new RPCopyRequestParams();
failoverTestRequest.setCopyVolumeInfo(protectionInfo);
failbackRequest.setCopyVolumeInfo(failbackProtectionInfo);
try {
try {
logger.info("Delete the CDP copy");
RecoverPointVolumeProtectionInfo deleteCopyInfo = null;
deleteCopyInfo = rpClient.getProtectionInfoForVolume(BourneRPTestCDPLUN1WWN);
rpClient.deleteCopy(deleteCopyInfo);
} catch (Exception e) {
logger.info("Ignore error deleting CDP copy");
}
logger.info("Failover test start");
rpClient.failoverCopyTest(failoverTestRequest);
logger.info("Sleep 15 seconds before complete of failover");
Thread.sleep(15000);
rpClient.failoverCopy(failoverTestRequest);
logger.info("Sleep 15 seconds before failback");
Thread.sleep(15000);
rpClient.failoverCopy(failbackRequest);
} catch (RecoverPointException e) {
foundError = true;
fail(e.getMessage());
} catch (InterruptedException e) {
foundError = true;
fail(e.getMessage());
}
if (!foundError) {
logger.info("TestFailoverTestAndFailoverAndFailback PASSED");
}
}
use of com.emc.storageos.recoverpoint.requests.RPCopyRequestParams in project coprhd-controller by CoprHD.
the class RecoverPointClientIntegrationTest method testFailover.
// @Test
public void testFailover() {
logger.info("Testing RecoverPoint Failover For Volume");
RecoverPointVolumeProtectionInfo protectionInfo = null;
RecoverPointVolumeProtectionInfo failbackProtectionInfo = null;
boolean foundError = false;
try {
recreateCGAndBookmark();
protectionInfo = rpClient.getProtectionInfoForVolume(BourneRPTestCRRLUN1WWN);
failbackProtectionInfo = rpClient.getProtectionInfoForVolume(BourneRPTestProdLUN1WWN);
} catch (RecoverPointException e) {
foundError = true;
fail(e.getMessage());
}
if (protectionInfo == null) {
foundError = true;
fail("Failed to find protection info for WWN: " + BourneRPTestCRRLUN1WWN);
}
if (failbackProtectionInfo == null) {
foundError = true;
fail("Failed to find protection info for WWN: " + BourneRPTestProdLUN1WWN);
}
if (!foundError) {
// Verify this is a source
if (protectionInfo.getRpVolumeCurrentProtectionStatus() == RecoverPointVolumeProtectionInfo.volumeProtectionStatus.PROTECTED_TARGET) {
logger.info("RecoverPoint Get Protection Info For Volume PASSED");
logger.info("Protected target volume " + BourneRPTestCRRLUN1WWN + " is on CG Name: " + protectionInfo.getRpProtectionName());
} else {
foundError = true;
fail("Volume " + BourneRPTestCRRLUN1WWN + " did not map to a protected source target");
}
}
RPCopyRequestParams failoverRequest = new RPCopyRequestParams();
RPCopyRequestParams failbackRequest = new RPCopyRequestParams();
failoverRequest.setCopyVolumeInfo(protectionInfo);
failbackRequest.setCopyVolumeInfo(failbackProtectionInfo);
try {
// try {
// logger.info("Delete the CDP copy");
// RecoverPointVolumeProtectionInfo deleteCopyInfo = null;
// deleteCopyInfo = rpClient.getProtectionInfoForVolume(BourneRPTestCDPLUN1WWN);
// rpClient.deleteCopy(deleteCopyInfo);
// } catch (Exception e) {
// logger.info("Ignore error deleting CDP copy");
// }
logger.info("Failover start");
rpClient.failoverCopy(failoverRequest);
logger.info("Sleep 15 seconds before failback");
Thread.sleep(15000);
logger.info("Failback start");
rpClient.failoverCopy(failbackRequest);
} catch (RecoverPointException e) {
foundError = true;
fail(e.getMessage());
} catch (InterruptedException e) {
foundError = true;
fail(e.getMessage());
}
if (!foundError) {
logger.info("TestFailover PASSED");
}
}
Aggregations