Merged with the latest master
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/IDeviceStorage.java b/src/main/java/net/onrc/onos/ofcontroller/core/IDeviceStorage.java
new file mode 100644
index 0000000..7310d8c
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/IDeviceStorage.java
@@ -0,0 +1,15 @@
+package net.onrc.onos.ofcontroller.core;
+
+import net.floodlightcontroller.devicemanager.IDevice;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
+
+public interface IDeviceStorage extends INetMapStorage {
+
+ public IDeviceObject addDevice(IDevice device);
+ public IDeviceObject updateDevice(IDevice device);
+ public void removeDevice(IDevice device);
+ public IDeviceObject getDeviceByMac(String mac);
+ public IDeviceObject getDeviceByIP(String ip);
+ public void changeDeviceAttachments(IDevice device);
+ public void changeDeviceIPv4Address(IDevice device);
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/ILinkStorage.java b/src/main/java/net/onrc/onos/ofcontroller/core/ILinkStorage.java
new file mode 100644
index 0000000..b56cfef
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/ILinkStorage.java
@@ -0,0 +1,53 @@
+package net.onrc.onos.ofcontroller.core;
+
+import java.util.List;
+
+import net.floodlightcontroller.routing.Link;
+import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
+
+public interface ILinkStorage extends INetMapStorage {
+
+ /*
+ * Link creation
+ */
+ public void update(Link link, DM_OPERATION op);
+ public void update(Link link, LinkInfo linkinfo, DM_OPERATION op);
+ public void update(List<Link> List, DM_OPERATION op);
+
+ /*
+ * Add Linkinfo
+ */
+ public void updateLink (Link link, LinkInfo linkinfo, DM_OPERATION op);
+
+ /*
+ * Delete a single link
+ */
+ public void deleteLink(Link link);
+
+ /*
+ * Delete links associated with dpid and port
+ * If only dpid is used, All links associated for switch are removed
+ * Useful for port up/down and also switch join/remove events
+ */
+ public void deleteLinksOnPort(Long dpid, short port);
+
+ /*
+ * Delete a list of links
+ */
+ public void deleteLinks(List<Link> links);
+
+ /*
+ * Get Links from Storage
+ * If dpid and port both are specified specific link is retrieved
+ * If only dpid is set all links associated with Switch are retrieved
+ */
+ public List<Link> getLinks(Long dpid, short port);
+ public List<Link> getLinks(String dpid);
+ public List<Link> getActiveLinks();
+
+ /*
+ * Init with Storage conf
+ */
+ public void init(String conf);
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
index 3cfa190..fc1c32f 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
@@ -1,7 +1,6 @@
package net.onrc.onos.ofcontroller.core;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.onrc.onos.ofcontroller.flowcache.web.DatapathSummarySerializer;
+import net.onrc.onos.ofcontroller.flowmanager.web.DatapathSummarySerializer;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonProperty;
@@ -49,7 +48,7 @@
// Requires Frames 2.3.0
@JsonIgnore
- @GremlinGroovy("_().out('on').has('number',port_num)")
+ @GremlinGroovy("it.out('on').has('number',port_num)")
public IPortObject getPort(@GremlinParam("port_num") final short port_num);
@Adjacency(label="on")
@@ -59,7 +58,7 @@
public void removePort(final IPortObject port);
@JsonIgnore
- @GremlinGroovy("_().out('on').out('host')")
+ @GremlinGroovy("it.out('on').out('host')")
public Iterable<IDeviceObject> getDevices();
@JsonIgnore
@@ -92,6 +91,7 @@
public void setPortState(Integer s);
@JsonIgnore
+// @GremlinGroovy("it.in('on')")
@Adjacency(label="on",direction = Direction.IN)
public ISwitchObject getSwitch();
@@ -155,7 +155,7 @@
public void removeHostPort(final IPortObject port);
@JsonIgnore
- @GremlinGroovy("_().in('host').in('on')")
+ @GremlinGroovy("it.in('host').in('on')")
public Iterable<ISwitchObject> getSwitch();
/* @JsonProperty("dpid")
@@ -268,7 +268,7 @@
public void setMatchDstIPv4Net(String matchDstIPv4Net);
@JsonIgnore
- @GremlinGroovy("_().in('flow').out('switch')")
+ @GremlinGroovy("it.in('flow').out('switch')")
public Iterable<ISwitchObject> getSwitches();
@JsonIgnore
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/IOFSwitchPortListener.java b/src/main/java/net/onrc/onos/ofcontroller/core/IOFSwitchPortListener.java
new file mode 100644
index 0000000..5deae69
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/IOFSwitchPortListener.java
@@ -0,0 +1,26 @@
+/**
+ *
+ */
+package net.onrc.onos.ofcontroller.core;
+
+import org.openflow.protocol.OFPhysicalPort;
+
+import net.floodlightcontroller.core.IOFSwitchListener;
+
+/**
+ * @author y-higuchi
+ *
+ */
+public interface IOFSwitchPortListener extends IOFSwitchListener {
+
+ /**
+ * Fired when ports on a switch area added
+ */
+ public void switchPortAdded(Long switchId, OFPhysicalPort port);
+
+ /**
+ * Fired when ports on a switch area removed
+ */
+ public void switchPortRemoved(Long switchId, OFPhysicalPort port);
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/IOnosRemoteSwitch.java b/src/main/java/net/onrc/onos/ofcontroller/core/IOnosRemoteSwitch.java
new file mode 100644
index 0000000..c9b0e2f
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/IOnosRemoteSwitch.java
@@ -0,0 +1,20 @@
+/**
+ *
+ */
+package net.onrc.onos.ofcontroller.core;
+
+import net.floodlightcontroller.core.IOFSwitch;
+
+/**
+ * @author y-higuchi
+ *
+ */
+public interface IOnosRemoteSwitch extends IOFSwitch {
+
+ /**
+ * Setup an unconnected switch with the info required.
+ * @param dpid of the switch
+ */
+ public void setupRemoteSwitch(Long dpid);
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/Main.java b/src/main/java/net/onrc/onos/ofcontroller/core/Main.java
new file mode 100644
index 0000000..a80ac36
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/Main.java
@@ -0,0 +1,50 @@
+package net.onrc.onos.ofcontroller.core;
+
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+
+import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.internal.CmdLineSettings;
+import net.floodlightcontroller.core.module.FloodlightModuleException;
+import net.floodlightcontroller.core.module.FloodlightModuleLoader;
+import net.floodlightcontroller.core.module.IFloodlightModuleContext;
+import net.floodlightcontroller.restserver.IRestApiService;
+
+/**
+ * Host for the ONOS main method
+ * @author alexreimers
+ */
+public class Main {
+
+ /**
+ * Main method to load configuration and modules
+ * @param args
+ * @throws FloodlightModuleException
+ */
+ public static void main(String[] args) throws FloodlightModuleException {
+ // Setup logger
+ System.setProperty("org.restlet.engine.loggerFacadeClass",
+ "org.restlet.ext.slf4j.Slf4jLoggerFacade");
+
+ CmdLineSettings settings = new CmdLineSettings();
+ CmdLineParser parser = new CmdLineParser(settings);
+ try {
+ parser.parseArgument(args);
+ } catch (CmdLineException e) {
+ parser.printUsage(System.out);
+ System.exit(1);
+ }
+
+ // Load modules
+ FloodlightModuleLoader fml = new FloodlightModuleLoader();
+ IFloodlightModuleContext moduleContext = fml.loadModulesFromConfig(settings.getModuleFile());
+ // Run REST server
+ IRestApiService restApi = moduleContext.getServiceImpl(IRestApiService.class);
+ restApi.run();
+ // Run the main floodlight module
+ IFloodlightProviderService controller =
+ moduleContext.getServiceImpl(IFloodlightProviderService.class);
+ // This call blocks, it has to be the last line in the main
+ controller.run();
+ }
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java
new file mode 100644
index 0000000..dcb28ce
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java
@@ -0,0 +1,264 @@
+package net.onrc.onos.ofcontroller.core.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.openflow.util.HexString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Lists;
+import com.thinkaurelius.titan.core.TitanException;
+import net.floodlightcontroller.devicemanager.IDevice;
+import net.floodlightcontroller.devicemanager.SwitchPort;
+import net.floodlightcontroller.packet.IPv4;
+import net.onrc.onos.ofcontroller.core.IDeviceStorage;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
+import net.onrc.onos.util.GraphDBOperation;
+
+/**
+ * This is the class for storing the information of devices into CassandraDB
+ * @author Pankaj
+ */
+public class DeviceStorageImpl implements IDeviceStorage {
+
+ private GraphDBOperation ope;
+ protected static Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
+
+ /***
+ * Initialize function. Before you use this class, please call this method
+ * @param conf configuration file for Cassandra DB
+ */
+ @Override
+ public void init(String conf) {
+ try{
+ ope = new GraphDBOperation(conf);
+ } catch(Exception e) {
+ log.error(e.getMessage());
+ }
+ }
+
+ /***
+ * Finalize/close function. After you use this class, please call this method.
+ * It will close the DB connection.
+ */
+ @Override
+ public void close() {
+ ope.close();
+ }
+
+ /***
+ * Finalize/close function. After you use this class, please call this method.
+ * It will close the DB connection. This is for Java gabage collection.
+ */
+ @Override
+ public void finalize() {
+ close();
+ }
+
+ /***
+ * This function is for adding the device into the DB.
+ * @param device The device you want to add into the DB.
+ * @return IDeviceObject which was added in the DB.
+ */
+ @Override
+ public IDeviceObject addDevice(IDevice device) {
+ IDeviceObject obj = null;
+ try {
+ if ((obj = ope.searchDevice(device.getMACAddressString())) != null) {
+ log.debug("Adding device {}: found existing device",device.getMACAddressString());
+ } else {
+ obj = ope.newDevice();
+ log.debug("Adding device {}: creating new device",device.getMACAddressString());
+ }
+ changeDeviceAttachments(device, obj);
+
+ String multiIntString = "";
+ for(Integer intValue : device.getIPv4Addresses()) {
+ if (multiIntString == null || multiIntString.isEmpty()){
+ multiIntString = IPv4.fromIPv4Address(intValue);
+ multiIntString = "[" + IPv4.fromIPv4Address(intValue);
+ }else{
+ multiIntString += "," + IPv4.fromIPv4Address(intValue);
+ }
+ }
+
+ if(multiIntString.toString() != null && !multiIntString.toString().isEmpty()){
+ obj.setIPAddress(multiIntString + "]");
+ }
+
+ obj.setMACAddress(device.getMACAddressString());
+ obj.setType("device");
+ obj.setState("ACTIVE");
+ ope.commit();
+
+ log.debug("Adding device {}",device.getMACAddressString());
+ } catch (Exception e) {
+ ope.rollback();
+ log.error(":addDevice mac:{} failed", device.getMACAddressString());
+ obj = null;
+ }
+ return obj;
+ }
+
+ /***
+ * This function is for updating the Device properties.
+ * @param device The device you want to add into the DB.
+ * @return IDeviceObject which was added in the DB.
+ */
+ @Override
+ public IDeviceObject updateDevice(IDevice device) {
+ return addDevice(device);
+ }
+
+ /***
+ * This function is for removing the Device from the DB.
+ * @param device The device you want to delete from the DB.
+ */
+ @Override
+ public void removeDevice(IDevice device) {
+ IDeviceObject dev;
+ try {
+ if ((dev = ope.searchDevice(device.getMACAddressString())) != null) {
+ ope.removeDevice(dev);
+ ope.commit();
+ log.error("DeviceStorage:removeDevice mac:{} done", device.getMACAddressString());
+ }
+ } catch (Exception e) {
+ ope.rollback();
+ log.error("DeviceStorage:removeDevice mac:{} failed", device.getMACAddressString());
+ }
+ }
+
+ /***
+ * This function is for getting the Device from the DB by Mac address of the device.
+ * @param mac The device mac address you want to get from the DB.
+ * @return IDeviceObject you want to get.
+ */
+ @Override
+ public IDeviceObject getDeviceByMac(String mac) {
+ return ope.searchDevice(mac);
+ }
+
+ /***
+ * This function is for getting the Device from the DB by IP address of the device.
+ * @param ip The device ip address you want to get from the DB.
+ * @return IDeviceObject you want to get.
+ */
+ @Override
+ public IDeviceObject getDeviceByIP(String ip) {
+ try
+ {
+ for(IDeviceObject dev : ope.getDevices()){
+ String ips;
+ if((ips = dev.getIPAddress()) != null){
+ String nw_addr_wob = ips.replace("[", "").replace("]", "");
+ ArrayList<String> iplists = Lists.newArrayList(nw_addr_wob.split(","));
+ if(iplists.contains(ip)){
+ return dev;
+ }
+ }
+ }
+ return null;
+ }
+ catch (Exception e)
+ {
+ log.error("DeviceStorage:getDeviceByIP:{} failed");
+ return null;
+ }
+ }
+
+ /***
+ * This function is for changing the Device attachment point.
+ * @param device The device you want change the attachment point
+ */
+ @Override
+ public void changeDeviceAttachments(IDevice device) {
+ IDeviceObject obj = null;
+ try {
+ if ((obj = ope.searchDevice(device.getMACAddressString())) != null) {
+ log.debug("Changing device ports {}: found existing device",device.getMACAddressString());
+ changeDeviceAttachments(device, obj);
+ ope.commit();
+ } else {
+ log.debug("failed to search device...now adding {}",device.getMACAddressString());
+ addDevice(device);
+ }
+ } catch (Exception e) {
+ ope.rollback();
+ log.error(":addDevice mac:{} failed", device.getMACAddressString());
+ }
+ }
+
+ /***
+ * This function is for changing the Device attachment point.
+ * @param device The new device you want change the attachment point
+ * @param obj The old device IDeviceObject that is going to change the attachment point.
+ */
+ public void changeDeviceAttachments(IDevice device, IDeviceObject obj) {
+ SwitchPort[] attachmentPoints = device.getAttachmentPoints();
+ List<IPortObject> attachedPorts = Lists.newArrayList(obj.getAttachedPorts());
+
+ for (SwitchPort ap : attachmentPoints) {
+ //Check weather there is the port
+ IPortObject port = ope.searchPort( HexString.toHexString(ap.getSwitchDPID()),
+ (short) ap.getPort());
+ log.debug("New Switch Port is {},{}", HexString.toHexString(ap.getSwitchDPID()),(short) ap.getPort());
+
+ if(port != null){
+ if(attachedPorts.contains(port))
+ {
+ log.debug("This is the port you already attached {}: do nothing",device.getMACAddressString());
+ //This port will be remained, so remove from the removed port lists.
+ attachedPorts.remove(port);
+ } else {
+ log.debug("Adding device {}: attaching to port",device.getMACAddressString());
+ port.setDevice(obj);
+ }
+
+ log.debug("port number is {}", port.getNumber().toString());
+ log.debug("port desc is {}", port.getDesc());
+ }
+ }
+
+ for (IPortObject port: attachedPorts) {
+ log.debug("Detouching the device {}: detouching from port",device.getMACAddressString());
+ port.removeDevice(obj);
+ }
+ }
+
+ /***
+ * This function is for changing the Device IPv4 address.
+ * @param device The new device you want change the ipaddress
+ */
+ @Override
+ public void changeDeviceIPv4Address(IDevice device) {
+ IDeviceObject obj;
+ try {
+ if ((obj = ope.searchDevice(device.getMACAddressString())) != null) {
+
+ String multiIntString = "";
+ for(Integer intValue : device.getIPv4Addresses()){
+ if (multiIntString == null || multiIntString.isEmpty()){
+ multiIntString = "[" + IPv4.fromIPv4Address(intValue);
+ } else {
+ multiIntString += "," + IPv4.fromIPv4Address(intValue);
+ }
+ }
+
+ if(multiIntString != null && !multiIntString.isEmpty()){
+ obj.setIPAddress(multiIntString + "]");
+ }
+
+ ope.commit();
+ } else {
+ log.error(":changeDeviceIPv4Address mac:{} failed", device.getMACAddressString());
+ }
+ } catch (TitanException e) {
+ ope.rollback();
+ log.error(":changeDeviceIPv4Address mac:{} failed due to exception {}", device.getMACAddressString(),e);
+ }
+ }
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java
new file mode 100644
index 0000000..b33591e
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java
@@ -0,0 +1,347 @@
+package net.onrc.onos.ofcontroller.core.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.floodlightcontroller.routing.Link;
+import net.onrc.onos.ofcontroller.core.ILinkStorage;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
+import net.onrc.onos.util.GraphDBOperation;
+
+import org.openflow.util.HexString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.thinkaurelius.titan.core.TitanException;
+import com.tinkerpop.blueprints.Direction;
+import com.tinkerpop.blueprints.Edge;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.gremlin.java.GremlinPipeline;
+import com.tinkerpop.pipes.PipeFunction;
+import com.tinkerpop.pipes.transform.PathPipe;
+
+public class LinkStorageImpl implements ILinkStorage {
+
+ protected static Logger log = LoggerFactory.getLogger(LinkStorageImpl.class);
+ protected GraphDBOperation dbop;
+
+ /**
+ * Update a record in the LinkStorage in a way provided by op.
+ * @param link Record of a link to be updated.
+ * @param op Operation to be done.
+ */
+ @Override
+ public void update(Link link, DM_OPERATION op) {
+ update(link, (LinkInfo)null, op);
+ }
+
+ /**
+ * Update multiple records in the LinkStorage in a way provided by op.
+ * @param links List of records to be updated.
+ * @param op Operation to be done.
+ */
+ @Override
+ public void update(List<Link> links, DM_OPERATION op) {
+ for (Link lt: links) {
+ update(lt, (LinkInfo)null, op);
+ }
+ }
+
+ /**
+ * Update a record of link with meta-information in the LinkStorage in a way provided by op.
+ * @param link Record of a link to update.
+ * @param linkinfo Meta-information of a link to be updated.
+ * @param op Operation to be done.
+ */
+ @Override
+ public void update(Link link, LinkInfo linkinfo, DM_OPERATION op) {
+ switch (op) {
+ case UPDATE:
+ case CREATE:
+ case INSERT:
+ updateLink(link, linkinfo, op);
+ break;
+ case DELETE:
+ deleteLink(link);
+ break;
+ }
+ }
+
+ /**
+ * Perform INSERT/CREATE/UPDATE operation to update the LinkStorage.
+ * @param lt Record of a link to be updated.
+ * @param linkinfo Meta-information of a link to be updated.
+ * @param op Operation to be done. (only INSERT/CREATE/UPDATE is acceptable)
+ */
+ public void updateLink(Link lt, LinkInfo linkinfo, DM_OPERATION op) {
+ IPortObject vportSrc = null, vportDst = null;
+
+ log.trace("updateLink(): op {} {} {}", new Object[]{op, lt, linkinfo});
+
+ try {
+ // get source port vertex
+ String dpid = HexString.toHexString(lt.getSrc());
+ short port = lt.getSrcPort();
+ vportSrc = dbop.searchPort(dpid, port);
+
+ // get dest port vertex
+ dpid = HexString.toHexString(lt.getDst());
+ port = lt.getDstPort();
+ vportDst = dbop.searchPort(dpid, port);
+
+ if (vportSrc != null && vportDst != null) {
+ // check if the link exists
+
+ Iterable<IPortObject> currPorts = vportSrc.getLinkedPorts();
+ List<IPortObject> currLinks = new ArrayList<IPortObject>();
+ for (IPortObject V : currPorts) {
+ currLinks.add(V);
+ }
+
+ if (currLinks.contains(vportDst)) {
+ // TODO: update linkinfo
+ if (op.equals(DM_OPERATION.INSERT) || op.equals(DM_OPERATION.CREATE)) {
+ log.debug("addOrUpdateLink(): failed link exists {} {} src {} dst {}",
+ new Object[]{op, lt, vportSrc, vportDst});
+ }
+ } else {
+ vportSrc.setLinkPort(vportDst);
+
+ dbop.commit();
+ log.debug("updateLink(): link added {} {} src {} dst {}", new Object[]{op, lt, vportSrc, vportDst});
+ }
+ } else {
+ log.error("updateLink(): failed invalid vertices {} {} src {} dst {}", new Object[]{op, lt, vportSrc, vportDst});
+ dbop.rollback();
+ }
+ } catch (TitanException e) {
+ /*
+ * retry till we succeed?
+ */
+ e.printStackTrace();
+ log.error("updateLink(): titan exception {} {} {}", new Object[]{op, lt, e.toString()});
+ }
+ }
+
+ /**
+ * Delete multiple records in the LinkStorage.
+ * @param links List of records to be deleted.
+ */
+ @Override
+ public void deleteLinks(List<Link> links) {
+
+ for (Link lt : links) {
+ deleteLink(lt);
+ }
+ }
+
+ /**
+ * Delete a record in the LinkStorage.
+ * @param link Record to be deleted.
+ */
+ @Override
+ public void deleteLink(Link lt) {
+ IPortObject vportSrc = null, vportDst = null;
+ int count = 0;
+
+ log.debug("deleteLink(): {}", lt);
+
+ try {
+ // get source port vertex
+ String dpid = HexString.toHexString(lt.getSrc());
+ short port = lt.getSrcPort();
+ vportSrc = dbop.searchPort(dpid, port);
+
+ // get dst port vertex
+ dpid = HexString.toHexString(lt.getDst());
+ port = lt.getDstPort();
+ vportDst = dbop.searchPort(dpid, port);
+ // FIXME: This needs to remove all edges
+
+ if (vportSrc != null && vportDst != null) {
+
+ /* 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++;
+ }
+ }*/
+ vportSrc.removeLink(vportDst);
+ dbop.commit();
+ 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});
+ dbop.rollback();
+ }
+
+ } catch (TitanException e) {
+ /*
+ * retry till we succeed?
+ */
+ log.error("deleteLink(): titan exception {} {}", new Object[]{lt, e.toString()});
+ dbop.rollback();
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Get list of all links connected to the port specified by given DPID and port number.
+ * @param dpid DPID of desired port.
+ * @param port Port number of desired port.
+ * @return List of links. Empty list if no port was found.
+ */
+ // TODO: Fix me
+ @Override
+ public List<Link> getLinks(Long dpid, short port) {
+ List<Link> links = new ArrayList<Link>();
+
+ IPortObject srcPort = dbop.searchPort(HexString.toHexString(dpid), port);
+ ISwitchObject srcSw = srcPort.getSwitch();
+
+ if(srcSw != null) {
+ for(IPortObject dstPort : srcPort.getLinkedPorts()) {
+ ISwitchObject dstSw = dstPort.getSwitch();
+ Link link = new Link(HexString.toLong(srcSw.getDPID()),
+ srcPort.getNumber(),
+ HexString.toLong(dstSw.getDPID()),
+ dstPort.getNumber());
+
+ links.add(link);
+ }
+ }
+
+ return links;
+ }
+
+ /**
+ * Initialize the object. Open LinkStorage using given configuration file.
+ * @param conf Path (absolute path for now) to configuration file.
+ */
+ @Override
+ public void init(String conf) {
+ //TODO extract the DB location from properties
+ this.dbop = new GraphDBOperation(conf);
+ }
+
+ /**
+ * Delete records of the links connected to the port specified by given DPID and port number.
+ * @param dpid DPID of desired port.
+ * @param port Port number of desired port.
+ */
+ // TODO: Fix me
+ @Override
+ public void deleteLinksOnPort(Long dpid, short port) {
+ List<Link> linksToDelete = getLinks(dpid,port);
+
+ for(Link l : linksToDelete) {
+ deleteLink(l);
+ }
+ }
+
+ /**
+ * Get list of all links connected to the switch specified by given DPID.
+ * @param dpid DPID of desired switch.
+ * @return List of links. Empty list if no port was found.
+ */
+ // TODO: Fix me
+ @Override
+ public List<Link> getLinks(String dpid) {
+ List<Link> links = new ArrayList<Link>();
+
+ ISwitchObject srcSw = dbop.searchSwitch(dpid);
+
+ if(srcSw != null) {
+ for(IPortObject srcPort : srcSw.getPorts()) {
+ for(IPortObject dstPort : srcPort.getLinkedPorts()) {
+ ISwitchObject dstSw = dstPort.getSwitch();
+ if(dstSw != null) {
+ Link link = new Link(HexString.toLong(srcSw.getDPID()),
+ srcPort.getNumber(),
+ HexString.toLong(dstSw.getDPID()),
+ dstPort.getNumber());
+ links.add(link);
+ }
+ }
+ }
+ }
+
+ return links;
+ }
+
+ /**
+ * Get list of all links whose state is ACTIVE.
+ * @return List of active links. Empty list if no port was found.
+ */
+ public List<Link> getActiveLinks() {
+ Iterable<ISwitchObject> switches = dbop.getActiveSwitches();
+
+ List<Link> links = new ArrayList<Link>();
+
+ for (ISwitchObject srcSw : switches) {
+ for(IPortObject srcPort : srcSw.getPorts()) {
+ for(IPortObject dstPort : srcPort.getLinkedPorts()) {
+ ISwitchObject dstSw = dstPort.getSwitch();
+
+ if(dstSw != null && dstSw.getState().equals("ACTIVE")) {
+ links.add(new Link(HexString.toLong(srcSw.getDPID()),
+ srcPort.getNumber(),
+ HexString.toLong(dstSw.getDPID()),
+ dstPort.getNumber()));
+ }
+ }
+ }
+ }
+
+ return links;
+ }
+
+ static class ExtractLink implements PipeFunction<PathPipe<Vertex>, Link> {
+
+ @Override
+ public Link compute(PathPipe<Vertex> pipe ) {
+ // TODO Auto-generated method stub
+ long s_dpid = 0;
+ long d_dpid = 0;
+ short s_port = 0;
+ short d_port = 0;
+ List<Vertex> V = new ArrayList<Vertex>();
+ V = pipe.next();
+ Vertex src_sw = V.get(0);
+ Vertex dest_sw = V.get(3);
+ Vertex src_port = V.get(1);
+ Vertex dest_port = V.get(2);
+ s_dpid = HexString.toLong((String) src_sw.getProperty("dpid"));
+ d_dpid = HexString.toLong((String) dest_sw.getProperty("dpid"));
+ s_port = (Short) src_port.getProperty("number");
+ d_port = (Short) dest_port.getProperty("number");
+
+ Link l = new Link(s_dpid,s_port,d_dpid,d_port);
+
+ return l;
+ }
+ }
+
+ /**
+ * Finalize the object.
+ */
+ public void finalize() {
+ close();
+ }
+
+ /**
+ * Close LinkStorage.
+ */
+ @Override
+ public void close() {
+ // TODO Auto-generated method stub
+// graph.shutdown();
+ }
+
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java
index ec0c993..b12ccfa 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java
@@ -207,4 +207,4 @@
log.info("SwitchStorage:deletePort dpid:{} port:{} failed", dpid, port);
}
}
-}
+}
\ No newline at end of file
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoLinkServiceImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoLinkServiceImpl.java
new file mode 100644
index 0000000..1222ff3
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoLinkServiceImpl.java
@@ -0,0 +1,77 @@
+package net.onrc.onos.ofcontroller.core.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.floodlightcontroller.routing.Link;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyService.ITopoLinkService;
+import net.onrc.onos.ofcontroller.core.internal.LinkStorageImpl.ExtractLink;
+import net.onrc.onos.util.GraphDBOperation;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.gremlin.java.GremlinPipeline;
+
+public class TopoLinkServiceImpl implements ITopoLinkService {
+
+ protected GraphDBOperation op;
+ protected static Logger log = LoggerFactory.getLogger(TopoLinkServiceImpl.class);
+
+ public void finalize() {
+ close();
+ }
+
+ @Override
+ public void close() {
+ op.close();
+ }
+
+ @Override
+ public List<Link> getActiveLinks() {
+ // TODO Auto-generated method stub
+ op = new GraphDBOperation("");
+ op.commit(); //Commit to ensure we see latest data
+ Iterable<ISwitchObject> switches = op.getActiveSwitches();
+ List<Link> links = new ArrayList<Link>();
+ for (ISwitchObject sw : switches) {
+ GremlinPipeline<Vertex, Link> pipe = new GremlinPipeline<Vertex, Link>();
+ ExtractLink extractor = new ExtractLink();
+
+ pipe.start(sw.asVertex());
+ pipe.enablePath(true);
+ pipe.out("on").out("link").in("on").path().step(extractor);
+
+ while (pipe.hasNext() ) {
+ Link l = pipe.next();
+ links.add(l);
+ }
+
+ }
+ op.commit();
+ return links;
+ }
+
+ @Override
+ public List<Link> getLinksOnSwitch(String dpid) {
+ // TODO Auto-generated method stub
+ List<Link> links = new ArrayList<Link>();
+ ISwitchObject sw = op.searchSwitch(dpid);
+ GremlinPipeline<Vertex, Link> pipe = new GremlinPipeline<Vertex, Link>();
+ ExtractLink extractor = new ExtractLink();
+
+ pipe.start(sw.asVertex());
+ pipe.enablePath(true);
+ pipe.out("on").out("link").in("on").path().step(extractor);
+
+ while (pipe.hasNext() ) {
+ Link l = pipe.next();
+ links.add(l);
+ }
+ return links;
+
+ }
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoSwitchServiceImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoSwitchServiceImpl.java
index e279422..c1659fb 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoSwitchServiceImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/TopoSwitchServiceImpl.java
@@ -3,7 +3,6 @@
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
import net.onrc.onos.ofcontroller.core.INetMapTopologyService.ITopoSwitchService;
-import net.onrc.onos.util.GraphDBConnection;
import net.onrc.onos.util.GraphDBOperation;
import org.slf4j.Logger;
@@ -15,7 +14,7 @@
protected static Logger log = LoggerFactory.getLogger(TopoSwitchServiceImpl.class);
public TopoSwitchServiceImpl(String conf) {
- op = new GraphDBOperation(GraphDBConnection.getInstance(conf));
+ op = new GraphDBOperation(conf);
}
public TopoSwitchServiceImpl() {
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/web/TopoLinksResource.java b/src/main/java/net/onrc/onos/ofcontroller/core/web/TopoLinksResource.java
new file mode 100644
index 0000000..327c110
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/web/TopoLinksResource.java
@@ -0,0 +1,20 @@
+package net.onrc.onos.ofcontroller.core.web;
+
+import java.util.List;
+import net.floodlightcontroller.routing.Link;
+import net.onrc.onos.ofcontroller.core.internal.TopoLinkServiceImpl;
+
+import org.restlet.resource.Get;
+import org.restlet.resource.ServerResource;
+
+public class TopoLinksResource extends ServerResource {
+
+ @Get("json")
+ public List<Link> retrieve() {
+ TopoLinkServiceImpl impl = new TopoLinkServiceImpl();
+
+ List<Link> retval = impl.getActiveLinks();
+ return retval;
+ }
+
+}