Dias atrás publiquei no meu blog do java.net um post que tenta ensinar jBPM para as pessoas baseado/comparando ao Struts Framework. Uma das melhores formas de aprendizado ainda é com base na comparação, esse é um dos exemplos que tenho mostrado no Brasil, e até essa semana em Londres, para mostrar o quao simples pode ser uma máquina de processos.
Linguagens de Processos
O JBoss jBPM é mais que um framework de BPM, de fato vamos além disto, onde temos uma máquina de execução de processo agnóstica do ponto de vista de que linguagens, hoje suportamos JPDL, BPEL e Seam Flow, com a ajuda do JBoss ESB também podemos até suportar algo baseado no Rules Flow, ou na sua linguagem desde que você forneça o provider para tal. Ainda que BPEL seja uma linguagem apontada para o “padrão”, na minha ótica é uma linguagem “não elegante”[1] e com vários buracos e necessidades ainda nao supridas, porém se seus processos envolvem apenas WebServices em termos de orquestração, BPEL atende, porém se você precisar de interações com usuários (Swinlanes), BPEL começa a ser problemático [1]. Ao passo que com JPDL, que é a linguagem padrão de representação do processo no jBPM, necessidades como estas relacionadas a tarefas associados a humanos(usuários) é algo extremamente simples.
Básico de um Processo
Longe da pretenção desse post explicar Finite State Machine ou Diagramas de Estado, mas estes conceitos em mente lhe deixam claro a cerca de processos. Basicamente tenha em mente que um fluxo tem um início e fim, e nesse caminho uma série de caminhos normais e fluxos alternativos. Veja o simples exemplo da entrega de um relatório de despesas:

Entre o início e fim, temos uma atividade, que tem o nome “entrega-report”. Esta caixinha por sua vez possui eventos, estados, informações, variáveis que podem ou não estar associados a ela. Por exemplo, para sair dessa caixinha, um bean com as informacoes do relatório deve estar preenchida.
Criando um Servlet para ser o Gerenciador/Controller de execução de Processos
Para explicar a máquina de processos, vamos criar um servlet inspirado no ActionServlet do Struts, que pega o valor da ação com base em um parametro, e entrao chama todo o engine do jBPM e faz a máquina ir para o tarefa do processo apontado através de uma simples URL ou Form Html, veja o exemplo:
[java]
public class ServletBPM extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
ProcessDefinition processDefinition;
static JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();
static JbpmContext bpmContext = jbpmConfiguration.getCurrentJbpmContext();
….
public void init() throws ServletException {
super.init();
processDefinition =
ProcessDefinition.parseXmlInputStream
(getServletContext().getResourceAsStream
(”/WEB-INF/processes/reembolso/processdefinition.xml”));
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ProcessInstance instance =
new ProcessInstance(processDefinition);
instance.getContextInstance().setVariable(”request”, request);
instance.getContextInstance().setVariable(”response”, response);
Token token = instance.getRootToken();
String acao = request.getParameter(”action”);
token.signal(acao);
}[/java]
Como você pode ver, antes de chamar o método signal, que funciona como um “pescoção” ou um “pedala robinho” na tarefa do processo, fazendo com que ela seja executada, nos adicionamos o request e o response do Servlet no contexto da máquina de processo. Isso serve para mostrar a idéia que você pode injetar o que quiser no contexto da execução do processo, assim como você faz no contexto de uma sessão http.
Criando a Action (ActionHandler)
No jBPM o que basicamente você precisa é criar uma ação que no nosso caso vai ser invocada depois que sairmos(node-leave) da tarefa(Caixinha), e veja que do jBPM context podemos dizer até para que página a aplicação deve ir pois temos tudo que precisamos para fazer o jBPM interagir num contexto Http.
[java]
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jbpm.graph.def.ActionHandler;
import org.jbpm.graph.exe.ExecutionContext;
import br.com.redhat.bpm.pojo.Reembolso;
public class EntregaReportAction implements ActionHandler {
HttpServletRequest request;
HttpServletResponse response;
private static final long serialVersionUID = -2649703227240922449L;
public void execute(ExecutionContext ctx) throws Exception {
//getting an HttpResponse from Context
request = (HttpServletRequest) ctx.getVariable(”request”);
response = (HttpServletResponse) ctx.getVariable(”response”);
Reembolso r = new Reembolso();
r.setFuncionario(request.getParameter(”funcionario”));
r.setPeriodo(request.getParameter(”data”));
r.setValor(new Double(request.getParameter(”valor”)));
JPAResolver.getResolver(Reembolso.class).save(r);
RequestDispatcher rd = request.getRequestDispatcher(”aguardeProcessamento.jsp”);
rd.forward(request, response);
}[/java]
Espero que esse exemplo, possa demonstrar a simplicidade de usar máquinas de processos, daqui pra frente estou certo que você poderia usar esta mesma abstração para Actions do Swing, ou usar isso com qualquer outra tecnologia cliente.
[1] - Porco, bem porco!
[]s


Entries (RSS)