use of com.emc.storageos.db.client.model.BlockObject in project coprhd-controller by CoprHD.
the class VplexVolumeIngestionContext method getAssociatedVolumeIds.
/**
* Returns a StringSet of associated volume URIs for this context's VPLEX virtual volume.
* If the volume already has associated backend volume URIs, then that Set is returned.
* Otherwise, the block objects to be created map will be checked for the existence of
* ingested backend volumes that haven't been associated yet.
*
* An incomplete or empty Set may be returned depending on the state of ingestion, but a warning
* will be logged if the count of volume URIs to be returned is not the expected number for the VPLEX
* virtual volume type (2 for distributed type, 1 for local type).
*
* @param volume the VPLEX virtual volume object to check
* @return a StringSet of associated volume URIs for this context's VPLEX virtual volume
*/
public StringSet getAssociatedVolumeIds(Volume volume) {
if (volume != null && volume.getAssociatedVolumes() != null && !volume.getAssociatedVolumes().isEmpty()) {
_logger.info("getAssociatedVolumes: volumes are already associated with the virtual volume, returning {}", volume.getAssociatedVolumes());
return volume.getAssociatedVolumes();
}
StringSet associatedVolumes = new StringSet();
for (String backendVolumeNativeGuid : getBackendVolumeGuids()) {
BlockObject backendVolume = getBlockObjectsToBeCreatedMap().get(backendVolumeNativeGuid);
associatedVolumes.add(backendVolume.getId().toString());
}
if (this.isDistributed() && associatedVolumes.size() != VPlexApiConstants.DISTRIBUTED_BACKEND_VOLUME_COUNT) {
_logger.warn("getAssociatedVolumes: virtual volume is distributed, but {} backend volumes were found (expected 2)", associatedVolumes.size());
} else if (this.isLocal() && associatedVolumes.size() != VPlexApiConstants.LOCAL_BACKEND_VOLUME_COUNT) {
_logger.warn("getAssociatedVolumes: virtual volume is local, but {} backend volumes were found (expected 1)", associatedVolumes.size());
}
_logger.info("getAssociatedVolumes: backend volumes assembled, returning {}", associatedVolumes);
return associatedVolumes;
}
use of com.emc.storageos.db.client.model.BlockObject in project coprhd-controller by CoprHD.
the class VplexVolumeIngestionContext method createVplexMirrorObjects.
/**
* Create a VplexMirror database object if a VPLEX native mirror is present.
* This should be called after the parent virtual volume has already been ingested.
*
* @param context the VplexBackendIngestionContext
* @param virtualVolume the ingested virtual volume's Volume object.
*/
private void createVplexMirrorObjects() {
if (!getUnmanagedVplexMirrors().isEmpty()) {
Volume virtualVolume = (Volume) _parentRequestContext.getProcessedBlockObject(getUnmanagedVirtualVolume().getNativeGuid());
_logger.info("creating VplexMirror object for virtual volume " + virtualVolume.getLabel());
for (Entry<UnManagedVolume, String> entry : getUnmanagedVplexMirrors().entrySet()) {
// find mirror and create a VplexMirror object
BlockObject mirror = getBlockObjectsToBeCreatedMap().get(entry.getKey().getNativeGuid().replace(VolumeIngestionUtil.UNMANAGEDVOLUME, VolumeIngestionUtil.VOLUME));
if (null != mirror) {
_logger.info("processing mirror " + mirror.getLabel());
if (mirror instanceof Volume) {
Volume mirrorVolume = (Volume) mirror;
// create VplexMirror set all the basic properties
VplexMirror vplexMirror = new VplexMirror();
vplexMirror.setId(URIUtil.createId(VplexMirror.class));
vplexMirror.setCapacity(mirrorVolume.getCapacity());
vplexMirror.setLabel(mirrorVolume.getLabel());
vplexMirror.setNativeId(entry.getValue());
// For Vplex virtual volumes set allocated capacity to 0 (cop-18608)
vplexMirror.setAllocatedCapacity(0L);
vplexMirror.setProvisionedCapacity(mirrorVolume.getProvisionedCapacity());
vplexMirror.setSource(new NamedURI(virtualVolume.getId(), virtualVolume.getLabel()));
vplexMirror.setStorageController(virtualVolume.getStorageController());
vplexMirror.setTenant(mirrorVolume.getTenant());
vplexMirror.setThinPreAllocationSize(mirrorVolume.getThinVolumePreAllocationSize());
vplexMirror.setThinlyProvisioned(mirrorVolume.getThinlyProvisioned());
vplexMirror.setVirtualArray(mirrorVolume.getVirtualArray());
vplexMirror.setVirtualPool(mirrorVolume.getVirtualPool());
// set the associated volume for this VplexMirror
StringSet associatedVolumes = new StringSet();
associatedVolumes.add(mirrorVolume.getId().toString());
vplexMirror.setAssociatedVolumes(associatedVolumes);
// VplexMirror will have the same project
// as the virtual volume (i.e., the front-end project)
// but the mirror backend will have the backend project
vplexMirror.setProject(new NamedURI(getFrontendProject().getId(), mirrorVolume.getLabel()));
mirrorVolume.setProject(new NamedURI(getBackendProject().getId(), mirrorVolume.getLabel()));
// update flags on mirror volume
Set<DataObject> updatedObjects = getDataObjectsToBeUpdatedMap().get(mirrorVolume.getNativeGuid());
if (updatedObjects == null) {
updatedObjects = new HashSet<DataObject>();
getDataObjectsToBeUpdatedMap().put(mirrorVolume.getNativeGuid(), updatedObjects);
}
VolumeIngestionUtil.clearInternalFlags(this, mirrorVolume, updatedObjects, _dbClient);
// VPLEX backend volumes should still have the INTERNAL_OBJECT flag
mirrorVolume.addInternalFlags(Flag.INTERNAL_OBJECT);
// deviceLabel will be the very last part of the native guid
String[] devicePathParts = entry.getValue().split("/");
String deviceName = devicePathParts[devicePathParts.length - 1];
vplexMirror.setDeviceLabel(deviceName);
// save the new VplexMirror & persist backend & updated objects
getCreatedVplexMirrors().add(vplexMirror);
// set mirrors property on the parent virtual volume
StringSet mirrors = virtualVolume.getMirrors();
if (mirrors == null) {
mirrors = new StringSet();
}
mirrors.add(vplexMirror.getId().toString());
virtualVolume.setMirrors(mirrors);
}
}
}
}
}
use of com.emc.storageos.db.client.model.BlockObject in project coprhd-controller by CoprHD.
the class UnManagedVolumeService method recordBourneVolumeEvent.
/**
* Generate and Record a Bourne volume specific event
*
* @param dbClient
* @param evtType
* @param status
* @param desc
* @throws Exception
*/
public void recordBourneVolumeEvent(DbClient dbClient, String evtType, Operation.Status status, String desc, URI id) throws Exception {
RecordableEventManager eventManager = new RecordableEventManager();
eventManager.setDbClient(dbClient);
BlockObject blockObject = null;
if (URIUtil.isType(id, Volume.class)) {
blockObject = dbClient.queryObject(Volume.class, id);
} else if (URIUtil.isType(id, BlockMirror.class)) {
blockObject = dbClient.queryObject(BlockMirror.class, id);
} else if (URIUtil.isType(id, BlockSnapshot.class)) {
blockObject = dbClient.queryObject(BlockSnapshot.class, id);
}
RecordableBourneEvent event = ControllerUtils.convertToRecordableBourneEvent(blockObject, evtType, desc, "", dbClient, EVENT_SERVICE_TYPE, RecordType.Event.name(), EVENT_SERVICE_SOURCE);
try {
eventManager.recordEvents(event);
_logger.info("Bourne {} event recorded", evtType);
} catch (Exception ex) {
_logger.error("Failed to record event. Event description: {}. Error:", evtType, ex);
}
}
use of com.emc.storageos.db.client.model.BlockObject 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);
}
use of com.emc.storageos.db.client.model.BlockObject 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;
}
Aggregations