use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.MultiVolumeTaskCompleter in project coprhd-controller by CoprHD.
the class BlockDeviceController method rollBackCreateVolumes.
/**
* {@inheritDoc} NOTE: The signature here MUST match the Workflow.Method rollbackCreateVolumesMethod just above
* (except opId).
*/
@Override
public void rollBackCreateVolumes(URI systemURI, List<URI> volumeURIs, String opId) throws ControllerException {
MultiVolumeTaskCompleter completer = new MultiVolumeTaskCompleter(volumeURIs, opId);
List<Volume> volumes = new ArrayList<>(volumeURIs.size());
completer.setRollingBack(true);
try {
String logMsg = String.format("rollbackCreateVolume start - Array:%s, Volume:%s", systemURI.toString(), Joiner.on(',').join(volumeURIs));
_log.info(logMsg.toString());
WorkflowStepCompleter.stepExecuting(opId);
volumes.addAll(_dbClient.queryObject(Volume.class, volumeURIs));
for (Volume volume : volumes) {
// CTRL-5597 clean volumes which have failed only in a multi-volume request
if (null != volume.getNativeGuid()) {
StorageSystem system = _dbClient.queryObject(StorageSystem.class, volume.getStorageController());
if (Type.xtremio.toString().equalsIgnoreCase(system.getSystemType())) {
continue;
}
}
// then we need to clear srdfTargets and personality fields for source
if (null != volume.getSrdfTargets()) {
_log.info("Clearing targets for existing source");
volume.getSrdfTargets().clear();
_dbClient.updateObject(volume);
// Clearing Source CG
URI sourceCgUri = volume.getConsistencyGroup();
if (null != sourceCgUri) {
BlockConsistencyGroup sourceCG = _dbClient.queryObject(BlockConsistencyGroup.class, sourceCgUri);
if (null != sourceCG && (null == sourceCG.getTypes() || NullColumnValueGetter.isNullURI(sourceCG.getStorageController()))) {
sourceCG.getRequestedTypes().remove(Types.SRDF.name());
_dbClient.updateObject(sourceCG);
}
}
}
// for change Virtual Pool, if failed, clear targets and personality field for source and also
if (!NullColumnValueGetter.isNullNamedURI(volume.getSrdfParent())) {
URI sourceUri = volume.getSrdfParent().getURI();
Volume sourceVolume = _dbClient.queryObject(Volume.class, sourceUri);
sourceVolume.setPersonality(NullColumnValueGetter.getNullStr());
if (null != sourceVolume.getSrdfTargets()) {
sourceVolume.getSrdfTargets().clear();
_dbClient.updateObject(sourceVolume);
}
// Clearing target CG
URI cgUri = volume.getConsistencyGroup();
if (null != cgUri) {
BlockConsistencyGroup targetCG = _dbClient.queryObject(BlockConsistencyGroup.class, cgUri);
if (null != targetCG && (null == targetCG.getTypes() || NullColumnValueGetter.isNullURI(targetCG.getStorageController()))) {
_log.info("Set target CG {} inactive", targetCG.getLabel());
targetCG.setInactive(true);
_dbClient.updateObject(targetCG);
}
// clear association between target volume and target cg
volume.setConsistencyGroup(NullColumnValueGetter.getNullURI());
_dbClient.updateAndReindexObject(volume);
}
}
// Check for loose export groups associated with this rolled-back volume
URIQueryResultList exportGroupURIs = new URIQueryResultList();
_dbClient.queryByConstraint(ContainmentConstraint.Factory.getVolumeExportGroupConstraint(volume.getId()), exportGroupURIs);
while (exportGroupURIs.iterator().hasNext()) {
URI exportGroupURI = exportGroupURIs.iterator().next();
ExportGroup exportGroup = _dbClient.queryObject(ExportGroup.class, exportGroupURI);
if (!exportGroup.getInactive()) {
exportGroup.removeVolume(volume.getId());
boolean canRemoveGroup = false;
List<ExportMask> exportMasks = ExportMaskUtils.getExportMasks(_dbClient, exportGroup);
// Make sure the volume is not in an export mask
for (ExportMask exportMask : exportMasks) {
exportMask.removeVolume(volume.getId());
exportMask.removeFromUserCreatedVolumes(volume);
exportMask.removeFromExistingVolumes(volume);
if (!exportMask.getCreatedBySystem() && !exportMask.hasAnyVolumes() && exportMask.emptyVolumes()) {
canRemoveGroup = true;
_dbClient.removeObject(exportMask);
} else {
_dbClient.updateObject(exportMask);
}
}
// If we didn't find that volume in a mask, it's OK to remove it.
if (canRemoveGroup && exportMasks.size() == 1 && exportGroup.getVolumes().isEmpty()) {
_dbClient.removeObject(exportGroup);
} else {
_dbClient.updateObject(exportGroup);
}
}
}
}
InvokeTestFailure.internalOnlyInvokeTestFailure(InvokeTestFailure.ARTIFICIAL_FAILURE_013);
deleteVolumesWithCompleter(systemURI, volumeURIs, completer);
InvokeTestFailure.internalOnlyInvokeTestFailure(InvokeTestFailure.ARTIFICIAL_FAILURE_014);
logMsg = String.format("rollbackCreateVolume end - Array:%s, Volume:%s", systemURI.toString(), Joiner.on(',').join(volumeURIs));
_log.info(logMsg.toString());
} catch (Exception e) {
_log.error(String.format("rollbackCreateVolume Failed - Array:%s, Volume:%s", systemURI.toString(), Joiner.on(',').join(volumeURIs)));
handleException(e, completer);
}
}
use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.MultiVolumeTaskCompleter in project coprhd-controller by CoprHD.
the class BlockDeviceController method createMetaVolumes.
/**
* {@inheritDoc} NOTE NOTE: The signature here MUST match the Workflow.Method createMetaVolumesMethod just above
* (except opId).
*/
@Override
public void createMetaVolumes(URI systemURI, URI poolURI, List<URI> volumeURIs, VirtualPoolCapabilityValuesWrapper capabilities, String opId) throws ControllerException {
boolean opCreateFailed = false;
List<Volume> volumes = new ArrayList<Volume>();
try {
StorageSystem storageSystem = _dbClient.queryObject(StorageSystem.class, systemURI);
List<VolumeTaskCompleter> volumeCompleters = new ArrayList<VolumeTaskCompleter>();
Iterator<URI> volumeURIsIter = volumeURIs.iterator();
StringBuilder logMsgBuilder = new StringBuilder(String.format("createMetaVolumes start - Array:%s Pool:%s", systemURI.toString(), poolURI.toString()));
while (volumeURIsIter.hasNext()) {
URI volumeURI = volumeURIsIter.next();
logMsgBuilder.append(String.format("%nVolume:%s", volumeURI.toString()));
Volume volume = _dbClient.queryObject(Volume.class, volumeURI);
volumes.add(volume);
VolumeCreateCompleter volumeCompleter = new VolumeCreateCompleter(volumeURI, opId);
volumeCompleters.add(volumeCompleter);
}
_log.info(logMsgBuilder.toString());
StoragePool storagePool = _dbClient.queryObject(StoragePool.class, poolURI);
MultiVolumeTaskCompleter completer = new MultiVolumeTaskCompleter(volumeURIs, volumeCompleters, opId);
Volume volume = volumes.get(0);
VirtualPool vpool = _dbClient.queryObject(VirtualPool.class, volume.getVirtualPool());
// All volumes are in the same storage pool with the same capacity. Get recommendation for the first volume.
MetaVolumeRecommendation recommendation = MetaVolumeUtils.getCreateRecommendation(storageSystem, storagePool, volume.getCapacity(), volume.getThinlyProvisioned(), vpool.getFastExpansion(), capabilities);
for (Volume metaVolume : volumes) {
MetaVolumeUtils.prepareMetaVolume(metaVolume, recommendation.getMetaMemberSize(), recommendation.getMetaMemberCount(), recommendation.getMetaVolumeType().toString(), _dbClient);
}
WorkflowStepCompleter.stepExecuting(completer.getOpId());
getDevice(storageSystem.getSystemType()).doCreateMetaVolumes(storageSystem, storagePool, volumes, capabilities, recommendation, completer);
logMsgBuilder = new StringBuilder(String.format("createMetaVolumes end - Array:%s Pool:%s", systemURI.toString(), poolURI.toString()));
volumeURIsIter = volumeURIs.iterator();
while (volumeURIsIter.hasNext()) {
logMsgBuilder.append(String.format("%nVolume:%s", volumeURIsIter.next().toString()));
}
_log.info(logMsgBuilder.toString());
} catch (InternalException e) {
_log.error(String.format("createMetaVolumes Failed - Array: %s Pool:%s Volume:%s", systemURI.toString(), poolURI.toString(), Joiner.on("\t").join(volumeURIs)));
doFailTask(Volume.class, volumeURIs, opId, e);
WorkflowStepCompleter.stepFailed(opId, e);
opCreateFailed = true;
} catch (Exception e) {
_log.error(String.format("createMetaVolumes Failed - Array: %s Pool:%s Volume:%s", systemURI.toString(), poolURI.toString(), Joiner.on("\t").join(volumeURIs)));
ServiceError serviceError = DeviceControllerException.errors.jobFailed(e);
doFailTask(Volume.class, volumeURIs, opId, serviceError);
WorkflowStepCompleter.stepFailed(opId, serviceError);
opCreateFailed = true;
}
if (opCreateFailed) {
for (Volume volume : volumes) {
volume.setInactive(true);
_dbClient.updateObject(volume);
}
}
}
use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.MultiVolumeTaskCompleter in project coprhd-controller by CoprHD.
the class BlockDeviceController method deleteVolumes.
/**
* {@inheritDoc} NOTE NOTE: The arguments here must match deleteVolumesMethod defined above (except opId).
*/
@Override
public void deleteVolumes(URI systemURI, List<URI> volumeURIs, String opId) throws ControllerException {
MultiVolumeTaskCompleter completer = new MultiVolumeTaskCompleter(volumeURIs, opId);
deleteVolumesWithCompleter(systemURI, volumeURIs, completer);
}
use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.MultiVolumeTaskCompleter in project coprhd-controller by CoprHD.
the class CinderStorageDevice method doDeleteVolumes.
/*
* (non-Javadoc)
*
* @see com.emc.storageos.volumecontroller.BlockStorageDevice#doDeleteVolumes
* (com.emc.storageos.db.client.model.StorageSystem,
* java.lang.String,
* java.util.List,
* com.emc.storageos.volumecontroller.TaskCompleter)
*/
@Override
public void doDeleteVolumes(StorageSystem storageSystem, String opId, List<Volume> volumes, TaskCompleter taskCompleter) throws DeviceControllerException {
try {
List<String> volumeNativeIdsToDelete = new ArrayList<String>(volumes.size());
List<String> volumeLabels = new ArrayList<String>(volumes.size());
StringBuilder logMsgBuilder = new StringBuilder(String.format("Delete Volume Start - Array:%s", storageSystem.getSerialNumber()));
log.info(logMsgBuilder.toString());
MultiVolumeTaskCompleter multiVolumeTaskCompleter = (MultiVolumeTaskCompleter) taskCompleter;
CinderEndPointInfo ep = CinderUtils.getCinderEndPoint(storageSystem.getActiveProviderURI(), dbClient);
log.info("Getting the cinder APi for the provider with id " + storageSystem.getActiveProviderURI());
CinderApi cinderApi = cinderApiFactory.getApi(storageSystem.getActiveProviderURI(), ep);
for (Volume volume : volumes) {
logMsgBuilder.append(String.format("%nVolume:%s", volume.getLabel()));
try {
// Check if the volume is present on the back-end device
cinderApi.showVolume(volume.getNativeId());
} catch (CinderException ce) {
// This means, the volume is not present on the back-end device
log.info(String.format("Volume %s already deleted: ", volume.getNativeId()));
volume.setInactive(true);
dbClient.persistObject(volume);
VolumeTaskCompleter deleteTaskCompleter = multiVolumeTaskCompleter.skipTaskCompleter(volume.getId());
deleteTaskCompleter.ready(dbClient);
continue;
}
volumeNativeIdsToDelete.add(volume.getNativeId());
volumeLabels.add(volume.getLabel());
// cleanup if there are any snapshots created for a volume
cleanupAnyBackupSnapshots(volume, cinderApi);
}
// Now - trigger the delete
if (!multiVolumeTaskCompleter.isVolumeTaskCompletersEmpty()) {
cinderApi.deleteVolumes(volumeNativeIdsToDelete.toArray(new String[] {}));
ControllerServiceImpl.enqueueJob(new QueueJob(new CinderDeleteVolumeJob(volumeNativeIdsToDelete.get(0), volumeLabels.get(0), volumes.get(0).getStorageController(), CinderConstants.ComponentType.volume.name(), ep, taskCompleter)));
} else {
// If we are here, there are no volumes to delete, we have
// invoked ready() for the VolumeDeleteCompleter, and told
// the multiVolumeTaskCompleter to skip these completers.
// In this case, the multiVolumeTaskCompleter complete()
// method will not be invoked and the result is that the
// workflow that initiated this delete request will never
// be updated. So, here we just call complete() on the
// multiVolumeTaskCompleter to ensure the workflow status is
// updated.
multiVolumeTaskCompleter.ready(dbClient);
}
} catch (Exception e) {
log.error("Problem in doDeleteVolume: ", e);
ServiceError error = DeviceControllerErrors.cinder.operationFailed("doDeleteVolume", e.getMessage());
taskCompleter.error(dbClient, error);
}
StringBuilder logMsgBuilder = new StringBuilder(String.format("Delete Volume End - Array: %s", storageSystem.getSerialNumber()));
for (Volume volume : volumes) {
logMsgBuilder.append(String.format("%nVolume:%s", volume.getLabel()));
}
log.info(logMsgBuilder.toString());
}
use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.MultiVolumeTaskCompleter in project coprhd-controller by CoprHD.
the class XIVSmisStorageDevicePostProcessor method processVolumeDeletion.
/**
* Update DB with SMI-S output, also set task completer status.
*/
public List<Volume> processVolumeDeletion(StorageSystem storageSystem, List<Volume> volumes, CIMArgument[] outArgs, MultiVolumeTaskCompleter multiVolumeTaskCompleter) throws Exception {
CimConnection connection = _cimConnection.getConnection(storageSystem);
WBEMClient client = connection.getCimClient();
List<Volume> volumesToProcess = new ArrayList<Volume>();
for (Volume vol : volumes) {
Volume volume = _dbClient.queryObject(Volume.class, vol.getId());
volumesToProcess.add(volume);
StoragePool storagePool = _dbClient.queryObject(StoragePool.class, volume.getPool());
updateStoragePoolCapacity(client, storagePool);
}
StringBuilder logMsgBuilder = new StringBuilder();
UnsignedInteger32[] returnCoedes = (UnsignedInteger32[]) _cimPath.getFromOutputArgs(outArgs, IBMSmisConstants.CP_RETURN_CODES);
List<Volume> volumesToSave = new ArrayList<Volume>(returnCoedes.length);
for (int i = 0; i < returnCoedes.length; i++) {
Volume volume = volumesToProcess.get(i);
VolumeTaskCompleter deleteTaskCompleter = multiVolumeTaskCompleter.skipTaskCompleter(volume.getId());
if (returnCoedes[i].longValue() == 0L) {
volume.setInactive(true);
volume.setConsistencyGroup(NullColumnValueGetter.getNullURI());
_dbClient.updateAndReindexObject(volume);
deleteTaskCompleter.ready(_dbClient);
if (logMsgBuilder.length() != 0) {
logMsgBuilder.append("\n");
}
logMsgBuilder.append(String.format("Successfully deleted volume %s", volume.getId()));
} else {
// cannot delete volume
String errorMessage = String.format("Failed to delete volume: %s , nativeId: %s with return code: %s", volume.getId(), volume.getNativeId(), returnCoedes[i].toString());
ServiceError error = DeviceControllerErrors.smis.methodFailed("doDeleteVolume", errorMessage);
deleteTaskCompleter.error(_dbClient, error);
if (logMsgBuilder.length() != 0) {
logMsgBuilder.append("\n");
}
logMsgBuilder.append(errorMessage);
}
}
if (logMsgBuilder.length() > 0) {
_log.info(logMsgBuilder.toString());
}
return volumesToSave;
}
Aggregations