Hi there AppWorks fans,
Welcome to a new installment of AppWorks tips.
Did you experience this feeling already: You have a nice and shiny BPM, using the current entity instance ‘rootEntityInstanceId’ from where the BPM triggers (like an action type of ‘Rule’ BB), and you do some magic service calls. Only, something is totally going wrong, and you want to debug the thing. So, you start a debug session, but your first service calls fails because you don’t have a ‘rootEntityInstanceId’ during your debugging! WHAT!? Yes, and now I hear some experts thinking; Well, just edit the messagemap and add one. Nice, but not if you need to debug multiple times. You can ask yourself if you took a wrong turn long before (the multiple debug sessions), but in that case you want to add an extra convenience check in the BPM…
Let get right into it…
Let’s assume you have a nice entity ‘Project’ with some fancy properties and the ‘Web service’ building block applied exposing the CRUD operations:
These operations depend on a service container of type ‘Application Server’; You can create it in the ‘System Resource Manager’ artifact with this input following the wizard:
- Connector:
Application Server Connector
- Group name:
sg_appserver
- Web Service Interfaces: Mark the
Method Set Entity project
(you must have published the entity once!)- Service name:
sc_appserver
- Startup automatically
- Assign to the OS process (as recommended for each service container by OpenText support!)
Next step is adding an action type of ‘Rule’ BB to our brand-new entity. This rule a_start_bpm
triggers a BPM…
…Looking like this (and saved in the bpms
folder of the project):
You can insert the
Readproject
webservice from the context menu; An easy task for yourself to accomplish!
Right…Basic stuff so far! Publish it all, create (and open) a new instance of the ‘Project’ entity in runtime and hit the Start BPM
action button.
…
Move back into design time and open the ‘Process Instance Manager’ artifact. You’ll see the “Aborted!” BPM instance of our action in runtime passing by. Checkmark it (from the consolidated view) and have a look at the messagemap:
The messagemap shows all the XML messages flowing through the BPM instance with the process instance properties (and project-id!) in specific:
This view in the power of an Enterprise Service Bus (ESB) implementation on the platform!
This is a copy with the highlights and cleaned from namespace details:
1 | <instanceProperties> |
Keep this all in mind as now we’ll dive back into our BPM template creation. From this view we can start an instance as well (in the context menu). Watch the PIM again on a new aborted instance and check the messagemap:
1 | <instanceProperties> |
Do you see what’s missing here? Well, it’s two things! The rootEntityInstanceId
and the extra project-id
element…Why would that be? Well, you started the BPM manually “out of context” of an entity.
Hmmmmm, but would it not be great that WHEN we run the BPM manually (with a simple run or during debugging), we can always use the same “rootEntityInstanceId”!? 🤔 Yes, please…
Smart BPM changes
Ok, let’s first make a copy of our project instance ID (in my case 080027f2140da1ef9bb130a24950b2ba.1
). You can do this from the messagemap of the first BPM instance or open the entity instance in runtime to copy it from the URL!
Back in design-time…Open the bpm_start
BPM and open the messagemap tab (at the bottom). On the source side (left), you can now create a new elements tree like this:
The
bpm:local
is just a best practice/habit learned from the godfathers of BPM! 👨
Now click on the start activity (at the top) and make a mapping to the target like this:
Don’t forget to update the assignment usage to ‘Replace Content With Expression’. You can use this expression as an example where you need to replace it with your correct input:
1 | if(string-length(instance:instanceProperties/instance:rootEntityInstanceId/text()) = 0) then |
In the ‘Readproject’, you can now connect source and target together:
You can instantly connect them together by first selecting the source (left), then hold the
<Ctrl>
key, and select the target (right)…It’s magic; Try it!
And now? Well, we’re done (if your already did a publication)! So, when we run the BPM manually from the designer, the rootEntityInstanceId
is not there (or empty), and we’ll fill ‘item_id’ with a fixed value. Otherwise, we’ll use the real value!
Works like a charm! 😇
Some closing notes
- What you don’t want to do (when you’re already familiar with BPMs), is creating an input message (instead of an element!) that fills the ‘ItemId’ variable from a popup. Why not? Because our action button can’t manage the input message properly and will give an error. This makes you less flexible (in this specific use-case!).
- Why not do the if-statement like this:
instance:instanceProperties/instance:rootEntityInstanceId/text() = ''
? This is not working when the elementrootEntityInstanceId
is not in the messagemap…So, just a small hack! - The fixed ‘ItemId’ must be available in runtime! Dûh, but if you don’t want to have it hard-coded, make sure it’s a solution variable (for development only). Check out on this post about feature flagging where we clearly explain this with examples. It’s more advanced with multiple conditional activities, but it also does the trick.
That’s an easy expressional “DONE” where we learned how to hard code an entity instanceId (from runtime) as debug input for our BPM to solve our problems. A simple and nice trick that will help you during debugging. Have a great weekend to try out this stuff, and we see each other next week in other great topic 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”?