miércoles, 16 de marzo de 2011

JBoss Drools EXPRESS

JBoss Drools EXPRESS!

Según la Wikipedia: "Las reglas de negocio describen las políticas, normas, operaciones, definiciones y restricciones presentes en una organización y que son de vital importancia para alcanzar sus objetivos. Las reglas de negocio especifican en detalle lo que una organización puede hacer."

Ejemplos de reglas de negocio podrían ser:
  • "A una persona que ingresa más de 20.000 euros al año Hacienda le retiene el 15%"
  • "A los clientes que gasten más de 1.000 euros se les hace un descuento del 5%"

Como se ve en los ejemplos, las reglas de negocio tienen una semántica if/then, si se cumple una determinada condición se debe realizar una determinada acción.

Cuando un negocio dispone de muchas reglas que se deben aplicar, las aplicaciones que las gestionan se convierten en una maraña de código formado por estructuras if/else anidadas, que dificultan enormemente la comprensión y mantenibilidad del código.

Si las reglas de negocio se aíslan del resto del código, se está separando la verdadera inteligencia sobre el negocio (las reglas) del resto del programa. Los sistemas de gestión de reglas de negocio (BRMS – Bussiness Rule Management System) permiten gestionar de forma independiente las reglas de negocio. Facilitan la modificación o inclusión de nuevas reglas en tiempo de ejecución.

Dentro de los sistemas de gestión de reglas de negocio en Java más populares hoy en día encontramos Drools. Drools es un BRMS de JBoss que implementa la Java Rule Engine API (JSR 94) y utiliza una implementación mejorada del algoritmo de Rete para la ejecución de reglas.

A continuación voy a mostrar un ejemplo simple de cómo utilizar Drools y cómo permite parametrizar las reglas del negocio de forma externa a la aplicación que las utiliza. Antes de comenzar, recomiendo haber instalado JBoss Tools en Eclipse, puesto que nos ofrecerá herramientas que facilitan el desarrollo de apicaciones que usan Drools.

El caso de uso que vamos a implementar en el ejemplo será el de una tienda online. En esta tienda hay dos tipos de clientes, aquellos que se han registrado previamente y los que no. Para todos los clientes que gasten más de 1.000 euros se les hace un descuento del 5%. A los que se han registrado, se les ofrece un descuento adicional del 5% en todas su compras, independientemente del importe. Vamos a hacer una aplicación que calcule el descuento que corresponde a cada usuario.

En primer lugar creamos un proyecto Drools en Eclipse, lo que es posible gracias a las utilidades instaladas en JBoss Tools:

El nuevo proyecto se va a llamar CalculadorDescuento:

El asistente nos permite crear ejemplos de uso de Drools:

Es necesario especificar el runtime de Drools, es decir, la carpeta donde se encuentran las librerías de Drools:


Ahora, creamos una clase Cliente que refleje los datos del cliente, su nombre, si está registrado, el gasto que ha realizado y el descuento que se le aplica:
package com.roldan.drools;

public class Cliente {
String nombre;
boolean registrado;
float gasto;
float descuento;

// Getters y setters...
}

En la clase CalculadorDescuento se crea el siguiente método, que lee las reglas que se han definido en el fichero Descuentos.drl:
private static KnowledgeBase readKnowledgeBase()
throws Exception {
KnowledgeBuilder kbuilder =
KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(
ResourceFactory.newClassPathResource("Descuentos.drl"),
ResourceType.DRL);
KnowledgeBuilderErrors errors = kbuilder.getErrors();
if (errors.size() > 0) {
for (KnowledgeBuilderError error: errors) {
System.err.println(error);
}
throw new IllegalArgumentException("Could not parse knowledge.");
}
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
return kbase;
}

