Nuevo proyecto: java, micro-servicios y entrega continua

Esta semana empecé a trabajar en un nuevo proyecto. Se trata de una aplicación que una empresa desarrolló para uso interno hace ya varios años y que ahora quiere”productizarla” para ofrecerla a terceros y montar un esquema de Software As A Service. Es ahí donde entro yo para dar una mano en “la productización” colaborando en cuestiones de refactoring de arquitectura, tareas de automatización, monitoreo y ajustes en el proceso de desarrollo.

La aplicación nació como un monolito Grails que fue evolucionando a lo largo de los años incorporando nuevas funcionalidades, en este momento está corriendo sobre Grails 2.5. Recientemente se decidió pasar a una arquitectura de micro-servicios construidos con Spring Boot sobre Java 8.

Más allá de las cuestiones técnicas, hay algunos issues a nivel de dinámica de trabajo. Si bien el equipo trabaja en un esquema tipo Scrum, el testing de la aplicación lo realiza otro sector de la empresa y es testing manual. Esto genera importantes delays en el release, ya que muchas veces se llega al final de la iteración y no se puede pasar a producción pues hay funcionalidades no testeadas.

Continuará…

Un caso robusto de integración contínua en Java

En el proyecto en el que he estado trabajando los últimos meses tenemos montado un proceso de integración continua bastante completo en mi opinión, comparto aquí algunos detalles. Se trata de un proyecto Java, basado en Spring, Hibernate, Camel y algunos otros frameworks. A nivel de herramientas tenemos quality checks con PMD, pruebas unitarias y de aceptación con JUnit y pruebas de aceptación y carga con JMeter. Como herramienta de build usamos Maven, como servidor de integración continua usamos Jenkins y el código lo tenemos en Git (gitlab). Al mismo tiempo tenemos un ambiente de tests en la nube donde desplegamos nuestra aplicación periódicamente. También tenemos un ambiente de prueba en las oficinas del cliente, donde desplegamos nuestra aplicación al final de cada iteración. En el jenkins tenemos varios jobs:

  • integración continua: monitorea el branch develop y ante cada cambio compila, ejecuta las pruebas de JUnit (unitarias y de integración)
  • quality-check: se ejecuta a continuación del job de integración continua y caso_java_jenkins_2básicamente ejecuta análisis de código (pmd)
  • integración continua de branches: en algunos casos creamos feature-branches, para lo cual seguimos una convención de nombres y este job se encarga de ejecutar integración continua sobre estos branches. En general procuramos que estos branches no vivan más de 3 días.
  • inicialización: es el job que dispara el build pipeline, y como tal comienza por inicializar el ambiente de test. Se ejecuta periódicamente (varias veces al dia siempre que haya cambios en el repositorio)
  • deploy: son dos jobs que se encargan de desplegar las dos aplicaciones que forman parte de nuestro sistema.
  • pruebas de aceptación: ejecuta las pruebas de aceptación (codeadas con jmeter) luego de cada despliegue
  • pruebas de carga: ejecuta un conjunto de pruebas de carga. Este job lo ejecutamos manualmente al menos una vez por iteración para asegurarnos que los cambios realizados no haya impactado en la performance del sistema
  • generador de release: este job lo ejecutamos manualmente al final de cada iteración para generar un nuevo release lo cual implica: taggear el repo, generar y publicar los artefactos (wars y jars) y actualizar la versión en los archivos del proyecto (pom.xml)
  • generador de instalable: este job toma  los artefactos generados por el job de generación de release y los empaqueta junto con un grupo de scripts que luego se utilizarán para instalar  el sistema en los ambientes del cliente.

caso_java_jenkins

Desarrollador y facilitador, no way

Como ya comenté en un artículo anterior, desde hace un tiempo estoy trabajando en un proyecto Java, una tecnología que no domino plenamente.

