Probando módulos de NancyFx

En el artículo anterior de la serie de NancyFx hablábamos de diferentes tipos de respuesta así como el uso de plantillas en la plataforma. En este artículo veremos cómo crear pruebas unitarias para asegurarnos que nuestros módulos funcionan correctamente.

Creando nuestro primer test

Desde la documentación de Nancy se recomienda usar un proyecto diferente (es decir, un ensamblado diferente) para nuestros tests, ya que los módulos se descubren de manera automática por el “bootstrapper”. Una vez creado nuestro proyecto, necesitamos agregar las siguientes referencias, via nuget o de manera manual:

  • NUnit (o XUnit, o el framework que deseemos)
  • Nancy
  • Nancy.Testing

Una vez tenemos las referencias, podemos crear nuestro primer test (que tiene el original nombre de RoutesTest.cs). Dicho test estará dividido en tres partes:

  • Arrange: Toda la preparación necesaria para poder llevar a cabo el test
  • Act: La ejecución de nuestro test
  • Assert: La fase de comprobación de los resultados
[Test ()]
public void TestPut ()
{
        //Arrange
	var bootstrapper = new DefaultNancyBootstrapper();
	var browser = new Browser(bootstrapper);

        //Act
	var result = browser.Put("/routes", with => {
		with.HttpRequest();
	});

        //Assert
	Assert.AreEqual (HttpStatusCode.OK, result.StatusCode);
	Assert.AreEqual ("Response with Put\n", result.Body.AsString());
}

Qué hace el test?

  • Arrange: Para este test el primer paso es crear nuestro Bootstrapper que descubrirá los módulos existentes, seguido de un Browser con el que simularemos las llamadas a nuestros módulos.

  • Act: Una vez tenemos el browser, el siguiente paso es generar la peticion, en este caso Put, a una ruta especificada.

  • Assert: Con el resultado de la ejecución, comprobamos el estado de la respuesta (en este caso 200 OK) y que el texto corresponda con lo que necesitamos, que es “Response with Put\n”.

Una vez tenemos las referencias, recordemos qué contenía el módulo que queríamos probar:

public class Routes : NancyModule
{
	public Routes ()
	{
		Get["/routes"] = _ => "Response with GET\n";
		Post["/routes"] = _ => "Response with POST\n";
		Put["/routes"] = _ => "Response with Put\n";
                ...
	}
}

Podemos identificar claramente una línea donde el verbo PUT devuelve “Response with Put\n”, con lo cual nuestro test es correcto

Probando una ruta errónea

Al igual que podemos probar rutas correctas, los test son igual de válidos para comprobar que el acceso a una ruta no autorizada o no implementada se controla correctamente, como sucede a continuación:

[Test ()]
public void TestNotFound ()
{
	//Arrange
	var bootstrapper = new DefaultNancyBootstrapper();
	var browser = new Browser(bootstrapper);

	//Act
	var result = browser.Delete("/routes", with => {
		with.HttpRequest();
	});

	//Assert
	Assert.AreEqual (HttpStatusCode.MethodNotAllowed, result.StatusCode);
}

En este caso, la ruta no está implementada, con lo cual el resultado será un error de tipo “Method Not Allowed”.

Conclusiones

Con pocas líneas de código podemos comenzar a probar nuestros módulos de NancyFx, podemos probar la respuesta de los mismos, así como códigos de error. El sistema de test permite, adicionalmente, pasar parámetros (simulando el uso de un formulario) o navegar a través del DOM del HTML devuelto, si usamos un ViewEngine.

Hangout el próximo miércoles con panel de lujo: Hablemos de blogs!

El próximo día 2 de julio, a las 21:00 (Hora Peninsular Española, ver hora local) tendremos un hangout donde hablaremos sobre la manera de escribir artículos tecnológicos.

Te apuntas? Inscríbete en: https://plus.google.com/events/cfglotuffumq9cd3665o8c15870

Todo surge a raíz de los siguientes tweets:

Tras hablarlo un poco, y convencer a algunos compañeros de batalla, Juan lo anunciaba públicamente:

Panel de asistentes

Para esta edición nos acompañan diferentes profesionales de campos variados, como son:

Jose Manuel Alarcón (@jm_alarcon)

31dbba0

Director de Krasis, editorial de libros de caracter técnico y plataforma de formación online a través de CampusMVP. MVP de Microsoft en materia de ASP.net, y autor de varios libros y cursos, tanto en castellano como en inglés sobre desarrollo web así como sobre e-mail marketing.

Escribe frecuentemente en sus dos blogs, cada uno de diferente temática:
- http://www.jasoft.org/blog/ de caracter técnico
- http://jmalarcon.es/ más relacionado con desarrollo empresarial

Bruno Capuano (@elbruno)

0b39c61

Innovation Product Manager en Avanade, y miembro activo de la comunidad de desarrolladores, podemos verlo habitualmente hablando en eventos de temas variados. Últimamente le hemos visto con tecnologías como Arduino/Netduino, .NET Gadgeter, Pebble, o Lego Mindstorms.

Apasionado de la tecnología en general, mantiene un blog desde hace ya algunos años, en el que podemos ver novedades (salvo raras excepciones) de manera diaria tanto en inglés como en castellano. http://elbruno.com

David Salgado (@davidsb)

0edfe9e

Product Marketing Manager en Microsoft Corporation en el equipo de Visual Studio Online. Anteriormente como parte del equipo de DPE en Microsoft Ibérica, se enfrentó con la tarea de dar el mismo mensaje a diferentes entornos, así como variar la forma y el contenido de estos mensajes.

Le hemos visto en charlas, talleres, workshops, en eventos con la comunidad de desarrolladores, y también en newsletters y artículos de MSDN.

Vanessa Pizarro (@vanesapizarro)

23554a4

Social Media Manager en Hydra Social Media, es una profesional de comunicación a nivel corporativo. La podemos encontrar definiendo estrategias para redes sociales, campañas de publicidad y tras clientes como IE Business School.

Durante 2011 estuvo trabajando en los canales corporativos de Microsoft Ibérica así como en el mantenimiento y la redacción de los contenidos del blog corporativo. Nos traerá la visión de los blogs como herramienta de comunicación desde el punto de vista de las marcas y las empresas.

Juan Carlos Quijano Abad (@jc_quijano)

1ed9a54

Juan, como todo buen superhéroe, tiene doble vida. Por el día es responsable del departamento de desarrollo de TeamPro, donde realiza labores de apoyo técnico así como gestión. Por la noche es editor en Xataka Windows y GenbetaDev, dos de los blogs más visitados a nivel nacional en cuanto a tecnologías Microsoft y Desarrollo web. Asistente y ponente habitual en eventos organizados por la comunidad, nos trae su visión como editor profesional de blogs tecnológicos, a su vez nos ayudará moderando y conduciendo el debate.

Roberto Luis Bisbé (@rlbisbe)

1b83681

Finalmente, el que escribe, Desarrollador de software en VS Anywhere, mantengo este blog desde 2009, escribiendo temática variada pero habitualmente relacionada con desarrollo software y concretamente con tecnologías Microsoft. Estaré comentando mi experiencia desde el punto de vista de un blog personal.

Es una suerte para mí poder formar parte de un panel tan selecto, y estoy seguro que el evento será muy enriquecedor para todos. Además, si no puedes asistir, quedará grabado en youtube.

Te he convencido? Inscríbete aquí!: https://plus.google.com/events/cfglotuffumq9cd3665o8c15870

Balanceo de carga y escalabilidad con ASP.net, primer contacto

Una de los problemas a los que no he tenido la oportunidad de enfrentarme, de manera profesional, es manejar carga de servidores web, así que esta semana me he dispuesto a montar un sistema para balancear dos sitios ASP.net alojados en Azure. En este artículo veremos cómo ponerlo en marcha. Ha sido una aventura muy interesante, así que te invito a que sigas leyendo.

La arquitectura

Últimamente tenemos muchas capas de servicios que nos abstraen de la lógica necesaria para todo esto: los Azure Websites pueden escalar automáticamente, Azure proporciona su propio balanceador de carga a través del componente Traffic Manager, y Amazon tiene su Elastic Load Balancer.

