07 mai 2014

test des accès base

Je vous présentais hier un petit outil bien fait pour écrire les tests d'API REST. Sur une application qui fait autre chose qu'un hello world, il faut cependant "bouchonner" les resources externes pour rendre ces appels prédictibles et donc reproductibles dans le cadre de tests automatisés.

Une pratique courante de test consiste à utiliser des Mocks, en considérant qu'on veut valider l'utilisation d'un système tiers, pas son implémentation. Dans le cas un peu particulier d'une base de donnée cependant on est confronté à un problème : le SQL

Les accès à la base de donnée sont en effet liés à son interprétation de ces fameuses requêtes, et le seul moyen de s'assurer que leur syntaxe est correcte, correspond au schéma de la base de données, et retourne bien les données attendues, c'est ... de l'exécuter.

Que l'on fasse du JDBC à l'ancienne ou qu'on utilise un outil de requêtage type-name-safe comme jooq le problème reste le même, une requête n'est vraiment fiable que si on a pu la valider sur une base de données réelle. La solution que tout le monde (?) utilise est une base de donnée H2 - base qui tourne en mémoire - ce qui permet de démarrer rapidement et sans complication une base juste pour la durée des tests. Je me suis fait une Rule junit pour monter cette base H2 et appliquer les scripts de création du schéma, qui sont - évidemment - stocké dans mon repo Git avec le code de mon appli (what else ?).

Pour mettre la base dans un état donné et valider le résultat de mes requêtes, à la recherche d'une solution sympa, légère et qui soit un peu plus productive que des fichiers xml DBunit, je suis tombé sur dbassert.

    @Rule
    public InMemoryDataBase dataBase = new InMemoryDataBase();

    @Test
    public void list_items() throws Exception {

        DbAssert db = DbAssert.init("dbassert.yml");
        DbSource h2 = db.source("h2", getClass());
        h2.clean_table("items");
        h2.fixture("items");

        // Proposal returned
        when()
            .get("/items")
        .then()
            .assertThat().body(containsString("Test item"));

    }

Ca reste un chouille verbeux, donc pour faire clair :

le init consiste à configurer DBAssert pour accéder à la base de test. La DBSource sert à définir où trouver les fichier de données - dans le même package que la classe indiquée. On applique ensuite des fixtures, des fichiers yml de données pour la table du nom correspondant. On peut de même comparer l'état de la base après un update.

Quelques points négatifs qui me font penser que c'est un projet encore jeune, ou bien qu'il y a mieux ailleurs :)


  • le projet est sous SVN sur google code. Clairement pas adapté pour la contribution a l'aire de GithHub.
  • la librairie n'est pas disponible sur maven central. J'ai fait un export des sources dans mon src/test/java, vu qu'il n'y a que quelques classes
  • l'API est perfectible. Je voudrais pouvoir initialiser DbAssert via une DataSource - que j'ai préparée par ailleurs dans ma InMemoryDatabase  - plutôt que via un fichier yml
  • l'application d'une fixture utilise un INSERT bête et méchant, sans rechercher les données déjà insérée. On doit donc faire un clean_table systématiquement.
Rien de bien grave, qui devrait pouvoir se corriger via une petite contribution (d'où le premier point).

Si vous connaissez un autre outil comparable, je suis preneur de vos retours d'expérience.




05 mai 2014

test de services Rest

Il y a quelques années, lorsque je développais des applications web (avant de devenir essentiellement un développeur  middleware/backend) il y avait une explosion de frameworks MVC. Struts, WebWork, Wicket, Stripes, pour n'en citer que quelques-uns.

Les applications actuelles tendent vers un modèle à base de vue riches JavaScript et un backend REST, et on voit émerger une foultitude de Frameworks JavaScript et de backend REST.

Je n'ai jamais été très fan des tests web, selenium ou htmlunit, qui ont toujours été délicat à stabiliser et bons pour la casse à la moindre refonte de l'UI. L'évolution vers une architecture JS+REST a l'avantage de permettre au moins de tester facilement la partie REST - je n'ai pas encore exploré les solutions pour la partie Web à proprement parler, c'est quelque part dans ma todo-list ...

Comme toujours, il y a pléthore de frameworks pour un même besoin, chacun avec ses propres spécificités et avantages. Je n'ai pas l'ambition de vous dire avoir trouvé la perle rare ni proposer un palmares exhaustif, vu que je n'en ai essayé qu'un : Rest-assured.

Ce que j'aime bien dans Rest-assured c'est la syntaxe très, très simple et lisible des conditions de test et des assertions, très inspirée de l'approche BDD ("given/when/then") :

    @Test
    public void should_create_user() {
        given()
           .body("{ \"name\": \"nicolas\" }")
        .when()
           .post("/users")
        .then()
           .assertThat().statusCode(CREATED);
    }

Très peu de code parasite dans la description d'un tel test d'API. Que le scénario de test soit lisible même par ma grand-mère (ou pire : ma MOA) comme le voudraient les partisans des tests fonctionnels m'importe peu, par contre que je puisse rapidement définir une condition de test sans partir dans des imbrications d'API sans fin, ça me parle.

L'approche "fluent" (qu'on appelait Builder Pattern dans le temps, mais c'est moins hype) apporte aussi beaucoup en lisibilité. En gros, si on fait abstraction de la ponctuation on peut lire une phrase quasi naturelle (enfin, humanoïde quoi), c'est ce qu'on appelle un Domain Specific Language. On retrouve ce pattern dans tous les frameworks récents, et les lambdas de Java 8 aident pas mal à étendre cette approche à de nouveaux cas d'application.

Ce que je constate surtout, c'est qu'à côté l'explosion des frameworks applicatifs on a aussi une explosion de l'outillage de test, souvent (toujours ?) la cinquième roue d'un développement, mal ficelé, mal entretenu, mal outillé. Pour ce qui me concerne je les redécouvre tardivement. Ne faites pas la même erreur que moi, gardez un oeil sur vos tests et la boite à outil qui va avec.


Bon ceci dit, c'est bien connu "tester c'est douter". Perso j'ai appris à mes dépends à douter et à prendre quelques précautions pour éviter les mauvaises surprises.



Small is beautiful

Faire des tests rapides, un build qui ne dépasse pas quelques minutes, ça reste un voeu pieux confronté à une appli de centaines de milliers (millions?) de lignes avec une architecture alambiquée. Je ne jette la pierre à personne, j'ai moi même largement contribué à rendre ces applications alambiquées à grand coup de Spring-truc et d'AOP.



Aujourd'hui, avec du recul et surtout en travaillant dans une équipe totalement distribuée (donc où il faut savoir limiter les besoins de synchronisation et  de communication), j'apprend les mérite d'une autre approche.

Vive les micro-services.

Le concept de micro-service est expliqué en détail par Martin Fowler et James Lewis. 

Une application mastodonte-monolithique est délicate à faire vivre et ardue à appréhender. Le découpage en couches à la JavaEE et les modules maven associés ne changent pas grand chose à la donne, et au contraire ont tendance à figer de possibles mauvais choix. Si par exemple j'ai développé mon UserRepository avec plein de beaux tests, et que je veux faire un savant refactoring de mon modèle, je vais m'assoir sur tous mes tests, car ils sont ciblés sur la vision de mon architecture à un instant t, alors que le besoin de départ est fonctionnel. On touche ici au distingo test unitaire / test fonctionnel. 

Selon une approche micro-service, plusieurs applications spécialisées prennent en charge des domaines métier restreints. Une équipe plus spécialisée et plus restreinte s'occupe de ce "fragment" et peut plus facilement le faire évoluer. Dans le cas d'une équipe distribuée à la CloudBees, ça donne des équipes de 1 :-)  Chaque service étant très spécialisé et ciblé il est facile de rentrer dans le code "en renfort".

