Search in sources :

Example 16 with ProtectionSystem

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

the class RPDeviceController method checkIfDistributedVplexOrVmaxFullCopies.

/**
 * Check if the full copies source volumes are distributed vplex volumes or VMAX volume
 *
 * @param fullcopies
 *            - URI of full copies
 * @return - the source volumes that are vmax or vplex distributed volumes
 */
private List<Volume> checkIfDistributedVplexOrVmaxFullCopies(List<URI> fullcopies) {
    List<Volume> sourceVolumes = new ArrayList<Volume>();
    for (URI fullCopyUri : fullcopies) {
        Volume fullCopy = _dbClient.queryObject(Volume.class, fullCopyUri);
        if (fullCopy != null) {
            boolean toadd = false;
            URI volume = fullCopy.getAssociatedSourceVolume();
            Volume sourceVol = _dbClient.queryObject(Volume.class, volume);
            if (sourceVol != null) {
                if (!sourceVol.checkForRp()) {
                    toadd = false;
                } else if (sourceVol.getAssociatedVolumes() != null && sourceVol.getAssociatedVolumes().size() == 2) {
                    // RP + VPLEX distributed
                    toadd = true;
                } else {
                    // RP + VMAX
                    URI storage = sourceVol.getStorageController();
                    if (!NullColumnValueGetter.isNullURI(storage)) {
                        StorageSystem storageSystem = _dbClient.queryObject(StorageSystem.class, storage);
                        if (storageSystem != null && storageSystem.getSystemType().equals(SystemType.vmax.name())) {
                            toadd = true;
                        }
                    } else {
                        _log.error(String.format("The source %s storage system is null", sourceVol.getLabel()));
                    }
                }
            }
            // volume is a distributed vplex or vmax volume
            if (!NullColumnValueGetter.isNullURI(sourceVol.getProtectionController()) && toadd) {
                ProtectionSystem rpSystem = _dbClient.queryObject(ProtectionSystem.class, sourceVol.getProtectionController());
                if (rpSystem == null) {
                    // Verify non-null storage device returned from the database client.
                    throw DeviceControllerExceptions.recoverpoint.failedConnectingForMonitoring(sourceVol.getProtectionController());
                }
                sourceVolumes.add(sourceVol);
            }
        }
    }
    return sourceVolumes;
}
Also used : Volume(com.emc.storageos.db.client.model.Volume) ArrayList(java.util.ArrayList) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) ProtectionSystem(com.emc.storageos.db.client.model.ProtectionSystem) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 17 with ProtectionSystem

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

the class RPDeviceController method addPostRestoreFromFullcopySteps.

/**
 * Adds the necessary RecoverPoint controller steps that need to be executed after
 * restoring a volume from full copy. The post-restore step is required if we
 * are restoring a VPLEX full copy, whoes source volume is a distributed VPLEX volume
 * or a VMAX volume
 *
 * @param workflow
 *            the Workflow being constructed
 * @param waitFor
 *            the step that the newly created steps will wait for.
 * @param storageSystemURI
 *            the URI of storage controller
 * @param fullCopies
 *            the URI of full copies to restore
 * @param taskId
 *            the top level operation's taskId
 * @return A waitFor key that can be used by subsequent controllers to wait on
 */
public String addPostRestoreFromFullcopySteps(Workflow workflow, String waitFor, URI storageSystemURI, List<URI> fullCopies, String taskId) {
    if (fullCopies != null && !fullCopies.isEmpty()) {
        List<Volume> sourceVolumes = checkIfDistributedVplexOrVmaxFullCopies(fullCopies);
        if (!sourceVolumes.isEmpty()) {
            Map<String, RecreateReplicationSetRequestParams> rsetParams = new HashMap<String, RecreateReplicationSetRequestParams>();
            List<URI> volumeURIs = new ArrayList<URI>();
            URI rpSystemId = sourceVolumes.get(0).getProtectionController();
            ProtectionSystem rpSystem = _dbClient.queryObject(ProtectionSystem.class, rpSystemId);
            for (Volume vol : sourceVolumes) {
                RecreateReplicationSetRequestParams rsetParam = getReplicationSettings(rpSystem, vol.getId());
                rsetParams.put(RPHelper.getRPWWn(vol.getId(), _dbClient), rsetParam);
                volumeURIs.add(vol.getId());
            }
            String stepId = workflow.createStepId();
            Workflow.Method recreateRSetExecuteMethod = new Workflow.Method(METHOD_RECREATE_RSET_STEP, rpSystemId, volumeURIs, rsetParams);
            waitFor = workflow.createStep(STEP_PRE_VOLUME_RESTORE, "Post volume restore from full copy, add replication set step for RP", waitFor, rpSystemId, rpSystem.getSystemType(), this.getClass(), recreateRSetExecuteMethod, rollbackMethodNullMethod(), stepId);
            _log.info("Created workflow step to recreate replication set for volumes");
        }
    }
    return waitFor;
}
Also used : HashMap(java.util.HashMap) 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) RecreateReplicationSetRequestParams(com.emc.storageos.recoverpoint.requests.RecreateReplicationSetRequestParams) Volume(com.emc.storageos.db.client.model.Volume)

