Search in sources :

Example 91 with Operation

use of com.emc.storageos.db.client.model.Operation in project coprhd-controller by CoprHD.

the class VPlexBlockServiceApiImpl method orchestrateVPoolChanges.

/**
 * Invokes the block orchestrator for a vpool change operation.
 *
 * @param volumes The volumes undergoing the vpool change.
 * @param descriptors The prepared volume descriptors.
 * @param taskId The task identifier.
 */
private void orchestrateVPoolChanges(List<Volume> volumes, List<VolumeDescriptor> descriptors, String taskId) {
    try {
        BlockOrchestrationController controller = getController(BlockOrchestrationController.class, BlockOrchestrationController.BLOCK_ORCHESTRATION_DEVICE);
        controller.changeVirtualPool(descriptors, taskId);
    } catch (InternalException e) {
        if (s_logger.isErrorEnabled()) {
            s_logger.error("Controller error", e);
        }
        String errMsg = String.format("Controller error on changeVolumeVirtualPool: %s", e.getMessage());
        Operation statusUpdate = new Operation(Operation.Status.error.name(), errMsg);
        for (Volume volume : volumes) {
            _dbClient.updateTaskOpStatus(Volume.class, volume.getId(), taskId, statusUpdate);
        }
        throw e;
    }
}
Also used : BlockOrchestrationController(com.emc.storageos.blockorchestrationcontroller.BlockOrchestrationController) Volume(com.emc.storageos.db.client.model.Volume) Operation(com.emc.storageos.db.client.model.Operation) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException)

Example 92 with Operation

use of com.emc.storageos.db.client.model.Operation in project coprhd-controller by CoprHD.

the class VPlexBlockServiceApiImpl method updateConsistencyGroup.

/**
 * {@inheritDoc}
 */
