Using Camunda for convenient orchestration based on REST and Workflow Engine (no Java)

Hello, Habr! I present to your attention the translation of the article "Use Camunda as an easy-to-use REST-based orchestration and workflow engine (without touching Java)" by Bernd RĂĽcker.



07.07.2020, translation of the article by Bernd RĂĽcker





Using Camunda for Convenient Orchestration



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:



Using Camunda for Convenient Orchestration



Camunda BPMN, XML-. Camunda Modeler.



Camunda Docker



Camunda — Docker. Camunda .



Using Camunda for Convenient Orchestration



:



  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 :



Using Camunda for Convenient Orchestration



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


REST API , :



  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).



Using Camunda for Convenient Orchestration



, 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: . Camunda;
  • Java: . Camunda;
  • C#: . , ;
  • PHP: — API , , .

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();


github.com



Camunda



Docker «Camunda standalone WAR»



Docker Camunda Tomcat (, Docker Tomcat), Camunda WAR-.



Using Camunda for Convenient Orchestration



Java, Camunda Standalone war. Maven : Maven war Maven Overlay.



Camunda Tomcat



— Camunda Tomcat, . Java Runtime Environment (JRE), . .



Using Camunda for Convenient Orchestration



- , 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.




All Articles