Search in sources :

Example 11 with Volume

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

the class RPDeviceController method updateConsistencyGroupPolicy.

@Override
public void updateConsistencyGroupPolicy(URI protectionDevice, URI consistencyGroup, List<URI> volumeURIs, URI newVpoolURI, String task) throws InternalException {
    _log.info(String.format("Request to update consistency group policy for volumes %s through virtual pool change to %s", volumeURIs, newVpoolURI));
    VolumeVpoolChangeTaskCompleter taskCompleter = null;
    URI oldVpoolURI = null;
    List<Volume> volumes = new ArrayList<Volume>();
    List<Volume> vplexBackendVolumes = new ArrayList<Volume>();
    try {
        // Get all CG source volumes. The entire CG policy is being updated so we
        // need to capture the existing vpools for all the source volumes before
        // changing them.
        List<Volume> cgVolumes = RPHelper.getCgSourceVolumes(consistencyGroup, _dbClient);
        VirtualPool newVpool = _dbClient.queryObject(VirtualPool.class, newVpoolURI);
        Map<URI, URI> oldVpools = new HashMap<URI, URI>();
        for (Volume volume : cgVolumes) {
            // Save the old virtual pool
            oldVpoolURI = volume.getVirtualPool();
            oldVpools.put(volume.getId(), oldVpoolURI);
            // Update to the new virtual pool
            volume.setVirtualPool(newVpoolURI);
            volumes.add(volume);
            // If this is a VPlex volume, there will be
            StringSet associatedVolumeIds = volume.getAssociatedVolumes();
            // Perform additional tasks if this volume is a VPlex volume
            if (associatedVolumeIds != null && !associatedVolumeIds.isEmpty()) {
                Volume backendSrc = null;
                Volume backendHa = null;
                for (String associatedVolumeId : associatedVolumeIds) {
                    Volume associatedVolume = _dbClient.queryObject(Volume.class, URI.create(associatedVolumeId));
                    // Assign the associated volumes to either be the source or HA
                    if (associatedVolume != null) {
                        if (associatedVolume.getVirtualArray().equals(volume.getVirtualArray())) {
                            backendSrc = associatedVolume;
                        } else {
                            backendHa = associatedVolume;
                        }
                    }
                }
                if (backendSrc != null) {
                    // Change the back end volume's vPool too
                    backendSrc.setVirtualPool(newVpoolURI);
                    vplexBackendVolumes.add(backendSrc);
                    _log.info(String.format("Changing VirtualPool for VPLEX backend source volume %s (%s) from %s to %s", backendSrc.getLabel(), backendSrc.getId(), oldVpoolURI, newVpoolURI));
                    if (backendHa != null) {
                        VirtualPool newHAVpool = VirtualPool.getHAVPool(newVpool, _dbClient);
                        if (newHAVpool == null) {
                            // it may not be set
                            newHAVpool = newVpool;
                        }
                        backendHa.setVirtualPool(newHAVpool.getId());
                        vplexBackendVolumes.add(backendHa);
                    }
                }
            }
        }
        _dbClient.updateObject(volumes);
        _dbClient.updateObject(vplexBackendVolumes);
        // The VolumeVpoolChangeTaskCompleter will restore the old Virtual Pool
        taskCompleter = new VolumeVpoolChangeTaskCompleter(volumeURIs, oldVpools, task);
    } catch (Exception ex) {
        _log.error("Unexpected exception reading volume or generating taskCompleter: ", ex);
        ServiceError serviceError = DeviceControllerException.errors.jobFailed(ex);
        VolumeWorkflowCompleter completer = new VolumeWorkflowCompleter(volumeURIs, task);
        completer.error(_dbClient, serviceError);
    }
    try {
        Workflow workflow = _workflowService.getNewWorkflow(this, "updateReplicationMode", false, task);
        ProtectionSystem protectionSystem = _dbClient.queryObject(ProtectionSystem.class, protectionDevice);
        if (!volumes.isEmpty()) {
            VirtualPool newVirtualPool = _dbClient.queryObject(VirtualPool.class, newVpoolURI);
            // Add workflow step
            addUpdateConsistencyGroupPolicyStep(workflow, protectionSystem, consistencyGroup, newVirtualPool.getRpCopyMode());
        }
        if (!workflow.getAllStepStatus().isEmpty()) {
            _log.info("The updateAutoTieringPolicy workflow has {} step(s). Starting the workflow.", workflow.getAllStepStatus().size());
            workflow.executePlan(taskCompleter, "Updated the consistency group policy successfully.");
        } else {
            taskCompleter.ready(_dbClient);
        }
    } catch (Exception ex) {
        _log.error("Unexpected exception: ", ex);
        ServiceError serviceError = DeviceControllerException.errors.jobFailed(ex);
        taskCompleter.error(_dbClient, serviceError);
    }
}
Also used : ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) HashMap(java.util.HashMap) VolumeWorkflowCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.VolumeWorkflowCompleter) ArrayList(java.util.ArrayList) Workflow(com.emc.storageos.workflow.Workflow) VirtualPool(com.emc.storageos.db.client.model.VirtualPool) 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) VolumeVpoolChangeTaskCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.VolumeVpoolChangeTaskCompleter) Volume(com.emc.storageos.db.client.model.Volume) StringSet(com.emc.storageos.db.client.model.StringSet)

