scieee AI-readable full text Open interactive document viewer

Aplicación móvil Ionic para la gestión de incidentes en carretera usando Kafka, Confluent, PostgreSQL, MicroProfile y Grafana

Castillo González, Alberto

Abstract

A nivel mundial, los accidentes de tráfico suponen casi 1,3 millones de muertes prevenibles y alrededor de 50 millones de lesiones cada año, lo que la convierte en la principal causa de muerte de niños y jóvenes en todo el mundo. Así se indica en el Plan Mundial para el Decenio de Acción para la Seguridad Vial 2021 2030[1], declarada de forma unánime por los gobiernos de todo el mundo en la Asamblea General de la ONU (Resolución 74/299) y con el objetivo fundamental de reducir las muertes y lesiones en al menos un 50% durante este periodo. Para lograr este objetivo, adquieren importancia los Sistemas de Transporte Inteligentes (ITS). Según la Unión Internacional de Telecomunicaciones (ITU) [2], se definen como sistemas que utilizan la combinación de ordenadores, comunicaciones, dispositivos de determinación de la posición y tecnologías de automatización para mejorar la seguridad, la gestión y la eficacia del transporte terrenal. Aplicando estas herramientas, sería posible evitar el fallo humano e impedir, en el caso de producirse, que tuviera consecuencias fatales. En este proyecto nos vamos a centrar en este último caso, en el que un conductor ha tenido una incidencia en carretera y quiere alertar a los servicios de emergencia para que le asistan. Utilizaremos una aplicación móvil que permitirá al dispositivo actuar como una baliza V16 [3] (capaz de comunicar su posición al punto de acceso nacional en materia de tráfico y movilidad) y enviar los datos del incidente a una cola de mensajes Kafka, permitiendo que múltiples usuarios reporten las alertas de forma continuada y simultánea. Además, los operarios que deban atender estos incidentes tendrán otra interfaz de la aplicación móvil, mediante la que podrán ver qué incidentes se están produciendo y obtener una ruta para atenderlos. Por último, también se proporciona un “dashboard” en Grafana que permite la monitorización de los incidentes y sus intervenciones.

Full text

