-
1. Re: Async service task questions
swiderski.maciej Oct 3, 2012 8:47 AM (in response to calvinchu101)If you don't have any state kept in the session (facts or timers) you can use any session to complete your process. That means in your MDB instead of loading same session you could create new session and complete your process with it. Please keep in mind that loading same session in two different threads can cause optimitic locking errors when both threads will make changes to it.
HTH
-
2. Re: Async service task questions
calvinchu101 Oct 4, 2012 10:46 AM (in response to calvinchu101)I have finally make it working by putting my MDB in the jbpm-gwt-console-server-5.3.0.Final.war (I am using JBoss AS 7.1.1) and successfully share the StatefulKnowledgeSessionUtil in jbpm-gwt-core.jar to create the session and complete the service task.
-
3. Re: Async service task questions
salaboy21 Oct 4, 2012 10:50 AM (in response to calvinchu101)Cool, can you write a blog post or a wiki page about your changes?
Cheers
-
4. Re: Async service task questions
cyrine Oct 24, 2012 4:48 AM (in response to calvinchu101)Hi Calvin,
Please, can you tell us about your changes and how you did it, on a small tutorial. It will be great and helpfull.
Thanks a lot!
-
5. Re: Async service task questions
calvinchu101 Oct 24, 2012 9:39 AM (in response to calvinchu101)Here's my quick and dirty changes for my demo.
First, I implement a WorkItemHandler to send JMS message to a request queue,
public class JmsRequestWorkItemHandler implements WorkItemHandler { public void executeWorkItem(WorkItem workItem, WorkItemManager workItemMgr) { MessageProducer producer ; //Some initialization of your JMS MessageProducer ... MapMessage mapMsg = session.createMapMessage() ; // Put the task ID in JMS message mapMsg.setString("taskid",String.valueOf(workItem.getId())) ; // Send the JMS message to queue producer.send(mapMsg); //DON'T complete the workitem here //workItemMgr.completeWorkItem(workItem.getId(), map) ; } ... }
Then register the handler in src/main/resources/META-INF/CustomWorkItemHandlers.conf of the jpm-gwt-console-server project,
[ "Log": new org.jbpm.process.instance.impl.demo.SystemOutWorkItemHandler(), "JmsRequest": new my.process.workitem.jms.JmsRequestWorkItemHandler(), ]
And then create a MDB in the jpm-gwt-console-server project,
@MessageDriven(name = "ExternalResponseMDB", activationConfig = { @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/response"), @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge") }) public class ExternalResponseMDB implements MessageListener { private final static Logger log = Logger.getLogger(ExternalResponseMDB.class.getName()); public void onMessage(Message rcvMessage) { MapMessage msg = null; log.info("Message received by ExternalResponseMDB") ; if (rcvMessage instanceof MapMessage) { msg = (MapMessage) rcvMessage; // retrieve sessionId from message String id = msg.getString("taskid") ; if (id != null && id.length()>0) { try { // Get knowledge session by StatefulKnowledgeSessionUtil which provided in jbpm-gwt-core-5.3.0.Final.jar // As your MDB is deployed within the jbpm-gwt-console-server.war, gwt-core jar already in lib StatefulKnowledgeSession session = StatefulKnowledgeSessionUtil.getStatefulKnowledgeSession() ; // With the session, you can complete the work item here session.getWorkItemManager().completeWorkItem(Long.parseLong(id), null) ; } catch (Throwable t) { log.severe("completeWorkItem:"+t.getMessage()) ; } } } else { log.warning("Message of wrong type: " + rcvMessage.getClass().getName()); } } }
Maven clean install your jpm-gwt-console-server project and deploy it. Then you can use the JmsRequest service task in your workflow to send request to external application. The external application should keep the "taskid" and reply back to the response queue such that the MDB can complete the process. Please be noted that the StatefulKnowledgeSessionUtil would try to find and reuse a serialized session ID, not sure if there are any issue if the session created by jbpm-console and MDB shares the same session ID.
As I mention above, it is my quick and dirty approach. I think a more appropiate way to do this is to wait for a signal and let the JmsRequestWorkItemHandler to complete the work item, when response received the MDB then signal the workflow to continue. i.e. calling session.signalEvent(arg0, arg1) in MDB instead of session.getWorkItemManager().completeWorkItem(arg0, arg1)
Like this, unfortunately I don't have any working sample yet.