Search in sources :

Example 56 with BlockSnapshot

use of com.emc.storageos.db.client.model.BlockSnapshot 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 57 with BlockSnapshot

use of com.emc.storageos.db.client.model.BlockSnapshot in project coprhd-controller by CoprHD.

the class VPlexBlockServiceApiImpl method changeVirtualArrayForVolumes.

/**
 * {@inheritDoc}
 */
@Override
public void changeVirtualArrayForVolumes(List<Volume> volumes, BlockConsistencyGroup cg, List<Volume> cgVolumes, VirtualArray newVirtualArray, String taskId) throws InternalException {
    // if they remove the snapshots, they can perform the varray change.
    for (Volume volume : volumes) {
        List<BlockSnapshot> snapshots = getSnapshots(volume);
        if (!snapshots.isEmpty()) {
            for (BlockSnapshot snapshot : snapshots) {
                if (!snapshot.getInactive()) {
                    throw APIException.badRequests.volumeForVarrayChangeHasSnaps(volume.getId().toString());
                }
            }
        }
        // If the volume has mirrors then varray change will not
        // be allowed. User needs to explicitly delete mirrors first.
        // This is applicable for both Local and Distributed volumes.
        // For distributed volume getMirrors will get mirror if any
        // on source or HA side.
        StringSet mirrorURIs = volume.getMirrors();
        if (mirrorURIs != null && !mirrorURIs.isEmpty()) {
            List<VplexMirror> mirrors = _dbClient.queryObject(VplexMirror.class, StringSetUtil.stringSetToUriList(mirrorURIs));
            if (mirrors != null && !mirrors.isEmpty()) {
                throw APIException.badRequests.volumeForVarrayChangeHasMirrors(volume.getId().toString(), volume.getLabel());
            }
        }
    }
    // vpool change.
    if ((cg != null) && (volumes.size() > _maxCgVolumesForMigration)) {
        throw APIException.badRequests.cgContainsTooManyVolumesForVArrayChange(cg.getLabel(), volumes.size(), _maxCgVolumesForMigration);
    }
    // we don't allow the varray change.
    if ((cg != null) && (cg.checkForType(Types.LOCAL)) && (cgVolumes.size() > 1)) {
        verifyTargetSystemsForCGDataMigration(volumes, null, newVirtualArray.getId());
    }
    // Create the volume descriptors for the virtual array change.
    List<VolumeDescriptor> descriptors = createVolumeDescriptorsForVarrayChange(volumes, newVirtualArray, taskId);
    try {
        // Orchestrate the virtual array change.
        BlockOrchestrationController controller = getController(BlockOrchestrationController.class, BlockOrchestrationController.BLOCK_ORCHESTRATION_DEVICE);
        controller.changeVirtualArray(descriptors, taskId);
        s_logger.info("Successfully invoked block orchestrator.");
    } catch (InternalException e) {
        s_logger.error("Controller error", e);
        for (VolumeDescriptor descriptor : descriptors) {
            // migration targets and migrations.
            if (VolumeDescriptor.Type.VPLEX_MIGRATE_VOLUME.equals(descriptor.getType())) {
                _dbClient.error(Volume.class, descriptor.getVolumeURI(), taskId, e);
                _dbClient.error(Migration.class, descriptor.getMigrationId(), taskId, e);
            }
        }
        throw e;
    }
}
Also used : VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) BlockOrchestrationController(com.emc.storageos.blockorchestrationcontroller.BlockOrchestrationController) Volume(com.emc.storageos.db.client.model.Volume) Migration(com.emc.storageos.db.client.model.Migration) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) StringSet(com.emc.storageos.db.client.model.StringSet) VplexMirror(com.emc.storageos.db.client.model.VplexMirror) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException)

Example 58 with BlockSnapshot

use of com.emc.storageos.db.client.model.BlockSnapshot in project coprhd-controller by CoprHD.

the class VPlexBlockServiceApiImpl method updateConsistencyGroup.

/**
 * {@inheritDoc}
 */
