I have to publish a (kafka) message for “ACK”/“NACK” in my process.
I want to use the intermediate throw event and implement a JavaDelegate (delegateExpression) for the message sending code.
I notice that in the modeler, I also can define a message key for this event. That seems to be unusal, as the code behind the delegate does not depend on a defined process-message.
But now I have it, can I use the defined message in my delegate, so I have only one implementation of the java delegate that uses the message key to decide which message to publish?
Or can/should I ignore the message on a send event and implent an “expression” instead of a JavaDelegate, passing the message key as a second parameter? (resulting in ${myDelegate.execute(execution, "message-key")}
rather than just ${myDelegate}
)
Thanks in advance
Jan
@jangalinski I have done a inspect on the BPMN model using the delegateExecution as the access point. So to get the message, it would be the delegate getting the current activity model, asserting that its a message throw and get the message name property/config.
Thanks for your response … I know I can access the BpmnModelElement from the DelegateExecution. But what I then get is a pure XML abstraction with attributes and nodes … I do not know how to read the property “message” from it, nor do I know how I can map this generated message-key to the relevant message-name I need for identification.
From the execution you should be able to get the message name attribute using something like the following in your JavaDelegate:
public void execute(DelegateExecution execution) throws Exception {
ThrowEvent event = (IntermediateThrowEvent)execution.getBpmnModelElementInstance();
event.getEventDefinitions().forEach(e->{
System.out.println(((MessageEventDefinition)e).getMessage().getName());
});
}
(Instance Model API for reference: https://docs.camunda.org/javadoc/camunda-bpm-platform/7.10/?org/camunda/bpm/model/bpmn/instance/package-summary.html)
nor do I know how I can map this generated message-key to the relevant message-name I need for identification.
Can you explain this part a bit more, not sure i understand.
1 Like
Explanation message-id/name:
Camunda generates a message id, only that is used in the thorwElement definition.
On global BPMN level this id is mapped to a “speaking” message name that I use when I interact with the instance.
So I have to
a) read the id from the element
b) map it with the id/name pairs defined on process level.
Hope that makes it clearer.
So are you using each generated message in the BPMN as a unique message name?
Cause usually you would have your message name which would then be correlated using the correlationbuilder. You would then use the ProcessDef Key, Process Vars, etc, as your unique identifiers.
I think its (b) i am not understanding: i think we might just be using different words for the same things.
I’ll use code. An IntermediateThrowEvent in the modeller requires an implementation of the actual message sender (here: delegate) and also allows definition of a message:
<bpmn:intermediateThrowEvent id="IntermediateThrowEvent_0d163x9" name="Publish RA gestarted">
<bpmn:incoming>SequenceFlow_05n70jk</bpmn:incoming>
<bpmn:outgoing>SequenceFlow_04o61vi</bpmn:outgoing>
<bpmn:messageEventDefinition messageRef="Message_0amo21d" camunda:delegateExpression="${myMessageSender}" />
</bpmn:intermediateThrowEvent>
The message is only referenced by its id. In the Bpmn process, this id is mapped to a name:
<bpmn:message id="Message_0amo21d" name="my_message_name" />
I want to reuse the same messageSender delegate but decide which messageBody/header to send based on the messageEventDefinition
of the intermediateThrowEvent
.
thats what I mean with a/b: first get the messageRef (aka id) from the element, then resolve the message name from the bpmn:message.
But are you extending the message definition to hold additional messageBody/header info? If so, where are you storing it specifically? Is just the Message name value you need?
The code i posted above would seem to solve it:. Your generic delegate will execute and use execution.getBpmnModelElementInstance()
to get the current activity (which will be your Message Throw Event), then it gets teh Event’s definition, and gets the Message Name for that Message Event.
The code i pasted in the previous post would have output: my_message_name
Ok, then I misread the snippet. I will give it a try. Thanks again.
On a related note, what i have done in the past is used the extensions (such as the Camunda Element Extensions) (extensions tab in the modeler) to hold additional data such as headers and body or just additional metadata needed for sending. If you decide to go down this path let me know, and can share the snippets for this.
I am aware of the extensions, but I do not like that they are “hidden” on another properties tab. So normally in cases like this, I would not use the JavaDelegate interface but come up with a parametrized method call:
${myMessageSender.execute(execution, "the message identifier")}
but in this case I wanted to use the message declaration from the model element.
checked your code … works. Nice!
1 Like