martes, 2 de julio de 2013

SAP propone Apache™ Olingo para Apache™ Incubator

Olingo

Recientemente se ha confeccionado ​la propuesta del proyecto Apache Olingo para dar continuidad a la implementación en Java de la ​versión 2.0 de ​OData hecha por ​SAP. Anteriormente la librería era desarrollada en ​su sitio de Github. Los objetivos consisten en actualizar el soporte para las versiones ​3.0 y ​4.0 del estándar. La propuesta inicial de integrantes consiste en empleados de SAP. Es por esto que la diversidad es uno de los temas fundamentales a considerar con vistas a la graduación del proyecto. Todo esto coincide en el tiempo con un desarrollo similar que llevo a cabo para ​Apache™ Bloodhound. Sin embargo, en los planes iniciales de Apache Olingo no se considera el desarrollo de una librería para Python.

Acerca de Apache™ Incubator

Es posible contabilizar más de 100 proyectos en el ecosistema de la ​Apache Software Foundation. ​Apache™ Incubator es el punto de partida en el camino a convertirse en un proyecto oficial de la fundación.

lunes, 1 de julio de 2013

La estrategia de Oracle en el segundo trimestre del 2013

Mark Hurd

Al cierre del segundo trimestre del año 2013 ​Oracle está agitado. Repentinamente se han suscitado una serie de eventos que, al menos a mí, me llaman la atención. Sin más preambulos comienzo la historia. Le invito a ​suscribirse a este blog para estar al tanto de otras noticias interesantes acerca del mundo de la informática.

La confrontación en al área del hardware

Este realmente es un capítulo en retrospectiva que permitirá entender mejor la historia (más reciente) que viene a continuación. Después de la ​adquisición de Sun Microsystems Oracle heredó la competencia que esta compañía sostenía con varios rivales en el sector del hardware. Uno de ellos resulta ser ​Hewlett-Packard. En el año 2011 ​Oracle anunciaba descontinuar sus desarrollos para Itanium. De más está decir que Intel y HP hicieron sus declaraciones al respecto ... en fin todo un culebrón. Se rompían así relaciones de negocios y líneas de cooperación que duraron más de 20 años. Este paso era de esperar pues Oracle contaba con la línea de hardware SPARC (RISC). Sun llegó a ser el mayor distribuidor de servidores RISC e Itanium en el mercado Unix con una participación estimada del 41.3% del mercado. Además HP ya en ese momento utilizaba casi toda la gama de procesadores Itanium en sus servidores Integrity Unix , sus soluciones NonStop y OpenVMS. La otra cara de la moneda era que las aplicaciones de Oracle eran el software más frecuentemente utilizado en la plataforma HP-UX (Unix). Este sistema operativo también era otro motivo de competencia con las soluciones basadas en Linux y Solaris que otrora fueron el motivo de otra disputa entre Sun y HP por la definición del futuro de Unix.

La historia continúa. Mark Hurd ex-CEO de HP fue contratado para el cargo de Presidente de Oracle. En los primeros días de junio de este año se presentó en el ​Dell Enterprise Forum para anunciar la alianza estratégica con ​Dell. El pacto consiste en llevar el software de sistema y aplicaciones negocios de Oracle al mercado pre-instalado en los servidores Dell de plataforma x86. De más está decir que el archirrival de Dell en el negocio de los servidores x86 resulta ser: HP. Se ha virado la tortilla (omelette).

Una ... ¿sorpresa?

Para continuar, el día 24 de junio 2013 anuncian una alianza estratégica con ​Microsoft. Si alguien me hubiera dicho esto en los tiempos de la ​adquisición de Sun Microsystems no lo creería. Después de este evento ambos gigantes quedaban como competidores directos en no pocos sectores. Además de todo esto las tecnologías y enfoques de ambos son notablemente ortogonales, aunque existen puntos de contacto.

