jueves, 26 de febrero de 2015

Acelerando el arranque de Tomcat 7

Regresamos con un mini-artículo sobre como mejorar los tiempos de arranque del servicio Tomcat, específicamente de la distribución de Tomcat 7 para el Framework Dinámica, que por correr aplicaciones creadas con este framework, no necesita JSPs, TagLibs, anotaciones de Servlet Spec 3.x ni otros artificios. Dinámica es minimalista, usa un solo Servlet (el Controller) y algunos filtros/listeners, nada ajeno a la especificación de servlets 3.0. Por este motivo hay varias cosas que se pueden desactivar en Tomcat para que arranque considerablemente más rápido.

La velocidad de arranque del servicio es importante para mantener la interrupción del mismo en un mínimo aceptable, sea por controles de cambio o contingencias.

Paso 1

En ${tomcat.home}/conf/catalina.properties se definen las reglas de scanning de anotaciones en los JARs, es el primer punto a tocar. La configuración por defecto pecha bastante el tiempo de arranque haciendo revisiones innecesarias (para Dinámica) en los JARs. El tiempo de arranque en nuestro Tomcat 7 con 4 WebApps instaladas es el siguiente:

[2015-02-25 16:01:57] INFORMACIËN: Initializing ProtocolHandler ["http-bio-80"]
[2015-02-25 16:01:57] INFORMACIËN: Initialization processed in 300 ms
[2015-02-25 16:01:57] INFORMACIËN: Arrancando servicio Catalina
[2015-02-25 16:01:57] INFORMACIËN: Starting Servlet Engine: Apache Tomcat/7.0.59
[2015-02-25 16:01:57] INFORMACIËN: Despliegue del directorio C:\tomcat7\webapps\admin de la aplicaci¾n web
[2015-02-25 16:01:57] INFORMACIËN: Despliegue del directorio C:\tomcat7\webapps\devel de la aplicaci¾n web
[2015-02-25 16:01:57] INFORMACIËN: Despliegue del directorio C:\tomcat7\webapps\nws de la aplicaci¾n web
[2015-02-25 16:01:57] INFORMACIËN: Despliegue del directorio C:\tomcat7\webapps\ROOT de la aplicaci¾n web
[2015-02-25 16:02:00] INFORMACIËN: Deployment of web application directory C:\tomcat7\webapps\ROOT has finished in 2.367 ms
[2015-02-25 16:02:00] INFORMACIËN: Deployment of web application directory C:\tomcat7\webapps\nws has finished in 2.517 ms
[2015-02-25 16:02:00] INFORMACIËN: [Dinamica] SecurityFilter started for context: AdminConsole
[2015-02-25 16:02:00] INFORMACIËN: Deployment of web application directory C:\tomcat7\webapps\admin has finished in 2.690 ms
[2015-02-25 16:02:01] INFORMACIËN: WSSERVLET14: inicializando el servlet de JAX-WS
[2015-02-25 16:02:01] INFORMACIËN: WSSERVLET12: inicializando el listener de contexto de JAX-WS
[2015-02-25 16:02:01] INFORMACIËN: Deployment of web application directory C:\tomcat7\webapps\devel has finished in 3.220 ms
[2015-02-25 16:02:01] INFORMACIËN: Starting ProtocolHandler ["http-bio-80"]
[2015-02-25 16:02:01] INFORMACIËN: Server startup in 3256 ms

Lo que vamos a hacer es desactivar el scanning de los JARs, configurando estos parámetros con los valores mostrados abajo:

tomcat.util.scan.DefaultJarScanner.jarsToSkip=*.jar
org.apache.catalina.startup.ContextConfig.jarsToSkip=*.jar
org.apache.catalina.startup.TldConfig.jarsToSkip=*.jar

Con este no se desactiva el uso de anotaciones muy útiles, como @WebService y @MultipartConfig.
Si reiniciamos Tomcat obtenemos estos tiempos:

[2015-02-25 16:09:21] INFORMACIËN: Initializing ProtocolHandler ["http-bio-80"]
[2015-02-25 16:09:21] INFORMACIËN: Initialization processed in 287 ms
[2015-02-25 16:09:21] INFORMACIËN: Arrancando servicio Catalina
[2015-02-25 16:09:21] INFORMACIËN: Starting Servlet Engine: Apache Tomcat/7.0.59
[2015-02-25 16:09:21] INFORMACIËN: Despliegue del directorio C:\tomcat7\webapps\admin de la aplicaci¾n web
[2015-02-25 16:09:21] INFORMACIËN: Despliegue del directorio C:\tomcat7\webapps\devel de la aplicaci¾n web
[2015-02-25 16:09:21] INFORMACIËN: Despliegue del directorio C:\tomcat7\webapps\nws de la aplicaci¾n web
[2015-02-25 16:09:21] INFORMACIËN: Despliegue del directorio C:\tomcat7\webapps\ROOT de la aplicaci¾n web
[2015-02-25 16:09:22] INFORMACIËN: Deployment of web application directory C:\tomcat7\webapps\ROOT has finished in 610 m
s
[2015-02-25 16:09:22] INFORMACIËN: Deployment of web application directory C:\tomcat7\webapps\nws has finished in 770 ms

