Search in sources :

Example 6 with Recommendation

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

the class VPlexScheduler method scheduleStorageForLocalVPLEXVolume.

/**
 * Get recommendations for resource placement for local VPLEX volumes.
 *
 * @param varray 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 storageSystem The URI of a specific backend storage system to
 *            which the source resource should be limited, or null when it
 *            doesn't matter.
 * @param vpool The virtual pool requested for the source resources.
 * @param capabilities The virtual pool capabilities.
 *
 * @return A list of VPlexRecommendation instances specifying the
 *         recommended resource placement.
 */
private List<Recommendation> scheduleStorageForLocalVPLEXVolume(VirtualArray varray, Set<URI> requestedVPlexSystems, URI storageSystem, VirtualPool vpool, VirtualPoolCapabilityValuesWrapper capabilities, Project project, VpoolUse vPoolUse, Map<VpoolUse, List<Recommendation>> currentRecommendations) {
    _log.info("Executing VPlex high availability placement strategy for Local VPLEX volumes");
    // of the StorageSystemsMatcher.
    if (storageSystem != null) {
        StorageSystem sourceStorageSystem = _dbClient.queryObject(StorageSystem.class, storageSystem);
        capabilities.put(VirtualPoolCapabilityValuesWrapper.SOURCE_STORAGE_SYSTEM, sourceStorageSystem);
    }
    // Initialize the list of recommendations that will be returned
    List<Recommendation> recommendations = new ArrayList<Recommendation>();
    // Call the lower level scheduler to get its baseRecommendations.
    Scheduler nextScheduler = _placementManager.getNextScheduler(SCHEDULER_NAME, vpool, vPoolUse);
    _log.info(String.format("Calling next scheduler: %s", nextScheduler.getClass().getSimpleName()));
    List<Recommendation> baseRecommendations = nextScheduler.getRecommendationsForVpool(varray, project, vpool, vPoolUse, capabilities, currentRecommendations);
    _log.info(String.format("Received %d recommendations from %s", baseRecommendations.size(), nextScheduler.getClass().getSimpleName()));
    List<StoragePool> allMatchingPools = _placementManager.getStoragePoolsFromRecommendations(baseRecommendations);
    _log.info("Found {} matching pools for varray", allMatchingPools.size());
    // Sort the matching pools by VPLEX system.
    Map<String, List<StoragePool>> vplexPoolMapForSrcVarray = getVPlexConnectedMatchingPools(varray, requestedVPlexSystems, capabilities, allMatchingPools);
    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;
    }
    // See if any one VPlex system can utilize all the specified pools.
    for (Map.Entry<String, List<StoragePool>> entry : vplexPoolMapForSrcVarray.entrySet()) {
        if (entry.getValue().containsAll(allMatchingPools)) {
            _log.info(String.format("Generating local recommendations for VPLEX %s", entry.getKey()));
            recommendations.addAll(createVPlexRecommendations(baseRecommendations, entry.getKey(), varray, vpool));
            break;
        }
    }
    if (recommendations.isEmpty()) {
        _log.info("No single VPLEX could front the entire set of recommendations");
    }
    _placementManager.logRecommendations("VPLEX Local", recommendations);
    return recommendations;
}
Also used : StoragePool(com.emc.storageos.db.client.model.StoragePool) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map) StringMap(com.emc.storageos.db.client.model.StringMap) Recommendation(com.emc.storageos.volumecontroller.Recommendation) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 7 with Recommendation

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

the class VPlexScheduler method scheduleStorageForMirror.

/**
 * Get recommendations for resource placement based on the passed
 * parameters.
 *
 * @param srcVarray The VirtualArray in which the resources were requested.
 * @param srcVpool Source volume virtual pool
 * @param mirrorVpool The virtual pool to be used for mirror
 * @param srcVpool The VirtualPool requested for the source resources.
 * @param capabilities The VirtualPool capabilities.
 * @param vplexStorageSystemURI The URI of the VPLEX system to which resources should be connected
 * @param excludeStorageSystem The URI of the storage system that needs to be excluded
 * @param cluster The VPLEX cluster to which resources should be connected
 *
 * @return A list of VPlexRecommendation instances specifying the
 *         recommended resource placement resources.
 */
