use of com.emc.storageos.recoverpoint.requests.CreateCopyParams 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.CreateCopyParams 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);
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>();
if (!standbyLocalCopyVols.isEmpty()) {
for (Volume standbyCopyVol : standbyLocalCopyVols) {
// 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);
}
// 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.CreateCopyParams in project coprhd-controller by CoprHD.
the class RPDeviceController method updateProtectionSet.
/**
* Update a protection set in the database that corresponds to the CG.
*
* BH Note: Currently this only supports adding to the protection set. We may eventually
* want to support removal as well.
*
* @param params
* CG params object
* @throws InternalException
*/
private ProtectionSet updateProtectionSet(ProtectionSet protectionSet, CGRequestParams params) throws InternalException {
StringSet protectionSetVolumes = new StringSet();
_log.info(String.format("Updating protection set [%s]", protectionSet.getLabel()));
// Keep a list of all volumes that were created. This will be used to ensure we do not
// consider volumes from this create request when setting access state and link status
// based on existing volumes in the CG.
List<URI> volumesInCreateRequest = new ArrayList<URI>();
for (CreateRSetParams rset : params.getRsets()) {
for (CreateVolumeParams volume : rset.getVolumes()) {
volumesInCreateRequest.add(volume.getVolumeURI());
}
}
// protection set
for (CreateRSetParams rset : params.getRsets()) {
for (CreateVolumeParams volume : rset.getVolumes()) {
if (protectionSet.getVolumes() != null && protectionSet.getVolumes().contains(volume.getVolumeURI().toString())) {
// Protection Set already has a reference to this volume, continue.
continue;
} else {
Volume vol = _dbClient.queryObject(Volume.class, volume.getVolumeURI());
// hasn't already been set.
if (protectionSet.getProject() == null) {
protectionSet.setProject(vol.getProject().getURI());
}
vol.setProtectionSet(new NamedURI(protectionSet.getId(), protectionSet.getLabel()));
if (vol.checkPersonality(Volume.PersonalityTypes.SOURCE.toString())) {
vol.setAccessState(Volume.VolumeAccessState.READWRITE.name());
vol.setLinkStatus(Volume.LinkStatus.IN_SYNC.name());
// Check the CG for an existing source volume. If the CG has an existing
// source volume, we want to mirror the access state and link status for
// all new source volumes.
List<Volume> existingCgSourceVolumes = RPHelper.getCgSourceVolumes(vol.getConsistencyGroup(), _dbClient);
if (existingCgSourceVolumes != null) {
for (Volume sourceVolume : existingCgSourceVolumes) {
if (!vol.getId().equals(sourceVolume.getId()) && !volumesInCreateRequest.contains(sourceVolume.getId())) {
_log.info(String.format("Updating source volume %s. Setting access state = %s, link status = %s. Based on existing CG source volume %s.", vol.getId(), sourceVolume.getAccessState(), sourceVolume.getLinkStatus(), sourceVolume.getId()));
vol.setAccessState(sourceVolume.getAccessState());
vol.setLinkStatus(sourceVolume.getLinkStatus());
break;
}
}
}
} else if (vol.checkPersonality(Volume.PersonalityTypes.TARGET.toString())) {
vol.setAccessState(Volume.VolumeAccessState.NOT_READY.name());
vol.setLinkStatus(Volume.LinkStatus.IN_SYNC.name());
// Check the CG for an existing target volume corresponding to the same RP copy
// as this volume and mirror its access state and link statues. If the target
// copy happens to be in direct access mode, it's important that the new volume
// be marked FAILED_OVER and READWRITE.
List<Volume> existingCgTargets = RPHelper.getTargetVolumesForVarray(_dbClient, vol.getConsistencyGroup(), vol.getVirtualArray());
if (existingCgTargets != null && vol.getRpCopyName() != null) {
for (Volume targetVolume : existingCgTargets) {
// lets use it to set the access state and link status values.
if (!vol.getId().equals(targetVolume.getId()) && !volumesInCreateRequest.contains(targetVolume.getId()) && vol.getRpCopyName().equalsIgnoreCase(targetVolume.getRpCopyName())) {
_log.info(String.format("Updating volume %s. Setting access state = %s, link status = %s. Based on existing CG target volume %s.", vol.getId(), targetVolume.getAccessState(), targetVolume.getLinkStatus(), targetVolume.getId()));
vol.setAccessState(targetVolume.getAccessState());
vol.setLinkStatus(targetVolume.getLinkStatus());
break;
}
}
}
}
_dbClient.updateObject(vol);
protectionSetVolumes.add(vol.getId().toString());
_log.info(String.format("Adding volume [%s] to protection set [%s]", vol.getLabel(), protectionSet.getLabel()));
}
}
}
// protection set
for (CreateCopyParams copy : params.getCopies()) {
for (CreateVolumeParams volume : copy.getJournals()) {
if (protectionSet.getVolumes() != null && protectionSet.getVolumes().contains(volume.getVolumeURI().toString())) {
// Protection Set already has a reference to this volume, continue.
continue;
} else {
Volume vol = _dbClient.queryObject(Volume.class, volume.getVolumeURI());
vol.setProtectionSet(new NamedURI(protectionSet.getId(), protectionSet.getLabel()));
vol.setAccessState(Volume.VolumeAccessState.NOT_READY.name());
_dbClient.updateObject(vol);
protectionSetVolumes.add(vol.getId().toString());
_log.info(String.format("Adding volume [%s] to protection set [%s]", vol.getLabel(), protectionSet.getLabel()));
}
}
}
if (protectionSet.getVolumes() == null) {
protectionSet.setVolumes(protectionSetVolumes);
} else {
protectionSet.getVolumes().addAll(protectionSetVolumes);
}
_dbClient.updateObject(protectionSet);
return protectionSet;
}
use of com.emc.storageos.recoverpoint.requests.CreateCopyParams in project coprhd-controller by CoprHD.
the class RPDeviceController method updateCGParams.
/**
* Update the params objects with the proper WWN information so the CG can be created.
*
* @param params
* cg params
* @throws InternalException
*/
private void updateCGParams(CGRequestParams params) throws InternalException {
for (CreateCopyParams copy : params.getCopies()) {
_log.info("View copy: " + copy.getName());
// Fill the map with varray
for (CreateVolumeParams volume : copy.getJournals()) {
Volume dbVolume = _dbClient.queryObject(Volume.class, volume.getVolumeURI());
volume.setNativeGuid(dbVolume.getNativeGuid());
volume.setWwn(RPHelper.getRPWWn(dbVolume.getId(), _dbClient));
}
}
for (CreateRSetParams rset : params.getRsets()) {
_log.info("View rset: " + rset.getName());
for (CreateVolumeParams volume : rset.getVolumes()) {
Volume dbVolume = _dbClient.queryObject(Volume.class, volume.getVolumeURI());
volume.setNativeGuid(dbVolume.getNativeGuid());
volume.setWwn(RPHelper.getRPWWn(dbVolume.getId(), _dbClient));
}
}
}
use of com.emc.storageos.recoverpoint.requests.CreateCopyParams in project coprhd-controller by CoprHD.
the class RecoverPointClient method addStandbyProductionCopy.
/**
* In a metropoint environment, adds the standby production and CDP copies to the CG after failover
* and set as production back to the original vplex metro
*
* @param standbyProdCopy has info about the standby production copy to be added
* @param standbyLocalCopyParams local standby copies
* @param rSet contains volume info for standby local copies
* @param activeProdCopy has info about the active production copy
*/
public void addStandbyProductionCopy(CreateCopyParams standbyProdCopy, CreateCopyParams standbyLocalCopyParams, List<CreateRSetParams> rSets, RPCopyRequestParams activeProdCopy) {
String cgName = "";
String activeCgCopyName = "";
ConsistencyGroupCopyUID standbyLocalCopyUID = null;
try {
ConsistencyGroupCopyUID activeProdCopyUID = RecoverPointUtils.mapRPVolumeProtectionInfoToCGCopyUID(activeProdCopy.getCopyVolumeInfo());
ConsistencyGroupUID cgUID = activeProdCopyUID.getGroupUID();
cgName = functionalAPI.getGroupName(cgUID);
logger.info(String.format("Adding Standby production and local volumes to Metropoint CG %s", cgName));
activeCgCopyName = functionalAPI.getGroupCopyName(activeProdCopyUID);
List<CreateCopyParams> copies = new ArrayList<CreateCopyParams>();
copies.add(standbyProdCopy);
if (standbyLocalCopyParams != null) {
copies.add(standbyLocalCopyParams);
}
Set<RPSite> allSites = scan(copies, rSets);
CreateVolumeParams volume = standbyProdCopy.getJournals().get(0);
ClusterUID clusterUid = RecoverPointUtils.getRPSiteID(functionalAPI, volume.getInternalSiteName());
// fetch the ConsistencyGroupCopyUID for standby production copy
ConsistencyGroupCopyUID standbyProdCopyUID = createCgCopyUid(cgUID, clusterUid, RecoverPointCGCopyType.PRODUCTION);
// fetch the link Settings between to be added standby prod copy and the remote copy
List<ConsistencyGroupLinkSettings> standbyProductionlinkSettings = new ArrayList<ConsistencyGroupLinkSettings>();
standbyProductionlinkSettings = getStandbyCopyLinkSettings(activeProdCopyUID, standbyProdCopyUID);
// add the standby production copy
addCopyToCG(cgUID, allSites, standbyProdCopy, null, RecoverPointCGCopyType.PRODUCTION, standbyProductionlinkSettings, standbyProdCopyUID);
// add the standby local copies if we have any
if (standbyLocalCopyParams != null) {
// fetch the ConsistencyGroupCopyUID for standby local Copy
standbyLocalCopyUID = createCgCopyUid(cgUID, clusterUid, RecoverPointCGCopyType.LOCAL);
// fetch the link Settings between to be added standby local copy and the standby Production copy
List<ConsistencyGroupLinkSettings> standbyLocallinkSettings = new ArrayList<ConsistencyGroupLinkSettings>();
standbyLocallinkSettings = getStandbyCopyLinkSettings(standbyProdCopyUID, standbyLocalCopyUID);
addCopyToCG(cgUID, allSites, standbyLocalCopyParams, rSets, RecoverPointCGCopyType.LOCAL, standbyLocallinkSettings, standbyLocalCopyUID);
logger.info("Setting link policy between production copy and local copy on standby cluster(id) : " + standbyLocalCopyUID.getGlobalCopyUID().getClusterUID().getId());
setLinkPolicy(false, standbyProdCopyUID, standbyLocalCopyUID, cgUID);
}
// enable the local copy
if (standbyLocalCopyUID != null) {
logger.info("enable standby local copy for CG ", cgName);
functionalAPI.enableConsistencyGroupCopy(standbyLocalCopyUID, true);
}
// enable the production copy
logger.info("enable production standby copy for CG ", cgName);
functionalAPI.enableConsistencyGroupCopy(standbyProdCopyUID, true);
// enable the CG
logger.info("enable CG " + cgName + " after standby copies added");
functionalAPI.startGroupTransfer(cgUID);
RecoverPointImageManagementUtils rpiMgmt = new RecoverPointImageManagementUtils();
rpiMgmt.waitForCGLinkState(functionalAPI, cgUID, RecoverPointImageManagementUtils.getPipeActiveState(functionalAPI, cgUID));
} catch (Exception e) {
throw RecoverPointException.exceptions.failedToFailoverCopy(activeCgCopyName, cgName, e);
}
}
Aggregations