/ Development  

BPM parent/child learnings (incl. sending messages with data)

Hi there AppWorks fans,

Welcome to a new installment of AppWorks tips.

A new week with a new post…This time something easy (I think!?) as we will explore the parent/child principles between 2 BPM instances. We can easily start a sub-process from a parent BPM process, but it gets more interesting when we start to play with ‘holds’ and ‘delays’ and sending out event signals where parent BPMs can ‘listen’ to. These practices are pretty common in every project where BPMs are involved, and I just want to share all the knowledge I see passing by on my own journey…Let me be honest to say I never implemented a parent/child BPM (yet!) during my projects. So, this is the best time to dive into and explore as we go with the knowledge we already gained…

Let get right into it…

Where to start? Well, I guess with 2 BPMs? 1 parent and 1 child? Nicely saved in the ‘bpms’ folder or our project…Almost forgot!…Don’t forget to spin up your VM, open your workspace…blablabla! 😋

Keep both our BPMs simple and easy with names like ‘bpm_parent’ and ‘bpm_child’:


It won’t get easier than this!…There is even a ‘Save as’ option in the menu of the BPM modeler to make it even more simple!

You feel the first sweat on your forehead? 😅😅 Yes, it’s also warm outside (in the time-frame this post is written).

Ok, next step…on the parent BPM!

Add a second activity called ‘Independent Sub-Process’ and insert a BPM to it (our ‘bpm_child’):


This activity has an interesting “default” setting which tells us to wait till the sub-process is finished:


Let’s try this our…shall we?

Do a publication on both those BPMs and right-click the ‘bpm_parent’ BPM from the project to execute one instance of it…After this we can check the PIM:


In the top left corner (that little arrow down; fourth icon from the left) will let you change to this view!

Ok, that’s not (yet!) any waiting, but that’s because we only used ‘Automatically’ triggered activities. Jump into the ‘bpm_child’ BPM and insert a ‘Human’ intervention:


Just select any of the default layouts available from the platform. It doesn’t matter for now as long as we see that small ‘User’ icon on the activity.

Save, deploy again, and start the parent…Have a check on the PIM:


There we go! The power of “human intervention”

Now (because we can!), open the ‘My Inbox’ artifact…The what? Yes…It’s old stuff, but it still does the trick of completing a task!


For the unbelievers: in the ‘new’ runtime it will look like this:


After completion and a refresh of the PIM we have 2 green lighted instances of our BPMs…GREAT!

Now what?…Or…What else?

Remove the ‘default mark’

The default mark?…Yes, my dear AppWorks explorer! The one in the properties of the activity where we call our ‘bpm_child’…


Hmmm…save, deploy, and execute our ‘bpm_parent’ again…and check the PIM…


Ok…That’s a so-called ‘fire-and-forget’ principle (as the parent is finished already!).

Just finish the task…What else?

Restore our ‘wait’ state with a message construct

As we remove that last mark on the ‘wait’ option, we will try to rebuild this feature with the message construct. Open de ‘bpm_parent’ and add the ‘Receive Message’ construct after the sub-process call.


You see we selected an ‘input Message’ to wait for. This message can be created in the ‘Message Map’ tab of the BPM…


Once created, you can select it in the properties of the message construct.

Ok, now that we’ve created a ‘wait’ in our parent flow it’s time to add a ‘send’ in our child BPM! Open it up and add the ‘Send Message’ construct like this:


The most important part here is that last ‘Message to send’ box. It needs to send to same message value that is listened to from our parent process! That same message can also for this child process created in the ‘Message Map’ of the BPM

I played with a message called bpm:hello_wrong, but this message never triggered my parent BPM to continue…As expected!

After saving both the BPMs and a deployment it’s testing time…You can do it yourself and checking out the instances from the PIM artifact. It should react exactly the same as we tried out before! For me, it is a green checkmark! ✅

Persistent vs. Transient

You saw it already passing by in one of the screenshots where we added our ‘receive message’ construct on the parent BPM. There was an option for a ‘mode’ selection where I could find this information from the “Advanced Developer Guide”:

  • Persistent - Consume message even before Receive Message event is active.

Select this option to ensure that all messages received while the ‘Receive Message’ event is inactive are kept in queue. When the ‘Receive Message’ event becomes active, it consumes the messages in queue and continues to execute the process.

  • Transient - Consume message only when Receive Message event is active.

Select this option to ensure that the ‘Receive Message’ event consumes only the messages received while it is active. Messages received before the ‘Receive Message’ event is active, are ignored.

Hmmm…interesting!? Also, that ‘queue’ is interesting to have a “view” on!

First things first as I understand the theory, but what about the practical part. We already tried out the default ‘persistent’ mode in our last test, and it already did what it needed to do!? That’s also correct! if I rethink again, because our ‘Receive Message’ at that moment is in ‘active’ state (as it waits for a message from the child process!). OK, but this means the ‘transient’ mode in this case will also work!?

I tried it out and indeed…A green checkmark again! ✅

How to create a ‘persistent’ scenario where we can view something in the ‘queue’? What about a man-in-the-middle on the parent BPM like this:


