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:
Deepak N 2011-07-19 11:25:31 +05:30
parent 0781498b84
commit 2de192bb46
2 changed files with 52 additions and 10 deletions

View File

@ -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("_")),

View File

@ -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):