Tag Archives: tutorial

Configurar HTTPS en un WebRole de Azure

 

Parece mentira pero algo tan sencillo como permitir el acceso por HTTPS con un dominio personalizado en Azure es algo que no es trivial.

Para empezar, a día de hoy 2 de Abril del 2013, no puedes usar certificados de seguridad en un Web Site de Azure si no estás usando su dominio “azurewebsites.net” por lo que nos hemos visto obligados a mover la web a un WebRole el cual tiene menos opciones de deployment y es más complejo que el Web Site solo para poder poner habilitar el acceso a https://www.midominio.com… lamentable.

Además el proceso completo para poder pedir, instalar y configurar el certificado de seguridad no es nada sencillo así que, para todos los que se vayan a pelear con este tema hasta que lo mejoren, les dedico este artículo.

Crear la solicitud del Certificado

Para poder configurar nuestro certificado de seguridad en Azure necesitamos conocer la clave privada con la que se generó la petición del certificado. Por este motivo no podemos crear la solicitud del certificado desde el IIS ya que no controlamos con qué clave se firma.

El mejor método de hacer esta solicitud es desde el OpenSSL siguiendo estos pasos:

  1. Descargar e instalar OpenSsl para Windows: http://slproweb.com/products/Win32OpenSSL.html
  2. Abrir una consola (cmd.exe) y establecer la variable de entorno para el fichero de configuración del OpenSSL
    set OPENSSL_CONF=c:\[Ruta a la carpeta donde has instalado el OpenSSL]\bin\openssl.cfg
  3. Crear la solicitud de certificado y creación de la clave privada:
    openssl req -nodes -newkey rsa:2048 -keyout private.key -out request.csr
    

    Asegúrate de que tienes permisos de escritura en la carpeta en la que estás depositando el .key y el .csr.
    Al lanzar esta llamada al openssl se te pedirá que rellenes una serie de datos para la solicitud del certificado. Ves introduciendo los datos y pulsa ENTER.
    También se pedirá una contraseña. Anótala ya que la usaremos más adelante.
    IMPORTANTE en “Common Name (e.g. server FQDN or YOUR name) []:” pon el nombre de dominio que quieres proteger (ej: www.compilando.es)

Con el “.csr” creado ya podemos pedir a nuestro proveedor de SSL de confianza que nos genere un certificado de seguridad instalable en nuestro servidor.

 

Exportar el fichero .PFX

Para poder configurar el Web Role en Azure necesitamos obtener el fichero que contiene el certificado de seguridad y la clave privada que generó la petición por eso debemos obtener este fichero .pfx mediante otra llamada al OpenSSL usando el “.crt” que nos ha enviado el proveedor de SSL junto con el “.key” que creamos en el paso anterior.

Supongamos que nuestro proveedor nos envía el fichero de certficado llamado “compilando.crt”

Para ello seguimos los siguientes pasos:

  • Abrimos el certificado que nos envía el proveedor, si no está en formato pkcs12 tenemos que convertirlo antes. Para ello abrimos una consola (cmd.exe) y ejecutamos el siguiente comando de openssl (ejemplo de conversión desde pkcs7):
    openssl pkcs7 -print_certs -in compilando.crt -out compilando_pkcs12.crt
  • Con el certificado ya en formato pkcs12 exportamos el pfx:
    openssl pkcs12 -export -in compilando.crt -inkey private.key -out azure.pfx
  • En la consola nos solicitarán la contraseña que pusimos en el primer paso cuando creamos “private.key” (por eso dije de anotarla ;-))

Con esto obtenemos un fichero llamado “azure.pfx” que ya podemos usar para configurar nuestro WebRole.

 

Configurar HTTP en Azure

Con el certificado correctamente generado y exportado ya podemos configurar nuestro WebRole para disponer de un endpoint funcionando con HTTPS.

Lo primero que debemos hacer es subir el .PFX que acabamos de generar a Azure. 