Example 12 with Volume

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

the class RPDeviceController method addPreRestoreVolumeSteps.

/**
 * Adds the necessary RecoverPoint controller steps that need to be executed prior
 * to restoring a volume from snapshot. The pre-restore step is required if we
 * are restoring a native array snapshot of the following parent volumes:
 * <ul>
 * <li>A BlockSnapshot parent volume that is a regular RP source/target residing on a VMAX.</li>
 * <li>A BlockSnapshot parent volume that is a backing volume to a VPlex distributed volume.</li>
 * </ul>
 *
 * @param workflow
 *            the Workflow being constructed
 * @param storageSystemURI
 *            the URI of storage controller
 * @param volumeURI
 *            the URI of volume to be restored
 * @param snapshotURI
 *            the URI of snapshot used for restoration
 * @param taskId
 *            the top level operation's taskId
 * @return A waitFor key that can be used by subsequent controllers to wait on
 */
public String addPreRestoreVolumeSteps(Workflow workflow, URI storageSystemURI, URI volumeURI, URI snapshotURI, String taskId) {
    String waitFor = null;
    BlockSnapshot snapshot = _dbClient.queryObject(BlockSnapshot.class, snapshotURI);
    // Only consider native snapshots
    if (snapshot != null && NullColumnValueGetter.isNotNullValue(snapshot.getTechnologyType()) && snapshot.getTechnologyType().equals(TechnologyType.NATIVE.toString())) {
        Volume volume = _dbClient.queryObject(Volume.class, volumeURI);
        StorageSystem storageSystem = _dbClient.queryObject(StorageSystem.class, storageSystemURI);
        if (volume != null && storageSystem != null) {
            boolean vplexDistBackingVolume = false;
            URI cgId = volume.getConsistencyGroup();
            Volume associatedVPlexVolume = Volume.fetchVplexVolume(_dbClient, volume);
            if (associatedVPlexVolume != null && associatedVPlexVolume.getAssociatedVolumes() != null && associatedVPlexVolume.getAssociatedVolumes().size() == 2) {
                vplexDistBackingVolume = true;
            }
            if (vplexDistBackingVolume) {
                volume = associatedVPlexVolume;
            }
            // before performing the native block restore.
            if (!NullColumnValueGetter.isNullURI(volume.getProtectionController()) && (vplexDistBackingVolume || (storageSystem != null && NullColumnValueGetter.isNotNullValue(storageSystem.getSystemType()) && storageSystem.getSystemType().equals(SystemType.vmax.toString())))) {
                ProtectionSystem rpSystem = null;
                rpSystem = _dbClient.queryObject(ProtectionSystem.class, volume.getProtectionController());
                if (rpSystem == null) {
                    // Verify non-null storage device returned from the database client.
                    throw DeviceControllerExceptions.recoverpoint.failedConnectingForMonitoring(volume.getProtectionController());
                }
                List<URI> volumeURIs = getVolumesForRestore(snapshot, volume);
                // Validate the replication sets for all volumes to restore. Must ensure the source
                // volume size is not greater than the target volume size
                List<Volume> volumes = _dbClient.queryObject(Volume.class, volumeURIs);
                RPHelper.validateRSetVolumeSizes(_dbClient, volumes);
                Map<String, RecreateReplicationSetRequestParams> rsetParams = new HashMap<String, RecreateReplicationSetRequestParams>();
                // Lock CG
                List<String> locks = new ArrayList<String>();
                String lockName = ControllerLockingUtil.getConsistencyGroupStorageKey(_dbClient, cgId, rpSystem.getId());
                if (null != lockName) {
                    locks.add(lockName);
                    acquireWorkflowLockOrThrow(workflow, locks);
                }
                for (URI volumeId : volumeURIs) {
                    Volume vol = _dbClient.queryObject(Volume.class, volumeId);
                    RecreateReplicationSetRequestParams rsetParam = getReplicationSettings(rpSystem, vol.getId());
                    rsetParams.put(RPHelper.getRPWWn(vol.getId(), _dbClient), rsetParam);
                }
                String stepId = workflow.createStepId();
                Workflow.Method deleteRsetExecuteMethod = new Workflow.Method(METHOD_DELETE_RSET_STEP, rpSystem.getId(), volumeURIs);
                Workflow.Method recreateRSetExecuteMethod = new Workflow.Method(METHOD_RECREATE_RSET_STEP, rpSystem.getId(), volumeURIs, rsetParams);
                waitFor = workflow.createStep(STEP_PRE_VOLUME_RESTORE, "Pre volume restore from snapshot, delete replication set step for RP: " + volumeURI.toString(), null, rpSystem.getId(), rpSystem.getSystemType(), this.getClass(), deleteRsetExecuteMethod, recreateRSetExecuteMethod, stepId);
                _log.info(String.format("Created workflow step to delete replication set for volume %s.", volume.getId().toString()));
            }
        }
    }
    return waitFor;
}
Also used : HashMap(java.util.HashMap) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) 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) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 13 with Volume

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

