Making a topology graph with OpenDaylight REST API, Python, and Javascript

The controller as it currently stands already has a nice topology view of the network, but I thought it would be a good exercise to try and make a web page showing the topology using the API. To do this I’ve written a short Python script leveraging the NetworkX library (which will later allow me to do things like use Dijkstra’s algorithm to find the shortest path between two links), D3.js for visualization, and the REST API from the controller.

First I grabbed all the topology data from the controller. This was just a few simple API calls, followed by some stuff to parse through the JSON data:

baseUrl = 'http://localhost:8080/controller/nb/v2/'
containerName = 'default/'

h = httplib2.Http(".cache")
h.add_credentials('admin', 'admin')

# Get all the edges/links
resp, content = h.request(baseUrl + 'topology/' + containerName, "GET")
edgeProperties = json.loads(content)
odlEdges = edgeProperties['edgeProperties']

# Get all the nodes/switches
resp, content = h.request(baseUrl + 'switchmanager/' + containerName + 'nodes/', "GET")
nodeProperties = json.loads(content)
odlNodes = nodeProperties['nodeProperties']

You’ll see we grabbed a list of all the edges (links) and all the nodes (switches). The edges are given in an array called edgeProperties. I take that array and assign it to odlEdges. Here is an example of an edge object:

  {
    "edge": {
      "tailNodeConnector": {
        "node": {
          "@id": "00:00:00:00:00:00:00:06",
          "@type": "OF"
        },
        "@id": "3",
        "@type": "OF"
      },
      "headNodeConnector": {
        "node": {
          "@id": "00:00:00:00:00:00:00:05",
          "@type": "OF"
        },
        "@id": "1",
        "@type": "OF"
      }
    },
    "properties": {
      "timeStamp": {
        "timestamp": "1370292151090",
        "timestampName": "creation"
      },
      "state": {
        "stateValue": "1"
      },
      "config": {
        "configValue": "1"
      },
      "name": {
        "nameValue": "s5-eth1"
      },
      "bandwidth": {
        "bandwidthValue": "10000000000"
      }
    }
  }

You’ll see that an edge has a head node, tail node, and the associated ports. This implies that there are two ‘edges’ for every link, one in each direction.

I also get an array Node objects called nodeProperties. The last line of the above code takes that array and assigns it to odlNodes, here is an example node:

  {
    "node": {
      "@id": "00:00:00:00:00:00:00:07",
      "@type": "OF"
    },
    "properties": {
      "macAddress": {
        "nodeMacAddress": "AAAAAAAH",
        "controllerMacAddress": "aKhtCMic"
      },
      "tables": {
        "tablesValue": "-1"
      },
      "timeStamp": {
        "timestamp": "1370292150118",
        "timestampName": "connectedSince"
      },
      "capabilities": {
        "capabilitiesValue": "199"
      },
      "actions": {
        "actionsValue": "4095"
      },
      "property": null,
      "buffers": {
        "buffersValue": "256"
      }
    }
  }

Next I take all those nodes/edges, and send them to NetworkX in a simpler format with just the info that I need:

# Put nodes and edges into a graph
graph = nx.Graph()
for node in odlNodes:
  graph.add_node(node['node']['@id'])
for edge in odlEdges:
  e = (edge['edge']['headNodeConnector']['node']['@id'], edge['edge']['tailNodeConnector']['node']['@id'])
  graph.add_edge(*e)

I’m not really making much use of NetworkX in this example, but one thing I can do is export this simplified graph to a number of different graph formats, or plot the graph. Since I wanted to try and make a web app, I chose to dump it as JSON, then send it over to D3.js for graphing.

d = json_graph.node_link_data(graph)
json.dump(d, open('topo.json','w'))
print('Wrote node-link JSON data')

Here is what the output file ends up looking like:

{"directed": false, "graph": [], "nodes": [{"id": "00:00:00:00:00:00:00:01"}, {"id": "00:00:00:00:00:00:00:03"}, {"id": "00:00:00:00:00:00:00:02"}, {"id": "00:00:00:00:00:00:00:05"}, {"id": "00:00:00:00:00:00:00:04"}, {"id": "00:00:00:00:00:00:00:07"}, {"id": "00:00:00:00:00:00:00:06"}], "links": [{"source": 0, "target": 2}, {"source": 0, "target": 3}, {"source": 1, "target": 2}, {"source": 2, "target": 4}, {"source": 3, "target": 5}, {"source": 3, "target": 6}], "multigraph": false}

I decided to leave the graph as undirected to just show a single link between the nodes. Now I can write some Javacript to graph everything with D3.js. I’m using a force-directed algorithm to lay everything out:

Now we can wrap it up in HTML and see our graph.
Screen Shot 2013-06-03 at 1.42.57 PM
This ended up being a pretty easy one, but it did help familiarize me with how the topology API works. You can find all the code here:
https://github.com/fredhsu/odl-scripts/tree/master/python/topo

Advertisements

6 thoughts on “Making a topology graph with OpenDaylight REST API, Python, and Javascript

  1. AMP says:

    Hi Fredhsu,

    Thank you for the article and I did some test on this. Now it looks there is change on REST API for nodes like below.

    old : resp, content = h.request(baseUrl + ‘switch/’ + containerName + ‘nodes/’, “GET”)

    new : resp, content = h.request(baseUrl + ‘switchmanager/’ + containerName + ‘nodes/’, “GET”)

    Regards,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s