blob: 3d3255aaf42e18379d834a21fb6374b98caf0bae [file] [log] [blame]
Matteo Scandolod2044a42017-08-07 16:08:28 -07001
2# Copyright 2017-present Open Networking Foundation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16
Scott Baker1b3b37b2017-02-21 22:53:33 -080017import os
18import inspect
19import imp
20import sys
21import threading
22import time
23from synchronizers.new_base.syncstep import SyncStep
24from synchronizers.new_base.event_loop import XOSObserver
Scott Bakere0cc8322017-05-30 14:38:43 -070025from synchronizers.new_base.model_policy_loop import XOSPolicyEngine
Scott Baker1b3b37b2017-02-21 22:53:33 -080026from synchronizers.new_base.modelaccessor import *
27from xos.logger import Logger, logging
Matteo Scandolo1879ce72017-05-30 15:45:26 -070028from xosconfig import Config
Scott Baker1b3b37b2017-02-21 22:53:33 -080029
Matteo Scandolo1879ce72017-05-30 15:45:26 -070030watchers_enabled = Config.get("enable_watchers")
Scott Baker1b3b37b2017-02-21 22:53:33 -080031
32if (watchers_enabled):
33 from synchronizers.new_base.watchers import XOSWatcher
34
35logger = Logger(level=logging.INFO)
36
37class Backend:
38
39 def __init__(self):
40 pass
41
Scott Baker5ac19602017-06-02 11:02:01 -070042 def load_sync_step_modules(self, step_dir):
Scott Baker1b3b37b2017-02-21 22:53:33 -080043 sync_steps = []
Scott Baker1b3b37b2017-02-21 22:53:33 -080044
45 logger.info("Loading sync steps from %s" % step_dir)
46
47 for fn in os.listdir(step_dir):
48 pathname = os.path.join(step_dir,fn)
49 if os.path.isfile(pathname) and fn.endswith(".py") and (fn!="__init__.py"):
50 module = imp.load_source(fn[:-3],pathname)
51 for classname in dir(module):
52 c = getattr(module, classname, None)
53
54 if classname.startswith("Sync"):
55 print classname, c, inspect.isclass(c), issubclass(c, SyncStep), hasattr(c,"provides")
56
57 # make sure 'c' is a descendent of SyncStep and has a
58 # provides field (this eliminates the abstract base classes
59 # since they don't have a provides)
60
61 if inspect.isclass(c) and issubclass(c, SyncStep) and hasattr(c,"provides") and (c not in sync_steps):
62 sync_steps.append(c)
63
64 logger.info("Loaded %s sync steps" % len(sync_steps))
65
66 return sync_steps
67
68 def run(self):
Scott Baker5ac19602017-06-02 11:02:01 -070069 observer_thread = None
Scott Baker1b3b37b2017-02-21 22:53:33 -080070 watcher_thread = None
71 model_policy_thread = None
72
73 model_accessor.update_diag(sync_start=time.time(), backend_status="0 - Synchronizer Start")
74
Matteo Scandolo1879ce72017-05-30 15:45:26 -070075 steps_dir = Config.get("steps_dir")
Scott Baker5ac19602017-06-02 11:02:01 -070076 if steps_dir:
77 sync_steps = self.load_sync_step_modules(steps_dir)
78 if sync_steps:
79 # start the observer
80 observer = XOSObserver(sync_steps)
81 observer_thread = threading.Thread(target=observer.run,name='synchronizer')
82 observer_thread.start()
Scott Baker1b3b37b2017-02-21 22:53:33 -080083
Scott Baker5ac19602017-06-02 11:02:01 -070084 # start the watcher thread
85 if (watchers_enabled):
86 watcher = XOSWatcher(sync_steps)
87 watcher_thread = threading.Thread(target=watcher.run,name='watcher')
88 watcher_thread.start()
89 else:
90 logger.info("Skipping observer and watcher threads due to no steps dir.")
Scott Baker1b3b37b2017-02-21 22:53:33 -080091
Scott Bakerbae9d842017-03-21 10:44:10 -070092 # start model policies thread
Matteo Scandolo1879ce72017-05-30 15:45:26 -070093 policies_dir = Config.get("model_policies_dir")
Scott Bakerbae9d842017-03-21 10:44:10 -070094 if policies_dir:
Scott Bakere0cc8322017-05-30 14:38:43 -070095 policy_engine = XOSPolicyEngine(policies_dir=policies_dir)
96 model_policy_thread = threading.Thread(target=policy_engine.run, name="policy_engine")
Scott Bakerbae9d842017-03-21 10:44:10 -070097 model_policy_thread.start()
98 else:
Scott Bakerbae9d842017-03-21 10:44:10 -070099 logger.info("Skipping model policies thread due to no model_policies dir.")
100
Scott Baker1b3b37b2017-02-21 22:53:33 -0800101 while True:
102 try:
103 time.sleep(1000)
104 except KeyboardInterrupt:
105 print "exiting due to keyboard interrupt"
106 # TODO: See about setting the threads as daemons
Scott Baker5ac19602017-06-02 11:02:01 -0700107 if observer_thread:
108 observer_thread._Thread__stop()
Scott Baker1b3b37b2017-02-21 22:53:33 -0800109 if watcher_thread:
110 watcher_thread._Thread__stop()
111 if model_policy_thread:
112 model_policy_thread._Thread__stop()
113 sys.exit(1)
114