En una conferencia de prensa se reunieron Steve Ballmer y Mark Hurd para anunciar esta nueva alianza. La misma consiste en que Oracle certificará y dará soporte a sus aplicaciones, plataformas y bases de datos para ejecutarlos en la plataforma Windows Azure y en los entornos de virtualización Hyper-V. Las distribuciones de Linux de Oracle también serán cerificadas para Hyper-V. Todo esto viene acompañado la posibilidad de que las licencias ya expedidas para Windows Server serán válidas también para Windows Azure. Microsoft, entre otras cosas, ofrecerá una versión completamente certificada de Java para Windows Azure. Para los usuarios que no posean licencias de Oracle en este momento Microsoft añadirá en la galería de imagenes de Windows Azure servicios de infraestructura con configuraciones que incluyen la base de datos de Oracle, WebLogic Server y Java.

Algunos productos de Oracle ya tenían una presencia notable en Windows, así que hasta aquí todo relativamente bien ... Lo más llamativo para mí fue que también se ofrecerán en Windows Azure instancias pre-configuradas de la distribución de Linux de Oracle con aplicaciones pre-instaladas de la misma compañía.

Aplicaciones empresariales en la nube

Recuerdo que hace un tiempo atrás ​Salesforce.com fue una de las compañías que más temprano y con mayor decisión desarrolló sus productos sobre la plataforma Google App Engine. Fue todo un acontecimiento mediático del momento. El día 25 de junio del 2013 se da a conocer ​una alianza por un período de nueve años durante los cuales la compañía estandarizará sus propuestas para correr sobre la base de datos, el sistema operativo Linux, la implementación y plataformas de Java y los servidores de base de datos Exadata ... de Oracle. Estos dos gigantes en el sector de aplicaciones empresariales también han acordado integrar la solución CRM de Salesforce.com y otras aplicaciones en la nube con Oracle's Fusion HCM y aplicaciones ​SaaS de Oracle en el sector de las finanzas. Salesforce.com adoptará todas estas tecnologías de Oracle en su infraestructura para desarrollar su propio negocio. La historia y el presente recogen la lucha en el campo de CRM entre estos dos actores de la tecnología y el software. Incluídas están varias declaraciones controvertidas como las de Larry Ellison (CEO de Oracle) en el Oracle OpenWorld 2010 cuando expresó que ​Saleforce.com no era una compañía de cloud computing.

Por otra parte, más esperado fue el ​acuerdo con Netsuite concretado el 26 de junio del 2013. Larry Ellison es el pricipal accionista de NetSuite. Oracle integrará sus aplicaciones y servicios en la nube para ​HCM con el ​ERP de NetSuite.

La repercusión directa de estas dos acciones apunta a hacerle frente a la competencia de SAP en el terreno de aplicaciones empresariales.

Conclusiones

Realmente en el 2011 veía muy lejana la visión de Peter Katz (CTO de PKA Technologies en ese momento) cuando mencionaba con respecto a la competencia de Oracle que después de comprar a Sun estaba en una posición de dar soporte a IBM y ayudar a Microsoft y Red Hat considerando a estos tres últimos como ganadores desplazados. Todo esto se ha concretado de manera acelerada después de conocer los detalles ​del resúmen del año fiscal de Oracle. A la lista se suman Google, HP, SAP ... y no me extrañaría que otros. Oracle tiene una visión clara de sus perpectivas considerando sus fortalezas actuales.

Tres días, tres alianzas. Nada ... que si le añadimos a todo esto una historia de amor y un poco de efectos especiales Hollywood y O'Globo tienen suficiente material para dos películas y una telenovela.

martes, 25 de junio de 2013

¿34000 qué?

 34000 visitas

El pasado día 14 de junio del 2013 a las 4:02 am -5GMT estaba tratando de redactar un artículo para mi blog. Coincidentemente mis ojeras descubrieron que el número de visitas había ascendido a 34001. Así que esta breve nota tiene como objetivo felicitar a todos aquellos que siguen interesados en los temas que se discuten en este blog. Espero que el interés se incremente porque realmente ahora es que empieza la mejor parte. Le invito a ​suscribirse mediante RSS para que no se pierda los próximos artículos acerca de varios temas interesantes en las ramas de la cibernética, edición de video, software libre, temas jurídicos, economía, música, lingüística, un poco de filosofía no muy elevada ... y hasta los temas de su preferencia. Todo es posible ... simelo pides :).

