Search in sources :

Example 1 with XtremIOExportMaskVolumesValidator

use of com.emc.storageos.volumecontroller.impl.validators.xtremio.XtremIOExportMaskVolumesValidator 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 2 with XtremIOExportMaskVolumesValidator

use of com.emc.storageos.volumecontroller.impl.validators.xtremio.XtremIOExportMaskVolumesValidator in project coprhd-controller by CoprHD.

the class XtremIOExportOperations method runLunMapDeletionOrRemoveInitiatorAlgorithm.

/**
 * It deletes the LunMap if the IG contains no other initiators than the requested ones.
 * Else it removes the requested initiators from the IG
 */
private void runLunMapDeletionOrRemoveInitiatorAlgorithm(StorageSystem storage, ExportMask exportMask, List<URI> volumes, List<Initiator> initiators, TaskCompleter taskCompleter) throws DeviceControllerException {
    // find LunMap associated with Volume
    // Then find initiatorGroup associated with this lun map
    XtremIOClient client = null;
    // Default_IG;
    try {
        String hostName = null;
        String clusterName = null;
        client = XtremIOProvUtils.getXtremIOClient(dbClient, storage, xtremioRestClientFactory);
        String xioClusterName = client.getClusterDetails(storage.getSerialNumber()).getName();
        boolean initiatorsOfRP = ExportUtils.checkIfInitiatorsForRP(initiators);
        for (Initiator initiator : initiators) {
            if (null != initiator.getHostName()) {
                // initiators already grouped by Host
                hostName = initiator.getHostName();
                clusterName = initiator.getClusterName();
                break;
            }
        }
        ArrayListMultimap<String, Initiator> groupInitiatorsByIG = XtremIOProvUtils.mapInitiatorToInitiatorGroup(storage.getSerialNumber(), initiators, null, xioClusterName, client);
        ArrayListMultimap<String, Initiator> knownInitiatorsToIGMap = ArrayListMultimap.create();
        // DU validations for removing volumes from IG.
        ExportMaskValidationContext ctx = new ExportMaskValidationContext();
        ctx.setStorage(storage);
        ctx.setExportMask(exportMask);
        ctx.setInitiators(initiators);
        ctx.setAllowExceptions(!WorkflowService.getInstance().isStepInRollbackState(taskCompleter.getOpId()));
        XtremIOExportMaskInitiatorsValidator initiatorsValidator = (XtremIOExportMaskInitiatorsValidator) validator.removeVolumes(ctx);
        initiatorsValidator.setInitiatorToIGMap(groupInitiatorsByIG);
        initiatorsValidator.setKnownInitiatorToIGMap(knownInitiatorsToIGMap);
        initiatorsValidator.validate();
        Set<String> igNames = groupInitiatorsByIG.keySet();
        List<String> failedVolumes = new ArrayList<String>();
        List<String> failedIGs = new ArrayList<String>();
        for (URI volumeUri : volumes) {
            BlockObject blockObj = BlockObject.fetch(dbClient, volumeUri);
            _log.info("Block Obj {} , wwn {}", blockObj.getId(), blockObj.getWWN());
            XtremIOVolume xtremIOVolume = null;
            if (URIUtil.isType(volumeUri, Volume.class)) {
                xtremIOVolume = XtremIOProvUtils.isVolumeAvailableInArray(client, blockObj.getDeviceLabel(), xioClusterName);
            } else {
                if (URIUtil.isType(volumeUri, BlockSnapshot.class) && BlockObject.checkForRP(dbClient, volumeUri)) {
                    // If the BlockObject is a BlockSnapshot of type RP (bookmark), there will be no exported
                    // snapshot. In this case, a target volume will have been exported and the deviceLabel of
                    // the BlockSnapshot reflects the name of that target.
                    _log.info(String.format("Dealing with a RecoverPoint bookmark lun mapping.  Checking to see if volume %s is available on array.", blockObj.getDeviceLabel()));
                    xtremIOVolume = XtremIOProvUtils.isVolumeAvailableInArray(client, blockObj.getDeviceLabel(), xioClusterName);
                } else {
                    xtremIOVolume = XtremIOProvUtils.isSnapAvailableInArray(client, blockObj.getDeviceLabel(), xioClusterName);
                }
            }
            if (null != xtremIOVolume) {
                // I need lun map id and igName
                // if iGName is available in the above group:
                _log.info("Volume Details {}", xtremIOVolume.toString());
                _log.info("Volume lunMap details {}", xtremIOVolume.getLunMaps().toString());
                // Lun Maps to delete
                Set<String> lunMaps = new HashSet<String>();
                boolean removeInitiator = false;
                String volId = xtremIOVolume.getVolInfo().get(2);
                if (xtremIOVolume.getLunMaps().isEmpty()) {
                    // handle scenarios where volumes gets unexported already
                    _log.info("Volume  {} doesn't have any existing export available on Array, unexported already.", xtremIOVolume.toString());
                    exportMask.removeFromUserCreatedVolumes(blockObj);
                    exportMask.removeVolume(blockObj.getId());
                    continue;
                }
                for (List<Object> lunMapEntries : xtremIOVolume.getLunMaps()) {
                    @SuppressWarnings("unchecked") List<Object> igDetails = (List<Object>) lunMapEntries.get(0);
                    String igName = (String) igDetails.get(1);
                    // IG details is actually transforming to a double by default, even though
                    // its modeled as List<String>
                    // hence this logic
                    Double IgIdDouble = (Double) igDetails.get(2);
                    String igId = String.valueOf(IgIdDouble.intValue());
                    _log.info("IG Name: {} Id: {} found in Lun Map", igName, igId);
                    if (!igNames.contains(igName)) {
                        _log.info("Volume is associated with IG {} which is not in the removal list requested, ignoring..", igName);
                        continue;
                    }
                    /**
                     * i) If Cluster export:
                     * If there are additional initiators other than the requested ones (Single IG with all cluster
                     * initiators)
                     * - - - remove initiator from IG,
                     * - - - Note: If initiators are of RP (CTRL-13622), always delete LunMap.
                     * - ii) Host export:
                     * - - -- delete LunMap
                     */
                    boolean igHasOtherHostInitiatorsOfSameCluster = knownInitiatorsToIGMap.get(igName).size() > groupInitiatorsByIG.get(igName).size();
                    if (!initiatorsOfRP && clusterName != null && igHasOtherHostInitiatorsOfSameCluster) {
                        removeInitiator = true;
                    }
                    if (!removeInitiator) {
                        // delete LunMap
                        @SuppressWarnings("unchecked") List<Object> tgtGroupDetails = (List<Object>) lunMapEntries.get(1);
                        Double tgIdDouble = (Double) tgtGroupDetails.get(2);
                        String tgtid = String.valueOf(tgIdDouble.intValue());
                        String lunMapId = volId.concat(XtremIOConstants.UNDERSCORE).concat(igId).concat(XtremIOConstants.UNDERSCORE).concat(tgtid);
                        _log.info("LunMap Id {} Found associated with Volume {}", lunMapId, blockObj.getDeviceLabel());
                        lunMaps.add(lunMapId);
                    }
                }
                // there will be only one lun map always
                for (String lunMap : lunMaps) {
                    try {
                        client.deleteLunMap(lunMap, xioClusterName);
                    } catch (Exception e) {
                        failedVolumes.add(volumeUri.toString().concat(XtremIOConstants.DASH).concat(e.getMessage()));
                        _log.warn("Deletion of Lun Map {} failed}", lunMap, e);
                    }
                }
                // remove initiator from IG
                if (removeInitiator) {
                    _log.info("Removing requested intiators from IG instead of deleting LunMap" + " as the IG contains other Host's initiators belonging to same Cluster.");
                    ctx = new ExportMaskValidationContext();
                    ctx.setStorage(storage);
                    ctx.setExportMask(exportMask);
                    ctx.setBlockObjects(volumes, dbClient);
                    ctx.setAllowExceptions(!WorkflowService.getInstance().isStepInRollbackState(taskCompleter.getOpId()));
                    // DU validation when removing initiators
                    XtremIOExportMaskVolumesValidator volumeValidator = (XtremIOExportMaskVolumesValidator) validator.removeInitiators(ctx);
                    volumeValidator.setIgNames(groupInitiatorsByIG.keySet());
                    volumeValidator.validate();
                    List<Initiator> initiatorsToBeRemoved = 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) {
                        ListIterator li = context.getOperations().listIterator(context.getOperations().size());
                        while (li.hasPrevious()) {
                            _log.info("Handling deleteExportMask as a result of rollback");
                            ExportOperationContextOperation operation = (ExportOperationContextOperation) li.previous();
                            if (operation != null && XtremIOExportOperationContext.OPERATION_ADD_INITIATORS_TO_INITIATOR_GROUP.equals(operation.getOperation())) {
                                initiatorsToBeRemoved = (List<Initiator>) operation.getArgs().get(0);
                                _log.info("Removing initiators {} as part of rollback", Joiner.on(',').join(initiatorsToBeRemoved));
                            }
                        }
                    } else {
                        initiatorsToBeRemoved = initiators;
                    }
                    // Deleting the initiator automatically removes the initiator from lun map
                    for (Initiator initiator : initiatorsToBeRemoved) {
                        try {
                            // check if Initiator has already been deleted during previous volume processing
                            String initiatorName = initiator.getMappedInitiatorName(storage.getSerialNumber());
                            XtremIOInitiator initiatorObj = client.getInitiator(initiatorName, xioClusterName);
                            if (null != initiatorObj) {
                                client.deleteInitiator(initiatorName, xioClusterName);
                            } else {
                                _log.info("Initiator {} already deleted", initiatorName);
                            }
                        } catch (Exception e) {
                            failedIGs.add(initiator.getLabel().concat(XtremIOConstants.DASH).concat(e.getMessage()));
                            _log.warn("Removal of Initiator {} from IG failed", initiator.getLabel(), e);
                        }
                    }
                }
            } else {
                exportMask.removeFromUserCreatedVolumes(blockObj);
                exportMask.removeVolume(blockObj.getId());
            }
        }
        dbClient.updateObject(exportMask);
        if (!failedVolumes.isEmpty()) {
            String errMsg = "Export Operations failed for these volumes: ".concat(Joiner.on(", ").join(failedVolumes));
            ServiceError serviceError = DeviceControllerException.errors.jobFailedMsg(errMsg, null);
            taskCompleter.error(dbClient, serviceError);
            return;
        }
        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 e) {
        _log.error(String.format("Export Operations failed - maskName: %s", exportMask.getId().toString()), e);
        ServiceError serviceError = DeviceControllerException.errors.jobFailed(e);
        taskCompleter.error(dbClient, serviceError);
    }
}
Also used : XtremIOExportMaskInitiatorsValidator(com.emc.storageos.volumecontroller.impl.validators.xtremio.XtremIOExportMaskInitiatorsValidator) ArrayList(java.util.ArrayList) URI(java.net.URI) XtremIOInitiator(com.emc.storageos.xtremio.restapi.model.response.XtremIOInitiator) XtremIOVolume(com.emc.storageos.xtremio.restapi.model.response.XtremIOVolume) 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) List(java.util.List) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) ExportOperationContextOperation(com.emc.storageos.volumecontroller.impl.utils.ExportOperationContext.ExportOperationContextOperation) BlockObject(com.emc.storageos.db.client.model.BlockObject) HashSet(java.util.HashSet) ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) XtremIOExportMaskVolumesValidator(com.emc.storageos.volumecontroller.impl.validators.xtremio.XtremIOExportMaskVolumesValidator) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) ListIterator(java.util.ListIterator) XtremIOApiException(com.emc.storageos.xtremio.restapi.errorhandling.XtremIOApiException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) ExportMaskValidationContext(com.emc.storageos.volumecontroller.impl.validators.contexts.ExportMaskValidationContext) XtremIOClient(com.emc.storageos.xtremio.restapi.XtremIOClient) BlockObject(com.emc.storageos.db.client.model.BlockObject)

