Test d’un service utilisant une base de données.
This commit is contained in:
parent
8c91e01a2b
commit
dcaf7da3bc
11
README.md
11
README.md
|
@ -18,3 +18,14 @@ echo "127.0.0.1 auth.example.com manager.example.com test1.example.com test2.exa
|
||||||
docker run -d --add-host reload.example.com:127.0.0.1 -p 80:80 coudot/lemonldap-ng
|
docker run -d --add-host reload.example.com:127.0.0.1 -p 80:80 coudot/lemonldap-ng
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Démarrer un serveur postgresql de test
|
||||||
|
```
|
||||||
|
podman pull docker.io/library/postgres:11-alpine
|
||||||
|
podman run -dt -p 5432:5432 postgres:11-alpine
|
||||||
|
|
||||||
|
psql -U postgres -h localhost -c "CREATE ROLE risotto WITH LOGIN PASSWORD 'risotto';"
|
||||||
|
psql -U postgres -h localhost -c "CREATE DATABASE risotto;"
|
||||||
|
psql -U postgres -h localhost -c "GRANT ALL ON DATABASE risotto TO risotto;"
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
uri: servermodel.init
|
||||||
|
|
||||||
|
description: |
|
||||||
|
Initialise la table pour les modèles de serveur.
|
||||||
|
|
||||||
|
sampleuse: |
|
||||||
|
zephir-client servermodel.init
|
||||||
|
|
||||||
|
pattern: rpc
|
||||||
|
|
||||||
|
public: true
|
||||||
|
|
||||||
|
domain: servermodel-domain
|
||||||
|
|
||||||
|
response:
|
||||||
|
type: ReturnStatus
|
||||||
|
description: Liste des modèles de serveur disponibles.
|
||||||
|
|
||||||
|
errors:
|
||||||
|
- uri: servermodel.list.error.database_engine_not_available
|
||||||
|
|
||||||
|
related:
|
||||||
|
- servermodel.describe
|
||||||
|
- servermodel.create
|
||||||
|
- servermodel.update
|
||||||
|
- servermodel.delete
|
||||||
|
- servermodel.event
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
title: ReturnStatus
|
||||||
|
type: object
|
||||||
|
description: Résultat d’une commande.
|
||||||
|
properties:
|
||||||
|
retcode:
|
||||||
|
type: number
|
||||||
|
description: Code de retour de la commande.
|
||||||
|
return:
|
||||||
|
type: string
|
||||||
|
description: Retour de la commande.
|
||||||
|
required:
|
||||||
|
- retcode
|
||||||
|
- return
|
|
@ -1,21 +0,0 @@
|
||||||
import psycopg2
|
|
||||||
|
|
||||||
KEY_DATABASE_NAME = 'dbname'
|
|
||||||
KEY_DATABASE_USER = 'user'
|
|
||||||
KEY_DATABASE_PASSWORD = 'password'
|
|
||||||
KEY_DATABASE_HOST = 'host'
|
|
||||||
|
|
||||||
|
|
||||||
def connect(conf, database_options=None):
|
|
||||||
if database_options is None:
|
|
||||||
option = conf.option['database']
|
|
||||||
database_options = {
|
|
||||||
'host': option[KEY_DATABASE_HOST],
|
|
||||||
'dbname': option[KEY_DATABASE_NAME],
|
|
||||||
'user': option[KEY_DATABASE_USER],
|
|
||||||
'password': option[KEY_DATABASE_PASSWORD]
|
|
||||||
|
|
||||||
}
|
|
||||||
if not database_options['host']:
|
|
||||||
raise Exception('cannot find postgresql')
|
|
||||||
return psycopg2.connect(**database_options)
|
|
|
@ -10,9 +10,8 @@ from .config import DEBUG
|
||||||
from .config import get_config
|
from .config import get_config
|
||||||
from .context import Context
|
from .context import Context
|
||||||
from . import register
|
from . import register
|
||||||
|
import asyncpg
|
||||||
|
|
||||||
def connect(db_conf):
|
|
||||||
return psycopg2.connect(**db_conf)
|
|
||||||
|
|
||||||
class CallDispatcher:
|
class CallDispatcher:
|
||||||
def valid_public_function(self,
|
def valid_public_function(self,
|
||||||
|
@ -38,6 +37,7 @@ class CallDispatcher:
|
||||||
raise CallError(str(err))
|
raise CallError(str(err))
|
||||||
else:
|
else:
|
||||||
if not isinstance(returns, dict):
|
if not isinstance(returns, dict):
|
||||||
|
log.error_msg(risotto_context, kwargs, returns)
|
||||||
err = _(f'function {module_name}.{function_name} has to return a dict')
|
err = _(f'function {module_name}.{function_name} has to return a dict')
|
||||||
log.error_msg(risotto_context, kwargs, err)
|
log.error_msg(risotto_context, kwargs, err)
|
||||||
raise CallError(str(err))
|
raise CallError(str(err))
|
||||||
|
@ -97,10 +97,15 @@ class CallDispatcher:
|
||||||
risotto_context.function = obj['function']
|
risotto_context.function = obj['function']
|
||||||
if obj['risotto_context']:
|
if obj['risotto_context']:
|
||||||
kw['risotto_context'] = risotto_context
|
kw['risotto_context'] = risotto_context
|
||||||
if obj['database']:
|
if 'database' in obj and obj['database']:
|
||||||
db_conf = get_config.get('database')
|
db_conf = get_config().get('database')
|
||||||
risotto_context.db_cursor = await connect(db_conf).cursor()
|
pool = await asyncpg.create_pool(database=db_conf.get('dbname'), user=db_conf.get('user'))
|
||||||
returns = await risotto_context.function(self.injected_self[obj['module']], **kw)
|
async with pool.acquire() as connection:
|
||||||
|
risotto_context.connection = connection
|
||||||
|
async with connection.transaction():
|
||||||
|
returns = await risotto_context.function(self.injected_self[obj['module']], **kw)
|
||||||
|
else:
|
||||||
|
returns = await risotto_context.function(self.injected_self[obj['module']], **kw)
|
||||||
except CallError as err:
|
except CallError as err:
|
||||||
raise err
|
raise err
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
|
|
|
@ -9,7 +9,8 @@ from .config import INTERNAL_USER
|
||||||
|
|
||||||
|
|
||||||
def register(uris: str,
|
def register(uris: str,
|
||||||
notification: str=undefined):
|
notification: str=undefined,
|
||||||
|
database: bool=False):
|
||||||
""" Decorator to register function to the dispatcher
|
""" Decorator to register function to the dispatcher
|
||||||
"""
|
"""
|
||||||
if not isinstance(uris, list):
|
if not isinstance(uris, list):
|
||||||
|
@ -21,6 +22,7 @@ def register(uris: str,
|
||||||
dispatcher.set_function(version,
|
dispatcher.set_function(version,
|
||||||
message,
|
message,
|
||||||
notification,
|
notification,
|
||||||
|
database,
|
||||||
function)
|
function)
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
|
@ -129,6 +131,7 @@ class RegisterDispatcher:
|
||||||
version: str,
|
version: str,
|
||||||
message: str,
|
message: str,
|
||||||
notification: str,
|
notification: str,
|
||||||
|
database: bool,
|
||||||
function: Callable):
|
function: Callable):
|
||||||
""" register a function to an URI
|
""" register a function to an URI
|
||||||
URI is a message
|
URI is a message
|
||||||
|
@ -180,6 +183,7 @@ class RegisterDispatcher:
|
||||||
function,
|
function,
|
||||||
function_args,
|
function_args,
|
||||||
inject_risotto_context,
|
inject_risotto_context,
|
||||||
|
database,
|
||||||
notification)
|
notification)
|
||||||
|
|
||||||
def register_rpc(self,
|
def register_rpc(self,
|
||||||
|
@ -189,11 +193,13 @@ class RegisterDispatcher:
|
||||||
function: Callable,
|
function: Callable,
|
||||||
function_args: list,
|
function_args: list,
|
||||||
inject_risotto_context: bool,
|
inject_risotto_context: bool,
|
||||||
|
database: bool,
|
||||||
notification: Optional[str]):
|
notification: Optional[str]):
|
||||||
self.messages[version][message]['module'] = module_name
|
self.messages[version][message]['module'] = module_name
|
||||||
self.messages[version][message]['function'] = function
|
self.messages[version][message]['function'] = function
|
||||||
self.messages[version][message]['arguments'] = function_args
|
self.messages[version][message]['arguments'] = function_args
|
||||||
self.messages[version][message]['risotto_context'] = inject_risotto_context
|
self.messages[version][message]['risotto_context'] = inject_risotto_context
|
||||||
|
self.messages[version][message]['database'] = database
|
||||||
if notification:
|
if notification:
|
||||||
self.messages[version][message]['notification'] = notification
|
self.messages[version][message]['notification'] = notification
|
||||||
|
|
||||||
|
@ -204,6 +210,7 @@ class RegisterDispatcher:
|
||||||
function: Callable,
|
function: Callable,
|
||||||
function_args: list,
|
function_args: list,
|
||||||
inject_risotto_context: bool,
|
inject_risotto_context: bool,
|
||||||
|
database: bool,
|
||||||
notification: Optional[str]):
|
notification: Optional[str]):
|
||||||
if 'functions' not in self.messages[version][message]:
|
if 'functions' not in self.messages[version][message]:
|
||||||
self.messages[version][message]['functions'] = []
|
self.messages[version][message]['functions'] = []
|
||||||
|
|
|
@ -1,14 +1,35 @@
|
||||||
from ...controller import Controller
|
from ...controller import Controller
|
||||||
from ...register import register
|
from ...register import register
|
||||||
|
|
||||||
|
sql_init = """
|
||||||
|
-- Création de la table ServerModel
|
||||||
|
CREATE TABLE ServerModel (
|
||||||
|
ServerModelId SERIAL PRIMARY KEY,
|
||||||
|
ServerModelName VARCHAR(255) NOT NULL,
|
||||||
|
ServerModelDescription VARCHAR(255) NOT NULL,
|
||||||
|
ServerModelSourceId INTEGER NOT NULL,
|
||||||
|
ServerModelParentId INTEGER,
|
||||||
|
ServerModelSubReleaseId INTEGER NOT NULL,
|
||||||
|
ServerModelSubReleaseName VARCHAR(255) NOT NULL,
|
||||||
|
UNIQUE (ServerModelName, ServerModelSubReleaseId)
|
||||||
|
);
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class Risotto(Controller):
|
class Risotto(Controller):
|
||||||
@register('v1.servermodel.list', None)
|
@register('v1.servermodel.init', None, database=True)
|
||||||
async def servermodel_list(self, sourceid):
|
async def servermodel_init(self, risotto_context):
|
||||||
return [{'servermodelid': 1,
|
result = await risotto_context.connection.execute(sql_init)
|
||||||
'servermodelname': 'name',
|
return {'retcode': 0, 'return': result}
|
||||||
'subreleasename': 'name',
|
|
||||||
'sourceid': 1,
|
|
||||||
'servermodeldescription': 'description'}]
|
@register('v1.servermodel.list', None, database=True)
|
||||||
|
async def servermodel_list(self, risotto_context, sourceid):
|
||||||
|
sql = '''
|
||||||
|
SELECT * FROM ServerModel
|
||||||
|
'''
|
||||||
|
servermodels = await risotto_context.connection.fetch(sql)
|
||||||
|
return [dict(r) for r in servermodels]
|
||||||
|
|
||||||
@register('v1.servermodel.describe', None)
|
@register('v1.servermodel.describe', None)
|
||||||
async def servermodel_describe(self, inheritance, creolefuncs, servermodelid, schema, conffiles, resolvdepends, probes):
|
async def servermodel_describe(self, inheritance, creolefuncs, servermodelid, schema, conffiles, resolvdepends, probes):
|
||||||
|
|
Loading…
Reference in New Issue