Desde hace tiempo he deseado hacer resúmenes semestrales de la actividad de mi blog parecidos al ​reporte del inicio del año 2011 y ​el reporte del primer trimestre del año 2011. Sinceramente no he tenido mucho tiempo ... pero ya se me ocurrirá algo al respecto.

lunes, 24 de junio de 2013

El (posible) significado de los números de versiones

Semantic versioning

A continuación les ofrezco unos comentarios acerca de un enfoque llamado ​semantic versioning. Esta guía ha sido formalizada por ​Tom Preston-Werner (inventor de ​Gravatar y co-fundador de ​Github) para lidiar con las dependencias de las aplicaciones de software. Muchas veces leí en las conversaciones de la lista ​bloodhound-dev@incubator.apache.org que los ​números de las versiones son ''baratos''. Para un proyecto que está en su fase inicial este consejo creo que es válido. Sin embargo, en mi opinión se deben considerar otras variantes para desarrollos con mayor madurez que implican un número considerable de usuarios. De gran importancia es este tema para librerías que son utilizadas muy frecuentemente para desarrollar distintos tipos de software.

¿Qué es el versionado semántico?

La ​versión 2.0.0 define este sistema de numeración de versiones de la siguiente manera:

  1. Cada versión se identifica utilizando tres números separados por punto MAJOR.MINOR.PATCH
    e.g. 2.3.1
  2. Los números de las versiones sucesivas se incrementan considerando las siguientes
    reglas generales
    1. Se incrementa MAJOR cuando se realizan cambios incompatibles en la API,
    2. Se incrementa MINOR cuando se añaden nuevos elementos compatibles con versiones anteriores,
    3. Se incrementa PATCH cuando se corrigen errores y el resultado es compatible con versiones anteriores.
  3. Se permiten ciertos calificadores para distribuciones todavía en desarrollo
    (e.g. alpha, beta, release candidate, ...)

¿Para qué sirve?

El objetivo fundamental consiste en prevenir, o al menos tener la capacidad de detectar casos del fenómeno conocido como ​dependency hell. En el ámbito de la ingeniería de software es muy importante poder hacer algo al respecto mientras se desarrollan sistemas complejos con gran número de dependencias. Bajo este esquema los números de versiones y la manera en que se asignan ofrecen rápidamente una información valiosa acerca del código y la compatibilidad de las mejoras incorporadas de una versión a la siguiente.

Ejemplo : La aplicación A se construye utilizando la versión 2.3.6 de la librería L.
Los usuarios finales la instalan de forma automática desde un repositorio que maneja las
relaciones entre los diferentes paquetes de software disponibles, quizás compilándolos en
tiempo de instalación. Como la librería L respeta los términos del versionado semántico
y la compatibilidad entre las versiones de la rama 2.x.x entonces los autores de la aplicación A
pueden especificar las restricciones L>=2.3.6 , L<3.0.0. En este rango de versiones
los autores de la librería L crean la expectativa de mantener compatibilidad en la API con las consecuentes garantías para permitir el correcto funcionamiento de A.

En mi experiencia como programador y arquitecto de sistemas considero útiles los puntos siguientes:

  • Punto 5: La versión 1.0.0 define la primera API pública estable.
  • Puntos 9, 10, 11: El estándar no impone un significado especial para las versiones de prueba.
    Existen modelos que le asocian un significado también a estas distribuciones intermedias, por ejemplo
    el ​esquema de versiones de ​Apache™ Subversion.
  • Se recomienda que la caducidad de una parte de la API se debe ofrecer inicialmente en una versión
    que incremente el número MINOR para que las dependencias puedan prepararse para adoptar versión
    subsecuente que incremente el número MAJOR.

Conclusiones

Existen otros esquemas para numerar las versiones. ​Apache™ Bloodhound no adoptó el versionado semántico. En este caso se consideró el número MAJOR como una señal. Es por eso que la próxima versión será la 0.6.0 a pesar de que es substancialmente diferente a (y en momentos incompatible con) las versiones precedentes; en especial definiendo la API pública de la solución multi-productos.

Sin embargo recomiendo mucho el uso del versionado semántico, el cual empleo en otros proyectos. Para estar al tanto de su utilidad es posible ​suscribirse mediante RSS.

viernes, 14 de junio de 2013

Tutorial de LD_PRELOAD, segunda parte

man ld.so

Un ​artículo previo mostraba cómo remplazar una función de la librería estándar de C con una versión personalizada. Esta nota explica lo que es preciso hacer para invocar la función original desde la nueva función.

Comencemos por recordar el ejemplo presentado anteriormente. Todo consistía en un programa llamado prog.c que invocaba la función fopen.


#include <stdio.h>

int main(void) {
    printf("Calling the fopen() function...\n");

    FILE *fd = fopen("test.txt", "r");
    if (!fd) {
        printf("fopen() returned NULL\n");
        return 1;
    }

    printf("fopen() succeeded\n");

    return 0;
}

¿Cómo hacer entonces una función que pueda remplazar a fopen y al mismo tiempo sea capaz de invocar la función fopen de la libraría estándar de C? Veamos el código de myfopen.c.


#define _GNU_SOURCE

#include <stdio.h>
#include <dlfcn.h>

FILE *fopen(const char *path, const char *mode) {
    printf("In our own fopen, opening %s\n", path);

    FILE *(*original_fopen)(const char*, const char*);
    original_fopen = dlsym(RTLD_NEXT, "fopen");
    return (*original_fopen)(path, mode);
}

Como se puede apreciar la librería exporta la versión personaizada de la función fopen. Prestando atención se puede constatar cómo se obtiene la referencia a la función original pasando el símbolo RTLD_NEXT a dlsym. Es muy importante definir el símbolo _GNU_SOURCE para tener acceso a RTLD_NEXT en dlfcn.h. De esta forma se coninua la resolución del símbolo en cuestión en el orden de búsqueda a continuación de la librería actual. La compilamos de la siguiente manera:

$ gcc -Wall -fPIC -shared -o myfopen.so myfopen.c -ldl

Al ejecutar el comando de ejemplo en cuestión con ayuda de la variable de entorno LD_PRELOAD, esto es lo que se obtiene:

$ LD_PRELOAD=./myfopen.so ./prog
Calling the fopen() function...
In our own fopen, opening test.txt
fopen() succeeded

Este truco es realmente útil para cambiar el funcionamiento de partes del sistema o depurar detalladamente ciertos detalles. Le invito a ​suscribirse mediante RSS para que no se pierda los próximos artículos de esta serie.

jueves, 30 de mayo de 2013

MetaModel y BeanShell propuestos para Apache™ Incubator

Apache™ Incubator

Es posible contabilizar más de 100 proyectos en el ecosistema de la ​Apache Software Foundation. El ​Apache™ Incubator es el punto de partida en el camino a convertirse en un proyecto oficial de la fundación. Recientemente se han propuesto dos proyectos interesantes. La primera ​propuesta que quería mencionar es la de ​BeanSheall, uno de los lenguajes de programación utilizado para escribir macros en ​Apache™ Open Office™. Este último ya es un proyecto oficial de la fundación; razón por la cual se podría justificar la incorporación directa a este proyecto en vez de pasar por todo el proceso de incubación. Quizás se justifique más incorporarlo en ​Apache™ Commons debido a que este proyecto ha estado relacionado con ​Apache™ Maven y ​Apache™ JMeter desde hace varios años.

La segunda ​propuesta es ​MetaModel; un framework muy interesante que provee una interfaz común para acceso, exploración y consulta de diferentes tipos de fuentes de datos. Entre los objetivos iniciales del proyecto se menciona establecer vínculos con otros proyectos de primer nivel como ​POI, ​Gora, ​HBase y ​CouchDB. Resulta interesante saber que estas dos tecnologías podrían incorporarse próximamente al ecosistema de la ASF, por lo que les invito a ​suscribirse mediante RSS a este blog si está interesado en conocer más acerca del futuro de ambos.