El miércoles pasado participé de una retrospectiva de este proyecto que fue facilitada por Alan y que me dejó pensando un buen rato. Ocurre que durante la retrospectiva Alan hizo dos sugerencias puntuales que yo mismo he hecho a otros equipos en reiteradas ocasiones pero que curiosamente esta vez no las sugerí a mi propio equipo.

Todo el viaje de vuelta a casa me lo pasé analizando esta cuestión y finalmente llegué a una conclusión que me convenció: mi falta de pleno dominio de Java me obliga a poner demasiada energía en cuestiones técnicas, lo que me hace perder de vista algunas otras cuestiones.

Luego de pensarlo por un par de días y de consultarlo con algunos amigos me animo a arriesgar:

Para que un desarrollador pueda ocupar el rol de facilitador en su equipo es necesario que tenga un buen dominio de las cuestiones técnicas con las que debe trabajar cotidianamente.

(posiblemente esta afirmación no tenga aplicación universal, pero definitivamente aplica a mi)

El cambio tecnológico más duro de mi carrera

No fue en 2002 cuando pase de hacer sitios web en Php a trabajar con la incipiente (en aquel momento) tecnología .Net.

No fue cuando en 2005 cuando tuve que programar un web server con C++.

No fue en 2009 cuando hice mis primeras experiencias en plataformas Cloud. Ni tampoco cuando pasé de Subversion a Git.

No fue cuando en 2010 cuando me metí con Ruby.

No fue cuando a fines del año pasado volví a trabajar con Php.

Fue en este último mes y medio cuando pasé de trabajar en Ruby a trabajar en Java.

Venía acostumbrado a trabajar desde la terminal con rake, usando Sublime como herramienta de edición de código e Irb como espacio de experimentación. Sinceramente me sentía muy cómo

El pasaje al mundo Java me resultó durísimo. Si bien desde 2004 siempre he estado haciendo algunas cosillas en Java, la realidad es que eran cosas más bien pequeñas o bastante específicas. Pero ahora estoy trabajando en un proyecto de una complejidad bastante mayor en el cual se utilizan diversos frameworks y componentes de infraestructura.

Por un lado el lenguaje me resulta muy incómodo, tipado estático, chequeo de excepciones, ausencia de lambdas (Java7) y una pobre implementación de generics son algunas de las cuestiones que primero vienen a mi mente.

Por otro lado Java es posiblemente de las tecnologías más pesadas que he utilizado (si, incluso más pesado que C# con Visual Studio incluido). Mi maquina (4 GB de memoria y disco de estado sólido) sufre cada vez que intento correr las pruebas de integración o iniciar una sesión de depuración.

El Eclipse si bien es muy potente, es también muy pesado y encima el esquema de shortcuts que utiliza es totalmente distinto al de la mayoría de los otros IDEs.

En fin, aquí estoy, “curtiendome” con el todo el stack enterprise de Java e intentando aportar una mirada más amplia (y “no-java”) al equipo de proyecto.

 

 

Nuevo proyecto, full Java

Esta semana comencé a trabajar en un nuevo proyecto que va a requerir que me meta con Java en profundidad. El proyecto consiste en el desarrollo de lo que podríamos denominar un Middleware, básicamente una aplicación que permite integrar aplicaciones.

Equipo de 3 personas, iteraciones de 2 semanas, Jira, Slack, Git, Jenkins, Maven, Spring, Camel, Eclipse, JUnit, Mockito y algunas otras cosillas.

Continuará…

Primeros pasos con Cucumber-JVM

Hace poco más de dos meses estoy trabajando casi cotidianamente con Cucumber-JVM y como consecuencia de ello he aprendido muchísimo sobre dicha herramienta. Si bien ya tenía bastante experiencia con la implementación Cucumber-Ruby, resulta que la implementación Java tiene sus particularidades.

Para compartir lo que he ido aprendiendo he decidido grabar una serie de videos. He aquí el primero de ellos: Introducción a Cucumber-JVM, espero les resulte útil.