Grails dans les tranchées
Dominique Jocal, Développeur et architecte logiciel, responsable de deux domaines applicafifs chez CBP Solutions.
Ceci est le support de la présentation au JUG Nantes, Mercredi 4 décembre 2013, Epitech.
(Vous pouvez aussi consulter le compte rendu de Rossi merci à lui)
Le décor
Une technologie: Grails
Un utilisateur : CBP Solutions, courtier délégataire de gestion en assurance spécialisé dans risque de la personne, 500 personnes, Paris, Barcelone, Milan; Beaucoup de développements internes; plusieurs générations technologiques (RPG, Java... Grails) et architecturales (centré données... orienté services) - Big Data Big Rules
Une situation
- 6 applications/modules en Grails de 1 à 2 ans d'age (60 en java de 1 à 13 ans, 100aines RPG de 1 à 20 ans)
- coeur de métier de 2 nouveaux business
- utilisées par 2 équipes de gestion (sur plusieurs dizaines)
Un partage en JUG de Patterns et Astuces retenus.
Des classes du domaine moins anémiques
Principe faire porter par une classe domaine la logique à laquelle elle et ses enfants sont soumis.
Grails aide
Validation
static constraints {
capitalAssure scale:2 validator:{ ... regle d assurance... }
}
Injection de service dans les domaines
class DomaineDonne {
void faitDoncCela(params) {
domaineParticulierService.partieDuBoulot(...);
...
}
def domaineParticulierService
}
Testing framework
@Mock, mockCommandObject()
Délégations entre objets plus facile à organiser
Principe "petites" classe de domaine - puis agrégées et composées
Grails aide
static embedded = [ ... ]
static hasMany = [ ... ]
Cascade de validation
lazy & eager loading hibernate
Testing Framework, Closures
GrailsMock, MetaClass, equivalence Map/Objet
Des techniques, exemple le résumé d'erreur de validation
resume_erreur(objet_invalide) renvoit un résumé de la 1ère erreur sous la forme "attribut.raison"
// un test de validation très lisible
Contrat contratSansCap = new Contrat( capitalAssure:null, produit:P1)
contratSansCap.validate()
assert resume_erreur(contratSansCap) == "capitalAssure.obligatoire"
// vérification d'un paramètre validable en entrée de méthode
assert parametre.validate(), "$resume_erreur(parametre)"
// log pour assister au diagnostic
if (!obj.validate()) {
log.debug "cas $obj non valide : ${resume_erreur(obj)}"
...
}
// cascade manuelle de validation
static constraints {
associe validator:{val, obj ->
return val.validate() ?: resume_erreur(val);
}
}
(Techniques, suite)
Egalement:
- constantes typées fortement
- batchs avec gorm
- webFlow à base de domaines dédiées
Périmètre de responsabilité façon "pizza team"
Principe l'équipe est responsable d'un service rendu => elle développe le code ET la base qui va avec
Principe les administrateurs de données sont responsables de la cohérence et de l'urbanisation du patrimoine de données => ils co-concoivent la base avec l'équipe.
Grails aide
Classes de domaine persistantes par convention
Code first au lieu de schema first
grails schema-export
Conventions de nommage sql d'Hibernate
Dialectes H2 et DB2 (ex)
Traiter le paramètre Temps et les flux de synchro
Principe design basé historisation si forte exigence de flux de synchronisation
Principe contrôler applicativement en bdd la date du jour (capacité de vieillissement)
Grails aide
Events and auto timestamping
plugin Spring Batch, reader, processors, writers
XmlSlurper et MarkupBuilder - événements XML
(temps et flux de synchro, suite)
Le monde Java aide
statelessSession et scroll Hibernate sur Domaines Gorm
Parsing/rendering flux XML volumineux
StaX = XMLStreamReader et Writer
Consommer flux volumineux
Uploading Files
IDE, un chemin accidenté
Courage !
GGTS, de 2.8 à 3.4 fin 2013
Impossible d'installer un plugin pourtant nécessaire pour qu'un code fonctionne (imports) ?
d'abord compilation OK, ensuite installer le plugin/la dépendance
La compilation se met à prendre des minutes.. jusqu'au OOM ?!
compilateur groovy "à la eclipse" (incrémental + concurrent)... a des problèmes de concurrence !
séquencer les opérations de génération de code, d'enregistrement d'un source, d'update svn, etc. et la compilation eclipse
temps de compil qui s'allonge => restart workspace
pc de roxor : Core i7 dernière gen + Ram + SSD
Adoption récente de Intellij: premiers retours très bons
un développeur tout de suite opérationnel
Principe svn checkout, grails refresh-dependencies, grails run-app : tada! ça fonctionne tout de suite
- environnements Grails: dev et prod
- runtime Grails : tomcat embarqué en dev
- datasource de dev H2, de prod bdd cible (pour intégration, recette, préprod, prod)
- bootstrap de développement créant données de référence, données de gestion d'exemple
- bootstrap de production - selon votre souhait de prise en charge par l'appli - attention au cluster!
- liens http locaux/distants avec autres applications
et plus encore
Q: Maquettage ?
développement Grais avec données bouchons
levier de productivité si écrans types
Q: Scalabilité fonctionnelle ? (supporte plusieurs 100aines de domaines et services ?)
ne scalez pas comme ça !
quelques 10aines de domaines et services max par webapp
scalez en wepapps qui interopèrent par services: serveur à serveur, navigateur à serveur (mashup)
Q: IHM Multi-page ou single-page ?
Grails très bon pour le multi-page; OK pour single-page simple via tags; escalader vers Vanilla/Angular/Ember/whatever-JS pour du plus évolué
Grails très bon pour le serveur dans tous les cas
Q: qualité, maintenabilité ?
Très bon testing framework, convention d'architecture très testable
sur 67 applications/modules Java sous Sonar, les 10 meilleurs (min 60% de couverture par les tests, etc.) comprennent les 5 applis grails du parcQ: authentification et habilitation ? recherche plein texte des données ? monitoring ? cache des données de ref ?
plugins ! :spring-security-core:1.2.7.2 :searchable:0.6.3 :grails-melody:1.46 :springcache:1.3.1
Vers l'infini et au delà
Une conclusion de l'expérience: Grails, Rails, Play... = nouveaux socles de base (dur dur pour les assemblages maison, les devs maison, pur jee...)
Des projets :
- partager les astuces sur un blog
- continuer à implémenter du coeur de métier de gestion + applications de paramétrage
- explorer le parallélisme (Grails 2.3)
- tester automatiquement le JS