miércoles, 29 de mayo de 2013

Proyectos de Apache™ Bloodhound en el Google Summer of Code 2013

GSoC 2013

El 27 de mayo de 2013 es la fecha en que se determinaron las propuestas que se aceptarían como parte del Google Summer of Code. En total este año se han aceptado 1,192 propuestas de proyectos de estudiantes de varias latitudes. Hasta el momento se han confirmado tres proyectos relacionados con ​Apache™ Bloodhound

Los proyectos son :

  1. ​Customizable time series reports
    por ​Pranay B. Sudre
    • en este caso espero poder estar apoyando el trabajo con fuentes de
      datos que permitan representar las tendencias en líneas de tiempo
      anotadas.
  2. ​Embeddable tickets/objects por ​Antonia Horincar
    • Esta es una oportunidad muy buena para continuar el trabajo de José Angel Franco
      acerca de una API de servicios REST para los recursos de Trac y
      Bloodhound
  3. ​Add time series reports for Bloodhound por ​Hua Xiang
    • mi colaboración en este caso puede ser relativamente similar a la
      del primer proyecto.

Le invito a ​suscribirse mediante RSS a este blog si está interesado en conocer los que acontece con estos proyectos. Espero que haya más noticias pronto acerca de ​las propuestas restantes.

PS: Otras organizaciones han propuesto proyectos interesantes como ​este acerca de RTEMS un sistema operativo de tiempo real y código abierto; o ​las propuestas del W3C. Sospecho que hay más detalles en ​la lista completa de proyectos aceptados.

lunes, 27 de mayo de 2013

Knockout.js ... lo que Usted no vió

KnockoutJs banner

Le dediqué un tiempo a conocer más acerca del patrón ​MVVM . Me agrada, así que se suma a la lista de tecnologías relacionadas con Microsoft que realmente recomiendo. Este es un enfoque propuesto por la compañía que consiste, según sus propios autores, en una especialización del enfoque ​Modelo Vista Controlador para tecnologías como Windows Presentation Foundation y Silverlight. En la ingeniería de software este tipo de soluciones resulta muy útil para construir interfaces de usuario. Su ámbito de aplicación se ha extendido también al ​framework ZK (del cual tengo muy buenas referencias) y a HTML5. Incluso existe ​Google mdv, una variante relacionada con estos temas. En mi caso particular puse mi atención en la implementación para Javascript conocida como ​KnockuotJs. En esta ocasión no pretendo comentarles las peculiaridades de su uso . Para esto les recomiendo leer ​este artículo y la ​documentación de KnockoutJs. Más bien pretendo comentarles algunos detalles que me llamaron la atención al probar los ​tutoriales.

Dependencias y <select />

KnockoutJs tutorial 1

Al terminar con el primer tutorial debe quedarnos como resultado un modelo más o menos como el que se muestra a continuación.

// This is a simple *viewmodel* - JavaScript that defines the data and behavior of your UI
function AppViewModel() {
    this.firstName = ko.observable("Bert");
    this.lastName = ko.observable("Bertington");

    this.fullName = ko.computed(function() {
        return this.firstName() + " " + this.lastName();    
    }, this);

    this.capitalizeLastName = function() {
        var currentVal = this.lastName();        // Read the current value
        this.lastName(currentVal.toUpperCase()); // Write back a modified value
    };
}

// Activates knockout.js
ko.applyBindings(new AppViewModel());

A continuación se muestra la vista relacionada después de añadir un elemento <select /> conectado con el atributo lastName del modelo.

<!-- This is a *view* - HTML markup that defines the appearance of your UI -->

<p>First name: <strong data-bind="text: firstName">todo</strong></p>
<p>Last name: <strong data-bind="text: lastName">todo</strong></p>
<p>First name: <input data-bind="value: firstName" /></p>
<p>Last name: <input data-bind="value: lastName" /></p>
<p>Full name: <strong data-bind="text: fullName"></strong></p>
<button data-bind="click: capitalizeLastName">Go caps</button>

