Search in sources :

Example 21 with Recommendation

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

the class RecoverPointScheduler method findVPlexHARecommendations.

/**
 * Find and return a recommendation for HA given the source side information.
 *
 * @param varray - Source Virtual Array
 * @param vpool - Source Virtual Pool
 * @param haVarray - HA Virtual Array
 * @param haVpool - HA Virtual Pool
 * @param project - Project
 * @param capabilities - Virtual Pool capabilities
 * @param vplexPoolMapForVarray - Map of virtual array to visible storage pools for that virtual array
 * @return HA recommendation
 */
private Recommendation findVPlexHARecommendations(VirtualArray varray, VirtualPool vpool, VirtualArray haVarray, VirtualPool haVpool, Project project, VirtualPoolCapabilityValuesWrapper capabilities, Map<String, List<StoragePool>> vplexPoolMapForVarray) {
    Recommendation haRecommendation = null;
    List<Recommendation> vplexHaVArrayRecommendations = null;
    if (haVarray == null) {
        haVarray = vplexScheduler.getHaVirtualArray(varray, project, vpool);
    }
    if (haVpool == null) {
        haVpool = vplexScheduler.getHaVirtualPool(varray, project, vpool);
    }
    vplexHaVArrayRecommendations = getAllHARecommendations(varray, vpool, haVarray, haVpool, capabilities, vplexPoolMapForVarray);
    if (!vplexHaVArrayRecommendations.isEmpty()) {
        // There is only one recommendation ever, return the first recommendation.
        haRecommendation = vplexHaVArrayRecommendations.get(0);
    }
    return haRecommendation;
}
Also used : VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) Recommendation(com.emc.storageos.volumecontroller.Recommendation) RPRecommendation(com.emc.storageos.volumecontroller.RPRecommendation) RPProtectionRecommendation(com.emc.storageos.volumecontroller.RPProtectionRecommendation)

Example 22 with Recommendation

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

the class SRDFScheduler method scheduleStorageSourcePoolConstraint.

/**
 * Schedule storage based on the incoming storage pools for source volumes. Find a source
 * storage pool that can provide a source volume that satisfies the vpool's criteria for all
 * targets varrays required and build a recommendation structure to describe the findings.
 *
 * Strategy:
 *
 * 0. When we come into method, we already have a list of candidate source pools, which may be
 * in multiple arrays 1. Get matching pools for each of the target virtual arrays based on the
 * target virtual pool. 2. Make a map of virtual array to potential pools in step 1. 3. Find a
 * pool from each entry in the map that belongs to a storage system that is connected via SRDF
 * (with the same policy) to the specific candidate pool we're looking at. 4. Generate an SRDF
 * Recommendation object that reflects the combination we found.
 *
 * @param varray
 *            varray requested for source
 * @param srdfVarrays
 *            Varray to protect this volume to.
 * @param vpool
 *            vpool requested
 * @param capabilities
 *            parameters
 * @param candidatePools
 *            candidate pools to use for source
 * @param vpoolChangeVolume
 *            vpool change volume, if applicable
 * @return list of Recommendation objects to satisfy the request
 */
private List<Recommendation> scheduleStorageSourcePoolConstraint(final VirtualArray varray, final Project project, final VirtualPool vpool, final VirtualPoolCapabilityValuesWrapper capabilities, final List<StoragePool> candidatePools, final Volume vpoolChangeVolume, final URI consistencyGroupUri) {
    // Initialize a list of recommendations to be returned.
    List<Recommendation> recommendations = new ArrayList<Recommendation>();
    if (capabilities.getResourceCount() == 1) {
        // For single resource request, select storage pool randomly from all candidate pools
        // (to minimize collisions).
        Collections.shuffle(candidatePools);
    } else {
        // Sort all pools in descending order by free capacity (first order) and in ascending
        // order by ratio
        // of pool's subscribed capacity to total capacity(suborder). This order is kept through
        // the selection procedure.
        _blockScheduler.sortPools(candidatePools);
    }
    List<VirtualArray> targetVarrays = getTargetVirtualArraysForVirtualPool(project, vpool, _dbClient, _permissionsHelper);
    // Attempt to use these pools for selection based on target
    StringBuffer sb = new StringBuffer("Determining if SRDF is possible from " + varray.getId() + " to: ");
    for (VirtualArray targetVarray : targetVarrays) {
        sb.append(targetVarray.getId()).append(" ");
    }
    _log.info(sb.toString());
    // The port group provided is belongs to SRDF source storage system.
    // If port group set in capabilities, ViPR looks storage pools from given PG's storage system only
    // Need to remove PORT_GROUP entry from capabilities for SRDF target volume,
    // so that ViPR picks SRDF target storage pools from right storage system.
    // 
    capabilities.removeCapabilityEntry(VirtualPoolCapabilityValuesWrapper.PORT_GROUP);
    Map<String, Object> attributeMap = new HashMap<String, Object>();
    Map<VirtualArray, List<StoragePool>> varrayPoolMap = getMatchingPools(targetVarrays, vpool, capabilities, attributeMap);
    if (varrayPoolMap == null || varrayPoolMap.isEmpty()) {
        // No matching storage pools found for any of the target varrays. There are no target
        // storage pools that match the passed vpool parameters and protocols and/or there are
        // no pools that have enough
        // capacity to hold at least one resource of the requested size.
        Set<String> tmpTargetVarrays = new HashSet<String>();
        sb = new StringBuffer("No matching storage pools found for any of the target varrays: [ ");
        for (VirtualArray targetVarray : targetVarrays) {
            sb.append(targetVarray.getId()).append(" ");
            tmpTargetVarrays.add(targetVarray.getLabel());
        }
        sb.append("]. There are no storage pools that match the passed vpool parameters and protocols and/or " + "there are no pools that have enough capacity to hold at least one resource of the requested size.");
        StringBuffer errorMessage = new StringBuffer();
        if (attributeMap.get(AttributeMatcher.ERROR_MESSAGE) != null) {
            errorMessage = (StringBuffer) attributeMap.get(AttributeMatcher.ERROR_MESSAGE);
        }
        _log.error(sb.toString());
        throw APIException.badRequests.noMatchingRecoverPointStoragePoolsForVpoolAndVarrays(vpool.getLabel(), tmpTargetVarrays, errorMessage.toString());
    }
    // Reduce the source and target pool down to the pools available via target.
    Set<SRDFPoolMapping> tmpDestPoolsList = getSRDFPoolMappings(varray, candidatePools, varrayPoolMap, vpool, vpoolChangeVolume, capabilities.getSize());
    if (tmpDestPoolsList == null || tmpDestPoolsList.isEmpty()) {
        // There are no target pools from any of the target varrays that share the
        // same SRDF connectivity as any of the source varray pools. Placement cannot
        // be achieved.
        Set<String> tmpSRDFVarrays = new HashSet<String>();
        sb = new StringBuffer("No matching target pool found for varray: ");
        sb.append(varray.getId());
        sb.append(" and vpool: ");
        sb.append(vpool.getId());
        sb.append(" to varrays: ");
        for (VirtualArray targetVarray : targetVarrays) {
            sb.append(targetVarray.getId()).append(" ");
            tmpSRDFVarrays.add(targetVarray.getLabel());
        }
        // No matching target pool found for varray so throw an exception
        // indicating a placement error.
        _log.error(sb.toString());
        throw APIException.badRequests.noMatchingSRDFPools(varray.getLabel(), vpool.getLabel(), tmpSRDFVarrays);
    }
    // Fire business rules to determine which SRDFPoolMappings can be eliminated
    // from consideration for placement.
    Set<SRDFPoolMapping> srcDestPoolsList = fireSRDFPlacementRules(tmpDestPoolsList, capabilities.getResourceCount());
    // the volume request configuration throw an exception.
    if (srcDestPoolsList == null || srcDestPoolsList.isEmpty()) {
        throw APIException.badRequests.srdfNoSolutionsFoundError();
    }
    // Get a new source pool list for pool selection
    Set<StoragePool> sourceCandidatePoolList = new HashSet<StoragePool>();
    for (SRDFPoolMapping srdfPoolMapping : srcDestPoolsList) {
        sourceCandidatePoolList.add(srdfPoolMapping.sourceStoragePool);
    }
    // Try with the storagePoolList as it currently is.
    // If we get through the process and couldn't achieve full target, we should
    // take out the matched pool from the storagePoolList and try again.
    List<StoragePool> sourcePoolList = new ArrayList<StoragePool>();
    sourcePoolList.addAll(sourceCandidatePoolList);
    // We need to create recommendations for one or more pools
    // that can accommodate the number of requested resources.
    // We start by trying to place all resources in a single
    // pool if one exists that can accommodate all requested
    // resources and work our way down as necessary trying to
    // minimize the number of pools used to satisfy the request.
    int recommendedCount = 0;
    int currentCount = capabilities.getResourceCount();
    // satisfied all of the requests.
    while (!sourcePoolList.isEmpty() && recommendedCount < capabilities.getResourceCount()) {
        // This request will either decrement the count OR shrink the sourcePoolList
        // In the case of decrementing the count, it's because it was successful at
        // placing volume(s). If it wasn't, that source pool goes in the trash and we
        // try the next one.
        long resourceSize = capabilities.getSize();
        int resourceCount = capabilities.getResourceCount();
        // We need to find a pool that matches the capacity for all the source/target luns
        long requiredPoolCapacity = resourceSize * currentCount;
        _log.info("Required pool capacity: " + requiredPoolCapacity);
        StoragePool poolWithRequiredCapacity = _blockScheduler.getPoolMatchingCapacity(requiredPoolCapacity, resourceSize, currentCount, sourcePoolList, VirtualPool.ProvisioningType.Thin.toString().equalsIgnoreCase(vpool.getSupportedProvisioningType()), null);
        // pool, setting the resource count for that recommendation.
        if (poolWithRequiredCapacity != null) {
            StoragePool recommendedPool = poolWithRequiredCapacity;
            _log.debug("Recommending storage pool {} for {} resources.", recommendedPool.getId(), currentCount);
            // Now we know what pool was selected, we can grab the target pools that jive with that
            // source
            Map<VirtualArray, List<StoragePool>> targetVarrayPoolMap = findDestPoolsForSourcePool(targetVarrays, srcDestPoolsList, recommendedPool, vpool);
            if (targetVarrayPoolMap == null || targetVarrayPoolMap.isEmpty()) {
                // A valid source pool was found but there are no pools from any of the
                // target varrays that can protect it.
                _log.info("There are no pools from any of the target varrays that can protect the source " + "varray pool {}.  Will try using another source varray pool.", recommendedPool.getLabel());
                // Remove the source pool and try the next one.
                sourcePoolList.remove(poolWithRequiredCapacity);
            } else {
                // A single recommendation object will create a set of volumes for an SRDF pair.
                SRDFRecommendation rec = new SRDFRecommendation();
                // For each target varray, we start the process of matching source and destination
                // pools to one storage system.
                Map<VirtualArray, Set<StorageSystem>> varrayTargetDeviceMap = new HashMap<VirtualArray, Set<StorageSystem>>();
                for (VirtualArray targetVarray1 : targetVarrayPoolMap.keySet()) {
                    if (rec.getSourceStoragePool() == null) {
                        rec.setVirtualArray(varray.getId());
                        rec.setVirtualPool(vpool);
                        rec.setSourceStoragePool(recommendedPool.getId());
                        rec.setResourceCount(currentCount);
                        rec.setSourceStorageSystem(recommendedPool.getStorageDevice());
                        rec.setVirtualArrayTargetMap(new HashMap<URI, Target>());
                        rec.setVpoolChangeVolume(vpoolChangeVolume != null ? vpoolChangeVolume.getId() : null);
                        rec.setVpoolChangeVpool(vpoolChangeVolume != null ? vpool.getId() : null);
                    }
                    if (targetVarrayPoolMap.get(targetVarray1) == null || targetVarrayPoolMap.get(targetVarray1).isEmpty()) {
                        _log.error("Could not find any suitable storage pool for target varray: " + targetVarray1.getLabel());
                        throw APIException.badRequests.unableToFindSuitablePoolForTargetVArray(targetVarray1.getLabel());
                    }
                    // Select the destination pool based on what was selected as source
                    StoragePool destinationPool = _blockScheduler.selectPool(targetVarrayPoolMap.get(targetVarray1));
                    _log.info("Destination target for varray " + targetVarray1.getLabel() + " was determined to be in pool: " + destinationPool.getLabel());
                    Target target = new Target();
                    target.setTargetPool(destinationPool.getId());
                    target.setTargetStorageDevice(destinationPool.getStorageDevice());
                    // Set the copy mode
                    Map<URI, VpoolRemoteCopyProtectionSettings> settingsMap = VirtualPool.getRemoteProtectionSettings(vpool, _dbClient);
                    target.setCopyMode(settingsMap.get(targetVarray1.getId()).getCopyMode());
                    if (target.getCopyMode() == null) {
                        // Set the default if not set
                        target.setCopyMode(RemoteDirectorGroup.SupportedCopyModes.ASYNCHRONOUS.toString());
                    }
                    // Generate a list of storage systems that match the src and dest pools lists.
                    Set<StorageSystem> targetDeviceList = findMatchingSRDFPools(targetVarray1, srcDestPoolsList, recommendedPool, destinationPool);
                    if (targetDeviceList.isEmpty()) {
                        _log.error("Could not find a Storage pool for target varray: " + targetVarray1.getLabel());
                        throw APIException.badRequests.unableToFindSuitablePoolForTargetVArray(targetVarray1.getLabel());
                    }
                    rec.getVirtualArrayTargetMap().put(targetVarray1.getId(), target);
                    // Add this potential solution to the map.
                    varrayTargetDeviceMap.put(targetVarray1, targetDeviceList);
                }
                // Grab any element since all varrays need to have the same SRDF connectivity.
                VirtualArray firstVarray = null;
                for (VirtualArray baseVarray : varrayTargetDeviceMap.keySet()) {
                    firstVarray = baseVarray;
                    break;
                }
                _log.info("Chose the first varray for SRDF comparison: " + firstVarray.getLabel());
                // Now go through each storage system in this varray and see if it matches up
                findInsertRecommendation(rec, firstVarray, recommendations, candidatePools, recommendedPool, varrayTargetDeviceMap, project, consistencyGroupUri);
                // Update the count of resources for which we have created
                // a recommendation.
                recommendedCount += currentCount;
                // Update the current count. The conditional prevents
                // unnecessary attempts to look for pools of a given
                // free capacity that we already know don't exist. For
                // example, say we want 100 resources and the first pool
                // we find that can hold multiple resources can hold only
                // 10. We don't want to continue looking for pools that
                // can hold 90,89,88,...11 resources. We just want to
                // see if there is another pool that can hold 10 resources,
                // then 9,8, and so on.
                currentCount = resourceCount - recommendedCount < currentCount ? resourceCount - recommendedCount : currentCount;
            }
        } else {
            // If we can't find a pool that can hold the current
            // count of resources, decrease the count so that we look
            // for pools that can hold the next smaller number.
            currentCount--;
            // Clear out the source pool list (which will cause failure)
            sourcePoolList.clear();
        }
        // log an error and clear the list of recommendations.
        if (recommendedCount != resourceCount) {
            _log.error("Could not find matching pools for varray {} & vpool {}", varray.getId(), vpool.getId());
            recommendations.clear();
            // Remove the pool we chose from the list so we can try again.
            sourcePoolList.remove(poolWithRequiredCapacity);
        }
    }
    return recommendations;
}
Also used : VirtualArray(com.emc.storageos.db.client.model.VirtualArray) VpoolRemoteCopyProtectionSettings(com.emc.storageos.db.client.model.VpoolRemoteCopyProtectionSettings) StoragePool(com.emc.storageos.db.client.model.StoragePool) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) Set(java.util.Set) StringSet(com.emc.storageos.db.client.model.StringSet) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) URI(java.net.URI) SRDFRecommendation(com.emc.storageos.volumecontroller.SRDFRecommendation) Target(com.emc.storageos.volumecontroller.SRDFRecommendation.Target) ArrayList(java.util.ArrayList) List(java.util.List) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) HashSet(java.util.HashSet) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) SRDFCopyRecommendation(com.emc.storageos.volumecontroller.SRDFCopyRecommendation) Recommendation(com.emc.storageos.volumecontroller.Recommendation) MetaVolumeRecommendation(com.emc.storageos.volumecontroller.impl.smis.MetaVolumeRecommendation) SRDFRecommendation(com.emc.storageos.volumecontroller.SRDFRecommendation) ContainmentConstraint(com.emc.storageos.db.client.constraint.ContainmentConstraint)