@Override
public TaskResourceRep updateConsistencyGroup(StorageSystem cgStorageSystem, List<Volume> cgVolumes, BlockConsistencyGroup consistencyGroup, List<URI> addVolumesList, List<URI> removeVolumesList, String taskId) throws ControllerException {
    // addVolumesList could be volumes, or full copies, or snapshots or mirrors.
    List<URI> addVolumes = new ArrayList<URI>();
    List<URI> addSnapshots = new ArrayList<URI>();
    List<URI> addFullcopies = new ArrayList<URI>();
    for (URI volumeURI : addVolumesList) {
        BlockObject blockObject = BlockObject.fetch(_dbClient, volumeURI);
        if (blockObject instanceof BlockMirror) {
            throw APIException.badRequests.actionNotApplicableForVplexVolumeMirrors(ResourceOperationTypeEnum.UPDATE_CONSISTENCY_GROUP.name());
        } else if (blockObject instanceof BlockSnapshot) {
            addSnapshots.add(volumeURI);
        } else if (blockObject instanceof Volume) {
            boolean isFullCopy = ControllerUtils.isVolumeFullCopy((Volume) blockObject, _dbClient);
            if (isFullCopy) {
                addFullcopies.add(volumeURI);
            } else {
                addVolumes.add(volumeURI);
            }
        }
    }
    if ((!addVolumes.isEmpty() && (!addSnapshots.isEmpty() || !addFullcopies.isEmpty())) || (!addSnapshots.isEmpty() && !addFullcopies.isEmpty())) {
        throw APIException.badRequests.cantUpdateCGWithMixedBlockObjects(consistencyGroup.getLabel());
    }
    // group.
    if (!addVolumes.isEmpty()) {
        Iterator<Volume> cgVolumesIter = cgVolumes.iterator();
        if (cgVolumesIter.hasNext()) {
            Volume cgVolume = cgVolumesIter.next();
            VirtualPool cgVPool = _permissionsHelper.getObjectById(cgVolume.getVirtualPool(), VirtualPool.class);
            URI cgVArrayURI = cgVolume.getVirtualArray();
            String cgHAType = cgVPool.getHighAvailability();
            for (URI volumeURI : addVolumes) {
                Volume addVolume = _permissionsHelper.getObjectById(volumeURI, Volume.class);
                VirtualPool addVolumeVPool = _permissionsHelper.getObjectById(addVolume.getVirtualPool(), VirtualPool.class);
                if (!addVolumeVPool.getHighAvailability().equals(cgHAType)) {
                    throw APIException.badRequests.invalidParameterConsistencyGroupVolumeHasIncorrectHighAvailability(cgVolume.getId(), cgHAType);
                } else if (!cgVArrayURI.equals(addVolume.getVirtualArray())) {
                    throw APIException.badRequests.invalidParameterConsistencyGroupVolumeHasIncorrectVArray(cgVolume.getId(), cgVArrayURI);
                }
            }
        }
        // Check if the volumes have been in the CG, and not ingestion case
        if (consistencyGroup.getTypes().contains(Types.LOCAL.toString()) && !cgVolumes.isEmpty()) {
            Set<String> cgVolumesURISet = new HashSet<String>();
            for (Volume cgVolume : cgVolumes) {
                cgVolumesURISet.add(cgVolume.getId().toString());
            }
            Iterator<URI> iter = addVolumes.iterator();
            while (iter.hasNext()) {
                if (cgVolumesURISet.contains(iter.next().toString())) {
                    iter.remove();
                }
            }
            if (addVolumes.isEmpty()) {
                // All volumes in the addVolumes list have been in the CG. return success
                s_logger.info("The volumes have been added to the CG");
                Operation op = new Operation();
                op.setResourceType(ResourceOperationTypeEnum.UPDATE_CONSISTENCY_GROUP);
                op.ready("Volumes have been added to the consistency group");
                _dbClient.createTaskOpStatus(BlockConsistencyGroup.class, consistencyGroup.getId(), taskId, op);
                return toTask(consistencyGroup, taskId, op);
            }
        }
    }
    // Only add snapshot or full copies to CG if backend volumes are from the same storage system.
    if (!addSnapshots.isEmpty() || !addFullcopies.isEmpty()) {
        if (!VPlexUtil.isVPLEXCGBackendVolumesInSameStorage(cgVolumes, _dbClient)) {
            throw APIException.badRequests.cantUpdateCGWithReplicaFromMultipleSystems(consistencyGroup.getLabel());
        }
    }
    Operation op = _dbClient.createTaskOpStatus(BlockConsistencyGroup.class, consistencyGroup.getId(), taskId, ResourceOperationTypeEnum.UPDATE_CONSISTENCY_GROUP);
    // When adding snapshots to CG, just call block implementation.
    if (!addSnapshots.isEmpty()) {
        BlockSnapshot snapshot = _permissionsHelper.getObjectById(addSnapshots.get(0), BlockSnapshot.class);
        URI systemURI = snapshot.getStorageController();
        StorageSystem system = _permissionsHelper.getObjectById(systemURI, StorageSystem.class);
        BlockController controller = getController(BlockController.class, system.getSystemType());
        controller.updateConsistencyGroup(system.getId(), consistencyGroup.getId(), addVolumesList, removeVolumesList, taskId);
        return toTask(consistencyGroup, taskId, op);
    }
    // all the virtual volumes in the CG have to be selected.
    if (!addVolumes.isEmpty()) {
        verifyAddVolumesToIngestedCG(consistencyGroup, addVolumes);
    }
    if (!addFullcopies.isEmpty()) {
        addVolumes.addAll(addFullcopies);
    }
    // Get VPlex controller
    VPlexController controller = getController();
    controller.updateConsistencyGroup(cgStorageSystem.getId(), consistencyGroup.getId(), addVolumes, removeVolumesList, taskId);
    return toTask(consistencyGroup, taskId, op);
}
Also used : BlockMirror(com.emc.storageos.db.client.model.BlockMirror) VPlexController(com.emc.storageos.vplexcontroller.VPlexController) BlockController(com.emc.storageos.volumecontroller.BlockController) ArrayList(java.util.ArrayList) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) 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) Volume(com.emc.storageos.db.client.model.Volume) BlockObject(com.emc.storageos.db.client.model.BlockObject) HashSet(java.util.HashSet) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 93 with Operation