[2015-02-25 16:09:22] INFORMACIËN: [Dinamica] SecurityFilter started for context: AdminConsole
[2015-02-25 16:09:22] INFORMACIËN: Deployment of web application directory C:\tomcat7\webapps\admin has finished in 1.01
1 ms
[2015-02-25 16:09:23] INFORMACIËN: WSSERVLET14: inicializando el servlet de JAX-WS
[2015-02-25 16:09:23] INFORMACIËN: WSSERVLET12: inicializando el listener de contexto de JAX-WS
[2015-02-25 16:09:23] INFORMACIËN: Deployment of web application directory C:\tomcat7\webapps\devel has finished in 1.59
1 ms
[2015-02-25 16:09:23] INFORMACIËN: Starting ProtocolHandler ["http-bio-80"]
[2015-02-25 16:09:23] INFORMACIËN: Server startup in 1617 ms

Una reducción de aproximadamente el 50%, nada mal.

Paso 2

A nivel de cada WebApp es necesario desactivar el scanning de TLDs, No sirve hacerlo en el context.xml global de Tomcat 7, ya lo probamos y no tiene efecto. Es necesario hacerlo en el context.xml privado de cada WebApp que está en /META-INF. Las WebApps creadas con Dinámica para correr en Tomcat usan la definición de su pool de conexiones a BD dentro de este archivo. Y el plugin del Framework para crear WebApps en Eclipse ya incluye esta entonación cuando crea el proyecto. Se trata de añadir el siguiente elemento (resaltado en amarillo):

<Context processTlds="false">

... el pool se define aquí ...

</Context>

Antes de esta optimización podríamos ver con JConsole el tiempo gastado en procesar TLDs aunque no los estemos usando:


Luego de aplicar el cambio en TODAS las WebApps instaladas, observamos que el tiempo del atributo tldScanTime=0 para cada WebApp.


Y el log de arranque del servicio muestra el resultado final de la entonación:

[2015-02-25 16:11:34] INFORMACIËN: Initializing ProtocolHandler ["http-bio-80"]
[2015-02-25 16:11:34] INFORMACIËN: Initialization processed in 297 ms
[2015-02-25 16:11:34] INFORMACIËN: Arrancando servicio Catalina
[2015-02-25 16:11:34] INFORMACIËN: Starting Servlet Engine: Apache Tomcat/7.0.59
[2015-02-25 16:11:34] INFORMACIËN: Despliegue del directorio C:\tomcat7\webapps\admin de la aplicaci¾n web
[2015-02-25 16:11:34] INFORMACIËN: Despliegue del directorio C:\tomcat7\webapps\devel de la aplicaci¾n web
[2015-02-25 16:11:34] INFORMACIËN: Despliegue del directorio C:\tomcat7\webapps\ROOT de la aplicaci¾n web
[2015-02-25 16:11:34] INFORMACIËN: Despliegue del directorio C:\tomcat7\webapps\nws de la aplicaci¾n web
[2015-02-25 16:11:34] INFORMACIËN: Deployment of web application directory C:\tomcat7\webapps\nws has finished in 441 ms

[2015-02-25 16:11:34] INFORMACIËN: Deployment of web application directory C:\tomcat7\webapps\ROOT has finished in 441 m
s
[2015-02-25 16:11:34] INFORMACIËN: [Dinamica] SecurityFilter started for context: AdminConsole
[2015-02-25 16:11:34] INFORMACIËN: Deployment of web application directory C:\tomcat7\webapps\admin has finished in 561
ms
[2015-02-25 16:11:35] INFORMACIËN: WSSERVLET14: inicializando el servlet de JAX-WS
[2015-02-25 16:11:35] INFORMACIËN: WSSERVLET12: inicializando el listener de contexto de JAX-WS
[2015-02-25 16:11:35] INFORMACIËN: Deployment of web application directory C:\tomcat7\webapps\devel has finished in 1.15
3 ms
[2015-02-25 16:11:35] INFORMACIËN: Starting ProtocolHandler ["http-bio-80"]
[2015-02-25 16:11:35] INFORMACIËN: Server startup in 1179 ms

¡El tiempo de arranque se redujo en 64%! Otra ventaja de usar el estilo Dinámica de programación simple, sin las complicaciones asociadas usualmente al desarrollo web con Java.

Plataforma utilizada:

  • Tomcat 7.0.59
  • Java 1.8 update 31 x64
  • Windows 7 Home Premium x64


Esperamos les resulte de utilidad este mini blog, sobre todo a los suscriptores del Framework (Dinámica se vende por suscripción), aprovechamos de celebrar con esto los 11 años de Dinámica en producción, utilizado a escala global en docenas de proyectos que traspasan dominios de negocios y le ha permitido nutrirse y robustecerse como herramienta de hiper productividad.

miércoles, 23 de abril de 2014

