Search in sources :

Example 26 with BlockSnapshot

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

the class AbstractBlockServiceApiImpl method prepareSnapshots.

/**
 * Prepares the snapshots for a snapshot request.
 *
 * @param volumes
 *            The volumes for which snapshots are to be created.
 * @param snapshotType
 *            The snapshot technology type.
 * @param snapshotName
 *            The snapshot name.
 * @param snapshotURIs
 *            [OUT] The URIs for the prepared snapshots.
 * @param taskId
 *            The unique task identifier
 *
 * @return The list of snapshots
 */
@Override
public List<BlockSnapshot> prepareSnapshots(List<Volume> volumes, String snapshotType, String snapshotName, List<URI> snapshotURIs, String taskId) {
    List<BlockSnapshot> snapshots = new ArrayList<BlockSnapshot>();
    int count = 1;
    for (Volume volume : volumes) {
        // Attempt to create distinct labels here when creating >1 volumes (ScaleIO requirement)
        String rgName = volume.getReplicationGroupInstance();
        VolumeGroup application = volume.getApplication(_dbClient);
        if (volume.isVPlexVolume(_dbClient)) {
            Volume backendVol = VPlexUtil.getVPLEXBackendVolume(volumes.get(0), true, _dbClient);
            if (backendVol != null && !backendVol.getInactive()) {
                rgName = backendVol.getReplicationGroupInstance();
            }
        }
        String label = snapshotName;
        if (NullColumnValueGetter.isNotNullValue(rgName) && application != null) {
            // There can be multiple RGs in a CG, in such cases generate unique name
            if (volumes.size() > 1) {
                label = String.format("%s-%s-%s", snapshotName, rgName, count++);
            } else {
                label = String.format("%s-%s", snapshotName, rgName);
            }
        } else if (volumes.size() > 1) {
            label = String.format("%s-%s", snapshotName, count++);
        }
        BlockSnapshot snapshot = prepareSnapshotFromVolume(volume, snapshotName, label);
        snapshot.setTechnologyType(snapshotType);
        snapshot.setOpStatus(new OpStatusMap());
        Operation op = new Operation();
        op.setResourceType(ResourceOperationTypeEnum.CREATE_VOLUME_SNAPSHOT);
        snapshot.getOpStatus().createTaskStatus(taskId, op);
        snapshotURIs.add(snapshot.getId());
        snapshots.add(snapshot);
    }
    _dbClient.createObject(snapshots);
    return snapshots;
}
Also used : Volume(com.emc.storageos.db.client.model.Volume) VolumeGroup(com.emc.storageos.db.client.model.VolumeGroup) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) ArrayList(java.util.ArrayList) OpStatusMap(com.emc.storageos.db.client.model.OpStatusMap) Operation(com.emc.storageos.db.client.model.Operation) AlternateIdConstraint(com.emc.storageos.db.client.constraint.AlternateIdConstraint) ContainmentPrefixConstraint(com.emc.storageos.db.client.constraint.ContainmentPrefixConstraint) ContainmentConstraint(com.emc.storageos.db.client.constraint.ContainmentConstraint)

Example 27 with BlockSnapshot

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

the class AbstractBlockServiceApiImpl method deleteSnapshot.

/**
 * {@inheritDoc}
 */
@Override
public void deleteSnapshot(BlockSnapshot requestedSnapshot, List<BlockSnapshot> allSnapshots, String taskId, String deleteType) {
    if (VolumeDeleteTypeEnum.VIPR_ONLY.name().equals(deleteType)) {
        s_logger.info("Executing ViPR-only snapshot deletion");
        // Do any cleanup necessary for the ViPR only delete.
        cleanupForViPROnlySnapshotDelete(allSnapshots);
        // Mark them inactive.
        _dbClient.markForDeletion(allSnapshots);
        // Note that we must go back to the database to get the latest snapshot status map.
        for (BlockSnapshot snapshot : allSnapshots) {
            BlockSnapshot updatedSnapshot = _dbClient.queryObject(BlockSnapshot.class, snapshot.getId());
            Operation op = updatedSnapshot.getOpStatus().get(taskId);
            op.ready("Snapshot succesfully deleted from ViPR");
            updatedSnapshot.getOpStatus().updateTaskStatus(taskId, op);
            _dbClient.updateObject(updatedSnapshot);
        }
    } else {
        StorageSystem device = _dbClient.queryObject(StorageSystem.class, requestedSnapshot.getStorageController());
        BlockController controller = getController(BlockController.class, device.getSystemType());
        controller.deleteSnapshot(device.getId(), requestedSnapshot.getId(), taskId);
    }
}
Also used : BlockController(com.emc.storageos.volumecontroller.BlockController) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) Operation(com.emc.storageos.db.client.model.Operation) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 28 with BlockSnapshot

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

