Search in sources :

Example 1 with Snapshot

use of com.emc.fapiclient.ws.Snapshot in project coprhd-controller by CoprHD.

the class RecoverPointBookmarkManagementUtils method getBookmarksForMostRecentBookmarkName.

/**
 * Find the most recent bookmarks that were created for a CG with a given name
 *
 * @param impl - RP handle to use for RP operations
 * @param request - Information about the bookmark that was created on the CGs
 * @param cgUID - The CG to look for bookmarks
 *
 * @return A set of RP bookmarks found on the CG
 *
 * @throws RecoverPointException
 */
private Set<RPBookmark> getBookmarksForMostRecentBookmarkName(FunctionalAPIImpl impl, CreateBookmarkRequestParams request, ConsistencyGroupUID cgUID) throws RecoverPointException {
    Set<RPBookmark> returnBookmarkSet = null;
    try {
        String bookmarkName = request.getBookmark();
        Set<RPBookmark> bookmarkSet = new HashSet<RPBookmark>();
        ConsistencyGroupSettings cgSettings = impl.getGroupSettings(cgUID);
        List<ConsistencyGroupCopySettings> cgCopySettings = cgSettings.getGroupCopiesSettings();
        ConsistencyGroupCopyUID prodCopyUID = cgSettings.getLatestSourceCopyUID();
        for (ConsistencyGroupCopySettings cgcopysetting : cgCopySettings) {
            RPBookmark newEM = new RPBookmark();
            newEM.setCGGroupCopyUID(cgcopysetting.getCopyUID());
            newEM.setBookmarkName(bookmarkName);
            newEM.setBookmarkTime(null);
            bookmarkSet.add(newEM);
        }
        logger.debug("Getting list of snapshots with event marker name: " + bookmarkName);
        List<ConsistencyGroupCopySnapshots> cgCopySnapList = impl.getGroupSnapshots(cgUID).getCopiesSnapshots();
        for (ConsistencyGroupCopySnapshots cgCopySnap : cgCopySnapList) {
            ConsistencyGroupCopyUID copyUID = cgCopySnap.getCopyUID();
            logger.debug("Found " + cgCopySnap.getSnapshots().size() + " snapshots on copy: " + copyUID.getGlobalCopyUID().getCopyUID());
            for (Snapshot snapItem : cgCopySnap.getSnapshots()) {
                if (snapItem.getDescription().equals(bookmarkName)) {
                    for (RPBookmark rpBookmark : bookmarkSet) {
                        ConsistencyGroupCopyUID rpBookmarkCopyCG = rpBookmark.getCGGroupCopyUID();
                        if (RecoverPointUtils.copiesEqual(copyUID, rpBookmarkCopyCG)) {
                            // Update record with bookmark time, and add back
                            rpBookmark.setBookmarkTime(snapItem.getClosingTimeStamp());
                            Timestamp protectionTimeStr = new Timestamp(snapItem.getClosingTimeStamp().getTimeInMicroSeconds() / numMicroSecondsInMilli);
                            // Remove it, and add it back
                            RPBookmark updatedBookmark = new RPBookmark();
                            updatedBookmark.setBookmarkTime(snapItem.getClosingTimeStamp());
                            updatedBookmark.setCGGroupCopyUID(rpBookmark.getCGGroupCopyUID());
                            logger.info("Found our bookmark with time: " + protectionTimeStr.toString() + " and group copy ID: " + rpBookmark.getCGGroupCopyUID().getGlobalCopyUID().getCopyUID());
                            updatedBookmark.setBookmarkName(rpBookmark.getBookmarkName());
                            updatedBookmark.setProductionCopyUID(prodCopyUID);
                            if (returnBookmarkSet == null) {
                                returnBookmarkSet = new HashSet<RPBookmark>();
                            }
                            // TODO: logic is suspect, need to revisit. Why are we removing and adding the same object??
                            returnBookmarkSet.remove(updatedBookmark);
                            returnBookmarkSet.add(updatedBookmark);
                        }
                    }
                }
            }
        }
    } catch (FunctionalAPIActionFailedException_Exception e) {
        throw RecoverPointException.exceptions.exceptionLookingForBookmarks(e);
    } catch (FunctionalAPIInternalError_Exception e) {
        throw RecoverPointException.exceptions.exceptionLookingForBookmarks(e);
    }
    logger.debug("Return set has " + ((returnBookmarkSet != null) ? returnBookmarkSet.size() : 0) + " items");
    return ((returnBookmarkSet != null) ? returnBookmarkSet : null);
}
Also used : FunctionalAPIActionFailedException_Exception(com.emc.fapiclient.ws.FunctionalAPIActionFailedException_Exception) Timestamp(java.sql.Timestamp) ConsistencyGroupCopySettings(com.emc.fapiclient.ws.ConsistencyGroupCopySettings) ConsistencyGroupCopyUID(com.emc.fapiclient.ws.ConsistencyGroupCopyUID) Snapshot(com.emc.fapiclient.ws.Snapshot) FunctionalAPIInternalError_Exception(com.emc.fapiclient.ws.FunctionalAPIInternalError_Exception) ConsistencyGroupCopySnapshots(com.emc.fapiclient.ws.ConsistencyGroupCopySnapshots) ConsistencyGroupSettings(com.emc.fapiclient.ws.ConsistencyGroupSettings) RPBookmark(com.emc.storageos.recoverpoint.objectmodel.RPBookmark) HashSet(java.util.HashSet)

Example 2 with Snapshot

use of com.emc.fapiclient.ws.Snapshot in project coprhd-controller by CoprHD.

the class RecoverPointImageManagementUtils method isGroupCopyImageEnabledForAPIT.

/**
 * Verify that a group copy image is enabled for an APIT time. Not a "wait for", just a check
 *
 * @param port - RP handle to use for RP operations
 * @param groupCopy - CG copy we are checking
 * @param expectLoggedAccess - We are explicitly checking for LOGGED_ACCESS
 * @param apitTime - An APIT time we are expecting to be enabled)
 *
 * @return boolean - true (enabled) or false (not enabled)
 *
 * @throws RecoverPointException, FunctionalAPIActionFailedException_Exception, FunctionalAPIInternalError_Exception,
 *             InterruptedException
 */
private boolean isGroupCopyImageEnabledForAPIT(FunctionalAPIImpl port, ConsistencyGroupCopyUID groupCopy, boolean expectLoggedAccess, RecoverPointTimeStamp apitTime) throws FunctionalAPIActionFailedException_Exception, FunctionalAPIInternalError_Exception, RecoverPointException {
    ConsistencyGroupUID groupUID = groupCopy.getGroupUID();
    ConsistencyGroupState groupState;
    List<ConsistencyGroupCopyState> groupCopyStateList;
    groupState = port.getGroupState(groupUID);
    groupCopyStateList = groupState.getGroupCopiesStates();
    String cgName = port.getGroupName(groupCopy.getGroupUID());
    String cgCopyName = port.getGroupCopyName(groupCopy);
    Timestamp enabledApitTime = null;
    // logger.debug ("isGroupCopyImageEnabledForAPIT called for copy " + cgCopyName + " of group " + cgName);
    for (ConsistencyGroupCopyState groupCopyState : groupCopyStateList) {
        if (RecoverPointUtils.copiesEqual(groupCopyState.getCopyUID(), groupCopy)) {
            StorageAccessState accessState = groupCopyState.getStorageAccessState();
            if (accessState == StorageAccessState.DIRECT_ACCESS) {
                // Not enabled
                logger.info("Copy image copy " + cgCopyName + " of group " + cgName + " is in direct access mode.");
                return false;
            }
            if (accessState == StorageAccessState.NO_ACCESS) {
                // Not enabled
                logger.info("Copy image copy " + cgCopyName + " of group " + cgName + " is in NO access mode.");
                return false;
            }
            // Enabled. Check out the details
            logger.info("Copy image copy " + cgCopyName + " of group " + cgName + "  IS enabled. State is: " + accessState.toString());
            if (groupCopyState.getAccessedImage().getDescription().isEmpty()) {
                RecoverPointTimeStamp enabledTimeDisplay = groupCopyState.getAccessedImage().getClosingTimeStamp();
                enabledApitTime = new Timestamp(enabledTimeDisplay.getTimeInMicroSeconds() / numMicroSecondsInMilli);
                logger.debug("No name. Mounted snapshot timestamp: " + enabledApitTime.toString());
            } else {
                // Unexpected, this is
                throw RecoverPointException.exceptions.expectingAPITMountFoundBookmark(groupCopyState.getAccessedImage().getDescription());
            }
            // Let's throw if its the wrong image
            if (apitTime != null) {
                // 
                // See if the time enabled is exactly the time we requested (regardless of whether it is
                // system generated, or AppSync generated.
                // 
                RecoverPointTimeStamp enabledTime = groupCopyState.getAccessedImage().getClosingTimeStamp();
                // Give it a 60 second variation
                if (Math.abs(enabledTime.getTimeInMicroSeconds() - apitTime.getTimeInMicroSeconds()) < (numMicroSecondsInSecond * 60)) {
                    // 
                    if (expectLoggedAccess) {
                        logger.debug("Seeing if copy is enabled for LOGGED_ACCESS");
                        if (accessState == StorageAccessState.LOGGED_ACCESS) {
                            logger.info("Copy image copy " + cgCopyName + " of group " + cgName + "  IS enabled in LOGGED_ACCESS");
                            return true;
                        }
                        logger.info("Copy image copy " + cgCopyName + " of group " + cgName + "  is NOT enabled in LOGGED_ACCESS. Image state is: " + accessState.toString());
                        return false;
                    } else {
                        logger.debug("APIT enabled for same time requested");
                        return true;
                    }
                }
                // 
                // It IS possible that an APIT image is not quite exactly the same time requested, but it is "close enough"
                // How do we tell? Well, we get the list of system snaps + or - 5 minutes from requested time, see if the one before the
                // requested APIT time is the one we are looking for. Limit the snaps we look at to 1 hour before/after requested APIT
                // time
                // 
                final Long timeDeviationInMicroSeconds = Long.valueOf(5 * 60 * numMicroSecondsInMilli * numMillisInSecond);
                TimeFrame window = new TimeFrame();
                RecoverPointTimeStamp endTime = new RecoverPointTimeStamp();
                RecoverPointTimeStamp startTime = new RecoverPointTimeStamp();
                RecoverPointTimeStamp prevSnapTime = null;
                // RecoverPointTimeStamp now = new RecoverPointTimeStamp();
                // now.setTimeInMicroSeconds (System.currentTimeMillis() * numMicroSecondsInMilli );
                // endTime.setTimeInMicroSeconds(now.getTimeInMicroSeconds() + timeDeviationInMicroSeconds);
                // startTime.setTimeInMicroSeconds(now.getTimeInMicroSeconds() - timeDeviationInMicroSeconds);
                endTime.setTimeInMicroSeconds(apitTime.getTimeInMicroSeconds() + timeDeviationInMicroSeconds);
                startTime.setTimeInMicroSeconds(apitTime.getTimeInMicroSeconds() - timeDeviationInMicroSeconds);
                window.setStartTime(startTime);
                window.setEndTime(endTime);
                // + " snapshots in the timeframe");
                for (Snapshot snapItem : port.getGroupCopySnapshotsForTimeFrameAndName(groupCopy, window, null).getSnapshots()) {
                    // logger.info("Checking snap with time: " + apitTimeStr.toString());
                    if (prevSnapTime == null) {
                        prevSnapTime = snapItem.getClosingTimeStamp();
                    } else {
                        if (prevSnapTime.getTimeInMicroSeconds() < snapItem.getClosingTimeStamp().getTimeInMicroSeconds()) {
                            prevSnapTime = snapItem.getClosingTimeStamp();
                        }
                    }
                }
                if (prevSnapTime != null) {
                    RecoverPointTimeStamp enabledTimeDisplay = groupCopyState.getAccessedImage().getClosingTimeStamp();
                    enabledApitTime = new Timestamp(enabledTimeDisplay.getTimeInMicroSeconds() / numMicroSecondsInMilli);
                    logger.debug("Previous snap time is : " + enabledApitTime.toString());
                    if (Math.abs(enabledTime.getTimeInMicroSeconds() - prevSnapTime.getTimeInMicroSeconds()) < numMicroSecondsInSecond) {
                        logger.debug("Currently enabled image is requested snap!");
                        if (expectLoggedAccess) {
                            logger.debug("Seeing if copy is enabled for LOGGED_ACCESS");
                            if (accessState == StorageAccessState.LOGGED_ACCESS) {
                                logger.info("Copy image copy " + cgCopyName + " of group " + cgName + "  IS enabled in LOGGED_ACCESS");
                                return true;
                            }
                            logger.info("Copy image copy " + cgCopyName + " of group " + cgName + "  is NOT enabled in LOGGED_ACCESS. Image state is: " + accessState.toString());
                            return false;
                        } else {
                            return true;
                        }
                    } else {
                        throw RecoverPointException.exceptions.wrongTimestampEnabled(enabledApitTime);
                    }
                }
            } else {
                return false;
            }
        }
    }
    logger.error("Could not locate CG copy state");
    return false;
}
Also used : TimeFrame(com.emc.fapiclient.ws.TimeFrame) RecoverPointTimeStamp(com.emc.fapiclient.ws.RecoverPointTimeStamp) Snapshot(com.emc.fapiclient.ws.Snapshot) ConsistencyGroupCopyState(com.emc.fapiclient.ws.ConsistencyGroupCopyState) ConsistencyGroupUID(com.emc.fapiclient.ws.ConsistencyGroupUID) StorageAccessState(com.emc.fapiclient.ws.StorageAccessState) Timestamp(java.sql.Timestamp) ConsistencyGroupState(com.emc.fapiclient.ws.ConsistencyGroupState)

