mardi 28 janvier 2014

[ESB open source] Introduction à Apache CAMEL (partie 1/6) : Problématique


Poste réalisé par Mohamed Karim LILI (Ingénieur logiciel confirmé à OXIA)


Prenez n’importe quel projet d’intégration et vous aurez plusieurs applications qui communiquent à travers plusieurs moyens de transport sur des plateformes totalement différentes. Rien qu’à lire cette phrase, vous aurez le tournis J

Comme vous pouvez l’imaginer, dans les applications des grandes entreprises (Editeurs, banques, assurances, etc..) ceci pourrait devenir complexe très rapidement.


La complexité en effet se résume en deux points essentiels :
  1.   Gérer les spécificités entre les applications et les moyens de transport.
  2.  Modéliser et implémenter les bonnes pratiques pour les solutions d’intégration.

Le fait de gérer la communication des applications ainsi que l’utilisation des différentes API de transport est relativement simple. N’importe quel développeur pourrait envoyer des messages JMS par exemple, bien que pour une bonne implémentation, cela nécessiterait une bonne connaissance de la spécification JMS (chose qui n’est pas évidente pour tout développeur). Qu’en est-il alors si vous voulez router ce message JMS à une destination spécifique, qui elle, réalisera d’autres traitements ? Vous devez alors prendre soin de bien mapper le message JMS et gérer les nouveaux concepts de la nouvelle application cible. Si vous y ajouter d’autres applications, cela deviendrait alors un vrai casse-tête.

Faisons abstraction des problématiques d’échange de message et de transport, et focalisons-nous plutôt sur la modélisation de l’interaction entre différentes applications d’entreprise. Heureusement, plusieurs solutions d’intégration ont été formalisées  dans le livre : « Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions, » de  Gregor Hohpe and Bobby Woolfe suite à une expérience de dizaines d’années dans l’architecture des applications d’entreprise dans une collection de 65 Entreprise Integration Pattern (EIP) 
Patrons de conception d’intégration. l’EAI (Enterprise Application Integration) nous livre tout le savoir, les bonnes pratiques et les moyens technologiques qui servent à créer des solutions d'intégration extensibles et entretenues en mode productif. Ceci constitue un énorme travail, sauf que nous avons encore besoin d’implémenter nous-mêmes ces patterns, car ils ne sont d’autres que des recommandations et non des solutions clés en main.
Apache Camel a été créé dans le but de répondre à ces deux problématiques.

[ESB open source] Introduction à Apache CAMEL (partie 2/6) : Qu’est ce que « Apache Camel » ?


Poste réalisé par Mohamed Karim LILI (Ingénieur logiciel confirmé à OXIA)

Apache Camel est une librairie java open source d’intégration (liberal Apache 2 license), c’est un framework léger qui permet à vos applications de réaliser un  routage intelligent, la transformation de messages, et qui représente un protocole de médiation utilisant les EIP (Entreprise Integration Patterns) avec un large panel de composants prêts à l’utilisation et une DSL (Domain Specific Language) hautement expressive et robuste (en 3 types : Java, XML (Spring based), Scala)..

Au cœur du framewok Camel existe un moteur de routage, ou plus exactement un Routing engine builder. Il vous permet de définir vos propres règles de routage, de décider à partir de quelle source accepter les messages d’entrée, et de déterminer comment les traiter et enfin d’envoyer ces messages transformés vers d’autres destinations. Camel utilise un langage d’intégration qui vous permet de définir des règles de routage complexes qui vont jusqu’au processus métier.
Un des principes fondamentaux de Camel est qu’il n’exige aucun format spécifique de données à intégrer, ce qui vous laisse à vous, développeur, une opportunité d’intégrer n’importe quel type de système, sans avoir besoin de convertir vos données en un format « canonique ».
Nous devons aussi préciser que Camel n’est pas un ESB (Entreprise Service Bus), bien que certains le décrivent comme un ESB léger pour son support au routage, la transformation et le monitoring, ainsi que l’orchestration. Camel n’a pas de conteneur ou un message-bus fiable, mais il peut être déployé dans un ESB, comme Open-ESB ou ServiceMix. Pour cette raison, on préfère appeler Camel un « framework d’intégration » plutôt qu’un ESB.