Usando Apache Commons DBCP V2 en Tomcat 7

El componente por defecto para el manejo del pool de conexiones a base de datos en Tomcat 7 es DBCP v1.4, que si bien tiene varias mejoras de estabilidad con respecto a la versión que usa Tomcat 6, igual padece problemas de concurrencia, que se evidenciarán con alta carga de threads solicitando conexiones al pool, ya que el DBCP tiene que sincronizar el acceso al pool. Esto ha sido una fuente de problemas y cuellos de botella en Tomcat, más crítico en la v6 que en la v7.

A partir de Tomcat 7 hay un componente de Connection Pooling alternativo, Tomcat JDBC Pool, que provee acceso concurrente al pool y varias otras mejoras, sin embargo no viene configurado por defecto (ni siquiera en Tomcat 8) y es un proyecto relativamente nuevo. Su guía de configuración:

http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html

El viejo proyecto Apache DBCP se renovó de forma importante el 2014 con su versión 2.0, que ahora usa el nuevo Apache Commons Pool, con mejoras de escalabilidad y desempeño, apoyándose en el paquete java.util.concurrent, requiere Java 7. Esta versión es el nuevo pool por defecto en Tomcat 8, y dice resolver los problemas de concurrencia de las versiones 1.2 y 1.4.

En Tomcat 7 se puede reemplazar el uso del DBCP v1.4 por el v2.0, es necesario añadir los siguientes JARs a la carpeta /lib de Tomcat:

commons-dbcp2-2.0.jar
commons-pool2-2.2.jar
commons-logging-1.1.3.jar

Los proyectos respectivos para descargar (en sus últimas versiones) cada JAR son:

http://commons.apache.org/proper/commons-dbcp/
http://commons.apache.org/proper/commons-pool/
http://commons.apache.org/proper/commons-logging/

En la definición del pool de conexiones en META-INF/context.xml de la WebApp se debe indicar el atributo factory, para que use el nuevo pool DBCP 2:



<Resource auth="Container" name="jdbc/dinamica" type="javax.sql.DataSource"> factory="org.apache.commons.dbcp2.BasicDataSourceFactory"
initialSize="3" maxIdle="10" maxWait="3000" maxTotal="100"
username="postgres" password="basica"
driverClassName="org.postgresql.Driver"
url="jdbc:postgresql://localhost/demodb"/>



El atributo maxActive ahora se llama maxTotal, esto requirió un cambio en la clase dinamica.SysInfo del framework Dinámica, para poder reportar correctamente en su página de estatus (/action/test) la información de los pools, sin importar si utilza DBCP v1.4 o DBCP v2. El resto es transparente para las WebApps.

Ahora puede utilizar la tecnología -supuestamente- superior de DBCP v2 en un producto solido como Tomcat 7, sin esperar a que salga Tomcat 8 o recurrir a un componente menos probado con el Tomcat JDBC Pool (por algo tampoco es el pool manager por defecto en Tomcat 8).

Los pools de conexiones concurrentes son "la nueva tendencia" en este tipo de componentes, porque hace tiempo que junto con sus ventajas también introdujeron el problema de la sincronización para acceder al pool, creando cuellos de botella. Hay varios productos de diversa calidad que ya usan esta técnica, facilitada desde hace pocos años por el paquete java.util.concurrent de Java SE, pero adolecen de un problema básico en relación a Tomcat, no vienen preparados para ser configurados como un Factory de DataSources, un reemplazo a lo "plugin" para el pool manager por defecto de Tomcat 7. El Apache DBCP v2 si puede ser usado de esa manera, como lo mostramos arriba.

Existe en este nuevo ecosistema de Pool Managers un producto que destaca, se llama HikariCP, y su documentación es muy interesante, aunque lamentablemente no provee configuración nativa como un Resource en Tomcat 7:

http://brettwooldridge.github.io/HikariCP/

Actualización del 26/04/2014

El autor de HikariCP nos proveyó de una versión de desarrollo (HikariCP-1.3.7-SNAPSHOT.jar) que incluye el DataSource Factory que permite usar este componente dentro de Tomcat 7 de forma transparente a las aplicaciones.

<Resource name="jdbc/dinamica" auth="Container" type="javax.sql.DataSource"
factory="com.zaxxer.hikari.HikariJNDIFactory"
username="postgres" password="basica"
driverClassName="org.postgresql.Driver"
jdbcUrl="jdbc:postgresql://localhost/demodb"/>

Lo malo es que no es compatible en cuanto a los nombres de los atributos, así que requiere nuevos atributos para indicar máximo de conexiones, tamaño inicial del pool, etc. Esto también supone un problema ya que no se puede monitorear este pool vía JMX con las facilidades de diagnóstico del framework Dinámica, y no tenemos planes de soportarlo en el corto plazo, además carece de atributos tan básicos y útiles como numActive y numIdle, que te dan de inmediato una radiografía del uso del pool. De todos modos el experimento con HikariCP ha sido positivo, en la medida que este producto vaya madurando y cumpla su promesa de estabilidad y velocidad, será una alternativa importante para mejorar el desempeño de un servidor Tomcat 7. Nuestro agradecimiento a Brett Wooldridge, el creador de HikariCP, por su rápido apoyo para implementar el soporte a Tomcat 7.

