Search in sources :

Example 1 with ApplicationAddVolumeList

use of com.emc.storageos.volumecontroller.ApplicationAddVolumeList 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)

Example 2 with ApplicationAddVolumeList

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

the class RPDeviceController method updateApplication.

/*
     * (non-Javadoc)
     * 
     * @see com.emc.storageos.protectioncontroller.RPController#updateApplication(java.net.URI,
     * com.emc.storageos.volumecontroller.ApplicationAddVolumeList, java.util.List, java.net.URI, java.lang.String)
     */
@Override
public void updateApplication(URI systemURI, ApplicationAddVolumeList addVolList, List<URI> removeVolumeURIs, URI applicationId, String taskId) {
    // get all source and target devices
    // for remove volumes source and targets can be processed in the same step
    // for add volumes, split up volumes into source and target
    // assign a different replication group name for target volumes so they don't end up in the same group as source
    // volumes
    // create one step for remove volumes and add source volumes and a separate step for add target volumes
    TaskCompleter completer = null;
    try {
        Set<URI> impactedCGs = new HashSet<URI>();
        List<URI> allRemoveVolumes = new ArrayList<URI>();
        Set<URI> removeVolumeSet = new HashSet<URI>();
        if (removeVolumeURIs != null && !removeVolumeURIs.isEmpty()) {
            // get source and target volumes to be removed from the application
            removeVolumeSet = RPHelper.getReplicationSetVolumes(removeVolumeURIs, _dbClient);
            for (URI removeUri : removeVolumeSet) {
                Volume removeVol = _dbClient.queryObject(Volume.class, removeUri);
                URI cguri = removeVol.getConsistencyGroup();
                impactedCGs.add(cguri);
                addBackendVolumes(removeVol, false, allRemoveVolumes, null);
            }
        }
        Set<URI> vplexVolumes = new HashSet<URI>();
        Set<URI> addVolumeSet = new HashSet<URI>();
        ApplicationAddVolumeList addSourceVols = new ApplicationAddVolumeList();
        ApplicationAddVolumeList addTargetVols = new ApplicationAddVolumeList();
        boolean existingSnapOrClone = false;
        URI protectionSystemId = null;
        ProtectionSystem protectionSystem = null;
        Set<String> volumeWWNs = new HashSet<String>();
        Volume aSrcVolume = null;
        if (addVolList != null && addVolList.getVolumes() != null && !addVolList.getVolumes().isEmpty()) {
            URI addVolCg = null;
            // get source and target volumes to be added the application
            addVolumeSet = RPHelper.getReplicationSetVolumes(addVolList.getVolumes(), _dbClient);
            // split up add volumes list by source and target
            List<URI> allAddSourceVolumes = new ArrayList<URI>();
            List<URI> allAddTargetVolumes = new ArrayList<URI>();
            for (URI volUri : addVolumeSet) {
                Volume vol = _dbClient.queryObject(Volume.class, volUri);
                if (protectionSystemId == null) {
                    protectionSystemId = vol.getProtectionController();
                }
                URI cguri = vol.getConsistencyGroup();
                if (addVolCg == null && cguri != null) {
                    addVolCg = cguri;
                }
                impactedCGs.add(cguri);
                if (vol.checkPersonality(Volume.PersonalityTypes.SOURCE.name())) {
                    addBackendVolumes(vol, true, allAddSourceVolumes, vplexVolumes);
                    aSrcVolume = vol;
                } else if (vol.checkPersonality(Volume.PersonalityTypes.TARGET.name())) {
                    addBackendVolumes(vol, true, allAddTargetVolumes, vplexVolumes);
                    volumeWWNs.add(RPHelper.getRPWWn(vol.getId(), _dbClient));
                }
            }
            if (protectionSystemId != null) {
                protectionSystem = _dbClient.queryObject(ProtectionSystem.class, protectionSystemId);
            }
            addSourceVols.setConsistencyGroup(addVolCg);
            addSourceVols.setReplicationGroupName(addVolList.getReplicationGroupName());
            addSourceVols.setVolumes(allAddSourceVolumes);
            String targetReplicationGroupName = addVolList.getReplicationGroupName() + REPLICATION_GROUP_RPTARGET_SUFFIX;
            addTargetVols.setConsistencyGroup(addVolCg);
            addTargetVols.setReplicationGroupName(targetReplicationGroupName);
            addTargetVols.setVolumes(allAddTargetVolumes);
            // if there are any target clones or snapshots, need to create a bookmark and enable image access
            List<Volume> existingVols = CustomQueryUtility.queryActiveResourcesByConstraint(_dbClient, Volume.class, AlternateIdConstraint.Factory.getVolumeByReplicationGroupInstance(targetReplicationGroupName));
            for (Volume existingVol : existingVols) {
                if (existingVol.getFullCopies() != null && !existingVol.getFullCopies().isEmpty()) {
                    existingSnapOrClone = true;
                    break;
                } else if (ControllerUtils.checkIfVolumeHasSnapshotSession(existingVol.getId(), _dbClient)) {
                    existingSnapOrClone = true;
                    break;
                } else if (ControllerUtils.checkIfVolumeHasSnapshot(existingVol, _dbClient)) {
                    existingSnapOrClone = true;
                    break;
                }
            }
        }
        // Get a new workflow to execute the volume group update.
        Workflow workflow = _workflowService.getNewWorkflow(this, BlockDeviceController.UPDATE_VOLUMES_FOR_APPLICATION_WS_NAME, false, taskId);
        // create the completer add the steps and execute the plan.
        completer = new VolumeGroupUpdateTaskCompleter(applicationId, addVolumeSet, removeVolumeSet, impactedCGs, taskId);
        String waitFor = null;
        if (existingSnapOrClone) {
            // A temporary date/time stamp for the bookmark name
            String bookmarkName = VIPR_SNAPSHOT_PREFIX + (new Random()).nextInt();
            // Step 1 - Create a RP bookmark
            String rpWaitFor = addCreateBookmarkStep(workflow, new ArrayList<URI>(), protectionSystem, bookmarkName, volumeWWNs, false, waitFor);
            // Lock CG for the duration of the workflow so enable and disable can complete before another workflow
            // tries to enable image
            // access
            List<String> locks = new ArrayList<String>();
            String lockName = ControllerLockingUtil.getConsistencyGroupStorageKey(_dbClient, aSrcVolume.getConsistencyGroup(), protectionSystem.getId());
            if (null != lockName) {
                locks.add(lockName);
                acquireWorkflowLockOrThrow(workflow, locks);
            }
            // Step 2 - Enable image access
            waitFor = addEnableImageAccessForCreateReplicaStep(workflow, protectionSystem, null, new ArrayList<URI>(), bookmarkName, volumeWWNs, rpWaitFor);
        }
        // add steps for add source and remove vols
        waitFor = _blockDeviceController.addStepsForUpdateApplication(workflow, addSourceVols, allRemoveVolumes, waitFor, taskId);
        // add steps for add target vols
        waitFor = _blockDeviceController.addStepsForUpdateApplication(workflow, addTargetVols, null, waitFor, taskId);
        if (existingSnapOrClone) {
            waitFor = addDisableImageAccessForCreateReplicaStep(workflow, protectionSystem, null, new ArrayList<URI>(), volumeWWNs, waitFor);
        }
        if (!vplexVolumes.isEmpty()) {
            _vplexDeviceController.addStepsForImportClonesOfApplicationVolumes(workflow, waitFor, new ArrayList<URI>(vplexVolumes), taskId);
        }
        _log.info("Executing workflow plan {}", BlockDeviceController.UPDATE_VOLUMES_FOR_APPLICATION_WS_NAME);
        String successMessage = String.format("Update application successful for %s", applicationId.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(applicationId.toString(), e.getMessage()));
        }
        throw e;
    }
}
Also used : ApplicationAddVolumeList(com.emc.storageos.volumecontroller.ApplicationAddVolumeList) ArrayList(java.util.ArrayList) Workflow(com.emc.storageos.workflow.Workflow) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) ProtectionSystem(com.emc.storageos.db.client.model.ProtectionSystem) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) InternalServerErrorException(com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException) ControllerException(com.emc.storageos.volumecontroller.ControllerException) LockRetryException(com.emc.storageos.locking.LockRetryException) FunctionalAPIActionFailedException_Exception(com.emc.fapiclient.ws.FunctionalAPIActionFailedException_Exception) URISyntaxException(java.net.URISyntaxException) WorkflowException(com.emc.storageos.workflow.WorkflowException) DatabaseException(com.emc.storageos.db.exceptions.DatabaseException) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) FunctionalAPIInternalError_Exception(com.emc.fapiclient.ws.FunctionalAPIInternalError_Exception) CoordinatorException(com.emc.storageos.coordinator.exceptions.CoordinatorException) RecoverPointException(com.emc.storageos.recoverpoint.exceptions.RecoverPointException) Random(java.util.Random) Volume(com.emc.storageos.db.client.model.Volume) VolumeGroupUpdateTaskCompleter(com.emc.storageos.vplexcontroller.completers.VolumeGroupUpdateTaskCompleter) VolumeGroupUpdateTaskCompleter(com.emc.storageos.vplexcontroller.completers.VolumeGroupUpdateTaskCompleter) TaskCompleter(com.emc.storageos.volumecontroller.TaskCompleter) VolumeVpoolChangeTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.VolumeVpoolChangeTaskCompleter) RPCGProtectionTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.RPCGProtectionTaskCompleter) HashSet(java.util.HashSet)

