Actualizando la Gestión de la Configuración de ASPNET CORE con Azure

Hace medio año conversábamos acerca de la potencialidad que Microsoft nos empezaba a ofrecer para desarrollar aplicaciones para plataformas Linux y Mac, en el caso Web la iniciativa se llamo ASP NET 5, y en ese sentido se presento una manera para acceder de manera transparente a los valores de configuración (antiguamente manejados por los Web.config) para no tener que preocuparnos si se guardaban dichos valores en un archivo JSON o si por el contrario estábamos guardando dichos valores mediante la consola que Azure nos da para gestionar las Web Apps.

Pues bien, en este lapso varias cosas han transcurrido, y una de ellas es que ASP.NET 5 ahora se llama ASP.NET Core, decisión de Microsoft que ayuda a tener claridad para entender que «este» .Net que corre de manera multiplataforma no es la «siguiente versión» luego de .NET 4.X, así que correspondía regresar al desarrollo puro y duro para verificar si nuestra clase Helper seguía funcionando,  como es lógico habiendo pasado de una versión beta a una release candidate, las API se han actualizado por lo cual algunos de los metodos que se utilizaban ya no funcionan o funcionan de manera diferente, asi que correspondió hacer el ejercicio de revisar el código y dejarlo operativo.

De igual manera aproveche la ocasión para incorporar algo que se me quedo pendiente: soporte para cadenas de conexión, de esta manera seguiremos teniendo (como en ASP.NET 4x) la opción de trabajar en desarrollo con una BD local, y en entornos de despliegue (QA, PROD, etc) con una conexión gestionada por el entorno de Azure, evitando de esta manera trabajar con las ya conocidas Transformaciones, de esta manera si antes teníamos un fragmento de codigo asi:

 services.AddEntityFramework()
                .AddSqlServer()
                .AddDbContext<ApplicationDbContext>(options =>
                    options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));

Con el uso de nuestro HelperConfig quedaria asi:

            services.AddEntityFramework()
                .AddSqlServer()
                .AddDbContext<ApplicationDbContext>(options =>
                    options.UseSqlServer(HelperConfig.GetConnectionString(Configuration, "DefaultConnection")));

Y de esta manera seria posible acceder de manera transparente al valor de la cadena de conexión que podria estar en nuestro JSON, asi:

  "Data": {
    "DefaultConnection": {
      "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=aspnet5-WebTestConfig2-b1ec5227-eb73-448b-86ee-63e3746185e7;Trusted_Connection=True;MultipleActiveResultSets=true"
    }
  },

O, como mencionamos antes, en la consola de Azure:

ConnectionsStrings

Todo esto lo he subido a GitHub junto a un proyecto Web sencillo (vamos, la aplicación por defecto de Visual Studio 2015) para que uds lo descarguen y revisen su funcionamiento, particular atención merecen los siguientes archivos:

https://github.com/fisica3/HelperConfig/blob/master/src/WebTestConfig2/Helper.cs (la clase HelperConfig en si y todo lo necesario para que funcione)

https://github.com/fisica3/HelperConfig/blob/master/src/WebTestConfig2/appsettings.json (Los AppSettings y Connection Strings involucrados)

https://github.com/fisica3/HelperConfig/blob/master/src/WebTestConfig2/Startup.cs (Clase de arranque que prepara la Inyección de Dependencias e invoca a HelperConfig.GetConnectionString)

https://github.com/fisica3/HelperConfig/blob/master/src/WebTestConfig2/Controllers/HomeController.cs (Controlador que hace uso de HelperConfig.GetAppSettings)

En los próximos días explicare un poco mas de este pequeño proyecto, espero que les sea de utilidad y no se olviden de enviarme sus comentarios.

 

Monitoreando la calidad del código en nuestros procesos de desarrollo: Sonarqube

