Search in sources :

Example 6 with ApplicationAddVolumeList

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

the class RPBlockServiceApiImpl method addVolumesToApplication.

/**
 * Get ApplicationAddVolumeList
 *
 * @param volumesList The add volume list
 * @param application The application that the volumes are added to
 * @return ApplicationVolumeList The volumes that are in the add volume list
 */
private ApplicationAddVolumeList addVolumesToApplication(VolumeGroupVolumeList volumeList, VolumeGroup application) {
    List<URI> addVolumeURIs = volumeList.getVolumes();
    String groupName = volumeList.getReplicationGroupName();
    Set<URI> allVolumes = RPHelper.getReplicationSetVolumes(addVolumeURIs, _dbClient);
    Map<String, Boolean> checkedRGMap = new HashMap<String, Boolean>();
    for (URI volumeUri : allVolumes) {
        Volume volume = _dbClient.queryObject(Volume.class, volumeUri);
        if (volume == null || volume.getInactive()) {
            throw APIException.badRequests.volumeCantBeAddedToVolumeGroup(volumeUri.toString(), "Volume has been deleted");
        }
        BlockServiceUtils.validateVolumeNoReplica(volume, application, _dbClient);
        boolean vplex = RPHelper.isVPlexVolume(volume, _dbClient);
        if (vplex) {
            // get the backend volume
            Volume backendVol = VPlexUtil.getVPLEXBackendVolume(volume, true, _dbClient);
            if (backendVol == null || backendVol.getInactive()) {
                throw APIException.badRequests.volumeCantBeAddedToVolumeGroup(volume.getLabel(), "The backing volume for the VPLEX virtual volume has been deleted");
            }
            String rgName = backendVol.getReplicationGroupInstance();
            if (NullColumnValueGetter.isNotNullValue(rgName) && rgName.equals(groupName)) {
                if (!vplexBlockServiceApiImpl.checkAllVPlexVolsInRequest(backendVol, allVolumes, checkedRGMap)) {
                    throw APIException.badRequests.volumeCantBeAddedToVolumeGroup(volume.getLabel(), "Volume has to be added to a different replication group than it is currently in");
                }
            }
            // Check if the backend volume is unity, and the subgroup already has snapshot.
            if (!BlockServiceUtils.checkUnityVolumeCanBeAddedOrRemovedToCG(volumeList.getReplicationGroupName(), backendVol, _dbClient, true)) {
                throw APIException.badRequests.volumeCantBeAddedToVolumeGroup(volume.getLabel(), "the Unity subgroup has snapshot.");
            }
        } else {
            if (!BlockServiceUtils.checkUnityVolumeCanBeAddedOrRemovedToCG(volumeList.getReplicationGroupName(), volume, _dbClient, true)) {
                throw APIException.badRequests.volumeCantBeAddedToVolumeGroup(volume.getLabel(), "the Unity subgroup has snapshot.");
            }
        }
    }
    ApplicationAddVolumeList outVolumesList = new ApplicationAddVolumeList();
    outVolumesList.setConsistencyGroup(volumeList.getConsistencyGroup());
    outVolumesList.setReplicationGroupName(groupName);
    outVolumesList.setVolumes(addVolumeURIs);
    return outVolumesList;
}
Also used : HashMap(java.util.HashMap) Volume(com.emc.storageos.db.client.model.Volume) ApplicationAddVolumeList(com.emc.storageos.volumecontroller.ApplicationAddVolumeList) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI)

Example 7 with ApplicationAddVolumeList

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

the class DefaultBlockServiceApiImpl method updateVolumesInVolumeGroup.

/**
 * {@inheritDoc}
 */