Para ello nos conectamos al panel de administración de Azure (https://manage.windowsazure.com/) y hacemos lo siguiente:

  • Cloud Services > [Web Role] > Certificates > Upload
  • Escogemos el fichero .PFX que acabamos de crear y escribimos la contraseña (la misma que pusimos al crear el .key y al exportar el .pfx)

 

  • Una vez subido veremos el certificado en el listado y copiamos el GUID de la columna “Thumbprint”

Ahora lo que nos queda es configurar el EndPoint en el Visual Studio. Para ello vamos a la solución en la que tenemos nuestro proyecto de Azure y editamos la definición del Servicio (ServiceDefinition.csdef) y los ficheros de configuracón del Servicio (ServiceConfiguration.XXXX.cscfg) tal y como se ve en los ejemplos que hay a continuación:

ServiceDefinition.csdef

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="Compilando.WebRole" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2012-10.1.8">
  <WebRole name="Compilando.WebRole" vmsize="Small">
<Sites> <Site name="Web"> <Bindings> <Binding name="Endpoint1" endpointName="Endpoint1" /> <Binding name="HttpsIn" endpointName="HttpsIn" /> </Bindings> </Site> </Sites> <Endpoints> <InputEndpoint name="Endpoint1" protocol="http" port="80" /> <InputEndpoint name="HttpsIn" protocol="https" port="443" certificate="www.compilando.es" /> </Endpoints> <Certificates> <Certificate name="www.compilando.es" storeLocation="LocalMachine" storeName="CA" /> </Certificates> </WebRole> </ServiceDefinition>

Como veis, se crea un nuevo EndPoint con el protocolo https apuntando al puerto 443 y usando el nuevo certificado que hemos subido.

ServiceConfiguration.Cloud.cscfg

<?xml version="1.0" encoding="utf-8"?>
<ServiceConfiguration serviceName="Predeploy.Terminis.Web.Azure" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" osFamily="3" osVersion="*" schemaVersion="2012-10.1.8">
  <Role name="Compilando.WebRole">
<Instances count="1" /> <Certificates> <Certificate name="www.compilando.es" thumbprint="F319BC716E1B17FC8824B9325059EC503B6609AE" thumbprintAlgorithm="sha1" /> </Certificates> </Role> </ServiceConfiguration>

En este caso, en la configuración Cloud de nuestra web “Compilando.WebRole” indicamos que el certificado llamado “www.compilando.es” tiene el Thumbprint que hemos copiado del panel de control de Azure. Con esto ya podríamos publicar el WebRole (recordando subir los cscfg y csdef actualizados) para que use el nuevo certificado y ya podríamos visitar nuestra web https://www.compilando.es sin problema alguno :)

 

¡Nos vemos Compilando!

Lanzar automáticamente tests de QUnit desde TeamCity

 

 

Como comentaba en el anterior post estoy investigando sobre testeo de Javascript/Jquery desde Visual Studio y para ello he optado por usar el framework QUnit.

Después de las primeras pruebas y solventar los primeros problemas (sobre todo como “mockear” las llamadas ajax o ciertas peticiones a nivel de servidor) ha llegado el momento de añadir a nuestro servidor de integración continua (en nuestro caso el TeamCity) un nuevo paso para que ejecute automáticamente estos tests cada vez que alguien haga un commit.+

 

El problema de esto radica en que TeamCity no dispone de un driver nativo para ejecutar QUnit ni para lanzar un navegador y leer los resultados así que para que los tests de QUnit se ejecuten como un test más necesitamos:

  1. Un navegador que lance nuestra web de pruebas
  2. Un dirver que le diga al TeamCity el resultado de cada test (usando los TeamCity Service Messages)

 

PhantomJS: Ejecutando JavaScript desde la línea de comandos

Lanzar un navegador por cada test de QUnit y leer su resultado es como matar moscas a cañonazos. Lo que queremos es simple: ejecutar javascript y enviarle al TeamCity un mensaje con la respuesta.

Para ello necesitamos un intérprete de Javascript lo más ligero posible y que se pueda lanzar desde el cmd de Windows. Para ello hemos optado por usar PhantomJS.

PhantomJS nos permite ejecutar un fichero .js como si de un navegador se tratara con la ventaja de que, al no tener interfaz gráfica, tan solo ejecuta el javascript y escribe en el log lo que le digamos.

 

Ahora necesitamos un script que ejecute nuestros tests y escriba por consola mensajes para el TeamCity.

QunitTeamCityDriver

Para hacernos la vida más fácil disponemos en NuGet de una librería llamada “QUnitTeamCityDriver” que nos añadirá a nuestro proyecto dos ficheros javascript:

  • QUnitTeamCityDriver.phantom.js
    • Script ejecutado por el PhantomJs al que le pasaremos como parámetro el fichero .html que contiene los tests QUnit
  • QUnitTeamCityDriver.js
    • Script encargado de leer la respuesta del PhatomJS y escribir en consola los mensajes necesarios para integrarlo con el TeamCity
 
Con estos dos ingredientes tenemos todo lo necesario para crear un nuevo Build Step en TeamCity para que se lancen solitos los tests QUnit.
 

Configurando TeamCity para lanzar los tests QUnit mediante PhantomJS

Como decía al principio TeamCity no soporta de manera nativa la ejecución de tests QUnit por lo que necesitamos un ejecutable externo que se encargue de interpretar javascript y enviar la respuesta al TeamCity.

Primero, descargamos en el servidor de TeamCity el PhantomJS y lo dejamos en una ruta reconocible (por ejemplo, C:\tools\phatomjs). Si tienes más de un agente recuerda hacer este paso en todos ellos.

En segunto lugar. desde la interfaz de administrador del TeamCity, creamos un nuevo Build Step de tipo “Command Line“, le ponemos el nombre que queramos y establecemos la ruta del PhatonmJS y los parámetros.

¡Importante! Hay que pasarle dos parámetros al PhatomJs, el primero es la ruta al fichero “QUnitTeamCityDriver.phantom.js” descargado previamente del paquete del NuGet, el segundo (bueno, realmente es un parámetro que le pasamos a QUnitTeamCityDriver.phantom.js) es la ruta del fichero HTML que contiene las pruebas tal y como explicamos en el anterior post.

¡OJO CON LAS RUTAS! Recuerda que, por defecto, TeamCity ejecuta los steps desde el directorio de checkout (aunque puedes modificarlo añadiendo otra ruta en el Working Directory del step).

El resultado debe de ser algo similar a esto:

Una vez hecho esto ya podremos ejecutar el Build y veremos como los tests se ejecutan de forma habitual como si fueran de NUnit indicandonos en verde o rojo el resultado de los mismos :)

 

Espero que os sea útil.

 

¡Nos vemos Compilando!

Testeo de javascript/jquery desde Visual Studio usando QUnit

 

 

Conforme pasa el tiempo la importancia del javascript en nuestros sitios web se hace más evidente y, en demasiadas ocasiones, esto se olvida y se relega dejando todo nuestro código .js fuera de la cobertura de tests.

En el nuevo proyecto que estoy desarrollando en Avanzis me he propuesto tener el mayor Code Coverage posible y, para ello, voy a testear también el javascript que escriba.

Para ello necesito un modo de hacerlo de forma cómoda y rápida y que, al ser un proyecto NET MVC, cumpla las siguientes condiciones:

  • Los tests de javascript se puedan lanzar desde Visual Studio.
  • El TeamCity sea capaz de lanzarlos automáticamente en cada compilación (o en un Nightly Build en caso de que tarde mucho)
  • Se pueda calcular el Code Coverage
Con estas tres premisas me he lanzado a investigar y he encontrado la combinación perfecta: QUnit + NQUnit + JSCoverage
¿Y como monto este puzzle? ¡Vamos a ello!
 
Este primer post explica como configurar Visual Studio para poder lanzar test QUnit de forma sencilla. En otros post hablaremos sobre NQUnit, como integrarlo con TeamCity y como usar JSCoverage.

Proyecto de QUnit en Visual Studio

QUnit es un framework de Javascript para realizar pruebas unitarios desarrollado por la gente de jQuery para testear sus propios plugins.

