Syntax Highlighter

martes, 30 de noviembre de 2010

Nuevo portal de Windows Azure y SDK 1.3

Por fin comienzan a llegar las novedades presentadas en el PDC10 sobre la plataforma Windows Azure. Ayer mismo se anunció la salida del SDK 1.3 de Windows Azure con importantísimas novedades (¡por fin el role de Virtual Machine!). 

Las principales novedades son:
  • Role VM Beta (Virtual Machine): permite crear una imagen VHD personalizada usando Windows Server 2008 R2 y alojarla en la nube -...olé, olé y olé!
  • Acceso a escritorio remoto: facilita la conexión a instancias de servicio individuales usando el cliente de Acceso a escritorio remoto (lo anterior sin esta característica, dejaría mucho que desear)
  • Soporte Full IIS en los web roles: habilita el alojamiento de web roles bajo IIS
  • Privilegios elevados: habilita la realización de tareas con privilegios elevados en una instancia de servicio
  • Virtual Network (CTP): habilita el soporte para Windows Azure Connect, que provee de conectividad a nivel IP entre alojamiento "on-premises" y los recursos de Windows Azure -...ole otra vez!
  • Diagnósticos: mejoras en Windows Azure Diagnosticos para habilitar la recolección datos de diagnóstico en más condiciones de error
  • Mejoras en conexiones de red: permite a los roles restringir tráfico inter-role y usar puertos fijos en InputEndpoints
  • Mejoras de rendimiento: mejora significativa  en el rendimiento al desplegar una máquina local (uf! a probarlo pero ya!).



Nuevo portal de Windows Azure
Otra de las novedades importantes -acaba de ponerse en producción hace menos de una hora- es la puesta en marcha del nuevo portal de gestión de la plataforma.

El nuevo portal, basado en Silverlight, por lo que he visto por encima facilita muchísimo la configuración y gestión, no teniendo que estar pasando entre distintos portales (Windows, SQL  Azure, App Fabric -bueno, a este último todavía sí, por ahora se limita a un enlace al portal-, etc.) como se hacía antes, sino teniendo todo en la misma herramienta centralizada.



