jueves, 29 de mayo de 2008

Continuous Integration

Si lo dice Fowler.... hay que creerle

"Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily - leading to multiple integrations per day. Each integration is verified by an automated build (including test) to detect integration errors as quickly as possible. Many teams find that this approach leads to significantly reduced integration problems and allows a team to develop cohesive software more rapidly. This article is a quick overview of Continuous Integration summarizing the technique and its current usage."
Martin Fowler


Les dejo el link al articulo de fowler
Si no le creen a Fowler, aca tienen la wikipedia....que dice lo que dice fowler


Existen varios CI servers que pueden integrarse al desarrollo de aplicaciones Java.
  • Continuum de Apache (eh.... ta bueno sep sep. Bastante facil de instalar. Open Source)
  • Cruise Control (Lo conozco como el mas antiguo y completo. Tiene una version para .NET. Open Source)
  • Dimensions Build de Serena (funciona con y para Serena. Por si se estan quedando pelados de luchar con Dimensions, este es el producto que poseen. Pago)


y les dejo un link sumamente interesante:
Matriz completisima y comparativa de diferentes productos de CI
Babeense :D

Saludos.

Revision de Codigo

Hoy en dia me encuentro escribiendo estandares y buenas practicas para la programacion en Java, y en algunos casos, para cualquier desarrollo que trate de ser dinamico (no digo agil, digo dinamico porque los diferencio en metodologia).

Creo que la revision de codigo es un fantasma empresarial al que muchas veces le han atribuido mas poder de resolucion de problemas del que tiene.
La revision de codigo automatica es el primer paso a una politica de desarrollo que termine en un Continuous Integration (voy a retomar este tema en otra entry) con buenas auditorias, de modo tal que el codigo se mejore continuamente y se modifique de una forma mas segura, llegando a produccion un codigo probado y lo mas estable posible, mitigando riesgos en ambientes productivos.

La idea que tengo ahora, es (en orden de prioridades):
  1. Revisar el formato del codigo... ok, eso ayuda a entender el codigo de la empresa siempre y cuando se determinen las reglas de nomenclatura mas importantes, el idioma del codigo, las entidades de negocio principales (para que este relacionado con el aspecto funcional y sea entendible) y archivos shipment y destinados al deploy.
  2. Corregir errores tipicos en el codigo estatico.
  3. Revisar de reglas de codigo de la empresa.
  4. Revisar y recomendar buenas practicas en el codigo (automaticamente) a modo de ir capacitando a los recursos.
  5. Crear un workspace comun a los diferentes proyectos y estandarizar los frameworks de desarrollo (maven).

Eso es lo que apunto en el primer paso. ya que creo que los pasos a Continuous Integration son:
  1. a- Repositorio comun, trabajo en equipo ordenado. b-Division clara de ambientes de desarrollo, prueba, preproduccion y produccion.
  2. Pruebas funcionales y regression tests
  3. Revisiones de codigo, estandarizaciones, convensions (si, hablo de poner maven y fijar un repositorio propio en lo posible donde controle los fwks y versiones que se pueden utilizar), buenas practicas
  4. Auditorias y automatizacion del proceso
  5. Stress test y automatizacion de pruebas funcionales
  6. Continuous Intregation (CI para los amigos :D).

No hablo de la integracion con todo el ciclo de SCM, ya que eso depende de las politicas de la empresa (si van a asociar cada cambio o si van a asociar un shipment por pedido, etc....). Ademas, el circuito de aprobacion de pedidos puede verse de forma separada, el ciclo de desarrollo como una caja negra y la salida (version, entregable, rollout, etc...) como el producto final del SCM.

  • 1 y 2 ya los tengo, me faltan los demas.
  • El 3 lo estoy haciendo.
  • Para el 4 necesito fuerza de trabajo (mas gente, aunque esto depende de cuanto desarrollo in-house tenga la empresa)
  • Para el 5, necesito suerte, porque voy a tener que trabajar muuuuucho para que las distintas areas me presten atencion y para que se definan las politicas de performance, atributos de calidad y se automaticen las pruebas funcionales :P
  • Para el 6, si tengo todo lo demas solo necesito equipamiento de infraestructura y gente que brinde el soporte.
  • Eso es lo que vengo calculando por ahora.


