viernes, 22 de octubre de 2010

Ver un PC virtual con VMWare Player desde la red

Hoy ha sido un día un interesante de trabajo para mi compañero Miguel Ángel y para mí. Estamos preparando un sistema de integración continua para nuestro proyecto y nos habíamos decidido por probar la solución de TeamCity, la cual ofrece una versión gratuita. La idea era montar este servicio sobre una unidad virtual en uno de los ordenadores de la red para que el resto del equipo tuviese acceso también.

Creamos la unidad virtual con VMWare Player v3.1.2 con Windows 7 Profesional e instalamos TeamCity sin complicaciones. La nueva unidad virtual puede ver sin problemas el resto de los ordenadores de la red así que configuramos TeamCity para que se conecte a los repositorios de código fuente. Todo perfecto… hasta aquí.

El problema

Si como he dicho antes la unidad virtual podía ver los ordenadores de la red, no era lo mismo al revés. Nadie, ni tan siquiera el host que albergaba a la unidad virtual era capaz de ver al equipo, y por tanto, acceder al servicio.

Buscamos por Internet suponiendo que este problema sería bastante común y que fácilmente encontraríamos la manera de configurar el sistema para solucionarlo. El caso es que no es así, y que además, la manera de solucionarlo es bastante… “truqui del almendruqui”.

Buscando la solución

Lo primero que debemos hacer es configurar la unidad virtual con configuración de red NAT como se muestra en la imagen:

clip_image002

Con esto hacemos que la unidad virtual comparta la misma IP que nuestro equipo host. Pero atención, debemos tener en cuenta que cuando instalamos VMware Player, automáticamente te instala un par de adaptadores de red: VMnet1 y VMnet2. Puedes verlo haciendo una llamada a ipconfig desde la consola:

clip_image003

Para hacer que la unidad virtual utilice de manera correcta el adaptador el adaptador, en nuestro caso VMnet8, necesitamos usar la herramienta de VMware: Virtual Network Editor.

Ya te puedes hinchar de buscar que no la vas a encontrar. Parece ser que no viene con la distribución gratuita de VMware Player. ¿O sí?

Conseguir Virtual Network Monitor

Por lo visto, a los chicos de VMware se les ha ocurrido una curiosa manera de “darte” esta aplicación, pero como si no existiera. En realidad la tienen oculta dentro del fichero de instalación. Para conseguirla tienes que seguir estos pasos:

1. Extrae todo el contenido del instalador mediante la llamada:
c:\> VMware-player-3.1.2.<versión>.exe /e vmware_temp

2. Dentro de la carpeta vmware_temp encontrarás un fichero network.cab. Descomprimelo con WinRAR o 7zip y dentro encontrarás el ejecutable que buscas: vmnetcfg.exe

3. Como este ejecutable tiene muchas dependencias con otras librerías, es aconsejable copiarlo a la carpeta donde esté instalado VMware Player.

4. Listo para configurar.

Configuración con Virtual Network Monitor

Una vez arranquemos la herramienta, realizará una búsqueda de todos los adaptadores de redes virtuales que se encuentren en el PC host. Entre ellos encontrará activados VMnet1 y VMnet8. Nosotros nos centramos en VMnet8. El cual configuramos de la siguiente manera:

clip_image005

Debemos asegurarnos que también esté configurado como NAT y que la IP y la máscara de subred corresponden con lo mostrado en la configuración que muestra el host con el ipconfig que le hicimos en VMnet8.

Con esto ya hemos conseguido configurar el adaptador de red que está asociado a nuestra unidad virtual.

Dado que desde fuera del host, no se tiene acceso a esa subred, y por tanto a la unidad virtual, debemos configurar el NAT para que el host haga de puente entre la red y la unidad virtual. Para ello, asociamos un puerto del host con un puerto de la unidad virtual.

Sabiendo que TeamCity lo que expone es un servicio web y por tanto se accede usando el navegador, configuramos el puerto 8080 del host para que se correspondiera con el puerto 80 de la unidad virtual:clip_image006

Es interesante destacar que hay que hacerlo tanto para el protocolo TCP y UDP, sino, no funciona.

Y listo. Cualquier ordenador de la red que acceda desde el navegador a la dirección 192.168.14.248:8080, realmente está accediendo a la subred privada 172.16.37.128:80

A continuación la configuración de red de la unidad virtual:

clip_image008

domingo, 3 de octubre de 2010

El patrón Modelo-Vista-Presentador (MVP) a examen

Desde hace tiempo llevo enfrentándome con diversos patrones de diseño cuyo objetivo principal es el de separar la interfaz de usuario de la lógica de las aplicaciones. Desde mis años de estudiante universitario con Smalltalk y el patrón Modelo-Vista-Controlador (MVC), hasta MVVM con WPF, pasando por MVP, MP y sus variaciones.

Cada vez que he tenido que me embarcaba a usar uno de estos patrones de diseño me encontraba con la misma curva de aprendizaje. Un concepto bastante sencillo pero que ante ciertos escenarios que encontraba en proyectos reales uno no sabe exactamente qué solución tomar.

En esta entrada quiero centrarme en el patrón de diseño Modelo-Vista-Presentador (MVP), pero yendo más allá de la descripción académica de este patrón y enfocándome en cómo puede ser aplicado en aplicaciones reales.

