use of com.emc.storageos.db.client.model.ProtectionSystem in project coprhd-controller by CoprHD.
the class RPDeviceController method cgCreateStep.
/**
* Workflow step method for creating/updating a consistency group.
*
* @param rpSystemId
* RP system Id
* @param recommendation
* parameters needed to create the CG
* @param token
* the task
* @return
* @throws InternalException
*/
public boolean cgCreateStep(URI rpSystemId, List<VolumeDescriptor> volumeDescriptors, String token) throws InternalException {
RecoverPointClient rp;
CGRequestParams cgParams = null;
boolean metropoint = false;
boolean lockException = false;
try {
// Get only the RP volumes from the descriptors.
List<VolumeDescriptor> sourceVolumeDescriptors = VolumeDescriptor.filterByType(volumeDescriptors, new VolumeDescriptor.Type[] { VolumeDescriptor.Type.RP_SOURCE, VolumeDescriptor.Type.RP_EXISTING_SOURCE, VolumeDescriptor.Type.RP_VPLEX_VIRT_SOURCE }, new VolumeDescriptor.Type[] {});
WorkflowStepCompleter.stepExecuting(token);
ProtectionSystem rpSystem = _dbClient.queryObject(ProtectionSystem.class, rpSystemId);
URI cgId = volumeDescriptors.iterator().next().getCapabilitiesValues().getBlockConsistencyGroup();
boolean attachAsClean = true;
for (VolumeDescriptor sourceVolumedescriptor : sourceVolumeDescriptors) {
Volume sourceVolume = _dbClient.queryObject(Volume.class, sourceVolumedescriptor.getVolumeURI());
metropoint = RPHelper.isMetroPointVolume(_dbClient, sourceVolume);
// if this is a change vpool, attachAsClean should be false so that source and target are synchronized
if (VolumeDescriptor.Type.RP_EXISTING_SOURCE.equals(sourceVolumedescriptor.getType())) {
attachAsClean = false;
}
}
// Build the CG Request params
cgParams = getCGRequestParams(volumeDescriptors, rpSystem);
updateCGParams(cgParams);
// Validate the source/target volumes before creating a CG.
validateCGVolumes(volumeDescriptors);
rp = RPHelper.getRecoverPointClient(rpSystem);
// Scan the rp sites for volume visibility
rp.waitForVolumesToBeVisible(cgParams);
// Before acquiring a lock on the CG we need to ensure that the
// CG is created. If it hasn't, then the first CGRequestParams
// to be allowed to pass through needs to have the journals
// defined.
//
// NOTE: The CG may not yet be created on the RP protection system and
// that's OK since this might be the first request going in.
waitForCGToBeCreated(cgId, cgParams);
// lock around create and delete operations on the same CG
List<String> lockKeys = new ArrayList<String>();
lockKeys.add(ControllerLockingUtil.getConsistencyGroupStorageKey(_dbClient, cgId, rpSystem.getId()));
boolean lockAcquired = _workflowService.acquireWorkflowStepLocks(token, lockKeys, LockTimeoutValue.get(LockType.RP_CG));
if (!lockAcquired) {
lockException = true;
throw DeviceControllerException.exceptions.failedToAcquireLock(lockKeys.toString(), String.format("Create or add volumes to RP consistency group id: %s", cgId.toString()));
}
RecoverPointCGResponse response = null;
// The CG already exists if it contains volumes and is of type RP
_log.info("Submitting RP Request: " + cgParams);
BlockConsistencyGroup cg = _dbClient.queryObject(BlockConsistencyGroup.class, cgId);
// Check to see if the CG has been created in ViPR and on the RP protection system
boolean cgAlreadyExists = rpCGExists(cg, rp, cgParams.getCgName(), rpSystem.getId());
if (cgAlreadyExists) {
// cg exists in both the ViPR db and on the RP system
_log.info(String.format("RP CG [%s] already exists, adding replication set(s) to it...", cgParams.getCgName()));
response = rp.addReplicationSetsToCG(cgParams, metropoint, attachAsClean);
} else {
_log.info(String.format("RP CG [%s] does not already exist, creating it now and adding replication set(s) to it...", cgParams.getCgName()));
response = rp.createCG(cgParams, metropoint, attachAsClean);
// "Turn-on" the consistency group
cg = _dbClient.queryObject(BlockConsistencyGroup.class, cgParams.getCgUri());
cg.addSystemConsistencyGroup(rpSystemId.toString(), cgParams.getCgName());
cg.addConsistencyGroupTypes(Types.RP.name());
}
// At this point, always clear the journal provisioning lock on the
// CG for any concurrent orders that may come in.
cg.setJournalProvisioningLock(0L);
_dbClient.updateObject(cg);
setVolumeConsistencyGroup(volumeDescriptors, cgParams.getCgUri());
// If this was a vpool Update, now is a good time to update the vpool and Volume information
if (VolumeDescriptor.getVirtualPoolChangeVolume(volumeDescriptors) != null) {
Volume volume = _dbClient.queryObject(Volume.class, VolumeDescriptor.getVirtualPoolChangeVolume(volumeDescriptors));
URI newVpoolURI = getVirtualPoolChangeNewVirtualPool(volumeDescriptors);
volume.setVirtualPool(newVpoolURI);
volume.setPersonality(Volume.PersonalityTypes.SOURCE.toString());
volume.setAccessState(Volume.VolumeAccessState.READWRITE.name());
volume.setLinkStatus(Volume.LinkStatus.IN_SYNC.name());
volume.setProtectionController(rpSystemId);
_dbClient.updateObject(volume);
// We might need to update the vpools of the backing volumes if this is an RP+VPLEX
// or MetroPoint change vpool.
VPlexUtil.updateVPlexBackingVolumeVpools(volume, newVpoolURI, _dbClient);
// Record Audit operation. (virtualpool change only)
AuditBlockUtil.auditBlock(_dbClient, OperationTypeEnum.CHANGE_VOLUME_VPOOL, true, AuditLogManager.AUDITOP_END, token);
}
// Create the ProtectionSet to contain the CG UID (which is truly unique to the protection system)
if (response.getCgId() != null) {
List<ProtectionSet> protectionSets = CustomQueryUtility.queryActiveResourcesByConstraint(_dbClient, ProtectionSet.class, AlternateIdConstraint.Factory.getConstraint(ProtectionSet.class, "protectionId", response.getCgId().toString()));
ProtectionSet protectionSet = null;
if (protectionSets.isEmpty()) {
// A protection set corresponding to the CG does not exist so we need to create one
protectionSet = createProtectionSet(rpSystem, cgParams, response.getCgId());
} else {
// Update the existing protection set. We will only have 1 protection set
// get the first one.
protectionSet = protectionSets.get(0);
protectionSet = updateProtectionSet(protectionSet, cgParams);
}
_dbClient.updateObject(protectionSet);
}
// Set the CG last created time to now.
rpSystem.setCgLastCreatedTime(Calendar.getInstance());
_dbClient.updateObject(rpSystem);
// Update the workflow state.
WorkflowStepCompleter.stepSucceded(token);
// collect and update the protection system statistics to account for
// the newly created CG.
_log.info("Collecting RP statistics post CG create.");
collectRPStatistics(rpSystem);
} catch (Exception e) {
if (lockException) {
List<URI> volUris = VolumeDescriptor.getVolumeURIs(volumeDescriptors);
ServiceError serviceError = DeviceControllerException.errors.createVolumesAborted(volUris.toString(), e);
doFailCgCreateStep(volumeDescriptors, cgParams, rpSystemId, token);
stepFailed(token, serviceError, "cgCreateStep");
} else {
doFailCgCreateStep(volumeDescriptors, cgParams, rpSystemId, token);
stepFailed(token, e, "cgCreateStep");
}
return false;
}
return true;
}
use of com.emc.storageos.db.client.model.ProtectionSystem in project coprhd-controller by CoprHD.
the class ConnectivityUtil method getProtectionSystemsForStoragePool.
/**
* Gets a list of the RP Protection systems for the passed pool.
*
* @param dbClient Reference to a DB client
* @param storagePool Reference to a storage pool
* @param varrayId Optional, filter by varray
* @param isRPVPlex Optional, specifies whether or not this is an RP+VPLEX/MetroPoint request
*
* @return A list of the RP protection systems.
*/
public static Set<ProtectionSystem> getProtectionSystemsForStoragePool(DbClient dbClient, StoragePool storagePool, URI varrayId, boolean isRPVPlex) {
Set<ProtectionSystem> rpSystems = new HashSet<ProtectionSystem>();
Set<ProtectionSystem> rpSystemsWithIsolatedVarrayEntry = new HashSet<ProtectionSystem>();
List<String> isolatedRPSites = new ArrayList<String>();
List<String> storageSystems = new ArrayList<String>();
_log.info(String.format("Find Protection Systems using the Storage System of Storage pool [%s]", storagePool.getLabel()));
// the VPLEX.
if (isRPVPlex) {
_log.info(String.format("RP+VPlex/MetroPoint - only consider Protection Systems associated to the VPLEX."));
// Get the VPLEXs associated with the Storage Pool
List<String> vplexSystemsForPool = VPlexHighAvailabilityMatcher.getVPlexStorageSystemsForStorageSystem(dbClient, storagePool.getStorageDevice(), null);
// Loop through all the VPLEXs
for (String vplexId : vplexSystemsForPool) {
if (varrayId != null) {
// Find the VPLEX(s) that are associated to this varray
List<URI> vplexVarrays = ConnectivityUtil.getVPlexSystemVarrays(dbClient, URI.create(vplexId));
if (vplexVarrays.contains(varrayId)) {
_log.info(String.format("Candidate VPLEX Storage System [%s]", vplexId));
storageSystems.add(vplexId);
}
} else {
_log.info(String.format("Candidate VPLEX Storage System [%s]", vplexId));
storageSystems.add(vplexId);
}
}
} else {
_log.info(String.format("Candidate Storage System [%s]", storagePool.getStorageDevice().toASCIIString()));
storageSystems.add(storagePool.getStorageDevice().toASCIIString());
}
// Find all the Protection Systems for these Storage Systems
for (String storageSystemId : storageSystems) {
Set<URI> rpSystemURIs = ConnectivityUtil.getProtectionSystemsAssociatedWithArray(dbClient, URI.create(storageSystemId));
for (URI uri : rpSystemURIs) {
ProtectionSystem ps = dbClient.queryObject(ProtectionSystem.class, uri);
// Make sure the ProtectionSystem is active
if (ps != null && !ps.getInactive()) {
// We could be isolating the varray in question to specific RPA clusters/sites.
// If there is an entry for this varray in the siteAssignedVirtualArrays field
// we need to honour that isolation and only return Protection Systems
// with an entry for that varray.
boolean varrayHasBeenIsolated = false;
if (varrayId != null) {
if (ps.getSiteAssignedVirtualArrays() != null && !ps.getSiteAssignedVirtualArrays().isEmpty()) {
// Loop over all entries to see if this Protection System has an entry for this varray to be isolated
for (Map.Entry<String, AbstractChangeTrackingSet<String>> entry : ps.getSiteAssignedVirtualArrays().entrySet()) {
// Check to see if this entry contains the varray
if (entry.getValue().contains(varrayId.toString())) {
// This varray has been isolated to a RP cluster/site
varrayHasBeenIsolated = true;
isolatedRPSites.add(entry.getKey());
break;
}
}
}
}
_log.info(String.format("Found Protection System [%s]", ps.getLabel()));
if (varrayHasBeenIsolated) {
rpSystemsWithIsolatedVarrayEntry.add(ps);
} else {
rpSystems.add(ps);
}
} else {
_log.info(String.format("Excluding ProtectionSystem %s because it is inactive or invalid.", uri));
}
}
}
// connectivity.
if (!rpSystemsWithIsolatedVarrayEntry.isEmpty()) {
// Only use RP Systems that have an entry for this varray,
// we will ignore the others.
rpSystems = rpSystemsWithIsolatedVarrayEntry;
StringBuffer logMsg = new StringBuffer();
logMsg.append(String.format("Varray [%s] has been isolated to these RP Sites: %s %n", varrayId.toString(), Joiner.on(',').join(isolatedRPSites)));
logMsg.append("Therefore only these Protection Systems can be used: ");
for (ProtectionSystem ps : rpSystems) {
logMsg.append(ps.getLabel() + " ");
}
_log.info(logMsg.toString());
}
return rpSystems;
}
use of com.emc.storageos.db.client.model.ProtectionSystem in project coprhd-controller by CoprHD.
the class ConnectivityUtil method updateRpSystemsConnectivity.
/**
* Refreshes the connected virtual arrays for the Recover Point (RP) systems that have sites for the storage systems.
* This function:
* <ol>
* <li>Finds all the RP systems that have sites in one or more of the storage systems</li>
* <li>for each RP system, find all the virtual arrays for all their connected storage systems' pools.</li>
* </ol>
*
* @param storageSystemUris the storage systems that have some change in their varray associations
* @param dbClient an instance of {@link DbClient}
*/
public static void updateRpSystemsConnectivity(Collection<URI> storageSystemUris, DbClient dbClient) {
if (storageSystemUris.isEmpty()) {
return;
}
List<URI> connectedRPSystems = getConnectedRPSystems(storageSystemUris, dbClient);
List<ProtectionSystem> rpSystems = dbClient.queryObject(ProtectionSystem.class, connectedRPSystems);
for (ProtectionSystem rpSystem : rpSystems) {
updateRpSystemConnectivity(rpSystem, dbClient);
}
}
use of com.emc.storageos.db.client.model.ProtectionSystem in project coprhd-controller by CoprHD.
the class ProtectionSystemService method getProtectionSystems.
/**
* Gets the id, name, and self link for all registered protection systems.
*
* @brief List protection systems
* @return A reference to a ProtectionSystemList.
*/
@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@CheckPermission(roles = { Role.SYSTEM_ADMIN, Role.SYSTEM_MONITOR })
public ProtectionSystemList getProtectionSystems() {
ProtectionSystemList systemsList = new ProtectionSystemList();
ProtectionSystem system = null;
List<URI> ids = _dbClient.queryByType(ProtectionSystem.class, true);
for (URI id : ids) {
system = _dbClient.queryObject(ProtectionSystem.class, id);
if (system != null && RegistrationStatus.REGISTERED.toString().equalsIgnoreCase(system.getRegistrationStatus())) {
systemsList.getSystems().add(toNamedRelatedResource(system));
}
}
return systemsList;
}
use of com.emc.storageos.db.client.model.ProtectionSystem in project coprhd-controller by CoprHD.
the class ProtectionSystemService method deleteProtectionSystem.
/**
* Deactivate protection system, this will move it to a "marked-for-delete" state.
* It will be deleted in the next iteration of garbage collector
*
* @param id the URN of a ViPR protection system
* @brief Delete protection system
* @return No data returned in response body
*/
@POST
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/{id}/deactivate")
@CheckPermission(roles = { Role.SYSTEM_ADMIN, Role.RESTRICTED_SYSTEM_ADMIN })
public Response deleteProtectionSystem(@PathParam("id") URI id) {
ArgValidator.checkFieldUriType(id, ProtectionSystem.class, "id");
ProtectionSystem system = _dbClient.queryObject(ProtectionSystem.class, id);
ArgValidator.checkEntityNotNull(system, id, isIdEmbeddedInURL(id));
// Check to make sure there are no volumes associated with this protection system
List<ProtectionSet> protectionSetsToDelete = new ArrayList<ProtectionSet>();
if (checkForVolumes(id, protectionSetsToDelete)) {
// don't allow the delete protection system if there are volumes
throw APIException.badRequests.unableToDeactivateDueToDependencies(id);
}
// delete any empty protection sets
_dbClient.markForDeletion(protectionSetsToDelete);
// Side-effect: RPSiteArray entries need to be cleaned up so placement and connectivity feeds are correct
// Mark all of the RPSiteArray entries associated with this protection system for deletion
URIQueryResultList sitelist = new URIQueryResultList();
_dbClient.queryByConstraint(AlternateIdConstraint.Factory.getRPSiteArrayProtectionSystemConstraint(id.toString()), sitelist);
Iterator<URI> it = sitelist.iterator();
while (it.hasNext()) {
URI rpSiteArrayId = it.next();
RPSiteArray siteArray = _dbClient.queryObject(RPSiteArray.class, rpSiteArrayId);
if (siteArray != null) {
_dbClient.markForDeletion(siteArray);
}
}
_dbClient.markForDeletion(system);
auditOp(OperationTypeEnum.DELETE_PROTECTION_SYSTEM, true, null, system.getId().toString());
return Response.ok().build();
}
Aggregations