El modo más cómodo de integrar QUnit en Visual Studio es instalar el paquete de NuGetQUnit for ASP.NET MVC” (http://nuget.org/packages/QUnit-MVC) en un nuevo proyecto web (en mi ejemplo: MiProyecto.Javascript.Tests) para que nos cree una estructura similar a esta:

 

 

En Content tendremos el css necesario para mostrar la web de resultados de QUnit.

“qunit.js” es la propia librería de QUnit.

Scripts es la carpeta en la que vamos a crear la estructura de carpetas de nuestros tests. En mi caso he optado por crear una carpeta “Tests” para los ficheros .js de test de QUnit y otra llamada como el proyecto (MiProyecto/Common) para los ficheros a testear.

Obviamente estos ficheros (miproyecto.common.math.js) están en su carpeta correspondiente dentro del proyecto de la web MVC por lo que debemos hacer es agregarlos como enlace desde la carpeta del proyecto de test: (en el ejemplo, botón derecho sobre “Common” > Add Existing Item > Buscamos el .js en su carpeta original y seleccionamos en el desplegable de “Add” la opción “Add as Link“:

De este modo puedes acceder al .js original desde el proyecto de Test sin tener que copiar el fichero.

Por último solo necesitamos una página html en la que incluir estos ficheros javascript con una estructura prefijada por QUnit para mostrar los resultados.

El código de la página debe ser similar a este:

<!DOCTYPE html>
<html>
<head>
    <title>QUnit Test Suite</title>
    <link rel="stylesheet" href="Content/qunit.css" type="text/css" media="screen" />
    <script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.min.js"></script>
    <script type="text/javascript" src="Scripts/qunit.js"></script>
    <script type="text/javascript" src="Scripts/MiProyecto/Common/math.js"></script>
    <script type="text/javascript" src="Scripts/Tests/math.tests.js"></script>
</head>
<body>
    <h1 id="qunit-header">
        MiProyecto QUnit Test Suite</h1>
    <h2 id="qunit-banner">
    </h2>
    <div id="qunit-testrunner-toolbar">
    </div>
    <h2 id="qunit-userAgent">
    </h2>
    <ol id="qunit-tests">
    </ol>
    <div id="qunit-fixture">
    </div>
</body>
</html>

Como ves hay que añadir tanto los scripts propios de QUnit como los ficheros a testear y los propios ficheros de tests.

Nota: Desde Resharper se pueden lanzar los tests directamente sin tener que ejecutar esta página PERO tiene ciertas limitaciones (no se puede usar la creación dinámica de valores en el qunit-fixture y no se puede depurar facilmente) por lo que al final opté por hacer la página y ejecutarla manualmente para poder depurar con Firebug.

¡Bien! Ya tenemos la estructura creada pero, ¿cómo se escriben los tests? ¡Allá vamos!

 

Tests en QUnit

Supongamos que tenemos el siguiente fichero javascript en nuestra web (miproyecto.common.math.js) que tiene un par de métodos para hacer sumas, uno que simplemente suma dos números y otro que obtiene el valor de dos inputs por id, los suma y devuelve un span con el resultado:

//Suma dos valores SOLO si son números 
var sumNumbers = function (x, y) {
    if (typeof x === "number" && typeof y === "number")
    { return x + y; } else {
        return "error";
    }
}

//Obtiene el valor de dos elementos por su id, los suma (si son números) y crea un <span> con el resultado
var createSpanSumResultFromInputs = function (idX, idY) {

    var spanResultado = $(document.createElement('span'));

    var x = $("#" + idX).val();
    var y = $("#" + idY).val();
    var result = sumNumbers(x, y);
    if (typeof result === "number") {
        var stringResult = x + '+' + y + '=' + result;
        spanResultado.InnerHtml = stringResult;
    } else {
        spanResultado.InnerHtml = "error";
    }

    return spanResultado;
}

Estos dos ejemplos sirven para demostrar como hacer tests simples para validar entrada de datos, validar resultado y validar modificación de la DOM (lo más común en nuestros scripts).

Para nuestro fichero de test creamos un nuevo fichero js (miproyecto.common.math.tests.js) que está estructurado de la siguiente forma:

// Referencia: Ruta relativa del fichero javascript a testear (para que Resharper la incluya antes de lanzar el test)
/// <reference path="/Scripts/Terminis/Common/math.js"/>

// Clase que engloba todos los tests. Es aquí donde se especifica el SetUp y el TearDown
module('Math Tests', {
    setup: function () {
        // setup code

    },
    teardown: function () {
        // teardown code
    }
});

// Método de test
test('nombre del test', function () {
    //... Asserts
});

Como ves la estructura es similar a la de una clase de test de NUnit. Tenemos SetUp y TearDown y varios métodos de tests con varios asserts (o afirmaciones). ¡Importante! no olvidar el “<reference>” o nuestros tests fallarán al invocar los métodos a probar.

 

Para empezar vamos a probar nuestro método “sum” validando que solo sume dos números y devuelva el valor correcto o el string “error” en caso contrario:

test('Sum Validation.', function () {
    equal(sumNumbers("", ""), "error", "sumar dos cadenas vacias devuelve error");
    equal(sumNumbers("zadasdad", "asdadsa"), "error", "sumar dos textos devuelve error");
    equal(sumNumbers("asdasd", 1), "error", "sumar texto y número devuelve error");
    equal(sumNumbers(1, "asdasdasd"), "error", "sumar número y texto devuelve error");
});

test('Sum Correct Results.', function () {
    equal(sumNumbers(1, 2), 3, "suma de dos enteros");
    equal(sumNumbers(-1, -2), -3, "suma de dos negativos");
    equal(sumNumbers(-2, 1), -1, "suma mixta");
    equal(sumNumbers(1, 2.5), 3.5, "suma de entero y decimal");
    equal(sumNumbers(1.5, 2.5), 4, "suma de dos decimales");
});

Es muy sencillo hacer los asserts. Tan solo hay que hacer uso de la API de QUnit (usando “ok”, “equal”, “notEqual”, “raises”, etc…), poner el resultado de la llamada, el valor esperado y un mensaje para identificar el tipo de afirmación que estamos probando.

 

En el segundo método las pruebas se complican ya que los valores de entrada dependen de elementos de la DOM y el resultado es un <span> por lo que necesitamos crear lo que necesitamos en el SetUp antes de lanzar los tests:

module('createSpanSumResultFromInputs Tests', {
    setup: function () {
        // setup code
        $('#qunit-fixture').append('<input type="text" id="xTest" value="1"/>');
        $('#qunit-fixture').append('<input type="text" id="yTest" value="2"/>');
        $('#qunit-fixture').append('<input type="text" id="wrongValue" value="this is not a number"/>');
    }
});

En el SetUp de este nuevo módulo (solo se ejecutará este SetUp antes de las siguientes llamadas “test()”) hemos creado 3 inputs, dos con valores correctos y uno incorrecto para tests de validación, como si de una página “mockeada” se tratara. 

Para crearlos los hemos añadido al contenedor con id “qunit-fixture“, este elemento es un div cuyo contenido se crea y de destruye en cada ejecución por lo que podemos guarrear todo lo que queramos con él.

Los tests en este caso no diferirían demasiado a los ya visto con anterioridad:

test('Validation Tests', function () {
    equal(createSpanSumResultFromInputs("not exists", "yTest").text(), "error", "Si no existe el idX devuelve error");
    equal(createSpanSumResultFromInputs("xTest", "not exists").text(), "error", "Si no existe el idY devuelve error");
    equal(createSpanSumResultFromInputs("xTest", "wrongValue").text(), "error", "Si uno de los dos no es un número devuelve error");
});

test('Correct Test', function () {
    equal(createSpanSumResultFromInputs("xTest", "yTest").text(), "1+2=3" , "Obtiene los dos valores de sendos input's y devuelve <span> con la operacion");
});

Con esto ya sabemos todo lo básico de los test con QUnit. Existen muchas más cosas como el asyncTest() para peticiones que incluyan callbacks que son harina de otro costal.

 

El resultado es una web similar a esta con todos los test organizados por módulos > tests > asserts pudiendo relanzar test, ocultar test correctos y depurar con FireBug:

 

Con esto ya sabemos la base para empezar a chapurrear tests de javascript en nuestro Visual Studio :)

En la próxima entrega hablaremos sobre como lanzar estos tests desde un servidor de integración continua (como TeamCity) y calcular el Code Coverage.

 

Un saludo.

¡Nos vemos Compilando!

Configurar Git (BitBucket) en Visual Studio 2010 y no morir en el intento

 

Que Git se ha convertido en el más famoso y mejor controlador de versiones de código es una cosa que ya sabéis pero, ¿cómo puedo configurar las herramientas necesarias para poder trabajar con un repositorio Git en mi Visual Studio 2010?

El objetivo de este pequeño tutorial es conseguirlo sin morir en el intento

Nota: Este tutorial no explica el funcionamiento de un control de versiones por lo que doy por supuesto que todo el mundo sabe lo que es un commit, push, pull, branch, etc… Otro día haré un artículo dedicado a explicar más a fondo como funciona un control de versiones :)

 