Como he comentado antes, MVP es otro patrón de diseño que tiene como objetivo separar la interfaz de usuario de la lógica de las aplicaciones.

Básicamente este patrón consiste en 3 componentes:

  • La vista. Compuesta de las ventanas y controles que forman la interfaz de usuario de la aplicación.
  • El modelo. Que es donde se lleva a cabo toda la lógica de negocio.
  • El presentador. Escucha los eventos que se producen en la vista y ejecuta las acciones necesarias a través del modelo. Además puede tener acceso a las vistas a través de las interfaces que la vista debe implementar.

image

El concepto de este patrón es bastante sencillo. Por un lado tengo la vista, que se encarga de mostrar la información al usuario y de interactuar con él para hacer ciertas operaciones. Por otro lado, tenemos el modelo que, ignorante de cómo la información es mostrada al usuario, realiza toda la lógica de las aplicaciones usando las entidades del dominio. Y por último tenemos al presentador que es el que “presenta” a ambos actores sin que haya ningún tipo de dependencia entre ellos.

El propósito del presentador tal y como se ha definido en este patrón no establece de manera clara el grado de control que este puede hacer de la vista.

Dependiendo de este grado de control podemos encontrarnos variaciones en la manera de ver MVP. De hecho, algunas de ellas, dejan de ser MVP para convertirse en MVC, por lo cual debemos tener cuidado.

MVP como Controlador Supervisado

Por un lado, podemos tener un presentador que no gestione la forma en que la información es mostrada en la vista. Es la vista quien define la lógica de cómo la información es formateada y mostrada en la pantalla a partir de los controles que contiene. En este caso, el presentador únicamente los casos más complejos para facilitar el trabajo de la vista. Martin Fowler llama a esta variación Controlador Supervisado.

image

Cuando la vista recibe algún evento de ratón o teclado por parte del usuario, delega el control del evento en el presentador. Este puede realizar ciertas operaciones relacionadas con la vista como el control del estado de los controles y después realizar la llamada a algún comando en el modelo que realice la operación requerida por el usuario. El modelo realiza las operaciones pudiendo realizar cambios en su estado generando el evento correspondiente, el cual es manejado por la vista para actualizar los controles de la pantalla.

Hay que tener en cuenta de que el hecho de que la vista pueda hacer referencia al modelo nos da como resultado un diagrama muy parecido al de MVC. Aunque este enfoque nos permita el uso de técnicas de Data Binding. Con lo cual la cantidad de código que la vista y presentador necesitan, se disminuye.

Este enfoque nos va a permitir el uso de técnicas de Data Binding sobre el modelo. Por tanto, la cantidad de líneas de código fuente en la vista y el presentador disminuyen. Si nos fijamos en el diagrama, este es similar al de MVC por lo que hay que tener mucho cuidado en no caer en un cambio de patrón.

MVP como Vista Pasiva

Por otro lado, podemos hacer que el presentador gestione totalmente cómo la información se muestra en la vista. Es decir, tenemos una vista "tonta", sin ningún tipo de lógica, cuya única función es la de mostrar la información que se le pasa a través de la interfaz de la vista. Martin Fowler llama a esta variación Vista Pasiva.

image

En este caso, cuando un usuario realiza alguna operación sobre la interfaz de usuario, la vista delega los eventos sobre el presentador. Este realizará algún cambio sobre la vista para indicar el cambio de estado y hará las llamadas a los comandos sobre el modelo para llevar a cabo la operación requerida por el usuario. Cuando el modelo provoque cambios en su estado, estos serán recogidos por el presentador (al contrario que en el controlador supervisado, que era la vista quien atendía a estos cambios de estado en el modelo), el cual pedirá al modelo los cambios realizados para luego actualizar la vista acorde a los cambios recibidos.

Ejemplo

Supongamos el siguiente ejemplo: Un programa que para una fecha que le introduzcamos, te diga si es pasado, futuro o la fecha del día actual.

image

Cuando el usuario introduce la fecha y pulsa el botón OK, la vista delega el evento de pulsación de botón sobre el presentador. El presentador toma la fecha introducida del cuadro de texto y valida que el contenido tiene el formato de fecha correcto.

Nota: He obviado la posibilidad de usar un control específico para introducir fechas y así ver en qué lugar se pude hacer la validación de datos.

Si la fecha introducida no fuera correcta, el presentador comunicaría al usuario este hecho a través de la vista.

En caso de que la fecha fuese correcta, el presentador realizaría la operación de comprobar la fecha usando el modelo. Al recibir el resultado de la operación, el presentador mostraría el resultado a través de la vista. Por ejemplo, modificando el texto de la etiqueta con el resultado.

En el siguiente diagrama vemos la secuencia de llamadas realizada para el caso de Vista Pasiva:

image

En caso de usar la variación de Controlador Supervisado, supondría que la vista toma el resultado directamente del modelo y que además, la vista define la lógica de cómo el resultado se muestra en la pantalla. En el caso de que la validación de la fecha fallara, el presentador podría, por ejemplo, enviar una excepción hacia la vista que al capturarla decidiría como se mostraría al usuario.

Actualización: 
He creado en Codeplex un proyecto que hace uso de este patrón. Se trata de un sencillo ejemplo de máquina tragaperras sobre Windows Forms. El enlace al proyecto es este.