Hay muchísimas novedades para las que hay muchos posts que escribir (Reporting, Azure Connect -redes virtuales con Azure-, aunque hay una muy sencilla que me ha llamado la atención sobre el resto y que llevaba esperando desde hace más de 2 años -parece una chorrada, pero en un entorno empresarial es muy importante. 

La característica a la que me refiero es la de poder añadir co-admnistradores para gestionar una suscripción de Windows Azure -sí, hasta ahora no se podía hacer, supongo que habría alguna cuestión técnica que ha hecho que esta característica se demorara en el tiempo.

Al acceder a la nueva sección de "User management", al pulsar sobre el botón "Add New Co-Admin" se nos presenta una ventana para indicar el Windows Live ID del usuario o usuarios que queremos que "co-administren" la suscripción. 




Otra de las novedades es la de poder unirse fácilmente a los programas Beta desde el mismo interfaz con sólo dos clicks. Ahora mismo aparecen las instancias Extra Smalls, Windows Azure Connect y el ya comentado VM Role, que es lo que voy a probar hoy mismo. En cuanto tenga novedades del funcionamiento del Virtual Machine Role comento algo.



Un saludo.

lunes, 22 de noviembre de 2010

Control de código fuente en la nube

Como algunos ya saben, desde el 17 de noviembre esta disponible la versión 5.06 del portal DotNetNuke Community, con algunos cambios y correcciones muy interesantes. Este momento lo tenía en el horizonte y llego el momento de fusionar los cambios que he realizado en el portal para que soporte la plataforma Azure con esta nueva versión, con el objetivo de comprobar la viabilidad de ir manteniendo una versión paralela con cada nueva versión oficial (por lo menos hasta que DNN soporte oficialmente la plataforma Azure).

Hace algunas semanas comenté en el grupo especializado en LinkedIn de DNN Community la estrategia que tenía en mente, que no es otra que la de utilizar una herramienta de control de código fuente como Team Foundation Server con ramificaciones -branching & merging-. Para mí lo ideal para ello es CodePlex, ya que mis conocimientos sobre TFS son totalmente extrapolables a este entorno -detrás de CodePlex hay un TFS, con muchas menos opciones que la versión completa, pero las suficientes para poder hacer lo que me propongo.

Ahora mismo estoy inmerso en la mezcla de las dos versiones y ya publicaré más adelante una entrada con mis impresiones finales al respecto.


Si bien CodePlex nos ofrece una integración perfecta con las herramientas de Visual Studio, tiene un pequeño problema, que no tiene repositorios privados -no se ofrece esta opción- y por lo tanto, si no se publica en menos de 30 días el proyecto, éste es eliminado del servidor. 


No es que para este proyecto en cuestión sea lo que busco, pero quizás sí para alguno más adelante con lo que la opción de tener algún repositorio privado es, cuando menos, necesario.

No quería dejar de comentar otra alternativa que me comentó Marco para poder almacenar y compartir código fuente en la red: GitHub, una herramientra de control de código fuente construida en la nube, tal y como reza a su pie de página (Powered by the Dedicated Servers and Cloud Computing of Rackspace Hosting).

Lo primero que me ha llamado la atención, es la política de precios. En una frase: "para todos los bolsillos", ya que es gratuita para repositorios públicos y para los privados comienza desde 7$ al mes. Me ha parecido un buen ejemplo de SaaS en la nube por sus planes de ampliación y el gran abanico de posibilidades.



Si bien la integración con Visual Studio se ciñe a una extensión que pone una barra de herramientas dentro del entorno y que abren diferentes ventanas el interfaz de Git, soporta protección bajo SSL, envío de notificaciones por email, Wikis, workitems, descargas y lo que está muy conseguido, el branching y merging, ya que se soportan diversos métodos para estas tareas. ¿Dije que es multiplataforma? (Windows, LinuxMac).

Después de un rato tecleando comandos en la consola de Git hice una prueba de publicación. Lo que no creo que con DNN Azure realice los branchs y merges con él, ya que con CodePlex me manejo mejor, pero por 5€ al mes, tener un backup privado en la nube con control de código fuente vale la pena. Para todo lo demás, Mastercard.



Pregunta para la bruja Lola

¿Cuáles serán las políticas de precios del Team Foundation Server que se ejecutará sobre plataforma Azure, que fue anunciado en el PDC10 y que estará disponible para el año que viene?

Os dejo un enlace al blog de Ibon Landa donde resume muy bien lo que fue anunciado en el PDC sobre este tema.

¡Happy coding!

lunes, 15 de noviembre de 2010

DotNetNuke en Azure: desplegando en la nube

Este fin de semana he estado haciendo algunos avances en el siguiente objetivo de la lista -adaptar la configuración de DNN a Azure-  y me he dado cuenta que aún no había publicado cómo desplegar el paquete de instalación en Azure ni traducido los posts a inglés, así que hoy toca trabajo documentar el trabajo de hace dos semanas. El hábito de ir haciendo capturas de pantalla y pegándolas en word a medida que avanzas facilita mucho la tarea.

El último capítulo del diario de bitácora finalizó con la creación y despliegue en Development Fabric, el entorno de desarrollo que viene con el SDK de Azure y que emula el entorno de producción. Llegaba la hora de publicar en real el webrole y ver con qué problemas nos podíamos encontrar. 

Desplegando en Azure

Desplegar el paquete que ya funcionaba en Development Fabric no tenía porqué ser diferente de desplegar cualquier otra aplicación adaptada a la plataforma. De hecho no lo fue, aunque cuando finalicé el trabajo me di cuenta de lo que quedaba aún por hacer -ver conclusiones finales.

Paso 1. Crear el servicio de almacenamiento 

El primer paso fue dirigirme al portal de Windows Azure para crear el servicio de almacenamiento, que es un servicio para almacenar de forma persistente la información. Hay que tener en cuenta que la información almacenada localmente en una instancia de un webrole es totalmente volátil, por lo que hace falta un espacio de almacenamiento persistente. 

Un ejemplo de este tipo de almacenamiento que utiliza DNN son los contenidos que se van agregando dinámicamente desde el módulo File Manager o desde el mismo editor HTML, y si bien en esta fase aún no había tocado código para que soportara esta característica de Azure, sí que lo iba a usar para almacenar la información de diagnóstico de Windows Azure. En cualquier caso, es obligatoria la creación de al menos un servicio de almacenamiento para poder desplegar más tarde un servicio de hosting.

Desde la pantalla inicial seleccionamos "Storage Account" para dar soporte de almacenamiento a nuestro portal en Azure:


En el siguiente paso, simplemente le ponemos un nombre y descripción al servicio de almacenamiento:


Al pulsar el botón "Next", tendremos que introducir el nombre público del servicio de almacenamiento que debe ser único a nivel global. Por otra parte, al seleccionar el grupo de afinidad, es importante seleccionar el mismo que utilizamos cuando creamos el servidor de SQL Azure (ojo, el servidor es al que se le da el grupo de afinidad, no a las bases de datos), tanto para evitar problemas de latencia como para evitar costes de tráfico de entrada/salida del datacenter. 


Transcurridos unos segundos se nos presenta la página de resumen del servicio que acabamos de crear -no perdáis el tiempo usando los datos de la imagen, es un servicio de prueba que ya eliminé sólo para escribir el artículo. De los datos presentados, hay dos muy importantes con los que tenemos que quedarnos para modificar el paquete que vamos a desplegar:
  • Account Name: es el nombre público "corto" que le pusimos antes. Siempre se puede ver, por ejemplo, en las URLs de los EndPoints (la parte http://<PublicStorageAccountName>.blob.core.windows.net, por ejemplo)
  • Primary Access Key: es el "churro" de caracteres que aparece en esa misma pantalla. Se puede utilizar tanto la primaria como la secundaria. 

Ahora volvemos al Visual Studio para modificar el paquete de instalación para que use este servicio en vez de Development Storage. En vez de explicar cómo se puede hacer a través de transformaciones de configuración -pendiente escribir un artículo sobre este tema, ya que difiere de las transformaciones a los .config- lo hago de manera sencilla:

1) Accedemos a la configuración del WebRole en nuestro DotNetNukeCloudService, en la pestaña "Settings"


2) Pulsamos sobre el botón para modificar el valor y utilizamos los dos datos anteriormente indicados y pulsamos aceptar:

NOTA IMPORTANTE: cuando estamos en producción, es obligatorio usar protocolo HTTPS con los EndPoints. En caso contrario, tendremos un problema de ciclado al iniciar el WebRole como se comenta en el Paso 5.


Paso 2. Crear el servicio de hosting

Para poder desplegar a continuación el WebRole, el primer paso es crear un servicio de hosting. Para ello, volvemos a la página de creación de servicios y esta vez selecionamos un Hosted Service:



Del mismo modo que hicimos con el servicio de almacenamiento, le ponemos una etiqueta y una descripción:


