ryu/app/wsapi.py should be removed for  apache license.
This is the candidate for wsgi server.
Another approach would be to reuse Openstack wsgi framework, but it would
be overkill for our purose.

ryu/app/wsgi.py is the wsgi framework and ryu/app/api.py is a sample.
If this direction is okay, the wsapi client will be converted. and
then remove wsapi.py

thanks,

Signed-off-by: Isaku Yamahata <[email protected]>
---
 bin/ryu-manager |    7 ++
 ryu/app/api.py  |  185 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ryu/app/wsgi.py |   84 +++++++++++++++++++++++++
 3 files changed, 276 insertions(+), 0 deletions(-)
 create mode 100644 ryu/app/api.py
 create mode 100644 ryu/app/wsgi.py

diff --git a/bin/ryu-manager b/bin/ryu-manager
index 8c62f14..b4216ae 100755
--- a/bin/ryu-manager
+++ b/bin/ryu-manager
@@ -28,6 +28,7 @@ from ryu import log
 log.early_init_log(logging.DEBUG)
 
 from ryu import utils
+# from ryu import app
 from ryu.app import wsapi
 from ryu.base.app_manager import AppManager
 from ryu.controller import controller
@@ -66,6 +67,12 @@ def main():
     thr = gevent.spawn_later(0, ws)
     services.append(thr)
 
+    # # TODO:XXX dynamically load applications. use paste?
+    # application = app.wsgi.WSGIApplication()
+    # app.api.setup_routes(application.mapper)
+    # # print 'mapper:\n%s' % application.mapper
+    # webapp = app.wsgi.WSGIServer(application)
+
     gevent.joinall(services)
     app_mgr.close()
 
