25 jul 2011

Comunicaciones unificadas, de que estamos hablando?

Ahhhh.... Unified Communications, ese tipo de palabritas que me es imposible resistir, de salir a buscar significados, propuestas, productos, en fin, deleitarse con toda esa parafernalia marketinera que nos haga sentir que ahora sí, tenemos a disposición la tecnología del futuro para entendernos.
Este es uno de esos términos tan ambiguos como prometedores y claro, hay que acercarse y ver de que se trata, de que va la cosa, y hoy más que nunca cuando esta más que claro que la eficiencia en las comunicaciones es vital para cualquier actividad productiva, bah, desde siempre para cualquier actividad diría yo, solo que ahora tenemos la pista libre, es más fácil buscarle otro sentido, unir esto con aquello y obtener algo que le de esa vuelta de tuerca que no imaginábamos.

Volviendo al termino tan vendedor de Comunicaciones Unificadas, no me voy a explayar sobre lo que es, no me gusta inventar, solo contar mis impresiones luego de una extensa lectura en paginas de productos, fabricantes y vendedores de humos varios.
Al trabajar en el desarrollo orientado a las comunicaciones VoIP los conceptos se vuelven familiares, pero se pierde un poco el foco, el de que se trata esto, y de como se puede mejorar.
Una constante que veo es la tendencia a integrar todas las vías de comunicación en un único punto central, una especie de hub de mails, chat, VoIP, fax.. y si me das tiempo te agrego capacidades de videoconferencia, SMS y una lata con una piola para hablar con el compañero de enfrente.
Amén de todo esto, a nuestra bandeja de entrada con esteroides podemos darle una patina social, otro buzzword de esos que me encantan, es el mismo planteo anterior solo que ahora le agregamos un botón de "me gusta", algo de Twitter o porque no Google+, total, mas vale que sobre a que falte, pero sobre esto me lo reservo para otra entrada :)

Wires Chaos...

Esto de unificadas, si bien se refiere a una especie de concentrador de diferentes vías de comunicación, o por lo menos así lo entienden no pocas empresas, surge de la necesidad de concentrar en algún punto toda esa parafernalia de chat, mail, llamadas telefónicas..., pero no basta, no es suficiente, para mi necesitamos continuar al próximo paso: volver transparente el como para ocuparnos del que, olvidarse de que se utilizo en el camino para establecer este contacto y ocuparnos de que es sobre lo que estamos tratando.
No estoy hablando de semántica, no me refiero a que la aplicación entienda sobre que trata el hilo de datos, me refiero a que el soporte de este hilo de información sea transparente, vital si, pero no condicione la comunicación, a ver, me explico, que tal si estoy chateando y tengo que adjuntar documentos, no debería ser la aplicación lo suficientemente capaz de proporcionarme esta alternativa sin tener que salir del chat para abrir el cliente de correo, no debería ver en mi timeline un SMS entrante en medio del hilo de mensajes?, son ejemplos simples, pero recién cosas de este tipo considero que pueden ser llamadas comunicaciones unificadas.

Claro que dicho así parece fácil, solo resucitemos un Google Wave y listo, comunicación + comunicación + comunicación con un plus de trabajo colaborativo, pero creo que va un poco mas allá, no solo saber como volver un recurso en compartido, algo que sea aplicable al mail, a los SMS, a un chat, a un loquesea, sino también capaz  de abstraerme incluso de la plataforma que  utilice, sea un smartphone, un pc u otro.
Por supuesto, algo tan abstracto no puede ser sencillo, un protocolo genérico , algo como BEEP tal vez?, XMPP recargado?, agrupar recursos según prestaciones, canales mixtos predefinidos con un input/output común?, mmmmmm, nada trivial, tampoco imposible, pero clave para abstraer un canal del tipo que sea y convertirlo en solo eso, un canal mas, solo otro recurso de los disponibles, y mientras lo digo lo pienso: 
la tecnología subyacente es lo de menos, basta que sea confiable, algo de que fiarse, otro paso hacia olvidarnos de ella, es mas, si un tipo de comunicación no esta disponible que el sistema utilice otro, que decida el mejor camino por mi, solo debo saberlo y decidir si me es relevante.

