more pep8-friendly
[sfa.git] / sfa / generic / __init__.py
1 from sfa.util.sfalogging import logger
2 from sfa.util.config import Config
3
4 from sfa.managers.managerwrapper import ManagerWrapper
5
6 # a bundle is the combination of
7 # (*) an api that reacts on the incoming requests to trigger the API methods
8 # (*) a manager that implements the function of the service,
9 #     either aggregate, registry, or slicemgr
10 # (*) a driver that controls the underlying testbed
11 #
12 #
13 # The Generic class is a utility that uses the configuration to figure out
14 # which combination of these pieces need to be put together
15 # from config.
16 # this extra indirection is needed to adapt to the current naming scheme
17 # where we have 'pl' and 'plc' and components and the like, that does not
18 # yet follow a sensible scheme
19
20 # needs refinements to cache more efficiently, esp. wrt the config
21
22
23 class Generic:
24
25     def __init__(self, flavour, config):
26         self.flavour = flavour
27         self.config = config
28
29     # proof of concept
30     # example flavour='pl' -> sfa.generic.pl.pl()
31     @staticmethod
32     def the_flavour(flavour=None, config=None):
33         if config is None:
34             config = Config()
35         if flavour is None:
36             flavour = config.SFA_GENERIC_FLAVOUR
37         flavour = flavour.lower()
38         # mixed = flavour.capitalize()
39         module_path = "sfa.generic.%s" % flavour
40         classname = "%s" % flavour
41         logger.debug("Generic.the_flavour with flavour=%s" % flavour)
42         try:
43             module = __import__(module_path, globals(), locals(), [classname])
44             return getattr(module, classname)(flavour, config)
45         except:
46             logger.log_exc(
47                 "Cannot locate generic instance with flavour=%s" % flavour)
48
49     # provide default for importer_class
50     def importer_class(self):
51         return None
52
53     # in the simplest case these can be redefined to the class/module objects to be used
54     # see pl.py for an example
55     # some descendant of SfaApi
56     def api_class(self): pass
57     # the python classes to use to build up the context
58
59     def registry_class(self): pass
60
61     def slicemgr_class(self): pass
62
63     def aggregate_class(self): pass
64
65     def component_class(self): pass
66
67     # build an API object
68     # insert a manager instance
69     def make_api(self, *args, **kwargs):
70         # interface is a required arg
71         if not 'interface' in kwargs:
72             logger.critical("Generic.make_api: no interface found")
73         api = self.api_class()(*args, **kwargs)
74         # xxx can probably drop support for managers implemented as modules
75         # which makes it a bit awkward
76         manager_class_or_module = self.make_manager(api.interface)
77         driver = self.make_driver(api)
78         # arrange stuff together
79         # add a manager wrapper
80         manager_wrap = ManagerWrapper(
81             manager_class_or_module, api.interface, api.config)
82         api.manager = manager_wrap
83         # add it in api as well; driver.api is set too as part of make_driver
84         api.driver = driver
85         return api
86
87     def make_manager(self, interface):
88         """
89         interface expected in ['registry', 'aggregate', 'slicemgr', 'component']
90         flavour is e.g. 'pl' or 'max' or whatever
91         """
92         flavour = self.flavour
93         message = "Generic.make_manager for interface=%s and flavour=%s" % (
94             interface, flavour)
95
96         classname = "%s_manager_class" % interface
97         try:
98             module_or_class = getattr(self, classname)()
99             logger.debug("%s : %s" % (message, module_or_class))
100             # this gets passed to ManagerWrapper that will
101             # call the class constructor if it's a class,
102             # or use the module as is if it's a module
103             # so bottom line is, don't try the constructor here
104             return module_or_class
105         except:
106             logger.log_exc_critical(message)
107
108     # need interface to select the right driver
109     def make_driver(self, api):
110         config = api.config
111         interface = api.interface
112         flavour = self.flavour
113         message = "Generic.make_driver for flavour=%s and interface=%s" % (
114             flavour, interface)
115
116         if interface == "component":
117             classname = "component_driver_class"
118         else:
119             classname = "driver_class"
120         try:
121             class_obj = getattr(self, classname)()
122             logger.debug("%s : %s" % (message, class_obj))
123             return class_obj(api)
124         except:
125             logger.log_exc_critical(message)