Search in sources :

Example 66 with Recommendation

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

the class VPlexScheduler method createVPlexRecommendations.

/**
 * Sets the Id of the VPlex storage system into the passed recommendations.
 *
 * @param vplexStorageSystemId The id of the VPlex storage system.
 * @param varray The varray for the recommendation.
 * @param vpool The vpool for the recommendation.
 * @param recommendations The list of recommendations.
 */
protected List<VPlexRecommendation> createVPlexRecommendations(String vplexStorageSystemId, VirtualArray varray, VirtualPool vpool, List<Recommendation> recommendations) {
    List<VPlexRecommendation> vplexRecommendations = new ArrayList<VPlexRecommendation>();
    for (Recommendation recommendation : recommendations) {
        VPlexRecommendation vplexRecommendation = new VPlexRecommendation();
        vplexRecommendation.setSourceStorageSystem(recommendation.getSourceStorageSystem());
        vplexRecommendation.setSourceStoragePool(recommendation.getSourceStoragePool());
        vplexRecommendation.setResourceCount(recommendation.getResourceCount());
        // vplexRecommendation.setSourceDevice(URI.create(vplexStorageSystemId));
        vplexRecommendation.setVPlexStorageSystem(URI.create(vplexStorageSystemId));
        vplexRecommendation.setVirtualArray(varray.getId());
        vplexRecommendation.setVirtualPool(vpool);
        vplexRecommendations.add(vplexRecommendation);
    }
    return vplexRecommendations;
}
Also used : VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) ArrayList(java.util.ArrayList) Recommendation(com.emc.storageos.volumecontroller.Recommendation) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation)

Example 67 with Recommendation

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

the class VolumeRecommendation method getDeviceMap.

/**
 * Return a map of device URI to a list of recommendations in that device.
 * This method can be used only for block volume recommendations since it assumes that there is only a single pool in the recommended
 * storage pools.
 *
 * @param recommendations List<VolumeRecommendation>
 * @param dbClient
 * @return Map of device URI to List<VolumeRecommendation> in that device
 */
public static Map<URI, List<VolumeRecommendation>> getDeviceMap(List<Recommendation> recommendations, DbClient dbClient) {
    HashMap<URI, List<VolumeRecommendation>> deviceMap = new HashMap<URI, List<VolumeRecommendation>>();
    for (Recommendation baseRecommendation : recommendations) {
        VolumeRecommendation recommendation = (VolumeRecommendation) baseRecommendation;
        URI poolId = recommendation.getCandidatePools().get(0);
        StoragePool storagePool = dbClient.queryObject(StoragePool.class, poolId);
        URI deviceId = storagePool.getStorageDevice();
        if (deviceMap.get(deviceId) == null) {
            deviceMap.put(deviceId, new ArrayList<VolumeRecommendation>());
        }
        deviceMap.get(deviceId).add(recommendation);
    }
    return deviceMap;
}
Also used : StoragePool(com.emc.storageos.db.client.model.StoragePool) HashMap(java.util.HashMap) List(java.util.List) ArrayList(java.util.ArrayList) URI(java.net.URI) Recommendation(com.emc.storageos.volumecontroller.Recommendation)

Example 68 with Recommendation

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

the class FileStorageScheduler method prepareFileSystems.

/**
 * create fileshare from the Recommendation object
 *
 * @param param
 *            -file share create param
 * @param task
 *            -task id
 * @param taskList
 *            - task list
 * @param project
 *            -project
 * @param varray
 *            - Virtual Array
 * @param vpool
 *            - Virtual Pool
 * @param recommendations
 *            - recommendation structure
 * @param cosCapabilities
 *            - Virtual pool wrapper
 * @param createInactive
 *            - create device sync inactive
 * @return
 */