¿BitBucket o GitHub?

¡Para empezar! Necesitamos una cuenta en algún servicio de repositorio de Git (si no dispones de uno local o el de tu empresa).

Actualmente existen dos grandes servicios gratuitos de Git que son GitHub y BitBucket. No voy a entrar a discutir cual es mejor en este artículo, solo diré que BitBucket te permite tener, de forma gratuita, repositorios privados lo cual es perfecto para esas pequeñas aplicaciones que tienes en casa y quieres salvaguardar.

Es por este motivo principalmente por lo que yo uso BitBucket como Source Control :)

 

¿Ya tienes cuenta en BitBucket? ¡Descarguemos Git!

 

Descargando y Configurando Git para Windows

Bien, lo primero que necesitamos es descargar Git para Windows el cual podemos encontrar aquí: http://code.google.com/p/msysgit/downloads/list

Descarga e instala la última versión disponible.

 

No hay que modificar casi nada durante el proceso de instalación. La única opción que recomiendo modificar es la de “Adjusing your PATH environment” la cual aconsejo cambiar de “Use Git Bash only” a “Run git from the Windows Command Prompt” tal y como se ve en la siguiente captura:

 

El resto lo puedes dejar igual.

 

¡Bien! ¡Ya lo tenemos instalado! Ahora tenemos que configurarlo para que funcione con nuestra cuenta de BitBucktet.

Para ello ejecutamos el “Git Bash” (si, es una consola, no te asustes, jeje) e introducimos la configuración global de nuestro usuario de BitBucket e Email escribiendo:

git config --global user.name "tu usuario de BitBucket aquí"

git config --globla user.email "tu email de BitBucket aquí"

 

Con esto ya lo tenemos!

Ahora vamos a configurar las herramientas en el Visual Studio 2010.

Configurando Git en Visual Studio 2010