the class AbstractBlockServiceApiImpl method prepareSnapshotFromVolume.

/**
 * Creates and returns a new ViPR BlockSnapshot instance with the passed
 * name for the passed volume.
 *
 * @param volume
 *            The volume for which the snapshot is being created.
 * @param snapsetLabel
 *            The snapset label for grouping this snapshot
 * @param label
 *            The label for the new snapshot
 * @return A reference to the new BlockSnapshot instance.
 */
protected BlockSnapshot prepareSnapshotFromVolume(Volume volume, String snapsetLabel, String label) {
    BlockSnapshot snapshot = new BlockSnapshot();
    snapshot.setId(URIUtil.createId(BlockSnapshot.class));
    URI cgUri = volume.getConsistencyGroup();
    if (cgUri != null) {
        snapshot.setConsistencyGroup(cgUri);
    }
    snapshot.setSourceNativeId(volume.getNativeId());
    snapshot.setParent(new NamedURI(volume.getId(), volume.getLabel()));
    snapshot.setLabel(label);
    snapshot.setStorageController(volume.getStorageController());
    snapshot.setSystemType(volume.getSystemType());
    snapshot.setVirtualArray(volume.getVirtualArray());
    snapshot.setProtocol(new StringSet());
    snapshot.getProtocol().addAll(volume.getProtocol());
    snapshot.setProject(new NamedURI(volume.getProject().getURI(), volume.getProject().getName()));
    snapshot.setSnapsetLabel(ResourceOnlyNameGenerator.removeSpecialCharsForName(snapsetLabel, SmisConstants.MAX_SNAPSHOT_NAME_LENGTH));
    return snapshot;
}
Also used : NamedURI(com.emc.storageos.db.client.model.NamedURI) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) StringSet(com.emc.storageos.db.client.model.StringSet) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI)

Example 29 with BlockSnapshot

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

the class BlockConsistencyGroupService method activateConsistencyGroupSnapshot.

/**
 * Activate the specified Consistency Group Snapshot
 *
 * @prereq Create consistency group snapshot as inactive
 *
 * @param consistencyGroupId
 *            - Consistency group URI
 * @param snapshotId
 *            - Consistency group snapshot URI
 *
 * @brief Activate consistency group snapshot
 * @return TaskResourceRep
 */