public List<FileShare> prepareFileSystems(FileSystemParam param, String task, TaskList taskList, Project project, VirtualArray varray, VirtualPool vpool, List<Recommendation> recommendations, VirtualPoolCapabilityValuesWrapper cosCapabilities, Boolean createInactive) {
    List<FileShare> preparedFileSystems = new ArrayList<>();
    Iterator<Recommendation> recommendationsIter = recommendations.iterator();
    while (recommendationsIter.hasNext()) {
        FileRecommendation recommendation = (FileRecommendation) recommendationsIter.next();
        // If id is already set in recommendation, do not prepare the fileSystem (fileSystem already exists)
        if (recommendation.getId() != null) {
            continue;
        }
        if (recommendation.getFileType().toString().equals(FileRecommendation.FileType.FILE_SYSTEM_DATA.toString())) {
            // Grab the existing fileshare and task object from the incoming task list
            FileShare fileShare = getPrecreatedFile(taskList, param.getLabel());
            // Set the recommendation
            _log.info(String.format("createFileSystem --- FileShare: %1$s, StoragePool: %2$s, StorageSystem: %3$s", fileShare.getId(), recommendation.getSourceStoragePool(), recommendation.getSourceStorageSystem()));
            setFileRecommendation(recommendation, fileShare, vpool, createInactive);
            preparedFileSystems.add(fileShare);
        }
    }
    return preparedFileSystems;
}
Also used : ArrayList(java.util.ArrayList) FileShare(com.emc.storageos.db.client.model.FileShare) Recommendation(com.emc.storageos.volumecontroller.Recommendation)

Example 69 with Recommendation

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

the class VPlexScheduler method getRecommendationsForVpool.

@Override
public List<Recommendation> getRecommendationsForVpool(VirtualArray vArray, Project project, VirtualPool vPool, VpoolUse vPoolUse, VirtualPoolCapabilityValuesWrapper capabilities, Map<VpoolUse, List<Recommendation>> currentRecommendations) {
    _log.info("Getting recommendations for VPlex volume placement");
    // availability volumes.
    if (!VirtualPool.vPoolSpecifiesHighAvailability(vPool)) {
        throw APIException.badRequests.invalidHighAvailability(vPool.getHighAvailability());
    }
    _log.info("VirtualPool has high availability {}", vPool.getHighAvailability());
    Set<URI> vplexSystemsForPlacement = new HashSet<URI>();
    if (vPoolUse == VpoolUse.ROOT) {
        // For now only validate that we're using the same vplex systems on the ROOT request
        vplexSystemsForPlacement = getVPlexSystemsForPlacement(vArray, vPool, capabilities);
    }
    // Determine if the volume creation request is for HA volumes.
    boolean isHAVolumeRequest = VirtualPool.vPoolSpecifiesHighAvailabilityDistributed(vPool);
    // Get and validate the high availability VirtualArray and VirtualPool.
    // Note that the HA VirtualPool is optional. When not specified, the
    // high availability VirtualPool is the passed (root) VirtualPool.
    VirtualPool haVPool = vPool;
    VirtualArray haVArray = null;
    StringMap haVaVpMap = vPool.getHaVarrayVpoolMap();
    if ((isHAVolumeRequest) && (haVaVpMap != null)) {
        _log.info("Is HA request and with an HA VirtualArray VirtualPool map");
        Iterator<String> vaIter = haVaVpMap.keySet().iterator();
        while (vaIter.hasNext()) {
            String haVaId = vaIter.next();
            _log.info("HA VirtualArray is {}", haVaId);
            if (!haVaId.equals(NullColumnValueGetter.getNullURI().toString())) {
                _log.info("HA VirtualArray is not a null URI");
                haVArray = getVirtualArrayForVolumeCreateRequest(project, URI.create(haVaId));
                if (vArray.getId().toString().equals(haVArray.getId().toString())) {
                    throw APIException.badRequests.sameVirtualArrayAndHighAvailabilityArray();
                }
            }
            // Now get the VirtualPool.
            String haVpId = haVaVpMap.get(haVaId);
            _log.info("HA VirtualPool is {}", haVpId);
            if (!haVpId.equals(NullColumnValueGetter.getNullURI().toString())) {
                _log.info("HA VirtualPool is not a null URI");
                haVPool = BlockService.getVirtualPoolForRequest(project, URI.create(haVpId), _dbClient, _permissionsHelper);
            }
        }
    }
    // Get the volume placement based on passed parameters.
    _log.info("VirtualPool: {}, HA VirtualPool: {}", vPool.getId().toString(), haVPool.getId().toString());
    List<Recommendation> recommendations = scheduleStorage(vArray, vplexSystemsForPlacement, null, vPool, isHAVolumeRequest, haVArray, haVPool, capabilities, project, vPoolUse, currentRecommendations);
    return recommendations;
}
Also used : VirtualArray(com.emc.storageos.db.client.model.VirtualArray) StringMap(com.emc.storageos.db.client.model.StringMap) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) URI(java.net.URI) Recommendation(com.emc.storageos.volumecontroller.Recommendation) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) HashSet(java.util.HashSet)

