Una sinfonía en C#

Un pequeño aporte a la comunidad de habla hispana.

¿Cómo hacer un test de HttpClient?

Cuando hacemos prueba unitarias (AKA unit testing) uno de los objetivos es aislarnos de los agentes externos para crear un ambiente controlado y que nuestros test se ejecuten bajo condiciones repetibles. Bien, dicho esto uno de las clases que al menos yo me encuentro más seguido es HttpClient, que no hace otra cosa que hacer llamadas HTTP, por desgracia al día de hoy no existe una interfaz para usarla para hacer un mock, entonces tenemos que echar mano de cosas como ésta:

Primera aproximación, hacer un wrapper:

public class HttpClientWrapper
{
    public Uri BaseAddress { get; set; }
    public HttpRequestHeaders DefaultRequestHeaders { get; }
    public TimeSpan Timeout { get; set; }
    public long MaxResponseContentBufferSize { get; set; }

    public void CancelPendingRequests();
    public Task DeleteAsync(string requestUri);
    public Task DeleteAsync(string requestUri, CancellationToken cancellationToken);
....

Algo así pero bien, copiar toooodos los métodos que queremos usar (pero marcados como virtuales) y tener dentro una instancia del verdadero HttpClient a la cual simplemente llamamos en cada uno de nuestro métodos, entonces cuando queremos probar simplemente hacemos un mock donde sobre-escribimos los método que queremos probar.

var mocked = new Mock();
var client = mocked.Object;

mocked.Setup(i => i.SendAsync(It.IsAny())).Returns(Task.FromResult( new HttpResponseMessage()));

Como imaginamos hacer un wrapper suena a mucho trabajo y, seamos realistas, es poco elegante.

Opción dos, heredar HttpMessageHandler

Algo que aprendí hace poco es la existencia de la clase HttpMessageHandler, que es internamente utilizado por HttpClient para hacer las llamadas, y además se puede sobre-escribir.

Entonces, podemos hacer dos cosas, primero crear una versión para probar, simplemente una clase para testing, que nos permita configurar cómo deber responder y después simplemente inyectar la clase en el constructor de HttpClient

public class OffLineResponseHandler : DelegatingHandler
{
    private readonly Dictionary responses = new Dictionary();
    public void AddResponse(Uri uri, HttpResponseMessage responseMessage)
    {
        responses.Add(uri, responseMessage);
    }
    public void AddOkResponse(Uri uri, string content)
    {
        var message = new HttpResponseMessage(HttpStatusCode.OK);
        message.Content = new StringContent(content);
        responses.Add(uri, message);
    }
    public void AddOkResponse(Uri uri)
    {
        this.AddOkResponse(uri, string.Empty);
    }
    public void AddServerErrorResponse(Uri uri)
    {
        var message = new HttpResponseMessage(HttpStatusCode.InternalServerError);
        responses.Add(uri, message);
    }
    public void RemoveAll()
    {
        this.responses.Clear();
    }
    protected async override Task SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
    {
        if (responses.ContainsKey(request.RequestUri))
        {
            return responses[request.RequestUri];
        }
        else
        {
            return await Task.FromResult(new HttpResponseMessage(HttpStatusCode.NotFound) { RequestMessage = request });
        }
    }
}

Esta solución es bastante elegante, permite configurar respuestas con los métodos AddOkResponse y AddServerErrorResponse se agregan a un diccionario que permite grabar respuestas, entonces cuando queremos probar hacemos algo así:

[TestMethod]
public void AddOkResponse()
{
    var target = new HttpClientTest.OffLineResponseHandler();
    var url = new Uri("http://www.fake.com");

    var client = new System.Net.Http.HttpClient(target);

    target.AddOkResponse(url);

    var result = client.GetAsync(url).Result;

    Assert.AreEqual(HttpStatusCode.OK, result.StatusCode);
}

En este ejemplo inyectamos el OfflineResponseHandler y lo inyectamos en el constructor de HttpClient, por otro lado configuramos las respuestas que queremos que de dependiendo de la URL.

La otra opción (es menos trabajo) es una clase que herede de HttpMessageHandler con los métodos Send y SendAsync marcados como virtuales para poder usar un framework de mocking del siguiente modo:

public class FakeHttpMessageHandler : HttpMessageHandler
{
    public virtual HttpResponseMessage Send(HttpRequestMessage request)
    {
        throw new NotImplementedException("Mock this please");
    }

