Blog de Amazon Web Services (AWS)
Creación de informes con Lambda, RDS y JasperReports
Por Pedro Rates, Arquitecto de Soluciones de AWS Brasil
La biblioteca JasperReports es un motor de generación de informes ampliamente utilizado en la industria, que proporciona a los usuarios la capacidad de crear informes completos y bien estructurados de forma fácil y rápida. La biblioteca es de código abierto y se puede incrustar en una aplicación Java, pudiendo integrarse con varias fuentes de datos y exportar documentos a una variedad de formatos. En esta entrada de blog, voy a discutir el despliegue de una función Lambda escrita en Java capaz de crear y poner a disposición un informe JasperReports en formato PDF. La función Lambda obtendrá los datos que formarán el informe, de una instancia de Amazon Relational Database Service (Amazon RDS) con el motor MySQL y utilizará una plantilla JasperReports almacenada en un bucket de Amazon Simple Storage Service (Amazon S3), en « .jrxml». Esta solución elimina la necesidad de administrar instancias para alojar la aplicación de informes, y mediante AWS Lambda y le permite utilizar JasperReports a través de un microservicio independiente y desacoplado.
Resumen de la solución
La solución que presentamos en este blog consiste en la arquitectura a continuación. En esto, utilizamos una función Lambda para obtener una plantilla JasperReports que está almacenada en un bucket de Amazon S3 y para generar el informe en función de los datos que obtenemos de una base de datos de Amazon RDS. Para que la función Lambda pueda acceder a la base de datos de forma segura, almacenamos las credenciales de la base de datos en forma de secreto en el servicio AWS Secrets Manager, de modo que la función solo acceda al secreto en tiempo de ejecución.
Arquitectura de la solución para informes JasperReports mediante AWS Lambda y Amazon API Gateway. En esta arquitectura, Amazon RDS almacena los datos que componen el informe, Amazon S3 almacena la plantilla de informe y AWS Secrets Manager almacena de forma segura las credenciales para conectarse a la base de datos.
En esta guía, seguiremos los siguientes pasos para implementar la solución de generación de JasperReports:
- Ejecute la plantilla Cloudformation para crear parte de los servicios que integran la solución;
- Creación de la solución en AWS Lambda mediante AWS Toolkit for Eclipse
- Asociar la función Lambda a la VPC creada por Cloudformation;
- Creación del secreto con las credenciales de base de datos en AWS Secrets Manager
- Agregar variables de entorno a la función Lambda
- Creación de una API Gateway integrada con la función Lambda
- Modificar consultas de base de datos y pasar parámetros la función
- Modificación del diseño de informe JasperReports
Requisitos previos
Para seguir esta guía, debe cumplir los siguientes requisitos previos:
- Tener una cuenta de AWS con permiso para crear y modificar recursos en los siguientes servicios: Cloudformation, Lambda, Amazon RDS, Secrets Manager, Amazon S3, VPC, API Gateway, IAM;
- Tener la CLI de AWS instalada y configurada con una cuenta que tenga el acceso mencionado anteriormente;
- IDE de Eclipse con AWS Toolkit for Eclipse instalado;
- Conocimientos intermedios en el lenguaje de programación Java;
- Familiaridad con la consola de administración de AWS.
Configuración inicial
En un directorio local, clone el siguiente repositorio:
https://github.com/aws-samples/jasper-reports-with-lambda-rds
En este repositorio se encuentra la plantilla Cloudformation responsable de crear parte de los recursos en su cuenta de AWS, la plantilla de informe JasperReports y el código Java de la función Lambda.
Parte 1 — Ejecución de la plantilla Cloudformation
Para iniciar la guía, vamos a lanzar una plantilla de Cloudformation. Para ello, vaya a Cloudformation desde la consola web de AWS y haga clic en «Create Stack» en la esquina superior derecha. Seleccione la opción «With new resources (standard)».
En la pantalla «Create Stack», mantenga activada la opción «Template is ready» y seleccione la opción «Upload a template file ». A continuación, haga clic en el botón «Choose file» y seleccione el archivo «jasper-lambda-architecture.json» ubicado en la raíz del proyecto que clonó en su máquina. Haga clic en «Next».
En la pantalla « Specify stack details», introduzca un nombre para la pila, el usuario y la contraseña de la cuenta maestra de la base de datos. La contraseña debe tener entre 8 y 41 caracteres, y puede incluir cualquier carácter imprimible ASCII excepto «@», «» y «/». Tome nota del nombre de usuario y la contraseña que introdujo, ya que se utilizarán en los próximos pasos.
Haga clic en «Next». En la pantalla «Configure stack options», deje todo como está y haga clic en «Next». En la pantalla «Review», marque la casilla «I acknowledge that AWS CloudFormation might create IAM resources.» y haga clic en «Create Stack».
La operación debe tardar unos minutos en completarse. Una vez completado, vaya a la pestaña «Salidas» de la pila y observe los valores de «IAMROLearn» y «JasperBucketName».
En la raíz del proyecto que clonó en su máquina, verifique la existencia del archivo «template.jrxml». Abra la consola de comandos en su ordenador y ejecute el siguiente comando para cargar este archivo en el bucket de Amazon S3 creado por CloudFormation. No olvide reemplazar el marcador de posición con el nombre de su bucket.
aws s3api put-object —-bucket marcador
de posición —-key
template.jrxml -—plantilla de cuerpo.jrxml
Parte 2 — Creación de la función Lambda
Importe el proyecto de Github clonado como un proyecto Maven en Eclipse. El primer paso necesario es implementar el método que genera el informe que queremos, en la clase «ReportGenerator.java». Para hacer esto, en el método «GenerateReport», reemplace la excepción lanzada en la línea 63 con el código que generará el informe.
Para que el código anterior funcione correctamente, deberá importar al proyecto la biblioteca JasperReports en la versión 6.11.0, que se puede encontrar en el siguiente enlace:
https://community.jaspersoft.com/project/jasperreports-library
También puede incluir esta biblioteca editando el archivo «pom.xml» ubicado en la raíz del proyecto.
Después de completar las modificaciones, haga clic con el botón derecho en el paquete «com.amazonaws.lambda.demo» y seleccione la opción «Amazon Web Services -> Upload function to AWS Lambda…». En la ventana que se abre, asegúrese de seleccionar la opción «Create a New Lambda function », elija un nombre para la función Lambda y haga clic en «Next».
En la siguiente ventana, seleccione el Rol de IAM creado por Cloudformation en «Function Role». En la sección «S3 Bucket for Function Code», seleccione el bucket de Amazon S3 creado por Cloudformation. Cambie el tiempo de espera a 300 y haga clic en «Finish». Una vez completada la operación, la función Lambda se puede ver en la consola de AWS.
Parte 3 – asocie la función Lambda con la VPC en la que se encuentra la base de datos de Amazon RDS
Desde la consola de AWS, vaya al servicio Lambda y seleccione la función que acabamos de crear con el Eclipse. Desplácese hacia abajo hasta la sección «VPC» y haga clic en «Editar». Seleccione la VPC creada por Cloudformation (CIDR 173.0.0.0/24) y seleccione sólo la subred privada: la que tiene el nombre «subnet-privada». En SecurityGroups, seleccione «JasperLambdaSecurityGroup». Haga clic en «Guardar».
Parte 4 — Creación de secreto en Secrets Manager
Acceda a Secrets Manager desde la consola de AWS y haga clic en «Almacenar datos confidenciales nuevos». Seleccione la opción «Credenciales para la base de datos RDS» e introduzca el usuario y la contraseña que utilizó al crear los recursos mediante Cloudformation. Seleccione la instancia «jasperreportsdb» en la sección «Seleccione a qué base de datos RDS tendrá acceso este secreto».
Haga clic en «Siguiente». En «Nombre de los datos confienciales», asigne un nombre al secreto y haga clic en «Siguiente». Escriba el nombre que dio para el secreto, ya que lo usaremos en el siguiente paso. En la siguiente pantalla, mantenga la configuración predeterminada y haga clic en «Siguiente». En la pantalla de Revisar, haga click en «Almacenar».
Parte 5 — Configuración de variables de entorno Lambda
Vuelva a la función Lambda que editamos en el paso 3. En la sección «Variables de entorno», haga clic en «Editar». Agregue los siguientes valores:
- RDS_DB_DRIVER: mariadb.jdbc.Driver
- SECRET_NAME: nombre del secreto creado en el paso 4
- SECRET_REGION: nosotros-este-1
- BUCKET_NAME: nombre del depósito creado por la plantilla de cloudformation
Haga clic en «Guardar».
Parte 6 — Creación de API Gateway
Vaya al servicio API Gateway en la consola de AWS y haga clic en el botón «Crear API» en la esquina superior derecha. Seleccione una API de tipo «API REST» haciendo clic en «Crear» en la tarjeta correspondiente.
Mantenga seleccionada la opción «API nueva», asigne a su API un nombre y una descripción, y mantenga el «Tipo de punto de enlace» como «Regional». Haga clic en «Crear API».
En la pantalla API creada, haga clic en «Acciones» y luego en «Crear método». Seleccione el método «GET».
Deje «Función Lambda» seleccionado como tipo de integración, marque la casilla «Usar integración de proxy de Lambda» y seleccione la función Lambda que se creó en el paso 2. Mantenga las otras opciones tal como están y haga clic en «Guardar». Haga clic en «Aceptar» en el cuadro que aparece.
En el menú API en el lado izquierdo de la pantalla, haga clic en «Configuración» arriba de «Planes de uso». Desplácese hacia abajo hasta la parte inferior de la pantalla hasta la sección «Tipos de medios binarios», haga clic en «Agregar tipo de medio binario» y agregue un comodín: «*/*». Haga clic en «Guardar los cambios».
Vuelva a la sección «Recursos» en el menú API, haga clic en «Acciones» y «Implementar la API». Cree una nueva etapa de despliegue e introduzca un nombre y una descripción opcionalmente para la etapa y el despliegue. Haga clic en «Implementación».
Ahora, en la pantalla «Etapas», haga clic en la url «Invocar URL», y una nueva apertura debería abrirse. Después de unos segundos, el informe JasperReports aparecerá en formato PDF para descargarlo en su equipo. Descargue el archivo y ábralo con su visor de PDF preferido. El resultado debería ser el siguiente:
Parte 7- Pasar parámetros para filtrar los resultados y personalizar la consulta SQL
Amazon API Gateway permite al usuario pasar datos a la función Lambda de varias maneras: a través de encabezados, cuerpo de solicitud, parámetros de ruta y parámetros de query string son algunos ejemplos. En esta guía, utilizaremos parámetros de consulta para que podamos filtrar la consulta en SQL modificando nuestro informe.
En la clase «LambdaFunctionHandler.java» de esta solución, extraemos todos los parámetros de cadena de consulta de la solicitud y los almacenamos en un objeto JSON en la variable «QueryParameters». Esta variable se pasa como parámetro al método «GetBeanList» de la clase «RDSConnector.java», responsable de obtener los datos del informe de la base de datos.
En el método «GetBeanList», consultamos la base de datos de Amazon RDS y recuperamos los datos del informe, que, en este ejemplo, es una lista de colaboradores que contiene el identificador, el nombre y el país de cada uno. En este método, buscamos el parámetro string con el nombre «country», y usamos su valor en la cláusula «where» de la consulta de base de datos. En nuestro ejemplo, si el parámetro de cadena «country» no existe en la URL de solicitud, devolveremos todos los elementos de la tabla.
Para ver el uso del filtro a través de la cadena de consulta en acción, copie la URL de invocación del API Gateway que usamos en el paso anterior y agregue la cadena de consulta «país» con el valor «Brazil», como en el siguiente ejemplo:
https://id-de-su-api.execute-api.us-east-1.amazonaws.com/Teste?country=Brazil
Esta vez, el informe generado debe estar compuesto únicamente por empleados brasileños:
Siéntase libre de editar la consulta y modificar los parámetros de cadena de consulta según lo considere necesario.
Parte 8 – Modificación del diseño del informe
El diseño de los informes JasperReports está controlado por el archivo de plantilla, que, en el caso de esta guía, es el archivo «template.jrxml» que agregamos a S3 en el paso 1 de esta guía. JasperReports utiliza XML para configurar la visualización del informe, y puede cambiar la plantilla utilizando el editor de texto de su elección o el editor especializado de JasperSoft Studios. Para que los cambios se reflejen en el informe, asegúrese de volver a cargar la plantilla a S3 después de actualizar la plantilla, teniendo cuidado de mantener el mismo nombre, ruta y depósito.
Limpiar recursos
Para evitar cargos futuros, es importante que limpiemos los recursos que creamos durante esta guía. El primer paso es eliminar la API Gateway que creamos en el paso 6. Para esto, vaya al menú «Recursos», haga clic en «Acciones» y luego en «Eliminar API». Introduzca el nombre de la API en el cuadro de diálogo y confirme la eliminación del recurso.
Luego eliminaremos la función Lambda creada en el paso 2. En la consola de servicio de Lambda, seleccione la función creado anteriormente. Haga clic en «Acciones -> Eliminar» y, a continuación, haga clic en «Eliminar» en el cuadro de diálogo para confirmar la eliminación.
Acceda al servicio Amazon S3 desde la consola y busque el bucket creado por CloudFormation. Seleccione el bucket, haga clic en «Vaciar», escriba «eliminar de forma permanente» y haga clic en «Vaciar» para confirmar la eliminación. Haga clic en «Salir» para volver a la pantalla principal de S3. Con el bucket todavía seleccionado, haga clic en «Eliminar», escriba (o pegue) el nombre del bucket y haga clic en «Eliminar bucket» para eliminarlo permanentemente.
Vaya al servicio «Secrets Manager» y haga clic en el secreto creado en el paso 4. Haga clic en el botón «Acciones», luego en «Eliminar dato confidencial». Establezca el «período de espera» en 7 días y haga clic en «Programar eliminación». Los secretos de Secrets Manager no se pueden eliminar inmediatamente y requieren que la eliminación se programe con al menos 7 días de antelación, tiempo durante el cual otras aplicaciones no pueden acceder al secreto.
Finalmente, vaya a CloudFormation Console, seleccione el stack que se creó en el paso 1 y haga clic en «Delete». Después de unos minutos, todos los recursos se eliminarán y el stack desaparecerá de la lista.
Es importante seguir el orden de los pasos correctamente para asegurarse de que todas las funciones se eliminen de su cuenta y no se sorprenderá con los costos en el futuro.
Conclusión
En este blog aprendemos cómo generar un informe JasperReport simple y ponerlo disponible para su descarga en formato PDF utilizando Lambda, API Gateway y otros servicios. Ahora puede modificar fácilmente la plantilla «.jrxml» y el código de función Java para crear informes que satisfagan sus necesidades particulares. El uso de una arquitectura sin servidor le permite pagar solo por los informes que realmente se generan y se ponen a disposición de sus clientes, sin tener que preocuparse por la administración del servidor.
Sobre el autor
Pedro Rates es arquitecto de soluciones en AWS y tiene experiencia en el desarrollo de aplicaciones web. Sirve a clientes empresariales, guiándolos a través de las mejores prácticas de la arquitectura de nube.