Example 70 with Recommendation

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

the class VPlexScheduler method scheduleStorageForDistributedVPLEXVolume.

/**
 * Get recommendations for resource placement for distributed VLPEX volumes.
 *
 * @param srcVarray The virtual array in which the resources were requested.
 * @param requestedVPlexSystems The URIs of the VPlex systems to which
 *            placement should be limited, or null when it doesn't matter.
 * @param srcStorageSystem The URI of a specific backend storage system to
 *            which the source resource should be limited, or null when it
 *            doesn't matter.
 * @param srcVpool The virtual pool requested for the source resources.
 * @param haVarray The desired HA varray.
 * @param haVpool The virtual pool for the HA resources.
 * @param capabilities The virtual pool capabilities.
 *
 * @return A list of VPlexRecommendation instances specifying the
 *         recommended resource placement.
 */
private List<Recommendation> scheduleStorageForDistributedVPLEXVolume(VirtualArray srcVarray, Set<URI> requestedVPlexSystems, URI srcStorageSystem, VirtualPool srcVpool, VirtualArray haVarray, VirtualPool haVpool, VirtualPoolCapabilityValuesWrapper capabilities, Project project, VpoolUse srcVpoolUse, Map<VpoolUse, List<Recommendation>> currentRecommendations) {
    _log.info("Executing VPLEX high availability placement strategy for Distributed VPLEX Volumes.");
    // Initialize the list of recommendations.
    List<Recommendation> recommendations = new ArrayList<Recommendation>();
    // of the StorageSystemsMatcher.
    if (srcStorageSystem != null) {
        StorageSystem sourceStorageSystem = _dbClient.queryObject(StorageSystem.class, srcStorageSystem);
        capabilities.put(VirtualPoolCapabilityValuesWrapper.SOURCE_STORAGE_SYSTEM, sourceStorageSystem);
    }
    // Call the lower level scheduler to get its recommendations.
    Scheduler nextScheduler = _placementManager.getNextScheduler(SCHEDULER_NAME, srcVpool, srcVpoolUse);
    _log.info(String.format("Calling next scheduler: %s", nextScheduler.getClass().getSimpleName()));
    List<Recommendation> baseRecommendations = nextScheduler.getRecommendationsForVpool(srcVarray, project, srcVpool, srcVpoolUse, capabilities, currentRecommendations);
    _log.info(String.format("Received %d recommendations from %s", baseRecommendations.size(), nextScheduler.getClass().getSimpleName()));
    if (baseRecommendations.isEmpty()) {
        throw BadRequestException.badRequests.noVplexLocalRecommendationFromSubScheduler(nextScheduler.getClass().getSimpleName(), srcVpool.getLabel(), srcVarray.getLabel());
    }
    _log.info(String.format("Received %d recommendations from %s", baseRecommendations.size(), nextScheduler.getClass().getSimpleName()));
    List<StoragePool> allMatchingPoolsForSrcVarray = _placementManager.getStoragePoolsFromRecommendations(baseRecommendations);
    _log.info("Found {} matching pools for source varray", allMatchingPoolsForSrcVarray.size());
    URI cgURI = capabilities.getBlockConsistencyGroup();
    BlockConsistencyGroup cg = (cgURI == null ? null : _dbClient.queryObject(BlockConsistencyGroup.class, cgURI));
    // Sort the matching pools for the source varray by VPLEX system.
    Map<String, List<StoragePool>> vplexPoolMapForSrcVarray = getVPlexConnectedMatchingPools(srcVarray, requestedVPlexSystems, capabilities, allMatchingPoolsForSrcVarray);
    if (vplexPoolMapForSrcVarray.isEmpty()) {
        _log.info("No matching pools on storage systems connected to a VPLEX");
        // and there are none for that VPlex system.
        return recommendations;
    }
    // Get all storage pools that match the passed HA VirtualPool params,
    // and HA virtual array. In addition, the pool must have enough
    // capacity to hold at least one resource of the requested size.
    _log.info("Getting all matching pools for HA varray {}", haVarray.getId());
    URI haStorageSystem = null;
    VirtualPoolCapabilityValuesWrapper haCapabilities = new VirtualPoolCapabilityValuesWrapper(capabilities);
    // Don't look for SRDF in the HA side.
    haCapabilities.put(VirtualPoolCapabilityValuesWrapper.PERSONALITY, null);
    // We don't require that the HA side have the same storage controller.
    haCapabilities.put(VirtualPoolCapabilityValuesWrapper.BLOCK_CONSISTENCY_GROUP, null);
    Map<String, Object> attributeMap = new HashMap<String, Object>();
    List<StoragePool> allMatchingPoolsForHaVarray = getMatchingPools(haVarray, haStorageSystem, haVpool, haCapabilities, attributeMap);
    if (allMatchingPoolsForHaVarray.isEmpty()) {
        StringBuffer errorMessage = new StringBuffer();
        if (attributeMap.get(AttributeMatcher.ERROR_MESSAGE) != null) {
            errorMessage = (StringBuffer) attributeMap.get(AttributeMatcher.ERROR_MESSAGE);
        }
        throw BadRequestException.badRequests.noMatchingHighAvailabilityStoragePools(haVpool.getLabel(), haVarray.getLabel(), errorMessage.toString());
    }
    _log.info("Found {} matching pools for HA varray", allMatchingPoolsForHaVarray.size());
    // Sort the matching pools for the HA varray by VPLEX system.
    Map<String, List<StoragePool>> vplexPoolMapForHaVarray = sortPoolsByVPlexStorageSystem(allMatchingPoolsForHaVarray, haVarray.getId().toString());
    if (vplexPoolMapForHaVarray.isEmpty()) {
        _log.info("No matching pools on storage systems connected to a VPlex");
        // on storage systems connected to a VPlex storage system.
        return recommendations;
    }
    // Get the list of potential VPlex storage systems for the source
    // virtual array.
    Set<String> vplexStorageSystemIds = vplexPoolMapForSrcVarray.keySet();
    _log.info("{} VPlex storage systems have matching pools", vplexStorageSystemIds.size());
    // Get the possible high availability varrays for each of these
    // potential VPlex storage system.
    Map<String, List<String>> vplexHaVarrayMap = ConnectivityUtil.getVPlexVarrays(_dbClient, vplexStorageSystemIds, srcVarray.getId());
    // Loop over the potential VPlex storage systems, and attempt
    // to place the resources.
    Iterator<String> vplexSystemIdsIter = vplexStorageSystemIds.iterator();
    while ((vplexSystemIdsIter.hasNext()) && (recommendations.isEmpty())) {
        String vplexStorageSystemId = vplexSystemIdsIter.next();
        _log.info("Attempting placement on VPlex {}", vplexStorageSystemId);
        // Check if this VPLEX can satisfy the requested HA varray.
        List<String> vplexHaVarrays = vplexHaVarrayMap.get(vplexStorageSystemId);
        if (!vplexHaVarrays.contains(haVarray.getId().toString())) {
            // It cannot, try the next VPLEX.
            continue;
        }
        // Check if there are HA storage pools for this VPLEX.
        if (!vplexPoolMapForHaVarray.containsKey(vplexStorageSystemId)) {
            // There are no HA pools for this VPLEX, try the next.
            continue;
        }
        // Check if the resource can be placed on the matching
        // pools for this VPlex storage system in the source varray.
        List<Recommendation> recommendationsForSrcVarray = new ArrayList<Recommendation>();
        recommendationsForSrcVarray.addAll(createVPlexRecommendations(baseRecommendations, vplexStorageSystemId, srcVarray, srcVpool));
        if (recommendationsForSrcVarray.isEmpty()) {
            _log.info("Matching pools for source varray insufficient for placement");
            // not sufficient, so we need to try another VPlex.
            continue;
        }
        // Get the storage systems specified by these recommendations.
        // We don't want to use these same storage systems on the HA
        // side when the same system is available to both, else you
        // could create a distributed volume with both backend volumes
        // on the same physical array.
        Set<URI> recommendedSrcSystems = new HashSet<URI>();
        for (Recommendation recommendation : recommendationsForSrcVarray) {
            recommendedSrcSystems.add(recommendation.getSourceStorageSystem());
        }
        // Remove any storage pools on these systems from the list of
        // matching pools for the HA varray for this VPLEX system.
        boolean haPoolsLimitedBySrcSelections = false;
        List<StoragePool> vplexPoolsForHaVarray = new ArrayList<StoragePool>(vplexPoolMapForHaVarray.get(vplexStorageSystemId));
        Iterator<StoragePool> vplexPoolsForHaVarrayIter = vplexPoolsForHaVarray.iterator();
        while (vplexPoolsForHaVarrayIter.hasNext()) {
            StoragePool haPool = vplexPoolsForHaVarrayIter.next();
            URI poolSystem = haPool.getStorageDevice();
            if (recommendedSrcSystems.contains(poolSystem)) {
                _log.info("Removing pool {} on system {} from consideration for HA placement", haPool.getId(), poolSystem);
                vplexPoolsForHaVarrayIter.remove();
                haPoolsLimitedBySrcSelections = true;
            }
        }
        // Now check if the resource can be placed on the matching
        // pools for this VPlex storage system in the HA varray.
        List<Recommendation> recommendationsForHaVarray = getRecommendationsForPools(haVarray.getId().toString(), haVpool, vplexPoolsForHaVarray, capabilities);
        if (recommendationsForHaVarray.isEmpty()) {
            _log.info("Matching pools for HA varray insufficient for placement");
            if (haPoolsLimitedBySrcSelections) {
                // If we limited the pools on the HA side and failed to place,
                // then let's reverse and use all pools on the HA side and limit
                // the source side. This is certainly not perfect, but at least
                // will try and use the pools on both sides before giving up.
                recommendationsForHaVarray = getRecommendationsForPools(haVarray.getId().toString(), haVpool, vplexPoolMapForHaVarray.get(vplexStorageSystemId), capabilities);
                if (recommendationsForHaVarray.isEmpty()) {
                    // Still can't place them on the HA side.
                    _log.info("Matching pools for HA varray still insufficient for placement");
                    continue;
                } else {
                    // Remove the systems from the source side and see
                    // if the source side can still be placed when limited.
                    _log.info("Matching pools for HA varray now sufficient for placement");
                }
            } else {
                // not sufficient, so we need to try another VPlex.
                continue;
            }
        }
        // We have recommendations for pools in both the source and HA varrays.
        recommendations.addAll(recommendationsForSrcVarray);
        recommendations.addAll(createVPlexRecommendations(vplexStorageSystemId, haVarray, haVpool, recommendationsForHaVarray));
        _log.info("Done trying to place resources for VPlex.");
        break;
    }
    _placementManager.logRecommendations("VPLEX Distributed", recommendations);
    return recommendations;
}
Also used : VirtualPoolCapabilityValuesWrapper(com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper) StoragePool(com.emc.storageos.db.client.model.StoragePool) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) URI(java.net.URI) ArrayList(java.util.ArrayList) List(java.util.List) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) HashSet(java.util.HashSet) Recommendation(com.emc.storageos.volumecontroller.Recommendation) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup)

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