Pourquoi utiliser Apache Camel ?

Camel introduit de nouvelles idées dans le monde de l’intégration, c’est pour cela que les auteurs de Camel ont décidé de le créer au lieu d’utiliser un framework existant.
Parmi les concepts clés de Camel :
  • Routing and mediation engine
  • Enterprise integration patterns (EIPs)
  • Domain-specific language (DSL)
  • Extensive component library
  • Payload-agnostic router
  • Modular and pluggable architecture
  • POJO model
  • Easy configuration
  • Automatic type converters
  • Lightweight core
  • Test kit
  • Vibrant community

[ESB open source] Introduction à Apache CAMEL (partie 3/6) : Comment fonctionne Camel ?

Nous avons vu que Camel se focalise sur la tâche qui consiste à rendre le travail de l’intégration le plus simple possible, ce qui pourrait se matérialiser dans les 3 points suivants :
·         Une implémentation concrète des EIP (Entreprise Integration Pattern) les plus utilisés.
·         Une connectivité à une grande variété de canaux de transports et d’APIs
·         Une DSL (Domain Specific Languauge) facile à utiliser pour relier les EIP et les moyens de transport ensemble.
Afin d’avoir une idée sur l’organisation de Camel, nous allons étudier son architecture :
Sur une vue d’ensemble, Camel est constitué de processeurs (Processors), de composants (Components) et de routes (Routes). Tous ces constituants sont contenus dans le CamelContext comme le montre la figure ci-dessous :



Le moteur de routage utilise les « Routes » comme spécification pour router les différents messages. Les « routes » sont définies en utilisant l’un des différents langages DSL Camel (Domain Specific Language).
Les Processors sont utilisés pour transformer et manipuler les messages durant le routage et aussi pour implémenter tout type de pattern EIP, qui ont des mots clé correspondants dans la DSL Camel.
Les composants (Components) sont les points d’extension de Camel pour ajouter de la connectivité à d’autres systèmes. Afin d’exposer ces systèmes au reste de Camel, les « Component » fournissent une interface Endpoint.
Voici le schéma d’une route « simple » qui reçoit en entrée un document XML et le guide selon une condition vers deux destinations système différentes :




[ESB open source] Introduction à Apache CAMEL (partie 4/6): Le modèle message de Camel (Camel Message model)


Poste réalisé par Mohamed Karim LILI (Ingénieur logiciel confirmé à OXIA)

Dans Camel, il y a deux abstractions pour modéliser les messages :
  1.            org.apache.camel.Message : L’entité fondamentale qui contient les données transportées et routées dans Camel.
  2.           org.apache.camel.Exchange : l’abstraction Camel pour l’échange de messages. Cet échange de messages a un message « IN » et en guise de réponse, un message « OUT »


Message

Les messages «(Message) sont des entités utilisées par les systèmes pour communiquer entre eux en utilisant des chaînes de communications (Messaging channels). Les messages transitent suivant une direction : à partir d’une source vers une destination (receiver) :


L’entité « Message » possède un Body (qui contient les données payload), un header et une partie « Attachements », ceci est illustré dans la figure suivante :

Les messages possèdent un identifiant unique avec un identifiant de type java.lang.String généré par le protocole utilisé et n’a pas de format garanti. Pour les protocoles n’ayant pas de système d’identification unique, Camel utilise son propre générateur UID.
Le « Header » content des valeurs associées au message, comme l’identifiant de l’émetteur (sender), des données sur l’encodage, les informations d’authentification, etc. Les Headers sont des entités clé-valeur, la clé est unique et est un String sensible à la casse, et la valeur est de type java.lang.Object, les headers sont stockés dans une Map au sein du message.
Un message peut aussi contenir des « Attachments » qui sont typiquement utilisés pour les web services et les composants email.
Le Body est de type java.lang.Object, ce qui voudrait dire que le message peut sauvegarder n’importe quel type de données. Lorsque la source et le récepteur utilisent des formats de données différents, Camel offre un large choix de mécanismes pour transformer les données dans un format acceptable, qui dans la plupart des cas est converti  en coulisses par Camel en utilisant ses propres converters Embedded.

Exchange 

