/* * Copyright (c) 2013 EMC Corporation * All Rights Reserved */ package com.emc.storageos.volumecontroller; import java.net.URI; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.emc.storageos.coordinator.client.service.CoordinatorClient; import com.emc.storageos.db.client.model.StoragePool; import com.emc.storageos.db.client.model.StorageSystem; import com.emc.storageos.volumecontroller.impl.utils.ObjectLocalCache; /** * AttributeMatcher is base class for all attribute matchers which provides base functionality * of identifying the valid matchers and finding the right pools for a given set of attribute matchers. * All new attribute matchers should just extend this and implement their own logic to match pools * against new attributes. */ public abstract class AttributeMatcher { /** * DbClient reference. */ private static final Logger _logger = LoggerFactory .getLogger(AttributeMatcher.class); protected ObjectLocalCache _objectCache; protected CoordinatorClient _coordinator; public static final String VPOOL_MATCHERS = "vpoolMatchers"; public static final String PLACEMENT_MATCHERS = "placementMatchers"; public static final String BASIC_PLACEMENT_MATCHERS = "basicPlacementMatchers"; public static final String CONNECTIVITY_PLACEMENT_MATCHERS = "connectivityMatchers"; public static final String ERROR_MESSAGE = "errorMessage"; public static enum Attributes { vpool_type, varrays, protocols, max_paths, paths_per_initiator, size, fast, raid_levels, drive_type, system_type, provisioning_type, high_availability_type, high_availability_varray, high_availability_vpool, high_availability_rp, metropoint, auto_tiering_policy_name, compression_enabled, thin_volume_preallocation_size, storage_system, multi_volume_consistency, max_native_snapshots, max_native_continuous_copies, recoverpoint_map, thin_volume_preallocation_percentage, unique_policy_names, remote_copy, long_term_retention_policy, support_soft_limit, support_notification_limit, file_replication_type, file_replication_copy_mode, file_replication, schedule_snapshots, file_snapshot_supported, file_replication_supported, file_replication_target_varray, file_replication_target_vpool, min_datacenters, quota, source_storage_system, remote_copy_mode, array_affinity, dedup, exclude_storage_system } /** * This method responsible to run the matchers even if there is CoS attribute on/off. * attributeOn => match pools based on the CoS attribute value set. * attributeOff => match pools when a CoS attribute value not set. * * @param pools : List of pools to match this attribute. * @param attributeMap : * @param errorMessage : Error Message * @return matchedPools : list of pools matching. */ public List<StoragePool> runMatchStoragePools(List<StoragePool> pools, Map<String, Object> attributeMap, StringBuffer errorMessage) { List<StoragePool> matchedPools = null; if (isAttributeOn(attributeMap)) { matchedPools = matchStoragePoolsWithAttributeOn(pools, attributeMap, errorMessage); } else { matchedPools = matchStoragePoolsWithAttributeOff(pools, attributeMap); } return matchedPools; } /** * Returns the StorageSystem object for the given StoragePool. * * @param storageSystemMap * @param pool * @return StorageSystem */ public StorageSystem getStorageSystem(Map<URI, StorageSystem> storageSystemMap, StoragePool pool) { URI storageSystemURI = pool.getStorageDevice(); if (storageSystemMap.containsKey(storageSystemURI)) { return storageSystemMap.get(storageSystemURI); } StorageSystem system = _objectCache.queryObject(StorageSystem.class, storageSystemURI); storageSystemMap.put(storageSystemURI, system); return system; } /** * Match pools if a attribute value is not set. * * @param pools : list of pools to match. * @param attributeMap : map contains the list of attribute values to match. */ protected List<StoragePool> matchStoragePoolsWithAttributeOff(List<StoragePool> pools, Map<String, Object> attributeMap) { return pools; } /** * Check whether attribute value is set or not. * Ex. If CoS protocols is set then this method returns true else false. * So, Based on this method return value, AttributeMatcher will run. * * @param attributeMap : map contains the list of attribute values to match. * @return */ protected abstract boolean isAttributeOn(Map<String, Object> attributeMap); /** * Matches the list of storagePools and returns only the pools * which are matching with the attribute. * * @param allPools : List of pools to match against each vpool attribute. * @param attributeMap : map contains the list of attribute values to match. * @param errorMessage : contains the the error message * @return matchedpools: */ protected abstract List<StoragePool> matchStoragePoolsWithAttributeOn(List<StoragePool> allPools, Map<String, Object> attributeMap, StringBuffer errorMessage); /** * For debug purpose, which lists the matched Pool Native Guids * * @param pools * @return */ protected List<String> getNativeGuidFromPools(List<StoragePool> pools) { List<String> poolURIList = new ArrayList<String>(); for (StoragePool pool : pools) { poolURIList.add(pool.getNativeGuid()); } return poolURIList; } /** * set Cache. * * @param cache */ public void setObjectCache(ObjectLocalCache cache) { _objectCache = cache; } /** * set CoordinatorClient. * * @param coordinator */ public void setCoordinatorClient(CoordinatorClient coordinator) { _coordinator = coordinator; } /** * Returns a Map contains AttributeName as key and its supported values else empty map. * By default this will return empty map and if someone wants * to show available attribute & its supported values, they must override this method * and return the available attributes.. * * Ex. In a varray, if any one system supports FAST, then * this method returns a map with key as FAST and its policynames as values. * ["FAST", [policy1, policy2,policy3...etc.]] * * @param neighborhoodPools * @param varrayUri virtual array URI * * @return */ public Map<String, Set<String>> getAvailableAttribute(List<StoragePool> neighborhoodPools, URI varrayUri) { return Collections.emptyMap(); } }