Você está na página 1de 76

Abimael Desales Lpez Java Developers Mexico www.facebook.

com/JavaDevelopersMexico

Endpoints
Un endpoint es una abstraccin que modela el extremo de un canal de mensaje a travs del cual un sistema puede enviar o recibir mensajes. En primer lugar vamos a ver cmo se pueden usar las URIs para configurar Camel para comunicar sobre FTP y JMS, los cuales son dos de los protocolos de transporte ms usados.

Trabajando con archivos sobre FTP


Una de las cosas que hace a Camel fcil de comprender es la URI del endpoint. Especificando una URI, puedes identificar el componente que quieres usar y cmo ese componente est configurado. Puedes decidir entonces ya sea enviar mensajes al componente configurado por esta URI, o consumir mensajes de l. Para comprender de una manera ms clara, se ilustrarn los conceptos a travs de un ejemplo: Auto Partes Rider, un negocio de partes de motocicletas ficticio, que provee partes a fabricantes de motocicletas.

Al paso de los aos, han cambiado la forma en que reciben rdenes varias veces. Inicialmente colocaban rdenes cargando archivos de valores separados por comas (CSV) a un servidor FTP. El formato de mensaje fue cambiado a la postre a XML. Actualmente proporcionan un sitio web a travs del cual las rdenes son emitidas como mensajes XML sobre HTTP. Auto Partes Rider solicita a los nuevos clientes usar la interfaz web para colocar las rdenes, pero debido a los SLAs con los clientes existentes, deben mantener todos los formatos e interfaces de mensajes viejos en funcionamiento.

Todos estos mensajes son convertidos a un formato POJO antes de ser procesado. En la siguiente figura se muestra una lista de alto nivel del sistema de procesamiento de rdenes.

Fig. 1. Un cliente tiene dos formas de emitir rdenes al sistema de manejo de rdenes Auto Partes Rider: ya sea cargando el archivo de rdenes plano a un servidor FTP o emitiendo una orden a travs de la tienda web de Auto Partes Rider. Eventualmente todas las rdenes son enviadas va JMS para procesarlas en Auto Partes Rider.

Como una primera asignacin, necesitars implementar el mdulo FTP en el sistema frontend de rdenes de Rider. Implementar el mdulo FTP involucrar los siguientes pasos: Votear en el FTP server y descargar nuevas rdenes 2. Convertir los archivos de rdenes a mensajes JMS 3. Enviar el mensaje a la queue JMS incomingOrdenes
1.

Para descargar nuevas rdenes del servidor FTP, necesitas hacer lo siguiente: 1. Conectar al servidor FTP rider.com en el puerto FTP default de 21 2. Proporcionar un username de rider y password de secret 3. Cambiar el directorio a ordenes 4. Descargar cualesquiera archivos de rdenes nuevas

Camel buscar primero el esquema ftp en el registro de componentes, el cual resolver al FTPComponent. El FTPComponent entonces funciona como una factory, creando el FTPEndpoint basado en la ruta del contexto y las opciones. La ruta del contexto de rider.com/ordenes le dice al FTPComponent que debe loguearse en el servidor FTP en rider.com en el puerto FTP default y cambiar el directorio a ordenes. Finalmente, las nicas opciones especificadas son username y password, las cuales son usadas para loguearse en el servidor FTP.

El FTPComponent no es parte del mdulo camel-core, as que tienes que agregar una dependencia adicional a tu proyecto. Usando Maven slo tienes que agregar la siguiente dependencia a tu POM:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-ftp</artifactId> <version>2.5.0</version> </dependency>

