package com.emc.storageos.volumecontroller.impl.utils; import static com.emc.storageos.db.client.util.NullColumnValueGetter.isNullURI; import java.net.URI; import java.util.List; import com.emc.storageos.db.client.DbClient; import com.emc.storageos.db.client.model.BlockConsistencyGroup; import com.emc.storageos.db.client.model.BlockMirror; import com.emc.storageos.db.client.model.BlockObject; import com.emc.storageos.db.client.model.BlockSnapshot; import com.emc.storageos.db.client.model.BlockSnapshotSession; import com.emc.storageos.db.client.model.DiscoveredDataObject; import com.emc.storageos.db.client.model.StorageSystem; import com.emc.storageos.db.client.model.Volume; import com.emc.storageos.db.client.util.NullColumnValueGetter; import com.emc.storageos.volumecontroller.impl.ControllerUtils; /** * Utility class for acquiring/checking consistency groups from ViPR block objects. * * @author Ian Bibby */ public class ConsistencyGroupUtils { /** * Gets the {@BlockConsistencyGroup} associated with the given clone. * * @param cloneURI * @param dbClient * @return */ public static BlockConsistencyGroup getCloneConsistencyGroup(URI cloneURI, DbClient dbClient) { BlockConsistencyGroup cgResult = null; Volume clone = dbClient.queryObject(Volume.class, cloneURI); if (clone != null) { URI systemURI = clone.getStorageController(); StorageSystem storage = dbClient.queryObject(StorageSystem.class, systemURI); if (storage.deviceIsType(DiscoveredDataObject.Type.ibmxiv)) { return null; } URI source = clone.getAssociatedSourceVolume(); BlockObject sourceObj = BlockObject.fetch(dbClient, source); if (sourceObj instanceof BlockSnapshot) { return null; } Volume sourceVolume = (Volume) sourceObj; if (!isNullURI(sourceVolume.getConsistencyGroup())) { final URI cgId = sourceVolume.getConsistencyGroup(); if (cgId != null) { cgResult = dbClient.queryObject(BlockConsistencyGroup.class, cgId); if (!ControllerUtils.checkCGCreatedOnBackEndArray(sourceVolume)) { return null; } } } } return cgResult; } public static BlockConsistencyGroup getSnapshotSessionConsistencyGroup(URI snapshotSession, DbClient dbClient) { BlockSnapshotSession snapshotSessionObj = dbClient.queryObject(BlockSnapshotSession.class, snapshotSession); if (snapshotSessionObj != null) { URI consistencyGroupId = snapshotSessionObj.getConsistencyGroup(); if (!isNullURI(consistencyGroupId) && NullColumnValueGetter.isNotNullValue(snapshotSessionObj.getReplicationGroupInstance())) { return dbClient.queryObject(BlockConsistencyGroup.class, consistencyGroupId); } } return null; } /** * Returns true, if the given clone is in a consistency group, false otherwise. * * @param cloneURI * @param dbClient * @return */ public static boolean isCloneInConsistencyGroup(URI cloneURI, DbClient dbClient) { return getCloneConsistencyGroup(cloneURI, dbClient) != null; } /** * Gets the {@BlockConsistencyGroup} associated with a snapshot in the given list of snapshots. * * @param snapshots * @param dbClient * @return */ public static BlockConsistencyGroup getSnapshotsConsistencyGroup(List<BlockSnapshot> snapshots, DbClient dbClient) { if (snapshots.isEmpty()) { return null; } BlockConsistencyGroup cgResult = null; BlockSnapshot snapshot = snapshots.get(0); if (snapshot != null && !isNullURI(snapshot.getConsistencyGroup()) && getSourceConsistencyGroupName(snapshot, dbClient) != null) { cgResult = dbClient.queryObject(BlockConsistencyGroup.class, snapshot.getConsistencyGroup()); } return cgResult; } /** * Gets the source consistency group name. * If the given block object is Volume, get the group name from Volume object. * If snapshot, mirror or clone, get the group name from its parent which is Volume. * * @param bo the block object * @return the consistency group name */ public static String getSourceConsistencyGroupName(BlockObject bo, DbClient dbClient) { Volume volume = null; if (bo instanceof BlockSnapshot) { volume = dbClient.queryObject(Volume.class, ((BlockSnapshot) bo).getParent().getURI()); } else if (bo instanceof BlockMirror) { volume = dbClient.queryObject(Volume.class, ((BlockMirror) bo).getSource().getURI()); } else if (bo instanceof Volume) { volume = (Volume) bo; if (ControllerUtils.isVolumeFullCopy(volume, dbClient)) { volume = dbClient.queryObject(Volume.class, volume.getAssociatedSourceVolume()); } } if (volume == null || NullColumnValueGetter.isNullValue(volume.getReplicationGroupInstance())) { return null; } return volume.getReplicationGroupInstance(); } /** * Returns true, if a snapshot in the given list of snapshots is in a consistency group, false otherwise. * * @param snapshots * @param dbClient * @return */ public static boolean isSnapshotInConsistencyGroup(List<BlockSnapshot> snapshots, DbClient dbClient) { return getSnapshotsConsistencyGroup(snapshots, dbClient) != null; } /** * Gets the {@BlockConsistencyGroup} associated with a mirror in the given list of mirrors. * * @param mirrors * @param dbClient * @return */ public static BlockConsistencyGroup getMirrorsConsistencyGroup(List<URI> mirrors, DbClient dbClient) { BlockMirror mirror = dbClient.queryObject(BlockMirror.class, mirrors.get(0)); Volume source = dbClient.queryObject(Volume.class, mirror.getSource().getURI()); BlockConsistencyGroup cgResult = null; if (source != null && source.isInCG() && ControllerUtils.checkCGCreatedOnBackEndArray(source)) { cgResult = dbClient.queryObject(BlockConsistencyGroup.class, source.getConsistencyGroup()); } return cgResult; } /** * Returns true, if a mirror in the given list of mirrors is in a consistency group, false otherwise. * * @param mirrors * @param dbClient * @return */ public static boolean isMirrorInConsistencyGroup(List<URI> mirrors, DbClient dbClient) { return getMirrorsConsistencyGroup(mirrors, dbClient) != null; } }