Example 3 with XtremIOExportMaskVolumesValidator

use of com.emc.storageos.volumecontroller.impl.validators.xtremio.XtremIOExportMaskVolumesValidator in project coprhd-controller by CoprHD.

the class XtremIOExportOperations method addInitiators.

@Override
public void addInitiators(StorageSystem storage, URI exportMaskURI, List<URI> volumeURIs, List<Initiator> initiators, List<URI> targets, TaskCompleter taskCompleter) throws DeviceControllerException {
    _log.info("{} addInitiators START...", storage.getSerialNumber());
    try {
        _log.info("addInitiators: Export mask id: {}", exportMaskURI);
        if (volumeURIs != null) {
            _log.info("addInitiators: volumes : {}", Joiner.on(',').join(volumeURIs));
        }
        _log.info("addInitiators: initiators : {}", Joiner.on(',').join(initiators));
        _log.info("addInitiators: targets : {}", Joiner.on(",").join(targets));
        ExportOperationContext context = new XtremIOExportOperationContext();
        // Prime the context object
        taskCompleter.updateWorkflowStepContext(context);
        ExportMask exportMask = dbClient.queryObject(ExportMask.class, exportMaskURI);
        if (exportMask == null || exportMask.getInactive()) {
            throw new DeviceControllerException("Invalid ExportMask URI: " + exportMaskURI);
        }
        XtremIOClient client = XtremIOProvUtils.getXtremIOClient(dbClient, storage, xtremioRestClientFactory);
        String xioClusterName = client.getClusterDetails(storage.getSerialNumber()).getName();
        List<Initiator> initiatorsToBeCreated = new ArrayList<Initiator>();
        ArrayListMultimap<String, Initiator> initiatorToIGMap = XtremIOProvUtils.mapInitiatorToInitiatorGroup(storage.getSerialNumber(), initiators, initiatorsToBeCreated, xioClusterName, client);
        XtremIOExportMaskVolumesValidator volumeValidator = (XtremIOExportMaskVolumesValidator) validator.addInitiators(storage, exportMask, volumeURIs);
        volumeValidator.setIgNames(initiatorToIGMap.keySet());
        volumeValidator.validate();
        Map<URI, Integer> map = new HashMap<URI, Integer>();
        for (URI volumeURI : volumeURIs) {
            String hlu = exportMask.getVolumes().get(volumeURI.toString());
            if (NullColumnValueGetter.isNotNullValue(hlu)) {
                map.put(volumeURI, Integer.parseInt(hlu));
            }
        }
        // to make it uniform , using these structures
        VolumeURIHLU[] volumeLunArray = ControllerUtils.getVolumeURIHLUArray(storage.getSystemType(), map, dbClient);
        runLunMapCreationAlgorithm(storage, exportMask, volumeLunArray, initiators, targets, client, xioClusterName, initiatorToIGMap, initiatorsToBeCreated, taskCompleter);
    } catch (final Exception ex) {
        _log.error("Problem in addInitiators: ", ex);
        ServiceError serviceError = DeviceControllerErrors.xtremio.operationFailed("addInitiators", ex.getMessage());
        taskCompleter.error(dbClient, serviceError);
    }
    _log.info("{} addInitiators END...", storage.getSerialNumber());
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) XtremIOExportMaskVolumesValidator(com.emc.storageos.volumecontroller.impl.validators.xtremio.XtremIOExportMaskVolumesValidator) HashMap(java.util.HashMap) ExportMask(com.emc.storageos.db.client.model.ExportMask) ArrayList(java.util.ArrayList) URI(java.net.URI) XtremIOApiException(com.emc.storageos.xtremio.restapi.errorhandling.XtremIOApiException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) 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) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) VolumeURIHLU(com.emc.storageos.volumecontroller.impl.VolumeURIHLU)

