Thiago Santos
Committed by Gerrit Code Review

[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
......@@ -34,6 +34,16 @@ public interface ClusterAdminService extends ClusterService {
void formCluster(Set<ControllerNode> nodes);
/**
* Forms cluster configuration based on the specified set of node
* information.&nbsp; 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
......
......@@ -71,6 +71,7 @@ public class ClusterManager
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 @@ public class ClusterManager
@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 @@ public class ClusterManager
}
}
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);
......
......@@ -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 @@ echo "{ \"nodes\": [ { \"ip\": \"$ip\" }" > $aux
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..."
......
......@@ -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 @@ else
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
......
......@@ -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 @@ public class ClusterWebResource extends AbstractWebResource {
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();
}
......