Como configurar HTTP/2 en nuestro App Service desde el portal de Azure

Hello world,

Hace justo un mes os contaba que el App Service de Azure se actualizaba para poder dar soporte al protocolo HTTP/2. Para poder configurarlo, teníamos que acceder mediante el explorador de recursos, a los archivos json de configuración del App Service y cambiar un valor de una clave de configuración.

Pues bien, desde ayer esta configuración está disponible desde el portal de Azure! Para acceder a ella solo tenemos que ir a la opción de “Configuración de la aplicación” y una vez dentro buscar la opción de “HTTP version“. Desde ahí podremos cambiar entre la versión 1.1 y las nueva 2.0.

Captura
Portal de azure, configuración de la aplicación

Si queréis saber más sobre las novedades que nos trae el protocolo HTTP/2, os animo a que os leáis el siguiente post:

HTTP/2 en nuestro Azure App Service

Hasta la próxima!

Anuncios
Como configurar HTTP/2 en nuestro App Service desde el portal de Azure

HTTP/2 en nuestro Azure App Service

Hello world,

Hace unos días el equipo de desarrollo de Azure, nos informaba de que introducían el esperado protocolo HTTP/2 para todas las apps desplegadas en App Services!

¿Qué es el protocolo HTTP/2?

Es el nuevo protocolo por el que se rigen las peticiones HTTP, dicho así, suena como algo que implica tener que modificar todas nuestras apps, pero nada más lejos de la realidad. Realmente no estariamos hablando de un “nuevo protocolo”, así que cambiaré esta definición y diré que es una actualización de nuestro “viejo” HTTP/1.1.

¿Qué novedades trae?

Sin entrar mucho en detalle porque no es lo que pretendo con este post, el objetivo de esta actualización no es otro que la optimización y con ello, conseguir mejorar el rendimiento de un protocolo, que ya había dado todo lo que podía dar. Para conseguir esto se han mejorado/cambiado las siguientes cositas:

  • Conexión única: En las versiones anteriores, para la carga de cualquier web, se utilizaban numerosas conexiones TCP para descargar el contenido de la misma(css, js, imágenes…). Con la llegada de la versión 2, solamente se realizará una única conexión, la cual será capaz de responder a múltiples solicitudes en paralelo.
  • Información redundante: Se elimina el envío de datos repetidos en cada petición, consiguiendo así, tener menos latencia en nuestras peticiones.
  • Multiplexación: palabra difícil, pero fácil de entender. En las versiones anteriores, el navegador tenia que esperar la respuesta de cualquier petición, antes de enviar otra… En la versión 2, esto se resuelve y permite el envío de varias peticiones sin tener que esperar la respuesta de la llamada anterior.
  • Servicio Server push: se podría decir que esto es como una cache, es decir, son una serie de estimaciones para que el servidor sea capaz de enviar la información al usuario antes de que este la solicite.
  • Compresión de cabeceras: en las versiones previas, las cabeceras no dejaban de ser texto plano, en esta versión se utiliza un sistema de compresión (HPACK). El cual hace que sean mucho más livianas.

Estas son, explicadas a groso modo, algunas de las novedades.

¿Qué tengo que hacer en mi App Service?

Vale, espero que hasta aqui os haya puesto los dientes largos y que queráis activar esto en vuestros App Services. Pues bien, os explicaré como, antes de nada, decir que de momento no existe una interfaz gráfica en Azure para hacerlo, sino que tendremos que entrar a toquetear los json de configuración de nuestra app.

El primer paso será buscar en la barra lateral la opción de “Explorador de recursos”:

Explorador de recursos
Explorador de recursos

Una vez dentro se nos abrirá un bonito editor, donde podremos ver todos los recursos de nuestra suscripción/es. En el árbol que se muestra a la izquierda tendremos que seleccionar:

subscription –> ResourceGroups –> providers –> Microsoft.Web –>sites –> [NUESTRO SITE] –> config –> web

Explorador de recursos2
Editor del explorador de recursos (árbol)

