Search in sources :

Example 21 with ProtectionSet

use of com.emc.storageos.db.client.model.ProtectionSet in project coprhd-controller by CoprHD.

the class BlockObjectMultipleConsistencyGroupsMigration method consolidateDuplicates.

/**
 * searches for protection sets with duplicate names and consolidates into one protection set
 *
 * @return
 */
private void consolidateDuplicates() {
    Map<String, List<ProtectionSet>> labelURIListMap = new HashMap<String, List<ProtectionSet>>();
    List<URI> protectionSetURIs = dbClient.queryByType(ProtectionSet.class, true);
    log.info("Scanning ProtectionSets for duplicate names.");
    for (URI protectionSetURI : protectionSetURIs) {
        ProtectionSet protectionSet = dbClient.queryObject(ProtectionSet.class, protectionSetURI);
        if (protectionSet == null || protectionSet.getInactive()) {
            log.info("Skipping null or inactive protection set {}", protectionSetURI);
            continue;
        }
        if (!labelURIListMap.containsKey(protectionSet.getLabel())) {
            labelURIListMap.put(protectionSet.getLabel(), new ArrayList<ProtectionSet>());
        }
        labelURIListMap.get(protectionSet.getLabel()).add(protectionSet);
    }
    List<ProtectionSet> protectionSetsToDelete = new ArrayList<ProtectionSet>();
    List<ProtectionSet> protectionSetsToPersist = new ArrayList<ProtectionSet>();
    List<Volume> volumesToPersist = new ArrayList<Volume>();
    List<BlockSnapshot> snapsToPersist = new ArrayList<BlockSnapshot>();
    for (Entry<String, List<ProtectionSet>> entry : labelURIListMap.entrySet()) {
        if (entry.getValue().size() > 1) {
            log.info("Duplicate protection sets found {} | {}", entry.getKey(), entry.getValue().toArray());
            ProtectionSet protectionSet = entry.getValue().iterator().next();
            for (ProtectionSet duplicate : entry.getValue()) {
                if (duplicate.getId().equals(protectionSet.getId())) {
                    continue;
                }
                log.info(String.format("duplicating %s protection set %s to %s)", protectionSet.getLabel(), duplicate.getId(), protectionSet.getId()));
                // add the volumes from the duplicate to the original
                protectionSet.getVolumes().addAll(duplicate.getVolumes());
                // reset the protection set id on the volumes in the duplicate
                for (String volid : duplicate.getVolumes()) {
                    Volume vol = dbClient.queryObject(Volume.class, URI.create(volid));
                    if (vol == null || vol.getInactive()) {
                        log.info("Skipping null or inactive volume {}", volid);
                        continue;
                    }
                    log.info(String.format("Changing protection set id on volume %s from %s to %s", vol.getId(), vol.getProtectionSet().getURI(), protectionSet.getId()));
                    vol.setProtectionSet(new NamedURI(protectionSet.getId(), protectionSet.getLabel()));
                    volumesToPersist.add(vol);
                }
                // reset any block snapshot that points to the duplicate protection set
                URIQueryResultList blockSnapIds = new URIQueryResultList();
                Constraint constraint = ContainmentConstraint.Factory.getProtectionSetBlockSnapshotConstraint(duplicate.getId());
                dbClient.queryByConstraint(constraint, blockSnapIds);
                Iterator<URI> itr = blockSnapIds.iterator();
                while (itr.hasNext()) {
                    URI snapId = itr.next();
                    BlockSnapshot snap = dbClient.queryObject(BlockSnapshot.class, snapId);
                    if (snap == null || snap.getInactive()) {
                        log.info("Skipping null or inactive volume {}", snapId);
                        continue;
                    }
                    log.info(String.format("Changing protection set id on snapshot %s from %s to %s", snap.getId(), snap.getProtectionSet(), protectionSet.getId()));
                    snap.setProtectionSet(protectionSet.getId());
                    snapsToPersist.add(snap);
                }
                log.info("deleting duplicate protection set {}", duplicate.getId());
                protectionSetsToDelete.add(duplicate);
            }
            protectionSetsToPersist.add(protectionSet);
        }
    }
    dbClient.persistObject(protectionSetsToPersist);
    dbClient.persistObject(volumesToPersist);
    dbClient.persistObject(snapsToPersist);
    dbClient.markForDeletion(protectionSetsToDelete);
}
Also used : HashMap(java.util.HashMap) NamedURI(com.emc.storageos.db.client.model.NamedURI) Constraint(com.emc.storageos.db.client.constraint.Constraint) ContainmentConstraint(com.emc.storageos.db.client.constraint.ContainmentConstraint) ProtectionSet(com.emc.storageos.db.client.model.ProtectionSet) ArrayList(java.util.ArrayList) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) Volume(com.emc.storageos.db.client.model.Volume) ArrayList(java.util.ArrayList) List(java.util.List) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList)

