aboutsummaryrefslogtreecommitdiffstats
path: root/sdv/core/loader
diff options
context:
space:
mode:
authoropensource-tnbt <sridhar.rao@spirent.com>2020-07-29 17:56:51 +0530
committeropensource-tnbt <sridhar.rao@spirent.com>2020-07-29 18:02:29 +0530
commitd5a010aa2e40cafabf012b096f508b144f9d3d8b (patch)
tree51c734e7c343c5a7dff37b32be1e5a190012c5b0 /sdv/core/loader
parent083133e1e619cb0b8bedb08562260ae2d0774553 (diff)
SDV: First commit.
Moving contents from parent cirv to cirv-sdv Remove pycache Signed-off-by: Sridhar K. N. Rao <sridhar.rao@spirent.com> Change-Id: I3744157eb6616591159abe3eca133160d803dda3
Diffstat (limited to 'sdv/core/loader')
-rw-r--r--sdv/core/loader/__init__.py18
-rw-r--r--sdv/core/loader/loader.py129
-rw-r--r--sdv/core/loader/loader_servant.py183
3 files changed, 330 insertions, 0 deletions
diff --git a/sdv/core/loader/__init__.py b/sdv/core/loader/__init__.py
new file mode 100644
index 0000000..e86c48e
--- /dev/null
+++ b/sdv/core/loader/__init__.py
@@ -0,0 +1,18 @@
+# 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.
+
+"""
+Core: Loader Component.
+"""
+
+# flake8: noqa
+from .loader import Loader
diff --git a/sdv/core/loader/loader.py b/sdv/core/loader/loader.py
new file mode 100644
index 0000000..c9f8e96
--- /dev/null
+++ b/sdv/core/loader/loader.py
@@ -0,0 +1,129 @@
+# Copyright 2020 Intel Corporation, Spirent Communications.
+#
+# 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.
+
+"""
+Abstract class for Software Prevalidations.
+Implementors, please inherit from this class.
+"""
+
+from conf import settings
+from core.loader.loader_servant import LoaderServant
+from SoftwarePreValid.swprevalidator import ISwPreValidator
+from SoftwarePostValid.swpostvalidator import ISwPostValidator
+from NwLinksValid.nwlinksvalidator import INwLinksValidator
+
+
+# pylint: disable=too-many-public-methods
+class Loader():
+ """Loader class - main object context holder.
+ """
+ _swvalidator_loader = None
+
+ def __init__(self):
+ """Loader ctor - initialization method.
+
+ All data is read from configuration each time Loader instance is
+ created. It is up to creator to maintain object life cycle if this
+ behavior is unwanted.
+ """
+ self._swprevalidator_loader = LoaderServant(
+ settings.getValue('SW_PRE_VALID_DIR'),
+ settings.getValue('SW_PRE_VALIDATOR'),
+ ISwPreValidator)
+ self._swpostvalidator_loader = LoaderServant(
+ settings.getValue('SW_POST_VALID_DIR'),
+ settings.getValue('SW_POST_VALIDATOR'),
+ ISwPostValidator)
+ self._nwlinksvalidator_loader = LoaderServant(
+ settings.getValue('NW_LINKS_VALID_DIR'),
+ settings.getValue('NW_LINKS_VALIDATOR'),
+ INwLinksValidator)
+
+ def get_swprevalidator(self):
+ """ Returns a new instance configured Software Validator
+ :return: ISwPreValidator implementation if available, None otherwise
+ """
+ return self._swprevalidator_loader.get_class()()
+
+ def get_swprevalidator_class(self):
+ """Returns type of currently configured Software Validator.
+
+ :return: Type of ISwPreValidator implementation if available.
+ None otherwise.
+ """
+ return self._swprevalidator_loader.get_class()
+
+ def get_swprevalidators(self):
+ """
+ Get Prevalidators
+ """
+ return self._swprevalidator_loader.get_classes()
+
+ def get_swprevalidators_printable(self):
+ """
+ Get Prevalidators for printing
+ """
+ return self._swprevalidator_loader.get_classes_printable()
+
+ def get_swpostvalidator(self):
+ """ Returns a new instance configured Software Validator
+ :return: ISwPostValidator implementation if available, None otherwise
+ """
+ return self._swpostvalidator_loader.get_class()()
+
+ def get_swpostvalidator_class(self):
+ """Returns type of currently configured Software Validator.
+
+ :return: Type of ISwPostValidator implementation if available.
+ None otherwise.
+ """
+ return self._swpostvalidator_loader.get_class()
+
+ def get_swpostvalidators(self):
+ """
+ Get Postvalidators
+ """
+ return self._swpostvalidator_loader.get_classes()
+
+ def get_swpostvalidators_printable(self):
+ """
+ Get Postvalidators for printing
+ """
+ return self._swpostvalidator_loader.get_classes_printable()
+
+ def get_nwlinksvalidator(self):
+ """ Returns a new instance configured Nw-Links Validator
+ :return: INwLinksValidator implementation if available, None otherwise
+ """
+ return self._nwlinksvalidator_loader.get_class()()
+
+ def get_nwlinksvalidator_class(self):
+ """Returns type of currently configured Nw-Links Validator.
+
+ :return: Type of NwLinksValidator implementation if available.
+ None otherwise.
+ """
+ return self._nwlinksvalidator_loader.get_class()
+
+ def get_nwlinkvalidators(self):
+ """
+ Get Linkvalidators
+ """
+ return self._nwlinksvalidator_loader.get_classes()
+
+ def get_nwlinkvalidators_printable(self):
+ """
+ Get Linkvalidators for printing
+ """
+ return self._nwlinksvalidator_loader.get_classes_printable()
diff --git a/sdv/core/loader/loader_servant.py b/sdv/core/loader/loader_servant.py
new file mode 100644
index 0000000..4e55c67
--- /dev/null
+++ b/sdv/core/loader/loader_servant.py
@@ -0,0 +1,183 @@
+# Copyright 2020 Intel Corporation, Spirent Communications.
+#
+# 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.
+
+"""
+Loader Support Module.
+"""
+
+import os
+from os import sys
+import imp
+import fnmatch
+import logging
+from conf import settings
+
+
+class LoaderServant():
+ """Class implements basic dynamic import operations.
+ """
+ _class_name = None
+ _path = None
+ _interface = None
+
+ def __init__(self, path, class_name, interface):
+ """LoaderServant constructor
+
+ Intializes all data needed for import operations.
+
+ Attributes:
+ path: path to directory which contains implementations derived from
+ interface.
+ class_name: Class name which will be returned in get_class
+ method, if such definition exists in directory
+ represented by path,
+ interface: interface type. Every object which doesn't
+ implement this particular interface will be
+ filtered out.
+ """
+ self._class_name = class_name
+ self._path = path
+ self._interface = interface
+
+ def get_class(self):
+ """Returns class type based on parameters passed in __init__.
+
+ :return: Type of the found class.
+ None if class hasn't been found
+ """
+
+ return self.load_module(path=self._path,
+ interface=self._interface,
+ class_name=self._class_name)
+
+ def get_classes(self):
+ """Returns all classes in path derived from interface
+
+ :return: Dictionary with following data:
+ - key: String representing class name,
+ - value: Class type.
+ """
+ return self.load_modules(path=self._path,
+ interface=self._interface)
+
+ def get_classes_printable(self):
+ """Returns all classes derived from _interface found in path
+
+ :return: String - list of classes in printable format.
+ """
+
+ out = self.load_modules(path=self._path,
+ interface=self._interface)
+ results = []
+
+ # sort modules to produce the same output everytime
+ for (name, mod) in sorted(out.items()):
+ desc = (mod.__doc__ or 'No description').strip().split('\n')[0]
+ results.append((name, desc))
+
+ header = 'Classes derived from: ' + self._interface.__name__
+ output = [header + '\n' + '=' * len(header) + '\n']
+
+ for (name, desc) in results:
+ output.append('* %-18s%s' % ('%s:' % name, desc))
+
+ output.append('')
+
+ output.append('')
+
+ return '\n'.join(output)
+
+ @staticmethod
+ def load_module(path, interface, class_name):
+ """Imports everything from given path and returns class type
+
+ This is based on following conditions:
+ - Class is derived from interface,
+ - Class type name matches class_name.
+
+ :return: Type of the found class.
+ None if class hasn't been found
+ """
+
+ results = LoaderServant.load_modules(
+ path=path, interface=interface)
+
+ if class_name in results:
+ logging.info(
+ "Class found: %s.", class_name)
+ return results.get(class_name)
+
+ return None
+
+ @staticmethod
+ def load_modules(path, interface):
+ """Returns dictionary of class name/class type found in path
+
+ This is based on following conditions:
+ - classes found under path are derived from interface.
+ - class is not interface itself.
+
+ :return: Dictionary with following data:
+ - key: String representing class name,
+ - value: Class type.
+ """
+ result = {}
+
+ for _, mod in LoaderServant._load_all_modules(path):
+ # find all classes derived from given interface, but suppress
+ # interface itself and any abstract class starting with iface name
+ gens = dict((k, v) for (k, v) in list(mod.__dict__.items())
+ if isinstance(v, type) and
+ issubclass(v, interface) and
+ not k.startswith(interface.__name__))
+ if gens:
+ for (genname, gen) in list(gens.items()):
+ result[genname] = gen
+ return result
+
+ @staticmethod
+ def _load_all_modules(path):
+ """Load all modules from ``path`` directory.
+
+ This is based on the design used by OFTest:
+ https://github.com/floodlight/oftest/blob/master/oft
+
+ :param path: Path to a folder of modules.
+
+ :return: List of modules in a folder.
+ """
+ mods = []
+
+ for root, _, filenames in os.walk(path):
+ # Iterate over each python file
+ for filename in fnmatch.filter(filenames, '[!.]*.py'):
+ modname = os.path.splitext(os.path.basename(filename))[0]
+
+ # skip module load if it is excluded by configuration
+ if modname in settings.getValue('EXCLUDE_MODULES'):
+ continue
+
+ try:
+ if modname in sys.modules:
+ mod = sys.modules[modname]
+ else:
+ mod = imp.load_module(
+ modname, *imp.find_module(modname, [root]))
+ except ImportError:
+ logging.error('Could not import file %s', filename)
+ raise
+
+ mods.append((modname, mod))
+
+ return mods