indi Equation Chapter 1 Section 1 Trabajo de Fin de Grado Grado en Ingeniería de las Tecnologías de Telecomunicación Aplicación móvil Ionic para la gestión de incidentes en carretera usando Kafka, Confluent, PostgreSQL, MicroProfile y Grafana Dpto. de Ingeniería Telemática Escuela Técnica Superior de Ingeniería Universidad de Sevilla Autor: Alberto Castillo González Tutor: María Teresa Ariza Gómez Sevilla, 2023 iii Trabajo de Fin de Grado Grado en Ingeniería de las Tecnologías de Telecomunicación Aplicación móvil Ionic para la gestión de incidentes en carretera usando Kafka, Confluent, PostgreSQL, MicroProfile y Grafana Autor: Alberto Castillo González Tutor: María Teresa Ariza Gómez Profesora titular Dpto. de Ingeniería Telemática Escuela Técnica Superior de Ingeniería Universidad de Sevilla Sevilla, 2023 v Trabajo de Fin de Grado: Aplicación móvil Ionic para la gestión de incidentes en carretera usando Kafka, Confluent, PostgreSQL, MicroProfile y Grafana Autor: Alberto Castillo González Tutor: María Teresa Ariza Gómez El tribunal nombrado para juzgar el Proyecto arriba indicado, compuesto por los siguientes miembros: Presidente: Vocales: Secretario: Acuerdan otorgarle la calificación de: Sevilla, 2023 El Secretario del Tribunal vii A mi familia A mis maestros ix Agradecimientos Agradecer a Teresa por haberme permitido realizar este proyecto y haberme ayudado siempre en todo lo que he necesitado. Agradecer a mi familia y amigos por haberme apoyado en los momentos más difíciles y por haber celebrado conmigo las pequeñas victorias del día a día. Alberto Castillo González Sevilla, 2023 xvii ÍNDICE DE TABLAS Tabla 1 Tabla Usuarios 43 Tabla 2 Tabla Contactos 44 Tabla 3 Tabla Incidentes 44 Tabla 4 Tabla Intervenciones 45 xix ÍNDICE DE ILUSTRACIONES Ilustración 1 Plan ITS de la Dirección General de Tráfico 25 Ilustración 2 Arquitectura de la solución adoptada 26 Ilustración 3 Ionic Framework 29 Ilustración 4 MicroProfile 30 Ilustración 5 Apache Kafka 31 Ilustración 6 Confluent 31 Ilustración 7 Arquitectura de un dashboard en Grafana 32 Ilustración 8 Grafana 32 Ilustración 9 PostgreSQL 33 Ilustración 10 Visual Studio Code 35 Ilustración 11 Thunder Client 35 Ilustración 12 GitHub Desktop 36 Ilustración 13 pgAdmin 36 Ilustración 14 Google Chrome 37 Ilustración 15 Windows Terminal 37 Ilustración 16 Visual Paradigm Online 38 Ilustración 17 Diagrama de componentes 39 Ilustración 18 Diagrama de secuencia: Reportar incidente 40 Ilustración 19 Diagrama de secuencia: Atender incidente 41 Ilustración 20 Modelo relacional 42 Ilustración 21 Creación del JDBC Sink Connector 49 Ilustración 22 Funcionalidad API REST Contactos 57 Ilustración 23 Funcionalidad API REST Incidentes 58 Ilustración 24 Funcionalidad API REST Intervenciones 59 Ilustración 25 Funcionalidad API REST Usuarios 60 Ilustración 26 Raíz de la aplicación móvil Ionic 63 Ilustración 27 Carpeta /src de la aplicación móvil Ionic 64 Ilustración 28 Carpeta /app de la aplicación móvil Ionic 65 Ilustración 29 Icono de la aplicación móvil 67 Ilustración 30 Pantalla de bienvenida 68 Ilustración 31 Pantalla Login 69 Ilustración 32 Pantalla Login: Error campos vacíos 70 Ilustración 33 Pantalla Login: Error formato 70 Ilustración 34 Pantalla Login: Error campos incorrectos 71 Ilustración 35 Pantalla Login: Error usuario no existe 72 Ilustración 36 Pantalla Login: Error contraseña incorrecta 72 Ilustración 37 Pantalla Login: Elegir rol 73 Ilustración 38 Pantalla Registro 73 Ilustración 39 Pantalla Registro: Error formato 74 Ilustración 40 Pantalla Registro: Formulario completo 74 Ilustración 41 Pantalla Inicio: Interfaz conductor 75 Ilustración 42 Pantalla Inicio: Interfaz operario 75 Ilustración 43 Pantalla Menú 76 Ilustración 44 Pantalla Configuración 77 Ilustración 45 Pantalla Editar Usuario 78 Ilustración 46 Pantalla Editar Usuario (continuación) 78 Ilustración 47 Pantalla Configuración: Eliminar usuario 79 Ilustración 48 Pantalla Configuración: Cambiar tema 79 Ilustración 49 Pantalla Login: Tema dark 80 Ilustración 50 Pantalla Inicio: Tema dark 80 Ilustración 51 Pantalla Contactos: Tema dark 80 Ilustración 52 Pantalla Login: Tema purple 81 Ilustración 53 Pantalla Inicio: Tema purple 81 Ilustración 54 Pantalla Contactos: Tema purple 81 Ilustración 55 Pantalla Login: Tema brown 82 Ilustración 56 Pantalla Inicio: Tema brown 82 Ilustración 57 Pantalla Contactos: Tema brown 82 Ilustración 58 Pantalla Login: Tema green 83 Ilustración 59 Pantalla Inicio: Tema green 83 Ilustración 60 Pantalla Contactos: Tema green 83 Ilustración 61 Pantalla Login: Tema red 84 Ilustración 62 Pantalla Inicio: Tema red 84 Ilustración 63 Pantalla Contactos: Tema red 84 Ilustración 64 Pantalla Contactos: Lista vacía 85 Ilustración 65 Pantalla Crear Contacto 85 Ilustración 66 Pantalla Contactos: Lista completa 86 Ilustración 67 Pantalla Editar Contacto 87 Ilustración 68 Pantalla Contactos: Eliminar contacto 87 Ilustración 69 Pantalla Ubicación 88 Ilustración 70 Pantalla Ubicación: Mapa 88 Ilustración 71 Mensaje permiso ubicación 89 Ilustración 72 Mensaje permiso SMS 89 xxi Ilustración 73 Pantalla Ubicación: Introducir nivel de peligro 90 Ilustración 74 Pantalla Ubicación: Avisar contactos 90 Ilustración 75 Mensaje SMS 91 Ilustración 76 Pantalla Ubicación: Envío de alertas finalizado 91 Ilustración 77 Pantalla Incidentes 92 Ilustración 78 Pantalla Incidentes: Atendiendo incidente 93 Ilustración 79 Pantalla Incidentes: Incidente atendido 94 Ilustración 80 Pantalla Ruta 95 Ilustración 81 Pantalla Ruta: Mapa 95 Ilustración 82 Pantalla Ruta: Error incidente no seleccionado 96 Ilustración 83 Pantalla Ruta: Ruta encontrada 96 Ilustración 84 Dashboard Grafana 97 Ilustración 85 Configuración Grafana 98 Ilustración 86 Configuración Data Source 98 Ilustración 87 Panel Mapa Incidentes 99 Ilustración 88 Consulta Incidentes sin atender 100 Ilustración 89 Consulta Incidentes siendo atendidos 100 Ilustración 90 Panel Mapa Incidentes: Atendiendo incidente 101 Ilustración 91 Panel Mapa Incidentes: Incidente atendido 101 Ilustración 92 Panel Tabla Intervenciones 102 Ilustración 93 Panel Tabla Intervenciones: Atendiendo incidente 102 Ilustración 94 Panel Tabla Intervenciones: Incidente atendido 103 Ilustración 95 Panel Tabla Incidentes 103 Ilustración 96 Instalar Java 11: Paso 1 107 Ilustración 97 Instalar Java 11: Paso 2 108 Ilustración 98 Instalar Java 11: Paso 3 108 Ilustración 99 Instalar Java 11: Paso 4 109 Ilustración 100 Instalar Java 11: Paso 5 109 Ilustración 101 Instalar Java 11: Paso 6 109 Ilustración 102 Instalar Java 11: Paso 7 110 Ilustración 103 Instalar Java 11: Paso 8 110 Ilustración 104 Instalar Java 11: Paso 9 110 Ilustración 105 Instalar Java 11: Paso 10 111 Ilustración 106 Instalar Java 11: Paso 11 111 Ilustración 107 Instalar Java 11: Paso 12 112 Ilustración 108 Instalar Java 11: Paso 13 112 Ilustración 109 Instalar Java 11: Paso 14 113 Ilustración 110 Instalar Java 11: Paso 15 113 Ilustración 111 Instalar Maven: Paso 1 113 Ilustración 112 Instalar Maven: Paso 2 114 Ilustración 113 Instalar Maven: Paso 3 114 Ilustración 114 Instalar Maven: Paso 4 114 Ilustración 115 Instalar Maven: Paso 5 115 Ilustración 116 Instalar Maven: Paso 6 115 Ilustración 117 Instalar Visual Studio Code: Paso 1 115 Ilustración 118 Instalar Visual Studio Code: Paso 2 116 Ilustración 119 Instalar Visual Studio Code: Paso 3 116 Ilustración 120 Instalar Visual Studio Code: Paso 4 116 Ilustración 121 Instalar Visual Studio Code: Paso 5 117 Ilustración 122 Instalar Visual Studio Code: Paso 6 117 Ilustración 123 Instalar Visual Studio Code: Paso 7 117 Ilustración 124 Instalar Visual Studio Code: Paso 8 118 Ilustración 125 Instalar Visual Studio Code: Paso 9 118 Ilustración 126 Instalar NodeJS: Paso 1 119 Ilustración 127 Instalar NodeJS: Paso 2 119 Ilustración 128 Instalar NodeJS: Paso 3 119 Ilustración 129 Instalar NodeJS: Paso 4 120 Ilustración 130 Instalar NodeJS: Paso 5 120 Ilustración 131 Instalar NodeJS: Paso 6 120 Ilustración 132 Instalar NodeJS: Paso 7 121 Ilustración 133 Instalar NodeJS: Paso 8 121 Ilustración 134 Instalar NodeJS: Paso 9 121 Ilustración 135 Instalar NodeJS: Paso 10 122 Ilustración 136 Instalar NodeJS: Paso 11 122 Ilustración 137 Instalar GitHub Desktop: Paso 1 122 Ilustración 138 Instalar GitHub Desktop: Paso 2 123 Ilustración 139 Instalar GitHub Desktop: Paso 3 123 Ilustración 140 Instalar GitHub Desktop: Paso 4 123 Ilustración 141 Instalar Ionic: Paso 1 124 Ilustración 142 Instalar Ionic: Paso 2 124 Ilustración 143 Instalar Ionic: Paso 3 124 Ilustración 144 Repositorio incidentes-carretera README 125 Ilustración 145 Clonar repositorio: Paso 1 125 Ilustración 146 Clonar repositorio: Paso 2 126 Ilustración 147 Instalar PostgreSQL: Paso 1 126 Ilustración 148 Instalar PostgreSQL: Paso 2 127 Ilustración 149 Instalar PostgreSQL: Paso 3 127 Ilustración 150 Instalar PostgreSQL: Paso 4 127 xxiii Ilustración 151 Instalar PostgreSQL: Paso 5 128 Ilustración 152 Instalar PostgreSQL: Paso 6 128 Ilustración 153 Instalar PostgreSQL: Paso 7 128 Ilustración 154 Instalar PostgreSQL: Paso 8 129 Ilustración 155 Instalar PostgreSQL: Paso 9 129 Ilustración 156 Instalar PostgreSQL: Paso 10 129 Ilustración 157 Instalar PostgreSQL: Paso 11 130 Ilustración 158 Instalar PostgreSQL: Paso 12 130 Ilustración 159 Instalar PostgreSQL: Paso 13 130 Ilustración 160 Instalar PostgreSQL: Paso 14 131 Ilustración 161 Instalar PostgreSQL: Paso 15 131 Ilustración 162 Instalar PostgreSQL: Paso 16 131 Ilustración 163 Instalar PostgreSQL: Paso 17 132 Ilustración 164 Instalar PostgreSQL: Paso 18 132 Ilustración 165 Instalar PostgreSQL: Paso 19 132 Ilustración 166 Instalar PostgreSQL: Paso 20 133 Ilustración 167 Instalar PostgreSQL: Paso 21 133 Ilustración 168 Instalar Confluent: Paso 1 133 Ilustración 169 Instalar Confluent: Paso 2 134 Ilustración 170 Instalar Kafka: Paso 1 134 Ilustración 171 Instalar Kafka: Paso 2 134 Ilustración 172 Instalar Kafka: Paso 3 134 Ilustración 173 Instalar Grafana: Paso 1 135 Ilustración 174 Instalar Grafana: Paso 2 135 Ilustración 175 Instalar Grafana: Paso 3 135 Ilustración 176 Instalar Grafana: Paso 4 136 Ilustración 177 Instalar Grafana: Paso 5 136 Ilustración 178 Instalar Grafana: Paso 6 136 Ilustración 179 Instalar Grafana: Paso 7 137 Ilustración 180 Instalar Grafana: Paso 8 137 Ilustración 181 Instalar Grafana: Paso 9 138 Ilustración 182 Instalar Grafana: Paso 10 138 Ilustración 183 Instalar Grafana: Paso 11 138 25 1 INTRODUCCIÓN 1.1 Motivación Los Sistemas de Transporte Inteligentes (ITS) proporcionan grandes mejoras en la eficiencia del transporte, la seguridad vial y la información a los ciudadanos. Una vez que vehículos, infraestructuras de carretera y usuarios sean capaz de comunicarse, se podrán conseguir realidades tan utópicas como evitar atascos, circular sin semáforos y evitar accidentes causados por el fallo humano. Esto es conocido por los organismos responsables, como la Dirección General de Tráfico (DGT). Desde la DGT se está colaborando con diversos proyectos piloto en materia de ITS que se están llevando a cabo en nuestro país [4]. Entre ellos, podríamos destacar la ciudad laboratorio de Málaga, el primer centro de pruebas y certificación de innovación abierta de Europa sobre tecnología V2X (vehicle to everything) para impulsar la comunicación conectada con tecnología 5G. Pero no se trata solo de una voluntad a nivel nacional, sino que coincide con la ambición de la Unión Europea. Ratificando el esfuerzo de la DGT, que lleva décadas fomentando, apoyando e impulsando el despliegue de estos sistemas, la Directiva 2010/40/UE del Parlamento Europeo y del Consejo estableció el marco para la implantación de los Sistemas de Transporte Inteligentes en el sector del transporte por carretera y para las interfaces con otros modos. Es así como surge el Plan ITS de la Dirección General de Tráfico [5], elaborado a partir de la experiencia acumulada en el despliegue de sistemas ITS y como resultado de un análisis de la materia. Se indica el equipamiento necesario, coste estimado y criterios básicos de implantación como referente técnico, con la finalidad de orientar y facilitar la toma de decisiones en la selección y utilización de dichos sistemas. Una de las fichas descriptivas de los sistemas que se incluyen en el documento se muestra en la Ilustración 1, en este caso centrada en el “desvío automatizado en infraestructuras singulares por incidentes, accidentes o catástrofes naturales”. Ilustración 1 Plan ITS de la Dirección General de Tráfico Tecnologías utilizadas 32 32 2.5 Grafana Grafana [30] es un software de código abierto que permite consultar, visualizar, alertar y explorar métricas, registros y seguimientos sin importar dónde estén almacenados. Grafana proporciona herramientas para convertir los datos de una base de datos de series de tiempo (TSDB) en gráficos y visualizaciones interesantes. Además, contiene plugins que permiten conectar otras fuentes de datos como bases de datos NoSQL/SQL. Grafana se basa en el concepto de “dashboard” [31]. Este concepto se toma prestado de los automóviles, donde un salpicadero alberga todo el sistema para vigilar el correcto funcionamiento del vehículo y la instrumentación de control de todo su equipamiento. De manera similar, un “dashboard” de Grafana consta de paneles que muestran datos en vistosos gráficos, tablas y otras visualizaciones, y que nos ayudan a comprender y administrar los sistemas. Los paneles se crean utilizando componentes que transforman los datos sin procesar de una fuente de datos en visualizaciones. Este proceso, mostrado en la Ilustración 7, implica tres fases: 1. Plugin: El objetivo de un plugin de fuente de datos de Grafana es tomar una consulta que se desea responder, recuperar los datos de la fuente de datos y arreglar las diferencias entre los modelos de datos utilizando una estructura de datos unificada llamada “data frame”. 2. Query: Permiten la reducción de la totalidad de los datos a un conjunto de datos específico, proporcionando una visualización más manejable, ayudando a resolver las preguntas concretas que se tengan sobre el sistema. 3. Transform: Cuando el formato de datos en una visualización no cumple con los requisitos, se puede aplicar una transformación que manipula los datos devueltos por una query. Algunas transformaciones podrían ser combinar varios campos o modificar el tipo de los campos. Ilustración 7 Arquitectura de un dashboard en Grafana Ilustración 8 Grafana 33 33 Tecnologías utilizadas 2.6 PostgreSQL PostgreSQL [32] es un sistema de gestión de bases de datos relacionales de objetos basado en POSTGRES, versión 4.2, desarrollado en el Departamento de Ciencias de la Computación de la Universidad de California en Berkeley. POSTGRES fue pionero en muchos conceptos que solo estuvieron disponibles en algunos sistemas de bases de datos comerciales mucho más tarde. PostgreSQL es un descendiente de código abierto de este código de Berkeley. Es compatible con una gran parte del estándar SQL y ofrece muchas características novedosas: • Consultas complejas. • Claves externas. • Triggers, que son funciones que se invocan automáticamente cuando un evento concreto tiene lugar, como insertar, actualizar o eliminar una entrada de la tabla. • Vistas actualizables. • Integridad en las transacciones. • Multi-Version Concurrency Control (MVCC), que es una técnica avanzada para mejorar el rendimiento de las bases de datos en un entorno con varios usuarios. Además, el usuario puede ampliar PostgreSQL de diversas formas, por ejemplo, añadiendo nuevos: • Tipos de datos • Funciones • Operadores • Funciones agregadas Y debido a la licencia liberal, cualquier persona puede usar, modificar y distribuir PostgreSQL de forma gratuita para cualquier propósito, ya sea privado, comercial o académico. Ilustración 9 PostgreSQL 35 3 HERRAMIENTAS Y RECURSOS UTILIZADOS 3.1 Visual Studio Code Visual Studio Code [33] es un editor de código fuente ligero pero potente que se ejecuta en el escritorio y está disponible para Windows, macOS y Linux. Viene con soporte integrado para JavaScript, TypeScript y Node.js y tiene un rico ecosistema de extensiones para otros lenguajes (como C++, C#, Java, Python, PHP, Go, .NET), temas, debuggers y más. Una extensión que utilizaremos para probar el servicio MicroProfile es Thunder Client. Con este editor desarrollaremos tanto la aplicación móvil Ionic como el servicio MicroProfile. 3.1.1 Thunder Client Thunder Client [34] es una extensión para Visual Studio Code que realiza la función de un cliente de una API REST. Fue lanzada en 2021 por Ranga Vadhineni convirtiéndose en el primer cliente de API REST basado en GUI dentro de Visual Studio Code. Algunas de sus características clave son: • Diseño simple y limpio que facilita el uso. • Ejecutar solicitudes/colecciones y ver los resultados de las pruebas. • Resaltado de sintaxis y temas de Visual Studio Code. • Interfaz de usuario de solicitud/colección abierta desde la terminal. • Mejoras en los comandos CURL. • Integración de CI/CD. Ilustración 10 Visual Studio Code Ilustración 11 Thunder Client Herramientas y recursos utilizados 36 36 3.2 GitHub Desktop GitHub Desktop [35] es una aplicación que te permite interactuar con GitHub utilizando una GUI en vez de la línea de comandos o de un navegador web. Puedes completar la mayoría de los comandos de Git con confirmaciones visuales de los cambios. Además, puedes subir (push to), extraer (pull from) y clonar repositorios remotos y utilizar herramientas colaborativas tales como atribuir commits y crear solicitudes de extracción (pull requests). Es un proyecto de código abierto. Puedes ver el itinerario, contribuir con el proyecto, o abrir un informe de problemas para proporcionar retroalimentación o solicitudes de características. Utilizaremos esta aplicación para controlar los cambios en el código tanto de la aplicación móvil Ionic como del servicio MicroProfile. Ilustración 12 GitHub Desktop 3.3 pgAdmin pgAdmin 4 [36] es la herramienta líder de código abierto para la gestión de Postgres, la base de datos de código abierto más avanzada del mundo. Está diseñado para satisfacer las necesidades tanto de los usuarios de Postgres novatos como de los más experimentados, proporcionando una potente inferfaz gráfica que simplifica la creación, mantenimiento y uso de los objetos de la base de datos. Puede utilizarse en Linux, Unix, macOS y Windows para gestionar PostgreSQL y EDB Advanced Server 10 en adelante. Ilustración 13 pgAdmin 3.4 Google Chrome Google Chrome [37] es un navegador web de código cerrado desarrollado por Google disponible de forma gratuita. El nombre del navegador deriva del término en inglés usado para el marco de la interfaz gráfica de usuario (chrome). Cuenta con más de 900 millones de usuarios y, dependiendo de la fuente de medición global, se considera el navegador más usado a nivel mundial. En nuestro proyecto, lo utilizaremos para acceder a Grafana y visualizar su contenido. 37 37 Herramientas y recursos utilizados Ilustración 14 Google Chrome 3.5 Terminal Windows Terminal [38] es una aplicación de terminal moderna, rápida, eficaz, eficiente y productiva para los usuarios de herramientas de línea de comandos y shell, como Símbolo del sistema, PowerShell y WSL. Entre las características principales se incluyen varias pestañas, paneles, compatibilidad con caracteres Unicode y UTF-8, un motor de representación de texto acelerado por GPU, y temas, estilos y configuraciones personalizados. En nuestro proyecto, lo utilizaremos para tener en una misma ventana todas las pestañas que necesitamos a la hora de preparar el entorno, con la comodidad de poder colocarle un nombre a cada una para diferenciarlas. Estas pestañas comprenderán los recursos de Kafka, Confluent y MicroProfile. Ilustración 15 Windows Terminal 3.6 Visual Paradigm Online Visual Paradigm Online [39] es una herramienta de diagramación basada en web que admite una gran variedad de diagramas técnicos y de negocios. Respecto al modelado UML, soporta 14 tipos de diagramas: • Diagrama de clase • Diagrama de caso de uso • Diagrama de secuencia • Diagrama de comunicación • Diagrama de máquina de estados Herramientas y recursos utilizados 38 38 • Diagrama de actividad • Diagrama de componentes • Diagrama de despliegue • Diagrama de paquetes • Diagrama de objetos • Diagrama de estructura compuesta • Diagrama de perfil • Diagrama de tiempos • Diagrama global de interacciones Esta herramienta la utilizaremos para crear los distintos diagramas que aparezcan en este documento. Ilustración 16 Visual Paradigm Online 39 4 ARQUITECTURA Y ANÁLISIS 4.1 Diagrama de componentes Con el fin de clarificar la arquitectura de este proyecto, vamos a apoyarnos en el diagrama de componentes mostrado en la Ilustración 17: Ilustración 17 Diagrama de componentes En primer lugar, la aplicación móvil Ionic podrá conectarse tanto con la cola de mensajes Kafka como con el servicio MicroProfile de base de datos mediante peticiones HTTP. En el caso de la cola de mensajes, el encargado de atender estas peticiones será el Confluent REST Proxy, mientras que en el caso del servicio se proporciona una API REST con los distintos métodos para consultar, insertar, actualizar y eliminar información de la base de datos. Los mensajes que vayan llegando desde el Confluent REST Proxy a la cola de mensajes Kafka irán almacenándose en la base de datos mediante el JDBC Sink Connector, que vuelca todos los datos de un topic a una tabla asociada al mismo. Por último, todos los cambios que se produzcan en la base de datos se verán reflejados en el dashboard de Grafana, permitiendo monitorizar fácilmente qué es lo que está sucediendo en nuestro entorno. 4.2 Diagramas de secuencia Una vez tenemos los componentes claros, vamos a especificar cómo se produce la interacción entre ellos. Nos vamos a centrar en dos de las tareas fundamentales del proyecto: • Un conductor reporta un incidente. • Un operario atiende un incidente. 4.2.1 Reportar incidente En la Ilustración 18 se muestra el diagrama de secuencia en el que un conductor reporta un incidente y se refleja en el dashboard: Arquitectura y análisis 40 40 Ilustración 18 Diagrama de secuencia: Reportar incidente 1. enviarAlerta(): El conductor pulsa el botón “Enviar Alerta” de la aplicación móvil. 2. postIncidente(): La aplicación móvil crea un objeto con los datos del incidente y realiza una petición POST a la dirección en la que esté escuchando el Confluent REST Proxy. Una vez que sea procesada, el objeto llega al topic de la cola de mensajes asociado a los incidentes. 3. sinkTopic(): Cuando se introduzca un nuevo mensaje en el topic, el JDBC Sink Connector está configurado para volcar los datos del mensaje en la tabla Incidentes de la base de datos. 4. getIncidentes(): De forma periódica, el dashboard está realizando consultas a la base de datos para ver si se producen cambios en la tabla Incidentes y reflejarlo gráficamente. En este caso, los pasos 4 y 5 sólo se han colocado una vez, cuando hay un cambio que reflejar, aunque, como se ha dicho anteriormente, este proceso se lleva a cabo periódicamente cada 5 segundos. 5. La base de datos devuelve el resultado de la consulta. 4.2.2 Atender incidente En la Ilustración 19 se muestra el diagrama de secuencia en el que un operario atiende un incidente y se refleja en el dashboard: 41 41 Arquitectura y análisis Ilustración 19 Diagrama de secuencia: Atender incidente 1. irPantallaIncidentes(): El operario se dirige a la pantalla Incidentes de la aplicación móvil. Cuando esta pantalla se carga, se refresca la lista de incidentes. 2. getIncidentes(): La aplicación móvil realiza una petición GET a la API REST del servicio de la base de datos para obtener la lista de incidentes. 3. getIncidentes(): El servicio realiza las consultas necesarias a la base de datos para poder formar la lista de incidentes. Cuáles son las consultas que se realizan se especificará en el punto 6 de esta memoria. 4. La base de datos devuelve los datos solicitados por el servicio. 5. El servicio devuelve la lista de los incidentes activos en ese momento. 6. La aplicación móvil muestra al operario la lista de los incidentes. 7. atenderIncidente(): El operario decide un incidente de la lista que quiere atender. 8. postIntervencion(): La aplicación móvil realiza una petición POST a la API REST del servicio de la base de datos para crear una nueva intervención asociada al conductor implicado en el incidente. En este caso, hemos supuesto que el conductor no ha sido atendido anteriormente, por lo que la intervención aún no ha sido creada. Si el conductor ya hubiera sido atendido anteriormente, esta intervención existiría en la base de datos y se realizaría una petición PUT (como en el paso 13) actualizando el estado de la intervención a “en proceso”. Cola de mensajes Kafka y proxy REST Confluent 48 48 .\bin\windows\kafka-server-start.bat .\config\server.properties Con esto, iniciamos Apache Kafka con los parámetros de configuración definidos en el fichero “server.properties”. 5.1.3 Topic Un topic es un flujo de datos sobre un tema en particular. Los topics serán identificados por su nombre y pueden dividirse en particiones en el momento de su creación. Cada elemento que se almacena en un topic se denomina mensaje, los cuales son añadidos a una partición determinada en el orden en el que fueron enviados. Es decir, se garantiza el orden dentro de una partición, pero no entre ellas. Para crear el topic que vamos a utilizar en el proyecto, ejecutamos el siguiente comando: .\bin\windows\kafka-topics.bat --create --topic incidentes --bootstrap-server 192.168.1.70:9092 --partitions 1 -- replication-factor 1 Con esto, creamos un topic, denominado “incidentes”, en el bróker de Kafka que tenemos en la dirección 192.168.1.70 y en el puerto 9092, en una sola partición y con un factor de replicación 1. 5.1.4 JDBC Sink Connector Un conector es un componente listo para usar que nos permite simplificar la integración entre sistemas externos y el clúster de Kafka. Podemos crear y ejecutar productores o consumidores reutilizables que conectan los topics de Kafka a las aplicaciones o sistemas externos, como, por ejemplo, una base de datos. JDBC Sink Connector te permite exportar los datos de un topic a cualquier base de datos relacional que esté basada en el controlador JDBC, por lo que puede soportar una gran variedad de bases de datos. El conector obtiene los datos de Kafka para escribirlos en la base de datos en función del topic al que se haya suscrito. También permite la creación automática de tablas asociadas al topic. En primer lugar, será necesario modificar el archivo “connect-distributed.properties” para añadir las siguientes características: • Modificamos la dirección y el puerto donde establecer la conexión inicial con el bróker de Kafka: o bootstrap.servers=192.168.1.70:9092 • Los convertidores especifican el formato de los datos en Kafka y cómo traducirlos a información que entienda el conector. Esta configuración debe ir en función del formato en el que se desee que se carguen o almacenen los datos en Kafka. En nuestro caso, optaremos por el formato JSON [40]: o key.converter=org.apache.kafka.connect.json.JsonConverter o value.converter=org.apache.kafka.connect.json.JsonConverter o key.converter.schemas.enable=true o value.converter.schemas.enable=true Después de realizar estas modificaciones, estamos en condiciones de ejecutar el siguiente comando: .\bin\windows\connect-distributed.bat .\config\connect-distributed.properties Con esto, iniciamos el servicio de Connect con los parámetros de configuración definidos en el fichero “connect-distributed.properties”. Para crear el conector que necesitamos, vamos a hacer uso de la API REST que incluye Connect. Por defecto, está escuchando en la dirección de localhost y en el puerto 8083, y admite los protocolos HTTP y HTTPS. Haciendo uso de la herramienta Thunder Client de Visual Studio Code, vamos a generar una petición POST, dirigida a la URL http://localhost:8083/connectors, y con el siguiente contenido: 49 49 Cola de mensajes Kafka y proxy REST Confluent Ilustración 21 Creación del JDBC Sink Connector Con esta petición, estamos indicando: • name: Nombre que queremos ponerle al conector. • connector.class: Clase del conector. • tasks.max: Número máximo de tareas simultáneas. • topics: Nombre del topic (o de los topics) que queremos vigilar. • connection.url: URL de conexión con la base de datos, donde indicamos: o Controlador de la base de datos: JDBC. o Tecnología de la base de datos: PostgreSQL. o Dirección y puerto de la base de datos: localhost:5432. o Nombre de la base de datos: incidentesCarretera. o Usuario de la base de datos: postgres. o Contraseña del usuario de la base de datos: postgres. • update.mode: Modo en el que las entradas de la base de datos se actualizan. Al elegir “update”, si el contenido de un topic se actualiza, también lo hará el contenido de la base de datos. • auto.create: Opción para que la tabla de la base de datos se genere automáticamente a partir de las características del topic. Cola de mensajes Kafka y proxy REST Confluent 50 50 5.2 Proxy REST Confluent Como ya hemos comentado cuando hablamos sobre la tecnología Confluent REST Proxy, esta herramienta nos facilita el trabajo con Kafka desde cualquier lenguaje al proporcionar un servicio HTTP RESTful para interactuar con los clústeres de Kafka. En la carpeta de Confluent, podemos encontrar una estructura similar a la que teníamos en la carpeta de Kafka, con 3 directorios principales: • bin: Contiene los ficheros ejecutables. • etc: Contiene los ficheros de configuración (properties). • lib: Contiene las librerías necesarias para que funcione correctamente. En nuestro caso, la ruta en la que se encuentra esta carpeta es “C:\Confluent\confluent-7.3.1”, por lo que, para poner en marcha el proxy REST, nos situaremos en ese directorio. A diferencia de los componentes de Kafka anteriormente mencionados, en la carpeta de Confluent no se incluye un ejecutable para Windows (“.bat”) que contenga la funcionalidad del proxy REST (sólo se incluye un ejecutable con extensión “.sh”). Por lo tanto, vamos a tener que crearlo a mano. 5.2.1 Fichero ejecutable El fichero ejecutable se denominará “kafka-rest-start.bat” y se situará en la ruta “C:\Confluent\confluent- 7.3.1\bin\windows”. Su contenido será el siguiente: java -Xmx256M -server -XX:+UseG1GC -XX:MaxGCPauseMillis=20 - XX:InitiatingHeapOccupancyPercent=35 -XX:+DisableExplicitGC -Djava.awt.headless=true - Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false - Dcom.sun.management.jmxremote.ssl=false -Dlog4j.configuration=file:C:/Confluent/confluent- 7.3.1/etc/kafka-rest/log4j.properties -cp .;C:/Confluent/confluent-7.3.1/share/java/confluentcommon/*;C:/Confluent/confluent-7.3.1/share/java/rest-utils/*;C:/Confluent/confluent-7.3.1/share/java/kafkarest-bin/*;C:/Confluent/confluent-7.3.1/share/java/kafka-rest-lib/* io.confluent.kafkarest.KafkaRestMain C:/Confluent/confluent-7.3.1/etc/kafka-rest/kafka-rest.properties Al ejecutarlo, ya estaremos obteniendo las propiedades configuradas en el archivo “kafka-rest.properties”, que se detallan a continuación. 5.2.2 Fichero de configuración El fichero de configuración, denominado “kafka-rest.properties”, se sitúa en la ruta “C:\Confluent\confluent- 7.3.1\etc\kafka-rest”. Las propiedades que configuraremos serán las siguientes: • La dirección y el puerto donde establecer la conexión inicial con el bróker de Kafka: o bootstrap.servers=PLAINTEXT://192.168.1.70:9092 • Permitir el acceso desde orígenes que no sean localhost, para que así podamos acceder a través de la red Wifi desde el teléfono móvil: o access.control.allow.origin=* o access.control.allow.methods=GET,POST,PUT,DELETE o access.control.allow.headers=origin,content-type,accept,authorization 51 51 Cola de mensajes Kafka y proxy REST Confluent 5.2.3 Interacción con la aplicación móvil No hemos cambiado la dirección ni el puerto donde escucha el proxy REST. Por defecto, atenderá a cualquier dirección que utilice el puerto 8082. En nuestro caso, desde la aplicación móvil se generarán peticiones POST cada 10 segundos, que irán dirigidas a la URL http://192.168.1.70:8082/topics/incidentes. De esta forma, estamos simulando el comportamiento de la baliza V16, que envía de forma continuada la posición actual del conductor. En el cuerpo de estas peticiones se incluirá el objeto Incidente, con los campos mostrados en la Tabla 3 Tabla Incidentes, dentro del apartado 4.3.4 Tabla Incidentes. Las peticiones POST se formarán de la siguiente manera: let headers = new HttpHeaders().set('Content-Type', 'application/vnd.kafka.json.v2+json'); let data = "{ \"records\": [ \ { \ \"key\": null, \ \"value\": { \ \"schema\": { \ \"type\":\"struct\", \ \"fields\": [ \ {\"type\":\"string\",\"optional\":true,\"field\":\"dni\"}, \ {\"type\":\"int64\",\"optional\":true,\"name\":\"org.apache.kafk a.connect.data.Timestamp\",\"version\":1,\"field\":\"fecha\"}, \ {\"type\":\"string\",\"optional\":true,\"field\":\"nombre\"}, \ {\"type\":\"string\",\"optional\":true,\"field\":\"localizacion\ "}, \ {\"type\":\"int32\",\"optional\":true,\"field\":\"peligro\"}, \ {\"type\":\"double\",\"optional\":true,\"field\":\"latitud\"}, \ {\"type\":\"double\",\"optional\":true,\"field\":\"longitud\"} \ ], \ \"optional\":false, \ \"name\":\"incidentes\" \ }, \ \"payload\": { \ \"dni\":\""+ incidente.dni + "\", \ \"fecha\":"+ incidente.fecha + ", \ \"nombre\":\""+ incidente.nombre + "\", \ \"localizacion\":\""+ incidente.localizacion + "\", \ \"peligro\":"+ incidente.peligro + ", \ \"latitud\":"+ incidente.latitud + ", \ \"longitud\":"+ incidente.longitud + " \ } \ } \ } \ ] \ } "; this.http.post("http://192.168.1.70:8082/topics/incidentes", data, { headers }); Cola de mensajes Kafka y proxy REST Confluent 52 52 • Cabeceras: Añadimos a la petición la cabecera 'Content-Type', con el valor 'application/vnd.kafka.json.v2+json'. De esta forma, el proxy REST sabrá interpretar el cuerpo de la petición y enviará el mensaje al topic. • Cuerpo: El cuerpo de la petición debe seguir la estructura mostrada en la variable data, que se completa con los datos del objeto Incidente pasado como parámetro a la función. Esta estructura es la siguiente: o Records ▪ Key ▪ Value • Schema: Indica la estructura de la tabla de la base de datos, especificando el nombre de la tabla y el tipo de cada uno de los campos. • Payload: Indica los datos que se quieren enviar a la cola de mensajes, que se van obteniendo de las propiedades del objeto Incidente enviado como parámetro. • Petición: Realizamos la petición POST a la URL indicada anteriormente. 53 6 SERVICIO MICROPROFILE La función principal del servicio es la de administrar la base de datos. Para ello, vamos a utilizar el framework de Hibernate [41], que nos permite persistir clases simples directamente a la base de datos. En este apartado, vamos a especificar los siguientes aspectos: • Los ficheros de configuración que tenemos que modificar. • La estructura en la que se organizan las clases que tenemos que implementar. • La funcionalidad que ofrecen los distintos métodos de la API REST del servicio. 6.1 Ficheros de configuración 6.1.1 pom.xml Tenemos que añadir Java EE 8, Hibernate y PostgreSQL en la sección de dependencias del fichero “pom.xml”. Para ello, colocamos: <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>8.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-agroal</artifactId> <version>5.4.3.Final</version> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.5.4</version> </dependency> 6.1.2 resources.xml Crearemos el archivo “resources.xml” dentro de la carpeta “src/main/webapp/WEB-INF/”. Aquí vamos a definir el recurso para acceder a la base de datos, llamado “DataSource”, y que contiene el siguiente código: <?xml version="1.0" encoding="UTF-8"?> <tomee> <Resource id="jdbc/incidentesCarretera_datasource" type="javax.sql.DataSource"> JdbcDriver = org.postgresql.Driver JdbcUrl = jdbc:postgresql://localhost/incidentesCarretera UserName = postgres Password = postgres jtaManaged = true Servicio MicroProfile 54 54 </Resource> </tomee> Con este fichero, estamos indicando: • El tipo del recurso que estamos declarando: “javax.sql.DataSource”. • El id del DataSource: “jdbc/incidentesCarretera_datasource”. • La URL de la base de datos: “jdbc:postgresql://localhost/incidentesCarretera”. • El usuario y contraseña de la base de datos: “postgres”. • Las transacciones estarán gestionadas por JTA (Java Transaction API) [42], encargada de administrar las transacciones del lado del servidor, abstrayendo casi en su totalidad al programador de abrir o cerrar las transacciones. De esta forma, el programador únicamente se preocupa por la lógica de negocio. 6.1.3 persistence.xml Crearemos el archivo “persistence.xml” dentro de la carpeta “src/main/resources/META-INF”. Este es el fichero estándar de configuración de JPA (Java Persistence API) [43] y su contenido es: <?xml version="1.0" encoding="UTF-8"?> <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="incidentesCarretera_PU" transaction-type="JTA"> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <jta-data-source>jdbc/incidentesCarretera_datasource</jta-data-source> <exclude-unlisted-classes>false</exclude-unlisted-classes> <properties> <property name="tomee.jpa.factory.lazy" value="true" /> <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL10Dialect" /> <property name="hibernate.show_sql" value="false" /> <property name="hibernate.format_sql" value="true" /> <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform"/> </properties> </persistence-unit> </persistence> Este fichero define las siguientes características: • El nombre de la unidad de persistencia, “incidentesCarretera_PU”, y modo en el que se van a gestionar las transacciones, “JTA”. • El provider establecido será Hibernate. • Pasamos el id del DataSource que hemos creado en el apartado anterior, “jdbc/incidentesCarretera_datasource”. • Las propiedades sobre cómo las clases deben ser mapeadas a las tablas de la base de datos. 55 55 Servicio MicroProfile 6.2 Estructura de las clases 6.2.1 Entities Las entidades son clases POJOs (Plan Old Java Objects) que poseen anotaciones para que se puedan persistir fácilmente. Algunas de estas anotaciones son: • @Entity: Indica que es una entidad JPA. • @Table: Indica el nombre de la tabla en la base de datos. • @NamedQueries: Se utiliza para añadir consultas que realizar a la base de datos. • @NamedQuery: Define una consulta con un nombre. • @Id: Define qué atributo de la clase se corresponde con la clave primaria de la tabla. • @Size: Establece que el valor del atributo debe estar comprendido entre un mínimo y un máximo. • @Column: Se utiliza para indicar qué columna de la base de datos se corresponde con cada atributo de la clase. Como cada entidad se corresponde con una tabla de la base de datos, vamos a definir las siguientes clases: • Contacto.java • Incidente.java • Intervencion.java • Usuario.java 6.2.2 Repositories Los repositorios son las clases donde vamos a implementar la lógica de negocio. Contienen los métodos donde se producen las operaciones con la base de datos. El esquema que siguen estas clases es el mismo: • La anotación @PersistenceContext inyecta en el objeto EntityManager [44] la unidad de persistencia que hemos definido anteriormente, de esta forma: o @PersistenceContext (unitName = “incidentesCarretera_PU”) • Utilizaremos la instancia del EntityManager para realizar las distintas operaciones sobre las entidades definidas en el apartado anterior. Algunos de los métodos que nos ofrece el objeto son: o createNamedQuery(): Crea una consulta personalizada a la que podemos añadir varios parámetros. o find(): Busca una entrada concreta de la base de datos utilizando su clave primaria. o persist(): Crea una nueva entrada en la base de datos pasándole la entidad completa como parámetro. o merge(): Actualiza una entrada concreta de la base de datos pasándole la entidad completa como parámetro. o remove(): Elimina una entrada concreta de la base de datos utilizando su clave primaria. Como cada repositorio realiza las operaciones sobre una entidad concreta, tendremos un repositorio asociado a cada entidad: • ContactoRepository.java • IncidenteRepository.java • IntervencionRepository.java • UsuarioRepository.java Servicio MicroProfile 56 56 6.2.3 Resources Los recursos contienen los métodos que ofrece la API. El primer recurso que vamos a destacar es el IncidentesCarreteraAPIRestApplication.java, que contiene la raíz de la URL que se utilizarán en el resto de las peticiones, y que se indica utilizando la anotación: • @ApplicationPath(“/incidentescarreteraapi”) Las anotaciones que se utilizan en el resto de los recursos son las siguientes: • @RequestScope: Indica que la clase será creada cada vez que se realice una petición. • @Path: Indica la ruta para acceder al recurso. • @PathParam: Se utiliza para obtener los parámetros incluidos en la ruta. • @Produces(MediaType.APPLICATION_JSON): Convierte automáticamente la respuesta al formato JSON. • @Consumes(MediaType.APPLICATION_JSON): Convierte automáticamente el JSON enviado dentro de la petición en una instancia de la entidad correspondiente. • @Inject: La utilizamos para inyectar los repositorios listados en el apartado anterior. • @GET: Mapea la petición HTTP GET, dirigida a la ruta especificada con @Path, al método que contenga esta anotación. Con este tipo de peticiones obtenemos entidades de la base de datos. • @POST: Mapea la petición HTTP POST al método que contenga esta anotación. Con este tipo de peticiones creamos nuevas entidades en la base de datos. • @PUT: Mapea la petición HTTP PUT, dirigida a la ruta especificada con @Path, al método que contenga esta anotación. Con este tipo de peticiones actualizamos entidades de la base de datos. • @DELETE: Mapea la petición HTTP DELETE, dirigida a la ruta especificada con @Path, al método que contenga esta anotación. Con este tipo de peticiones eliminamos entidades de la base de datos. Estos recursos están asociados a cada entidad, por lo que definimos los siguientes: • ContactoResource.java • IncidenteResource.java • IntervencionResource.java • UsuarioResource.java 6.2.4 Filters Para conseguir el acceso desde el dispositivo móvil, tenemos que permitir la recepción de peticiones desde orígenes distintos a la dirección de localhost. Por ello, definimos el filtro CorsFilter.java, que implementa la interfaz ContainerResponseFilter [45], para que modifique las cabeceras de las respuestas. Los filtros que implementan esta interfaz se deben anotar con @Provider para que sean detectados en tiempo de ejecución. El contenido de la clase será el siguiente: @Provider public class CorsFilter implements ContainerResponseFilter { @Override public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { responseContext.getHeaders().add( "Access-Control-Allow-Origin", "*"); responseContext.getHeaders().add( 57 57 Servicio MicroProfile "Access-Control-Allow-Credentials", "true"); responseContext.getHeaders().add( "Access-Control-Allow-Headers", "origin, content-type, accept, authorization"); responseContext.getHeaders().add( "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD"); } } 6.3 Funcionalidad En este apartado, vamos a listar los distintos métodos que ofrece la API REST a la aplicación móvil. 6.3.1 Contactos Los recursos que ofrece la API REST para la gestión de los contactos, mostrados en la Ilustración 22, son los siguientes: Ilustración 22 Funcionalidad API REST Contactos • POST o /incidentescarreteraapi/contactos: Crea un nuevo contacto. ▪ Petición: El cuerpo de la petición debe ser un objeto de tipo Contacto. ▪ Respuesta correcta (200 OK): El cuerpo de la respuesta aparecerá vacío. Indica que el insert en la base de datos se ha realizado satisfactoriamente. • GET o /incidentescarreteraapi/contactos/{dniUsuario}: Recupera todos los contactos del usuario. ▪ Petición: El parámetro de entrada será el DNI del usuario que ha registrado los contactos que se quieren recuperar. ▪ Respuesta correcta (200 OK): El cuerpo de la respuesta contendrá la lista de los contactos pertenecientes al usuario. o /incidentescarreteraapi/contactos/{dniUsuario}&{dniContacto}: Recupera un contacto concreto del usuario. ▪ Petición: Los parámetros de entrada serán el DNI del usuario que ha registrado el contacto que se quiere recuperar y el DNI de dicho contacto. Aplicación móvil Ionic 64 64 “npm install”. • /resources: Cuando se compila la aplicación para diferentes plataformas (como iOS o Android), esta carpeta se generará automáticamente con los recursos de la aplicación, como el logo y la pantalla de bienvenida. • /src: Esta es la carpeta más importante y donde se desarrollará la mayor parte de la aplicación. • /www: Esta carpeta se genera automáticamente y contiene todos los archivos compilados. • angular.json: Archivo de configuración principal para Angular CLI [49]. • package.json: Necesitamos un sistema de paquetes y un administrador de paquetes para manejar todas las librerías y módulos de terceros que usa nuestra aplicación. Dentro de este archivo, se encuentran todas las dependencias y algunas utilidades más, como los scripts npm, que nos ayudarán a gestionar tareas como el empaquetado y la compilación. • tsconfig.json: Archivo de configuración principal. Debe estar en la ruta raíz, ya que es donde el compilador de TypeScript [50] lo buscará. Como hemos comentado, la carpeta /src es la más importante de la aplicación. Del contenido de esta carpeta, mostrado en la Ilustración 27, destacamos los siguientes archivos y directorios: Ilustración 27 Carpeta /src de la aplicación móvil Ionic • /app: Contiene todos los guards, interfaces, páginas y servicios que se utilizan en la aplicación. • /assets: Contiene todo tipo de recursos que utiliza la aplicación, como imágenes, fuentes, iconos, etc. • /environments: En esta carpeta se encuentran los archivos de configuración utilizados por Angular CLI para administrar las diferentes variables de entorno. Por ejemplo, podemos tener una base de datos local para nuestro entorno de desarrollo y luego tener una base de datos en producción para el entorno de producción. • /theme: Contiene todos los temas y variables que se utilizan en la aplicación. • global.scss: Contiene todas las reglas de estilo que queremos aplicar globalmente. Estos estilos son para la aplicación entera, no solo para un componente. De esta forma, agrupamos todo el estilo de la aplicación en sólo un documento, en lugar de tener un archivo de estilo por cada componente. • index.html: Este es el punto de entrada principal para la aplicación, aunque su propósito es configurar scripts, incluir archivos CSS o comenzar a ejecutar nuestra aplicación. La carpeta /app es el núcleo del proyecto, además de ser la carpeta más extensa, porque contiene todo el código de nuestra aplicación. De su contenido, mostrado en la Ilustración 28, destacamos los siguientes archivos y carpetas: 65 65 Aplicación móvil Ionic Ilustración 28 Carpeta /app de la aplicación móvil Ionic • app-routing.module.ts: Aquí se definen las rutas principales para permitir la navegación entre las páginas. Las rutas internas de otros módulos se encuentran definidas dentro de esos módulos. • app.component.html: Sirve como esqueleto de la aplicación. Por lo general, tiene un <ion-router- outlet> para representar las rutas y su contenido. También podemos añadir aquí los elementos que queremos que se muestren en cada página, como pies de página o menús laterales. • app.component.scss: Es el fichero de estilos asociado al archivo html mencionado anteriormente. • app.component.ts: Es el componente Angular que otorga la funcionalidad al archivo html mencionado anteriormente. • app.module.ts: Es el módulo principal de la aplicación. • /guards: Los guards son componentes que nos permiten limitar el acceso a ciertas rutas si no se cumplen una serie de condiciones. El ejemplo de uso más común es cuando queremos limitar el acceso a ciertas páginas si el usuario no está logeado. Además de este caso, también vamos a tener en cuenta que hay algunas páginas que, dependiendo del rol del usuario que esté logeado, se mostrarán o no. Los guards que utilizaremos en nuestra aplicación son los siguientes: o auth.guard.ts: Lo implementarán las páginas en las que el usuario necesite estar logeado para acceder, como la pantalla de inicio o la de configuración. o no-auth.guard.ts: Lo implementarán las páginas a las que sólo puedan acceder los usuarios que todavía no se hayan logeado, como la pantalla de login o la de registro. o conductor.guard.ts: Lo implementarán las páginas a las que sólo puedan acceder los usuarios con el rol de conductor, como la pantalla de ubicación o la de contactos. o operario.guard.ts: Lo implementarán las páginas a las que sólo puedan acceder los usuarios con el rol de operario, como la pantalla de ruta y la de incidentes. • /interfaces: Las interfaces son archivos que contienen la estructura de los objetos que utilizamos en toda la aplicación, como, por ejemplo, las entidades de la base de datos. Se incluyen los campos que componen el objeto y sus tipos. Las interfaces que vamos a utilizar son las siguientes: o contacto.interface.ts: Contiene la estructura de un objeto Contacto. o direccion.interface.ts: Contiene los distintos campos que componen una dirección. Esta dirección será inyectada en el campo “localización” del objeto Incidente. La interfaz tiene la siguiente forma: Aplicación móvil Ionic 66 66 export interface Direccion { numero: string; calle: string; localidad: string; ciudad: string; comunidad: string; codPostal: string; pais: string; codPais: string; latitud: number; longitud: number; } o incidente.interface.ts: Contiene la estructura de un objeto Incidente. o intervencion.interface.ts: Contiene la estructura de un objeto Intervención. o usuario.interface.ts: Contiene la estructura de un objeto Usuario. • /pages: Las páginas son las distintas pantallas que se muestran en la aplicación. En Ionic se llaman páginas, mientras que en Angular son componentes (como el componente “app” mostrado al inicio de esta lista). Sin embargo, tanto los componentes como las páginas se crean usando los mismos archivos: o [nombre de la página]-routing.module.ts: Contiene las rutas internas dentro de la página. o [nombre de la página].module.ts: Contiene el módulo de la página. o [nombre de la página].page.html: Contiene la plantilla de la página. o [nombre de la página].page.scss: Contiene el estilo de la página. o [nombre de la página].page.ts: Contiene la funcionalidad de la página. • Las páginas que vamos a utilizar en esta aplicación son: o Configuración: Permite configurar algunos aspectos de la aplicación, como la configuración del usuario, las URL de la base de datos y de la cola de mensajes, y los temas de la aplicación. o Contactos: Muestra la lista de los contactos que el usuario ha registrado. o Crear-contacto: Muestra un formulario para crear un nuevo contacto. o Editar-contacto: Muestra un formulario para editar la información de un contacto. o Editar-usuario: Muestra un formulario para editar la información del usuario. o Incidentes: Muestra la lista de los incidentes que hay que atender. o Inicio: Pantalla principal que muestra una pequeña guía de uso de la aplicación. o Login: Muestra un formulario para logearse en la aplicación. o Menú: Menú desplegable que permite acceder a la pantalla de configuración, volver a la pantalla de inicio, o cerrar la sesión actual del usuario. o Registro: Muestra un formulario para registrar un usuario en la aplicación. o Ruta: Muestra en un mapa la ruta para atender un incidente. o Tabs: Barra de herramientas inferior que permite navegar entre las distintas pantallas a través de sus iconos. Contiene pestañas para las pantallas Inicio, Ubicación y Contactos, en el caso de que el usuario tenga el rol de conductor, o Inicio, Ruta e Incidentes, en el caso de que el usuario tenga el rol de operario. 67 67 Aplicación móvil Ionic o Ubicación: Muestra en un mapa la ubicación actual y permite enviar alertas a la cola de mensajes. • /services: Los servicios son archivos que contienen la funcionalidad de un servicio concreto de la aplicación, permitiendo así aislarlos de la lógica que hay detrás de las páginas. Además, de esta forma podemos utilizarlos en varias páginas distintas sin tener que volver a escribir todo el código. Los servicios que utilizaremos en la aplicación son: o http.service.ts: Contiene todos los recursos para realizar peticiones HTTP. o location.service.ts: Contiene todos los recursos para poder obtener la ubicación del dispositivo. o sms.service.ts: Contiene todos los recursos para poder enviar mensajes SMS. 7.2 Interfaz gráfica Para mostrar la interfaz gráfica de la aplicación, vamos a recorrer cada una de las pantallas mostrando el flujo de la aplicación. Este apartado también puede servir como: • Manual de usuario, ya que vamos a explicar en profundidad cómo actuar en cada situación que se nos presente en la aplicación. • Pruebas de la funcionalidad, ya que vamos a seguir el flujo completo de la aplicación comprobando cómo se ejecutan cada uno de los pasos. Con el objetivo de facilitar el seguimiento de la aplicación, vamos a dividir este apartado en varias secciones: • Acceso a la aplicación: Muestra la pantalla de login y el registro de un nuevo usuario. Además, se mostrará el contenido común a los dos tipos de usuarios que pueden acceder a la aplicación, como el icono de la aplicación, la pantalla de bienvenida, el menú desplegable y la pantalla de configuración. • Interfaz del conductor: Muestra la funcionalidad que la aplicación le ofrece a un conductor, como enviar alertas y registrar contactos. • Interfaz del operario: Muestra la funcionalidad que la aplicación le ofrece a un operario, como atender incidentes y obtener la ruta para atenderlos. 7.2.1 Acceso a la aplicación El icono de la aplicación se muestra en la Ilustración 29. La pantalla de bienvenida, mostrada en la Ilustración 30, aparece cuando iniciamos la aplicación y está cargando la primera pantalla (la pantalla de login si no nos hemos logeado, o la pantalla de inicio si estamos ya logeados). Ilustración 29 Icono de la aplicación móvil Aplicación móvil Ionic 68 68 Ilustración 30 Pantalla de bienvenida 69 69 Aplicación móvil Ionic Si es la primera vez que accedemos a la aplicación (o si hemos cerrado la sesión anterior), nos aparecerá la pantalla de login mostrada en la Ilustración 31. En esta pantalla tendremos que ingresar nuestro DNI y nuestra contraseña para poder iniciar sesión. Ambos campos tienen que ser rellenados, como se muestra en la Ilustración 32. Estos datos tienen que cumplir un formato concreto, como indica el error mostrado en la Ilustración 33: • El DNI tiene que cumplir el formato “12345678A”, es decir, 8 números y una letra mayúscula. • La contraseña debe tener mínimo 6 caracteres. Ilustración 31 Pantalla Login Aplicación móvil Ionic 70 70 Ilustración 32 Pantalla Login: Error campos vacíos Ilustración 33 Pantalla Login: Error formato 71 71 Aplicación móvil Ionic Cuando terminemos de ingresar los datos, pulsaremos el botón “Iniciar sesión” para acceder a la aplicación. Los posibles fallos que pueden surgir en este momento son: • Hay campos sin rellenar o con un formato incorrecto, mostrado en la Ilustración 34. • No existe ningún usuario con el DNI introducido, mostrado en la Ilustración 35. • La contraseña no coincide con la del usuario, mostrado en la Ilustración 36. En el caso de que no se produzca ningún error, accederemos a la pantalla de Inicio de la aplicación. Ilustración 34 Pantalla Login: Error campos incorrectos Aplicación móvil Ionic 72 72 Ilustración 35 Pantalla Login: Error usuario no existe Ilustración 36 Pantalla Login: Error contraseña incorrecta 73 73 Aplicación móvil Ionic En el caso de que no tengamos un usuario registrado para iniciar sesión, pulsaremos el botón “Registrarse”. El primer paso es elegir qué tipo de rol va a tener el usuario que vamos a crear, mostrado en la Ilustración 37. Una vez que completemos este paso, nos aparecerá la pantalla Registro, mostrada en la Ilustración 38. Ilustración 37 Pantalla Login: Elegir rol Ilustración 38 Pantalla Registro Aplicación móvil Ionic 80 80 En las Ilustraciones 49, 50 y 51 se muestran algunas pantallas de la aplicación con el tema “dark”. Ilustración 49 Pantalla Login: Tema dark Ilustración 50 Pantalla Inicio: Tema dark Ilustración 51 Pantalla Contactos: Tema dark 81 81 Aplicación móvil Ionic En las Ilustraciones 52, 53 y 54 se muestran algunas pantallas de la aplicación con el tema “purple”. Ilustración 52 Pantalla Login: Tema purple Ilustración 53 Pantalla Inicio: Tema purple Ilustración 54 Pantalla Contactos: Tema purple Aplicación móvil Ionic 82 82 En las Ilustraciones 55, 56 y 57 se muestran algunas pantallas de la aplicación con el tema “brown”. Ilustración 55 Pantalla Login: Tema brown Ilustración 56 Pantalla Inicio: Tema brown Ilustración 57 Pantalla Contactos: Tema brown Aplicación móvil Ionic 83 83 En las Ilustraciones 58, 59 y 60 se muestran algunas pantallas de la aplicación con el tema “green”. Ilustración 58 Pantalla Login: Tema green Ilustración 59 Pantalla Inicio: Tema green Ilustración 60 Pantalla Contactos: Tema green Aplicación móvil Ionic 84 84 En las Ilustraciones 61, 62 y 63 se muestran algunas pantallas de la aplicación con el tema “red”. Ilustración 61 Pantalla Login: Tema red Ilustración 62 Pantalla Inicio: Tema red Ilustración 63 Pantalla Contactos: Tema red Aplicación móvil Ionic 85 85 7.2.2 Interfaz del conductor En este apartado, nos vamos a centrar en las pantallas propias del conductor, que son la pantalla de Contactos y la de Ubicación. Al acceder a la pantalla de Contactos, nos encontramos una lista de contactos a los que avisar en el caso de que se produzca un incidente. La primera vez que accedamos, encontraremos la lista vacía, como en la Ilustración 64. • Para añadir nuevos contactos, pulsaremos el botón “Añadir”, que desplegará el formulario de la pantalla Crear Contacto, mostrado en la Ilustración 65. • Para actualizar la lista, pulsaremos el botón “Recargar”. Ilustración 64 Pantalla Contactos: Lista vacía Ilustración 65 Pantalla Crear Contacto Aplicación móvil Ionic 86 86 En la Ilustración 66, se muestra una lista a la que se han añadido dos contactos completando el formulario de la pantalla Crear Contacto. Cada contacto contiene dos botones: • Botón “Modificar”: Abre el formulario de la pantalla Editar Contacto, mostrada en la Ilustración 67, para poder modificar los datos de un contacto. • Botón “Eliminar”: Muestra un mensaje, mostrado en la Ilustración 68, para confirmar la eliminación del contacto. Ilustración 66 Pantalla Contactos: Lista completa 87 87 Aplicación móvil Ionic Ilustración 67 Pantalla Editar Contacto Ilustración 68 Pantalla Contactos: Eliminar contacto Aplicación móvil Ionic 88 88 Al acceder a la pantalla Ubicación, nos encontraremos la interfaz mostrada en la Ilustración 69, con dos botones: • Botón “Ver mapa”: Muestra un mapa sobre el que podremos ubicarnos antes de enviar alertas, incluido en la Ilustración 70, para comprobar que la ubicación es la correcta. Para obtener la ubicación del dispositivo, pulsaremos el botón “Ubícame”. En el caso de que la ubicación captada por el dispositivo no fuera precisa, se podría desplazar el marcador arrastrándolo a la posición correcta. • Botón “Enviar alerta”: Inicia el proceso de notificar un incidente, que se detallará a continuación. Ilustración 69 Pantalla Ubicación Ilustración 70 Pantalla Ubicación: Mapa 89 89 Aplicación móvil Ionic Si es la primera vez que se accede a esta pantalla o a la pantalla Ruta, nos pedirá que demos permisos para utilizar la ubicación del dispositivo, mostrando el mensaje incluido en la Ilustración 71. Ilustración 71 Mensaje permiso ubicación Además, si es la primera vez que se envía una alerta, cuando lleguemos al paso de enviar los SMS, nos pedirá que demos permisos para enviar mensajes SMS, como se muestra en la Ilustración 72. Ilustración 72 Mensaje permiso SMS Aplicación móvil Ionic 96 96 Una vez que la ubicación sea correcta, pulsamos el botón “Ruta” para generar la ruta hacia el incidente que se esté atendiendo. Cuando lo pulsemos, pueden plantearse dos escenarios: • En el caso de que no se esté atendiendo ningún incidente, se mostrará el mensaje de error mostrado en la Ilustración 82. • En el caso de que sí estuviéramos atendiendo un incidente, se mostrará la ruta para llegar al incidente, como se indica en la Ilustración 83. Se muestra la distancia al destino, el tiempo previsto de viaje y las instrucciones paso a paso sobre el itinerario a seguir. Ilustración 82 Pantalla Ruta: Error incidente no seleccionado Ilustración 83 Pantalla Ruta: Ruta encontrada 97 8 GRAFANA Para terminar de explicar la arquitectura del proyecto, en este apartado nos vamos a centrar en el último componente, el dashboard de Grafana. Nos va a permitir monitorizar de una forma visual los cambios que estén sucediendo en la base de datos. Vamos a profundizar en cada uno de los paneles del dashboard, destacando la configuración más relevante y aportando capturas que reflejan los cambios que se han producido a raíz de las pruebas del apartado anterior. De esta forma, podemos comprobar que todos los componentes del proyecto funcionan en su conjunto. Para acceder a Grafana, abriremos el navegador Google Chrome y nos dirigiremos a la dirección localhost y puerto 3000, que es la dirección por defecto. 8.1 Dashboard Incidentes en Carretera Hemos creado un dashboard, llamado “Incidentes en Carretera”, que se muestra en la Ilustración 84. Está compuesto por varios paneles: • Mapa Incidentes: Contiene un mapa que muestra los incidentes que se están produciendo en tiempo real. • Tabla Intervenciones: Muestra el contenido de la tabla Intervenciones de la base de datos. • Tabla Incidentes: Muestra el contenido de la tabla Incidentes de la base de datos. El contenido de cada uno de los paneles se refrescará cada 5 segundos, como podemos observar en la esquina superior derecha. Ilustración 84 Dashboard Grafana Grafana 98 98 Para poder acceder a la base de datos, hemos tenido que configurar previamente la fuente de datos. En el apartado de Configuración, mostrado en la Ilustración 85, nos dirigimos a la pestaña de “Data sources”. Ilustración 85 Configuración Grafana Dentro de esta pestaña, podemos observar que ya tenemos creada la fuente de datos que estamos utilizando en el dashboard, con la configuración mostrada en la Ilustración 86. Para añadir una nueva fuente de datos, o si no existiera ninguna, pulsaríamos el botón “Add data source” y rellenaríamos los campos correspondientes. Ilustración 86 Configuración Data Source Grafana 99 99 8.1.1 Panel Mapa Incidentes En este panel, observamos los distintos incidentes que están teniendo lugar. En la Ilustración 87, se ha seleccionado el incidente notificado en el apartado de la aplicación móvil. De cada incidente, se muestran las siguientes propiedades: • Fecha: Es la fecha de la última alerta recibida en la cola de mensajes. • Latitud: Es la latitud de la última posición recibida en la cola de mensajes. • Longitud: Es la longitud de la última posición recibida en la cola de mensajes. • Métrica: Es la métrica utilizada para asignarle el color al punto mostrado en el mapa. En este caso, se mapea al campo “peligro” del incidente, por lo que el incidente se mostrará con un color dependiendo del nivel de peligrosidad que tenga. Estos colores se muestran en la leyenda situada en la parte inferior izquierda: o Si es un incidente que no está siendo atendido aún: ▪ Leve: Verde. ▪ Moderado: Amarillo. ▪ Grave: Rojo. o Si es un incidente que ya se está atendiendo, aparecerá en color azul. • Nombre: Nombre del conductor que ha sufrido el incidente. Ilustración 87 Panel Mapa Incidentes Como hemos podido observar, hay dos conjuntos de datos que se están representando en el mapa, por lo que es necesario realizar dos consultas distintas a la base de datos: • La primera consulta, denominada “A”, obtiene los incidentes sin atender de la base de datos. La consulta aparece en la Ilustración 88, en la que se han realizado los siguientes filtros: Grafana 100 100 Ilustración 88 Consulta Incidentes sin atender o Primero, obtenemos todos los DNI distintos que aparecen en la tabla Incidentes. Para cada DNI, se realizan las siguientes operaciones: ▪ Obtener la fecha más reciente de los incidentes enviados por el conductor con ese DNI, para que la posición sea la más actualizada. ▪ Comprobar que el conductor con ese DNI sigue apareciendo en la tabla Usuarios (es decir, que no ha sido eliminado). ▪ Comprobar que no aparece en la tabla Intervenciones. Esto significa que el usuario no ha sido atendido anteriormente, por lo que podemos representarlo. ▪ Si aparece en la tabla Intervenciones, comprobar que el estado es “atendido” (es decir, que el incidente que tuvo anteriormente ya está atendido) y que la fecha más reciente del incidente es posterior a la fecha de actualización de la intervención (con esto, nos aseguramos de que el incidente es uno nuevo y no el que ya quedó atendido). • La segunda consulta, denominada “B”, obtiene los incidentes que están siendo atendidos de la base de datos. La consulta aparece en la Ilustración 89, en la que se han realizado los siguientes filtros: Ilustración 89 Consulta Incidentes siendo atendidos o Obtener la fecha más reciente de los incidentes enviados por el conductor, para que la posición sea la más actualizada. o Comprobar que el conductor sigue apareciendo en la tabla Usuarios (es decir, que no ha sido eliminado). o Comprobar que aparece en la tabla Intervenciones y que su estado es “en proceso”. 101 101 Grafana Siguiendo con las pruebas realizadas en el apartado de la aplicación móvil, una vez que se empieza a atender el incidente, se muestra en el mapa como un incidente siendo atendido. Podemos observar, en la Ilustración 90, que su color cambia de amarillo a azul. Ilustración 90 Panel Mapa Incidentes: Atendiendo incidente Por último, cuando el incidente ya ha sido atendido, desaparece del mapa, como podemos observar en la Ilustración 91. Ilustración 91 Panel Mapa Incidentes: Incidente atendido Grafana 102 102 8.1.2 Panel Tabla Intervenciones En este panel, se muestra el contenido de la tabla Intervenciones, ordenado por la fecha de la última actualización de más reciente a más antigua. En la Ilustración 92, podemos observar el contenido cuando el incidente todavía no ha sido atendido. Ilustración 92 Panel Tabla Intervenciones Cuando el incidente empieza a ser atendido, podemos ver en la Ilustración 93 como ya aparece en la tabla el conductor con el DNI “24624624A” y con el estado “en proceso”. Ilustración 93 Panel Tabla Intervenciones: Atendiendo incidente 103 103 Grafana Por último, cuando el incidente ya ha sido atendido, cambia su estado a “atendido”, como podemos observar en la Ilustración 94. Ilustración 94 Panel Tabla Intervenciones: Incidente atendido 8.1.3 Panel Tabla Incidentes En este panel, se muestra el contenido de la tabla Incidentes, ordenado por la fecha del envío del incidente de más reciente a más antigua. En la Ilustración 95, podemos observar el contenido del panel cuando el conductor del apartado de la aplicación móvil, con DNI “24624624A”, ya ha enviado sus alertas. Ilustración 95 Panel Tabla Incidentes Grafana 104 104 105 9 LÍNEAS DE MEJORA Y CONCLUSIONES 9.1 Líneas de mejora En este apartado, se van a listar un conjunto de propuestas que se podrían aplicar con el fin de mejorar la calidad del proyecto: • Respecto a la arquitectura general del proyecto, se podría hacer que todos los componentes se encontraran en la nube, permitiendo que se pudiera acceder desde cualquier parte, en lugar de depender de estar en la misma red Wifi. o Como base de datos, se podría utilizar Firebase [51] y su base de datos Cloud Firestore [52], una base de datos flexible y escalable que mantiene los datos sincronizados a través de objetos de escucha en tiempo real y ofrece soporte sin conexión para dispositivos móviles y la Web. Además, es compatible con Grafana mediante el uso del plugin Firestore [53]. o Como cola de mensajes, se podría utilizar Confluent Cloud [54], permitiendo conectar y procesar todos los datos en tiempo real. Ofrece una plataforma de streaming de datos completamente gestionada y disponible desde cualquier lugar. • Para aumentar la funcionalidad de la aplicación móvil, se podrían incluir las siguientes mejoras: o En la pantalla de Login, se podría incluir una forma de obtener una nueva contraseña para el usuario en el caso de que la olvidara. Necesitaríamos generar una nueva contraseña y enviarla al usuario, por ejemplo, mediante correo electrónico. Este es un campo del usuario que ya estamos recogiendo, pero finalmente no le estamos dando uso, con lo que podría ser una buena idea. Para enviar los correos electrónicos desde la aplicación móvil Ionic, podríamos hacer uso del plugin Email Composer [55], que nos proporciona la habilidad de crear y enviar emails desde la aplicación. o Siguiendo con el tema de los correos electrónicos, como también estamos guardando este campo de los contactos, podríamos avisarlos por este método. De este modo, además de un SMS, se enviaría un correo electrónico para avisar del incidente notificado por el conductor. o Para aportar más relevancia al mapa que se encuentra en las pantallas de Ubicación y Ruta, podríamos añadir a la base de datos algunos puntos de interés en una región concreta, por ejemplo, en Andalucía, para que se mostraran en él. Algunos de estos lugares podrían ser hospitales, centros de salud, talleres, servicios de grúa, etc. En el caso de seleccionar alguno, se mostraría la ruta para llegar al mismo, tal y como aparece en la pantalla Ruta. o Si se utilizara una base de datos en la nube y en tiempo real, como la mencionada en la primera propuesta, podríamos conseguir que los conductores y los operarios estuvieran conectados. Modificando la tabla Intervenciones, incluyendo campos para guardar la posición del operario, podríamos conseguir que el conductor viera en todo momento en qué lugar se encuentra el operario que le va a atender y cuánto tiempo queda para que llegue a su posición. Además, si los conductores también tuvieran acceso a la tabla Incidentes, podrían observar los diferentes incidentes que se produzcan cerca de él, pudiendo prevenir un posible accidente por colisión. Al fin y al cabo, el hecho de evitar muertes y lesiones, como hemos señalado en el resumen de este documento, es el objetivo principal que persiguen los Servicios de Transporte Inteligentes. Anexo: Instalación del entorno 112 112 o Añadimos la variable de entorno JAVA_HOME con la ruta donde instalamos el Java 11 y pulsamos “Aceptar” (Ilustración 107). Ilustración 107 Instalar Java 11: Paso 12 o Ahora, en el apartado “Variables del sistema”, seleccionamos la variable “Path” y pulsamos el botón “Editar” (Ilustración 108). Ilustración 108 Instalar Java 11: Paso 13 o Vamos a pulsar “Nuevo”, añadimos “%JAVA_HOME%\bin” (Ilustración 109) y pulsamos “Aceptar”. 113 113 Anexo: Instalación del entorno Ilustración 109 Instalar Java 11: Paso 14 o Por último, comprobamos que se ha instalado correctamente ejecutando el comando “java - version” (Ilustración 110). Ilustración 110 Instalar Java 11: Paso 15 • Maven o Nos dirigimos a la página https://maven.apache.org/download.cgi#Installation (Ilustración 111) y pulsamos en el enlace “Binary zip archive”. Ilustración 111 Instalar Maven: Paso 1 Anexo: Instalación del entorno 114 114 o Se comenzará a descargar el archivo (Ilustración 112). Ilustración 112 Instalar Maven: Paso 2 o Descomprimimos el archivo donde queramos. En mi caso, lo he descomprimido en la carpeta “C:\Maven” (Ilustración 113). Ilustración 113 Instalar Maven: Paso 3 o Como ya hicimos en el proceso de instalación de Java 11, vamos a escribir en Inicio “variables de entorno”. Seleccionaremos “Editar las variables de entorno del sistema” y nos llevará a la pantalla mostrada en la Ilustración 105. Aquí, pulsamos en la opción “Variables de entorno”. o En el apartado “Variables del sistema”, pulsamos el botón “Nueva” (Ilustración 106). o Añadimos la variable de entorno MAVEN_HOME con la ruta donde descomprimimos el archivo de Maven y pulsamos “Aceptar” (Ilustración 114). Ilustración 114 Instalar Maven: Paso 4 o Ahora, en el apartado “Variables del sistema”, seleccionamos la variable “Path” y pulsamos el botón “Editar” (Ilustración 108). 115 115 Anexo: Instalación del entorno o Vamos a pulsar “Nuevo”, añadimos “%MAVEN_HOME%\bin” (Ilustración 115) y pulsamos “Aceptar”. Ilustración 115 Instalar Maven: Paso 5 o Por último, comprobamos que se ha instalado correctamente ejecutando el comando “mvn - v” (Ilustración 116). Ilustración 116 Instalar Maven: Paso 6 • Visual Studio Code o Nos vamos a la página https://code.visualstudio.com/download (Ilustración 117) y pulsamos en “Windows”. Ilustración 117 Instalar Visual Studio Code: Paso 1 Anexo: Instalación del entorno 116 116 o Comenzará a descargarse el instalador (Ilustración 118). Ilustración 118 Instalar Visual Studio Code: Paso 2 o Cuando ejecutemos el instalador, nos aparecerá una pantalla de acuerdo de licencia (Ilustración 119). Aceptaremos el acuerdo y pulsaremos en “Siguiente”. Ilustración 119 Instalar Visual Studio Code: Paso 3 o Dejaremos que se instale en la ruta por defecto y pulsamos en “Siguiente” (Ilustración 120). Ilustración 120 Instalar Visual Studio Code: Paso 4 117 117 Anexo: Instalación del entorno o Pulsaremos en “Siguiente” para crear los accesos directos al programa (Ilustración 121). Ilustración 121 Instalar Visual Studio Code: Paso 5 o Seleccionamos todas las tareas adicionales y pulsamos en siguiente (Ilustración 122). Ilustración 122 Instalar Visual Studio Code: Paso 6 o Pulsamos en “Instalar” (Ilustración 123). Ilustración 123 Instalar Visual Studio Code: Paso 7 Anexo: Instalación del entorno 118 118 o Comenzará a instalarse (Ilustración 124). Ilustración 124 Instalar Visual Studio Code: Paso 8 o Cuando termine de instalarse, pulsamos en “Finalizar” (Ilustración 125). Ilustración 125 Instalar Visual Studio Code: Paso 9 119 119 Anexo: Instalación del entorno • NodeJS o Nos dirigimos a la página https://nodejs.org/en (Ilustración 126) y pulsamos en la versión “LTS”. Ilustración 126 Instalar NodeJS: Paso 1 o Comenzará a descargarse el instalador (Ilustración 127). Ilustración 127 Instalar NodeJS: Paso 2 o Ejecutamos el instalador y pulsamos “Next” (Ilustración 128). Ilustración 128 Instalar NodeJS: Paso 3 Anexo: Instalación del entorno 120 120 o Aceptamos los términos y condiciones y pulsamos “Next” (Ilustración 129). Ilustración 129 Instalar NodeJS: Paso 4 o Dejamos que se instale en la ruta por defecto y pulsamos “Next” (Ilustración 130). Ilustración 130 Instalar NodeJS: Paso 5 o Dejamos las características que vienen por defecto y pulsamos “Next” (Ilustración 131). Ilustración 131 Instalar NodeJS: Paso 6 121 121 Anexo: Instalación del entorno o Dejamos la casilla sin marcar y pulsamos “Next” (Ilustración 132). Ilustración 132 Instalar NodeJS: Paso 7 o Pulsamos el botón “Install” (Ilustración 133). Ilustración 133 Instalar NodeJS: Paso 8 o Comenzará la instalación (Ilustración 134). Ilustración 134 Instalar NodeJS: Paso 9 Anexo: Instalación del entorno 128 128 o Cuando ejecutemos el instalador, pulsamos en “Siguiente” (Ilustración 151). Ilustración 151 Instalar PostgreSQL: Paso 5 o Dejamos que se instale en la ruta por defecto y pulsamos en “Siguiente” (Ilustración 152). Ilustración 152 Instalar PostgreSQL: Paso 6 o Marcamos todos los componentes, menos “Stack Builder” (Ilustración 153). Ilustración 153 Instalar PostgreSQL: Paso 7 129 129 Anexo: Instalación del entorno o Dejamos que se guarden los datos en la ruta por defecto y pulsamos en “Siguiente” (Ilustración 154). Ilustración 154 Instalar PostgreSQL: Paso 8 o Establecemos la contraseña para el usuario postgres (en nuestro caso, la contraseña también será “postgres”) y pulsamos en “Siguiente” (Ilustración 155). Ilustración 155 Instalar PostgreSQL: Paso 9 o Dejamos el puerto por defecto y pulsamos “Siguiente” (Ilustración 156). Ilustración 156 Instalar PostgreSQL: Paso 10 Anexo: Instalación del entorno 130 130 o Dejamos la configuración regional por defecto y pulsamos “Siguiente” (Ilustración 157). Ilustración 157 Instalar PostgreSQL: Paso 11 o Pulsamos en “Siguiente” (Ilustración 158). Ilustración 158 Instalar PostgreSQL: Paso 12 o Para comenzar la instalación, pulsamos “Siguiente” (Ilustración 159). Ilustración 159 Instalar PostgreSQL: Paso 13 131 131 Anexo: Instalación del entorno o La instalación comenzará (Ilustración 160). Ilustración 160 Instalar PostgreSQL: Paso 14 o Cuando termine la instalación, pulsamos “Terminar” (Ilustración 161). Ilustración 161 Instalar PostgreSQL: Paso 15 o Ejecutaremos pgAdmin 4 y colocaremos la contraseña del usuario postgres (Ilustración 162). Ilustración 162 Instalar PostgreSQL: Paso 16 Anexo: Instalación del entorno 132 132 o Para acceder a las bases de datos de “PostgreSQL 15”, volvemos a ingresar la contraseña del usuario postgres (Ilustración 163). Ilustración 163 Instalar PostgreSQL: Paso 17 o Una vez dentro, nos vamos a Databases -> Create -> Database (Ilustración 164). Ilustración 164 Instalar PostgreSQL: Paso 18 o Creamos la base de datos “incidentesCarretera” (Ilustración 165). Ilustración 165 Instalar PostgreSQL: Paso 19 133 133 Anexo: Instalación del entorno o Nos dirigimos a la base de datos creada y pulsamos “Restore” (Ilustración 166). Ilustración 166 Instalar PostgreSQL: Paso 20 o En “Filename”, seleccionamos el archivo “database-backup.sql”, que se encuentra en la carpeta API del repositorio clonado anteriormente, y pulsamos “Restore” (Ilustración 167). Ilustración 167 Instalar PostgreSQL: Paso 21 • Confluent o Descargamos el archivo ejecutando el comando “curl -O https://packages.confluent.io/archive/7.4/confluent-7.4.0.zip” (Ilustración 168). Ilustración 168 Instalar Confluent: Paso 1 Anexo: Instalación del entorno 134 134 o Extraemos el contenido del archivo en la carpeta que queramos, en este caso, se ha hecho en la ruta “C:\Confluent” (Ilustración 169). Ilustración 169 Instalar Confluent: Paso 2 • Kafka o Nos dirigimos a la página https://kafka.apache.org/downloads y descargamos la última versión del tipo “Scala 2.13” (Ilustración 170). Ilustración 170 Instalar Kafka: Paso 1 o El archivo comenzará a descargarse (Ilustración 171). Ilustración 171 Instalar Kafka: Paso 2 o Extraemos el contenido del archivo en la carpeta que queramos, en este caso, se ha hecho en la ruta “C:\Kafka” (Ilustración 172). Ilustración 172 Instalar Kafka: Paso 3 135 135 Anexo: Instalación del entorno • Grafana o Nos dirigimos a la página https://grafana.com/grafana/download y seleccionamos la última versión disponible, la edición “OSS” y el sistema operativo “Windows” (Ilustración 173). Ilustración 173 Instalar Grafana: Paso 1 o Cuando pulsemos “Download the installer” debajo del apartado “Windows Installer” comenzará la descarga del instalador (Ilustración 174). Ilustración 174 Instalar Grafana: Paso 2 o Ejecutamos el instalador y pulsamos en “Next” (Ilustración 175). Ilustración 175 Instalar Grafana: Paso 3 Anexo: Instalación del entorno 136 136 o Aceptamos los términos de licencia y pulsamos en “Next” (Ilustración 176). Ilustración 176 Instalar Grafana: Paso 4 o Dejamos que se instale en la ruta por defecto y pulsamos en “Next” (Ilustración 177). Ilustración 177 Instalar Grafana: Paso 5 o Pulsamos en “Install” (Ilustración 178). Ilustración 178 Instalar Grafana: Paso 6 137 137 Anexo: Instalación del entorno o Comenzará la instalación (Ilustración 179). Ilustración 179 Instalar Grafana: Paso 7 o Cuando termine la instalación, pulsamos en “Finish” (Ilustración 180). Ilustración 180 Instalar Grafana: Paso 8 o Si accedemos en un navegador a la dirección “localhost” en el puerto 3000, se nos mostrará la pantalla de login (Ilustración 181). Por defecto, existe un usuario “admin” con contraseña “admin”.