Merge pull request #13 from effy/RAMCloud

batch flow entry set properties
diff --git a/src/main/java/net/onrc/onos/graph/DBOperation.java b/src/main/java/net/onrc/onos/graph/DBOperation.java
index 0b91dd2..b39771e 100644
--- a/src/main/java/net/onrc/onos/graph/DBOperation.java
+++ b/src/main/java/net/onrc/onos/graph/DBOperation.java
@@ -5,12 +5,19 @@
 package net.onrc.onos.graph;
 
 import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.blueprints.impls.ramcloud.*;
 import com.tinkerpop.frames.FramedGraph;
 import com.tinkerpop.frames.structures.FramedVertexIterable;
 import com.tinkerpop.gremlin.java.GremlinPipeline;
+
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IBaseObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
@@ -20,16 +27,15 @@
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
 import net.onrc.onos.ofcontroller.core.ISwitchStorage;
+import net.onrc.onos.ofcontroller.flowmanager.FlowDatabaseOperation;
 import net.onrc.onos.ofcontroller.util.FlowEntryId;
 import net.onrc.onos.ofcontroller.util.FlowId;
 
-/**
- *
- * @author nickkaranatsios
- */
 public abstract class DBOperation implements IDBOperation {
 
 	protected DBConnection conn;
+	private final static Logger log = LoggerFactory.getLogger(DBOperation.class);
+
 
 	/**
 	 * Search and get an active switch object with DPID.
@@ -414,4 +420,12 @@
 	public void close() {
 	    conn.close();
 	}
+
+	@Override
+	public void setFlowProperties(IFlowEntry flowEntry, Map<String, Object> map) {
+		log.debug("setProperties start: size {}", map.size());
+		RamCloudVertex v = (RamCloudVertex) flowEntry.asVertex();
+		v.setProperties(map);
+		log.debug("setProperties end: size {}, id {}", map.size(), v.getId());
+	}
 }
diff --git a/src/main/java/net/onrc/onos/graph/GraphDBOperation.java b/src/main/java/net/onrc/onos/graph/GraphDBOperation.java
deleted file mode 100644
index ab775b9..0000000
--- a/src/main/java/net/onrc/onos/graph/GraphDBOperation.java
+++ /dev/null
@@ -1,447 +0,0 @@
-package net.onrc.onos.graph;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IBaseObject;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IIpv4Address;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
-import net.onrc.onos.ofcontroller.util.FlowEntryId;
-import net.onrc.onos.ofcontroller.util.FlowId;
-
-import com.thinkaurelius.titan.core.TitanGraph;
-import com.tinkerpop.blueprints.Vertex;
-import com.tinkerpop.frames.FramedGraph;
-import com.tinkerpop.frames.structures.FramedVertexIterable;
-import com.tinkerpop.gremlin.java.GremlinPipeline;
-
-public class GraphDBOperation implements IDBOperation {
-	private GraphDBConnection conn;
-
-	/**
-	 * Create a GraphDBOperation instance from specified GraphDBConnection's instance.
-	 * @param dbConnection an instance of GraphDBConnection
-	 */
-	public GraphDBOperation(GraphDBConnection dbConnection) {
-		this.conn = dbConnection;
-	}
-
-	/**
-	 * Create a GraphDBOperation instance from database configuration path.
-	 * @param dbConfPath a path for database configuration file.
-	 */
-	public GraphDBOperation(final String dbConfPath) {
-		this.conn = GraphDBConnection.getInstance(dbConfPath);
-	}
-
-	/**
-	 * Create a new switch and return the created switch object.
-	 * @param dpid DPID of the switch
-	 */
-	@Override
-	public ISwitchObject newSwitch(String dpid) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		ISwitchObject obj = fg.addVertex(null,ISwitchObject.class);
-		if (obj != null) {
-			obj.setType("switch");
-			obj.setDPID(dpid);
-		}
-		return obj;
-	}
-
-	/**
-	 * Search and get a switch object with DPID.
-	 * @param dpid DPID of the switch
-	 */
-	@Override
-	public ISwitchObject searchSwitch(String dpid) {
-
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		if ( fg == null ) return null;
-		Iterator<ISwitchObject> it = fg.getVertices("dpid",dpid,ISwitchObject.class).iterator();
-		return (it.hasNext()) ? it.next() : null;
-
-	}
-
-	/**
-	 * Search and get an active switch object with DPID.
-	 * @param dpid DPID of the switch
-	 */
-	@Override
-	public ISwitchObject searchActiveSwitch(String dpid) {
-
-	    ISwitchObject sw = searchSwitch(dpid);
-	    if ((sw != null) &&
-	        sw.getState().equals(SwitchState.ACTIVE.toString())) {
-	        return sw;
-	    }
-	    return null;
-	}
-
-	/**
-	 * Get all switch objects.
-	 */
-	@Override
-	public Iterable<ISwitchObject> getAllSwitches() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		Iterable<ISwitchObject> switches =  fg.getVertices("type","switch",ISwitchObject.class);
-		return switches;
-	}
-
-	/**
-	 * Get all active switch objects.
-	 */
-	@Override
-	public Iterable<ISwitchObject> getActiveSwitches() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		Iterable<ISwitchObject> switches =  fg.getVertices("type","switch",ISwitchObject.class);
-		List<ISwitchObject> activeSwitches = new ArrayList<ISwitchObject>();
-
-		for (ISwitchObject sw: switches) {
-			if(sw.getState().equals(SwitchState.ACTIVE.toString())) {
-				activeSwitches.add(sw);
-			}
-		}
-		return activeSwitches;
-	}
-
-	/**
-	 * Get all inactive switch objects.
-	 */
-	@Override
-	public Iterable<ISwitchObject> getInactiveSwitches() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		Iterable<ISwitchObject> switches =  fg.getVertices("type","switch",ISwitchObject.class);
-		List<ISwitchObject> inactiveSwitches = new ArrayList<ISwitchObject>();
-
-		for (ISwitchObject sw: switches) {
-			if(sw.getState().equals(SwitchState.INACTIVE.toString())) {
-				inactiveSwitches.add(sw);
-			}
-		}
-		return inactiveSwitches;
-	}
-
-	/**
-	 * Get all flow entries' objects where their switches are not updated.
-	 */
-	@Override
-	public Iterable<IFlowEntry> getAllSwitchNotUpdatedFlowEntries() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		//TODO: Should use an enum for flow_switch_state
-		return fg.getVertices("switch_state", "FE_SWITCH_NOT_UPDATED", IFlowEntry.class);
-	}
-
-	/**
-	 * Remove specified switch.
-	 * @param sw switch object to remove
-	 */
-	@Override
-	public void removeSwitch(ISwitchObject sw) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		fg.removeVertex(sw.asVertex());
-	}
-
-	@Override
-	public IPortObject newPort(String dpid, Short portNumber) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		IPortObject obj = fg.addVertex(null,IPortObject.class);
-		if (obj != null) {
-			obj.setType("port");
-			String id = dpid + portNumber.toString();
-			obj.setPortId(id);
-			obj.setNumber(portNumber);
-		}
-		return obj;
-
-	}
-
-	/**
-	 * Create a port having specified port number.
-	 * @param portNumber port number
-	 */
-	@Override
-	@Deprecated
-	public IPortObject newPort(Short portNumber) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		IPortObject obj = fg.addVertex(null,IPortObject.class);
-		if (obj != null) {
-			obj.setType("port");
-			obj.setNumber(portNumber);
-		}
-		return obj;
-	}
-
-	/**
-	 * Search and get a port object of specified switch and port number.
-	 * @param dpid DPID of a switch
-	 * @param number port number of the switch's port
-	 */
-	@Override
-	public IPortObject searchPort(String dpid, Short number) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		if ( fg == null ) return null;
-		String id = dpid + number.toString();
-		Iterator<IPortObject> ports =  fg.getVertices("port_id",id,IPortObject.class).iterator();
-		if ( ports.hasNext() ) {
-			return ports.next();
-		} else {
-			return null;
-		}
-	}
-
-	/**
-	 * Remove the specified switch port.
-	 * @param port switch port object to remove
-	 */
-	@Override
-	public void removePort(IPortObject port) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-//		EventGraph<TitanGraph> eg = conn.getEventGraph();
-		if (fg != null) fg.removeVertex(port.asVertex());
-	}
-
-	/**
-	 * Create and return a device object.
-	 */
-	@Override
-	public IDeviceObject newDevice() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		IDeviceObject obj = fg.addVertex(null,IDeviceObject.class);
-		if (obj != null) obj.setType("device");
-		return obj;
-	}
-
-	/**
-	 * Search and get a device object having specified MAC address.
-	 * @param macAddr MAC address to search and get
-	 */
-	@Override
-	public IDeviceObject searchDevice(String macAddr) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		if ( fg == null ) return null;
-		Iterator<IDeviceObject> devices =  fg.getVertices("dl_addr",macAddr, IDeviceObject.class).iterator();
-		if ( devices.hasNext() ) {
-			return devices.next();
-		} else {
-			return null;
-		}
-	}
-
-	/**
-	 * Get all devices.
-	 */
-	@Override
-	public Iterable<IDeviceObject> getDevices() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		return fg != null ? fg.getVertices("type","device",IDeviceObject.class) : null;
-	}
-
-	/**
-	 * Remove the specified device.
-	 * @param dev a device object to remove
-	 */
-	@Override
-	public void removeDevice(IDeviceObject dev) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		if (fg != null) fg.removeVertex(dev.asVertex());
-	}
-
-	public IIpv4Address newIpv4Address() {
-		return newVertex("ipv4Address", IIpv4Address.class);
-	}
-
-	private <T extends IBaseObject> T newVertex(String type, Class<T> vertexType) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		T newVertex = fg.addVertex(null, vertexType);
-		if (newVertex != null) {
-			newVertex.setType(type);
-		}
-		return newVertex;
-	}
-
-	public IIpv4Address searchIpv4Address(int intIpv4Address) {
-		return searchForVertex("ipv4_address", intIpv4Address, IIpv4Address.class);
-	}
-
-	private <T> T searchForVertex(String propertyName, Object propertyValue, Class<T> vertexType) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		if (fg != null) {
-			Iterator<T> it =
-					fg.getVertices(propertyName, propertyValue, vertexType).iterator();
-			if (it.hasNext()) {
-				return it.next();
-			}
-		}
-		return null;
-	}
-
-	public IIpv4Address ensureIpv4Address(int intIpv4Address) {
-		IIpv4Address ipv4Vertex = searchIpv4Address(intIpv4Address);
-		if (ipv4Vertex == null) {
-			ipv4Vertex = newIpv4Address();
-			ipv4Vertex.setIpv4Address(intIpv4Address);
-		}
-		return ipv4Vertex;
-	}
-
-	public void removeIpv4Address(IIpv4Address ipv4Address) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		fg.removeVertex(ipv4Address.asVertex());
-	}
-
-	/**
-	 * Create and return a flow path object.
-	 */
-	@Override
-	public IFlowPath newFlowPath() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		IFlowPath flowPath = fg.addVertex(null, IFlowPath.class);
-		if (flowPath != null) flowPath.setType("flow");
-		return flowPath;
-	}
-
-	/**
-	 * Search and get a flow path object with specified flow ID.
-	 * @param flowId flow ID to search
-	 */
-	@Override
-	public IFlowPath searchFlowPath(FlowId flowId) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		if ( fg == null ) return null;
-		Iterator<IFlowPath> flowpaths = fg.getVertices("flow_id", flowId.toString(), IFlowPath.class).iterator();
-		if ( flowpaths.hasNext() ) {
-			return flowpaths.next();
-		} else {
-			return null;
-		}
-	}
-
-	/**
-	 * Get a flow path object with a flow entry.
-	 * @param flowEntry flow entry object
-	 */
-	@Override
-	public IFlowPath getFlowPathByFlowEntry(IFlowEntry flowEntry) {
-		GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
-		pipe.start(flowEntry.asVertex()).out("flow");
-		FramedVertexIterable<IFlowPath> r = new FramedVertexIterable<IFlowPath>(conn.getFramedGraph(),
-				pipe, IFlowPath.class);
-		return r.iterator().hasNext() ? r.iterator().next() : null;
-	}
-
-	/**
-	 * Get all flow path objects.
-	 */
-	@Override
-	public Iterable<IFlowPath> getAllFlowPaths() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		Iterable<IFlowPath> flowPaths = fg.getVertices("type", "flow", IFlowPath.class);
-
-		List<IFlowPath> nonNullFlows = new ArrayList<IFlowPath>();
-
-		for (IFlowPath fp: flowPaths) {
-			if (fp.getFlowId() != null) {
-				nonNullFlows.add(fp);
-			}
-		}
-		return nonNullFlows;
-	}
-
-    /**
-     * Remove the specified flow path.
-     * @param flowPath flow path object to remove
-     */
-	@Override
-	public void removeFlowPath(IFlowPath flowPath) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		fg.removeVertex(flowPath.asVertex());
-	}
-
-	/**
-	 * Create and return a flow entry object.
-	 */
-	@Override
-	public IFlowEntry newFlowEntry() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		IFlowEntry flowEntry = fg.addVertex(null, IFlowEntry.class);
-		if (flowEntry != null) flowEntry.setType("flow_entry");
-		return flowEntry;
-	}
-
-	/**
-	 * Search and get a flow entry object with flow entry ID.
-	 * @param flowEntryId flow entry ID to search
-	 */
-	@Override
-	public IFlowEntry searchFlowEntry(FlowEntryId flowEntryId) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		if ( fg == null ) return null;
-		Iterator<IFlowEntry> flowentries = fg.getVertices("flow_entry_id", flowEntryId.toString(), IFlowEntry.class).iterator();
-		if ( flowentries.hasNext() ) {
-			return flowentries.next();
-		} else {
-			return null;
-		}
-	}
-
-	/**
-	 * Get all flow entry objects.
-	 */
-	@Override
-	public Iterable<IFlowEntry> getAllFlowEntries() {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-
-		return fg.getVertices("type", "flow_entry", IFlowEntry.class);
-	}
-
-	/**
-	 * Remove the specified flow entry.
-	 * @param flowEntry flow entry object to remove
-	 */
-	@Override
-	public void removeFlowEntry(IFlowEntry flowEntry) {
-		FramedGraph<TitanGraph> fg = conn.getFramedGraph();
-		fg.removeVertex(flowEntry.asVertex());
-	}
-
-	/**
-	 * Get the instance of GraphDBConnection assigned to this class.
-	 */
-	@Override
-	public IDBConnection getDBConnection() {
-		return conn;
-	}
-
-	/**
-	 * Commit changes for the graph.
-	 */
-	@Override
-	public void commit() {
-		conn.commit();
-	}
-
-	/**
-	 * Rollback changes for the graph.
-	 */
-	@Override
-	public void rollback() {
-		conn.rollback();
-	}
-
-	/**
-	 * Close the connection of the assigned GraphDBConnection.
-	 */
-	@Override
-	public void close() {
-		conn.close();
-	}
-
-
-}
diff --git a/src/main/java/net/onrc/onos/graph/IDBOperation.java b/src/main/java/net/onrc/onos/graph/IDBOperation.java
index f873f27..a2c6044 100644
--- a/src/main/java/net/onrc/onos/graph/IDBOperation.java
+++ b/src/main/java/net/onrc/onos/graph/IDBOperation.java
@@ -1,5 +1,7 @@
 package net.onrc.onos.graph;
 
