use of com.emc.storageos.volumecontroller.RPRecommendation in project coprhd-controller by CoprHD.
the class PlacementTests method testPlacementRpVplexProtectHASite.
/**
* RP VPLEX placement -- placement decision based on RP array visibility
* Protect HA side of the VPLEX Metro volume.
*/
@Test
public void testPlacementRpVplexProtectHASite() {
String[] vmax1FE = { "50:FE:FE:FE:FE:FE:FE:00", "50:FE:FE:FE:FE:FE:FE:01" };
String[] vmax2FE = { "51:FE:FE:FE:FE:FE:FE:00", "51:FE:FE:FE:FE:FE:FE:01" };
String[] vmax3FE = { "52:FE:FE:FE:FE:FE:FE:00", "52:FE:FE:FE:FE:FE:FE:01" };
String[] rp1FE = { "53:FE:FE:FE:FE:FE:FE:00", "53:FE:FE:FE:FE:FE:FE:01" };
String[] rp2FE = { "54:FE:FE:FE:FE:FE:FE:00", "54:FE:FE:FE:FE:FE:FE:01" };
String[] vplex1FE = { "FE:FE:FE:FE:FE:FE:FE:00", "FE:FE:FE:FE:FE:FE:FE:01" };
String[] vplex1BE = { "BE:BE:BE:BE:BE:BE:BE:00", "BE:BE:BE:BE:BE:BE:BE:01" };
String[] vplex2FE = { "FE:FE:FE:FE:FE:FE:FE:02", "FE:FE:FE:FE:FE:FE:FE:03" };
String[] vplex2BE = { "BE:BE:BE:BE:BE:BE:BE:02", "BE:BE:BE:BE:BE:BE:BE:03" };
String[] vplex3FE = { "FE:FE:FE:FE:FE:FE:FE:04", "FE:FE:FE:FE:FE:FE:FE:05" };
String[] vplex3BE = { "BE:BE:BE:BE:BE:BE:BE:04", "BE:BE:BE:BE:BE:BE:BE:05" };
// Create 3 Virtual Arrays
VirtualArray haVarray = PlacementTestUtils.createVirtualArray(_dbClient, "varray1");
VirtualArray srcVarray = PlacementTestUtils.createVirtualArray(_dbClient, "varray2");
VirtualArray tgtVarray = PlacementTestUtils.createVirtualArray(_dbClient, "varray3");
// Create 1 Network
StringSet connVA = new StringSet();
connVA.add(haVarray.getId().toString());
connVA.add(srcVarray.getId().toString());
connVA.add(tgtVarray.getId().toString());
Network network = PlacementTestUtils.createNetwork(_dbClient, vplex1FE, "VSAN", "FC+BROCADE", connVA);
PlacementTestUtils.addEndpoints(_dbClient, network, vplex2FE);
PlacementTestUtils.addEndpoints(_dbClient, network, vplex3FE);
PlacementTestUtils.addEndpoints(_dbClient, network, vplex1BE);
PlacementTestUtils.addEndpoints(_dbClient, network, vplex2BE);
PlacementTestUtils.addEndpoints(_dbClient, network, vplex3BE);
PlacementTestUtils.addEndpoints(_dbClient, network, rp1FE);
PlacementTestUtils.addEndpoints(_dbClient, network, rp2FE);
PlacementTestUtils.addEndpoints(_dbClient, network, vmax1FE);
PlacementTestUtils.addEndpoints(_dbClient, network, vmax2FE);
PlacementTestUtils.addEndpoints(_dbClient, network, vmax3FE);
// Create 3 storage systems
StorageSystem storageSystem1 = PlacementTestUtils.createStorageSystem(_dbClient, "vmax", "vmax1");
StorageSystem storageSystem2 = PlacementTestUtils.createStorageSystem(_dbClient, "vmax", "vmax2");
StorageSystem storageSystem3 = PlacementTestUtils.createStorageSystem(_dbClient, "vmax", "vmax3");
// Create two front-end storage ports VMAX1
List<StoragePort> vmax1Ports = new ArrayList<StoragePort>();
for (int i = 0; i < vmax1FE.length; i++) {
vmax1Ports.add(PlacementTestUtils.createStoragePort(_dbClient, storageSystem1, network, vmax1FE[i], haVarray, StoragePort.PortType.frontend.name(), "portGroupvmax1" + i, "C0+FC0" + i));
}
// Create two front-end storage ports VMAX2
List<StoragePort> vmax2Ports = new ArrayList<StoragePort>();
for (int i = 0; i < vmax2FE.length; i++) {
vmax2Ports.add(PlacementTestUtils.createStoragePort(_dbClient, storageSystem2, network, vmax2FE[i], srcVarray, StoragePort.PortType.frontend.name(), "portGroupvmax2" + i, "D0+FC0" + i));
}
// Create two front-end storage ports VMAX3
List<StoragePort> vmax3Ports = new ArrayList<StoragePort>();
for (int i = 0; i < vmax3FE.length; i++) {
vmax3Ports.add(PlacementTestUtils.createStoragePort(_dbClient, storageSystem3, network, vmax3FE[i], tgtVarray, StoragePort.PortType.frontend.name(), "portGroupvmax3" + i, "E0+FC0" + i));
}
// Create 2 VPLEX storage systems
StorageSystem vplexStorageSystem1 = PlacementTestUtils.createStorageSystem(_dbClient, "vplex", "vplex1");
StorageSystem vplexStorageSystem2 = PlacementTestUtils.createStorageSystem(_dbClient, "vplex", "vplex2");
// Create two front-end storage ports VPLEX1
List<StoragePort> fePorts1 = new ArrayList<StoragePort>();
for (int i = 0; i < vplex1FE.length; i++) {
fePorts1.add(PlacementTestUtils.createStoragePort(_dbClient, vplexStorageSystem1, network, vplex1FE[i], haVarray, StoragePort.PortType.frontend.name(), "portGroupFE1-" + (i + 1), "A0+FC0" + i));
}
// Create two back-end storage ports VPLEX1
List<StoragePort> bePorts1 = new ArrayList<StoragePort>();
for (int i = 0; i < vplex1BE.length; i++) {
bePorts1.add(PlacementTestUtils.createStoragePort(_dbClient, vplexStorageSystem1, network, vplex1BE[i], haVarray, StoragePort.PortType.backend.name(), "portGroupBE1-" + (i + 1), "B0+FC0" + i));
}
// Create two front-end storage ports VPLEX2
List<StoragePort> fePorts2 = new ArrayList<StoragePort>();
for (int i = 0; i < vplex2FE.length; i++) {
fePorts2.add(PlacementTestUtils.createStoragePort(_dbClient, vplexStorageSystem1, network, vplex2FE[i], srcVarray, StoragePort.PortType.frontend.name(), "portGroupFE2-" + (i + 1), "F0+FC0" + i));
}
// Create two back-end storage ports VPLEX2
List<StoragePort> bePorts2 = new ArrayList<StoragePort>();
for (int i = 0; i < vplex2BE.length; i++) {
bePorts2.add(PlacementTestUtils.createStoragePort(_dbClient, vplexStorageSystem1, network, vplex2BE[i], srcVarray, StoragePort.PortType.backend.name(), "portGroupBE2-" + (i + 1), "G0+FC0" + i));
}
// Create two front-end storage ports VPLEX3
List<StoragePort> fePorts3 = new ArrayList<StoragePort>();
for (int i = 0; i < vplex3FE.length; i++) {
fePorts3.add(PlacementTestUtils.createStoragePort(_dbClient, vplexStorageSystem2, network, vplex3FE[i], tgtVarray, StoragePort.PortType.frontend.name(), "portGroupFE3-" + (i + 1), "H0+FC0" + i));
}
// Create two back-end storage ports VPLEX3
List<StoragePort> bePorts3 = new ArrayList<StoragePort>();
for (int i = 0; i < vplex3BE.length; i++) {
bePorts3.add(PlacementTestUtils.createStoragePort(_dbClient, vplexStorageSystem2, network, vplex3BE[i], tgtVarray, StoragePort.PortType.backend.name(), "portGroupBE3-" + (i + 1), "I0+FC0" + i));
}
// Create RP system
AbstractChangeTrackingSet<String> wwnSite1 = new StringSet();
for (int i = 0; i < rp1FE.length; i++) {
wwnSite1.add(rp1FE[i]);
}
StringSetMap initiatorsSiteMap = new StringSetMap();
initiatorsSiteMap.put("site1", wwnSite1);
AbstractChangeTrackingSet<String> wwnSite2 = new StringSet();
for (int i = 0; i < rp2FE.length; i++) {
wwnSite2.add(rp2FE[i]);
}
initiatorsSiteMap.put("site2", wwnSite2);
StringSet storSystems = new StringSet();
storSystems.add(ProtectionSystem.generateAssociatedStorageSystem("site1", "vplex1cluster1"));
storSystems.add(ProtectionSystem.generateAssociatedStorageSystem("site1", "vplex1cluster2"));
storSystems.add(ProtectionSystem.generateAssociatedStorageSystem("site2", "vplex2cluster1"));
storSystems.add(ProtectionSystem.generateAssociatedStorageSystem("site2", "vplex2cluster2"));
StringSetMap rpVisibleSystems = new StringSetMap();
StringSet storageIds = new StringSet();
storageIds.add(vplexStorageSystem1.getId().toString());
rpVisibleSystems.put("site1", storageIds);
StringSet storageIds2 = new StringSet();
storageIds2.add(vplexStorageSystem2.getId().toString());
rpVisibleSystems.put("site2", storageIds2);
StringMap siteVolCap = new StringMap();
siteVolCap.put("site1", "3221225472");
siteVolCap.put("site2", "3221225472");
StringMap siteVolCnt = new StringMap();
siteVolCnt.put("site1", "10");
siteVolCnt.put("site2", "10");
ProtectionSystem rpSystem = PlacementTestUtils.createProtectionSystem(_dbClient, "rp", "rp1", "site1", "site2", null, "IP", initiatorsSiteMap, storSystems, rpVisibleSystems, Long.valueOf("3221225472"), Long.valueOf("2"), siteVolCap, siteVolCnt);
// RP Site Array objects
RPSiteArray rpSiteArray1 = new RPSiteArray();
rpSiteArray1.setId(URI.create("rsa1"));
rpSiteArray1.setStorageSystem(URI.create("vplex1"));
rpSiteArray1.setRpInternalSiteName("site1");
rpSiteArray1.setRpProtectionSystem(rpSystem.getId());
_dbClient.createObject(rpSiteArray1);
RPSiteArray rpSiteArray2 = new RPSiteArray();
rpSiteArray2.setId(URI.create("rsa2"));
rpSiteArray2.setStorageSystem(URI.create("vplex2"));
rpSiteArray2.setRpInternalSiteName("site2");
rpSiteArray2.setRpProtectionSystem(rpSystem.getId());
_dbClient.createObject(rpSiteArray2);
// Create a storage pool for vmax1
StoragePool pool1 = PlacementTestUtils.createStoragePool(_dbClient, haVarray, storageSystem1, "pool1", "Pool1", Long.valueOf(1024 * 1024 * 10), Long.valueOf(1024 * 1024 * 10), 300, 300, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax1
StoragePool pool2 = PlacementTestUtils.createStoragePool(_dbClient, haVarray, storageSystem1, "pool2", "Pool2", Long.valueOf(1024 * 1024 * 10), Long.valueOf(1024 * 1024 * 10), 300, 300, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax1
StoragePool pool3 = PlacementTestUtils.createStoragePool(_dbClient, haVarray, storageSystem1, "pool3", "Pool3", Long.valueOf(1024 * 1024 * 1), Long.valueOf(1024 * 1024 * 1), 100, 100, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax2
StoragePool pool4 = PlacementTestUtils.createStoragePool(_dbClient, srcVarray, storageSystem2, "pool4", "Pool4", Long.valueOf(SIZE_GB * 10), Long.valueOf(SIZE_GB * 10), 300, 300, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax2
StoragePool pool5 = PlacementTestUtils.createStoragePool(_dbClient, srcVarray, storageSystem2, "pool5", "Pool5", Long.valueOf(SIZE_GB * 10), Long.valueOf(SIZE_GB * 50), 300, 300, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax2
StoragePool pool6 = PlacementTestUtils.createStoragePool(_dbClient, srcVarray, storageSystem2, "pool6", "Pool6", Long.valueOf(1024 * 1024 * 1), Long.valueOf(1024 * 1024 * 1), 100, 100, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax3
StoragePool pool7 = PlacementTestUtils.createStoragePool(_dbClient, tgtVarray, storageSystem3, "pool7", "Pool7", Long.valueOf(1024 * 1024 * 10), Long.valueOf(1024 * 1024 * 10), 300, 300, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax3
StoragePool pool8 = PlacementTestUtils.createStoragePool(_dbClient, tgtVarray, storageSystem3, "pool8", "Pool8", Long.valueOf(1024 * 1024 * 10), Long.valueOf(1024 * 1024 * 10), 300, 300, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax3
StoragePool pool9 = PlacementTestUtils.createStoragePool(_dbClient, tgtVarray, storageSystem3, "pool9", "Pool9", Long.valueOf(1024 * 1024 * 1), Long.valueOf(1024 * 1024 * 1), 100, 100, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create HA virtual pool
VirtualPool haVpool = new VirtualPool();
haVpool.setId(URI.create(haVpoolUri));
haVpool.setLabel("haVpool");
haVpool.setType("block");
haVpool.setSupportedProvisioningType(VirtualPool.ProvisioningType.Thin.name());
haVpool.setDriveType(SupportedDriveTypes.FC.name());
StringSet matchedPools = new StringSet();
matchedPools.add(pool1.getId().toString());
matchedPools.add(pool2.getId().toString());
matchedPools.add(pool3.getId().toString());
haVpool.setMatchedStoragePools(matchedPools);
StringSet virtualArrays1 = new StringSet();
virtualArrays1.add(haVarray.getId().toString());
haVpool.setVirtualArrays(virtualArrays1);
haVpool.setUseMatchedPools(true);
_dbClient.createObject(haVpool);
// Create RP target vpool
VirtualPool rpTgtVpool = new VirtualPool();
rpTgtVpool.setId(URI.create("rpTgtVpool"));
rpTgtVpool.setLabel("rpTgtVpool");
rpTgtVpool.setType("block");
rpTgtVpool.setSupportedProvisioningType(VirtualPool.ProvisioningType.Thin.name());
rpTgtVpool.setDriveType(SupportedDriveTypes.FC.name());
rpTgtVpool.setHighAvailability(VirtualPool.HighAvailabilityType.vplex_local.name());
matchedPools = new StringSet();
matchedPools.add(pool7.getId().toString());
matchedPools.add(pool8.getId().toString());
matchedPools.add(pool9.getId().toString());
rpTgtVpool.setMatchedStoragePools(matchedPools);
rpTgtVpool.setUseMatchedPools(true);
StringSet virtualArrays3 = new StringSet();
virtualArrays3.add(tgtVarray.getId().toString());
rpTgtVpool.setVirtualArrays(virtualArrays3);
_dbClient.createObject(rpTgtVpool);
// Create a RP VPLEX source virtual pool
VirtualPool rpVplexSrcVpool = new VirtualPool();
rpVplexSrcVpool.setId(URI.create(dummyVpoolUri));
rpVplexSrcVpool.setLabel("rpVplexSrcVpool");
rpVplexSrcVpool.setType("block");
rpVplexSrcVpool.setSupportedProvisioningType(VirtualPool.ProvisioningType.Thin.name());
rpVplexSrcVpool.setDriveType(SupportedDriveTypes.FC.name());
rpVplexSrcVpool.setHighAvailability(VirtualPool.HighAvailabilityType.vplex_distributed.name());
StringMap vavpMap = new StringMap();
vavpMap.put(haVarray.getId().toString(), haVpool.getId().toString());
rpVplexSrcVpool.setHaVarrayVpoolMap(vavpMap);
VpoolProtectionVarraySettings protectionSettings = new VpoolProtectionVarraySettings();
protectionSettings.setVirtualPool(rpTgtVpool.getId());
protectionSettings.setId(URI.create("protectionSettings"));
_dbClient.createObject(protectionSettings);
List<VpoolProtectionVarraySettings> protectionSettingsList = new ArrayList<VpoolProtectionVarraySettings>();
protectionSettingsList.add(protectionSettings);
StringMap protectionVarray = new StringMap();
protectionVarray.put(tgtVarray.getId().toString(), protectionSettingsList.get(0).getId().toString());
rpVplexSrcVpool.setProtectionVarraySettings(protectionVarray);
rpVplexSrcVpool.setRpCopyMode("SYNCHRONOUS");
rpVplexSrcVpool.setRpRpoType("MINUTES");
rpVplexSrcVpool.setRpRpoValue(Long.valueOf("5"));
matchedPools = new StringSet();
matchedPools.add(pool4.getId().toString());
matchedPools.add(pool5.getId().toString());
matchedPools.add(pool6.getId().toString());
rpVplexSrcVpool.setMatchedStoragePools(matchedPools);
rpVplexSrcVpool.setHaVarrayConnectedToRp(haVarray.getId().toString());
rpVplexSrcVpool.setUseMatchedPools(true);
StringSet virtualArrays2 = new StringSet();
virtualArrays2.add(srcVarray.getId().toString());
rpVplexSrcVpool.setVirtualArrays(virtualArrays2);
_dbClient.createObject(rpVplexSrcVpool);
// Create Tenant
TenantOrg tenant = new TenantOrg();
tenant.setId(URI.create("tenant"));
_dbClient.createObject(tenant);
// Create a project object
Project project = new Project();
project.setId(URI.create("project"));
project.setLabel("project");
project.setTenantOrg(new NamedURI(tenant.getId(), project.getLabel()));
_dbClient.createObject(project);
// Create block consistency group
BlockConsistencyGroup cg = new BlockConsistencyGroup();
cg.setProject(new NamedURI(project.getId(), project.getLabel()));
cg.setId(URI.create("blockCG"));
_dbClient.createObject(cg);
// Create capabilities
VirtualPoolCapabilityValuesWrapper capabilities = PlacementTestUtils.createCapabilities("2GB", 1, cg);
// Run single volume placement: Run 10 times to make sure pool6 never comes up for source and pool9 for target.
for (int i = 0; i < 10; i++) {
List recommendations = PlacementTestUtils.invokePlacement(_dbClient, _coordinator, srcVarray, project, rpVplexSrcVpool, capabilities);
assertNotNull(recommendations);
assertTrue(!recommendations.isEmpty());
assertNotNull(recommendations.get(0));
RPProtectionRecommendation rec = (RPProtectionRecommendation) recommendations.get(0);
assertNotNull(rec.getSourceRecommendations());
assertTrue(!rec.getSourceRecommendations().isEmpty());
assertNotNull(rec.getProtectionDevice());
assertTrue("rp1".equals(rec.getProtectionDevice().toString()));
for (RPRecommendation sourceRec : rec.getSourceRecommendations()) {
assertNotNull(sourceRec.getInternalSiteName());
assertNotNull(sourceRec.getVirtualArray());
assertNotNull(sourceRec.getVirtualPool());
assertNotNull(sourceRec.getVirtualVolumeRecommendation());
assertNotNull(sourceRec.getHaRecommendation());
assertNotNull(sourceRec.getTargetRecommendations());
assertTrue(!sourceRec.getTargetRecommendations().isEmpty());
assertTrue("site1".equals(sourceRec.getInternalSiteName()));
assertTrue("vmax1".equals(sourceRec.getSourceStorageSystem().toString()));
assertTrue(("pool1".equals(sourceRec.getSourceStoragePool().toString())) || ("pool2".equals(sourceRec.getSourceStoragePool().toString())));
assertTrue("vplex1".equals(sourceRec.getVirtualVolumeRecommendation().getVPlexStorageSystem().toString()));
assertNotNull(sourceRec.getHaRecommendation().getVirtualVolumeRecommendation());
assertTrue("vplex1".equals(sourceRec.getHaRecommendation().getVirtualVolumeRecommendation().getVPlexStorageSystem().toString()));
assertTrue("varray2".equals(sourceRec.getHaRecommendation().getVirtualArray().toString()));
assertTrue(dummyVpoolUri.equals(sourceRec.getHaRecommendation().getVirtualPool().getId().toString()));
assertTrue("vmax2".equals(sourceRec.getHaRecommendation().getSourceStorageSystem().toString()));
assertTrue(("pool4".equals(sourceRec.getHaRecommendation().getSourceStoragePool().toString())) || ("pool5".equals(sourceRec.getHaRecommendation().getSourceStoragePool().toString())));
assertNotNull(sourceRec.getTargetRecommendations());
assertTrue(!sourceRec.getTargetRecommendations().isEmpty());
for (RPRecommendation targetRec : sourceRec.getTargetRecommendations()) {
assertNotNull(targetRec.getInternalSiteName());
assertNotNull(targetRec.getVirtualArray());
assertNotNull(targetRec.getVirtualPool());
if (VirtualPool.vPoolSpecifiesHighAvailability(targetRec.getVirtualPool())) {
assertNotNull(targetRec.getVirtualVolumeRecommendation());
}
assertTrue("varray3".equals(targetRec.getVirtualArray().toString()));
assertTrue(rpTgtVpool.getId().toString().equals(targetRec.getVirtualPool().getId().toString()));
assertTrue("site2".equals(targetRec.getInternalSiteName()));
assertTrue("vmax3".equals(targetRec.getSourceStorageSystem().toString()));
assertTrue(("pool8".equals(targetRec.getSourceStoragePool().toString())) || ("pool7".equals(targetRec.getSourceStoragePool().toString())));
}
}
// source journal
assertNotNull(rec.getSourceJournalRecommendation());
RPRecommendation sourceJournalRec = rec.getSourceJournalRecommendation();
if (VirtualPool.vPoolSpecifiesHighAvailability(sourceJournalRec.getVirtualPool())) {
assertNotNull(sourceJournalRec.getVirtualVolumeRecommendation());
}
assertTrue(("pool1".equals(sourceJournalRec.getSourceStoragePool().toString())) || ("pool2".equals(sourceJournalRec.getSourceStoragePool().toString())));
// target journals
assertNotNull(rec.getTargetJournalRecommendations());
assertTrue(!rec.getTargetJournalRecommendations().isEmpty());
for (RPRecommendation targetJournalRec : rec.getTargetJournalRecommendations()) {
assertNotNull(targetJournalRec.getInternalSiteName());
assertNotNull(targetJournalRec.getVirtualArray());
assertNotNull(targetJournalRec.getVirtualPool());
if (VirtualPool.vPoolSpecifiesHighAvailability(targetJournalRec.getVirtualPool())) {
assertNotNull(targetJournalRec.getVirtualVolumeRecommendation());
}
assertTrue("vmax3".equals(targetJournalRec.getSourceStorageSystem().toString()));
assertTrue(("pool8".equals(targetJournalRec.getSourceStoragePool().toString())) || ("pool7".equals(targetJournalRec.getSourceStoragePool().toString())));
}
_log.info("Recommendation : " + rec.toString(_dbClient));
}
}
use of com.emc.storageos.volumecontroller.RPRecommendation in project coprhd-controller by CoprHD.
the class PlacementTests method testPlacementRpVplex.
/**
* RP VPLEX placement
*/
@Test
public void testPlacementRpVplex() {
String[] vmax1FE = { "50:FE:FE:FE:FE:FE:FE:00", "50:FE:FE:FE:FE:FE:FE:01" };
String[] vmax2FE = { "51:FE:FE:FE:FE:FE:FE:00", "51:FE:FE:FE:FE:FE:FE:01" };
String[] vmax3FE = { "52:FE:FE:FE:FE:FE:FE:00", "52:FE:FE:FE:FE:FE:FE:01" };
String[] rp1FE = { "53:FE:FE:FE:FE:FE:FE:00", "53:FE:FE:FE:FE:FE:FE:01" };
String[] rp2FE = { "54:FE:FE:FE:FE:FE:FE:00", "54:FE:FE:FE:FE:FE:FE:01" };
String[] vplex1FE = { "FE:FE:FE:FE:FE:FE:FE:00", "FE:FE:FE:FE:FE:FE:FE:01" };
String[] vplex1BE = { "BE:BE:BE:BE:BE:BE:BE:00", "BE:BE:BE:BE:BE:BE:BE:01" };
String[] vplex2FE = { "FE:FE:FE:FE:FE:FE:FE:02", "FE:FE:FE:FE:FE:FE:FE:03" };
String[] vplex2BE = { "BE:BE:BE:BE:BE:BE:BE:02", "BE:BE:BE:BE:BE:BE:BE:03" };
String[] vplex3FE = { "FE:FE:FE:FE:FE:FE:FE:04", "FE:FE:FE:FE:FE:FE:FE:05" };
String[] vplex3BE = { "BE:BE:BE:BE:BE:BE:BE:04", "BE:BE:BE:BE:BE:BE:BE:05" };
// Create 3 Virtual Arrays
VirtualArray varray1 = PlacementTestUtils.createVirtualArray(_dbClient, "varray1");
VirtualArray varray2 = PlacementTestUtils.createVirtualArray(_dbClient, "varray2");
VirtualArray varray3 = PlacementTestUtils.createVirtualArray(_dbClient, "varray3");
// Create 2 Networks
StringSet connVA = new StringSet();
connVA.add(varray1.getId().toString());
Network networkFE1 = PlacementTestUtils.createNetwork(_dbClient, vplex1FE, "VSANFE1", "FC+BROCADE+FE", connVA);
Network networkBE1 = PlacementTestUtils.createNetwork(_dbClient, vplex1BE, "VSANBE1", "FC+BROCADE+BE", connVA);
connVA = new StringSet();
connVA.add(varray2.getId().toString());
Network networkFE2 = PlacementTestUtils.createNetwork(_dbClient, (String[]) ArrayUtils.addAll(vplex2FE, rp1FE), "VSANFE2", "FC+CISCO+FE", connVA);
Network networkBE2 = PlacementTestUtils.createNetwork(_dbClient, vplex2BE, "VSANBE2", "FC+CISCO+BE", connVA);
connVA = new StringSet();
connVA.add(varray3.getId().toString());
Network networkFE3 = PlacementTestUtils.createNetwork(_dbClient, (String[]) ArrayUtils.addAll(vplex3FE, rp2FE), "VSANFE3", "FC+IBM+FE", connVA);
Network networkBE3 = PlacementTestUtils.createNetwork(_dbClient, vplex3BE, "VSANBE3", "FC+IBM+BE", connVA);
// Create 3 storage systems
StorageSystem storageSystem1 = PlacementTestUtils.createStorageSystem(_dbClient, "vmax", "vmax1");
StorageSystem storageSystem2 = PlacementTestUtils.createStorageSystem(_dbClient, "vmax", "vmax2");
StorageSystem storageSystem3 = PlacementTestUtils.createStorageSystem(_dbClient, "vmax", "vmax3");
// Create two front-end storage ports VMAX1
List<StoragePort> vmax1Ports = new ArrayList<StoragePort>();
for (int i = 0; i < vmax1FE.length; i++) {
vmax1Ports.add(PlacementTestUtils.createStoragePort(_dbClient, storageSystem1, networkBE1, vmax1FE[i], varray1, StoragePort.PortType.frontend.name(), "portGroupvmax1" + i, "C0+FC0" + i));
}
// Create two front-end storage ports VMAX2
List<StoragePort> vmax2Ports = new ArrayList<StoragePort>();
for (int i = 0; i < vmax2FE.length; i++) {
vmax2Ports.add(PlacementTestUtils.createStoragePort(_dbClient, storageSystem2, networkBE2, vmax2FE[i], varray2, StoragePort.PortType.frontend.name(), "portGroupvmax2" + i, "D0+FC0" + i));
}
// Create two front-end storage ports VMAX3
List<StoragePort> vmax3Ports = new ArrayList<StoragePort>();
for (int i = 0; i < vmax3FE.length; i++) {
vmax3Ports.add(PlacementTestUtils.createStoragePort(_dbClient, storageSystem3, networkBE3, vmax3FE[i], varray3, StoragePort.PortType.frontend.name(), "portGroupvmax3" + i, "E0+FC0" + i));
}
// Create 2 VPLEX storage systems
StorageSystem vplexStorageSystem1 = PlacementTestUtils.createStorageSystem(_dbClient, "vplex", "vplex1");
StorageSystem vplexStorageSystem2 = PlacementTestUtils.createStorageSystem(_dbClient, "vplex", "vplex2");
// Create two front-end storage ports VPLEX1
List<StoragePort> fePorts1 = new ArrayList<StoragePort>();
for (int i = 0; i < vplex1FE.length; i++) {
fePorts1.add(PlacementTestUtils.createStoragePort(_dbClient, vplexStorageSystem1, networkFE1, vplex1FE[i], varray1, StoragePort.PortType.frontend.name(), "portGroupFE1-" + (i + 1), "A0+FC0" + i));
}
// Create two back-end storage ports VPLEX1
List<StoragePort> bePorts1 = new ArrayList<StoragePort>();
for (int i = 0; i < vplex1BE.length; i++) {
bePorts1.add(PlacementTestUtils.createStoragePort(_dbClient, vplexStorageSystem1, networkBE1, vplex1BE[i], varray1, StoragePort.PortType.backend.name(), "portGroupBE1-" + (i + 1), "B0+FC0" + i));
}
// Create two front-end storage ports VPLEX2
List<StoragePort> fePorts2 = new ArrayList<StoragePort>();
for (int i = 0; i < vplex2FE.length; i++) {
fePorts2.add(PlacementTestUtils.createStoragePort(_dbClient, vplexStorageSystem1, networkFE2, vplex2FE[i], varray2, StoragePort.PortType.frontend.name(), "portGroupFE2-" + (i + 1), "F0+FC0" + i));
}
// Create two back-end storage ports VPLEX2
List<StoragePort> bePorts2 = new ArrayList<StoragePort>();
for (int i = 0; i < vplex2BE.length; i++) {
bePorts2.add(PlacementTestUtils.createStoragePort(_dbClient, vplexStorageSystem1, networkBE2, vplex2BE[i], varray2, StoragePort.PortType.backend.name(), "portGroupBE2-" + (i + 1), "G0+FC0" + i));
}
// Create two front-end storage ports VPLEX3
List<StoragePort> fePorts3 = new ArrayList<StoragePort>();
for (int i = 0; i < vplex3FE.length; i++) {
fePorts3.add(PlacementTestUtils.createStoragePort(_dbClient, vplexStorageSystem2, networkFE3, vplex3FE[i], varray3, StoragePort.PortType.frontend.name(), "portGroupFE3-" + (i + 1), "H0+FC0" + i));
}
// Create two back-end storage ports VPLEX3
List<StoragePort> bePorts3 = new ArrayList<StoragePort>();
for (int i = 0; i < vplex3BE.length; i++) {
bePorts3.add(PlacementTestUtils.createStoragePort(_dbClient, vplexStorageSystem2, networkBE3, vplex3BE[i], varray3, StoragePort.PortType.backend.name(), "portGroupBE3-" + (i + 1), "I0+FC0" + i));
}
// Create RP system
AbstractChangeTrackingSet<String> wwnSite1 = new StringSet();
for (int i = 0; i < rp1FE.length; i++) {
wwnSite1.add(rp1FE[i]);
}
StringSetMap initiatorsSiteMap = new StringSetMap();
initiatorsSiteMap.put("site1", wwnSite1);
AbstractChangeTrackingSet<String> wwnSite2 = new StringSet();
for (int i = 0; i < rp2FE.length; i++) {
wwnSite2.add(rp2FE[i]);
}
initiatorsSiteMap.put("site2", wwnSite2);
StringSet storSystems = new StringSet();
storSystems.add(ProtectionSystem.generateAssociatedStorageSystem("site1", "vplex1cluster1"));
storSystems.add(ProtectionSystem.generateAssociatedStorageSystem("site2", "vplex2cluster1"));
StringMap siteVolCap = new StringMap();
siteVolCap.put("site1", "3221225472");
siteVolCap.put("site2", "3221225472");
StringMap siteVolCnt = new StringMap();
siteVolCnt.put("site1", "10");
siteVolCnt.put("site2", "10");
ProtectionSystem rpSystem = PlacementTestUtils.createProtectionSystem(_dbClient, "rp", "rp1", "site1", "site2", null, "IP", initiatorsSiteMap, storSystems, null, Long.valueOf("3221225472"), Long.valueOf("2"), siteVolCap, siteVolCnt);
// RP Site Array objects
RPSiteArray rpSiteArray1 = new RPSiteArray();
rpSiteArray1.setId(URI.create("rsa1"));
rpSiteArray1.setStorageSystem(URI.create("vplex1"));
rpSiteArray1.setRpInternalSiteName("site1");
rpSiteArray1.setRpProtectionSystem(rpSystem.getId());
_dbClient.createObject(rpSiteArray1);
RPSiteArray rpSiteArray2 = new RPSiteArray();
rpSiteArray2.setId(URI.create("rsa2"));
rpSiteArray2.setStorageSystem(URI.create("vplex2"));
rpSiteArray2.setRpInternalSiteName("site2");
rpSiteArray2.setRpProtectionSystem(rpSystem.getId());
_dbClient.createObject(rpSiteArray2);
// Create a storage pool for vmax1
StoragePool pool1 = PlacementTestUtils.createStoragePool(_dbClient, varray1, storageSystem1, "pool1", "Pool1", Long.valueOf(SIZE_GB * 200), Long.valueOf(SIZE_GB * 200), 300, 300, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax1
StoragePool pool2 = PlacementTestUtils.createStoragePool(_dbClient, varray1, storageSystem1, "pool2", "Pool2", Long.valueOf(SIZE_GB * 200), Long.valueOf(SIZE_GB * 200), 300, 300, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax1
StoragePool pool3 = PlacementTestUtils.createStoragePool(_dbClient, varray1, storageSystem1, "pool3", "Pool3", Long.valueOf(SIZE_GB * 200), Long.valueOf(SIZE_GB * 200), 100, 100, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax2
StoragePool pool4 = PlacementTestUtils.createStoragePool(_dbClient, varray2, storageSystem2, "pool4", "Pool4", Long.valueOf(SIZE_GB * 200), Long.valueOf(SIZE_GB * 200), 300, 300, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax2
StoragePool pool5 = PlacementTestUtils.createStoragePool(_dbClient, varray2, storageSystem2, "pool5", "Pool5", Long.valueOf(SIZE_GB * 200), Long.valueOf(SIZE_GB * 200), 300, 300, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax2
StoragePool pool6 = PlacementTestUtils.createStoragePool(_dbClient, varray2, storageSystem2, "pool6", "Pool6", Long.valueOf(SIZE_GB * 200), Long.valueOf(SIZE_GB), 100, 100, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax3
StoragePool pool7 = PlacementTestUtils.createStoragePool(_dbClient, varray3, storageSystem3, "pool7", "Pool7", Long.valueOf(SIZE_GB * 200), Long.valueOf(SIZE_GB * 200), 300, 300, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax3
StoragePool pool8 = PlacementTestUtils.createStoragePool(_dbClient, varray3, storageSystem3, "pool8", "Pool8", Long.valueOf(SIZE_GB * 200), Long.valueOf(SIZE_GB * 200), 300, 300, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax3
StoragePool pool9 = PlacementTestUtils.createStoragePool(_dbClient, varray3, storageSystem3, "pool9", "Pool9", Long.valueOf(SIZE_GB * 200), Long.valueOf(SIZE_GB * 200), 100, 100, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a base HA virtual pool
VirtualPool haVpool = new VirtualPool();
haVpool.setId(URI.create(dummyVpoolUri));
haVpool.setLabel("vpoolHA");
haVpool.setType("block");
haVpool.setSupportedProvisioningType(VirtualPool.ProvisioningType.Thin.name());
haVpool.setDriveType(SupportedDriveTypes.FC.name());
StringSet matchedPools = new StringSet();
matchedPools.add(pool1.getId().toString());
matchedPools.add(pool2.getId().toString());
matchedPools.add(pool3.getId().toString());
haVpool.setMatchedStoragePools(matchedPools);
StringSet virtualArrays1 = new StringSet();
virtualArrays1.add(varray1.getId().toString());
haVpool.setVirtualArrays(virtualArrays1);
haVpool.setUseMatchedPools(true);
_dbClient.createObject(haVpool);
// Create a base RP virtual pool
VirtualPool tgtVpool = new VirtualPool();
tgtVpool.setId(URI.create("vpoolRP"));
tgtVpool.setLabel("vpoolRP");
tgtVpool.setSupportedProvisioningType(VirtualPool.ProvisioningType.Thin.name());
tgtVpool.setDriveType(SupportedDriveTypes.FC.name());
tgtVpool.setHighAvailability(VirtualPool.HighAvailabilityType.vplex_local.name());
matchedPools = new StringSet();
matchedPools.add(pool7.getId().toString());
matchedPools.add(pool8.getId().toString());
matchedPools.add(pool9.getId().toString());
tgtVpool.setMatchedStoragePools(matchedPools);
tgtVpool.setUseMatchedPools(true);
StringSet virtualArrays3 = new StringSet();
virtualArrays3.add(varray3.getId().toString());
tgtVpool.setVirtualArrays(virtualArrays3);
_dbClient.createObject(tgtVpool);
// Create a RP VPLEX virtual pool
VirtualPool rpSrcVpool = new VirtualPool();
rpSrcVpool.setId(URI.create("rpVplexVpool"));
rpSrcVpool.setLabel("rpVplexVpool");
rpSrcVpool.setSupportedProvisioningType(VirtualPool.ProvisioningType.Thin.name());
rpSrcVpool.setDriveType(SupportedDriveTypes.FC.name());
rpSrcVpool.setHighAvailability(VirtualPool.HighAvailabilityType.vplex_distributed.name());
rpSrcVpool.setJournalSize("2.5X");
StringMap vavpMap = new StringMap();
vavpMap.put(varray1.getId().toString(), haVpool.getId().toString());
rpSrcVpool.setHaVarrayVpoolMap(vavpMap);
VpoolProtectionVarraySettings protectionSettings = new VpoolProtectionVarraySettings();
protectionSettings.setVirtualPool(tgtVpool.getId());
protectionSettings.setJournalSize("32GB");
protectionSettings.setId(URI.create("protectionSettings"));
_dbClient.createObject(protectionSettings);
List<VpoolProtectionVarraySettings> protectionSettingsList = new ArrayList<VpoolProtectionVarraySettings>();
protectionSettingsList.add(protectionSettings);
StringMap protectionVarray = new StringMap();
protectionVarray.put(varray3.getId().toString(), protectionSettingsList.get(0).getId().toString());
rpSrcVpool.setProtectionVarraySettings(protectionVarray);
rpSrcVpool.setRpCopyMode("SYNCHRONOUS");
rpSrcVpool.setRpRpoType("MINUTES");
rpSrcVpool.setRpRpoValue(Long.valueOf("5"));
// rpSrcVpool.setHaVarrayConnectedToRp(varray1.getId().toString());
matchedPools = new StringSet();
matchedPools.add(pool4.getId().toString());
matchedPools.add(pool5.getId().toString());
matchedPools.add(pool6.getId().toString());
rpSrcVpool.setMatchedStoragePools(matchedPools);
rpSrcVpool.setUseMatchedPools(true);
StringSet virtualArrays2 = new StringSet();
virtualArrays2.add(varray2.getId().toString());
rpSrcVpool.setVirtualArrays(virtualArrays2);
_dbClient.createObject(rpSrcVpool);
// Create Tenant
TenantOrg tenant = new TenantOrg();
tenant.setId(URI.create("tenant"));
_dbClient.createObject(tenant);
// Create a project object
Project project = new Project();
project.setId(URI.create("project"));
project.setLabel("project");
project.setTenantOrg(new NamedURI(tenant.getId(), project.getLabel()));
_dbClient.createObject(project);
// Create block consistency group
BlockConsistencyGroup cg = new BlockConsistencyGroup();
cg.setProject(new NamedURI(project.getId(), project.getLabel()));
cg.setId(URI.create("blockCG"));
_dbClient.createObject(cg);
// Create capabilities
VirtualPoolCapabilityValuesWrapper capabilities = PlacementTestUtils.createCapabilities("5GB", 4, cg);
// Run single volume placement: Run 10 times to make sure pool6 never comes up for source and pool9 for target.
for (int i = 0; i < 10; i++) {
List recommendations = PlacementTestUtils.invokePlacement(_dbClient, _coordinator, varray2, project, rpSrcVpool, capabilities);
assertNotNull(recommendations);
assertTrue(!recommendations.isEmpty());
assertNotNull(recommendations.get(0));
RPProtectionRecommendation rec = (RPProtectionRecommendation) recommendations.get(0);
for (RPRecommendation rpVplexRec : rec.getSourceRecommendations()) {
assertNotNull(rpVplexRec.getVirtualVolumeRecommendation());
assertNotNull(rpVplexRec.getVirtualVolumeRecommendation().getVPlexStorageSystem());
assertNotNull(rpVplexRec.getSourceStoragePool());
assertNotNull(rpVplexRec.getSourceStorageSystem());
assertNotNull(rpVplexRec.getHaRecommendation());
assertNotNull(rpVplexRec.getTargetRecommendations());
assertTrue(!rpVplexRec.getTargetRecommendations().isEmpty());
assertNotNull(rpVplexRec.getInternalSiteName());
assertTrue("site1".equals(rpVplexRec.getInternalSiteName()));
assertTrue("vmax2".equals(rpVplexRec.getSourceStorageSystem().toString()));
assertTrue(("pool5".equals(rpVplexRec.getSourceStoragePool().toString())) || ("pool4".equals(rpVplexRec.getSourceStoragePool().toString())));
assertTrue("vplex1".equals(rpVplexRec.getVirtualVolumeRecommendation().getVPlexStorageSystem().toString()));
assertNotNull(rpVplexRec.getHaRecommendation().getSourceStoragePool());
assertNotNull(rpVplexRec.getHaRecommendation().getSourceStorageSystem());
assertNotNull(rpVplexRec.getHaRecommendation().getVirtualVolumeRecommendation().getVPlexStorageSystem());
for (RPRecommendation targetRec : rpVplexRec.getTargetRecommendations()) {
assertNotNull(targetRec.getSourceStoragePool());
assertNotNull(targetRec.getInternalSiteName());
assertNotNull(targetRec.getSourceStorageSystem());
assertNotNull(targetRec.getVirtualPool());
assertTrue("vpoolRP".equals(targetRec.getVirtualPool().getId().toString()));
assertTrue("varray3".equals(targetRec.getVirtualArray().toString()));
assertTrue("site2".equals(targetRec.getInternalSiteName()));
assertTrue("vplex2".equals(targetRec.getVirtualVolumeRecommendation().getVPlexStorageSystem().toString()));
assertTrue("vmax3".equals(targetRec.getSourceStorageSystem().toString()));
assertTrue(("pool8".equals(targetRec.getSourceStoragePool().toString())) || ("pool7".equals(targetRec.getSourceStoragePool().toString())));
}
}
assertNotNull(rec.getSourceJournalRecommendation());
assertNotNull(rec.getSourceJournalRecommendation().getInternalSiteName());
assertNotNull(rec.getSourceJournalRecommendation().getSourceStorageSystem());
assertNotNull(rec.getSourceJournalRecommendation().getSourceStoragePool());
if (rec.getSourceJournalRecommendation().getVirtualVolumeRecommendation() != null) {
assertTrue("vplex1".equals(rec.getSourceJournalRecommendation().getVirtualVolumeRecommendation().getVPlexStorageSystem().toString()));
}
assertTrue("site1".equals(rec.getSourceJournalRecommendation().getInternalSiteName().toString()));
assertTrue(("pool5".equals(rec.getSourceJournalRecommendation().getSourceStoragePool().toString())) || ("pool4".equals(rec.getSourceJournalRecommendation().getSourceStoragePool().toString())));
assertNotNull(rec.getTargetJournalRecommendations());
assertTrue(!rec.getTargetJournalRecommendations().isEmpty());
for (RPRecommendation targetJournalRec : rec.getTargetJournalRecommendations()) {
assertNotNull(targetJournalRec.getVirtualArray());
assertNotNull(targetJournalRec.getInternalSiteName());
assertNotNull(targetJournalRec.getSourceStorageSystem());
assertNotNull(targetJournalRec.getSourceStoragePool());
assertTrue("varray3".equals(targetJournalRec.getVirtualArray().toString()));
assertTrue("vmax3".equals(targetJournalRec.getSourceStorageSystem().toString()));
assertTrue("site2".equals(targetJournalRec.getInternalSiteName().toString()));
assertTrue(("pool9".equals(targetJournalRec.getSourceStoragePool().toString()) || "pool7".equals(targetJournalRec.getSourceStoragePool().toString())) || "pool8".equals(targetJournalRec.getSourceStoragePool().toString()));
assertTrue("vplex2".equals(targetJournalRec.getVirtualVolumeRecommendation().getVPlexStorageSystem().toString()));
}
_log.info(rec.toString(_dbClient));
}
}
use of com.emc.storageos.volumecontroller.RPRecommendation in project coprhd-controller by CoprHD.
the class PlacementTests method testBasicRPPlacement.
/**
* Simple block placement with RP
* Basic RP Placement test - VMAX
*/
@Test
public void testBasicRPPlacement() {
String[] vmax1FE = { "50:FE:FE:FE:FE:FE:FE:00", "50:FE:FE:FE:FE:FE:FE:01" };
String[] vmax2FE = { "51:FE:FE:FE:FE:FE:FE:00", "51:FE:FE:FE:FE:FE:FE:01" };
String[] rp1FE = { "52:FE:FE:FE:FE:FE:FE:00", "52:FE:FE:FE:FE:FE:FE:01" };
String[] rp2FE = { "53:FE:FE:FE:FE:FE:FE:00", "53:FE:FE:FE:FE:FE:FE:01" };
// Create 2 Virtual Arrays
VirtualArray rpSrcVarray = PlacementTestUtils.createVirtualArray(_dbClient, "rpSrcVarray");
VirtualArray rpTgtVarray = PlacementTestUtils.createVirtualArray(_dbClient, "rpTgtVarray");
// Create 2 Networks
StringSet connVA = new StringSet();
connVA.add(rpSrcVarray.getId().toString());
Network network1 = PlacementTestUtils.createNetwork(_dbClient, rp1FE, "VSANSite1", "FC+BROCADE+FE", connVA);
connVA = new StringSet();
connVA.add(rpTgtVarray.getId().toString());
Network network2 = PlacementTestUtils.createNetwork(_dbClient, rp2FE, "VSANSite2", "FC+CISCO+FE", connVA);
// Create 2 storage systems
StorageSystem storageSystem1 = PlacementTestUtils.createStorageSystem(_dbClient, "vmax", "vmax1");
StorageSystem storageSystem2 = PlacementTestUtils.createStorageSystem(_dbClient, "vmax", "vmax2");
// Create two front-end storage ports VMAX1
List<StoragePort> vmax1Ports = new ArrayList<StoragePort>();
for (int i = 0; i < vmax1FE.length; i++) {
vmax1Ports.add(PlacementTestUtils.createStoragePort(_dbClient, storageSystem1, network1, vmax1FE[i], rpSrcVarray, StoragePort.PortType.frontend.name(), "portGroupSite1vmax" + i, "C0+FC0" + i));
}
// Create two front-end storage ports VMAX2
List<StoragePort> vmax2Ports = new ArrayList<StoragePort>();
for (int i = 0; i < vmax2FE.length; i++) {
vmax2Ports.add(PlacementTestUtils.createStoragePort(_dbClient, storageSystem2, network2, vmax2FE[i], rpTgtVarray, StoragePort.PortType.frontend.name(), "portGroupSite2vmax" + i, "D0+FC0" + i));
}
// Create RP system
AbstractChangeTrackingSet<String> wwnSite1 = new StringSet();
for (int i = 0; i < rp1FE.length; i++) {
wwnSite1.add(rp1FE[i]);
}
StringSetMap initiatorsSiteMap = new StringSetMap();
initiatorsSiteMap.put("site1", wwnSite1);
AbstractChangeTrackingSet<String> wwnSite2 = new StringSet();
for (int i = 0; i < rp2FE.length; i++) {
wwnSite2.add(rp2FE[i]);
}
initiatorsSiteMap.put("site2", wwnSite2);
StringSet storSystems = new StringSet();
storSystems.add(ProtectionSystem.generateAssociatedStorageSystem("site1", storageSystem1.getSerialNumber()));
storSystems.add(ProtectionSystem.generateAssociatedStorageSystem("site2", storageSystem2.getSerialNumber()));
StringMap siteVolCap = new StringMap();
siteVolCap.put("site1", "3221225472");
siteVolCap.put("site2", "3221225472");
StringMap siteVolCnt = new StringMap();
siteVolCnt.put("site1", "10");
siteVolCnt.put("site2", "10");
ProtectionSystem rpSystem = PlacementTestUtils.createProtectionSystem(_dbClient, "rp", "rp1", "site1", "site2", null, "IP", initiatorsSiteMap, storSystems, null, Long.valueOf("3221225472"), Long.valueOf("2"), siteVolCap, siteVolCnt);
// RP Site Array objects
RPSiteArray rpSiteArray1 = new RPSiteArray();
rpSiteArray1.setId(URI.create("rsa1"));
rpSiteArray1.setStorageSystem(URI.create("vmax1"));
rpSiteArray1.setRpInternalSiteName("site1");
rpSiteArray1.setRpProtectionSystem(rpSystem.getId());
_dbClient.createObject(rpSiteArray1);
RPSiteArray rpSiteArray2 = new RPSiteArray();
rpSiteArray2.setId(URI.create("rsa2"));
rpSiteArray2.setStorageSystem(URI.create("vmax2"));
rpSiteArray2.setRpInternalSiteName("site2");
rpSiteArray2.setRpProtectionSystem(rpSystem.getId());
_dbClient.createObject(rpSiteArray2);
// Create a storage pool for vmax1
StoragePool pool1 = PlacementTestUtils.createStoragePool(_dbClient, rpSrcVarray, storageSystem1, "pool1", "Pool1", Long.valueOf(SIZE_GB * 10), Long.valueOf(SIZE_GB * 10), 300, 300, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax1
StoragePool pool2 = PlacementTestUtils.createStoragePool(_dbClient, rpSrcVarray, storageSystem1, "pool2", "Pool2", Long.valueOf(SIZE_GB * 10), Long.valueOf(SIZE_GB * 10), 300, 300, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax1
StoragePool pool3 = PlacementTestUtils.createStoragePool(_dbClient, rpSrcVarray, storageSystem1, "pool3", "Pool3", Long.valueOf(SIZE_GB * 1), Long.valueOf(SIZE_GB * 1), 100, 100, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax2
StoragePool pool4 = PlacementTestUtils.createStoragePool(_dbClient, rpTgtVarray, storageSystem2, "pool4", "Pool4", Long.valueOf(SIZE_GB * 10), Long.valueOf(SIZE_GB * 10), 300, 300, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax2
StoragePool pool5 = PlacementTestUtils.createStoragePool(_dbClient, rpTgtVarray, storageSystem2, "pool5", "Pool5", Long.valueOf(SIZE_GB * 10), Long.valueOf(SIZE_GB * 10), 300, 300, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax2
StoragePool pool6 = PlacementTestUtils.createStoragePool(_dbClient, rpTgtVarray, storageSystem2, "pool6", "Pool6", Long.valueOf(SIZE_GB * 1), Long.valueOf(SIZE_GB * 1), 100, 100, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a virtual pool
VirtualPool rpTgtVpool = new VirtualPool();
rpTgtVpool.setId(URI.create("rpTgtVpool"));
rpTgtVpool.setLabel("RP Target Vpool");
rpTgtVpool.setSupportedProvisioningType(VirtualPool.ProvisioningType.Thin.name());
rpTgtVpool.setDriveType(SupportedDriveTypes.FC.name());
StringSet matchedPools = new StringSet();
matchedPools.add(pool4.getId().toString());
matchedPools.add(pool5.getId().toString());
matchedPools.add(pool6.getId().toString());
rpTgtVpool.setMatchedStoragePools(matchedPools);
rpTgtVpool.setUseMatchedPools(true);
StringSet virtualArrays2 = new StringSet();
virtualArrays2.add(rpTgtVarray.getId().toString());
rpTgtVpool.setVirtualArrays(virtualArrays2);
_dbClient.createObject(rpTgtVpool);
// Create a RP virtual pool
VirtualPool rpSrcVpool = new VirtualPool();
rpSrcVpool.setId(URI.create("rpSrcVpool"));
rpSrcVpool.setLabel("RP Source Vpool");
rpSrcVpool.setSupportedProvisioningType(VirtualPool.ProvisioningType.Thin.name());
rpSrcVpool.setDriveType(SupportedDriveTypes.FC.name());
VpoolProtectionVarraySettings protectionSettings = new VpoolProtectionVarraySettings();
protectionSettings.setVirtualPool(rpTgtVpool.getId());
protectionSettings.setId(URI.create("protectionSettings"));
_dbClient.createObject(protectionSettings);
List<VpoolProtectionVarraySettings> protectionSettingsList = new ArrayList<VpoolProtectionVarraySettings>();
protectionSettingsList.add(protectionSettings);
StringMap protectionVarray = new StringMap();
protectionVarray.put(rpTgtVarray.getId().toString(), protectionSettingsList.get(0).getId().toString());
rpSrcVpool.setProtectionVarraySettings(protectionVarray);
rpSrcVpool.setRpCopyMode("SYNCHRONOUS");
rpSrcVpool.setRpRpoType("MINUTES");
rpSrcVpool.setRpRpoValue(Long.valueOf("5"));
matchedPools = new StringSet();
matchedPools.add(pool1.getId().toString());
matchedPools.add(pool2.getId().toString());
matchedPools.add(pool3.getId().toString());
rpSrcVpool.setMatchedStoragePools(matchedPools);
rpSrcVpool.setUseMatchedPools(true);
StringSet virtualArrays1 = new StringSet();
virtualArrays1.add(rpSrcVarray.getId().toString());
rpSrcVpool.setVirtualArrays(virtualArrays1);
_dbClient.createObject(rpSrcVpool);
// Create Tenant
TenantOrg tenant = new TenantOrg();
tenant.setId(URI.create("tenant"));
_dbClient.createObject(tenant);
// Create a project object
Project project = new Project();
project.setId(URI.create("project"));
project.setLabel("project");
project.setTenantOrg(new NamedURI(tenant.getId(), project.getLabel()));
_dbClient.createObject(project);
// Create block consistency group
BlockConsistencyGroup cg = new BlockConsistencyGroup();
cg.setProject(new NamedURI(project.getId(), project.getLabel()));
cg.setId(URI.create("blockCG"));
_dbClient.createObject(cg);
// Create capabilities
VirtualPoolCapabilityValuesWrapper capabilities = PlacementTestUtils.createCapabilities("2GB", 1, cg);
// Run single volume placement: Run 10 times to make sure pool3 never comes up for source and pool6 for target.
for (int i = 0; i < 10; i++) {
List recommendations = PlacementTestUtils.invokePlacement(_dbClient, _coordinator, rpSrcVarray, project, rpSrcVpool, capabilities);
assertNotNull(recommendations);
assertTrue(!recommendations.isEmpty());
assertNotNull(recommendations.get(0));
RPProtectionRecommendation rec = (RPProtectionRecommendation) recommendations.get(0);
assertNotNull(rec.getSourceRecommendations());
assertTrue(!rec.getSourceRecommendations().isEmpty());
assertNotNull(rec.getProtectionDevice());
assertNotNull(rec.getPlacementStepsCompleted().name());
assertTrue("rp1".equals(rec.getProtectionDevice().toString()));
for (RPRecommendation rpRec : rec.getSourceRecommendations()) {
assertNotNull(rpRec.getInternalSiteName());
assertNotNull(rpRec.getSourceStorageSystem());
assertNotNull(rpRec.getSourceStoragePool());
assertTrue("site1".equals(rpRec.getInternalSiteName()));
assertTrue("vmax1".equals(rpRec.getSourceStorageSystem().toString()));
assertTrue(("pool2".equals(rpRec.getSourceStoragePool().toString())) || ("pool1".equals(rpRec.getSourceStoragePool().toString())));
assertNotNull(rpRec.getTargetRecommendations());
assertTrue(!rpRec.getTargetRecommendations().isEmpty());
for (RPRecommendation targetRec : rpRec.getTargetRecommendations()) {
assertNotNull(targetRec.getSourceStoragePool());
assertTrue("vmax2".equals(targetRec.getSourceStorageSystem().toString()));
assertTrue("site2".equals(targetRec.getInternalSiteName()));
assertTrue("pool5".equals(targetRec.getSourceStoragePool().toString()) || "pool4".equals(targetRec.getSourceStoragePool().toString()));
}
}
// source journal
assertNotNull(rec.getSourceJournalRecommendation());
assertNotNull(rec.getSourceJournalRecommendation().getSourceStoragePool());
assertNotNull(rec.getSourceJournalRecommendation().getInternalSiteName());
assertTrue(("pool2".equals(rec.getSourceJournalRecommendation().getSourceStoragePool().toString())) || ("pool1".equals(rec.getSourceJournalRecommendation().getSourceStoragePool().toString())));
// target journal
assertNotNull(rec.getTargetJournalRecommendations());
assertNotNull(!rec.getTargetJournalRecommendations().isEmpty());
for (RPRecommendation targetJournalRec : rec.getTargetJournalRecommendations()) {
assertNotNull(targetJournalRec.getSourceStoragePool());
assertTrue("pool5".equals(targetJournalRec.getSourceStoragePool().toString()) || "pool4".equals(targetJournalRec.getSourceStoragePool().toString()));
assertTrue("site2".equals(targetJournalRec.getInternalSiteName()));
assertTrue("vmax2".equals(targetJournalRec.getSourceStorageSystem().toString()));
}
_log.info(rec.toString(_dbClient));
}
}
use of com.emc.storageos.volumecontroller.RPRecommendation in project coprhd-controller by CoprHD.
the class PlacementTests method testPlacementRpVplexAdvancedSite2toSite1.
/**
* RP VPLEX placement -- placement decision based on RP array visibility
*/
@Test
public void testPlacementRpVplexAdvancedSite2toSite1() {
String[] vmax1FE = { "50:FE:FE:FE:FE:FE:FE:00", "50:FE:FE:FE:FE:FE:FE:01" };
String[] vmax2FE = { "51:FE:FE:FE:FE:FE:FE:00", "51:FE:FE:FE:FE:FE:FE:01" };
String[] vmax3FE = { "52:FE:FE:FE:FE:FE:FE:00", "52:FE:FE:FE:FE:FE:FE:01" };
String[] rp1FE = { "53:FE:FE:FE:FE:FE:FE:00", "53:FE:FE:FE:FE:FE:FE:01" };
String[] rp2FE = { "54:FE:FE:FE:FE:FE:FE:00", "54:FE:FE:FE:FE:FE:FE:01" };
String[] vplex1FE = { "FE:FE:FE:FE:FE:FE:FE:00", "FE:FE:FE:FE:FE:FE:FE:01" };
String[] vplex1BE = { "BE:BE:BE:BE:BE:BE:BE:00", "BE:BE:BE:BE:BE:BE:BE:01" };
String[] vplex2FE = { "FE:FE:FE:FE:FE:FE:FE:02", "FE:FE:FE:FE:FE:FE:FE:03" };
String[] vplex2BE = { "BE:BE:BE:BE:BE:BE:BE:02", "BE:BE:BE:BE:BE:BE:BE:03" };
String[] vplex3FE = { "FE:FE:FE:FE:FE:FE:FE:04", "FE:FE:FE:FE:FE:FE:FE:05" };
String[] vplex3BE = { "BE:BE:BE:BE:BE:BE:BE:04", "BE:BE:BE:BE:BE:BE:BE:05" };
// Create 3 Virtual Arrays
VirtualArray varray1 = PlacementTestUtils.createVirtualArray(_dbClient, "varray1");
VirtualArray varray2 = PlacementTestUtils.createVirtualArray(_dbClient, "varray2");
VirtualArray varray3 = PlacementTestUtils.createVirtualArray(_dbClient, "varray3");
// Create 1 Network
StringSet connVA = new StringSet();
connVA.add(varray1.getId().toString());
connVA.add(varray2.getId().toString());
connVA.add(varray3.getId().toString());
Network network = PlacementTestUtils.createNetwork(_dbClient, vplex1FE, "VSAN", "FC+BROCADE", connVA);
PlacementTestUtils.addEndpoints(_dbClient, network, vplex2FE);
PlacementTestUtils.addEndpoints(_dbClient, network, vplex3FE);
PlacementTestUtils.addEndpoints(_dbClient, network, vplex1BE);
PlacementTestUtils.addEndpoints(_dbClient, network, vplex2BE);
PlacementTestUtils.addEndpoints(_dbClient, network, vplex3BE);
PlacementTestUtils.addEndpoints(_dbClient, network, rp1FE);
PlacementTestUtils.addEndpoints(_dbClient, network, rp2FE);
PlacementTestUtils.addEndpoints(_dbClient, network, vmax1FE);
PlacementTestUtils.addEndpoints(_dbClient, network, vmax2FE);
PlacementTestUtils.addEndpoints(_dbClient, network, vmax3FE);
// Create 3 storage systems
StorageSystem storageSystem1 = PlacementTestUtils.createStorageSystem(_dbClient, "vmax", "vmax1");
StorageSystem storageSystem2 = PlacementTestUtils.createStorageSystem(_dbClient, "vmax", "vmax2");
StorageSystem storageSystem3 = PlacementTestUtils.createStorageSystem(_dbClient, "vmax", "vmax3");
// Create two front-end storage ports VMAX1
List<StoragePort> vmax1Ports = new ArrayList<StoragePort>();
for (int i = 0; i < vmax1FE.length; i++) {
vmax1Ports.add(PlacementTestUtils.createStoragePort(_dbClient, storageSystem1, network, vmax1FE[i], varray1, StoragePort.PortType.frontend.name(), "portGroupvmax1" + i, "C0+FC0" + i));
}
// Create two front-end storage ports VMAX2
List<StoragePort> vmax2Ports = new ArrayList<StoragePort>();
for (int i = 0; i < vmax2FE.length; i++) {
vmax2Ports.add(PlacementTestUtils.createStoragePort(_dbClient, storageSystem2, network, vmax2FE[i], varray2, StoragePort.PortType.frontend.name(), "portGroupvmax2" + i, "D0+FC0" + i));
}
// Create two front-end storage ports VMAX3
List<StoragePort> vmax3Ports = new ArrayList<StoragePort>();
for (int i = 0; i < vmax3FE.length; i++) {
vmax3Ports.add(PlacementTestUtils.createStoragePort(_dbClient, storageSystem3, network, vmax3FE[i], varray3, StoragePort.PortType.frontend.name(), "portGroupvmax3" + i, "E0+FC0" + i));
}
// Create 2 VPLEX storage systems
StorageSystem vplexStorageSystem1 = PlacementTestUtils.createStorageSystem(_dbClient, "vplex", "vplex1");
StorageSystem vplexStorageSystem2 = PlacementTestUtils.createStorageSystem(_dbClient, "vplex", "vplex2");
// Create two front-end storage ports VPLEX1
List<StoragePort> fePorts1 = new ArrayList<StoragePort>();
for (int i = 0; i < vplex1FE.length; i++) {
fePorts1.add(PlacementTestUtils.createStoragePort(_dbClient, vplexStorageSystem1, network, vplex1FE[i], varray1, StoragePort.PortType.frontend.name(), "portGroupFE1-" + (i + 1), "A0+FC0" + i));
}
// Create two back-end storage ports VPLEX1
List<StoragePort> bePorts1 = new ArrayList<StoragePort>();
for (int i = 0; i < vplex1BE.length; i++) {
bePorts1.add(PlacementTestUtils.createStoragePort(_dbClient, vplexStorageSystem1, network, vplex1BE[i], varray1, StoragePort.PortType.backend.name(), "portGroupBE1-" + (i + 1), "B0+FC0" + i));
}
// Create two front-end storage ports VPLEX2
List<StoragePort> fePorts2 = new ArrayList<StoragePort>();
for (int i = 0; i < vplex2FE.length; i++) {
fePorts2.add(PlacementTestUtils.createStoragePort(_dbClient, vplexStorageSystem1, network, vplex2FE[i], varray2, StoragePort.PortType.frontend.name(), "portGroupFE2-" + (i + 1), "F0+FC0" + i));
}
// Create two back-end storage ports VPLEX2
List<StoragePort> bePorts2 = new ArrayList<StoragePort>();
for (int i = 0; i < vplex2BE.length; i++) {
bePorts2.add(PlacementTestUtils.createStoragePort(_dbClient, vplexStorageSystem1, network, vplex2BE[i], varray2, StoragePort.PortType.backend.name(), "portGroupBE2-" + (i + 1), "G0+FC0" + i));
}
// Create two front-end storage ports VPLEX3
List<StoragePort> fePorts3 = new ArrayList<StoragePort>();
for (int i = 0; i < vplex3FE.length; i++) {
fePorts3.add(PlacementTestUtils.createStoragePort(_dbClient, vplexStorageSystem2, network, vplex3FE[i], varray3, StoragePort.PortType.frontend.name(), "portGroupFE3-" + (i + 1), "H0+FC0" + i));
}
// Create two back-end storage ports VPLEX3
List<StoragePort> bePorts3 = new ArrayList<StoragePort>();
for (int i = 0; i < vplex3BE.length; i++) {
bePorts3.add(PlacementTestUtils.createStoragePort(_dbClient, vplexStorageSystem2, network, vplex3BE[i], varray3, StoragePort.PortType.backend.name(), "portGroupBE3-" + (i + 1), "I0+FC0" + i));
}
// Create RP system
AbstractChangeTrackingSet<String> wwnSite1 = new StringSet();
for (int i = 0; i < rp1FE.length; i++) {
wwnSite1.add(rp1FE[i]);
}
StringSetMap initiatorsSiteMap = new StringSetMap();
initiatorsSiteMap.put("site1", wwnSite1);
AbstractChangeTrackingSet<String> wwnSite2 = new StringSet();
for (int i = 0; i < rp2FE.length; i++) {
wwnSite2.add(rp2FE[i]);
}
initiatorsSiteMap.put("site2", wwnSite2);
StringSet storSystems = new StringSet();
storSystems.add(ProtectionSystem.generateAssociatedStorageSystem("site2", "vplex1cluster1"));
storSystems.add(ProtectionSystem.generateAssociatedStorageSystem("site2", "vplex1cluster2"));
storSystems.add(ProtectionSystem.generateAssociatedStorageSystem("site1", "vplex2cluster1"));
storSystems.add(ProtectionSystem.generateAssociatedStorageSystem("site1", "vplex2cluster2"));
StringSetMap rpVisibleSystems = new StringSetMap();
StringSet storageIds = new StringSet();
storageIds.add(vplexStorageSystem2.getId().toString());
rpVisibleSystems.put("site1", storageIds);
StringSet storageIds2 = new StringSet();
storageIds2.add(vplexStorageSystem1.getId().toString());
rpVisibleSystems.put("site2", storageIds2);
StringMap siteVolCap = new StringMap();
siteVolCap.put("site1", "3221225472");
siteVolCap.put("site2", "3221225472");
StringMap siteVolCnt = new StringMap();
siteVolCnt.put("site1", "10");
siteVolCnt.put("site2", "10");
ProtectionSystem rpSystem = PlacementTestUtils.createProtectionSystem(_dbClient, "rp", "rp1", "site1", "site2", null, "IP", initiatorsSiteMap, storSystems, rpVisibleSystems, Long.valueOf("3221225472"), Long.valueOf("2"), siteVolCap, siteVolCnt);
// RP Site Array objects
RPSiteArray rpSiteArray1 = new RPSiteArray();
rpSiteArray1.setId(URI.create("rsa1"));
rpSiteArray1.setStorageSystem(URI.create("vplex1"));
rpSiteArray1.setRpInternalSiteName("site1");
rpSiteArray1.setRpProtectionSystem(rpSystem.getId());
_dbClient.createObject(rpSiteArray1);
RPSiteArray rpSiteArray2 = new RPSiteArray();
rpSiteArray2.setId(URI.create("rsa2"));
rpSiteArray2.setStorageSystem(URI.create("vplex2"));
rpSiteArray2.setRpInternalSiteName("site2");
rpSiteArray2.setRpProtectionSystem(rpSystem.getId());
_dbClient.createObject(rpSiteArray2);
// Create a storage pool for vmax1
StoragePool pool1 = PlacementTestUtils.createStoragePool(_dbClient, varray1, storageSystem1, "pool1", "Pool1", Long.valueOf(1024 * 1024 * 10), Long.valueOf(1024 * 1024 * 100), 300, 300, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax1
StoragePool pool2 = PlacementTestUtils.createStoragePool(_dbClient, varray1, storageSystem1, "pool2", "Pool2", Long.valueOf(1024 * 1024 * 10), Long.valueOf(1024 * 1024 * 100), 300, 300, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax1
StoragePool pool3 = PlacementTestUtils.createStoragePool(_dbClient, varray1, storageSystem1, "pool3", "Pool3", Long.valueOf(1024 * 1024 * 1), Long.valueOf(1024 * 1024 * 10), 100, 100, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax2
StoragePool pool4 = PlacementTestUtils.createStoragePool(_dbClient, varray2, storageSystem2, "pool4", "Pool4", Long.valueOf(1024 * 1024 * 10), Long.valueOf(1024 * 1024 * 10), 300, 300, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax2
StoragePool pool5 = PlacementTestUtils.createStoragePool(_dbClient, varray2, storageSystem2, "pool5", "Pool5", Long.valueOf(1024 * 1024 * 10), Long.valueOf(1024 * 1024 * 100), 300, 300, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax2
StoragePool pool6 = PlacementTestUtils.createStoragePool(_dbClient, varray2, storageSystem2, "pool6", "Pool6", Long.valueOf(1024 * 1024 * 1), Long.valueOf(1024 * 1024 * 1024), 100, 100, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax3
StoragePool pool7 = PlacementTestUtils.createStoragePool(_dbClient, varray3, storageSystem3, "pool7", "Pool7", Long.valueOf(1024 * 1024 * 10), Long.valueOf(1024 * 1024 * 10), 300, 300, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax3
StoragePool pool8 = PlacementTestUtils.createStoragePool(_dbClient, varray3, storageSystem3, "pool8", "Pool8", Long.valueOf(1024 * 1024 * 10), Long.valueOf(1024 * 1024 * 1024), 300, 300, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a storage pool for vmax3
StoragePool pool9 = PlacementTestUtils.createStoragePool(_dbClient, varray3, storageSystem3, "pool9", "Pool9", Long.valueOf(1024 * 1024 * 1), Long.valueOf(1024 * 1024 * 1), 100, 100, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
// Create a base HA virtual pool
VirtualPool vpoolHA = new VirtualPool();
vpoolHA.setId(URI.create("urn:storageos:VirtualPool:015810fc-0793-4ca1-8281-16adef26dd41:vdc1"));
vpoolHA.setLabel("vpoolHA");
vpoolHA.setType("block");
vpoolHA.setSupportedProvisioningType(VirtualPool.ProvisioningType.Thin.name());
vpoolHA.setDriveType(SupportedDriveTypes.FC.name());
StringSet matchedPools = new StringSet();
matchedPools.add(pool1.getId().toString());
matchedPools.add(pool2.getId().toString());
matchedPools.add(pool3.getId().toString());
vpoolHA.setMatchedStoragePools(matchedPools);
StringSet virtualArrays1 = new StringSet();
virtualArrays1.add(varray1.getId().toString());
vpoolHA.setVirtualArrays(virtualArrays1);
vpoolHA.setUseMatchedPools(true);
_dbClient.createObject(vpoolHA);
// Create a base RP virtual pool
VirtualPool vpoolRP = new VirtualPool();
vpoolRP.setId(URI.create("vpoolRP"));
vpoolRP.setLabel("vpoolRP");
vpoolRP.setSupportedProvisioningType(VirtualPool.ProvisioningType.Thin.name());
vpoolRP.setDriveType(SupportedDriveTypes.FC.name());
vpoolRP.setHighAvailability(VirtualPool.HighAvailabilityType.vplex_local.name());
matchedPools = new StringSet();
matchedPools.add(pool7.getId().toString());
matchedPools.add(pool8.getId().toString());
matchedPools.add(pool9.getId().toString());
vpoolRP.setMatchedStoragePools(matchedPools);
vpoolRP.setUseMatchedPools(true);
StringSet virtualArrays3 = new StringSet();
virtualArrays3.add(varray3.getId().toString());
vpoolRP.setVirtualArrays(virtualArrays3);
_dbClient.createObject(vpoolRP);
// Create a RP VPLEX virtual pool
VirtualPool rpVplexVpool = new VirtualPool();
rpVplexVpool.setId(URI.create("rpVplexVpool"));
rpVplexVpool.setLabel("rpVplexVpool");
rpVplexVpool.setSupportedProvisioningType(VirtualPool.ProvisioningType.Thin.name());
rpVplexVpool.setDriveType(SupportedDriveTypes.FC.name());
rpVplexVpool.setHighAvailability(VirtualPool.HighAvailabilityType.vplex_distributed.name());
StringMap vavpMap = new StringMap();
vavpMap.put(varray1.getId().toString(), vpoolHA.getId().toString());
rpVplexVpool.setHaVarrayVpoolMap(vavpMap);
VpoolProtectionVarraySettings protectionSettings = new VpoolProtectionVarraySettings();
protectionSettings.setVirtualPool(vpoolRP.getId());
protectionSettings.setId(URI.create("protectionSettings"));
_dbClient.createObject(protectionSettings);
List<VpoolProtectionVarraySettings> protectionSettingsList = new ArrayList<VpoolProtectionVarraySettings>();
protectionSettingsList.add(protectionSettings);
StringMap protectionVarray = new StringMap();
protectionVarray.put(varray3.getId().toString(), protectionSettingsList.get(0).getId().toString());
rpVplexVpool.setProtectionVarraySettings(protectionVarray);
rpVplexVpool.setRpCopyMode("SYNCHRONOUS");
rpVplexVpool.setRpRpoType("MINUTES");
rpVplexVpool.setRpRpoValue(Long.valueOf("5"));
matchedPools = new StringSet();
matchedPools.add(pool4.getId().toString());
matchedPools.add(pool5.getId().toString());
matchedPools.add(pool6.getId().toString());
rpVplexVpool.setMatchedStoragePools(matchedPools);
rpVplexVpool.setUseMatchedPools(true);
StringSet virtualArrays2 = new StringSet();
virtualArrays2.add(varray2.getId().toString());
rpVplexVpool.setVirtualArrays(virtualArrays2);
_dbClient.createObject(rpVplexVpool);
// Create Tenant
TenantOrg tenant = new TenantOrg();
tenant.setId(URI.create("tenant"));
_dbClient.createObject(tenant);
// Create a project object
Project project = new Project();
project.setId(URI.create("project"));
project.setLabel("project");
project.setTenantOrg(new NamedURI(tenant.getId(), project.getLabel()));
_dbClient.createObject(project);
// Create block consistency group
BlockConsistencyGroup cg = new BlockConsistencyGroup();
cg.setProject(new NamedURI(project.getId(), project.getLabel()));
cg.setId(URI.create("blockCG"));
_dbClient.createObject(cg);
// Create capabilities
VirtualPoolCapabilityValuesWrapper capabilities = PlacementTestUtils.createCapabilities("2GB", 2, cg);
// Run single volume placement: Run 10 times to make sure pool6 never comes up for source and pool9 for target.
for (int i = 0; i < 10; i++) {
List recommendations = PlacementTestUtils.invokePlacement(_dbClient, _coordinator, varray2, project, rpVplexVpool, capabilities);
assertNotNull(recommendations);
assertTrue(!recommendations.isEmpty());
assertNotNull(recommendations.get(0));
RPProtectionRecommendation rec = (RPProtectionRecommendation) recommendations.get(0);
for (RPRecommendation rpRec : rec.getSourceRecommendations()) {
assertNotNull(rpRec.getVirtualArray());
assertNotNull(rpRec.getVirtualPool());
assertNotNull(rpRec.getInternalSiteName());
assertNotNull(rpRec.getSourceStorageSystem());
assertNotNull(rpRec.getSourceStoragePool());
assertTrue("site2".equals(rpRec.getInternalSiteName()));
assertTrue("vmax2".equals(rpRec.getSourceStorageSystem().toString()));
assertTrue(("pool4".equals(rpRec.getSourceStoragePool().toString())) || ("pool5".equals(rec.getSourceStoragePool().toString())));
assertNotNull(rpRec.getVirtualVolumeRecommendation());
assertTrue("vplex1".equals(rpRec.getVirtualVolumeRecommendation().getVPlexStorageSystem().toString()));
assertNotNull(rpRec.getHaRecommendation());
assertTrue("vplex1".equals(rpRec.getHaRecommendation().getVirtualVolumeRecommendation().getVPlexStorageSystem().toString()));
assertTrue("varray1".equals(rpRec.getHaRecommendation().getVirtualArray().toString()));
assertTrue("urn:storageos:VirtualPool:015810fc-0793-4ca1-8281-16adef26dd41:vdc1".equals(rpRec.getHaRecommendation().getVirtualPool().getId().toString()));
assertTrue("vmax1".equals(rpRec.getHaRecommendation().getSourceStorageSystem().toString()));
assertTrue(("pool2".equals(rpRec.getHaRecommendation().getSourceStoragePool().toString())) || ("pool1".equals(rpRec.getHaRecommendation().getSourceStoragePool().toString())));
assertNotNull(rpRec.getTargetRecommendations());
assertTrue(!rpRec.getTargetRecommendations().isEmpty());
for (RPRecommendation targetRec : rpRec.getTargetRecommendations()) {
assertNotNull(targetRec.getInternalSiteName());
assertNotNull(targetRec.getVirtualArray());
assertNotNull(targetRec.getVirtualPool());
assertNotNull(targetRec.getSourceStorageSystem());
assertNotNull(targetRec.getSourceStoragePool());
assertTrue("vmax3".equals(targetRec.getSourceStorageSystem().toString()));
assertTrue("varray3".equals(targetRec.getVirtualArray().toString()));
assertTrue("site1".equals(targetRec.getInternalSiteName()));
assertTrue("vpoolRP".equals(targetRec.getVirtualPool().getId().toString()));
assertTrue(("pool8".equals(targetRec.getSourceStoragePool().toString())) || ("pool7".equals(targetRec.getSourceStoragePool().toString())));
}
}
// Source journal
assertNotNull(rec.getSourceJournalRecommendation());
assertNotNull(rec.getSourceJournalRecommendation().getInternalSiteName());
assertNotNull(rec.getSourceJournalRecommendation().getSourceStoragePool());
assertNotNull(rec.getSourceJournalRecommendation().getSourceStorageSystem());
assertNotNull(rec.getSourceJournalRecommendation().getVirtualArray());
assertNotNull(rec.getSourceJournalRecommendation().getVirtualPool());
assertTrue("site2".equals(rec.getSourceJournalRecommendation().getInternalSiteName()));
assertTrue(("pool5".equals(rec.getSourceJournalRecommendation().getSourceStoragePool().toString())) || ("pool4".equals(rec.getSourceJournalRecommendation().getSourceStoragePool().toString())));
// TargetJournal
assertNotNull(rec.getTargetJournalRecommendations());
assertTrue(!rec.getTargetJournalRecommendations().isEmpty());
for (RPRecommendation targetJournalRec : rec.getTargetJournalRecommendations()) {
assertNotNull(targetJournalRec);
assertNotNull(targetJournalRec.getInternalSiteName());
assertNotNull(targetJournalRec.getSourceStoragePool());
assertNotNull(targetJournalRec.getSourceStorageSystem());
assertNotNull(targetJournalRec.getVirtualArray());
assertNotNull(targetJournalRec.getVirtualPool());
assertTrue("vmax3".equals(targetJournalRec.getSourceStorageSystem().toString()));
assertTrue("site1".equals(targetJournalRec.getInternalSiteName()));
assertTrue(("pool8".equals(targetJournalRec.getSourceStoragePool().toString())) || ("pool7".equals(targetJournalRec.getSourceStoragePool().toString())));
}
_log.info(String.format("Placement results (#%s) : \n %s", i, rec.toString(_dbClient)));
}
}
use of com.emc.storageos.volumecontroller.RPRecommendation in project coprhd-controller by CoprHD.
the class RecoverPointScheduler method createRPProtectionRecommendationForMetroPoint.
/**
* Creates primary (active) and secondary (standby) cluster recommendations for MetroPoint.
*
* We first determine the type of MetroPoint request based on the protection virtual array
* configuration (single remote, local only, or local and remote). Using this information
* we determine a possible placement recommendation for the primary cluster. Using the
* primary cluster recommendation we then figure out a secondary cluster recommendation.
* The secondary cluster recommendation needs protection attributes that give with the
* primary cluster recommendation to satisfy the type of MetroPoint configuration requested.
*
* @param varray the source virtual array.
* @param protectionVarrays the RecoverPoint protection virtual arrays.
* @param vpool the source virtual pool.
* @param haVarray the HA virtual array - secondary cluster.
* @param haVpool the HA virtual pool - secondary cluster.
* @param capabilities parameters.
* @param candidateActiveSourcePools the candidate primary cluster source pools.
* @param candidateStandbySourcePools the candidate secondary cluster source pools.
* @param candidateProtectionPoolsMap pre-populated map for tgt varray to storage pools, use null if not needed
* @return list of Recommendation objects to satisfy the request
*/
private RPProtectionRecommendation createRPProtectionRecommendationForMetroPoint(VirtualArray varray, List<VirtualArray> protectionVarrays, VirtualPool vpool, VirtualArray haVarray, VirtualPool haVpool, VirtualPoolCapabilityValuesWrapper capabilities, List<StoragePool> candidateActiveSourcePools, List<StoragePool> candidateStandbySourcePools, Map<VirtualArray, List<StoragePool>> candidateProtectionPools, Volume vpoolChangeVolume, Project project) {
// Initialize a list of recommendations to be returned.
Set<ProtectionSystem> secondaryProtectionSystems = null;
placementStatus = new PlacementStatus();
secondaryPlacementStatus = new PlacementStatus();
int requestedResourceCount = capabilities.getResourceCount();
int totalSatisfiedCount = 0;
List<URI> protectionVarrayURIs = new ArrayList<URI>();
for (VirtualArray vArray : protectionVarrays) {
protectionVarrayURIs.add(vArray.getId());
placementStatus.getProcessedProtectionVArrays().put(vArray.getId(), false);
}
// Active journal varray - Either explicitly set by the user or use the default varray.
VirtualArray activeJournalVarray = (NullColumnValueGetter.isNotNullValue(vpool.getJournalVarray()) ? dbClient.queryObject(VirtualArray.class, URI.create(vpool.getJournalVarray())) : varray);
// Active journal vpool - Either explicitly set by the user or use the default vpool.
VirtualPool activeJournalVpool = (NullColumnValueGetter.isNotNullValue(vpool.getJournalVpool()) ? dbClient.queryObject(VirtualPool.class, URI.create(vpool.getJournalVpool())) : vpool);
// Standby journal varray - Either explicitly set by the user or use the default haVarray.
VirtualArray standbyJournalVarray = (NullColumnValueGetter.isNotNullValue(vpool.getStandbyJournalVarray()) ? dbClient.queryObject(VirtualArray.class, URI.create(vpool.getStandbyJournalVarray())) : haVarray);
// Standby journal vpool - Either explicitly set by the user or use the default haVpool.
VirtualPool standbyJournalVpool = (NullColumnValueGetter.isNotNullValue(vpool.getStandbyJournalVpool()) ? dbClient.queryObject(VirtualPool.class, URI.create(vpool.getStandbyJournalVpool())) : haVpool);
// Build the list of protection virtual arrays to consider for determining a
// primary placement solution. Add all virtual arrays from the source virtual
// pool list of protection virtual arrays, except for the HA/standby virtual array.
// In the case of local and/or remote protection, the HA virtual array should
// never be considered as a valid protection target for primary placement.
List<VirtualArray> activeProtectionVarrays = new ArrayList<VirtualArray>();
for (VirtualArray protectionVarray : protectionVarrays) {
if (!protectionVarray.getId().equals(haVarray.getId())) {
activeProtectionVarrays.add(protectionVarray);
}
}
// Build the list of protection virtual arrays to consider for determining a
// standby placement solution. Add all virtual arrays from the source virtual
// pool list of protection virtual arrays, except for the source virtual array.
// In the case of local and/or remote protection, the source virtual array should
// never be considered as a valid protection target for standby placement.
List<VirtualArray> standbyProtectionVarrays = new ArrayList<VirtualArray>();
for (VirtualArray protectionVarray : protectionVarrays) {
if (!protectionVarray.getId().equals(varray.getId())) {
standbyProtectionVarrays.add(protectionVarray);
}
}
// The attributes below will not change throughout the placement process
placementStatus.setSrcVArray(varray.getLabel());
placementStatus.setSrcVPool(vpool.getLabel());
boolean secondaryRecommendationSolution = false;
int satisfiedSourceVolCount = 0;
int totalRequestedResourceCount = capabilities.getResourceCount();
boolean isChangeVpool = (vpoolChangeVolume != null);
// Top level recommendation object
RPProtectionRecommendation rpProtectionRecommendation = new RPProtectionRecommendation();
// Source pool recommendations
List<Recommendation> sourcePoolRecommendations = new ArrayList<Recommendation>();
// Map to hold standby storage pools to protection systems
Map<URI, Set<ProtectionSystem>> standbyStoragePoolsToProtectionSystems = new HashMap<URI, Set<ProtectionSystem>>();
// Change vpool only: Set values for change vpool. If not a change vpool these values will be null.
rpProtectionRecommendation.setVpoolChangeVolume(vpoolChangeVolume != null ? vpoolChangeVolume.getId() : null);
rpProtectionRecommendation.setVpoolChangeNewVpool(vpoolChangeVolume != null ? vpool.getId() : null);
rpProtectionRecommendation.setVpoolChangeProtectionAlreadyExists(vpoolChangeVolume != null ? vpoolChangeVolume.checkForRp() : false);
// Change vpool only: Recommendation objects specifically used for change vpool. These will not be populated otherwise.
Recommendation changeVpoolSourceRecommendation = new Recommendation();
Recommendation changeVpoolStandbyRecommendation = new Recommendation();
if (isChangeVpool) {
// valid pool, the existing ones for active and standby. This is just to used to pass through the placement code.
if (null == vpoolChangeVolume.getAssociatedVolumes() || vpoolChangeVolume.getAssociatedVolumes().isEmpty()) {
_log.error("VPLEX volume {} has no backend volumes.", vpoolChangeVolume.forDisplay());
throw InternalServerErrorException.internalServerErrors.noAssociatedVolumesForVPLEXVolume(vpoolChangeVolume.forDisplay());
}
for (String associatedVolume : vpoolChangeVolume.getAssociatedVolumes()) {
Volume assocVol = dbClient.queryObject(Volume.class, URI.create(associatedVolume));
if (assocVol.getVirtualArray().equals(varray.getId())) {
// This is the existing active source backing volume
changeVpoolSourceRecommendation.setSourceStoragePool(assocVol.getPool());
StoragePool pool = dbClient.queryObject(StoragePool.class, assocVol.getPool());
changeVpoolSourceRecommendation.setSourceStorageSystem(pool.getStorageDevice());
changeVpoolSourceRecommendation.setResourceCount(1);
sourcePoolRecommendations.add(changeVpoolSourceRecommendation);
_log.info(String.format("RP Placement : Change Virtual Pool - Active source pool already exists, reuse pool: [%s] [%s].", pool.getLabel().toString(), pool.getId().toString()));
} else if (assocVol.getVirtualArray().equals(haVarray.getId())) {
// This is the existing standby source backing volume
changeVpoolStandbyRecommendation.setSourceStoragePool(assocVol.getPool());
StoragePool pool = dbClient.queryObject(StoragePool.class, assocVol.getPool());
changeVpoolStandbyRecommendation.setSourceStorageSystem(pool.getStorageDevice());
changeVpoolStandbyRecommendation.setResourceCount(1);
_log.info(String.format("RP Placement : Change Virtual Pool - Standby source pool already exists, reuse pool: [%s] [%s].", pool.getLabel().toString(), pool.getId().toString()));
}
}
satisfiedSourceVolCount = 1;
} else {
// If this is not a change vpool, then gather the recommended pools for the source.
sourcePoolRecommendations = getRecommendedPools(rpProtectionRecommendation, varray, vpool, null, null, capabilities, RPHelper.SOURCE, null);
}
// If we have no source pools at this point, throw an exception.
if (sourcePoolRecommendations == null || sourcePoolRecommendations.isEmpty()) {
_log.error(String.format("RP Placement : No matching storage pools found for the source varray: [%s. " + "There are no storage pools that match the passed vpool parameters and protocols and/or there are " + "no pools that have enough capacity to hold at least one resource of the requested size.", varray.getLabel()));
throw APIException.badRequests.noMatchingStoragePoolsForVpoolAndVarray(vpool.getLabel(), varray.getLabel());
}
_log.info(String.format("RP Placement : Determining RP placement for the primary (active) MetroPoint cluster for %s resources.", totalRequestedResourceCount));
// Keep track of the possible pools to use for the source. This will help us determine if we have
// exhausted all our options.
int remainingPossiblePrimarySrcPoolSolutions = sourcePoolRecommendations.size();
// Iterate over the source pools found to find a solution...
for (Recommendation recommendedPool : sourcePoolRecommendations) {
StoragePool sourcePool = dbClient.queryObject(StoragePool.class, recommendedPool.getSourceStoragePool());
--remainingPossiblePrimarySrcPoolSolutions;
satisfiedSourceVolCount = (recommendedPool.getResourceCount() >= requestedResourceCount) ? requestedResourceCount : recommendedPool.getResourceCount();
Set<ProtectionSystem> primaryProtectionSystems = new HashSet<ProtectionSystem>();
ProtectionSystem cgProtectionSystem = getCgProtectionSystem(capabilities.getBlockConsistencyGroup());
// used by other volumes in it.
if (cgProtectionSystem != null) {
BlockConsistencyGroup cg = dbClient.queryObject(BlockConsistencyGroup.class, capabilities.getBlockConsistencyGroup());
_log.info(String.format("RP Placement : Narrowing down placement to use protection system %s, which is currently used " + "by RecoverPoint consistency group %s.", cgProtectionSystem.getLabel(), cg));
primaryProtectionSystems.add(cgProtectionSystem);
} else {
primaryProtectionSystems = getProtectionSystemsForStoragePool(sourcePool, varray, true);
if (primaryProtectionSystems.isEmpty()) {
continue;
}
}
// Sort the ProtectionSystems based on the last time a CG was created. Always use the
// ProtectionSystem with the oldest cgLastCreated timestamp to support a round-robin
// style of load balancing.
List<ProtectionSystem> primaryProtectionSystemsList = sortProtectionSystems(primaryProtectionSystems);
for (ProtectionSystem primaryProtectionSystem : primaryProtectionSystemsList) {
Calendar cgLastCreated = primaryProtectionSystem.getCgLastCreatedTime();
_log.info(String.format("RP Placement : Attempting to use protection system [%s], which was last used to create a CG on [%s].", primaryProtectionSystem.getLabel(), cgLastCreated != null ? cgLastCreated.getTime().toString() : "N/A"));
// Get a list of associated storage systems for the pool, varray, and the protection system.
// This will return a list of strings that are in the format of:
// <storage system serial number>:<rp site name>
List<String> primaryAssociatedStorageSystems = getCandidateVisibleStorageSystems(sourcePool, primaryProtectionSystem, varray, activeProtectionVarrays, true);
if (primaryAssociatedStorageSystems.isEmpty()) {
// In this case no rp sites were connected to this storage system, we should not hit this,
// but just to be safe we'll catch it.
_log.info(String.format("RP Placement: Protection System %s does not have an rp site cluster connected to Storage pool %s ", primaryProtectionSystem.getLabel(), sourcePool.getLabel()));
continue;
}
// Iterate over the associated storage systems
for (String primaryAssociatedStorageSystem : primaryAssociatedStorageSystems) {
rpProtectionRecommendation.setProtectionDevice(primaryProtectionSystem.getId());
_log.info(String.format("RP Placement : Build MetroPoint Active Recommendation..."));
RPRecommendation sourceRec = buildSourceRecommendation(primaryAssociatedStorageSystem, varray, vpool, primaryProtectionSystem, sourcePool, capabilities, satisfiedSourceVolCount, placementStatus, vpoolChangeVolume, false);
if (sourceRec == null) {
// No source placement found for the primaryAssociatedStorageSystem, so continue.
_log.warn(String.format("RP Placement : Could not create MetroPoint Active Recommendation using [%s], continuing...", primaryAssociatedStorageSystem));
continue;
}
URI primarySourceStorageSystemURI = sourceRec.getVirtualVolumeRecommendation().getVPlexStorageSystem();
if (rpProtectionRecommendation.getSourceJournalRecommendation() == null) {
_log.info(String.format("RP Placement : Build MetroPoint Active Journal Recommendation..."));
RPRecommendation activeJournalRecommendation = buildJournalRecommendation(rpProtectionRecommendation, sourceRec.getInternalSiteName(), vpool.getJournalSize(), activeJournalVarray, activeJournalVpool, primaryProtectionSystem, capabilities, totalRequestedResourceCount, vpoolChangeVolume, false);
if (activeJournalRecommendation == null) {
// No source journal placement found, so continue.
_log.warn(String.format("RP Placement : Could not create MetroPoint Active Journal Recommendation, continuing..."));
continue;
}
rpProtectionRecommendation.setSourceJournalRecommendation(activeJournalRecommendation);
}
rpProtectionRecommendation.getSourceRecommendations().add(sourceRec);
_log.info("RP Placement : An RP source placement solution has been identified for the MetroPoint primary (active) cluster.");
// Find a solution, given this vpool, and the target varrays
if (findSolution(rpProtectionRecommendation, sourceRec, varray, vpool, activeProtectionVarrays, capabilities, satisfiedSourceVolCount, true, null, project)) {
_log.info("RP Placement : An RP target placement solution has been identified for the MetroPoint primary (active) cluster.");
// We have a primary cluster protection recommendation for the specified metroPointType. We need to now determine if
// we can protect the secondary cluster for the given metroPointType.
_log.info("RP Placement : Determining RP placement for the secondary (standby) MetroPoint cluster.");
secondaryRecommendationSolution = false;
// Get the candidate secondary cluster source pools - sets secondarySourcePoolURIs.
List<Recommendation> secondaryPoolsRecommendation = new ArrayList<Recommendation>();
if (isChangeVpool) {
secondaryPoolsRecommendation.add(changeVpoolStandbyRecommendation);
} else {
secondaryPoolsRecommendation = getRecommendedPools(rpProtectionRecommendation, haVarray, haVpool, null, null, capabilities, RPHelper.TARGET, null);
}
secondaryPlacementStatus.setSrcVArray(haVarray.getLabel());
secondaryPlacementStatus.setSrcVPool(haVpool.getLabel());
for (Recommendation secondaryPoolRecommendation : secondaryPoolsRecommendation) {
// Start with the top of the list of source pools, find a solution based on that.
StoragePool standbySourcePool = dbClient.queryObject(StoragePool.class, secondaryPoolRecommendation.getSourceStoragePool());
// Lookup source pool protection systems in the cache first.
if (standbyStoragePoolsToProtectionSystems.containsKey(standbySourcePool.getId())) {
secondaryProtectionSystems = standbyStoragePoolsToProtectionSystems.get(standbySourcePool.getId());
} else {
secondaryProtectionSystems = getProtectionSystemsForStoragePool(standbySourcePool, haVarray, true);
if (secondaryProtectionSystems.isEmpty()) {
continue;
}
// Cache the result for this pool
standbyStoragePoolsToProtectionSystems.put(standbySourcePool.getId(), secondaryProtectionSystems);
}
ProtectionSystem selectedSecondaryProtectionSystem = null;
// Ensure the we have a secondary protection system that matches the primary protection system
for (ProtectionSystem secondaryProtectionSystem : secondaryProtectionSystems) {
if (secondaryProtectionSystem.getId().equals(rpProtectionRecommendation.getProtectionDevice())) {
// We have a protection system match for this pool, continue.
selectedSecondaryProtectionSystem = secondaryProtectionSystem;
break;
}
}
if (selectedSecondaryProtectionSystem == null) {
// There is no protection system for this pool that matches the selected primary
// protection system. So lets try another pool.
_log.info(String.format("RP Placement: Secondary source storage pool %s " + " does not have connectivity to the selected primary protection system.", standbySourcePool.getLabel()));
continue;
} else {
// List of concatenated strings that contain the RP site + associated storage system.
List<String> secondaryAssociatedStorageSystems = getCandidateVisibleStorageSystems(standbySourcePool, selectedSecondaryProtectionSystem, haVarray, activeProtectionVarrays, true);
// make sure you check RP topology to see if the sites can protect that many targets
if (secondaryAssociatedStorageSystems.isEmpty()) {
// no rp site clusters connected to this storage system, should not hit this,
// but just to be safe we'll catch it
_log.info("RP Placement: Protection System " + selectedSecondaryProtectionSystem.getLabel() + " does not have an rp site cluster connected to Storage pool " + standbySourcePool.getLabel());
continue;
}
Set<String> validSecondaryAssociatedStorageSystems = new LinkedHashSet<String>();
// that reference the same storage system as the primary recommendation and has a different RP site.
for (String secondaryAssociatedStorageSystem : secondaryAssociatedStorageSystems) {
String secondarySourceInternalSiteName = ProtectionSystem.getAssociatedStorageSystemSiteName(secondaryAssociatedStorageSystem);
URI secondarySourceStorageSystemURI = ConnectivityUtil.findStorageSystemBySerialNumber(ProtectionSystem.getAssociatedStorageSystemSerialNumber(secondaryAssociatedStorageSystem), dbClient, StorageSystemType.BLOCK);
boolean validForStandbyPlacement = false;
if (secondarySourceStorageSystemURI.equals(primarySourceStorageSystemURI) && !secondarySourceInternalSiteName.equals(sourceRec.getInternalSiteName())) {
validForStandbyPlacement = true;
validSecondaryAssociatedStorageSystems.add(secondaryAssociatedStorageSystem);
}
_log.info(String.format("RP Placement: associated storage system entry [%s] " + "%s valid for standby placement.", secondaryAssociatedStorageSystem, (validForStandbyPlacement ? "" : "NOT")));
}
for (String secondaryAssociatedStorageSystem : validSecondaryAssociatedStorageSystems) {
_log.info(String.format("RP Placement : Build MetroPoint Standby Recommendation..."));
RPRecommendation secondaryRpRecommendation = buildSourceRecommendation(secondaryAssociatedStorageSystem, haVarray, haVpool, selectedSecondaryProtectionSystem, standbySourcePool, capabilities, satisfiedSourceVolCount, secondaryPlacementStatus, null, true);
if (secondaryRpRecommendation == null) {
// No standby placement found for the secondaryAssociatedStorageSystem, so continue.
_log.warn(String.format("RP Placement : Could not create MetroPoint Standby Recommendation using [%s], continuing...", secondaryAssociatedStorageSystem));
continue;
}
if (rpProtectionRecommendation.getStandbyJournalRecommendation() == null) {
_log.info(String.format("RP Placement : Build MetroPoint Standby Journal Recommendation..."));
RPRecommendation standbyJournalRecommendation = buildJournalRecommendation(rpProtectionRecommendation, secondaryRpRecommendation.getInternalSiteName(), vpool.getJournalSize(), standbyJournalVarray, standbyJournalVpool, primaryProtectionSystem, capabilities, totalRequestedResourceCount, vpoolChangeVolume, true);
if (standbyJournalRecommendation == null) {
// No standby journal placement found, so continue.
_log.warn(String.format("RP Placement : Could not create MetroPoint Standby Journal Recommendation, continuing..."));
continue;
}
rpProtectionRecommendation.setStandbyJournalRecommendation(standbyJournalRecommendation);
}
sourceRec.setHaRecommendation(secondaryRpRecommendation);
// Find a solution, given this vpool, and the target varrays
if (findSolution(rpProtectionRecommendation, secondaryRpRecommendation, haVarray, vpool, standbyProtectionVarrays, capabilities, satisfiedSourceVolCount, true, sourceRec, project)) {
_log.info("RP Placement : An RP target placement solution has been identified for the " + "MetroPoint secondary (standby) cluster.");
secondaryRecommendationSolution = true;
break;
} else {
_log.info("RP Placement : Unable to find a suitable solution, continuining to find other solutions.");
continue;
}
}
if (secondaryRecommendationSolution) {
break;
} else {
continue;
}
}
}
if (!secondaryRecommendationSolution) {
_log.info("RP Placement : Unable to find MetroPoint secondary cluster placement recommendation that " + "jives with primary cluster recommendation. Need to find a new primary recommendation.");
// Exhausted all the secondary pool URIs. Need to find another primary solution.
break;
}
// We are done - secondary recommendation found
requestedResourceCount = requestedResourceCount - satisfiedSourceVolCount;
totalSatisfiedCount += satisfiedSourceVolCount;
if (totalSatisfiedCount >= totalRequestedResourceCount) {
rpProtectionRecommendation.setResourceCount(totalSatisfiedCount);
// Check to ensure the protection system can handle the new resources about to come down
if (!verifyPlacement(primaryProtectionSystem, rpProtectionRecommendation, rpProtectionRecommendation.getResourceCount())) {
continue;
}
return rpProtectionRecommendation;
} else {
// loop back to the next pool
break;
}
} else {
// Not sure there's anything to do here. Just go to the next candidate protection system or Protection System
_log.info(String.format("RP Placement : Could not find a solution against protection system %s and internal " + "cluster name %s", primaryProtectionSystem.getLabel(), sourceRec.getInternalSiteName()));
rpProtectionRecommendation = getNewProtectionRecommendation(vpoolChangeVolume, vpool);
}
}
// end of for loop trying to find solution using possible rp cluster sites
rpProtectionRecommendation = getNewProtectionRecommendation(vpoolChangeVolume, vpool);
}
// end of protection systems for loop
}
// a solution
if ((remainingPossiblePrimarySrcPoolSolutions == 0) && totalSatisfiedCount < capabilities.getResourceCount()) {
_log.error("Could not find a MetroPoint placement solution. In a MetroPoint consistency group, there can " + "exist at most one remote copy and from zero to two local copies. If there is no remote copy, " + "there must be two local copies, one at each side of the VPLEX Metro.");
throw APIException.badRequests.cannotFindSolutionForRP(buildMetroProintPlacementStatusString());
}
_log.error("ViPR could not find matching target storage pools that could be protected via RecoverPoint");
_log.error("Could not find a MetroPoint placement solution. In a MetroPoint consistency group, there can " + "exist at most one remote copy and from zero to two local copies. If there is no remote copy, " + "there must be two local copies, one at each side of the VPLEX Metro.");
throw APIException.badRequests.cannotFindSolutionForRP(buildMetroProintPlacementStatusString());
}
Aggregations