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

Conflicts:
	src/test/java/net/onrc/onos/ofcontroller/core/internal/TestDatabaseManager.java
diff --git a/cluster-mgmt/bin/func.sh b/cluster-mgmt/bin/func.sh
index fe65ab6..b42ead1 100755
--- a/cluster-mgmt/bin/func.sh
+++ b/cluster-mgmt/bin/func.sh
@@ -29,9 +29,11 @@
   case "$1" in
     start)
       echo "Starting ZK.."
-      dsh -g $basename "$ZK_DIR/bin/zkServer.sh start"
+#      dsh -g $basename "$ZK_DIR/bin/zkServer.sh start"
+      dsh -g $basename 'cd ONOS; ./start-zk.sh start'
       while [ 1 ]; do
-        nup=`dsh -g $basename "$ZK_DIR/bin/zkServer.sh status" | grep "Mode" | egrep "leader|follower" | wc -l`
+#        nup=`dsh -g $basename "$ZK_DIR/bin/zkServer.sh status" | grep "Mode" | egrep "leader|follower" | wc -l`
+        nup=`dsh -g $basename "cd ONOS; ./start-zk.sh status" | grep "Mode" | egrep "leader|follower|standalone" | wc -l`
         if [ $nup == $nr_nodes ]; then
           echo "everybody's up: $nup up of of $nr_nodes"
           echo "ZK started"
@@ -125,7 +127,9 @@
     start)
       if [ x$2 == "x" -o x$2 == "xall" ]; then
         echo "Starting ONOS on all nodes"
-        dsh -g ${basename} "cd $ONOS_DIR; ./start-onos.sh start"
+        dsh -w ${basename}1 "cd $ONOS_DIR; ./start-onos.sh start"
+        sleep 3
+        dsh -g ${basename} -x ${basename}1 "cd $ONOS_DIR; ./start-onos.sh start"
         dsh -g ${basename} "cd $ONOS_DIR; ./start-rest.sh start"
       else
         echo "Starting ONOS on ${basename}$2"
diff --git a/cluster-mgmt/bin/zk b/cluster-mgmt/bin/zk
index 262c936..b2033ad 100755
--- a/cluster-mgmt/bin/zk
+++ b/cluster-mgmt/bin/zk
@@ -1,5 +1,5 @@
 #! /bin/bash
-. ${HOME}/bin/func.sh
+. `dirname $0`/func.sh
 
 #$0 $1 $2
 `basename $0` $1 $2
diff --git a/src/main/java/net/onrc/onos/ofcontroller/routing/TopoRouteService.java b/src/main/java/net/onrc/onos/ofcontroller/routing/TopoRouteService.java
index 432e578..5328eae 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/routing/TopoRouteService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/routing/TopoRouteService.java
@@ -40,6 +40,10 @@
  * of shortest paths.
  */
 class Node {
+    /**
+     * A class for storing Link information for fast computation of shortest
+     * paths.
+     */
     class Link {
 	public Node me;			// The node this link originates from
 	public Node neighbor;		// The neighbor node on the other side
@@ -90,7 +94,9 @@
     }
 };
 
-
+/**
+ * A class for implementing Topology Route Service.
+ */
 public class TopoRouteService implements IFloodlightModule, ITopoRouteService {
 
     /** The logger. */
@@ -99,6 +105,11 @@
     
     protected GraphDBOperation op;
 
+    /**
+     * Get the collection of module services.
+     *
+     * @return the collection of services provided by this module.
+     */
     @Override
     public Collection<Class<? extends IFloodlightService>> getModuleServices() {
         Collection<Class<? extends IFloodlightService>> l = 
@@ -107,6 +118,11 @@
         return l;
     }
 
+    /**
+     * Get a map with the services provided by this module.
+     *
+     * @return a map with the services provided by this module.
+     */
     @Override
     public Map<Class<? extends IFloodlightService>, IFloodlightService> 
 			       getServiceImpls() {
@@ -118,6 +134,11 @@
         return m;
     }
 
+    /**
+     * Get the collection with the services this module depends on.
+     *
+     * @return the collection with the services this module depends on.
+     */
     @Override
     public Collection<Class<? extends IFloodlightService>> 
                                                     getModuleDependencies() {
@@ -128,6 +149,12 @@
         return l;
     }
 
+    /**
+     * Init the module.
+     *
+     * @param context the module context to use for the initialization.
+     * @see FloodlightModuleContext.
+     */
     @Override
     public void init(FloodlightModuleContext context)
 	throws FloodlightModuleException {
@@ -135,25 +162,22 @@
     	op = new GraphDBOperation("");
     }
 
+    /**
+     * Startup initialization.
+     */
     @Override
     public void startUp(FloodlightModuleContext context) {
 	// TODO: Add the approprate setup
     }
 
-
-    static class ShortestPathLoopFunction implements PipeFunction<LoopBundle<Vertex>, Boolean> {
-	String dpid;
-	public ShortestPathLoopFunction(String dpid) {
-	    super();
-	    this.dpid = dpid;
-	}
-	public Boolean compute(LoopBundle<Vertex> bundle) {
-	    Boolean output = false;
-	    if (! bundle.getObject().getProperty("dpid").equals(dpid)) {
-		output = true;
-	    }
-	    return output;
-	}
+    /**
+     * Set the database operation handler.
+     *
+     * @param init_op the database operation handler to use for the
+     * initialization.
+     */
+    public void setDbOperationHandler(GraphDBOperation init_op) {
+    	op = init_op;
     }
 
     /**
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestDatabaseManager.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestDatabaseManager.java
index 5371d6d..5b0a5b1 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestDatabaseManager.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestDatabaseManager.java
@@ -56,6 +56,7 @@
         
         //Change the type of all port numbers to short in the database
         Iterator<Vertex> it = titanGraph.getVertices("type", "port").iterator();
+
         while (it.hasNext()){
         	Vertex port = it.next();
 
@@ -83,4 +84,4 @@
 		}
 	}
 	
-}
\ No newline at end of file
+}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java b/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java
index 5add3cd..06e828d 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/flowmanager/FlowManagerTest.java
@@ -11,6 +11,7 @@
 import java.util.concurrent.TimeUnit;
 
 import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.restserver.IRestApiService;
@@ -25,8 +26,12 @@
 import org.easymock.IAnswer;
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.openflow.protocol.OFFlowMod;
+import org.openflow.protocol.OFType;
+import org.openflow.protocol.factory.BasicFactory;
 import org.powermock.core.classloader.annotations.PrepareForTest;
 import org.powermock.modules.junit4.PowerMockRunner;
 
@@ -83,13 +88,10 @@
 		expect(iFlowPath.getSrcPort()).andReturn(new Short((short)srcPort)).anyTimes();
 		expect(iFlowPath.getDstSwitch()).andReturn(new Dpid(dstDpid).toString()).anyTimes();
 		expect(iFlowPath.getDstPort()).andReturn(new Short((short)dstPort)).anyTimes();
-		expect(iFlowPath.getFlowEntries()).andReturn(new ArrayList<IFlowEntry>()).anyTimes();
 		return iFlowPath;
 	}
 	
-	private FlowPath createTestFlowPath(
-			long flowId,
-			String installerId,
+	private FlowPath createTestFlowPath(long flowId, String installerId,
 			final long srcDpid, final int srcPort,
 			final long dstDpid, final int dstPort			
 			) {
@@ -131,6 +133,7 @@
 		FlowId flowId = new FlowId(123);
 		FlowPath flowPath = new FlowPath();
 		flowPath.setFlowId(flowId);
+		FlowManager fm = new FlowManager();
 		
 		// setup expectations
 		expectInitWithContext();
@@ -140,9 +143,7 @@
 
 		// start the test
 		replayAll();
-//		replay(GraphDBOperation.class);
 
-		FlowManager fm = new FlowManager();
 		fm.init(context);
 		Boolean result = fm.addFlow(flowPath, flowId, "");
 
@@ -230,6 +231,7 @@
 		ArrayList<IFlowPath> flowPaths = new ArrayList<IFlowPath>();
 		flowPaths.add(flowPath1);
 		flowPaths.add(flowPath2);
+		FlowManager fm = new FlowManager();
 		
 		// setup expectations
 		expectInitWithContext();
@@ -251,7 +253,6 @@
 		// start the test
 		replayAll();
 		
-		FlowManager fm = new FlowManager();
 		fm.init(context);
 		Boolean result = fm.deleteAllFlows();
 
@@ -266,6 +267,9 @@
 	 */
 	@Test
 	public final void testDeleteFlowSuccessEmptyFlowPath() throws Exception {
+		// instantiate required objects
+		FlowManager fm = new FlowManager();
+		
 		// create mock objects
 		IFlowPath flowObj = createNiceMock(IFlowPath.class);
 
@@ -280,7 +284,6 @@
 		// start the test
 		replayAll();
 		
-		FlowManager fm = new FlowManager();
 		fm.init(context);
 		Boolean result = fm.deleteFlow(new FlowId(1));
 		
@@ -336,11 +339,12 @@
 	public final void testGetFlowSuccessNormally() throws Exception {
 		// instantiate required objects
 		FlowManager fm = new FlowManager();
+		IFlowPath iFlowPath = createIFlowPathMock(1, "caller id", 1, 1, 2, 2); 
 
 		// setup expectations
 		expectInitWithContext();
-		expect(op.searchFlowPath(cmpEq(new FlowId(1)))).andReturn(
-				createIFlowPathMock(1, "caller id", 1, 1, 2, 2));
+		expect(op.searchFlowPath(cmpEq(new FlowId(1)))).andReturn(iFlowPath);
+		expect(iFlowPath.getFlowEntries()).andReturn(new ArrayList<IFlowEntry>()).anyTimes();
 		op.commit();
 		
 		// start the test
@@ -467,15 +471,21 @@
 	 */
 	@Test
 	public final void testGetAllFlowsSuccessNormally() throws Exception {
+		// create mock objects
+		IFlowPath iFlowPath1 = createIFlowPathMock(1, "caller id", 1, 1, 2, 2); 
+		IFlowPath iFlowPath2 = createIFlowPathMock(2, "caller id", 2, 5, 3, 5);
+		
 		// instantiate required objects
 		ArrayList<IFlowPath> flowPaths = new ArrayList<IFlowPath>();
-		flowPaths.add(createIFlowPathMock(1, "caller id", 1, 1, 2, 2));
-		flowPaths.add(createIFlowPathMock(1, "caller id", 2, 5, 3, 5));
+		flowPaths.add(iFlowPath1);
+		flowPaths.add(iFlowPath2);
 		FlowManager fm = new FlowManager();
 
 		// setup expectations
 		expectInitWithContext();
 		expect(op.getAllFlowPaths()).andReturn(flowPaths);
+		expect(iFlowPath1.getFlowEntries()).andReturn(new ArrayList<IFlowEntry>()).anyTimes();
+		expect(iFlowPath2.getFlowEntries()).andReturn(new ArrayList<IFlowEntry>()).anyTimes();
 		op.commit();
 		
 		// start the test
@@ -749,6 +759,7 @@
 		// instantiate required objects
 		FlowPath paramFlow = createTestFlowPath(100, "installer id", 1, 3, 2, 4);
 		Map<Long, Object> shortestPathMap = new HashMap<Long, Object>();
+		FlowManager fm = new FlowManager();
 
 		// setup expectations
 		expectInitWithContext();
@@ -763,7 +774,6 @@
 		// start the test
 		replayAll();
 		
-		FlowManager fm = new FlowManager();
 		fm.init(context);
 		fm.measurementStorePathFlow(paramFlow);
 		Boolean result = fm.measurementClearAllPaths();
@@ -785,6 +795,9 @@
 	 */
 	@Test
 	public final void testInitSuccessNormally() throws Exception {
+		// instantiate required objects
+		FlowManager fm = new FlowManager();
+
 		// create mock objects
 		op = createMock(GraphDBOperation.class);
 
@@ -794,7 +807,6 @@
 		// start the test
 		replayAll();
 		
-		FlowManager fm = new FlowManager();
 		fm.init("/dummy/path");
 		
 		// verify the test
@@ -934,7 +946,6 @@
 		mockStaticPartial(Executors.class, "newScheduledThreadPool");
 		ScheduledExecutorService scheduler = createMock(ScheduledExecutorService.class);
 
-
 		// instantiate required objects
 		FlowManager fm = new FlowManager();
 		
@@ -958,4 +969,233 @@
 		// verify the test
 		verifyAll();
 	}
+	
+	
+	// other methods
+	
+	
+	/**
+	 * Test method for {@link FlowManager#clearFlow(FlowId)}.
+	 * @throws Exception
+	 */
+	@Test
+	public final void testClearFlowSuccessNormally() throws Exception {
+		// create mock objects
+		IFlowPath flowPath = createIFlowPathMock(123, "id", 1, 2, 3, 4);
+		IFlowEntry flowEntry1 = createMock(IFlowEntry.class);
+		IFlowEntry flowEntry2 = createMock(IFlowEntry.class);
+		IFlowEntry flowEntry3 = createMock(IFlowEntry.class);
+		
+		// instantiate required objects
+		FlowManager fm = new FlowManager();
+		FlowId flowId = new FlowId(123);
+		ArrayList<IFlowEntry> flowEntries = new ArrayList<IFlowEntry>();
+		flowEntries.add(flowEntry1);
+		flowEntries.add(flowEntry2);
+		flowEntries.add(flowEntry3);
+
+		// setup expectations
+		expectInitWithContext();
+		expect(op.searchFlowPath(cmpEq(flowId))).andReturn(flowPath);
+		expect(flowPath.getFlowEntries()).andReturn(flowEntries);
+		flowPath.removeFlowEntry(flowEntry1);
+		flowPath.removeFlowEntry(flowEntry2);
+		flowPath.removeFlowEntry(flowEntry3);
+		op.removeFlowEntry(flowEntry1);
+		op.removeFlowEntry(flowEntry2);
+		op.removeFlowEntry(flowEntry3);
+		op.removeFlowPath(flowPath);
+		op.commit();
+
+		// start the test
+		replayAll();
+		
+		fm.init(context);
+		fm.clearFlow(flowId);
+
+		// verify the test
+		verifyAll();
+	}
+	
+	/**
+	 * Test method for {@link FlowManager#getAllFlowsWithoutFlowEntries()}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testGetAllFlowsWithoutFlowEntriesSuccessNormally() throws Exception {
+		// create mock objects
+		IFlowPath iFlowPath1 = createIFlowPathMock(1, "caller id", 1, 1, 2, 2); 
+		IFlowPath iFlowPath2 = createIFlowPathMock(2, "caller id", 2, 5, 3, 5);
+		
+		// instantiate required objects
+		ArrayList<IFlowPath> flowPaths = new ArrayList<IFlowPath>();
+		flowPaths.add(iFlowPath1);
+		flowPaths.add(iFlowPath2);
+		FlowManager fm = new FlowManager();
+		
+		// setup expectations
+		expectInitWithContext();
+		op.commit();
+		expect(op.getAllFlowPaths()).andReturn(flowPaths);
+		
+		// start the test
+		replayAll();
+		
+		fm.init(context);
+		ArrayList<IFlowPath> result = fm.getAllFlowsWithoutFlowEntries();
+		
+		// verify the test
+		verifyAll();
+		assertEquals(iFlowPath1, result.get(0));
+		assertEquals(iFlowPath2, result.get(1));
+		
+		// TODO: does this method just return the replica of the flow paths?
+	}
+	
+	/**
+	 * Test method for {@link FlowManager#reconcileFlow(IFlowPath, DataPath)}.
+	 * @throws Exception
+	 */
+	@Test
+	public final void testReconcileFlowWithFlowPathAndDataPathSuccessNormally() throws Exception {
+		final String addFlowEntry = "addFlowEntry";
+		
+		// create mock objects
+		IFlowPath iFlowPath1 = createIFlowPathMock(1, "caller id", 1, 1, 2, 2);
+		IFlowEntry iFlowEntry1 = createMock(IFlowEntry.class);
+		IFlowEntry iFlowEntry2 = createMock(IFlowEntry.class);
+		FlowManager fm = createPartialMockAndInvokeDefaultConstructor(FlowManager.class, addFlowEntry);
+		
+		// instantiate required objects
+		FlowEntry flowEntry1 = new FlowEntry();
+		flowEntry1.setDpid(new Dpid(1));
+		flowEntry1.setFlowId(new FlowId(1));
+		flowEntry1.setInPort(new Port((short) 1));
+		flowEntry1.setOutPort(new Port((short) 11));
+		flowEntry1.setFlowEntryId(new FlowEntryId(1));
+		flowEntry1.setFlowEntryMatch(new FlowEntryMatch());
+		flowEntry1.setFlowEntryActions(new ArrayList<FlowEntryAction>());
+		flowEntry1.setFlowEntryErrorState(new FlowEntryErrorState());
+		
+		FlowEntry flowEntry2 = new FlowEntry();
+		flowEntry2.setDpid(new Dpid(2));
+		flowEntry2.setFlowId(new FlowId(2));
+		flowEntry2.setInPort(new Port((short) 22)); 
+		flowEntry2.setOutPort(new Port((short) 2));
+		flowEntry2.setFlowEntryId(new FlowEntryId(2));
+		flowEntry2.setFlowEntryMatch(new FlowEntryMatch());
+		flowEntry2.setFlowEntryActions(new ArrayList<FlowEntryAction>());
+		flowEntry2.setFlowEntryErrorState(new FlowEntryErrorState());
+		
+		DataPath dataPath = new DataPath();
+		ArrayList<FlowEntry> flowEntries = new ArrayList<FlowEntry>();
+		flowEntries.add(flowEntry1);
+		flowEntries.add(flowEntry2);
+		dataPath.setFlowEntries(flowEntries);
+		
+		ArrayList<IFlowEntry> oldFlowEntries = new ArrayList<IFlowEntry>();
+		oldFlowEntries.add(iFlowEntry1);
+		oldFlowEntries.add(iFlowEntry2);
+
+		// setup expectations
+		expectInitWithContext();
+		expect(floodlightProvider.getSwitches()).andReturn(null); // TODO: why is this needed?
+		expect(iFlowPath1.getFlowEntries()).andReturn(oldFlowEntries);
+		iFlowEntry1.setUserState("FE_USER_DELETE");
+		iFlowEntry1.setSwitchState("FE_SWITCH_NOT_UPDATED");
+		iFlowEntry2.setUserState("FE_USER_DELETE");
+		iFlowEntry2.setSwitchState("FE_SWITCH_NOT_UPDATED");
+		expectPrivate(fm, addFlowEntry, iFlowPath1, flowEntry1).andReturn(null);
+		expectPrivate(fm, addFlowEntry, iFlowPath1, flowEntry2).andReturn(null);
+
+		// start the test
+		replayAll();
+		
+		fm.init(context);
+		Boolean result = fm.reconcileFlow(iFlowPath1, dataPath);
+		
+		// verify the test
+		verifyAll();
+		assertTrue(result);
+		// TODO: write more asserts
+	}
+	
+	/**
+	 * Test method for {@link FlowManager#installFlowEntry(net.floodlightcontroller.core.IOFSwitch, IFlowPath, IFlowEntry)}.
+	 * @throws Exception 
+	 */
+	@Test
+	public final void testInstallFlowEntryWithIFlowPathSuccessNormally() throws Exception {
+		// create mock object
+		IOFSwitch iofSwitch = createNiceMock(IOFSwitch.class);
+		IFlowPath iFlowPath = createIFlowPathMock(1, "id", 1, 2, 3, 4); 
+		IFlowEntry iFlowEntry = createMock(IFlowEntry.class);
+		BasicFactory basicFactory = createMock(BasicFactory.class);
+		
+		// instantiate required objects
+		FlowManager fm = new FlowManager();
+		
+		// setup expectations
+		expectInitWithContext();
+		expect(iFlowEntry.getFlowEntryId()).andReturn(new FlowEntryId(123).toString());
+		expect(iFlowEntry.getUserState()).andReturn("FE_USER_ADD");
+		iFlowEntry.setSwitchState("FE_SWITCH_UPDATED");
+		expect(iFlowEntry.getMatchInPort()).andReturn(new Short((short) 1));
+		expect(iFlowEntry.getMatchEthernetFrameType()).andReturn(new Short((short)0x0800));
+		expect(iFlowEntry.getMatchSrcIPv4Net()).andReturn("192.168.0.1");
+		expect(iFlowEntry.getMatchDstIPv4Net()).andReturn("192.168.0.2");
+		expect(iFlowEntry.getMatchSrcMac()).andReturn("01:23:45:67:89:01");
+		expect(iFlowEntry.getMatchDstMac()).andReturn("01:23:45:67:89:02");
+		expect(iFlowEntry.getActionOutput()).andReturn(new Short((short) 2));
+		expect(floodlightProvider.getOFMessageFactory()).andReturn(basicFactory);
+		expect(basicFactory.getMessage(OFType.FLOW_MOD)).andReturn(new OFFlowMod());
+		expect(iofSwitch.getStringId()).andReturn(new Dpid(100).toString());
+
+		// start the test
+		replayAll();
+		
+		fm.init(context);
+		Boolean result = fm.installFlowEntry(iofSwitch, iFlowPath, iFlowEntry);
+		
+		// verify the test
+		verifyAll();
+		assertTrue(result);
+		// TODO: write more asserts
+	}
+
+	/**
+	 * Test method for {@link FlowManager#installFlowEntry(net.floodlightcontroller.core.IOFSwitch, FlowPath, FlowEntry)}.
+	 * The method seems to be not used for now.
+	 */
+	@Ignore @Test
+	public final void testInstallFlowEntryWithFlowPathSuccessNormally() {
+		fail("not yet implemented");
+	}
+
+	/**
+	 * Test method for {@link FlowManager#removeFlowEntry(net.floodlightcontroller.core.IOFSwitch, FlowPath, FlowEntry)}.
+	 * The method seems to be not implemented and not used for now.
+	 */
+	@Ignore @Test
+	public final void testRemoveFlowEntrySuccessNormally() {
+		fail("not yet implemented");
+	}
+
+	/**
+	 * Test method for {@link FlowManager#installRemoteFlowEntry(FlowPath, FlowEntry)}.
+	 * The method seems to be not implemented and not used for now.
+	 */
+	@Ignore @Test
+	public final void testInstallRemoteFlowEntrySuccessNormally() {
+		fail("not yet implemented");
+	}
+
+	/**
+	 * Test method for {@link FlowManager#removeRemoteFlowEntry(FlowPath, FlowEntry)}.
+	 * The method seems to be not implemented and not used for now.
+	 */
+	@Ignore @Test
+	public final void testRemoveRemoteFlowEntrySuccessNormally() {
+		fail("not yet implemented");
+	}
 }
\ No newline at end of file
diff --git a/src/test/java/net/onrc/onos/ofcontroller/routing/TopoRouteServiceTest.java b/src/test/java/net/onrc/onos/ofcontroller/routing/TopoRouteServiceTest.java
new file mode 100644
index 0000000..e6d7d16
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/routing/TopoRouteServiceTest.java
@@ -0,0 +1,234 @@
+package net.onrc.onos.ofcontroller.routing;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.easymock.EasyMock;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.thinkaurelius.titan.core.TitanFactory;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine;
+import com.tinkerpop.gremlin.java.GremlinPipeline;
+import com.tinkerpop.pipes.PipeFunction;
+import com.tinkerpop.pipes.branch.LoopPipe.LoopBundle;
+
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+
+import net.onrc.onos.graph.GraphDBConnection;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.internal.TestDatabaseManager;
+import net.onrc.onos.ofcontroller.routing.TopoRouteService;
+import net.onrc.onos.ofcontroller.util.DataPath;
+import net.onrc.onos.ofcontroller.util.Dpid;
+import net.onrc.onos.ofcontroller.util.Port;
+import net.onrc.onos.ofcontroller.util.SwitchPort;
+
+/**
+ * A class for testing the TopoRouteService class.
+ * @see net.onrc.onos.ofcontroller.routing.TopoRouteService
+ * @author Pavlin Radoslavov (pavlin@onlab.us)
+ */
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, TopoRouteService.class})
+public class TopoRouteServiceTest {
+    String conf;
+    private GraphDBConnection conn = null;
+    private GraphDBOperation oper = null;
+    private TitanGraph titanGraph = null;
+    private TopoRouteService topoRouteService = null;
+
+    /**
+     * Setup the tests.
+     */
+    @Before
+    public void setUp() throws Exception {
+	conf = "/dummy/path/to/db";
+
+	//
+	// Make mock database.
+	// Replace TitanFactory.open() to return the mock database.
+	//
+	titanGraph = TestDatabaseManager.getTestDatabase();
+	PowerMock.mockStatic(TitanFactory.class);
+	EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
+	PowerMock.replay(TitanFactory.class);
+
+	// Create the connection to the database
+	conn = GraphDBConnection.getInstance(conf);
+	oper = new GraphDBOperation(conn);
+
+	// Populate the database
+	TestDatabaseManager.populateTestData(titanGraph);
+
+	// Prepare the TopoRouteService instance
+	topoRouteService = new TopoRouteService();
+	topoRouteService.setDbOperationHandler(oper);
+    }
+
+    /**
+     * Cleanup after the tests.
+     */
+    @After
+    public void tearDown() throws Exception {
+	titanGraph.shutdown();
+	TestDatabaseManager.deleteTestDatabase();
+    }
+
+    /**
+     * Test method TopoRouteService.getTopoShortestPath()
+     *
+     * @see net.onrc.onos.ofcontroller.routing.TopoRouteService#getTopoShortestPath
+     */
+    @Test
+    public void test_getTopoShortestPath() {
+	DataPath dataPath = null;
+	String srcDpidStr = "00:00:00:00:00:00:0a:01";
+	String dstDpidStr = "00:00:00:00:00:00:0a:06";
+	short srcPortShort = 1;
+	short dstPortShort = 1;
+
+	//
+	// Initialize the source and destination points
+	//
+	Dpid srcDpid = new Dpid(srcDpidStr);
+	Port srcPort = new Port(srcPortShort);
+	Dpid dstDpid = new Dpid(dstDpidStr);
+	Port dstPort = new Port(dstPortShort);
+	SwitchPort srcSwitchPort = new SwitchPort(srcDpid, srcPort);
+	SwitchPort dstSwitchPort = new SwitchPort(dstDpid, dstPort);
+
+	//
+	// Test a valid Shortest-Path computation
+	//
+	Map<Long, ?> shortestPathTopo =
+	    topoRouteService.prepareShortestPathTopo();
+	dataPath = topoRouteService.getTopoShortestPath(shortestPathTopo,
+							srcSwitchPort,
+							dstSwitchPort);
+	assertTrue(dataPath != null);
+	String dataPathSummaryStr = dataPath.dataPathSummary();
+	// System.out.println(dataPathSummaryStr);
+	String expectedResult = "1/00:00:00:00:00:00:0a:01/2;1/00:00:00:00:00:00:0a:03/2;2/00:00:00:00:00:00:0a:04/3;1/00:00:00:00:00:00:0a:06/1;";
+	assertEquals(dataPathSummaryStr, expectedResult);
+
+	//
+	// Test Shortest-Path computation to non-existing destination
+	//
+	String noSuchDpidStr = "ff:ff:00:00:00:00:0a:06";
+	Dpid noSuchDstDpid = new Dpid(noSuchDpidStr);
+	SwitchPort noSuchDstSwitchPort = new SwitchPort(noSuchDstDpid, dstPort);
+	dataPath = topoRouteService.getTopoShortestPath(shortestPathTopo,
+							srcSwitchPort,
+							noSuchDstSwitchPort);
+	assertTrue(dataPath == null);
+
+	topoRouteService.dropShortestPathTopo(shortestPathTopo);
+    }
+
+    /**
+     * Test method TopoRouteService.getShortestPath()
+     *
+     * @see net.onrc.onos.ofcontroller.routing.TopoRouteService#getShortestPath
+     */
+    @Test
+    public void test_getShortestPath() {
+	DataPath dataPath = null;
+	String srcDpidStr = "00:00:00:00:00:00:0a:01";
+	String dstDpidStr = "00:00:00:00:00:00:0a:06";
+	short srcPortShort = 1;
+	short dstPortShort = 1;
+
+	//
+	// Initialize the source and destination points
+	//
+	Dpid srcDpid = new Dpid(srcDpidStr);
+	Port srcPort = new Port(srcPortShort);
+	Dpid dstDpid = new Dpid(dstDpidStr);
+	Port dstPort = new Port(dstPortShort);
+	SwitchPort srcSwitchPort = new SwitchPort(srcDpid, srcPort);
+	SwitchPort dstSwitchPort = new SwitchPort(dstDpid, dstPort);
+
+	//
+	// Test a valid Shortest-Path computation
+	//
+	dataPath = topoRouteService.getShortestPath(srcSwitchPort,
+						dstSwitchPort);
+	assertTrue(dataPath != null);
+	String dataPathSummaryStr = dataPath.dataPathSummary();
+	// System.out.println(dataPathSummaryStr);
+	String expectedResult = "1/00:00:00:00:00:00:0a:01/2;1/00:00:00:00:00:00:0a:03/2;2/00:00:00:00:00:00:0a:04/3;1/00:00:00:00:00:00:0a:06/1;";
+	assertEquals(dataPathSummaryStr, expectedResult);
+
+	//
+	// Test Shortest-Path computation to non-existing destination
+	//
+	String noSuchDpidStr = "ff:ff:00:00:00:00:0a:06";
+	Dpid noSuchDstDpid = new Dpid(noSuchDpidStr);
+	SwitchPort noSuchDstSwitchPort = new SwitchPort(noSuchDstDpid, dstPort);
+
+	dataPath = topoRouteService.getShortestPath(srcSwitchPort,
+						    noSuchDstSwitchPort);
+	assertTrue(dataPath == null);
+    }
+
+    /**
+     * Test method TopoRouteService.routeExists()
+     *
+     * @see net.onrc.onos.ofcontroller.routing.TopoRouteService#routeExists
+     */
+    @Test
+    public void test_routeExists() {
+	Boolean result;
+	String srcDpidStr = "00:00:00:00:00:00:0a:01";
+	String dstDpidStr = "00:00:00:00:00:00:0a:06";
+	short srcPortShort = 1;
+	short dstPortShort = 1;
+
+	//
+	// Initialize the source and destination points
+	//
+	Dpid srcDpid = new Dpid(srcDpidStr);
+	Port srcPort = new Port(srcPortShort);
+	Dpid dstDpid = new Dpid(dstDpidStr);
+	Port dstPort = new Port(dstPortShort);
+	SwitchPort srcSwitchPort = new SwitchPort(srcDpid, srcPort);
+	SwitchPort dstSwitchPort = new SwitchPort(dstDpid, dstPort);
+
+	//
+	// Test a valid route
+	//
+	result = topoRouteService.routeExists(srcSwitchPort, dstSwitchPort);
+	assertTrue(result == true);
+
+	//
+	// Test a non-existing route
+	//
+	String noSuchDpidStr = "ff:ff:00:00:00:00:0a:06";
+	Dpid noSuchDstDpid = new Dpid(noSuchDpidStr);
+	SwitchPort noSuchDstSwitchPort = new SwitchPort(noSuchDstDpid, dstPort);
+	result = topoRouteService.routeExists(srcSwitchPort,
+					      noSuchDstSwitchPort);
+	assertTrue(result != true);
+    }
+}
diff --git a/start-cassandra.sh b/start-cassandra.sh
index d4d722c..426fa60 100755
--- a/start-cassandra.sh
+++ b/start-cassandra.sh
@@ -3,8 +3,8 @@
 # Set paths
 ONOS_HOME=`dirname $0`
 CASSANDRA_DIR=${HOME}/apache-cassandra-1.2.4
-LOGDIR=${HOME}/ONOS/onos-logs
-CASSANDRA_LOG=$LOGDIR/cassandara.`hostname`.log
+LOGDIR=${ONOS_HOME}/ONOS/onos-logs
+CASSANDRA_LOG=${LOGDIR}/cassandara.`hostname`.log
 
 function lotate {
     logfile=$1
@@ -30,10 +30,11 @@
 
   # Run cassandra 
   echo "Starting cassandra"
-  echo "[WARNING] This script copies conf/cassandra.yam to $CASSANDRA_DIR/conf/cassandra.yaml (overwrites)"
-  echo "original cassandra.yaml was backed up as cassandra.yaml.backup"
-  cp $CASSANDRA_DIR/conf/cassandra.yaml $CASSANDRA_DIR/conf/cassandra.yaml.backup
-  cp ${ONOS_HOME}/conf/cassandra.yaml $CASSANDRA_DIR/conf
+#  echo "[WARNING] This script copies conf/cassandra.yaml to $CASSANDRA_DIR/conf/cassandra.yaml (overwrites)"
+#  echo "original cassandra.yaml was backed up as cassandra.yaml.backup"
+#  id=`hostid`
+#  cp ${CASSANDRA_DIR}/conf/cassandra.yaml $CASSANDRA_DIR/conf/cassandra.yaml.backup
+#  cp ${ONOS_HOME}/conf/cassandra.yaml.${id} $CASSANDRA_DIR/conf
   $CASSANDRA_DIR/bin/cassandra > $CASSANDRA_LOG 2>&1 
 }
 
diff --git a/start-onos-embedded.sh b/start-onos-embedded.sh
index 5da4d9b..dac0331 100755
--- a/start-onos-embedded.sh
+++ b/start-onos-embedded.sh
@@ -14,9 +14,14 @@
 JVM_OPTS=""
 JVM_OPTS="$JVM_OPTS -server -d64"
 JVM_OPTS="$JVM_OPTS -Xmx2g -Xms2g -Xmn800m"
-JVM_OPTS="$JVM_OPTS -XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
+#JVM_OPTS="$JVM_OPTS -XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
+JVM_OPTS="$JVM_OPTS -XX:+UseConcMarkSweepGC -XX:+UseAdaptiveSizePolicy -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
 JVM_OPTS="$JVM_OPTS -XX:MaxInlineSize=8192 -XX:FreqInlineSize=8192"
 JVM_OPTS="$JVM_OPTS -XX:CompileThreshold=1500 -XX:PreBlockSpin=8 \
+		-XX:+UseThreadPriorities \
+		-XX:ThreadPriorityPolicy=42 \
+                 -XX:+UseCompressedOops \
+		-Dcassandra.compaction.priority=1 \
             -Dcom.sun.management.jmxremote.port=7199 \
               -Dcom.sun.management.jmxremote.ssl=false \
               -Dcom.sun.management.jmxremote.authenticate=false"
diff --git a/start-onos.sh b/start-onos.sh
index 667fd31..c356c87 100755
--- a/start-onos.sh
+++ b/start-onos.sh
@@ -4,6 +4,7 @@
 if [ -z "${ONOS_HOME}" ]; then
         ONOS_HOME=`dirname $0`
 fi
+
 ONOS_LOGBACK="${ONOS_HOME}/logback.xml"
 LOGDIR=${ONOS_HOME}/onos-logs
 ONOS_LOG="${LOGDIR}/onos.`hostname`.log"
@@ -16,17 +17,24 @@
 #JVM_OPTS="$JVM_OPTS -Xmx2g -Xms2g -Xmn800m"
 JVM_OPTS="$JVM_OPTS -Xmx1g -Xms1g -Xmn800m"
 #JVM_OPTS="$JVM_OPTS -XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
-JVM_OPTS="$JVM_OPTS -XX:+UseConcMarkSweepGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
+JVM_OPTS="$JVM_OPTS -XX:+UseConcMarkSweepGC -XX:+UseAdaptiveSizePolicy -XX:+AggressiveOpts -XX:+UseFastAccessorMethods"
 JVM_OPTS="$JVM_OPTS -XX:MaxInlineSize=8192 -XX:FreqInlineSize=8192"
 JVM_OPTS="$JVM_OPTS -XX:CompileThreshold=1500 -XX:PreBlockSpin=8"
 JVM_OPTS="$JVM_OPTS -XX:OnError=crash-logger" ;# For dumping core
 #JVM_OPTS="$JVM_OPTS -Dpython.security.respectJavaAccessibility=false"
+JVM_OPTS="$JVM_OPTS -XX:CompileThreshold=1500 -XX:PreBlockSpin=8 \
+		-XX:+UseThreadPriorities \
+		-XX:ThreadPriorityPolicy=42 \
+                 -XX:+UseCompressedOops \
+            -Dcom.sun.management.jmxremote.port=7189 \
+              -Dcom.sun.management.jmxremote.ssl=false \
+              -Dcom.sun.management.jmxremote.authenticate=false"
 
 # Set ONOS core main class
 MAIN_CLASS="net.onrc.onos.ofcontroller.core.Main"
 
 if [ -z "${MVN}" ]; then
-    MVN="mvn"
+    MVN="mvn -o"
 fi
 
 #<logger name="net.floodlightcontroller.linkdiscovery.internal" level="TRACE"/>
@@ -89,7 +97,8 @@
 
   # XXX : MVN has to run at the project top dir 
   cd ${ONOS_HOME}
-  ${MVN} exec:exec -Dexec.executable="java" -Dexec.args="${JVM_OPTS} -Dlogback.configurationFile=${ONOS_LOGBACK} -cp %classpath ${MAIN_CLASS} -cf ${ONOS_HOME}/conf/onos.properties" > ${LOGDIR}/onos.stdout 2>${LOGDIR}/onos.stderr &
+  echo "${MVN} exec:exec -Dexec.executable=\"java\" -Dexec.args=\"${JVM_OPTS} -Dlogback.configurationFile=${ONOS_LOGBACK} -cp %classpath ${MAIN_CLASS} -cf ${ONOS_HOME}/conf/onos.properties\""
+  ${MVN} exec:exec -Dexec.executable="java" -Dexec.args="${JVM_OPTS} -Dlogback.configurationFile=${ONOS_LOGBACK} -cp %classpath ${MAIN_CLASS} -cf ${ONOS_HOME}/conf/onos.properties" > ${LOGDIR}/onos.`hostname`.stdout 2>${LOGDIR}/onos.`hostname`.stderr &
 
   echo "Waiting for ONOS to start..."
   COUNT=0
@@ -117,7 +126,7 @@
   for p in ${pids}; do
     if [ x$p != "x" ]; then
       kill -KILL $p
-      echo "Killed existing prosess (pid: $p)"
+      echo "Killed existing process (pid: $p)"
     fi
   done
 }
diff --git a/start-zk.sh b/start-zk.sh
index 206370f..0853a96 100755
--- a/start-zk.sh
+++ b/start-zk.sh
@@ -3,18 +3,19 @@
 
 ONOS_HOME=`dirname $0`
 ZK_DIR=${HOME}/zookeeper-3.4.5
-ZK_CONF=${ONOS_HOME}/conf/zoo.cfg
+#ZK_CONF=${ONOS_HOME}/conf/zoo.cfg
 
 function start {
   # Run Zookeeper with our configuration
   echo "Starting Zookeeper"
-  echo "[WARNING] This script copies conf/zoo.cfg to $ZK_DIR/conf/zoo.cfg (overwrites)"
-  echo "original zoo.cfg was backed up as zoo.cfg.backup"
-  if [ $ZK_DIR/conf/zoo.cfg ]; then
-    cp $ZK_DIR/conf/zoo.cfg $ZK_DIR/conf/zoo.cfg.backup
-  fi
-  cp $ZK_CONF $ZK_DIR/conf
-  echo "cp $ZK_CONF $ZK_DIR/conf"
+#  echo "[WARNING] This script copies conf/zoo.cfg to $ZK_DIR/conf/zoo.cfg (overwrites)"
+#  echo "original zoo.cfg was backed up as zoo.cfg.backup"
+#  if [ $ZK_DIR/conf/zoo.cfg ]; then
+#    cp $ZK_DIR/conf/zoo.cfg $ZK_DIR/conf/zoo.cfg.backup
+#  fi
+#  hostid > /var/lib/zookeeper/myid
+#  cp $ZK_CONF $ZK_DIR/conf
+#  echo "cp $ZK_CONF $ZK_DIR/conf"
   $ZK_DIR/bin/zkServer.sh start
 }
 
@@ -29,7 +30,7 @@
   done
 }
 function status {
-  $ZK_DIR/bin/zkServer.sh status $ZK_CONF
+  $ZK_DIR/bin/zkServer.sh status
 }
 
 case "$1" in