A continuación le damos el nombre público donde va a estar alojado el servicio comprobando que está disponible globalmente. También seleccionamos el mismo grupo de afinidad que el servicio de almacenamiento y el servidor de SQL Azure para evitar los costes y latencias comentados previamente.


Una vez que pulsamos el botón "Create", ya tenemos listo el servicio para poder desplegar el WebRole.




Paso 3. Desplegar en Azure

Pulsando el botón "Deploy" de la pantalla anterior nos sale un interfaz para subir el paquete de instalación. Se pueden seguir los pasos hasta finalizar el asistente. Sin embargo voy a explicar la forma "integrada" con Visual Studio que viene desde la versión 1.1 del SDK:

1) Agregamos un certificado X.509 al servicio que acabamos de crear. Este paso lo describí hace algunas semanas por lo que me lo salto;
2) Pulsamos con el botón derecho sobre el servicio y pulsamos sobre "Publicar" para iniciar el asistente 
3) Seleccionamos la opción "Deploy your Cloud Service to Windows Azure"
4) Configuramos las credenciales con las que vamos a publicar desplegando el cuadro combinado y seleccionando "Add...": indicamos el certificado X.509 que configuramos en el paso 1; introducimos el ID de suscripción del portal de Azure y finalmente indicamos un nombre para los credenciales con el fin de volver a usarlos más adelante. Pulsamos el botón OK para comprobar que todo está correcto;


5) Al volver de la pantalla de credenciales, nos aparecen los servicios que acabamos de configurar: el servicio de hosting -que podemos utilizar el de producción o preproducción- y la cuenta de servicio de almacenamiento a través de la que se va a realizar el despliegue. También se pueden activar en este momento las opciones para habilitar IntelliTrace en el despliegue -por favor, un gran "clap!" por el que tuvo la idea de incluir esta funcionalidad.



6) Pulsamos el botón "OK" y...¡comienza la fiesta! 

Paso 4. Ir a hacerse un café...un sandwich...subir un personaje en el WoW a nivel 80...conseguir el título de Matarreyes

Comienza la publicación automática. Quiero dejar claro desde el principio, que por lo que he podido comprobar habilitar IntelliTrace tiene sus inconvenientes, y es que el despliegue viene tardando más del doble que sin él. ¿Y cuánto es el doble? Depende del servicio y número de instancias a desplegar. Lo mínimo que he tardado en un despliegue con un HelloWorld sin IntelliTrace es alrededor de 8 minutos. El de DNN con IntelliTrace activado, me ha llegado a tardar casi 1 hora en finalizar. En el PDC10 anunciaron que en breve el despliegue iba a tardar muchísimo menos...a ver si llega esto.

Resumiendo: 
1) primero la subida del paquete a la nube, que tardará más o menos dependiendo de la línea de comunicaciones que tengamos (tengo que hacerme con una línea de esas de 50Mb...es un buen momento para mirar en los distintos proveedores a ver si alguno te da cobertura...).
2) inicialización de las instancias a desplegar
3) entrando en estado ocupado "Busy"...
4) Stopping... ¡me voy a <censored> en todo lo que se menea!



Paso 5. Tómatelo con calma, todo es cuestión de perseverancia

El error de ciclado en la inicialización es muy común en los primeros despliegues. Para ello, recomiendo este artículo en el foro de MSDN en el que puedes repasar cada una de las causas comunes de este problema.

Después de una detenida lectura -el tiempo desperdiciado con un despliegue fallido hace que te lo tomes bastante en serio- realicé los siguientes cambios:
  • Configuré los EndPoints del servicio de almacenamiento para que usaran protocolo HTTPS ya que es obligatorio en Azure -una prueba sobre desarrollo me hizo dejarlo sobre HTTP 
  • Reconfiguré la compilación de los proyectos para que utilizaran .NET Framework 4.0 y 64bits. Si bien lo de Framework 4.0 no es obligatorio, según el artículo no se deben referenciar ensamblados de 32bits -por lo que he probado, esto es obligatorio para los WorkerRoles pero no así para los WebRoles, con lo que creo que no fue determinante
  • Agregué referencias que estaban en el web.config y que no estaban en el proyecto. Esto se había quedado al migrar del WebSite al WebApplication
  • Me aseguré de que todas las referencias estaban como "Copy Local"
Tras estos cambios el WebRole se desplegó correctamente. Pulsé rápidamente sobre el enlace y el resultado es lo que veis hoy en http://dotnetnukecommunitytest.cloudapp.net 




Conclusión

Con este trabajo conseguía lo que, por lo que he podido comprobar, es la primera publicación de DNN sobre Azure. Sabía que faltaban muchas cosas por delante, como separar la configuración, utilizar el servicio de almacenamiento para contenidos, migrar más módulos, etc. pero era un gran paso...no como caminar por la luna, pero emocionaba.

El mejor consejo que puedo dar para este paso en las migraciones es "empaparse" del foro de MSDN de Windows Azure Platform Troubleshooting, Diagnostics & Logging. No usarlo sólo cuando tengamos un problema, sino leerlo frecuentemente, ya que nos ahorrará mucho tiempo y despliegues intermedios. Estáis tardando en ponerlo como fuente RSS.

El siguiente objetivo: cambiar el sistema de configuración para usar Service Configuration.


Off-Topic: lo de matar a Arthas en el WoW no era coña. Conseguimos el logro de "Matarreyes" en una raid entre despliegue y despliegue del DNN sobre Azure -un saludo para la gente de la guild. No veas lo contento que acabamos ese día, sobre todo yo :) Podéis comparar la fecha del logro con la de la captura del primer deploy con éxito que está unas líneas más arriba.