Bueno, en nuestras ultimas series de artículos prácticamente hemos completado el ciclo de despliegue de una aplicación desde el cambio de código hasta su publicación en los entornos, pero como es lógico esto no se acaba ahí, nuestro objetivo debe ser siempre la búsqueda de calidad en lo que estamos desarrollando, y esto necesariamente involucra al código: legibilidad, mantenibilidad, seguridad, buenas practicas según lenguaje, etc.

En ese sentido la idea seria mantener unos niveles de calidad y «parar la Build» en caso que la calidad del código no cumpla unos mínimos, tradicionalmente en .Net hemos contado con la opción de definir unas reglas mediante Code Analysis, permitiendo que no se haga checkin de código si no se cumplen las reglas (si usamos TFVC) o que ciertas reglas se cataloguen como error (forzando a corregirlas si o si), alternativa muy interesante sobre la que tratare de regresar en un post futuro.

En todo caso, en paralelo a lo que veíamos en el mundo .Net iba evolucionando una herramienta muy potente que permitía explotar el análisis de código estático al máximo: Sonarqube, herramienta a la que pude conocer cuando me correspondió configurar un proyecto de Integración Continua donde me gustaron mucho sus dashboard que permitía ir analizando con detalle los diversos tipos de deuda técnica existente en nuestras aplicaciones (para verlo en acción revisa aquí) y como esta ha ido evolucionando históricamente; en ese momento si querías integrarlo en .Net tenias dos opciones: invocar manualmente el análisis, o enlazarlo a un ciclo de Integración Continua usando Jenkins, pero ahora Microsoft ha colaborado para que sea posible integrarlo con TFS y VSTS y de esto se trata este post.

Para mas razones por las cuales usar Sonarqube en nuestros desarrollos, revisar este post de Adrian.

Finish Reading: Monitoreando la calidad del código en nuestros procesos de desarrollo: Sonarqube

Integración Continua con el nuevo modelo de Builds de VSO/TFS 2015 (IV)

Pues si, como fue prometido, ya va tocando meternos con el modelo de Builds, pero antes de proseguir respondamos la pregunta que deje en el post anterior, ¿en que parte de la solución estoy grabando los parámetros de conexión a la BD? pues en el archivo PartsUnlimitedWebsite.pubxml ya que es ahí donde el wizard de deploy guardo los datos de la cadena de conexión a pesar de que al final no sobrescribió los valores del web.config, nos corresponde editar las secciones de dicho archivo a fin de que no persistan los valores dentro de nuestra solución.

Curiosamente, debemos agregar este archivo a nuestra solución, para lo cual hacemos clic derecho y ya formara parte de lo gestionado por VSO, ojo esto solo funciona si hemos editado adecuadamente nuestro archivo .gitignore como ya hemos explicado en el segundo post de esta serie.

Clipboard27
Bueno, ahora si, subamos el cambio y volvamos a nuestro Team Project en Visual Studio Online, dirigiéndonos a la zona de BUILD, de momento estará vacía.Clipboard28
Posicionados sobre la zona que dice «Build definitions» (nótese que aparte tenemos una zona correspondiente a las XAML definitions) y presionamos el «+», nos saldrá la siguiente pantalla:Clipboard29
Finish Reading: Integración Continua con el nuevo modelo de Builds de VSO/TFS 2015 (IV)

Integración Continua con el nuevo modelo de Builds de VSO/TFS 2015 (III)

Bueno, luego de una pausa, proseguimos con esta serie de artículos para establecer un escenario completo de despliegue usando el nuevo modelo de Builds que traen tanto Visual Studio Online como Team Foundation Server 2015, ¡así que manos a la obra!

Para proseguir con el demo de Parts Unlimited, debemos mencionar que en este ejemplo se hace uso intensivo de los Resource Groups que ya conversamos anteriormente, esto permite automatizar la creación del entorno donde se desplegara nuestra aplicación, vale decir que reduciremos nuestras visitas al Portal de Azure para la creación de nuestros recursos.

