use of com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor in project coprhd-controller by CoprHD.
the class RPDeviceController method addPreVolumeExpandSteps.
/**
* RP specific workflow steps required prior to expanding the underlying volume are added here.
* Ex. RP CG remove replication sets.
*
* @param workflow
* @param volURI
* @param expandVolURIs
* @param taskId
* @return
* @throws WorkflowException
*/
public String addPreVolumeExpandSteps(Workflow workflow, List<VolumeDescriptor> volumeDescriptors, String taskId) throws WorkflowException {
// Just grab a legit target volume that already has an assigned protection controller.
// This will work for all operations, adding, removing, vpool change, etc.
List<VolumeDescriptor> protectionControllerDescriptors = VolumeDescriptor.filterByType(volumeDescriptors, new VolumeDescriptor.Type[] { VolumeDescriptor.Type.RP_TARGET, VolumeDescriptor.Type.RP_VPLEX_VIRT_TARGET }, new VolumeDescriptor.Type[] {});
// If there are no RP volumes, just return
if (protectionControllerDescriptors.isEmpty()) {
return null;
}
// Grab any volume from the list so we can grab the protection system, which will be the same for all volumes.
Volume volume = _dbClient.queryObject(Volume.class, protectionControllerDescriptors.get(0).getVolumeURI());
ProtectionSystem rpSystem = _dbClient.queryObject(ProtectionSystem.class, volume.getProtectionController());
// Get only the RP volumes from the descriptors.
List<VolumeDescriptor> volumeDescriptorsTypeFilter = VolumeDescriptor.filterByType(volumeDescriptors, new VolumeDescriptor.Type[] { VolumeDescriptor.Type.RP_SOURCE, VolumeDescriptor.Type.RP_EXISTING_SOURCE, VolumeDescriptor.Type.RP_VPLEX_VIRT_SOURCE }, new VolumeDescriptor.Type[] {});
// If there are no RP volumes, just return
if (volumeDescriptorsTypeFilter.isEmpty()) {
return null;
}
for (VolumeDescriptor descriptor : volumeDescriptorsTypeFilter) {
URI volURI = descriptor.getVolumeURI();
ProtectionSystem rp = _dbClient.queryObject(ProtectionSystem.class, volume.getProtectionController());
Map<String, RecreateReplicationSetRequestParams> rsetParams = new HashMap<String, RecreateReplicationSetRequestParams>();
RecreateReplicationSetRequestParams rsetParam = getReplicationSettings(rpSystem, volURI);
rsetParams.put(RPHelper.getRPWWn(volURI, _dbClient), rsetParam);
String stepId = workflow.createStepId();
Workflow.Method deleteRsetExecuteMethod = new Workflow.Method(METHOD_DELETE_RSET_STEP, rpSystem.getId(), Arrays.asList(volURI));
Workflow.Method deleteRsetRollbackeMethod = new Workflow.Method(METHOD_DELETE_RSET_ROLLBACK_STEP, rpSystem.getId(), Arrays.asList(volURI), rsetParams);
workflow.createStep(STEP_PRE_VOLUME_EXPAND, "Pre volume expand, delete replication set subtask for RP: " + volURI.toString(), null, rpSystem.getId(), rp.getSystemType(), this.getClass(), deleteRsetExecuteMethod, deleteRsetRollbackeMethod, stepId);
_log.info("addPreVolumeExpandSteps Replication Set in workflow");
}
return STEP_PRE_VOLUME_EXPAND;
}
use of com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor in project coprhd-controller by CoprHD.
the class RPDeviceController method addPostVolumeExpandSteps.
/**
* RP specific workflow steps after volume expansion are added here in this method
* RP CG replication sets that were removed during pre expand are reconstructed with the new expanded volumes.
*
* @param workflow
* @param waitFor
* @param volume
* descriptors
* @param taskId
* @return
* @throws WorkflowException
*/
public String addPostVolumeExpandSteps(Workflow workflow, String waitFor, List<VolumeDescriptor> volumeDescriptors, String taskId) throws WorkflowException {
// Get only the RP volumes from the descriptors.
List<VolumeDescriptor> volumeDescriptorsTypeFilter = VolumeDescriptor.filterByType(volumeDescriptors, new VolumeDescriptor.Type[] { VolumeDescriptor.Type.RP_SOURCE, VolumeDescriptor.Type.RP_EXISTING_SOURCE, VolumeDescriptor.Type.RP_VPLEX_VIRT_SOURCE }, new VolumeDescriptor.Type[] {});
// If there are no RP volumes, just return
if (volumeDescriptorsTypeFilter.isEmpty()) {
return waitFor;
}
for (VolumeDescriptor descriptor : volumeDescriptorsTypeFilter) {
Volume volume = _dbClient.queryObject(Volume.class, descriptor.getVolumeURI());
ProtectionSystem rpSystem = _dbClient.queryObject(ProtectionSystem.class, volume.getProtectionController());
Map<String, RecreateReplicationSetRequestParams> rsetParams = new HashMap<String, RecreateReplicationSetRequestParams>();
RecreateReplicationSetRequestParams rsetParam = getReplicationSettings(rpSystem, volume.getId());
rsetParams.put(RPHelper.getRPWWn(volume.getId(), _dbClient), rsetParam);
String stepId = workflow.createStepId();
Workflow.Method recreateRSetExecuteMethod = new Workflow.Method(METHOD_RECREATE_RSET_STEP, rpSystem.getId(), Arrays.asList(volume.getId()), rsetParams);
workflow.createStep(STEP_POST_VOLUME_EXPAND, "Post volume Expand, Recreate replication set subtask for RP: " + volume.toString(), waitFor, rpSystem.getId(), rpSystem.getSystemType(), this.getClass(), recreateRSetExecuteMethod, null, stepId);
_log.info("Recreate Replication Set in workflow");
}
return STEP_POST_VOLUME_EXPAND;
}
use of com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor in project coprhd-controller by CoprHD.
the class RPDeviceController method validateCGVolumes.
/**
* Validates the source and target volumes to ensure the provisioned
* sizes are all the same.
*
* @param volumeDescriptors
* the volumes to validate
*/
private void validateCGVolumes(List<VolumeDescriptor> volumeDescriptors) {
// then CG creation or fail-over will fail.
for (VolumeDescriptor volumeDescriptor : volumeDescriptors) {
if (volumeDescriptor.getType().equals(VolumeDescriptor.Type.RP_SOURCE) || volumeDescriptor.getType().equals(VolumeDescriptor.Type.RP_EXISTING_SOURCE) || volumeDescriptor.getType().equals(VolumeDescriptor.Type.RP_VPLEX_VIRT_SOURCE)) {
// Find the Source volume from the descriptor
Volume sourceVolume = _dbClient.queryObject(Volume.class, volumeDescriptor.getVolumeURI());
StorageSystem sourceStorageSystem = _dbClient.queryObject(StorageSystem.class, sourceVolume.getStorageController());
// Check all Target volumes of the Source to ensure that Source capacity < Target capacity.
for (String targetId : sourceVolume.getRpTargets()) {
Volume targetVolume = _dbClient.queryObject(Volume.class, URI.create(targetId));
StorageSystem targetStorageSystem = _dbClient.queryObject(StorageSystem.class, targetVolume.getStorageController());
// target must be equal to or larger than the source
if (Long.compare(targetVolume.getProvisionedCapacity(), sourceVolume.getProvisionedCapacity()) < 0) {
_log.error(String.format("Source volume [%s - %s] has provisioned capacity of [%s] and Target volume [%s - %s] has provisioned capacity of [%s]. " + "Source capacity cannot be > Target capacity.", sourceVolume.getLabel(), sourceVolume.getId(), sourceVolume.getProvisionedCapacity(), targetVolume.getLabel(), targetVolume.getId(), targetVolume.getProvisionedCapacity()));
throw DeviceControllerExceptions.recoverpoint.cgCannotBeCreatedInvalidVolumeSizes(sourceStorageSystem.getSystemType(), String.valueOf(sourceVolume.getProvisionedCapacity()), targetStorageSystem.getSystemType(), String.valueOf(targetVolume.getProvisionedCapacity()));
}
}
}
}
}
use of com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor 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.blockorchestrationcontroller.VolumeDescriptor in project coprhd-controller by CoprHD.
the class RPDeviceController method cgCreateRollbackStep.
/**
* Workflow step method for cg create rollback
*
* @param rpSystem
* RP system
* @param params
* parameters needed to create the CG
* @param token
* the task
* @return
* @throws WorkflowException
*/
public boolean cgCreateRollbackStep(URI rpSystemId, List<VolumeDescriptor> volumeDescriptors, String token) throws WorkflowException {
_log.info("Start cg create rollback step");
WorkflowStepCompleter.stepExecuting(token);
// Get only the RP source volumes from the descriptors.
List<VolumeDescriptor> sourceVolumeDescriptors = VolumeDescriptor.filterByType(volumeDescriptors, new VolumeDescriptor.Type[] { VolumeDescriptor.Type.RP_SOURCE, VolumeDescriptor.Type.RP_EXISTING_SOURCE, VolumeDescriptor.Type.RP_VPLEX_VIRT_SOURCE }, new VolumeDescriptor.Type[] {});
// Get all journal volumes
List<VolumeDescriptor> journalVolumeDescriptors = VolumeDescriptor.filterByType(volumeDescriptors, new VolumeDescriptor.Type[] { VolumeDescriptor.Type.RP_JOURNAL, VolumeDescriptor.Type.RP_VPLEX_VIRT_JOURNAL }, new VolumeDescriptor.Type[] {});
if (sourceVolumeDescriptors == null || sourceVolumeDescriptors.isEmpty()) {
WorkflowStepCompleter.stepSucceded(token);
return true;
}
List<URI> volumeIDs = new ArrayList<URI>();
for (VolumeDescriptor descriptor : sourceVolumeDescriptors) {
volumeIDs.add(descriptor.getVolumeURI());
}
List<URI> journalVolumeIDs = new ArrayList<URI>();
for (VolumeDescriptor journalDescriptor : journalVolumeDescriptors) {
journalVolumeIDs.add(journalDescriptor.getVolumeURI());
}
return cgDeleteStep(rpSystemId, volumeIDs, journalVolumeIDs, token);
}
Aggregations