Una vez estemos en este archivo, solo tendremos que buscar la clave “http20Enabled” y ponerla a true, ojo, en las apps viejas, o mejor dicho, creadas antes de abril de 2018 el valor que tendrá será por defecto a false, en las nuevas que nos creemos, este valor ya viene a true.

http20Enabled
Editor json configuración web app

Por último, para que surja efecto el cambio tendremos que reiniciar la web app. OJO, yo soy más partidario de pararla, esperar unos segundos y volver a arrancarla.

Espero que el post os haya servido como una introducción a este “nuevo” protocolo así como para que sepáis configurar vuestros App Services hacia el nuevo protocolo.

Saludos y ¡hasta la próxima!

HTTP/2 en nuestro Azure App Service

Testeo aplicación ASP.net MVC con Selenium (Parte 2)

Hello world,

Continuando con la serie de posts sobre testeo de aplicaciones ASP.net MVC, hoy toca hablar sobre algo que muchas veces a los desarrolladores se nos olvida, o mejor dicho, pasamos por alto: QUE FUNCIONE EN TODOS LOS NAVEGADORES!

Siguiendo el dicho de “cada maestrillo tiene su librillo”, en los desarrolladores web pasa algo parecido, pero con los navegadores. Cada cual trabaja con el que más a gusto se siente… Chrome, Firefox, Edge… Internet Explorer (vale sí, no creo que nadie se sienta a gusto con este…). Por ejemplo en mi caso, siempre utilizo Chrome, me gustan las herramientas de desarrolladores que tiene, sencillas y claras de utilizar, y también por la gran cantidad de extensiones que le puedes instalar. En definitiva, que aunque todos sigamos las convenciones, empleemos buenas prácticas, etc… no podemos asegurar que cuando vayamos a desplegar nuestra web funcione en todos y cada uno de ellos como esperamos. Evidentemente, cuando estamos desarrollando NO probamos en todos, sino los desarrollos se eternizarían, pero si que antes de pasar al equipo de QA, deberia haber pasado unas pruebas mínimas en todos los navegadores. Ya que como desarrollador, y pese a contar con el comodín del equipo de QA, no gusta que estos encuentren bugs en nuestros desarrollos. Una vez soltado todo este rollo, vamos a entrar en materia.

En el primer post, hablamos de como crearnos una clase base donde irá la configuración del IIS Express, una vez hecho esto, lo siguiente sería continuar preparando la base de los test para que se puedan lanzar en uno o varios navegadores. Para ello, tendremos que empezar por descargarnos los webDrivers de cada navegador:

Una vez descargados, debemos incluirlos en nuestra solución de test (imagen 1). Posteriormente haremos “botón derecho” sobre cada uno de ellos, seleccionar la opción de propiedades y decirle que se copien a la carpeta de compilación (imagen 2). En mi caso, siempre le pongo que se copie si es una versión más reciente, ya que no me interesa que se copie cada vez, sino, solo cuando haya actualizado la versión de los drivers.

Imagen 1 (Archivos en proyecto de test)
Imagen 1 (Archivos en proyecto de test)

Captura2
Imagen 2 (Propiedades archivos)

Si no hacemos el paso anterior, al ejecutar nuestros test, nos daría una bonita excepción, diciéndonos que no puede encontrar los drivers, y lo que es un detalle, en la excepción nos dice la url donde descargar cada uno de ellos.

Continuamos…

Lo siguiente es configurar los distintos drivers de navegadores para poder ejecutar las pruebas. Para ello bastará con importar los correspondientes usings que nos proporciona la librería de selenium:

using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Edge;
using OpenQA.Selenium.Firefox;

Con esto ya podríamos crearnos los objetos necesarios para cada navegador. En mi caso, y siguiendo lo que comentaba en el post anterior, tengo una clase base, y en el TestInitialize es donde instancio dichos objetos para tenerlos disponibles desde cualquier test:

public ChromeDriver ChromeDriver { get; set; }
public FirefoxDriver FirefoxDriver { get; set; }
public EdgeDriver EdgeDriver { get; set; }

