¿Qué aprenderá?

¿Qué hará?

¿Cuáles son los prerrequisitos?

Ejemplo DayTrader

En este tutorial también usaremos DayTrader como aplicación legado. A continuación, listamos las principales funcionalidades de DayTrader y lo invitamos a revisar el anexo A en donde presentamos una descripción y una captura de pantalla ilustrativa para cada una de ellas:

Mono2Micro

Mono2Micro es una herramienta que usa el poder de la Inteligencia Artificial (IA) para rearquitecturar aplicaciones monolíticas hechas en Java hacia microservicios en la tecnología Liberty de IBM. Liberty es un framework ligero de código abierto que permite crear microservicios en Java para la nube, su principal objetivo es crear código eficiente y de rápido despliegue. Esta herramienta rearquitectura el monolito siguiendo un principio de descomposición espacio-temporal en donde, a medida que se ejecutan los casos de uso de negocio, se colectan trazas y aplican algoritmos de clustering en las clases observadas en dichas trazas. Los resultados de los algoritmos de clustering son los módulos candidatos en los cuales se desagrega el monolito. En nuestro ejemplo de DayTrader algunos de los casos de uso de negocio son: login, registro, comprar una acción, vender una acción.

Para lograr la rearquitectura, Mono2Micro sigue el proceso que podemos ver en la gráfica y que describiremos a continuación:


Figure 1: Flujo de trabajo de Mono2Micro

Capturar trazas dinámicas

Este paso busca generar trazas del código que se está efectivamente corriendo a fin de identificar la cohesión entre clases directamente relacionadas a cada caso de uso de negocio. Para lograr esto, Mono2Micro incluye dentro de su framework un procesador que, dado un código en Java, agrega dentro del software de entrada (monolito) código que genera trazas con el formato que la herramienta necesita. Con este código agregado, se pone a correr el software y se comienzan a capturar las trazas que se usan como entrada para la herramienta. Pero, —¿cómo se identifican los casos de uso de negocio relacionados a esas trazas?—. El proceso es simple: antes de ejecutar un caso de uso, otra librería, llamada Flicker Logger, es usada para registrar la fecha y hora de inicio de un caso de uso, a este registro se le da un nombre que represente un caso de uso. Es un proceso manual y separado de la ejecución del código, cuyo objetivo, al finalizar, es tener la fecha, hora de inicio y fin de cada caso de estudio en un archivo de logs, que luego será usado como una de las entradas junto con las trazas, así podremos saber qué clases están relacionadas entre sí porque hacen parte de un mismo caso de uso.

Reducir trazas

Como los archivos de trazas pueden ser muy grandes, el segundo paso es la reducción de las trazas, esto permite disminuir el tiempo de procesamiento de los logs de casos de uso. Mono2Micro reduce las trazas de dos maneras: eliminando trazas repetidas y llamados redundantes que pueden deberse, por ejemplo, a ciclos en el código.

Computar relaciones directas e indirectas

El siguiente paso es procesar las trazas y computar las llamadas directas e indirectas entre clases. Una llamada es directa si y sólo si una clase A en un método ma, llama directamente un método mb en una clase B. Una llamada es indirecta si entre una clase A y una clase C existe un camino para llamar algún método en la clase C. Basado en ese cálculo de llamados directos e indirectos la herramienta es capaz de reconocer relaciones entre clases.

Remover clases utilitarias

En ocasiones los llamados entre clases incluyen llamados a clases utilitarias, por ejemplo, clases para leer archivos que vienen dentro del JDK de Java. Estas clases no aportan nada a la definición de particiones de los casos de uso de negocio. Por lo anterior, en este paso se eliminan del resultado de cómputo las llamadas directas e indirectas a clases utilitarias.

Determinar el tamaño de particiones y realizar agrupamientos

En este paso se analiza el resultado del paso anterior para saber el máximo número de particiones posibles. Una partición agrupa clases relacionadas directa o indirectamente entre sí.

