Primero que nada bienvenidos al post numero #15 de la serie Jugando con jBPM. En este post veremos algunos detalles del componente de identidades.

Como estamos acostumbrados a ver en la típica imagen de arquitectura (o división lógica del proyecto) de jBPM se diferencia el componente de Identity (Identidades) como un bloque separado del core del framework:

Componentes de jBPM

Componentes de jBPM

Esta separacion le da a jBPM la flexibilidad de poder adaptarse a cualquier modulo de identidades que ya se encuentre en la empresa donde se vaya a realizar una implementación.

Pero entonces, en que consiste este modulo Identity que muestra la figura?

La respuesta es bastante simple, consiste en un modulo muy simple, que funciona out-of-the-box, que cuenta con tres conceptos para administrar nuestras identidades: Usuarios, Grupos y Membresias (User, Group y Membership). La idea es que apenas empezamos a usar jBPM ya tengamos una forma fácil y sencilla de user datos de usuarios, grupos y las relaciones N a N entre ellos con las membresias.

Esto no quiere decir que jBPM esta fuertemente acoplado a este esquema de usuarios, ya que en la mayoría de los casos, tenemos que adaptarnos a implementaciones y estructuras ya existentes de identidades.

Llegado al caso en el que tenemos que remover el componente de identidades que viene con jBPM y adaptar nuestro propio componente, debemos tener en cuenta cuales son los pasos a seguir y que bloques o clases debemos reescribir para adaptarnos.

El primer dato que encontramos si buscamos un poco sobre el tema es que debemos comentar en el archivo hibernate.cfg.xml las siguientes lineas:

<!-- identity mappings (begin) ===
<mapping resource="org/jbpm/identity/User.hbm.xml"/>
<mapping resource="org/jbpm/identity/Group.hbm.xml"/>
<mapping resource="org/jbpm/identity/Membership.hbm.xml"/>
==== identity mappings (end) -->

Estos mapeos de hibernate se encargan de administrar las entidades que se manejan en este modulo que viene por defecto, cuyo diagrama de clases es el siguiente:

Modelo de Clases de Identity

Modelo de Clases de Identity

Por lo tanto desactivando estos mapeos desacoplamos totalmente a jBPM de este modulo de identidades que viene por defecto, y estamos listos para insertar nuestro propio (puede ser ya existente) modelo al framework.

jBPM para realizar este desacoplamiento de la forma mas transparente posible, maneja el concepto de actor, que es simplemente un String que representa a nuestros usuarios o grupos de usuarios.

Ahora bien, si en este punto nosotros tenemos un proceso que tiene una tarea y la asignación de esta tarea se realiza mediante una expresion, como por ejemplo:

<task name="Elegir tarea del dia">
 <assignment expression="group(admin)"/>
 ..

Esta expresión lo que hace es resolver el grupo admin y asignarle la tarea a todos los usuarios de este grupo (en este caso admin).

