From 1d25d3a58213a777b5736abaf6045a3044b237e9 Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Thu, 26 Dec 2019 11:38:31 +0100 Subject: [PATCH] tiramisu is now async --- src/risotto/dispatcher.py | 57 +++--- src/risotto/http.py | 9 +- src/risotto/message/message.py | 10 +- src/risotto/register.py | 79 ++++---- src/risotto/services/config/config.py | 228 ++++++++++++------------ src/risotto/services/session/session.py | 44 ++--- src/risotto/services/session/storage.py | 44 ++--- 7 files changed, 241 insertions(+), 230 deletions(-) diff --git a/src/risotto/dispatcher.py b/src/risotto/dispatcher.py index e32ba2a..3414015 100644 --- a/src/risotto/dispatcher.py +++ b/src/risotto/dispatcher.py @@ -24,10 +24,10 @@ class CallDispatcher: log.error_msg(risotto_context, kwargs, msg) raise NotAllowedError(msg) - def valid_call_returns(self, - risotto_context: Context, - returns: Dict, - kwargs: Dict): + async def valid_call_returns(self, + risotto_context: Context, + returns: Dict, + kwargs: Dict): response = self.messages[risotto_context.version][risotto_context.message]['response'] module_name = risotto_context.function.__module__.split('.')[-2] function_name = risotto_context.function.__name__ @@ -47,11 +47,12 @@ class CallDispatcher: raise Exception('hu?') else: for ret in returns: - config = Config(response, display_name=lambda self, dyn_name: self.impl_getname()) - config.property.read_write() + config = await Config(response, + display_name=lambda self, dyn_name: self.impl_getname()) + await config.property.read_write() try: for key, value in ret.items(): - config.option(key).value.set(value) + await config.option(key).value.set(value) except AttributeError: err = _(f'function {module_name}.{function_name} return the unknown parameter "{key}"') log.error_msg(risotto_context, kwargs, err) @@ -60,13 +61,13 @@ class CallDispatcher: err = _(f'function {module_name}.{function_name} return the parameter "{key}" with an unvalid value "{value}"') log.error_msg(risotto_context, kwargs, err) raise CallError(str(err)) - config.property.read_only() - mandatories = list(config.value.mandatory()) + await config.property.read_only() + mandatories = await config.value.mandatory() if mandatories: mand = [mand.split('.')[-1] for mand in mandatories] raise ValueError(_(f'missing parameters in response: {mand} in message "{risotto_context.message}"')) try: - config.value.dict() + await config.value.dict() except Exception as err: err = _(f'function {module_name}.{function_name} return an invalid response {err}') log.error_msg(risotto_context, kwargs, err) @@ -91,10 +92,10 @@ class CallDispatcher: self.check_message_type(risotto_context, kwargs) try: - tiramisu_config = self.load_kwargs_to_config(risotto_context, - kwargs) + tiramisu_config = await self.load_kwargs_to_config(risotto_context, + kwargs) function_obj = self.messages[version][message] - kw = tiramisu_config.option(message).value.dict() + kw = await tiramisu_config.option(message).value.dict() risotto_context.function = function_obj['function'] if function_obj['risotto_context']: kw['risotto_context'] = risotto_context @@ -126,9 +127,9 @@ class CallDispatcher: err) raise CallError(str(err)) # valid returns - self.valid_call_returns(risotto_context, - returns, - kwargs) + await self.valid_call_returns(risotto_context, + returns, + kwargs) # log the success log.info_msg(risotto_context, kwargs, @@ -157,9 +158,9 @@ class PublishDispatcher: self.check_message_type(risotto_context, kwargs) try: - config = self.load_kwargs_to_config(risotto_context, - kwargs) - config_arguments = config.option(message).value.dict() + config = await self.load_kwargs_to_config(risotto_context, + kwargs) + config_arguments = await config.option(message).value.dict() except CallError as err: return except Exception as err: @@ -247,28 +248,28 @@ class Dispatcher(register.RegisterDispatcher, CallDispatcher, PublishDispatcher) log.error_msg(risotto_context, kwargs, msg) raise CallError(msg) - def load_kwargs_to_config(self, - risotto_context: Context, - kwargs: Dict): + async def load_kwargs_to_config(self, + risotto_context: Context, + kwargs: Dict): """ create a new Config et set values to it """ # create a new config - config = Config(self.option) - config.property.read_write() + config = await Config(self.option) + await config.property.read_write() # set message's option - config.option('message').value.set(risotto_context.message) + await config.option('message').value.set(risotto_context.message) # store values subconfig = config.option(risotto_context.message) for key, value in kwargs.items(): try: - subconfig.option(key).value.set(value) + await subconfig.option(key).value.set(value) except AttributeError: if DEBUG: print_exc() raise ValueError(_(f'unknown parameter "{key}"')) # check mandatories options - config.property.read_only() - mandatories = list(config.value.mandatory()) + await config.property.read_only() + mandatories = await config.value.mandatory() if mandatories: mand = [mand.split('.')[-1] for mand in mandatories] raise ValueError(_(f'missing parameters: {mand}')) diff --git a/src/risotto/http.py b/src/risotto/http.py index 14e3e49..c7a5b54 100644 --- a/src/risotto/http.py +++ b/src/risotto/http.py @@ -89,10 +89,10 @@ async def handle(request): async def api(request, risotto_context): global tiramisu if not tiramisu: - config = Config(get_messages(load_shortarg=True, - only_public=True)[1]) - config.property.read_write() - tiramisu = config.option.dict(remotable='none') + config = await Config(get_messages(load_shortarg=True, + only_public=True)[1]) + await config.property.read_write() + tiramisu = await config.option.dict(remotable='none') return tiramisu @@ -107,6 +107,7 @@ async def get_app(loop): load_services() app = Application(loop=loop) routes = [] + await dispatcher.load() for version, messages in dispatcher.messages.items(): print() print(_('======== Registered messages ========')) diff --git a/src/risotto/message/message.py b/src/risotto/message/message.py index 20b8d3b..6e523bb 100644 --- a/src/risotto/message/message.py +++ b/src/risotto/message/message.py @@ -3,7 +3,7 @@ from os.path import join, basename, dirname from glob import glob from tiramisu import StrOption, IntOption, BoolOption, ChoiceOption, OptionDescription, SymLinkOption, \ - Config, Calculation, Params, ParamOption, ParamValue, calc_value, calc_value_property_help, \ + Calculation, Params, ParamOption, ParamValue, calc_value, calc_value_property_help, \ groups, Option from yaml import load, SafeLoader @@ -616,12 +616,4 @@ def get_messages(load_shortarg=False, only_public=False): load_shortarg) root = _get_root_option(select_option, optiondescriptions) - try: - config = Config(root) - except Exception as err: - raise Exception('error when generating root optiondescription: {}'.format(err)) - - config.property.read_write() - # config.property.add('demoting_error_warning') - # return needs, responses, config return optiondescriptions_info, root diff --git a/src/risotto/register.py b/src/risotto/register.py index be4758b..582136d 100644 --- a/src/risotto/register.py +++ b/src/risotto/register.py @@ -1,6 +1,7 @@ from tiramisu import Config from inspect import signature from typing import Callable, Optional + from .utils import undefined, _ from .error import RegistrationError from .message import get_messages @@ -47,22 +48,22 @@ class RegisterDispatcher: first_argument_index = 1 return [param.name for param in list(signature(function).parameters.values())[first_argument_index:]] - def valid_rpc_params(self, - version: str, - message: str, - function: Callable, - module_name: str): + async def valid_rpc_params(self, + version: str, + message: str, + function: Callable, + module_name: str): """ parameters function must have strictly all arguments with the correct name """ - def get_message_args(): + async def get_message_args(): # load config - config = Config(self.option) - config.property.read_write() + config = await Config(self.option) + await config.property.read_write() # set message to the uri name - config.option('message').value.set(message) + await config.option('message').value.set(message) # get message argument - subconfig = config.option(message) - return set(config.option(message).value.dict().keys()) + dico = await config.option(message).value.dict() + return set(dico.keys()) def get_function_args(): function_args = self.get_function_args(function) @@ -72,7 +73,7 @@ class RegisterDispatcher: return set(function_args) # get message arguments - message_args = get_message_args() + message_args = await get_message_args() # get function arguments function_args = get_function_args() # compare message arguments with function parameter @@ -90,22 +91,22 @@ class RegisterDispatcher: msg = _(' and ').join(msg) raise RegistrationError(_(f'error with {module_name}.{function_name} arguments: {msg}')) - def valid_event_params(self, - version: str, - message: str, - function: Callable, - module_name: str): + async def valid_event_params(self, + version: str, + message: str, + function: Callable, + module_name: str): """ parameters function validation for event messages """ - def get_message_args(): + async def get_message_args(): # load config - config = Config(self.option) - config.property.read_write() + config = await Config(self.option) + await config.property.read_write() # set message to the message name - config.option('message').value.set(message) + await config.option('message').value.set(message) # get message argument - subconfig = config.option(message) - return set(config.option(message).value.dict().keys()) + dico = await config.option(message).value.dict() + return set(dico.keys()) def get_function_args(): function_args = self.get_function_args(function) @@ -115,7 +116,7 @@ class RegisterDispatcher: return set(function_args) # get message arguments - message_args = get_message_args() + message_args = await get_message_args() # get function arguments function_args = get_function_args() # compare message arguments with function parameter @@ -159,18 +160,11 @@ class RegisterDispatcher: if 'function' in self.messages[version][message]: raise RegistrationError(_(f'uri {version}.{message} already registered')) - # valid function's arguments + # check notification if self.messages[version][message]['pattern'] == 'rpc': if notification is undefined: function_name = function.__name__ raise RegistrationError(_(f'notification is mandatory when registered "{message}" with "{module_name}.{function_name}" even if you set None')) - valid_params = self.valid_rpc_params - else: - valid_params = self.valid_event_params - valid_params(version, - message, - function, - module_name) # register if self.messages[version][message]['pattern'] == 'rpc': @@ -253,3 +247,24 @@ class RegisterDispatcher: risotto_context.paths.append(f'{module_name}.on_join') risotto_context.type = None await module.on_join(risotto_context) + + async def load(self): + # valid function's arguments + for version, messages in self.messages.items(): + for message, message_infos in messages.items(): + if message_infos['pattern'] == 'rpc': + module_name = message_infos['module'] + function = message_infos['function'] + await self.valid_rpc_params(version, + message, + function, + module_name) + else: + if 'functions' in message_infos: + for function_infos in message_infos['functions']: + module_name = function_infos['module'] + function = function_infos['function'] + await self.valid_event_params(version, + message, + function, + module_name) diff --git a/src/risotto/services/config/config.py b/src/risotto/services/config/config.py index aa13575..3033396 100644 --- a/src/risotto/services/config/config.py +++ b/src/risotto/services/config/config.py @@ -59,10 +59,10 @@ class Risotto(Controller): for servermodel in servermodels: if 'servermodel_parents_id' in servermodel: for servermodelparentid in servermodel['servermodel_parents_id']: - self.servermodel_legacy(risotto_context, - servermodel['servermodel_name'], - servermodel['servermodel_id'], - servermodelparentid) + await self.servermodel_legacy(risotto_context, + servermodel['servermodel_name'], + servermodel['servermodel_id'], + servermodelparentid) def get_funcs_filename(self, servermodel_id: int): @@ -104,16 +104,16 @@ class Risotto(Controller): # # loads tiramisu config and store it with open(cache_file) as fileio: xmlroot = parse(fileio).getroot() - self.servermodel[servermodel_id] = self.build_metaconfig(servermodel_id, - servermodel_name, - xmlroot, - funcs_file) + self.servermodel[servermodel_id] = await self.build_metaconfig(servermodel_id, + servermodel_name, + xmlroot, + funcs_file) - def build_metaconfig(self, - servermodel_id: int, - servermodel_name: str, - xmlroot: str, - funcs_file: str) -> MetaConfig: + async def build_metaconfig(self, + servermodel_id: int, + servermodel_name: str, + xmlroot: str, + funcs_file: str) -> MetaConfig: """ Build metaconfig for a servermodel """ # build tiramisu's session ID @@ -123,44 +123,44 @@ class Risotto(Controller): funcs_file) # build servermodel metaconfig (v_xxx.m_v_xxx) - metaconfig = MetaConfig([], - optiondescription=optiondescription, - persistent=True, - session_id=session_id, - storage=self.save_storage) - mixconfig = MixConfig(children=[], - optiondescription=optiondescription, - persistent=True, - session_id='m_' + session_id, - storage=self.save_storage) - metaconfig.config.add(mixconfig) + metaconfig = await MetaConfig([], + optiondescription=optiondescription, + persistent=True, + session_id=session_id, + storage=self.save_storage) + mixconfig = await MixConfig(children=[], + optiondescription=optiondescription, + persistent=True, + session_id='m_' + session_id, + storage=self.save_storage) + await metaconfig.config.add(mixconfig) # change default rights - ro_origin = metaconfig.property.getdefault('read_only', 'append') + ro_origin = await metaconfig.property.getdefault('read_only', 'append') ro_append = frozenset(ro_origin - {'force_store_value'}) - rw_origin = metaconfig.property.getdefault('read_write', 'append') + rw_origin = await metaconfig.property.getdefault('read_write', 'append') rw_append = frozenset(rw_origin - {'force_store_value'}) - metaconfig.property.setdefault(ro_append, 'read_only', 'append') - metaconfig.property.setdefault(rw_append, 'read_write', 'append') + await metaconfig.property.setdefault(ro_append, 'read_only', 'append') + await metaconfig.property.setdefault(rw_append, 'read_write', 'append') - metaconfig.property.read_only() - metaconfig.permissive.add('basic') - metaconfig.permissive.add('normal') - metaconfig.permissive.add('expert') + await metaconfig.property.read_only() + await metaconfig.permissive.add('basic') + await metaconfig.permissive.add('normal') + await metaconfig.permissive.add('expert') # set informtion and owner - metaconfig.owner.set('v_{}'.format(servermodel_name)) - metaconfig.information.set('servermodel_id', servermodel_id) - metaconfig.information.set('servermodel_name', servermodel_name) + await metaconfig.owner.set('v_{}'.format(servermodel_name)) + await metaconfig.information.set('servermodel_id', servermodel_id) + await metaconfig.information.set('servermodel_name', servermodel_name) # return configuration return metaconfig - def servermodel_legacy(self, - risotto_context: Context, - servermodel_name: str, - servermodel_id: int, - servermodel_parent_id: int) -> None: + async def servermodel_legacy(self, + risotto_context: Context, + servermodel_name: str, + servermodel_id: int, + servermodel_parent_id: int) -> None: """ Make link between parent and children """ if servermodel_parent_id is None: @@ -173,7 +173,7 @@ class Risotto(Controller): msg) return servermodel_parent = self.servermodel[servermodel_parent_id] - servermodel_parent_name = servermodel_parent.information.get('servermodel_name') + servermodel_parent_name = await servermodel_parent.information.get('servermodel_name') if DEBUG: msg = _(f'Create legacy of servermodel {servermodel_name} ({servermodel_id}) with parent {servermodel_parent_name} ({servermodel_parent_id})') log.info_msg(risotto_context, @@ -181,9 +181,9 @@ class Risotto(Controller): msg) # do link - mix = servermodel_parent.config.get('m_v_' + str(servermodel_parent_id)) + mix = await servermodel_parent.config.get('m_v_' + str(servermodel_parent_id)) try: - mix.config.add(self.servermodel[servermodel_id]) + await mix.config.add(self.servermodel[servermodel_id]) except Exception as err: if DEBUG: log.error_msg(risotto_context, @@ -203,10 +203,10 @@ class Risotto(Controller): # loads servers for server in servers: try: - self.load_server(risotto_context, - server['server_id'], - server['server_name'], - server['server_servermodel_id']) + await self.load_server(risotto_context, + server['server_id'], + server['server_name'], + server['server_servermodel_id']) except Exception as err: if DEBUG: print_exc() @@ -217,11 +217,11 @@ class Risotto(Controller): None, msg) - def load_server(self, - risotto_context: Context, - server_id: int, - server_name: str, - server_servermodel_id: int) -> None: + async def load_server(self, + risotto_context: Context, + server_id: int, + server_name: str, + server_servermodel_id: int) -> None: """ Loads a server """ if server_id in self.server: @@ -243,30 +243,30 @@ class Risotto(Controller): metaconfig = self.servermodel[server_servermodel_id] # create server configuration and server 'to deploy' configuration and store it - self.server[server_id] = {'server': self.build_config(session_id, - server_id, - server_name, - metaconfig), - 'server_to_deploy': self.build_config(f'std_{server_id}', - server_id, - server_name, - metaconfig), + self.server[server_id] = {'server': await self.build_config(session_id, + server_id, + server_name, + metaconfig), + 'server_to_deploy': await self.build_config(f'std_{server_id}', + server_id, + server_name, + metaconfig), 'funcs_file': self.get_funcs_filename(server_servermodel_id)} - def build_config(self, - session_id: str, - server_id: int, - server_name: str, - metaconfig: MetaConfig) -> None: + async def build_config(self, + session_id: str, + server_id: int, + server_name: str, + metaconfig: MetaConfig) -> None: """ build server's config """ - config = metaconfig.config.new(session_id, - storage=self.save_storage, - persistent=True) - config.information.set('server_id', server_id) - config.information.set('server_name', server_name) - config.owner.set(server_name) - config.property.read_only() + config = await metaconfig.config.new(session_id, + storage=self.save_storage, + persistent=True) + await config.information.set('server_id', server_id) + await config.information.set('server_name', server_name) + await config.owner.set(server_name) + await config.property.read_only() return config @register('v1.server.created') @@ -277,10 +277,10 @@ class Risotto(Controller): server_servermodel_id: int) -> None: """ Loads server's configuration when a new server is created """ - self.load_server(risotto_context, - server_id, - server_name, - server_servermodel_id) + await self.load_server(risotto_context, + server_id, + server_name, + server_servermodel_id) @register('v1.server.deleted') async def server_deleted(self, @@ -288,10 +288,10 @@ class Risotto(Controller): # delete config to it's parents for server_type in ['server', 'server_to_deploy']: config = self.server[server_id]['server'] - for parent in config.config.parents(): - parent.config.pop(config.config.name()) + for parent in await config.config.parents(): + await parent.config.pop(config.config.name()) delete_session(storage=self.save_storage, - session_id=config.config.name()) + session_id=await config.config.name()) # delete metaconfig del self.server[server_id] @@ -319,27 +319,27 @@ class Risotto(Controller): servermodel_name) if servermodel_parents_id is not None: for servermodelparentid in servermodel_parents_id: - self.servermodel_legacy(risotto_context, - servermodel_name, - servermodel_id, - servermodelparentid) + await self.servermodel_legacy(risotto_context, + servermodel_name, + servermodel_id, + servermodelparentid) - def servermodel_delete(self, - servermodel_id: int) -> List[MetaConfig]: + async def servermodel_delete(self, + servermodel_id: int) -> List[MetaConfig]: metaconfig = self.servermodel.pop(servermodel_id) - mixconfig = next(metaconfig.config.list()) + mixconfig = await metaconfig.config.list()[0] children = [] - for child in mixconfig.config.list(): + for child in await mixconfig.config.list(): children.append(child) - mixconfig.config.pop(child.config.name()) - metaconfig.config.pop(mixconfig.config.name()) + await mixconfig.config.pop(await child.config.name()) + await metaconfig.config.pop(await mixconfig.config.name()) delete_session(storage=self.save_storage, - session_id=mixconfig.config.name()) + session_id=await mixconfig.config.name()) del mixconfig - for parent in metaconfig.config.parents(): - parent.config.pop(metaconfig.config.name()) + for parent in await metaconfig.config.parents(): + await parent.config.pop(await metaconfig.config.name()) delete_session(storage=self.save_storage, - session_id=metaconfig.config.name()) + session_id=await metaconfig.config.name()) return children @register('v1.servermodel.updated') @@ -358,10 +358,10 @@ class Risotto(Controller): # store all informations if servermodel_id in self.servermodel: - old_values = self.servermodel[servermodel_id].value.exportation() - old_permissives = self.servermodel[servermodel_id].permissive.exportation() - old_properties = self.servermodel[servermodel_id].property.exportation() - children = self.servermodel_delete(servermodel_id) + old_values = await self.servermodel[servermodel_id].value.exportation() + old_permissives = await self.servermodel[servermodel_id].permissive.exportation() + old_properties = await self.servermodel[servermodel_id].property.exportation() + children = await self.servermodel_delete(servermodel_id) else: old_values = None @@ -373,14 +373,14 @@ class Risotto(Controller): # migrates informations if old_values is not None: - self.servermodel[servermodel_id].value.importation(old_values) - self.servermodel[servermodel_id].permissive.importation(old_permissives) - self.servermodel[servermodel_id].property.importation(old_properties) + await self.servermodel[servermodel_id].value.importation(old_values) + await self.servermodel[servermodel_id].permissive.importation(old_permissives) + await self.servermodel[servermodel_id].property.importation(old_properties) for child in children: - self.servermodel_legacy(risotto_context, - child.information.get('servermodel_name'), - child.information.get('servermodel_id'), - servermodel_id) + await self.servermodel_legacy(risotto_context, + await child.information.get('servermodel_name'), + await child.information.get('servermodel_id'), + servermodel_id) @register('v1.config.configuration.server.get', None) async def get_configuration(self, @@ -398,9 +398,9 @@ class Risotto(Controller): else: server = self.server[server_id]['server_to_deploy'] - server.property.read_only() + await server.property.read_only() try: - configuration = server.value.dict(fullpath=True) + configuration = await server.value.dict(fullpath=True) except: if deployed: msg = _(f'No configuration available for server {server_id}') @@ -423,19 +423,19 @@ class Risotto(Controller): config_std = self.server[server_id]['server_to_deploy'] # when deploy, calculate force_store_value - ro = config_std.property.getdefault('read_only', 'append') + ro = await config_std.property.getdefault('read_only', 'append') if 'force_store_value' not in ro: ro = frozenset(list(ro) + ['force_store_value']) - config_std.property.setdefault(ro, 'read_only', 'append') - rw = config_std.property.getdefault('read_write', 'append') + await config_std.property.setdefault(ro, 'read_only', 'append') + rw = await config_std.property.getdefault('read_write', 'append') rw = frozenset(list(rw) + ['force_store_value']) - config_std.property.setdefault(rw, 'read_write', 'append') - config_std.property.add('force_store_value') + await config_std.property.setdefault(rw, 'read_write', 'append') + await config_std.property.add('force_store_value') # copy informations from server 'to deploy' configuration to server configuration - config.value.importation(config_std.value.exportation()) - config.permissive.importation(config_std.permissive.exportation()) - config.property.importation(config_std.property.exportation()) + await config.value.importation(await config_std.value.exportation()) + await config.permissive.importation(await config_std.permissive.exportation()) + await config.property.importation(await config_std.property.exportation()) return {'server_id': server_id, 'deployed': True} diff --git a/src/risotto/services/session/session.py b/src/risotto/services/session/session.py index 3494422..8233fc4 100644 --- a/src/risotto/services/session/session.py +++ b/src/risotto/services/session/session.py @@ -98,11 +98,11 @@ class Risotto(Controller): session_id = 'z' + hexlify(urandom(23)).decode() if not session_id in sessions: break - storage.add_session(session_id, - config, - id, - risotto_context.username, - self.modify_storage) + await storage.add_session(session_id, + config, + id, + risotto_context.username, + self.modify_storage) # return session's information return self.get_session_informations(risotto_context, @@ -135,11 +135,11 @@ class Risotto(Controller): if mode is not None: if mode not in ('basic', 'normal', 'expert'): raise Exception(f'unknown mode {mode}') - storage.set_config_mode(session_id, - mode) + await storage.set_config_mode(session_id, + mode) if debug is not None: - storage.set_config_debug(session_id, - debug) + await storage.set_config_debug(session_id, + debug) return self.get_session_informations(risotto_context, session_id, type) @@ -160,7 +160,7 @@ class Risotto(Controller): # if multi and not follower the value is in fact in value_multi # FIXME option = session['option'].option(name).option option = session['config'].option(name).option - if option.ismulti() and not option.isfollower(): + if await option.ismulti() and not await option.isfollower(): value = value_multi #FIXME namespace = session['namespace'] #FIXME update = {'name': f'{namespace}.{name}', @@ -170,7 +170,7 @@ class Risotto(Controller): if index is not None: update['index'] = index updates = {'updates': [update]} - ret = session['option'].updates(updates) + ret = await session['option'].updates(updates) if update['name'] in ret: for val in ret[update['name']][index]: if isinstance(val, ValueError): @@ -190,14 +190,14 @@ class Risotto(Controller): session_id, type) try: - session['config'].forcepermissive.option(session['namespace']).value.dict() + await session['config'].forcepermissive.option(session['namespace']).value.dict() except Exception as err: raise Exception(str(err)) if type == 'server': config = session['config'] - config.property.read_only() - mandatories = list(config.value.mandatory()) - config.property.read_write() + await config.property.read_only() + mandatories = list(await config.value.mandatory()) + await config.property.read_write() if mandatories: # FIXME mandatories = [mandatory.split('.', 1)[1] for mandatory in mandatories] if len(mandatories) == 1: @@ -221,9 +221,11 @@ class Risotto(Controller): type) info = self.format_session(session_id, session) if name is not None: - info['content'] = {name: session['option'].option(name).value.get()} + content = {name: await session['option'].option(name).value.get()} else: - info['content'] = session['option'].value.dict(fullpath=True) + content = await session['option'].value.dict(fullpath=True, + leader_to_list=True) + info['content'] = content return info @register(['v1.session.server.stop', 'v1.session.servermodel.stop'], None) @@ -243,8 +245,8 @@ class Risotto(Controller): config = config_module.servermodel[id_] if save: modif_config = session['config'] - config.value.importation(modif_config.value.exportation()) - config.permissive.importation(modif_config.permissive.exportation()) + await config.value.importation(await modif_config.value.exportation()) + await config.permissive.importation(await modif_config.permissive.exportation()) storage.del_session(session_id) return self.format_session(session_id, session) @@ -255,7 +257,7 @@ class Risotto(Controller): session_id: str) -> Dict: session = storage_server.get_session(session_id, risotto_context.username) - return session['option'].dict(remotable='all') + return await session['option'].dict(remotable='all') @register_http('v1', '/config/servermodel/{session_id}') async def get_servermodel_api(self, @@ -264,4 +266,4 @@ class Risotto(Controller): session_id: str) -> Dict: session = storage_servermodel.get_session(session_id, risotto_context.username) - return session['option'].dict(remotable='all') + return await session['option'].dict(remotable='all') diff --git a/src/risotto/services/session/storage.py b/src/risotto/services/session/storage.py index eaef165..9e2854c 100644 --- a/src/risotto/services/session/storage.py +++ b/src/risotto/services/session/storage.py @@ -15,26 +15,26 @@ class Storage(object): def __init__(self): self.sessions = {} - def add_session(self, - session_id: int, - orig_config: Config, - server_id: int, - username: str, - config_storage): + async def add_session(self, + session_id: int, + orig_config: Config, + server_id: int, + username: str, + config_storage): prefix_id = f'{session_id}_' config_name = self.get_config_name(server_id) config_id = f'{prefix_id}{config_name}' # copy Config and all it's parents - meta = orig_config.config.deepcopy(session_id=config_id, - storage=config_storage, - metaconfig_prefix=prefix_id) + meta = await orig_config.config.deepcopy(session_id=config_id, + storage=config_storage, + metaconfig_prefix=prefix_id) # retrieve the copied config (not metaconfig) config = meta while True: try: - children = list(config.config.list()) + children = list(await config.config.list()) if not children: # it's an empty metaconfig break @@ -42,7 +42,7 @@ class Storage(object): except: # it's a config, so no "list" method break - config.property.read_write() + await config.property.read_write() # set the default owner self.set_owner(config, username) @@ -54,34 +54,34 @@ class Storage(object): 'id': server_id, 'timestamp': int(time.time()), 'username': username} - self.set_config_mode(session_id, + await self.set_config_mode(session_id, 'normal') - self.set_config_debug(session_id, - False) + await self.set_config_debug(session_id, + False) self.set_namespace(session_id, 'creole') - def set_config_mode(self, - id: int, - mode: str): + async def set_config_mode(self, + id: int, + mode: str): """ Define which edition mode to select """ config = self.sessions[id]['config'] for mode_level in modes.values(): if modes[mode] < mode_level: - config.property.add(mode_level.name) + await config.property.add(mode_level.name) else: - config.property.pop(mode_level.name) + await config.property.pop(mode_level.name) self.sessions[id]['mode'] = mode - def set_config_debug(self, id_, is_debug): + async def set_config_debug(self, id_, is_debug): """ Enable/Disable debug mode """ config = self.sessions[id_]['config'] if is_debug: - config.property.pop('hidden') + await config.property.pop('hidden') else: - config.property.add('hidden') + await config.property.add('hidden') self.sessions[id_]['debug'] = is_debug def set_namespace(self,