Fix for Bug ONOS-150:
Replace "dl_address" with "dl_addr" in the database schema
to fix a name mismatch.
diff --git a/src/main/java/net/onrc/onos/graph/GraphDBConnection.java b/src/main/java/net/onrc/onos/graph/GraphDBConnection.java
index 53235ab..a883c59 100644
--- a/src/main/java/net/onrc/onos/graph/GraphDBConnection.java
+++ b/src/main/java/net/onrc/onos/graph/GraphDBConnection.java
@@ -66,8 +66,8 @@
 			if (!s.contains("type")) {
 				graph.createKeyIndex("type", Vertex.class);
 			}
-			if (!s.contains("dl_address")) {
-				graph.createKeyIndex("dl_address", Vertex.class);
+			if (!s.contains("dl_addr")) {
+				graph.createKeyIndex("dl_addr", Vertex.class);
 			}
 			if (!s.contains("flow_id")) {
 				graph.createKeyIndex("flow_id", Vertex.class);
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..64cc9d4
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/routing/TopoRouteServiceTest.java
@@ -0,0 +1,175 @@
+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.Collection;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.tinkerpop.blueprints.Vertex;
+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 com.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine;
+
+
+/**
+ * A class for testing the TopoRouteService class.
+ * @see net.onrc.onos.ofcontroller.routing.TopoRouteService
+ * @author Pavlin Radoslavov (pavlin@onlab.us)
+ */
+public class TopoRouteServiceTest {
+
+	private TitanGraph titanGraph;
+	
+	@Before
+	public void setUp() throws Exception {
+		titanGraph = TestDatabaseManager.getTestDatabase();
+		TestDatabaseManager.populateTestData(titanGraph);
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		titanGraph.shutdown();
+	}
+
+	@Ignore @Test
+	public void testUpdate() {
+		fail("Not yet implemented");
+	}
+
+	static class MyLoopFunction implements PipeFunction<LoopBundle<Vertex>, Boolean> {
+	    String dpid;
+	    public MyLoopFunction(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;
+	    }
+	}
+
+	@Test
+	public void testShortestPath() {
+	    String dpid_src = "00:00:00:00:00:00:0a:01";
+	    String dpid_dest = "00:00:00:00:00:00:0a:06";
+
+	    //
+	    // Implement the Shortest Path between two vertices by using
+	    // the following Gremlin CLI code:
+	    //   v_src.as("x").out("on").out("link").in("on").dedup().loop("x"){it.object.dpid != v_dest.dpid}.path(){it.dpid}{it.number}{it.number}
+	    // The equivalent code used here is:
+	    //   results = []; v_src.as("x").out("on").out("link").in("on").dedup().loop("x"){it.object.dpid != v_dest.dpid}.path().fill(results)
+	    //
+
+	    // Get the source vertex
+	    Iterator<Vertex> iter = titanGraph.getVertices("dpid", dpid_src).iterator();
+	    if (! iter.hasNext())
+		return;			// Source vertex not found
+	    Vertex v_src = iter.next();
+
+	    // Get the destination vertex
+	    iter = titanGraph.getVertices("dpid", dpid_dest).iterator();
+	    if (! iter.hasNext())
+		return;			// Destination vertex not found
+	    Vertex v_dest = iter.next();
+
+	    //
+	    // Implement the Gremlin script and run it
+	    //
+	    // NOTE: This mechanism is slower. The code is kept here
+	    // for future reference.
+	    //
+	    /*
+	    String gremlin = "v_src.as(\"x\").out(\"on\").out(\"link\").in(\"on\").dedup().loop(\"x\"){it.object.dpid != v_dest.dpid}.path().fill(results)";
+
+	    String gremlin_nopath = "v_src.as(\"x\").out(\"on\").out(\"link\").in(\"on\").dedup().loop(\"x\"){it.object.dpid != \"NO-SUCH-DPID\"}.path().fill(results)";
+
+	    ScriptEngine engine = new GremlinGroovyScriptEngine();
+	    ArrayList<ArrayList<Vertex>> results = new ArrayList<ArrayList<Vertex>>();
+	    engine.getBindings(ScriptContext.ENGINE_SCOPE).put("g", titanGraph);
+	    engine.getBindings(ScriptContext.ENGINE_SCOPE).put("v_src", v_src);
+	    engine.getBindings(ScriptContext.ENGINE_SCOPE).put("v_dest", v_dest);
+	    engine.getBindings(ScriptContext.ENGINE_SCOPE).put("results", results);
+
+	    try {
+		engine.eval(gremlin);
+	    } catch (ScriptException e) {
+		System.err.println("Caught ScriptException running Gremlin script: " + e.getMessage());
+		return;
+	    }
+
+	    for (ArrayList<Vertex> lv : results) {
+		...
+	    }
+	    */
+
+	    MyLoopFunction whileFunction = new MyLoopFunction(dpid_dest);
+	    GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
+	    Collection<List> results = new ArrayList<List>();
+	    GremlinPipeline<Vertex, List> path;
+	    path = pipe.start(v_src).as("x").out("on").out("link").in("on").dedup().loop("x", whileFunction).path();
+	    path.fill(results);
+
+	    //
+	    // Extract the result and compose it into a string
+	    //
+	    String results_str = "";
+	    // System.out.println("BEGIN " + results.size());
+	    for (List l : results) {
+		for (Object o: l) {
+		    Vertex v = (Vertex)(o);
+		    // System.out.println(v);
+		    String type = v.getProperty("type").toString();
+		    results_str += "[type: " + type;
+		    // System.out.println("type: " + type);
+		    if (type.equals("port")) {
+			String number = v.getProperty("number").toString();
+			// System.out.println("number: " + number);
+			results_str += " number: " + number + "]";
+		    }
+		    if (type.equals("switch")) {
+			String dpid = v.getProperty("dpid").toString();
+			// System.out.println("dpid: " + dpid);
+			results_str += " dpid: " + dpid + "]";
+		    }
+		}
+	    }
+	    // System.out.println("END\n");
+	    System.out.println(results_str);
+
+	    //
+	    // Check the result
+	    //
+	    String expected_result = "[type: switch dpid: 00:00:00:00:00:00:0a:01][type: port number: 2][type: port number: 1][type: switch dpid: 00:00:00:00:00:00:0a:03][type: port number: 2][type: port number: 2][type: switch dpid: 00:00:00:00:00:00:0a:04][type: port number: 3][type: port number: 1][type: switch dpid: 00:00:00:00:00:00:0a:06]";
+
+	    assertEquals(results_str, expected_result);
+
+	    //
+	    // Test Shortest-Path computation to non-existing destination
+	    //
+	    results.clear();
+	    MyLoopFunction noDestWhileFunction = new MyLoopFunction("NO-SUCH-DPID");
+	    path = pipe.start(v_src).as("x").out("on").out("link").in("on").dedup().loop("x", noDestWhileFunction).path();
+	    path.fill(results);
+	    assertTrue(results.size() == 0);
+	}
+}