use of com.emc.storageos.volumecontroller.TaskCompleter in project coprhd-controller by CoprHD.
the class HDSMirrorOperations method detachSingleVolumeMirror.
/**
* 1. Delete ShadowImage Pair
* 2. Delete DummyLunPath from secondary volume
*/
@Override
public void detachSingleVolumeMirror(StorageSystem storage, URI mirror, TaskCompleter taskCompleter) throws DeviceControllerException {
NamedURI sourceVolumeURI = null;
try {
BlockMirror mirrorObj = dbClient.queryObject(BlockMirror.class, mirror);
// TODO needs to sync pair and wait for synchronization here
Volume source = dbClient.queryObject(Volume.class, mirrorObj.getSource());
sourceVolumeURI = mirrorObj.getSource();
boolean status = hdsProtectionOperations.modifyShadowImagePair(storage, source.getNativeId(), mirrorObj.getNativeId(), HDSApiProtectionManager.ShadowImageOperationType.split);
if (status) {
String taskId = UUID.randomUUID().toString();
TaskCompleter completer = new SimpleTaskCompleter(BlockMirror.class, mirror, taskId);
HDSJob syncjob = new HDSReplicationSyncJob(storage.getId(), source.getNativeId(), mirrorObj.getNativeId(), ReplicationStatus.SPLIT, completer);
hdsCommandHelper.waitForAsyncHDSJob(syncjob);
} else {
log.info("Replication info is not available on pair management server");
}
hdsProtectionOperations.deleteShadowImagePair(storage, source, mirrorObj);
hdsProtectionOperations.removeDummyLunPath(storage, mirror);
taskCompleter.ready(dbClient);
} catch (Exception e) {
String errorMsg = String.format(DETACH_ERROR_MSG_FORMAT, mirror, sourceVolumeURI != null ? sourceVolumeURI.toString() : HDSConstants.SPACE_STR);
log.error(errorMsg, e);
ServiceError serviceError = DeviceControllerErrors.hds.methodFailed("detachSingleVolumeMirror", e.getMessage());
taskCompleter.error(dbClient, serviceError);
}
}
use of com.emc.storageos.volumecontroller.TaskCompleter in project coprhd-controller by CoprHD.
the class HDSProtectionOperations method createSecondaryVolumeForSnapshot.
/**
* Creates Snapshot Volume
*
* @param storageSystem
* @param sourceVolume
* @param snapshotObj
* @throws Exception
*/
public void createSecondaryVolumeForSnapshot(StorageSystem storageSystem, Volume sourceVolume, BlockSnapshot snapshotObj) throws Exception {
log.info("SecondaryVolume for snapshot creation operation started");
String taskId = UUID.randomUUID().toString();
TaskCompleter taskCompleter = new BlockSnapshotCreateCompleter(Arrays.asList(snapshotObj.getId()), taskId);
String asyncTaskMessageId = null;
HDSApiClient hdsApiClient = HDSUtils.getHDSApiClient(hdsApiFactory, storageSystem);
String systemObjectID = HDSUtils.getSystemObjectID(storageSystem);
asyncTaskMessageId = hdsApiClient.createSnapshotVolume(systemObjectID, sourceVolume.getCapacity(), storageSystem.getModel());
if (asyncTaskMessageId != null) {
HDSJob createHDSJob = new HDSBlockCreateSnapshotJob(asyncTaskMessageId, snapshotObj.getStorageController(), taskCompleter);
hdsCommandHelper.waitForAsyncHDSJob(createHDSJob);
} else {
throw HDSException.exceptions.asyncTaskFailed("Unable to get async taskId from HiCommand Device Manager for the create snapshot volume call");
}
log.info("SecondaryVolume for snapshot creation operation completed successfully");
}
use of com.emc.storageos.volumecontroller.TaskCompleter in project coprhd-controller by CoprHD.
the class ReplicaDeviceController method removeFromReplicationGroup.
/**
* Orchestration method for removing members from a replication group.
*
* @param storage
* @param consistencyGroup
* @param repGroupName
* @param addVolumesList
* @param opId
* @return
* @throws ControllerException
*/
public boolean removeFromReplicationGroup(URI storage, URI consistencyGroup, String repGroupName, List<URI> addVolumesList, String opId) throws ControllerException {
TaskCompleter taskCompleter = new BlockConsistencyGroupUpdateCompleter(consistencyGroup, opId);
try {
List<String> lockKeys = new ArrayList<>();
lockKeys.add(ControllerLockingUtil.getReplicationGroupStorageKey(_dbClient, repGroupName, storage));
WorkflowService workflowService = _blockDeviceController.getWorkflowService();
workflowService.acquireWorkflowStepLocks(opId, lockKeys, LockTimeoutValue.get(LockType.ARRAY_CG));
StorageSystem storageSystem = _dbClient.queryObject(StorageSystem.class, storage);
_blockDeviceController.getDevice(storageSystem.getSystemType()).doRemoveFromReplicationGroup(storageSystem, consistencyGroup, repGroupName, addVolumesList, taskCompleter);
} catch (Exception e) {
ServiceError serviceError = DeviceControllerException.errors.jobFailed(e);
taskCompleter.error(_dbClient, serviceError);
WorkflowStepCompleter.stepFailed(opId, serviceError);
return false;
}
return true;
}
use of com.emc.storageos.volumecontroller.TaskCompleter in project coprhd-controller by CoprHD.
the class VPlexXIVMaskingOrchestrator method createOrAddVolumesToExportMask.
/*
* (non-Javadoc)
*
* @see com.emc.storageos.volumecontroller.impl.block.
* VplexBackEndMaskingOrchestrator#createOrAddVolumesToExportMask(java.net.URI, java.net.URI,
* java.net.URI, java.util.Map, com.emc.storageos.volumecontroller.TaskCompleter, java.lang.String)
*/
@Override
public void createOrAddVolumesToExportMask(URI arrayURI, URI exportGroupURI, URI exportMaskURI, Map<URI, Integer> volumeMap, List<URI> initiatorURIs2, TaskCompleter completer, String stepId) {
try {
WorkflowStepCompleter.stepExecuting(stepId);
StorageSystem array = _dbClient.queryObject(StorageSystem.class, arrayURI);
ExportMask exportMask = _dbClient.queryObject(ExportMask.class, exportMaskURI);
// If the exportMask isn't found, or has been deleted, fail, ask user to retry.
if (exportMask == null || exportMask.getInactive()) {
_log.info(String.format("ExportMask %s deleted or inactive, failing", exportMaskURI));
ServiceError svcerr = VPlexApiException.errors.createBackendExportMaskDeleted(exportMaskURI.toString(), arrayURI.toString());
WorkflowStepCompleter.stepFailed(stepId, svcerr);
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
BlockStorageDevice device = _blockController.getDevice(array.getSystemType());
if (exportMask.getNativeId() != null) {
exportMask = refreshExportMask(array, device, exportMask);
}
// We are creating this ExportMask on the hardware! (Maybe not the first time though...)
// Fetch the Initiators
List<URI> initiatorURIs = new ArrayList<URI>();
List<Initiator> initiators = new ArrayList<Initiator>();
for (String initiatorId : exportMask.getInitiators()) {
Initiator initiator = _dbClient.queryObject(Initiator.class, URI.create(initiatorId));
if (initiator != null) {
initiators.add(initiator);
initiatorURIs.add(initiator.getId());
}
}
if (!exportMask.hasAnyVolumes()) {
// Fetch the targets
List<URI> targets = new ArrayList<URI>();
for (String targetId : exportMask.getStoragePorts()) {
targets.add(URI.create(targetId));
}
// If some invalid export mask exists
if (exportMask.getNativeId() != null) {
exportMask.setNativeId("");
_dbClient.updateAndReindexObject(exportMask);
}
// The default completer passed in is for add volume, create correct one
TaskCompleter createCompleter = new ExportMaskCreateCompleter(exportGroupURI, exportMaskURI, initiatorURIs, volumeMap, stepId);
device.doExportCreate(array, exportMask, volumeMap, initiators, targets, createCompleter);
} else {
device.doExportAddVolumes(array, exportMask, initiators, volumeMap, completer);
}
} catch (Exception ex) {
_log.error("Failed to create or add volumes to export mask for XIV: ", ex);
VPlexApiException vplexex = DeviceControllerExceptions.vplex.addStepsForCreateVolumesFailed(ex);
WorkflowStepCompleter.stepFailed(stepId, vplexex);
}
}
use of com.emc.storageos.volumecontroller.TaskCompleter in project coprhd-controller by CoprHD.
the class VNXeMaskingOrchestrator method exportGroupAddInitiators.
@Override
public void exportGroupAddInitiators(URI storageURI, URI exportGroupURI, List<URI> initiatorURIs, String token) throws Exception {
TaskCompleter taskCompleter = null;
try {
_log.info(String.format("exportAddInitiator start - Array: %s ExportMask: " + "%s Initiator: %s", storageURI.toString(), exportGroupURI.toString(), Joiner.on(',').join(initiatorURIs)));
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("initiators : {}", Joiner.on(",").join(computeResourceToInitiators.entrySet()));
taskCompleter = new ExportOrchestrationTask(exportGroupURI, token);
Map<URI, Integer> volumes = selectExportMaskVolumes(exportGroup, storageURI);
_log.info("Volumes : {}", Joiner.on(",").join(volumes.keySet()));
if (!CollectionUtils.isEmpty(exportMasks)) {
// Refresh all export masks
for (ExportMask exportMask : exportMasks) {
refreshExportMask(storage, getDevice(), exportMask);
}
// find the export mask which has the same Host name as the initiator
// Add the initiator to that export mask
// Set up workflow steps.
_log.info("Creating AddInitiators workFlow");
Workflow workflow = _workflowService.getNewWorkflow(MaskingWorkflowEntryPoints.getInstance(), "exportGroupAddInitiators", true, token, taskCompleter);
// irrespective of cluster name, host will be always present
Map<String, URI> hostToEMaskGroup = ExportMaskUtils.mapHostToExportMask(_dbClient, exportGroup, storage.getId());
_log.info("hostsToExportMask : {}", Joiner.on(",").join(hostToEMaskGroup.entrySet()));
// if export masks are found for the Host, then add initiators to the export mask
Map<URI, List<URI>> masksToInitiators = new HashMap<URI, List<URI>>();
String addIniStep = null;
for (String computeKey : computeResourceToInitiators.keySet()) {
URI exportMaskUri = hostToEMaskGroup.get(computeKey);
if (null != exportMaskUri) {
_log.info("Processing export mask {}", exportMaskUri);
ExportMask exportMask = _dbClient.queryObject(ExportMask.class, exportMaskUri);
if (exportMask.getStorageDevice().equals(storageURI)) {
_log.info("Processing export mask {} with expected storage {}", exportMaskUri, storageURI);
// AddInitiatorWorkFlow
masksToInitiators.put(exportMaskUri, computeResourceToInitiators.get(computeKey));
// all masks will be always created by system = true, hence port allocation will happen
addIniStep = generateExportMaskAddInitiatorsWorkflow(workflow, null, storage, exportGroup, exportMask, initiatorURIs, null, token);
computeResourceToInitiators.remove(computeKey);
}
if (!masksToInitiators.isEmpty()) {
generateZoningAddInitiatorsWorkflow(workflow, addIniStep, exportGroup, masksToInitiators);
}
}
}
_log.info("Left out initiators : {}", Joiner.on(",").join(computeResourceToInitiators.entrySet()));
// left out initiator's Host which doesn't have any export mask.
Map<URI, Map<URI, Integer>> zoneNewMasksToVolumeMap = new HashMap<URI, Map<URI, Integer>>();
if (!computeResourceToInitiators.isEmpty()) {
for (Map.Entry<String, List<URI>> resourceEntry : computeResourceToInitiators.entrySet()) {
String computeKey = resourceEntry.getKey();
List<URI> computeInitiatorURIs = resourceEntry.getValue();
_log.info(String.format("New export masks for %s", computeKey));
GenExportMaskCreateWorkflowResult result = generateExportMaskCreateWorkflow(workflow, EXPORT_GROUP_ZONING_TASK, storage, exportGroup, computeInitiatorURIs, volumes, token);
zoneNewMasksToVolumeMap.put(result.getMaskURI(), volumes);
}
if (!zoneNewMasksToVolumeMap.isEmpty()) {
List<URI> exportMaskList = new ArrayList<URI>();
exportMaskList.addAll(zoneNewMasksToVolumeMap.keySet());
Map<URI, Integer> overallVolumeMap = new HashMap<URI, Integer>();
for (Map<URI, Integer> oneVolumeMap : zoneNewMasksToVolumeMap.values()) {
overallVolumeMap.putAll(oneVolumeMap);
}
generateZoningCreateWorkflow(workflow, null, exportGroup, exportMaskList, overallVolumeMap);
}
}
String successMessage = String.format("Initiators successfully added to export StorageArray %s", storage.getLabel());
workflow.executePlan(taskCompleter, successMessage);
} else {
_log.info("export_initiator_add: first initiator, creating a new export");
// No existing export masks available inexport Group
Workflow workflow = _workflowService.getNewWorkflow(MaskingWorkflowEntryPoints.getInstance(), "exportGroupCreate", true, token, taskCompleter);
List<URI> exportMasksToZoneCreate = new ArrayList<URI>();
Map<URI, Integer> volumesToZoneCreate = new HashMap<URI, Integer>();
for (Map.Entry<String, List<URI>> resourceEntry : computeResourceToInitiators.entrySet()) {
String computeKey = resourceEntry.getKey();
List<URI> computeInitiatorURIs = resourceEntry.getValue();
_log.info(String.format("New export masks for %s", computeKey));
GenExportMaskCreateWorkflowResult result = generateExportMaskCreateWorkflow(workflow, EXPORT_GROUP_ZONING_TASK, storage, exportGroup, computeInitiatorURIs, volumes, token);
exportMasksToZoneCreate.add(result.getMaskURI());
volumesToZoneCreate.putAll(volumes);
}
if (!exportMasksToZoneCreate.isEmpty()) {
generateZoningCreateWorkflow(workflow, null, exportGroup, exportMasksToZoneCreate, volumesToZoneCreate);
}
String successMessage = String.format("Initiators successfully added to export StorageArray %s", storage.getLabel());
workflow.executePlan(taskCompleter, successMessage);
}
_log.info(String.format("exportAddInitiator end - Array: %s ExportMask: %s " + "Initiator: %s", storageURI.toString(), exportGroupURI.toString(), Joiner.on(',').join(initiatorURIs)));
} catch (Exception e) {
if (taskCompleter != null) {
ServiceError serviceError = DeviceControllerException.errors.jobFailedMsg(e.getMessage(), e);
taskCompleter.error(_dbClient, serviceError);
} else {
throw DeviceControllerException.exceptions.exportGroupAddInitiatorsFailed(e);
}
}
}
Aggregations