Example 3 with Snapshot

use of com.emc.fapiclient.ws.Snapshot in project coprhd-controller by CoprHD.

the class RecoverPointBookmarkManagementUtils method getRPBookmarksForCG.

/**
 * Find the bookmarks associated with a consistency group
 *
 * @param impl - RP handle to use for RP operations
 * @param cgUID - The CG to look for bookmarks
 *
 * @return A set of RP bookmarks found on the CG
 *
 * @throws RecoverPointException
 */
public List<RPBookmark> getRPBookmarksForCG(FunctionalAPIImpl impl, ConsistencyGroupUID cgUID) throws RecoverPointException {
    List<RPBookmark> returnBookmarkSet = null;
    try {
        logger.debug("Getting list of snapshots for CG: " + cgUID.getId());
        List<ConsistencyGroupCopySnapshots> cgCopySnapList = impl.getGroupSnapshots(cgUID).getCopiesSnapshots();
        for (ConsistencyGroupCopySnapshots cgCopySnap : cgCopySnapList) {
            ConsistencyGroupCopyUID copyUID = cgCopySnap.getCopyUID();
            logger.debug("Found " + cgCopySnap.getSnapshots().size() + " snapshots on copy: " + copyUID.getGlobalCopyUID().getCopyUID());
            for (Snapshot snapItem : cgCopySnap.getSnapshots()) {
                // We're not interested in bookmarks without names
                if (snapItem.getDescription() != null && !snapItem.getDescription().isEmpty()) {
                    RPBookmark bookmark = new RPBookmark();
                    bookmark.setBookmarkTime(snapItem.getClosingTimeStamp());
                    bookmark.setCGGroupCopyUID(cgCopySnap.getCopyUID());
                    bookmark.setBookmarkName(snapItem.getDescription());
                    if (returnBookmarkSet == null) {
                        returnBookmarkSet = new ArrayList<RPBookmark>();
                    }
                    returnBookmarkSet.add(bookmark);
                    logger.debug("Recording bookmark: " + bookmark.getBookmarkName());
                }
            }
        }
    } catch (FunctionalAPIActionFailedException_Exception e) {
        throw RecoverPointException.exceptions.exceptionLookingForBookmarks(e);
    } catch (FunctionalAPIInternalError_Exception e) {
        throw RecoverPointException.exceptions.exceptionLookingForBookmarks(e);
    }
    logger.debug("Return set has " + ((returnBookmarkSet != null) ? returnBookmarkSet.size() : 0) + " items");
    return ((returnBookmarkSet != null) ? returnBookmarkSet : null);
}
Also used : Snapshot(com.emc.fapiclient.ws.Snapshot) FunctionalAPIInternalError_Exception(com.emc.fapiclient.ws.FunctionalAPIInternalError_Exception) FunctionalAPIActionFailedException_Exception(com.emc.fapiclient.ws.FunctionalAPIActionFailedException_Exception) ConsistencyGroupCopySnapshots(com.emc.fapiclient.ws.ConsistencyGroupCopySnapshots) RPBookmark(com.emc.storageos.recoverpoint.objectmodel.RPBookmark) ConsistencyGroupCopyUID(com.emc.fapiclient.ws.ConsistencyGroupCopyUID)

