Es algo sobre lo que se pregunta bastante, ya que es un concepto que esta asociado con el modelado de procesos en general. Para no confundir, podemos definir a una swimlane como un rol del proceso, para ser mas especificos, podriamos decir que vamos a usar una swimlane cuando en un proceso que estemos modelando necesitemos especificar que un set de tareas deben ser realizadas por la misma persona, ya que esta es la que conoce el contexto de esas tareas para una instancia del proceso en particular.

Por lo tanto el comportamiento que vamos a obtener en jBPM es el siguiente:

  • Definimos (modelamos) varias tareas asignadas a una swimlane
  • Cuando la primer tarea de la swimlane se instancia, se llama al AssignmentHandler correspondiente y se asigna un actor a la swimlane
  • Cuando la segunda tarea de la swimlane se instancie, se recupera el actor ya asignado por el AssignmentHandler y se asigna este a la tarea.
  • Así para el resto de las tareas que estén asignadas a la swimlane.

Por lo tanto debemos tener cuidad de no aplicar un assignment handler a las tareas que se encuentran con una swimlane especificada.

Notas o aclaraciones nuevas:

Voy a tratar de en un par de puntos aclarar algunos conceptos que puede ayudar:

  • En la definicion del proceso definimos task-node y task.
  • Las task-nodes contienen 0 o mas task, las cuales se instancian dinámicamente (por defecto) cuando el flujo del proceso llega al task-node que las contiene
  • En el momento de instanciación de cada una de las tareas (tasks dentro del task-node) se llama al correspondiente AssignmentHandler que esta definido en cada tarea.
  • En un caso normal este AssignmentHandler resuelve a que actor del proceso le corresponde realizar la tarea y asigna al campo ActorId el nombre del actor obtenido. (También esta el caso de pooled actors pero no viene al tema)
  • En el caso de que haya varias tareas a lo largo de varios task-nodes asociadas a un swimlane, genera otro comportamiento, que describo a continuación:
    • Cuando el flujo de ejecución del proceso llega al primer task-node que contiene una tarea la cual esta asociada a una swimlane, esta tarea se instancia y se llama al assignment que tenga asociado la swimlane. Este AssignmentHandler tiene la particularidad que solo va a ser invocado por la primer tarea que se instancie y que este asociada con la swimlane. Lo que significa que cuando se instancie la segunda tarea asociada a la swimlane, el actor ya estará resuelto y deberá llamarse al AssignmentHandler correspondiente. Todo esto se logra manteniendo una ” instancia”  de la clase SwimlaneInstance con el actor ya resuelto y recordándola (o sea persistiendo la) para que las nuevas tareas no tengan que realizar la logica de asignación nuevamente.

Espero que haya quedado un poco mas claro, prometo subir un ejemplo para discutir mas adelante.

Saludos!

