keystone源码解析-装饰器【原创】

@controller.protected()

@controller.protected()
    def create_credential(self, request, credential):
        validation.lazy_validate(schema.credential_create, credential)
        ref = self._assign_unique_id(self._normalize_dict(credential),
                                     request.context.trust_id)
        ref = self.credential_api.create_credential(ref['id'], ref)
        return CredentialV3.wrap_member(request.context_dict, ref)
        
    def protected(callback=None):
        # 该函数实现认证的权限检查check_policy,也就是说有没有权限去访问该API
        def wrapper(f):
            @functools.wraps(f)
            def inner(self, request, *args, **kwargs):
                check_function = authorization.check_protection
                if callback is not None:
                    check_function = callback

                protected_wrapper(
                    self, f, check_function, request, None, *args, **kwargs)
                return f(self, request, *args, **kwargs)
            return inner
        return wrapper

 
protected是一个带参数的装饰器, callback为装饰器的参数,可以为空
当程序调用到create_credential函数时,会先执行controller.protected()函数。即会调用到protecetd函数中,
函数参数request, args, kwargs也会传入inner中,执行。然后返回继续执行create_credential。

@dependency.provider

 

@dependency.provider('id_generator_api')
class Manager(manager.Manager):
    """Default pivot point for the identifier generator backend."""

    driver_namespace = 'keystone.identity.id_generator'

    def __init__(self):
        super(Manager, self).__init__(CONF.identity_mapping.generator)



def provider(name):
    def wrapper(cls):
        def wrapped(init):
            def __wrapped_init__(self, *args, **kwargs):
                """Initialize the wrapped object and add it to the registry."""
                init(self, *args, **kwargs)
                _set_provider(name, self)
                resolve_future_dependencies(__provider_name=name)

            return __wrapped_init__

        cls.__init__ = wrapped(cls.__init__)
        _factories[name] = cls
        return cls
    return wrapper

 
这是一个由闭包实现的类装饰器,provider接受参数name='id_generator_api', 并将类Manager作为参数传入,作为wrapper的参数。
provider函数实现的功能:初始化类并将该类注册到全局变量_REGISTRY中,_REGISTRY是保存所有的manager实体的dict.


@dependency.requires

该装饰器的作用是将相应的manager模块设置为本类的一个成员变量,以达到不同类之间的相互引用不同的manager的效果。manager是一组关于逻辑处理的集合。所以这样就达到了
不同的类之间的逻辑操作的效果

@dependency.requires('assignment_api', 'identity_api', 'resource_api',
                     'role_api')
class GrantAssignmentV3(controller.V3Controller):

 



以上的意思是: GrantAssignmentV3中添加GrantAssignmentV3.assignment_api = _REGISTRY['identity_api']等

 

 metaclass

metaclass被称之为元类,即能生成类的类。是一种抽象的概念。是实现多态的一种机制。可以动态的生成类。
abstractmethod  虚函数, 在元类中的含有abstractmethod  的函数在子类中必须要实现。

元类RoleDriverBase
@six.add_metaclass(abc.ABCMeta)
class RoleDriverBase(object):

    def _get_list_limit(self):
        return CONF.role.list_limit or CONF.list_limit

    @abc.abstractmethod
    def create_role(self, role_id, role):
        """Create a new role.

        :raises keystone.exception.Conflict: If a duplicate role exists.

        """
        raise exception.NotImplemented()  # pragma: no cover

子类
class Role(base.RoleDriverBase):
    @sql.handle_conflicts(conflict_type='role')
    def create_role(self, role_id, role):
        with sql.session_for_write() as session:
            ref = RoleTable.from_dict(role)
            session.add(ref)
            return ref.to_dict()

 





posted on 2017-11-14 15:20  _沉睡的狮子  阅读(393)  评论(0)    收藏  举报

导航