Search in sources :

Example 1 with XtremIOInitiator

use of com.emc.storageos.xtremio.restapi.model.response.XtremIOInitiator in project coprhd-controller by CoprHD.

the class XtremIOExportMaskInitiatorsValidator method validate.

/**
 * Get list of initiators associated with the IG.
 *
 * a. If there are unknown initiators in IG, fail the operation
 * b. i) If Cluster export:
 * - - - If there are additional initiators other than the ones in ExportMask:
 * - - - check if all of them belong to different host but same cluster (Single IG with all cluster initiators)
 * - ii) Host export: Check additional initiators belong to same host or different host
 * - - -- If different host, fail the operation
 *
 * Reason for failing: We do not want to cause DU by choosing an operation when additional initiators
 * are present in the IG. Better fail the operation explaining the situation instead of resulting in DU.
 */
@Override
public boolean validate() throws Exception {
    log.info("Initiating initiators validation of XtremIO ExportMask: " + id);
    try {
        XtremIOClient client = XtremIOProvUtils.getXtremIOClient(getDbClient(), storage, getClientFactory());
        String xioClusterName = client.getClusterDetails(storage.getSerialNumber()).getName();
        if (knownInitiatorToIGMap == null) {
            knownInitiatorToIGMap = ArrayListMultimap.create();
        }
        // Don't validate against backing masks or RP
        if (ExportMaskUtils.isBackendExportMask(getDbClient(), exportMask)) {
            log.info("validation against backing mask for VPLEX or RP is disabled.");
            return true;
        }
        List<Initiator> knownInitiatorsInIGs = new ArrayList<Initiator>();
        List<String> allInitiatorsInIGs = new ArrayList<String>();
        List<XtremIOInitiator> initiators = client.getXtremIOInitiatorsInfo(xioClusterName);
        for (XtremIOInitiator initiator : initiators) {
            String igNameInInitiator = initiator.getInitiatorGroup().get(1);
            if (initiatorToIGMap.keySet().contains(igNameInInitiator)) {
                allInitiatorsInIGs.add(Initiator.normalizePort(initiator.getPortAddress()));
                Initiator knownInitiator = NetworkUtil.getInitiator(initiator.getPortAddress(), getDbClient());
                if (knownInitiator != null) {
                    knownInitiatorsInIGs.add(knownInitiator);
                    knownInitiatorToIGMap.put(igNameInInitiator, knownInitiator);
                }
            }
        }
        log.info("Initiators present in IG: {}", allInitiatorsInIGs);
        // Fail the operation if there are unknown initiators in the IG (not registered in ViPR)
        if (knownInitiatorsInIGs.size() < allInitiatorsInIGs.size()) {
            Collection<String> knownInitiatorNames = Collections2.transform(knownInitiatorsInIGs, CommonTransformerFunctions.fctnInitiatorToPortName());
            Set<String> differences = Sets.difference(Sets.newHashSet(allInitiatorsInIGs), Sets.newHashSet(knownInitiatorNames));
            for (String diff : differences) {
                getLogger().logDiff(exportMask.getId().toString(), "initiators", ValidatorLogger.NO_MATCHING_ENTRY, diff);
            }
            checkForErrors();
        }
        for (String igName : initiatorToIGMap.keySet()) {
            List<Initiator> requestedInitiatorsInIG = initiatorToIGMap.get(igName);
            List<Initiator> initiatorsInIG = knownInitiatorToIGMap.get(igName);
            String hostName = null;
            String clusterName = null;
            for (Initiator initiator : requestedInitiatorsInIG) {
                if (null != initiator.getHostName()) {
                    // initiators already grouped by Host
                    hostName = initiator.getHostName();
                    clusterName = initiator.getClusterName();
                    break;
                }
            }
            Collection<String> knownInitiators = Collections2.transform(Lists.newArrayList(initiatorsInIG), CommonTransformerFunctions.fctnInitiatorToPortName());
            Collection<String> requestedInitiators = Collections2.transform(requestedInitiatorsInIG, CommonTransformerFunctions.fctnInitiatorToPortName());
            log.info("Validation requested initiators: {}", requestedInitiators);
            log.info("Validation discovered initiators: {}", knownInitiators);
            knownInitiators.removeAll(requestedInitiators);
            log.info("Validation unknown initiators in IG: {}", knownInitiators);
            if (!knownInitiators.isEmpty()) {
                List<String> listToIgnore = new ArrayList<String>();
                log.info("There are other initiators present in the IG - {}. Checking if they all belong to same host or different host but same cluster.", knownInitiators);
                log.info("Host name: {}, Cluster name: {}", hostName, clusterName);
                // check if the other initiators belong to different host
                for (Initiator ini : initiatorsInIG) {
                    if (NullColumnValueGetter.isNotNullValue(clusterName) && ini.getHostName() != null && !ini.getHostName().equalsIgnoreCase(hostName)) {
                        // check if they belong to same cluster
                        if (ini.getClusterName() != null && clusterName != null && !clusterName.isEmpty() && ini.getClusterName().equalsIgnoreCase(clusterName)) {
                            listToIgnore.add(Initiator.normalizePort(ini.getInitiatorPort()));
                        }
                    } else if (ini.getHostName() != null && ini.getHostName().equalsIgnoreCase(hostName)) {
                        listToIgnore.add(Initiator.normalizePort(ini.getInitiatorPort()));
                    }
                }
                log.info("Validation initiators that belong to same host or cluster: {}", listToIgnore);
                knownInitiators.removeAll(listToIgnore);
                log.info("Validation remaining initiators that are not managed by controller: {}", knownInitiators);
                for (String knownInitiator : knownInitiators) {
                    getLogger().logDiff(exportMask.getId().toString(), "initiators", ValidatorLogger.NO_MATCHING_ENTRY, knownInitiator);
                }
            }
        }
    } catch (Exception ex) {
        log.error("Unexpected exception validating ExportMask initiators: " + ex.getMessage(), ex);
        if (getConfig().isValidationEnabled()) {
            throw DeviceControllerException.exceptions.unexpectedCondition("Unexpected exception validating ExportMask initiators: " + ex.getMessage());
        }
    }
    checkForErrors();
    log.info("Completed initiator validation of XtremIO ExportMask: " + id);
    return true;
}
Also used : Initiator(com.emc.storageos.db.client.model.Initiator) XtremIOInitiator(com.emc.storageos.xtremio.restapi.model.response.XtremIOInitiator) XtremIOClient(com.emc.storageos.xtremio.restapi.XtremIOClient) ArrayList(java.util.ArrayList) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) XtremIOInitiator(com.emc.storageos.xtremio.restapi.model.response.XtremIOInitiator)