Obviamente se requiere algo que pueda mostrar coherentemente este panorama, algo que me ilustre "te llame y no contestabas así que te deje un mensaje, como no estas conectado te reenvío un mail y fijate vos" y me ayude a digerirlo, ni hablar ya de si tenemos que incluir documentación, con todo el marasmo de formatos y demás, tranquilamente toda una aplicación aparte solo para eso, en ese caso con mostrar los docs como un flujo asociado y observaciones de forma organizada creo que es mas que suficiente, la comunicación hoy día ya ni por asomo se limita solo a la voz, es un flujo de datos multiformato, no nos estanquemos en el VoIP, hablamos de comunicaciones, no de comunicaciones de tal tipo.

Cables in Zürich

Seguramente no menciono nada nuevo, es mas, quizás ya hay alguna aplicación que hace esto hace rato y no tengo el gusto, el resto de soluciones que por ahora solo se limitan a manejar estas vías aun así parten con ventaja, ya tienen disponibles estos canales de datos, ahora solo falta buscarle la forma de hacerlos pasar de protagonistas a mero soporte.

22 jul 2011

Mi opción de Speech Bubble

"La necesidad es la madre del ingenio" dicen, y que mejor que vivirlo uno mismo para comprobarlo.
Estaba en el trabajo realizando unas interfaces de usuario (perdón: GUI's) cuando vi que un texto de aviso podría llegar a quedar mucho mejor si en vez de un tosco marco colocaba el mismo dentro de una burbuja de diálogo.
Así que, manos a la obra me dije peeeero... luego de buscar un poco por aqui y por allá me encontre con soluciones demasiado complejas que si bien son muy vistosas me parecieron excesivas, ni hablar de las que utilizan jQuery.

Hubo que ponerle ganas y hacerlo uno mismo, así que buscándole la vuelta llegué a un código que para mi gusto esta bastante compacto y claro:

<div style="overflow:auto;width:50%;">
   <img src="tip_top.gif" style="float: right; margin-right: 10px;"/>
   <div style="border: solid 1px #CCC; margin-top: 6px; padding: 5px; background: #FFF;">

    contenido de prueba
    contenido de prueba
    contenido de prueba

   </div>
  </div>

Es casi sin estilos y solo algunos tags, de acuerdo que la burbuja en este caso solo señala hacia arriba pero
modificándolo un poco seguro se adapta a mas de una necesidad.
Lo primero es un div que actúa como contenedor de los demás elementos, aquí podemos definir el ancho que queramos, luego colocamos la imagen que marca el origen del diálogo y seguido otro div que sera el que defina el borde de nuestra burbuja.
Ahora lo interesante, al darle a la imagen un float: right; esta se coloca encima de nuestro segundo div, con un poco de margen en la misma y en este div de contenido podemos afinar posiciones, y listo, un diálogo súper sencillo.

Si se quiere posicionar la imagen con respecto al elemento que lo invoque un poco de javascript basta, solo tenemos que obtener su posición y ajustar el left y top del contenedor principal, lo probé en varias versiones de FF, Chrome, Opera, IE y Safari tanto en Linux como Windows y no tuve problemas, mas sencillo creo que difícil.




PD: adjunto la imagen del tip en este ejemplo para ahorrarles el trabajo, eso si, solo en borde gris :)

21 jul 2011

How to hire good Java developers?

Comparto unas líneas traídas desde Java.net, entiendo que no todo es fácilmente aplicable pero no deja de ser un punto de vista interesante independientemente del lenguaje que utilicemos.
Destaco el punto 2, que me gustaría ver mucho mas seguido en empresas de estas latitudes, de corolario un palito para los fanáticos de las "métodos ágiles":
How to hire good Java developers?
Just in case you are seriously looking for good Java developers, some hints:
  1. Raise the salary (no excuses).
  2. Offer learning as part of the job benefits (conferences, books, courses, etc).
  3. Allow your developers to take project decisions.
  4. Use modern Java technologies (Still using Java 1.4?)
  5. Give the developers some stability and carrier perspective, and don't try that in a bureaucratic way.
  6. Flexible working time and remote office should be available.
  7. Give the developers more than water and coffee.. how about fruits? cokes and other beverages? How much it costs for you to buy 1 coke per developer a day? If you think it is too much, please leave the market :)
  8. Don't try poor copies of Google and IBM ideas, these companies are just richer than yours. Be creative and honest with your developers.
