use of com.emc.storageos.db.client.model.ProtectionSystem in project coprhd-controller by CoprHD.
the class BlockConsistencyGroupUtils method referencesNonLocalCgs.
/**
* Determines if the given BlockConsistencyGroup references any non-LOCAL storage system
* consistency groups.
*
* @param cg the BlockConsistencyGroup.
* @param dbClient the DB client references.
* @return true if the CG references any non-local CGs, false otherwise.
*/
public static boolean referencesNonLocalCgs(BlockConsistencyGroup cg, DbClient dbClient) {
List<StorageSystem> storageSystems = getVPlexStorageSystems(cg, dbClient);
List<ProtectionSystem> protectionSystems = getRPProtectionSystems(cg, dbClient);
boolean referencesVplexCgs = false;
boolean referencesRpCgs = false;
if (storageSystems != null && !storageSystems.isEmpty()) {
for (StorageSystem storageSystem : storageSystems) {
StringSet cgs = cg.getSystemConsistencyGroups().get(storageSystem.getId().toString());
if (cgs != null && !cgs.isEmpty()) {
referencesVplexCgs = true;
break;
}
}
}
if (protectionSystems != null && !protectionSystems.isEmpty()) {
for (ProtectionSystem protectionSystem : protectionSystems) {
StringSet cgs = cg.getSystemConsistencyGroups().get(protectionSystem.getId().toString());
if (cgs != null && !cgs.isEmpty()) {
referencesRpCgs = true;
break;
}
}
}
return referencesVplexCgs || referencesRpCgs;
}
use of com.emc.storageos.db.client.model.ProtectionSystem in project coprhd-controller by CoprHD.
the class ProtectionSystemAssocStorageSystemMigrationTest method verifyProtectionSystemResults.
/**
* Verifies the migration results for volumes.
*
* @throws Exception When an error occurs verifying the volume migration
* results.
*/
private void verifyProtectionSystemResults() throws Exception {
log.info("Verifying migration of ProtectionSystems.");
List<URI> protectionSystemURIs = _dbClient.queryByType(ProtectionSystem.class, false);
int count = 0;
Iterator<ProtectionSystem> protectionSystemIter = _dbClient.queryIterativeObjects(ProtectionSystem.class, protectionSystemURIs);
while (protectionSystemIter.hasNext()) {
ProtectionSystem protectionSystem = protectionSystemIter.next();
count++;
Assert.assertTrue("ProtectionSystem associated storage systems should be empty", protectionSystem.getAssociatedStorageSystems().isEmpty());
}
Assert.assertTrue("Should still have 2 ProtectionSystems after migration, not " + count, count == 2);
}
use of com.emc.storageos.db.client.model.ProtectionSystem in project coprhd-controller by CoprHD.
the class RecoverPointBlockSnapshotMigrationTest method prepareSnapData.
/**
* Prepares the data for RP BlockSnapshot migration tests.
*
* @throws Exception When an error occurs preparing the BlockSnapshot migration data.
*/
private void prepareSnapData() throws Exception {
log.info("Preparing BlockSnapshots for RecoverPointBlockSnapshotMigration");
ProtectionSystem ps = new ProtectionSystem();
URI protectionSystemUri = URIUtil.createId(ProtectionSystem.class);
ps.setId(protectionSystemUri);
_dbClient.createObject(ps);
VirtualArray targetVarray = new VirtualArray();
URI targetVarrayUri = URIUtil.createId(VirtualArray.class);
targetVarray.setId(targetVarrayUri);
_dbClient.createObject(targetVarray);
Volume targetVolume = new Volume();
URI targetVolumeUri = URIUtil.createId(Volume.class);
targetVolume.setId(targetVolumeUri);
targetVolume.setLabel("targetVolume");
targetVolume.setDeviceLabel(DEVICE_LABEL);
targetVolume.setVirtualArray(targetVarrayUri);
_dbClient.createObject(targetVolume);
Volume parentVolume = new Volume();
URI volumeUri = URIUtil.createId(Volume.class);
parentVolume.setId(volumeUri);
parentVolume.setLabel("parentVolume");
StringSet rpTargets = new StringSet();
rpTargets.add(targetVolume.getId().toString());
parentVolume.setRpTargets(rpTargets);
_dbClient.createObject(parentVolume);
BlockSnapshot snapshot = new BlockSnapshot();
snapURI = URIUtil.createId(BlockSnapshot.class);
snapshot.setId(snapURI);
snapshot.setProtectionController(protectionSystemUri);
NamedURI parentVolNamedUri = new NamedURI(parentVolume.getId(), parentVolume.getLabel());
snapshot.setParent(parentVolNamedUri);
snapshot.setVirtualArray(targetVarrayUri);
_dbClient.createObject(snapshot);
}
use of com.emc.storageos.db.client.model.ProtectionSystem in project coprhd-controller by CoprHD.
the class ProtectionAttrMatcher method matchStoragePoolsWithAttributeOn.
@Override
public List<StoragePool> matchStoragePoolsWithAttributeOn(List<StoragePool> allPools, Map<String, Object> attributeMap, StringBuffer errorMessage) {
StringMap rpMap = (StringMap) attributeMap.get(Attributes.recoverpoint_map.name());
_logger.info("Pools matching protection attributes Started {}, {} :", rpMap, Joiner.on("\t").join(getNativeGuidFromPools(allPools)));
// If protection is not specified, we can return all remaining pools.
if (rpMap == null || rpMap.isEmpty()) {
_logger.info("No protection specified, return all remaining pools.");
return allPools;
}
List<StoragePool> matchedPools = new ArrayList<StoragePool>();
Iterator<StoragePool> poolIterator = allPools.iterator();
// Check if MetroPoint has been enabled.
Boolean metroPointEnabled = (Boolean) attributeMap.get(Attributes.metropoint.toString());
boolean isRPVPlex = NullColumnValueGetter.isNotNullValue((String) attributeMap.get(Attributes.high_availability_type.toString()));
// Flag to indicate if this is an RP+VPLEX setup with HA as the Source.
boolean haAsRPSource = false;
if (isRPVPlex && (metroPointEnabled == null || !metroPointEnabled)) {
_logger.info("Not a MetroPoint Virtual Pool");
String haVarrayForRPSource = (String) attributeMap.get(Attributes.high_availability_rp.toString());
haAsRPSource = NullColumnValueGetter.isNotNullValue(haVarrayForRPSource);
if (haAsRPSource) {
_logger.info("Virtual Pool indicates to use HA as the RP Source");
// Get HA Virtual Pool
String haVpoolId = (String) attributeMap.get(Attributes.high_availability_vpool.toString());
List<StoragePool> haVpoolPoolList = new ArrayList<StoragePool>();
if (haVpoolId != null) {
VirtualPool haVpool = _objectCache.queryObject(VirtualPool.class, URI.create(haVpoolId));
haVpoolPoolList = VirtualPool.getValidStoragePools(haVpool, _objectCache.getDbClient(), true);
_logger.info(String.format("HA Virtual Pool exists [%s](%s), consider Storage Pools from it.", haVpool.getLabel(), haVpool.getId()));
} else {
_logger.info("No HA Virtual Pool exists, consider Storage Pools from main Virtual Pool.");
haVpoolPoolList.addAll(allPools);
}
List<StoragePool> filterPools = new ArrayList<StoragePool>();
_logger.info(String.format("Remove Storage Pools that are not tagged with Virtual Array (%s).", haVarrayForRPSource));
for (StoragePool haPool : haVpoolPoolList) {
if (haPool.getTaggedVirtualArrays() != null && !haPool.getTaggedVirtualArrays().contains(haVarrayForRPSource)) {
filterPools.add(haPool);
}
}
haVpoolPoolList.removeAll(filterPools);
poolIterator = haVpoolPoolList.iterator();
_logger.info("HA Storage Pools to consider: {}", Joiner.on("\t").join(getNativeGuidFromPools(haVpoolPoolList)));
}
}
boolean validProtectionSystems = false;
while (poolIterator.hasNext()) {
StoragePool storagePool = poolIterator.next();
_logger.info(String.format("Checking storage pool [%s]", storagePool.getLabel()));
// then the pool is not allowed.
if (!checkMirrorProtectionValidPool(storagePool, attributeMap)) {
_logger.info(String.format("Storage pool [%s] has a mirror attribute, " + "and the the pool doesn't fit mirror capabilities. Disregard pool.", storagePool.getLabel()));
continue;
}
// Get the RP systems for this pool.
Set<ProtectionSystem> protectionSystems = ConnectivityUtil.getProtectionSystemsForStoragePool(_objectCache.getDbClient(), storagePool, null, isRPVPlex);
// Only pools connected to an RP system can potentially match.
if (protectionSystems.isEmpty()) {
_logger.info(String.format("Storage pool [%s] not connected to any Protection System. Disregard storage pool.", storagePool.getLabel()));
continue;
} else {
validProtectionSystems = true;
}
// Scan each RP system and see if the pool is valid, given the target/copy attributes
for (ProtectionSystem ps : protectionSystems) {
// is not allowed
if (ps.getVirtualArrays() == null || ps.getVirtualArrays().isEmpty()) {
_logger.warn(String.format("Protection System [%s] has no associated virtual arrays. " + "Can not use storage pool [%s]. Please run Protection System discovery.", ps.getLabel(), storagePool.getLabel()));
continue;
}
Map<String, Boolean> validStoragePoolForProtection = new HashMap<String, Boolean>();
// of virtual arrays for this RP system. If not, move on.
for (String targetVarrayId : rpMap.keySet()) {
// Assume false to start
validStoragePoolForProtection.put(targetVarrayId, Boolean.FALSE);
// then this pool is not allowed
if (!ps.getVirtualArrays().contains(targetVarrayId)) {
_logger.info(String.format("Virtual array [%s] of Storage Pool [%s](%s) can't be seen by Protection System [%s](%s). " + "Disregard storage pool.", targetVarrayId, storagePool.getLabel(), storagePool.getId(), ps.getLabel(), ps.getId()));
continue;
}
// If the virtual pool was not specified for this target virtual array, then use the virtual pool
// we're in right now. We already know that our target virtual array is in this RP system's
// domain, so we'll say yes to this pool.
String targetVpoolId = rpMap.get(targetVarrayId);
if (NullColumnValueGetter.isNullValue(targetVpoolId)) {
_logger.info(String.format("No target virtual pool defined. Using source virtual pool. " + "Storage pool [%s](%s) allowed.", storagePool.getLabel(), storagePool.getId()));
validStoragePoolForProtection.put(targetVarrayId, Boolean.TRUE);
break;
}
VirtualPool targetVpool = _objectCache.queryObject(VirtualPool.class, URI.create(targetVpoolId));
List<StoragePool> targetPoolList = VirtualPool.getValidStoragePools(targetVpool, _objectCache.getDbClient(), true);
boolean targetVpoolSpecifiesVPlex = VirtualPool.vPoolSpecifiesHighAvailability(targetVpool);
// Protection System as the source/candidate storage pool. If so, we have a match.
for (StoragePool tgtPool : targetPoolList) {
// Only consider target storage pools for the target varray in question
if (tgtPool.getTaggedVirtualArrays() != null && tgtPool.getTaggedVirtualArrays().contains(targetVarrayId)) {
_logger.info(String.format("Checking target storage pool [%s](%s)...", tgtPool.getLabel(), tgtPool.getId()));
// Get the RP systems for this target pool
Set<ProtectionSystem> targetProtectionSystems = ConnectivityUtil.getProtectionSystemsForStoragePool(_objectCache.getDbClient(), tgtPool, URI.create(targetVarrayId), targetVpoolSpecifiesVPlex);
// Check to see if the protection systems line up between the source storage pool
// and at least one target storage pool.
boolean matchFound = false;
for (ProtectionSystem targetProtectionSystem : targetProtectionSystems) {
if (targetProtectionSystem != null && targetProtectionSystem.getId().equals(ps.getId())) {
_logger.info(String.format("Target storage pool [%s](%s) is connected to same " + "Protection system [%s](%s) as source storage pool [%s](%s). " + "Storage pool allowed.", tgtPool.getLabel(), tgtPool.getId(), ps.getLabel(), ps.getId(), storagePool.getLabel(), storagePool.getId()));
validStoragePoolForProtection.put(targetVarrayId, Boolean.TRUE);
matchFound = true;
break;
}
}
if (matchFound) {
// we found at least one match.
break;
}
}
}
}
// Iterate through the results of valid storage pools, if there are any false entries for this
// storage pool, we can not consider it.
boolean matchedPool = true;
for (Boolean validStoragePool : validStoragePoolForProtection.values()) {
if (!validStoragePool) {
matchedPool = false;
break;
}
}
if (matchedPool) {
matchedPools.add(storagePool);
} else {
_logger.info(String.format("Storage Pool [%s](%s) is not valid for protection.", storagePool.getLabel(), storagePool.getId()));
}
}
}
if (!validProtectionSystems) {
_logger.warn("No valid protection system could be found for storage pools. " + "Please check data protection systems to ensure they are not inactive or invalid.");
}
if (haAsRPSource) {
if (!matchedPools.isEmpty()) {
// If we found at least 1 matched pool using HA as the RP Source, return all pools.
matchedPools = allPools;
}
}
if (CollectionUtils.isEmpty(matchedPools)) {
errorMessage.append("No valid protection system could be found for storage pools. " + "Please check data protection systems to ensure they are not inactive or invalid. ");
}
_logger.info("Pools matching protection attributes ended. " + "Matched pools are: {}", Joiner.on("\t").join(getNativeGuidFromPools(matchedPools)));
return matchedPools;
}
use of com.emc.storageos.db.client.model.ProtectionSystem in project coprhd-controller by CoprHD.
the class VPlexDeviceController method restoreSnapshotSession.
/**
* {@inheritDoc}
*/
@Override
public void restoreSnapshotSession(URI vplexURI, URI snapSessionURI, String opId) throws InternalException {
BlockSnapshotSession snapSession = getDataObject(BlockSnapshotSession.class, snapSessionURI, _dbClient);
try {
// Generate the Workflow.
Workflow workflow = _workflowService.getNewWorkflow(this, RESTORE_SNAP_SESSION_WF_NAME, false, opId);
_log.info("Created restore snapshot session workflow with operation id {}", opId);
// Get the VPLEX volume(s) to be restored.
List<Volume> vplexVolumes = new ArrayList<Volume>();
if (!snapSession.hasConsistencyGroup()) {
// If the snap session is not in a CG, the only VPLEX
// volume to restore is the VPLEX volume using the
// snap session parent.
URI parentVolumeURI = snapSession.getParent().getURI();
URIQueryResultList queryResults = new URIQueryResultList();
_dbClient.queryByConstraint(AlternateIdConstraint.Factory.getVolumeByAssociatedVolumesConstraint(parentVolumeURI.toString()), queryResults);
vplexVolumes.add(_dbClient.queryObject(Volume.class, queryResults.iterator().next()));
} else {
BlockConsistencyGroup cg = _dbClient.queryObject(BlockConsistencyGroup.class, snapSession.getConsistencyGroup());
List<Volume> allVplexVolumesInCG = BlockConsistencyGroupUtils.getActiveVplexVolumesInCG(cg, _dbClient, null);
List<BlockObject> allVplexVolumesInRG = ControllerUtils.getAllVolumesForRGInCG(allVplexVolumesInCG, snapSession.getReplicationGroupInstance(), snapSession.getStorageController(), _dbClient);
// that are RP source volumes.
for (BlockObject vplexVolume : allVplexVolumesInRG) {
// RP target and sources restore is supported
vplexVolumes.add((Volume) vplexVolume);
}
}
// Determine the backend storage system containing the native snapshot session.
Volume firstVplexVolume = vplexVolumes.get(0);
Volume firstSnapSessionParentVolume = VPlexUtil.getVPLEXBackendVolume(firstVplexVolume, true, _dbClient);
StorageSystem snapSessionSystem = getDataObject(StorageSystem.class, firstSnapSessionParentVolume.getStorageController(), _dbClient);
// Maps Vplex volume that needs to be flushed to underlying array volume
Map<Volume, Volume> vplexToArrayVolumesToFlush = new HashMap<Volume, Volume>();
for (Volume vplexVolume : vplexVolumes) {
Volume arrayVolumeToBeRestored = VPlexUtil.getVPLEXBackendVolume(vplexVolume, true, _dbClient);
vplexToArrayVolumesToFlush.put(vplexVolume, arrayVolumeToBeRestored);
}
Map<URI, String> vplexVolumeIdToDetachStep = new HashMap<URI, String>();
boolean isRP = firstVplexVolume.checkForRp();
if (null == firstVplexVolume.getAssociatedVolumes() || firstVplexVolume.getAssociatedVolumes().isEmpty()) {
_log.error("VPLEX volume {} has no backend volumes.", firstVplexVolume.forDisplay());
throw InternalServerErrorException.internalServerErrors.noAssociatedVolumesForVPLEXVolume(firstVplexVolume.forDisplay());
}
boolean isDistributed = firstVplexVolume.getAssociatedVolumes().size() > 1;
String waitFor = null;
if (isRP && isDistributed) {
ProtectionSystem rpSystem = getDataObject(ProtectionSystem.class, firstVplexVolume.getProtectionController(), _dbClient);
// Create the pre restore step which will be the first step executed
// in the workflow.
createWorkflowStepForDeleteReplicationSet(workflow, rpSystem, vplexVolumes, null);
}
// Generate pre restore steps
waitFor = addPreRestoreResyncSteps(workflow, vplexToArrayVolumesToFlush, vplexVolumeIdToDetachStep, waitFor);
// Now create a workflow step to natively restore the backend
// volume. We execute this after the invalidate cache.
createWorkflowStepForRestoreNativeSnapshotSession(workflow, snapSessionSystem, snapSessionURI, waitFor, rollbackMethodNullMethod());
// Generate post restore steps
waitFor = addPostRestoreResyncSteps(workflow, vplexToArrayVolumesToFlush, vplexVolumeIdToDetachStep, waitFor);
if (isRP && isDistributed) {
ProtectionSystem rpSystem = getDataObject(ProtectionSystem.class, firstVplexVolume.getProtectionController(), _dbClient);
// Create the post restore step, which will be the last step executed
// in the workflow after the volume shave been rebuilt.
waitFor = createWorkflowStepForRecreateReplicationSet(workflow, rpSystem, vplexVolumes, waitFor);
}
// Execute the workflow.
_log.info("Executing workflow plan");
TaskCompleter completer = new BlockSnapshotSessionRestoreWorkflowCompleter(snapSessionURI, Boolean.TRUE, opId);
String successMsg = String.format("Restore VPLEX volume(s) from snapshot session %s" + "completed successfully", snapSessionURI);
workflow.executePlan(completer, successMsg);
_log.info("Workflow plan executing");
} catch (Exception e) {
String failMsg = String.format("Restore VPLEX volume from snapshot session %s failed", snapSessionURI);
_log.error(failMsg, e);
TaskCompleter completer = new BlockSnapshotSessionRestoreWorkflowCompleter(snapSessionURI, Boolean.TRUE, opId);
ServiceError serviceError = VPlexApiException.errors.restoreVolumeFailed(snapSessionURI.toString(), e);
failStep(completer, opId, serviceError);
}
}
Aggregations