use of com.emc.storageos.recoverpoint.objectmodel.RPBookmark 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;
}
use of com.emc.storageos.recoverpoint.objectmodel.RPBookmark in project coprhd-controller by CoprHD.
the class RPHelper method cleanupSnapshots.
/**
* Validate Block snapshots that correspond to RP bookmarks. Some may no longer exist in the RP system, and we
* need to mark them as invalid.
*
* The strategy is as follows:
* 1. Get all of the protection sets associated with the protection system
* 2. Are there any Block Snapshots of type RP? (if not, don't bother cleaning up)
* 3. Query the RP Appliance for all bookmarks for that CG (protection set)
* 4. Find each block snapshot of type RP for each site
* 5. If you can't find the bookmark in the RP list, move the block snapshot to inactive
*
* @param protectionSystem Protection System
*/
public static void cleanupSnapshots(DbClient dbClient, ProtectionSystem protectionSystem) throws RecoverPointException {
// 1. Get all of the protection sets associated with the protection system
Set<URI> protectionSetIDs = new HashSet<URI>();
Set<Integer> cgIDs = new HashSet<Integer>();
URIQueryResultList list = new URIQueryResultList();
Constraint constraint = ContainmentConstraint.Factory.getProtectionSystemProtectionSetConstraint(protectionSystem.getId());
dbClient.queryByConstraint(constraint, list);
Iterator<URI> it = list.iterator();
while (it.hasNext()) {
URI protectionSetId = it.next();
// Get all snapshots that are part of this protection set.
URIQueryResultList plist = new URIQueryResultList();
Constraint pconstraint = ContainmentConstraint.Factory.getProtectionSetBlockSnapshotConstraint(protectionSetId);
dbClient.queryByConstraint(pconstraint, plist);
if (plist.iterator().hasNext()) {
// OK, we know there are snapshots for this protection set/CG.
// Retrieve all of the bookmarks associated with this protection set/CG later on by adding to the list now
ProtectionSet protectionSet = dbClient.queryObject(ProtectionSet.class, protectionSetId);
if (protectionSet != null && !protectionSet.getInactive()) {
protectionSetIDs.add(protectionSet.getId());
cgIDs.add(Integer.valueOf(protectionSet.getProtectionId()));
}
}
}
// 2. No reason to bother the RPAs if there are no protection sets for this protection system.
if (protectionSetIDs.isEmpty()) {
_log.info("Block Snapshot of RP Bookmarks cleanup not run for this protection system. No Protections or RP Block Snapshots found on protection system: " + protectionSystem.getLabel());
return;
}
// 3. Query the RP appliance for all of the bookmarks for these CGs in one call
BiosCommandResult result = getRPBookmarks(protectionSystem, cgIDs);
GetBookmarksResponse bookmarkMap = (GetBookmarksResponse) result.getObjectList().get(0);
// 4. Go through each protection set's snapshots and see if they're there.
it = protectionSetIDs.iterator();
while (it.hasNext()) {
URI protectionSetId = it.next();
ProtectionSet protectionSet = dbClient.queryObject(ProtectionSet.class, protectionSetId);
// The map should have an entry for that CG with an empty list if it looked and couldn't find any. (a successful empty set)
if (protectionSet.getProtectionId() != null && bookmarkMap.getCgBookmarkMap() != null && bookmarkMap.getCgBookmarkMap().containsKey(new Integer(protectionSet.getProtectionId()))) {
// list to avoid issues further down.
if (bookmarkMap.getCgBookmarkMap().get(new Integer(protectionSet.getProtectionId())) == null) {
bookmarkMap.getCgBookmarkMap().put(new Integer(protectionSet.getProtectionId()), new ArrayList<RPBookmark>());
}
// Get all snapshots that are part of this protection set.
URIQueryResultList plist = new URIQueryResultList();
Constraint pconstraint = ContainmentConstraint.Factory.getProtectionSetBlockSnapshotConstraint(protectionSetId);
dbClient.queryByConstraint(pconstraint, plist);
Iterator<URI> snapshotIter = plist.iterator();
while (snapshotIter.hasNext()) {
URI snapshotId = snapshotIter.next();
BlockSnapshot snapshot = dbClient.queryObject(BlockSnapshot.class, snapshotId);
boolean deleteSnapshot = true;
if (snapshot.getInactive()) {
// Don't bother deleting or processing if the snapshot is already on its way out.
deleteSnapshot = false;
} else if (snapshot.getEmCGGroupCopyId() == null) {
// If something bad happened and we weren't able to get the site information off of the snapshot
_log.info("Found that ViPR Snapshot corresponding to RP Bookmark is missing Site information, thus not analyzing for automated deletion. " + snapshot.getId() + " - " + protectionSet.getLabel() + ":" + snapshot.getEmInternalSiteName() + ":" + snapshot.getEmName());
deleteSnapshot = false;
} else if (!bookmarkMap.getCgBookmarkMap().get(Integer.valueOf(protectionSet.getProtectionId())).isEmpty()) {
for (RPBookmark bookmark : bookmarkMap.getCgBookmarkMap().get(Integer.valueOf(protectionSet.getProtectionId()))) {
// bookmark (from RP) vs. snapshot (from ViPR)
if (snapshot.getEmName().equalsIgnoreCase(bookmark.getBookmarkName()) && snapshot.getEmCGGroupCopyId().equals(bookmark.getCGGroupCopyUID().getGlobalCopyUID().getCopyUID())) {
deleteSnapshot = false;
_log.info("Found that ViPR Snapshot corresponding to RP Bookmark still exists, thus saving in ViPR: " + snapshot.getId() + " - " + protectionSet.getLabel() + ":" + snapshot.getEmInternalSiteName() + ":" + snapshot.getEmCGGroupCopyId() + ":" + snapshot.getEmName());
}
}
} else {
// Just for debugging, otherwise useless
_log.debug("Found that ViPR Snapshot corresponding to RP Bookmark doesn't exist, thus going to delete from ViPR: " + snapshot.getId() + " - " + protectionSet.getLabel() + ":" + snapshot.getEmInternalSiteName() + ":" + snapshot.getEmCGGroupCopyId() + ":" + snapshot.getEmName());
}
if (deleteSnapshot) {
// 5. We couldn't find the bookmark, and the query for it was successful, so it's time to mark it as gone
_log.info("Found that ViPR Snapshot corresponding to RP Bookmark no longer exists, thus deleting in ViPR: " + snapshot.getId() + " - " + protectionSet.getLabel() + ":" + snapshot.getEmInternalSiteName() + ":" + snapshot.getEmCGGroupCopyId() + ":" + snapshot.getEmName());
dbClient.markForDeletion(snapshot);
}
}
} else if (protectionSet.getProtectionId() == null) {
_log.error("Can not determine the consistency group ID of protection set: " + protectionSet.getLabel() + ", can not perform any cleanup of snapshots.");
} else {
_log.info("No consistency groups were found associated with protection system: " + protectionSystem.getLabel() + ", can not perform cleanup of snapshots.");
}
}
}
use of com.emc.storageos.recoverpoint.objectmodel.RPBookmark 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);
}
use of com.emc.storageos.recoverpoint.objectmodel.RPBookmark in project coprhd-controller by CoprHD.
the class RecoverPointBookmarkManagementUtils method findRPBookmarks.
/**
* Find the bookmarks that were created for a CG
*
* @param impl - RP handle to use for RP operations
* @param rpCGset - List of CGs that had this bookmark created
* @param request - Information about the bookmark that was created on the CGs
*
* @return Map of CGs with the bookmark information (CDP and/or CRR)
*
* @throws RecoverPointException
*/
public Map<RPConsistencyGroup, Set<RPBookmark>> findRPBookmarks(FunctionalAPIImpl impl, Set<RPConsistencyGroup> rpCGSet, CreateBookmarkRequestParams request) throws RecoverPointException {
Map<RPConsistencyGroup, Set<RPBookmark>> returnMap = new HashMap<RPConsistencyGroup, Set<RPBookmark>>();
final int numRetries = 6;
final int secondsToWaitForRetry = 5;
RecoverPointCopyType rpCopyType = RecoverPointCopyType.UNKNOWN_PROTECTION;
boolean wantCDP = false;
boolean wantCRR = false;
// If rpCopyType not specified
boolean acceptAnyCopy = false;
// later.
if (rpCopyType == null || rpCopyType == RecoverPointCopyType.UNKNOWN_PROTECTION) {
acceptAnyCopy = true;
} else {
if (rpCopyType == RecoverPointCopyType.CDP_PROTECTION) {
wantCDP = true;
} else if (rpCopyType == RecoverPointCopyType.CRR_PROTECTION) {
wantCRR = true;
} else if (rpCopyType == RecoverPointCopyType.CRR_PROTECTION) {
wantCRR = true;
wantCDP = true;
}
}
boolean tooManyRetries = false;
for (RPConsistencyGroup rpCG : rpCGSet) {
if (tooManyRetries) {
// Stop trying
break;
}
for (int i = 0; i < numRetries; i++) {
logger.info(String.format("Getting event markers for CG: %s. Attempt number %d. Copy type: %s", rpCG.getName() != null ? rpCG.getName() : rpCG.getCGUID().getId(), i, rpCopyType.toString()));
Set<RPBookmark> rpEventMarkersForCG = getBookmarksForMostRecentBookmarkName(impl, request, rpCG.getCGUID());
if (rpEventMarkersForCG != null) {
if (acceptAnyCopy && (!rpEventMarkersForCG.isEmpty())) {
// We will take anything, and we found at least one event marker
returnMap.put(rpCG, rpEventMarkersForCG);
// Go to the next CG
break;
} else if ((wantCDP && wantCRR) && rpEventMarkersForCG.size() > 1) {
// Need 2 event markers for CLR
returnMap.put(rpCG, rpEventMarkersForCG);
// Go to the next CG
break;
} else if ((wantCDP && wantCRR) && rpEventMarkersForCG.size() < 2) {
logger.error("Didn't find enough bookmarks for CG: " + rpCG.getName() + ". Going to sleep and retry.");
} else if (!rpEventMarkersForCG.isEmpty()) {
// Either want CDP or CRR and we found at least 1
returnMap.put(rpCG, rpEventMarkersForCG);
// Go to the next CG
break;
} else {
logger.error("Didn't find enough bookmarks for CG: " + rpCG.getName() + ". Going to sleep and retry.");
}
} else {
// Didn't get what we wanted
logger.error("Didn't find any bookmarks for CG: " + rpCG.getName() + ". Going to sleep and retry.");
}
try {
Thread.sleep(Long.valueOf((secondsToWaitForRetry * numMillisInSecond)));
} catch (InterruptedException e) {
// NOSONAR
// It's ok to ignore this
}
}
}
if (returnMap.size() != rpCGSet.size()) {
throw RecoverPointException.exceptions.failedToFindExpectedBookmarks();
}
return returnMap;
}
use of com.emc.storageos.recoverpoint.objectmodel.RPBookmark 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);
}
Aggregations