Skip to content

Category: AWS

SQS en AWS con Spring Boot – Parte II

En el post pasado, revisamos que es una cola cuando hablamos de desarrollo, en que casos nos puede servir y que alternativas encontramos en el mercado para poder usarlas. Puntualmente, hicimos una demo de el uso de esta herramientas con SQS que es un servicio ofrecido por AWS. Sin embargo, buscando no extender el post y la demo demasiado conforme iba avanzando el post anterior, decidí que era mejor dividirlo en dos partes. En la primera, revisamos como crear desde AWS un usuario con los permisos necesarios para conectarse a una cola, en código con un proyecto hecho con spring boot conectarnos a esta y poder enviar mensajes.

En esta segunda parte, revisaremos como podemos suscribirnos a una cola, y estar a la escucha de nuevos mensajes.

Para poder conseguir esto, y no estar llenandonos de proyectos voy a usar el mismo proyecto en spring boot de la ves pasada, con la diferencia que creare algunos nuevos componentes, la idea basicamente es consumir una api desde un controlador, esta encola el mensaje y en un listener recibirlo e imprimirlo en consola.

Veamos que hemos añadido en nuestro proyecto inicial.

POM

Nuevas dependencias en el POM
Nuevas dependencias en el POM

JmsConfiguration

Clase de configuración del JMS
Clase de configuración del JMS

SqsListener

Clases del SqsListener
Clases del SqsListener

Con lo añadido en nuestro POM, tenemos acceso a clases de configuración que nos permitirán configurar un listener para las colas que ya tenemos definida en SQS. Si vemos a detalle la clase de configuración que hemos creado, tenemos lo siguiente:

Configuración en el JmsListener
Configuración en el JmsListener

En esta clase, como podemos ver, estamos creando un factory para las conexiones a AWS esto en el método “sqsConnectionFactory” y adicionalmente, configuramos nuestro listener factory para estar a la escucha de nuestra cola definida en AWS.

Como ven, tenemos que indicar que esta clase es de configuración con @Configuration, además de indicarse que habilite el JMS con @EnableJms. Sólo para aclarar por si hubiera alguna duda, JMS son las siglas de Java Message Service que es una clase definida en la librería JMS que nos permite realizar la creación y suscripción de mensajes a través de una cola.

Y finalmente, tenemos que crear nuestro listener, esto lo hacemos del siguiente modo:

SqsListener
SqsListener

Creamos una clase y dentro creamos un método void con las siguientes anotaciones “@JmsListeners” que tiene dentro un “@JmsListener”. Es necesario dentro de esta última anotación indicarle cual es el nombre de la cola que vamos a estar a la escucha en nuestro listener.

Hagamos una prueba de todo junto.

Primero realizamos el consumo de nuestro controlador con una mensaje cualquiera.

Consumiendo el API
Consumiendo el API

Recibimos el mensaje en nuestro controlador.

Recibiendo el mensaje en el controlador
Recibiendo el mensaje en el controlador

El mensaje es enviado a nuestra cola previamente configurada en SQS.

Se genera el mensaje correctamente
Se genera el mensaje correctamente

Mensaje encolado en SQS.

Mensaje en SQS
Mensaje en SQS

Ahora, segundos despues de que se encoló el mensaje, debería llegar a nuestro listener que esta escuchando la misma cola “SqsTest”.

Recibimos el mensaje
Recibimos el mensaje
Log del mensaje
Log del mensaje

Con esta prueba concluye este post. El código lo subire como una actualización al proyecto anterior. Espero que les sirva, como ven es sencillos tener un manejo de colas funcional con sólo un poco de código. Dejo el link del repo y el video.

REPO GITHUB

Saludos.

Leave a Comment

SQS (Manejo de Colas) en AWS con Spring Boot – Parte I

Hola, hace ya algún tiempo desde el último post, la verdad es que la cuarentena nos a permitido a todos tener más tiempo con la familia, pero también a los que nos dedicamos al desarrollo de software nos hemos cargado de trabajo. En mi caso, especialmente por que mi familia tiene un colegio y he tenido que asumir la migración a la enseñanza virtual.

Bueno, vamos al tema que nos reclama este post, en el proyecto en el que me encuentro trabajando he tenido la oportunidad de meterme a bucear por distintos servicios de AWS que estamos usando en la arquitectura. Este proceso a sido desafiante y de mucho aprendizaje, y quiero plasmar en una serie de posts mi exploración a los servicios de AWS. Empezando por el servicio de SQS que es basicamente un encolador de mensajes, sólo que es la alternativa que nos ofrece AWS. Deben ya de conocer algún servicio similar a estos, que yo recuerde ahora uno con el que hice una pruebas era RabbitMQ, que era un software open source que tenías que instalar en tu pc o en el servidor en el que lo quisieras usar y te permitia generar las colas y suscribirte a ellas, y realizaba el manejo de los mensajes que ibas encolando.

