use of com.emc.storageos.db.client.model.Operation in project coprhd-controller by CoprHD.
the class ConsistencyGroupSnapshotService method deleteConsistencyGroupSnapshot.
/**
* Delete a consistency group snapshot
*
* @param openstackTenantId
* openstack tenant id
* @param consistencyGroupSnapshot_id
* consistency group snapshot id
* @brief Delete a consistency group snapshot
* @param isV1Call
* Cinder V1 call
* @param header
* Http Header
* @return Response
*/
@DELETE
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/{consistencyGroupSnapshot_id}")
@CheckPermission(roles = { Role.SYSTEM_MONITOR, Role.TENANT_ADMIN }, acls = { ACL.ANY })
public Response deleteConsistencyGroupSnapshot(@PathParam("tenant_id") String openstackTenantId, @PathParam("consistencyGroupSnapshot_id") String consistencyGroupSnapshot_id, @HeaderParam("X-Cinder-V1-Call") String isV1Call, @Context HttpHeaders header) {
final BlockSnapshot snapshot = findSnapshot(consistencyGroupSnapshot_id, openstackTenantId);
final URI snapshotCgURI = snapshot.getConsistencyGroup();
URIQueryResultList uris = getCinderHelper().getConsistencyGroupsUris(openstackTenantId, getUserFromContext());
boolean isConsistencyGroupHasSnapshotId = false;
if (uris != null && snapshotCgURI != null) {
for (URI blockCGUri : uris) {
BlockConsistencyGroup blockCG = _dbClient.queryObject(BlockConsistencyGroup.class, blockCGUri);
if (blockCG != null && !blockCG.getInactive()) {
if (snapshotCgURI.equals(blockCG.getId())) {
isConsistencyGroupHasSnapshotId = true;
}
}
}
}
if (isConsistencyGroupHasSnapshotId) {
// Generate task id
final String task = UUID.randomUUID().toString();
TaskList response = new TaskList();
// Not an error if the snapshot we try to delete is already deleted
if (snapshot.getInactive()) {
Operation op = new Operation();
op.ready("The consistency group snapshot has already been deactivated");
op.setResourceType(ResourceOperationTypeEnum.DELETE_CONSISTENCY_GROUP_SNAPSHOT);
_dbClient.createTaskOpStatus(BlockSnapshot.class, snapshot.getId(), task, op);
TaskResourceRep taskResponse = toTask(snapshot, task, op);
if (taskResponse.getState().equals("ready")) {
return Response.status(202).build();
}
}
Volume volume = _permissionsHelper.getObjectById(snapshot.getParent(), Volume.class);
BlockServiceApi blockServiceApiImpl = BlockService.getBlockServiceImpl(volume, _dbClient);
blockServiceApiImpl.deleteSnapshot(snapshot, Arrays.asList(snapshot), task, VolumeDeleteTypeEnum.FULL.name());
auditBlockConsistencyGroup(OperationTypeEnum.DELETE_CONSISTENCY_GROUP_SNAPSHOT, AuditLogManager.AUDITLOG_SUCCESS, AuditLogManager.AUDITOP_BEGIN, snapshot.getId().toString(), snapshot.getLabel());
return Response.status(202).build();
} else {
return CinderApiUtils.createErrorResponse(400, "Snapshot not attached to any active consistencygroup");
}
}
use of com.emc.storageos.db.client.model.Operation in project coprhd-controller by CoprHD.
the class SnapshotService method deleteSnapshot.
/**
* Delete a specific snapshot
*
* @prereq none
*
* @param tenant_id
* the URN of the tenant
* @param snapshot_id
* the URN of the snapshot
*
* @brief Delete Snapshot
* @return Task result
*/
@DELETE
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/{snapshot_id}")
@CheckPermission(roles = { Role.SYSTEM_MONITOR, Role.TENANT_ADMIN }, acls = { ACL.ANY })
public Response deleteSnapshot(@PathParam("tenant_id") String openstack_tenant_id, @PathParam("snapshot_id") String snapshot_id) {
_log.info("Delete Snapshot: id = {}", snapshot_id);
BlockSnapshot snap = findSnapshot(snapshot_id, openstack_tenant_id);
if (snap == null) {
_log.error("Not Found : Invalid volume snapshot id");
return CinderApiUtils.createErrorResponse(404, "Not Found : Invalid volume snapshot id");
} else if (snap.hasConsistencyGroup()) {
_log.error("Not Found : Snapshot belongs to a consistency group");
return CinderApiUtils.createErrorResponse(400, "Invalid snapshot: Snapshot belongs to consistency group");
}
URI snapshotURI = snap.getId();
String task = UUID.randomUUID().toString();
TaskList response = new TaskList();
ArgValidator.checkReference(BlockSnapshot.class, snapshotURI, checkForDelete(snap));
// Not an error if the snapshot we try to delete is already deleted
if (snap.getInactive()) {
Operation op = new Operation();
op.ready("The snapshot has already been deleted");
op.setResourceType(ResourceOperationTypeEnum.DELETE_VOLUME_SNAPSHOT);
_dbClient.createTaskOpStatus(BlockSnapshot.class, snap.getId(), task, op);
response.getTaskList().add(toTask(snap, task, op));
return Response.status(202).build();
}
StorageSystem device = _dbClient.queryObject(StorageSystem.class, snap.getStorageController());
List<BlockSnapshot> snapshots = new ArrayList<BlockSnapshot>();
final URI cgId = snap.getConsistencyGroup();
if (!NullColumnValueGetter.isNullURI(cgId)) {
// Collect all the BlockSnapshots if part of a CG.
URIQueryResultList results = new URIQueryResultList();
_dbClient.queryByConstraint(AlternateIdConstraint.Factory.getBlockSnapshotsBySnapsetLabel(snap.getSnapsetLabel()), results);
while (results.iterator().hasNext()) {
URI uri = results.iterator().next();
_log.info("BlockSnapshot being deactivated: " + uri);
BlockSnapshot snapshot = _dbClient.queryObject(BlockSnapshot.class, uri);
if (snapshot != null) {
snapshots.add(snapshot);
}
}
} else {
// Snap is not part of a CG so only delete the snap
snapshots.add(snap);
}
for (BlockSnapshot snapshot : snapshots) {
Operation snapOp = _dbClient.createTaskOpStatus(BlockSnapshot.class, snapshot.getId(), task, ResourceOperationTypeEnum.DELETE_VOLUME_SNAPSHOT);
response.getTaskList().add(toTask(snapshot, task, snapOp));
}
// Note that for snapshots of VPLEX volumes, the parent volume for the
// snapshot is the source side backend volume, which will have the same
// vpool as the VPLEX volume and therefore, the correct implementation
// should be returned.
Volume volume = _permissionsHelper.getObjectById(snap.getParent(), Volume.class);
BlockServiceApi blockServiceApiImpl = BlockService.getBlockServiceImpl(volume, _dbClient);
blockServiceApiImpl.deleteSnapshot(snap, snapshots, task, VolumeDeleteTypeEnum.FULL.name());
StringMap extensions = snap.getExtensions();
if (extensions == null) {
extensions = new StringMap();
}
for (TaskResourceRep rep : response.getTaskList()) {
extensions.put("taskid", rep.getId().toString());
break;
}
snap.setExtensions(extensions);
_dbClient.updateObject(snap);
auditOp(OperationTypeEnum.DELETE_VOLUME_SNAPSHOT, true, AuditLogManager.AUDITOP_BEGIN, snapshot_id, snap.getLabel(), snap.getParent().getName(), device.getId().toString());
return Response.status(202).build();
}
use of com.emc.storageos.db.client.model.Operation in project coprhd-controller by CoprHD.
the class VPlexBlockServiceApiImpl method importVirtualVolume.
/**
* Import an existing volume to a VPLEX to make it a Virtual Volume.
* Outline: 1. Determine the VPLEX(s) that could be used. 2. If this is to
* become a distributed virtual volume, get a Recommendation for the pool
* for the haVirtualArray of the Virtual Volume. 3. Create a Virtual Volume
* and link it to the existing Volume. 4. If this is a distributed virtual
* volume, create a new Volume and link it to the virtual volume. 5. Format
* the parameters and call the controller.
*
* @param arrayURI -- the URI of the Storage Array holding the existing
* Volume.
* @param importVolume -- An existing Volume that has been provisioned.
* @param vpool -- The vpool requested on the vpool change request.
* @param taskId -- The taskId
* @throws InternalException
*/
public void importVirtualVolume(URI arrayURI, Volume importVolume, VirtualPool vpool, String taskId) throws InternalException {
VirtualArray neighborhood = _dbClient.queryObject(VirtualArray.class, importVolume.getVirtualArray());
Project project = _dbClient.queryObject(Project.class, importVolume.getProject());
URI nullPoolURI = NullColumnValueGetter.getNullURI();
BlockConsistencyGroup consistencyGroup = null;
if (importVolume.getConsistencyGroup() != null) {
consistencyGroup = _dbClient.queryObject(BlockConsistencyGroup.class, importVolume.getConsistencyGroup());
}
// Determine the VPLEX(s) that could be used.
Set<URI> vplexes = ConnectivityUtil.getVPlexSystemsAssociatedWithArray(_dbClient, arrayURI);
Iterator<URI> vplexIter = vplexes.iterator();
while (vplexIter.hasNext()) {
StorageSystem vplex = _dbClient.queryObject(StorageSystem.class, vplexIter.next());
StringSet vplexVarrays = vplex.getVirtualArrays();
if ((vplexVarrays == null) || (vplexVarrays.isEmpty()) || (!vplexVarrays.contains(neighborhood.getId().toString()))) {
vplexIter.remove();
}
}
if (vplexes.isEmpty()) {
throw APIException.badRequests.noVPlexSystemsAssociatedWithStorageSystem(arrayURI);
}
// If distributed virtual volume, get a recommendation.
// Then create the volume.
List<VolumeDescriptor> descriptors = new ArrayList<VolumeDescriptor>();
URI vplexURI = null;
StorageSystem vplexSystem = null;
Volume createVolume = null;
Project vplexProject;
if (vpool.getHighAvailability().equals(VirtualPool.HighAvailabilityType.vplex_distributed.name())) {
// Determine if the user requested a specific HA VirtualArray and an associated HA VirtualPool.
VirtualArray requestedHaVarray = null;
VirtualPool requestedHaVirtualPool = vpool;
try {
if (vpool.getHaVarrayVpoolMap() != null && !vpool.getHaVarrayVpoolMap().isEmpty()) {
for (String haNH : vpool.getHaVarrayVpoolMap().keySet()) {
if (haNH.equals(NullColumnValueGetter.getNullURI().toString())) {
continue;
}
requestedHaVarray = _dbClient.queryObject(VirtualArray.class, new URI(haNH));
String haVirtualPool = vpool.getHaVarrayVpoolMap().get(haNH);
if (haVirtualPool.equals(NullColumnValueGetter.getNullURI().toString())) {
continue;
}
requestedHaVirtualPool = _dbClient.queryObject(VirtualPool.class, new URI(haVirtualPool));
break;
}
}
} catch (URISyntaxException ex) {
s_logger.error("URISyntaxException", ex);
}
VirtualPoolCapabilityValuesWrapper cosCapabilities = new VirtualPoolCapabilityValuesWrapper();
cosCapabilities.put(VirtualPoolCapabilityValuesWrapper.SIZE, getVolumeCapacity(importVolume));
cosCapabilities.put(VirtualPoolCapabilityValuesWrapper.RESOURCE_COUNT, new Integer(1));
cosCapabilities.put(VirtualPoolCapabilityValuesWrapper.THIN_PROVISIONING, importVolume.getThinlyProvisioned());
// Get the recommendations and pick one.
List<Recommendation> recommendations = getBlockScheduler().scheduleStorageForImport(neighborhood, vplexes, requestedHaVarray, requestedHaVirtualPool, cosCapabilities);
if (recommendations.isEmpty()) {
throw APIException.badRequests.noStorageFoundForVolumeMigration(requestedHaVirtualPool.getLabel(), requestedHaVarray.getLabel(), importVolume.getId());
}
Recommendation recommendation = recommendations.get(0);
VPlexRecommendation vplexRecommendation = (VPlexRecommendation) recommendation;
vplexURI = vplexRecommendation.getVPlexStorageSystem();
vplexSystem = _dbClient.queryObject(StorageSystem.class, vplexURI);
vplexProject = getVplexProject(vplexSystem, _dbClient, _tenantsService);
// Prepare the created volume.
VirtualArray haVirtualArray = _dbClient.queryObject(VirtualArray.class, vplexRecommendation.getVirtualArray());
createVolume = prepareVolumeForRequest(getVolumeCapacity(importVolume), vplexProject, haVirtualArray, vpool, vplexRecommendation.getSourceStorageSystem(), vplexRecommendation.getSourceStoragePool(), importVolume.getLabel() + "-1", ResourceOperationTypeEnum.CREATE_BLOCK_VOLUME, taskId, _dbClient);
createVolume.addInternalFlags(Flag.INTERNAL_OBJECT);
_dbClient.updateObject(createVolume);
VolumeDescriptor desc = new VolumeDescriptor(VolumeDescriptor.Type.BLOCK_DATA, createVolume.getStorageController(), createVolume.getId(), createVolume.getPool(), cosCapabilities);
descriptors.add(desc);
} else {
vplexURI = vplexes.toArray(new URI[0])[0];
vplexSystem = _dbClient.queryObject(StorageSystem.class, vplexURI);
vplexProject = getVplexProject(vplexSystem, _dbClient, _tenantsService);
}
// Prepare the VPLEX Virtual volume.
Volume vplexVolume = prepareVolumeForRequest(getVolumeCapacity(importVolume), project, neighborhood, vpool, vplexURI, nullPoolURI, importVolume.getLabel(), ResourceOperationTypeEnum.CREATE_BLOCK_VOLUME, taskId, _dbClient);
vplexVolume.setAssociatedVolumes(new StringSet());
vplexVolume.getAssociatedVolumes().add(importVolume.getId().toString());
if (createVolume != null) {
vplexVolume.getAssociatedVolumes().add(createVolume.getId().toString());
}
if (consistencyGroup != null) {
// If the volume being converted to a virtual volume has a CG, make the virtual
// volume a member of the CG.
vplexVolume.setConsistencyGroup(consistencyGroup.getId());
consistencyGroup.addRequestedTypes(Arrays.asList(BlockConsistencyGroup.Types.VPLEX.name()));
_dbClient.updateObject(consistencyGroup);
}
vplexVolume.setVirtualPool(vpool.getId());
_dbClient.updateObject(vplexVolume);
// Add a descriptor for the VPLEX_VIRT_VOLUME
VolumeDescriptor desc = new VolumeDescriptor(VolumeDescriptor.Type.VPLEX_VIRT_VOLUME, vplexURI, vplexVolume.getId(), null, null);
descriptors.add(desc);
// Add a descriptor for the import volume too!
desc = new VolumeDescriptor(VolumeDescriptor.Type.VPLEX_IMPORT_VOLUME, importVolume.getStorageController(), importVolume.getId(), importVolume.getPool(), null);
descriptors.add(desc);
// Now send the command to the controller.
try {
s_logger.info("Calling VPlex controller.");
VPlexController controller = getController();
controller.importVolume(vplexURI, descriptors, vplexProject.getId(), vplexProject.getTenantOrg().getURI(), vpool.getId(), importVolume.getLabel() + SRC_BACKEND_VOL_LABEL_SUFFIX, null, Boolean.TRUE, taskId);
} catch (InternalException ex) {
s_logger.error("ControllerException on importVolume", ex);
String errMsg = String.format("ControllerException: %s", ex.getMessage());
Operation statusUpdate = new Operation(Operation.Status.error.name(), errMsg);
_dbClient.updateTaskOpStatus(Volume.class, vplexVolume.getId(), taskId, statusUpdate);
_dbClient.markForDeletion(vplexVolume);
if (createVolume != null) {
_dbClient.markForDeletion(createVolume);
}
throw ex;
}
}
use of com.emc.storageos.db.client.model.Operation in project coprhd-controller by CoprHD.
the class VPlexBlockServiceApiImpl method prepareVolumeForRequest.
/**
* Prepare a new Bourne volume.
*
* TODO: Use existing function (prepareVolume) when VirtualPool capabilities change
* completed by Stalin. Just pass size instead of getting from VolumeCreate
* parameter.
*
* @param size The volume size.
* @param project A reference to the volume's Project.
* @param neighborhood A reference to the volume's varray.
* @param vpool A reference to the volume's VirtualPool.
* @param storageSystemURI The URI of the volume's storage system.
* @param storagePoolURI The URI of the volume's storage pool.
* @param label The volume label.
* @param token The task id for volume creation.
* @param dbClient A reference to a database client.
*
* @return A reference to the new volume.
*/
public static Volume prepareVolumeForRequest(Long size, Project project, VirtualArray neighborhood, VirtualPool vpool, URI storageSystemURI, URI storagePoolURI, String label, ResourceOperationTypeEnum opType, String token, DbClient dbClient) {
Volume volume = new Volume();
volume.setId(URIUtil.createId(Volume.class));
volume.setLabel(label);
volume.setCapacity(size);
volume.setThinlyProvisioned(VirtualPool.ProvisioningType.Thin.toString().equalsIgnoreCase(vpool.getSupportedProvisioningType()));
volume.setVirtualPool(vpool.getId());
volume.setProject(new NamedURI(project.getId(), volume.getLabel()));
volume.setTenant(new NamedURI(project.getTenantOrg().getURI(), volume.getLabel()));
volume.setVirtualArray(neighborhood.getId());
StoragePool storagePool = null;
if (!NullColumnValueGetter.getNullURI().toString().equals(storagePoolURI.toString())) {
storagePool = dbClient.queryObject(StoragePool.class, storagePoolURI);
if (null != storagePool) {
volume.setProtocol(new StringSet());
volume.getProtocol().addAll(VirtualPoolUtil.getMatchingProtocols(vpool.getProtocols(), storagePool.getProtocols()));
}
} else {
// Must be preparing a VPLEX volume which does not
// have a storage pool so a null URI is passed. Set
// the volume protocols to FC.
StringSet protocols = new StringSet();
protocols.add(StorageProtocol.Block.FC.name());
volume.setProtocol(protocols);
}
volume.setStorageController(storageSystemURI);
StorageSystem storageSystem = dbClient.queryObject(StorageSystem.class, storageSystemURI);
String systemType = storageSystem.checkIfVmax3() ? DiscoveredDataObject.Type.vmax3.name() : storageSystem.getSystemType();
volume.setSystemType(systemType);
volume.setPool(storagePoolURI);
volume.setOpStatus(new OpStatusMap());
// Set the auto tiering policy.
if (null != vpool.getAutoTierPolicyName()) {
URI autoTierPolicyUri = StorageScheduler.getAutoTierPolicy(storagePoolURI, vpool.getAutoTierPolicyName(), dbClient);
if (null != autoTierPolicyUri) {
volume.setAutoTieringPolicyUri(autoTierPolicyUri);
}
}
if (opType != null) {
Operation op = new Operation();
op.setResourceType(opType);
volume.getOpStatus().createTaskStatus(token, op);
}
dbClient.createObject(volume);
return volume;
}
use of com.emc.storageos.db.client.model.Operation in project coprhd-controller by CoprHD.
the class VPlexBlockServiceApiImpl method preparePromotedVolumes.
/**
* This method creates volume objects for the copiesToStop which will used as
* independent virtual volumes if detach mirror action completes successfully.
*/
private List<URI> preparePromotedVolumes(List<VplexMirror> copiesToStop, TaskList taskList, String opId) {
List<URI> promotedVolumes = new ArrayList<URI>();
for (VplexMirror copy : copiesToStop) {
Volume v = new Volume();
v.setId(URIUtil.createId(Volume.class));
Volume sourceVplexVolume = _dbClient.queryObject(Volume.class, copy.getSource());
String promotedLabel = String.format("%s-%s", sourceVplexVolume.getLabel(), copy.getLabel());
v.setProject(new NamedURI(copy.getProject().getURI(), promotedLabel));
StringSet protocols = new StringSet();
protocols.add(StorageProtocol.Block.FC.name());
v.setProtocol(protocols);
v.setTenant(new NamedURI(copy.getTenant().getURI(), promotedLabel));
_dbClient.createObject(v);
Operation op = _dbClient.createTaskOpStatus(Volume.class, v.getId(), opId, ResourceOperationTypeEnum.PROMOTE_COPY_TO_VPLEX, copy.getId().toString());
taskList.getTaskList().add(toTask(v, Arrays.asList(copy), opId, op));
promotedVolumes.add(v.getId());
}
return promotedVolumes;
}
Aggregations