diff --git a/titan/schema/test-network.xml b/titan/schema/test-network.xml
index 5c63d90..630c5da 100644
--- a/titan/schema/test-network.xml
+++ b/titan/schema/test-network.xml
@@ -3,6 +3,7 @@
 
     <key id="id" for="node" attr.name="id" attr.type="string"></key>
     <key id="type" for="node" attr.name="type" attr.type="string"></key>
+    <key id="state" for="node" attr.name="state" attr.type="string"></key>
     <key id="dpid" for="node" attr.name="dpid" attr.type="string"></key>
     <key id="desc" for="node" attr.name="desc" attr.type="string"></key>
     <key id="number" for="node" attr.name="number" attr.type="int"></key>
@@ -17,31 +18,37 @@
         <node id="1">
             <data key="type">switch</data>
             <data key="dpid">00:00:00:00:00:00:0a:01</data>
+            <data key="state">ACTIVE</data>
             <data key="desc">OpenFlow Switch at SEA</data>
         </node>
         <node id="2">
             <data key="type">switch</data>
             <data key="dpid">00:00:00:00:00:00:0a:02</data>
+            <data key="state">ACTIVE</data>
             <data key="desc">OpenFlow Switch at LAX</data>
         </node>
         <node id="3">
             <data key="type">switch</data>
             <data key="dpid">00:00:00:00:00:00:0a:03</data>
+            <data key="state">ACTIVE</data>
             <data key="desc">OpenFlow Switch at CHI</data>
         </node>
         <node id="4">
             <data key="type">switch</data>
             <data key="dpid">00:00:00:00:00:00:0a:04</data>
+            <data key="state">ACTIVE</data>
             <data key="desc">OpenFlow Switch at IAH</data>
         </node>
         <node id="5">
             <data key="type">switch</data>
             <data key="dpid">00:00:00:00:00:00:0a:05</data>
+            <data key="state">ACTIVE</data>
             <data key="desc">OpenFlow Switch at NYC</data>
         </node>
         <node id="6">
             <data key="type">switch</data>
             <data key="dpid">00:00:00:00:00:00:0a:06</data>
+            <data key="state">ACTIVE</data>
             <data key="desc">OpenFlow Switch at ATL</data>
         </node>