/* * Copyright (c) 2016 EMC Corporation * All Rights Reserved */ package com.emc.storageos.api.service.impl.resource.blockingestorchestration.cg; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.Map.Entry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.emc.storageos.api.service.impl.resource.blockingestorchestration.context.IngestionRequestContext; import com.emc.storageos.db.client.model.AbstractChangeTrackingSet; import com.emc.storageos.db.client.model.BlockConsistencyGroup; import com.emc.storageos.db.client.model.BlockConsistencyGroup.Types; import com.emc.storageos.db.client.model.BlockObject; import com.emc.storageos.db.client.model.StringSetMap; import com.emc.storageos.db.client.model.Volume; import com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume; import com.emc.storageos.db.client.util.NullColumnValueGetter; /** * This decorator is responsible for decorating the CG with the backend/regular volume. * * If the BlockObjects are behind RP + VPLEX, blockConsistencyGroup should belongs to RP. * And should decorate the CG with the VPLEX & its backend volumes protected by RP. * * */ public class BlockVolumeCGIngestDecorator extends BlockCGIngestDecorator { private static final Logger logger = LoggerFactory.getLogger(BlockVolumeCGIngestDecorator.class); @Override public void decorateCG(BlockConsistencyGroup cg, Collection<BlockObject> associatedObjects, IngestionRequestContext requestContext, UnManagedVolume unManagedVolume) throws Exception { if (null == associatedObjects || associatedObjects.isEmpty()) { logger.info("No associated BlockObject's found to decorate for cg {}", cg.getLabel()); return; } for (BlockObject blockObj : associatedObjects) { StringSetMap systemCGs = cg.getSystemConsistencyGroups(); // No entries yet in the system consistency groups list. That's OK, we'll create it. if (null == systemCGs || systemCGs.isEmpty()) { cg.setSystemConsistencyGroups(new StringSetMap()); } // This volume is not in a CG of this type if (NullColumnValueGetter.isNullValue(blockObj.getReplicationGroupInstance())) { logger.info("BlockObject {} doesn't have replicationGroup name {}. No need to set system cg information.", blockObj.getNativeGuid()); continue; } boolean found = false; // Look through the existing entries in the CG and see if we find a match. for (Entry<String, AbstractChangeTrackingSet<String>> systemCGEntry : systemCGs.entrySet()) { if (systemCGEntry.getKey().equalsIgnoreCase(blockObj.getStorageController().toString())) { if (systemCGEntry.getValue().contains(blockObj.getReplicationGroupInstance())) { logger.info(String.format("Found BlockObject %s,%s system details in cg %s", blockObj.getNativeGuid(), blockObj.getReplicationGroupInstance(), cg.getLabel())); found = true; break; } } } // If we didn't find this storage:cg combo, let's add it. if (!found) { logger.info(String.format("Adding BlockObject %s/%s in CG %s", blockObj.getNativeGuid(), blockObj.getReplicationGroupInstance(), cg.getLabel())); cg.addSystemConsistencyGroup(blockObj.getStorageController().toString(), blockObj.getReplicationGroupInstance()); } if (!cg.getTypes().contains(Types.LOCAL.toString())) { cg.getTypes().add(Types.LOCAL.toString()); } } } @Override protected Collection<BlockObject> getAssociatedObjects(BlockConsistencyGroup cg, Collection<BlockObject> allCGBlockObjects, IngestionRequestContext requestContext) throws Exception { Collection<BlockObject> blockObjects = new ArrayList<BlockObject>(); // Filter out vplex volumes Iterator<BlockObject> allCGBlockObjectItr = allCGBlockObjects.iterator(); while (allCGBlockObjectItr.hasNext()) { BlockObject blockObject = allCGBlockObjectItr.next(); if (blockObject instanceof Volume) { Volume volume = (Volume) blockObject; if (null == volume.getAssociatedVolumes() || volume.getAssociatedVolumes().isEmpty()) { blockObjects.add(volume); } } } return blockObjects; } @Override public boolean isExecuteDecorator(UnManagedVolume umv, IngestionRequestContext requestContext) { return true; } @Override public void setNextDecorator(BlockCGIngestDecorator decorator) { this.nextCGIngestDecorator = decorator; } }