Jugando con jBPM #11 – Crear Task Dinámicas!

La idea de este post es mostrar que detalles hay que tener en cuenta a la hora de crear tareas dinámicas, algo muy útil cuando se presenta un caso donde no podemos saber de antemano cuantas tareas se deberán instanciar, o cuando esta cantidad de tareas nos la dicta algún variable del proceso. (También tenemos que optar por esta opción cuando necesitamos tener mas de una tarea de la cual tenemos una sola definición)

Task Process Example
Task Process Example

En este simple proceso, que carece de significado real (debido a que el modelado, raramente debería ser de la manera planteada), pero útil para demostrar la practica, vamos a ver como podemos crear en el nodo Tomar Curso una cantidad X de tareas “Tomar Curso” dependiendo de cuantos alumnos atiendan al dictado.

Para realizar esto tendríamos que a la hora de iniciar el proceso, en cualquier paso antes de llegar al nodo Tomar Curso asignar una nueva variable en el contexto que indique la cantidad de alumnos que van a asistir al curso. Esto lo hacemos de la siguiente manera.

executionContext.getContextInstance().setVariable(“cantStudent”, 4);

Donde la cantidad 4, podría ser calculada mediante la llamada a un servicio de reservas, o algo similar.

Luego a nivel jPDL vemos como seria la definición del Task-Node para que no nos cree la tarea definida dentro de el automáticamente cuando la ejecución del proceso llegue a este nodo:

<task-node name="Tomar Curso" create-tasks="false">
  <task name="Tomar Curso" swimlane="student"></task>
  <event type="node-enter">
    <action name="Create Dinamic Tasks" class="com.sample.action.CreateDinamicTasksActionHandler"></action>
  </event>
  <transition to="end"></transition>
</task-node>

Dos cosas importantes tenemos que notar en jPDL:

  • create-tasks=”false”: se encarga de que la tarea (task name=”Tomar Curso”) no sea instanciada cuando el flujo de ejecución llegue al task-node
  • La acción en el evento node-enter: esta acción sera la encargada de crear automáticamente las tareas especificadas dentro del nodo task-node.

Sin duda  el comportamiento  del proceso que definimos sera el siguiente:

  • El proceso comienza su ejecución mediante un signal sobre el nodo de arranque
  • La ejecución continua hasta el nodo Tomar Curso. Ya que la ejecución no se detiene en el nodo Dictar Curso, porque he decidido que el nodo Dictar Curso solo debe crear la tarea para el instructor y debe dar la posibilidad de que los alumnos puedan ver sus tareas creadas antes de que se termine de dictar el curso. Para esto utilice la siguiente propiedad del nodo task-node:
    <task-node name="Dictar Curso" signal="unsynchronized">
            <task name="Dictar Curso" swimlane="instructor"></task>
            <transition to="Tomar Curso"></transition>
     </task-node>
  • Cuando la ejecución llega al nodo Tomar Curso, este por definición no crea las tareas (TaskInstances) que tiene definidas dentro, sino que delega esta acción al evento que especifico en el evento node-enter. Esta clase delegada contiene lo siguiente:
    public void execute(ExecutionContext context) throws Exception {
            TaskMgmtInstance tmi=context.getTaskMgmtInstance();
            TaskNode tomarCurso=(TaskNode)context.getNode();
            Task tomarCursoTask=tomarCurso.getTask("Tomar Curso");
            int cantStudent = Integer.parseInt(context.getContextInstance().getVariable("cantStudent").toString());
            for(int i=0; i < cantStudent;i++){
                tmi.createTaskInstance(tomarCursoTask, context.getToken());
            }
        }

    Lo que podemos ver a simple vista es que obtenemos el nodo donde estamos parados, a este le pedimos las tareas (por nombre) que tiene y a esta tareas la instanciamos haciendo uso del método createTaskInstance de la clase TaskMgmtInstance. Como el nodo task-node que contiene a estas tareas no le he cambiado la opción por defecto para hacer signal, va a esperar que se completen las tareas instanciadas dinámicamente (en este caso 4 iguales).

  • Cuando las cuatro tareas se finalizan el proceso llega con su ejecución al nodo end.