<p>Last name: 
  <select data-bind="value: lastName" >
      <option value="x">Pérez</option>
      <option>Suárez</option>
      <option value="z">García</option>
      <option>Bertington</option>
      <option>BERTINGTON</option>
  </select>
</p>

En este punto me resultó muy interesante que la librería preserva automáticamente la consistencia del modelo teniendo en cuenta los bindings. Esta es la razón por la cual el botón Go caps solo funciona cuando el apellido es Bertington . La razón es que el binding con el combobox limita el número de valores que se le puede asignar al atributo del modelo. En el ejemplo el valor mencionado es el único que tiene también una opción con las letras mayúsculas.

Las listas y <select /> ... otra vez …

KnockoutJs tutorial 2

Pasando la página (literalmente ;) llegamos al segundo ejemplo que trata sobre los bindings para listas y colecciones de objetos. Lo que se muestra es impresionante y se completa cada paso satisfactoriamente; pero ... hay (al menos) un detalle muy sutil que se escapa. Utilizando ​Firebug, ​DragonFly o una herramienta similar es posible constatar que el atributo value de los elementos <option /> utilizados para escoger el menú siempre está asignado a una cadena vacía (al menos en las versiones de Opera, Firefox y Google Chrome que utilicé para probar ...). Con el fin de enviar los datos hacia el servidor es posible que sea útil asignar ciertos identificadores. Para lograr ese objetivo en la versión final es posible añadir en el model el atributo mealId

// Class to represent a row in the seat reservations grid
function SeatReservation(name, initialMeal) {
    var self = this;
    self.name = name;
    self.meal = ko.observable(initialMeal);

    self.formattedPrice = ko.computed(function() {
        var price = self.meal().price;
        return price ? "$" + price.toFixed(2) : "None";        
    });
}

// Overall viewmodel for this screen, along with initial state
function ReservationsViewModel() {
    var self = this;

    // Non-editable catalog data - would come from the server
    self.availableMeals = [
        { mealId: "s", mealName: "Standard (sandwich)", price: 0 },
        { mealId: "p", mealName: "Premium (lobster)", price: 34.95 },
        { mealId: "u", mealName: "Ultimate (whole zebra)", price: 290 }
    ];    

    // Editable data
    self.seats = ko.observableArray([
        new SeatReservation("Steve", self.availableMeals[0]),
        new SeatReservation("Bert", self.availableMeals[0])
    ]);

    self.addSeat = function() {
        self.seats.push(new SeatReservation("", self.availableMeals[0]));
    }

    self.removeSeat = function(seat) { self.seats.remove(seat) }

    self.totalSurcharge = ko.computed(function() {
       var total = 0;
       for (var i = 0; i < self.seats().length; i++)
           total += self.seats()[i].meal().price;
       return total;
    });
}

ko.applyBindings(new ReservationsViewModel());

Después es necesario utilizar el binding optionsValue en la vista como se muestra a continuación:

<h2>Your seat reservations</h2>

<button data-bind="click: addSeat">Reserve another seat</button>

<table>
    <thead><tr>
        <th>Passenger name</th><th>Meal</th><th>Surcharge</th><th></th>
    </tr></thead>
    <!-- Todo: Generate table body -->
    <tbody data-bind="foreach: seats">
        <tr>
            <td><input data-bind="value: name" /></td>
            <td><select data-bind="options: $root.availableMeals, value: meal, optionsText: 'mealName', optionsValue: 'mealId'"></select></td>
            <td data-bind="text: formattedPrice"></td>
            <td><a href="#" data-bind="click: $root.removeSeat">Remove</a></td>
        </tr>
    </tbody>
</table>

<h3 data-bind="visible: totalSurcharge() > 0">
    Total surcharge: $<span data-bind="text: totalSurcharge().toFixed(2)"></span>
</h3>

Al aplicar estos cambios se logra generar unos elementos como los siguientes:

<select data-bind="options: $root.availableMeals, value: meal, optionsText: 'mealName', optionsValue: 'mealId'">
  <option value="s">Standard (sandwich)</option>
  <option value="p">Premium (lobster)</option>
  <option value="u">Ultimate (whole zebra)</option>