Example 3 with ApplicationAddVolumeList

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

the class BlockDeviceController method addStepsForUpdateApplication.

/**
 * add step for update application, using by VPLEX and RP to
 * add/remove block volumes to/from replication groups on multiple storage systems
 *
 * @param workflow
 * @param addVolList
 * @param removeVolumeURIs
 * @param waitForStep
 * @param taskId
 * @return
 */
public String addStepsForUpdateApplication(Workflow workflow, ApplicationAddVolumeList addVolList, List<URI> removeVolumeURIs, String waitForStep, String taskId) {
    String waitFor = waitForStep;
    // split up volumes by storage system, replication group, and add steps for each storage system and RG
    Table<URI, String, List<URI>> storageRGToRemoveVolumes = getStorageSystemRGVolumes(removeVolumeURIs, null);
    // map volumes to add by storage system, replication group
    if (addVolList != null) {
        // add source and target volumes from array replication groups
        Table<URI, String, List<URI>> storageRGToAddVolumes = getStorageSystemRGVolumes(addVolList.getVolumes(), addVolList.getReplicationGroupName());
        for (Cell<URI, String, List<URI>> cell : storageRGToAddVolumes.cellSet()) {
            URI storage = cell.getRowKey();
            String rgName = cell.getColumnKey();
            List<URI> addVolumes = cell.getValue();
            List<URI> removeVolumes = new ArrayList<URI>();
            if (NullColumnValueGetter.isNotNullValue(rgName)) {
                // volumes have already been in a RG, need remove them from original RG
                removeVolumes.addAll(addVolumes);
            }
            if (storageRGToRemoveVolumes.contains(storage, rgName)) {
                removeVolumes.addAll(storageRGToRemoveVolumes.remove(storage, rgName));
            }
            waitFor = addStepsForUpdateApplicationSingleStorage(workflow, storage, addVolList.getReplicationGroupName(), addVolumes, removeVolumes, waitFor, taskId);
        }
    }
    // process remaining storage system and RG that has volumes to remove from application
    for (Cell<URI, String, List<URI>> cell : storageRGToRemoveVolumes.cellSet()) {
        waitFor = addStepsForUpdateApplicationSingleStorage(workflow, cell.getRowKey(), null, null, cell.getValue(), waitFor, taskId);
    }
    return waitFor;
}
Also used : ArrayList(java.util.ArrayList) 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) 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)

Example 4 with ApplicationAddVolumeList

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

the class RPBlockServiceApiImpl method updateVolumesInVolumeGroup.

/**
 * {@inheritDoc}
 */
@Override
public void updateVolumesInVolumeGroup(VolumeGroupVolumeList addVolumes, List<Volume> removeVolumes, URI applicationId, String taskId) {
    VolumeGroup volumeGroup = _dbClient.queryObject(VolumeGroup.class, applicationId);
    ApplicationAddVolumeList addVolumeList = null;
    List<URI> removeVolumesURI = null;
    RPController controller = null;
    URI protSystemUri = null;
    Volume firstVolume = null;
    if (addVolumes != null && addVolumes.getVolumes() != null && !addVolumes.getVolumes().isEmpty()) {
        addVolumeList = addVolumesToApplication(addVolumes, volumeGroup);
        List<URI> vols = addVolumeList.getVolumes();
        if (vols != null && !vols.isEmpty()) {
            firstVolume = _dbClient.queryObject(Volume.class, vols.get(0));
        }
    }
    if (removeVolumes != null && !removeVolumes.isEmpty()) {
        removeVolumesURI = getValidVolumesToRemoveFromCG(removeVolumes);
        if (firstVolume == null) {
            firstVolume = removeVolumes.get(0);
        }
    }
    if ((addVolumeList != null && !addVolumeList.getVolumes().isEmpty()) || (removeVolumesURI != null && !removeVolumesURI.isEmpty())) {
        protSystemUri = firstVolume.getProtectionController();
        ProtectionSystem system = _dbClient.queryObject(ProtectionSystem.class, protSystemUri);
        controller = getController(RPController.class, system.getSystemType());
        controller.updateApplication(protSystemUri, addVolumeList, removeVolumesURI, 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) RPController(com.emc.storageos.protectioncontroller.RPController) Volume(com.emc.storageos.db.client.model.Volume) VolumeGroup(com.emc.storageos.db.client.model.VolumeGroup) Operation(com.emc.storageos.db.client.model.Operation) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) ProtectionSystem(com.emc.storageos.db.client.model.ProtectionSystem)

Example 5 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)

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