Ces micro-services communiquent ensemble via des APIs, et peuvent utiliser des protocoles binaires pour limiter l'impact d'un appel HTTP sur les performances, mais ce qui compte ce sont les frontières qu'on a défini dans le modèle métier.


Ces frontières et la réduction du scope allègent grandement chaque service et permettent de mettre en place des pratiques de développement efficaces, et d'augmenter l'agilité de chaque service. L'agilité de l'application dans son ensemble s'améliore aussi, malgré un surcout de synchronisation des développements de chaque service. C'est un peu le principe des scrums-de-scrum.

Autre bénéfice qui émerge rapidement, chaque micro-service peut avoir sa propre architecture, voir son propre langage d'implémentation, et donc mieux répondre au besoin "local". 

Ce n'est pas forcement lié, mais si on ajoute Docker dans l'équation, tous ces services peuvent tourner sur la même machine et la communication entre micro-services a alors un coût minimal. Docker permet de donner des quotas à chaque service, et donc d'identifier facilement lequel part en vrille lorsque c'est le cas - ce qui est souvent un challenge ardu sur une grosse appli monolithique. Il permet aussi de gérer un dimensionnement différent de chaque service, un cycle de vie différent, etc.

Bref, vous l'aurez compris, je suis fan :)

02 mai 2014

To test or not to test ?

