From 98d2ea344bb67e10ff1b61038139c7bb2db83948 Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Fri, 1 Mar 2019 20:41:13 +0100 Subject: [PATCH] add RouterManager --- boswatch/router.py | 160 +++++++++++++++++++++++++-------------------- config/server.yaml | 1 + router_test.py | 83 ++++------------------- 3 files changed, 103 insertions(+), 141 deletions(-) diff --git a/boswatch/router.py b/boswatch/router.py index b4dc7e3..c167461 100644 --- a/boswatch/router.py +++ b/boswatch/router.py @@ -1,84 +1,104 @@ -class Module: +#!/usr/bin/python +# -*- coding: utf-8 -*- +"""! + ____ ____ ______ __ __ __ _____ + / __ )/ __ \/ ___/ | / /___ _/ /______/ /_ |__ / + / __ / / / /\__ \| | /| / / __ `/ __/ ___/ __ \ /_ < + / /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / ___/ / +/_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ /____/ + German BOS Information Script + by Bastian Schroll + +@file: router.py +@date: 01.03.2019 +@author: Bastian Schroll +@description: Class for the BOSWatch packet router +""" +import logging +import copy +import importlib + +logging.debug("- %s loaded", __name__) + + +class _Router: def __init__(self, name): self.__name = name + self.__route = [] + logging.debug("add new router: %s", self.__name) - def run(self, bwPacket): - print("-- run module:", self.__name) + def addRoute(self, route): + logging.debug("[%s] add route: %s", self.__name, route) + self.__route.append(route) + + def runRouter(self, bwPacket): + logging.debug("[%s] started", self.__name) + for routeCall in self.__route: + logging.debug("[%s] -> run route: %s", self.__name, routeCall) + bwPacket_tmp = routeCall(copy.deepcopy(bwPacket)) # copy bwPacket to prevent edit the original + + if bwPacket_tmp is None: # returning None doesnt change the bwPacket + continue + + if bwPacket_tmp is False: # returning False stops the router immediately + logging.debug("[%s] stopped", self.__name) + break + + bwPacket = bwPacket_tmp + logging.debug("[%s] <- bwPacket returned: %s", self.__name, bwPacket) + logging.debug("[%s] ended", self.__name) return bwPacket + @property + def name(self): + return self.__name -class Plugin: - def __init__(self, name): - self.__name = name - - def run(self, bwPacket): - print("-- run plugin:", self.__name) + @property + def route(self): + return self.__route -class Router: - def __init__(self, name): - self.__name = name - self.__modules = [] - self.__endpoints = [] - self.__bwPacket = None +class RouterManager: + def __init__(self): + self.__routerDict = {} - def addModule(self, module): - if type(module) is Module: - self.__modules.append(module) - else: - print("not a instance of module class:", module) + def __del__(self): + del self.__routerDict + + def buildRouter(self, config): + self.__routerDict = {} # all routers and loaded modules/plugins would be unloaded + logging.debug("build routers") - def addEndpoint(self, endpoint): - if (type(endpoint) is Plugin) or (type(endpoint) is Router): - self.__endpoints.append(endpoint) - else: - print("not a instance of plugin class:", endpoint) + # first we have to init all routers + # because a router can be a valid target and we need his reference + for router in config.get("router"): + self.__routerDict[router.get("name")] = _Router(router.get("name")) + + for router in config.get("router"): + for route in router.get("route"): + + if route.get("type") == "plugin": + importedFile = importlib.import_module(route.get("type") + "." + route.get("name")) + loadedClass = importedFile.BoswatchPlugin(route.get("config")) + self.__routerDict[router.get("name")].addRoute(loadedClass._run) + + elif route.get("type") == "module": + importedFile = importlib.import_module(route.get("type") + "." + route.get("name")) + loadedClass = importedFile.BoswatchModule(route.get("config")) + self.__routerDict[router.get("name")].addRoute(loadedClass._run) + + elif route.get("type") == "router": + self.__routerDict[router.get("name")].addRoute(self.__routerDict[route.get("name")].runRouter) - def call(self, bwPacket): - # bwPacket has to be copied for each router - # make it possible to run more routers parallel - print("call router:", self.__name) - for module in self.__modules: - bwPacket = module.run(bwPacket) - self.__callEndpoints(bwPacket) - print("router finished:", self.__name) + def runRouter(self, routerList, bwPacket): + for router in routerList: + if router in self.__routerDict: + self.__routerDict[router].runRouter(bwPacket) - def __callEndpoints(self, bwPacket): - print("call endpoints:", self.__name) - for endpoint in self.__endpoints: - if type(endpoint) is not Router: - endpoint.run(bwPacket) - else: - print("> endpoint is a new router") - endpoint.call(bwPacket) + def showRouterRoute(self): + for name, router in self.__routerDict.items(): + logging.debug("Route for %s", name) + for route in router.route: + logging.debug("- %s", route) -# module -double = Module("double") -descriptor = Module("descriptor") -# boswatch plugins -telegram = Plugin("telegram") -mysql = Plugin("mysql") - -Router1 = Router("R1") -Router2 = Router("R2") - -# Router 1 module -Router1.addModule(double) -Router1.addModule(descriptor) -Router1.addModule(double) -Router1.addModule(double) -Router1.addModule(descriptor) -# Router 1 endpoints -Router1.addEndpoint(telegram) -Router1.addEndpoint(mysql) -Router1.addEndpoint(Router2) - -# Router 2 module -Router2.addModule(double) -Router2.addModule(descriptor) -# Router 2 endpoints -Router2.addEndpoint(telegram) -Router2.addEndpoint(mysql) - -Router1.call("Test123") diff --git a/config/server.yaml b/config/server.yaml index 1c648ab..c4d9e6c 100644 --- a/config/server.yaml +++ b/config/server.yaml @@ -14,6 +14,7 @@ server: alarmRouter: - Router 1 +- Test router: diff --git a/router_test.py b/router_test.py index ee27200..9b29028 100644 --- a/router_test.py +++ b/router_test.py @@ -1,84 +1,25 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -import logging - from boswatch.configYaml import ConfigYAML from boswatch.packet import Packet - -import importlib -import copy - - -class Router: - def __init__(self, name): - self.__name = name - self.__route = [] - logging.debug("add new router: %s", self.__name) - - def addRoute(self, route): - logging.debug("[%s] add route: %s", self.__name, route) - self.__route.append(route) - - def call(self, bwPacket): - for call in self.__route: - logging.debug("[%s] -> run route: %s", self.__name, call) - bwPacket_tmp = call(copy.deepcopy(bwPacket)) # todo is deepcopy here right? - - if bwPacket_tmp is None: # returning None doesnt change the bwPacket - continue - - if bwPacket is False: # returning False stops the router immediately - logging.debug("[%s] stopped", self.__name) - break - - bwPacket = bwPacket_tmp - logging.debug("[%s] <- route returned: %s", self.__name, bwPacket) - logging.debug("[%s] ended", self.__name) - return bwPacket - - def showRoute(self): - logging.debug("[%s] internal route", self.__name) - for call in self.__route: - logging.debug(" - %s", call) +from boswatch.router import RouterManager config = ConfigYAML() config.loadConfigFile("config/server.yaml") -routerList = {} -for router in config.get("router"): - routerList[router.get("name")] = Router(router.get("name")) - - -for router in config.get("router"): - for route in router.get("route"): - - if route.get("type") == "plugin": - importedFile = importlib.import_module(route.get("type") + "." + route.get("name")) - loadedClass = importedFile.BoswatchPlugin(route.get("config")) - routerList[router.get("name")].addRoute(loadedClass._run) - - elif route.get("type") == "module": - importedFile = importlib.import_module(route.get("type") + "." + route.get("name")) - loadedClass = importedFile.BoswatchModule(route.get("config")) - routerList[router.get("name")].addRoute(loadedClass._run) - - elif route.get("type") == "router": - routerList[router.get("name")].addRoute(routerList[route.get("name")].call) - -print() -print(routerList) -print() - -for router in routerList: - routerList[router].showRoute() - -print() - bwPack = Packet("{'timestamp': 1551421020.9004176, 'mode': 'zvei', 'zvei': '12345'}") -for alaRouter in config.get("alarmRouter"): - routerList[str(alaRouter)].call(bwPack) + +print() + +routMan = RouterManager() + +routMan.buildRouter(config) +print() +routMan.showRouterRoute() +routMan.runRouter(config.get("alarmRouter"), bwPack) -#exit(0) +print() +exit()