    protected override Task SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
    {
        return Task.FromResult(Send(request));
    }
}

Entonces cuando queremos probar con simplemente configuramos el framework de mocking así:

var fakeHttpMessageHandler = new Mock { CallBase = true };

fakeHttpMessageHandler.Setup(f => f.Send(It.IsAny())).Returns(new HttpResponseMessage
{
    StatusCode = HttpStatusCode.OK,
    Content = new StringContent("Hi!")
});

Y listo, mismo efecto, simplemente inyectamos en el constructor del HttpClient y tirar millas, podemos probar con bastante facilidad.

Dejo un link con el código de ambas utilidades, nos leemos.

¿Qué es un circuit breaker?

En este post voy a contar de qué se trata el patrón circuit breaker para utilizar cuando dependemos de recursos externos y vamos a ver un ejemplo de implementación en C#.

Objetivo

El objetivo de este patrón es poder manejar un error al cosultar un servicio remoto que puede tomar un tiempo indeterminado en recupearse. La idea es mejorar la capacidad de nuestra aplicación a ser resilente a fallos.

Cuando nuestra aplicación consume un servicio externo puede ocurrir que este servicio sufra problemas momentaneos o que tengamos problemas de latencia o conectividad, en general estos problemas se pueden manejar utilizando el patrón retry, sin embargo si el problema no se resuelve rápidamente ésta no es siempre la mejor estrategia.

Entonces el circuit breaker evita que nuestra aplicación consulte un recurso externo (otra aplicación, un servicio, una base de datos, etc.) que muy probablemente nos de error por un tiempo hasta que se estabilice.

En resumen el circuit breaker se utilizará donde no tenga sentido seguir reintentando que el recurso externo responda y el patrón retry no tendía utilidad y por supuesto trasladar los errores causados por la falla del recurso externo (o la espera a que responda) a nuestra aplicación nos traería otro tipo de problemas como por ejemplo operaciones de que se quedan esperando y consumiendo hilos de ejecución, memoria y potencialmente causando más problemas a nuestra aplicación e incluso podamos empeorar la situación del servicio externo no dándole oportunidad de recuperarse si lo continuamos consultando.

Por último el circuit breaker actuará como un proxy sobre las operaciones que queramos manejar con él, esto por supuesto puede penalizar levemente la performance.

Implementando un circuit breaker con C#

Básicamente el circuit breaker es una máquina de estados que puede exponer los siguientes estados:

  • Open: El recurso no está disponible porque se alcanzó un número de fallas en cierto tiempo.
  • Half-Open: Estando en Open ha transcurrido un tiempo dado y pasa a este estado, si se puede acceder al recurso se pasa a Closed, si falla se vuelve a Open y se pone el contador en cero
  • Closed: el circuito funciona, en caso de detectarse una falla se incrementa un contador, si se alcanza un número determinado en un periodo de tiempo dado se cambiar a Open

Por otro lado tendremos al menos dos parámetros

  • Threshold: La cantidad de veces que aceptamos que el recurso externo de error antes de considerarlo en problemas.
  • Reset timeout: El tiempo que se esperará antes que volver a intentar consultar el servicio (el tiempo que le daremos a que se recupere)

 

image

Implemetación simple en C#

Acá dejo una implementación simple den C# utilizando una máquia de estados clásica, esto se puede evolucionar mucho por supuesto.

public interface ICircuitBreaker
{
    /// <summary>
    /// Obtiene la cantidad de fallas aceptadas hasta pasar a estado Open
    /// </summary>
    int Threshold { get; }

    /// <summary>
    /// Obtine el tiempo de espera para pasar a estado Half-Open
    /// </summary>

    TimeSpan Timeout { get; }
    /// <summary>
    /// Obtiene el estado actual
    /// </summary>

    CircuitBreakerState CurrentState { get; }
    /// <summary>
    /// Permite invocar una acción utilizado el circuit breaker
    /// </summary>
    /// <param name="protectedCode">La acción que será invocada</param>
    /// <returns>El estado resultante</returns>
    CircuitBreakerState AttemptCall(Action protectedCode);
}

Esta sería la interfaz de nuestro circuit breaker, es sencilla y se puede mejorar mucho pero sirve para el ejemplo, vamos a la implementación

public enum CircuitBreakerState
{
    Close,
    Open,
    HalfOpen
}

public class SimpleCircuitBreaker : ICircuitBreaker
{
    private int threshold;
    private TimeSpan timeout;
    private int attemptCounter;
    private DateTime failureTime;
    private CircuitBreakerState currentState = CircuitBreakerState.Close;

    public int Threshold => this.threshold;
    public TimeSpan Timeout => this.timeout;
    public CircuitBreakerState CurrentState => this.currentState;

    public SimpleCircuitBreaker(int threshold, TimeSpan timeout)
    {
        this.threshold = threshold;
        this.timeout = timeout;
    }