Debido a que Visual Studio no incluye Git como control de código por defecto (solo incluye SourceSafe y Team Foundation Server) necesitamos instalar una pequeña extensión de Git para que funcione.
Para ello vamos a “Tools > Extension Manager” o “Herramientas > Administrador de Extensiones” en castellano y, en la Galería Online buscamos “Git” para instalar el “Git Source Control Provider“:

Una vez instalado lo escogemos como Source Control por defecto en “Herramientas > Opciones > Source Control > Selección de Complemento > Git Source Control Provider”

 

Lo próximo que debemos hacer es abrir (o crear) la solución que queremos subir a BitBucket y, pulsando botón derecho sobre el nombre de la solución clickamos en “New Repository“.

Esto creará un nuevo repositorio Git en el mismo directorio en el que está la solución.

Verás que en el “Solution Explorer” aparecen unos símbolos con un “+” amarillo. Esto indica que el fichero es nuevo y no se encuentra en tu repositorio local.

Haciendo click derecho de nuevo sobre la solución y pulsando en “Pending Changes” podremos ver el listado de ficheros pendientes, escribir un comentario y hacer el primer commit contra tu repositorio local.

¡Ya está! ¡Ya tenemos configurado Git para Visual Studio! Eso si, de momento solo lo deja en local y BitBucket ni lo hemos usado.

¿Qué toca ahora? Configurar Git Bash para que suba nuestros commits a BitBucket.

 

Configurar Remote y hacer Push desde Visual Studio a BitBucket

De nuevo botón derecho en la solución > Pending Changes > Git Bash y se nos abrirá la consola de Git. Ahora tenemos que configurar el acceso remoto.

Para ello escribimos lo siguiente:

git remote add origin https://usuario@bitbucket.org/nombre_del_repositorio.git

Supongamos que mi usuario es “vfportero” y mi repositorio en BitBucket se llama “demo”. El remote sería así:

git remote add origin https://vfportero@bitbucket.org/demo.git

 

¡Perfecto! Con esto ya podemos escribir: 

git push

Nos pedirá el password de BitBucket y, una vez escrito, y el bash solito se encargará de subir los ficheros al repositorio remoto :)

 

Espero que os haya servido de ayuda.

¡Nos vemos Compilando!

Configurar Réplica Maestro – Esclavo en MySql Server

 

Sé que este artículo se aleja un poco de lo que suelo escribir por aquí pero la clase magistral que me ha dado mi gran amigo Pedro Sanz sobre MySql bien se merece una entrada en el blog :-)

 

Hoy hemos tenido que montar para un cliente un servidor de réplica de MySql en el que era imperioso que los datos se espejeran de forma inmediata entre el servidor maestro y el esclavo.

Una réplica de MySql Server hace uso del fichero binario de transacciones para almacenar en el maestro todos los cambios reaizados (UPDATES, DELETES, CREATE, etc..) para que un servidor externo lo lea y replique exactamente los mismos cambios en su propia base de datos.

De este modo tenemos uno o más servidores MySql esclavos haciendo las mismas transacciones que el maestro para así tener los mismos datos en diferentes servidores cosa que se realmente útil y, no sólo ante caídas, ya que es posible configurar nuestra aplicación para compartir las SELECT entre distintos nodos de MySql y mejorar así el rendimiento.

 

Bueno, menos teoría y vamos al lío!.

Lo primero que debemos hacer es configurar el servidor maestro para que almacene el log binario y asignarle un identificador. Para ello editamos el my.cnf añadiendo (o editando si ya las tiene) las siguientes entradas:

#Identificador único del servidor maestro
server-id=1
#Nombre del fichero binario donde se almacenarán las transacciones
log-bin=mysql-bin
sync_binlog=1
#Tamaño del fichero de log tras lo que se truncara
max-binlog-size=500M
expire_logs_days=4
innodb_flush_log_at_trx_commit=1

Como siempre que modificamos un my.cnf hay que reiniciar el servicio de MySql para que acepte los cambios.

Luego tenemos que hacer lo propio con el (o los) esclavo(s). Modificar el my.cnf con los siguientes parámetros y luego reiniciar el servicio:

#Indentificador único del esclavo
server-id=2
relay-log=mysqld-relay-bin
max-relay-log-size=500M
relay_log_purge=1

¡Muy bien! Ya tenemos un servidor maestro y un esclavo pero ahora necesitamos crear un usuario para que el esclavo se conecte al maestro y pueda leer el log de transacciones. Para ello vamos a crear un nuevo usuario llamado “replicador” (el nombre y pass puede variar, jeje) en el master con privilegios de “REPLICATION SLAVE“:

CREATE USER replicador IDENTIFIED BY 'elpassword';

