Search in sources :

Example 1 with VirtualPoolCapabilityValuesWrapper

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;
    }
}
Also used : VirtualPoolCapabilityValuesWrapper(com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper) VirtualArray(com.emc.storageos.db.client.model.VirtualArray) VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) VPlexController(com.emc.storageos.vplexcontroller.VPlexController) ArrayList(java.util.ArrayList) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) URISyntaxException(java.net.URISyntaxException) Operation(com.emc.storageos.db.client.model.Operation) FCTN_STRING_TO_URI(com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_STRING_TO_URI) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) FCTN_VPLEX_MIRROR_TO_URI(com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_VPLEX_MIRROR_TO_URI) SRDFCopyRecommendation(com.emc.storageos.volumecontroller.SRDFCopyRecommendation) VolumeRecommendation(com.emc.storageos.api.service.impl.placement.VolumeRecommendation) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) Recommendation(com.emc.storageos.volumecontroller.Recommendation) SRDFRecommendation(com.emc.storageos.volumecontroller.SRDFRecommendation) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) Project(com.emc.storageos.db.client.model.Project) Volume(com.emc.storageos.db.client.model.Volume) StringSet(com.emc.storageos.db.client.model.StringSet) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 2 with VirtualPoolCapabilityValuesWrapper

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());
        }
    }
}
Also used : VirtualPoolCapabilityValuesWrapper(com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper) VirtualArray(com.emc.storageos.db.client.model.VirtualArray) RPProtectionRecommendation(com.emc.storageos.volumecontroller.RPProtectionRecommendation) SwapContainer(com.emc.storageos.api.service.impl.placement.RecoverPointScheduler.SwapContainer) ArrayList(java.util.ArrayList) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) AlternateIdConstraint(com.emc.storageos.db.client.constraint.AlternateIdConstraint) Recommendation(com.emc.storageos.volumecontroller.Recommendation) RPRecommendation(com.emc.storageos.volumecontroller.RPRecommendation) RPProtectionRecommendation(com.emc.storageos.volumecontroller.RPProtectionRecommendation) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) InternalServerErrorException(com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) APIException(com.emc.storageos.svcs.errorhandling.resources.APIException) RecoverPointException(com.emc.storageos.recoverpoint.exceptions.RecoverPointException) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) Volume(com.emc.storageos.db.client.model.Volume) RPRecommendation(com.emc.storageos.volumecontroller.RPRecommendation)

Example 3 with VirtualPoolCapabilityValuesWrapper

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;
}
Also used : VirtualPoolCapabilityValuesWrapper(com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper) VirtualArray(com.emc.storageos.db.client.model.VirtualArray) VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) BlockOrchestrationController(com.emc.storageos.blockorchestrationcontroller.BlockOrchestrationController) HashMap(java.util.HashMap) TaskList(com.emc.storageos.model.TaskList) ArrayList(java.util.ArrayList) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) URI(java.net.URI) APIException(com.emc.storageos.svcs.errorhandling.resources.APIException) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) Volume(com.emc.storageos.db.client.model.Volume) VolumeRecommendation(com.emc.storageos.api.service.impl.placement.VolumeRecommendation) BlockObject(com.emc.storageos.db.client.model.BlockObject)

Example 4 with VirtualPoolCapabilityValuesWrapper

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;
}
Also used : VirtualPoolCapabilityValuesWrapper(com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper) VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) Volume(com.emc.storageos.db.client.model.Volume) ArrayList(java.util.ArrayList)

Example 5 with VirtualPoolCapabilityValuesWrapper

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);
}
Also used : VirtualPoolCapabilityValuesWrapper(com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper) VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) BlockOrchestrationController(com.emc.storageos.blockorchestrationcontroller.BlockOrchestrationController) ArrayList(java.util.ArrayList) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Aggregations

VirtualPoolCapabilityValuesWrapper (com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper)65 ArrayList (java.util.ArrayList)50 VirtualArray (com.emc.storageos.db.client.model.VirtualArray)44 VirtualPool (com.emc.storageos.db.client.model.VirtualPool)44 Project (com.emc.storageos.db.client.model.Project)41 URI (java.net.URI)34 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)33 NamedURI (com.emc.storageos.db.client.model.NamedURI)32 List (java.util.List)31 StoragePool (com.emc.storageos.db.client.model.StoragePool)28 StringSet (com.emc.storageos.db.client.model.StringSet)25 Volume (com.emc.storageos.db.client.model.Volume)22 RPProtectionRecommendation (com.emc.storageos.volumecontroller.RPProtectionRecommendation)22 RPRecommendation (com.emc.storageos.volumecontroller.RPRecommendation)22 BlockConsistencyGroup (com.emc.storageos.db.client.model.BlockConsistencyGroup)21 Recommendation (com.emc.storageos.volumecontroller.Recommendation)21 TenantOrg (com.emc.storageos.db.client.model.TenantOrg)20 Test (org.junit.Test)20 Network (com.emc.storageos.db.client.model.Network)19 StringMap (com.emc.storageos.db.client.model.StringMap)19