Example 23 with Recommendation

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

the class SRDFScheduler method getRecommendationsForCopy.

/**
 * This routine retrieves recommendations for the SRDF_COPY from previously generated SRDF Source
 * recommendations. The SRDF scheduler generates them together, but upper layers of code need
 * them separately so they can be encapsulated in higher level recommendations such as Vplex.
 * @param vArray - Virtual Array object
 * @param project - Project object
 * @param vPool - Virtual Pool object
 * @param capabilities - VirtualPoolCapabilitiesWrapper contains parameters
 * @param currentRecommendations - Contains the current recommendations that would include SRDFRecommendations.
 * The SrdfCopyRecommendations are generated from them
 * @return - List of Recommendations, specifically, SRDFCopyRecommendations
 */
private List<Recommendation> getRecommendationsForCopy(VirtualArray vArray, Project project, VirtualPool vPool, VirtualPoolCapabilityValuesWrapper capabilities, List<Recommendation> currentRecommendations) {
    List<Recommendation> recommendations = new ArrayList<Recommendation>();
    if (currentRecommendations == null) {
        throw WorkflowException.exceptions.workflowConstructionError("Required parameter currentRecommendations is null");
    }
    // that has has matching varray and vpool.
    for (Recommendation recommendation : currentRecommendations) {
        Recommendation rec = recommendation;
        while (rec != null) {
            if (rec instanceof SRDFRecommendation) {
                SRDFRecommendation srdfrec = (SRDFRecommendation) rec;
                if (srdfrec.getVirtualArrayTargetMap().containsKey(vArray.getId())) {
                    SRDFRecommendation.Target target = srdfrec.getVirtualArrayTargetMap().get(vArray.getId());
                    _log.info(String.format("Found SRDF target recommendation for va %s vpool %s", vArray.getLabel(), vPool.getLabel()));
                    SRDFCopyRecommendation targetRecommendation = new SRDFCopyRecommendation();
                    targetRecommendation.setVirtualArray(vArray.getId());
                    targetRecommendation.setVirtualPool(vPool);
                    targetRecommendation.setSourceStorageSystem(target.getTargetStorageDevice());
                    targetRecommendation.setSourceStoragePool(target.getTargetStoragePool());
                    targetRecommendation.setResourceCount(srdfrec.getResourceCount());
                    targetRecommendation.setRecommendation(srdfrec);
                    recommendations.add(targetRecommendation);
                }
            }
            // Check child recommendations, if any
            rec = rec.getRecommendation();
        }
    }
    return recommendations;
}
Also used : SRDFRecommendation(com.emc.storageos.volumecontroller.SRDFRecommendation) ArrayList(java.util.ArrayList) Target(com.emc.storageos.volumecontroller.SRDFRecommendation.Target) SRDFCopyRecommendation(com.emc.storageos.volumecontroller.SRDFCopyRecommendation) Recommendation(com.emc.storageos.volumecontroller.Recommendation) MetaVolumeRecommendation(com.emc.storageos.volumecontroller.impl.smis.MetaVolumeRecommendation) SRDFRecommendation(com.emc.storageos.volumecontroller.SRDFRecommendation) SRDFCopyRecommendation(com.emc.storageos.volumecontroller.SRDFCopyRecommendation)

