Initial commit
[ta/config-manager.git] / cmframework / src / cmframework / server / cmactivateserverhandler.py
diff --git a/cmframework/src/cmframework/server/cmactivateserverhandler.py b/cmframework/src/cmframework/server/cmactivateserverhandler.py
new file mode 100644 (file)
index 0000000..d6122d7
--- /dev/null
@@ -0,0 +1,129 @@
+# Copyright 2019 Nokia
+
+# 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.
+import logging
+import time
+
+from cmframework.utils import cmpluginmanager
+from cmframework.utils import cmpluginloader
+from cmframework.utils import cmactivationwork
+
+from cmframework.apis import cmactivator
+from cmframework.server import cmactivatehandler
+
+
+class CMActivateServerHandler(cmactivatehandler.CMActivateHandler,
+                              cmpluginmanager.CMPluginManager,
+                              cmpluginloader.CMPluginLoader.LoadingFilter):
+
+    def __init__(self, plugins_path, plugin_client, changemonitor, activationstate_handler):
+        cmpluginmanager.CMPluginManager.__init__(self, plugins_path)
+        self.load_plugin()
+        self.plugin_client = plugin_client
+        self.changemonitor = changemonitor
+        self.activationstate_handler = activationstate_handler
+
+    def is_supported(self, activator_plugin):
+        logging.debug('Checking %s', activator_plugin)
+        return isinstance(activator_plugin, cmactivator.CMGlobalActivator)
+
+    def load_plugin(self):
+        plugin_filter = self
+        pl = cmpluginloader.CMPluginLoader(self.plugins_path, plugin_filter)
+        self.pluginlist, self.filterdict = pl.load()
+        logging.info('pluginlist is %r', self.pluginlist)
+
+    def activate_set(self, indata):
+        return self._activate(indata, 'activate_set')
+
+    def activate_delete(self, indata):
+        return self._activate(indata, 'activate_delete')
+
+    def activate_full(self, target_node, startup_activation=False):
+        return self._activate(target_node, 'activate_full', startup_activation)
+
+    def activate_node(self, target_node):
+        return self._activate(target_node, 'activate_full')
+
+    def _activate(self, indata, operation, startup_activation=False):
+        logging.info('%s called with %s', operation, indata)
+        failures = {}
+        for plugin, objectname in self.pluginlist.iteritems():
+            logging.info('Running plugin %s.%s', plugin, operation)
+            func = None
+            try:
+                class_name = getattr(objectname, plugin)
+                instance = class_name()
+                instance.plugin_client = self.plugin_client
+                func = getattr(instance, operation)
+                if operation != 'activate_full':
+                    filtername = self.filterdict[plugin]
+                    inputdata = self.build_input(indata, filtername)
+
+                    if not inputdata:
+                        logging.info('Skipping plugin %s as no input data is to be processed by it',
+                                     plugin)
+                        continue
+
+                    start_time = time.time()
+                    func(inputdata)
+                    logging.info('Plugin %s.%s took %s seconds', plugin, operation,
+                                 time.time() - start_time)
+                else:
+                    if startup_activation:
+                        if plugin not in self.activationstate_handler.get_full_failed():
+                            logging.info('Skipping plugin %s during startup as '
+                                         'it has not failed in last activation', plugin)
+                            continue
+
+                    start_time = time.time()
+                    func(indata)
+                    logging.info('Plugin %s.%s took %s seconds', plugin, operation,
+                                 time.time() - start_time)
+            except AttributeError as exp:
+                logging.info('Plugin %s does not have %s defined', plugin, operation)
+                logging.info(str(exp))
+                failures[str(plugin)] = 'Plugin does not have {} defined'.format(operation)
+                continue
+            except Exception as exp:  # pylint: disable=broad-except
+                failures[str(plugin)] = str(exp)
+                logging.error('Skipping %s, got exception %s', plugin, str(exp))
+                failures[str(plugin)] = str(exp)
+                continue
+
+        logging.info('%s done with %s', operation, indata)
+
+        return failures
+
+    def activate(self, work):
+        logging.debug('CMAcivateServerHandler activating %s', work)
+        failures = {}
+        if work.get_operation() == cmactivationwork.CMActivationWork.OPER_SET:
+            failures = self.activate_set(work.get_props())
+        elif work.get_operation() == cmactivationwork.CMActivationWork.OPER_DELETE:
+            failures = self.activate_delete(work.get_props())
+        elif work.get_operation() == cmactivationwork.CMActivationWork.OPER_FULL:
+            startup_activation = work.is_startup_activation()
+            failures = self.activate_full(work.get_target(), startup_activation)
+        elif work.get_operation() == cmactivationwork.CMActivationWork.OPER_NODE:
+            failures = self.activate_node(work.get_target())
+        else:
+            logging.error('Unsupported activation operation %s', work.get_operation())
+
+        if work.uuid_value:
+            if failures:
+                self.changemonitor.change_nok(work.uuid_value, failures)
+            else:
+                self.changemonitor.change_ok(work.uuid_value)
+
+        return failures