[ONOS-5184] Allow configuring cluster partition size
Adds a new parameter to onos-form-cluster: -s <partition-size>
to allow specifying the partition size to be used when creating
the cluster.
Change-Id: I4c31d6e97fe0fd811831296f41a09160bebb58de
diff --git a/core/api/src/main/java/org/onosproject/cluster/ClusterAdminService.java b/core/api/src/main/java/org/onosproject/cluster/ClusterAdminService.java
index 6b7d614..179adfc 100644
--- a/core/api/src/main/java/org/onosproject/cluster/ClusterAdminService.java
+++ b/core/api/src/main/java/org/onosproject/cluster/ClusterAdminService.java
@@ -34,6 +34,16 @@
void formCluster(Set<ControllerNode> nodes);
/**
+ * Forms cluster configuration based on the specified set of node
+ * information. This method resets and restarts the controller
+ * instance.
+ *
+ * @param nodes set of nodes that form the cluster
+ * @param partitionSize number of nodes to compose a partition
+ */
+ void formCluster(Set<ControllerNode> nodes, int partitionSize);
+
+ /**
* Adds a new controller node to the cluster.
*
* @param nodeId controller node identifier
diff --git a/core/net/src/main/java/org/onosproject/cluster/impl/ClusterManager.java b/core/net/src/main/java/org/onosproject/cluster/impl/ClusterManager.java
index 0041547..a2b9000 100644
--- a/core/net/src/main/java/org/onosproject/cluster/impl/ClusterManager.java
+++ b/core/net/src/main/java/org/onosproject/cluster/impl/ClusterManager.java
@@ -71,6 +71,7 @@
implements ClusterService, ClusterAdminService {
public static final String INSTANCE_ID_NULL = "Instance ID cannot be null";
+ private static final int DEFAULT_PARTITION_SIZE = 3;
private final Logger log = getLogger(getClass());
private ClusterStoreDelegate delegate = new InternalStoreDelegate();
@@ -146,10 +147,15 @@
@Override
public void formCluster(Set<ControllerNode> nodes) {
+ formCluster(nodes, DEFAULT_PARTITION_SIZE);
+ }
+
+ @Override
+ public void formCluster(Set<ControllerNode> nodes, int partitionSize) {
checkNotNull(nodes, "Nodes cannot be null");
checkArgument(!nodes.isEmpty(), "Nodes cannot be empty");
- ClusterMetadata metadata = new ClusterMetadata("default", nodes, buildDefaultPartitions(nodes));
+ ClusterMetadata metadata = new ClusterMetadata("default", nodes, buildDefaultPartitions(nodes, partitionSize));
clusterMetadataAdminService.setClusterMetadata(metadata);
try {
log.warn("Shutting down container for cluster reconfiguration!");
@@ -183,13 +189,13 @@
}
}
- private static Set<Partition> buildDefaultPartitions(Collection<ControllerNode> nodes) {
+ private static Set<Partition> buildDefaultPartitions(Collection<ControllerNode> nodes, int partitionSize) {
List<ControllerNode> sorted = new ArrayList<>(nodes);
Collections.sort(sorted, (o1, o2) -> o1.id().toString().compareTo(o2.id().toString()));
Set<Partition> partitions = Sets.newHashSet();
// add partitions
int length = nodes.size();
- int count = Math.min(3, length);
+ int count = Math.min(partitionSize, length);
for (int i = 0; i < length; i++) {
int index = i;
Set<NodeId> set = new HashSet<>(count);
diff --git a/tools/package/bin/onos-form-cluster b/tools/package/bin/onos-form-cluster
index 578a443..9286d0c 100755
--- a/tools/package/bin/onos-form-cluster
+++ b/tools/package/bin/onos-form-cluster
@@ -6,10 +6,11 @@
[ $# -lt 2 ] && echo "usage: $(basename $0) ip1 ip2..." && exit 1
# Scan arguments for user/password or other options...
-while getopts u:p: o; do
+while getopts u:p:s: o; do
case "$o" in
u) user=$OPTARG;;
p) password=$OPTARG;;
+ s) partitionsize=$OPTARG;;
esac
done
ONOS_WEB_USER=${ONOS_WEB_USER:-onos} # ONOS WEB User defaults to 'onos'
@@ -32,7 +33,11 @@
for node in $nodes; do
echo ", { \"ip\": \"$node\" }" >> $aux
done
-echo "], \"ipPrefix\": \"$ipPrefix.*\" }" >> $aux
+echo "], \"ipPrefix\": \"$ipPrefix.*\"" >> $aux
+if ! [ -z ${partitionsize} ]; then
+ echo ", \"partitionSize\": $partitionsize" >> $aux
+fi
+echo " }" >> $aux
for node in $ip $nodes; do
echo "Forming cluster on $node..."
diff --git a/tools/test/bin/onos-form-cluster b/tools/test/bin/onos-form-cluster
index d0672db..a9f6a5b 100755
--- a/tools/test/bin/onos-form-cluster
+++ b/tools/test/bin/onos-form-cluster
@@ -7,10 +7,11 @@
. $ONOS_ROOT/tools/build/envDefaults
# Scan arguments for user/password or other options...
-while getopts u:p: o; do
+while getopts u:p:s: o; do
case "$o" in
u) user=$OPTARG;;
p) password=$OPTARG;;
+ s) partitionsize=$OPTARG;;
esac
done
ONOS_WEB_USER=${ONOS_WEB_USER:-onos} # ONOS WEB User defaults to 'onos'
@@ -29,6 +30,12 @@
nodes="$@"
fi
+if ! [ -z ${partitionsize} ]; then
+ partitionarg="-s ${partitionsize}"
+else
+ partitionarg=
+fi
+
set -x
-ssh $ONOS_USER@$node $ONOS_INSTALL_DIR/bin/onos-form-cluster -u $user -p $password $nodes
+ssh $ONOS_USER@$node $ONOS_INSTALL_DIR/bin/onos-form-cluster -u $user -p $partitionarg $password $nodes
diff --git a/web/api/src/main/java/org/onosproject/rest/resources/ClusterWebResource.java b/web/api/src/main/java/org/onosproject/rest/resources/ClusterWebResource.java
index 250fd02..63a4081 100644
--- a/web/api/src/main/java/org/onosproject/rest/resources/ClusterWebResource.java
+++ b/web/api/src/main/java/org/onosproject/rest/resources/ClusterWebResource.java
@@ -15,6 +15,7 @@
*/
package org.onosproject.rest.resources;
+import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.cluster.ClusterAdminService;
@@ -94,7 +95,16 @@
ObjectNode root = (ObjectNode) mapper().readTree(config);
List<ControllerNode> nodes = codec.decode((ArrayNode) root.path("nodes"), this);
- get(ClusterAdminService.class).formCluster(new HashSet<>(nodes));
+ JsonNode partitionSizeNode = root.get("partitionSize");
+ if (partitionSizeNode != null) {
+ int partitionSize = partitionSizeNode.asInt();
+ if (partitionSize == 0) {
+ return Response.notAcceptable(null).build();
+ }
+ get(ClusterAdminService.class).formCluster(new HashSet<>(nodes), partitionSize);
+ } else {
+ get(ClusterAdminService.class).formCluster(new HashSet<>(nodes));
+ }
return Response.ok().build();
}