Pendant des années j'ai fait la promotion des tests unitaires, expérimenté tout un tas d'outils (c'est le côté rigolo) sans moi même trop me plier à la pratique. Je pouvais prétexter intervenir sur des couches techniques et/ou d'intégration qui sont d'un compliqué ma pauv' dame.

Bref faites ce que je dis, pas ce que je fais.

J'ai utilisé le TDD une fois lorsque j'ai voulu ré-implémenter fonzie proprement (la version initiale étant au mieux un jouet, ce qui n'a pas empêché de le mettre en production, m'enfin). Il faut reconnaître que ça marche du tonnerre si on arrive à se discipliner.

J'arrive après la bataille et je ne vais donc pas vous faire l'apologie des tests unitaires, d'autre l'ont fait et le font encore bien mieux que moi avec nettement plus de crédibilité. Ce que je constate par contre, c'est que c'est une pratique qui a un impact fort sur les choix d'architecture et de frameworks.

Architecture : une grosses appli Java EE de centaines de milliers de lignes, avec toute la bonne volonté du monde ça met vite un temps fou à builder/tester. Je pourrais vous parler de micro-services (un autre jour ?) mais il est évident qu'avec une suite de test qui prend plusieurs minutes et écroule la machine, le développeur ne va pas lancer les tests régulièrement, ni sans doute avant de committer des modifs mineures (sic!) sauf à faire la police dans l'open-space - bonne ambiance garantie.
Ca veut donc dire qu'il faut savoir cibler les tests à l'essentiels, le 100% de couverture qui teste tous les getter/setter (si si, y'en a) n'apporte vraiment que du surpoids au projet.

Frameworks : Je vous parlais hier de fluent-http, et sans surprise ce framework web permet d'écrire des tests très léger et très rapides. Il sait démarrer sur un port libre aléatoire (ce qui permet aux tests de tourner en parallèle), et ce en quelques centaines de millisecondes.

public class MyResourceTest {

    @BeforeClass
    public static void runWebServer() throws Exception {
        WebServer server = new WebServer(routes -> {
            routes.add(MyResource.class);
        }).startOnRandomPort();
    }


    @Test
    public void should_create_user() {
        given()
           .body("{ \"name\": \"nicolas\" }")
        .when()
           .post("/user")
        .then()
           .assertThat().statusCode(CREATED);
        // TODO test database insert was successful
    }
}


Ce tout petit test me permet de tester mon service REST, il manque juste un peu de mocking pour la partie backend. Il est de niveau API, donc orienté fonctionnel, et me permet de jouer avec l'implémentation.

Jouer c'est bien le mot, car avec des tests aussi rapides, on peut activer infinitest.

Infinitest joue les tests à chaque modification de code (compilation si vous utilisez IntelliJ Idea). On va donc tripatouiller le code par petites touches, Cmd+S et hop le test vérifie qu'on a pas tout cassé et/ou qu'on a enfin réussi à implémenter la fonctionnalité attendue.

On est donc dans une logique de type micro-intégration-continue, très très efficace. Evidemment, si vous n'avez pas des tests rapides, ça n'est pas d'un grand intérêt. C'est donc un ensemble complet de pratique, d'outils, et d'architecture auquel il faut s'attaquer, tous d'un même front.

Pour en arriver là sur des projets non triviaux, il faut aussi savoir découper son appli correctement. Mais je vous parlerais de micro-services une autre fois :)


30 avril 2014

fluent-http, un amis qui vous veut du bien

Le Call-for-Papers du BreizhCamp est une appli custom développées au fil du temps libre l'an dernier et un peu rafraichie cette année. J'ai pour ambition d'en faire une appli "as-a-service" pour toutes les conférence qui veulent bien s'en servir (n'est-ce pas un super business model ?)

Pour arriver à ce résultat, un grand coup de ménage s'impose, et c'est donc l'occasion pour toute équipe de dev de critiquer les choix techniques "historiques" et essayer de nouvelles choses.

J'ai été tenté par Spring Boot, pour finalement me tourner vers fluent-http. Plusieurs raisons à cela :


  1. fluent-http est un framework tout neuf, c'est donc motivant d'y mettre son nez
  2. fluent-http est fait par l'équipe codestory, avec tout plein de Gageot-eries dedans, et donc c'est beaucoup plus sympa de se dire qu'on peut en discuter avec eux autour d'une bière.
  3. fluent-http est incroyablement léger et rapide. Cela permet d'écrire des tests unitaires (voir plus loin) efficaces
  4. fluent-http nécessite java 8, donc pas d'excuse, il est temps de se mettre aux lambdas et pourquoi par de mettre null hors d'état de nuire à grand coups de Optional.
  5. ça nous fera un sujet pour proposer une conférence :)

L'un des points techniques majeur qu'apporte fluent-http c'est la légèreté. Le serveur démarre en vraiment pas longtemps, et s'il ne supporte pas (encore) le hot-reload le cycle stop/restart prend plus de temps à cliquer qu'à attendre le serveur. Pas d'initialisation à la Spring à parser du XML ou à scanner le classpath à la recherche d'annotations, fluent-http est taillé pour démarrer vite avec juste ce qu'il faut. 

Le "juste ce qu'il faut" est aussi amha un point important. A utiliser des frameworks sensés nous simplifier la vie, on finit par se créer des contraintes et perdre un temps fou sur des problèmes d'intégration. 

Exemple concret : sur la version initiale du CfP, écrite en Play/Java+Angular, la sécurité est confiée à SecureSocial. Sur le papier c'est génial, trois fichier de conf et roule ma poule. Dans la réalité, lorsqu'on veut introduire du multi-tenant, utiliser l'email comme clé d'identification des utilisateurs, etc, on galère (surtout quand l'implémentation LinkedIn ne récupère pas l'email). Ajoutez quelques bugs (?) : je m'inscrit avec github, je fait ma cuisine, je tente de me reconnecter avec Google, et là j'ai un nouveau compte. Ballot non ? 

Au final j'ai passé pas mal de temps à comprendre la structure de SecureSocial, puis finalement a en forker un bout (pour le multi-tenant). C'est certes intéressant, mais tout bien pesé, implémenter mon propre login en comprenant les mécanismes OAuth2 ne prend pas nécessairement plus de temps (la preuve).

Donc, faut-il tout recoder sois-même ? Non, soyons réalistes. Faut-il mettre des frameworks pour tout juste parce qu'ils couvrent mon besoin (plus tout un tas de trucs) ? Non. C'est ce en quoi je ne suis pas fan de JHipster. Sur le papier c'est super, mais rien que la structure de code générée par défaut me fait peur. On peut débattre du bienfait d'avoir tous ces outils pré-cablés, qui seront nécessaires à un moment ou à un autre et ne coutent pas plus cher, mais personnellement ça ne me donne pas envie. J'ai par exemple peur de ce que va devenir mon build Grunt que je n'ai pas du tout conçu moi même. En gros, on m'impose des outils dont je ne sais rien, que je n'ai pas demandés, et que je ne maîtrise pas.

fluent-http se contente (sic) de prendre en charge la couche HTTP et l'exposition de resources REST, en ajoutant le support de templates html. Juste ce qu'il me faut, à moi de définir sur mesure ce que je veux ajouter dessus, au cas par cas.

J'ai glissé un mot sur les tests. Et oui, ça sent le Gageot entre chaque ligne de code. Fluent-http est très rapide à démarrer, non pas pour booster vos serveurs de production (quoi que ...) mais surtout pour permettre d'écrire des tests web rapides. 

Je vous en dirais un mot vendredi, il parait que c'est bien de faire un billet de blog par jour :)




16 avril 2014

la rançon du succès

Si vous ne le saviez pas, cette semaine c'est DevoxxFrance...

Je ne vais pas vous parler des divers talks de la journée, mais d'un événement tout à fait indirect.

Les organisateur de Devoxx on en effet du faire face à de la publicité sauvage, sur le trotroir juste devant le centre de conférence :



Ce marquage est fait au karsher, c'est donc écrit en "propre sur fond sale", rien à reprocher en termes de la dégradation de la voie publique.


  • D'un point de vue communication c'est inattaquable et  assez génial, il faut l'avouer
  • Du point de vue de DevoxxFrance, c'est une marque de reconnaissance indirecte : se faire ainsi "hacker" pour une campagne de pub, c'est montrer qu'ils sont incontournable.
  • Du point de vue du respect de la conférence, c'est nettement plus discutable. DevoxxFrance vie de l'énergie d'une quinzaine de bénévoles, et avec l'aide de sponsors qui payent leur place. Détourner ainsi cette énergie à des fins de promotion pirate est assez lamentable. En écrivant ce billet je me rend compte que je relaie leur message, mais en même temps j'espère vous faire comprendre à qui vous avez affaire. Détourner ainsi, sans contrepartie, les efforts d'une équipe qui se plie en quatre pour faire bouger notre écosystème, c'est minable.

Donc, si vous cherchez du taf, dites le moi, je publierais les CV des 10 premiers qui me contactent, juste pour montrer qu'il y a des manières plus respectueuses de faire les choses.

14 avril 2014

Jenkins meets Docker - round 2

On my previous blog post I explained how to use docker from Jenkins.



I can see some issues with this setup :


  1. You have to register the docker image you want to use as a slave in Jenkins global configuration, and rebuild the image when your environment requires some changes. 
  2. Dockefile has to define a ssh server, just to act as a jenkins slave, unrelated to your project needs.
  3. Docker plugin isn't elastic, even being a "Cloud" Jenkins plugin. It relies on a static docker-enabled host to run containers. I'd like to keep the Cloud principle to get resources as needed.


So, please welcome oki-docki jenkins plugin. This is still an experimental, unreleased, work-in-progress, use-at-your-own-risk plugin, but here's the concept :

You use your SCM to store both project source code, build script and a Dockerfile that describes your build environment. oki docki will use your Dockerfile to build+run a container and execute build script.


Plugin actually

  • checks project workspace for a Dockerfile
  • computes its hash, to detect changes
  • search for an existing docker image to match, build one if required
  • run a container, mounting build workspace in container as /var/workspace
  • executes build script

You may notice the docker image isn't pushed to a repository. This is intentional. I like the idea I can rebuild my docker image at any time from scratch, not relying on some binary deployed somewhere. Thanks to Docker incremental build, this isn't such time-consuming.


Benefits :


  1. no need to setup anything on jenkins, just have docker-enabled slaves. I'm using a "docker" label for this purpose. This one can benefit from jenkins Cloud slave providers.
  2. Dockerfile just defines requirements to build your project. All yours to select a specific JDK, system packages or nodejs version. The same Dockerfile can be used by developers to get a ready-to-use development environment.
  3. project Dockerfile is stored in SCM, with application code and build scripts, and all is kept in sync without manual steps. You can have a distinct Dockerfile in a branch if needed.


The current implementation is more a Proof-of-concept than a production-ready plugin, but already let you run a build inside Dockerfile. My initial goal was to start the container and then let jenkins run any regular build steps inside, but this require some Jenkins-remoting redirection hack, which development skills I don't have. On the other side, I also think it make sense to define your CI process as a script store in SCM, not relying on a set of build steps configured in jenkins (must admit I like travis-ci approach on this topic).

I plan to demonstrate this at DevoxxFrance during my talk "La révolution Docker" - assuming I don't break my environment in the meantime :)




08 avril 2014

Jenkins meets Docker - round 1

I'm investigating Docker usage in a Jenkins context, and would like to report here progress I made so far.



Step 1 : get docker up and running

My development laptop is running OSX, so I had to setup boot2docker. Compared to previous docker vagrant environment, this one is missing (sic) port redirection to host, so you for sure can run a container but can't access it :-\

No panic, you just have to run :

for i in {49000..49900} 
do
   VBoxManage modifyvm "boot2docker-vm" --natpf1 "tcp-port$i,tcp,,$i,,$i"
   VBoxManage modifyvm "boot2docker-vm" --natpf1 "udp-port$i,udp,,$i,,$i" 
done

Not a big deal, but I guess lot's of non-Linux users will search google for this tip. I also recommend you to run boot2docker if you're a Linux user, as it's far simpler to "drop" everything in a virtualbox instance vs cleaning up your system after you made some bad docker experiments.

Right, so docker is up and running on my MacBook. checked

Step 2 : create Docker image for jenkins slave (and use jenkins to build them, what else ?)

First thing I want to do is use Docker to manage my build environment. Jenkins for sure has various automated tools installers, but I prefer to manage this my way, with setup script stored within project SCM. With a Docker, I have a simple way to prepare build slave to match project prerequisites, with full isolation between jobs.

So, I need to setup a docker image to act as a jenkins slave. For this I need it to embed a ssh server - would be nice for jenkins to be able to use docker attach to access container, but I don't think anybody tried this yet.

Docker documentation gives you all necessary information to setup a sshd service, anyway that's not fun enough : as a Jenkins-guy, I want my environment setup to be automated and reproducible !

So, I'm using Michael Neale's docker-build-and-publish plugin to build my Dockerfile. This plugin is designed to ... build and publish docker images. Limited scope, do it well. Think about it as "my own trusted builds infrastructure"

I had to tweak my setup a few as recent docker version changed the behavior for ADD keyword. As I'm not much of a system packages fan, I used to ADD tools as tar.gz from a S3 bucket URL, but now only local files are unpacked by ADD command, so I need to first copy them to workspace so docker will expand them. I wonder docker team made such an error-prone choice, and didn't introduce an explicit EXPAND keyword, or something equivalent.

Anyway, after a dozen broken builds (sic) I got my environment setup and container ready to accept ssh connections to start a jenkins slave.

➜  ~ ssh root@localhost -p 49162
Welcome to Ubuntu 12.10 (GNU/Linux 3.13.3-tinycore64 x86_64)

 * Documentation:  https://help.ubuntu.com/
Last login: Tue Apr  8 11:05:01 2014 from 10.0.2.2
root@f720cc089b6c:~# java -version
java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b132)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b70, mixed mode)
root@f720cc089b6c:~# 

Step 3 : use docker containers as jenkins slaves

Then I've setup Docker-plugin to use it later for other jobs, running on the same Docker infrastructure - at this time, docker plugin acts as a Jenkins Cloud extension, but it doesn't offer scalability. I expect to find some way to introduce an alternative design so you can get slaves provisioned by IaaS on-demand (like other Cloud plugins do) and run a container on top of it, probably by using a build wrapper ... will see.