Example 4 with Snapshot

use of com.emc.fapiclient.ws.Snapshot in project coprhd-controller by CoprHD.

the class RecoverPointImageManagementUtils method findPiTSnapshot.

/**
 * Given a list of snapshots, finds the snapshot that is closest to the the provided any point-in-time
 * in microseconds.
 *
 * @param copySnapshots the list of group copy snapshots.
 * @param apitTimeInMicroSeconds the point-in-time in microseconds
 * @return the snapshot closest to the provided point-in-time.
 */
private Snapshot findPiTSnapshot(ConsistencyGroupCopySnapshots copySnapshots, long apitTimeInMicroSeconds) {
    long min = Long.MAX_VALUE;
    Snapshot closest = null;
    for (Snapshot snapshot : copySnapshots.getSnapshots()) {
        final long diff = Math.abs(snapshot.getClosingTimeStamp().getTimeInMicroSeconds() - apitTimeInMicroSeconds);
        logger.debug(String.format("Examining snapshot %s with closing timestamp %s. Determining if it's closest to provided point-in-time %s. Difference is %s", snapshot.getSnapshotUID().getId(), snapshot.getClosingTimeStamp().getTimeInMicroSeconds(), apitTimeInMicroSeconds, diff));
        if (diff < min) {
            min = diff;
            closest = snapshot;
        } else {
            // We have hit the point where we have found the closest result to the APIT.
            logger.info(String.format("Determined that snapshot %s with closing timestamp %s is closest to point-in-time %s", closest.getSnapshotUID().getId(), closest.getClosingTimeStamp().getTimeInMicroSeconds(), apitTimeInMicroSeconds));
            break;
        }
    }
    return closest;
}
Also used : Snapshot(com.emc.fapiclient.ws.Snapshot)

