| # |
| # Copyright 2017 the original author or authors. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| # |
| |
| """ |
| Loader to load each adapter. |
| In this initial simple implementation we scan all subdirs in this directory, |
| look for a python module with the same name as the subdir, and if module |
| has a class that implements the IAdapterInterface, instantiate class and |
| add it to plugins. |
| """ |
| import os |
| |
| import structlog |
| from twisted.internet.defer import inlineCallbacks, returnValue |
| from zope.interface import implementer |
| from zope.interface.verify import verifyClass |
| |
| from voltha.adapters.interface import IAdapterInterface |
| from voltha.core.adapter_agent import AdapterAgent |
| from voltha.protos import third_party |
| from voltha.registry import IComponent |
| |
| log = structlog.get_logger() |
| |
| |
| mydir = os.path.abspath(os.path.dirname(__file__)) |
| |
| |
| @implementer(IComponent) |
| class AdapterLoader(object): |
| |
| def __init__(self, config): |
| self.config = config |
| self.adapter_agents = {} # adapter-name -> adapter instance |
| |
| @inlineCallbacks |
| def start(self): |
| log.debug('starting') |
| for adapter_name, adapter_class in self._find_adapters(): |
| agent = AdapterAgent(adapter_name, adapter_class) |
| yield agent.start() |
| self.adapter_agents[adapter_name] = agent |
| log.info('started') |
| returnValue(self) |
| |
| @inlineCallbacks |
| def stop(self): |
| log.debug('stopping') |
| for proxy in self.adapter_agents.values(): |
| yield proxy.stop() |
| self.adapter_agents = {} |
| log.info('stopped') |
| |
| def get_agent(self, adapter_name): |
| return self.adapter_agents[adapter_name] |
| |
| def _find_adapters(self): |
| subdirs = os.walk(mydir).next()[1] |
| for subdir in subdirs: |
| try: |
| adapter_name = subdir |
| py_file = os.path.join(mydir, subdir, subdir + '.py') |
| if os.path.isfile(py_file): |
| try: |
| package_name = __package__ + '.' + subdir |
| pkg = __import__(package_name, None, None, [adapter_name]) |
| module = getattr(pkg, adapter_name) |
| except ImportError, e: |
| log.exception('cannot-load', file=py_file, e=e) |
| continue |
| |
| for attr_name in dir(module): |
| cls = getattr(module, attr_name) |
| if isinstance(cls, type) and \ |
| IAdapterInterface.implementedBy(cls): |
| verifyClass(IAdapterInterface, cls) |
| yield adapter_name, cls |
| except Exception, e: |
| log.exception('failed', e=e) |