Search in sources :

Example 6 with VPlexRecommendation

use of com.emc.storageos.volumecontroller.VPlexRecommendation in project coprhd-controller by CoprHD.

the class VPlexBlockServiceApiImpl method validateVolumeLabels.

/**
 * Convenient method to generate volume labels and check for duplicate. If there is a duplicate, throw exception
 *
 * @param baseVolumeLabel
 *            - volume prefix
 * @param project
 *            - project volume creates within
 * @param vArray
 *            - virtual array where volume is create
 * @param vPool
 *            - volume's vpool
 * @param vPoolCapabilities
 *            - vpool capabilities
 * @param varrayRecomendationsMap
 *            - map of virtual array to its list of recommendation
 */
private void validateVolumeLabels(String baseVolumeLabel, Project project, VirtualPoolCapabilityValuesWrapper vPoolCapabilities, Map<String, List<VPlexRecommendation>> varrayRecomendationsMap) {
    int varrayCount = 0;
    Iterator<String> varrayIter = varrayRecomendationsMap.keySet().iterator();
    while (varrayIter.hasNext()) {
        String varrayId = varrayIter.next();
        s_logger.info("Processing recommendations for virtual array {}", varrayId);
        int volumeCounter = 0;
        // Sum the resource counts from all recommendations.
        int totalResourceCount = 0;
        for (VPlexRecommendation recommendation : varrayRecomendationsMap.get(varrayId)) {
            totalResourceCount += recommendation.getResourceCount();
        }
        Iterator<VPlexRecommendation> recommendationsIter = varrayRecomendationsMap.get(varrayId).iterator();
        while (recommendationsIter.hasNext()) {
            VPlexRecommendation recommendation = recommendationsIter.next();
            URI storagePoolURI = recommendation.getSourceStoragePool();
            VirtualPool volumeVpool = recommendation.getVirtualPool();
            s_logger.info("Volume virtual pool is {}", volumeVpool.getId().toString());
            vPoolCapabilities.put(VirtualPoolCapabilityValuesWrapper.AUTO_TIER__POLICY_NAME, volumeVpool.getAutoTierPolicyName());
            s_logger.info("Recommendation is for {} resources in pool {}", recommendation.getResourceCount(), storagePoolURI.toString());
            for (int i = 0; i < recommendation.getResourceCount(); i++) {
                // Each volume has a unique label based off the passed
                // value. Note that the way the storage system creates
                // the actual volumes in a multi volume request, the
                // names given the Bourne volumes here likely will not
                // match the names given by the storage system. If desired,
                // we will need to update the actual volumes after they
                // are created to match the names given here. Currently,
                // this is not implemented.
                String volumeLabel = generateVolumeLabel(baseVolumeLabel, varrayCount, volumeCounter, totalResourceCount);
                // throw exception of duplicate found
                validateVolumeLabel(volumeLabel, project);
                s_logger.info("Volume label is {}", volumeLabel);
                volumeCounter++;
            }
        }
        varrayCount++;
    }
}
Also used : VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) 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) PrefixConstraint(com.emc.storageos.db.client.constraint.PrefixConstraint) AlternateIdConstraint(com.emc.storageos.db.client.constraint.AlternateIdConstraint) ContainmentPrefixConstraint(com.emc.storageos.db.client.constraint.ContainmentPrefixConstraint) ContainmentConstraint(com.emc.storageos.db.client.constraint.ContainmentConstraint)

Example 7 with VPlexRecommendation

use of com.emc.storageos.volumecontroller.VPlexRecommendation in project coprhd-controller by CoprHD.

the class VPlexBlockServiceApiImpl method createVPlexVolumeDescriptors.

/**
 * Create the necessary volume descriptors for Vplex volumes, including the backend
 * volume descriptors and the virtual volume descriptors.
 *
 * @param param
 *            - the VolumeCreate parameters
 * @param project
 *            -- user's project
 * @param vArray
 *            -- virtual array volumes are created in
 * @param vPool
 *            -- virtual pool (ROOT) used to create the volumes
 * @param recommendations
 *            -- recommendations received from placement
 * @param task
 *            -- a task identifier
 * @param vPoolCapabilities
 *            - VirtualPoolCapabilitiesWrapper
 * @param blockConsistencyGroupURI
 *            - the block consistency group URI
 * @param taskList
 *            - OUTPUT list of tasks created
 * @param allVolumes
 *            - OUTPUT - list of volumes created
 * @param createTask
 *            -- boolean flag indicating to create tasks
 * @return
 */