Saludos,
El Team Dinámica

jueves, 19 de septiembre de 2013

Actualizando el Java de un Tomcat 7 en Linux

Volvemos con un mini blog útil para los usuarios del Framework Dinámica que mantienen servidores Tomcat 7 en Linux.

Se asume que el Tomcat 7 está instalado en /opt/tomcat7 de acuerdo a nuestros lineamientos y viene de nuestra distribución para Dinámica:
http://www.martincordova.com/files/tomcat7.tgz

Oracle ahora provee paquetes TGZ con JRE para servidores de 64 bits en Linux y Windows. Solo hay que descomprimir y listo, no hay programa de instalación para ejecutar.

Esta conveniente distribución de la JVM y sus herramientas se descarga desde este link:
http://www.oracle.com/technetwork/java/javase/downloads/server-jre7-downloads-1931105.html

Escoja la opción "Linux x64".

Una vez que se copia el comprimido TGZ al directorio /opt, se procede a descomprimirlo con este comando, asumiendo que ya está en el directorio /opt:

sudo tar -xzf server-jre*
Esto creará el directorio /opt/jdk1.7.0_40

Ahora solo resta configurar el servicio Tomcat para que use este Java. Editar el archivo /opt/tomcat7/bin/catalina.sh y cambie la línea donde se define el JAVA_HOME al inicio del archivo:

JAVA_HOME=/opt/jdk1.7.0_40

Ya está listo, ahora reinicie el servicio Tomcat 7, la interrupción de servicio será mínima:

sudo /etc/init.d/tomcat stop (espere por el [OK])
sudo /etc/init.d/tomcat start
Ahora con el navegador puede solicitar la página de diagnóstico /action/test que tienen todas las Webapps construidas con Dinámica, debería ver un mensaje como este:


Listo. Para desinstalar este Java basta con eliminar la carpeta /opt/jdk1.7.0_40.

Actualización del 2014/04/23: Descargar directo desde Oracle al servidor Linux

Como saben, ya salió el Java 8, y hace pocos días salió una actualización crítica de seguridad de Java 6, 7 y 8 inclusive (1.8.0_5), para eliminar un conjunto de vulnerabilidades. Si tienen un hosting en USA y en su región tienen un ancho de banda pobre (como es nuestro caso en Caracas), saben que es tedioso subir al servidor una nueva versión del JRE que puede pesar unos 50MB. Sin embargo nuestro hosting en USA tiene muy alta velocidad para descargarse archivos de Oracle, así que con este comando logramos bajar el último update de Java 8 en 5 segundos, directo a nuestro server en USA, ingresamos con putty, nos colocamos en el directorio /opt y procedemos a ejecutar el comando:

wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/8u5-b13/server-jre-8u5-linux-x64.tar.gz"

El URL de descarga lo deberían obtener de la página de descarga de Oracle una vez que aceptan la licencia, luego lo copian en su comando, el URL cambia de acuerdo a los números de versiones de Java. Este es para bajar el Server JRE para Linux de 64 bits v1.8 update 5 (el último a la fecha).

El crédito por el tip de descarga con comando WGET no va para nosotros, sino para unos cuantos sitios webs que tratan el tema, uno en particular:

https://ivan-site.com/2012/05/download-oracle-java-jre-jdk-using-a-script/

martes, 8 de mayo de 2012

Cómo encriptar las contraseñas en Tomcat 7

Las contraseñas de los pools de conexiones a base de datos y del KeyStore de certificados (cuando se usa SSL) se almacenan en archivos XML de configuración en texto claro, por defecto. Nosotros no tenemos mayor problema con esto, ya que de todos modos hay que asegurar la instalación para restringir el acceso al servidor, pero es normal que en ambientes corporativos, como Bancos o Casas de Seguros esto no esté permitido, les representa un hallazgo de seguridad y piden que estas contraseñas sean almacenadas en forma encriptada, con algún algoritmo simétrico, como TripleDES con SHA1.

Si bien esto no le añade mucha más seguridad necesariamente, porque siempre se necesita otra llave para encriptar, es normal que los clientes soliciten este tipo de cambios, algo que los desarrolladores de Tomcat no parecen entender, por lo que pude ver en los forums, encriptar estas contraseñas ha sido una petición frecuente, pero que es despreciada por ellos con el argumento de que no ofrece mayor seguridad, etc, etc, en una mezcla de arrogancia y falta de pragmatismo.

Nosotros proveemos a los suscriptores de nuestra tecnología (Dinámica Deluxe) y a nuestros clientes un JAR que le añade a Tomcat 7 la capacidad de manejar las contraseñas de los pools de BD y de Keystore en forma encriptada. El JAR se llama dinamica-tomcat.jar y contiene unas clases que reemplazan las que vienen por defecto en Tomcat y que se ocupan de leer esas contraseñas. No fue un trabajo fácil, aunque debería serlo, porque Tomcat en su diseño no provee vías muy directas para afectar esta parte y proveer un lector de contraseña encriptada, sobre todo en el caso del KeyStore.

En el caso de los pools de conexiones a base de datos es un poco más fácil, requiere solo de una clase que extiende a BasicDataSourceFactory, luego esta clase es configurada en el archivo context.xml correspondiente, usando el atributo "factory".

En el caso del KeyStore, hay que crear una clase una extensión de la clase org.apache.tomcat.util.net.SSLImplementation, la cual será luego utilizada para configurar el conector SSL usando el atributo sslImplementationName. Para ser justos con el diseño de Tomcat, si bien pudo ser más fácil, al menos existe la forma de hacerlo vía extensión y configuración. El problema en el caso del KeyStore es que se requieren 2 clases más para lograr el efecto, básicamente tuvimos que identificar las clases, copiarlas de los fuentes de Tomcat a otro paquete y hacerle los ajustes para leer el password encriptado, que van en un método específico.

El JAR que proveemos contiene unos comandos para generar la contraseña encriptada, y también para codificar la llave que se usa para encriptar y desencriptar. Por ejemplo para generar la contraseña encriptada teniendo ya la llave codificada, se usa este comando:

@java -classpath ./dinamica-tomcat.jar -Dsemilla=cGVwaXRv dinamica.tomcat.MakePassword basica
En este caso la contraseña basica queda transformada en: A31CInaRgDk=

Así queda la configuración de un pool de conexiones a base de datos con el uso de contraseña encriptada y codificada en Base64:


El atributo factory indica que vamos a usar nuestra clase para leer la configuración, en particular el atributo password.

Para el caso del KeyStore se modifica server.xml para configurar el conector SSL de esta manera:


El atributo sslImplementation le dice a Tomcat 7 que use nuestra clase, la cual permite leer el atributo password encriptado.

De esta manera proveemos a nuestros clientes una forma sencilla para resolver el problema de las contraseñas en texto claro, sin configuraciones rebuscadas y suficiente para pasar una auditoria de seguridad.

Saludos,
el Team Dinámica

miércoles, 18 de enero de 2012

De terror: Weblogic y filtros de servlets

Para hacer el cuento corto: a un suscriptor de Dinámica en Perú le tocó instalar una webapp hecha con nuestro framework en un servidor WebLogic y reportó un comportamiento absolutamente anormal: "un usuario sin autorización puede ejecutar un URL restringido, el filtro de seguridad de Dinámica parece no estar funcionando en WebLogic! aunque las pruebas en Tomcat funcionaron perfecto..." y por nuestra parte hemos verificado este mecanismo en Glassfish, Oracle J2EE container y Resin, además de Tomcat. Tiene años funcionando sin novedades.

No tuvimos alternativa, nos tocó montar un WebLogic de desarrollo para hacer nuestras propias pruebas controladas, usamos el último disponible, v12.1.1. Un proceso innecesariamente accidentado, a pesar que en principio era descomprimir un ZIP y cambiar unas variables de ambiente, resultó un dolor de cabeza por diversos motivos. En fin, lo pusimos en marcha y procedimos a probarlo reproduciendo el caso reportado por nuestro suscriptor, usando la webapp que sirve como consola de seguridad -Admin-, pero levantando unas trazas adicionales que serían útiles para diagnosticar el caso, usando tanto facilidades del framework Dinámica así como los logs del servidor.

Usando una credencial de usuario sin suficientes permisos, pudimos comprobar que nos dejaba ejecutar URLs restringidas... ese era el síntoma. Las evidencias resultaron más inquietantes.

El filtro de seguridad verifica los roles del usuario y los niveles de autorización de cada rol para ver si el URL requerido puede o no ser ejecutado, si no tiene permisos suficientes, se retorna un error http 403, acceso denegado, de lo contrario se deja pasar el request. No hay espacio para la ambiguedad:

Cuando verificamos los logs HTTP de WebLogic, la cosa se pone peor:

[12/Jan/2012:21:04:26 -0430] "GET /admin/action/admin/app/view HTTP/1.1" 200 4648 
[12/Jan/2012:21:06:12 -0430] "GET /admin/action/admin/app/edit?id=501 HTTP/1.1" 403 1833


El URL o Action -en la jerga de Dinámica- en cuestión es /app/edit, pudimos constatar en el browser que el servidor nos retornó la página que por la configuración de seguridad no deberíamos haber visto, pero lo más extraño es que quedó registrada una respuesta 403, de acceso denegado, sin embargo la página objetivo fue retornada, no un mensaje de error, ¿cómo es esto posible? El filtro parece estar haciendo su trabajo, pero el mismo es ignorado por WebLogic!

Más evidencia, esta vez de las trazas que deja el mecanismo de seguridad de Dinámica al momento de interceptar el request para el URL restringido /app/edit:

