Note
|
TP de deux slots de 1h20 |
Commentaires éventuels des étudiants : N/A
-
Disposer d’un PC d’au moins 6 Gio de RAM avec 20 Gio de disque disponible ;
-
Disposer d’une version recente de VirtualBox ;
-
Disposer d’un compte Github par personne (ou un pour deux personnes si vous êtes en binôme) ;
-
Télécharger et décompresser l’image VirtualBox de l’environnement de développement ici (à faire avant le TP). Le login/mot de passe est :
tp
/tp
.
Répondre aux questions de la feuille de TP juste sous la question (en modifiant, commitant puis poussant le fichier README.adoc
).
Nous fournissons différents projets Eclipse servant de base de travail aux exercices suivant. Cela permet un point de synchronisation de tous les étudiants à différents moments du TP.
Tip
|
Fermer chaque projet Eclipse (sans supprimer les sources) avant de passer à l’exercice suivant pour éviter de confondre les projets ex1 et ex2. |
Temps estimé : 40 mins
-
Importer dans Eclipse les projets
todolist-debut-ex1
ettodolist-debut-ex2
.
Faire File
→ Import
→ Projects from Git (with smart import)
→ Clone URI
→ URI: https://github.com/<x>/tp1-miage-2021.git
(conserver les autres options inchangées) → 'Import projects from File System or Archives' : ne laisser cocher que tp1-miage-2021/tolist-debut-ex1
et tp1-miage-2021/tolist-debut-ex2
('import as Maven') → Bouton 'Finish'.
Tip
|
[Rappel Git] Trois dépôts sont ici utilisés: le dépot Github de l’enseignant (bflorat/tp1-miage-2021 ), le dépot Github du binôme (<x>/tp1-miage-2021 ), le dépot local sur le portable de l’un ou des deux étudiants du binôme.
|
-
Observer le code du projet
todolist-debut-ex1
Le code est-il structuré en couches ? Quel problèmes ce code peut-il poser ?
Non, le code n’est pas structuré en couche, on a un seul package. Ce code peut poser problème puisque dans le même package on va gérer des persistances, des configurations, le Rest et l’entité. On aura un problème de maintenabilité, dans la structuration du projet. Pour l’instant ça va car le projet est petit, mais si il grossit on va avoir de gros problèmes.
Où se trouve le code métier (voir la règle de gestion RG 1) ?
Le code métier se trouve dans le TodoListController.
Cette règle est-elle facilement testable par un test unitaire ?
La règle est facilement testable dans ce cas (petit projet) car il suffira de comparer le time de l’item et le time actuel et de vérifier s’il ne dépasse pas 24h. Si on dépasse les 24h, il faut vérifier que la chaîne content dispose bien des caractères. Mais si le projet était plus important, il sera difficile de tester la règle car la méthode est privée et il peut y avoir plusieurs contrôleurs ce qui complique la tâche.
-
Lancer une base PostgreSQL en Docker dans un terminal (on lance ici la base en mode interactif pour visualiser son activité. Pour la lancer en tâche de fond, remplacer les options
it
pard
comme 'daemon'):
docker run -it -e POSTGRES_PASSWORD=password -p 5432:5432 postgres
Expliquer cette ligne de commande (y compris les options utilisées)
On va lancer une base avec l’aide de Docker. On utilise donc la commande run pour indiquer qu’on veut lancer la base. On indique soit l’option -it pour interactif ou alors -d pour qu’elle se lance seule. Ensuite, on utilise l’option -e pour indiquer les variables d’environnement de la base, ici on indique que le mot de passe de la base sera password et on va indiquer le port avec l’option -p. Ensuite, on indique le nom de la base, ici postgres.
-
Compléter le code manquant dans la méthode
TodoListController.createTodoItem()
Pourquoi todoItemRepository
est-il null
? Quelle est la meilleure façon de l’injecter ?
todoItemRepository est null puisqu’il manque l’injection dans le todoListController. La meilleure façon de l’injecter est en utilisant l’annotation, c’est à dire : "@Inject"
-
Modifier le code en conséquence.
-
Tester vos endpoints avec un client REST.
Note
|
{
"id": "0f8-06eb17ba8d34",
"time": "2020-02-27T10:31:43Z",
"content": "Faire les courses"
} |
Note
|
Pour lancer l’application Spring, selectionner la classe TodolistApplication et faire bouton droit → 'Run as' → 'Java Application'.
|
-
Quand les deux endpoints fonctionnent, commiter, faire un push vers Github et fermer le projet Eclipse (ne pas le supprimer).
-
Vérifier avec DBeaver que les donnnées sont bien en base PostgreSQL.
Temps estimé : 1 h 20
-
Partir du projet
todolist-debut-ex2
Note
|
Le projet a été réusiné suivant les principes de l’architecture hexagonale : |
Source : Tom Hombergs
-
Nous avons découpé le coeur en deux couches :
-
la couche
application
qui contient tous les contrats : ports (interfaces) et les implémentations des ports d’entrée (ou "use case") et qui servent à orchestrer les entités. -
la couche
domain
qui contient les entités (au sens DDD, pas au sens JPA). En général des classes complexes (méthodes riches, relations entre les entités)
-
Rappeler en quelques lignes les grands principes de l’architecture hexagonale.
L’objectif principal de l’architecture hexagonale est de découpler la partie métier d’une application de ses services techniques. Ceci dans le but de préserver la partie métier pour qu’elle ne contienne que des éléments liés aux traitements fonctionnels.
Compléter ce code avec une fonctionnalité de création de TodoItem
persisté en base et appelé depuis un endpoint REST POST /todos
qui :
-
prend un
TodoItem
au format JSON dans le body (voir exemple de contenu plus haut); -
renvoie un code
201
en cas de succès.
La fonctionnalité à implémenter est contractualisée par le port d’entrée AddTodoItem
.
Temps estimé : 20 mins
-
Rester sur le même code que l’exercice 2
-
Implémenter (en junit) des TU sur la règle de gestion qui consiste à afficher
[LATE!]
dans la description d’un item en retard de plus de 24h.
Quels types de tests devra-t-on écrire pour les adapteurs ?
On fait des tests d’intégrations
Que teste-on dans ce cas ?
On va tester la technologie et voir si tout fonctionne bien lorsque l’on rassemble tous les éléments ensemble.
S’il vous reste du temps, écrire quelques uns de ces types de test.
Tip
|
|
-
Par constructeur :
La classe MailClient :
class MailClient {
SmtpServer server ;
MessageFormatter ;
@Inject
public MailClient (SmtpServer server, MessageFormatter formatter) {
this.server = server;
this.formatter= formatter;
}
}
La classe SmtpServer :
class SmtpServer {
Connexion connexion ;
@Inject
public SmtpServer (Connexion connexion) {
this.connexion = connexion ;
}
}
-
Par setter :
La classe MailClient :
class MailClient {
SmtpServer server;
MessageFormatter formatter;
//constructeur
public MailClient(){}
@Inject
public void setServer (SmtpServer Server) {
this.server = server;
}
@Inject
public void setFormatter (MessageFormatter formatter) {
this.formatter = formatter;
}
}
La classe SmtpServer :
class SmtpServer {
Connexion connexion;
public SmtpServer(){}
@Inject
public void setConnexion (Connexion connexion) {
this.connexion = connexion;
}
}
-
Par attribut :
La classe MailClient :
class MailClient {
@Inject
SmtpServer server;
@Inject
MessageFormatter formatter;
}
La classe SmtpServer :
class SmtpServer {
@Inject
Connexion connexion;
}
-
MessageFormatter manipule des beans Message sans dépendances. Doit-on injecter l’objet Message ?
Il faut juste importer une librairie donc non, on ne doit pas injecter l’objet Message.