use of org.onosproject.net.MastershipRole.MASTER in project onos by opennetworkinglab.
the class MastershipManager method balanceRolesInRegion.
/**
* Balances the nodes in specified region.
*
* @param region region in which nodes are to be balanced
* @param allControllerDevices controller nodes to devices map
* @return controller nodes that were balanced
*/
private Map<ControllerNode, Set<DeviceId>> balanceRolesInRegion(Region region, Map<ControllerNode, Set<DeviceId>> allControllerDevices) {
// Retrieve all devices associated with specified region
Set<DeviceId> devicesInRegion = regionService.getRegionDevices(region.id());
log.info("Region {} has {} devices.", region.id(), devicesInRegion.size());
if (devicesInRegion.isEmpty()) {
// no devices in this region, so nothing to balance.
return new HashMap<>();
}
List<Set<NodeId>> mastersList = region.masters();
log.info("Region {} has {} sets of masters.", region.id(), mastersList.size());
if (mastersList.isEmpty()) {
// for now just leave devices alone
return new HashMap<>();
}
// Get the region's preferred set of masters
Set<DeviceId> devicesInMasters = Sets.newHashSet();
Map<ControllerNode, Set<DeviceId>> regionalControllerDevices = getRegionsPreferredMasters(region, devicesInMasters, allControllerDevices);
// Now re-balance the buckets until they are roughly even.
List<CompletableFuture<Void>> balanceBucketsFutures = Lists.newArrayList();
balanceControllerNodes(regionalControllerDevices, devicesInMasters.size(), balanceBucketsFutures);
// Handle devices that are not currently mastered by the master node set
Set<DeviceId> devicesNotMasteredWithControllers = Sets.difference(devicesInRegion, devicesInMasters);
if (!devicesNotMasteredWithControllers.isEmpty()) {
// active controllers in master node set are already balanced, just
// assign device mastership in sequence
List<ControllerNode> sorted = new ArrayList<>(regionalControllerDevices.keySet());
Collections.sort(sorted, Comparator.comparingInt(o -> (regionalControllerDevices.get(o)).size()));
int deviceIndex = 0;
for (DeviceId deviceId : devicesNotMasteredWithControllers) {
ControllerNode cnode = sorted.get(deviceIndex % sorted.size());
balanceBucketsFutures.add(setRole(cnode.id(), deviceId, MASTER));
regionalControllerDevices.get(cnode).add(deviceId);
deviceIndex++;
}
}
CompletableFuture<Void> balanceRolesFuture = allOf(balanceBucketsFutures.toArray(new CompletableFuture[balanceBucketsFutures.size()]));
Futures.getUnchecked(balanceRolesFuture);
// Update the map before returning
regionalControllerDevices.forEach((controllerNode, deviceIds) -> {
regionalControllerDevices.put(controllerNode, new HashSet<>(getDevicesOf(controllerNode.id())));
});
return regionalControllerDevices;
}
use of org.onosproject.net.MastershipRole.MASTER in project onos by opennetworkinglab.
the class DeviceManager method mastershipCheck.
/**
* Checks if all the reachable devices have a valid mastership role.
*/
private void mastershipCheck() {
log.debug("Checking mastership");
for (Device device : getDevices()) {
final DeviceId deviceId = device.id();
MastershipRole myRole = mastershipService.getLocalRole(deviceId);
log.trace("Checking device {}. Current role is {}", deviceId, myRole);
log.debug("Device {} local status is {}", deviceId, localStatus(deviceId));
final boolean isGracePeriodOn = inGracePeriod(deviceId);
final boolean isReachable = isReachable(deviceId, isGracePeriodOn);
// Passed the grace period and it is still not reachable
if (!isGracePeriodOn && !isReachable) {
if (myRole != NONE) {
// Verify if the device is fully disconnected from the cluster
if (updateMastershipFor(deviceId) == null && myRole == MASTER && isAvailable(deviceId)) {
log.info("Local Role {}, Marking unreachable device {} offline", MASTER, deviceId);
// Following the deviceDisconnected method logic (line 734) we are marking also all the
// ports as disabled.
List<PortDescription> descs = store.getPortDescriptions(getProvider(deviceId).id(), deviceId).map(desc -> ensurePortEnabledState(desc, false)).collect(Collectors.toList());
store.updatePorts(getProvider(deviceId).id(), deviceId, descs);
post(store.markOffline(deviceId));
}
} else {
// never be hit unless in a device removed phase for NONE mastership roles.
try {
mastershipService.requestRoleFor(deviceId).get();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error("Interrupted waiting for Mastership", e);
} catch (ExecutionException e) {
log.error("Encountered an error waiting for Mastership", e);
}
MastershipTerm term = termService.getMastershipTerm(deviceId);
if (updateMastershipFor(deviceId) == null && term != null && localNodeId.equals(term.master()) && isAvailable(deviceId)) {
log.info("Marking unreachable device {} offline", deviceId);
// Following the deviceDisconnected method logic (line 734) we are marking also all the
// ports as disabled.
List<PortDescription> descs = store.getPortDescriptions(getProvider(deviceId).id(), deviceId).map(desc -> ensurePortEnabledState(desc, false)).collect(Collectors.toList());
store.updatePorts(getProvider(deviceId).id(), deviceId, descs);
post(store.markOffline(deviceId));
}
}
roleToAcknowledge.remove(deviceId);
} else if (isReachable) {
// If this node is the master, ensure the device is marked online.
if (myRole == MASTER && canMarkOnline(device)) {
log.debug("Can mark online {}", deviceId);
post(store.markOnline(deviceId));
}
log.debug("{} is reachable - reasserting the role", deviceId);
// Device is still reachable. It is useful for some protocols
// to reassert the role. Note: NONE triggers request to MastershipService
reassertRole(deviceId, myRole);
} else {
// Do not proceed furthermore if the grace period is still on
log.debug("Skipping mastership check for {}", deviceId);
}
}
}
Aggregations