Example 2 with XtremIOInitiator

use of com.emc.storageos.xtremio.restapi.model.response.XtremIOInitiator in project coprhd-controller by CoprHD.

the class XtremIOUnManagedVolumeDiscoverer method discoverUnmanagedExportMasks.

/**
 * Group existing known initiators by Host.
 * For each HostName in HostGroup
 * 1. Get List of IGs associated with Host
 * 2. For each IG, get unmanaged and managed volumes
 * 3. create/update mask with volumes/initiators/ports
 *
 * @param systemId
 * @param igUnmanagedVolumesMap IgName--Unmanaged volume list
 * @param igKnownVolumesMap IgName -- managed volume list
 * @param xtremIOClient
 * @param dbClient
 * @param partitionManager
 * @param volumeIGHLUMap
 * @throws Exception
 */
private void discoverUnmanagedExportMasks(URI systemId, Map<String, List<UnManagedVolume>> igUnmanagedVolumesMap, Map<String, StringSet> igKnownVolumesMap, XtremIOClient xtremIOClient, String xioClusterName, DbClient dbClient, PartitionManager partitionManager, Map<String, Map<String, Integer>> volumeIGHLUMap) throws Exception {
    unManagedExportMasksToCreate = new ArrayList<UnManagedExportMask>();
    unManagedExportMasksToUpdate = new ArrayList<UnManagedExportMask>();
    List<UnManagedVolume> unManagedExportVolumesToUpdate = new ArrayList<UnManagedVolume>();
    // In XtremIO, the volumes are exposed through all the storage ports.
    // Get all the storage ports of xtremIO to be added as known ports in the unmanaged export mask
    // If the host ports are FC, then all add all FC storage ports to the mask
    // else add all IP ports
    StringSet knownFCStoragePortUris = new StringSet();
    StringSet knownIPStoragePortUris = new StringSet();
    List<StoragePort> matchedFCPorts = new ArrayList<StoragePort>();
    URIQueryResultList storagePortURIs = new URIQueryResultList();
    dbClient.queryByConstraint(ContainmentConstraint.Factory.getStorageDeviceStoragePortConstraint(systemId), storagePortURIs);
    Iterator<URI> portsItr = storagePortURIs.iterator();
    while (portsItr.hasNext()) {
        URI storagePortURI = portsItr.next();
        StoragePort port = dbClient.queryObject(StoragePort.class, storagePortURI);
        if (TransportType.FC.toString().equals(port.getTransportType())) {
            knownFCStoragePortUris.add(storagePortURI.toString());
            matchedFCPorts.add(port);
        } else if (TransportType.IP.toString().equals(port.getTransportType())) {
            knownIPStoragePortUris.add(storagePortURI.toString());
        }
    }
    // Group all the initiators and their initiator groups based on ViPR host.
    // To be used for constructing unmanaged export masks
    Map<String, List<Initiator>> hostInitiatorsMap = new HashMap<String, List<Initiator>>();
    Map<String, Set<String>> hostIGNamesMap = new HashMap<String, Set<String>>();
    List<XtremIOInitiator> initiators = xtremIOClient.getXtremIOInitiatorsInfo(xioClusterName);
    for (XtremIOInitiator initiator : initiators) {
        String initiatorNetworkId = initiator.getPortAddress();
        // check if a host initiator exists for this id
        Initiator knownInitiator = NetworkUtil.getInitiator(initiatorNetworkId, dbClient);
        if (knownInitiator == null) {
            // TODO need to think of ways to handle unknown initiators
            continue;
        }
        // Special case for RP: group masks by cluster.
        String hostName = knownInitiator.checkInternalFlags(Flag.RECOVERPOINT) ? knownInitiator.getClusterName() : knownInitiator.getHostName();
        if (hostName != null && !hostName.isEmpty()) {
            log.info("   found an initiator in ViPR on host " + hostName);
            String igName = initiator.getInitiatorGroup().get(1);
            List<Initiator> hostInitiators = hostInitiatorsMap.get(hostName);
            Set<String> hostIGNames = hostIGNamesMap.get(hostName);
            if (hostInitiators == null) {
                hostInitiators = new ArrayList<Initiator>();
                hostInitiatorsMap.put(hostName, hostInitiators);
            }
            if (hostIGNames == null) {
                hostIGNames = new HashSet<String>();
                hostIGNamesMap.put(hostName, hostIGNames);
            }
            hostInitiators.add(knownInitiator);
            hostIGNames.add(igName);
        }
    }
    // create export mask per vipr host
    for (String hostname : hostInitiatorsMap.keySet()) {
        StringSet knownIniSet = new StringSet();
        StringSet knownNetworkIdSet = new StringSet();
        StringSet knownVolumeSet = new StringSet();
        List<Initiator> matchedFCInitiators = new ArrayList<Initiator>();
        List<Initiator> hostInitiators = hostInitiatorsMap.get(hostname);
        Set<String> hostIGs = hostIGNamesMap.get(hostname);
        Map<String, List<String>> rpVolumeSnapMap = new HashMap<String, List<String>>();
        Map<String, UnManagedVolume> rpVolumeMap = new HashMap<String, UnManagedVolume>();
        boolean isRpBackendMask = false;
        if (ExportUtils.checkIfInitiatorsForRP(hostInitiators)) {
            log.info("host {} contains RP initiators, " + "so this mask contains RP protected volumes", hostname);
            isRpBackendMask = true;
        }
        boolean isVplexBackendMask = false;
        for (Initiator hostInitiator : hostInitiators) {
            if (!isVplexBackendMask && VPlexControllerUtils.isVplexInitiator(hostInitiator, dbClient)) {
                log.info("host {} contains VPLEX backend ports, " + "so this mask contains VPLEX backend volumes", hostname);
                isVplexBackendMask = true;
            }
            knownIniSet.add(hostInitiator.getId().toString());
            knownNetworkIdSet.add(hostInitiator.getInitiatorPort());
            if (HostInterface.Protocol.FC.toString().equals(hostInitiator.getProtocol())) {
                matchedFCInitiators.add(hostInitiator);
            }
        }
        UnManagedExportMask mask = getUnManagedExportMask(hostInitiators.get(0).getInitiatorPort(), dbClient, systemId);
        mask.setStorageSystemUri(systemId);
        // set the host name as the mask name
        mask.setMaskName(hostname);
        allCurrentUnManagedExportMaskUris.add(mask.getId());
        for (String igName : hostIGs) {
            StringSet knownVols = igKnownVolumesMap.get(igName);
            if (knownVols != null) {
                knownVolumeSet.addAll(knownVols);
            }
            List<UnManagedVolume> hostUnManagedVols = igUnmanagedVolumesMap.get(igName);
            if (hostUnManagedVols != null) {
                for (UnManagedVolume hostUnManagedVol : hostUnManagedVols) {
                    hostUnManagedVol.getInitiatorNetworkIds().addAll(knownNetworkIdSet);
                    hostUnManagedVol.getInitiatorUris().addAll(knownIniSet);
                    hostUnManagedVol.getUnmanagedExportMasks().add(mask.getId().toString());
                    String nativeGuid = hostUnManagedVol.getNativeGuid();
                    Map<String, Integer> igHLUMap = volumeIGHLUMap.get(nativeGuid);
                    if (igHLUMap != null) {
                        Integer hlu = igHLUMap.get(igName);
                        if (hlu != null) {
                            StringSet hostHlu = new StringSet();
                            hostHlu.add(hostname + "=" + hlu);
                            StringSet existingHostHlu = (StringSet) hostUnManagedVol.getVolumeInformation().get(SupportedVolumeInformation.HLU_TO_EXPORT_MASK_NAME_MAP.toString());
                            if (existingHostHlu != null) {
                                hostHlu.addAll(existingHostHlu);
                            }
                            hostUnManagedVol.getVolumeInformation().put(SupportedVolumeInformation.HLU_TO_EXPORT_MASK_NAME_MAP.toString(), hostHlu);
                        }
                    }
                    if (isVplexBackendMask) {
                        log.info("marking unmanaged Xtremio volume {} as a VPLEX backend volume", hostUnManagedVol.getLabel());
                        hostUnManagedVol.putVolumeCharacterstics(SupportedVolumeCharacterstics.IS_VPLEX_BACKEND_VOLUME.toString(), TRUE);
                    }
                    // volume IS associated with RP, we want to mark that volume as RP enabled.
                    if (!isRpBackendMask) {
                        log.info("unmanaged volume {} is exported to something other than RP.  Marking IS_NONRP_EXPORTED.", hostUnManagedVol.forDisplay());
                        hostUnManagedVol.putVolumeCharacterstics(SupportedVolumeCharacterstics.IS_NONRP_EXPORTED.toString(), TRUE);
                    } else {
                        log.info("unmanaged volume {} is an RP volume", hostUnManagedVol.getLabel());
                        hostUnManagedVol.putVolumeCharacterstics(SupportedVolumeCharacterstics.IS_RECOVERPOINT_ENABLED.toString(), TRUE);
                        rpVolumeMap.put(hostUnManagedVol.getNativeGuid(), hostUnManagedVol);
                    }
                    if (hostUnManagedVol != null) {
                        mask.getUnmanagedVolumeUris().add(hostUnManagedVol.getId().toString());
                        unManagedExportVolumesToUpdate.add(hostUnManagedVol);
                    }
                }
            }
        }
        mask.replaceNewWithOldResources(knownIniSet, knownNetworkIdSet, knownVolumeSet, !matchedFCInitiators.isEmpty() ? knownFCStoragePortUris : knownIPStoragePortUris);
        updateZoningMap(mask, matchedFCInitiators, matchedFCPorts);
        if (!unManagedExportMasksToCreate.isEmpty()) {
            partitionManager.insertInBatches(unManagedExportMasksToCreate, Constants.DEFAULT_PARTITION_SIZE, dbClient, UNMANAGED_EXPORT_MASK);
            unManagedExportMasksToCreate.clear();
        }
        if (!unManagedExportMasksToUpdate.isEmpty()) {
            partitionManager.updateInBatches(unManagedExportMasksToUpdate, Constants.DEFAULT_PARTITION_SIZE, dbClient, UNMANAGED_EXPORT_MASK);
            unManagedExportMasksToUpdate.clear();
        }
        if (!unManagedExportVolumesToUpdate.isEmpty()) {
            partitionManager.updateAndReIndexInBatches(unManagedExportVolumesToUpdate, Constants.DEFAULT_PARTITION_SIZE, dbClient, UNMANAGED_VOLUME);
            unManagedExportVolumesToUpdate.clear();
        }
        DiscoveryUtils.markInActiveUnManagedExportMask(systemId, allCurrentUnManagedExportMaskUris, dbClient, partitionManager);
    }
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) StringSet(com.emc.storageos.db.client.model.StringSet) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) URI(java.net.URI) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) XtremIOInitiator(com.emc.storageos.xtremio.restapi.model.response.XtremIOInitiator) XtremIOInitiator(com.emc.storageos.xtremio.restapi.model.response.XtremIOInitiator) Initiator(com.emc.storageos.db.client.model.Initiator) StringSet(com.emc.storageos.db.client.model.StringSet) List(java.util.List) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) UnManagedExportMask(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedExportMask) StoragePort(com.emc.storageos.db.client.model.StoragePort) UnManagedVolume(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume)