El método main de esta clase crea una sesión de Drools y crea también varios clientes que introduce en esta sesión a los que se aplican las reglas que se definen en el fichero Descuentos.drl:
public static void main(String[] args) {
try {
// Cargar las reglas
KnowledgeBase kbase = readKnowledgeBase();
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
KnowledgeRuntimeLogger logger =
KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test");

// Cliente no registrado que gasta más de 1.000 euros
Cliente cliente1 = new Cliente();
cliente1.setNombre("Cliente 1");
cliente1.setRegistrado(false);
cliente1.setGasto(1200);
ksession.insert(cliente1);

// Cliente registrado que gasta menos de 1.000 euros
Cliente cliente2 = new Cliente();
cliente2.setNombre("Cliente 2");
cliente2.setRegistrado(true);
cliente2.setGasto(800);
ksession.insert(cliente2);

// Cliente registrado que gasta más de 1.000 euros
Cliente cliente3 = new Cliente();
cliente3.setNombre("Cliente 3");
cliente3.setRegistrado(true);
cliente3.setGasto(1600);
ksession.insert(cliente3);

ksession.fireAllRules();
logger.close();

System.out.println("El cliente 1 tiene un descuento de "
+ cliente1.getDescuento() + " euros.");
System.out.println("El cliente 2 tiene un descuento de "
+ cliente2.getDescuento() + " euros.");
System.out.println("El cliente 3 tiene un descuento de "
+ cliente3.getDescuento() + " euros.");

} catch (Throwable t) {
t.printStackTrace();
}
}

Ahora vamos a ver cómo se definen las reglas anteriormente descritas en el ficheroDescuentos.drl:
package com.roldan.drools

rule "Gastos superior a 1.000 euros"
when
cliente : Cliente( gasto > 1000 )
then
System.out.println("El cliente "
+ cliente.getNombre() + " ha gastado más de 1.000 euros.");
cliente.setDescuento(
cliente.getDescuento() + cliente.getGasto()*5/100);
end

rule "Cliente registrado"
when
cliente : Cliente( registrado == true )
then
System.out.println("El cliente "
+ cliente.getNombre() + " está registrado.");
cliente.setDescuento(
cliente.getDescuento() + cliente.getGasto()*5/100);
end

Al ejecutar la clase principal, obtenemos la siguiente salida que nos informa sobre lo que ha pasado:
El cliente Cliente 3 está registrado.
El cliente Cliente 3 ha gastado más de 1.000 euros.
El cliente Cliente 2 está registrado.
El cliente Cliente 1 ha gastado más de 1.000 euros.

El cliente 1 tiene un descuento de 60.0 euros.
El cliente 2 tiene un descuento de 40.0 euros.
El cliente 3 tiene un descuento de 160.0 euros.

En esta traza vemos qué condiciones ha cumplido cada uno de los clientes y el resultado final de aplicarles todos los descuentos a los que tienen derecho según su condición.

Aunque este es un ejemplo muy sencillo, se puede apreciar que ahora, si se quisiese variar el descuento aplicado para cada uno de estos casos o aplicar un nuevo descuento según otra condición distinta, no haría falta manipular el código de la aplicación. Bastaría con modificar las reglas definidas de forma separada en el fichero Descuentos.drl.

Esto no es más que una sencilla aplicación de lo que ofrece Drools, aunque esteBRMS es mucho más potente que esto y ofrece mucha más funcionalidad que ya iremos viendo.

Despliegue de Drools

Despliegue de Drools – BRMS en el servidor de aplicaciones
Para realizar el despliegue de la interfaz web de administración de reglas de drools realice los siguientes pasos:
• Descargue el archivo zip de Drools BRMS indicado en la página de descargas
• Descomprima el archivo (Debió aparecer un archivo denominado drools-jbrms.war)
• Copie este archivo y péguelo en la carpeta de deploy en servidor de aplicaciones JBoss (JBOSS_HOME\server\default\deploy)
• Inicie JBoss ejecutando el archivo binario JBOSS_HOME\bin\run.bat
• Si le sale una notificación de Windows, dele click en Desbloquear.
• Una vez terminado el despliegue de JBoss, desde su navegador puede ingresar a la siguiente dirección donde se encuentra el administrador web de drools: http://localhost:8080/drools-jbrms/

