/* * Copyright (c) 2014-2015 EMC Corporation * All Rights Reserved */ package com.emc.storageos.volumecontroller.impl.plugins.discovery.smis.processor.detailedDiscovery; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.cim.CIMObjectPath; import javax.cim.UnsignedInteger32; import javax.wbem.CloseableIterator; import javax.wbem.client.EnumerateResponse; import javax.wbem.client.WBEMClient; import com.emc.storageos.volumecontroller.impl.plugins.SMICommunicationInterface; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.emc.storageos.db.client.DbClient; import com.emc.storageos.db.client.model.AutoTieringPolicy; import com.emc.storageos.db.client.model.StorageSystem; import com.emc.storageos.db.client.model.Volume; import com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume; import com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume.SupportedVolumeCharacterstics; 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.PartitionManager; import com.emc.storageos.plugins.common.domainmodel.Operation; import com.emc.storageos.volumecontroller.impl.plugins.discovery.smis.processor.StorageProcessor; import com.emc.storageos.volumecontroller.impl.utils.DiscoveryUtils; /** * This processor gets invoked only for VNX unManaged volume discoveries. * It populates the fast policy information for volumes. * Both Auto_tier and Start_High_then_Auto are represented as Auto_Tier in Provider. * Hence, it stores the objectPaths of Auto_tier alone. These object paths will be used to get * VolumeSettings (next SMI-S operation), from which the exact policy is being found. */ public class VNXFastVolumesProcessor extends StorageProcessor { List<UnManagedVolume> _unManagedVolumesUpdate = null; private Logger _logger = LoggerFactory.getLogger(VNXFastVolumesProcessor.class); private List<Object> _args; private DbClient _dbClient; private PartitionManager _partitionManager; public void setPartitionManager(PartitionManager partitionManager) { _partitionManager = partitionManager; } @Override public void processResult(Operation operation, Object resultObj, Map<String, Object> keyMap) throws BaseCollectionException { CloseableIterator<CIMObjectPath> volumeInstances = null; try { WBEMClient client = SMICommunicationInterface.getCIMClient(keyMap); _unManagedVolumesUpdate = new ArrayList<UnManagedVolume>(); @SuppressWarnings("unchecked") EnumerateResponse<CIMObjectPath> volumeInstanceChunks = (EnumerateResponse<CIMObjectPath>) resultObj; volumeInstances = volumeInstanceChunks.getResponses(); _dbClient = (DbClient) keyMap.get(Constants.dbClient); CIMObjectPath tierPolicypath = getObjectPathfromCIMArgument(_args); processVolumes(volumeInstances, tierPolicypath, keyMap, operation); while (!volumeInstanceChunks.isEnd()) { _logger.info("Processing Next Volume Chunk of size {}", BATCH_SIZE); volumeInstanceChunks = client.getInstancePaths(tierPolicypath, volumeInstanceChunks.getContext(), new UnsignedInteger32(BATCH_SIZE)); processVolumes(volumeInstanceChunks.getResponses(), tierPolicypath, keyMap, operation); } if (!_unManagedVolumesUpdate.isEmpty()) { _partitionManager.updateInBatches(_unManagedVolumesUpdate, getPartitionSize(keyMap), _dbClient, "VOLUME"); _unManagedVolumesUpdate.clear(); } } catch (Exception e) { _logger.error("Discovering Tier Policies for vnx volumes failed", e); } finally { volumeInstances.close(); } } private void processVolumes(Iterator<CIMObjectPath> it, CIMObjectPath tierPolicyPath, Map<String, Object> keyMap, Operation operation) { AccessProfile profile = (AccessProfile) keyMap.get(Constants.ACCESSPROFILE); StorageSystem system = _dbClient.queryObject(StorageSystem.class, profile.getSystemId()); while (it.hasNext()) { CIMObjectPath volumePath = null; try { volumePath = it.next(); if (tierPolicyPath.toString().contains(AutoTieringPolicy.VnxFastPolicy.DEFAULT_AUTOTIER.toString())) { _logger.debug("Adding Auto Tier Policy Rule "); addPath(keyMap, operation.getResult(), volumePath); continue; } String volumeNativeGuid = getVolumeNativeGuid(volumePath); Volume volume = checkStorageVolumeExistsInDB(volumeNativeGuid, _dbClient); if (null != volume) { _logger.debug("Skipping discovery, as this Volume {} is already being managed by ViPR.", volumeNativeGuid); continue; } String unManagedVolumeNativeGuid = getUnManagedVolumeNativeGuidFromVolumePath(volumePath); UnManagedVolume unManagedVolume = checkUnManagedVolumeExistsInDB( unManagedVolumeNativeGuid, _dbClient); if (null != unManagedVolume) { String policyName = getCIMPropertyValue(tierPolicyPath, Constants.POLICYRULENAME); _logger.info("Adding {} Policy Rule to UnManaged Volume {}", policyName, unManagedVolumeNativeGuid); injectIntoVolumeInformationContainer(unManagedVolume, Constants.POLICYRULENAME, tierPolicyPath); unManagedVolume.putVolumeCharacterstics( SupportedVolumeCharacterstics.IS_AUTO_TIERING_ENABLED.toString(), "true"); // StorageVolumeInfoProcessor updated supported_vpool_list based on its pool's presence in vPool // Now, filter those vPools based on policy associated DiscoveryUtils.filterSupportedVpoolsBasedOnTieringPolicy(unManagedVolume, policyName, system, _dbClient); _unManagedVolumesUpdate.add(unManagedVolume); } if (_unManagedVolumesUpdate.size() > BATCH_SIZE) { _partitionManager.updateInBatches(_unManagedVolumesUpdate, getPartitionSize(keyMap), _dbClient, "VOLUME"); _unManagedVolumesUpdate.clear(); } } catch (Exception ex) { _logger.error("Processing UnManaged Storage Volume {} ", volumePath, ex); } } } @Override protected void setPrerequisiteObjects(List<Object> inputArgs) throws BaseCollectionException { _args = inputArgs; } }