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