@Override
public TaskResourceRep updateConsistencyGroup(StorageSystem cgStorageSystem, List<Volume> cgVolumes, BlockConsistencyGroup consistencyGroup, List<URI> addVolumesList, List<URI> removeVolumesList, String taskId) throws ControllerException {
    // addVolumesList could be volumes, or full copies, or snapshots or mirrors.
    List<URI> addVolumes = new ArrayList<URI>();
    List<URI> addSnapshots = new ArrayList<URI>();
    List<URI> addFullcopies = new ArrayList<URI>();
    for (URI volumeURI : addVolumesList) {
        BlockObject blockObject = BlockObject.fetch(_dbClient, volumeURI);
        if (blockObject instanceof BlockMirror) {
            throw APIException.badRequests.actionNotApplicableForVplexVolumeMirrors(ResourceOperationTypeEnum.UPDATE_CONSISTENCY_GROUP.name());
        } else if (blockObject instanceof BlockSnapshot) {
            addSnapshots.add(volumeURI);
        } else if (blockObject instanceof Volume) {
            boolean isFullCopy = ControllerUtils.isVolumeFullCopy((Volume) blockObject, _dbClient);
            if (isFullCopy) {
                addFullcopies.add(volumeURI);
            } else {
                addVolumes.add(volumeURI);
            }
        }
    }
    if ((!addVolumes.isEmpty() && (!addSnapshots.isEmpty() || !addFullcopies.isEmpty())) || (!addSnapshots.isEmpty() && !addFullcopies.isEmpty())) {
        throw APIException.badRequests.cantUpdateCGWithMixedBlockObjects(consistencyGroup.getLabel());
    }
    // group.
    if (!addVolumes.isEmpty()) {
        Iterator<Volume> cgVolumesIter = cgVolumes.iterator();
        if (cgVolumesIter.hasNext()) {
            Volume cgVolume = cgVolumesIter.next();
            VirtualPool cgVPool = _permissionsHelper.getObjectById(cgVolume.getVirtualPool(), VirtualPool.class);
            URI cgVArrayURI = cgVolume.getVirtualArray();
            String cgHAType = cgVPool.getHighAvailability();
            for (URI volumeURI : addVolumes) {
                Volume addVolume = _permissionsHelper.getObjectById(volumeURI, Volume.class);
                VirtualPool addVolumeVPool = _permissionsHelper.getObjectById(addVolume.getVirtualPool(), VirtualPool.class);
                if (!addVolumeVPool.getHighAvailability().equals(cgHAType)) {
                    throw APIException.badRequests.invalidParameterConsistencyGroupVolumeHasIncorrectHighAvailability(cgVolume.getId(), cgHAType);
                } else if (!cgVArrayURI.equals(addVolume.getVirtualArray())) {
                    throw APIException.badRequests.invalidParameterConsistencyGroupVolumeHasIncorrectVArray(cgVolume.getId(), cgVArrayURI);
                }
            }
        }
        // Check if the volumes have been in the CG, and not ingestion case
        if (consistencyGroup.getTypes().contains(Types.LOCAL.toString()) && !cgVolumes.isEmpty()) {
            Set<String> cgVolumesURISet = new HashSet<String>();
            for (Volume cgVolume : cgVolumes) {
                cgVolumesURISet.add(cgVolume.getId().toString());
            }
            Iterator<URI> iter = addVolumes.iterator();
            while (iter.hasNext()) {
                if (cgVolumesURISet.contains(iter.next().toString())) {
                    iter.remove();
                }
            }
            if (addVolumes.isEmpty()) {
                // All volumes in the addVolumes list have been in the CG. return success
                s_logger.info("The volumes have been added to the CG");
                Operation op = new Operation();
                op.setResourceType(ResourceOperationTypeEnum.UPDATE_CONSISTENCY_GROUP);
                op.ready("Volumes have been added to the consistency group");
                _dbClient.createTaskOpStatus(BlockConsistencyGroup.class, consistencyGroup.getId(), taskId, op);
                return toTask(consistencyGroup, taskId, op);
            }
        }
    }
    // Only add snapshot or full copies to CG if backend volumes are from the same storage system.
    if (!addSnapshots.isEmpty() || !addFullcopies.isEmpty()) {
        if (!VPlexUtil.isVPLEXCGBackendVolumesInSameStorage(cgVolumes, _dbClient)) {
            throw APIException.badRequests.cantUpdateCGWithReplicaFromMultipleSystems(consistencyGroup.getLabel());
        }
    }
    Operation op = _dbClient.createTaskOpStatus(BlockConsistencyGroup.class, consistencyGroup.getId(), taskId, ResourceOperationTypeEnum.UPDATE_CONSISTENCY_GROUP);
    // When adding snapshots to CG, just call block implementation.
    if (!addSnapshots.isEmpty()) {
        BlockSnapshot snapshot = _permissionsHelper.getObjectById(addSnapshots.get(0), BlockSnapshot.class);
        URI systemURI = snapshot.getStorageController();
        StorageSystem system = _permissionsHelper.getObjectById(systemURI, StorageSystem.class);
        BlockController controller = getController(BlockController.class, system.getSystemType());
        controller.updateConsistencyGroup(system.getId(), consistencyGroup.getId(), addVolumesList, removeVolumesList, taskId);
        return toTask(consistencyGroup, taskId, op);
    }
    // all the virtual volumes in the CG have to be selected.
    if (!addVolumes.isEmpty()) {
        verifyAddVolumesToIngestedCG(consistencyGroup, addVolumes);
    }
    if (!addFullcopies.isEmpty()) {
        addVolumes.addAll(addFullcopies);
    }
    // Get VPlex controller
    VPlexController controller = getController();
    controller.updateConsistencyGroup(cgStorageSystem.getId(), consistencyGroup.getId(), addVolumes, removeVolumesList, taskId);
    return toTask(consistencyGroup, taskId, op);
}
Also used : BlockMirror(com.emc.storageos.db.client.model.BlockMirror) VPlexController(com.emc.storageos.vplexcontroller.VPlexController) BlockController(com.emc.storageos.volumecontroller.BlockController) ArrayList(java.util.ArrayList) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) Operation(com.emc.storageos.db.client.model.Operation) FCTN_STRING_TO_URI(com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_STRING_TO_URI) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) FCTN_VPLEX_MIRROR_TO_URI(com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_VPLEX_MIRROR_TO_URI) Volume(com.emc.storageos.db.client.model.Volume) BlockObject(com.emc.storageos.db.client.model.BlockObject) HashSet(java.util.HashSet) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 59 with BlockSnapshot

