Merge branch 'master' of github.com:OPENNETWORKINGLAB/ONOS into refactor_phase2_simple

Conflicts:
	build.xml
	src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
	src/test/java/net/onrc/onos/util/GraphDBOperationTest.java
diff --git a/build.xml b/build.xml
deleted file mode 100644
index 22461dd..0000000
--- a/build.xml
+++ /dev/null
@@ -1,315 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-
- <!--
-   Copyright 2011, Big Switch Networks, Inc.
-   
-   Licensed to the Apache Software Foundation (ASF) under one or more
-   contributor license agreements.  See the NOTICE file distributed with
-   this work for additional information regarding copyright ownership.
-   The ASF licenses this file to You under the Apache License, Version 2.0
-   (the "License"); you may not use this file except in compliance with
-   the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
--->
-
-<!--
-    The build uses pregenerated Thrift code by default to reduce build
-    dependencies. To generate it locally run the gen-thrift target.
-    If you change the Thrift files be sure to also commit the updated
-    generated code.
--->
-
-<project default="jar" name="Floodlight">
-    <property name="target" location="target"/>
-    <property name="build" location="${target}/bin"/>
-    <property name="build-test" location="${target}/bin-test"/>
-    <property name="build-coverage" location="${target}/bin-coverage"/>
-    <property name="test-output" location="${target}/test"/>
-    <property name="coverage-output" location="${target}/coverage"/>
-    <property name="source" location="src/main/java"/>
-    <property name="resources" location="src/main/resources/"/>
-    <property name="source-test" location="src/test/java"/>
-    <property name="python-src" location="src/main/python"/>
-    <property name="docs" location="${target}/docs"/>
-    <property name="main-class" value="net.onrc.onos.ofcontroller.core.Main"/>
-    <property name="floodlight-jar" location="${target}/floodlight.jar"/>
-    <property name="floodlight-test-jar" location="${target}/floodlight-test.jar"/>
-    <property name="floodlight-only-jar" location="${target}/floodlight-only.jar"/>
-    <property name="thrift.dir" value="${basedir}/src/main/thrift"/>
-    <property name="thrift.out.dir" value="lib/gen-java"/>
-    <property name="thrift.package" value="net/floodlightcontroller/packetstreamer/thrift"/>
-    <property name="ant.build.javac.source" value="1.6"/>
-    <property name="ant.build.javac.target" value="1.6"/>
-    <property name="lib" location="lib"/>
-    <property name="titanlib" location="lib/titan/"/>
-
-    <patternset id="lib">
-        <include name="logback-classic-1.0.0.jar"/>
-        <include name="logback-core-1.0.0.jar"/>
-        <include name="jackson-core-asl-1.9.11.jar"/>
-        <include name="jackson-mapper-asl-1.9.11.jar"/>
-        <include name="slf4j-api-1.6.4.jar"/>
-        <include name="org.restlet-2.1-RC1.jar"/>
-        <include name="org.restlet.ext.jackson-2.1-RC1.jar"/>
-        <include name="org.restlet.ext.simple-2.1-RC1.jar"/>
-        <include name="org.restlet.ext.slf4j-2.1-RC1.jar"/>
-        <include name="simple-4.1.21.jar"/>
-        <include name="netty-3.2.6.Final.jar"/>
-        <include name="args4j-2.0.16.jar"/>
-        <include name="concurrentlinkedhashmap-lru-1.3.jar"/>
-        <include name="jython-2.5.2.jar"/>
-        <include name="libthrift-0.7.0.jar"/>
-	<include name="curator-client-1.3.5-SNAPSHOT.jar"/>
-	<include name="curator-framework-1.3.5-SNAPSHOT.jar"/>
-	<include name="curator-recipes-1.3.5-SNAPSHOT.jar"/>
-	<include name="curator-x-discovery-1.3.5-SNAPSHOT.jar"/>
-	<include name="zookeeper-3.4.5.jar"/>
-	<include name="ezmorph-1.0.6.jar"/>	
- 	<include name="json-lib-2.4-jdk15.jar"/>
-    </patternset>
-
-    <patternset id="titanlib">
-	<include name="**/*.jar"/>
-    </patternset>
-
-    <path id="classpath">
-        <fileset dir="${lib}">
-            <patternset refid="lib"/>
-        </fileset>
-        <fileset dir="${titanlib}">
-            <patternset refid="titanlib"/>
-        </fileset>
-    </path>
-
-    <patternset id="lib-cobertura">
-        <include name="cobertura-1.9.4.1.jar"/>
-        <include name="asm-3.0.jar"/>
-        <include name="asm-tree-3.0.jar"/>
-        <include name="oro/jakarta-oro-2.0.8.jar"/>
-        <include name="log4j-1.2.9.jar"/>
-    </patternset>
-    <path id="classpath-cobertura">
-        <fileset dir="${lib}">
-            <patternset refid="lib-cobertura"/>
-    </fileset>
-    </path>
-
-    <patternset id="lib-test">
-        <include name="junit-4.8.2.jar"/>
-        <include name="org.easymock-3.1.jar"/>
-        <include name="objenesis-1.2.jar"/>  <!-- required by easymock to mock classes -->
-        <include name="cglib-nodep-2.2.2.jar"/>    <!-- required by easymock to mock classes -->
-    </patternset>
-    <path id="classpath-test">
-        <fileset dir="${lib}">
-            <patternset refid="lib-test"/>
-            <patternset refid="lib-cobertura"/>
-            <patternset refid="lib"/>
-            <patternset refid="titanlib"/>
-        </fileset>
-    </path>
-
-    <target name="init">
-        <mkdir dir="${build}"/>
-        <mkdir dir="${build-test}"/>
-        <mkdir dir="${target}/lib"/>
-        <mkdir dir="${thrift.out.dir}"/>
-        <mkdir dir="${test-output}"/>
-    </target>
-
-    <target name="compile" depends="init">
-        <javac includeAntRuntime="false" 
-           classpathref="classpath" 
-           debug="true" 
-           srcdir="${source}:${thrift.out.dir}"
-           destdir="${build}">
-	  <compilerarg value="-Xlint:unchecked"/>
-        </javac>
-    </target>
-
-    <target name="compile-tests" depends="compile-test"/>
-    <target name="compile-test" depends="compile">
-        <fileset dir="${resources}"/>
-        <javac includeAntRuntime="false" debug="true" 
-           srcdir="${source-test}"
-           classpath="${build}"
-           classpathref="classpath-test"
-           destdir="${build-test}"/>
-    </target>
-
-    <!-- Thrift build based on http://www.flester.com/blog/2009/04/26/using-thrift-from-ant -->
-    <fileset id="thrift.files" dir="${thrift.dir}">
-        <include name="**/*.thrift"/>
-    </fileset>
-
-    <target name="gen-thrift" depends="init">
-        <pathconvert property="thrift.file.list" refid="thrift.files"
-            pathsep=" " dirsep="/">
-        </pathconvert>
-        <echo message="Running thrift generator on ${thrift.file.list}"/>
-        <exec executable="thrift" dir="${basedir}" failonerror="true">
-            <arg line="--strict -v --gen java -o ${thrift.out.dir}/.. ${thrift.file.list}"/>
-        </exec>
-        <!-- Get rid of annoying warnings in thrift java: at annotations -->
-        <echo message="Adding @SuppressWarning annotations"/>
-        <replaceregexp byline="true">
-            <regexp pattern="^public "/>
-            <substitution expression='@SuppressWarnings("all") public '/>
-            <fileset id="thrift.output.files" dir="${thrift.out.dir}/..">
-                <include name="**/*.java"/>
-            </fileset>
-        </replaceregexp>
-    </target>
-
-    <target name="clean">
-        <delete dir="${target}"/>
-    </target>
-
-    <target name="run" depends="dist">
-        <java fork="true" jar="${floodlight-jar}" classpathref="classpath">
-            <jvmarg value="-server"/>
-            <jvmarg value="-Xms1024M"/>
-            <jvmarg value="-Xmx1024M"/>
-        </java>
-    </target>
-
-    <target name="tests" depends="test"/>
-    <target name="test" depends="compile-test">
-        <junit fork="true" forkmode="once"
-           failureproperty="junit.failure"
-           printsummary="on">
-        <sysproperty key="net.sourceforge.cobertura.datafile"
-             file="${target}/cobertura.ser" />
-            <classpath>
-                <pathelement location="${build-coverage}"/>
-                <pathelement location="${build}"/>
-                <pathelement location="${build-test}"/>
-                <pathelement location="${floodlight-jar}"/>
-                <path refid="classpath-test"/>
-            </classpath>
-            <formatter type="brief" usefile="true" />
-            <batchtest todir="${test-output}">
-                <fileset dir="${source-test}">
-                    <exclude name="**/storage/tests/StorageTest.java"/>
-				    <include name="**/*Test*.java"/>
-                    <exclude name="**/core/test/**"/>
-                    <exclude name="**/core/module/**"/>
-                </fileset>
-            </batchtest>
-        </junit>
-        <fail if="junit.failure" message="Unit test(s) failed.  See reports!"/>
-    </target>
-
-    <taskdef classpathref="classpath-cobertura" resource="tasks.properties"/>
-    <target name="clean-instrument">
-        <delete file="${target}/cobertura.ser"/>
-        <delete dir="${build-coverage}"/>
-    </target>
-    <target name="instrument" depends="compile,compile-test,clean-instrument">
-      <cobertura-instrument datafile="${target}/cobertura.ser"
-                todir="${build-coverage}"
-                classpathref="classpath-cobertura">
-    <fileset dir="${build}">
-      <include name="**/*.class"/>
-    </fileset>
-      </cobertura-instrument>
-    </target>
-    <target name="coverage-report">
-        <cobertura-report format="html"
-              datafile="${target}/cobertura.ser"
-              destdir="${coverage-output}"
-              srcdir="${source}"/>
-        <cobertura-report format="xml"
-              datafile="${target}/cobertura.ser"
-              destdir="${coverage-output}"
-              srcdir="${source}"/>
-    </target>
-    <target name="coverage" depends="instrument,test,coverage-report"/>
-
-    <target name="jar" depends="compile">
-        <jar destfile="${floodlight-only-jar}">
-	    <fileset dir="${build}"/>
-	    <fileset dir="${resources}"/>
-	    <fileset dir="${python-src}">
-	        <include name="**/*.py"/>
-	    </fileset>
-        </jar>
-    </target>
-
-    <target name="dist" depends="compile,compile-test">
-        <jar destfile="${floodlight-jar}" filesetmanifest="mergewithoutmain">
-            <manifest>
-                <attribute name="Main-Class" value="${main-class}"/>
-                <attribute name="Class-Path" value="."/>
-            </manifest>
-            <fileset dir="${build}"/>
-            <fileset dir="${resources}"/>
-            <fileset dir="${python-src}">
-                <include name="**/*.py"/>
-            </fileset>
-            <zipgroupfileset dir="${titanlib}">
-                <patternset refid="titanlib"/>
-            </zipgroupfileset>
-            <zipgroupfileset dir="${lib}">
-                <patternset refid="lib"/>
-            </zipgroupfileset>
-        </jar>
-        <jar destfile="${floodlight-test-jar}" filesetmanifest="mergewithoutmain">
-            <manifest>
-                <attribute name="Class-Path" value="."/>
-            </manifest>
-            <fileset dir="${build-test}"/>
-            <fileset dir="${resources}"/>
-            <zipgroupfileset dir="${lib}">
-                <patternset refid="lib-test"/>
-                <patternset refid="lib-cobertura"/>
-            </zipgroupfileset>
-            <zipgroupfileset dir="${titanlib}">
-                <patternset refid="titanlib"/>
-            </zipgroupfileset>
-        </jar>
-    </target>
-
-    <target name="javadoc">
-        <javadoc access="protected"
-            author="true"
-            classpathref="classpath"
-            destdir="${docs}"
-            doctitle="Floodlight"
-            nodeprecated="false"
-            nodeprecatedlist="false"
-            noindex="false"
-            nonavbar="false"
-            notree="false"
-            source="1.6"
-            sourcepath="${source}"
-            splitindex="true"
-            use="true"
-            version="true"/>
-    </target>
-
-    <target name="eclipse" depends="init">
-        <pathconvert property="eclipse-lib">
-            <map from="${basedir}/" to=""/>
-            <fileset dir="${lib}">
-                <patternset refid="lib"/>
-                <patternset refid="lib-test"/>
-            </fileset>
-            <fileset dir="${titanlib}">
-                <patternset refid="titanlib"/>
-            </fileset>
-        </pathconvert>
-        <exec executable="${basedir}/setup-eclipse.sh">
-            <arg value="${main-class}"/>
-            <arg value="${eclipse-lib}"/>
-        </exec>
-    </target>
-
-</project>
diff --git a/pom.xml b/pom.xml
index b9b666f..98d0e61 100644
--- a/pom.xml
+++ b/pom.xml
@@ -25,6 +25,9 @@
       <id>tinkerpop-repository</id>
       <name>TinkerPop Maven2 Repository</name>
       <url>http://tinkerpop.com/maven2</url>
