From: YAMAMOTO Takashi Date: Tue, 29 Sep 2015 10:58:53 +0000 (+0900) Subject: Simplify extension processing X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=d952cfa8b0a947eedfa5d4291bac965cc4ec8626;p=openstack-build%2Fneutron-build.git Simplify extension processing Now ExtensionDescriptor defines the contract for extensions, don't bother to check existence of attributes which exists in ExtensionDescriptor. Also, reject extensions not derived from ExtensionDescriptor. Closes-Bug: #1501186 Change-Id: I48e179b8739b61f336f5180a22fc66283b9b6991 --- diff --git a/neutron/api/extensions.py b/neutron/api/extensions.py index 4af58774a..c78b5a07d 100644 --- a/neutron/api/extensions.py +++ b/neutron/api/extensions.py @@ -144,6 +144,10 @@ class ExtensionDescriptor(object): """ return None + def get_required_extensions(self): + """Returns a list of extensions to be processed before this one.""" + return [] + def update_attributes_map(self, extended_attributes, extension_attrs_map=None): """Update attributes map for this extension. @@ -389,36 +393,21 @@ class ExtensionManager(object): resources.append(ResourceExtension('extensions', ExtensionController(self))) for ext in self.extensions.values(): - try: - resources.extend(ext.get_resources()) - except AttributeError: - # NOTE(dprince): Extension aren't required to have resource - # extensions - pass + resources.extend(ext.get_resources()) return resources def get_actions(self): """Returns a list of ActionExtension objects.""" actions = [] for ext in self.extensions.values(): - try: - actions.extend(ext.get_actions()) - except AttributeError: - # NOTE(dprince): Extension aren't required to have action - # extensions - pass + actions.extend(ext.get_actions()) return actions def get_request_extensions(self): """Returns a list of RequestExtension objects.""" request_exts = [] for ext in self.extensions.values(): - try: - request_exts.extend(ext.get_request_extensions()) - except AttributeError: - # NOTE(dprince): Extension aren't required to have request - # extensions - pass + request_exts.extend(ext.get_request_extensions()) return request_exts def extend_resources(self, version, attr_map): @@ -430,33 +419,22 @@ class ExtensionManager(object): After this function, we will extend the attr_map if an extension wants to extend this map. """ - update_exts = [] - processed_exts = set() + processed_exts = {} exts_to_process = self.extensions.copy() # Iterate until there are unprocessed extensions or if no progress # is made in a whole iteration while exts_to_process: processed_ext_count = len(processed_exts) for ext_name, ext in list(exts_to_process.items()): - if not hasattr(ext, 'get_extended_resources'): - del exts_to_process[ext_name] + # Process extension only if all required extensions + # have been processed already + required_exts_set = set(ext.get_required_extensions()) + if required_exts_set - set(processed_exts): continue - if hasattr(ext, 'update_attributes_map'): - update_exts.append(ext) - if hasattr(ext, 'get_required_extensions'): - # Process extension only if all required extensions - # have been processed already - required_exts_set = set(ext.get_required_extensions()) - if required_exts_set - processed_exts: - continue - try: - extended_attrs = ext.get_extended_resources(version) - for res, resource_attrs in six.iteritems(extended_attrs): - attr_map.setdefault(res, {}).update(resource_attrs) - except AttributeError: - LOG.exception(_LE("Error fetching extended attributes for " - "extension '%s'"), ext.get_name()) - processed_exts.add(ext_name) + extended_attrs = ext.get_extended_resources(version) + for res, resource_attrs in six.iteritems(extended_attrs): + attr_map.setdefault(res, {}).update(resource_attrs) + processed_exts[ext_name] = ext del exts_to_process[ext_name] if len(processed_exts) == processed_ext_count: # Exit loop as no progress was made @@ -468,7 +446,7 @@ class ExtensionManager(object): ','.join(exts_to_process.keys())) # Extending extensions' attributes map. - for ext in update_exts: + for ext in processed_exts.values(): ext.update_attributes_map(attr_map) def _check_extension(self, extension): @@ -482,7 +460,7 @@ class ExtensionManager(object): LOG.exception(_LE("Exception loading extension: %s"), six.text_type(ex)) return False - return True + return isinstance(extension, ExtensionDescriptor) def _load_all_extensions(self): """Load extensions from the configured path. @@ -567,8 +545,7 @@ class PluginAwareExtensionManager(ExtensionManager): return supports_extension def _plugins_implement_interface(self, extension): - if(not hasattr(extension, "get_plugin_interface") or - extension.get_plugin_interface() is None): + if extension.get_plugin_interface() is None: return True for plugin in self.plugins.values(): if isinstance(plugin, extension.get_plugin_interface()): diff --git a/neutron/tests/unit/extension_stubs.py b/neutron/tests/unit/extension_stubs.py index f98d21491..bd3bbdc6b 100644 --- a/neutron/tests/unit/extension_stubs.py +++ b/neutron/tests/unit/extension_stubs.py @@ -19,7 +19,7 @@ from neutron.api import extensions from neutron import wsgi -class StubExtension(object): +class StubExtension(extensions.ExtensionDescriptor): def __init__(self, alias="stub_extension"): self.alias = alias diff --git a/neutron/tests/unit/extensions/foxinsocks.py b/neutron/tests/unit/extensions/foxinsocks.py index 88908a490..d42f2b494 100644 --- a/neutron/tests/unit/extensions/foxinsocks.py +++ b/neutron/tests/unit/extensions/foxinsocks.py @@ -34,7 +34,7 @@ class FoxInSocksPluginInterface(extensions.PluginInterface): pass -class Foxinsocks(object): +class Foxinsocks(extensions.ExtensionDescriptor): def __init__(self): pass diff --git a/neutron/tests/unit/extensions/v2attributes.py b/neutron/tests/unit/extensions/v2attributes.py index 6259eb356..2adfcc12f 100644 --- a/neutron/tests/unit/extensions/v2attributes.py +++ b/neutron/tests/unit/extensions/v2attributes.py @@ -13,6 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +from neutron.api import extensions + + EXTENDED_ATTRIBUTES_2_0 = { 'networks': { 'v2attrs:something': {'allow_post': False, @@ -25,7 +28,7 @@ EXTENDED_ATTRIBUTES_2_0 = { } -class V2attributes(object): +class V2attributes(extensions.ExtensionDescriptor): def get_name(self): return "V2 Extended Attributes Example"