Espero que haya servido de ayuda para introducir un poco la API de Task MGMT. Cualquier duda comenten!

Advertisements

53 thoughts on “Jugando con jBPM #11 – Crear Task Dinámicas!”

  1. Hola, al parsear la definicion del workflow

    ProcessDefinition processDefinition = ProcessDefinition.parseXmlResource(“multiple/processdefinition.xml”);

    Me da el siguiente error:
    10:33:40,343 [main] WARN JpdlXmlReader :
    process xml warning: task references unknown swimlane ‘instructor’:

    ¿Hay que crear las swimlanes antes del proceso que las usa o algo parecido?

    Like

  2. Exacto, debes definirlas antes a nivel de , En GPD (Graphic Process Designer / Eclipse) si haces click sobre el fondo (es decir, la parte blanca del dibujo) vas a ver que ahi podes definir las swimlanes.
    Saludos.

    Like

    1. Hola, hace unos meses que inicie un proyecto en BPM y si no llega a ser por tu página creo que ya hubiera tirado la toalla.
      Te escribo además de agradecerte tu aportación para consultar un tema.

      Este proyecto consiste en realizar procesos de contratación y además nos han obligado a crear un web-console identico al que tiene jboss (para morirse).
      Los entornos de desarrollo son los siguientes:

      JDeveloper 10.1.3.4
      Eclipse Ganimede
      jdk1.5.0_16
      jbpm-jpdl-3.2.3
      OC4J
      JSF

      ¿Podrías indicarme como crear y trabajador con temporizadores ? Te agradezco de antemano tu ayuda.

      Gracias.
      Mamen

      Like

      1. Gracias por tu comentario.
        El tema de los timers y los reminders es bastante sencillo. Son ambos tratados como tareas asincronicas con tiempo de vencimiento.
        Esto significa que tienes que tener tu Job Executor corriendo, para que los mismos se comprueben y corran.
        Puedes aclarar para que quieres usarlo exactamente?
        Saludos

        Like

      2. Hola salaboy, pues exactamente lo necesito para controlar lo siguiente , te lo expongo:
        – Una tarea realiza por un departamento de contratación envía a un adjudicatario una solicitud de requerimiento de información, pasado 5 días de dicho requerimiento nuestro sistema debe de enviar un mail al servicio correspondiente un aviso para poder finalizar esta tarea activa y continuar con la siguiente, es decir, controlar la finalización de dicha tarea con los temporizadores.

        Podrías indicarme donde localizar un ejemplo??, he leido documentación que explica la teoría pero no me queda muy claro el tema (tb es por el poco tiempo que llevo con esto del BPM).
        Muchas Gracias, por tu rápida respuesta.

        Like

      3. con respecto a tu pregunta de los timers, no tengo ninguna ejemplo concreto.. Tendria que crear uno para aclararte el panorama.
        Pero como te decía en la respuesta anterior, se manejan muy fácilmente.
        Tendrias que crear un timer que tenga fecha de vencimiento 5 dias a futuro de tu actividad. jBPM automaticamente se encargara de ejecutar la accion que tenga configurada en el timer (por ejemplo mandar un mail), siempre y cuando tengas corriendo el Job Executor service. Tienes que investigar sobre eso.
        Tambien depende de que tipo de aplicacion estes creando, si es Java SE tendras que usar el mecanismo que viene built-in y sino configurar el servicio para entornos Java EE.
        Saludos

        Like

  3. Excelente articulo!!!

    Si en vez de 4 “tomar cursos” fueran 4 “aprobar curso” donde la idea es que tengo 4 alumnos inscriptos y un rol APROBADOR que analiza si acepta a ese alumno o no, y si NO lo aprueba se cancela el curso.
    Como sería la instanciacion de esa tarea? ya que tendria que tener una decision en el medio (si la respuesta es Aprobar OK, pasa a la proxima tarea, y si la respuesta es Aprobar NO, termina el task node)

    Like

  4. En realidad deberíamos modelarlo de la siguiente manera:

    Primero una tarea o un nodo que tome un parametro que indique cuantas inscripciones a un curso se abren.
    Luego basándonos en esta cantidad de inscripciones disponibles deberías tener un task-node que cree dinámicamente las tareas de inscripciones para que cada alumno se inscriba. Aca podrías utilizar alguna política para que si algún alumno no se inscribe y el curso tiene que empezar no se espere a que todos los alumnos se inscriban.
    Una vez que los alumnos se inscriben, por cada alumno inscripto deberías crear una tarea de aprobación asignada al aprobado, que va revisando el perfil de cada alumno y le da el ok o no a cada uno para realizar el curso.

    Luego con la cantidad de alumnos ok, yo crearía una tarea que represente al curso, esta quizas no la necesitas.

    Espero haber sido claro con mi comentario, sino espero tu nuevo comentario y podemos ampliar el ejemplo propuesto arriba.
    Saludos!

    Like

  5. Hola, Muchas gracias por la rápida respuesta!.
    Me surgieron nuevas dudas!!.
    1) Es posible definir Procesos (workflows), tareas, etc, DINAMICAMENTE, sin usar los XML? (por ejemplo escribiendo en la base)
    Como se haría esto en el caso de que se pueda? (una idea)

    2)respecto del ejemplo anterior. Lo que necesitaba hacer es un proceso donde se crean dinamicamente 4 task “Aprobar Alumno”, pero en caso de que el usuario NO aprueba a un alumno, Se termina el proceso. Si se aprueba, se pasa a la siguiente task “Aprobar alumno”. O sea que no solo deberia crear dinamicamente los 4 task “Aprobar Alumno” sino que despues de crear cada uno, deberia engancharle una “Decision”. Eso es lo que me esta mareando un poco, y nose bien como hacerlo.

    Muchas gracias de nuevo por tu ayuda!!!!!

    Like

  6. con respecto a tu pregunta 2) lo que realmente necesitarías es un nodo Fork dinámico, donde se definen ramas enteras de ejecución. en estas ramas vas a poder definir varios nodos, que pueden ser distintos en cada rama o iguales en tu caso. Veo que en tu caso cuando dices terminar el proceso, es que se termina solamente para el alumno y no para el proceso. Con este enfoque podrías modelarlo bien. Revisa un poco el nodo Fork para ver como se comporta.
    Con respecto a tu pregunta 1) no deberías estar queriendo hacer esto.. si es tan dinámico no tiene sentido que modeles un proceso. Tienes que pensarlo por ese lado.

    Saludos!

    Like

  7. Muchas gracias de Nuevo!!!
    Respecto a 1), leí en un foro que se puede de deployar un XML programaticamente (en runtime), con ProcessArchiveDeployer, pero no encontre NADA al respecto en la documentacion.
    Hay algo de cierto en eso? Se puede?
    Muchas gracias de nuevo!, y mil disculpas por tantas preguntas. Es que estoy evaluando si usamos JBPM o no.

    Like

  8. Si totalmente puedes hacer deploy de xml en runtime cuando quieras, y si lo vas a hacer programaticamente seguramente te convenga usar JbpmContext.deployProcessDefinition(String), eso siempre lo puedes hacer.
    Cualquier pregunta que tengas no dudes en postearla. COmo te decía antes por ahí tienes que aprender un poco sobre modelado antes de decidir como vas a modelar tus procesos y si tienen carácter dinámico o no.

    Saludos!

    Like

  9. Tenes toda la razon!!
    Excelente!,es lo que estaba buscando. Lo bueno es que estas dudas, tambien le van a servir a otro.

    Mi duda ahora es, si deployo en runtime un proceso que tiene un Node. Como hago en runtime para definir el metodo execute de dicho nodo? (veo dificil que se pueda hacer)

    Like

  10. No no es difícil, lo que puedes hacer es ya tener deployado las clases que van a tener las acciones delegadas.. es decir, pones en el classloader de tu jboss un jar que tenga muchos action handlers implementados y luego en el node solo aclaras la clase que ya esta deployada. Si en realidad necesitas hacer esto dinámicamente tienes dos opciones mas:
    1) recurrir al PAR deployer, a mi gusto no es la mas linda
    2) leer un poco sobre runtime actions

    Saludos!

    Like

  11. Hola!, quería saber si conoces, donde puedo encontrar un ejemplo de uso de Forms con tasks, o explicar un poco para que sirve. No encontre nada en la web.
    Si vi que existe un libro sobre JBPM, si algun bondadoso estaría dispuesto a compartirlo, mi email es tangomannn@yahoo.com.ar
    Es una lastima que algo tan poderoso como JBPM tenga una documentacion tan pobre.
    Muchas gracias!!
    Saludos, desde Buenos Aires

    Like

  12. Gracias por tu comentario. Te comento que a lo largo de mis experiencias con jBPM encontré que la mejor documentación del framework es el código. Y muchos en el comunidad no estan acostumbrados o no tienen el tiempo necesario como para interiorisarse con el mismo. Actualmente hay un solo libro publicado sobre jBPM pero esta muy orientado a analistas de negocios, por lo tanto solo comenta temas básicos de desarrollo.
    Con respecto a tu problemática sobre los task y forms, creo que el tema en si merece un post. Por lo tanto voy a tratar de escribir uno en la brevedad.
    Por el momento puedo decirte que deberías buscar y leer en la documentación oficial cuando habla sobre task controllers y algunos ejemplos sobre esto.
    Saludos, yo también me encuentro en capital federal – Buenos Aires!

    Like

  13. Hola Sala, te queria hacer una consulta.
    Al querer arrancar una instancia de una tarea(TaskInstance.start()) estoy recibiendo una exception. La verdad me tiene trabadisimo hace dos dias. Te pego el codigo, por si se te ocurre algo.
    Muchisimas gracias

    Exception: org.hibernate.HibernateException: null index column for collection: org.jbpm.graph.exe.ProcessInstance.instances
    La Taskinstance esta ya asignada al usuario

    Codigo:
    protected void executeFirsTask(){
    JbpmContext ctx = JbpmConfiguration.getInstance().createJbpmContext();
    try{
    List tasks = ctx.getTaskMgmtSession().findTaskInstances(getUsername());

    if (tasks!=null && tasks.size() >0){
    TaskInstance ti =tasks.remove(0);
    ti.start(); //HERE Throws the ExceptioN!
    ti.end();
    ctx.save(ti);
    }
    }finally{
    ctx.close();
    }
    }

    Like

  14. Puedes debuggear y decirme si la TaskInstance tiene date de start?
    Tambien serviría un poco mas de la exception.
    Fijate que solamente estas tratando de comenzar la primer tarea de la lista… estas seguro que es la que quieres empezar?

    Like

  15. Hola
    Hasta recien el date de start estaba en null. Ahora actualice el JAR a 3.3.0 y arranca la task, y le pone fecha a start, PERO ahora la exception salta en ti.end() (La misma exception: org.hibernate.HibernateException: null index column for collection: org.jbpm.graph.exe.ProcessInstance.instances
    )

    Si es la primera tarea la que quiero empezar (la debuguie para chequear que sea).

    Me parece que lo que indica la exception es que:
    TaskInstance.ProcessInstance.instances esta en null. Pero por lo que vi, siempre esta en null.

    Te juro que hace 2 dias que estoy trabado con esto…
    Cualquier ayuda es bienvenida
    muchas gracias

    Like

  16. Me llama la atención. Vos estabas generando tareas dinámicamente no?
    Yo conociendo tan poco de como estas manejando las cosas en tu aplicación, se me complica para aconsejarte.
    Pero una pregunta que se me ocurre es:
    como se creo esa taskInstance que estas tratando de arrancar y terminar?
    Eso me puede dar una pista sobre tu problema.
    Saludos

    Like

  17. Aparentemente las crea y las persiste bien a las tareas.

    Pongo el breve codigo.

    public class TaskCreation implements ActionHandler {
    public static String AUTH_NUMBER = “AUTH_NUMBER”;
    public static String USERS = “USERS”;

    public void execute(ExecutionContext executionContext) throws Exception {

    JbpmContext jbpmContext = JbpmConfiguration.getInstance().createJbpmContext();
    try{
    TaskMgmtInstance tmi = executionContext.getTaskMgmtInstance();
    TaskNode nodeApproval = (TaskNode)executionContext.getNode();
    Task task = (Task)((nodeApproval.getTasks().iterator().hasNext())?nodeApproval.getTasks().iterator().next():null);

    Integer tasksNumber = (Integer)executionContext.getVariable(nodeApproval.getName()+AUTH_NUMBER);
    String user = (String)executionContext.getVariable(nodeApproval.getName()+USERS);
    for (int i=0; i<tasksNumber; i++){
    TaskInstance newTaskInstance= tmi.createTaskInstance(task, executionContext.getToken());
    newTaskInstance.setActorId(user);

    jbpmContext.save(newTaskInstance);
    }

    jbpmContext.getSession().save(executionContext.getTaskMgmtInstance());
    }finally{
    jbpmContext.close();
    }

    }
    }

    Aclaracion:
    La linea:
    jbpmContext.getSession().save(executionContext.getTaskMgmtInstance());
    la tuve que poner para que NO me salte la siguiente exception.

    ERROR DbPersistenceService : hibernate flush failed
    org.hibernate.TransientObjectException: object references an unsaved transient instance – save the transient instance before flushing: org.jbpm.taskmgmt.exe.TaskInstance

    Estara por aca el problema?

    Like

  18. Si debe ser por eso el problema..
    Si estas en un actionHandler se supone que el proceso ya conoce el contexto.
    Por lo tanto si vos especificas el contexto con las lineas:
    JbpmContext jbpmContext = JbpmConfiguration.getInstance().createJbpmContext();

    estas mezclando los conceptos.
    Tenes que sacar todo lo que tenga que ver con el contexto y dejarlo como lo puse yo en el ejemplo..
    Proba asi…
    Saludos

    Like

  19. Sala!, muchisimasss graciasss por orientarme!!!
    Lo que hice ahora y anda, es crear UNA SOLA VEZ el contexto, y despues reutilizarlo con
    JbpmContext jbpmContext = JbpmConfiguration.getInstance().getCurrentJbpmContext();
    Ahora esto trae un problema!!,y es que JBPM No persiste hasta que haces context.close(). Pero se soluciona haciendo explicitamente:
    jbpmContext.getSession().flush();

    Muchas Gracias !! en serio!!
    Saludos, Fer

    Like

  20. para que quede claro, al contexto solo lo tenes que crear desde donde estas ejecutando el proceso (cliente) y no dentro de los action handlers.
    Si todavía estas haciendo eso dentro del action handler debes sacarlo, sino te vas a encontrar con problemas cuando no deberías.

    Saludos

    Like

  21. Si, es medio peligroso. Habria que encapsularlo en un Singleton donde si ya esta creado te de la instancia actual.

    Muchas gracias!!, ya de a poco despues de debuguear tanto el framework le voy agarrando la mano.
    Pero eso de tener que hacer jbpmContext.getSession().flush(); o persistir a mano algunos objetos, me parece que son algunos bugcitos que se les pasaron.

    Like

  22. No no, no deberia estar encapsulado, debido a que ya lo tiene. Debes sacar eso. Si estas usando el método flush de la session de hibernate ya es porque estas haciendo algo mal.
    Prueba sacando todo rastro del contexto en ese ActionHandler y vas a ver que todo va a funcionar correctamente y te va a quedar el codigo mucho mas limpio y como debe ser.
    Saludos

    Like

  23. Juro que probe todas las combinaciones que se te pueden ocurrir y si no hago un save, y luego un flush() desde la session de hibernate, no me me persiste las TaskInstances que creo dinamicamente.
    Segun la documentación:
    Uno tiene que encargarse de hacer los save() de los process instances, y el flush se hace en el close() del JbpmCOntext, y para hacer un save() necesitas si o si utilizar el context, porque es un metodo del JbpmContext.
    A menos que hagas jbpmContext.loadProcessInstanceForUpdate() y ahi en el close se hace automaticamente el save().

    Abrazo!

    Like

  24. En la documentacion hace referencia a los clientes que estan utilizando a jBPM y no a los action handlers que ya por defecto tiene el contexto y saben como deben persistirse..
    Tiene que dejar el codigo limpio como esta en el ejemplo:
    public void execute(ExecutionContext context) throws Exception {
    TaskMgmtInstance tmi=context.getTaskMgmtInstance();
    TaskNode tomarCurso=(TaskNode)context.getNode();
    Task tomarCursoTask=tomarCurso.getTask(“Tomar Curso”);
    int cantStudent = Integer.parseInt(context.getContextInstance().getVariable(“cantStudent”).toString());
    for(int i=0; i < cantStudent;i++){
    tmi.createTaskInstance(tomarCursoTask, context.getToken());
    }
    }

    En este código en ningún lugar se hace referencia al contexto ya que eso lo define el cliente y el proceso lo único que hace es ejecutarse y utilizar los servicios que el contexto le provee.
    Esta suele ser una de las grandes fallas conceptuales a la hora de usar jBPM.
    Entiendes mi punto de vista?
    Mas alla de que lo hayas hecho funcionar no es la manera correcta de usarlo, entiendes porque?
    Saludos.
    PD: esta bueno que tengamos estas discusiones un poco mas teóricas.

    Like

  25. Me gusto esta última aclaración. Me aclaró mucho mas el panorama.
    Voy a tratar hacerlo funcionar como decis, dejando las persistencias del lado del cliente.
    Te cuento en breve.
    Muchas gracias por el tiempo Sala!

    Like

  26. Bueno, encontre el “error”.
    Era que estaba haciendo
    new ProcessDefinition() en vez de ProcessDefinition pd = ProcessDefinition.createNewProcessDefinition();

    Aparentemente al crear un process definition programaticamente si no usas esa linea, la persistencia funciona MUYYY MALLL. Tenia que hacer chanchadas por todos lados.
    La verdad que muy mal que no expliquen eso en la documentacion. Ya deje un post en el foro de jboss.
    Un abrazo y MUCHISIMAS GRACIAS Sala.

    Like

  27. Si vi tu post en el foro.
    En realidad la mejor documentación esta en el mismo código de jBPM.
    Tienes que aprender a buscar en el código ya que es una de las ventajas de que el proyecto sea open source.
    Si revisas la implementación de la clase ProcessDefinition vas a encontrar que no hay ningun problema con hacer
    ProcessDefinition processDefinition = new ProcessDefinition();
    Salvo que después tenes que agregarle información a mano como hace el método createNewProcessDefinition().
    Te dejo como consejo entonces que te amigues con el código y con el debug de tu IDE.
    Cualquier consulta, no dudes en dejar tu comentario.
    Saludos

    Like

  28. je, no es que le tenga miedo a debuguear codigo ajeno y que no lo haya hecho, es que la ventaja de usar un framework ajeno es esa, la de leer la interfaz, saber lo que hace la clase y olvidarte de la implementación. Si tuviera que ponerme a debuguear, hibernate, spring, struts y las decenas de frameworks y herramientas que se utilizan en un proyecto, se hace un poco larga la cosa. No pido mucho!! un Javadoc nada mas!
    saludos.

    Like

  29. Tienes razón en que no hay mucha documentación y la documentación que hay no es muy completa.
    Por eso mi recomendación para este framework en particular, es programar con los fuentes al lado, al menos para empezar a comprender el funcionamiento interno de la herramienta. Una vez que encuentres los comportamientos básicos ya no te harían falta, es como parte del aprendizaje.
    Tienes que tener en cuenta también la madurez del framework para compararlo con otros como hibernate y struts que probablemente tienen mas de 20 libros escritos sobre ellos y muchas implementaciones que han ayudado a que esas herramientas se mejoren con el tiempo, asi como la documentación sobre ellos.

    Si tienes algún problema preguntame, yo no tengo problema en tratar de buscar la solución, asi no te pasas una semana luchando con un tema en particular.

    Saludos

    Like

  30. Salaboy! Me surgio otra pregunta con respecto a las tareas.

    ¿Yo puedo definir formularios de tarea que funcionen en otro contexto diferente al de la web-console de jBPM? (por ejemplo, en un contexto de una aplicacion nuestra) o es mejor cambiar el codigo de la web-console para adaptarlo a nuestras necesidades?

    Disculpa que pregunte tanto, pero no encuentro mas informacion al respecto, anduve revisando el codigo fuente, pero no encontré muchas cosas.

    Like

  31. No hay problemas con tus preguntas, gracias por tus comentarios.
    Con respecto a definir formularios que funcionen en otro contexto, por supuesto que puedes. La web-console es solo una aplicacion para ver como funciona jBPM de una manera rapida.
    Por eso mismo te recomiendo que no trates de adaptarla a tus necesidades. Creando aplicaciones con JBoss Seam o cualquier otro framework web seria lo recomendable, asi tenes todo el control del desarrollo. Si revisas un poco los foros de jBPM mucha gente se queja de esto y hasta los mismos desarroladores dicen que no todos entienden que mente retorcida ideo esa consola.

    Con respecto a los archivos, es todo un tema, ya que dependiendo de que tipo de archivos y como quieras manejarlos es la solucion que vas a implementar.
    Para dejarte un ejemplo te recomiendo que veas como esta implementado Alfresco, que mas que manejar archivos, maneja documentos en un repositorio de contenidos. Si no quieres algo tan sofisticado, guardando el nombre y la ruta al archivo en una variable del proceso y subir el archivo a un servidor con alguna rutina, podria ser una solucion valida.

    Espero haber sido de ayuda, sino vuelve a preguntar.
    Saludos!

    Like

  32. salboy,
    q tal, primero que nada, buenisimo el blog, la verdad que me ha servido muchisimo de referencia, lujo.
    Tengo una consulta y nose si es aca el lugar indicado para hacerla, pero ahi va.
    En nuestra empresa estamos comenzando con un proyecto en el cual usaremos jbpm, ya q se adecua mucho a nuestras necesidades, pero aún estamos en duda si utilizar la version jbpm 4.0 ya disponible o las versiones 3. anteriores, las cuales utilizas en los diversos ejemplos.
    Por lo que estuve mirando ha cambiado mucho y esta mas orientado a servicios.
    Mientras seguiré investigando, pero me gustaria que me des tu punto de vista si no es molestia.
    muchas gracias por todo.
    Saludos.

    Like

  33. Buenas, gracias por tu comentario.
    Por mi falta de tiempo no he podido publicar un articulo que muestra las diferencias claves entre las versiones de jBPM y Drools Flow.
    Con respecto a este tema, es importante saber y tener en cuenta el tipo de proyecto en el que piensas utilizarlo.
    Los cambios que sufrio jBPM entre estas ultimas versiones (3.2.6.SP1 y 4.0) son bastantes, pero a un nivel interno del framework. Por lo tanto, lo que hay que analizar cuidadosamente es si el framework en el estado actual (version 4.0) sirve para un entorno de producción, debido a que el cambio interno causo que muchas funcionalidades existentes desaparecieran.
    Ahora si tu aplicacion es una prueba, o algo que va a correr en ambientes no criticos, creo que es la opcion acertada, siempre y cuando no quieras saltar a Drools Flow, el cual recomiendo sobre ambas versiones de jBPM.

    Espero haber aclarado tus dudas. Saludos y cualquier cosa espero un nuevo comentario tuyo

    Like

  34. Hola,
    Gracias por responder tan rapido.
    La idea que tenemos es usar jbpm 4.0 sobre tomcat, ya que tenemos una arquitectura estable funcionando en tomcat y la idea es continuar con ella y otros framworks ya embebidos, como struts 2 y spring.
    Pero viendo ejemplos y analizando nuestra problematica, creo que la version 3.2.6 SP1 no es mala opcion ya que se trata de un proyecto donde tenemos los procesos definidos por el cliente (a nivel de diagrama de actividades), y la mayoria de los procesos estan basados en tareas simples,y algunos nodos de decicion, pero tambien sencillos, Creo que la version 3. cubre hasta el momento nuestras necesidades, aún asi , tendremos proyectos mas complejos en los cuales quiza necesitemos actualizar a la 4.0, por el momento veo que hay mucho mas documentacion sobre la 3, lo cual es favorable al momento de arrancar en este mundo de jbpm.
    De todos modos es probar un poco de cada una.
    Veo que en la vesion 4 cambia bastante tambien el modo de configurar las tareas, los action, los actores, etc, no hay tanta trazabilidad como esperaba.
    Bueno, muchas gracias por todo.
    saludos.

    Like

    1. Gracias a vos por tu comentario, la idea de esto es que las personas que se encuentren en la misma situacion que vos puedan tomar decisiones basadas en estas discusiones. Si te surgen nuevas inquietudes no dudes en preguntarlas, ya que estas contribuyendo a que a otras personas se le respondan antes sus dudas.
      Saludos

      Like

  35. Salboy, q tal
    estoy viendo el tema del historial historyService en jbpm 4.0, queria saber si tenes algun ejemplo del funcionamiento de registros en jbpm 3, ya aun no logro decidirme.
    gracias.

    saludos.

    Like

    1. Como estas Sebastian, veo que estas investigando a fondo toda la herramienta.
      Actualmente no tengo ningun ejemplo que pueda publicar al respecto. Ni bien tenga tiempo me gustaria publicar algo al respecto ya que es un feature muy utilizando en los proyectos que he trabajado.
      No esta dentro de mis prioridades actuales, pero ni bien tenga algo de tiempo prometo ponerme con eso.
      Si tu puedes publicar un articulo de como funciona el historyService de jBPM 4.0 seria de gran ayuda para la comunidad.
      Saludos

      Like

  36. Bueno, finalmente decidimos lanzarnos por el jbpm 4 ya que nos permitia una mejor integracion con spring entre otras cosas.
    Ni bien tenga solidos los conocimientos si duda que posteare algo sobre historyServices y algun otro servicio interesante.

    Saludos,

    muchas gracias por todo.

    Like

  37. Buenas Salaboy, tengo una pregunta para tí. Estoy siguiendo tu libro (por cierto bastante interesante y muy útil) y tengo un problema en un apartado.

    Comentas que a una “human task” se le puede asignar un nombre dinámicamente de la siguiente forma:

    task name=”Review #{client.lastName,client.name} Bill”

    La cosa es que, yo he realizado una prueba y no me interpreta la expresión, sino que me pinta como nombre de la tarea: Review #{client.lastName,client.name} Bill

    Realmente mi prueba es la siguiente:
    task name=”Evaluacion #{contenido.titulo}”

    Luego probe con:
    task name=”Evaluacion #{2>1}”

    Para ver si era un problema de que no estaba capturando la variable, pero igualmente tampoco me interpretaba la expresion.

    Sabes de que puede ser?

    Muchas gracias por todo.

    Like

  38. Hola salaboy muy buenos post, siguiendo la idea de crear tareas dinámicas en node-task tengo problema que seria los siguiente.
    cuando se creó las N tareas de forma dinámica en un nodo todo va bien el problema es que cada una de esas tareas creadas de forma dinámica también cree otra tarea individualmente cada vez que una de ellas se termine en el siguiente node-task, el escenario seria lo siguiente: creo N tareas de registrar sustento técnico y cada tarea cuando esté terminada debe crear su tarea que sería revisar sustentos técnico y decida , y no esperar que todas las tareas de registrar sustento técnico se terminen para crear solo una tarea de revisar sustento . A ver si me echas una manito con esto

    Gracias de antemano.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s