Example 24 with Recommendation

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

the class StorageScheduler method getRecommendedPools.

/**
 * Try to determine a list of storage pools from the passed list of storage
 * pools that can accommodate the passed number of resources of the passed
 * size.
 *
 * @param varrayId The VirtualArray for the recommendations.
 * @param candidatePools The list of candidate storage pools.
 * @param capabilities The characteristics of the recommendation request.
 * @param orderPools true if candidate pools should be ordered before
 *            determining the recommendation, false otherwise
 *
 * @return The list of Recommendation instances reflecting the recommended
 *         pools.
 */
protected List<Recommendation> getRecommendedPools(String varrayId, List<StoragePool> candidatePools, VirtualPoolCapabilityValuesWrapper capabilities, boolean orderPools) {
    List<Recommendation> recommendations = new ArrayList<Recommendation>();
    long thinVolumePreAllocateSize = capabilities.getThinVolumePreAllocateSize();
    if (orderPools) {
        // Sort all pools in descending order by free capacity (first order)
        // and in ascending order by ratio of pool's subscribed capacity to
        // total capacity(suborder). This order is kept through the
        // selection procedure.
        sortPools(candidatePools);
    }
    // We need to create recommendations for one or more pools
    // that can accommodate the number of requested resources.
    // We start by trying to place all resources in a single
    // pool if one exists that can accommodate all requested
    // resources and work our way down as necessary trying to
    // minimize the number of pools used to satisfy the request.
    int recommendedCount = 0;
    int currentCount = capabilities.getResourceCount();
    while ((!candidatePools.isEmpty()) && (recommendedCount < capabilities.getResourceCount()) && (currentCount > 0)) {
        long requiredPoolCapacity = capabilities.getSize() * currentCount;
        long reqThinVolumePreAllocateSize = thinVolumePreAllocateSize * currentCount;
        StoragePool poolWithRequiredCapacity = getPoolMatchingCapacity(requiredPoolCapacity, capabilities.getSize(), currentCount, candidatePools, capabilities.getThinProvisioning(), reqThinVolumePreAllocateSize);
        if (poolWithRequiredCapacity != null) {
            StoragePool recommendedPool = poolWithRequiredCapacity;
            candidatePools.remove(recommendedPool);
            _log.debug("Recommending storage pool {} for {} resources.", recommendedPool.getId(), currentCount);
            Recommendation recommendation = new Recommendation();
            recommendation.setSourceStoragePool(recommendedPool.getId());
            recommendation.setResourceCount(currentCount);
            recommendation.setSourceStorageSystem(recommendedPool.getStorageDevice());
            recommendations.add(recommendation);
            // Update the count of resources for which we have created
            // a recommendation.
            recommendedCount += currentCount;
            // Update the current count. The conditional prevents
            // unnecessary attempts to look for pools of a given
            // free capacity that we already know don't exist. For
            // example, say we want 100 resources and the first pool
            // we find that can hold multiple resources can hold only
            // 10. We don't want to continue looking for pools that
            // can hold 90,89,88,...11 resources. We just want to
            // see if there is another pool that can hold 10 resources,
            // then 9,8, and so on.
            currentCount = (capabilities.getResourceCount() - recommendedCount < currentCount ? capabilities.getResourceCount() - recommendedCount : currentCount);
        } else {
            // If we can't find a pool that can hold the current
            // count of resources, decrease the count so that we look
            // for pools that can hold the next smaller number.
            currentCount--;
        }
    }
    // log an error and clear the list of recommendations.
    if (recommendedCount != capabilities.getResourceCount()) {
        recommendations.clear();
    }
    return recommendations;
}
Also used : StoragePool(com.emc.storageos.db.client.model.StoragePool) ArrayList(java.util.ArrayList) Recommendation(com.emc.storageos.volumecontroller.Recommendation) AlternateIdConstraint(com.emc.storageos.db.client.constraint.AlternateIdConstraint) ContainmentPrefixConstraint(com.emc.storageos.db.client.constraint.ContainmentPrefixConstraint) ContainmentConstraint(com.emc.storageos.db.client.constraint.ContainmentConstraint)

