Merge pull request #378 from pgreyson/master

Fix label display bug
diff --git a/cluster-mgmt/bin/demo-reset-hw.sh b/cluster-mgmt/bin/demo-reset-hw.sh
index c5101a1..8c586f5 100755
--- a/cluster-mgmt/bin/demo-reset-hw.sh
+++ b/cluster-mgmt/bin/demo-reset-hw.sh
@@ -1,11 +1,27 @@
 #! /bin/bash
 DIR=${HOME}/ONOS
+echo "==== Reset Demo to the initial State ==="
+date
+start=`date +"%s"`
+echo "all link up.."
 $DIR/scripts/all-linkup-hw.sh
+echo "link up done"
+
+echo "cleanup excess flows"
 $DIR/web/delete_flow.py 201 300
-$DIR/web/clean_flow.py 201 300
+$DIR/web/clear_flow.py 201 300
+echo "cleanup excess flows done"
+echo "Adding 200 flows"
 $DIR/web/add_flow.py -m onos -f $DIR/web/flowdef_demo_start.txt
+echo "done"
+echo "killing iperf"
+dsh -g onos 'sudo pkill -KILL iperf'
+echo "done"
+echo "kill onos at 5 and 7"
 onos stop 5
 onos stop 7
+echo "done"
+echo "bringup 1 2 3 4 6 8 if dead"
 for i in 1 2 3 4 6 8; do
   status=`onos status $i | grep instance | awk '{print $2}'`
   echo "onos $i status $status"
@@ -13,5 +29,10 @@
     onos start $i
   fi
 done
+echo "done"
+
 sleep 2
 switch local
+endt=`date +"%s"`
+(( delta = endt -start ))
+echo "finish: took $delta sec"
diff --git a/cluster-mgmt/bin/demo-scale-out-hw.sh b/cluster-mgmt/bin/demo-scale-out-hw.sh
index eb06c56..6a44c8d 100755
--- a/cluster-mgmt/bin/demo-scale-out-hw.sh
+++ b/cluster-mgmt/bin/demo-scale-out-hw.sh
@@ -1,7 +1,6 @@
 #! /bin/bash
 onos start 5
 onos start 7
-sleep 2
-cd ONOS/web; ./add_flow.py -m onos -f flowdef_demo_add.txt
-sleep 3
-switch all
+switch local
+sleep 4 
+cd ~/ONOS/web; ./add_flow.py -m onos -f flowdef_demo_add.txt &
diff --git a/scripts/demo-reset-sw.sh b/scripts/demo-reset-sw.sh
new file mode 100755
index 0000000..65a2ff1
--- /dev/null
+++ b/scripts/demo-reset-sw.sh
@@ -0,0 +1,23 @@
+#! /bin/bash
+basename=$ONOS_CLUSTER_BASENAME
+DIR=${HOME}/ONOS
+tstart=`date +"%s"`
+echo "All Link Up"
+$DIR/scripts/all-linkup.sh
+echo "Delete Flows"
+$DIR/web/delete_flow.py 201 300
+$DIR/web/clear_flow.py 201 300
+echo "Adding Flows"
+$DIR/web/add_flow.py -m onos -f $DIR/web/flowdef_demo_start.txt
+ssh -i ~/.ssh/onlabkey.pem  ${basename}5 'ONOS/start-onos.sh stop'
+ssh -i ~/.ssh/onlabkey.pem  ${basename}7 'ONOS/start-onos.sh stop'
+for i in 1 2 3 4 6 8; do
+    ssh -i ~/.ssh/onlabkey.pem  ${basename}$i 'ONOS/start-onos.sh startifdown'
+done
+sleep 2
+for i in 1 2 3 4 5 6 7 8; do
+    ssh -i ~/.ssh/onlabkey.pem  ${basename}$i 'cd ONOS/scripts; ./ctrl-local.sh'
+done
+tend=`date +"%s"`
+(( delta = tend - tstart ))
+echo "Demo Reset Done: took $delta sec"
diff --git a/scripts/demo-scale-out-sw.sh b/scripts/demo-scale-out-sw.sh
new file mode 100755
index 0000000..887a025
--- /dev/null
+++ b/scripts/demo-scale-out-sw.sh
@@ -0,0 +1,14 @@
+#! /bin/bash
+basename=$ONOS_CLUSTER_BASENAME
+DIR=${HOME}/ONOS
+start=`date +"%s"`
+echo "bring up two nodes"
+ssh -i ~/.ssh/onlabkey.pem  ${basename}5 'ONOS/start-onos.sh start'
+ssh -i ~/.ssh/onlabkey.pem  ${basename}7 'ONOS/start-onos.sh start'
+sleep 2
+echo "Adding more flows"
+$DIR/web/add_flow.py -m onos -f $DIR/web/flowdef_demo_add.txt
+endt=`date +"%s"`
+(( delta = endt -start ))
+echo "Scale Up Done: took $delta sec"
+
diff --git a/src/main/java/net/floodlightcontroller/core/internal/TopoSwitchServiceImpl.java b/src/main/java/net/floodlightcontroller/core/internal/TopoSwitchServiceImpl.java
index 931802e..502fad6 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/TopoSwitchServiceImpl.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/TopoSwitchServiceImpl.java
@@ -29,6 +29,7 @@
 	public Iterable<ISwitchObject> getActiveSwitches() {
 		// TODO Auto-generated method stub
 		conn = GraphDBConnection.getInstance("/tmp/cassandra.titan");
+		conn.close(); //Commit to ensure we see latest data
 		return conn.utils().getActiveSwitches(conn);
 	}
 
