Initial impl for NetMap service
diff --git a/src/main/java/net/floodlightcontroller/core/INetMapService.java b/src/main/java/net/floodlightcontroller/core/INetMapService.java
new file mode 100644
index 0000000..fcc542a
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/core/INetMapService.java
@@ -0,0 +1,5 @@
+package net.floodlightcontroller.core;
+
+public interface INetMapService {
+
+}
diff --git a/src/main/java/net/floodlightcontroller/core/INetMapTopologyService.java b/src/main/java/net/floodlightcontroller/core/INetMapTopologyService.java
new file mode 100644
index 0000000..da00e0f
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/core/INetMapTopologyService.java
@@ -0,0 +1,36 @@
+package net.floodlightcontroller.core;
+
+import java.util.List;
+
+import net.floodlightcontroller.routing.Link;
+import net.floodlightcontroller.topology.NodePortTuple;
+
+public interface INetMapTopologyService extends INetMapService {
+
+ public interface ITopoSwitchService {
+ List<String> GetActiveSwitches();
+ List<String> GetAllSwitches();
+ List<String> GetInactiveSwitches();
+ List<String> GetPortsOnSwitch(String dpid);
+ }
+
+ public interface ITopoLinkService {
+ List<Link> GetActiveLinks();
+ List<Link> GetLinksOnSwitch(String dpid);
+ }
+ public interface ITopoDeviceService {
+ List<Link> GetActiveDevices();
+ List<Link> GetDevicesOnSwitch(String dpid);
+ }
+
+ public interface ITopoRouteService {
+ List<NodePortTuple> GetShortestpath(NodePortTuple src, NodePortTuple dest);
+ Boolean RouteExists(NodePortTuple src, NodePortTuple dest);
+ }
+
+ public interface ITopoFlowService {
+ Boolean FlowExists(NodePortTuple src, NodePortTuple dest);
+ List<NodePortTuple> GetShortestFlowPath(NodePortTuple src, NodePortTuple dest);
+
+ }
+}
diff --git a/src/main/java/net/floodlightcontroller/core/ISwitchStorage.java b/src/main/java/net/floodlightcontroller/core/ISwitchStorage.java
index 082995f..8060c4d 100644
--- a/src/main/java/net/floodlightcontroller/core/ISwitchStorage.java
+++ b/src/main/java/net/floodlightcontroller/core/ISwitchStorage.java
@@ -50,9 +50,13 @@
public void deletePort(String dpid, String portName);
public List<String> getActiveSwitches();
+ public List<String> getAllSwitches();
+ public List<String> getInactiveSwitches();
/*
* Initialize
*/
public void init(String conf);
+
+
}
diff --git a/src/main/java/net/floodlightcontroller/core/internal/SwitchStorageImpl.java b/src/main/java/net/floodlightcontroller/core/internal/SwitchStorageImpl.java
index 1be6e44..be33659 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/SwitchStorageImpl.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/SwitchStorageImpl.java
@@ -1,5 +1,6 @@
package net.floodlightcontroller.core.internal;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
@@ -198,8 +199,14 @@
@Override
public List<String> getActiveSwitches() {
- // TODO Auto-generated method stub
- return null;
+ // TODO Add unit test
+ List<String> switches = new ArrayList<String>();
+ for (Vertex V : graph.getVertices("type","switch")) {
+ if (V.getProperty("state").equals(SwitchState.ACTIVE.toString())) {
+ switches.add((String) V.getProperty("dpid"));
+ }
+ }
+ return switches;
}
@Override
@@ -219,4 +226,27 @@
}
}
+ @Override
+ public List<String> getAllSwitches() {
+ // TODO Auto-generated method stub
+ List<String> switches = new ArrayList<String>();
+ for (Vertex V : graph.getVertices("type","switch")) {
+ switches.add((String) V.getProperty("dpid"));
+ }
+ return switches;
+ }
+
+ @Override
+ public List<String> getInactiveSwitches() {
+ // TODO Auto-generated method stub
+ List<String> switches = new ArrayList<String>();
+ for (Vertex V : graph.getVertices("type","switch")) {
+ if (V.getProperty("state").equals(SwitchState.INACTIVE.toString())) {
+ switches.add((String) V.getProperty("dpid"));
+ }
+ }
+ return switches;
+ }
+
+
}
diff --git a/src/main/java/net/floodlightcontroller/core/internal/SwitchStorageImplStubs.java b/src/main/java/net/floodlightcontroller/core/internal/SwitchStorageImplStubs.java
index c281141..88f94db 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/SwitchStorageImplStubs.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/SwitchStorageImplStubs.java
@@ -111,4 +111,16 @@
}
+ @Override
+ public List<String> getAllSwitches() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public List<String> getInactiveSwitches() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
}
diff --git a/src/main/java/net/floodlightcontroller/core/internal/TopoSwitchServiceImpl.java b/src/main/java/net/floodlightcontroller/core/internal/TopoSwitchServiceImpl.java
new file mode 100644
index 0000000..99f291d
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/core/internal/TopoSwitchServiceImpl.java
@@ -0,0 +1,45 @@
+package net.floodlightcontroller.core.internal;
+
+import java.util.List;
+
+import net.floodlightcontroller.core.INetMapTopologyService.ITopoSwitchService;
+
+public class TopoSwitchServiceImpl implements ITopoSwitchService {
+
+ ThreadLocal<SwitchStorageImpl> store = new ThreadLocal<SwitchStorageImpl>() {
+ @Override
+ protected SwitchStorageImpl initialValue() {
+ SwitchStorageImpl swStore = new SwitchStorageImpl();
+ //TODO: Get the file path from global properties
+ swStore.init("/tmp/cassandra.titan");
+ return swStore;
+ }
+ };
+
+ SwitchStorageImpl swStore = store.get();
+
+ @Override
+ public List<String> GetActiveSwitches() {
+ // TODO Auto-generated method stub
+ return swStore.getActiveSwitches();
+ }
+
+ @Override
+ public List<String> GetAllSwitches() {
+ // TODO Auto-generated method stub
+ return swStore.getAllSwitches();
+ }
+
+ @Override
+ public List<String> GetInactiveSwitches() {
+ // TODO Auto-generated method stub
+ return swStore.getInactiveSwitches();
+ }
+
+ @Override
+ public List<String> GetPortsOnSwitch(String dpid) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java b/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
index 45ef6e9..0c41259 100644
--- a/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
+++ b/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
@@ -60,6 +60,7 @@
router.attach("/role/json", ControllerRoleResource.class);
router.attach("/health/json", HealthCheckResource.class);
router.attach("/system/uptime/json", SystemUptimeResource.class);
+ router.attach("/topology/switches/{filter}/json", TopoSwitchesResource.class);
return router;
}
}
diff --git a/src/main/java/net/floodlightcontroller/core/web/TopoSwitchesResource.java b/src/main/java/net/floodlightcontroller/core/web/TopoSwitchesResource.java
new file mode 100644
index 0000000..a73b0b4
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/core/web/TopoSwitchesResource.java
@@ -0,0 +1,27 @@
+package net.floodlightcontroller.core.web;
+
+import java.util.Iterator;
+
+import net.floodlightcontroller.core.internal.TopoSwitchServiceImpl;
+
+import org.restlet.resource.Get;
+import org.restlet.resource.ServerResource;
+
+public class TopoSwitchesResource extends ServerResource {
+
+ @Get("json")
+ public Iterator<String> retrieve() {
+ TopoSwitchServiceImpl impl = new TopoSwitchServiceImpl();
+
+ String filter = (String) getRequestAttributes().get("filter");
+
+ if (filter.equals("active")) {
+ return (Iterator<String>) impl.GetActiveSwitches().iterator();
+ }
+ if (filter.equals("inactive")) {
+ return (Iterator<String>) impl.GetInactiveSwitches().iterator();
+ }
+ return (Iterator<String>) impl.GetAllSwitches().iterator();
+ }
+
+}
diff --git a/web/restapi3.py b/web/restapi3.py
deleted file mode 100755
index e1b1c04..0000000
--- a/web/restapi3.py
+++ /dev/null
@@ -1,271 +0,0 @@
-#! /usr/bin/env python
-import pprint
-import os
-import sys
-import subprocess
-import json
-import argparse
-import io
-import time
-
-from flask import Flask, json, Response, render_template, make_response, request
-
-## Global Var ##
-RestIP="127.0.0.1"
-RestPort=8182
-DBName="onos-network-map"
-
-DEBUG=1
-pp = pprint.PrettyPrinter(indent=4)
-
-app = Flask(__name__)
-
-## Worker Functions ##
-def log_error(txt):
- print '%s' % (txt)
-
-def debug(txt):
- if DEBUG:
- print '%s' % (txt)
-
-def portV_to_dpid(vertex):
- try:
- command = "curl -s http://%s:%s/graphs/%s/vertices/%d/in" % (RestIP, RestPort, DBName, vertex)
- result = os.popen(command).read()
- parsedResult = json.loads(result)['results']
- except:
- log_error("REST IF has issue")
- exit
-
- debug("portV_to_dpid %s" % command)
- debug("parsed %s" % parsedResult)
- for v in parsedResult:
- if v.has_key('type') and v['type'] == "switch":
- sw_dpid = v['dpid']
- break
-
- return sw_dpid
-
-def switchV_to_dpid(vertex):
- try:
- command = "curl -s http://%s:%s/graphs/%s/vertices/%d" % (RestIP, RestPort, DBName, vertex)
- result = os.popen(command).read()
- parsedResult = json.loads(result)['results']
- except:
- log_error("REST IF has issue")
- exit
-
- debug("switchV_to_dpid %s" % command)
- if not parsedResult.has_key("type") or parsedResult['type'] != "switch":
- print "not a switch vertex"
- exit
- else:
- sw_dpid = parsedResult['dpid']
-
- return sw_dpid
-
-def portV_to_port_dpid(vertex):
- try:
- command = "curl -s http://%s:%s/graphs/%s/vertices/%d" % (RestIP, RestPort, DBName, vertex)
- result = os.popen(command).read()
- parsedResult = json.loads(result)['results']
- except:
- log_error("REST IF has issue")
- exit
-
- debug("portV_to_port_dpid %s" % command)
- port_number = parsedResult['number']
- switch_dpid = portV_to_dpid(vertex)
-
- return (port_number, switch_dpid)
-
-def deviceV_to_attachpoint(vertex):
- try:
- command = "curl -s http://%s:%s/graphs/%s/vertices/%d/in" % (RestIP, RestPort, DBName, vertex)
- result = os.popen(command).read()
- parsedResult = json.loads(result)['results']
- except:
- log_error("REST IF has issue")
- exit
-
- port = parsedResult[0]['number']
- vertex = parsedResult[0]['_id']
- dpid = portV_to_dpid(vertex)
- return port, dpid
-
-## Rest APIs ##
-### File Fetch ###
-@app.route('/ui/img/<filename>', methods=['GET'])
-@app.route('/img/<filename>', methods=['GET'])
-@app.route('/css/<filename>', methods=['GET'])
-@app.route('/js/models/<filename>', methods=['GET'])
-@app.route('/js/views/<filename>', methods=['GET'])
-@app.route('/js/<filename>', methods=['GET'])
-@app.route('/lib/<filename>', methods=['GET'])
-@app.route('/', methods=['GET'])
-@app.route('/<filename>', methods=['GET'])
-@app.route('/tpl/<filename>', methods=['GET'])
-def return_file(filename="index.html"):
- if request.path == "/":
- fullpath = "./index.html"
- else:
- fullpath = str(request.path)[1:]
-
- response = make_response(open(fullpath).read())
- suffix = fullpath.split(".")[-1]
-
- if suffix == "html" or suffix == "htm":
- response.headers["Content-type"] = "text/html"
- elif suffix == "js":
- response.headers["Content-type"] = "application/javascript"
- elif suffix == "css":
- response.headers["Content-type"] = "text/css"
- elif suffix == "png":
- response.headers["Content-type"] = "image/png"
-
- return response
-
-@app.route("/wm/device/")
-def devices():
- try:
- command = "curl -s http://%s:%s/graphs/%s/vertices\?key=type\&value=device" % (RestIP, RestPort, DBName)
- result = os.popen(command).read()
- parsedResult = json.loads(result)['results']
- except:
- log_error("REST IF has issue")
- exit
-
- devices = []
- for v in parsedResult:
- dl_addr = v['dl_addr']
- nw_addr = v['nw_addr']
- vertex = v['_id']
- mac = []
- mac.append(dl_addr)
- ip = []
- ip.append(nw_addr)
- device = {}
- device['entryClass']="DefaultEntryClass"
- device['mac']=mac
- device['ipv4']=ip
- device['vlan']=[]
- device['lastSeen']=0
- attachpoints =[]
-
- port, dpid = deviceV_to_attachpoint(vertex)
- attachpoint = {}
- attachpoint['port']=port
- attachpoint['switchDPID']=dpid
- attachpoints.append(attachpoint)
- device['attachmentPoint']=attachpoints
- devices.append(device)
-
- print devices
- js = json.dumps(devices)
- resp = Response(js, status=200, mimetype='application/json')
- return resp
-
-#{"entityClass":"DefaultEntityClass","mac":["7c:d1:c3:e0:8c:a3"],"ipv4":["192.168.2.102","10.1.10.35"],"vlan":[],"attachmentPoint":[{"port":13,"switchDPID":"00:01:00:12:e2:78:32:44","errorStatus":null}],"lastSeen":1357333593496}
-
-
-## return fake stat for now
-@app.route("/wm/core/switch/<switchId>/<statType>/json")
-def switch_stat(switchId, statType):
- if statType == "desc":
- desc=[{"length":1056,"serialNumber":"None","manufacturerDescription":"Nicira Networks, Inc.","hardwareDescription":"Open vSwitch","softwareDescription":"1.4.0+build0","datapathDescription":"None"}]
- ret = {}
- ret[switchId]=desc
- elif statType == "aggregate":
- aggr = {"packetCount":0,"byteCount":0,"flowCount":0}
- ret = {}
- ret[switchId]=aggr
- else:
- ret = {}
-
- js = json.dumps(ret)
- resp = Response(js, status=200, mimetype='application/json')
- return resp
-
-@app.route("/wm/core/controller/switches/json")
-def query_switch():
- try:
- command = "curl -s \'http://%s:%s/graphs/%s/vertices?key=type&value=switch\'" % (RestIP, RestPort, DBName)
- result = os.popen(command).read()
- parsedResult = json.loads(result)['results']
- except:
- log_error("REST IF has issue")
- exit
-
- switches_ = []
- for v in parsedResult:
- if v.has_key('dpid'):
-# if v.has_key('dpid') and str(v['state']) == "ACTIVE":#;if you want only ACTIVE nodes
- dpid = str(v['dpid'])
- state = str(v['state'])
- sw = {}
- sw['dpid']=dpid
- sw['active']=state
- switches_.append(sw)
-
- pp.pprint(switches_)
- js = json.dumps(switches_)
- resp = Response(js, status=200, mimetype='application/json')
- return resp
-
-@app.route("/wm/topology/links/json")
-def query_links():
- try:
- command = 'curl -s http://%s:%s/graphs/%s/vertices?key=type\&value=port' % (RestIP, RestPort, DBName)
- result = os.popen(command).read()
- parsedResult = json.loads(result)['results']
- except:
- log_error("REST IF has issue")
- exit
-
- debug("query_links %s" % command)
- pp.pprint(parsedResult)
- sport = []
- links = []
- for v in parsedResult:
- srcport = v['_id']
- try:
- command = "curl -s http://%s:%s/graphs/%s/vertices/%d/out?_label=link" % (RestIP, RestPort, DBName, srcport)
- print command
- result = os.popen(command).read()
- linkResults = json.loads(result)['results']
- except:
- log_error("REST IF has issue")
- exit
-
- # print linkResults
- for p in linkResults:
- if p.has_key('type') and p['type'] == "port":
- dstport = p['_id']
- (sport, sdpid) = portV_to_port_dpid(srcport)
- (dport, ddpid) = portV_to_port_dpid(dstport)
- link = {}
- link["src-switch"]=sdpid
- link["src-port"]=sport
- link["src-port-state"]=0
- link["dst-switch"]=ddpid
- link["dst-port"]=dport
- link["dst-port-state"]=0
- link["type"]="internal"
- links.append(link)
-
- pp.pprint(links)
- js = json.dumps(links)
- resp = Response(js, status=200, mimetype='application/json')
- return resp
-
-if __name__ == "__main__":
- if len(sys.argv) > 1 and sys.argv[1] == "-d":
- print "-- query all switches --"
- query_switch()
- print "-- query all links --"
- query_links()
- print "-- query all devices --"
- devices()
- else:
- app.debug = True
- app.run(host="0.0.0.0", port=9000)