Example 5 with Snapshot

use of com.emc.fapiclient.ws.Snapshot in project coprhd-controller by CoprHD.

the class RecoverPointImageManagementUtils method enableCGCopy.

/**
 * Perform an enable image access on a CG copy
 *
 * @param impl - RP handle to use for RP operations
 * @param cgCopy - CG copy to perform the enable image access on
 * @param accessMode - The access mode to use (LOGGED_ACCESS, VIRTUAL_ACCESS, VIRTUAL_ACCESS_WITH_ROLL
 * @param bookmarkName - The bookmark image to enable (can be null)
 * @param apitTime -The APIT time to enable (can be null)
 *
 * @return void
 *
 * @throws RecoverPointException
 */
public void enableCGCopy(FunctionalAPIImpl impl, ConsistencyGroupCopyUID cgCopy, boolean waitForLinkState, ImageAccessMode accessMode, String bookmarkName, Date apitTime) throws RecoverPointException {
    String cgCopyName = NAME_UNKNOWN;
    String cgName = NAME_UNKNOWN;
    Snapshot snapshotToEnable = null;
    try {
        cgCopyName = impl.getGroupCopyName(cgCopy);
        cgName = impl.getGroupName(cgCopy.getGroupUID());
        if (waitForLinkState) {
            // Make sure the CG copy is ready for enable
            waitForCGCopyLinkState(impl, cgCopy, RecoverPointImageManagementUtils.getPipeActiveState(impl, cgCopy.getGroupUID()));
        } else {
            logger.info("Not waiting on any link states, proceeding with the operation");
        }
        if (bookmarkName == null) {
            // Time based enable
            if (apitTime == null) {
                logger.info("Enable most recent image on RP CG: " + cgName + " for CG copy: " + cgCopyName);
                // No APIT specified. Get the most recent snapshot image
                int numRetries = 0;
                boolean foundSnap = false;
                // Wait up to 15 minutes to find a snap
                while (!foundSnap && numRetries++ < MAX_RETRIES) {
                    ConsistencyGroupCopySnapshots copySnapshots = impl.getGroupCopySnapshots(cgCopy);
                    Snapshot newestSnapshot = null;
                    for (Snapshot snapshot : copySnapshots.getSnapshots()) {
                        if (newestSnapshot == null) {
                            newestSnapshot = snapshot;
                        } else {
                            if (snapshot.getClosingTimeStamp().getTimeInMicroSeconds() > newestSnapshot.getClosingTimeStamp().getTimeInMicroSeconds()) {
                                newestSnapshot = snapshot;
                            }
                        }
                    }
                    if (newestSnapshot != null) {
                        snapshotToEnable = newestSnapshot;
                        bookmarkName = newestSnapshot.getDescription();
                        if (bookmarkName.length() == 0) {
                            bookmarkName = "Internal";
                        }
                    }
                    if (snapshotToEnable == null) {
                        logger.info("Did not find most recent snapshot. Sleep 15 seconds and retry");
                        Thread.sleep(15000);
                    } else {
                        foundSnap = true;
                    }
                }
            } else {
                // Get the snapshotToEnable based on the APIT
                Calendar apitTimeCal = Calendar.getInstance();
                apitTimeCal.setTime(apitTime);
                Calendar apitTimeStart = Calendar.getInstance();
                apitTimeStart.setTime(apitTime);
                apitTimeStart.add(Calendar.MINUTE, -SNAPSHOT_QUERY_WINDOW_BUFFER);
                Calendar apitTimeEnd = Calendar.getInstance();
                apitTimeEnd.setTime(apitTime);
                apitTimeEnd.add(Calendar.MINUTE, SNAPSHOT_QUERY_WINDOW_BUFFER);
                // Convert all times to microseconds so they can be used in constructing a
                // snapshot query time frame.
                long apitTimeInMicroSeconds = apitTimeCal.getTimeInMillis() * numMicroSecondsInMilli;
                long apitTimeStartInMicroSeconds = apitTimeStart.getTimeInMillis() * numMicroSecondsInMilli;
                long apitTimeEndInMicroSeconds = apitTimeEnd.getTimeInMillis() * numMicroSecondsInMilli;
                logger.info(String.format("Request to enable a PiT image on RP CG: %s for CG copy: %s. The PiT requested is %s which evaluates to %s microseconds.", cgName, cgCopyName, apitTime, apitTimeInMicroSeconds));
                logger.info(String.format("Building snapshot query window between %s and %s.  Evaluates to a microsecond window between %s and %s.", apitTimeStart.getTime(), apitTimeEnd.getTime(), apitTimeStartInMicroSeconds, apitTimeEndInMicroSeconds));
                // Construct the RecoverPoint TimeFrame
                RecoverPointTimeStamp startTime = new RecoverPointTimeStamp();
                startTime.setTimeInMicroSeconds(apitTimeStartInMicroSeconds);
                RecoverPointTimeStamp endTime = new RecoverPointTimeStamp();
                endTime.setTimeInMicroSeconds(apitTimeEndInMicroSeconds);
                TimeFrame timeFrame = new TimeFrame();
                timeFrame.setStartTime(startTime);
                timeFrame.setEndTime(endTime);
                // Get the CG copy snapshots for the given time frame.
                ConsistencyGroupCopySnapshots copySnapshots = impl.getGroupCopySnapshotsForTimeFrameAndName(cgCopy, timeFrame, null);
                if (copySnapshots != null && copySnapshots.getSnapshots() != null && copySnapshots.getSnapshots().isEmpty()) {
                    // There are no snapshots returned so lets see if the query window is valid. First, see if
                    // the point-in-time is before the start of the protection window.
                    logger.info(String.format("Determined that the protection window is between %s and %s.", copySnapshots.getEarliest().getTimeInMicroSeconds(), copySnapshots.getLatest().getTimeInMicroSeconds()));
                    if (apitTimeInMicroSeconds < copySnapshots.getEarliest().getTimeInMicroSeconds()) {
                        logger.info("The specified point-in-time is before the start of the protection window.  As a result, returning the first snapshot in the protection window.");
                        startTime.setTimeInMicroSeconds(copySnapshots.getEarliest().getTimeInMicroSeconds());
                        // Set the start and end time to the same to get the exact snapshot
                        timeFrame.setStartTime(startTime);
                        timeFrame.setEndTime(startTime);
                        copySnapshots = impl.getGroupCopySnapshotsForTimeFrameAndName(cgCopy, timeFrame, null);
                        snapshotToEnable = copySnapshots.getSnapshots().get(0);
                    } else if (apitTimeInMicroSeconds > copySnapshots.getLatest().getTimeInMicroSeconds()) {
                        logger.info("The specified point-in-time is after the end of the protection window.  As a result, returning the most current snapshot in the protection window.");
                        startTime.setTimeInMicroSeconds(copySnapshots.getLatest().getTimeInMicroSeconds());
                        // Set the start and end time to the same to get the exact snapshot
                        timeFrame.setStartTime(startTime);
                        timeFrame.setEndTime(startTime);
                        copySnapshots = impl.getGroupCopySnapshotsForTimeFrameAndName(cgCopy, timeFrame, null);
                        snapshotToEnable = copySnapshots.getSnapshots().get(0);
                    } else {
                        // The snapshot falls within the protection window but the query window was too small to find
                        // a snapshot that matches the PiT. We will attempt to gradually expand the query window
                        // and retry until we find a match or exhaust our retry count.
                        int queryAttempt = 1;
                        while (queryAttempt <= NUM_SNAPSHOT_QUERY_ATTEMPTS) {
                            // Expand the snapshot query window in each direction by the defined buffer amount.
                            apitTimeStart.add(Calendar.MINUTE, -SNAPSHOT_QUERY_WINDOW_BUFFER);
                            apitTimeEnd.add(Calendar.MINUTE, SNAPSHOT_QUERY_WINDOW_BUFFER);
                            apitTimeStartInMicroSeconds = apitTimeStart.getTimeInMillis() * numMicroSecondsInMilli;
                            apitTimeEndInMicroSeconds = apitTimeEnd.getTimeInMillis() * numMicroSecondsInMilli;
                            startTime.setTimeInMicroSeconds(apitTimeStartInMicroSeconds);
                            endTime.setTimeInMicroSeconds(apitTimeEndInMicroSeconds);
                            timeFrame.setStartTime(startTime);
                            timeFrame.setEndTime(endTime);
                            logger.info(String.format("The PiT falls within the protection window but no results are returned. Attempt %s of %s. Expanding the query window by %s minute(s) in both directions to [%s - %s].", queryAttempt, NUM_SNAPSHOT_QUERY_ATTEMPTS, SNAPSHOT_QUERY_WINDOW_BUFFER, apitTimeStartInMicroSeconds, apitTimeEndInMicroSeconds));
                            copySnapshots = impl.getGroupCopySnapshotsForTimeFrameAndName(cgCopy, timeFrame, null);
                            if (!copySnapshots.getSnapshots().isEmpty()) {
                                // Snapshots have been found for the given query window so now attempt to find the correct
                                // snapshot that matches the specified PiT.
                                snapshotToEnable = findPiTSnapshot(copySnapshots, apitTimeInMicroSeconds);
                                break;
                            }
                            // increment the query attempt
                            queryAttempt++;
                        }
                    }
                } else {
                    snapshotToEnable = findPiTSnapshot(copySnapshots, apitTimeInMicroSeconds);
                }
            }
        } else {
            // Bookmark based enable. Set snapshotToEnable
            logger.info("Enable bookmark image " + bookmarkName + " on RP CG: " + cgName + " for CG copy: " + cgCopyName);
            // No APIT specified. Get the most recent snapshot image
            int numRetries = 0;
            boolean foundSnap = false;
            // Wait up to 15 minutes to find a snap
            while (!foundSnap && numRetries++ < MAX_RETRIES) {
                ConsistencyGroupCopySnapshots copySnapshots = impl.getGroupCopySnapshots(cgCopy);
                for (Snapshot snapItem : copySnapshots.getSnapshots()) {
                    if (snapItem.getDescription() != null && !snapItem.getDescription().isEmpty()) {
                        logger.info("Look at description: " + snapItem.getDescription());
                        if (snapItem.getDescription().equals(bookmarkName)) {
                            foundSnap = true;
                            snapshotToEnable = snapItem;
                            break;
                        }
                    }
                }
                if (!foundSnap) {
                    logger.info("Did not find snapshot to enable. Sleep 15 seconds and retry");
                    Thread.sleep(15000);
                }
            }
        }
        if (snapshotToEnable == null) {
            throw RecoverPointException.exceptions.failedToFindBookmarkOrAPIT();
        }
        String bookmarkDate = new java.util.Date(snapshotToEnable.getClosingTimeStamp().getTimeInMicroSeconds() / numMicroSecondsInMilli).toString();
        logger.info("Enable snapshot image: " + bookmarkName + " of time " + bookmarkDate + " on CG Copy " + cgCopyName + " for CG name " + cgName);
        impl.enableImageAccess(cgCopy, snapshotToEnable, accessMode, ImageAccessScenario.NONE);
        if (waitForEnableToComplete(impl, cgCopy, accessMode, null)) {
            // Verify image is enabled correctly
            logger.info("Wait for image to be in correct mode");
            // This will wait for the state change, and throw if it times out or gets some other error
            waitForCGCopyState(impl, cgCopy, false, accessMode);
        }
    } catch (FunctionalAPIActionFailedException_Exception e) {
        throw RecoverPointException.exceptions.failedToEnableCopy(cgCopyName, cgName, e);
    } catch (FunctionalAPIInternalError_Exception e) {
        throw RecoverPointException.exceptions.failedToEnableCopy(cgCopyName, cgName, e);
    } catch (InterruptedException e) {
        throw RecoverPointException.exceptions.failedToEnableCopy(cgCopyName, cgName, e);
    }
}
Also used : TimeFrame(com.emc.fapiclient.ws.TimeFrame) RecoverPointTimeStamp(com.emc.fapiclient.ws.RecoverPointTimeStamp) FunctionalAPIActionFailedException_Exception(com.emc.fapiclient.ws.FunctionalAPIActionFailedException_Exception) Date(java.util.Date) Calendar(java.util.Calendar) Snapshot(com.emc.fapiclient.ws.Snapshot) FunctionalAPIInternalError_Exception(com.emc.fapiclient.ws.FunctionalAPIInternalError_Exception) ConsistencyGroupCopySnapshots(com.emc.fapiclient.ws.ConsistencyGroupCopySnapshots)

