Ir a Tecsisa.com
24feb/09

Tutorial: Enterprise Integration Patterns (EIP) en Apache ServiceMix

Continuamos con la serie de tutoriales que comenzamos con el artículo Explorando Apache ServiceMix en 15 minutos con el objetivo de introducir las potentes características que presenta el ESB Apache ServiceMix. En esta entrega, veremos como Apache ServiceMix soluciona escenarios de integración que se ajustan a los llamados patrones de integración empresariales o EIPs. Plantearemos un nuevo caso de uso típico de estos escenarios y lo resolveremos reduciendo al mínimo el acoplamiento entre los distintos componentes de la solución.

¿Por qué aplicar patrones de integración?

Los EIPs identifican problemas de integración comunes presentando una manera unificada de resolverlos sin entrar en el detalle de su implementación. Estos patrones fueron identificados y redactados por Gregor Hohpe y Bobby Woolf en el famoso libro Enterprise Integration Patterns manteniendo además una comunidad activa a través de su sitio web.

Tutorial sobre el uso de patrones de integración en ServiceMixLas necesidades de integración de sistemas y aplicaciones son comunes a la mayoría de organizaciones y son mayores conforme crece el tamaño o la complejidad tecnológica de la organización. Históricamente, se han venido desarrollando distintas maneras de enfocar el problema de la integración y por supuesto éste ha sido abordado con anterioridad a los ESBs. Desde los ficheros planos, o las bases de datos relacionales, hasta los más recientes productos del tipo hub and spoke, la evolución en el tratamiento de la integración se ha dirigido hacia la reducción del acoplamiento entre los distintos agentes intervinientes.

En este sentido, los ESBs, y en particular Apache ServiceMix, pueden verse como una culminación de esta tendencia en la que ni siquiera es necesario mantener un elemento central de orquestación, como ocurre con los hub and spoke, sino que la propia orquestación puede estar distribuida en varios nodos cada uno de ellos con su propia instancia de ESB.

Los EIPs en Apache ServiceMix

Apache ServiceMix permite aplicar gran número de patrones de integración basándose en diversas tecnologías, pero en este tutorial nos centraremos en aplicarlos utilizando el service engine servicemix-eip. Este componente permite configurar los patrones de forma muy intuitiva y simple, de forma que podremos centrar la atención en qué patrón es el que mejor se adapta a nuestro caso de uso y no en cómo implementar el patrón que necesitamos.

La otra gran alternativa de implementación de EIPs en Apache ServiceMix es el componente servicemix-camel, al que dedicaremos un tutorial en un futuro artículo de esta serie.

Caso de uso

Partiendo de la pequeña solución SOA creada en el artículo anterior, nuestro siguiente paso será coordinar los antiguos servicios con uno nuevo mediante un EIP. Enriqueceremos el escenario insertando una bifurcación en el flujo de los mensajes, quedando así:

  • El ESB deberá recoger el fichero de entrada en cuanto éste haya sido depositado en nuestro directorio monitorizado.
  • El contenido del fichero deberá ser traceado desde nuestro logger desplegado sobre el service engine servicemix-bean.
  • Al mismo tiempo que el punto anterior, el fichero deberá ser enviado a una carpeta de salida desde un nuevo servicio desplegado sobre el ya existente binding component servicemix-file.

El siguiente diagrama de flujo da una buena visión del escenario planteado:

Diagrama de flujo ESB con bifurcación de mensajes

Creación del nuevo endpoint

De forma muy similar a la creación del file poller del artículo anterior, crearemos un endpoint para el file sender: sólo habrá que declarar su nombre de servicio y de endpoint y asignarle una carpeta de destino, que en nuestro caso llamaremos "outbox".

<file:sender service="foo:sender" 
             endpoint="sender" 
             directory="outbox" />

Creación del patrón EIP

El patrón que más se adapta a las necesidades de nuestro caso de uso es el Static Recipient List, es decir, una lista estática (fija) de endpoints a la que se reenviarán todos los mensajes que lleguen a nuestro servicio de EIP. Por tanto, crearemos un endpoint que cumpla este patrón en nuestro servicemix.xml como se muestra a continuación.

