Search in sources :

Example 1 with UnManagedExportMask

use of com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedExportMask in project coprhd-controller by CoprHD.

the class ClusterService method getUnmanagedExportMasks.

/**
 * Gets the UnManagedExportMasks found for a Cluster.
 *
 * @param id the URI of a ViPR Cluster
 * @brief List unmanaged export masks for a cluster
 * @return a list of UnManagedExportMasks found for the Cluster
 * @throws DatabaseException when a database error occurs
 */
@GET
@Path("/{id}/unmanaged-export-masks")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public UnManagedExportMaskList getUnmanagedExportMasks(@PathParam("id") URI id) throws DatabaseException {
    Cluster cluster = queryObject(Cluster.class, id, false);
    // check the user permissions
    verifyAuthorizedInTenantOrg(cluster.getTenant(), getUserFromContext());
    // get the unmanaged export masks
    List<UnManagedExportMask> uems = VolumeIngestionUtil.findUnManagedExportMasksForCluster(id, _dbClient);
    UnManagedExportMaskList list = new UnManagedExportMaskList();
    for (UnManagedExportMask uem : uems) {
        list.getUnManagedExportMasks().add(toRelatedResource(ResourceTypeEnum.UNMANAGED_EXPORT_MASKS, uem.getId()));
    }
    return list;
}
Also used : UnManagedExportMaskList(com.emc.storageos.model.block.UnManagedExportMaskList) MapCluster(com.emc.storageos.api.mapper.functions.MapCluster) Cluster(com.emc.storageos.db.client.model.Cluster) UnManagedExportMask(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedExportMask) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET)

Example 2 with UnManagedExportMask

use of com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedExportMask in project coprhd-controller by CoprHD.

the class BlockRecoverPointIngestOrchestrator method performRPExportIngestion.

/**
 * RecoverPoint volumes are expected to have export masks where the volume is exported to
 * a RecoverPoint site. Therefore every RP volume (sources, targets, journals) will need to
 * go through this code and have their export mask ingested. Even if the mask has already been
 * ingested by a previous volume ingestion, this method still needs to update the ExportGroup and
 * ExportMask objects to reflect the newly ingested volume as part of its management.
 *
 * @param volumeContext the RecoverPointVolumeIngestionContext for the volume currently being ingested
 * @param unManagedVolume unmanaged volume
 * @param volume managed volume
 * @return managed volume with export ingested
 */