La idea, es que la mayor parte del trabajo sea automatica, por lo que no voy a ponerme a revisar cada regla que escribo, sino, que voy a buscar herramientas que se integren facilmente al desarrollo que lo hagan por mi.
Para .NET ya lo tenemos. Ahi todo bien, se integra con el IDE, se generan reportes y la auditoria de estos reportes.....bueno, todo bien.
Para Java aun no, asi que vamos a usar alguno de estos:

checkstyle
Se integra con eclipse y maven, esta ampliamente difundido, genera reportes en diferentes formatos. Es configurable desde el IDE, se pueden exportar e importar las reglas a traves de un XML, se pueden extender las reglas.
Limitacion: Evalua codigo estatico, sin tomar en cuenta euristicas de codigo en tiempo de ejecucion. Las reglas evaluan el contexto de una sola clase y no todo el programa.
PRO: Ya hay gente que lo esta usando y definio un conjunto de reglas.

PMD
Se integra con eclipse y maven, esta ampliamente difundido, genera reportes en diferentes formatos. Es configurable desde el IDE, se pueden exportar e importar las reglas, se pueden extender las reglas.
Limitaciones: remarla para que lo pongan y aprendan. Evalua codigo estatico, sin tomar en cuenta euristicas de codigo en tiempo de ejecucion.
PRO: Es igual que checkstyle pero permite que las reglas que se crean actuen en un contexto de ejecucion de programa y no de clase.

Otros...
Hay uno de Parasoft (tiene muy buenos productos, como Jtest que genera los casos de prueba funcional visualmente y de ahi podes obtener los Junit. Y trabaja con python :D) que aplica euristicas sobre el codigo estatico que evaluan como se comportara en tiempo de ejecucion.... Guaaauuuuu, pero es pago y es caro, ergo NOT.


Asi que, por el momento me encuentro escribiendo documentos, para al final llegar a la meta.
Paso a paso :D
Igual, esto tiene muuuuucho mas sentidos en compañias que tienen mucho desarrollo in-house y mas sentido para compañias productoras de aplicaciones.

Saludos.

lunes, 26 de mayo de 2008

Ruby

Ruby es un lenguaje de scripting dinamico bastante piola.
Se puede integrar con Java o .NET.
Viene pegando muy fuerte desde la salida de "Ruby on Rails", que permite la creacion de una aplicacion web de forma muy facil, rapida y divertida.

Les dejo un par de links interesantes para que vean:

Try Ruby!
http://tryruby.hobix.com/
El mejor tutorial que vi, veo y creo que vere en mucho tiempo. Es interactivo y muy, pero muy divertido :D

Un Eclipse para programar con Ruby:
http://rubyeclipse.sourceforge.net/

Ruby On Rails:
http://www.rubyonrails.org/
Aca tienen un par de screencast incluso, si se cansan de leer.

Saludos

domingo, 25 de mayo de 2008

Sistemas de Monitoreo

Aca dejo un link de una compañia (AKCP) que se encarga de hacer la integracion de NMS (Network Management Systems) y que se encargo de hacer una descripcion para cada sistema que soportan.

Es una buena referencia para tener en cuenta:
http://www.akcpinc.com/company/nms.htm

Yo use BigBrother, Tivoli y HP Open View.
En el trabajo actual, tambien estamos usando Control M de BMC:
http://www.bmc.com/products/proddocview/0,2832,19052_19429_23437_1521,00.html
http://en.wikipedia.org/wiki/CONTROL-M
Pero esto no es de monitoreo, sino de ejecucion remota (algo que tambien tiene Tivoli).
Es un producto muy completo en cuanto a que tiene puede disparar eventos ante la llegada de un mensaje a una cola, la invocacion de un web service, etc...

