use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportTaskCompleter in project coprhd-controller by CoprHD.
the class VPlexVnxMaskingOrchestrator 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 workflow 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()) {
device.doExportDelete(array, exportMask, passedVolumesInMask, initiatorURIs, completer);
} else {
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 vnx: ", ex);
VPlexApiException vplexex = DeviceControllerExceptions.vplex.addStepsForCreateVolumesFailed(ex);
completer.error(_dbClient, vplexex);
}
}
use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportTaskCompleter in project coprhd-controller by CoprHD.
the class VPlexXIVMaskingOrchestrator method deleteOrRemoveVolumesFromExportMask.
/*
* (non-Javadoc)
*
* @see com.emc.storageos.volumecontroller.impl.block.
* VplexBackEndMaskingOrchestrator#deleteOrRemoveVolumesFromExportMask(java.net.URI,
* java.net.URI, java.net.URI, java.util.List,
* java.lang.String)
*/
@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} duple.
// 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
if (exportMask.getNativeId() != null) {
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()) {
device.doExportDelete(array, exportMask, passedVolumesInMask, initiatorURIs, completer);
} else {
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 XIV: ", 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 HDSMaskingOrchestrator method generateDeviceSpecificDeleteWorkflow.
@Override
public String generateDeviceSpecificDeleteWorkflow(Workflow workflow, String previousStep, ExportGroup exportGroup, ExportMask mask, List<URI> volumes, List<URI> initiators, StorageSystem storage) throws Exception {
List<ExportMask> masks = new ArrayList<ExportMask>();
masks.add(mask);
ExportTaskCompleter hdsExportMaskDeleteCompleter = new HDSExportMaskDeleteCompleter(exportGroup.getId(), mask.getId(), previousStep);
String exportMaskDeleteStepId = generateExportMaskDeleteWorkflow(workflow, null, storage, exportGroup, mask, volumes, initiators, hdsExportMaskDeleteCompleter);
String zoningStepId = generateZoningDeleteWorkflow(workflow, exportMaskDeleteStepId, exportGroup, masks);
generateWorkflowStepToMarkExportMaskInActive(workflow, zoningStepId, exportGroup, mask, null);
return exportMaskDeleteStepId;
}
use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportTaskCompleter in project coprhd-controller by CoprHD.
the class MaskingWorkflowEntryPoints method rollbackExportGroupAddVolumes.
/**
* Rollback entry point. This is a wrapper around the exportGroupRemoveVolumes
* operation, which requires that we create a specific completer using the token
* that's passed in. This token is generated by the rollback processing.
*
* @param storageURI
* [in] - StorageSystem URI
* @param exportGroupURI
* [in] - ExportGroup URI
* @param exportGroupURIs
* [in] - All ExportGroup URIs that the export mask associates with
* @param exportMaskURI
* [in] - ExportMask URI
* @param volumeMap
* [in] - Map of Volume URI to HLU Integer value
* @param initiatorURIs
* [in] - Impacted initiators
* @param contextKey
* [in] - context token
* @param token
* [in] - String token generated by the rollback processing
* @throws ControllerException
*/
public void rollbackExportGroupAddVolumes(URI storageURI, URI exportGroupURI, List<URI> exportGroupURIs, URI exportMaskURI, Map<URI, Integer> volumeMap, List<URI> initiatorURIs, String contextKey, String token) throws ControllerException {
List<URI> list = new ArrayList<URI>();
list.addAll(volumeMap.keySet());
ExportTaskCompleter taskCompleter = new ExportMaskRemoveVolumeCompleter(exportGroupURI, exportMaskURI, list, token);
taskCompleter.setExportGroups(exportGroupURIs);
// in order to only perform rollback of operations we successfully performed.
try {
ExportOperationContext context = (ExportOperationContext) WorkflowService.getInstance().loadStepData(contextKey);
WorkflowService.getInstance().storeStepData(token, context);
} catch (ClassCastException e) {
_log.info("Step {} has stored step data other than ExportOperationContext. Exception: {}", token, e);
}
doExportGroupRemoveVolumes(storageURI, exportGroupURI, exportMaskURI, list, initiatorURIs, taskCompleter, token);
}
use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportTaskCompleter in project coprhd-controller by CoprHD.
the class MaskingWorkflowEntryPoints method rollbackExportGroupCreate.
/**
* Rollback entry point. This is a wrapper around the exportGroupDelete operation,
* which requires that we create a specific completer using the token that's passed
* in. This token is generated by the rollback processing.
*
* @param storageURI
* [in] - StorageSystem URI
* @param exportGroupURI
* [in] - ExportGroup URI
* @param exportMaskURI
* [in] - ExportMask URI
* @param contextKey
* [in] - context token
* @param token
* [in] - String token generated by the rollback processing
*
* @throws ControllerException
*/
public void rollbackExportGroupCreate(URI storageURI, URI exportGroupURI, URI exportMaskURI, String contextKey, String token) throws ControllerException {
ExportTaskCompleter taskCompleter = new RollbackExportGroupCreateCompleter(exportGroupURI, exportMaskURI, token);
// Take the context of the step in flight and feed it into our current step
// in order to only perform rollback of operations we successfully performed.
ExportOperationContext context = null;
try {
context = (ExportOperationContext) WorkflowService.getInstance().loadStepData(contextKey);
WorkflowService.getInstance().storeStepData(token, context);
} catch (ClassCastException e) {
_log.info("Step {} has stored step data other than ExportOperationContext. Exception: {}", token, e);
}
_log.info("Rolling back operations: " + context);
doExportGroupDelete(storageURI, exportGroupURI, exportMaskURI, null, null, taskCompleter, token);
}
Aggregations