use of com.emc.fapiclient.ws.FunctionalAPIActionFailedException_Exception 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);
}
}
use of com.emc.fapiclient.ws.FunctionalAPIActionFailedException_Exception in project coprhd-controller by CoprHD.
the class RecoverPointUtils method getSplittersToAttachToForVolume.
/**
* Finds the splitter(s) to attach a volume to (if any need to be attached).
*
* @param impl - handle for FAPI
* @param ClusterUID - site for the volume
* @param volume - volume ID we are looking for
* @return - Set<SplitterUID>
*/
private static Set<SplitterUID> getSplittersToAttachToForVolume(FunctionalAPIImpl impl, ClusterUID ClusterUID, DeviceUID volume) throws RecoverPointException {
Set<SplitterUID> returnSplitters = new HashSet<SplitterUID>();
try {
logger.info("Finding splitters with unattached volumes");
List<SplitterUID> splittersWithUnattachedVols = impl.getAvailableSplittersToAttachToVolume(ClusterUID, volume);
for (SplitterUID splitterUID : splittersWithUnattachedVols) {
SplitterSettings splitterSettings = impl.getSplitterSettings(splitterUID);
List<DeviceUID> unattachedVolumes = impl.getAvailableVolumesToAttachToSplitter(splitterUID, true);
if (!unattachedVolumes.isEmpty()) {
for (DeviceUID unattachedVolume : unattachedVolumes) {
if (unattachedVolume.getId() == volume.getId()) {
returnSplitters.add(splitterSettings.getSplitterUID());
}
}
}
}
return returnSplitters;
} catch (FunctionalAPIActionFailedException_Exception e) {
logger.error(e.getMessage(), e);
throw RecoverPointException.exceptions.exceptionGettingSplittersVolume(e);
} catch (FunctionalAPIInternalError_Exception e) {
logger.error(e.getMessage(), e);
throw RecoverPointException.exceptions.exceptionGettingSplittersVolume(e);
}
}
Aggregations