Search in sources :

Example 16 with VPlexRecommendation

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

the class VPlexBlockServiceApiImpl method startNativeContinuousCopies.

/**
 * {@inheritDoc}
 */
@Override
public TaskList startNativeContinuousCopies(StorageSystem vplexStorageSystem, Volume vplexVolume, VirtualPool sourceVirtualPool, VirtualPoolCapabilityValuesWrapper capabilities, NativeContinuousCopyCreate param, String taskId) throws ControllerException {
    // using the target volume of a block snapshot.
    if (VPlexUtil.isVolumeBuiltOnBlockSnapshot(_dbClient, vplexVolume)) {
        throw APIException.badRequests.mirrorNotAllowedVolumeIsExposedSnapshot(vplexVolume.getId().toString());
    }
    validateNotAConsistencyGroupVolume(vplexVolume, sourceVirtualPool);
    TaskList taskList = new TaskList();
    // Currently, For Vplex Local Volume this will create a single mirror and add it
    // to the vplex volume. For Vplex Distributed Volume this will create single mirror
    // on source and/or HA side and add it to the vplex volume. Two steps: first place
    // the mirror and then prepare the mirror.
    URI vplexStorageSystemURI = vplexVolume.getStorageController();
    // For VPLEX Local volume there will be only one associated volume entry in this set.
    StringSet associatedVolumeIds = vplexVolume.getAssociatedVolumes();
    if (associatedVolumeIds == null) {
        throw InternalServerErrorException.internalServerErrors.noAssociatedVolumesForVPLEXVolume(vplexVolume.forDisplay());
    }
    VirtualPool sourceMirrorVPool = null;
    // Set source mirror vpool
    if (!isNullOrEmpty(sourceVirtualPool.getMirrorVirtualPool()) && !NullColumnValueGetter.isNullURI(URI.create(sourceVirtualPool.getMirrorVirtualPool()))) {
        sourceMirrorVPool = _dbClient.queryObject(VirtualPool.class, URI.create(sourceVirtualPool.getMirrorVirtualPool()));
    }
    // Check if volume is distributed and if HA Mirror Vpool is also set
    VirtualPool haMirrorVPool = VPlexUtil.getHAMirrorVpool(sourceVirtualPool, associatedVolumeIds, _dbClient);
    // Map of backend volume and the mirror pool to target backend volume for the mirror
    Map<Volume, VirtualPool> backendVolumeToMirrorVpoolMap = new HashMap<Volume, VirtualPool>();
    if (associatedVolumeIds.size() > 1) {
        // If associatedVolumeIds size is greater than 1 then its a VPLEX Distributed Volume
        updateBackendVolumeToMirrorVpoolMap(vplexVolume, associatedVolumeIds, sourceVirtualPool, sourceMirrorVPool, haMirrorVPool, backendVolumeToMirrorVpoolMap);
    } else {
        // If we are here that means we need to create mirror for the VPLEX local volume
        for (String associatedVolumeId : associatedVolumeIds) {
            Volume associatedVolume = _dbClient.queryObject(Volume.class, URI.create(associatedVolumeId));
            if (associatedVolume != null) {
                backendVolumeToMirrorVpoolMap.put(associatedVolume, sourceMirrorVPool);
            }
        }
    }
    // Project is not passed in continuous copies call.
    // Implicit assumption to use same project as the source volume.
    Project project = _permissionsHelper.getObjectById(vplexVolume.getProject(), Project.class);
    Map<Volume, List<Recommendation>> backendvolumeToMirrorRecommendationMap = new HashMap<Volume, List<Recommendation>>();
    Map<Volume, VirtualArray> backendvolumeToMirrorVarrayMap = new HashMap<Volume, VirtualArray>();
    for (Volume backendVolume : backendVolumeToMirrorVpoolMap.keySet()) {
        URI backendVolumeVarrayURI = backendVolume.getVirtualArray();
        // Get the VPLEX cluster value from the varray
        String cluster = ConnectivityUtil.getVplexClusterForVarray(backendVolumeVarrayURI, vplexStorageSystemURI, _dbClient);
        if (cluster.equals(ConnectivityUtil.CLUSTER_UNKNOWN)) {
            throw InternalServerErrorException.internalServerErrors.noVplexClusterInfoForVarray(backendVolumeVarrayURI.toString(), vplexStorageSystemURI.toString());
        }
        VirtualPool backendVolumeVpool = _dbClient.queryObject(VirtualPool.class, backendVolume.getVirtualPool());
        VirtualPool mirrorVpool = backendVolumeToMirrorVpoolMap.get(backendVolume);
        // Get recommendations for the mirror placement
        List<Recommendation> volumeRecommendations = null;
        VirtualArray varray = null;
        if (mirrorVpool != null) {
            // If mirror vpool is provided try to get recommendations using the provided mirror vpool
            // Check if any of the varray for mirror vpool is same as that of the source volume varray.
            // If yes then get recommendations using that varray.
            StringSet mirrorVPoolVarrays = mirrorVpool.getVirtualArrays();
            boolean foundMatch = false;
            for (String mirrorVPoolVarrayId : mirrorVPoolVarrays) {
                if (mirrorVPoolVarrayId.equals(backendVolumeVarrayURI.toString())) {
                    varray = _dbClient.queryObject(VirtualArray.class, backendVolumeVarrayURI);
                    volumeRecommendations = _scheduler.getRecommendationsForMirrors(varray, project, backendVolumeVpool, mirrorVpool, capabilities, vplexStorageSystemURI, backendVolume.getStorageController(), cluster);
                    foundMatch = true;
                    break;
                }
            }
            if (!foundMatch) {
                s_logger.info("Mirror Vpool varray is different than the source vpool varray");
                // with the source volume VPLEX system.
                for (String mirrorVPoolVarrayId : mirrorVPoolVarrays) {
                    if (VPlexUtil.checkIfVarrayContainsSpecifiedVplexSystem(mirrorVPoolVarrayId, cluster, vplexStorageSystemURI, _dbClient)) {
                        varray = _dbClient.queryObject(VirtualArray.class, URI.create(mirrorVPoolVarrayId));
                        volumeRecommendations = _scheduler.getRecommendationsForMirrors(varray, project, backendVolumeVpool, mirrorVpool, capabilities, vplexStorageSystemURI, backendVolume.getStorageController(), cluster);
                        if (!volumeRecommendations.isEmpty()) {
                            foundMatch = true;
                            break;
                        } else {
                            s_logger.info("Tried to get recommemdations using varray {} {}. ", varray.getId(), varray.getLabel());
                        }
                    }
                }
            }
        } else {
            if (sourceVirtualPool.getHighAvailability().equals(VirtualPool.HighAvailabilityType.vplex_local.name())) {
                s_logger.info("Mirror vpool is not specified, use the source volume virtual pool and virtual array");
                // In case of Vplex local if mirror pool is not provided then we can use source vpool as mirror vpool.
                sourceMirrorVPool = backendVolumeVpool;
                mirrorVpool = backendVolumeVpool;
                backendVolumeToMirrorVpoolMap.put(backendVolume, sourceMirrorVPool);
                // Separate Mirror vpool is not provided so use the source volume vpool and varray for
                // getting recommendations.Here sourceVirtualPool and mirrorVPool will be same.
                varray = _dbClient.queryObject(VirtualArray.class, backendVolumeVarrayURI);
                volumeRecommendations = _scheduler.getRecommendationsForMirrors(varray, project, backendVolumeVpool, mirrorVpool, capabilities, vplexStorageSystemURI, backendVolume.getStorageController(), cluster);
            }
        }
        if (mirrorVpool == null) {
            throw APIException.badRequests.noMirrorVpoolForVplexVolume(vplexVolume.getLabel());
        }
        if (varray == null) {
            throw APIException.badRequests.noVarrayForMirrorVpoolWithExpectedVplex(mirrorVpool.getLabel(), vplexStorageSystem.getLabel(), cluster);
        }
        if (volumeRecommendations == null || volumeRecommendations.isEmpty()) {
            if (volumeRecommendations.isEmpty()) {
                StorageSystem storageSystem = _dbClient.queryObject(StorageSystem.class, backendVolume.getStorageController());
                throw APIException.badRequests.noMatchingStoragePoolsForContinuousCopiesVpoolForVplex(varray.getLabel(), sourceMirrorVPool.getLabel(), storageSystem.getLabel());
            }
        }
        // Add mirror recommendations for the backend volume to the map
        backendvolumeToMirrorRecommendationMap.put(backendVolume, volumeRecommendations);
        backendvolumeToMirrorVarrayMap.put(backendVolume, varray);
    }
    // Prepare mirror.
    int varrayCount = 0;
    int volumeCounter = 1;
    // volumeCount will be always 1 for now
    int volumeCount = capabilities.getResourceCount();
    String volumeLabel = param.getName();
    List<URI> allVolumes = new ArrayList<URI>();
    List<URI> allMirrors = new ArrayList<URI>();
    List<VolumeDescriptor> descriptors = new ArrayList<VolumeDescriptor>();
    // Currently only one local mirror is supported for the VPLEX local virtual volume
    List<VplexMirror> preparedMirrors = new ArrayList<VplexMirror>();
    for (Volume backendVolume : backendvolumeToMirrorRecommendationMap.keySet()) {
        List<Recommendation> volumeRecommendations = backendvolumeToMirrorRecommendationMap.get(backendVolume);
        VirtualArray varray = backendvolumeToMirrorVarrayMap.get(backendVolume);
        VirtualPool mirrorVpool = backendVolumeToMirrorVpoolMap.get(backendVolume);
        long thinVolumePreAllocationSize = 0;
        if (null != mirrorVpool.getThinVolumePreAllocationPercentage()) {
            thinVolumePreAllocationSize = VirtualPoolUtil.getThinVolumePreAllocationSize(mirrorVpool.getThinVolumePreAllocationPercentage(), vplexVolume.getCapacity());
        }
        for (Recommendation volumeRecommendation : volumeRecommendations) {
            VPlexRecommendation vplexRecommendation = (VPlexRecommendation) volumeRecommendation;
            StringBuilder mirrorLabelBuilder = new StringBuilder(volumeLabel);
            if (backendVolume.getVirtualArray().equals(vplexVolume.getVirtualArray())) {
                varrayCount = 0;
            } else {
                varrayCount = 1;
            }
            mirrorLabelBuilder.append('-').append(varrayCount);
            if (volumeCount > 1) {
                mirrorLabelBuilder.append('-').append(volumeCounter++);
            }
            // Create mirror object
            VplexMirror createdMirror = initializeMirror(vplexVolume, mirrorVpool, varray, mirrorLabelBuilder.toString(), thinVolumePreAllocationSize, _dbClient);
            preparedMirrors.add(createdMirror);
            Operation op = _dbClient.createTaskOpStatus(VplexMirror.class, createdMirror.getId(), taskId, ResourceOperationTypeEnum.ATTACH_VPLEX_LOCAL_MIRROR);
            s_logger.info("Prepared mirror {}", createdMirror.getId());
            allMirrors.add(createdMirror.getId());
            // Add descriptor for the mirror.
            VolumeDescriptor descriptor = new VolumeDescriptor(VolumeDescriptor.Type.VPLEX_LOCAL_MIRROR, vplexStorageSystemURI, createdMirror.getId(), null, capabilities);
            descriptors.add(descriptor);
            // Create backend volume object and add it to the VplexMirror created above.
            Volume volume = prepareVolume(createdMirror, backendVolume, mirrorVpool, varray, vplexRecommendation.getSourceStorageSystem(), vplexRecommendation.getSourceStoragePool(), mirrorLabelBuilder.toString(), thinVolumePreAllocationSize, capabilities, _dbClient);
            op = new Operation();
            op.setResourceType(ResourceOperationTypeEnum.CREATE_BLOCK_VOLUME);
            _dbClient.createTaskOpStatus(Volume.class, volume.getId(), taskId, op);
            URI volumeId = volume.getId();
            allVolumes.add(volumeId);
            s_logger.info("Prepared volume {}", volumeId);
            // Add descriptor for the backend volume
            descriptor = new VolumeDescriptor(VolumeDescriptor.Type.BLOCK_DATA, vplexRecommendation.getSourceStorageSystem(), volumeId, vplexRecommendation.getSourceStoragePool(), capabilities);
            descriptors.add(descriptor);
        }
    }
    Collection<URI> mirrorTargetIds = Collections2.transform(preparedMirrors, FCTN_VPLEX_MIRROR_TO_URI);
    String mirrorTargetCommaDelimList = Joiner.on(',').join(mirrorTargetIds);
    Operation op = _dbClient.createTaskOpStatus(Volume.class, vplexVolume.getId(), taskId, ResourceOperationTypeEnum.ATTACH_VPLEX_LOCAL_MIRROR, mirrorTargetCommaDelimList);
    taskList.getTaskList().add(toTask(vplexVolume, preparedMirrors, taskId, op));
    try {
        VPlexController controller = getController();
        controller.attachContinuousCopies(vplexStorageSystem.getId(), descriptors, vplexVolume.getId(), taskId);
    } catch (InternalException e) {
        if (s_logger.isErrorEnabled()) {
            s_logger.error("Controller error", e);
        }
        String errMsg = String.format("Controller error: %s", e.getMessage());
        for (URI volumeURI : allVolumes) {
            _dbClient.error(Volume.class, volumeURI, taskId, e);
        }
        for (URI mirrorURI : allMirrors) {
            _dbClient.error(VplexMirror.class, mirrorURI, taskId, e);
        }
        for (TaskResourceRep volumeTask : taskList.getTaskList()) {
            volumeTask.setState(Operation.Status.error.name());
            volumeTask.setMessage(errMsg);
        }
        throw e;
    }
    return taskList;
}
Also used : VirtualArray(com.emc.storageos.db.client.model.VirtualArray) VPlexController(com.emc.storageos.vplexcontroller.VPlexController) HashMap(java.util.HashMap) TaskList(com.emc.storageos.model.TaskList) 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) 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) VplexMirror(com.emc.storageos.db.client.model.VplexMirror) 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) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) 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) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) Project(com.emc.storageos.db.client.model.Project) Volume(com.emc.storageos.db.client.model.Volume)