domingo, 14 de noviembre de 2010

Sé ecoísta, la nube es verde

Después de un decepcionante día para los españoles en la Fórmula 1 -no así para Alemania y Red Bull, felicidades Vettel- en vez de dedicarme a leer comentarios sobre si la estrategia de Ferrari fue correcta o no (lo hecho, hecho está) ha llegado a mi navegador un interesante documento sobre otro de los grandes beneficios del uso del Cloud Computing. 

Y es que más allá de los beneficios sobre ahorros de costes, flexibilidad, agilidad del cambio y su elasticidad, comienzan a surgir estudios sobre los efectos "colaterales" del cloud computing. Si estos efectos tienen un impacto positivo en nuestra sociedad, pasan a ser lo que denomino beneficios colaterales.

El resultado del estudio realizado por Microsoft, Accenture y la consultora WSP no puede estar más alineado con la definición de ecotecnologíaLa nube es verde: el consumo de energía es menor y produce menos emisiones de carbono.

Los datos

Las cifras son impresionantes. El estudio desvela lo siguiente:


  • En pequeñas compañías (menos de 100 usuarios), el ahorro energético y las emisiones de carbono se reducen en un 90% cuando se pasa del modelo tradicional "on-premises" al modelo cloud
  • En compañías de tamaño medio (entre 100 y 1000 usuarios), la reducción varía entre un 60% y un 90%
  • En compañías de gran tamaño que requieren un gran despliegue (unos 10.000 usuarios) la reducción varía ente un 30% y un 60%


Factores determinantes

En el estudio se nombran los factores clave que hacen posible estos beneficios colaterales:
  • Aprovisionamiento dinámico: la capacidad de los servidores se adapta mucho mejor a la demanda. En el modelo tradicional, si espero que mi negocio crezca a corto plazo y sé que voy a necesitar una infraestructura que lo soporte, tendría que adquirir y aprovisionarme de equipamiento que esté en equilibrio entre la inversión realizada y el servicio ofrecido para garantizar el retorno de la inversión. En el modelo de la nube no hace falta adquirir inicialmente un "megaservidor" que esté infrautilizado y consuma más energía, sino que podemos ajustarlo según nuestro negocio vaya creciendo.
  • Multitenancy: este término que está cobrando mucha mayor relevancia con la nube, viene a significar el uso compartido de los mismos recursos en el mismo instante (tanto hardware, software, etc.). Por poner una metáfora, una licencia de taxi compartida entre tres taxistas hace explotar mejor el uso de la misma, pero si pudieran conducir los tres a la vez haciendo carreras distintas con el mismo taxi, eso sería multitenancy. Esto que por desgracia no es posible con un vehículo, en términos de IT es posible -no fácil, sí posible- y de hecho es una de las características más importantes de la nube. SQL Azure es un ejemplo.
  • Uso de servidores: este es un factor clave. Me hace pensar en todos esos servidores que están hoy domingo encendidos consumiendo energía...¿cuánta gente accedería a la aplicación de su compañía durante la carrera de F1 de hoy? Una cosa es que el servicio esté disponible y otra que se mantenga con la misma infraestructura que en una hora punta de trabajo. 
  • Eficiencia de los datacenters: las continuas investigaciones e innovaciones de los proveedores en este campo van en busca de minimizar el consumo energético. Teniendo en cuenta que será uno de los gastos más importantes de un centro de datos a gran escala es el consumo, la eficiencia para minimizar el uso de energía cobra una relevancia determinante. Consecuentemente dicha eficacia hacen que sean más verdes.
Si quieres conocer con más detalle el estudio y descargar una copia del White Paper puedes hacerlo desde este enlace.


¡Sé ecoísta! Hoy por ti. Mañana por ti.

martes, 9 de noviembre de 2010

DotNetNuke en Azure: convirtiendo el WebApplication en un WebRole

Ahora que ya tenemos la base de datos en Azure y el WebSite convertido a una WebApplication, por fin podemos ponernos manos a la obra con la conversión en un WebRole de Azure.

Realmente, no se trata de una conversión, sino más bien añadir una funcionalidad a la aplicación web para que pueda ejecutarse como tal. La idea es simplemente añadir una clase que herede de RoleEntryPoint para que el controlador de AppFabric de Azure pueda manejar la aplicación.

Convirtiendo la WebApplication en un WebRole

El primer paso es agregar las referencias necesarias de Windows Azure de todo WebRole. Estas referencias son -recordad descargar el SDK de Windows Azure para tenerlas disponibles:
  • Microsoft.WindowsAzure.Diagnostics
  • Microsoft.WindowsAzure.ServiceRuntime
  • Microsoft.WindowsAzure.StorageClient
El segundo paso a realizar, es añadir la entrada del listener de monitor de diagnósticos de Windows Azure en el web.config. Para ello añadimos la siguiente entrada justo después de la sección <configSections>:

  <system.diagnostics>
    <trace>
      <listeners>
        <add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
          name="AzureDiagnostics">
          <filter type="" />
        </add>
      </listeners>
    </trace>
  </system.diagnostics>


Finalmente, en el tercer paso agregamos la clase WebRole que hereda de RoleEntryPoint:

Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports Microsoft.WindowsAzure
Imports Microsoft.WindowsAzure.Diagnostics
Imports Microsoft.WindowsAzure.ServiceRuntime

