Search in sources :

Example 51 with StringSet

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;
}
Also used : Method(com.emc.storageos.workflow.Workflow.Method) Volume(com.emc.storageos.db.client.model.Volume) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) ArrayList(java.util.ArrayList) StringSet(com.emc.storageos.db.client.model.StringSet) Workflow(com.emc.storageos.workflow.Workflow) RemoteDirectorGroup(com.emc.storageos.db.client.model.RemoteDirectorGroup) Method(com.emc.storageos.workflow.Workflow.Method) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) FCTN_STRING_TO_URI(com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_STRING_TO_URI) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 52 with StringSet

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);
    }
}
Also used : Volume(com.emc.storageos.db.client.model.Volume) NamedURI(com.emc.storageos.db.client.model.NamedURI) Mode(com.emc.storageos.volumecontroller.impl.smis.SRDFOperations.Mode) StringSet(com.emc.storageos.db.client.model.StringSet) RemoteDirectorGroup(com.emc.storageos.db.client.model.RemoteDirectorGroup) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) FCTN_STRING_TO_URI(com.emc.storageos.db.client.util.CommonTransformerFunctions.FCTN_STRING_TO_URI) StorageSystem(com.emc.storageos.db.client.model.StorageSystem)

Example 53 with StringSet

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;
}
Also used : ExportMask(com.emc.storageos.db.client.model.ExportMask) StringSet(com.emc.storageos.db.client.model.StringSet) ArrayList(java.util.ArrayList) List(java.util.List) ArrayList(java.util.ArrayList) URIQueryResultList(com.emc.storageos.db.client.constraint.URIQueryResultList) URI(java.net.URI)

Example 54 with StringSet

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;
}
Also used : StringSetMap(com.emc.storageos.db.client.model.StringSetMap) StringSet(com.emc.storageos.db.client.model.StringSet) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI)

Example 55 with StringSet

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);
    }
}
Also used : ExportGroup(com.emc.storageos.db.client.model.ExportGroup) ExportMask(com.emc.storageos.db.client.model.ExportMask) StringSet(com.emc.storageos.db.client.model.StringSet) ArrayList(java.util.ArrayList) NamedURI(com.emc.storageos.db.client.model.NamedURI) URI(java.net.URI) DeviceControllerException(com.emc.storageos.exceptions.DeviceControllerException) ControllerException(com.emc.storageos.volumecontroller.ControllerException)

Aggregations

StringSet (com.emc.storageos.db.client.model.StringSet)760 URI (java.net.URI)371 ArrayList (java.util.ArrayList)278 Volume (com.emc.storageos.db.client.model.Volume)189 NamedURI (com.emc.storageos.db.client.model.NamedURI)176 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)137 HashMap (java.util.HashMap)132 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)124 StringSetMap (com.emc.storageos.db.client.model.StringSetMap)116 List (java.util.List)108 HashSet (java.util.HashSet)106 StoragePort (com.emc.storageos.db.client.model.StoragePort)90 StoragePool (com.emc.storageos.db.client.model.StoragePool)75 StringMap (com.emc.storageos.db.client.model.StringMap)74 VirtualPool (com.emc.storageos.db.client.model.VirtualPool)71 UnManagedVolume (com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume)70 Initiator (com.emc.storageos.db.client.model.Initiator)60 DeviceControllerException (com.emc.storageos.exceptions.DeviceControllerException)60 DatabaseException (com.emc.storageos.db.exceptions.DatabaseException)50 Map (java.util.Map)48