use of com.emc.storageos.db.client.model.ProtectionSystem in project coprhd-controller by CoprHD.
the class RPDeviceController method checkIfDistributedVplexOrVmaxFullCopies.
/**
* Check if the full copies source volumes are distributed vplex volumes or VMAX volume
*
* @param fullcopies
* - URI of full copies
* @return - the source volumes that are vmax or vplex distributed volumes
*/
private List<Volume> checkIfDistributedVplexOrVmaxFullCopies(List<URI> fullcopies) {
List<Volume> sourceVolumes = new ArrayList<Volume>();
for (URI fullCopyUri : fullcopies) {
Volume fullCopy = _dbClient.queryObject(Volume.class, fullCopyUri);
if (fullCopy != null) {
boolean toadd = false;
URI volume = fullCopy.getAssociatedSourceVolume();
Volume sourceVol = _dbClient.queryObject(Volume.class, volume);
if (sourceVol != null) {
if (!sourceVol.checkForRp()) {
toadd = false;
} else if (sourceVol.getAssociatedVolumes() != null && sourceVol.getAssociatedVolumes().size() == 2) {
// RP + VPLEX distributed
toadd = true;
} else {
// RP + VMAX
URI storage = sourceVol.getStorageController();
if (!NullColumnValueGetter.isNullURI(storage)) {
StorageSystem storageSystem = _dbClient.queryObject(StorageSystem.class, storage);
if (storageSystem != null && storageSystem.getSystemType().equals(SystemType.vmax.name())) {
toadd = true;
}
} else {
_log.error(String.format("The source %s storage system is null", sourceVol.getLabel()));
}
}
}
// volume is a distributed vplex or vmax volume
if (!NullColumnValueGetter.isNullURI(sourceVol.getProtectionController()) && toadd) {
ProtectionSystem rpSystem = _dbClient.queryObject(ProtectionSystem.class, sourceVol.getProtectionController());
if (rpSystem == null) {
// Verify non-null storage device returned from the database client.
throw DeviceControllerExceptions.recoverpoint.failedConnectingForMonitoring(sourceVol.getProtectionController());
}
sourceVolumes.add(sourceVol);
}
}
}
return sourceVolumes;
}
use of com.emc.storageos.db.client.model.ProtectionSystem in project coprhd-controller by CoprHD.
the class RPDeviceController method addPostRestoreFromFullcopySteps.
/**
* Adds the necessary RecoverPoint controller steps that need to be executed after
* restoring a volume from full copy. The post-restore step is required if we
* are restoring a VPLEX full copy, whoes source volume is a distributed VPLEX volume
* or a VMAX volume
*
* @param workflow
* the Workflow being constructed
* @param waitFor
* the step that the newly created steps will wait for.
* @param storageSystemURI
* the URI of storage controller
* @param fullCopies
* the URI of full copies to restore
* @param taskId
* the top level operation's taskId
* @return A waitFor key that can be used by subsequent controllers to wait on
*/
public String addPostRestoreFromFullcopySteps(Workflow workflow, String waitFor, URI storageSystemURI, List<URI> fullCopies, String taskId) {
if (fullCopies != null && !fullCopies.isEmpty()) {
List<Volume> sourceVolumes = checkIfDistributedVplexOrVmaxFullCopies(fullCopies);
if (!sourceVolumes.isEmpty()) {
Map<String, RecreateReplicationSetRequestParams> rsetParams = new HashMap<String, RecreateReplicationSetRequestParams>();
List<URI> volumeURIs = new ArrayList<URI>();
URI rpSystemId = sourceVolumes.get(0).getProtectionController();
ProtectionSystem rpSystem = _dbClient.queryObject(ProtectionSystem.class, rpSystemId);
for (Volume vol : sourceVolumes) {
RecreateReplicationSetRequestParams rsetParam = getReplicationSettings(rpSystem, vol.getId());
rsetParams.put(RPHelper.getRPWWn(vol.getId(), _dbClient), rsetParam);
volumeURIs.add(vol.getId());
}
String stepId = workflow.createStepId();
Workflow.Method recreateRSetExecuteMethod = new Workflow.Method(METHOD_RECREATE_RSET_STEP, rpSystemId, volumeURIs, rsetParams);
waitFor = workflow.createStep(STEP_PRE_VOLUME_RESTORE, "Post volume restore from full copy, add replication set step for RP", waitFor, rpSystemId, rpSystem.getSystemType(), this.getClass(), recreateRSetExecuteMethod, rollbackMethodNullMethod(), stepId);
_log.info("Created workflow step to recreate replication set for volumes");
}
}
return waitFor;
}
use of com.emc.storageos.db.client.model.ProtectionSystem in project coprhd-controller by CoprHD.
the class RPDeviceController method addRemoveProtectionOnVolumeStep.
/**
* Step to remove protection on RP Source volumes
*
* @param workflow
* The current WF
* @param waitFor
* The previous waitFor step ID or Group
* @param volumeDescriptors
* RP Source volume descriptors
* @param taskId
* The Task ID
* @param blockDeviceController
* Reference to a BlockDeviceController, used for specific steps on
* the volumes not covered by RP but required for the operation to be complete.
* @return The next waitFor step ID or Group
*/
private String addRemoveProtectionOnVolumeStep(Workflow workflow, String waitFor, List<VolumeDescriptor> volumeDescriptors, String taskId, BlockDeviceController blockDeviceController) {
List<URI> volumeURIs = new ArrayList<URI>();
URI newVpoolURI = null;
// Filter to get only the RP Source volumes.
List<VolumeDescriptor> rpSourceDescriptors = VolumeDescriptor.filterByType(volumeDescriptors, new VolumeDescriptor.Type[] { VolumeDescriptor.Type.RP_SOURCE, VolumeDescriptor.Type.RP_VPLEX_VIRT_SOURCE }, new VolumeDescriptor.Type[] {});
for (VolumeDescriptor descriptor : rpSourceDescriptors) {
if (descriptor.getParameters().get(VolumeDescriptor.PARAM_DO_NOT_DELETE_VOLUME) != null) {
// This is a rollback protection operation. We do not want to delete the volume but we do
// want to remove protection from it.
newVpoolURI = (URI) descriptor.getParameters().get(VolumeDescriptor.PARAM_VPOOL_CHANGE_NEW_VPOOL_ID);
_log.info(String.format("Adding step to remove protection from Volume (%s) and move it to vpool (%s)", descriptor.getVolumeURI(), newVpoolURI));
volumeURIs.add(descriptor.getVolumeURI());
}
}
if (volumeURIs.isEmpty()) {
return waitFor;
}
// Filter to get only the Block Data volumes
List<VolumeDescriptor> blockDataDescriptors = VolumeDescriptor.filterByType(volumeDescriptors, new VolumeDescriptor.Type[] { VolumeDescriptor.Type.BLOCK_DATA }, new VolumeDescriptor.Type[] {});
// Check to see if there are any BLOCK_DATA volumes flagged to not be fully deleted.
// These volumes could potentially need to have some untag operation performed
// on the underlying array even though they won't be deleted.
List<VolumeDescriptor> doNotDeleteDescriptors = VolumeDescriptor.getDoNotDeleteDescriptors(blockDataDescriptors);
// Breakup the descriptors further into RP and RP+VPLEX descriptors
List<VolumeDescriptor> rpDescriptors = new ArrayList<VolumeDescriptor>();
List<VolumeDescriptor> rpVPlexDescriptors = new ArrayList<VolumeDescriptor>();
for (VolumeDescriptor descr : doNotDeleteDescriptors) {
Volume volume = _dbClient.queryObject(Volume.class, descr.getVolumeURI());
// Check to see if this volume is associated to a RP+VPLEX Source volume.
if (RPHelper.isAssociatedToRpVplexType(volume, _dbClient, PersonalityTypes.SOURCE)) {
rpVPlexDescriptors.add(descr);
} else {
rpDescriptors.add(descr);
}
}
if (doNotDeleteDescriptors != null && !doNotDeleteDescriptors.isEmpty()) {
// Call the BlockDeviceController to perform untag operations on the volumes.
// NOTE: Only needed for RP volumes.
waitFor = blockDeviceController.addStepsForUntagVolumes(workflow, waitFor, rpDescriptors, taskId);
// Call the BlockDeviceController to remove the volumes from any backend array CGs.
// NOTE: Only needed for RP+VPLEX/MP volumes.
waitFor = blockDeviceController.addStepsForUpdateConsistencyGroup(workflow, waitFor, null, rpVPlexDescriptors);
}
// Grab any volume from the list so we can grab the protection system. This
// request could be over multiple protection systems but we don't really
// care at this point. We just need this reference to pass into the
// WorkFlow.
Volume volume = _dbClient.queryObject(Volume.class, volumeURIs.get(0));
ProtectionSystem rpSystem = _dbClient.queryObject(ProtectionSystem.class, volume.getProtectionController());
String stepId = workflow.createStepId();
Workflow.Method removeProtectionExecuteMethod = new Workflow.Method(METHOD_REMOVE_PROTECTION_STEP, volumeURIs, newVpoolURI);
workflow.createStep(STEP_REMOVE_PROTECTION, "Remove RP protection on volume(s)", waitFor, rpSystem.getId(), rpSystem.getSystemType(), this.getClass(), removeProtectionExecuteMethod, null, stepId);
return STEP_REMOVE_PROTECTION;
}
use of com.emc.storageos.db.client.model.ProtectionSystem in project coprhd-controller by CoprHD.
the class RPDeviceController method updateApplication.
/*
* (non-Javadoc)
*
* @see com.emc.storageos.protectioncontroller.RPController#updateApplication(java.net.URI,
* com.emc.storageos.volumecontroller.ApplicationAddVolumeList, java.util.List, java.net.URI, java.lang.String)
*/
@Override
public void updateApplication(URI systemURI, ApplicationAddVolumeList addVolList, List<URI> removeVolumeURIs, URI applicationId, String taskId) {
// get all source and target devices
// for remove volumes source and targets can be processed in the same step
// for add volumes, split up volumes into source and target
// assign a different replication group name for target volumes so they don't end up in the same group as source
// volumes
// create one step for remove volumes and add source volumes and a separate step for add target volumes
TaskCompleter completer = null;
try {
Set<URI> impactedCGs = new HashSet<URI>();
List<URI> allRemoveVolumes = new ArrayList<URI>();
Set<URI> removeVolumeSet = new HashSet<URI>();
if (removeVolumeURIs != null && !removeVolumeURIs.isEmpty()) {
// get source and target volumes to be removed from the application
removeVolumeSet = RPHelper.getReplicationSetVolumes(removeVolumeURIs, _dbClient);
for (URI removeUri : removeVolumeSet) {
Volume removeVol = _dbClient.queryObject(Volume.class, removeUri);
URI cguri = removeVol.getConsistencyGroup();
impactedCGs.add(cguri);
addBackendVolumes(removeVol, false, allRemoveVolumes, null);
}
}
Set<URI> vplexVolumes = new HashSet<URI>();
Set<URI> addVolumeSet = new HashSet<URI>();
ApplicationAddVolumeList addSourceVols = new ApplicationAddVolumeList();
ApplicationAddVolumeList addTargetVols = new ApplicationAddVolumeList();
boolean existingSnapOrClone = false;
URI protectionSystemId = null;
ProtectionSystem protectionSystem = null;
Set<String> volumeWWNs = new HashSet<String>();
Volume aSrcVolume = null;
if (addVolList != null && addVolList.getVolumes() != null && !addVolList.getVolumes().isEmpty()) {
URI addVolCg = null;
// get source and target volumes to be added the application
addVolumeSet = RPHelper.getReplicationSetVolumes(addVolList.getVolumes(), _dbClient);
// split up add volumes list by source and target
List<URI> allAddSourceVolumes = new ArrayList<URI>();
List<URI> allAddTargetVolumes = new ArrayList<URI>();
for (URI volUri : addVolumeSet) {
Volume vol = _dbClient.queryObject(Volume.class, volUri);
if (protectionSystemId == null) {
protectionSystemId = vol.getProtectionController();
}
URI cguri = vol.getConsistencyGroup();
if (addVolCg == null && cguri != null) {
addVolCg = cguri;
}
impactedCGs.add(cguri);
if (vol.checkPersonality(Volume.PersonalityTypes.SOURCE.name())) {
addBackendVolumes(vol, true, allAddSourceVolumes, vplexVolumes);
aSrcVolume = vol;
} else if (vol.checkPersonality(Volume.PersonalityTypes.TARGET.name())) {
addBackendVolumes(vol, true, allAddTargetVolumes, vplexVolumes);
volumeWWNs.add(RPHelper.getRPWWn(vol.getId(), _dbClient));
}
}
if (protectionSystemId != null) {
protectionSystem = _dbClient.queryObject(ProtectionSystem.class, protectionSystemId);
}
addSourceVols.setConsistencyGroup(addVolCg);
addSourceVols.setReplicationGroupName(addVolList.getReplicationGroupName());
addSourceVols.setVolumes(allAddSourceVolumes);
String targetReplicationGroupName = addVolList.getReplicationGroupName() + REPLICATION_GROUP_RPTARGET_SUFFIX;
addTargetVols.setConsistencyGroup(addVolCg);
addTargetVols.setReplicationGroupName(targetReplicationGroupName);
addTargetVols.setVolumes(allAddTargetVolumes);
// if there are any target clones or snapshots, need to create a bookmark and enable image access
List<Volume> existingVols = CustomQueryUtility.queryActiveResourcesByConstraint(_dbClient, Volume.class, AlternateIdConstraint.Factory.getVolumeByReplicationGroupInstance(targetReplicationGroupName));
for (Volume existingVol : existingVols) {
if (existingVol.getFullCopies() != null && !existingVol.getFullCopies().isEmpty()) {
existingSnapOrClone = true;
break;
} else if (ControllerUtils.checkIfVolumeHasSnapshotSession(existingVol.getId(), _dbClient)) {
existingSnapOrClone = true;
break;
} else if (ControllerUtils.checkIfVolumeHasSnapshot(existingVol, _dbClient)) {
existingSnapOrClone = true;
break;
}
}
}
// Get a new workflow to execute the volume group update.
Workflow workflow = _workflowService.getNewWorkflow(this, BlockDeviceController.UPDATE_VOLUMES_FOR_APPLICATION_WS_NAME, false, taskId);
// create the completer add the steps and execute the plan.
completer = new VolumeGroupUpdateTaskCompleter(applicationId, addVolumeSet, removeVolumeSet, impactedCGs, taskId);
String waitFor = null;
if (existingSnapOrClone) {
// A temporary date/time stamp for the bookmark name
String bookmarkName = VIPR_SNAPSHOT_PREFIX + (new Random()).nextInt();
// Step 1 - Create a RP bookmark
String rpWaitFor = addCreateBookmarkStep(workflow, new ArrayList<URI>(), protectionSystem, bookmarkName, volumeWWNs, false, waitFor);
// Lock CG for the duration of the workflow so enable and disable can complete before another workflow
// tries to enable image
// access
List<String> locks = new ArrayList<String>();
String lockName = ControllerLockingUtil.getConsistencyGroupStorageKey(_dbClient, aSrcVolume.getConsistencyGroup(), protectionSystem.getId());
if (null != lockName) {
locks.add(lockName);
acquireWorkflowLockOrThrow(workflow, locks);
}
// Step 2 - Enable image access
waitFor = addEnableImageAccessForCreateReplicaStep(workflow, protectionSystem, null, new ArrayList<URI>(), bookmarkName, volumeWWNs, rpWaitFor);
}
// add steps for add source and remove vols
waitFor = _blockDeviceController.addStepsForUpdateApplication(workflow, addSourceVols, allRemoveVolumes, waitFor, taskId);
// add steps for add target vols
waitFor = _blockDeviceController.addStepsForUpdateApplication(workflow, addTargetVols, null, waitFor, taskId);
if (existingSnapOrClone) {
waitFor = addDisableImageAccessForCreateReplicaStep(workflow, protectionSystem, null, new ArrayList<URI>(), volumeWWNs, waitFor);
}
if (!vplexVolumes.isEmpty()) {
_vplexDeviceController.addStepsForImportClonesOfApplicationVolumes(workflow, waitFor, new ArrayList<URI>(vplexVolumes), taskId);
}
_log.info("Executing workflow plan {}", BlockDeviceController.UPDATE_VOLUMES_FOR_APPLICATION_WS_NAME);
String successMessage = String.format("Update application successful for %s", applicationId.toString());
workflow.executePlan(completer, successMessage);
} catch (Exception e) {
_log.error("Exception while updating the application", e);
if (completer != null) {
completer.error(_dbClient, DeviceControllerException.exceptions.failedToUpdateVolumesFromAppication(applicationId.toString(), e.getMessage()));
}
throw e;
}
}
use of com.emc.storageos.db.client.model.ProtectionSystem in project coprhd-controller by CoprHD.
the class RPDeviceController method addStepsForRestoreVolume.
@Override
public String addStepsForRestoreVolume(Workflow workflow, String waitFor, URI storage, URI pool, URI volume, URI snapshot, Boolean updateOpStatus, String syncDirection, String taskId, BlockSnapshotRestoreCompleter completer) throws InternalException {
BlockSnapshot snap = _dbClient.queryObject(BlockSnapshot.class, snapshot);
if (snap != null && NullColumnValueGetter.isNotNullValue(snap.getTechnologyType())) {
Volume vol = _dbClient.queryObject(Volume.class, volume);
if (vol != null) {
if (snap.getTechnologyType().equals(TechnologyType.RP.toString())) {
// Perform an RP controller restore operation only if restoring from an RP BlockSnapshot.
ProtectionSystem rpSystem = null;
rpSystem = _dbClient.queryObject(ProtectionSystem.class, vol.getProtectionController());
if (rpSystem == null) {
// Verify non-null storage device returned from the database client.
throw DeviceControllerExceptions.recoverpoint.failedConnectingForMonitoring(vol.getProtectionController());
}
String stepId = workflow.createStepId();
Workflow.Method restoreVolumeFromSnapshotMethod = new Workflow.Method(METHOD_RESTORE_VOLUME_STEP, rpSystem.getId(), storage, snapshot, completer);
waitFor = workflow.createStep(null, "Restore volume from RP snapshot: " + volume.toString(), waitFor, rpSystem.getId(), rpSystem.getSystemType(), this.getClass(), restoreVolumeFromSnapshotMethod, rollbackMethodNullMethod(), stepId);
_log.info(String.format("Created workflow step to restore RP volume %s from snapshot %s.", volume, snapshot));
}
}
}
return waitFor;
}
Aggregations