Added ability to force mastership re-balancing between instances from the GUI.
Change-Id: I98e56deb3e2b00df630ed85b596c8e35b3d6efab
diff --git a/cli/src/main/java/org/onlab/onos/cli/BalanceMastersCommand.java b/cli/src/main/java/org/onlab/onos/cli/BalanceMastersCommand.java
index 77d0c16..9b31715 100644
--- a/cli/src/main/java/org/onlab/onos/cli/BalanceMastersCommand.java
+++ b/cli/src/main/java/org/onlab/onos/cli/BalanceMastersCommand.java
@@ -15,23 +15,8 @@
*/
package org.onlab.onos.cli;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
import org.apache.karaf.shell.commands.Command;
-import org.onlab.onos.cluster.ClusterService;
-import org.onlab.onos.cluster.ControllerNode;
import org.onlab.onos.mastership.MastershipAdminService;
-import org.onlab.onos.mastership.MastershipService;
-import org.onlab.onos.net.DeviceId;
-import org.onlab.onos.net.device.DeviceService;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static org.onlab.onos.net.MastershipRole.MASTER;
/**
* Forces device mastership rebalancing.
@@ -42,72 +27,7 @@
@Override
protected void execute() {
- ClusterService service = get(ClusterService.class);
- MastershipService mastershipService = get(MastershipService.class);
- MastershipAdminService adminService = get(MastershipAdminService.class);
-
- List<ControllerNode> nodes = newArrayList(service.getNodes());
-
- Multimap<ControllerNode, DeviceId> controllerDevices = HashMultimap.create();
-
- // Create buckets reflecting current ownership.
- for (ControllerNode node : nodes) {
- Set<DeviceId> devicesOf = mastershipService.getDevicesOf(node.id());
- controllerDevices.putAll(node, devicesOf);
- print("Node %s has %d devices.", node.id(), devicesOf.size());
- }
-
- int rounds = nodes.size();
- for (int i = 0; i < rounds; i++) {
- // Iterate over the buckets and find the smallest and the largest.
- ControllerNode smallest = findBucket(true, nodes, controllerDevices);
- ControllerNode largest = findBucket(false, nodes, controllerDevices);
- balanceBuckets(smallest, largest, controllerDevices, adminService);
- }
- }
-
- private ControllerNode findBucket(boolean min, Collection<ControllerNode> nodes,
- Multimap<ControllerNode, DeviceId> controllerDevices) {
- int xSize = min ? Integer.MAX_VALUE : -1;
- ControllerNode xNode = null;
- for (ControllerNode node : nodes) {
- int size = controllerDevices.get(node).size();
- if ((min && size < xSize) || (!min && size > xSize)) {
- xSize = size;
- xNode = node;
- }
- }
- return xNode;
- }
-
- // FIXME: enhance to better handle cases where smallest cannot take any of the devices from largest
-
- private void balanceBuckets(ControllerNode smallest, ControllerNode largest,
- Multimap<ControllerNode, DeviceId> controllerDevices,
- MastershipAdminService adminService) {
- Collection<DeviceId> minBucket = controllerDevices.get(smallest);
- Collection<DeviceId> maxBucket = controllerDevices.get(largest);
- int bucketCount = controllerDevices.keySet().size();
- int deviceCount = get(DeviceService.class).getDeviceCount();
-
- int delta = (maxBucket.size() - minBucket.size()) / 2;
- delta = Math.min(deviceCount / bucketCount, delta);
-
- if (delta > 0) {
- print("Attempting to move %d nodes from %s to %s...",
- delta, largest.id(), smallest.id());
-
- int i = 0;
- Iterator<DeviceId> it = maxBucket.iterator();
- while (it.hasNext() && i < delta) {
- DeviceId deviceId = it.next();
- print("Setting %s as the master for %s", smallest.id(), deviceId);
- adminService.setRole(smallest.id(), deviceId, MASTER);
- controllerDevices.put(smallest, deviceId);
- it.remove();
- i++;
- }
- }
+ get(MastershipAdminService.class).balanceRoles();
}
}