private void performRPExportIngestion(IngestionRequestContext parentRequestContext, RecoverPointVolumeIngestionContext volumeContext, UnManagedVolume unManagedVolume, Volume volume) {
    _logger.info("starting RecoverPoint export ingestion for volume {}", volume.forDisplay());
    Project project = volumeContext.getProject();
    ProtectionSystem protectionSystem = _dbClient.queryObject(ProtectionSystem.class, volume.getProtectionController());
    StorageSystem storageSystem = _dbClient.queryObject(StorageSystem.class, volume.getStorageController());
    List<UnManagedExportMask> unManagedRPExportMasks = findUnManagedRPExportMask(protectionSystem, unManagedVolume);
    if (unManagedRPExportMasks.isEmpty()) {
        _logger.error("Could not find any unmanaged export masks associated with volume: " + unManagedVolume.getLabel());
        throw IngestionException.exceptions.noUnManagedExportMaskFound(unManagedVolume.getNativeGuid());
    }
    // Keep a map for internal site name name and varray
    Map<String, VirtualArray> internalSiteToVarrayMap = new HashMap<String, VirtualArray>();
    internalSiteToVarrayMap.put(volume.getInternalSiteName(), volumeContext.getVarray(unManagedVolume));
    // If this is a MetroPoint volume we're going to have multiple ExportMasks/ExportGroups to deal with.
    // We'll need to query the backend volumes for extra info to populate internalSiteToVarrayMap so
    // we can properly line up the ExportMasks/ExportGroups.
    boolean metropoint = RPHelper.isMetroPointVolume(_dbClient, volume);
    if (metropoint) {
        // We need the VPLEX ingest context to get the backend volume info
        VplexVolumeIngestionContext vplexVolumeContext = ((RpVplexVolumeIngestionContext) volumeContext.getVolumeContext()).getVplexVolumeIngestionContext();
        for (String associatedVolumeIdStr : vplexVolumeContext.getAssociatedVolumeIds(volume)) {
            // Find the associated volumes using the context maps or the db if they are already there
            Volume associatedVolume = VolumeIngestionUtil.findVolume(_dbClient, vplexVolumeContext.getBlockObjectsToBeCreatedMap(), vplexVolumeContext.getDataObjectsToBeUpdatedMap(), associatedVolumeIdStr);
            String internalSiteName = associatedVolume.getInternalSiteName();
            // If we don't already have an entry for this internal site name, let's add it now.
            if (!internalSiteToVarrayMap.containsKey(internalSiteName)) {
                internalSiteToVarrayMap.put(internalSiteName, _dbClient.queryObject(VirtualArray.class, associatedVolume.getVirtualArray()));
            }
        }
    }
    // this will more than likely only loop once.
    for (Entry<String, VirtualArray> entry : internalSiteToVarrayMap.entrySet()) {
        String internalSiteName = entry.getKey();
        VirtualArray virtualArray = entry.getValue();
        UnManagedExportMask em = null;
        if (metropoint) {
            // Since we're flagged for MetroPoint we need to determine which ExportMask to use.
            // We need the MetroPoint volume to be added to BOTH ExportGroups that represent the
            // two Storage Views on VPLEX for cluster-1 and cluster-2.
            // So let's use the varray to find the cluster we're looking for on this pass and match
            // it to the maskingViewParth of the UnManagedExportMask.
            // This should line things up roughly as:
            // VPLEX Storage View 1 -> VPLEX Cluster1 + RPA1
            // VPLEX Storage View 2 -> VPLEX Cluster2 + RPA2
            String vplexCluster = ConnectivityUtil.getVplexClusterForVarray(virtualArray.getId(), storageSystem.getId(), _dbClient);
            // First try and match based on UnManagedExportMask ports
            for (UnManagedExportMask exportMask : unManagedRPExportMasks) {
                for (String portUri : exportMask.getKnownStoragePortUris()) {
                    StoragePort port = _dbClient.queryObject(StoragePort.class, URI.create(portUri));
                    if (port != null && !port.getInactive()) {
                        String vplexClusterForMask = ConnectivityUtil.getVplexClusterOfPort(port);
                        if (vplexCluster.equals(vplexClusterForMask)) {
                            em = exportMask;
                            break;
                        }
                    }
                }
                if (em != null) {
                    break;
                }
            }
            if (em == null) {
                // It really shouldn't come to this, but leaving this code just in case.
                for (UnManagedExportMask exportMask : unManagedRPExportMasks) {
                    if (exportMask.getMaskingViewPath().contains("cluster-" + vplexCluster)) {
                        em = exportMask;
                        break;
                    }
                }
            }
        } else {
            em = unManagedRPExportMasks.get(0);
        }
        // If the mask for ingested volume is in a mask that contains JOURNAL keyword, make sure the ExportGroup created contains
        // that internal flag.
        boolean isJournalExport = false;
        if (em.getMaskName().toLowerCase().contains(VolumeIngestionUtil.RP_JOURNAL)) {
            isJournalExport = true;
        }
        String exportGroupGeneratedName = RPHelper.generateExportGroupName(protectionSystem, storageSystem, internalSiteName, virtualArray, isJournalExport);
        ExportGroup exportGroup = VolumeIngestionUtil.verifyExportGroupExists(parentRequestContext, exportGroupGeneratedName, project.getId(), em.getKnownInitiatorUris(), virtualArray.getId(), _dbClient);
        boolean exportGroupCreated = false;
        if (null == exportGroup) {
            exportGroupCreated = true;
            Integer numPaths = em.getZoningMap().size();
            _logger.info("Creating Export Group with label {}", em.getMaskName());
            exportGroup = RPHelper.createRPExportGroup(exportGroupGeneratedName, virtualArray, project, numPaths, isJournalExport);
        }
        if (null != exportGroup) {
            // check if the ExportGroup has already been fetched
            ExportGroup loadedExportGroup = parentRequestContext.findExportGroup(exportGroup.getLabel(), project.getId(), virtualArray.getId(), null, null);
            if (null != loadedExportGroup) {
                exportGroup = loadedExportGroup;
            }
        }
        volumeContext.setExportGroup(exportGroup);
        volumeContext.setExportGroupCreated(exportGroupCreated);
        volumeContext.getRpExportGroupMap().put(exportGroup, exportGroupCreated);
        // set RP device initiators to be used as the "host" for export mask ingestion
        List<Initiator> initiators = new ArrayList<Initiator>();
        Iterator<Initiator> initiatorItr = _dbClient.queryIterativeObjects(Initiator.class, URIUtil.toURIList(em.getKnownInitiatorUris()));
        while (initiatorItr.hasNext()) {
            initiators.add(initiatorItr.next());
        }
        volumeContext.setDeviceInitiators(initiators);
        // find the ingest export strategy and call into for this unmanaged export mask
        IngestExportStrategy ingestStrategy = ingestStrategyFactory.buildIngestExportStrategy(unManagedVolume);
        volume = ingestStrategy.ingestExportMasks(unManagedVolume, volume, volumeContext);
        if (null == volume) {
            // ingestion did not succeed, but in case it wasn't, throw one
            throw IngestionException.exceptions.generalVolumeException(unManagedVolume.getLabel(), "check the logs for more details");
        }
    }
}
Also used : VirtualArray(com.emc.storageos.db.client.model.VirtualArray) HashMap(java.util.HashMap) VplexVolumeIngestionContext(com.emc.storageos.api.service.impl.resource.blockingestorchestration.context.impl.VplexVolumeIngestionContext) RpVplexVolumeIngestionContext(com.emc.storageos.api.service.impl.resource.blockingestorchestration.context.impl.RpVplexVolumeIngestionContext) StoragePort(com.emc.storageos.db.client.model.StoragePort) ArrayList(java.util.ArrayList) ProtectionSystem(com.emc.storageos.db.client.model.ProtectionSystem) Project(com.emc.storageos.db.client.model.Project) ExportGroup(com.emc.storageos.db.client.model.ExportGroup) UnManagedVolume(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume) Volume(com.emc.storageos.db.client.model.Volume) Initiator(com.emc.storageos.db.client.model.Initiator) RpVplexVolumeIngestionContext(com.emc.storageos.api.service.impl.resource.blockingestorchestration.context.impl.RpVplexVolumeIngestionContext) StorageSystem(com.emc.storageos.db.client.model.StorageSystem) UnManagedExportMask(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedExportMask)