Luego volveremos a esta consola, por ahora detenga el servidor de aplicaciones cerrando la ventana donde se ve el log de JBoss.
Configuración de los Proyectos de Drools
El proyecto de la biblioteca consta de dos proyectos drools_biblioteca y drools_biblioteca_prestamo. Siga los siguientes pasos para importar correctamente los proyectos en eclipse.

• Inicie eclipse ejecutando eclipse.exe que se encuentra en el directorio de instalación.
• Importe todos los proyectos del tutorial y abra la vista de ANT.
• Arrastre todos los archivos de tareas ANT al panel de ANT. (Los archivos se encuentran en el directorio bin de cada proyecto)
Necesitamos crear un servidor para referenciar las librerías que estamos utilizando. Para ello abra la vista Servers y al hacer clic derecho sobre el panel de trabajo seleccione la opción new Server

• Seleccione el servidor tipo JBoss versión 4.2
• Seleccione agregar un nuevo runtime y en la nueva ventana coloque el directorio de instalación de su JBoss AS (Es la misma ruta JBOSS_HOME). De Aceptar.

• De nuevo en la ventana de New Server, escriba un nombre al servidor y de clic en aceptar. Su servidor debe aparecer en el panel de la vista Servers.
• Corrija los errores de compilación arreglando el classpath con las librerías necesitadas. Para esto haga clic derecho sobre cada proyecto y seleccione la opción.
• Build path -> Configure Build Path.
• En ambos proyectos agregue las librerías del JRE (La versión de Java utilizada DEBE ser la versión 5).
• Para importar la librería de JBoss debe configurar el runtime del servidor en eclipse. Para esto:
o Ubíquese en la pestaña Libraries de la ventana de configuración del Path que abrió anteriormente.
o Seleccione la opción add Library y en la nueva ventana seleccione la opción server Runtime.

Ejecución de los proyectos de Drools
Una vez configuradas las librerías del proyecto (No deben salir errores en la pestaña de problemas de eclipse) proseguimos en el proceso de ejecutar nuestra aplicación.
Cada proyecto trae incluido un archivo de tareas ANT ( bin/build.xml ), una de estas es realizar el despliegue. Así que se requiere (1) abrir la vista de ANT en Eclipse, (2) adicionar a la vista de ANT el archivo build.xml de cada proyecto y (3) ejecutar la tarea de deploy de los proyectos en el orden que se especifica a continuación:
• Biblioteca Prestamo
• Biblioteca Web
Verifique que los siguientes archivos se encuentran desplegados los archivos (a) biblioteca.war y (b) préstamo.ejb3 en la ruta JBOSS_HOME/server/default/deploy.
Ya estamos listos para correr la aplicación:
• En la pestaña de server de eclipse, inicie el servidor.
• Una vez iniciado el servidor, ingrese desde su navegador a la aplicación de la biblioteca enhttp://localhost:8080/biblioteca/
• Haga login (En el archivo bibliotecaLibros.xml de la carpeta data se encuentran tanto los libros cargados como los usuarios) (Puede ingresar utilizando login: carlos, password: 123456)
• Haga click en buscar libro.
• Haga click en buscar por nombre
• En el cuadro de texto ingrese la cadena “el” y haga click en enviar consulta
• Haga click en alquilar a alguno de los libros que aparecen
• Note que todos los libros se alquilan por un día. Esto se debe a que en la implementación del proyecto por defecto la duración del préstamo es de 1 día y todavía no hay reglas para modificar esto.
En la sección de Creación de Reglas se continúa con el proceso para crearlas reglas que van a modificar el comportamiento de nuestra aplicación.


Instalando el software

Drools - 4.0.7

En el desarrollo del tutorial se utilizan las librerías de Drools en su versión binaria que se añaden al proyecto y que se añaden al servidor de aplicación JBoss AS.

