Jugando con jBPM #4 – start-state Node

La idea de este post y los siguientes a ser repasar brevemente la funcionalidad de los distintos tipos de nodos, tanto en su funcionalidad como en su sintaxis XML, con la idea de poseer una fuente de conocimiento sobre cada tipo de nodo. Este post especialmente esta dedicado al nodo de tipo <start-state> como indica el titulo.

<start-state>

Este nodo se caracteriza por ser el nodo inicial de nuestros procesos. Al ser el primer nodo tiene algunas características especiales para cumplir cumplir con su funcionalidad.

Las características mas obvias, pero que no hay que dejar de lado y siempre tener en cuenta son:

  • No posee transiciones que llegan a el
  • Solo puede haber un solo <start-state> por proceso

Con respecto a la primer característica podemos ver la implementación exacta de la clase StartState.java que extiende su funcionalidad de la clase Node (como absolutamente todos los nodos) y sobre escribe los siguientes dos métodos para cumplir esta funcionalidad:

public Transition addArrivingTransition(Transition t) {
    throw new UnsupportedOperationException( "illegal operation : its not possible to add a transition that is arriving in a start state" );
  }

  public void setArrivingTransitions(Map arrivingTransitions) {
    if ( (arrivingTransitions!=null)
         && (arrivingTransitions.size()>0)) {
      throw new UnsupportedOperationException( "illegal operation : its not possible to set a non-empty map in the arriving transitions of a start state" );
    }
  }

Otra característica que sale a la luz cuando vemos la implementación de la clase StartState, es que esta clase sobre escribe el método execute que contiene la logica a realizar por el nodo de la siguiente manera:

public void execute(ExecutionContext executionContext) {}

En otras palabras el nodo start-state no se ejecuta. Solo sirve para indicar que el proceso acaba de ser creado y todavía no comienza su ejecución. Esto quiere decir que cuando con la API nosotros creamos un nuevo Objeto ProcessInstance, se crea un RootToken que apunta al start-state del proceso.

A nivel jPDL podemos ver una definición simple de un nodo <start-state>

<start-state name="start">
  <transition to="next node"></transition>
</start-state>

o también una mas compleja que incluye la definición de una tarea dentro del nodo <start-state>

<start-state name="start">
        <task name="Start Task" priority="high">
            <assignment actor-id="salaboy"></assignment>
            <controller>
                <variable access="read,write" name="variable1" mapped-name="variable1"></variable>
            </controller>
        </task>
        <transition to="next node"></transition>
</start-state>

Con respecto a la tarea, ya voy a describir un poco mas en un post dedicado solo a eso. Pero lo importante aca, es el significado que puede tener esta tarea dentro del proceso. Por lo general se suele poner una tarea en el <start-state> con el fin de poder capturar quien fue el actor que inicio el proceso. Tambien probablemente lo mejor seria que posteara un ejemplo de implementacion de esto mas adelante.

Como ultimo detalle y no menor, esta bueno tener bien en claro que eventos soporta este nodo tan particular. Ya que el nodo <start-state> no tiene transiciones que llegan a el, los eventos como por ejemplo, node-enter en este caso no estan soportados. Por esto viendo en la implementacion, vemos que los unicos soportados son los siguientes:

public static final String[] supportedEventTypes = new String[]{
    Event.EVENTTYPE_NODE_LEAVE,
    Event.EVENTTYPE_AFTER_SIGNAL
};

Espero que se entienda y si alguien tiene algun comentario para agregar, bienvenido sea.

Advertisements

