Merge branch 'master' of https://github.com/OPENNETWORKINGLAB/ONOS
diff --git a/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java b/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java
index 587b3c2..e72baf7 100644
--- a/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java
+++ b/src/main/java/net/floodlightcontroller/core/INetMapTopologyObjects.java
@@ -77,7 +77,7 @@
public void setDesc(String s);
@JsonIgnore
- @Property("port_sate")
+ @Property("port_state")
public Integer getPortState();
@Property("port_state")
@@ -86,8 +86,7 @@
@JsonIgnore
@Incidence(label="on",direction = Direction.IN)
public ISwitchObject getSwitch();
-
-
+
@JsonProperty("devices")
@Adjacency(label="host")
public Iterable<IDeviceObject> getDevices();
@@ -106,6 +105,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();
@@ -238,7 +240,7 @@
@JsonIgnore
@GremlinGroovy("_().in('flow').out('switch')")
- public Iterable<IDeviceObject> getSwitches();
+ public Iterable<ISwitchObject> getSwitches();
}
public interface IFlowEntry extends IBaseObject {
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/GraphDBUtils.java b/src/main/java/net/onrc/onos/util/GraphDBUtils.java
index 7283d09..c43434f 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,13 @@
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.frames.FramedGraph;
+import com.tinkerpop.frames.FramedVertexIterable;
+import com.tinkerpop.gremlin.java.GremlinPipeline;
+
public class GraphDBUtils implements IDBUtils {
@Override
@@ -68,7 +69,7 @@
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);
+ FramedVertexIterable<IPortObject> r = new FramedVertexIterable<IPortObject>(conn.getFramedGraph(), (Iterable) pipe, IPortObject.class);
return r.iterator().hasNext() ? r.iterator().next() : null;
}
@@ -88,8 +89,9 @@
@Override
public void removePort(GraphDBConnection conn, IPortObject port) {
- FramedGraph<TitanGraph> fg = conn.getFramedGraph();
- fg.removeVertex(port.asVertex());
+// FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ EventGraph<TitanGraph> eg = conn.getEventGraph();
+ eg.removeVertex(port.asVertex());
}
@Override
@@ -135,7 +137,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;
}