Example 17 with VPlexRecommendation

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

the class VPlexBlockServiceApiImpl method createVolumes.

/**
 * {@inheritDoc}
 *
 * @throws InternalException
 */
@Override
public TaskList createVolumes(VolumeCreate param, Project project, VirtualArray vArray, VirtualPool vPool, Map<VpoolUse, List<Recommendation>> recommendationMap, TaskList taskList, String task, VirtualPoolCapabilityValuesWrapper vPoolCapabilities) throws InternalException {
    List<Recommendation> volRecommendations = recommendationMap.get(VpoolUse.ROOT);
    List<Recommendation> srdfCopyRecommendations = recommendationMap.get(VpoolUse.SRDF_COPY);
    if (taskList == null) {
        taskList = new TaskList();
    }
    List<URI> allVolumes = new ArrayList<URI>();
    List<VolumeDescriptor> descriptors = createVPlexVolumeDescriptors(param, project, vArray, vPool, volRecommendations, task, vPoolCapabilities, vPoolCapabilities.getBlockConsistencyGroup(), taskList, allVolumes, true);
    for (VolumeDescriptor desc : descriptors) {
        s_logger.info("Vplex Root Descriptors: " + desc.toString());
    }
    if (srdfCopyRecommendations != null) {
        // This may be a Vplex volume or not
        for (Recommendation srdfCopyRecommendation : srdfCopyRecommendations) {
            vArray = _dbClient.queryObject(VirtualArray.class, srdfCopyRecommendation.getVirtualArray());
            vPool = srdfCopyRecommendation.getVirtualPool();
            List<VolumeDescriptor> srdfCopyDescriptors = new ArrayList<VolumeDescriptor>();
            List<Recommendation> copyRecommendations = new ArrayList<Recommendation>();
            copyRecommendations.add(srdfCopyRecommendation);
            if (srdfCopyRecommendation instanceof VPlexRecommendation) {
                String name = param.getName();
                // Do not pass in the consistency group for vplex volumes fronting targets
                // as we will eventually put them in the target CG.
                srdfCopyDescriptors = createVPlexVolumeDescriptors(param, project, vArray, vPool, copyRecommendations, task, vPoolCapabilities, null, taskList, allVolumes, true);
                param.setName(name);
            } else {
                srdfCopyDescriptors = super.createVolumesAndDescriptors(srdfCopyDescriptors, param.getName() + "_srdf_copy", vPoolCapabilities.getSize(), project, vArray, vPool, copyRecommendations, taskList, task, vPoolCapabilities);
            }
            for (VolumeDescriptor desc : srdfCopyDescriptors) {
                s_logger.info("SRDF Copy: " + desc.toString());
            }
            descriptors.addAll(srdfCopyDescriptors);
        }
    }
    // Log volume descriptor information
    logVolumeDescriptorPrecreateInfo(descriptors, task);
    // Now we get the Orchestration controller and use it to create the volumes of all types.
    try {
        BlockOrchestrationController controller = getController(BlockOrchestrationController.class, BlockOrchestrationController.BLOCK_ORCHESTRATION_DEVICE);
        controller.createVolumes(descriptors, task);
    } catch (InternalException e) {
        if (s_logger.isErrorEnabled()) {
            s_logger.error("Controller error", e);
        }
        String errMsg = String.format("Controller error: %s", e.getMessage());
        Operation statusUpdate = new Operation(Operation.Status.error.name(), errMsg);
        for (URI volumeURI : allVolumes) {
            _dbClient.updateTaskOpStatus(Volume.class, volumeURI, task, statusUpdate);
        }
        for (TaskResourceRep volumeTask : taskList.getTaskList()) {
            volumeTask.setState(Operation.Status.error.name());
            volumeTask.setMessage(errMsg);
        }
        throw e;
    }
    return taskList;
}
Also used : VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) VirtualArray(com.emc.storageos.db.client.model.VirtualArray) BlockOrchestrationController(com.emc.storageos.blockorchestrationcontroller.BlockOrchestrationController) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) TaskList(com.emc.storageos.model.TaskList) ArrayList(java.util.ArrayList) TaskResourceRep(com.emc.storageos.model.TaskResourceRep) 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) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) Volume(com.emc.storageos.db.client.model.Volume)