Example 3 with XtremIOInitiator

use of com.emc.storageos.xtremio.restapi.model.response.XtremIOInitiator 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 4 with XtremIOInitiator

use of com.emc.storageos.xtremio.restapi.model.response.XtremIOInitiator in project coprhd-controller by CoprHD.

the class XtremIOExportOperations method refreshExportMask.

/*
     * Refresh all export masks, not only the one passed in
     * @see com.emc.storageos.volumecontroller.impl.smis.ExportMaskOperations#refreshExportMask(com.emc.storageos.db.client.model.StorageSystem, com.emc.storageos.db.client.model.ExportMask)
     */
@Override
public ExportMask refreshExportMask(StorageSystem storage, ExportMask mask) throws DeviceControllerException {
    ExportMask maskToReturn = null;
    try {
        _log.info("Refreshing volumes and initiator labels in ViPR.. ");
        XtremIOClient client = XtremIOProvUtils.getXtremIOClient(dbClient, storage, xtremioRestClientFactory);
        Set<String> igNameSet = new HashSet<>();
        Map<URI, Set<String>> maskToIGNameMap = new HashMap<>();
        String xioClusterName = client.getClusterDetails(storage.getSerialNumber()).getName();
        List<XtremIOInitiator> initiators = client.getXtremIOInitiatorsInfo(xioClusterName);
        List<Initiator> initiatorObjs = new ArrayList<Initiator>();
        for (XtremIOInitiator initiator : initiators) {
            URIQueryResultList initiatorResult = new URIQueryResultList();
            dbClient.queryByConstraint(AlternateIdConstraint.Factory.getInitiatorPortInitiatorConstraint(initiator.getPortAddress()), initiatorResult);
            if (initiatorResult.iterator().hasNext()) {
                Initiator initiatorObj = dbClient.queryObject(Initiator.class, initiatorResult.iterator().next());
                _log.info("Updating Initiator label from {} to {} in ViPR DB", initiatorObj.getLabel(), initiator.getName());
                initiatorObj.setLabel(initiator.getName());
                initiatorObj.mapInitiatorName(storage.getSerialNumber(), initiator.getName());
                initiatorObjs.add(initiatorObj);
                List<ExportMask> results = CustomQueryUtility.queryActiveResourcesByConstraint(dbClient, ExportMask.class, ContainmentConstraint.Factory.getConstraint(ExportMask.class, "initiators", initiatorObj.getId()));
                String igName = initiator.getInitiatorGroup().get(1);
                for (ExportMask exportMask : results) {
                    if (exportMask != null && storage.getId().equals(exportMask.getStorageDevice())) {
                        igNameSet.add(igName);
                        // update export mask to IG name map
                        URI maskId = exportMask.getId();
                        Set<String> igNames = maskToIGNameMap.get(maskId);
                        if (igNames == null) {
                            igNames = new HashSet<String>();
                            maskToIGNameMap.put(maskId, igNames);
                        }
                        igNames.add(igName);
                    }
                }
            } else {
                _log.info("No initiator objects in vipr db for port address {}", initiator.getPortAddress());
            }
        }
        if (!initiatorObjs.isEmpty()) {
            dbClient.updateObject(initiatorObjs);
        }
        // get volumes for each IG
        Map<String, Map<String, Integer>> igNameToVolMap = new HashMap<>();
        boolean bulkApiCallFlag = Boolean.valueOf(ControllerUtils.getPropertyValueFromCoordinator(coordinator, XTREMIO_BULK_API_CALL));
        Map<String, List<XtremIOVolume>> igNameToVolumesMap = new HashMap<>();
        _log.debug("Bulk API Flag", bulkApiCallFlag);
        _log.debug("XtremIO Firmware Version", storage.getFirmwareVersion());
        if (client.isVersion2() && XtremIOProvUtils.isBulkAPISupported(storage.getFirmwareVersion(), client) && bulkApiCallFlag) {
            long starttime = System.nanoTime();
            if (!igNameSet.isEmpty())
                igNameToVolumesMap = XtremIOProvUtils.getLunMapAndVolumes(igNameSet, xioClusterName, client, igNameToVolumesMap);
            _log.debug("Time taken for Bulk API Call : " + "total time = " + String.format("%2.6f", (System.nanoTime() - starttime) / 1000000000.0) + " seconds");
            for (Map.Entry<String, List<XtremIOVolume>> entry : igNameToVolumesMap.entrySet()) {
                Map<String, Integer> discoveredVolumesMap = new HashMap<String, Integer>();
                for (XtremIOVolume volume : entry.getValue()) {
                    for (List<Object> lunMapEntries : volume.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)) {
                            continue;
                        }
                        String igNameToProcess = (String) igDetails.get(1);
                        if (!entry.getKey().equalsIgnoreCase(igNameToProcess)) {
                            continue;
                        }
                        Double hluNumber = (Double) lunMapEntries.get(2);
                        _log.info("Found HLU {} for volume {}", hluNumber, volume.getVolInfo().get(1));
                        discoveredVolumesMap.put(volume.getWwn(), Integer.valueOf(hluNumber.intValue()));
                    }
                }
                igNameToVolMap.put(entry.getKey(), discoveredVolumesMap);
            }
            _log.debug("Time taken for All iteration in BulK API  : " + "total time = " + String.format("%2.6f", (System.nanoTime() - starttime) / 1000000000.0) + " seconds");
        } else {
            long totaltime = System.nanoTime();
            for (String igName : igNameSet) {
                Map<String, Integer> discoveredVolumes = new HashMap<String, Integer>();
                long starttime1 = System.nanoTime();
                List<XtremIOVolume> igVolumes = XtremIOProvUtils.getInitiatorGroupVolumes(igName, xioClusterName, client);
                _log.debug("Time taken for each ig name normal API Call : " + "total time = " + String.format("%2.6f", (System.nanoTime() - starttime1) / 1000000000.0) + " seconds");
                for (XtremIOVolume igVolume : igVolumes) {
                    for (List<Object> lunMapEntries : igVolume.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 or hlu is null in returned lun map response for volume {}", igVolume.toString());
                            continue;
                        }
                        String igNameToProcess = (String) igDetails.get(1);
                        if (!igName.equalsIgnoreCase(igNameToProcess)) {
                            continue;
                        }
                        Double hluNumber = (Double) lunMapEntries.get(2);
                        _log.info("Found HLU {} for volume {}", hluNumber, igVolume.getVolInfo().get(1));
                        // for each IG involved, the same volume is visible through different HLUs.
                        // TODO we might need a list of HLU for each Volume URI
                        discoveredVolumes.put(BlockObject.normalizeWWN(igVolume.getWwn()), Integer.valueOf(hluNumber.intValue()));
                    }
                }
                igNameToVolMap.put(igName, discoveredVolumes);
            }
            _log.debug("Time taken for all ig name normal API Call : " + "total time = " + String.format("%2.6f", (System.nanoTime() - totaltime) / 1000000000.0) + " seconds");
        }
        // update each mask
        for (Entry<URI, Set<String>> entry : maskToIGNameMap.entrySet()) {
            URI maskId = entry.getKey();
            ExportMask exportMask = dbClient.queryObject(ExportMask.class, maskId);
            if (exportMask == null || exportMask.getInactive()) {
                continue;
            }
            Map<String, Integer> discoveredVolumes = new HashMap<String, Integer>();
            for (String igName : entry.getValue()) {
                discoveredVolumes.putAll(igNameToVolMap.get(igName));
            }
            // Clear the existing volumes to update with the latest info
            if (exportMask.getExistingVolumes() != null && !exportMask.getExistingVolumes().isEmpty()) {
                exportMask.getExistingVolumes().clear();
            }
            // COP-27296 fix
            if (null == exportMask.getUserAddedVolumes()) {
                exportMask.setUserAddedVolumes(new StringMap());
            }
            // 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));
            }
            Set<URI> allRelatedVolumes = new HashSet<URI>();
            allRelatedVolumes.addAll(findAllRelatedExportMaskVolumesForInitiator(relatedInitiators, exportMask.getStorageDevice()));
            // If there are related volumes found, get the WWNs so we can diff against what has
            // been discovered on the array.
            Set<String> allRelatedVolumesWWN = new HashSet<String>();
            for (URI relatedVolumeURI : allRelatedVolumes) {
                BlockObject relatedObj = BlockObject.fetch(dbClient, relatedVolumeURI);
                if (relatedObj != null) {
                    allRelatedVolumesWWN.add(relatedObj.getWWN());
                }
            }
            Set<String> existingVolumes = Sets.difference(discoveredVolumes.keySet(), allRelatedVolumesWWN);
            _log.info(String.format("XtremIO discovered volumes: {%s}%n", Joiner.on(',').join(discoveredVolumes.keySet())));
            _log.info(String.format("%nXtremIO mask existing volumes: {%s}%n", Joiner.on(',').join(existingVolumes)));
            for (String wwn : existingVolumes) {
                exportMask.addToExistingVolumesIfAbsent(wwn, discoveredVolumes.get(wwn).toString());
            }
            // Update user added volume's HLU information in ExportMask and ExportGroup
            ExportMaskUtils.updateHLUsInExportMask(exportMask, discoveredVolumes, dbClient);
            dbClient.updateObject(exportMask);
            if (mask != null && maskId.equals(mask.getId())) {
                maskToReturn = exportMask;
            }
        }
    } catch (Exception e) {
        if (null != e.getMessage() && !e.getMessage().contains(XtremIOConstants.OBJECT_NOT_FOUND)) {
            String msg = String.format("Error when refreshing export masks for the system %s, details: %s", storage.forDisplay(), e.getMessage());
            throw XtremIOApiException.exceptions.refreshExistingMaskFailure(msg, e);
        } else {
            _log.warn("Error refreshing export masks for the system {}", storage.forDisplay());
        }
    }
    return maskToReturn;
}
Also used : StringMap(com.emc.storageos.db.client.model.StringMap) Set(java.util.Set) HashSet(java.util.HashSet) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) URI(java.net.URI) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) 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) 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) ExportMask(com.emc.storageos.db.client.model.ExportMask) XtremIOApiException(com.emc.storageos.xtremio.restapi.errorhandling.XtremIOApiException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) XtremIOClient(com.emc.storageos.xtremio.restapi.XtremIOClient) BlockObject(com.emc.storageos.db.client.model.BlockObject) Map(java.util.Map) HashMap(java.util.HashMap) StringMap(com.emc.storageos.db.client.model.StringMap) XtremIOLunMap(com.emc.storageos.xtremio.restapi.model.response.XtremIOLunMap)