public List<VolumeDescriptor> createVPlexVolumeDescriptors(VolumeCreate param, Project project, final VirtualArray vArray, final VirtualPool vPool, List<Recommendation> recommendations, String task, VirtualPoolCapabilityValuesWrapper vPoolCapabilities, URI blockConsistencyGroupURI, TaskList taskList, List<URI> allVolumes, boolean createTask) {
    s_logger.info("Request to create {} VPlex virtual volume(s)", vPoolCapabilities.getResourceCount());
    // Determine if we're processing an SRDF copy so we can set appropriate name.
    boolean srdfCopy = false;
    if (recommendations.get(0).getRecommendation() != null && recommendations.get(0).getRecommendation() instanceof SRDFCopyRecommendation) {
        srdfCopy = true;
    }
    // Sort the recommendations by VirtualArray. There can be up to two
    // VirtualArrays, the requested VirtualArray and the HA VirtualArray
    // either passed or determined by the placement when HA virtual volumes
    // are being created. We also set the VPlex storage system, which
    // should be the same for all recommendations.
    URI vplexStorageSystemURI = null;
    URI[] vplexSystemURIOut = new URI[1];
    Map<String, List<VPlexRecommendation>> varrayRecommendationsMap = sortRecommendationsByVarray(recommendations, vplexSystemURIOut);
    vplexStorageSystemURI = vplexSystemURIOut[0];
    // for the srdf copies, since they are already pre-created.
    if (!srdfCopy) {
        validateVolumeLabels(param.getName(), project, vPoolCapabilities, varrayRecommendationsMap);
    }
    // Determine the project to be used for the VPlex's artifacts
    StorageSystem vplexStorageSystem = _dbClient.queryObject(StorageSystem.class, vplexStorageSystemURI);
    Project vplexProject = getVplexProject(vplexStorageSystem, _dbClient, _tenantsService);
    // The volume size.
    long size = SizeUtil.translateSize(param.getSize());
    // The consistency group or null when not specified.
    final BlockConsistencyGroup consistencyGroup = blockConsistencyGroupURI == null ? null : _dbClient.queryObject(BlockConsistencyGroup.class, blockConsistencyGroupURI);
    // Find all volumes assigned to the group
    boolean cgContainsVolumes = false;
    if (consistencyGroup != null) {
        final List<Volume> activeCGVolumes = getActiveCGVolumes(consistencyGroup);
        cgContainsVolumes = (activeCGVolumes != null && !activeCGVolumes.isEmpty());
    }
    // If the consistency group is created but does not specify the LOCAL
    // type, the CG must be a CG created prior to 2.2 or an ingested CG. In
    // this case, we don't want a volume creation to result in backend CGs.
    // The only exception is if the CG does not reference any volumes. In
    // this case, if the LOCAL type isn't specified, we can create backend
    // CGs.
    BlockConsistencyGroup backendCG = null;
    if (consistencyGroup != null && (!consistencyGroup.created() || !cgContainsVolumes || consistencyGroup.getTypes().contains(Types.LOCAL.toString()))) {
        backendCG = consistencyGroup;
    }
    // Prepare Bourne volumes to represent the backend volumes for the
    // recommendations in each VirtualArray.
    int varrayCount = 0;
    String volumeLabel = param.getName();
    List<VolumeDescriptor> descriptors = new ArrayList<VolumeDescriptor>();
    URI[][] varrayVolumeURIs = new URI[2][vPoolCapabilities.getResourceCount()];
    Iterator<String> varrayIter = varrayRecommendationsMap.keySet().iterator();
    while (varrayIter.hasNext()) {
        String varrayId = varrayIter.next();
        s_logger.info("Processing backend recommendations for Virtual Array {}", varrayId);
        List<VPlexRecommendation> vplexRecommendations = varrayRecommendationsMap.get(varrayId);
        List<VolumeDescriptor> varrayDescriptors = makeBackendVolumeDescriptors(vplexRecommendations, project, vplexProject, vPool, volumeLabel, varrayCount, size, backendCG, vPoolCapabilities, createTask, task);
        descriptors.addAll(varrayDescriptors);
        List<URI> varrayURIs = VolumeDescriptor.getVolumeURIs(varrayDescriptors);
        allVolumes.addAll(varrayURIs);
        for (int i = 0; i < varrayURIs.size(); i++) {
            varrayVolumeURIs[varrayCount][i] = varrayURIs.get(i);
        }
        varrayCount++;
    }
    // Prepare Bourne volumes to represent the highly available virtual
    // volumes and associate the virtual volumes with their associated
    // backend volumes.
    s_logger.info("Preparing virtual volumes");
    List<URI> virtualVolumeURIs = new ArrayList<URI>();
    URI nullPoolURI = NullColumnValueGetter.getNullURI();
    vPoolCapabilities.put(VirtualPoolCapabilityValuesWrapper.AUTO_TIER__POLICY_NAME, null);
    for (int i = 0; i < vPoolCapabilities.getResourceCount(); i++) {
        // Compute the volume label based on the label of the underlying volume
        String volumeLabelBuilt = null;
        Volume associatedVolume = _dbClient.queryObject(Volume.class, varrayVolumeURIs[0][i]);
        // Get the virtual volume backing replication group instance name, if available.
        String backingReplicationGroupInstance = null;
        if (associatedVolume != null) {
            volumeLabelBuilt = generateLabelFromAssociatedVolume(volumeLabel, associatedVolume);
            backingReplicationGroupInstance = NullColumnValueGetter.isNotNullValue(associatedVolume.getReplicationGroupInstance()) ? associatedVolume.getReplicationGroupInstance() : NullColumnValueGetter.getNullStr();
        } else {
            volumeLabelBuilt = AbstractBlockServiceApiImpl.generateDefaultVolumeLabel(volumeLabel, i, vPoolCapabilities.getResourceCount());
        }
        s_logger.info("Volume label is {}", volumeLabelBuilt);
        Volume volume = StorageScheduler.getPrecreatedVolume(_dbClient, taskList, volumeLabelBuilt);
        boolean volumePrecreated = false;
        if (volume != null) {
            volumePrecreated = true;
        }
        long thinVolumePreAllocationSize = 0;
        if (null != vPool.getThinVolumePreAllocationPercentage()) {
            thinVolumePreAllocationSize = VirtualPoolUtil.getThinVolumePreAllocationSize(vPool.getThinVolumePreAllocationPercentage(), size);
        }
        volume = prepareVolume(VolumeType.VPLEX_VIRTUAL_VOLUME, volume, size, thinVolumePreAllocationSize, project, vArray, vPool, vplexStorageSystemURI, nullPoolURI, volumeLabelBuilt, consistencyGroup, vPoolCapabilities);
        StringSet associatedVolumes = new StringSet();
        associatedVolumes.add(varrayVolumeURIs[0][i].toString());
        s_logger.info("Associating volume {}", varrayVolumeURIs[0][i].toString());
        // associated with the virtual volume.
        if (varrayCount > 1) {
            associatedVolumes.add(varrayVolumeURIs[1][i].toString());
            s_logger.info("Associating volume {}", varrayVolumeURIs[1][i].toString());
        }
        volume.setAssociatedVolumes(associatedVolumes);
        if (null != backingReplicationGroupInstance) {
            s_logger.info("Setting virtual volume backingReplicationGroupInstance to {}", backingReplicationGroupInstance);
            volume.setBackingReplicationGroupInstance(backingReplicationGroupInstance);
        }
        _dbClient.updateObject(volume);
        URI volumeId = volume.getId();
        s_logger.info("Prepared virtual volume {}", volumeId);
        virtualVolumeURIs.add(volumeId);
        allVolumes.add(volumeId);
        if (createTask && !volumePrecreated) {
            Operation op = _dbClient.createTaskOpStatus(Volume.class, volume.getId(), task, ResourceOperationTypeEnum.CREATE_BLOCK_VOLUME);
            TaskResourceRep volumeTask = toTask(volume, task, op);
            taskList.getTaskList().add(volumeTask);
        }
        VolumeDescriptor descriptor = new VolumeDescriptor(VolumeDescriptor.Type.VPLEX_VIRT_VOLUME, vplexStorageSystemURI, volumeId, null, consistencyGroup == null ? null : consistencyGroup.getId(), vPoolCapabilities, volume.getCapacity());
        // Set the compute resource in the descriptor if the volume to be created will be exported
        // to a host/cluster after it has been created so that the compute resource name can be
        // included in the volume name if the custom volume naming is so configured. Do not set the
        // compute resource if the descriptor is for an SRDF target as the target is not exported
        // to the compute resource.
        URI computeResourceURI = param.getComputeResource();
        if ((computeResourceURI != null) && (!srdfCopy)) {
            s_logger.info(String.format("Volume %s - will be exported to Host/Cluster: %s", volume.getLabel(), computeResourceURI.toString()));
            descriptor.setComputeResource(computeResourceURI);
        }
        descriptors.add(descriptor);
    }
    return descriptors;
}
Also used : ArrayList(java.util.ArrayList) 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) StringSet(com.emc.storageos.db.client.model.StringSet) ApplicationAddVolumeList(com.emc.storageos.volumecontroller.ApplicationAddVolumeList) ArrayList(java.util.ArrayList) TaskList(com.emc.storageos.model.TaskList) VolumeGroupVolumeList(com.emc.storageos.model.application.VolumeGroupUpdateParam.VolumeGroupVolumeList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) StorageSystemConnectivityList(com.emc.storageos.model.systems.StorageSystemConnectivityList) List(java.util.List) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) TaskResourceRep(com.emc.storageos.model.TaskResourceRep) PrefixConstraint(com.emc.storageos.db.client.constraint.PrefixConstraint) AlternateIdConstraint(com.emc.storageos.db.client.constraint.AlternateIdConstraint) ContainmentPrefixConstraint(com.emc.storageos.db.client.constraint.ContainmentPrefixConstraint) ContainmentConstraint(com.emc.storageos.db.client.constraint.ContainmentConstraint) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) Project(com.emc.storageos.db.client.model.Project) Volume(com.emc.storageos.db.client.model.Volume)

