4. IMPLEMENTATION
4.5. Optimization with Genetic Algorithms
4.1.1. Componente “APP PLATFORM”
En la siguiente figura se muestran todos los subcomponentes que conforman la APP Platform.
En donde:
API Rest Layer
: Esta capa es el medio para conectar cada subcomponente de la APP PLATFORM con el componente WEB APP. Actúa como intermediario entre cada uno de los servicios ofrecidos por la plataforma y las aplicaciones que los utilizan, brindando un acceso uniforme y estandarizado. De esta forma se permite implementar una arquitectura multiservicio en el componente App Platform, que permite distintas opciones de despliegue para cada uno de los servicios en función de las necesidades de escalabilidad y mantenimiento que se vaya presentando con el uso de la infraestructura y por la demanda de los usuarios. Para garantizar el acceso unificado descripto, e incluso para permitir a futuro trabajar con dos o más versiones distintas de una API REST a través de un mismo dominio de acceso,
Página 44 de 86
Figura 10: Diseño Arquitectura APP PLATFORM Auth
Service
Arquitectura componente APP PLATFORM
User Service
Itinerary Service API REST LAYER
ORM DBPARSER
BD
Knowledge Service
esta capa utiliza entre sus componentes un proxy reverso, y permite la inclusión de balanceadores de carga, permitiendo así ejecutar distintas versiones de la plataforma y de los servicios de forma paralela, de forma de permitir adaptarse a los cambios y requerimientos con un impacto mínimo en los servicios y aplicaciones existentes. Para implementar esta capa se usa de base una especificación REST3 que sigue el estándar de OpenAPI4 (para ello se implementa utilizando herramientas y módulos de Swagger5), el intercambio de datos se realiza en formato JSON. Para construir el acceso a los puntos de entrada (entrypoints o endpoints) se utiliza Hapi.JS6 y para integrar la especificación de OpenAPI se utiliza Swagger-Hapi Plugin7. El proxy reverso se realiza con Nginx, pero puede realizarse con otras opciones como Apache2 Proxy o HAProxy; dependiendo de los condicionamientos de la infraestructura de despliegue.
Auth Service y
User Service
: Estos componentes trabajan en conjunto.
• Auth Service: gestiona los permisos de accesos de los usuarios. Se encarga de validar la identidad de los usuarios y de proveer autorización para acceder a los recursos que App Platform ofrece a través de las puntos de entrada de la API REST. Para minimizar la exposición de las credenciales de usuario, este componente genera un JSON Web Token8 utilizando como referencia un protocolo basado en OAuth29 para autorizar el uso de los recursos del sistema.
3 REST (Representational State Transfer) - https://en.wikipedia.org/wiki/Representational_state_transfer 4 OpenAPI Initiative - https://www.openapis.org/
5 Swagger es un conjunto de herramientas para el desarrollador de APIs que sigan la especificación de OpenAPI - http://swagger.io/
6 https://hapijs.com/ 7 https://hapijs.com/plugins
8 JSON Web Token (RFC 7519) - https://jwt.io/ 9 OAuth version 2 - https://oauth.net/2/
• User Service: gestiona los perfiles de usuarios, así como los datos requeridos para su verificación de identidad (nombre de usuario, identificador, email y contraseña). Es utilizado principalmente por Auth Service en la etapa de verificación de identidad, previo a la generación del token de permiso utilizado para obtener el token de acceso (ver protocolo OAuth210 para mayor información).
Itinerary Service
: Gestiona todos los servicios relacionados a las Actividades, Punto de interés, Traslados y demás datos que permiten obtener y crear los itinerarios; así como también se encarga de proveer los servicios de creación y filtrado de los itinerarios.
Knowledge Service
: Provee el acceso a todos los servicios que gestionan la información de conocimiento utilizados para generar los itinerarios, para realizar filtrados basados en aprendizaje, y para la integración futura de servicios basados en inteligencia artificial y deep learning. A través de este servicio, Itinerary Service genera perfiles de aprendizaje de los itinerarios, y aprende los tiempos de los nodos Actividad-Puntos-de-interés utilizados en la construcción de un itinerario.
ORM : El acceso que requiera persistencia en el sistema, se realiza a través de un componente que media entra la tecnología de persistencia subyacente y los servicios que la utilizan. Para ello se utiliza un engine que mapea datos relacionales en objetos, y permite interactuar con ellos de forma independiente a la tecnología subyacente. Este componente permite ser intercambiado o extendido para permitir diversas tecnologías de representación de datos según se requiera, ya sea una base de datos No-SQL como
10 Flujo protocolo OAuth2 - https://tools.ietf.org/html/rfc6749#section-1.2
ser por ejemplo Neo4J o Redis, o soportar bases de datos multiengine como MariaDB. Esta capa permite así no condicionar los servicios a una representación específica en la persistencia, y permite niveles de modificabilidad con bajo impacto arquitectónico ante cambios en los requerimientos de la tecnología de persistencia.
En este proyecto se utilizó como implementación de referencia a Sequelize.JS11, sobre todo por su estabilidad y por ser una tecnología battle-tested, y por contar por un mecanismo de migraciones y creación de estructuras de datos agnóstico a la tecnología de persistencia subyacente.
DB : Para la base de datos se utilizó MySQL 5.712 dado que tiene soporte para guardar objetos en formato JSON13 y Georeferencial (para la gestión de los datos georeferenciales de los Puntos de Interés), de esta forma permite realizar representaciones híbridas de datos SQL- No SQL, que dan lugar a prescindir inicialmente del uso de dos base de datos (por ejemplo una documental como MongoDB y una relacional como MySQL con engine InnoDB), y permitir utilizar una sola que provea lo mejor de los dos mundos (MySQL permite realizar consultas sobre los datos JSON y permite realizar consultas optimizadas sobre los datos georeferenciales, desde su última versión).
DBPARSER : Este Parser se definió para poder independizarse aún más de la representación de bajo nivel provista por el ORM de la utilizada en general por los servicios. Los registros de datos provistos por el ORM mantienen una convención de nombre estándar que se acerca o respeta a la utilizada por la tecnología de persistencia subyacente (ver sección “Base de datos”), en cambio los servicios usan una representación de objetos pura, que respeta las
11 http://docs.sequelizejs.com/ 12 https://www.mysql.com/ 13 http://www.json.org/
definiciones fijadas en la especificación de la API REST (OpenAPI Definitions), por ello el componente DBParser, realiza transformaciones entre los objetos retornados por el ORM para llevarlos al formato de salida requerido por los servicios a fin de utilizar también la especificación como un estándar común de comunicación entre servicios y entre la plataforma y las aplicaciones.
Algunas consideraciones
El componente Auth Service tal como esta planteado puede ser desplegado en otro servidor, en caso de que se necesite escalar la aplicación y se tenga que gestionar de forma separada toda la validación de usuarios, o si se prefiere delegar este servicio a un tercero (por ejemplo Auth014).
Interacción entre componentes
El flujo entre los subcomponentes del componente App Platform, se produce de la siguiente forma:
1. Una petición entrante llega a la plataforma desde una aplicación, en forma de una petición HTTP (preferiblemente utilizando HTTPS para seguridad). La petición va dirigida a una URL específica que contiene un punto de entrada correspondiente en la especificación REST creada. Un proxy reverso redirige al servidor adecuado en función del dominio y la versión, de ahí es atendida por un servidor HTTP implementado en NodeJS y HapiJS. Si la petición es una autenticación, primero serán obtenidas de la petición los datos de la credenciales, y son pasados a Auth Service, esté verifica en conjunto con User Service que el usuario exista y retorna un token de permiso, que en una petición posterior la aplicación debe utilizar para acceder a un token de acceso con vencimiento. Si la petición es de acceso a recursos del sistema, se obtienen el token de acceso del header de la petición HTTP y el verbo HTTP, de allí se envía a Auth Service para verificar que el token sea válido, es decir que pertenezca a un usuario existente en el sistema, por lo cual Auth Service junto a User Service determinan la identidad, y Auth Service a su vez verifica que el token no esté vencido y que pertenezca a una aplicación autorizada. Una vez todo verificado, en función del verbo HTTP y del punto de entrada, se
14 Plataforma de identidad Auth0 - https://auth0.com/
extraen los parámetros y se pasan al servicio correspondiente.
2. Se produce la ejecución de los servicios vía Itinerary Service si se requieren datos u operaciones sobre los itinerarios, y la ejecución de los servicios vía User Service si se requieren datos y operaciones sobre los perfiles de usuarios. Cada uno de estos servicios interactúan con el ORM y DBParser (y en el caso de Itinerary Service con Knowledge Service si se trata de un alta de un itinerario).
3. El ORM interactúa con las tecnologías de persistencia subyacente (base de datos MySQL en este caso). Una vez se realiza la operación requerida retorna el resultado al servicio que lo llamó.
4. El componente que realizó el llamado inicial al ORM obtiene la respuesta que es normalizada por DBParser y pasa estos datos a la API Layer.
5. En la API Layer retorna los resultados en formato JSON, a través de un HTTP Response, con el código HTTP de resultado de la operación (200 en caso de éxito, 401 en caso de acceso denegado por tener credenciales erróneas, 406 por un error de validación en los datos, 404 si el recurso no se encontró, y 500 si existió un error en la ejecución del servicio). La respuesta HTTP es enviada a la aplicación.