Creatign and deploy new processes at runtime on-the-fly

Let me explain my use case first. I’m developing workflows for payment approval. A payment must be approved by users or group of users and this information is retrieved at runtime from a service. For instance, let’s say a given user named ‘Peter’ does a payment. The service tells me that it must be approved by ‘John’ or ‘Mary’ and then by someone belonging to the group ‘Accounting’. This is the rule for Peter. As you can imagine, each rule will be different depending on which user is making a payment and/or the amount of money involved. For these reasons, I cannot create pre-defined models.

I achieved to do that with Camunda by generating on-the-fly bpmn model instances. Here’s an example where I hardcoded the list of approvers but imagine it is retrieved from a dedicated service.

BpmnModelInstance modelInstance = Bpmn.createExecutableProcess(“myProcessId”)
.startEvent(“paymentInitiated”)
.userTask()
.camundaCandidateUsers(Arrays.asList(“john”, “mary”))
.userTask()
.camundaCandidateGroups(“Accouting”)
.exclusiveGateway(“paymentApprovedOrNot”)
.name(“Payment Approved?”)
.condition(“yes”, “${approved}”)
.serviceTask()
.name(“Notification Payment Successful”)
.camundaClass(NotificationService.class.getName())
.endEvent(“paymentApproved”)
.moveToLastGateway() // move to previous gateway to edit the second path
.condition(“no”, “${!approved}”)
.serviceTask()
.name(“Notification Payment Unsuccessful”)
.camundaClass(NotificationService.class.getName())
.endEvent(“paymentRejected”)
.done();
Deployment deployment = rule.getProcessEngine().getRepositoryService()
.createDeployment()
.addModelInstance(“123456.bpmn”, modelInstance)
.deploy();

It works but I want to know if it is the right way to do. Regarding the performance, is it costly to deploy a new instance for each payment? What about deployment of model in parallel if several users (hundred of them) are making payment at the same time?

Hi @paulbares,

Don’t create a new process definitions for each payment, rather than it’s good to start a new process instance per user transaction.

To handle high frequency of concurrent users, your camunda setup should be scalable deployment model, like one example is, you can setup homogeneous cluster model deployment which can handle huge network traffic. So Scale-out(horizontal scaling)/ Scale-up(vertical scaling) is depends on the operation you are performing.

you can achieve this using decision-table in Business rules task.

Thanks for your prompt answer but I don’t see how can I do that with decision-table or Business rules task. Take for example these two scenarios that can happen.

First case, the payment must be validated by John or Mary then if it is approved, it must be validated by an accountant:
Second case, the payment must be validated by either John or Mary or an accountant:

The first scenario requires two user tasks, the second one requires only one and depending on our business logic (user, amount of money…), it can vary.

Hi @paulbares,

the idea of process modeling is to find an abstraction that fits all your process instances and create a single model for all of them. Exclusive or inclusive gateways helps you to declare different execution paths in your model.

Modeling every single process instance individually can be done, but it’s the same if you throw your programs away and start coding again when you want to run the program again.

Form the performance point of view you can run many different process models in the engine.

Hope this helps, Ingo

For those who are interested, I managed to do what I need with a loop and and multi-instance user task. The loop is for the sequential part of the flow (user john or mary and then group accounting), the multi-instance is for having the ability to have multiple approvers for a given step of the approval process. Here’s what it looks like:

Yeah, that’s a general pattern!

Thanks for sharing, Ingo