Example 22 with ProtectionSet

use of com.emc.storageos.db.client.model.ProtectionSet in project coprhd-controller by CoprHD.

the class BlockObjectMultipleConsistencyGroupsMigration method cleanupStaleProtectionSetVolumes.

/**
 * Cleans up stale ProtectionSet volume references. Meaning, volumes referenced
 * by the ProtectionSet that no longer exist in the DB will be removed. Also,
 * if the ProtectionSet ends up containing zero volumes after this operation, the
 * ProtectionSet itself will be removed from the DB.
 *
 * @param protectionSetUri the ProtectionSet to be cleaned-up.
 * @return boolean true if the ProtectionSet has been removed from the DB, false otherwise.
 */
private boolean cleanupStaleProtectionSetVolumes(URI protectionSetURI) {
    ProtectionSet protectionSet = dbClient.queryObject(ProtectionSet.class, protectionSetURI);
    boolean protectionSetRemoved = false;
    if (protectionSet != null) {
        StringSet protectionSetVolumes = protectionSet.getVolumes();
        StringSet volumesToRemove = new StringSet();
        if (protectionSetVolumes != null) {
            Iterator<String> volumesItr = protectionSetVolumes.iterator();
            while (volumesItr.hasNext()) {
                String volumeUriStr = volumesItr.next();
                Volume volume = dbClient.queryObject(Volume.class, URI.create(volumeUriStr));
                if (volume == null) {
                    volumesToRemove.add(volumeUriStr);
                    // Volume is referenced by the ProtectionSet but it is not in the database. It should
                    // be removed from the ProtectionSet.
                    log.info("Removing stale Volume {} referenced by ProtectionSet {}.", volumeUriStr, protectionSet.getId());
                }
            }
            if (protectionSetVolumes.size() == volumesToRemove.size()) {
                // There are no volume references for this ProtectionSet so remove it.
                log.info("ProtectionSet {} has no volume references so it is being removed.", protectionSet.getId());
                dbClient.markForDeletion(protectionSet);
                protectionSetRemoved = true;
            } else {
                // Stale volume references have been removed.
                protectionSetVolumes.removeAll(volumesToRemove);
                dbClient.persistObject(protectionSet);
            }
        }
    }
    return protectionSetRemoved;
}
Also used : Volume(com.emc.storageos.db.client.model.Volume) ProtectionSet(com.emc.storageos.db.client.model.ProtectionSet) StringSet(com.emc.storageos.db.client.model.StringSet)

Example 23 with ProtectionSet

use of com.emc.storageos.db.client.model.ProtectionSet in project coprhd-controller by CoprHD.

the class BlockObjectMultipleConsistencyGroupsMigration method migrateRpConsistencyGroups.

/**
 * Migrates the RP/RP+VPlex BlockConsistencyGroups and BlockObjects.
 */
