Search in sources :

Example 16 with VolumeURIHLU

use of com.emc.storageos.volumecontroller.impl.VolumeURIHLU in project coprhd-controller by CoprHD.

the class XIVRestOperationsHelper method addVolumesUsingREST.

/**
 * Adds volumes to an export mask
 *
 * @param storage
 *            Storage system instance
 * @param exportMaskURI
 *            Export mask URI
 * @param volumeURIHLUs
 *            Volume to be added URI
 * @param initiatorList
 *            initiators to be valiated against for this operation
 * @param taskCompleter
 *            task completer instance
 */
public void addVolumesUsingREST(StorageSystem storage, URI exportMaskURI, VolumeURIHLU[] volumeURIHLUs, List<Initiator> initiatorList, TaskCompleter taskCompleter) {
    _log.info("{} addVolume START...", storage.getLabel());
    try {
        // Export volume to Cluster
        if (volumeURIHLUs != null && volumeURIHLUs.length > 0) {
            ExportMask exportMask = _dbClient.queryObject(ExportMask.class, exportMaskURI);
            final String storageIP = storage.getSmisProviderIP();
            XIVRestClient restExportOpr = getRestClient(storage);
            // Find HOST from Export Mask
            URI hostName = null;
            Set<Initiator> exportMaskInits = ExportMaskUtils.getInitiatorsForExportMask(_dbClient, exportMask, null);
            Iterator<Initiator> exportMaskInitsItr = exportMaskInits.iterator();
            if (exportMaskInitsItr.hasNext()) {
                hostName = exportMaskInitsItr.next().getHost();
            }
            final Host host = _dbClient.queryObject(Host.class, hostName);
            // Validate if it is a cluster
            String exportName = host.getLabel();
            String clusterName = null;
            final String exportType = ExportMaskUtils.getExportType(_dbClient, exportMask);
            if (ExportGroup.ExportGroupType.Cluster.name().equals(exportType)) {
                Cluster cluster = _dbClient.queryObject(Cluster.class, host.getCluster());
                clusterName = cluster.getLabel();
                exportName = clusterName;
            }
            // Export volume
            List<BlockObject> userAddedVolumes = new ArrayList<BlockObject>();
            for (VolumeURIHLU volumeURIHLU : volumeURIHLUs) {
                final BlockObject blockObject = getBlockObject(volumeURIHLU.getVolumeURI());
                final String volumeHLU = volumeURIHLU.getHLU();
                if (volumeHLU != null && !volumeHLU.equalsIgnoreCase(ExportGroup.LUN_UNASSIGNED_STR)) {
                    int hluDec = Integer.parseInt(volumeHLU, 16);
                    if (hluDec > MAXIMUM_LUN) {
                        String errMsg = String.format(INVALID_LUN_ERROR_MSG, hluDec, MAXIMUM_LUN);
                        _log.error(errMsg);
                        throw new Exception(errMsg);
                    } else {
                        restExportOpr.exportVolume(storageIP, exportType, exportName, blockObject.getLabel(), String.valueOf(hluDec), isSnapshot(volumeURIHLU.getVolumeURI()));
                        userAddedVolumes.add(blockObject);
                    }
                }
            }
            exportMask.addToUserCreatedVolumes(userAddedVolumes);
            _dbClient.updateObject(exportMask);
            taskCompleter.ready(_dbClient);
        }
    } catch (Exception e) {
        _log.error("Unexpected error: addVolume failed.", e);
        XIVRestException error = XIVRestException.exceptions.methodFailed("addVolume", e);
        taskCompleter.error(_dbClient, error);
    }
    _log.info("{} addVolume END...", storage.getLabel());
}
Also used : ExportMask(com.emc.storageos.db.client.model.ExportMask) ArrayList(java.util.ArrayList) Cluster(com.emc.storageos.db.client.model.Cluster) Host(com.emc.storageos.db.client.model.Host) URI(java.net.URI) AlternateIdConstraint(com.emc.storageos.db.client.constraint.AlternateIdConstraint) XIVRestException(com.emc.storageos.xiv.api.XIVRestException) Initiator(com.emc.storageos.db.client.model.Initiator) XIVRestClient(com.emc.storageos.xiv.api.XIVRestClient) XIVRestException(com.emc.storageos.xiv.api.XIVRestException) BlockObject(com.emc.storageos.db.client.model.BlockObject) VolumeURIHLU(com.emc.storageos.volumecontroller.impl.VolumeURIHLU)