13 thoughts on “Jugando con jBPM #4 – start-state Node”

  1. Hola, creo que esta pregunta no se corresponde mucho con este post, pero bueno, ahi va:

    Quería saber si existe alguna forma de parar la ejecución, y desde otro punto poder rearrancarla y continuar en el punto donde se suspendió. He intentado suspender el token, la instancia de tarea, jugar con nodos y transiciones…pero no he sido capaz.

    La única forma que ha funcionado es definiendo un elemento “state” previamente, pero no quería modificar la definición de tareas añadiendole ese elemento. Tampoco he podido crear un nodo “state” en ejecución.

    Muchisimas gracias, y gracias por el blog, que nos está siendo de mucha utilidad a los que empezamos con estas tecnologías.

    Saludos.

    Like

  2. Primero que nada, gracias por tu comentario.
    Respondiendo a tu pregunta, creo que has llegado a las conclusiones correctas, es decir, si tu proceso necesita ser suspendido a la espera de alguna senial externa, debes modelar un nodo state, o cualquier nodo que se comporte como Wait State.
    Por definición cada tipo de nodo decide si propagar la ejecución o comportarse como wait state. Por esto, a menos que tengas un caso realmente particular, no deberías necesitar para la ejecución si tu definición de proceso no lo dice así.
    Comentame tu caso particular, y vemos que solución podemos encontrar.
    Saludos!

    Like

  3. Hola! Muchas gracias por contestar tan rápido 🙂

    Un ejemplo de lo que tengo que hacer vendría definido por esta definición de proceso:

    Ahora imaginemos que el node “n2” es un nodo de cancelación, o de suspensión de la ejecución, y que en ese mismo nodo, o justo después, queremos que la ejecución se pare. Una vez que la ejecución esté parada se pretende que desde otro punto de la aplicación se arranque de nuevo el proceso, y continue la ejecución en el nodo “n3”, y que todo siga como estaba previsto.

    Lo que decía del elemento “state” es que probé haciendo un ejemplo de esta manera:

    Lo malo es que no quiero definir ese elemento “state” en la definición de proceso. Quería que ese elemento se pudiera definir en ejecución, o que se pudiera parar la ejecución de alguna otra manera pero sin tener que cambiar la definición de proceso.

    Muchas gracias otra vez.

    Saludos!

    Like

  4. Uy, no sé que ha pasado, la primera definición de proceso es:

    super-state name=”tarea1″
    node name=”n1″

    transition to=”n2″ name=”n2″
    /node

    node name=”n2″

    transition to=”n3″ name=”n3″
    /node

    node name=”n3″

    transition to=”n3″ name=”n3″
    /node

    transition to=”end” name=”end”

    /super-state
    end-state name=”end”

    Y la segunda definición es:

    super-state name=”tarea1″
    node name=”n1″

    transition to=”n2″ name=”n2″
    /node

    node name=”n2″

    transition to=”nState” name=”nState”
    /node

    state name=”nState”
    transition name=”n3″ to=”n3″
    /state

    node name=”n3″

    transition to=”n3″ name=”n3″
    /node

    transition to=”end” name=”end”

    /super-state

    end-state name=”end”

    Like

  5. Bien, sigo sin comprender cual es el motivo por el cual no quieres cambiar la definición del proceso para mostrar el comportamiento que quieres lograr. Con el nodo state, estas logrando exactamente eso que quieres hacer.
    Dejando de lado eso, el nodo de tipo Node, esta pensado para que si le defines un ActionHandler, este ActionHandler tome la decisión de si continua (es decir, propaga) la ejecución, o si debe comportarse como un Wait State.
    Por lo tanto, te recomendaría que revisaras las acciones, o la lógica de tus nodos tipo Node, ya que en ellos puedes especificar que hay que hacer con el flujo de ejecución luego de realizar la acción especificada dentro del ActionHandler.
    Te comento, que si tienes ya definida lógica dentro de ActionHandlers, lo único que tendrás que ver es si la ultima linea de esa lógica es algo similar a lo siguiente:

    context.leaveNode();

    Comentando esta linea tus nodos de tipo Node, ejecutaran su lógica pero se comportaran como un wait state y no continuaran la ejecución del proceso a menos que alguien externamente les de un signal.

    Espero haber sido claro, tus comentarios son bienvenidos.
    Saludos

    Like

  6. Hola salaboy!

    Gracias por tu ayuda. Al final, despúes de muchas pruebas, hemos decidido seguir tu consejo de utilizar el state porque nos estabamos complicando mucho, pero no añadimos un nuevo nodo state (como pensabamos en un principio), si no que el último nodo lo definimos como un state (que es donde queríamos parar).

    Muchas gracias de nuevo.
    Saludos!!

    Like

  7. Hola salaboy, encantado de poder volver a hablar contigo.
    Me preguntaba si en un ejemplo como el que has incluido:

    ¿¿¿seria posible desde un conocer el valor de las variables ya definidas, como en este caso “variable1”???
    Si es posible, de qué forma.
    Gracias

    Like

  8. Perdon por el coment de antes, hay cosillas que no se visualizan.
    Lo correcto en mi respuesta seria lo siguiente:

    Me preguntaba si en un ejemplo como el que has incluido, en el que se define “variable1” en un controller dentro de un task, o un node, o un task-node, si es posible desde otro node, task, … mediante las etiquetas script poder acceder al valor de ésta variable

    Si es posible, de qué forma.
    Gracias

    Like

  9. Hola,
    aunque este post es de hace tiempo tengo una dudilla con respecto al start-state.
    El caso es que lo que quiero conseguir es que pase del start-state sin hacer nada.Mi codigo del start es el siguiente:

    Donde en el execute del StartHandler solo tengo un executionContext.leaveNode().

    Pero el codigo de esta acción no se ejecuta al entrar en el start-state. ¿Sabes de alguna manera de hacer esto?

    Like

  10. No puso el codigo:
    start-state name=”start”>
    action class=”cinfo.wf.modelo.handlers.wf.StartHandler” config-type=”bean”>
    transition to=”fork”>
    /start-state>

    Like

  11. Start State, es un wait state por defecto, no puedes hacerlo que comience automaticamente. Por eso siempre tiene que crear una instancia del proceso y luego llamar al metodo signal.
    Esa accion que has puesto ahi nunca se ejecutara, ya que el metodo execute de la clase Start State nunca busca acciones para ejecutar.
    Saludos

    Like

  12. Hola Salaboy… excelente blog, no se si depronto me puedas ayudar un poco con esto:

    Como podria montar un proceso básico para la seguridad de una aplicación en SEAM, alguna idea de como lo prodra modelar??

    Como podra integrar un basket de tareas dentro de la aplicación??, es decir, que yo al ingresar a la aplicación se muestren las tareas que un determinado usuario tenga pendientes

    Like

    1. Hola santiago, perdona la respuesta tardía. Cuentame con que versión de jBPM estas trabajando. Si quieres integrar la lista de tarea con tu aplicación, es bastante sencillo, solo tienes que usar las APIs para traer las tareas de cada usuario.
      Con respecto a la seguridad y SEAM, no entiendo muy bien que quiere modelar.
      Saludos

      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