private void migrateRpConsistencyGroups() {
    log.info("Migrating RP+VPlex BlockConsistencyGroup objects and Volume references.");
    List<URI> protectionSetURIs = dbClient.queryByType(ProtectionSet.class, true);
    log.info("Scanning ProtectionSets for stale Volume references.");
    for (URI protectionSetURI : protectionSetURIs) {
        // First, cleanup any stale volume references for the ProtectionSet
        if (cleanupStaleProtectionSetVolumes(protectionSetURI)) {
            log.info("ProtectionSet {} has been removed so continuing to the next one.", protectionSetURI);
        }
    }
    consolidateDuplicates();
    protectionSetURIs = dbClient.queryByType(ProtectionSet.class, true);
    log.info("Scanning ProtectionSets for RP+VPlex Volume references.");
    for (URI protectionSetURI : protectionSetURIs) {
        // Lookup the ProtectionSet again after stale volume references have been removed.
        ProtectionSet protectionSet = dbClient.queryObject(ProtectionSet.class, protectionSetURI);
        log.info("Scanning ProtectionSet {}|{} ", protectionSet.getLabel(), protectionSet.getId());
        if (protectionSet != null && protectionSet.getVolumes() != null) {
            // are RP+VPlex volumes.
            if (protectionSet.getVolumes() != null && !protectionSet.getVolumes().isEmpty()) {
                Iterator<String> protectionSetVolumes = protectionSet.getVolumes().iterator();
                Volume protectionSetVolume = null;
                while (protectionSetVolumes.hasNext()) {
                    Volume vol = dbClient.queryObject(Volume.class, URI.create(protectionSetVolumes.next()));
                    if (vol != null) {
                        log.info("Using ProtectionSet Volume {}|{} to migrate consistency group.", vol.getLabel(), vol.getId());
                        protectionSetVolume = vol;
                        break;
                    }
                }
                BlockConsistencyGroup primaryCg = null;
                // other type of volume will only reference a single BlockConsistencyGroup.
                if (protectionSetVolume.getConsistencyGroups() != null && !protectionSetVolume.getConsistencyGroups().isEmpty() && protectionSetVolume.getConsistencyGroups().size() == 2) {
                    log.info("Found RP+VPlex ProtectionSet {}|{}.  Preparing to migrated referenced RP+VPlex " + "volumes and associated BlockConsistencyGroups.", protectionSet.getLabel(), protectionSet.getId());
                    // There are references to 2 different BlockConsistencyGroup objects,
                    // so this is an RP+VPlex volume.
                    Iterator<String> cgUriItr = protectionSetVolume.getConsistencyGroups().iterator();
                    log.info("Attempting to locate the RP BlockConsistencyGroup for Volume {}|{}", protectionSetVolume.getLabel(), protectionSetVolume.getId());
                    while (cgUriItr.hasNext()) {
                        BlockConsistencyGroup cg = dbClient.queryObject(BlockConsistencyGroup.class, URI.create(cgUriItr.next()));
                        log.info("Found BlockConsistencyGroup {} of type {}", cg.getLabel(), cg.getType());
                        // will be mapped to this primary BlockConsistencyGroup.
                        if (cg.getTypes() != null && cg.getType().equals(Types.RP.name())) {
                            log.info("Primary RP BlockConsistencyGroup {} found for ProtectionSet {}.", cg.getLabel(), protectionSet.getLabel());
                            primaryCg = cg;
                            // Add the RP type
                            primaryCg.addConsistencyGroupTypes(Types.RP.name());
                            break;
                        }
                    }
                    if (primaryCg == null) {
                        log.warn("Unable to migration volumes/consistency groups associated with ProtectionSet {}.  Could not find an RP associated BlockConsistencyGroup for Volume {}.  ", protectionSet.getId(), protectionSetVolume.getId());
                        continue;
                    }
                    // Migrate the protection system/cg entry that replaces the use of the deviceName field.
                    primaryCg.addSystemConsistencyGroup(protectionSet.getProtectionSystem().toString(), "ViPR-" + primaryCg.getLabel());
                    Iterator<String> volumeUriItr = protectionSet.getVolumes().iterator();
                    while (volumeUriItr.hasNext()) {
                        String volumeUri = volumeUriItr.next();
                        Volume volume = dbClient.queryObject(Volume.class, URI.create(volumeUri));
                        if (volume != null) {
                            log.info("Scanning volume {} for protection set {}.", volume.getLabel(), protectionSet.getLabel());
                            // Get the volume's VPlex CG, copy the info in the primary CG, and remove
                            // the VPlex CG from Cassandra.
                            BlockConsistencyGroup vplexCg = null;
                            if (volume.getConsistencyGroups() != null && !volume.getConsistencyGroups().isEmpty()) {
                                cgUriItr = volume.getConsistencyGroups().iterator();
                                while (cgUriItr.hasNext()) {
                                    BlockConsistencyGroup cg = dbClient.queryObject(BlockConsistencyGroup.class, URI.create(cgUriItr.next()));
                                    if (cg.getType() != null && cg.getType().equals(Types.VPLEX.name())) {
                                        vplexCg = cg;
                                        log.info("Volume {} belongs to VPLEX BlockConsistencyGroup {}.", volume.getLabel(), cg.getLabel());
                                        break;
                                    }
                                }
                            }
                            if (vplexCg != null && volume.getAssociatedVolumes() != null) {
                                // Copy the VPlex CG info over to the primary CG
                                StorageSystem vplexStorageSystem = dbClient.queryObject(StorageSystem.class, vplexCg.getStorageController());
                                String clusterId = getVPlexClusterFromVolume(volume);
                                primaryCg.addSystemConsistencyGroup(vplexStorageSystem.getId().toString(), BlockConsistencyGroupUtils.buildClusterCgName(clusterId, vplexCg.getLabel()));
                                if (NullColumnValueGetter.isNullURI(primaryCg.getStorageController())) {
                                    primaryCg.setStorageController(vplexStorageSystem.getId());
                                }
                                if (!primaryCg.getTypes().contains(Types.VPLEX.name())) {
                                    // Add the VPlex type
                                    primaryCg.addConsistencyGroupTypes(Types.VPLEX.name());
                                }
                                primaryCg.setType(NullColumnValueGetter.getNullStr());
                                primaryCg.setDeviceName(NullColumnValueGetter.getNullStr());
                                // Persist the changes to the primary CG, update the volume reference to the single
                                // primary CG, and remove the VPlex CG.
                                dbClient.persistObject(primaryCg);
                                volume.setConsistencyGroup(primaryCg.getId());
                                StringSet cgs = volume.getConsistencyGroups();
                                cgs.remove(vplexCg.getId().toString());
                                volume.setConsistencyGroups(cgs);
                                dbClient.persistObject(volume);
                                log.info("Volume {} fields have been migrated.", volume.getLabel());
                                dbClient.markForDeletion(vplexCg);
                                log.info("VPlex BlockConsistencyGroup {} has been migrated over to RP BlockConsistencyGroup and has been deleted.", vplexCg.getLabel(), primaryCg.getLabel());
                            }
                        }
                    }
                } else if (protectionSetVolume != null && protectionSetVolume.getConsistencyGroups() != null && !protectionSetVolume.getConsistencyGroups().isEmpty() && protectionSetVolume.getConsistencyGroups().size() == 1) {
                    Iterator<String> cgUriItr = protectionSetVolume.getConsistencyGroups().iterator();
                    BlockConsistencyGroup cg = dbClient.queryObject(BlockConsistencyGroup.class, URI.create(cgUriItr.next()));
                    // Migration logic for RP only BlockConsistencyGroup
                    cg.addConsistencyGroupTypes(cg.getType());
                    // In ViPR 2.0, the RP deviceName was not being prefixed with 'ViPR-', which is what is used on
                    // the actual RP appliance for the CG name.
                    cg.addSystemConsistencyGroup(protectionSet.getProtectionSystem().toString(), "ViPR-" + cg.getLabel());
                    // Remove type and deviceName fields
                    cg.setType(NullColumnValueGetter.getNullStr());
                    cg.setDeviceName(NullColumnValueGetter.getNullStr());
                    dbClient.persistObject(cg);
                }
            }
        }
    }
}
Also used : Volume(com.emc.storageos.db.client.model.Volume) ProtectionSet(com.emc.storageos.db.client.model.ProtectionSet) StringSet(com.emc.storageos.db.client.model.StringSet) Iterator(java.util.Iterator) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 24 with ProtectionSet