Example 17 with VolumeURIHLU

use of com.emc.storageos.volumecontroller.impl.VolumeURIHLU in project coprhd-controller by CoprHD.

the class XIVRestOperationsHelper method createRESTExportMask.

/**
 * Creates Export mask for a Cluster. Creates Cluster, Host and Inititators on XIV. Exports the volume to the
 * Cluster.
 *
 * @param storage
 *            XIV Storage System
 * @param exportMaskURI
 *            Export Mask URI
 * @param volumeURIHLUs
 *            Volume URIs to be exported
 * @param targetURIList
 *            Target ports (not used for XIV)
 * @param initiatorList
 *            Initiator ports
 * @param taskCompleter
 *            Task Completer instance
 */
public void createRESTExportMask(StorageSystem storage, URI exportMaskURI, VolumeURIHLU[] volumeURIHLUs, List<URI> targetURIList, List<Initiator> initiatorList, TaskCompleter taskCompleter) {
    try {
        ExportMask exportMask = _dbClient.queryObject(ExportMask.class, exportMaskURI);
        XIVRestClient restExportOpr = getRestClient(storage);
        final String storageIP = storage.getSmisProviderIP();
        String exportName = null;
        String clusterName = null;
        URI clusterURI = null;
        Set<String> hosts = new HashSet<String>();
        for (Initiator initiator : initiatorList) {
            final Host host = _dbClient.queryObject(Host.class, initiator.getHost());
            exportName = host.getLabel();
            hosts.add(exportName);
            clusterURI = host.getCluster();
        }
        final String exportType = ExportMaskUtils.getExportType(_dbClient, exportMask);
        if (ExportGroup.ExportGroupType.Cluster.name().equals(exportType) && null != clusterURI) {
            Cluster cluster = _dbClient.queryObject(Cluster.class, clusterURI);
            clusterName = cluster.getLabel();
            exportName = clusterName;
            // Create Cluster if not exist
            restExportOpr.createCluster(storageIP, clusterName);
        }
        // Create Host if not exist
        for (String hostName : hosts) {
            restExportOpr.createHost(storageIP, clusterName, hostName);
        }
        List<Initiator> userAddedInitiator = new ArrayList<Initiator>();
        List<BlockObject> userAddedVolumes = new ArrayList<BlockObject>();
        for (Initiator initiator : initiatorList) {
            final Host host = _dbClient.queryObject(Host.class, initiator.getHost());
            // Add Initiators to Host.
            if (!restExportOpr.createHostPort(storageIP, host.getLabel(), Initiator.normalizePort(initiator.getInitiatorPort()), initiator.getProtocol().toLowerCase())) {
                userAddedInitiator.add(initiator);
            }
        }
        // Export volume to Cluster
        if (volumeURIHLUs != null && volumeURIHLUs.length > 0) {
            for (VolumeURIHLU volumeURIHLU : volumeURIHLUs) {
                final BlockObject blockObject = getBlockObject(volumeURIHLU.getVolumeURI());
                final String volumeHLU = volumeURIHLU.getHLU();
                if (volumeHLU != null && !volumeHLU.equalsIgnoreCase(ExportGroup.LUN_UNASSIGNED_STR)) {
                    int hluDec = Integer.parseInt(volumeHLU, 16);
                    if (hluDec > MAXIMUM_LUN) {
                        String errMsg = String.format(INVALID_LUN_ERROR_MSG, hluDec, MAXIMUM_LUN);
                        _log.error(errMsg);
                        throw new Exception(errMsg);
                    } else {
                        if (!restExportOpr.exportVolume(storageIP, exportType, exportName, blockObject.getLabel(), String.valueOf(hluDec), isSnapshot(volumeURIHLU.getVolumeURI()))) {
                            userAddedVolumes.add(blockObject);
                        }
                    }
                }
            }
        }
        // Update Masking information
        exportMask.setCreatedBySystem(true);
        exportMask.addToUserCreatedInitiators(userAddedInitiator);
        exportMask.addToUserCreatedVolumes(userAddedVolumes);
        exportMask.setMaskName(exportName);
        exportMask.setNativeId(exportName);
        exportMask.setLabel(exportName);
        _dbClient.updateObject(exportMask);
        taskCompleter.ready(_dbClient);
    } catch (Exception e) {
        _log.error("Unexpected error: createRESTExportMask failed.", e);
        XIVRestException error = XIVRestException.exceptions.methodFailed("createExportMask", e);
        taskCompleter.error(_dbClient, error);
    }
}
Also used : ExportMask(com.emc.storageos.db.client.model.ExportMask) ArrayList(java.util.ArrayList) Cluster(com.emc.storageos.db.client.model.Cluster) Host(com.emc.storageos.db.client.model.Host) URI(java.net.URI) AlternateIdConstraint(com.emc.storageos.db.client.constraint.AlternateIdConstraint) XIVRestException(com.emc.storageos.xiv.api.XIVRestException) Initiator(com.emc.storageos.db.client.model.Initiator) XIVRestClient(com.emc.storageos.xiv.api.XIVRestClient) XIVRestException(com.emc.storageos.xiv.api.XIVRestException) BlockObject(com.emc.storageos.db.client.model.BlockObject) HashSet(java.util.HashSet) VolumeURIHLU(com.emc.storageos.volumecontroller.impl.VolumeURIHLU)