+import java.util.Map;
+
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
@@ -39,7 +41,9 @@
 	public IFlowEntry searchFlowEntry(FlowEntryId flowEntryId);
 	public Iterable<IFlowEntry> getAllFlowEntries();
 	public void removeFlowEntry(IFlowEntry flowEntry);
-	
+
+	public void setFlowProperties(IFlowEntry flowEntry, Map<String, Object> map);
+
 	public IDBConnection getDBConnection();	
 	public void commit();
 	public void rollback();
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
index c04d8ad..6beb6d8 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
@@ -420,12 +420,15 @@
 	if (measureONOSFlowEntryTimeProp) {
 	    startSetProperties = System.nanoTime();
 	}
+	
+	FlowProperty flowProp = new FlowProperty(dbHandler, flowEntryObj);
+	
 	//
 	// Set the Flow Entry key:
 	// - flowEntry.flowEntryId()
 	//
-	flowEntryObj.setFlowEntryId(flowEntry.flowEntryId().toString());
-	flowEntryObj.setType("flow_entry");
+	flowProp.setFlowEntryId(flowEntry.flowEntryId().toString());
+	flowProp.setType("flow_entry");
 	if (measureONOSFlowEntryTimeProp) {
 	    numProperties += 2;
 	}
@@ -465,9 +468,9 @@
 	    endSearchSwitch = System.nanoTime();
 	}
 
-	flowEntryObj.setIdleTimeout(flowEntry.idleTimeout());
-	flowEntryObj.setHardTimeout(flowEntry.hardTimeout());
-	flowEntryObj.setSwitchDpid(flowEntry.dpid().toString());
+	flowProp.setIdleTimeout(flowEntry.idleTimeout());
+	flowProp.setHardTimeout(flowEntry.hardTimeout());
+	flowProp.setSwitchDpid(flowEntry.dpid().toString());
 	if (measureONOSFlowEntryTimeProp) {
 	    numProperties += 3;
 	}
@@ -490,7 +493,7 @@
 		endSearchInPort = System.nanoTime();
 	    }
 
-	    flowEntryObj.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
+	    flowProp.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
 	    if (measureONOSFlowEntryTimeProp) {
 		++numProperties;
 	    }
@@ -504,67 +507,67 @@
 	    }
 	}
 	if (flowEntry.flowEntryMatch().matchSrcMac()) {
-	    flowEntryObj.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
+		flowProp.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
 	    if (measureONOSFlowEntryTimeProp) {
 		++numProperties;
 	    }
 	}
 	if (flowEntry.flowEntryMatch().matchDstMac()) {
-	    flowEntryObj.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
+		flowProp.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
 	    if (measureONOSFlowEntryTimeProp) {
 		++numProperties;
 	    }
 	}
 	if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
-	    flowEntryObj.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
+		flowProp.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
 	    if (measureONOSFlowEntryTimeProp) {
 		++numProperties;
 	    }
 	}
 	if (flowEntry.flowEntryMatch().matchVlanId()) {
-	    flowEntryObj.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
+		flowProp.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
 	    if (measureONOSFlowEntryTimeProp) {
 		++numProperties;
 	    }
 	}
 	if (flowEntry.flowEntryMatch().matchVlanPriority()) {
-	    flowEntryObj.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
+		flowProp.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
 	    if (measureONOSFlowEntryTimeProp) {
 		++numProperties;
 	    }
 	}
 	if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
-	    flowEntryObj.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
+		flowProp.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
 	    if (measureONOSFlowEntryTimeProp) {
 		++numProperties;
 	    }
 	}
 	if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
-	    flowEntryObj.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
+		flowProp.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
 	    if (measureONOSFlowEntryTimeProp) {
 		++numProperties;
 	    }
 	}
 	if (flowEntry.flowEntryMatch().matchIpProto()) {
-	    flowEntryObj.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
+		flowProp.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
 	    if (measureONOSFlowEntryTimeProp) {
 		++numProperties;
 	    }
 	}
 	if (flowEntry.flowEntryMatch().matchIpToS()) {
-	    flowEntryObj.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
+		flowProp.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
 	    if (measureONOSFlowEntryTimeProp) {
 		++numProperties;
 	    }
 	}
 	if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
-	    flowEntryObj.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
+		flowProp.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
 	    if (measureONOSFlowEntryTimeProp) {
 		++numProperties;
 	    }
 	}
 	if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
-	    flowEntryObj.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
+		flowProp.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
 	    if (measureONOSFlowEntryTimeProp) {
 		++numProperties;
 	    }
@@ -583,7 +586,7 @@
 		    endSearchOutPort = System.nanoTime();
 		}
 
-		flowEntryObj.setActionOutputPort(fa.actionOutput().port().value());
+		flowProp.setActionOutputPort(fa.actionOutput().port().value());
 		if (measureONOSFlowEntryTimeProp) {
 		    ++numProperties;
 		}
@@ -598,7 +601,7 @@
 	    }
 	}
 	if (! flowEntry.flowEntryActions().isEmpty()) {
-	    flowEntryObj.setActions(flowEntry.flowEntryActions().toString());
+		flowProp.setActions(flowEntry.flowEntryActions().toString());
 	    if (measureONOSFlowEntryTimeProp) {
 		++numProperties;
 	    }
@@ -606,10 +609,10 @@
 
 	// TODO: Hacks with hard-coded state names!
 	if (found)
-	    flowEntryObj.setUserState("FE_USER_MODIFY");
+		flowProp.setUserState("FE_USER_MODIFY");
 	else
-	    flowEntryObj.setUserState("FE_USER_ADD");
-	flowEntryObj.setSwitchState(flowEntry.flowEntrySwitchState().toString());
+		flowProp.setUserState("FE_USER_ADD");
+	flowProp.setSwitchState(flowEntry.flowEntrySwitchState().toString());
 	if (measureONOSFlowEntryTimeProp) {
 	    numProperties += 2;
 	}
@@ -633,6 +636,7 @@
 		endAddEdgeBetweenFlowPath = System.nanoTime();
 	    }
 	}
