/* * Copyright (c) 2008-2011 EMC Corporation * All Rights Reserved */ package com.emc.storageos.volumecontroller.impl.plugins.discovery.smis.processor.fast.vmax; import com.emc.storageos.db.client.DbClient; import com.emc.storageos.db.client.constraint.AlternateIdConstraint; import com.emc.storageos.db.client.model.AutoTieringPolicy; import com.emc.storageos.db.client.model.StorageTier; 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.fast.AbstractFASTPolicyProcessor; import com.google.common.base.Joiner; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.cim.CIMInstance; import javax.cim.CIMObjectPath; import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import static com.emc.storageos.volumecontroller.impl.plugins.discovery.smis.processor.AutoTieringPolicyProcessorHelper.getAutoTieringPolicyByNameFromDB; /** * refer FASTPolicyProcessor comments before looking into below * Goal: * For each Discovered VMax fast Policy, run associatorNames on * EMC_StorageTier, which returns the list of Storage Tiers available for * VMax associated with this Policy. * * Using the returned Tier list,construct mapping between Tier-->Fast Policy * which will be used later to associate Policy--->Pools * * The reason behind this mapping is, for VMax, we get pools through * Policy-->tiers-->Pools, as we don't have a TierModel right now, we need this. * */ public class VMAXPolicyToTierProcessor extends AbstractFASTPolicyProcessor { private Logger _logger = LoggerFactory.getLogger(VMAXPolicyToTierProcessor.class); private List<Object> _args; private DbClient _dbClient; private List<StorageTier> _updateTierList; private List<StorageTier> _newTierList; @Override public void processResult( Operation operation, Object resultObj, Map<String, Object> keyMap) throws BaseCollectionException { try { @SuppressWarnings("unchecked") final Iterator<CIMInstance> it = (Iterator<CIMInstance>) resultObj; _dbClient = (DbClient) keyMap.get(Constants.dbClient); _updateTierList = new ArrayList<StorageTier>(); _newTierList = new ArrayList<StorageTier>(); // value will be set already always Object[] arguments = (Object[]) _args.get(0); Set<String> tierNativeGuidsfromProvider = new HashSet<String>(); CIMObjectPath vmaxFastPolicyRule = (CIMObjectPath) arguments[0]; String vmaxPolicyId = getFASTPolicyID(vmaxFastPolicyRule); AutoTieringPolicy vmaxFastPolicy = getAutoTieringPolicyByNameFromDB(vmaxPolicyId, _dbClient); // construct a Map (TierID--->PolicyRule), this is needed to construct // the relationship between Policy--->Pools while (it.hasNext()) { CIMInstance vmaxTierInstance = it.next(); CIMObjectPath tierPath = vmaxTierInstance.getObjectPath(); String tierID = tierPath.getKey(Constants.INSTANCEID).getValue() .toString(); // For 8.x -+- becomes +, internal DB format uses + only; for 4.6 remains as it is tierID = tierID.replaceAll(Constants.SMIS_80_STYLE, Constants.SMIS_PLUS_REGEX); if (keyMap.containsKey(tierID)) { List<CIMObjectPath> policyPaths = (List<CIMObjectPath>) keyMap.get(tierID); policyPaths.add(vmaxFastPolicyRule); } else { addPath(keyMap, Constants.STORAGETIERS, tierPath); List<CIMObjectPath> policyPaths = new ArrayList<CIMObjectPath>(); policyPaths.add(vmaxFastPolicyRule); keyMap.put(tierID, policyPaths); } String tierNativeGuid = getTierNativeGuidForVMax(tierID); tierNativeGuidsfromProvider.add(tierNativeGuid); StorageTier tierObject = checkStorageTierExistsInDB(tierNativeGuid, _dbClient); String driveTechnologyIdentifier = vmaxTierInstance.getPropertyValue( Constants.TECHNOLOGY).toString(); String driveType = StorageTier.SupportedTiers.getTier(driveTechnologyIdentifier); createStorageTier(vmaxTierInstance, tierObject, tierNativeGuid, vmaxFastPolicy.getId(), _newTierList, _updateTierList, driveType); } _dbClient.createObject(_newTierList); _dbClient.persistObject(_updateTierList); performStorageTierBookKeeping(tierNativeGuidsfromProvider, vmaxFastPolicy.getId()); } catch (Exception e) { _logger.error("Policy to Tier Processing failed :", e); } } /** * remove Tiers which had been deleted from Array * * @param tierNativeGuidsfromProvider * @param id * @throws IOException */ private void performStorageTierBookKeeping( Set<String> tierNativeGuidsfromProvider, URI id) throws IOException { List<URI> tierUrisAssociatedWithPolicy = _dbClient .queryByConstraint(AlternateIdConstraint.Factory .getStorageTierFASTPolicyConstraint(id.toString())); _logger.info("Tiers {} associated with Policy {}", Joiner.on("\t").join(tierUrisAssociatedWithPolicy), id); List<StorageTier> existingTierObjectsInDB = _dbClient.queryObject( StorageTier.class, tierUrisAssociatedWithPolicy); for (StorageTier tier : existingTierObjectsInDB) { if (!tierNativeGuidsfromProvider.contains(tier.getNativeGuid())) { if (null != tier.getAutoTieringPolicies()) { tier.getAutoTieringPolicies().clear(); } _dbClient.updateAndReindexObject(tier); } } } @Override protected void setPrerequisiteObjects(List<Object> inputArgs) throws BaseCollectionException { _args = inputArgs; } }