Para este escenario, sin embargo, quería montarlo de manera un poco más artesanal, y esta es la arquitectura:

  • Dos Azure Websites diferentes, uno alojado en North Europe y otro en West US.
  • Una máquina virtual, con Linux (aquí meteremos el balanceador de carga) alojada en East Asia.

¿Por qué Linux? Linux tiene una gran importancia en la actualidad en el área de servidores. Llevaba tiempo sin trabajar con él y además parecía divertido combinar las diferentes plataformas.

Identificando las instancias

Un detalle que puede pasar desapercibido si vamos a nuget.org, es que en el pie de página identifican el servidor en el que estamos (You are on XXXX), con lo cual, si refrescamos la página, veremos otro servidor.

nuget

Para esta prueba sería muy útil saber qué servidor está sirviendo los contenidos, así que lo primero que haremos será crear un proyecto por defecto de ASP.net, y sustituir la acción Index de HomeController por:

public ActionResult Index()
{
    ViewBag.Title = "Home Page";
    ViewBag.ServerName = System.Environment.MachineName;
    return View();
}

Por otro lado sustituimos el código de Index.cshtml (la vista) por:

<div class="jumbotron">
    <h1>Load balancing testing</h1>
    <p class="lead">You are on @ViewBag.ServerName</p>
</div>

El resultado (en local) es este:

Lb_local

Una vez que tenemos nuestro sitio funcionando, el siguiente paso es subirlo a dos servidores diferentes, que son en este caso:

Cada máquina tiene un identificador diferente, de esta manera, cuando hagamos el balanceo de carga, podremos saber en qué máquina estamos.

Agregando el balanceador

Para el balanceador he optado por un Ubuntu Server 12 hospedado en una máquina virtual también en Azure. Una de las cosas que no debemos olvidar es abrir el puerto 80 para poder recibir tráfico normal de Internet (para este ejemplo dejamos de lado temas relacionados con HTTPS, certificados SSL y similares). Con Linux tenemos muchas opciones. Estuve probando las siguientes:

Fair

Es una opción muy sencilla para empezar, pero tiene un problema, ya que necesita un componente en cada máquina que queremos balancear, lo cual nos limita el radio de acción. Puede que en otra ocasión…

Balance

A diferencia de Fair, no necesita un componente en cada máquina, lo que era un plus. Sin embargo, el hecho de estar basado en comandos y no en configuración no me acababan de convencer. Finalmente, no pude hacerlo funcionar por problemas de puertos, permisos y otros.

HAProxy

HAproxy es, según he podido leer, el balanceador más completo y configurable. Funciona mediante un fichero de configuración y necesita direcciones IP fijas, ya que, según los ejemplos, está pensado para que los servidores a balancear estén en la misma red. Después de varios intentos, no conseguí que el balanceador funcionara, así que desistí.

Apache

Por último, descubrí que Apache tiene un módulo específico para proxy y balanceo, que se parecía bastante a lo que necesitaba. Aunque parezca matar moscas a cañonazos, al final resultó ser bastante fácil de configurar.

Instalando y configurando Apache

El primer paso es instalar Apache en nuestro sistema:

sudo apt-get install apache2

El siguiente paso es habilitar los componentes necesarios para el balanceador:

sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_balancer

Una vez tenemos activados todos los componentes, debemos escribir la configuración al final (justo antes de la directiva </IfModule>) de /etc/apache2/mods-available/proxy.conf:

<VirtualHost *:80>
ProxyRequests off
<Proxy balancer://mycluster>
    # WebHead1
    BalancerMember http://scaledemo7844.azurewebsites.net:80

    # WebHead2
    BalancerMember http://scaledemoamerica.azurewebsites.net:80

                Order Deny,Allow
                Deny from none
                Allow from all

    ProxySet lbmethod=byrequests

</Proxy>
        ProxyPass / balancer://mycluster/
</VirtualHost>

Finalmente reiniciamos el servicio:

sudo apache2 restart

Si todo ha ido bien (y espero que sí), podemos acudir a http://ubuntubalancer.cloudapp.net/, donde accederemos indistintamente a cualquiera de las dos instancias y podremos ver su identificador.

Conclusiones

En este artículo hemos visto cómo podemos escalar nuestra página y usar un balanceador intermedio para gestionar las peticiones. Es un primer paso y todavía quedaría mucho por hacer. En el próximo artículo de esta serie, veremos cómo compartir la sesión entre las diferentes páginas que componen nuestro pequeño cluster.