Example 18 with VolumeURIHLU

use of com.emc.storageos.volumecontroller.impl.VolumeURIHLU 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 19 with VolumeURIHLU

use of com.emc.storageos.volumecontroller.impl.VolumeURIHLU 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)

Example 20 with VolumeURIHLU

use of com.emc.storageos.volumecontroller.impl.VolumeURIHLU in project coprhd-controller by CoprHD.

the class VmaxExportOperations method createOrSelectSLOBasedStorageGroup.

/**
 * This is used only for VMAX3.
 */
private CIMObjectPath createOrSelectSLOBasedStorageGroup(StorageSystem storage, URI exportMaskURI, Collection<Initiator> initiators, VolumeURIHLU[] volumeURIHLUs, String parentGroupName, Map<StorageGroupPolicyLimitsParam, CIMObjectPath> newlyCreatedChildVolumeGroups, TaskCompleter taskCompleter) throws Exception {
    List<CIMObjectPath> childVolumeGroupsToBeAddedToParentGroup = new ArrayList<CIMObjectPath>();
    String groupName = null;
    CIMObjectPath groupPath = null;
    ExportMask mask = _dbClient.queryObject(ExportMask.class, exportMaskURI);
    // group volumes based on policy
    ListMultimap<StorageGroupPolicyLimitsParam, VolumeURIHLU> policyToVolumeGroup = ArrayListMultimap.create();
    WBEMClient client = _helper.getConnection(storage).getCimClient();
    for (VolumeURIHLU volumeUriHLU : volumeURIHLUs) {
        StorageGroupPolicyLimitsParam sgPolicyLimitsParam = null;
        URI boUri = volumeUriHLU.getVolumeURI();
        BlockObject bo = BlockObject.fetch(_dbClient, boUri);
        String policyName = volumeUriHLU.getAutoTierPolicyName();
        boolean fastAssociatedAlready = false;
        // Also note that Volumes with Compression set to true are also fast managed below is for vmax3.
        if (_helper.isFastPolicy(policyName) || volumeUriHLU.getCompression()) {
            policyName = _helper.getVMAX3FastSettingForVolume(boUri, policyName);
            fastAssociatedAlready = _helper.checkVolumeAssociatedWithAnySGWithPolicy(bo.getNativeId(), storage, policyName);
        }
        // should not be created with a FAST policy assigned.
        if (fastAssociatedAlready || isRPJournalVolume(bo)) {
            _log.info("Forcing policy name to NONE to prevent volume from using FAST policy.");
            volumeUriHLU.setAutoTierPolicyName(Constants.NONE);
            // Compression was applied on existing SG associated with policy!!
            volumeUriHLU.setCompression(false);
            sgPolicyLimitsParam = new StorageGroupPolicyLimitsParam(Constants.NONE, volumeUriHLU.getHostIOLimitBandwidth(), volumeUriHLU.getHostIOLimitIOPs(), storage);
        } else {
            sgPolicyLimitsParam = new StorageGroupPolicyLimitsParam(volumeUriHLU, storage, _helper);
        }
        policyToVolumeGroup.put(sgPolicyLimitsParam, volumeUriHLU);
    }
    _log.info("{} Groups generated based on grouping volumes by fast policy", policyToVolumeGroup.size());
    /**
     * Grouped Volumes based on Fast Policy
     */
    for (Entry<StorageGroupPolicyLimitsParam, Collection<VolumeURIHLU>> policyToVolumeGroupEntry : policyToVolumeGroup.asMap().entrySet()) {
        List<CIMObjectPath> childVolumeGroupsToBeAdded = new ArrayList<CIMObjectPath>();
        StorageGroupPolicyLimitsParam storageGroupPolicyLimitsParam = policyToVolumeGroupEntry.getKey();
        ListMultimap<String, VolumeURIHLU> expectedVolumeHluMap = ControllerUtils.getVolumeNativeGuids(policyToVolumeGroupEntry.getValue(), _dbClient);
        Map<String, Set<String>> existingGroupPaths;
        /**
         * Find any existing Storage Groups can be reused, in
         * case of Fast Enabled volumes
         */
        _log.info("Running Storage Group Selection Process");
        existingGroupPaths = _helper.findAnyStorageGroupsCanBeReUsed(storage, expectedVolumeHluMap, storageGroupPolicyLimitsParam);
        _log.info("Existing Storage Groups Found :" + Joiner.on("\t").join(existingGroupPaths.keySet()));
        if (existingGroupPaths.size() > 0) {
            if (existingGroupPaths.size() > 0) {
                childVolumeGroupsToBeAdded.addAll(_helper.constructMaskingGroupPathsFromNames(existingGroupPaths.keySet(), storage));
            }
        }
        Set<String> volumesInExistingStorageGroups = _helper.constructVolumeNativeGuids(existingGroupPaths.values());
        _log.debug("Volumes part of existing reusable Storage Groups {}", Joiner.on("\t").join(volumesInExistingStorageGroups));
        // Storage Group needs to be created for those volumes,
        // which doesn't fit into
        // existing groups.
        Set<String> diff = Sets.difference(expectedVolumeHluMap.asMap().keySet(), volumesInExistingStorageGroups);
        _log.debug("Remaining Volumes, for which new Storage Group needs to be created", Joiner.on("\t").join(diff));
        // need to construct a new group for remaining volumes.
        if (!diff.isEmpty()) {
            VolumeURIHLU[] volumeURIHLU = ControllerUtils.constructVolumeUriHLUs(diff, expectedVolumeHluMap);
            // TODO: VMAX3 customized names
            groupName = generateStorageGroupName(storage, mask, initiators, storageGroupPolicyLimitsParam);
            _log.debug("Group Name Created :", groupName);
            groupPath = createVolumeGroup(storage, groupName, volumeURIHLU, taskCompleter, true);
            _log.info("{} Volume Group created on Array {}", storage.getSerialNumber());
        }
        if (null != groupPath) {
            /**
             * used later in deleting created groups on failure
             */
            newlyCreatedChildVolumeGroups.put(storageGroupPolicyLimitsParam, groupPath);
            childVolumeGroupsToBeAdded.add(groupPath);
        }
        childVolumeGroupsToBeAddedToParentGroup.addAll(childVolumeGroupsToBeAdded);
    }
    // Avoid duplicate names for the Cascaded VolumeGroup
    parentGroupName = _helper.generateGroupName(_helper.getExistingStorageGroupsFromArray(storage), parentGroupName);
    CIMObjectPath cascadedGroupPath = createCascadedVolumeGroup(storage, parentGroupName, childVolumeGroupsToBeAddedToParentGroup, taskCompleter);
    // for proper roll back , that is volume removal, if exception is thrown during update
    for (Entry<StorageGroupPolicyLimitsParam, CIMObjectPath> createdChildVolumeGroupEntry : newlyCreatedChildVolumeGroups.entrySet()) {
        CIMObjectPath childGroupPath = createdChildVolumeGroupEntry.getValue();
        StorageGroupPolicyLimitsParam storageGroupPolicyLimitsParam = createdChildVolumeGroupEntry.getKey();
        if (storageGroupPolicyLimitsParam.isHostIOLimitBandwidthSet()) {
            _helper.updateHostIOLimitBandwidth(client, childGroupPath, storageGroupPolicyLimitsParam.getHostIOLimitBandwidth());
        }
        if (storageGroupPolicyLimitsParam.isHostIOLimitIOPsSet()) {
            _helper.updateHostIOLimitIOPs(client, childGroupPath, storageGroupPolicyLimitsParam.getHostIOLimitIOPs());
        }
    }
    return cascadedGroupPath;
}
Also used : Set(java.util.Set) Sets.newHashSet(com.google.common.collect.Sets.newHashSet) HashSet(java.util.HashSet) StringSet(com.emc.storageos.db.client.model.StringSet) ExportMask(com.emc.storageos.db.client.model.ExportMask) CIMObjectPath(javax.cim.CIMObjectPath) ArrayList(java.util.ArrayList) URI(java.net.URI) Collection(java.util.Collection) StorageGroupPolicyLimitsParam(com.emc.storageos.volumecontroller.impl.StorageGroupPolicyLimitsParam) WBEMClient(javax.wbem.client.WBEMClient) BlockObject(com.emc.storageos.db.client.model.BlockObject) VolumeURIHLU(com.emc.storageos.volumecontroller.impl.VolumeURIHLU)

