use of com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedExportMask in project coprhd-controller by CoprHD.
the class VolumeIngestionUtil method findUnManagedVolumesForHost.
/**
* Get UnManagedVolumes associated with a Host.
*
* @param hostUri the URI of the Host to check
* @param dbClient a reference to the database client
* @param coordinator a reference to the coordinator client
* @return a List of UnManagedVolume associated with the given Host
*/
public static List<UnManagedVolume> findUnManagedVolumesForHost(URI hostUri, DbClient dbClient, CoordinatorClient coordinator) {
_logger.info("finding unmanaged volumes for host " + hostUri);
List<UnManagedVolume> unmanagedVolumes = new ArrayList<UnManagedVolume>();
List<Initiator> initiators = ComputeSystemHelper.queryInitiators(dbClient, hostUri);
Map<String, UnManagedExportMask> cache = new HashMap<String, UnManagedExportMask>();
Host host = dbClient.queryObject(Host.class, hostUri);
Set<String> clusterInis = new HashSet<String>();
/**
* If host is part of a cluster, then unmanaged volumes which are exclusive to this host will be selected
* Get the remaining Host initiators of this cluster, and if there is at least a match between the cluster inis and
* the initiators the unmanaged volume is exposed, then the volume will be skipped.
*/
if (!NullColumnValueGetter.isNullURI(host.getCluster())) {
List<URI> hostUris = ComputeSystemHelper.getChildrenUris(dbClient, host.getCluster(), Host.class, "cluster");
hostUris.remove(hostUri);
for (URI uri : hostUris) {
List<URI> inis = dbClient.queryByConstraint(ContainmentConstraint.Factory.getContainedObjectsConstraint(uri, Initiator.class, "host"));
clusterInis.addAll(Collections2.transform(inis, CommonTransformerFunctions.FCTN_URI_TO_STRING));
}
}
Set<URI> unManagedVolumeUris = new HashSet<URI>();
URIQueryResultList results = new URIQueryResultList();
for (Initiator initiator : initiators) {
_logger.info(" looking at initiator " + initiator.getInitiatorPort());
dbClient.queryByConstraint(AlternateIdConstraint.Factory.getUnManagedVolumeInitiatorNetworkIdConstraint(initiator.getInitiatorPort()), results);
if (results.iterator() != null) {
for (URI uri : results) {
_logger.debug(" found UnManagedVolume " + uri);
unManagedVolumeUris.add(uri);
}
}
}
_logger.info("Found Unmanaged volumes {} associated to Host {}", Joiner.on(",").join(unManagedVolumeUris), hostUri);
for (URI unmanagedVolumeUri : unManagedVolumeUris) {
UnManagedVolume unmanagedVolume = dbClient.queryObject(UnManagedVolume.class, unmanagedVolumeUri);
if (unmanagedVolume == null || unmanagedVolume.getInactive() == true) {
continue;
}
boolean noFilteringOutClusterVolumes = Boolean.valueOf(ControllerUtils.getPropertyValueFromCoordinator(coordinator, UNMANAGEDVOLUME_CLUSTER_FILTERING_SETTING));
Set<String> inisOfunManagedMask = getInitiatorsOfUnmanagedExportMask(unmanagedVolume, cache, dbClient);
Set<String> interSection = Sets.intersection(clusterInis, inisOfunManagedMask);
if (noFilteringOutClusterVolumes || interSection.isEmpty()) {
unmanagedVolumes.add(unmanagedVolume);
_logger.info(" volume: " + unmanagedVolume.getLabel() + " nativeGuid: " + unmanagedVolume.getNativeGuid());
} else {
_logger.info("UnManagedVolume {} is exposed to cluster as well, skipping", unmanagedVolume.getNativeGuid());
}
}
if (unmanagedVolumes.isEmpty()) {
_logger.info(" did not find any unmanaged volumes for this host");
}
return unmanagedVolumes;
}
use of com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedExportMask in project coprhd-controller by CoprHD.
the class VolumeIngestionUtil method findMatchingExportMaskForHost.
/**
* Find matching UnManagedExportMasks for a Host.
*
* @param volume the BlockObject being ingested
* @param unManagedMasks a List of UnManagedExportMasks
* @param initiatorUris a List of Initiator URIs
* @param iniByProtocol a Map of Initiators sorted by protocol
* @param dbClient a reference to the database client
* @param vArray the VirtualArray
* @param vPoolURI the VirtualPool
* @param hostPartOfCluster boolean indicating if the Host is part of a Cluster
* @param initiatorsPartOfCluster initiators that are part of the Cluster
* @param clusterUri the URI of the Cluster
* @param errorMessages error messages to add to if necessary
* @return a List of matching UnManagedExportMasks for a Host
*/
public static <T extends BlockObject> List<UnManagedExportMask> findMatchingExportMaskForHost(T volume, List<UnManagedExportMask> unManagedMasks, Set<String> initiatorUris, Map<String, Set<String>> iniByProtocol, DbClient dbClient, URI vArray, URI vPoolURI, boolean hostPartOfCluster, Set<String> initiatorsPartOfCluster, URI clusterUri, List<String> errorMessages) {
List<UnManagedExportMask> eligibleMasks = new ArrayList<UnManagedExportMask>();
Iterator<UnManagedExportMask> itr = unManagedMasks.iterator();
while (itr.hasNext()) {
// if required initiators are available in the mask, then choose it,
// irrespective of actual initiators on the MV on Array
// if all initiators are available, then choose it
// else, group initiators by protocol
// for each group, find if its a complete subset of the available
// masking views, if yes then choose it
// if its not a complete subset & if other unknown initiators are
// not available, then choose it
UnManagedExportMask mask = itr.next();
if (!VolumeIngestionUtil.validateStoragePortsInVarray(dbClient, volume, vArray, mask.getKnownStoragePortUris(), mask, errorMessages)) {
itr.remove();
_logger.info("unManagedMask skipped due to invalid storage ports: " + mask.getMaskName());
continue;
}
if (null != mask.getKnownInitiatorUris() && !mask.getKnownInitiatorUris().isEmpty()) {
_logger.info("unManagedMask being checked now: " + mask.getMaskName());
_logger.info("Grouping initiators by protocol: {}", Joiner.on(",").join(iniByProtocol.entrySet()));
// group Initiators by Protocol
for (Entry<String, Set<String>> entry : iniByProtocol.entrySet()) {
Set<String> hostInitiatorsForProtocol = entry.getValue();
_logger.info("Processing initiators for {} Protocol Group: {}", entry.getKey(), hostInitiatorsForProtocol);
if (hostPartOfCluster) {
/**
* If Host is part of a Cluster, then
*
* Host's initiators -> UnManagedExportMask's initiators
* case 1: I1,I2 -> I1,I3,I4,I2 [Verify whether I3,I4 are part of then same Cluster, then skip it]
* case 2: I1,I2,I3 -> I1,I2 -- mask selected
* case 3: I1,I3 -> I1,I2 -- not selected
*/
_logger.info("Host in Cluster- Comparing host's initiators [{}] \nwith UnManagedExportMask {} initiators [{}] ", Joiner.on(",").join(getInitiatorNames(URIUtil.toURIList(hostInitiatorsForProtocol), dbClient)), mask.forDisplay(), Joiner.on(",").join(getInitiatorNames(URIUtil.toURIList(mask.getKnownInitiatorUris()), dbClient)));
Set<String> hostInitiatorsNotInUnManagedExportMask = Sets.difference(hostInitiatorsForProtocol, mask.getKnownInitiatorUris());
if (hostInitiatorsNotInUnManagedExportMask.isEmpty()) {
// check whether remaining existing initiators on mask are part of the cluster
Set<String> unManagedExportMaskInitiatorsNotInHost = Sets.difference(mask.getKnownInitiatorUris(), hostInitiatorsForProtocol);
Set<String> remainingInitsNotInClusterOrUnManagedExportMask = Sets.difference(unManagedExportMaskInitiatorsNotInHost, initiatorsPartOfCluster);
_logger.info("The host's initiators are all included in the UnManagedExportMask {} initiators. " + "Checking whether any remaining initiators [{}] in the unmanaged mask are actually " + "included in the cluster {} this host belongs to.", mask.forDisplay(), Joiner.on(",").join(remainingInitsNotInClusterOrUnManagedExportMask), clusterUri);
if (remainingInitsNotInClusterOrUnManagedExportMask.size() == unManagedExportMaskInitiatorsNotInHost.size()) {
_logger.info("UnManagedExportMask {} is a match, as there are no other initiators " + "unaccounted for in the cluster this host belongs to.", mask.forDisplay());
if (verifyNumPath(Collections.singletonList(initiatorUris), mask, volume, vPoolURI, vArray, dbClient)) {
eligibleMasks.add(mask);
} else {
_logger.info("UnManagedExportMask {} doesn't satisfy the num path requirements, so it'll be skipped.", mask.forDisplay());
}
itr.remove();
} else {
_logger.info("Even though UnManagedExportMask {} contains a subset of the cluster's initiators, " + "it can't be used as there are other initiators [{}] in the mask which are owned " + "by a different host in the same cluster this host belongs to.", new Object[] { mask.forDisplay(), Joiner.on(",").join(getInitiatorNames(URIUtil.toURIList(remainingInitsNotInClusterOrUnManagedExportMask), dbClient)), clusterUri });
}
} else {
Set<String> unManagedExportMaskInitiatorsNotInHost = Sets.difference(mask.getKnownInitiatorUris(), hostInitiatorsForProtocol);
if (unManagedExportMaskInitiatorsNotInHost.isEmpty()) {
_logger.info("Matching UnManagedExportMask {} found, as its initiators are a complete subset of the host's initiators.", mask.forDisplay());
if (verifyNumPath(Collections.singletonList(initiatorUris), mask, volume, vPoolURI, vArray, dbClient)) {
eligibleMasks.add(mask);
} else {
_logger.info("UnManagedExportMask {} doesn't satisfy the num path requirements, so it'll be skipped.", mask.forDisplay());
}
itr.remove();
} else {
_logger.info("UnManagedExportMask initiators are not a complete subset of " + "the host's initiators, skipping UnManagedExportMask {}, inits not in host are: {}", mask.forDisplay(), Joiner.on(",").join(getInitiatorNames(URIUtil.toURIList(unManagedExportMaskInitiatorsNotInHost), dbClient)));
}
}
} else {
_logger.info("Host not part of any Cluster- Comparing host's initiators " + "[{}] with UnManagedExportMask's initiators [{}] ", Joiner.on(",").join(getInitiatorNames(URIUtil.toURIList(hostInitiatorsForProtocol), dbClient)), Joiner.on(",").join(getInitiatorNames(URIUtil.toURIList(mask.getKnownInitiatorUris()), dbClient)));
Set<String> unManagedExportMaskInitiatorsNotInHost = Sets.difference(mask.getKnownInitiatorUris(), hostInitiatorsForProtocol);
if (unManagedExportMaskInitiatorsNotInHost.isEmpty()) {
_logger.info("Matching UnManagedExportMask {} found, since its initiators " + "are a complete subset of the host's initiators", mask.getMaskName());
if (verifyNumPath(Collections.singletonList(initiatorUris), mask, volume, vPoolURI, vArray, dbClient)) {
eligibleMasks.add(mask);
} else {
_logger.info("UnManagedExportMask {} doesn't satisfy the num path requirements, so it'll be skipped.", mask.forDisplay());
}
itr.remove();
} else {
_logger.info("UnManagedExportMask has initiators from a different host [{}], not part of cluster", Joiner.on(",").join(getInitiatorNames(URIUtil.toURIList(unManagedExportMaskInitiatorsNotInHost), dbClient)));
}
}
}
}
}
_logger.info("returning host eligible masks: " + getMaskNames(URIUtil.toUris(eligibleMasks), dbClient));
return eligibleMasks;
}
use of com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedExportMask in project coprhd-controller by CoprHD.
the class VolumeIngestionUtil method clearInternalFlags.
/**
* This method will clear the internal flags set during ingestion.
* Before clearing the flags check if there is any unmanaged volume corresponding to the block object.
* If yes, then perform the below operations:
* 1) Find all the export masks corresponding to the unmanaged export masks of the unmanaged volume.
* For each export mask:
* a) Remove the block object from existing volumes of the export mask
* b) Add the block object to user created volumes of the export mask
* 2) Get the export groups corresponding to the export masks and add the block object to the export groups
* 3) Remove the unmanaged volume from the unmanaged export mask
* 4) Remove the unmanaged export mask from the unmanaged volume
*
* @param blockObject the BlockObject to clear flags on
* @param updatedObjects a Set of DataObjects being updated related to the given BlockObject
* @param dbClient a reference to the database client
*/
public static void clearInternalFlags(IngestionRequestContext requestContext, BlockObject blockObject, Set<DataObject> updatedObjects, DbClient dbClient) {
// for each block object, get the corresponding unmanaged volume.
_logger.info("clearInternalFlags for blockObject " + blockObject.forDisplay());
boolean isVplexBackendVolume = false;
boolean isRPVolume = false;
UnManagedVolume unManagedVolume = getUnManagedVolumeForBlockObject(blockObject, dbClient);
if (unManagedVolume != null) {
UnManagedVolume loadedUnmanagedVolume = requestContext.findDataObjectByType(UnManagedVolume.class, unManagedVolume.getId(), false);
unManagedVolume = ((loadedUnmanagedVolume != null) ? loadedUnmanagedVolume : unManagedVolume);
}
if (unManagedVolume != null) {
// Check if this is a VPLEX backend volume, which we need to treat a little differently
isVplexBackendVolume = VolumeIngestionUtil.isVplexBackendVolume(unManagedVolume);
// Check if this is a RP volume
isRPVolume = VolumeIngestionUtil.checkUnManagedResourceIsRecoverPointEnabled(unManagedVolume);
// Get the exportGroupType from the unManagedVolume
String exportGroupType = unManagedVolume.getVolumeCharacterstics().get(SupportedVolumeCharacterstics.EXPORTGROUP_TYPE.toString());
Set<URI> supportedVirtualArrays = new HashSet<URI>();
supportedVirtualArrays.add(blockObject.getVirtualArray());
// virtual array
if (blockObject instanceof Volume && RPHelper.isMetroPointVolume(dbClient, (Volume) blockObject)) {
StringSet vplexBackendVolumes = PropertySetterUtil.extractValuesFromStringSet(SupportedVolumeInformation.VPLEX_BACKEND_VOLUMES.toString(), unManagedVolume.getVolumeInformation());
if (vplexBackendVolumes != null && !vplexBackendVolumes.isEmpty()) {
StringSet vplexBackendVolumeGUIDs = getListofVolumeIds(vplexBackendVolumes);
List<BlockObject> associatedVolumes = getVolumeObjects(vplexBackendVolumeGUIDs, requestContext, dbClient);
for (BlockObject associatedVolume : associatedVolumes) {
supportedVirtualArrays.add(associatedVolume.getVirtualArray());
}
}
}
// If there are unmanaged export masks, get the corresponding ViPR export masks
StringSet unmanagedExportMasks = unManagedVolume.getUnmanagedExportMasks();
if (null != unmanagedExportMasks && !unmanagedExportMasks.isEmpty()) {
List<URI> unManagedMaskUris = new ArrayList<URI>(Collections2.transform(unmanagedExportMasks, CommonTransformerFunctions.FCTN_STRING_TO_URI));
List<UnManagedExportMask> unManagedMasks = new ArrayList<UnManagedExportMask>();
for (URI uri : unManagedMaskUris) {
UnManagedExportMask uem = requestContext.findDataObjectByType(UnManagedExportMask.class, uri, true);
if (uem != null) {
unManagedMasks.add(uem);
}
}
for (UnManagedExportMask unManagedExportMask : unManagedMasks) {
Map<URI, ExportMask> exportMaskMap = new HashMap<URI, ExportMask>();
List<URI> initiatorUris = new ArrayList<URI>(Collections2.transform(unManagedExportMask.getKnownInitiatorUris(), CommonTransformerFunctions.FCTN_STRING_TO_URI));
for (URI ini : initiatorUris) {
List<URI> exportMaskUris = dbClient.queryByConstraint(AlternateIdConstraint.Factory.getExportMaskInitiatorConstraint(ini.toString()));
if (null == exportMaskUris) {
continue;
}
for (URI eMaskUri : exportMaskUris) {
ExportMask eMask = requestContext.findDataObjectByType(ExportMask.class, eMaskUri, true);
if ((null != eMask) && (null != eMask.getStorageDevice()) && eMask.getStorageDevice().equals(unManagedExportMask.getStorageSystemUri())) {
if (!exportMaskMap.containsKey(eMaskUri)) {
_logger.info("Found Mask {} with matching initiator and matching Storage System", eMaskUri);
exportMaskMap.put(eMaskUri, eMask);
}
} else {
_logger.info("Found Mask {} with matching initiator and unmatched Storage System. Skipping mask", eMaskUri);
}
}
}
Set<ExportGroup> exportGroups = new HashSet<ExportGroup>();
// Remove the block object from existing volumes and add to the user created volumes of the export mask
for (ExportMask exportMask : exportMaskMap.values()) {
String normalizedWWN = BlockObject.normalizeWWN(blockObject.getWWN());
if (null == normalizedWWN) {
throw IngestionException.exceptions.exportedVolumeIsMissingWwn(unManagedVolume.getLabel());
}
boolean foundExportMask = false;
if (exportMask.hasAnyExistingVolumes() && exportMask.getExistingVolumes().containsKey(normalizedWWN)) {
_logger.info("Removing block object {} from existing volumes and adding to user created volumes of export mask {}", blockObject.getNativeGuid(), exportMask.getMaskName());
exportMask.removeFromExistingVolumes(blockObject);
exportMask.addToUserCreatedVolumes(blockObject);
updatedObjects.add(exportMask);
foundExportMask = true;
exportGroups.addAll(ExportMaskUtils.getExportGroups(dbClient, exportMask));
}
if (foundExportMask) {
_logger.info("breaking relationship between UnManagedExportMask {} and UnManagedVolume {}", unManagedExportMask.getMaskName(), unManagedVolume.forDisplay());
unManagedVolume.getUnmanagedExportMasks().remove(unManagedExportMask.getId().toString());
unManagedExportMask.getUnmanagedVolumeUris().remove(unManagedVolume.getId().toString());
updatedObjects.add(unManagedExportMask);
}
}
// If the mask for ingested volume contains JOURNAL keyword, make sure we add it to
// the ExportGroup created for journals
boolean isJournalExport = false;
if (unManagedExportMask.getMaskName().toLowerCase().contains(RP_JOURNAL)) {
isJournalExport = true;
}
_logger.info("exportGroupType is " + exportGroupType);
URI computeResource = requestContext.getCluster() != null ? requestContext.getCluster() : requestContext.getHost();
_logger.info("computeResource is " + computeResource);
// Add the block object to the export groups corresponding to the export masks
for (ExportGroup exportGroup : exportGroups) {
_logger.info("Processing exportGroup {} to add block object", exportGroup.forDisplay());
// only add to those export groups whose project and varray matches the block object
_logger.info("exportGroup.getType() is " + exportGroup.getType());
boolean exportGroupTypeMatches = (null != exportGroupType) && exportGroupType.equalsIgnoreCase(exportGroup.getType());
boolean isRPJournalExportGroup = exportGroup.checkInternalFlags(Flag.RECOVERPOINT_JOURNAL);
// the ExportGroup created for journals
if (isJournalExport && !isRPJournalExportGroup) {
_logger.info("Block object is associated with RP journal mask but export group is not marked for RP journals. Not adding to the export group");
continue;
} else if (!isJournalExport && isRPJournalExportGroup) {
_logger.info("Block object is not associated with RP journal mask but export group is marked for RP journals. Not adding to the export group");
continue;
}
if (exportGroup.getProject().getURI().equals(getBlockProject(blockObject)) && supportedVirtualArrays.contains(exportGroup.getVirtualArray()) && (exportGroupTypeMatches || isVplexBackendVolume)) {
// check if this ExportGroup URI has already been loaded in this ingestion request
ExportGroup loadedExportGroup = requestContext.findDataObjectByType(ExportGroup.class, exportGroup.getId(), false);
// if it wasn't found for update, check if it's tied to any ingestion contexts
if (loadedExportGroup == null) {
loadedExportGroup = requestContext.findExportGroup(exportGroup.getLabel(), exportGroup.getProject().getURI(), exportGroup.getVirtualArray(), computeResource, exportGroup.getType());
}
// if an ExportGroup for the URI and params was found, use it
if (loadedExportGroup != null) {
_logger.info("Adding block object {} to already-loaded export group {}", blockObject.getNativeGuid(), loadedExportGroup.getLabel());
exportGroup = loadedExportGroup;
} else {
_logger.info("Adding block object {} to newly-loaded export group {}", blockObject.getNativeGuid(), exportGroup.getLabel());
updatedObjects.add(exportGroup);
}
exportGroup.addVolume(blockObject.getId(), ExportGroup.LUN_UNASSIGNED);
}
}
}
} else {
_logger.info("No unmanaged export masks found for the unmanaged volume {}", unManagedVolume.getNativeGuid());
}
if (canDeleteUnManagedVolume(unManagedVolume)) {
_logger.info("Set unmanaged volume inactive: {}", unManagedVolume.forDisplay());
unManagedVolume.setInactive(true);
requestContext.getUnManagedVolumesToBeDeleted().add(unManagedVolume);
} else {
updatedObjects.add(unManagedVolume);
}
} else {
_logger.info("No unmanaged volume found for the block object {}", blockObject.getNativeGuid());
}
blockObject.clearInternalFlags(BlockIngestOrchestrator.INTERNAL_VOLUME_FLAGS);
// Do not clear the flags for snapshot sessions associated with RP volumes till the RP CG is fully ingested.
if (getRPUnmanagedVolume(unManagedVolume, dbClient) == null) {
clearSnapshotSessionsFlags(blockObject, updatedObjects, dbClient);
}
if ((blockObject instanceof Volume) && (isVplexBackendVolume || isRPVolume)) {
// VPLEX backend volumes and RP protected volumes should still have the INTERNAL_OBJECT flag.
// Note that snapshots can also be VPLEX backend volumes so make sure
// to also check the type of the block object. We don't want a
// BlockSnapshot instance to be made internal. The ingestion process
// will also create Volume instance to represent the backend volume
// and this is what will be marked internal.
// RP volumes will be made visible when the RP CG is fully ingested
blockObject.addInternalFlags(Flag.INTERNAL_OBJECT);
}
}
use of com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedExportMask in project coprhd-controller by CoprHD.
the class VolumeIngestionUtil method findUserAddedInisFromExistingIniListInMask.
/**
* Find the user-added initiators from a List of existing Initiators.
*
* @param existingInitiators a List of existing Initiators
* @param excludeUnmanagedMask an UnManagedExportMask URI to exclude
* @param dbClient a reference to the database client
* @return a List of user-added Initiators
*/
public static List<Initiator> findUserAddedInisFromExistingIniListInMask(List<Initiator> existingInitiators, URI excludeUnmanagedMask, DbClient dbClient) {
List<Initiator> userAddedInis = new ArrayList<Initiator>();
for (Initiator initiator : existingInitiators) {
// get All unmanaged masks
List<URI> unManagedMaskUris = dbClient.queryByConstraint(AlternateIdConstraint.Factory.getUnManagedExportMaskKnownInitiatorConstraint(initiator.getInitiatorPort()));
if (null == unManagedMaskUris || unManagedMaskUris.isEmpty()) {
_logger.info("UnManaged Masks Empty, adding initiator {}..{} to userAddedList", initiator.getId(), initiator.getInitiatorPort());
userAddedInis.add(initiator);
} else {
unManagedMaskUris.remove(excludeUnmanagedMask);
if (unManagedMaskUris.isEmpty()) {
userAddedInis.add(initiator);
}
List<UnManagedExportMask> unManagedMasks = dbClient.queryObject(UnManagedExportMask.class, unManagedMaskUris);
for (UnManagedExportMask unManagedMask : unManagedMasks) {
ExportMask exportMask = getExportsMaskAlreadyIngested(unManagedMask, dbClient);
if (null != exportMask && exportMask.getCreatedBySystem()) {
_logger.info("ViPR created/ingested Export Mask {} found for unmanaged mask, adding initiator {}..{} to userAddedList", new Object[] { exportMask.getMaskName(), initiator.getId(), initiator.getInitiatorPort() });
// update the userAddedInitiators for those already ingested export mask as well.
exportMask.addToUserCreatedInitiators(initiator);
exportMask.addToExistingInitiatorsIfAbsent(initiator);
exportMask.addInitiator(initiator);
dbClient.updateAndReindexObject(exportMask);
userAddedInis.add(initiator);
} else {
_logger.info("UnManaged Mask {} doesn't have any ViPR created export masks, skipping initiator from user added list", unManagedMask.getMaskName(), initiator.getId());
}
}
}
}
_logger.info("User Added Initiators found {}", Joiner.on(",").join(userAddedInis));
return userAddedInis;
}
use of com.emc.storageos.db.client.model.UnManagedDiscoveredObjects.UnManagedExportMask in project coprhd-controller by CoprHD.
the class BlockIngestExportOrchestrator method ingestExportMasks.
/**
* Ingests UnManagedExportMasks associated with the current UnManagedVolume being processed.
*
* @param requestContext the IngestionRequestContext for this ingestion process
* @param unManagedVolume unManagedVolume to ingest
* @param blockObject created BlockObject
* @param unManagedMasks list of unmanaged masks this unmanaged volume is associated with
* @param masksIngestedCount number of export masks ingested
*/
protected <T extends BlockObject> void ingestExportMasks(IngestionRequestContext requestContext, UnManagedVolume unManagedVolume, T blockObject, List<UnManagedExportMask> unManagedMasks, MutableInt masksIngestedCount) throws IngestionException {
try {
_logger.info("Ingesting unmanaged masks {} for unmanaged volume {}", Joiner.on(",").join(unManagedVolume.getUnmanagedExportMasks()), unManagedVolume.getNativeGuid());
VolumeIngestionUtil.validateUnManagedExportMasks(unManagedVolume, unManagedMasks, _dbClient);
List<UnManagedExportMask> uemsToPersist = new ArrayList<UnManagedExportMask>();
Iterator<UnManagedExportMask> itr = unManagedMasks.iterator();
List<String> errorMessages = requestContext.getErrorMessagesForVolume(unManagedVolume.getNativeGuid());
ExportGroup exportGroup = requestContext.getExportGroup();
StorageSystem system = requestContext.getStorageSystem();
boolean portGroupEnabled = false;
if (Type.vmax.name().equals(system.getSystemType())) {
portGroupEnabled = Boolean.valueOf(_customConfigHandler.getComputedCustomConfigValue(CustomConfigConstants.VMAX_USE_PORT_GROUP_ENABLED, system.getSystemType(), null));
}
Host host = null;
Cluster cluster = null;
List<Host> hosts = new ArrayList<Host>();
String exportGroupType = null;
if (null != requestContext.getHost()) {
host = _dbClient.queryObject(Host.class, requestContext.getHost());
hosts.add(host);
exportGroupType = ExportGroupType.Host.name();
}
if (null != requestContext.getCluster()) {
cluster = _dbClient.queryObject(Cluster.class, requestContext.getCluster());
hosts.addAll(getHostsOfCluster(requestContext.getCluster()));
exportGroupType = ExportGroupType.Cluster.name();
}
// In cluster/Host , if we don't find at least 1 initiator in
// registered state, then skip this volume from ingestion.
StringSet computeInitiators = new StringSet();
for (Host hostObj : hosts) {
Set<String> initiatorSet = getInitiatorsOfHost(hostObj.getId());
Set<URI> initiatorUris = new HashSet<URI>(Collections2.transform(initiatorSet, CommonTransformerFunctions.FCTN_STRING_TO_URI));
List<Initiator> initiators = _dbClient.queryObject(Initiator.class, initiatorUris);
if (!VolumeIngestionUtil.validateInitiatorPortsRegistered(initiators)) {
// logs already inside the above method.
_logger.warn("Host skipped {} as we can't find at least 1 initiator in registered status", hostObj.getLabel());
return;
}
computeInitiators.addAll(initiatorSet);
}
if (null != requestContext.getDeviceInitiators() && !requestContext.getDeviceInitiators().isEmpty()) {
if (exportGroup.checkInternalFlags(Flag.RECOVERPOINT)) {
// RP export groups are cluster-based, although they don't contains a cluster/host ID
exportGroupType = ExportGroupType.Cluster.name();
} else {
// note: ViPR-generated greenfield VPLEX export groups
// actually have no export group type set
exportGroupType = ExportGroupType.Host.name();
}
if (!VolumeIngestionUtil.validateInitiatorPortsRegistered(requestContext.getDeviceInitiators())) {
_logger.warn("Device with initiators {} skipped as we can't " + "find at least 1 initiator in registered status", requestContext.getDeviceInitiators());
return;
}
// For validation checks below, add these initiator to the compute resource list
for (Initiator initiator : requestContext.getDeviceInitiators()) {
computeInitiators.add(initiator.getId().toString());
}
}
// update the ExportGroupType in UnManagedVolume. This will be used to place the
// volume in the right ExportGroup based on the ExportGroupType.
updateExportTypeInUnManagedVolume(unManagedVolume, exportGroupType);
// then add this unmanaged volume to the mask.
while (itr.hasNext()) {
UnManagedExportMask unManagedExportMask = itr.next();
if (!VolumeIngestionUtil.validateStoragePortsInVarray(_dbClient, blockObject, requestContext.getVarray(unManagedVolume).getId(), unManagedExportMask.getKnownStoragePortUris(), unManagedExportMask, errorMessages)) {
// logs already inside the above method.
itr.remove();
continue;
}
if (!VolumeIngestionUtil.validateExportMaskMatchesComputeResourceInitiators(_dbClient, exportGroup, computeInitiators, unManagedExportMask, errorMessages)) {
// logs already inside the above method.
itr.remove();
continue;
}
if (VolumeIngestionUtil.isVplexVolume(unManagedVolume)) {
boolean crossConnectedDistributedVolume = VolumeIngestionUtil.isVplexDistributedVolume(unManagedVolume) && requestContext.getVpool(unManagedVolume).getAutoCrossConnectExport();
if (!crossConnectedDistributedVolume && !VolumeIngestionUtil.isRpExportMask(unManagedExportMask, _dbClient) && !VolumeIngestionUtil.validateExportMaskMatchesVplexCluster(requestContext, unManagedVolume, unManagedExportMask)) {
// logs already inside the above method.
itr.remove();
continue;
}
}
_logger.info("looking for an existing export mask for " + unManagedExportMask.getMaskName());
ExportMask exportMask = getExportMaskAlreadyIngested(unManagedExportMask, _dbClient);
if (null != exportMask) {
// check if mask has already been loaded
DataObject loadedExportMask = requestContext.findInUpdatedObjects(exportMask.getId());
if (loadedExportMask != null) {
exportMask = (ExportMask) loadedExportMask;
}
} else {
// check if mask has already been created
exportMask = getExportMaskAlreadyCreated(unManagedExportMask, requestContext.getRootIngestionRequestContext(), _dbClient);
if (exportMask == null) {
continue;
}
}
_logger.info("Export Mask {} already available", exportMask.getMaskName());
masksIngestedCount.increment();
List<URI> iniList = new ArrayList<URI>(Collections2.transform(exportMask.getInitiators(), CommonTransformerFunctions.FCTN_STRING_TO_URI));
List<Initiator> initiators = _dbClient.queryObject(Initiator.class, iniList);
// of the mask, else add it to user created volumes
if (blockObject.checkInternalFlags(Flag.PARTIALLY_INGESTED)) {
_logger.info("Block object {} is marked internal. Adding to existing volumes of the mask {}", blockObject.getNativeGuid(), exportMask.getMaskName());
exportMask.addToExistingVolumesIfAbsent(blockObject, ExportGroup.LUN_UNASSIGNED_STR);
} else {
exportMask.addToUserCreatedVolumes(blockObject);
// remove this volume if already in existing
exportMask.removeFromExistingVolumes(blockObject);
}
// Add new initiators found in ingest to list if absent.
exportMask.addInitiators(initiators);
// Add all unknown initiators to existing
exportMask.addToExistingInitiatorsIfAbsent(new ArrayList(unManagedExportMask.getUnmanagedInitiatorNetworkIds()));
// Always set this flag to true for ingested masks.
exportMask.setCreatedBySystem(true);
ExportMaskUtils.setExportMaskResource(_dbClient, exportGroup, exportMask);
List<Initiator> userAddedInis = VolumeIngestionUtil.findUserAddedInisFromExistingIniListInMask(initiators, unManagedExportMask.getId(), _dbClient);
exportMask.addToUserCreatedInitiators(userAddedInis);
// remove from existing if present - possible in ingestion after
// coexistence
exportMask.removeFromExistingInitiator(userAddedInis);
// need to sync up all remaining existing volumes
Map<String, Integer> wwnToHluMap = VolumeIngestionUtil.extractWwnToHluMap(unManagedExportMask, _dbClient);
exportMask.addToExistingVolumesIfAbsent(wwnToHluMap);
// find the HLU and set it in the volumes
Integer hlu = ExportGroup.LUN_UNASSIGNED;
if (wwnToHluMap.containsKey(blockObject.getWWN())) {
hlu = wwnToHluMap.get(blockObject.getWWN());
}
exportMask.addVolume(blockObject.getId(), hlu);
// adding volume we need to add FCZoneReferences
StringSetMap zoneMap = ExportMaskUtils.getZoneMapFromZoneInfoMap(unManagedExportMask.getZoningMap(), initiators);
if (!zoneMap.isEmpty()) {
exportMask.setZoningMap(zoneMap);
}
requestContext.addDataObjectToUpdate(exportMask, unManagedVolume);
ExportMaskUtils.updateFCZoneReferences(exportGroup, exportMask, blockObject, unManagedExportMask.getZoningMap(), initiators, _dbClient);
// remove the unmanaged mask from unmanaged volume only if the block object has not been marked as internal
if (!blockObject.checkInternalFlags(Flag.PARTIALLY_INGESTED)) {
_logger.info("block object {} is fully ingested, " + "breaking relationship between UnManagedExportMask {} and UnManagedVolume {}", blockObject.forDisplay(), unManagedExportMask.getMaskName(), unManagedVolume.forDisplay());
unManagedVolume.getUnmanagedExportMasks().remove(unManagedExportMask.getId().toString());
unManagedExportMask.getUnmanagedVolumeUris().remove(unManagedVolume.getId().toString());
uemsToPersist.add(unManagedExportMask);
}
if (exportGroup.getExportMasks() == null || !exportGroup.getExportMasks().contains(exportMask.getId().toString())) {
exportGroup.addExportMask(exportMask.getId().toString());
}
VolumeIngestionUtil.updateExportGroup(exportGroup, blockObject, wwnToHluMap, _dbClient, initiators, hosts, cluster);
_logger.info("Removing unmanaged mask {} from the list of items to process, as block object is added already", unManagedExportMask.getMaskName());
itr.remove();
requestContext.addDataObjectToUpdate(exportMask, unManagedVolume);
}
_logger.info("{} unmanaged mask(s) validated as eligible for further processing: {}", unManagedMasks.size(), VolumeIngestionUtil.getMaskNames(URIUtil.toUris(unManagedMasks), _dbClient));
URI blockId = null;
if (!blockObject.checkInternalFlags(Flag.PARTIALLY_INGESTED)) {
blockId = blockObject.getId();
}
List<ExportMask> exportMasksToCreate = new ArrayList<ExportMask>();
List<UnManagedExportMask> eligibleMasks = null;
if (!unManagedMasks.isEmpty()) {
if (null != cluster) {
_logger.info("Processing Cluster {}", cluster.forDisplay());
// get Hosts for Cluster & get Initiators by Host Name
// TODO handle multiple Hosts in one call
List<URI> hostUris = ComputeSystemHelper.getChildrenUris(_dbClient, requestContext.getCluster(), Host.class, "cluster");
_logger.info("Found Hosts {} in cluster {}", Joiner.on(",").join(hostUris), cluster.forDisplay());
List<Set<String>> iniGroupByHost = new ArrayList<Set<String>>();
URI varrayUri = requestContext.getVarray(unManagedVolume).getId();
boolean isVplexDistributedVolume = VolumeIngestionUtil.isVplexDistributedVolume(unManagedVolume);
boolean isVplexAutoCrossConnect = requestContext.getVpool(unManagedVolume).getAutoCrossConnectExport();
for (URI hostUri : hostUris) {
Set<String> initsOfHost = getInitiatorsOfHost(hostUri);
Host host2 = _dbClient.queryObject(Host.class, hostUri);
_logger.info("Host {} has these initiators: " + VolumeIngestionUtil.getInitiatorNames(URIUtil.toURIList(initsOfHost), _dbClient), host2.forDisplay());
if (isVplexDistributedVolume && !isVplexAutoCrossConnect) {
_logger.info("this is a distributed vplex volume which may have split fabrics with different connectivity per host");
Iterator<String> initsOfHostIt = initsOfHost.iterator();
while (initsOfHostIt.hasNext()) {
String uriStr = initsOfHostIt.next();
Initiator init = _dbClient.queryObject(Initiator.class, URI.create(uriStr));
if (null != init) {
_logger.info("checking initiator {} for connectivity", init.getInitiatorPort());
Set<String> connectedVarrays = ConnectivityUtil.getInitiatorVarrays(init.getInitiatorPort(), _dbClient);
_logger.info("initiator's connected varrays are: {}", connectedVarrays);
if (!connectedVarrays.contains(varrayUri.toString())) {
_logger.info("initiator {} of host {} is not connected to varray {}, removing", init.getInitiatorPort(), host2.getLabel(), VolumeIngestionUtil.getVarrayName(varrayUri, _dbClient));
initsOfHostIt.remove();
}
}
}
}
if (!initsOfHost.isEmpty()) {
iniGroupByHost.add(initsOfHost);
}
}
eligibleMasks = VolumeIngestionUtil.findMatchingExportMaskForCluster(blockObject, unManagedMasks, iniGroupByHost, _dbClient, varrayUri, requestContext.getVpool(unManagedVolume).getId(), requestContext.getCluster(), errorMessages);
// Volume cannot be exposed to both Cluster and Host
if (eligibleMasks.size() == 1) {
// all initiators of all hosts in 1 MV
// add Volume,all Initiators and StoragePorts to
// ExportMask
_logger.info("Only 1 eligible mask found for cluster {}: ", cluster.forDisplay(), eligibleMasks.get(0).toString());
ExportMask exportMaskToCreate = VolumeIngestionUtil.createExportMask(eligibleMasks.get(0), unManagedVolume, exportGroup, blockObject, _dbClient, hosts, cluster, cluster.getLabel());
updateExportMaskWithPortGroup(system, eligibleMasks.get(0), exportMaskToCreate, exportGroup, blockId);
exportMasksToCreate.add(exportMaskToCreate);
uemsToPersist.add(eligibleMasks.get(0));
masksIngestedCount.increment();
} else if (eligibleMasks.size() > 1) {
_logger.info("Multiple masks found for cluster {}: {}", cluster.forDisplay(), Joiner.on(";").join(eligibleMasks));
// 1 MV per Cluster Node
for (UnManagedExportMask eligibleMask : eligibleMasks) {
_logger.info("Setting up eligible mask " + eligibleMask.forDisplay());
ExportMask exportMaskToCreate = VolumeIngestionUtil.createExportMask(eligibleMask, unManagedVolume, exportGroup, blockObject, _dbClient, hosts, cluster, cluster.getLabel());
updateExportMaskWithPortGroup(system, eligibleMask, exportMaskToCreate, exportGroup, blockId);
exportMasksToCreate.add(exportMaskToCreate);
uemsToPersist.add(eligibleMask);
masksIngestedCount.increment();
}
}
} else if (null != host) {
_logger.info("Processing Host {} ", host.forDisplay());
Set<String> initiatorSet = getInitiatorsOfHost(requestContext.getHost());
boolean hostPartOfCluster = (!NullColumnValueGetter.isNullURI(host.getCluster()));
Map<String, Set<String>> iniByProtocol = VolumeIngestionUtil.groupInitiatorsByProtocol(initiatorSet, _dbClient);
eligibleMasks = VolumeIngestionUtil.findMatchingExportMaskForHost(blockObject, unManagedMasks, initiatorSet, iniByProtocol, _dbClient, requestContext.getVarray(unManagedVolume).getId(), requestContext.getVpool(unManagedVolume).getId(), hostPartOfCluster, getInitiatorsOfCluster(host.getCluster(), hostPartOfCluster), null, errorMessages);
if (!eligibleMasks.isEmpty()) {
_logger.info("Eligible masks found for Host {}: {}", host.forDisplay(), Joiner.on(",").join(eligibleMasks));
} else {
_logger.info("No eligible unmanaged export masks found for Host {}", host.forDisplay());
}
for (UnManagedExportMask eligibleMask : eligibleMasks) {
_logger.info("Setting up eligible mask " + eligibleMask.forDisplay());
ExportMask exportMaskToCreate = VolumeIngestionUtil.createExportMask(eligibleMask, unManagedVolume, exportGroup, blockObject, _dbClient, hosts, cluster, host.getHostName());
updateExportMaskWithPortGroup(system, eligibleMask, exportMaskToCreate, exportGroup, blockId);
exportMasksToCreate.add(exportMaskToCreate);
uemsToPersist.add(eligibleMask);
masksIngestedCount.increment();
}
} else if (null != requestContext.getDeviceInitiators() && !requestContext.getDeviceInitiators().isEmpty()) {
List<Initiator> deviceInitiators = requestContext.getDeviceInitiators();
_logger.info("Processing device initiators {}", deviceInitiators);
Set<String> initiatorSet = new HashSet<String>();
for (Initiator init : deviceInitiators) {
initiatorSet.add(init.getId().toString());
}
boolean hostPartOfCluster = false;
Map<String, Set<String>> iniByProtocol = VolumeIngestionUtil.groupInitiatorsByProtocol(initiatorSet, _dbClient);
eligibleMasks = VolumeIngestionUtil.findMatchingExportMaskForHost(blockObject, unManagedMasks, initiatorSet, iniByProtocol, _dbClient, requestContext.getVarray(unManagedVolume).getId(), requestContext.getVpool(unManagedVolume).getId(), hostPartOfCluster, getInitiatorsOfCluster(null, hostPartOfCluster), null, errorMessages);
if (!eligibleMasks.isEmpty()) {
_logger.info("Eligible masks found for device initiators {}: {}", deviceInitiators, Joiner.on(",").join(eligibleMasks));
} else {
_logger.info("No eligible unmanaged export masks found for device initiators {}", deviceInitiators);
}
for (UnManagedExportMask eligibleMask : eligibleMasks) {
_logger.info("Setting up eligible mask " + eligibleMask.forDisplay());
// this getHostName will be the name of the VPLEX device
ExportMask exportMaskToCreate = VolumeIngestionUtil.createExportMask(eligibleMask, unManagedVolume, exportGroup, blockObject, _dbClient, hosts, cluster, deviceInitiators.get(0).getHostName());
updateExportMaskWithPortGroup(system, eligibleMask, exportMaskToCreate, exportGroup, blockId);
exportMasksToCreate.add(exportMaskToCreate);
uemsToPersist.add(eligibleMask);
masksIngestedCount.increment();
}
}
}
for (UnManagedExportMask uem : uemsToPersist) {
requestContext.addDataObjectToUpdate(uem, unManagedVolume);
}
for (ExportMask exportMaskToCreate : exportMasksToCreate) {
requestContext.addDataObjectToCreate(exportMaskToCreate, unManagedVolume);
exportGroup.addExportMask(exportMaskToCreate.getId());
}
} catch (IngestionException e) {
throw e;
} catch (Exception e) {
_logger.error("Export Mask Ingestion failed for UnManaged block object : {}", unManagedVolume.getNativeGuid(), e);
}
}
Aggregations