El propósito de este artículo es mostrar mi experiencia, después de realizar el curso de Fundamentos de programación en iOS, de un primer “proyecto” que combina el uso de iOS, NodeJS, RabbitMQ y MongoDB. Para ello, quiero mostrar cómo hacer que un dato viaje desde una App en iOS hasta diversos componentes desarrollados en NodeJS, usando RabbitMQ y WebServices, así como su almacenamiento en MongoDB.
Este viaje es una metáfora del viaje real que hace una maleta cuando es facturada en un gran aeropuerto. Este proyecto forma parte de un “hobby proyecto” que estoy desarrollando en mi blog superfreak sobre aviación y tecnologías, podéis ver más sobre el proyecto aquí y en los artículos ya publicados.
¿Qué encontrarás en este post?
ToggleEl Proyecto. Cómo hacer que tu maleta se suba al avión contigo.
Para tan sufrido objetivo, sobre todo para los pasajeros, vamos a simular el funcionamiento de este procedimiento en la mayoría de los aeropuertos mundiales “grandes”. En modo resumen el proceso es el siguiente:
- El sufrido pasajero se presta a facturar su maleta en el mostrador de la compañía.
- El agente de facturación, tras revisar la documentación, expide la tarjeta de embarque y genera las etiquetas de equipaje para adherirlas a la maleta.
- En ese preciso momento, el sistema de facturación de la compañía aérea genera genera un mensaje, denominado BSM (Baggage Source Message), con los datos que identifican la maleta: su vuelo, destino, horario de partida, nombre del pasajero, etc.
- Este mensaje, primero viaja al Host de la compañía (fuera del aeropuerto), el sistema central encamina el mensaje, a través de una red mundial aeronáutica de datos, hacia el sistema automático de clasificación de equipajes del aeropuerto. Este viaje no dura más de 1 o 2 segundos. En nuestro caso, para simplificar, nos saltaremos este paso, no deja de ser una pasarela entre el sistema de facturación y de equipajes.
- La maleta empieza su viaje por el laberinto de cintas del aeropuerto y se topa con un primer arco lector de códigos de barras, también los hay que leen RFID, etc. como prefiráis.
- El lector lee el código y comprueba en el sistema de equipajes, BHS (Baggage Handling System), que existe almacenado un registro que concuerda con la lectura de la etiqueta del equipaje.
- Si es así, el sistema ya sabe qué hacer con el equipaje, su camino, dónde debe dirigirlo. Durante el camino se producirán más lecturas para ir conociendo el estado del equipaje.
- El equipaje llega a su destino (hipódromo de formación) y ya se puede cargar en la bodega del avión.
De modo general, en el siguiente diagrama se pueden ver los diferentes actores y componentes de este viaje.
En el diagrama podéis observar la aparición del sistema AODB (Airport Operational Database), es el sistema principal de un aeropuerto, el que contiene los vuelos, horarios, estados, puertas de embarque, etc. En este artículo lo usaremos para ver vuelos, pero quería mencionarlo para que podáis ver la potencialidad de sistemas que están conectados a un ESB de cualquier aeropuerto “de los grandes”.
Una vez definido el proceso, vamos a ver cómo construimos el sistema para soportarlo. Las piezas son:
- Un sistema de facturación de pasajeros y equipajes. Departure Control System (DCS). Será nuestra App en iOS.
- El Host de la aerolínea que tiene las reservas de los pasajeros y es el que remite los mensajes que identifican a los equipajes. Desarrollado en NodeJS y se comunica con el DCS mediante Web Service.
- El AODB, contiene los vuelos que podemos consultar en el DCS, veremos su código, destino, hora y puerta de embarque asignada.
- Un bus de mensajería, o ESB, que distribuirá los mensajes de equipajes entre el Host de la aerolínea y el sistema de equipajes del aeropuerto. Baggage Handling System (BHS). Usaremos RabittMQ.
- El sistema de equipajes (BHS) que recibe los mensajes desde el bus de mensajería y los almacena en su base de datos. El sistema también estará desarrollado en NodeJS y la base de datos será MongoDB.
Esta es la arquitectura que planteamos:
El DCS
El sistema Departure Control System es el sistema que tiene las reservas de los pasajeros, el que permite emitir las tarjetas de embarque y las etiquetas de equipaje (tanto en mostrador como en kioscos) y además permite también realizar el proceso de embarque. En nuestro caso la App va a contener las siguientes cuatro secciones principales:
- Home: pantalla principal de bienvenida.
- Check Pax (Facturación de Pasajeros): en este apartado facturaremos a los pasajeros emitiendo su tarjeta de embarque y su etiqueta de equipaje, ambas “virtuales”.
- Sell Flights: esta sección está, “under construction” y la realizaré para probar el uso de una API pública que ha publicado una gran aerolínea.
- List Flights: mostrará los vuelos que tenemos en nuestro aeropuerto virtual, nos permitirá ver su código, destino, hora de salida y puerta de embarque asignada.
Vayamos al grano. Vamos a facturar a nuestro primer pasajero, el cual viene con una reserva con número AER0005. Esta reserva la tenemos previamente introducida en nuestra Colección de Reservas en MongoDB.
Pues iniciemos el proceso:
En este momento consultamos mediante WebService al backend de nuestro DCS, desarrollado en NodeJS, el backend tiene disponible un servicio REST para tal efecto.
Por lo tanto llamaremos al servicio /CheckPax/:ResNumber con el número de la reserva.
La petición llega al WebService, el cual la encamina al método correspondiente y realiza la búsqueda en la base de datos.
Et voilá, recuperamos los datos del pasajero en nuestro DCS sin trampa ni cartón.
Procedamos entonces a emitirle su tarjeta de embarque y la etiqueta de equipaje, para lo primero, introduciremos el asiento deseado (23F) y la emitimos con los datos del vuelo y del pasajero.
Por cierto la librería para la generación del QR es bastante sencilla de utilizar, la tenéis disponible, como no, en GitHub
Ahora toca disparar el evento que da sentido a este artículo, la emisión de la etiqueta de equipaje, indicamos que tenemos solo una maleta y emitimos la etiqueta.
Esta etiqueta contiene la información del vuelo y el identificador de la etiqueta (matrícula en el argot), procedemos a enviarla al backend del DCS, mediante el WebService disponible (/CheckPax/BSM:BSMNumber), en donde llamaremos al método correspondiente, sendBSM. Este método enviará el BSM a una cola a la que está suscrita el sistema de equipajes (BHS).
Antes de continuar veamos brevemente qué es un ESB y una breve descripción de RabbitMQ.
¿Que es un ESB?
Enterprise Service Bus, es una plataforma que permite comunicar, integrar y transformar la información entre varias aplicaciones, orientado a mensajes o eventos y que permite abstraer las arquitecturas de cada sistema y los protocolos que usan. Dentro de sus múltiples características y ventajas podemos destacar las siguientes:
- Permite desacoplar la lógica de negocio, si bien es cierto que las herramientas actuales permiten interactuar con la lógica de negocio e incorporarse a la misma.
- Conversión de protocolos de comunicación o estructuras de datos. Permite conectar, mediante adaptadores, aplicaciones que utilicen diferentes protocolos tanto de entrada como de salida al BUS. Por ejemplo de HTTP -> JMS, de FTP ->MQSeries, SOAP -> EJB, etc.
- Transformación de mensajes. Permite adaptar, componer, agregar, etc. la información contenida en los mensajes.
- Encaminamiento de mensajes. Filtra y encamina los mensajes basados en técnicas de tópicos, colas, etc.
- Permite una comunicación tanto síncrona como asíncrona entre sus componentes.
No acabaría este artículo contando más detalles, al final os incluiré algunas referencias por si queréis profundizar más, pero en nuestro caso vamos a usar RabbitMQ como ESB, a este ESB vamos a conectar el backend del DCS y el sistema de equipajes, BHS, para ello de momento usaremos la cola como medio de intercambio ya que sabemos que este mensaje sólo interesa al BHS y que los va a consumir según su orden de entrada. Para otros tipos de integración entre sistemas, en los que más sistemas pueden estar interesados por una mismo información, del tipo petición/respuesta y sobre todo para publicación/subscripción es más útil usar los tópicos como medio muy potente de envío y filtrado.
¿Qué es RabbitMQ?
RabbitMQ Es un sistema de mensajería de código abierto, escrito en Erlang, y que implementa el protocolo AMQP usado por multitud de sistemas de mensajería tanto libres como comerciales. Está disponible para casi todos los lenguajes de programación y sistemas operativos.
El concepto principal de AMQP es poner en contacto dos, o más, extremos para intercambiar información, y esto se hace con dos elementos fundamentales:
- El Broker de mensajería, que es el que recibe y gestiona los mensajes.
- Canal en donde los clientes consumen y producen mensajes.
En el caso de RabbitMQ el broker de mensajería está conformado por dos partes básicas:
- Exchanges: que es donde se filtran y encaminan los mensajes a las colas, ya sea uno a uno, mediante tópicos, reglas, etc.
- Queues (colas): que almacenan los mensajes para que sean consumidos por los clientes.
Os recomiendo una breve introducción de un amigo mío sobre amqp y RabbitMQ.
Volvamos al lío, vamos a conectarnos a nuestra cola de RabbitMQ para poder enviar mensajes desde el DCS al BHS. En NodeJS sería así (lo haremos de igual forma en ambos sistemas DCS y BHS):
Pues bien, ya podemos comunicar ambos sistemas y realizar el viaje completo desde que emitimos la etiqueta de equipaje hasta que el mensaje llega al BHS y permitirá casar los equipajes físicos con el BSM.
El viaje de la maleta
Tras este breve apunte sobre ESB y RabbitMQ, retomamos donde lo habíamos dejado, acabábamos de imprimir la etiqueta de equipaje, en ese momento, construimos el mensaje BSM y procedemos a enviarlo al backend del DCS mediante WebService. El mensaje que identifica a la maleta es el siguiente:
BSM.V/.F/DLH3293/1/.N/2041483196.P/CARMENRIVASENDBSM
Es un mensaje formateado mediante separadores, por ejemplo .F indica el vuelo, en este caso es un vuelo de Lufthansa DLH3293 vuela con un equipaje (/1/), la matrícula del equipaje, campo .N, es 2041483196 y el pasajero se llama CARMENRIVAS (ya sabemos la peculiaridad de composición de nuestros nombres en las tarjetas de embarque).
Una vez enviado al backend, éste, que ya está conectado a la cola de RabbitMQ, lo remite en formato JSON.
La aplicación BHS recoge de la cola bsm el mensaje y lo inserta en la colección de bsms que tenemos en MongoDB, esta es la secuencia expresada en el código.
El mensaje queda insertado en la base de datos y ya se quedará a la espera de que la etiqueta del equipaje sea leída por el primer arco lector del sistema de transporte de equipajes y así pueda ser casado y encaminado al hipódromo desde el cual será llevado a la bodega del avión.
La siguiente pantalla muestra el registro de los diferentes BSMs que van llegando al sistema BHS, el inferior de la lista es el que hemos generado. Estos mensajes son servidos por la aplicación BHS en NodeJS mediante WebService.
Listado de vuelos
Faltaba por mostrar la funcionalidad del listado de vuelos, en este caso tenemos otra aplicación, desarrollada también bajo NodeJS, el AODB que contiene la información acerca de los vuelos del aeropuerto, así como sus diferentes atributos. Una vez más, la información es servida mediante WebService a nuestro DCS en iOS.
Los vuelos son mostrados en la sección de la aplicación correspondiente, en rojo os he marcado el vuelo para el que hemos facturado el equipaje.
Fin del trayecto
Espero que os haya entretenido el post. Si deseáis saber un poco más sobre el mundo de los sistemas aeroportuarios, integración de sistemas.