Para facilitar esto debemos preparar a nuestra maquina para que sea capaz de provisionar directamente en Azure, para lo cual abrimos una ventana de PowerShell (con permisos de Administrador, claro esta) y escribimos Set-ExecutionPolicy RemoteSigned.

5554.image_thumb_6CC60E94

Bien, terminaron los preparativos así que ya con la aplicación cargada en Visual Studio (y bien conectada a VSO) vamos al proyecto PartsUnlimitedEnv, hacemos clic derecho y elegimos New Deployment… Finish Reading: Integración Continua con el nuevo modelo de Builds de VSO/TFS 2015 (III)

Gestión de la Configuración de ASPNET 5 con Azure (y Docker!)

Quienes han leído mis anteriores artículos sobre el despliegue en Azure pensaran que uff, ya tenemos todo listo para buscarnos la vida hasta que Release Management de un soporte total a PaaS, pero la verdad es que la cosa tiende a evolucionar y hay que hacer pequeños ajustes de cara a los cambios que se anunciaron en el Build y que vienen con el Visual Studio 2015.

Esto a propósito de la posibilidad que nos ofrece Microsoft de desarrollar aplicaciones .Net que corran tanto en Mac como en Linux, una posibilidad totalmente disruptiva que es todo un ejemplo de los cambios que llegaron de la mano de Satya, pero claro, esto no implica que lo que hemos desarrollado hasta ahora en ASP.NET lo recompilamos y lo subimos a Linux y ya esta… no, claro que no, para lograr el objetivo Microsoft ha sacado una nueva edición del .NET Framework llamada Core, sobre la cual se ha desarrollado una nueva versión de ASP.NET (concretamente la 5) mas modular y ligera, sin las dependencias monolíticas usuales, aprovechando tendencias ya existentes en el mercado: Bower, Grunt, npm…