Anyway, Docker-plugin already does the job for my initial setup, just need to know it's using a pure java docker client (jDocker, a docker-java fork - Jenkins folks use to fork anything that doesn't accept pull requests within a week), and as such only support http. So don't set your docker URL as tcp://localhost:4243 as I use to set in .bash_profile for OSX development.

I also got various configuration issues and all sort of compatibility bugs that makes the distinction between documentation and reality :) Anyway, I now can run my demo job on this custom slave environment.


[04/08/14 14:10:21] [SSH] Opening SSH connection to localhost:49192.
[04/08/14 14:10:21] [SSH] Authentication successful.
[04/08/14 14:10:21] [SSH] Checking java version of java
[04/08/14 14:10:21] [SSH] java -version returned 1.8.0.
[04/08/14 14:10:21] [SSH] Starting sftp client.
[04/08/14 14:10:21] [SSH] Copying latest slave.jar...
[04/08/14 14:10:21] [SSH] Copied 364 754 bytes.
Expanded the channel window size to 4MB
[04/08/14 14:10:21] [SSH] Starting slave process: cd "/tmp" && java  -jar slave.jar
<===[JENKINS REMOTING CAPACITY]===>channel started
Slave.jar version: 2.36
Ceci est un esclave Unix
Evacuated stdout
Slave successfully connected and online

02 avril 2014

BreizhCamp 2014 : go, go, go

A nouveau cette année, l'équipe maintenant bien rodée du BreizhCamp est à pied d'oeuvre pour préparer la 4ème édition de la conférence connue internationalement (si, si)

Nouveauté majeure cette année, vu que nous ne parvenons pas à trouver des locaux plus vastes pour vous éviter la déception de ne pas obtenir de place, nous avons étalé la conférence sur une demi journée supplémentaire, mercredi après-midi, pour un hacker-space :


  • une session devoxx4kids, profitons que les nouveaux rythmes scolaires ne soient pas encore en application, nos gamins peuvent encore profiter de leur mercredi pour ... coder.
  • un hackergarten, l'occasion de découvrir un projet open-source et y contribuer avec l'aide d'un de ses principaux committers.
  • des ateliers pratiques divers (voir le call-for-papers plus loin)
  • des démos, en particulier sur tout ce qui touche au hardware et à l'embarqué. Les objets connectés, l'Internet des objets (IoT), et les wearables seront à l'honneur.

Nous avions aussi plein d'idées pour rendre le BreizhCamp 2014 plus beau, plus fort, mais le temps nous manque - la conférence aura lieu les 21, 22 et 23 mai, plus tôt que l'an dernier ... et nous voulons avant toute chose conserver la qualité de la conférence.

L'autre nouveauté c'est l'organisation d'une party jeudi soir, ouverte à tous, pour prolonger tard dans la nuit les discussions de la journée. Plus d'info très bientôt, dans notre newsletter.

Une autre nouveauté, et pas des moindres, c'est la liste de nos sponsors. On y retrouve des fidèles du BreizhCamp: Softeam, Zenika, Serli, CloudBees, Google, SQLi, mais aussi des nouveaux, Github, SonarSource, Sii, et notre second sponsor platinum, Microsoft.

Microsoft ? Et oui, même si le public du BreizhCamp est très coloré Java, la conférence a toujours eu comme objectif le brassage des cultures et les confrontations amicales. Découvrir le cloud de Microsoft ou leur approche fonctionnelle F# est une occasion de sortir de votre zone de confort !

Je vous le disais, BreizhCamp c'est une conférence mondialement reconnue, comme le prouve le sponsoring de GitHub et le speaker qu'ils nous envoient tout droit de SFO. Nous avons ouvert le call-for-papers aux speakers internationaux, nous espérons ainsi vous proposer quelques sujets de tout premier choix.

Le call-for-papers, d'ailleurs, est toujours ouvert (jusqu'au 10 avril). N'hésitez pas à postuler, mais ne tardez pas si vous voulez nous laisser une chance de prendre connaissance de votre sujet et de vous questionner avant le dépouillement.

Cette année, je ne serais pas membre du comité de sélection lors de l'établissement du programme (je ferais le con sur le stand CloudBees de scrum day). C'est aussi une garantie de l'objectivité de notre sélection, étant dans l'organisation de la conférence le "dictateur bénévole", cela laisse à l'équipe toute liberté pour s'exprimer et établir un programme équilibré.

L'équipe, c'est aujourd'hui la clé du BreizhCamp. Si j'ai monté la première édition quasiment seul (un des avantages de bosser pour FT c'est le temps libre que ça laisse), les choses se compliquent et sans mes camarades de jeu je n'irais pas bien loin. Un petit noyau dur donne la dynamique générale, et on y retrouve quelques Javaistes, mais aussi un Rubyiste et un dotNeteu, comme quoi le "mix de technologies", on l'a dans le sang.

Bref, tout ça pour dire que nous vous préparons un BreizhCamp 2014 de haut vol, et qu'il ne faudra pas trainer pour vous inscrire. 250 entrées max, c'est ce auquel nous sommes contraints par les locaux de l'ISTIC (si vous connaissez de super locaux à Rennes ...). Nous avons ouvert des inscriptions early-bird mardi midi, à 20h les 30 places étaient parties. Autant vous dire de surveiller l'ouverture de la billetterie, en suivant @breizhcamp par exemple :)

Cette année, le DIF est pris en charge pas SQLi, nous avons pris grand soin de faire les choses dans les règles de l'art pour éviter les désagréments que certains d'entre vous ont subis l'an dernier de la part de leur RH un peu trop à cheval sur le règlement.

go, go, go !






18 février 2014

Maven est mort ...

vive Maven.

Non, je ne parle pas du projet Apache Maven (ce serait peu scrupuleux de ma part de jouer sur l'ambiguïté et d'écrire un billet de blog avec un titre tapageur) mais du livre Apache Maven, édité par Pearson.

Arnaud et moi avons aujourd'hui reçu ce courrier :


Nous avions été prévenus de l'arrêt de la publication, et avons demandé la restitution de nos droits. Voilà chose qui est donc officielle. Au passage, je m'amuse de voir le livre toujours référencé sur http://www.pearson.fr/livre/?GCOI=27440100730370 et disponible en eBook :P

Bon bref, cette expérience d'édition a été instructive :

  • le travail sous Word avec un template barbare est une horreur
  • le processus de relecture et de PAO est une horreur
  • ça prend un temps fou
  • ça rapport très peu par rapport aux heures consacrées
Nous avons donc décidé de diffuser le contenu librement, après conversion au format AsciiDoc. La conversion étant loin d'être parfaire il reste pas mal de couacs, en plus de ceux présents dans le texte lui même, mais globalement, vous pouvez à présent nous lire de manière totalement gratuite et libre (license CC BY-SA).

https://github.com/ndeloof/apache-maven-book

Si vous voulez nous aider à faire vivre ce livre, vos contributions sont les bienvenues. Sinon il finira de mourir tranquillement en attendant que Maven 4.0 voie le jour. Et si vous regrettez l'époque où vous pouviez nous rémunérer pour ce travail (1,23€ par vente, imposable), nous sommes à votre disposition pour une bière ;-)

28 janvier 2014

Jouons un peu avec securesocial

L'équipe du BreizhCamp est en train de dépoussiérer l'appli Call-for-Papers développée l'an dernier. L'objectif premier est bien sur l'ouverture prochaine du CFP 2014, mais aussi l'hébergement à moyen termes d'un Call-for-Paper "as-a-Service", opensource et gratuit pour les tous les organisateurs de conférences. 