Con respecto a Java:
En la JVM puede habilitarse la opcion de monitoreo SNMP. http://java.sun.com/j2se/1.5.0/docs/guide/management/SNMP.html

APIS SNMP para java:
Java No tiene SNMP
Jakarta En su biblioteca de commons de red no tiene soporte para SNMP
SNMP4J Es extremadamente precaria la doc. Tanto que los ejemplos se encuentran en la mismas clases :P y deben ser vistos en la javadoc. Se basa en una biblioteca SNMP de C++
JSNMP Es una biblioteca Java... Paga :P. Algo que no es recomendable es comprar bibliotecas... Es preferible comprar productos. Comprar libs es raro, el soporte de las libs puede ser patetico, las veces que vi comprar libs terminaron en resultados caoticos en cuanto a utilizacion y soporte. Ergo... NO COMPRO libs.

Saludos.

Integrando .NET y Java

Como hacer que dos mundos diferentes se vean?

Esa es la pregunta que nos haciamos en mi nuevo trabajo.
Resulta que tenemos una aplicacion que tiene fuertemente encapsulada la logica de negocio y no puede desacoplarse.
El paso tipico seria poner un motor de reglas, un motor de BPM, de BPEL o algo para sacar la logica de ahi dentro y poder exponerla como servicio o en algun lugar normal de donde pueda consumir cualquier aplicacion (quizas con costo de performance, qos y tolerancia a fallos).
Resulta que no podemos hacer eso aun, por lo que requerimos copiar el codigo y hacerlo lo mas transportable y desacoplable a futuro posible. Estaria muy bueno poder hacer una biblioteca generica que represente una capa de negocio que se pueda utilizar en cualquier app, hecha en cualquier lenguaje. He aqui el problema... como integrar mundos diferentes? como integro Java y .NET si no puedo hacerlo con un servicio, un package de BD, un socket, una cola, ni un motor de reglas? Si tuviera que hacerlo con codigo como lo haria?

Al investigar descubrimos un par de cosas interesantes, aunque al final haremos una lib para Java y otra para .NET:

Integracion directa:
JNBridge
Las clases .NET se ven en Java, las clases Java se ven en .NET. Simple.
http://www.jnbridge.com/jnbphow.htm
Este es un producto pago.


Integracion por una 3ra tecnologia:
En estos casos, desde Java o .NET se pueden ver clases de un 3er lenguaje. En este caso lenguajes de scripting.
Desde el lenguaje de scripting (dependiendo del framework) se pueden ver las clases de Java o .NET.
Problema: debuggeo complicado, probables problemas en la integracion de las libs (en el manejo de memoria), codificacion antinatural :P

Python
Python for .NET
Jython

Ruby
Ruby para .NET . Hay varios interpretes. Esta es al direccion de un blog que habla al respecto Entry
JRuby

Groovy
Esta integrado en Java, pero no en .NET. Es que, esta pensado para Java
"An agile dynamic language for the Java Platform"
http://groovy.codehaus.org/

Javascript
Java soporta engines de interpretacion de javascript via rhino
Intuyo que .NET debe soportar VBScript, sino... bueno, capaz ni es util :P


Por framework que cargue los objetos:
Spring puede utilizar engines de interpretacion de lenguajes, al fin de que declarando que un bean esta hecho en ruby/python/groovy pueda crearse y utilizarse en codigo Java. Les dejo 2 formas:
Documentacion de spring:
http://static.springframework.org/spring/docs/2.0.x/reference/dynamic-language.html

Un ejemplo de un blog para hacerlo de otra forma, con una Ruby Bean Factory:
http://jroller.com/habuma/entry/spring_meet_ruby

