¿Qué aprenderá?
¿Qué hará?
¿Cuáles son los prerrequisitos?
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 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
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.
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.
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.
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.
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.
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:
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.
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.
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
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".
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.
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".
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:
Al ir a la URL, se visualizará lo que se muestra a continuación:
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):
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.
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.
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.
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.
Kevin Sánchez, Kelly Garcés | Autores |
Miguel Peña, David Valderrama | Revisores |
Kevin Sánchez, Carlos Castiblanco | Autores |
Kelly Garcés | Revisores |
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.
Registrar nuevos usuarios. Llene los datos y de clic en "Submit registration"
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.
Al dar clic en "Account" es posible ver el perfil del usuario, al igual que actualizar la información de dicho usuario.
Al hacer clic en Portfolio, se pueden ver los Holdings del usuario. Desde esta vista es posible vender un Holding dando clic en sell.
Para vender de clic en el enlace sell de alguno de los holdings del usuario.
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.