Configure ZooKeeper connection to ONOS/RAMCloud

- ZooKeeper server list specified by zookeeper.hosts (onos_node.conf)
  will be used as ZooKeeper fallback connection list for
  ONOS, RAMCloud. (ONOS-1756)

Change-Id: Iaef6bee82a28f3181f3fc681707666033f8d746f
diff --git a/conf/onos_node.conf b/conf/onos_node.conf
index 19c6ae6..3607585 100644
--- a/conf/onos_node.conf
+++ b/conf/onos_node.conf
@@ -20,10 +20,18 @@
 host.backend = hazelcast
 #host.backend = ramcloud
 
+# ZooKeeper: port to listen for client connections/
+#            port that clients attemApt to connect to
+#            (2181 by default)
+#zookeeper.clientPort = 2181
+
 # List of host name/IPs that constitute ZooKeeper cluster (only current host by default)
 # myid will be assigned incrementally according to order of list
 #zookeeper.hosts = onosdev1,onosdev2,onosdev3,onosdev4
 
+# ZooKeeper: ports to be used as leader, leader election. (2888:3888 by default)
+#zookeeper.ports = 2888:3888
+
 # RAMCloud clusterName (same as onos.cluster.name by default)
 #ramcloud.clusterName = onos
 
diff --git a/conf/template/zoo.cfg.template b/conf/template/zoo.cfg.template
index 39dc329..69bd3c0 100644
--- a/conf/template/zoo.cfg.template
+++ b/conf/template/zoo.cfg.template
@@ -11,7 +11,7 @@
 # example sakes.
 dataDir=__DATADIR__
 # the port at which the clients will connect
-clientPort=2181
+clientPort=__CLIENTPORT__
 #
 # specify all servers in the Zookeeper ensemble
 #server.1=onosgui1:2888:3888
diff --git a/onos.sh b/onos.sh
index 147ed74..e674baf 100755
--- a/onos.sh
+++ b/onos.sh
@@ -45,6 +45,8 @@
 ONOS_HOST_ROLE=$(read-conf ${ONOS_CONF}     host.role)
 ONOS_HOST_BACKEND=$(read-conf ${ONOS_CONF}  host.backend)
 ZK_HOSTS=$(read-conf ${ONOS_CONF}           zookeeper.hosts               ${ONOS_HOST_NAME})
+ZK_CLIENTPORT=$(read-conf ${ONOS_CONF}      zookeeper.clientPort          2181)
+ZK_PORTS=$(read-conf ${ONOS_CONF}           zookeeper.ports               2888:3888)
 RC_COORD_PROTOCOL=$(read-conf ${ONOS_CONF}  ramcloud.coordinator.protocol "fast+udp")
 RC_COORD_IP=$(read-conf ${ONOS_CONF}        ramcloud.coordinator.ip       ${ONOS_HOST_IP})
 RC_COORD_PORT=$(read-conf ${ONOS_CONF}      ramcloud.coordinator.port     12246)
@@ -328,8 +330,8 @@
     if [[ $line =~ ^__HOSTS__$ ]]; then
       i=1
       for host in ${hostarr}; do
-        # TODO: ports might be configurable
-        local hostline="server.${i}=${host}:2888:3888"
+        # TODO: ZK ports should be configurable per host
+        local hostline="server.${i}=${host}:${ZK_PORTS}"
         echo $hostline
         i=`expr $i + 1`
       done
@@ -339,6 +341,7 @@
       echo $line
     fi
   done < ${ZK_CONF_TEMPLATE} > ${temp_zk}
+  sed -e "s|__CLIENTPORT__|${ZK_CLIENTPORT}|" -i "" ${temp_zk}
   
   end-conf-creation ${ZK_CONF}
   
@@ -391,11 +394,12 @@
 
   local temp_rc=`begin-conf-creation ${RAMCLOUD_CONF}`
 
+  local rc_locator=`echo "${ZK_HOSTS}" | sed -e "s/,/:${ZK_CLIENTPORT},/g"`
+  rc_locator+=":${ZK_CLIENTPORT}"
+
   local rc_cluster_name=$(read-conf ${ONOS_CONF} ramcloud.clusterName ${ONOS_CLUSTER_NAME})
 
-  # TODO make ZooKeeper address configurable.
-  echo "ramcloud.locator=zk:localhost:2181" > ${temp_rc}
-  echo "#ramcloud.locator=zk:localhost:2181,otherhost:2181" >> ${temp_rc}
+  echo "ramcloud.locator=zk:localhost:2181,${rc_locator}" > ${temp_rc}
   echo "ramcloud.clusterName=${rc_cluster_name}" >> ${temp_rc}
 
   end-conf-creation ${RAMCLOUD_CONF}
@@ -956,6 +960,13 @@
   # specify ZooKeeper(curator) namespace
   JVM_OPTS="${JVM_OPTS} -Dzookeeper.namespace=${ONOS_CLUSTER_NAME}"
 
+  # specify ZooKeeper connectionString
+  local zk_locator=`echo "${ZK_HOSTS}" | sed -e "s/,/:${ZK_CLIENTPORT},/g"`
+  zk_locator+=":${ZK_CLIENTPORT}"
+  zk_locator="localhost:${ZK_CLIENTPORT},${zk_locator}"
+
+  JVM_OPTS="${JVM_OPTS} -Dnet.onrc.onos.core.registry.ZookeeperRegistry.connectionString=${zk_locator}"
+
   # specify hazelcast.xml to datagrid
   JVM_OPTS="${JVM_OPTS} -Dnet.onrc.onos.core.datagrid.HazelcastDatagrid.datagridConfig=${HC_CONF}"
 
diff --git a/src/main/java/net/onrc/onos/core/registry/ZookeeperRegistry.java b/src/main/java/net/onrc/onos/core/registry/ZookeeperRegistry.java
index 103438e..ce68ec2 100644
--- a/src/main/java/net/onrc/onos/core/registry/ZookeeperRegistry.java
+++ b/src/main/java/net/onrc/onos/core/registry/ZookeeperRegistry.java
@@ -56,6 +56,8 @@
 public class ZookeeperRegistry implements IFloodlightModule,
                                           IControllerRegistryService {
 
+    private static final String DEFAULT_CONNECTION_STRING = "localhost:2181";
+
     private static final Logger log = LoggerFactory.getLogger(ZookeeperRegistry.class);
 
     private String controllerId;
@@ -64,7 +66,7 @@
 
     // This is the default. It is overwritten by the connectionString
     // configuration parameter
-    private String connectionString = "localhost:2181";
+    private String connectionString = DEFAULT_CONNECTION_STRING;
 
     /**
      * JVM Option to specify ZooKeeper namespace.
@@ -570,6 +572,10 @@
         String connectionStringParam = configParams.get("connectionString");
         if (connectionStringParam != null) {
             connectionString = connectionStringParam;
+        } else {
+            connectionString = System.getProperty(
+                    "net.onrc.onos.core.registry.ZookeeperRegistry.connectionString",
+                    DEFAULT_CONNECTION_STRING);
         }
         log.info("Setting Zookeeper connection string to {}", this.connectionString);