Mono2Micro reduce el número de particiones basado en un algoritmo de clustering jerárquico. El algoritmo consiste en ir comparando particiones y agrupando en el mismo grupo si se cumple una función S. Esta función halla un valor de similitud entre dos particiones dadas y verifica que esté dentro de un umbral, si ese es el caso, se agrupan las particiones.

Generar recomendaciones

En este paso, Mono2Micro utiliza técnicas de inferencia de tipo para identificar dependencias entre los componentes de la aplicación, lo cual le permite entender cómo las clases de una aplicación interactúan entre sí y cómo pueden ser separadas en diferentes servicios. Una vez que se han identificado grupos de clases que pueden separarse en particiones, Mono2Micro genera recomendaciones sobre cómo separar la aplicación monolito en servicios independientes. Cabe señalar que estas recomendaciones son solo sugerencias, ya que los desarrolladores pueden ajustarlas según sus necesidades. En general, el paso de generación de recomendaciones es uno de los aspectos clave de Mono2Micro, ya que permite a los desarrolladores comenzar a visualizar cómo se puede separar una aplicación monolito en módulos funcionales y tomar decisiones informadas sobre cómo proceder con la refactorización.

El tutorial inicia clonando el repositorio de código de la aplicación DayTrader. Luego, usará Mono2Micro para agregar el código que generará las trazas de ejecución de DayTrader. Seguidamente, usará Flicker para generar logs de inicio y fin de los casos de uso de la aplicación y correrá el código para ejecutar los casos de uso y obtener las trazas. Con estas entradas, usará Mono2Micro para generar sugerencias de las particiones funcionales que componen un monolito. Cada uno de estos pasos se estructuran en secciones. Las secciones pueden tener asociados vídeos que muestran el paso a paso. Al principio de cada sección hay una anotación que aclara lo que se espera que el/la estudiante haya logrado al terminar la sección.

Hay dos entornos posibles para instalar Mono2Micro:

  1. Máquina virtual: es la máquina Ubuntu del curso la cual tiene los prerrequisitos que necesita Mono2Micro, a saber: Java, Docker y Apache Maven.
  2. Máquina personal: esta requiere una preparación que indicamos en la siguiente nota. Para algunas instrucciones estaremos indicando las variantes, dependiendo del sistema operativo. Sin embargo, les recomendamos que reflexionen sobre cómo cada instrucción se extrapola a su ambiente particular.

Una vez configurado el entorno de su preferencia puede instalar Mono2Micro. Para esto basta con acceder a la página del proyecto y solicitar una prueba de 90 días. Debemos dar clic en "Start your no-cost trial" y seguir los pasos.

La imagen muestra la landing page de Mono2Micro

El primer paso consiste en llenar un formulario con información de contacto. Luego de llenar toda la información, seremos redireccionados a la página de descarga.

La imagen muestra un formulario con campos que se han de llenar con información personal a fin de poder probar Mono2Micro

Debemos descargar Mono2Micro-CLI.zip y Mono2Micro-Example

Mono2Micro-CLI.zip contiene los scripts y librerías que nos ayudarán a utilizar Mono2Micro y conseguir analizar monolitos hechos en Java para poder migrarlos a una arquitectura destino.

El primer paso es instalar todos los componentes de Mono2Micro. Podemos incluir la carpeta en donde descomprimimos Mono2Micro-CLI.zip en una variable del PATH del sistema operativo. Esto permitirá correr los comandos directamente en el shell sin especificar la carpeta cada vez. En la máquina virtual se hace a través del comando:

export PATH=$PATH:/path/to/m2m-cli

Luego, para instalar Mono2Micro debemos ejecutar:

mono2micro install -c docker

Con esto vamos a tener las imágenes de Docker descargadas y listas para usar.

Usted deberá clonar el siguiente proyecto en el entorno de su elección:

https://github.com/SELF-Software-Evolution-Lab/com.uniandes.miso.daytrader.monolith

Enlace al video

Agregar trazas a DayTrader

Si usted está usando la máquina virtual, deberá ejecutar el siguiente comando:

