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;
}
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);
}
}
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;
}
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);
}
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);
}
Aggregations