@POST
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/{id}/protection/snapshots/{sid}/activate")
@CheckPermission(roles = { Role.TENANT_ADMIN }, acls = { ACL.ANY })
public TaskResourceRep activateConsistencyGroupSnapshot(@PathParam("id") final URI consistencyGroupId, @PathParam("sid") final URI snapshotId) {
    Operation op = new Operation();
    op.setResourceType(ResourceOperationTypeEnum.ACTIVATE_CONSISTENCY_GROUP_SNAPSHOT);
    final BlockConsistencyGroup consistencyGroup = (BlockConsistencyGroup) queryResource(consistencyGroupId);
    final BlockSnapshot snapshot = (BlockSnapshot) queryResource(snapshotId);
    verifySnapshotIsForConsistencyGroup(snapshot, consistencyGroup);
    // check for backend CG
    if (BlockConsistencyGroupUtils.getLocalSystemsInCG(consistencyGroup, _dbClient).isEmpty()) {
        _log.error("{} Group Snapshot operations not supported when there is no backend CG", consistencyGroup.getId());
        throw APIException.badRequests.cannotCreateSnapshotOfCG();
    }
    final StorageSystem device = _dbClient.queryObject(StorageSystem.class, snapshot.getStorageController());
    final BlockController controller = getController(BlockController.class, device.getSystemType());
    final String task = UUID.randomUUID().toString();
    // activate it again.
    if (snapshot.getIsSyncActive()) {
        op.ready();
        op.setMessage("The consistency group snapshot is already active.");
        _dbClient.createTaskOpStatus(BlockSnapshot.class, snapshot.getId(), task, op);
        return toTask(snapshot, task, op);
    }
    _dbClient.createTaskOpStatus(BlockSnapshot.class, snapshot.getId(), task, op);
    try {
        final List<URI> snapshotList = new ArrayList<URI>();
        // Query all the snapshots by snapshot label
        final List<BlockSnapshot> snaps = ControllerUtils.getSnapshotsPartOfReplicationGroup(snapshot, _dbClient);
        // Build a URI list with all the snapshots ids
        for (BlockSnapshot snap : snaps) {
            snapshotList.add(snap.getId());
        }
        // Activate snapshots
        controller.activateSnapshot(device.getId(), snapshotList, task);
    } catch (final ControllerException e) {
        throw new ServiceCodeException(CONTROLLER_ERROR, e, "An exception occurred when activating consistency group snapshot {0}. Caused by: {1}", new Object[] { snapshotId, e.getMessage() });
    }
    auditBlockConsistencyGroup(OperationTypeEnum.ACTIVATE_CONSISTENCY_GROUP_SNAPSHOT, AuditLogManager.AUDITLOG_SUCCESS, AuditLogManager.AUDITOP_BEGIN, snapshot.getId().toString(), snapshot.getLabel());
    return toTask(snapshot, task, op);
}
Also used : ControllerException(com.emc.storageos.volumecontroller.ControllerException) BlockController(com.emc.storageos.volumecontroller.BlockController) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) ArrayList(java.util.ArrayList) ServiceCodeException(com.emc.storageos.svcs.errorhandling.resources.ServiceCodeException) Operation(com.emc.storageos.db.client.model.Operation) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) MapBlockConsistencyGroup(com.emc.storageos.api.mapper.functions.MapBlockConsistencyGroup) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) BlockObject(com.emc.storageos.db.client.model.BlockObject) DiscoveredDataObject(com.emc.storageos.db.client.model.DiscoveredDataObject) DataObject(com.emc.storageos.db.client.model.DataObject) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Produces(javax.ws.rs.Produces) CheckPermission(com.emc.storageos.security.authorization.CheckPermission)

Example 30 with BlockSnapshot

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

the class BlockConsistencyGroupService method updateConsistencyGroup.

/**
 * Update the specified consistency group
 *
 * @prereq none
 *
 * @param id the URN of a ViPR Consistency group
 *
 * @brief Update consistency group
 * @return TaskResourceRep
 */