Good luck :) Java market is dry, good developers are scarce.. it is time for smart managers to raise the salaries and catch the good ones, the rest can be shared by people reading Scrum and Kanban manuals.
Y ojalá no les toque como a mi que tuve que arreglar mi propia silla :(


15 jul 2011

Google DevFest 2010

Aunque ya paso un tiempo ahora que estoy evaluando ir al Google Developer Day de Buenos Aires traigo por aquí algunas fotos del DevFest del 2010, en el que tuve el gusto de poder participar en el mismo, como cualquiera vamos, ahi van:

Google DevFest 2010

14 jul 2011

Google Master Plan





Genial fotografia con las propuestas de los empleados de Google para dominar el mundo, me encanto "Reemplazar a Britney Spears con Google Generic Pop Singer" o esta "Contratar ingenieros de hardware" modificada por "Robar ingenieros de hardware de NVidia" , se puede pasar un buen rato recorriendola y seguro hechar unas risas

Enlace: GoogleMasterPlanEN

20 jun 2011

Rotar un gif

Hay ocasiones que las cosas simples se complican un poco, claro, con paciencia y saliva todo se puede, pero a veces simplemente no vale la pena el esfuerzo, mejor dejarlo y seguir con otra cosa,si, es verdad, esta introduccion suena un poco dramatica pero la escribo en el preciso momento en que la frustracion, el desencanto, la rabia y por poco la locura se apoderan de mi ser: estoy tratando de rotar un gif en Kubuntu.

Parece chiste, pero quiero hacer una burbuja de dialogo, simplemente eso, pero la imagen de la flecha que señala el origen de la burbuja apunta hacia abajo, y yo la quiero hacia arriba, bien, simple en principio, o eso al menos creia yo.

Bien, veamos.., doble click... trato de editarla con Eye of GNOME 2.30.0, predeterminado (vengo de Gnome) y tiene los botones de rotar, simple!, roto y salvo... pero mmmmmm, error: "Formato de archivo desconocido o no permitido", rayos, a ver que mas tengo.

Abrir con Gwenview 2.4.3, ok, tiene los comandos de rotar, bien, roto a la derecha dos veces y salvo, pero ohoh!:
"Gwenview no puede guardar imágenes en formato «gif».", pero caracoles!, que raro, sera porque el formato no es libre o algo asi?
(offtopic, busco algo de info al respecto: segun Wikipedia "El 20 de junio de 2003 expiró en Estados Unidos la patente por el algoritmo LZW" que supongo usaria el formato GIF), en fin, que se yo, no pasa nada, la bateria de herramientas Linux a mi rescate.

Probemos con F-Spot 0.6.1.5, a ver que tal, editar > rotar a la derecha..., ups!!!: "Error al rotar la foto. Se recibio el error 'No se puede rotar este tipo de foto'", caramba caramba, la puta que lo pario con la dichosa imagencita.

Mmmmm, Okular? nones, es para PDF's, que hace ahi esa opcion?, a ver que mas tengo...

Sigo con Gimp, este esta poderoso, tiene que andar, veamos.... tiene mas comandos que una central nuclear: Archivo: no..., Editar no...,Seleccionar no..., Ver tampoco..., me estoy calentando... aca! Imagen > transformar > Rotar 180º, ja! pan comido.

Salvo y listo, al fin, a ver que tal quedo, OMFG!!, me cambio el fondo de la imagen, ahora se ven bloques grises y blancos de fondo, NOOOOO!!! LRPMQLP!!, maldita maquina, QUIERO ROTAR UN GIFFFFF!!!!, uffffffff!!!!

Paz! paz!, me voy a VirtualBox a abrir un Windows XP, me niego a instalar nada para esta tonteria, espero que uds tengan mas suerte.

Evitando SOP en GWT

Cuando desarrollamos aplicaciones web una de las tares mas básicas es la comunicación cliente servidor, y si bien GWT nos proporciona diferentes mecanismos (RPC, JSONP, etc) , uno de los mas habituales es la realización de peticiones HTTP al servidor.
Para esto se nos proporciona la clase HTTP cliente mediante la cual creamos y recibimos requests, siempre bajo las restricciones que impone la política de SOP (same origin policy) de los navegadores, que evita que el código cliente interactue con recursos de otros dominios previniendo potenciales problemas de seguridad.
Por otro lado, una de las formas mas prácticas de desarrollar en GWT es el llamado modo desarrollo, en el cual las aplicaciones corren sobre la máquina virtual de Java, pero quedamos restringuidos a realizar peticiones HTTP al dominio en el cual estamos ejecutando, del tipo "http://127.0.0.1:8888/MyApp.html?gwt.codesvr=127.0.0.1:9997".
Dicho esto nada mas cómodo que trabajar en modo desarrollo y realizar desde ahí las consultas al server, pero lamentablemente estos dos panoramas son totalmente incompatibles, quizás podríamos crear resultados de retorno simulados para las peticiones, también compilar todo cada tanto para verificar que todo funciona como esperamos, pero aun así cualquiera de las dos opciones es bastante impráctica, sobre todo compilar que ya de por si se lleva su tiempo, otra posible solución es cambiar todo esto por el uso de JSONP, pero no es lo que queremos, eso es solo otro hack al navegador, yo quiero Modo Desarrollo mas peticiones HTTP.

Leyendo precisamente en Wikipedia sobre SOP, encontré un enlace a una técnica un poco desconocida llamada CORS (Cross-Origin Resource Sharing) la cual habilita la posibilidad de realizar peticiones evitando el SOP de los navegadores, y claro, vi la luz al final del tunel.
Básicamente se trata de agregarle a la respuesta del servidor una serie de cabeceras que especifiquen el uso de esta técnica, soportada por varios navegadores modernos (ok, ok,  solo probé en Chrome y FF4, si alguien desarrolla con otro browser largo de aquí).

Para ver como funciona, realizaremos una aplicación de prueba con GWT y Python, recuerden que el uso de esta técnica es solo para desarrollo, nunca para codigo en produccion.
Este metodo fue probado con Python sobre WSGI y PHP, los navegadores son Firefox 4.0 y Chrome 6.0.472.63 sobre una caja Kubuntu 10.04.2 LTS.

Primero, abrimos Eclipse y realizamos un nuevo proyecto GWT, vacío, asi observamos bien el funcionamiento de esta técnica, luego creamos una petición HTTP (recordar de agregar al archivo XML del módulo la linea  <inherits name="com.google.gwt.http.HTTP" />) y la apuntamos a un dominio diferente al que corremos la aplicación, quedando de tal manera:


package cors.test.client;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.http.client.URL;
import com.google.gwt.user.client.Window;
/**
* Entry point classes define onModuleLoad().
*/
public class CORS_test implements EntryPoint {
 public void onModuleLoad() {
  
  String url = "http://localhost/CORS_test.wsgi";
  RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, URL.encode(url));
  
  try{
   Request request = builder.sendRequest(null, new RequestCallback() {
    
    @Override
    public void onResponseReceived(Request request, Response response) {
     
     if(200 == response.getStatusCode()){
      Window.alert(response.getText());
     }
     else{
      // handle the error
      Window.alert("failed petition");
     }
    }
    
    @Override
    public void onError(Request request, Throwable exception) {
     Window.alert("CORS... sure");
    }
   });
   
  }
  catch(RequestException e){
   Window.alert("Couldn't connect to server");
  }
  
 }
}

