Search in sources :

Example 1 with BlockServiceApi

use of com.emc.storageos.api.service.impl.resource.BlockServiceApi in project coprhd-controller by CoprHD.

the class ConsistencyGroupService method deleteConsistencyGroup.

/**
 * Delete consistency group
 *
 * @param openstackTenantId openstack tenant id
 * @param consistencyGroupId consistency group id
 * @param param pojo class to bind request
 * @param isV1Call cinder V1 api
 * @param header HTTP header
 * @brief delete Consistency group
 * @return Response
 */
@POST
@Path("/{consistencyGroup_id}/delete")
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response deleteConsistencyGroup(@PathParam("tenant_id") String openstackTenantId, @PathParam("consistencyGroup_id") String consistencyGroupId, ConsistencyGroupDeleteRequest param, @HeaderParam("X-Cinder-V1-Call") String isV1Call, @Context HttpHeaders header) {
    boolean isForced = param.consistencygroup.force;
    final BlockConsistencyGroup consistencyGroup = findConsistencyGroup(consistencyGroupId, openstackTenantId);
    if (consistencyGroup == null) {
        _log.error("Not Found : No Such Consistency Group Found {}", consistencyGroupId);
        return CinderApiUtils.createErrorResponse(404, "Not Found : No Such Consistency Group Found");
    } else if (!consistencyGroupId.equals(CinderApiUtils.splitString(consistencyGroup.getId().toString(), ":", 3))) {
        _log.error("Bad Request : There is no consistency group with id {} , please retry with correct consistency group id", consistencyGroupId);
        return CinderApiUtils.createErrorResponse(400, "Bad Request : There is no consistency group exist, please retry with correct consistency group id");
    }
    String task = UUID.randomUUID().toString();
    TaskResourceRep taskRep = null;
    if (getCinderHelper().verifyConsistencyGroupHasSnapshot(consistencyGroup)) {
        _log.error("Bad Request : Consistency Group {} has Snapshot", consistencyGroupId);
        return CinderApiUtils.createErrorResponse(400, "Bad Request : Consistency Group has Snapshot ");
    }
    if (isForced) {
        final URIQueryResultList cgVolumesResults = new URIQueryResultList();
        _dbClient.queryByConstraint(getVolumesByConsistencyGroup(consistencyGroup.getId()), cgVolumesResults);
        while (cgVolumesResults.iterator().hasNext()) {
            Volume volume = _dbClient.queryObject(Volume.class, cgVolumesResults.iterator().next());
            if (!volume.getInactive()) {
                BlockServiceApi api = BlockService.getBlockServiceImpl(volume, _dbClient);
                URI systemUri = volume.getStorageController();
                List<URI> volumeURIs = new ArrayList<URI>();
                volumeURIs.add(volume.getId());
                api.deleteVolumes(systemUri, volumeURIs, "FULL", null);
                if (volume.getExtensions() == null) {
                    volume.setExtensions(new StringMap());
                }
                volume.getExtensions().put("status", CinderConstants.ComponentStatus.DELETING.getStatus().toLowerCase());
                volume.setInactive(true);
                _dbClient.updateObject(volume);
            }
        }
    }
    try {
        ArgValidator.checkReference(BlockConsistencyGroup.class, consistencyGroup.getId(), checkForDelete(consistencyGroup));
    } catch (APIException e) {
        _log.error("Bad Request : Consistency Group Contains active references of type : {}", e.getMessage());
        return CinderApiUtils.createErrorResponse(400, "Bad Request : Consistency Group Contains active references");
    }
    // RP + VPlex CGs cannot be be deleted without VPlex controller intervention.
    if (!consistencyGroup.getTypes().contains(Types.VPLEX.toString()) || canDeleteConsistencyGroup(consistencyGroup)) {
        final URIQueryResultList cgVolumesResults = new URIQueryResultList();
        _dbClient.queryByConstraint(getVolumesByConsistencyGroup(consistencyGroup.getId()), cgVolumesResults);
        while (cgVolumesResults.iterator().hasNext()) {
            Volume volume = _dbClient.queryObject(Volume.class, cgVolumesResults.iterator().next());
            if (!volume.getInactive()) {
                return CinderApiUtils.createErrorResponse(400, "Bad Request : Try to delete consistency group with --force");
            }
        }
        consistencyGroup.setStorageController(null);
        consistencyGroup.setInactive(true);
        _dbClient.updateObject(consistencyGroup);
        taskRep = finishDeactivateTask(consistencyGroup, task);
        if (taskRep.getState().equals("ready") || taskRep.getState().equals("pending")) {
            return Response.status(202).build();
        }
    }
    final StorageSystem storageSystem = consistencyGroup.created() ? _permissionsHelper.getObjectById(consistencyGroup.getStorageController(), StorageSystem.class) : null;
    // If the consistency group has been created, and the system
    // is a VPlex, then we need to do VPlex related things to destroy
    // the consistency groups on the system. If the consistency group
    // has not been created on the system or the system is not a VPlex
    // revert to the default.
    BlockServiceApi blockServiceApi = BlockService.getBlockServiceImpl("group");
    if (storageSystem != null) {
        String systemType = storageSystem.getSystemType();
        if (DiscoveredDataObject.Type.vplex.name().equals(systemType)) {
            blockServiceApi = BlockService.getBlockServiceImpl(systemType);
        }
        _log.info(String.format("BlockConsistencyGroup %s is associated to StorageSystem %s. Going to delete it on that array.", consistencyGroup.getLabel(), storageSystem.getNativeGuid()));
        // Otherwise, invoke operation to delete CG from the array.
        taskRep = blockServiceApi.deleteConsistencyGroup(storageSystem, consistencyGroup, task);
        if (taskRep.getState().equals("ready") || taskRep.getState().equals("pending")) {
            return Response.status(202).build();
        }
    }
    if (taskRep == null) {
        _log.info(String.format("BlockConsistencyGroup %s was not associated with any storage. Deleting it from ViPR only.", consistencyGroup.getLabel()));
        TaskResourceRep resp = finishDeactivateTask(consistencyGroup, task);
        if (resp.getState().equals("ready") || resp.getState().equals("pending")) {
            return Response.status(202).build();
        }
    }
    return CinderApiUtils.createErrorResponse(400, "Bad Request");
}
Also used : StringMap(com.emc.storageos.db.client.model.StringMap) ArrayList(java.util.ArrayList) TaskResourceRep(com.emc.storageos.model.TaskResourceRep) BlockServiceApi(com.emc.storageos.api.service.impl.resource.BlockServiceApi) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) APIException(com.emc.storageos.svcs.errorhandling.resources.APIException) Volume(com.emc.storageos.db.client.model.Volume) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces)