Example 3 with UnManagedExportMask

use of com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedExportMask in project coprhd-controller by CoprHD.

the class BlockRecoverPointIngestOrchestrator method findUnManagedRPExportMask.

/**
 * This unmanaged volume may be associated with several export masks. We need to find the export mask
 * that belongs specifically to the RP protection system supplied.
 *
 * Note: There could only be more than one mask that contains both the protection system's initiators AND the volume which
 * would indicate MetroPoint. In a MetroPoint configuration the VPLEX Distributed Source volume is exported to RP
 * via two different Storage Views. One per VPLEX cluster to two different RPA clusters.
 *
 * @param protectionSystem protection system
 * @param unManagedVolume unmanaged volume
 * @return unmanaged export masks that belong to the protection system that contains the unmanaged volume
 */
private List<UnManagedExportMask> findUnManagedRPExportMask(ProtectionSystem protectionSystem, UnManagedVolume unManagedVolume) {
    List<UnManagedExportMask> unManagedRPExportMasks = new ArrayList<UnManagedExportMask>();
    for (String maskIdStr : unManagedVolume.getUnmanagedExportMasks()) {
        // Find the mask associated with the protection system.
        UnManagedExportMask em = _dbClient.queryObject(UnManagedExportMask.class, URI.create(maskIdStr));
        if (em == null) {
            _logger.error("UnManagedExportMask with ID: " + maskIdStr + " could not be found in DB.  Could already be ingested.");
            continue;
        }
        // Check for unlikely conditions on the mask, such as no initiators assigned.
        if (em.getKnownInitiatorNetworkIds() == null || em.getKnownInitiatorNetworkIds().isEmpty()) {
            _logger.error("UnManagedExportMask with ID: " + maskIdStr + " does not contain any RP initiators.  Ignoring for ingestion.");
            continue;
        }
        boolean foundMask = false;
        for (String wwn : em.getKnownInitiatorNetworkIds()) {
            for (Entry<String, AbstractChangeTrackingSet<String>> siteInitEntry : protectionSystem.getSiteInitiators().entrySet()) {
                if (siteInitEntry.getValue().contains(wwn)) {
                    _logger.info(String.format("UnManagedVolume %s was found in UnManagedExportMask %s and will be ingested (if not ingested already)", unManagedVolume.getLabel(), em.getMaskName()));
                    unManagedRPExportMasks.add(em);
                    foundMask = true;
                    break;
                }
            }
            if (foundMask) {
                break;
            }
        }
    }
    return unManagedRPExportMasks;
}
Also used : ArrayList(java.util.ArrayList) UnManagedExportMask(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedExportMask) AbstractChangeTrackingSet(com.emc.storageos.db.client.model.AbstractChangeTrackingSet)

Example 4 with UnManagedExportMask

use of com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedExportMask in project coprhd-controller by CoprHD.

the class IngestExportStrategy method ingestExportMasks.

/**
 * After volume object gets created successfully locally, now start
 * running ingest associated masks of the volume
 */