</select>

¡Urra! ... pero no todo es color de rosa. Como resultado la columna Surcharge deja de actualizarse . Por consiguiente no se muestra el sub-total que se calcula en el último paso. Sin embargo el comando Remove introducido en esa misma etapa sí sigue funcionando. Esto me hace pensar que haya algún problema al calcular alguno de los diferentes tipos de bindings involucrados.

Quizás existe una forma de hacer que vuelvan a funcionar las actualizaciones, pero hasta este momento no la he encontrado. Tampoco he tenido mucho tiempo para profundizar en el tema.

Conclusiones

​KnockuotJs es una librería excelente. Sinceramente preferiría que algunos detalles de los bindings fueran más parecidos al estilo de Genshi. De todas maneras los própositos son diferentes; quizás ni siquiera sea apropiado o posible realizarlo.

Me da la impresión de que no voy a poder dejar de utilizarlo después que lo pruebe en alguna aplicación. La recomiendo. Le invito a ​suscribirse a este blog mediante RSS si desea conocer si descubro algo más en el resto de los tutoriales . En próximos artículos comentaré cómo utilizar esta solución para enriquecer la experiencia de usuario de sus aplicaciones. A pesar de estas pifias los resultados son impresionantes.

miércoles, 15 de mayo de 2013

Apache™ Bloodhound 0.6 : Bootstrap handlers

Apache™ Bloodhound

Rumbo a la próxima liberación de la versión 0.6 de ​Apache™ Bloodhound en este artículo comienzo una serie con el objetivo de presentar las diferentes características que marcan pautas con respecto a las versiones precedentes . Explicaré brevemente su utilidad y funcionamiento. Estimo tener tiempo también para redactar algún que otro tutorial . Espero que me perdonen si no logro satisfacer todas las expectativas . Comprendan que todavía hay muchas cosas por hacer y estoy increíblemente ocupado . Tod@s l@s interesad@s en estos temas pueden mantenerse informados del desarrollo de la serie . Solo deben ​suscribirse mediante RSS .

Hasta el presente ​la arquitectura que me robó tantas noches de sueño ha probado satisfacer el 95% de los requisitos que se plantearon inicialmente . Para conocer los detalles , empezamos por el principio ...

¿Qué son los bootstrap handlers?

Una aplicación web consta de múltiples funcionalidades , secciones y opciones de navegaciones. Por lo tanto todo framework de desarrollo de aplicaciones web contiene un subsistema que se encarga de seleccionar el componente (e.g. clase) responsable por procesar las peticiones HTTP que se envían hacia el servidor. ​Trac y por consiguiente ​Apache™ Bloodhound no son la excepción . En las versiones anteriores (i.e. Bloodhound<0.6 ) el manejo de las peticiones web de ambos gestores de incidencias lo realizaban exactamente las mismas clases exactamente de la misma forma.

En pocas palabras a partir de la versión 0.6 de Apache™ Bloodhound el manejo de peticiones web varía un poco ... y para mejor :) . El siguiente diagrama muestra cómo es que todo esto se lleva a cabo.

Bloodhound bootstrap handlers explained

El primer actor que interviene en el lado del servidor es siempre un servidor web e.g. ​Apache httpd , ​Nginx , ​tracd, ... en fin , cualquier servidor que sea capaz de correr sitios implementados con ​Python. Posteriormente , de ser necesario, se ubican los frontends (gateways) responsables de adaptar las tecnologías del servidor web (e.g. CGI, FastCGI, ...) al estándar WSGI . En todos los casos se llega a la función trac.web.main.dispatch_request , el punto de entrada del manejo de peticiones web de Trac . Hasta este punto Bloodhound solo introduce cambios menores relacionados con el middleware de autentificación de tracd ; nada en especial.

