use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportTaskCompleter in project coprhd-controller by CoprHD.
the class VmaxMaskingOrchestrator method generateChangePortGroupDeleteMaskWorkflowstep.
/**
* Generate change port group delete old mask steps
*
* @param storageURI - Storage system URI
* @param exportGroupURI - Export group URI
* @param oldMaskURI - Old export mask URI
* @param waitFor - The previous step
* @param workflow - Workflow
* @return - The last step it generates
* @throws Exception
*/
private String generateChangePortGroupDeleteMaskWorkflowstep(URI storageURI, ExportGroup exportGroup, ExportMask oldMask, String waitFor, Workflow workflow) throws Exception {
StorageSystem storage = _dbClient.queryObject(StorageSystem.class, storageURI);
// Remove the old export mask.
String maskingStep = workflow.createStepId();
ExportTaskCompleter exportTaskCompleter = new ExportMaskDeleteCompleter(exportGroup.getId(), oldMask.getId(), maskingStep);
StringMap volMap = oldMask.getVolumes();
List<URI> volumes = null;
if (volMap != null) {
volumes = StringSetUtil.stringSetToUriList(volMap.keySet());
}
List<URI> inits = StringSetUtil.stringSetToUriList(oldMask.getInitiators());
Workflow.Method maskingExecuteMethod = new Workflow.Method("doExportGroupDelete", storageURI, exportGroup.getId(), oldMask.getId(), volumes, inits, exportTaskCompleter);
_log.info(String.format("ExportMask %s is to be deleted:", oldMask.getMaskName()));
Workflow.Method maskinkRollbackMethod = new Workflow.Method("rollbackChangePortGroupDeleteMask", storageURI, exportGroup.getId(), oldMask.getId());
maskingStep = workflow.createStep(EXPORT_GROUP_MASKING_TASK, String.format("Deleting mask %s (%s)", oldMask.getMaskName(), oldMask.getId().toString()), waitFor, storageURI, storage.getSystemType(), MaskingWorkflowEntryPoints.class, maskingExecuteMethod, maskinkRollbackMethod, maskingStep);
List<ExportMask> masks = new ArrayList<ExportMask>();
masks.add(oldMask);
String zoningStep = generateZoningDeleteWorkflow(workflow, maskingStep, exportGroup, masks);
return zoningStep;
}
use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportTaskCompleter in project coprhd-controller by CoprHD.
the class VnxMaskingOrchestrator method generateExportMaskAddInitiatorsWorkflow.
/*
* (non-Javadoc)
*
* @see
* com.emc.storageos.volumecontroller.impl.block.AbstractDefaultMaskingOrchestrator#
* generateExportMaskAddInitiatorsWorkflow(com.emc.
* storageos.workflow.Workflow, java.lang.String, com.emc.storageos.db.client.model.StorageSystem,
* com.emc.storageos.db.client.model.ExportGroup, com.emc.storageos.db.client.model.ExportMask, java.util.List,
* java.util.Set,
* java.lang.String)
*/
@Override
public String generateExportMaskAddInitiatorsWorkflow(Workflow workflow, String previousStep, StorageSystem storage, ExportGroup exportGroup, ExportMask exportMask, List<URI> initiatorURIs, Set<URI> newVolumeURIs, String token) throws Exception {
URI exportGroupURI = exportGroup.getId();
URI exportMaskURI = exportMask.getId();
URI storageURI = storage.getId();
List<URI> newTargetURIs = new ArrayList<>();
List<Initiator> initiators = null;
if (initiatorURIs != null && !initiatorURIs.isEmpty()) {
initiators = _dbClient.queryObject(Initiator.class, initiatorURIs);
}
// Allocate any new ports that are required for the initiators
// and update the zoning map in the exportMask.
Collection<URI> volumeURIs = (exportMask.getVolumes() == null) ? newVolumeURIs : (Collection<URI>) (Collections2.transform(exportMask.getVolumes().keySet(), CommonTransformerFunctions.FCTN_STRING_TO_URI));
ExportPathParams pathParams = _blockScheduler.calculateExportPathParamForVolumes(volumeURIs, exportGroup.getNumPaths(), storage.getId(), exportGroup.getId());
if (exportGroup.getType() != null) {
pathParams.setExportGroupType(exportGroup.getType());
}
Map<URI, List<URI>> assignments = _blockScheduler.assignStoragePorts(storage, exportGroup, initiators, exportMask.getZoningMap(), pathParams, volumeURIs, _networkDeviceController, exportGroup.getVirtualArray(), token);
newTargetURIs = BlockStorageScheduler.getTargetURIsFromAssignments(assignments);
exportMask.addZoningMap(BlockStorageScheduler.getZoneMapFromAssignments(assignments));
_dbClient.updateObject(exportMask);
String maskingStep = workflow.createStepId();
ExportTaskCompleter exportTaskCompleter = new ExportMaskAddInitiatorCompleter(exportGroupURI, exportMask.getId(), initiatorURIs, newTargetURIs, maskingStep);
Workflow.Method maskingExecuteMethod = new Workflow.Method("doExportGroupAddInitiators", storageURI, exportGroupURI, exportMaskURI, new ArrayList<URI>(volumeURIs), initiatorURIs, newTargetURIs, exportTaskCompleter);
Workflow.Method rollbackMethod = new Workflow.Method("rollbackExportGroupAddInitiators", storageURI, exportGroupURI, exportMaskURI, new ArrayList<URI>(volumeURIs), initiatorURIs, maskingStep);
maskingStep = workflow.createStep(EXPORT_GROUP_MASKING_TASK, String.format("Adding initiators to mask %s (%s)", exportMask.getMaskName(), exportMask.getId().toString()), previousStep, storageURI, storage.getSystemType(), MaskingWorkflowEntryPoints.class, maskingExecuteMethod, rollbackMethod, maskingStep);
return maskingStep;
}
use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportTaskCompleter in project coprhd-controller by CoprHD.
the class VplexCinderMaskingOrchestrator method deleteOrRemoveVolumesFromExportMask.
@Override
public void deleteOrRemoveVolumesFromExportMask(URI arrayURI, URI exportGroupURI, URI exportMaskURI, List<URI> volumes, List<URI> initiatorURIs, String stepId) {
ExportTaskCompleter completer = null;
try {
completer = new ExportMaskOnlyRemoveVolumeCompleter(exportGroupURI, exportMaskURI, volumes, stepId);
WorkflowStepCompleter.stepExecuting(stepId);
StorageSystem array = _dbClient.queryObject(StorageSystem.class, arrayURI);
BlockStorageDevice device = _blockController.getDevice(array.getSystemType());
ExportMask exportMask = _dbClient.queryObject(ExportMask.class, exportMaskURI);
// If the exportMask isn't found, or has been deleted, nothing to do.
if (exportMask == null || exportMask.getInactive()) {
_log.info(String.format("ExportMask %s inactive, returning success", exportMaskURI));
completer.ready(_dbClient);
return;
}
// Protect concurrent operations by locking {host, array} dupple.
// Lock will be released when work flow step completes.
List<String> lockKeys = ControllerLockingUtil.getHostStorageLockKeys(_dbClient, ExportGroupType.Host, StringSetUtil.stringSetToUriList(exportMask.getInitiators()), arrayURI);
getWorkflowService().acquireWorkflowStepLocks(stepId, lockKeys, LockTimeoutValue.get(LockType.VPLEX_BACKEND_EXPORT));
// Refresh the ExportMask
exportMask = refreshExportMask(array, device, exportMask);
// Determine if we're deleting the last volume in the mask.
StringMap maskVolumesMap = exportMask.getVolumes();
Set<String> remainingVolumes = new HashSet<String>();
List<URI> passedVolumesInMask = new ArrayList<>(volumes);
if (maskVolumesMap != null) {
remainingVolumes.addAll(maskVolumesMap.keySet());
}
for (URI volume : volumes) {
remainingVolumes.remove(volume.toString());
// are not in the mask to handle this condition.
if ((maskVolumesMap != null) && (!maskVolumesMap.keySet().contains(volume.toString()))) {
passedVolumesInMask.remove(volume);
}
}
// None of the volumes is in the export mask, so we are done.
if (passedVolumesInMask.isEmpty()) {
_log.info("None of these volumes {} are in export mask {}", volumes, exportMask.forDisplay());
completer.ready(_dbClient);
return;
}
// If it is last volume and there are no existing volumes, delete the ExportMask.
if (remainingVolumes.isEmpty() && !exportMask.hasAnyExistingVolumes()) {
_log.debug(String.format("Calling doExportDelete on the device %s", array.getId().toString()));
device.doExportDelete(array, exportMask, null, null, completer);
} else {
_log.debug(String.format("Calling doExportRemoveVolumes on the device %s", array.getId().toString()));
List<Initiator> initiators = null;
if (initiatorURIs != null && !initiatorURIs.isEmpty()) {
initiators = _dbClient.queryObject(Initiator.class, initiatorURIs);
}
device.doExportRemoveVolumes(array, exportMask, passedVolumesInMask, initiators, completer);
}
completer.ready(_dbClient);
} catch (Exception ex) {
_log.error("Failed to delete or remove volumes to export mask for cinder: ", ex);
VPlexApiException vplexex = DeviceControllerExceptions.vplex.addStepsForDeleteVolumesFailed(ex);
completer.error(_dbClient, vplexex);
}
}
use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportTaskCompleter in project coprhd-controller by CoprHD.
the class XtremIOMaskingOrchestrator method exportGroupRemoveVolumes.
@Override
public void exportGroupRemoveVolumes(URI storageURI, URI exportGroupURI, List<URI> volumes, String token) throws Exception {
ExportTaskCompleter taskCompleter = null;
try {
log.info(String.format("exportRemoveVolume start - Array: %s ExportGroup: %s " + "Volume: %s", storageURI.toString(), exportGroupURI.toString(), Joiner.on(',').join(volumes)));
ExportGroup exportGroup = _dbClient.queryObject(ExportGroup.class, exportGroupURI);
StorageSystem storage = _dbClient.queryObject(StorageSystem.class, storageURI);
taskCompleter = new ExportOrchestrationTask(exportGroupURI, token);
List<ExportMask> exportMasks = ExportMaskUtils.getExportMasks(_dbClient, exportGroup, storageURI);
// CTRL-13080 fix - Mask really not needed, this method has to get called on every export operation once.
if (exportMasks != null && !exportMasks.isEmpty()) {
Workflow workflow = _workflowService.getNewWorkflow(MaskingWorkflowEntryPoints.getInstance(), "exportGroupRemoveVolumes", true, token);
List<ExportMask> exportMaskstoDelete = new ArrayList<ExportMask>();
List<ExportMask> exportMaskstoRemoveVolume = new ArrayList<ExportMask>();
String previousStep = null;
refreshExportMask(storage, getDevice(), exportMasks.get(0));
for (ExportMask exportMask : exportMasks) {
List<URI> maskVolumes = new ArrayList<URI>();
for (URI egVolumeID : volumes) {
BlockObject bo = Volume.fetchExportMaskBlockObject(_dbClient, egVolumeID);
if (bo != null && exportMask.hasUserCreatedVolume(bo.getId())) {
maskVolumes.add(egVolumeID);
} else {
_log.info(String.format("Export mask %s does not contain system-created volume %s, so it will not be removed from this export mask", exportMask.getId().toString(), egVolumeID.toString()));
}
}
if (!maskVolumes.isEmpty()) {
if (isRemoveAllVolumes(exportMask, volumes)) {
exportMaskstoDelete.add(exportMask);
} else {
exportMaskstoRemoveVolume.add(exportMask);
}
}
}
if (!exportMaskstoRemoveVolume.isEmpty()) {
for (ExportMask exportMask : exportMaskstoRemoveVolume) {
List<URI> initiators = StringSetUtil.stringSetToUriList(exportMask.getInitiators());
previousStep = generateExportMaskRemoveVolumesWorkflow(workflow, previousStep, storage, exportGroup, exportMask, volumes, initiators, null);
}
previousStep = generateZoningRemoveVolumesWorkflow(workflow, previousStep, exportGroup, exportMaskstoRemoveVolume, volumes);
}
if (!exportMaskstoDelete.isEmpty()) {
for (ExportMask exportMask : exportMaskstoDelete) {
List<URI> volumesInMask = ExportMaskUtils.getUserAddedVolumeURIs(exportMask);
List<URI> initiators = StringSetUtil.stringSetToUriList(exportMask.getInitiators());
previousStep = generateExportMaskDeleteWorkflow(workflow, previousStep, storage, exportGroup, exportMask, volumesInMask, initiators, null);
}
previousStep = generateZoningDeleteWorkflow(workflow, previousStep, exportGroup, exportMaskstoDelete);
}
// volumes
List<URI> initiators = StringSetUtil.stringSetToUriList(exportGroup.getInitiators());
generateExportGroupRemoveVolumesCleanup(workflow, previousStep, storage, exportGroup, volumes, initiators);
String successMessage = String.format("Volumes successfully unexported from StorageArray %s", storage.getLabel());
workflow.executePlan(taskCompleter, successMessage);
} else {
log.info("export_volume_remove: no export (initiator should be empty)");
exportGroup.removeVolumes(volumes);
_dbClient.persistObject(exportGroup);
taskCompleter.ready(_dbClient);
}
log.info(String.format("exportRemoveVolume end - Array: %s ExportGroup: %s " + "Volume: %s", storageURI.toString(), exportGroupURI.toString(), Joiner.on(',').join(volumes)));
} catch (Exception e) {
if (taskCompleter != null) {
ServiceError serviceError = DeviceControllerException.errors.jobFailedMsg(e.getMessage(), e);
taskCompleter.error(_dbClient, serviceError);
} else {
throw DeviceControllerException.exceptions.exportRemoveVolumes(e);
}
}
}
use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportTaskCompleter in project coprhd-controller by CoprHD.
the class XtremIOMaskingOrchestrator method exportGroupRemoveInitiators.
@Override
public void exportGroupRemoveInitiators(URI storageURI, URI exportGroupURI, List<URI> initiatorURIs, String token) throws Exception {
ExportTaskCompleter taskCompleter = null;
try {
log.info(String.format("exportRemoveInitiator start - Array: %s " + "ExportGroup: %s Initiator: %s", storageURI.toString(), exportGroupURI.toString(), Joiner.on(',').join(initiatorURIs)));
taskCompleter = new ExportOrchestrationTask(exportGroupURI, token);
ExportGroup exportGroup = _dbClient.queryObject(ExportGroup.class, exportGroupURI);
StorageSystem storage = _dbClient.queryObject(StorageSystem.class, storageURI);
List<ExportMask> exportMasks = ExportMaskUtils.getExportMasks(_dbClient, exportGroup, storageURI);
Map<String, List<URI>> computeResourceToInitiators = mapInitiatorsToComputeResource(exportGroup, initiatorURIs);
log.info("Host to initiators : {}", Joiner.on(",").join(computeResourceToInitiators.entrySet()));
refreshExportMask(storage, getDevice(), null);
if (exportMasks != null && !exportMasks.isEmpty()) {
// find the export mask which has the same Host name as the initiator
// Add the initiator to that export mask
// Set up workflow steps.
Workflow workflow = _workflowService.getNewWorkflow(MaskingWorkflowEntryPoints.getInstance(), "exportGroupRemoveInitiators", true, token);
// irrespective of cluster name, host will be always present
Map<String, URI> hostToEMaskGroup = ExportMaskUtils.mapHostToExportMask(_dbClient, exportGroup, storage.getId());
log.info("Host to ExportMask : {}", Joiner.on(",").join(hostToEMaskGroup.entrySet()));
// if export masks are found for the Host, then remove initiators from the export mask
// Export Masks are not shared between export Groups
// list of export masks from which initiators need to be removed
List<ExportMask> exportMaskRemoveInitiator = new ArrayList<ExportMask>();
// list of export masks to delete as all initiators are removed
List<ExportMask> exportMaskDelete = new ArrayList<ExportMask>();
// map of masks to initiators being removed needed to remove zones
Map<URI, List<URI>> maskToInitiatorsMap = new HashMap<URI, List<URI>>();
String previousStep = null;
for (String computeKey : computeResourceToInitiators.keySet()) {
URI exportMaskUri = hostToEMaskGroup.get(computeKey);
if (null != exportMaskUri) {
ExportMask exportMask = _dbClient.queryObject(ExportMask.class, exportMaskUri);
if (exportMask.getStorageDevice().equals(storageURI)) {
List<Initiator> initiators = _dbClient.queryObject(Initiator.class, computeResourceToInitiators.get(computeKey));
List<Initiator> maskInitiators = new ArrayList<Initiator>();
for (Initiator initiator : initiators) {
if (exportMask.hasUserInitiator(initiator.getId())) {
maskInitiators.add(initiator);
} else {
_log.info(String.format("Initiator %s was not added by ViPR, so ViPR cannot remove it. No action will be taken for this initiator", initiator.getId()));
}
}
log.info("Processing export mask {} with initiators {}", storageURI, Joiner.on(",").join(maskInitiators));
if (!maskInitiators.isEmpty()) {
maskToInitiatorsMap.put(exportMask.getId(), Lists.newArrayList(Collections2.transform(maskInitiators, CommonTransformerFunctions.fctnDataObjectToID())));
if (isRemoveAllInitiators(exportMask, initiators)) {
exportMaskDelete.add(exportMask);
} else {
exportMaskRemoveInitiator.add(exportMask);
}
}
}
}
}
if (!exportMaskRemoveInitiator.isEmpty()) {
for (ExportMask exportMask : exportMaskRemoveInitiator) {
Collection<URI> volumeURIs = (Collections2.transform(exportMask.getUserAddedVolumes().values(), CommonTransformerFunctions.FCTN_STRING_TO_URI));
previousStep = generateExportMaskRemoveInitiatorsWorkflow(workflow, previousStep, storage, exportGroup, exportMask, new ArrayList<URI>(volumeURIs), initiatorURIs, true);
}
}
if (!exportMaskDelete.isEmpty()) {
for (ExportMask exportMask : exportMaskDelete) {
List<URI> volumesInMask = ExportMaskUtils.getUserAddedVolumeURIs(exportMask);
List<URI> initiators = maskToInitiatorsMap.get(exportMask.getId());
previousStep = generateExportMaskDeleteWorkflow(workflow, previousStep, storage, exportGroup, exportMask, volumesInMask, initiators, null);
}
}
if (!maskToInitiatorsMap.isEmpty()) {
previousStep = generateZoningRemoveInitiatorsWorkflow(workflow, previousStep, exportGroup, maskToInitiatorsMap);
}
String successMessage = String.format("Initiators successfully removed from export StorageArray %s", storage.getLabel());
workflow.executePlan(taskCompleter, successMessage);
log.info(String.format("exportRemoveInitiator end - Array: %s ExportGroup: " + "%s Initiator: %s", storageURI.toString(), exportGroupURI.toString(), Joiner.on(',').join(initiatorURIs)));
} else {
taskCompleter.ready(_dbClient);
}
} catch (Exception e) {
if (taskCompleter != null) {
ServiceError serviceError = DeviceControllerException.errors.jobFailedMsg(e.getMessage(), e);
taskCompleter.error(_dbClient, serviceError);
} else {
throw DeviceControllerException.exceptions.exportGroupRemoveInitiatorsFailed(e);
}
}
}
Aggregations