Search in sources :

Example 1 with ExportMaskRemoveInitiatorCompleter

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;
}
Also used : ExportTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportTaskCompleter) Workflow(com.emc.storageos.workflow.Workflow) URI(java.net.URI) ExportMaskRemoveInitiatorCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskRemoveInitiatorCompleter)

Example 2 with ExportMaskRemoveInitiatorCompleter

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);
}
Also used : ExportTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportTaskCompleter) ExportOperationContext(com.emc.storageos.volumecontroller.impl.utils.ExportOperationContext) ExportMaskRemoveInitiatorCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskRemoveInitiatorCompleter)

Example 3 with ExportMaskRemoveInitiatorCompleter

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());
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) XtremIOExportMaskVolumesValidator(com.emc.storageos.volumecontroller.impl.validators.xtremio.XtremIOExportMaskVolumesValidator) ExportMask(com.emc.storageos.db.client.model.ExportMask) ArrayList(java.util.ArrayList) ListIterator(java.util.ListIterator) ExportMaskRemoveInitiatorCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskRemoveInitiatorCompleter) URI(java.net.URI) XtremIOApiException(com.emc.storageos.xtremio.restapi.errorhandling.XtremIOApiException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) ExportMaskValidationContext(com.emc.storageos.volumecontroller.impl.validators.contexts.ExportMaskValidationContext) XtremIOInitiator(com.emc.storageos.xtremio.restapi.model.response.XtremIOInitiator) Initiator(com.emc.storageos.db.client.model.Initiator) ExportOperationContext(com.emc.storageos.volumecontroller.impl.utils.ExportOperationContext) XtremIOClient(com.emc.storageos.xtremio.restapi.XtremIOClient) ExportOperationContextOperation(com.emc.storageos.volumecontroller.impl.utils.ExportOperationContext.ExportOperationContextOperation) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) HashSet(java.util.HashSet)

Example 4 with ExportMaskRemoveInitiatorCompleter

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;
            }
        }
    }
}
Also used : ExportMask(com.emc.storageos.db.client.model.ExportMask) CIMObjectPath(javax.cim.CIMObjectPath) ArrayList(java.util.ArrayList) ListIterator(java.util.ListIterator) URI(java.net.URI) ExportMaskRemoveInitiatorCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskRemoveInitiatorCompleter) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) SmisException(com.emc.storageos.volumecontroller.impl.smis.SmisException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) WBEMException(javax.wbem.WBEMException) Initiator(com.emc.storageos.db.client.model.Initiator) ExportOperationContextOperation(com.emc.storageos.volumecontroller.impl.utils.ExportOperationContext.ExportOperationContextOperation) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) List(java.util.List) WBEMClient(javax.wbem.client.WBEMClient) CIMArgument(javax.cim.CIMArgument) VolumeURIHLU(com.emc.storageos.volumecontroller.impl.VolumeURIHLU)

Example 5 with ExportMaskRemoveInitiatorCompleter

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());
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) VNXeApiClient(com.emc.storageos.vnxe.VNXeApiClient) ExportMask(com.emc.storageos.db.client.model.ExportMask) ArrayList(java.util.ArrayList) ListIterator(java.util.ListIterator) VNXeHostInitiator(com.emc.storageos.vnxe.models.VNXeHostInitiator) ExportMaskRemoveInitiatorCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskRemoveInitiatorCompleter) VNXeException(com.emc.storageos.vnxe.VNXeException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) ExportMaskValidationContext(com.emc.storageos.volumecontroller.impl.validators.contexts.ExportMaskValidationContext) AbstractVNXeValidator(com.emc.storageos.volumecontroller.impl.validators.vnxe.AbstractVNXeValidator) Initiator(com.emc.storageos.db.client.model.Initiator) VNXeHostInitiator(com.emc.storageos.vnxe.models.VNXeHostInitiator) ExportOperationContext(com.emc.storageos.volumecontroller.impl.utils.ExportOperationContext) StringSet(com.emc.storageos.db.client.model.StringSet) ExportOperationContextOperation(com.emc.storageos.volumecontroller.impl.utils.ExportOperationContext.ExportOperationContextOperation) HashSet(java.util.HashSet)

Aggregations

ExportMaskRemoveInitiatorCompleter (com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportMaskRemoveInitiatorCompleter)9 ExportMask (com.emc.storageos.db.client.model.ExportMask)6 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)6 ExportOperationContext (com.emc.storageos.volumecontroller.impl.utils.ExportOperationContext)6 URI (java.net.URI)6 ArrayList (java.util.ArrayList)6 Initiator (com.emc.storageos.db.client.model.Initiator)5 ServiceError (com.emc.storageos.svcs.errorhandling.model.ServiceError)5 ExportOperationContextOperation (com.emc.storageos.volumecontroller.impl.utils.ExportOperationContext.ExportOperationContextOperation)5 ExportTaskCompleter (com.emc.storageos.volumecontroller.impl.block.taskcompleter.ExportTaskCompleter)4 ExportMaskValidationContext (com.emc.storageos.volumecontroller.impl.validators.contexts.ExportMaskValidationContext)4 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)3 HashSet (java.util.HashSet)3 ListIterator (java.util.ListIterator)3 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)2 ExportGroup (com.emc.storageos.db.client.model.ExportGroup)2 NamedURI (com.emc.storageos.db.client.model.NamedURI)2 StoragePort (com.emc.storageos.db.client.model.StoragePort)2 StringSet (com.emc.storageos.db.client.model.StringSet)2 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)2