diff --git a/sdncon/rest/RestApiTestData.py b/sdncon/rest/RestApiTestData.py
new file mode 100755
index 0000000..f907e5d
--- /dev/null
+++ b/sdncon/rest/RestApiTestData.py
@@ -0,0 +1,84 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+# This i data file for testing Rest APIs
+# This file is read by RestApiTests.py
+
+test_dpid="11:22:33:44:55:66:77:01"
+test_dpid2="11:22:33:44:55:66:77:01"
+test_mac ="11:22:33:44:55:01"
+test_vns_id   ="test_vns_id_1"
+test_flow_entry_name = "test_flow_entry_name"
+test_vns_acl_name = "test_vns_acl"
+test_syncd_config_id = "test_syncd_config_id"
+test_syncd_transport_config_test_data="test_sync_transport_config_id"
+test_syncd_transport_config_name = "test_syncd_transport_cfg_name"
+test_vns_interface_rule_name = "test_vns_intf_rule_name"
+test_vns_interface_name = "test_vns_intf_name"
+test_vns_interface_acl_direction = "in"
+test_vns_interface_acl_id = "test_vns_interface_acl_id"
+test_vns_acl_name_id = test_vns_id+"|"+test_vns_acl_name
+test_vns_acl_entry_type = "ip"
+test_acl_entry_seq_no = "10"
+test_vns_acl_entry_id = test_vns_acl_name_id+"|"+test_acl_entry_seq_no
+test_vns_acl_entry_src_ip="11.22.33.44"
+test_vns_acl_entry_action="deny"
+test_vns_acl_entry_type="deny"
+test_tag_name = "test_tag_name"
+test_tag_value = "test_tag_value"
+test_tag_id = test_vns_id+"|"+test_tag_name+"|"+test_tag_value
+test_tag_mapping_id = test_tag_id+"|"+test_mac
+
+model_switch_test_data={"path":"model/switch", "data":{"dpid":test_dpid}, "id":"dpid"}
+model_host_test_data  ={"path":"model/host",   "data":{"mac":test_mac}, "id":"mac"}
+model_flow_entry_test_data = {"path":"model/flow-entry", "data":{"switch":test_dpid, "name":test_flow_entry_name}, "id":"name"}
+model_vns_definition_test_data = {"path":"model/vns-definition", "data":{"id":test_vns_id}, "id":"id"}
+model_vns_acl_test_data = {"path":"model/vns-access-list", "data":{"vns":test_vns_id, "name":test_vns_acl_name_id}, "id":"name"}
+model_host_network_address_test_data = {"path":"model/host-network-address", \
+    "data":{"id":"ea:81:27:2a:6b:6b-10.0.0.1"}, "id":"id"}
+model_syncd_config_test_data = {"path":"model/syncd-config", "data":{"id":test_syncd_config_id}, "id":"id"}
+model_tag_test_data = {"path":"model/tag", "data":{"id":test_tag_id, \
+    "name":"tagname", "value":"tagvalue", "namespace":test_vns_id}, "id":"id"}
+model_tag_mapping_test_data = {"path":"model/tag-mapping", "data":{"id": test_tag_mapping_id, \
+                               "tag": test_tag_id, "type": "host", "host": test_mac}, "id":"id"}
+model_syncd_transport_config_test_data = {"path":"model/syncd-transport-config", 
+    "data":{"id":"test_syncd_transport_config_test_data", "type":"random1", "args":"test_args", \
+    "config":test_syncd_config_id, "target-cluster":"Testcluster", "name":test_syncd_transport_config_name}, "id":"id"}
+model_syncd_progress_info_test_data = {"path":"model/syncd-progress-info", "data":{"id":test_syncd_config_id}, "id":"id"}
+model_vns_interface_rule_test_data ={"path":"model/vns-interface-rule", \
+    "data":{"id":test_vns_id+"|"+test_vns_interface_rule_name, "vns":test_vns_id}, "id":"id"}
+model_vns_interface_acl_test_data = {"path":"model/vns-interface-access-list", "data":{"id":test_vns_interface_acl_id, \
+    "in-out":test_vns_interface_acl_direction, "vns-interface":test_vns_interface_name, "vns-access-list":test_vns_acl_name_id}, "id":"id"}
+model_vns_acl_entry_test_data = {"path":"model/vns-access-list-entry", \
+    "data":{"id":test_vns_acl_entry_id, "src-ip":test_vns_acl_entry_src_ip, \
+    "action":test_vns_acl_entry_action, "vns-access-list":test_vns_acl_name_id, "type":test_vns_acl_entry_type}, "id":"id"}
+
+test_index=0
+rest_api_test_data = {}
+rest_api_test_data[test_index] = model_switch_test_data ; test_index += 1
+rest_api_test_data[test_index] = model_host_test_data; test_index += 1
+rest_api_test_data[test_index] = model_flow_entry_test_data; test_index += 1
+rest_api_test_data[test_index] = model_vns_definition_test_data; test_index += 1
+rest_api_test_data[test_index] = model_vns_acl_test_data; test_index += 1
+rest_api_test_data[test_index] = model_host_network_address_test_data; test_index += 1
+rest_api_test_data[test_index] = model_syncd_config_test_data; test_index += 1
+rest_api_test_data[test_index] = model_tag_test_data; test_index += 1
+rest_api_test_data[test_index] = model_tag_mapping_test_data; test_index += 1
+rest_api_test_data[test_index] = model_syncd_transport_config_test_data; test_index += 1
+rest_api_test_data[test_index] = model_syncd_progress_info_test_data; test_index += 1
+rest_api_test_data[test_index] = model_vns_interface_rule_test_data; test_index += 1
+rest_api_test_data[test_index] = model_vns_interface_acl_test_data; test_index += 1
+rest_api_test_data[test_index] = model_vns_acl_entry_test_data; test_index += 1
diff --git a/sdncon/rest/__init__.py b/sdncon/rest/__init__.py
new file mode 100755
index 0000000..580a7bb
--- /dev/null
+++ b/sdncon/rest/__init__.py
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from sdncon.rest.config import init_config
+
+init_config()
diff --git a/sdncon/rest/config.py b/sdncon/rest/config.py
new file mode 100755
index 0000000..7c0de5c
--- /dev/null
+++ b/sdncon/rest/config.py
@@ -0,0 +1,219 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.db.models.signals import post_save, post_delete
+import json
+import os
+import traceback
+from django.core import serializers
+import sdncon
+
+# FIXME: This code is not thread-safe!!!
+# Currently we don't run Django with multiple threads so this isn't a problem,
+# but if we were to try to enable threading this code would need to be fixed.
+
+pre_save_instance = None
+config_handlers = []
+config_models = set()
+
+
+def add_config_handler(dependencies, handler):
+    """
+    The dependencies argument is a dictionary where the key is a model
+    (i.e. the actual model, not the name of the mode) and the value of the
+    key is a tuple (or list) of field names whose modification should
+    trigger the config handler. The value can also be None to indicate
+    that the config handler should be triggered when any field in the
+    model is modified.
+    
+    The calling convention of a config handler is:
+    
+    def my_config_handler(op, old_instance, new_instance, modified_fields)
+    
+    The 'op' argument is one of 'INSERT', 'UPDATE' or 'DELETE', corresponding
+    to an insertion, update or deletion of a row in the model.
+    The 'old_instance' argument is the instance of the model before the changes.
+    For an 'INSERT' op, old_instance and modified_fields are both None.
+    The 'new_instance' argument is the instance of the model after the changes.
+    For a 'DELETE' op, new_instance and modified_fields are both None.
+    the 'modified_fields' is a dictionary containing the fields that were changed.
+    The dictionary key is the name of the field and the value is the new value.
+    """
+    assert dependencies != None
+    assert handler != None
+    
+    for model in dependencies.keys():
+        config_models.add(model)
+            
+    config_handlers.append((dependencies, handler))
+
+last_config_state_path = None
+
+def get_last_config_state_path():
+    global last_config_state_path
+    if not last_config_state_path:
+        last_config_state_dir = "%s/run/" % sdncon.SDN_ROOT
+        if not os.path.exists(last_config_state_dir):
+            last_config_state_dir = '/tmp'
+        last_config_state_path = os.path.join(last_config_state_dir, 'last-config-state')
+    return last_config_state_path
+
+def reset_last_config_state():
+    path = get_last_config_state_path()
+    try:
+        os.unlink(path)
+    except Exception, _e:
+        pass
+    
+
+def config_read_state():
+    last_config_state = None
+    f = None
+    try:
+        f = open(get_last_config_state_path(), 'r')
+        last_config_state_text = f.read()
+        last_config_state = json.loads(last_config_state_text)
+    except Exception, _e:
+        pass
+    finally:
+        if f:
+            f.close()
+    return last_config_state
+
+def config_write_state(config_state):
+    f = None
+    try:
+        config_state_text = json.dumps(config_state)
+        f = open(get_last_config_state_path(), 'w')
+        f.write(config_state_text)
+    except Exception, e:
+        print "Error writing last config state: %s" % str(e)
+    finally:
+        if f:
+            f.close()
+
+def config_do_insert(sender, new_instance):
+    for config_handler in config_handlers:
+        dependencies = config_handler[0]
+        if sender in dependencies:
+            handler = config_handler[1]
+            try:
+                handler(op='INSERT', old_instance=None, new_instance=new_instance, modified_fields=None)
+            except Exception, _e:
+                traceback.print_exc()
+                
+def config_do_update(sender, old_instance, new_instance):
+    for config_handler in config_handlers:
+        dependencies = config_handler[0]
+        if sender in dependencies:
+            handler = config_handler[1]
+            modified_fields = {}
+            fields = dependencies.get(sender)
+            if not fields:
+                # If no fields were specified for the model then check all of the fields.
+                fields = [field.name for field in sender._meta.fields]
+                
+            for field in fields:
+                old_value = getattr(old_instance, field)
+                new_value = getattr(new_instance, field)
+                if new_value != old_value:
+                    modified_fields[field] = new_value
+            if modified_fields:
+                try:
+                    handler(op='UPDATE', old_instance=old_instance, new_instance=new_instance, modified_fields=modified_fields)
+                except Exception, _e:
+                    traceback.print_exc()
+
+
+def config_do_delete(sender, instance):
+    for config_handler in config_handlers:
+        dependencies = config_handler[0]
+        if sender in dependencies:
+            handler = config_handler[1]
+            try:
+                handler(op='DELETE', old_instance=instance, new_instance=None, modified_fields=None)
+            except Exception, _e:
+                traceback.print_exc()
+
+def model_instances_equal(instance1, instance2):
+    if instance1 == None:
+        return instance1 == instance2
+    
+    for field in instance1._meta.fields:
+        value1 = field.value_from_object(instance1)
+        value2 = field.value_from_object(instance2)
+        if value1 != value2:
+            return False
+    return True
+
+def config_check_state():
+    from sdncon.controller.notification import do_modify_notification, do_delete_notification
+    last_config_state = config_read_state()
+    try:
+        last_config_instances = last_config_state.get('instances')
+    except Exception, _e:
+        last_config_instances = {}
+    
+    current_config_instances = {}
+    
+    for config_model in config_models:
+        try:
+            serialized_old_instances = json.dumps(last_config_instances.get(config_model.__name__,[]))
+            old_instance_info = serializers.deserialize('json', serialized_old_instances)
+            old_instances = [info.object for info in old_instance_info]
+        except Exception, _e:
+            old_instances = []
+            
+        new_instances = config_model.objects.all()
+        
+        for new_instance in new_instances:
+            for index, old_instance in enumerate(old_instances):
+                if new_instance.pk == old_instance.pk:
+                    if not model_instances_equal(new_instance, old_instance):
+                        config_do_update(config_model, old_instance, new_instance)
+                        do_modify_notification(config_model, new_instance)
+                    del old_instances[index]
+                    break
+            else:
+                config_do_insert(config_model, new_instance)
+                do_modify_notification(config_model, new_instance)
+        
+        for deleted_instance in old_instances:
+            config_do_delete(config_model, deleted_instance)
+            do_delete_notification(config_model, deleted_instance)
+
+        try:
+            serialized_new_instances = serializers.serialize("json", new_instances)
+            current_config_instances[config_model.__name__] = json.loads(serialized_new_instances)
+        except:
+            print 'Failed to serialize', config_model.__name__
+        
+    config_write_state({'instances': current_config_instances})
+
+def config_post_save_handler(sender, **kwargs):
+    if not kwargs['raw'] and (kwargs['using'] == "default") and sender in config_models:
+        config_check_state()
+    
+def config_post_delete_handler(sender, **kwargs):
+    if kwargs['using'] == 'default' and sender in config_models:
+        config_check_state()
+
+def is_config_model(model):
+    return model in config_models
+ 
+def init_config():
+    post_save.connect(config_post_save_handler)
+    post_delete.connect(config_post_delete_handler)
diff --git a/sdncon/rest/jsonview.py b/sdncon/rest/jsonview.py
new file mode 100755
index 0000000..61c7c39
--- /dev/null
+++ b/sdncon/rest/jsonview.py
@@ -0,0 +1,63 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.http import HttpResponseForbidden, HttpResponse
+from django.utils.simplejson import JSONEncoder
+from django.utils.encoding import force_unicode
+from django.db.models.base import ModelBase
+from django.utils.simplejson import dumps
+
+class JsonResponse(HttpResponse):
+    """A HttpResponse subclass that creates properly encoded JSON response"""
+
+    def __init__(self, content='', json_opts={},
+                 mimetype="application/json", *args, **kwargs):
+        
+        if content is None: content = []
+        content = serialize_to_json(content,**json_opts)
+        super(JsonResponse,self).__init__(content,mimetype,*args,**kwargs)
+
+class JsonEncoder(JSONEncoder):
+    """A JSONEncoder subclass that also handles querysets and models objects."""
+
+    def default(self,o):
+        # this handles querysets and other iterable types
+        try: iterable = iter(o)
+        except TypeError: pass
+        else: return list(iterable)
+ 
+        # this handlers Models objects
+        try: isinstance(o.__class__,ModelBase)
+        except Exception: pass
+        else: return force_unicode(o)
+ 
+        # delegate the rest to JSONEncoder
+        return super(JsonEncoder,self).default(obj)
+ 
+def serialize_to_json(obj,*args,**kwargs):
+    """A wrapper for dumps with defaults as:
+        ensure_ascii=False
+        cls=JsonEncoder"""
+ 
+    kwargs['ensure_ascii'] = kwargs.get('ensure_ascii', False)
+    kwargs['cls'] = kwargs.get('cls', JsonEncoder)
+    return dumps(obj,*args,**kwargs)
+
+def as_kwargs(qdict):
+    kwargs = {}
+    for k,v in qdict.items():
+        kwargs[str(k)] = v
+    return kwargs
diff --git a/sdncon/rest/models.py b/sdncon/rest/models.py
new file mode 100755
index 0000000..436a90e
--- /dev/null
+++ b/sdncon/rest/models.py
@@ -0,0 +1,26 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.db import models
+from django.contrib.auth.models import User
+# Create your models here.
+
+class UserData(models.Model):
+    user = models.ForeignKey(User, null=True)
+    name = models.CharField(max_length=256)
+    content_type = models.CharField(max_length=128)
+    binary = models.BooleanField()
+    data = models.TextField()
diff --git a/sdncon/rest/poll.py b/sdncon/rest/poll.py
new file mode 100755
index 0000000..bfd0573
--- /dev/null
+++ b/sdncon/rest/poll.py
@@ -0,0 +1,128 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+"""Polling interface for the polling services setup by the rest API"""
+
+import sys, os, time, random, json
+
+from packetstreamer import PacketStreamer
+from packetstreamer.ttypes import *
+
+from thrift import Thrift
+from thrift.transport import TSocket
+from thrift.transport import TTransport
+from thrift.protocol import TBinaryProtocol
+
+def sample_func(request, environ):
+    data = {
+        'pid': os.getpid(),
+        'random': int(random.random()*100),
+    }
+
+    return {
+        'status':    '200 OK',
+        'body':      json.dumps(data),
+        'headers':   [('Content-type', 'application/json')], # list of tuples
+    }
+
+def getPackets_func(request, environ, sessionid):
+    retData = {}
+
+    try:
+        # Make socket
+        transport = TSocket.TSocket('localhost', 9090)
+        # Buffering is critical. Raw sockets are very slow
+        transport = TTransport.TFramedTransport(transport)
+        # Wrap in a protocol
+        protocol = TBinaryProtocol.TBinaryProtocol(transport)
+        # Create a client to use the protocol encoder
+        client = PacketStreamer.Client(protocol)
+        # Connect!
+        transport.open()
+
+        packets = client.getPackets(sessionid)
+
+        # Close!
+        transport.close()
+
+        retData = {
+          'status':    '200 OK',
+          'body':       json.dumps(packets),
+          'headers':    [('Content-type', 'application/json')], # list of tuples
+        }
+
+    except Thrift.TException, tx:
+        retData = {
+          'status':    '500 Internal Server Error',
+          'body':      'error: %s'%tx.message,
+          'headers':   [('Content-type', 'application/json')], # list of tuples
+        }
+
+    return retData
+
+# The polling service
+#   The service is driven by the urlpatterns tuples that list the specific function
+#   to use for a matching pattern in URL. The pattern should not include initial '^/poll'.
+#   For Example:
+#     (r'^/sample', sample_func)
+#from sdncon.rest.poll import sample_func
+urlpatterns = [
+    (r'^/packets/(?P<sessionid>[A-Za-z0-9_.\-]+)/?$', getPackets_func),
+    (r'^/sample', sample_func)
+]
+
+import re, wsgiref.util
+
+def compile_patterns(urlpatterns):
+    return map(lambda pat: (re.compile(pat[0]), pat[1]), urlpatterns)
+
+def main(environ, start_response):
+    patterns = compile_patterns(urlpatterns)
+    request = environ['PATH_INFO']
+    response = None
+    status, body = '404 Not Found', 'Sorry, the requested resource "%s" was not found."' % request
+    headers = []
+    for (pat, func) in patterns:
+        m = pat.match(request)
+        if m:
+            args = m.groups()
+            if args:
+                response = func(request, environ, *args)
+            else:
+                response = func(request, environ)
+
+            status, body = response['status'], response['body']
+            if 'headers' in response:
+                headers.extend(response['headers'])
+            break
+    if 'Cache-Control' not in headers:
+        headers.append(('Cache-Control', 'no-cache'))
+    if 'Content-type' not in headers:
+         headers.append(('Content-type', 'text/plain'))
+    if 'Content-Length' not in headers:
+         headers.append(('Content-Length', str(len(body))))
+    start_response(status, headers)
+    return [body]
+
+if __name__ == "__main__":
+    def start_response(x, y):
+        print 'Status:', x
+        print 'Headers:', y
+
+    print 'Sample', sample_func(None, None)
+    print 'Response:', main({'PATH_INFO':'/sample/100'}, start_response)
+    print 'Response:', main({'PATH_INFO':'/xsample/100'}, start_response)
diff --git a/sdncon/rest/tests.py b/sdncon/rest/tests.py
new file mode 100755
index 0000000..7430831
--- /dev/null
+++ b/sdncon/rest/tests.py
@@ -0,0 +1,648 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.core.validators import validate_ipv4_address, MinValueValidator
+from django.db import models
+from django.forms import ValidationError
+from django.test import TestCase, Client
+from django.utils import simplejson
+import copy
+import urllib
+import urllib2
+from sdncon.rest.validators import validate_mac_address, RangeValidator, ChoicesValidator
+from sdncon.rest.config import add_config_handler, reset_last_config_state, model_instances_equal
+
+# These are the test models used in the unit tests
+# When running the unit tests, syncdb looks for model definitions
+# in this file (i.e. tests.py), so these will be in the complete
+# list of models used by the REST code
+
+class RestTestModel(models.Model):
+    name = models.CharField(max_length=32, primary_key=True)
+    enabled = models.BooleanField()
+    min = models.IntegerField(validators=[MinValueValidator(100)])
+    range = models.IntegerField(validators=[RangeValidator(10,100)])
+    internal = models.CharField(max_length=24,default='foo')
+    ip = models.IPAddressField(validators=[validate_ipv4_address])
+    mac = models.CharField(max_length=20, validators=[validate_mac_address])
+    ratio = models.FloatField()
+    COLOR_CHOICES = (
+        ('red', 'Dark Red'),
+        ('blue', 'Navy Blue'),
+        ('green', 'Green'),
+        ('white', 'Ivory White')
+    )
+    color = models.CharField(max_length=20, validators=[ChoicesValidator(COLOR_CHOICES)])
+    
+    def clean(self):
+        # This is just a dummy check for testing purposes. Typically you'd only
+        # use the model-level clean function for validating things across multiple fields
+        if self.range == 50:
+            raise ValidationError("Dummy model-level validation failure.")
+    
+    class Rest:
+        NAME = 'rest-test'
+        FIELD_INFO = ({'name':'internal', 'private': True},)
+
+class RestTestTagModel(models.Model):
+    rest_test = models.ForeignKey(RestTestModel)
+    name = models.CharField(max_length=32)
+    value = models.CharField(max_length=256)
+    
+    class Rest:
+        NAME = 'rest-test-tag'
+        FIELD_INFO = ({'name':'rest_test', 'rest_name':'rest-test'},)
+        
+class RestTestRenamedFieldModel(models.Model):
+    test = models.CharField(max_length=16,primary_key=True)
+    
+    class Rest:
+        NAME = 'rest-test-renamed'
+        FIELD_INFO = ({'name':'test', 'rest_name':'renamed'},)
+        
+class RestDisabledModel(models.Model):
+    dummy = models.CharField(max_length=32)
+
+class RestCompoundKeyModel(models.Model):
+    name = models.CharField(max_length=32)
+    index = models.IntegerField()
+    extra = models.CharField(max_length=32, default='dummy')
+    
+    class CassandraSettings:
+        COMPOUND_KEY_FIELDS = ['name', 'index']
+        
+    class Rest:
+        NAME = 'rest-compound-key'
+        
+#############################################################################
+# These are some client-side utility functions for getting, putting, deleting
+# data using the REST API
+#############################################################################
+
+def construct_rest_url(path, query_params=None):
+    url = 'http://localhost:8000/rest/v1/%s/' % path
+    if query_params:
+        url += '?'
+        url += urllib.urlencode(query_params)
+    return url
+
+def get_rest_data(type, query_param_dict=None):
+    url = construct_rest_url(type, query_param_dict)
+    request = urllib2.Request(url)
+    response = urllib2.urlopen(request)
+    response_text = response.read()
+    obj = simplejson.loads(response_text)
+    return obj
+
+def put_rest_data(obj, type, query_param_dict=None):
+    url = construct_rest_url(type, query_param_dict)
+    post_data = simplejson.dumps(obj)
+    request = urllib2.Request(url, post_data, {'Content-Type':'application/json'})
+    request.get_method = lambda: 'PUT'
+    response = urllib2.urlopen(request)
+    return response.read()
+
+def delete_rest_data(type, query_param_dict=None):
+    url = construct_rest_url(type, query_param_dict)
+    request = urllib2.Request(url)
+    request.get_method = lambda: 'DELETE'
+    response = urllib2.urlopen(request)
+    return response.read()
+
+def test_construct_rest_url(path, query_params=None):
+    url = '/rest/v1/%s/' % path
+    if query_params:
+        url += '?'
+        url += urllib.urlencode(query_params)
+    return url
+
+def test_construct_rest_model_url(path, query_params=None):
+    return test_construct_rest_url('model/' + path, query_params)
+    
+def test_get_rest_model_data(type, query_params=None):
+    url = test_construct_rest_model_url(type,query_params)
+    c = Client()
+    response = c.get(url)
+    return response
+
+def test_put_rest_model_data(obj, type, query_params=None):
+    url = test_construct_rest_model_url(type, query_params)
+    data = simplejson.dumps(obj)
+    c = Client()
+    response = c.put(url , data, 'application/json')
+    return response
+
+def test_delete_rest_model_data(type, query_params=None):
+    url = test_construct_rest_model_url(type, query_params)
+    c = Client()
+    response = c.delete(url)
+    return response
+
+def get_sorted_list(data_list, key_name, create_copy=False):
+    if create_copy:
+        data_list = copy.deepcopy(data_list)
+    if key_name:
+        key_func = lambda item: item.get(key_name)
+    else:
+        key_func = lambda item: item[0]
+    data_list.sort(key = key_func)
+    return data_list
+
+#############################################################################
+# The actual unit test classes
+#############################################################################
+
+class BasicFunctionalityTest(TestCase):
+    
+    REST_TEST_DATA = [
+        {'name':'foobar','enabled':True,'min':100,'range':30,'ip':'192.168.1.1','mac':'00:01:22:34:56:af','ratio':4.56,'color':'red'},
+        {'name':'sdnplatform','enabled':False,'min':400,'range':45,'ip':'192.168.1.2','mac':'00:01:22:CC:56:DD','ratio':8.76,'color':'green'},
+        {'name':'foobar2','enabled':True,'min':1000,'range':100,'ip':'192.168.1.3','mac':'00:01:22:34:56:af','ratio':1,'color':'white'},
+    ]
+    
+    REST_TEST_TAG_DATA = [
+        {'id':'1','rest-test':'foobar','name':'one','value':'testit'},
+        {'id':'2','rest-test':'foobar','name':'two','value':'test2'},
+        {'id':'3','rest-test':'sdnplatform','name':'three','value':'three'},
+    ]
+    
+    def setUp(self):
+        # Create the RestTestModel instances
+        rest_test_list = []
+        for rtd in self.REST_TEST_DATA:
+            rt = RestTestModel(**rtd)
+            rt.save()
+            rest_test_list.append(rt)
+        
+        # Create the RestTestTagModel instances
+        for rttd in self.REST_TEST_TAG_DATA:
+            rttd_init = rttd.copy()
+            for rt in rest_test_list:
+                if rt.name == rttd['rest-test']:
+                    del rttd_init['rest-test']
+                    rttd_init['rest_test'] = rt
+                    break
+            else:
+                raise Exception('Invalid initialization data for REST unit tests')
+            rtt = RestTestTagModel(**rttd_init)
+            rtt.save()
+        
+        rtrf = RestTestRenamedFieldModel(test='test')
+        rtrf.save()
+        
+        # Create the RestDisabledModel instance. We're only going to test that
+        # we can't access this model via the REST API, so we don't need to keep
+        # track of the data used for the instance
+        #rdm = RestDisabledModel(dummy='dummy')
+        #rdm.save()
+    
+    def check_rest_test_data_result(self, data_list, expected_data_list, message=None):
+        data_list = get_sorted_list(data_list, 'name', True)
+        expected_data_list = get_sorted_list(expected_data_list, 'name', True)
+        self.assertEqual(len(data_list), len(expected_data_list), message)
+        for i in range(len(data_list)):
+            data = data_list[i]
+            expected_data = expected_data_list[i]
+            self.assertEqual(data['name'], expected_data['name'], message)
+            self.assertEqual(data['enabled'], expected_data['enabled'], message)
+            self.assertEqual(data['min'], expected_data['min'], message)
+            self.assertEqual(data['range'], expected_data['range'], message)
+            self.assertEqual(data['ip'], expected_data['ip'], message)
+            self.assertEqual(data['mac'], expected_data['mac'], message)
+            self.assertAlmostEqual(data['ratio'], expected_data['ratio'], 7, message)
+            self.assertEqual(data['color'], expected_data['color'], message)
+    
+    def check_rest_test_tag_data_result(self, data_list, expected_data_list, message=None):
+        data_list = get_sorted_list(data_list, 'name', True)
+        expected_data_list = get_sorted_list(expected_data_list, 'name', True)
+        self.assertEqual(len(data_list), len(expected_data_list), message)
+        for i in range(len(data_list)):
+            data = data_list[i]
+            expected_data = expected_data_list[i]
+            self.assertEqual(str(data['id']), expected_data['id'], message)
+            self.assertEqual(data['rest-test'], expected_data['rest-test'], message)
+            self.assertEqual(data['name'], expected_data['name'], message)
+            self.assertEqual(data['value'], expected_data['value'], message)
+            
+    def test_put_one(self):
+        test_put_rest_model_data({'min':200,'color':'white'}, 'rest-test/foobar')
+        response = test_get_rest_model_data('rest-test')
+        data = simplejson.loads(response.content)
+        rtd_copy = copy.deepcopy(self.REST_TEST_DATA)
+        rtd_copy[0]['min'] = 200
+        rtd_copy[0]['color'] = 'white'
+        self.check_rest_test_data_result(data, rtd_copy)
+        
+    def test_put_query(self):
+        test_put_rest_model_data({'min':200,'color':'white'}, 'rest-test', {'enabled':True})
+        response = test_get_rest_model_data('rest-test')
+        data = simplejson.loads(response.content)
+        rtd_copy = copy.deepcopy(self.REST_TEST_DATA)
+        for rtd in rtd_copy:
+            if rtd['enabled']:
+                rtd['min'] = 200
+                rtd['color'] = 'white'
+        self.check_rest_test_data_result(data, rtd_copy)
+    
+    def test_create_one(self):
+        rtd_copy = copy.deepcopy(self.REST_TEST_DATA)
+        create_rtd = rtd_copy[0].copy()
+        create_rtd['name'] = 'test-create'
+        rtd_copy.append(create_rtd)
+        test_put_rest_model_data(create_rtd, 'rest-test')
+        response = test_get_rest_model_data('rest-test')
+        data = simplejson.loads(response.content)
+        self.check_rest_test_data_result(data, rtd_copy)
+    
+    def test_create_many(self):
+        rtd_copy = copy.deepcopy(self.REST_TEST_DATA)
+        create_rtd1 = rtd_copy[0].copy()
+        create_rtd1['name'] = 'test-create1'
+        create_rtd1['min'] = 2000
+        rtd_copy.append(create_rtd1)
+        create_rtd2 = rtd_copy[0].copy()
+        create_rtd2['name'] = 'test-create2'
+        create_rtd1['min'] = 4000
+        rtd_copy.append(create_rtd2)
+        test_put_rest_model_data([create_rtd1,create_rtd2], 'rest-test')
+        response = test_get_rest_model_data('rest-test')
+        data = simplejson.loads(response.content)
+        self.check_rest_test_data_result(data, rtd_copy)
+        
+    def test_get(self):
+        RTD = self.REST_TEST_DATA
+        RTTD = self.REST_TEST_TAG_DATA
+        GET_TEST_VECTORS = (
+            #model_name, query_params, expected_data
+            ('rest-test', None, RTD, 'Failure getting all rest-test instances'),
+            ('rest-test-tag', None, RTTD, 'Failure getting all rest-test-tag instances'),
+            ('rest-test/foobar', None, RTD[0], 'Failure getting single rest-test instance by URL'),
+            ('rest-test', {'name':'foobar'}, [RTD[0]], 'Failure querying for single rest-test instance'),
+            ('rest-test', {'name':'foobar','nolist':True}, RTD[0], 'Failure querying for single rest-test instance using nolist'),
+            ('rest-test', {'enabled':True}, [RTD[0],RTD[2]], 'Failure querying for multiple rest-test instances'),
+            ('rest-test', {'name__startswith':'foobar'}, [RTD[0],RTD[2]], 'Failure querying for multiple rest-test instances using startswith'),
+            ('rest-test', {'orderby':'ratio'}, [RTD[2],RTD[0],RTD[1]], 'Failure querying with ascending orderby'),
+            ('rest-test', {'orderby':'-ratio'}, [RTD[1],RTD[0],RTD[2]], 'Failure querying with descending orderby'),
+            ('rest-test', {'orderby':'enabled,-ratio'}, [RTD[1],RTD[0],RTD[2]], 'Failure querying with multi-field orderby'),
+            ('rest-test-tag', {'rest-test':'foobar'}, [RTTD[0],RTTD[1]], 'Failure querying by ForeignKey value'),
+            ('rest-test-tag', {'rest-test__startswith':'foo'}, [RTTD[0],RTTD[1]], 'Failure querying by ForeignKey value'),
+            ('rest-test-tag', {'rest-test__contains':'swi'}, [RTTD[2]], 'Failure querying by ForeignKey value'),
+        )
+        
+        for model_name, query_params, expected_data, message in GET_TEST_VECTORS:
+            response = test_get_rest_model_data(model_name, query_params)
+            data = simplejson.loads(response.content)
+            #print model_name
+            #self.check_rest_test_data_result(data, expected_data, message)
+            if type(data) is not list:
+                data = [data]
+                #data = get_sorted_list(data, 'name', False)
+            if type(expected_data) is not list:
+                expected_data = [expected_data]
+                #expected_data = get_sorted_list(expected_data, 'name', True)
+            if model_name.startswith('rest-test-tag'):
+                self.check_rest_test_tag_data_result(data, expected_data, message)
+            else:
+                self.check_rest_test_data_result(data, expected_data, message)
+            
+    def test_renamed_field(self):
+        response = test_get_rest_model_data('rest-test-renamed/test')
+        self.assertEqual(response.status_code,200)
+        data = simplejson.loads(response.content)
+        self.assertEqual(data['renamed'], 'test')
+        
+    def test_delete_one(self):
+        test_delete_rest_model_data('rest-test/foobar')
+        response = test_get_rest_model_data('rest-test')
+        data = simplejson.loads(response.content)
+        self.check_rest_test_data_result(data, self.REST_TEST_DATA[1:])
+    
+    def test_delete_query(self):
+        test_delete_rest_model_data('rest-test', {'name__startswith':'foobar'})
+        response = test_get_rest_model_data('rest-test')
+        data = simplejson.loads(response.content)
+        self.check_rest_test_data_result(data, [self.REST_TEST_DATA[1]])
+    
+    def test_delete_all(self):
+        test_delete_rest_model_data('rest-test')
+        response = test_get_rest_model_data('rest-test')
+        data = simplejson.loads(response.content)
+        self.assertEqual(len(data),0)
+
+class NegativeTest(TestCase):
+    
+    def test_invalid_model_name(self):
+        response = test_get_rest_model_data('foobar')
+        self.assertEqual(response.status_code,400)
+        response_obj = simplejson.loads(response.content)
+        self.assertEqual(response_obj['error_type'],'RestInvalidDataTypeException')
+        
+    def test_resource_not_found(self):
+        response = test_get_rest_model_data('rest-test/foobar')
+        self.assertEqual(response.status_code,404)
+        response_obj = simplejson.loads(response.content)
+        self.assertEqual(response_obj['error_type'],'RestResourceNotFoundException')
+
+    def test_invalid_orderby(self):
+        response = test_get_rest_model_data('rest-test', {'orderby':'foobar'})
+        self.assertEqual(response.status_code,400)
+        response_obj = simplejson.loads(response.content)
+        self.assertEqual(response_obj['error_type'],'RestInvalidOrderByException')
+    
+    def test_hidden_model(self):
+        response = test_get_rest_model_data('restdisabledmodel')
+        self.assertEqual(response.status_code,400)
+        response_obj = simplejson.loads(response.content)
+        self.assertEqual(response_obj['error_type'],'RestInvalidDataTypeException')
+
+class ValidationTest(TestCase):
+    
+    DEFAULT_DATA = {'name':'foobar','enabled':True,'min':100,'range':30,'ip':'192.168.1.1','mac':'00:01:22:34:56:af','ratio':4.56,'color':'red'}
+    TEST_VECTORS = (
+        #update-dict, error-type, error-messgae
+        ({'min':99}, ['min'],'Min value validation failed'),
+        ({'range':8}, ['range'],'Min range validation failed'),
+        ({'range':2000}, ['range'],'Max range validation failed'),
+        ({'range':50}, None,'Model-level clean validation failed'),
+        ({'mac':'00:01:02:03:05'}, ['mac'],'Too short MAC address validation failed'),
+        ({'mac':'00:01:02:03:05:99:45'}, ['mac'],'Too long MAC address validation failed'),
+        ({'mac':'00,01,02,03,05,99'}, ['mac'],'MAC address separator char validation failed'),
+        ({'mac':'0r:01:02:03:05:99'}, ['mac'],'MAC address character validation failed'),
+        ({'mac':'123:01:02:03:05:99'}, ['mac'],'MAC address byte length validation failed'),
+        ({'color':'purple'}, ['color'],'Choices validation failed'),
+        ({'ip':'foobar'}, ['ip'], 'Invalid IP address char validation failed'),
+        ({'ip':'192.168.1'}, ['ip'], 'Too short IP address char validation failed'),
+        ({'ip':'192.168.1.0.5'}, ['ip'], 'Too long IP address char validation failed'),
+        ({'ip':'192,168,1,0'}, ['ip'], 'IP address separator char validation failed'),
+        ({'ip':'256.168.1.0'}, ['ip'], 'Out of range IP address byte validation failed'),
+        ({'min':99, 'ip':'256.168.1.0'}, ['min', 'ip'], 'Multiple field validation failed'),
+    )
+    
+    def check_response(self, response, invalid_fields, message):
+        self.assertEqual(response.status_code,400)
+        response_obj = simplejson.loads(response.content)
+        self.assertEqual(response_obj['error_type'], 'RestValidationException', message)
+        if invalid_fields:
+            self.assertEqual(response_obj.get('model_error'), None)
+            field_errors = response_obj.get('field_errors')
+            self.assertNotEqual(field_errors, None)
+            self.assertEqual(len(invalid_fields), len(field_errors), message)
+            for field_name in field_errors.keys():
+                self.assertTrue(field_name in invalid_fields, message)
+        else:
+            self.assertEqual(response_obj.get('field_errors'), None)
+            self.assertNotEqual(response_obj.get('model_error'), None)
+        # FIXME: Maybe check the description here too?
+        
+    def test_create_validation(self):
+        for test_data, invalid_fields, message in self.TEST_VECTORS:
+            data = self.DEFAULT_DATA.copy()
+            for name, value in test_data.items():
+                data[name] = value
+            put_response = test_put_rest_model_data(data, 'rest-test')
+            self.check_response(put_response, invalid_fields, message)
+            
+    def test_update_validation(self):
+        # First add an instance with the default data and check that it's OK
+        put_response = test_put_rest_model_data(self.DEFAULT_DATA, 'rest-test')
+        self.assertEqual(put_response.status_code,200)
+        
+        for test_data, invalid_fields, message in self.TEST_VECTORS:
+            put_response = test_put_rest_model_data(test_data, 'rest-test/foobar')
+            self.check_response(put_response, invalid_fields, message)
+
+
+class ConfigHandlerTest(TestCase):
+
+    TEST_DATA = {'name':'foobar','enabled':True,'min':100,'range':30,'ip':'192.168.1.1','mac':'00:01:22:34:56:af','ratio':4.56,'color':'red'}
+    
+    test_op = None
+    test_old_instance = None
+    test_new_instance = None
+    test_modified_fields = None
+    
+    @staticmethod
+    def reset_config_handler():
+        ConfigHandlerTest.test_op = None
+        ConfigHandlerTest.test_old_instance = None
+        ConfigHandlerTest.test_new_instance = None
+        ConfigHandlerTest.test_modified_fields = None
+    
+    @staticmethod
+    def config_handler(op, old_instance, new_instance, modified_fields):
+        ConfigHandlerTest.test_op = op
+        ConfigHandlerTest.test_old_instance = old_instance
+        ConfigHandlerTest.test_new_instance = new_instance
+        ConfigHandlerTest.test_modified_fields = modified_fields
+    
+    def check_config_handler(self, expected_op, expected_old_instance, expected_new_instance, expected_modified_fields):
+        self.assertEqual(ConfigHandlerTest.test_op, expected_op)
+        self.assertTrue(model_instances_equal(ConfigHandlerTest.test_old_instance, expected_old_instance))
+        self.assertTrue(model_instances_equal(ConfigHandlerTest.test_new_instance, expected_new_instance))
+        self.assertEqual(ConfigHandlerTest.test_modified_fields, expected_modified_fields)
+        
+    def test_config(self):
+        reset_last_config_state()
+        # Install the config handler
+        field_list = ['internal', 'min', 'mac']
+        add_config_handler({RestTestModel: field_list}, ConfigHandlerTest.config_handler)
+        
+        # Check that config handler is triggered on an insert
+        ConfigHandlerTest.reset_config_handler()
+        test = RestTestModel(**self.TEST_DATA)
+        test.save()
+        self.check_config_handler('INSERT', None, test, None)
+        
+        # Check that config handler is triggered on an update
+        ConfigHandlerTest.reset_config_handler()
+        expected_old = RestTestModel.objects.get(pk='foobar')
+        test.internal = 'check'
+        test.min = 125
+        test.save()
+        self.check_config_handler('UPDATE', expected_old, test, {'internal': 'check', 'min': 125})
+        
+        # Check that config handler is not triggered on an update to a field that
+        # it's not configured to care about
+        ConfigHandlerTest.reset_config_handler()
+        test.max = 500
+        test.save()
+        self.check_config_handler(None, None, None, None)
+        
+        # Check that config handler is triggered on a delete
+        ConfigHandlerTest.reset_config_handler()
+        test.delete()
+        # delete() clears the pk which messes up the instance
+        # comparison logic in check_config_handler, so we hack
+        # it back to the value it had before the delete
+        test.name = 'foobar'    
+        self.check_config_handler('DELETE', test, None, None)
+
+
+class CompoundKeyModelTest(TestCase):
+    
+    TEST_DATA = [
+        {'name': 'foo', 'index': 3},
+        {'name': 'foo', 'index': 7},
+        {'name': 'bar', 'index': 2, 'extra': 'abc'},
+        {'name': 'bar', 'index': 4, 'extra': 'test'},
+    ]
+    
+    def setUp(self):
+        for data in self.TEST_DATA:
+            test_put_rest_model_data(data, 'rest-compound-key')
+    
+    def check_query_results(self, actual_results, expected_results):
+        self.assertEqual(len(actual_results), len(expected_results))
+        actual_results = get_sorted_list(actual_results, 'id', False)
+        expected_results = copy.deepcopy(expected_results)
+        for expected_result in expected_results:
+            expected_result['id'] = expected_result['name'] + '|' + str(expected_result['index'])
+        expected_results = get_sorted_list(expected_results, 'id')
+        
+        for actual_result, expected_result in zip(actual_results, expected_results):
+            self.assertEqual(actual_result['id'], expected_result['id'])
+            self.assertEqual(actual_result['name'], expected_result['name'])
+            self.assertEqual(actual_result['index'], expected_result['index'])
+            expected_extra = expected_result.get('extra', 'dummy')
+            self.assertEqual(actual_result['extra'], expected_extra)
+                
+    def test_set_up(self):
+        response = test_get_rest_model_data('rest-compound-key')
+        self.assertEqual(response.status_code, 200)
+        actual_results = simplejson.loads(response.content)
+        self.check_query_results(actual_results, self.TEST_DATA)
+        
+    def test_delete_by_id(self):
+        test_delete_rest_model_data('rest-compound-key', {'id': 'foo|3'})
+        test_delete_rest_model_data('rest-compound-key', {'id': 'bar|4'})
+        response = test_get_rest_model_data('rest-compound-key')
+        self.assertEqual(response.status_code, 200)
+        actual_results = simplejson.loads(response.content)
+        self.check_query_results(actual_results, self.TEST_DATA[1:-1])
+    
+    def test_delete_by_fields(self):
+        test_delete_rest_model_data('rest-compound-key', {'name': 'bar', 'index': 4})
+        response = test_get_rest_model_data('rest-compound-key')
+        self.assertEqual(response.status_code, 200)
+        actual_results = simplejson.loads(response.content)
+        self.check_query_results(actual_results, self.TEST_DATA[:-1])
+        
+class UserDataTest(TestCase):
+    
+    TEST_DATA = [
+        # name, data, binary, content-type
+        ('test/foobar', 'hello world\nanother line', False, None),
+        ('test/json-test', '[0,1,2]', False, 'application/json'),
+        ('test/binary-test', '\x01\x02\x03\x04\x55', True, None),
+    ]
+    
+    MORE_TEST_DATA = [
+        ('moretests/foo1', 'moretest1', False, None),
+        ('moretests/foo2', 'moretest2', False, None),
+    ]
+    
+    def add_user_data(self, client, user_data):
+        for name, data, binary, content_type in user_data:
+            if not content_type:
+                if binary:
+                    content_type = 'application/octet-stream'
+                else:
+                    content_type = 'text/plain'
+            url = test_construct_rest_url('data/' + name, {'binary':binary})
+            response = client.put(url, data, content_type)
+            self.assertEquals(response.status_code, 200)
+
+    def check_expected_info_list(self, info_list, expected_info_list):
+        self.assertEqual(type(info_list), list)
+        info_list = get_sorted_list(info_list, 'name', True)
+        expected_info_list = get_sorted_list(expected_info_list, None, True)
+        self.assertEqual(len(info_list), len(expected_info_list))
+        for i in range(len(info_list)):
+            data = info_list[i]
+            expected_data = expected_info_list[i]
+            expected_name = expected_data[0]
+            expected_url_path = 'rest/v1/data/' + expected_name + '/'
+            self.assertEqual(data['name'], expected_name)
+            self.assertEqual(data['url_path'], expected_url_path)
+
+    def get_info_list(self, client, query_params=None):
+        url = test_construct_rest_url('data', query_params)
+        get_response = client.get(url)
+        self.assertEqual(get_response.status_code, 200)
+        info_list = simplejson.loads(get_response.content)
+        
+        # The view for listing user data items hard-codes inclusion of some
+        # *magic* user data items corresponding to the startup-config
+        # and update-config, depending on the presence of certain files
+        # in the file system. To make the unit tests work correctly if/when
+        # either/both of those items are added we do this filtering pass
+        # over the items returned from the REST API. Ugly hack!
+        info_list = [item for item in info_list if '-config' not in item['name']]
+        
+        return info_list
+
+    def test_user_data_basic(self):
+        c = Client()
+        self.add_user_data(c, self.TEST_DATA)
+        for name, data, binary, content_type in self.TEST_DATA:
+            if not content_type:
+                if binary:
+                    content_type = 'application/octet-stream'
+                else:
+                    content_type = 'text/plain'
+            url = test_construct_rest_url('data/' + name)
+            get_response = c.get(url)
+            self.assertEqual(get_response.content, data)
+            self.assertEqual(get_response['Content-Type'], content_type)
+
+    def test_user_data_delete(self):
+        c = Client()
+        
+        self.add_user_data(c, self.TEST_DATA)
+        self.add_user_data(c, self.MORE_TEST_DATA)
+        
+        # Do a delete with a query filter
+        url = test_construct_rest_url('data', {'name__startswith':'moretests/'})
+        response = c.delete(url)
+        self.assertEqual(response.status_code, 200)
+        
+        info_list = self.get_info_list(c)
+        expected_info_list = self.TEST_DATA
+        self.check_expected_info_list(info_list, expected_info_list)
+        
+        # Do a delete of a specific user data element
+        url = test_construct_rest_url('data/' + self.TEST_DATA[0][0])
+        response = c.delete(url)
+        self.assertEqual(response.status_code, 200)
+
+        info_list = self.get_info_list(c)
+        expected_info_list = self.TEST_DATA[1:]
+        self.check_expected_info_list(info_list, expected_info_list)
+
+    def test_user_data_info(self):
+
+        c = Client()
+        
+        self.add_user_data(c, self.TEST_DATA)
+        self.add_user_data(c, self.MORE_TEST_DATA)
+        
+        info_list = self.get_info_list(c)
+        expected_info_list = self.TEST_DATA + self.MORE_TEST_DATA
+        self.check_expected_info_list(info_list, expected_info_list)
+        
+        info_list = self.get_info_list(c, {'name__startswith':'test/'})
+        expected_info_list = self.TEST_DATA
+        self.check_expected_info_list(info_list, expected_info_list)
diff --git a/sdncon/rest/validators.py b/sdncon/rest/validators.py
new file mode 100755
index 0000000..856038a
--- /dev/null
+++ b/sdncon/rest/validators.py
@@ -0,0 +1,448 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+import re
+import os.path
+
+from django.forms import ValidationError
+from django.core.validators import RegexValidator, MinValueValidator, MaxValueValidator
+
+validate_mac_address = RegexValidator('^(([A-Fa-f\d]){2}:?){5}[A-Fa-f\d]{2}$', 'MAC address is a 48-bit quantity, expressed in hex as AA:BB:CC:DD:EE:FF', 'invalid')
+validate_dpid = RegexValidator('^([A-Fa-f\d]{2}:?){7}[A-Fa-f\d]{2}$', 'Switch DPID is a 64-bit quantity, expressed in hex as AA:BB:CC:DD:EE:FF:00:11', 'invalid')
+validate_controller_id = RegexValidator('^[A-Fa-f\d]{8}-([A-Fa-f\d]{4}-){3}[A-Fa-f\d]{12}$', 'Controller ID is a 128-bit quantity, expressed in hex as aabbccdd-eeff-0011-2233-445566778899', 'invalid')
+
+class UfwProtocolValditor(object):
+    def __init__(self):
+        pass
+    
+    def __call__(self, value):
+        if not (value != "tcp" or value != "udp" or value != 'vrrp'):
+            raise ValidationError("Protocol must be either 'tcp' or 'udp' or 'vrrp'")
+
+octet = r'(?:0|[1-9][0-9]*)'
+IP_RE = re.compile("^" + octet + '[.]' + octet
+                   + '[.]' + octet + '[.]' + octet + "$")
+
+class IpValidator(object):
+    def __call__(self, value):
+        if not IP_RE.match(value) or len([x for x in value.split('.') if int(x) < 256]) != 4:
+            raise ValidationError("IP must be in dotted decimal format, 234.0.59.1")
+            
+class IpMaskValidator(object):
+    def __call__(self, value):
+        if not IP_RE.match(value):
+            raise ValidationError("IP must be in dotted decimal format, 255.255.128.0")
+        invalid_netmask = False
+        invalid_inverse_netmask = False
+        lookForZero = False
+        for x in value.split('.'):
+            xInt = int(x)
+            if lookForZero:
+                if xInt:
+                    invalid_netmask = True
+                    break  # go check inverse mask
+            if xInt != 255:
+                if xInt:
+                    if xInt >= 128:
+                        while (xInt % 2) == 0:
+                            xInt = xInt >> 1
+                        if xInt & (xInt + 1) == 0:
+                            continue
+                    invalid_netmask = True
+                    break # go check inverse mask
+                lookForZero = True
+
+        lookForOne = False
+        for x in value.split('.'):
+            xInt = int(x)
+            if lookForOne: # all bits should be 1 bits
+                if (xInt != 255):
+                    invalid_inverse_netmask = True
+                    break
+                else:
+                    continue
+            if xInt != 0:
+                # check for contiguous 1-bits from LSb
+                lookForOne = True
+                if xInt == 255:
+                    continue
+                if xInt & (xInt + 1) != 0:
+                    invalid_inverse_netmask = True
+                    break
+        if invalid_netmask and invalid_inverse_netmask: # no valid mask, then raise exception
+            raise ValidationError("Invalid IP Mask, should be like 255.255.128.0 or 0.0.127.255")
+
+
+class PortRangeSpecValidator(object):
+    def __init__(self):
+        self.RANGE_RE = re.compile(r'^([A-Za-z0-9-/\.:]*?)(\d+)\-(\d+)$')
+        self.SINGLE_RE = re.compile(r'^([A-Za-z0-9-/\.:]+)$')
+    def __call__(self, value):
+        values = value.split(',')
+        for v in values:
+            m = self.RANGE_RE.match(v);
+            if (m):
+                startport = int(m.group(2))
+                endport = int(m.group(3))
+                if (startport >= endport):
+                    raise ValidationError("Invalid range numerals: %d-%d" % (startport, endport))
+            elif not self.SINGLE_RE.match(v):
+                raise ValidationError("Must be a list of ports or ranges, such as 'A10-15,B25,C1-13'")
+
+class VLANRangeSpecValidator(object):
+    def __init__(self):
+        self.RANGE_RE = re.compile(r'^([\d]+)\-([\d]+)$')
+        self.SINGLE_RE = re.compile(r'^[\d]+$')
+
+    def __call__(self, value):
+        values = value.split(',')
+        for v in values:
+            m = self.RANGE_RE.match(v);
+            if v == 'untagged':
+                pass
+            elif (m):
+                if (int(m.group(1)) >= int(m.group(2))):
+                    raise ValidationError("Invalid range numerals in {}: {} must be less than {}".format(v, m.group(1), m.group(2)))
+                elif (int(m.group(1)) > 4095):
+                    raise ValidationError("Invalid VLAN: {} must be in range 0-4095".format(m.group(1)))
+                elif (int(m.group(2)) < 0):
+                    raise ValidationError("Invalid VLAN: {} must be in range 0-4095".format(m.group(2)))
+            elif not self.SINGLE_RE.match(v):
+                raise ValidationError("Must be a list of VLANs or ranges,"
+                                      " such as '5-20,45,4053,untagged'")
+            elif int(v) > 4095 or int(v) < 0:
+                raise ValidationError("Invalid VLAN: {} must be in range 0-4095".format(v))
+
+class TagSpecValidator(object):
+    def __init__(self):
+        self.TAG_NAME_RE = re.compile(r'^([a-zA-Z0-9_-]+(?:\.?[a-zA-Z0-9_-]+)*)=+([a-zA-Z0-9_-]+)$')
+
+    def __call__(self,value):
+        values = value.split(',')
+        for v in values:
+            v = v.strip()
+            if not self.TAG_NAME_RE.match(v):
+                raise ValidationError("Invalid tag: " + 
+                        '='.join(v.split('|')) +
+                        "\nFormat: tag namespace.namel value1, " +
+                        "where namespace may be empty or must be a-z, A-Z, 0-9, -, . or _, " + 
+                        "name and value must be a-z, A-Z, 0-9, - or _")
+
+class CidrValidator(object):
+    def __init__(self, mask_required=True):
+        self.mask_required = mask_required
+        self.CIDR_RE = re.compile(r'^(\d{1,3}\.){3}\d{1,3}/\d{1,2}?$')
+
+    def __call__(self, value):
+        ip_validator = IpValidator()
+        if self.CIDR_RE.match(value):
+            ip, mask = value.split('/')
+            ip_validator(ip)
+            if int(mask) < 1 or int(mask) > 32:
+                raise ValidationError("Mask should be between 1-32")
+        else:
+            if self.mask_required: # if mask was required and we didn't match above, problem!
+                raise ValidationError("Must be in dotted decimal format with a mask between 1-32")
+            else:
+                ip_validator(value)
+        
+class EnumerationValidator(object):
+    def __init__(self, enumerated_values, case_sensitive=False, message=None, code=None):
+        self.case_sensitive = case_sensitive
+        if case_sensitive:
+            self.enumerated_values = enumerated_values
+        else:
+            self.enumerated_values = [s.lower() for s in enumerated_values]
+        if not message:
+            message = 'Invalid enumerated value'
+        self.message = message
+        if not code:
+            code = 'invalid'
+        self.code = code
+
+    def __call__(self, value):
+        if not self.case_sensitive:
+            value = value.lower()
+        if value not in self.enumerated_values:
+            raise ValidationError(self.message, self.code)
+
+class ChoicesValidator(EnumerationValidator):
+    def __init__(self, choices, case_sensitive=False, message=None, code=None):
+        enumerated_values = [choice[0] for choice in choices]
+        EnumerationValidator.__init__(self, enumerated_values, case_sensitive, message, code)
+
+class RangeValidator(object):
+    def __init__(self, min, max):
+        self.min_value_validator = MinValueValidator(min)
+        self.max_value_validator = MaxValueValidator(max)
+
+    def __call__(self, value):
+        try:
+            self.min_value_validator(int(value))
+            self.max_value_validator(int(value))
+        except ValidationError:
+            raise ValidationError('Ensure this value is within the range (%d-%d)' %
+                                  (self.min_value_validator.limit_value,
+                                   self.max_value_validator.limit_value))
+
+class ControllerAliaVsalidator(object):
+    def __init__(self):
+        self.CONTROLLER_ALIAS_RE = re.compile(r'^[a-zA-Z0-9_-]+$')
+
+    def __call__(self, value):
+        if not self.CONTROLLER_ALIAS_RE.match(value):
+            raise ValidationError("controller alias name must ba a-z, 0-9, _ or _")
+
+class SwitchAliasValidator(object):
+    def __init__(self):
+        self.SWITCH_ALIAS_RE = re.compile(r'^[a-zA-Z0-9_-]+$')
+
+    def __call__(self, value):
+        if not self.SWITCH_ALIAS_RE.match(value):
+            raise ValidationError("switch alias name must ba a-z, 0-9, _ or _")
+
+class PortAliasValidator(object):
+    def __init__(self):
+        self.PORT_ALIAS_RE = re.compile(r'^[a-zA-Z0-9_-]+$')
+
+    def __call__(self, value):
+        if not self.PORT_ALIAS_RE.match(value):
+            raise ValidationError("port alias name must ba a-z, 0-9, _ or _")
+
+class HostAliasValidator(object):
+    def __init__(self):
+        self.HOST_ALIAS_RE = re.compile(r'^[a-zA-Z0-9_-]+$')
+
+    def __call__(self, value):
+        if not self.HOST_ALIAS_RE.match(value):
+            raise ValidationError("host alias name must ba a-z, 0-9, _ or _")
+
+class AddressSpaceNameValidator(object):
+    def __init__(self):
+        self.ADDRESS_SPACE_NAME_RE = re.compile(r'^[a-zA-Z0-9_-]+$')
+
+    def __call__(self,value):
+        if not self.ADDRESS_SPACE_NAME_RE.match(value):
+            raise ValidationError("address-space name must be a-z, A-Z, 0-9, - or _")
+
+class TenantNameValidator(object):
+    def __init__(self):
+        self.TENANT_NAME_RE = re.compile(r'^[a-zA-Z0-9_-]+$')
+
+    def __call__(self,value):
+        if not self.TENANT_NAME_RE.match(value):
+            raise ValidationError("tenant name must be a-z, A-Z, 0-9, - or _")
+
+class GeneralNameValidator(object):
+    def __init__(self):
+        self.GENERAL_NAME_RE = re.compile(r'^[a-zA-Z0-9_-]+$')
+
+    def __call__(self,value):
+        if not self.GENERAL_NAME_RE.match(value):
+            raise ValidationError("Name must be a-z, A-Z, 0-9, - or _")
+
+class VnsNameValidator(object):
+    def __init__(self):
+        self.VNS_NAME_RE = re.compile(r'^[a-zA-Z0-9_-]+$')
+
+    def __call__(self,value):
+        if not self.VNS_NAME_RE.match(value):
+            raise ValidationError("vns name must be a-z, A-Z, 0-9, - or _")
+
+class VnsInterfaceNameValidator(object):
+    def __init__(self):
+        self.VNS_INTERFACE_RE = re.compile(r'^[a-zA-Z0-9_-]+$')
+        self.PORT_RE = re.compile(r'^([A-Za-z0-9-]*?)(\d+)$')
+        self.MAC_RE = re.compile(r'^(([A-Fa-f\d]){2}:?){5}[A-Fa-f\d]{2}$')
+
+    def __call__(self,value):
+        if not self.VNS_INTERFACE_RE.match(value):
+            items = value.split('/')
+            if len(items) == 2:
+                if not self.PORT_RE.match(items[1]) and \
+                    not self.MAC_RE.match(items[1]):
+                        raise ValidationError("interface name after '/' must be either a port or a mac address")
+            else:
+                raise ValidationError("invalid syntax for interface name")
+
+class VnsAclNameValidator(object):
+    def __init__(self):
+        self.VNS_ACL_NAME_RE = re.compile(r'[a-zA-Z0-9_-]+$')
+
+    def __call__(self,value):
+        if not self.VNS_ACL_NAME_RE.match(value):
+            raise ValidationError("acl name must be a-z, A-Z, 0-9, - or _")
+
+class VnsAclEntryActionValidator(object):
+    def __call__(self,value):
+        if not "permit".startswith(value.lower()) and \
+           not "deny".startswith(value.lower()):
+            raise ValidationError("acl entry action must be 'permit' or 'deny'")
+
+class VnsInterfaceAclInOutValidator(object):
+    def __call__(self,value):
+        if not "in".startswith(value.lower()) and \
+           not "out".startswith(value.lower()):
+            raise ValidationError("acl entry action must be 'permit' or 'deny'")
+
+class VnsRuleNameValidator(object):
+    def __init__(self):
+        self.IF_NAME_RE = re.compile(r'^\d*$')
+
+    def __call__(self, value):
+        if not self.IF_NAME_RE.match(value):
+            print value
+            raise ValidationError("Invalid rule name, only digits allowed")
+
+class TagNameValidator(object):
+    def __init__(self):
+        self.TAG_NAME_RE = re.compile(r'^[a-zA-Z0-9_-]+(?:\.?[a-zA-Z0-9_-]+)*(?:\|[a-zA-Z0-9_-]+)+$')
+
+    def __call__(self,value):
+        if not self.TAG_NAME_RE.match(value):
+            raise ValidationError("Invalid tag: " + value + "\nFormat: tag namespace|namel|value1, " +
+                        "where namespace may be empty or must be a-z, A-Z, 0-9, -, . or _, " + 
+                        "name and value must be a-z, A-Z, 0-9, - or _")
+
+
+class VnsArpModeValidator(object):
+    def __init__(self):
+        self.ARP_MODES = ['flood-if-unknown', 'always-flood', 'drop-if-unknown']
+
+    def __call__(self,value):
+        if not value in self.ARP_MODES:
+            raise ValidationError("must be one of %s" % ', '.join(self.ARP_MODES))
+
+class VnsDhcpModeValidator(object):
+    def __init__(self):
+        self.DHCP_MODES = ['flood-if-unknown', 'always-flood', 'static']
+
+    def __call__(self,value):
+        if not value in self.DHCP_MODES:
+            raise ValidationError("must be one of %s" % ', '.join(self.DHCP_MODES))
+
+class VnsBroadcastModeValidator(object):
+    def __init__(self):
+        self.BROADCAST_MODES = ['drop', 'always-flood', 'forward-to-known']
+
+    def __call__(self,value):
+        if not value in self.BROADCAST_MODES:
+            raise ValidationError("must be one of %s" % ', '.join(self.BROADCAST_MODES))
+        
+class IntfNameValidator(object):
+    def __init__(self):
+        self.IntfName_RE = re.compile(r'^ethernet[0-9]')
+        
+    def __call__(self, value):
+        if not self.IntfName_RE.match(value):
+            raise ValidationError("Interface name must be Ethernet<num>")
+
+class DomainNameValidator(object):
+    def __init__(self):
+        self.DomainName_RE = re.compile(r'^([a-zA-Z0-9-]+.?)+$')
+    def __call__(self,value):
+        if not self.DomainName_RE.match(value):
+            raise ValidationError("Value must be a valid domain name")
+
+class IpOrDomainNameValidator(object):
+    def __init__(self):
+        self.DomainName_RE = re.compile(r'^([a-zA-Z0-9-]+.?)+$')
+        
+    def __call__(self,value):
+        if not IP_RE.match(value) and not self.DomainName_RE.match(value):
+            raise ValidationError("Value must be a valid IP address or domain name")
+        
+class TimeZoneValidator(object):
+    timezones = None
+    def __call__(self, value):
+        if not TimeZoneValidator.timezones:
+            import pytz
+            TimeZoneValidator.timezones = pytz.all_timezones
+        if value not in TimeZoneValidator.timezones:
+            raise ValidationError("Invalid time zone string")
+        
+class VCenterMgrIdsValidator(object):
+    def __init__(self):
+        self.VCenterMgrId_RE = re.compile(r'^[a-zA-Z]([a-zA-Z0-9_-])*')
+    def __call__(self,value):
+        if not self.VCenterMgrId_RE.match(value):
+            raise ValidationError("Value must be a valid name, starts with a alphabet and can have alphabets, numbers, _ and -")
+        
+class VCenterObjNamesValidator(object):
+    def __init__(self):
+        self.VCenterObjName_RE = re.compile(r'(?!.*\|.*)')
+    def __call__(self, value):
+        if not self.VCenterObjName_RE.match(value):
+            raise ValidationError("VCenter object names can contain any character except '|'")        
+    
+class FeatureValidator(object):
+    """Validates that a specific feature has been installed
+
+    We assume that a feature has been installed if the following file exists:
+        {sdncon.SDN_ROOT}/feature/<feature-name>
+
+    NOTE: The feature is enabled/disabled for use by updating the controller
+    object, this validator just ensures that before we enable a feature, it
+    has been actually installed.
+    """
+    def __init__(self, feature, featuredir=None):
+        self.feature = feature
+        if featuredir is None:
+            featuredir = \
+                    os.path.join(os.path.sep, 'opt', 'sdnplatform', 'feature')
+        self.featurefile = os.path.join(featuredir, feature)
+
+    def __call__(self, value):
+        if value and not os.path.isfile(self.featurefile):
+            raise ValidationError(
+                    'Feature not installed, please install "%s"' %
+                    self.feature)
+
+class VlanStringValidator(object):
+    def __call__(self, value):
+        self.vlan = 0
+        try:
+            self.vlan = int(value)
+            if (self.vlan < 1 or self.vlan > 4095):
+                raise ValidationError("VLAN must be in the range of 1 to 4095 with 4095 as untagged")
+        except ValueError:
+            raise ValidationError(
+             "VLAN must be in the range of 1 to 4095 with 4095 as untagged")
+
+
+class SafeForPrimaryKeyValidator(object):
+    """Validates that a string does not contain any character that would be 
+    illegal for use in a primary key. Currently this is the pipe | symbol
+    """
+
+    def __call__(self, value):
+        if "|" in value:
+            raise ValidationError(
+             "The pipe symbol '|' is not a valid character")
+        
+
+class IsRegexValidator(object):
+    """Validates that a given string is a valid regular expression
+    """
+
+    def __call__(self, value):
+        try:
+            value = str(value)
+            re.compile(value)
+        except re.error as e:
+            raise ValidationError(
+              "Input is not a valid regular expression: %s", e)
+
diff --git a/sdncon/rest/views.py b/sdncon/rest/views.py
new file mode 100755
index 0000000..66dc75a
--- /dev/null
+++ b/sdncon/rest/views.py
@@ -0,0 +1,2208 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+#      http://www.eclipse.org/legal/epl-v10.html
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+
+from django.db.models import AutoField, BooleanField, IntegerField, FloatField, ForeignKey
+from django.forms import ValidationError
+from django.http import HttpResponse
+from django.utils import simplejson
+from functools import wraps
+#from sdncon.controller.models import Controller
+#from sdncon.controller.models import ControllerAlias, ControllerDomainNameServer, ControllerInterface, FirewallRule
+#from sdncon.controller.models import Switch, Port, PortAlias, Link
+from sdncon.rest.models import UserData
+from sdncon.controller.notification import begin_batch_notification, end_batch_notification
+from django.views.decorators.csrf import csrf_exempt
+import base64
+import urllib
+import urllib2
+import sys
+import json
+import os
+import re
+import time
+import traceback
+import collections
+import uuid
+import subprocess
+from datetime import datetime
+from sdncon.controller.oswrapper import exec_os_wrapper
+from sdncon.controller.config import get_local_controller_id
+from sdncon.rest.config import config_check_state
+from sdncon.controller.oswrapper import get_system_version_string
+import sdncon
+
+TEXT_PLAIN_CONTENT_TYPE = 'text/plain'
+TEXT_JAVASCRIPT_CONTENT_TYPE = 'text/javascript'
+JSON_CONTENT_TYPE = 'application/json'
+BINARY_DATA_CONTENT_TYPE = 'application/octet-stream'
+
+onos = 1
+
+if onos == 1:
+    #CONTROLLER_URL_PREFIX = 'http://localhost:9000/wm/'
+    CONTROLLER_URL_PREFIX = 'http://localhost:8080/wm/'
+else:
+    CONTROLLER_URL_PREFIX = 'http://localhost:8080/wm/'
+
+def controller_url(*elements):
+    return CONTROLLER_URL_PREFIX + '/'.join(elements)
+
+class RestException(Exception):
+    pass
+        
+class RestInvalidDataTypeException(RestException):
+    def __init__(self, name):
+        super(RestInvalidDataTypeException,self).__init__('Invalid data type: ' + name)
+
+class RestInvalidMethodException(RestException):
+    def __init__(self):
+        super(RestInvalidMethodException,self).__init__('Invalid HTTP method')
+
+class RestResourceNotFoundException(RestException):
+    def __init__(self, url):
+        super(RestResourceNotFoundException,self).__init__('Resource not found: ' + url)
+
+class RestDatabaseConnectionException(RestException):
+    def __init__(self):
+        super(RestDatabaseConnectionException,self).__init__('Error connecting to database')
+        
+class RestAuthenticationRequiredException(RestException):
+    def __init__(self):
+        super(RestAuthenticationRequiredException,self).__init__('Authentication required')
+
+class RestInvalidQueryParameterException(RestException):
+    def __init__(self, param_name):
+        super(RestInvalidQueryParameterException, self).__init__('Invalid query parameter: ' + str(param_name))
+
+class RestInvalidFilterParameterException(RestException):
+    def __init__(self, param_name):
+        super(RestInvalidFilterParameterException, self).__init__('Filter query parameters not allowed when URL contains resource iD: ' + str(param_name))
+
+class RestNoListResultException(RestException):
+    def __init__(self):
+        super(RestNoListResultException, self).__init__('The query result must be a single instance if the "nolist" query param is set')
+
+class RestInvalidPutDataException(RestException):
+    def __init__(self):
+        super(RestInvalidPutDataException, self).__init__('The request data for a PUT request must be a JSON dictionary object')
+
+class RestMissingRequiredQueryParamException(RestException):
+    def __init__(self, param_name):
+        super(RestMissingRequiredQueryParamException, self).__init__('Missing required query parameter: ' + str(param_name))
+
+class RestValidationException(RestException):
+    def __init__(self, model_error=None, field_errors=None):
+        # Build the exception message from model error and field errors
+        message = 'Validation error'
+        if model_error:
+            message = message + '; ' + model_error
+        if field_errors:
+            message += '; invalid fields: {'
+            first_time = True
+            for field_name, field_message in field_errors.items():
+                if not first_time:
+                    message += '; '
+                else:
+                    first_time = False
+                message = message + field_name + ': ' + field_message
+                
+            message += '}'
+            
+        super(RestValidationException, self).__init__(message)
+        self.model_error = model_error
+        self.field_errors = field_errors
+        
+class RestModelException(RestException):
+    def __init__(self, exc):
+        super(RestModelException, self).__init__('Error: ' + str(exc))
+
+class RestSaveException(RestException):
+    def __init__(self, exc):
+        super(RestSaveException, self).__init__('Error saving data: ' + str(exc))
+
+class RestInvalidOrderByException(RestException):
+    def __init__(self,field_name):
+        super(RestInvalidOrderByException, self).__init__('Invalid orderby field: ' + field_name)
+        
+class RestInternalException(RestException):
+    def __init__(self, exc):
+        super(RestInternalException,self).__init__('Unknown REST error: ' + unicode(exc))
+
+class RestUpgradeException(RestException):
+    def __init__(self, exc):
+        super(RestUpgradeException, self).__init__('Error: ' + str(exc))
+
+class RestProvisionException(RestException):
+    def __init__(self, exc):
+        super(RestProvisionException, self).__init__('Error: ' + str(exc))
+
+class RestDecommissionException(RestException):
+    def __init__(self, exc):
+        super(RestDecommissionException, self).__init__('Error: ' + str(exc))
+
+class RestInvalidLog(RestException):
+    def __init__(self, exc):
+        super(RestInvalidLog, self).__init__('Error: ' + str(exc))
+
+def handle_validation_error(model_info, validation_error):
+    model_error = None
+    field_errors = None
+    if hasattr(validation_error, 'message_dict'):
+        # The field errors we get in the ValidationError are a bit different
+        # then what we want for the RestValidationException. First, we
+        # need to convert the Django field name to the (possibly renamed)
+        # REST field name. Second, the per-field error message is possibly a
+        # list of messages, which we concatenate into a single string for the
+        # RestValidationException
+        for field_name, field_message in validation_error.message_dict.items():
+            if type(field_message) in (list, tuple):
+                converted_field_message = ''
+                for msg in field_message:
+                    converted_field_message = converted_field_message + msg + ' '
+            else:
+                converted_field_message += unicode(field_message)
+            if field_name == '__all__':
+                model_error = converted_field_message
+            else:
+                if not field_errors:
+                    field_errors = {}
+                field_info = model_info.field_name_dict.get(field_name)
+                if field_info:
+                    field_errors[field_info.rest_name] = converted_field_message
+                else:
+                    field_errors[field_name] = 'Private field invalid; ' + converted_field_message
+    elif hasattr(validation_error, 'messages'):
+        model_error = ':'.join(validation_error.messages)
+    else:
+        model_error = str(validation_error)
+    raise RestValidationException(model_error, field_errors)
+
+def get_successful_response(description=None, status_code=200):
+    content = get_successful_response_data(description)
+    return HttpResponse(content, JSON_CONTENT_TYPE, status_code)
+
+def get_successful_response_data(description = 'success'):
+    obj = {'description': description}
+    return simplejson.dumps(obj)
+ 
+def get_sdnplatform_response(url, timeout = None):
+    
+    try:
+        response_text = urllib2.urlopen(url, timeout=timeout).read()
+        return HttpResponse(response_text, JSON_CONTENT_TYPE)
+    except urllib2.HTTPError, e:
+        response_text = e.read()
+        response = simplejson.loads(response_text)
+        response['error_type'] = "SDNPlatformError"
+        return HttpResponse(content=simplejson.dumps(response), 
+                            status=e.code, 
+                            content_type=JSON_CONTENT_TYPE)
+
+def get_sdnplatform_query(request, path):
+    """
+    This returns controller-level storage table list
+    """
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    url = controller_url(path) + '/?%s' % request.META['QUERY_STRING']
+    return get_sdnplatform_response(url)        
+
+def safe_rest_view(func):
+    """
+    This is a decorator that takes care of exception handling for the
+    REST views so that we return an appropriate error HttpResponse if
+    an exception is thrown from the view
+    """
+    @wraps(func)
+    def _func(*args, **kwargs):
+        try:
+            response = func(*args, **kwargs)
+        except Exception, exc:
+            end_batch_notification(True)
+            if not isinstance(exc, RestException):
+                # traceback.print_exc()
+                exc = RestInternalException(exc)
+            response_obj = {'error_type': exc.__class__.__name__, 'description': unicode(exc)}
+            if isinstance(exc, RestValidationException):
+                if exc.model_error:
+                    response_obj['model_error'] = exc.model_error
+                if exc.field_errors:
+                    response_obj['field_errors'] = exc.field_errors
+            content = simplejson.dumps(response_obj)
+            content_type = JSON_CONTENT_TYPE
+            
+            if isinstance(exc, RestInvalidMethodException):
+                status_code = 405
+            elif isinstance(exc, RestResourceNotFoundException):
+                status_code = 404
+            elif isinstance(exc, RestInternalException):
+                status_code = 500
+            else:
+                status_code = 400
+            response = HttpResponse(content, content_type, status_code)
+            if isinstance(exc, RestInvalidMethodException):
+                response['Allow'] = "GET, PUT, DELETE"
+        return response
+    return _func
+
+rest_model_info_dict = {}
+
+class RestFieldInfo(object):
+    def __init__(self, name, django_field_info, hidden=False,
+                 rest_name=None, json_serialize=False):
+        self.name = name
+        self.django_field_info = django_field_info
+        self.rest_name = rest_name
+        self.json_serialize = json_serialize
+        
+class RestModelInfo(object):
+    def __init__(self, rest_name, model_class):
+        self.rest_name = rest_name
+        self.model_class = model_class
+        self.primary_key = None
+        self.field_name_dict = {}
+        self.rest_name_dict = {}
+        
+        for field in model_class._meta.local_fields:
+            field_name = field.name
+            rest_name = field.name
+            if field.primary_key:
+                self.primary_key = field_name
+            # TODO: Are there other field types that should be included here?
+            json_serialize =  type(field) not in (AutoField, BooleanField, IntegerField, FloatField)
+            self.set_field_info(field_name, rest_name, field, json_serialize)
+
+    
+    # this is how a RestFieldInfo is created - pass in django_field_info
+    def get_field_info(self, field_name, django_field_info=None):
+        field_info = self.field_name_dict.get(field_name)
+        if not field_info and django_field_info:
+            field_info = RestFieldInfo(field_name, django_field_info)
+            self.field_name_dict[field_name] = field_info
+        return field_info
+    
+    def hide_field(self, field_name):
+        field_info = self.get_field_info(field_name)
+        del self.field_name_dict[field_name]
+        del self.rest_name_dict[field_info.rest_name]
+        
+    def set_field_info(self, field_name, rest_name, django_field_info, json_serialize=None):
+        field_info = self.get_field_info(field_name, django_field_info)
+        if field_info.rest_name in self.rest_name_dict:
+            del self.rest_name_dict[field_info.rest_name]
+        field_info.rest_name = rest_name
+        if json_serialize != None:
+            field_info.json_serialize = json_serialize
+        self.rest_name_dict[rest_name] = field_info
+
+def get_rest_model_info(name):
+    return rest_model_info_dict[name]
+
+def add_rest_model_info(info):
+    if rest_model_info_dict.get(info.rest_name):
+        raise RestException('REST model info already exists')
+    rest_model_info_dict[info.rest_name] = info
+    
+rest_initialized = False
+
+def get_default_rest_name(model):
+    # TODO: Ideally should do something a bit smarter here.
+    # Something like convert from camel-case class names to hyphenated names:
+    # For example:
+    #  MyTestClass => my-test-class
+    #  MyURLClass => my-url-class
+    #
+    # This isn't super-important for now, since you can set it explicitly
+    # with the nested Rest class.
+    return model.__name__.lower()
+
+def initialize_rest():
+    global rest_initialized
+    if rest_initialized:
+        return
+    
+    from django.db.models import get_models
+    for model in get_models():
+                
+        # If the model class has a nested class named 'Rest' then that means
+        # the model should be exposed in the REST API.
+        if hasattr(model, 'Rest'):
+            # By default the REST API uses the lower-case-converted name
+            # of the model class as the name in the REST URL, but this can
+            # be overridden by defining the 'NAME' attribute in the Rest class.
+            if hasattr(model.Rest, 'NAME'):
+                rest_name = model.Rest.NAME
+            else:
+                rest_name = get_default_rest_name(model)
+
+            if model._meta.proxy:
+                # This is a proxy class, drop through to the real one
+                base_model = model._meta.proxy_for_model
+            else:
+                base_model = model
+            
+            # OK, we have the basic REST info, so we can create the info class
+            rest_model_info = RestModelInfo(rest_name, base_model)
+            
+            # Check if there are any private or renamed fields
+            if hasattr(model.Rest, 'FIELD_INFO'):
+                for field_info in model.Rest.FIELD_INFO:
+                    field_name = field_info['name']
+                    rest_field_info = rest_model_info.get_field_info(field_name)
+                    # Check if field exists in models - don't allow field only here in FIELD_INFO)
+                    if not rest_field_info:
+                        # LOOK! This field only exists in FIELD_INFO - skip
+                        print "ERROR: %s for %s only in FIELD_INFO" % (field_name, rest_name)
+                        continue
+                    
+                    if field_info.get('private', False):
+                        rest_model_info.hide_field(field_name)
+                    else:
+                        rest_name = field_info.get('rest_name')
+                        if rest_name:
+                            rest_model_info.set_field_info(field_name, rest_name, rest_field_info.django_field_info)
+            
+            # Finished setting it up, so now add it to the list
+            add_rest_model_info(rest_model_info)
+    
+    rest_initialized = True
+
+initialize_rest()
+
+@safe_rest_view
+def do_model_list(request):
+    """
+    This returns the list of models available in the REST API.
+    """
+    
+    json_model_list = []
+    for model_name in rest_model_info_dict.keys():
+        json_model_info = {}
+        json_model_info["name"] = model_name
+        json_model_info["url_path"] = "rest/v1/model/" + model_name + "/"
+        json_model_list.append(json_model_info)
+
+    json_data = simplejson.dumps(json_model_list)
+    return HttpResponse(json_data, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_realtimestats(request, stattype, dpid):
+    """
+    This returns realtime statistics (flows, ports, table, aggregate,
+    desc, ...)  for a dpid by calling the localhost sdnplatform
+    """
+    #raise RestInvalidMethodException()
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    #url = controller_url('core', 'switch', dpid, stattype, 'json')
+    if stattype == 'group':
+        stattype = 'groupStats'
+    if stattype == 'groupdesc':
+        stattype = 'groupDesc'
+    url = "http://localhost:8080/wm/floodlight/core/switch/%s/%s/json" % (dpid, stattype)
+    return get_sdnplatform_response(url)
+
+@safe_rest_view
+def do_realtimegroupstats(request, groupId, dpid ):
+    """
+    This returns realtime group statistics for specified groupId
+    for a dpid by calling the localhost sdnplatform
+    """
+    #raise RestInvalidMethodException()
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    #url = controller_url('core', 'switch', dpid, stattype, 'json')
+    #import error
+    #raise error.ArgumentValidationError('\n\n\n %s' % (groupId))
+    url = "http://localhost:8080/wm/floodlight/core/switch/%s/groupStats/%s/json" % (dpid, groupId)
+    return get_sdnplatform_response(url)
+
+@safe_rest_view
+def do_tablerealtimestats(request, tabletype, dpid):
+    """
+    This returns realtime statistics per table (flows (only)
+    current implementation)  for a dpid by calling the localhost sdnplatform
+    """
+    #raise RestInvalidMethodException()
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    #url = controller_url('core', 'switch', dpid, stattype, 'json')
+    url = "http://localhost:8080/wm/floodlight/core/switch/%s/table/%s/flow/json" % (dpid,tabletype)
+    #url ="http://localhost:8080/wm/floodlight/core/switch/00:00:00:00:00:00:00:01/flow/json"
+    return get_sdnplatform_response(url)
+
+@safe_rest_view
+def do_sdnplatform_realtimestats(request, stattype, dpid=None, portid=None):
+    """
+    This returns realtime statistics from sdnplatform
+    """
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    if dpid == None:
+        url = controller_url('core', 'counter', stattype, 'json')
+    elif portid == None:
+        url = controller_url('core', 'counter', dpid, stattype, 'json')
+    else:
+        url = controller_url('core', 'counter', dpid, portid, stattype, 'json')
+    return get_sdnplatform_response(url)
+
+@safe_rest_view
+def do_topology_tunnel_verify(request, srcdpid=None, dstdpid=None):
+    """
+    This initiates a liveness detection of tunnels.
+    """
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+
+    urlstring = srcdpid + '/' + dstdpid
+    url = controller_url('topology/tunnelverify', urlstring, 'json')
+
+    response_text = urllib2.urlopen(url).read()
+    time.sleep(4)
+    return do_topology_tunnel_status(request, srcdpid, dstdpid)
+
+@safe_rest_view
+def do_topology_tunnel_status(request, srcdpid='all', dstdpid='all'):
+    """
+    This returns the list of tunnels that have failed over the last observation interval.
+    """
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+
+    urlstring = srcdpid + '/' + dstdpid
+    url = controller_url('topology/tunnelstatus', urlstring, 'json')
+    response_text = urllib2.urlopen(url).read()
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_sdnplatform_realtimestatus(request, category=None, subcategory=None, srcdpid=None, dstdpid = None):
+    """
+    This returns realtime status of sdnplatform
+    """
+
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+
+    response_text = None
+    url = None
+    if category == 'network':
+        if subcategory == 'cluster':
+            url = controller_url('topology', 'switchclusters', 'json')
+        if subcategory == 'externalports':
+            url = controller_url('topology', 'externalports', 'json')
+        if subcategory == 'tunnelverify':
+            urlstring = subcategory+ '/' + srcdpid + '/' + dstdpid
+            url = controller_url('topology', urlstring, 'json')
+        if subcategory == 'tunnelstatus':
+            url = controller_url('topology', 'tunnelstatus', 'json')
+
+    if url:
+        response_text = urllib2.urlopen(url).read()
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_sdnplatform_realtimetest(http_request, category=None, subcategory=None):
+    """
+    This does a realtime test by sending an "explain packet" as packet in 
+    and collecting the operations performed on the packet
+    """
+
+    if http_request.method != 'PUT':
+        raise RestInvalidMethodException()
+
+    response_text = None
+    url = None
+    if category == 'network':
+        if subcategory == 'explain-packet':
+            # set up the sdnplatform URL for explain packet (at internal port 8080
+            url = controller_url('vns', 'explain-packet', 'json')
+            post_data = http_request.raw_post_data
+            request = urllib2.Request(url, post_data)
+            request.add_header('Content-Type', 'application/json')
+            response = urllib2.urlopen(request)
+            response_text = response.read()
+        elif subcategory == 'path':
+            post_data = json.loads(http_request.raw_post_data)
+            url = controller_url('topology', 'route',
+                                 post_data['src-switch'],
+                                 str(post_data['src-switch-port']),
+                                 post_data['dst-switch'],
+                                 str(post_data['dst-switch-port']),
+                                 'json')
+
+            return get_sdnplatform_response(url)
+
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_sdnplatform_performance_monitor(http_request, category=None,
+                    subcategory=None, type='all'):
+    """
+    This API returns performance related information from the sdnplatform and
+    sdnplatform components
+    """
+
+    if http_request.method != 'GET':
+        raise RestInvalidMethodException()
+
+    response_text = None
+    url = None
+    if category == 'performance-monitor':
+        # set up the sdnplatform URL for explain packet (at internal port 8080
+        url = controller_url('performance', type, 'json')
+        request = urllib2.Request(url)
+        response = urllib2.urlopen(request)
+        response_text = response.read()
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_sdnplatform_internal_debugs(http_request, category=None, subcategory=None,
+                              query='all', component='device-manager'):
+    """
+    This API returns debugging related information from the sdnplatform and
+    sdnplatform components
+    """
+
+    if http_request.method != 'GET':
+        raise RestInvalidMethodException()
+
+    response_text = None
+    url = None
+    if category == 'internal-debugs':
+        # set up the sdnplatform URL for explain packet (at internal port 8080
+        url = controller_url('vns', 'internal-debugs', component, query, 'json')
+        request = urllib2.Request(url)
+        response = urllib2.urlopen(request)
+        response_text = response.read()
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_sdnplatform_event_history(http_request, category=None, subcategory=None,
+                              evHistName='all', count='100'):
+    """
+    This API returns real-time event-history information from the sdnplatform and
+    sdnplatform components
+    """
+
+    if http_request.method != 'GET':
+        raise RestInvalidMethodException()
+
+    response_text = None
+    url = None
+    if category == 'event-history':
+        # set up the sdnplatform URL for explain packet (at internal port 8080
+        url = controller_url('core', 'event-history', evHistName, count, 'json')
+        request  = urllib2.Request(url)
+        response = urllib2.urlopen(request)
+        response_text = response.read()
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_flow_cache(http_request, category=None, subcategory=None,
+                          applName='None', applInstName='all', queryType='all'):
+    """
+    This API returns real-time event-history information from the sdnplatform and
+    sdnplatform components
+    """
+
+    if http_request.method != 'GET':
+        raise RestInvalidMethodException()
+
+    response_text = None
+    url = None
+    if category == 'flow-cache':
+        # set up the sdnplatform URL for explain packet (at internal port 8080
+        url = controller_url('vns', 'flow-cache', applName, applInstName, queryType, 'json')
+        request  = urllib2.Request(url)
+        response = urllib2.urlopen(request)
+        response_text = response.read()
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+
+@safe_rest_view
+def do_vns_realtimestats_flow(http_request, category=None, vnsName="all"):
+    """
+    This gets realtime flows for one or more vnses
+    """
+
+    if http_request.method != 'GET':
+        raise RestInvalidMethodException()
+
+    # set up the sdnplatform URL for per-vns flow (at internal port 8080
+    url = controller_url('vns', 'flow', vnsName, 'json')
+    return get_sdnplatform_response(url)
+
+@safe_rest_view
+def do_sdnplatform_counter_categories(request, stattype, layer, dpid=None, portid=None):
+    """
+    This returns counter categories from sdnplatform
+    """
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    if dpid == None:
+        url = controller_url('core', 'counter', 'categories', stattype, layer, 'json')
+    elif portid == None:
+        url = controller_url('core', 'counter', 'categories', dpid, stattype, layer, 'json')
+    else:
+        url = controller_url('core', 'counter', 'categories', dpid, portid, stattype, layer, 'json')
+
+    return get_sdnplatform_response(url)
+
+@safe_rest_view
+@csrf_exempt
+def do_packettrace(request):
+    """
+    This sets a packet trace in sdnplatform.
+    period: 
+        . >0 starts a trace session with the period
+        . =0 starts a trace session with no timeout
+        . <0 ends an ongoing session
+
+    The request method has to be POST since each request gets an unique sessionID
+    """
+    SESSIONID = 'sessionId'
+    sessionId = ""
+    filter = ""
+    if request.method != 'POST':
+        raise RestInvalidMethodException()
+
+    url = 'http://localhost:8080/wm/vns/packettrace/json'
+    request = urllib2.Request(url, request.raw_post_data, {'Content-Type':'application/json'})
+    try:
+        response = urllib2.urlopen(request)
+        response_text = response.read()
+    except Exception, e:
+        # SDNPlatform may not be running, but we don't want that to be a fatal
+        # error, so we just ignore the exception in that case.
+        pass
+
+    #response_data = json.loads(response_text) 
+    #if SESSIONID in response_data:
+    #    sessionId = response_data[SESSIONID]
+    #response_text = {SESSIONID:sessionId}
+
+    return HttpResponse(response_text, mimetype=JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_controller_stats(request, stattype):
+    """
+    This returns controller-level statistics/info from sdnplatform
+    """
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    url = 'http://127.0.0.1:8080/wm/core/controller/%s/json' % stattype
+    return get_sdnplatform_response(url)
+
+@safe_rest_view
+def do_controller_storage_table_list(request):
+    """
+    This returns controller-level storage table list
+    """
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    url = 'http://127.0.0.1:8080/wm/core/storage/tables/json'
+    return get_sdnplatform_response(url)
+
+@safe_rest_view
+def do_device(request):
+    if onos == 0:
+        return get_sdnplatform_query(request, "device")
+    else:
+        url = controller_url("onos", "topology", "hosts")
+        if request.META['QUERY_STRING']:
+            url += '?' + request.META['QUERY_STRING']
+        return get_sdnplatform_response(url)        
+
+@safe_rest_view
+def do_switches(request):
+    if onos == 0:
+        url = controller_url("core", "controller", "switches", "json")
+    else:
+        url = controller_url("onos", "topology", "switches")
+    if request.META['QUERY_STRING']:
+        url += '?' + request.META['QUERY_STRING']
+    return get_sdnplatform_response(url)        
+
+@safe_rest_view
+def do_routers(request):
+    if onos == 0:
+        url = controller_url("core", "controller", "switches", "json")
+    else:
+        url = controller_url("onos","segmentrouting", "routers")
+    if request.META['QUERY_STRING']:
+        url += '?' + request.META['QUERY_STRING']
+    return get_sdnplatform_response(url)        
+
+@safe_rest_view
+def do_router_stats(request, stattype, dpid):
+    """
+    This returns the subnets info about the specifed
+    router dpid. statetype should be 'port'.
+    """
+    #raise RestInvalidMethodException()
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    #url = controller_url('core', 'switch', dpid, stattype, 'json')
+    url = "http://localhost:8080/wm/onos/segmentrouting/router/%s/%s" % (dpid, stattype)
+    #raise RestInvalidMethodException(url)
+    #url = "http://localhost:8080/wm/onos/segementrouting/router/00:00:00:00:00:00:00:01/port"
+    return get_sdnplatform_response(url)
+
+@safe_rest_view
+def do_mastership(request):
+    url = controller_url("onos", "registry", "switches" ,"json")
+    #url = "http://127.0.0.1:8080/wm/onos/registry/switches/json"
+    if request.META['QUERY_STRING']:
+        url += '?' + request.META['QUERY_STRING']
+    return get_sdnplatform_response(url)
+
+@safe_rest_view
+def do_controller(request):
+    url = controller_url("onos", "registry", "controllers" ,"json")
+    #url = "http://127.0.0.1:8080/wm/onos/registry/switches/json"
+    if request.META['QUERY_STRING']:
+        url += '?' + request.META['QUERY_STRING']
+    return get_sdnplatform_response(url) 
+#'''
+
+@safe_rest_view
+def do_links(request):
+    if onos == 0:
+        url = controller_url("topology", "links", "json")
+    else:
+        url = controller_url("onos", "topology", "links")
+    if request.META['QUERY_STRING']:
+        url += '?' + request.META['QUERY_STRING']
+    return get_sdnplatform_response(url)        
+
+@safe_rest_view
+def do_vns_device_interface(request):
+    return get_sdnplatform_query(request, "vns/device-interface")
+
+@safe_rest_view
+def do_vns_interface(request):
+    return get_sdnplatform_query(request, "vns/interface")
+
+@safe_rest_view
+def do_vns(request):
+    return get_sdnplatform_query(request, "vns")
+
+@safe_rest_view
+def do_system_version(request):
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    version = get_system_version_string()
+    response_text = simplejson.dumps([{ 'controller' : version }])
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+available_log_files = {
+    'syslog'           : '/var/log/syslog',
+    'sdnplatform'       : '/opt/sdnplatform/sdnplatform/log/sdnplatform.log',
+    'console-access'   : '/opt/sdnplatform/con/log/access.log',
+    'cassandra'        : '/opt/sdnplatform/db/log/system.log',
+    'authlog'          : '/var/log/auth.log',
+    'pre-start'        : '/tmp/pre-start',
+    'post-start'       : '/tmp/post-start',
+    # 'ftp'              : '/var/log/ftp.log',
+}
+
+available_log_commands = {
+    'dmesg'     : 'dmesg',
+    'process'   : 'ps lax'
+}
+
+@safe_rest_view
+def do_system_log_list(request):
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    existing_logs = []
+    for (log_name, log_path) in available_log_files.items():
+        try:
+            log_file = open(log_path, 'r')
+            existing_logs.append({ 'log' : log_name })
+            log_file.close()
+        except Exception, e:
+            pass
+
+    print '??'
+    for log_name in available_log_commands.keys():
+        print 'ADD', log_name
+        existing_logs.append({ 'log' : log_name })
+    response_text = simplejson.dumps(existing_logs)
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+
+def generate_subprocess_output(cmd):
+
+    process = subprocess.Popen(cmd, shell=True,
+                                   stdout=subprocess.PIPE,
+                                   stderr=subprocess.STDOUT,
+                                   bufsize=1)
+    while True:
+        line = process.stdout.readline()
+        if line != None and line != "":
+            yield line
+        else:
+            break
+
+
+@safe_rest_view
+def do_system_log(request, log_name):
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    print 'do system log', log_name
+
+    # manage command ouput differently
+    if log_name in available_log_commands:
+        cmd = available_log_commands[log_name]
+        print 'DOING COMMAND', cmd
+
+        return HttpResponse(generate_subprocess_output(cmd),
+                            TEXT_PLAIN_CONTENT_TYPE)
+        return
+
+    log_path = available_log_files.get(log_name)
+    if log_name == None:
+        raise RestInvalidLog('No such log: %s' % log_name)
+    
+    try:
+        log_file = open(log_path, 'r')
+    except Exception,e:
+        raise RestInvalidLog('Log does not exist: %s' % log_name)
+        
+    # use a generator so that the complete log is not ever held in memory
+    def response(log_name, file):
+        for line in file:
+            yield line
+        file.close()
+
+    return HttpResponse(response(log_name, log_file), TEXT_PLAIN_CONTENT_TYPE)
+
+
+@safe_rest_view
+def do_system_uptime(request):
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    url = controller_url('core', 'system', 'uptime', 'json')
+    return get_sdnplatform_response(url)        
+
+
+def _collect_system_interfaces(lo = False):
+    from netifaces import interfaces, ifaddresses, AF_INET, AF_LINK
+    result = []
+    for iface in interfaces():
+        if iface.startswith('lo') and not lo:
+            continue # ignore loopback
+        addrs = ifaddresses(iface)
+        if AF_INET in addrs:
+            for addr in ifaddresses(iface)[AF_INET]:
+                result.append({'name'      : iface,
+                               'addr'      : addr.get('addr', ''),
+                               'netmask'   : addr.get('netmask', ''),
+                               'broadcast' : addr.get('broadcast', ''),
+                               'peer'      : addr.get('peer', '')})
+    return result
+
+
+def do_system_inet4_interfaces(request):
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    response_text = simplejson.dumps(_collect_system_interfaces(lo = True))
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+
+@safe_rest_view
+def do_system_time_zone_strings(request, list_type):
+    import pytz
+    if list_type == 'common':
+        string_list = pytz.common_timezones
+    elif list_type == "all":
+        string_list = pytz.all_timezones
+    else:
+        raise RestResourceNotFoundException(request.path)
+    
+    response_text = simplejson.dumps(string_list)
+    
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_check_config(request):
+    config_check_state()
+    return get_successful_response('checked config')
+
+@safe_rest_view
+def do_local_controller_id(request):
+    if request.method == 'GET':
+        controller_id = get_local_controller_id()
+        if not controller_id:
+            raise Exception("Unspecified local controller id")
+        response_text = simplejson.dumps({'id': controller_id})
+    elif request.method == 'PUT':
+        put_data = json.loads(request.raw_post_data)
+        controller_id = put_data.get('id')
+        _result = exec_os_wrapper("ControllerId", 'set', [controller_id])
+        response_text = get_successful_response_data('updated')
+    else:
+        raise RestInvalidMethodException()
+    
+    response = HttpResponse(response_text, JSON_CONTENT_TYPE)
+    
+    return response
+
+@safe_rest_view
+def do_ha_failback(request):
+    if request.method != 'PUT':
+        raise RestInvalidMethodException()
+    _result = exec_os_wrapper("HAFailback", 'set', [])
+    response_text = get_successful_response_data('forced failback')
+    response = HttpResponse(response_text, JSON_CONTENT_TYPE)
+    return response
+
+def delete_ha_firewall_rules(ip):
+    rules = FirewallRule.objects.filter(action='allow', src_ip=ip)
+    rules.filter(port=80).delete()
+    rules.filter(proto='tcp', port=7000).delete()
+    rules.filter(proto='vrrp').delete()
+
+def cascade_delete_controller_node(controller_id):
+    ControllerAlias.objects.filter(controller=controller_id).delete()
+    ControllerDomainNameServer.objects.filter(controller=controller_id).delete()
+    for iface in ControllerInterface.objects.filter(controller=controller_id):
+        FirewallRule.objects.filter(interface=iface.id).delete()
+    ControllerInterface.objects.filter(controller=controller_id).delete()
+    Controller.objects.filter(id=controller_id).delete()
+
+# FIXME: this assume a single-interface design and will look for the IP on eth0
+#        need to fix this when we have a proper multi-interface design
+def get_controller_node_ip(controller_id):
+    node_ip = ''
+    iface = ControllerInterface.objects.filter(controller=controller_id, type='Ethernet', number=0)
+    if iface:
+        node_ip = iface[0].discovered_ip
+    return node_ip
+
+# This method is "external" facing
+# It is designed to be called by CLI or other REST clients
+# This should only run on the master node, where decommissioning of a remote node is initiated
+@safe_rest_view
+def do_decommission(request):
+    if request.method != 'PUT':
+        raise RestInvalidMethodException()
+    data = simplejson.loads(request.raw_post_data)
+    node_id = data['id']
+
+    # Disallow self-decommissioning
+    local_id = get_local_controller_id()
+    if local_id == node_id:
+        raise RestDecommissionException("Decommissioning of the master node is not allowed. " + \
+                                        "Please perform a failover first.")
+
+    try :
+        controller = Controller.objects.get(id=node_id)
+    except Controller.DoesNotExist:
+        raise RestDecommissionException("No controller found")
+
+    node_ip = get_controller_node_ip(node_id)
+
+    # Case 1: controller node has IP
+    if node_ip:
+        result = exec_os_wrapper("Decommission", 'set', [node_ip])
+        output = result['out'].strip()
+        if result['out'].strip().endswith('is already decommissioned'):
+            delete_ha_firewall_rules(node_ip)
+            cascade_delete_controller_node(node_id)
+
+    # Case 2: controller node has NO IP
+    else:
+        output = '%s is already decommissioned' % node_id
+        cascade_delete_controller_node(node_id)
+
+    jsondict = {}
+    jsondict['status'] = "OK"
+    jsondict['description'] = output
+    return HttpResponse(simplejson.dumps(jsondict), JSON_CONTENT_TYPE)
+
+# This method is "internal" facing
+# It is designed to be called only by sys/remove-node.sh
+# This should only run on the node being decommissioned (slave)
+@safe_rest_view
+def do_decommission_internal(request):
+    if request.method != 'PUT':
+        raise RestInvalidMethodException()
+    data = simplejson.loads(request.raw_post_data)
+    node_ip = data['ip']
+    exec_os_wrapper("DecommissionLocal", 'set', [node_ip])
+
+    jsondict = {}
+    jsondict['status'] = "OK"
+    return HttpResponse(simplejson.dumps(jsondict), JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_ha_provision(request):
+    if request.method != 'PUT':
+        raise RestInvalidMethodException()
+    data = simplejson.loads(request.raw_post_data)
+    node_ip = data['ip']
+    
+    try :
+        ci = ControllerInterface.objects.get(ip=node_ip)
+        id = ci.controller.id
+        print 'got id', id
+        try:
+            a = ControllerAlias.objects.get(controller=id)
+            alias = a.alias
+        except:
+            alias = '(no controller alias)'
+
+        print 'alias:', alias
+        raise RestProvisionException('ip address already in controller %s %s' %
+                                     (id, alias))
+        
+    except ControllerInterface.DoesNotExist:
+        id = uuid.uuid4().urn[9:]
+        print "generated id = ", id
+        c = Controller(id=id)
+        try:
+            c.save()
+        except:
+            # describe failure
+            raise RestProvisionException('can\t save controller')
+            pass
+        print "save controller"
+        ci = ControllerInterface(controller=c,
+                                 ip=node_ip,
+                                 discovered_ip=node_ip)
+        try:
+            ci.save()
+        except:
+            # describe failure
+            raise RestProvisionException('can\t save controllar interfacer')
+
+    for c in Controller.objects.all():
+        if c.id != id:
+            #if there are multiple interfaces, assume the
+            # ethernet0 interface is for management purpose 
+            # XXX this could be better.
+            iface = ControllerInterface.objects.get(controller=c.id,
+                                                    type='Ethernet',
+                                                    number=0)
+            ip = iface.ip
+            fw = FirewallRule(interface=iface, action='allow',
+                              src_ip=node_ip, port=80, proto='tcp')
+            try:
+                fw.save()
+            except:
+                # describe failure
+                raise RestProvisionException('can\t save firewall rule from master')
+                
+            fw = FirewallRule(interface=ci, action='allow',
+                              src_ip=ip, port=80, proto='tcp')
+            try:
+                fw.save()
+            except:
+                raise RestProvisionException('can\t save firewall from slave')
+        
+
+    response_text = get_successful_response_data(id)
+    response = HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+    return response
+
+
+def get_clustername():
+    name = os.popen("grep cluster_name /opt/sdnplatform/db/conf/cassandra.yaml | awk  '{print $2}'").readline()
+    # name may be '', perhaps this ought to None?
+    return name
+
+
+@safe_rest_view
+def do_clustername(request):
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    response_text = simplejson.dumps([{ 'clustername' : get_clustername() }])
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+    
+    
+@safe_rest_view
+def do_local_ha_role(request):
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+
+    url = controller_url('core', 'role', 'json')
+    try:
+        response_text = urllib2.urlopen(url, timeout=2).read()
+        response = json.loads(response_text)
+    except Exception:
+        response = HttpResponse('{"role":"UNAVAILABLE"}', JSON_CONTENT_TYPE)
+        return response
+    # now determine our controller id
+    controller_id = get_local_controller_id()
+
+    # find all the interfaces
+    ifs = ControllerInterface.objects.filter(controller=controller_id)
+
+    for intf in ifs:
+        firewall_id = '%s|%s|%s' % (controller_id, intf.type, intf.number)
+
+        rules = FirewallRule.objects.filter(interface=firewall_id)
+        for rule in rules:
+            if rule.action == 'reject' and rule.proto == 'tcp' and rule.port == 6633:
+                if response['role'] in {'MASTER', 'SLAVE'}:
+                    response['role']+='-BLOCKED'
+
+    response['clustername'] = get_clustername()
+        
+    return HttpResponse(simplejson.dumps(response), JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_system_clock(request, local=True):
+    local_or_utc_str = 'local' if local else 'utc'
+    if request.method == 'GET':
+        result = exec_os_wrapper("DateTime", 'get', [local_or_utc_str])
+    elif request.method == 'PUT':
+        time_info = simplejson.loads(request.raw_post_data)
+        dt = datetime(**time_info)
+        new_date_time_string = dt.strftime('%Y:%m:%d:%H:%M:%S')
+        result = exec_os_wrapper("DateTime", 'set', [local_or_utc_str, new_date_time_string])
+    else:
+        raise RestInvalidMethodException()
+
+    if len(result) == 0:
+        raise Exception('Error executing date command')
+    
+    # The DateTime OS wrapper only has a single command so the return
+    # date/time is the first line of the first element of the out array
+    values = result['out'].strip().split(':')
+    date_time_info = {
+        'year': int(values[0]),
+        'month': int(values[1]),
+        'day': int(values[2]),
+        'hour': int(values[3]),
+        'minute': int(values[4]),
+        'second': int(values[5]),
+        'tz': values[6]
+    }
+    response_text = simplejson.dumps(date_time_info)
+    response = HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+    return response
+
+@safe_rest_view
+def do_instance(request, model_name,id=None):
+    """
+    This function handles both GET and PUT methods.
+    
+    For a GET request it returns a list of all of the instances of the
+    model corresponding to the specified type that match the specified
+    query parameters. If there are no query parameters then it returns
+    a list of all of the instances of the specified type. The names of
+    the query parameters can use the Django double underscore syntax
+    for doing more complicated tests than just equality
+    (e.g. mac__startswith=192.168).
+    
+    For a PUT request it can either update an existing instance or
+    insert one or more new instances. If there are any query parameters
+    then it assumes that its the update case and that the query
+    parameters identify exactly one instance. If that's not the case
+    then an error response is returned. For the update case any subset
+    of the fields can be updated with the PUT data. The format of the
+    PUT data is a JSON dictionary
+    """
+    
+    # FIXME: Hack to remap 'localhost' id for the controller-node model
+    # to the real ID for this controller
+    if model_name == 'controller-node' and id == 'localhost':
+        id = get_local_controller_id()
+        
+    # Lookup the model class associated with the specified name
+    model_info = rest_model_info_dict.get(model_name)
+    if not model_info:
+        raise RestInvalidDataTypeException(model_name)
+            
+    # Set up the keyword argument dictionary we use to filter the QuerySet.
+    filter_keyword_args = {}
+
+    jsonp_prefix = None
+    nolist = False
+    order_by = None
+    
+    # Now iterate over the query params and add further filter keyword arguments
+    query_param_dict = request.GET
+    for query_param_name, query_param_value in query_param_dict.items():
+        add_query_param = False
+        query_param_name = str(query_param_name)
+        query_param_value = str(query_param_value)
+        if query_param_name == 'callback': #switching to match up with jquery getJSON call naming convention.
+            jsonp_prefix = query_param_value
+        elif query_param_name == 'nolist':
+            if query_param_value not in ('False', 'false', '0', ''):
+                nolist = True
+        elif query_param_name == 'orderby':
+            order_by = query_param_value.split(',')
+            for i in range(len(order_by)):
+                name = order_by[i]
+                if name.startswith('-'):
+                    descending = True
+                    name = name[1:]
+                else:
+                    descending = False
+                field_info = model_info.rest_name_dict.get(name)
+                if not field_info:
+                    raise RestInvalidOrderByException(name)
+                name = field_info.name
+                if descending:
+                    name = '-' + name
+                order_by[i] = name
+        elif query_param_name in model_info.rest_name_dict:
+            field_info = model_info.rest_name_dict.get(query_param_name)
+            # For booleans, translate True/False strings into 0/1.
+            if field_info and type(field_info.django_field_info) == BooleanField:
+                if query_param_value.lower() == 'false':
+                    query_param_value = 0
+                elif query_param_value.lower() == 'true':
+                    query_param_value = 1
+            query_param_name = field_info.name
+            if model_name == 'controller-node' and \
+              query_param_name == 'id' and query_param_value == 'localhost':
+                query_param_value = get_local_controller_id()
+            if model_name in 'controller-interface' and \
+              query_param_name == 'controller' and \
+              query_param_value == 'localhost':
+                query_param_value = get_local_controller_id()
+            add_query_param = True
+        else:
+            double_underscore_start = query_param_name.find("__")
+            if double_underscore_start >= 0:
+                rest_name = query_param_name[:double_underscore_start]
+                field_info = model_info.rest_name_dict.get(rest_name)
+                if field_info:
+                    operation = query_param_name[double_underscore_start:]
+                    query_param_name = field_info.name
+                    if type(field_info.django_field_info) == ForeignKey:
+                        query_param_name = query_param_name + '__' + field_info.django_field_info.rel.field_name
+                    # Substitute in the model field name for the (possible renamed) rest name
+                    query_param_name += operation
+                    add_query_param = True
+        if add_query_param:
+            filter_keyword_args[query_param_name] = query_param_value
+
+    if id != None:
+        if len(filter_keyword_args) > 0:
+            raise RestInvalidFilterParameterException(filter_keyword_args.keys()[0])
+        try:
+            get_args = {model_info.primary_key:id}
+            instance = model_info.model_class.objects.get(**get_args)
+            instance_list = (instance,)
+            nolist = True
+        except model_info.model_class.DoesNotExist,e:
+            raise RestResourceNotFoundException(request.path)
+        except model_info.model_class.MultipleObjectsReturned, exc:
+            # traceback.print_exc()
+            raise RestInternalException(exc)
+    elif (request.method != 'PUT') or (len(filter_keyword_args) > 0):
+        # Get the QuerySet based on the keyword arguments we constructed
+        instance_list = model_info.model_class.objects.filter(**filter_keyword_args)
+        if order_by:
+            instance_list = instance_list.order_by(*order_by)
+    else:
+        # We're inserting new objects, so there's no need to do a query
+        instance_list = None
+        
+    response_content_type = JSON_CONTENT_TYPE
+    
+    if request.method == 'GET':
+        json_response_data = []
+        for instance in instance_list:
+            json_instance = {}
+            for field_info in model_info.field_name_dict.values():
+                # Made some minor edits to deal with a) fields that are empty and b) fields that are not strings -Kyle
+                # Changed this to only do an explicit string conversion if it's a unicode string.
+                # The controller is expecting to get the unstringified value (e.g. for boolean values)
+                # Not sure if this will break things in the UI, but we'll need to resolve how
+                # we want to handle this. Also, how do we want to handle unicode strings? -- robv
+                field_name = field_info.name
+                if type(field_info.django_field_info) == ForeignKey:
+                    field_name += '_id'
+                value = instance.__dict__.get(field_name)
+                if value != None:
+                    if field_info.json_serialize:
+                        value = str(value)
+                    json_instance[field_info.rest_name] = value
+            json_response_data.append(json_instance)
+        
+        # If the nolist query param was enabled then check to make sure
+        # that there was only a single instance in the response list and,
+        # if so, unpack it from the list
+        if nolist:
+            if len(json_response_data) != 1:
+                raise RestNoListResultException()
+            json_response_data = json_response_data[0]
+        
+        # Convert to json
+        response_data = simplejson.dumps(json_response_data)
+        
+        # If the jsonp query parameter was specified, wrap the data with
+        # the jsonp prefix
+        if jsonp_prefix:
+            response_data = jsonp_prefix + '(' + response_data + ')'
+            # We don't really know what the content type is here, but it's typically javascript
+            response_content_type = TEXT_JAVASCRIPT_CONTENT_TYPE
+    elif request.method == 'PUT':
+        response_data = get_successful_response_data('saved')
+        response_content_type = JSON_CONTENT_TYPE
+        
+        begin_batch_notification()
+        json_object = simplejson.loads(request.raw_post_data)
+        if instance_list is not None:
+
+            # don't allow the ip address of the first interface to
+            # be updated once it is set.  This really applies to
+            # the interface cassandra uses to sync the db.
+            if model_name == 'controller-interface':
+                for instance in instance_list:
+                    if instance.number == 0 and instance.ip != '':
+                        if 'ip' in json_object and json_object['ip'] != instance.ip:
+                            raise RestModelException("In this version, ip-address of primary interface can't be updated after initial configuration")
+
+            # In this case the URL includes query parameter(s) which we assume
+            # narrow the request to the instances of the model to be updated
+            # updated with the PUT data. So we're updating existing instances
+            
+            # If it's a list with one element then extract the single element
+            if (type(json_object) == list) and (len(json_object) == 1):
+                json_object = json_object[0]
+                
+            # We're expecting a dictionary where the keys match the model field names
+            # If the data isn't a dictionary then return an error
+            if type(json_object) != dict:
+                raise RestInvalidPutDataException() # TODO: Should return something different here
+            
+            # Set the fields in the model instance with the data from the dictionary
+            for instance in instance_list:
+                for rest_name, value in json_object.items():
+                    if not rest_name in model_info.rest_name_dict:
+                        raise RestModelException("Model '%s' has no field '%s'" % 
+                                                 (model_name, rest_name))
+                    field_info = model_info.rest_name_dict[rest_name]
+                    field_name = str(field_info.name)   # FIXME: Do we need the str cast?
+                    if type(field_info.django_field_info) == ForeignKey:
+                        field_name += '_id'
+                    # TODO: Does Django still not like unicode strings here?
+                    if type(value) == unicode:
+                        value = str(value)
+                    instance.__dict__[field_name] = value
+                # Save the updated model instance
+                try:
+                    instance.full_clean()
+                    instance.save()
+                except ValidationError, err:
+                    handle_validation_error(model_info, err)
+                    #raise RestValidationException(err)
+                except Exception, exc:
+                    raise RestSaveException(exc)
+        else:
+            # In this case no query parameters or id were specified so we're inserting new
+            # instances into the database. The PUT data can be either a list of new
+            # items to add (i.e. top level json object is a list) or else a single
+            # new element (i.e. top-level json object is a dict).
+            #print "creating object(s)"
+
+            # To simplify the logic below we turn the single object case into a list
+            if type(json_object) != list:
+                json_object = [json_object]
+            
+            # Create new model instances for all of the items in the list
+            for instance_data_dict in json_object:
+                # We expect the data to be a dictionary keyed by the field names
+                # in the model. If it's not a dict return an error
+                if type(instance_data_dict) != dict:
+                    raise RestInvalidPutDataException()
+                
+                converted_dict = {}
+                
+                # Now add the fields specified in the PUT data
+                for rest_name, value in instance_data_dict.items():
+
+                    #print "  processing " + str(name) + " " + str(value)
+
+                    if not rest_name in model_info.rest_name_dict:
+                        raise RestModelException("Model '%s' has no field '%s'" % 
+                                                 (model_name, rest_name))
+                    field_info = model_info.rest_name_dict[rest_name]
+                    # simplejson uses unicode strings when it loads the objects which
+                    # Django doesn't like that, so we convert these to ASCII strings
+                    if type(rest_name) == unicode:
+                        rest_name = str(rest_name)
+                    if type(value) == unicode:
+                        value = str(value)
+                    field_name = field_info.name
+                    # FIXME: Hack to remap localhost controller node id alias to the actual
+                    # ID for the controller node. We shouldn't be doing this here (this code
+                    # shouldn't have anything about specific models), but it's the easiest
+                    # way to handle it for now and this code is likely going away sometime
+                    # pretty soon (written in May, 2012, let's see how long "pretty soon"
+                    # is :-) )
+                    if model_name == 'controller-node' and field_name == 'id' and value == 'localhost':
+                        value = get_local_controller_id()
+                    if type(field_info.django_field_info) == ForeignKey:
+                        field_name += '_id'
+                    converted_dict[field_name] = value
+                
+                try:
+                    instance = model_info.model_class(**converted_dict)
+                    instance.full_clean()
+                    instance.save()
+                except ValidationError, err:
+                    handle_validation_error(model_info, err)
+                    #raise RestValidationException(err)
+                except Exception, e:
+                    # traceback.print_exc()
+                    raise RestSaveException(e)
+                
+        end_batch_notification()
+    elif request.method == 'DELETE':
+        begin_batch_notification()
+        for instance in instance_list:
+            try:
+                instance.delete()
+            except ValidationError, err:
+                handle_validation_error(model_info, err)
+            except Exception, e:
+                raise RestException(e)
+        end_batch_notification()
+        response_data = "deleted"
+        response_content_type = 'text/plain'
+    else:
+        raise RestInvalidMethodException()
+    
+    return HttpResponse(response_data, response_content_type)
+
+def synthetic_controller_interface(model_name, query_param_dict, json_response_data):
+    # ---
+    if model_name == 'controller-interface':
+        # For controller-interfaces, when an ip address (netmask too)
+        # is left unconfigured, then it may be possible to associate
+        # ifconfig details with the interface.
+        #
+        # Since controller-interfaces has no mechanism to associate 
+        # specific ifconfig interfaces with rows, it's only possible to
+        # associate ip's when a single unconfigured ip address exists,
+        # using a process of elimination.  For all ip address in the
+        # ifconfig output, all statically configured controller-interface
+        # items are removed.  If only one result is left, and only
+        # one controller-interface has an unconfigured ip address
+        # (either a dhcp acquired address, or a static address where
+        # the ip address is uncofigured), the ifconfig ip address
+        # is very-likely to be the one associated with the 
+        # controller-interface row.
+
+        # Check the list of values to see if any are configured as dhcp
+        dhcp_count = 0
+        unconfigured_static_ip = 0
+        this_host = get_local_controller_id()
+
+        for entry in json_response_data:
+            if 'mode' in entry and entry['mode'] == 'dhcp' and \
+               'controller' in entry and entry['controller'] == this_host:
+                    dhcp_count += 1
+            if 'mode' in entry and entry['mode'] == 'static' and \
+               'ip' in entry and entry['ip'] == '':
+                    unconfigured_static_ip += 1
+        if dhcp_count + unconfigured_static_ip != 1:
+            for entry in json_response_data:
+                entry['found-ip']        = entry['ip']
+            return
+
+        need_controller_query = False
+        # determine whether the complete list of interfaces needs
+        # to be collected to associate the dhcp address.
+        for query_param_name, query_param_value in query_param_dict.items():
+            if query_param_name != 'controller':
+                need_controller_query = True
+            if query_param_name == 'controller' and \
+               query_param_value != this_host:
+                need_controller_query = True
+
+        if need_controller_query == False:
+            model_interfaces = [x for x in json_response_data
+                                if 'controller' in x and x['controller'] == this_host]
+        else:
+            # print 'need to collect all interfaces'
+            filter_keyword_args = {'controller' : this_host}
+            model_info = rest_model_info_dict.get(model_name)
+            instance_list = model_info.model_class.objects.filter(**filter_keyword_args)
+            response_data = []
+            for instance in instance_list:
+                data = {}
+                for field_info in model_info.field_name_dict.values():
+                    field_name = field_info.name
+                    if type(field_info.django_field_info) == ForeignKey:
+                        field_name += '_id'
+                    value = instance.__dict__.get(field_name)
+                    if value != None:
+                        if field_info.json_serialize:
+                            value = str(value)
+                        data[field_info.rest_name] = value
+                response_data.append(data)
+            model_interfaces = response_data
+
+        # Recompute the number of dhcp configured interfaces,
+        # model_interfaces is the collection of interface for 'this_host'
+        dhcp_count = 0
+        unconfigured_static_ip = 0
+        for ifs in model_interfaces:
+            if 'mode' in ifs and ifs['mode'] == 'dhcp':
+                dhcp_count += 1
+            if 'mode' in ifs and ifs['mode'] == 'static' and \
+               'ip' in ifs and ifs['ip'] == '':
+                    unconfigured_static_ip += 1
+
+        if dhcp_count + unconfigured_static_ip != 1:
+            # print "Sorry, %s dhcp + %s unconfigured static interfaces on %s" % \
+                  # (dhcp_count, unconfigured_static_ip, this_host)
+            # copy over static ip's
+            for entry in json_response_data:
+                entry['found-ip']        = entry['ip']
+            return
+
+        # collect current details for all the network interfaces
+        inet4_ifs = _collect_system_interfaces()
+
+        # iterate over the model_interfaces's interfaces, and 
+        # remove ip addresses from inet4_ifs which are static, and
+        # have the correct static value.
+
+        report_static = False
+        match_id = ''
+
+        for ifs in model_interfaces:
+            if 'mode' in ifs and ifs['mode'] == 'static':
+                if 'ip' in ifs and ifs['ip'] == '':
+                    # print "Unconfigured static ip for %s", ifs['id']
+                    match_id = ifs['id']
+                if 'ip' in ifs and ifs['ip'] != '':
+                    # find this address in the known addresses
+                    remove_entry = -1
+                    for index, inet4_if in enumerate(inet4_ifs):
+                        if inet4_if['addr'] == ifs['ip']:
+                            remove_entry = index
+                            break
+                    if remove_entry == -1:
+                        # print "Static ip %s not found" % ifs['ip']
+                        pass 
+                    else:
+                        del inet4_ifs[remove_entry]
+            elif 'mode' in ifs and ifs['mode'] == 'dhcp':
+                match_id = ifs['id']
+            else:
+                # ought to assert here, not_reached()
+                pass
+
+        # When only one entry is left in inet, its possible to do the assocation
+        if len(inet4_ifs) != 1:
+            # print "Incorrect number %s of inet4 interfaces left" % len(inet4_ifs)
+            pass
+
+        for entry in json_response_data:
+            entry['found-ip']        = entry['ip']
+            entry['found-netmask']   = entry['netmask']
+
+            if entry['id'] == match_id:
+                # make sure the address isn't set
+                if entry['ip'] == '':
+                    entry['found-ip']        = inet4_ifs[0]['addr']
+                    entry['found-netmask']   = inet4_ifs[0]['netmask']
+                    entry['found-broadcast'] = inet4_ifs[0]['broadcast']
+                else:
+                    # ought to assert here, not_reached()
+                    pass
+
+@safe_rest_view
+def do_synthetic_instance(request, model_name, id=None):
+    
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+
+    # Lookup the model class associated with the specified name
+    model_info = rest_model_info_dict.get(model_name)
+    if not model_info:
+        raise RestInvalidDataTypeException(model_name)
+            
+    # Set up the keyword argument dictionary we use to filter the QuerySet.
+    filter_keyword_args = {}
+
+    jsonp_prefix = None
+    nolist = False
+    order_by = None
+    
+    # Now iterate over the query params and add further filter keyword arguments
+    query_param_dict = request.GET
+    for query_param_name, query_param_value in query_param_dict.items():
+        add_query_param = False
+        query_param_name = str(query_param_name)
+        query_param_value = str(query_param_value)
+        if query_param_name == 'callback': #switching to match up with jquery getJSON call naming convention.
+            jsonp_prefix = query_param_value
+        elif query_param_name == 'nolist':
+            if query_param_value not in ('False', 'false', '0', ''):
+                nolist = True
+        elif query_param_name == 'orderby':
+            order_by = query_param_value.split(',')
+            for i in range(len(order_by)):
+                name = order_by[i]
+                if name.startswith('-'):
+                    descending = True
+                    name = name[1:]
+                else:
+                    descending = False
+                field_info = model_info.rest_name_dict.get(name)
+                if not field_info:
+                    raise RestInvalidOrderByException(name)
+                name = field_info.name
+                if descending:
+                    name = '-' + name
+                order_by[i] = name
+        elif query_param_name in model_info.rest_name_dict:
+            field_info = model_info.rest_name_dict.get(query_param_name)
+            query_param_name = field_info.name
+            add_query_param = True
+        else:
+            double_underscore_start = query_param_name.find("__")
+            if double_underscore_start >= 0:
+                rest_name = query_param_name[:double_underscore_start]
+                field_info = model_info.rest_name_dict.get(rest_name)
+                if field_info:
+                    operation = query_param_name[double_underscore_start:]
+                    query_param_name = field_info.name
+                    if type(field_info.django_field_info) == ForeignKey:
+                        query_param_name = query_param_name + '__' + field_info.django_field_info.rel.field_name
+                    # Substitute in the model field name for the (possible renamed) rest name
+                    query_param_name += operation
+                    add_query_param = True
+        if add_query_param:
+            filter_keyword_args[query_param_name] = query_param_value
+
+    if id != None:
+        if len(filter_keyword_args) > 0:
+            raise RestInvalidFilterParameterException(filter_keyword_args.keys()[0])
+        try:
+            get_args = {model_info.primary_key:id}
+            instance = model_info.model_class.objects.get(**get_args)
+            instance_list = (instance,)
+            nolist = True
+        except model_info.model_class.DoesNotExist,e:
+            raise RestResourceNotFoundException(request.path)
+        except model_info.model_class.MultipleObjectsReturned, exc:
+            # traceback.print_exc()
+            raise RestInternalException(exc)
+    elif (request.method != 'PUT') or (len(filter_keyword_args) > 0):
+        # Get the QuerySet based on the keyword arguments we constructed
+        instance_list = model_info.model_class.objects.filter(**filter_keyword_args)
+        if order_by:
+            instance_list = instance_list.order_by(*order_by)
+    else:
+        # We're inserting new objects, so there's no need to do a query
+        instance_list = None
+        
+    response_content_type = JSON_CONTENT_TYPE
+    
+    # Syntheric types only do requests --
+    json_response_data = []
+    for instance in instance_list:
+        json_instance = {}
+        for field_info in model_info.field_name_dict.values():
+            # Made some minor edits to deal with a) fields that are empty and b) fields that are not strings -Kyle
+            # Changed this to only do an explicit string conversion if it's a unicode string.
+            # The controller is expecting to get the unstringified value (e.g. for boolean values)
+            # Not sure if this will break things in the UI, but we'll need to resolve how
+            # we want to handle this. Also, how do we want to handle unicode strings? -- robv
+            field_name = field_info.name
+            if type(field_info.django_field_info) == ForeignKey:
+                field_name += '_id'
+            value = instance.__dict__.get(field_name)
+            if value != None:
+                if field_info.json_serialize:
+                    value = str(value)
+                json_instance[field_info.rest_name] = value
+        json_response_data.append(json_instance)
+    
+    # ---
+    if model_name == 'controller-interface':
+        synthetic_controller_interface(model_name, query_param_dict, json_response_data)
+
+    # Convert to json
+    response_data = simplejson.dumps(json_response_data)
+    
+    # If the nolist query param was enabled then check to make sure
+    # that there was only a single instance in the response list and,
+    # if so, unpack it from the list
+    if nolist:
+        if len(json_response_data) != 1:
+            raise RestNoListResultException()
+        json_response_data = json_response_data[0]
+    
+    # If the jsonp query parameter was specified, wrap the data with
+    # the jsonp prefix
+    if jsonp_prefix:
+        response_data = jsonp_prefix + '(' + response_data + ')'
+        # We don't really know what the content type is here, but it's typically javascript
+        response_content_type = TEXT_JAVASCRIPT_CONTENT_TYPE
+
+    return HttpResponse(response_data, response_content_type)
+
+@safe_rest_view
+def do_user_data_list(request):
+    # Now iterate over the query params and add any valid filter keyword arguments
+    filter_keyword_args = {}
+    for query_param_name, query_param_value in request.GET.items():
+        query_param_name = str(query_param_name)
+        double_underscore_start = query_param_name.find("__")
+        if double_underscore_start >= 0:
+            attribute_name = query_param_name[:double_underscore_start]
+        else:
+            attribute_name = query_param_name
+            
+        # In the future, if we add support for things like mod_date, creation_date, etc.
+        # which would be supported in query params, then they'd be added to this list/tuple.
+        if attribute_name not in ('name',):
+            raise RestInvalidFilterParameterException(query_param_name)
+        filter_keyword_args[query_param_name] = query_param_value
+
+    instance_list = UserData.objects.filter(**filter_keyword_args)
+    
+    if request.method == 'GET':
+        user_data_info_list = []
+
+        # FIXME: robv: It's incorrect to *always* add this to the user data,
+        # because it means we're not respecting the filter query parameters.
+        # To work completely correctly we'd need to duplicate a lot of logic
+        # for processing the query parameters, which would be tedious.
+        # Should talk to Mandeep about why it was done this way. Maybe we
+        # should expose these special cases in a different URL/view.
+        for fn in ['startup-config', 'upgrade-config']:
+            try:
+                sc = "%s/run/%s" % (sdncon.SDN_ROOT, fn)
+                f = open(sc, 'r')
+                f.close()
+                t = time.strftime("%Y-%m-%d.%H:%M:%S",
+                                  time.localtime(os.path.getmtime(sc)))
+                instance_name = fn + '/timestamp=' + t + \
+                                '/version=1/length=' + \
+                                str(os.path.getsize(sc))
+                url_path = 'rest/v1/data/' + instance_name + '/'
+                            
+                user_data_info = { 'name' : instance_name,
+                                   'url_path' : url_path, }
+                user_data_info_list.append(user_data_info)
+            except:
+                pass
+
+        for instance in instance_list:
+            user_data_info = {'name': instance.name,
+                              'url_path': 'rest/v1/data/' + instance.name + '/'}
+            user_data_info_list.append(user_data_info)
+        
+        response_data = simplejson.dumps(user_data_info_list)
+    elif request.method == 'DELETE':
+        instance_list.delete()
+        response_data = {}
+        response_data['status'] = 'success'
+        response_data['message'] = 'user data deleted'
+        response_data = simplejson.dumps(response_data)
+        response_content_type = JSON_CONTENT_TYPE
+    else:
+        raise RestInvalidMethodException()
+        
+    return HttpResponse(response_data, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_user_data(request, name):
+    query_param_dict = request.GET
+    #
+    # Manage startup-config/update-config differently
+    if name.find('/') >= 0 and \
+       name.split('/')[0] in ['startup-config', 'upgrade-config']:
+        path = "%s/run/%s" % (sdncon.SDN_ROOT, name.split('/')[0])
+        response_data = {}
+
+        if request.method == 'GET':
+            with open(path, 'r') as f:
+                response_data = f.read()
+            response_content_type = "text/plain"
+        elif request.method == 'PUT':
+            try:
+                with open(path, 'w') as f:
+                    f.write(request.raw_post_data)
+                response_data['status'] = 'success'
+                response_data['message'] = 'user data updated'
+            except:
+                response_data['status'] = 'failure'
+                response_data['message'] = "can't write file"
+            response_content_type = JSON_CONTENT_TYPE
+            response_data = simplejson.dumps(response_data)
+        elif request.method == 'DELETE':
+            try:
+                f = open(path, "r")
+                f.close()
+            except:
+                raise RestResourceNotFoundException(request.path)
+
+            try:
+                os.remove(path)
+                response_data['status'] = 'success'
+                response_data['message'] = 'user data deleted'
+            except:
+                response_data['status'] = 'failure'
+                response_data['message'] = "can't delete file"
+            response_data = simplejson.dumps(response_data)
+            response_content_type = JSON_CONTENT_TYPE
+        else:
+            raise RestInvalidMethodException()
+            
+        return HttpResponse(response_data, response_content_type)
+            
+    
+    # Default values for optional query parameters
+    #private = False
+    binary = False
+    
+    for param_name, param_value in query_param_dict.items():
+        if param_name == 'binary':
+            if request.method != 'PUT':
+                raise RestInvalidQueryParameterException(name)
+            binary = param_value.lower() == 'true' or param_value == '1'
+        #elif param_name == 'private':
+        #    private = param_value
+        else:
+            raise RestInvalidQueryParameterException(param_name)
+    
+    # FIXME: Need HTTP basic/digest auth support for the following
+    # code to work.
+    #if private:
+    #    user = request.user
+    #else:
+    #    user = None
+    #if user != None and not user.is_authenticated():
+    #    raise RestAuthenticationRequiredException()
+    user = None
+    
+    # There's currently an issue with filtering on the user when using the
+    # Cassandra database backend. Since we don't support private per-user
+    # data right now, I'm just disabling filtering on the user and only
+    # filter on the name
+    #user_data_query_set = UserData.objects.filter(user=user, name=name)
+    user_data_query_set = UserData.objects.filter(name=name)
+
+    count = user_data_query_set.count()
+    if count > 1:
+        raise RestInternalException('Duplicate user data values for the same name')
+    
+    if request.method == 'GET':
+        if count == 0:
+            raise RestResourceNotFoundException(request.path)
+        user_data = user_data_query_set[0]
+        response_data = user_data.data
+        if user_data.binary:
+            response_data = base64.b64decode(response_data)
+        response_content_type = user_data.content_type
+    elif request.method == 'PUT':
+        content_type = request.META['CONTENT_TYPE']
+        if content_type == None:
+            if binary:
+                content_type = BINARY_DATA_CONTENT_TYPE
+            else:
+                content_type = JSON_CONTENT_TYPE
+        response_data = {}
+        if count == 1:
+            response_data['status'] = 'success'
+            response_data['message'] = 'user data updated'
+            user_data = user_data_query_set[0]
+        else:
+            response_data['status'] = 'success'
+            response_data['message'] = 'user data created'
+            user_data = UserData(user=user,name=name)
+        user_data.binary = binary
+        user_data.content_type = content_type
+        data = request.raw_post_data
+        if binary:
+            data = base64.b64encode(data)
+        user_data.data = data
+        user_data.save()
+        response_data = simplejson.dumps(response_data)
+        response_content_type = JSON_CONTENT_TYPE
+    elif request.method == 'DELETE':
+        if count == 0:
+            raise RestResourceNotFoundException(request.path)
+        user_data = user_data_query_set[0]
+        user_data.delete()
+        response_data = {}
+        response_data['status'] = 'success'
+        response_data['message'] = 'user data deleted'
+        response_data = simplejson.dumps(response_data)
+        response_content_type = JSON_CONTENT_TYPE
+    else:
+        raise RestInvalidMethodException()
+   
+    return HttpResponse(response_data, response_content_type)
+
+@safe_rest_view
+def do_sdnplatform_tunnel_manager(request, dpid=None):
+    """
+    This returns realtime statistics from sdnplatform
+    """
+
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    if dpid == None:
+        raise RestInvalidMethodException()
+
+    print 'DPID', dpid
+    if dpid == 'all':
+        url = controller_url('vns', 'tunnel-manager', 'all', 'json')
+    else:
+        url = controller_url('vns', 'tunnel-manager', 'switch='+dpid, 'json')
+
+    response_text = urllib2.urlopen(url).read()
+    entries = simplejson.loads(response_text)
+
+    if 'error' in entries and entries['error'] != None:
+        RestInternalException(entries['error'])
+
+    return HttpResponse(json.dumps(entries['tunnMap']), JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_sdnplatform_controller_summary(request):
+    """
+    This returns summary statistics from sdnplatform modules
+    """
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+
+    url = controller_url('core', 'controller', 'summary', 'json')
+    return get_sdnplatform_response(url)
+
+def filter_queries(choice_list, param_dict):
+    return dict([[x, param_dict[x]] for x in choice_list
+                if x in param_dict and param_dict[x] != 'all'])
+
+@safe_rest_view
+def do_reload(request):
+    """
+    This calls an oswrapper that reloads the box.
+    """
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    exec_os_wrapper("ReloadController", 'set', [])
+    response_text = '{"status":"reloading"}'
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_resetbsc(request):
+    """
+    This calls an oswrapper that resets the box.
+    """
+    if request.method != 'PUT':
+        raise RestInvalidMethodException()
+    exec_os_wrapper("ResetBsc", 'set', [])
+    response_text = '{"status":"resetting"}'
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_abort_upgrade(request):
+    """
+    This calls an oswrapper that reloads the box.
+    """
+    if request.method != 'PUT':
+        raise RestInvalidMethodException()
+    controller_id = get_local_controller_id()
+    controller = Controller.objects.get(id=controller_id)
+    if controller.status != 'Upgrading':
+        raise RestUpgradeException("No Upgrade pending")
+    exec_os_wrapper("AbortUpgrade", 'set', [])
+    controller.status = 'Ready'
+    controller.save()
+    response_text = '{"status":"Ready"}'
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_config_rollback(request):
+    data = simplejson.loads(request.raw_post_data)
+    path = data['path']
+    print "Executing config rollback with config @", path
+    
+    if request.method != 'PUT':
+        raise RestInvalidMethodException()
+    exec_os_wrapper("RollbackConfig", 'set', [path])
+    response_text = get_successful_response_data('prepared config rollbacked')
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_upload_data(request):
+    if request.method != 'PUT':
+        raise RestInvalidMethodException()
+    data = simplejson.loads(request.raw_post_data)
+    content = data['data']
+    path = data['dst']
+    print "Executing config rollback with config @", path
+    
+    exec_os_wrapper("WriteDataToFile", 'set', [content, path])
+    response_text = get_successful_response_data('written data')
+    return HttpResponse(response_text, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_diff_config(request):
+    if request.method != 'PUT':
+        raise RestInvalidMethodException()
+    data = simplejson.loads(request.raw_post_data)
+    config1 = data['config-1']
+    config2 = data['config-2']
+    print "diffing '%s' with '%s'" %(config1, config2)
+    
+    result = exec_os_wrapper("DiffConfig", 'set', [config1, config2])
+    return HttpResponse(simplejson.dumps(result), JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_extract_upgrade_pkg_manifest(request):
+    """
+    This calls an oswrapper that extracts the upgrade package.
+    This returns the install package 'manifest'.
+    """
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    exec_os_wrapper("GetLatestUpgradePkg", 'get', [])
+    output = exec_os_wrapper("CatUpgradeImagesFile", 'get')
+    upgradePkg = output['out'].strip()
+    exec_os_wrapper("ExtractUpgradePkgManifest", 'set', [upgradePkg])
+    output = exec_os_wrapper("ExtractUpgradePkgManifest", 'get')
+    manifest = output['out']
+    return HttpResponse(manifest, JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_extract_upgrade_pkg(request):
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    exec_os_wrapper("GetLatestUpgradePkg", 'get', [])
+    output = exec_os_wrapper("CatUpgradeImagesFile", 'get')
+    upgradePkg = output['out'].strip()
+    exec_os_wrapper("ExtractUpgradePkg", 'set', [upgradePkg])
+    return HttpResponse('{"status": "OK"}', JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_get_upgrade_pkg(request):
+    """
+    This calls an oswrapper to get the latest upgrade
+    package uploaded to the controller.
+    """
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    exec_os_wrapper("GetLatestUpgradePkg", 'get')
+    result = exec_os_wrapper("CatUpgradeImagesFile", 'get')
+    jsondict = {'file': result['out'].strip()}
+    return HttpResponse(simplejson.dumps(jsondict), JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_cleanup_old_pkgs(request):
+    if request.method != 'GET':
+        raise RestInvalidMethodException()
+    exec_os_wrapper("CleanupOldUpgradeImages", 'get')
+    return HttpResponse('{"status": "OK"}', JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_execute_upgrade_step(request):
+    """
+    Executes a particular upgrade step according to the
+    upgrade package manifest.
+    """
+    if request.method != 'PUT':
+        raise RestInvalidMethodException()
+
+    put_data = json.loads(request.raw_post_data)
+    imageName = put_data.get('imageName')
+    stepNum = put_data.get('step')
+    force = put_data.get('force')
+    
+    args = [stepNum, imageName]
+    if force:
+        args.append("--force")
+    result = exec_os_wrapper("ExecuteUpgradeStep", 'get', 
+                             args)
+    jsondict = {}
+    if len(str(result['err']).strip()) > 0:
+        jsondict['status'] = "ERROR"
+        jsondict['description'] = str(result['err']).strip()
+    else:
+        jsondict['status'] = "OK"
+        jsondict['description'] = str(result['out']).strip()
+
+    return HttpResponse(simplejson.dumps(jsondict), JSON_CONTENT_TYPE)
+
+@safe_rest_view
+def do_sdnplatform_tunnel_config(request):    
+    if request.method != 'PUT' and request.method != 'DELETE':
+        raise RestInvalidMethodException()
+
+    url = controller_url('onos', 'segmentrouting', 'tunnel')
+    post_data = request.raw_post_data
+    put_request = urllib2.Request(url, post_data)
+    method = request.method
+    if method == 'PUT':
+        method = 'POST'
+    put_request.get_method = lambda: method
+    put_request.add_header('Content-Type', 'application/json')
+    response = urllib2.urlopen(put_request)
+    response_text = response.read()
+    response = HttpResponse(response_text, JSON_CONTENT_TYPE)
+    
+    return response
+
+@safe_rest_view
+def do_sdnplatform_policy_config(request):    
+    if request.method != 'PUT' and request.method != 'DELETE':
+        raise RestInvalidMethodException()
+
+    url = controller_url('onos', 'segmentrouting', 'policy')
+    post_data = request.raw_post_data
+    put_request = urllib2.Request(url, post_data)
+    method = request.method
+    if method == 'PUT':
+        method = 'POST'
+    put_request.get_method = lambda: method
+    put_request.add_header('Content-Type', 'application/json')
+    response = urllib2.urlopen(put_request)
+    response_text = response.read()
+    response = HttpResponse(response_text, JSON_CONTENT_TYPE)
+    
+    return response
+
+@safe_rest_view
+def do_show_tunnel(request):    
+    #if request.method != 'GET':
+    #    raise RestInvalidMethodException()
+
+    url = controller_url('onos', 'segmentrouting','tunnel')
+    if request.META['QUERY_STRING']:
+        url += '?' + request.META['QUERY_STRING']
+    return get_sdnplatform_response(url)
+
+@safe_rest_view
+def do_show_policy(request):    
+    #if request.method != 'GET':
+    #    raise RestInvalidMethodException()
+
+    url = controller_url('onos', 'segmentrouting','policy')
+    if request.META['QUERY_STRING']:
+        url += '?' + request.META['QUERY_STRING']
+    return get_sdnplatform_response(url)
\ No newline at end of file