Example 8 with VPlexRecommendation

use of com.emc.storageos.volumecontroller.VPlexRecommendation in project coprhd-controller by CoprHD.

the class VPlexBlockServiceApiImpl method makeBackendVolumeDescriptors.

/**
 * Takes a list of recommendations and makes the backend volumes and volume descriptors needed to
 * provision. When possible (e.g. for SRDF and Block), All recommendations must be in single varray.
 * calls the underlying storage routine createVolumesAndDescriptors().
 *
 * @param recommendations -- a VPlex recommendation list
 * @param project - Project containing the Vplex volumes
 * @param vplexProject -- private project of the Vplex
 * @param rootVpool -- top level Virtual Pool (VpoolUse.ROOT)
 * @param varrayCount -- instance count of the varray being provisioned
 * @param size -- size of each volume
 * @param backendCG -- the CG to be used on the backend Storage Systems
 * @param vPoolCapabilities - a VirtualPoolCapabilityValuesWrapper containing provisioning arguments
 * @param createTask -- boolean if true creates a task
 * @param task -- Overall task id
 * @return -- list of VolumeDescriptors to be provisioned
 */
private List<VolumeDescriptor> makeBackendVolumeDescriptors(List<VPlexRecommendation> recommendations, Project project, Project vplexProject, VirtualPool rootVpool, String volumeLabel, int varrayCount, long size, BlockConsistencyGroup backendCG, VirtualPoolCapabilityValuesWrapper vPoolCapabilities, boolean createTask, String task) {
    VPlexRecommendation firstRecommendation = recommendations.get(0);
    List<VolumeDescriptor> descriptors = new ArrayList<VolumeDescriptor>();
    URI varrayId = firstRecommendation.getVirtualArray();
    VirtualPool vpool = firstRecommendation.getVirtualPool();
    s_logger.info("Generated backend descriptors for {} recommendations varray {}", recommendations.size(), varrayCount);
    vPoolCapabilities.put(VirtualPoolCapabilityValuesWrapper.AUTO_TIER__POLICY_NAME, vpool.getAutoTierPolicyName());
    if (firstRecommendation.getRecommendation() != null) {
        // If these recommendations have lower level recommendation, process them.
        // This path is used for the source side of Distributed Volumes and for Local volumes
        // where we support building on top of SRDF or the BlockStorage as appropriate.
        List<Recommendation> childRecommendations = new ArrayList<Recommendation>();
        Recommendation childRecommendation = null;
        for (VPlexRecommendation recommendation : recommendations) {
            childRecommendation = recommendation.getRecommendation();
            childRecommendations.add(childRecommendation);
        }
        VirtualArray varray = _dbClient.queryObject(VirtualArray.class, varrayId);
        String newVolumeLabel = generateVolumeLabel(volumeLabel, varrayCount, 0, 0);
        boolean srdfTarget = (childRecommendation instanceof SRDFCopyRecommendation);
        boolean srdfSource = (childRecommendation instanceof SRDFRecommendation);
        if (srdfTarget) {
            newVolumeLabel = newVolumeLabel + "-target";
        } else if (srdfSource) {
        } else {
            // nothing special about these volumes, hide them in the vplex project
            // We can't use the vplexProject for SRDF volumes as they determine their RDF group
            // grom the project.
            project = vplexProject;
        }
        TaskList taskList = new TaskList();
        descriptors = super.createVolumesAndDescriptors(descriptors, newVolumeLabel, size, project, varray, vpool, childRecommendations, taskList, task, vPoolCapabilities);
        VolumeDescriptor.Type[] types;
        if (srdfTarget) {
            types = new VolumeDescriptor.Type[] { VolumeDescriptor.Type.SRDF_TARGET };
        } else {
            types = new VolumeDescriptor.Type[] { VolumeDescriptor.Type.BLOCK_DATA, VolumeDescriptor.Type.SRDF_SOURCE, VolumeDescriptor.Type.SRDF_EXISTING_SOURCE };
        }
        descriptors = VolumeDescriptor.filterByType(descriptors, types);
        for (VolumeDescriptor descriptor : descriptors) {
            Volume volume = _dbClient.queryObject(Volume.class, descriptor.getVolumeURI());
            s_logger.info(String.format("Received prepared volume %s (%s, args) type %s", volume.getLabel(), volume.getId(), descriptor.getType().name()));
            volume.addInternalFlags(DataObject.Flag.INTERNAL_OBJECT);
            configureCGAndReplicationGroup(rootVpool, vPoolCapabilities, backendCG, volume);
            _dbClient.updateObject(volume);
        }
        return descriptors;
    }
    // Sum resourceCount across all recommendations
    int totalResourceCount = 0;
    for (VPlexRecommendation recommendation : recommendations) {
        totalResourceCount += recommendation.getResourceCount();
    }
    // The code below is used for the HA side of distributed volumes.
    // The HA side does not currently call the lower level schedulers to get descriptors.
    s_logger.info("Processing recommendations for Virtual Array {}", varrayId);
    int volumeCounter = 0;
    for (VPlexRecommendation recommendation : recommendations) {
        for (int i = 0; i < recommendation.getResourceCount(); i++) {
            vpool = recommendation.getVirtualPool();
            URI storageDeviceURI = recommendation.getSourceStorageSystem();
            URI storagePoolURI = recommendation.getSourceStoragePool();
            String newVolumeLabel = generateVolumeLabel(volumeLabel, varrayCount, volumeCounter, totalResourceCount);
            validateVolumeLabel(newVolumeLabel, project);
            s_logger.info("Volume label is {}", newVolumeLabel);
            VirtualArray varray = _dbClient.queryObject(VirtualArray.class, varrayId);
            // This is also handled in StorageScheduler.prepareRecomendedVolumes
            long thinVolumePreAllocationSize = 0;
            if (null != vpool.getThinVolumePreAllocationPercentage()) {
                thinVolumePreAllocationSize = VirtualPoolUtil.getThinVolumePreAllocationSize(vpool.getThinVolumePreAllocationPercentage(), size);
            }
            Volume volume = prepareVolume(VolumeType.BLOCK_VOLUME, null, size, thinVolumePreAllocationSize, vplexProject, varray, vpool, storageDeviceURI, storagePoolURI, newVolumeLabel, backendCG, vPoolCapabilities);
            configureCGAndReplicationGroup(rootVpool, vPoolCapabilities, backendCG, volume);
            volume.addInternalFlags(Flag.INTERNAL_OBJECT);
            _dbClient.persistObject(volume);
            if (createTask) {
                _dbClient.createTaskOpStatus(Volume.class, volume.getId(), task, ResourceOperationTypeEnum.CREATE_BLOCK_VOLUME);
            }
            s_logger.info("Prepared volume {} ({}) ", volume.getLabel(), volume.getId());
            VolumeDescriptor descriptor = new VolumeDescriptor(VolumeDescriptor.Type.BLOCK_DATA, storageDeviceURI, volume.getId(), storagePoolURI, backendCG == null ? null : backendCG.getId(), vPoolCapabilities, size);
            descriptors.add(descriptor);
            volumeCounter++;
        }
    }
    return descriptors;
}
Also used : VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) VirtualArray(com.emc.storageos.db.client.model.VirtualArray) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) TaskList(com.emc.storageos.model.TaskList) ArrayList(java.util.ArrayList) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) 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) PrefixConstraint(com.emc.storageos.db.client.constraint.PrefixConstraint) AlternateIdConstraint(com.emc.storageos.db.client.constraint.AlternateIdConstraint) ContainmentPrefixConstraint(com.emc.storageos.db.client.constraint.ContainmentPrefixConstraint) ContainmentConstraint(com.emc.storageos.db.client.constraint.ContainmentConstraint) SRDFCopyRecommendation(com.emc.storageos.volumecontroller.SRDFCopyRecommendation) SRDFRecommendation(com.emc.storageos.volumecontroller.SRDFRecommendation) VolumeType(com.emc.storageos.api.service.impl.placement.VolumeRecommendation.VolumeType) Volume(com.emc.storageos.db.client.model.Volume)