public List<Recommendation> scheduleStorageForMirror(VirtualArray srcVarray, VirtualPool srcVpool, VirtualPool mirrorVpool, VirtualPoolCapabilityValuesWrapper capabilities, URI vplexStorageSystemURI, URI excludeStorageSystem, String cluster) {
    _log.info("Executing VPlex Mirror placement strategy");
    // Initialize the list of recommendations.
    List<Recommendation> recommendations = new ArrayList<Recommendation>();
    // Get all storage pools that match the passed VirtualPool params,
    // and virtual array. In addition, the pool must
    // have enough capacity to hold at least one resource of the
    // requested size.
    _log.info("Getting placement recommendations for srcVarray {}", srcVarray.getId());
    Map<String, Object> attributeMap = new HashMap<String, Object>();
    List<StoragePool> allMatchingPools = getMatchingPools(srcVarray, null, excludeStorageSystem, mirrorVpool, capabilities, attributeMap);
    _log.info("Found {} Matching pools for VirtualArray for the Mirror", allMatchingPools.size());
    // If the attribute matcher framework returns an error, then throw that error.
    // Otherwise, even when there are no pools, let the code return the empty list
    // of recommendations which is handled by the caller. This code was added for
    // COP-17666, but resulted in a regression captured by COP-25216. Therefore,
    // we now only throw an exception if there is an actual error set by a matcher.
    // If there is no error, returning the empty list will result in the previous
    // message being displayed.
    StringBuffer errorMessage = (StringBuffer) attributeMap.get(AttributeMatcher.ERROR_MESSAGE);
    if ((CollectionUtils.isEmpty(allMatchingPools)) && (errorMessage != null) && (errorMessage.length() != 0)) {
        throw APIException.badRequests.noStoragePools(srcVarray.getLabel(), srcVpool.getLabel(), errorMessage.toString());
    }
    // Due to VirtualPool attribute matching, we should only get storage
    // pools on storage systems that are connected to a VPlex
    // storage system. We find these storage pools and associate
    // them to the VPlex storage systems to which their storage
    // systems are connected.
    Map<String, List<StoragePool>> vplexPoolMapForSrcVarray = sortPoolsByVPlexStorageSystem(allMatchingPools, srcVarray.getId().toString(), cluster);
    // If only specified VPlex from source volume is desired, filter the vplexPoolMapForSrcVarray
    // to only use pools from the vplexStorageSystemURI.
    Iterator<Entry<String, List<StoragePool>>> it = vplexPoolMapForSrcVarray.entrySet().iterator();
    if (vplexStorageSystemURI != null) {
        while (it.hasNext()) {
            Entry<String, List<StoragePool>> entry = it.next();
            String vplexKey = entry.getKey();
            URI vplexURI = null;
            try {
                vplexURI = URI.create(vplexKey);
            } catch (IllegalArgumentException ex) {
                _log.error("Bad VPLEX URI: " + vplexURI);
                continue;
            }
            if (false == vplexStorageSystemURI.equals(vplexURI)) {
                it.remove();
            }
        }
    }
    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;
    }
    // The list of potential VPlex storage systems.
    Set<String> vplexStorageSystemIds = vplexPoolMapForSrcVarray.keySet();
    vplexStorageSystemIds = vplexPoolMapForSrcVarray.keySet();
    _log.info("{} VPlex storage systems have matching pools", vplexStorageSystemIds.size());
    Iterator<String> vplexSystemIdsIter = vplexStorageSystemIds.iterator();
    while ((vplexSystemIdsIter.hasNext()) && (recommendations.isEmpty())) {
        String vplexStorageSystemId = vplexSystemIdsIter.next();
        _log.info("Check matching pools for VPlex {}", vplexStorageSystemId);
        // pools for this VPlex storage system.
        if (VirtualPool.ProvisioningType.Thin.toString().equalsIgnoreCase(mirrorVpool.getSupportedProvisioningType())) {
            capabilities.put(VirtualPoolCapabilityValuesWrapper.THIN_PROVISIONING, Boolean.TRUE);
        }
        List<Recommendation> recommendationsForMirrorVarray = _blockScheduler.getRecommendationsForPools(srcVarray.getId().toString(), vplexPoolMapForSrcVarray.get(vplexStorageSystemId), capabilities);
        if (recommendationsForMirrorVarray.isEmpty()) {
            _log.info("Matching pools insufficient for placement");
            // not sufficient, so we need to try another VPlex.
            continue;
        }
        _log.info("Matching pools sufficient for placement");
        recommendations.addAll(createVPlexRecommendations(vplexStorageSystemId, srcVarray, srcVpool, recommendationsForMirrorVarray));
        continue;
    }
    return recommendations;
}
Also used : StoragePool(com.emc.storageos.db.client.model.StoragePool) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) URI(java.net.URI) Recommendation(com.emc.storageos.volumecontroller.Recommendation) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) Entry(java.util.Map.Entry) ArrayList(java.util.ArrayList) List(java.util.List)