Enlaces Interesantes:

Preparando el examen 70-484

El pasado 30 de mayo aprobé el examen 70-484 de desarrollo de aplicaciones para Windows 8 con C#, lo que me acerca un paso más al MCPD en desarrollo de apps para la plataforma, y es a su vez una excusa y un reto para aprender más de la misma.

Al comentarlo por Twitter, algunos desarrolladores me preguntaron qué recursos había usado, y aquí va un pequeño resumen.

Sigue leyendo

Y esto son las Interactive Rooms

En las últimas semanas he estado trabajando junto con el resto del equipo de VS Anywhere en una funcionalidad completamente nueva para nuestro Web Workspace, que hemos denominado Interactive Rooms.

Con ella, y aprovechando la recientemente presentada API de Visual Studio Online, podemos iniciar sesiones de colaboración directamente desde el navegador conectados con un repositorio Git o TFSVC, algo que, hasta ahora, resultaba imposible.

En este artículo veremos qué tecnologías y servicios hemos empleado para poder hacer posible este producto.

Obteniendo la información de Visual Studio Online

La API REST de Visual Studio Online, presentada en el pasado TechEd, permite acceder a la información de los ficheros almacenados en un repositorio, para poder comenzar una sesión en un punto específico de la historia del proyecto. Entre la información a la que podemos acceder están:

  • Team projects del portal de Visual Studio
  • Commits de un team project específico
  • Estado del repositorio en un commit específico, es decir, acceso a los ficheros.
  • Acceso a la Team Room del Team Project, para poder emitir mensajes.

Con esto, mostramos esta pantalla para que el usuario seleccione los datos antes de comenzar la sesión:

session

La autenticación está basada en OAuth2, lo que permite, una vez autorizado, poder realizar llamadas a la API sin tener que solicitar el usuario y la contraseña una y otra vez. El funcionamiento de OAuth va asociado a dos tokens, de autorización y de refresco, para asegurar la integridad de la cuenta en caso de que alguno de ellos se vea comprometido.

connectToVSO

Estos tokens, en nuestro caso, se asocian a la cuenta de usuario de VS Anywhere.

Almacenamiento y caché

Cuando creamos una sesión guardamos un snapshot de esta primera versión, que no contiene cambios. Esta snapshot se almacena dentro de Windows Azure Storage, concretamente dentro de un blob, que tiene esta estructura:

  • 123456789
    • 123456789000
    • 235123789021
    • 563473568561

Si accedemos desde el Azure Storage Explorer podemos ver qué se está almacenando:

blobs

Esta estructura de árbol nos permite obtener el histórico de una sesión y poder agregar nuevos items usando los ticks como clave. De esta manera podemos mostrar la fecha de creación sin necesidad de acceder al contenido del blob.

El resto de información almacenada (serializada como JSON) está relacionada con el tipo de autenticación, el team project, el commit o la lista de ficheros que se ha usado para poder re-crear la sesión en el futuro.

Para mantener una caché de sesiones activas usamos Redis, que nos permite un almacenamiento clave-valor con un acceso increíblemente rápido.

Descargando los datos

De la misma manera que podemos crear un snapshot, también podemos descargar el estado actual del proyecto, para integrarlo en nuestro workspace de git o TFS local, descargando un fichero que contiene solamente los documentos abiertos y los editados, siendo el resultado el que se muestra:

download

El fichero .zip se genera sobre la marcha, usando la información actual de la sesión y las opciones de compresión de .net 4.5 (ver más en MSDN).

Conclusiones

Mediante el uso de Azure Storage, Redis, y las API de Visual Studio Online hemos podido crear una funcionalidad adicional que complementa, por una parte el Web Workspace, y por otra el propio Visual Studio Online, dando nuevas opciones de colaboración.

La API, aún en estado beta, está bastante avanzada y productos como UserVoice o Zapier la están integrando dentro de sus propias soluciones.

¿Cómo empiezo?