use of com.emc.storageos.db.client.model.Operation in project coprhd-controller by CoprHD.

the class VPlexBlockServiceApiImpl method deleteConsistencyGroup.

/**
 * {@inheritDoc}
 */
@Override
public TaskResourceRep deleteConsistencyGroup(StorageSystem device, BlockConsistencyGroup consistencyGroup, String task) throws ControllerException {
    Operation op = _dbClient.createTaskOpStatus(BlockConsistencyGroup.class, consistencyGroup.getId(), task, ResourceOperationTypeEnum.DELETE_CONSISTENCY_GROUP);
    // Get VPlex controller and delete the consistency group.
    VPlexController controller = getController();
    controller.deleteConsistencyGroup(device.getId(), consistencyGroup.getId(), task);
    return toTask(consistencyGroup, task, op);
}
Also used : VPlexController(com.emc.storageos.vplexcontroller.VPlexController) Operation(com.emc.storageos.db.client.model.Operation)

Example 94 with Operation

use of com.emc.storageos.db.client.model.Operation 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 95 with Operation

use of com.emc.storageos.db.client.model.Operation in project coprhd-controller by CoprHD.

the class VPlexBlockServiceApiImpl method updateVolumesInVolumeGroup.

/**
 * {@inheritDoc}
 */
@Override
public void updateVolumesInVolumeGroup(VolumeGroupVolumeList addVolumes, List<Volume> removeVolumes, URI volumeGroupId, String taskId) {
    ApplicationAddVolumeList addVols = new ApplicationAddVolumeList();
    VolumeGroup volumeGroup = _dbClient.queryObject(VolumeGroup.class, volumeGroupId);
    URI systemURI = getVolumesToAddToApplication(addVols, addVolumes, volumeGroup, taskId);
    List<URI> removeVolIds = new ArrayList<URI>();
    URI removeSystemURI = getVolumesToRemoveFromApplication(removeVolIds, removeVolumes);
    if (systemURI == null) {
        systemURI = removeSystemURI;
    }
    if (systemURI != null) {
        VPlexController controller = getController();
        controller.updateVolumeGroup(systemURI, addVols, removeVolIds, volumeGroup.getId(), taskId);
    } else {
        // No need to call to controller. update the application task
        Operation op = volumeGroup.getOpStatus().get(taskId);
        op.ready();
        volumeGroup.getOpStatus().updateTaskStatus(taskId, op);
        _dbClient.updateObject(volumeGroup);
    }
}
Also used : VPlexController(com.emc.storageos.vplexcontroller.VPlexController) ApplicationAddVolumeList(com.emc.storageos.volumecontroller.ApplicationAddVolumeList) VolumeGroup(com.emc.storageos.db.client.model.VolumeGroup) 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)

Aggregations

Operation (com.emc.storageos.db.client.model.Operation)272 URI (java.net.URI)114 CheckPermission (com.emc.storageos.security.authorization.CheckPermission)105 Path (javax.ws.rs.Path)105 Produces (javax.ws.rs.Produces)103 Volume (com.emc.storageos.db.client.model.Volume)93 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)92 ArrayList (java.util.ArrayList)83 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)70 Consumes (javax.ws.rs.Consumes)70 NamedURI (com.emc.storageos.db.client.model.NamedURI)68 TaskResourceRep (com.emc.storageos.model.TaskResourceRep)68 POST (javax.ws.rs.POST)67 TaskList (com.emc.storageos.model.TaskList)59 FileShare (com.emc.storageos.db.client.model.FileShare)56 SMBFileShare (com.emc.storageos.db.client.model.SMBFileShare)49 APIException (com.emc.storageos.svcs.errorhandling.resources.APIException)40 MapFileShare (com.emc.storageos.api.mapper.functions.MapFileShare)36 VirtualPool (com.emc.storageos.db.client.model.VirtualPool)35 ControllerException (com.emc.storageos.volumecontroller.ControllerException)35