use of com.emc.storageos.db.client.model.BlockConsistencyGroup 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);
}
}
}
}
}
use of com.emc.storageos.db.client.model.BlockConsistencyGroup in project coprhd-controller by CoprHD.
the class SRDFVolumesInCGMigration method updateVolumesInConsistencyGroup.
/**
* Migrate the SRDF volumes in CG
*/
private void updateVolumesInConsistencyGroup() {
log.info("Migrating SRDF volumes in CG");
DbClient dbClient = getDbClient();
List<URI> volumeURIs = dbClient.queryByType(Volume.class, true);
Iterator<Volume> volumes = dbClient.queryIterativeObjects(Volume.class, volumeURIs);
int totalVolumes = 0;
int volumesUpdated = 0;
while (volumes.hasNext()) {
totalVolumes++;
Volume volume = volumes.next();
if (!NullColumnValueGetter.isNullURI(volume.getStorageController()) && !NullColumnValueGetter.isNullURI(volume.getConsistencyGroup())) {
URI cgUri = volume.getConsistencyGroup();
URI storageUri = volume.getStorageController();
BlockConsistencyGroup cg = dbClient.queryObject(BlockConsistencyGroup.class, cgUri);
StorageSystem system = dbClient.queryObject(StorageSystem.class, storageUri);
if (cg == null || system == null) {
log.warn(String.format("Volume %s is being skipped because the refrenced CG or storage system is null; cgUri: %s; storageUri: %s", volume.getId().toString(), cgUri.toString(), storageUri.toString()));
continue;
}
if (volume.getSrdfParent() != null || volume.getSrdfTargets() != null) {
String replicationGroupName = cg.getCgNameOnStorageSystem(volume.getStorageController());
if (replicationGroupName != null && !replicationGroupName.isEmpty() && NullColumnValueGetter.isNullValue(volume.getReplicationGroupInstance())) {
log.info("updating the SRDF volume {} replicationgroup {}", volume.getLabel(), replicationGroupName);
volume.setReplicationGroupInstance(replicationGroupName);
dbClient.updateObject(volume);
volumesUpdated++;
}
}
}
}
log.info(String.format("%d volumes updated out of a total of %d volumes", volumesUpdated, totalVolumes));
}
use of com.emc.storageos.db.client.model.BlockConsistencyGroup in project coprhd-controller by CoprHD.
the class BlockObjectConsistencyGroupMigrationTest method createBlockConsistencyGroup.
/**
* Creates the consistency group used by the BlockObjects.
*
* @param name
* @return
*/
private URI createBlockConsistencyGroup(String name) {
BlockConsistencyGroup cg = new BlockConsistencyGroup();
URI cgURI = URIUtil.createId(BlockConsistencyGroup.class);
cg.setId(cgURI);
cg.setLabel(name);
_dbClient.createObject(cg);
return cg.getId();
}
use of com.emc.storageos.db.client.model.BlockConsistencyGroup 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);
}
use of com.emc.storageos.db.client.model.BlockConsistencyGroup in project coprhd-controller by CoprHD.
the class BlockObjectMultipleConsistencyGroupsMigrationTest method createRpVolumes.
/**
* Creates the RP source volume/journal and the specified number of
* target/journal volumes.
*
* @param volumeName
* @param numTargets
*/
private List<Volume> createRpVolumes(String volumeName, int numTargets, ProtectionSet protectionSet, boolean isRpVPlex) {
List<Volume> volumes = new ArrayList<Volume>();
StringSet associatedVolumes = new StringSet();
associatedVolumes.add("associatedVol1");
StorageSystem storageSystem = null;
if (isRpVPlex) {
storageSystem = createStorageSystem(true);
} else {
storageSystem = createStorageSystem(false);
}
String rsetName = "RSet-" + volumeName;
Volume sourceVolume = new Volume();
URI sourceVolumeURI = URIUtil.createId(Volume.class);
volumes.add(sourceVolume);
sourceVolume.setId(sourceVolumeURI);
sourceVolume.setLabel(volumeName);
sourceVolume.setPersonality(Volume.PersonalityTypes.SOURCE.toString());
sourceVolume.setRSetName(rsetName);
sourceVolume.setProtectionSet(new NamedURI(protectionSet.getId(), protectionSet.getLabel()));
sourceVolume.setStorageController(storageSystem.getId());
if (isRpVPlex) {
sourceVolume.setAssociatedVolumes(associatedVolumes);
sourceVolume.setNativeId("/clusters/cluster-1/virtual-volumes/device_V000195701573-01E7A_vol");
// Create a VPLEX ViPR BlockConsistencyGroup for the source volume
BlockConsistencyGroup sourceVolumeCg = createBlockConsistencyGroup(sourceVolume.getLabel() + "-CG", storageSystem.getId(), Types.VPLEX.name(), true);
addVolumeToBlockConsistencyGroup(sourceVolumeCg.getId(), sourceVolume);
rpVplexVolumeToCgMapping.put(sourceVolumeURI, sourceVolumeCg.getId());
} else {
rpVolumeURIs.add(sourceVolumeURI);
}
_dbClient.createObject(sourceVolume);
Volume sourceVolumeJournal = new Volume();
URI sourceVolumeJournalURI = URIUtil.createId(Volume.class);
volumes.add(sourceVolumeJournal);
sourceVolumeJournal.setId(sourceVolumeJournalURI);
sourceVolumeJournal.setLabel(volumeName + RP_SRC_JOURNAL_APPEND);
sourceVolumeJournal.setPersonality(Volume.PersonalityTypes.METADATA.toString());
sourceVolumeJournal.setProtectionSet(new NamedURI(protectionSet.getId(), protectionSet.getLabel()));
sourceVolumeJournal.setStorageController(storageSystem.getId());
if (isRpVPlex) {
sourceVolumeJournal.setAssociatedVolumes(associatedVolumes);
sourceVolumeJournal.setNativeId("/clusters/cluster-1/virtual-volumes/device_V000195701573-01E7B_vol");
// Create a VPLEX ViPR BlockConsistencyGroup for the source journal volume
BlockConsistencyGroup sourceVolumeJournalCg = createBlockConsistencyGroup(sourceVolumeJournal.getLabel() + "-CG", storageSystem.getId(), Types.VPLEX.name(), true);
addVolumeToBlockConsistencyGroup(sourceVolumeJournalCg.getId(), sourceVolumeJournal);
rpVplexVolumeToCgMapping.put(sourceVolumeJournalURI, sourceVolumeJournalCg.getId());
} else {
rpVolumeURIs.add(sourceVolumeJournalURI);
}
_dbClient.createObject(sourceVolumeJournal);
for (int i = 1; i <= numTargets; i++) {
Volume sourceVolumeTarget = new Volume();
URI sourceVolumeTargetURI = URIUtil.createId(Volume.class);
volumes.add(sourceVolumeTarget);
sourceVolumeTarget.setId(sourceVolumeTargetURI);
sourceVolumeTarget.setLabel(volumeName + RP_TGT_APPEND + "vArray" + i);
sourceVolumeTarget.setPersonality(Volume.PersonalityTypes.TARGET.toString());
sourceVolumeTarget.setRSetName(rsetName);
sourceVolumeTarget.setProtectionSet(new NamedURI(protectionSet.getId(), protectionSet.getLabel()));
sourceVolumeTarget.setStorageController(storageSystem.getId());
if (isRpVPlex) {
sourceVolumeTarget.setAssociatedVolumes(associatedVolumes);
sourceVolumeTarget.setNativeId("/clusters/cluster-2/virtual-volumes/device_V000195701573-01E7C_vol" + i);
// Create a VPLEX ViPR BlockConsistencyGroup for the target volume
BlockConsistencyGroup sourceVolumeTargetCg = createBlockConsistencyGroup(sourceVolumeTarget.getLabel() + "-CG", storageSystem.getId(), Types.VPLEX.name(), true);
addVolumeToBlockConsistencyGroup(sourceVolumeTargetCg.getId(), sourceVolumeTarget);
rpVplexVolumeToCgMapping.put(sourceVolumeTargetURI, sourceVolumeTargetCg.getId());
} else {
rpVolumeURIs.add(sourceVolumeTargetURI);
}
_dbClient.createObject(sourceVolumeTarget);
Volume sourceVolumeTargetJournal = new Volume();
URI sourceVolumeTargetJournalURI = URIUtil.createId(Volume.class);
volumes.add(sourceVolumeTargetJournal);
sourceVolumeTargetJournal.setId(sourceVolumeTargetJournalURI);
sourceVolumeTargetJournal.setLabel(volumeName + RP_TGT_JOURNAL_APPEND + "vArray" + i);
sourceVolumeTargetJournal.setPersonality(Volume.PersonalityTypes.METADATA.toString());
sourceVolumeTargetJournal.setProtectionSet(new NamedURI(protectionSet.getId(), protectionSet.getLabel()));
sourceVolumeTargetJournal.setStorageController(storageSystem.getId());
if (isRpVPlex) {
sourceVolumeTargetJournal.setAssociatedVolumes(associatedVolumes);
sourceVolumeTargetJournal.setNativeId("/clusters/cluster-2/virtual-volumes/device_V000195701573-01ED_vol" + i);
// Create a VPLEX ViPR BlockConsistencyGroup for the source target journal volume
BlockConsistencyGroup sourceVolumeTargetJournalCg = createBlockConsistencyGroup(sourceVolumeTargetJournal.getLabel() + "-CG", storageSystem.getId(), Types.VPLEX.name(), true);
addVolumeToBlockConsistencyGroup(sourceVolumeTargetJournalCg.getId(), sourceVolumeTargetJournal);
rpVplexVolumeToCgMapping.put(sourceVolumeTargetJournalURI, sourceVolumeTargetJournalCg.getId());
} else {
rpVolumeURIs.add(sourceVolumeTargetJournalURI);
}
_dbClient.createObject(sourceVolumeTargetJournal);
}
return volumes;
}
Aggregations