Para poder empezar a usar las Interactive Rooms, solamente necesitas VS Anywhere 3.0.0.157 y una cuenta en Visual Studio Online. Puedes comenzar desde el propio Visual Studio siempre que:

  • Estés conectado a Visual Studio Online
  • El proyecto sea C# y esté en control de versiones
  • El team project esté conectado a visualstudio.com

Si se cumplen esos dos requisitos, las opciones se mostrarán al hacer click derecho sobre un proyecto:

options

Información y registro

Puedes encontrar más información (y registrarte) en la web de Interactive Rooms

Challenges developing Karmacracy for Windows 8

Update: The source code is available now at https://github.com/rlbisbe/karmacracy

Leer la versión en castellano de este artículo

Last April, after several months of development, and continuing the work with HTML, CSS and Javascript I was doing with RealPoll, I published Karmacracy, a Windows 8 app for the popular social network that looks like this:

upload1

The technology that lies behind is HTML + CSS + Javascript. The framework used was AngularJS with some WinJS features like the AppBar or flyouts. Except these two components, the goal was to get an app as portable as possible that could be then exported to platforms like Firefox OS.

Architecture

The architecture used includes partial views, controllers and services who serve as a link to share information between components:

Architecture

Each controller is associated with a view, and in this case we have three of them:

  • user: Displays information of current logged-in user
  • details: Display the details of a kcy
  • world: Displays the main screen, where we can share our link

There are also a couple of additional services that share information between controllers:

  • currentKcy: Allows to share the current kcy from the world view to the details view
  • karmacracyLogin: Allows to share the login status on the different controllers

Finally, a key component was the karmacracy.js library developed by Jorge del Casar, who has saved me a lot of development time by encapsulating the API calls easily.

Challenges

Developing this app has been very challenging, there were adaptations needed from AngularJS to run on a sandbox environment, a custom horizontal scroll was made, and also, the interaction with WinJS has been tough, let’s see a couple examples:

Horizontal scroll

One of the coolest things was to do a custom horizontal scroll that could be multiplatform, so after some research and try-and-error, the result looks nice:

The solution is extended more deeply on this article.

AngularJS with Windows Store

It turns out that making AngularJS to work on a sandbox environment we need to do some small changes to the library source code, in the methods where we inject HTML. Windows considers it a security leak, so we must tell it to ignore it. The solution is extended on this article

WinJS integration

For having details such as the back buttons, the flyouts or the app bar, we needed some integration with WinJS, which provides styles and interactions. The first thing we need is to add the references to WinJS on the main page:

    <link href="//Microsoft.WinJS.2.0/css/ui-light.css" rel="stylesheet" />
    <script src="//Microsoft.WinJS.2.0/js/base.js"></script>
    <script src="//Microsoft.WinJS.2.0/js/ui.js"></script>

We also needed to call the “processAll” event from the controller for the styles and commands to start working. To do it, we wait until the page is active, and we make the call:

$scope.$on("$routeChangeSuccess", function (scope, next, current) {
          $scope.transitionState = "active";
          WinJS.UI.processAll();
});

Once the code is up and running we can add the AppBar, and assign the buttons an action ng-click and (if required) a style with ng-style

    <div id="appBar" data-win-control="WinJS.UI.AppBar" data-win-options="">
        <button ng-click="refresh(true)" data-win-control="WinJS.UI.AppBarCommand"
                data-win-options="{label:'Actualizar',icon:'refresh',
                section:'global',tooltip:'Actualizar'}"></button>

        <button ng-style="{'visibility': logged_in}" ng-click="share()" data-win-control="WinJS.UI.AppBarCommand"
                data-win-options="{id:'cmdCamera',label:'Compartir',icon:'reshare',
                section:'selection',tooltip:'Compartir'}"></button>
    </div>

Launching the flyouts is as easy as search for the control, and display it like we could do with jQuery:

var flyout = document.getElementById("contactFlyout").winControl;
flyout.show(main);

Finally, we can access preferences in a very similar way, in this case the call is performed from the app.js file, right after the routing and the controllers:

WinJS.Application.onsettings = function (e) {
    e.detail.e.request.applicationCommands.append(new Windows.UI.ApplicationSettings.SettingsCommand('privacy', 'Política de privacidad', function () {
        Windows.System.Launcher.launchUriAsync(new Windows.Foundation.Uri('http://rlbisbe.github.io/karmacracy/privacidad'));
    }));
};