public <T extends BlockObject> T ingestExportMasks(UnManagedVolume unManagedVolume, T blockObject, IngestionRequestContext requestContext) throws IngestionException {
    _logger.info("ingesting export masks for requestContext " + requestContext.getCurrentUnmanagedVolume());
    if (null != requestContext.getExportGroup()) {
        if (null != unManagedVolume.getUnmanagedExportMasks() && !unManagedVolume.getUnmanagedExportMasks().isEmpty()) {
            List<URI> unManagedMaskUris = new ArrayList<URI>(Collections2.transform(unManagedVolume.getUnmanagedExportMasks(), CommonTransformerFunctions.FCTN_STRING_TO_URI));
            List<UnManagedExportMask> unManagedMasks = _dbClient.queryObject(UnManagedExportMask.class, unManagedMaskUris);
            int originalSize = unManagedMasks.size();
            MutableInt masksIngestedCount = new MutableInt(0);
            // Ingest Associated Masks
            ingestExportOrchestrator.ingestExportMasks(requestContext, unManagedVolume, blockObject, unManagedMasks, masksIngestedCount);
            _logger.info("{} of {} unmanaged export masks were ingested", masksIngestedCount, originalSize);
            List<String> errorMessages = requestContext.getErrorMessagesForVolume(unManagedVolume.getNativeGuid());
            // If the internal flags are set, return the block object
            if (blockObject.checkInternalFlags(Flag.PARTIALLY_INGESTED)) {
                _logger.info("block object {} is partially ingested", blockObject.forDisplay());
                // check if none of the export masks are ingested
                if (masksIngestedCount.intValue() == 0) {
                    if (null != errorMessages && !errorMessages.isEmpty()) {
                        throw IngestionException.exceptions.unmanagedVolumeMasksNotIngestedAdditionalInfo(unManagedVolume.getLabel(), Joiner.on(", ").join(errorMessages));
                    } else {
                        throw IngestionException.exceptions.unmanagedVolumeMasksNotIngested(unManagedVolume.getLabel());
                    }
                } else {
                    // If the unmanaged volume is not marked for deletion, then it should be updated with the changes done.
                    requestContext.addDataObjectToUpdate(unManagedVolume, unManagedVolume);
                    _logger.info("all export masks of unmanaged volume {} have been ingested, " + "but the volume is still marked as partially ingested, returning block object {}", unManagedVolume.forDisplay(), blockObject.forDisplay());
                    return blockObject;
                }
            }
            if (unManagedVolume.getUnmanagedExportMasks().size() != originalSize) {
                // delete this volume only if the masks are ingested.
                if (VolumeIngestionUtil.canDeleteUnManagedVolume(unManagedVolume)) {
                    _logger.info("Marking UnManaged Volume {} inactive as it doesn't have any associated unmanaged export masks ", unManagedVolume.getNativeGuid());
                    boolean isRPVolume = VolumeIngestionUtil.checkUnManagedResourceIsRecoverPointEnabled(unManagedVolume);
                    // if its RP volume and non RP exported, then check whether the RP CG is fully ingested
                    if (isRPVolume && VolumeIngestionUtil.checkUnManagedResourceIsNonRPExported(unManagedVolume)) {
                        _logger.info("unmanaged volume {} is both RecoverPoint protected and exported to another Host or Cluster", unManagedVolume.forDisplay());
                        Set<DataObject> updateObjects = requestContext.getDataObjectsToBeUpdatedMap().get(unManagedVolume.getNativeGuid());
                        if (updateObjects == null) {
                            updateObjects = new HashSet<DataObject>();
                            requestContext.getDataObjectsToBeUpdatedMap().put(unManagedVolume.getNativeGuid(), updateObjects);
                        }
                        List<UnManagedVolume> ingestedUnManagedVolumes = requestContext.findAllUnManagedVolumesToBeDeleted();
                        ingestedUnManagedVolumes.add(unManagedVolume);
                        UnManagedProtectionSet umpset = VolumeIngestionUtil.getUnManagedProtectionSetForUnManagedVolume(requestContext, unManagedVolume, _dbClient);
                        // unmanaged volume has already been ingested. In this case, try to get it from the managed volume
                        if (umpset == null) {
                            umpset = VolumeIngestionUtil.getUnManagedProtectionSetForManagedVolume(requestContext, blockObject, _dbClient);
                        }
                        // If fully ingested, then setup the RP CG too.
                        if (VolumeIngestionUtil.validateAllVolumesInCGIngested(ingestedUnManagedVolumes, umpset, requestContext, _dbClient)) {
                            VolumeIngestionUtil.validateRPVolumesAlignWithIngestVpool(requestContext, umpset, _dbClient);
                            VolumeIngestionUtil.setupRPCG(requestContext, umpset, unManagedVolume, updateObjects, _dbClient);
                        } else {
                            // else mark the volume as internal. This will be marked visible when the RP CG is ingested
                            blockObject.addInternalFlags(BlockRecoverPointIngestOrchestrator.INTERNAL_VOLUME_FLAGS);
                        }
                    }
                    unManagedVolume.setInactive(true);
                    requestContext.getUnManagedVolumesToBeDeleted().add(unManagedVolume);
                } else {
                    // If the unmanaged volume is not marked for deletion, then it should be updated with the changes done.
                    requestContext.addDataObjectToUpdate(unManagedVolume, unManagedVolume);
                }
                return blockObject;
            } else {
                if (null != errorMessages && !errorMessages.isEmpty()) {
                    Collections.sort(errorMessages);
                    throw IngestionException.exceptions.unmanagedVolumeMasksNotIngestedAdditionalInfo(unManagedVolume.getLabel(), "\n\n" + Joiner.on("\n\n").join(errorMessages));
                } else {
                    throw IngestionException.exceptions.unmanagedVolumeMasksNotIngested(unManagedVolume.getLabel());
                }
            }
        }
    }
    return blockObject;
}
Also used : ArrayList(java.util.ArrayList) URI(java.net.URI) UnManagedProtectionSet(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedProtectionSet) DataObject(com.emc.storageos.db.client.model.DataObject) UnManagedVolume(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume) MutableInt(org.apache.commons.lang.mutable.MutableInt) UnManagedExportMask(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedExportMask)