http://www.jboss.org/drools/downloads.html

Drools Brms - 4.0.7 GA

Para el desarrollo del tutorial se utiliza la versión 4.07 del BRMS (Business Rule Management System)

http://www.jboss.org/drools/downloads.html

Las siguientes herramientas tambien se necesitan:

  • Apache ANT
  • JBoss 4.2.2 GA
  • Eclipse 3.5 Estructuras de Datos que contiene el plugin de JBoss IDE instalado.

INSTALACIÓN DE ECLIPSE

Para instalar sólo es necesario descomprimir los archivos en una carpeta de su sistema e iniciar eclipse.exe. (Requiere JDK 5 para funcionar). Para la correcta ejecución de todas las tareas se debe iniciar Eclipse después de que se tengan todas las variables de entorno necesarias, de lo contrario no se reconocerán.

INSTALACIÓN DE JBOSS AS

Para instalar sólo es necesario descomprimir los archivos en una carpeta de su sistema preferiblemente en una ruta que no tenga espacios entre los nombres. Se debe crear una variable de entorno JBOSS_HOME para utilizar las tareas de ant que se incluyen en el tutorial.

INSTALACIÓN DE ANT

Para instalar sólo es necesario descomprimir los archivos en una carpeta de su sistema preferiblemente en una ruta que no tenga espacios entre los nombres. Se debe crear una variable de entorno ANT_HOME. Agregue dicha variable en su variable PATH de la siguiente forma: %ANT_HOME%/bin

Creación de Variables de Entorno en sistemas Windows

Entre a las propiedades del sistema y selecciona la pestaña de opciones avanzadas. En esta pestaña encontrará una opción para la edición de variables de entorno.

En la ventana de edición de variables de entorno cree una nueva en la sección de variables del sistema. JBOSS_HOME debe apuntar al directorio de instalación de JBoss. ANT_HOME debe apuntar al directorio de instalación de Ant.

INSTALACIÓN DE LAS LIBRERÍAS DE DROOLS EN EL JBOSS AS

Debido a que se va a utilizar el Droold BRMS para la administración de las reglas se deben copiar dentro del servidor de aplicación JBOSS las librerías necesarias. Para esto se siguen los siguientes pasos:

Descargue el archivo .zip con las librerías de Drools que se indicó la página de instaladores

  • Descomprima este archivo
  • Copie los siguientes jars:
    • drools-core-4.0.7.jar (Se encuentra en la carpeta donde descomprimió el archivo).
    • mvel-1.3.1-java1.4.jar (Se encuentra en la carpeta /lib donde descomprimió el .zip).
    • Pegue los jars en la carpeta JBOSS_HOME\server\default\lib.

DROOLS - retomamos el Tutorial

entro del contexto de aplicaciones empresariales, existe el concepto de regla de negocio. Estas reglas de negocio son definidas propiamente por las directivas de la organización y pueden ser condiciones o parámetros de los diferentes servicios que ésta presta. Algunos ejemplos son:

  • El precio de un minuto de telefonía celular, según el plan al que pertenezca el usuario
  • Las condiciones para aceptar o rechazar una solicitud de crédito
  • Los parámetros para realizar descuentos por compra de productos en combo
  • Las condiciones para admitir a un estudiante en una Universidad

Las reglas evolucionan a lo largo del ciclo de vida de la organización debido a su estrecha dependencia de los motivadores de negocio (e.g. autoservicio, disminución de costos, reducción del ‘time to market’) que puede tener una organización y las fuerzas externas (e.g. competencia, exigencias legales). Por tal razón, el tiempo de respuesta ante dicha evolución debe ser el mínimo posible al igual que el impacto económico ante un cambio en un motivador o en una fuerza externa. Es así como la decisión de mantener dentro del código de una o varias aplicaciones de la empresa las reglas de negocio, tiene gran impacto económico. Específicamente debido a la cantidad de cambios que se puedan requerir, para ajustar el código en las aplicaciones en el momento en que apremia satisfacer una necesidad de negocio basada en una nueva regla o en el cambio de una de éstas.