+      <snapshots>
+	<enabled>false</enabled>
+      </snapshots>
     </repository>
   </repositories>
   <properties>
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
index 486d057..1f3939a 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
@@ -14,11 +14,13 @@
 
 import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.IOFSwitchListener;
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.core.module.FloodlightModuleException;
 import net.floodlightcontroller.core.module.IFloodlightModule;
 import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.devicemanager.IDeviceService;
+import net.floodlightcontroller.linkdiscovery.ILinkDiscovery;
 import net.floodlightcontroller.linkdiscovery.ILinkDiscovery.LDUpdate;
 import net.floodlightcontroller.packet.Ethernet;
 import net.floodlightcontroller.restserver.IRestApiService;
@@ -36,21 +38,23 @@
 import org.codehaus.jackson.JsonParseException;
 import org.codehaus.jackson.map.JsonMappingException;
 import org.codehaus.jackson.map.ObjectMapper;
-import org.codehaus.jackson.type.TypeReference;
 import org.openflow.protocol.OFFlowMod;
 import org.openflow.protocol.OFMatch;
 import org.openflow.protocol.OFMessage;
 import org.openflow.protocol.OFPacketOut;
+import org.openflow.protocol.OFPhysicalPort;
 import org.openflow.protocol.OFType;
 import org.openflow.protocol.action.OFAction;
 import org.openflow.protocol.action.OFActionDataLayerDestination;
 import org.openflow.protocol.action.OFActionOutput;
+import org.openflow.util.HexString;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.net.InetAddresses;
 
-public class BgpRoute implements IFloodlightModule, IBgpRouteService, ITopologyListener {
+public class BgpRoute implements IFloodlightModule, IBgpRouteService, 
+									ITopologyListener, IOFSwitchListener {
 	
 	protected static Logger log = LoggerFactory.getLogger(BgpRoute.class);
 
@@ -79,16 +83,27 @@
 	protected final short SDNIP_PRIORITY = 10;
 	
 	protected Map<String, GatewayRouter> gatewayRouters;
+	protected List<String> switches;
+	
+	//True when all switches have connected
+	protected volatile boolean switchesConnected = false;
+	//True when we have a full mesh of shortest paths between gateways
+	protected volatile boolean topologyReady = false;
 	
 	private void readGatewaysConfiguration(String gatewaysFilename){
 		File gatewaysFile = new File(gatewaysFilename);
 		ObjectMapper mapper = new ObjectMapper();
 		
-		TypeReference<HashMap<String, GatewayRouter>> typeref 
-			= new TypeReference<HashMap<String, GatewayRouter>>() {};
-		
 		try {
-			gatewayRouters = mapper.readValue(gatewaysFile, typeref);
+			Configuration config = mapper.readValue(gatewaysFile, Configuration.class);
+			
+			gatewayRouters = config.getGateways();
+			switches = config.getSwitches();
+			
+			for (String sw : switches){
+				log.debug("Switchjoin {}", sw);
+			}
+			
 		} catch (JsonParseException e) {
 			log.error("Error in JSON file", e);
 			System.exit(1);
@@ -265,6 +280,18 @@
 
 	}
 	
+	private String getPrefixFromPtree(PtreeNode node){
+        InetAddress address = null;
+        try {
+			address = InetAddress.getByAddress(node.key);
+		} catch (UnknownHostException e1) {
+			//Should never happen is the reverse conversion has already been done
+			log.error("Malformed IP address");
+			return "";
+		}
+        return address.toString() + "/" + node.rib.masklen;
+	}
+	
 	private void retrieveRib(){
 		String url = "http://" + bgpdRestIp + "/wm/bgp/" + routerId;
 		String response = RestClient.get(url);
@@ -318,6 +345,15 @@
 	}
 	
 	public void prefixAdded(PtreeNode node) {
+		if (!topologyReady){
+			return;
+		}
+		
+		String prefix = getPrefixFromPtree(node);
+		
+		log.debug("New prefix {} added, next hop {}", 
+				prefix, node.rib.nextHop.toString());
+		
 		//Add a flow to rewrite mac for this prefix to all border switches
 		GatewayRouter thisRouter = gatewayRouters
 				.get(InetAddresses.toAddrString(node.rib.nextHop));
@@ -425,15 +461,88 @@
 	}
 	
 	public void prefixDeleted(PtreeNode node) {
-		//Remove MAC rewriting flows from other border switches
+		if (!topologyReady) {
+			return;
+		}
 		
+		String prefix = getPrefixFromPtree(node);
+		
+		log.debug("Prefix {} deleted, next hop {}", 
+				prefix, node.rib.nextHop.toString());
+		
+		//Remove MAC rewriting flows from other border switches
+		GatewayRouter thisRouter = gatewayRouters
+				.get(InetAddresses.toAddrString(node.rib.nextHop));
+		
+		for (GatewayRouter ingressRouter : gatewayRouters.values()){
+			if (ingressRouter == thisRouter) {
+				continue;
+			}
+			
+			//Set up the flow mod
+			OFFlowMod fm =
+	                (OFFlowMod) floodlightProvider.getOFMessageFactory()
+	                                              .getMessage(OFType.FLOW_MOD);
+			
+	        fm.setIdleTimeout((short)0)
+	        .setHardTimeout((short)0)
+	        .setBufferId(OFPacketOut.BUFFER_ID_NONE)
+	        .setCookie(MAC_RW_COOKIE)
+	        .setCommand(OFFlowMod.OFPFC_DELETE)
+	        //.setMatch(match)
+	        //.setActions(actions)
+	        .setPriority(SDNIP_PRIORITY)
+	        .setLengthU(OFFlowMod.MINIMUM_LENGTH);
+	        		//+ OFActionDataLayerDestination.MINIMUM_LENGTH
+	        		//+ OFActionOutput.MINIMUM_LENGTH);
+	        
+	        OFMatch match = new OFMatch();
+	        match.setDataLayerType(Ethernet.TYPE_IPv4);
+	        match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_TYPE);
+	        
+	        match.setDataLayerSource(ingressRouter.getRouterMac().toBytes());
+	        match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_SRC);
+	        
+	        //match.setDataLayerDestination(ingressRouter.getSdnRouterMac().toBytes());
+	        //match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_DST);
+
+	        InetAddress address = null;
+	        try {
+				address = InetAddress.getByAddress(node.key);
+			} catch (UnknownHostException e1) {
+				//Should never happen is the reverse conversion has already been done
+				log.error("Malformed IP address");
+				return;
+			}
+	        
+	        match.setFromCIDR(address.getHostAddress() + "/" + node.rib.masklen, OFMatch.STR_NW_DST);
+	        fm.setMatch(match);
+	        
+	        //Write to switch
+	        IOFSwitch sw = floodlightProvider.getSwitches()
+	        		.get(ingressRouter.getAttachmentPoint().dpid().value());
+	        
+            if (sw == null){
+            	log.warn("Switch not found when pushing flow mod");
+            	continue;
+            }
+            
+            List<OFMessage> msglist = new ArrayList<OFMessage>();
+            msglist.add(fm);
+            try {
+				sw.write(msglist, null);
+				sw.flush();
+			} catch (IOException e) {
+				log.error("Failure writing flow mod", e);
+			}
+		}
 	}
 	
 	/*
 	 * On startup we need to calculate a full mesh of paths between all gateway
 	 * switches
 	 */
-	private void calculateFullMesh(){
+	private void setupFullMesh(){
 		Map<IOFSwitch, SwitchPort> gatewaySwitches = new HashMap<IOFSwitch, SwitchPort>();
 		
 		//have to account for switches not being there, paths not being found.
@@ -455,7 +564,6 @@
 			}
 			
 		}
-		log.debug("size {}", gatewaySwitches.size());
 		
 		//For each border router, calculate and install a path from every other
 		//border switch to said border router. However, don't install the entry
@@ -544,46 +652,122 @@
 		}
 	}
 	
