use of com.emc.storageos.db.client.model.ProtectionSet in project coprhd-controller by CoprHD.
the class BlockService method queryProtectionSetResource.
/**
* queryResource(), but for protection set.
*
* @param id
* the URN of a ViPR ID of protection set
* @return protection set object
*/
private ProtectionSet queryProtectionSetResource(URI id) {
if (id == null) {
return null;
}
ProtectionSet ret = _permissionsHelper.getObjectById(id, ProtectionSet.class);
ArgValidator.checkEntityNotNull(ret, id, isIdEmbeddedInURL(id));
return ret;
}
use of com.emc.storageos.db.client.model.ProtectionSet in project coprhd-controller by CoprHD.
the class RPDeviceController method updatePostFailover.
/**
* After a failover, we need to set specific flags
*
* @param id
* volume we failed over to
* @throws InternalException
*/
private void updatePostFailover(Volume volume) throws InternalException {
_log.info("Setting respective flags after failover");
ProtectionSet protectionSet = _dbClient.queryObject(ProtectionSet.class, volume.getProtectionSet());
List<URI> volumeIDs = new ArrayList<URI>();
for (String volumeString : protectionSet.getVolumes()) {
URI volumeURI;
try {
volumeURI = new URI(volumeString);
volumeIDs.add(volumeURI);
} catch (URISyntaxException e) {
_log.error("URI syntax incorrect: ", e);
}
}
for (URI protectionVolumeID : volumeIDs) {
Volume protectionVolume = _dbClient.queryObject(Volume.class, protectionVolumeID);
if (protectionVolume == null || protectionVolume.getInactive()) {
continue;
}
if ((protectionVolume.checkPersonality(Volume.PersonalityTypes.TARGET.toString())) && (protectionVolume.getRpCopyName().equals(volume.getRpCopyName()))) {
_log.info("Change flags of failover target " + RPHelper.getRPWWn(protectionVolume.getId(), _dbClient));
protectionVolume.setAccessState(Volume.VolumeAccessState.READWRITE.name());
protectionVolume.setLinkStatus(Volume.LinkStatus.FAILED_OVER.name());
_dbClient.updateObject(protectionVolume);
} else if (protectionVolume.checkPersonality(Volume.PersonalityTypes.SOURCE.toString())) {
_log.info("Change flags of failover source " + RPHelper.getRPWWn(protectionVolume.getId(), _dbClient));
protectionVolume.setLinkStatus(Volume.LinkStatus.FAILED_OVER.name());
_dbClient.updateObject(protectionVolume);
}
}
}
use of com.emc.storageos.db.client.model.ProtectionSet in project coprhd-controller by CoprHD.
the class RPDeviceController method setProtectionSetStatus.
private void setProtectionSetStatus(RecoverPointVolumeProtectionInfo volumeProtectionInfo, String protectionSetStatus, ProtectionSystem system) {
//
if (volumeProtectionInfo.getRpVolumeCurrentProtectionStatus() == RecoverPointVolumeProtectionInfo.volumeProtectionStatus.PROTECTED_SOURCE) {
URIQueryResultList list = new URIQueryResultList();
Constraint constraint = ContainmentConstraint.Factory.getProtectionSystemProtectionSetConstraint(system.getId());
try {
_dbClient.queryByConstraint(constraint, list);
Iterator<URI> it = list.iterator();
while (it.hasNext()) {
URI protectionSetId = it.next();
_log.info("Check protection set ID: " + protectionSetId);
ProtectionSet protectionSet;
protectionSet = _dbClient.queryObject(ProtectionSet.class, protectionSetId);
if (protectionSet.getInactive() == false) {
_log.info("Change the status to: " + protectionSetStatus);
protectionSet.setProtectionStatus(protectionSetStatus);
_dbClient.updateObject(protectionSet);
break;
}
}
} catch (DatabaseException e) {
// Don't worry about this
}
} else {
_log.info("Did not pause the protection source. Not updating protection status");
}
}
use of com.emc.storageos.db.client.model.ProtectionSet in project coprhd-controller by CoprHD.
the class RPDeviceController method createProtectionSet.
/**
* Create a protection set in the database that corresponds to this CG.
*
* @param params
* CG params object
* @param cgId
* @throws InternalException
*/
private ProtectionSet createProtectionSet(ProtectionSystem rpSystem, CGRequestParams params, Long cgId) throws InternalException {
ProtectionSet protectionSet = new ProtectionSet();
protectionSet.setProtectionSystem(rpSystem.getId());
protectionSet.setLabel(params.getCgName());
protectionSet.setNativeGuid(rpSystem.getNativeGuid() + Constants.PLUS + cgId);
protectionSet.setProtectionStatus(ProtectionStatus.ENABLED.toString());
protectionSet.setProtectionId(cgId.toString());
protectionSet.setId(URIUtil.createId(ProtectionSet.class));
_dbClient.createObject(protectionSet);
protectionSet = updateProtectionSet(protectionSet, params);
return protectionSet;
}
use of com.emc.storageos.db.client.model.ProtectionSet in project coprhd-controller by CoprHD.
the class RPDeviceController method cgDeleteStep.
/**
* The step that deletes the CG from the RecoverPoint appliance if all of the volumeIDs are in the request,
* otherwise delete replication sets and associated journals.
*
* @param rpSystem
* protection system
* @param volumeIDs
* volume IDs
* @param journalVolumeIDs
* Volume IDs of journals
* @param token
* task ID
* @return true if successful
* @throws ControllerException
*/
public boolean cgDeleteStep(URI rpSystem, List<URI> volumeIDs, List<URI> journalVolumeIDs, String token) throws ControllerException {
WorkflowStepCompleter.stepExecuting(token);
_log.info("cgDeleteStep is running");
boolean lockException = false;
try {
// Validate input arguments
if (rpSystem == null) {
_log.error("Protection system not sent into cgDeleteStep");
throw DeviceControllerExceptions.recoverpoint.cgDeleteStepInvalidParam("protection system URI");
}
ProtectionSystem system = _dbClient.queryObject(ProtectionSystem.class, rpSystem);
if (system == null) {
_log.error("Protection system not in database");
throw DeviceControllerExceptions.recoverpoint.cgDeleteStepInvalidParam("protection system null");
}
if (system.getInactive()) {
_log.error("Protection system set to be deleted");
throw DeviceControllerExceptions.recoverpoint.cgDeleteStepInvalidParam("protection system deleted");
}
if (volumeIDs == null) {
_log.error("Volume IDs list is null");
throw DeviceControllerExceptions.recoverpoint.cgDeleteStepInvalidParam("volume IDs null");
}
if (volumeIDs.isEmpty()) {
_log.error("Volume IDs list is empty");
throw DeviceControllerExceptions.recoverpoint.cgDeleteStepInvalidParam("volume IDs empty");
}
List<Volume> volumes = _dbClient.queryObject(Volume.class, volumeIDs);
if (volumes.isEmpty()) {
_log.info("All volumes already deleted. Not performing RP CG operation");
WorkflowStepCompleter.stepSucceded(token);
return true;
}
BlockConsistencyGroup cg = _dbClient.queryObject(BlockConsistencyGroup.class, volumes.get(0).getConsistencyGroup());
// lock around create and delete operations on the same CG
List<String> lockKeys = new ArrayList<String>();
lockKeys.add(ControllerLockingUtil.getConsistencyGroupStorageKey(_dbClient, cg.getId(), system.getId()));
boolean lockAcquired = _workflowService.acquireWorkflowLocks(_workflowService.getWorkflowFromStepId(token), lockKeys, LockTimeoutValue.get(LockType.RP_CG));
if (!lockAcquired) {
lockException = true;
throw DeviceControllerException.exceptions.failedToAcquireLock(lockKeys.toString(), String.format("Delete or remove volumes from RP consistency group %s", cg.getCgNameOnStorageSystem(rpSystem)));
}
// Validate that all volumes belong to the same BlockConsistencyGroup
for (Volume volume : volumes) {
if (!volume.getConsistencyGroup().equals(cg.getId())) {
_log.error("Not all volumes belong to the same consistency group.");
throw DeviceControllerExceptions.recoverpoint.cgDeleteStepInvalidParam("volumes from different consistency groups");
}
}
// Find a valid protection set reference so we can cleanup the protection set later.
ProtectionSet protectionSet = null;
for (Volume volume : volumes) {
if (!NullColumnValueGetter.isNullNamedURI(volume.getProtectionSet())) {
protectionSet = _dbClient.queryObject(ProtectionSet.class, volume.getProtectionSet());
break;
}
}
RecoverPointClient rp = RPHelper.getRecoverPointClient(system);
// Validate that we found the protection info for each volume.
RecoverPointVolumeProtectionInfo volumeProtectionInfo = null;
for (Volume volume : volumes) {
try {
if (volumeProtectionInfo == null) {
volumeProtectionInfo = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(volume.getId(), _dbClient));
VirtualPool virtualPool = _dbClient.queryObject(VirtualPool.class, volume.getVirtualPool());
volumeProtectionInfo.setMetroPoint(VirtualPool.vPoolSpecifiesMetroPoint(virtualPool));
}
} catch (Exception e) {
// Do nothing. If we cannot find volume protection info for a volume, we do not want that
// exception preventing us from trying to find it for other volumes being deleted.
_log.warn("Looks like the volume(s) we're trying to remove from the RP appliance are no longer associated with a RP CG, continuing delete process.");
}
}
// is nothing in RP we need to cleanup.
if (volumeProtectionInfo == null) {
_log.warn("Looks like the volume(s) we're trying to remove from the RP appliance are no longer associated with a RP CG, continuing delete process.");
WorkflowStepCompleter.stepSucceded(token);
return true;
}
if (RPHelper.cgSourceVolumesContainsAll(_dbClient, cg.getId(), volumeIDs)) {
// We are deleting all source volumes in the consistency group so we can delete the
// RecoverPoint CG as well.
rp.deleteCG(volumeProtectionInfo);
// We want to reflect the CG being deleted in the BlockConsistencyGroup
if (volumeIDs != null && !volumeIDs.isEmpty()) {
// Get the CG URI from the first volume
Volume vol = _dbClient.queryObject(Volume.class, volumeIDs.get(0));
if (vol.getConsistencyGroup() != null) {
cleanUpRPCG(system.getId(), vol.getConsistencyGroup());
}
if (protectionSet == null || protectionSet.getInactive() || protectionSet.getVolumes() == null || protectionSet.getVolumes().isEmpty()) {
_log.info("Cleanup unnecessary as protection set in ViPR is empty or has already been marked for deletion.");
} else {
_log.info("Removing all volume from protection set: " + protectionSet.getLabel());
// Remove all volumes in the ProtectionSet and mark for deletion
List<String> removeVolumeIDs = new ArrayList<String>(protectionSet.getVolumes());
cleanupProtectionSetVolumes(protectionSet, removeVolumeIDs, true);
}
}
setProtectionSetStatus(volumeProtectionInfo, ProtectionStatus.DISABLED.toString(), system);
} else {
List<RecoverPointVolumeProtectionInfo> replicationSetsToRemove = new ArrayList<RecoverPointVolumeProtectionInfo>();
List<String> removeVolumeIDs = new ArrayList<String>();
for (Volume volume : volumes) {
_log.info(String.format("Volume [%s] (%s) needs to have its replication set removed from RP", volume.getLabel(), volume.getId()));
// Delete the replication set if there are more volumes (other replication sets).
// If there are no other replications sets we will simply delete the CG instead.
volumeProtectionInfo = rp.getProtectionInfoForVolume(RPHelper.getRPWWn(volume.getId(), _dbClient));
// Volume Info to give RP to clean up the RSets
replicationSetsToRemove.add(volumeProtectionInfo);
// Source volume to be removed from Protection Set
if (!NullColumnValueGetter.isNullURI(volume.getId())) {
removeVolumeIDs.add(volume.getId().toString());
}
// All Target volumes to be removed from Protection Set
List<Volume> targetVolumes = RPHelper.getTargetVolumes(volume, _dbClient);
for (Volume targetVol : targetVolumes) {
removeVolumeIDs.add(targetVol.getId().toString());
}
}
// Remove the Replication Sets from RP.
// Wait for a min before attempting to delete the rsets.
// RP has not yet synced up with the fact that new rsets were added and we attempted to delete them
// because the rollback
// started.
// This delay helps in RP catching up before we issue another command.
_log.info("waiting for 1 min before deleting replication sets");
Thread.sleep(1000 * 60);
rp.deleteReplicationSets(replicationSetsToRemove);
// Remove any journal volumes that were added in this operation. Otherwise CG ends up in a weird state.
if (journalVolumeIDs.isEmpty()) {
_log.info("There are no journal volumes to be deleted");
} else {
List<Volume> journalVolumes = _dbClient.queryObject(Volume.class, journalVolumeIDs);
for (Volume journalVolume : journalVolumes) {
String journalWWN = RPHelper.getRPWWn(journalVolume.getId(), _dbClient);
_log.info(String.format("Removing Journal volume - %s : WWN - %s", journalVolume.getLabel(), journalWWN));
volumeProtectionInfo = rp.getProtectionInfoForVolume(journalWWN);
rp.deleteJournalFromCopy(volumeProtectionInfo, journalWWN);
removeVolumeIDs.add(journalVolume.getId().toString());
}
}
// Cleanup the ViPR Protection Set
cleanupProtectionSetVolumes(protectionSet, removeVolumeIDs, false);
}
WorkflowStepCompleter.stepSucceded(token);
_log.info("cgDeleteStep is complete");
// collect and update the protection system statistics to account for
// the CG that has been removed
_log.info("Collection RP statistics post CG delete.");
// Collect stats, even if we didn't delete the CG, because the volume count in the CG will go down.
collectRPStatistics(system);
} catch (Exception e) {
if (lockException) {
ServiceError serviceError = DeviceControllerException.errors.deleteVolumesAborted(volumeIDs.toString(), e);
return stepFailed(token, serviceError, "cgDeleteStep");
} else {
return stepFailed(token, e, "cgDeleteStep");
}
}
return true;
}
Aggregations