use of org.onosproject.cluster.ControllerNode in project onos by opennetworkinglab.
the class AtomixClusterStore method addNode.
@Override
public ControllerNode addNode(NodeId nodeId, IpAddress ip, int tcpPort) {
checkNotNull(nodeId, INSTANCE_ID_NULL);
ControllerNode node = new DefaultControllerNode(nodeId, ip, tcpPort);
nodes.put(node.id(), node);
ControllerNode.State state = node.equals(localNode) ? ControllerNode.State.ACTIVE : ControllerNode.State.INACTIVE;
Member member = membershipService.getMember(node.id().id());
member.properties().setProperty(STATE_KEY, state.name());
notifyDelegate(clusterEvent(ClusterEvent.Type.INSTANCE_ADDED, member, node));
return node;
}
use of org.onosproject.cluster.ControllerNode in project onos by opennetworkinglab.
the class AtomixClusterStore method changeMembership.
private void changeMembership(ClusterMembershipEvent event) {
ControllerNode node = nodes.get(NodeId.nodeId(event.subject().id().id()));
log.debug("Received a membership event {}", event);
switch(event.type()) {
case MEMBER_ADDED:
case METADATA_CHANGED:
if (node == null) {
node = toControllerNode(event.subject());
nodes.put(node.id(), node);
notifyDelegate(clusterEvent(ClusterEvent.Type.INSTANCE_ADDED, event.subject(), node));
}
updateVersion(node, event.subject());
updateState(node, event.subject());
break;
case MEMBER_REMOVED:
if (node != null && states.put(node.id(), ControllerNode.State.INACTIVE) != ControllerNode.State.INACTIVE) {
notifyDelegate(clusterEvent(ClusterEvent.Type.INSTANCE_DEACTIVATED, event.subject(), node));
notifyDelegate(clusterEvent(ClusterEvent.Type.INSTANCE_REMOVED, event.subject(), node));
}
break;
default:
break;
}
}
use of org.onosproject.cluster.ControllerNode in project onos by opennetworkinglab.
the class PrimitivePerfApp method startTestRun.
private void startTestRun() {
if (running) {
return;
}
sampleCollector.clearSamples();
startTime = System.currentTimeMillis();
currentStartTime = startTime;
currentCounter = new AtomicLong();
overallCounter = new AtomicLong();
reporterTask = new ReporterTask();
reportTimer.scheduleAtFixedRate(reporterTask, REPORT_PERIOD - currentTimeMillis() % REPORT_PERIOD, REPORT_PERIOD);
running = true;
Map<String, ControllerNode> nodes = new TreeMap<>();
for (ControllerNode node : clusterService.getNodes()) {
nodes.put(node.id().id(), node);
}
// Compute the index of the local node in a sorted list of nodes.
List<String> sortedNodes = Lists.newArrayList(nodes.keySet());
int nodeCount = nodes.size();
int index = sortedNodes.indexOf(nodeId.id());
// Count the number of workers assigned to this node.
int workerCount = 0;
for (int i = 1; i <= numClients; i++) {
if (i % nodeCount == index) {
workerCount++;
}
}
// Create a worker pool and start the workers for this node.
if (workerCount > 0) {
String[] keys = createStrings(keyLength, numKeys);
String[] values = createStrings(valueLength, numValues);
workers = Executors.newFixedThreadPool(workerCount, groupedThreads("onos/primitive-perf", "worker-%d"));
for (int i = 0; i < workerCount; i++) {
if (deterministic) {
workers.submit(new DeterministicRunner(keys, values));
} else {
workers.submit(new NonDeterministicRunner(keys, values));
}
}
}
log.info("Started test run");
}
use of org.onosproject.cluster.ControllerNode 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.cluster.ControllerNode in project onos by opennetworkinglab.
the class DeviceManager method updateMastershipFor.
/**
* Update the mastership for this device. If there is a node able
* to reach the device and this node is the master move the
* mastership to the next node still connected to this device.
* If the current node is a backup, it demotes itself to the bottom
* of the candidates list
*
* @param deviceId the device for which we have to update the mastership
* @return the NodeId of any node that can reach the device, or null if
* none of the ONOS instances can reach the device
*/
private NodeId updateMastershipFor(DeviceId deviceId) {
Map<NodeId, CompletableFuture<Boolean>> probes = Maps.newHashMap();
// Request a probe only if the node is ready
for (ControllerNode onosNode : clusterService.getNodes()) {
if (!clusterService.getState(onosNode.id()).isReady() || localNodeId.equals(onosNode.id())) {
continue;
}
probes.put(onosNode.id(), communicationService.sendAndReceive(deviceId, PROBE_SUBJECT, SERIALIZER::encode, SERIALIZER::decode, onosNode.id()));
}
// Returns the first node able to reach the device
// FIXME [SDFAB-935] optimize by looking at the MastershipInfo
boolean isReachable;
NodeId nextMaster = null;
// FIXME Should we expose timeout? Understand if there is need to signal to the caller
for (Map.Entry<NodeId, CompletableFuture<Boolean>> probe : probes.entrySet()) {
isReachable = Tools.futureGetOrElse(probe.getValue(), PROBE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS, Boolean.FALSE);
if (isReachable) {
nextMaster = probe.getKey();
}
}
// FIXME [SDFAB-935] optimize demote by looking at the MastershipInfo;
if (nextMaster != null) {
log.info("Device {} is still connected to {}", deviceId, nextMaster);
MastershipRole myRole = mastershipService.getLocalRole(deviceId);
if (myRole == MASTER) {
log.info("Handing over the mastership of {} to next master {}", deviceId, nextMaster);
mastershipAdminService.setRole(nextMaster, deviceId, MASTER);
// Do not demote here because setRole can return before the mastership has been passed.
// Current implementation promotes first the nextMaster as top of candidate list and then
// transfer the leadership. We can use the BACKUP events to do demote or leverage periodic
// checks.
} else if (myRole == STANDBY) {
log.info("Demote current instance to the bottom of the candidates list for {}", deviceId);
mastershipAdminService.demote(localNodeId, deviceId);
} else {
log.debug("No valid role for {}", deviceId);
}
}
return nextMaster;
}
Aggregations