[TestInitialize]
public void TestInitialize()
{
    // Start IISExpress
    StartIIS();

    // Start Selenium drivers
    ChromeDriver = new ChromeDriver();
    FirefoxDriver = new FirefoxDriver();
    EdgeDriver = new EdgeDriver();
}

Con esto ya tendríamos casi casi completa la clase base de nuestros tests, donde lanzaremos el IIS Express, y tendriamos las instancias de los distintos navegadores sobre los que quisiéramos probar nuestra web. Quedaría como dije en el primer post, “limpiar” todo lo que hemos hecho hasta el momento, en este caso, seria “matar” las instancias de los distintos navegadores. Para ello en el TestCleanup de la clase base tendríamos que poner lo siguiente:

[TestCleanup]
public void TestCleanup()
{
     // Ensure IISExpress is stopped
     if (_iisProcess.HasExited == false)
     {
         _iisProcess.Kill();
     }

     // Stop all Selenium drivers
     ChromeDriver.Quit();
     FirefoxDriver.Quit();
     EdgeDriver.Quit();
}

To be continued…

Testeo aplicación ASP.net MVC con Selenium (Parte 2)

Testeo aplicación ASP.net MVC con Selenium (Parte 1)

Hello world,

Cuando hacemos las estimaciones de un proyecto, siempre se nos olvida una de las partes mas importantes, a la vez que mas desagradecidas e incluso podría decir, que más costosas… Esto son los test, si si, los test, eso que siempre queremos hacer pero que “nunca” hacemos…

Hoy empiezo una serie de post en los que me gustaría explicar como hacer testing funcional en nuestra web, desarrollada en ASP.net MVC. En este primero hablaré de como montar las base de nuestros test, así como las librerías a utilizar.

Vamos al tema… Lo primero que tenemos que tener claro (sin entrar demasiado en detalle) es que un test se compone de 3 partes:

  1. TestInitialize: Aquí inicializaremos todo lo que necesitemos para que nuestro test se pueda ejecutar (recordad que un test tiene que probar “algo” en un entorno controlado). Imaginad que nuestro test lo que hace es ejecutar una pantalla que modifica un valor de una entidad de base de datos, evidentemente no modificaremos algo que ya esté creado, con lo que aquí podremos crearnos una entidad (entorno controlado) a la que después modificaremos desde el punto 2.
  2. TestMethod: Aquí pondremos el código necesario para probar nuestra casuística, en el ejemplo explicado en el punto anterior, modificaríamos algo de la entidad creada y validaríamos que esa modificación se ha realizado correctamente.
  3. TestCleanup: Como dijimos en el punto 1, un test se realiza sobre un entorno controlado, para ello hemos realizado una serie de acciones en el punto 1, y otras tantas en el punto 2 y es aquí donde tenemos que deshacer, o mejor dicho, volver al estado de antes de haber lanzado nuestro test. (Este punto cobra especial sentido cuando estamos haciendo test funciona o test de integración).

Hecha esta pequeña aclaración, vamos a continuar con el tema… Cuando vamos a hacer un test funcional tenemos que tener claro que lo que vamos a probar es un flujo de nuestra aplicación. Por ejemplo, quiero probar que funciona el alta de usuario, en el que yo relleno una serie de campos y por ultimo le doy a un botón “guardar”. Muy bien, ya tenemos decidido cual será nuestro primer test. Ahora llega lo divertido, ¿Cómo puedo probar eso sin yo tener que interactuar con la aplicación? ¿puedo hacerlo programaticamente?, mi web corre sobre un IISExpress que se lanza cuando le doy al “play” del Visual Studio ¿Cómo puedo simular eso? y en el mismo sentido, ¿sobre que navegador correrán mis test?… Como dijo Jack el destripador, vamos por partes!

Lo primero, existen librerías que nos proporcionan el poder realizar este tipo de testing, en este caso yo voy a utilizar Selenium. Para ello solo tendremos que ir al administrador de paquetes Nuget de nuestro proyecto de test e instalar “Selenium.WebDriver”:

selenium_nuget
Administrador de paquetes nuget VS2017

Una vez instalado el paquete, lo siguiente que tenemos que pensar es como vamos a lanzar nuestros test y sobre que navegadores queremos que corran dichos tests. En mi caso he decidido que se lancen sobre un IISExpress y se ejecuten en Google Chrome(veremos como configurar varios navegadores). Para ello en el TestInitialize levantaré una instancia de IISExpress:

private Process _iisProcess;
const int _iisPort = 9515;
[TestInitialize]
public void TestInitialize()
{
     // Start IISExpress
     StartIIS();
}
private void StartIIS()
{
     // Obtain application path
     var applicationPath = GetApplicationPath("MyApplication");
     var programFiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
     
     // create instance of IIS
     _iisProcess = new Process();
     // Set Path of instalation ISSExpress in the machine
     _iisProcess.StartInfo.FileName = $@"{programFiles}\IIS Express\iisexpress.exe";
     // set the application path to atach the ISS and the port
     _iisProcess.StartInfo.Arguments = $" /path:{applicationPath} /port:{_iisPort}";
     // Start the IIS
     _iisProcess.Start();
}
protected virtual string GetApplicationPath(string applicationName)
{
     var solutionFolder = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory)));
     return Path.Combine(solutionFolder, applicationName);
}

Con esto ya tendríamos una instancia de IISExpress sobre la que correr nuestros test. Este código seria interesante implementarlo en una clase base ya que lo utilizaremos desde todos los test que queramos realizar con selenium.

Si recordáis al principio del post, comentaba que los test constan de 3 partes, el initialize, el test y el Cleanup. En este caso seria interesante configurar un Cleanup en el que matemos nuestra instancia de IISExpress.

[TestCleanup]
 public void TestCleanup()
 {
      // Ensure IISExpress is stopped
      if (_iisProcess.HasExited == false)
      {
          _iisProcess.Kill();
      }
 }

Con este simple código ya tendríamos la configuración del IISExpress para que se  puedan lanzar nuestros tests. En el próximo post veremos como configurar los drivers para los distintos navegadores sobre los que corran nuestros tests.

Saludos y hasta el próximo post!

Testeo aplicación ASP.net MVC con Selenium (Parte 1)

ASP.NET Core, nuevo modelo de configuración

Hello world!

Con la llegada de core a nuestras vidas, una de las cosas que mas “choca” es ver que ya no tenemos web.config. Con lo que lo mas normal es que nos asalten varias dudas, como por ejemplo: ¿Donde configuro ahora mi cadena de conexión a la base de datos? o ¿Dónde puedo poner todas mis keys de configuración de mi web?…

La respuesta es simple: HELLO appsettings.json!! En el momento que estamos en el mundo del desarrollo, dominado por las “apis” y los “jsons”, el viejo modelo de XML por el que se regía el web.config (trabajaba como un diccionario Key-Value) se ha quedado obsoleto, con lo que Microsoft con la llegada de ASP.NET core se ha decidido por un nuevo sistema de configuración para nuestras aplicaciones basado en un json, que como ya sabéis, es menos pesado, mas legible y sobre todo mas estructurado.

Hecha esta breve introducción, vamos al tema. Lo primero que nos vamos a encontrar en nuestra nueva aplicación en core es un appsettings.json el cual tendrá el siguiente formato:

{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  },
  "Smtp": {
    "Server": "0.0.0.1",
    "User": "nfanjul@pasiona.com",
    "Pass": "123456789",
    "Port": "25"
  }
}

Como podéis ver, ya le he incluido una configuración para un servidor smtp, en este post nos centraremos en como recoger estos valores desde nuestra aplicación.

Lo primero que deberemos hacer es crearnos un modelo con las propiedades que hemos puesto en nuestra configuración, este modelo será donde se mapearán los valores que hayamos configurado en nuestro appsettings.json:

public class Smtp
    {
        public string Server { get; }
        public string User { get; }
        public string Pass { get; }
        public int Port { get; }
    }