use of com.emc.storageos.db.client.model.ProtectionSet in project coprhd-controller by CoprHD.

the class BlockObjectMultipleConsistencyGroupsMigrationTest method prepareRPVplexConsistencyGroupData.

/**
 * Prepares the RP + VPlex consistency group test data.
 *
 * @throws Exception
 */
private void prepareRPVplexConsistencyGroupData() throws Exception {
    String cg1Name = "rpVplexCg";
    // Create the primary RecoverPoint BlockConsistencyGroup that will be shared by all the
    // RP+VPlex volumes.
    BlockConsistencyGroup rpVplexCg = createBlockConsistencyGroup(cg1Name, null, Types.RP.name(), true);
    // Save the CG references for migration verification.
    rpVplexPrimaryConsistencyGroupURI = rpVplexCg.getId();
    // Create the ProtectionSet that the RP + VPlex volumes will belong to.
    ProtectionSet rpVplexProtectionSet = createProtectionSet(cg1Name, projectURI);
    // Create all the RP+VPlex volumes
    List<Volume> rpVplexVolumes = createRpVolumes("rpVplexCgVolume1", 1, rpVplexProtectionSet, true);
    rpVplexVolumes.addAll(createRpVolumes("rpVplexCgVolume2", 1, rpVplexProtectionSet, true));
    // Add the RP + VPlex volumes to the RP consistency group
    addVolumesToBlockConsistencyGroup(rpVplexCg.getId(), rpVplexVolumes);
    // Add the RP+VPlex volumes to the protection set.
    addVolumesToProtectionSet(rpVplexProtectionSet.getId(), rpVplexVolumes);
}
Also used : Volume(com.emc.storageos.db.client.model.Volume) ProtectionSet(com.emc.storageos.db.client.model.ProtectionSet) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup)