Me parece importante detallar un poco bajo que condiciones es necesario usar este servicio. Usualmente, cuando tenemos varios microservicios (puede entendeser como varias APIs), entrar a detallar de las caraterísticas que la hacen un microservicio va a extender mucho el post así que dejemoslo ahí. Pero cuando queremos que estos se comuniquen, podemos directamente hacer una solicitud http entre ellas y de ese modo la solicitud sería instantanea. Sin embargo, que sucede si son miles de peticiones, si alguna se cae o si se satura el microservicio que estamos consumiendo, como tener un control en la llegada de estas peticiones.

Teniendo en cuenta esto, es que entran a tallar soluciones de encolación de mensajes. Dado que nos permiten enviar mensajes (peticiones) a una cola que tengamos definido (inclusive definirla en tiempo de ejecución) y luego el suscriptor a esa cola va a ir desencolando los mensajes y procesandolos uno a uno. Del modo más básico esto es lo que se consigue usando este tipo de herramientas y amazon nos provee este servicio con SQS.

Entonces, ya teniendo claro para que podemos usarlo, veamos como se implementó. Primero debemos de tener una cuenta de AWS creada, en este punto quiero aclarar que si bien todos los recursos que voy a crear puede ser hechos desde un json y luego deployados con cloudformation en AWS o desde el AWSCLI, yo voy a usar la web de amazon por que me parece que es la forma más simple de hacerlo y a propositos de esta demo me sirve más. Con la cuenta que debemos tener, es necesario ir a IAM y crear un usuario que tenga asignado el siguiente rol:

Creacion de usuario
Indicar permisos

Luego no olviden copiar el access-key y secret-key que nos va a brindar IAM. Ahora veamos el proyecto en spring que hemos creado.

Usaremos las siguiente dependencias, en el POM:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-aws-messaging</artifactId>
            <version>2.0.1.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
Estructura del proyecto

He dividido de módo básico en capas el proyecto, quedando del siguiente modo:

  • Controller: Y sabemos para que es esta capa.
  • Service: Para ejecutar la lógica que necesitemos.
  • Configuration: Para realizar la configuracion inicial de aws.
  • Infraestructure: Acá ejectuamos las acciones en las librerias externas que usemos.

Nuestro controlador, es un endpoint que recibe una path variable que sera lo que encolaremos.

Controller

En nuestro service, llamamos a nuestra capa infraestructure para pasarle nuestro mensaje y que realice en encolado, estamos devolviendo un objeto anonimo, que indica si se registro correctamente, el mensaje que se a encolado y el uuid que nos retorna aws cuando generamos el encolado.Veamos que hace el método marcado.

Service

Como pueden ver, preparamos el objeto que vamos a encolar, estamos usando un ObjectMapper para convertir el objeto que recibimos (en nuestro caso un string) a un formato json y esto encolarlo. En este punto, también indicamos cual es la URL a la cual se dedbe encolar, la cual obtuvimos en el service por injección de dependencia directamente desde nuestro archivo yml.

Infraestructure

Revisemos que configuración tenemos en nuestro “AwsConfiguration”. Como pueden ver, por injección de dependencia obtenemos el accesskey y secretkey que hemos generado al iniciar todo y los seteamos en el “BasicAWSCredentials” que luego usamos para generar un objeto del tipo “AmazonSQS”, que es el que nos permite encolar la información entre otras cosas.

AwsConfiguration

Mientras realizaba el desarrollo del post, me di cuenta que hacer el listener de esta cola en este post iba a hacer que sea demasiado extenso. Por lo que termine decidiendo que en el próximo entrare a cubrir este detalle. Espero que les sriva y si tienen alguna duda pueden contactarme por alguno de los medios que he dejado, ver el video o revisar la documentacion oficial de AWS que es muy buena y completa.

Documentación Oficial

REPO GITHUB

Saludos

Leave a Comment

Logging en Cloudwatch (Amazon Web Services)

Hace un tiempo en el trabajo tuve la oportunidad de ser parte de un proyecto que buscaba centralizar el logging de múltiples aplicaciones en una sola y persistir esta información no en una base de datos, sino en uno de los servició que ofrece Amazon Web Services (AWS) para este fin que es CloudWatch. Esto me llevo a todo un proceso de investigación y recabar información sobre la mejor manera de realizar este grabado de log. De ese proceso de investigación nace este post.

Primero, hay que decir que AWS es todo un mundo por si solo, se tienen muchos servicios orientados a necesidades especificas en el proceso de desarrollo de software, asi como también de cara al despliegue de aplicaciones, seguridad, networking, almacenamiento, entre otros. Esto me lleva a comentarles que en adelante intentaré realizar más post sobre los servicios que ofrecen y como se pueden usar, esto obviamente lo hago para compartir la información y también afianzar lo poco o mucho que puedo ir aprendiendo. Vamos al tema en específico, cuando me planteo realizar esta aplicación, que por lo demás tenía claro que era un API en net core, busque que alternativas tengo para comunicarme con AWS y específicamente con cloudwatch, encontrando las siguientes:

  • SDK de Amazon
  • Diversas librerias que se integran con aplicaciones de loggers (Nlog, Log4net, Serilog, etc).