use of com.emc.storageos.db.client.model.BlockSnapshot in project coprhd-controller by CoprHD.

the class BlockSnapshotSessionUtils method querySnapshotSessionSource.

/**
 * Returns the volume or block snapshot instance for the passed URI.
 *
 * @param sourceURI The URI for the Volume or BlockSnapshot instance.
 * @param uriInfo A reference to the URI information.
 * @param checkAssociatedVolumes check if the passed source is an associated volume for another volume.
 * @param dbClient A reference to a database client.
 *
 * @return A reference to the block object.
 */
public static BlockObject querySnapshotSessionSource(URI sourceURI, UriInfo uriInfo, boolean checkAssociatedVolumes, DbClient dbClient) {
    ArgValidator.checkUri(sourceURI);
    if ((!URIUtil.isType(sourceURI, Volume.class)) && (!URIUtil.isType(sourceURI, BlockSnapshot.class))) {
        throw APIException.badRequests.invalidSnapshotSessionSource(sourceURI.toString());
    }
    BlockObject sourceObj = BlockObject.fetch(dbClient, sourceURI);
    ArgValidator.checkEntity(sourceObj, sourceURI, BlockServiceUtils.isIdEmbeddedInURL(sourceURI, uriInfo), true);
    // is returned.
    if (URIUtil.isType(sourceURI, Volume.class) && (checkAssociatedVolumes)) {
        List<Volume> volumes = CustomQueryUtility.queryActiveResourcesByConstraint(dbClient, Volume.class, AlternateIdConstraint.Factory.getVolumeByAssociatedVolumesConstraint(sourceURI.toString()));
        if (!volumes.isEmpty()) {
            sourceObj = volumes.get(0);
        }
    }
    return sourceObj;
}
Also used : Volume(com.emc.storageos.db.client.model.Volume) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) BlockObject(com.emc.storageos.db.client.model.BlockObject)

Example 60 with BlockSnapshot

use of com.emc.storageos.db.client.model.BlockSnapshot in project coprhd-controller by CoprHD.

the class BlockSnapshotSessionUtils method querySnapshotSessionSourceProject.

/**
 * Returns the project for the snapshot session source.
 *
 * @param sourceObj A reference to the Volume or BlockSnapshot instance.
 * @param dbClient A reference to a database client.
 *
 * @return A reference to the project for the snapshot session source.
 */
public static Project querySnapshotSessionSourceProject(BlockObject sourceObj, DbClient dbClient) {
    URI sourceURI = sourceObj.getId();
    URI projectURI = null;
    if (URIUtil.isType(sourceURI, Volume.class)) {
        projectURI = ((Volume) sourceObj).getProject().getURI();
    } else if (URIUtil.isType(sourceURI, BlockSnapshot.class)) {
        projectURI = ((BlockSnapshot) sourceObj).getProject().getURI();
    }
    if (projectURI == null) {
        throw APIException.badRequests.invalidSnapshotSessionSource(sourceURI.toString());
    }
    Project project = dbClient.queryObject(Project.class, projectURI);
    return project;
}
Also used : Project(com.emc.storageos.db.client.model.Project) Volume(com.emc.storageos.db.client.model.Volume) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) URI(java.net.URI)

Aggregations

BlockSnapshot (com.emc.storageos.db.client.model.BlockSnapshot)401 Volume (com.emc.storageos.db.client.model.Volume)215 URI (java.net.URI)209 ArrayList (java.util.ArrayList)112 NamedURI (com.emc.storageos.db.client.model.NamedURI)110 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)106 ServiceError (com.emc.storageos.svcs.errorhandling.model.ServiceError)91 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)63 BlockObject (com.emc.storageos.db.client.model.BlockObject)63 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)55 CIMObjectPath (javax.cim.CIMObjectPath)51 StringSet (com.emc.storageos.db.client.model.StringSet)49 HashMap (java.util.HashMap)48 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)46 BlockSnapshotSession (com.emc.storageos.db.client.model.BlockSnapshotSession)41 WBEMException (javax.wbem.WBEMException)38 Produces (javax.ws.rs.Produces)36 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)35 CheckPermission (com.emc.storageos.security.authorization.CheckPermission)33 Path (javax.ws.rs.Path)33