use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskRemoveInitiatorCompleter in project coprhd-controller by CoprHD.
the class AbstractDefaultMaskingOrchestrator method generateExportMaskRemoveInitiatorsWorkflow.
/**
* Generate workflow steps to remove initiators from an export mask
*
* @param workflow
* workflow
* @param previousStep
* previous step ID
* @param storage
* storage device
* @param exportGroup
* export group
* @param exportMask
* export mask
* @param volumeURIs
* volumes impacted by this operation
* @param initiatorURIs
* initiators
* @param removeTargets
* ports to remove
* @param completer
* completer
* @return step ID
* @throws Exception
*/
public String generateExportMaskRemoveInitiatorsWorkflow(Workflow workflow, String previousStep, StorageSystem storage, ExportGroup exportGroup, ExportMask exportMask, List<URI> volumeURIs, List<URI> initiatorURIs, boolean removeTargets, ExportTaskCompleter completer) throws Exception {
URI exportGroupURI = exportGroup.getId();
URI exportMaskURI = exportMask.getId();
URI storageURI = storage.getId();
String maskingStep = workflow.createStepId();
ExportTaskCompleter exportTaskCompleter = null;
if (completer != null) {
exportTaskCompleter = completer;
exportTaskCompleter.setOpId(maskingStep);
} else {
exportTaskCompleter = new ExportMaskRemoveInitiatorCompleter(exportGroupURI, exportMask.getId(), initiatorURIs, maskingStep);
}
Workflow.Method maskingExecuteMethod = new Workflow.Method("doExportGroupRemoveInitiators", storageURI, exportGroupURI, exportMaskURI, volumeURIs, initiatorURIs, removeTargets, exportTaskCompleter);
maskingStep = workflow.createStep(EXPORT_GROUP_MASKING_TASK, String.format("Removing initiators from %s (%s)", exportMask.getMaskName(), exportMask.getId().toString()), previousStep, storageURI, storage.getSystemType(), MaskingWorkflowEntryPoints.class, maskingExecuteMethod, null, maskingStep);
return maskingStep;
}
use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskRemoveInitiatorCompleter in project coprhd-controller by CoprHD.
the class VPlexDeviceController method storageViewAddInitiatorsRollback.
/**
* Rollback entry point. This is a wrapper around the exportRemoveInitiators
* 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 vplexURI
* [in] - StorageSystem URI
* @param exportGroupURI
* [in] - ExportGroup URI
* @param exportMaskURI
* [in] - ExportMask URI
* @param initiatorURIs
* [in] - List of Initiator URIs
* @param targetURIs
* [in] - List of storage port URIs
* @param rollbackContextKey
* [in] - context token
* @param token
* [in] - String token generated by the rollback processing
* @throws ControllerException
*/
public void storageViewAddInitiatorsRollback(URI vplexURI, URI exportGroupURI, URI exportMaskURI, List<URI> initiatorURIs, List<URI> targetURIs, String rollbackContextKey, String token) throws ControllerException {
ExportTaskCompleter taskCompleter = new ExportMaskRemoveInitiatorCompleter(exportGroupURI, exportMaskURI, initiatorURIs, token);
// in order to only perform rollback of operations we successfully performed.
try {
ExportOperationContext context = (ExportOperationContext) WorkflowService.getInstance().loadStepData(rollbackContextKey);
WorkflowService.getInstance().storeStepData(token, context);
} catch (ClassCastException e) {
_log.info("Step {} has stored step data other than ExportOperationContext. Exception: {}", token, e);
}
storageViewRemoveInitiators(vplexURI, exportGroupURI, exportMaskURI, initiatorURIs, targetURIs, taskCompleter, rollbackContextKey, token);
}
use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskRemoveInitiatorCompleter in project coprhd-controller by CoprHD.
the class XtremIOExportOperations method removeInitiators.
@Override
public void removeInitiators(StorageSystem storage, URI exportMaskURI, List<URI> volumeURIList, List<Initiator> initiators, List<URI> targets, TaskCompleter taskCompleter) throws DeviceControllerException {
_log.info("{} removeInitiators START...", storage.getSerialNumber());
boolean isRollback = WorkflowService.getInstance().isStepInRollbackState(taskCompleter.getOpId());
if (isRollback) {
_log.info("Handling removeInitiators as a result of rollback");
List<Initiator> addedInitiators = new ArrayList<Initiator>();
// Get the context from the task completer.
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 && XtremIOExportOperationContext.OPERATION_ADD_INITIATORS_TO_INITIATOR_GROUP.equals(operation.getOperation())) {
addedInitiators = (List<Initiator>) operation.getArgs().get(0);
_log.info("Removing initiators {} as part of rollback", Joiner.on(',').join(addedInitiators));
}
}
}
// Update the initiators in the task completer such that we update the export mask/group correctly
for (Initiator initiator : initiators) {
if (addedInitiators == null || !addedInitiators.contains(initiator)) {
((ExportMaskRemoveInitiatorCompleter) taskCompleter).removeInitiator(initiator.getId());
}
}
initiators = addedInitiators;
if (initiators == null || initiators.isEmpty()) {
_log.info("There was no context found for add initiator. So there is nothing to rollback.");
taskCompleter.ready(dbClient);
return;
}
}
ExportMask exportMask = dbClient.queryObject(ExportMask.class, exportMaskURI);
if (exportMask == null || exportMask.getInactive()) {
throw new DeviceControllerException("Invalid ExportMask URI: " + exportMaskURI);
}
XtremIOClient client = null;
// if host Name is not available in at least one of the initiator, then set it to
// Default_IG;
List<String> failedIGs = new ArrayList<String>();
ArrayListMultimap<String, Initiator> groupInitiatorsByIG = ArrayListMultimap.create();
try {
String hostName = null;
String clusterName = null;
client = XtremIOProvUtils.getXtremIOClient(dbClient, storage, xtremioRestClientFactory);
String xioClusterName = client.getClusterDetails(storage.getSerialNumber()).getName();
Iterator<Initiator> iniItr = initiators.iterator();
while (iniItr.hasNext()) {
Initiator initiator = iniItr.next();
String igName = null;
if (null != initiator.getHostName()) {
// initiators already grouped by Host
hostName = initiator.getHostName();
clusterName = initiator.getClusterName();
}
igName = XtremIOProvUtils.getIGNameForInitiator(initiator, storage.getSerialNumber(), client, xioClusterName);
if (igName != null && !igName.isEmpty()) {
groupInitiatorsByIG.put(igName, initiator);
} else {
// initiator not found in Array, remove from DB
exportMask.removeFromExistingInitiators(initiator);
exportMask.removeFromUserCreatedInitiators(initiator);
iniItr.remove();
}
}
// We need to look at all related initiators from the affected EM. We can use this list
// to then find all related volumes across all EMs. This will allow us to properly
// perform our validations.
List<Initiator> relatedInitiators = new ArrayList<Initiator>();
if (exportMask.getInitiators() != null && !exportMask.getInitiators().isEmpty()) {
Collection<URI> relatedInitiatorURIs = Collections2.transform(exportMask.getInitiators(), CommonTransformerFunctions.FCTN_STRING_TO_URI);
relatedInitiators.addAll(dbClient.queryObject(Initiator.class, relatedInitiatorURIs));
} else {
relatedInitiators.addAll(initiators);
}
Set<URI> allRelatedVolumes = new HashSet<URI>();
allRelatedVolumes.addAll(findAllRelatedExportMaskVolumesForInitiator(relatedInitiators, exportMask.getStorageDevice()));
_log.info("removeInitiators: Export mask id: {}", exportMaskURI);
if (!CollectionUtils.isEmpty(allRelatedVolumes)) {
_log.info("removeInitiators: volumes : {}", Joiner.on(',').join(allRelatedVolumes));
}
_log.info("removeInitiators: initiators : {}", Joiner.on(',').join(initiators));
_log.info("removeInitiators: targets : {}", Joiner.on(',').join(targets));
_log.info("List of IGs found {} with size : {}", Joiner.on(",").join(groupInitiatorsByIG.asMap().entrySet()), groupInitiatorsByIG.size());
ExportMaskValidationContext ctx = new ExportMaskValidationContext();
ctx.setStorage(storage);
ctx.setExportMask(exportMask);
ctx.setBlockObjects(allRelatedVolumes, dbClient);
ctx.setAllowExceptions(!isRollback);
XtremIOExportMaskVolumesValidator volumeValidator = (XtremIOExportMaskVolumesValidator) validator.removeInitiators(ctx);
volumeValidator.setIgNames(groupInitiatorsByIG.keySet());
volumeValidator.validate();
// lun map
for (Initiator initiator : initiators) {
try {
client.deleteInitiator(initiator.getMappedInitiatorName(storage.getSerialNumber()), xioClusterName);
exportMask.removeFromExistingInitiators(initiator);
exportMask.removeFromUserCreatedInitiators(initiator);
} catch (Exception e) {
failedIGs.add(initiator.getLabel().concat(XtremIOConstants.DASH).concat(e.getMessage()));
_log.warn("Removal of Initiator {} failed", initiator.getLabel(), e);
}
}
dbClient.updateObject(exportMask);
if (!failedIGs.isEmpty()) {
String errMsg = "Export Operations failed deleting these initiators: ".concat(Joiner.on(", ").join(failedIGs));
ServiceError serviceError = DeviceControllerException.errors.jobFailedMsg(errMsg, null);
taskCompleter.error(dbClient, serviceError);
return;
}
// Clean IGs if empty
deleteInitiatorGroup(groupInitiatorsByIG, client, xioClusterName);
// delete IG Folder as well if IGs are empty
deleteInitiatorGroupFolder(client, xioClusterName, clusterName, hostName, storage);
taskCompleter.ready(dbClient);
} catch (Exception ex) {
_log.error("Problem in removeInitiators: ", ex);
ServiceError serviceError = DeviceControllerErrors.xtremio.operationFailed("removeInitiators", ex.getMessage());
taskCompleter.error(dbClient, serviceError);
return;
}
_log.info("{} removeInitiators END...", storage.getSerialNumber());
}
use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskRemoveInitiatorCompleter in project coprhd-controller by CoprHD.
the class VmaxExportOperations method exportMaskRollback.
/**
* Export mask operation rollback method.
*
* @param storage
* storage device
* @param taskCompleter
* task completer
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
private void exportMaskRollback(StorageSystem storage, ExportOperationContext context, TaskCompleter taskCompleter) throws Exception {
// Go through each operation and roll it back.
if (context != null && context.getOperations() != null) {
WBEMClient client = _helper.getConnection(storage).getCimClient();
ListIterator li = context.getOperations().listIterator(context.getOperations().size());
while (li.hasPrevious()) {
ExportOperationContextOperation operation = (ExportOperationContextOperation) li.previous();
// Flag to indicate whether or not we need to use the EMCForce flag on this operation.
// We currently use this flag when dealing with RP Volumes as they are tagged for RP and the
// operation on these volumes would fail otherwise.
//
// IMPORTANT NOTE: Default is FALSE, each rollback method will need to determine if it should be set to
// true if it is needed.
boolean forceFlag = false;
try {
switch(operation.getOperation()) {
case VmaxExportOperationContext.OPERATION_ADD_INITIATORS_TO_INITIATOR_GROUP:
// remove initiators from the initiator group
List<Initiator> initiatorList = (List<Initiator>) operation.getArgs().get(0);
CIMObjectPath initiatorGroupPath = (CIMObjectPath) operation.getArgs().get(1);
CIMArgument[] inArgs = _helper.getRemoveInitiatorsFromMaskingGroupInputArguments(storage, initiatorGroupPath, initiatorList);
CIMArgument[] outArgs = new CIMArgument[5];
_helper.invokeMethodSynchronously(storage, _cimPath.getControllerConfigSvcPath(storage), "RemoveMembers", inArgs, outArgs, null);
break;
case VmaxExportOperationContext.OPERATION_ADD_INITIATOR_GROUPS_TO_INITIATOR_GROUP:
// remove initiator groups from cascaded initiator group
CIMObjectPath childInitiatorGroup = (CIMObjectPath) operation.getArgs().get(0);
CIMObjectPath parentInitiatorGroup = (CIMObjectPath) operation.getArgs().get(1);
inArgs = _helper.getRemoveIGFromCIG(childInitiatorGroup, parentInitiatorGroup);
outArgs = new CIMArgument[5];
_helper.invokeMethodSynchronously(storage, _cimPath.getControllerConfigSvcPath(storage), "RemoveMembers", inArgs, outArgs, null);
break;
case VmaxExportOperationContext.OPERATION_CREATE_CASCADING_STORAGE_GROUP:
case VmaxExportOperationContext.OPERATION_CREATE_STORAGE_GROUP:
// Delete storage group
String groupName = (String) operation.getArgs().get(0);
// .get(2) arg is different depending on the operation, but for now we don't need it so we
// won't get it.
_helper.deleteMaskingGroup(storage, groupName, SmisCommandHelper.MASKING_GROUP_TYPE.SE_DeviceMaskingGroup);
break;
case VmaxExportOperationContext.OPERATION_CREATE_PORT_GROUP:
// Delete port group
groupName = (String) operation.getArgs().get(0);
_helper.deleteMaskingGroup(storage, groupName, SmisCommandHelper.MASKING_GROUP_TYPE.SE_TargetMaskingGroup);
break;
case VmaxExportOperationContext.OPERATION_ADD_TIER_TO_STORAGE_GROUP:
// Remove tier policy from storage group
String policyName = (String) operation.getArgs().get(0);
CIMObjectPath[] volumeGroupPaths = (CIMObjectPath[]) operation.getArgs().get(1);
for (CIMObjectPath volumeGroupPath : volumeGroupPaths) {
_helper.removeVolumeGroupFromPolicyAndLimitsAssociation(client, storage, volumeGroupPath);
}
break;
case VmaxExportOperationContext.OPERATION_ADD_STORAGE_GROUP_TO_CASCADING_STORAGE_GROUP:
// Remove storage group from cascading storage group
groupName = (String) operation.getArgs().get(0);
forceFlag = (boolean) operation.getArgs().get(2);
CIMObjectPath[] volumeGroupPathList = (CIMObjectPath[]) operation.getArgs().get(1);
inArgs = _helper.modifyCascadedStorageGroupInputArguments(storage, groupName, volumeGroupPathList, forceFlag);
outArgs = new CIMArgument[5];
_helper.invokeMethodSynchronously(storage, _cimPath.getControllerConfigSvcPath(storage), "RemoveMembers", inArgs, outArgs, null);
break;
case VmaxExportOperationContext.OPERATION_CREATE_CASCADED_INITIATOR_GROUP:
case VmaxExportOperationContext.OPERATION_CREATE_INITIATOR_GROUP:
// Remove initiator group
groupName = (String) operation.getArgs().get(0);
_helper.deleteMaskingGroup(storage, groupName, SmisCommandHelper.MASKING_GROUP_TYPE.SE_InitiatorMaskingGroup);
break;
case VmaxExportOperationContext.OPERATION_CREATE_MASKING_VIEW:
// Remove masking view
String maskName = (String) operation.getArgs().get(0);
// Find the mask using the name
boolean foundMaskInDb = false;
ExportMask exportMask = null;
URIQueryResultList uriQueryList = new URIQueryResultList();
_dbClient.queryByConstraint(AlternateIdConstraint.Factory.getExportMaskByNameConstraint(maskName), uriQueryList);
while (uriQueryList.iterator().hasNext()) {
URI uri = uriQueryList.iterator().next();
exportMask = _dbClient.queryObject(ExportMask.class, uri);
if (exportMask != null && !exportMask.getInactive() && exportMask.getStorageDevice().equals(storage.getId())) {
foundMaskInDb = true;
// given name for any storage array.
break;
}
}
// If we have the mask, check to see if we need to use the force flag
if (foundMaskInDb) {
for (String volURI : exportMask.getUserAddedVolumes().values()) {
forceFlag = ExportUtils.useEMCForceFlag(_dbClient, URI.create(volURI));
if (forceFlag) {
break;
}
}
}
inArgs = _helper.getDeleteMaskingViewInputArguments(storage, maskName, forceFlag);
outArgs = new CIMArgument[5];
_helper.invokeMethodSynchronously(storage, _cimPath.getControllerConfigSvcPath(storage), "DeleteMaskingView", inArgs, outArgs, null);
break;
case VmaxExportOperationContext.OPERATION_ADD_PORTS_TO_PORT_GROUP:
// Remove ports from port group
groupName = (String) operation.getArgs().get(0);
List<URI> targetURIList = (List<URI>) operation.getArgs().get(1);
inArgs = _helper.getRemoveTargetPortsFromMaskingGroupInputArguments(storage, groupName, targetURIList);
outArgs = new CIMArgument[5];
_helper.invokeMethodSynchronously(storage, _cimPath.getControllerConfigSvcPath(storage), "RemoveMembers", inArgs, outArgs, null);
break;
case VmaxExportOperationContext.OPERATION_ADD_VOLUMES_TO_STORAGE_GROUP:
// Remove volumes from storage group
groupName = (String) operation.getArgs().get(0);
forceFlag = (boolean) operation.getArgs().get(2);
VolumeURIHLU[] volumeList = (VolumeURIHLU[]) operation.getArgs().get(1);
List<URI> volumesInSG = new ArrayList<>();
for (VolumeURIHLU volumeUriHlu : volumeList) {
volumesInSG.add(volumeUriHlu.getVolumeURI());
}
inArgs = _helper.getRemoveVolumesFromMaskingGroupInputArguments(storage, groupName, volumesInSG, forceFlag);
outArgs = new CIMArgument[5];
_helper.invokeMethodSynchronously(storage, _cimPath.getControllerConfigSvcPath(storage), "RemoveMembers", inArgs, outArgs, null);
break;
case VmaxExportOperationContext.OPERATION_ADD_EXISTING_INITIATOR_TO_EXPORT_GROUP:
URI initiator = (URI) operation.getArgs().get(0);
_log.info("Not removing initiator: {} because it already existed in the masking view", initiator);
// Ensure the task completer does not remove it from ViPR ExportMask/Group.
((ExportMaskRemoveInitiatorCompleter) taskCompleter).removeInitiator(initiator);
break;
default:
}
} catch (Exception e) {
_log.error("Exception caught while running rollback", e);
throw e;
}
}
}
}
use of com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskRemoveInitiatorCompleter in project coprhd-controller by CoprHD.
the class VNXeExportOperations method removeInitiators.
@Override
public void removeInitiators(StorageSystem storage, URI exportMask, List<URI> volumeURIList, List<Initiator> initiators, List<URI> targets, TaskCompleter taskCompleter) throws DeviceControllerException {
_logger.info("{} removeInitiators START...", storage.getSerialNumber());
ExportMask mask = _dbClient.queryObject(ExportMask.class, exportMask);
if (mask == null || mask.getInactive()) {
_logger.error(String.format("The exportMask %s is invalid.", exportMask));
throw DeviceControllerException.exceptions.invalidObjectNull();
}
boolean isRollback = WorkflowService.getInstance().isStepInRollbackState(taskCompleter.getOpId());
if (isRollback) {
List<Initiator> addedInitiators = new ArrayList<Initiator>();
// 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 removeInitiators 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_INITIATORS_TO_HOST.equals(operation.getOperation())) {
addedInitiators = (List<Initiator>) operation.getArgs().get(0);
_logger.info("Removing initiators {} as part of rollback", Joiner.on(',').join(addedInitiators));
}
}
}
// Update the initiators in the task completer such that we update the export mask/group correctly
for (Initiator initiator : initiators) {
if (addedInitiators == null || !addedInitiators.contains(initiator)) {
((ExportMaskRemoveInitiatorCompleter) taskCompleter).removeInitiator(initiator.getId());
}
}
initiators = addedInitiators;
if (initiators == null || initiators.isEmpty()) {
_logger.info("There was no context found for add initiator. So there is nothing to rollback.");
taskCompleter.ready(_dbClient);
return;
}
}
StringSet initiatorsInMask = mask.getInitiators();
List<Initiator> initiatorToBeRemoved = new ArrayList<>();
for (Initiator initiator : initiators) {
if (initiatorsInMask.contains(initiator.getId().toString())) {
initiatorToBeRemoved.add(initiator);
}
}
try {
VNXeApiClient apiClient = getVnxeClient(storage);
List<Initiator> allInitiators = ExportUtils.getExportMaskInitiators(exportMask, _dbClient);
String vnxeHostId = getHostIdFromInitiators(allInitiators, apiClient);
if (vnxeHostId != null) {
List<VNXeHostInitiator> vnxeInitiators = apiClient.getInitiatorsByHostId(vnxeHostId);
// initiators is a subset of allInitiators
Map<Initiator, VNXeHostInitiator> vnxeInitiatorsToBeRemoved = prepareInitiators(initiatorToBeRemoved);
Set<String> initiatorIds = new HashSet<String>();
for (VNXeHostInitiator vnxeInit : vnxeInitiators) {
initiatorIds.add(vnxeInit.getInitiatorId());
}
Set<String> initiatorsToBeRemoved = new HashSet<String>();
for (VNXeHostInitiator vnxeInit : vnxeInitiatorsToBeRemoved.values()) {
String initiatorId = vnxeInit.getId();
if (initiatorIds.remove(initiatorId)) {
initiatorsToBeRemoved.add(initiatorId);
}
}
ExportMaskValidationContext ctx = new ExportMaskValidationContext();
ctx.setStorage(storage);
ctx.setExportMask(mask);
ctx.setBlockObjects(volumeURIList, _dbClient);
// Allow exceptions to be thrown when not rolling back
ctx.setAllowExceptions(!isRollback);
AbstractVNXeValidator removeInitiatorsValidator = (AbstractVNXeValidator) validator.removeInitiators(ctx);
removeInitiatorsValidator.setHostId(vnxeHostId);
removeInitiatorsValidator.validate();
// 3. shared initiators, but all export masks have same set of initiators
if (!isRollback) {
boolean hasSharedInitiator = false;
for (Initiator initiator : initiatorToBeRemoved) {
if (ExportUtils.isInitiatorSharedByMasks(_dbClient, mask, initiator.getId())) {
hasSharedInitiator = true;
break;
}
}
if (hasSharedInitiator) {
validateAllMasks(_dbClient, mask, apiClient, vnxeHostId);
}
}
}
List<String> initiatorIdList = new ArrayList<>();
for (Initiator initiator : initiatorToBeRemoved) {
_logger.info("Processing initiator {}", initiator.getLabel());
if (vnxeHostId != null) {
String initiatorId = initiator.getInitiatorPort();
if (Protocol.FC.name().equals(initiator.getProtocol())) {
initiatorId = initiator.getInitiatorNode() + ":" + initiatorId;
}
initiatorIdList.add(initiatorId);
}
mask.removeFromExistingInitiators(initiator);
mask.removeFromUserCreatedInitiators(initiator);
}
if (!initiatorIdList.isEmpty()) {
apiClient.deleteInitiators(initiatorIdList);
}
_dbClient.updateObject(mask);
taskCompleter.ready(_dbClient);
} catch (Exception e) {
_logger.error("Problem in removeInitiators: ", e);
ServiceError serviceError = DeviceControllerErrors.vnxe.jobFailed("removeInitiator", e.getMessage());
taskCompleter.error(_dbClient, serviceError);
}
_logger.info("{} removeInitiators END...", storage.getSerialNumber());
}
Aggregations