Example 8 with Recommendation

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

the class VPlexScheduler method scheduleStorageForImport.

/**
 * Schedule Storage for a VPLEX import operation where we are creating the
 * HA volume.
 *
 * @param srcNH Source Neighborhood
 * @param vplexs Set<URI> Set of Vplex System URIs that can be used
 * @param requestedHaNH Optional requested HA Neighborhood. Can be null.
 * @param cos CoS to be used for new volumes
 * @param capabilities CoS capabilities to be used for new volume
 * @return List<Recommendation>
 */
public List<Recommendation> scheduleStorageForImport(VirtualArray srcNH, Set<URI> vplexs, VirtualArray requestedHaNH, VirtualPool cos, VirtualPoolCapabilityValuesWrapper capabilities) {
    Set<String> vplexSystemIds = new HashSet<String>();
    for (URI vplexURI : vplexs) {
        vplexSystemIds.add(vplexURI.toString());
    }
    List<Recommendation> recommendations = new ArrayList<Recommendation>();
    // For an HA request, get the possible high availability neighborhoods
    // for each potential VPlex storage system.
    Map<String, List<String>> vplexHaNHMap = ConnectivityUtil.getVPlexVarrays(_dbClient, vplexSystemIds, srcNH.getId());
    for (URI vplexSystemURI : vplexs) {
        StorageSystem vplexSystem = _dbClient.queryObject(StorageSystem.class, vplexSystemURI);
        // See if there is an HA varray
        // for the VPlex that also contains pools suitable to place
        // the resources.
        List<String> vplexHaNHIds = vplexHaNHMap.get(vplexSystem.getId().toString());
        if (vplexHaNHIds == null) {
            continue;
        }
        _log.info("Found {} HA varrays", vplexHaNHIds.size());
        for (String vplexHaNHId : vplexHaNHIds) {
            _log.info("Check HA varray {}", vplexHaNHId);
            // varray is not it, then skip the varray.
            if ((requestedHaNH != null) && (!vplexHaNHId.equals(requestedHaNH.getId().toString()))) {
                _log.info("Not the requested HA varray, skip");
                continue;
            }
            // Get all storage pools that match the passed CoS params,
            // protocols, and this HA varray. In addition, the
            // pool must have enough capacity to hold at least one
            // resource of the requested size.
            VirtualArray vplexHaNH = _dbClient.queryObject(VirtualArray.class, URI.create(vplexHaNHId));
            Map<String, Object> attributeMap = new HashMap<String, Object>();
            List<StoragePool> allMatchingPools = getMatchingPools(vplexHaNH, null, cos, capabilities, attributeMap);
            _log.info("Found {} matching pools for HA varray", allMatchingPools.size());
            // Now from the list of candidate pools, we only want pools
            // on storage systems that are connected to the VPlex
            // storage system. We find these storage pools and associate
            // them to the VPlex storage systems to which their storage
            // system is connected.
            Map<String, List<StoragePool>> vplexPoolMapForHaNH = sortPoolsByVPlexStorageSystem(allMatchingPools, vplexHaNHId);
            // If the HA varray has candidate pools for this
            // VPlex, see if the candidate pools in this HA
            // varray are sufficient to place the resources.
            List<Recommendation> recommendationsForHaNH = new ArrayList<Recommendation>();
            if (vplexPoolMapForHaNH.containsKey(vplexSystem.getId().toString())) {
                _log.info("Found matching pools in HA NH for VPlex {}", vplexSystem.getId());
                recommendationsForHaNH = _blockScheduler.getRecommendationsForPools(vplexHaNH.getId().toString(), vplexPoolMapForHaNH.get(vplexSystem.getId().toString()), capabilities);
            } else {
                _log.info("No matching pools in HA NH for VPlex {}", vplexSystem.getId());
            }
            recommendations.addAll(createVPlexRecommendations(vplexSystem.getId().toString(), vplexHaNH, cos, recommendationsForHaNH));
        }
    }
    return recommendations;
}
Also used : VirtualArray(com.emc.storageos.db.client.model.VirtualArray) StoragePool(com.emc.storageos.db.client.model.StoragePool) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) URI(java.net.URI) Recommendation(com.emc.storageos.volumecontroller.Recommendation) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 9 with Recommendation

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