L'idée vient évidemment de ce que je bosse chez CloudBees (ce qui nous permet d'avoir des tarifs d'hébergement imbattables !) et que le développement d'un SaaS multi-tenant est un sujet qui m'intéresse énormément. 

L'idée vient aussi de ce que je suis moi-même speaker, et que j'en ai marre de copier/coller ma bio d'un CFP à l'autre. Avec un seul service sur lequel j'aurais mon profil, je pourrais postuler plus confortablement :)

Bref, ménage de printemps dans le code, qui est fonctionnel mais ... mérite quelques améliorations :) En gros, l'appli a été finalisée l'an dernier PENDANT le call-for-papers, il y avait donc pas mal de trucs plus ou moins bien finis.


L'appli est en Play2 / Java (l'équipe n'est pas très friande de code Scala) et l'UI en AngularJS. Nous avons donc naturellement confié l'authentification à la librairie SecureSocial. Vous pouvez donc vous identifier via les services OAuth github, google, etc.

OAuth

OAuth est un protocole d'authentification qui permet de fournir à une appli l'accès à vos données hébergées par une autre appli, sans pour autant lui donner votre mot de passe. L'application "cliente" vous renvoie vers l'applicable "cible", qui affiche une demande de confirmation, indiquant les droits demandés. Un callback fournit alors à l'application cliente un token pour accéder aux infos demanders. 

La sécurité d'OAuth est basée sur l'enregistrement de l'appli cliente chez le fournisseur de données.Le client dispose un ID+Secret unique qu'il utilise pour demander au fournisseur l'accès aux données - fournisseur qui demande l'autorisation de l'utilisateur - avant d'appeler le callback redirect_url.  



Je ne vais pas vous détailler plus OAuth, complètement pris en charge par securesocial, ce qu'il faut retenir c'est cette redirect_url vers laquelle vous ramène le provider après confirmation de l'accès. Ce callback doit être sur le domaine prévu, ce qui évite une utilisation frauduleuse, en complément de l'ID+Secret.

SecureSocial

SecureSocial est une libraire bien pensée, offrant des API Scala et Java, ce qui nous arrange bien :)

Un problème qui avait émergé dès l'an dernier, est que securesocial nous fournit comme identifiant d'utilisateur l'ID défini par le provider OAuth. Cela veut dire que Jean Dupont identifié par github n'est pas la même personne que Jean Dupont identifié par google. Par ailleurs, l'API de twitter ne permet pas d'obtenir l'email de l'utilisateur - et c'est volontaire

Première évolution, l'email devient la clé d'un utilisateur, ce qui autorise l'identification multi provider, et bien sur Twitter passe à la trappe (nous pourrions le rétablir, sous réserver d'obliger l'utilisateur à saisir son email et à le confirmer ... bref ce n'est pas du tout indispensable).

Seconde évolution, j'ai ajouté l'authentification via linkedin. J'ai galéré un moment, avant de comprendre que le provider OpenSocial ne prend pas le scope email chargé de demander l'email utilisateur. J'ai donc du définir ma propre implémentation, l'occasion aussi de remettre un peu le nez dans du Scala, j'aime bien de temps en temps, ça me change de Jenkins...

Détail amusant (?), l'implem' OAuth de LinkedIn ne contrôle pas du tout le domaine utilisé par la redirect_url, ce qui permet de tester même depuis localhost:9000 - de là à se demander si c'est très sécurisé tout ça ...

Troisième évolution, dans le but de faire de notre Call-for-Papers un SaaS, il faut gérer des sous-domaines (breizhcamp.call-for-papers.io, javaone.call-for-papers.io, etc). Vous voyez rapidement le problème, chaque conférence ayant un domaine propre, il faudrait un ID+Secret différent sur chaque provider OAuth. L'idée est donc que la page de login soit sur www.call-for-papers.io puis redirige vers le tenant initialement demandé.

La librairie securesocial, initialement sélectionnée pour nous simplifier la vie, nous met des battons dans les roues. J'ai dû créer une version custom de SecureAction qui rajoute deux lignes pour forcer l'hôte "www" en login, et mémoriser l'URL complète (pas juste l'URI relative au serveur) pour renvoyer l'utilisateur vers la page initialement demandée.

Pour l'instant, j'ai copié/coller du code de securesocial, je pense à plutôt me baser sur un fork, ce qui permettrait de synchroniser les évolutions upstream plus facilement (merci Git).

Bref, la vie n'est pas un long fleuve tranquille :)



23 janvier 2014

Les détails sont dans l'épaisseur du trait

Olivier Croisier a publié un article sur ses expérimentations avec Java 8, plus précisément l'introduction des default methods dans les interfaces. Cette nouveauté dans la syntaxe Java a été introduite initialement pour permettre à l'API Collections d'évoluer sans nécessiter à tout un écosystème de librairie de produire de nouvelles versions mises à jour pour Java 8, autrement dit d'attendre 2020 pour que ce soit utilisable concrètement.

Comme l'a très bien analysé Olivier, ces default methods apportent à Java le concept de trait très utilisé en Scala. La tournure fonctionnelle que Java 8 va permettre de faire prendre au langage est un pas majeur, bien plus important amha que l'introduction des génériques en Java 5.

Pour rebondir sur le problème du diamant exposé par Olivier, mon interrogation sur les conflits de méthodes introduites pas les default methods se pose un peu différemment :

nous avons donc une classe Clazz qui implémente deux interfaces Foo et Bar.

1 public interface Foo {
2     public default void helloWorld() {
3         System.out.println("Hello World");}
4 }

1 public interface Bar {
2 }


1 public class Clazz implements Foo, Bar {
2 
3     public static void main(String args[]) throws Exception {
4         new Main().helloWorld();
5     }
6 }

Disons que la première déclare une default method helloworld(). Si Bar définit lui aussi la même default method le compilateur détecte le conflit. Supposons cependant que dans un premier temps Bar n'a pas de telle méthode et que nous compilons notre projet. Nous ajoutons alors a Bar la default method conflictuelle, et re-compilons la classe Bar (et elle seule).

Question : est-ce que notre programme continue de fonctionner comme avant - en gros, est-ce que le bytecode produit fait directement référence à la méthode Foo.helloworld(). Ce qui veut dire que nous ne pouvons plus le re-compiler depuis les sources. Une bonne raison de configurer votre intégration continue avec un "mvn clean install" :)

Je vous laisse essayer par vous même pour avoir la réponse :-D

Java 8 apporte des changements profonds, et expérimenter est la seule façon concrète de comprendre leur impact. Voir ce que fait Yan sur https://github.com/ybonnel/Jdk8Experiments par exemple, je vous encourage à en faire autant.

Je suis en ce moment (exactement en ce moment, dans le TGV Rennes-Paris, connecté en tethering) en train de lire le livre "Functional Programming for Java Developers". Si le livre n'est pas tout juste sorti des presses et ne parle donc qu'à peine de Java 8, et avec une syntaxe obsolète, les concepts fondamentaux sont bien présents et très utiles.


J'entend beaucoup de monde me dire qu'ils n'utiliseront pas Java 8 avant une décennie, bloqués par les contraintes client d'un runtime websphere 6. C'est évidement une réalité, et clairement vous n'aurez pas de traits dans vos applications. Ca n'empêche pas de commence à appréhender les concepts fonctionnels, qui sont un excellent complément à l'approche objet.

En dehors de l'approche fonctionnel que va (mieux) permettre Java 8, ces changements annoncent aussi des bouleversements dans l'écosystème des librairies et frameworks. Exemple type, de nombres frameworks définissent des classes abstraites, que votre code doit étendre. Un jeu d'interface serait plus propre, mais alors impossible de faire évoluer les API. Jenkins par exemple comporte une quantité phénoménale de classes abstraites pour cette raison.

Autre approche si on aime pas les classes abstraites, faire à la façon d'Eclipse, en définissant des interfaces HelloWorld1, HelloWorld2, HelloWorld3, et en testant au runtime quelle interface est implémentée, bref une solution pire que le mal lui même.