    public CircuitBreakerState AttemptCall(Action protectedCode)
    {
        switch (this.currentState)
        {
            case CircuitBreakerState.Close:

                try
                {
                    protectedCode();
                }
                catch (Exception)
                {
                    this.attemptCounter++;
                    if (this.attemptCounter > this.threshold)
                    {
                        this.failureTime = DateTime.Now;
                        this.attemptCounter = 0;
                        this.currentState = CircuitBreakerState.Open;
                    }
                }

                break;
            case CircuitBreakerState.Open:
                if (this.failureTime.Add(this.timeout) > DateTime.Now)
                {
                    this.currentState = CircuitBreakerState.HalfOpen;
                }
                break;
            case CircuitBreakerState.HalfOpen:
                try
                {
                    protectedCode();
                }
                catch (Exception)
                {
                    this.failureTime = DateTime.Now;
                    this.attemptCounter = 0;
                    this.currentState = CircuitBreakerState.Open;
                }
                break;
        }
        return this.currentState;
    }
}

La forma de utilizar el código es crear una instancia del SimpleCircuitBreaker y llamar al recurso externo a través del método AttenptCall.

Como vemos una máquina de estados que inicia en Closed y en caso de error incrementa un contador, si se llega el número de fallos permitos (threshold) pasa a Open, si se ha pasa un tiempo dado (el que consideramos que es adecuado para que el recurso externo se recupere) se pasa al Half-Open, si se intenta acceder nuevamente y falla se vuelve a Open, si funciona a Close.

De esta manera todo el código que dependa de recursos externos puede conocer el estado del recurso y esperar para llamarlo en caso que se encuentre en fallo.

Como dije se puede mejorar mucho este código no tiene sentido para explicar el concepto hacerlo ahora.

Les dejo un link con el código en github.

Nos leemos.

Javascript: Arrow functions

Arrow function es otra de las novedades de Ecma Script 6 y para quienes usamos C# nos va a resultar familiar la sintaxis.

Básicamente nos permite expresar cualquier función usando una flecha ( => ) hasta ahora podíamos hacer esto:

 

[1,2,3,4,5,6,7,8].filter(function(item) { 
  return item > 4 ;
});

con ES6 se puede hacer así:

[1,2,3,4,5,6,7,8].filter( item => { 
  return item > 4;
});

En definitiva no es más que una forma corta de declarar una función anónima.

Parámetros

Con respecto a los parámetros podemos hacer varias cosas dependiendo de si tenemos parámetros, o cuántos tengamos uno o muchos, por ejemplo.

cuando no tenémos  parámetros podemos poner los dos paréntesis o un guión bajo.

var a = () => { console.log("hola");}
var a = _ => { console.log("hola”);}

Cuando tenemos un único parámetro podemos usar o no los paréntesis

var a = (y) => { return y };
var a = y => { return y };

En cuando a varios parámetros siempre usamos los paréntesis

var a = (x,y) => { return x + y;}

Retorno implícito

En ciertas circunstancias las arrow functions crean el return por nosotros, es decir, no siempre es requerido utilizar return

var a = (x, y) => x + y;

Es equivalente a

var a = (x, y)=> { return x + y; }

En resultado

Usando arrow functions el primer ejemplo quedaría así:

[1,2,3,4,5,6,7,8].filter(item => item > 4)

Nos leemos.

Material de mi charla sobre Blockchain, Smart Contracts y Azure

El pasado Miércoles 24 de Mayo tuve el honor de una vez más participar de SGVirtual, en este caso con una charla sobre Blockchain, Smart Contracts y Azure.

El charla fue grabada como hace siempre la gente de Software Gurú.

 

El material que utilicé se puede bajar de mi repo de Github

Algunos links sobre el tema:

Nos leemos.

Serverless computing: Azure functions.

Una técnica muy común en el desarrollo de software consiste en desacoplar, es decir, intentar independizar una porción de código de otra cosa, ya sea otra porción de código, un dispositivo, un servicios y todo lo que no se pueda, por diferentes motivos, hoy en día esto se intensifica ya que necesitamos cada vez más tener código funcionando lo más rápido posible.

Los servidores, las máquinas virtuales, la nube, los contenedores

En principio, la forma más común de desplegar una aplicación es utilizar un servidor físico, o sea una PC de carne y hueso con un servidor, bases de datos y cosas dentro, esto fue cambiando con el tiempo y nos quisimos independizar de administrar el hardware (si tenemos una PC que administramos nosotros y se corta la energía eléctrica o se rompe un disco tenemos que solucionarlo nosotros) entonces nos movimos a servidores de terceros.

Por otro lado las máquinas virtuales vinieron a ayudarnos un poco con esto, porque hace un poco más simple aislarnos del hardware sin movernos a un servicio de terceros, sin embargo nos seguimos encargando de administrar el sistema operativo nosotros, mantenerlo actualizado y demás.

La nube nos permite poner nuestras máquinas virtuales, copiarlas y demás fácilmente, mejorando bastante el escenario de hacerlo nosotros incluso se pueden mantener actualizadas y cambiar de tamaño fácilmente, pero seguimos atados a tener que instalar todo el software necesario para nuestra aplicación, IIS, Apache, MySQL o lo que sea, y siguen siendo pesadas por así decirlo, además no es raro que instalemos más de una aplicación por máquina lo cual en algún momento nos puede traer problemas.

Por otro lado están los contenedores, que sería como tener solamente la parte que necesitamos de la máquina virtual necesaria para correr nuestra aplicación, creamos el contenedor y santo remedio, pero seguimos necesitando crear y desplegar el contenedor con el software asociado a éste.

Serverless computing

La mínima expresión de aislar nuestro código del resto del mundo es lo que se denomina Serverless computing, que en pocas palabras es tomar nuestro código y ponerlo en un lugar donde simplemente funciona, sin servidores, ni software adicional, ni contenedores, ni nada, si queremos más potencia movemos un slider y ya, también se conoce como FaaS (functions as a service) y AWSLamda fue lo primero que se vio por el estilo.

Azure functions

La servicio que ofrece Microsoft de Serverless computing se llama Azure Functions y es el tema del que voy a hablar en este post.

Componentes de una Azure Function

  • Código
  • Triggers / Bindings
  • Configuración

El código puede ser escrito en C#, Javascript, Python, PHP, F#, Bash, Batch o cualquier ejecutable.

Los trigger y los bindings son la forma de definir las entradas y salidar de nuestra función y cómo se dispara, un trigger define cómo se dispara la función, solo pude haber un único trigger por función los bindings son los datos de entrada y de salida si los ubiese, éste es el listado de bindings y triggers actualmente soportados.

 

image

La configuración es donde definimos todo lo que necesita nuestra app que es externo, como librerías de terceros, Azure functions soporta NuGet y NPM.

Creando nuestra primera Azure function

Hoy por hoy el soporte para crear Azure functions desde Visual Studio no es tan bueno, así que vamos a hacerlo desde el portal

image

Creamos la función C# y colocamos el siguiente código:

using System.Net;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
	dynamic data = await req.Content.ReadAsAsync<object>();
	string name = data?.name;
	return req.CreateResponse(HttpStatusCode.OK, "Hello " + name);
}

En este sencillo ejemplo hay un par de cosas interesante: primero el mensaje de respuesta es una Task, es decir, es asincrónico y dentro del código utilizamos req.Content.ReadAsAsync y lo asignamos a dynamic para poder leer la información pasada  por POST como un JSON.

Probar la función desde el portal

image

En este caso podemos configurar el cuerpo del request y probar el resultado.

Si vamos al panel de la izquierda podemos ver algunos detalles interesantes, por ejemplo el trigger de la función

 

image

 

En este caso nuestro trigger es del tipo HTTP request, es decir nuestra función solamente se ejecuta cuando llega un request HTTP, como vemos hay otras muchas opciones para modificar, como los verbos HTTP permitidos, uno interesante el el Mode, el cual puede ser Standard como ahora o un Webhook.

Si hacemos click en Advanced Editor vemos la configuración avanzada, básicamente todos los parámetros se configuran a través de un JSON.

{
  "disabled": false,
  "bindings": [
    {
      "authLevel": "function",
      "name": "req",
      "type": "httpTrigger",
      "direction": "in"
    },
    {
      "name": "return",
      "type": "http",
      "direction": "out"
    }
  ]
}

 

Invocar las funciones desde internet

Haciendo click en Get function URL vemos la URL pública de la función junto con la clave de acceso por defecto

image

Podemos regenerar la clave o agregar otras cuando queramos, entonces con la URL hacemos una pequeño formulario y probamos la función, pero antes cambiamos nuestra función para que lea los parámetros que envía el formulario de este modo

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
  string name = req.GetQueryNameValuePairs()
    .FirstOrDefault(q => string.Compare(q.Key, "name", true) == 0)
    .Value;
        
  return req.CreateResponse(HttpStatusCode.OK, "Hello " + name);
}

gracias al método GetQueryNameValuePairs permite recuperar los parámetros que legan por query string.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <form method="get" action="https://functionslgm.azurewebsites.net/api/HttpTriggerCSharp1">
        <input type="text" name="name" />
        <input type="hidden" name="code" value="HctmiZNEOjyLTNm7uVZCUynbScU2lEsXDrKvO4AJEIwAwtaVxu14vw==" />
        <input type="submit" value="Enviar" />
    </form>
</body>
</html>

Un simple formulario para enviar el parámetro name y la clave en el elemento hidden, hacemos click en Enviar y listo.

image

Por supuesto que es un ejemplo muy simple, pero lo que acabamos de hacer es procesar un request remoto simplemente escribiendo 4 líneas de C# y nada más.

Más adelamente vamos a ver más detalles sobre Azure functions, por ahora lo dejamos acá.

Nos leemos.