class methods and sub resources in base api ext
Today the get_extended_resources method of our APIExtensionDescriptor class does not account for the SUB_RESOURCE_ATTRIBUTE_MAP and as a result callers of update_attributes_map will also not see the sub resources. This patch updates get_extended_resources to include the sub resources as well. Note that today in neutron, we have both uses: - neutron.extensions.qos.Qos.get_extended_resources uses sub resources. - neutron.extensions.flavors.Flavors.get_extended_resources does not use the sub resource map. In addition this patch changes the methods defined in the APIExtensionDescriptor to be class methods rather than instance methods. There is no real instance data to maintain and in addition consumers need a way to access the update_attributes_map method without having to import and create a concrete neutron extension instance [1]. [1] http://codesearch.openstack.org/?q=%5C(%5C)%5C.update_attributes_map%5C( Change-Id: I8ae11633962a48de6e8559b85447b8c8c753d705
This commit is contained in:
parent
ca47ee87e6
commit
5f2f51d83a
@ -220,32 +220,50 @@ class APIExtensionDescriptor(ExtensionDescriptor):
|
||||
cls._assert_api_definition('UPDATED_TIMESTAMP')
|
||||
return cls.api_definition.UPDATED_TIMESTAMP
|
||||
|
||||
def get_extended_resources(self, version):
|
||||
"""Retrieve the resource attribute map for the API definition."""
|
||||
@classmethod
|
||||
def get_extended_resources(cls, version):
|
||||
"""Retrieve the extended resource map for the API definition.
|
||||
|
||||
:param version: The API version to retrieve the resource attribute
|
||||
map for.
|
||||
:returns: The extended resource map for the underlying API definition
|
||||
if the version is 2.0. The extended resource map returned includes
|
||||
both the API definition's RESOURCE_ATTRIBUTE_MAP and
|
||||
SUB_RESOURCE_ATTRIBUTE_MAP where applicable. If the version is
|
||||
not 2.0, an empty dict is returned.
|
||||
"""
|
||||
if version == "2.0":
|
||||
self._assert_api_definition('RESOURCE_ATTRIBUTE_MAP')
|
||||
return self.api_definition.RESOURCE_ATTRIBUTE_MAP
|
||||
cls._assert_api_definition('RESOURCE_ATTRIBUTE_MAP')
|
||||
cls._assert_api_definition('SUB_RESOURCE_ATTRIBUTE_MAP')
|
||||
# support api defs that use None for sub attr map
|
||||
sub_attrs = cls.api_definition.SUB_RESOURCE_ATTRIBUTE_MAP or {}
|
||||
return dict(
|
||||
list(cls.api_definition.RESOURCE_ATTRIBUTE_MAP.items()) +
|
||||
list(sub_attrs.items()))
|
||||
else:
|
||||
return {}
|
||||
|
||||
def get_required_extensions(self):
|
||||
@classmethod
|
||||
def get_required_extensions(cls):
|
||||
"""Returns the API definition's required extensions."""
|
||||
self._assert_api_definition('REQUIRED_EXTENSIONS')
|
||||
return self.api_definition.REQUIRED_EXTENSIONS
|
||||
cls._assert_api_definition('REQUIRED_EXTENSIONS')
|
||||
return cls.api_definition.REQUIRED_EXTENSIONS
|
||||
|
||||
def get_optional_extensions(self):
|
||||
@classmethod
|
||||
def get_optional_extensions(cls):
|
||||
"""Returns the API definition's optional extensions."""
|
||||
self._assert_api_definition('OPTIONAL_EXTENSIONS')
|
||||
return self.api_definition.OPTIONAL_EXTENSIONS
|
||||
cls._assert_api_definition('OPTIONAL_EXTENSIONS')
|
||||
return cls.api_definition.OPTIONAL_EXTENSIONS
|
||||
|
||||
def update_attributes_map(self, attributes, extension_attrs_map=None):
|
||||
@classmethod
|
||||
def update_attributes_map(cls, attributes, extension_attrs_map=None):
|
||||
"""Update attributes map for this extension.
|
||||
|
||||
Behaves like ExtensionDescriptor.update_attributes_map(), but
|
||||
if extension_attrs_map is not given the extension's API
|
||||
definition RESOURCE_ATTRIBUTE_MAP is used.
|
||||
if extension_attrs_map is not given the dict returned from
|
||||
self.get_extended_resources('2.0') is used.
|
||||
"""
|
||||
if extension_attrs_map is None:
|
||||
extension_attrs_map = self.get_extended_resources('2.0')
|
||||
super(APIExtensionDescriptor, self).update_attributes_map(
|
||||
extension_attrs_map = cls.get_extended_resources('2.0')
|
||||
super(APIExtensionDescriptor, cls()).update_attributes_map(
|
||||
attributes, extension_attrs_map=extension_attrs_map)
|
||||
|
@ -119,6 +119,7 @@ class TestAPIExtensionDescriptor(base.BaseTestCase):
|
||||
DESCRIPTION = 'A test API definition'
|
||||
UPDATED_TIMESTAMP = '2017-02-01T10:00:00-00:00'
|
||||
RESOURCE_ATTRIBUTE_MAP = {'ports': {}}
|
||||
SUB_RESOURCE_ATTRIBUTE_MAP = {'ports': {'debug': {}}}
|
||||
REQUIRED_EXTENSIONS = ['l3']
|
||||
OPTIONAL_EXTENSIONS = ['fw']
|
||||
|
||||
@ -162,7 +163,9 @@ class TestAPIExtensionDescriptor(base.BaseTestCase):
|
||||
self.assertRaises(NotImplementedError, _EmptyAPIDefinition.get_updated)
|
||||
|
||||
def test_get_extended_resources_v2(self):
|
||||
self.assertEqual(self.RESOURCE_ATTRIBUTE_MAP,
|
||||
self.assertEqual(
|
||||
dict(list(self.RESOURCE_ATTRIBUTE_MAP.items()) +
|
||||
list(self.SUB_RESOURCE_ATTRIBUTE_MAP.items())),
|
||||
self.extn.get_extended_resources('2.0'))
|
||||
|
||||
def test_get_extended_resources_v2_unset(self):
|
||||
|
@ -0,0 +1,11 @@
|
||||
---
|
||||
features:
|
||||
- All methods defined in ``APIExtensionDescriptor`` are now class methods.
|
||||
This allows consumers to call them without a reference to an actual
|
||||
extension object instance.
|
||||
fixes:
|
||||
- The ``get_extended_resources`` method of the ``APIExtensionDescriptor``
|
||||
was updated to also include the underlying API definition's
|
||||
``SUB_RESOURCE_ATTRIBUTE_MAP`` in the returned dict. As a result, the
|
||||
``update_attributes_map`` method now also includes the sub-resources if no
|
||||
``extension_attrs_map`` is passed to it.
|
Loading…
Reference in New Issue
Block a user