BGPSpeaker/api/operator: Simplify registration decorator

Currently, in Python3, api.operator call APIs, which are used by
BGPSpeaker.rib_get() for example, cannot be registered correctly.
So call('operator.show', **kwargs) fails to get the registered
method by the symbol 'operator.show'.

This patch simplifies the registration decorator for api.operator
call APIs and fixes this problem.

Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
This commit is contained in:
IWASE Yusuke 2016-09-26 13:59:52 +09:00 committed by FUJITA Tomonori
parent 4348ae6a1f
commit 29d1a97139
2 changed files with 30 additions and 70 deletions

View File

@ -20,7 +20,6 @@
"""
from __future__ import absolute_import
import inspect
import logging
import traceback
@ -89,43 +88,6 @@ def register(**kwargs):
return decorator
def register_method(name):
"""Decorator for registering methods that provide BGPS public API.
"""
def decorator(func):
setattr(func, '__api_method_name__', name)
return func
return decorator
def register_class(cls):
"""Decorator for the registering class whose instance methods provide BGPS
public API.
"""
old_init = cls.__init__
def new_init(self, *args, **kwargs):
old_init(self, *args, **kwargs)
api_registered_methods = \
[(m_name, m) for m_name, m in
inspect.getmembers(cls, predicate=inspect.ismethod)
if hasattr(m, '__api_method_name__')]
for _, method in api_registered_methods:
api_name = getattr(method, '__api_method_name__')
def create_wrapper(method):
def api_method_wrapper(*args, **kwargs):
return method(self, *args, **kwargs)
return api_method_wrapper
register(name=api_name)(create_wrapper(method))
cls.__init__ = new_init
return cls
class RegisterWithArgChecks(object):
"""Decorator for registering API functions.

View File

@ -20,8 +20,7 @@
import logging
from ryu.services.protocols.bgp.api.base import ApiException
from ryu.services.protocols.bgp.api.base import register_class
from ryu.services.protocols.bgp.api.base import register_method
from ryu.services.protocols.bgp.api.base import register
from ryu.services.protocols.bgp.api.rpc_log_handler import RpcLogHandler
from ryu.services.protocols.bgp.operator.command import Command
from ryu.services.protocols.bgp.operator.command import STATUS_ERROR
@ -32,6 +31,18 @@ from ryu.services.protocols.bgp.operator.internal_api import InternalApi
LOG = logging.getLogger('bgpspeaker.api.rtconf')
DEFAULT_LOG_FORMAT = '%(asctime)s %(levelname)s %(message)s'
def _init_log_handler():
log_handler = RpcLogHandler()
log_handler.setLevel(logging.ERROR)
log_handler.formatter = logging.Formatter(DEFAULT_LOG_FORMAT)
return log_handler
INTERNAL_API = InternalApi(_init_log_handler())
class RootCmd(Command):
subcommands = {
@ -40,39 +51,26 @@ class RootCmd(Command):
'clear': ClearCmd}
@register_class
class OperatorApi(object):
default_log_format = '%(asctime)s %(levelname)s %(message)s'
def operator_run(cmd, **kwargs):
params = kwargs.get('params', [])
fmt = kwargs.get('format', 'json')
root = RootCmd(api=INTERNAL_API, resp_formatter_name=fmt)
ret, _ = root([cmd] + params)
if ret.status == STATUS_ERROR:
raise ApiException(str(ret.value))
return ret.value
def __init__(self):
self._init_log_handler()
self.internal_api = InternalApi(self.log_handler)
def _init_log_handler(self):
self.log_handler = RpcLogHandler()
self.log_handler.setLevel(logging.ERROR)
self.log_handler.formatter = logging.Formatter(self.default_log_format)
@register(name="operator.show")
def operator_show(**kwargs):
return operator_run('show', **kwargs)
@register_method(name="operator.show")
def show(self, **kwargs):
return self._run('show', kw=kwargs)
@register_method(name="operator.set")
def set(self, **kwargs):
return self._run('set', kw=kwargs)
@register(name="operator.set")
def operator_set(**kwargs):
return operator_run('set', **kwargs)
@register_method(name="operator.clear")
def clear(self, **kwargs):
return self._run('clear', kw=kwargs)
def _run(self, cmd, kw=None):
kw = kw if kw else {}
params = kw.get('params', [])
fmt = kw.get('format', 'json')
root = RootCmd(api=self.internal_api, resp_formatter_name=fmt)
ret, _ = root([cmd] + params)
if ret.status == STATUS_ERROR:
raise ApiException(str(ret.value))
return ret.value
_OPERATOR_API = OperatorApi()
@register(name="operator.clear")
def operator_clear(**kwargs):
return operator_run('clear', **kwargs)