Commit 2274c818 authored by François Agneray's avatar François Agneray
Browse files

#21 => done

parent ecde6a2d
# ANIS V3 SERVER
# Anis Server
## Introduction
AstroNomical Information System est un outil web générique qui vise à faciliter
la mise à disposition de données (Astrophysiques), accessible depuis
une base de données, à une communauté de scientifiques.
AstroNomical Information System is a generic web tool that aims to facilitate the provision of data (Astrophysics), accessible from a database, for the scientific community.
ANIS-V3-SERVER est un composant de ANIS-V3 qui permet de piloter une ou plusieurs
bases de données liées à des projets en astronomie uniquement via des URLS.
Anis server is a software that allows you to control one or more databases related to astronomical projects and allows access to datasets via URLs.
ANIS permet de rechercher et visualiser des données à partir de formulaires de
recherche générés automatiquement par l'application. Le scientifique à la
possibilité de visualiser ces données sous la forme d'un tableau HTML interactif,
il à également la possibilité de visualiser des données issues d'images
astronomiques, de spectres ou de fichier FITS.
This software is protected by the `CeCILL` licence (see LICENCE file at the software root).
## Auteurs
## Authors
* `François Agneray` : Laboratoire d'Astrophysique de Marseille (CNRS)
* `Chrystel Moreau` : Laboratoire d'Astrophysique de Marseille (CNRS)
# Guide d'installation
# Installation guide
## Dépendances
## Make commandes
Cette application requiert les dépendances suivantes pour fonctionner:
The `Makefile` at the root of the project provides a list of commands available to manage the application.
To see the list of commands:
> make
## Software dependencies: introduction
This application requires the following dependencies to work:
"slim/slim": "^3.8",
"doctrine/orm": "^2.5"
......@@ -32,64 +33,47 @@ Cette application requiert les dépendances suivantes pour fonctionner:
"lcobucci/jwt": "^3.2",
"swiftmailer/swiftmailer": "^6.0"
Ces dépendances sont installées via le logiciel `composer.phar` et le fichier de
configuration `composer.json` disponible à la racine de l'application.
## Dépendances : installation
These dependencies are installed with software `composer.phar` and the configuration files `composer.json` and `composer.lock` available at the root of the application.
Pour lancer l'installation des dépendances, il faut utiliser la commande suivante
à la racine du projet ANIS :
## Software dependencies: installation
> php composer.phar install
To start installing dependancies, use the following command at the software root:
`Composer.phar` va utiliser automatique le fichier `composer.json` pour télécharger
les dépendances et les placer dans le dossier `vendor` à la racine du projet.
> make install
## Base de données metamodel : création de la base
`Composer.phar` will automatically use the `composer.json` file to download all the dependancies and save them to the `vendor` directory at the root of the application.
Une instance ANIS nécessite une base de données de `metamodel` pour fonctionner.
Commencer par créer une base de données vierge avec un utilisateur en mode lecture
écriture pouvant s'y connecter.
## Build Anis server software
## Base de données metamodel : fichier de configuration
Anis server has been developed to be used with docker containers. If you open the docker-compose.yml file you can see all containers needed for the "development configuration" of anis server.
La configuration pour la connexion à la base de données `metamodel` se trouve dans
le fichier `settings.php` dans le dossier `app` du projet.
`Makefile` provides a command to build an install all the containers that you need for create a fresh installation of Anis server software:
Le fichier `settings.php` contient un tableau de clé => valeur. Les options de
connexion se trouvent dnas la partie settings => metadata => connection_options.
> make up
Mettez les options de connexion correspondant à la base de données `metamodel`
vierge préalablement créée.
## Start Anis server
## Base de données metamodel: génération des tables
After the creation of containers you are now ready to start them:
Pour générer les tables de la la base de données `metamodel` qui correspondent aux
fichier `Entity` (voir la doc `Doctrine2` pour plus d'information), il faut utiliser
l'utilitaire en ligne de commande fournit par `Doctrine 2` disponible dans le dossier `vendor` :
> ./vendor/bin/doctrine
Doctrine 2 permet de valider le schéma qui correpond aux fichiers `entity` :
> make start
> ./vendor/bin/doctrine orm:validate-schema
## Metamodel database installation
Si le schéma est valide, Doctrine 2 permet de générer automatiquement la base de données :
Anis server need a database to save the metadata information about business databases, projects and datasets availables for users. After that, anis administrator will be able to define a configuration by calling specific URLs (REST API).
> ./vendor/bin/doctrine orm:schema-tool:create
Create the metamodel database:
## Lancement de l'application en mode docker :
> make init-db
Vous pouvez lancer l'application en mode docker gràce au fichier docker-compose.yml se trouvant à la racine du projet.
And create the first superuser to define a configuration:
Pour ce faire vous devez avoir installé docker et docker-compose sur votre machine puis lancer la commande suivante :
> make email=admin@anis.fr password=admin add-superuser
> make build
> make start
## Anis server is now ready to use
Le container une fois lancé va rédiriger l'application su le port 8080 de votre machine. Rendez-vous sur l'URL http://localhost:8080 de votre machine pour vous assurez que l'application fonctionne.
Open a browser and go => [http://localhost:8080/](http://localhost:8080/)
## Liens
## Links
* `Slim` : [http://www.slimframework.com/](http://www.slimframework.com/)
* `Doctrine 2` : [https://www.doctrine-project.org/](https://www.doctrine-project.org/)
......@@ -98,198 +82,20 @@ Le container une fois lancé va rédiriger l'application su le port 8080 de votr
* `Composer` : [https://getcomposer.org/](https://getcomposer.org/)
* `PHP-FIG` : [http://www.php-fig.org/](http://www.php-fig.org/)
* `PHP-Unit` : [http://phpunit.de/](http://phpunit.de/)
* `Docker` : [https://www.docker.com/](https://www.docker.com/)
* `GIT` : [http://git-scm.com/](http://git-scm.com/)
* `CeCILL`: [http://www.cecill.info/index.en.html](http://www.cecill.info/index.en.html)
## Répertoires
* `config`: Répèrtoire qui contient le fichier de configuration nécéssaire pour l'utilitaire doctrine en ligne de commande
* `documentation`: Contient le MCD de la base de données metamodel ainsi que la documentation des URL disponibles
* `public`: Racine du serveur web
* `src`: Code source de l'application
* `test`: Tests de l'application avec `phpunit`
* `vendor`: Dépendances de l'application
## Fichiers clés
* `public/index.php`: Fichier de démarrage de l'application
* `src/settings.php`: Configuration de l'application
* `src/dependencies.php`: Configuration des services disponibles dans Pimple
* `src/middleware.php`: Configuration des middlewares
* `src/routes.php`: Configuration des routes de l'application (URL)
# Guide d'utilisation des URLS
# Vérification du service
* [/](documentation/api/root.md) => `GET`
# Login
Création d'un nouvel utilisateur :
- [/register](documentation/api/register.md) => `POST`
- [/activate-account](documentation/api/activate-account.md) => `GET`
Connexion et récupération d'un jeton d'authentification
- [/login](documentation/api/login.md) => `POST`
Changement de mot de passe
- [/new-password](documentation/api/new-password.md) => `POST`
- [/change-password](documentation/change-password.md) => `POST`
# Pilotage de la base metamodel
La base de données metamodel se pilote via une API REST et fonctionne avec les
méthodes `GET`, `POST`, `PUT` et `DELETE`
* `GET`: Récupération d'un ou plusieurs enregistrements
* `POST`: Ajout d'un enregistrement
* `PUT`: Modification d'un enregistrement
* `DELETE`: Suppression d'un enregistrement
Voici la liste des URLS et méthodes disponibles:
* Information sur les bases de données métiers {name} = nom de la base et {tname} = nom de la table:
- [/metadata/database](documentation/api/database-list.md) => `GET`, `POST`
- [/metadata/database/{name}](documentation/api/database.md) => `GET`, `PUT`, `DELETE`
- [/metadata/database/{name}/table](documentation/api/tables-available.md) => `GET`
* Information sur les projets {name} = nom du projet:
- [/metadata/project](documentation/api/project-list.md) => `GET`, `POST`
- [/metadata/project/{name}](documentation/api/project.md) => `GET`, `PUT`, `DELETE`
* Information sur les jeux de données {name} = nom du dataset:
- [/metadata/dataset](documentation/api/dataset-list.md) => `GET`, `POST`
- [/metadata/dataset/{name}](documentation/api/dataset.md) => `GET`, `PUT`, `DELETE`
- [/metadata/dataset/{name}/file](documentation/api/file-list.md) => `GET`, `POST` (fichiers associés au jeux de données)
- /metadata/dataset/{name}/attribute => `GET`, `PUT` (attributs associés au jeux de données)
- /metadata/dataset/{name}/attribute/option => `GET`
* Information sur un fichier d'un jeu de données {id} = identifiant du fichier
- [/metadata/file/{id}](documentation/api/file.md) => `GET`, `PUT`, `DELETE`
* Information sur une categorie {id} = identifiant de la catégorie
- [/metadata/category](documentation/api/category-list.md) => `GET`, `POST`
- [/metadata/cayegory/{id}](documentation/api/category.md) => `GET`, `PUT`, `DELETE`
* Information sur les groupes d'utilisateur {name} = nom du groupe
- [/metadata/group](documentation/api/group-list.md) => `GET`, `POST`
- [/metadata/group/{id}](documentation/api/group.md) => `GET`, `PUT`, `DELETE`
* Information sur les utilisateurs {login} = login de l'utilisateur
- [/metadata/user](documentation/api/user-list.md) => `GET`, `POST`
- [/metadata/user/{login}](documentation/api/user.md) => `GET`, `PUT`, `DELETE`
# Effectuer une recherche dans un dataset
* URL d'interrogation: /search
* Le paramètre `d` est obligatoire est doit contenir le nom du dataset à interroger
## Recherche par `critères`
* `c`: Le paramètre `c` est un tableau qui contient la liste des critères de
recherche
* Un critère de recherche doit contenir trois paramètres séparés par le caractère `-`
- Le premier paramètre contient l'`id` de l'attribut sur lequel le critère s'applique
- Le deuxième paramètre contient le type de critère sous la forme de deux lettres
- Le troisième paramètre contient les information nécessaires pour la création du critère
* Exemple: c[]=78-bw-102.49334|102.49540
## Liste des `critères` de recherche disponible
* Between (`bw`) :
1. Le troisième paramètre doit contenir les `valeurs` séparés par le caractère `|`
2. Exemple: 78-bw-`102.49334|102.49540`
* Date range (`dr`) paramètres :
1. Le troisième paramètre doit contenir les `dates` séparés par le caractère `|`
* Field (`fd`) paramètres :
1. Le troisième paramètre doit contenir l'`opérateur` et la `valeur` séparés par le caractère `|`
* Combobox (`co`) paramètres :
1. TODO
* Radio (`ra`) paramètre :
1. TODO
* Datalist (`dl`) paramètre :
1. TODO
* Select (`se`) paramètre :
1. TODO
* Checkbox (`ch`) paramètre :
1. TODO
## Recherche par `cone-search`
* Fonction de recherche spatiale
* Paramètres du `cone-search` :
1. `RA`: Ascension droite en degré
2. `DE`: Déclinaison en degré
3. `SR`: Rayon du `cone-search` en arc seconde
## Affichage des `colonnes de sortie`
* Le choix d'affichage des colonnes de sortie s'applique à tous les types de recherche
* `a`: Le paramètre `a` doit contenir une liste d'identifiants d'attribut séparés par un `|`
* Exemple: `a`=1|2|5|8
## `Ordre` d'affichage des enregistrements
* Par défaut les enregistrements sont triés par l'attribut contenant le search_flag `ID`
* Si l'utilisateur veut un ordre d'affichage précis il doit utiliser le paramètre `o` avec
comme valeur l'identifiant d'attribut souhaité ainsi que le sens
* `a` pour ascendant et `d` pour descendant
* Exemple: `o=5-a`
## Choix du `format` de sortie
* Le choix du format de sortie s'applique également à tous les types de recherche
* `f`: Le paramètre `f` doit contenir un format de sortie disponible (`json`,`csv`,`ascii`)
* Si le format `json` est sélectionné les paramètres de pagination sont obligatoires :
- `p[s]`: Contient le nombre d'objets par page
- `p[c]`: Contient le numéro de la page courante
# Guide développeur
# phpunit
* Permet d'éffectuer des tests unitaires sur le code source
> ./vendor/bin/phpunit --bootstrap ./test/bootstrap.php --colors ./test
# phpdoc
* Permet de fabriquer la documentation à partir des sources PHP
`$ php phpDocumentor.phar -d app/ -t ./build/api --ignore *library/*,*tests/*,*utils/*,*build/*,*js/*,*drupal/*,*bin/*`
# phpcpd
* Permet de détecter les copier coller (duplication) dans le code source
`$ ./vendor/bin/phpcpd app/`
# phploc
* Permet de mesurer la taille et d'analyser la structure du code source d'un projet PHP
`$ ./vendor/bin/phploc --progress app/`
# PHP_CodeSniffer
* Permet de valider le code à la norme de codage PSR-2
`$ ./vendor/bin/phpcs --report=full --standard=PSR2 --extensions=php --ignore=*library/*,*tests/*,*utils/*,*build/*,*js/*,*drupal/*,*bin/* ./app`
# PhpMetrics
* Donne des informations statistiques sur un projet PHP
## Software directories
`$ ./vendor/bin/phpmetrics --report-html=./build/phpmetrics.html app/
`
# PHP Mess Detector
* `conf-dev`: Configuration files for all anis containers (mode dev)
* `public`: Web server root (index.php)
* `src`: Source code of Anis software
* `test`: Anis Unit tests `phpunit`
* `vendor`: Software dependancies repository
* Permet d'évaluer la qualité de code source PHP
## Key files
`$ ./vendor/bin/phpmd ./app html cleancode,codesize,controversial,design,naming,unusedcode --reportfile ./build/pmd.html --exclude *library/*,*tests/*,*utils/*,*build/*,*js/*,*drupal/*,*bin/*`
* `public/index.php`: Bootstrap file for starting application (file used by an http web server like nginx or apache)
* `src/settings.php`: Anis server configuration file
* `src/routes.php`: Anis server configured routes (List of available URLs)
......@@ -33,6 +33,8 @@ final class ActivateAccountAction
/**
* The logger interface is the central access point to log anis information
*
* @var LoggerInterface
*/
private $logger;
......
......@@ -31,6 +31,8 @@ final class ChangePasswordAction
/**
* The logger interface is the central access point to log anis information
*
* @var LoggerInterface
*/
private $logger;
......
......@@ -30,6 +30,8 @@ final class NewPasswordAction
/**
* The logger interface is the central access point to log anis information
*
* @var LoggerInterface
*/
private $logger;
......
......@@ -32,6 +32,8 @@ final class RegisterAction
/**
* The logger interface is the central access point to log anis information
*
* @var LoggerInterface
*/
private $logger;
......
......@@ -32,6 +32,8 @@ final class TokenAction
/**
* The logger interface is the central access point to log anis information
*
* @var LoggerInterface
*/
private $logger;
......
......@@ -13,6 +13,7 @@ namespace App\Action\Root;
use Psr\Log\LoggerInterface;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use file_get_contents;
/**
* This action returns the open api description for the anis service. (GET)
......@@ -24,6 +25,8 @@ final class OpenApiAction
{
/**
* The logger interface is the central access point to log anis information
*
* @var LoggerInterface
*/
private $logger;
......@@ -50,7 +53,7 @@ final class OpenApiAction
{
$this->logger->info('Open api action dispatched');
$filePath = __DIR__ . '/../../../anis-server.yaml';
$openApi = \file_get_contents($filePath);
$openApi = file_get_contents($filePath);
return $response->write($openApi)->withHeader('Content-Type', 'text/yaml');
}
}
......@@ -25,6 +25,8 @@ final class RootAction
{
/**
* The logger interface is the central access point to log anis information
*
* @var LoggerInterface
*/
private $logger;
......
......@@ -19,15 +19,52 @@ use App\Utils\ActionTrait;
use App\Utils\DBALConnectionFactory;
use App\utils\AnisQueryBuilderFactory;
/**
* Get anis data search (GET)
*
* @author François Agneray <francois.agneray@lam.fr>
* @package App\Action\Search
*/
final class SearchDataAction
{
use ActionTrait;
/**
* The logger interface is the central access point to log anis information
*
* @var LoggerInterface
*/
private $logger;
/**
* The EntityManager is the central access point to Doctrine ORM functionality (metadata database)
*
* @var EntityManagerInterface
*/
private $em;
/**
* Factory method used to retrieve a PDO connection object to the business database
*
* @var DBALConnectionFactory
*/
private $dcf;
/**
* Factory method allows to retrieve an anis query builder object used to construct the SQL request
*
* @var AnisQueryBuilderFactory
*/
private $aqbf;
/**
* This class is creates before call __invoke to execute the action
*
* @param LoggerInterface $logger
* @param EntityManagerInterface $em
* @param DBALConnectionFactory $dcf
* @param AnisQueryBuilderFactory $aqbf
*/
public function __construct(
LoggerInterface $logger,
EntityManagerInterface $em,
......@@ -40,6 +77,15 @@ final class SearchDataAction
$this->aqbf = $aqbf;
}
/**
* This action returns data from an anis request
*
* @param ServerRequestInterface $request This object contains the HTTP request
* @param ResponseInterface $response This object represents the HTTP response
* @param array $args This table contains information transmitted in the URL (see routes.php)
*
* @return ResponseInterface
*/
public function __invoke(Request $request, Response $response, array $args): Response
{
$this->logger->info('Search meta action dispatched');
......
......@@ -19,15 +19,52 @@ use App\Utils\ActionTrait;
use App\Utils\DBALConnectionFactory;
use App\utils\AnisQueryBuilderFactory;
/**
* Get anis metadata search (GET)
*
* @author François Agneray <francois.agneray@lam.fr>
* @package App\Action\Search
*/
final class SearchMetaAction
{
use ActionTrait;
/**
* The logger interface is the central access point to log anis information
*
* @var LoggerInterface
*/
private $logger;
/**
* The EntityManager is the central access point to Doctrine ORM functionality (metadata database)
*
* @var EntityManagerInterface
*/
private $em;
/**
* Factory method used to retrieve a PDO connection object to the business database
*
* @var DBALConnectionFactory
*/
private $dcf;
/**
* Factory method allows to retrieve an anis query builder object used to construct the SQL request
*
* @var AnisQueryBuilderFactory
*/
private $aqbf;
/**
* This class is creates before call __invoke to execute the action
*
* @param LoggerInterface $logger
* @param EntityManagerInterface $em
* @param DBALConnectionFactory $dcf
* @param AnisQueryBuilderFactory $aqbf
*/
public function __construct(
LoggerInterface $logger,
EntityManagerInterface $em,
......@@ -40,6 +77,15 @@ final class SearchMetaAction
$this->aqbf = $aqbf;
}
/**
* This action retrieves meta information about an anis request (ex: number of objects)
*
* @param ServerRequestInterface $request This object contains the HTTP request
* @param ResponseInterface $response This object represents the HTTP response
* @param array $args This table contains information transmitted in the URL (see routes.php)
*
* @return ResponseInterface
*/
public function __invoke(Request $request, Response $response, array $args): Response
{
$this->logger->info('Search meta action dispatched');
......
......@@ -16,6 +16,12 @@ use App\Entity\Dataset;
use App\Search\Operator\IOperatorFactory;
use App\Search\AnisQueryBuilder;
/**
* Factory used to create an anis query builder
*
* @author François Agneray <francois.agneray@lam.fr>
* @package App\Utils
*/
class AnisQueryBuilderFactory
{
private $operatorFactory;
......@@ -25,7 +31,7 @@ class AnisQueryBuilderFactory
$this->operatorFactory = $operatorFactory;
}
public function create(QueryBuilder $queryBuilder, Dataset $dataset)
public function create(QueryBuilder $queryBuilder, Dataset $dataset): AnisQueryBuilder
{
return new AnisQueryBuilder($queryBuilder, $dataset, $this->operatorFactory);
}
......
......@@ -10,11 +10,31 @@
*/
namespace App\Utils;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Connection;
use App\Entity\Database;
/**
* Factory used to create a Doctrine DBAL connection to a business database
*
* @author François Agneray <francois.agneray@lam.fr>
* @package App\Utils
*/
class DBALConnectionFactory
{
public static function create(Database $database)
/**
* This static method create a connection to a business database.
* It retrieves connection information from the Database object.
*
* Databae object stores information about a business database in
* the metamodel
*
* @param Database $database This object contains the database connection parameters
*
* @return Connection
*/
public static function create(Database $database): Connection
{
$config = new \Doctrine\DBAL\Configuration();
$connectionParams = array(
......@@ -25,7 +45,7 @@ class DBALConnectionFactory
'port' => $database->getPort(),
'driver' => $database->getType(),
);
$connection = \Doctrine\DBAL\DriverManager::getConnection($connectionParams, $config);
$connection = DriverManager::getConnection($connectionParams, $config);
// Permet de faire fonctionner Doctrine avec les fonctions de pgsphere
$connection->getDatabasePlatform()->registerDoctrineTypeMapping('spoly', 'string');
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment