Skip to content

Creating Apps With REST and JSON

Craig Riecke edited this page Jun 21, 2016 · 5 revisions

The Frenetic Python language bindings communicate to Frenetic through REST and JSON. But you can use this communication channel directly as well. That way you can use any programming language that speaks HTTP and JSON (pretty much any one) to write your Frenetic-based apps.

To show how this works, let's do it from the command line. In one Terminal window start up a sample Mininet network:

frenetic@ubuntu-14.04:~/src/frenetic/examples$ sudo mn --topo=single,2 --controller=remote
*** Creating network
*** Adding controller
Unable to contact the remote controller at 127.0.0.1:6633
*** Adding hosts:
h1 h2
*** Adding switches:
s1
*** Adding links:
(h1, s1) (h2, s1)
*** Configuring hosts
h1 h2
*** Starting controller
c0
*** Starting 1 switches
s1 ...
*** Starting CLI:
mininet>

In another terminal window, start up Frenetic:

frenetic@ubuntu-1404: ̃src/frenetic$ frenetic http-controller --verbosity debug
 [INFO] Calling create!
 [INFO] Current uid: 1000
 [INFO] Successfully launched OpenFlow controller with pid 3062
 [INFO] Connecting to first OpenFlow server socket
 [INFO] Failed to open socket to OpenFlow server: (Unix.Unix_error...
 [INFO] Retrying in 1 second
 [INFO] Successfully connected to first OpenFlow server socket
 [INFO] Connecting to second OpenFlow server socket
 [INFO] Successfully connected to second OpenFlow server socket

Here's a file with a simple NatKAT policy, which we write in JSON Syntax:

{
  "type":"seq", "pols": [
    { "type":"filter", "pred": { "type": true } },
    { "type": "mod", "header": "location", "value": {"type":"pipe", "name": "my_app"} }
  ]
}

And in the third window, we'll send commands with curl

vagrant@frenetic:~/src/frenetic/examples$ curl -X POST http://localhost:9000/myapp/update_json -d @template_json.json

The compiled flow-table show up in Frenetic's log:

[DEBUG] Setting up flow table
+-----------------------------------------------------+
| 282574488338432 | Pattern | Action                  |
|-----------------------------------------------------|
|                           | Output(Controller(128)) |
+-----------------------------------------------------+

In the Mininet window, type pingall. The pings won't succeed, but the Packet In messages will be saved in Frenetic's event buffer. To retrieve the waiting events, repeatedly call the REST endpoint /event:

vagrant@frenetic:~/src/frenetic/examples$ curl -X GET http://localhost:9000/myapp/event
{"type":"packet_in","pipe":"my_app","switch_id":1,"port_id":1,"payload":{"buffer":"////////aklBYI66CAYAAQgABgQAAWpJQWCOugoAAAEAAAAAAAAKAAAC","id":256},"length":42}

vagrant@frenetic:~/src/frenetic/examples$ curl -X GET http://localhost:9000/myapp/event
{"type":"packet_in","pipe":"my_app","switch_id":1,"port_id":1,"payload":{"buffer":"////////aklBYI66CAYAAQgABgQAAWpJQWCOugoAAAEAAAAAAAAKAAAC","id":257},"length":42}

vagrant@frenetic:~/src/frenetic/examples$ curl -X GET http://localhost:9000/myapp/event
{"type":"packet_in","pipe":"my_app","switch_id":1,"port_id":1,"payload":{"buffer":"////////aklBYI66CAYAAQgABgQAAWpJQWCOugoAAAEAAAAAAAAKAAAC","id":258},"length":42}

vagrant@frenetic:~/src/frenetic/examples$ curl -X GET http://localhost:9000/myapp/event
{"type":"packet_in","pipe":"my_app","switch_id":1,"port_id":2,"payload":{"buffer":"////////zhqg/FgmCAYAAQgABgQAAc4aoPxYJgoAAAIAAAAAAAAKAAAB","id":259},"length":42}

vagrant@frenetic:~/src/frenetic/examples$ curl -X GET http://localhost:9000/myapp/event
{"type":"packet_in","pipe":"my_app","switch_id":1,"port_id":2,"payload":{"buffer":"////////zhqg/FgmCAYAAQgABgQAAc4aoPxYJgoAAAIAAAAAAAAKAAAB","id":260},"length":42}

vagrant@frenetic:~/src/frenetic/examples$ curl -X GET http://localhost:9000/myapp/event
{"type":"packet_in","pipe":"my_app","switch_id":1,"port_id":2,"payload":{"buffer":"////////zhqg/FgmCAYAAQgABgQAAc4aoPxYJgoAAAIAAAAAAAAKAAAB","id":261},"length":42}

vagrant@frenetic:~/src/frenetic/examples$ curl -X GET http://localhost:9000/myapp/event
   ... hang ...

Note the last call blocks because the pingall only generated 6 events, and we got all of them. When the next event becomes available, the REST command will unblock.