W. Libardo Pantoja Y.

Ejemplo de una arquitectura hexagonal

En el blog anterior se dieron las motivaciones que hay detras de una arquitectura hexagonal. Se hablo principlamente  que el corazon de una aplicacion deberia ser la Logica de Negocio, y su evolucion debe ser independiente de la tecnologia de acceso a datos.
Este blog se centra en dar un ejemplo claro que implemente la arquitectura hexagonal. Para ello se ha construido una aplicación en Netbeans de gestión de tareas diarias. Este ejemplo está basado en el blog Domain Driven Design Spring Boot Kata.
Primero se va explicar cómo está construido el ejemplo original y luego la versión que se ha escrito para el ambiente netbeans.

Ejemplo versión original

El ejemplo orginal, está implementado en el framework Spring Boot. Para abrirlo y por facilidad se recomienda instalar el entorno Spring Suite Tool for eclipse. La aplicación está conformado por tres proyectos independientes: Dominio, infraestructura y aplicación (ver Figura 1).
 /Blogs/EjemploArquitecturaHexagonal/EjemploArquitecturaHexagonal-SpringBoot.png
 Figura 1. Gestor de tareas en Spring Suit Tool: Dominio, infraestructura y aplicación.
  1. El primer proyecto llamado GetThingsDone-domain, contiene básicamente la lógica de negocio. Posee las  reglas de validación de las entradas de los usuarios; información obligatoria para una tarea, formato de campos, etc.,  valida los objetos de valor invariantes que ingresan al sistema contiene objetos de dominio. Los conceptos y las palabras comerciales tienen sus objetos en su código (lenguaje ubicuo). Ademas, posee los límites de las transacciones: gestionar las transacciones de la base de datos; decidir si los resultados de las acciones deben persistir o deshacerse.
  2. El segundo proyecto es GetThingsDone-infra que contiene la infraestructura de la aplicación, en este caso específico la gestión de persistencia de tareas (pero podrían ser muchas otras responsabilidades: enviar correo electrónico, SMS, notificaciones push, leer información de configuración, etc.).
  3. El tercer proyecto es GetThingsDone-app que es la capa de interfaz de usuario y contiene el artefacto main ejecutable. Expone los servicios en una API Rest.
Algo para rescatar es que el corazón es la capa de dominio, y es un proyecto simple e independiente, no tiene dependecias con las demás capas, ni siquiera con JPA.
Para ejecutar la aplicación, se da clic derecho en la aplicación de dominio / Run as /Spring Boot App. La aplicación no requiere configurar ni base de datos ni servidor de aplicacaciones. Corre sobre un servidor tomcat embebido en la apllicación y utiliza el motor de base base de datos H2 que crea la base de datos en el momento de ejecutar la aplicación. Por lo tanto, es una aplicación que requiere abrirla en el entorno de desarrollo y simplemente ejecutarla. En el blogo está en enlace al código fuente del repositorio git hub.
Para probar la aplicación se puede usar un cliente que invoque los servicios web. Se puede utilizar postman o un cliente por consola curl, tal como se muestra a continuación:
La URL de los endpoints URL es: http://localhost:8080/todos
Para crear una tarea se invoca:

curl -X POST \
  http://localhost:8080/todos/ \
  -H 'Content-Type: application/json' \
  -d '{
   "title":"plant a tree",
   "description" : "because green is pleasing",
   "dueDate": 1557847007
}'

Para listar:

curl -X GET \
  http://localhost:8080/todos \

... y se puede usar los métodos http: PUT, DELETE HTTP para gestionar las demás acciones.
La aplicación también tiene implementadas las respectivas pruebas unitarias de cada capa y componente.
 
La Figura 2 muestra cómo se ejecuta la API rest desde un cliente por consola:
 /Blogs/EjemploArquitecturaHexagonal/Todos-Consola.png
Figura 2. Ejecutando el servicio desde consola.
La Figura 3 muestra la misma ejecución desde postman:
 /Blogs/EjemploArquitecturaHexagonal/Todos-Postman.png
Figura 3. ejecutando la aplicación desde Postman

Ejemplo modificado y adaptado para Java EE en Netbeans.

