/** * Creates the consistency group used by the BlockObjects. * * @param name * @return */ private BlockConsistencyGroup createBlockConsistencyGroup( String name, URI storageSystem, String type, boolean setType) { BlockConsistencyGroup cg = new BlockConsistencyGroup(); URI cgURI = URIUtil.createId(BlockConsistencyGroup.class); cg.setId(cgURI); cg.setLabel(name); cg.setStorageController(storageSystem); if (type.equals(Types.LOCAL.name())) { // Set the 'old' field value so it can be migrated cg.setDeviceName("localArrayDeviceName"); } else if (type.equals(Types.VPLEX.name())) { // Set the 'old' field value so it can be migrated cg.setDeviceName("vplexDeviceName"); } else if (type.equals(Types.RP.name())) { // Set the 'old' field value so it can be migrated. cg.setDeviceName("rpDeviceName"); } else if (type.equals(Types.SRDF.name())) { // Set the 'old' field value so it can be migrated cg.setDeviceName("srdfDeviceName"); } if (setType) { cg.setType(type); } // Set the 'old' field value so it can be migrated _dbClient.createObject(cg); return cg; }
/** * Verify the RP+VPlex consistency group and its volumes have been properly migrated. * * @throws Exception */ private void verifyRpVplexConsistencyGroupMigration() throws Exception { log.info("Verifying RP+VPlex BlockConsistencyGroup and associated volume migration."); List<BlockObject> blockObjects = new ArrayList<BlockObject>(); BlockConsistencyGroup rpVplexPrimaryCg = _dbClient.queryObject(BlockConsistencyGroup.class, rpVplexPrimaryConsistencyGroupURI); // Verify the RP+VPLEX consistency group was properly migrated verifyConsistencyGroupMigration(rpVplexPrimaryCg, Types.RP.name(), Types.VPLEX.name()); Assert.assertNotNull( "The RP+VPlex BlockConsistencyGroup.systemConsistencyGroups field should be populated.", rpVplexPrimaryCg.getSystemConsistencyGroups()); Assert.assertNotNull( "The RP+VPlex BlockConsistencyGroup.systemConsistencyGroups field should contain an entry for " + protectionSystemURI.toString(), rpVplexPrimaryCg.getSystemConsistencyGroups().get(protectionSystemURI.toString())); Assert.assertTrue( "The RP+VPlex BlockConsistencyGroup.systemConsistencyGroups field should contain a mapping for " + protectionSystemURI.toString() + "-> ViPR-" + rpVplexPrimaryCg.getLabel(), rpVplexPrimaryCg .getSystemConsistencyGroups() .get(protectionSystemURI.toString()) .contains("ViPR-" + rpVplexPrimaryCg.getLabel())); // Verify that primary CG has a mapping reference for each of the VPlex storage system/cg name. for (URI rpVplexVolumeId : rpVplexVolumeToCgMapping.keySet()) { Volume rpVplexVolume = _dbClient.queryObject(Volume.class, rpVplexVolumeId); blockObjects.add(rpVplexVolume); // Get the VPlex consistency group URI cgUri = rpVplexVolumeToCgMapping.get(rpVplexVolumeId); BlockConsistencyGroup vplexCg = _dbClient.queryObject(BlockConsistencyGroup.class, cgUri); String cgName = vplexCg.getLabel(); String clusterName = getVPlexClusterFromVolume(rpVplexVolume); String storageSystem = rpVplexVolume.getStorageController().toString(); String clusterCgName = BlockConsistencyGroupUtils.buildClusterCgName(clusterName, cgName); // Verify that primary CG contains the correct mapping Assert.assertTrue( "The RP+VPlex BlockConsistencyGroup.systemConsistencyGroups field should contain a mapping for " + storageSystem + "->" + clusterCgName, rpVplexPrimaryCg.getSystemConsistencyGroups().get(storageSystem).contains(clusterCgName)); // Verify that the VPlex CG has been marked for deletion Assert.assertTrue( "The VPlex BlockConsistencyGroup " + vplexCg.getLabel() + "should be inactive.", vplexCg.getInactive()); } // Verify the volume migration took place correctly verifyBlockObjects(blockObjects); }
/** * Prepare the VPlex volumes and associated consistency group data. * * @throws Exception */ private void prepareVPlexConsistencyGroupData() throws Exception { // Create a VPlex storage system StorageSystem storageSystem = createStorageSystem(true); // Create the VPlex volumes and add them to the VPlex consistency group List<Volume> vplexVolumes = createVPlexVolumes("vplexVolume", 3, storageSystem.getId()); // Prior to 2.2, VPlex only CGs (nothing to do with RP) did not set the CG type of VPLEX. So we // pass false here. BlockConsistencyGroup vplexCg = createBlockConsistencyGroup("vplexCg", storageSystem.getId(), Types.VPLEX.name(), false); // Save a references to the cg for migration verification vplexConsistencyGroupURI = vplexCg.getId(); // Add the VPlex volumes to the VPlex consistency group addVolumesToBlockConsistencyGroup(vplexCg.getId(), vplexVolumes); }
/** * Verify the VPlex consistency group and its volumes have been properly migrated. * * @throws Exception */ private void verifyVplexConsistencyGroupMigration() throws Exception { log.info("Verifying VPlex BlockConsistencyGroup and associated volume migration."); BlockConsistencyGroup vplexCg = _dbClient.queryObject(BlockConsistencyGroup.class, vplexConsistencyGroupURI); Iterator<Volume> vplexVolumeItr = _dbClient.queryIterativeObjects(Volume.class, vplexVolumeURIs); // Verify the VPLEX consistency group was properly migrated verifyConsistencyGroupMigration(vplexCg, Types.VPLEX.name()); while (vplexVolumeItr.hasNext()) { Volume vplexVolume = vplexVolumeItr.next(); // Get the VPlex consistency group String cgName = vplexCg.getLabel(); String clusterName = getVPlexClusterFromVolume(vplexVolume); String storageSystem = vplexVolume.getStorageController().toString(); String clusterCgName = BlockConsistencyGroupUtils.buildClusterCgName(clusterName, cgName); // Verify that primary CG contains the correct mapping Assert.assertNotNull( "The VPlex BlockConsistencyGroup.vplexStorageSystemToCg field should be populated.", vplexCg.getSystemConsistencyGroups()); Assert.assertTrue( "The VPlex BlockConsistencyGroup.vplexStorageSystemToCg should contain a key for storage system " + storageSystem, vplexCg.getSystemConsistencyGroups().containsKey(storageSystem)); Assert.assertTrue( "The VPlex BlockConsistencyGroup.vplexStorageSystemToCg field should contain a mapping for " + storageSystem + "->" + clusterCgName, vplexCg.getSystemConsistencyGroups().get(storageSystem).contains(clusterCgName)); } // Verify the volume migration took place correctly List<BlockObject> blockObjects = new ArrayList<BlockObject>(); while (vplexVolumeItr.hasNext()) { blockObjects.add(vplexVolumeItr.next()); } verifyBlockObjects(blockObjects); }
/** * 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(), sourceVolume.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(), sourceVolumeJournal.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(), sourceVolumeTarget.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(), sourceVolumeTargetJournal.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; }