/* * 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.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.DiscoveredDataObject.Type; import com.emc.storageos.db.client.model.StoragePool; import com.emc.storageos.db.client.model.StorageSystem; import com.emc.storageos.db.client.model.StringSet; import com.emc.storageos.db.client.model.VirtualPool.SupportedDriveTypes; import com.emc.storageos.volumecontroller.AttributeMatcher; import com.google.common.base.Joiner; public class DriveTypeMatcher extends ConditionalAttributeMatcher { private static final Logger _logger = LoggerFactory .getLogger(DriveTypeMatcher.class); @Override protected boolean isAttributeOn(Map<String, Object> attributeMap) { // same code is being used for 2 different code paths, placement & cos matchers, and both behaviors are different. // hence this flag is used if (isAutoTieringPolicyOn(attributeMap) && !attributeMap.containsKey(AttributeMatcher.PLACEMENT_MATCHERS)) { _logger.info("Skipping DriveType matcher, as VMAX FAST Policy is chosen"); return false; } return (null != attributeMap && attributeMap.containsKey(Attributes.drive_type.toString()) && !SupportedDriveTypes.NONE.toString().equals(attributeMap.get(Attributes.drive_type.toString()).toString())); } @Override protected List<StoragePool> matchStoragePoolsWithAttributeOn( List<StoragePool> allPools, Map<String, Object> attributeMap, StringBuffer errorMessage) { List<StoragePool> filteredPools = new ArrayList<StoragePool>(); String desiredInitialDriveType = attributeMap.get(Attributes.drive_type.toString()).toString(); _logger.info("Drive Type Matcher Started : {}, {}", desiredInitialDriveType, Joiner.on("\t").join(getNativeGuidFromPools(allPools))); for (StoragePool pool : allPools) { if (null == pool || null == pool.getSupportedDriveTypes()) { continue; } StorageSystem system = _objectCache.getDbClient().queryObject(StorageSystem.class, pool.getStorageDevice()); // If pool belongs to a HDS system and contains External storage, then add the pools to matched list. if (Type.isHDSStorageSystem(StorageSystem.Type.valueOf(system.getSystemType()))) { if (pool.getSupportedDriveTypes().contains(SupportedDriveTypes.UNKNOWN.toString())) { filteredPools.add(pool); continue; } } if (pool.getSupportedDriveTypes().contains(desiredInitialDriveType)) { filteredPools.add(pool); } else { _logger.info("Ignoring pool {} as it does not support Drive types.", pool.getNativeGuid()); } } if (CollectionUtils.isEmpty(filteredPools)) { errorMessage.append(String.format("No matching storage pool found for the drive type %s. ", desiredInitialDriveType)); _logger.error(errorMessage.toString()); } _logger.info("Drive Type Matcher Ended : {}, {}", desiredInitialDriveType, Joiner.on("\t").join(getNativeGuidFromPools(filteredPools))); return filteredPools; } @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 driveTypes = pool.getSupportedDriveTypes(); if (null != driveTypes && !driveTypes.isEmpty()) { availableAttrValues.addAll(driveTypes); } } if (!availableAttrValues.isEmpty()) { availableAttrMap.put(Attributes.drive_type.toString(), availableAttrValues); return availableAttrMap; } } catch (Exception e) { _logger.error("Exception occurred while getting available attributes using DriveTypeMatcher.", e); } return Collections.emptyMap(); } }