/* * Copyright (c) 2015 EMC Corporation * All Rights Reserved */ package com.emc.storageos.volumecontroller.impl.utils.attrmatchers; import java.net.URI; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.CollectionUtils; import com.emc.storageos.db.client.model.StoragePool; import com.emc.storageos.db.client.model.StringSet; import com.emc.storageos.db.client.model.VirtualPool.RaidLevel; import com.emc.storageos.volumecontroller.AttributeMatcher; import com.google.common.base.Joiner; public class RaidLevelMatcher extends ConditionalAttributeMatcher { private static final Logger _logger = LoggerFactory.getLogger(RaidLevelMatcher.class); @Override protected boolean isAttributeOn(Map<String, Object> attributeMap) { boolean isMatcherNeeded = false; if (isAutoTieringPolicyOn(attributeMap) && !attributeMap.containsKey(AttributeMatcher.PLACEMENT_MATCHERS)) { _logger.info("Skipping RaidLevel matcher, as VMAX FAST Policy is chosen"); return isMatcherNeeded; } if (attributeMap != null && attributeMap.get(Attributes.raid_levels.name()) != null) { HashSet<String> raidLevels = (HashSet<String>) attributeMap.get(Attributes.raid_levels.name()); if (!raidLevels.isEmpty()) { isMatcherNeeded = true; } } return isMatcherNeeded; } @SuppressWarnings("unchecked") @Override protected List<StoragePool> matchStoragePoolsWithAttributeOn(List<StoragePool> pools, Map<String, Object> attributeMap, StringBuffer errorMessage) { List<StoragePool> filteredPoolList = new ArrayList<StoragePool>(pools); Set<String> raidLevels = null; raidLevels = (Set<String>) attributeMap.get(Attributes.raid_levels.toString()); _logger.info("Pools Matching RaidLevels {} Started:{}", raidLevels, Joiner.on("\t").join(getNativeGuidFromPools(pools))); Iterator<StoragePool> poolIterator = pools.iterator(); while (poolIterator.hasNext()) { StoragePool pool = poolIterator.next(); StringSet poolSupportedRaidLevels = pool.getSupportedRaidLevels(); if (null != poolSupportedRaidLevels) { _logger.info("Supported Raid Levels {} for Pool {} ", Joiner.on("\t") .join(poolSupportedRaidLevels), pool.getNativeGuid()); } else { _logger.info("Supported Raid Levels Empty for Pool {} ", pool.getNativeGuid()); } // if Pool doesn't have any details on Raid Level, remove that Pool if (null == poolSupportedRaidLevels) { _logger.info("Ignoring pool {} as it doesn't have raid levels", pool.getNativeGuid()); filteredPoolList.remove(pool); continue; } Set<String> copies = new HashSet<String>(poolSupportedRaidLevels); copies.retainAll(raidLevels); if (copies.isEmpty()) { _logger.info("Ignoring pool {} as it is not supporting the raid levels.", pool.getNativeGuid()); filteredPoolList.remove(pool); } } if (CollectionUtils.isEmpty(filteredPoolList)) { errorMessage.append(String.format("No matching storage pool found for the given raid levels : %s. ", raidLevels)); _logger.error(errorMessage.toString()); } _logger.info("Pools Matching RaidLevels Ended :{}", Joiner.on("\t").join(getNativeGuidFromPools(filteredPoolList))); return filteredPoolList; } @Override public Map<String, Set<String>> getAvailableAttribute(List<StoragePool> neighborhoodPools, URI vArrayId) { try { Map<String, Set<String>> availableAttrMap = new HashMap<String, Set<String>>(1); Set<String> availableAttrValues = new HashSet<String>(); for (StoragePool pool : neighborhoodPools) { StringSet raidLevels = pool.getSupportedRaidLevels(); if (null != raidLevels && !raidLevels.isEmpty()) { for (String raidLevel : raidLevels) { if (RaidLevel.lookup(raidLevel) != null) { availableAttrValues.add(raidLevel); } } } } if (!availableAttrValues.isEmpty()) { availableAttrMap.put(Attributes.raid_levels.name(), availableAttrValues); return availableAttrMap; } } catch (Exception e) { _logger.error("Exception occurred while getting available attributes using RaidLevelMatcher.", e); } return Collections.emptyMap(); } }