Agilité, Développement Java, Nouvelles technologies et plus…
  • rss
  • Accueil
  • Management
  • Programmation agile
  • Technologie
  • Linux
  • Evénement
  • App Android
  • Contact
  • A propos de l'auteur
  • English
  • Francais

Une première approche du Camel d’Apache

Fabian Piau | vendredi 11 mai 2012 - 09:05
  • Imprimer
  • Twitter
  • LinkedIn
  • Facebook
  • Pocket

 English version available

Remarque
Pour en savoir plus sur Camel, vous pouvez lire un extrait gratuit du chapitre 1 du livre « Camel in Action », le livre de référence de ce framework (en anglais).

Raphaël Delaporte (@rafdelaporte) nous a proposé de dompter un chameau cette semaine au JUG Nantes.

Photo chameau

Et ne vous fiez pas à cette photo ! Notre chameau d’informaticien n’est pas un paresseux, bien au contraire ! Retour sur une présentation forte intéressante d’Apache Camel.

Logo Apache Camel

Apache Camel s’appuie et reprend les Entreprise Integration Patterns – EIP (à ne pas confondre avec les Design Patterns qui sont utilisés pour la conception objet).


Les patterns EIP

Voici les principaux patterns du plus simple au plus complexe (extrait de la présentation).

Entreprise Integration Patterns

Entreprise Integration Patterns

En les combinant, les possibilités sont quasi-infinies. Vous trouverez la liste des Patterns implémentés dans Camel sur le site officiel du framework.

Un livre complet sur le sujet existe « Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions ». L’auteur n’est autre que le créateur de ce concept, autant dire que c’est la référence dans ce domaine.


Faire des EIP avec Apache Camel

Pour mettre en oeuvre les EIP, on trouve trois éléments de base dans Camel :

  • Route
  • Processor
  • Endpoint (dans la littérature française, le terme est parfois traduit par « point d’extrémité »)

Une route est conceptualisée de la manière suivante : la liaison de deux endpoints par un processor. Ainsi, nous avons un endpoint de départ et un endpoint de fin, un endpoint est associé à une ressource. Une route symbolise un traitement plus ou moins complexe en fonction du traitement voulu (processor) et de l’EIP choisi.

Pour répondre au besoin, on peut imbriquer les routes, les chainer, appliquer des traitements différents tout au long de la route, etc.


Dans Apache Camel, la définition de routes peut se faire de deux manières :

  • Soit en utilisant le langage Java (domain specific language – DSL). Apache Camel fournit une API. Très pratique pour l’autocomplétion dans l’IDE.
  • Soit en utilisant le langage XML. Plus verbeux donc un peu moins lisible et finalement un peu moins pratique. Avec Camel, on préconise l’utilisation du DSL lorsque les routes sont complexes.

Dans la suite, nous privilégierons donc l’écriture en code Java. Dans tous les cas, un minimum de code XML est nécessaire pour la configuration de Camel (le contexte Camel, les sources de données, etc.).

Voici un exemple de route :

import org.apache.camel.builder.RouteBuilder;

public class MyFirstRoute extends RouteBuilder {
    @Override
    public void configure() thwrows Exception {
        // Ma première route
        from('file:/Users/fabian/src').to('file:/Users/fabian/dest').end();

        // D'autres routes peuvent être définies
        // ...
    }
}

Le mot clé .end() n’est pas obligatoire, mais il est conseillé pour bien délimiter les routes et permettre de s’y retrouver (maintenabilité). Dans cet exemple, le traitement est très simple et il n’y a qu’une seule route, il n’est pas vraiment indispensable.