Example 9 with VPlexRecommendation

use of com.emc.storageos.volumecontroller.VPlexRecommendation in project coprhd-controller by CoprHD.

the class RecoverPointScheduler method buildRpRecommendationFromExistingVolume.

/**
 * Build the RP Recommendation using an existing volume found in the CG.
 *
 * @param volume Existing volume to use
 * @param vpool The current vpool for the volume
 * @param capabilities The capabilities map
 * @param journalSize Size of the journal (only needed for journals, null otherwise)
 * @return Fully formed RP Recommendation formed from resources of the existing CG
 */
private RPRecommendation buildRpRecommendationFromExistingVolume(Volume volume, VirtualPool vpool, VirtualPoolCapabilityValuesWrapper capabilities, Long journalSize) {
    // Build the recommendation
    RPRecommendation rec = new RPRecommendation();
    rec.setVirtualPool(vpool);
    rec.setVirtualArray(volume.getVirtualArray());
    rec.setSourceStoragePool(volume.getPool());
    rec.setSourceStorageSystem(volume.getStorageController());
    rec.setInternalSiteName(volume.getInternalSiteName());
    rec.setRpCopyName(volume.getRpCopyName());
    rec.setSize((journalSize == null) ? capabilities.getSize() : journalSize);
    rec.setResourceCount(capabilities.getResourceCount());
    // Build VPLEX recommendation if specified
    if (VirtualPool.vPoolSpecifiesHighAvailability(vpool)) {
        VPlexRecommendation vplexRec = new VPlexRecommendation();
        vplexRec.setVirtualPool(vpool);
        vplexRec.setVirtualArray(volume.getVirtualArray());
        vplexRec.setVPlexStorageSystem(volume.getStorageController());
        // Always force count to 1 for a VPLEX rec for RP. VPLEX uses
        // these recs and they are invoked one at a time even
        // in a multi-volume request.
        vplexRec.setResourceCount(1);
        if (null == volume.getAssociatedVolumes() || volume.getAssociatedVolumes().isEmpty()) {
            _log.error("VPLEX volume {} has no backend volumes.", volume.forDisplay());
            throw InternalServerErrorException.internalServerErrors.noAssociatedVolumesForVPLEXVolume(volume.forDisplay());
        }
        for (String backingVolumeId : volume.getAssociatedVolumes()) {
            Volume backingVolume = dbClient.queryObject(Volume.class, URI.create(backingVolumeId));
            if (backingVolume.getVirtualArray().equals(volume.getVirtualArray())) {
                rec.setSourceStoragePool(backingVolume.getPool());
                rec.setSourceStorageSystem(backingVolume.getStorageController());
                vplexRec.setSourceStoragePool(backingVolume.getPool());
                vplexRec.setSourceStorageSystem(backingVolume.getStorageController());
            } else {
                if (journalSize == null) {
                    // Build HA recommendation if specified and this is not a VPLEX Journal.
                    // VPLEX Journals are always forced to VPLEX Local so we would not
                    // build a HA rec for it.
                    RPRecommendation haRec = new RPRecommendation();
                    VirtualPool haVpool = dbClient.queryObject(VirtualPool.class, backingVolume.getVirtualPool());
                    haRec.setVirtualPool(haVpool);
                    haRec.setVirtualArray(backingVolume.getVirtualArray());
                    haRec.setSourceStoragePool(backingVolume.getPool());
                    haRec.setSourceStorageSystem(backingVolume.getStorageController());
                    haRec.setResourceCount(capabilities.getResourceCount());
                    haRec.setSize(capabilities.getSize());
                    haRec.setInternalSiteName(backingVolume.getInternalSiteName());
                    haRec.setRpCopyName(backingVolume.getRpCopyName());
                    VPlexRecommendation haVPlexRec = new VPlexRecommendation();
                    haVPlexRec.setVirtualPool(haRec.getVirtualPool());
                    haVPlexRec.setVirtualArray(haRec.getVirtualArray());
                    haVPlexRec.setVPlexStorageSystem(volume.getStorageController());
                    haVPlexRec.setSourceStoragePool(haRec.getSourceStoragePool());
                    haVPlexRec.setSourceStorageSystem(haRec.getSourceStorageSystem());
                    // Always force count to 1 for a VPLEX rec for RP. VPLEX uses
                    // these recs and they are invoked one at a time even
                    // in a multi-volume request.
                    haVPlexRec.setResourceCount(1);
                    haRec.setVirtualVolumeRecommendation(haVPlexRec);
                    rec.setHaRecommendation(haRec);
                }
            }
        }
        rec.setVirtualVolumeRecommendation(vplexRec);
    }
    return rec;
}
Also used : VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) Volume(com.emc.storageos.db.client.model.Volume) RPRecommendation(com.emc.storageos.volumecontroller.RPRecommendation) VirtualPool(com.emc.storageos.db.client.model.VirtualPool)

