use of com.emc.storageos.db.client.model.VolumeGroup in project coprhd-controller by CoprHD.
the class BlockDeviceController method createFullCopy.
@Override
public void createFullCopy(URI storage, List<URI> fullCopyVolumes, Boolean createInactive, String taskId) throws ControllerException {
_log.info("START fullCopyVolumes");
TaskCompleter taskCompleter = new CloneCreateWorkflowCompleter(fullCopyVolumes, taskId);
Volume clone = _dbClient.queryObject(Volume.class, fullCopyVolumes.get(0));
URI sourceVolume = clone.getAssociatedSourceVolume();
try {
StorageSystem storageSystem = _dbClient.queryObject(StorageSystem.class, storage);
Workflow workflow = _workflowService.getNewWorkflow(this, FULL_COPY_WORKFLOW, true, taskId);
boolean isCG = false;
Volume source = URIUtil.isType(sourceVolume, Volume.class) ? _dbClient.queryObject(Volume.class, sourceVolume) : null;
VolumeGroup volumeGroup = (source != null) ? source.getApplication(_dbClient) : null;
if (volumeGroup != null) {
/**
* If a Volume is in Volume Group (COPY type),
* Query all volumes belonging to that Volume Group,
* Group full-copies by Array Replication Group and create workflow step for each Array Group,
* these steps runs in parallel
*/
_log.info("Creating full copy for Application {}", volumeGroup.getLabel());
createFullCopyForApplicationCGs(workflow, volumeGroup, fullCopyVolumes, createInactive, taskCompleter);
} else if (checkCloneConsistencyGroup(fullCopyVolumes.get(0), _dbClient, taskCompleter)) {
// check if the clone is in a CG
isCG = true;
_log.info("Creating group full copy");
createCGFullCopy(storage, sourceVolume, fullCopyVolumes, storageSystem, workflow, createInactive, isCG);
} else {
for (URI uri : fullCopyVolumes) {
Workflow.Method createMethod = createFullCopyVolumeMethod(storage, sourceVolume, Arrays.asList(uri), createInactive, isCG);
Workflow.Method rollbackMethod = rollbackFullCopyVolumeMethod(storage, asList(uri));
workflow.createStep(FULL_COPY_CREATE_STEP_GROUP, "Creating full copy", null, storage, storageSystem.getSystemType(), getClass(), createMethod, rollbackMethod, null);
// clone state.
if (!createInactive && !getDriverManager().isDriverManaged(storageSystem.getSystemType())) {
// After all full copies have been created, wait for synchronization to complete
Workflow.Method waitForSyncMethod = waitForSynchronizedMethod(Volume.class, storage, Arrays.asList(uri), isCG);
String waitForSyncStep = workflow.createStep(FULL_COPY_WFS_STEP_GROUP, "Waiting for synchronization", FULL_COPY_CREATE_STEP_GROUP, storage, storageSystem.getSystemType(), getClass(), waitForSyncMethod, rollbackMethodNullMethod(), null);
Volume cloneVol = _dbClient.queryObject(Volume.class, uri);
BlockObject sourceObj = BlockObject.fetch(_dbClient, cloneVol.getAssociatedSourceVolume());
// detach if source is snapshot, or storage system is not vmax/vnx/hds
if (storageSystem.deviceIsType(Type.openstack)) {
setCloneReplicaStateStep(workflow, storageSystem, asList(uri), waitForSyncStep, ReplicationState.SYNCHRONIZED);
} else if (sourceObj instanceof BlockSnapshot || !(storageSystem.deviceIsType(Type.vmax) || storageSystem.deviceIsType(Type.hds) || storageSystem.deviceIsType(Type.vnxblock))) {
Workflow.Method detachMethod = detachFullCopyMethod(storage, asList(uri));
workflow.createStep(FULL_COPY_DETACH_STEP_GROUP, "Detaching full copy", waitForSyncStep, storage, storageSystem.getSystemType(), getClass(), detachMethod, rollbackMethodNullMethod(), null);
} else if (storageSystem.deviceIsType(Type.vnxblock)) {
workflow.createStep(FULL_COPY_FRACTURE_STEP_GROUP, "fracture full copy", waitForSyncStep, storage, storageSystem.getSystemType(), BlockDeviceController.class, fractureCloneMethod(storage, Arrays.asList(uri), isCG), rollbackMethodNullMethod(), null);
} else {
setCloneReplicaStateStep(workflow, storageSystem, asList(uri), waitForSyncStep, ReplicationState.SYNCHRONIZED);
}
}
}
}
String successMsg = String.format("Full copy of %s to %s successful", sourceVolume, fullCopyVolumes);
workflow.executePlan(taskCompleter, successMsg);
} catch (InternalException e) {
_log.error("Failed to create full copy of volume", e);
doFailTask(Volume.class, sourceVolume, taskId, e);
WorkflowStepCompleter.stepFailed(taskId, e);
} catch (Exception e) {
_log.error("Failed to create full copy of volume", e);
ServiceError serviceError = DeviceControllerException.errors.jobFailed(e);
doFailTask(Volume.class, sourceVolume, taskId, serviceError);
WorkflowStepCompleter.stepFailed(taskId, serviceError);
}
}
use of com.emc.storageos.db.client.model.VolumeGroup in project coprhd-controller by CoprHD.
the class BlockConsistencyGroupAddVolumeCompleter method complete.
@Override
protected void complete(DbClient dbClient, Status status, ServiceCoded coded) throws DeviceControllerException {
log.info("Updating add volume replicationGroupInstance");
try {
super.complete(dbClient, status, coded);
if (status == Status.ready) {
BlockConsistencyGroup cg = dbClient.queryObject(BlockConsistencyGroup.class, getId());
if (groupName == null) {
groupName = (cg.getAlternateLabel() != null) ? cg.getAlternateLabel() : cg.getLabel();
}
VolumeGroup volumeGroup = ControllerUtils.getApplicationForCG(dbClient, cg, groupName);
for (URI voluri : addVolumeList) {
Volume volume = dbClient.queryObject(Volume.class, voluri);
if (volume != null && !volume.getInactive()) {
boolean isFullCopy = ControllerUtils.isVolumeFullCopy(volume, dbClient);
if (!isFullCopy) {
volume.setReplicationGroupInstance(groupName);
volume.setConsistencyGroup(this.getConsistencyGroupURI());
boolean isVplexBackendVolume = Volume.checkForVplexBackEndVolume(dbClient, volume);
if (volumeGroup != null && !isVplexBackendVolume) {
// do not set Application Id on VPLEX backend volume
volume.getVolumeGroupIds().add(volumeGroup.getId().toString());
}
// instance on the parent virtual volume
if (isVplexBackendVolume) {
Volume virtualVolume = Volume.fetchVplexVolume(dbClient, volume);
if (null != virtualVolume) {
if (!groupName.equals(virtualVolume.getBackingReplicationGroupInstance())) {
virtualVolume.setBackingReplicationGroupInstance(groupName);
dbClient.updateObject(virtualVolume);
}
}
}
dbClient.updateObject(volume);
}
}
}
}
} catch (Exception e) {
log.error("Failed updating status. BlockConsistencyGroupRemoveVolume {}, for task " + getOpId(), getId(), e);
}
}
use of com.emc.storageos.db.client.model.VolumeGroup in project coprhd-controller by CoprHD.
the class StorageScheduler method prepareVolume.
/**
* Prepare Volume for an unprotected traditional block volume.
*
* @param volume pre-created volume (optional)
* @param size volume size
* @param project project requested
* @param neighborhood varray requested
* @param vpool vpool requested
* @param placement recommendation for placement
* @param label volume label
* @param consistencyGroup cg ID
* @param createInactive
*
* @return a persisted volume
*/
public static Volume prepareVolume(DbClient dbClient, Volume volume, long size, long thinVolumePreAllocationSize, Project project, VirtualArray neighborhood, VirtualPool vpool, VolumeRecommendation placement, String label, BlockConsistencyGroup consistencyGroup, VirtualPoolCapabilityValuesWrapper cosCapabilities, Boolean createInactive) {
// In the case of a new volume that wasn't pre-created, make sure that volume doesn't already exist
if (volume == null) {
List<Volume> volumeList = CustomQueryUtility.queryActiveResourcesByConstraint(dbClient, Volume.class, ContainmentPrefixConstraint.Factory.getFullMatchConstraint(Volume.class, "project", project.getId(), label));
if (!volumeList.isEmpty()) {
throw APIException.badRequests.duplicateLabel(label);
}
}
boolean newVolume = false;
StoragePool pool = null;
if (volume == null) {
newVolume = true;
volume = new Volume();
volume.setId(URIUtil.createId(Volume.class));
volume.setOpStatus(new OpStatusMap());
} else {
// Reload volume object from DB
volume = dbClient.queryObject(Volume.class, volume.getId());
}
volume.setSyncActive(!Boolean.valueOf(createInactive));
volume.setLabel(label);
volume.setCapacity(size);
if (0 != thinVolumePreAllocationSize) {
volume.setThinVolumePreAllocationSize(thinVolumePreAllocationSize);
}
volume.setThinlyProvisioned(VirtualPool.ProvisioningType.Thin.toString().equalsIgnoreCase(vpool.getSupportedProvisioningType()));
volume.setVirtualPool(vpool.getId());
volume.setProject(new NamedURI(project.getId(), volume.getLabel()));
volume.setTenant(new NamedURI(project.getTenantOrg().getURI(), volume.getLabel()));
volume.setVirtualArray(neighborhood.getId());
URI poolId = placement.getCandidatePools().get(0);
if (null != poolId) {
pool = dbClient.queryObject(StoragePool.class, poolId);
if (null != pool) {
volume.setProtocol(new StringSet());
volume.getProtocol().addAll(VirtualPoolUtil.getMatchingProtocols(vpool.getProtocols(), pool.getProtocols()));
}
}
URI storageControllerUri = placement.getCandidateSystems().get(0);
StorageSystem storageSystem = dbClient.queryObject(StorageSystem.class, storageControllerUri);
String systemType = storageSystem.checkIfVmax3() ? DiscoveredDataObject.Type.vmax3.name() : storageSystem.getSystemType();
volume.setSystemType(systemType);
volume.setStorageController(storageControllerUri);
volume.setPool(poolId);
if (consistencyGroup != null) {
volume.setConsistencyGroup(consistencyGroup.getId());
if (!consistencyGroup.isProtectedCG()) {
String rgName = consistencyGroup.getCgNameOnStorageSystem(volume.getStorageController());
if (rgName == null) {
// for new CG
rgName = consistencyGroup.getLabel();
} else {
// if other volumes in the same CG are in an application, add this volume to the same application
VolumeGroup volumeGroup = ControllerUtils.getApplicationForCG(dbClient, consistencyGroup, rgName);
if (volumeGroup != null) {
volume.getVolumeGroupIds().add(volumeGroup.getId().toString());
}
}
volume.setReplicationGroupInstance(rgName);
}
}
if (null != cosCapabilities.getAutoTierPolicyName()) {
URI autoTierPolicyUri = getAutoTierPolicy(poolId, cosCapabilities.getAutoTierPolicyName(), dbClient);
if (null != autoTierPolicyUri) {
volume.setAutoTieringPolicyUri(autoTierPolicyUri);
}
}
if (vpool.getDedupCapable() != null) {
volume.setIsDeduplicated(vpool.getDedupCapable());
}
if (newVolume) {
dbClient.createObject(volume);
} else {
dbClient.updateAndReindexObject(volume);
}
return volume;
}
use of com.emc.storageos.db.client.model.VolumeGroup in project coprhd-controller by CoprHD.
the class VPlexDeviceController method createFullCopy.
/**
* {@inheritDoc}
*/
@Override
public void createFullCopy(URI vplexURI, List<VolumeDescriptor> volumeDescriptors, String opId) throws ControllerException {
_log.info("Copy volumes on VPLEX", vplexURI);
// When we copy a VPLEX virtual volume we natively copy the primary backend
// volume of the virtual volume. This primary copy is then imported to the
// VPLEX as a local or distributed virtual volume depending upon the type of
// the VPLEX volume being copied. Note that we could be creating multiple
// copies of a single source volume that is not in a consistency group or
// creating a single copy of multiple source volumes which are in a consistency
// group.
URI vplexSrcVolumeURI = null;
List<URI> vplexCopyVolumesURIs = new ArrayList<URI>();
TaskCompleter completer = null;
try {
// Set up the task completer
List<VolumeDescriptor> vplexVolumeDescrs = VolumeDescriptor.filterByType(volumeDescriptors, new VolumeDescriptor.Type[] { Type.VPLEX_VIRT_VOLUME }, new VolumeDescriptor.Type[] {});
List<VolumeDescriptor> vplexSrcVolumeDescs = getDescriptorsForFullCopySrcVolumes(vplexVolumeDescrs);
// VPLEX copy volumes
vplexVolumeDescrs.removeAll(vplexSrcVolumeDescs);
vplexCopyVolumesURIs = VolumeDescriptor.getVolumeURIs(vplexVolumeDescrs);
completer = new VPlexTaskCompleter(Volume.class, vplexCopyVolumesURIs, opId, null);
Volume firstFullCopy = _dbClient.queryObject(Volume.class, vplexCopyVolumesURIs.get(0));
URI sourceVolume = firstFullCopy.getAssociatedSourceVolume();
Volume source = URIUtil.isType(sourceVolume, Volume.class) ? _dbClient.queryObject(Volume.class, sourceVolume) : null;
VolumeGroup volumeGroup = (source != null) ? source.getApplication(_dbClient) : null;
if (volumeGroup != null && !ControllerUtils.checkVolumeForVolumeGroupPartialRequest(_dbClient, source)) {
_log.info("Creating full copy for Application {}", volumeGroup.getLabel());
// add VolumeGroup to task completer
completer.addVolumeGroupId(volumeGroup.getId());
}
// Generate the Workflow.
Workflow workflow = _workflowService.getNewWorkflow(this, COPY_VOLUMES_WF_NAME, false, opId);
_log.info("Created new full copy workflow with operation id {}", opId);
/**
* Volume descriptors contains
* 1. VPLEX v-volume to be copied (source),
* 2. VPLEX copy v-volume to be created,
* 3. backend source volume to be created as clone for (1)'s backend volume
* 4. Empty volume to be created as HA backend volume for (2) in case of Distributed
*
* Group the given volume descriptors by backend Array Replication Group (RG).
* -For each RG entry, create workflow steps,
* -These RG steps run in parallel
*/
Map<String, List<VolumeDescriptor>> repGroupToVolumeDescriptors = groupDescriptorsByReplicationGroup(volumeDescriptors);
for (String repGroupName : repGroupToVolumeDescriptors.keySet()) {
_log.info("Processing Array Replication Group {}", repGroupName);
List<URI> vplexCopyVolumeURIs = new ArrayList<URI>();
List<VolumeDescriptor> volumeDescriptorsRG = repGroupToVolumeDescriptors.get(repGroupName);
// We need to know which of the passed volume descriptors represents
// the VPLEX virtual volumes that are being copied. We also remove it
// from the list, so the only VPLEX volumes in the list are those
// of the copies.
List<VolumeDescriptor> vplexVolumeDescriptors = VolumeDescriptor.filterByType(volumeDescriptorsRG, new VolumeDescriptor.Type[] { Type.VPLEX_VIRT_VOLUME }, new VolumeDescriptor.Type[] {});
List<VolumeDescriptor> vplexSrcVolumeDescrs = getDescriptorsForFullCopySrcVolumes(vplexVolumeDescriptors);
vplexVolumeDescriptors.removeAll(vplexSrcVolumeDescrs);
_log.info("Got volume descriptors for VPLEX volumes being copied.");
// Get the URIs of the VPLEX copy volumes.
vplexCopyVolumeURIs.addAll(VolumeDescriptor.getVolumeURIs(vplexVolumeDescriptors));
vplexURI = getDataObject(Volume.class, vplexCopyVolumeURIs.get(0), _dbClient).getStorageController();
// Add a rollback step to make sure all full copies are
// marked inactive and that the full copy relationships
// are updated. This will also mark any HA backend volumes
// inactive in the case the copies are distributed. The
// step only provides functionality on rollback. Normal
// execution is a no-op.
List<URI> volumesToMarkInactive = new ArrayList<URI>();
volumesToMarkInactive.addAll(vplexCopyVolumeURIs);
List<VolumeDescriptor> blockDescriptors = VolumeDescriptor.filterByType(volumeDescriptorsRG, new VolumeDescriptor.Type[] { Type.BLOCK_DATA }, new VolumeDescriptor.Type[] {});
if (!blockDescriptors.isEmpty()) {
volumesToMarkInactive.addAll(VolumeDescriptor.getVolumeURIs(blockDescriptors));
}
StorageSystem vplexSystem = getDataObject(StorageSystem.class, vplexURI, _dbClient);
Workflow.Method executeMethod = rollbackMethodNullMethod();
Workflow.Method rollbackMethod = markVolumesInactiveMethod(volumesToMarkInactive);
String waitFor = workflow.createStep(null, "Mark volumes inactive on rollback", null, vplexURI, vplexSystem.getSystemType(), this.getClass(), executeMethod, rollbackMethod, null);
if (!vplexSrcVolumeDescrs.isEmpty()) {
// Find the backend volume that is the primary volume for one of
// the VPLEX volumes being copied. The primary backend volume is the
// associated volume in the same virtual array as the VPLEX volume.
// It does not matter which one if there are multiple source VPLEX
// volumes. These volumes will all be in a consistency group and
// use the same backend storage system.
VolumeDescriptor vplexSrcVolumeDescr = vplexSrcVolumeDescrs.get(0);
vplexSrcVolumeURI = vplexSrcVolumeDescr.getVolumeURI();
BlockObject primarySourceObject = getPrimaryForFullCopySrcVolume(vplexSrcVolumeURI);
_log.info("Primary volume/snapshot is {}", primarySourceObject.getId());
// add CG to taskCompleter
if (!NullColumnValueGetter.isNullURI(primarySourceObject.getConsistencyGroup())) {
completer.addConsistencyGroupId(primarySourceObject.getConsistencyGroup());
}
}
// Next, create a step to create and start an import volume
// workflow for each copy.
createStepsForFullCopyImport(workflow, vplexURI, vplexVolumeDescriptors, volumeDescriptorsRG, waitFor);
_log.info("Created workflow steps to import the primary copies");
}
_log.info("Executing workflow plan");
FullCopyOperationCompleteCallback wfCompleteCB = new FullCopyOperationCompleteCallback();
workflow.executePlan(completer, String.format("Copy of VPLEX volume %s completed successfully", vplexSrcVolumeURI), wfCompleteCB, new Object[] { vplexCopyVolumesURIs }, null, null);
_log.info("Workflow plan executing");
} catch (Exception e) {
String failMsg = String.format("Copy of VPLEX volume %s failed", vplexSrcVolumeURI);
_log.error(failMsg, e);
ServiceError serviceError = VPlexApiException.errors.fullCopyVolumesFailed((vplexSrcVolumeURI != null ? vplexSrcVolumeURI.toString() : ""), e);
failStep(completer, opId, serviceError);
}
}
use of com.emc.storageos.db.client.model.VolumeGroup in project coprhd-controller by CoprHD.
the class BlockConsistencyGroupRemoveVolumeCompleter method complete.
@Override
protected void complete(DbClient dbClient, Status status, ServiceCoded coded) throws DeviceControllerException {
log.info("Updating removed volume replicationGroupInstance");
try {
if (status == Status.ready && !keepRGReference) {
for (URI blockObjectURI : removedVolumeList) {
BlockObject blockObject = BlockObject.fetch(dbClient, blockObjectURI);
if (blockObject != null) {
boolean isVplexBackendVolume = false;
if (blockObject instanceof Volume) {
VolumeGroup volumeGroup = ((Volume) blockObject).getApplication(dbClient);
if (volumeGroup != null) {
((Volume) blockObject).getVolumeGroupIds().remove(volumeGroup.getId().toString());
}
isVplexBackendVolume = Volume.checkForVplexBackEndVolume(dbClient, (Volume) blockObject);
}
if (!NullColumnValueGetter.isNullURI(blockObject.getConsistencyGroup())) {
BlockConsistencyGroup cg = dbClient.queryObject(BlockConsistencyGroup.class, blockObject.getConsistencyGroup());
if (!cg.checkForType(BlockConsistencyGroup.Types.RP)) {
blockObject.setConsistencyGroup(NullColumnValueGetter.getNullURI());
}
}
blockObject.setReplicationGroupInstance(NullColumnValueGetter.getNullStr());
// instance on the parent virtual volume
if (isVplexBackendVolume) {
Volume virtualVolume = Volume.fetchVplexVolume(dbClient, (Volume) blockObject);
if (null != virtualVolume) {
virtualVolume.setBackingReplicationGroupInstance(NullColumnValueGetter.getNullStr());
dbClient.updateObject(virtualVolume);
}
}
}
dbClient.updateObject(blockObject);
}
}
super.complete(dbClient, status, coded);
} catch (Exception e) {
log.error("Failed updating status. BlockConsistencyGroupRemoveVolume {}, for task " + getOpId(), getId(), e);
}
}
Aggregations