Y luego le damos los permisos de REPLICATION SLAVE:

GRANT REPLICATION SLAVE ON *.* TO 'replicador'@'%' IDENTIFIED BY 'elpassword';
FLUSH PRIVILEGES;

Ok! Ya tenemos los servidores bien configurados y el usuario que usaremos como replicador por lo que lo próximo que tenemos que hacer es crear una copia inicial o “snapshot” de la base de datos que queremos replicar para luego poder indicar al servidor esclavo desde dónde tiene que empezar a leer.

Para hacer el snapshot primero ejecutamos las siguientes consultas:

FLUSH TABLES;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;

Ten en cuenta que al hacer “READ LOCK” estamos bloqueando la tabla para que nadie cambie nada por lo que lo que viene a continuación deberíamos hacerlo lo más rápidamente posible.

El SHOW MASTER STATUS muestra dos valores que debemos anotar que son el “File” y “Position“. Necesitaremos indicarselos al servidor de réplica una vez hayamos cargado la copia inicial.

+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 |     492 |              |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

¡Muy bien! Vamos al servidor esclavo y lo terminamos de configurar.

Lo primero es cargar una copia de seguridad de base de datos que queremos replicar del master al esclavo (puedes usar el método que quieras, mysqldump, HeidSql, MySql Workbench…) y, una vez restaurada, configurar el esclavo e iniciarlo.

En este ejemplo vamos a suponer que el servidor maestro está alojado en 10.0.1.10. Fíjate que tenemos que indicar el File y la Position que hemos obtenido antes del SHOW MASTER STATUS:

CHANGE MASTER TO MASTER_HOST='10.0.1.10', MASTER_USER='replicador', MASTER_PASSWORD='elpassword', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=492, MASTER_PORT=3306;

START SLAVE;

Para terminar volvemos al maestro y desbloqueamos de nuevo las tablas para que puedan volver a editar datos:

UNLOCK TABLES;

¡Ya está! Si no ha pasado nada raro tendremos el servidor esclavo con la carga inicial funcionando y todo cambio en el master se replicara por arte de magia.

Si queremos saber el estado del servidor de réplica podemos usar la consulta:

SHOW SLAVE STATUS\G

Que nos mostrará un listado de datos. Yo miro el valor “Seconds_Behind_Master” que indica que “retraso” tiene el servidor esclavo respecto al maestro (si es NULL es que no va. Revisa el “Slave_IO_State” y “Last_Error”).

Ahora empieza a meter datos en la base de datos maestra y verás como ellos solitos aparecen en la esclava… ¡brujería! :-)

 

Espero que esto os sea útil.

Nos vemos Compilando!!

Uso de App.Config en aplicaciones de consola o Win Forms en .NET

Es muy común en nuestras aplicaciones el tener que extraer ciertas variables de configuración a un fichero externo para que se puedan modificar sin necesidad de volver a publicar la aplicación (como por ejemplo rutas que varían en función del servidor en el que publicas la aplicación, cuentas de correo para envíos que pueden cambiar su contraseña, cadenas de conexión, etc…)

En web ya tenemos el famoso Web.Config y su uso es bastante común para cualquier desarrollador web por lo que nos vamos a centrar en este sencillo artículo a cómo añadir un fichero de configuración a una aplicación de escritorio, escribirlo, leerlo y posteriormente modificarlo desde el bloc de notas.

 

Crear el fichero de configuración

Lo primero que debemos hacer es agregar el fichero de configuración a nuestra solución. Para ello nos vamos al explorador de soluciones de nuestro Visual Studio > Botón Derecho > Add > New Item > Application Configuration File.

 

 

Se añadirá un fichero XML con una estructura similar a la del Web.Config en el que podremos ir añadiendo las variables que queramos extraer añadiendo entradas al tag “appSettings” como el ejemplo siguiente:

 

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="mailEnvio" value="info@compilando.es"/>
    <add key="servidorEnvio" value="mail.compilando.es"/>
  </appSettings>
</configuration>

 

 

Leer el fichero de configuración desde la apliación

Una vez creado el fichero de configuración y añadidas las variables de configuración que queramos basta con hacer uso de la clase ConfigurationManager para leer el valor de las misma desde el código de nuestra aplicación:

 

 

string mailEnvio = ConfigurationManager.AppSettings["mailEnvio"];

 

 

Recuerda que has de utilizar el espacio de nombres “System.Configuration” (si no te aparece la clase es porque te falta añadir la dll al proyecto. Vete a Referencias > Añadir Referencia y en la pestaña de .NET busca System.Configuration y añadela al proyecto).

 

Publicar y Modificar la configuración del fichero desde fuera del Visual Studio

