Introduzione ad Apache Camel

1. Panoramica

In questo articolo, introdurremo Camel ed esploreremo uno dei suoi concetti fondamentali: il routing dei messaggi .

Inizieremo coprendo questi concetti fondamentali e la terminologia e quindi presenteremo due opzioni principali per la definizione delle rotte: Java DSL e Spring DSL.

Li dimostreremo anche in un esempio, definendo un percorso che consuma i file da una cartella e li sposta in un'altra anteponendo un timestamp a ciascun nome di file.

2. Informazioni su Apache Camel

Apache Camel è un framework di integrazione open source progettato per rendere l'integrazione dei sistemi semplice e facile.

Consente agli utenti finali di integrare vari sistemi utilizzando la stessa API, fornendo supporto per più protocolli e tipi di dati, pur essendo estensibile e consentendo l'introduzione di protocolli personalizzati.

3. Dipendenze di Maven

Per poter utilizzare Camel, dobbiamo prima aggiungere la dipendenza Maven:

 org.apache.camel camel-core 2.18.0 

L'ultima versione del manufatto Camel può essere trovata qui.

3. Lingua specifica del dominio

I percorsi e il motore di routing sono la parte centrale di Camel. I percorsi contengono il flusso e la logica di integrazione tra diversi sistemi.

Al fine di definire percorsi più facili e puliti, Camel offre diversi linguaggi specifici del dominio (DSL) per linguaggi di programmazione come Java o Groovy. D'altra parte, fornisce anche la definizione di percorsi in XML con Spring DSL.

L'utilizzo di Java DSL o Spring DSL è principalmente la preferenza dell'utente, poiché la maggior parte delle funzionalità sono disponibili in entrambi.

Java DSL offre un po 'più di funzionalità che non sono supportate in Spring DSL. Tuttavia, Spring DSL a volte è più vantaggioso in quanto XML può essere modificato senza la necessità di ricompilare il codice.

4. Terminologia e architettura

Parliamo ora della terminologia e dell'architettura di base di Camel.

Per prima cosa, daremo uno sguardo ai concetti fondamentali di Camel qui:

  • Il messaggio contiene dati che vengono trasferiti a una rotta. Ogni messaggio ha un identificatore univoco ed è costituito da un corpo, intestazioni e allegati
  • Exchange è il contenitore di un messaggio e viene creato quando un messaggio viene ricevuto da un consumatore durante il processo di instradamento. Exchange consente diversi tipi di interazione tra i sistemi: può definire un messaggio unidirezionale o un messaggio di richiesta-risposta
  • L'endpoint è un canale attraverso il quale il sistema può ricevere o inviare un messaggio. Può fare riferimento a un URI di un servizio Web, un URI di coda, un file, un indirizzo e-mail, ecc
  • Il componente funge da fabbrica di endpoint. Per dirla semplicemente, i componenti offrono un'interfaccia a diverse tecnologie utilizzando lo stesso approccio e la stessa sintassi. Camel supporta già molti componenti nei suoi DSL per quasi tutte le tecnologie possibili, ma offre anche la possibilità di scrivere componenti personalizzati
  • Il processore è una semplice interfaccia Java che viene utilizzata per aggiungere una logica di integrazione personalizzata a un percorso. Contiene un unico metodo di processo utilizzato per preformare la logica aziendale personalizzata su un messaggio ricevuto da un consumatore

Ad un livello elevato, l'architettura di Camel è semplice. CamelContext rappresenta il sistema di runtime Camel e collega diversi concetti come rotte, componenti o endpoint.

Inoltre, i processori gestiscono il routing e le trasformazioni tra gli endpoint, mentre gli endpoint integrano sistemi diversi.

5. Definizione di una rotta

I percorsi possono essere definiti con Java DSL o Spring DSL.

Illustreremo entrambi gli stili definendo un percorso che consuma i file da una cartella e li sposta in un'altra cartella anteponendo un timestamp a ciascun nome di file.

5.1. Instradamento con Java DSL

Per definire un percorso con Java DSL dovremo prima creare un'istanza DefaultCamelContext . Dopodiché, dobbiamo estendere la classe RouteBuilder e implementare il metodo configure che conterrà il flusso del percorso:

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(); }

Il metodo di configurazione può essere letto in questo modo: leggere i file dalla cartella di origine, elaborarli con FileProcessor e inviare il risultato a una cartella di destinazione. L'impostazione di delete = true significa che il file verrà eliminato dalla cartella di origine dopo essere stato elaborato correttamente.

Per avviare Camel, dobbiamo chiamare il metodo di avvio su CamelContext . Thread.sleep viene richiamato per dare a Camel il tempo necessario per spostare i file da una cartella all'altra.

FileProcessor implementa l' interfaccia del processore e contiene un metodo di processo singolo che contiene la logica per la modifica dei nomi dei file:

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); } }

Per recuperare il nome del file, dobbiamo recuperare un messaggio in arrivo da uno scambio e accedere alla sua intestazione. Allo stesso modo, per modificare il nome del file, dobbiamo aggiornare l'intestazione del messaggio.

5.2. Routing con Spring DSL

Quando definiamo una rotta con Spring DSL, utilizziamo un file XML per impostare le nostre rotte e processori. Questo ci consente di configurare rotte senza utilizzare codice utilizzando Spring e, in definitiva, ci offre il vantaggio di una totale inversione di controllo.

Questo è già stato trattato nell'articolo esistente, quindi ci concentreremo sull'utilizzo sia di Spring DSL che di Java DSL, che è comunemente un modo preferito per definire i percorsi.

In questa disposizione, CamelContext è definito nel file XML Spring utilizzando la sintassi XML personalizzata per Camel, ma senza la definizione del percorso come nel caso del DSL Spring "puro" che utilizza XML:

In questo modo diciamo a Camel di utilizzare la classe FileRouter che contiene la definizione del nostro percorso 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); } }

Per testarlo, dobbiamo creare un'istanza di ClassPathXmlApplicationContext che caricherà il nostro CamelContext in primavera:

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

Utilizzando questo approccio, otteniamo ulteriore flessibilità e vantaggi forniti da Spring, così come tutte le possibilità del linguaggio Java utilizzando Java DSL.

6. Conclusione

In questo rapido articolo, abbiamo presentato un'introduzione ad Apache Camel e dimostrato i vantaggi dell'utilizzo di Camel per attività di integrazione come l'instradamento dei file da una cartella all'altra.

Nel nostro esempio, abbiamo visto che Camel ti consente di concentrarti sulla logica aziendale e riduce la quantità di codice standard.

Il codice di questo articolo può essere trovato su GitHub.