Public Class WebRole
    Inherits RoleEntryPoint

    Public Overrides Function OnStart() As Boolean

        ' Change the transfer period to the Blob
        Dim config = DiagnosticMonitor.GetDefaultInitialConfiguration()
        config.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(1)
        config.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1)
        config.WindowsEventLog.ScheduledTransferPeriod = TimeSpan.FromMinutes(1)

        ' Enable collection of crash dumps
        Microsoft.WindowsAzure.Diagnostics.CrashDumps.EnableCollection(True)

        DiagnosticMonitor.Start("DiagnosticsConnectionString", config)

        ' For information on handling configuration changes
        ' see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
        AddHandler RoleEnvironment.Changing, AddressOf RoleEnvironmentChanging

        Return MyBase.OnStart()

    End Function

    Private Sub RoleEnvironmentChanging(ByVal sender As Object, ByVal e As RoleEnvironmentChangingEventArgs)

        ' If a configuration setting is changing
        If (e.Changes.Any(Function(change) TypeOf change Is RoleEnvironmentConfigurationSettingChange)) Then
            ' Set e.Cancel to true to restart this role instance
            e.Cancel = True
        End If

    End Sub

End Class

Con estas tres sencillas acciones tenemos nuestra aplicación web preparada para ejecutarse como un WebRole. Nótese que se ha añadido código para supervisión de diagnóstico del WebRole, en base a lo que ya escribí hace unos días sobre la supervisión de WebRoles en Azure.

Bueno, ya está convertida la aplicación en un WebRole. ¿Y ahora cómo podemos comprobar su funcionamiento?

Creación del proyecto de servicio en la nube

Antes de desplegarlo, hay que agregar a la solución un nuevo proyecto del tipo "Servicio en la nube"

   1) Pulsamos botón derecho sobre la solución y seleccionamos "Agregar->Nuevo proyecto..."
   2) Seleccionamos de las plantillas de Cloud el tipo de proyecto "Windows Azure Cloud Project"
   3) En la siguiente ventana de incluir roles al servicio, no agregamos ninguno y pulsamos el botón "Ok"
   4) Ahora, pulsando con el botón derecho sobre la subcarpeta Roles, usamos la acción "Add->Web Role project in solution..."
   5) En la ventana se nos presentan todos los proyectos tipo WebApplication que existen en la solución. Seleccionamos nuestro DotNetNukeCommunityWebApp para incluirlo dentro de la configuración del servicio y pulsamos Ok
   6) Pulsamos botón derecho sobre el servicio y seleccionamos el menú "Establecer como proyecto de inicio"


Dejando el resto de los parámetros tal y como vienen por defecto y si tenemos correctamente configurado nuestro entorno de desarrollo de Azure (Development Fabric y Development Storage), estamos listos para hacer la prueba inicial del despliegue.

Iniciando el WebRole en Development Fabric

Una vez que estamos listos para arrancar por primera vez el WebRole, pulsamos F5 para ejecutarlo dentro del entorno de desarrollo. Se despliega automáticamente sobre Development Fabric...



...y luego se abre el navegador...vaya, un error :) No todo iba a ser un paseo...

Errores solucionados para el despliegue

Los errores solucionados no eran muchos, realmente sólo tres, así que los expongo porque son "curiosos". Empecemos de menos a más.

1. Error de .NET trust level

El primero error que me apareció en pantalla era referido fue por un parámetro de configuración en el web.config de DNN. El error en cuestión era el siguiente:

"This configuration section cannot be used at this path.  This happens when the site administrator has locked access to this section using <location allowOverride="false"> from an inherited configuration file"
Line 123: <trust level="Medium" originUrl=".*" />

Esto es lógico porque en el modelo de servicios cloud la configuración de .NET Trust se realiza en la configuración del WebRole. Para evitar este error dentro de Fabric, simplemente hay que comentar en el web.config la línea <trust level=”Medium” orginURL=”.*” /> e indicar el nivel de confianza de .NET en la pestaña de configuración del WebRole:


2. Error de ruta demasiado larga

La siguiente vez que realicé el despliegue, surgió un nuevo error, que me dejó algo preocupado. El error en cuestión se dió cuando al iniciar la aplicación se intentaron cargar archivos que estaban ubicados en una ruta demasiado larga:

“The path is too long after being fully qualified.  Make sure the full path is less than 260 characters and the directory name is less than 248 characters.”

Este límite está impuesto por la WIN32 API y ha sido bastante criticado a lo largo de los años. Como a mí me encanta decir: "NEFASTO!"

Madre mía, ¿y ahora? Tranquilidad...esto le ha tenido que pasar a alguien más. Un segundo de búsquedas después apareció la respuesta en este post en un blog de MSDN.

Por defecto la ruta donde se despliegan los webroles en Development Fabric es en c:\Users\<username>\AppData\Local\dftmp. A partir de ahí se despliega y dependiendo de la profundidad de las carpetas y largo de nombre de archivos este límite es muy fácil de alcanzar, ya que el despliegue le añade a la ruta un "churro" de caracteres que identifican unívocamente al mismo.

Como solución temporal para ganar unos caracteres, podemos establecer la ruta por defecto de los despliegues de Development Fabric en una ruta más corta, por ejemplo en "C:\A". ¿Cómo? Creando una variable de entorno llamada _CSRUN_STATE_DIRECTORY con el valor de dicha ruta.