Example 18 with VPlexRecommendation

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

the class VPlexBlockServiceApiImpl method sortRecommendationsByVarray.

/**
 * 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.
 *
 * @param recommendations -- list of Recommendations
 * @param vplexSystemURIOut -- Output parameter the Vplex system URI
 * @return
 */
private Map<String, List<VPlexRecommendation>> sortRecommendationsByVarray(List<Recommendation> recommendations, URI[] vplexSystemURIOut) {
    URI vplexStorageSystemURI = null;
    Map<String, List<VPlexRecommendation>> varrayRecommendationsMap = new HashMap<String, List<VPlexRecommendation>>();
    for (Recommendation recommendation : recommendations) {
        VPlexRecommendation vplexRecommendation = (VPlexRecommendation) recommendation;
        String varrayId = vplexRecommendation.getVirtualArray().toString();
        if (vplexStorageSystemURI == null) {
            vplexStorageSystemURI = vplexRecommendation.getVPlexStorageSystem();
            vplexSystemURIOut[0] = vplexStorageSystemURI;
        }
        if (!varrayRecommendationsMap.containsKey(varrayId)) {
            List<VPlexRecommendation> varrayRecommendations = new ArrayList<VPlexRecommendation>();
            varrayRecommendations.add(vplexRecommendation);
            varrayRecommendationsMap.put(varrayId, varrayRecommendations);
        } else {
            List<VPlexRecommendation> varrayRecommendations = varrayRecommendationsMap.get(varrayId);
            varrayRecommendations.add(vplexRecommendation);
        }
    }
    return varrayRecommendationsMap;
}
Also used : VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) 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) 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)

