adpating wsgi files
This commit is contained in:
parent
3a421e759f
commit
64ed5da205
|
@ -56,12 +56,12 @@ class Controller(wsgi.Controller):
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
def index(self, request):
|
def index(self, req):
|
||||||
""" Returns a list of network names and ids """
|
""" Returns a list of network names and ids """
|
||||||
#TODO: this should be for a given tenant!!!
|
#TODO: this should be for a given tenant!!!
|
||||||
print "PIPPO"
|
print "PIPPO"
|
||||||
LOG.debug("HERE - index")
|
LOG.debug("HERE - index")
|
||||||
return self._items(request, is_detail=False)
|
return self._items(req, is_detail=False)
|
||||||
|
|
||||||
def _items(self, req, is_detail):
|
def _items(self, req, is_detail):
|
||||||
""" Returns a list of networks. """
|
""" Returns a list of networks. """
|
||||||
|
|
|
@ -53,6 +53,10 @@ class NotFound(Error):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ClassNotFound(NotFound):
|
||||||
|
message = _("Class %(class_name)s could not be found")
|
||||||
|
|
||||||
|
|
||||||
class Duplicate(Error):
|
class Duplicate(Error):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,8 @@ import logging
|
||||||
import sys
|
import sys
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
from xml.dom import minidom
|
||||||
|
|
||||||
import eventlet
|
import eventlet
|
||||||
import eventlet.wsgi
|
import eventlet.wsgi
|
||||||
eventlet.patcher.monkey_patch(all=False, socket=True)
|
eventlet.patcher.monkey_patch(all=False, socket=True)
|
||||||
|
@ -33,6 +35,7 @@ import routes.middleware
|
||||||
import webob.dec
|
import webob.dec
|
||||||
import webob.exc
|
import webob.exc
|
||||||
|
|
||||||
|
from quantum import utils
|
||||||
from quantum.common import exceptions as exception
|
from quantum.common import exceptions as exception
|
||||||
|
|
||||||
LOG = logging.getLogger('quantum.common.wsgi')
|
LOG = logging.getLogger('quantum.common.wsgi')
|
||||||
|
@ -313,66 +316,95 @@ class Router(object):
|
||||||
|
|
||||||
|
|
||||||
class Controller(object):
|
class Controller(object):
|
||||||
"""
|
"""WSGI app that dispatched to methods.
|
||||||
|
|
||||||
WSGI app that reads routing information supplied by RoutesMiddleware
|
WSGI app that reads routing information supplied by RoutesMiddleware
|
||||||
and calls the requested action method upon itself. All action methods
|
and calls the requested action method upon itself. All action methods
|
||||||
must, in addition to their normal parameters, accept a 'req' argument
|
must, in addition to their normal parameters, accept a 'req' argument
|
||||||
which is the incoming webob.Request. They raise a webob.exc exception,
|
which is the incoming wsgi.Request. They raise a webob.exc exception,
|
||||||
or return a dict which will be serialized by requested content type.
|
or return a dict which will be serialized by requested content type.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@webob.dec.wsgify
|
@webob.dec.wsgify(RequestClass=Request)
|
||||||
def __call__(self, req):
|
def __call__(self, req):
|
||||||
"""
|
"""Call the method specified in req.environ by RoutesMiddleware."""
|
||||||
Call the method specified in req.environ by RoutesMiddleware.
|
|
||||||
"""
|
|
||||||
arg_dict = req.environ['wsgiorg.routing_args'][1]
|
arg_dict = req.environ['wsgiorg.routing_args'][1]
|
||||||
action = arg_dict['action']
|
action = arg_dict['action']
|
||||||
method = getattr(self, action)
|
method = getattr(self, action)
|
||||||
|
LOG.debug("%s %s" % (req.method, req.url))
|
||||||
del arg_dict['controller']
|
del arg_dict['controller']
|
||||||
del arg_dict['action']
|
del arg_dict['action']
|
||||||
arg_dict['request'] = req
|
if 'format' in arg_dict:
|
||||||
|
del arg_dict['format']
|
||||||
|
arg_dict['req'] = req
|
||||||
result = method(**arg_dict)
|
result = method(**arg_dict)
|
||||||
|
|
||||||
if type(result) is dict:
|
if type(result) is dict:
|
||||||
return self._serialize(result, req)
|
content_type = req.best_match_content_type()
|
||||||
|
default_xmlns = self.get_default_xmlns(req)
|
||||||
|
body = self._serialize(result, content_type, default_xmlns)
|
||||||
|
|
||||||
|
response = webob.Response()
|
||||||
|
response.headers['Content-Type'] = content_type
|
||||||
|
response.body = body
|
||||||
|
msg_dict = dict(url=req.url, status=response.status_int)
|
||||||
|
msg = _("%(url)s returned with HTTP %(status)d") % msg_dict
|
||||||
|
LOG.debug(msg)
|
||||||
|
return response
|
||||||
else:
|
else:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def _serialize(self, data, request):
|
def _serialize(self, data, content_type, default_xmlns):
|
||||||
"""
|
"""Serialize the given dict to the provided content_type.
|
||||||
Serialize the given dict to the response type requested in request.
|
|
||||||
Uses self._serialization_metadata if it exists, which is a dict mapping
|
Uses self._serialization_metadata if it exists, which is a dict mapping
|
||||||
MIME types to information needed to serialize to that type.
|
MIME types to information needed to serialize to that type.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
_metadata = getattr(type(self), "_serialization_metadata", {})
|
_metadata = getattr(type(self), '_serialization_metadata', {})
|
||||||
|
|
||||||
|
serializer = Serializer(_metadata, default_xmlns)
|
||||||
|
try:
|
||||||
|
return serializer.serialize(data, content_type)
|
||||||
|
except exception.InvalidContentType:
|
||||||
|
raise webob.exc.HTTPNotAcceptable()
|
||||||
|
|
||||||
|
def _deserialize(self, data, content_type):
|
||||||
|
"""Deserialize the request body to the specefied content type.
|
||||||
|
|
||||||
|
Uses self._serialization_metadata if it exists, which is a dict mapping
|
||||||
|
MIME types to information needed to serialize to that type.
|
||||||
|
|
||||||
|
"""
|
||||||
|
_metadata = getattr(type(self), '_serialization_metadata', {})
|
||||||
serializer = Serializer(_metadata)
|
serializer = Serializer(_metadata)
|
||||||
return serializer.to_content_type(data)
|
return serializer.deserialize(data, content_type)
|
||||||
|
|
||||||
|
|
||||||
|
def get_default_xmlns(self, req):
|
||||||
|
"""Provide the XML namespace to use if none is otherwise specified."""
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
class Serializer(object):
|
class Serializer(object):
|
||||||
"""
|
"""Serializes and deserializes dictionaries to certain MIME types."""
|
||||||
Serializes a dictionary to a Content Type specified by a WSGI environment.
|
|
||||||
"""
|
def __init__(self, metadata=None, default_xmlns=None):
|
||||||
|
"""Create a serializer based on the given WSGI environment.
|
||||||
|
|
||||||
def __init__(self,metadata=None):
|
|
||||||
"""
|
|
||||||
Create a serializer based on the given WSGI environment.
|
|
||||||
'metadata' is an optional dict mapping MIME types to information
|
'metadata' is an optional dict mapping MIME types to information
|
||||||
needed to serialize a dictionary to that type.
|
needed to serialize a dictionary to that type.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.metadata = metadata or {}
|
self.metadata = metadata or {}
|
||||||
self._methods = {
|
self.default_xmlns = default_xmlns
|
||||||
'application/json': self._to_json,
|
|
||||||
'application/xml': self._to_xml}
|
|
||||||
|
|
||||||
|
|
||||||
def _get_serialize_handler(self, content_type):
|
def _get_serialize_handler(self, content_type):
|
||||||
handlers = {
|
handlers = {
|
||||||
'application/json': self._to_json,
|
'application/json': self._to_json,
|
||||||
'application/xml': self._to_xml,
|
'application/xml': self._to_xml,
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return handlers[content_type]
|
return handlers[content_type]
|
||||||
except Exception:
|
except Exception:
|
||||||
|
@ -382,6 +414,14 @@ class Serializer(object):
|
||||||
"""Serialize a dictionary into the specified content type."""
|
"""Serialize a dictionary into the specified content type."""
|
||||||
return self._get_serialize_handler(content_type)(data)
|
return self._get_serialize_handler(content_type)(data)
|
||||||
|
|
||||||
|
def deserialize(self, datastring, content_type):
|
||||||
|
"""Deserialize a string to a dictionary.
|
||||||
|
|
||||||
|
The string must be in the format of a supported MIME type.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return self.get_deserialize_handler(content_type)(datastring)
|
||||||
|
|
||||||
def get_deserialize_handler(self, content_type):
|
def get_deserialize_handler(self, content_type):
|
||||||
handlers = {
|
handlers = {
|
||||||
'application/json': self._from_json,
|
'application/json': self._from_json,
|
||||||
|
@ -393,35 +433,71 @@ class Serializer(object):
|
||||||
except Exception:
|
except Exception:
|
||||||
raise exception.InvalidContentType(content_type=content_type)
|
raise exception.InvalidContentType(content_type=content_type)
|
||||||
|
|
||||||
def deserialize(self, datastring, content_type):
|
def _from_json(self, datastring):
|
||||||
"""Deserialize a string to a dictionary.
|
return utils.loads(datastring)
|
||||||
|
|
||||||
The string must be in the format of a supported MIME type.
|
def _from_xml(self, datastring):
|
||||||
|
xmldata = self.metadata.get('application/xml', {})
|
||||||
|
plurals = set(xmldata.get('plurals', {}))
|
||||||
|
node = minidom.parseString(datastring).childNodes[0]
|
||||||
|
return {node.nodeName: self._from_xml_node(node, plurals)}
|
||||||
|
|
||||||
|
def _from_xml_node(self, node, listnames):
|
||||||
|
"""Convert a minidom node to a simple Python type.
|
||||||
|
|
||||||
|
listnames is a collection of names of XML nodes whose subnodes should
|
||||||
|
be considered list items.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return self.get_deserialize_handler(content_type)(datastring)
|
if len(node.childNodes) == 1 and node.childNodes[0].nodeType == 3:
|
||||||
|
return node.childNodes[0].nodeValue
|
||||||
|
elif node.nodeName in listnames:
|
||||||
|
return [self._from_xml_node(n, listnames) for n in node.childNodes]
|
||||||
|
else:
|
||||||
|
result = dict()
|
||||||
|
for attr in node.attributes.keys():
|
||||||
|
result[attr] = node.attributes[attr].nodeValue
|
||||||
|
for child in node.childNodes:
|
||||||
|
if child.nodeType != node.TEXT_NODE:
|
||||||
|
result[child.nodeName] = self._from_xml_node(child,
|
||||||
|
listnames)
|
||||||
|
return result
|
||||||
|
|
||||||
def _to_json(self, data):
|
def _to_json(self, data):
|
||||||
def sanitizer(obj):
|
return utils.dumps(data)
|
||||||
if isinstance(obj, datetime.datetime):
|
|
||||||
return obj.isoformat()
|
|
||||||
return obj
|
|
||||||
|
|
||||||
return json.dumps(data, default=sanitizer)
|
|
||||||
|
|
||||||
def _to_xml(self, data):
|
def _to_xml(self, data):
|
||||||
metadata = self.metadata.get('application/xml', {})
|
metadata = self.metadata.get('application/xml', {})
|
||||||
# We expect data to contain a single key which is the XML root.
|
# We expect data to contain a single key which is the XML root.
|
||||||
root_key = data.keys()[0]
|
root_key = data.keys()[0]
|
||||||
from xml.dom import minidom
|
|
||||||
doc = minidom.Document()
|
doc = minidom.Document()
|
||||||
node = self._to_xml_node(doc, metadata, root_key, data[root_key])
|
node = self._to_xml_node(doc, metadata, root_key, data[root_key])
|
||||||
|
|
||||||
|
xmlns = node.getAttribute('xmlns')
|
||||||
|
if not xmlns and self.default_xmlns:
|
||||||
|
node.setAttribute('xmlns', self.default_xmlns)
|
||||||
|
|
||||||
return node.toprettyxml(indent=' ')
|
return node.toprettyxml(indent=' ')
|
||||||
|
|
||||||
def _to_xml_node(self, doc, metadata, nodename, data):
|
def _to_xml_node(self, doc, metadata, nodename, data):
|
||||||
"""Recursive method to convert data members to XML nodes."""
|
"""Recursive method to convert data members to XML nodes."""
|
||||||
result = doc.createElement(nodename)
|
result = doc.createElement(nodename)
|
||||||
|
|
||||||
|
# Set the xml namespace if one is specified
|
||||||
|
# TODO(justinsb): We could also use prefixes on the keys
|
||||||
|
xmlns = metadata.get('xmlns', None)
|
||||||
|
if xmlns:
|
||||||
|
result.setAttribute('xmlns', xmlns)
|
||||||
|
|
||||||
if type(data) is list:
|
if type(data) is list:
|
||||||
|
collections = metadata.get('list_collections', {})
|
||||||
|
if nodename in collections:
|
||||||
|
metadata = collections[nodename]
|
||||||
|
for item in data:
|
||||||
|
node = doc.createElement(metadata['item_name'])
|
||||||
|
node.setAttribute(metadata['item_key'], str(item))
|
||||||
|
result.appendChild(node)
|
||||||
|
return result
|
||||||
singular = metadata.get('plurals', {}).get(nodename, None)
|
singular = metadata.get('plurals', {}).get(nodename, None)
|
||||||
if singular is None:
|
if singular is None:
|
||||||
if nodename.endswith('s'):
|
if nodename.endswith('s'):
|
||||||
|
@ -432,15 +508,26 @@ class Serializer(object):
|
||||||
node = self._to_xml_node(doc, metadata, singular, item)
|
node = self._to_xml_node(doc, metadata, singular, item)
|
||||||
result.appendChild(node)
|
result.appendChild(node)
|
||||||
elif type(data) is dict:
|
elif type(data) is dict:
|
||||||
|
collections = metadata.get('dict_collections', {})
|
||||||
|
if nodename in collections:
|
||||||
|
metadata = collections[nodename]
|
||||||
|
for k, v in data.items():
|
||||||
|
node = doc.createElement(metadata['item_name'])
|
||||||
|
node.setAttribute(metadata['item_key'], str(k))
|
||||||
|
text = doc.createTextNode(str(v))
|
||||||
|
node.appendChild(text)
|
||||||
|
result.appendChild(node)
|
||||||
|
return result
|
||||||
attrs = metadata.get('attributes', {}).get(nodename, {})
|
attrs = metadata.get('attributes', {}).get(nodename, {})
|
||||||
for k, v in data.items():
|
for k, v in data.items():
|
||||||
LOG.debug("K:%s - V:%s",k,v)
|
|
||||||
if k in attrs:
|
if k in attrs:
|
||||||
result.setAttribute(k, str(v))
|
result.setAttribute(k, str(v))
|
||||||
else:
|
else:
|
||||||
node = self._to_xml_node(doc, metadata, k, v)
|
node = self._to_xml_node(doc, metadata, k, v)
|
||||||
result.appendChild(node)
|
result.appendChild(node)
|
||||||
else: # atom
|
else:
|
||||||
|
# Type is atom
|
||||||
node = doc.createTextNode(str(data))
|
node = doc.createTextNode(str(data))
|
||||||
result.appendChild(node)
|
result.appendChild(node)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,8 @@ import sys
|
||||||
import time
|
import time
|
||||||
import types
|
import types
|
||||||
|
|
||||||
|
from quantum.common import exceptions as exception
|
||||||
|
|
||||||
|
|
||||||
def import_class(import_str):
|
def import_class(import_str):
|
||||||
"""Returns a class from a string including module and class."""
|
"""Returns a class from a string including module and class."""
|
||||||
|
@ -55,3 +57,34 @@ def import_object(import_str):
|
||||||
except ImportError:
|
except ImportError:
|
||||||
cls = import_class(import_str)
|
cls = import_class(import_str)
|
||||||
return cls()
|
return cls()
|
||||||
|
|
||||||
|
def to_primitive(value):
|
||||||
|
if type(value) is type([]) or type(value) is type((None,)):
|
||||||
|
o = []
|
||||||
|
for v in value:
|
||||||
|
o.append(to_primitive(v))
|
||||||
|
return o
|
||||||
|
elif type(value) is type({}):
|
||||||
|
o = {}
|
||||||
|
for k, v in value.iteritems():
|
||||||
|
o[k] = to_primitive(v)
|
||||||
|
return o
|
||||||
|
elif isinstance(value, datetime.datetime):
|
||||||
|
return str(value)
|
||||||
|
elif hasattr(value, 'iteritems'):
|
||||||
|
return to_primitive(dict(value.iteritems()))
|
||||||
|
elif hasattr(value, '__iter__'):
|
||||||
|
return to_primitive(list(value))
|
||||||
|
else:
|
||||||
|
return value
|
||||||
|
|
||||||
|
def dumps(value):
|
||||||
|
try:
|
||||||
|
return json.dumps(value)
|
||||||
|
except TypeError:
|
||||||
|
pass
|
||||||
|
return json.dumps(to_primitive(value))
|
||||||
|
|
||||||
|
|
||||||
|
def loads(s):
|
||||||
|
return json.loads(s)
|
||||||
|
|
Loading…
Reference in New Issue