use of com.emc.storageos.db.client.model.VirtualPool in project coprhd-controller by CoprHD.
the class VPlexBlockServiceApiImpl method createVolumeDescriptorsForVarrayChange.
/**
* Creates the volumes descriptors for a varray change for the passed
* list of VPLEX volumes.
*
* @param volumes The VPLEX volumes being moved
* @param newVarray The target virtual array
* @param taskId The task identifier
*
* @return A list of volume descriptors
*/
private List<VolumeDescriptor> createVolumeDescriptorsForVarrayChange(List<Volume> volumes, VirtualArray newVarray, String taskId) {
// The list of descriptors for the virtual array change.
List<VolumeDescriptor> descriptors = new ArrayList<VolumeDescriptor>();
// The VPLEX system.
StorageSystem vplexSystem = _dbClient.queryObject(StorageSystem.class, volumes.get(0).getStorageController());
// Create a descriptor for each vplex volume.
for (Volume vplexVolume : volumes) {
VolumeDescriptor descriptor = new VolumeDescriptor(VolumeDescriptor.Type.VPLEX_VIRT_VOLUME, vplexVolume.getStorageController(), vplexVolume.getId(), null, null);
Map<String, Object> descrParams = new HashMap<String, Object>();
descrParams.put(VolumeDescriptor.PARAM_VARRAY_CHANGE_NEW_VAARAY_ID, newVarray.getId());
descriptor.setParameters(descrParams);
descriptors.add(descriptor);
// We'll need to prepare a target volume and create a
// descriptor for each backend volume being migrated.
StringSet assocVolumes = vplexVolume.getAssociatedVolumes();
if (null == assocVolumes) {
s_logger.warn("VPLEX volume {} has no backend volumes. It was possibly ingested 'Virtual Volume Only'.", vplexVolume.forDisplay());
} else {
String assocVolumeId = assocVolumes.iterator().next();
URI assocVolumeURI = URI.create(assocVolumeId);
Volume assocVolume = _dbClient.queryObject(Volume.class, assocVolumeURI);
VirtualPool assocVolumeVPool = _dbClient.queryObject(VirtualPool.class, assocVolume.getVirtualPool());
descriptors.addAll(createBackendVolumeMigrationDescriptors(vplexSystem, vplexVolume, assocVolume, newVarray, assocVolumeVPool, getVolumeCapacity(assocVolume), taskId, null, false, null));
}
}
return descriptors;
}
use of com.emc.storageos.db.client.model.VirtualPool in project coprhd-controller by CoprHD.
the class VPlexBlockServiceApiImpl method createChangeVirtualPoolDescriptors.
/**
* Change the VirtualPool for the passed virtual volume on the passed VPlex
* storage system.
*
* @param vplexSystem A reference to the VPlex storage system.
* @param volume A reference to the virtual volume.
* @param newVpool The desired VirtualPool.
* @param taskId The task identifier.
* @param operationsWrapper a wrapper of various controller options
* @param allowHighAvailabilityMigrations Flag to allow HA migration descriptors to be created
* @throws InternalException
*/
protected List<VolumeDescriptor> createChangeVirtualPoolDescriptors(StorageSystem vplexSystem, Volume volume, VirtualPool newVpool, String taskId, List<Recommendation> recommendations, VirtualPoolCapabilityValuesWrapper capabilities, ControllerOperationValuesWrapper operationsWrapper, boolean allowHighAvailabilityMigrations) throws InternalException {
// Get the varray and current vpool for the virtual volume.
URI volumeVarrayURI = volume.getVirtualArray();
VirtualArray volumeVarray = _dbClient.queryObject(VirtualArray.class, volumeVarrayURI);
URI volumeVpoolURI = volume.getVirtualPool();
VirtualPool currentVpool = _dbClient.queryObject(VirtualPool.class, volumeVpoolURI);
s_logger.info(String.format("Creating VPLEX change vpool descriptors for volume [%s](%s) " + "which belongs to: varray [%s](%s) - vpool [%s](%s)", volume.getLabel(), volume.getId(), volumeVarray.getLabel(), volumeVarray.getId(), currentVpool.getLabel(), currentVpool.getId()));
List<VolumeDescriptor> descriptors = new ArrayList<VolumeDescriptor>();
// Add the VPLEX Virtual Volume Descriptor for change vpool
VolumeDescriptor vplexVirtualVolumeDesc = new VolumeDescriptor(VolumeDescriptor.Type.VPLEX_VIRT_VOLUME, volume.getStorageController(), volume.getId(), volume.getPool(), null);
Map<String, Object> volumeParams = new HashMap<String, Object>();
volumeParams.put(VolumeDescriptor.PARAM_VPOOL_CHANGE_EXISTING_VOLUME_ID, volume.getId());
volumeParams.put(VolumeDescriptor.PARAM_VPOOL_CHANGE_NEW_VPOOL_ID, newVpool.getId());
volumeParams.put(VolumeDescriptor.PARAM_VPOOL_CHANGE_OLD_VPOOL_ID, volume.getVirtualPool());
if (operationsWrapper != null) {
if (operationsWrapper.getMigrationSuspendBeforeCommit() != null) {
volumeParams.put(VolumeDescriptor.PARAM_MIGRATION_SUSPEND_BEFORE_COMMIT, operationsWrapper.getMigrationSuspendBeforeCommit());
}
if (operationsWrapper.getMigrationSuspendBeforeDeleteSource() != null) {
volumeParams.put(VolumeDescriptor.PARAM_MIGRATION_SUSPEND_BEFORE_DELETE_SOURCE, operationsWrapper.getMigrationSuspendBeforeDeleteSource());
}
}
vplexVirtualVolumeDesc.setParameters(volumeParams);
descriptors.add(vplexVirtualVolumeDesc);
// nothing about the backend volumes.
if (VirtualPoolChangeAnalyzer.vpoolChangeRequiresMigration(currentVpool, newVpool)) {
Volume migSrcVolume = getAssociatedVolumeInVArray(volume, volumeVarrayURI);
descriptors.addAll(createBackendVolumeMigrationDescriptors(vplexSystem, volume, migSrcVolume, volumeVarray, newVpool, getVolumeCapacity(migSrcVolume != null ? migSrcVolume : volume), taskId, recommendations, false, capabilities));
}
if (allowHighAvailabilityMigrations) {
// Now determine if the backend volume in the HA varray
// needs to be migrated.
URI haVarrayURI = VirtualPoolChangeAnalyzer.getHaVarrayURI(currentVpool);
if (haVarrayURI != null) {
VirtualArray haVarray = _dbClient.queryObject(VirtualArray.class, haVarrayURI);
VirtualPool currentHaVpool = VirtualPoolChangeAnalyzer.getHaVpool(currentVpool, _dbClient);
VirtualPool newHaVpool = VirtualPoolChangeAnalyzer.getNewHaVpool(currentVpool, newVpool, _dbClient);
if (VirtualPoolChangeAnalyzer.vpoolChangeRequiresMigration(currentHaVpool, newHaVpool)) {
Volume migSrcVolume = getAssociatedVolumeInVArray(volume, haVarrayURI);
descriptors.addAll(createBackendVolumeMigrationDescriptors(vplexSystem, volume, migSrcVolume, haVarray, newHaVpool, getVolumeCapacity(migSrcVolume != null ? migSrcVolume : volume), taskId, recommendations, true, capabilities));
}
}
}
return descriptors;
}
use of com.emc.storageos.db.client.model.VirtualPool 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.db.client.model.VirtualPool in project coprhd-controller by CoprHD.
the class VPlexBlockServiceApiImpl method updateConsistencyGroup.
/**
* {@inheritDoc}
*/
@Override
public TaskResourceRep updateConsistencyGroup(StorageSystem cgStorageSystem, List<Volume> cgVolumes, BlockConsistencyGroup consistencyGroup, List<URI> addVolumesList, List<URI> removeVolumesList, String taskId) throws ControllerException {
// addVolumesList could be volumes, or full copies, or snapshots or mirrors.
List<URI> addVolumes = new ArrayList<URI>();
List<URI> addSnapshots = new ArrayList<URI>();
List<URI> addFullcopies = new ArrayList<URI>();
for (URI volumeURI : addVolumesList) {
BlockObject blockObject = BlockObject.fetch(_dbClient, volumeURI);
if (blockObject instanceof BlockMirror) {
throw APIException.badRequests.actionNotApplicableForVplexVolumeMirrors(ResourceOperationTypeEnum.UPDATE_CONSISTENCY_GROUP.name());
} else if (blockObject instanceof BlockSnapshot) {
addSnapshots.add(volumeURI);
} else if (blockObject instanceof Volume) {
boolean isFullCopy = ControllerUtils.isVolumeFullCopy((Volume) blockObject, _dbClient);
if (isFullCopy) {
addFullcopies.add(volumeURI);
} else {
addVolumes.add(volumeURI);
}
}
}
if ((!addVolumes.isEmpty() && (!addSnapshots.isEmpty() || !addFullcopies.isEmpty())) || (!addSnapshots.isEmpty() && !addFullcopies.isEmpty())) {
throw APIException.badRequests.cantUpdateCGWithMixedBlockObjects(consistencyGroup.getLabel());
}
// group.
if (!addVolumes.isEmpty()) {
Iterator<Volume> cgVolumesIter = cgVolumes.iterator();
if (cgVolumesIter.hasNext()) {
Volume cgVolume = cgVolumesIter.next();
VirtualPool cgVPool = _permissionsHelper.getObjectById(cgVolume.getVirtualPool(), VirtualPool.class);
URI cgVArrayURI = cgVolume.getVirtualArray();
String cgHAType = cgVPool.getHighAvailability();
for (URI volumeURI : addVolumes) {
Volume addVolume = _permissionsHelper.getObjectById(volumeURI, Volume.class);
VirtualPool addVolumeVPool = _permissionsHelper.getObjectById(addVolume.getVirtualPool(), VirtualPool.class);
if (!addVolumeVPool.getHighAvailability().equals(cgHAType)) {
throw APIException.badRequests.invalidParameterConsistencyGroupVolumeHasIncorrectHighAvailability(cgVolume.getId(), cgHAType);
} else if (!cgVArrayURI.equals(addVolume.getVirtualArray())) {
throw APIException.badRequests.invalidParameterConsistencyGroupVolumeHasIncorrectVArray(cgVolume.getId(), cgVArrayURI);
}
}
}
// Check if the volumes have been in the CG, and not ingestion case
if (consistencyGroup.getTypes().contains(Types.LOCAL.toString()) && !cgVolumes.isEmpty()) {
Set<String> cgVolumesURISet = new HashSet<String>();
for (Volume cgVolume : cgVolumes) {
cgVolumesURISet.add(cgVolume.getId().toString());
}
Iterator<URI> iter = addVolumes.iterator();
while (iter.hasNext()) {
if (cgVolumesURISet.contains(iter.next().toString())) {
iter.remove();
}
}
if (addVolumes.isEmpty()) {
// All volumes in the addVolumes list have been in the CG. return success
s_logger.info("The volumes have been added to the CG");
Operation op = new Operation();
op.setResourceType(ResourceOperationTypeEnum.UPDATE_CONSISTENCY_GROUP);
op.ready("Volumes have been added to the consistency group");
_dbClient.createTaskOpStatus(BlockConsistencyGroup.class, consistencyGroup.getId(), taskId, op);
return toTask(consistencyGroup, taskId, op);
}
}
}
// Only add snapshot or full copies to CG if backend volumes are from the same storage system.
if (!addSnapshots.isEmpty() || !addFullcopies.isEmpty()) {
if (!VPlexUtil.isVPLEXCGBackendVolumesInSameStorage(cgVolumes, _dbClient)) {
throw APIException.badRequests.cantUpdateCGWithReplicaFromMultipleSystems(consistencyGroup.getLabel());
}
}
Operation op = _dbClient.createTaskOpStatus(BlockConsistencyGroup.class, consistencyGroup.getId(), taskId, ResourceOperationTypeEnum.UPDATE_CONSISTENCY_GROUP);
// When adding snapshots to CG, just call block implementation.
if (!addSnapshots.isEmpty()) {
BlockSnapshot snapshot = _permissionsHelper.getObjectById(addSnapshots.get(0), BlockSnapshot.class);
URI systemURI = snapshot.getStorageController();
StorageSystem system = _permissionsHelper.getObjectById(systemURI, StorageSystem.class);
BlockController controller = getController(BlockController.class, system.getSystemType());
controller.updateConsistencyGroup(system.getId(), consistencyGroup.getId(), addVolumesList, removeVolumesList, taskId);
return toTask(consistencyGroup, taskId, op);
}
// all the virtual volumes in the CG have to be selected.
if (!addVolumes.isEmpty()) {
verifyAddVolumesToIngestedCG(consistencyGroup, addVolumes);
}
if (!addFullcopies.isEmpty()) {
addVolumes.addAll(addFullcopies);
}
// Get VPlex controller
VPlexController controller = getController();
controller.updateConsistencyGroup(cgStorageSystem.getId(), consistencyGroup.getId(), addVolumes, removeVolumesList, taskId);
return toTask(consistencyGroup, taskId, op);
}
use of com.emc.storageos.db.client.model.VirtualPool in project coprhd-controller by CoprHD.
the class VPlexBlockServiceApiImpl method printMigrationInfo.
/**
* Method for logging for migrations.
*
* @param migration The migration that has been created
* @param sourceVolume The source/original volume to be migrated from (potential to be null for ingested volumes)
* @param targetVolume The target volume to be migrated to
*/
private void printMigrationInfo(Migration migration, Volume sourceVolume, Volume targetVolume) {
StringBuffer migrationInfo = new StringBuffer();
migrationInfo.append("\n+++++++++++++++++++++++++++++++++++++++++++");
migrationInfo.append(String.format("\nPrepared Migration: (%s)", migration.getId()));
if (sourceVolume != null) {
VirtualArray migrationSourceVarray = _dbClient.queryObject(VirtualArray.class, sourceVolume.getVirtualArray());
VirtualPool migrationSourceVpool = _dbClient.queryObject(VirtualPool.class, sourceVolume.getVirtualPool());
StoragePool migrationSourcePool = _dbClient.queryObject(StoragePool.class, sourceVolume.getPool());
StorageSystem migrationSourceStorageSystem = _dbClient.queryObject(StorageSystem.class, sourceVolume.getStorageController());
migrationInfo.append("\nMigration from... ");
migrationInfo.append(String.format("\n\tMigration Source Volume: [%s](%s)", sourceVolume.getLabel(), sourceVolume.getId()));
migrationInfo.append(String.format("\n\tMigration Source Varray: [%s](%s)", migrationSourceVarray.getLabel(), migrationSourceVarray.getId()));
migrationInfo.append(String.format("\n\tMigration Source Vpool: [%s](%s)", migrationSourceVpool.getLabel(), migrationSourceVpool.getId()));
migrationInfo.append(String.format("\n\tMigration Source Pool: [%s](%s)", migrationSourcePool.getLabel(), migrationSourcePool.getId()));
migrationInfo.append(String.format("\n\tMigration Source Storage: [%s](%s)", migrationSourceStorageSystem.getLabel(), migrationSourceStorageSystem.getId()));
}
VirtualArray migrationTargetVarray = _dbClient.queryObject(VirtualArray.class, targetVolume.getVirtualArray());
VirtualPool migrationTargetVpool = _dbClient.queryObject(VirtualPool.class, targetVolume.getVirtualPool());
StoragePool migrationTargetPool = _dbClient.queryObject(StoragePool.class, targetVolume.getPool());
StorageSystem migrationTargetStorageSystem = _dbClient.queryObject(StorageSystem.class, targetVolume.getStorageController());
migrationInfo.append("\nMigration to... ");
migrationInfo.append(String.format("\n\tMigration Target Volume: [%s](%s)", targetVolume.getLabel(), targetVolume.getId()));
migrationInfo.append(String.format("\n\tMigration Target Varray: [%s](%s)", migrationTargetVarray.getLabel(), migrationTargetVarray.getId()));
migrationInfo.append(String.format("\n\tMigration Target Vpool: [%s](%s)", migrationTargetVpool.getLabel(), migrationTargetVpool.getId()));
migrationInfo.append(String.format("\n\tMigration Target Pool: [%s](%s)", migrationTargetPool.getLabel(), migrationTargetPool.getId()));
migrationInfo.append(String.format("\n\tnMigration Target Storage: [%s](%s)", migrationTargetStorageSystem.getLabel(), migrationTargetStorageSystem.getId()));
migrationInfo.append("\n+++++++++++++++++++++++++++++++++++++++++++");
s_logger.info(migrationInfo.toString());
}
Aggregations