Bref, tous les frameworks pre-java 8 - en dehors d'Eclipse - se basent sur des classes abstraites, et pourrissent nos arbres d'héritage. Une opportunité apparaît donc avec Java 8 pour une nouvelle génération de frameworks, basés sur des traits. Le même genre de changement qui a laissé commons-collections sur le carreau avec l'arrivée des génériques et une mise à niveau jamais aboutie, qui a laissé la place à Guava et quelques autres.

Donc, oui, votre client a du Java 5 en production. Oui, c'est une version "End of Life" mais il s'en fout, et vous n'y pouvez rien. Et pourtant, si vous ne voulez pas passer pour un développeur avec des faux airs de Cobol dans quelques années, il est temps pour vous de regarder ce qu'apporte Java 8, d'expérimenter, de découvrir les bénéfices et les concepts de la programmation fonctionnelle, et de pleurer en revenant à votre code sans lambdas ;)

13 janvier 2014

BootCamp Rennes DevOps

Même si on atteint pas la prolifération de S*UG (Scala | Scrum | Spring | ... | user-groups) qu'offre la capitale, Rennes n'est pas en reste d'activité communautaire. Il y a bien sur le BreizhJUG, devenu au fil du temps une institution locale, mais aussi de plus petit groupes plein de bonnes idées, comme par exemple Rennes Devops.

Avec la possible venue d'OVH dans la capitale Bretonne, le groupe veut démontrer son dynamisme, et organise le 25 janvier un BootCamp DevOps à la Cantine Numérique Rennaise.


Pour ma part, j'ai proposé d'y parler un peu de déploiement continu avec Jenkins, mais surtout de Docker. Donc si vous voulez passer un bon moment et élargir un peu vos horizon d'architecte Java EE, bloquez votre agenda !

Interview de Nicolas Ledez, initiateur du BootCamp :


Bonjour Nicolas, est-ce que tu peux te présenter en quelques mots ? 

Bonjour Nicolas, je suis un "hacker" Ruby, DevOps, Admin Système, Arduino, etc. Je bidouille depuis tout petit, électronique, informatique. Coup de bol, j'ai réussi à en faire mon metier.

Est-ce que tu peux nous expliquer le concept de "BootCamp" ? 

Je vois ça comme la possibilité d'aider les gens à réussir leurs bonnes résolutions de début d'année. Aux US c'est du sport. Mais comme il fait encore un peu froid en Bretagne, je propose de commencer l'année en démarrant avec des technos comme Docker, le Cloud, Chef et plein de trucs DevOps. 

Qu'est ce qui t'es passé par la tête pour lancer ce projet ? Trop de temps libre ? 

À l'origine, c'était une idée de Frédéric Alix (http://blog.fredalix.com). Qui pour différentes raisons n'a pas pu y donner suite. Et finalement, pour les développeurs, il y a l'excellent Breizhcamp, mais rien pour les ops - donc…

Et j'ai aussi un petit coté maso :p

Tu enseigne aussi la robotique sur Lego NXT ! As tu encore beaucoup d'autres  cordes cachées à ton arc ? 


Hou là !!! Oui beaucoup.
Je vais démarrer des cours pour débutant de développement Web dans le cadre du http://labfab.fr/
+ Breizhcamp, Devcamp, et plein d'autre trucs 

ok, rendez vous le 25 pour te voir à l'oeuvre 

infos et inscriptions : http://rennesdevops.fr/bootcamp-rennes-devops/

13 décembre 2013

Rendez-vous à Devoxx France

Devoxx France a ouvert son Call for Paper début décembre, et se pose pour moi la question de quoi proposer.

L'an dernier j'ai mis tout ce que j'avais en magasin, au risque de passer pour un spam-bot. J'ai constaté que les sujets "cloud" ou "continuous delivery" qui me sont chers ne font pas rêver le comité de sélection - ou alors je ne suis pas bon vendeur.

Bref, suivant une suggestion de Nico Martignole, je lance un Google Moderator :

Quel sujet voudriez-vous me voir présenter à Devoxx 2014

A vous de jouer !

19 novembre 2013

être speaker à Devoxx

Devoxx a toujours été pour moi LA conférence. Les locaux inégalables, l'ambiance bon-enfant, la diversité et la fréquentation en font un événement sans équivalent.

J'ai présenté ma conférence "Cloud Patterns" pour la première fois à Mix-IT, ce qui m'a permis d'en caller la durée. J'ai pu l'expérimenter en version EN_fr à GeeCon, la re-jouer à SoftShake et CodeurEnSeine et en peaufiner les détails. J'ai eu le temps de me faire à Keynote pour agrémenter mes slides d'effets graphiques sympas. Bref, c'est un talk rodé.

J'ai été retenu à JavaOne. Très franchement, après l'expérience GeeCon je n'étais pas spécialement stressé de faire ce talk devant le public américain. JavaOne c'est beaucoup de monde mais surtout beaucoup de petites salles. Et comme j'étais prévu en dernier slot la question était plutôt de savoir si je serais tout seul dans la salle...

Et il y a eu Devoxx.

Mon talk a été retenu, et c'est une grande fierté. Et malgré le rodage préalable, faire cette conf à Devoxx a suscité un trac important. Je ne saurais pas dire précisément ce que cette conférence à de si particulier, mais elle est clairement à part.

D'une part, il n'y a pas de "speaker room" et c'est volontaire : les organisateurs désirent que les speakers se mélangent à la foule et soient accessibles. De grandes tables permettent aux geeks en tout genre de bosser/hacker entre deux sessions, beaucoup de speakers en profitent et sont ainsi disponibles pour des questions complémentaires. Bref, un speaker à Devoxx est un Devoxian comme les autres

Il n'y a pas de "petite salle". Si on met de côté les deux salles des BOFs, les immenses salles de cinéma du Métropolis accueillent de 400 à 800 personnes. Evidemment on est pas sur qu'elles soient pleines, mais ça fait un effet non négligeable sur le speaker tout seul en bas.

Il ya les copains. Devoxx c'est à 2h de Paris et les Français y sont nombreux. On en repère un ou deux dans la salle malgré les projecteurs en plein tronche et ça aide bien moralement.

Il y a Stephan et toute l'équipe Devoxx, ultra disponibles à toute heure. Stephan a eu la gentillesse de venir me dire un mot juste avant mon talk - en fait deux : "bonne chance" et "évite les photos compromettantes". J'ai presque tenu compte de ses conseils.

Bref, être à Devoxx comme speaker, c'est quelque chose de spécial. C'est à la fois se sentir comme à la maison et dans la plus prestigieuse conférence de l'univers. De quoi se sentir à l'aise pour donner son maximum.






09 novembre 2013

on est pourtant pas vendredi 13

J'enchaine les coups de stress ces temps ci

la semaine dernière, en plein pendant un week-end dans la famille, mon Galaxy S3 me fait le coup de la "mort subite". J'ai retiré 25 fois la batterie, épluché les forums ... en vain.


Bon, allez, y'a pas mort d'homme, et en plus voilà un prétexte tout trouvé pour commander le Nexus 5.

Lundi, allez hop soyons fou je migre mon MacBook sous Maverick. "upgrade gratuit" de la part d'Apple, j'aurais de me méfier. Aucun changement notable.

petite parenthèse : j'essaye "plan" vite fait, dont j'ai entendu tant de mal, et la photo aérienne de mon chez-moi est plus à jour et de bien meilleure qualité que google maps. Donc pour un gars qui vit dans sa campagne comme moi c'est plutôt positif ;)




Après l'ugrade, mon code d'accès à https (je bosse sur le plugin git jenkins) se met à planter - j'apprends qu'il faut réinstaller le java 6 Apple.

Bon, allez, y'a pas mort d'homme, c'est pas méchant ça m'a "juste" fait perdre une journée de taf, c'est pas comme si j'était grave à la bourre juste avant Devoxx.

Sinon R.A.S, ça reste un OSX quasiment tout pareil - ça m'aurait fait mal de payer un upgrade pour ça - jusqu'à ce que je décide de rebooter (quand git n'arrive plus à résoudre "github.com", c'est pas bon), après tout un reboot une fois par semestre ça peut pas faire de mal.

Et là, gros coup de stress : mot de passe refusé.



Donc chez Apple, ils ont décidé que maintenant, le clavier au démarrage serait en QWERTY, voilà comme ça. Il y a une icône à peine visible pour l'indiquer. C'est pas comme si l'avantage concurrentiel d'apple c'est de maitriser le hardware, donc on pourrait s'attendre à ce que l'OS sache quel variante du clavier est intégrée au MacBook. 

Bon, allez, y'a pas mort d'homme, j'ai juste appris quelques injures à mes gamins et pris 2 points de tension, en plus ça me rappelle de faire une sauvegarde time-machine.

quelques heures après, juste le temps de se détendre un peu (sic) je reçois un coup de fil sur mon nexus 5 tout neuf - un appel automatique du monitoring CloudBees - je raccroche, et j'ai un écran noir. Le téléphone ne répond plus à aucune touche (moralité, il ne faut pas répondre aux appels d'alerte du monitoring).

