use of com.emc.storageos.db.client.model.StringSet in project coprhd-controller by CoprHD.
the class SRDFDeviceController method deleteAllSrdfVolumesInCG.
/**
* Delete All SRDF Volumes in CG in one attempt.
*
* @param sourcesVolumeMap
* @param workflow
* @param waitFor
* @return
*/
private String deleteAllSrdfVolumesInCG(Map<URI, Volume> sourcesVolumeMap, final Workflow workflow, String waitFor, final List<VolumeDescriptor> sourceDescriptors) {
// TODO Improve this logic
Volume sourceVolume = sourcesVolumeMap.get(sourceDescriptors.get(0).getVolumeURI());
Volume targetVolume = getFirstTarget(sourceVolume);
if (targetVolume == null) {
log.info("No target volume available for source {}", sourceVolume.getId());
return waitFor;
}
RemoteDirectorGroup group = dbClient.queryObject(RemoteDirectorGroup.class, targetVolume.getSrdfGroup());
StorageSystem sourceSystem = dbClient.queryObject(StorageSystem.class, group.getSourceStorageSystemUri());
StorageSystem targetSystem = dbClient.queryObject(StorageSystem.class, group.getRemoteStorageSystemUri());
// Suspend all members in the group
Method method = suspendSRDFGroupLinkMethod(targetSystem.getId(), sourceVolume.getId(), targetVolume.getId(), false);
String splitStep = workflow.createStep(DELETE_SRDF_MIRRORS_STEP_GROUP, SPLIT_SRDF_MIRRORS_STEP_DESC, waitFor, targetSystem.getId(), targetSystem.getSystemType(), getClass(), method, null, null);
// Second we detach the group...
Workflow.Method detachMethod = detachGroupPairsMethod(targetSystem.getId(), sourceVolume.getId(), targetVolume.getId());
String detachMirrorStep = workflow.createStep(DELETE_SRDF_MIRRORS_STEP_GROUP, DETACH_SRDF_MIRRORS_STEP_DESC, splitStep, targetSystem.getId(), targetSystem.getSystemType(), getClass(), detachMethod, null, null);
waitFor = detachMirrorStep;
List<URI> targetVolumeIds = new ArrayList<URI>();
for (Volume source : sourcesVolumeMap.values()) {
StringSet srdfTargets = source.getSrdfTargets();
for (String srdfTarget : srdfTargets) {
log.info("suspend and detach: source:{}, target:{}", source.getId(), srdfTarget);
URI targetURI = URI.create(srdfTarget);
Volume target = dbClient.queryObject(Volume.class, targetURI);
if (null == target) {
log.warn("Target volume {} not available for SRDF source volume {}", source.getId(), targetURI);
return DELETE_SRDF_MIRRORS_STEP_GROUP;
}
log.info("target Volume {} with srdf group {}", target.getNativeGuid(), target.getSrdfGroup());
// Third we remove the device groups, a defensive step to remove
// members from deviceGroups if it exists.
Workflow.Method removeGroupsMethod = removeDeviceGroupsMethod(sourceSystem.getId(), source.getId(), targetURI);
waitFor = workflow.createStep(DELETE_SRDF_MIRRORS_STEP_GROUP, REMOVE_DEVICE_GROUPS_STEP_DESC, waitFor, sourceSystem.getId(), sourceSystem.getSystemType(), getClass(), removeGroupsMethod, null, null);
}
}
// refresh provider before invoking deleteVolume call
if (null != targetSystem) {
addStepToRefreshSystem(DELETE_SRDF_MIRRORS_STEP_GROUP, targetSystem, targetVolumeIds, waitFor, workflow);
}
return DELETE_SRDF_MIRRORS_STEP_GROUP;
}
use of com.emc.storageos.db.client.model.StringSet in project coprhd-controller by CoprHD.
the class SRDFDeviceController method createCGSRDFVolumes.
protected void createCGSRDFVolumes(Workflow workflow, String waitFor, List<VolumeDescriptor> sourceDescriptors, List<VolumeDescriptor> targetDescriptors, Map<URI, Volume> uriVolumeMap) {
RemoteDirectorGroup group = getRAGroup(targetDescriptors, uriVolumeMap);
StorageSystem system = dbClient.queryObject(StorageSystem.class, group.getSourceStorageSystemUri());
StorageSystem targetSystem = dbClient.queryObject(StorageSystem.class, group.getRemoteStorageSystemUri());
// finding actual volumes from Provider
Set<String> volumes = findVolumesPartOfRDFGroups(system, group);
if (group.getVolumes() == null) {
group.setVolumes(new StringSet());
}
/*
* Check the following 2 conditions.
* 1. If there are no volumes in RDFGroup on Array & volumes in RDFGroup in ViPR DB.
* 2. If there are volumes in RDFGroup on Array & no volumes in RDFGroup in ViPR DB.
*/
if ((group.getVolumes().isEmpty() && !volumes.isEmpty()) || (!group.getVolumes().isEmpty() && volumes.isEmpty())) {
// throw Exception rediscover source and target arrays.
log.warn("RDF Group {} out of sync with Array", group.getNativeGuid());
List<URI> sourceURIs = VolumeDescriptor.getVolumeURIs(sourceDescriptors);
List<URI> targetURIs = VolumeDescriptor.getVolumeURIs(targetDescriptors);
URI vpoolChangeUri = getVirtualPoolChangeVolume(sourceDescriptors);
for (URI sourceUri : sourceURIs) {
Volume sourceVolume = dbClient.queryObject(Volume.class, sourceUri);
if (null != sourceVolume) {
log.info("Clearing source volume {}-->{}", sourceVolume.getNativeGuid(), sourceVolume.getId());
if (null == vpoolChangeUri) {
// clear everything if not vpool change
sourceVolume.setPersonality(NullColumnValueGetter.getNullStr());
sourceVolume.setAccessState(Volume.VolumeAccessState.READWRITE.name());
sourceVolume.setInactive(true);
sourceVolume.setConsistencyGroup(NullColumnValueGetter.getNullURI());
}
if (null != sourceVolume.getSrdfTargets()) {
sourceVolume.getSrdfTargets().clear();
}
dbClient.updateObject(sourceVolume);
}
}
for (URI targetUri : targetURIs) {
Volume targetVolume = dbClient.queryObject(Volume.class, targetUri);
if (null != targetVolume) {
log.info("Clearing target volume {}-->{}", targetVolume.getNativeGuid(), targetVolume.getId());
targetVolume.setPersonality(NullColumnValueGetter.getNullStr());
targetVolume.setAccessState(Volume.VolumeAccessState.READWRITE.name());
targetVolume.setSrdfParent(new NamedURI(NullColumnValueGetter.getNullURI(), NullColumnValueGetter.getNullStr()));
targetVolume.setSrdfCopyMode(NullColumnValueGetter.getNullStr());
targetVolume.setSrdfGroup(NullColumnValueGetter.getNullURI());
targetVolume.setConsistencyGroup(NullColumnValueGetter.getNullURI());
targetVolume.setInactive(true);
dbClient.updateObject(targetVolume);
}
}
throw DeviceControllerException.exceptions.srdfAsyncStepCreationfailed(group.getNativeGuid());
}
group.getVolumes().replace(volumes);
dbClient.updateObject(group);
if (volumes.isEmpty() && SupportedCopyModes.ALL.toString().equalsIgnoreCase(group.getSupportedCopyMode())) {
log.info("RA Group {} was empty", group.getId());
waitFor = createSrdfCgPairStepsOnEmptyGroup(sourceDescriptors, targetDescriptors, group, waitFor, workflow);
} else {
log.info("RA Group {} not empty", group.getId());
waitFor = createSrdfCGPairStepsOnPopulatedGroup(sourceDescriptors, group, uriVolumeMap, waitFor, workflow);
}
// Generate workflow step to refresh target system after CG creation.
if (null != system) {
waitFor = addStepToRefreshSystem(CREATE_SRDF_MIRRORS_STEP_GROUP, system, null, waitFor, workflow);
}
if (null != targetSystem) {
waitFor = addStepToRefreshSystem(CREATE_SRDF_MIRRORS_STEP_GROUP, targetSystem, null, waitFor, workflow);
}
// Refresh target volume properties
Mode SRDFMode = getSRDFMode(sourceDescriptors, uriVolumeMap);
if (Mode.ACTIVE.equals(SRDFMode)) {
refreshVolumeProperties(targetDescriptors, targetSystem, waitFor, workflow);
}
}
use of com.emc.storageos.db.client.model.StringSet in project coprhd-controller by CoprHD.
the class VPlexUtil method getSharedExportMaskInDb.
/**
* Returns the shared export mask in the export group i:e single ExportMask in database for multiple hosts
* corresponding to the single storage view on VPLEX with multiple hosts.
*
* At-least there should be two host in the exportMask to be called as sharedExportMask. Also there shouldn't be more than one
* exportMask for the exportGroup for a VPLEX cluster.
*
* Note : This is applicable from Darth release onwards.
*
* @param exportGroup ExportGroup object
* @param vplexURI URI of the VPLEX system
* @param dbClient database client instance
* @param varrayUri Varray we want the Export Mask in
* @param vplexCluster Vplex Cluster we want ExportMask for
* @param hostInitiatorMap Map of host to initiators that are not yet added to the storage view on VPLEX
* @return shared ExportMask for a exportGroup
* @throws Exception
*/
public static ExportMask getSharedExportMaskInDb(ExportGroup exportGroup, URI vplexURI, DbClient dbClient, URI varrayUri, String vplexCluster, Map<URI, List<Initiator>> hostInitiatorMap) throws Exception {
ExportMask sharedExportMask = null;
if (exportGroup.getExportMasks() == null) {
return null;
}
StringSet exportGrouphosts = exportGroup.getHosts();
// Get all the exportMasks for the VPLEX from the export group
List<ExportMask> exportMasks = ExportMaskUtils.getExportMasks(dbClient, exportGroup, vplexURI);
// exportMasks list could have mask for both the VPLEX cluster for the same initiators for the cross-connect case
// for the cross-connect case hence get the ExportMask for the specific VPLEX cluster.
List<ExportMask> exportMasksForVplexCluster = getExportMasksForVplexCluster(vplexURI, dbClient, varrayUri, vplexCluster, exportMasks);
// and we found only one exportMask in database for the VPLEX cluster
if (exportGrouphosts != null && exportGrouphosts.size() > 1 && exportMasksForVplexCluster.size() == 1) {
ExportMask exportMask = exportMasksForVplexCluster.get(0);
ArrayList<String> exportMaskInitiators = new ArrayList<>(exportMask.getInitiators());
Map<URI, List<Initiator>> exportMaskHostInitiatorsMap = makeHostInitiatorsMap(URIUtil.toURIList(exportMaskInitiators), dbClient);
// Remove the host which is not yet added by CorpHD
if (hostInitiatorMap != null) {
for (Entry<URI, List<Initiator>> entry : hostInitiatorMap.entrySet()) {
exportMaskHostInitiatorsMap.remove(entry.getKey());
}
}
// If we found more than one host in the exportMask then its a sharedExportMask
if (exportMaskHostInitiatorsMap.size() > 1) {
sharedExportMask = exportMask;
}
}
return sharedExportMask;
}
use of com.emc.storageos.db.client.model.StringSet in project coprhd-controller by CoprHD.
the class ExportUtils method updateZoningMap.
/**
* This method updates zoning map to add new assignments.
*
* @param dbClient an instance of {@link DbClient}
* @param exportMask The reference to exportMask
* @param assignments New assignments Map of initiator to storagePorts that will be updated in the zoning map
* @param exportMasksToUpdateOnDeviceWithStoragePorts OUT param -- Map of ExportMask to new Storage ports
* @return returns an updated exportMask
*/
public static ExportMask updateZoningMap(DbClient dbClient, ExportMask exportMask, Map<URI, List<URI>> assignments, Map<URI, List<URI>> exportMasksToUpdateOnDeviceWithStoragePorts) {
StringSetMap existingZoningMap = exportMask.getZoningMap();
for (URI initiatorURI : assignments.keySet()) {
boolean initiatorMatchFound = false;
if (existingZoningMap != null && !existingZoningMap.isEmpty()) {
for (String initiatorId : existingZoningMap.keySet()) {
if (initiatorURI.toString().equals(initiatorId)) {
StringSet ports = existingZoningMap.get(initiatorId);
if (ports != null && !ports.isEmpty()) {
initiatorMatchFound = true;
StringSet newTargets = StringSetUtil.uriListToStringSet(assignments.get(initiatorURI));
if (!ports.containsAll(newTargets)) {
ports.addAll(newTargets);
// Adds zoning map entry with new and existing ports. Its kind of updating storage ports for the initiator.
exportMask.addZoningMapEntry(initiatorId, ports);
updateExportMaskStoragePortsMap(exportMask, exportMasksToUpdateOnDeviceWithStoragePorts, assignments, initiatorURI);
}
}
}
}
}
if (!initiatorMatchFound) {
// Adds new zoning map entry for the initiator with new assignments as there isn't one already.
exportMask.addZoningMapEntry(initiatorURI.toString(), StringSetUtil.uriListToStringSet(assignments.get(initiatorURI)));
updateExportMaskStoragePortsMap(exportMask, exportMasksToUpdateOnDeviceWithStoragePorts, assignments, initiatorURI);
}
}
dbClient.persistObject(exportMask);
return exportMask;
}
use of com.emc.storageos.db.client.model.StringSet in project coprhd-controller by CoprHD.
the class ExportUtils method cleanStaleMaskReferences.
/**
* Cleans stale mask references from export group instance
*
* @param exportGroup {@link ExportGroup}
* @param dbClient {@link DbClient}
*/
private static void cleanStaleMaskReferences(ExportGroup exportGroup, DbClient dbClient) {
if (null == exportGroup || exportGroup.getInactive()) {
return;
}
// Clean stale export mask references from ExportGroup.
StringSet exportMasks = exportGroup.getExportMasks();
if (!CollectionUtils.isEmpty(exportMasks)) {
List<URI> staleMasks = new ArrayList<>();
List<URI> unstaleMasks = new ArrayList<>();
StringSet exportGroupInitiators = exportGroup.getInitiators();
for (String mask : exportMasks) {
boolean isStaleMask = false;
URI maskURI = null;
try {
maskURI = URI.create(mask);
} catch (Exception e) {
_log.error(e.getMessage(), e);
isStaleMask = true;
}
if (maskURI != null) {
ExportMask maskObj = dbClient.queryObject(ExportMask.class, maskURI);
if (maskObj != null && !CollectionUtils.isEmpty(maskObj.getInitiators())) {
isStaleMask = Sets.intersection(exportGroupInitiators, maskObj.getInitiators()).isEmpty();
} else {
isStaleMask = true;
}
}
if (isStaleMask) {
staleMasks.add(maskURI);
_log.info("Stale mask {} will be removed from Export Group {}", maskURI, exportGroup.getId());
} else {
unstaleMasks.add(maskURI);
}
}
if (!CollectionUtils.isEmpty(staleMasks)) {
exportGroup.removeExportMasks(staleMasks);
for (URI maskURI : staleMasks) {
List<ExportGroup> exportGroups = getExportGroupsForMask(maskURI, dbClient);
if (exportGroups.isEmpty() || (exportGroups.size() == 1 && exportGroups.get(0).getId().equals(exportGroup.getId()))) {
ExportMask maskObj = dbClient.queryObject(ExportMask.class, maskURI);
if (maskObj != null) {
_log.info("Deleting export mask {} because it is no longer in use by an export group", maskObj);
dbClient.removeObject(maskObj);
}
}
}
}
// masks that are not stale.
if (!CollectionUtils.isEmpty(unstaleMasks)) {
cleanStaleZoningMapEntries(unstaleMasks, dbClient);
}
}
if (CollectionUtils.isEmpty(exportGroup.getExportMasks()) && !exportGroup.checkInternalFlags(DataObject.Flag.INTERNAL_OBJECT)) {
// COP-27689 - Even if all the export masks got cleared, the export Group still remains with initiators and volumes.
// Clean up all the initiators, volumes and ports as there are no available export masks.
_log.info("There are no masks in the export Group {}-->{} after cleaning up stale masks.", exportGroup.getId(), exportGroup.getLabel());
resetExportGroup(exportGroup, dbClient);
}
}
Aggregations