docker run -e LICENSE=accept --rm -it -v /path/to/daytrader/parentfolder:/var/application ibmcom/mono2micro-bluejay /var/application/monolith

Donde "/path/to/daytrader/parentfolder" es la ruta a la carpeta en la que se encuentra el proyecto "com.uniandes.miso.daytrader.monolith", usted deberá reemplazarla por la ruta en donde clonó el proyecto. En la ruta "/var/application/monolith", "monolith" es el nombre del proyecto clonado "com.uniandes.miso.daytrader.monolith". Ejemplo de cómo queda el comando para la máquina virtual:

docker run -e LICENSE=accept --rm -it -v "C:\Workspaces":/var/application ibmcom/mono2micro-bluejay /var/application/com.uniandes.miso.daytrader.monolith

Este comando enriquece la aplicación DayTrader con el código que generará las trazas de logs, las cuales serán usadas por la IA para analizar el código fuente. Además, agrega los primeros archivos resultantes del análisis estático de Mono2Micro: "refTable.json" y "symTable.json". Estos archivos describen detalles y metadatos de las clases Java del proyecto, tales como:

Luego de ejecutar este comando tendremos en la ruta raíz de nuestro proyecto, el nuevo proyecto generado por Mono2Micro, cuya carpeta tendrá el sufijo "-mono2micro".

Ejecutar DayTrader

El código enriquecido será el que ejecutaremos para producir la información que Mono2Micro requiere para realizar el análisis. Para esto usted deberá ejecutar la aplicación como se indica a continuación.

En primer lugar, debe navegar, desde una terminal de la máquina, hasta la carpeta padre del proyecto generado por Mono2Micro en el paso anterior. En la máquina virtual se hace así:

cd /path/to/parentfolder

Y a fin de evitar problemas con los permisos de acceso es recomendable que ejecute el siguiente comando:

sudo chmod -R 777 monolith-mono2micro

Donde "monolith-mono2micro" es el nombre del directorio del proyecto (aquel con sufijo "-mono2micro").

Ahora, sitúese en el directorio del proyecto de la máquina virtual:

cd monolith-mono2micro

Y ejecute los siguientes comandos de Maven para instalar las dependencias y compilar la aplicación:

mvn clean install

El servidor de aplicaciones de OpenLiberty requiere de la variable de entorno WLP_USER_DIR, para hacer que la variable esté disponible en la terminal, ejecute el siguiente comando:

export WLP_USER_DIR=/path/to/monolith-mono2micro/daytrader-ee7-wlpcfg

Con esto ya es posible ejecutar la aplicación DayTrader en un servidor Liberty, para lo cual debe ejecutar el siguiente comando:

/path/to/monolith-mono2micro/daytrader-ee7/target/liberty/wlp/bin/server start daytrader7Sample

Valide que la aplicación está corriendo entrando a la siguiente ruta desde el explorador web de la máquina. Puede entrar a la aplicación utilizando las credenciales que aparecen por defecto.

http://localhost:9082/daytrader

Ahora explore la aplicación DayTrader para entender todas las funcionalidades que ésta tiene. Las funcionalidades de DayTrader están descritas en el Anexo A de este tutorial.

Ejecutar casos de uso

Mono2Micro usa información de negocio como entrada para analizar monolitos y sugerir cuáles son las particiones funcionales de la arquitectura legado. Para esto, el usuario de la herramienta que quiere migrar una aplicación, debe conocer el funcionamiento de la aplicación, agrupar funcionalidades en casos de uso y dar esa información como entrada a Mono2Micro.

Siga las instrucciones a continuación para indicar a Flicker el inicio y finalización de cada caso de uso.

En una terminal de la máquina ejecute los siguientes comandos:

cd path/to/mono2micro-cli/flicker
java -cp flicker-1.0.jar com.ibm.mono2micro.Flicker -no_ntp

Por cada caso de uso del anexo A escriba el nombre y de clic en enter. Usted es libre de colocar un nombre a cada caso de uso, pero debe ser significativo para el contexto que está ejecutando.