Example 5 with UnManagedExportMask

use of com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedExportMask in project coprhd-controller by CoprHD.

the class MaskPerHostIngestOrchestrator method getExportMaskAlreadyIngested.

/**
 * maskPerHost Mode guaranteed to have initiators in only 1 export mask
 * always.
 */
@Override
protected ExportMask getExportMaskAlreadyIngested(UnManagedExportMask mask, DbClient dbClient) {
    ExportMask eMask = null;
    boolean maskFound = false;
    List<URI> initiatorUris = new ArrayList<URI>(Collections2.transform(mask.getKnownInitiatorUris(), CommonTransformerFunctions.FCTN_STRING_TO_URI));
    for (URI ini : initiatorUris) {
        List<URI> exportMaskUris = _dbClient.queryByConstraint(AlternateIdConstraint.Factory.getExportMaskInitiatorConstraint(ini.toString()));
        if (null == exportMaskUris) {
            return eMask;
        }
        for (URI eMaskUri : exportMaskUris) {
            ExportMask potentialMask = _dbClient.queryObject(ExportMask.class, eMaskUri);
            if (potentialMask.getStorageDevice() != null && potentialMask.getStorageDevice().equals(mask.getStorageSystemUri())) {
                _logger.info("Found Mask {} with matching initiator and matching Storage System", eMaskUri);
                eMask = potentialMask;
                maskFound = true;
                break;
            } else {
                _logger.info("Found Mask {} with matching initiator and unmatched Storage System. Skipping mask", eMaskUri);
            }
        }
        if (maskFound) {
            break;
        }
    }
    return eMask;
}
Also used : UnManagedExportMask(com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedExportMask) ExportMask(com.emc.storageos.db.client.model.ExportMask) ArrayList(java.util.ArrayList) URI(java.net.URI)

Aggregations

UnManagedExportMask (com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedExportMask)46 URI (java.net.URI)33 ArrayList (java.util.ArrayList)26 HashSet (java.util.HashSet)20 URIQueryResultList (com.emc.storageos.db.client.constraint.URIQueryResultList)19 StringSet (com.emc.storageos.db.client.model.StringSet)17 Initiator (com.emc.storageos.db.client.model.Initiator)15 HashMap (java.util.HashMap)14 UnManagedVolume (com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedVolume)13 ExportMask (com.emc.storageos.db.client.model.ExportMask)8 NamedURI (com.emc.storageos.db.client.model.NamedURI)8 Map (java.util.Map)8 Set (java.util.Set)8 StringSetMap (com.emc.storageos.db.client.model.StringSetMap)7 Volume (com.emc.storageos.db.client.model.Volume)7 StoragePort (com.emc.storageos.db.client.model.StoragePort)6 StorageSystem (com.emc.storageos.db.client.model.StorageSystem)6 BaseCollectionException (com.emc.storageos.plugins.BaseCollectionException)6 CIMInstance (javax.cim.CIMInstance)5 CIMObjectPath (javax.cim.CIMObjectPath)5