Merge "Simplify extension processing"
This commit is contained in:
commit
0399f8383f
|
@ -144,6 +144,10 @@ class ExtensionDescriptor(object):
|
||||||
"""
|
"""
|
||||||
return None
|
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,
|
def update_attributes_map(self, extended_attributes,
|
||||||
extension_attrs_map=None):
|
extension_attrs_map=None):
|
||||||
"""Update attributes map for this extension.
|
"""Update attributes map for this extension.
|
||||||
|
@ -389,36 +393,21 @@ class ExtensionManager(object):
|
||||||
resources.append(ResourceExtension('extensions',
|
resources.append(ResourceExtension('extensions',
|
||||||
ExtensionController(self)))
|
ExtensionController(self)))
|
||||||
for ext in self.extensions.values():
|
for ext in self.extensions.values():
|
||||||
try:
|
resources.extend(ext.get_resources())
|
||||||
resources.extend(ext.get_resources())
|
|
||||||
except AttributeError:
|
|
||||||
# NOTE(dprince): Extension aren't required to have resource
|
|
||||||
# extensions
|
|
||||||
pass
|
|
||||||
return resources
|
return resources
|
||||||
|
|
||||||
def get_actions(self):
|
def get_actions(self):
|
||||||
"""Returns a list of ActionExtension objects."""
|
"""Returns a list of ActionExtension objects."""
|
||||||
actions = []
|
actions = []
|
||||||
for ext in self.extensions.values():
|
for ext in self.extensions.values():
|
||||||
try:
|
actions.extend(ext.get_actions())
|
||||||
actions.extend(ext.get_actions())
|
|
||||||
except AttributeError:
|
|
||||||
# NOTE(dprince): Extension aren't required to have action
|
|
||||||
# extensions
|
|
||||||
pass
|
|
||||||
return actions
|
return actions
|
||||||
|
|
||||||
def get_request_extensions(self):
|
def get_request_extensions(self):
|
||||||
"""Returns a list of RequestExtension objects."""
|
"""Returns a list of RequestExtension objects."""
|
||||||
request_exts = []
|
request_exts = []
|
||||||
for ext in self.extensions.values():
|
for ext in self.extensions.values():
|
||||||
try:
|
request_exts.extend(ext.get_request_extensions())
|
||||||
request_exts.extend(ext.get_request_extensions())
|
|
||||||
except AttributeError:
|
|
||||||
# NOTE(dprince): Extension aren't required to have request
|
|
||||||
# extensions
|
|
||||||
pass
|
|
||||||
return request_exts
|
return request_exts
|
||||||
|
|
||||||
def extend_resources(self, version, attr_map):
|
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
|
After this function, we will extend the attr_map if an extension
|
||||||
wants to extend this map.
|
wants to extend this map.
|
||||||
"""
|
"""
|
||||||
update_exts = []
|
processed_exts = {}
|
||||||
processed_exts = set()
|
|
||||||
exts_to_process = self.extensions.copy()
|
exts_to_process = self.extensions.copy()
|
||||||
# Iterate until there are unprocessed extensions or if no progress
|
# Iterate until there are unprocessed extensions or if no progress
|
||||||
# is made in a whole iteration
|
# is made in a whole iteration
|
||||||
while exts_to_process:
|
while exts_to_process:
|
||||||
processed_ext_count = len(processed_exts)
|
processed_ext_count = len(processed_exts)
|
||||||
for ext_name, ext in list(exts_to_process.items()):
|
for ext_name, ext in list(exts_to_process.items()):
|
||||||
if not hasattr(ext, 'get_extended_resources'):
|
# Process extension only if all required extensions
|
||||||
del exts_to_process[ext_name]
|
# have been processed already
|
||||||
|
required_exts_set = set(ext.get_required_extensions())
|
||||||
|
if required_exts_set - set(processed_exts):
|
||||||
continue
|
continue
|
||||||
if hasattr(ext, 'update_attributes_map'):
|
extended_attrs = ext.get_extended_resources(version)
|
||||||
update_exts.append(ext)
|
for res, resource_attrs in six.iteritems(extended_attrs):
|
||||||
if hasattr(ext, 'get_required_extensions'):
|
attr_map.setdefault(res, {}).update(resource_attrs)
|
||||||
# Process extension only if all required extensions
|
processed_exts[ext_name] = ext
|
||||||
# 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)
|
|
||||||
del exts_to_process[ext_name]
|
del exts_to_process[ext_name]
|
||||||
if len(processed_exts) == processed_ext_count:
|
if len(processed_exts) == processed_ext_count:
|
||||||
# Exit loop as no progress was made
|
# Exit loop as no progress was made
|
||||||
|
@ -468,7 +446,7 @@ class ExtensionManager(object):
|
||||||
','.join(exts_to_process.keys()))
|
','.join(exts_to_process.keys()))
|
||||||
|
|
||||||
# Extending extensions' attributes map.
|
# Extending extensions' attributes map.
|
||||||
for ext in update_exts:
|
for ext in processed_exts.values():
|
||||||
ext.update_attributes_map(attr_map)
|
ext.update_attributes_map(attr_map)
|
||||||
|
|
||||||
def _check_extension(self, extension):
|
def _check_extension(self, extension):
|
||||||
|
@ -481,7 +459,7 @@ class ExtensionManager(object):
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
LOG.exception(_LE("Exception loading extension"))
|
LOG.exception(_LE("Exception loading extension"))
|
||||||
return False
|
return False
|
||||||
return True
|
return isinstance(extension, ExtensionDescriptor)
|
||||||
|
|
||||||
def _load_all_extensions(self):
|
def _load_all_extensions(self):
|
||||||
"""Load extensions from the configured path.
|
"""Load extensions from the configured path.
|
||||||
|
@ -566,8 +544,7 @@ class PluginAwareExtensionManager(ExtensionManager):
|
||||||
return supports_extension
|
return supports_extension
|
||||||
|
|
||||||
def _plugins_implement_interface(self, extension):
|
def _plugins_implement_interface(self, extension):
|
||||||
if(not hasattr(extension, "get_plugin_interface") or
|
if extension.get_plugin_interface() is None:
|
||||||
extension.get_plugin_interface() is None):
|
|
||||||
return True
|
return True
|
||||||
for plugin in self.plugins.values():
|
for plugin in self.plugins.values():
|
||||||
if isinstance(plugin, extension.get_plugin_interface()):
|
if isinstance(plugin, extension.get_plugin_interface()):
|
||||||
|
|
|
@ -19,7 +19,7 @@ from neutron.api import extensions
|
||||||
from neutron import wsgi
|
from neutron import wsgi
|
||||||
|
|
||||||
|
|
||||||
class StubExtension(object):
|
class StubExtension(extensions.ExtensionDescriptor):
|
||||||
|
|
||||||
def __init__(self, alias="stub_extension"):
|
def __init__(self, alias="stub_extension"):
|
||||||
self.alias = alias
|
self.alias = alias
|
||||||
|
|
|
@ -34,7 +34,7 @@ class FoxInSocksPluginInterface(extensions.PluginInterface):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Foxinsocks(object):
|
class Foxinsocks(extensions.ExtensionDescriptor):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -13,6 +13,9 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
from neutron.api import extensions
|
||||||
|
|
||||||
|
|
||||||
EXTENDED_ATTRIBUTES_2_0 = {
|
EXTENDED_ATTRIBUTES_2_0 = {
|
||||||
'networks': {
|
'networks': {
|
||||||
'v2attrs:something': {'allow_post': False,
|
'v2attrs:something': {'allow_post': False,
|
||||||
|
@ -25,7 +28,7 @@ EXTENDED_ATTRIBUTES_2_0 = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class V2attributes(object):
|
class V2attributes(extensions.ExtensionDescriptor):
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
return "V2 Extended Attributes Example"
|
return "V2 Extended Attributes Example"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue