Search in sources :

Example 11 with Recommendation

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

the class FileMirrorServiceApiImpl method prepareFileSystems.

/**
 * Prepare the source and target filesystems
 *
 * @param param
 * @param task
 * @param taskList
 * @param project
 * @param varray
 * @param vpool
 * @param recommendations
 * @param cosCapabilities
 * @param createInactive
 * @return
 */
public List<FileShare> prepareFileSystems(FileSystemParam param, String task, TaskList taskList, Project project, TenantOrg tenantOrg, DataObject.Flag[] flags, VirtualArray varray, VirtualPool vpool, List<Recommendation> recommendations, VirtualPoolCapabilityValuesWrapper cosCapabilities, Boolean createInactive) {
    List<FileShare> preparedFileSystems = new ArrayList<>();
    Iterator<Recommendation> recommendationsIter = recommendations.iterator();
    while (recommendationsIter.hasNext()) {
        FileMirrorRecommendation recommendation = (FileMirrorRecommendation) recommendationsIter.next();
        // If id is already set in recommendation, do not prepare the fileSystem (fileSystem already exists)
        if (recommendation.getId() != null) {
            continue;
        }
        // Get the source file share!!
        FileShare sourceFileShare = getPrecreatedFile(taskList, param.getLabel());
        if (!cosCapabilities.createMirrorExistingFileSystem()) {
            // Set the recommendation only for source file systems which are not meant for vpool change!!
            _log.info(String.format("createFileSystem --- FileShare: %1$s, StoragePool: %2$s, StorageSystem: %3$s", sourceFileShare.getId(), recommendation.getSourceStoragePool(), recommendation.getSourceStorageSystem()));
            validateFileSystem(recommendation, sourceFileShare);
        }
        // set the source mirror recommendations
        setFileMirrorRecommendation(recommendation, vpool, varray, false, false, sourceFileShare);
        FileShare targetFileShare = null;
        StringBuilder fileLabelBuilder = null;
        VirtualPool targetVpool = vpool;
        String targetFsPrefix = sourceFileShare.getName();
        if (cosCapabilities.getFileTargetCopyName() != null && !cosCapabilities.getFileTargetCopyName().isEmpty()) {
            targetFsPrefix = cosCapabilities.getFileTargetCopyName();
        }
        if (FileReplicationType.LOCAL.name().equalsIgnoreCase(cosCapabilities.getFileReplicationType())) {
            // Stripping out the special characters like ; /-+!@#$%^&())";:[]{}\ | but allow underscore character _
            String varrayName = varray.getLabel().replaceAll("[^\\dA-Za-z\\_]", "");
            fileLabelBuilder = new StringBuilder(targetFsPrefix).append("-localTarget");
            _log.info("Target file system name {}", fileLabelBuilder.toString());
            targetFileShare = prepareEmptyFileSystem(fileLabelBuilder.toString(), sourceFileShare.getCapacity(), project, recommendation, tenantOrg, varray, vpool, targetVpool, flags, task);
            // Set target file recommendations to target file system!!!
            setFileMirrorRecommendation(recommendation, vpool, varray, true, false, targetFileShare);
            // Update the source and target relationship!!
            setMirrorFileShareAttributes(sourceFileShare, targetFileShare);
            preparedFileSystems.add(sourceFileShare);
            preparedFileSystems.add(targetFileShare);
        } else {
            // Source file system!!
            preparedFileSystems.add(sourceFileShare);
            List<VirtualArray> virtualArrayTargets = new ArrayList<VirtualArray>();
            if (cosCapabilities.getFileReplicationTargetVArrays() != null & !cosCapabilities.getFileReplicationTargetVArrays().isEmpty()) {
                for (String strVarray : cosCapabilities.getFileReplicationTargetVArrays()) {
                    virtualArrayTargets.add(_dbClient.queryObject(VirtualArray.class, URI.create(strVarray)));
                }
            }
            for (VirtualArray targetVArray : virtualArrayTargets) {
                if (cosCapabilities.getFileReplicationTargetVPool() != null) {
                    targetVpool = _dbClient.queryObject(VirtualPool.class, cosCapabilities.getFileReplicationTargetVPool());
                } else {
                    targetVpool = vpool;
                }
                // Stripping out the special characters like ; /-+!@#$%^&())";:[]{}\ | but allow underscore character _
                String varrayName = targetVArray.getLabel().replaceAll("[^\\dA-Za-z\\_]", "");
                fileLabelBuilder = new StringBuilder(targetFsPrefix).append("-target");
                _log.info("Target file system name {}", fileLabelBuilder.toString());
                targetFileShare = prepareEmptyFileSystem(fileLabelBuilder.toString(), sourceFileShare.getCapacity(), project, recommendation, tenantOrg, targetVArray, vpool, targetVpool, flags, task);
                // Set target file recommendations to target file system!!!
                setFileMirrorRecommendation(recommendation, targetVpool, targetVArray, true, false, targetFileShare);
                // Update the source and target relationship!!
                setMirrorFileShareAttributes(sourceFileShare, targetFileShare);
                preparedFileSystems.add(targetFileShare);
            }
        }
    }
    return preparedFileSystems;
}
Also used : VirtualArray(com.emc.storageos.db.client.model.VirtualArray) ArrayList(java.util.ArrayList) FileMirrorRecommendation(com.emc.storageos.api.service.impl.placement.FileMirrorRecommendation) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) FileShare(com.emc.storageos.db.client.model.FileShare) FileMirrorRecommendation(com.emc.storageos.api.service.impl.placement.FileMirrorRecommendation) Recommendation(com.emc.storageos.volumecontroller.Recommendation)