Les recomiendo que vean en la documentación oficial como pueden ser estas expresiones ya que es un tema bastante interesante. (link: http://docs.jboss.com/jbpm/v3.2/userguide/html_single/#theidentitycomponent)

Por lo tanto si tratamos de ejecutar nuestro proceso y hemos desactivado los mapeos a las entidades de hibernate, vamos a ver en la consola el siguiente WARN:

11:10:24,812 [main] WARN  QuerySplitter : no persistent classes found for query class: select g from org.jbpm.identity.Group as g where g.name = :groupName

Que nos dice exactamente eso, no tiene ninguna clase para consultar los grupos de usuarios y resolver la expresion que habiamos puesto en el tag assigment dentro de nuestra tarea.

Entonces, la pregunta que se hace obvia es: quien se encarga de hacer estas resoluciones de expresiones?

La respuesta tambien es obvia y es una clase llamada: org.jbpm.identity.assignment.ExpressionAssignmentHandler

La cual mediante una propiedad ExpressionSession expressionSession, se encarga de comunicarse con el esquema de identidades que se encontraba mapeado con hibernate. En este caso del mapeo con hibernate donde nuestro esquema de identidades se encuentra almacenado en la base de datos (es muy comun que el esquema de identidades este en un Arbol LDAP tambien) la clase que implementa la interfaz ExpressionSession para esta implementacion del componente de identidades es: org.jbpm.identity.hibernate.IdentitySession.

SI analizamos los metodos de esta clase veremos que ellos cumplen con todas las funcionalidades necesarias para resolver usuarios y grupos de la manera mas simple (en este caso realizando consultas con la session de hibernate a las entidades mapeadas).

Algunos metodos de org.jbpm.identity.hibernate.IdentitySession:

</pre>
public User getUserByName(String userName) {
    User user = null;
    Query query = session.createQuery(
      "select u " +
      "from org.jbpm.identity.User as u " +
      "where u.name = :userName"
    );
    query.setString("userName", userName);
    List users = query.list();
    if ( (users!=null)
         && (users.size()>0) ) {
      user = (User) users.get(0);
    }
    return user;
  }

  public Group getGroupByName(String groupName) {
    Group group = null;
    Query query = session.createQuery(
      "select g " +
      "from org.jbpm.identity.Group as g " +
      "where g.name = :groupName"
    );
    query.setString("groupName", groupName);
    List groups = query.list();
    if ( (groups!=null)
         && (groups.size()>0) ) {
      group = (Group) groups.get(0);
    }
    return group;
  }

Como ultimo dato agrego que la sugerencia, muy correcta en la documentación, dice que si queremos reutilizar el esquema de acceso a los componentes de identidades que nos propone jBPM debemos extender la clase ExpressionAssignmentHandler y sobre escribir el método getExpressionSession que en este caso nos devolvería en vez de un org.jbpm.identity.hibernate.IdentitySession nuestra propia implementación de acceso a nuestras propias identidades.

Entonces las ideas que me gustaría que quedaran claras en este post son las cosas a tener en cuenta para implementar o acoplar un nuevo esquema de identidades a jBPM.

También espero que les sirva como punta pie inicial para investigar en profundidad estas expresiones de asignación que son muy importantes cuando tenemos tareas y grupos de usuarios complejos.

Cualquier consulta, ya saben que estoy a su disposición.

jBPM vs 7 visiones de BPM

Noviembre 3, 2008

Pocas veces hago un review sobre algún articulo que publica alguien mas, ya por lo general me gusta expresar mi visión sobre los distintos frameworks con los que suelo jugar todos los dias.

En este caso me dedico a comentar un articulo escrito nada mas y nada menos que por el senior Tom Baeyens (Leader y Core Developer del desarrollo de jBPM), tambien agregándole mi vision y no tanto traduciendo el articulo.

En este articulo, lleno de experiencia, Tom comenta 7 formas distintas de ver a BPM, ya que actualmente BPM es un termino muy sobrecargado y por esto es muy importante  distinguir entre los distintos significados a la hora de abordar el tema no solo tecnológica mente sino en todos los aspectos que el termino califica.

A continuación vemos estas 7 visiones de BPM resumidas del articulo original:

1) BPM como una disciplina:

Siempre debemos recordar que Business Process Management surge como una disciplina que se enfoca en el análisis, la documentación y la mejora de procesos que dictan como las personas y los sistemas trabajan dentro de una organización.

En esta disciplina se hace un esfuerzo para, primero que nada detectar y visualizar como trabajan las personas, como se comunican entre ellas, como se mueve la información que administra la organización, etc. Una vez que tenemos un estudio inicial se formalizan estos procesos en algún lenguaje como BPMN (Business Process Management Notation) y al mismo tiempo se trata de mejorar estos procesos para ahorrar tiempos y recursos dentro de la organización.

Como podran ver (y si leen un poco de BPMN) nos damos cuenta que en esta disciplina hay una distancia bastante considerable con el aspecto tecnológico. Ya que por lo general el resultado de esta disciplina, son los procesos optimizados presentados como una extensa documentación.

Por lo tanto, como menciona Tom en su articulo, jPDL (jBPM Process Definition Language) trata de ser el vinculo entre este análisis y formalización que se realiza en la disciplina con el aspecto tecnológico de un proyecto de software.

2) Combinando administración de tareas basadas en templates y tareas ad-hoc

Las cosas importantes que me parece que hay que destacar en este punto del articulo es que por lo general en los procesos de la vida real se termina haciendo una orquestación de las tareas humanas que se definen formalmente. Y por lo general, no es un tema al que se le preste mucha atención ya que por lo general estas orquestaciones, para que funcionen bien hay que ser muy rigurosos en cuanto al modelado y cubrir todas las posibles excepciones que puedan llegar a presentarse en la ejecución de las mismas.

Esto presenta situaciones donde la complejidad del análisis es alta y el costo de estabilizar estos procesos es alto.

Para esto en jBPM 4 van a aparecer las tareas ad-hoc que nos permiten definir tareas dentro de tareas, es decir que dentro de una tarea podamos crear sub tareas y asignarlas para modelar situaciones complejas donde las tareas humanas juegan un rol mas que importante en nuestros procesos.

3) Arquitecturas asíncronas transaccionales:

