use of com.emc.storageos.model.TaskList in project coprhd-controller by CoprHD.
the class BlockSnapshotService method deactivateSnapshot.
/**
* Deactivate volume snapshot, will result in permanent deletion of the requested snapshot from the storage system it was created on
* and will move the snapshot to a "marked-for-delete" state after the deletion happens on the array side.
* It will be deleted by the garbage collector on a subsequent iteration
* If this snapshot was created from a volume that is part of a consistency group,
* then all the related snapshots will be deactivated, as well.
*
* If "?type=VIPR_ONLY" is added to the path, it will delete snapshot only from ViPR data base and leaves the snapshot on storage array
* as it is.
* Possible value for attribute type : FULL, VIPR_ONLY
* FULL : Deletes the snapshot permanently on array and ViPR data base.
* VIPR_ONLY : Deletes the snapshot only from ViPR data base and leaves the snapshot on array as it is.
*
* @prereq none
* @param id the URN of a ViPR snapshot
* @param type the type of deletion {@link DefaultValue} FULL
* @brief Delete snapshot
* @return Snapshot information
*/
@POST
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/{id}/deactivate")
@CheckPermission(roles = { Role.TENANT_ADMIN }, acls = { ACL.ANY })
public TaskList deactivateSnapshot(@PathParam("id") URI id, @DefaultValue("FULL") @QueryParam("type") String type) {
_log.info("Executing {} snapshot delete for snapshot {}", type, id);
String opStage = null;
boolean successStatus = true;
String taskId = UUID.randomUUID().toString();
TaskList response = new TaskList();
// Get the snapshot.
BlockSnapshot snap = (BlockSnapshot) queryResource(id);
// We can ignore dependencies on BlockSnapshotSession. In this case
// the BlockSnapshot instance is a linked target for a BlockSnapshotSession
// and we will unlink the snapshot from the session and delete it.
List<Class<? extends DataObject>> excludeTypes = new ArrayList<Class<? extends DataObject>>();
excludeTypes.add(BlockSnapshotSession.class);
if (VolumeDeleteTypeEnum.VIPR_ONLY.name().equals(type)) {
excludeTypes.add(ExportGroup.class);
excludeTypes.add(ExportMask.class);
}
ArgValidator.checkReference(BlockSnapshot.class, id, checkForDelete(snap, excludeTypes));
if (!VolumeDeleteTypeEnum.VIPR_ONLY.name().equals(type)) {
// The audit log message operation stage.
opStage = AuditLogManager.AUDITOP_BEGIN;
// If the BlockSnapshot instance represents a linked target, then
// we need to unlink the target form the snapshot session and then
// delete the target.
URIQueryResultList snapSessionURIs = new URIQueryResultList();
_dbClient.queryByConstraint(ContainmentConstraint.Factory.getLinkedTargetSnapshotSessionConstraint(id), snapSessionURIs);
Iterator<URI> snapSessionURIsIter = snapSessionURIs.iterator();
if (snapSessionURIsIter.hasNext()) {
_log.info("Snapshot is linked target for a snapshot session");
SnapshotSessionUnlinkTargetsParam param = new SnapshotSessionUnlinkTargetsParam();
List<SnapshotSessionUnlinkTargetParam> targetInfoList = new ArrayList<SnapshotSessionUnlinkTargetParam>();
SnapshotSessionUnlinkTargetParam targetInfo = new SnapshotSessionUnlinkTargetParam(id, Boolean.TRUE);
targetInfoList.add(targetInfo);
param.setLinkedTargets(targetInfoList);
response.getTaskList().add(getSnapshotSessionManager().unlinkTargetVolumesFromSnapshotSession(snapSessionURIsIter.next(), param, OperationTypeEnum.DELETE_VOLUME_SNAPSHOT));
return response;
}
// Not an error if the snapshot we try to delete is already deleted
if (snap.getInactive()) {
_log.info("Snapshot is already inactive");
Operation op = new Operation();
op.ready("The snapshot has already been deleted");
op.setResourceType(ResourceOperationTypeEnum.DELETE_VOLUME_SNAPSHOT);
_dbClient.createTaskOpStatus(BlockSnapshot.class, snap.getId(), taskId, op);
response.getTaskList().add(toTask(snap, taskId, op));
return response;
}
}
// Get the storage system.
StorageSystem device = _dbClient.queryObject(StorageSystem.class, snap.getStorageController());
// Determine all snapshots to delete.
List<BlockSnapshot> snapshots = new ArrayList<BlockSnapshot>();
final URI cgId = snap.getConsistencyGroup();
if (!NullColumnValueGetter.isNullURI(cgId) && !NullColumnValueGetter.isNullValue(snap.getReplicationGroupInstance())) {
// Collect all the BlockSnapshots if part of a CG.
snapshots = ControllerUtils.getSnapshotsPartOfReplicationGroup(snap, _dbClient);
} else {
// Snap is not part of a CG so only delete the snap
snapshots.add(snap);
}
// Get the snapshot parent volume.
Volume parentVolume = _permissionsHelper.getObjectById(snap.getParent(), Volume.class);
// Check that there are no pending tasks for these snapshots.
checkForPendingTasks(Arrays.asList(parentVolume.getTenant().getURI()), snapshots);
// Create tasks on the volume.
for (BlockSnapshot snapshot : snapshots) {
Operation snapOp = _dbClient.createTaskOpStatus(BlockSnapshot.class, snapshot.getId(), taskId, ResourceOperationTypeEnum.DELETE_VOLUME_SNAPSHOT);
response.getTaskList().add(toTask(snapshot, taskId, snapOp));
}
// should be returned.
try {
BlockServiceApi blockServiceApiImpl = BlockService.getBlockServiceImpl(parentVolume, _dbClient);
blockServiceApiImpl.deleteSnapshot(snap, snapshots, taskId, type);
} catch (APIException | InternalException e) {
successStatus = false;
String errorMsg = String.format("Exception attempting to delete snapshot %s: %s", snap.getId(), e.getMessage());
_log.error(errorMsg);
for (TaskResourceRep taskResourceRep : response.getTaskList()) {
taskResourceRep.setState(Operation.Status.error.name());
taskResourceRep.setMessage(errorMsg);
_dbClient.error(BlockSnapshot.class, taskResourceRep.getResource().getId(), taskId, e);
}
} catch (Exception e) {
successStatus = false;
String errorMsg = String.format("Exception attempting to delete snapshot %s: %s", snap.getId(), e.getMessage());
_log.error(errorMsg);
ServiceCoded sc = APIException.internalServerErrors.genericApisvcError(errorMsg, e);
for (TaskResourceRep taskResourceRep : response.getTaskList()) {
taskResourceRep.setState(Operation.Status.error.name());
taskResourceRep.setMessage(sc.getMessage());
_dbClient.error(BlockSnapshot.class, taskResourceRep.getResource().getId(), taskId, sc);
}
}
auditOp(OperationTypeEnum.DELETE_VOLUME_SNAPSHOT, successStatus, opStage, id.toString(), snap.getLabel(), snap.getParent().getName(), device.getId().toString());
return response;
}
use of com.emc.storageos.model.TaskList in project coprhd-controller by CoprHD.
the class CreateFileSystemSchedulingThread method run.
@Override
public void run() {
_log.info("Starting scheduling placement thread for task {}", task);
try {
// Call out placementManager to get the recommendation for placement.
List recommendations = this.fileService._filePlacementManager.getRecommendationsForFileCreateRequest(varray, project, vpool, capabilities);
if (recommendations == null || recommendations.isEmpty()) {
throw APIException.badRequests.noMatchingStoragePoolsForVpoolAndVarray(vpool.getLabel(), varray.getLabel());
} else {
// Call out to the respective file service implementation to prepare
// and create the fileshares based on the recommendations.
fileServiceImpl.createFileSystems(param, project, varray, vpool, tenantOrg, flags, recommendations, taskList, task, capabilities);
}
} catch (Exception ex) {
for (TaskResourceRep taskObj : taskList.getTaskList()) {
if (ex instanceof ServiceCoded) {
this.fileService._dbClient.error(FileShare.class, taskObj.getResource().getId(), taskObj.getOpId(), (ServiceCoded) ex);
} else {
this.fileService._dbClient.error(FileShare.class, taskObj.getResource().getId(), taskObj.getOpId(), InternalServerErrorException.internalServerErrors.unexpectedErrorVolumePlacement(ex));
}
_log.error(ex.getMessage(), ex);
taskObj.setMessage(ex.getMessage());
// Set the fileshare to inactive
FileShare file = this.fileService._dbClient.queryObject(FileShare.class, taskObj.getResource().getId());
file.setInactive(true);
this.fileService._dbClient.updateObject(file);
}
}
_log.info("Ending scheduling/placement thread...");
}
use of com.emc.storageos.model.TaskList in project coprhd-controller by CoprHD.
the class EventService method executeEventMethod.
/**
* Executes an actionable event method
*
* @param event the event to execute
* @param approve if true, the action is to approve, if false the action is to decline
* @return list of tasks
*/
public TaskList executeEventMethod(ActionableEvent event, boolean approve) {
TaskList taskList = new TaskList();
byte[] method = approve ? event.getApproveMethod() : event.getDeclineMethod();
String eventStatus = approve ? ActionableEvent.Status.approved.name() : ActionableEvent.Status.declined.name();
event.setEventExecutionTime(Calendar.getInstance());
event.setApproveDetails(new StringSet(getEventDetails(event, true)));
event.setDeclineDetails(new StringSet(getEventDetails(event, false)));
if (method == null || method.length == 0) {
_log.info("Method is null or empty for event " + event.getId());
event.setEventStatus(eventStatus);
_dbClient.updateObject(event);
return taskList;
}
ActionableEvent.Method eventMethod = ActionableEvent.Method.deserialize(method);
if (eventMethod == null) {
_log.info("Event method is null or empty for event " + event.getId());
event.setEventStatus(eventStatus);
_dbClient.updateObject(event);
return taskList;
}
try {
Method classMethod = getMethod(ActionableEventExecutor.class, eventMethod.getMethodName());
ComputeSystemController controller = getController(ComputeSystemController.class, null);
ActionableEventExecutor executor = new ActionableEventExecutor(_dbClient, controller);
Object[] parameters = Arrays.copyOf(eventMethod.getArgs(), eventMethod.getArgs().length + 1);
parameters[parameters.length - 1] = event.getId();
event.setEventStatus(eventStatus);
_dbClient.updateObject(event);
TaskResourceRep result = (TaskResourceRep) classMethod.invoke(executor, parameters);
if (result != null && result.getId() != null) {
Collection<String> taskCollection = Lists.newArrayList(result.getId().toString());
ActionableEvent updatedEvent = _dbClient.queryObject(ActionableEvent.class, event.getId());
updatedEvent.setTaskIds(new StringSet(taskCollection));
_dbClient.updateObject(updatedEvent);
}
taskList.addTask(result);
return taskList;
} catch (SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
_log.error(e.getMessage(), e.getCause());
throw APIException.badRequests.errorInvokingEventMethod(event.getId(), eventMethod.getMethodName());
}
}
use of com.emc.storageos.model.TaskList in project coprhd-controller by CoprHD.
the class VolumeGroupService method restoreVolumeGroupFullCopy.
/**
* Restore the specified Volume group full copy.
* - Restores full copy for all the array replication groups within this Application.
* - If partial flag is specified, it restores full copy only for set of array replication groups.
* A Full Copy from each array replication group can be provided to indicate which array replication
* groups's full copies needs to be restored.
*
* @prereq Create Volume group full copy as active.
*
* @param volumeGroupId The URI of the Volume group.
* @param fullCopyURI The URI of the full copy.
*
* @brief Restore Volume group full copy.
*
* @return TaskList
*/
@POST
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/{id}/protection/full-copies/restore")
@CheckPermission(roles = { Role.TENANT_ADMIN }, acls = { ACL.ANY })
public TaskList restoreVolumeGroupFullCopy(@PathParam("id") final URI volumeGroupId, final VolumeGroupFullCopyRestoreParam param) {
ArgValidator.checkFieldUriType(volumeGroupId, VolumeGroup.class, "id");
// Query Volume Group
final VolumeGroup volumeGroup = (VolumeGroup) queryResource(volumeGroupId);
TaskList taskList = new TaskList();
// validate replica operation for volume group
validateCopyOperationForVolumeGroup(volumeGroup, ReplicaTypeEnum.FULL_COPY);
// validate the requested full copies
List<Volume> fullCopyVolumesInRequest = new ArrayList<Volume>();
boolean partial = validateFullCopiesInRequest(fullCopyVolumesInRequest, param.getFullCopies(), param.getCopySetName(), param.getSubGroups(), volumeGroupId);
/**
* 1. VolumeGroupService Clone API accepts a Clone URI (to identify clone set and RG)
* - then get All full copies belonging to same full copy set
* - get full copy set name from the requested full copy
* 2. If partial, there will be a List of Clone URIs (one from each RG)
* 3. Group the full copies by Replication Group(RG)
* 4. For each RG, invoke the ConsistencyGroup full copy API (CG uri, clone uri)
* - a. Skip the CG/RG calls when thrown error and continue with other entries; create 'ERROR' Task for this call
* - b. Finally return the Task List (RG tasks may finish at different times as they are different calls)
*/
if (!partial) {
Volume fullCopy = fullCopyVolumesInRequest.get(0);
log.info("Full Copy operation requested for entire Application, Considering full copy {} in request.", fullCopy.getLabel());
fullCopyVolumesInRequest.clear();
fullCopyVolumesInRequest.addAll(getClonesBySetName(fullCopy.getFullCopySetName(), volumeGroup.getId()));
} else {
log.info("Full Copy operation requested for subset of array replication groups in Application.");
}
checkForApplicationPendingTasks(volumeGroup, _dbClient, true);
Map<String, Volume> repGroupToFullCopyMap = groupVolumesByReplicationGroup(fullCopyVolumesInRequest);
for (Map.Entry<String, Volume> entry : repGroupToFullCopyMap.entrySet()) {
String replicationGroup = entry.getKey();
Volume fullCopy = entry.getValue();
log.info("Processing Array Replication Group {}, Full Copy {}", replicationGroup, fullCopy.getLabel());
try {
// get CG URI
URI cgURI = getConsistencyGroupForFullCopy(fullCopy);
// Restore the full copy. Note that it will take into account the
// fact that the volume is in a ReplicationGroup
// and all volumes in that ReplicationGroup will be restored.
taskList.getTaskList().addAll(_blockConsistencyGroupService.restoreConsistencyGroupFullCopy(cgURI, fullCopy.getId()).getTaskList());
} catch (InternalException | APIException e) {
String errMsg = String.format("Error restoring Array Replication Group %s, Full Copy %s", replicationGroup, fullCopy.getLabel());
log.error(errMsg, e);
TaskResourceRep task = BlockServiceUtils.createFailedTaskOnVolume(_dbClient, fullCopy, ResourceOperationTypeEnum.RESTORE_VOLUME_FULL_COPY, e);
taskList.addTask(task);
}
}
if (!partial) {
auditOp(OperationTypeEnum.RESTORE_VOLUME_GROUP_FULL_COPY, true, AuditLogManager.AUDITOP_BEGIN, volumeGroup.getId().toString(), fullCopyVolumesInRequest.get(0).getLabel());
}
return taskList;
}
use of com.emc.storageos.model.TaskList in project coprhd-controller by CoprHD.
the class VolumeGroupService method performVolumeGroupSnapshotOperation.
/*
* Wrapper of BlockConsistencyGroupService methods for snapshot operations
*
* @param volumeGroupId
* @param param
* @return a TaskList
*/
private TaskList performVolumeGroupSnapshotOperation(final URI volumeGroupId, final VolumeGroupSnapshotOperationParam param, OperationTypeEnum opType) {
Map<String, List<BlockSnapshot>> snapsetToSnapshots = getSnapshotsGroupedBySnapset(volumeGroupId, param);
// validate that it's ok to do the snapshot operation
validateSnapshotOperation(volumeGroupId, snapsetToSnapshots, opType);
auditOp(opType, true, AuditLogManager.AUDITOP_BEGIN, volumeGroupId.toString(), param.getSnapshots());
TaskList taskList = new TaskList();
Set<Entry<String, List<BlockSnapshot>>> entrySet = snapsetToSnapshots.entrySet();
for (Entry<String, List<BlockSnapshot>> entry : entrySet) {
Table<URI, String, BlockSnapshot> storageRgToSnapshot = ControllerUtils.getSnapshotForStorageReplicationGroup(entry.getValue());
for (Cell<URI, String, BlockSnapshot> cell : storageRgToSnapshot.cellSet()) {
log.info("{} for replication group {}", opType.getDescription(), cell.getColumnKey());
try {
BlockSnapshot snapshot = cell.getValue();
URI cgUri = snapshot.getConsistencyGroup();
URI snapshotUri = snapshot.getId();
switch(opType) {
case ACTIVATE_VOLUME_GROUP_SNAPSHOT:
taskList.addTask(_blockConsistencyGroupService.activateConsistencyGroupSnapshot(cgUri, snapshotUri));
break;
case RESTORE_VOLUME_GROUP_SNAPSHOT:
taskList.addTask(_blockConsistencyGroupService.restoreConsistencyGroupSnapshot(cgUri, snapshotUri));
break;
case RESYNCHRONIZE_VOLUME_GROUP_SNAPSHOT:
taskList.addTask(_blockConsistencyGroupService.resynchronizeConsistencyGroupSnapshot(cgUri, snapshotUri));
break;
case DEACTIVATE_VOLUME_GROUP_SNAPSHOT:
TaskList cgTaskList = _blockConsistencyGroupService.deactivateConsistencyGroupSnapshot(cgUri, snapshotUri);
List<TaskResourceRep> taskResourceRepList = cgTaskList.getTaskList();
if (taskResourceRepList != null && !taskResourceRepList.isEmpty()) {
for (TaskResourceRep taskResRep : taskResourceRepList) {
taskList.addTask(taskResRep);
}
}
break;
default:
log.error("Unsupported operation {}", opType.getDescription());
break;
}
} catch (InternalException | APIException e) {
log.error("Exception on {} for replication group {}: {}", opType.getDescription(), cell.getColumnKey(), e.getMessage());
}
}
}
auditOp(opType, true, AuditLogManager.AUDITOP_END, volumeGroupId.toString(), param.getSnapshots());
return taskList;
}
Aggregations