/* * Copyright (c) 2008-2011 EMC Corporation * All Rights Reserved */ package com.emc.storageos.volumecontroller.impl.plugins.discovery.smis.processor.fast.vnx; import java.io.IOException; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.cim.CIMInstance; import javax.cim.CIMObjectPath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.emc.storageos.db.client.DbClient; import com.emc.storageos.db.client.model.StoragePool; import com.emc.storageos.db.client.model.StorageSystem; import com.emc.storageos.plugins.AccessProfile; import com.emc.storageos.plugins.BaseCollectionException; import com.emc.storageos.plugins.common.Constants; import com.emc.storageos.plugins.common.domainmodel.Operation; import com.emc.storageos.volumecontroller.impl.plugins.discovery.smis.processor.PoolProcessor; /** * Check whether the Storage Pool Setting already Exists in Provider for this Storage Pool * This processor would have been called as part of the below executions * 1. Associators SMI-S call * CIMPath : VNXPoolCapabilities * ResultClass : EMC_StoragePoolSetting * The resultant list of existing Storage pool Settings is being returned as Result to this Processor. * * Goal of this Processor: * To verify, one StoragePoolSetting Object per InitialStorageTierMethodology is returned. * By default, Bourne expects 4 different Pool Settings (1 per InitialStorageTierMethodology value) * should exist for each PoolCapabilities. * * If yes, then we never need to create a new Setting, if not, we have to create Setting. * Create Setting is the next SMI-S operation to be run. This processor updates the List of * Settings which needs to be created, so that Create Setting call runs above the updated List. * * For each received Setting,get its InitialStorageTierMethodology value. * InitialStorageTierMethodology : * 0 - No_Data_Movement * 2 - Auto_Tier * 6- High_Available_tier * 7 - Low_Available_tier * * Compare the setting ID from returned Settings object against the setting Id in pool. * If exists, then remove the entry from the default expected Setting list. * * Default expected Setting list for each capability is being populated in PoolcapabilitiesProcessor. * Format : vnxcapabilitiesPath-2;vnxcapabilitiesPath-0;vnxcapabilitiesPath-6;vnxcapabilitiesPath-7; * If the result includes item 1 and 2, the list would be updated to * vnxcapabilitiesPath-6;vnxcapabilitiesPath-7 * * Create Setting would run only above this new updated list */ public class CheckPoolSettingExistenceProcessor extends PoolProcessor { private Logger _logger = LoggerFactory .getLogger(CheckPoolSettingExistenceProcessor.class); private List<Object> _args; private DbClient _dbClient; @SuppressWarnings("unchecked") @Override public void processResult( Operation operation, Object resultObj, Map<String, Object> keyMap) throws BaseCollectionException { @SuppressWarnings("unchecked") final Iterator<CIMInstance> it = (Iterator<CIMInstance>) resultObj; _dbClient = (DbClient) keyMap.get(Constants.dbClient); AccessProfile profile = (AccessProfile) keyMap.get(Constants.ACCESSPROFILE); try { StorageSystem device = getStorageSystem(_dbClient, profile.getSystemId()); CIMObjectPath poolCapabilitiesPath = getObjectPathfromCIMArgument(); String poolID = getPoolIdFromCapabilities(poolCapabilitiesPath); // get Pool from DB StoragePool pool = checkStoragePoolExistsInDB(poolID, _dbClient, device); List<String> poolSettingsList = (List<String>) keyMap .get(Constants.VNXPOOLCAPABILITIES_TIER); while (it.hasNext()) { CIMInstance settingInstance = it.next(); _logger.debug("settingInstance :{}", settingInstance); int tierMethodology = Integer.parseInt(settingInstance.getPropertyValue( Constants.INITIAL_STORAGE_TIER_METHODOLOGY).toString()); int tierSelection = Integer.parseInt(settingInstance.getPropertyValue( Constants.INITIAL_STORAGE_TIERING_SELECTION).toString()); String poolSettingId = settingInstance.getPropertyValue( Constants.INSTANCEID).toString(); // remove already existing settings from list if (checkPoolSettingExistsBasedOnTierMethodology(tierMethodology, pool, poolSettingId) && tierSelection == Constants.RELATIVE_PERFORMANCE_ORDER) { poolSettingsList.remove(poolCapabilitiesPath.toString() + Constants.HYPHEN + tierMethodology); } } } catch (Exception e) { _logger.error("CheckPoolExistence Processor failed:", e); } } /** * check whether pool Setting already exists * * @param tierMethodology * @param pool * @param poolSettingId * @return * @throws IOException */ private boolean checkPoolSettingExistsBasedOnTierMethodology( int tierMethodology, StoragePool pool, String poolSettingId) throws IOException { boolean poolChanged = false; if (null == pool) { return poolChanged; } switch (tierMethodology) { case Constants.NO_DATA_MOVEMENT: if (null == pool.getNoDataMovementId() || !pool.getNoDataMovementId().equalsIgnoreCase(poolSettingId)) { pool.setNoDataMovementId(poolSettingId); } poolChanged = true; break; case Constants.AUTO_TIER: if (null == pool.getAutoTierSettingId() || !pool.getAutoTierSettingId().equalsIgnoreCase(poolSettingId)) { pool.setAutoTierSettingId(poolSettingId); } poolChanged = true; break; case Constants.HIGH_AVAILABLE_TIER: if (null == pool.getHighAvailableTierId() || !pool.getHighAvailableTierId().equalsIgnoreCase(poolSettingId)) { pool.setHighAvailableTierId(poolSettingId); } poolChanged = true; break; case Constants.LOW_AVAILABLE_TIER: if (null == pool.getLowAvailableTierId() || !pool.getLowAvailableTierId().equalsIgnoreCase(poolSettingId)) { pool.setLowAvailableTierId(poolSettingId); } poolChanged = true; break; case Constants.START_HIGH_THEN_AUTO_TIER: if (null == pool.getStartHighThenAutoTierId() || !pool.getStartHighThenAutoTierId().equalsIgnoreCase(poolSettingId)) { pool.setStartHighThenAutoTierId(poolSettingId); } poolChanged = true; break; default: _logger.warn( "Found Invalid Storage tier methodology '{}' for Storage Pool {}", tierMethodology, pool.getId()); break; } if (poolChanged) { _dbClient.persistObject(pool); } return poolChanged; } /** * return 1st Argument in inputArguments used to * call this SMI-S call. * * @return */ private CIMObjectPath getObjectPathfromCIMArgument() { Object[] arguments = (Object[]) _args.get(0); return (CIMObjectPath) arguments[0]; } @Override protected void setPrerequisiteObjects(List<Object> inputArgs) throws BaseCollectionException { _args = inputArgs; } }