+	
+	private void beginRouting(){
+		log.debug("Topology is now ready, beginning routing function");
+		
+		//traverse ptree and create flows for all routes
+		for (PtreeNode node = ptree.begin(); node != null; node = ptree.next(node)){
+			if (node.rib != null){
+				prefixAdded(node);
+			}
+		}
+	}
+	
+	private void checkSwitchesConnected(){
+		for (String dpid : switches){
+			if (floodlightProvider.getSwitches().get(HexString.toLong(dpid)) == null){
+				log.debug("Not all switches are here yet");
+				return;
+			}
+		}
+		switchesConnected = true;
+	}
+	
+	private void checkTopologyReady(){
+		for (GatewayRouter dstRouter : gatewayRouters.values()){
+			SwitchPort dstAttachmentPoint = dstRouter.getAttachmentPoint();
+			for (GatewayRouter srcRouter : gatewayRouters.values()) {
+				
+				if (dstRouter == srcRouter){
+					continue;
+				}
+				
+				SwitchPort srcAttachmentPoint = srcRouter.getAttachmentPoint();
+				
+				DataPath shortestPath = topoRouteService.getShortestPath(
+						srcAttachmentPoint, dstAttachmentPoint);
+				
+				if (shortestPath == null){
+					log.debug("Shortest path between {} and {} not found",
+							srcAttachmentPoint, dstAttachmentPoint);
+					return;
+				}
+			}
+		}
+		topologyReady = true;
+	}
+	
+	private void checkStatus(){
+		log.debug("In checkStatus, swC {}, toRe {}", switchesConnected, topologyReady);
+		
+		if (!switchesConnected){
+			checkSwitchesConnected();
+		}
+		boolean oldTopologyReadyStatus = topologyReady;
+		if (switchesConnected && !topologyReady){
+			checkTopologyReady();
+		}
+		if (!oldTopologyReadyStatus && topologyReady){
+			beginRouting();
+		}
+	}
+	
 	@Override
 	public void startUp(FloodlightModuleContext context) {
 		restApi.addRestletRoutable(new BgpRouteWebRoutable());
+		floodlightProvider.addOFSwitchListener(this);
 		topology.addListener(this);
 		
 		//Retrieve the RIB from BGPd during startup
 		retrieveRib();
-		
-		//Don't have to do this as we'll never have switches connected here
-		//calculateFullMesh();
 	}
 
 	@Override
-	public void topologyChanged() {
-		//Probably need to look at all changes, not just port changes
-		/*
-		boolean change = false;
-		String changelog = "";
+	public void topologyChanged() {		
+		//There seems to be more topology events than there should be. Lots of link
+		//updated, port up and switch updated on what should be a fairly static topology
 		
-		for (LDUpdate ldu : topology.getLastLinkUpdates()) {
-			if (ldu.getOperation().equals(ILinkDiscovery.UpdateOperation.PORT_DOWN)) {
-				change = true;
-				changelog = changelog + " down ";
-			} else if (ldu.getOperation().equals(ILinkDiscovery.UpdateOperation.PORT_UP)) {
-				change = true;
-				changelog = changelog + " up ";
+		boolean refreshNeeded = false;
+		for (LDUpdate ldu : topology.getLastLinkUpdates()){
+			if (!ldu.getOperation().equals(ILinkDiscovery.UpdateOperation.LINK_UPDATED)){
+				//We don't need to recalculate anything for just link updates
+				//They happen way too frequently (may be a bug in our link discovery)
+				refreshNeeded = true;
+			}
+			log.debug("Topo change {}", ldu.getOperation());
+		}
+		
+		if (refreshNeeded){
+			if (topologyReady){
+				setupFullMesh();
+			}
+			else{
+				checkStatus();
 			}
 		}
-		log.info ("received topo change" + changelog);
+	}
 
-		if (change) {
-			//RestClient.get ("http://localhost:5000/topo_change");
-		}
-		*/
-		
-		for (LDUpdate update : topology.getLastLinkUpdates()){
-			log.debug("{} event causing internal L2 path recalculation",
-					update.getOperation().toString());
-			
-		}
-		calculateFullMesh();
+	//TODO determine whether we need to listen for switch joins
+	@Override
+	public void addedSwitch(IOFSwitch sw) {
+		//checkStatus();
+	}
+
+	@Override
+	public void removedSwitch(IOFSwitch sw) {
+		// TODO Auto-generated method stub	
+	}
+
+	@Override
+	public void switchPortChanged(Long switchId) {}
+	@Override
+	public void switchPortAdded(Long switchId, OFPhysicalPort port) {}
+	@Override
+	public void switchPortRemoved(Long switchId, OFPhysicalPort port) {}
+
+	@Override
+	public String getName() {
+		return "BgpRoute";
 	}
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteResource.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteResource.java
index 34c5c43b..8355308 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteResource.java
@@ -184,6 +184,16 @@
 			}
 
 			PtreeNode node = ptree.lookup(p.getAddress(), p.masklen);
+			
+			//Remove the flows from the switches before the rib is lost
+			//Theory: we could get a delete for a prefix not in the Ptree.
+			//This would result in a null node being returned. We could get a delete for
+			//a node that's not actually there, but is a aggregate node. This would result
+			//in a non-null node with a null rib. Only a non-null node with a non-null
+			//rib is an actual prefix in the Ptree.
+			if (node != null && node.rib != null){
+				bgpRoute.prefixDeleted(node);
+			}
 
 			Rib r = new Rib(routerId, nextHop, p.masklen);
 
@@ -193,8 +203,6 @@
 					ptree.delReference(node);					
 				}
 			}
-
-			bgpRoute.prefixDeleted(node);
 			
 			reply =reply + "[DELE: " + prefix + "/" + mask + ":" + nextHop + "]";
 		}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/Configuration.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/Configuration.java