+    flowProp.commitProperties();
 	if (measureONOSFlowEntryTimeProp) {
 	    endAddFlowEntry = System.nanoTime();
 
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowProperty.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowProperty.java
new file mode 100644
index 0000000..ccc1124
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowProperty.java
@@ -0,0 +1,150 @@
+package net.onrc.onos.ofcontroller.flowmanager;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import net.onrc.onos.graph.DBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
+
+public class FlowProperty {
+    private Map<String, Object> map = new HashMap<>();
+    private DBOperation dbhandler;
+    private IFlowEntry flowEntry;
+    
+    public FlowProperty(DBOperation dbHandler, IFlowEntry flowEntry) {
+        this.dbhandler = dbHandler;
+        this.flowEntry = flowEntry;
+    }
+    
+    public void setFlowId(String value) {
+        map.put("flow_id", value);
+    }
+    
+    public void setUserState(String value) {
+        map.put("user_state", value);
+    }
+    
+    public void setFlowEntryId(String value) {
+        map.put("flow_entry_id", value);
+    }
+    
+    public void setType(String value) {
+        map.put("type", value);
+    }
+    
+    public void setInstallerId(String value) {
+        map.put("installer_id", value);
+    }
+    
+    public void setFlowPathType(String value) {
+        map.put("flow_path_type", value);
+    }
+    
+    public void setFlowPathUserState(String value) {
+        map.put("user_state", value);
+    }
+    
+    public void flow_path_flags(Long value) {
+        map.put("flow_path_flags", value);
+    }
+    
+    public void setIdleTimeout(Integer value) {
+        map.put("idle_timeout", value);
+    }
+    
+    public void setHardTimeout(Integer value) {
+        map.put("hard_timeout", value);
+    }
+    
+    public void setSwitchDpid(String value) {
+        map.put("switch_dpid", value);
+    }
+    
+    public void setSwitchState(String value) {
+        map.put("switch_state", value);
+    }
+    
+    public void setSrcSwitch(String value) {
+        map.put("src_switch", value);
+    }
+    
+    public void setSrcPort(Short value) {
+        map.put("src_port", value);
+    }
+    
+    public void setDstSwitch(String value) {
+        map.put("dst_switch", value);
+    }
+    
+    public void setDstPort(Short value) {
+        map.put("dst_port", value);
+    }
+    
+    public void setMatchSrcMac(String value) {
+        map.put("matchSrcMac", value);
+    }
+    
+    public void setMatchDstMac(String value) {
+        map.put("matchDstMac", value);
+    }
+    
+    public void setMatchEthernetFrameType(Short value) {
+        map.put("matchEthernetFrameType", value);
+    }
+    
+    public void setMatchVlanId(Short value) {
+        map.put("matchVlanId", value);
+    }
+    
+    public void setMatchVlanPriority(Byte value) {
+        map.put("matchVlanPriority", value);
+    }
+    
+    public void setMatchSrcIPv4Net(String value) {
+        map.put("matchSrcIPv4Net", value);
+    }
+    
+    public void setMatchDstIPv4Net(String value) {
+        map.put("matchDstIPv4Net", value);
+    }
+    
+    public void setMatchIpProto(Byte value) {
+        map.put("matchIpProto", value);
+    }
+    
+    public void setMatchIpToS(Byte value) {
+        map.put("matchIpToS", value);
+    }
+    
+    public void setMatchInPort(Short value) {
+        map.put("matchInPort", value);
+    }
+    
+    public void setMatchSrcTcpUdpPort(Short value) {
+        map.put("matchSrcTcpUdpPort", value);
+    }
+    
+    public void setMatchDstTcpUdpPort(Short value) {
+        map.put("matchDstTcpUdpPort", value);
+    }
+    
+    public void setActions(String value) {
+        map.put("actions", value);
+    }
+    
+    public void setActionOutputPort(Short value) {
+        map.put("actionOutputPort", value);
+    }
+    
+    public void setDataPathSummary(String value) {
+        map.put("data_path_summary", value);
+    }
+    
+    /**
+     *
+     * @param dbhandler
+     */
+    public void commitProperties() {
+        dbhandler.setFlowProperties(flowEntry ,map);
+    }
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java b/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java
index 570e94f..cbc3224 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/TopologyManager.java
@@ -14,7 +14,6 @@
 import net.onrc.onos.datagrid.IDatagridService;
 import net.onrc.onos.graph.DBOperation;
 import net.onrc.onos.graph.GraphDBManager;
-import net.onrc.onos.graph.GraphDBOperation;
 import net.onrc.onos.ofcontroller.floodlightlistener.INetworkGraphService;
 import net.onrc.onos.ofcontroller.topology.web.OnosTopologyWebRoutable;
 import net.onrc.onos.ofcontroller.util.DataPath;