07.07.2020, translation of the article by Bernd RĂĽcker
I often discuss microservice architecture with people outside of Java: C # developers, Node.JS / JavaScript developers, or Golang devotees. All of them are faced with the fact that they need an orchestration mechanism in a microservice architecture, or just a tool to optimize the workflow and get the opportunity to order, handle timeouts, Saga and compensating transactions.
Camunda's open source BPM platform is great for such tasks. Developer friendliness is one of the key features of the product. But if you look at its documentation, you might get the impression that most of Camunda's "friendliness" is aimed at Java developers. The platform provides many possibilities for connecting your own functions and extensions, but all this is done in Java. Is it really?
Not! In fact, you can easily launch Camunda without any Java knowledge and configure the architecture for code in any language of your choice. In this article, we'll cover:
- basic architecture;
- REST API;
- advice on existing client libraries for languages ​​other than Java;
- an example of using C # and Node.JS;
- ways to start Camunda server (Docker or Tomcat).
Camunda Java Java (JVM). Camunda REST API, , , REST Camunda:
Camunda BPMN, XML-. Camunda Modeler.
Camunda Docker
Camunda — Docker. Camunda .
:
docker run -d -p 8080:8080 camunda/camunda-bpm-platform:latest
Linux, Java Tomcats. Dockerfiles (, ) Github.
Camunda Enterprise Edition, Dockerfile.
Camunda Docker : Tomcat, . - , Docker- Tomcat, , , .
, Saga , . BPMN :
REST API . , trip.bpmn Camunda Docker, localhost: 8080:
curl -w "\n" \
-H "Accept: application/json" \
-F "deployment-name=trip" \
-F "enable-duplicate-filtering=true" \
-F "deploy-changed-only=true" \
-F "trip.bpmn=@trip.bpmn" \
http://localhost:8080/engine-rest/deployment/creat
curl \
-H "Content-Type: application/json" \
-X POST \
-d '{"variables":{"someData" : {"value" : "someValue", "type": "String"}},"businessKey" : "12345"}}' \
http://localhost:8080/engine-rest/<!-- -->process-definition/key/<!-- -->FlowingTripBookingSaga<!-- -->/start
: Camunda , ? Camunda (Push-Principle), , . worker REST, Camunda (Pull-Principle).
, fetchAndLock ( worker ):
curl \
-H "Content-Type: application/json" \
-X POST \
-d <!-- -->'{"workerId":"worker123","maxTasks":1,"usePriority":true,"topics":[{"topicName": "reserve-car"}, "lockDuration": 10000, "variables": ["someData"]}]}'<!-- --> \
http://localhost:8080/engine-rest/external-task/fetchAndLock
Camunda, worker ( , external task, ):
curl \
-H "Content-Type: application/json" \
-X POST \
-d <!-- -->'{"workerId":"worker123", "variables": {}}'<!-- --> \
http://localhost:8080/engine-rest/<!-- -->external-task/EXTERNAL_TASK_ID/complete
— Java, ? !
REST API . JavaScript JQuery, C# — System.Net.Http Newtonsoft.Json. . - .
:
JavaScript Java, Camunda. , REST API Camunda. , , , REST API Camunda. .
C#
, :
var camunda = new CamundaEngineClient("http://localhost:8080/engine-rest/engine/default/", null, null);
// Deploy the BPMN XML file from the resources
camunda.RepositoryService.Deploy("trip-booking", new List<object> {
FileParameter.FromManifestResource(Assembly.GetExecutingAssembly(), "FlowingTripBookingSaga.Models.FlowingTripBookingSaga.bpmn")
});
// Register workers
registerWorker("reserve-car", externalTask => {
// here you can do the real thing! Like a sysout :-)
Console.WriteLine("Reserving car now...");
camunda.ExternalTaskService.Complete(workerId, externalTask.Id);
});
registerWorker("cancel-car", externalTask => {
Console.WriteLine("Cancelling car now...");
camunda.ExternalTaskService.Complete(workerId, externalTask.Id);
});
registerWorker("book-hotel", externalTask => {
Console.WriteLine("Reserving hotel now...");
camunda.ExternalTaskService.Complete(workerId, externalTask.Id);
});
// Register more workers...
StartPolling();
string processInstanceId = camunda.BpmnWorkflowService.StartProcessInstance("FlowingTripBookingSaga", new Dictionary<string, object>()
{
{"someBookingData", "..." }
});
Node.js
var Workers = require('camunda-worker-node');
var workers = Workers('http://localhost:8080/engine-rest', {
workerId: 'some-worker-id'
});
workers.registerWorker('reserve-car', [ 'someData' ], function(context, callback) {
var someNewData = context.variables.someData + " - added something";
callback(null, {
variables: {
someNewData: someNewData
}
});
});
workers.shutdown();
Camunda
Docker «Camunda standalone WAR»
Docker Camunda Tomcat (, Docker Tomcat), Camunda WAR-.
Java, Camunda Standalone war. Maven : Maven war Maven Overlay.
Camunda Tomcat
— Camunda Tomcat, . Java Runtime Environment (JRE), . .
- , Tomcat, . , Tomcat , . Google , .
Camunda Tomcat
— Tomcat Camunda, . Tomcat, , , , Windows.
Camunda
, - Camunda. Camunda , , — : REST API . , .
As you may have noticed, getting started with Camunda is very easy, regardless of the language you are using. The key point is that all communication is done through the REST API. Installation is pretty easy too, especially when using Docker.