Artículos

Funciones en Facelets para Spring Security

Created by: Juan (admin) 4 months ago

Breve introducción a Facelets

Facelets es el mecanismo de plantillas empleado por JavaServer Faces (JSF). Esencialmente es un "JSP" mejorado para ofrecer más funcionalidad, convertir el documento en XML estricto y orientarlo totalmente al mundo de JSF.

En un principio Facelets fue el desarrollo de un único programador, que lo ofreció como código abierto y con una documentación bastante buena. En poco tiempo otros desarrolladores lo adoptaron en sus proyectos y pronto pasó a ser empleado como un estándar de facto para JSF. Algunas compañías se unieron también -notablemente JBoss, que desde el comienzo apostó por él en Seam- y rápidamente emplear JavaServer Faces se hizo sinónimo de emplear esta librería.

Finalmente la especificación de JSF 2 lo añadió como el mecanismo de plantillas por defecto, convirtiéndolo en un estándar oficial.

Etiquetas y funciones EL en Facelets

Facelets ofrece un API sencillo y muy limpio para implementar funciones EL. ¿Qué son exactamente "funciones EL"? Código que podemos invocar desde las plantillas de nuestras páginas. Facelets eliminó por completo la posibilidad de añadir scriptlets (fragmentos de código) típicos de las páginas JSP. Muchos desarrolladores -especialmente los menos experimentados- estaban abusando de ellos y las páginas se hacían difíciles de leer y mantener -cuando no introducían directamente problemas de arquitectura-. Facelets limitó ese uso de código puro potenciando el empleo de funciones y etiquetas que el programador podía diseñar fuera de la própia página para ser invocadas desde la misma.

Las etiquetas son exactamente eso: componentes estándar de JSF. Por ejemplo, un caso sencillo de seguridad en donde sólo quisieramos mostrar un contenido a un determinado rol podría ser:

La otra posibilidad sería escribir una función -código que se invocará-. En este caso podría ser:

Spring Security

Desde que la especificación del estándar JEE 6 fue presentada, quedó claro que habría aspectos en que su funcionalidad se solaparía con Spring: la plataforma empresarial de Java había aprendido mucho de SpringSource, pero seguiría un camino distinto. En su implementación actual, la inyección de dependencias es diferente, los APIs obviamente también lo son y, logícamente, las empresas detrás de ambos frameworks compiten en este espacio.

La reacción de Spring está siendo ignorar en parte algunos de los elementos presentes en JEE 6. Ambos frameworks son perfectamente integrables, pero si Spring ha sido siempre un líder en relación a la calidad de integración, se hace extraño ahora encontrar carencias en las librerías de Spring Security para JSF 2, la ausencia de apoyo firme para Facelets o que, en la documentación de uno de sus productos -Spring Roo, en su versión actual (XXX.XXX)- la sección referida a la generación de código para JSF 2 esté totalmente en blanco, los beans que se anotan empleando JSF 2 no son visibles para Spring, etc-.

En el caso concreto de Spring Security, se ofrece un pequeño conjunto de componentes y funciones para gestionar la seguridad. En algunos casos sin embargo se hace necesario ampliarlos y, como se puede ver, es algo trivial.

Una función sencilla

Una función básica requiere dos ficheros: uno en XML con la declaración de la función y otro en Java con la implementación.

El archivo XML debe contener este formato:

Hasta JSF 1.2 http://www.mi-espacio-de-nombres.com/un/path/en/el nombreDeLaFuncion com.juanmedin.facelets.funciones.ClaseDeLaFuncion boolean nombreDeLaFuncion(java.lang.String)

El DOCTYPE varía en función de si estamos empleando JSF 1.2 o JSF 2)

namespaceEs el nombre de este espacio de nombres. Podemos imaginar el espacio de nombres como el identificador único para estas funciones y componentes. Se emplea para evitar que dos funciones desarrolladas con el mismo nombre y parámetros por dos desarrolladores distintos colisionen. Más abajo lo veremos en acción y quedará más claro.

function-name - Es simplemente el nombre la función. Coincidirá con el nombre del método en Java.

function-class Nombre cualificado de la función

function-signature Firma de la función, con los parámetros y el tipo de retorno

Definir una función sencilla -comprobar si un usuario tiene un rol concreto en Spring Security- sería entonces:

	<?xml version='1.0' encoding='UTF-8' ?>
	<!DOCTYPE facelet-taglib PUBLIC
	  "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
	  "facelet-taglib_1_0.dtd">
	<facelet-taglib>    
	    <namespace>http://www.juanmedin.com/spring-security/taglibs</namespace>
	    <function>
	        <function-name>tieneRol</function-name>
	        <function-class>com.juanmedin.security.taglibs.TieneRol</function-class>
	        <function-signature>boolean tieneRol(java.lang.String)</function-signature>
	    </function>
	</facelet-taglib>

La clase que contiene la implementación en Java es sencilla. En nuestro caso la dividiremos en dos partes: la implementación que satisface el contrato de las funciones para JSF (la clase TieneRol) y que delega las tareas en sí mismas a una segunda (XXX)

package com.juanmedin.security.taglibs;

// Imports

public class TieneRol extends TagHandler {

    private final TagAttribute rol;    

    public TieneRol(ComponentConfig componentConfig) {
        super(componentConfig);	

        this.rol = this.getRequiredAttribute("rol");

        if(this.rol == null) {
            throw new TagAttributeException(this.rol, "Tienes que especificar el `rol`.");
        }
    }

    public void apply(FaceletContext faceletContext, UIComponent uiComponent)
               throws IOException, FacesException, FaceletException, ELException {
        
        if(this.rol == null) {
            throw new FaceletException("Tienes que proporcionar un rol. Ahora mismo es null.");
        }

        String roles = this.rol.getValue(faceletContext);
        if(roles == null || roles.trim().isEmpty()) {
            throw new FaceletException("Debes indicar un rol");
        }

        if(isGranted(rols)) {
            this.nextHandler.apply(faceletContext, uiComponent);
        }
    }

    public static boolean tieneRol(String rol) {
        GrantedAuthority[] authorities = TagUtilities.getUserAuthorities();

        for (GrantedAuthority authority : authorities) {
            if(authority.getAuthority().equals(rol)) {
                return true;
            }
        }
        return false;    
    }
}

Mostrar

Java: evolución de la plataforma y los nuevos lenguajes (Scala, JRuby, Cylon, etc)

Created by: Juan (admin) 11 months ago

A raíz de una entrada en la web de JavaHispano sobre unas declaraciones de Gosling en las que decía que poco le importaba ya Java como lenguaje quería comentar de forma más ampliada mi impresión sobre ello.

Lo cierto es que estamos en un punto interesante en la evolución de la plataforma Java: la desvinculación entre la máquina virtual y el lenguaje en sí mismo. Esto es algo que se tenía claro desde el mismo día en que se diseñó pero que no ha comenzado a tener fuerza hasta que han aparecido alternativas creíbles como lenguajes de desarrollo al propio Java.

¿Cómo hemos llegado a esto?

Es difícil emplazar en el tiempo un momento concreto pero sí han existido varios eventos interesantes que parecen haberlo impulsado:

- La lentitud en la evolución de Java como lenguaje. Después de todos los cambios drásticos incorporados en Java 5 poco o nada nuevo llegó en Java 6. La versión 7 se hizo esperar y, con la compra de Sun por parte de Oracle, aún más -y ni hablar de la ya celebre falta de innovación de esta compañía, conocida por su impresionante fuerza comercial pero no por sus alardes técnicos-. Algunas personas se mostraron además partidarias de congelar la especificación del lenguaje -capturado muy bien en el podcast de Java Pose de comienzos del 2008 por Bruce Eckel- frente a quienes creían que debía continuar evolucionando. Era un caldo de cultivo ideal para quienes deseaban nuevas opciones.

- La aparición de otros paradigmas de desarrollo para los que Java no estaba preparado. Y especialmente los lenguajes funcionales en un mundo en donde la concurrencia era cada vez más importante -incluso en las máquinas de usuarios finales-.

- La aparición de Rails como framework para Ruby. Rails comenzó a ocupar desde el principio un espacio que pertenecía hasta el momento a Java y PHP. Su creador, David Heinemeier Hansson -más conocido en la comunidad como DHH-, una persona con opiniones muy fuertes, atacó directamente la complejidad y el coste de los desarrollos en Java. Muchos programadores comenzaron a usar este framework con Ruby, descubriendo este lenguaje de forma activa y las virtudes prácticas de emplear otro tipo de lenguajes más eficientes para el desarrollo Web. Es precisamente la plataforma Java desde donde llegaron una gran número de desarrolladores a Rails. Aunque, obviamente, existió también una corriente crítica con el recién llegado, nadie negó la elegancia y claridad de Rails y Ruby. Era un framework que explotaba las ventajas de un lenguaje muy flexible y cercano al desarrollador de una forma que era imposible de alcanzar desde Java.

A partir de su presentación en sociedad se pudo comenzar a leer todo tipo de opiniones en los blogs de reconocidos desarrolladores y líderes de la industria: defensas a capa y espada, ataques frontales, etc. Lo único cierto es que Rails no fue en forma alguna ignorado. Ahora ya existía una alternativa popular y comercial que mostraba las claras deficiencias de la programación en Java. El daño estaba hecho.

- Se había llevado al límite el lenguaje. Java, siendo diseñado específicamente para ser sencillo, no es tan moldeable como otras alternativas. Desde las primeras aplicaciones, los métodos encadenados (típicos de Hibernate y otras librerías y frameworks) para formar DSLs, la inclusión de complejos ficheros XML como pseudo-lenguajes para suplir las carencias existentes y los usos creativos de su capacidad de introspección, se había llegado al techo. Lo que se estaba viendo era lo que permitía el lenguaje y no era sencillo ir más allá.

