First QoS versioned objects, ever

Well, first versioned objects in the tree.

Binding to networks and ports is not implemented.

No tests. Checked manually.

blueprint quantum-qos-api

Co-Authored-By: vikram.choudhary <vikram.choudhary@huawei.com>
Change-Id: I9b6cacfda4f40230d746222bed5b6c490be63743
This commit is contained in:
Ihar Hrachyshka 2015-06-30 13:32:27 +03:00
parent d7e60d59a3
commit e90b28662e
7 changed files with 250 additions and 0 deletions

View File

@ -19,9 +19,12 @@ import six
from oslo_config import cfg
from oslo_db import exception as os_db_exception
from oslo_db.sqlalchemy import session
from oslo_utils import uuidutils
from sqlalchemy import exc
from sqlalchemy import orm
from neutron.db import common_db_mixin
_FACADE = None
@ -85,3 +88,39 @@ class convert_db_exception_to_retry(object):
except self.to_catch as e:
raise os_db_exception.RetryRequest(e)
return wrapper
# Common database operation implementations
def get_object(context, model, id):
with context.session.begin(subtransactions=True):
return (common_db_mixin.model_query(context, model)
.filter_by(id=id)
.one())
def get_objects(context, model):
with context.session.begin(subtransactions=True):
return common_db_mixin.model_query(context, model).all()
def create_object(context, model, values):
with context.session.begin(subtransactions=True):
if 'id' not in values:
values['id'] = uuidutils.generate_uuid()
db_obj = model(**values)
context.session.add(db_obj)
return db_obj.__dict__
def update_object(context, model, id, values):
with context.session.begin(subtransactions=True):
db_obj = get_object(context, model, id)
db_obj.update(values)
db_obj.save(session=context.session)
return db_obj.__dict__
def delete_object(context, model, id):
with context.session.begin(subtransactions=True):
db_obj = get_object(context, model, id)
db_obj.delete()

View File

62
neutron/objects/base.py Normal file
View File

@ -0,0 +1,62 @@
# 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 abc
from oslo_versionedobjects import base as obj_base
import six
from neutron.db import api as db_api
# TODO(QoS): revisit dict compatibility and how we can isolate dict behavior
@six.add_metaclass(abc.ABCMeta)
class NeutronObject(obj_base.VersionedObject,
obj_base.VersionedObjectDictCompat):
# should be overridden for all persistent objects
db_model = None
def from_db_object(self, *objs):
for field in self.fields:
for db_obj in objs:
if field in db_obj:
setattr(self, field, db_obj[field])
break
self.obj_reset_changes()
@classmethod
def get_by_id(cls, context, id):
db_obj = db_api.get_object(context, cls.db_model, id)
return cls(context, **db_obj)
@classmethod
def get_objects(cls, context):
db_objs = db_api.get_objects(context, cls.db_model)
objs = [cls(context, **db_obj) for db_obj in db_objs]
return objs
def create(self):
fields = self.obj_get_changes()
db_obj = db_api.create_object(self._context, self.db_model, fields)
self.from_db_object(db_obj)
def update(self):
updates = self.obj_get_changes()
db_obj = db_api.update_object(self._context, self.db_model,
self.id, updates)
self.from_db_object(self, db_obj)
def delete(self):
db_api.delete_object(self._context, self.db_model, self.id)

View File

View File

@ -0,0 +1,38 @@
# Copyright 2015 Red Hat, Inc.
# All Rights Reserved.
#
# 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 oslo_versionedobjects import base as obj_base
from oslo_versionedobjects import fields as obj_fields
from neutron.db.qos import models as qos_db_model
from neutron.objects import base
# TODO(QoS): add rule lists to object fields
# TODO(QoS): implement something for binding networks and ports with policies
@obj_base.VersionedObjectRegistry.register
class QosPolicy(base.NeutronObject):
db_model = qos_db_model.QosPolicy
fields = {
'id': obj_fields.UUIDField(),
'tenant_id': obj_fields.UUIDField(),
'name': obj_fields.StringField(),
'description': obj_fields.StringField(),
'shared': obj_fields.BooleanField()
}

110
neutron/objects/qos/rule.py Normal file
View File

@ -0,0 +1,110 @@
# Copyright 2015 Huawei Technologies India Pvt Ltd, Inc.
# All Rights Reserved.
#
# 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 abc
from oslo_versionedobjects import base as obj_base
from oslo_versionedobjects import fields as obj_fields
import six
from neutron.db import api as db_api
from neutron.db.qos import models as qos_db_model
from neutron.objects import base
@six.add_metaclass(abc.ABCMeta)
class QosRule(base.NeutronObject):
base_db_model = qos_db_model.QosRule
fields = {
'id': obj_fields.UUIDField(),
'tenant_id': obj_fields.UUIDField(),
'type': obj_fields.StringField(),
'qos_policy_id': obj_fields.UUIDField()
}
_core_fields = list(fields.keys())
@classmethod
def _is_core_field(cls, field):
return field in cls._core_fields
@staticmethod
def _filter_fields(fields, func):
return {
key: val for key, val in fields.items()
if func(key)
}
# TODO(QoS): reimplement get_by_id to merge both core and addn fields
def _get_changed_core_fields(self):
fields = self.obj_get_changes()
return self._filter_fields(fields, self._is_core_field)
def _get_changed_addn_fields(self):
fields = self.obj_get_changes()
return self._filter_fields(
fields, lambda key: not self._is_core_field(key))
# TODO(QoS): create and update are not transactional safe
def create(self):
# create base qos_rule
core_fields = self._get_changed_core_fields()
base_db_obj = db_api.create_object(
self._context, self.base_db_model, core_fields)
# create type specific qos_..._rule
addn_fields = self._get_changed_addn_fields()
addn_fields['qos_rule_id'] = base_db_obj.id
addn_db_obj = db_api.create_object(
self._context, self.db_model, addn_fields)
# merge two db objects into single neutron one
self.from_db_object(self._context, self, base_db_obj, addn_db_obj)
def update(self):
updated_db_objs = []
# update base qos_rule, if needed
core_fields = self._get_changed_core_fields()
if core_fields:
base_db_obj = db_api.create_object(
self._context, self.base_db_model, core_fields)
updated_db_objs.append(base_db_obj)
addn_fields = self._get_changed_addn_fields()
if addn_fields:
addn_db_obj = db_api.update_object(
self._context, self.base_db_model, self.id, addn_fields)
updated_db_objs.append(addn_db_obj)
# update neutron object with values from both database objects
self.from_db_object(self._context, self, *updated_db_objs)
# delete is the same, additional rule object cleanup is done thru cascading
@obj_base.VersionedObjectRegistry.register
class QosBandwidthLimitRule(QosRule):
db_model = qos_db_model.QosBandwidthLimitRule
fields = {
'max_kbps': obj_fields.IntegerField(),
'max_burst_kbps': obj_fields.IntegerField()
}

View File

@ -35,6 +35,7 @@ oslo.rootwrap>=2.0.0 # Apache-2.0
oslo.serialization>=1.4.0 # Apache-2.0
oslo.service>=0.1.0 # Apache-2.0
oslo.utils>=1.6.0 # Apache-2.0
oslo.versionedobjects>=0.3.0,!=0.5.0
python-novaclient>=2.22.0