Example 19 with VPlexRecommendation

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

the class VPlexBlockFullCopyApiImpl method prepareFullCopyHAVolumes.

/**
 * Places and prepares the HA volumes when copying a distributed VPLEX
 * volume.
 *
 * @param name The base name for the volume.
 * @param copyCount The number of copies to be made.
 * @param size The size for the HA volume.
 * @param vplexSystem A reference to the VPLEX storage system.
 * @param vplexSystemProject A reference to the VPLEX system project.
 * @param srcVarray The virtual array for the VPLEX volume being copied.
 * @param srcHAVolume The HA volume of the VPLEX volume being copied.
 * @param taskId The task identifier.
 * @param volumeDescriptors The list of descriptors.
 *
 * @return A list of the prepared HA volumes for the VPLEX volume copy.
 */
private List<Volume> prepareFullCopyHAVolumes(String name, int copyCount, Long size, StorageSystem vplexSystem, Project vplexSystemProject, VirtualArray srcVarray, Volume srcHAVolume, String taskId, List<VolumeDescriptor> volumeDescriptors) {
    List<Volume> copyHAVolumes = new ArrayList<>();
    // Get the storage placement recommendations for the volumes.
    // Placement must occur on the same VPLEX system
    Set<URI> vplexSystemURIS = new HashSet<>();
    vplexSystemURIS.add(vplexSystem.getId());
    VirtualArray haVarray = _dbClient.queryObject(VirtualArray.class, srcHAVolume.getVirtualArray());
    VirtualPool haVpool = _dbClient.queryObject(VirtualPool.class, srcHAVolume.getVirtualPool());
    VirtualPoolCapabilityValuesWrapper haCapabilities = new VirtualPoolCapabilityValuesWrapper();
    haCapabilities.put(VirtualPoolCapabilityValuesWrapper.SIZE, size);
    haCapabilities.put(VirtualPoolCapabilityValuesWrapper.RESOURCE_COUNT, copyCount);
    VirtualPool vpool = BlockFullCopyUtils.queryFullCopySourceVPool(srcHAVolume, _dbClient);
    if (VirtualPool.ProvisioningType.Thin.toString().equalsIgnoreCase(vpool.getSupportedProvisioningType())) {
        haCapabilities.put(VirtualPoolCapabilityValuesWrapper.THIN_PROVISIONING, Boolean.TRUE);
        // To guarantee that storage pool for a copy has enough physical
        // space to contain current allocated capacity of thin source volume
        haCapabilities.put(VirtualPoolCapabilityValuesWrapper.THIN_VOLUME_PRE_ALLOCATE_SIZE, BlockFullCopyUtils.getAllocatedCapacityForFullCopySource(srcHAVolume, _dbClient));
    }
    List<Recommendation> recommendations = ((VPlexScheduler) _scheduler).scheduleStorageForImport(srcVarray, vplexSystemURIS, haVarray, haVpool, haCapabilities);
    if (recommendations.isEmpty()) {
        throw APIException.badRequests.noStorageForHaVolumesForVplexVolumeCopies();
    }
    // Prepare the HA volumes for the VPLEX volume copy.
    int copyIndex = 1;
    for (Recommendation recommendation : recommendations) {
        VPlexRecommendation haRecommendation = (VPlexRecommendation) recommendation;
        for (int i = 0; i < haRecommendation.getResourceCount(); i++) {
            // Determine the name for the HA volume copy.
            StringBuilder nameBuilder = new StringBuilder(name);
            nameBuilder.append("-1");
            if (copyCount > 1) {
                nameBuilder.append("-");
                nameBuilder.append(copyIndex++);
            }
            // Prepare the volume.
            Volume volume = VPlexBlockServiceApiImpl.prepareVolumeForRequest(size, vplexSystemProject, haVarray, haVpool, haRecommendation.getSourceStorageSystem(), haRecommendation.getSourceStoragePool(), nameBuilder.toString(), null, taskId, _dbClient);
            volume.addInternalFlags(Flag.INTERNAL_OBJECT);
            _dbClient.persistObject(volume);
            copyHAVolumes.add(volume);
            // Create the volume descriptor and add it to the passed list.
            VolumeDescriptor volumeDescriptor = new VolumeDescriptor(VolumeDescriptor.Type.BLOCK_DATA, volume.getStorageController(), volume.getId(), volume.getPool(), haCapabilities);
            volumeDescriptors.add(volumeDescriptor);
        }
    }
    return copyHAVolumes;
}
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) ArrayList(java.util.ArrayList) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) URI(java.net.URI) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) Recommendation(com.emc.storageos.volumecontroller.Recommendation) VolumeRecommendation(com.emc.storageos.api.service.impl.placement.VolumeRecommendation) AlternateIdConstraint(com.emc.storageos.db.client.constraint.AlternateIdConstraint) Volume(com.emc.storageos.db.client.model.Volume) VPlexScheduler(com.emc.storageos.api.service.impl.placement.VPlexScheduler) HashSet(java.util.HashSet)

