use of com.emc.storageos.volumecontroller.VPlexRecommendation in project coprhd-controller by CoprHD.
the class VPlexBlockServiceApiImpl method validateVolumeLabels.
/**
* Convenient method to generate volume labels and check for duplicate. If there is a duplicate, throw exception
*
* @param baseVolumeLabel
* - volume prefix
* @param project
* - project volume creates within
* @param vArray
* - virtual array where volume is create
* @param vPool
* - volume's vpool
* @param vPoolCapabilities
* - vpool capabilities
* @param varrayRecomendationsMap
* - map of virtual array to its list of recommendation
*/
private void validateVolumeLabels(String baseVolumeLabel, Project project, VirtualPoolCapabilityValuesWrapper vPoolCapabilities, Map<String, List<VPlexRecommendation>> varrayRecomendationsMap) {
int varrayCount = 0;
Iterator<String> varrayIter = varrayRecomendationsMap.keySet().iterator();
while (varrayIter.hasNext()) {
String varrayId = varrayIter.next();
s_logger.info("Processing recommendations for virtual array {}", varrayId);
int volumeCounter = 0;
// Sum the resource counts from all recommendations.
int totalResourceCount = 0;
for (VPlexRecommendation recommendation : varrayRecomendationsMap.get(varrayId)) {
totalResourceCount += recommendation.getResourceCount();
}
Iterator<VPlexRecommendation> recommendationsIter = varrayRecomendationsMap.get(varrayId).iterator();
while (recommendationsIter.hasNext()) {
VPlexRecommendation recommendation = recommendationsIter.next();
URI storagePoolURI = recommendation.getSourceStoragePool();
VirtualPool volumeVpool = recommendation.getVirtualPool();
s_logger.info("Volume virtual pool is {}", volumeVpool.getId().toString());
vPoolCapabilities.put(VirtualPoolCapabilityValuesWrapper.AUTO_TIER__POLICY_NAME, volumeVpool.getAutoTierPolicyName());
s_logger.info("Recommendation is for {} resources in pool {}", recommendation.getResourceCount(), storagePoolURI.toString());
for (int i = 0; i < recommendation.getResourceCount(); i++) {
// Each volume has a unique label based off the passed
// value. Note that the way the storage system creates
// the actual volumes in a multi volume request, the
// names given the Bourne volumes here likely will not
// match the names given by the storage system. If desired,
// we will need to update the actual volumes after they
// are created to match the names given here. Currently,
// this is not implemented.
String volumeLabel = generateVolumeLabel(baseVolumeLabel, varrayCount, volumeCounter, totalResourceCount);
// throw exception of duplicate found
validateVolumeLabel(volumeLabel, project);
s_logger.info("Volume label is {}", volumeLabel);
volumeCounter++;
}
}
varrayCount++;
}
}
use of com.emc.storageos.volumecontroller.VPlexRecommendation in project coprhd-controller by CoprHD.
the class VPlexBlockServiceApiImpl method createVPlexVolumeDescriptors.
/**
* Create the necessary volume descriptors for Vplex volumes, including the backend
* volume descriptors and the virtual volume descriptors.
*
* @param param
* - the VolumeCreate parameters
* @param project
* -- user's project
* @param vArray
* -- virtual array volumes are created in
* @param vPool
* -- virtual pool (ROOT) used to create the volumes
* @param recommendations
* -- recommendations received from placement
* @param task
* -- a task identifier
* @param vPoolCapabilities
* - VirtualPoolCapabilitiesWrapper
* @param blockConsistencyGroupURI
* - the block consistency group URI
* @param taskList
* - OUTPUT list of tasks created
* @param allVolumes
* - OUTPUT - list of volumes created
* @param createTask
* -- boolean flag indicating to create tasks
* @return
*/
public List<VolumeDescriptor> createVPlexVolumeDescriptors(VolumeCreate param, Project project, final VirtualArray vArray, final VirtualPool vPool, List<Recommendation> recommendations, String task, VirtualPoolCapabilityValuesWrapper vPoolCapabilities, URI blockConsistencyGroupURI, TaskList taskList, List<URI> allVolumes, boolean createTask) {
s_logger.info("Request to create {} VPlex virtual volume(s)", vPoolCapabilities.getResourceCount());
// Determine if we're processing an SRDF copy so we can set appropriate name.
boolean srdfCopy = false;
if (recommendations.get(0).getRecommendation() != null && recommendations.get(0).getRecommendation() instanceof SRDFCopyRecommendation) {
srdfCopy = true;
}
// Sort the recommendations by VirtualArray. There can be up to two
// VirtualArrays, the requested VirtualArray and the HA VirtualArray
// either passed or determined by the placement when HA virtual volumes
// are being created. We also set the VPlex storage system, which
// should be the same for all recommendations.
URI vplexStorageSystemURI = null;
URI[] vplexSystemURIOut = new URI[1];
Map<String, List<VPlexRecommendation>> varrayRecommendationsMap = sortRecommendationsByVarray(recommendations, vplexSystemURIOut);
vplexStorageSystemURI = vplexSystemURIOut[0];
// for the srdf copies, since they are already pre-created.
if (!srdfCopy) {
validateVolumeLabels(param.getName(), project, vPoolCapabilities, varrayRecommendationsMap);
}
// Determine the project to be used for the VPlex's artifacts
StorageSystem vplexStorageSystem = _dbClient.queryObject(StorageSystem.class, vplexStorageSystemURI);
Project vplexProject = getVplexProject(vplexStorageSystem, _dbClient, _tenantsService);
// The volume size.
long size = SizeUtil.translateSize(param.getSize());
// The consistency group or null when not specified.
final BlockConsistencyGroup consistencyGroup = blockConsistencyGroupURI == null ? null : _dbClient.queryObject(BlockConsistencyGroup.class, blockConsistencyGroupURI);
// Find all volumes assigned to the group
boolean cgContainsVolumes = false;
if (consistencyGroup != null) {
final List<Volume> activeCGVolumes = getActiveCGVolumes(consistencyGroup);
cgContainsVolumes = (activeCGVolumes != null && !activeCGVolumes.isEmpty());
}
// If the consistency group is created but does not specify the LOCAL
// type, the CG must be a CG created prior to 2.2 or an ingested CG. In
// this case, we don't want a volume creation to result in backend CGs.
// The only exception is if the CG does not reference any volumes. In
// this case, if the LOCAL type isn't specified, we can create backend
// CGs.
BlockConsistencyGroup backendCG = null;
if (consistencyGroup != null && (!consistencyGroup.created() || !cgContainsVolumes || consistencyGroup.getTypes().contains(Types.LOCAL.toString()))) {
backendCG = consistencyGroup;
}
// Prepare Bourne volumes to represent the backend volumes for the
// recommendations in each VirtualArray.
int varrayCount = 0;
String volumeLabel = param.getName();
List<VolumeDescriptor> descriptors = new ArrayList<VolumeDescriptor>();
URI[][] varrayVolumeURIs = new URI[2][vPoolCapabilities.getResourceCount()];
Iterator<String> varrayIter = varrayRecommendationsMap.keySet().iterator();
while (varrayIter.hasNext()) {
String varrayId = varrayIter.next();
s_logger.info("Processing backend recommendations for Virtual Array {}", varrayId);
List<VPlexRecommendation> vplexRecommendations = varrayRecommendationsMap.get(varrayId);
List<VolumeDescriptor> varrayDescriptors = makeBackendVolumeDescriptors(vplexRecommendations, project, vplexProject, vPool, volumeLabel, varrayCount, size, backendCG, vPoolCapabilities, createTask, task);
descriptors.addAll(varrayDescriptors);
List<URI> varrayURIs = VolumeDescriptor.getVolumeURIs(varrayDescriptors);
allVolumes.addAll(varrayURIs);
for (int i = 0; i < varrayURIs.size(); i++) {
varrayVolumeURIs[varrayCount][i] = varrayURIs.get(i);
}
varrayCount++;
}
// Prepare Bourne volumes to represent the highly available virtual
// volumes and associate the virtual volumes with their associated
// backend volumes.
s_logger.info("Preparing virtual volumes");
List<URI> virtualVolumeURIs = new ArrayList<URI>();
URI nullPoolURI = NullColumnValueGetter.getNullURI();
vPoolCapabilities.put(VirtualPoolCapabilityValuesWrapper.AUTO_TIER__POLICY_NAME, null);
for (int i = 0; i < vPoolCapabilities.getResourceCount(); i++) {
// Compute the volume label based on the label of the underlying volume
String volumeLabelBuilt = null;
Volume associatedVolume = _dbClient.queryObject(Volume.class, varrayVolumeURIs[0][i]);
// Get the virtual volume backing replication group instance name, if available.
String backingReplicationGroupInstance = null;
if (associatedVolume != null) {
volumeLabelBuilt = generateLabelFromAssociatedVolume(volumeLabel, associatedVolume);
backingReplicationGroupInstance = NullColumnValueGetter.isNotNullValue(associatedVolume.getReplicationGroupInstance()) ? associatedVolume.getReplicationGroupInstance() : NullColumnValueGetter.getNullStr();
} else {
volumeLabelBuilt = AbstractBlockServiceApiImpl.generateDefaultVolumeLabel(volumeLabel, i, vPoolCapabilities.getResourceCount());
}
s_logger.info("Volume label is {}", volumeLabelBuilt);
Volume volume = StorageScheduler.getPrecreatedVolume(_dbClient, taskList, volumeLabelBuilt);
boolean volumePrecreated = false;
if (volume != null) {
volumePrecreated = true;
}
long thinVolumePreAllocationSize = 0;
if (null != vPool.getThinVolumePreAllocationPercentage()) {
thinVolumePreAllocationSize = VirtualPoolUtil.getThinVolumePreAllocationSize(vPool.getThinVolumePreAllocationPercentage(), size);
}
volume = prepareVolume(VolumeType.VPLEX_VIRTUAL_VOLUME, volume, size, thinVolumePreAllocationSize, project, vArray, vPool, vplexStorageSystemURI, nullPoolURI, volumeLabelBuilt, consistencyGroup, vPoolCapabilities);
StringSet associatedVolumes = new StringSet();
associatedVolumes.add(varrayVolumeURIs[0][i].toString());
s_logger.info("Associating volume {}", varrayVolumeURIs[0][i].toString());
// associated with the virtual volume.
if (varrayCount > 1) {
associatedVolumes.add(varrayVolumeURIs[1][i].toString());
s_logger.info("Associating volume {}", varrayVolumeURIs[1][i].toString());
}
volume.setAssociatedVolumes(associatedVolumes);
if (null != backingReplicationGroupInstance) {
s_logger.info("Setting virtual volume backingReplicationGroupInstance to {}", backingReplicationGroupInstance);
volume.setBackingReplicationGroupInstance(backingReplicationGroupInstance);
}
_dbClient.updateObject(volume);
URI volumeId = volume.getId();
s_logger.info("Prepared virtual volume {}", volumeId);
virtualVolumeURIs.add(volumeId);
allVolumes.add(volumeId);
if (createTask && !volumePrecreated) {
Operation op = _dbClient.createTaskOpStatus(Volume.class, volume.getId(), task, ResourceOperationTypeEnum.CREATE_BLOCK_VOLUME);
TaskResourceRep volumeTask = toTask(volume, task, op);
taskList.getTaskList().add(volumeTask);
}
VolumeDescriptor descriptor = new VolumeDescriptor(VolumeDescriptor.Type.VPLEX_VIRT_VOLUME, vplexStorageSystemURI, volumeId, null, consistencyGroup == null ? null : consistencyGroup.getId(), vPoolCapabilities, volume.getCapacity());
// Set the compute resource in the descriptor if the volume to be created will be exported
// to a host/cluster after it has been created so that the compute resource name can be
// included in the volume name if the custom volume naming is so configured. Do not set the
// compute resource if the descriptor is for an SRDF target as the target is not exported
// to the compute resource.
URI computeResourceURI = param.getComputeResource();
if ((computeResourceURI != null) && (!srdfCopy)) {
s_logger.info(String.format("Volume %s - will be exported to Host/Cluster: %s", volume.getLabel(), computeResourceURI.toString()));
descriptor.setComputeResource(computeResourceURI);
}
descriptors.add(descriptor);
}
return descriptors;
}
use of com.emc.storageos.volumecontroller.VPlexRecommendation in project coprhd-controller by CoprHD.
the class VPlexBlockServiceApiImpl method makeBackendVolumeDescriptors.
/**
* Takes a list of recommendations and makes the backend volumes and volume descriptors needed to
* provision. When possible (e.g. for SRDF and Block), All recommendations must be in single varray.
* calls the underlying storage routine createVolumesAndDescriptors().
*
* @param recommendations -- a VPlex recommendation list
* @param project - Project containing the Vplex volumes
* @param vplexProject -- private project of the Vplex
* @param rootVpool -- top level Virtual Pool (VpoolUse.ROOT)
* @param varrayCount -- instance count of the varray being provisioned
* @param size -- size of each volume
* @param backendCG -- the CG to be used on the backend Storage Systems
* @param vPoolCapabilities - a VirtualPoolCapabilityValuesWrapper containing provisioning arguments
* @param createTask -- boolean if true creates a task
* @param task -- Overall task id
* @return -- list of VolumeDescriptors to be provisioned
*/
private List<VolumeDescriptor> makeBackendVolumeDescriptors(List<VPlexRecommendation> recommendations, Project project, Project vplexProject, VirtualPool rootVpool, String volumeLabel, int varrayCount, long size, BlockConsistencyGroup backendCG, VirtualPoolCapabilityValuesWrapper vPoolCapabilities, boolean createTask, String task) {
VPlexRecommendation firstRecommendation = recommendations.get(0);
List<VolumeDescriptor> descriptors = new ArrayList<VolumeDescriptor>();
URI varrayId = firstRecommendation.getVirtualArray();
VirtualPool vpool = firstRecommendation.getVirtualPool();
s_logger.info("Generated backend descriptors for {} recommendations varray {}", recommendations.size(), varrayCount);
vPoolCapabilities.put(VirtualPoolCapabilityValuesWrapper.AUTO_TIER__POLICY_NAME, vpool.getAutoTierPolicyName());
if (firstRecommendation.getRecommendation() != null) {
// If these recommendations have lower level recommendation, process them.
// This path is used for the source side of Distributed Volumes and for Local volumes
// where we support building on top of SRDF or the BlockStorage as appropriate.
List<Recommendation> childRecommendations = new ArrayList<Recommendation>();
Recommendation childRecommendation = null;
for (VPlexRecommendation recommendation : recommendations) {
childRecommendation = recommendation.getRecommendation();
childRecommendations.add(childRecommendation);
}
VirtualArray varray = _dbClient.queryObject(VirtualArray.class, varrayId);
String newVolumeLabel = generateVolumeLabel(volumeLabel, varrayCount, 0, 0);
boolean srdfTarget = (childRecommendation instanceof SRDFCopyRecommendation);
boolean srdfSource = (childRecommendation instanceof SRDFRecommendation);
if (srdfTarget) {
newVolumeLabel = newVolumeLabel + "-target";
} else if (srdfSource) {
} else {
// nothing special about these volumes, hide them in the vplex project
// We can't use the vplexProject for SRDF volumes as they determine their RDF group
// grom the project.
project = vplexProject;
}
TaskList taskList = new TaskList();
descriptors = super.createVolumesAndDescriptors(descriptors, newVolumeLabel, size, project, varray, vpool, childRecommendations, taskList, task, vPoolCapabilities);
VolumeDescriptor.Type[] types;
if (srdfTarget) {
types = new VolumeDescriptor.Type[] { VolumeDescriptor.Type.SRDF_TARGET };
} else {
types = new VolumeDescriptor.Type[] { VolumeDescriptor.Type.BLOCK_DATA, VolumeDescriptor.Type.SRDF_SOURCE, VolumeDescriptor.Type.SRDF_EXISTING_SOURCE };
}
descriptors = VolumeDescriptor.filterByType(descriptors, types);
for (VolumeDescriptor descriptor : descriptors) {
Volume volume = _dbClient.queryObject(Volume.class, descriptor.getVolumeURI());
s_logger.info(String.format("Received prepared volume %s (%s, args) type %s", volume.getLabel(), volume.getId(), descriptor.getType().name()));
volume.addInternalFlags(DataObject.Flag.INTERNAL_OBJECT);
configureCGAndReplicationGroup(rootVpool, vPoolCapabilities, backendCG, volume);
_dbClient.updateObject(volume);
}
return descriptors;
}
// Sum resourceCount across all recommendations
int totalResourceCount = 0;
for (VPlexRecommendation recommendation : recommendations) {
totalResourceCount += recommendation.getResourceCount();
}
// The code below is used for the HA side of distributed volumes.
// The HA side does not currently call the lower level schedulers to get descriptors.
s_logger.info("Processing recommendations for Virtual Array {}", varrayId);
int volumeCounter = 0;
for (VPlexRecommendation recommendation : recommendations) {
for (int i = 0; i < recommendation.getResourceCount(); i++) {
vpool = recommendation.getVirtualPool();
URI storageDeviceURI = recommendation.getSourceStorageSystem();
URI storagePoolURI = recommendation.getSourceStoragePool();
String newVolumeLabel = generateVolumeLabel(volumeLabel, varrayCount, volumeCounter, totalResourceCount);
validateVolumeLabel(newVolumeLabel, project);
s_logger.info("Volume label is {}", newVolumeLabel);
VirtualArray varray = _dbClient.queryObject(VirtualArray.class, varrayId);
// This is also handled in StorageScheduler.prepareRecomendedVolumes
long thinVolumePreAllocationSize = 0;
if (null != vpool.getThinVolumePreAllocationPercentage()) {
thinVolumePreAllocationSize = VirtualPoolUtil.getThinVolumePreAllocationSize(vpool.getThinVolumePreAllocationPercentage(), size);
}
Volume volume = prepareVolume(VolumeType.BLOCK_VOLUME, null, size, thinVolumePreAllocationSize, vplexProject, varray, vpool, storageDeviceURI, storagePoolURI, newVolumeLabel, backendCG, vPoolCapabilities);
configureCGAndReplicationGroup(rootVpool, vPoolCapabilities, backendCG, volume);
volume.addInternalFlags(Flag.INTERNAL_OBJECT);
_dbClient.persistObject(volume);
if (createTask) {
_dbClient.createTaskOpStatus(Volume.class, volume.getId(), task, ResourceOperationTypeEnum.CREATE_BLOCK_VOLUME);
}
s_logger.info("Prepared volume {} ({}) ", volume.getLabel(), volume.getId());
VolumeDescriptor descriptor = new VolumeDescriptor(VolumeDescriptor.Type.BLOCK_DATA, storageDeviceURI, volume.getId(), storagePoolURI, backendCG == null ? null : backendCG.getId(), vPoolCapabilities, size);
descriptors.add(descriptor);
volumeCounter++;
}
}
return descriptors;
}
use of com.emc.storageos.volumecontroller.VPlexRecommendation in project coprhd-controller by CoprHD.
the class RecoverPointScheduler method buildRpRecommendationFromExistingVolume.
/**
* Build the RP Recommendation using an existing volume found in the CG.
*
* @param volume Existing volume to use
* @param vpool The current vpool for the volume
* @param capabilities The capabilities map
* @param journalSize Size of the journal (only needed for journals, null otherwise)
* @return Fully formed RP Recommendation formed from resources of the existing CG
*/
private RPRecommendation buildRpRecommendationFromExistingVolume(Volume volume, VirtualPool vpool, VirtualPoolCapabilityValuesWrapper capabilities, Long journalSize) {
// Build the recommendation
RPRecommendation rec = new RPRecommendation();
rec.setVirtualPool(vpool);
rec.setVirtualArray(volume.getVirtualArray());
rec.setSourceStoragePool(volume.getPool());
rec.setSourceStorageSystem(volume.getStorageController());
rec.setInternalSiteName(volume.getInternalSiteName());
rec.setRpCopyName(volume.getRpCopyName());
rec.setSize((journalSize == null) ? capabilities.getSize() : journalSize);
rec.setResourceCount(capabilities.getResourceCount());
// Build VPLEX recommendation if specified
if (VirtualPool.vPoolSpecifiesHighAvailability(vpool)) {
VPlexRecommendation vplexRec = new VPlexRecommendation();
vplexRec.setVirtualPool(vpool);
vplexRec.setVirtualArray(volume.getVirtualArray());
vplexRec.setVPlexStorageSystem(volume.getStorageController());
// Always force count to 1 for a VPLEX rec for RP. VPLEX uses
// these recs and they are invoked one at a time even
// in a multi-volume request.
vplexRec.setResourceCount(1);
if (null == volume.getAssociatedVolumes() || volume.getAssociatedVolumes().isEmpty()) {
_log.error("VPLEX volume {} has no backend volumes.", volume.forDisplay());
throw InternalServerErrorException.internalServerErrors.noAssociatedVolumesForVPLEXVolume(volume.forDisplay());
}
for (String backingVolumeId : volume.getAssociatedVolumes()) {
Volume backingVolume = dbClient.queryObject(Volume.class, URI.create(backingVolumeId));
if (backingVolume.getVirtualArray().equals(volume.getVirtualArray())) {
rec.setSourceStoragePool(backingVolume.getPool());
rec.setSourceStorageSystem(backingVolume.getStorageController());
vplexRec.setSourceStoragePool(backingVolume.getPool());
vplexRec.setSourceStorageSystem(backingVolume.getStorageController());
} else {
if (journalSize == null) {
// Build HA recommendation if specified and this is not a VPLEX Journal.
// VPLEX Journals are always forced to VPLEX Local so we would not
// build a HA rec for it.
RPRecommendation haRec = new RPRecommendation();
VirtualPool haVpool = dbClient.queryObject(VirtualPool.class, backingVolume.getVirtualPool());
haRec.setVirtualPool(haVpool);
haRec.setVirtualArray(backingVolume.getVirtualArray());
haRec.setSourceStoragePool(backingVolume.getPool());
haRec.setSourceStorageSystem(backingVolume.getStorageController());
haRec.setResourceCount(capabilities.getResourceCount());
haRec.setSize(capabilities.getSize());
haRec.setInternalSiteName(backingVolume.getInternalSiteName());
haRec.setRpCopyName(backingVolume.getRpCopyName());
VPlexRecommendation haVPlexRec = new VPlexRecommendation();
haVPlexRec.setVirtualPool(haRec.getVirtualPool());
haVPlexRec.setVirtualArray(haRec.getVirtualArray());
haVPlexRec.setVPlexStorageSystem(volume.getStorageController());
haVPlexRec.setSourceStoragePool(haRec.getSourceStoragePool());
haVPlexRec.setSourceStorageSystem(haRec.getSourceStorageSystem());
// Always force count to 1 for a VPLEX rec for RP. VPLEX uses
// these recs and they are invoked one at a time even
// in a multi-volume request.
haVPlexRec.setResourceCount(1);
haRec.setVirtualVolumeRecommendation(haVPlexRec);
rec.setHaRecommendation(haRec);
}
}
}
rec.setVirtualVolumeRecommendation(vplexRec);
}
return rec;
}
use of com.emc.storageos.volumecontroller.VPlexRecommendation in project coprhd-controller by CoprHD.
the class PlacementTests method testVPlexLocalSRDFBasicPlacement.
@Test
public void testVPlexLocalSRDFBasicPlacement() {
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[] vplexFE = { "FE:FE:FE:FE:FE:FE:FE:00", "FE:FE:FE:FE:FE:FE:FE:01" };
String[] vplexBE = { "BE:BE:BE:BE:BE:BE:BE:00", "BE:BE:BE:BE:BE:BE:BE: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);
StorageSystem vplexSystem = PlacementTestUtils.createVPlexOneCluster(_dbClient, "vplex1", srcVarray, network1, network1, vplexFE, vplexBE);
// 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 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.getRecommendation() instanceof SRDFRecommendation);
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()));
}
}
Aggregations