Example 10 with VPlexRecommendation

use of com.emc.storageos.volumecontroller.VPlexRecommendation in project coprhd-controller by CoprHD.

the class PlacementTests method testVPlexLocalSRDFBasicPlacement.

@Test
public void testVPlexLocalSRDFBasicPlacement() {
    String[] vmax1FE = { "50:FE:FE:FE:FE:FE:FE:00", "50:FE:FE:FE:FE:FE:FE:01" };
    String[] vmax2FE = { "51:FE:FE:FE:FE:FE:FE:00", "51:FE:FE:FE:FE:FE:FE:01" };
    String[] vplexFE = { "FE:FE:FE:FE:FE:FE:FE:00", "FE:FE:FE:FE:FE:FE:FE:01" };
    String[] vplexBE = { "BE:BE:BE:BE:BE:BE:BE:00", "BE:BE:BE:BE:BE:BE:BE:01" };
    // Create 2 Virtual Arrays
    VirtualArray srcVarray = PlacementTestUtils.createVirtualArray(_dbClient, "srcVarray");
    VirtualArray tgtVarray = PlacementTestUtils.createVirtualArray(_dbClient, "tgtVarray");
    // Create 2 Networks
    StringSet connVA = new StringSet();
    connVA.add(srcVarray.getId().toString());
    Network network1 = PlacementTestUtils.createNetwork(_dbClient, vmax1FE, "VSANSite1", "FC+BROCADE+FE", connVA);
    connVA = new StringSet();
    connVA.add(tgtVarray.getId().toString());
    Network network2 = PlacementTestUtils.createNetwork(_dbClient, vmax2FE, "VSANSite2", "FC+CISCO+FE", connVA);
    // Create 2 storage systems
    StorageSystem[] storageSystems = PlacementTestUtils.createSRDFStorageSystems(_dbClient, "vmax1", network1, vmax1FE, srcVarray, "vmax2", network2, vmax2FE, tgtVarray);
    StorageSystem storageSystem1 = storageSystems[1];
    StorageSystem storageSystem2 = storageSystems[2];
    StoragePool[] storagePools = PlacementTestUtils.createStoragePoolsForTwo(_dbClient, storageSystem1, srcVarray, storageSystem2, tgtVarray);
    StorageSystem vplexSystem = PlacementTestUtils.createVPlexOneCluster(_dbClient, "vplex1", srcVarray, network1, network1, vplexFE, vplexBE);
    // Create a target virtual pool
    VirtualPool tgtVpool = new VirtualPool();
    tgtVpool.setId(URI.create("tgtVpool"));
    tgtVpool.setLabel("Target Vpool");
    tgtVpool.setSupportedProvisioningType(VirtualPool.ProvisioningType.Thin.name());
    tgtVpool.setDriveType(SupportedDriveTypes.FC.name());
    StringSet matchedPools2 = new StringSet();
    matchedPools2.add(storagePools[4].getId().toString());
    matchedPools2.add(storagePools[5].getId().toString());
    matchedPools2.add(storagePools[6].getId().toString());
    tgtVpool.setMatchedStoragePools(matchedPools2);
    tgtVpool.setUseMatchedPools(true);
    StringSet virtualArrays2 = new StringSet();
    virtualArrays2.add(tgtVarray.getId().toString());
    tgtVpool.setVirtualArrays(virtualArrays2);
    _dbClient.createObject(tgtVpool);
    // Make a remote copy protection setting
    VpoolRemoteCopyProtectionSettings settings = new VpoolRemoteCopyProtectionSettings();
    settings.setId(URI.create("remoteCopySettings"));
    settings.setCopyMode(VpoolRemoteCopyProtectionSettings.CopyModes.ASYNCHRONOUS.name());
    settings.setVirtualArray(tgtVarray.getId());
    settings.setVirtualPool(tgtVpool.getId());
    _dbClient.createObject(settings);
    // Create an VPLEX Local/SRDF source virtual pool
    VirtualPool srcVpool = new VirtualPool();
    srcVpool.setId(URI.create("srcVpool"));
    srcVpool.setLabel("Source Vpool");
    srcVpool.setSupportedProvisioningType(VirtualPool.ProvisioningType.Thin.name());
    srcVpool.setDriveType(SupportedDriveTypes.FC.name());
    StringSet matchedPools1 = new StringSet();
    matchedPools1.add(storagePools[1].getId().toString());
    matchedPools1.add(storagePools[2].getId().toString());
    matchedPools1.add(storagePools[3].getId().toString());
    srcVpool.setMatchedStoragePools(matchedPools1);
    srcVpool.setUseMatchedPools(true);
    StringSet virtualArrays1 = new StringSet();
    virtualArrays1.add(srcVarray.getId().toString());
    srcVpool.setVirtualArrays(virtualArrays1);
    StringMap remoteProtectionSettings = new StringMap();
    remoteProtectionSettings.put(tgtVarray.getId().toString(), settings.getId().toString());
    srcVpool.setProtectionRemoteCopySettings(remoteProtectionSettings);
    srcVpool.setHighAvailability(VirtualPool.HighAvailabilityType.vplex_local.name());
    _dbClient.createObject(srcVpool);
    // Create Tenant
    TenantOrg tenant = new TenantOrg();
    tenant.setId(URI.create("tenant"));
    _dbClient.createObject(tenant);
    // Create a project object
    Project project = new Project();
    project.setId(URI.create("project"));
    project.setLabel("RDG1");
    project.setTenantOrg(new NamedURI(tenant.getId(), project.getLabel()));
    _dbClient.createObject(project);
    // Create capabilities
    VirtualPoolCapabilityValuesWrapper capabilities = PlacementTestUtils.createCapabilities("2GB", 1, null);
    // Run single volume placement: Run 10 times to make sure pool3 never comes up for source and pool6 for target.
    for (int i = 0; i < 10; i++) {
        Map<VpoolUse, List<Recommendation>> recommendationsMap = PlacementTestUtils.invokePlacementForVpool(_dbClient, _coordinator, srcVarray, project, srcVpool, capabilities);
        List<Recommendation> recommendations = recommendationsMap.get(VpoolUse.ROOT);
        assertNotNull(recommendations);
        assertTrue(!recommendations.isEmpty());
        assertNotNull(recommendations.get(0));
        assert (recommendations.get(0) instanceof VPlexRecommendation);
        VPlexRecommendation vplexRecommendation = (VPlexRecommendation) recommendations.get(0);
        URI srcStoragePool = vplexRecommendation.getSourceStoragePool();
        assert (srcStoragePool.equals(storagePools[1].getId()) || srcStoragePool.equals(storagePools[2].getId()));
        assert (vplexRecommendation.getRecommendation() instanceof SRDFRecommendation);
        recommendations = recommendationsMap.get(VpoolUse.SRDF_COPY);
        assertTrue(!recommendations.isEmpty());
        assertNotNull(recommendations.get(0));
        assert (recommendations.get(0) instanceof SRDFCopyRecommendation);
        SRDFCopyRecommendation srdfCopyRecommendation = (SRDFCopyRecommendation) recommendations.get(0);
        URI tgtStoragePool = srdfCopyRecommendation.getSourceStoragePool();
        assert (tgtStoragePool.equals(storagePools[4].getId()) || tgtStoragePool.equals(storagePools[5].getId()));
    }
}
Also used : VirtualPoolCapabilityValuesWrapper(com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper) VirtualArray(com.emc.storageos.db.client.model.VirtualArray) VpoolRemoteCopyProtectionSettings(com.emc.storageos.db.client.model.VpoolRemoteCopyProtectionSettings) StringMap(com.emc.storageos.db.client.model.StringMap) StoragePool(com.emc.storageos.db.client.model.StoragePool) NamedURI(com.emc.storageos.db.client.model.NamedURI) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) SRDFCopyRecommendation(com.emc.storageos.volumecontroller.SRDFCopyRecommendation) SRDFRecommendation(com.emc.storageos.volumecontroller.SRDFRecommendation) Network(com.emc.storageos.db.client.model.Network) StringSet(com.emc.storageos.db.client.model.StringSet) List(java.util.List) ArrayList(java.util.ArrayList) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) SRDFCopyRecommendation(com.emc.storageos.volumecontroller.SRDFCopyRecommendation) Recommendation(com.emc.storageos.volumecontroller.Recommendation) SRDFRecommendation(com.emc.storageos.volumecontroller.SRDFRecommendation) RPRecommendation(com.emc.storageos.volumecontroller.RPRecommendation) RPProtectionRecommendation(com.emc.storageos.volumecontroller.RPProtectionRecommendation) Project(com.emc.storageos.db.client.model.Project) TenantOrg(com.emc.storageos.db.client.model.TenantOrg) Test(org.junit.Test)

