¡@

Home 

OpenStack Study: sql.py

OpenStack Index

**** CubicPower OpenStack Study ****

# 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 uuid

from keystone.common import config

from keystone.common import sql

from keystone.contrib import revoke

from keystone.contrib.revoke import model

CONF = config.CONF

**** CubicPower OpenStack Study ****

class RevocationEvent(sql.ModelBase, sql.ModelDictMixin):

__tablename__ = 'revocation_event'

attributes = model.REVOKE_KEYS

# The id field is not going to be exposed to the outside world.

# It is, however, necessary for SQLAlchemy.

id = sql.Column(sql.String(64), primary_key=True)

domain_id = sql.Column(sql.String(64))

project_id = sql.Column(sql.String(64))

user_id = sql.Column(sql.String(64))

role_id = sql.Column(sql.String(64))

trust_id = sql.Column(sql.String(64))

consumer_id = sql.Column(sql.String(64))

access_token_id = sql.Column(sql.String(64))

issued_before = sql.Column(sql.DateTime(), nullable=False)

expires_at = sql.Column(sql.DateTime())

revoked_at = sql.Column(sql.DateTime(), nullable=False)

**** CubicPower OpenStack Study ****

class Revoke(revoke.Driver):

**** CubicPower OpenStack Study ****

    def _flush_batch_size(self, dialect):

        batch_size = 0

        if dialect == 'ibm_db_sa':

            # This functionality is limited to DB2, because

            # it is necessary to prevent the transaction log

            # from filling up, whereas at least some of the

            # other supported databases do not support update

            # queries with LIMIT subqueries nor do they appear

            # to require the use of such queries when deleting

            # large numbers of records at once.

            batch_size = 100

            # Limit of 100 is known to not fill a transaction log

            # of default maximum size while not significantly

            # impacting the performance of large token purges on

            # systems where the maximum transaction log size has

            # been increased beyond the default.

        return batch_size

**** CubicPower OpenStack Study ****

    def _prune_expired_events(self):

        oldest = revoke.revoked_before_cutoff_time()

        session = sql.get_session()

        dialect = session.bind.dialect.name

        batch_size = self._flush_batch_size(dialect)

        if batch_size > 0:

            query = session.query(RevocationEvent.id)

            query = query.filter(RevocationEvent.revoked_at < oldest)

            query = query.limit(batch_size).subquery()

            delete_query = (session.query(RevocationEvent).

                            filter(RevocationEvent.id.in_(query)))

            while True:

                rowcount = delete_query.delete(synchronize_session=False)

                if rowcount == 0:

                    break

        else:

            query = session.query(RevocationEvent)

            query = query.filter(RevocationEvent.revoked_at < oldest)

            query.delete(synchronize_session=False)

        session.flush()

**** CubicPower OpenStack Study ****

    def get_events(self, last_fetch=None):

        self._prune_expired_events()

        session = sql.get_session()

        query = session.query(RevocationEvent).order_by(

            RevocationEvent.revoked_at)

        if last_fetch:

            query.filter(RevocationEvent.revoked_at >= last_fetch)

            # While the query filter should handle this, it does not

            # appear to be working. It might be a SQLite artifact.

            events = [model.RevokeEvent(**e.to_dict())

                      for e in query

                      if e.revoked_at > last_fetch]

        else:

            events = [model.RevokeEvent(**e.to_dict()) for e in query]

        return events

**** CubicPower OpenStack Study ****

    def revoke(self, event):

        kwargs = dict()

        for attr in model.REVOKE_KEYS:

            kwargs[attr] = getattr(event, attr)

        kwargs['id'] = uuid.uuid4().hex

        record = RevocationEvent(**kwargs)

        session = sql.get_session()

        with session.begin():

            session.add(record)