The ‘Receive Message’ construct will be ‘persistent’ and will always receive our message from the child BPM. The ‘manual’ activity will prevent the ‘Receive Message’ construct to get ‘active’…You get it…correct?

When you get it…Save it, publish it, and do a first run…(You can also run it from the BPM modeler with the <F12> key!)

From the PIM perspective we should have 2 ‘Waiting’ instances (1 parent; 1 child) as they both wait for manual input. You can grab a graphical view in the running parent BPM, and we can clearly see our ‘Receive Message’ is not active:


Time to ‘Complete’ the task in our child BPM, so our message is sent out and placed on some kind of ‘queue’!

Ok, now our child BPM is completed, and our parent is waiting for human interaction for that manual task. Before we complete this one, let’s have a look at that ‘queue’. Open the PIM, mark our parent BPM and have a look:


Et-voila…there it is…


Now, finish the task and see what happens in the PIM for the parent process!? Well, what do you expect? Our ‘Receive Message’ picks up the message from the queue; removes it from the queue; and finishes our process…NICE!…as expected!

Hmmm…time for the ‘transient’ mode!…Toggle the switch (in the properties of the ‘Receive Message’ of the parent BPM), save it, publish it, and run it. What to expect this time? Upfront this is what I think will happen: They both start the same in ‘Waiting’ state for those 2 manual tasks. When we finish the child task, it will send out a message. Because there is no ‘active’ message receiver available, this message should end up in a queue (like we saw before!), but as we made our receiver “transient” there is no queue available, and the message will be lost in the AppWorks space. Then, when our parent task is completed, the ‘Receive Message’ construct gets active, but will not continue as there is nothing in the queue!

Let’s see this in practice!

  • Start the parent…both are waiting in the PIM…
  • Finish the child task…child BPM is complete…message sent, but parent queue is empty! (as expected!)
  • Finish the parent task…The parent waits for a message which will never be received!?


What about this question: Can we start our child BPM directly, so the message is sent again? 🤔 Let’s try that one, but I think it will not…

…indeed, it will not!

What if we grab the ‘waiting’ BPM instance ID…


…and we update our child BPM ‘Send Message’ construct to target ‘Any Process’!?!?


Let’s save this option, publish the child BPM, and do a run on the child BPM. Don’t forget that human interaction to complete the task…

…Hmmm, an aborted ‘Send Message’ with an error:

24Error occurred while execution SendMessage Event 'Send Message'. The error is 'Rule/Expression evaluation failed. 'Rule/Expression evaluation failed. Error while evaluating the expression 0800273e-9411-a1eb-b14d-264b6125b0ac. Error is : XPath expression compilation failed. syntax error at position 36

You stupid me!…Make it a String with quotes: '0800273e-9411-a1eb-b14d-264b6125b0ac'

A retry…


For those non-believers:


Ohwwww mama…!!! Beer time! 🍻

Don’t forget to remove the static process instance ID of this last test, so the target process model is ‘parent’ again.


Pass information between processes?

A common question I always get: How to pass data from one process to the other? In our case we’ll pass data back to our parent BPM. So, let’s dive into the child BPM and update the message details with some more ‘static’ information:


In quick steps:

  • Open the child BPM
  • Go to the ‘Message Map’ (tab at the bottom)
  • Add a new element called ‘data’ to the already existing ‘hello’ message
  • Go to the ‘Send Message’ construct
  • Add a fixed value ‘DONE’ to the ‘data’ element, but this could also be something more dynamic. Also, xPath with expressions can be used here.

On the parent BPM we need to add that same ‘data’ element to the ‘hello’ message:


After these 2 changes, we can do a save and a publication. Now we just run our parent BPM, we finish both tasks (parent and child) from the inbox and now in the PIM we see this message data passing by on the received message:


Pass information in the sub process?

Well, the same kind of question I also get every time! ‘How to pass data to our sub process?’ It’s again in the ‘message’ component and this time for the child BPM where our green ‘Start’ construct gets enriched with a message input like this:


The ‘bpm:start’ message was created in the ‘Message Map’ like before! Also, with a ‘data’ element to try full functionality.

We can save this child BPM and do a publication. Next, we open the parent BPM (maybe you need to re-open it!?) where we can have a view on the properties of the ‘sub process’ activity in the tab ‘Messages’:


There we see our ‘bpm:start’ message again! We can now go to the ‘Message Map’ where we can pass in our ‘data’ with some static value ‘INIT’ on the ‘bpm_child’ construct:


Nice…Let’s try that our after save and publication!

In the end we see exactly what we want to see in the PIM for our child BPM:


That’s it my AppWorks friends…I give it a “DONE” on this great post where we learned more about calling a sub process from a parent process. We also played with the “Wait until finished” feature, and we even build the same feature our own. As a final step we also did some implementations for passing messages and data from one process to the other…Great stuff! Have the best of all week-end, and I see you next week in another great post on AppWorks Tips.

Don’t forget to subscribe to get updates on the activities happening on this site. Have you noticed the quiz where you find out if you are also “The AppWorks guy”?