use of com.emc.storageos.volumecontroller.impl.validators.contexts.ExportMaskValidationContext in project coprhd-controller by CoprHD.
the class HDSExportOperations method removeInitiators.
@Override
public void removeInitiators(StorageSystem storage, URI exportMaskURI, List<URI> volumeURIList, List<Initiator> initiators, List<URI> targets, TaskCompleter taskCompleter) throws DeviceControllerException {
long startTime = System.currentTimeMillis();
log.info("{} removeInitiator START...", storage.getSerialNumber());
try {
log.info("removeInitiator: Export mask id: {}", exportMaskURI);
if (volumeURIList != null) {
log.info("removeInitiator: volumes : {}", Joiner.on(',').join(volumeURIList));
}
log.info("removeInitiator: initiators : {}", Joiner.on(',').join(initiators));
log.info("removeInitiator: targets : {}", Joiner.on(',').join(targets));
if (null == initiators || initiators.isEmpty()) {
log.info("No initiators found to remove {}", exportMaskURI);
taskCompleter.ready(dbClient);
return;
}
ExportMask exportMask = dbClient.queryObject(ExportMask.class, exportMaskURI);
// Get the context from the task completer, in case this is a rollback.
boolean isRollback = WorkflowService.getInstance().isStepInRollbackState(taskCompleter.getOpId());
ExportMaskValidationContext ctx = new ExportMaskValidationContext();
ctx.setStorage(storage);
ctx.setExportMask(exportMask);
ctx.setBlockObjects(volumeURIList, dbClient);
ctx.setInitiators(initiators);
// Allow exceptions to be thrown when not rolling back
ctx.setAllowExceptions(!isRollback);
AbstractHDSValidator removeInitiatorFromMaskValidator = (AbstractHDSValidator) validator.removeInitiators(ctx);
removeInitiatorFromMaskValidator.validate();
HDSApiClient hdsApiClient = hdsApiFactory.getClient(HDSUtils.getHDSServerManagementServerInfo(storage), storage.getSmisUserName(), storage.getSmisPassword());
HDSApiExportManager exportMgr = hdsApiClient.getHDSApiExportManager();
String systemObjectID = HDSUtils.getSystemObjectID(storage);
StringSetMap deviceDataMap = exportMask.getDeviceDataMap();
if (null != deviceDataMap && !deviceDataMap.isEmpty()) {
Set<String> hsdObjectIDSet = deviceDataMap.keySet();
for (String hsdObjectID : hsdObjectIDSet) {
HostStorageDomain hsd = exportMgr.getHostStorageDomain(systemObjectID, hsdObjectID);
if (null == hsd) {
log.warn("Not able to remove initiators as HSD {} couldn't find on array.", hsdObjectID);
continue;
}
List<String> fcInitiators = getFCInitiatorsExistOnHSD(hsd, initiators);
List<String> iSCSIInitiators = getISCSIInitiatorsExistOnHSD(hsd, initiators);
boolean isLastFCInitiator = (fcInitiators.size() == 1 && null != hsd.getWwnList() && hsd.getWwnList().size() == fcInitiators.size());
boolean isLastISCSIInitiator = (iSCSIInitiators.size() == 1 && null != hsd.getIscsiList() && hsd.getIscsiList().size() == iSCSIInitiators.size());
// If Initiator is last one, remove the HSD
if (isLastFCInitiator || isLastISCSIInitiator) {
exportMgr.deleteHostStorageDomain(systemObjectID, hsd.getObjectID(), storage.getModel());
exportMask.getDeviceDataMap().remove(hsd.getObjectID());
} else {
if (null != fcInitiators && !fcInitiators.isEmpty()) {
// remove FC initiators from HSD.
exportMgr.deleteWWNsFromHostStorageDomain(systemObjectID, hsd.getObjectID(), fcInitiators, storage.getModel());
}
if (null != iSCSIInitiators && !iSCSIInitiators.isEmpty()) {
// remove ISCSInames from HSD.
exportMgr.deleteISCSIsFromHostStorageDomain(systemObjectID, hsd.getObjectID(), iSCSIInitiators, storage.getModel());
}
}
}
dbClient.updateObject(exportMask);
// update the task status after processing all HSD's.
taskCompleter.ready(dbClient);
} else {
log.info("No Host groups found on exportMask {}", exportMaskURI);
// No HSD's found in exportMask.
taskCompleter.ready(dbClient);
}
} catch (Exception e) {
log.error(String.format("removeInitiator failed - maskURI: %s", exportMaskURI.toString()), e);
ServiceError serviceError = DeviceControllerException.errors.jobFailedOpMsg(ResourceOperationTypeEnum.DELETE_EXPORT_INITIATOR.getName(), e.getMessage());
taskCompleter.error(dbClient, serviceError);
} finally {
long totalTime = System.currentTimeMillis() - startTime;
log.info(String.format("findExportMasks took %f seconds", (double) totalTime / (double) 1000));
}
log.info("{} removeInitiator END...", storage.getSerialNumber());
}
use of com.emc.storageos.volumecontroller.impl.validators.contexts.ExportMaskValidationContext in project coprhd-controller by CoprHD.
the class HDSExportOperations method removeVolumes.
@Override
public void removeVolumes(StorageSystem storage, URI exportMaskURI, List<URI> volumes, List<Initiator> initiatorList, TaskCompleter taskCompleter) throws DeviceControllerException {
log.info("{} removeVolumes START...", storage.getSerialNumber());
try {
log.info("removeVolumes: Export mask id: {}", exportMaskURI);
log.info("removeVolumes: volumes: {}", Joiner.on(',').join(volumes));
if (initiatorList != null) {
log.info("removeVolumes: impacted initiators: {}", Joiner.on(",").join(initiatorList));
}
HDSApiClient hdsApiClient = hdsApiFactory.getClient(HDSUtils.getHDSServerManagementServerInfo(storage), storage.getSmisUserName(), storage.getSmisPassword());
HDSApiExportManager exportMgr = hdsApiClient.getHDSApiExportManager();
String systemObjectID = HDSUtils.getSystemObjectID(storage);
ExportMask exportMask = dbClient.queryObject(ExportMask.class, exportMaskURI);
if (CollectionUtils.isEmpty(exportMask.getDeviceDataMap())) {
log.info("HSD's are not found in the exportMask {} device DataMap.", exportMask.getId());
taskCompleter.ready(dbClient);
}
// Get the context from the task completer, in case this is a rollback.
boolean isRollback = WorkflowService.getInstance().isStepInRollbackState(taskCompleter.getOpId());
ExportMaskValidationContext ctx = new ExportMaskValidationContext();
ctx.setStorage(storage);
ctx.setExportMask(exportMask);
ctx.setBlockObjects(volumes, dbClient);
ctx.setInitiators(initiatorList);
// Allow exceptions to be thrown when not rolling back
ctx.setAllowExceptions(!isRollback);
AbstractHDSValidator removeVolumeFromMaskValidator = (AbstractHDSValidator) validator.removeVolumes(ctx);
removeVolumeFromMaskValidator.validate();
StringSetMap deviceDataMap = exportMask.getDeviceDataMap();
Set<String> hsdList = deviceDataMap.keySet();
List<Path> pathObjectIdList = new ArrayList<Path>();
if (null == hsdList || hsdList.isEmpty()) {
throw HDSException.exceptions.notAbleToFindHostStorageDomain(systemObjectID);
}
if (null != exportMask && !exportMask.getInactive()) {
for (String hsdObjectId : hsdList) {
HostStorageDomain hsd = exportMgr.getHostStorageDomain(systemObjectID, hsdObjectId);
if (null == hsd) {
log.warn("Couldn't find the HSD {} to remove volume from ExportMask", hsdObjectId);
continue;
}
if (null != hsd.getPathList() && !hsd.getPathList().isEmpty()) {
pathObjectIdList.addAll(getPathObjectIdsFromHsd(hsd, volumes));
}
}
if (!pathObjectIdList.isEmpty()) {
hdsApiClient.getHDSBatchApiExportManager().deleteLUNPathsFromStorageSystem(systemObjectID, pathObjectIdList, storage.getModel());
} else {
log.info("No volumes found on system: {}", systemObjectID);
}
}
// Update the status after deleting the volume from all HSD's.
taskCompleter.ready(dbClient);
} catch (Exception e) {
log.error(String.format("removeVolume failed - maskURI: %s", exportMaskURI.toString()), e);
ServiceError serviceError = DeviceControllerException.errors.jobFailedMsg(e.getMessage(), e);
taskCompleter.error(dbClient, serviceError);
}
log.info("{} removeVolumes END...", storage.getSerialNumber());
}
use of com.emc.storageos.volumecontroller.impl.validators.contexts.ExportMaskValidationContext in project coprhd-controller by CoprHD.
the class VnxExportOperations method deleteExportMask.
/*
* (non-Javadoc)
*
* @see
* com.emc.storageos.volumecontroller.impl.smis.ExportMaskOperations#deleteExportMask(com.emc.storageos.db.client.
* model.StorageSystem, java.net.URI, java.util.List, java.util.List, java.util.List,
* com.emc.storageos.volumecontroller.TaskCompleter)
*
* IDs
* Note: No need to verify storage ports.
*/
@Override
public void deleteExportMask(StorageSystem storage, URI exportMaskURI, List<URI> volumeURIList, List<URI> targetURIList, List<Initiator> initiatorList, TaskCompleter taskCompleter) throws DeviceControllerException {
_log.info("{} deleteExportMask START...", storage.getSerialNumber());
try {
_log.info("Export mask id: {}", exportMaskURI);
if (volumeURIList != null) {
_log.info("deleteExportMask: volumes: {}", Joiner.on(',').join(volumeURIList));
}
if (targetURIList != null) {
_log.info("deleteExportMask: assignments: {}", Joiner.on(',').join(targetURIList));
}
if (initiatorList != null) {
_log.info("deleteExportMask: initiators: {}", Joiner.on(',').join(initiatorList));
}
ExportMask exportMask = _dbClient.queryObject(ExportMask.class, exportMaskURI);
String nativeId = exportMask.getNativeId();
if (Strings.isNullOrEmpty(nativeId)) {
_log.warn(String.format("ExportMask %s does not have a nativeID, " + "indicating that this export may not have been created " + "successfully. Marking the delete operation ready.", exportMaskURI.toString()));
// Perform post-mask-delete cleanup steps
ExportUtils.cleanupAssociatedMaskResources(_dbClient, exportMask);
taskCompleter.ready(_dbClient);
return;
}
boolean isRollback = WorkflowService.getInstance().isStepInRollbackState(taskCompleter.getOpId());
if (isRollback) {
boolean maskCreated = false;
// Get the context from the task completer as this is a rollback.
ExportOperationContext context = (ExportOperationContext) WorkflowService.getInstance().loadStepData(taskCompleter.getOpId());
if (context != null && context.getOperations() != null) {
ListIterator li = context.getOperations().listIterator(context.getOperations().size());
while (li.hasPrevious()) {
ExportOperationContextOperation operation = (ExportOperationContextOperation) li.previous();
_log.info("Handling deleteExportMask as a result of rollback");
if (operation != null && VnxExportOperationContext.OPERATION_CREATE_STORAGE_GROUP.equals(operation.getOperation())) {
URI createdExportMaskURI = (URI) operation.getArgs().get(0);
if (exportMask.getId().equals(createdExportMaskURI)) {
maskCreated = true;
break;
}
}
}
}
if (!maskCreated) {
_log.warn(String.format("This is a case of rollback but the ExportMask %s was not found in the export context, " + "indicating that this export may not have been created successfully. Marking the delete operation ready.", exportMaskURI.toString()));
// Perform post-mask-delete cleanup steps
ExportUtils.cleanupAssociatedMaskResources(_dbClient, exportMask);
taskCompleter.ready(_dbClient);
return;
}
}
ExportMaskValidationContext ctx = new ExportMaskValidationContext();
ctx.setStorage(storage);
ctx.setExportMask(exportMask);
ctx.setBlockObjects(volumeURIList, _dbClient);
ctx.setInitiators(initiatorList);
ctx.setAllowExceptions(!isRollback);
validator.exportMaskDelete(ctx).validate();
CIMObjectPath protocolController = _cimPath.getClarProtocolControllers(storage, nativeId)[0];
CIMInstance instance = _helper.checkExists(storage, protocolController, true, true);
if (instance != null) {
_helper.setProtocolControllerNativeId(exportMaskURI, null);
ExportMask mask = _dbClient.queryObject(ExportMask.class, exportMaskURI);
if (mask != null) {
List<URI> initiatorURIs = new ArrayList<URI>();
if (mask.getInitiators() != null) {
for (String initUriStr : mask.getInitiators()) {
initiatorURIs.add(URI.create(initUriStr));
}
}
List<Initiator> initiators = _dbClient.queryObject(Initiator.class, initiatorURIs);
deleteStorageHWIDs(storage, initiators);
deleteOrShrinkStorageGroup(storage, exportMaskURI, null, null);
}
}
// Perform post-mask-delete cleanup steps
ExportUtils.cleanupAssociatedMaskResources(_dbClient, exportMask);
taskCompleter.ready(_dbClient);
} catch (Exception e) {
_log.error("Unexpected error: deleteExportMask failed.", e);
ServiceError error = DeviceControllerErrors.smis.methodFailed("deleteExportMask", e.getMessage());
taskCompleter.error(_dbClient, error);
}
_log.info("{} deleteExportMask END...", storage.getSerialNumber());
}
use of com.emc.storageos.volumecontroller.impl.validators.contexts.ExportMaskValidationContext in project coprhd-controller by CoprHD.
the class VnxExportOperations method removeVolumes.
/*
* (non-Javadoc)
*
* @see
* com.emc.storageos.volumecontroller.impl.smis.ExportMaskOperations#removeVolume(com.emc.storageos.db.client.model.
* StorageSystem, java.net.URI, java.util.List, com.emc.storageos.volumecontroller.TaskCompleter)
*
*/
@Override
public void removeVolumes(StorageSystem storage, URI exportMaskURI, List<URI> volumeURIList, List<Initiator> initiatorList, TaskCompleter taskCompleter) throws DeviceControllerException {
_log.info("{} removeVolumes START...", storage.getSerialNumber());
try {
_log.info("removeVolumes: Export mask id: {}", exportMaskURI);
_log.info("removeVolumes: volumes: {}", Joiner.on(',').join(volumeURIList));
if (initiatorList != null) {
_log.info("removeVolumes: impacted initiators: {}", Joiner.on(",").join(initiatorList));
}
boolean isRollback = WorkflowService.getInstance().isStepInRollbackState(taskCompleter.getOpId());
if (isRollback) {
_log.info("Handling removeVolumes as a result of rollback");
List<URI> addedVolumes = new ArrayList<URI>();
// Get the context from the task completer as this is a rollback.
ExportOperationContext context = (ExportOperationContext) WorkflowService.getInstance().loadStepData(taskCompleter.getOpId());
if (context != null && context.getOperations() != null) {
ListIterator li = context.getOperations().listIterator(context.getOperations().size());
while (li.hasPrevious()) {
ExportOperationContextOperation operation = (ExportOperationContextOperation) li.previous();
if (operation != null && VnxExportOperationContext.OPERATION_ADD_VOLUMES_TO_STORAGE_GROUP.equals(operation.getOperation())) {
addedVolumes = (List<URI>) operation.getArgs().get(0);
_log.info("Removing volumes {} as part of rollback", Joiner.on(',').join(addedVolumes));
}
}
}
volumeURIList = addedVolumes;
if (volumeURIList == null || volumeURIList.isEmpty()) {
_log.info("There was no context found for add volumes. So there is nothing to rollback.");
taskCompleter.ready(_dbClient);
return;
}
}
if (null == volumeURIList || volumeURIList.isEmpty()) {
taskCompleter.ready(_dbClient);
_log.warn("{} removeVolumes invoked with zero volumes, resulting in no-op....", storage.getSerialNumber());
return;
}
ExportMask exportMask = _dbClient.queryObject(ExportMask.class, exportMaskURI);
ExportMaskValidationContext ctx = new ExportMaskValidationContext();
ctx.setStorage(storage);
ctx.setExportMask(exportMask);
ctx.setInitiators(initiatorList);
ctx.setAllowExceptions(!isRollback);
validator.removeVolumes(ctx).validate();
String[] volumeNames = null;
volumeNames = _helper.getBlockObjectAlternateNames(volumeURIList);
/**
* This extra condition makes sure ViPR do not pass null as volume name while invoking HidePaths.
* If we pass null into HidePaths call, SMI will remove the entire storage group and that will give DU.
*/
if (volumeNames == null || volumeNames.length == 0) {
_log.error("Volume's {} alternate name can not be null", volumeURIList);
ServiceError error = DeviceControllerException.errors.removeVolumeFromMaskFailed(volumeURIList.toString());
taskCompleter.error(_dbClient, error);
} else {
deleteOrShrinkStorageGroup(storage, exportMaskURI, volumeURIList, null);
taskCompleter.ready(_dbClient);
}
} catch (Exception e) {
_log.error("Unexpected error: removeVolumes failed.", e);
ServiceError error = DeviceControllerErrors.smis.methodFailed("removeVolumes", e.getMessage());
taskCompleter.error(_dbClient, error);
}
_log.info("{} removeVolumes END...", storage.getSerialNumber());
}
use of com.emc.storageos.volumecontroller.impl.validators.contexts.ExportMaskValidationContext in project coprhd-controller by CoprHD.
the class VNXeExportOperations method removeVolumes.
@Override
public void removeVolumes(StorageSystem storage, URI exportMaskUri, List<URI> volumes, List<Initiator> initiatorList, TaskCompleter taskCompleter) throws DeviceControllerException {
_logger.info("{} removeVolumes: START...", storage.getSerialNumber());
try {
_logger.info("removeVolumes: Export mask id: {}", exportMaskUri);
_logger.info("removeVolumes: volumes: {}", Joiner.on(',').join(volumes));
if (initiatorList != null) {
_logger.info("removeVolumes: impacted initiators: {}", Joiner.on(",").join(initiatorList));
}
boolean isRollback = WorkflowService.getInstance().isStepInRollbackState(taskCompleter.getOpId());
if (isRollback) {
List<URI> addedVolumes = new ArrayList<URI>();
// Get the context from the task completer, in case this is a rollback.
ExportOperationContext context = (ExportOperationContext) WorkflowService.getInstance().loadStepData(taskCompleter.getOpId());
if (context != null && context.getOperations() != null) {
_logger.info("Handling removeVolumes as a result of rollback");
ListIterator li = context.getOperations().listIterator(context.getOperations().size());
while (li.hasPrevious()) {
ExportOperationContextOperation operation = (ExportOperationContextOperation) li.previous();
if (operation != null & VNXeExportOperationContext.OPERATION_ADD_VOLUMES_TO_HOST_EXPORT.equals(operation.getOperation())) {
addedVolumes = (List<URI>) operation.getArgs().get(0);
_logger.info("Removing volumes {} as part of rollback", Joiner.on(',').join(addedVolumes));
}
}
}
volumes = addedVolumes;
if (volumes == null || volumes.isEmpty()) {
_logger.info("There was no context found for add volumes. So there is nothing to rollback.");
taskCompleter.ready(_dbClient);
return;
}
}
if (volumes == null || volumes.isEmpty()) {
taskCompleter.ready(_dbClient);
_logger.warn("{} removeVolumes invoked with zero volumes, resulting in no-op....", storage.getSerialNumber());
return;
}
ExportMask exportMask = _dbClient.queryObject(ExportMask.class, exportMaskUri);
if (exportMask == null || exportMask.getInactive()) {
throw new DeviceControllerException("Invalid ExportMask URI: " + exportMaskUri);
}
List<Initiator> initiators = ExportUtils.getExportMaskInitiators(exportMask, _dbClient);
VNXeApiClient apiClient = getVnxeClient(storage);
String hostId = getHostIdFromInitiators(initiators, apiClient);
if (hostId != null) {
ExportMaskValidationContext ctx = new ExportMaskValidationContext();
ctx.setStorage(storage);
ctx.setExportMask(exportMask);
ctx.setInitiators(initiatorList);
// Allow exceptions to be thrown when not rolling back
ctx.setAllowExceptions(!isRollback);
AbstractVNXeValidator removeVolumesValidator = (AbstractVNXeValidator) validator.removeVolumes(ctx);
removeVolumesValidator.setHostId(hostId);
removeVolumesValidator.validate();
}
String opId = taskCompleter.getOpId();
Set<String> processedCGs = new HashSet<String>();
StringMap volsMap = exportMask.getVolumes();
for (URI volUri : volumes) {
if (hostId != null && volsMap != null && !volsMap.isEmpty() && volsMap.keySet().contains(volUri.toString())) {
BlockObject blockObject = BlockObject.fetch(_dbClient, volUri);
// COP-25254 this method could be called when delete vplex volume created from snapshot. in this case
// the volume passed in is an internal volume, representing the snapshot. we need to find the snapshot
// with the same nativeGUID, then unexport the snapshot.
BlockObject snapshot = findSnapshotByInternalVolume(blockObject);
if (snapshot != null) {
blockObject = snapshot;
exportMask.removeVolume(volUri);
volUri = blockObject.getId();
}
String cgName = VNXeUtils.getBlockObjectCGName(blockObject, _dbClient);
if (cgName != null && !processedCGs.contains(cgName)) {
processedCGs.add(cgName);
VNXeUtils.getCGLock(workflowService, storage, cgName, opId);
}
String nativeId = blockObject.getNativeId();
if (URIUtil.isType(volUri, Volume.class)) {
apiClient.unexportLun(hostId, nativeId);
} else if (URIUtil.isType(volUri, BlockSnapshot.class)) {
apiClient.unexportSnap(hostId, nativeId);
setSnapWWN(apiClient, blockObject, nativeId);
}
}
// update the exportMask object
exportMask.removeVolume(volUri);
}
_dbClient.updateObject(exportMask);
taskCompleter.ready(_dbClient);
} catch (Exception e) {
_logger.error("Unexpected error: removeVolumes failed.", e);
ServiceError error = DeviceControllerErrors.vnxe.jobFailed("remove volumes failed", e.getMessage());
taskCompleter.error(_dbClient, error);
}
_logger.info("{} removeVolumes END...", storage.getSerialNumber());
}
Aggregations