Example 5 with XtremIOInitiator

use of com.emc.storageos.xtremio.restapi.model.response.XtremIOInitiator in project coprhd-controller by CoprHD.

the class XtremIOProvUtils method getIGNameForInitiator.

/**
 * @param initiator
 * @param storageSerialNumber
 * @param client
 * @param xioClusterName
 * @return
 * @throws Exception
 */
public static String getIGNameForInitiator(Initiator initiator, String storageSerialNumber, XtremIOClient client, String xioClusterName) throws Exception {
    String igName = null;
    String initiatorName = initiator.getMappedInitiatorName(storageSerialNumber);
    if (null != initiatorName) {
        // Get initiator by Name and find IG Group
        XtremIOInitiator initiatorObj = client.getInitiator(initiatorName, xioClusterName);
        if (null != initiatorObj) {
            igName = initiatorObj.getInitiatorGroup().get(1);
        }
    }
    return igName;
}
Also used : XtremIOInitiator(com.emc.storageos.xtremio.restapi.model.response.XtremIOInitiator)

Aggregations

XtremIOInitiator (com.emc.storageos.xtremio.restapi.model.response.XtremIOInitiator)11 XtremIOApiException (com.emc.storageos.xtremio.restapi.errorhandling.XtremIOApiException)7 URI (java.net.URI)7 ArrayList (java.util.ArrayList)7 Initiator (com.emc.storageos.db.client.model.Initiator)6 XtremIOClient (com.emc.storageos.xtremio.restapi.XtremIOClient)4 XtremIOInitiators (com.emc.storageos.xtremio.restapi.model.response.XtremIOInitiators)4 ClientResponse (com.sun.jersey.api.client.ClientResponse)4 HashSet (java.util.HashSet)4 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)3 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)3 HashMap (java.util.HashMap)3 List (java.util.List)3 Set (java.util.Set)3 BlockObject (com.emc.storageos.db.client.model.BlockObject)2 XtremIOInitiatorsInfo (com.emc.storageos.xtremio.restapi.model.response.XtremIOInitiatorsInfo)2 XtremIOObjectInfo (com.emc.storageos.xtremio.restapi.model.response.XtremIOObjectInfo)2 XtremIOVolume (com.emc.storageos.xtremio.restapi.model.response.XtremIOVolume)2 BlockSnapshot (com.emc.storageos.db.client.model.BlockSnapshot)1 ExportMask (com.emc.storageos.db.client.model.ExportMask)1