Example 20 with VPlexRecommendation

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

the class RecoverPointScheduler method getHaRecommendation.

/**
 * Determine high availability recommendation
 *
 * @param varray - High availability Virtual Array
 * @param vpool - High availability Virtual Pool
 * @param project - Project
 * @param capabilities - Virtual Pool capabilities
 * @return RPRecommendation representation for HA
 */
private RPRecommendation getHaRecommendation(VirtualArray varray, VirtualPool vpool, Project project, VirtualPoolCapabilityValuesWrapper capabilities) {
    // this logic.
    if (vpool.getHighAvailability() == null || VirtualPool.HighAvailabilityType.vplex_local.name().equals(vpool.getHighAvailability()) || VirtualPool.vPoolSpecifiesMetroPoint(vpool)) {
        return null;
    }
    VirtualArray haVarray = vplexScheduler.getHaVirtualArray(varray, project, vpool);
    VirtualPool haVpool = vplexScheduler.getHaVirtualPool(varray, project, vpool);
    Map<String, Object> attributeMap = new HashMap<String, Object>();
    Map<String, List<StoragePool>> vplexPoolMapForSrcVarray = getVplexMatchingPools(varray, vpool, haVarray, haVpool, capabilities, attributeMap);
    Recommendation haRecommendation = findVPlexHARecommendations(varray, vpool, haVarray, haVpool, project, capabilities, vplexPoolMapForSrcVarray);
    if (haRecommendation == null) {
        _log.error("No HA Recommendations could be created.");
        StringBuffer errorMessage = new StringBuffer();
        if (attributeMap.get(AttributeMatcher.ERROR_MESSAGE) != null) {
            errorMessage = (StringBuffer) attributeMap.get(AttributeMatcher.ERROR_MESSAGE);
        }
        throw APIException.badRequests.noStoragePools(varray.getLabel(), vpool.getLabel(), errorMessage.toString());
    }
    RPRecommendation rpHaRecommendation = new RPRecommendation();
    VPlexRecommendation vplexRec = (VPlexRecommendation) haRecommendation;
    // 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);
    rpHaRecommendation.setVirtualVolumeRecommendation(vplexRec);
    rpHaRecommendation.setSourceStoragePool(vplexRec.getSourceStoragePool());
    rpHaRecommendation.setSourceStorageSystem(vplexRec.getSourceStorageSystem());
    rpHaRecommendation.setVirtualArray(vplexRec.getVirtualArray());
    rpHaRecommendation.setVirtualPool(vplexRec.getVirtualPool());
    rpHaRecommendation.setResourceCount(capabilities.getResourceCount());
    rpHaRecommendation.setSize(capabilities.getSize());
    return rpHaRecommendation;
}
Also used : VirtualArray(com.emc.storageos.db.client.model.VirtualArray) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) HashMap(java.util.HashMap) RPRecommendation(com.emc.storageos.volumecontroller.RPRecommendation) DiscoveredDataObject(com.emc.storageos.db.client.model.DiscoveredDataObject) List(java.util.List) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) VPlexRecommendation(com.emc.storageos.volumecontroller.VPlexRecommendation) Recommendation(com.emc.storageos.volumecontroller.Recommendation) RPRecommendation(com.emc.storageos.volumecontroller.RPRecommendation) RPProtectionRecommendation(com.emc.storageos.volumecontroller.RPProtectionRecommendation)

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