use of com.emc.storageos.volumecontroller.Recommendation in project coprhd-controller by CoprHD.
the class PlacementTests method testVPlexLocalSRDFVPlexTargetBasicPlacement.
@Test
public void testVPlexLocalSRDFVPlexTargetBasicPlacement() {
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[] 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" };
// Create 2 Virtual Arrays
VirtualArray srcVarray = PlacementTestUtils.createVirtualArray(_dbClient, "srcVarray");
VirtualArray tgtVarray = PlacementTestUtils.createVirtualArray(_dbClient, "tgtVarray");
// Create 2 Networks
StringSet connVA = new StringSet();
connVA.add(srcVarray.getId().toString());
Network network1 = PlacementTestUtils.createNetwork(_dbClient, vmax1FE, "VSANSite1", "FC+BROCADE+FE", connVA);
network1.addEndpoints(Arrays.asList(vplex1FE), true);
network1.addEndpoints(Arrays.asList(vplex1BE), true);
connVA = new StringSet();
connVA.add(tgtVarray.getId().toString());
Network network2 = PlacementTestUtils.createNetwork(_dbClient, vmax2FE, "VSANSite2", "FC+CISCO+FE", connVA);
network2.addEndpoints(Arrays.asList(vplex2FE), true);
network2.addEndpoints(Arrays.asList(vplex2BE), true);
// Create 2 storage systems
StorageSystem[] storageSystems = PlacementTestUtils.createSRDFStorageSystems(_dbClient, "vmax1", network1, vmax1FE, srcVarray, "vmax2", network2, vmax2FE, tgtVarray);
StorageSystem storageSystem1 = storageSystems[1];
StorageSystem storageSystem2 = storageSystems[2];
StoragePool[] storagePools = PlacementTestUtils.createStoragePoolsForTwo(_dbClient, storageSystem1, srcVarray, storageSystem2, tgtVarray);
StorageSystem vplexSystem = PlacementTestUtils.createVPlexOneCluster(_dbClient, "vplex1", srcVarray, network1, network1, vplex1FE, vplex1BE);
StorageSystem vplexSystem2 = PlacementTestUtils.createVPlexOneCluster(_dbClient, "vplex2", tgtVarray, network2, network2, vplex2FE, vplex2BE);
// Create a target virtual pool
VirtualPool tgtVpool = new VirtualPool();
tgtVpool.setId(URI.create("tgtVpool"));
tgtVpool.setLabel("Target Vpool");
tgtVpool.setSupportedProvisioningType(VirtualPool.ProvisioningType.Thin.name());
tgtVpool.setDriveType(SupportedDriveTypes.FC.name());
StringSet matchedPools2 = new StringSet();
matchedPools2.add(storagePools[4].getId().toString());
matchedPools2.add(storagePools[5].getId().toString());
matchedPools2.add(storagePools[6].getId().toString());
tgtVpool.setMatchedStoragePools(matchedPools2);
tgtVpool.setUseMatchedPools(true);
StringSet virtualArrays2 = new StringSet();
virtualArrays2.add(tgtVarray.getId().toString());
tgtVpool.setVirtualArrays(virtualArrays2);
tgtVpool.setHighAvailability(VirtualPool.HighAvailabilityType.vplex_local.name());
_dbClient.createObject(tgtVpool);
// Make a remote copy protection setting
VpoolRemoteCopyProtectionSettings settings = new VpoolRemoteCopyProtectionSettings();
settings.setId(URI.create("remoteCopySettings"));
settings.setCopyMode(VpoolRemoteCopyProtectionSettings.CopyModes.ASYNCHRONOUS.name());
settings.setVirtualArray(tgtVarray.getId());
settings.setVirtualPool(tgtVpool.getId());
_dbClient.createObject(settings);
// Create an VPLEX Local/SRDF source virtual pool
VirtualPool srcVpool = new VirtualPool();
srcVpool.setId(URI.create("srcVpool"));
srcVpool.setLabel("Source Vpool");
srcVpool.setSupportedProvisioningType(VirtualPool.ProvisioningType.Thin.name());
srcVpool.setDriveType(SupportedDriveTypes.FC.name());
StringSet matchedPools1 = new StringSet();
matchedPools1.add(storagePools[1].getId().toString());
matchedPools1.add(storagePools[2].getId().toString());
matchedPools1.add(storagePools[3].getId().toString());
srcVpool.setMatchedStoragePools(matchedPools1);
srcVpool.setUseMatchedPools(true);
StringSet virtualArrays1 = new StringSet();
virtualArrays1.add(srcVarray.getId().toString());
srcVpool.setVirtualArrays(virtualArrays1);
StringMap remoteProtectionSettings = new StringMap();
remoteProtectionSettings.put(tgtVarray.getId().toString(), settings.getId().toString());
srcVpool.setProtectionRemoteCopySettings(remoteProtectionSettings);
srcVpool.setHighAvailability(VirtualPool.HighAvailabilityType.vplex_local.name());
_dbClient.createObject(srcVpool);
// 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("RDG1");
project.setTenantOrg(new NamedURI(tenant.getId(), project.getLabel()));
_dbClient.createObject(project);
// Create capabilities
VirtualPoolCapabilityValuesWrapper capabilities = PlacementTestUtils.createCapabilities("2GB", 1, null);
// 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++) {
Map<VpoolUse, List<Recommendation>> recommendationsMap = PlacementTestUtils.invokePlacementForVpool(_dbClient, _coordinator, srcVarray, project, srcVpool, capabilities);
List<Recommendation> recommendations = recommendationsMap.get(VpoolUse.ROOT);
assertNotNull(recommendations);
assertTrue(!recommendations.isEmpty());
assertNotNull(recommendations.get(0));
assert (recommendations.get(0) instanceof VPlexRecommendation);
VPlexRecommendation vplexRecommendation = (VPlexRecommendation) recommendations.get(0);
URI srcStoragePool = vplexRecommendation.getSourceStoragePool();
assert (srcStoragePool.equals(storagePools[1].getId()) || srcStoragePool.equals(storagePools[2].getId()));
assert (vplexRecommendation.getVPlexStorageSystem().equals(vplexSystem.getId()));
assert (vplexRecommendation.getRecommendation() instanceof SRDFRecommendation);
recommendations = recommendationsMap.get(VpoolUse.SRDF_COPY);
assertTrue(!recommendations.isEmpty());
assertNotNull(recommendations.get(0));
assert (recommendations.get(0) instanceof VPlexRecommendation);
VPlexRecommendation vplex2Recommendation = (VPlexRecommendation) recommendations.get(0);
URI tgtStoragePool = vplex2Recommendation.getSourceStoragePool();
assert (tgtStoragePool.equals(storagePools[4].getId()) || tgtStoragePool.equals(storagePools[5].getId()));
assert (vplex2Recommendation.getVPlexStorageSystem().equals(vplexSystem2.getId()));
assert (vplex2Recommendation.getRecommendation() instanceof SRDFCopyRecommendation);
;
}
}
use of com.emc.storageos.volumecontroller.Recommendation in project coprhd-controller by CoprHD.
the class PlacementTests method testVPlexLocalSRDFVPlexTargetAdvancedPlacement.
/**
* This tests that given multiple Vmax arrays capable of SRDF pairing, it will always
* choose those that are Vplex protected. Below vmax1 and vmax2 are on networks with Vplex;
* vmax3 and vmax4 are on different works in same varrays with no Vplex.
*/
@Test
public void testVPlexLocalSRDFVPlexTargetAdvancedPlacement() {
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[] vmax4FE = { "53:FE:FE:FE:FE:FE:FE:00", "53: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" };
// Create 2 Virtual Arrays
VirtualArray srcVarray = PlacementTestUtils.createVirtualArray(_dbClient, "srcVarray");
VirtualArray tgtVarray = PlacementTestUtils.createVirtualArray(_dbClient, "tgtVarray");
// Create 4 Networks
StringSet connVA = new StringSet();
connVA.add(srcVarray.getId().toString());
Network network1 = PlacementTestUtils.createNetwork(_dbClient, vmax1FE, "VSANSite1", "FC+BROCADE+FE", connVA);
connVA = new StringSet();
connVA.add(tgtVarray.getId().toString());
Network network2 = PlacementTestUtils.createNetwork(_dbClient, vmax2FE, "VSANSite2", "FC+CISCO+FE", connVA);
connVA = new StringSet();
connVA.add(srcVarray.getId().toString());
Network network3 = PlacementTestUtils.createNetwork(_dbClient, vmax3FE, "VSANSite1B", "FC+BROCADE+FEB", connVA);
connVA = new StringSet();
connVA.add(tgtVarray.getId().toString());
Network network4 = PlacementTestUtils.createNetwork(_dbClient, vmax4FE, "VSANSite2B", "FC+CISCO+FEB", connVA);
// Create 2 storage systems
StorageSystem[] storageSystems = PlacementTestUtils.createSRDFStorageSystems(_dbClient, "vmax1", network1, vmax1FE, srcVarray, "vmax2", network2, vmax2FE, tgtVarray);
StorageSystem storageSystem1 = storageSystems[1];
StorageSystem storageSystem2 = storageSystems[2];
StoragePool[] storagePools = PlacementTestUtils.createStoragePoolsForTwo(_dbClient, storageSystem1, srcVarray, storageSystem2, tgtVarray);
StorageSystem[] storageSystemsB = PlacementTestUtils.createSRDFStorageSystems(_dbClient, "vmax3", network3, vmax3FE, srcVarray, "vmax4", network4, vmax4FE, tgtVarray);
StorageSystem storageSystem3 = storageSystemsB[1];
StorageSystem storageSystem4 = storageSystemsB[2];
StoragePool[] storagePoolsB = PlacementTestUtils.createStoragePoolsForTwo(_dbClient, storageSystem3, srcVarray, storageSystem4, tgtVarray);
StorageSystem vplexSystem = PlacementTestUtils.createVPlexOneCluster(_dbClient, "vplex1", srcVarray, network1, network1, vplex1FE, vplex1BE);
StorageSystem vplexSystem2 = PlacementTestUtils.createVPlexOneCluster(_dbClient, "vplex2", tgtVarray, network2, network2, vplex2FE, vplex2BE);
// Create a target virtual pool
VirtualPool tgtVpool = new VirtualPool();
tgtVpool.setId(URI.create("tgtVpool"));
tgtVpool.setLabel("Target Vpool");
tgtVpool.setSupportedProvisioningType(VirtualPool.ProvisioningType.Thin.name());
tgtVpool.setDriveType(SupportedDriveTypes.FC.name());
tgtVpool.setUseMatchedPools(true);
StringSet virtualArrays2 = new StringSet();
virtualArrays2.add(tgtVarray.getId().toString());
tgtVpool.setVirtualArrays(virtualArrays2);
tgtVpool.setHighAvailability(VirtualPool.HighAvailabilityType.vplex_local.name());
List<StoragePool> targetStoragePools = new ArrayList<StoragePool>();
targetStoragePools.add(storagePools[4]);
targetStoragePools.add(storagePools[5]);
targetStoragePools.add(storagePools[6]);
targetStoragePools.add(storagePoolsB[4]);
targetStoragePools.add(storagePoolsB[5]);
targetStoragePools.add(storagePoolsB[6]);
StringSet matchedPools = PlacementTestUtils.runVPlexHighAvailabilityMatcher(_dbClient, tgtVpool, targetStoragePools);
assert (matchedPools.size() == 3);
tgtVpool.setMatchedStoragePools(matchedPools);
_dbClient.createObject(tgtVpool);
// Make a remote copy protection setting
VpoolRemoteCopyProtectionSettings settings = new VpoolRemoteCopyProtectionSettings();
settings.setId(URI.create("remoteCopySettings"));
settings.setCopyMode(VpoolRemoteCopyProtectionSettings.CopyModes.ASYNCHRONOUS.name());
settings.setVirtualArray(tgtVarray.getId());
settings.setVirtualPool(tgtVpool.getId());
_dbClient.createObject(settings);
// Create an VPLEX Local/SRDF source virtual pool
VirtualPool srcVpool = new VirtualPool();
srcVpool.setId(URI.create("srcVpool"));
srcVpool.setLabel("Source Vpool");
srcVpool.setSupportedProvisioningType(VirtualPool.ProvisioningType.Thin.name());
srcVpool.setDriveType(SupportedDriveTypes.FC.name());
srcVpool.setUseMatchedPools(true);
StringSet virtualArrays1 = new StringSet();
virtualArrays1.add(srcVarray.getId().toString());
srcVpool.setVirtualArrays(virtualArrays1);
StringMap remoteProtectionSettings = new StringMap();
remoteProtectionSettings.put(tgtVarray.getId().toString(), settings.getId().toString());
srcVpool.setProtectionRemoteCopySettings(remoteProtectionSettings);
srcVpool.setHighAvailability(VirtualPool.HighAvailabilityType.vplex_local.name());
List<StoragePool> sourceStoragePools = new ArrayList<StoragePool>();
sourceStoragePools.add(storagePools[1]);
sourceStoragePools.add(storagePools[2]);
sourceStoragePools.add(storagePools[3]);
sourceStoragePools.add(storagePoolsB[1]);
sourceStoragePools.add(storagePoolsB[2]);
sourceStoragePools.add(storagePoolsB[3]);
matchedPools = PlacementTestUtils.runVPlexHighAvailabilityMatcher(_dbClient, srcVpool, sourceStoragePools);
assert (matchedPools.size() == 3);
srcVpool.setMatchedStoragePools(matchedPools);
_dbClient.createObject(srcVpool);
// 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("RDG1");
project.setTenantOrg(new NamedURI(tenant.getId(), project.getLabel()));
_dbClient.createObject(project);
// Create capabilities
VirtualPoolCapabilityValuesWrapper capabilities = PlacementTestUtils.createCapabilities("2GB", 1, null);
// 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++) {
Map<VpoolUse, List<Recommendation>> recommendationsMap = PlacementTestUtils.invokePlacementForVpool(_dbClient, _coordinator, srcVarray, project, srcVpool, capabilities);
List<Recommendation> recommendations = recommendationsMap.get(VpoolUse.ROOT);
assertNotNull(recommendations);
assertTrue(!recommendations.isEmpty());
assertNotNull(recommendations.get(0));
assert (recommendations.get(0) instanceof VPlexRecommendation);
VPlexRecommendation vplexRecommendation = (VPlexRecommendation) recommendations.get(0);
URI srcStoragePool = vplexRecommendation.getSourceStoragePool();
assert (srcStoragePool.equals(storagePools[1].getId()) || srcStoragePool.equals(storagePools[2].getId()));
assert (vplexRecommendation.getVPlexStorageSystem().equals(vplexSystem.getId()));
assert (vplexRecommendation.getRecommendation() instanceof SRDFRecommendation);
recommendations = recommendationsMap.get(VpoolUse.SRDF_COPY);
assertTrue(!recommendations.isEmpty());
assertNotNull(recommendations.get(0));
assert (recommendations.get(0) instanceof VPlexRecommendation);
VPlexRecommendation vplex2Recommendation = (VPlexRecommendation) recommendations.get(0);
URI tgtStoragePool = vplex2Recommendation.getSourceStoragePool();
assert (tgtStoragePool.equals(storagePools[4].getId()) || tgtStoragePool.equals(storagePools[5].getId()));
assert (vplex2Recommendation.getVPlexStorageSystem().equals(vplexSystem2.getId()));
assert (vplex2Recommendation.getRecommendation() instanceof SRDFCopyRecommendation);
;
}
}
use of com.emc.storageos.volumecontroller.Recommendation in project coprhd-controller by CoprHD.
the class PlacementTests method testSRDFBasicPlacement.
@Test
public void testSRDFBasicPlacement() {
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" };
// Create 2 Virtual Arrays
VirtualArray srcVarray = PlacementTestUtils.createVirtualArray(_dbClient, "srcVarray");
VirtualArray tgtVarray = PlacementTestUtils.createVirtualArray(_dbClient, "tgtVarray");
// Create 2 Networks
StringSet connVA = new StringSet();
connVA.add(srcVarray.getId().toString());
Network network1 = PlacementTestUtils.createNetwork(_dbClient, vmax1FE, "VSANSite1", "FC+BROCADE+FE", connVA);
connVA = new StringSet();
connVA.add(tgtVarray.getId().toString());
Network network2 = PlacementTestUtils.createNetwork(_dbClient, vmax2FE, "VSANSite2", "FC+CISCO+FE", connVA);
// Create 2 storage systems
StorageSystem[] storageSystems = PlacementTestUtils.createSRDFStorageSystems(_dbClient, "vmax1", network1, vmax1FE, srcVarray, "vmax2", network2, vmax2FE, tgtVarray);
StorageSystem storageSystem1 = storageSystems[1];
StorageSystem storageSystem2 = storageSystems[2];
StoragePool[] storagePools = PlacementTestUtils.createStoragePoolsForTwo(_dbClient, storageSystem1, srcVarray, storageSystem2, tgtVarray);
// Create a target virtual pool
VirtualPool tgtVpool = new VirtualPool();
tgtVpool.setId(URI.create("tgtVpool"));
tgtVpool.setLabel("Target Vpool");
tgtVpool.setSupportedProvisioningType(VirtualPool.ProvisioningType.Thin.name());
tgtVpool.setDriveType(SupportedDriveTypes.FC.name());
StringSet matchedPools2 = new StringSet();
matchedPools2.add(storagePools[4].getId().toString());
matchedPools2.add(storagePools[5].getId().toString());
matchedPools2.add(storagePools[6].getId().toString());
tgtVpool.setMatchedStoragePools(matchedPools2);
tgtVpool.setUseMatchedPools(true);
StringSet virtualArrays2 = new StringSet();
virtualArrays2.add(tgtVarray.getId().toString());
tgtVpool.setVirtualArrays(virtualArrays2);
_dbClient.createObject(tgtVpool);
// Make a remote copy protection setting
VpoolRemoteCopyProtectionSettings settings = new VpoolRemoteCopyProtectionSettings();
settings.setId(URI.create("remoteCopySettings"));
settings.setCopyMode(VpoolRemoteCopyProtectionSettings.CopyModes.ASYNCHRONOUS.name());
settings.setVirtualArray(tgtVarray.getId());
settings.setVirtualPool(tgtVpool.getId());
_dbClient.createObject(settings);
// Create an SRDF source virtual pool
VirtualPool srcVpool = new VirtualPool();
srcVpool.setId(URI.create("srcVpool"));
srcVpool.setLabel("Source Vpool");
srcVpool.setSupportedProvisioningType(VirtualPool.ProvisioningType.Thin.name());
srcVpool.setDriveType(SupportedDriveTypes.FC.name());
StringSet matchedPools1 = new StringSet();
matchedPools1.add(storagePools[1].getId().toString());
matchedPools1.add(storagePools[2].getId().toString());
matchedPools1.add(storagePools[3].getId().toString());
srcVpool.setMatchedStoragePools(matchedPools1);
srcVpool.setUseMatchedPools(true);
StringSet virtualArrays1 = new StringSet();
virtualArrays1.add(srcVarray.getId().toString());
srcVpool.setVirtualArrays(virtualArrays1);
StringMap remoteProtectionSettings = new StringMap();
remoteProtectionSettings.put(tgtVarray.getId().toString(), settings.getId().toString());
srcVpool.setProtectionRemoteCopySettings(remoteProtectionSettings);
_dbClient.createObject(srcVpool);
// 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("RDG1");
project.setTenantOrg(new NamedURI(tenant.getId(), project.getLabel()));
_dbClient.createObject(project);
// Create capabilities
VirtualPoolCapabilityValuesWrapper capabilities = PlacementTestUtils.createCapabilities("2GB", 1, null);
// 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++) {
Map<VpoolUse, List<Recommendation>> recommendationsMap = PlacementTestUtils.invokePlacementForVpool(_dbClient, _coordinator, srcVarray, project, srcVpool, capabilities);
List<Recommendation> recommendations = recommendationsMap.get(VpoolUse.ROOT);
assertNotNull(recommendations);
assertTrue(!recommendations.isEmpty());
assertNotNull(recommendations.get(0));
assert (recommendations.get(0) instanceof SRDFRecommendation);
SRDFRecommendation srdfRecommendation = (SRDFRecommendation) recommendations.get(0);
URI srcStoragePool = srdfRecommendation.getSourceStoragePool();
assert (srcStoragePool.equals(storagePools[1].getId()) || srcStoragePool.equals(storagePools[2].getId()));
recommendations = recommendationsMap.get(VpoolUse.SRDF_COPY);
assertTrue(!recommendations.isEmpty());
assertNotNull(recommendations.get(0));
assert (recommendations.get(0) instanceof SRDFCopyRecommendation);
SRDFCopyRecommendation srdfCopyRecommendation = (SRDFCopyRecommendation) recommendations.get(0);
URI tgtStoragePool = srdfCopyRecommendation.getSourceStoragePool();
assert (tgtStoragePool.equals(storagePools[4].getId()) || tgtStoragePool.equals(storagePools[5].getId()));
}
}
use of com.emc.storageos.volumecontroller.Recommendation in project coprhd-controller by CoprHD.
the class VPlexBlockServiceApiImpl method upgradeToDistributed.
/**
* Upgrade a local VPLEX volume to a distributed VPLEX volume.
*
* @param vplexURI -- VPLEX System URI
* @param vplexVolume -- VPlex volume (existing).
* @param vpool -- Requested vpool.
* @param taskId
* @throws InternalException
*/
private void upgradeToDistributed(URI vplexURI, Volume vplexVolume, VirtualPool vpool, String transferSpeed, String taskId) throws InternalException {
try {
VirtualArray neighborhood = _dbClient.queryObject(VirtualArray.class, vplexVolume.getVirtualArray());
Set<URI> vplexes = new HashSet<URI>();
vplexes.add(vplexURI);
if (null == vplexVolume.getAssociatedVolumes() || vplexVolume.getAssociatedVolumes().isEmpty()) {
s_logger.error("VPLEX volume {} has no backend volumes.", vplexVolume.forDisplay());
throw InternalServerErrorException.internalServerErrors.noAssociatedVolumesForVPLEXVolume(vplexVolume.forDisplay());
}
Iterator<String> assocIter = vplexVolume.getAssociatedVolumes().iterator();
URI existingVolumeURI = new URI(assocIter.next());
Volume existingVolume = _dbClient.queryObject(Volume.class, existingVolumeURI);
if (existingVolume == null || existingVolume.getInactive() == true) {
throw new ServiceCodeException(ServiceCode.UNFORSEEN_ERROR, "Existing volume inactive", new Object[] {});
}
VirtualPoolCapabilityValuesWrapper cosCapabilities = new VirtualPoolCapabilityValuesWrapper();
cosCapabilities.put(VirtualPoolCapabilityValuesWrapper.SIZE, getVolumeCapacity(existingVolume));
cosCapabilities.put(VirtualPoolCapabilityValuesWrapper.RESOURCE_COUNT, new Integer(1));
cosCapabilities.put(VirtualPoolCapabilityValuesWrapper.THIN_PROVISIONING, existingVolume.getThinlyProvisioned());
// Get a recommendation.
// Then create the volume.
List<VolumeDescriptor> descriptors = new ArrayList<VolumeDescriptor>();
Volume createVolume = null;
// Determine if the user requested a specific HA VirtualArray and an associated HA VirtualPool.
VirtualArray requestedHaVarray = null;
VirtualPool requestedHaVirtualPool = vpool;
if (vpool.getHaVarrayVpoolMap() != null && !vpool.getHaVarrayVpoolMap().isEmpty()) {
for (String haNH : vpool.getHaVarrayVpoolMap().keySet()) {
if (haNH.equals(NullColumnValueGetter.getNullURI().toString())) {
continue;
}
requestedHaVarray = _dbClient.queryObject(VirtualArray.class, new URI(haNH));
String haVirtualPool = vpool.getHaVarrayVpoolMap().get(haNH);
if (haVirtualPool.equals(NullColumnValueGetter.getNullURI().toString())) {
continue;
}
requestedHaVirtualPool = _dbClient.queryObject(VirtualPool.class, new URI(haVirtualPool));
break;
}
}
// Get the recommendations and pick one.
List<Recommendation> recommendations = getBlockScheduler().scheduleStorageForImport(neighborhood, vplexes, requestedHaVarray, requestedHaVirtualPool, cosCapabilities);
if (recommendations.isEmpty()) {
throw APIException.badRequests.noStorageFoundForVolumeMigration(requestedHaVirtualPool.getLabel(), requestedHaVarray.getLabel(), existingVolume.getId());
}
Recommendation recommendation = recommendations.get(0);
VPlexRecommendation vplexRecommendation = (VPlexRecommendation) recommendation;
if (false == vplexURI.equals(vplexRecommendation.getVPlexStorageSystem())) {
APIException.badRequests.vplexPlacementError(vplexVolume.getId());
}
StorageSystem vplexSystem = _dbClient.queryObject(StorageSystem.class, vplexURI);
Project vplexProject = getVplexProject(vplexSystem, _dbClient, _tenantsService);
// Prepare the created volume.
VirtualArray haVirtualArray = _dbClient.queryObject(VirtualArray.class, vplexRecommendation.getVirtualArray());
createVolume = prepareVolumeForRequest(getVolumeCapacity(existingVolume), vplexProject, haVirtualArray, requestedHaVirtualPool, vplexRecommendation.getSourceStorageSystem(), vplexRecommendation.getSourceStoragePool(), vplexVolume.getLabel() + "-1", ResourceOperationTypeEnum.CREATE_BLOCK_VOLUME, taskId, _dbClient);
createVolume.addInternalFlags(Flag.INTERNAL_OBJECT);
_dbClient.updateObject(createVolume);
VolumeDescriptor desc = new VolumeDescriptor(VolumeDescriptor.Type.BLOCK_DATA, createVolume.getStorageController(), createVolume.getId(), createVolume.getPool(), cosCapabilities);
descriptors.add(desc);
// Add a descriptor for the VPlex Virtual Volume.
desc = new VolumeDescriptor(VolumeDescriptor.Type.VPLEX_VIRT_VOLUME, vplexVolume.getStorageController(), vplexVolume.getId(), vplexVolume.getPool(), cosCapabilities);
descriptors.add(desc);
// Now send the command to the controller.
try {
s_logger.info("Calling VPlex controller.");
VPlexController controller = getController();
controller.importVolume(vplexURI, descriptors, null, null, vpool.getId(), null, transferSpeed, Boolean.TRUE, taskId);
// controller.importVolume(vplexURI, vpool.getId(),
// null, null, /* no need to pass System Project/Tenant */
// null, /* no import volume */
// createVolume.getId(), vplexVolume.getId(), taskId);
} catch (InternalException ex) {
s_logger.error("ControllerException on upgradeToDistributed", ex);
String errMsg = String.format("ControllerException: %s", ex.getMessage());
Operation statusUpdate = new Operation(Operation.Status.error.name(), errMsg);
_dbClient.updateTaskOpStatus(Volume.class, vplexVolume.getId(), taskId, statusUpdate);
throw ex;
}
} catch (URISyntaxException ex) {
s_logger.debug("URISyntaxException", ex);
}
}
use of com.emc.storageos.volumecontroller.Recommendation in project coprhd-controller by CoprHD.
the class VPlexBlockServiceApiImpl method startNativeContinuousCopies.
/**
* {@inheritDoc}
*/
@Override
public TaskList startNativeContinuousCopies(StorageSystem vplexStorageSystem, Volume vplexVolume, VirtualPool sourceVirtualPool, VirtualPoolCapabilityValuesWrapper capabilities, NativeContinuousCopyCreate param, String taskId) throws ControllerException {
// using the target volume of a block snapshot.
if (VPlexUtil.isVolumeBuiltOnBlockSnapshot(_dbClient, vplexVolume)) {
throw APIException.badRequests.mirrorNotAllowedVolumeIsExposedSnapshot(vplexVolume.getId().toString());
}
validateNotAConsistencyGroupVolume(vplexVolume, sourceVirtualPool);
TaskList taskList = new TaskList();
// Currently, For Vplex Local Volume this will create a single mirror and add it
// to the vplex volume. For Vplex Distributed Volume this will create single mirror
// on source and/or HA side and add it to the vplex volume. Two steps: first place
// the mirror and then prepare the mirror.
URI vplexStorageSystemURI = vplexVolume.getStorageController();
// For VPLEX Local volume there will be only one associated volume entry in this set.
StringSet associatedVolumeIds = vplexVolume.getAssociatedVolumes();
if (associatedVolumeIds == null) {
throw InternalServerErrorException.internalServerErrors.noAssociatedVolumesForVPLEXVolume(vplexVolume.forDisplay());
}
VirtualPool sourceMirrorVPool = null;
// Set source mirror vpool
if (!isNullOrEmpty(sourceVirtualPool.getMirrorVirtualPool()) && !NullColumnValueGetter.isNullURI(URI.create(sourceVirtualPool.getMirrorVirtualPool()))) {
sourceMirrorVPool = _dbClient.queryObject(VirtualPool.class, URI.create(sourceVirtualPool.getMirrorVirtualPool()));
}
// Check if volume is distributed and if HA Mirror Vpool is also set
VirtualPool haMirrorVPool = VPlexUtil.getHAMirrorVpool(sourceVirtualPool, associatedVolumeIds, _dbClient);
// Map of backend volume and the mirror pool to target backend volume for the mirror
Map<Volume, VirtualPool> backendVolumeToMirrorVpoolMap = new HashMap<Volume, VirtualPool>();
if (associatedVolumeIds.size() > 1) {
// If associatedVolumeIds size is greater than 1 then its a VPLEX Distributed Volume
updateBackendVolumeToMirrorVpoolMap(vplexVolume, associatedVolumeIds, sourceVirtualPool, sourceMirrorVPool, haMirrorVPool, backendVolumeToMirrorVpoolMap);
} else {
// If we are here that means we need to create mirror for the VPLEX local volume
for (String associatedVolumeId : associatedVolumeIds) {
Volume associatedVolume = _dbClient.queryObject(Volume.class, URI.create(associatedVolumeId));
if (associatedVolume != null) {
backendVolumeToMirrorVpoolMap.put(associatedVolume, sourceMirrorVPool);
}
}
}
// Project is not passed in continuous copies call.
// Implicit assumption to use same project as the source volume.
Project project = _permissionsHelper.getObjectById(vplexVolume.getProject(), Project.class);
Map<Volume, List<Recommendation>> backendvolumeToMirrorRecommendationMap = new HashMap<Volume, List<Recommendation>>();
Map<Volume, VirtualArray> backendvolumeToMirrorVarrayMap = new HashMap<Volume, VirtualArray>();
for (Volume backendVolume : backendVolumeToMirrorVpoolMap.keySet()) {
URI backendVolumeVarrayURI = backendVolume.getVirtualArray();
// Get the VPLEX cluster value from the varray
String cluster = ConnectivityUtil.getVplexClusterForVarray(backendVolumeVarrayURI, vplexStorageSystemURI, _dbClient);
if (cluster.equals(ConnectivityUtil.CLUSTER_UNKNOWN)) {
throw InternalServerErrorException.internalServerErrors.noVplexClusterInfoForVarray(backendVolumeVarrayURI.toString(), vplexStorageSystemURI.toString());
}
VirtualPool backendVolumeVpool = _dbClient.queryObject(VirtualPool.class, backendVolume.getVirtualPool());
VirtualPool mirrorVpool = backendVolumeToMirrorVpoolMap.get(backendVolume);
// Get recommendations for the mirror placement
List<Recommendation> volumeRecommendations = null;
VirtualArray varray = null;
if (mirrorVpool != null) {
// If mirror vpool is provided try to get recommendations using the provided mirror vpool
// Check if any of the varray for mirror vpool is same as that of the source volume varray.
// If yes then get recommendations using that varray.
StringSet mirrorVPoolVarrays = mirrorVpool.getVirtualArrays();
boolean foundMatch = false;
for (String mirrorVPoolVarrayId : mirrorVPoolVarrays) {
if (mirrorVPoolVarrayId.equals(backendVolumeVarrayURI.toString())) {
varray = _dbClient.queryObject(VirtualArray.class, backendVolumeVarrayURI);
volumeRecommendations = _scheduler.getRecommendationsForMirrors(varray, project, backendVolumeVpool, mirrorVpool, capabilities, vplexStorageSystemURI, backendVolume.getStorageController(), cluster);
foundMatch = true;
break;
}
}
if (!foundMatch) {
s_logger.info("Mirror Vpool varray is different than the source vpool varray");
// with the source volume VPLEX system.
for (String mirrorVPoolVarrayId : mirrorVPoolVarrays) {
if (VPlexUtil.checkIfVarrayContainsSpecifiedVplexSystem(mirrorVPoolVarrayId, cluster, vplexStorageSystemURI, _dbClient)) {
varray = _dbClient.queryObject(VirtualArray.class, URI.create(mirrorVPoolVarrayId));
volumeRecommendations = _scheduler.getRecommendationsForMirrors(varray, project, backendVolumeVpool, mirrorVpool, capabilities, vplexStorageSystemURI, backendVolume.getStorageController(), cluster);
if (!volumeRecommendations.isEmpty()) {
foundMatch = true;
break;
} else {
s_logger.info("Tried to get recommemdations using varray {} {}. ", varray.getId(), varray.getLabel());
}
}
}
}
} else {
if (sourceVirtualPool.getHighAvailability().equals(VirtualPool.HighAvailabilityType.vplex_local.name())) {
s_logger.info("Mirror vpool is not specified, use the source volume virtual pool and virtual array");
// In case of Vplex local if mirror pool is not provided then we can use source vpool as mirror vpool.
sourceMirrorVPool = backendVolumeVpool;
mirrorVpool = backendVolumeVpool;
backendVolumeToMirrorVpoolMap.put(backendVolume, sourceMirrorVPool);
// Separate Mirror vpool is not provided so use the source volume vpool and varray for
// getting recommendations.Here sourceVirtualPool and mirrorVPool will be same.
varray = _dbClient.queryObject(VirtualArray.class, backendVolumeVarrayURI);
volumeRecommendations = _scheduler.getRecommendationsForMirrors(varray, project, backendVolumeVpool, mirrorVpool, capabilities, vplexStorageSystemURI, backendVolume.getStorageController(), cluster);
}
}
if (mirrorVpool == null) {
throw APIException.badRequests.noMirrorVpoolForVplexVolume(vplexVolume.getLabel());
}
if (varray == null) {
throw APIException.badRequests.noVarrayForMirrorVpoolWithExpectedVplex(mirrorVpool.getLabel(), vplexStorageSystem.getLabel(), cluster);
}
if (volumeRecommendations == null || volumeRecommendations.isEmpty()) {
if (volumeRecommendations.isEmpty()) {
StorageSystem storageSystem = _dbClient.queryObject(StorageSystem.class, backendVolume.getStorageController());
throw APIException.badRequests.noMatchingStoragePoolsForContinuousCopiesVpoolForVplex(varray.getLabel(), sourceMirrorVPool.getLabel(), storageSystem.getLabel());
}
}
// Add mirror recommendations for the backend volume to the map
backendvolumeToMirrorRecommendationMap.put(backendVolume, volumeRecommendations);
backendvolumeToMirrorVarrayMap.put(backendVolume, varray);
}
// Prepare mirror.
int varrayCount = 0;
int volumeCounter = 1;
// volumeCount will be always 1 for now
int volumeCount = capabilities.getResourceCount();
String volumeLabel = param.getName();
List<URI> allVolumes = new ArrayList<URI>();
List<URI> allMirrors = new ArrayList<URI>();
List<VolumeDescriptor> descriptors = new ArrayList<VolumeDescriptor>();
// Currently only one local mirror is supported for the VPLEX local virtual volume
List<VplexMirror> preparedMirrors = new ArrayList<VplexMirror>();
for (Volume backendVolume : backendvolumeToMirrorRecommendationMap.keySet()) {
List<Recommendation> volumeRecommendations = backendvolumeToMirrorRecommendationMap.get(backendVolume);
VirtualArray varray = backendvolumeToMirrorVarrayMap.get(backendVolume);
VirtualPool mirrorVpool = backendVolumeToMirrorVpoolMap.get(backendVolume);
long thinVolumePreAllocationSize = 0;
if (null != mirrorVpool.getThinVolumePreAllocationPercentage()) {
thinVolumePreAllocationSize = VirtualPoolUtil.getThinVolumePreAllocationSize(mirrorVpool.getThinVolumePreAllocationPercentage(), vplexVolume.getCapacity());
}
for (Recommendation volumeRecommendation : volumeRecommendations) {
VPlexRecommendation vplexRecommendation = (VPlexRecommendation) volumeRecommendation;
StringBuilder mirrorLabelBuilder = new StringBuilder(volumeLabel);
if (backendVolume.getVirtualArray().equals(vplexVolume.getVirtualArray())) {
varrayCount = 0;
} else {
varrayCount = 1;
}
mirrorLabelBuilder.append('-').append(varrayCount);
if (volumeCount > 1) {
mirrorLabelBuilder.append('-').append(volumeCounter++);
}
// Create mirror object
VplexMirror createdMirror = initializeMirror(vplexVolume, mirrorVpool, varray, mirrorLabelBuilder.toString(), thinVolumePreAllocationSize, _dbClient);
preparedMirrors.add(createdMirror);
Operation op = _dbClient.createTaskOpStatus(VplexMirror.class, createdMirror.getId(), taskId, ResourceOperationTypeEnum.ATTACH_VPLEX_LOCAL_MIRROR);
s_logger.info("Prepared mirror {}", createdMirror.getId());
allMirrors.add(createdMirror.getId());
// Add descriptor for the mirror.
VolumeDescriptor descriptor = new VolumeDescriptor(VolumeDescriptor.Type.VPLEX_LOCAL_MIRROR, vplexStorageSystemURI, createdMirror.getId(), null, capabilities);
descriptors.add(descriptor);
// Create backend volume object and add it to the VplexMirror created above.
Volume volume = prepareVolume(createdMirror, backendVolume, mirrorVpool, varray, vplexRecommendation.getSourceStorageSystem(), vplexRecommendation.getSourceStoragePool(), mirrorLabelBuilder.toString(), thinVolumePreAllocationSize, capabilities, _dbClient);
op = new Operation();
op.setResourceType(ResourceOperationTypeEnum.CREATE_BLOCK_VOLUME);
_dbClient.createTaskOpStatus(Volume.class, volume.getId(), taskId, op);
URI volumeId = volume.getId();
allVolumes.add(volumeId);
s_logger.info("Prepared volume {}", volumeId);
// Add descriptor for the backend volume
descriptor = new VolumeDescriptor(VolumeDescriptor.Type.BLOCK_DATA, vplexRecommendation.getSourceStorageSystem(), volumeId, vplexRecommendation.getSourceStoragePool(), capabilities);
descriptors.add(descriptor);
}
}
Collection<URI> mirrorTargetIds = Collections2.transform(preparedMirrors, FCTN_VPLEX_MIRROR_TO_URI);
String mirrorTargetCommaDelimList = Joiner.on(',').join(mirrorTargetIds);
Operation op = _dbClient.createTaskOpStatus(Volume.class, vplexVolume.getId(), taskId, ResourceOperationTypeEnum.ATTACH_VPLEX_LOCAL_MIRROR, mirrorTargetCommaDelimList);
taskList.getTaskList().add(toTask(vplexVolume, preparedMirrors, taskId, op));
try {
VPlexController controller = getController();
controller.attachContinuousCopies(vplexStorageSystem.getId(), descriptors, vplexVolume.getId(), taskId);
} catch (InternalException e) {
if (s_logger.isErrorEnabled()) {
s_logger.error("Controller error", e);
}
String errMsg = String.format("Controller error: %s", e.getMessage());
for (URI volumeURI : allVolumes) {
_dbClient.error(Volume.class, volumeURI, taskId, e);
}
for (URI mirrorURI : allMirrors) {
_dbClient.error(VplexMirror.class, mirrorURI, taskId, e);
}
for (TaskResourceRep volumeTask : taskList.getTaskList()) {
volumeTask.setState(Operation.Status.error.name());
volumeTask.setMessage(errMsg);
}
throw e;
}
return taskList;
}
Aggregations