From f7a97cf575f9d241ff3a77f010fe3d0cf9de2e48 Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Thu, 19 Dec 2019 12:25:16 +0100 Subject: [PATCH] source>release>applicationservice>servermodel --- .../v1/messages/applicationservice.create.yml | 2 +- .../applicationservice.dataset.updated.yml | 10 +-- .../messages/applicationservice.get_by_id.yml | 36 ++++++++++ .../v1/messages/source.release.create.yml | 7 +- messages/v1/types/applicationservice.yml | 10 ++- messages/v1/types/release.yml | 4 ++ script/database_manager.py | 5 +- .../applicationservice/applicationservice.py | 40 +++++++++-- .../services/servermodel/servermodel.py | 71 +++++++++---------- src/risotto/services/source/source.py | 25 ++++--- 10 files changed, 146 insertions(+), 64 deletions(-) create mode 100644 messages/v1/messages/applicationservice.get_by_id.yml diff --git a/messages/v1/messages/applicationservice.create.yml b/messages/v1/messages/applicationservice.create.yml index 5bbb56c..295a651 100644 --- a/messages/v1/messages/applicationservice.create.yml +++ b/messages/v1/messages/applicationservice.create.yml @@ -27,7 +27,7 @@ parameters: response: type: ApplicationService - description: Informations sur le modèle de serveur créé. + description: Informations sur le service applicatif créé. errors: - uri: servermodel.create.error.database_not_available diff --git a/messages/v1/messages/applicationservice.dataset.updated.yml b/messages/v1/messages/applicationservice.dataset.updated.yml index dc0cfba..c5dc68f 100644 --- a/messages/v1/messages/applicationservice.dataset.updated.yml +++ b/messages/v1/messages/applicationservice.dataset.updated.yml @@ -1,21 +1,21 @@ uri: applicationservice.dataset.updated description: | - Initialise la table pour les services applicatifs. + Les services applicatifs sont mis à jour. pattern: rpc public: true parameters: - release_path: + source_name: type: String shortarg: s description: Nom de la source. - release_id: - type: Number + release_distribution: + type: String shortarg: r - description: Nom de la version. + description: Distribution de la source. response: type: ReturnStatus diff --git a/messages/v1/messages/applicationservice.get_by_id.yml b/messages/v1/messages/applicationservice.get_by_id.yml new file mode 100644 index 0000000..e079b2c --- /dev/null +++ b/messages/v1/messages/applicationservice.get_by_id.yml @@ -0,0 +1,36 @@ +--- +uri: applicationservice.get_by_id + +description: | + Retourne un service applicatif suivant l'identifiant. + +pattern: rpc + +public: true + +parameters: + applicationservice_id: + type: Number + shortarg: i + description: | + ID du service applicatif à créer. + +response: + type: ApplicationService + description: Informations sur le service applicatif créé. + +errors: + - uri: servermodel.create.error.database_not_available + - uri: servermodel.create.error.duplicate_servermodel + - uri: servermodel.create.error.invalid_parentservermodel_id + - uri: servermodel.create.error.invalid_source_id + - uri: servermodel.create.error.unknown_parentservermodel_id + - uri: servermodel.create.error.unknown_source_id + - uri: servermodel.create.error.servermodelname_not_provided + +related: + - servermodel.list + - servermodel.describe + - servermodel.update + - servermodel.delete + - servermodel.event diff --git a/messages/v1/messages/source.release.create.yml b/messages/v1/messages/source.release.create.yml index c7db7d4..082532a 100644 --- a/messages/v1/messages/source.release.create.yml +++ b/messages/v1/messages/source.release.create.yml @@ -6,7 +6,7 @@ description: | pattern: rpc -public: false +public: true parameters: source_id: @@ -18,6 +18,11 @@ parameters: shortarg: n description: | Nom de la version. + release_distribution: + type: String + shortarg: d + description: | + Distribution de la version. response: type: 'Release' diff --git a/messages/v1/types/applicationservice.yml b/messages/v1/types/applicationservice.yml index 3bf3dbe..2322c67 100644 --- a/messages/v1/types/applicationservice.yml +++ b/messages/v1/types/applicationservice.yml @@ -12,7 +12,7 @@ properties: applicationservice_description: type: string description: Description du service applicatif. - release_id: + applicationservice_release_id: type: number ref: Version.ReleaseId description: Version du service applicatif. @@ -23,8 +23,6 @@ properties: description: Liste des services applicatifs déclarés en dépendance de ce service applicatif. required: - - servermodelid - - servermodelname - - servermodeldescription - - servermodelsubreleaseid - - subreleasename + - applicationservice_id + - applicationservice_name + - applicationservice_release_id diff --git a/messages/v1/types/release.yml b/messages/v1/types/release.yml index 2c3171d..5bda9bd 100644 --- a/messages/v1/types/release.yml +++ b/messages/v1/types/release.yml @@ -9,6 +9,9 @@ properties: release_name: type: string description: Le nom de la version. + release_distribution: + type: string + description: Le nom de la distribution de la version. source_url: type: string description: URL de la source. @@ -19,6 +22,7 @@ properties: required: - release_id - release_name + - release_distribution - source_name - source_url diff --git a/script/database_manager.py b/script/database_manager.py index 4d63f3d..1d64bf7 100644 --- a/script/database_manager.py +++ b/script/database_manager.py @@ -84,4 +84,7 @@ async def main(): async with connection.transaction(): returns = await connection.execute(VERSION_INIT) -asyncio.run(main()) +if __name__ == '__main__': + loop = asyncio.get_event_loop() + loop.run_until_complete(main()) + # asyncio.run(main()) diff --git a/src/risotto/services/applicationservice/applicationservice.py b/src/risotto/services/applicationservice/applicationservice.py index 9b91f01..ebc632f 100644 --- a/src/risotto/services/applicationservice/applicationservice.py +++ b/src/risotto/services/applicationservice/applicationservice.py @@ -12,6 +12,9 @@ from ...context import Context from ...utils import _ class Risotto(Controller): + def __init__(self): + self.source_root_path = get_config().get('source').get('root_path') + async def _applicationservice_create(self, risotto_context: Context, applicationservice_name: str, @@ -26,6 +29,7 @@ class Risotto(Controller): release_id) return {'applicationservice_name': applicationservice_name, 'applicationservice_description': applicationservice_description, + 'applicationservice_release_id': release_id, 'applicationservice_id': applicationservice_id} @register('v1.applicationservice.create', None, database=True) @@ -41,10 +45,21 @@ class Risotto(Controller): @register('v1.applicationservice.dataset.updated', None, database=True) async def applicationservice_update(self, - risotto_context, - release_path: str, - release_id: int) -> Dict: - applicationservice_path = join(release_path, 'applicationservice') + risotto_context: Context, + source_name: str, + release_distribution: str) -> Dict: + source = await self.call('v1.source.describe', + risotto_context, + source_name=source_name) + release = await self.call('v1.source.release.get_by_distribution', + risotto_context, + source_id=source['source_id'], + release_distribution=release_distribution) + applicationservice_path = join(self.source_root_path, + source_name, + release['release_name'], + 'applicationservice') + release_id = release['release_id'] for service in listdir(applicationservice_path): try: applicationservice_description_path = join(applicationservice_path, @@ -68,3 +83,20 @@ class Risotto(Controller): raise ExecutionError(_(f"Error while injecting application service {applicationservice_description['name']} in database: {err}")) return {'retcode': 0, 'returns': _('Application Services successfully loaded')} + + @register('v1.applicationservice.get_by_id', None, database=True) + async def applicationservice_get_by_id(self, + risotto_context: Context, + applicationservice_id: int) -> Dict: + applicationservice_query = """ + SELECT ApplicationServiceId as applicationservice_id, ApplicationServiceName as applicationservice_name, ApplicationServiceDependencies as applicationservice_dependencies, ApplicationServiceReleaseId as applicationservice_release_id + FROM applicationservice + WHERE applicationserviceid=$1""" + applicationservice = await risotto_context.connection.fetchrow(applicationservice_query, + applicationservice_id) + if applicationservice is None: + raise Exception(_(f'unknown service with ID {applicationservice_id}')) + applicationservice = dict(applicationservice) + if applicationservice['applicationservice_dependencies'] is None: + applicationservice['applicationservice_dependencies'] = [] + return applicationservice diff --git a/src/risotto/services/servermodel/servermodel.py b/src/risotto/services/servermodel/servermodel.py index a311936..ef6c1f5 100644 --- a/src/risotto/services/servermodel/servermodel.py +++ b/src/risotto/services/servermodel/servermodel.py @@ -29,13 +29,15 @@ class Risotto(Controller): internal_release = await self.call('v1.source.release.create', risotto_context, source_id=internal_source['source_id'], - release_name='none') + release_name='none', + release_distribution='stable') self.internal_release_id = internal_release['release_id'] async def servermodel_gen_schema(self, risotto_context: Context, servermodel_id: int, - applicationservice_id: int) -> None: + applicationservice_id: int, + release_cache: Dict) -> None: dependencies = await self.get_applicationservices(risotto_context, applicationservice_id) if release_cache is None: @@ -45,10 +47,11 @@ class Risotto(Controller): applicationservice_name, as_release_id = applicationservice_infos if as_release_id not in release_cache: release_cache[as_release_id] = await self.call('v1.source.release.get_by_id', + risotto_context, release_id=as_release_id) dict_paths.append(join(self.source_root_path, release_cache[as_release_id]['source_name'], - release_cache[as_release_id]['release_distribution'], + release_cache[as_release_id]['release_name'], 'applicationservice', applicationservice_name, 'dictionaries')) @@ -85,9 +88,10 @@ class Risotto(Controller): servermodel_parents_id, release_id, applicationservice_id) - self.servermodel_gen_schema(risotto_context, - servermodel_id, - applicationservice_id) + await self.servermodel_gen_schema(risotto_context, + servermodel_id, + applicationservice_id, + release_cache) return {'servermodel_name': servermodel_name, 'servermodel_description': servermodel_description, 'servermodel_parents_id': servermodel_parents_id, @@ -120,12 +124,6 @@ class Risotto(Controller): risotto_context: Context, source_name: str, release_distribution: int): - servermodel_path = join(self.source_root_path, - source_name, - release_distribution, - 'servermodel') - servermodels = {} - # for dependencies reason load all servermodels source = await self.call('v1.source.describe', risotto_context, source_name=source_name) @@ -134,6 +132,11 @@ class Risotto(Controller): source_id=source['source_id'], release_distribution=release_distribution) release_id = release['release_id'] + servermodel_path = join(self.source_root_path, + source_name, + release['release_name'], + 'servermodel') + servermodels = {} for servermodel in listdir(servermodel_path): if not servermodel.endswith('.yml'): continue @@ -195,30 +198,26 @@ class Risotto(Controller): return [dict(r) for r in servermodels] async def _parse_depends(self, - risotto_context, - applicationservice_id: int, - or_depends: list, - ids: list) -> None: - applicationservice_query = """ - SELECT ApplicationServiceName, ApplicationServiceDependencies, ApplicationServiceReleaseId - FROM applicationservice - WHERE applicationserviceid=$1""" - applicationservice = await risotto_context.connection.fetchval(servermodel_update, - applicationservice_id) - ids[applicationservice_id] = (applicationserverice['ApplicationServiceName'], - applicationserverice['ApplicationServiceReleaseId']) - if applicationserverice['ApplicationServiceDependencies']: - for depend in pplicationserverice['ApplicationServiceDependencies']: - if isinstance(depend, dict): - or_depends.append(depend['or']) - elif depend not in ids: - await self._parse_depends(risotto_context, - depend, - or_depends, - ids) + risotto_context: Context, + applicationservice_id: int, + or_depends: list, + ids: list) -> None: + applicationservice = await self.call('v1.applicationservice.get_by_id', + risotto_context, + applicationservice_id=applicationservice_id) + ids[applicationservice_id] = (applicationservice['applicationservice_name'], + applicationservice['applicationservice_release_id']) + for depend in applicationservice['applicationservice_dependencies']: + if isinstance(depend, dict): + or_depends.append(depend['or']) + elif depend not in ids: + await self._parse_depends(risotto_context, + depend, + or_depends, + ids) async def _parse_or_depends(self, - risotto_context, + risotto_context: Context, or_depends: list, ids: list) -> None: new_or_depends = [] @@ -236,12 +235,12 @@ class Risotto(Controller): ids) async def get_applicationservices(self, - risotto_context, + risotto_context: Context, applicationservice_id: int) -> list: """Return consolidated dependencies or raise. """ or_depends = [] - ids = [] + ids = {} await self._parse_depends(risotto_context, applicationservice_id, or_depends, diff --git a/src/risotto/services/source/source.py b/src/risotto/services/source/source.py index bf050c9..d00f3db 100644 --- a/src/risotto/services/source/source.py +++ b/src/risotto/services/source/source.py @@ -54,7 +54,7 @@ class Risotto(Controller): source = await risotto_context.connection.fetchrow(source_get, source_name) if not source: - raise Exception(f'unknown source with name {source_name}') + raise Exception(_(f'unknown source with name {source_name}')) return dict(source) @register('v1.source.list', None, database=True) @@ -85,12 +85,13 @@ class Risotto(Controller): async def source_release_create(self, risotto_context: Context, source_id: int, - release_name: str) -> Dict: + release_name: str, + release_distribution: str) -> Dict: source_get = """SELECT SourceId as source_id, SourceName as source_name, SourceURL as source_url FROM Source WHERE SourceId = $1 """ - release_upsert = """INSERT INTO Release(ReleaseName, ReleaseSourceId) VALUES ($1, $2) + release_upsert = """INSERT INTO Release(ReleaseName, ReleaseSourceId, ReleaseDistribution) VALUES ($1, $2, $3) ON CONFLICT (ReleaseName, ReleaseSourceId) DO UPDATE SET ReleaseName = $1 RETURNING ReleaseId """ @@ -98,16 +99,18 @@ class Risotto(Controller): source_id)) release_id = await risotto_context.connection.fetchval(release_upsert, release_name, - source_id) + source_id, + release_distribution) del source['source_id'] source['release_id'] = release_id source['release_name'] = release_name + source['release_distribution'] = release_distribution return source @register('v1.source.release.list', None, database=True) async def release_list(self, risotto_context): - release_query = """SELECT ReleaseId as release_id, SourceName as source_name, SourceURL as source_url, ReleaseName as release_name + release_query = """SELECT ReleaseId as release_id, SourceName as source_name, SourceURL as source_url, ReleaseName as release_name, ReleaseDistribution as release_distribution FROM Release, Source WHERE Source.SourceId=Release.ReleaseSourceId""" result = await risotto_context.connection.fetch(release_query) @@ -117,11 +120,13 @@ class Risotto(Controller): async def release_get_by_id(self, risotto_context: Context, release_id: int) -> Dict: - release_query = """SELECT ReleaseId as release_id, SourceName as source_name, SourceURL as source_url, ReleaseName as release_name + release_query = """SELECT ReleaseId as release_id, SourceName as source_name, SourceURL as source_url, ReleaseName as release_name, ReleaseDistribution as release_distribution FROM Release, Source - WHERE Release.ReleaseId = $1""" + WHERE Release.ReleaseId = $1 AND Source.SourceId = Release.ReleaseSourceId""" result = await risotto_context.connection.fetchrow(release_query, release_id) + if not result: + raise Exception(_(f'unknown release id {release_id}')) return dict(result) @register('v1.source.release.get_by_distribution', None, database=True) @@ -129,12 +134,12 @@ class Risotto(Controller): risotto_context: Context, source_id: int, release_distribution: str) -> Dict: - release_query = """SELECT ReleaseId as release_id, SourceName as source_name, SourceURL as source_url, ReleaseName as release_name + release_query = """SELECT ReleaseId as release_id, SourceName as source_name, SourceURL as source_url, ReleaseName as release_name, ReleaseDistribution as release_distribution FROM Release, Source - WHERE Source.SourceId = $1 AND Release.ReleaseName = $2""" + WHERE Release.ReleaseSourceId = $1 AND Release.ReleaseDistribution = $2 AND Source.SourceId = Release.ReleaseSourceId""" result = await risotto_context.connection.fetchrow(release_query, source_id, release_distribution) if not result: - raise Exception(f'unknown distribution {release_distribution} with source {source_id}') + raise Exception(_(f'unknown distribution {release_distribution} with source {source_id}')) return dict(result)