La présentation était ponctuée de nombreuses démos. A partir d’un projet Maven bien configuré (dépendances Spring, Camel, contextes…), Raphaël nous a montré quelques cas d’utilisation écoles :

  • Déplacer les fichiers d’un répertoire à un autre (il s’agit du bout de code ci-dessus). Tous les fichiers créés dans le répertoire src seront déplacés dans le répertoire dest. Cette route s’écrit en une ligne, témoignant de la puissance d’un tel outil.
  • Créer des fichiers correspondants à chaque message poolé dans une queue JMS. Pour la présentation, Raphaël a utilisé Apache ActiveMQ, un message broker JMS. Ce cas illustre le pattern Splitter.
  • Transférer des messages JMS vers une queue en fonction de leurs contenus. Ce cas illustre le pattern Content-based Router.
  • La route est la suivante, en supposant que queue.in existe dans ActiveMQ et qu’on y poole des messages :

    import org.apache.camel.builder.RouteBuilder;
    
    public class MyContentBasedRoute extends RouteBuilder {
        @Override
        public void configure() thwrows Exception {
            from('amq:queue.in')
                .choice()
                    .when(header('JMSCorrelationID').isEqualTo('nantes'))
                        .to('amq:queue.nantes')
                    .when(header('JMSCorrelationID').isEqualTo('rennes'))
                        .to('amq:queue.rennes')
                    .otherwise()
                        .to('amq:queue.others')
            .end();
        }
    }
    

    Depuis la console d’admin d’ActiveMQ, on crée quelques messages de test avec les différents cas possibles. En fonction de son header, le message est routé vers la bonne queue.

    Il est possible de chainer des prédicats avec les opérateurs logiques habituels afin de créer des critères de routage plus complexe. Ici, le prédicat est simple et se base seulement sur le header du message. On aurait pu également se baser sur le body pour faire un routage plus fin des messages.

  • Créer des messages JMS à partir du contenu d’un fichier XML. Ce cas illustre le pattern Dynamic Router.
  • Voici le contenu du fichier messages_jug.xml :

    <jug>
        <nantes>Hello from Nantes</nantes>
        <paris>Hello from Paris</paris>
        <rennes>Hello from Rennes</nantes>
        <nantes>Hello again from Nantes</nantes>
        <paris>Hello again from Paris</paris>
        [...]
    </jug>
    

    Avec Camel, on veut extraire les différents messages pour les envoyer dans une queue.

    Voici le code de la route correspondante :

    import org.apache.camel.builder.RouteBuilder;
    
    public class MyDynamicRoute extends RouteBuilder {
        @Override
        public void configure() thwrows Exception {
            from('files:/Users/fabian/src/messages_jug.xml')
                .split(xpath('/jug/child::*'))
            .to('amq:queue.jugs');
        }
    }
    

    On aurait pu router vers un autre fichier en filtrant sur les messages de Nantes. Les possibilités sont multiples.


    Optimisations Camel

    On peut se poser le problème de l’indisponibilité… Que se passe-t’il dans le cas du traitement d’un message si la machine crashe et n’a pas le temps de router le message ? Malheureusement, vous perdez le message ! Celui-ci a été consommé dans la queue de départ, mais n’a jamais pu atteindre sa destination. La solution est de passer la route en mode transactionnel. Cela se fait en ajoutant .transacted() juste après le .from(...) et en prenant soin d’indiquer à votre source JMS de se mettre en mode transactionnel (configuration XML).

    On peut aussi noter que, par défaut, le traitement est monothread. Une amélioration est d’activer la parallélisation sur le processor (ici split) en ajoutant l’option .parallelProcessing() juste après le .split(...).

    Nous avons parlé de file et de jms, mais les composants disponibles dans Camel sont légion grâce à une communauté très active. Cette page recense l’ensemble des composants disponibles. Citons jdbc, ftp, gmail, atom, pop, imap entres autres.


    Faire des EIP avec Spring Integration

    Raphaël nous a parlé de Spring Integration, une alternative à Camel. Spring Integration ne laisse pas le choix à l’utilisateur et s’utilise avec la notation XML exclusivement.

    D’après Raphaël, il s’intègre mieux avec Spring Batch, mais l’objectif n’était pas de juger les deux outils. Chacun a ses avantages et ses inconvénients.

    Voici l’exemple du transfert des fichiers d’un répertoire à un autre, cette fois écrit avec Spring Integration :

    <channel id='myFirstChannel' />
    
    <file:inbound-channel-adapter id='filesIn'
            channel='myFirstChannel'
            directory='file:/Users/fabian/src' />
    
    <file:outbound-channel-adapter id='filesOut'
            channel='myFirstChannel'
            directory='files:/Users/fabian/dest' />
    

    La notion de route n’est pas présente, on parle de channel. Une channel relie deux composants. On se rapproche clairement de la philosophie de Spring qui place la notion de composant au centre. Des composants que l’on injecte et que l’on relie entre eux (et c’est logique puisqu’il s’agit du même éditeur SpringSource).

    En fait, le terme route n’est utilisé que par Camel. Spring Integration est plus fidèle aux concepts des EIP en utilisant des termes similaires comme channel.

    Autre différence, la channel apparait concrètement dans Spring Integration alors que la route dans Camel est implicite (pas de mot-clé route()). Si on reprend notre première route :

    from('file:/Users/fabian/src').to('file:/Users/fabian/dest');
    

    La route est symbolisée par le « . » entre les deux endpoints. Il n’est pas possible de la configuer. A ce niveau, Spring Integration est un peu plus poussé avec la possibilité de configurer le type de channel notamment.

    Articles similaires

    springQCon London 2016 – Spring Framework 5 – Preview et Roadmap Java 11Une migration Java 11 réussie devoxxDevoxx UK 2018 – Jour 2 Java EE vs SpringJava EE & CDI vs. Spring
