Hi Folks,
is it possible to create a Modeller element template which is able to select a Message (or even define a Message) as it done for example by a Message throwing event?
I would like to build a “Send” task, with a Message attribute, defined in the model. By parsing a model, I created some code that extracts this attributes and is able to use it during the execution of the delegate.
Kind regards,
Simon
How are you sending/generating your message? script, expression or delegate?
I would go for a delegate and read the message name from the element definition.
For a throwing event I’m doing it like this (here in Kotlin, as an extension function to delegate execution):
fun DelegateExecution.messageName(): String {
// rebind to allow smart cast
val modelInstance = bpmnModelElementInstance
// try the message throw event
if (modelInstance is ThrowEvent) {
val eventDefinition = modelInstance.eventDefinitions.iterator().next()
if (eventDefinition is MessageEventDefinition) {
return eventDefinition.message.name.trim()
}
}
throw IllegalArgumentException("Message must be set.")
}
Can you use local variable inputs or field injection ? And have this populated with your element template?
Hm… I know how to build a work-around for this, but this is actually not the question.
Creating a Message Template you cannot currently do as per: https://github.com/camunda/camunda-modeler/issues/861.
@zambrovski as a interim, have you considered editing the BPMN post deployment as a parse listener and/or editing it as a fluent API? Where you could add the required data / flags as extension key/values (or wherever you see as best) and then you further configure the BPMN/add the missing config using a parse listener
@zambrovski here is a simple solution that adds the custom message based on a Extension property on the task:
BpmnModelInstance addMessages(BpmnModelInstance modelInstance){
modelInstance.getModelElementsByType(ReceiveTask.class).each { receiveTask ->
CamundaProperties properties = receiveTask.getExtensionElements().getElementsQuery().filterByType(CamundaProperties.class).singleResult()
Collection<CamundaProperty> messageDetails = properties.getCamundaProperties().findAll { property ->
property.getCamundaName() == 'MessageName'
}
if (!messageDetails.first().getCamundaValue().isEmpty()){
receiveTask.builder().message(messageDetails.first().getCamundaValue()).done()
} else {
throw new Exception("Cannot add message to element: ${it.getId()} because MessageName extension property value is not set")
}
}
return modelInstance
}
and then setting up the builder with something like:
...
BpmnModelInstance instance = Bpmn.readModelFromStream(resourceStream('bpmn/addMessage.bpmn'))
builder.addModelInstance('addMessage.bpmn', addMessages(instance))
...
its just setup for Receive Task, but you can easily extend / apply the same logic in kotlin and for Throw Events.
inside of the BPMN:
before deployment:
and the result after running the above code:
1 Like
Excellent idea to use the deployment to modify the BPMN. In fact, I created the extension element and just work with the message name from there…
@zambrovski take a look at: Ability to edit BpmnModelInstance before bpmn parse listener? If you want to build a deployment modifier. It will implement your transformations during deployment