Debido al tiempo que tenía para realizar la aplicación y a la experiencia que tenía con las herramientas que tenía a la mano, termine decantandome por usar la librería para Nlog. Esto, por que ya tenía el conocimiento de Nlog, te instala un módulo que le permite tener acceso a cierta información para grabar un log. Sin embargo, esto me trajo algunas complicaciones para el caso de net core que ya más adelante veremos.

Proyecto

La demo, consta de una aplicación web api generada de 0, con lo mímimo necesario apra que pueda funcionar nuestro log en AWS. Las librerías a usar, son las siguientes:

  • AWS.Logger.NLog (v1.5.1)
  • NLog (v4.6.8)

Me interesa explicar como se lleva a cabo esta configuración, dado que lo demás es lo típico con cualquier aplicación en net core. En nuestro archivo “Startup.cs” tenemos que realizar las siguientes configuraciones:

Configuración del target en nlog para AWS

Config target

Como se puede ver, se crea una nueva clase del target (que esta disponible luego de instalar la librería) y tenemos que proporciarle cierta información:

  • Credentials: Se le indica el tipo de autenticación que se va a usar, para la demo he creado en AWS un IAM (manejo de indentidad) que sólo tenga permisos para poder comunicarse con cloudwatch (en otro post voy a ahondar en como AWS maneja la seguridad), existen otras tipos de credenciales, por ejemplo en el trabajo dado que nuestro aplicativo está en un EC2 se puede obtener la autenticación de la máquina.
  • LogGroup: Cada uno de los log que se graben están asociados a un log group, que digamos que es la instancia que se crea para almacenar todos los logs que provengan de ese cliente.
  • Region: Es la región en la cual está nuestra cuenta de AWS. Entendamos que esta plataforma esta mundial, y por lo tanto tiene servidores en distintos lugares del mundo, esto debido a buscar que sus servicios sean escalables y redundantes ante cualquier eventualidad y a ti como usuario te permite elegir consumir los servicios que ofrecen en distintos lugares del mundo. De esto también se puede ahondar más adelante.
  • LogStreamNameSuffix y LogStreamNamePrefix : Cuando se crea una nueva instancia en un log group esta se crea con un identificador único la cual es un GUID más un timestamp, esto es así si no se le proporciona ningún parámetro. En cambio si le pasamos un sufijo o un prefijo ya no se genera el GUID, sino se le concatena a lo establecido (prefijo y sufijo) la marca de tiempo.
  • Layout: Este punto lo deje al final por que es donde probablemente me deba explayar más. como ven es un texto, pero me estoy valiendo de los layouts renders proporcionados por nlog para obtener cierta información y evitarme tener que obtenerla por otros medios.

Ampliando el último punto, pueden encontrar más información sobre esto en este link.

Una ves que se configura el target de AWS, es necesario indicarle a nlog que debe de usarlo, asociarle los eventos del log y la configuración a logmanager. Veamos como se hace esto en código.

Configuración de nlog

Como se puede ver, se crea el un nuevo “LoggingConfiguration”, a este se le asocia el target a aws creado y además las reglas a las cuales estará vinculado nuestro target, finalmente también estoy indicando donde estará el log interno de nlog y le paso toda está configuración a logmanager.

Para cierta información que en teoría debería ser proporcionada por los layout render, pero que parece que en net core no funcionan correctamente, me valí de un Middleware, acá pueden ver que información de obtiene de ahí.

Configuración del middleware

Se está obteniendo la URL que se está consumiendo, el username que consume la aplicación, si se tuviera como header, el método http (PUT, POST, GET, etc). Finalmente, cuando un evento de log (para nuestra demo excepción) se lleva a cabo.

Evento de error disparándose
Disparando el log

Finalmente, veamos nuestro appsettings para ver que configuración tenemos ahí.

Configuración del appsetting

El accesskey y secretkey son las que cree para la demo, este usuario ya ha sido eliminado de mi cuenta de aws.

Realicemos la prueba de nuestra demo para ver si efectivamente tenemos nuestro log en AWS ahora. Primero tomemos algunas capturas del ambiente antes de ejecutar nuestra demo.

Log Groups en AWS

Listado de log groups

Postman

Get request

Levantamos la solución (con lo que nuestro log group ya debería haberse creado en AWS) y realizamos la solicitud al api.

Entro a la excepción
Esta por enviarse el log a AWS
Respuesta en postman
Validamos que se creo nuestro log group
Validamos nuestro log stream
El log grabado

Como podemos ver (si hacemos zoom) nuestro log se ha grabado correctamente en AWS.

Con esto llegamos al fin del post, dejo el link al repositorio donde está el código fuente por si quieres revisarlo y un video de la demo.


REPO: GITHUB

Saludos.

2 Comments