diff --git a/ryu/app/api.py b/ryu/app/api.py
new file mode 100644
index 0000000..a2a9533
--- /dev/null
+++ b/ryu/app/api.py
@@ -0,0 +1,185 @@
+# Copyright (C) 2012 Isaku Yamahata <yamahata at private email ne jp>
+#
+# Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+#
+# 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 .wsgi import ControllerBase
+
+## TODO:XXX
+## define db interface and store those information into db
+
+
+class TenantController(ControllerBase):
+    tenants = {}
+
+    def __init__(self, req, link, **config):
+        super(TenantController, self).__init__(req, link, **config)
+
+    def create(self, req, **kwargs):
+        print req
+        print kwargs
+
+    def lists(self, req):
+        print self.tenants
+
+    def detail(self, req, tenant_id, **kwargs):
+        print req
+        print tenant_id
+        print kwargs
+
+    def delete(self, req, tenant_id, **kwargs):
+        print req
+        print tenant_id
+        print kwargs
+
+
+class NetworkController(ControllerBase):
+    def __init__(self, req, link, **config):
+        super(NetworkController, self).__init__(req, link, **config)
+
+    def create(self, req, tenant_id, **kwargs):
+        print req
+        print kwargs
+
+    def lists(self, req, tenant_id):
+        print req
+        print tenant_id
+
+    def detail(self, req, tenant_id, network_id, **kwargs):
+        print req
+        print tenant_id
+        print kwargs
+
+    def delete(self, req, tenant_id, network_id, **kwargs):
+        print req
+        print tenant_id
+        print kwargs
+
+
+class PortsController(ControllerBase):
+    def __init__(self, req, link, **config):
+        super(PortsController, self).__init__(req, link, **config)
+
+    def create(self, req, tenant_id, network_id, **kwargs):
+        print req
+        print kwargs
+        print tenant_id
+        print network_id
+
+    def lists(self, req, tenant_id, network_id, **kwargs):
+        print req
+        print tenant_id
+        print network_id
+
+    def detail(self, req, tenant_id, network_id, port_id, **kwargs):
+        print req
+        print tenant_id
+        print network_id
+        print port_id
+        print kwargs
+
+    def delete(self, req, tenant_id, network_id, port_id, **kwargs):
+        print req
+        print tenant_id
+        print network_id
+        print port_id
+        print kwargs
+
+
+class AttachmentController(ControllerBase):
+    def __init__(self, req, link, **config):
+        super(AttachmentController, self).__init__(req, link, **config)
+
+    def create(self, req, tenant_id, network_id, port_id, **kwargs):
+        print req
+        print tenant_id
+        print network_id
+        print port_id
+        print kwargs
+
+    def detail(self, req, tenant_id, network_id, port_id, **kwargs):
+        print req
+        print tenant_id
+        print network_id
+        print port_id
+        print kwargs
+
+    def delete(self, req, tenant_id, network_id, port_id, **kwargs):
+        print req
+        print tenant_id
+        print network_id
+        print port_id
+        print kwargs
+
+
+def setup_routes(mapper):
+    ## Add mappers
+    # TODO:XXX add controllers
+    uri = '/v1.0/tenants'
+    mapper.connect('tenants', uri,
+                   controller=TenantController, action='create',
+                   conditions=dict(method=['POST']))
+    mapper.connect('tenants', uri,
+                   controller=TenantController, action='lists',
+                   conditions=dict(method=['GET', 'HEAD']))
+
+    uri += '/{tenant_id}'
+    mapper.connect('tenants', uri,
+                   controller=TenantController, action='detail',
+                   conditions=dict(method=['GET', 'HEAD']))
+    mapper.connect('tenants', uri,
+                   controller=TenantController, action='delete',
+                   conditions=dict(method=['DELETE']))
+
+    uri += '/networks'
+    mapper.connect('networks', uri,
+                   controller=NetworkController, action='create',
+                   conditions=dict(method=['POST']))
+    mapper.connect('networks', uri,
+                   controller=NetworkController, action='lists',
+                   conditions=dict(method=['GET', 'HEAD']))
+
+    uri += '/{network_id}'
+    mapper.connect('networks', uri,
+                   controller=NetworkController, action='detail',
+                   conditions=dict(method=['GET', 'HEAD']))
+    mapper.connect('networks', uri,
+                   controller=NetworkController, action='delete',
+                   conditions=dict(method=['DELETE']))
+
+    uri += '/ports'
+    mapper.connect('ports', uri,
+                   controller=PortsController, action='create',
+                   conditions=dict(method=['POST']))
+    mapper.connect('ports', uri,
+                   controller=PortsController, action='lists',
+                   conditions=dict(method=['GET', 'HEAD']))
+
+    uri += '/{port_id}'
+    mapper.connect('ports', uri,
+                   controller=PortsController, action='detail',
+                   conditions=dict(method=['GET', 'HEAD']))
+    mapper.connect('ports', uri,
+                   controller=PortsController, action='delete',
+                   conditions=dict(method=['DELETE']))
+
+    uri += '/attachment'
+    mapper.connect('attachment', uri,
+                   controller=AttachmentController, action='create',
+                   conditions=dict(method=['POST']))
+    mapper.connect('attachment', uri,
+                   controller=AttachmentController, action='detail',
+                   conditions=dict(method=['GET', 'HEAD']))
+    mapper.connect('attachment', uri,
+                   controller=AttachmentController, action='delete',
+                   conditions=dict(method=['DELETE']))
diff --git a/ryu/app/wsgi.py b/ryu/app/wsgi.py
new file mode 100644
index 0000000..16d3d07
--- /dev/null
+++ b/ryu/app/wsgi.py
@@ -0,0 +1,84 @@
+# Copyright (C) 2012 Isaku Yamahata <yamahata at private email ne jp>
+#
+# Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+#
+# 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 gflags
+import logging
+import webob.dec
+
+from gevent import pywsgi
+from routes import Mapper
+from routes.util import URLGenerator
+
+LOG = logging.getLogger('scarab.webapp.wsgi')
+LOG.setLevel(logging.DEBUG)
+
+FLAGS = gflags.FLAGS
+gflags.DEFINE_string('wsgi_host', '', 'webapp listen host')
+gflags.DEFINE_integer('wsgi_port', 8081, 'webapp listen port')
+
+
+class ControllerBase(object):
+    special_vars = ['action', 'controller']
+
+    def __init__(self, req, link, **config):
+        self.req = req
+        self.link = link
+        for name, value in config.items():
+            setattr(self, name, value)
+
+    def __call__(self, req):
+        action = self.req.urlvars.get('action', 'index')
+        if hasattr(self, '__before__'):
+            self.__before__()
+
+        kwargs = self.req.urlvars.copy()
+        for attr in self.special_vars:
+            if attr in kwargs:
+                del kwargs[attr]
+
+        # LOG.debug('kwargs %s', kwargs)
+        return getattr(self, action)(req, **kwargs)
+
+
+class WSGIApplication(object):
+    def __init__(self, **config):
+        self.config = config
+        self.mapper = Mapper()
+        super(WSGIApplication, self).__init__()
+
+    @webob.dec.wsgify
+    def __call__(self, req):
+        # LOG.debug('mapper %s', self.mapper)
+        # LOG.debug('req: %s\n', req)
+        # LOG.debug('\nreq.environ: %s', req.environ)
+        res = self.mapper.routematch(environ=req.environ)
+
+        if not res:
+            return webob.exc.HTTPNotFound()
+
+        match, route = res
+        req.urlvars = match
+        link = URLGenerator(self.mapper, req.environ)
+        controller = match['controller'](req, link, **self.config)
+        return controller(req)
+
+
+class WSGIServer(pywsgi.WSGIServer):
+    def __init__(self, application, **config):
+        super(WSGIServer, self).__init__((FLAGS.wsgi_host, FLAGS.wsgi_port),
+                                         application, **config)
+
+    def __call__(self):
+        self.serve_forever()
-- 
1.7.1.1


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to