#### <[Dinamica_DEBUG_SecurityFilter] URI (/action/admin/app/edit) Intercepting request...> 
#### <[Dinamica_DEBUG_SecurityFilter] URI (/action/admin/app/edit) Session Cookie: f78WPPKWfgbGCNjhgJhTv80GpqqvWjXnWXyh19Nb0QlxfQQcNp1W!-750755119!1326418454955>
#### <[Dinamica_DEBUG_SecurityFilter] URI (/action/admin/app/edit) Authorized Roles (sysadmin;) USER (mcordova) User Roles (tester;) > 
#### <[Dinamica_DEBUG_SecurityFilter] URI (/action/admin/app/edit) Request rechazado por falla de autorización> 

Se puede ver claramente que el filtro rechazó el request!!! nunca se ejecutó el método next.doFilter() que es  lo que haría que el request se ejecute después de pasar por el filtro. ¿Cómo es posible que WebLogic retorne la página si nunca se ejecutó el doFilter? Una falla horrorosa en la implementación de la especificación de servlets.

La causa:

Resulta ser que en el web.xml de una aplicación hecha por Dinámica, se mapea el código de error HTTP 403 a un Servlet, práctica perfectamente aceptada en el estándar de servlets.


Pues esto no le gustó a WebLogic, y en vez de dejar algún rastro en sus logs o de retornar un propio mensaje para el código 403, decidió que era mejor retornar el recurso solicitado, aunque el filtro nunca lo dejo pasar!

La solución al problema fue usar un recurso estático, una página HTML en la raíz de la webapp y referenciarlo como mapping para el error 403 en web.xml. El problema desapareció y el filtro de seguridad de Dinámica funcionó como se esperaba, consistente con la configuración de seguridad.

La experiencia sirvió para enriquecer y actualizar nuestra guía de Deployment JEE de Dinámica, que muestra como hacer deployment de webapps hechas con Dinámica en distintos servidores JEE, ahora incluyendo a WebLogic v12.1.




domingo, 18 de septiembre de 2011

De romance con Lenovo y Dinámica

Lenovo K330: la nueva estación de trabajo de Dinámica

OJO: ver actualización mayo 2012 al final.

Llegó el momento de renovar nuestras computadoras de escritorio para crear las próximas versiones de Dinámica, no es solo una compra sino también una inversión. Una cosa tengo claro, nada de comprar piezas y mandar a armar "a la medida", nunca quedé satisfecho con el resultado. Esta vez compramos marca de calidad, Lenovo. A la hora de revender también saldremos mejor parados si es de marca.

Lenovo tiene mejores precios que HP, aunque esta última era nuestra primera opción, buscando en Amazon (en Venezuela estamos un poco limitados a comprar en Amazon por cuestiones de billing address) conseguí que Lenovo también ofrecía mejores opciones, por ejemplo: HP vende por Amazon lo que en apariencia son muy buenos PCs de escritorio, pero con discos de 5200RPM! no tiene sentido. En cambio las PC de Lenovo vienen con configuraciones más "honestas", por decirlo así, y con una diferencia de precio sustancial.

Hay otro punto a favor de Lenovo: su fuerte integración con Windows en la forma de una ventaja llamada Windows Enhanced Experience, que hace que Windows 7 funcione más rápido, sobre todo en el arranque. En algunos modelos seleccionados viene también con un disco SSD que permite implementar una técnica propietaria de Lenovo llamada RapidDrive y provee un tiempo de respuesta instantáneo para levantar aplicaciones. La navegación y funciones de red también se sienten más rápidas.

El modelo seleccionado por nosotros es el K330 77274HU, que viene con un procesador Intel I7 2600 de 2da generación de 3.4Ghz que en modo turbo llega hasta 3.8, 12GB de RAM de 1333Mhz, un disco duro de 7200RPM de 1.5TB, una quemadora DVD y una tarjeta de video ATI RADEON 6450 con 1GB de RAM DDR3.

Está ensamblada de una manera muy limpia, la incorporación de nuevos componentes de hardware se realiza sin necesidad de herramientas, el interior es ordenado, sin enredos de cables, realmente impresionante el resultado final. Muy bien ventilada, super silenciosa, la más silenciosa que he usado, además de fresca, prácticamente no produce calor, su fuente de poder es de 280W.

Los componentes de la PC no se ven de lujo ni estrambóticos, al contrario, se ven muy modestos pero se percibe que Lenovo manda a manufacturar a la medida versiones OEM de todo lo que requiere para su plan de ingeniería que resulta en una PC rápida, silenciosa, fresca y de bajo consumo de corriente.

Los precios son muy dinámicos en estos días (agosto-septiembre 2011), la primera la compramos en US$999.- hace un par de semanas, la restantes en US$850.-, nada mal la rebaja. Otros modelos K330 de Lenovo también bajaron de precio en Amazon en días recientes.

Lo que no me gustó