@PUT
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/{id}")
@CheckPermission(roles = { Role.TENANT_ADMIN }, acls = { ACL.OWN, ACL.ALL })
public TaskResourceRep updateConsistencyGroup(@PathParam("id") final URI id, final BlockConsistencyGroupUpdate param) {
    // Get the consistency group.
    BlockConsistencyGroup consistencyGroup = (BlockConsistencyGroup) queryResource(id);
    StorageDriverManager storageDriverManager = (StorageDriverManager) StorageDriverManager.getApplicationContext().getBean(StorageDriverManager.STORAGE_DRIVER_MANAGER);
    // Verify a volume was specified to be added or removed.
    if (!param.hasEitherAddOrRemoveVolumes()) {
        throw APIException.badRequests.noVolumesToBeAddedRemovedFromCG();
    }
    // TODO require a check if requested list contains all volumes/replicas?
    // For replicas, check replica count with volume count in CG
    StorageSystem cgStorageSystem = null;
    // Throw exception if the operation is attempted on volumes that are in RP CG.
    if (consistencyGroup.isRPProtectedCG()) {
        throw APIException.badRequests.operationNotAllowedOnRPVolumes();
    }
    // This method also supports adding volumes or replicas to CG (VMAX - SMIS 8.0.x)
    if ((!consistencyGroup.created() || NullColumnValueGetter.isNullURI(consistencyGroup.getStorageController())) && param.hasVolumesToAdd()) {
        // we just need to check the case of add volumes in this case
        BlockObject bo = BlockObject.fetch(_dbClient, param.getAddVolumesList().getVolumes().get(0));
        cgStorageSystem = _permissionsHelper.getObjectById(bo.getStorageController(), StorageSystem.class);
    } else {
        cgStorageSystem = _permissionsHelper.getObjectById(consistencyGroup.getStorageController(), StorageSystem.class);
    }
    // IBMXIV, XtremIO, VPlex, VNX, ScaleIO, and VMax volumes only
    String systemType = cgStorageSystem.getSystemType();
    if (!storageDriverManager.isDriverManaged(cgStorageSystem.getSystemType())) {
        if (!systemType.equals(DiscoveredDataObject.Type.vplex.name()) && !systemType.equals(DiscoveredDataObject.Type.vnxblock.name()) && !systemType.equals(DiscoveredDataObject.Type.vmax.name()) && !systemType.equals(DiscoveredDataObject.Type.vnxe.name()) && !systemType.equals(DiscoveredDataObject.Type.unity.name()) && !systemType.equals(DiscoveredDataObject.Type.ibmxiv.name()) && !systemType.equals(DiscoveredDataObject.Type.scaleio.name()) && !systemType.equals(DiscoveredDataObject.Type.xtremio.name())) {
            throw APIException.methodNotAllowed.notSupported();
        }
    }
    // Get the specific BlockServiceApiImpl based on the storage system type.
    BlockServiceApi blockServiceApiImpl = getBlockServiceImpl(cgStorageSystem);
    List<URI> volIds = null;
    Set<URI> addSet = new HashSet<URI>();
    boolean isReplica = true;
    if (param.hasVolumesToAdd()) {
        volIds = param.getAddVolumesList().getVolumes();
        addSet.addAll(volIds);
        URI volId = volIds.get(0);
        if (URIUtil.isType(volId, Volume.class)) {
            Volume volume = _permissionsHelper.getObjectById(volId, Volume.class);
            ArgValidator.checkEntity(volume, volId, false);
            if (!BlockFullCopyUtils.isVolumeFullCopy(volume, _dbClient)) {
                isReplica = false;
            }
        }
    }
    List<Volume> cgVolumes = blockServiceApiImpl.getActiveCGVolumes(consistencyGroup);
    // check if add volume list is same as existing volumes in CG
    boolean volsAlreadyInCG = false;
    if (!isReplica && cgVolumes != null && !cgVolumes.isEmpty()) {
        Collection<URI> cgVolIds = transform(cgVolumes, fctnDataObjectToID());
        if (addSet.size() == cgVolIds.size()) {
            volsAlreadyInCG = addSet.containsAll(cgVolIds);
        }
    }
    // Verify that the add and remove lists do not contain the same volume.
    if (param.hasBothAddAndRemoveVolumes()) {
        /*
             * Make sure the add and remove lists are unique by getting the intersection and
             * verifying the size is 0.
             */
        Set<URI> removeSet = new HashSet<URI>(param.getRemoveVolumesList().getVolumes());
        addSet.retainAll(removeSet);
        if (!addSet.isEmpty()) {
            throw APIException.badRequests.sameVolumesInAddRemoveList();
        }
    }
    if (cgStorageSystem.getUsingSmis80() && cgStorageSystem.deviceIsType(Type.vmax)) {
        // CG can have replicas
        if (_log.isDebugEnabled()) {
            _log.debug("CG can have replicas for VMAX with SMI-S 8.x");
        }
    } else if (param.hasVolumesToRemove() || (!isReplica && !volsAlreadyInCG)) {
        // CG cannot have replicas when adding/removing volumes to/from CG
        // Check snapshots
        // Adding/removing volumes to/from a consistency group
        // is not supported when the consistency group has active
        // snapshots.
        URIQueryResultList cgSnapshotsResults = new URIQueryResultList();
        _dbClient.queryByConstraint(getBlockSnapshotByConsistencyGroup(id), cgSnapshotsResults);
        Iterator<URI> cgSnapshotsIter = cgSnapshotsResults.iterator();
        while (cgSnapshotsIter.hasNext()) {
            BlockSnapshot cgSnapshot = _dbClient.queryObject(BlockSnapshot.class, cgSnapshotsIter.next());
            if ((cgSnapshot != null) && (!cgSnapshot.getInactive())) {
                throw APIException.badRequests.notAllowedWhenCGHasSnapshots();
            }
        }
        // VNX group clones and mirrors are just list of replicas, no corresponding group on array side
        if (!cgStorageSystem.deviceIsType(Type.vnxblock)) {
            // is not supported when existing volumes in CG have mirrors.
            if (cgVolumes != null && !cgVolumes.isEmpty()) {
                Volume firstVolume = cgVolumes.get(0);
                StringSet mirrors = firstVolume.getMirrors();
                if (mirrors != null && !mirrors.isEmpty()) {
                    throw APIException.badRequests.notAllowedWhenCGHasMirrors();
                }
            }
            // Check clones
            // Adding/removing volumes to/from a consistency group
            // is not supported when the consistency group has
            // volumes with full copies to which they are still
            // attached or has volumes that are full copies that
            // are still attached to their source volumes.
            getFullCopyManager().verifyConsistencyGroupCanBeUpdated(consistencyGroup, cgVolumes);
        }
    }
    // Verify the volumes to be removed.
    List<URI> removeVolumesList = new ArrayList<URI>();
    if (param.hasVolumesToRemove()) {
        for (URI volumeURI : param.getRemoveVolumesList().getVolumes()) {
            // Validate the volume to be removed exists.
            if (URIUtil.isType(volumeURI, Volume.class)) {
                Volume volume = _permissionsHelper.getObjectById(volumeURI, Volume.class);
                ArgValidator.checkEntity(volume, volumeURI, false);
                /**
                 * Remove SRDF volume from CG is not supported.
                 */
                if (volume.checkForSRDF()) {
                    throw APIException.badRequests.notAllowedOnSRDFConsistencyGroups();
                }
                if (!BlockFullCopyUtils.isVolumeFullCopy(volume, _dbClient)) {
                    blockServiceApiImpl.verifyRemoveVolumeFromCG(volume, cgVolumes);
                }
            }
            removeVolumesList.add(volumeURI);
        }
    }
    URI xivPoolURI = null;
    if (systemType.equals(DiscoveredDataObject.Type.ibmxiv.name()) && !cgVolumes.isEmpty()) {
        Volume firstVolume = cgVolumes.get(0);
        xivPoolURI = firstVolume.getPool();
    }
    // Verify the volumes to be added.
    List<URI> addVolumesList = new ArrayList<URI>();
    List<Volume> volumes = new ArrayList<Volume>();
    if (param.hasVolumesToAdd()) {
        for (URI volumeURI : param.getAddVolumesList().getVolumes()) {
            // Validate the volume to be added exists.
            Volume volume = null;
            if (!isReplica) {
                volume = _permissionsHelper.getObjectById(volumeURI, Volume.class);
                ArgValidator.checkEntity(volume, volumeURI, false);
                blockServiceApiImpl.verifyAddVolumeToCG(volume, consistencyGroup, cgVolumes, cgStorageSystem);
                volumes.add(volume);
            } else {
                verifyAddReplicaToCG(volumeURI, consistencyGroup, cgStorageSystem);
            }
            // IBM XIV specific checking
            if (systemType.equals(DiscoveredDataObject.Type.ibmxiv.name())) {
                // all volumes should be on the same storage pool
                if (xivPoolURI == null) {
                    xivPoolURI = volume.getPool();
                } else {
                    if (!xivPoolURI.equals(volume.getPool())) {
                        throw APIException.badRequests.invalidParameterIBMXIVConsistencyGroupVolumeNotInPool(volumeURI, xivPoolURI);
                    }
                }
            }
            // Add the volume to list.
            addVolumesList.add(volumeURI);
        }
        if (!volumes.isEmpty()) {
            blockServiceApiImpl.verifyReplicaCount(volumes, cgVolumes, volsAlreadyInCG);
        }
    }
    // Create the task id;
    String taskId = UUID.randomUUID().toString();
    // Call the block service API to update the consistency group.
    return blockServiceApiImpl.updateConsistencyGroup(cgStorageSystem, cgVolumes, consistencyGroup, addVolumesList, removeVolumesList, taskId);
}
Also used : BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) ArrayList(java.util.ArrayList) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) MapBlockConsistencyGroup(com.emc.storageos.api.mapper.functions.MapBlockConsistencyGroup) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) StorageDriverManager(com.emc.storageos.services.util.StorageDriverManager) Volume(com.emc.storageos.db.client.model.Volume) Iterator(java.util.Iterator) StringSet(com.emc.storageos.db.client.model.StringSet) BlockObject(com.emc.storageos.db.client.model.BlockObject) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) HashSet(java.util.HashSet) Path(javax.ws.rs.Path) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces) PUT(javax.ws.rs.PUT) CheckPermission(com.emc.storageos.security.authorization.CheckPermission)

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