Catégories
Programmation agile
Tags
camel, eip, entreprise integration pattern, jug
Flux rss des commentaires
Flux rss des commentaires

« Ce fichier est actuellement utilisé… Merci Windows ! Open Street Map, une meilleure carte que Google Maps? »

Télécharger l'app CarmaBlog

Flux RSS

  • Flux RSS RSS - Articles
  • Flux RSS RSS - Commentaires

Articles les plus vus

  • Changer la langue de Firefox - 115 579 vues
  • Réaliser un sondage en ligne avec Google Forms / Drive / Docs - 63 166 vues
  • FAQ – Sondage en ligne avec Google Forms / Drive / Docs - 52 403 vues
  • Personnaliser Gnome 3 (Shell) - 30 017 vues
  • La signification d’URL, URI et URN - 17 251 vues
  • Java EE & CDI vs. Spring - 15 442 vues
  • Open Street Map, une meilleure carte que Google Maps? - 14 648 vues
  • Comparaison NoSQL: Couchbase et MongoDB - 14 082 vues
  • Firefox Nightly, Aurora, Beta, Desktop, Mobile, ESR & Co. - 13 087 vues
  • API, REST, JSON, XML, HTTP, URI… Vous parlez quelle langue en fait? - 12 718 vues

Commentaires récents

  • Pauline sur FAQ – Sondage en ligne avec Google Forms / Drive / DocsMerci Fabian, mais le but étant que nos clients pu…
  • Fabian Piau sur FAQ – Sondage en ligne avec Google Forms / Drive / DocsProbablement mais ces options sont en général paya…
  • Pauline sur FAQ – Sondage en ligne avec Google Forms / Drive / DocsBonjour Fabian, Merci de votre retour, oui j'avais…
  • Fabian Piau sur FAQ – Sondage en ligne avec Google Forms / Drive / DocsBonjour Pauline, ce n'est pas possible de créer un…
  • Pauline sur FAQ – Sondage en ligne avec Google Forms / Drive / DocsBonjour, Je suis en train de créer un Google Forms…

Articles récents

  • Comment écrire un article de blog? En tout cas à ma façon! - Il y a 3 mois et 2 semaines
  • Attaques de robots: vous n’êtes pas seul… - Il y a 1 an et 11 mois
  • Flagger – Monitorer vos déploiements Canary avec Grafana - Il y a 2 ans et 8 mois
  • Flagger – Déploiements Canary sur Kubernetes - Il y a 2 ans et 10 mois
  • Flagger – Premiers pas avec Istio et Kubernetes - Il y a 2 ans et 10 mois
  • CoderDojo Expedia à Londres - Il y a 3 ans et 7 mois
  • Etre bénévole à Devoxx4Kids - Il y a 3 ans et 10 mois
  • Une migration Java 11 réussie - Il y a 4 ans et 2 mois
  • Conseils pour sécuriser votre site WordPress - Il y a 4 ans et 5 mois
  • Devoxx UK 2018 – Jour 2 - Il y a 4 ans et 9 mois
  • Devoxx UK 2018 – Jour 1 - Il y a 4 ans et 9 mois
  • Wise, Revolut et Monzo, une petite révolution dans le monde des expatriés et voyageurs - Il y a 5 ans et 1 mois
  • Autocomplétion pour Git - Il y a 5 ans et 10 mois
  • Swagger, la documentation API automatisée - Il y a 6 ans et 2 semaines
  • Architecture Microservices – Les bonnes pratiques - Il y a 6 ans et 5 mois