@Override
public void updateVolumesInVolumeGroup(VolumeGroupVolumeList addVolumes, List<Volume> removeVolumes, URI volumeGroupId, String taskId) {
    VolumeGroup volumeGroup = _dbClient.queryObject(VolumeGroup.class, volumeGroupId);
    ApplicationAddVolumeList addVolumeList = null;
    if (addVolumes != null && addVolumes.getVolumes() != null && !addVolumes.getVolumes().isEmpty()) {
        addVolumeList = addVolumesToApplication(addVolumes, volumeGroup, taskId);
    }
    if (removeVolumes != null && !removeVolumes.isEmpty()) {
        removeVolumesFromApplication(removeVolumes, volumeGroup, taskId);
    }
    // call controller to handle non application ready CG volumes
    if ((addVolumeList != null && !addVolumeList.getVolumes().isEmpty())) {
        List<URI> vols = addVolumeList.getVolumes();
        Volume firstVolume = _dbClient.queryObject(Volume.class, vols.get(0));
        URI systemURI = firstVolume.getStorageController();
        StorageSystem system = _dbClient.queryObject(StorageSystem.class, systemURI);
        BlockController controller = getController(BlockController.class, system.getSystemType());
        controller.updateApplication(systemURI, addVolumeList, 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 : ApplicationAddVolumeList(com.emc.storageos.volumecontroller.ApplicationAddVolumeList) Volume(com.emc.storageos.db.client.model.Volume) BlockController(com.emc.storageos.volumecontroller.BlockController) VolumeGroup(com.emc.storageos.db.client.model.VolumeGroup) Operation(com.emc.storageos.db.client.model.Operation) URI(java.net.URI) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 8 with ApplicationAddVolumeList

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

the class DefaultBlockServiceApiImpl method addVolumesToApplication.

/**
 * Update volumes with volumeGroup Id, if the volumes are application ready
 * (non VNX, or VNX volumes not in a real replication group)
 *
 * @param volumesList
 *            The add volume list
 * @param application
 *            The application that the volumes are added to
 * @param taskId
 * @return ApplicationVolumeList The volumes that are not application ready (in real VNX CG with array replication
 *         group)
 */
private ApplicationAddVolumeList addVolumesToApplication(VolumeGroupVolumeList volumeList, VolumeGroup application, String taskId) {
    ApplicationAddVolumeList addVolumeList = new ApplicationAddVolumeList();
    Map<URI, List<URI>> addCGVolsMap = new HashMap<URI, List<URI>>();
    String newRGName = volumeList.getReplicationGroupName();
    for (URI voluri : volumeList.getVolumes()) {
        Volume volume = _dbClient.queryObject(Volume.class, voluri);
        if (volume == null || volume.getInactive()) {
            _log.info(String.format("The volume %s does not exist or has been deleted", voluri));
            continue;
        }
        URI cgUri = volume.getConsistencyGroup();
        if (!NullColumnValueGetter.isNullURI(cgUri)) {
            List<URI> vols = addCGVolsMap.get(cgUri);
            if (vols == null) {
                vols = new ArrayList<URI>();
            }
            vols.add(voluri);
            addCGVolsMap.put(cgUri, vols);
        } else {
            // The volume is not in CG
            throw APIException.badRequests.volumeGroupCantBeUpdated(application.getLabel(), String.format("The volume %s is not in a consistency group", volume.getLabel()));
        }
        String rgName = volume.getReplicationGroupInstance();
        if (NullColumnValueGetter.isNotNullValue(rgName) && !rgName.equals(newRGName)) {
            throw APIException.badRequests.volumeGroupCantBeUpdated(application.getLabel(), String.format("The volume %s is already in an array replication group, only the existing group name is allowed.", volume.getLabel()));
        }
    }
    Set<URI> appReadyCGUris = new HashSet<URI>();
    Set<Volume> appReadyCGVols = new HashSet<Volume>();
    Set<URI> nonAppReadyCGVolUris = new HashSet<URI>();
    // validate input volumes first, then batch processing, to avoid partial success
    for (Map.Entry<URI, List<URI>> entry : addCGVolsMap.entrySet()) {
        URI cgUri = entry.getKey();
        List<URI> cgVolsToAdd = entry.getValue();
        BlockConsistencyGroup cg = _dbClient.queryObject(BlockConsistencyGroup.class, cgUri);
        List<Volume> cgVolumes = getActiveCGVolumes(cg);
        Set<URI> cgVolumeURIs = new HashSet<URI>();
        for (Volume cgVol : cgVolumes) {
            cgVolumeURIs.add(cgVol.getId());
        }
        Volume firstVolume = _dbClient.queryObject(Volume.class, cgVolsToAdd.get(0));
        // Check if all CG volumes are adding into the application
        if (!cgVolumeURIs.containsAll(cgVolsToAdd) || cgVolsToAdd.size() != cgVolumeURIs.size()) {
            throw APIException.badRequests.volumeCantBeAddedToVolumeGroup(firstVolume.getLabel(), "not all volumes in consistency group are in the add volume list");
        }
        if (ControllerUtils.isVnxVolume(firstVolume, _dbClient) && !ControllerUtils.isNotInRealVNXRG(firstVolume, _dbClient)) {
            // VNX CG cannot have snapshots, user has to remove the snapshots first in order to add the CG to an
            // application
            URIQueryResultList cgSnapshotsResults = new URIQueryResultList();
            _dbClient.queryByConstraint(getBlockSnapshotByConsistencyGroup(cgUri), cgSnapshotsResults);
            Iterator<URI> cgSnapshotsIter = cgSnapshotsResults.iterator();
            while (cgSnapshotsIter.hasNext()) {
                BlockSnapshot cgSnapshot = _dbClient.queryObject(BlockSnapshot.class, cgSnapshotsIter.next());
                if ((cgSnapshot != null) && (!cgSnapshot.getInactive())) {
                    throw APIException.badRequests.notAllowedWhenVNXCGHasSnapshot();
                }
            }
            nonAppReadyCGVolUris.addAll(cgVolumeURIs);
        } else {
            // non VNX CG volume, or volume in VNX CG with no array replication group
            appReadyCGUris.add(cgUri);
            appReadyCGVols.addAll(cgVolumes);
        }
    }
    if (!appReadyCGVols.isEmpty()) {
        for (Volume cgVol : appReadyCGVols) {
            StringSet applications = cgVol.getVolumeGroupIds();
            applications.add(application.getId().toString());
            cgVol.setVolumeGroupIds(applications);
            // handle clones
            StringSet fullCopies = cgVol.getFullCopies();
            List<Volume> fullCopiesToUpdate = new ArrayList<Volume>();
            if (fullCopies != null && !fullCopies.isEmpty()) {
                for (String fullCopyId : fullCopies) {
                    Volume fullCopy = _dbClient.queryObject(Volume.class, URI.create(fullCopyId));
                    if (fullCopy != null && !fullCopy.getInactive()) {
                        fullCopy.setFullCopySetName(fullCopy.getReplicationGroupInstance());
                        fullCopiesToUpdate.add(fullCopy);
                    }
                }
            }
            if (!fullCopiesToUpdate.isEmpty()) {
                _dbClient.updateObject(fullCopiesToUpdate);
            }
            Operation op = cgVol.getOpStatus().get(taskId);
            op.ready();
            cgVol.getOpStatus().updateTaskStatus(taskId, op);
        }
        _dbClient.updateObject(appReadyCGVols);
    }
    if (!appReadyCGUris.isEmpty()) {
        for (URI cgUri : appReadyCGUris) {
            BlockConsistencyGroup cg = _dbClient.queryObject(BlockConsistencyGroup.class, cgUri);
            if (cg != null && !cg.getInactive()) {
                cg.setArrayConsistency(false);
                Operation op = cg.getOpStatus().get(taskId);
                op.ready();
                cg.getOpStatus().updateTaskStatus(taskId, op);
                _dbClient.updateObject(cg);
            }
        }
    }
    addVolumeList.getVolumes().addAll(nonAppReadyCGVolUris);
    _log.info("Added volumes in CG to the application");
    return addVolumeList;
}
Also used : ApplicationAddVolumeList(com.emc.storageos.volumecontroller.ApplicationAddVolumeList) HashMap(java.util.HashMap) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) ArrayList(java.util.ArrayList) Operation(com.emc.storageos.db.client.model.Operation) URI(java.net.URI) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) Volume(com.emc.storageos.db.client.model.Volume) StringSet(com.emc.storageos.db.client.model.StringSet) ApplicationAddVolumeList(com.emc.storageos.volumecontroller.ApplicationAddVolumeList) StorageSystemConnectivityList(com.emc.storageos.model.systems.StorageSystemConnectivityList) List(java.util.List) VirtualPoolChangeList(com.emc.storageos.model.vpool.VirtualPoolChangeList) 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) Map(java.util.Map) HashMap(java.util.HashMap) HashSet(java.util.HashSet)