nombre-caso-de-uso

Realice todos los pasos correspondientes al caso de uso en la interfaz web de DayTrader. Por ejemplo, para el caso "registrar usuarios" los pasos son: llenar el formulario y presionar el botón "submit". Cuando termine los pasos, digite "STOP" en la consola donde está corriendo Flicker.

STOP
Exit

Flicker generará un archivo llamado "context_<unixdate>.json".

Enlace al video

Con los logs generados y los tiempos de inicio y fin de cada caso de uso, debemos crear una carpeta con todos los archivos de salida. Recomendamos que la carpeta sea llamada "application-data". Esta carpeta deberá tener tres subcarpetas:

Además, en la raíz de está carpeta, usted deberá crear un archivo "config.ini" con la siguiente configuración

[Global]
Logging = stderr
LoggingLevel = WARN

[LogProcessor]
RunlogDir = logs
ContextDir = contexts
TableDir = tables
ClassDiffFile = No

[AI]
MaxNumPartitions = 5

[Report]
ReportedGraphView = micro_detail_partition_by_business_logic

[Modify]
UserModifiedGraph = fixed-nodes.json
ModifiedGraphView = custom_view

Ahora que tenemos la carpeta creada, proceda a ejecutar el siguiente comando:

docker run -e LICENSE=accept --rm -it -v /path/to/application-data:/var/application ibmcom/mono2micro-aipl 

Donde "/path/to/application-data" representa la ruta a la carpeta que creó anteriormente.

Este comando generará una carpeta de salida mono2micro dentro de la carpeta "application-data", donde los archivos más importantes son:

"/path/to/defaultapplication/application-data/mono2micro/mono2micro-output/Oriole-Report.html"

"/path/to/m2m-example/application-data/mono2micro/mono2micro-output/oriole/final_graph.json"

Para visualizar las particiones resultantes del análisis, usaremos la GUI de Mono2Micro, para esto debemos ejecutar el siguiente comando:

docker run -d -e LICENSE=accept -p 3000:3000 --name=m2mgui ibmcom/mono2micro-ui

La GUI estará disponible en la siguiente URL:

http://localhost:3000

Al ir a la URL, se visualizará lo que se muestra a continuación:

La imagen muestra la vista de carga de Mono2Micro, donde se debe subir el final_graph.json resultante de procesar el monolito

Al dar clic en "Drag and drop or open file" cargue el archivo "final_graph.json" que contiene el conjunto completo de particiones sugeridas (en la sección anterior especificamos la ruta donde se encuentra este archivo):

La imagen muestra la lista de archivos disponible para carga en la vista de carga de Mono2Micro. Allí se ve que se encuentra listado final_graph.json

Como resultado de la carga del archivo observaremos tres visualizaciones en la interfaz de Mono2Micro: "Business Logic" (lógica de negocio), "Natural Seams" (similitud natural) y "Custom View" (de usuario). A continuación, explicaremos el propósito de cada visualización, ilustrando con DayTrader.

Enlace al video

Visualización por lógica de negocio (Business Logic)

Esta visualización se centra en agrupar las funcionalidades de la aplicación en diferentes particiones según su lógica de negocio. En este enfoque, se busca dividir la aplicación en unidades autónomas y cohesivas que se encarguen de realizar tareas específicas. Por ejemplo, si una aplicación tiene una funcionalidad para el manejo de pagos, se podría separar esta lógica en un módulo de Pagos. En general, gran parte de las decisiones de esta vista vienen de la ejecución de los casos de uso, con lo que Mono2Micro es capaz de reconocer qué partes del código fuente intervienen en cada uno de los casos de uso y así sugerir particiones por lógica de negocio.

La imagen muestra el grafo y las particiones generadas por Mono2Micro para la visualización de business logic

Visualización por similitud natural (Natural Seams)

