I need send separate message for each instance of Wait for message task. How can i do that? Currently I used workaround demonstrated here which means that my message name is dynamic like MY_MESSAGE_dynamicPart_. I can easily send message through REST API using message command for example:
{
“messageName” : “MY_MESSAGE_1”,
}
Instead of individual message names I’d like to hit each task using it’s process variable(imagine that some transaction id is generated as a part of Do something task) or loop index variable (e.g send message to nth element from collection) How can I achieve this? I try play with process variables but is seems that they are global (e.g loopCounter variable) which means that all instances share same value set and I cannot use it as a correlationVariables because it doesn’t identify exact one task instance
Do you have more than 1 variable you want to use ? What was the reason for not wanting to use a dynamic message name such as my-message-${dynamicVar} ?
You can set a Input mapping in your receive task that is the dynamic variable values you need per instance. You will need to get the dynamic values from somewhere: since your multi instance is a sub process, then you could use a collection of objects as your collection that runs the multi instance, and access each object.
Currently I use dynamic message names cause see no other way. I dislike it cause I have now individual message type/name for each task. I prefer one broad message type which is revived by tasks who matches correlation criteria. But this is a matter of taste. Current approach is useless when I do not know in advance a unique key which can be used to generate a massage. Imagine that my service task starts a transaction in external system identified by some UUID. I’d like use this transaction UUID in a message to finalize this concrete instance. Is it feasible?
Thanks Stephen for valuable example. It helps me a lot. You assume that values used into wait for message task are known before loop(cat,dog,horse). I wonder about more dynamic solution where correlation variables are generated inside loop in some service task which preceded Receive message task. Is it feasible to model something like this?
I can understand the proposed solution so far.
I was wondering if the correlation has to be made across all instances of the main process though using just one value. Could the activityInstanceID be used to make the value unique within a Camunda deployment.
Actually I wanted to create the ID in the corresponding send task (and pass it with the outbound message) and pass the value to the receive task for the correlation.
The activeInstanceID looks like: SendTask_0725jaj:0c925f08-f312-11e8-a011-80000b689ff2 for the send task. Are the latter 35 characters of the string unique?
Any idea how to pass the value from the send task to the receive task?
And then I am trying to correlate with following code:
public void correlate(String correlationId) {
runtimeService.createMessageCorrelation("success")
.localVariableEquals("correlationId", correlationId)
.correlate();
}
When I call correlate method I get:
org.camunda.bpm.engine.MismatchingMessageCorrelationException: Cannot correlate message 'success': No process definition or execution matches the parameters
Looks like it’s impossible to pass local variable to an intermediate catch message event.
@thedenische Can you look in cockpit and show a screenshot of the message waiting with the local variable in its scope? Just want to confirm that it’s there
@thedenische the easiest fix to your model is to use Sub-Process scoped Process Variables: aka: Process Variables that are part of the embedded Sub-Process.
So you have vars such as “correlationid-success” and “correlationid-failure”, and then change localVariableEquals to processVariableEquals
No. When you create a sub process, it is its own process instance. Thus your embedded sub process has process variables. When you send your variables into your sub process as using the multi instance, you can use the multi instance element variable to pass your correlation var. take a look at: Pattern Review: DMN Looping for Array Input for a example
In the process you showed above: you have a init script: I would assume you are generating some array of correlation IDs? As you need these in your multi-instance sub process? So when you configure your multi instance you are setting your collection to that array of objects (object would be your success and failure correlation id, or just a array of correlation Ids, if its the same var but different message names).
Ok, now I understand, but I generate correlationId inside multi-instance (inside Start waiting task).
In real process inside wait() method I generate correlation Id and send request to external asynchronous rest-api.
As far as I understand, I have several options
Use Receive task
Replace Event based gateway with Receive task and add Exclusive Gateway after Receive task with two branches (isError == true and isError == false)
Use as correlationId local variable “correlationId”
When receive success callback set variable isError = false and call runtimeService.createMessageCorrelation("callback").localVariableEquals("correlationId", correlationId).correlate()
When receive error callback set variable isError = true and call runtimeService.createMessageCorrelation("callback").localVariableEquals("correlationId", correlationId).correlate()