Example 9 with ApplicationAddVolumeList

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

the class BlockDeviceController method updateApplication.

/**
 * Adding/removing volumes to/from an application is ViPR DB only operation (no controller side involved),
 * except for adding VNX volumes to an application, if the VNX volumes are in a real replication group.
 *
 * 1. remove volumes from replication group, keep volume's replicationGroupInstance unchanged
 * 2. delete the replication group from array, keep CG's systemConsistencyGroup unchanged
 * 3. change CG's arrayConsistency to false, update volume's volumeGroupIds, update clone's fullCopySetName
 * (performed in the completer class)
 */
@Override
public void updateApplication(URI storage, ApplicationAddVolumeList addVolList, URI application, String opId) throws ControllerException {
    TaskCompleter completer = null;
    String waitFor = null;
    try {
        // Generate the Workflow.
        Workflow workflow = _workflowService.getNewWorkflow(this, UPDATE_VOLUMES_FOR_APPLICATION_WS_NAME, false, opId);
        List<URI> volumesToAdd = null;
        if (addVolList != null) {
            volumesToAdd = addVolList.getVolumes();
        }
        if (volumesToAdd != null && !volumesToAdd.isEmpty()) {
            Map<URI, List<URI>> addVolsMap = new HashMap<URI, List<URI>>();
            for (URI voluri : volumesToAdd) {
                Volume vol = _dbClient.queryObject(Volume.class, voluri);
                if (vol != null && !vol.getInactive()) {
                    if (ControllerUtils.isVnxVolume(vol, _dbClient) && vol.isInCG() && !ControllerUtils.isNotInRealVNXRG(vol, _dbClient)) {
                        URI cguri = vol.getConsistencyGroup();
                        List<URI> vols = addVolsMap.get(cguri);
                        if (vols == null) {
                            vols = new ArrayList<URI>();
                        }
                        vols.add(voluri);
                        addVolsMap.put(cguri, vols);
                    }
                }
            }
            List<URI> cgs = new ArrayList<URI>(addVolsMap.keySet());
            completer = new ApplicationTaskCompleter(application, volumesToAdd, null, cgs, opId);
            for (Map.Entry<URI, List<URI>> entry : addVolsMap.entrySet()) {
                _log.info("Creating workflows for adding CG volumes to application");
                URI cguri = entry.getKey();
                List<URI> cgVolsToAdd = entry.getValue();
                URI voluri = cgVolsToAdd.get(0);
                Volume vol = _dbClient.queryObject(Volume.class, voluri);
                StorageSystem storageSystem = _dbClient.queryObject(StorageSystem.class, vol.getStorageController());
                BlockConsistencyGroup cg = _dbClient.queryObject(BlockConsistencyGroup.class, cguri);
                String groupName = ControllerUtils.generateReplicationGroupName(storageSystem, cguri, vol.getReplicationGroupInstance(), _dbClient);
                // remove volumes from array replication group, and delete the group, but keep volumes reference
                waitFor = workflow.createStep(UPDATE_CONSISTENCY_GROUP_STEP_GROUP, String.format("Removing volumes from consistency group %s", cg.getLabel()), waitFor, storage, storageSystem.getSystemType(), this.getClass(), removeFromConsistencyGroupMethod(storage, cguri, cgVolsToAdd, true), rollbackMethodNullMethod(), null);
                // remove replication group
                waitFor = workflow.createStep(UPDATE_CONSISTENCY_GROUP_STEP_GROUP, String.format("Deleting replication group for consistency group %s", cg.getLabel()), waitFor, storage, storageSystem.getSystemType(), this.getClass(), deleteConsistencyGroupMethod(storage, cguri, groupName, true, false, false), rollbackMethodNullMethod(), null);
            }
        }
        // Finish up and execute the plan.
        _log.info("Executing workflow plan {}", UPDATE_VOLUMES_FOR_APPLICATION_WS_NAME);
        String successMessage = String.format("Update application successful for %s", application.toString());
        workflow.executePlan(completer, successMessage);
    } catch (Exception e) {
        _log.error("Exception while updating the application", e);
        if (completer != null) {
            completer.error(_dbClient, DeviceControllerException.exceptions.failedToUpdateVolumesFromAppication(application.toString(), e.getMessage()));
        }
    }
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Workflow(com.emc.storageos.workflow.Workflow) NamedURI(com.emc.storageos.db.client.model.NamedURI) FCTN_MIRROR_TO_URI(com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_MIRROR_TO_URI) URI(java.net.URI) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) BaseCollectionException(com.emc.storageos.plugins.BaseCollectionException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) WorkflowException(com.emc.storageos.workflow.WorkflowException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) DataBindingException(javax.xml.bind.DataBindingException) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) Volume(com.emc.storageos.db.client.model.Volume) Arrays.asList(java.util.Arrays.asList) ApplicationAddVolumeList(com.emc.storageos.volumecontroller.ApplicationAddVolumeList) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) List(java.util.List) ScanTaskCompleter(com.emc.storageos.volumecontroller.impl.plugins.discovery.smis.ScanTaskCompleter) BlockSnapshotEstablishGroupTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.BlockSnapshotEstablishGroupTaskCompleter) BlockMirrorTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.BlockMirrorTaskCompleter) CloneTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.CloneTaskCompleter) ApplicationTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ApplicationTaskCompleter) SimpleTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.SimpleTaskCompleter) VolumeTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.VolumeTaskCompleter) DiscoverTaskCompleter(com.emc.storageos.volumecontroller.impl.plugins.discovery.smis.DiscoverTaskCompleter) TaskCompleter(com.emc.storageos.volumecontroller.TaskCompleter) MultiVolumeTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.MultiVolumeTaskCompleter) ApplicationTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.ApplicationTaskCompleter) Map(java.util.Map) OpStatusMap(com.emc.storageos.db.client.model.OpStatusMap) HashMap(java.util.HashMap) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Aggregations

ApplicationAddVolumeList (com.emc.storageos.volumecontroller.ApplicationAddVolumeList)9 URI (java.net.URI)9 NamedURI (com.emc.storageos.db.client.model.NamedURI)7 Volume (com.emc.storageos.db.client.model.Volume)7 ArrayList (java.util.ArrayList)6 Operation (com.emc.storageos.db.client.model.Operation)4 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)3 VolumeGroup (com.emc.storageos.db.client.model.VolumeGroup)3 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)3 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)3 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)3 ControllerException (com.emc.storageos.volumecontroller.ControllerException)3 TaskCompleter (com.emc.storageos.volumecontroller.TaskCompleter)3 Workflow (com.emc.storageos.workflow.Workflow)3 WorkflowException (com.emc.storageos.workflow.WorkflowException)3 HashMap (java.util.HashMap)3 HashSet (java.util.HashSet)3 List (java.util.List)3 BlockConsistencyGroup (com.emc.storageos.db.client.model.BlockConsistencyGroup)2 ProtectionSystem (com.emc.storageos.db.client.model.ProtectionSystem)2