Panique à bord, avec un ++ vu que je n'ai même pas encore annoncé à Madame que j'ai acheté ce nouveau jouet. Twitter est ton amis et j'apprend donc à utiliser le power + volume bas (10 secondes) pour un reboot forcé.



A ce stade le week-end ne fait que commencer, mais j'ai mon compte. Je dois encore finir de préparer mes slides pour Devoxx, j'espère qu'on va en rester là.


Bon, allez, y'a pas mort d'homme. 

Mais vous savez à quelle point un Geek est dépendant de son attirail high-tech...






31 octobre 2013

Git sucks

Titre tapageur - serais-je un peu provocateur ?


Non, je ne vais pas faire l'apologie de Clearcase, je suis très content de Git en tant que développeur et je n'ai absolument pas l'intention de changer, même pour un autre DVCS.

Par contre, je suis mainteneur du plugin Git pour jenkins. J'ai hérité de ce plugin sans trop savoir comment, au départ en backportant des correctifs utilisés par CloudBees puis rapidement faute d'une mainteneur en place. Et j'ai rapidement compris pourquoi : ce plugin est un amalgame de pull-requests en tout genre.

Le problème de la pull-request, c'est


  1. quand on crée un patch, et donc une pull-request, on essaie de faire minimaliste. On ne fait pas un gros refactoring juste pour la beauté du geste. On va donc ajouter un "if (foo) { ... } else" dans le code existant. 25 pull requests plus tard la méthode fait 400 lignes et est incompréhensible.
  2. si c'est un mécanisme de revue de code formidable, en opensource la pull-request a ce désagréable effet de bord de permettre à un contributeur de "balancer" du code par dessus le mur, sans s'impliquer forcément dans le projet. D'où l'absence de continuté sur ce plugin.

Bon, ça c'est l'historique, qui n'aide pas, mais pas le coeur du problème.

L'un des principaux objectifs pour la version 2.0 du plugin Git était d'introduire le support de l'authentification via le plugin credentials.

L'option 1, c'était JGit. Il y a quelques temps le plugin Subversion est passé à svnkit plutôt que de piloter le client svn pour des raisons comparables. JGit prométait de faire de même. Sauf que JGit est encore loin du niveau de maturité nécessaire pour être utilisé dans le plugin jenkins. J'ai rapidement découvert la ... créativité des développeurs dans leur usage de Git, et le manque de documentation de JGit, ainsi que l'absence de fonctionnalités pourtant pas mineures. Quand je pense que les utilisateurs d'Eclipse se basent dessus j'ai un peu peur...

JGit reste donc une option expérimentale, et ça risque d'être le cas encore un bon moment.


L'option 2, c'était de conserver le pilotage de la ligne de commande git. Plusieurs problèmes majeurs, et c'est ce qui me fait dire que "Git - i.e., le client git en ligne de commande - sucks"

  1. le client git n'a pas de mode non-interactif. Il peut donc bloquer en demandant à l'utilisateur son username, ce qui bloque jenkins par la même occasion. Je ne connais pas d'outil en ligne de commande qui n'ai pas une option "batch", "quiet" ou "force", bref un truc prévu justement pour ce genre de cas de figure où il n'y a PAS d'utilisateur en face de la console.
  2. le client git ne fournit AUCUN moyen de passer les paramètres d'authentification. En http il se base éventuellement sur .netrc (un fichier prévu pour ftp soit dit en passant), et en ssh il se base sur le client ssh et vous laisse dans la m... StackOverflow regorge de hacks divers pour contourner ces problèmes, et même la doc officielle s'en lave les mains et vous dit de bricoler un script shell. 
To pass options to the program that you want to list in GIT_SSH you will need to wrap the program and options into a shell script, then set GIT_SSH to refer to the shell script.


Ce qui, bien évidement, ne fonctionne que sur un système Unix-like (JENKINS-20356)


Je cherche toujours l'option 3. Il n'existe à ma connaissance pas d'autre client Git que je pourrais utiliser depuis du code Java (des suggestions ?).


Update:
Certains sont surpris. Après tout JGit est utilisé par EGit, mais aussi Gerrit, ou GitBlit; alors quoi, peut être que le plugin jenkins est juste codé avec les pieds - ce qui n'est pas faux mais bon je m'égare.
Je viens d'apprendre que le plugin git maven lui aussi souffre des limitations de JGit. Entre autre des file leaks sous windows, problème rapporté par de nombreux utilisateurs de git-plugin. 

De mon côté je lorgne sur libgit2, qui permettrait d'utiliser un client git natif. Mais évidemment il n'existe pas de binding Java :'(



18 octobre 2013

Configuration Management JSR

I recently discovered project to start a JSR for Configuration Management. Mike Keith introduced this project at JavaOne, you can download slides for his presentation here. I wasn't aware so didn't attend the live talk, but reviewing the slides I have few comments.

Proposal (afaik)

Scope for such a JSR is difficult to establish. If you want to embrace the existing tools, there is overlap with generic platform provisioning. I don't think this is a good idea to consider this until there's a reasonable consensus on application-level configuration management. Looks like this is also the diagnostic for this JSR.

The current state for JavaEE configuration is "JNDI" : if you need to inject some resources / parameter to an application, you have to provide some container-specific xml file in your WAR archive. This suppose Ops will unzip the WAR, edit xml to put production resource binding and credentials, then re-archive and deploy using container-specific commands. Nobody never did this. So this is a great idea to review this and provide something to better match actual practices and tools.

Also have to consider the DevOps impact on development/deployment practices.

Contract for configuration management is also complex to establish. Reviewing slides, the proposal seems to be to package application configuration in a CAR (configuration archive).


I think this is a very bad idea. For the same reason Ops don't unzip WAR to edit xml files, they won't do this to create CAR files. Ops tools and practices are based on scriptable solutions from system shell. I don't think we will see JavaEE apps packaged as RPM/DEB system packages, at least because Java is supposed to "run everywhere", not just on Linux distros. But a configuration management JSR must primarily focus on Ops practices, not on JavaEE developers. JSR use to define Java based API, I think this specific JSR must NOT use Java as primary language. My main concern with a java-based approach is that this will result in a new java.util.prefs.Preferences nobody is using.


My vision

I'd prefer the JSR to define a REST API application container (or platform as a service) have to expose to allow defining the configuration for an application. REST is neutral, well supported both from Java tooling and base script shell (using curl).

So, you can imagine a REST endpoint on your application server that let you define an "application" (unique ID) and bind server resources / configuration parameters to this application. Application server is responsible to implement actual persistence.

