Introduction à Apache Camel

1. Vue d'ensemble

Dans cet article, nous présenterons Camel et explorerons l'un de ses concepts fondamentaux: le routage des messages .

Nous commencerons par couvrir ces concepts fondamentaux et la terminologie, puis nous présenterons deux options principales pour définir les routes - Java DSL et Spring DSL.

Nous allons également les démontrer dans un exemple - en définissant une route qui consomme les fichiers d'un dossier et les déplace vers un autre tout en ajoutant un horodatage à chaque nom de fichier.

2. À propos d'Apache Camel

Apache Camel est un framework d'intégration open source conçu pour rendre l'intégration des systèmes simple et facile.

Il permet aux utilisateurs finaux d'intégrer divers systèmes à l'aide de la même API, en prenant en charge plusieurs protocoles et types de données, tout en étant extensible et en permettant l'introduction de protocoles personnalisés.

3. Dépendances de Maven

Pour utiliser Camel, nous devons d'abord ajouter la dépendance Maven:

 org.apache.camel camel-core 2.18.0 

La dernière version de l'artefact Camel peut être trouvée ici.

3. Langage spécifique au domaine

Les itinéraires et le moteur de routage sont la partie centrale de Camel. Les routes contiennent le flux et la logique d'intégration entre différents systèmes.

Afin de définir des itinéraires plus faciles et plus propres, Camel propose plusieurs langages spécifiques au domaine (DSL) pour les langages de programmation comme Java ou Groovy. D'autre part, il fournit également des routes de définition en XML avec Spring DSL.

L'utilisation de Java DSL ou de Spring DSL est principalement la préférence de l'utilisateur, car la plupart des fonctionnalités sont disponibles dans les deux.

Java DSL offre un peu plus de fonctionnalités qui ne sont pas prises en charge dans Spring DSL. Cependant, Spring DSL est parfois plus avantageux car XML peut être modifié sans qu'il soit nécessaire de recompiler le code.

4. Terminologie et architecture

Discutons maintenant de la terminologie et de l'architecture de base de Camel.

Tout d'abord, nous allons jeter un œil aux concepts de base de Camel ici:

  • Le message contient des données en cours de transfert vers une route. Chaque message a un identifiant unique et est construit à partir d'un corps, d'en-têtes et de pièces jointes
  • Exchange est le conteneur d'un message et il est créé lorsqu'un message est reçu par un consommateur pendant le processus de routage. Exchange permet différents types d'interaction entre les systèmes - il peut définir un message à sens unique ou un message de demande-réponse
  • Endpoint est un canal par lequel le système peut recevoir ou envoyer un message. Il peut faire référence à un URI de service Web, à un URI de file d'attente, à un fichier, à une adresse e-mail, etc.
  • Le composant agit comme une fabrique de points de terminaison. Pour faire simple, les composants offrent une interface à différentes technologies utilisant la même approche et la même syntaxe. Camel prend déjà en charge de nombreux composants dans ses DSL pour presque toutes les technologies possibles, mais il donne également la possibilité d'écrire des composants personnalisés
  • Processor est une interface Java simple utilisée pour ajouter une logique d'intégration personnalisée à une route. Il contient une méthode de processus unique utilisée pour préformer une logique métier personnalisée sur un message reçu par un consommateur

À un niveau élevé, l'architecture de Camel est simple. CamelContext représente le système d'exécution de Camel et il relie différents concepts tels que les itinéraires, les composants ou les points de terminaison.

Et en dessous, les processeurs gèrent le routage et les transformations entre les points de terminaison, tandis que les points de terminaison intègrent différents systèmes.

5. Définition d'un itinéraire

Les itinéraires peuvent être définis avec Java DSL ou Spring DSL.

Nous illustrerons les deux styles en définissant une route qui consomme les fichiers d'un dossier et les déplace dans un autre dossier tout en ajoutant un horodatage à chaque nom de fichier.

5.1. Routage avec Java DSL

To define a route with Java DSL we will first need to create a DefaultCamelContext instance. After that, we need to extend RouteBuilder class and implement the configure method which will contain route flow:

private static final long DURATION_MILIS = 10000; private static final String SOURCE_FOLDER = "src/test/source-folder"; private static final String DESTINATION_FOLDER = "src/test/destination-folder"; @Test public void moveFolderContentJavaDSLTest() throws Exception { CamelContext camelContext = new DefaultCamelContext(); camelContext.addRoutes(new RouteBuilder() { @Override public void configure() throws Exception { from("file://" + SOURCE_FOLDER + "?delete=true").process( new FileProcessor()).to("file://" + DESTINATION_FOLDER); } }); camelContext.start(); Thread.sleep(DURATION_MILIS); camelContext.stop(); }

The configure method can be read like this: read files from the source folder, processes them with FileProcessor and send the result to a destination folder. Setting delete=true means the file will be deleted from source folder after it is processed successfully.

In order to start Camel, we need to call start method on CamelContext. Thread.sleep is invoked in order to allow Camel the time necessary to move the files from one folder to another.

FileProcessor implements Processor interface and contains single process method which contains logic for modifying file names:

public class FileProcessor implements Processor { public void process(Exchange exchange) throws Exception { String originalFileName = (String) exchange.getIn().getHeader( Exchange.FILE_NAME, String.class); Date date = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy-MM-dd HH-mm-ss"); String changedFileName = dateFormat.format(date) + originalFileName; exchange.getIn().setHeader(Exchange.FILE_NAME, changedFileName); } }

In order to retrieve file name, we have to retrieve an incoming message from an exchange and access its header. Similar to that, to modify file name, we have to update message header.

5.2. Routing With Spring DSL

When defining a route with Spring DSL, we use an XML file to set up our routes and processors. This allows us to configure routes using no code by using Spring and ultimately, gives us the benefit of total inversion of control.

This was already covered in existing article, so we will focus on using both Spring DSL along with Java DSL, which is commonly a preferred way of defining routes.

In this arrangement, CamelContext is defined in Spring XML file using custom XML syntax for Camel, but without the route definition like in the case of “pure” Spring DSL using XML:

This way we tell Camel to use FileRouter class which holds the definition of our route in Java DSL:

public class FileRouter extends RouteBuilder { private static final String SOURCE_FOLDER = "src/test/source-folder"; private static final String DESTINATION_FOLDER = "src/test/destination-folder"; @Override public void configure() throws Exception { from("file://" + SOURCE_FOLDER + "?delete=true").process( new FileProcessor()).to("file://" + DESTINATION_FOLDER); } }

Pour tester cela, nous devons créer une instance de ClassPathXmlApplicationContext qui chargera notre CamelContext au printemps:

@Test public void moveFolderContentSpringDSLTest() throws InterruptedException { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("camel-context.xml"); Thread.sleep(DURATION_MILIS); applicationContext.close(); }

En utilisant cette approche, nous obtenons une flexibilité et des avantages supplémentaires fournis par Spring, ainsi que toutes les possibilités du langage Java en utilisant Java DSL.

6. Conclusion

Dans cet article rapide, nous avons présenté une introduction à Apache Camel et démontré les avantages de l'utilisation de Camel pour les tâches d'intégration telles que le routage de fichiers d'un dossier à un autre.

Dans notre exemple, nous avons vu que Camel vous permet de vous concentrer sur la logique métier et de réduire la quantité de code standard.

Le code de cet article est disponible à l'adresse over sur GitHub.