Example 12 with Recommendation

use of com.emc.storageos.volumecontroller.Recommendation 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 13 with Recommendation

use of com.emc.storageos.volumecontroller.Recommendation 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 14 with Recommendation

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

the class FileStorageScheduler method selectStorageHADomainMatchingVpool.

/**
 * Select the right StorageHADomain matching vpool protocols.
 *
 * @param vpool
 * @param vArray
 * @param poolRecommends
 *            recommendations after selecting matching storage pools.
 * @return list of FileRecommendation
 */
private List<FileRecommendation> selectStorageHADomainMatchingVpool(VirtualPool vpool, URI vArray, List<Recommendation> poolRecommends, List<VirtualNAS> invalidNasServers) {
    // Get the storage ports from invalid vnas servers!!!
    List<URI> invalidPorts = getvNasStoragePortUris(invalidNasServers);
    _log.debug("select matching StorageHADomain");
    List<FileRecommendation> result = new ArrayList<FileRecommendation>();
    for (Recommendation recommendation : poolRecommends) {
        FileRecommendation rec = new FileRecommendation(recommendation);
        URI storageUri = recommendation.getSourceStorageSystem();
        StorageSystem storage = _dbClient.queryObject(StorageSystem.class, storageUri);
        // found
        if (storage.getSystemType().equals(Type.unity.toString())) {
            continue;
        }
        if (!storage.getSystemType().equals(Type.netapp.toString()) && !storage.getSystemType().equals(Type.netappc.toString()) && !storage.getSystemType().equals(Type.vnxe.toString()) && !storage.getSystemType().equals(Type.vnxfile.toString()) && !storage.getSystemType().equals(Type.datadomain.toString())) {
            result.add(rec);
            continue;
        }
        List<StoragePort> portList = getStorageSystemPortsInVarray(storageUri, vArray);
        if (portList == null || portList.isEmpty()) {
            _log.info("No valid storage port found from the virtual array: " + vArray);
            continue;
        }
        List<URI> storagePorts = new ArrayList<URI>();
        boolean foundValidPort = false;
        for (StoragePort port : portList) {
            if (invalidPorts.contains(port.getId())) {
                _log.debug("Storage port {} belongs to invalid vNas server ", port.getIpAddress());
                continue;
            }
            foundValidPort = true;
            _log.debug("Looking for port {}", port.getLabel());
            URI haDomainUri = port.getStorageHADomain();
            // Data Domain does not have a filer entity.
            if ((haDomainUri == null) && (!storage.getSystemType().equals(Type.datadomain.toString()))) {
                _log.info("No StorageHADomain URI for port {}", port.getLabel());
                continue;
            }
            StorageHADomain haDomain = null;
            if (haDomainUri != null) {
                haDomain = _dbClient.queryObject(StorageHADomain.class, haDomainUri);
            }
            if (haDomain != null) {
                StringSet protocols = haDomain.getFileSharingProtocols();
                // to see if it matches virtualPool's protocols
                StringSet vpoolProtocols = vpool.getProtocols();
                if (protocols != null && protocols.containsAll(vpoolProtocols)) {
                    _log.info("Found the StorageHADomain {} for recommended storagepool: {}", haDomain.getName(), recommendation.getSourceStoragePool());
                    storagePorts.add(port.getId());
                }
            } else if (storage.getSystemType().equals(Type.datadomain.toString())) {
                // The same file system on DD can support NFS and CIFS
                storagePorts.add(port.getId());
            } else {
                _log.error("No StorageHADomain for port {}", port.getIpAddress());
            }
        }
        // minimize collisions).
        if (foundValidPort) {
            Collections.shuffle(storagePorts);
            rec.setStoragePorts(storagePorts);
            result.add(rec);
        } else {
            _log.info("No valid storage port found from the storage system : " + storageUri + ", All ports belongs to invalid vNas ");
        }
    }
    return result;
}
Also used : ArrayList(java.util.ArrayList) StoragePort(com.emc.storageos.db.client.model.StoragePort) StringSet(com.emc.storageos.db.client.model.StringSet) StorageHADomain(com.emc.storageos.db.client.model.StorageHADomain) URI(java.net.URI) Recommendation(com.emc.storageos.volumecontroller.Recommendation) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 15 with Recommendation

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