Como ya nos imaginamos con el nombre de este caso de uso, esta perspectiva esta fuertemente asociada a conceptos técnicos y de implementación de BPM, y por lo tanto esta en gran contraste con el caso de uso numero uno (BPM como disciplina).

En este caso, el proceso que vamos a implementar, por lo general no tiene relación con ningún proceso de nivel de negocio real. Sino que nuestro proceso nos va a permitir reflejar una implementación limpia y transparente para una solución compleja de comunicación entre varios puntos de manera transaccional (esto quiere decir, que en todo momento podremos saber en que estado estamos y tenemos la posibilidad de deshacer todo lo que hemos hecho, por conocer el estado en el que estamos y los estados por donde fuimos pasando)

4) Orquestacion de servicios

Esta es otra de las frases mas escuchadas cuandos se habla de jBPM, y este caso de uso es un caso particular del mensionado en el punto 3, ya que tambien esta fuertemente basado en la comunicaciones asincronicas entre varios interesados, pero en este caso la implementación de la comunicación suele darse por medio de un ESB (Enterprise Service Bus). “En estos casos es donde BPEL cobra un sentido fuerte, ya que se caracteriza por darnos un lenguaje de comunicación común y standard para nuestras comunicaciones”.

5) Programación Visual

La programación visual, como menciona Tom en el articulo, es importante ya que brinda a los analistas y a desarrolladores que no estan tan acostumbrados a entornos Java, a empezar fácilmente dibujando los procesos de manera bastante simple.

Si bien esto es mucho menos flexible que la programación en Java, esto presenta varias ventajas entre las cuales se incluyen: una curva mucho mas baja de aprendizaje, un alto impacto visual y fácil comprendimiento.

6) Lenguaje de Control de ejecuciones multi hilo

Es importante notar un caso particular de esta programación visual que mencionábamos en el punto anterior, ya que el lenguaje que utilizamos cuando programamos visualmente (con designer / plug in para eclipse de jBPM) nos permite, usando nodos Fork/Join, modelar situaciones donde concurrentemente deben ejecutarse varias ramas del mismo proceso.

7)  Fácil creación de DSLs (Data Definition Languages)

Uno de los pilares de jBPM es reconocer que cada entorno de los procesos en la vida real es distinto. Por lo tanto una sola nomenclatura para definir los nodos de nuestros procesos no basta. Por esto mismo jBPM presenta jPDL, BPEL y PageFlow (de Seam) como tres lenguajes propuestos para tres entornos distintos.

Pero la idea real detras de todo esto es que sobre la Process Virtual Machine (PVM, el nucleo de jBPM) pueda escribirse/definirse cualquier lenguaje que se adapte correctamente al entorno del proceso que vamos a modelar.

Como menciona Tom en su conclusión, la mayoría de las personas que han leido poco de BPM y jBPM piensan que BPM es un software donde podemos dibujar un flujo de acciones y ya estamos listos para ejecutarlo y ponerlo en producción. Esta es una idea que escapa mucho a la realidad del framework jBPM y a la teoría de BPM en general, por esto mismo deben tenerse en cuenta estos puntos planteados.

Les dejo el link del articulo original para que lean la experiencia de Tom y los links que deja ya que son muy interesantes, porque amplían en detalle el tema.

http://java.dzone.com/print/5585

En este post vamos a ver un poco de la API para la administración de tareas en jBPM, la cual es muy útil a la hora consultar las tareas que se van creando a medida que nuestra ejecución del proceso va pasando por los diferentes Task Nodes que tengamos definidos.

En este caso, y para este ejemplo, cree el siguiente proceso básicamente compuesto por Task Nodes:

Proceso Ejemplo

Proceso Ejemplo

Como vemos en la imagen, una vez que el proceso comience se creara una tarea contenida dentro del task node “Elegir Tarea del Dia”. Como por defecto las tareas que van a ser realizadas por personas se comportan como Wait States (Estados de espera), nos bloquean la ejecución del proceso. Por lo tanto el comportamiento del proceso sera el siguiente:

1) Se comienza la ejecución del mismo desde el nodo Start (mediante la llamada al método signal)

2) La ejecución del proceso llega hasta el task node llamado “Elegir Tarea del Dia”, crea las instancias de las tareas que estan especificadas dentro del task node (crea objetos TaskInstance).

3) Se persisten los cambios y las instancias de las tareas que se crearon en el schema de jBPM, para esperar la interacción del usuario.

Cuando el usuario quiere interactuar con la tarea que fue creada para el debe ir a buscar en su lista de tareas, donde encontrara todas las TaskInstances que fueron creadas por procesos para el.

Una vez que encontramos la tarea que queremos comenzar en la lista de tareas, deberíamos seleccionarla, completar los datos y luego finalizarla para que el proceso continúe su ejecución.

