use of com.emc.fapiclient.ws.ConsistencyGroupUID 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.ConsistencyGroupUID in project coprhd-controller by CoprHD.
the class RecoverPointUtils method mapRPVolumeProtectionInfoToCGCopyUID.
/**
* @param rpProtectionInfo
* @return
*/
public static ConsistencyGroupCopyUID mapRPVolumeProtectionInfoToCGCopyUID(RecoverPointVolumeProtectionInfo rpProtectionInfo) {
ConsistencyGroupUID cgUID = new ConsistencyGroupUID();
ConsistencyGroupCopyUID cgCopyUID = new ConsistencyGroupCopyUID();
if (rpProtectionInfo != null) {
cgUID.setId(rpProtectionInfo.getRpVolumeGroupID());
cgCopyUID.setGlobalCopyUID(new GlobalCopyUID());
cgCopyUID.getGlobalCopyUID().setCopyUID(rpProtectionInfo.getRpVolumeGroupCopyID());
cgCopyUID.setGroupUID(cgUID);
ClusterUID ClusterUID = new ClusterUID();
ClusterUID.setId(rpProtectionInfo.getRpVolumeSiteID());
cgCopyUID.getGlobalCopyUID().setClusterUID(ClusterUID);
}
return cgCopyUID;
}
use of com.emc.fapiclient.ws.ConsistencyGroupUID in project coprhd-controller by CoprHD.
the class RecoverPointClient method setCopyAsProduction.
/**
* Prepares the copy link settings and sets copy as production. This would typically be
* called following a call to swapCopy.
*
* @param copyParams the volume info for preparing the CG links and setting copy as production.
* @throws RecoverPointException
*/
public void setCopyAsProduction(RPCopyRequestParams copyParams) throws RecoverPointException {
logger.info(String.format("Setting copy %s as production copy.", (copyParams.getCopyVolumeInfo() != null) ? copyParams.getCopyVolumeInfo().getRpCopyName() : "N/A"));
// Make sure the copy is already enabled or RP will fail the operation. If it isn't enabled, enable it.
RecoverPointImageManagementUtils imageManager = new RecoverPointImageManagementUtils();
ConsistencyGroupCopyUID cgCopyUID = RecoverPointUtils.mapRPVolumeProtectionInfoToCGCopyUID(copyParams.getCopyVolumeInfo());
// Prepare the link settings for new links
prepareLinkSettings(cgCopyUID);
// Set the failover copy as production to resume data flow
imageManager.setCopyAsProduction(functionalAPI, cgCopyUID);
// wait for links to become active
ConsistencyGroupUID cgUID = cgCopyUID.getGroupUID();
String cgName = null;
try {
cgName = functionalAPI.getGroupName(cgUID);
} catch (FunctionalAPIActionFailedException_Exception | FunctionalAPIInternalError_Exception e) {
// benign error -- cgName is only used for logging
logger.error(e.getMessage(), e);
}
boolean waitForLinkStates = false;
// In a true DR scenario, we cant expect links to become active and that should not fail the swap/failover operation.
if (waitForLinkStates) {
logger.info("Waiting for links to become active for CG " + (cgName == null ? "unknown CG name" : cgName));
(new RecoverPointImageManagementUtils()).waitForCGLinkState(functionalAPI, cgUID, PipeState.ACTIVE);
} else {
logger.info("Not waiting for links to become active for CG" + (cgName == null ? "unknown CG name" : cgName));
}
logger.info(String.format("Replication sets have been added to consistency group %s.", (cgName == null ? "unknown CG name" : cgName)));
}
use of com.emc.fapiclient.ws.ConsistencyGroupUID in project coprhd-controller by CoprHD.
the class RecoverPointClient method deleteReplicationSets.
/**
* Deletes one-to-many replication sets based on the volume information passed in.
*
* @param volumeInfoList the volume information that relates to one or more replication sets.
* @throws RecoverPointException
*/
public void deleteReplicationSets(List<RecoverPointVolumeProtectionInfo> volumeInfoList) throws RecoverPointException {
// Used to capture the volume WWNs associated with each replication set to remove.
List<String> volumeWWNs = new ArrayList<String>();
Map<Long, String> rsetNames = new HashMap<Long, String>();
List<Long> rsetIDsToValidate = new ArrayList<Long>();
try {
ConsistencyGroupUID cgID = new ConsistencyGroupUID();
cgID.setId(volumeInfoList.get(0).getRpVolumeGroupID());
ConsistencyGroupSettingsChangesParam cgSettingsParam = new ConsistencyGroupSettingsChangesParam();
cgSettingsParam.setGroupUID(cgID);
ConsistencyGroupSettings groupSettings = functionalAPI.getGroupSettings(cgID);
List<ReplicationSetSettings> replicationSetSettings = groupSettings.getReplicationSetsSettings();
for (RecoverPointVolumeProtectionInfo volumeInfo : volumeInfoList) {
boolean found = false;
// Validate that the requested replication sets to delete actually exist.
for (ReplicationSetSettings replicationSet : replicationSetSettings) {
if (replicationSet.getReplicationSetUID().getId() == volumeInfo.getRpVolumeRSetID()) {
rsetNames.put(volumeInfo.getRpVolumeRSetID(), replicationSet.getReplicationSetName());
found = true;
break;
}
}
if (!found) {
logger.warn(String.format("No matching replication set for volume [%s] with replication set ID [%s] found." + " This will need to be checked on the RP System.", volumeInfo.getRpVolumeWWN(), volumeInfo.getRpVolumeRSetID()));
continue;
}
ReplicationSetUID repSetUID = new ReplicationSetUID();
repSetUID.setId(volumeInfo.getRpVolumeRSetID());
repSetUID.setGroupUID(cgID);
if (!containsRepSetUID(cgSettingsParam.getRemovedReplicationSets(), repSetUID)) {
cgSettingsParam.getRemovedReplicationSets().add(repSetUID);
rsetIDsToValidate.add(repSetUID.getId());
}
volumeWWNs.add(volumeInfo.getRpVolumeWWN());
logger.info(String.format("Adding replication set [%s] (%d) to be removed from RP CG [%s] (%d)", rsetNames.get(volumeInfo.getRpVolumeRSetID()), volumeInfo.getRpVolumeRSetID(), groupSettings.getName(), cgID.getId()));
}
// to remove.
if (cgSettingsParam.getRemovedReplicationSets() != null && !cgSettingsParam.getRemovedReplicationSets().isEmpty()) {
if (replicationSetSettings.size() == cgSettingsParam.getRemovedReplicationSets().size()) {
// We are removing all the replication sets in the CG so we need to disable
// the entire CG.
disableConsistencyGroup(cgID);
}
// Remove the replication sets
functionalAPI.setConsistencyGroupSettings(cgSettingsParam);
// Validate that the RSets have been removed
validateRSetsRemoved(rsetIDsToValidate, cgID, volumeWWNs);
logger.info("Request to delete replication sets " + rsetNames.toString() + " from RP CG " + groupSettings.getName() + " completed.");
} else {
logger.warn(String.format("No replication sets found to be deleted from RP CG [%s] (%d)", groupSettings.getName(), cgID.getId()));
}
} catch (Exception e) {
throw RecoverPointException.exceptions.failedToDeleteReplicationSet(volumeWWNs.toString(), e);
}
}
use of com.emc.fapiclient.ws.ConsistencyGroupUID in project coprhd-controller by CoprHD.
the class RecoverPointClient method validateCGRemoved.
/**
* Validate that the CG has been removed from the RP system by calling out
* to get all CGs and ensuring the one we are trying to delete is gone.
*
* If we still see the CG being returned, wait and try again until max attempts is
* reached.
*
* @param cgToValidate The CG UID to check
* @param cgName The CG name to check
* @throws RecoverPointException RP Exception to throw if we hit it
*/
private void validateCGRemoved(ConsistencyGroupUID cgToValidate, String cgName) throws RecoverPointException {
try {
logger.info(String.format("Validating that RP CG [%s] (%d) has been removed.", cgName, cgToValidate.getId()));
int cgDeleteAttempt = 0;
while (cgDeleteAttempt < MAX_WAIT_FOR_RP_DELETE_ATTEMPTS) {
boolean cgDeleted = true;
logger.info(String.format("Validation attempt %d of %d", cgDeleteAttempt + 1, MAX_WAIT_FOR_RP_DELETE_ATTEMPTS));
// Get all the CGs from RecoverPoint
List<ConsistencyGroupUID> allCGs = functionalAPI.getAllConsistencyGroups();
// If not, wait and check again.
for (ConsistencyGroupUID cgUID : allCGs) {
if (cgToValidate.getId() == cgUID.getId()) {
logger.info(String.format("RP CG [%s] (%d) has not been removed yet. Will wait and check again...", cgName, cgToValidate.getId()));
waitForRpOperation();
cgDeleteAttempt++;
cgDeleted = false;
// to RecoverPoint to ensure we do not have a stale connection.
if (cgDeleteAttempt == (MAX_WAIT_FOR_RP_DELETE_ATTEMPTS / 2)) {
this.reconnect();
}
break;
}
}
if (cgDeleted) {
// RP CG appears to have been removed from RP
logger.info(String.format("RP CG [%s] (%d) has been removed.", cgName, cgToValidate.getId()));
break;
}
}
// If we reached max attempts alert the user and continue on with delete operation.
if (cgDeleteAttempt >= MAX_WAIT_FOR_RP_DELETE_ATTEMPTS) {
// Allow the cleanup to continue in ViPR but warn the user
logger.error(String.format("Max attempts reached waiting for RP CG [%s] (%d) to be removed from RP. " + "Please check RP System. Delete operation will continue...", cgName, cgToValidate.getId()));
throw RecoverPointException.exceptions.failedToDeleteConsistencyGroup(cgName, new Exception("Max attempts reached waiting for RP CG to be removed from RP."));
}
} catch (Exception e) {
logger.error(String.format("Exception hit while waiting for RP CG [%s] to be removed.", cgName));
throw RecoverPointException.exceptions.failedToDeleteConsistencyGroup(cgName, e);
}
}
Aggregations