Example 2 with BlockServiceApi

use of com.emc.storageos.api.service.impl.resource.BlockServiceApi 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");
    }
}
Also used : Volume(com.emc.storageos.db.client.model.Volume) TaskList(com.emc.storageos.model.TaskList) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) TaskResourceRep(com.emc.storageos.model.TaskResourceRep) Operation(com.emc.storageos.db.client.model.Operation) URI(java.net.URI) BlockServiceApi(com.emc.storageos.api.service.impl.resource.BlockServiceApi) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) Path(javax.ws.rs.Path) DELETE(javax.ws.rs.DELETE) Produces(javax.ws.rs.Produces) CheckPermission(com.emc.storageos.security.authorization.CheckPermission)

Example 3 with BlockServiceApi

use of com.emc.storageos.api.service.impl.resource.BlockServiceApi in project coprhd-controller by CoprHD.

the class ConsistencyGroupSnapshotService method createConsistencyGroupSnapshot.

/**
 * Create consistency group snapshot
 *
 * @param openstackTenantId
 *            openstack tenant Id
 * @param param
 *            Pojo class to bind request
 * @param isV1Call
 *            cinder V1 api
 * @param header
 *            HTTP header
 * @brief Create Consistency Group Snapshot
 * @return Response
 */
@POST
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response createConsistencyGroupSnapshot(@PathParam("tenant_id") String openstackTenantId, final ConsistencyGroupSnapshotCreateRequest param, @HeaderParam("X-Cinder-V1-Call") String isV1Call, @Context HttpHeaders header) {
    // Query Consistency Group
    final String consistencyGroupId = param.cgsnapshot.consistencygroup_id;
    final BlockConsistencyGroup consistencyGroup = findConsistencyGroup(consistencyGroupId, openstackTenantId);
    if (consistencyGroup == null) {
        _log.error("Not Found : No Such Consistency Group Found {}", consistencyGroupId);
        return CinderApiUtils.createErrorResponse(404, "Not Found : No Such Consistency Group Found");
    } else if (!consistencyGroupId.equals(CinderApiUtils.splitString(consistencyGroup.getId().toString(), ":", 3))) {
        _log.error("Bad Request : Invalid Snapshot Id {} : Please enter valid or full Id", consistencyGroupId);
        return CinderApiUtils.createErrorResponse(400, "Bad Request : No such consistency id exist, Please enter valid or full Id");
    }
    if (!isSnapshotCreationpermissible(consistencyGroup)) {
        _log.error("Bad Request : vpool not being configured for the snapshots creation");
        return CinderApiUtils.createErrorResponse(400, "Bad Request : vpool not being configured for the snapshots creation");
    }
    // system types.
    if (!consistencyGroup.created()) {
        CinderApiUtils.createErrorResponse(400, "No such consistency group created");
    }
    Project project = getCinderHelper().getProject(openstackTenantId, getUserFromContext());
    URI cgStorageControllerURI = consistencyGroup.getStorageController();
    if (!NullColumnValueGetter.isNullURI(cgStorageControllerURI)) {
        // No snapshots for VPLEX consistency groups.
        StorageSystem cgStorageController = _dbClient.queryObject(StorageSystem.class, cgStorageControllerURI);
        if ((DiscoveredDataObject.Type.vplex.name().equals(cgStorageController.getSystemType())) && (!consistencyGroup.checkForType(Types.LOCAL))) {
            CinderApiUtils.createErrorResponse(400, "can't create snapshot for VPLEX");
        }
    }
    // Get the block service implementation
    BlockServiceApi blockServiceApiImpl = getBlockServiceImpl(consistencyGroup);
    // Get the volumes in the consistency group.
    List<Volume> volumeList = blockServiceApiImpl.getActiveCGVolumes(consistencyGroup);
    _log.info("Active CG volume list : " + volumeList);
    // Generate task id
    String taskId = UUID.randomUUID().toString();
    // Set snapshot type.
    String snapshotType = BlockSnapshot.TechnologyType.NATIVE.toString();
    if (consistencyGroup.checkForType(BlockConsistencyGroup.Types.RP)) {
        snapshotType = BlockSnapshot.TechnologyType.RP.toString();
    } else if ((!volumeList.isEmpty()) && (volumeList.get(0).checkForSRDF())) {
        snapshotType = BlockSnapshot.TechnologyType.SRDF.toString();
    }
    // Determine the snapshot volume for RP.
    Volume snapVolume = null;
    if (consistencyGroup.checkForType(BlockConsistencyGroup.Types.RP)) {
        for (Volume volumeToSnap : volumeList) {
            // Get the RP source volume.
            if (volumeToSnap.getPersonality() != null && volumeToSnap.getPersonality().equals(Volume.PersonalityTypes.SOURCE.toString())) {
                snapVolume = volumeToSnap;
                break;
            }
        }
    } else if (!volumeList.isEmpty()) {
        // Any volume.
        snapVolume = volumeList.get(0);
    }
    // Set the create inactive flag.
    Boolean createInactive = Boolean.FALSE;
    Boolean readOnly = Boolean.FALSE;
    // Validate the snapshot request.
    String snapshotName = param.cgsnapshot.name;
    blockServiceApiImpl.validateCreateSnapshot(snapVolume, volumeList, snapshotType, snapshotName, readOnly, getFullCopyManager());
    // Prepare and create the snapshots for the group.
    List<URI> snapIdList = new ArrayList<URI>();
    List<BlockSnapshot> snapshotList = new ArrayList<BlockSnapshot>();
    TaskList response = new TaskList();
    snapshotList.addAll(blockServiceApiImpl.prepareSnapshots(volumeList, snapshotType, snapshotName, snapIdList, taskId));
    for (BlockSnapshot snapshot : snapshotList) {
        response.getTaskList().add(toTask(snapshot, taskId));
    }
    blockServiceApiImpl.createSnapshot(snapVolume, snapIdList, snapshotType, createInactive, readOnly, taskId);
    auditBlockConsistencyGroup(OperationTypeEnum.CREATE_CONSISTENCY_GROUP_SNAPSHOT, AuditLogManager.AUDITLOG_SUCCESS, AuditLogManager.AUDITOP_BEGIN, param.cgsnapshot.name, consistencyGroup.getId().toString());
    ConsistencyGroupSnapshotCreateResponse cgSnapshotCreateRes = new ConsistencyGroupSnapshotCreateResponse();
    for (TaskResourceRep rep : response.getTaskList()) {
        URI snapshotUri = rep.getResource().getId();
        BlockSnapshot snap = _dbClient.queryObject(BlockSnapshot.class, snapshotUri);
        snap.setId(snapshotUri);
        snap.setConsistencyGroup(consistencyGroup.getId());
        snap.setLabel(snapshotName);
        if (snap != null) {
            StringMap extensions = snap.getExtensions();
            if (extensions == null) {
                extensions = new StringMap();
            }
            extensions.put("status", CinderConstants.ComponentStatus.CREATING.getStatus().toLowerCase());
            extensions.put("taskid", rep.getId().toString());
            snap.setExtensions(extensions);
            ScopedLabelSet tagSet = new ScopedLabelSet();
            snap.setTag(tagSet);
            tagSet.add(new ScopedLabel(project.getTenantOrg().getURI().toString(), CinderApiUtils.splitString(snapshotUri.toString(), ":", 3)));
        }
        _dbClient.updateObject(snap);
        cgSnapshotCreateRes.id = CinderApiUtils.splitString(snapshotUri.toString(), ":", 3);
        cgSnapshotCreateRes.name = param.cgsnapshot.name;
    }
    return CinderApiUtils.getCinderResponse(cgSnapshotCreateRes, header, true, CinderConstants.STATUS_OK);
}
Also used : StringMap(com.emc.storageos.db.client.model.StringMap) TaskList(com.emc.storageos.model.TaskList) ArrayList(java.util.ArrayList) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) TaskResourceRep(com.emc.storageos.model.TaskResourceRep) URI(java.net.URI) BlockServiceApi(com.emc.storageos.api.service.impl.resource.BlockServiceApi) ScopedLabelSet(com.emc.storageos.db.client.model.ScopedLabelSet) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) Project(com.emc.storageos.db.client.model.Project) Volume(com.emc.storageos.db.client.model.Volume) ScopedLabel(com.emc.storageos.db.client.model.ScopedLabel) ConsistencyGroupSnapshotCreateResponse(com.emc.storageos.cinder.model.ConsistencyGroupSnapshotCreateResponse) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces)