El resultado en cualquier caso fue el sentimiento de que se escribía demasiado código en Java, el código no era tan legible como podría ser, no cubría los nuevos paradigmas de desarrollo, y por otro lado gestionar los DSL's camuflados como XML era un infierno. Si bien eso ya se sufría desde hacía tiempo, ahora había otros lenguajes y frameworks con aplicaciones en producción  que facturaban millones para demostrarlo. Y, desde luego, siempre ha existido un deseo por explorar y avanzar en la comunidad Java. Que sería sin ese "deseo patológico por la complejidad" en la comunidad Java del que hablaba Rod Johson hace poco.

¿Por qué el valor de un nuevo lenguaje en concreto para la JVM?

Varias razones:

- El valor de la marca 'Java' es indiscutible. Sobre todo en grandes corporaciones y la Administración. Se identifica como algo seguro, consolidado. Si en los 80 era típico el "nadie ha sido nunca despedido por contratar IBM" y en los 90 "Tampoco nadie ha sido nunca despedido por contratar Microsoft" durante la primera década del 2000 lo mismo era aplicable con Java como plataforma corporativa de desarrollo.

- Un conjunto de librerías disponibles increíblemente alto. Junto con C, Java es uno de los lenguajes con mayor número de librerías disponibles. Su número, en prácticamente cualquier escenario, es simplemente abrumador.. El coste de penetración de un nuevo lenguaje es absurdamente alto si hay que desarrollar todo desde cero pero, si es posible emplear la impresionante base de código existente (de la misma forma en que Ruby o Pythonemplean librerías en C), el escenario es completamente distinto.

- Facilidad de desarrollo entre diferentes arquitecturas de hardware. Toda la potencia de las librerías de Java se puede emplear en la mayor parte de las arquitecturas de hardware actuales sin apenas cambios. No hay que pasar por la pesadilla de las librerías en C, que deben ser recompiladas no sólo para cada plataforma sino para cada sistema operativo. Con Java disponer de un nuevo lenguaje es poderlo emplear inmediatamente en todas las máquinas. Y en la mayoría de los casos es tan sencillo como añadir un nuevo JAR.

¿Cuál es la situación actual?

Hay muchos lenguajes disponibles para la JVM, cada uno es un estado de madurez distinto. La situación es, sin embargo, muy diferente a cuando se incorporaron nuevos frameworks y librerías como herramientas "casi obligadas" de desarrollo en el pasado. O'Reilly acuñó el término "Alpha geeks" para referirse a las principales personas apasionadas por la tecnologías que definían el futuro de una tendencia en un sector. Un consenso entre ellos solía significar que una tecnología tenía muchísimas posibilidades de ser adoptada. Ocurrió contínuamente: cuando determinadas personas que eran consideradas "gurus" en la comunidad comenzaban a adoptar en conjunto ciertas soluciones, éstas llegaban al entorno corporativo: Struts hace años, Hibernate, Spring, ANT para luego pasar muchos de ellos a Maven, JPA cuando se aceptó que era una alternativa válida a Hibernate, etc, etc. 

En su momento existió un consenso sobre que esas eran las mejores opciones en su campo y se comenzaron a implantar en entornos de producción reales. La diferencia es que no existe ese consenso en relación a los lenguajes.

No obstante hay dos que están presentes en muchos blogs, podcasts y foros: JRuby, una implementación de Ruby, y Scala, un lenguaje mixto funcional-orientado a objetos. Ambos con sus méritos y también ambos extremadamente interesantes. El último en llegar haciendo ruído ha sido Cylon, una evolución de Java a manos de Gavin King. Estoy seguro de que vamos a oír hablar mucho de ellos a la espera de que llegue una alternativa totalmente nueva, aunque también es cierto que mucha gente lo ha asociado a JBoss -RedHat- por venir de él. Esta "marca" no ha abandona nunca a Seam, por ejemplo, que no ha conseguido llegar tan lejos como podría por méritos propios.

Un ejemplo interesante sobre los problemas en la adopción de un nuevo lenguaje se pueden escuchar en el podcast de hace unas semanas de Java Pose. En él un grupo de desarrolladores con perfiles altos evalúan la idoneidad de añadir un nuevo lenguaje -en este caso Scala- en un equipo de desarrollo muy motivado y dispuesto a invertir tiempo personal en ello (uno de los mejores escenarios posibles). En esencia comentan cuatro problemas en el caso de Scala: falta de desarrolladores en el mercado para ese lenguaje, falta de experiencia ya no con el propio lenguaje -que se puede aprender relativamente rápido- sino en programación funcional, cambios contínuos en la propia definición del mismo (falta de madurez) y alto riesgo de incluir un nuevo elemento fundamental en el desarrollo que todavía está sin consolidar en una aplicación de misión crítica que deben mantener y continuar desarrollando.

¿Pero qué se busca en un nuevo lenguaje?

Sin entrar en necesidades específicas de entornos concretos, hay algunas cosas que se han demostrado muy útiles y productivas en los escenarios que habitualemnte cubre Java. La fantástica capacidad de crear DSL's internos de Ruby ha llevado por un lado a crear un código increíblemente conciso y legible, con una reconocida productividad (aunque aquí habría que hablar de otras cosas, como su capacidad para redesplegar en caliente  -el demoledor "turnaround" en el despliegue- sin traumas a pesar de JRebel -se dice que han encontrado a programadores fosilizados mientras introducían cambios en una clase-), que es algo que se echa muchísimo de menos en Java. Esta facilidad ha llevado a crear ficheros de apoyo escritos directamente en Ruby sin necesidad de XMLs infernales, difíciles de escribir y aún peores de entender cuando un equipo entero trabaja con ellos.

En relación a Scala y lenguajes funcionales, creo sinceramente que la búsqueda de opciones de concurrencia sencillas preocupan a un número bastante limitado y especializado de desarrolladores. No obstante las otras virtudes de Scala (evitar el exceso de  código de Java, su flexibilidad para crear DSLs, ser un lenguaje estáticamente tipado -que lo hace más atractivo a los ojos de algunos desarrolladores-, su magnífica integración con las librerías existentes, etc) son extremadamente interesantes. Su complejidad -que algunos ya llegan a definir como el C++ de la JVM- puede ser sin embargo un problema para programadores casuales.

Hay que estar atentos a Scala y JRuby, con Cylon en el radar como potencial opción de futuro cuando esté disponible. El lenguaje que más tracción parece estar ganando es, sin embargo, Scala, con una notable diferencia frente a los demás.

Mostrar

Backups sencillos en Amazon S3

Created by: Juan (admin) 11 months ago

He estado buscando una solución sencilla para realizar un backup semanal incremental de mi servidor. La opción por robustez, seguridad y coste ha sido Amazon S3.

Amazon S3 es un referente en este sentido pero a la vez no es un sistema con el que sea trivial interactuar de forma inmediata desde un shell Unix (nada de rsync, scp o demás). Las buenas noticias son que, en tanto es un servicio que lleva varios años funcionando, hay diversas herramientas disponibles para tratar con él.

Revisando las diferentes utilidades s3sync parecía, con diferencia, la mejor opción. Pero ha sido abandonada por su autor, quien ha comenzado a usar Tarsnap para sus propios backups.

No quería pasar por un servicio de terceros, así que siguiendo la búsqueda de una alternativa, me he encontrado con duplicity. Su punto fuerte es su sencillez de instalación y uso (en esta entrada de blog de Tim Riley se comenta de forma totalmente clara el proceso). Su punto débil es que pasamos a depender de este programa para recuperar los datos (no se podrán recuperar accediendo directamente al bucket en Amazon).

Si bien siempre es agradable poder acceder directamente a los archivos, en mi caso no representa un problema y es la solución adoptada.

Una combinación realmente buena: Amazon S3 + Duplicy = backups incrementales encriptados de forma sencilla en un espacio de la calidad de Amazon S3. 

Una utilidad interesante para gestionar los buckets de forma gráfica es DragonDisk, disponible de forma gratuita para varias plataformas. Es un cliente de Amazon S3 que permite realizar tareas sencillas, especialmente el tedioso borrado de archivos.

Mostrar

Drupal: Puntos fuertes y débiles

Created by: Juan (admin) about 1 year ago

1. Abstracto

Drupal es un gestor de contenido (un CMS por su acrónimo en inglés) desarrollado en PHP, de código abierto de 10 años de antigüedad que está detrás del 1,5% de todos los sitios web del mundo –casi 800.000-

Su virtud ha sido la de crear un conjunto de librerías de desarrollo en PHP de gran calidad para controlar el día a día de una página web, permitiendo además a terceros ampliar su funcionalidad de forma estructurada, logrando crear una gran comunidad de usuarios y desarrolladores.

Drupal fue desarrollado por y para programadores, siendo esta es una de sus virtudes y a la vez, comparado con alternativas más enfocadas a usuarios finales, sus defectos: mucha de su funcionalidad y potencia viene a costa de implementaciones manuales de procesos.

2. Evolución y partes

Uno de los aspectos característicos de Drupal es el ofrecer unas librerías de desarrollo flexibles y potentes. Esto ha llevado a muchos programadores a escribir sus propias contribuciones -que modifican o amplían su funcionalidad- mediante los llamados “módulos”.

Se distinguen entonces dos partes claramente diferenciadas: el núcleo –la parte principal, autosuficiente que proporciona las librerías básicas- y los módulos, contribuciones de los programadores de la comunidad.

El núcleo es el que define las funciones básicas y la arquitectura y a la que se debe adaptar cualquier proyecto que se realice. Su desarrollo es muy cuidado y cada nuevo cambio profundo en el mismo implica una versión de Drupal (siento la actual la 7)

Entre otras cosas, aporta:

  • Seguridad por usuarios y roles
  • Sistemas de introducción de datos y de tipos de contenido
  • Soporte multi-idioma
  • Sistema de “temas”, aspectos visuales que cada diseñador puede cambiar
  • Funcionalidades de foro, blog, etc, básicas
  • Menús gráficos con los que gestionar todo el sistema
  • Y, asociado a todo esto, un potente API que podemos emplear en nuestros desarrollos.

Los módulos proporcionan ampliaciones de todo tipo, ofreciendo desde funcionalidades muy sencillas como extraer un valor de la bolsa a grandes paquetes de funcionalidad, como una tienda virtual entera. A menudo forman cadenas de dependencias, necesitando tener módulos instalados para poder emplear los que dependen de ellos.

A nivel estructural, un módulo es conjunto de ficheros de código en PHP y modificaciones visuales (ficheros HTML, CSS, imágenes, etc.). Existen literalmente miles de ellos: se distribuyen como ficheros ZIP a través de la página de Drupal –que actúa como gran catálogo de los mismos- y se despliegan como directorios dentro de la instalación de Drupal. Cada módulo es gestionado por una o varias personas que se encargan de corregir errores y hacerlos avanzar, normalmente de forma gratuita. La calidad suele ser desigual, con módulos excelentes y muy bien acabados a auténticos desastres. La implicación de los desarrolladores suele variar también bastante, desde personas que siguen la discusión de la comunidad en torno a su desarrollo literalmente hora a hora a otras que ignoran el módulo y lo abandonan.

Es extremadamente atípico en Drupal encontrar módulos de pago siendo en casi todos los casos contribuciones gratuitas de código abierto de los autores.

Alguna funcionalidad que podemos encontrar a modo de ejemplo es:

  • Posibilidad de geo-posicionar la información introducida
  • Notificar a Google de cada cambio que hagamos
  • Crear un foro
  • Añadir sistemas de votación para la información disponible
  • Integración con Facebook
  • Tienda online
  • Sistema de blogs
  • Taxonomía (clasificar toda la información de acuerdo a nuestro propio criterio y operar con ella)
  • Análisis semántico de la información existente
  • Gestión de los parámetros típicamente configurados en SEO
  • Conexión en tiempo real a servidores de cambio de divisa, meteorológicos, etc.
  • Conexión a sistemas corporativos de seguridad en árboles LDAP
  • Gestión de imágenes
  • Creación de grupos de debate sobre cualquier elemento introducido
  • Creación de “vistas” (similares a informes) de la información introducida
  • Creación de nuevos tipos de contenido definidos por el usuario

Estos son sólo algunos de los ejemplos de la opciones actualmente disponibles. La funcionalidad de cada módulo interactúa con la de los demás, lo que lo hace extremadamente potente.

Por otro lado puede existir más de un módulo para cada cosa –esto es, diferentes programadores ofreciendo aproximaciones distintas entre las que podemos elegir-.

3. Situación actual

Drupal 6 es la versión actualmente instalada en el mayor número de máquinas. Drupal 7 ha sido lanzado en enero de este año siendo el futuro de este gestor de contenido. Su principal problema viene de los módulos que estaban disponibles, pues necesitan ser adaptados para la 7. Esto está ocurriendo lentamente y muchos aún están en fase beta o directamente no disponibles.

La plataforma sigue en crecimiento, con más usuarios, desarrolladores, libros, conferencias y presencia en la red año a año. Es el sistema empleado en la actualidad por numerosas multinacionales de primer orden y organizaciones gubernamentales, siendo simbólico el empleo de la misma por la Casa Blanca en Estados Unidos.

4. Adopción

Hasta aquí ha sido una descripción general de este gestor de contenido. Vamos a destacar ahora qué aspectos es interesante conocer sobre Drupal.

5. Factores negativos a tener en cuenta

  1. Drupal son esencialmente dos partes de calidad extremadamente desigual: el núcleo y los módulos. Aunque habitualmente se presenta Drupal como un CMS en el que podemos elegir entre, literalmente, miles de extensiones gratuitas disponibles –que le proporcionan su increíble versatilidad-, es muy importante recordar que no tienen absolutamente nada que ver en cuanto a calidad, documentación, soporte y comunidad. Los módulos, salvo excepciones concretas, suelen ir muy, muy por detrás en calidad del núcleo.
  2. El núcleo de Drupal no está bien documentado. Si bien existe abundante documentación online, ésta adolece de muchas, muchas lagunas y funciones indocumentadas. Se está haciendo un esfuerzo constante y especialmente intenso en los últimos tiempos en este sentido, pero a día de hoy es así.
  3. Los módulos esencialmente están totalmente indocumentados. Si bien nos podemos encontrar alguno que sí lo está –o al menos en parte- especialmente entre los más conocidos, lo habitual es que sean simplemente código. La comunidad de desarrollo es también muchísimo más reducida en cada uno (no es posible enfatizar esto lo suficiente) y en muchos casos esencialmente lo conoce la persona que lo ha desarrollado y quien lo está manteniendo.
  4. Muchos módulos están desarrollados por una o dos personas. Esto es absolutamente frecuente, incluso con módulos muy empleados y de reconocida utilidad. Por ejemplo, el “Foro avanzado”, el foro de-facto empleado en Drupal, está desarrollado por una madre soltera que trabaja en él cuando puede.
  5. La evolución y mantenimiento de los módulos es lento. Excepto en los más empleados, si hay un bug o un problema de seguridad, éste puede tardar bastante tiempo en corregirse. Muchas veces se nos pedirá que lo desarrollemos nosotros para enviar el parche con la corrección. Esto es totalmente lógico, pues estamos trabajando con una comunidad y es coherente que se nos pida formar parte de ella. Pero es algo a tener en cuenta.
  6. Hay una curva de aprendizaje, y no es trivial. Mientras que Drupal está en PHP y eso invita a pensar en algo sencillo e inmediato, lo cierto es que es un conjunto de librerías con un API extenso que hay que conocer. La arquitectura general se puede adquirir en un curso sin problemas, pero los primeros meses de desarrollo implican descubrir el API.
  7. Extrema lentitud. La escalabilidad y el rendimiento dependen del uso de datos cacheados. Algo común a los lenguajes de script es la necesidad de cachear todo lo existente. Su velocidad suele ser mala de forma general y en Drupal de forma especial.
  8. Necesidad de hacerlo todo respetando la arquitectura de Drupal. Cuando estamos desarrollando de forma pura en un framework de Java o en Rails en Ruby, modificar una página suele ser tan rápido como abrirla y editarla. En Drupal debemos seguir un procedimiento concreto, indicando qué vamos a editar, declarando las funciones oportunas (los así llamados ‘hooks’ a los que se refiere la documentación) –que debemos haber consultado previamente- para finalmente escribir una plantilla con el cambio que deseamos.

  9. Dependencia del desarrollador de un módulo para ampliarlo y corregirlo. Drupal se comenzó a desarrollar antes de la incorporación de los elementos de orientación a objetos a PHP, imposibilitando emplear patrones típicos en la orientación a objetos. La lógica a modificar no se podía ni sobrescribir ni delegar.
  10. La aproximación de los desarrolladores de Drupal ha sido interesante: definir unos criterios de nomenclatura para las funciones que se desean permitir modificar por otros módulos. Durante el proceso inicial de una invocación al servidor, aprovechando la capacidad de introspección de PHP, se comprueba si el usuario ha escrito funciones con ese nombre y, de ser así, se invoca su código.

    El problema viene de la necesidad de prever por parte del programador original qué partes van a poder ser modificables por terceros desarrolladores. En caso de no estar éstas previstas, se puede proponer a este programador la inclusión de esas nuevas funciones.

    El problema es dual: por un lado puede no ser aceptado, y por otro puede serlo pero tardar demasiado en llegar a una versión estable que podamos emplear en producción.

    En caso de no integrar nuestra necesidad con el programador original, pasamos a ir por nuestra cuenta. Esto implica aplicar las correcciones que se produzcan en el módulo original, tanto en bugs como en problemas de seguridad y perder las evoluciones futuras o tener que integrarlas una a una con nuestro código modificado. Es una tarea mucho, mucho más seria de lo que parece, que consume gran cantidad de tiempo, es propensa a generar errores y debemos repetir periódicamente.

6. Factores positivos a tener en cuenta

Aunque algunos de estos puntos se podrían resumir en aspectos más generales, son lo bastante importantes como para incluirlos de forma independiente.

  1. Hay una comunidad gigantesca detrás. Visitar los foros y los grupos de Drupal es entrar en contacto con miles de desarrolladores y usuarios intercambiando ideas, soluciones y aproximaciones a los problemas que aparecen. Como se suele decir, emplear Drupal es no volver a caminar ya nunca más sólo.
  2. Podemos contratar consultoría en cualquier momento. Imposible enfatizar esto lo suficiente. Hay un mercado enorme y dinámico de excelentes desarrolladores en torno a Drupal a los que se puede recurrir, ya sea para participar durante todo el proyecto o para participar de forma puntual desarrollando o ampliando un modulo concreto. Es frecuente encontrar una diferencia de calidad enorme entre el trabajo de un programador que forma parte de un proyecto de código abierto y uno que simplemente trabaja de 9-a-5 en una compañía.
  3. Está probado en batalla. Desde la Casa Blanca en Estados Unidos a miles de empresas, incluyendo multinacionales de primer nivel, emplean Drupal. Con 800.000 sitios web -y creciendo- es difícil para un producto estar más probado.
  4. Gran número de desarrolladores PHP. El propio creador de Drupal reconoce que eligió PHP –a pesar de que él mismo era un programador profesional en Java- por el gran número de desarrolladores que existían en este lenguaje y que podían contribuir. Es un mercado amplio al que se puede acceder con facilidad.
  5. Es código abierto. Cuando la necesidad surge podemos ver o tocar los aspectos necesarios. Es una garantía: en un sistema con código propietario, si aparece un problema automáticamente se depende de la empresa proveedora: una vez que les hemos pedido ayuda, pasamos a depender en exclusiva de ellos, en resolución, coste y tiempo. Drupal, a pesar de tener una base de código amplia, ésta es razonablemente comprensible como para acometer por desarrolladores del equipo. Al mismo tiempo podemos solicitar ayuda a terceras partes sin problema.
  6. Gran cantidad de módulos. Si queremos desarrollar una nueva funcionalidad siempre podemos ver si un módulo ya la ofrece al completo o, si no lo hace, se puede personalizar o ampliar. Incluso aunque no se emplee en absoluto puede servir como ejemplo totalmente funcional de código en un apartado que queremos tocar.
  7. Independencia de la parte visual. Como es frecuente en la actualidad, Drupal establece una distinción clara entre la parte visual y la parte lógica. Esto posibilita la contratación de diseñadores que, ya de antemano, conocen el sistema a emplear y pueden trabajar de forma independiente.

7. Factores neutros a tener en cuenta

Algunas cosas no pueden clasificarse como positivas o negativas, pero tienen definitivamente un peso real al elegir este CMS.

  1. Generar un base de código en PHP. Conozco a pocos equipos de desarrollo que trabajen de forma nativa con PHP. Muchos llegan a Drupal porque, a pesar de no ser PHP su lenguaje principal, Drupal aporta una funcionalidad ya probada y es el tipo de herramienta más adecuada para un proyecto concreto. Una consecuencia curiosa es la base de código que se va generando: librerías y módulos en PHP que no son reutilizables en ningún otro proyecto.
  2. Estás entregando tu código. Algo que, ofuscando el código, puede no suele ser un problema excepto a nivel político. Si el desarrollo se despliega en un cliente, éste pasará a tener todo el código proporcionado. En desarrollos en Java o .NET esto es más fácil de evitar, pero en PHP, aunque ciertamente se puede ofuscar, es mucho más sencillo acceder a él.
  3. Desplegar y/o escalar una aplicación en PHP es un proceso diferente a hacerlo en Java o .NET. Esto va a exigir no sólo tener a las personas adecuadas en desarrollo, sino que en sistemas deberán asumir el despliegue de no sólo una nueva aplicación, sino una nueva arquitectura.

8. Evaluando Drupal

Es sencillo cegarse por la cantidad de funcionalidad disponible en Drupal vía su núcleo y módulos, o por la increíble cantidad de información disponible aportadada por su comunidad. Algunos de estos puntos pueden llevar a desestimar totalmente Drupal o incluso PHP como plataforma.

  1. Contenido dinámico de las páginas. Uno de los aspectos más negativos de Drupal es su lentitud. Cuando los datos están cacheados obviamente no importa: basta con generar las páginas una vez. Pero si existen páginas dinámicas es crítico conocer el rendimiento porque, casi con seguridad, va a decepcionar de forma extrema. Se puede usar algo tan sencillo como el Apache Benchmark  (ab) para tener una primera aproximación del rendimiento del sistema. Y no, que en un servidor de última generación, con un solo usuario y una única petición tarde más de dos segundos en generar una sola página no es nada extraño. En muchos casos es lento hasta ese punto o incluso más.
  2. Hay diferentes escenarios: si tenemos un CMS que va a gestionar información estática que no cambia según el perfil y el propio usuario, no es un problema. Si la información depende del usuario (esto puede ser tan sencillo como mostrar los comentarios sin leer que tiene en un foro o tan complejo como mostrar una página tipo Facebook con información específica a cada persona que se conecte) entonces es un factor totalmente crítico a considerar.

    Describir cómo optimizar el servidor y hacer una prueba real exigiría un artículo en sí mismo (Carles Climent ha escrito uno muy interesante en el wiki español de Drupal), pero algunas cosas, aunque obvias, es interesante comentarlas:

    1. APC debe estar instalado en el servidor. De otra forma estamos obteniendo un resultado con PHP sustancialmente peor que en un entorno de producción.
    2. Desactivar cualquier sistema de caché. Interno o externo a Drupal. Lógicamente una de las cosas que más desvirtúa los resultados.
    3. La latencia en el acceso a la base de datos es crítica en Drupal. Un signo distintivo de este CMS es la increíble cantidad de peticiones que realiza a la base de datos para procesar cada petición. Este número no hace sino aumentar a medida que se añaden nuevos módulos. La latencia que tengamos en cada petición es extraordinariamente importante empleando Drupal. Normalmente en el entorno de desarrollo tenemos la base de datos en la misma máquina. Si en producción no es así, es crítico probarlo en Drupal.
    4. Toda la información está en una sola tabla. Uno de los aspectos característicos de Drupal es el de almacenar todos los tipos de información que introduzcamos (una entrada en un foro, un artículo, los tipos de información definidos por nosotros mismos, etc.) en una sola tabla: nodes. Esto aporta algunas ventajas a nivel de desarrollo pero no es difícil ver el potencial problema. Todos las unidades de información que introduzcamos tendrán una entrada en esta tabla.
    5. Velocidad de AJAX. Derivado del punto anterior, impresiona comprobar la lentitud que tiene una simple llamada vía AJAX al servidor. El proceso de bootstrapping (los procesos que siempre se ejecutan cuando hacemos una llamada a una función en Drupal) es pesado y se nota cuando hacemos una simple petición. Que consuma, en una invocación trivial que lea un dato de una tabla de una sola fila, más de 300ms sólo en tiempo de proceso no es extraño. Si bien hay alternativas en forma de módulos, éstas no están bien probadas.
    6. Necesidad de un prototipo de desarrollo, no una maqueta. Otro aspecto realmente crítico: que el prototipo que se emplee para evaluar el CMS implique un desarrollo real.  Muchas estimaciones de tiempos en Drupal vienen de evaluar la creación de una maqueta a nivel de usuario. Es rápido, aparentemente muestra la potencia de Drupal y al fin y al cabo es el 80% percibido del producto final. Pero es que el problema con los proyectos que se retrasan no es que estén al 10%, es que están al 90%. Y siguen al 90%  al siguiente año de su hipotética entrega. El riesgo de caer en este espejismo con Drupal es enorme. El coste en tiempo no viene de “Crear un sistema para geo-localizar elementos de información”. Eso es inmediato. Viene de personalizar, aunque sea poco, esa funcionalidad. Lo mismo ocurre con un foro, un sistema de registro, una integración con un sistema de legado existente vía un módulo, etc.

Es crítico desarrollar un aspecto concreto hasta el final porque sólo de esa forma se pueden ver las carencias reales de documentación del núcleo y los módulos afectados, la dificultad de trabajar con la peculiar arquitectura de Drupal, el esfuerzo real necesario en un módulo y los agujeros de formación que existen en el equipo.

7. Un ejemplo

De forma concreta, se puede plantear un escenario sencillo: personalizar cinco elementos de un foro. No vamos a entrar en la parte técnica, tan sólo en qué implica.

Montar un foro en Drupal es rápido. Añadir nuevos campos al  perfil de un usuario también. Pero esa es simplemente la configuración por defecto, lo que ya nos dan hecho. ¿Qué ocurre si un usuario pide las siguientes cosas –nada descabelladas-?

    1. Al igual que muchos foros, mostrar el número de posts que el usuario ha hecho al lado de su nombre.
    2. Añadir un campo extra a su perfil, “profesión”, que debe aparecer bajo su nombre.
    3. Si el usuario que está visitando la página no está registrado, mostrar un cuadro de texto invitándole a hacerlo.
    4. El usuario debe poder insertar vídeos de youtube de forma sencilla, como en la mayor parte de las aplicaciones populares actuales.
    5. De la misma manera, algo que van a hacer con frecuencia es subir imágenes, debería poder hacerlo de forma sencilla (un clic y elegir una imagen)

Esencialmente hay dos problemas distintos: desconocimiento del API y coste de integración en Drupal.

Los puntos 1-3 son desconocimiento del API del núcleo. El coste en tiempo es encontrar qué funciones emplear y qué partes tocar para implementarlas. Hacerlo no es siempre tan evidente como parece y hay que recordar que no siempre disponemos de una documentación completa. Estos son sólo tres casos simples, pero en un desarrollo durante los primeros meses hay un bombardeo continuo. Por otro lado, suele ser normal no implementarlas de una forma afín a la arquitectura de Drupal, por lo que lo que estamos haciendo no es sólo perder el tiempo, sino poner bombas en el proyecto que estallarán en el futuro. La figura del mentor durante esta fase –alguien que conoce Drupal en profundidad- es extremadamente útil.

Los puntos 4-5 implican coste de integración. No sólo exigen conocer el API, es necesario conocer en profundidad la arquitectura de Drupal, en este caso en la parte de introducción de datos. Tan cercanos al usuario como pueden parecer (subir imágenes y vídeos) no son en absoluto inmediatos en tiempo de desarrollo. Obviamente podemos ofrecer al usuario la funcionalidad que ya existe en alguno de los módulos existentes, pero de ser necesario establecerla nosotros, el coste es muy alto si no conocemos en profundidad este CMS.

Por poner un ejemplo real: introducir imágenes de forma sencilla mediante es hoy en día un módulo existente con una persona detrás que ha tenido que dedicar una cantidad seria de tiempo y esfuerzo -y aún así existen flecos abiertos.

8. Información adicional

Podcasts

  • Drupal Voices - Entrevistas a diferentes personas implicadas proyectos de Drupal de todo tipo. Muy interesante. Lo produce junto con el Lullabot Podcast la empresa con el mismo nombre, Lullabot, implicada totalmente en los desarrollos con Drupal.
  • Acquia - Discusiones y entrevistas de todo tipo sobre Drupal. También recomendado.
  • Lullabot Podcast - Información sobre Drupal, estando dedicado cada episodio a un aspecto del CMS. Muy buena calidad.

Libros

Formación online

  • Drupalizeme. Vídeos de iniciación a Drupal producidos por Lullabot tocando en algunos aspectos relacionados con la programación. La realización es simple pero cuidada y se nota que están realizados por personas que conocen plenamente la materia y que tratan activamente de transmitir ese conocimiento. Son de introducción pero sin paja y directos al grano. Muy útiles para tener una iniciación de calidad o para nuevos miembros del equipo que no conocen Drupal.

Enlaces útiles

Mostrar