Example 25 with Recommendation

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

the class StorageScheduler method getRecommendationsForResources.

/**
 * Returns list of recommendations for block volumes.
 *
 * Select and return one or more storage pools where the volume(s)/fileshare(s)
 * should be created. The placement logic is based on:
 * - VirtualArray, only storage devices in the given varray are candidates
 * - VirtualPool, specifies must-meet & best-meet service specifications
 * - access-protocols: storage pools must support all protocols specified in VirtualPool
 * - snapshots: if yes, only select storage pools with this capability
 * - snapshot-consistency: if yes, only select storage pools with this capability
 * - performance: best-match, select storage pools which meets desired performance
 * - provision-mode: thick/thin
 * - numPaths: select storage pools with required number of paths to the volume
 * - size: Place the resources in the minimum number of storage pools that can
 * accommodate the size and number of resource requested.
 *
 * @param neighborhood
 * @param cos
 * @param capabilities
 * @return list of VolumeRecommendation instances
 */
@Override
public List<Recommendation> getRecommendationsForResources(VirtualArray neighborhood, Project project, VirtualPool cos, VirtualPoolCapabilityValuesWrapper capabilities) {
    _log.debug("Schedule storage for {} resource(s) of size {}.", capabilities.getResourceCount(), capabilities.getSize());
    List<Recommendation> volumeRecommendations = new ArrayList<Recommendation>();
    // Initialize a list of recommendations to be returned.
    List<Recommendation> recommendations = new ArrayList<Recommendation>();
    Map<String, Object> attributeMap = new HashMap<String, Object>();
    // Get all storage pools that match the passed CoS params and
    // protocols. In addition, the pool must have enough capacity
    // to hold at least one resource of the requested size.
    List<StoragePool> candidatePools = getMatchingPools(neighborhood, cos, capabilities, attributeMap);
    if (CollectionUtils.isEmpty(candidatePools)) {
        StringBuffer errorMessage = new StringBuffer();
        if (attributeMap.get(AttributeMatcher.ERROR_MESSAGE) != null) {
            errorMessage = (StringBuffer) attributeMap.get(AttributeMatcher.ERROR_MESSAGE);
        }
        throw APIException.badRequests.noStoragePools(neighborhood.getLabel(), cos.getLabel(), errorMessage.toString());
    }
    // Get the recommendations for the candidate pools.
    recommendations = getRecommendationsForPools(neighborhood.getId().toString(), candidatePools, capabilities);
    // log an error and clear the list of recommendations.
    if (recommendations.isEmpty()) {
        // TODO reevaluate
        _log.error("Could not find matching pools for VArray {} & VPool {}", neighborhood.getId(), cos.getId());
        return volumeRecommendations;
    }
    // create list of VolumeRecommendation(s) for volumes
    for (Recommendation recommendation : recommendations) {
        int count = recommendation.getResourceCount();
        while (count > 0) {
            VolumeRecommendation volumeRecommendation = new VolumeRecommendation(VolumeRecommendation.VolumeType.BLOCK_VOLUME, capabilities.getSize(), cos, neighborhood.getId());
            volumeRecommendation.setSourceStoragePool(recommendation.getSourceStoragePool());
            volumeRecommendation.setSourceStorageSystem(recommendation.getSourceStorageSystem());
            volumeRecommendation.setVirtualArray(neighborhood.getId());
            volumeRecommendation.setVirtualPool(cos);
            volumeRecommendation.setResourceCount(1);
            volumeRecommendation.addStoragePool(recommendation.getSourceStoragePool());
            volumeRecommendation.addStorageSystem(recommendation.getSourceStorageSystem());
            volumeRecommendations.add(volumeRecommendation);
            if (capabilities.getBlockConsistencyGroup() != null) {
                volumeRecommendation.setParameter(VolumeRecommendation.ARRAY_CG, capabilities.getBlockConsistencyGroup());
            }
            count--;
        }
    }
    return volumeRecommendations;
}
Also used : StoragePool(com.emc.storageos.db.client.model.StoragePool) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) BlockObject(com.emc.storageos.db.client.model.BlockObject) DiscoveredDataObject(com.emc.storageos.db.client.model.DiscoveredDataObject) Recommendation(com.emc.storageos.volumecontroller.Recommendation) AlternateIdConstraint(com.emc.storageos.db.client.constraint.AlternateIdConstraint) ContainmentPrefixConstraint(com.emc.storageos.db.client.constraint.ContainmentPrefixConstraint) ContainmentConstraint(com.emc.storageos.db.client.constraint.ContainmentConstraint)

