Resolved merge conflict and back to Titan 0.2.0
diff --git a/web/ons-demo/RELEASE_NOTES.txt b/web/ons-demo/RELEASE_NOTES.txt
index 916a965..08e6ba0 100644
--- a/web/ons-demo/RELEASE_NOTES.txt
+++ b/web/ons-demo/RELEASE_NOTES.txt
@@ -1,11 +1,24 @@
 ** April 4, 2013 **
+- denser iperf display
+- don't pop alert on command error response. just log it
+
+** April 4, 2013 **
+iperf display implemented
+- scaled to 50,000,000
+- update rate is every 2s
+- the display does not draw until receiving 2 buffers of data (this way if there is a stale buffer it doesn't get displayed)
+- duration is 10000 seconds. seems like there is no need for a button to restart?
+- displaying 10s data
+- if the data underruns (either because the server response is too slow or because the iperf data stops being updated) the display draws 0s
+- seeing the data stall a lot (timestamp and end-time remain the same through many fetches)
+
+** April 4, 2013 **
 Fix issues:
 	305 - "close x" now unselects flow. double click to delete a flow
 	323 - gui now recovers on timeout errors and polls again
 	324 - fixed problem with added flows not displaying
 	325 - fixed logic displaying flows in topology view
 
-
 ** March 28, 2013 **
 - add and delete flow implemented
 - to add flow
diff --git a/web/ons-demo/css/layout.default.css b/web/ons-demo/css/layout.default.css
index 018e728..5e1f1ce 100644
--- a/web/ons-demo/css/layout.default.css
+++ b/web/ons-demo/css/layout.default.css
@@ -76,6 +76,15 @@
 .iperf {
 	width: 100%;
 	-webkit-box-flex: 1.0;
+	position: relative;
+	display: -webkit-box;
+}
+
+.iperf-container {
+	position: absolute;
+	top: 0px;
+	height: 100%;
+	width: 100%;
 }
 
 #controllers {
diff --git a/web/ons-demo/css/skin.default.css b/web/ons-demo/css/skin.default.css
index 1ce4897..1d656b0 100644
--- a/web/ons-demo/css/skin.default.css
+++ b/web/ons-demo/css/skin.default.css
@@ -145,6 +145,12 @@
 	border-top: 1px solid #AAA;
 }
 
+path.iperfdata {
+	fill: none;
+	stroke-width: 2px;
+	stroke: rgba(255, 255, 255, .75);
+}
+
 #flowChooser {
 	pointer-events: none;
 	background-color: rgba(0, 0, 0, .25);
diff --git a/web/ons-demo/js/app.js b/web/ons-demo/js/app.js
index 695e4bb..bc3cc6d 100644
--- a/web/ons-demo/js/app.js
+++ b/web/ons-demo/js/app.js
@@ -96,10 +96,10 @@
 				return;
 			}
 			var pts = [];
-			if (!d.dataPath.flowEntries || !d.dataPath.flowEntries.length) {
+			if (!d.dataPath.flowEntries) {
 				// create a temporary vector to indicate the pending flow
-				var s1 = d3.select(document.getElementById(d.dataPath.srcPort.dpid.value));
-				var s2 = d3.select(document.getElementById(d.dataPath.dstPort.dpid.value));
+				var s1 = d3.select(document.getElementById(d.srcDpid));
+				var s2 = d3.select(document.getElementById(d.dstDpid));
 
 				var pt1 = document.querySelector('svg').createSVGPoint();
 				pt1.x = s1.attr('x');
@@ -128,7 +128,11 @@
 					}
 				});
 			}
-			return line(pts);
+			if (pts.length) {
+				return line(pts);
+			} else {
+				return "M0,0";
+			}
 		})
 		.attr('id', function (d) {
 			if (d) {
@@ -153,6 +157,16 @@
 		row.append('div').classed('dstDPID', true);
 		row.append('div').classed('iperf', true);
 
+		row.select('.iperf')
+			.append('div')
+			.attr('class', 'iperf-container')
+			.append('svg:svg')
+			.attr('viewBox', '0 0 1000 32')
+			.attr('preserveAspectRatio', 'none')
+			.append('svg:g')
+			.append('svg:path')
+			.attr('class', 'iperfdata');
+
 		row.on('mouseover', function (d) {
 			if (d) {
 				var path = document.getElementById(makeFlowKey(d));
@@ -164,18 +178,28 @@
 				var path = document.getElementById(makeFlowKey(d));
 				d3.select(path).classed('highlight', false);
 			}
-		})
+		});
 	}
 
 	function rowUpdate(d) {
 		var row = d3.select(this);
+		row.attr('id', function (d) {
+			if (d) {
+				return makeSelectedFlowKey(d);
+			}
+		});
+
+		if (!d || !hasIPerf(d)) {
+			row.select('.iperfdata')
+				.attr('d', 'M0,0');
+		}
+
 		row.select('.deleteFlow').on('click', function () {
-			selectedFlows[selectedFlows.indexOf(d)] = null;
-			updateSelectedFlows();
+			deselectFlow(d);
 		});
 		row.on('dblclick', function () {
 			if (d) {
-				var prompt = 'Delete flow ' + d.flowId.value + '?';
+				var prompt = 'Delete flow ' + d.flowId + '?';
 				if (confirm(prompt)) {
 					deleteFlow(d);
 					d.deletePending = true;
@@ -193,7 +217,7 @@
 			.text(function (d) {
 				if (d) {
 					if (d.flowId) {
-						return d.flowId.value;
+						return d.flowId;
 					} else {
 						return '0x--';
 					}
@@ -206,14 +230,14 @@
 		row.select('.srcDPID')
 			.text(function (d) {
 				if (d) {
-					return d.dataPath.srcPort.dpid.value;
+					return d.srcDpid;
 				}
 			});
 
 		row.select('.dstDPID')
 			.text(function (d) {
 				if (d) {
-					return d.dataPath.dstPort.dpid.value;
+					return d.dstDpid;
 				}
 			});
 	}
@@ -232,6 +256,74 @@
 	flows.exit().remove();
 }
 
+// TODO: cancel the interval when the flow is desel
+function startIPerfForFlow(flow) {
+	var duration = 10000; // seconds
+	var interval = 100; // ms. this is defined by the server
+	var updateRate = 2000; // ms
+	var pointsToDisplay = 1000;
+
+	function makePoints() {
+		var pts = [];
+		var i;
+		for (i=0; i < pointsToDisplay; ++i) {
+			var sample = flow.iperfData.samples[i];
+			var height = 32 * sample/50000000;
+			if (height > 32)
+				height = 32;
+			pts.push({
+				x: i * 1000/(pointsToDisplay-1),
+				y: 32 - height
+			})
+		}
+		return pts;
+	}
+
+	if (flow.flowId) {
+		console.log('starting iperf for: ' + flow.flowId);
+		startIPerf(flow, duration, updateRate/interval);
+		flow.iperfDisplayInterval = setInterval(function () {
+			if (flow.iperfData) {
+				while (flow.iperfData.samples.length < pointsToDisplay) {
+					flow.iperfData.samples.push(0);
+				}
+				var iperfPath = d3.select(document.getElementById(makeSelectedFlowKey(flow))).select('path');
+				iperfPath.attr('d', line(makePoints()));
+				flow.iperfData.samples.shift();
+			}
+
+
+		}, interval);
+		flow.iperfFetchInterval = setInterval(function () {
+			getIPerfData(flow, function (data) {
+				try {
+					if (!flow.iperfData) {
+						flow.iperfData = {
+							samples: []
+						};
+						var i;
+						for (i = 0; i < pointsToDisplay; ++i) {
+							flow.iperfData.samples.push(0);
+						}
+					}
+
+					var iperfData = JSON.parse(data);
+					// if the data is fresh
+					if (flow.iperfData.timestamp && iperfData.timestamp != flow.iperfData.timestamp) {
+						iperfData.samples.forEach(function (s) {
+							flow.iperfData.samples.push(s);
+						});
+					}
+					flow.iperfData.timestamp = iperfData.timestamp;
+				} catch (e) {
+					console.log('bad iperf data: ' + data);
+				}
+//				console.log(data);
+			});
+		}, updateRate/2); // over sample to avoid gaps
+	}
+}
+
 function updateSelectedFlows() {
 	// make sure that all of the selected flows are either
 	// 1) valid (meaning they are in the latest list of flows)
@@ -249,13 +341,22 @@
 				if (liveFlow) {
 					newSelectedFlows.push(liveFlow);
 					liveFlow.deletePending = flow.deletePending;
+					liveFlow.iperfFetchInterval = flow.iperfFetchInterval;
+					liveFlow.iperfDisplayInterval = flow.iperfDisplayInterval;
 				} else if (flow.createPending) {
 					newSelectedFlows.push(flow);
+				} else if (hasIPerf(flow)) {
+					clearIPerf(flow);
 				}
 			}
 		});
 		selectedFlows = newSelectedFlows;
 	}
+	selectedFlows.forEach(function (flow) {
+		if (!hasIPerf(flow)) {
+			startIPerfForFlow(flow);
+		}
+	});
 	while (selectedFlows.length < 3) {
 		selectedFlows.push(null);
 	}
@@ -280,6 +381,19 @@
 	}
 }
 
+function hasIPerf(flow) {
+	return flow && flow.iperfFetchInterval;
+}
+
+function clearIPerf(flow) {
+	console.log('clearing iperf interval for: ' + flow.flowId);
+	clearInterval(flow.iperfFetchInterval);
+	delete flow.iperfFetchInterval;
+	clearInterval(flow.iperfDisplayInterval);
+	delete flow.iperfDisplayInterval;
+	delete flow.iperfData;
+}
+
 function deselectFlow(flow, ifCreatePending) {
 	var flowKey = makeFlowKey(flow);
 	var newSelectedFlows = [];
@@ -288,6 +402,10 @@
 				flowKey !== makeFlowKey(flow) ||
 				flowKey === makeFlowKey(flow) && ifCreatePending && !flow.createPending ) {
 			newSelectedFlows.push(flow);
+		} else {
+			if (hasIPerf(flow)) {
+				clearIPerf(flow);
+			}
 		}
 	});
 	selectedFlows = newSelectedFlows;