En esta caso, para el ejemplo decidi que la tarea dentro del task node “Elegir Tarea del Dia”, tuviera como requerida una variable que se llama “tarea” que le va a indicar al proceso porque rama continuar su ejecucion usando el valor de esta variable para decidir en el nodo decisión.

Vamos a ver un poco el código asi se van aclarando las cosas, para esto les cuento un poco el contexto donde estoy ejecutando el siguiente bloque de código:


context=conf.createJbpmContext();
// Obtenemos a partir del contexto una sesion del administrador de tareas, esta nos dara acceso a todas las tareas
// creadas en todos los procesos y asignadas al usuario salaboy.
// Tambien podriamos haber utilizado la instancia del proceso para acceder a una API mas enfocada a la instancia
// del proceso.
List<TaskInstance> tasksForSalaboy=context.getTaskMgmtSession().findTaskInstances("salaboy");

// Itereamos sobre la lista de tareas para el usuario Salaboy
// de esta manera deberiamos armar la UI
for(TaskInstance ti : tasksForSalaboy){
System.out.println("TaskInstance ID: "+ti.getId()+" - Name: "+ti.getName()+ " - Creada: " +ti.getCreate());

}
if(tasksForSalaboy.size() > 0){

TaskInstance elegirTarea=tasksForSalaboy.get(0);

System.out.println("Encontre una tarea = "+elegirTarea.getName());
// Deberiamos comprobar que es la tarea de elegir tarea
// Lo podemos hacer revisando el nombre de la tarea con elegirTarea.getName()
elegirTarea.start();
//Comprobamos que no tenga seteada nada la variable
assertNull(elegirTarea.getVariable("tarea"));
System.out.println("la variable TAREA tiene el valor = "+elegirTarea.getVariable("tarea"));
// Le asignamos el valor lavar a la variable tarea, cocinar nunca antes morir!
elegirTarea.setVariable("tarea", "lavar");
System.out.println("la variable TAREA tiene el valor = "+elegirTarea.getVariable("tarea"));

assertEquals("lavar",elegirTarea.getVariable("tarea"));
//Terminamos la tarea

elegirTarea.end();

}

context.close();

Hay que tener en cuenta que para ejecutar este bloque de código tenemos que tener una instancia de JbpmConfiguration (la variable conf) que debe estar correctamente configurada para comunicarse con nuestra fuente de datos que contiene el schema de jBPM (esta configuración se realiza en el archivo hibernate.cfg.xml).

Creo que el codigo se explica por si solo y los comentarios ayudan en caso de que no se entienda alguna linea en particular. Como se que si no ven el proyecto entero se complica terminar de entender el ejemplo, subi el proyecto entero (pesa 45k) a rapidshare para que pueda verlo. Aca les dejo el link:

(Actualizado)

http://rapidshare.com/files/289991585/jBPMTaskMGMTExample.zip.html

Algunas Notas sobre el Ejemplo:

1) Uso postgreSQL como base de datos, por lo tanto necesitaran el driver JDBC de postgreSQL (el cual pueden descargar de aca: http://jdbc.postgresql.org/download.html, revisar bien la version que necesiten)

2) En este ejemplo la configuración realizada en hibernate.cfg.xml es para un cliente standalone y no para el framework deployado en un Servidor de Aplicaciones como JBoss. En el caso de estar dentro de una aplicación que esta corriendo sobre JBoss habría que configurar un DataSource y no la conexión directa por JDBC.

3) El ejemplo esta creado con eclipse y el plug in de jBPM, no es como acostumbro a trabajar pero para las personas que estan comenzando me parece un buen punto de partida. (Ver post anteriores para ver como configurar el plug in de jBPM en eclipse/ También llamado designer )

4) Toda la funcionalidad del proyecto se encuentra en una clase que utiliza JUnit para realizar las pruebas de funcionalidad. Buscar en la sección de Tests (scr/test/java/com/sample/SimpleProcessTest.java). Estas pruebas no estan muy prolijas por cuestiones de tiempo.

5) Si el link de rapidshare se cae, por favor avisar asi lo vuelvo a subir.

Les dejo el link de la documentacion oficial donde se habla bastante sobre las tareas:

http://docs.jboss.org/jbpm/v3/userguide/taskmanagement.html

Es importantísima!!!!!!! la sección que se llama: “11.2.2. Task instances and graph execution”

Saludos, espero que sirva de ayuda para entender el uso muy basico de la API, en un post futuro prometo escribir un post sobre la API mas en profundidad.

Cualquier duda sobre la documentacion oficial o sobre este post, no duden en comentar!!!