Aggregations

Recommendation (com.emc.storageos.volumecontroller.Recommendation)70 ArrayList (java.util.ArrayList)62 URI (java.net.URI)49 VirtualArray (com.emc.storageos.db.client.model.VirtualArray)37 VPlexRecommendation (com.emc.storageos.volumecontroller.VPlexRecommendation)36 NamedURI (com.emc.storageos.db.client.model.NamedURI)28 StoragePool (com.emc.storageos.db.client.model.StoragePool)28 List (java.util.List)28 VirtualPool (com.emc.storageos.db.client.model.VirtualPool)27 RPProtectionRecommendation (com.emc.storageos.volumecontroller.RPProtectionRecommendation)27 RPRecommendation (com.emc.storageos.volumecontroller.RPRecommendation)27 Volume (com.emc.storageos.db.client.model.Volume)24 SRDFRecommendation (com.emc.storageos.volumecontroller.SRDFRecommendation)23 HashMap (java.util.HashMap)23 SRDFCopyRecommendation (com.emc.storageos.volumecontroller.SRDFCopyRecommendation)21 VirtualPoolCapabilityValuesWrapper (com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper)21 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)19 AlternateIdConstraint (com.emc.storageos.db.client.constraint.AlternateIdConstraint)18 Project (com.emc.storageos.db.client.model.Project)17 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)16