Luego, creamos el archivo de respondera a la petición, en este caso CORS_test.wsgi y lo colocamos en nuestro localhost:

def application(environ, start_response):
    status = '200 OK'
    response_headers = [('Content-type','text/plain')]
    start_response(status, response_headers)
    return ['Hello world from Python!']

apuntamos nuestro navegador a http://localhost/CORS_test.wsgi y debemos ver el mensaje "Hello world from Python!"
Ahora, corremos nuestra aplicación GWT en modo desarrollo, recibimos el siguiente mensaje: "failed petition", efectivamente SOP nos esta bloqueando las peticiones, por lo que agregamos las siguientes cabeceras en la respuesta:

# CORS_test.wsgi

def application(environ, start_response):
    status = '200 OK'
    response_headers = [
        ('Content-type','text/plain'),
        ('Access-Control-Allow-Origin','http://127.0.0.1:8888'),
        ('Access-Control-Allow-Methods','GET, POST')
    ]
    start_response(status, response_headers)
    return ['Hello world from Python!']

y probamos nuevamente, obteniendo el mensaje: "Hello world from Python!"
Fácil verdad, lo importante es que la cabecera "Access-Control-Allow-Origin" especifique nuestro dominio, en este caso "127.0.0.1:8888", aunque también podríamos haber colocado *  e igual funcionaría, ahora toca en nuestro querido PHP, recordemos cambiar el valor de la URL por: String url = "http://localhost/CORS_test.php".

# CORS_test.php

<?php

header("Content-type:text/plain");
header("Access-Control-Allow-Origin:http://127.0.0.1:8888");
header("Access-Control-Allow-Methods:GET, POST");
echo "Hello world! from PHP";

?>

cuidado con los espacios en blanco de la etiqueta header, pueden hacer que la aplicación falle, ahora al correrlo veremos el mensaje: "Hello world! from PHP".
Bueno, esta es la técnica básica, los invito a leer la  especificación  , y ahora si: podemos volver a desarrollar dignamente.