L’Exchange est le conteneur Camel du message durant le routage. C’est un support pour les différents types d’interaction entre les systèmes, plus connu sous le nom de MEP (Message exchange Pattern). Les MEPs sont utilisés pour différencier entre les « one-way » et les « request-response » styles de messages.
L’exchange Camel peut ainsi être :
·         InOnly : un « one-way » message (Event message), par exemple : les messages JMS sont des messages « one way »
·         InOut : Ce sont des messages « request-response », par exemple, les messages http sont souvent des messages request reply dans lesquels le client demande à trouver une page web, en attendant la réponse du serveur.
Ci-dessous un schéma expliquant l’architecture d’un Exchange :



[ESB open source Camel ] Introduction à Apache CAMEL (partie 5/6) : Le DSL Camel (Domain Specific Language)


Poste réalisé par Mohamed Karim LILI (Ingénieur logiciel confirmé à OXIA)


   Afin de relier les processors et les components 
ensemble pour former les routes, Camel définit un langage DSL.

Il existe 3 types de DSL dans Camel, c’est à votre choix d’utiliser l’une d’entre elles :


Dans les trois exemples ci-dessus, nous définissons une route qui va charger des fichiers d’un répertoire « /tmp » dans la mémoire, créer un nouveau message JMS qui aura comme contenu le contenu du fichier chargé auparavant et l’envoyer à ue Queue JMS nommée « aQueue ».

[ESB open source] Introduction à Apache CAMEL (partie 6/6) : tutorial CAMEL


Poste réalisé par Mohamed Karim LILI (Ingénieur logiciel confirmé à OXIA)


Dans cet exemple (tiré du livre Camel in Action), nous créons un scénario qui consiste à copier un fichier d’un répertoire source vers un répertoire destination. 

De ce fait, nous allons comparer l’approche Java classique avec l’approche Camel en créant une route qui se charge de charger un fichier XML à partir d’un emplacement spécifique et de le copier vers un répertoire cible.

Commençons par lee fichier POM.xml du projet Maven (sans compter la partie pluginManagement maven):


Ensuite, on crée le deux fichiers java correspondants : FileCopier.java et le fichier FileCopierWithCamel.java :

FileCopier.java :
/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package camelinaction;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class FileCopier {

    public static void main(String args[]) throws Exception {
        File inboxDirectory = new File("data/inbox");
        File outboxDirectory = new File("data/outbox");
       
        outboxDirectory.mkdir();
       
        File[] files = inboxDirectory.listFiles();
        for (File source : files) {
            if (source.isFile()) {
                File dest = new File(
                        outboxDirectory.getPath()
                        + File.separator
                        + source.getName());
                copyFile(source, dest);
            }
        }
    }
   
    private static void copyFile(File source, File dest)
        throws IOException {
        OutputStream out = new FileOutputStream(dest);
        byte[] buffer = new byte[(int) source.length()];
        FileInputStream in = new FileInputStream(source);
        in.read(buffer);
        try {
            out.write(buffer);
        } finally {
            out.close();     
            in.close();
        }
    }
}

Et le fichier FileCopierWithCamel.java :

/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package camelinaction;

import org.apache.camel.CamelContext;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;


public class FileCopierWithCamel {

    public static void main(String args[]) throws Exception {
        // create CamelContext
        CamelContext context = new DefaultCamelContext();

        // add our route to the CamelContext
        context.addRoutes(new RouteBuilder() {
            public void configure() {
                from("file:data/inbox?noop=true").to("file:data/outbox");
            }
        });

        // start the route and let it do its work
        context.start();
        Thread.sleep(10000);

        // stop the CamelContext
        context.stop();
    }
}

Bien entendu, n’oubliez pas de configurer le fichier « log4j.properties » sous « src/main/resources » et de créer un répertoire « data/inbox » à la racine du projet qui contient le fichier XML suivant qu’on nommera par exemple « message1.xml » :

xml version="1.0" encoding="UTF-8"?>
name="motor" amount="1" customer="honda"/>

Architecte SOA & Professionnel Open Source Headline Animator

 
Khaled BEN DRISS
Cloud Computing, SOA et Web 2.0 : Des sujets techniques sur SOA et l'Open Source : de Java & .Net, PHP5, Symfony, à SaaS / PaaS en passant par Azure, google appengine, le BPM, la Modélisation et d'autres sujets du coté du serveur et cloud computing.