/* * Copyright (c) 2012-2015 EMC Corporation * All Rights Reserved */ package com.emc.storageos.volumecontroller.impl.plugins.discovery.smis.processor.detailedDiscovery; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import javax.cim.CIMInstance; import javax.cim.CIMObjectPath; import javax.wbem.client.WBEMClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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.StorageProcessor; /** * Process synchronization aspects (EMC_SynchronizationAspectForSource instances). */ public class SynchronizationAspectProcessor extends StorageProcessor { private final Logger _logger = LoggerFactory .getLogger(SynchronizationAspectProcessor.class); private static String SOURCE_ELEMENT = "SourceElement"; private static String SYNC_TYPE = "SyncType"; private AccessProfile _profile; private Map<String, Map<String, String>> _syncAspectMap; private Map<String, Set<String>> _duplicateSyncAspectElementNameMap; @Override public void processResult(Operation operation, Object resultObj, Map<String, Object> keyMap) throws BaseCollectionException { _logger.debug("Calling SynchronizationAspectProcessor"); _profile = (AccessProfile) keyMap.get(Constants.ACCESSPROFILE); _syncAspectMap = new HashMap<String, Map<String, String>>(); _duplicateSyncAspectElementNameMap = new HashMap<String, Set<String>>(); processResultbyChunk(resultObj, keyMap); keyMap.put(Constants.SNAPSHOT_NAMES_SYNCHRONIZATION_ASPECT_MAP, _syncAspectMap); keyMap.put(Constants.DUPLICATE_SYNC_ASPECT_ELEMENT_NAME_MAP, _duplicateSyncAspectElementNameMap); } /** * {@inheritDoc} */ @Override protected int processInstances(Iterator<CIMInstance> instances) { return processInstances(instances, null); } /** * {@inheritDoc} */ @Override protected int processInstances(Iterator<CIMInstance> instances, WBEMClient client) { int count = 0; Map<String, Set<String>> processedNameMap = new HashMap<String, Set<String>>(); while (instances.hasNext()) { try { count++; CIMInstance instance = instances.next(); String srcElement = getCIMPropertyValue(instance, SOURCE_ELEMENT); CIMObjectPath srcPath = new CIMObjectPath(srcElement); String serialId = srcPath.getKey(Constants.SYSTEMNAME).getValue().toString(); // skip synchronization aspects belonging to other arrays if (!serialId.contains(_profile.getserialID())) { continue; } String syncType = getCIMPropertyValue(instance, SYNC_TYPE); if (!SYNC_TYPE_SNAPSHOT.equals(syncType)) { continue; } // ViPR currently does not support SnapVx generation names. Generation // names allow the user to use the same name for all array snapshots // for a given source volume and assign a unique generation number to // differentiate them. Therefore, if we encounter a synchronization aspect // with the same element name this means this array snapshot is using // generation names and we will not ingest it. In this case, make sure // the aspect is not placed in the aspect map. This will prevent these // aspects from being ingested as BlockSnapshotSession instances in ViPR. // Also add the duplicate name to the duplicate aspect element name map. // When the replication relationship processor runs we will use the // duplicate names map to determine if a snapshot target volume is linked // to an invalid aspect, which in turn will prevent that linked target // from being ingested as a BlockSnapshot instance in ViPR. String srcNativeGuid = getUnManagedVolumeNativeGuidFromVolumePath(srcPath); String elementName = getCIMPropertyValue(instance, Constants.ELEMENTNAME); boolean isDuplicateElementNameForSrc = false; if (processedNameMap.containsKey(srcNativeGuid)) { Set<String> elementNamesForSrc = processedNameMap.get(srcNativeGuid); if (elementNamesForSrc.contains(elementName)) { _logger.info("Processed duplicate synchronization aspect element name {} for source {}", elementName, srcNativeGuid); Set<String> duplicateElementNamesForSrc; if (_duplicateSyncAspectElementNameMap.containsKey(srcNativeGuid)) { duplicateElementNamesForSrc = _duplicateSyncAspectElementNameMap.get(srcNativeGuid); } else { duplicateElementNamesForSrc = new HashSet<String>(); _duplicateSyncAspectElementNameMap.put(srcNativeGuid, duplicateElementNamesForSrc); } duplicateElementNamesForSrc.add(elementName); isDuplicateElementNameForSrc = true; } else { elementNamesForSrc.add(elementName); } } else { Set<String> elementNamesForSrc = new HashSet<String>(); elementNamesForSrc.add(elementName); processedNameMap.put(srcNativeGuid, elementNamesForSrc); } Map<String, String> aspectsForSource; String aspectKey = getSyncAspectMapKey(srcNativeGuid, elementName); if (!isDuplicateElementNameForSrc) { if (_syncAspectMap.containsKey(srcNativeGuid)) { aspectsForSource = _syncAspectMap.get(srcNativeGuid); } else { aspectsForSource = new HashMap<String, String>(); _syncAspectMap.put(srcNativeGuid, aspectsForSource); } aspectsForSource.put(aspectKey, instance.getObjectPath().getKeyValue(Constants.INSTANCEID).toString()); } else { aspectsForSource = _syncAspectMap.get(srcNativeGuid); aspectsForSource.remove(aspectKey); } } catch (Exception e) { _logger.error("Exception on processing instances", e); } } return count; } }