the class AbstractBlockServiceApiImpl method createVolumesAndDescriptors.

@Override
public List<VolumeDescriptor> createVolumesAndDescriptors(List<VolumeDescriptor> descriptors, String name, Long size, Project project, VirtualArray varray, VirtualPool vpool, List<Recommendation> recommendations, TaskList taskList, String task, VirtualPoolCapabilityValuesWrapper vpoolCapabilities) {
    BlockServiceApi api = null;
    List<VolumeDescriptor> volumeDescriptors = new ArrayList<VolumeDescriptor>();
    for (Recommendation recommendation : recommendations) {
        if (recommendation instanceof SRDFRecommendation || recommendation instanceof SRDFCopyRecommendation) {
            api = BlockService.getBlockServiceImpl(DiscoveredDataObject.Type.srdf.name());
        } else if (recommendation instanceof VolumeRecommendation) {
            api = BlockService.getBlockServiceImpl(BlockServiceApi.DEFAULT);
        } else {
            String message = String.format("No BlockServiceApiImpl to handle recommendation of class: ", recommendation.getClass().getName());
            s_logger.error(message);
            throw WorkflowException.exceptions.workflowConstructionError(message);
        }
        volumeDescriptors.addAll(api.createVolumesAndDescriptors(descriptors, name, size, project, varray, vpool, recommendations, taskList, task, vpoolCapabilities));
    }
    return volumeDescriptors;
}
Also used : SRDFRecommendation(com.emc.storageos.volumecontroller.SRDFRecommendation) VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) ArrayList(java.util.ArrayList) VolumeRecommendation(com.emc.storageos.api.service.impl.placement.VolumeRecommendation) SRDFCopyRecommendation(com.emc.storageos.volumecontroller.SRDFCopyRecommendation) Recommendation(com.emc.storageos.volumecontroller.Recommendation) SRDFRecommendation(com.emc.storageos.volumecontroller.SRDFRecommendation) VolumeRecommendation(com.emc.storageos.api.service.impl.placement.VolumeRecommendation) SRDFCopyRecommendation(com.emc.storageos.volumecontroller.SRDFCopyRecommendation)

Example 10 with Recommendation

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

the class BlockMirrorServiceApiImpl method startNativeContinuousCopies.