Esta visualización se enfoca en encontrar puntos de separación natural dentro de la aplicación. Estos puntos pueden estar relacionados con diferentes factores, por ejemplo, la tecnología utilizada, las interfaces de usuario o simplemente las relaciones directas o indirectas dentro del código fuente.

En la captura que sigue se muestra la visualización "Natural Seams" para DayTrader la cual muestra 4 particiones, cada una agrupando elementos de la aplicación fuertemente dependientes. Dichas dependencias se descubren a partir de la traza de llamados entre clases. Además, también se observan relaciones entre las particiones 1, 2 y 3. Observando el detalle de cada partición podemos notar que la partición 1 es la más grande en términos del número de elementos y también es la que contiene los elementos "core" del negocio como Order, Quote, Holding, Account, etc. Si uno de los propósitos de la modernización de DayTrader fuera construir módulos más cohesivos entonces habría que rearquitecturar la partición 1.

La imagen muestra el grafo y las particiones generadas por Mono2Micro para la visualización de natural seams

Visualización definida por el usuario

Esta visualización se crea a partir ya sea de la "Business Logic" o de la "Natural Seams" y da la posibilidad de que los ingenieros rearquitecturen las particiones basados en sus prioridades. Por ejemplo, crear una sola partición de front-end y varias de back-end favoreciendo así atributos como la mantenibilidad y la escalabilidad.

Además del grafo, por cada visualización se puede obtener una tabla que lista los artefactos de software y a qué partición pertenecen.

Este tutorial le permitió usar Mono2Micro como herramienta para analizar el código legado de un monolito en Java y obtener como resultado visualizaciones de los módulos candidatos en los que se puede desagregar el legado.

Versión 1.0

Kevin Sánchez, Kelly Garcés

Autores

Miguel Peña, David Valderrama

Revisores

Versión 2.0

Kevin Sánchez, Carlos Castiblanco

Autores

Kelly Garcés

Revisores

Configuración

Esta funcionalidad permite inicializar la base de datos de DayTrader con datos de prueba. Es aconsejable ejecutar "Reset DayTrader" para iniciar con una copia limpia de la aplicación, después de cada uso.

La opción de "Configure DayTrader run-time parameters" permite definir el número de usuarios y "quotes" que se van a inicializar. Usted deberá ejecutar" (Re)-create DayTrader Database Tables and Indexes" para crear o recrear la base de datos y consecuentemente "(Re)-populate DayTrader Database" para crear los datos de prueba de la aplicación parametrizados en "Configure DayTrader run-time". Finalmente, está "Test DayTrader Scenario" cuya descripción se encuentra en la captura que sigue.

La imagen muestra el panel de configuración de DayTrader

Registro de usuarios

Registrar nuevos usuarios. Llene los datos y de clic en "Submit registration"

La imagen muestra el formulario de registro de DayTrader

Login

Haga login de un usuario colocando el usuario y la contraseña. DayTrader carga un primer usuario por defecto "uid:0", el cual puede ser usado por Ud. para navegar la app. También, puede usar las credenciales de un usuario nuevo registrado por Ud.

La imagen muestra la función de inicio de sesión de DayTrader

Ver cuenta/Ver y actualizar perfil

Al dar clic en "Account" es posible ver el perfil del usuario, al igual que actualizar la información de dicho usuario.

La imagen muestra la función de datos de la cuenta en DayTrader

Ver portafolio

Al hacer clic en Portfolio, se pueden ver los Holdings del usuario. Desde esta vista es posible vender un Holding dando clic en sell.

La imagen muestra la función de portafolio de DayTrader. Allí se muestra el listado de holdings de la cuenta

La imagen muestra la continuación de la lista de holdings de una cuenta de DayTrader

Vender acciones

Para vender de clic en el enlace sell de alguno de los holdings del usuario.

La imagen muestra la función de portafolio de DayTrader. Allí se muestra el listado de holdings de la cuenta

Ver cotizaciones y comprar acciones

En la pestaña de Quotes/Trade es posible visualizar los quotes disponibles para hacer trade, al comprar quotes dando clic en el botón Buy.