Aggregations

VolumeURIHLU (com.emc.storageos.volumecontroller.impl.VolumeURIHLU)35 URI (java.net.URI)26 ArrayList (java.util.ArrayList)22 BlockObject (com.emc.storageos.db.client.model.BlockObject)19 ExportMask (com.emc.storageos.db.client.model.ExportMask)18 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)17 ServiceError (com.emc.storageos.svcs.errorhandling.model.ServiceError)14 HashMap (java.util.HashMap)14 HashSet (java.util.HashSet)13 CIMObjectPath (javax.cim.CIMObjectPath)13 Initiator (com.emc.storageos.db.client.model.Initiator)9 WBEMException (javax.wbem.WBEMException)9 AlternateIdConstraint (com.emc.storageos.db.client.constraint.AlternateIdConstraint)8 StorageGroupPolicyLimitsParam (com.emc.storageos.volumecontroller.impl.StorageGroupPolicyLimitsParam)7 CIMInstance (javax.cim.CIMInstance)7 Volume (com.emc.storageos.db.client.model.Volume)6 ContainmentConstraint (com.emc.storageos.db.client.constraint.ContainmentConstraint)5 StringSet (com.emc.storageos.db.client.model.StringSet)5 SmisException (com.emc.storageos.volumecontroller.impl.smis.SmisException)5 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)4