Full text
Equation Chapter 1 Section 1 Trabajo de Fin de Grado Grado en Ingeniería de las Tecnologías de Telecomunicación Aplicación Android y Servicio Web para la recolección en tiempo real de infracciones de velocidad, con representación en mapa mediante ELK y Kafka Departamento de Ingeniería Telemática Escuela Técnica Superior de Ingeniería Universidad de Sevilla Autor: David Madroñal Sánchez Tutor: María Teresa Ariza Gómez Sevilla, 2023 Trabajo de Fin de Grado Grado en Ingeniería de las Tecnologías de Telecomunicación
iii Trabajo de Fin de Grado Grado en Ingeniería de las Tecnologías de Telecomunicación Aplicación Android y Servicio Web para la recolección en tiempo real de infracciones de velocidad, con representación en mapa mediante ELK y Kafka Autor: David Madroñal Sánchez Tutor: María Teresa Ariza Gómez Profesor titular Departamento 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 Android y Servicio Web para la recolección en tiempo real de infracciones de velocidad, con representación en mapa mediante ELK y Kafka Autor: David Madroñal Sánchez 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 amigos A mis maestros
ix Agradecimientos En primer lugar, agradecer a mi tutora, María Teresa Ariza Gómez, por brindarme la oportunidad de trabajar con ella, por su ayuda, consejos y tiempo. En segundo lugar, agradecer a mis padres por confiar en mí y por todo el sacrificio que han hecho durante este tiempo. Agradecer a mis hermanos por aguantarme y apoyarme. Agradecer a Carmen, por su infinita paciencia, ayuda y motivación. Además de ser el mayor apoyo de mi día a día. Y por último, agradecer a los compañeros que me han acompañado durante esta etapa. Sobre todo, gracias a Fernando, Ferchu, Ocaña y Chazo por todas las risas y por todos los buenos momentos, sin vuestra amistad todo hubiera sido más duro. David Madroñal Sánchez Sevilla, 2023
ÍNDICE DE TABLAS Tabla 1: Consultas de datos mediante GET – servicio web Firebase. 20 Tabla 2: Almacenamientos de datos mediante POST – servicio web Firebase. 20 Tabla 3: Almacenamiento de datos mediante POST – servicio web Kafka. 23
xvii ÍNDICE DE ILUSTRACIONES Ilustración 1: Arquitectura del sistema. 3 Ilustración 2: Arquitectura del inicio de sesión. 3 Ilustración 3: Arquitectura del registro de datos. 4 Ilustración 4: Procesador AMD Ryzen 5 3600. 5 Ilustración 5: Logo Android Studio. 6 Ilustración 6: Logo Google Chrome. 6 Ilustración 7: Configuración Máquina Virtual. 6 Ilustración 8: Logo Eclipse. 7 Ilustración 9: Logo Firebase. 8 Ilustración 10: Logo Docker-Compose. 9 Ilustración 11: Logo Kafka. 9 Ilustración 12: Logo ELK. 10 Ilustración 13: Detectar infracción – diagrama de secuencia. 11 Ilustración 14: Inicio sesión – diagrama de secuencia. 12 Ilustración 15: Mostrar matrícula – diagrama de secuencia. 12 Ilustración 16: Modificar matrícula – diagrama de secuencia. 12 Ilustración 17: Mostrar historial de infracciones – diagrama de secuencia. 13 Ilustración 18: Paquetes y clases del servicio web Firebase. 13 Ilustración 19: ApirestFirebaseApplication. 14 Ilustración 20: FirebaseConfig. 14 Ilustración 21: InfraccionData – Firebase. 15 Ilustración 22: SecurityConfig. 15 Ilustración 23: TokenModel. 16 Ilustración 24: UserModel. 16 Ilustración 25: FirebaseEntryPoint. 17 Ilustración 26: FirebaseFilter. 17 Ilustración 27: FirebaseProvider. 18 Ilustración 28: getMatriculaByUserId. 19
Ilustración 29: getInfraccionesByUserId. 19 Ilustración 30: setMatriculaByUserId. 20 Ilustración 31: setInfraccionByUserId. 20 Ilustración 32: Paquetes y clases del servicio web Kafka. 21 Ilustración 33: KafkaproducerApplication. 21 Ilustración 34: InfraccionData – Kafka. 22 Ilustración 35: Producer. 22 Ilustración 36: KafkaController. 23 Ilustración 37: Fichero .yaml de Kafka. 24 Ilustración 38: Detalles cluster Kafka. 26 Ilustración 39: Dependencias pom.xml Kafka. 26 Ilustración 40: Application.properties servicio web Kafka. 27 Ilustración 41: Diagrama de casos de uso – aplicación Android. 28 Ilustración 42: Paquetes y clases – aplicación Android. 29 Ilustración 43: Pantalla inicial – App Android. 35 Ilustración 44: Pantalla inicio sesión Google – App Android. 36 Ilustración 45: Pantalla principal – App Android. 37 Ilustración 46: Pantalla historial de infracciones – App Android. 38 Ilustración 47: Pantalla detectar infracción – App Android. 39 Ilustración 48: Filtrado de datos - Kibana. 40 Ilustración 49: Filtrado por tiempo – Kibana 40 Ilustración 50: Otro filtrado por tiempo – Kibana. 41 Ilustración 51: Pantalla discover – Kibana. 41 Ilustración 52: Pantalla discover información expandida – Kibana. 42 Ilustración 53: Pantalla maps con poco zoom – Kibana. 42 Ilustración 54: Pantalla maps con más zoom – Kibana. 43 Ilustración 55: Mapping del index de Kibana. 44 Ilustración 56: Creación de Maps Kibana. 45 Ilustración 57: Repositorios y dependencias build.gradle(Project) 47 Ilustración 58: Plugins y dependencias buil.gradle(App) 48 Ilustración 59: Agregar Firebase a aplicación Android 48 Ilustración 60: Mas dependencias build.gradle(App) 48 Ilustración 61: Dependencia pom.xml Firebase 49 Ilustración 62: Path de la configuración de Firebase 49 Ilustración 63: Fichero .yaml de ElasticSearch y Kibana. 50 Ilustración 64: Fichero configuración Logstash. 52
xix
1 1 INTRODUCCIÓN 1.1 Motivación ste Proyecto se ha realizado con la finalidad de diseñar un sistema que ayude a la seguridad en carretera en tiempo real. Dicho sistema ayudará a detectar las infracciones de velocidad, gracias a la aplicación Android y al GPS del smartphone, y representar geográficamente los puntos donde se ha cometido dicha infracción, gracias a la integración de tecnologías que se comentará más adelante. La representación geográfica facilita la identificación de las áreas de mayor incidencia y contribuye a la planificación de estrategias de seguridad vial más efectivas. Una de las tecnologías a destacar es Apache Kafka, una plataforma distribuida para la transmisión de datos que permite publicar, almacenar y procesar flujos de eventos de forma inmediata y también suscribirse a ellos. Está diseñada para administrar los flujos de datos de varias fuentes, en este caso todos los usuarios que usen la aplicación Android, y enviarlos a distintas fuentes, en este caso la tecnología ELK, otra de las tecnologías a destacar. La tecnología ELK, formada por ElasticSearch, Logstash y Kibana, es un conjunto de herramientas de código abierto utilizadas para la recopilación, indexación, búsqueda y visualización de datos en tiempo real. 1.2 Objetivos Los objetivos de este proyecto son los siguientes: • Desarrollar una aplicación Android capaz de detectar y registrar infracciones de velocidad en tiempo real, con una interfaz sencilla para todos los usuarios. • Implementar un inicio de sesión con seguridad de token, lo cual implica diseñar y desarrollar un mecanismo de autenticación que utilice tokens seguros para contribuir a la seguridad y protección de los datos de los usuarios, así como a la prevención de accesos no autorizados a la aplicación. • Integrar dos tecnologías clave para el procesamiento y visualización de los datos de infracciones en tiempo real: Kafka y ELK. o Kafka como tecnología de envío de datos en tiempo real. E La tecnología es sólo una herramienta. En términos de motivar a los niños y lograr que trabajen juntos, el profesor es el recurso más importante. - Bill Gates -
Introducción 2 o ELK que permite obtener y procesar los datos de Kafka y visualizarlos en un mapa, para una representación geográfica de las ubicaciones en las que se cometieron infracciones. 1.3 Antecedentes El proyecto realizado en 2019 por Pablo Bermejo Pérez [2] y el realizado en 2020 por Sergio Mellado Contioso [3] para sus Trabajos de Fin de Grado han servido como inspiración e idea base para este proyecto. El proyecto de Pablo Bermejo Pérez hacía uso de un dispositivo IoT dotado de un sensor GPS y de un acelerómetro con giroscopio, el cual funcionaba de forma autónoma y se incorporaba a un vehículo midiendo los parámetros de posición, velocidad, aceleración y dirección. También consultaba a un servicio web, creado por él, la velocidad máxima. Para ello tenía una base de datos en la que había importado datos de la DGT sobre velocidades máximas asociadas a tipos de vehículos. Al obtener la velocidad máxima comprobaba si el vehículo excedía dicha velocidad y en caso afirmativo avisaba al conductor con señales luminosas y acústicas. Además, se centraba en el desarrollo de una aplicación web, con la que el usuario podía suscribirse, mediante un número de matrícula, a la información que el context broker recopilara sobre su vehículo, así como consultar los datos recogidos y almacenados, tras la suscripción, en una base de datos. Por otro lado, el proyecto de Sergio Mellado Contioso diseñaba una aplicación Android para la monitorización de la velocidad, posición, aceleración y la velocidad de rotación de los vehículos, obtenidos por los sensores del móvil. También, enviaba los datos recogidos por los sensores a un context broker y desarrollaba un servicio web para suscribirse al context broker, obtener la información y almacenarla en una base de datos. En este proyecto se hace uso de un dispositivo móvil, basándose en la idea de Sergio Mellado Contioso, pero en este caso solo del sensor GPS. Además, se desarrolla una aplicación Android encargada de detectar infracciones de velocidad, basándose en la idea de Pablo Bermejo Pérez. En este caso, la aplicación Android consulta el servicio web “overpass-api”, el cual devuelve la velocidad máxima en tiempo real de la vía por la que se circula y en caso de cometerse una infracción se registra, tanto en una base de datos de tiempo real de Firebase, como en la tecnología ELK, la cual nos permite la representación geográfica de los puntos en los que se comete dicha infracción. 1.4 Descripción de la solución A continuación, se presenta la solución desarrollada para poder alcanzar los objetivos establecidos en la memoria. 1.4.1 Funcionalidades El proyecto presenta las siguientes funcionalidades: - Autenticación y verificación de usuario mediante la aplicación Android, Firebase y API REST. - Interfaz de usuario sencilla para el uso de cualquier usuario. - Permitir guardar y modificar la matrícula vinculada a un determinado usuario. - Permitir consultar las infracciones vinculadas a un determinado usuario. - Detección en tiempo real de las infracciones. - Procesamiento, almacenamiento y visualización de las infracciones en un mapa a tiempo real. - Múltiples opciones de filtrados de datos en la representación geográfica.
3 3 Aplicación Android y Servicio Web para la recolección en tiempo real de infracciones de velocidad, con representación en mapa mediante ELK y Kafka 1.4.2 Arquitectura del Sistema La arquitectura del sistema, la cual se muestra en la ilustración 1, detalla el sistema desarrollado. Ilustración 1: Arquitectura del sistema. A continuación, se muestra la división de la arquitectura por bloques, ilustración 2 e ilustración 3, detallando los protocolos y puertos estándares usados para las conexiones entre las tecnologías. Ilustración 2: Arquitectura del inicio de sesión. • Bloque I (ilustración 2): El primer bloque muestra la arquitectura del inicio de sesión, mediante autenticación con token, de la aplicación Android, detallando las conexiones necesarias para el inicio de sesión y la obtención de datos de la realtime database (base de datos en tiempo real) de Firebase.
Introducción 4 Ilustración 3: Arquitectura del registro de datos. • Bloque II (ilustración 3): El segundo bloque muestra la arquitectura del registro de datos, mostrando las conexiones que se realizan desde que se detecta una infracción, desde la aplicación Android, hasta que llega a Kibana para su representación. 1.5 Estructura de la memoria Para facilitar la lectura de esta memoria, en este apartado se resumen el contenido de cada capítulo: 1 Introducción: Presentación del problema en su contexto y solución adoptada. 2 Recursos utilizados: Recursos software y hardware empleados para la creación de la aplicación Android, los servicios web y las tecnologías utilizadas. 3 Tecnologías utilizadas: Resumen de las principales tecnologías empleadas para desarrollar el Proyecto. 4 Aplicación desarrollada: Servicios Web: Estructura de los dos servicios web desarrollados. Uno de ellos para el inicio de sesión y obtención de datos del usuario y el otro para el envío de los datos a Kafka. 5 Aplicación desarrollada: Aplicación Android: Estructura y análisis de la aplicación Android. 6 Interfaz de aplicación Android: Descripción de las funcionalidades que ofrece la aplicación Android de cara al usuario. 7 Interfaz de Kibana: Descripción de las funcionalidades que ofrece Kibana para la representación de las infracciones 8 Conclusión y líneas futuras: Ideas que podrían mejorar el proyecto en próximas versiones del mismo.
5 2 RECURSOS UTILIZADOS ste capítulo se centra en comentar los recursos, tanto hardware como software, que se han utilizado para el desarrollo de este proyecto. 2.1 Recursos Hardware 2.1.1 Ordenador de escritorio AMD Ryzen 5 3600 El recurso hardware que se ha utilizado para este proyecto es un ordenador de escritorio, utilizado para alojar Android Studio y la máquina virtual de Ubuntu, en la cual se lanzan los servicios web, Kafka y ELK. Las características del ordenador son las siguientes: Ilustración 4: Procesador AMD Ryzen 5 3600. • Procesador: AMD Ryzen 5 3600, 6 núcleos 3.6Hz. • Memoria RAM: 16,0 GB. • Tarjeta gráfica: NVIDIA GeForce RTX 2060. • Almacenamiento: 1TB HDD + 500GB SDD. • Sistema Operativo: Windows 10 Pro. 2.2 Recursos Software 2.3.1 Android Studio La aplicación móvil ha sido desarrollada mediante el entorno de desarrollo integrado Android Studio, ya que es la herramienta oficial de desarrollo de Android. Además, se hace uso del emulador de Android, que éste integra, para probar la aplicación y poder realizar pruebas emulando rutas con el mapa que incorpora. E
Aplicación desarrollada: Servicios Web 12 12 Ilustración 14: Inicio sesión – diagrama de secuencia. • En el segundo diagrama se puede observar cómo se obtiene y se muestra la matrícula al usuario una vez que el usuario ha iniciado sesión y se encuentra en la pantalla principal, ilustración 15. Ilustración 15: Mostrar matrícula – diagrama de secuencia. • En el tercer diagrama se muestra cómo se guarda/modifica la matrícula del usuario desde la pantalla principal, ilustración 16. Ilustración 16: Modificar matrícula – diagrama de secuencia.
13 13 Aplicación Android y Servicio Web para la recolección en tiempo real de infracciones de velocidad, con representación en mapa mediante ELK y Kafka • En el cuarto diagrama se observa como se muestra el historial de infracciones una vez se presiona el botón de la pantalla principal, ilustración 17. Ilustración 17: Mostrar historial de infracciones – diagrama de secuencia. 4.1.1 Estructura y funcionalidad En este apartado se detalla la estructura y la funcionalidad del servicio web Firebase. El proyecto está formado por los paquetes y las clases que se muestran en la ilustración 18. Ilustración 18: Paquetes y clases del servicio web Firebase. • ApirestFirebaseApplication (ilustración 19) Es la clase principal de la aplicación. La anotación “@SpringBootApplication” indica que es una clase de aplicación Spring Boot y configura automáticamente la aplicación. El método “main” llama al método “run” de “SpringApplication” para iniciar la aplicación.
Aplicación desarrollada: Servicios Web 14 14 Ilustración 19: ApirestFirebaseApplication. • FirebaseConfig (ilustración 20) Ésta es la clase de configuración para la inicialización de Firebase, como indica la anotación “@Configuration”. El método “init” es anotado con “@PostConstruct”, lo que significa que se ejecuta después de que la clase haya sido construida. Este método construye una instancia de “FirebaseOptions” utilizando las credenciales de Google y la URL de la realtime database de Firebase. Por último, se inicializa la aplicación de Firebase llamando al método “initializeApp”. Ilustración 20: FirebaseConfig. • InfraccionData (ilustración 21) Esta clase es un modelo que representa los datos de una infracción, los cuales son: fecha, longitud, latitud, velocidad y velocidad máxima. En la ilustración 21 no se muestra la clase completa, pero todos los atributos tienen el método getter y setter.
15 15 Aplicación Android y Servicio Web para la recolección en tiempo real de infracciones de velocidad, con representación en mapa mediante ELK y Kafka Ilustración 21: InfraccionData – Firebase. • SecurityConfig (ilustración 22) Esta clase configura la seguridad de la aplicación, como indica su anotación “@Configuration” y “@EnableWebSecurity”. Esta clase extiende de “WebSecurityConfigurerAdapter”, que es una clase base proporcionada por Spring Security para facilitar la configuración de la seguridad en una aplicación web. El método “configure” es donde se configuran las reglas de seguridad para las solicitudes HTTP. Se configura un filtro de seguridad y proveedor de autenticación personalizados, “FirebaseFilter” y “FirebaseProvider” respectivamente. Ilustración 22: SecurityConfig. • TokenModel (ilustración 23) Es una clase que implementa “AbstractAuthenticationToken” y representa un token de autenticación. Tiene una propiedad para almacenar el token.
Aplicación desarrollada: Servicios Web 16 16 Ilustración 23: TokenModel. • UserModel (ilustración 24) Esta clase implementa la interfaz “Authentication” y representa un usuario autenticado. Tiene una propiedad para almacenar el registro de usuario de Firebase e implementa los métodos de la interfaz “Authentication” para acceder a la información del usuario. Ilustración 24: UserModel.
17 17 Aplicación Android y Servicio Web para la recolección en tiempo real de infracciones de velocidad, con representación en mapa mediante ELK y Kafka • FirebaseEntryPoint (ilustración 25) Esta clase implementa el método “commence()” de la interfaz “AuthenticationEntryPoint”. Este método se invoca cuando una solicitud no está autenticada y debe ser manejada por el “AuthenticationEntryPoint”. En este método, se responde con un error de autenticación. Ilustración 25: FirebaseEntryPoint. • FirebaseFilter (ilustración 26) Esta clase es un filtro de servlet que intercepta las solicitudes HTTP y extrae el token de autenticación de la cabecera de autorización. El método “doFilterInternal” se ejecuta para cada solicitud y extrae el token de la cabecera de autorización. Luego, crea una instancia de “TokenModel” y la establece en el contexto de seguridad utilizando “SecurityContextHolder”. Ilustración 26: FirebaseFilter. • FirebaseProvider (ilustración 27) Esta clase es un proveedor de autenticación personalizado que utiliza el SDK de Firebase para verificar y autenticar el token de autenticación. Implementa la interfaz “AuthenticationProvider” de Spring Security. El método “supports” verifica si la clase de autenticación es compatible con este proveedor. Y el método “authenticate” se encarga de la autenticación del token utilizando el SDK de Firebase.
Aplicación desarrollada: Servicios Web 18 18 Ilustración 27: FirebaseProvider. • FirebaseController Esta clase es un controlador REST que maneja las solicitudes relacionadas con Firebase, como indica la anotación “@RestController”. o El método “getMatriculaByUserId” maneja una solicitud GET a "/usuarios/{userId}/matricula" y devuelve la matrícula asociada al usuario con el ID especificado, ilustración 28. o El método “getInfraccionesByUserId” maneja una solicitud GET a "/usuarios/{userId}/infracciones" y devuelve una lista de infracciones asociadas al usuario con el ID especificado, ilustración 29. o El método “setMatriculaByUserId” maneja una solicitud POST a "/usuarios/{userId}/matricula" y almacena la matrícula para el usuario con el ID especificado, ilustración 30. o El método “setInfraccionByUserId” maneja una solicitud POST a "/usuarios/{userId}/infracciones" y almacena una nueva infracción para el usuario con el ID especificado, ilustración 31.
19 19 Aplicación Android y Servicio Web para la recolección en tiempo real de infracciones de velocidad, con representación en mapa mediante ELK y Kafka Ilustración 28: getMatriculaByUserId. Ilustración 29: getInfraccionesByUserId.
Aplicación desarrollada: Servicios Web 20 20 Ilustración 30: setMatriculaByUserId. Ilustración 31: setInfraccionByUserId. A continuación, se muestran dos tablas (tabla 1 y tabla 2) con las consultas y almacenamientos de datos mediante solicitud GET y otra tabla con las de solicitud POST: URI Parámetros Descripción /usuarios/{parámetro}/matricula “userId”: Id del usuario Obtiene la matrícula asociada al Id del usuario /usuarios/{parámetro}/infracciones “userId”: Id del usuario Obtiene las infracciones asociadas al Id del usuario. Tabla 1: Consultas de datos mediante GET – servicio web Firebase. URI Parámetros Descripción /usuarios/{parámetro}/matricula “userId”: Id del usuario Almacena la matrícula del cuerpo de la solicitud asociándola al Id del usuario. /usuarios/{parámetro}/infracciones “userId”: Id del usuario Almacena la infracción del cuerpo de la solicitud asociándola al Id del usuario. Tabla 2: Almacenamientos de datos mediante POST – servicio web Firebase.
21 21 Aplicación Android y Servicio Web para la recolección en tiempo real de infracciones de velocidad, con representación en mapa mediante ELK y Kafka 4.2 Servicio Web Kafka Este servicio web sirve para recibir la infracción de la aplicación Android y enviarla al topic configurado de Kafka. En este punto además se detalla la configuración necesaria de esta tecnología para el proyecto. 4.2.1 Estructura y funcionalidad En este apartado se detalla la estructura y la funcionalidad del servicio web Kafka. El proyecto está formado por los paquetes y clases que se muestran en la ilustración 32. Ilustración 32: Paquetes y clases del servicio web Kafka. • KafkaproducerApplication (ilustración 33) Es la clase principal de la aplicación. La anotación “@SpringBootApplication” indica que es una clase de aplicación Spring Boot y configura automáticamente la aplicación. El método “main” llama al método “run” de “SpringApplication” para iniciar la aplicación. Ilustración 33: KafkaproducerApplication. • InfraccionData (ilustración 34) Esta clase es un modelo que representa los datos de una infracción, los cuales son: latitud, longitud, matrícula y velocidad.
Aplicación desarrollada: Aplicación Android 28 28 5 APLICACIÓN DESARROLLADA: APLICACIÓN ANDROID n este capítulo se describe la parte del proyecto de la Aplicación Android. La aplicación Android ha sido llamada como “ELKaf Velocity”. La configuración necesaria de la aplicación Android relacionada con Firebase se detalla en el Anexo A. A continuación, se muestra un diagrama con los casos de uso de la Aplicación Android, ilustración 41. Ilustración 41: Diagrama de casos de uso – aplicación Android. 5.1 Estructura y funcionalidad En este apartado se detalla la estructura de la aplicación y las clases de ésta, ilustración 42. E
29 29 Aplicación Android y Servicio Web para la recolección en tiempo real de infracciones de velocidad, con representación en mapa mediante ELK y Kafka Ilustración 42: Paquetes y clases – aplicación Android. A diferencia del capítulo anterior, en este apartado no se pondrán ilustraciones de las clases, ya que son clases más extensas, pero se detallarán los métodos y su utilidad de forma clara. Se tienen dos clases que se usan como modelo para el usuario y para la infracción: ▪ UserData La clase UserData es una clase modelo que representa los datos del usuario registrado con los siguientes atributos: - userId: Id del usuario. - token: token asociado al usuario. - matricula: matrícula asociada al usuario. La clase también contiene los métodos getter y setter de dichos atributos y un constructor con todos los atributos. Además, esta clase implementa la interfaz “Serializable”, lo que significa que los objetos de esta clase se pueden convertir en una secuencia de bytes para ser transferidos o almacenados y luego se pueden reconstruir a partir de esa secuencia de bytes. ▪ InfraccionData La clase InfraccionData es una clase modelo que representa los datos de la infracción cometido con los siguientes atributos: - fecha: fecha en la que se comete la infracción. - longitud: longitud en la que se comete la infracción. - latitud: latitud en la que se comete la infracción. - velocidad: velocidad a la que se comete la infracción. - velocidadMáxima: velocidad máxima de la vía en la que se comete la infracción. La clase también contiene los métodos getter y setter de dichos atributos y un constructor con todos los atributos. En el paquete interfaces, existen dos clases: ▪ ApiService La clase ApiService es una interfaz que define los endpoints y los métodos para realizar llamadas a los servicios web de Firebase y de Kafka y al servicio web “overpass-api”. A continuación, se detallan los métodos definidos en la interfaz:
Aplicación desarrollada: Aplicación Android 30 30 o Servicio web “overpass-api”: - getVelMax(String url): Realiza una solicitud GET a una URL específica del servicio web “overpass’api” y devuelve un objeto JsonObject en la respuesta, del cual se obtienen datos como la velocidad máxima y el nombre de la vía. o Servicio web Kafka: - sendKafka(String lat, String lon, String matricula, String velocidad): Realiza una solicitud POST a la ruta "kafkaproducer/infracciones" con los parámetros de latitud (lat), longitud (lon), matrícula (matricula) y velocidad (velocidad). o Servicio web Firebase: - getMatriculaByUserId(String token, String userId): Realiza una solicitud GET, a la ruta "/usuarios/{userId}/matricula" con el token de autorización (token) y el ID de usuario (userId). Devuelve la matrícula del usuario en la respuesta. - setMatriculaByUserId(String token, String userId, String matricula): Realiza una solicitud POST a la ruta "/usuarios/{userId}/matricula" con el token de autorización (token), el ID de usuario (userId) y la matrícula (matricula). - getInfracciones(String token, String userId): Realiza una solicitud GET a la ruta "/usuarios/{userId}/infracciones" con el token de autorización (token) y el ID de usuario (userId). Devuelve una lista de objetos “InfraccionData” que representan las infracciones del usuario en la respuesta. - setInfraccion(String token, String userId, InfraccionData infraccionData): Realiza una solicitud POST a la ruta "usuarios/{userId}/infracciones" con el token de autorización (token), el ID de usuario (userId) y un objeto InfraccionData (infraccionData). La interfaz utiliza anotaciones de Retrofit para especificar el tipo de solicitud (GET o POST), las rutas de la API, los encabezados y los cuerpos de las solicitudes. Los tipos de respuesta esperados se especifican utilizando la clase Call de Retrofit junto con los tipos de datos correspondientes. ▪ InfraccionCallback La clase InfraccionCallback es una interfaz que define dos métodos de devolución de llamada (callback) para manejar los resultados de la obtención de infracciones y los errores en un contexto determinado. A continuación, se detallan los métodos definidos en la interfaz: - onInfraccionesObtenidas(List<InfraccionData> infracciones): Este método se llama cuando se han obtenido las infracciones de manera exitosa. Recibe como parámetro una lista de objetos InfraccionData que representan las infracciones obtenidas. - onError(String mensajeError): Este método se llama cuando se produce un error durante la obtención de las infracciones. Recibe como parámetro un mensaje de error que describe la causa del error. Esta interfaz se usa en la clase “HistorialInfraccionesActivity” que se verá a continuación. En el paquete adapter, existe la clase: ▪ InfraccionAdapter La clase InfraccionAdapter es un adaptador personalizado utilizado en el contexto de un RecyclerView para mostrar una lista de infracciones en la pantalla “Historial Infracciones”. A continuación, se detalla su funcionamiento: La clase extiende de RecyclerView.Adapter<RecyclerView.ViewHolder>, lo que indica que se
31 31 Aplicación Android y Servicio Web para la recolección en tiempo real de infracciones de velocidad, con representación en mapa mediante ELK y Kafka utilizarán elementos de vista “ViewHolder” dentro de un “RecyclerView”. El adaptador recibe una lista de objetos “InfraccionData” en su constructor, que representa las infracciones que se mostrarán en la lista. - Los métodos “onCreateViewHolder”, “onBindViewHolder” y “getItemCount” son métodos obligatorios de la clase RecyclerView.Adapter que deben implementarse. - La clase InfraccionAdapter contiene dos clases internas estáticas: HeaderViewHolder y InfraccionViewHolder, que extienden de RecyclerView.ViewHolder. Estas clases se utilizan para mantener las referencias a los elementos de vista en las vistas de encabezado (título de las columnas) y de infracción (valores de las columnas) respectivamente. En el constructor de cada clase, se obtienen las referencias a los elementos de vista “TextView” mediante el método “findViewById()”. - onCreateViewHolder(@NotNull ViewGroup parent, int viewType): en este método se rellena el diseño de vista correspondiente según el tipo de vista “viewType”. Si viewType es igual a HEADER_VIEW, se rellena el diseño del título de las columnas “item_encabezado”, de lo contrario, se rellena el diseño de los valores de las columnas “item_infraccion”. Luego, se crea y devuelve un objeto ViewHolder correspondiente al diseño rellenado. - onBindViewHolder(@NotNull RecyclerView.ViewHolder holder, int position): en este método se asignan los datos de las infracciones a los elementos de vista del “ViewHolder”. Si el “ViewHolder” es una instancia de “InfraccionViewHolder”, se obtiene la infracción de la lista según la posición y se asignan los valores correspondientes a los elementos de vista “textFecha”, “textPosicion”, “textVelocidad” y “textVelocidadMaxima”. - getItemCount(): este método devuelve el número total de elementos en la lista de infracciones más uno, ya que se agrega una vista de encabezado adicional para el título de las columnas. - getItemViewType(int position): este método determina el tipo de vista para una posición determinada. Si la posición es cero, se devuelve HEADER_VIEW (títulos de las columnas), de lo contrario, se devuelve ITEM_VIEW (valores de las columnas). A continuación, detallamos las clases Activity: • MainActivity La clase MainActivity es una actividad de Android que se utiliza como pantalla inicial de la aplicación. A continuación, se detallan los métodos y sus funciones en la clase: Esta clase contiene una instancia de “ActivityResultLauncher” llamada “resultLauncher”. Esta instancia se utiliza para registrar y manejar el resultado de la actividad de inicio de sesión de Google. El resultado se recibe en el método “onActivityResult()” del “ActivityResultCallback”, donde se obtiene la cuenta de Google firmada y se llama al método “firebaseAuthWithGoogle()” para realizar la autenticación en Firebase - onCreate(Bundle savedInstanceState): Este método se llama cuando se crea la actividad. Aquí se inicializan y configuran los componentes de la interfaz de usuario, se asocia al botón el inicio de sesión, usando el método “resultLauncher.launch()” y se crea una instancia del cliente de inicio de sesión de Google “mGoogleSignInClient” y de Firebase Authentication “mAuth”. - onStart(): Este método se llama cuando la actividad se vuelve visible para el usuario. Aquí se obtiene el usuario actualmente autenticado y se llama al método updateUI() para actualizar la interfaz de usuario en consecuencia.
Aplicación desarrollada: Aplicación Android 32 32 - firebaseAuthWithGoogle(String idToken): Este método se utiliza para autenticar al usuario en Firebase utilizando las credenciales de Google. Recibe un token de ID de Google como parámetro y llama al método “signInWithCredential()” de “FirebaseAuth” para realizar la autenticación. Si la autenticación es exitosa, se llama al método “updateUI()” con el usuario autenticado. - updateUI(FirebaseUser user): Este método se utiliza para actualizar la interfaz de usuario según el estado de autenticación del usuario. Si hay un usuario autenticado, se inicia la actividad “LoggedActivity” y se pasa a la pantalla LoggedActivity. • LoggedActivity La clase LoggedActivity es una actividad de Android que representa la pantalla principal de la aplicación una vez que el usuario ha iniciado sesión. A continuación, se detallan los métodos: - onCreate(Bundle savedInstanceState): Este método se llama cuando se crea la actividad. Aquí se inicializan y configuran los componentes de la interfaz de usuario, se obtiene el usuario actualmente autenticado de Firebase, se muestra la matrícula del usuario y se configuran los listeners de los botones. - showMatricula(String token, String userId): Este método utiliza Retrofit para realizar una solicitud HTTP al servicio web Firebase y obtener la matrícula del usuario. La matrícula se muestra en el campo de entrada de texto “matriculaTextInput” y se almacena en UserData. - saveMatricula(): Este método utiliza Retrofit para enviar una solicitud HTTP al servicio web Firebase y guardar la matrícula del usuario. La matrícula se obtiene del campo de entrada de texto “matriculaTextInput” y se almacena en UserData. - signOut(): Este método se utiliza para cerrar la sesión del usuario. Llama al método signOut() de FirebaseAuth para cerrar la sesión actual, luego inicia la actividad “MainActivity” y nos devuelve a la pantalla inicial. - irADeteccion(View view): Este método se llama cuando se hace clic en el botón "iraDeteccion". Crea una nueva instancia de la actividad “DetectorInfraccionesActivity” y pasa los datos de usuario “userData” a través de un intent. - irAInfracciones(View view): Este método se llama cuando se hace clic en el botón "mostrarInfracciones". Crea una nueva instancia de la actividad “HistorialInfraccionesActivity” y pasa los datos de usuario “userData” a través de un intent. - setUserData(String token, String userId, TextInputEditText matriculaTextInput): Este método se utiliza para configurar los datos de usuario “userData”. Crea una nueva instancia de UserData con el ID de usuario, el token y la matrícula proporcionados. - showToast(String message): Este método se utiliza para mostrar un mensaje emergente (Toast) en la pantalla con el mensaje proporcionado. • HistorialInfraccionesActivity La clase HistorialInfraccionesActivity es una actividad de Android que muestra el historial de infracciones de un usuario. A continuación, se detallan los métodos de la clase: - onCreate(Bundle savedInstanceState): en este método se obtiene el objeto “UserData” enviado desde la actividad anterior a través del intent. Luego, se llama al método “getInfracciones” para obtener las infracciones del usuario utilizando el
33 33 Aplicación Android y Servicio Web para la recolección en tiempo real de infracciones de velocidad, con representación en mapa mediante ELK y Kafka token y el ID de usuario. - goBack(): este método se utiliza para regresar a la actividad anterior (LoggedActivity) cuando se hace clic en el botón "singOut". - getInfracciones(String token, String userId, InfraccionCallback callback): este método se encarga de realizar una solicitud GET al servicio web Firebase para obtener las infracciones del usuario utilizando Retrofit. Se crea una instancia de “ApiService” y se realiza una llamada a “getInfracciones” pasando el token y el ID de usuario. La respuesta se maneja en los métodos onResponse y onFailure que hacen uso del método “onInfraccionesObtenidas” y “OnError” de la interfaz “InfraccionCallback”, respectivamente. - La implementación del método onInfraccionesObtenidas de la interfaz InfraccionCallback se llama cuando se obtienen las infracciones de manera exitosa. En este método, las infracciones se ordenan por fecha de manera descendente utilizando un comparador, y luego se crea y asigna el adaptador “InfraccionAdapter” al RecyclerView para mostrar las infracciones en forma de lista. - La implementación del método onError de la interfaz InfraccionCallback se llama cuando se produce un error durante la obtención de las infracciones. En este caso, se crea una lista de infracciones de error y se asigna al RecyclerView un adaptador que muestra el mensaje de error. • DetectorInfraccionesActivity La clase "DetectorInfraccionesActivity" es una actividad de Android que se encarga de detectar infracciones de velocidad utilizando la ubicación del dispositivo y enviar la infracción a Firebase y Kafka, a través de los servicios web anteriormente comentados. A continuación, está la descripción de los métodos: - onCreate(Bundle savedInstanceState): Método que se llama cuando se crea la actividad. Aquí se inicializan los componentes de la interfaz de usuario, se configuran los listeners y se obtiene “UserData” de la actividad anterior. - goBack(): Método que se llama cuando se hace clic en el botón "singOut". Su funcionalidad es regresar a la actividad anterior para regresar a la pantalla principal. - checkLocation(): Método que verifica si la ubicación está habilitada en el dispositivo usando el método “isLocationEnabled()”. Si no lo está, muestra un cuadro de diálogo de alerta llamando al método “showAlert()”. - showAlert(): Método que muestra un cuadro de diálogo para alertar al usuario de que la ubicación está desactivada y le proporciona la opción de ir a la configuración de ubicación para habilitarla. - isLocationEnabled(): Método que verifica si la ubicación está habilitada en el dispositivo. Devuelve true si está habilitada, y false en caso contrario. - showData(View view): Método que se llama cuando se hace clic en el botón "showData". Dependiendo del estado actual, comienza la detección de infracción o la para. - locationListenerBest: Implementación de “LocationListener” que se utiliza para obtener los cambios de ubicación cada 5 segundos o 50metros. Cuando se produce un cambio de ubicación, actualiza las variables de latitud, longitud, velocidad y se obtiene la velocidad máxima con el método “getVelMax”. Una vez los datos actualizados, muestra los datos en la interfaz de usuario y verifica si se ha cometido una infracción de velocidad, en el caso de haberse cometido una infracción se llama a los métodos “sendKafka” y “sendFirebase”, además de mostrar una alerta y registrarlo en el campo de infracción. En el caso contrario se muestra en el campo de
Aplicación desarrollada: Aplicación Android 34 34 infracción que no se ha cometido ninguna infracción. - getVelMax(double lat, double lon): Método que realiza una solicitud GET, al servicio web “overpass-api” utilizando Retrofit para obtener la velocidad máxima permitida en la ubicación actual. Construye la URL de la solicitud con la latitud y longitud proporcionadas, procesa la respuesta, actualiza la interfaz de usuario con la velocidad máxima obtenida y la devuelve. Se crea una instancia de “ApiService” y se realiza una llamada a “getVelMax”. - sendKafka(String latv, String lonv, String velv): este método se encarga de realizar una solicitud POST al servicio web Kafka para registrar la infracción utilizando Retrofit. Se crea una instancia de “ApiService” y se realiza una llamada a “sendKafka” pasando la latitud, longitud, matrícula y velocidad. - sendFirebase(String latv, String lonv, String velv, String velMaxv): este método se encarga de realizar una solicitud POST al servicio web Firebase para registrar la infracción utilizando Retrofit. Se crea una instancia de “ApiService” y se realiza una llamada a “sendFirebase” pasando el token, userId y infraccionData. - showToast(String message): Método que muestra un mensaje de texto corto en forma de Toast en la pantalla.
35 35 Aplicación Android y Servicio Web para la recolección en tiempo real de infracciones de velocidad, con representación en mapa mediante ELK y Kafka 6 INTERFAZ DE APLICACIÓN ANDROID n este capítulo se analiza cada una de las pantallas de la aplicación Android y las funcionalidades que ofrecen al usuario. Las pantallas de la aplicación Android se pueden agrupar en las de inicio de sesión, las que obtienen y envían datos al servicio web relacionado con Firebase y la encargada de detectar las infracciones de velocidad y enviar los datos al servicio web relacionado con Kafka. Para no repetir esta información por cada pantalla, se define que, salvo la pantalla inicial, todas las pantallas poseen un botón en la parte superior izquierda que te permite volver a la pantalla anterior. Además, en la pantalla principal al volver a la pantalla inicial se cierra la sesión. A continuación, se muestran y describen cada una de las pantallas de la aplicación Android. 6.1 Pantalla inicial La pantalla inicial de la aplicación, ilustración 43, permite: • Ir a la pantalla de inicio de sesión de Google, ilustración 44, la cual es propia de Google, ésta permite iniciar sesión con una cuenta ya existente o crear una cuenta para iniciar sesión con ella. Ilustración 43: Pantalla inicial – App Android. E
Interfaz de aplicación Android 36 36 Ilustración 44: Pantalla inicio sesión Google – App Android. 6.2 Pantalla principal La pantalla principal de la aplicación, ilustración 45, permite: • Ir a la pantalla de detección de infracción. • Ir a la pantalla del histórico de infracciones. • Ver la matrícula que tiene asociada el usuario o en caso de nuevo usuario aparece el texto “Introduce Matrícula” en el campo “Matrícula”. • Modificar la matrícula, para ello se debe modificar el texto que aparece en “Matrícula” y se presiona el botón “MODIFICAR MATRICULA”. Las dos primeras opciones mostrarán dichas pantallas en el caso de que el usuario tenga una matrícula registrada, en caso contrario pedirá que se introduzca una matrícula.
37 37 Aplicación Android y Servicio Web para la recolección en tiempo real de infracciones de velocidad, con representación en mapa mediante ELK y Kafka Ilustración 45: Pantalla principal – App Android. 6.3 Pantalla historial de infracciones La pantalla historial de infracciones, ilustración 46, permite: • Visualizar todas las infracciones cometidas, ordenadas por fecha. Muestra la fecha, posición (latitud, longitud), velocidad a la que se cometió la infracción y la velocidad máxima.
Interfaz de Kibana 44 44 Ilustración 55: Mapping del index de Kibana. De este mapping se destaca los siguientes campos, que ya se contemplaban en el filtro del fichero de configuración de Logstash, en el Anexo B: • Location de tipo geo_point, con el cual se puede representar el punto en el mapa • Matrícula de tipo texto, el cual representa la matrícula del vehículo. • Velocidad de tipo float, el cual representa la velocidad a la que se cometió la infracción. Para añadir este mapping al index se tienen que seguir los siguientes sencillos pasos [4]: 1 En la barra lateral izquierda seleccionar Dev Tools dentro de la categoría Management para abrir la consola. 2 Introducir PUT /nombre_index/_mapping y pegar el mapping de la ilustración 55. Ya solo queda la creación del Maps para poder representar las infracciones de forma geográfica. Para la creación de este Maps se tienen que seguir los siguientes pasos:
45 45 Aplicación Android y Servicio Web para la recolección en tiempo real de infracciones de velocidad, con representación en mapa mediante ELK y Kafka 1 En la barra lateral izquierda seleccionar Maps dentro de la categoría Analytics. 2 Presionar el botón create map. 3 Presionar Add layer. 4 Seleccionar Documents como tipo de layer para la representación de puntos. 5 Seleccionar el Data view que se quiera representar, en este caso el del index mencionado anteriormente y en la pestaña Geospatial field seleccionar el campo location, también mencionado anteriormente. 6 Presionamos Add layer. 7 Se introduce un nombre y se añade los campos matricula y velocidad, ilustración 56, y se presiona save&close. Ilustración 56: Creación de Maps Kibana.
Conclusión y líneas futuras 46 46 8 CONCLUSIÓN Y LÍNEAS FUTURAS Como conclusión, en este proyecto, se ha desarrollado una aplicación Android que permite a los usuarios iniciar sesión utilizando su cuenta de Google mediante la integración de Firebase. Además, la aplicación utiliza un servicio web y Firebase con su realtime database para almacenar la matrícula del vehículo asociada al usuario e infracciones de velocidad en dicha base de datos. Estas infracciones se pueden visualizar en una pantalla dentro de la aplicación. La aplicación utiliza el GPS para obtener la velocidad y la posición del usuario, y también accede a una API externa para obtener la velocidad máxima permitida en esa ubicación. Si la velocidad del usuario supera la velocidad máxima permitida, se envía la ubicación, matrícula y velocidad a un servicio web que a su vez lo envía a Kafka. La información es consumida por ELK (Elasticsearch, Logstash y Kibana), y finalmente se representa en un mapa en Kibana mostrando la ubicación del usuario junto con la velocidad y la matrícula correspondiente. Este proyecto ha demostrado la viabilidad de la integración de múltiples tecnologías y servicios para crear una aplicación Android con funcionalidades avanzadas, como la detección de infracciones de velocidad y su representación en un mapa interactivo. El uso de Firebase ha facilitado el almacenamiento y la recuperación de datos en tiempo real, mientras que Spring Boot ha permitido crear servicios web eficientes y escalables. La combinación de Kafka y ELK ha posibilitado la transmisión y el procesamiento de datos en tiempo real, proporcionando una visualización geográfica clara y concisa de las infracciones de velocidad. Aunque este proyecto ha logrado cumplir con los objetivos planteados, existen algunas áreas que podrían mejorarse en futuros desarrollos. Algunas de estas mejoras son: • Implementación de un sistema de clasificación y priorización de infracciones: Sería útil asignar una prioridad a cada infracción de velocidad registrada, para que las autoridades puedan tomar medidas rápidas y eficientes en función de la gravedad de cada infracción. • Mejora en la precisión de la detección de velocidad máxima: Si bien se ha consultado una API REST para obtener la velocidad máxima de la vía por la que circula el usuario, puede haber situaciones en las que la precisión no sea óptima. Sería beneficioso investigar y utilizar métodos adicionales para mejorar la precisión de la detección de velocidad máxima. Por último, una mejora relevante para el desarrollo futuro de esta aplicación sería el despliegue en la nube de todos los componentes involucrados. Actualmente, las pruebas se han realizado utilizando el emulador de Android Studio, lo cual puede limitar la precisión y la representación realista de situaciones en el mundo real. De hecho, se ha tenido que modificar la velocidad máxima, multiplicando ésta por dos, aunque el emulador de Android Studio ofrece 5 velocidades, la velocidad más lenta que éste ofrece supera la velocidad máxima. Al migrar el sistema a la nube, se podrían realizar pruebas reales utilizando dispositivos móviles físicos y obtener datos más precisos. En resumen, este proyecto ha sentado las bases para una aplicación Android completa y funcional que integra diversas tecnologías y servicios para detectar y representar infracciones de velocidad en tiempo real. Las mejoras mencionadas anteriormente podrían proporcionar una mayor usabilidad, funcionalidad y precisión, y podrían ser consideradas en futuros desarrollos de la aplicación.
47 47 Aplicación Android y Servicio Web para la recolección en tiempo real de infracciones de velocidad, con representación en mapa mediante ELK y Kafka Anexo A: Configuración de Firebase Ya se ha detallado que es Firebase y las dos características principales que se usan en el proyecto en el punto 3.1 de esta memoria. En este anexo se especifica como configurar Firebase desde su interfaz web y lo que hay que añadir a la aplicación Android y al servicio web para el correcto funcionamiento entre ellos. A.1 Autenticación con Google Lo primero es incorporar Firebase a nuestro proyecto Android y seleccionar cuenta de Google como inicio de sesión o método de autenticación, para ello existe una guía oficial [5] de la cual se han realizado los siguientes pasos, se destacarán algunos pasos importantes dentro de ellos: 1 Tener creado un proyecto en Android Studio. 2 Ir a la consola de firebase [6] e iniciar sesión con una cuenta de Google. 3 Una vez iniciada la sesión, se selecciona “agregar proyecto” y se continua con los pasos de creación del proyecto. 4 Se agrega Firebase a la aplicación Android seleccionando el icono de Android, como se muestra en la ilustración 59, y se siguen los pasos, de los cuales destacamos: a. Agregar el google-service.json, el cual tenemos que descargar, a la carpeta app del proyecto Android. b. Agregar el repositorio y dependencia detalladas en la ilustración 57 al build.gradle a nivel de proyecto y el plugins y dependencias detalladas en la ilustración 58 al build.gradle a nivel de app. Ilustración 57: Repositorios y dependencias build.gradle(Project)
Conclusión y líneas futuras 48 48 Ilustración 58: Plugins y dependencias buil.gradle(App) Ilustración 59: Agregar Firebase a aplicación Android 5 Importar las dependencias detalladas en la ilustración 60 al build.gradle a nivel de app, para el BoM de Firebase a fin de declarar la dependencia de la biblioteca de Android para Firebase Authenticacion, además, el SDK de Servicios de Google Play a la app. Ilustración 60: Mas dependencias build.gradle(App) 6 Habilitar el método de Acceso con Google, para ello se selecciona la pestaña “Authentication” en la barra lateral de la izquierda de la pantalla console de Firebase y se selecciona Google. A.2 SDK de Firebase Admin para servicio web El siguiente paso es agregar el SDK de Firebase Admin al servicio web, para ello tenemos una guía oficial [7] de la cual se han realizado los siguientes pasos, se destacarán algunos pasos importantes dentro de ellos: 1 Tener creado un proyecto de spring boot. 2 Importar la dependencia detallada en la ilustración 61 en el pom.xml.
49 49 Aplicación Android y Servicio Web para la recolección en tiempo real de infracciones de velocidad, con representación en mapa mediante ELK y Kafka Ilustración 61: Dependencia pom.xml Firebase 3 Inicializar el SDK, para ello, en la pantalla principal de la consola, ir a la pestaña configuración del proyecto, luego cuentas y servicio, seleccionamos Java y se selecciona “generar nueva clave privada”. Esta clave privada se guarda en la ruta “src/main/resources” con el nombre “serviceAccountKey.json”. 4 En el fichero “application.properties” se crea la variable que se muestra en la ilustración 62. Ilustración 62: Path de la configuración de Firebase 5 Incluir el código necesario al servicio web para que cuando se reciba cualquier petición se autentique con “Bearer token”. Dicho código se detalla en el apartado 5 de la memoria.
Conclusión y líneas futuras 50 50 Anexo B: Configuración ELK Ya se ha hablado de lo que es ELK, de sus características en el capítulo 3 de esta memoria y de la configuración de Kibana y creación de la pantalla Maps en el capítulo 7 de esta memoria. En este punto veremos el fichero .yaml que se ha creado para el uso de esta tecnología y cómo configurar Logstash para suscribirse a Kafka, transformar los datos obtenidos y almacenarlos en ElasticSearch. B.1 Fichero .yaml El fichero que podemos ver en la ilustración 63 detalla la configuración de ElasticSearch y Kibana, dos de las tres tecnologías que componen ELK, con sus respectivas imágenes de Docker y configuraciones específicas [8]. Ilustración 63: Fichero .yaml de ElasticSearch y Kibana. A continuación, se detalla la utilidad de cada campo: • version: '3.7': Indica la versión de la sintaxis de Docker Compose que se está utilizando en el archivo. • services: Define los servicios que se ejecutarán en contenedores, en este caso elasticsearch y kibana. o elasticsearch: Es el nombre del servicio de Elasticsearch.
51 51 Aplicación Android y Servicio Web para la recolección en tiempo real de infracciones de velocidad, con representación en mapa mediante ELK y Kafka ▪ image: Especifica la imagen de Docker utilizada para el servicio, en este caso, la imagen de Elasticsearch versión 8.1.0. ▪ container_name: Define el nombre del contenedor que se creará para el servicio. ▪ restart: always: Indica que el contenedor se reiniciará automáticamente en caso de que se detenga. ▪ environment: Permite definir variables de entorno dentro del contenedor de Elasticsearch. En este caso, se establecen dos variables: xpack.security.enabled=false para deshabilitar la seguridad de X-Pack y discovery.type=single-node para configurar Elasticsearch en modo de un solo nodo. ▪ ulimits: Establece los límites de recursos para el contenedor. En este caso, se configura memlock (bloqueo de memoria) y nofile (cantidad máxima de archivos abiertos) con valores específicos. ▪ cap_add: Permite agregar capacidades adicionales al contenedor. En este caso, se agrega la capacidad IPC_LOCK, que se utiliza para permitir el bloqueo de memoria en Elasticsearch. ▪ volumes: Mapea el volumen llamado "elasticsearch-data" al directorio dentro del contenedor donde Elasticsearch almacena sus datos. ▪ ports: Mapea el puerto 9200 del host al puerto 9200 del contenedor. o kibana: Es el nombre del servicio de Kibana. ▪ container_name: Define el nombre del contenedor que se creará para el servicio. ▪ image: Especifica la imagen de Docker utilizada para el servicio, en este caso, la imagen de Kibana versión 8.1.0. ▪ restart: always: Indica que el contenedor se reiniciará automáticamente en caso de que se detenga. ▪ environment: Permite definir variables de entorno dentro del contenedor de Kibana. En este caso, se establece ELASTICSEARCH_HOSTS como http://elasticsearch:9200, lo que indica que Kibana se conectará a Elasticsearch en el host "elasticsearch" en el puerto 9200. ▪ ports: Mapea el puerto 5601 del host al puerto 5601 del contenedor. ▪ depends_on: Define una dependencia entre servicios. En este caso, se indica que Kibana depende de que el servicio de Elasticsearch esté en funcionamiento antes de iniciar. • volumes: Define un volumen llamado "elasticsearch-data" que se utilizará para persistir los datos de Elasticsearch fuera del contenedor. B.2 Configuración Logstash En este apartado se detalla el archivo de configuración utilizado por Logstash, ilustración 64, en el cual se especifica la entrada, el filtro y la salida de datos. Dicho archivo se debe ubicar en la ruta “etc/logstash/conf.d”.
Conclusión y líneas futuras 52 52 Ilustración 64: Fichero configuración Logstash. A continuación, se expone la estructura y utilidad de cada campo: • Input: kafka: Configura Logstash para leer datos de un clúster de Kafka. o bootstrap_servers: Especifica la dirección y el puerto de los servidores de Kafka desde los que se leerán los datos. o topics: Define los temas de Kafka de los que se leerán los mensajes. En este caso, se utiliza el tema "prueba". o codec: Establece el códec de entrada para decodificar los mensajes. Aquí se utiliza el códec JSON para procesar mensajes en formato JSON. • filter: o json: Analiza el campo "message" y convierte su contenido de JSON a una estructura de datos. o mutate: Realiza varias transformaciones en los campos de los eventos. ▪ convert: Convierte los campos "lat", "lon" y "vel" en tipo de datos float. ▪ add_field: Agrega nuevos campos al evento. En este caso, se crean los campos "location", "matricula" y "velocidad" a partir de otros campos existentes en el evento. ▪ remove_field: Elimina los campos "event", "lat", "lon", "mat" y "vel" del evento.
53 53 Aplicación Android y Servicio Web para la recolección en tiempo real de infracciones de velocidad, con representación en mapa mediante ELK y Kafka • Output: elasticsearch: Configura Logstash para enviar los datos procesados a Elasticsearch. o hosts: Especifica la dirección y el puerto del servidor de Elasticsearch al que se enviarán los datos. o index: Define el nombre del índice en Elasticsearch donde se almacenarán los datos. En este caso, se utiliza el índice "prueba". o workers: Establece el número de trabajadores (hilos) que Logstash utilizará para enviar los datos a Elasticsearch. Aquí se especifica un único trabajador. Se destaca de este fichero el filter, debido a que es el que se encarga de convertir los tipos de datos obtenidos de Kafka a el tipo de dato que se necesita en Elasticsearch para su correcta representación en Kibana. La forma en la que se define el campo “location” es muy importante, ya que como se detalla en el siguiente apartado, se define ese campo como tipo “geo_point”, el cual necesita estar formado por dos float.