use of com.emc.fapiclient.ws.TimeFrame 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;
}
use of com.emc.fapiclient.ws.TimeFrame 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);
}
}
Aggregations