34 comentarios para “Jugando con jBPM #13 – Swimlanes a nivel conceptual”

  1. Diego López León escribió

    ahora sí le entendí sala.
    Haberme dicho que ponga tu blog en mis rss fue un grave error de tu parte ;P

  2. Rodrigo escribió

    Yo no entiendo muy bien lo de las dos tareas asociadas a la swimlane. Mi problema es integrar el jbpm con mi modelo de usuarios ya que hay ciertas tareas que solo podrian realizar determinados usuarios, si explicaras un poco más lo de las swimlanes a mi me ayudarias un monton.
    Gracias

  3. salaboy escribió

    Con las nuevas anotaciones aclare un poco tu visión sobre el asunto? si tenes mas preguntas concretas serán bienvenidas!
    Saludos, gracias por tu comentario!

  4. Rodrigo escribió

    Algo mas claro si, gracias.

    Aun asi no se como se le asigna Handlers a las swimlanes, creo que con un buen ejemplo me aclararia mucho mejor, asi q esperare para plantear mas dudas.

    Gracias a ti!

  5. Sebastian Arbona escribió

    Excelente iniciativa salaboy, saludos desde el jug que esta a tres grados al oeste del jugmza, ;)

  6. salaboy escribió

    No he tenido mucho tiempo, para hacer el ejemplo, hoy trato de postear alguno. Saludos.. Disculpen la demora

  7. sergio escribió

    … quede un poco perdido.. espero a que postees el ejemplo para ver si comprendo mejor.

  8. Jorge escribió

    Hola. Estoy comenzando a investigar un poco sobre jBPM y me parece realmente interesante este blog. Tengo un problema porque no consigo descargarme los fuentes del console para empezar a probar cosas. Con la suite viene el jbpm-console.war, pero no consigo encontrar los fuentes. Estoy peleándome con la CVS, pero no consigo localizarlo. Podría alguien echarme un cable, por favor?

  9. salaboy escribió

    Gracias por tu comentario Jorge, te comento
    que el repositorio del código nuevo de jBPM esta en http://anonsvn.jboss.org/repos/jbpm/jbpm3/trunk/
    que pertenece a SVN, no a CVS, asi que deberías revisar estos fuentes nuevos.
    Una cosa que vas a notar es que actualmente, como en la mayoría de los proyectos de JBoss, se utiliza Maven y no Ant para compilar y administrar el código. Por lo cual vas a tener que instalarlo también aparte de SVN.
    En cuanto al código de la consola web, en este repositorio se encuentran en: http://anonsvn.jboss.org/repos/jbpm/jbpm3/trunk/modules/console/
    Cualquier duda sobre ese repositorio o sobre la consola, no tienes mas que comentar.
    Saludos

  10. Jorge escribió

    Muchísimas gracias!!! Te quiero!! ;)

    De todas formas, ando perdido, un poco más cerca, pero sigo perdido. Me he instalado un pluggin de eclipse para svn y me he traído el código de http://anonsvn.jboss.org/repos/jbpm/jbpm3/trunk/modules/console/, tal y como me indicas y me crea un proyecto jbpm-console en mi workspace. Parece que va bien, pero cuando reviso el proyecto que me crea sólo hay una clase java (ProcessUploadServlet.java) y además me lo marca con error(no encuentra los imports). Realmente no tengo ni idea, no sé si es algo que se arreglará al utilizar el maven o qué (no lo he usado nunca).
    Por último me he instalado un pluggin de maven (de apache) y ya sí que no sé qué hacer. Nunca he utilizado ni ant ni maven. He leído un par de páginas sobre maven, pero no consigo avanzar.
    Lo que yo quiero es un proyecto en eclipse que tenga el jbpm-console, que pueda ir tocando y desplegando para ir viendo cómo queda e investigar un poco. En la oficina tienen los fuentes del 3.2, pero ya no se parece en nada al original (muy personalizado) y además, me gustaría echarle un ojo a la 3.2.3, que me parece bastante más completa.
    Podrías ayudarme otra vez? quizás unas instrucciones para tontos me vendrían bien. Perdona por molestarte, pero ando algo desesperado.

    Por otra parte, si alguien tiene los fuentes ya en un proyecto eclipse y me lo puede pasar se lo agradecería eternamente.

    Gracias a todos

  11. Jorge escribió

    Ups! se me olvidaba: he leído en los foros de jboss que también haría falta el módulo jbpm4jsf, con lo que ya me han matado…

  12. Jony escribió

    Hola. Estoy investigando un poco sobre jbpm y este blog me resulta de gran utilidad por lo cual queria agradecrte y felicitarte. Estamos tratando de desarrollar una aplicacion que pueda ejecutar genericamente varios diferentes process definitions y a tal fin queria saber si existe la forma de asignar un Process Definition a un swimlane particular o si estos sirven unicamente para definir a nivel de tarea. Gracias.

  13. salaboy escribió

    Primero que nada gracias por tu comentario!
    Paso a responder tu pregunta, primero que nada debes saber que el concepto de swimlane vive dentro del process definition a la hora de la definición. Luego en la ejecucion, solo tiene influencia sobre los nodos asignables (que por lo general son tareas, y el nodo start-state el cual puede definir una tarea dentro del mismo). Por lo tanto la respuesta concreta a tu preguntas es No. Sin embargo, a mi punto de vista, ese tema tendrías que limitar la ejecución de varios process instances a nivel presentación o a nivel autorización de usuario. Espero haber sido claro, sino no dudes en volver a escribir.
    Saludos!

  14. Jony escribió

    Clarisimo. Muchas Gracias.

  15. salaboy escribió

    De nada, cualquier cosa, ya sabes donde encontrarme!
    Saludos

  16. Rosa escribió

    Holaa!! he estado leyendo y creo que lo que yo necesito son grupos de usuarios por que dentro de ese grupo cualquiera puede realizar un task…
    ahora me confunde un poco esta definicion …

    < swinlane name=”nombre” >
    < assignment expression = “group (administradores)” class = “……..”>

    esta definicion es para un grupo de usuarios?

    por que por lo que he estado leyendo en tu blog dice que tienes un swinlane pero que a cada task tienes que asignarle un actor-id … en mi caso cualquier actor del grupo de actores que yo seleccione puede realizar una determinada tarea…
    como se manejan los grupos de usuarios? como los defino ?

  17. Guillermo escribió

    Hola,

    no comprendo muy bien la diferencia de declarar un swimlane o hacer algo de este estilo:

    ….

  18. Guillermo escribió

    Uy no ha salidooo lo que queria poner…

    ….

  19. Guillermo escribió

    No sale el XML que pongo, ¿por qué? :(

  20. Guillermo escribió

    Bueno, dicho todo en prosa. No entiendo cual es la diferencia entre usar Swimlane o dentro de un task-node–>task hacer un assigment de un actor_id o un pooled_actors. ¿Es equivalente o cual es la diferencia?

    Muchas gracias.

  21. salaboy escribió

    Buena pregunta.
    Perdon por lo del XML pero parece que wordpress considera que los usuarios no deben ingresar tags de ningun tipo.
    Respondiendo a tu pregunta, si hay diferencias, entre usar un swimline y hacer las asignaciones en cada tarea.
    En realidad justamente esa es la diferencia. La asignacion en un swimline se hace cuando se llega a la primer tarea que esta dentro de un swimlane especifico. Una vez hecha esta asginacion se propaga al resto de las tareas que tengan el mismo swimlane. Esto quiere decir que no se debera llamar a los assignment handlers por cada nueva tarea que se cree con ese swimline.
    Esto suele ser util en muchas situaciones, donde se requiere que una misma persona atienda por ejemplo a un mismo cliente en distintas tareas a lo largo de un proceso.
    Haciendo las asignaciones en cada caso, podria asignarses distintas personas para atender a un cliente.
    Espero que se haya entendido la respuesta.
    Cualquier cosa comenta de vuelta.
    Saludos y Gracias por tu comentario!

  22. Guillermo escribió

    Gracias por la respuesta. Según entiendo te ahorrarias llamadas a los AssignmentHandler pero la funcionalidad que aportan es la misma, ¿correcto?.

    Por otra parte, tengo otra duda de JBPM a ver si sabes como funciona.

    Tengo una “tareaA” que puede hacer el rol “ROL-A” y tengo el usuario1, y usuario2 que pertenecen al “ROL-A”. Si la tareaA no está asignada a ningún usuario tanto el usuario1 como el usuario2 la pueden ver, pero en cuanto es asignada a un usuario el otro aunque tiene el rol no puede ver que esa tarea está ya activada., sino que solo puede ver las que no han sido asignadas pero que con su rol podria ejecutar.

    ¿Sabes si con JBPM se podrian ver todas las tareas sin asgianr o asignadas a tu mismo rol en un momento dado?

    Bueno, muchas gracias de antemano.

  23. salaboy escribió

    Gracias por tu nuevo comentario. Con respecto a la funcionalidad podria decirse que ambos realizan asignaciones, en distinto tiempo, pero la funcionalidad de asignacion es la misma. Solo que una se ejecuta varias veces y la otra sola una vez.
    Con respecto a tu segunda duda, la funcionalidad es como vos mencionas. Cuando una tarea es tomada por alguien, esta tarea tiene que desaparecer para las demas personas en el mismo rol. Esto es para que dos personas no trabajen sobre la misma tarea concurrentemente. La funcionalidad que queres obtener, podria lograrla implementando un NamedQuery que no filtre por el usuario que esta asginado. Pero deberias analizar bien que caso de uso quieres cumplir, para no cometer un error conceptual.
    Saludos

  24. Guillermo escribió

    Vale, gracias. Yo estoy intentado usar Seam-Jbpm. Te ofrece unas listas en contexto “taskInstaceList”, “pooledTaskListInstance” y poca cosa más y con esas la verdad que no me llega.

    No se muy bien que es eso de NameQuery pero mirando he visto que simplemente es una anotación para realizar consultas hacia la base de datos, ¿no?. Entonces supongo que deberia de implementar mis propias consultas SOBRE LAS TABLAS de JBPM para obtener una lista con las tareas que me interesan, ¿no?. Pues si que va a ser complicada el asunto…

  25. salaboy escribió

    No se a esta altura como esta la integracion con seam.
    Revisa la documentacion de seam para ver como funciona.
    Pero digamos que es bastante sencillo escribir una NamedQuery. Que de paso te aclaro que no son consulta directas a la base sino que estan escritas en HQL, lenguaje de consulta de Hibernate.
    Saludos

  26. Martín escribió

    Hola salaboy, antes que nada te felicito por el blog, está muy bueno y es de gran utilidad. Soy nuevo en jbpm y luego de implementar unos test, me surge la siguiente duda:

    Yo tengo una tarea que tiene swimlane=”Revisar”. Ahora bien, por otro lado tengo definido el swimlane “Revisar” que tiene como assignment expression=”group(Revisor)”. Luego tengo las siguientes líneas dentro de un test que me falla:

    List task = jbpmContext.getTaskMgmtSession().
    findTaskInstances(”1″);
    Assert.assertTrue(task.size() > 0);

    Donde 1 es el id de un usuario que pertenece al grupo Revisor en la bd.

    Lo mismo ocurre si ejecuto:

    List task = jbpmContext.getTaskMgmtSession().
    findTaskInstances(”Revisor”);

    Estoy en el nodo correcto y ejecutando la tarea correcta (de eso estoy seguro).

    Obviamente la pregunta es como recuperar las tareas en función de lo definido en expression=”group(Revisor)”

    Saludos y mil gracias.

    Martín.-

  27. salaboy escribió

    Primero que nada, Gracias por tu comentario.
    Vamos con la respuesta y vamos despacio. Ya que en tu comentario entran varios conceptos, que me van a ser dificiles de explicar en una respuesta corta.
    Primero que nada una swimline es un rol de proceso, como podria ser Contador, Administrador, Cajero, etc. Un rol de proceso como en UML representa un concepto y la capacidad de realizar alguna tarea en el dominio del proceso, y no a una persona. Por lo tanto una Swimline no deberia llamarse nunca “Revisar”, estaria bien que se llame “Revisor” como el nombre de tu grupo.
    Por otro lado, en jBPM los ids de los usuarios no son numericos, es directamente el nombre en forma de String. Por esto revisa que usuarios tienes creados, en que grupos estan dichos usuarios y directamente deberias llamar al metodo findTaskInstances(”pepe″); por ejemplo.
    Para darte una idea de como funciona las consultas que se realizan para buscar las tareas, puedes revisar las named queries que se encuentran en el archivo hibernate.queries.hbm.xml.
    Espero haber sido de ayuda. Cualquier duda espero tu nuevo comentario!
    Saludos

  28. Martín escribió

    Mil gracias por la respuesta, ahora me quedan mas claros los conceptos. En estos días seguiré haciendo pruebas y quizás vuelva a molestarte.

    Saludos.

    Martín.-

  29. Guillermo escribió

    Buenass,

    tengo otra preguntaaa. No entiendo que diferencia que hay entre poner:

    pooled_actor=’ROL1′ o pooled_actor=”group(ROL1)” que diferencia hay entre poner eso de “group” o no?

    A parte, cuando usas swimlane hay que implementar los AssigmentManager, ¿no? o solo se escribe la definición de flujo y no hay que implementar nada? He intentado cambiar los assigment por swimlane y me daba algún error que supongo que será por algo de eso..

    Muchas graciasss!

  30. salaboy escribió

    Gracias por tu comentario.
    Te comento que la diferencia entre usar la funcion group() o no es bastante. Si usas la funcion group(”GroupName”) cualquier persona que se encuentre en el grupo con nombre “GroupName” va a poder tomar y realizar esta tarea. De la otra manera solamente el usuario con ID ROL1 podra realizarla.

    Con respecto a los Swimlanes, puedes o no escribir los AssignmentHandlers. Exactamente igual que para las asignaciones de pooled actors o actors id. En las swimlanes tambien puedes usar la funcion group() si quieres.

    Disculpa la demora de mi respuesta.
    Saludos!

  31. Martín escribió

    Hola, yo te escribí hace unos días sobre el tema de los Swimlanes. Tengo el siguiente problema:

    Si tengo esta definición que la tarea tiene como assignment la expression=”group(Revisor)”

    dentro de un test
    List task = jbpmContext.getTaskMgmtSession().findTaskInstances(”Martin”);

    me retorna una tarea, puesto que el usuario martín pertence al grupo “Revisor”.

    Ahora bien, si en lugar de la definición anterior tengo una swimlane cuyo assignment tiene expression=”group(Revisor)” y mi tarea tiene swimlane=”Revisor” en lugar del assignment, entonces la línea del test anterior no me retorna nada.

    Alguna idea?.

    Muchas gracias.

    Saludos, Martín.-

  32. salaboy escribió

    Eso puede ser porque la asignacion se resuleve cuando se ejecuta la primer tarea de la swimlane.
    Tendrias que analizar bien tu flujo de ejecucion y si se esta resolviendo bien los grupos para las swimlanes.

  33. Nacho escribió

    Hola y felicidades por el blog, genial!
    Una cuestión que me intriga. Quiero que una tarea pueda ser tratada por varios roles. Por ejemplo, que la tarea “Corregir error” pueda ser tomada por cualquier usuario que pertenezca tanto al “Rol1″ como al “Rol2″. Serviría la opción: swimlane=”Rol1,Rol2″ ??

    Gracias.

  34. Nebo escribió

    Por favor me podrias ayudar con el codigo jboss jbpm 3.2.3… o alguna version.. gracias.

Escribe un comentario