Con esto por suerte a mí me valió. ¿Qué podemos hacer si en otro proyecto pasa algo similar? Podemos seguir dos estrategias:
  1. Si podemos tocar los nombres de los ensamblados, archivos, etc. renombrar los archivos con nombres más cortos. ¿Una broma? Sí, aunque ganaríamos unos caracteres posiblemente podríamos alcanzar el límite en algún momento -sin contar el estúpido esfuerzo. ¿Alguna otra solución?
  2. Indagando un poco por la red, me encontré con este otro post que aclara que el sistema de archivos NTFS soporta rutas de hasta 32k de largo...32k!!! ¿Cómo? Pues simplemente añadiendo como prefijo los caracteres "\\?\" a la ruta...ale, otra que no sabía. Con esto, podríamos modificar la ruta anterior a "\\?\C:\A" y no habría límite. Lo he probado y no funciona -¡NEFASTO!. Da un error de "Caracteres no válidos" al desplegar sobre Development Fabric desde Visual Studio.

Si tengo alguna novedad sobre el tema, lo pondré como un comentario.

3. Problema con el módulo de UrlRewriteModule
Este tercer error, con el que podría escribir un post entero con más detalle, fue con el único que tuve que retocar algo el código fuente. También fue uno de los que más que me costó detectar, ya que se me pasó en esta fase de desarrollo y realmente lo detecté haciendo una traza con IntelliTrace sobre Azure en la fase posterior.

Una vez detectado, volví al entorno de desarrollo y observé que también se daba con lo que fue ya mucho más fácil corregirlo.

Bueno...déjate de rollos y al grano.

El error en concreto es un fallo de bucle infinito de redirección (DNN Redirect Loop). En resumen es que al abrir cualquier página del portal el navegador se queda redirigiéndose una y otra vez a la página de inicio -con Internet Explorer se queda en bucle, Chrome o Firefox lo detectan y te lo muestra con más detalle.

Lo primero que pensé era un problema con los Alias del portal. Tras repasarlos, pude comprobar que estaban correctamente configurados. Sin ponerme a depurar aún -recuerden que lo detecté cuando estaba publicado en Azure- me puse a buscar los posibles motivos.

La mayoría de los posts eran indicando un problema de versión con la versión de las librerías AJAX. Como cada deploy en la nube me costaba mucho tiempo entre pruebas -mínimo 30 minutos entre cada despliegue- quise comprobar que efectivamente se trataba de lo que comentaban. Fue aquí donde usé IntelliTrace -ya escribiré ún post con el detalle de cómo hacerlo, que no acabamos hoy.

Pues no tenía que ver para nada con las librerías AJAX. Se trataba de la diferencia de resultados que devuelve el método Request.Url.AbsoluteUri que usa el módulo de Rewriting dependiendo de si se ejecuta en la arquitectura Azure o no.

Para que se entienda rápidamente, imaginemos una simple aplicación con una página aspx que en el evento PageLoad tiene el siguiente código:

   Response.Write(Request.Url.AbsoluteUri)


Si se ejecuta fuera del entorno Azure -como una aplicación web normal y corriente- el valor que devuelve coincide con la URL que se está solicitando:


Si ahora lo ejecutamos dentro del entorno de Development Fabric (en Azure pasa lo mismo) el resultado es el siguiente (en Development Fabric se muestra el puerto 5100, en real el puerto usado es el 20000):


¿Por qué devuelve esto? Muy claro. Tal y como se menciona en el foro de Windows Azure, las peticiones en Azure se envían al Fabric Controller, que es la dirección "pública". Luego el controlador envía la petición a una de las instancias de IIS Hosted Web Core que tengan alojado el WebRole -actúa como un balanceador de carga. El problema es que devuelve la URL del Hosted Web Role, no la externa del Fabric Controller.

La solución pasa por utilizar este código en vez del anterior:

Response.Write(Request.Url.Scheme & Uri.SchemeDelimiter & Request.Headers("Host") & Request.RawUrl)



Una vez realizados los cambios en el módulo, se acabaron los problemas. Ya funcionaba todo correctamente.



Quiero más...¡potencia!

Recordando las palabras de Maverick en TopGun -realmente decía "¡Quiero más velocidad!" aunque también me vale- me vino a la mente probar a desplegar más instancias para comprobar las posibilidades del portal adaptado al entorno Azure.

¿Que hace falta añadir máquinas del servicio porque tenemos el portal saturado? ¿Qué hace falta quitar capacidad de proceso porque ya no hacen falta tantas?

Muy fácil. Para eso precisamente está pensada la nube. Vamos al fichero de configuración y modificamos el número o tipo de instancias a desplegar. Pulsamos F5 para desplegar de nuevo en el entorno de desarrollo y listo (he de reconocer que me pasé al agregar 10 instancias, casi me quedo sin memoria física en mi máquina de desarrollo y el disco duro no me paraba de hacer swapping, pero una imagen vale más que mil palabras):


Tarea para el futuro: crear un módulo en DNN para poder realizar todas las configuraciones y modiificaciones de despliegues desde dentro del mismo portal.



Conclusión

Después de algunos errores algo "curiosos", la solución está preparada para su despliegue en Azure. La prueba de desplegar en varias instancias funciona de perillas y deja entrever las posibilidades de tener un CMS en la nube.

El siguiente objetivo estaba cerca: desplegar en la nube.

Como siempre, les dejo el enlace al portal que ya está publicado en Azure para que vayan viendo las evoluciones:

lunes, 8 de noviembre de 2010

DotNetNuke en Azure: convirtiendo el WebSite en una WebApplication

Hoy vamos a continuar con el diario de bitácora de la migración de DotNetNuke a la plataforma Azure justo donde lo dejamos después de dejar funcionando el WebSite en local con una base de datos remota en SQL Azure.

