top of page

Camunda

  • Writer: megha dureja
    megha dureja
  • May 4, 2020
  • 5 min read

Updated: Feb 18, 2021

Workflow -> A business process

Camunda -> A workflow engine which process the workflows.

Modeler -> A tool use to create workflow diagrams which is nothing a visual representation of business process.

It is not applicable to every project out here, but if your project has:

  • Process oriented, i.e., you have workflow of managing things like documents, requests or applications between multiple users, APIs, frontends and systems.

  • Lots of different processes, multiple roles, and integrations between systems

  • Long-lived processes, i.e., process spans days, months, even years.

  • Processes defined by business (customer, analysts) and frequently change along with rules and roles

you might benefit from using BPM methodology.


Camunda Architecture

Process Engine :- is a java library responsible for executing BPMN 2.0 processes and workflows. It has a lightweight POJO core and uses a relational database for persistence.


Spring Framework Integration :- The camunda-engine spring framework integration is located inside the camunda-engine-spring module.


<dependency> <groupId>org.camunda.bpm</groupId> <artifactId>camunda-engine-spring</artifactId> </dependency>


Process engine configuration :-

You can use a spring application context xml file for bootstrapping the process engine. You can bootstrap both application-managed and container-managed process engines through Spring.

----- application-managed Process Engine -------


<bean id="processEngineConfiguration" class="org.camunda.bpm.engine.spring.SpringProcessEngineConfiguration"> ... </bean> <bean id="processEngine" class="org.camunda.bpm.engine.spring.ProcessEngineFactoryBean"> <property name="processEngineConfiguration" ref="processEngineConfiguration" /> </bean>

----- application-managed Process Engine -------


Process Engine Architecture

Camunda BPM is a Java-based framework. It can be used both as a standalone process engine server or embedded inside custom Java applications.

Public API:- Service-oriented API allowing Java applications to interact with the process engine.

Core Engine:- a BPMN 2.0 parser which transforms BPMN 2.0 XML files into Java Objects

Job Executor:- the Job Executor is responsible for processing asynchronous background work such as Timers or asynchronous continuations in a process.

Persistence Layer:- is responsible for persisting process instance state to a relational database.

Services API


A process definition is a Java counterpart of BPMN 2.0 process. It is a representation of the structure and behavior of each of the steps of a process.

A deployment is the unit of packaging within the engine.

A process instance is an individual execution of a process definition.

If you start a process instance which contains a wait state, for example a user task , the process engine must make sure that the state of the process instance is captured and stored inside a database until the wait state is left (the user task is completed).


//start process instance - "invoice" - process key

ProcessInstance instance = runtimeService.startProcessInstanceByKey("invoice");

// you may optionally pass in a couple of variables:

Map<String, Object> variables = new HashMap<String,Object>();
variables.put("creditor", "Nice Pizza Inc.");
ProcessInstance instance = runtimeService.startProcessInstanceByKey("invoice", variables);

Process variables are available to all tasks in a process instance and are automatically persisted to the database in case the process instance reaches a wait state.


=> start process instance using REST API


RepositoryService allows to deploy such packages. Deployment means process definition is uploaded to the engine, where process is inspected and parsed before being stored in the database.

RuntimeService deals with starting new process instances of process definitions.

A process instance can have various wait states and this service contains various operations to 'signal' the instance that the external trigger is received and the process instance can be continued.


//To Do


Transactions in Processes:-

When a web application sends a request to application server, a thread from application server's thread-pool will invoke runtimeService.startProcessInstanceByKey(...) API method, thus entering the process engine and starting a new process instance.


What is a wait state/transaction boundary ? - A wait state is a task which is performed later, which means that the process engine persists the current execution to the database and waits to be triggered again.


For example in case of a user task, the external trigger on task completion causes the runtime to execute the next bit of the process until wait states are reached again (or the instance ends).

In contrast to user tasks, a timer event is not triggered externally. Instead it is continued by an internal trigger. That is why the engine also needs an active component, the job executor, which is able to fetch registered jobs and process them asynchronously.


