Make @truncated common for all backends
Although not used in all backends now, @truncated decorator can be useful in all of them and there is no sense in making it sql-only. Change-Id: I063cb1d621f4e2bf4d350450a56044d0b6cee7c1 Partial-Bug: 1501698
This commit is contained in:
parent
1968ab54aa
commit
19a25bab9c
|
@ -11,6 +11,7 @@
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from keystone import assignment
|
from keystone import assignment
|
||||||
|
from keystone.common import driver_hints
|
||||||
from keystone.common import sql
|
from keystone.common import sql
|
||||||
from keystone import exception
|
from keystone import exception
|
||||||
|
|
||||||
|
@ -24,7 +25,7 @@ class Role(assignment.RoleDriverV9):
|
||||||
session.add(ref)
|
session.add(ref)
|
||||||
return ref.to_dict()
|
return ref.to_dict()
|
||||||
|
|
||||||
@sql.truncated
|
@driver_hints.truncated
|
||||||
def list_roles(self, hints):
|
def list_roles(self, hints):
|
||||||
with sql.transaction() as session:
|
with sql.transaction() as session:
|
||||||
query = session.query(RoleTable)
|
query = session.query(RoleTable)
|
||||||
|
|
|
@ -21,6 +21,7 @@ from sqlalchemy.sql import true
|
||||||
|
|
||||||
from keystone import catalog
|
from keystone import catalog
|
||||||
from keystone.catalog import core
|
from keystone.catalog import core
|
||||||
|
from keystone.common import driver_hints
|
||||||
from keystone.common import sql
|
from keystone.common import sql
|
||||||
from keystone import exception
|
from keystone import exception
|
||||||
from keystone.i18n import _
|
from keystone.i18n import _
|
||||||
|
@ -171,7 +172,7 @@ class Catalog(catalog.CatalogDriverV8):
|
||||||
return ref.to_dict()
|
return ref.to_dict()
|
||||||
|
|
||||||
# Services
|
# Services
|
||||||
@sql.truncated
|
@driver_hints.truncated
|
||||||
def list_services(self, hints):
|
def list_services(self, hints):
|
||||||
session = sql.get_session()
|
session = sql.get_session()
|
||||||
services = session.query(Service)
|
services = session.query(Service)
|
||||||
|
@ -240,7 +241,7 @@ class Catalog(catalog.CatalogDriverV8):
|
||||||
session = sql.get_session()
|
session = sql.get_session()
|
||||||
return self._get_endpoint(session, endpoint_id).to_dict()
|
return self._get_endpoint(session, endpoint_id).to_dict()
|
||||||
|
|
||||||
@sql.truncated
|
@driver_hints.truncated
|
||||||
def list_endpoints(self, hints):
|
def list_endpoints(self, hints):
|
||||||
session = sql.get_session()
|
session = sql.get_session()
|
||||||
endpoints = session.query(Endpoint)
|
endpoints = session.query(Endpoint)
|
||||||
|
|
|
@ -13,6 +13,50 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import functools
|
||||||
|
|
||||||
|
from keystone import exception
|
||||||
|
from keystone.i18n import _
|
||||||
|
|
||||||
|
|
||||||
|
def truncated(f):
|
||||||
|
"""Ensure list truncation is detected in Driver list entity methods.
|
||||||
|
|
||||||
|
This is designed to wrap Driver list_{entity} methods in order to
|
||||||
|
calculate if the resultant list has been truncated. Provided a limit dict
|
||||||
|
is found in the hints list, we increment the limit by one so as to ask the
|
||||||
|
wrapped function for one more entity than the limit, and then once the list
|
||||||
|
has been generated, we check to see if the original limit has been
|
||||||
|
exceeded, in which case we truncate back to that limit and set the
|
||||||
|
'truncated' boolean to 'true' in the hints limit dict.
|
||||||
|
|
||||||
|
"""
|
||||||
|
@functools.wraps(f)
|
||||||
|
def wrapper(self, hints, *args, **kwargs):
|
||||||
|
if not hasattr(hints, 'limit'):
|
||||||
|
raise exception.UnexpectedError(
|
||||||
|
_('Cannot truncate a driver call without hints list as '
|
||||||
|
'first parameter after self '))
|
||||||
|
|
||||||
|
if hints.limit is None:
|
||||||
|
return f(self, hints, *args, **kwargs)
|
||||||
|
|
||||||
|
# A limit is set, so ask for one more entry than we need
|
||||||
|
list_limit = hints.limit['limit']
|
||||||
|
hints.set_limit(list_limit + 1)
|
||||||
|
ref_list = f(self, hints, *args, **kwargs)
|
||||||
|
|
||||||
|
# If we got more than the original limit then trim back the list and
|
||||||
|
# mark it truncated. In both cases, make sure we set the limit back
|
||||||
|
# to its original value.
|
||||||
|
if len(ref_list) > list_limit:
|
||||||
|
hints.set_limit(list_limit, truncated=True)
|
||||||
|
return ref_list[:list_limit]
|
||||||
|
else:
|
||||||
|
hints.set_limit(list_limit)
|
||||||
|
return ref_list
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
class Hints(object):
|
class Hints(object):
|
||||||
"""Encapsulate driver hints for listing entities.
|
"""Encapsulate driver hints for listing entities.
|
||||||
|
|
|
@ -34,6 +34,7 @@ from sqlalchemy.ext import declarative
|
||||||
from sqlalchemy.orm.attributes import flag_modified, InstrumentedAttribute
|
from sqlalchemy.orm.attributes import flag_modified, InstrumentedAttribute
|
||||||
from sqlalchemy import types as sql_types
|
from sqlalchemy import types as sql_types
|
||||||
|
|
||||||
|
from keystone.common import driver_hints
|
||||||
from keystone.common import utils
|
from keystone.common import utils
|
||||||
from keystone import exception
|
from keystone import exception
|
||||||
from keystone.i18n import _
|
from keystone.i18n import _
|
||||||
|
@ -200,42 +201,7 @@ def transaction(expire_on_commit=False):
|
||||||
|
|
||||||
|
|
||||||
def truncated(f):
|
def truncated(f):
|
||||||
"""Ensure list truncation is detected in Driver list entity methods.
|
return driver_hints.truncated(f)
|
||||||
|
|
||||||
This is designed to wrap and sql Driver list_{entity} methods in order to
|
|
||||||
calculate if the resultant list has been truncated. Provided a limit dict
|
|
||||||
is found in the hints list, we increment the limit by one so as to ask the
|
|
||||||
wrapped function for one more entity than the limit, and then once the list
|
|
||||||
has been generated, we check to see if the original limit has been
|
|
||||||
exceeded, in which case we truncate back to that limit and set the
|
|
||||||
'truncated' boolean to 'true' in the hints limit dict.
|
|
||||||
|
|
||||||
"""
|
|
||||||
@functools.wraps(f)
|
|
||||||
def wrapper(self, hints, *args, **kwargs):
|
|
||||||
if not hasattr(hints, 'limit'):
|
|
||||||
raise exception.UnexpectedError(
|
|
||||||
_('Cannot truncate a driver call without hints list as '
|
|
||||||
'first parameter after self '))
|
|
||||||
|
|
||||||
if hints.limit is None:
|
|
||||||
return f(self, hints, *args, **kwargs)
|
|
||||||
|
|
||||||
# A limit is set, so ask for one more entry than we need
|
|
||||||
list_limit = hints.limit['limit']
|
|
||||||
hints.set_limit(list_limit + 1)
|
|
||||||
ref_list = f(self, hints, *args, **kwargs)
|
|
||||||
|
|
||||||
# If we got more than the original limit then trim back the list and
|
|
||||||
# mark it truncated. In both cases, make sure we set the limit back
|
|
||||||
# to its original value.
|
|
||||||
if len(ref_list) > list_limit:
|
|
||||||
hints.set_limit(list_limit, truncated=True)
|
|
||||||
return ref_list[:list_limit]
|
|
||||||
else:
|
|
||||||
hints.set_limit(list_limit)
|
|
||||||
return ref_list
|
|
||||||
return wrapper
|
|
||||||
|
|
||||||
|
|
||||||
class _WontMatch(Exception):
|
class _WontMatch(Exception):
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
from keystone.common import driver_hints
|
||||||
from keystone.common import sql
|
from keystone.common import sql
|
||||||
from keystone import credential
|
from keystone import credential
|
||||||
from keystone import exception
|
from keystone import exception
|
||||||
|
@ -41,7 +42,7 @@ class Credential(credential.CredentialDriverV8):
|
||||||
session.add(ref)
|
session.add(ref)
|
||||||
return ref.to_dict()
|
return ref.to_dict()
|
||||||
|
|
||||||
@sql.truncated
|
@driver_hints.truncated
|
||||||
def list_credentials(self, hints):
|
def list_credentials(self, hints):
|
||||||
session = sql.get_session()
|
session = sql.get_session()
|
||||||
credentials = session.query(CredentialModel)
|
credentials = session.query(CredentialModel)
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
|
|
||||||
|
from keystone.common import driver_hints
|
||||||
from keystone.common import sql
|
from keystone.common import sql
|
||||||
from keystone.common import utils
|
from keystone.common import utils
|
||||||
from keystone import exception
|
from keystone import exception
|
||||||
|
@ -118,7 +119,7 @@ class Identity(identity.IdentityDriverV8):
|
||||||
session.add(user_ref)
|
session.add(user_ref)
|
||||||
return identity.filter_user(user_ref.to_dict())
|
return identity.filter_user(user_ref.to_dict())
|
||||||
|
|
||||||
@sql.truncated
|
@driver_hints.truncated
|
||||||
def list_users(self, hints):
|
def list_users(self, hints):
|
||||||
session = sql.get_session()
|
session = sql.get_session()
|
||||||
query = session.query(User)
|
query = session.query(User)
|
||||||
|
@ -249,7 +250,7 @@ class Identity(identity.IdentityDriverV8):
|
||||||
session.add(ref)
|
session.add(ref)
|
||||||
return ref.to_dict()
|
return ref.to_dict()
|
||||||
|
|
||||||
@sql.truncated
|
@driver_hints.truncated
|
||||||
def list_groups(self, hints):
|
def list_groups(self, hints):
|
||||||
session = sql.get_session()
|
session = sql.get_session()
|
||||||
query = session.query(Group)
|
query = session.query(Group)
|
||||||
|
|
|
@ -14,6 +14,7 @@ from oslo_config import cfg
|
||||||
from oslo_log import log
|
from oslo_log import log
|
||||||
|
|
||||||
from keystone.common import clean
|
from keystone.common import clean
|
||||||
|
from keystone.common import driver_hints
|
||||||
from keystone.common import sql
|
from keystone.common import sql
|
||||||
from keystone import exception
|
from keystone import exception
|
||||||
from keystone.i18n import _LE
|
from keystone.i18n import _LE
|
||||||
|
@ -50,7 +51,7 @@ class Resource(keystone_resource.ResourceDriverV8):
|
||||||
raise exception.ProjectNotFound(project_id=tenant_name)
|
raise exception.ProjectNotFound(project_id=tenant_name)
|
||||||
return project_ref.to_dict()
|
return project_ref.to_dict()
|
||||||
|
|
||||||
@sql.truncated
|
@driver_hints.truncated
|
||||||
def list_projects(self, hints):
|
def list_projects(self, hints):
|
||||||
with sql.transaction() as session:
|
with sql.transaction() as session:
|
||||||
query = session.query(Project)
|
query = session.query(Project)
|
||||||
|
@ -176,7 +177,7 @@ class Resource(keystone_resource.ResourceDriverV8):
|
||||||
session.add(ref)
|
session.add(ref)
|
||||||
return ref.to_dict()
|
return ref.to_dict()
|
||||||
|
|
||||||
@sql.truncated
|
@driver_hints.truncated
|
||||||
def list_domains(self, hints):
|
def list_domains(self, hints):
|
||||||
with sql.transaction() as session:
|
with sql.transaction() as session:
|
||||||
query = session.query(Domain)
|
query = session.query(Domain)
|
||||||
|
|
Loading…
Reference in New Issue