this is a question about the JbpmCallback action provided by the jBPM version that is shipped with the JBoss ESB (in these tests I'm using ESB 4.4 and the contained jBPM 3.2.2 in a JBoss AS 4.2.3). I'm applying this action in order to get back from the ESB to a running process instance in jBPM. In ESB 4.4 I could also have applied the BpmProcessor service with the "SignalCommand" property for this purpose, but since this is not supported anymore in ESB 4.5 (and presumably in future version) I was looking for something general that hopefully stays.

To get back and forth between jBPM and ESB via JbpmCallback works fine (after one finds out that the necessary process information is expected in the message at Message.getHeader().getCall().getTo(), instead of getRepyTo() ...), but what did not work for me yet is to bring new data with the message into the process.

Specifically, I start the process (named "AccountingStandardProcess") from within the ESB like that (in the jboss-esb.xml):

So, there are two parts of the message body, messageContent and settingsESB, which are mapped into the jBPM context. This works fine, the bpm-Objects are existing within jBPM, can be modified there and are correctly returned if I call the ESB again via the ESBActionHandler (processdefintion.xml):

As you can see, a part of this is commented. For just getting back to the ESB, the bpmToEsbVars mapping is enough. When I leave jBPM, the token stays at this node shown here, and gets back to it after calling JbpmCallback in jboss-esb.xml:

First, my action PrepareMessageForCallback just copies the "replyTo" object of the header into the "To" object (as described above). Then JbpmCallback jumps back and the process runs to its end without problems. BUT: The data in messageContent has been changed meanwhile (in the ESB) and I need it also in the process. If I do it like that, even if I also have such a mapping in the ESBActionHandler (commented lines above), the new content is not copied into the process.

I tried also to give the jbpm variables new names when calling JbpmCallback, e.g.:

in order to access the changend content at a new name in jBPM, but this resulted in a runtime error which sounded somehow like that he was not able to create these variables at this stage.

So I guess, context variables in jBPM are only created at the start of the process, not when getting back to a running instance. This would make sense, but why can't I transmit changed message data when re-entering? Did I miss something or isn't this possible in principle? If not, this would be a hard restriction for using a combination of jBPM and the ESB.

As I can see in the code, the "esbToBpmVars" property (from the processdefinition.xml) IS used, but I guess you have to copy it fto Message.getHeader().getCall().getTo() as well (like the token id stuff).

Does that help?

Best thing I can encourage is to look at the code how it is implemented. Even is that is a bit wired in the current implementation (will be rewritten in future).

yes, of course, obviously this was still somehow not clear to me. I just tested it and it works as well.

So, you "only" need to set the esbToBpmVars-Mapping in the processdefiniton.xml and afterwards take care about that this mapping is also copied from replyTo() to To() in the Call object of the message header.

Let me first just briefly explain what I'm generally doing: I'm using the JBoss AS, ESB and jBPM. In the AS there are some EJBs sending messages into one central ESB gateway queue and retrieving messages from other JMS queues (not ESB aware). So the process is like that:

a. the ESB retrieves a message that starts the jBPM process with the ESB action/property BpmProcessor/StartProcessInstanceCommand. Also I add here the esbToBpmVars

b. In the jBPM process I jump back to the ESB with the ESBActionHandler. Here I need to specify the esbToBpmVars again as well as the bpmToEsbVars for transporting the changed variables into the ESB.

c. Back in the ESB I'm sending a message to an "outside" ordinary JMS queue (i.e., not ESB aware). This is retrieved by one of the EJBs and at one later point in time (i.e, completely asynchronous) this EJB sends again a message to the ESB gateway, which now does of course not start again the jBPM process, but should be able to jump back to the still running process.

In order to realize espcially c, I had to look for a method to jump back. For now we're still using ESB 4.4, but of course don't want to apply methods that won't be available in future. Since I read in the blog of Bernd that this is the case for the ESB action/command BpmProcessor/SignalCommand, I tried to use BpmCallback.

It is true that the necessary process information to get back via BpmCallback is copied into the message header when leaving jBPM with the EsbActionHandler. But there are two problems with it:

p1. The EsbActionHandler copies the necesary information into the replyTo-EPR of message.header.call, but BpmCallback expects this information at the to-EPR. I found this in the code of BpmCallback:

So, even if you stay inside jBPM/ESB (i.e., if jBPM starts a service that immediately calls the BpmCallback action) you need to copy the replyTo-EPR to the To-EPR.

p2. This is not really a problem, but merely the fact that if you "leave" the ESB as I described in a. to c. above, you need to get the process information from the message leaving the ESB and set it into the new message (at Header.Call.setTo of course) entering again the ESB and attempting to call back the running jBPM problem. That is why I need to create an EPR. But this works without problems.

Also it is no real problem to go around p1 by copying the information to the expected destination, although it is a bit tricky to figure out ...

Regarding the variable mappings it is like that I know now that these are also to be copied with the other process information (like tokenId etc.). But I need also specify it at all the places I described above (a-c). From your post I understand that you think that it is sufficient to define both mappings (esbToBpmVars and bpmToEsbVars) only at the start of the jBPM process, but this is definitely not the case, I just tested it again. Both mappings need to be specified in all jBPM nodes that leave jBPM into the ESB. If I leave out the bpmToEsb mapping, the changes done inside jPBM are not transimitted to the ESB and if I leave out the esbToBpmVars mapping at this place, the changes in the data done in the ESB are not transferred back to jBPM.

But again, also this is not problematic as you know how to do it :-).