@@ -36,6 +37,7 @@
 	public Iterable<ISwitchObject> getAllSwitches() {
 		// TODO Auto-generated method stub
 		conn = GraphDBConnection.getInstance("/tmp/cassandra.titan");
+		conn.close(); //Commit to ensure we see latest data
 		return conn.utils().getAllSwitches(conn);
 	}
 
@@ -43,6 +45,7 @@
 	public Iterable<ISwitchObject> getInactiveSwitches() {
 		// TODO Auto-generated method stub
 		conn = GraphDBConnection.getInstance("/tmp/cassandra.titan");
+		conn.close(); //Commit to ensure we see latest data
 		return conn.utils().getInactiveSwitches(conn);
 	}
 
diff --git a/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java b/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
index c562556..1372c60 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
@@ -1111,6 +1111,8 @@
     	ArrayList<IFlowPath> flowPathsObjArray = new ArrayList<IFlowPath>();
     	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
 
+    	conn.endTx(Transaction.COMMIT);
+    	
     	try {
     	    if ((flowPathsObj = conn.utils().getAllFlowPaths(conn)) != null) {
     		log.debug("Get all FlowPaths: found FlowPaths");
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/TopoLinkServiceImpl.java b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/TopoLinkServiceImpl.java
index c493887..1bd6421 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/TopoLinkServiceImpl.java
+++ b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/TopoLinkServiceImpl.java
@@ -34,6 +34,7 @@
 	public List<Link> getActiveLinks() {
 		// TODO Auto-generated method stub
 		conn = GraphDBConnection.getInstance("");
+		conn.close(); //Commit to ensure we see latest data
 		Iterable<ISwitchObject> switches = conn.utils().getActiveSwitches(conn);
 		List<Link> links = new ArrayList<Link>(); 
 		for (ISwitchObject sw : switches) {
diff --git a/src/main/java/net/onrc/onos/util/GraphDBConnection.java b/src/main/java/net/onrc/onos/util/GraphDBConnection.java
index 4d23b0d..cc3cff2 100644
--- a/src/main/java/net/onrc/onos/util/GraphDBConnection.java
+++ b/src/main/java/net/onrc/onos/util/GraphDBConnection.java
@@ -42,7 +42,7 @@
 	   private GraphDBConnection(){ }
 	   
 	   /* Static 'instance' method */
-	   public static GraphDBConnection getInstance(final String conf) {
+	   public static synchronized GraphDBConnection getInstance(final String conf) {
 		   if (GraphDBConnection.configFile == null || GraphDBConnection.configFile.isEmpty()) {
 			   GraphDBConnection.configFile = conf;
 			   log.debug("GraphDBConnection::Setting Config File {}", GraphDBConnection.configFile);
diff --git a/start-onos.sh b/start-onos.sh
index 7e23eaf..77accd0 100755
--- a/start-onos.sh
+++ b/start-onos.sh
@@ -127,6 +127,14 @@
     check_db
     start 
     ;;
+  startifdown)
+    n=`jps -l |grep "net.floodlightcontroller.core.Main" | wc -l`
+    if [ $n == 0 ]; then
+      start
+    else 
+      echo "$n instance of onos running"
+    fi
+    ;;
   stop)
     stop
     ;;
@@ -134,10 +142,10 @@
     deldb
     ;;
   status)
-    n=`ps -edalf |grep java |grep logback.xml | wc -l`
+    n=`jps -l |grep "net.floodlightcontroller.core.Main" | wc -l`
     echo "$n instance of onos running"
     ;;
   *)
-    echo "Usage: $0 {start|stop|restart|status}"
+    echo "Usage: $0 {start|stop|restart|status|startifdown}"
     exit 1
 esac
diff --git a/web/ons-demo/css/skin.default.css b/web/ons-demo/css/skin.default.css
index 2b07e33..b860f1d 100644
--- a/web/ons-demo/css/skin.default.css
+++ b/web/ons-demo/css/skin.default.css
@@ -122,9 +122,13 @@
 #actions {
 	padding-right: .25em;
 	padding-left: .25em;
+	padding-top: .25em;
+	padding-bottom: .25em;
 	border-left: 1px solid white;
 	display: -webkit-box;
 	-webkit-box-align: center;
+	-webkit-box-orient: vertical;
+	-webkit-box-pack: center;
 }
 
 #controllers {
@@ -132,6 +136,9 @@
 	background-color: black;
 	margin: .25em;
 	border-radius: 8px;
+	overflow: hidden;
+	display: -webkit-box;
+	-webkit-box-align: center;
 }
 
 #flowChooser .selectedFlow {
@@ -167,12 +174,12 @@
 
 path.flow {
 	fill: none;
-	stroke-width: 8px;
+	stroke-width: 10px;
 	stroke: rgba(255, 255, 255, .35);
 }
 
 path.flow.highlight {
-	stroke-width: 6px;
+	stroke-width: 16px;
 	stroke: rgba(255, 255, 255, .75);
 }
 
@@ -181,7 +188,7 @@
 }
 
 path.iperfdata {
-	fill: #ccc;
+	fill: none;
 	stroke-width: 1px;
 	stroke: #ccc;
 }
@@ -233,17 +240,20 @@
 	padding: .25em;
 	padding-left: 2.5em;
 	position: relative;
+	height: 1.5em;
 	border: 1px solid #444;
 	color: white;
 	position: relative;
 	border-radius: 8px;
+	display: -webkit-box;
+	-webkit-box-align: center;
 }
 
 .controller:hover {
 	border: 1px solid white;
 }
 
-.action, .controller {
+.controller {
 	font-size: 18px;
 }
 
@@ -293,7 +303,7 @@
 text {
 	stroke: none;
 	fill: white;
-	font-size: 22px;
+	font-size: 28px;
 	pointer-events: none;
 }
 
@@ -341,8 +351,8 @@
 .color1 {
 	opacity: .15;
 	pointer-events: none;
-	fill: #EC0033;
-	background-color: #EC0033;
+	fill: #FF0000;
+	background-color: #FF0000;
 }
 
 .color2 {
@@ -362,8 +372,8 @@
 .color4 {
 	opacity: .2;
 	pointer-events: none;
-	fill: #B12C49;
-	background-color: #B12C49;
+	fill: #800080;
+	background-color: #800080;
 }
 
 .color5 {
@@ -376,63 +386,64 @@
 .color6 {
 	opacity: .2;
 	pointer-events: none;
-	fill: #990021;
-	background-color: #990021;
+	fill: #5555FF;
+	background-color: #2222FF;
 }
 
 .color7 {
 	opacity: .2;
 	pointer-events: none;
-	fill: #990021;
-	background-color: #990021;
+	fill: #5555FF;
+	background-color: #2222FF;
 }
 
 .color8 {
 	opacity: .2;
 	pointer-events: none;
-	fill: #A67900;
-	background-color: #A67900;
+	fill: #A0522D;
+	background-color: #A0522D;
 }
 
 .color9 {
 	opacity: .2;
 	pointer-events: none;
-	fill: #F53D65;
-	background-color: #F53D65;
+	fill: #66CDAA;
+	background-color: #66CDAA;
 }
 
 .color10 {
 	opacity: .2;
 	pointer-events: none;
-	fill: #1F0772;
-	background-color: #1F0772;
+	fill: #FFA500;
+	background-color: #FFA500;
 }
 
 .color11 {
 	opacity: .2;
 	pointer-events: none;
-	fill: #F56E8B;
-	background-color: #F56E8B;
+	fill: #FFA500;
+	background-color: #FFA500;
 }
 
 .color12 {
 	opacity: .2;
 	pointer-events: none;
-	fill: #6949D7;
-	background-color: #6949D7;
+	fill: #FF69B4;
+	background-color: #FF69B4;
 }
 
 .action {
-	margin: .25em;
+	margin: .1em;
 	border: 2px solid #AAA;
-	height: 2em;
-	width: 2em;
+	height: 1.5em;
+	width: 5em;
+	font-size: 9px;
 	background-color: #444;
 	display: -webkit-box;
 	-webkit-box-pack: center;
 	-webkit-box-align: center;
 	color: #AAA;
-	border-radius: 50%;
+	border-radius: 0%;
 	-webkit-box-sizing: border-box;
 }
 
@@ -469,8 +480,8 @@
 }
 
 .flowCount {
-	font-size: 24px;
-	fill: rgba(255, 255, 255, .75);
+	font-size: 32px;
+	fill: rgba(255, 255, 255, .99);
 }
 
 #confirm {
diff --git a/web/ons-demo/index.html b/web/ons-demo/index.html
index ed31bee..5c1a650 100644
--- a/web/ons-demo/index.html
+++ b/web/ons-demo/index.html
@@ -20,14 +20,14 @@
 	</div>
 
 	<div id='onos'>
-		<div id='cluster-label'>ONOS Node Cluster</div>
+		<div id='cluster-label'>ONOS Instances</div>
 		<div id='controllers'></div>
 		<div id='actions'>
-			<div id='action-local' class='action'>1</div>
-			<div id='action-reset' class='action'>R</div>
-			<div id='action-scale' class='action'>S</div>
-			<div id='action-all' class='action'>A</div>
-			<div id='action-kill' class='action'>K</div>
+			<!--<div id='action-local' class='action'>1</div>-->
+			<div id='action-reset' class='action'>Reset</div>
+			<div id='action-scale' class='action'>Scale</div>
+			<div id='action-all' class='action'>Backup</div>
+			<div id='action-kill' class='action'>Kill</div>
 		</div>
 	</div>
 
@@ -82,4 +82,4 @@
 <script src="js/app.js"></script>
 </body>
 
-</html>
\ No newline at end of file
+</html>
diff --git a/web/ons-demo/js/controller.js b/web/ons-demo/js/controller.js
index f9b4baf..fb516ae 100644
--- a/web/ons-demo/js/controller.js
+++ b/web/ons-demo/js/controller.js
@@ -108,6 +108,9 @@
 function switchLocal() {
 	controllerFunctions.switchControllerCmd('local');
 }
+function switchAll() {
+	controllerFunctions.switchControllerCmd('all');
+}
 
 function resetNetwork() {
 	controllerFunctions.resetCmd();
diff --git a/web/ons-demo/js/init.js b/web/ons-demo/js/init.js
index bf812aa..6328272 100644
--- a/web/ons-demo/js/init.js
+++ b/web/ons-demo/js/init.js
@@ -8,7 +8,7 @@
 	});
 
 	d3.select('#action-all').on('click', function () {
-		var prompt = "Switch controllers to all?"
+		var prompt = "Add backup controllers?"
 		doConfirm(prompt, function (result) {
 			if (result) {
 				switchAll();
diff --git a/web/ons-demo/js/iperf.js b/web/ons-demo/js/iperf.js
index d8a3215..ee0e305 100644
--- a/web/ons-demo/js/iperf.js
+++ b/web/ons-demo/js/iperf.js
@@ -49,9 +49,9 @@
 					continue;
 				}
 
-				var y = 28 * sample.value/1000000;
-				if (y > 28) {
-					y = 28;
+				var y = 24 * sample.value/1000000;
+				if (y > 24) {
+					y = 24;
 				}
 				if (i == iperfData.samples.length - 1) {
 					d = 'M' + x + ',30';
diff --git a/web/ons-demo/js/utils.js b/web/ons-demo/js/utils.js
index 1b4c38c..68e567f 100644
--- a/web/ons-demo/js/utils.js
+++ b/web/ons-demo/js/utils.js
@@ -79,7 +79,7 @@
 update the app header using the current model
 ***************************************************************************************************/
 function updateHeader() {
-	d3.select('#lastUpdate').text(new Date());
+	d3.select('#lastUpdate').text(new Date().toLocaleString());
 
 	var activeSwitchCount = 0;
 	model.edgeSwitches.forEach(function (s) {
diff --git a/web/topology_rest.py b/web/topology_rest.py
index 43865f1..f867ad8 100755
--- a/web/topology_rest.py
+++ b/web/topology_rest.py
@@ -229,8 +229,35 @@
   resp = Response(result, status=200, mimetype='application/json')
   return resp
 
+@app.route("/proxy/gui/reset")
+def proxy_gui_reset():
+  result = ""
+  try:
+    command = "curl -m 300 -s %s/gui/reset" % (ONOS_GUI3_CONTROL_HOST)
+    print command
+    result = os.popen(command).read()
+  except:
+    print "REST IF has issue"
+    exit
 
-###### ONOS RESET API ##############################
+  resp = Response(result, status=200, mimetype='application/json')
+  return resp
+
+@app.route("/proxy/gui/scale")
+def proxy_gui_scale():
+  result = ""
+  try:
+    command = "curl -m 300 -s %s/gui/scale" % (ONOS_GUI3_CONTROL_HOST)
+    print command
+    result = os.popen(command).read()
+  except:
+    print "REST IF has issue"
+    exit
+
+  resp = Response(result, status=200, mimetype='application/json')
+  return resp
+
+###### ONOS REST API ##############################
 ## Worker Func ###
 def get_json(url):
   code = 200
@@ -692,17 +719,20 @@
 def controller_status_change(cmd, controller_name):
   if (TESTBED == "hw"):
     start_onos="/home/admin/bin/onos start %s" % (controller_name[-1:])
+#    start_onos="/home/admin/bin/onos start %s > /tmp/debug " % (controller_name[-1:])
     stop_onos="/home/admin/bin/onos stop %s" % (controller_name[-1:])
+#    stop_onos="/home/admin/bin/onos stop %s > /tmp/debug " % (controller_name[-1:])
+#    print "Debug: Controller command %s called %s" % (cmd, controller_name)
   else:
     start_onos="ssh -i ~/.ssh/onlabkey.pem %s ONOS/start-onos.sh start" % (controller_name)
     stop_onos="ssh -i ~/.ssh/onlabkey.pem %s ONOS/start-onos.sh stop" % (controller_name)
 
   if cmd == "up":
     result=os.popen(start_onos).read()
-    ret = "controller %s is up" % (controller_name)
+    ret = "controller %s is up: %s" % (controller_name, result)
   elif cmd == "down":
     result=os.popen(stop_onos).read()
-    ret = "controller %s is down" % (controller_name)
+    ret = "controller %s is down: %s" % (controller_name, result)
 
   return ret
 
@@ -712,26 +742,43 @@
     print "All aggr switches connects to local controller only"
     result=""
     if (TESTBED == "sw"):
-      for i in range(0, len(controllers)):
+      for i in range(1, len(controllers)):
         cmd_string="ssh -i ~/.ssh/onlabkey.pem %s 'cd ONOS/scripts; ./ctrl-local.sh'" % (controllers[i])
         result += os.popen(cmd_string).read()
     else:
-      cmd_string="cd; switch local"
+      cmd_string="cd; switch local > /tmp/watch"
       result += os.popen(cmd_string).read()
   elif cmd =="all":
     print "All aggr switches connects to all controllers except for core controller"
     result=""
     if (TESTBED == "sw"):
-      for i in range(0, len(controllers)):
+      for i in range(1, len(controllers)):
         cmd_string="ssh -i ~/.ssh/onlabkey.pem %s 'cd ONOS/scripts; ./ctrl-add-ext.sh'" % (controllers[i])
+        print "cmd is: "+cmd_string
         result += os.popen(cmd_string).read()
     else:
-      cmd_string="cd; switch all"
+      cmd_string="/home/admin/bin/switch all > /tmp/watch"
       result += os.popen(cmd_string).read()
 
   return result
 
+@app.route("/gui/reset")
+def reset_demo():
+  if (TESTBED == "hw"):
+    cmd_string="cd ~/bin; ./demo-reset-hw.sh > /tmp/watch &"
+  else:
+    cmd_string="cd ~/ONOS/scripts; ./demo-reset-sw.sh > /tmp/watch &"
+  os.popen(cmd_string)
+  return "Reset" 
 
+@app.route("/gui/scale")
+def scale_demo():
+  if (TESTBED == "hw"):
+    cmd_string="cd ~/bin;  ~/bin/demo-scale-out-hw.sh > /tmp/watch &"
+  else:
+    cmd_string="cd ~/ONOS/scripts; ./demo-scale-out-sw.sh > /tmp/watch &"
+  os.popen(cmd_string)
+  return "scale"
 
 @app.route("/gui/switch/<cmd>/<dpid>")
 def switch_status_change(cmd, dpid):
@@ -1061,7 +1108,8 @@
 #    iperf_start(1,10,15)
 #    iperf_rate(1)
 #    switches()
-    add_flow(1,2,3,4,5,6)
+#    add_flow(1,2,3,4,5,6)
+    reset_demo()
   else:
     app.debug = True
     app.run(threaded=True, host="0.0.0.0", port=9000)