Deepak/Vinkesh | Added an base abstract class which can be inherited by PluginInterface class which defines the contract expected by extension.
This commit is contained in:
parent
0781498b84
commit
2de192bb46
|
@ -23,15 +23,36 @@ import routes
|
|||
import logging
|
||||
import webob.dec
|
||||
import webob.exc
|
||||
from gettext import gettext as _
|
||||
from abc import ABCMeta, abstractmethod
|
||||
|
||||
from quantum.manager import QuantumManager
|
||||
from quantum.common import exceptions
|
||||
from quantum.common import wsgi
|
||||
from gettext import gettext as _
|
||||
|
||||
LOG = logging.getLogger('quantum.common.extensions')
|
||||
|
||||
|
||||
class PluginInterface(object):
|
||||
__metaclass__ = ABCMeta
|
||||
|
||||
@classmethod
|
||||
def __subclasshook__(cls, klass):
|
||||
"""
|
||||
The __subclasshook__ method is a class method
|
||||
that will be called everytime a class is tested
|
||||
using issubclass(klass, PluginInterface).
|
||||
In that case, it will check that every method
|
||||
marked with the abstractmethod decorator is
|
||||
provided by the plugin class.
|
||||
"""
|
||||
for method in cls.__abstractmethods__:
|
||||
if any(method in base.__dict__ for base in klass.__mro__):
|
||||
continue
|
||||
return NotImplemented
|
||||
return True
|
||||
|
||||
|
||||
class ExtensionDescriptor(object):
|
||||
"""Base class that defines the contract for extensions.
|
||||
|
||||
|
@ -108,6 +129,14 @@ class ExtensionDescriptor(object):
|
|||
request_exts = []
|
||||
return request_exts
|
||||
|
||||
def get_plugin_interface(self):
|
||||
"""
|
||||
Returns an abstract class which defines contract for the plugin.
|
||||
The abstract class should inherit from extesnions.PluginInterface,
|
||||
Methods in this abstract class should be decorated as abstractmethod
|
||||
"""
|
||||
return None
|
||||
|
||||
|
||||
class ActionExtensionController(wsgi.Controller):
|
||||
|
||||
|
@ -363,13 +392,10 @@ class ExtensionManager(object):
|
|||
self.plugin.supports_extension(extension))
|
||||
|
||||
def _plugin_implements_interface(self, extension):
|
||||
if not hasattr(extension, "get_plugin_interface"):
|
||||
if(not hasattr(extension, "get_plugin_interface") or
|
||||
extension.get_plugin_interface() is None):
|
||||
return True
|
||||
interface = extension.get_plugin_interface()
|
||||
expected_methods = self._get_public_methods(interface)
|
||||
implemented_methods = self._get_public_methods(self.plugin.__class__)
|
||||
missing_methods = set(expected_methods) - set(implemented_methods)
|
||||
return not missing_methods
|
||||
return isinstance(self.plugin, extension.get_plugin_interface())
|
||||
|
||||
def _get_public_methods(self, klass):
|
||||
return filter(lambda name: not(name.startswith("_")),
|
||||
|
|
|
@ -18,6 +18,7 @@ import unittest
|
|||
import routes
|
||||
import os.path
|
||||
from tests.unit import BaseTest
|
||||
from abc import abstractmethod
|
||||
|
||||
from webtest import TestApp
|
||||
from quantum.common import extensions
|
||||
|
@ -104,15 +105,16 @@ class StubPlugin(object):
|
|||
class ExtensionExpectingPluginInterface(StubExtension):
|
||||
"""
|
||||
This extension expects plugin to implement all the methods defined
|
||||
in PluginInterface
|
||||
in StubPluginInterface
|
||||
"""
|
||||
|
||||
def get_plugin_interface(self):
|
||||
return PluginInterface
|
||||
return StubPluginInterface
|
||||
|
||||
|
||||
class PluginInterface(object):
|
||||
class StubPluginInterface(extensions.PluginInterface):
|
||||
|
||||
@abstractmethod
|
||||
def get_foo(self, bar=None):
|
||||
pass
|
||||
|
||||
|
@ -207,6 +209,20 @@ class ExtensionManagerTest(unittest.TestCase):
|
|||
|
||||
self.assertTrue("e1" in self.ext_mgr.extensions)
|
||||
|
||||
def test_extensions_without_need_for__plugin_interface_are_loaded(self):
|
||||
class ExtensionWithNoNeedForPluginInterface(StubExtension):
|
||||
"""
|
||||
This Extension does not need any plugin interface.
|
||||
This will work with any plugin implementing QuantumPluginBase
|
||||
"""
|
||||
def get_plugin_interface(self):
|
||||
return None
|
||||
|
||||
self.ext_mgr.plugin = StubPlugin(supported_extensions=["e1"])
|
||||
self.ext_mgr.add_extension(ExtensionWithNoNeedForPluginInterface("e1"))
|
||||
|
||||
self.assertTrue("e1" in self.ext_mgr.extensions)
|
||||
|
||||
|
||||
class ActionExtensionTest(unittest.TestCase):
|
||||
|
||||
|
|
Loading…
Reference in New Issue