Ademas de eso, Java 1.6 soporta engines para lenguajes de scripting:
http://java.sun.com/javase/6/docs/technotes/guides/scripting/index.html
La idea esta basada en el framework rhino

Pero Spring .NET y la VM de .NET todavia no soportan lenguajes dinamicos.


Espero que les sirva esta pequeña investigacion.
Saludos

viernes, 16 de mayo de 2008

Analisis disfuncional, parte 2

Logre convencerlos.... cosa rara

En el pasaje al nuevo repositorio se va a subir todo igual, versionar la version inicial y a partir de ahi se haran las operaciones.....
O sea, como les pedia...

Me empiezo a asustar.... nunca me habian dado bolilla. Puedo enviciarme :P

Saludos.

jueves, 15 de mayo de 2008

Analisis disfuncional

En sistemas, aun pensamos que todos los problemas se resuelven con programacion.
ERROR!

Sistemas de informacion implica definir procesos de conversion de datos a informacion pero no siempre llega a automatizarse a traves de un programa informatico.

Un error comun que ocurre en los analistas, es que cuando tienen una herramienta que resuelve un problema les parece infinitamente modificable para ajustar a otras necesidades similares.
Existen casos de sobreautomatizacion, donde generar un programa es 10000 veces mas complicado y problematico que definir un buen proceso manual.

Expongo algunos items de los que fui viendo

La pluma es mas poderosa que el click: No todo es automatizable, existen validaciones que solo se pueden dar manualmente.
La revision humana es factible de errores, los data entries tambien. Hay veces que los circuitos humanos bien definidos pueden funcionar de manera mas segura que un sistema y la revision por ojo humano no puede ser reemplazada por un sistema complicado pasible de ataques.
Ejemplo: en el caso de alta de nuevos usuarios en un sistema remoto, que no debe ser accesible por cualquiera y cuando se posee un centro de atencion, podriamos eliminar los workflows asociados al alta y crearlos via formularios y back-office (una persona que los da de alta), siempre que el volumen y la demanda sea acotada. No informaticemos todo de entrada.
Es asi como una compañia gano en tiempo de salida al mercado en su phonobanking y otra en numeros amigos... pero shhhh no digan nada jeje

Otra mas simple, cosas que se pueden hacer manualmente si se pregunta el costo beneficio

Herramienta Martillo: Cuando nuestra herramienta es un martillo, todo parece un clavo. No todo se ajusta a nuestro problema, algunas veces, tenemos que pensar mas alla de los sistemas (y mas alla aun de los sistemas existentes). Debemos pensar si es viable el esfuerzo de hacer un sistema.
Ejemplo: por algo que es poco usable y complicado de mantener....
El usuario quiere que se le automice el proceso de borrado de archivos basura en su maquina a traves de un conjunto de regla que definira mensualmente. El proceso de borrado se efectuara una vez al mes, la definicion de reglas se hara en un XML parseable y la cantidad de archivos mensuales a borrar son todos los que cumplan un filtro de nombre en un directorio.

Podriamos plantearnos si el usuario en vez de definirnos toooooodo esto no hace un schedule del sistema operativo o directamente lo borra el. Cuanto esfuerzo de analisis, desarrollo, versionado conlleva esto y cuanto beneficio aporta????? Seguramente luego de esto va a querer mas cosas, lo que lleva al siguiente punto:


Reingenieria infinita: Los programas no son infinitamente modificables, ya que terminarian en una reingenieria constante (hasta los chicles tienen limites)... y reingenieria es una palabra magica que soluciona todo lo que fue un caos, pero... al no corregir nunca la actitud se puede caer en infinitas reingenierias.

Otro problema tipico en la especificacion de requerimientos

Detalles tecnicos de diseño y desarrollo en los requerimientos: ok ok, puede pasar... pero, es un problema cuando llegan requerimientos del estilo: el usuario escribe un XML con el pedido a hacer y blablabla...
Por favor, escribanlo puro y que la gente tecnica decida como va a ser el formato. No lo atemos a la idea del cliente... especialmente si va a terminar realizandose con un programa o una interfaz que va a hacer la implementacion transparente.



Hoy escribi esto porque por enesima vez, por desconocimiento de las herramientas existentes, me choque con un requerimiento que como programador tuve decir que se puede hacer y como arquitecto dije que es en vano realizarlo y que va en contra de toda logica.
El requerimiento era modificar un script de shell de traspazo de repositorios (o sea, algo para un problema puntual y salir del paso) para que se adapte a un conjunto de reglas a definir sobre la reestructuracion de directorios, para hacer automaticamente y la primera vez que se sube ese proyecto al nuevo repo.
Estas reglas debian documentarse en un xml que seria parseable por el todavia simple script de shell. Estas reglas eran validadas por un circuito de UAT (user aceptance test).


Digo yo... los analistas.... no deberian decirle al usuario lo que le dije yo a ellos:

1- que suban las cosas como estan y hagan los cambios despues para que sea traceable dentro del mismo repo y comparable con el anterior (querian que se mantenga la misma revision aunque en la reestructuracion los paths cambien). No manchemos la pelota por favor.
2- shell script es para un problema puntual, esto ya es un programa que lee un pseudocodigo de reglas (es cualquiera :P)
3- si solo se va a hacer una sola vez, que lo reestructuren manualmente y no pierdan tiempo con XML's. Los clientes de repositorios pueden hacerlo
4- No digan XML, no saben como va a ser. Denme las reglas.
5- que no hagan un proceso de sistemas de una solucion puntual que puede resolverse con herramientas existentes --> no reinventen la rueda y lean la documentacion de las herramientas.


Esta tarea puede realizarse con clientes pesados que manejan filtros... pero al no conocer este tipo de herramientas, el usuario pidio informatizar y modificar una que existia....

Regla de oro conclusiva:

"When your only tool is a hammer, everything looks like a nail"

miércoles, 14 de mayo de 2008

Problemas al loguear la IP cliente

Hoy estamos corriendo detras de un tema que es obtener la IP cliente este en la topologia que este.
Necesitamos loguear los accesos y sacar estadisticas sobre estas ip's. Al estilo Apache, nosotros podemos tomar cualquier header HTTP y loguearlo en un access.log

En el caso de Oracle Web Cache, que actua de Proxy reverso, esta setea la ip cliente en un header HTTP llamado "
Client-IP" (que no encontre en el estandard HTTP 1.1). Este es nuestro reverse proxy interno.

En el caso del balanceador, el CISCO que tenemos JUSTO no tiene la funcionalidad de setear el header "X-Forwaded-for", asi que nos estamos queriendo matar. Adjunto un link de una pagina muy interesante sobre el tema:
http://lbdigest.com/2008/01/09/question-about-source-ip-addresses/

Algunos proxies de internet setean el X-Forwarded-for, otros dispositivos intermedios pueden setear otros headers (Como "NP-Client" o algo asi), pero el estandar es el X-Forwarded-for.

En el PEOR de los casos, y si la aplicacion es propia, lo unico que queda es que la ip del cliente venga como un parametro de aplicacion, por lo que nos veremos obligados a, si es HTTP, obtenerla a traves de un applet/server side javascript. Por javascript puro no hay forma de obtenerlo y VBScript esta atado a IE.
Adjunto un link al respecto. Como obtenerla en distintos lenguajes:
http://javascript.about.com/library/blip.htm
Una de las mas prolijas dentro de toda la desprolijidad es invocar a la JVM que esta en el browser:


<html>
<body>

<
script language="javascript">
var ip = java.net.InetAddress.getLocalHost().getHostAddress();
document.writeln('IP=="' + ip + '"');
script>
body>
html>

(los tags no estan cerrados por problemas de publicacion en el blog)