use of com.emc.storageos.api.service.impl.resource.blockingestorchestration.IngestionException in project coprhd-controller by CoprHD.
the class VolumeIngestionUtil method findMatchingExportMaskForCluster.
/**
* Find matching UnManagedExportMasks for a Cluster.
*
* @param volume the BlockObject being ingested
* @param unManagedMasks a List of UnManagedExportMasks
* @param initiatorUris a List of Initiator URIs
* @param dbClient a reference to the database client
* @param vArray the VirtualArray
* @param vPoolURI the VirtualPool
* @param clusterUri the URI of the Cluster
* @param errorMessages error messages to add to if necessary
* @return a List of matching UnManagedExportMasks for a Cluster
*/
public static <T extends BlockObject> List<UnManagedExportMask> findMatchingExportMaskForCluster(T volume, List<UnManagedExportMask> unManagedMasks, List<Set<String>> initiatorUris, DbClient dbClient, URI vArray, URI vPoolURI, URI cluster, List<String> errorMessages) {
List<UnManagedExportMask> eligibleMasks = new ArrayList<UnManagedExportMask>();
Set<String> clusterInitiators = new HashSet<String>();
for (Set<String> initiatorUriList : initiatorUris) {
clusterInitiators.addAll(initiatorUriList);
}
Map<String, Set<String>> clusterIniByProtocol = groupInitiatorsByProtocol(clusterInitiators, dbClient);
Iterator<UnManagedExportMask> itr = unManagedMasks.iterator();
List<String> maskErrorMessages = new ArrayList<String>();
try {
while (itr.hasNext()) {
UnManagedExportMask mask = itr.next();
if (!VolumeIngestionUtil.validateStoragePortsInVarray(dbClient, volume, vArray, mask.getKnownStoragePortUris(), mask, errorMessages)) {
// not a valid mask remove it
itr.remove();
_logger.info("unManagedMask skipped due to invalid storage ports: " + mask.getMaskName());
continue;
}
// irrespective of actual initiators on the MV on Array
if (null != mask.getKnownInitiatorUris() && !mask.getKnownInitiatorUris().isEmpty()) {
_logger.info("unManagedMask being checked now: " + mask.getMaskName());
for (Entry<String, Set<String>> entry : clusterIniByProtocol.entrySet()) {
Set<String> clusterInitiatorsForProtocol = entry.getValue();
_logger.info("Processing Initiators by {} Protocol Group: {}", entry.getKey(), clusterInitiatorsForProtocol);
_logger.info("Comparing cluster's initiators [{}] \nwith UnManagedExportMask's initiators [{}] ", Joiner.on(",").join(getInitiatorNames(URIUtil.toURIList(clusterInitiatorsForProtocol), dbClient)), Joiner.on(",").join(getInitiatorNames(URIUtil.toURIList(mask.getKnownInitiatorUris()), dbClient)));
Set<String> unmanagedExportMaskInitiatorsNotInCluster = Sets.difference(mask.getKnownInitiatorUris(), clusterInitiatorsForProtocol);
/**
* Host's initiators -> UnManagedExportMask's initiators
* case 1: I1,I2,I3,I4 -> I1,I2 -- mask skipped, as I1,I2 are initiators of a single node in cluster (exclusive export mode)
* case 2: I1,I2 -> I1,I2,I3 -- mask selected
* case 3: I1,I3 -> I1,I2 -- not selected
*/
if (unmanagedExportMaskInitiatorsNotInCluster.isEmpty()) {
_logger.info("UnManagedExportMask {} matches: its initiators are all included in the cluster's initiators. " + "Will try to find whether the subset actually corresponds to a single node in the cluster. " + "If true, then skip this UnManagedExportMask, as it is meant for Exclusive mode exports.", mask.forDisplay());
if (groupInitiatorsByHost(mask.getKnownInitiatorUris(), dbClient).size() == 1) {
_logger.info("Skipping UnManagedExportMask {}, as the mask has only initiators from a single node in the cluster. " + "It is probably meant for Exclusive mode export.", mask.forDisplay());
} else {
_logger.info("UnManagedExportMask {} found with a subset of initiators from more than a single node in the cluster.", mask.forDisplay());
if (verifyNumPath(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("The initiators of UnManagedExportMask {} are NOT all included in the cluster's initiators, " + "checking whether the cluster's initiators are a subset of the UnManagedExportMask's initiators instead.");
Set<String> clusterInitiatorsNotInUnManagedExportMask = Sets.difference(clusterInitiatorsForProtocol, mask.getKnownInitiatorUris());
if (clusterInitiatorsNotInUnManagedExportMask.isEmpty()) {
_logger.info("UnManagedExportMask {} found with a subset of the cluster's initiators.", mask.forDisplay());
if (verifyNumPath(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();
}
}
}
}
}
if (eligibleMasks.isEmpty() && !unManagedMasks.isEmpty()) {
_logger.info("Unable to find a masking construct with all the cluster initiators. " + "Grouping initiators by host and restarting the search.");
// well, to support exclusive mode volume export.
for (Set<String> initiatorUriList : initiatorUris) {
// if mask is already selected, the no need to run this again
if (unManagedMasks.isEmpty()) {
break;
}
_logger.info("Looking for an UnManagedExportMask for initiators {} belonging to a cluster node.", Joiner.on(",").join(initiatorUriList));
Map<String, Set<String>> iniByProtocol = groupInitiatorsByProtocol(initiatorUriList, dbClient);
eligibleMasks.addAll(findMatchingExportMaskForHost(volume, unManagedMasks, initiatorUriList, iniByProtocol, dbClient, vArray, vPoolURI, true, clusterInitiators, cluster, errorMessages));
}
} else {
_logger.info("Either masks were already found or there are no unmanaged masks available.");
}
} catch (IngestionException ex) {
_logger.error(ex.getLocalizedMessage());
if (!maskErrorMessages.contains(ex.getLocalizedMessage())) {
maskErrorMessages.add(ex.getLocalizedMessage());
}
}
if (!maskErrorMessages.isEmpty()) {
String message = maskErrorMessages.size() + " of " + unManagedMasks.size() + " unmanaged export mask(s) failed zoning checks: ";
String messages = Joiner.on("; ").join(maskErrorMessages);
_logger.error(message + messages);
throw IngestionException.exceptions.inconsistentZoningAcrossHosts(message + messages);
}
_logger.info("returning cluster eligible masks: " + getMaskNames(URIUtil.toUris(eligibleMasks), dbClient));
return eligibleMasks;
}
Aggregations