El siguiente paso será irnos a la clase startup y en su constructor añadir nuestro appsettings.json: 

public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables();
            Configuration = builder.Build();
        }

En este código podemos ver varias cosas interesantes:

  • Parámetro “optional”: Aquí podremos decir si el appsettings.json es obligatorio o no.
  • Parámetro “reloadOnChange”: Especificaremos si queremos que se recargue la aplicación cuando hagamos cambios en los settings.
  • Segundo “addJsonFile”: ahí podríamos tener un segundo settings para la gestión de nuestros settings locales, y dado que la ejecución de este constructor es secuencial machacaría el appsettings.json principal con nuestros settings locales. Esto nos facilitará el poder tener conexiones a nuestras bases de datos locales. Gestionar esto desde el web.config era un poco í ya q tendríamos que utilizar el famoso “Templating” que tantos dolores de cabeza nos dio en su momento. Por otro lado, al ser opcional no pasará nada si no existe, pudiendo así no tenerlo subido a nuestro repositorio de código.

Continuemos… Una vez visto esto, queda realmente ver como leemos ese appsettings.json. Cuando trabajábamos con el web.config tirábamos de la clase ConfigurationManager , ahora en core también tendremos un helper para cargar esto y poder tenerlo accesible desde todo el ciclo de vida de la aplicación sin tener que utilizar librerías de terceros para el tratamiento de json (ej: Newtonsoft). Para ello en la misma clase startup tendremos el método ConfigureServices  desde el cual podremos resolver la carga de nuestros settings de la siguiente manera:

public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.
            services.AddMvc();
            services.Configure<Smtp>(Configuration.GetSection("Smtp"));
        }

Donde le especificaremos:

  • <Smtp>: Nuestro modelo de datos creado para estos settings.
  • Configuration.GetSection(“Smtp”): al GetSection le pasaremos nombre de la propiedad del json que queremos cargar.

Con habéis podido ver, esta nueva forma de tener nuestros settings es mucho mas limpia, ya que podríamos crearnos tantas secciones como quisiéramos para poder tener agrupados todos los settings por funcionalidad.

Con esto y un bizcocho… Saludos y hasta pronto!

ASP.NET Core, nuevo modelo de configuración

Métodos de Extensión, pon un “this” en tu desarrollo

Hello world!

¿Cuantas veces nos ha pasado que tenemos que agregar funcionalidad a un tipo ya existente? O peor aún ¿que pasa si tenemos que modificar algo también existente que no sabemos que repercusiones tendrá? y ¿si tenemos que mapear entre objetos? Estas y algunas otras preguntas son las que intentaré destripar en este post.

Vamos con un poquito de literatura, ¿Qué son los métodos de extensión? Según la msdn:

Los métodos de extensión permiten “agregar” métodos a los tipos existentes sin crear un nuevo tipo derivado, recompilar o modificar de otra manera el tipo original. Los métodos de extensión son una clase especial de método estático, pero se les llama como si fueran métodos de instancia en el tipo extendido.

Esta muy bien la definición, pero no acabo de ver esto de los métodos de extensión, ni como aplicarlo a mi código… Y si os digo .ToString()string.IsNullOrWhiteSpace(xxxx), y muchos otros que seguro que habéis utilizado millones de veces y no os habíais parado a pensar que esa funcionalidad “extra” de los tipos que la nos proporciona el propio framework de .NET, podríamos aplicarla a nuestros tipos…

Empezaremos declarando la  clase Phone:

public class Phone
    {
        public Guid Id { get; set; }
        public string SerialNumber { get; set; }
        public string Model { get; set; }
        public string Description { get; set; }
        public List Properties { get; set; }
    }

En esta clase lo primero que se me ocurre es querer validar si tiene informadas Properties  o no… ya que a la larga tendremos que hacer mil veces la validación de si tiene registros, con la típica doble validación de if(phone.Properties != null && phone.Properties.Count > 0). la verdad que ese if metido en cada uno de los sitios desde donde tengamos que utilizar nuestra clase Phone no es demasiado “elegante”. ¿Como resolveríamos esto de una forma mas elegante? pues extendiendo nuestra clase de la siguiente manera:

