| # |
| # 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. |
| # |
| |
| """ |
| Voltha's CORE components. |
| """ |
| |
| from Queue import Queue |
| |
| import structlog |
| from twisted.internet.defer import inlineCallbacks, returnValue |
| from zope.interface import implementer |
| |
| from voltha.core.config.config_proxy import CallbackType |
| from voltha.core.device_agent import DeviceAgent |
| from voltha.core.dispatcher import Dispatcher |
| from voltha.core.global_handler import GlobalHandler |
| from voltha.core.local_handler import LocalHandler |
| from voltha.core.logical_device_agent import LogicalDeviceAgent |
| from voltha.protos.voltha_pb2 import \ |
| VolthaLocalServiceStub, \ |
| Device, LogicalDevice |
| from voltha.registry import IComponent |
| |
| log = structlog.get_logger() |
| |
| |
| @implementer(IComponent) |
| class VolthaCore(object): |
| |
| def __init__(self, instance_id, version, log_level): |
| self.instance_id = instance_id |
| self.stopped = False |
| self.dispatcher = Dispatcher(self, instance_id) |
| self.global_handler = GlobalHandler( |
| dispatcher=self.dispatcher, |
| instance_id=instance_id, |
| version=version, |
| log_level=log_level) |
| self.local_handler = LocalHandler( |
| core=self, |
| instance_id=instance_id, |
| version=version, |
| log_level=log_level) |
| self.local_root_proxy = None |
| self.device_agents = {} |
| self.logical_device_agents = {} |
| self.packet_in_queue = Queue() |
| self.change_event_queue = Queue() |
| |
| @inlineCallbacks |
| def start(self, config_backend=None): |
| log.debug('starting') |
| yield self.dispatcher.start() |
| yield self.global_handler.start() |
| yield self.local_handler.start(config_backend=config_backend) |
| self.local_root_proxy = self.get_proxy('/') |
| self.local_root_proxy.register_callback( |
| CallbackType.POST_ADD, self._post_add_callback) |
| self.local_root_proxy.register_callback( |
| CallbackType.POST_REMOVE, self._post_remove_callback) |
| log.info('started') |
| returnValue(self) |
| |
| def stop(self): |
| log.debug('stopping') |
| self.stopped = True |
| log.info('stopped') |
| |
| def get_local_handler(self): |
| return self.local_handler |
| |
| def get_proxy(self, path, exclusive=False): |
| return self.local_handler.get_proxy(path, exclusive) |
| |
| def _post_add_callback(self, data, *args, **kw): |
| log.debug('added', data=data, args=args, kw=kw) |
| if isinstance(data, Device): |
| self._handle_add_device(data) |
| elif isinstance(data, LogicalDevice): |
| self._handle_add_logical_device(data) |
| else: |
| pass # ignore others |
| |
| def _post_remove_callback(self, data, *args, **kw): |
| log.debug('removed', data=data, args=args, kw=kw) |
| if isinstance(data, Device): |
| self._handle_remove_device(data) |
| elif isinstance(data, LogicalDevice): |
| self._handle_remove_logical_device(data) |
| else: |
| pass # ignore others |
| |
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~DeviceAgent Mgmt ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| @inlineCallbacks |
| def _handle_add_device(self, device): |
| # when a device is added, we attach an observer to it so that we can |
| # guard it and propagate changes down to its owner adapter |
| assert isinstance(device, Device) |
| path = '/devices/{}'.format(device.id) |
| assert device.id not in self.device_agents |
| self.device_agents[device.id] = yield DeviceAgent(self, device).start() |
| |
| @inlineCallbacks |
| def _handle_remove_device(self, device): |
| if device.id in self.device_agents: |
| yield self.device_agents[device.id].stop(device) |
| del self.device_agents[device.id] |
| |
| def get_device_agent(self, device_id): |
| return self.device_agents[device_id] |
| |
| # ~~~~~~~~~~~~~~~~~~~~~~~ LogicalDeviceAgent Mgmt ~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| @inlineCallbacks |
| def _handle_add_logical_device(self, logical_device): |
| assert isinstance(logical_device, LogicalDevice) |
| assert logical_device.id not in self.logical_device_agents |
| agent = yield LogicalDeviceAgent(self, logical_device).start() |
| self.logical_device_agents[logical_device.id] = agent |
| |
| @inlineCallbacks |
| def _handle_remove_logical_device(self, logical_device): |
| if logical_device.id in self.logical_device_agents: |
| yield self.logical_device_agents[logical_device.id].stop() |
| del self.logical_device_agents[logical_device.id] |
| |
| def get_logical_device_agent(self, logical_device_id): |
| return self.logical_device_agents[logical_device_id] |