<eip:static-recipient-list service="foo:router" endpoint="router"> 
    <eip:recipients> 
     <eip:exchange-target service="foo:logger" /> 
 <eip:exchange-target service="foo:sender" /> 
   </eip:recipients> 
</eip:static-recipient-list>

Configuración del ESB

Tras añadir nuestros dos nuevos endpoints al fichero servicemix.xml, éste debería haber tomado el siguiente aspecto:


<?xml version="1.0" encoding="UTF-8"?> 

<beans xmlns="http://xbean.org/schemas/spring/1.0"

       xmlns:sm="http://servicemix.apache.org/config/1.0" 

       xmlns:jencks="http://jencks.org/2.0" 

       xmlns:file="http://servicemix.apache.org/file/1.0" 

       xmlns:bean="http://servicemix.apache.org/bean/1.0" 

       xmlns:eip="http://servicemix.apache.org/eip/1.0" 

       xmlns:foo="http://foo.bar/smx15mins/"> 

    <!-- Transaction Manager --> 

    <jencks:transactionManager id="transactionManager" /> 

    <sm:container id="jbi" 

                  rootDir="SMXData" 

                  useMBeanServer="true" 

                  createMBeanServer="true" 

                  transactionManager="#transactionManager" 

                  flowName="seda" 

                  autoEnlistInTransaction="true"> 

        <sm:activationSpecs> 

            <sm:activationSpec componentName="fileComponent"> 

                <sm:component> 

                    <file:component> 

                        <file:endpoints> 

                            <file:poller service="foo:poller" 

                                         endpoint="poller" 

                                         targetService="foo:router" 

                                         file="inbox" /> 

                            <file:sender service="foo:sender" 

                                         endpoint="sender" 

                                         directory="outbox" /> 

                        </file:endpoints> 

                    </file:component> 

                </sm:component> 

            </sm:activationSpec> 

            <sm:activationSpec componentName="beanComponent"> 

                <sm:component> 

                    <bean:component> 

                        <bean:endpoints> 

                            <bean:endpoint service="foo:logger" 

                                           endpoint="logger"> 

                                <bean:bean> 

                                    <bean class="smx15mins.LogService" /> 

                                </bean:bean> 

                            </bean:endpoint> 

                        </bean:endpoints>

                    </bean:component> 

                </sm:component> 

            </sm:activationSpec> 

            <sm:activationSpec componentName="eipComponent"> 

                <sm:component> 

                    <eip:component> 

                        <eip:endpoints> 

                            <eip:static-recipient-list service="foo:router"

                                                       endpoint="router"> 

                                <eip:recipients> 

                                    <eip:exchange-target service="foo:logger" /> 

                                    <eip:exchange-target service="foo:sender" /> 

                                </eip:recipients> 

                            </eip:static-recipient-list> 

                        </eip:endpoints> 

                    </eip:component> 

                </sm:component>

            </sm:activationSpec>

        </sm:activationSpecs>

    </sm:container>

</beans>

Beneficios

Observando la configuración final de nuestro conjunto de endpoints podemos ver como el acoplamiento que existe entre los distintos servicios de la solución es mínimo, y totalmente concentrado en nuestro router. Salvo éste, el resto de servicios es absolutamente independiente de los demás, por lo que podríamos reutilizar cualquiera de ellos en otra solución SOA. Además, en caso de surgir una nueva necesidad de negocio que obligara a distribuir el mensaje a un nuevo endpoint, bastaría con añadirlo a la lista de recipients, sin afectar en absoluto al resto de endpoints de la solución.

Próximos pasos

Conociendo la forma de implementar patrones de integración en ServiceMix, podemos seguir haciendo más sofisticado nuestro escenario y buscando los EIPs que lo resuelvan de la forma más universal posible, por ejemplo:

Código fuente de la solución

Para descargar el código mostrado en este tutorial, haga clic aquí.

Sebastián Gómez Eyles

Acerca de Sebastián Gómez Eyles

Sebastián es consultor de Tecsisa
Comentarios (0) Trackbacks (0)

Sin comentarios por ahora.


Deja un comentario


Sin trackbacks por el momento.