Resolved merge conflict and back to Titan 0.2.0
diff --git a/scripts/cleanup-cassandra.sh b/scripts/cleanup-cassandra.sh
index a88ae6a..def4b59 100755
--- a/scripts/cleanup-cassandra.sh
+++ b/scripts/cleanup-cassandra.sh
@@ -1,3 +1,3 @@
#! /bin/bash
-DIR=~/ONOS
-~/titan-0.2.0/bin/gremlin.sh -e $DIR/scripts/cleanup-onos-db
+DIR=~/src/ONOS
+~/src/titan/titan-0.2.0/bin/gremlin.sh -e $DIR/scripts/cleanup-onos-db
diff --git a/scripts/cleanup-onos-db b/scripts/cleanup-onos-db
index 8949fea..1725051 100644
--- a/scripts/cleanup-onos-db
+++ b/scripts/cleanup-onos-db
@@ -1,4 +1,5 @@
g=TitanFactory.open('/tmp/cassandra.titan')
+g.V('type','device').each{g.removeVertex(it)}
g.V('type','port').each{g.removeVertex(it)}
g.V('type','switch').each{g.removeVertex(it)}
g.V('type','flow').each{g.removeVertex(it)}
diff --git a/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java b/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java
index 19addad..4f11c6c 100644
--- a/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java
+++ b/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java
@@ -45,7 +45,8 @@
@Adjacency(label="on")
public Iterable<IPortObject> getPorts();
- @Adjacency(label="on")
+ @JsonIgnore
+ @GremlinGroovy("_().out('on').has('number',portnum)")
public IPortObject getPort(final short port_num);
@Adjacency(label="on")
@@ -80,7 +81,7 @@
public void setDesc(String s);
@JsonIgnore
- @Property("port_sate")
+ @Property("port_state")
public Integer getPortState();
@Property("port_state")
@@ -89,8 +90,7 @@
@JsonIgnore
@Incidence(label="on",direction = Direction.IN)
public ISwitchObject getSwitch();
-
-
+
@JsonProperty("devices")
@Adjacency(label="host")
public Iterable<IDeviceObject> getDevices();
@@ -109,6 +109,9 @@
@Incidence(label="outport",direction = Direction.IN)
public Iterable<IFlowEntry> getOutFlowEntries();
+ @Adjacency(label="link")
+ public void removeLink(final IPortObject dest_port);
+
// @JsonIgnore
// @Adjacency(label="link")
// public Iterable<ILinkObject> getLinks();
@@ -255,7 +258,7 @@
@JsonIgnore
@GremlinGroovy("_().in('flow').out('switch')")
- public Iterable<IDeviceObject> getSwitches();
+ public Iterable<ISwitchObject> getSwitches();
@JsonIgnore
@Property("state")
diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
index 1a9a9c5..0d49c03 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
@@ -2215,9 +2215,11 @@
this.roleChanger = new RoleChanger();
String conf = configParams.get("dbconf");
- if (conf == null) {
+ if (conf == null || conf.isEmpty()) {
conf = "/tmp/cassandra.titan";
+ log.debug("did not get DB config setting using default {}", conf);
}
+ log.debug("setting DB config {}", conf);
this.swStore = new SwitchStorageImpl();
this.swStore.init(conf);
diff --git a/src/main/java/net/floodlightcontroller/core/internal/SwitchStorageImpl.java b/src/main/java/net/floodlightcontroller/core/internal/SwitchStorageImpl.java
index a068586..17ab274 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/SwitchStorageImpl.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/SwitchStorageImpl.java
@@ -6,6 +6,7 @@
import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
import net.floodlightcontroller.core.ISwitchStorage;
import net.onrc.onos.util.GraphDBConnection;
+import net.onrc.onos.util.GraphDBConnection.GenerateEvent;
import net.onrc.onos.util.GraphDBConnection.Transaction;
import org.openflow.protocol.OFPhysicalPort;
@@ -15,7 +16,7 @@
import org.slf4j.LoggerFactory;
public class SwitchStorageImpl implements ISwitchStorage {
- public GraphDBConnection conn;
+ protected GraphDBConnection conn;
protected static Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
@Override
@@ -177,11 +178,12 @@
log.info("SwitchStorage:deletePort dpid:{} port:{} found and deleted", dpid, port);
sw.removePort(p);
conn.utils().removePort(conn, p);
- conn.endTx(Transaction.COMMIT);
+ conn.endTx(Transaction.COMMIT,GenerateEvent.TRUE);
}
}
} catch (Exception e) {
// TODO: handle exceptions
+ e.printStackTrace();
conn.endTx(Transaction.ROLLBACK);
log.info("SwitchStorage:deletePort dpid:{} port:{} failed", dpid, port);
}
diff --git a/src/main/java/net/floodlightcontroller/core/internal/TopoSwitchServiceImpl.java b/src/main/java/net/floodlightcontroller/core/internal/TopoSwitchServiceImpl.java
index b3c31ec..9f63fd7 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/TopoSwitchServiceImpl.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/TopoSwitchServiceImpl.java
@@ -28,21 +28,21 @@
@Override
public Iterable<ISwitchObject> getActiveSwitches() {
// TODO Auto-generated method stub
- conn = GraphDBConnection.getInstance("");
+ conn = GraphDBConnection.getInstance("/tmp/cassandra.titan");
return conn.utils().getActiveSwitches(conn);
}
@Override
public Iterable<ISwitchObject> getAllSwitches() {
// TODO Auto-generated method stub
- conn = GraphDBConnection.getInstance("");
+ conn = GraphDBConnection.getInstance("/tmp/cassandra.titan");
return conn.utils().getAllSwitches(conn);
}
@Override
public Iterable<ISwitchObject> getInactiveSwitches() {
// TODO Auto-generated method stub
- conn = GraphDBConnection.getInstance("");
+ conn = GraphDBConnection.getInstance("/tmp/cassandra.titan");
return conn.utils().getInactiveSwitches(conn);
}
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImpl.java b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImpl.java
index 176a1a0..33ae22a 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImpl.java
+++ b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImpl.java
@@ -5,12 +5,16 @@
import java.util.List;
import java.util.Set;
+import net.floodlightcontroller.core.INetMapTopologyObjects.IPortObject;
import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
import net.floodlightcontroller.core.INetMapTopologyService.ITopoSwitchService;
import net.floodlightcontroller.core.internal.TopoSwitchServiceImpl;
import net.floodlightcontroller.linkdiscovery.ILinkStorage;
import net.floodlightcontroller.linkdiscovery.LinkInfo;
import net.floodlightcontroller.routing.Link;
+import net.onrc.onos.util.GraphDBConnection;
+import net.onrc.onos.util.GraphDBConnection.GenerateEvent;
+import net.onrc.onos.util.GraphDBConnection.Transaction;
import org.openflow.util.HexString;
import org.slf4j.Logger;
@@ -23,6 +27,8 @@
import com.tinkerpop.blueprints.TransactionalGraph.Conclusion;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.Edge;
+import com.tinkerpop.blueprints.util.wrappers.event.EventGraph;
+import com.tinkerpop.blueprints.util.wrappers.event.EventTransactionalGraph;
import com.tinkerpop.gremlin.java.GremlinPipeline;
import com.tinkerpop.pipes.PipeFunction;
import com.tinkerpop.pipes.transform.PathPipe;
@@ -128,7 +134,8 @@
@Override
public void deleteLink(Link lt) {
- Vertex vportSrc = null, vportDst = null;
+ GraphDBConnection conn = GraphDBConnection.getInstance("");
+ IPortObject vportSrc = null, vportDst = null;
int count = 0;
log.debug("deleteLink(): {}", lt);
@@ -137,29 +144,33 @@
// get source port vertex
String dpid = HexString.toHexString(lt.getSrc());
short port = lt.getSrcPort();
- vportSrc = getPortVertex(dpid, port);
+ vportSrc = conn.utils().searchPort(conn, dpid, port);
// get dst port vertex
dpid = HexString.toHexString(lt.getDst());
port = lt.getDstPort();
- vportDst = getPortVertex(dpid, port);
+ vportDst = conn.utils().searchPort(conn, dpid, port);
+ // FIXME: This needs to remove all edges
+ // FIXME: Events will only be generated on singleton graph object (GraphDBConnection)
if (vportSrc != null && vportDst != null) {
- for (Edge e : vportSrc.getEdges(Direction.OUT)) {
+
+ /* for (Edge e : vportSrc.asVertex().getEdges(Direction.OUT)) {
log.debug("deleteLink(): {} in {} out {}",
new Object[]{e.getLabel(), e.getVertex(Direction.IN), e.getVertex(Direction.OUT)});
if (e.getLabel().equals("link") && e.getVertex(Direction.IN).equals(vportDst)) {
graph.removeEdge(e);
count++;
}
- }
- graph.stopTransaction(Conclusion.SUCCESS);
- log.debug("deleteLink(): deleted {} edges {} src {} dst {}", new Object[]{
- count, lt, vportSrc, vportDst});
+ }*/
+ vportSrc.removeLink(vportDst);
+ conn.endTx(Transaction.COMMIT, GenerateEvent.TRUE);
+ log.debug("deleteLink(): deleted edges src {} dst {}", new Object[]{
+ lt, vportSrc, vportDst});
} else {
log.error("deleteLink(): failed invalid vertices {} src {} dst {}", new Object[]{lt, vportSrc, vportDst});
- graph.stopTransaction(Conclusion.FAILURE);
+ conn.endTx(Transaction.ROLLBACK);
}
} catch (TitanException e) {
diff --git a/src/main/java/net/floodlightcontroller/onoslistener/OnosPublisher.java b/src/main/java/net/floodlightcontroller/onoslistener/OnosPublisher.java
index 585fc36..6d8087b 100644
--- a/src/main/java/net/floodlightcontroller/onoslistener/OnosPublisher.java
+++ b/src/main/java/net/floodlightcontroller/onoslistener/OnosPublisher.java
@@ -34,6 +34,8 @@
import net.onrc.onos.registry.controller.IControllerRegistryService;
import net.onrc.onos.registry.controller.IControllerRegistryService.ControlChangeCallback;
import net.onrc.onos.registry.controller.RegistryException;
+import net.onrc.onos.util.GraphDBConnection;
+import net.onrc.onos.util.LocalTopologyEventListener;
public class OnosPublisher implements IDeviceListener, IOFSwitchListener,
ILinkDiscoveryListener, IFloodlightModule {
@@ -43,6 +45,7 @@
protected static Logger log;
protected IDeviceService deviceService;
protected IControllerRegistryService registryService;
+ protected GraphDBConnection conn;
protected static final String DBConfigFile = "dbconf";
protected static final String CleanupEnabled = "EnableCleanup";
@@ -198,6 +201,7 @@
// TODO Auto-generated method stub
Map<String, String> configMap = context.getConfigParams(this);
String conf = configMap.get(DBConfigFile);
+ conn = GraphDBConnection.getInstance(conf);
log = LoggerFactory.getLogger(OnosPublisher.class);
deviceService = context.getServiceImpl(IDeviceService.class);
@@ -221,6 +225,9 @@
String cleanupNeeded = configMap.get(CleanupEnabled);
deviceService.addListener(this);
+
+ log.debug("Adding EventListener");
+ conn.addEventListener(new LocalTopologyEventListener(conn));
// Setup the Cleanup task.
if (cleanupNeeded == null || !cleanupNeeded.equals("False")) {
ScheduledExecutorService ses = threadPool.getScheduledExecutor();
diff --git a/src/main/java/net/onrc/onos/flow/FlowManagerImpl.java b/src/main/java/net/onrc/onos/flow/FlowManagerImpl.java
index 7cf1cab..b8b3303 100644
--- a/src/main/java/net/onrc/onos/flow/FlowManagerImpl.java
+++ b/src/main/java/net/onrc/onos/flow/FlowManagerImpl.java
@@ -1,17 +1,43 @@
package net.onrc.onos.flow;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
+
+import org.openflow.util.HexString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.tinkerpop.blueprints.Direction;
+import com.tinkerpop.blueprints.Vertex;
import net.floodlightcontroller.core.INetMapTopologyObjects.IFlowEntry;
import net.floodlightcontroller.core.INetMapTopologyObjects.IFlowPath;
import net.floodlightcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.floodlightcontroller.core.ISwitchStorage.SwitchState;
import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.util.DataPath;
+import net.floodlightcontroller.util.Dpid;
import net.floodlightcontroller.util.FlowEntry;
+import net.floodlightcontroller.util.FlowEntryAction;
+import net.floodlightcontroller.util.FlowEntryMatch;
import net.floodlightcontroller.util.FlowPath;
+import net.floodlightcontroller.util.Port;
+import net.floodlightcontroller.util.SwitchPort;
+import net.onrc.onos.util.GraphDBConnection;
+import net.onrc.onos.util.LocalTopologyEventListener;
+import net.onrc.onos.util.GraphDBConnection.Transaction;
public class FlowManagerImpl implements IFlowManager {
+
+ protected static Logger log = LoggerFactory.getLogger(LocalTopologyEventListener.class);
+ protected static GraphDBConnection conn;
@Override
public void createFlow(IPortObject src_port, IPortObject dest_port) {
@@ -44,6 +70,7 @@
public void reconcileFlows(IPortObject src_port) {
// TODO Auto-generated method stub
+ log.debug("Reconcile Flows for Port removed: {}:{}",src_port.getSwitch().getDPID(),src_port.getNumber());
Iterable<IFlowEntry> flowEntries = src_port.getOutFlowEntries();
for(IFlowEntry fe: flowEntries) {
@@ -54,6 +81,29 @@
private void reconcileFlow(IFlowPath flow) {
// TODO Auto-generated method stub
+ String src_dpid = flow.getSrcSwitch();
+ String dst_dpid = flow.getDstSwitch();
+ Short src_port = flow.getSrcPort();
+ Short dst_port = flow.getDstPort();
+ IPortObject src = null;
+ IPortObject dst = null;
+ src = conn.utils().searchPort(conn, src_dpid, src_port);
+ dst = conn.utils().searchPort(conn, dst_dpid, dst_port);
+ if (src != null && dst != null) {
+ FlowPath newFlow = this.computeFlowPath(src,dst);
+ installFlow(newFlow);
+ removeFlow(flow);
+ }
+
+ }
+
+ private void removeFlow(IFlowPath flow) {
+ // TODO Auto-generated method stub
+
+ }
+
+ private void installFlow(FlowPath newFlow) {
+ // TODO Auto-generated method stub
}
@@ -66,7 +116,188 @@
@Override
public FlowPath computeFlowPath(IPortObject src_port, IPortObject dest_port) {
// TODO Auto-generated method stub
- return null;
+ DataPath dataPath = new DataPath();
+
+ // FIXME: Bad idea to use FloodLight data structures (SwitchPort)
+
+ dataPath.setSrcPort(new SwitchPort(new Dpid(src_port.getSwitch().getDPID()),
+ new Port(src_port.getNumber())));
+ dataPath.setDstPort(new SwitchPort(new Dpid(src_port.getSwitch().getDPID()),
+ new Port(src_port.getNumber())));
+
+ if (src_port.getSwitch().equals(dest_port.getSwitch())) {
+ // on same switch create quick path
+ FlowEntry flowEntry = new FlowEntry();
+ flowEntry.setDpid(new Dpid(src_port.getSwitch().getDPID()));
+ flowEntry.setInPort(new Port(src_port.getNumber()));
+ flowEntry.setOutPort(new Port(src_port.getNumber()));
+ flowEntry.setFlowEntryMatch(new FlowEntryMatch());
+ flowEntry.flowEntryMatch().enableInPort(flowEntry.inPort());
+
+ // Set the outgoing port output action
+ ArrayList<FlowEntryAction> flowEntryActions = flowEntry.flowEntryActions();
+ if (flowEntryActions == null) {
+ flowEntryActions = new ArrayList<FlowEntryAction>();
+ flowEntry.setFlowEntryActions(flowEntryActions);
+ }
+ FlowEntryAction flowEntryAction = new FlowEntryAction();
+ flowEntryAction.setActionOutput(flowEntry.outPort());
+ flowEntryActions.add(flowEntryAction);
+ dataPath.flowEntries().add(flowEntry);
+
+ FlowPath flowPath = new FlowPath();
+ flowPath.setDataPath(dataPath);
+
+ return flowPath;
+ }
+ Vertex v_src = src_port.getSwitch().asVertex();
+ Vertex v_dest = dest_port.getSwitch().asVertex();
+
+ //
+ // Implement the Shortest Path computation by using Breath First Search
+ //
+ Set<Vertex> visitedSet = new HashSet<Vertex>();
+ Queue<Vertex> processingList = new LinkedList<Vertex>();
+ Map<Vertex, Vertex> previousVertexMap = new HashMap<Vertex, Vertex>();
+
+ processingList.add(v_src);
+ visitedSet.add(v_src);
+ Boolean path_found = false;
+ while (! processingList.isEmpty()) {
+ Vertex nextVertex = processingList.poll();
+ if (v_dest.equals(nextVertex)) {
+ path_found = true;
+ break;
+ }
+ for (Vertex parentPort : nextVertex.getVertices(Direction.OUT, "on")) {
+ for (Vertex childPort : parentPort.getVertices(Direction.OUT, "link")) {
+ for (Vertex child : childPort.getVertices(Direction.IN, "on")) {
+ // Ignore inactive switches
+ String state = child.getProperty("state").toString();
+ if (! state.equals(SwitchState.ACTIVE.toString()))
+ continue;
+
+ if (! visitedSet.contains(child)) {
+ previousVertexMap.put(parentPort, nextVertex);
+ previousVertexMap.put(childPort, parentPort);
+ previousVertexMap.put(child, childPort);
+ visitedSet.add(child);
+ processingList.add(child);
+ }
+ }
+ }
+ }
+ }
+ if (! path_found) {
+ return null; // No path found
+ }
+
+ List<Vertex> resultPath = new LinkedList<Vertex>();
+ Vertex previousVertex = v_dest;
+ resultPath.add(v_dest);
+ while (! v_src.equals(previousVertex)) {
+ Vertex currentVertex = previousVertexMap.get(previousVertex);
+ resultPath.add(currentVertex);
+ previousVertex = currentVertex;
+ }
+ Collections.reverse(resultPath);
+
+ // Loop through the result and prepare the return result
+ // as a list of Flow Entries.
+ //
+ long nodeId = 0;
+ short portId = 0;
+ Port inPort = new Port(src_port.getNumber());
+ Port outPort = new Port();
+ int idx = 0;
+ for (Vertex v: resultPath) {
+ 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);
+ }
+ idx++;
+ if (idx == 1) {
+ continue;
+ }
+ int mod = idx % 3;
+ if (mod == 0) {
+ // Setup the incoming port
+ inPort = new Port(portId);
+ continue;
+ }
+ if (mod == 2) {
+ // Setup the outgoing port, and add the Flow Entry
+ outPort = new Port(portId);
+
+ FlowEntry flowEntry = new FlowEntry();
+ flowEntry.setDpid(new Dpid(nodeId));
+ flowEntry.setInPort(inPort);
+ flowEntry.setOutPort(outPort);
+ flowEntry.setFlowEntryMatch(new FlowEntryMatch());
+ flowEntry.flowEntryMatch().enableInPort(flowEntry.inPort());
+
+ // Set the outgoing port output action
+ ArrayList<FlowEntryAction> flowEntryActions = flowEntry.flowEntryActions();
+ if (flowEntryActions == null) {
+ flowEntryActions = new ArrayList<FlowEntryAction>();
+ flowEntry.setFlowEntryActions(flowEntryActions);
+ }
+ FlowEntryAction flowEntryAction = new FlowEntryAction();
+ flowEntryAction.setActionOutput(flowEntry.outPort());
+ flowEntryActions.add(flowEntryAction);
+ dataPath.flowEntries().add(flowEntry);
+ continue;
+ }
+ }
+ if (idx > 0) {
+ // Add the last Flow Entry
+ FlowEntry flowEntry = new FlowEntry();
+ flowEntry.setDpid(new Dpid(nodeId));
+ flowEntry.setInPort(inPort);
+ flowEntry.setOutPort(new Port(dest_port.getNumber()));
+ flowEntry.setFlowEntryMatch(new FlowEntryMatch());
+ flowEntry.flowEntryMatch().enableInPort(flowEntry.inPort());
+
+ // Set the outgoing port output action
+ ArrayList<FlowEntryAction> flowEntryActions = flowEntry.flowEntryActions();
+ if (flowEntryActions == null) {
+ flowEntryActions = new ArrayList<FlowEntryAction>();
+ flowEntry.setFlowEntryActions(flowEntryActions);
+ }
+ FlowEntryAction flowEntryAction = new FlowEntryAction();
+ flowEntryAction.setActionOutput(flowEntry.outPort());
+ flowEntryActions.add(flowEntryAction);
+ dataPath.flowEntries().add(flowEntry);
+ dataPath.flowEntries().add(flowEntry);
+ }
+
+
+ if (dataPath.flowEntries().size() > 0) {
+ FlowPath flowPath = new FlowPath();
+ flowPath.setDataPath(dataPath);
+
+ return flowPath;
+ }
+ return null;
+
}
@Override
@@ -106,5 +337,6 @@
// TODO Auto-generated method stub
return false;
}
+
}
diff --git a/src/main/java/net/onrc/onos/util/GraphDBConnection.java b/src/main/java/net/onrc/onos/util/GraphDBConnection.java
index ee50cd0..01b22ae 100644
--- a/src/main/java/net/onrc/onos/util/GraphDBConnection.java
+++ b/src/main/java/net/onrc/onos/util/GraphDBConnection.java
@@ -2,10 +2,18 @@
import java.util.Set;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.esotericsoftware.minlog.Log;
import com.thinkaurelius.titan.core.TitanFactory;
import com.thinkaurelius.titan.core.TitanGraph;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.TransactionalGraph.Conclusion;
+import com.tinkerpop.blueprints.util.wrappers.event.EventGraph;
+import com.tinkerpop.blueprints.util.wrappers.event.EventTransactionalGraph;
+import com.tinkerpop.blueprints.util.wrappers.event.EventTransactionalIndexableGraph;
+import com.tinkerpop.blueprints.util.wrappers.event.listener.GraphChangedListener;
import com.tinkerpop.frames.FramedGraph;
public class GraphDBConnection {
@@ -13,9 +21,17 @@
COMMIT,
ROLLBACK
}
+ public enum GenerateEvent {
+ TRUE,
+ FALSE
+ }
+ protected static Logger log = LoggerFactory.getLogger(GraphDBConnection.class);
private static GraphDBConnection singleton = new GraphDBConnection( );
private static TitanGraph graph;
+ private static EventTransactionalGraph<TitanGraph> eg;
private static GraphDBUtils utils;
+ private static String configFile;
+
/* A private Constructor prevents any other
* class from instantiating.
@@ -23,9 +39,14 @@
private GraphDBConnection(){ }
/* Static 'instance' method */
- public static GraphDBConnection getInstance(String conf) {
- if (graph == null||graph.isOpen() == Boolean.FALSE) {
- graph = TitanFactory.open(conf);
+ public static GraphDBConnection getInstance(final String conf) {
+ if (GraphDBConnection.configFile == null || GraphDBConnection.configFile.isEmpty()) {
+ GraphDBConnection.configFile = conf;
+ log.debug("GraphDBConnection::Setting Config File {}", GraphDBConnection.configFile);
+ }
+ if (!GraphDBConnection.configFile.isEmpty() &&
+ (graph == null||graph.isOpen() == Boolean.FALSE)) {
+ graph = TitanFactory.open(GraphDBConnection.configFile);
// FIXME: Creation on Indexes should be done only once
Set<String> s = graph.getIndexedKeys(Vertex.class);
if (!s.contains("dpid")) {
@@ -44,8 +65,9 @@
graph.createKeyIndex("flow_entry_id",
Vertex.class);
}
- }
- graph.stopTransaction(Conclusion.SUCCESS);
+ graph.stopTransaction(Conclusion.SUCCESS);
+ eg = new EventTransactionalGraph<TitanGraph>(graph);
+ }
if (utils == null) {
utils = new GraphDBUtils();
}
@@ -66,6 +88,21 @@
}
}
+ protected EventTransactionalGraph<TitanGraph> getEventGraph() {
+
+ if (isValid()) {
+ return eg;
+ } else {
+ return null;
+ }
+ }
+
+ public void addEventListener(final LocalGraphChangedListener listener) {
+ EventTransactionalGraph<TitanGraph> eg = this.getEventGraph();
+ eg.addListener(listener);
+ log.debug("Registered listener {}",listener.getClass());
+ }
+
public Boolean isValid() {
return (graph != null||graph.isOpen());
@@ -78,14 +115,33 @@
public void endTx(Transaction tx) {
switch (tx) {
case COMMIT:
- graph.stopTransaction(Conclusion.SUCCESS);
+ eg.stopTransaction(Conclusion.SUCCESS);
case ROLLBACK:
- graph.stopTransaction(Conclusion.FAILURE);
+ eg.stopTransaction(Conclusion.FAILURE);
}
}
+ public void endTx(Transaction tx, GenerateEvent fire) {
+
+ try {
+ if (fire.equals(GenerateEvent.TRUE)) {
+ switch (tx) {
+ case COMMIT:
+ eg.stopTransaction(Conclusion.SUCCESS);
+ case ROLLBACK:
+ eg.stopTransaction(Conclusion.FAILURE);
+ }
+ } else {
+ endTx(tx);
+ }
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
public void close() {
- graph.stopTransaction(Conclusion.SUCCESS);
+ graph.shutdown();
}
}
diff --git a/src/main/java/net/onrc/onos/util/GraphDBUtils.java b/src/main/java/net/onrc/onos/util/GraphDBUtils.java
index 7283d09..b0ca23b 100644
--- a/src/main/java/net/onrc/onos/util/GraphDBUtils.java
+++ b/src/main/java/net/onrc/onos/util/GraphDBUtils.java
@@ -3,12 +3,6 @@
import java.util.ArrayList;
import java.util.List;
-import com.thinkaurelius.titan.core.TitanGraph;
-import com.tinkerpop.blueprints.Vertex;
-import com.tinkerpop.frames.FramedGraph;
-import com.tinkerpop.frames.FramedVertexIterable;
-import com.tinkerpop.gremlin.java.GremlinPipeline;
-
import net.floodlightcontroller.core.INetMapTopologyObjects.IDeviceObject;
import net.floodlightcontroller.core.INetMapTopologyObjects.IFlowEntry;
import net.floodlightcontroller.core.INetMapTopologyObjects.IFlowPath;
@@ -18,6 +12,14 @@
import net.floodlightcontroller.util.FlowEntryId;
import net.floodlightcontroller.util.FlowId;
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.blueprints.util.wrappers.event.EventGraph;
+import com.tinkerpop.blueprints.util.wrappers.event.EventTransactionalGraph;
+import com.tinkerpop.frames.FramedGraph;
+import com.tinkerpop.frames.structures.FramedVertexIterable;
+import com.tinkerpop.gremlin.java.GremlinPipeline;
+
public class GraphDBUtils implements IDBUtils {
@Override
@@ -44,16 +46,6 @@
}
@Override
- public ISwitchObject searchActiveSwitch(GraphDBConnection conn, String dpid) {
- ISwitchObject sw = searchSwitch(conn, dpid);
- if ((sw != null) &&
- sw.getState().equals(SwitchState.ACTIVE.toString())) {
- return sw;
- }
- return null;
- }
-
- @Override
public IDeviceObject searchDevice(GraphDBConnection conn, String macAddr) {
// TODO Auto-generated method stub
FramedGraph<TitanGraph> fg = conn.getFramedGraph();
@@ -65,11 +57,12 @@
@Override
public IPortObject searchPort(GraphDBConnection conn, String dpid, short number) {
ISwitchObject sw = searchSwitch(conn, dpid);
- GremlinPipeline<Vertex, IPortObject> pipe = new GremlinPipeline<Vertex, IPortObject>();
+ return sw != null ? sw.getPort(number): null;
+ /* GremlinPipeline<Vertex, IPortObject> pipe = new GremlinPipeline<Vertex, IPortObject>();
pipe.start(sw.asVertex());
pipe.out("on").has("number", number);
- FramedVertexIterable<IPortObject> r = new FramedVertexIterable(conn.getFramedGraph(), pipe, IPortObject.class);
- return r.iterator().hasNext() ? r.iterator().next() : null;
+ FramedVertexIterable<IPortObject> r = new FramedVertexIterable<IPortObject>(conn.getFramedGraph(), (Iterable) pipe, IPortObject.class);
+ return r.iterator().hasNext() ? r.iterator().next() : null; */
}
@Override
@@ -89,6 +82,7 @@
@Override
public void removePort(GraphDBConnection conn, IPortObject port) {
FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+// EventGraph<TitanGraph> eg = conn.getEventGraph();
fg.removeVertex(port.asVertex());
}
@@ -135,7 +129,7 @@
GremlinPipeline<Vertex, IFlowPath> pipe = new GremlinPipeline<Vertex, IFlowPath>();
pipe.start(flowEntry.asVertex());
pipe.out("flow");
- FramedVertexIterable<IFlowPath> r = new FramedVertexIterable(conn.getFramedGraph(), pipe, IFlowPath.class);
+ FramedVertexIterable<IFlowPath> r = new FramedVertexIterable(conn.getFramedGraph(), (Iterable) pipe, IFlowPath.class);
return r.iterator().hasNext() ? r.iterator().next() : null;
}
@@ -211,4 +205,10 @@
}
return inactiveSwitches;
}
+
+ @Override
+ public ISwitchObject searchActiveSwitch(GraphDBConnection conn, String dpid) {
+ // TODO Auto-generated method stub
+ return null;
+ }
}
diff --git a/src/main/java/net/onrc/onos/util/LocalGraphChangedListener.java b/src/main/java/net/onrc/onos/util/LocalGraphChangedListener.java
new file mode 100644
index 0000000..ac819f9
--- /dev/null
+++ b/src/main/java/net/onrc/onos/util/LocalGraphChangedListener.java
@@ -0,0 +1,7 @@
+package net.onrc.onos.util;
+
+import com.tinkerpop.blueprints.util.wrappers.event.listener.GraphChangedListener;
+
+public interface LocalGraphChangedListener extends GraphChangedListener {
+
+}
diff --git a/src/main/java/net/onrc/onos/util/LocalTopologyEventListener.java b/src/main/java/net/onrc/onos/util/LocalTopologyEventListener.java
index 186ba58..61f227d 100644
--- a/src/main/java/net/onrc/onos/util/LocalTopologyEventListener.java
+++ b/src/main/java/net/onrc/onos/util/LocalTopologyEventListener.java
@@ -1,10 +1,6 @@
package net.onrc.onos.util;
-import net.floodlightcontroller.core.INetMapTopologyObjects.IFlowEntry;
-import net.floodlightcontroller.core.INetMapTopologyObjects.IFlowPath;
import net.floodlightcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.floodlightcontroller.linkdiscovery.internal.TopoLinkServiceImpl;
-import net.floodlightcontroller.util.FlowPath;
import net.onrc.onos.flow.FlowManagerImpl;
import net.onrc.onos.flow.IFlowManager;
@@ -15,12 +11,15 @@
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Vertex;
-import com.tinkerpop.blueprints.util.wrappers.event.listener.GraphChangedListener;
-public class LocalTopologyEventListener implements GraphChangedListener {
+public class LocalTopologyEventListener implements LocalGraphChangedListener {
protected static Logger log = LoggerFactory.getLogger(LocalTopologyEventListener.class);
- protected static GraphDBConnection conn = GraphDBConnection.getInstance("");
+ protected static GraphDBConnection conn;
+
+ public LocalTopologyEventListener(GraphDBConnection conn) {
+ LocalTopologyEventListener.conn = conn;
+ }
@Override
public void edgeAdded(Edge arg0) {
@@ -28,11 +27,6 @@
// Convert this Event into NetMapEvent (LinkAdded, FlowEntryEnabled, HostAttached, PortEnabled)
}
- @Override
- public void edgePropertyChanged(Edge arg0, String arg1, Object arg2) {
- // TODO Auto-generated method stub
- // Generate State change events on edges too
- }
@Override
public void edgePropertyRemoved(Edge arg0, String arg1, Object arg2) {
@@ -71,22 +65,40 @@
}
@Override
- public void vertexPropertyChanged(Vertex arg0, String arg1, Object arg2) {
- // TODO Auto-generated method stub
-
-
- }
-
- @Override
public void vertexPropertyRemoved(Vertex arg0, String arg1, Object arg2) {
// TODO Auto-generated method stub
}
@Override
- public void vertexRemoved(Vertex arg0) {
+ public void vertexRemoved(Vertex vertex) {
// TODO Auto-generated method stub
+ // Generate NetMapEvents
+ String type = (String) vertex.getProperty("type");
+ log.debug("TopologyEvents: Received vertex removed event: {}",vertex.toString());
+ if (type.equals("port")) {
+ // port is removed...lets fire reconcile here directly for now
+
+ IPortObject src_port = conn.getFramedGraph().frame(vertex, IPortObject.class);
+ log.debug("TopologyEvents: Port removed: {}:{}",src_port.getSwitch().getDPID(),src_port.getNumber());
+ IFlowManager manager = new FlowManagerImpl();
+ manager.reconcileFlows(src_port);
+ }
+ }
+
+ @Override
+ public void edgePropertyChanged(Edge arg0, String arg1, Object arg2,
+ Object arg3) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void vertexPropertyChanged(Vertex arg0, String arg1, Object arg2,
+ Object arg3) {
+ // TODO Auto-generated method stub
+
}
}
diff --git a/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java b/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java
index cea67c3..3d5e03b 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java
@@ -27,7 +27,8 @@
public static TitanGraph getTestDatabase(){
//return TitanFactory.open(testDbLocation);
- return TitanFactory.openInMemoryGraph();
+// return TitanFactory.openInMemoryGraph();
+ return TitanFactory.open(testDbLocation);
}
public static void populateTestData(TitanGraph titanGraph){
diff --git a/start-rest.sh b/start-rest.sh
index 01e7638..8251c0f 100755
--- a/start-rest.sh
+++ b/start-rest.sh
@@ -1,7 +1,7 @@
#! /bin/bash
# Change this accordingly
-ONOSDIR=${HOME}/ONOS
+ONOSDIR=${HOME}/src/ONOS
script_name="topology_rest.py"
#######################
diff --git a/web/onos-topology.html b/web/onos-topology.html
index 72e9fc4..725866a 100644
--- a/web/onos-topology.html
+++ b/web/onos-topology.html
@@ -52,8 +52,13 @@
<div id="topology"></div>
<script type="text/javascript" src="js/controller-status.js"></script>
<script type="text/javascript">
+<<<<<<< Updated upstream
controller_status("http://gui3.onlab.us:8081/controller_status");
gui("http://gui3.onlab.us:8081/topology");
+=======
+controller_status("http://localhost:9000/controller_status");
+gui("http://localhost:9000/topology");
+>>>>>>> Stashed changes
</script>
</svg>
</body>
diff --git a/web/shortest_path.py b/web/shortest_path.py
index 0f23bf4..b379a82 100755
--- a/web/shortest_path.py
+++ b/web/shortest_path.py
@@ -20,7 +20,7 @@
ControllerIP="127.0.0.1"
ControllerPort=8080
-DEBUG=0
+DEBUG=1
pp = pprint.PrettyPrinter(indent=4)
app = Flask(__name__)
diff --git a/web/topology_rest.py b/web/topology_rest.py
index eb270ba..392cb87 100755
--- a/web/topology_rest.py
+++ b/web/topology_rest.py
@@ -19,18 +19,32 @@
## Uncomment the desired block based on your testbed environment
# Settings for running on production
+<<<<<<< HEAD
+core_switches=["00:00:00:00:ba:5e:ba:11", "00:00:00:00:00:00:ba:12", "00:00:20:4e:7f:51:8a:35", "00:00:00:00:ba:5e:ba:13", "00:00:00:08:a2:08:f9:01", "00:00:00:16:97:08:9a:46"]
+ONOS_GUI3_HOST="http://localhost:9000"
+ONOS_GUI3_CONTROL_HOST="http://localhost:9000"
+=======
#controllers=["onosgui1", "onosgui2", "onosgui3", "onosgui4", "onosgui5", "onosgui6", "onosgui7", "onosgui8"]
#core_switches=["00:00:00:00:ba:5e:ba:11", "00:00:00:00:00:00:ba:12", "00:00:20:4e:7f:51:8a:35", "00:00:00:00:ba:5e:ba:13", "00:00:00:08:a2:08:f9:01", "00:00:00:16:97:08:9a:46"]
#ONOS_GUI3_HOST="http://gui3.onlab.us:8080"
#ONOS_GUI3_CONTROL_HOST="http://gui3.onlab.us:8081"
+>>>>>>> ecee79b1df12c337cba14cbc9e3660741ae72441
# Settings for running on dev testbed. Replace dev
#controllers=["onosdevb1", "onosdevb2", "onosdevb3", "onosdevb4"]
controllers=["onosdevt1", "onosdevt2", "onosdevt3", "onosdevt4", "onosdevt5", "onosdevt6", "onosdevt7", "onosdevt8"]
core_switches=["00:00:00:00:00:00:01:01", "00:00:00:00:00:00:01:02", "00:00:00:00:00:00:01:03", "00:00:00:00:00:00:01:04", "00:00:00:00:00:00:01:05", "00:00:00:00:00:00:01:06"]
+<<<<<<< HEAD
+ONOS_LOCAL_HOST="http://localhost:8080" ;# for Amazon EC2
+controllers=["Berde-MBP.local"]
+#controllers=["onosgui1", "onosgui2", "onosgui3", "onosgui4", "onosgui5", "onosgui6", "onosgui7", "onosgui8"]
+#core_switches=["00:00:00:00:ba:5e:ba:11", "00:00:00:00:00:00:ba:12", "00:00:20:4e:7f:51:8a:35", "00:00:00:00:ba:5e:ba:13", "00:00:00:08:a2:08:f9:01", "00:00:00:16:97:08:9a:46"]
+core_switches=["00:00:00:00:00:00:01:01", "00:00:00:00:00:00:01:02", "00:00:00:00:00:00:01:03", "00:00:00:00:00:00:01:04", "00:00:00:00:00:00:01:05", "00:00:00:00:00:00:01:06"]
+=======
ONOS_GUI3_HOST="http://devt-gui.onlab.us:8080"
ONOS_GUI3_CONTROL_HOST="http://devt-gui.onlab.us:8080"
+>>>>>>> ecee79b1df12c337cba14cbc9e3660741ae72441
LB=True #; True or False
ONOS_DEFAULT_HOST="localhost" ;# Has to set if LB=False
@@ -639,7 +653,7 @@
@app.route("/controller_status")
def controller_status():
- onos_check="ssh -i ~/.ssh/onlabkey.pem %s ONOS/start-onos.sh status | awk '{print $1}'"
+ onos_check="sh ~/src/ONOS/start-onos.sh status | awk '{print $1}'"
#cassandra_check="ssh -i ~/.ssh/onlabkey.pem %s ONOS/start-cassandra.sh status"
cont_status=[]
@@ -658,8 +672,8 @@
### Command ###
@app.route("/gui/controller/<cmd>/<controller_name>")
def controller_status_change(cmd, controller_name):
- start_onos="ssh -i ~/.ssh/onlabkey.pem %s ONOS/start-onos.sh start" % (controller_name)
- stop_onos="ssh -i ~/.ssh/onlabkey.pem %s ONOS/start-onos.sh stop" % (controller_name)
+ start_onos="~/src/ONOS/start-onos.sh start" % (controller_name)
+ stop_onos="~/src/ONOS/start-onos.sh stop" % (controller_name)
if cmd == "up":
result=os.popen(start_onos).read()
@@ -694,8 +708,8 @@
r = re.compile(':')
dpid = re.sub(r, '', dpid)
host=controllers[0]
- cmd_string="ssh -i ~/.ssh/onlabkey.pem %s 'cd ONOS/scripts; ./switch.sh %s %s'" % (host, dpid, cmd)
- get_status="ssh -i ~/.ssh/onlabkey.pem %s 'cd ONOS/scripts; ./switch.sh %s'" % (host, dpid)
+ cmd_string="'cd ~/src/ONOS/scripts; ./switch.sh %s %s'" % (host, dpid, cmd)
+ get_status="'cd ~/src/ONOS/scripts; ./switch.sh %s'" % (host, dpid)
print "cmd_string"
if cmd =="up" or cmd=="down":