Los motores de reglas de negocio o BRMS (Business Rule Manager Systems) surgen como una alternativa de solución a la problemática de administrar el cambio de las reglas de negocio en una organización. En particular los BRMS ofrecen:

  • Un repositorio común a las aplicaciones donde se guardan las reglas de negocio versionadas
  • Herramientas que permiten definir estas reglas tanto a usuarios técnicos (desarrolladores) como a usuarios no técnicos (directivos, expertos de negocio)
  • Independencia entre el lenguaje de programación de una aplicación y el lenguaje para expresar las reglas
  • Facilidad para definir las reglas de negocio, por categorías, en un lenguaje de alto nivel propio del motor de reglas
  • Un mecanismo de despliegue de las reglas de negocio
En el desarrollo de este tutorial utilizaremos Drools, que es el administrador de reglas de negocio de JBoss, como también la consola web de administración JBRMS para modificar las reglas.

Requisitos
Para la realización de este tutorial es necesario que se encuentre familiarizado con el desarrollo de aplicaciones Java en el ambiente de desarrollo Eclipse. Además se espera un conocimiento mínimo sobre WebServices y desarrollo de aplicaciones Web con tecnología de servlets.

Se quiere construir un sistema de consulta y préstamo de libros para una biblioteca web. De cada libro la biblioteca almacena: (1) un título, (2) una lista de autores, (3) una referencia bibliográfica que debe ser única, (4) una lista de descriptores y (5) un número de ejemplares disponibles.

El periodo de préstamo de un libro se determina a partir de la evaluación de ciertas características del libro y del usuario que lo solicita. En particular, la biblioteca tiene como motivador de negocio centrarse en los usuarios en el momento de ofrecer sus servicios. Es por esto que, la biblioteca permite el ajuste de periodos de préstamo al comienzo de cada semestre y esporádicamente en el trascurso del semestre. Este ajuste se debe a que con el cambio de libros sugeridos en los programas de los cursos, los profesores se ven en la necesidad de solicitar a la biblioteca un periodo máximo para el préstamo de libros debido al volumen de préstamos que se prevé en el semestre. De esta forma el servicio que se da a los estudiantes y al mismo profesor es a la medida.

Debido a lo anterior, se desea incorporar al sistema de la biblioteca un servicio de préstamos que revise algunas características del libro alquilado y del usuario que solicita el libro y de acuerdo a unas reglas de negocio definidas determine el número de días que se va a prestar el libro. El servicio de préstamos debe estar desacoplado de la aplicación actual con lo cual se quiere que el servicio de cálculo de días de préstamo se exponga como un webservice.

Se requiere además que la tecnología utilizada para la administración de las reglas sea JBoss Drools.

Adicionalmente se tiene como restricción, que el administrador de las reglas del negocio no necesariamente es un programador, por lo cual el mecanismo para modificar las reglas se haga de manera independiente al desarrollo de la aplicación. Para esta restricción se impone que se debe acoplar el Drools - BRMS a la aplicación de la biblioteca para permitir la creación y modificación de reglas desde una interfaz web, totalmente independiente del entorno de desarrollo de la aplicación. En particular, el cambio del periodo de préstamo de libros lo realiza el administrador de la biblioteca.

La descripción de los requerimientos funcionales se encuentra en la sección con dicho nombre.

Las siguientes restricciones existen sobre la implementación de la solución:

  • Se debe hacer un desarrollo basado en componentes y utilizar servlets y JBoss para el sistema de la biblioteca.
  • El sistema de préstamos debe ser implementado de manera independiente a la aplicación de la biblioteca y la comunicación entre ambas partes se realiza mediante web services.
La administración de las reglas debe hacerse mediante el drools-jbrms (JBoss Business Rules Management System) y la aplicación debe comunicarse con la interfaz web que ofrece este sistema.<