El siguiente objetivo era hacer un despliegue del gestor de contenidos en la nube, aunque tal y como estaban estructurados los archivos de proyecto no iba a ser una publicación directa. El principal inconveniente era que el portal está concebido como un WebSite (WSP - Web Site Project) en vez de una WebApplication (WAP - Web Application Project). Los WSP no están soportados en Azure sino los WAP que tengan una clase que herede de WebRole, con lo que había que hacer un trabajo de conversión.

WebSites vs WebApplications

Antes de comenzar con la conversión, lo primero que me vino a la mente fue buscar el motivo de porqué DNN, que estaba actualizado a los últimos Frameworks de .NET y que ha evolucionado acorde con la tecnología, seguía usando un modelo de proyectos que, aún siendo soportado hoy en día, desde 2006 estaba en desuso. Busqué algo de información en los foros y encontré un post con la misma cuestión, y resuelto con estos motivos:
  • Porque es más fácil hacer cambios: esto es cierto, ya que no hay que recompilar todo el sitio si se hace una modificación en código, aprovechando las características de compilación dinámica de ASP.NET. Realmente no me preocupaba, ya que esto en Azure "no se puede hacer" y lo tenía asumido. Esto es debido a que no se tiene acceso remoto a las instancias de WebRoles para poder modificarlos (por lo menos hasta que salga el nuevo role de Virtual Machine, pero como expliqué en la introducción, no era mi intención usarlo).
  • Por historia: cuando salió en 2006 el modelo de WAP, se había hecho ya mucho esfuerzo en migrar DNN a ASP.NET 2.0 con el modelo WSP, por lo que se decidió seguir con él. Comentan que según Microsoft no hay diferencias significativas de rendimiento y escalabilidad entre los dos modelos. En esto último difiero totalmente. Desde que salió ASP.NET 2.0 en la empresa en la que trabajo estuvimos sufriendo el rendimiento en los proyectos que teníamos como WebSites, sin contar con los problemas de integración con TFS al no tener archivo de proyecto y para qué hablar del infierno de las referencias. Cuando surgió de nuevo el modelo WAP -que existió en VS2003 y que por una mala decisión de Microsoft inicialmente no lo incluyeron cuando salió VS2005-, después de muchas pruebas de stress, rendimiento y comparación entre los dos modelos, decidimos migrar todos los proyectos WSP que teníamos a WAP. Las mejoras fueron notables, no sólo en la integración con nuestras herramientas de control de código fuente y tiempos de desarrollo, sino en los tiempos de compilación y ejecución en producción.
En esta dirección de MSDN podéis ver una comparación de los dos tipos de proyectos por si alguien tiene más interés en el tema.

Finalmente, alguién preguntó en los foros de DNN cómo convertir el proyecto en una WebApplication y se dieron directrices con enlaces a MSDN de cómo llevar a cabo la migración, aunque se advertía que habría que realizar este proceso cada vez que surgiera una actualización.

Asumido.

Convirtiendo el proyecto

Para convertir el proyecto en una WebApplication, hay muchas guías para hacerlo como el enlace de MSDN que puse dos párrafos atrás. Aquí dejo otro enlace de una guía que seguí en su momento para convertir todos los proyectos que teníamos en el trabajo.

Como el objetivo no es escribir un artículo de cómo convertir WSPs en WAPs, sino comentar lo que me encontré en la conversión, detallo todo el proceso que seguí con DotNetNuke.

Paso 1: agregar a la solución un proyecto nuevo tipo WebApplication

La mejor estrategia para migrar un WebSite a un WAP es crear un proyecto en blanco en una carpeta por separado para evitar tener que estar cambiando los ficheros existentes. Para hacerlo:
  1. Pulsamos con el botón derecho sobre el archivo de solución y seleccionamos el menú "Agregar->Nuevo proyecto".
  2. Seleccionamos el tipo de proyecto "Aplicación web vacía de ASP.NET" e introducimos, el nombre de proyecto, por ejemplo, "DotNetNuke.WebApplication"
  3. Una vez creado eliminamos el archivo "web.config" que se añade por defecto. La solución tenía la siguiente pinta:

Paso 2: establecer las referencias del proyecto

El siguiente paso es agregar las mismas referencias que tiene el website a nuestro nuevo proyecto. Para ello:
  1. Pulsamos botón derecho sobre el WebSite y seleccionamos "Páginas de propiedades". En la seccion de referencias nos anotamos las referencias que usa el website y si son a ensamblados o a proyectos -la técnica del Alt-PrintScreen + Pegar en el paint suele ayudar mucho para ir revisando luego el siguiente paso.
  2. Vamos añadiendo una a una a nuestro nuevo proyecto todas las referencias. Las que son a ensamblados, hacemos que apunten a la carpeta "bin" del WebSite, para asegurarnos de tomar la misma versión.
  3. Luego compilamos el proyecto y verificamos que todas las referencias están funcionando correctamente
Uno de los problemas que me encontré fue que el proyecto WebApplication que acaba de agregar tenía configurado como Framwork destino el 4.0. Al añadir referencias de proyecto de otra versión de Framework, salta una advertencia indicando que no es posible combinar distintos motores en tiempo de ejeucución y que la referencia iba a ser de archivo. Para no tener problemas, reconfiguré el WebApplication a Framwork 3.5 que es el mismo que el que tienen los proyectos del DNN, aunque más adelante cuando publiqué en Azure las establecí todas a 4.0 -esta última explicación la dejo para el capítulo correspondiente.

Paso 3: copiar los ficheros desde el WebSite al nuevo proyecto WebApplication