So, the only things I would recommend are to document BpmCallback a bit better if this is really the preferred way for combining jBPM and the ESB. And maybe to get the information from replyTo, where it is already copied to. Then BpmCallback would be more intuitive to use.

One additional thing: I figured out that if you immediately call back the jBPM process after leaving it, (or if you start several times the same process) you need to have a short stop time in between (e.g., Thread.sleep(10) is enough) in order to have jBPM up and ready. If the calls are too fast, the token is still locked. Maybe such a small pause could be included into the call back.

Hope, you understand my setting better and these explanations were not too exhaustive ... :-)

"andreskusa" wrote:p1. The EsbActionHandler copies the necesary information into the replyTo-EPR of message.header.call, but BpmCallback expects this information at the to-EPR.

This is correct. The invocations from EsbActionHandler are sending messages to a target service (the To EPR) and also including the necessary information for replying (the ReplyTo EPR).

"andreskusa" wrote:So, even if you stay inside jBPM/ESB (i.e., if jBPM starts a service that immediately calls the BpmCallback action) you need to copy the replyTo-EPR to the To-EPR.

But jBPM should not be invoking the reply service, it should be invoking another service which then sends its reply to the callback service. The processing of a RequestResponse mep in the pipeline will send a response to the ReplyTo EPR and, in this way, we are no different from specs such as WS-Addressing.

"andreskusa" wrote:p2. This is not really a problem, but merely the fact that if you "leave" the ESB as I described in a. to c. above, you need to get the process information from the message leaving the ESB and set it into the new message (at Header.Call.setTo of course) entering again the ESB and attempting to call back the running jBPM problem. That is why I need to create an EPR. But this works without problems.

Okay, that explains things. It is the correlation between the internal EPR and external services that we are currently missing.

"andreskusa" wrote:Regarding the variable mappings it is like that I know now that these are also to be copied with the other process information (like tokenId etc.). But I need also specify it at all the places I described above (a-c). From your post I understand that you think that it is sufficient to define both mappings (esbToBpmVars and bpmToEsbVars) only at the start of the jBPM process, but this is definitely not the case

No, they need to be specified on every node that communicates with the ESB. They define the variables which are specific to that invocation and are not specified globally on the process.

"andreskusa" wrote:I just tested it again. Both mappings need to be specified in all jBPM nodes that leave jBPM into the ESB. If I leave out the bpmToEsb mapping, the changes done inside jPBM are not transimitted to the ESB and if I leave out the esbToBpmVars mapping at this place, the changes in the data done in the ESB are not transferred back to jBPM.

This is correct.

"andreskusa" wrote:So, the only things I would recommend are to document BpmCallback a bit better if this is really the preferred way for combining jBPM and the ESB. And maybe to get the information from replyTo, where it is already copied to. Then BpmCallback would be more intuitive to use.

One thing that would also help would be to remove the variable mapping and scope from the EPR as there is no real need for this to be included in the information sent back to the callback service. They can be retrieved automatically from the process definition.

"andreskusa" wrote:One additional thing: I figured out that if you immediately call back the jBPM process after leaving it, (or if you start several times the same process) you need to have a short stop time in between (e.g., Thread.sleep(10) is enough) in order to have jBPM up and ready. If the calls are too fast, the token is still locked. Maybe such a small pause could be included into the call back.

This is strange, the messages should be covered by a transaction and sent on the transaction boundary. Can you send me an example of this?

"andreskusa" wrote:Hope, you understand my setting better and these explanations were not too exhaustive ... :-)

But jBPM should not be invoking the reply service, it should be invoking another service which then sends its reply to the callback service. The processing of a RequestResponse mep in the pipeline will send a response to the ReplyTo EPR and, in this way, we are no different from specs such as WS-Addressing.

No, sorry, the way I meant it was the way you described it: I did not start the bpmCallback-Service from jBPM, but rather started an ESB service (via EsbActionHandler) which directly called the action org.jboss.soa.esb.services.jbpm.actions.JBpmCallback. This is what I mean with "inside" in comparison to what I described by the correlation of internal EPR and external services.

So, since I "leave" the ESB I have to create a new EPR anyway and it doesn't matter for me so much now that I need to call an action which fills my to-Object in the EPR.

I just tried such an "internal" test again and tried to use also the JbpmCallback-Service instead of only the action. But I get in both cases only errors like that:

Which is currently no problem for me, I'm happy now using the bpmCallback action.

I will need a bit more time (hope to have that time the next days) to create again a testing situation where I use direct callbacks and can hopefully also reproduce the time out thing I also described. Then I'll get back to you.

First @Andre: I think what Kevin meant is, that if you use the action mep="RequestResponse" in the service you call from the process the JbpmCallback is triggered outomatically, you don't have to code that yourself.

But this is a different use case. There the Callback works as expected out-of-the-box without problems.

Kevin wrote:

Okay, that explains things. It is the correlation between the internal EPR and external services that we are currently missing.

+1!!! This is what I raised already a couple of times: Removing the SignalCommand befor this problem is solved. I think there we should come up with some working solution shortly and document it properly. What do you think Kevin?

And for integrating jbpm 4 we should find a really decent correlation mechanism :-)

I am facing similar issues on how to callback jbpm from esb, when the bpm process stops at a state. Basically i want to do a state machine. I tried to use the action method to call back jbpm, however i couldn't figure out how to make the EPR as mentioned by you in this post.

You said - "So, there are two parts of the message body, messageContent and settingsESB, which are mapped into the jBPM context. This works fine, the bpm-Objects are existing within jBPM". How do you understood this? I mean how can i get this objects in jBPM process(in ActionHandler for example).