Deploying an application would then be :


  1. create the application with unique ID
  2. set application configuration 
    • resource bindings (JDBC DataSource, JavaMail session, JMS queues, etc)
    • simple parameters
    • structured parameters (? - see later)
  3. deploy WAR/EAR for application ID


Application configuration has to be persistent : it will survive application restart and redeployment, as long as application unique ID is unchanged. It's also idempotent: binding same resource twice don't result in a duplicated resource. This is a requirement for infrastructure automation tools (like Chef/Puppet) to work in this context.

Without any surprise, you probably notice how this proposal mimic CloudBees configuration management. We also support cloudbees-web.xml and some of us like it, but I consider this legacy. Using SDK to bind a Database to my application, whatever application server I'm using - Tomcat, JBoss, Glassfish, Jetty - and getting it injected as a JNDI DataSource is awesome.


How does application access configuration ?

Based on slides, JSR proposal defines a new API for application code to access configuration. So, you'll have to wait for all frameworks to be updated to benefit this API :-/

To workaround design issue for JavaEE to miss a configuration API, most framework rely on placeholders, the common denominator being support for system properties. I never have seen a JavaEE application to use String declared in JNDI, but I not a bunch of apps to get runtime settings from system properties. For adoption of a configuration management JSR, and immediate support on most frameworks, system properties must be considered as first-class citizens in configuration land.

Injecting a simple parameter in an application should result in getting the equivalent system property set. With system properties, you already can manage a bunch of use-cases. I'm not sure there's actual need for structured parameters. This could be addressed by JAXB / JSONB data binding anyway.

Conclusion

I'd be very happy to contribute this JSR. I've been looking for an "incubator" page for it but can't find this on jcp.org. I'm not sure then how expert group is established, but if I can join I'd be very happy to compare my point of view with others and help as much as possible to make this JSR a useful one.


29 septembre 2013

private, public, hybrid

Après mon talk "Cloud Patterns"et comme presque à chaque fois j'ai eu droit à des réactions étonnées sur ma position (ie. celle de CloudBees) sur l'approche "Private Cloud". Explications:

photo credit: Cici D



disclaimer: Je Bosse chez CloudBees. Je partage l'analyse de ma société, cependant libre à vous de considérer que je suis biaisé dans ma perception des choses.

1. Cloud != DataCenter

Première confusion, de nombreuses sociétés parlent de "Cloud Privé" pour le DataCenter dans lequel elles sont en train de mettre en place de la virtualisation. Soyons clair, je définit un "Cloud" comme :

  • ressources (quasi) illimitées, disponibles à la demande - ce qui ne veut pas dire sans quotas ni restrictions,
  • accès direct par API, sans passage par la case "formulaire bleu à envoyer à l'admin signé par le CdP",
  • mutualisation des ressources et facturation à l'usage,
  • délégation complète de la maintenance et du support.

De ce point de vue, nombreux sont les projets de "Cloud privé" qui sont en fait des migrations d'une IT basée sur du hardware dédié vers des solutions de type IaaS à la main. Je n'insisterais pas, mais lorsque je parle de Cloud je parle clairement de Plateforme as a Service.

le "Cloud" vu par de nombreuses sociétés en pleine mutation


Le dernier point, "délégation complète de la maintenance et du support", cher à CloudBees comme à Google AppEngine, est ce qui nous différencie de CloudFoundry et OpenShift. Nous considérons qu'il est la clé du concept même de Cloud, au delà de la virtualisation complète des ressources.

Mettre en place votre infra OpenStack est passionnant pour l'ingénierie, mais couteux en termes de formation des équipes de maintenance (voir ce témoignage). OpenStack ou autre est loin, très loin d'être une solution triviale, et s'assurer que l'hyperviseur est compatible et sera maintenu sur votre infra physique est une gageure. C'est d'ailleurs un nouveau marché pour les HP et autres Dell, de proposer du hardware labellisé pour ces usages.

La force d'amazon EC2 est justement le contrôle complet du hardware sur lequel tourne l'IaaS. La standardisation est la clé de la réduction de coût à grande échelle. Elle permet de monter rapidement de nouveaux services ou de blinder ceux qui existent, là ou des solutions ouvertes, malgré leur qualités indiscutables, s'imposent un gigantesque effort de suivi.

un exemple de standardisation : le hardware des datacenter Facebook

2. Private != Service

Installer la solution "private" de CloudPoireaux sur votre infra, c'est installer un soft; c'est du Platform-as-a-Software. C'est disposer d'une équipe infra à la hauteur. Nous avons l'habitude chez CloudBees de demander "produisez-vous votre propre électricité ?". Il y a un siècle, c'était le cas dans pas mal de grosses entreprises, avant que les tensions et la distribution se standardise et que la production ce concentre dans des usines spécialisées. L'informatique vit la même évolution. L'OS standard est un Linux sur architecture x86. L'étape qui suit est la concentration.

On évoque souvent des contraintes de sécurité. Ne croyez pas que CloudBees n'ait comme client que des start-ups, et que les banques et assurances nous boudent. 

La sécurité est un problème technique parfaitement géré. Le lancement d'Amazon Virtual Private Cloud est un signe: les clients d'Amazon sont de grosses, voir très grosses entités, qui déportent partiellement leur infra sur EC2. VPC leur assure une isolation techniquement sans appel.

amazon VPC : un bout de cloud dans votre réseau privé


Il reste ensuite le problème politique pour la direction IT de lâcher son emprise sur l'infra et évoluer vers un métier de niveau supérieur - le Cloud ne vous privant pas de boulot, avec d'intéressants challenges d'intégration de services. Problème de transformation interne que je vous laisse traiter :D

L'argument clé que nous avons chez CloudBees pour nos clients sceptiques c'est la mobilité. Certains de nos clients développent ainsi des applications mobiles pour leurs équipes sur le terrain. De fait, les données transitent déjà sur le réseau public. Le problème de la sécurité a donc forcément déjà été traité, reste à l'appliquer de manière plus globale. Amusant aussi de voire que ces mêmes entreprises ont leurs données client, données hautement stratégiques s'il en est, hébergées sur SalesForce, sans parler du commercial Microsoft qui se prépare à leur vendre du Office 365. De la politique donc.

3. Public Cloud + Private data = Hybrid 

L'hybridation private/public est une piste très prometteuse. En effet, le réel frein à la migration d'une société vers le Cloud est son coeur de métier, sa base d'information Oracle / SAP hébergée en interne et souvent volumineuse. Ces données ne migreront pas vers le Cloud, car cela impacterait trop d'applications legacy et le transfert de données auxquelles le SI accède en continu est délicat. 

Migrer un tel existant est à la fois techniquement et politiquement complexe. Inutile de commencer pas le plus difficile lorsqu'il existe des solutions simples et fiables de contournement.

L'hybridation entre des applications sur Cloud public, bénéficiant d'une plateforme standardisée, supportée, et élastique, couplée aux données privées via VPC/VPN, permet de mettre en place des solutions très élégantes avec un cycle de développement extrêmement court. 


un zorse (zébrule en bon français), hybride zèbre/jument à l'élégance rare :P

CloudBees propose depuis 2011 une solution hybride inverse, à savoir installer la base technique CloudBees sur votre IaaS privé (VMWare, OpenStack) tout en conservant le pilotage depuis le Cloud public cloudbees.com. Cette approche "AnyCloud" n'a pas révolutionné la donne à ce jour, entre autre parce qu'elle impose de disposer d'une équipe IaaS privée qui réduit sensiblement les bénéfices du Cloud, et qu'il manque alors à vos applications tout l'écosystème de service qui, eux, restent sur Amazon.

un zonkey (zébrâne), autre hybride sympathique



N'hésitez pas à me toper à l'occasion d'une conférence si vous voulez en discuter :)