Algo casi religioso en nuestro ritmo de trabajo es una partidita de Call of Duty WAW a todo tren al final de la tarde. Y aquí viene el punto débil de esta oferta de Lenovo: la tarjeta Radeon 6450 no tiene poder para juegos exigentes como COD WAW,  al menos no a resoluciones altas, lo que resulta decepcionante en una PC que se mercadea para Gamers y entretenimiento. La tarjeta se porta bien para todo excepto para juegos modernos, su índice de Windows Experience era bastante bajo, como de 5.0.

La fotografía que aparece arriba muestra la versión OEM de la ATI Radeon 6450, pues la versión OEM de Lenovo es aún más simple, sin conector DVI y más liviana, casi que parece "de juguete", pero es una muestra interesante de como Lenovo manda a modificar las piezas para lograr su concepto de PC ultra cool, aunque en este caso se pasaron de tacaños.

La cambiamos, pero no fue tan fácil, porque la fuente de poder es de 280W, muy baja, no puedes usar cualquier tarjeta de video, hay que seleccionar con cuidado y Lenovo no brinda información al respecto en su website de soporte. Finalmente dimos con la Radeon 5670 con 1GB DDR3, que por unos US$75.- brinda un desempeño bastante bueno sin perturbar el funcionamiento fresco y silencioso de este PC, y eso era importante para nosotros, no queríamos intervenir en nada el equipo, está perfecto salvo por la mala elección de tarjeta de video que hizo Lenovo. Hasta donde pude averiguar cambiar la fuente de poder de esta PC no es tan fácil, viene con unos conectores especiales para un selector de modo de operación que tiene el Case Lenovo en la parte frontal (Turbo, Auto, Cool). Lenovo no vende fuentes de poder alternativas para este modelo.

La Radeon 5670 que aparece en la foto de arriba a la derecha, viene con conector DVI, lo que nos permitió aprovechar la conexión digital de nuestros monitores de 22", y el índice de Windows Experience saltó de 5.0 a 6.8! Ahora el juego se siente realmente bien, considerando que la fuente de poder es de 280W, la máquina se calienta apenas un poco más solo luego de jugar, no durante la operación rutinaria, y no causa problemas de estabilidad. Es la tarjeta que esta máquina debió traer desde un principio, estoy seguro que además en una versión OEM especial para Lenovo se integraría aun mejor en este PC.



El teclado y el mouse podrían ser de mejor calidad, se sienten un poco baratos, podrían haber hecho uno parecido al que vende Microsoft, que no es nada caro pero su calidad y funcionalidad es notablemente superior, con teclas de acceso directo realmente útiles, como la calculadora, el navegador y los controles multimedia y de volumen, a diferencia del de Lenovo que no trae nada de eso.

Rectificación

Lenovo acaba de sacar nuevos modelos de la línea K330, con fuente de poder de 450W y de una vez vienen con una tarjeta nVidia GeForce GTX 460 capaz de correr eficientemente juegos pesados como COD WAW. Idénticos a nuestro modelo pero incluyen también una unidad Blueray y más espacio en disco duro, aunque son un poco más caros y no siempre están disponibles en Amazon, sino directamente en la tienda online de Lenovo. 

Conclusión

En lo personal yo puedo vivir con la fuente de 280W, pero la PC debió traer de una vez una tarjeta de video más potente y compatible con esa fuente de poder. Otra adición importante seria un disco SSD, haría realmente una diferencia mejorando aun más el rendimiento de la PC. Se le puede añadir, pero Lenovo podría haberlo incorporado de una vez de forma transparente con su tecnología RapidDrive sin impactar demasiado el costo, para disparar el rendimiento de Windows y de las aplicaciones más importantes (Eclipse, Java, Office, etc).

Cuando compras un PC de lujo como este no quieres estar perdiendo tiempo modificándolo, debería venir listo de fábrica para cumplir con las tareas para las cuales se mercadea, video games entre otras. Al menos Lenovo hizo los ajustes en los modelos poseriores que acaba de lanzar. De cualquier manera estoy muy contento, no tuve que gastarle mucho más para que tuviera el rendimiento que yo esperaba, y añadir un SSD rápido y confiable de 64GB  cuesta alrededor de los US$110.-. A los precios actuales de nuestro modelo, te termina saliendo como US$1030.- con video mejorado Radeon HD 5670 y SSD de 64GB, nada mal.

Recomiendo los K330, me quedo con Lenovo, aunque hay mucho que pueden mejorar, incluyendo su website y servicio de soporte. En mi nueva PC las máquinas virtuales de Linux y Windows XP corren muy rápido con VirtualBox, además podemos correr al mismo tiempo varios servidores de base de datos y todo el entorno Java de desarrollo, con Eclipse y Tomcat, y además levantar COD WAW y no quedamos estrechos de memoria en ningún momento. Por cierto hay espacio para llevarla a 16GB, no es nada costoso, solo hay que tener cuidado de comprar el chip correcto para ese modelo, nosotros conseguimos las memorias originales Samsung en Amazon y aumentamos la RAM a 16GB por un costo muy razonable.

Actualización del 8/mayo/2012:

El modelo actual que pueden conseguir en Amazon se llama Lenovo IdeaCentre K330 77275SU, es prácticamente el mismo que compramos nosotros el 2011, pero viene con 2TB en disco duro, y actualmente lo venden en $950.- + S&H, directamente de Amazon.


Esta PC también soporta la tarjeta gráfica ATI Radeon 6670, que es más poderosa que la 5670, lleva el índice de rendimiento gráfico de Windows a 7.1 en vez de 6.8, y se consigue desde $70.- en Amazon (han bajado de precio este año), de diversos fabricantes. Nosotros compramos la de Asus, pero no es tan silenciosa como la de XFX. La 6670 tiene un bajo consumo de corriente y es perfectamente soportada por la fuente de poder que viene de fábrica con la K330 que vende Amazon (280W solamente). Viene con 1GB de memoria DDR3 o DDR5, soporta un monitor de 27" HDMI a máxima resolución sin problemas, y permite jugar COD WAW a esta resolución con alto rendimiento - ¡un asunto importante en esta empresa!

lunes, 18 de julio de 2011

Tomcat 7: cuatro puntos a favor

Esta es una mini-entrada para contarles rápidamente mis impresiones del Tomcat 7.0.16, que ya es un release estable para producción y funciona muy bien con Dinámica, incluyendo el ambiente de desarrollo.

Lo que me gustó:

1.- Por fin los logs de Catalina pueden ser rotados diariamente cuando corre como servicio Windows. Este es un problema con Tomcat 6, el log de errores crece sin medida cuando se ejecuta el proceso como servicio. Además utiliza logging.properties para la configuración de los logs. Por cierto que la última versión de Dinámica (3.1.4) que publicamos hoy incorpora un servicio para descargar los archivos de log de tomcat vía browser, de uso opcional y sujeto a seguridad por supuesto, muy útil en producción cuando el entorno es cerrado y no hay acceso al filesystem del host.

2.- El context.xml privado de cada webapp se queda en un solo sitio. Tomcat 6 tenía la mala costumbre de hacer una copia a /conf/Catalina/localhost apenas hacía deploy de la webapp, y a partir de ese momento ese era el Context.xml (renombrado a XXX.xml según el nombre del contexto) que valía. Ahora no, el context.xml se queda en la carpeta /META-INF de la webapp. Si lo quiere editar, basta con tocar el archivo en esa carpeta.

3.- Es rápido, hemos visto tiempos promedios por debajo de los 10ms para solicitudes de web services que retornan recordsets serializados, por poner un ejemplo. Llegamos a obtener tiempos de hasta de 4ms para ejecutar Actions de Dinámica. Nada mal.

4.- Los utilities Monitor y WebApp Reloader de Dinámica siguen funcionando bien con Tomcat 7, aunque tuvimos que hacer ajustes a los servicios de diagnóstico porque hubo leves cambios en los nombres de ciertos atributos en relación a Tomcat 6, pero fue una molestia menor, la última versión de Dinámica resuelve este problema y garantiza un comportamiento homogeneo de estas facilidades entre la Tomcat 6 y Tomcat 7.


Y otro punto a favor es que las modificaciones que le hicimos a Tomcat 6 para que permitiera contraseñas encriptadas en los archivos context.xml siguieron funcionando sin necesidad de modificar el código en Tomcat 7.


Ya están disponibles nuestras distros de Tomcat 7 para Windows y Linux, en nuestro estilo minimalista, sin JSP, sin webapps preinstaladas y con un server.xml casi vacío. Vienen listas para desarrollar con Dinámica, incluyendo JAX-WS 2.2.5, JavaMail 1.4.4, los últimos drivers JDBC de PostgreSQL y SQLServer (jTDS), JMS y un manager de transacciones distribuidas JTA (JOTM). Empresarial pero sin sobrecarga ni complicaciones.

Si lo quieren descargar (Tomcat 7.0.27):

Windows 32 y 64 bits (incluye lo necesario para correr como servicio).
Linux

A tomar en cuenta: Aunque Tomcat 6.0.32 es una versión muy sólida, hay que tener en cuenta que Tomcat 7 es la continuación de esta línea de velocidad y estabilidad, pero con mejoras, y más importante aun, todo el esfuerzo de desarrollo se enfoca ahora en Tomcat 7, así que tarde o temprano tocará migrar.

De la especificación de servlets 3.0, hasta el momento puedo decir que lo único que me gusta es que finalmente regularon el tema de los Uploads como parte del estándar y del API, ya era hora, y es una verdadera mejora al excelente modelo de programación web que representan los Servlets. El resto me parece que es un exceso de Annotations y concesiones con los frameworks dominantes y aburridos, ya que sus creadores son miembros del comité JCP que regula la especificación.

UPDATE del 8 de mayo 2012: recientemente le pusieron a Tomcat una mejora para inicializar los contextos en paralelo, lo que hace que el servicio levante más rápido, es un atributo del elemento Host, llamado StartStopThreads, por defecto es 1 pero lo pueden poner en 3 o 4 para ver la diferencia... funciona!

Un abrazo,
El team Dinámica