Como aporte y ejercicio académico se ha sacado una versión del proyecto de tareas (Todos) para que se pueda ejecutar a Java EE, preferiblemente en Netbeans. Los aportes concretos son los siguientes:
  1. Se ha reescrito muchas partes del código para que se pueda ejecutar con Java EE sin la necesidad del Framework Spring Boot. Por ejemplo, la parte de inyección de dependencias fue adaptada.
  2. Se utiliza un servidor de aplicaciones Payara 4.1.2. en lugar de Apache Tomcat Embebido.
  3. Se utiliza una base de datos MySql en lugar de H2.
Una vez abierto el proyecto en Netbeans, se deben hacer los siguientes pasos:
  1. Instalar Payara 4.1.2 y agrearlo a los servidores de aplicaciones de Netbeans. Dejamos que el estudiante intente hacer este paso por su cuenta.
  2. Abrir la consola de administración de payara y crear el Pool y la fuente de datos JDBC.
  3. Se debe instalar Mariadb (o MySql). Luego se debe crear la base de datos llamada tareas.
 Para el paso 2, se debe ejecutar el servicio de Payara desde Netbeans, luego ir a la pestaña Services / Servers /Payara / View Domain Admin Consola. Se abrirá el navegador web con la consola de administración de Payara En ella se debe ir al nodo Resources / JDBC / y crear primero el Pool de Conexiones JDBC y la fuente de datos JDBC (Resources JDC). Para el primero, el pool se debe llamar tareasPool y debe tener las siguientes configuraciones y  propiedades:
 /Blogs/EjemploArquitecturaHexagonal/Pool-Configuracion.png
Figura 4. Configuración del Pool de conexiones llamado tareasPool
/Blogs/EjemploArquitecturaHexagonal/Pool-Propiedades.png
Figura 5. Propieades del Pool de conexiones (Nota: el password debe ir acorde a la contraseña de root que tenga cada máquina)
Para el Resources Jdbc se debe tener las siguientes configuraciones.
/Blogs/EjemploArquitecturaHexagonal/Resources-configuracion.png
 
Figura 6. Configuración del Resources JDBC
 
Para el paso 3, a continuación se coloca el script de la base de datos en Mariadb:
--
-- Base de datos: `tareas`
--
--
-- Estructura de tabla para la tabla `todo`
--

CREATE TABLE `todo` (
  `id` bigint(20) NOT NULL,
  `creation_date` datetime DEFAULT NULL,
  `description` varchar(255) DEFAULT NULL,
  `due_date` datetime DEFAULT NULL,
  `title` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


INSERT INTO `todo` (`id`, `creation_date`, `description`, `due_date`, `title`) VALUES
(3, '2020-07-26 19:56:41', 'because green is pleasing', '2020-07-07 11:49:56', 'plant a tree');


-- Indices de la tabla `todo`
--
ALTER TABLE `todo`
  ADD PRIMARY KEY (`id`);

-- AUTO_INCREMENT de la tabla `todo`
--
ALTER TABLE `todo`
  MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
Como se puede apreciar esta versión requiere configurar más pasos, pero la ventaja es que se aprende a configurar servicios y se entiende detalles de cómo funciona la aplicación. Finalmente, la Figura 7, muestra el código fuente en Netbeans. Se puede apreciar que hay tres proyectos tal cual el proyecto original.
/Blogs/EjemploArquitecturaHexagonal/Netbeans.png 
 
 Figura 7. Aplicación Todos en netbeans, versión para Java EE.
 
Se debe ejecutar el proyecto TareasPendientes-app y las pruebas se hacen desde consola o por medio de Postman. Queda en manos del estudiante estudiar y comprender el código fuente (debidamente documentado con fines de aprendizaje). También, para comprender cómo interactuan los distintos componentes de la aplicación, a continuación se han elaborado algunos diagramas UML.
 /Blogs/EjemploArquitecturaHexagonal/DiagramaClases.png
 Figura 8. Diagrama de clases de la aplicación
 /Blogs/EjemploArquitecturaHexagonal/DiagramaPaquetesGrl.png
Figura 8. Paquetes y sus dependencias
/Blogs/EjemploArquitecturaHexagonal/ReadTodo.png Figura 9. Diagrama de secuencia del caso de uso leer una tarea.
/Blogs/EjemploArquitecturaHexagonal/CreateTodo.png
 
Figura 10. Diagrama de secuencia del caso de uso crear una tarea.
Universidad del Cauca - Facultad de Ingeniería Electrónica y Telecomunicaciones - Dpto Sistemas