Aggregations

Snapshot (com.emc.fapiclient.ws.Snapshot)5 ConsistencyGroupCopySnapshots (com.emc.fapiclient.ws.ConsistencyGroupCopySnapshots)3 FunctionalAPIActionFailedException_Exception (com.emc.fapiclient.ws.FunctionalAPIActionFailedException_Exception)3 FunctionalAPIInternalError_Exception (com.emc.fapiclient.ws.FunctionalAPIInternalError_Exception)3 ConsistencyGroupCopyUID (com.emc.fapiclient.ws.ConsistencyGroupCopyUID)2 RecoverPointTimeStamp (com.emc.fapiclient.ws.RecoverPointTimeStamp)2 TimeFrame (com.emc.fapiclient.ws.TimeFrame)2 RPBookmark (com.emc.storageos.recoverpoint.objectmodel.RPBookmark)2 Timestamp (java.sql.Timestamp)2 ConsistencyGroupCopySettings (com.emc.fapiclient.ws.ConsistencyGroupCopySettings)1 ConsistencyGroupCopyState (com.emc.fapiclient.ws.ConsistencyGroupCopyState)1 ConsistencyGroupSettings (com.emc.fapiclient.ws.ConsistencyGroupSettings)1 ConsistencyGroupState (com.emc.fapiclient.ws.ConsistencyGroupState)1 ConsistencyGroupUID (com.emc.fapiclient.ws.ConsistencyGroupUID)1 StorageAccessState (com.emc.fapiclient.ws.StorageAccessState)1 Calendar (java.util.Calendar)1 Date (java.util.Date)1 HashSet (java.util.HashSet)1