the class FileStorageScheduler method placeFileShare.

/**
 * Schedule storage for fileshare in the varray with the given CoS
 * capabilities.
 *
 * @param vArray
 * @param vPool
 * @param capabilities
 * @param project
 * @return list of recommended storage ports for VNAS
 */
public List<FileRecommendation> placeFileShare(VirtualArray vArray, VirtualPool vPool, VirtualPoolCapabilityValuesWrapper capabilities, Project project, Map<String, Object> optionalAttributes) {
    _log.debug("Schedule storage for {} resource(s) of size {}.", capabilities.getResourceCount(), capabilities.getSize());
    // create map object if null, it used to receive the error message
    if (optionalAttributes == null) {
        optionalAttributes = new HashMap<String, Object>();
    }
    if (capabilities.getFileProtectionSourceStorageDevice() != null || capabilities.getTargetStorageSystem() != null) {
        Set<String> storageSystemSet = new HashSet<String>();
        if (capabilities.getFileProtectionSourceStorageDevice() != null) {
            storageSystemSet.add(capabilities.getFileProtectionSourceStorageDevice().toString());
        } else if (capabilities.getTargetStorageSystem() != null) {
            storageSystemSet.add(capabilities.getTargetStorageSystem().toString());
        }
        optionalAttributes.put(AttributeMatcher.Attributes.storage_system.name(), storageSystemSet);
    }
    // Get all storage pools that match the passed vpool params and
    // protocols. In addition, the pool must have enough capacity
    // to hold at least one resource of the requested size.
    List<StoragePool> candidatePools = _scheduler.getMatchingPools(vArray, vPool, capabilities, optionalAttributes);
    if (CollectionUtils.isEmpty(candidatePools)) {
        StringBuffer errorMessage = new StringBuffer();
        if (optionalAttributes.get(AttributeMatcher.ERROR_MESSAGE) != null) {
            errorMessage = (StringBuffer) optionalAttributes.get(AttributeMatcher.ERROR_MESSAGE);
        }
        throw APIException.badRequests.noStoragePools(vArray.getLabel(), vPool.getLabel(), errorMessage.toString());
    }
    // Holds the invalid virtual nas servers from both
    // assigned and un-assigned list.
    // the invalid vnas server clould be
    // over loaded or protocol not supported or
    // the ports from these invalid vnas servers
    // should not be considered for file provisioning!!!
    List<VirtualNAS> invalidNasServers = new ArrayList<VirtualNAS>();
    boolean provisioningOnVirtualNAS = true;
    VirtualNAS sourcevNAsServer = null;
    if (capabilities.getPersonality() != null && capabilities.getPersonality().equalsIgnoreCase(VirtualPoolCapabilityValuesWrapper.FILE_REPLICATION_TARGET)) {
        // Get the source nas server, if no source vnas server, then need storage from physical nas server!!
        URI sourceVNas = capabilities.getSourceVirtualNasServer();
        if (sourceVNas == null) {
            provisioningOnVirtualNAS = false;
        } else {
            sourcevNAsServer = _dbClient.queryObject(VirtualNAS.class, sourceVNas);
            if (sourcevNAsServer == null || sourcevNAsServer.getInactive()) {
                provisioningOnVirtualNAS = false;
            }
        }
    }
    List<FileRecommendation> fileRecommendations = new ArrayList<FileRecommendation>();
    List<FileRecommendation> recommendations = null;
    if (provisioningOnVirtualNAS) {
        // Get the recommendation based on virtual nas servers
        Map<VirtualNAS, List<StoragePool>> vNASPoolMap = getRecommendedVirtualNASBasedOnCandidatePools(vPool, vArray.getId(), candidatePools, project, invalidNasServers);
        VirtualNAS currvNAS = null;
        if (!vNASPoolMap.isEmpty()) {
            for (Entry<VirtualNAS, List<StoragePool>> eachVNASEntry : vNASPoolMap.entrySet()) {
                // If No storage pools recommended!!!
                if (eachVNASEntry.getValue().isEmpty()) {
                    continue;
                }
                currvNAS = eachVNASEntry.getKey();
                if (currvNAS != null) {
                    if (capabilities.getPersonality() != null && capabilities.getPersonality().equalsIgnoreCase(VirtualPoolCapabilityValuesWrapper.FILE_REPLICATION_TARGET)) {
                        if (sourcevNAsServer != null && sourcevNAsServer.getBaseDirPath().equalsIgnoreCase(currvNAS.getBaseDirPath())) {
                            _log.info("Target Nas server path {} is similar to source nas server {}, so considering this nas server", currvNAS.getBaseDirPath(), sourcevNAsServer.getBaseDirPath());
                        } else if (capabilities.getTargetNasServer() != null && capabilities.getTargetNasServer().equals(currvNAS.getId())) {
                            _log.info("Nas server {} is same as required target Nas server {}, so considering this nas server", currvNAS.getId(), capabilities.getTargetNasServer());
                        } else {
                            _log.info("Nas server {} is not the required target Nas server, so ignoring this nas server", currvNAS.getId());
                            continue;
                        }
                    }
                    _log.info("Best vNAS selected: {}", currvNAS.getNasName());
                    List<StoragePool> recommendedPools = eachVNASEntry.getValue();
                    // Get the recommendations for the current vnas pools.
                    List<Recommendation> poolRecommendations = _scheduler.getRecommendationsForPools(vArray.getId().toString(), recommendedPools, capabilities);
                    // Pick the pools from next available vNas recommended pools!!!
                    if (poolRecommendations.isEmpty()) {
                        _log.info("Skipping vNAS {}, as pools are not having enough resources", currvNAS.getNasName());
                        continue;
                    }
                    // Get the file recommendations for pool recommendation!!!
                    recommendations = getFileRecommendationsForVNAS(currvNAS, vArray.getId(), vPool, poolRecommendations);
                    if (!recommendations.isEmpty()) {
                        fileRecommendations.addAll(recommendations);
                        if (!capabilities.isVpoolProjectPolicyAssign() && !capabilities.getAllSourceRecommnedations()) {
                            _log.info("Selected vNAS {} for placement", currvNAS.getNasName());
                            break;
                        } else {
                            // Policy assignment required to create the policy on all applicable vNAS servers!!!
                            _log.info(" vNAS {} for Added to the list of recommendations", currvNAS.getNasName());
                        }
                    }
                }
            }
        }
    }
    // Get the file recommendations
    if (fileRecommendations == null || fileRecommendations.isEmpty() || capabilities.isVpoolProjectPolicyAssign() || capabilities.getAllSourceRecommnedations() || isTargetRequiredOnPhyscialNAS(capabilities)) {
        // Get the recommendations for the candidate pools.
        _log.info("Placement on HADomain matching pools");
        List<Recommendation> poolRecommendations = _scheduler.getRecommendationsForPools(vArray.getId().toString(), candidatePools, capabilities);
        recommendations = selectStorageHADomainMatchingVpool(vPool, vArray.getId(), poolRecommendations, invalidNasServers);
        if (recommendations != null && !recommendations.isEmpty()) {
            if (fileRecommendations != null) {
                fileRecommendations.addAll(recommendations);
            }
        }
    }
    // log an error and clear the list of recommendations.
    if (fileRecommendations == null || fileRecommendations.isEmpty()) {
        _log.error("Could not find matching pools for virtual array {} & vpool {}", vArray.getId(), vPool.getId());
    } else {
        // add code for file for default recommendations for file data
        for (FileRecommendation recommendation : fileRecommendations) {
            FileRecommendation fileRecommendation = recommendation;
            fileRecommendation.setFileType(FileType.FILE_SYSTEM_DATA);
            StorageSystem system = _dbClient.queryObject(StorageSystem.class, recommendation.getSourceStorageSystem());
            fileRecommendation.setDeviceType(system.getSystemType());
        }
    }
    return fileRecommendations;
}
Also used : StoragePool(com.emc.storageos.db.client.model.StoragePool) ArrayList(java.util.ArrayList) URI(java.net.URI) Recommendation(com.emc.storageos.volumecontroller.Recommendation) VirtualNAS(com.emc.storageos.db.client.model.VirtualNAS) DiscoveredDataObject(com.emc.storageos.db.client.model.DiscoveredDataObject) List(java.util.List) ArrayList(java.util.ArrayList) TaskList(com.emc.storageos.model.TaskList) HashSet(java.util.HashSet) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Aggregations