A job is created whenever a wait state is reached during process execution that has to be triggered internally.


---------------------------------------------------------------------------------------------------------------------------


Spring Boot Integration :-


1) How to integrate Camunda BPM platform into Spring Boot application:-


Use Camunda bpm initializr website to setup a project


Steps:- Update POM

1. Add Spring Boot and Camunda Dependency

2. Configure H2 database

3. Configure Camunda username and password

src/main/resources -> application.yaml

4. a process definition/.bpmn is already added by camunda bpm initializr

src/main/resources -> process.bpmn

5. Generate project


Build:-

Select the pom.xml in the Package Explorer, perform a right-click and select Run As / Maven Install or mvn clean install


Our first Camunda Spring Boot application is ready now. As a result of the build, you will have a JAR-file in your target folder. This JAR is a Spring Boot application, which embeds inside Tomcat as a web container, Camunda engine and Camunda Web applications resources. When started, it will use an in-memory H2 database for Camunda Engine needs.


Run:-

You can run the application by right-clicking on the Application class and selecting Run as / Java application or mvn spring-boot : run


Once Application is started, from postman or run the command to send a message to spring boot application.


-H 'Content-Type: application/json'

-d '{

"variables" : {

"xx" : {

}

}

}'


Camunda Admin Console :-


H2 console :-


By default, the camunda-spring-boot-starter is configured to use the SpringProcessEngineConfiguration auto deployment feature.


2) Create process definition using Camunda Modeler :-

The process definition contains a Service Task that is configured to invoke a java delegate or or an (e.g. JUEL) expression within Spring boot application.

Java delegate class retrieves variables from process.


3) Testing :- Unit Tests and Integration Tests

Using the JUnit4 style of writing unit tests, the ProcessEngineRule must be used. Through this rule, the process engine and services are available through getters.

public class MyBusinessProcessTest {

  @Rule
  public ProcessEngineRule processEngineRule = new ProcessEngineRule();

  @Test
  @Deployment
  public void ruleUsageExample() {
    RuntimeService runtimeService = processEngineRule.getRuntimeService();
    runtimeService.startProcessInstanceByKey("ruleUsage");

    TaskService taskService = processEngineRule.getTaskService();
    Task task = taskService.createTaskQuery().singleResult();
    assertEquals("My Task", task.getName());

    taskService.complete(task.getId());
    assertEquals(0, runtimeService.createProcessInstanceQuery().count());
  }
}

4) Mock the Business Service Methods

Mock everything which does not belong to the process definition, e.g. a business service method called by a java delegate. Consider the service task "Publish on Twitter" which delegates to java code:-


<serviceTask id="service_task_publish_on_twitter" camunda:delegateExpression="#{tweetPublicationDelegate}" name="Publish on Twitter"> </serviceTask>

@Component
public class TweetPublicationDelegate implements JavaDelegate {

  @Autowired
  private TweetPublicationService tweetPublicationService;

  public void execute(DelegateExecution execution) throws Exception {
    String tweet = new TwitterDemoProcessVariables(execution).getTweet(); //not mocked
    // ...
    try {
      tweetPublicationService.tweet(tweet); //business code - need to be mocked
    } catch (DuplicateTweetException e) {
      throw new BpmnError("duplicateMessage"); //business exception - not mocked
    }
  }

Mocking -


@Mock 
private TweetPublicationService tweetPublicationService;

@Before
public void setup() {
  // set up java delegate to use the mocked tweet service
TweetPublicationDelegate tweetPublicationDelegate = new TweetPublicationDelegate(); 
  tweetPublicationDelegate.setTweetService(tweetPublicationService;
  
  // register a bean name with mock expression manager
  Mocks.register("tweetPublicationDelegate", tweetPublicationDelegate); 
}

@After
public void teardown() {
  Mocks.reset(); 
}

5) Drive the Process and Assert the State


Recent Posts

See All

Komentarze


Drop Me a Line, Let Me Know What You Think

Thanks for submitting!

© 2023 by Train of Thoughts. Proudly created with Wix.com

bottom of page