use of com.emc.storageos.db.client.model.StoragePool in project coprhd-controller by CoprHD.
the class VPlexScheduler method sortPoolsByVPlexStorageSystem.
/**
* Determines if each pool is on storage system that is connected to a VPlex
* storage system that has connectivity to the passed varray. If so, the
* pool is mapped to that VPlex storage system.
*
* @param storagePools A list of storage pools.
* @param varrayId The varray to which the VPLEX must have connectivity.
* @param cluster The VPLEX cluster to which storage system should be connected.
*
* @return A map of storage pools keyed by the VPlex storage system to which
* they have connectivity.
*/
protected Map<String, List<StoragePool>> sortPoolsByVPlexStorageSystem(List<StoragePool> storagePools, String varrayId, String cluster) {
Map<String, List<StoragePool>> vplexPoolMap = new HashMap<String, List<StoragePool>>();
// group the pools by system
Map<URI, List<StoragePool>> poolsBySystem = getPoolsBySystem(storagePools);
for (URI systemUri : poolsBySystem.keySet()) {
// for each system, find the associated vplexes in the requested varray
Set<URI> vplexSystemURIs = ConnectivityUtil.getVPlexSystemsAssociatedWithArray(_dbClient, systemUri, new HashSet<String>(Arrays.asList(varrayId)), cluster);
for (URI vplexUri : vplexSystemURIs) {
StorageSystem vplexSystem = _dbClient.queryObject(StorageSystem.class, vplexUri);
String vplexId = vplexUri.toString();
// fill the map
if (vplexSystem != null) {
if (!vplexPoolMap.containsKey(vplexId)) {
List<StoragePool> vplexPoolList = new ArrayList<StoragePool>();
vplexPoolList.addAll(poolsBySystem.get(systemUri));
vplexPoolMap.put(vplexId, vplexPoolList);
} else {
List<StoragePool> vplexPoolList = vplexPoolMap.get(vplexId);
vplexPoolList.addAll(poolsBySystem.get(systemUri));
}
}
}
}
return vplexPoolMap;
}
use of com.emc.storageos.db.client.model.StoragePool 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;
}
use of com.emc.storageos.db.client.model.StoragePool 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;
}
use of com.emc.storageos.db.client.model.StoragePool 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;
}
use of com.emc.storageos.db.client.model.StoragePool in project coprhd-controller by CoprHD.
the class VPlexScheduler method getMatchingPools.
/**
* Gets all storage pools in the passed varray, satisfying the passed
* CoS and capable of holding a resource of the requested size. Additionally
* filters the storage pools to those on the storage system with the
* passed URI, when the passed storage system is not null.
*
* @param varray The desired virtual array.
* @param storageSystemURI The desired storage system or null.
* @param excludeStorageSystemURI The storage system that should be excluded or null.
* @param vpool The required virtual pool.
* @param capabilities The virtual pool capabilities.
* @param attributeMap
* @return A list of storage pools.
*/
protected List<StoragePool> getMatchingPools(VirtualArray varray, URI storageSystemURI, URI excludeStorageSystemURI, VirtualPool vpool, VirtualPoolCapabilityValuesWrapper capabilities, Map<String, Object> attributeMap) {
// to filter for pools only on that system.
if (storageSystemURI != null) {
StorageSystem storageSystem = _dbClient.queryObject(StorageSystem.class, storageSystemURI);
capabilities.put(VirtualPoolCapabilityValuesWrapper.SOURCE_STORAGE_SYSTEM, storageSystem);
} else if (excludeStorageSystemURI != null) {
// Otherwise, if an excluded system is provided, enable the exclude storage
// system matcher to filter out pools on the excluded system. Note that there
// should never be an excluded system when a specific storage system to match
// is passed.
StorageSystem excludeStorageSystem = _dbClient.queryObject(StorageSystem.class, excludeStorageSystemURI);
capabilities.put(VirtualPoolCapabilityValuesWrapper.EXCLUDED_STORAGE_SYSTEM, excludeStorageSystem);
}
// Now call the block scheduler to get the matching storage pools.
List<StoragePool> storagePools = _blockScheduler.getMatchingPools(varray, vpool, capabilities, attributeMap);
return storagePools;
}
Aggregations