Una vez terminada y publicada nuestra aplicación (para este caso la llamaremos “Ejemplo”) tendremos el fichero ejecutable “Ejemplo.exe” que será el que arranque nuestra aplicación de consola o Win Forms y, junto a él, tendremos otro fichero llamado “Ejemplo.exe.config”

Este fichero es el fichero de configuración de la aplicación y se puede abrir perfectamente con el Bloc de Notas y editar los valores del XML para cambiar las variables de configuración si necesitar de recompilar la aplicación.

Así, en este ejemplo, podríamos cambiar el mail desde el que nuestra aplicación envío tan solo editando este fichero sin necesidad de abrir el Visual Studio lo que nos da una flexibilidad mayor a la hora de publicar y distribuir nuestra aplicaciones de escritorio.

 

Nos vemos Compilando!!

Gestión de Errores en ASP .NET: customErrors y Error Handling en Global.Asax

Uno de los aspectos más importantes a tener en cuenta cuando se pasa a producción una aplicación es como vas a tratar los posibles errores que ocurran en ella.

Por defecto, si no modificamos nada y ocurre un error sin controlar, la aplicación nos mostrará una página con el siguiente texto:

 

Server Error in ‘/’ Application.


Runtime Error

Description: An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed remotely (for security reasons). It could, however, be viewed by browsers running on the local server machine. 

Details: To enable the details of this specific error message to be viewable on remote machines, please create a <customErrors> tag within a “web.config” configuration file located in the root directory of the current web application. This <customErrors> tag should then have its “mode” attribute set to “Off”.

 

 

Este mensaje nos indica que ha ocurrido un error y no se muestra al visitante debido a la configuración del Web.Config que por defecto viene así:

 

<configuration>
    <system.web>
        <customErrors mode="Off"/>
    </system.web>
</configuration>

La forma más rápida para poder ver el error es cambiar el “RemoteOnly” por “Off” pero esto no es para nada recomendable ya que muestra los errores a cualquier visitante de la web pudiendo poner en entredicho la seguridad del sistema.

La tercera configuración que permite el apartado “customErrors” es redirigir a una página específica de error y luego guardar el error en un fichero de log o base de datos o bien enviarlo por mail. 

 

Este tutorial explica cómo implementar esta última opción:

Primero: Modificamos el Web.Config para activar los errores personalizados para que redirija a la página “error.aspx”:

<configuration>
    <system.web>
        <customErrors mode="On" defaultRedirect="error.aspx"/>
    </system.web>
</configuration>

Segundo: Creamos la página “error.aspx” para indicar al usuario qué debe de hacer. Como ejemplo os dejo la página de error personalizada que hicimos en Domitienda.com:

Tercero: Sobreescribir el método “Application_Error()” del fichero “Global.asax” (si no tienes ese fichero en tu proyecto lo puedes agregar). Este método se ejecuta cada vez que ocurre un error sin capturar. En este ejemplo vamos a enviar un mail con el error para que podamos revisarlo y solventarlo cuanto antes:

 

void Application_Error(object sender, EventArgs e)
{

	try
	{
		//Obtenemos el error
		Exception ex = Server.GetLastError();

		//Formateamos el correo con los datos del error
		string bodyMail = "Error en Aplicación<br/>";
		bodyMail+= "<br/>Fecha: " + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString();
		bodyMail+= "<br/>Descripción: " + ex.Message;
		bodyMail+= "<br/>Origen: " + ex.Source;
		bodyMail+= "<br/>Pila: " + ex.StackTrace;

		System.Net.Mail.MailMessage oMsg = new System.Net.Mail.MailMessage();
		oMsg.From = new System.Net.Mail.MailAddress("error@mydomain.com");
		oMsg.To.Add("webmaster@mydomain.com");
		oMsg.Subject = "Error en Aplicación";
		oMsg.Body = bodyMail;
		oMsg.IsBodyHtml = true;

		System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient("mail.mydomain.com");
		smtp.Credentials = new System.Net.NetworkCredential("error@mydomain.com","passCuentaCorreo");

		smtp.Send(oMsg);

		//Limpiamos el error 
		Server.ClearError();
	}
	catch(Exception errorEnEnvioDeError)
	{
		//En caso de fallar el envío de error podíamos probar un método alternativo como guardar "bodyMail" en un fichero de texto o en base de datos
	}
}

 

 

Con este sencillo método tendremos nuestra web protegida ante errores inesperados, el visitante verá una página de error más usable y el adminitrador de la web tendrá el mensaje de error en su buzón de correo inmediatamente para poder solventarlo cuanto antes.

Nos vemos Compilando!!