Search in sources :

Example 1 with VPlexRecommendation

use of com.emc.storageos.volumecontroller.VPlexRecommendation 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 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 3 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 4 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 5 with VPlexRecommendation

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

the class PlacementTests method testPlacementVPlexXIO.

/**
 * Simple VPLEX local XIO block placement.
 */
@Test
public void testPlacementVPlexXIO() {
    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" };
    String[] xio1FE = { "50:FE:FE:FE:FE:FE:FE:00", "50:FE:FE:FE:FE:FE:FE:01" };
    String[] xio2FE = { "51:FE:FE:FE:FE:FE:FE:00", "51:FE:FE:FE:FE:FE:FE:01" };
    String[] xio3FE = { "52:FE:FE:FE:FE:FE:FE:00", "52:FE:FE:FE:FE:FE:FE:01" };
    // Create a Network
    Network networkFE = PlacementTestUtils.createNetwork(_dbClient, vplexFE, "VSANFE", "FC+BROCADE+FE", null);
    Network networkBE = PlacementTestUtils.createNetwork(_dbClient, vplexBE, "VSANBE", "FC+BROCADE+BE", null);
    // Create a Virtual Array
    VirtualArray varray = PlacementTestUtils.createVirtualArray(_dbClient, "varray1");
    // Create 3 storage systems for xio
    StorageSystem storageSystem1 = PlacementTestUtils.createStorageSystem(_dbClient, "xtremio", "xtremio1");
    StorageSystem storageSystem2 = PlacementTestUtils.createStorageSystem(_dbClient, "xtremio", "xtremio2");
    StorageSystem storageSystem3 = PlacementTestUtils.createStorageSystem(_dbClient, "xtremio", "xtremio3");
    // Create two front-end storage ports xio1
    List<StoragePort> xio1Ports = new ArrayList<StoragePort>();
    for (int i = 0; i < xio1FE.length; i++) {
        xio1Ports.add(PlacementTestUtils.createStoragePort(_dbClient, storageSystem1, networkBE, xio1FE[i], varray, StoragePort.PortType.frontend.name(), "portGroupXio1" + i, "C0+FC0" + i));
    }
    // Create two front-end storage ports xio2
    List<StoragePort> xio2Ports = new ArrayList<StoragePort>();
    for (int i = 0; i < xio2FE.length; i++) {
        xio2Ports.add(PlacementTestUtils.createStoragePort(_dbClient, storageSystem2, networkBE, xio2FE[i], varray, StoragePort.PortType.frontend.name(), "portGroupXio2" + i, "D0+FC0" + i));
    }
    // Create two front-end storage ports xio3
    List<StoragePort> xio3Ports = new ArrayList<StoragePort>();
    for (int i = 0; i < xio3FE.length; i++) {
        xio3Ports.add(PlacementTestUtils.createStoragePort(_dbClient, storageSystem3, networkBE, xio3FE[i], varray, StoragePort.PortType.frontend.name(), "portGroupXio3" + i, "E0+FC0" + i));
    }
    // Create a VPLEX storage system
    StorageSystem vplexStorageSystem = PlacementTestUtils.createStorageSystem(_dbClient, "vplex", "vplex1");
    // Create two front-end storage ports VPLEX
    List<StoragePort> fePorts = new ArrayList<StoragePort>();
    for (int i = 0; i < vplexFE.length; i++) {
        fePorts.add(PlacementTestUtils.createStoragePort(_dbClient, vplexStorageSystem, networkFE, vplexFE[i], varray, StoragePort.PortType.frontend.name(), "portGroupFE" + i, "A0+FC0" + i));
    }
    // Create two back-end storage ports VPLEX
    List<StoragePort> bePorts = new ArrayList<StoragePort>();
    for (int i = 0; i < vplexBE.length; i++) {
        bePorts.add(PlacementTestUtils.createStoragePort(_dbClient, vplexStorageSystem, networkBE, vplexBE[i], varray, StoragePort.PortType.backend.name(), "portGroupBE" + i, "B0+FC0" + i));
    }
    // Create a storage pool on xio1
    StoragePool pool1 = PlacementTestUtils.createStoragePool(_dbClient, varray, storageSystem1, "pool1", "Pool1", Long.valueOf(1024 * 1024 * 10), Long.valueOf(1024 * 1024 * 10), 300, 300, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
    // Create a storage pool on xio2
    StoragePool pool2 = PlacementTestUtils.createStoragePool(_dbClient, varray, storageSystem2, "pool2", "Pool2", Long.valueOf(1024 * 1024 * 1), Long.valueOf(1024 * 1024 * 1), 100, 100, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
    // Create a storage pool on xio3
    StoragePool pool3 = PlacementTestUtils.createStoragePool(_dbClient, varray, storageSystem3, "pool3", "Pool3", Long.valueOf(1024 * 10), Long.valueOf(1024 * 1024 * 10), 300, 300, StoragePool.SupportedResourceTypes.THIN_ONLY.toString());
    // Create a virtual pool
    VirtualPool vpool = new VirtualPool();
    vpool.setId(URI.create("vpool"));
    vpool.setLabel("vpool");
    vpool.setSupportedProvisioningType(VirtualPool.ProvisioningType.Thin.name());
    vpool.setDriveType(SupportedDriveTypes.FC.name());
    StringSet matchedPools = new StringSet();
    matchedPools.add(pool1.getId().toString());
    matchedPools.add(pool2.getId().toString());
    matchedPools.add(pool3.getId().toString());
    vpool.setMatchedStoragePools(matchedPools);
    vpool.setUseMatchedPools(true);
    _dbClient.createObject(vpool);
    // Create a VPLEX virtual pool
    VirtualPool vplexVpool = new VirtualPool();
    vplexVpool.setId(URI.create("vplexVpool"));
    vplexVpool.setLabel("vplexVpool");
    vplexVpool.setSupportedProvisioningType(VirtualPool.ProvisioningType.Thin.name());
    vplexVpool.setHighAvailability(VirtualPool.HighAvailabilityType.vplex_local.name());
    // 
    vplexVpool.setDriveType(SupportedDriveTypes.FC.name());
    matchedPools = new StringSet();
    matchedPools.add(pool1.getId().toString());
    matchedPools.add(pool2.getId().toString());
    matchedPools.add(pool3.getId().toString());
    vplexVpool.setMatchedStoragePools(matchedPools);
    vplexVpool.setUseMatchedPools(true);
    _dbClient.createObject(vplexVpool);
    // Create a project object
    Project project = new Project();
    project.setId(URI.create("project"));
    project.setLabel("project");
    _dbClient.createObject(project);
    VirtualPoolCapabilityValuesWrapper capabilities = PlacementTestUtils.createCapabilities("2GB", 1, null);
    // Run single volume placement: Run 10 times to make sure pool2 nRever comes up.
    for (int i = 0; i < 10; i++) {
        List recommendations = PlacementTestUtils.invokePlacement(_dbClient, _coordinator, varray, project, vplexVpool, capabilities);
        assertNotNull(recommendations);
        assertTrue(!recommendations.isEmpty());
        assertNotNull(recommendations.get(0));
        VPlexRecommendation rec = (VPlexRecommendation) recommendations.get(0);
        assertNotNull(rec.getSourceStoragePool());
        assertNotNull(rec.getSourceStorageSystem());
        assertNotNull(rec.getVPlexStorageSystem());
        assertTrue(("xtremio3".equals(rec.getSourceStorageSystem().toString())) || ("xtremio1".equals(rec.getSourceStorageSystem().toString())));
        assertTrue("vplex1".equals(rec.getVPlexStorageSystem().toString()));
        assertTrue(("pool3".equals(rec.getSourceStoragePool().toString())) || ("pool1".equals(rec.getSourceStoragePool().toString())));
        _log.info("Recommendation " + i + ": " + recommendations.size() + ", Pool Chosen: " + rec.getSourceStoragePool().toString());
        _log.info(rec.toString());
    }
}
Also used : VirtualPoolCapabilityValuesWrapper(com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper) VirtualArray(com.emc.storageos.db.client.model.VirtualArray) StoragePool(com.emc.storageos.db.client.model.StoragePool) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) StoragePort(com.emc.storageos.db.client.model.StoragePort) ArrayList(java.util.ArrayList) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) Project(com.emc.storageos.db.client.model.Project) 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) 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