Merge branch 'master' of github.com:OPENNETWORKINGLAB/ONOS
diff --git a/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java b/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java
index 587b3c2..19addad 100644
--- a/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java
+++ b/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java
@@ -1,7 +1,10 @@
 package net.floodlightcontroller.core;
 
+import net.floodlightcontroller.flowcache.web.DatapathSummarySerializer;
+
 import org.codehaus.jackson.annotate.JsonIgnore;
 import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
 
 import com.tinkerpop.blueprints.Direction;
 import com.tinkerpop.frames.Adjacency;
@@ -155,48 +158,57 @@
 	}
 
 public interface IFlowPath extends IBaseObject {
+		@JsonProperty("flowId")
 		@Property("flow_id")
 		public String getFlowId();
 
 		@Property("flow_id")
 		public void setFlowId(String flowId);
 
+		@JsonProperty("installerId")
 		@Property("installer_id")
 		public String getInstallerId();
 
 		@Property("installer_id")
 		public void setInstallerId(String installerId);
 
+		@JsonProperty("srcDpid")
 		@Property("src_switch")
 		public String getSrcSwitch();
 
 		@Property("src_switch")
 		public void setSrcSwitch(String srcSwitch);
 
+		@JsonProperty("srcPort")
 		@Property("src_port")
 		public Short getSrcPort();
 
 		@Property("src_port")
 		public void setSrcPort(Short srcPort);
 
+		@JsonProperty("dstDpid")
 		@Property("dst_switch")
 		public String getDstSwitch();
 
 		@Property("dst_switch")
 		public void setDstSwitch(String dstSwitch);
 
+		@JsonProperty("dstPort")
 		@Property("dst_port")
 		public Short getDstPort();
 
 		@Property("dst_port")
 		public void setDstPort(Short dstPort);
 
+		@JsonProperty("dataPath")
+		@JsonSerialize(using=DatapathSummarySerializer.class)
 		@Property("data_path_summary")
 		public String getDataPathSummary();
 
 		@Property("data_path_summary")
 		public void setDataPathSummary(String dataPathSummary);
 
+		@JsonIgnore
 		@Adjacency(label="flow", direction=Direction.IN)
 		public Iterable<IFlowEntry> getFlowEntries();
 
@@ -206,30 +218,35 @@
 		@Adjacency(label="flow", direction=Direction.IN)
 		public void removeFlowEntry(final IFlowEntry flowEntry);
 
+		@JsonIgnore
 		@Property("matchEthernetFrameType")
 		public Short getMatchEthernetFrameType();
 
 		@Property("matchEthernetFrameType")
 		public void setMatchEthernetFrameType(Short matchEthernetFrameType);
 
+		@JsonIgnore
 		@Property("matchSrcMac")
 		public String getMatchSrcMac();
 
 		@Property("matchSrcMac")
 		public void setMatchSrcMac(String matchSrcMac);
 
+		@JsonIgnore
 		@Property("matchDstMac")
 		public String getMatchDstMac();
 
 		@Property("matchDstMac")
 		public void setMatchDstMac(String matchDstMac);
 
+		@JsonIgnore
 		@Property("matchSrcIPv4Net")
 		public String getMatchSrcIPv4Net();
 
 		@Property("matchSrcIPv4Net")
 		public void setMatchSrcIPv4Net(String matchSrcIPv4Net);
 
+		@JsonIgnore
 		@Property("matchDstIPv4Net")
 		public String getMatchDstIPv4Net();
 
@@ -239,6 +256,10 @@
 		@JsonIgnore
 		@GremlinGroovy("_().in('flow').out('switch')")
 		public Iterable<IDeviceObject> getSwitches();
+		
+		@JsonIgnore
+		@Property("state")
+		public String getState();
 	}
 
 public interface IFlowEntry extends IBaseObject {
diff --git a/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java b/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
index 516d99c..2b9bf68 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/FlowManager.java
@@ -3,7 +3,6 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -12,12 +11,9 @@
 import java.util.Map;
 import java.util.Random;
 import java.util.TreeMap;
-import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.Executors;
-import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 
 import net.floodlightcontroller.core.IFloodlightProviderService;
@@ -32,13 +28,12 @@
 import net.floodlightcontroller.core.module.FloodlightModuleException;
 import net.floodlightcontroller.core.module.IFloodlightModule;
 import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.flowcache.IFlowService;
 import net.floodlightcontroller.flowcache.web.FlowWebRoutable;
 import net.floodlightcontroller.restserver.IRestApiService;
 import net.floodlightcontroller.util.CallerId;
 import net.floodlightcontroller.util.DataPath;
-import net.floodlightcontroller.util.Dpid;
 import net.floodlightcontroller.util.DataPathEndpoints;
+import net.floodlightcontroller.util.Dpid;
 import net.floodlightcontroller.util.FlowEntry;
 import net.floodlightcontroller.util.FlowEntryAction;
 import net.floodlightcontroller.util.FlowEntryId;
@@ -62,7 +57,6 @@
 import org.openflow.protocol.OFType;
 import org.openflow.protocol.action.OFAction;
 import org.openflow.protocol.action.OFActionOutput;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -908,7 +902,10 @@
      * @return the Flow Paths if found, otherwise null.
      */
     @Override
-    public ArrayList<FlowPath> getAllFlowsSummary(FlowId flowId, int maxFlows) {
+    public ArrayList<IFlowPath> getAllFlowsSummary(FlowId flowId, int maxFlows) {
+    	
+    	
+    	
 		//
 		// TODO: The implementation below is not optimal:
 		// We fetch all flows, and then return only the subset that match
@@ -916,10 +913,15 @@
 		// We should use the appropriate Titan/Gremlin query to filter-out
 		// the flows as appropriate.
 		//
-    	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
+    	//ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
     	
+    	ArrayList<IFlowPath> flowPathsWithoutFlowEntries = getAllFlowsWithoutFlowEntries();
+    	
+    	return flowPathsWithoutFlowEntries;
+    	
+    	/*
     	ArrayList<FlowPath> allFlows = getAllFlows();
-	
+
 		if (allFlows == null) {
 		    log.debug("Get FlowPathsSummary for {} {}: no FlowPaths found", flowId, maxFlows);
 		    return flowPaths;
@@ -954,6 +956,7 @@
 		}
 	
 		return flowPaths;
+		*/
     }
     
     /**
@@ -995,6 +998,45 @@
 
 	return flowPaths;
     }
+    
+    public ArrayList<IFlowPath> getAllFlowsWithoutFlowEntries(){
+    	Iterable<IFlowPath> flowPathsObj = null;
+    	ArrayList<IFlowPath> flowPathsObjArray = new ArrayList<IFlowPath>();
+    	ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
+
+    	try {
+    	    if ((flowPathsObj = conn.utils().getAllFlowPaths(conn)) != null) {
+    		log.debug("Get all FlowPaths: found FlowPaths");
+    	    } else {
+    		log.debug("Get all FlowPaths: no FlowPaths found");
+    	    }
+    	} catch (Exception e) {
+    	    // TODO: handle exceptions
+    	    conn.endTx(Transaction.ROLLBACK);
+    	    log.error(":getAllFlowPaths failed");
+    	}
+    	if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
+    	    return new ArrayList<IFlowPath>();	// No Flows found
+    	}
+    	
+    	for (IFlowPath flowObj : flowPathsObj){
+    		flowPathsObjArray.add(flowObj);
+    	}
+    	/*
+    	for (IFlowPath flowObj : flowPathsObj) {
+    	    //
+    	    // Extract the Flow state
+    	    //
+    	    FlowPath flowPath = extractFlowPath(flowObj);
+    	    if (flowPath != null)
+    		flowPaths.add(flowPath);
+    	}
+    	*/
+
+    	//conn.endTx(Transaction.COMMIT);
+
+    	return flowPathsObjArray;
+    }
 
     /**
      * Extract Flow Path State from a Titan Database Object @ref IFlowPath.
diff --git a/src/main/java/net/floodlightcontroller/flowcache/IFlowService.java b/src/main/java/net/floodlightcontroller/flowcache/IFlowService.java
index 619d36b..855f064 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/IFlowService.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/IFlowService.java
@@ -2,6 +2,7 @@
 
 import java.util.ArrayList;
 
+import net.floodlightcontroller.core.INetMapTopologyObjects.IFlowPath;
 import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.util.CallerId;
 import net.floodlightcontroller.util.DataPathEndpoints;
@@ -77,7 +78,7 @@
      * @param maxFlows: number of flows to return
      * @return the Flow Paths if found, otherwise null.
      */
-    ArrayList<FlowPath> getAllFlowsSummary(FlowId flowId, int maxFlows);
+    ArrayList<IFlowPath> getAllFlowsSummary(FlowId flowId, int maxFlows);
     
     /**
      * Get all installed flows by all installers.
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/DatapathSummarySerializer.java b/src/main/java/net/floodlightcontroller/flowcache/web/DatapathSummarySerializer.java
new file mode 100644
index 0000000..b780e5c
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/flowcache/web/DatapathSummarySerializer.java
@@ -0,0 +1,82 @@
+package net.floodlightcontroller.flowcache.web;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.map.JsonSerializer;
+import org.codehaus.jackson.map.SerializerProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DatapathSummarySerializer extends JsonSerializer<String>{
+	static Logger log = LoggerFactory.getLogger(DatapathSummarySerializer.class);
+	
+	@Override
+	public void serialize(String datapathSummary, JsonGenerator jGen,
+			SerializerProvider serializer) throws IOException,
+			JsonProcessingException {
+		
+		String[] flowEntries = datapathSummary.split(";");
+		if (flowEntries.length < 2){
+			log.debug("datapathSummary string to short to parse: {}", 
+					datapathSummary);
+			jGen.writeStartObject();
+			jGen.writeEndObject();
+			return;
+		}
+		
+		String[] srcFlowEntry = flowEntries[0].split("/");
+		String[] dstFlowEntry = flowEntries[flowEntries.length - 1].split("/");
+		if (srcFlowEntry.length != 3 || dstFlowEntry.length != 3){
+			log.debug("Malformed datapathSummary string: {}", datapathSummary);
+			jGen.writeStartObject();
+			jGen.writeEndObject();
+			return;
+		}
+		
+		jGen.writeStartObject();
+		
+		/*
+		jGen.writeObjectFieldStart("srcPort");
+		jGen.writeObjectFieldStart("dpid");
+		jGen.writeStringField("value", srcFlowEntry[1]);
+		jGen.writeEndObject();
+		jGen.writeObjectFieldStart("port");
+		jGen.writeStringField("value", srcFlowEntry[0]);
+		jGen.writeEndObject();
+		jGen.writeEndObject();
+		
+		jGen.writeObjectFieldStart("dstPort");
+		jGen.writeObjectFieldStart("dpid");
+		jGen.writeStringField("value", srcFlowEntry[1]);
+		jGen.writeEndObject();
+		jGen.writeObjectFieldStart("port");
+		jGen.writeStringField("value", srcFlowEntry[2]);
+		jGen.writeEndObject();
+		jGen.writeEndObject();
+		*/
+		jGen.writeArrayFieldStart("flowEntries");
+		
+		for (String flowEntryString : flowEntries){
+			String[] flowEntry = flowEntryString.split("/");
+			if (flowEntry.length != 3){
+				log.debug("Malformed datapathSummary string: {}", datapathSummary);
+				jGen.writeStartObject();
+				jGen.writeEndObject();
+				continue;
+			}
+			
+			jGen.writeStartObject();
+			jGen.writeObjectFieldStart("dpid");
+			jGen.writeStringField("value", flowEntry[1]);
+			jGen.writeEndObject();
+			jGen.writeEndObject();
+		}
+		
+		jGen.writeEndArray();
+		
+		jGen.writeEndObject();
+	}
+
+}
diff --git a/src/main/java/net/floodlightcontroller/flowcache/web/GetSummaryFlowsResource.java b/src/main/java/net/floodlightcontroller/flowcache/web/GetSummaryFlowsResource.java
index 7a928c9..5f63222 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/web/GetSummaryFlowsResource.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/web/GetSummaryFlowsResource.java
@@ -2,9 +2,10 @@
 
 import java.util.ArrayList;
 
+import net.floodlightcontroller.core.INetMapTopologyObjects.IFlowPath;
 import net.floodlightcontroller.flowcache.IFlowService;
-import net.floodlightcontroller.util.FlowPath;
 import net.floodlightcontroller.util.FlowId;
+import net.floodlightcontroller.util.FlowPath;
 
 import org.restlet.resource.Get;
 import org.restlet.resource.ServerResource;
@@ -15,8 +16,8 @@
     protected static Logger log = LoggerFactory.getLogger(GetSummaryFlowsResource.class);
 
     @Get("json")
-    public ArrayList<FlowPath> retrieve() {
-    	ArrayList<FlowPath> result = null;
+    public ArrayList<IFlowPath> retrieve() {
+    	ArrayList<IFlowPath> result = null;
     	
     	FlowId flowId;
     	int maxFlows = 0;
diff --git a/web/ons-demo/js/app.js b/web/ons-demo/js/app.js
index d6fa983..62060fd 100644
--- a/web/ons-demo/js/app.js
+++ b/web/ons-demo/js/app.js
@@ -98,8 +98,8 @@
 			var pts = [];
 			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');
@@ -199,7 +199,7 @@
 		});
 		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;
@@ -217,7 +217,7 @@
 			.text(function (d) {
 				if (d) {
 					if (d.flowId) {
-						return d.flowId.value;
+						return d.flowId;
 					} else {
 						return '0x--';
 					}
@@ -230,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;
 				}
 			});
 	}
@@ -432,20 +432,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;
 			});
 
 	}
@@ -588,7 +588,7 @@
 }
 
 function makeFlowKey(flow) {
-	return flow.dataPath.srcPort.dpid.value + '=>' + flow.dataPath.dstPort.dpid.value;
+	return flow.srcDpid + '=>' + flow.dstDpid;
 }
 
 function makeSelectedFlowKey(flow) {
@@ -934,6 +934,8 @@
 								}
 							}
 						},
+					        srcDpid: srcData.dpid,
+					        dstDpid: dstData.dpid,
 						createPending: true
 					};
 
diff --git a/web/ons-demo/js/controller.js b/web/ons-demo/js/controller.js
index c7c80ec..ea2143a 100644
--- a/web/ons-demo/js/controller.js
+++ b/web/ons-demo/js/controller.js
@@ -38,7 +38,7 @@
 		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) {