the class RPDeviceController method addPostVolumeExpandSteps.

/**
 * RP specific workflow steps after volume expansion are added here in this method
 * RP CG replication sets that were removed during pre expand are reconstructed with the new expanded volumes.
 *
 * @param workflow
 * @param waitFor
 * @param volume
 *            descriptors
 * @param taskId
 * @return
 * @throws WorkflowException
 */
public String addPostVolumeExpandSteps(Workflow workflow, String waitFor, List<VolumeDescriptor> volumeDescriptors, String taskId) throws WorkflowException {
    // Get only the RP volumes from the descriptors.
    List<VolumeDescriptor> volumeDescriptorsTypeFilter = VolumeDescriptor.filterByType(volumeDescriptors, new VolumeDescriptor.Type[] { VolumeDescriptor.Type.RP_SOURCE, VolumeDescriptor.Type.RP_EXISTING_SOURCE, VolumeDescriptor.Type.RP_VPLEX_VIRT_SOURCE }, new VolumeDescriptor.Type[] {});
    // If there are no RP volumes, just return
    if (volumeDescriptorsTypeFilter.isEmpty()) {
        return waitFor;
    }
    for (VolumeDescriptor descriptor : volumeDescriptorsTypeFilter) {
        Volume volume = _dbClient.queryObject(Volume.class, descriptor.getVolumeURI());
        ProtectionSystem rpSystem = _dbClient.queryObject(ProtectionSystem.class, volume.getProtectionController());
        Map<String, RecreateReplicationSetRequestParams> rsetParams = new HashMap<String, RecreateReplicationSetRequestParams>();
        RecreateReplicationSetRequestParams rsetParam = getReplicationSettings(rpSystem, volume.getId());
        rsetParams.put(RPHelper.getRPWWn(volume.getId(), _dbClient), rsetParam);
        String stepId = workflow.createStepId();
        Workflow.Method recreateRSetExecuteMethod = new Workflow.Method(METHOD_RECREATE_RSET_STEP, rpSystem.getId(), Arrays.asList(volume.getId()), rsetParams);
        workflow.createStep(STEP_POST_VOLUME_EXPAND, "Post volume Expand, Recreate replication set subtask for RP: " + volume.toString(), waitFor, rpSystem.getId(), rpSystem.getSystemType(), this.getClass(), recreateRSetExecuteMethod, null, stepId);
        _log.info("Recreate Replication Set in workflow");
    }
    return STEP_POST_VOLUME_EXPAND;
}
Also used : VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) Volume(com.emc.storageos.db.client.model.Volume) HashMap(java.util.HashMap) Workflow(com.emc.storageos.workflow.Workflow) ProtectionSystem(com.emc.storageos.db.client.model.ProtectionSystem) RecreateReplicationSetRequestParams(com.emc.storageos.recoverpoint.requests.RecreateReplicationSetRequestParams)

Example 14 with Volume

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

use of com.emc.storageos.db.client.model.Volume 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)

Aggregations

Volume (com.emc.storageos.db.client.model.Volume)1303 URI (java.net.URI)775 ArrayList (java.util.ArrayList)522 NamedURI (com.emc.storageos.db.client.model.NamedURI)412 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)319 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)291 BlockSnapshot (com.emc.storageos.db.client.model.BlockSnapshot)221 StringSet (com.emc.storageos.db.client.model.StringSet)208 HashMap (java.util.HashMap)203 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)202 ServiceError (com.emc.storageos.svcs.errorhandling.model.ServiceError)197 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)160 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)152 BlockObject (com.emc.storageos.db.client.model.BlockObject)150 ControllerException (com.emc.storageos.volumecontroller.ControllerException)143 BlockConsistencyGroup (com.emc.storageos.db.client.model.BlockConsistencyGroup)139 WorkflowException (com.emc.storageos.workflow.WorkflowException)126 HashSet (java.util.HashSet)126 CIMObjectPath (javax.cim.CIMObjectPath)107 VirtualPool (com.emc.storageos.db.client.model.VirtualPool)104