Example 4 with XtremIOExportMaskVolumesValidator

use of com.emc.storageos.volumecontroller.impl.validators.xtremio.XtremIOExportMaskVolumesValidator in project coprhd-controller by CoprHD.

the class XtremIOExportOperations method runLunMapCreationAlgorithm.

private void runLunMapCreationAlgorithm(StorageSystem storage, ExportMask exportMask, VolumeURIHLU[] volumeURIHLUs, List<Initiator> initiators, List<URI> targets, XtremIOClient client, String xioClusterName, ArrayListMultimap<String, Initiator> initiatorToIGMap, List<Initiator> initiatorsToBeCreated, TaskCompleter taskCompleter) throws DeviceControllerException {
    Set<String> igNames = null;
    List<URI> mappedVolumes = new ArrayList<URI>();
    // Default_IG;
    try {
        String hostName = null;
        String clusterName = null;
        _log.info("Finding re-usable IGs available on Array {}", storage.getNativeGuid());
        List<URI> initiatorIds = new ArrayList<>();
        for (Initiator initiator : initiators) {
            initiatorIds.add(initiator.getId());
            if (null != initiator.getHostName()) {
                // initiators already grouped by Host
                hostName = initiator.getHostName();
                clusterName = initiator.getClusterName();
                break;
            }
        }
        // since we're reusing existing IGs, volumes might get exposed to other initiators in
        // IG.
        // for initiators without label, create IGs and add them to a host folder by name
        // initiator.getHost() in cases ,where initiator.getLabel() is not present, we try
        // creating IG, if fails
        // then we consider that it's already created
        igNames = new HashSet<String>();
        igNames.addAll(initiatorToIGMap.keySet());
        if (initiatorsToBeCreated != null && !initiatorsToBeCreated.isEmpty()) {
            // create new initiator and add to IG; add IG to IG folder
            addInitiatorToInitiatorGroup(client, xioClusterName, clusterName, hostName, initiatorsToBeCreated, igNames, exportMask, storage, taskCompleter);
            List<URI> volumeURIs = new ArrayList<URI>();
            for (VolumeURIHLU volURIHLU : volumeURIHLUs) {
                volumeURIs.add(volURIHLU.getVolumeURI());
            }
            XtremIOExportMaskVolumesValidator volumeValidator = (XtremIOExportMaskVolumesValidator) validator.addInitiators(storage, exportMask, volumeURIs);
            volumeValidator.setIgNames(initiatorToIGMap.keySet());
            volumeValidator.validate();
        }
        if (igNames.isEmpty()) {
            ServiceError serviceError = DeviceControllerException.errors.xtremioInitiatorGroupsNotDetected(storage.getNativeGuid());
            taskCompleter.error(dbClient, serviceError);
            return;
        }
        // Small block of declarations/initializations to assist with vblock boot volume check in below block.
        Set<String> vblockConflictIgNames = new HashSet<>();
        Map<URI, Integer> volumeMap = new HashMap<>();
        for (VolumeURIHLU volumeIdHlu : volumeURIHLUs) {
            volumeMap.put(volumeIdHlu.getVolumeURI(), Integer.valueOf(volumeIdHlu.getHLU()));
        }
        // Check for volumes which are already mapped to the IG. We do not need to create lun map for them.
        ArrayListMultimap<String, String> volumesToIGMap = ArrayListMultimap.create();
        for (String igName : igNames) {
            List<XtremIOVolume> igVols = XtremIOProvUtils.getInitiatorGroupVolumes(igName, xioClusterName, client);
            for (XtremIOVolume igVolume : igVols) {
                volumesToIGMap.put(igName, igVolume.getVolInfo().get(1));
                /**
                 * COP-28674: During Vblock Boot volume export, if existing masking views are found then check for existing volumes
                 * If found throw exception. This condition is valid only for boot volume vblock export.
                 */
                if (ExportMaskUtils.isVblockHost(initiatorIds, dbClient) && ExportMaskUtils.isBootVolume(dbClient, volumeMap)) {
                    _log.error(String.format("VBlock boot volume Export: found existing IG (%s) with volumes in it on %s.", igName, storage.getNativeGuid()));
                    vblockConflictIgNames.add(igName);
                }
            }
        }
        // error for the customer.
        if (!vblockConflictIgNames.isEmpty()) {
            ServiceError serviceError = DeviceControllerException.errors.existingMaskFoundDuringBootVolumeExportXio(Joiner.on(',').join(vblockConflictIgNames), hostName);
            taskCompleter.error(dbClient, serviceError);
            return;
        }
        InvokeTestFailure.internalOnlyInvokeTestFailure(InvokeTestFailure.ARTIFICIAL_FAILURE_052);
        // create Lun Maps
        for (VolumeURIHLU volURIHLU : volumeURIHLUs) {
            BlockObject blockObj = BlockObject.fetch(dbClient, volURIHLU.getVolumeURI());
            String hluValue = volURIHLU.getHLU().equalsIgnoreCase(ExportGroup.LUN_UNASSIGNED_STR) ? "-1" : volURIHLU.getHLU();
            _log.info("HLU value {}", hluValue);
            for (String igName : igNames) {
                List<String> igVols = volumesToIGMap.get(igName);
                if (igVols != null && !igVols.contains(blockObj.getDeviceLabel())) {
                    // Create lun map
                    _log.info("Creating Lun Map for  Volume {} using IG {}", blockObj.getDeviceLabel(), igName);
                    client.createLunMap(blockObj.getDeviceLabel(), igName, hluValue, xioClusterName);
                    mappedVolumes.add(blockObj.getId());
                }
            }
        }
        // post process created lun maps
        for (VolumeURIHLU volURIHLU : volumeURIHLUs) {
            BlockObject blockObj = BlockObject.fetch(dbClient, volURIHLU.getVolumeURI());
            Integer hluNumberFound = 0;
            // get volume/snap details again and populate wwn and hlu
            XtremIOVolume xtremIOVolume = null;
            String deviceName = blockObj.getDeviceLabel();
            xtremIOVolume = XtremIOProvUtils.isVolumeAvailableInArray(client, deviceName, xioClusterName);
            // COP-19828: If we can't find a volume by the given name, try to find a snap with the given name
            if (xtremIOVolume == null) {
                xtremIOVolume = XtremIOProvUtils.isSnapAvailableInArray(client, deviceName, xioClusterName);
            }
            if (xtremIOVolume != null) {
                _log.info("Volume lunMap details Found {}", xtremIOVolume.getLunMaps().toString());
                if (!xtremIOVolume.getWwn().isEmpty()) {
                    blockObj.setWWN(xtremIOVolume.getWwn());
                    blockObj.setNativeId(xtremIOVolume.getWwn());
                    dbClient.updateObject(blockObj);
                }
                for (String igName : igNames) {
                    for (List<Object> lunMapEntries : xtremIOVolume.getLunMaps()) {
                        @SuppressWarnings("unchecked") List<Object> // This can't be null
                        igDetails = (List<Object>) lunMapEntries.get(0);
                        if (null == igDetails.get(1) || null == lunMapEntries.get(2)) {
                            _log.warn("IG Name is null in returned lun map response for volume {}", xtremIOVolume.toString());
                            continue;
                        }
                        String igNameToProcess = (String) igDetails.get(1);
                        _log.info("IG Name: {} found in Lun Map", igNameToProcess);
                        if (!igName.equalsIgnoreCase(igNameToProcess)) {
                            _log.info("Volume is associated with IG {} which is not in the expected list requested, ignoring..", igNameToProcess);
                            continue;
                        }
                        Double hluNumber = (Double) lunMapEntries.get(2);
                        _log.info("Found HLU {} for volume {}", hluNumber, blockObj.getDeviceLabel());
                        // for each IG involved, the same volume is visible thro different HLUs.
                        // TODO we might need a list of HLU for each Volume URI
                        hluNumberFound = hluNumber.intValue();
                        exportMask.addVolume(blockObj.getId(), hluNumberFound);
                        exportMask.addToUserCreatedVolumes(blockObj);
                    }
                }
            }
        }
        InvokeTestFailure.internalOnlyInvokeTestFailure(InvokeTestFailure.ARTIFICIAL_FAILURE_053);
        ExportOperationContext.insertContextOperation(taskCompleter, XtremIOExportOperationContext.OPERATION_ADD_VOLUMES_TO_INITIATOR_GROUP, mappedVolumes);
        _log.info("Updated Volumes with HLUs {} after successful export", Joiner.on(",").join(exportMask.getVolumes().entrySet()));
        dbClient.updateObject(exportMask);
        // Test mechanism to invoke a failure. No-op on production systems.
        InvokeTestFailure.internalOnlyInvokeTestFailure(InvokeTestFailure.ARTIFICIAL_FAILURE_003);
        InvokeTestFailure.internalOnlyInvokeTestFailure(InvokeTestFailure.ARTIFICIAL_FAILURE_002);
        taskCompleter.ready(dbClient);
    } catch (Exception e) {
        _log.error(String.format("Export Operations failed - maskName: %s", exportMask.getId().toString()), e);
        ServiceError serviceError = DeviceControllerException.errors.jobFailed(e);
        taskCompleter.error(dbClient, serviceError);
    }
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) URI(java.net.URI) XtremIOVolume(com.emc.storageos.xtremio.restapi.model.response.XtremIOVolume) XtremIOInitiator(com.emc.storageos.xtremio.restapi.model.response.XtremIOInitiator) Initiator(com.emc.storageos.db.client.model.Initiator) List(java.util.List) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) BlockObject(com.emc.storageos.db.client.model.BlockObject) HashSet(java.util.HashSet) ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) XtremIOExportMaskVolumesValidator(com.emc.storageos.volumecontroller.impl.validators.xtremio.XtremIOExportMaskVolumesValidator) XtremIOApiException(com.emc.storageos.xtremio.restapi.errorhandling.XtremIOApiException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) BlockObject(com.emc.storageos.db.client.model.BlockObject) VolumeURIHLU(com.emc.storageos.volumecontroller.impl.VolumeURIHLU)

