Added initial implementation of the Titan + Gremlin based shortest-path
computation. It replaces the existing Floodlight backend, and
can be used with the existing REST-based API.

Added a test Python-script which is just a wrapper for
the "curl" call.
diff --git a/src/main/java/net/floodlightcontroller/routing/TopoRouteService.java b/src/main/java/net/floodlightcontroller/routing/TopoRouteService.java
new file mode 100644
index 0000000..be78494
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/routing/TopoRouteService.java
@@ -0,0 +1,150 @@
+package net.floodlightcontroller.routing;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import net.floodlightcontroller.core.internal.SwitchStorageImpl;
+import net.floodlightcontroller.core.INetMapTopologyService.ITopoRouteService;
+import net.floodlightcontroller.topology.NodePortTuple;
+
+import org.openflow.util.HexString;
+
+import com.thinkaurelius.titan.core.TitanFactory;
+import com.thinkaurelius.titan.core.TitanGraph;
+// import com.tinkerpop.blueprints.Direction;
+import com.tinkerpop.blueprints.Vertex;
+// import com.tinkerpop.gremlin.groovy.Gremlin;
+// import com.tinkerpop.gremlin.java.GremlinPipeline;
+// import com.tinkerpop.pipes.Pipe;
+// import com.tinkerpop.pipes.PipeFunction;
+// import com.tinkerpop.pipes.branch.LoopPipe;
+// import com.tinkerpop.pipes.branch.LoopPipe.LoopBundle;
+// import com.tinkerpop.pipes.filter.FilterPipe.Filter;
+// import com.tinkerpop.pipes.util.PipesFluentPipeline;
+
+import com.tinkerpop.blueprints.Element;
+
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+import com.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine;
+
+public class TopoRouteService implements ITopoRouteService {
+
+	ThreadLocal<SwitchStorageImpl> store = new ThreadLocal<SwitchStorageImpl>() {
+	    @Override
+	    protected SwitchStorageImpl initialValue() {
+		SwitchStorageImpl swStore = new SwitchStorageImpl();
+		// NOTE: This is the file path from global properties
+		swStore.init("/tmp/cassandra.titan");
+		return swStore;
+	    }
+	};
+
+	SwitchStorageImpl swStore = store.get();
+
+	@Override
+	public List<NodePortTuple> GetShortestpath(NodePortTuple src,
+			NodePortTuple dest) {
+	    List<NodePortTuple> result_list = new ArrayList<NodePortTuple>();
+
+	    TitanGraph titanGraph = swStore.graph;
+
+	    String dpid_src = HexString.toHexString(src.getNodeId());
+	    String dpid_dest = HexString.toHexString(dest.getNodeId());
+
+	    //
+	    // Implement the Shortest Path between two vertices by using
+	    // the following Gremlin code:
+	    //   results = []; v_src.as('x').out.out.in.has("type", "switch").dedup().loop('x'){it.object.dpid != v_dest.dpid & it.loops < 10}.path().fill(results)
+	    //
+
+	    String gremlin = "v_src.as(\"x\").out.out.in.has(\"type\", \"switch\").dedup().loop(\"x\"){it.object.dpid != v_dest.dpid & it.loops < 10}.path().fill(results)";
+
+	    // Get the source vertex
+	    Iterator<Vertex> iter = titanGraph.getVertices("dpid", dpid_src).iterator();
+	    if (! iter.hasNext())
+		return null;		// Source vertex not found
+	    Vertex v_src = iter.next();
+
+	    // Get the destination vertex
+	    iter = titanGraph.getVertices("dpid", dpid_dest).iterator();
+	    if (! iter.hasNext())
+		return null;		// Destination vertex not found
+	    Vertex v_dest = iter.next();
+	
+	    //
+	    // Implement the Gremlin script and run it
+	    //
+	    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 null;
+	    }
+
+	    //
+	    // Loop through the result and return the list
+	    // of <dpid, port> tuples.
+	    //
+	    long nodeId = 0;
+	    short portId = 0;
+	    for (ArrayList<Vertex> lv : results) {
+		int idx = 0;
+		for (Vertex v: lv) {
+		    String type = v.getProperty("type").toString();
+		    System.out.println("type: " + type);
+		    if (type.equals("port")) {
+                        String number = v.getProperty("number").toString();
+                        System.out.println("number: " + number);
+
+			Object obj = v.getProperty("number");
+			// String class_str = obj.getClass().toString();
+			if (obj instanceof Short) {
+			    portId = (Short)obj;
+			} else if (obj instanceof Integer) {
+			    Integer int_nodeId = (Integer)obj;
+			    portId = int_nodeId.shortValue();
+			    // int int_nodeId = (Integer)obj;
+			    // portId = (short)int_nodeId.;
+			}
+		    } else if (type.equals("switch")) {
+			String dpid = v.getProperty("dpid").toString();
+			nodeId = HexString.toLong(dpid);
+
+                        System.out.println("dpid: " + dpid);
+		    }
+		    if (idx == 0) {
+			idx++;
+			continue;
+		    }
+		    int mod = (idx - 1) % 3;
+		    if ((mod == 0) || (mod == 2))  {
+			result_list.add(new NodePortTuple(nodeId, portId));
+		    }
+		    idx++;
+		}
+	    }
+	    if (result_list.size() > 0)
+		return result_list;
+
+	    return null;
+	}
+
+	@Override
+	public Boolean RouteExists(NodePortTuple src, NodePortTuple dest) {
+		List<NodePortTuple> route = GetShortestpath(src, dest);
+		if (route != null)
+		    return true;
+		return false;
+	}
+}