use of com.emc.storageos.model.block.VolumeVirtualPoolChangeParam in project coprhd-controller by CoprHD.
the class ChangeBlockVolumeVirtualPool method doExecute.
@Override
protected Tasks<VolumeRestRep> doExecute() throws Exception {
VolumeVirtualPoolChangeParam input = new VolumeVirtualPoolChangeParam();
input.setVolumes(volumeIds);
input.setVirtualPool(targetVirtualPoolId);
input.setForceFlag(forceFlag);
if (!NullColumnValueGetter.isNullURI(consistencyGroup)) {
input.setConsistencyGroup(consistencyGroup);
}
input.setMigrationSuspendBeforeCommit(suspendOnMigration);
input.setMigrationSuspendBeforeDeleteSource(suspendOnMigration);
return getClient().blockVolumes().changeVirtualPool(input);
}
use of com.emc.storageos.model.block.VolumeVirtualPoolChangeParam in project coprhd-controller by CoprHD.
the class ChangeBlockVolumeVirtualPoolNoWait method executeTask.
@Override
public Tasks<VolumeRestRep> executeTask() throws Exception {
Tasks<VolumeRestRep> result = new Tasks<VolumeRestRep>(getClient().auth().getClient(), null, VolumeRestRep.class);
// One request per virtual pool
for (URI vpool : volumeIds.keySet()) {
if (!vpool.equals(targetVirtualPoolId)) {
VolumeVirtualPoolChangeParam input = new VolumeVirtualPoolChangeParam();
input.setVolumes(Lists.newArrayList(volumeIds.get(vpool)));
input.setVirtualPool(targetVirtualPoolId);
try {
Tasks<VolumeRestRep> tasks = getClient().blockVolumes().changeVirtualPool(input);
for (Task<VolumeRestRep> task : tasks.getTasks()) {
addOrderIdTag(task.getTaskResource().getId());
}
result.getTasks().addAll(tasks.getTasks());
} catch (ServiceErrorException ex) {
logError(ex.getMessage());
}
}
}
return result;
}
use of com.emc.storageos.model.block.VolumeVirtualPoolChangeParam in project coprhd-controller by CoprHD.
the class BlockService method changeVolumesVirtualPool.
/**
* Allows the caller to change the virtual pool for the volumes identified in
* the request. Currently, the only virtual pool changes that are supported via
* this method are as follows:
*
* Change the virtual pool for a VPLEX virtual volume. This virtual pool
* change would allow the caller to change the types of drives, for example,
* used for the backend volume(s) that are used by the virtual volume.
*
* Change the virtual pool for a VPLEX virtual volume, such that a local
* VPLEX virtual volumes becomes a distributed VPLEX virtual volume.
*
* Change the virtual pool of a VMAX or VNX Block volume to make the volume
* a local or distributed VPLEX virtual volume. Essentially, the volume
* becomes the backend volume for a VPLEX virtual volume. Similar to
* creating a virtual volume, but instead of creating a new backend volume,
* using the volume identified in the request. The VMAX or VNX volume cannot
* currently be exported for this change.
*
* Change the virtual pool of a VMAX or VNX Block volume to make the volume
* a RecoverPoint protected volume. The volume must be able to stay put, and
* ViPR will build a protection around it.
*
* Change the virtual pool of a VMAX or VNX Block volume to allow native
* continuous copies to be created for it.
*
* Change the virtual pool of a volume to increase the export path parameter max_paths.
* The number of paths will be upgraded if possible for all Export Groups / Export Masks
* containing this volume. If the volume is not currently exported, max_paths can be
* decreased or paths_per_initiator can be changed. Note that changing max_paths does
* not have any effect on the export of BlockSnapshots that were created from this volume.
*
* Change the virtual pool of a VMAX and VNX volumes to allow change of Auto-tiering policy
* associated with it.
*
* Note: Operations other than Auto-tiering Policy change will call the
* internal single volume method (BlockServiceApiImpl) in a loop.
*
* @brief Change the virtual pool for the given volumes.
*
* @param param
* the VolumeVirtualPoolChangeParam
* @return A List of TaskResourceRep representing the virtual pool change for the
* volumes.
* @throws InternalException,
* APIException
*/
@POST
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/vpool-change")
@CheckPermission(roles = { Role.TENANT_ADMIN }, acls = { ACL.OWN, ACL.ALL })
public TaskList changeVolumesVirtualPool(VolumeVirtualPoolChangeParam param) throws InternalException, APIException {
// verify volume ids list is provided.
List<URI> ids = param.getVolumes();
ArgValidator.checkFieldNotEmpty(ids, "volumes");
_log.info("Request to change VirtualPool for volumes {}", ids);
List<Volume> volumes = new ArrayList<Volume>();
TaskList taskList = new TaskList();
for (URI id : ids) {
// Get the volume.
ArgValidator.checkFieldUriType(id, Volume.class, "volume");
Volume volume = queryVolumeResource(id);
volumes.add(volume);
// Make sure that we don't have some pending
// operation against the volume
checkForPendingTasks(Arrays.asList(volume.getTenant().getURI()), Arrays.asList(volume));
}
_log.info("Found volumes");
/**
* verify that all volumes belong to same vPool.
*
* If so and vPool change detects it as Auto-tiering policy change,
* then they are of same system type.
*
* Special case: If the request contains a VMAX volume and a VNX volume
* belonging to a generic vPool and the target vPool has some VMAX FAST policy,
* the below verifyVirtualPoolChangeSupportedForVolumeAndVirtualPool() check will
* throw error for VNX volume (saying it does not come under any valid change).
*/
verifyAllVolumesBelongToSameVpool(volumes);
// target vPool
VirtualPool vPool = null;
// total provisioned capacity to check for vPool quota.
long totalProvisionedCapacity = 0;
for (Volume volume : volumes) {
_log.info("Checking on volume: {}", volume.getId());
// Don't operate on VPLEX backend or RP Journal volumes.
BlockServiceUtils.validateNotAnInternalBlockObject(volume, param.getForceFlag());
// Don't operate on ingested volumes.
VolumeIngestionUtil.checkOperationSupportedOnIngestedVolume(volume, ResourceOperationTypeEnum.CHANGE_BLOCK_VOLUME_VPOOL, _dbClient);
// Get the project.
URI projectURI = volume.getProject().getURI();
Project project = _permissionsHelper.getObjectById(projectURI, Project.class);
ArgValidator.checkEntity(project, projectURI, false);
_log.info("Found volume project {}", projectURI);
// Verify the user is authorized for the volume's project.
BlockServiceUtils.verifyUserIsAuthorizedForRequest(project, getUserFromContext(), _permissionsHelper);
_log.info("User is authorized for volume's project");
// Get the VirtualPool for the request and verify that the
// project's tenant has access to the VirtualPool.
vPool = getVirtualPoolForRequest(project, param.getVirtualPool(), _dbClient, _permissionsHelper);
_log.info("Found new VirtualPool {}", vPool.getId());
// Verify that the VirtualPool change is allowed for the
// requested volume and VirtualPool.
verifyVirtualPoolChangeSupportedForVolumeAndVirtualPool(volume, vPool);
_log.info("VirtualPool change is supported for requested volume and VirtualPool");
totalProvisionedCapacity += volume.getProvisionedCapacity().longValue();
}
verifyAllVolumesInCGRequirement(volumes, vPool);
// verify target vPool quota
if (!CapacityUtils.validateVirtualPoolQuota(_dbClient, vPool, totalProvisionedCapacity)) {
throw APIException.badRequests.insufficientQuotaForVirtualPool(vPool.getLabel(), "volume");
}
// Create a unique task id.
String taskId = UUID.randomUUID().toString();
// if this vpool request change has a consistency group, set its requested types
if (param.getConsistencyGroup() != null) {
BlockConsistencyGroup cg = _dbClient.queryObject(BlockConsistencyGroup.class, param.getConsistencyGroup());
if (cg != null && !cg.getInactive()) {
cg.getRequestedTypes().addAll(getRequestedTypes(vPool));
_dbClient.updateObject(cg);
}
}
// to execute the VirtualPool update on the volume.
try {
/**
* If it is Auto-tiering policy change, the system type remains same
* between source and target vPools.
* Volumes from single vPool would be of same characteristics and
* all would specify same operation.
*/
BlockServiceApi blockServiceAPI = getBlockServiceImplForVirtualPoolChange(volumes.get(0), vPool);
_log.info("Got block service implementation for VirtualPool change request");
VirtualPoolChangeParam oldParam = convertNewVirtualPoolChangeParamToOldParam(param);
TaskList taskList2 = blockServiceAPI.changeVolumeVirtualPool(volumes, vPool, oldParam, taskId);
if (taskList2 != null && !taskList2.getTaskList().isEmpty()) {
taskList.getTaskList().addAll(taskList2.getTaskList());
}
_log.info("Executed VirtualPool change for given volumes.");
} catch (Exception e) {
String errorMsg = String.format("Volume VirtualPool change error: %s", e.getMessage());
_log.error(errorMsg, e);
if (!taskList.getTaskList().isEmpty()) {
for (TaskResourceRep volumeTask : taskList.getTaskList()) {
volumeTask.setState(Operation.Status.error.name());
volumeTask.setMessage(errorMsg);
_dbClient.updateTaskOpStatus(Volume.class, volumeTask.getResource().getId(), taskId, new Operation(Operation.Status.error.name(), errorMsg));
}
} else {
for (Volume volume : volumes) {
_dbClient.updateTaskOpStatus(Volume.class, volume.getId(), taskId, new Operation(Operation.Status.error.name(), errorMsg));
}
}
throw e;
}
// Record Audit operation.
for (Volume volume : volumes) {
auditOp(OperationTypeEnum.CHANGE_VOLUME_VPOOL, true, AuditLogManager.AUDITOP_BEGIN, volume.getLabel(), 1, volume.getVirtualArray().toString(), volume.getProject().toString());
}
return taskList;
}
use of com.emc.storageos.model.block.VolumeVirtualPoolChangeParam in project coprhd-controller by CoprHD.
the class BlockService method convertNewVirtualPoolChangeParamToOldParam.
/**
* Copy the contents from new virtual pool change param to old param.
*
* Old param is passed as an argument in multiple methods and it is not advisable
* to create over-loaded methods for all those.
* When we remove the old deprecated param class, we can change the argument in
* all those methods to take the new param.
*
* @param param
* the param
* @return the virtual pool change param
*/
private VirtualPoolChangeParam convertNewVirtualPoolChangeParamToOldParam(VolumeVirtualPoolChangeParam newParam) {
VirtualPoolChangeParam oldParam = new VirtualPoolChangeParam();
oldParam.setVirtualPool(newParam.getVirtualPool());
oldParam.setProtection(newParam.getProtection());
oldParam.setConsistencyGroup(newParam.getConsistencyGroup());
oldParam.setTransferSpeedParam(newParam.getTransferSpeedParam());
oldParam.setMigrationSuspendBeforeCommit(newParam.isMigrationSuspendBeforeCommit());
oldParam.setMigrationSuspendBeforeDeleteSource(newParam.isMigrationSuspendBeforeDeleteSource());
return oldParam;
}
Aggregations