A partir de este punto aparecen las diferencias . El algoritmo de Trac funciona de la manera siguiente:

  1. Trac determina la configuración de los directorios donde están los environments,
    estableciendo si se corren varios dentro de una misma carpeta o uno solo .
  2. Trata de extraer del camino de la URL el nombre del environment al que va
    dirigido la petición e.g. si la URL fuera http://dominio.com/env/something/else
    entonces el camino de la URL sería /env/something/else y el primer componente
    seria el nombre del environment (env en el ejemplo).
    • En caso de no conseguirlo e.g. si la URL fuera http://dominio.com/
      entonces muestra un índice de los proyectos disponibles.
  3. Se instancia el environment al que va dirigida la petición.
  4. Se crea un objeto del tipo trac.web.api.Request
  5. Se utiliza el resto del camino e.g. /something/else para determinar dentro
    de ese environment la instancia de la interfaz trac.web.api.IRequestHandler
    que es responsable de procesar la petición y dar
    una respuesta al cliente.

En la práctica los pasos (2) , (3) y (4) son un poco limitados . La razón por la cual Apache™ Bloodhound introduce los objetos llamados bootstrap handlers es exactamente poder implementar algoritmos personalizados para realizar estos pasos. Como consecuencia los pasos anteriores varían de la siguiente manera :

  1. Bloodhound determina la configuración de los directorios donde están los environments,
    estableciendo si se corren varios dentro de una misma carpeta o uno solo .
  2. En la variable WSGI trac.bootstrap_handler se busca una
    ​definición de entry point (e.g. package.module:object.attribute)
    con el módulo y la referencia al objeto bootstrap handler
    • si no se encuentra dicha instancia se utiliza trac.hooks.default_bootstrap_handler
      como valor predeterminado.
  3. Se ejecuta el método open_environment() del objeto determinado en el paso anterior.
    Como resultado se obtiene :
    • El nombre del environment incluído en la variable trac.env_name
      del entorno WSGI
      • Nótese que el procedimiento puede ser completamente diferente a los pasos
        (2) y (3) de la secuencia anterior
    • El environment debidamente inicializado
      • La implementación predeterminada en trac.hooks.default_bootstrap_handler
        analiza el camino de la URL de manera similar a cómo se hace en Trac .
        La diferencia más notoria consiste en el hecho que las que comienzan con
        /products/ se asocian a ​environments de un producto
        e.g. http://dominio.com/env/products/P1/wiki/TitleIndex se procesaría
        en el contexto del environment del product P1 en el environment env
        mientras que la URL http://dominio.com/env/wiki/TitleIndex es procesada
        por el environment env (global) directamente.
  4. Se ejecuta el método create_request para obtener un objeto
    del tipo trac.web.api.Request o equivalente
  5. Se utiliza el resto del camino e.g. /something/else para determinar
    la instancia de la interfaz trac.web.api.IRequestHandler dentro
    de ese environment que es responsable de procesar la petición y dar
    una respuesta al cliente.

Variantes existentes de bootstrap handlers

El framework ​Routes , inspirado en ​Ruby on Rails , se ha convertido en el estándar para este tipo de enrutamiento de peticiones . En un proyecto que será publicado próximamente se están preparando unas variantes que permiten el uso de este framework para implementar bootstrap handlers para Apache™ Bloodhound. De especial interés resultan los casos en que se utiliza el encabezamiento HTTP Host para identificar los environments a partir del dominio al que va dirigida la petición e.g. http://dominio.com/wiki/TitleIndex para el environment global y http://P1.dominio.com/wiki/TitleIndex para el environment del producto P1 . Otro campo de aplicación es la integración con otros frameworks e.g. ​Pylons , ​Turbogears 2 , ...

Conclusiones

​Apache™ Bloodhound ofrece una versión mejorada del mecanismo que facilitaría tanto despliegues similares a los de Trac como otros basados en sub-dominios , más parecidos al dominio edgewall.org (i.e. babel.edgewall.org, genshi.edgewall.org, trac.edgewall.org) . Todo esto es posible gracias a ​la arquitectura multi-productos ; que ha probado satisfacer el 95% de los requisitos que se plantearon inicialmente para Apache™ Bloodhound .

Solo me queda invitar a tod@s l@s interesad@s en estos temas a ​suscribirse mediante RSS a este blog para estar al tanto de las mejoras que propone este gestor de incidencias .