La URI de este endpoint se estar usando para descargar rdenes del servidor FTP. Para hacerlo as, necesitas usarlo en un nodo from del DSL de Camel:
from(ftp://rider.com/ordenes?username=rider&password=secret)

Lo anterior es todo lo que necesitas hacer para consumir archivos desde un servidor FTP.
ftp://rider.com/ordenes?username=rider&password=secret
Esquema Ruta del contexto Opciones

Figura 2. La URI de un endpoint Camel consiste de tres partes: un esquema, una ruta de contexto, y una lista de opciones.

Enviando a una Queue JMS


Camel proporciona soporte extensivo para conectar proveedores habilitados para JMS. Por ahora slo cubriremos lo suficiente para que puedas completar tu primer tarea para Auto Partes Rider. Recordemos que necesitas descargar rdenes de un servidor FTP y enviarlas a una queue JMS.
JMS Java Message Service es una API Java que te permite crear, recibir, y leer mensajes. Adems obliga que la mensajera sea asncrona y tenga elementos especficos de confiabilidad, como entrega garantizada y una-y-solamente-una-vez. JMS es la solucin de facto en la comunidad Java.

En JMS, los consumidores y productores de mensajes se hablan uno a otro a travs de un intermediario un destino JMS. Como se muestra en la figura 3, un destino puede ser una queue o un topic. Las Queues son estrictamente punto-a-punto, donde cada mensaje tiene slo un consumidor. Los Topics operan en un esquema publish/subscribe; un slo mensaje puede ser entregado a muchos consumidores si ellos se han suscrito al topic. JMS tambin proporciona una ConnectionFactory la cual los clientes (como Camel) pueden usar para crear una conexin con un proveedor JMS. A los proveedores JMS generalmente se les refiere como brokers debido a que ellos gestionan la comunicacin entre el productor del mensaje y el consumidor del mensaje.

Cmo usar camel para usar un Proveedor JMS


Para conectar camel a un proveedor JMS especfico, necesitas configurar el componente JMS de Camel con una ConnectionFactory apropiada. Apache ActiveMQ es uno de los proveedores JMS open source ms populares; y es el broker JMS que el equipo de Camel usa para probar el componente JMS. Por lo cual estaremos usndolo para demostrar los conceptos JMS en el artculo.
Figura 3. Hay dos tipos de destinos JMS: queues y topics. La queue es un canal punto a punto, donde cada mensaje tiene un slo receptor. Un topic entrega una copia del mensaje a todos los clientes quienes se hayan suscrito para recibirlo.

As que en el caso de Apache ActiveMQ, puedes crear una ActiveMQConnectionFactory que apunta a la ubicacin del broker ActiveMQ que est corriendo.
ConnectionFactory cf = new ActiveMQConnectionFactory(vm://localhost);

La URI vm:/localhost significa que debes conectarte a un broker embebido llamado localhost corriendo dentro de la JVM actual. El conector de transporte vm en ActiveMQ crea un broker bajo demanda si uno no est corriendo an. de forma que es muy prctico para aplicaciones JMS de pruebas; para escenarios de produccin, se recomienda que conectes un broker que ya est en ejecucin. Adems, en escenarios de produccin se recomienda que se use un pool de conexiones cuando se conecta a un broker JMS.

A continuacin, cuando creas tu CamelContext puedes agregar el componente JMS como sigue:
CamelContext context = new DefaultCamelContext(); context.addComponent(jms, JmsComponent.jmsComponentAutoAcknowldge(connectionFactory));

El componente JMS y la connection factory especfica de ActiveMQ no son parte del mdulo core de Camel. Con fines de usar este, necesitars agregar algunas dependencias a tu proyecto basado en Maven. Para el componente JMS plano, todo lo que tienes que hacer es esto:
<dependency> <groupId>org.apache.camel</groupId> <artefactId>camel-jms</artefactId> <version>5.3.2</version> </dependency>

La connection factory viene directamente de ActiveMQ, de forma que tendrs que agregar la siguiente dependencia:
<dependency> <groupId>org.apache.activemq</groupId> <artefactId>activemq-core</artefactId> <version>5.3.2</version> </dependency>

Ahora que has configurado el componente JMS para conectar a un broker JMS real, es hora de ver cmo las URIs pueden ser usadas para especificar el destino.

Usando URIs para especificar el Destino


Una vez configurado el componente JMS, puedes enviar y recibir mensajes JMS a tu gusto. Debido a que ests usando URIs es muy fcil de configurar. Digamos que quieres enviar un mensaje JMS a la queue llamada incomingOrders. La URI en este caso sera:
jms:queue:incomingOrders

Esto es muy autoexplicatorio. El prefijo jms indica que ests usando el componente JMS que configuraste antes. Especificando queue, el componente JMS sabe que enviar a una queue llamada incomingOrders. An pudiste haber omitido el calificador queue, debido a que el comportamiento default es enviar a una queue ms que a un topic.

Usando el DSL Java de Camel puedes enviar un mensaje a la queue incomingOrders usando la palabra clave to, como en este caso:
to(jms:queue:incomingOrders)

Lo cual puede ser ledo como enviando a la queue JMS llamada incomingOrders.

Creando routes en Java


Antes de adentrarnos en los enrutamientos es necesario conocer unos conceptos bsicos de los mismos. CamelContext La figura 1.7 muestra los servicios ms notables que mantiene unidos el CamelContext. Estos servicios son descritos en la tabla 1.

Figura 1.7 El CamelContext provee acceso a muchos servicios tiles, los ms notables siendo componentes, convertidores de tipo, un registro, endpoints, routes, formatos de datos, y lemguajes.

Servicio
Componentes

Descripcin
Contiene los componentes usados. Camel es capaz de cargar componentes en el aire, ya sea autodescubriendo en el claspath o cuando un nuevo bundle es activado en un contenedor OSGi. Contiene los endpoints que han sido creados Contiene los routes que han sido agregados. Contiene los convertidores de tipo cargados. Camel tiene un mecanismo que te permite convertir manual o automticamente de un tipo a otro. Contiene los formatos de datos cargados Contiene un registro que te permite localizar beans. Por default, este ser un registro JNDI. Si ests usando Camel desde Spring, ser el ApplicationContext. Puede ser un registro OSGi si usas Camel en un contenedor OSGi. Contiene los lenguajes cargados. Camel te permite usar diferentes lenguajes para crear exprsiones.

Endpoints Routes Convertidores de tipo

Formatos de datos Registro

Lenguajes

Motor de Enrutamiento
El motor de enrutamiento de Camel es lo que realmente mueve los mensajes tras bambalinas. Este motor no es expuesto al desarrollador, pero debe estar consciente de que est ah y hace el trabajo pesado, asegurando que los mensajes sean enrutados adecuadamente.

Routes
Las routes son obviamente una abstraccin de Camel. La forma ms simple de definir una route es como una cadena de procesadores. Hay muchas razones para usar routes en aplicaciones de mensajera

Desacoplando los clientes de los servidores, y productores de consumidores, routes puede: Decidir dinmicamente a qu servidor un cliente invocar Proporcionar una forma sensible de agregar procesamiento extra Permitir a los clientes y servidores ser desarrollados de forma independiente Permitir a los clientes y servidores ser apagados (usando mocks) por propsitos de prueba Promover mejores prcticas de diseo conectando sistemas distintos que hacen una cosa bien Mejorar las caractersticas y funcionalidades de algunos sistemas (tales como brokers de mensajes y ESBs)

Domain Specific Languaje (DSL) Para vincular (cablear) procesadores y/a endpoints para formar routes, camel define un DSL. En Camel, DSL significa una API Java fluida que contiene mtodos nombrados por tminos de EIP. Considera este ejemplo:
from(file:data/inbox) .filter().xpath(/order[not(@test)]) .to(jms:queue:order)

Aqu, en una sola declaracin Java, defines una route que consume archivos de un endpoint de archivos . Los mensajes son luego enrutados al filtro EIP, el cual usar un predicado XPath para probar si el mensaje es una orden de prueba o no. Si un mensaje pasa el test, es reenviado al endpoint JMS. Los mensajes que fallen el filtro de prueba sern desechados.

Camel proporciona varios lenguajes DSL, de forma que puedas definir la misma route usando el DSL de Spring, como en este caso:
<route> <from uri=file:data/inbox> <filter> <xpath>/order[Not(@test)]</xpath> <to uri=jms:queue:order> </filter> </route>

El DSL proporciona una buena abstraccin para los usuarios de Camel con las cuales construir aplicaciones. Aunque, tras bambalinas, un route realmente est compuesto de un grafo de processors.

Processor El processor es un concepto de core de Camel que representa un nodo capaz de usar, crear, o modificar un exchange entrante. Durante el enrutamiento, los exchanges fluyen de un processor a otro; como tal, puedes pensar de un route como un grafo teniendo especializado processors como los nodos, y lneas que conectan las salidas de un processor a la entrada de otro. Muchos de los processors son implementaciones de EIPs, pero uno podra fcilmente implementar su propio processor personalizado e insertarlo en un route. As que, cmo los exchanges entran o salen de este grafo processor? Para descubrirlo necesitaremos ver los componentes y endpoints.

Componente Los componentes son los principales puntos de extensin en Camel. Hasta la fecha, hay alrededor de 80 componentes en el ecosistema de Camel que van del rango en funcin de protocolos de datos, a DSLs, formatos de datos, etc. Adems de que puedes crear tus propios componentes para Camel. Desde un punto de vista de programacin, los componentes son completamente simples: estn asociados con un nombre, que es usado en una URI, y actan como una factory de endpoints. Por ejemplo, un FileComponent es referenciado por un file en una URI, y crea FileEndpoints. El endpoint es tal vez an un concepto ms fundamental en Camel.

Endpoint Un endpoint es la abstraccin Camel que modela el extremo de un canal a travs del cual un sistema puede enviar o recibir mensajes. Esto se ilustra en la figura 1.8

Figura 1.8 Un endpoint acta como una interface neutral permitiendo a los sistemas integrarse.

En Camel, puedes configurar endpoints usando URIs, como es file:data/inbox?delay=5000, y puedes referirte a enpoints de esa forma. En tiempo de ejecucin, Camel buscar un endpoint basado en la notacin de URI. Productor (Producer) Un productor es la abstraccin Camel que se refiere a una entidad capaz de crear y enviar un mensaje a un endpoint. La figura 1.10 ilustra donde el productor se ajusta con otros conceptos Camel. Cuando un mensaje necesita ser enviado a un endpoint, el productor crear un exchange y lo llena con datos compatibles con ese endpoint particular. Por ejemplo, un FileProducer escribir el body de un mensaje a un archivo. Por otro lado, un JMSProducer, mapear el mensaje Camel antes de enviarlo a un destino JMS.

Esta es una caracterstica importante de Camel, ya que oculta la complejidad de interactuar con transportes particulares .
crea

crea

usa

usa crea

crea

Consumidor

Productor

usa

Figura 1.10 Cmo los endpoints trabajan con productores, consumidores, y un exchange

Consumidor Un consumidor es el servicio que recibe mensajes producidos por un productor, los envuelve en un exhange, y los enva a ser procesados. Los consumidores son la fuente de los exchanges que estn siendo enrutados en Camel. Para crear un nuevo exchange, un consumidor usar el endpoint que envuelve el payload que est siendo consumido. Un processor es luego usado para iniciar el enrutamiento del exchange en Camel usando el motor de enrutamiento. En Camel hay dos clases de consumidores: consumidores guiados por eventos y consumidores de voteo. Las diferencias entre estos consumidores son importantes, debido a que ellos ayudan a resolver problemas diferentes.

Consumidor guiado por evento El consumidor ms familiar es probablemente el consumidor guiado por evento, el cual se ilustra en la figura 1.11 Esta clase de consumidor est principalmente asociado con la arquitectura cliente servidor y web services. Tambin se le refiere como un receptor asncrono en el mundo EIP. Un consumidor guiado por evento escucha en un canal de mensaje particular, usualmente un puerto TCP/IP o una queue JMS, y espera para que un cliente le enve mensajes. Cuando un mensaje llega, el consumidor despierta y toma el mensaje para procesarlo.
Figura 1.1 Un consumidor guiado por evento espera ocioso hasta que un mensaje llega, punto en el cual despierta y consume el mensaje.

Consumidor de voteo La otra clase de consumidor es el consumidor de voteo, el cual se ilustra en la figura 1.12. En contraste al consumidor guiado por eventos, el consumidor de voteo va activamente y obtiene mensajes desde una fuente particular, como lo es un servidor FTP. El consumidor de voteo es tambin conocido como receptor sncrono en la jerga EIP, debido a que no votear por ms mensajes hasta que haya finalizado el procesamiento del mensaje actual. Un sabor comn del consumidor de voteo es el consumidor de voteo programado, el cual votea en intervalos programados. Todos los transportes de File, FTP, y email usan consumidores de voteo programados.

Ahora que hemos cubierto todos los conceptos bsicos de Camel, es hora de proseguir con la creacin de los routes. El RouteBuilder no es el route final que el CamelContext usar en tiempo de ejecucin; es un builder para uno o ms routes, los cuales son luego agregados al CamelContext. El mtodo addRoutes del CamelContext acepta un RoutesBuilder, no slo un RouteBuilder. La interface RoutesBuilder tiene un slo mtodo definido:
void addRoutesToCamelContext(CamelContext context) throws Exception;

Esto significa que podras construir tu propia clase personalizada para construir routes Camel. Aunque, la forma ms comn de construir routes es usando la clase RouteBuilder, que implementa RoutesBuilder. La clase RouteBuilder te da acceso al DSL Java de camel para creacin de route.

Figura 2.5 Los RoutesBuilders son usados para crear routes en Camel. Cada RouteBuilder puede crear mltiples routes en Camel.

Usando el RouteBuilder
Para usar la clase org.camel.builder.RouteBuilder, extiendes de ella una clase e implementas el mtodo configure, como esto:
class MyRouteBuilder extends RouteBuilder{ public void configure() throws Exception{ } }

Luego necesitas agregar la clase al CamelContext con el mtodo addRoutes:


CamelContext context = new DefaultCamelContext(); context.addRoutes(new MyRouteBuilder());

Alternativamente, puedes combinar el RouteBuilder y la configuracin del CamelContext agregando una clase RouteBuilder annima directamente en el CamelContext, como esta:
CamelContext context = new DefaultCamelContext(); context.addRoutes(new RouteBuilder(){ public void configure(){ } });

En el mtodo configure t defines tus routes usando el DSL Java. El mtodo from acepta una URI de endpoint como argumento. Puedes agregar la URI de un endpoint FTP para conectar al servidor de rdenes de AutoPartes Rider de la siguiente forma:

from(ftp://rider.com/orders?username=rider&password=secret)

El mtodo from retorna un objeto RouteDefinition, en el cual puedes invocar un nmero de diferentes mtodos que implementan EIPs y otros conceptos de mensajera.

El DSL Java
Los lenguajes especficos de dominio (DSLs) son lenguajes de computadora que se dirigen a problemas especficos de dominio, ms que a un dominio de propsito general como la mayora de los lenguajes de programacin. El dominio de Camel es la integracin empresarial, de forma que el DSL Java es esencialmente un conjunto de interfaces fluidas que contienen mtodos nombrados despus de trminos del libro EIP. En el editor de Eclipse, toma una mirada a lo que est disponible usando autocompletar despus de un mtodo from en el RouteBuilder. Por ahora, slo selecciona el mtodo to y finaliza el route con un punto y coma. Cada declaracin Java que inicia con un mtodo from en el RouteBuilder crea un nuevo Route. Este nuevo route ahora completa tu primer tarea de AutoPartes Rider consumir rdenes de un servidor FTP y enviarlas a la queue JMS incomingOrders.

Cdigo 1. Voteando por mensajes FTP y envindolos a la queue incomingOrders


import import import import import import javax.jms.ConnectionFactory; org.apache.activemq.ActiveMQConnectionFactory; org.apache.camel.CamelContext; org.apache.camel.builder.RouteBuilder; org.apache.camel.component.jms.JmsComponent; org.apache.camel.impl.DefaultCamelContext;

public class FtpToJMSExample { public static void main(String args[]) throws Exception { CamelContext context = new DefaultCamelContext(); ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost"); context.addComponent("jms", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory)); context.addRoutes(new RouteBuilder() { public void configure() { from("ftp://rider.com/orders?username=rider&password=secret") Sentencia Java que .to("jms:incomingOrders"); forma una route } }); context.start(); Thread.sleep(10000); context.stop(); } }

El flujo de mensajes en este route simple puede ser visualizado como una tubera bsica, donde la salida del consumidor es alimentada en el productor como entrada. Esto se describe en la figura 2.8:

Figura 2.8 El route mostrado en el cdigo anterior forma una tubera simple. La salida del consumidor FTP es alimentada en la entrada del productor JMS. La conversin del payload de archivo a mensaje JMS es hecha automticamente.

Una cosa que puedes haber notado es que no hicimos alguna conversin del tipo de archivo FTP al tipo mensaje JMS esto fue hecho automticamente por la facilidad TypeConverter de Camel. Puedes forzar las conversiones de tipo para que ocurran en cualquier momento durante una route, pero frecuentemente no tienes que preocuparte de todo ello.

Agregando un Processor La interface Processor en Camel es un bloque de construccin importante de routes complejos. Es una interface simple que tiene un slo mtodo:
public void process(Exchange exchange) throws Exception

Esto te da acceso completo al intercambio de mensajes, permitindote hacer casi todo lo que quieras con el payload o headers. Todos los EIPs en Camel son implementados como processors. An puedes agregar un processor simple a tu route inline, como esta:
from(ftp://rider.com/orders?username=rider&password=secret). process(new processor(){ public void process(Exchange exchange) throws Exception{ System.out.println(Solo has descargado: + exchange.getIn().getHeader(CamelFileName)); } }

Esta route imprimir el nombre de archivo de la orden que fue descargada antes de enviarla a la queue JMS.

Agregando este processor en medio del route, efectivamente lo has agregado al pipeline conceptual que mencionamos antes. La salida del consumido FTP es alimentada en el processor como entrada; el processor no modifica el payload o headers del mensaje, de forma que el exchange se mueve en el productor JMS como entrada. El mtodo principal de Camel para crear routes es a travs del DSL Java. Esto est, despus de todo, construido en el mdulo camelcore.
Figura 2.9 Con un processor en la mezcla, la salida del consumidor FTP es ahora alimentada en el processor, y luego la salida del processor es alimentada en el productor JMS.

Creando routes con Spring


Spring es el contenedor Java de Inversin de Control (IoC) ms popular. El framework core te permite vincular beans para formas aplicaciones. Esta vinculacin es hecha a travs de un archivo de configuracin XML. Inyeccin de bean y Spring Crear una aplicaciones desde beans usando Spring es muy simple. Todo lo que necesitas son algunos beans Java (clases), un archivo de configuracin XML de Spring, y un ApplicationContext. El ApplicationContext es similar al CamelContext, en que es el contenedor de runtime para Spring. Vamos a ver un ejemplo muy simple.

Considera una aplicacin que imprime un saludo seguido por tu username. En esta aplicacin no quieres que el saludo sea hardcodeado, de forma que puedas usar una interface para romper esta dependencia. Considera la siguiente interface:
public interface Greeter{ public String diHola(); }

Esta interface es implementada por las siguientes clases:


public class EnglishGreeter implements Greeter{ public String diHola(){ return Hello + System.getProperty(user.name); } }

public class DanishGreeter implements Greeter{ public String diHola(){ return Davs + System.getProperty(user.name); } }

Ahora puedes crear una aplicacin greeter como sigue:


public class GreeterMeBean{ public Greeter greeter; public void setGreeter(Greeter greeter){ this.greeter = greeter; } public void execute(){ System.out.println(greeter.diHola()); } }

Esta aplicacin sacar un saludo diferente dependiendo de cmo lo configures. Para configurar esta aplicacin usando Spring, puedes hacer algo como esto:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="myGreeter" class="camelinaction.EnglishGreeter"/> <bean id="greetMeBean" class="camelinaction.GreetMeBean"> <property name="greeter" ref="myGreeter"/> </bean> </beans>

Este archivo XML instruye a Spring a hacer lo siguiente: 1. Crear una instancia de EnglishGreeter y nombrar al bean myGreeter 2. Crear una instancia de GreetMeBean y nombrar al bean greetMeBean 3. Asignar la referencia de la propiedad greeter del GreetMeBean al bean llamado myGreeter

Esta configuracin de beans es llamada wiring. Ahora te toca cargar el archivo XML de configuracin de Spring en tu aplicacin para poder hacer uso de los beans inyectados. Para hacer las cosas ms fciles a los ojos, Camel utiliza los mecanismos de extensin de Spring para proporcionar sintaxis XML personalizada para conceptos Camel en el archivo XML de Spring. Para cargar un CamelContext en Spring, puedes hacer lo siguiente:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> ... <camelContext xmlns="http://camel.apache.org/schema/spring"/> </beans>

Lo anterior automticamente iniciar un SpringCamelContext, la cual es una subclase del DefaultCamelContext que usaste para el DSL Java. Adems nota que tuviste que incluir la definicin de esquema XML http://camel.apache.org/schema/spring/camelspring.xsd en el archivo XML que es necesario para importar los elementos XML personalizados. Este snippet no va a hacer nada por s solo. Necesitas decirle a Camel qu routes va a usar, como lo hiciste cuando usabas el DSL Java. El siguiente cdigo usa Spring para producir los mismos resultados que el listado 2.1

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> <bean id="jms" class="org.apache.camel.component.jms.JmsComponent"> <property name="connectionFactory"> <bean class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="vm://localhost" /> </bean> </property> </bean> <bean id="ftpToJmsRoute" class="camelinaction.FtpToJMSRoute"/> <camelContext xmlns="http://camel.apache.org/schema/spring"> <routeBuilder ref="ftpToJmsRoute"/> </camelContext> </beans>

Puedes haber notado que nos estamos refiriendo a la clase camelinaction.FtpToJMSRoute como un RouteBuilder. Con el fin de reproducir el DSL Java del listado 2.1, tienes que factorizar el RouteBuilder annimo en su propia clase nombrada. La clase FtpToJMSRoute se parece a la siguiente:
public class FtpToJMSRoute extends RouteBuilder { public void configure() { from("ftp://rider.com" + "/orders?username=rider&password=secret") .to("jms:incomingOrders"); } }

Lo que hemos visto de la integracin de Camel con Spring es adecuado, pero no est tomando completa ventaja de la metodologa de Spring sin usar cdigo. Para completamente invertir el control de crear aplicaciones usando XML Spring, Camel proporciona extensiones XML personalizadas a las que llamamos el DSL Spring. El DSL Spring te permite hacer casi todo lo que puedes hacer en el DSL Java. Continuemos con el ejemplo de AutoPartes Rider mostrado en el listado 2.2, pero esta vez especificars las reglas de enrutamiento definidas en el RouteBuilder puramente en XML. El siguiente XML Spring hace esto.

Listado 2.3 Ejemplo DSL Spring que produce el mismo resultado que el listado 2.1
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> <bean id="jms" class="org.apache.camel.component.jms.JmsComponent"> <property name="connectionFactory"> <bean class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="vm://localhost" /> </bean> </property> </bean> <camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="ftp://rider.com/orders?username=rider&password=secret"/> <to uri="jms:incomingOrders"/> </route> </camelContext> </beans>

En el listado anterior bajo el elemento camelContext remplazas el routeBuilder con el elemento route. En el elemento route, especificas el route usando elementos con nombres similares a aquellos usados dentro del RouteBuilder del DSL Java. Este listado es funcionalmente equivalente a la versin DSL de Java en el listado 2.1 y la combinacin de Spring ms el DSL Java. El endpoint file cargar archivos de rdenes del directorio src/data relativo. La propiedad noop configura el endpoint para que deje el archivo como est despus de procesarlo, esta opcin es muy til para testing. Este route no desplegar algo interesante an. Necesitas agregar un paso de procesamiento adicional para testing.

Agregando un Processor

Agregar pasos de procesamiento adicional es simple, como en el DSL Java, aqu agregars un procesador personalizado como lo hiciste en la seccin 2.3.2. Debido a que no puedes referirte a una clase annima en el XML Spring, necesitas refactorizar el procesador annimo en la siguiente clase:
public class DownloadLogger implements Processor { public void process(Exchange exchange) throws Exception { System.out.println("We just downloaded: " + exchange.getIn().getHeader("CamelFileName")); } }

Puedes ahora usarla en el route de tu DSL Spring como sigue:


<bean id="downloadLogger" class="camelinaction.DownloadLogger"/> <camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="file:src/data?noop=true"/> <process ref="downloadLogger"/> <to uri="jms:incomingOrders"/> </route> </camelContext>

Enrutamientos y EIPs
Usando un Enrutador Basado en Contenido (CBR) Como su nombre lo implica, un Enrutador Basado en Contenido (CBR) es un router de mensaje que enruta un mensaje a un destino basado en su contenido. El contenido podra ser un header de mensaje, el tipo de dato del payload, parte del mismo payload. Para demostrar, vamos atrs a Autopartes Rider. Algunos clientes han empezado a cargar rdenes al servidor FTP en el formato XML ms nuevo ms que CSV. Lo que significa que tienes dos tipos de mensajes entrantes a la queue incomingOrders. No hemos tocado esto antes, pero necesitas convertir las rdenes entrantes en un formato POJO interno. Obviamente necesitas hacer diferentes conversiones para los diferentes tipos de rdenes entrantes. Como una posible solucin, podras usar la extensin del nombre de archivo si un mensaje de orden particular debe ser enviado a la queue para rdenes CSV o a una queue para rdenes XML.

Enrutamientos y EIPs
Usando un Enrutador Basado en Contenido (CBR)

Figura 2.10. El CBR enruta mensajes basado en su contenido. En este caso, la extensin filename (como un header del mensaje) es usado para determinar a qu queue enrutar.

Enrutamientos y EIPs
Como lo viste antes, puedes usar el header CamelFileName asignado por el consumidor FTP para obtener el nombre de archivo. Para hacer el enrutamiento condicional requerido por el CBR, Camel introduce algunas keywords en el DSL. El mtodo choice crea un processor CBR, y las condiciones son agregadas siguiendo choice con una combinacin de un mtodo choice con una combinacin de un mtodo when y un predicado.
from("jms:incomingOrders") .choice() .when(predicate) .to("jms:xmlOrders") .when(predicate) .to("jms:csvOrders");

Enrutamientos y EIPs
Puedes haber notado que no llenamos el predicado requerido por cada mtodo when. Un predicado en Camel es una simple interface que slo tiene un mtodo matches:
public interface Predicate { boolean matches(Exchange exchange); }

Por ejemplo, puedes pensar de un predicado como una condicin booleana en una sentencia if Java. Probablemente no quieras buscar por ti mismo dentro del exchange y hacer una comparacin. Afortunadamente, los predicados son construidos de expresiones, y las expresiones son usadas para extraer resultados basados de un exchange basado en el contenido de la expresin.

Enrutamientos y EIPs
Hay muchos lenguajes de expresin de los cuales elegir en Camel, algunos de los cuales incluyen Simple, EL, JXPath, Mvel, OGNL, PHP, BeanShell, JavaScript, Groovy, Python, Ruby, XPath y XQuery. En el RouteBuilder, puedes comenzar usando el mtodo header, que retorna una expresin que evaluar al valor del header. Por ejemplo, header(CamelFileName) crear una expresin que resolver al valor del header CamelFileName en el siguiente exchange. En esta expresin puedes invocar muchos mtodos para crear un predicado. As que verifica si la extensin del nombre del archivo es .xml, puedes usar el siguiente predicado:
header(CamelFileName).endsWith(.xml);

Enrutamientos y EIPs
context.addRoutes(new RouteBuilder() { public void configure() { from("file:src/data?noop=true").to("jms:incomingOrders"); from("jms:incomingOrders") .choice() .when(header("CamelFileName") .endsWith(".xml")) .to("jms:xmlOrders") .when(header("CamelFileName") .endsWith(".csv")) .to("jms:csvOrders"); from("jms:xmlOrders").process(new Processor() { public void process(Exchange exchange) throws Exception { System.out.println("Received XML order: " + exchange.getIn().getHeader("CamelFileName")); } }); from("jms:csvOrders").process(new Processor() { public void process(Exchange exchange) throws Exception { System.out.println("Received CSV order: " + exchange.getIn().getHeader("CamelFileName")); } }); } });

Enrutamientos y EIPs
Usando Filtros de Mensajes

Figura 2.12. Un Filtro de Mensaje te permite filtrar los mensajes que no importan basados en alguna condicin. En este caso los mensajes de prueba son filtrados.

Enrutamientos y EIPs
Usando filtros de mensajes AutoPartes Rider ahora tiene un nuevo issue su departamento de QA ha expresado la necesidad de enviar rdenes de prueba en el frontend web en vivo del sistema de rdenes. Tu solucin actual aceptara estas rdenes como reales y enviarlas a los sistemas externos para procesamiento. Tu has sugerido que QA pruebe en un clon de desarrollo del sistema real, pero la gestin ha desechado esa idea, alegando un presupuesto limitado. Lo que necesitas es una solucin que descarte estos mensajes de prueba mientras an se opera en las rdenes reales. El EIP Message Filter, proporciona una buena forma de tratar con esta clase de problemas. Los mensajes entrantes slo pasan el filtro si renen una cierta condicin. Los mensajes que no renen la condicin son desechados.

Enrutamientos y EIPs
Usando filtros de mensajes
from("jms:xmlOrders").filter(xpath("/order[not(@test)]")) .process(new Processor() { public void process(Exchange exchange) throws Exception { System.out.println("Received XML order: " + exchange.getIn().getHeader("CamelFileName")); } }); El anterior en el DSL Java, y el siguiente en el DSL de Spring <route> <from uri="jms:xmlOrders"/> <filter> <xpath>/order[not(@test)]</xpath> <process ref="orderLogger"/> </filter> </route>

Enrutamientos y EIPs
Usando Multicasting

Figura 2.13. Un multicast enva un mensaje a un nmero de receptores especficos.

Enrutamientos y EIPs
Usando Multicasting Frecuentemente en las aplicaciones empresariales necesitars enviar una copia de un mensaje a varios destinos diferentes para procesamiento. Cuando la lista de destinos es conocida adelante del tiempo y es esttica, puedes agregar un elemento al route que consumir mensajes desde un endpoint fuente y luego enviar el mensaje a una lista de destinos.

Enrutamientos y EIPs
Usando lista de receptores

Figura 2.14. Una lista de receptores inspecciona los mensajes entrantes y determina una lista de receptores basado en el contenido del mensaje. En este caso, slo es enviado a los destinos A, B, y D.

Enrutamientos y EIPs
Usando lista de receptores Usando el EIP Recipient List. Una lista de receptores primero inspecciona el mensaje entrante, luego genera una lista de receptores deseados basados en el contenido del mensaje, y enva el mensaje a esos receptores. Un receptor es especificado por una URI. Nota que la lista de receptores es diferente que el multicast debido a que la lista de receptores es dinmica. Camel proporciona un mtodo recipientList para implementar el patrn EIP Recipient List. Por ejemplo, el siguiente route tomar la lista de receptores desde un header llamado recipients, donde cada recipiente es separado del siguiente por una coma:
from("jms:xmlOrders") .recipientList(header("recipients"));

Enrutamientos y EIPs
En la versin DSL Java
from("jms:xmlOrders") .setHeader("customer", xpath("/order/@customer")) .process(new Processor() { public void process(Exchange exchange) throws Exception { String recipients = "jms:accounting"; String customer = exchange.getIn().getHeader("customer", String.class); if (customer.equals("honda")) { recipients += ",jms:production"; } exchange.getIn().setHeader("recipients", recipients); } }) .recipientList(header("recipients"));

Enrutamientos y EIPs
En la versin DSL Spring
<route> <from uri="jms:xmlOrders" /> <setHeader headerName="customer"> <xpath>/order/@customer</xpath> </setHeader> <process ref="calculateRecipients" /> <recipientList> <header>recipients</header> </recipientList> </route>

Enrutamientos y EIPs
Usando el mtodo wireTap

Enrutamientos y EIPs
Usando el mtodo wireTap Frecuentemente en aplicaciones empresariales es til y necesario inspeccionar cmo los mensajes fluyen a travs del sistema. Por ejemplo, cuando una orden falla, necesitas una forma de buscar qu mensajes fueron recibidos fueron recibidos para determinar la causa de la falla. Usando el mtodo wireTap en el DSL Java, puedes enviar una copia del exchange a un destino secundario sin afectar el comportamiento del resto del route.
from("jms:incomingOrders") .wireTap("jms:orderAudit") .choice() .when(header("CamelFileName").endsWith(".xml")) .to("jms:xmlOrders") .when(header("CamelFileName").regex("^.*(csv|csl)$")) .to("jms:csvOrders") .otherwise() .to("jms:badOrders");

GRACIAS
Dudas y comentarios al email: it.adesales@gmail.com Y en la pgina www.facebook.com/JavaDevelopersMexico No olviden regalarnos un like.

Você também pode gostar