@Override
public TaskList startNativeContinuousCopies(StorageSystem storageSystem, Volume sourceVolume, VirtualPool sourceVirtualPool, VirtualPoolCapabilityValuesWrapper capabilities, NativeContinuousCopyCreate param, String taskId) throws ControllerException {
    if (!((storageSystem.getUsingSmis80() && storageSystem.deviceIsType(Type.vmax)) || storageSystem.deviceIsType(Type.vnxblock))) {
        validateNotAConsistencyGroupVolume(sourceVolume, sourceVirtualPool);
    }
    TaskList taskList = new TaskList();
    // Currently, this will create a single mirror and add it to the source volume
    // Two steps: first place the mirror and then prepare the mirror.
    List<Recommendation> volumeRecommendations = new ArrayList<Recommendation>();
    // Prepare mirror.
    int volumeCounter = 1;
    int volumeCount = capabilities.getResourceCount();
    String volumeLabel = param.getName();
    List<Volume> preparedVolumes = new ArrayList<Volume>();
    // If the requested volume is part of CG
    if (sourceVolume.isInCG()) {
        if (volumeCount > 1) {
            throw APIException.badRequests.invalidMirrorCountForVolumesInConsistencyGroup();
        }
        URIQueryResultList cgVolumeList = new URIQueryResultList();
        _dbClient.queryByConstraint(ContainmentConstraint.Factory.getVolumesByConsistencyGroup(sourceVolume.getConsistencyGroup()), cgVolumeList);
        // recommendation
        while (cgVolumeList.iterator().hasNext()) {
            Volume cgSourceVolume = _dbClient.queryObject(Volume.class, cgVolumeList.iterator().next());
            _log.info("Processing volume {} in CG {}", cgSourceVolume.getId(), sourceVolume.getConsistencyGroup());
            VirtualPool cgVolumeVPool = _dbClient.queryObject(VirtualPool.class, cgSourceVolume.getVirtualPool());
            populateVolumeRecommendations(capabilities, cgVolumeVPool, cgSourceVolume, taskId, taskList, volumeCount, volumeCounter, volumeLabel, preparedVolumes, volumeRecommendations);
        }
    } else {
        // Source Volume without CG
        populateVolumeRecommendations(capabilities, sourceVirtualPool, sourceVolume, taskId, taskList, volumeCount, volumeCounter, volumeLabel, preparedVolumes, volumeRecommendations);
    }
    List<URI> mirrorList = new ArrayList<URI>(preparedVolumes.size());
    for (Volume volume : preparedVolumes) {
        Operation op = _dbClient.createTaskOpStatus(BlockMirror.class, volume.getId(), taskId, ResourceOperationTypeEnum.ATTACH_BLOCK_MIRROR);
        volume.getOpStatus().put(taskId, op);
        TaskResourceRep volumeTask = toTask(volume, taskId, op);
        taskList.getTaskList().add(volumeTask);
        mirrorList.add(volume.getId());
    }
    BlockController controller = getController(BlockController.class, storageSystem.getSystemType());
    try {
        controller.attachNativeContinuousCopies(storageSystem.getId(), sourceVolume.getId(), mirrorList, taskId);
    } catch (ControllerException ce) {
        String errorMsg = format("Failed to start continuous copies on volume %s: %s", sourceVolume.getId(), ce.getMessage());
        _log.error(errorMsg, ce);
        for (TaskResourceRep taskResourceRep : taskList.getTaskList()) {
            taskResourceRep.setState(Operation.Status.error.name());
            taskResourceRep.setMessage(errorMsg);
            Operation statusUpdate = new Operation(Operation.Status.error.name(), errorMsg);
            _dbClient.updateTaskOpStatus(Volume.class, taskResourceRep.getResource().getId(), taskId, statusUpdate);
        }
        throw ce;
    }
    return taskList;
}
Also used : DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) BlockController(com.emc.storageos.volumecontroller.BlockController) TaskList(com.emc.storageos.model.TaskList) ArrayList(java.util.ArrayList) TaskResourceRep(com.emc.storageos.model.TaskResourceRep) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) Operation(com.emc.storageos.db.client.model.Operation) NamedURI(com.emc.storageos.db.client.model.NamedURI) FCTN_MIRROR_TO_URI(com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_MIRROR_TO_URI) URI(java.net.URI) FCTN_STRING_TO_URI(com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_STRING_TO_URI) Recommendation(com.emc.storageos.volumecontroller.Recommendation) VolumeRecommendation(com.emc.storageos.api.service.impl.placement.VolumeRecommendation) AlternateIdConstraint(com.emc.storageos.db.client.constraint.AlternateIdConstraint) ContainmentConstraint(com.emc.storageos.db.client.constraint.ContainmentConstraint) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) Volume(com.emc.storageos.db.client.model.Volume)

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