public static class PhoneExtension
    {
        public static bool HasProperties(this Phone source)
        {
            if (source.Properties != null && source.Properties.Count > 0)
                return true;
            else
                return false;
        }
    }

Es esta clase podemos ver 2 puntos clave, uno es que la clase tiene que ser estática, y el otro es el this que ponemos en el parámetro del método, este especifica para que tipo va a funcionar este método, es decir, este método pertenece al tipo “xxxx”.

Otra de las cosas para las que se puede utilizar esto, es para el mapeo entre diferentes tipos, por ejemplo para convertir tu dto a tu viewModel. Vale si, me diréis que actualmente ya hay librerías como AutoMapper que me lo hace “automaticamente”, pongo esto entre comillas porque efectivamente te lo hace “automaticamente” siempre y cuando cumpla la convención de nombres… Pero eso no siempre es así, o incluso hay veces que nos va a interesar tener un control mas exhausto del mapeo. Veamos un ejemplo:

En este caso nos crearemos una clase PhoneDto que tendrá solamente 2 propiedades que serán las que tengamos que transportar entre capas:

public class PhoneDto
{
      public string SerialNumber { get; set; }
      public string Description { get; set; }
}

Dentro de la misma clase estática que nos habíamos creado previamente, podemos incluir algo como esto:

public static PhoneDto ToPhoneDto(this Phone source)
{
      if (source == null) return null;
      var result = new PhoneDto();
      result.Description = source.Description;
      result.SerialNumber = source.SerialNumber;
      return result;
}

Y con esto ya tendríamos nuestro mapper implementando, simplemente extendiendo nuestro modelos de datos.

Por ultimo quedaría ver como utilizarlo. Pues es tan simple como nombre del objeto “punto” y esto ya nos mostrará el intelligence (OJO, hay que añadir el using*) con todas las extensiones/propiedades que tenga nuestro objeto!

extension
Intelligence VS mostrando la extensión

Hasta VS 2015, se tenia que añadir el using a mano… pero a partir de esta versión, con la combinación de teclas “Ctrl + .” ya te sabe reconocer y proponer tus propias extensiones para importarlas como using.

Espero que os resulte útil!

Un saludo y hasta pronto!

Métodos de Extensión, pon un “this” en tu desarrollo

Resumen 2016

Hello world!

Después de mucho tiempo sin escribir, o mejor dicho, sin poner nada nuevo, ya que las entradas de este sitio vienen de un blog anterior, tengo la intención de volver a escribir. No penséis que durante este tiempo he estado parado… nada mas lejos de la realidad, si que he estado parado en términos literarios pero no en “faranduleo”, definiendo “faranduleo” como el acto de ponerse delante de “x” personas para explicarles cositas… vamos, lo que viene siendo dar charlas! Esto es algo que me hacia especial ilusión hacer, el hecho de poder transmitir pero “face to face”, nada de hacerlo escupiendo 4 palabras en un blog!

Acreditación Codemotion 2016
Acreditación Codemotion 2016

Todo esto del “faranduleo” empezó un día cualquiera, hace ya un año, en una conversación de café… Conseguí “engañar” a mi compañera Carmen para embarcarnos en esta nueva aventura. Después de mil horas de preparación, nervios, tensión y montones de sensaciones inexplicables, el resumen es el siguiente:

Si a esto sumamos una formación que impartí para mis compis de Pasiona sobre MVC… Cerramos el año con 9 eventos! Quizá ahora entendáis un poco mejor el porque he tenido olvidado el tema del blog…

Equipo [T] en Codemotion 2016
Equipo [T] en Codemotion 2016

Y este es el resumen de 2016 a nivel de “faranduleo”. Ahora toca descansar, centrarme en el blog y encarar 2017 con ganas y fuerzas renovadas!

Os dejo en enlace a todas las slides de las charlas –> Aquí

Saludos y hasta pronto!

Resumen 2016