use of com.emc.storageos.svcs.errorhandling.resources.InternalException in project coprhd-controller by CoprHD.
the class MigrationService method resumeMigration.
/**
* Resume a migration that was previously paused.
*
* @prereq The migration is paused
*
* @param id the URN of a ViPR migration.
*
* @brief Resume a paused migration.
* @return A TaskResourceRep
*/
@POST
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/{id}/resume")
@CheckPermission(roles = { Role.SYSTEM_ADMIN, Role.RESTRICTED_SYSTEM_ADMIN })
public TaskResourceRep resumeMigration(@PathParam("id") URI id) {
ArgValidator.checkFieldUriType(id, Migration.class, "id");
Migration migration = queryResource(id);
if (!BulkList.MigrationFilter.isUserAuthorizedForMigration(migration, getUserFromContext(), _permissionsHelper)) {
StorageOSUser user = getUserFromContext();
throw APIException.forbidden.insufficientPermissionsForUser(user.getName());
}
String status = migration.getMigrationStatus();
String migrationName = migration.getLabel();
if (status == null || status.isEmpty() || migrationName == null || migrationName.isEmpty()) {
throw APIException.badRequests.migrationHasntStarted(id.toString());
}
if (!status.equalsIgnoreCase(VPlexMigrationInfo.MigrationStatus.PAUSED.getStatusValue())) {
throw APIException.badRequests.migrationCantBeResumed(migrationName, status);
}
URI volId = migration.getVolume();
Volume vplexVol = _dbClient.queryObject(Volume.class, volId);
// Create a unique task id.
String taskId = UUID.randomUUID().toString();
// Create a task for the virtual volume being migrated and set the
// initial task state to pending.
Operation op = _dbClient.createTaskOpStatus(Volume.class, volId, taskId, ResourceOperationTypeEnum.RESUME_MIGRATION);
TaskResourceRep task = toTask(vplexVol, taskId, op);
try {
VPlexController controller = _vplexBlockServiceApi.getController();
controller.resumeMigration(vplexVol.getStorageController(), id, taskId);
} catch (InternalException e) {
s_logger.error("Error", e);
String errMsg = String.format("Error: %s", e.getMessage());
task.setState(Operation.Status.error.name());
task.setMessage(errMsg);
op.error(e);
vplexVol.getOpStatus().updateTaskStatus(taskId, op);
_dbClient.persistObject(vplexVol);
}
return task;
}
use of com.emc.storageos.svcs.errorhandling.resources.InternalException in project coprhd-controller by CoprHD.
the class MigrationService method cancelMigration.
/**
* Cancel a migration that has yet to be committed.
*
* @prereq none
*
* @param id the URN of a ViPR migration.
*
* @brief Cancel an uncommitted migration.
* @return A TaskResourceRep
*/
@POST
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/{id}/cancel")
@CheckPermission(roles = { Role.SYSTEM_ADMIN, Role.RESTRICTED_SYSTEM_ADMIN })
public TaskResourceRep cancelMigration(@PathParam("id") URI id) {
ArgValidator.checkFieldUriType(id, Migration.class, "id");
Migration migration = queryResource(id);
if (!BulkList.MigrationFilter.isUserAuthorizedForMigration(migration, getUserFromContext(), _permissionsHelper)) {
StorageOSUser user = getUserFromContext();
throw APIException.forbidden.insufficientPermissionsForUser(user.getName());
}
if (migration == null || migration.getInactive()) {
throw APIException.badRequests.cancelMigrationFailed(id.toString(), "The migration is invalid");
}
String status = migration.getMigrationStatus();
String migrationName = migration.getLabel();
URI volId = migration.getVolume();
Volume vplexVol = _dbClient.queryObject(Volume.class, volId);
if (vplexVol == null || vplexVol.getInactive()) {
throw APIException.badRequests.cancelMigrationFailed(migrationName, "The migrating volume is not valid");
}
// Don't allow cancel operation if the vplex volume is in a CG
URI cgURI = vplexVol.getConsistencyGroup();
if (!NullColumnValueGetter.isNullURI(cgURI)) {
throw APIException.badRequests.cancelMigrationFailed(migrationName, "Migration cancellation is not supported for the volumes in consistency group");
}
if (status == null || status.isEmpty() || migrationName == null || migrationName.isEmpty()) {
throw APIException.badRequests.migrationHasntStarted(id.toString());
}
if (status.equalsIgnoreCase(VPlexMigrationInfo.MigrationStatus.COMMITTED.getStatusValue())) {
throw APIException.badRequests.migrationCantBeCancelled(migrationName, status);
}
// Create a unique task id.
String taskId = UUID.randomUUID().toString();
Operation op = _dbClient.createTaskOpStatus(Volume.class, volId, taskId, ResourceOperationTypeEnum.CANCEL_MIGRATION);
TaskResourceRep task = toTask(vplexVol, taskId, op);
if (status.equalsIgnoreCase(VPlexMigrationInfo.MigrationStatus.CANCELLED.getStatusValue()) || status.equalsIgnoreCase(VPlexMigrationInfo.MigrationStatus.PARTIALLY_CANCELLED.getStatusValue())) {
// it has been cancelled
s_logger.info("Migration {} has been cancelled", id);
op.ready();
vplexVol.getOpStatus().createTaskStatus(taskId, op);
_dbClient.persistObject(vplexVol);
return task;
}
try {
VPlexController controller = _vplexBlockServiceApi.getController();
controller.cancelMigration(vplexVol.getStorageController(), id, taskId);
} catch (InternalException e) {
s_logger.error("Controller Error", e);
String errMsg = String.format("Controller Error: %s", e.getMessage());
task.setState(Operation.Status.error.name());
task.setMessage(errMsg);
op.error(e);
vplexVol.getOpStatus().updateTaskStatus(taskId, op);
_dbClient.persistObject(vplexVol);
}
return task;
}
use of com.emc.storageos.svcs.errorhandling.resources.InternalException in project coprhd-controller by CoprHD.
the class RPBlockServiceApiImpl method createVolumes.
@Override
public TaskList createVolumes(VolumeCreate param, Project project, VirtualArray varray, VirtualPool vpool, Map<VpoolUse, List<Recommendation>> recommendationMap, TaskList taskList, String task, VirtualPoolCapabilityValuesWrapper capabilities) throws InternalException {
List<Recommendation> recommendations = recommendationMap.get(VpoolUse.ROOT);
// List of volumes to be prepared
List<URI> volumeURIs = new ArrayList<URI>();
// Volume label from the param
String volumeLabel = param.getName();
// List to store the volume descriptors for the Block Orchestration
List<VolumeDescriptor> volumeDescriptors = new ArrayList<VolumeDescriptor>();
// Store capabilities of the CG, so they make it down to the controller
if (vpool.getRpCopyMode() != null) {
capabilities.put(VirtualPoolCapabilityValuesWrapper.RP_COPY_MODE, vpool.getRpCopyMode());
}
if (vpool.getRpRpoType() != null && NullColumnValueGetter.isNotNullValue(vpool.getRpRpoType())) {
capabilities.put(VirtualPoolCapabilityValuesWrapper.RP_RPO_TYPE, vpool.getRpRpoType());
}
if (vpool.checkRpRpoValueSet()) {
capabilities.put(VirtualPoolCapabilityValuesWrapper.RP_RPO_VALUE, vpool.getRpRpoValue());
}
// Get the first recommendation, we need to figure out if this is a change vpool
RPProtectionRecommendation rpProtectionRec = (RPProtectionRecommendation) recommendations.get(0);
boolean isChangeVpool = (rpProtectionRec.getVpoolChangeVolume() != null);
boolean isChangeVpoolForProtectedVolume = rpProtectionRec.isVpoolChangeProtectionAlreadyExists();
// for change vpool, save off the original source volume in case we need to roll back
URI oldVpoolId = null;
if (isChangeVpool || isChangeVpoolForProtectedVolume) {
Volume changeVpoolVolume = _dbClient.queryObject(Volume.class, rpProtectionRec.getVpoolChangeVolume());
oldVpoolId = changeVpoolVolume.getVirtualPool();
}
try {
// Prepare the volumes
prepareRecommendedVolumes(param, task, taskList, project, varray, vpool, capabilities.getResourceCount(), recommendations, volumeLabel, capabilities, volumeDescriptors, volumeURIs);
// Execute the volume creations requests for each recommendation.
Iterator<Recommendation> recommendationsIter = recommendations.iterator();
while (recommendationsIter.hasNext()) {
RPProtectionRecommendation recommendation = (RPProtectionRecommendation) recommendationsIter.next();
volumeDescriptors.addAll(createVolumeDescriptors(recommendation, volumeURIs, capabilities, oldVpoolId, param.getComputeResource()));
logDescriptors(volumeDescriptors);
BlockOrchestrationController controller = getController(BlockOrchestrationController.class, BlockOrchestrationController.BLOCK_ORCHESTRATION_DEVICE);
// TODO might be able to use param.getSize() instead of the below code to find requestedVolumeCapactity
Long requestedVolumeCapactity = 0L;
for (URI volumeURI : volumeURIs) {
Volume volume = _dbClient.queryObject(Volume.class, volumeURI);
if (Volume.PersonalityTypes.SOURCE.name().equalsIgnoreCase(volume.getPersonality())) {
requestedVolumeCapactity = volume.getCapacity();
break;
}
}
computeProtectionCapacity(volumeURIs, requestedVolumeCapactity, false, isChangeVpool, null);
if (isChangeVpool) {
_log.info("Add Recoverpoint Protection to existing volume");
controller.changeVirtualPool(volumeDescriptors, task);
} else {
_log.info("Create RP volumes");
controller.createVolumes(volumeDescriptors, task);
}
}
} catch (Exception e) {
_log.error(e.getMessage(), e);
try {
// We want to return the volume back to its original state.
if (isChangeVpool || isChangeVpoolForProtectedVolume) {
Volume changeVpoolVolume = _dbClient.queryObject(Volume.class, rpProtectionRec.getVpoolChangeVolume());
VirtualPool oldVpool = _dbClient.queryObject(VirtualPool.class, oldVpoolId);
RPHelper.rollbackProtectionOnVolume(changeVpoolVolume, oldVpool, _dbClient);
}
for (URI volumeURI : volumeURIs) {
// completely rollback an existing volume (which the change vpool volume would be).
if (!volumeURI.equals(rpProtectionRec.getVpoolChangeVolume())) {
RPHelper.rollbackVolume(volumeURI, _dbClient);
}
}
} catch (Exception e2) {
// best effort for rollback; still need to set the tasks to error
_log.error("rollback create volume or change vpool failed");
_log.error(e2.getMessage(), e);
}
// Let's check to see if there are existing tasks, if so, put them in error.
if (taskList.getTaskList() != null && !taskList.getTaskList().isEmpty()) {
for (TaskResourceRep volumeTask : taskList.getTaskList()) {
volumeTask.setState(Operation.Status.error.name());
volumeTask.setMessage(e.getMessage());
Operation statusUpdate = new Operation(Operation.Status.error.name(), e.getMessage());
_dbClient.updateTaskOpStatus(Volume.class, volumeTask.getResource().getId(), task, statusUpdate);
}
}
throw APIException.badRequests.rpBlockApiImplPrepareVolumeException(volumeLabel);
}
return taskList;
}
use of com.emc.storageos.svcs.errorhandling.resources.InternalException in project coprhd-controller by CoprHD.
the class FileService method createQuotaDirectory.
/**
* Create Quota directory for a file system
* <p>
* NOTE: This is an asynchronous operation.
*
* @param id
* the URN of a ViPR File system
* @param param
* File system Quota directory parameters
* @brief Create file system Quota directory
* @return Task resource representation
* @throws InternalException
*/
@POST
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/{id}/quota-directories")
@CheckPermission(roles = { Role.TENANT_ADMIN }, acls = { ACL.OWN, ACL.ALL })
public TaskResourceRep createQuotaDirectory(@PathParam("id") URI id, QuotaDirectoryCreateParam param) throws InternalException {
_log.info("FileService::createQtree Request recieved {}", id);
String origQtreeName = param.getQuotaDirName();
ArgValidator.checkQuotaDirName(origQtreeName, "name");
ArgValidator.checkFieldMaximum(param.getSoftLimit(), 100, "softLimit");
ArgValidator.checkFieldMaximum(param.getNotificationLimit(), 100, "notificationLimit");
if (param.getSoftLimit() != 0L) {
ArgValidator.checkFieldMinimum(param.getSoftGrace(), 1L, "softGrace");
}
// check duplicate QuotaDirectory names for this fileshare
checkForDuplicateName(origQtreeName, QuotaDirectory.class, id, "parent", _dbClient);
String task = UUID.randomUUID().toString();
ArgValidator.checkFieldUriType(id, FileShare.class, "id");
if (param.getSecurityStyle() != null) {
ArgValidator.checkFieldValueFromEnum(param.getSecurityStyle(), "security_style", EnumSet.allOf(QuotaDirectory.SecurityStyles.class));
}
// Get the FileSystem object from the URN
FileShare fs = queryResource(id);
ArgValidator.checkEntity(fs, id, isIdEmbeddedInURL(id));
int fsSoftLimit = -1;
if (null != fs.getSoftLimit()) {
fsSoftLimit = fs.getSoftLimit().intValue();
}
int fsNotifiLimit = -1;
if (null != fs.getNotificationLimit()) {
fsNotifiLimit = fs.getNotificationLimit().intValue();
}
int fsGraceLimit = -1;
if (null != fs.getSoftGracePeriod()) {
fsGraceLimit = fs.getSoftGracePeriod().intValue();
}
// Create the QuotaDirectory object for the DB
QuotaDirectory quotaDirectory = new QuotaDirectory();
quotaDirectory.setId(URIUtil.createId(QuotaDirectory.class));
// ICICIC - Curious !
quotaDirectory.setParent(new NamedURI(id, origQtreeName));
quotaDirectory.setLabel(origQtreeName);
quotaDirectory.setOpStatus(new OpStatusMap());
quotaDirectory.setProject(new NamedURI(fs.getProject().getURI(), origQtreeName));
quotaDirectory.setTenant(new NamedURI(fs.getTenant().getURI(), origQtreeName));
quotaDirectory.setSoftLimit(param.getSoftLimit() > 0 ? param.getSoftLimit() : fsSoftLimit > 0 ? fsSoftLimit : 0);
quotaDirectory.setSoftGrace(param.getSoftGrace() > 0 ? param.getSoftGrace() : fsGraceLimit > 0 ? fsGraceLimit : 0);
quotaDirectory.setNotificationLimit(param.getNotificationLimit() > 0 ? param.getNotificationLimit() : fsNotifiLimit > 0 ? fsNotifiLimit : 0);
String convertedName = origQtreeName.replaceAll("[^\\dA-Za-z_]", "");
_log.info("FileService::QuotaDirectory Original name {} and converted name {}", origQtreeName, convertedName);
quotaDirectory.setName(convertedName);
if (param.getOpLock() != null) {
quotaDirectory.setOpLock(param.getOpLock());
} else {
quotaDirectory.setOpLock(true);
}
if (param.getSecurityStyle() != null) {
quotaDirectory.setSecurityStyle(param.getSecurityStyle());
} else {
quotaDirectory.setSecurityStyle(SecurityStyles.parent.toString());
}
if (param.getSize() != null) {
// converts the input string in format "<value>GB"
Long quotaSize = SizeUtil.translateSize(param.getSize());
// to bytes
ArgValidator.checkFieldMaximum(quotaSize, fs.getCapacity(), SizeUtil.SIZE_B, "size", true);
quotaDirectory.setSize(quotaSize);
} else {
quotaDirectory.setSize((long) 0);
}
fs.setOpStatus(new OpStatusMap());
Operation op = new Operation();
op.setResourceType(ResourceOperationTypeEnum.CREATE_FILE_SYSTEM_QUOTA_DIR);
quotaDirectory.getOpStatus().createTaskStatus(task, op);
fs.getOpStatus().createTaskStatus(task, op);
_dbClient.createObject(quotaDirectory);
_dbClient.persistObject(fs);
// Create an object of type "FileShareQuotaDirectory" to be passed into the south-bound layers.
FileShareQuotaDirectory qt = new FileShareQuotaDirectory(quotaDirectory);
// Now get ready to make calls into the controller
StorageSystem device = _dbClient.queryObject(StorageSystem.class, fs.getStorageDevice());
FileController controller = getController(FileController.class, device.getSystemType());
try {
controller.createQuotaDirectory(device.getId(), qt, fs.getId(), task);
} catch (InternalException e) {
quotaDirectory.setInactive(true);
_dbClient.persistObject(quotaDirectory);
// should discriminate between validation problems vs. internal errors
throw e;
}
auditOp(OperationTypeEnum.CREATE_FILE_SYSTEM_QUOTA_DIR, true, AuditLogManager.AUDITOP_BEGIN, quotaDirectory.getLabel(), quotaDirectory.getId().toString(), fs.getId().toString());
fs = _dbClient.queryObject(FileShare.class, id);
_log.debug("FileService::QuotaDirectory Before sending response, FS ID : {}, Tasks : {} ; Status {}", fs.getOpStatus().get(task), fs.getOpStatus().get(task).getStatus());
return toTask(quotaDirectory, task, op);
}
use of com.emc.storageos.svcs.errorhandling.resources.InternalException in project coprhd-controller by CoprHD.
the class FileService method reduce.
/**
* Reduce file system quota -- supported only on Isilon
*
* @param id - the URN of a ViPR File system
* @param param - File system reduction parameters
* @return Task resource representation
* @throws InternalException
*/
@POST
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/{id}/reduce")
@CheckPermission(roles = { Role.TENANT_ADMIN }, acls = { ACL.OWN, ACL.ALL })
public TaskResourceRep reduce(@PathParam("id") URI id, FileSystemReduceParam param) throws InternalException {
_log.info(String.format("FileShareReduce --- FileShare id: %1$s, New Quota: %2$s", id, param.getNewSize()));
// check file system
ArgValidator.checkFieldUriType(id, FileShare.class, "id");
FileShare fs = queryResource(id);
ArgValidator.checkEntity(fs, id, isIdEmbeddedInURL(id));
StorageSystem device = _dbClient.queryObject(StorageSystem.class, fs.getStorageDevice());
if (!device.deviceIsType(DiscoveredDataObject.Type.isilon)) {
String msg = String.format("reducing filesystem is not supported for storage system %s", device.getSystemType());
throw APIException.badRequests.reduceFileSystemNotSupported(msg);
}
Long newFSsize = SizeUtil.translateSize(param.getNewSize());
long quotaFsSize = newFSsize - fs.getCapacity();
final long MIN_EXPAND_SIZE = SizeUtil.translateSize("1MB") + 1;
if (newFSsize <= 0) {
throw APIException.badRequests.parameterMustBeGreaterThan("new_size", 0);
} else {
if (quotaFsSize < MIN_EXPAND_SIZE) {
List<QuotaDirectory> quotaDirs = queryDBQuotaDirectories(fs);
if (null != quotaDirs && !quotaDirs.isEmpty()) {
long qdsize = 0;
// that new size should not be less than any of the sub quota.
for (QuotaDirectory quotaDir : quotaDirs) {
qdsize = newFSsize - quotaDir.getSize();
Double quotasize = SizeUtil.translateSize(quotaDir.getSize(), SizeUtil.SIZE_GB);
Double newFScapacity = SizeUtil.translateSize(newFSsize, SizeUtil.SIZE_GB);
if (qdsize < MIN_EXPAND_SIZE) {
String msg = String.format("as requested reduced size [%.1fGB] is smaller than its quota size [%.1fGB] for filesystem %s", newFScapacity, quotasize, fs.getName());
throw APIException.badRequests.reduceFileSystemNotSupported(msg);
}
}
}
} else {
throw APIException.badRequests.parameterMustBeLessThan("new_size", fs.getCapacity());
}
}
String task = UUID.randomUUID().toString();
Operation op = _dbClient.createTaskOpStatus(FileShare.class, fs.getId(), task, ResourceOperationTypeEnum.REDUCE_FILE_SYSTEM);
op.setDescription("Filesystem reduce quota");
FileServiceApi fileServiceApi = getFileShareServiceImpl(fs, _dbClient);
try {
fileServiceApi.reduceFileShareQuota(fs, newFSsize, task);
} catch (InternalException e) {
if (_log.isErrorEnabled()) {
_log.error("Reduce File Quota error", e);
}
fs = _dbClient.queryObject(FileShare.class, fs.getId());
op = fs.getOpStatus().get(task);
op.error(e);
fs.getOpStatus().updateTaskStatus(task, op);
_dbClient.updateObject(fs);
throw e;
}
return toTask(fs, task, op);
}
Aggregations