Example 4 with BlockServiceApi

use of com.emc.storageos.api.service.impl.resource.BlockServiceApi 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();
}
Also used : StringMap(com.emc.storageos.db.client.model.StringMap) TaskList(com.emc.storageos.model.TaskList) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) ArrayList(java.util.ArrayList) TaskResourceRep(com.emc.storageos.model.TaskResourceRep) Operation(com.emc.storageos.db.client.model.Operation) URI(java.net.URI) BlockServiceApi(com.emc.storageos.api.service.impl.resource.BlockServiceApi) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) Volume(com.emc.storageos.db.client.model.Volume) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) Path(javax.ws.rs.Path) DELETE(javax.ws.rs.DELETE) Produces(javax.ws.rs.Produces) CheckPermission(com.emc.storageos.security.authorization.CheckPermission)

Example 5 with BlockServiceApi

use of com.emc.storageos.api.service.impl.resource.BlockServiceApi in project coprhd-controller by CoprHD.

the class SnapshotService method createSnapshot.

/**
 * The snapshot of a volume in Block Store is a point in time copy of the
 * volume. This API allows the user to create snapshot of a volume
 * NOTE: This is an asynchronous operation.
 *
 * @prereq none
 *
 * @param param
 *            POST data containing the snapshot creation information.
 *
 * @brief Create snapshot
 * @return Details of the newly created snapshot
 * @throws InternalException
 */
