use of com.emc.storageos.model.TaskResourceRep in project coprhd-controller by CoprHD.
the class BlockConsistencyGroupService method deleteConsistencyGroup.
/**
* Deletes a consistency group
*
* Do not delete if snapshots exist for consistency group
*
* @prereq Dependent snapshot resources must be deleted
*
* @param id the URN of a ViPR Consistency group
*
* @brief Delete consistency group
* @return TaskResourceRep
*
* @throws InternalException
*/
@POST
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/{id}/deactivate")
@CheckPermission(roles = { Role.TENANT_ADMIN }, acls = { ACL.OWN, ACL.ALL })
public TaskResourceRep deleteConsistencyGroup(@PathParam("id") final URI id, @DefaultValue("FULL") @QueryParam("type") String type) throws InternalException {
// Query for the given consistency group and verify it is valid.
final BlockConsistencyGroup consistencyGroup = (BlockConsistencyGroup) queryResource(id);
ArgValidator.checkReference(BlockConsistencyGroup.class, id, checkForDelete(consistencyGroup));
// Create a unique task identifier.
String task = UUID.randomUUID().toString();
// So, we do need to verify that no volumes reference the CG.
if (deletingUncreatedConsistencyGroup(consistencyGroup) || VolumeDeleteTypeEnum.VIPR_ONLY.name().equals(type)) {
markCGForDeletion(consistencyGroup);
return finishDeactivateTask(consistencyGroup, task);
}
// Otherwise, we need to clean up the array consistency groups.
TaskResourceRep taskRep = null;
try {
List<StorageSystem> vplexSystems = BlockConsistencyGroupUtils.getVPlexStorageSystems(consistencyGroup, _dbClient);
if (!vplexSystems.isEmpty()) {
// If there is a VPLEX system, then we simply call the VPLEX controller which
// will delete all VPLEX CGS on all VPLEX systems, and also all local CGs on
// all local systems.
BlockServiceApi blockServiceApi = getBlockServiceImpl(DiscoveredDataObject.Type.vplex.name());
taskRep = blockServiceApi.deleteConsistencyGroup(vplexSystems.get(0), consistencyGroup, task);
} else {
// Otherwise, we call the block controller to delete the local CGs on all local systems.
List<URI> localSystemURIs = BlockConsistencyGroupUtils.getLocalSystems(consistencyGroup, _dbClient);
if (!localSystemURIs.isEmpty()) {
boolean foundSystem = false;
for (URI localSystemURI : localSystemURIs) {
StorageSystem localSystem = _dbClient.queryObject(StorageSystem.class, localSystemURI);
if (localSystem != null) {
foundSystem = true;
BlockServiceApi blockServiceApi = getBlockServiceImpl(BLOCKSERVICEAPIIMPL_GROUP);
taskRep = blockServiceApi.deleteConsistencyGroup(localSystem, consistencyGroup, task);
if (Task.Status.error.name().equals(taskRep.getState())) {
break;
}
} else {
_log.warn("Local system {} for consistency group {} does not exist", localSystemURI, consistencyGroup.getLabel());
}
}
// Check to make sure we found at least one of these local systems.
if (!foundSystem) {
// For some reason we have a CG with local systems, but none of them
// are in the database. In this case, we will log a warning and mark
// it for deletion.
_log.warn("Deleting created consistency group {} where none of the local systems for the group exist", consistencyGroup.getLabel());
markCGForDeletion(consistencyGroup);
return finishDeactivateTask(consistencyGroup, task);
}
} else {
// For some reason the CG has no VPLEX or local systems but is
// marked as being active and created. In this case, we will log
// a warning and mark it for deletion.
_log.info("Deleting created consistency group {} with no local or VPLEX systems", consistencyGroup.getLabel());
markCGForDeletion(consistencyGroup);
return finishDeactivateTask(consistencyGroup, task);
}
}
} catch (APIException | InternalException e) {
String errorMsg = String.format("Exception attempting to delete consistency group %s: %s", consistencyGroup.getLabel(), e.getMessage());
_log.error(errorMsg);
taskRep.setState(Operation.Status.error.name());
taskRep.setMessage(errorMsg);
_dbClient.error(BlockConsistencyGroup.class, taskRep.getResource().getId(), task, e);
} catch (Exception e) {
String errorMsg = String.format("Exception attempting to delete consistency group %s: %s", consistencyGroup.getLabel(), e.getMessage());
_log.error(errorMsg);
APIException apie = APIException.internalServerErrors.genericApisvcError(errorMsg, e);
taskRep.setState(Operation.Status.error.name());
taskRep.setMessage(apie.getMessage());
_dbClient.error(BlockConsistencyGroup.class, taskRep.getResource().getId(), task, apie);
}
// the request was successful.
if (Task.Status.ready.name().equals(taskRep.getState())) {
markCGForDeletion(consistencyGroup);
}
return taskRep;
}
use of com.emc.storageos.model.TaskResourceRep in project coprhd-controller by CoprHD.
the class BlockConsistencyGroupService method failoverProtection.
/**
* Request to failover the protection link associated with the copy. The target
* copy is specified by identifying the virtual array in param.copyId.
*
* NOTE: This is an asynchronous operation.
*
* If volume is srdf protected, then invoking failover internally triggers
* SRDF SWAP on volume pairs.
*
* @prereq none
*
* @param id the URI of a BlockConsistencyGroup
* @param param Copy to failover to
*
* @brief Failover the protection link
* @return TaskList
*
* @throws ControllerException
*/
@POST
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/{id}/protection/continuous-copies/failover")
@CheckPermission(roles = { Role.TENANT_ADMIN }, acls = { ACL.OWN, ACL.ALL })
public TaskList failoverProtection(@PathParam("id") URI id, CopiesParam param) throws ControllerException {
TaskResourceRep taskResp = null;
TaskList taskList = new TaskList();
// Validate the consistency group URI
ArgValidator.checkFieldUriType(id, BlockConsistencyGroup.class, "id");
// Validate the list of copies
ArgValidator.checkFieldNotEmpty(param.getCopies(), "copies");
// Query Consistency Group
final BlockConsistencyGroup consistencyGroup = (BlockConsistencyGroup) queryResource(id);
// system types.
if (!consistencyGroup.created()) {
throw APIException.badRequests.consistencyGroupNotCreated();
}
List<Copy> copies = param.getCopies();
if (copies.size() > 1) {
throw APIException.badRequests.failoverCopiesParamCanOnlyBeOne();
}
Copy copy = copies.get(0);
ArgValidator.checkFieldUriType(copy.getCopyID(), VirtualArray.class, "copyId");
ArgValidator.checkFieldNotEmpty(copy.getType(), "type");
if (TechnologyType.RP.name().equalsIgnoreCase(copy.getType())) {
taskResp = performProtectionAction(id, copy, ProtectionOp.FAILOVER.getRestOp());
taskList.getTaskList().add(taskResp);
} else if (TechnologyType.SRDF.name().equalsIgnoreCase(copy.getType())) {
taskResp = performSRDFProtectionAction(id, copy, ProtectionOp.FAILOVER.getRestOp());
taskList.getTaskList().add(taskResp);
} else {
throw APIException.badRequests.invalidCopyType(copy.getType());
}
return taskList;
}
use of com.emc.storageos.model.TaskResourceRep in project coprhd-controller by CoprHD.
the class BlockMirrorServiceApiImpl method deactivateMirror.
/**
* {@inheritDoc}
*
* @throws ControllerException
*/
@SuppressWarnings("unchecked")
@Override
public TaskList deactivateMirror(StorageSystem storageSystem, URI mirrorURI, String taskId, String deleteType) throws ControllerException {
_log.info("START: deactivate mirror");
TaskList taskList = new TaskList();
BlockMirror mirror = _dbClient.queryObject(BlockMirror.class, mirrorURI);
Volume sourceVolume = _dbClient.queryObject(Volume.class, mirror.getSource().getURI());
List<URI> mirrorURIs = new ArrayList<URI>();
boolean isCG = sourceVolume.isInCG();
List<URI> promotees = null;
if (isCG) {
// for group mirrors, deactivate task will detach and delete the mirror that user asked to deactivate, and
// promote other mirrors
// in the group
Map<BlockMirror, Volume> groupMirrorSourceMap = getGroupMirrorSourceMap(mirror, sourceVolume);
mirrorURIs = new ArrayList<URI>(transform(new ArrayList<BlockMirror>(groupMirrorSourceMap.keySet()), FCTN_MIRROR_TO_URI));
if (VolumeDeleteTypeEnum.VIPR_ONLY.name().equals(deleteType)) {
// Create a task for each source/mirror pair.
for (Entry<BlockMirror, Volume> entry : groupMirrorSourceMap.entrySet()) {
Operation op = _dbClient.createTaskOpStatus(Volume.class, entry.getValue().getId(), taskId, ResourceOperationTypeEnum.DEACTIVATE_VOLUME_MIRROR, entry.getKey().getId().toString());
taskList.getTaskList().add(toTask(entry.getValue(), Arrays.asList(entry.getKey()), taskId, op));
}
} else {
// deactivate (detach and delete) mirrorURI
Operation op = _dbClient.createTaskOpStatus(Volume.class, sourceVolume.getId(), taskId, ResourceOperationTypeEnum.DEACTIVATE_VOLUME_MIRROR, mirrorURI.toString());
taskList.getTaskList().add(toTask(sourceVolume, Arrays.asList(mirror), taskId, op));
// detach and promote other mirrors in the group
groupMirrorSourceMap.remove(mirror);
populateTaskList(sourceVolume, groupMirrorSourceMap, taskList, taskId, ResourceOperationTypeEnum.DETACH_BLOCK_MIRROR);
// detached mirrors (except the one deleted), will be promoted to regular block volumes
promotees = preparePromotedVolumes(new ArrayList<BlockMirror>(groupMirrorSourceMap.keySet()), taskList, taskId);
}
} else {
// for single volume mirror, deactivate task will detach and delete the mirror
mirrorURIs = Arrays.asList(mirror.getId());
Operation op = _dbClient.createTaskOpStatus(Volume.class, sourceVolume.getId(), taskId, ResourceOperationTypeEnum.DEACTIVATE_VOLUME_MIRROR, mirror.getId().toString());
taskList.getTaskList().add(toTask(sourceVolume, Arrays.asList(mirror), taskId, op));
}
try {
if (VolumeDeleteTypeEnum.VIPR_ONLY.name().equals(deleteType)) {
_log.info("Perform ViPR-only delete for mirrors %s", mirrorURIs);
// Perform any database cleanup that is required.
cleanupForViPROnlyMirrorDelete(mirrorURIs);
// Mark them inactive.
_dbClient.markForDeletion(_dbClient.queryObject(BlockMirror.class, mirrorURIs));
// Update the task status for each snapshot to successfully completed.
for (TaskResourceRep taskResourceRep : taskList.getTaskList()) {
Volume taskVolume = _dbClient.queryObject(Volume.class, taskResourceRep.getResource().getId());
Operation op = taskVolume.getOpStatus().get(taskId);
op.ready("Continuous copy succesfully deleted from ViPR");
taskVolume.getOpStatus().updateTaskStatus(taskId, op);
_dbClient.updateObject(taskVolume);
}
} else {
BlockController controller = getController(BlockController.class, storageSystem.getSystemType());
controller.deactivateMirror(storageSystem.getId(), mirrorURIs, promotees, isCG, taskId);
}
} catch (ControllerException e) {
String errorMsg = format("Failed to deactivate continuous copy %s: %s", mirror.getId().toString(), e.getMessage());
_log.error(errorMsg);
for (TaskResourceRep taskResourceRep : taskList.getTaskList()) {
taskResourceRep.setState(Operation.Status.error.name());
taskResourceRep.setMessage(errorMsg);
_dbClient.error(URIUtil.getModelClass(taskResourceRep.getResource().getId()), taskResourceRep.getResource().getId(), taskId, e);
}
// Mark the mirrors that would have been promoted inactive.
if (promotees != null && !promotees.isEmpty()) {
List<Volume> volumes = _dbClient.queryObject(Volume.class, promotees);
for (Volume volume : volumes) {
volume.setInactive(true);
}
_dbClient.updateObject(volumes);
}
} catch (Exception e) {
String errorMsg = format("Failed to deactivate continuous copy %s: %s", mirror.getId().toString(), e.getMessage());
_log.error(errorMsg);
ServiceCoded sc = APIException.internalServerErrors.genericApisvcError(errorMsg, e);
for (TaskResourceRep taskResourceRep : taskList.getTaskList()) {
taskResourceRep.setState(Operation.Status.error.name());
taskResourceRep.setMessage(sc.getMessage());
_dbClient.error(URIUtil.getModelClass(taskResourceRep.getResource().getId()), taskResourceRep.getResource().getId(), taskId, sc);
}
// Mark the mirrors that would have been promoted inactive.
if (promotees != null && !promotees.isEmpty()) {
List<Volume> volumes = _dbClient.queryObject(Volume.class, promotees);
for (Volume volume : volumes) {
volume.setInactive(true);
}
_dbClient.updateObject(volumes);
}
}
return taskList;
}
use of com.emc.storageos.model.TaskResourceRep in project coprhd-controller by CoprHD.
the class BlockMirrorServiceApiImpl method startNativeContinuousCopies.
@Override
public TaskList startNativeContinuousCopies(StorageSystem storageSystem, Volume sourceVolume, VirtualPool sourceVirtualPool, VirtualPoolCapabilityValuesWrapper capabilities, NativeContinuousCopyCreate param, String taskId) throws ControllerException {
if (!((storageSystem.getUsingSmis80() && storageSystem.deviceIsType(Type.vmax)) || storageSystem.deviceIsType(Type.vnxblock))) {
validateNotAConsistencyGroupVolume(sourceVolume, sourceVirtualPool);
}
TaskList taskList = new TaskList();
// Currently, this will create a single mirror and add it to the source volume
// Two steps: first place the mirror and then prepare the mirror.
List<Recommendation> volumeRecommendations = new ArrayList<Recommendation>();
// Prepare mirror.
int volumeCounter = 1;
int volumeCount = capabilities.getResourceCount();
String volumeLabel = param.getName();
List<Volume> preparedVolumes = new ArrayList<Volume>();
// If the requested volume is part of CG
if (sourceVolume.isInCG()) {
if (volumeCount > 1) {
throw APIException.badRequests.invalidMirrorCountForVolumesInConsistencyGroup();
}
URIQueryResultList cgVolumeList = new URIQueryResultList();
_dbClient.queryByConstraint(ContainmentConstraint.Factory.getVolumesByConsistencyGroup(sourceVolume.getConsistencyGroup()), cgVolumeList);
// recommendation
while (cgVolumeList.iterator().hasNext()) {
Volume cgSourceVolume = _dbClient.queryObject(Volume.class, cgVolumeList.iterator().next());
_log.info("Processing volume {} in CG {}", cgSourceVolume.getId(), sourceVolume.getConsistencyGroup());
VirtualPool cgVolumeVPool = _dbClient.queryObject(VirtualPool.class, cgSourceVolume.getVirtualPool());
populateVolumeRecommendations(capabilities, cgVolumeVPool, cgSourceVolume, taskId, taskList, volumeCount, volumeCounter, volumeLabel, preparedVolumes, volumeRecommendations);
}
} else {
// Source Volume without CG
populateVolumeRecommendations(capabilities, sourceVirtualPool, sourceVolume, taskId, taskList, volumeCount, volumeCounter, volumeLabel, preparedVolumes, volumeRecommendations);
}
List<URI> mirrorList = new ArrayList<URI>(preparedVolumes.size());
for (Volume volume : preparedVolumes) {
Operation op = _dbClient.createTaskOpStatus(BlockMirror.class, volume.getId(), taskId, ResourceOperationTypeEnum.ATTACH_BLOCK_MIRROR);
volume.getOpStatus().put(taskId, op);
TaskResourceRep volumeTask = toTask(volume, taskId, op);
taskList.getTaskList().add(volumeTask);
mirrorList.add(volume.getId());
}
BlockController controller = getController(BlockController.class, storageSystem.getSystemType());
try {
controller.attachNativeContinuousCopies(storageSystem.getId(), sourceVolume.getId(), mirrorList, taskId);
} catch (ControllerException ce) {
String errorMsg = format("Failed to start continuous copies on volume %s: %s", sourceVolume.getId(), ce.getMessage());
_log.error(errorMsg, ce);
for (TaskResourceRep taskResourceRep : taskList.getTaskList()) {
taskResourceRep.setState(Operation.Status.error.name());
taskResourceRep.setMessage(errorMsg);
Operation statusUpdate = new Operation(Operation.Status.error.name(), errorMsg);
_dbClient.updateTaskOpStatus(Volume.class, taskResourceRep.getResource().getId(), taskId, statusUpdate);
}
throw ce;
}
return taskList;
}
use of com.emc.storageos.model.TaskResourceRep in project coprhd-controller by CoprHD.
the class BlockService method stopContinuousCopies.
/**
* Stop continuous copies.
*
* @prereq none
*
* @param id
* the URN of a ViPR Source volume
* @param param
* List of copies to stop
*
* @brief Stop continuous copies.
* @return TaskList
*
* @throws ControllerException
*/
@POST
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/{id}/protection/continuous-copies/stop")
@CheckPermission(roles = { Role.TENANT_ADMIN }, acls = { ACL.OWN, ACL.ALL })
public TaskList stopContinuousCopies(@PathParam("id") URI id, CopiesParam param) throws ControllerException {
TaskResourceRep taskResp = null;
TaskList taskList = new TaskList();
// Validate the source volume URI
ArgValidator.checkFieldUriType(id, Volume.class, "id");
Volume volume = _dbClient.queryObject(Volume.class, id);
// Make sure that we don't have some pending
// operation against the volume
checkForPendingTasks(Arrays.asList(volume.getTenant().getURI()), Arrays.asList(volume));
boolean vplexVolume = checkIfVolumeIsForVplex(id);
// Validate the list of copies
ArgValidator.checkFieldNotEmpty(param.getCopies(), "copies");
// Verify that the copy IDs are either all specified or none are specified
// for a particular protection type. Combinations are not allowed
verifyCopyIDs(param);
// Validate for SRDF Stop operation
validateSRDFStopOperation(id, param);
// Process the list of copies
for (Copy copy : param.getCopies()) {
// If copyID is not set all copies are stopped
URI copyID = copy.getCopyID();
if (!URIUtil.isValid(copyID)) {
copyID = null;
}
// Validate a copy type was passed
ArgValidator.checkFieldNotEmpty(copy.getType(), "type");
// If copyID is null all copies are stopped
if (copy.getType().equalsIgnoreCase(TechnologyType.RP.toString())) {
taskResp = performProtectionAction(id, copy, ProtectionOp.STOP.getRestOp());
taskList.getTaskList().add(taskResp);
} else if (!vplexVolume && copy.getType().equalsIgnoreCase(TechnologyType.NATIVE.toString())) {
taskList = stopMirrors(id, copyID);
} else if (vplexVolume && copy.getType().equalsIgnoreCase(TechnologyType.NATIVE.toString())) {
taskList = stopVplexMirrors(id, copyID);
} else if (copy.getType().equalsIgnoreCase(TechnologyType.SRDF.toString())) {
id = VPlexSrdfUtil.getSrdfIdFromVolumeId(_dbClient, id);
copy.setCopyID(VPlexSrdfUtil.getSrdfIdFromVolumeId(_dbClient, copy.getCopyID()));
taskResp = performSRDFProtectionAction(id, copy, ProtectionOp.STOP.getRestOp());
taskList.getTaskList().add(taskResp);
} else {
throw APIException.badRequests.invalidCopyType(copy.getType());
}
// If copyID is null, we have already stopped all copies
if (copyID == null) {
return taskList;
}
}
return taskList;
}
Aggregations