Aggregations

VPlexRecommendation (com.emc.storageos.volumecontroller.VPlexRecommendation)24 ArrayList (java.util.ArrayList)21 Recommendation (com.emc.storageos.volumecontroller.Recommendation)17 VirtualArray (com.emc.storageos.db.client.model.VirtualArray)15 VirtualPool (com.emc.storageos.db.client.model.VirtualPool)15 URI (java.net.URI)15 List (java.util.List)15 NamedURI (com.emc.storageos.db.client.model.NamedURI)13 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)13 Project (com.emc.storageos.db.client.model.Project)11 StoragePool (com.emc.storageos.db.client.model.StoragePool)11 SRDFCopyRecommendation (com.emc.storageos.volumecontroller.SRDFCopyRecommendation)11 VirtualPoolCapabilityValuesWrapper (com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper)11 StringSet (com.emc.storageos.db.client.model.StringSet)10 SRDFRecommendation (com.emc.storageos.volumecontroller.SRDFRecommendation)10 Volume (com.emc.storageos.db.client.model.Volume)8 FCTN_STRING_TO_URI (com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_STRING_TO_URI)8 FCTN_VPLEX_MIRROR_TO_URI (com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_VPLEX_MIRROR_TO_URI)8 RPRecommendation (com.emc.storageos.volumecontroller.RPRecommendation)8 VolumeRecommendation (com.emc.storageos.api.service.impl.placement.VolumeRecommendation)7