Genial, pero todo esto viene con un precio, el primero y para mi el mas doloroso es que esta nueva versión de ASPNET no incluye proyectos en WebForms (sniff :'( ), ha habido un reacomodo en algunas librerías (sobre todo de cara a lograr la integración entre MVC y WebAPI), desaparición de global.asax, en fin no doy mas detalle porque para eso mejor leer los artículos de José M. Aguilar que va cubriendo con detalle las cosas que van saliendo.

Pero dentro de todos los cambios habidos hay uno que nos afecta especialmente a quienes trabajamos en la gestión de entornos de trabajo y de despliegue, y es que por defecto al crear un proyecto nuevo ya no hay un archivo web.config, esto debido a que la gestión de configuración ya no esta centralizada en un archivo monolítico sino que puede estar dispersa a lo largo de un conjunto de archivos (de preferencia JSON) o de las variables de entorno del sistema, correspondiendonos a nosotros el elegir que archivos usaremos y en que orden de secuencia y prioridad se van sacando, y claro la forma de acceder a estas propiedades, que vimos anteriormente, han cambiado.

slots29

Si pues, ya no mas ConfigurationManager y similares…

Y por lado de la estructura de los archivos JSON seria de esta forma, mucho ojo a este config.json, lo usaremos mas abajo:

configjson

Ok, entonces ¿como hago para acceder a dichos valores desde mi código? Finish Reading: Gestión de la Configuración de ASPNET 5 con Azure (y Docker!)

Gestión automática de entornos de despliegue con Azure (tercera parte ¡desplegando!)

Luego de que el camino de usar las Azure API Apps no fuera el mas adecuado para la prueba de concepto (lo cual no quita que sea una tecnología muy prometedora para desarrollar con REST) de nuestro entorno de despliegue, toca proceder a usar los ya conocidos Azure Websites para el ejemplo, en ese sentido repasemos lo que tenemos hasta el momento:

  • Un Team Project en Visual Studio Online, bajo modelo Git (por cierto ¿sabían que está en camino la posibilidad de renombrar los proyectos?)
  • Ya sabemos cómo subir nuestros cambios de nuestro repositorio local de Git a VSO
  • Ya sabemos cómo crear un entorno de despligue en Azure desde Visual Studio, lo hemos visto con API Apps, pero el proceso es básicamente similar para Azure Websites, y claro también hemos aprendido a desplegar desde Visual Studio.
  • Hemos entrado al Portal de Azure y revisado lo que hemos instalado desde Visual Studio.

Con estas bases regresemos a nuestro problema inicial, gestionar los despliegues en entornos separados de QA, Staging, Preproducción, Integración, etc.., en ese sentido debo mencionar que las practicas usuales y conocidas respecto a Integración Continua se basan en el versionamiento de : Código fuente, scripts, datos de prueba, archivos de configuración, siendo lo de Infraestructura como Código un paso más allá en ello (algo en lo que tengo que ponerme cuanto antes); dicho esto el enfoque asumido por Microsoft en los web slots consiste en dejar que el entorno (Azure en este caso) se haga cargo de la gestión de ciertos atributos críticos (definidos por los usuarios, claro está) como las cadenas de conexión a BD de producción, lo cual permite copiar todo el contenido versionado con la seguridad de que no habrá forma de que se hagan públicos esos datos sensitivos, probablemente este enfoque (que personalmente me reduce la cantidad de Perfiles de Publicación que debo de crear en mi proyecto) sea chocante para algunos, pero yo lo veo como una apuesta muy seria y con bastante lógica especialmente cuando ya se trabaja con entornos muy sensitivos, recordemos que los archivos de transformación, que vimos en la primera parte de esta serie, obligan a tener una copia de los atributos variables de cada entorno a fin de luego poder regenerar un .config mezclado.

(Muchas gracias a Scott Hunter quien en el último DevDays me conto estos detalles y permitió que le diera un nuevo vistazo a los slots que es el que comparto con ustedes)

Ya sabemos a que vamos a enfrentarnos, así que manos a la obra.

Como primer paso agregamos a nuestra solución un nuevo proyecto ASP.NET Web que llamaremos WebSlots02SimpleWeb, en este caso lo estamos agregando dentro de la estructura de solución WebSlots01 que ya teníamos.

slots25 Finish Reading: Gestión automática de entornos de despliegue con Azure (tercera parte ¡desplegando!)

Errores de alto vuelo en la web de Air Plus

Un articulo reciente de Eduardo y su posterior discusión, me ha convencido de seguir con esto de los problemas en las paginas Web, problemas que no están restringidos a ninguna tecnología en particular, ya que como le decía a Eduardo no ha sido rara la ocasión en que he visto la entera pila interna de mensajes de error generados en sites JSP o PHP. Sin ir mas lejos, la primera versión de la web del Continental te sacaba todos sus mensajes JSP cada vez que salia un error (cosa muy frecuente entonces)

Como sabran estoy yendo a Perú en Septiembre, así que como contaba entonces realice mi investigación de precios (con los resultados conocidos), lo que no conté entonces fue de este error que aparecio mientras buscaba precios en la web de Air Plus Comet

Lindo, no? Una hermosa query SQL para que todo el mundo intuya como van tus tablas mySQL, y de ahí … hasta la cocina.

Por cierto, los webmasters de El Comercio bien harían en revisar el siguiente articulo: 25+ ASP Tips to Improve Performance and Style, articulo muy especifico a ASP y que me sirvió de gran ayuda antes de la llegada de ASP.NET.

Joder con el puto AJAX de los cojones!!

Como decia un profesor en el IE «mis muertos los cuento frios», asi que recien ahora puedo contar algo de mi experiencia profesional reciente, que espero que sea de utilidad para el que le interese la gestion del desarrollo de software.

Con todos estos años de practica, algunas cosas se te quedan claras en base a las experiencias pasadas y tratas de aplicarlas en la medida de lo posible, lamentablemente a veces no se esta en la posicion de aplicarlas y este fue el caso.

Como decia, algunas cosas se te quedan claras y con fundamento, en este caso tenia claro que avanzado un proyecto no es conveniente meter una tecnologia nueva salvo que: Estuviera focalizada en un sector con poca interaccion con el resto de la aplicacion, o que estuviera claro que fuera completamente compatible y/o evolutiva de la tecnologia empleandose en ese momento.

Pareceria una politica simple y razonable de seguir, pero quienes estan en informatica sabran que estas dos palabras no estan precisamente a la orden del dia en la gestion de proyectos, aunque debo reconocer que he tenido jefes que sin tenido la habilidad suficiente como para llevar razonablemente el proyecto y los intereses de los stakeholders.

Se trataba de una aplicacion Web para uso interno, donde como consecuencia del alto numero de datos a ingresar eran frecuentes las idas y vueltas al servidor, ocasionando un efecto de parpadeo o «pantallazo» que era incomodo para algunos usuarios. Sin ir al detalle tecnico (conocido para quienes conocen esta tecnologia) sabran que este efecto es consecuencia del modelo que trajo ASP.NET el cual es necesario para brindarnos una facilidad de desarrollo que habiamos perdido cuando se paso de la Programacion Visual (con VB, Delphi o PowerBuilder) a desarrollar para la Web (quien ha programado CGIs, ASP Clasico o PHP3 sabe de lo que hablo).

Lamentablemente las quejas salieron cuando la estructura de la aplicacion estaba completada en un 80%, asi que poco se podia hacer (yo proponia aumentar la capacidad de procesamiento del servidor), hasta que alguien planteo la posibilidad de usar lo que recientemente se ha dado por denominar AJAX (aunque las tecnologias base han estado disponibles desde hace tiempo) para solucionar el problema y claro …. se dio el visto bueno a dicha propuesta.

Como ya he comentado la aplicacion ya habia avanzado bastante pero aun faltaban ajustes finales, por lo que se inicio un desarrollo paralelo, por un lado se trataba de replicar en AJAX la funcionalidad existente, y por otro lado se continuaba el refinamiento en la tecnologia actual hasta llegar a un punto de convergencia para integrar las modificaciones hechas en paralelo (las cuales tenian que apuntarse con sumo cuidado).

Cuando correspondio a que se manipulara mis modulos recien cai en la cruda realidad, trabajar con AJAX (al menos en la version que se utilizo) involucraba un paso atras en lo que habiamos ganado en funcionalidad de desarrollo con ASP.NET (si quieres la explicacion marciana ve al final del articulo) siendo mucho mas complicado depurar la aplicacion obligandote a mantener un doble juego de variables y de logica de la pantalla, ya que como la tecnologia se inyecto estando la aplicacion avanzada no hubo alternativa, siendo otra la situacion si se hubiera tenido un desarrollo en AJAX puro desde el principio o con modelo ASP.NET como lo teniamos.

La desesperacion para tratar de ajustar y que vuelvan a funcionar cosas que YA ESTABAN BIEN nos llevo en algunos momentos a decir la frase que titula este post, porque de veras…. era desesperante que cosas sencillas como asignar u obtener el valor de un control de una variable fuera algo complicadisimo.

En honor a la verdad debo decir que el proyecto salio adelante y ya esta en produccion, pero no dejo de pensar que los dos meses (como minimo) que se agregaron al proyecto multiplicado por el coste de 2 recursos (igualmente como minimo) hubiera podido alcanzar para la adquisicion de un mejor servidor, sin el inconveniente de la poca mantenibilidad que adquirio el proyecto.

En resumidas cuentas con ASP.NET uno se acostumbra a manipular directamente los valores de los diversos controles que estan en la pantalla, con AJAX tareas simples como requerian la regeneracion de un XML con el conjunto de valores de los controles, siendo necesario implementar funciones (mas complejas) para recuperar los valores utilizados pues los valores que usa por defecto ASP.NET se vuelven completamente inutiles, mas aun: como en este caso teniamos logica duplicada en ciertos momentos debia hacerse una multiple verificacion para saber que conjunto de variables estaba informado, so pena de que la aplicacion fallara.