Recommendation (com.emc.storageos.volumecontroller.Recommendation)70 ArrayList (java.util.ArrayList)62 URI (java.net.URI)49 VirtualArray (com.emc.storageos.db.client.model.VirtualArray)37 VPlexRecommendation (com.emc.storageos.volumecontroller.VPlexRecommendation)36 NamedURI (com.emc.storageos.db.client.model.NamedURI)28 StoragePool (com.emc.storageos.db.client.model.StoragePool)28 List (java.util.List)28 VirtualPool (com.emc.storageos.db.client.model.VirtualPool)27 RPProtectionRecommendation (com.emc.storageos.volumecontroller.RPProtectionRecommendation)27 RPRecommendation (com.emc.storageos.volumecontroller.RPRecommendation)27 Volume (com.emc.storageos.db.client.model.Volume)24 SRDFRecommendation (com.emc.storageos.volumecontroller.SRDFRecommendation)23 HashMap (java.util.HashMap)23 SRDFCopyRecommendation (com.emc.storageos.volumecontroller.SRDFCopyRecommendation)21 VirtualPoolCapabilityValuesWrapper (com.emc.storageos.volumecontroller.impl.utils.VirtualPoolCapabilityValuesWrapper)21 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)19 AlternateIdConstraint (com.emc.storageos.db.client.constraint.AlternateIdConstraint)18 Project (com.emc.storageos.db.client.model.Project)17 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)16