def step_impl(context): """ :type context behave.runner.Context """ _namespaces = CumulativeDict() _namespaces.load_dicts(_definition_files=core_language + [os.path.join(script_dir, "../fake_bpm_lib.json")], _top_attribute="namespaces") context.tokens = ProcessTokens(_namespaces = _namespaces) context.verbs = context.tokens.parse(_filename=os.path.join(script_dir, "../source.py"))
def step_impl(context): """ :type context behave.runner.Context """ _namespaces = CumulativeDict() _namespaces.load_dicts(_definition_files=core_language + [os.path.join(script_dir, "../fake_bpm_lib.json")], _top_attribute="namespaces") context.tokens = ProcessTokens(_namespaces=_namespaces) context.verbs = context.tokens.parse( _filename=os.path.join(script_dir, "../source.py"))
def refresh_plugins(self, _plugins_folder): # If < 30 seconds since last refresh (or some other principle) _curr_time = time.time() if self.last_refresh_time - _curr_time > 30: return # Reset unresolved schemas self._unresolved_schemas = {} # Find plugins directory if not os.path.exists(_plugins_folder): raise Exception("Plugin initialisation failed, no plugin directory where expected(" + _plugins_folder + ")") # Manually add the optimal framework ("of") namespace self.namespaces["of"]["schemas"] = [_curr_ref for _curr_ref in self.schema_tools.json_schema_objects.keys()] self.schema_tools.resolver.handlers = {"ref": self.uri_handler} # Loop plugins _plugin_names = os.listdir(_plugins_folder) self.plugins = CumulativeDict() for _plugin_name in _plugin_names: # Only look att non-hidden and non system directories if ( os.path.isdir(os.path.join(_plugins_folder, _plugin_name)) and _plugin_name[0:2] != "__" and _plugin_name[0] != "." ): self.load_plugin(_plugins_folder, _plugin_name) self.write_debug_info("Loaded plugin " + _plugin_name) self.write_debug_info( "Schemas in " + str(", ").join([_curr_plugin["description"] for _curr_plugin in self.plugins.values()]) + " loaded and resolved: " + str.join(", ", ['"' + _curr_schema["title"] + '"' for _curr_schema in self._unresolved_schemas.values()]) ) # Remember refresh self.last_refresh_time = _curr_time
class CherryPyPlugins(object): """ The CherryPyPlugins class is a plugin for CherryPy to handle the Optimal BPM plug-ins """ """List of plugins""" plugins = None """Last refresh""" last_refresh_time = None """ Schema tools instance""" schema_tools = None """Reference to the namespaces""" namespaces = None """The process id (not pid)""" process_id = None """Do not prefix modules with "plugin." for this plugin. This is usually used for testing when the plugin tests are loading the broker.""" no_package_name_override = None def __init__(self, _plugins_folder, _schema_tools, _namespaces, _process_id, _no_package_name_override=None): # TODO: Create a dicts schema self.schema_tools = _schema_tools self.last_refresh_time = -31 self.namespaces = _namespaces self.process_id = _process_id self.no_package_name_override = _no_package_name_override # Add the parent of plugins to sys path sys.path.append(os.path.abspath(os.path.join(_plugins_folder, ".."))) self.refresh_plugins(_plugins_folder) def validate_uuid(self, _value): try: UUID(_value, version=4) return True except: return False def write_debug_info(self, _data): write_to_log(_data=_data, _category=EC_NOTIFICATION, _severity=SEV_DEBUG, _process_id=self.process_id) def call_hook(self, _hook_name, **kwargs): self.write_debug_info("Running hook " + _hook_name) for _curr_plugin_name, _curr_plugin in self.plugins.items(): if "failed" in _curr_plugin and _curr_plugin["failed"]: self.write_debug_info("Plugin " + _curr_plugin_name + " marked failed, will not call its hook.") continue if "hooks_instance" in _curr_plugin: _hooks_instance = _curr_plugin["hooks_instance"] if hasattr(_hooks_instance, _hook_name): try: self.write_debug_info("Calling " + _hook_name + " in " + _curr_plugin["description"]) getattr(_hooks_instance, _hook_name)(**kwargs) except Exception as e: write_to_log( "An error occurred " + "Calling " + _hook_name + " in " + _curr_plugin_name + ":" + str(e), _category=EC_SERVICE, _severity=SEV_ERROR, ) if "failOnError" in _curr_plugin and _curr_plugin["failOnError"]: write_to_log( "Setting " + _curr_plugin_name + " as Failed. No more hooks will be called for this plugin.", _category=EC_SERVICE, _severity=SEV_INFO, ) _curr_plugin["failed"] = True else: write_to_log( "Ignores error, this plugin will continue to attempt initialization.", _category=EC_SERVICE, _severity=SEV_INFO, ) def load_plugin(self, _plugins_dir, _plugin_name): # Load definitions.json _dirname = os.path.join(_plugins_dir, _plugin_name) # TODO: Here any check for licensing should be made to define if a plugin should be loaded. self.write_debug_info("Loading plugin: " + _dirname) try: # A plugin is defince by having a definitions.json-file in its root folder. _definitions_filename = os.path.join(_dirname, "definitions.json") if not os.path.exists(_definitions_filename): raise Exception( "Error loading plugin " + _dirname + ", definition file (" + _definitions_filename + ") missing." ) with open(_definitions_filename) as _f_def: _definitions_data = json.load(_f_def) _plugin_data = _definitions_data["plugins"][_plugin_name] _plugin_data["baseDirectoryName"] = _dirname self.write_debug_info("Loading plugin in " + _plugin_data["description"]) # Add definitions if "namespaces" in _definitions_data: for _curr_namespace in _definitions_data["namespaces"]: self.namespaces[_curr_namespace] self.namespaces.add_cumulatively(_definitions_data["namespaces"]) # Add same resolver for the namespaces (these resolvers will persist throughout the system) self.schema_tools.resolver.handlers.update( {_curr_namespace: self.uri_handler for _curr_namespace in _definitions_data["namespaces"]} ) self.plugins.add_cumulatively(_definitions_data["plugins"]) # Load schemas from /schema _schema_dir = os.path.join(_dirname, "schemas", "namespaces") if os.path.exists(_schema_dir): _refs = self.schema_tools.load_schemas_from_directory(_schema_dir, self._unresolved_schemas) for _curr_schema_key in _refs: _resolved_schema = self.schema_tools.resolveSchema(self._unresolved_schemas[_curr_schema_key]) self.namespaces[urlparse(_curr_schema_key).netloc.split(".")[0]]["schemas"].append(_curr_schema_key) self.schema_tools.json_schema_objects[_curr_schema_key] = _resolved_schema else: self.write_debug_info("No schema folder, not loading schemas.") except Exception as e: write_to_log( "An error occurred importing " + _plugin_name + ":" + str(e), _category=EC_SERVICE, _severity=SEV_ERROR ) write_to_log( "Setting " + _plugin_name + " as Failed. No dependent plugins will be loaded.", _category=EC_SERVICE, _severity=SEV_INFO, ) print("Setting " + _plugin_name + " as Failed. No dependent plugins will be loaded.") _plugin_data = {"failed": True, "description": _plugin_name + "(failed)"} return _plugin_data # Add server side stuff if "hooks_module" in _plugin_data: _hooks_modulename = _plugin_data["hooks_module"] if self.no_package_name_override == _plugin_name: # For testing, the plugin is itself loading its code. _module_ref = ".".join([_plugin_name, _hooks_modulename]) else: _module_ref = ".".join(["plugins", _plugin_name, _hooks_modulename]) try: _module = importlib.import_module(_module_ref) _plugin_data["hooks_instance"] = _module except Exception as e: write_to_log( "An error occurred importing " + _hooks_modulename + " in " + _plugin_data["description"] + ":" + str(e), _category=EC_SERVICE, _severity=SEV_ERROR, ) if "failOnError" in _plugin_data and _plugin_data["failOnError"]: write_to_log( "Setting " + _hooks_modulename + " as Failed. No hooks will be called for this plugin.", _category=EC_SERVICE, _severity=SEV_INFO, ) _plugin_data["failed"] = True else: write_to_log( "Ignores error, the plugin will continue to attempt initialization.", _category=EC_SERVICE, _severity=SEV_INFO, ) return _plugin_data def refresh_plugins(self, _plugins_folder): # If < 30 seconds since last refresh (or some other principle) _curr_time = time.time() if self.last_refresh_time - _curr_time > 30: return # Reset unresolved schemas self._unresolved_schemas = {} # Find plugins directory if not os.path.exists(_plugins_folder): raise Exception("Plugin initialisation failed, no plugin directory where expected(" + _plugins_folder + ")") # Manually add the optimal framework ("of") namespace self.namespaces["of"]["schemas"] = [_curr_ref for _curr_ref in self.schema_tools.json_schema_objects.keys()] self.schema_tools.resolver.handlers = {"ref": self.uri_handler} # Loop plugins _plugin_names = os.listdir(_plugins_folder) self.plugins = CumulativeDict() for _plugin_name in _plugin_names: # Only look att non-hidden and non system directories if ( os.path.isdir(os.path.join(_plugins_folder, _plugin_name)) and _plugin_name[0:2] != "__" and _plugin_name[0] != "." ): self.load_plugin(_plugins_folder, _plugin_name) self.write_debug_info("Loaded plugin " + _plugin_name) self.write_debug_info( "Schemas in " + str(", ").join([_curr_plugin["description"] for _curr_plugin in self.plugins.values()]) + " loaded and resolved: " + str.join(", ", ['"' + _curr_schema["title"] + '"' for _curr_schema in self._unresolved_schemas.values()]) ) # Remember refresh self.last_refresh_time = _curr_time def uri_handler(self, uri): """ Handle all schema references, also for unresolved schemas :param uri: The uri to handle :return: The schema """ if uri in self.schema_tools.json_schema_objects: return self.schema_tools.json_schema_objects[uri] else: return self._unresolved_schemas[uri]