Example 25 with ProtectionSet

use of com.emc.storageos.db.client.model.ProtectionSet in project coprhd-controller by CoprHD.

the class BlockObjectMultipleConsistencyGroupsMigrationTest method verifyStaleProtectionSet.

/**
 * Verifies that ProtectionSets referencing all stale volumes get removed from the DB.
 */
private void verifyStaleProtectionSet() {
    ProtectionSet protectionSet = _dbClient.queryObject(ProtectionSet.class, staleProtectionSetURI);
    Assert.assertTrue("ProtectionSet  " + staleProtectionSetURI + " is stale and should have been removed.", (protectionSet == null || protectionSet.getInactive()));
}
Also used : ProtectionSet(com.emc.storageos.db.client.model.ProtectionSet)

Aggregations

ProtectionSet (com.emc.storageos.db.client.model.ProtectionSet)57 Volume (com.emc.storageos.db.client.model.Volume)39 URI (java.net.URI)30 NamedURI (com.emc.storageos.db.client.model.NamedURI)26 ArrayList (java.util.ArrayList)25 StringSet (com.emc.storageos.db.client.model.StringSet)18 UnManagedProtectionSet (com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedProtectionSet)14 BlockConsistencyGroup (com.emc.storageos.db.client.model.BlockConsistencyGroup)13 UnManagedVolume (com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume)11 URISyntaxException (java.net.URISyntaxException)10 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)9 BlockSnapshot (com.emc.storageos.db.client.model.BlockSnapshot)9 ProtectionSystem (com.emc.storageos.db.client.model.ProtectionSystem)9 RecoverPointClient (com.emc.storageos.recoverpoint.impl.RecoverPointClient)9 HashSet (java.util.HashSet)8 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)7 RecoverPointException (com.emc.storageos.recoverpoint.exceptions.RecoverPointException)7 FunctionalAPIActionFailedException_Exception (com.emc.fapiclient.ws.FunctionalAPIActionFailedException_Exception)6 FunctionalAPIInternalError_Exception (com.emc.fapiclient.ws.FunctionalAPIInternalError_Exception)6 RecoverPointVolumeIngestionContext (com.emc.storageos.api.service.impl.resource.blockingestorchestration.context.impl.RecoverPointVolumeIngestionContext)6