El siguiente paso en la migración es copiar los archivos del proyecto WebSite a nuestra WebApplication. Para esta tarea, la solución más sencilla es copiar y pegar todos los ficheros dentro de nuestro proyecto. Hay que tener en cuenta que en este punto todavía los ficheros no han sido convertidos y la estructura de carpetas es similar a la que está en el proyecto WebSite.

En este momento, tenemos la WebApplication con una copia de todos los archivos del WebSite. Hay que tener en cuenta que una de las diferencias de los dos tipos de proyectos es que el IDE de Visual Studio crea dinámicamente una clase parcial para cada página con la extensión ".designer.vb", lo que permite tiempos de compilación mucho más rápidos. En este momento los ficheros no tienen esta clase parcial generada, además de que se puede observar que en los tags de declaración de los archivos con extensión aspx|ascx|master que se sigue usando el tag "CodeFile" en lugar del "CodeBehind".

Hay que tener en cuenta que se puede tener una WebApplication con mezcla de estas dos técnicas (yo denominaría esta técnica WSAP! o "Web Site Application Projects") en los que podemos tener páginas con CodeFile para aquellas que querramos modificar en el entorno de producción sin tener que recompilar toda la aplicación. Yo utilizaría estas páginas como excepción, no como norma, debido al rendimiento de las mismas así como muchos otros factores ya comentados.

Paso 4: convertir los archivos del proyecto

Para generar todas estas clases parciales seguimos un sencillo proceso:
  1. Pulsamos con el botón derecho sobre el nodo de la WebApplication y seleccionamos el comando "Convertir en aplicación web"
Tras unos minutos -el proyecto tiene bastantes archivos- esta acción hará que se examine recursivamente cada página, control de usuario y página maestra en el proyecto, generando automáticametne el fichero .designer.vb sociado a cada una de ellas, además de cambiar el atributo "CodeFile" por el "CodeBehind".

Además, se renombrará la carpeta App_Code por Old_App_Code para evitar la doble compilación de los archivos que estén en dicha carpeta. Si se dejara el mismo nombre de carpeta la clase sería compilada dos veces, una durante la compilación del proyecto y otra dinámicament en tiempo de ejecución, lo que resultaría en errores típicos de "no se pudo cargar el tipo". En nuestro caso, los dos únicos archivos que estaban en dicha carpeta "Global.asax.vb" y "AssemblyInfo.vb" fueron reubicados a sus carpetas correspondientes (en el root y en "My Project").


Paso 5: añadir espacios de nombres

El último paso antes de comenzar a ejecutar es corregir los errores que nos han surgido en la ventana de Lista de Errores. El más repetitivo de todos ellos es el del problema con los espacios de nombres.

Hay que tener en cuenta que los archivos que hemos copiado del WebSite por defecto no tiene un espacio de nombres a no ser que se indíque explícitamente en código. Esto es obvio ya que no existe archivo de proyecto. Para evitar este error y respetar los mismos espacios de nombres que tenía el WebSite, quitaremos el espacio de nombres del WebApplication:
  1. Pulsamos con el botón derecho sobre el nodo del WebApplication y seleccionamos "Propiedades". En la pestaña "Aplicación" dejamos en blanco la caja de texto "Espacio de nombres raíz".
Del mismo modo, puede que se hayan añadido espacios de nombres en el WebSite que no hayan sido contemplados en nuestro nuevo WebApplication. Para agregar estos espacios de nombres:
  1. Abrimos el archivo web.config y buscamos la cadena de texto "<namespaces>", anotando todos los espacios de nombres
  2. Pulsamos con el botón derecho sobre el nodo del WebApplication y seleccionamos "Propiedades". En la pestaña "Referencias", agregamos todos los espacios de nombres que estaban en el paso anterior
Paso 6: compilar y comprobar funcionamiento

Una vez realizados todos estos pasos y solucionado algún error menor con algún namespace "peleón", la ventana de errores estaba vacía. Así que dando un doble salto mortal le dí al botón de generar aplicación web e inicié la aplicación en el navegador.

Lo primero que me di cuenta es que cada vez que se iniciaba la aplicación el portal me redirigía a la aplicación antigua. Después de leer algo y ver la configuración del DotNetNuke, me di cuenta de la utilidad de los alias en el portal -perdón a los expertos en DNN, ya comenté que no tengo experiencia en el portal :P

Para añadir un alias con la nueva URL a la WebApplication, existen dos formas que yo conozca:
  • Añadiéndola a través del propio interfaz del portal, en herramientas de Host>Porltal>Aliases
  • Añadiendo un registro en la base de datos en la tabla dbo.dnn_PortalAlias
Una vez añadido el registro, hay que hacer que la aplicación web se reinicie porque estos datos son cacheados durante el inicio de la aplicaicón. Para ello, basta por ejemplo escribir un espacio en el web.config y guardarlo.


NOTA: aparte del nuevo alias en la imagen se ven más, que corresponden a la publicación en Development Fabric y el sitio real en Azure. La captura la he hecho una vez que lo he publicado todo.

Ya teníamos convertido el WebSite en una WebApplication


Conclusión

Convertir el sitio web en una aplicación web era un paso necesario para poder publicar un WebRole en Windows Azure. Aunque realmente en este paso no se ha hecho ninguna tarea de recodificación, era un paso necesario para llevar a cabo la migración.

Una vez realizados estos pasos, el siguiente era inminente: convertir la WebApplication en un WebRole y probarlo con el SDK en Development Fabric.

Hasta aquí el capítulo de hoy. En el próximo más.

Como siempre les dejo el enlace al portal que he publicado en Azure para que vayan viendo la evolución.

Related Posts Plugin for WordPress, Blogger...