use of com.emc.storageos.recoverpoint.impl.RecoverPointClient in project coprhd-controller by CoprHD.
the class RPHelper method getRPBookmarks.
/**
* For an RP configuration, get all RP bookmarks for the CGs provided
*
* @param system RP system
* @param cgIDs IDs of the consistency groups to get the bookmarks
* @return command result object, object list [0] has GetBookmarksResponse
* @throws RecoverPointException
*/
private static BiosCommandResult getRPBookmarks(ProtectionSystem system, Set<Integer> cgIDs) throws RecoverPointException {
_log.info("getRPBookmarks {} - start", system.getId());
RecoverPointClient rp = RPHelper.getRecoverPointClient(system);
GetBookmarksResponse bookmarkResponse = rp.getRPBookmarks(cgIDs);
_log.info("getRPBookmarks {} - complete", system.getId());
BiosCommandResult result = BiosCommandResult.createSuccessfulResult();
List<Object> returnList = new ArrayList<Object>();
returnList.add(bookmarkResponse);
result.setObjectList(returnList);
return result;
}
use of com.emc.storageos.recoverpoint.impl.RecoverPointClient in project coprhd-controller by CoprHD.
the class RPUnManagedObjectDiscoverer method discoverUnManagedObjects.
/**
* Discovers the RP CGs and all the volumes therein. It updates/creates the UnManagedProtectionSet
* objects and updates (if it exists) the UnManagedVolume objects with RP information needed for
* ingestion
*
* @param accessProfile access profile
* @param dbClient db client
* @param partitionManager partition manager
* @throws Exception
*/
public void discoverUnManagedObjects(AccessProfile accessProfile, DbClient dbClient, PartitionManager partitionManager) throws Exception {
this.partitionManager = partitionManager;
log.info("Started discovery of UnManagedVolumes for system {}", accessProfile.getSystemId());
ProtectionSystem protectionSystem = dbClient.queryObject(ProtectionSystem.class, accessProfile.getSystemId());
if (protectionSystem == null) {
log.error("Discovery is not run! Protection System not found: " + accessProfile.getSystemId());
return;
}
RecoverPointClient rp = RPHelper.getRecoverPointClient(protectionSystem);
unManagedCGsInsert = new ArrayList<UnManagedProtectionSet>();
unManagedCGsUpdate = new ArrayList<UnManagedProtectionSet>();
unManagedVolumesToDelete = new ArrayList<UnManagedVolume>();
unManagedVolumesToUpdateByWwn = new HashMap<String, UnManagedVolume>();
unManagedCGsReturnedFromProvider = new HashSet<URI>();
// Get all of the consistency groups (and their volumes) from RP
Set<GetCGsResponse> cgs = rp.getAllCGs();
if (cgs == null) {
log.warn("No CGs were found on protection system: " + protectionSystem.getLabel());
return;
}
// This section of code allows us to cache XIO native GUID to workaround an issue
// with RP's understanding of XIO volume WWNs (128-bit) and the rest of the world's
// understanding of the XIO volume WWN once it's exported (64-bit)
Map<String, String> rpWwnToNativeWwn = new HashMap<String, String>();
List<URI> storageSystemIds = dbClient.queryByType(StorageSystem.class, true);
List<String> storageNativeIdPrefixes = new ArrayList<String>();
if (storageSystemIds != null) {
Iterator<StorageSystem> storageSystemsItr = dbClient.queryIterativeObjects(StorageSystem.class, storageSystemIds);
while (storageSystemsItr.hasNext()) {
StorageSystem storageSystem = storageSystemsItr.next();
if (storageSystem.getSystemType().equalsIgnoreCase(Type.xtremio.name())) {
storageNativeIdPrefixes.add(storageSystem.getNativeGuid());
}
}
}
for (GetCGsResponse cg : cgs) {
try {
log.info("Processing returned CG: " + cg.getCgName());
boolean newCG = false;
// UnManagedProtectionSet native GUID is protection system GUID + consistency group ID
String nativeGuid = protectionSystem.getNativeGuid() + Constants.PLUS + cg.getCgId();
// First check to see if this protection set is already part of our managed DB
if (null != DiscoveryUtils.checkProtectionSetExistsInDB(dbClient, nativeGuid)) {
log.info("Protection Set " + nativeGuid + " already is managed by ViPR, skipping unmanaged discovery");
continue;
}
// Now check to see if the unmanaged CG exists in the database
UnManagedProtectionSet unManagedProtectionSet = DiscoveryUtils.checkUnManagedProtectionSetExistsInDB(dbClient, nativeGuid);
if (null == unManagedProtectionSet) {
log.info("Creating new unmanaged protection set for CG: " + cg.getCgName());
unManagedProtectionSet = new UnManagedProtectionSet();
unManagedProtectionSet.setId(URIUtil.createId(UnManagedProtectionSet.class));
unManagedProtectionSet.setNativeGuid(nativeGuid);
unManagedProtectionSet.setProtectionSystemUri(protectionSystem.getId());
StringSet protectionId = new StringSet();
protectionId.add("" + cg.getCgId());
unManagedProtectionSet.putCGInfo(SupportedCGInformation.PROTECTION_ID.toString(), protectionId);
// Default MP to false until proven otherwise
unManagedProtectionSet.getCGCharacteristics().put(UnManagedProtectionSet.SupportedCGCharacteristics.IS_MP.name(), Boolean.FALSE.toString());
newCG = true;
} else {
log.info("Found existing unmanaged protection set for CG: " + cg.getCgName() + ", using " + unManagedProtectionSet.getId().toString());
}
unManagedCGsReturnedFromProvider.add(unManagedProtectionSet.getId());
// Update the fields for the CG
unManagedProtectionSet.setCgName(cg.getCgName());
unManagedProtectionSet.setLabel(cg.getCgName());
// Indicate whether the CG is in a healthy state or not to ingest.
unManagedProtectionSet.getCGCharacteristics().put(UnManagedProtectionSet.SupportedCGCharacteristics.IS_HEALTHY.name(), cg.getCgState().equals(GetCGStateResponse.HEALTHY) ? Boolean.TRUE.toString() : Boolean.FALSE.toString());
// Indicate whether the CG is sync or async
unManagedProtectionSet.getCGCharacteristics().put(UnManagedProtectionSet.SupportedCGCharacteristics.IS_SYNC.name(), cg.getCgPolicy().synchronous ? Boolean.TRUE.toString() : Boolean.FALSE.toString());
// Fill in RPO type and value information
StringSet rpoType = new StringSet();
rpoType.add(cg.getCgPolicy().rpoType);
unManagedProtectionSet.putCGInfo(SupportedCGInformation.RPO_TYPE.toString(), rpoType);
StringSet rpoValue = new StringSet();
rpoValue.add(cg.getCgPolicy().rpoValue.toString());
unManagedProtectionSet.putCGInfo(SupportedCGInformation.RPO_VALUE.toString(), rpoValue);
if (null == cg.getCopies()) {
log.info("Protection Set " + nativeGuid + " does not contain any copies. Skipping...");
continue;
}
if (null == cg.getRsets()) {
log.info("Protection Set " + nativeGuid + " does not contain any replication sets. Skipping...");
continue;
}
// clean up the existing journal and replicationsets info in the unmanaged protection set, so that updated info is populated
if (!newCG) {
cleanUpUnManagedResources(unManagedProtectionSet, unManagedVolumesToUpdateByWwn, dbClient);
}
// Now map UnManagedVolume objects to the journal and rset (sources/targets) and put RP fields in them
Map<String, String> rpCopyAccessStateMap = new HashMap<String, String>();
mapCgJournals(unManagedProtectionSet, cg, rpCopyAccessStateMap, rpWwnToNativeWwn, storageNativeIdPrefixes, dbClient);
mapCgSourceAndTargets(unManagedProtectionSet, cg, rpCopyAccessStateMap, rpWwnToNativeWwn, storageNativeIdPrefixes, dbClient);
if (newCG) {
unManagedCGsInsert.add(unManagedProtectionSet);
} else {
unManagedCGsUpdate.add(unManagedProtectionSet);
}
} catch (Exception ex) {
log.error("Error processing RP CG {}", cg.getCgName(), ex);
}
}
handlePersistence(dbClient, false);
cleanUp(protectionSystem, dbClient);
}
use of com.emc.storageos.recoverpoint.impl.RecoverPointClient in project coprhd-controller by CoprHD.
the class RPCommunicationInterface method discoverProtectionSet.
/**
* Discover a single protection set.
*
* @param protectionSystem protection system
* @param protectionSetId protection set
* @throws RecoverPointException
*/
private void discoverProtectionSet(ProtectionSystem protectionSystem, URI protectionSetId) throws RecoverPointException {
ProtectionSet protectionSet = _dbClient.queryObject(ProtectionSet.class, protectionSetId);
if (protectionSet == null || protectionSet.getInactive()) {
return;
}
List<String> staleVolumes = new ArrayList<String>();
StringSet protectionVolumes = protectionSet.getVolumes();
RecoverPointVolumeProtectionInfo protectionVolume = null;
RecoverPointClient rp = RPHelper.getRecoverPointClient(protectionSystem);
boolean changed = false;
_log.info("ProtectionSet discover in the RPDeviceController called for protection set: " + protectionSet.getLabel());
for (String volume : protectionVolumes) {
Volume protectionVolumeWWN = _dbClient.queryObject(Volume.class, URI.create(volume));
if (protectionVolumeWWN == null || protectionVolumeWWN.getInactive()) {
staleVolumes.add(volume);
continue;
}
try {
protectionVolume = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(protectionVolumeWWN.getId(), _dbClient));
} catch (RecoverPointException re) {
StringBuffer errMsgBuilder = new StringBuffer();
String msg = "Discovery of protection set failed. Protection system: " + protectionSystem.getId() + ", ";
errMsgBuilder.append(msg);
errMsgBuilder.append(re.getMessage());
_log.warn(errMsgBuilder.toString());
}
if (protectionVolume == null) {
continue;
}
// If the volume is a source volume, let's check to see if the personality changed.
if ((!changed) && (((protectionVolume.getRpVolumeCurrentProtectionStatus() == RecoverPointVolumeProtectionInfo.volumeProtectionStatus.PROTECTED_SOURCE) && (protectionVolumeWWN.getPersonality().equalsIgnoreCase(Volume.PersonalityTypes.TARGET.toString())))) || ((protectionVolume.getRpVolumeCurrentProtectionStatus() == RecoverPointVolumeProtectionInfo.volumeProtectionStatus.PROTECTED_TARGET) && (protectionVolumeWWN.getPersonality().equalsIgnoreCase(Volume.PersonalityTypes.SOURCE.toString())))) {
_log.info("Changing personality of volume {} due to RP condition on consistency group", protectionVolumeWWN.getLabel());
updatePostFailoverPersonalities(protectionVolumeWWN);
changed = true;
}
if (protectionVolume.getRpVolumeCurrentProtectionStatus() == RecoverPointVolumeProtectionInfo.volumeProtectionStatus.PROTECTED_SOURCE) {
switch(rp.getCGState(protectionVolume)) {
case DELETED:
protectionSet.setProtectionStatus(ProtectionStatus.DELETED.toString());
break;
case STOPPED:
protectionSet.setProtectionStatus(ProtectionStatus.DISABLED.toString());
break;
case PAUSED:
protectionSet.setProtectionStatus(ProtectionStatus.PAUSED.toString());
break;
case MIXED:
protectionSet.setProtectionStatus(ProtectionStatus.MIXED.toString());
break;
case READY:
protectionSet.setProtectionStatus(ProtectionStatus.ENABLED.toString());
break;
}
_dbClient.updateObject(protectionSet);
break;
}
}
// remove stale entries from protection set
if (!staleVolumes.isEmpty()) {
_log.info(String.format("ProtectionSet %s references at least one volume id that no longer exist in the database. Removing all stale volume references: %s", protectionSet.getLabel(), String.join(",", staleVolumes)));
protectionSet.getVolumes().removeAll(staleVolumes);
_dbClient.updateObject(protectionSet);
}
}
use of com.emc.storageos.recoverpoint.impl.RecoverPointClient in project coprhd-controller by CoprHD.
the class RPCommunicationInterface method discoverVisibleStorageSystems.
/**
* Discovers the Storage Systems associated to the Protection System.
*
* @param protectionSystem A reference to the Protection System
*/
private void discoverVisibleStorageSystems(ProtectionSystem protectionSystem) {
RecoverPointClient rp = RPHelper.getRecoverPointClient(protectionSystem);
Map<String, Set<String>> siteStorageSystems = rp.getArraysForClusters();
if (protectionSystem.getSiteVisibleStorageArrays() != null) {
protectionSystem.getSiteVisibleStorageArrays().clear();
} else {
protectionSystem.setSiteVisibleStorageArrays(new StringSetMap());
}
List<URI> storageSystemIDs = _dbClient.queryByType(StorageSystem.class, true);
if (storageSystemIDs == null) {
return;
}
List<StorageSystem> storageSystems = _dbClient.queryObject(StorageSystem.class, storageSystemIDs);
if (storageSystems == null) {
return;
}
// (for the arrays ViPR knows about)
if (siteStorageSystems != null) {
for (Map.Entry<String, Set<String>> clusterEntry : siteStorageSystems.entrySet()) {
if (clusterEntry.getValue() == null || clusterEntry.getValue().isEmpty()) {
continue;
}
for (String serialNumber : clusterEntry.getValue()) {
if (serialNumber == null || serialNumber.isEmpty()) {
continue;
}
// Find the storage system ID associated with this serial number
// We have a serial number from the RP appliances, and for the most part, that works
// with a Constraint Query, but in the case of VPLEX, the serial number object for distributed
// VPLEX clusters will contain two serial numbers, not just one. So we need a long-form
// way of finding those VPLEXs as well.
Iterator<StorageSystem> activeSystemListItr = storageSystems.iterator();
StorageSystem foundStorageSystem = null;
while (activeSystemListItr.hasNext() && foundStorageSystem == null) {
StorageSystem system = activeSystemListItr.next();
if (NullColumnValueGetter.isNotNullValue(system.getSerialNumber()) && system.getSerialNumber().contains(serialNumber)) {
foundStorageSystem = system;
}
}
if (foundStorageSystem != null) {
protectionSystem.addSiteVisibleStorageArrayEntry(clusterEntry.getKey(), serialNumber);
_log.info(String.format("RP Discovery found RP cluster %s is configured to use a registered storage system: %s, %s", clusterEntry.getKey(), serialNumber, foundStorageSystem.getNativeGuid()));
} else {
_log.info(String.format("RP Discovery found RP cluster %s is configured to use a storage system: %s, but it is not configured for use in ViPR", clusterEntry.getKey(), serialNumber));
}
}
}
}
_dbClient.persistObject(protectionSystem);
}
use of com.emc.storageos.recoverpoint.impl.RecoverPointClient in project coprhd-controller by CoprHD.
the class RecoverPointClientFactory method getClient.
/**
* Static method to manage Recover Point connections via the RecoverPointClient class.
*
* When a valid connection is created the RecoverPointClient object is kept in a ConcurrentHashMap
* and referenced by a unique key combination comprised of the endpoint + username + password.
*
* If a connection key exists, a handle to an existing RecoverPointClient object will
* be returned instead of creating a brand new connection. Otherwise, a new connection will be created
* and stored (if valid).
*
* If the connection info is invalid, an exception will be thrown and the object will not be stored.
*
* The method can potentially be called by multiple threads, therefore synchronization is required
* to maintain thread safety. ConcurrentHashMap is, by default, thread safe which is why
* it is being used to store valid connections.
*
* @param protectionSystem for a unique key, if we connect using a secondary address, keep using that address.
* @param endpoints URI to the RecoverPoint System
* @param username Username to log into the RecoverPoint System
* @param password Password to log into the RecoverPoint System
*
* @return RecoverPointClient with a connection to the RPA.
* @throws RecoverPointException
*/
public static synchronized RecoverPointClient getClient(URI protectionSystem, List<URI> endpoints, String username, String password) throws RecoverPointException {
logger.info("Attempting to get RecoverPointClient connection...");
// Throw an exception if null credentials are passed in.
if (endpoints == null || username == null || password == null) {
throw RecoverPointException.exceptions.invalidCrendentialsPassedIn(username, password);
}
// Unique key to identify RP connections for different Protection Systems
String key = String.valueOf(protectionSystem) + username + password;
// See if there is an existing valid RecoverPointClient using the protection system key
RecoverPointClient existingClient = clientMap.get(key);
if (existingClient != null) {
logger.info("Existing RecoverPointClient connection found. Re-using connection: " + existingClient.getEndpoint().toString());
try {
// Do a ping check. If this fails, try the other IP addresses.
existingClient.ping();
return existingClient;
} catch (Exception e) {
logger.error("Received " + e.toString() + ". Failed to ping Mgmt IP: " + existingClient.getEndpoint().toString() + ", Cause: " + RecoverPointClient.getCause(e));
// remove the protection system's connection from the factory, and the endpoint from the endpoints list
clientMap.remove(key);
endpoints.remove(existingClient.getEndpoint());
}
}
// Now go through the endpoints and try to create a new RP client connection.
Iterator<URI> endpointIter = endpoints.iterator();
while (endpointIter.hasNext()) {
URI endpoint = endpointIter.next();
// Throw an exception if the endpoint can not be resolved to an ASCII string
String mgmtIPAddress = endpoint.toASCIIString();
if (mgmtIPAddress == null) {
throw RecoverPointException.exceptions.noRecoverPointEndpoint();
}
logger.info("Creating new RecoverPointClient connection to: " + mgmtIPAddress);
// If we don't have an existing RecoverPointClient, create a new one and add it to the client map only
// if the connection is valid.
RecoverPointClient newRecoverpointClient = new RecoverPointClient(endpoint, username, password);
FunctionalAPIImpl impl = null;
try {
// Create the connection
impl = new RecoverPointConnection().connect(endpoint, username, password);
logger.info("New RecoverPointClient connection created to: " + mgmtIPAddress);
// Add the new RecoverPointConnection to the RecoverPointClient
newRecoverpointClient.setFunctionalAPI(impl);
// We just connected but to be safe, lets do a quick ping to confirm that
// we can reach the new RecoverPoint client
newRecoverpointClient.ping();
// Update the client map
clientMap.put(key, newRecoverpointClient);
return newRecoverpointClient;
} catch (Exception e) {
logger.error("Received " + e.toString() + ". Failed to create new RP connection: " + endpoint.toString() + ", Cause: " + RecoverPointClient.getCause(e));
// Remove invalid entry
clientMap.remove(key);
if (endpointIter.hasNext()) {
logger.info("Trying a different IP address to contact RP...");
} else {
throw RecoverPointException.exceptions.failedToPingMgmtIP(mgmtIPAddress, RecoverPointClient.getCause(e));
}
}
}
// You'll never get here.
return null;
}
Aggregations