WinJS.Application.start();

In this case, the goal was to show a privacy policy and redirect it to the web, but we can also use it as an internal link (for account configuration, for example).

Recap

This has been my first HTML5 app, the source code will be available soon on Github (and I’ll update the post when that occurs. Develop an app for Windows 8 is very, very easy but can be very challenging if you use a framework like angular.

I’ll keep refining the app while I read more and continue my training on this platform.

En el evento //publish en Madrid

Lo que empezó en el //Build 2014, con la presentación de Windows Phone 8.1 y Windows 8.1 Update 1, se ha extendido a eventos como //learn, donde los expertos y MVPs de la plataforma Windows 8 han ayudado mediante webcasts a crear aplicaciones, y ha concluido con //publish, donde, de manera presencial, hemos podido dar los últimos retoques a nuestras apps, de la mano también de expertos, entre los que destacaron:

  • Alejandro Campos @alejacma (Evangelista de Microsoft en el área Windows Phone)
  • Josue Yeray @josueyeray (Microsoft MVP y Nokia Champion)
  • Javier Suarez Ruiz @jsuarezruiz (Desarrollador Windows Phone)
  • Santiago Porras @saintwukong (Microsoft MVP)

Durante algo más de 8 horas estuvimos revisando el diseño de las aplicaciones, agregando más funcionalidad a nuestras apps y corrigiendo algunos fallos puntuales:

My Super Heroes con fuentes personalizadas gracias a @jsuarezruiz

My Super Heroes con fuentes personalizadas gracias a @jsuarezruiz

Preparando la presentación

Preparando la presentación

Pasadas las seis de la tarde empezaron las presentaciones. Durante cinco minutos tuvimos la oportunidad de mostrar qué hacía nuestra aplicación y explicar las decisiones tomadas en cuanto a diseño y arquitectura. Por otra parte, si habíamos hecho aplicaciones universales o aprovechado alguna característica de las plataformas era interesante comentarlo, como en el caso de las aplicaciones de geotagging, que hacen uso del GPS del teléfono.

2014-05-16 19.09.24

La aplicación ganadora, mymood, se basaba en la idea de que el cerebro funciona a diferentes longitudes de onda dependiendo de nuestro estado anímico, pudiéndose inducir mediante el uso de sonidos.

Además de ella, una app que combinaba fotografías y gps, varios juegos tanto en 2D como en 3D, recordatorios dependientes de nuestra ubicación actual y mi propuesta: My Super Heroes.

MY SUPER HEROES

WP_20140516_010

En mi caso, la app presentada era una base de datos de personajes de Marvel en la cual podíamos acceder a los cómics en los que aparecen, los diferentes “universos” a los que pertenecen, así como las películas relacionadas. Tenemos además la posibilidad de guardar nuestros personajes favoritos para que aparezcan en la primera pantalla. De manera adicional, permitía acceder a la Wiki de Marvel para más información de los mismos.

Página principal con mis personajes preferidos

Página principal con mis personajes preferidos

Detalles de un personaje, en este caso, Iron Man

Detalles de un personaje, en este caso, Iron Man

La app se desarrolló en primer lugar para Windows 8.1 Update 1 y una vez considerada “lista para mostrar” comenzó la migración y adaptación de vistas para Windows Phone 8.1. Para la información y las imágenes de los personajes se usó la API que ofrece Marvel para ese propósito.

Por otra parte, para las películas se usó OMDB (una API disponible públicamente con la información de IMDB) y para el acceso a la Wiki se empleó una API generada con KimonoLabs.

Una vez presentadas todas las apps, los asistentes votaron entregando una hoja con su puntuación (1, 2 y 3 puntos). Como había dos premios, el primer puesto, escogía entre una tablet Dell Venue Pro y un Nokia Lumia 1520. Mymood consiguió llevarse el primer puesto, obteniendo MY SUPER HEROES una increíble segunda posición, y el teléfono :):

2014-05-16 20.28.58

La app necesita aún un poco más de trabajo y hay detalles que pulir, pero espero que para finales de mayo todos podáis disfrutar en vuestro Windows Phone de vuestros héroes favoritos de Marvel.