use of com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper in project coprhd-controller by CoprHD.
the class VPlexBlockServiceApiImpl method importVirtualVolume.
/**
* Import an existing volume to a VPLEX to make it a Virtual Volume.
* Outline: 1. Determine the VPLEX(s) that could be used. 2. If this is to
* become a distributed virtual volume, get a Recommendation for the pool
* for the haVirtualArray of the Virtual Volume. 3. Create a Virtual Volume
* and link it to the existing Volume. 4. If this is a distributed virtual
* volume, create a new Volume and link it to the virtual volume. 5. Format
* the parameters and call the controller.
*
* @param arrayURI -- the URI of the Storage Array holding the existing
* Volume.
* @param importVolume -- An existing Volume that has been provisioned.
* @param vpool -- The vpool requested on the vpool change request.
* @param taskId -- The taskId
* @throws InternalException
*/
public void importVirtualVolume(URI arrayURI, Volume importVolume, VirtualPool vpool, String taskId) throws InternalException {
VirtualArray neighborhood = _dbClient.queryObject(VirtualArray.class, importVolume.getVirtualArray());
Project project = _dbClient.queryObject(Project.class, importVolume.getProject());
URI nullPoolURI = NullColumnValueGetter.getNullURI();
BlockConsistencyGroup consistencyGroup = null;
if (importVolume.getConsistencyGroup() != null) {
consistencyGroup = _dbClient.queryObject(BlockConsistencyGroup.class, importVolume.getConsistencyGroup());
}
// Determine the VPLEX(s) that could be used.
Set<URI> vplexes = ConnectivityUtil.getVPlexSystemsAssociatedWithArray(_dbClient, arrayURI);
Iterator<URI> vplexIter = vplexes.iterator();
while (vplexIter.hasNext()) {
StorageSystem vplex = _dbClient.queryObject(StorageSystem.class, vplexIter.next());
StringSet vplexVarrays = vplex.getVirtualArrays();
if ((vplexVarrays == null) || (vplexVarrays.isEmpty()) || (!vplexVarrays.contains(neighborhood.getId().toString()))) {
vplexIter.remove();
}
}
if (vplexes.isEmpty()) {
throw APIException.badRequests.noVPlexSystemsAssociatedWithStorageSystem(arrayURI);
}
// If distributed virtual volume, get a recommendation.
// Then create the volume.
List<VolumeDescriptor> descriptors = new ArrayList<VolumeDescriptor>();
URI vplexURI = null;
StorageSystem vplexSystem = null;
Volume createVolume = null;
Project vplexProject;
if (vpool.getHighAvailability().equals(VirtualPool.HighAvailabilityType.vplex_distributed.name())) {
// Determine if the user requested a specific HA VirtualArray and an associated HA VirtualPool.
VirtualArray requestedHaVarray = null;
VirtualPool requestedHaVirtualPool = vpool;
try {
if (vpool.getHaVarrayVpoolMap() != null && !vpool.getHaVarrayVpoolMap().isEmpty()) {
for (String haNH : vpool.getHaVarrayVpoolMap().keySet()) {
if (haNH.equals(NullColumnValueGetter.getNullURI().toString())) {
continue;
}
requestedHaVarray = _dbClient.queryObject(VirtualArray.class, new URI(haNH));
String haVirtualPool = vpool.getHaVarrayVpoolMap().get(haNH);
if (haVirtualPool.equals(NullColumnValueGetter.getNullURI().toString())) {
continue;
}
requestedHaVirtualPool = _dbClient.queryObject(VirtualPool.class, new URI(haVirtualPool));
break;
}
}
} catch (URISyntaxException ex) {
s_logger.error("URISyntaxException", ex);
}
VirtualPoolCapabilityValuesWrapper cosCapabilities = new VirtualPoolCapabilityValuesWrapper();
cosCapabilities.put(VirtualPoolCapabilityValuesWrapper.SIZE, getVolumeCapacity(importVolume));
cosCapabilities.put(VirtualPoolCapabilityValuesWrapper.RESOURCE_COUNT, new Integer(1));
cosCapabilities.put(VirtualPoolCapabilityValuesWrapper.THIN_PROVISIONING, importVolume.getThinlyProvisioned());
// Get the recommendations and pick one.
List<Recommendation> recommendations = getBlockScheduler().scheduleStorageForImport(neighborhood, vplexes, requestedHaVarray, requestedHaVirtualPool, cosCapabilities);
if (recommendations.isEmpty()) {
throw APIException.badRequests.noStorageFoundForVolumeMigration(requestedHaVirtualPool.getLabel(), requestedHaVarray.getLabel(), importVolume.getId());
}
Recommendation recommendation = recommendations.get(0);
VPlexRecommendation vplexRecommendation = (VPlexRecommendation) recommendation;
vplexURI = vplexRecommendation.getVPlexStorageSystem();
vplexSystem = _dbClient.queryObject(StorageSystem.class, vplexURI);
vplexProject = getVplexProject(vplexSystem, _dbClient, _tenantsService);
// Prepare the created volume.
VirtualArray haVirtualArray = _dbClient.queryObject(VirtualArray.class, vplexRecommendation.getVirtualArray());
createVolume = prepareVolumeForRequest(getVolumeCapacity(importVolume), vplexProject, haVirtualArray, vpool, vplexRecommendation.getSourceStorageSystem(), vplexRecommendation.getSourceStoragePool(), importVolume.getLabel() + "-1", ResourceOperationTypeEnum.CREATE_BLOCK_VOLUME, taskId, _dbClient);
createVolume.addInternalFlags(Flag.INTERNAL_OBJECT);
_dbClient.updateObject(createVolume);
VolumeDescriptor desc = new VolumeDescriptor(VolumeDescriptor.Type.BLOCK_DATA, createVolume.getStorageController(), createVolume.getId(), createVolume.getPool(), cosCapabilities);
descriptors.add(desc);
} else {
vplexURI = vplexes.toArray(new URI[0])[0];
vplexSystem = _dbClient.queryObject(StorageSystem.class, vplexURI);
vplexProject = getVplexProject(vplexSystem, _dbClient, _tenantsService);
}
// Prepare the VPLEX Virtual volume.
Volume vplexVolume = prepareVolumeForRequest(getVolumeCapacity(importVolume), project, neighborhood, vpool, vplexURI, nullPoolURI, importVolume.getLabel(), ResourceOperationTypeEnum.CREATE_BLOCK_VOLUME, taskId, _dbClient);
vplexVolume.setAssociatedVolumes(new StringSet());
vplexVolume.getAssociatedVolumes().add(importVolume.getId().toString());
if (createVolume != null) {
vplexVolume.getAssociatedVolumes().add(createVolume.getId().toString());
}
if (consistencyGroup != null) {
// If the volume being converted to a virtual volume has a CG, make the virtual
// volume a member of the CG.
vplexVolume.setConsistencyGroup(consistencyGroup.getId());
consistencyGroup.addRequestedTypes(Arrays.asList(BlockConsistencyGroup.Types.VPLEX.name()));
_dbClient.updateObject(consistencyGroup);
}
vplexVolume.setVirtualPool(vpool.getId());
_dbClient.updateObject(vplexVolume);
// Add a descriptor for the VPLEX_VIRT_VOLUME
VolumeDescriptor desc = new VolumeDescriptor(VolumeDescriptor.Type.VPLEX_VIRT_VOLUME, vplexURI, vplexVolume.getId(), null, null);
descriptors.add(desc);
// Add a descriptor for the import volume too!
desc = new VolumeDescriptor(VolumeDescriptor.Type.VPLEX_IMPORT_VOLUME, importVolume.getStorageController(), importVolume.getId(), importVolume.getPool(), null);
descriptors.add(desc);
// Now send the command to the controller.
try {
s_logger.info("Calling VPlex controller.");
VPlexController controller = getController();
controller.importVolume(vplexURI, descriptors, vplexProject.getId(), vplexProject.getTenantOrg().getURI(), vpool.getId(), importVolume.getLabel() + SRC_BACKEND_VOL_LABEL_SUFFIX, null, Boolean.TRUE, taskId);
} catch (InternalException ex) {
s_logger.error("ControllerException on importVolume", ex);
String errMsg = String.format("ControllerException: %s", ex.getMessage());
Operation statusUpdate = new Operation(Operation.Status.error.name(), errMsg);
_dbClient.updateTaskOpStatus(Volume.class, vplexVolume.getId(), taskId, statusUpdate);
_dbClient.markForDeletion(vplexVolume);
if (createVolume != null) {
_dbClient.markForDeletion(createVolume);
}
throw ex;
}
}
use of com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper in project coprhd-controller by CoprHD.
the class RPBlockServiceApiImpl method prepareRecommendedVolumes.
/**
* Prepare Recommended Volumes for Protected scenarios only.
*
* This method is responsible for acting the same as the unprotected "prepareRecommendedVolumes" call,
* however it needs to create multiple volumes per single volume requests in order to generate protection.
*
* Those most typical scenario is, that for any one volume requested in a CRR configuration, we create:
* 1. One Source Volume
* 2. One Source Journal Volume (minimum 10GB, otherwise 2.5X source size)
* 3. One Target Volume on protection varray
* 4. One Target Journal Volume on protection varray
*
* In a CLR configuration, there are additional volumes created for the Local Target and Local Target Journal.
*
* This method will assemble a ProtectionSet object in Cassandra that will describe the Protection that
* will be created on the Protection System.
*
* When other protection mechanisms come on board, the RP-ness of this method will need to be pulled out.
*
* @param param volume create request
* @param task task from request or generated
* @param taskList task list
* @param project project from request
* @param originalVarray varray from request
* @param originalVpool vpool from request
* @param numberOfVolumesInRequest volume count from the request
* @param recommendations list of resulting recommendations from placement
* @param consistencyGroup consistency group ID
* @param capabilities Capabilities object
* @param descriptors List of descriptors to be populated
* @param volumeURIs List to hold volumes that have been prepared
*/
private void prepareRecommendedVolumes(VolumeCreate param, String task, TaskList taskList, Project project, VirtualArray originalVarray, VirtualPool originalVpool, Integer numberOfVolumesInRequest, List<Recommendation> recommendations, String volumeLabel, VirtualPoolCapabilityValuesWrapper capabilities, List<VolumeDescriptor> descriptors, List<URI> volumeURIs) throws APIException {
boolean isChangeVpool = false;
boolean isChangeVpoolForProtectedVolume = false;
boolean isSrcAndHaSwapped = VirtualPool.isRPVPlexProtectHASide(originalVpool);
boolean metroPointEnabled = VirtualPool.vPoolSpecifiesMetroPoint(originalVpool);
// This copy of capabilities object is meant to be used by all volume prepares that require changing data,
// which is our case is TARGET and JOURNALS. SOURCE will use always use the main capabilities object.
VirtualPoolCapabilityValuesWrapper copyOfCapabilities = new VirtualPoolCapabilityValuesWrapper(capabilities);
// Set the volume name from the param
String volumeName = volumeLabel;
// Need to check if we should swap src and ha, call the block scheduler code to
// find out. Nothing will be changed for MetroPoint.
VirtualArray haVarray = null;
VirtualPool haVpool = null;
SwapContainer container = this.getBlockScheduler().new SwapContainer();
container.setSrcVarray(originalVarray);
container.setSrcVpool(originalVpool);
container.setHaVarray(haVarray);
container.setHaVpool(haVpool);
container = RecoverPointScheduler.initializeSwapContainer(container, _dbClient);
// Use the new references post swap
VirtualArray varray = container.getSrcVarray();
VirtualPool vpool = container.getSrcVpool();
// Save a reference to the CG, we'll need this later
BlockConsistencyGroup consistencyGroup = capabilities.getBlockConsistencyGroup() == null ? null : _dbClient.queryObject(BlockConsistencyGroup.class, capabilities.getBlockConsistencyGroup());
// Total volumes to be created
int totalVolumeCount = 0;
// Create an entire Protection object for each recommendation result.
Iterator<Recommendation> recommendationsIter = recommendations.iterator();
while (recommendationsIter.hasNext()) {
RPProtectionRecommendation rpProtectionRec = (RPProtectionRecommendation) recommendationsIter.next();
URI protectionSystemURI = rpProtectionRec.getProtectionDevice();
URI changeVpoolVolumeURI = rpProtectionRec.getVpoolChangeVolume();
Volume changeVpoolVolume = (changeVpoolVolumeURI == null ? null : _dbClient.queryObject(Volume.class, changeVpoolVolumeURI));
isChangeVpool = (changeVpoolVolumeURI != null);
isChangeVpoolForProtectedVolume = rpProtectionRec.isVpoolChangeProtectionAlreadyExists();
boolean addJournalForStandbySourceCopy = capabilities.getAddJournalCapacity() && (rpProtectionRec.getStandbyJournalRecommendation() != null);
String newVolumeLabel = volumeName;
// Find the Source RP Copy Name
String sourceCopyName = retrieveRpCopyName(originalVpool, varray, consistencyGroup, true);
String standbySourceCopyName = "";
if (addJournalForStandbySourceCopy) {
// Find the Source Standby RP Copy Name - for add journal operation
standbySourceCopyName = retrieveRpCopyName(originalVpool, varray, consistencyGroup, true);
}
if (metroPointEnabled) {
// Find the Source Standby RP Copy Name - for MetorPoint
haVarray = _dbClient.queryObject(VirtualArray.class, VPlexUtil.getHAVarray(originalVpool));
standbySourceCopyName = retrieveRpCopyName(originalVpool, haVarray, consistencyGroup, true);
}
StringBuffer volumeInfoBuffer = new StringBuffer();
volumeInfoBuffer.append(String.format(NEW_LINE));
// Prepare the Journals first
try {
prepareRpJournals(rpProtectionRec, project, consistencyGroup, vpool, originalVpool, param, numberOfVolumesInRequest, newVolumeLabel, isChangeVpoolForProtectedVolume, copyOfCapabilities, protectionSystemURI, taskList, task, descriptors, volumeURIs, volumeInfoBuffer, sourceCopyName, standbySourceCopyName);
} catch (Exception e) {
_log.error("Error trying to prepare RP Journal volumes", e);
throw APIException.badRequests.rpBlockApiImplPrepareVolumeException(newVolumeLabel);
}
// Prepare the source and targets
if (rpProtectionRec.getSourceRecommendations() != null) {
for (RPRecommendation sourceRec : rpProtectionRec.getSourceRecommendations()) {
// Get a reference to all existing VPLEX Source volumes (if any)
List<Volume> allSourceVolumesInCG = BlockConsistencyGroupUtils.getActiveVplexVolumesInCG(consistencyGroup, _dbClient, Volume.PersonalityTypes.SOURCE);
// first MP volume of a new CG.
if (metroPointEnabled && allSourceVolumesInCG.isEmpty()) {
validateMetroPointType(sourceRec.getMetroPointType());
}
// Get the number of volumes needed to be created for this recommendation.
int volumeCountInRec = sourceRec.getResourceCount();
// All source volumes will share the same secondary journal.
if (isChangeVpoolForProtectedVolume) {
_log.info(String.format("Change Virtual Pool Protected: %d existing source volume(s) in CG [%s](%s) are affected.", allSourceVolumesInCG.size(), consistencyGroup.getLabel(), consistencyGroup.getId()));
// Force the count to the number of existing source volumes in the CG.
volumeCountInRec = allSourceVolumesInCG.size();
}
// Grab a handle of the haRec, it could be null which is Ok.
RPRecommendation haRec = sourceRec.getHaRecommendation();
for (int volumeCount = 0; volumeCount < volumeCountInRec; volumeCount++) {
// Let's not get into multiple of multiples, this class will handle multi volume creates.
// So force the incoming VolumeCreate param to be set to 1 always from here on.
sourceRec.setResourceCount(1);
if (haRec != null) {
haRec.setResourceCount(1);
}
newVolumeLabel = generateDefaultVolumeLabel(volumeName, totalVolumeCount, numberOfVolumesInRequest);
// Grab the existing volume and task object from the incoming task list
Volume preCreatedVolume = StorageScheduler.getPrecreatedVolume(_dbClient, taskList, newVolumeLabel);
// Assemble a Replication Set; A Collection of volumes. One production, and any number of
// targets.
String rsetName = "RSet-" + newVolumeLabel;
// Increment total volume count
totalVolumeCount++;
// This name has to remain unique, especially when the number of volumes requested to be created
// is more than 1.
param.setName(newVolumeLabel);
Volume sourceVolume = null;
// /////// SOURCE ///////////
if (!isChangeVpoolForProtectedVolume) {
if (isChangeVpool) {
_log.info(String.format("Change Vpool, use existing Source Volume [%s].", changeVpoolVolume.getLabel()));
} else {
_log.info("Create RP Source Volume...");
}
// Create the source
sourceVolume = createRecoverPointVolume(sourceRec, newVolumeLabel, project, capabilities, consistencyGroup, param, protectionSystemURI, Volume.PersonalityTypes.SOURCE, rsetName, preCreatedVolume, null, taskList, task, sourceCopyName, descriptors, changeVpoolVolume, isChangeVpool, isSrcAndHaSwapped, true);
} else {
if (metroPointEnabled) {
_log.info("Upgrade to MetroPoint operation...");
// in the CG to reference the newly created stand-by journal.
for (Volume sourceVol : allSourceVolumesInCG) {
_log.info(String.format("Update the source volume [%s](%s) with new standby journal.", sourceVol.getLabel(), sourceVol.getId()));
// All RP+VPLEX Metro volumes in this CG need to have their backing volume
// references updated with the internal site names for exports.
setInternalSitesForSourceBackingVolumes(sourceRec, haRec, sourceVol, true, false, originalVpool.getHaVarrayConnectedToRp(), sourceCopyName, standbySourceCopyName);
// We need to have all the existing RP+VPLEX Metro volumes from the CG
// added to the volumeURI list so we can properly export the standby
// leg to RP for each volume.
volumeURIs.add(sourceVol.getId());
}
} else {
// NOTE: Upgrade to MetroPoint is (currently) the only supported Change Virtual Pool Protected
// operation, so if we have a null standby journal we're in real trouble.
_log.error("Error trying to upgrade to MetroPoint. Standby journal is null.");
throw APIException.badRequests.rpBlockApiImplPrepareVolumeException(newVolumeLabel);
}
// past this point.
break;
}
volumeURIs.add(sourceVolume.getId());
// NOTE: This is only needed for MetroPoint and Distributed RP+VPLEX(HA as RP source),
// nothing will happen for regular RP volumes.
//
// Source volumes need to have their backing volumes set with the correct internal
// site name. The reason for this is so we know later on where to export the volumes to.
//
// This is very evident with MetroPoint as we need to export BOTH sides of the VPLEX Distributed
// Volume.
//
// This is less evident with Distributed RP+VPLEX that has "HA as RP source" set.
// In this case we need to set it on the HA volume as that is the side to export (not the source
// side).
// To do this we need to pass in a hint...
// We need the (unswapped) original vpool and we then check the getHaVarrayConnectedToRp() value
// which tells us
// which side(varray) to export.
// This value will only be used if isSrcAndHaSwapped == true.
setInternalSitesForSourceBackingVolumes(sourceRec, haRec, sourceVolume, metroPointEnabled, isSrcAndHaSwapped, originalVpool.getHaVarrayConnectedToRp(), sourceCopyName, standbySourceCopyName);
// /////// TARGET(S) ///////////
List<URI> protectionTargets = new ArrayList<URI>();
for (RPRecommendation targetRec : sourceRec.getTargetRecommendations()) {
// Keep track of the targets created
protectionTargets.add(targetRec.getVirtualArray());
// Grab the target's varray
VirtualArray targetVirtualArray = _dbClient.queryObject(VirtualArray.class, targetRec.getVirtualArray());
_log.info(String.format("Create Target (%s)...", targetVirtualArray.getLabel()));
// to provision this target.
if (isChangeVpoolForProtectedVolume) {
Volume alreadyProvisionedTarget = RPHelper.findAlreadyProvisionedTargetVolume(changeVpoolVolume, targetRec.getVirtualArray(), _dbClient);
if (alreadyProvisionedTarget != null) {
_log.info(String.format("Existing target volume [%s] found for varray [%s].", alreadyProvisionedTarget.getLabel(), targetVirtualArray.getLabel()));
// No need to go further, continue on to the next target varray
continue;
}
}
// Generate target volume name
String targetVolumeName = new StringBuilder(newVolumeLabel).append(VOLUME_TYPE_TARGET + targetVirtualArray.getLabel()).toString();
// Create the target
Volume targetVolume = createRecoverPointVolume(targetRec, targetVolumeName, project, copyOfCapabilities, consistencyGroup, param, protectionSystemURI, Volume.PersonalityTypes.TARGET, rsetName, null, sourceVolume, taskList, task, targetRec.getRpCopyName(), descriptors, null, false, false, false);
volumeInfoBuffer.append(logVolumeInfo(targetVolume));
volumeURIs.add(targetVolume.getId());
}
// /////// METROPOINT LOCAL TARGET(S) ///////////
if (metroPointEnabled && haRec.getTargetRecommendations() != null && !haRec.getTargetRecommendations().isEmpty()) {
// then we need to create targets for the second (stand-by) leg.
for (RPRecommendation standbyTargetRec : haRec.getTargetRecommendations()) {
// Grab the MP target's varray
VirtualArray standyTargetVirtualArray = _dbClient.queryObject(VirtualArray.class, standbyTargetRec.getVirtualArray());
_log.info(String.format("Create Standby Target (%s)..", standyTargetVirtualArray.getLabel()));
// source recommendation.
if (protectionTargets.contains(standbyTargetRec.getVirtualArray())) {
continue;
}
// standby.
if (isChangeVpoolForProtectedVolume) {
Volume alreadyProvisionedTarget = RPHelper.findAlreadyProvisionedTargetVolume(changeVpoolVolume, standyTargetVirtualArray.getId(), _dbClient);
if (alreadyProvisionedTarget != null) {
_log.info(String.format("Existing target volume [%s] found for varray [%s].", alreadyProvisionedTarget.getLabel(), standyTargetVirtualArray.getLabel()));
// No need to go further, continue on to the next target varray
continue;
}
}
// Generate standby target label
String standbyTargetVolumeName = new StringBuilder(newVolumeLabel).append(VOLUME_TYPE_TARGET + standyTargetVirtualArray.getLabel()).toString();
// Create the standby target
Volume standbyTargetVolume = createRecoverPointVolume(standbyTargetRec, standbyTargetVolumeName, project, copyOfCapabilities, consistencyGroup, param, protectionSystemURI, Volume.PersonalityTypes.TARGET, rsetName, null, sourceVolume, taskList, task, standbyTargetRec.getRpCopyName(), descriptors, null, false, false, false);
volumeInfoBuffer.append(logVolumeInfo(standbyTargetVolume));
volumeURIs.add(standbyTargetVolume.getId());
}
}
// Hold off on logging the source volume until we're done creating the targets
volumeInfoBuffer.append(logVolumeInfo(sourceVolume));
}
}
volumeInfoBuffer.append(String.format(NEW_LINE));
_log.info(volumeInfoBuffer.toString());
}
}
}
use of com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper in project coprhd-controller by CoprHD.
the class DefaultBlockFullCopyApiImpl method create.
/**
* {@inheritDoc}
*/
@Override
public TaskList create(List<BlockObject> fcSourceObjList, VirtualArray varray, String name, boolean createInactive, int count, String taskId) {
// Get the placement recommendations for the full copies and
// prepare the ViPR volumes to represent the full copies.
// TBD We are getting recommendations one at a time instead
// of for all full copies at the same time as was done
// previously. However, now we are allowing for creating
// full copies for multiple volume form a CG. These volumes
// could have different vpools and sizes. Therefore, I don't
// see how we can get them at the same time for all volumes
// as the capabilities could be different. I guess the
// possible result is that if the volumes are the same, they
// could be placed in the same storage pool and if the pool
// is approaching capacity, there may not actually be enough
// space in the recommended pool.
int sourceCounter = 0;
List<Volume> volumesList = new ArrayList<Volume>();
BlockObject aFCSource = null;
Map<URI, VirtualArray> vArrayCache = new HashMap<URI, VirtualArray>();
List<BlockObject> sortedSourceObjectList = sortFullCopySourceList(fcSourceObjList);
try {
for (BlockObject fcSourceObj : sortedSourceObjectList) {
// Make sure when there are multiple source objects,
// each full copy has a unique name.
aFCSource = fcSourceObj;
// volumes in VolumeGroup can be from different vArrays
varray = getVarrayFromCache(vArrayCache, fcSourceObj.getVirtualArray());
String copyName = null;
boolean inApplication = false;
if (aFCSource instanceof Volume && ((Volume) aFCSource).getApplication(_dbClient) != null) {
inApplication = true;
}
if (NullColumnValueGetter.isNotNullValue(fcSourceObj.getReplicationGroupInstance()) && inApplication) {
copyName = name + "-" + fcSourceObj.getReplicationGroupInstance() + (sortedSourceObjectList.size() > 1 ? "-" + ++sourceCounter : "");
} else {
copyName = name + (sortedSourceObjectList.size() > 1 ? "-" + ++sourceCounter : "");
}
VirtualPool vpool = BlockFullCopyUtils.queryFullCopySourceVPool(fcSourceObj, _dbClient);
VirtualPoolCapabilityValuesWrapper capabilities = getCapabilitiesForFullCopyCreate(fcSourceObj, vpool, count);
List<VolumeRecommendation> placementRecommendations = getPlacementRecommendations(fcSourceObj, capabilities, varray, vpool.getId());
volumesList.addAll(prepareClonesForEachRecommendation(copyName, name, fcSourceObj, capabilities, createInactive, placementRecommendations));
}
} catch (Exception ex) {
handlePlacementFailure(volumesList);
throw ex;
}
// get volume descriptors
List<VolumeDescriptor> volumeDescriptors = prepareVolumeDescriptorsForFullCopy(volumesList, createInactive);
// get all tasks
TaskList tasks = getTasksForCreateFullCopy(aFCSource, volumesList, taskId);
try {
BlockOrchestrationController controller = getController(BlockOrchestrationController.class, BlockOrchestrationController.BLOCK_ORCHESTRATION_DEVICE);
controller.createFullCopy(volumeDescriptors, taskId);
} catch (InternalException ie) {
handleFailedRequest(taskId, tasks, volumesList, ie, true);
}
return tasks;
}
use of com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper in project coprhd-controller by CoprHD.
the class DefaultBlockFullCopyApiImpl method prepareVolumeDescriptorsForFullCopy.
/**
* creates volume descriptors based on the recommendations from placement
*
* @param volumes volume list that came from the placement algorithm
* @param createInactive flag to determine if the clone should be activated or not
* @return a list of volume descriptors
*/
private List<VolumeDescriptor> prepareVolumeDescriptorsForFullCopy(List<Volume> volumes, boolean createInactive) {
// Build up a list of VolumeDescriptors based on the volumes
final List<VolumeDescriptor> volumeDescriptors = new ArrayList<VolumeDescriptor>();
VirtualPoolCapabilityValuesWrapper vpoolCapabilities = new VirtualPoolCapabilityValuesWrapper();
vpoolCapabilities.put(VirtualPoolCapabilityValuesWrapper.REPLICA_CREATE_INACTIVE, new Boolean(createInactive).toString());
for (Volume volume : volumes) {
VolumeDescriptor desc = new VolumeDescriptor(VolumeDescriptor.Type.BLOCK_DATA, volume.getStorageController(), volume.getId(), volume.getPool(), volume.getConsistencyGroup(), vpoolCapabilities);
volumeDescriptors.add(desc);
}
return volumeDescriptors;
}
use of com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper in project coprhd-controller by CoprHD.
the class VMAX3BlockSnapshotSessionApiImpl method createSnapshotSession.
/**
* {@inheritDoc}
*/
@Override
public void createSnapshotSession(BlockObject sourceObj, URI snapSessionURI, List<List<URI>> snapSessionSnapshotURIs, String copyMode, String taskId) {
// Invoke the BlockDeviceController to create the array snapshot session and create and link
// target volumes as necessary.
StorageSystem storageSystem = _dbClient.queryObject(StorageSystem.class, sourceObj.getStorageController());
VirtualPoolCapabilityValuesWrapper capabilities = new VirtualPoolCapabilityValuesWrapper();
capabilities.put(VirtualPoolCapabilityValuesWrapper.SNAPSHOT_SESSION_COPY_MODE, copyMode);
VolumeDescriptor sessionDescriptor = new VolumeDescriptor(VolumeDescriptor.Type.BLOCK_SNAPSHOT_SESSION, storageSystem.getId(), snapSessionURI, null, sourceObj.getConsistencyGroup(), capabilities, snapSessionSnapshotURIs);
List<VolumeDescriptor> volumeDescriptors = new ArrayList<VolumeDescriptor>();
volumeDescriptors.add(sessionDescriptor);
BlockOrchestrationController controller = getController(BlockOrchestrationController.class, BlockOrchestrationController.BLOCK_ORCHESTRATION_DEVICE);
controller.createSnapshotSession(volumeDescriptors, taskId);
}
Aggregations