Search in sources :

Example 6 with RecoverPointClient

use of com.emc.storageos.recoverpoint.impl.RecoverPointClient in project coprhd-controller by CoprHD.

the class RPDeviceController method constructSnapshotObjectFromBookmark.

/**
 * Amend the BlockSnapshot object based on the results of the Bookmark creation operation
 *
 * @param result
 *            result from the snapshot creation command
 * @param system
 *            protection system
 * @param snapshotList
 *            snapshot list generated
 * @param name
 *            emName
 * @param opId
 *            operation ID for task completer
 * @throws InternalException
 * @throws FunctionalAPIInternalError_Exception
 * @throws FunctionalAPIActionFailedException_Exception
 */
private void constructSnapshotObjectFromBookmark(CreateBookmarkResponse response, ProtectionSystem system, List<URI> snapshotList, String name, String opId) throws InternalException {
    ProtectionSet protectionSet = null;
    RecoverPointClient rp = RPHelper.getRecoverPointClient(system);
    // Update each snapshot object with the respective information.
    for (URI snapshotID : snapshotList) {
        // Get the snapshot and the associated volume
        BlockSnapshot snapshot = _dbClient.queryObject(BlockSnapshot.class, snapshotID);
        Volume volume = _dbClient.queryObject(Volume.class, snapshot.getParent().getURI());
        // Fetch the VPLEX volume that is created with this volume as the back-end volume.
        if (Volume.checkForVplexBackEndVolume(_dbClient, volume)) {
            volume = Volume.fetchVplexVolume(_dbClient, volume);
        }
        if (protectionSet == null || !protectionSet.getId().equals(volume.getProtectionSet().getURI())) {
            protectionSet = _dbClient.queryObject(ProtectionSet.class, volume.getProtectionSet());
        }
        // Gather the bookmark date, which is different than the snapshot date
        Date bookmarkDate = new Date();
        if (response.getVolumeWWNBookmarkDateMap() != null) {
            bookmarkDate = response.getVolumeWWNBookmarkDateMap().get(RPHelper.getRPWWn(volume.getId(), _dbClient));
        } else {
            _log.warn("Bookmark date was not filled-in.  Will use current date/time.");
        }
        snapshot.setEmName(name);
        snapshot.setInactive(false);
        snapshot.setEmBookmarkTime("" + bookmarkDate.getTime());
        snapshot.setCreationTime(Calendar.getInstance());
        snapshot.setTechnologyType(TechnologyType.RP.toString());
        Volume targetVolume = RPHelper.getRPTargetVolumeFromSource(_dbClient, volume, snapshot.getVirtualArray());
        // This section will identify and store the COPY ID associated with the bookmarks created.
        // It is critical to store this information so we can later determine which bookmarks have
        // been deleted from the RPA.
        // 
        // May be able to remove this if the protection set object is more detailed (for instance, if
        // we store the copy id with the volume)
        RecoverPointVolumeProtectionInfo protectionInfo = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(targetVolume.getId(), _dbClient));
        for (RPConsistencyGroup rpcg : response.getCgBookmarkMap().keySet()) {
            if (rpcg.getCGUID().getId() == protectionInfo.getRpVolumeGroupID()) {
                for (RPBookmark bookmark : response.getCgBookmarkMap().get(rpcg)) {
                    if (bookmark.getBookmarkName() != null && bookmark.getBookmarkName().equalsIgnoreCase(name) && bookmark.getCGGroupCopyUID().getGlobalCopyUID().getCopyUID() == protectionInfo.getRpVolumeGroupCopyID()) {
                        snapshot.setEmCGGroupCopyId(protectionInfo.getRpVolumeGroupCopyID());
                        break;
                    }
                }
            }
        }
        if (targetVolume.getId().equals(volume.getId())) {
            _log.error("The source and the target volumes are the same");
            throw DeviceControllerExceptions.recoverpoint.cannotActivateSnapshotNoTargetVolume();
        }
        snapshot.setDeviceLabel(targetVolume.getDeviceLabel());
        snapshot.setStorageController(targetVolume.getStorageController());
        snapshot.setSystemType(targetVolume.getSystemType());
        snapshot.setVirtualArray(targetVolume.getVirtualArray());
        snapshot.setNativeId(targetVolume.getNativeId());
        snapshot.setAlternateName(targetVolume.getAlternateName());
        snapshot.setNativeGuid(NativeGUIDGenerator.generateNativeGuid(system, snapshot));
        snapshot.setIsSyncActive(false);
        // Setting the WWN of the bookmark to the WWN of the volume, no functional reason for now.
        snapshot.setWWN(RPHelper.getRPWWn(targetVolume.getId(), _dbClient));
        snapshot.setProtectionController(system.getId());
        snapshot.setProtectionSet(volume.getProtectionSet().getURI());
        _log.info(String.format("Updated bookmark %1$s associated with block volume %2$s on site %3$s.", name, volume.getDeviceLabel(), snapshot.getEmInternalSiteName()));
        _dbClient.updateObject(snapshot);
        List<URI> taskSnapshotURIList = new ArrayList<URI>();
        taskSnapshotURIList.add(snapshot.getId());
        TaskCompleter completer = new BlockSnapshotCreateCompleter(taskSnapshotURIList, opId);
        completer.ready(_dbClient);
    }
    // Get information about the bookmarks created so we can get to them later.
    _log.info("Bookmark(s) created for snapshot operation");
    return;
}
Also used : ProtectionSet(com.emc.storageos.db.client.model.ProtectionSet) BlockSnapshot(com.emc.storageos.db.client.model.BlockSnapshot) ArrayList(java.util.ArrayList) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) BlockSnapshotCreateCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.BlockSnapshotCreateCompleter) Date(java.util.Date) RPConsistencyGroup(com.emc.storageos.recoverpoint.objectmodel.RPConsistencyGroup) RecoverPointVolumeProtectionInfo(com.emc.storageos.recoverpoint.responses.RecoverPointVolumeProtectionInfo) Volume(com.emc.storageos.db.client.model.Volume) RecoverPointClient(com.emc.storageos.recoverpoint.impl.RecoverPointClient) 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) RPBookmark(com.emc.storageos.recoverpoint.objectmodel.RPBookmark)

Example 7 with RecoverPointClient

use of com.emc.storageos.recoverpoint.impl.RecoverPointClient in project coprhd-controller by CoprHD.

the class RPDeviceController method enableImageAccessForCreateReplicaStep.

/**
 * Enable image access before create native array replica operation
 *
 * @param protectionDevice
 * @param clazz
 *            type of replica (such as Volume, BlockSnapshot or BlockSnapshotSession)
 * @param copyList
 *            list of replica ids
 * @param bookmarkName
 *            name of the bookmark created for this operation
 * @param volumeWWNs
 *            wwns of volumes that are parents to replica objects
 * @param opId
 * @return
 * @throws ControllerException
 */
public boolean enableImageAccessForCreateReplicaStep(URI protectionDevice, Class<? extends DataObject> clazz, List<URI> copyList, String bookmarkName, Set<String> volumeWWNs, String opId) throws ControllerException {
    TaskCompleter completer = null;
    try {
        WorkflowStepCompleter.stepExecuting(opId);
        _log.info(String.format("Activating bookmark %s on the RP CG(s)", bookmarkName));
        completer = new RPCGCopyVolumeCompleter(clazz, copyList, opId);
        // Verify non-null storage device returned from the database client.
        ProtectionSystem system = _dbClient.queryObject(ProtectionSystem.class, protectionDevice);
        if (system == null || system.getInactive()) {
            throw DeviceControllerExceptions.recoverpoint.databaseExceptionActivateSnapshot(protectionDevice);
        }
        // enable image access to that bookmark
        RecoverPointClient rp = RPHelper.getRecoverPointClient(system);
        MultiCopyEnableImageRequestParams request = new MultiCopyEnableImageRequestParams();
        request.setVolumeWWNSet(volumeWWNs);
        request.setBookmark(bookmarkName);
        MultiCopyEnableImageResponse response = rp.enableImageCopies(request);
        if (response == null) {
            throw DeviceControllerExceptions.recoverpoint.failedEnableAccessOnRP();
        }
        completer.ready(_dbClient);
        // Update the workflow state.
        WorkflowStepCompleter.stepSucceded(opId);
        return true;
    } catch (InternalException e) {
        _log.error("Operation failed with Exception: ", e);
        if (completer != null) {
            completer.error(_dbClient, e);
        }
        stepFailed(opId, "enableImageAccessStep: Failed to enable image");
        return false;
    } catch (Exception e) {
        _log.error("Operation failed with Exception: ", e);
        if (completer != null) {
            completer.error(_dbClient, DeviceControllerException.errors.jobFailed(e));
        }
        stepFailed(opId, "enableImageAccessStep: Failed to enable image");
        return false;
    }
}
Also used : RPCGCopyVolumeCompleter(com.emc.storageos.volumecontroller.impl.block.taskcompleter.RPCGCopyVolumeCompleter) MultiCopyEnableImageResponse(com.emc.storageos.recoverpoint.responses.MultiCopyEnableImageResponse) RecoverPointClient(com.emc.storageos.recoverpoint.impl.RecoverPointClient) 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) ProtectionSystem(com.emc.storageos.db.client.model.ProtectionSystem) MultiCopyEnableImageRequestParams(com.emc.storageos.recoverpoint.requests.MultiCopyEnableImageRequestParams) 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) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException)

Example 8 with RecoverPointClient

use of com.emc.storageos.recoverpoint.impl.RecoverPointClient in project coprhd-controller by CoprHD.

the class RPDeviceController method performProtectionOperationStep.

/**
 * Workflow step to perform RP protection operation
 *
 * @param protectionSystem
 * @param cgId
 * @param volId
 * @param copyID
 * @param pointInTime
 * @param imageAccessMode
 * @param op
 * @param stepId
 * @return
 * @throws ControllerException
 */
public boolean performProtectionOperationStep(URI protectionSystem, URI cgId, URI volId, URI copyID, String pointInTime, String imageAccessMode, String op, String stepId) throws ControllerException {
    WorkflowStepCompleter.stepExecuting(stepId);
    try {
        ProtectionSystem rpSystem = getRPSystem(protectionSystem);
        // Take out a workflow step lock on the CG
        _workflowService.getWorkflowFromStepId(stepId);
        List<String> lockKeys = new ArrayList<String>();
        lockKeys.add(ControllerLockingUtil.getConsistencyGroupStorageKey(_dbClient, cgId, rpSystem.getId()));
        boolean lockAcquired = _workflowService.acquireWorkflowStepLocks(stepId, lockKeys, LockTimeoutValue.get(LockType.RP_CG));
        if (!lockAcquired) {
            throw DeviceControllerException.exceptions.failedToAcquireLock(lockKeys.toString(), String.format("failed to get lock while restoring volumes in RP consistency group: %s", cgId.toString()));
        }
        // set the protection volume to the source volume if the copyID is null (operation is performed on all
        // copies)
        // otherwise set it to the volume referenced by the copyID (operation is performed on specifc copy)
        Volume protectionVolume = (copyID == null) ? _dbClient.queryObject(Volume.class, volId) : _dbClient.queryObject(Volume.class, copyID);
        RecoverPointClient rp = RPHelper.getRecoverPointClient(rpSystem);
        RecoverPointVolumeProtectionInfo volumeProtectionInfo = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(protectionVolume.getId(), _dbClient));
        if (op.equals(STOP)) {
            rp.disableProtection(volumeProtectionInfo);
            setProtectionSetStatus(volumeProtectionInfo, ProtectionStatus.DISABLED.toString(), rpSystem);
            _log.info("doStopProtection {} - complete", rpSystem.getId());
        } else if (op.equals(START)) {
            rp.enableProtection(volumeProtectionInfo);
            setProtectionSetStatus(volumeProtectionInfo, ProtectionStatus.ENABLED.toString(), rpSystem);
        } else if (op.equals(SYNC)) {
            Set<String> volumeWWNs = new HashSet<String>();
            volumeWWNs.add(RPHelper.getRPWWn(protectionVolume.getId(), _dbClient));
            // Create and enable a temporary bookmark for the volume associated with this volume
            CreateBookmarkRequestParams request = new CreateBookmarkRequestParams();
            request.setVolumeWWNSet(volumeWWNs);
            request.setBookmark("Sync-Snapshot");
            rp.createBookmarks(request);
        } else if (op.equals(PAUSE)) {
            rp.pauseTransfer(volumeProtectionInfo);
            setProtectionSetStatus(volumeProtectionInfo, ProtectionStatus.PAUSED.toString(), rpSystem);
        } else if (op.equals(RESUME)) {
            rp.resumeTransfer(volumeProtectionInfo);
            setProtectionSetStatus(volumeProtectionInfo, ProtectionStatus.ENABLED.toString(), rpSystem);
        } else if (op.equals(FAILOVER_TEST)) {
            RPCopyRequestParams copyParams = new RPCopyRequestParams();
            copyParams.setCopyVolumeInfo(volumeProtectionInfo);
            rp.failoverCopyTest(copyParams);
        } else if (op.equals(FAILOVER)) {
            // cancel.
            if (protectionVolume.getLinkStatus() != null && protectionVolume.getLinkStatus().equalsIgnoreCase(Volume.LinkStatus.FAILED_OVER.name())) {
                // TODO: ViPR 2.0 needs to support this.
                // TODO BEGIN: allow re-failover perform the same as a failback in 2.0 since the UI support will not
                // be there to do a
                // swap or cancel.
                // Jira CTRL-2773: Once UI adds support for /swap and /failover-cancel, we can remove this and
                // replace with an error.
                // If protectionVolume is a source, then the "source" sent in must be a target. Verify.
                Volume targetVolume = null;
                if (protectionVolume.checkPersonality(Volume.PersonalityTypes.SOURCE.toString())) {
                    targetVolume = _dbClient.queryObject(Volume.class, volId);
                } else {
                    targetVolume = protectionVolume;
                }
                // Disable the image access that is in effect.
                volumeProtectionInfo = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(targetVolume.getId(), _dbClient));
                RPCopyRequestParams copyParams = new RPCopyRequestParams();
                copyParams.setCopyVolumeInfo(volumeProtectionInfo);
                rp.failoverCopyCancel(copyParams);
                // Set the flags back to where they belong.
                updatePostFailoverCancel(targetVolume);
            // TODO END
            // Replace with this error: taskCompleter.error(_dbClient, _locker,
            // DeviceControllerErrors.recoverpoint.stepFailed("performFailoverOperation: source volume specified
            // for failover where target volume specified is not in failover state"));
            } else {
                // Standard failover case.
                RPCopyRequestParams copyParams = new RPCopyRequestParams();
                copyParams.setCopyVolumeInfo(volumeProtectionInfo);
                if (pointInTime != null) {
                    // Build a Date reference.
                    copyParams.setApitTime(TimeUtils.getDateTimestamp(pointInTime));
                }
                rp.failoverCopy(copyParams);
                updatePostFailover(protectionVolume);
            }
        } else if (op.equals(FAILOVER_CANCEL)) {
            // cancel.
            if (protectionVolume.checkPersonality(Volume.PersonalityTypes.SOURCE.name())) {
                throw DeviceControllerExceptions.recoverpoint.failoverWrongTargetSpecified();
            } else {
                if (protectionVolume.getLinkStatus() != null && protectionVolume.getLinkStatus().equalsIgnoreCase(Volume.LinkStatus.FAILED_OVER.name())) {
                    // Disable the image access that is in effect.
                    volumeProtectionInfo = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(protectionVolume.getId(), _dbClient));
                    RPCopyRequestParams copyParams = new RPCopyRequestParams();
                    copyParams.setCopyVolumeInfo(volumeProtectionInfo);
                    rp.failoverCopyCancel(copyParams);
                    // Set the flags back to where they belong.
                    updatePostFailoverCancel(protectionVolume);
                } else {
                    // failed over target.
                    throw DeviceControllerExceptions.recoverpoint.failoverWrongTargetSpecified();
                }
            }
        } else if (op.equals(SWAP)) {
            RPCopyRequestParams copyParams = new RPCopyRequestParams();
            copyParams.setCopyVolumeInfo(volumeProtectionInfo);
            rp.swapCopy(copyParams);
            protectionVolume = updatePostSwapPersonalities(protectionVolume);
            rp.setCopyAsProduction(copyParams);
            // 3. add back the standby CDP copy
            if (RPHelper.isMetroPointVolume(_dbClient, protectionVolume)) {
                // copy exists, we can skip all the CG reconstruction steps.
                if (!rp.doesStandbyProdCopyExist(volumeProtectionInfo)) {
                    _log.info(String.format("Adding back standby production copy after swap back to original VPlex Metro for Metropoint volume %s (%s)", protectionVolume.getLabel(), protectionVolume.getId().toString()));
                    List<Volume> standbyLocalCopyVols = RPHelper.getMetropointStandbyCopies(protectionVolume, _dbClient);
                    CreateCopyParams standbyLocalCopyParams = null;
                    List<CreateRSetParams> rSets = new ArrayList<CreateRSetParams>();
                    Set<URI> journalVolumes = new HashSet<URI>();
                    if (!standbyLocalCopyVols.isEmpty()) {
                        for (Volume standbyCopyVol : standbyLocalCopyVols) {
                            // 1. delete the standby CDP copy if it exists
                            if (rp.doesProtectionVolumeExist(RPHelper.getRPWWn(standbyCopyVol.getId(), _dbClient))) {
                                RecoverPointVolumeProtectionInfo standbyCdpCopy = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(standbyCopyVol.getId(), _dbClient));
                                rp.deleteCopy(standbyCdpCopy);
                            }
                            // set up volume info for the standby copy volume
                            CreateVolumeParams vol = new CreateVolumeParams();
                            vol.setWwn(RPHelper.getRPWWn(standbyCopyVol.getId(), _dbClient));
                            vol.setInternalSiteName(standbyCopyVol.getInternalSiteName());
                            vol.setProduction(false);
                            List<CreateVolumeParams> volumes = new ArrayList<CreateVolumeParams>();
                            volumes.add(vol);
                            CreateRSetParams rSet = new CreateRSetParams();
                            rSet.setName(standbyCopyVol.getRSetName());
                            rSet.setVolumes(volumes);
                            rSets.add(rSet);
                            List<Volume> standbyJournals = RPHelper.findExistingJournalsForCopy(_dbClient, standbyCopyVol.getConsistencyGroup(), standbyCopyVol.getRpCopyName());
                            // compile a unique set of journal volumes
                            for (Volume standbyJournal : standbyJournals) {
                                journalVolumes.add(standbyJournal.getId());
                            }
                        }
                        // prepare journal volumes info
                        String rpCopyName = null;
                        List<CreateVolumeParams> journalVols = new ArrayList<CreateVolumeParams>();
                        for (URI journalVolId : journalVolumes) {
                            Volume standbyLocalJournal = _dbClient.queryObject(Volume.class, journalVolId);
                            if (standbyLocalJournal != null) {
                                _log.info(String.format("Found standby local journal volume %s (%s) for metropoint volume %s (%s)", standbyLocalJournal.getLabel(), standbyLocalJournal.getId().toString(), protectionVolume.getLabel(), protectionVolume.getId().toString()));
                                rpCopyName = standbyLocalJournal.getRpCopyName();
                                CreateVolumeParams journalVolParams = new CreateVolumeParams();
                                journalVolParams.setWwn(RPHelper.getRPWWn(standbyLocalJournal.getId(), _dbClient));
                                journalVolParams.setInternalSiteName(standbyLocalJournal.getInternalSiteName());
                                journalVols.add(journalVolParams);
                            }
                        }
                        // if we found any journal volumes, add them to the local copies list
                        if (!journalVols.isEmpty()) {
                            standbyLocalCopyParams = new CreateCopyParams();
                            standbyLocalCopyParams.setName(rpCopyName);
                            standbyLocalCopyParams.setJournals(journalVols);
                        } else {
                            _log.error("no journal volumes found for standby production copy for source volume " + protectionVolume.getLabel());
                        }
                    }
                    String standbyProductionCopyName = RPHelper.getStandbyProductionCopyName(_dbClient, protectionVolume);
                    // Build standby production journal
                    if (standbyProductionCopyName != null) {
                        List<Volume> existingStandbyJournals = RPHelper.findExistingJournalsForCopy(_dbClient, protectionVolume.getConsistencyGroup(), standbyProductionCopyName);
                        // Get the first standby production journal
                        Volume standbyProdJournal = existingStandbyJournals.get(0);
                        if (standbyProdJournal != null) {
                            _log.info(String.format("Found standby production journal volume %s (%s) for metropoint volume %s (%s)", standbyProdJournal.getLabel(), standbyProdJournal.getId().toString(), protectionVolume.getLabel(), protectionVolume.getId().toString()));
                            List<CreateVolumeParams> journalVols = new ArrayList<CreateVolumeParams>();
                            CreateVolumeParams journalVolParams = new CreateVolumeParams();
                            journalVolParams.setWwn(RPHelper.getRPWWn(standbyProdJournal.getId(), _dbClient));
                            journalVolParams.setInternalSiteName(standbyProdJournal.getInternalSiteName());
                            journalVols.add(journalVolParams);
                            CreateCopyParams standbyProdCopyParams = new CreateCopyParams();
                            standbyProdCopyParams.setName(standbyProdJournal.getRpCopyName());
                            standbyProdCopyParams.setJournals(journalVols);
                            // 2. and 3. add back the standby production copy; add back the standby CDP copy
                            rp.addStandbyProductionCopy(standbyProdCopyParams, standbyLocalCopyParams, rSets, copyParams);
                        } else {
                            _log.error(String.format("Cannot add standby production copy because the standby production journal could not be found for copy %s.", standbyProductionCopyName));
                        }
                    }
                }
            }
            // copy bookmarks before we cleanup the corresponding BlockSnapshot objects from ViPR.
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            // When we perform a swap, the target swap copy will become the production copy and lose all
            // its bookmarks so we need to sync with RP.
            RPHelper.cleanupSnapshots(_dbClient, rpSystem);
        } else if (op.equals(FAILOVER_TEST_CANCEL)) {
            RPCopyRequestParams copyParams = new RPCopyRequestParams();
            copyParams.setCopyVolumeInfo(volumeProtectionInfo);
            rp.failoverCopyTestCancel(copyParams);
        } else if (op.equals(CHANGE_ACCESS_MODE)) {
            RPCopyRequestParams copyParams = new RPCopyRequestParams();
            copyParams.setCopyVolumeInfo(volumeProtectionInfo);
            copyParams.setImageAccessMode(imageAccessMode);
            if (imageAccessMode != null) {
                rp.updateImageAccessMode(copyParams);
                // BlockSnapshot objects that reference the target copy being set to direct access mode.
                if (Copy.ImageAccessMode.DIRECT_ACCESS.name().equalsIgnoreCase(imageAccessMode)) {
                    _log.info(String.format("Updated imaged access mode for copy %s at %s to DIRECT_ACCESS. Removing all bookmarks associated with that copy and site.", volumeProtectionInfo.getRpCopyName(), volumeProtectionInfo.getRpSiteName()));
                    // Wait for RP to remove copy snapshots
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                    RPHelper.cleanupSnapshots(_dbClient, rpSystem);
                }
            } else {
                throw DeviceControllerExceptions.recoverpoint.imageAccessModeNotSupported(imageAccessMode);
            }
        } else {
            throw DeviceControllerExceptions.recoverpoint.protectionOperationNotSupported(op);
        }
        _log.info("performProtectionOperation: after " + op + " operation successful");
        WorkflowStepCompleter.stepSucceded(stepId);
        return true;
    } catch (InternalException e) {
        _log.error("Operation failed with Exception: ", e);
        return stepFailed(stepId, (ServiceCoded) e, "removeProtection operation failed.");
    } catch (Exception e) {
        stepFailed(stepId, e, "removeProtection operation failed.");
        return false;
    }
}
Also used : CreateRSetParams(com.emc.storageos.recoverpoint.requests.CreateRSetParams) ArrayList(java.util.ArrayList) ProtectionSystem(com.emc.storageos.db.client.model.ProtectionSystem) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) RPCopyRequestParams(com.emc.storageos.recoverpoint.requests.RPCopyRequestParams) CreateVolumeParams(com.emc.storageos.recoverpoint.requests.CreateVolumeParams) 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) InternalException(com.emc.storageos.svcs.errorhandling.resources.InternalException) CreateBookmarkRequestParams(com.emc.storageos.recoverpoint.requests.CreateBookmarkRequestParams) RecoverPointVolumeProtectionInfo(com.emc.storageos.recoverpoint.responses.RecoverPointVolumeProtectionInfo) Volume(com.emc.storageos.db.client.model.Volume) ServiceCoded(com.emc.storageos.svcs.errorhandling.model.ServiceCoded) RecoverPointClient(com.emc.storageos.recoverpoint.impl.RecoverPointClient) CreateCopyParams(com.emc.storageos.recoverpoint.requests.CreateCopyParams) HashSet(java.util.HashSet)