Aggregations

Initiator (com.emc.storageos.db.client.model.Initiator)4 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)4 ServiceError (com.emc.storageos.svcs.errorhandling.model.ServiceError)4 XtremIOExportMaskVolumesValidator (com.emc.storageos.volumecontroller.impl.validators.xtremio.XtremIOExportMaskVolumesValidator)4 XtremIOApiException (com.emc.storageos.xtremio.restapi.errorhandling.XtremIOApiException)4 XtremIOInitiator (com.emc.storageos.xtremio.restapi.model.response.XtremIOInitiator)4 URI (java.net.URI)4 ArrayList (java.util.ArrayList)4 ExportOperationContext (com.emc.storageos.volumecontroller.impl.utils.ExportOperationContext)3 XtremIOClient (com.emc.storageos.xtremio.restapi.XtremIOClient)3 HashSet (java.util.HashSet)3 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)2 BlockObject (com.emc.storageos.db.client.model.BlockObject)2 ExportMask (com.emc.storageos.db.client.model.ExportMask)2 VolumeURIHLU (com.emc.storageos.volumecontroller.impl.VolumeURIHLU)2 ExportOperationContextOperation (com.emc.storageos.volumecontroller.impl.utils.ExportOperationContext.ExportOperationContextOperation)2 ExportMaskValidationContext (com.emc.storageos.volumecontroller.impl.validators.contexts.ExportMaskValidationContext)2 XtremIOVolume (com.emc.storageos.xtremio.restapi.model.response.XtremIOVolume)2 HashMap (java.util.HashMap)2 List (java.util.List)2