Merge "Refactor Evoque API"

This commit is contained in:
Jenkins 2015-11-10 02:03:12 +00:00 committed by Gerrit Code Review
commit 00ad8f48a0
9 changed files with 182 additions and 145 deletions

View File

@ -1,75 +0,0 @@
# 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 pecan
from pecan import rest
from oslo_log import log
LOG = log.getLogger(__name__)
class TicketController(rest.RestController):
@pecan.expose('json')
def get(self):
return {"version": "1.0.0"}
@pecan.expose('json')
def post(self, **kwargs):
ticket = pecan.request.rpcapi.ticket_create(
name=kwargs['name'])
return ticket
class V1Controller(object):
def __init__(self):
self.sub_controllers = {
"ticket": TicketController(),
}
for name, ctrl in self.sub_controllers.items():
setattr(self, name, ctrl)
@pecan.expose('json')
def index(self):
return {
"version": "1.0",
"links": [
{"rel": "self",
"href": pecan.request.application_url + "/v1"}
] + [
{"rel": name,
"href": pecan.request.application_url + "/v1/" + name}
for name in sorted(self.sub_controllers)
]
}
class RootController(object):
v1 = V1Controller()
@staticmethod
@pecan.expose('json')
def index():
return {
"versions": [{
"status": "CURRENT",
"links": [{
"rel": "self",
"href": pecan.request.application_url + "/v1/"
}],
"id": "v1.0",
"updated": "2015-03-19"
}]
}

View File

@ -10,81 +10,30 @@
# License for the specific language governing permissions and limitations
# under the License.
from oslo_log import log
import pecan
import webob.exc
from werkzeug import serving
from evoque.api import hooks
from evoque.common import service
from evoque import exceptions
LOG = log.getLogger(__name__)
from evoque.api import config as api_config
PECAN_CONFIG = {
'app': {
'root': 'evoque.api.RootController',
'modules': ['evoque.api'],
'hooks': [
hooks.ContextHook(),
hooks.RPCHook(),
],
},
}
def get_pecan_config():
# Set up the pecan configuration
filename = api_config.__file__.replace('.pyc', '.py')
return pecan.configuration.conf_from_file(filename)
class NotImplementedMiddleware(object):
def __init__(self, app):
self.app = app
def setup_app(config=None):
if not config:
config = get_pecan_config()
def __call__(self, environ, start_response):
try:
return self.app(environ, start_response)
except exceptions.NotImplementedError:
raise webob.exc.HTTPNotImplemented(
"Sorry, this Evoque server does "
"not implement this feature :(")
def setup_app(config=PECAN_CONFIG, cfg=None):
if cfg is None:
raise RuntimeError("Config is actually mandatory")
# NOTE(lawrancejing): pecan debug won't work in multi-process environment
pecan_debug = cfg.api.pecan_debug
if cfg.api.workers != 1 and pecan_debug:
pecan_debug = False
LOG.warning('pecan_debug cannot be enabled, if workers is > 1, '
'the value is overrided with False')
app_conf = dict(config.app)
app = pecan.make_app(
config['app']['root'],
debug=pecan_debug,
hooks=config['app']['hooks'],
guess_content_type_from_ext=False,
app_conf.pop('root'),
logging=getattr(config, 'logging', {}),
**app_conf
)
# TODO(liuqing): Add oslo.middleware cors and keystone auth
# http://docs.openstack.org/developer/oslo.middleware/cors.html
return app
class WerkzeugApp(object):
# NOTE(lawrancejing): The purpose of this class is only to be used
# with werkzeug to create the app after the werkzeug
# fork gnocchi-api
def __init__(self, conf):
self.app = None
self.conf = conf
def __call__(self, environ, start_response):
if self.app is None:
self.app = setup_app(cfg=self.conf)
return self.app(environ, start_response)
def build_server():
conf = service.prepare_service()
serving.run_simple(conf.api.host, conf.api.port,
WerkzeugApp(conf),
processes=conf.api.workers)

31
evoque/api/config.py Normal file
View File

@ -0,0 +1,31 @@
# 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 evoque.api import hooks
# Pecan Application Configurations
app = {
'root': 'evoque.api.controllers.root.RootController',
'modules': ['evoque.api'],
'debug': False,
'hooks': [
hooks.ContextHook(),
hooks.RPCHook(),
],
}
# Custom Configurations must be in Python dictionary format::
#
# foo = {'bar':'baz'}
#
# All configurations are accessible at::
# pecan.conf

View File

View File

@ -0,0 +1,34 @@
# 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 pecan
from evoque.api.controllers import v1
class RootController(object):
v1 = v1.Controller()
@staticmethod
@pecan.expose('json')
def index():
return {
"versions": [{
"status": "CURRENT",
"links": [{
"rel": "self",
"href": pecan.request.application_url + "/v1/"
}],
"id": "v1.0",
"updated": "2015-03-19"
}]
}

View File

@ -0,0 +1,40 @@
# 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 pecan
from evoque.api.controllers.v1 import ticket
class Controller(object):
def __init__(self):
self.sub_controllers = {
"ticket": ticket.Controller(),
}
for name, ctrl in self.sub_controllers.items():
setattr(self, name, ctrl)
@pecan.expose('json')
def index(self):
return {
"version": "1.0",
"links": [
{"rel": "self",
"href": pecan.request.application_url + "/v1"}
] + [
{"rel": name,
"href": pecan.request.application_url + "/v1/" + name}
for name in sorted(self.sub_controllers)
]
}

View File

@ -0,0 +1,28 @@
# 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 pecan
from pecan import rest
class Controller(rest.RestController):
@pecan.expose('json')
def get(self):
return {"version": "1.0.0"}
@pecan.expose('json')
def post(self, **kwargs):
ticket = pecan.request.rpcapi.ticket_create(
name=kwargs['name'])
return ticket

View File

@ -11,8 +11,40 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from evoque.api import app
"""Evoque API service."""
import os
from werkzeug import serving
from oslo_config import cfg
from oslo_log import log as logging
from evoque.api import app as api_app
from evoque.common.i18n import _LI
from evoque.common import service
LOG = logging.getLogger(__name__)
class WerkzeugApp(object):
# NOTE(lawrancejing): The purpose of this class is only to be used
# with werkzeug to create the wsgi app
def __init__(self, conf):
self.app = None
self.conf = conf
def __call__(self, environ, start_response):
if self.app is None:
self.app = api_app.setup_app()
return self.app(environ, start_response)
def main():
app.build_server()
service.prepare_service()
LOG.info(_LI('Starting evoque api in PID %s') % os.getpid())
serving.run_simple(cfg.CONF.api.host, cfg.CONF.api.port,
WerkzeugApp(cfg.CONF),
processes=cfg.CONF.api.workers)

View File

@ -31,5 +31,3 @@ def prepare_service():
cfg.CONF(sys.argv[1:], project='evoque')
logging.setup(cfg.CONF, 'evoque')
return cfg.CONF