:: Enseignements :: ESIPE :: E4INFO :: 2016-2017 :: Java Avancé ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) |
Projet d'IR2/IG2
|
Exercice 1 - PapayaDB
Le but de ce projet est d'implanter une base de données orientée document (), stockant un ensemble de valeurs au format JSON et auto-optimisée (la BD s’optimise toute seule).
PapayaDB permet
-
de créer, de supprimer une base de façon sécurisée (login/password + HTTPS),
-
d'insérer des documents au format JSON de façon sécurisée (avec un POST pas un GET, SVP!),
-
d'exporter l'ensemble des documents contenus dans une base (HTTP ou HTTPS sans authentification),
-
de répondre à des requêtes de sélection (HTTP ou HTTPS sans authentification) en profilant les requêtes dans le but d'optimiser les requêtes. La phase d’optimisation se fait de façon asynchrone,
-
de supprimer des documents de façon sécurisée en marquant ceux-ci comme détruits (avec DELETE pas un GET, SVP!)
puis en recréant une nouvelle base de façon asynchrone lorsqu'il y a trop (paramétrable) de documents marqués à détruire.
Le projet est composé de plusieurs parties implantant la base de données en elle même, un serveur Web (REST) permettant
de faire des requêtes (les requêtes sont elles-mêmes des documents JSON) ainsi qu'une API client en Java permettant
de faire des requêtes au serveur REST.
Chaque module doit être séparé et indépendant. L'ensemble doit être livré sous forme de JARs modulaires (compatibles avec les modules de Java 9):
-
l'API de la base de données coté serveur,
-
l'implantation de la base de données coté serveur,
-
le serveur de requêtes exportant des services au format REST,
-
l'API client en Java qui émet des requêtes vers le serveur de requêtes
(le résultat d'une requêtes doit être un Stream Java).
En bonus, l'interface de l'API de la base de données coté serveur et l'interface de l'API coté client peuvent être identiques.
-
Configuration
Il n'y a pas de configuration, tout est automatique sauf dans l'API client où l'on doit spécifier sur quelle machine se trouve le serveur de requêtes.
-
Sécurité
Si un couple login/password doit passer sur le réseau, il doit transiter dans un tunnel HTTPS.
-
Base de données sur le disque
Une base de données est stockée sur le disque sous forme d'un fichier en utilisant la fonction système mmap
(FileChannel.mmap en Java) et doit garantir que l'insertion de document est atomique.
Les indices permettant d’accélérer les requêtes doivent être stockés sur le disque aussi.
Une base de données doit stocker le moins de choses possibles en mémoire.
-
Langage de requêtes
Il doit être possible de faire des requêtes permettant de sélectionner les documents en fonction de leur contenu,
il doit être possible de spécifier le nom d'un champ, un chemin dans l'arbre (dans le cas d'un tableau, on peut utiliser un joker),
puis pour les valeurs numériques/les dates/les chaînes de caractères une borne min et une borne max.
La syntaxe exacte du langage est laissée à votre appréciation.
-
Profiling de requêtes
A chaque fois qu'une requête est demandée, la base de données doit répondre à cette requête et en même temps,
de façon asynchrone (dans une autre thread) essayer d'optimiser la requête (et surtout les suivantes) si cela
n'a pas déjà été effectué.
-
API cliente en Java
L'API client en Java doit être capable de faire les mêmes requêtes que celles disponibles en utilisant un browser
pour interroger le serveur suivant le protocole REST.
Les données des requêtes sont exportées par le serveur sous forme de services Web respectant la technologie REST.
Le serveur Web est imposé, il s'agit de
vertx dans une version
spéciale Marne la Vallée appelée
mini-vertx.
Cette version ne contient que les librairies nécessaires et est plus ou moins compatible
avec Java 9 si vous ajouter les deux
--add-exports suivant lorsque vous exécuté
avec la commande
java:
--add-exports java.base/sun.nio.ch=ALL-UNNAMED
--add-exports java.base/sun.net.dns=ALL-UNNAMED
Vous pouvez aussi regarder l'exemple
ExampleApp.java fourni dans le répertoire
src.
Note: pour exécuter le code vous devez aussi mettre l'ensemble des libraries de vertx (
vertx/lib)
dans le classpath (ou sous vous avez le courage les transformer en module).
Pour la partie client émettant des requêtes HTTP/HTTPS, vous ne pouvez utiliser que les classes du JDK 9.
Pour la serialization/deserialization JSON des requêtes, vous utiliserez jackson livré avec mini-vertx.
Le projet (un seul fichier par binôme) doit être déposé par le binôme
dont le nom est le premier dans l'ordre alphabétique sur la plate-forme
elearning
avant le ????.
Le livrable est un fichier au format ZIP (avec l'encodage correct si vous utilisez Windows)
et devra contenir dans un répertoire principal à vos deux noms
-
un répertoire src contenant les sources du projet avec autant de sous-répertoires que de modules Java 9;
-
un répertoire docs contenant le manuel de l'utilisateur (user.pdf) et
le rapport qui explique votre architecture (dev.pdf) au format PDF;
-
un répertoire classes vide dans l'archive et qui contiendra les classes une fois compilées;
-
un répertoire libs qui contiendra le ou les jars nécessaires pour JavaMail;
-
un jar modulaire de démonstration papaya-demo-1.0.jar permettant de montrer à travers l'API
Java client l'ensemble des fonctionnalités de la base de données (afficher les temps des requêtes pour que
l'on voit la base de données qui s'optimise)
-
un build.xml (écrit à la main, pas illisible car généré par un outil) qui permet de
- compiler les sources (target compile)
- créer le jar exécutable (target jar)
- générer la javadoc dans docs/api (target javadoc)
- nettoyer le projet pour qu'il ne reste plus que les éléments demandés (target clean).
Ce projet est évalué par les enseignants de Java, la dernière semaine du trimestre sous forme d'une soutenance
de 10 mins (on discutera architecture et code)
-
Concurrence
L’optimisation des requêtes et la suppression des documents marqués doivent se faire
dans une (ou plusieurs) thread(s) alors que la base de données continue à effectuer
des optimisations. Il faut pour cela que que le moteur de base de données,
le moteur d'optimisation et la partie suppression discutent entre eux sans qu'il y
ait de problèmes de concurrence.
Le code doit clairement séparer la gestions des threads du reste du programme,
utiliser les principes de la programmation objet pour encapsuler la gestion
de la concurrence en utilisant les principes et techniques vus en cours.
La présence de classes qui devraient être thread-safe mais qui permettent une utilisation
non-thread safe de ces méthodes sera très sévèrement sanctionnée.
-
Java Avancé
Le programme doit être écrit en utilisant correctement les différents concepts
vus lors du cours de Java Avancé (sous-typage, polymorphisme, lambda, classes internes,
exceptions, types paramétrés, collections, entrées/sorties et réflexion).
Pour vous aider, si vous ne respectez pas les indications de "mort imminente" suivantes,
il vous sera retiré 1 points pour chaque non respect d'une indication.
-
Il ne doit pas y avoir de warnings lorsque l'on passe findbugs.
-
Il ne doit pas y avoir de warnings lorsque l'on charge le code dans Eclipse.
-
Il ne doit pas y avoir de warnings lorsque l'on compile avec javac.
-
Dans un module, les packages d'implantations ne doivent pas être exportés et
requires transitive doit être utilisé là où c'est nécessaire.
-
Il ne doit pas y avoir de raw types, de @SuppressWarning non justifié, de cast non justifié.
-
Il ne doit pas y avoir de champs ou méthodes protected.
-
Il ne doit pas y avoir d'instanceof/switch/if...else sur des types là où il est possible
d'utiliser le polymorphisme.
-
Chaque interface devra être nécessaire.
-
Aucune classe abstraite ne doit être publique ou utilisée comme un type.
-
Chaque méthode devra être appelée (pas de code mort).
-
Aucune méthode ne doit pas faire plus de 8 lignes sans une vraie justification.
-
Il est interdit d'utiliser des champs static typés par un objet (pas de globale),
seule les constantes (static final) de type primitif sont autorisées.
© Université de Marne-la-Vallée