Example 18 with ProtectionSystem

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

the class RPDeviceController method addRemoveProtectionOnVolumeStep.

/**
 * Step to remove protection on RP Source volumes
 *
 * @param workflow
 *            The current WF
 * @param waitFor
 *            The previous waitFor step ID or Group
 * @param volumeDescriptors
 *            RP Source volume descriptors
 * @param taskId
 *            The Task ID
 * @param blockDeviceController
 *            Reference to a BlockDeviceController, used for specific steps on
 *            the volumes not covered by RP but required for the operation to be complete.
 * @return The next waitFor step ID or Group
 */
private String addRemoveProtectionOnVolumeStep(Workflow workflow, String waitFor, List<VolumeDescriptor> volumeDescriptors, String taskId, BlockDeviceController blockDeviceController) {
    List<URI> volumeURIs = new ArrayList<URI>();
    URI newVpoolURI = null;
    // Filter to get only the RP Source volumes.
    List<VolumeDescriptor> rpSourceDescriptors = VolumeDescriptor.filterByType(volumeDescriptors, new VolumeDescriptor.Type[] { VolumeDescriptor.Type.RP_SOURCE, VolumeDescriptor.Type.RP_VPLEX_VIRT_SOURCE }, new VolumeDescriptor.Type[] {});
    for (VolumeDescriptor descriptor : rpSourceDescriptors) {
        if (descriptor.getParameters().get(VolumeDescriptor.PARAM_DO_NOT_DELETE_VOLUME) != null) {
            // This is a rollback protection operation. We do not want to delete the volume but we do
            // want to remove protection from it.
            newVpoolURI = (URI) descriptor.getParameters().get(VolumeDescriptor.PARAM_VPOOL_CHANGE_NEW_VPOOL_ID);
            _log.info(String.format("Adding step to remove protection from Volume (%s) and move it to vpool (%s)", descriptor.getVolumeURI(), newVpoolURI));
            volumeURIs.add(descriptor.getVolumeURI());
        }
    }
    if (volumeURIs.isEmpty()) {
        return waitFor;
    }
    // Filter to get only the Block Data volumes
    List<VolumeDescriptor> blockDataDescriptors = VolumeDescriptor.filterByType(volumeDescriptors, new VolumeDescriptor.Type[] { VolumeDescriptor.Type.BLOCK_DATA }, new VolumeDescriptor.Type[] {});
    // Check to see if there are any BLOCK_DATA volumes flagged to not be fully deleted.
    // These volumes could potentially need to have some untag operation performed
    // on the underlying array even though they won't be deleted.
    List<VolumeDescriptor> doNotDeleteDescriptors = VolumeDescriptor.getDoNotDeleteDescriptors(blockDataDescriptors);
    // Breakup the descriptors further into RP and RP+VPLEX descriptors
    List<VolumeDescriptor> rpDescriptors = new ArrayList<VolumeDescriptor>();
    List<VolumeDescriptor> rpVPlexDescriptors = new ArrayList<VolumeDescriptor>();
    for (VolumeDescriptor descr : doNotDeleteDescriptors) {
        Volume volume = _dbClient.queryObject(Volume.class, descr.getVolumeURI());
        // Check to see if this volume is associated to a RP+VPLEX Source volume.
        if (RPHelper.isAssociatedToRpVplexType(volume, _dbClient, PersonalityTypes.SOURCE)) {
            rpVPlexDescriptors.add(descr);
        } else {
            rpDescriptors.add(descr);
        }
    }
    if (doNotDeleteDescriptors != null && !doNotDeleteDescriptors.isEmpty()) {
        // Call the BlockDeviceController to perform untag operations on the volumes.
        // NOTE: Only needed for RP volumes.
        waitFor = blockDeviceController.addStepsForUntagVolumes(workflow, waitFor, rpDescriptors, taskId);
        // Call the BlockDeviceController to remove the volumes from any backend array CGs.
        // NOTE: Only needed for RP+VPLEX/MP volumes.
        waitFor = blockDeviceController.addStepsForUpdateConsistencyGroup(workflow, waitFor, null, rpVPlexDescriptors);
    }
    // Grab any volume from the list so we can grab the protection system. This
    // request could be over multiple protection systems but we don't really
    // care at this point. We just need this reference to pass into the
    // WorkFlow.
    Volume volume = _dbClient.queryObject(Volume.class, volumeURIs.get(0));
    ProtectionSystem rpSystem = _dbClient.queryObject(ProtectionSystem.class, volume.getProtectionController());
    String stepId = workflow.createStepId();
    Workflow.Method removeProtectionExecuteMethod = new Workflow.Method(METHOD_REMOVE_PROTECTION_STEP, volumeURIs, newVpoolURI);
    workflow.createStep(STEP_REMOVE_PROTECTION, "Remove RP protection on volume(s)", waitFor, rpSystem.getId(), rpSystem.getSystemType(), this.getClass(), removeProtectionExecuteMethod, null, stepId);
    return STEP_REMOVE_PROTECTION;
}
Also used : VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) Volume(com.emc.storageos.db.client.model.Volume) 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)

Example 19 with ProtectionSystem

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

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

the class RPDeviceController method addStepsForRestoreVolume.

@Override
public String addStepsForRestoreVolume(Workflow workflow, String waitFor, URI storage, URI pool, URI volume, URI snapshot, Boolean updateOpStatus, String syncDirection, String taskId, BlockSnapshotRestoreCompleter completer) throws InternalException {
    BlockSnapshot snap = _dbClient.queryObject(BlockSnapshot.class, snapshot);
    if (snap != null && NullColumnValueGetter.isNotNullValue(snap.getTechnologyType())) {
        Volume vol = _dbClient.queryObject(Volume.class, volume);
        if (vol != null) {
            if (snap.getTechnologyType().equals(TechnologyType.RP.toString())) {
                // Perform an RP controller restore operation only if restoring from an RP BlockSnapshot.
                ProtectionSystem rpSystem = null;
                rpSystem = _dbClient.queryObject(ProtectionSystem.class, vol.getProtectionController());
                if (rpSystem == null) {
                    // Verify non-null storage device returned from the database client.
                    throw DeviceControllerExceptions.recoverpoint.failedConnectingForMonitoring(vol.getProtectionController());
                }
                String stepId = workflow.createStepId();
                Workflow.Method restoreVolumeFromSnapshotMethod = new Workflow.Method(METHOD_RESTORE_VOLUME_STEP, rpSystem.getId(), storage, snapshot, completer);
                waitFor = workflow.createStep(null, "Restore volume from RP snapshot: " + volume.toString(), waitFor, rpSystem.getId(), rpSystem.getSystemType(), this.getClass(), restoreVolumeFromSnapshotMethod, rollbackMethodNullMethod(), stepId);
                _log.info(String.format("Created workflow step to restore RP volume %s from snapshot %s.", volume, snapshot));
            }
        }
    }
    return waitFor;
}
Also used : Volume(com.emc.storageos.db.client.model.Volume) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) Workflow(com.emc.storageos.workflow.Workflow) ProtectionSystem(com.emc.storageos.db.client.model.ProtectionSystem)

Aggregations

ProtectionSystem (com.emc.storageos.db.client.model.ProtectionSystem)120 URI (java.net.URI)57 ArrayList (java.util.ArrayList)52 NamedURI (com.emc.storageos.db.client.model.NamedURI)44 Volume (com.emc.storageos.db.client.model.Volume)44 HashMap (java.util.HashMap)32 StringSet (com.emc.storageos.db.client.model.StringSet)30 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)28 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)25 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)25 ControllerException (com.emc.storageos.volumecontroller.ControllerException)25 RPProtectionRecommendation (com.emc.storageos.volumecontroller.RPProtectionRecommendation)25 URISyntaxException (java.net.URISyntaxException)25 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)24 RecoverPointException (com.emc.storageos.recoverpoint.exceptions.RecoverPointException)24 InternalServerErrorException (com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException)24 WorkflowException (com.emc.storageos.workflow.WorkflowException)24 Test (org.junit.Test)24 FunctionalAPIActionFailedException_Exception (com.emc.fapiclient.ws.FunctionalAPIActionFailedException_Exception)23 FunctionalAPIInternalError_Exception (com.emc.fapiclient.ws.FunctionalAPIInternalError_Exception)23