Example 9 with RecoverPointClient

use of com.emc.storageos.recoverpoint.impl.RecoverPointClient in project coprhd-controller by CoprHD.

the class RPDeviceController method cgCreateStep.

/**
 * Workflow step method for creating/updating a consistency group.
 *
 * @param rpSystemId
 *            RP system Id
 * @param recommendation
 *            parameters needed to create the CG
 * @param token
 *            the task
 * @return
 * @throws InternalException
 */
public boolean cgCreateStep(URI rpSystemId, List<VolumeDescriptor> volumeDescriptors, String token) throws InternalException {
    RecoverPointClient rp;
    CGRequestParams cgParams = null;
    boolean metropoint = false;
    boolean lockException = false;
    try {
        // Get only the RP volumes from the descriptors.
        List<VolumeDescriptor> sourceVolumeDescriptors = VolumeDescriptor.filterByType(volumeDescriptors, new VolumeDescriptor.Type[] { VolumeDescriptor.Type.RP_SOURCE, VolumeDescriptor.Type.RP_EXISTING_SOURCE, VolumeDescriptor.Type.RP_VPLEX_VIRT_SOURCE }, new VolumeDescriptor.Type[] {});
        WorkflowStepCompleter.stepExecuting(token);
        ProtectionSystem rpSystem = _dbClient.queryObject(ProtectionSystem.class, rpSystemId);
        URI cgId = volumeDescriptors.iterator().next().getCapabilitiesValues().getBlockConsistencyGroup();
        boolean attachAsClean = true;
        for (VolumeDescriptor sourceVolumedescriptor : sourceVolumeDescriptors) {
            Volume sourceVolume = _dbClient.queryObject(Volume.class, sourceVolumedescriptor.getVolumeURI());
            metropoint = RPHelper.isMetroPointVolume(_dbClient, sourceVolume);
            // if this is a change vpool, attachAsClean should be false so that source and target are synchronized
            if (VolumeDescriptor.Type.RP_EXISTING_SOURCE.equals(sourceVolumedescriptor.getType())) {
                attachAsClean = false;
            }
        }
        // Build the CG Request params
        cgParams = getCGRequestParams(volumeDescriptors, rpSystem);
        updateCGParams(cgParams);
        // Validate the source/target volumes before creating a CG.
        validateCGVolumes(volumeDescriptors);
        rp = RPHelper.getRecoverPointClient(rpSystem);
        // Scan the rp sites for volume visibility
        rp.waitForVolumesToBeVisible(cgParams);
        // Before acquiring a lock on the CG we need to ensure that the
        // CG is created. If it hasn't, then the first CGRequestParams
        // to be allowed to pass through needs to have the journals
        // defined.
        // 
        // NOTE: The CG may not yet be created on the RP protection system and
        // that's OK since this might be the first request going in.
        waitForCGToBeCreated(cgId, cgParams);
        // lock around create and delete operations on the same CG
        List<String> lockKeys = new ArrayList<String>();
        lockKeys.add(ControllerLockingUtil.getConsistencyGroupStorageKey(_dbClient, cgId, rpSystem.getId()));
        boolean lockAcquired = _workflowService.acquireWorkflowStepLocks(token, lockKeys, LockTimeoutValue.get(LockType.RP_CG));
        if (!lockAcquired) {
            lockException = true;
            throw DeviceControllerException.exceptions.failedToAcquireLock(lockKeys.toString(), String.format("Create or add volumes to RP consistency group id: %s", cgId.toString()));
        }
        RecoverPointCGResponse response = null;
        // The CG already exists if it contains volumes and is of type RP
        _log.info("Submitting RP Request: " + cgParams);
        BlockConsistencyGroup cg = _dbClient.queryObject(BlockConsistencyGroup.class, cgId);
        // Check to see if the CG has been created in ViPR and on the RP protection system
        boolean cgAlreadyExists = rpCGExists(cg, rp, cgParams.getCgName(), rpSystem.getId());
        if (cgAlreadyExists) {
            // cg exists in both the ViPR db and on the RP system
            _log.info(String.format("RP CG [%s] already exists, adding replication set(s) to it...", cgParams.getCgName()));
            response = rp.addReplicationSetsToCG(cgParams, metropoint, attachAsClean);
        } else {
            _log.info(String.format("RP CG [%s] does not already exist, creating it now and adding replication set(s) to it...", cgParams.getCgName()));
            response = rp.createCG(cgParams, metropoint, attachAsClean);
            // "Turn-on" the consistency group
            cg = _dbClient.queryObject(BlockConsistencyGroup.class, cgParams.getCgUri());
            cg.addSystemConsistencyGroup(rpSystemId.toString(), cgParams.getCgName());
            cg.addConsistencyGroupTypes(Types.RP.name());
        }
        // At this point, always clear the journal provisioning lock on the
        // CG for any concurrent orders that may come in.
        cg.setJournalProvisioningLock(0L);
        _dbClient.updateObject(cg);
        setVolumeConsistencyGroup(volumeDescriptors, cgParams.getCgUri());
        // If this was a vpool Update, now is a good time to update the vpool and Volume information
        if (VolumeDescriptor.getVirtualPoolChangeVolume(volumeDescriptors) != null) {
            Volume volume = _dbClient.queryObject(Volume.class, VolumeDescriptor.getVirtualPoolChangeVolume(volumeDescriptors));
            URI newVpoolURI = getVirtualPoolChangeNewVirtualPool(volumeDescriptors);
            volume.setVirtualPool(newVpoolURI);
            volume.setPersonality(Volume.PersonalityTypes.SOURCE.toString());
            volume.setAccessState(Volume.VolumeAccessState.READWRITE.name());
            volume.setLinkStatus(Volume.LinkStatus.IN_SYNC.name());
            volume.setProtectionController(rpSystemId);
            _dbClient.updateObject(volume);
            // We might need to update the vpools of the backing volumes if this is an RP+VPLEX
            // or MetroPoint change vpool.
            VPlexUtil.updateVPlexBackingVolumeVpools(volume, newVpoolURI, _dbClient);
            // Record Audit operation. (virtualpool change only)
            AuditBlockUtil.auditBlock(_dbClient, OperationTypeEnum.CHANGE_VOLUME_VPOOL, true, AuditLogManager.AUDITOP_END, token);
        }
        // Create the ProtectionSet to contain the CG UID (which is truly unique to the protection system)
        if (response.getCgId() != null) {
            List<ProtectionSet> protectionSets = CustomQueryUtility.queryActiveResourcesByConstraint(_dbClient, ProtectionSet.class, AlternateIdConstraint.Factory.getConstraint(ProtectionSet.class, "protectionId", response.getCgId().toString()));
            ProtectionSet protectionSet = null;
            if (protectionSets.isEmpty()) {
                // A protection set corresponding to the CG does not exist so we need to create one
                protectionSet = createProtectionSet(rpSystem, cgParams, response.getCgId());
            } else {
                // Update the existing protection set. We will only have 1 protection set
                // get the first one.
                protectionSet = protectionSets.get(0);
                protectionSet = updateProtectionSet(protectionSet, cgParams);
            }
            _dbClient.updateObject(protectionSet);
        }
        // Set the CG last created time to now.
        rpSystem.setCgLastCreatedTime(Calendar.getInstance());
        _dbClient.updateObject(rpSystem);
        // Update the workflow state.
        WorkflowStepCompleter.stepSucceded(token);
        // collect and update the protection system statistics to account for
        // the newly created CG.
        _log.info("Collecting RP statistics post CG create.");
        collectRPStatistics(rpSystem);
    } catch (Exception e) {
        if (lockException) {
            List<URI> volUris = VolumeDescriptor.getVolumeURIs(volumeDescriptors);
            ServiceError serviceError = DeviceControllerException.errors.createVolumesAborted(volUris.toString(), e);
            doFailCgCreateStep(volumeDescriptors, cgParams, rpSystemId, token);
            stepFailed(token, serviceError, "cgCreateStep");
        } else {
            doFailCgCreateStep(volumeDescriptors, cgParams, rpSystemId, token);
            stepFailed(token, e, "cgCreateStep");
        }
        return false;
    }
    return true;
}
Also used : RecoverPointCGResponse(com.emc.storageos.recoverpoint.responses.RecoverPointCGResponse) ServiceError(com.emc.storageos.svcs.errorhandling.model.ServiceError) VolumeDescriptor(com.emc.storageos.blockorchestrationcontroller.VolumeDescriptor) ArrayList(java.util.ArrayList) ProtectionSet(com.emc.storageos.db.client.model.ProtectionSet) ProtectionSystem(com.emc.storageos.db.client.model.ProtectionSystem) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) 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) BlockConsistencyGroup(com.emc.storageos.db.client.model.BlockConsistencyGroup) Volume(com.emc.storageos.db.client.model.Volume) RecoverPointClient(com.emc.storageos.recoverpoint.impl.RecoverPointClient) CGRequestParams(com.emc.storageos.recoverpoint.requests.CGRequestParams) ApplicationAddVolumeList(com.emc.storageos.volumecontroller.ApplicationAddVolumeList) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) List(java.util.List)

Example 10 with RecoverPointClient

use of com.emc.storageos.recoverpoint.impl.RecoverPointClient in project coprhd-controller by CoprHD.

the class RPHelper method getRecoverPointClient.

/**
 * Get the FAPI RecoverPoint Client using the ProtectionSystem
 *
 * @param ps ProtectionSystem object
 * @return RecoverPointClient object
 * @throws RecoverPointException
 */
public static RecoverPointClient getRecoverPointClient(ProtectionSystem protectionSystem) throws RecoverPointException {
    RecoverPointClient recoverPointClient = null;
    if (protectionSystem.getUsername() != null && !protectionSystem.getUsername().isEmpty()) {
        try {
            List<URI> endpoints = new ArrayList<URI>();
            // Main endpoint that was registered by the user
            endpoints.add(new URI(HTTPS, null, protectionSystem.getIpAddress(), protectionSystem.getPortNumber(), RP_ENDPOINT, WSDL, null));
            // Add any other endpoints for cluster management ips we have
            for (String clusterManagementIp : protectionSystem.getClusterManagementIPs()) {
                endpoints.add(new URI(HTTPS, null, clusterManagementIp, protectionSystem.getPortNumber(), RP_ENDPOINT, WSDL, null));
            }
            recoverPointClient = RecoverPointClientFactory.getClient(protectionSystem.getId(), endpoints, protectionSystem.getUsername(), protectionSystem.getPassword());
        } catch (URISyntaxException ex) {
            throw DeviceControllerExceptions.recoverpoint.errorCreatingServerURL(protectionSystem.getIpAddress(), protectionSystem.getPortNumber(), ex);
        }
    } else {
        throw DeviceControllerExceptions.recoverpoint.noUsernamePasswordSpecified(protectionSystem.getIpAddress());
    }
    return recoverPointClient;
}
Also used : RecoverPointClient(com.emc.storageos.recoverpoint.impl.RecoverPointClient) ArrayList(java.util.ArrayList) URISyntaxException(java.net.URISyntaxException) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI)

Aggregations

RecoverPointClient (com.emc.storageos.recoverpoint.impl.RecoverPointClient)31 ArrayList (java.util.ArrayList)18 URI (java.net.URI)17 ProtectionSystem (com.emc.storageos.db.client.model.ProtectionSystem)15 Volume (com.emc.storageos.db.client.model.Volume)15 RecoverPointException (com.emc.storageos.recoverpoint.exceptions.RecoverPointException)15 URISyntaxException (java.net.URISyntaxException)15 FunctionalAPIActionFailedException_Exception (com.emc.fapiclient.ws.FunctionalAPIActionFailedException_Exception)13 FunctionalAPIInternalError_Exception (com.emc.fapiclient.ws.FunctionalAPIInternalError_Exception)13 CoordinatorException (com.emc.storageos.coordinator.exceptions.CoordinatorException)13 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)13 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)13 LockRetryException (com.emc.storageos.locking.LockRetryException)13 InternalException (com.emc.storageos.svcs.errorhandling.resources.InternalException)13 InternalServerErrorException (com.emc.storageos.svcs.errorhandling.resources.InternalServerErrorException)13 ControllerException (com.emc.storageos.volumecontroller.ControllerException)13 WorkflowException (com.emc.storageos.workflow.WorkflowException)13 NamedURI (com.emc.storageos.db.client.model.NamedURI)12 ProtectionSet (com.emc.storageos.db.client.model.ProtectionSet)10 StringSet (com.emc.storageos.db.client.model.StringSet)7