@POST
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response createSnapshot(@PathParam("tenant_id") String openstack_tenant_id, SnapshotCreateRequestGen param, @Context HttpHeaders header, @HeaderParam("X-Cinder-V1-Call") String isV1Call) throws InternalException {
    // Step 1: Parameter validation
    String snapshotName = null;
    String snapshotDescription = null;
    if (isV1Call != null) {
        snapshotName = param.snapshot.display_name;
        snapshotDescription = param.snapshot.display_description;
    } else {
        snapshotName = param.snapshot.name;
        snapshotDescription = param.snapshot.description;
    }
    // if snapshot name is empty create random name
    if (snapshotName == null) {
        snapshotName = "snapshot-" + RandomStringUtils.random(10);
    }
    if (snapshotName == null || (snapshotName.length() <= 2)) {
        throw APIException.badRequests.parameterIsNotValid(param.snapshot.name);
    }
    URI volumeUri = null;
    Volume volume = null;
    volumeUri = URI.create(param.snapshot.volume_id);
    volume = queryVolumeResource(volumeUri, openstack_tenant_id);
    if (volume == null) {
        _log.error("Invalid source volume id to create snapshot ={} ", param.snapshot.volume_id);
        return CinderApiUtils.createErrorResponse(404, "Not Found : Invalid source volume id " + param.snapshot.volume_id);
    }
    VirtualPool pool = _dbClient.queryObject(VirtualPool.class, volume.getVirtualPool());
    if (pool == null) {
        _log.info("Virtual Pool corresponding to the volume does not exist.");
        throw APIException.badRequests.parameterIsNotValid(volume.getVirtualPool().toString());
    }
    if (!validateSnapshotCreate(openstack_tenant_id, pool, volume.getProvisionedCapacity())) {
        _log.info("The volume can not be created because of insufficient quota for virtual pool.");
        throw APIException.badRequests.insufficientQuotaForVirtualPool(pool.getLabel(), "virtual pool");
    }
    if (!validateSnapshotCreate(openstack_tenant_id, null, volume.getProvisionedCapacity())) {
        _log.info("The volume can not be created because of insufficient quota for Project.");
        throw APIException.badRequests.insufficientQuotaForProject(pool.getLabel(), "project");
    }
    BlockFullCopyManager fcManager = new BlockFullCopyManager(_dbClient, _permissionsHelper, _auditMgr, _coordinator, _placementManager, sc, uriInfo, _request, _tenantsService);
    VolumeIngestionUtil.checkOperationSupportedOnIngestedVolume(volume, ResourceOperationTypeEnum.CREATE_VOLUME_SNAPSHOT, _dbClient);
    // Don't operate on VPLEX backend volumes or RP journal volumes.
    BlockServiceUtils.validateNotAnInternalBlockObject(volume, false);
    validateSourceVolumeHasExported(volume);
    String snapshotType = TechnologyType.NATIVE.toString();
    Boolean createInactive = Boolean.FALSE;
    Boolean readOnly = Boolean.FALSE;
    BlockServiceApi api = getBlockServiceImpl(pool, _dbClient);
    List<Volume> volumesToSnap = new ArrayList<Volume>();
    volumesToSnap.addAll(api.getVolumesToSnap(volume, snapshotType));
    api.validateCreateSnapshot(volume, volumesToSnap, snapshotType, snapshotName, readOnly, fcManager);
    String taskId = UUID.randomUUID().toString();
    List<URI> snapshotURIs = new ArrayList<URI>();
    List<BlockSnapshot> snapshots = api.prepareSnapshots(volumesToSnap, snapshotType, snapshotName, snapshotURIs, taskId);
    TaskList response = new TaskList();
    for (BlockSnapshot snapshot : snapshots) {
        response.getTaskList().add(toTask(snapshot, taskId));
    }
    // Update the task status for the volumes task.
    _dbClient.createTaskOpStatus(Volume.class, volume.getId(), taskId, ResourceOperationTypeEnum.CREATE_VOLUME_SNAPSHOT);
    // Invoke the block service API implementation to create the snapshot
    api.createSnapshot(volume, snapshotURIs, snapshotType, createInactive, readOnly, taskId);
    SnapshotCreateResponse snapCreateResp = new SnapshotCreateResponse();
    for (TaskResourceRep rep : response.getTaskList()) {
        URI snapshotUri = rep.getResource().getId();
        BlockSnapshot snap = _dbClient.queryObject(BlockSnapshot.class, snapshotUri);
        if (snap != null) {
            StringMap extensions = snap.getExtensions();
            if (extensions == null)
                extensions = new StringMap();
            extensions.put("display_description", (snapshotDescription == null) ? "" : snapshotDescription);
            extensions.put("taskid", rep.getId().toString());
            _log.debug("Create snapshot : stored description");
            snap.setExtensions(extensions);
            ScopedLabelSet tagSet = new ScopedLabelSet();
            snap.setTag(tagSet);
            String[] splits = snapshotUri.toString().split(":");
            String tagName = splits[3];
            // this check will verify whether  retrieved data is not corrupted
            if (tagName == null || tagName.isEmpty() || tagName.length() < 2) {
                throw APIException.badRequests.parameterTooShortOrEmpty("Tag", 2);
            }
            Volume parentVol = _permissionsHelper.getObjectById(snap.getParent(), Volume.class);
            URI tenantOwner = parentVol.getTenant().getURI();
            ScopedLabel tagLabel = new ScopedLabel(tenantOwner.toString(), tagName);
            tagSet.add(tagLabel);
            _dbClient.updateObject(snap);
            if (isV1Call != null) {
                _log.debug("Inside V1 call");
                return CinderApiUtils.getCinderResponse(getSnapshotDetail(snap, isV1Call, openstack_tenant_id), header, true, CinderConstants.STATUS_OK);
            } else {
                return CinderApiUtils.getCinderResponse(getSnapshotDetail(snap, isV1Call, openstack_tenant_id), header, true, CinderConstants.STATUS_ACCEPT);
            }
        }
    }
    return CinderApiUtils.getCinderResponse(new CinderSnapshot(), header, true, CinderConstants.STATUS_ACCEPT);
}
Also used : SnapshotCreateResponse(com.emc.storageos.cinder.model.SnapshotCreateResponse) StringMap(com.emc.storageos.db.client.model.StringMap) TaskList(com.emc.storageos.model.TaskList) ArrayList(java.util.ArrayList) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) TaskResourceRep(com.emc.storageos.model.TaskResourceRep) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) URI(java.net.URI) BlockServiceApi(com.emc.storageos.api.service.impl.resource.BlockServiceApi) ScopedLabelSet(com.emc.storageos.db.client.model.ScopedLabelSet) BlockFullCopyManager(com.emc.storageos.api.service.impl.resource.fullcopy.BlockFullCopyManager) CinderSnapshot(com.emc.storageos.cinder.model.CinderSnapshot) Volume(com.emc.storageos.db.client.model.Volume) ScopedLabel(com.emc.storageos.db.client.model.ScopedLabel) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces)

Aggregations

BlockServiceApi (com.emc.storageos.api.service.impl.resource.BlockServiceApi)9 Volume (com.emc.storageos.db.client.model.Volume)9 StringMap (com.emc.storageos.db.client.model.StringMap)8 URI (java.net.URI)8 Produces (javax.ws.rs.Produces)8 BlockSnapshot (com.emc.storageos.db.client.model.BlockSnapshot)6 TaskResourceRep (com.emc.storageos.model.TaskResourceRep)6 ArrayList (java.util.ArrayList)6 TaskList (com.emc.storageos.model.TaskList)5 Path (javax.ws.rs.Path)5 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)4 BlockConsistencyGroup (com.emc.storageos.db.client.model.BlockConsistencyGroup)4 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)4 VirtualPool (com.emc.storageos.db.client.model.VirtualPool)4 CheckPermission (com.emc.storageos.security.authorization.CheckPermission)4 Consumes (javax.ws.rs.Consumes)4 POST (javax.ws.rs.POST)4 BlockFullCopyManager (com.emc.storageos.api.service.impl.resource.fullcopy.BlockFullCopyManager)3 Operation (com.emc.storageos.db.client.model.Operation)3 Project (com.emc.storageos.db.client.model.Project)3