Offre moi un café

Langue

  • Français
  • English

Suivez-moi!

Suivez-moi sur Linkedin
Suivez-moi sur Twitter
Suivez-moi sur Stackoverflow
Suivez-moi sur Github
Suivez-moi sur Rss
Link to my Contact

Abonnement email

Saisissez votre adresse email pour être informé des nouveaux articles.

Étiquettes

.net agile agilité android bash blog bonnes pratiques cache cloud conférence css devoxx docker développeur eclipse extreme programming firefox flagger google helm hibernate informatique intégration continue istio java jug kubernetes londres mobilité informatique métier outil panorama partage performance plugin programmeur script société spring sécurité tdd test ubuntu windows wordpress

Liens

  • Blog Ippon Technologies
  • Blog Publicis Sapient
  • Blog Zenika
  • Classpert
  • CommitStrip
  • Coursera
  • Le Touilleur Express
  • Les Cast Codeurs Podcast
  • OCTO talks !
  • The Twelve-Factor App

Catégories

  • Evénement (15)
  • Linux (3)
  • Management (8)
  • Programmation agile (29)
  • Technologie (45)

Archives

  • décembre 2022 (1)
  • avril 2021 (1)
  • juin 2020 (1)
  • mai 2020 (2)
  • juillet 2019 (1)
  • mai 2019 (1)
  • décembre 2018 (1)
  • octobre 2018 (1)
  • juin 2018 (1)
  • mai 2018 (1)
  • janvier 2018 (1)
  • mai 2017 (1)
  • mars 2017 (1)
  • octobre 2016 (1)
  • avril 2016 (2)
  • mars 2016 (1)
  • novembre 2015 (1)
  • mai 2015 (1)
  • février 2015 (1)
  • décembre 2014 (1)
  • novembre 2014 (1)
  • septembre 2014 (2)
  • août 2014 (1)
  • juillet 2014 (2)
  • juin 2014 (1)
  • avril 2014 (1)
  • mars 2014 (1)
  • février 2014 (2)
  • janvier 2014 (1)
  • décembre 2013 (1)
  • novembre 2013 (1)
  • octobre 2013 (3)
  • septembre 2013 (5)
  • juillet 2013 (1)
  • juin 2013 (1)
  • mai 2013 (1)
  • avril 2013 (1)
  • mars 2013 (2)
  • février 2013 (1)
  • janvier 2013 (2)
  • décembre 2012 (2)
  • octobre 2012 (1)
  • septembre 2012 (1)
  • juillet 2012 (1)
  • mai 2012 (1)
  • avril 2012 (1)
  • mars 2012 (1)
  • février 2012 (1)
  • janvier 2012 (2)
  • décembre 2011 (1)
  • novembre 2011 (2)
  • octobre 2011 (2)
  • septembre 2011 (1)
  • juillet 2011 (1)
  • juin 2011 (2)
  • avril 2011 (1)
  • mars 2011 (1)
  • février 2011 (1)
  • janvier 2011 (2)
  • novembre 2010 (2)
  • septembre 2010 (1)
  • août 2010 (1)
  • juillet 2010 (1)
  • juin 2010 (1)
  • mai 2010 (1)
  • avril 2010 (1)
  • mars 2010 (1)
  • février 2010 (1)
  • décembre 2009 (1)
  • novembre 2009 (1)
  • octobre 2009 (2)
  • septembre 2009 (2)
  • août 2009 (3)
  • juillet 2009 (1)
  • juin 2009 (2)
Suivez-moi sur Twitter
Suivez-moi sur Linkedin
Suivez-moi sur Stackoverflow
Suivez-moi sur Rss
Link to my Contact
Suivez-moi sur Github
 
Fabian Piau | © 2009 - 2023
Tous droits réservés | Haut ↑