@@ -315,20 +433,20 @@
 		row.append('div')
 			.classed('flowId', true)
 			.text(function (d) {
-				return d.flowId.value;
+				return d.flowId;
 			});
 
 		row.append('div')
 			.classed('srcDPID', true)
 			.text(function (d) {
-				return d.dataPath.srcPort.dpid.value;
+				return d.srcDpid;
 			});
 
 
 		row.append('div')
 			.classed('dstDPID', true)
 			.text(function (d) {
-				return d.dataPath.dstPort.dpid.value;
+				return d.dstDpid;
 			});
 
 	}
@@ -471,7 +589,11 @@
 }
 
 function makeFlowKey(flow) {
-	return flow.dataPath.srcPort.dpid.value + '=>' + flow.dataPath.dstPort.dpid.value;
+	return flow.srcDpid + '=>' + flow.dstDpid;
+}
+
+function makeSelectedFlowKey(flow) {
+	return 'S' + makeFlowKey(flow);
 }
 
 function createLinkMap(links) {
@@ -813,6 +935,8 @@
 								}
 							}
 						},
+					        srcDpid: srcData.dpid,
+					        dstDpid: dstData.dpid,
 						createPending: true
 					};
 
@@ -1066,6 +1190,7 @@
 
 }
 
+var modelString;
 function sync(svg) {
 	var d = Date.now();
 	updateModel(function (newModel) {
@@ -1073,9 +1198,11 @@
 
 		if (newModel) {
 			var modelChanged = false;
-			if (!model || JSON.stringify(model) != JSON.stringify(newModel)) {
+			var newModelString = JSON.stringify(newModel);
+			if (!modelString || newModelString != modelString) {
 				modelChanged = true;
 				model = newModel;
+				modelString = newModelString;
 			} else {
 	//			console.log('no change');
 			}
diff --git a/web/ons-demo/js/controller.js b/web/ons-demo/js/controller.js
index fd3f6ae..fbc381e 100644
--- a/web/ons-demo/js/controller.js
+++ b/web/ons-demo/js/controller.js
@@ -1,11 +1,14 @@
 /*global d3*/
 
-function callURL(url) {
+function callURL(url, cb) {
 	d3.text(url, function (error, result) {
 		if (error) {
-			alert(url + ' : ' + error.status);
+			console.log(url + ' : ' + error.status);
 		} else {
-			console.log(result);
+			if (cb) {
+				cb(result);
+			}
+//			console.log(result);
 		}
 	});
 }
@@ -35,8 +38,18 @@
 		callURL(url);
 	},
 	delFlowCmd: function (flow) {
-		var url = '/proxy/gui/delflow/' + flow.flowId.value;
+		var url = '/proxy/gui/delflow/' + flow.flowId;
 		callURL(url);
+	},
+	startIPerfCmd: function (flow, duration, numSamples) {
+		var flowId = parseInt(flow.flowId, 16);
+		var url = '/proxy/gui/iperf/start/' + [flowId, duration, numSamples].join('/');
+		callURL(url)
+	},
+	getIPerfDataCmd: function (flow, cb) {
+		var flowId = parseInt(flow.flowId, 16);
+		var url = '/proxy/gui/iperf/rate/' + flowId;
+		callURL(url, cb);
 	}
 };
 
@@ -70,4 +83,12 @@
 
 function deleteFlow(flow) {
 	controllerFunctions.delFlowCmd(flow);
-}
\ No newline at end of file
+}
+
+function startIPerf(flow, duration, numSamples) {
+	controllerFunctions.startIPerfCmd(flow, duration, numSamples);
+}
+
+function getIPerfData(flow, cb) {
+	controllerFunctions.getIPerfDataCmd(flow, cb);
+}
diff --git a/web/topology_rest.py b/web/topology_rest.py
index 3238656..392cb87 100755
--- a/web/topology_rest.py
+++ b/web/topology_rest.py
@@ -7,40 +7,51 @@
 import argparse
 import io
 import time
+import random
 
 import re
 
 from flask import Flask, json, Response, render_template, make_response, request
 
-## Global Var ##
+## Global Var for ON.Lab local REST ##
 RestIP="localhost"
 RestPort=8080
-#DBName="onos-network-map"
 
 ## Uncomment the desired block based on your testbed environment
-
 # Settings for running on production
+<<<<<<< HEAD
 core_switches=["00:00:00:00:ba:5e:ba:11", "00:00:00:00:00:00:ba:12", "00:00:20:4e:7f:51:8a:35", "00:00:00:00:ba:5e:ba:13", "00:00:00:08:a2:08:f9:01", "00:00:00:16:97:08:9a:46"]
 ONOS_GUI3_HOST="http://localhost:9000"
 ONOS_GUI3_CONTROL_HOST="http://localhost:9000"
+=======
+#controllers=["onosgui1", "onosgui2", "onosgui3", "onosgui4", "onosgui5", "onosgui6", "onosgui7", "onosgui8"]
+#core_switches=["00:00:00:00:ba:5e:ba:11", "00:00:00:00:00:00:ba:12", "00:00:20:4e:7f:51:8a:35", "00:00:00:00:ba:5e:ba:13", "00:00:00:08:a2:08:f9:01", "00:00:00:16:97:08:9a:46"]
+#ONOS_GUI3_HOST="http://gui3.onlab.us:8080"
+#ONOS_GUI3_CONTROL_HOST="http://gui3.onlab.us:8081"
+>>>>>>> ecee79b1df12c337cba14cbc9e3660741ae72441
 
 # Settings for running on dev testbed. Replace dev
 #controllers=["onosdevb1", "onosdevb2", "onosdevb3", "onosdevb4"]
-#core_switches=["00:00:00:00:00:00:01:01", "00:00:00:00:00:00:01:02", "00:00:00:00:00:00:01:03", "00:00:00:00:00:00:01:04", "00:00:00:00:00:00:01:05", "00:00:00:00:00:00:01:06"]
-#ONOS_GUI3_HOST="http://devb-gui.onlab.us:8080"
-#ONOS_GUI3_CONTROL_HOST="http://devb-gui.onlab.us:8080"
+controllers=["onosdevt1", "onosdevt2", "onosdevt3", "onosdevt4", "onosdevt5", "onosdevt6", "onosdevt7", "onosdevt8"]
+core_switches=["00:00:00:00:00:00:01:01", "00:00:00:00:00:00:01:02", "00:00:00:00:00:00:01:03", "00:00:00:00:00:00:01:04", "00:00:00:00:00:00:01:05", "00:00:00:00:00:00:01:06"]
 
+<<<<<<< HEAD
 ONOS_LOCAL_HOST="http://localhost:8080" ;# for Amazon EC2
 controllers=["Berde-MBP.local"]
 #controllers=["onosgui1", "onosgui2", "onosgui3", "onosgui4", "onosgui5", "onosgui6", "onosgui7", "onosgui8"]
 #core_switches=["00:00:00:00:ba:5e:ba:11", "00:00:00:00:00:00:ba:12", "00:00:20:4e:7f:51:8a:35", "00:00:00:00:ba:5e:ba:13", "00:00:00:08:a2:08:f9:01", "00:00:00:16:97:08:9a:46"]
 core_switches=["00:00:00:00:00:00:01:01", "00:00:00:00:00:00:01:02", "00:00:00:00:00:00:01:03", "00:00:00:00:00:00:01:04", "00:00:00:00:00:00:01:05", "00:00:00:00:00:00:01:06"]
+=======
+ONOS_GUI3_HOST="http://devt-gui.onlab.us:8080"
+ONOS_GUI3_CONTROL_HOST="http://devt-gui.onlab.us:8080"
+>>>>>>> ecee79b1df12c337cba14cbc9e3660741ae72441
 
-nr_flow=0
+LB=True #; True or False
+ONOS_DEFAULT_HOST="localhost" ;# Has to set if LB=False
 
 DEBUG=1
-pp = pprint.PrettyPrinter(indent=4)
 
+pp = pprint.PrettyPrinter(indent=4)
 app = Flask(__name__)
 
 ## Worker Functions ##
@@ -51,7 +62,6 @@
   if DEBUG:
     print '%s' % (txt)
 
-## Rest APIs ##
 ### File Fetch ###
 @app.route('/ui/img/<filename>', methods=['GET'])
 @app.route('/img/<filename>', methods=['GET'])
@@ -75,6 +85,13 @@
   else:
     fullpath = str(request.path)[1:]
 
+  try: 
+    open(fullpath)
+  except:
+    response = make_response("Cannot find a file: %s" % (fullpath), 500)
+    response.headers["Content-type"] = "text/html"
+    return response
+
   response = make_response(open(fullpath).read())
   suffix = fullpath.split(".")[-1]
 
@@ -91,7 +108,7 @@
 
   return response
 
-
+## Proxy ##
 @app.route("/proxy/gui/link/<cmd>/<src_dpid>/<src_port>/<dst_dpid>/<dst_port>")
 def proxy_link_change(cmd, src_dpid, src_port, dst_dpid, dst_port):
   try:
@@ -105,6 +122,19 @@
   resp = Response(result, status=200, mimetype='application/json')
   return resp
 
+@app.route("/proxy/gui/switchctrl/<cmd>")
+def proxy_switch_controller_setting(cmd):
+  try:
+    command = "curl -s %s/gui/switchctrl/%s" % (ONOS_GUI3_CONTROL_HOST, cmd)
+    print command
+    result = os.popen(command).read()
+  except:
+    print "REST IF has issue"
+    exit
+
+  resp = Response(result, status=200, mimetype='application/json')
+  return resp
+
 @app.route("/proxy/gui/switch/<cmd>/<dpid>")
 def proxy_switch_status_change(cmd, dpid):
   try:
@@ -156,33 +186,11 @@
 
   resp = Response(result, status=200, mimetype='application/json')
   return resp
-@app.route("/wm/core/topology/switches/all/json")
-def switches():
-  if request.args.get('proxy') == None:
-    host = ONOS_LOCAL_HOST
-  else:
-    host = ONOS_GUI3_HOST
 
+@app.route("/proxy/gui/iperf/start/<flow_id>/<duration>/<samples>")
+def proxy_iperf_start(flow_id,duration,samples):
   try:
-    command = "curl -s %s/wm/core/topology/switches/all/json" % (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
-
-@app.route("/wm/core/topology/links/json")
-def links():
-  if request.args.get('proxy') == None:
-    host = ONOS_LOCAL_HOST
-  else:
-    host = ONOS_GUI3_HOST
-
-  try:
-    command = "curl -s %s/wm/core/topology/links/json" % (host)
+    command = "curl -s %s/gui/iperf/start/%s/%s/%s" % (ONOS_GUI3_CONTROL_HOST, flow_id, duration, samples)
     print command
     result = os.popen(command).read()
   except:
@@ -192,62 +200,117 @@
   resp = Response(result, status=200, mimetype='application/json')
   return resp
 
-@app.route("/wm/flow/getsummary/<start>/<range>/json")
-def flows(start, range):
-  if request.args.get('proxy') == None:
-    host = ONOS_LOCAL_HOST
-  else:
-    host = ONOS_GUI3_HOST
-
+@app.route("/proxy/gui/iperf/rate/<flow_id>")
+def proxy_iperf_rate(flow_id):
   try:
-    command = "curl -s %s/wm/flow/getsummary/%s/%s/json" % (host, start, range)
-#    print command
+    command = "curl -s %s/gui/iperf/rate/%s" % (ONOS_GUI3_CONTROL_HOST, flow_id)
+    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 RESET API ##############################
+## Worker Func ###
+def get_json(url):
+  code = 200
+  try:
+    command = "curl -s %s" % (url)
+    result = os.popen(command).read()
+    parsedResult = json.loads(result)    
+    if type(parsedResult) == 'dict' and parsedResult.has_key('code'):
+      print "REST %s returned code %s" % (command, parsedResult['code'])
+      code=500
+  except:
+    print "REST IF %s has issue" % command
+    result = ""
+    code = 500
+
+  return (code, result)
+
+def pick_host():
+  if LB == True:
+    nr_host=len(controllers)
+    r=random.randint(0, nr_host - 1)
+    host=controllers[r]
+  else:
+    host=ONOS_DEFAULT_HOST
+    
+  return "http://" + host + ":8080"
+
+## Switch ##
+@app.route("/wm/core/topology/switches/all/json")
+def switches():
+  if request.args.get('proxy') == None:
+    host = pick_host()
+  else:
+    host = ONOS_GUI3_HOST
+
+  url ="%s/wm/core/topology/switches/all/json" % (host)
+  (code, result) = get_json(url)
+
+  resp = Response(result, status=code, mimetype='application/json')
+  return resp
+
+## Link ##
+@app.route("/wm/core/topology/links/json")
+def links():
+  if request.args.get('proxy') == None:
+    host = pick_host()
+  else:
+    host = ONOS_GUI3_HOST
+
+  url ="%s/wm/core/topology/links/json" % (host)
+  (code, result) = get_json(url)
+
+  resp = Response(result, status=code, mimetype='application/json')
+  return resp
+
+## FlowSummary ##
+@app.route("/wm/flow/getsummary/<start>/<range>/json")
+def flows(start, range):
+  if request.args.get('proxy') == None:
+    host = pick_host()
+  else:
+    host = ONOS_GUI3_HOST
+
+  url ="%s/wm/flow/getsummary/%s/%s/json" % (host, start, range)
+  (code, result) = get_json(url)
+
+  resp = Response(result, status=code, mimetype='application/json')
+  return resp
+
 @app.route("/wm/registry/controllers/json")
 def registry_controllers():
   if request.args.get('proxy') == None:
-    host = ONOS_LOCAL_HOST
+    host = pick_host()
   else:
     host = ONOS_GUI3_HOST
 
-  try:
-    command = "curl -s %s/wm/registry/controllers/json" % (host)
-#    print command
-    result = os.popen(command).read()
-  except:
-    print "REST IF has issue"
-    exit
+  url= "%s/wm/registry/controllers/json" % (host)
+  (code, result) = get_json(url)
 
-  resp = Response(result, status=200, mimetype='application/json')
+  resp = Response(result, status=code, mimetype='application/json')
   return resp
 
+
 @app.route("/wm/registry/switches/json")
 def registry_switches():
   if request.args.get('proxy') == None:
-    host = ONOS_LOCAL_HOST
+    host = pick_host()
   else:
     host = ONOS_GUI3_HOST
 
-  try:
-    command = "curl -s %s/wm/registry/switches/json" % (host)
-#    print command
-    result = os.popen(command).read()
-  except:
-    print "REST IF has issue"
-    exit
+  url="%s/wm/registry/switches/json" % (host)
+  (code, result) = get_json(url)
 
-  resp = Response(result, status=200, mimetype='application/json')
+  resp = Response(result, status=code, mimetype='application/json')
   return resp
 
-
 def node_id(switch_array, dpid):
   id = -1
   for i, val in enumerate(switch_array):
@@ -287,39 +350,6 @@
         sw['group']=0
       switches.append(sw)
 
-## Comment in if we need devies
-#      sw_index = len(switches) - 1
-#      for p in v['ports']:
-#        for d in p['devices']:
-#          device = {}
-#          device['attached_switch']=dpid
-#          device['name']=d['mac']
-#          if d['state'] == "ACTIVE":
-#            device['group']=1000
-#          else:
-#            device['group']=1001
-#
-#          switches.append(device)
-#          device_index = len (switches) -1
-#          link = {}
-#          link['source'] = device_index
-#          link['target'] = sw_index
-#          link['type'] = -1
-#          links.append(link)
-#          link = {}
-#          link['source'] = sw_index
-#          link['target'] = device_index
-#          link['type'] = -1
-#          links.append(link)
-
-#  try:
-#    command = "curl -s \'http://%s:%s/wm/registry/controllers/json\'" % (RestIP, RestPort)
-#    result = os.popen(command).read()
-#    controllers = json.loads(result)
-#  except:
-#    log_error("xx REST IF has issue: %s" % command)
-#    log_error("%s" % result)
-
   try:
     command = "curl -s \'http://%s:%s/wm/registry/switches/json\'" % (RestIP, RestPort)
     result = os.popen(command).read()
@@ -391,7 +421,6 @@
   topo['nodes'] = switches
   topo['links'] = links
 
-  pp.pprint(topo)
   js = json.dumps(topo)
   resp = Response(js, status=200, mimetype='application/json')
   return resp
@@ -478,7 +507,6 @@
   topo['nodes'] = switches
   topo['links'] = links
 
-#  pp.pprint(topo)
   js = json.dumps(topo)
   resp = Response(js, status=200, mimetype='application/json')
   return resp
@@ -550,7 +578,6 @@
     device['attachmentPoint']=attachpoints
     devices.append(device)
 
-  print devices
   js = json.dumps(devices)
   resp = Response(js, status=200, mimetype='application/json')
   return resp
@@ -624,82 +651,6 @@
   resp = Response(js, status=200, mimetype='application/json')
   return resp
 
-topo_less = {
-  "nodes" : [
-    {"name" : "00:a0", "group" : 1},
-    {"name" : "00:a1", "group" : 1},
-    {"name" : "00:a2", "group" : 1},
-    ],
-  "links" : [
-    {"source" :0, "target": 1},
-    {"source" :1, "target": 0},
-    {"source" :0, "target": 2},
-    {"source" :2, "target": 0},
-    {"source" :1, "target": 2},
-    {"source" :2, "target": 1},
-    ]
-}
-
-topo_more = {
-  "nodes" : [
-    {"name" : "00:a3", "group" : 2},
-    {"name" : "00:a0", "group" : 1},
-    {"name" : "00:a1", "group" : 1},
-    {"name" : "00:a2", "group" : 1},
-    ],
-  "links" : [
-    {"source" :1, "target": 2},
-    {"source" :2, "target": 1},
-    {"source" :1, "target": 3},
-    {"source" :3, "target": 1},
-    {"source" :2, "target": 3},
-    {"source" :3, "target": 2},
-    {"source" :0, "target": 2},
-    ]
-}
-
-@app.route("/topology_more")
-def topology_more():
-  topo = topo_more
-  js = json.dumps(topo)
-  resp = Response(js, status=200, mimetype='application/json')
-  return resp
-
-@app.route("/topology_less")
-def topology_less():
-  topo = topo_less
-  js = json.dumps(topo)
-  resp = Response(js, status=200, mimetype='application/json')
-  return resp
-
-cont_status1 = [
-           {"name":"onos9vpc",  "onos": 1, "cassandra": 1},
-            {"name":"onos10vpc",  "onos": 0, "cassandra": 1},
-            {"name":"onos11vpc",  "onos": 1, "cassandra": 0},
-            {"name":"onos12vpc",  "onos": 1, "cassandra": 0}]
-
-cont_status2 = [
-            {"name":"onos9vpc",  "onos": 0, "cassandra": 1},
-            {"name":"onos10vpc",  "onos": 0, "cassandra": 1},
-            {"name":"onos11vpc",  "onos": 0, "cassandra": 1},
-            {"name":"onos12vpc",  "onos": 0, "cassandra": 1}]
-
-@app.route("/controller_status1")
-def controller_status1():
-  status = cont_status1
-  js = json.dumps(status)
-  resp = Response(js, status=200, mimetype='application/json')
-  pp.pprint(resp)
-  return resp
-
-@app.route("/controller_status2")
-def controller_status2():
-  status = cont_status2
-  js = json.dumps(status)
-  resp = Response(js, status=200, mimetype='application/json')
-  pp.pprint(resp)
-  return resp
-
 @app.route("/controller_status")
 def controller_status():
   onos_check="sh ~/src/ONOS/start-onos.sh status | awk '{print $1}'"
@@ -716,25 +667,42 @@
 
   js = json.dumps(cont_status)
   resp = Response(js, status=200, mimetype='application/json')
-  pp.pprint(js)
   return resp
 
+### Command ###
 @app.route("/gui/controller/<cmd>/<controller_name>")
 def controller_status_change(cmd, controller_name):
   start_onos="~/src/ONOS/start-onos.sh start" % (controller_name)
   stop_onos="~/src/ONOS/start-onos.sh stop" % (controller_name)
 
   if cmd == "up":
-    print start_onos
     result=os.popen(start_onos).read()
     ret = "controller %s is up" % (controller_name)
   elif cmd == "down":
-    print stop_onos
     result=os.popen(stop_onos).read()
     ret = "controller %s is down" % (controller_name)
 
   return ret
 
+@app.route("/gui/switchctrl/<cmd>")
+def switch_controller_setting(cmd):
+  if cmd =="local":
+    print "All aggr switches connects to local controller only"
+    result=""
+    for i in range(0, len(controllers)): 
+      cmd_string="ssh -i ~/.ssh/onlabkey.pem %s 'cd ONOS/scripts; ./ctrl-local.sh'" % (controllers[i])
+      result += os.popen(cmd_string).read()
+  elif cmd =="all":
+    print "All aggr switches connects to all controllers except for core controller"
+    result=""
+    for i in range(0, len(controllers)): 
+      cmd_string="ssh -i ~/.ssh/onlabkey.pem %s 'cd ONOS/scripts; ./ctrl-add-ext.sh'" % (controllers[i])
+      result += os.popen(cmd_string).read()
+
+  return result
+
+
+
 @app.route("/gui/switch/<cmd>/<dpid>")
 def switch_status_change(cmd, dpid):
   r = re.compile(':')
@@ -845,6 +813,7 @@
 
   parsedResult = json.loads(result)
 
+#  flowId = int(parsedResult['flowId']['value'], 16)
   flowId = int(parsedResult['flowId']['value'], 16)
   src_dpid = parsedResult['dataPath']['srcPort']['dpid']['value']
   src_port = parsedResult['dataPath']['srcPort']['port']['value']
@@ -874,8 +843,8 @@
     print command
     result = os.popen(command).read()
     if len(result) == 0:
-      print "No Flow found"
-      return;
+      resp = Response(result, status=400, mimetype='text/html')
+      return "no such iperf flow (flowid %s)" % flow_id;
   except:
     print "REST IF has issue"
     exit
@@ -899,14 +868,18 @@
     print command
     result = os.popen(command).read()
   except:
-    print "REST IF has issue"
     exit
 
-  resp = Response(result, status=200, mimetype='application/json')
-  return resp
+  if len(result) == 0:
+    resp = Response(result, status=400, mimetype='text/html')
+    return "no iperf file found (flowid %s)" % flow_id;
+  else:
+    resp = Response(result, status=200, mimetype='application/json')
+    return resp
 
 
 if __name__ == "__main__":
+  random.seed()
   if len(sys.argv) > 1 and sys.argv[1] == "-d":
 #      add_flow("00:00:00:00:00:00:02:02", 1, "00:00:00:00:00:00:03:02", 1, "00:00:00:00:02:02", "00:00:00:00:03:0c")
 #     link_change("up", "00:00:00:00:ba:5e:ba:11", 1, "00:00:00:00:00:00:00:00", 1)
@@ -922,8 +895,9 @@
 #    query_links()
 #    print "-- query all devices --"
 #    devices()
-    iperf_start(1,10,15)
-    iperf_rate(1)
+#    iperf_start(1,10,15)
+#    iperf_rate(1)
+    switches()
   else:
     app.debug = True
     app.run(threaded=True, host="0.0.0.0", port=9000)