new file mode 100644
index 0000000..5194584
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/Configuration.java
@@ -0,0 +1,34 @@
+package net.onrc.onos.ofcontroller.bgproute;
+
+import java.util.List;
+import java.util.Map;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+public class Configuration {
+	List<String> switches;
+	Map<String, GatewayRouter> gateways;
+	
+	public Configuration() {
+		// TODO Auto-generated constructor stub
+	}
+
+	public List<String> getSwitches() {
+		return switches;
+	}
+
+	@JsonProperty("switches")
+	public void setSwitches(List<String> switches) {
+		this.switches = switches;
+	}
+
+	public Map<String, GatewayRouter> getGateways() {
+		return gateways;
+	}
+
+	@JsonProperty("gateways")
+	public void setGateways(Map<String, GatewayRouter> gateways) {
+		this.gateways = gateways;
+	}
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
index 7b89502..fc1c32f 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
@@ -48,7 +48,7 @@
 
 // Requires Frames 2.3.0		
 		@JsonIgnore
-		@GremlinGroovy("_().out('on').has('number',port_num)")
+		@GremlinGroovy("it.out('on').has('number',port_num)")
 		public IPortObject getPort(@GremlinParam("port_num") final short port_num);
 		
 		@Adjacency(label="on")
@@ -58,7 +58,7 @@
 		public void removePort(final IPortObject port);
 		
 		@JsonIgnore
-		@GremlinGroovy("_().out('on').out('host')")
+		@GremlinGroovy("it.out('on').out('host')")
 		public Iterable<IDeviceObject> getDevices();
 		
 		@JsonIgnore
@@ -91,6 +91,7 @@
 		public void setPortState(Integer s);
 		
 		@JsonIgnore
+//		@GremlinGroovy("it.in('on')")
 		@Adjacency(label="on",direction = Direction.IN)
 		public ISwitchObject getSwitch();
 				
@@ -154,7 +155,7 @@
 		public void removeHostPort(final IPortObject port);
 		
 		@JsonIgnore
-		@GremlinGroovy("_().in('host').in('on')")
+		@GremlinGroovy("it.in('host').in('on')")
 		public Iterable<ISwitchObject> getSwitch();
 		
 /*		@JsonProperty("dpid")
@@ -267,7 +268,7 @@
 		public void setMatchDstIPv4Net(String matchDstIPv4Net);
 		
 		@JsonIgnore
-		@GremlinGroovy("_().in('flow').out('switch')")
+		@GremlinGroovy("it.in('flow').out('switch')")
 		public Iterable<ISwitchObject> getSwitches();
 		
 		@JsonIgnore
diff --git a/src/main/java/net/onrc/onos/util/GraphDBOperation.java b/src/main/java/net/onrc/onos/util/GraphDBOperation.java
index 950741d..5a70dbc 100644
--- a/src/main/java/net/onrc/onos/util/GraphDBOperation.java
+++ b/src/main/java/net/onrc/onos/util/GraphDBOperation.java
@@ -174,9 +174,8 @@
 	public IDeviceObject searchDevice(String macAddr) {
 		// TODO Auto-generated method stub
 		FramedGraph<TitanGraph> fg = conn.getFramedGraph();	
-		return (fg != null && fg.getVertices("dl_addr",macAddr).iterator().hasNext()) ? fg.getVertices("dl_addr",macAddr,
-    			IDeviceObject.class).iterator().next() : null;
-    			
+		return (fg != null && fg.getVertices("dl_addr",macAddr).iterator().hasNext()) ?
+			fg.getVertices("dl_addr",macAddr, IDeviceObject.class).iterator().next() : null;
 	}
 
 	@Override
diff --git a/src/test/java/net/onrc/onos/util/GraphDBOperationTest.java b/src/test/java/net/onrc/onos/util/GraphDBOperationTest.java
index 041f5d0..294c043 100644
--- a/src/test/java/net/onrc/onos/util/GraphDBOperationTest.java
+++ b/src/test/java/net/onrc/onos/util/GraphDBOperationTest.java
@@ -5,11 +5,19 @@
 
 import static org.junit.Assert.*;
 
-import java.util.Iterator;
+import java.util.*;
 
+import junit.framework.TestCase;
+
+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.IPortObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
 import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
 import net.onrc.onos.ofcontroller.core.internal.TestDatabaseManager;
+import net.onrc.onos.ofcontroller.util.FlowEntryId;
+import net.onrc.onos.ofcontroller.util.FlowId;
 
 import org.easymock.EasyMock;
 import org.junit.After;
@@ -30,9 +38,10 @@
  * @author Toshio Koide
  *
  */
+
 @RunWith(PowerMockRunner.class)
 @PrepareForTest({TitanFactory.class})
-public class GraphDBOperationTest {
+public class GraphDBOperationTest extends TestCase {
 	private static TitanGraph testdb;
 	private static GraphDBConnection conn;
 	private static GraphDBOperation op;
@@ -59,13 +68,14 @@
 		TestDatabaseManager.deleteTestDatabase();
 		testdb = TestDatabaseManager.getTestDatabase();
 //		TestDatabaseManager.populateTestData(titanGraph);
-		
+
+		String dummyPath = "/dummy/to/conf";
 		// replace return value of TitanFactory.open() to dummy DB created above
 		PowerMock.mockStatic(TitanFactory.class);
-		EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(testdb);
+		EasyMock.expect(TitanFactory.open(dummyPath)).andReturn(testdb);
 		PowerMock.replay(TitanFactory.class);
 		
-		conn = GraphDBConnection.getInstance("/dummy/to/conf");
+		conn = GraphDBConnection.getInstance(dummyPath);
 		op = new GraphDBOperation(conn);
 	}
 
@@ -76,28 +86,22 @@
 	public void tearDown() throws Exception {
 		conn.close();
 		testdb.shutdown();
+		PowerMock.verifyAll();
 	}
 
-	private Iterator<Vertex> enumerateVertices(String vertexType) {
-		return testdb.getVertices("type", vertexType).iterator();
-	}
-	
 	/**
 	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#newSwitch(net.onrc.onos.util.GraphDBConnection)}.
 	 */
 	@Test
 	public final void testNewSwitch() {
-		Iterator<Vertex> vertices;
-		assertFalse(enumerateVertices("switch").hasNext());
+		assertNull(op.searchSwitch("123"));
 
-		ISwitchObject sw = op.newSwitch("123");
-		
-		assertEquals("123", sw.getDPID());
+		op.newSwitch("123");		
 		op.commit();
 
-		vertices = enumerateVertices("switch");
-		assertTrue(vertices.hasNext());
-		assertEquals(vertices.next().getProperty("dpid").toString(), "123");		
+		ISwitchObject sw = op.searchSwitch("123");
+		assertNotNull(op);
+		assertEquals("123", sw.getDPID());
 	}
 
 	/**
@@ -105,13 +109,16 @@
 	 */
 	@Test
 	public final void testSearchSwitch() {
-		ISwitchObject sw = op.newSwitch("123");
+		op.newSwitch("123");
+		op.newSwitch("456");
 		op.commit();
-		
-		sw = op.searchSwitch("123");
-		
+
+		ISwitchObject sw = op.searchSwitch("123");
 		assertNotNull(sw);
 		assertEquals("123", sw.getDPID());
+
+		sw = op.searchSwitch("789");
+		assertNull(sw);
 	}
 
 	/**
@@ -119,13 +126,11 @@
 	 */
 	@Test
 	public final void testSearchActiveSwitch() {
-		ISwitchObject sw = op.newSwitch("111");
-		sw.setState(SwitchState.ACTIVE.toString());
-		sw = op.newSwitch("222");
-		sw.setState(SwitchState.INACTIVE.toString());
+		op.newSwitch("111").setState(SwitchState.ACTIVE.toString());
+		op.newSwitch("222").setState(SwitchState.INACTIVE.toString());
 		op.commit();
 		
-		sw = op.searchActiveSwitch("111");
+		ISwitchObject sw = op.searchActiveSwitch("111");
 		assertNotNull(sw);
 		assertEquals("111", sw.getDPID());
 		
@@ -138,16 +143,71 @@
 	 */
 	@Test
 	public final void testGetActiveSwitches() {
-		ISwitchObject sw = op.newSwitch("111");
-		sw.setState(SwitchState.ACTIVE.toString());
-		sw = op.newSwitch("222");
-		sw.setState(SwitchState.INACTIVE.toString());
+		op.newSwitch("111").setState(SwitchState.ACTIVE.toString());
+		op.newSwitch("222").setState(SwitchState.INACTIVE.toString());
 		op.commit();
 		
 		Iterator<ISwitchObject> i = op.getActiveSwitches().iterator();
+		
 		assertTrue(i.hasNext());
 		assertEquals("111", i.next().getDPID());
-		assertFalse(i.hasNext());		
+		assertFalse(i.hasNext());
+	}
+
+	/**
+	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#getAllSwitches(net.onrc.onos.util.GraphDBConnection)}.
+	 */
+	@Test
+	public final void testGetAllSwitches() {
+		List<String> dpids = Arrays.asList("111", "222", "333");
+		Collections.sort(dpids);
+		
+		for (String dpid: dpids) op.newSwitch(dpid);
+		op.commit();
+
+		List<String> actual_ids = new ArrayList<String>();
+		for (ISwitchObject switchObj: op.getAllSwitches()) actual_ids.add(switchObj.getDPID());
+		Collections.sort(actual_ids);
+
+		assertArrayEquals(dpids.toArray(), actual_ids.toArray());
+	}
+
+	/**
+	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#getInactiveSwitches(net.onrc.onos.util.GraphDBConnection)}.
+	 */
+	@Test
+	public final void testGetInactiveSwitches() {
+		op.newSwitch("111").setState(SwitchState.ACTIVE.toString());
+		op.newSwitch("222").setState(SwitchState.INACTIVE.toString());
+		op.commit();
+		
+		Iterator<ISwitchObject> i = op.getInactiveSwitches().iterator();
+		
+		assertTrue(i.hasNext());
+		assertEquals("222", i.next().getDPID());
+		assertFalse(i.hasNext());
+	}
+
+	/**
+	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#getAllSwitchNotUpdatedFlowEntries(net.onrc.onos.util.GraphDBConnection)}.
+	 */
+	@Test
+	public final void testGetAllSwitchNotUpdatedFlowEntries() {
+		FlowEntryId flowEntryId10 = new FlowEntryId(10);
+		FlowEntryId flowEntryId20 = new FlowEntryId(20);
+		IFlowEntry flowEntry10 = op.newFlowEntry();
+		IFlowEntry flowEntry20 = op.newFlowEntry();
+		flowEntry10.setFlowEntryId(flowEntryId10.toString());
+		flowEntry20.setFlowEntryId(flowEntryId20.toString());
+		flowEntry10.setSwitchState("FE_SWITCH_NOT_UPDATED");
+		flowEntry20.setSwitchState("FE_SWITCH_UPDATED");
+ 		op.commit();
+		
+		Iterator<IFlowEntry> flowEntries = op.getAllSwitchNotUpdatedFlowEntries().iterator();
+		assertNotNull(flowEntries);
+		assertTrue(flowEntries.hasNext());
+		assertEquals(flowEntryId10.toString(), flowEntries.next().getFlowEntryId());
+		assertFalse(flowEntries.hasNext());
 	}
 
 	/**
@@ -158,26 +218,12 @@
 		ISwitchObject sw = op.newSwitch("123");
 		op.commit();	
 		sw = op.searchSwitch("123");
-		
+		assertNotNull(sw);
+
 		op.removeSwitch(sw);
-
-		assertFalse(enumerateVertices("switch").hasNext());
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#searchDevice(net.onrc.onos.util.GraphDBConnection, java.lang.String)}.
-	 */
-	@Test
-	public final void testSearchDevice() {
-		fail("Not yet implemented");
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#searchPort(net.onrc.onos.util.GraphDBConnection, java.lang.String, short)}.
-	 */
-	@Test
-	public final void testSearchPort() {
-		fail("Not yet implemented");
+		op.commit();
+		
+		assertNull(op.searchSwitch("123"));
 	}
 
 	/**
@@ -185,15 +231,65 @@
 	 */
 	@Test
 	public final void testNewPort() {
-		fail("Not yet implemented");
+		assertFalse(testdb.getVertices("type", "port").iterator().hasNext());
+		
+		IPortObject port = op.newPort((short) 10);
+		assertTrue(port.getNumber() == 10);
+		op.commit();
+		
+		Iterator<Vertex> vertices = testdb.getVertices("type", "port").iterator();
+		assertTrue(vertices.hasNext());
+		assertEquals(vertices.next().getProperty("number").toString(), "10");		
 	}
 
 	/**
-	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#newDevice(net.onrc.onos.util.GraphDBConnection)}.
+	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#searchPort(net.onrc.onos.util.GraphDBConnection, java.lang.String, short)}.
 	 */
 	@Test
-	public final void testNewDevice() {
-		fail("Not yet implemented");
+	public final void testSearchPort() {
+		ISwitchObject sw;
+		IPortObject port;
+		
+		sw = op.newSwitch("1");
+		sw.addPort(op.newPort((short) 1));
+		sw.addPort(op.newPort((short) 2));
+		
+		sw = op.newSwitch("2");
+		sw.addPort(op.newPort((short) 1));
+		sw.addPort(op.newPort((short) 2));
+
+		op.commit();
+
+		assertNull(op.searchPort("3", (short) 1));
+		assertNull(op.searchPort("1", (short) 3));
+
+		port = op.searchPort("1", (short) 1);
+		assertNotNull(port);
+		assertTrue(port.getNumber() == 1);
+		sw = port.getSwitch();
+		assertNotNull(sw);
+		assertEquals("1", sw.getDPID());
+
+		port = op.searchPort("1", (short) 2);
+		assertNotNull(port);
+		assertTrue(port.getNumber() == 2);
+		sw = port.getSwitch();
+		assertNotNull(sw);
+		assertEquals("1", sw.getDPID());
+
+		port = op.searchPort("2", (short) 1);
+		assertNotNull(port);
+		assertTrue(port.getNumber() == 1);
+		sw = port.getSwitch();
+		assertNotNull(sw);
+		assertEquals("2", sw.getDPID());
+
+		port = op.searchPort("2", (short) 2);
+		assertNotNull(port);
+		assertTrue(port.getNumber() == 2);
+		sw = port.getSwitch();
+		assertNotNull(sw);
+		assertEquals("2", sw.getDPID());
 	}
 
 	/**
@@ -201,15 +297,69 @@
 	 */
 	@Test
 	public final void testRemovePort() {
-		fail("Not yet implemented");
+		ISwitchObject sw;
+		IPortObject port;
+		
+		sw = op.newSwitch("1");
+		sw.addPort(op.newPort((short) 1));
+		sw.addPort(op.newPort((short) 2));
+		
+		op.commit();
+
+		port = op.searchPort("1", (short) 1);
+		assertNotNull(port);
+		assertNotNull(op.searchPort("1", (short) 2));
+		assertNull(op.searchPort("1", (short) 3));
+
+		op.removePort(port);
+		op.commit();
+		
+		assertNull(op.searchPort("1", (short) 1));
+		port = op.searchPort("1", (short) 2);
+		assertNotNull(port);
+		
+		op.removePort(port);
+		op.commit();
+
+		assertNull(op.searchPort("1", (short) 1));
+		assertNull(op.searchPort("1", (short) 2));
 	}
 
 	/**
-	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#removeDevice(net.onrc.onos.util.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IDeviceObject)}.
+	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#newDevice(net.onrc.onos.util.GraphDBConnection)}.
 	 */
 	@Test
-	public final void testRemoveDevice() {
-		fail("Not yet implemented");
+	public final void testNewDevice() {
+		assertFalse(testdb.getVertices("type", "device").iterator().hasNext());
+		
+		IDeviceObject device = op.newDevice();
+		device.setMACAddress("11:22:33:44:55:66");
+		device.setIPAddress("192.168.1.1");
+		op.commit();
+		
+		Iterator<Vertex> vertices = testdb.getVertices("type", "device").iterator();
+		assertTrue(vertices.hasNext());
+		Vertex v = vertices.next();
+		assertEquals("11:22:33:44:55:66", v.getProperty("dl_addr").toString());
+		assertEquals("192.168.1.1", v.getProperty("nw_addr").toString());
+	}
+
+	/**
+	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#searchDevice(net.onrc.onos.util.GraphDBConnection, java.lang.String)}.
+	 */
+	@Test
+	public final void testSearchDevice() {
+		assertNull(op.searchDevice("11:22:33:44:55:66"));
+		assertNull(op.searchDevice("66:55:44:33:22:11"));
+
+		op.newDevice().setMACAddress("11:22:33:44:55:66");
+		op.commit();
+		
+		IDeviceObject device = op.searchDevice("11:22:33:44:55:66");
+		assertNotNull(device);
+		assertEquals("11:22:33:44:55:66", device.getMACAddress());
+		
+		assertNull(op.searchDevice("66:55:44:33:22:11"));
 	}
 
 	/**
@@ -217,15 +367,33 @@
 	 */
 	@Test
 	public final void testGetDevices() {
-		fail("Not yet implemented");
+		List<String> original_macs = Arrays.asList(
+				"11:11:11:11:11:11",
+				"22:22:22:22:22:22",
+				"33:33:33:33:33:33"
+				);
+		
+		for (String mac: original_macs) op.newDevice().setMACAddress(mac);
+		op.commit();
+		
+		Iterable<IDeviceObject> devices = op.getDevices();
+		List<String> macs = new ArrayList<String>();
+		for (IDeviceObject device: devices) macs.add(device.getMACAddress());
+		Collections.sort(macs);
+		assertArrayEquals(original_macs.toArray(), macs.toArray());
 	}
 
 	/**
-	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#searchFlowPath(net.onrc.onos.util.GraphDBConnection, net.floodlightcontroller.util.FlowId)}.
+	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#removeDevice(net.onrc.onos.util.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IDeviceObject)}.
 	 */
 	@Test
-	public final void testSearchFlowPath() {
-		fail("Not yet implemented");
+	public final void testRemoveDevice() {
+		op.newDevice().setMACAddress("11:22:33:44:55:66");
+		op.commit();
+		
+		op.removeDevice(op.searchDevice("11:22:33:44:55:66"));
+		op.commit();
+		assertNull(op.searchDevice("11:22:33:44:55:66"));
 	}
 
 	/**
@@ -233,15 +401,30 @@
 	 */
 	@Test
 	public final void testNewFlowPath() {
-		fail("Not yet implemented");
+		FlowId flowId = new FlowId(10);
+		IFlowPath flowPath = op.newFlowPath();
+		flowPath.setFlowId(flowId.toString());
+		op.commit();
+
+		Iterator<IFlowPath> flows = op.getAllFlowPaths().iterator();
+		assertTrue(flows.hasNext());
+		assertEquals(flowId.toString(), flows.next().getFlowId());
 	}
 
 	/**
-	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#removeFlowPath(net.onrc.onos.util.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IFlowPath)}.
+	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#searchFlowPath(net.onrc.onos.util.GraphDBConnection, net.floodlightcontroller.util.FlowId)}.
 	 */
 	@Test
-	public final void testRemoveFlowPath() {
-		fail("Not yet implemented");
+	public final void testSearchFlowPath() {
+		FlowId flowId = new FlowId(20);
+		assertNull(op.searchFlowPath(flowId));
+
+		op.newFlowPath().setFlowId(flowId.toString());
+		op.commit();
+		
+		IFlowPath flowPath = op.searchFlowPath(flowId);
+		assertNotNull(flowPath);
+		assertEquals(flowId.toString(), flowPath.getFlowId());
 	}
 
 	/**
@@ -249,7 +432,38 @@
 	 */
 	@Test
 	public final void testGetFlowPathByFlowEntry() {
-		fail("Not yet implemented");
+		FlowId flowId10 = new FlowId(10);
+		FlowId flowId20 = new FlowId(20);
+		IFlowPath flowPath10 = op.newFlowPath();
+		IFlowPath flowPath20 = op.newFlowPath();
+		IFlowEntry flowEntry10 = op.newFlowEntry();
+		IFlowEntry flowEntry20 = op.newFlowEntry();
+		IFlowEntry flowEntry30 = op.newFlowEntry();
+		FlowEntryId flowEntryId10 = new FlowEntryId(10); 
+		FlowEntryId flowEntryId20 = new FlowEntryId(20); 
+		FlowEntryId flowEntryId30 = new FlowEntryId(30); 
+		flowEntry10.setFlowEntryId(flowEntryId10.toString());
+		flowEntry20.setFlowEntryId(flowEntryId20.toString());
+		flowEntry30.setFlowEntryId(flowEntryId30.toString());
+		flowPath10.setFlowId(flowId10.toString());
+		flowPath10.addFlowEntry(flowEntry10);
+		flowPath20.setFlowId(flowId20.toString());
+		flowPath20.addFlowEntry(flowEntry20);
+		op.commit();
+
+		flowEntry10 = op.searchFlowEntry(flowEntryId10);
+		IFlowPath obtainedFlowPath = op.getFlowPathByFlowEntry(flowEntry10);
+		assertNotNull(obtainedFlowPath);
+		assertEquals(flowId10.toString(), obtainedFlowPath.getFlowId());
+		
+		flowEntry20 = op.searchFlowEntry(flowEntryId20);
+		obtainedFlowPath = op.getFlowPathByFlowEntry(flowEntry20);
+		assertNotNull(obtainedFlowPath);
+		assertEquals(flowId20.toString(), obtainedFlowPath.getFlowId());
+		
+		flowEntry30 = op.searchFlowEntry(flowEntryId30);
+		obtainedFlowPath = op.getFlowPathByFlowEntry(flowEntry30);
+		assertNull(obtainedFlowPath);
 	}
 
 	/**
@@ -257,15 +471,43 @@
 	 */
 	@Test
 	public final void testGetAllFlowPaths() {
-		fail("Not yet implemented");
+		List<FlowId> flowids = Arrays.asList(
+				new FlowId(10), new FlowId(20), new FlowId(30)
+				);
+		
+		for (FlowId flowId: flowids)
+			op.newFlowPath().setFlowId(flowId.toString());
+		op.commit();
+
+		List<String> actual_ids = new ArrayList<String>();
+		for (IFlowPath flowPath: op.getAllFlowPaths()) actual_ids.add(flowPath.getFlowId());
+		Collections.sort(actual_ids);
+
+		List<String> expected_ids = new ArrayList<String>();
+		for (FlowId flowid: flowids) expected_ids.add(flowid.toString());
+		Collections.sort(expected_ids);
+		
+		assertArrayEquals(expected_ids.toArray(), actual_ids.toArray());
 	}
 
 	/**
-	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#searchFlowEntry(net.onrc.onos.util.GraphDBConnection, net.floodlightcontroller.util.FlowEntryId)}.
+	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#removeFlowPath(net.onrc.onos.util.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IFlowPath)}.
 	 */
 	@Test
-	public final void testSearchFlowEntry() {
-		fail("Not yet implemented");
+	public final void testRemoveFlowPath() {
+		FlowId flowId10 = new FlowId(10);
+		FlowId flowId20 = new FlowId(20);
+		op.newFlowPath().setFlowId(flowId10.toString());
+		op.newFlowPath().setFlowId(flowId20.toString());
+		op.commit();
+		
+		IFlowPath flowPath = op.searchFlowPath(flowId10);
+		assertNotNull(flowPath);
+		op.removeFlowPath(flowPath);
+		op.commit();
+		
+		assertNull(op.searchFlowPath(flowId10));
+		assertNotNull(op.searchFlowPath(flowId20));
 	}
 
 	/**
@@ -273,15 +515,38 @@
 	 */
 	@Test
 	public final void testNewFlowEntry() {
-		fail("Not yet implemented");
+		IFlowEntry flowEntry = op.newFlowEntry();
+		FlowEntryId flowEntryId = new FlowEntryId();
+		flowEntryId.setValue(12345);
+		flowEntry.setFlowEntryId(flowEntryId.toString());
+		op.commit();
+		
+		flowEntry = op.searchFlowEntry(flowEntryId);
+		assertNotNull(flowEntry);
+		assertEquals(flowEntry.getFlowEntryId(), flowEntryId.toString());		
 	}
 
 	/**
-	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#removeFlowEntry(net.onrc.onos.util.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IFlowEntry)}.
+	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#searchFlowEntry(net.onrc.onos.util.GraphDBConnection, net.floodlightcontroller.util.FlowEntryId)}.
 	 */
 	@Test
-	public final void testRemoveFlowEntry() {
-		fail("Not yet implemented");
+	public final void testSearchFlowEntry() {
+		FlowEntryId flowEntryId10 = new FlowEntryId();
+		flowEntryId10.setValue(10);
+		FlowEntryId flowEntryId20 = new FlowEntryId();
+		flowEntryId20.setValue(20);
+		FlowEntryId flowEntryId30 = new FlowEntryId();
+		flowEntryId30.setValue(30);
+		
+		op.newFlowEntry().setFlowEntryId(flowEntryId10.toString());
+		op.newFlowEntry().setFlowEntryId(flowEntryId20.toString());
+		op.commit();
+		
+		assertNull(op.searchFlowEntry(flowEntryId30));
+		IFlowEntry flowEntry = op.searchFlowEntry(flowEntryId10);
+		assertEquals(flowEntry.getFlowEntryId(), flowEntryId10.toString());
+		flowEntry = op.searchFlowEntry(flowEntryId20);
+		assertEquals(flowEntry.getFlowEntryId(), flowEntryId20.toString());
 	}
 
 	/**
@@ -289,31 +554,43 @@
 	 */
 	@Test
 	public final void testGetAllFlowEntries() {
-		fail("Not yet implemented");
+		List<FlowEntryId> flowEntryIds = Arrays.asList(
+				new FlowEntryId(10), new FlowEntryId(20), new FlowEntryId(30)
+				);
+		
+		for (FlowEntryId flowEntryId: flowEntryIds)
+			op.newFlowEntry().setFlowEntryId(flowEntryId.toString());
+		op.commit();
+
+		List<String> actual_ids = new ArrayList<String>();
+		for (IFlowEntry flowEntry: op.getAllFlowEntries()) actual_ids.add(flowEntry.getFlowEntryId());
+		Collections.sort(actual_ids);
+
+		List<String> expected_ids = new ArrayList<String>();
+		for (FlowEntryId flowEntryId: flowEntryIds) expected_ids.add(flowEntryId.toString());
+		Collections.sort(expected_ids);
+		
+		assertArrayEquals(expected_ids.toArray(), actual_ids.toArray());
 	}
 
 	/**
-	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#getAllSwitchNotUpdatedFlowEntries(net.onrc.onos.util.GraphDBConnection)}.
+	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#removeFlowEntry(net.onrc.onos.util.GraphDBConnection, net.floodlightcontroller.core.INetMapTopologyObjects.IFlowEntry)}.
 	 */
 	@Test
-	public final void testGetAllSwitchNotUpdatedFlowEntries() {
-		fail("Not yet implemented");
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#getAllSwitches(net.onrc.onos.util.GraphDBConnection)}.
-	 */
-	@Test
-	public final void testGetAllSwitches() {
-		fail("Not yet implemented");
-	}
-
-	/**
-	 * Test method for {@link net.onrc.onos.util.GraphDBOperation#getInactiveSwitches(net.onrc.onos.util.GraphDBConnection)}.
-	 */
-	@Test
-	public final void testGetInactiveSwitches() {
-		fail("Not yet implemented");
+	public final void testRemoveFlowEntry() {
+		FlowEntryId flowEntryId10 = new FlowEntryId(10);
+		FlowEntryId flowEntryId20 = new FlowEntryId(20);
+		op.newFlowEntry().setFlowEntryId(flowEntryId10.toString());
+		op.newFlowEntry().setFlowEntryId(flowEntryId20.toString());
+		op.commit();
+		
+		IFlowEntry flowEntry = op.searchFlowEntry(flowEntryId10);
+		assertNotNull(flowEntry);
+		op.removeFlowEntry(flowEntry);
+		op.commit();
+		
+		assertNull(op.searchFlowEntry(flowEntryId10));
+		assertNotNull(op.searchFlowEntry(flowEntryId20));
 	}
 
 }