/* * Copyright (c) 2008-2013 EMC Corporation * All Rights Reserved */ package com.emc.storageos.volumecontroller.impl.utils.attrmatchers; import java.net.URI; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.CollectionUtils; import com.emc.storageos.db.client.DbClient; import com.emc.storageos.db.client.model.FileShare; import com.emc.storageos.db.client.model.StoragePool; import com.emc.storageos.db.client.model.StorageSystem; import com.emc.storageos.db.client.model.Volume; import com.emc.storageos.volumecontroller.AttributeMatcher; import com.google.common.base.Joiner; /** * Filter out the pools which reaches its maximum resources set. */ public class MaxResourcesMatcher extends AttributeMatcher { private static final Logger _log = LoggerFactory.getLogger(MaxResourcesMatcher.class); @Override protected boolean isAttributeOn(Map<String, Object> attributeMap) { return true; } @Override protected List<StoragePool> matchStoragePoolsWithAttributeOn(List<StoragePool> pools, Map<String, Object> attributeMap, StringBuffer errorMessage) { _log.info("Pools Matching max resources Started: {}", Joiner.on("\t").join(getNativeGuidFromPools(pools))); List<StoragePool> filteredPoolList = new ArrayList<StoragePool>(pools); Iterator<StoragePool> poolIterator = pools.iterator(); while (poolIterator.hasNext()) { StoragePool pool = poolIterator.next(); if (checkPoolMaximumResourcesApproached(pool, _objectCache.getDbClient(), 0)) { filteredPoolList.remove(pool); } } if (CollectionUtils.isEmpty(filteredPoolList)) { errorMessage.append("Reached Virtual Pool/System maximum resources limit. "); _log.error(errorMessage.toString()); } _log.info("Pools Matching max resources Ended: {}", Joiner.on("\t").join(getNativeGuidFromPools(filteredPoolList))); return filteredPoolList; } /** * Check whether pool & its system maximum resources approached or not. * * @param pool : Storage Pool * @param dbClient : dbClient ref. * @return */ public static boolean checkPoolMaximumResourcesApproached(StoragePool pool, DbClient dbClient, Integer resourceCount) { // Check whether maximum resources limit reached for pool or not. if (pool.getIsResourceLimitSet()) { Integer poolResources = getNumResources(pool, dbClient); if (pool.getMaxResources() < (poolResources + resourceCount)) { _log.info( "Ignoring Storage pool {} since it's approaching Resource limit: {}. ", pool.getNativeGuid(), pool.getMaxResources()); return true; } } // Check whether maximum resources limit reached for storage system or not URI systemId = pool.getStorageDevice(); StorageSystem system = dbClient.queryObject(StorageSystem.class, systemId); if (system.getIsResourceLimitSet()) { Integer systemResources = getNumResources(system, dbClient); if (system.getMaxResources() < (systemResources + resourceCount)) { _log.info( "Ignoring Storage system {} pools since it's approaching Resource limit: {}. ", system.getNativeGuid(), system.getMaxResources()); return true; } } return false; } /** * Counts and returns the number of resources in a pool * * @param pool * @param dbClient * @return */ public static Integer getNumResources(StoragePool pool, DbClient dbClient) { String serviceType = pool.getPoolServiceType(); Integer count = 0; if (StoragePool.PoolServiceType.file.name().equals(serviceType) || StoragePool.PoolServiceType.block_file.name().equals(serviceType)) { count = count + dbClient.countObjects(FileShare.class, "pool", pool.getId()); } if (StoragePool.PoolServiceType.block.name().equals(serviceType) || StoragePool.PoolServiceType.block_file.name().equals(serviceType)) { count = count + dbClient.countObjects(Volume.class, "pool", pool.getId()); } // We don't do anything if it's of type object return count; } /** * Counts and returns the number of resources in a storage system * * @param system * @param dbClient * @return */ public static Integer getNumResources(StorageSystem system, DbClient dbClient) { Integer count = 0; if (StorageSystem.Type.isFileStorageSystem(system.getSystemType())) { count = count + dbClient.countObjects(FileShare.class, "storageDevice", system.getId()); } if (StorageSystem.Type.isBlockStorageSystem(system.getSystemType())) { count = count + dbClient.countObjects(Volume.class, "storageDevice", system.getId()); } return count; } }