/* * Copyright (c) 2013 EMC Corporation * All Rights Reserved */ package com.emc.storageos.volumecontroller.impl.utils.attrmatchers; import static com.emc.storageos.db.client.model.StorageSystem.AsyncActions.CreateGroupReplica; import static com.emc.storageos.db.client.util.CommonTransformerFunctions.fctnStoragePoolToStorageSystemURI; import static com.google.common.collect.Collections2.transform; import static com.google.common.collect.Lists.newArrayList; import java.net.URI; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; 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.model.StoragePool; import com.emc.storageos.db.client.model.StorageSystem; import com.emc.storageos.db.client.model.StringSet; import com.emc.storageos.volumecontroller.AttributeMatcher; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableSet; /** * StorageSystemMatcher is responsible to match the storage systems of Storage * Pools. * */ public class MultiVolumeConsistencyMatcher extends AttributeMatcher { private static final Logger _logger = LoggerFactory .getLogger(MultiVolumeConsistencyMatcher.class); /** * Check whether the given StoragePool supports ConsistencyGroups */ @Override public List<StoragePool> matchStoragePoolsWithAttributeOn(List<StoragePool> pools, Map<String, Object> attributeMap, StringBuffer errorMessage) { final List<StoragePool> matchedPools = new ArrayList<StoragePool>(); final Iterator<StoragePool> poolIterator = pools.iterator(); Map<URI, StorageSystem> storageSystems = getStorageSystems(pools); _logger.info("Pools Matching MultiVolumeConsisistency attribute Started:{}", Joiner.on("\t").join(getNativeGuidFromPools(pools))); while (poolIterator.hasNext()) { final StoragePool pool = poolIterator.next(); final StorageSystem system = storageSystems.get(pool.getStorageDevice()); // Add pool if any of the check* methods return true if (checkAsynchronousActions(system) || checkStorageSystemType(system)) { matchedPools.add(pool); } else { _logger.info("Ignoring pool {} as it does not support Consistency Groups", pool.getNativeGuid()); continue; } } _logger.info("Pool Matching MultiVolumeConsistency Matcher Ended:{}", Joiner.on("\t").join(getNativeGuidFromPools(matchedPools))); if (CollectionUtils.isEmpty(matchedPools)) { errorMessage.append("No matching stoarge pool found with consistency group support. "); _logger.error(errorMessage.toString()); } return matchedPools; } @Override protected boolean isAttributeOn(Map<String, Object> attributeMap) { if (attributeMap == null || attributeMap.get(Attributes.multi_volume_consistency.name()) == null) { return false; } final Boolean multiVolumeConsistency = (Boolean) attributeMap.get(Attributes.multi_volume_consistency.name()); return (multiVolumeConsistency != null && multiVolumeConsistency); } private Map<URI, StorageSystem> getStorageSystems(List<StoragePool> pools) { // Convert list of StoragePool to list of associated StorageSystem URI's Collection<URI> systemURIs = transform(pools, fctnStoragePoolToStorageSystemURI()); // Remove duplicates using a Set ImmutableSet<URI> uniqueURIs = ImmutableSet.copyOf(systemURIs); // Query all systems in one call (need to convert back to a List) List<StorageSystem> storageSystems = _objectCache.queryObject(StorageSystem.class, newArrayList(uniqueURIs)); // Finally, create a map of StorageSystemURI -> StorageSystem Map<URI, StorageSystem> result = new HashMap<>(); for (StorageSystem system : storageSystems) { result.put(system.getId(), system); } return result; } private boolean checkAsynchronousActions(StorageSystem system) { StringSet asyncSet = system.getSupportedAsynchronousActions(); // Only add pools that support ConsistencyGroups (i.e. CreateGroupReplica is present within asynchronous actions) return asyncSet != null && !asyncSet.isEmpty() && asyncSet.contains(CreateGroupReplica.name()); } private boolean checkStorageSystemType(StorageSystem system) { if (StorageSystem.Type.scaleio.name().equalsIgnoreCase(system.getSystemType()) || StorageSystem.Type.xtremio.name().equalsIgnoreCase(system.getSystemType()) || StorageSystem.Type.hds.name().equalsIgnoreCase(system.getSystemType()) || StorageSystem.Type.openstack.name().equalsIgnoreCase(system.getSystemType()) || StorageSystem.Type.ceph.name().equalsIgnoreCase(system.getSystemType())) { return true; } return false; } }