Posteado por: edeortuzar | 27/06/2012

Como probar una regla Drools sin utilizar Guvnor


Hace ya casi tres años que estoy como líder de un proyecto en el que usamos Drools como motor de inferencia. Nuestro proyecto ya gano el premio internacional de innovación otorgado por la gente de RedHat (http://customers.redhat.com/2010/06/17/anses-jboss-innovation-award-winner/) y una mención como caso de éxito CIO CONO Sur 2011, como el más votado entre los CIOs presentes en el evento (http://america.infobae.com/notas/38321-Casos-exitosos-dentro-y-fuera-de-la-nube).

En este tiempo he tomado cursos específicos de la herramienta y he tenido contacto con gente de desarrollo del core de dicha herramienta.

Y ahora que tengo un poco más de tiempo me voy a dedicar a compartir los conocimientos adquiridos en este tiempo.

En este caso, la idea es poder probar reglas sin tener que utilizar el Guvnor ni tener que andar generando clases con propiedades, etc.

La idea es utilizar JBoss Developer Studio, ir menú File – New Project – Drools Project.

En ese momento nos muestra el wizard para crear el proyecto. Lo único que tenemos que indicar es el nombre, por ejemplo: Test

Le damos Finish.

Esto nos crea el proyecto Test.

En la clase DroolsTest quitar el código y pegar el siguiente:

package com.sample;

import java.util.HashMap;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderErrors;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.logger.KnowledgeRuntimeLogger;
import org.drools.logger.KnowledgeRuntimeLoggerFactory;
import org.drools.runtime.StatelessKnowledgeSession;

public class DroolsTest {

@SuppressWarnings({ “restriction”, “rawtypes” })
public static final void main(String[] args) {
try {

KnowledgeBase kbase = readKnowledgeBase();
StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession();

KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newConsoleLogger(ksession);

ksession.execute(new HashMap());

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

private static KnowledgeBase readKnowledgeBase() throws Exception {
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource(“Sample.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;
}

}

Como verán acá no se está insertando ningún objeto, solo un HashMap

ksession.execute(new HashMap());

Luego en el archivo Sample.drl borrar todo el código original, copiar y pegar el siguiente código:

package com.sample

import java.util.HashMap;

declare Persona
nombre : String
porcentajeDiscapacidad : Double
gradoDiscapacidad : String
end

declare Parametro
porcentajeDiscapcidadDesde : Double
porcentajeDiscapcidadHasta : Double
gradoDiscapacidad : String
end

rule “Primera regla que se va a ejecutar”
when
$ini : HashMap()
then

Persona objeto = new Persona();
objeto.setNombre(“Pedro”);
objeto.setPorcentajeDiscapacidad(16.0);
insert(objeto);

Persona objeto2 = new Persona();
objeto2.setNombre(“Juan”);
objeto2.setPorcentajeDiscapacidad(75.0);
insert(objeto2);

Parametro objeto3 = new Parametro();
objeto3.setPorcentajeDiscapcidadDesde(0.0);
objeto3.setPorcentajeDiscapcidadHasta(49.9);
objeto3.setGradoDiscapacidad(“A”);
insert(objeto3);

Parametro objeto4 = new Parametro();
objeto4.setPorcentajeDiscapcidadDesde(50.0);
objeto4.setPorcentajeDiscapcidadHasta(69.9);
objeto4.setGradoDiscapacidad(“B”);
insert(objeto4);

Parametro objeto5 = new Parametro();
objeto5.setPorcentajeDiscapcidadDesde(70.0);
objeto5.setPorcentajeDiscapcidadHasta(100.0);
objeto5.setGradoDiscapacidad(“C”);
insert(objeto5);

retract($ini);
end

rule “Test”
when
$p : Persona($porcentajeDiscapacidad : porcentajeDiscapacidad, gradoDiscapacidad == null)
$par : Parametro($gradoDiscapacidad : gradoDiscapacidad, porcentajeDiscapcidadDesde <= $porcentajeDiscapacidad, porcentajeDiscapcidadHasta >= $porcentajeDiscapacidad)
then
$p.setGradoDiscapacidad($gradoDiscapacidad);
update($p);
System.out.println(“Para ” + $p.getNombre() + ” el grado de discapacidad es ” + $p.getGradoDiscapacidad());
end

Como se puede ver en el código lo que hacemos es utilizar la sentencia DECLARE para declarar los objetos, solo con el nombre, sus atributos y el tipo de dato de estos. Ejemplo:

declare Persona
    nombre : String
    porcentajeDiscapacidad : Double
    gradoDiscapacidad : String
end

Luego hacemos una regla fake para generar las instancias de dichos objetos con los datos que queremos. Esta es la regla “Primera regla que se va a ejecutar”.

El when de dicha regla tiene como única condición $ini : HashMap() que es lo único que insertamos en la clase DroolsTest.java cuando hicimos el execute.

ksession.execute(new HashMap());

En el then de dicha regla tenemos la instanciación de los objetos, el seteo de sus atributos y el insert en memoria de los mismos.

Persona objeto = new Persona();
objeto.setNombre(“Pedro”);
objeto.setPorcentajeDiscapacidad(16.0);
insert(objeto);

Y por último el retract del objeto HashMap para que esa regla se ejecute solo una vez.

retract($ini);

Luego de dicha regla tenemos nuestra regla que queremos ejecutar.

Para probarla, hacemos botón derecho sobre el proyecto Test, vamos al menú Run As y seleccionamos la opción Java Application, la primera vez que lo ejecutamos nos pregunta cual es el inicio del proyecto, para lo que escribimos DroolsTest y seleccionamos la clase que nos muestra en el listado.

Y listo, de esta manera podemos ver el resultado de la regla, poner mas mensajes de salida para controlar que pasa a cada momento, etc.

Espero que les sirva e interese.

Saludos.

Anuncios

Responses

  1. Hola Miguel, por lo que entiendo puede ser que te falte registrar el proyecto de las clases. Yo uso Maven y tengo que hacer un install para poder hacer eso, si es que te entendí bien. Sino copia parte del código para que lo vea y analice un poco.
    Saludos


Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

Categorías

A %d blogueros les gusta esto: