Arquitectura y componenetes

OMniLeads es una aplicación basada en múltiples componentes que residen en repositorios individuales de Gitlab, donde se almacena el código fuente y/o de configuración, los scripts de Build, Deploy y pipelines CI/CD.

Si bien al momento de ejecutar una instancia de OMniLeads los componentes interactúan como una unidad a través de conexiones TCP/IP, la realidad es que cada uno es una entidad propia con su repositorio GitLab y ciclo DevOps.

A nivel de Build cada componente se distribuye a partir de RPM (para instalaciones sobre Linux) y Docker-IMG (para instalaciones sobre Docker Engine). Con respecto al Deploy cada componente cuenta con un script first_boot_installer.tpl con el cual se puede desplegar fácilmente sobre un Linux Host de manera manual (editando variables) o invocando el mismo como plantilla de Terraform renderizando variables provistas por el mismo terraform.

Podemos pensar a cada componente como una pieza de un rompecabezas con sus atributos:

_images/arq_component.png

Descripción de cada componente

A continuación se describe cada componente:

  • OMLApp (https://gitlab.com/omnileads/ominicontacto): la aplicación Web (Python/Django/uwsgi) está contenida en OMLApp.

    Nginx es el webserver que recibe la peticiones HTTPS y redirecciona hacia Django la solicitudes pertinentes. OMLApp interactua con varios componentes a la hora de provisionar configuración o generar llamadas. OMLApp utiliza PostgreSQL como motor SQL, Redis como caché y también para provisionar la configuración de Asterisk ya sea a través de archivos .conf así como también generando ciertas estructuras clave/valor que son consultadas por asterisk en tiempo real a la hora de procesar llamadas de campañas. OMLApp se conecta a la interfaz AMI de Asterisk para generar llamadas y recargar alguna que otra configuración, también realiza conexiones hacia la API de Wombat Dialer cuando es necesario generar campañas con discado predictivas.

_images/arq_omlapp.png
  • Asterisk (https://gitlab.com/omnileads/omlacd): OMniLeads se apoya en el framework Asterisk a la hora de definir un ACD, es decir en la implementación de lógica de negocio; campañas telefónicas, grabaciones, reportes y métricas de la canalidad telefónica. A nivel conexiones de red, Asterisk recibe peticiones AMI desde OMLapp y desde Wombat Dialer, a su vez que necesita conexión hacia PostgresSQL para dejar logs, hacia Redis para consultar parámetros de campañas provisionados desde de OMLApp, también necesita acceder a Nginx para el establecimiento del Websocket utilizado para el push/pull de archivos .conf (etc/asterisk) de configuración generados desde OMLApp.
_images/arq_omlacd.png
  • Kamailio (https://gitlab.com/omnileads/omlkamailio): este componente es utilizado en connjunto con RTPengine a la hora de gestionar comunicaciones WebRTC (SIP over WSS) contra los usuarios Agentes a su vez mantiene sesiones (SIP over UDP) contra Asterisk. A Kamailio le llegan los REGISTER generados por el webphone (JSSIP) desde los Agentes por lo tanto se encarga de la labor de Registro y Localización de usuarios utilizando REDIS para almacenar la localización de cada usuario. Para Asterisk todos los agentes se encuentran disponibles en la URI de Kamailio por lo tanto Kamailio recibe INVITES (UDP 5060) desde Asterisk cuando éste requiere «ubicar» un agente para conectar una llamada. Finalmente mencionar el hecho de que Kamailio genera conexiones hacia RTPengine (TCP 22222) a la hora de establecer sesiones SIP entre Asterisk VoIP y los agentes WebRTC.
_images/arq_omlkamailio.png
  • RTPengine (https://gitlab.com/omnileads/omlrtpengine): OMniLeads se apoya en RTPengine a la hora del transcoding y bridge entre la tecnología WebRTC y la tecnología VoIP. El componente mantiene canales de audio sRTP-WebRTC con los usuarios Agentes por un lado, mientras que por el otro establece canales RTP-VoIP contra Asterisk. RTPengine recibe conexiones desde Kamailio al puerto 22222.
_images/arq_omlrtpengine.png
  • Nginx (https://gitlab.com/omnileads/omlnginx): El web server del proyecto es NGINX y tiene como tarea recibir la peticiones TCP 443 por parte de los usuarios así como también desde algunos componentes como Asterisk. Por un lado NGINX es invocado cada vez que un usuario dispara el URL implicado en el ambiente desplegado, las peticiones de los usuarios tienen como destino renderizar alguna vista de la aplicación web Django o establecer un websocket contra Kamailio (para el manejo de las llamadas) o un websocket contra el componente python websocket, nginx se encarga de redireccionar las peticiones hacia el destino correcto. Por otro lado Asterisk apunta a Nginx para alcanzar el componente python-websocket utilizado para la gestión de configuraciones en archivos (/etc/asterisk/.conf).
_images/arq_omlnginx.png
  • Python Websocket (https://gitlab.com/omnileads/omnileads-websockets): OMniLeads se apoya en un servidor de websockets utilizado para dejar corriendo tareas en segundo plano (reportes y generación de CSV) y recibir una notificación asíncrona cuando la tarea se haya completado, esto optimiza el desempeño de la aplicación. A su vez es utilizado como «puente» entre OMLApp y Asterisk en el provisionamiento de la configuración de archivos .conf (/etc/asterisk). A iniciar Asterisk se lanza un proceso que establece el WS contra dicho componente y a partir de allí recibe notificaciones cada vez que se proporcionan cambios en la configuración. En su configuración por defecto levanta el puerto TCP 8000 y las conexiones recibidas son siempre redirigidas desde Nginx.
_images/arq_omlws.png
  • Redis (https://gitlab.com/omnileads/omlredis): Redis es utilizado con tres fines bien concretos, por un lado como caché para almacenar resultados de queries recurrentes implicadas en las vistas de supervisión de campañas y agentes, por otro lado se utiliza como DB para la prescencia de los usuarios y finalmente para el almacenamiento de la configuración de Asterisk (/etc/asterisk/) así como también los parámetros de configuración implicados en cada módulo (campañas, troncales, rutas, IVR, etc.) oficiando de esta manera como si fuera AstDB.
_images/arq_omlredis.png
  • PostgreSQL (https://gitlab.com/omnileads/omlpgsql): PGSQL es el motor de DB SQL utilizado por OMniLeads. A partir de allí se materializan todos los reportes y métricas del sistema. También allí se almacena toda la información de configuración que debe persistir en el tiempo. Recibe conexiones en su puerto TCP 5432 desde los componentes OMLApp (lectura / escritura) y desde Asterisk (escritura de logs).
_images/arq_omlpgsql.png
  • Wombat Dialer (https://manuals.loway.ch/WD_UserManual-chunked/ch07.html): Para trabajar con campañas de discado predictivo OMniLeads recurre a este software de terceros comercial llamado Wombat Dialer. Este discador cuenta con una API (TCP 8080) sobre la cual OMLApp genera conexiones para provisionar campañas y contactos, mientras que Wombat Dialer recurre a la interfaz AMI del componente Asterisk a la hora de generar llamadas salientes automáticas y checkear el estado de los agentes de cada campaña. Este componente utiliza su propio motor SQL (MySQL) para operar.
_images/arq_omlwd.png

Deploy y variables de entorno

Cada componente encaja como un rompecabezas que conforma la Aplicación OMniLeads. Como se explica en la sección de instalación, los componentes pueden convivir en un Linux Host compartido o bien ser desplegados individualmente en forma de cluster horizontal.

En el momento de materializar un componente sobre un Linux Host individual o compartido por otros componentes, todos los parámetros de configuración necesarios son provisionados a través de variables de entorno. De esta manera logramos una compatibilidad a la hora de construir los binarios (RPM y Docker-Img) así como también a la hora de generar un deploy de OMniLeads utilizando instancias Linux o Contenedores Docker.

_images/arq_envvars_deploy.png

El hecho de provisionar los parámetros de configuración vía variables de entorno y además considerando la posibilidad de desplegar siempre la aplicación resguardando los datos que deben persisitir (grabaciones de llamadas y la base de datos PostgreSQL) sobre recursos montados en sobre el sistema de archivos del linux que vehiculiza cada componente, nos permite plantear la inmutabilidad de la infraestructura.

Es decir podemos facilmente destruir y recrear cada componente sin perder los datos importantes, por lo que a la hora de hacer un redimensionamiento de componentes o plantear actualizaciones podremos simplemente descartar el host donde corre una versión y desplegar uno nuevo con la última actualización. Sin que esto sea un mandato, ya que se pueden manejar las actualizaciones desde la óptima mas tradicional tenemos el potencial del abordaje que plantea la infraestructura como código / infraestructura inmutable planteado desde la perspectiva de la cultura DevOps.

_images/arq_envvars_deploy_2.png