Как стать автором
Обновить

Используйте Camunda как удобный REST-движок для оркестрации и workflow — без необходимости работать с Java

Уровень сложностиПростой
Время на прочтение6 мин
Количество просмотров2.8K
Автор оригинала: Бернд Рюккер (Bernd Ruecker) — соучредитель и главный технолог Camunda

Я много общаюсь о микросервисных архитектурах с «не-Java-людьми» — будь то разработчики на C#, энтузиасты Node.JS/JavaScript или GoLang. Все они сталкиваются с необходимостью оркестрации в микросервисной архитектуре — или просто хотят использовать workflow, упорядочивание действий, обработку таймаутов, Saga и компенсации, а также другие полезные возможности.

Open Source BPM-платформа Camunda отлично подходит для этих задач. Ориентированность на разработчиков — один из ключевых принципов продукта, но при изучении документации может показаться, что она рассчитана в основном на Java-разработчиков. Платформа предоставляет множество точек расширения и интеграции, но всё это реализуется на Java. Значит ли это, что другим разработчикам путь закрыт?

Нет! На самом деле, запустить Camunda и работать с ней без знания Java очень просто — архитектуру можно выстроить так, чтобы писать код на любом удобном языке. В этом посте:

  • рассматривается базовая архитектура,

  • описывается REST API,

  • даются рекомендации по существующим клиентским библиотекам для языков, кроме Java,

  • приводятся примеры с C# и Node.JS,

  • рассказывается о способах запуска Camunda-сервера (Docker или Tomcat).

Архитектура

Camunda написана на Java и требует для работы JVM. Camunda предоставляет REST API, что позволяет писать код на любом языке и просто общаться с Camunda по REST:

В Camunda процессы определяются в BPMN, который по сути является XML-файлом. Его можно графически моделировать с помощью Camunda Modeler.

Подписывайтесь на наш телеграм-канал BPM Developers — про бизнес-процессы: новости, гайды, полезная информация и юмор.

Запуск Camunda из готового Docker-образа

Самый простой способ запустить Camunda — использовать Docker. Другие варианты описаны далее в статье.

В простейшем случае достаточно выполнить:

docker run -d -p 8080:8080 camunda/camunda-bpm-platform:latest

Не нужно заботиться о Linux, JVM или Tomcat. Dockerfile и документация (например, как подключить нужную БД) доступны на Github:

camunda/docker-camunda-bpm-platform
docker-camunda-bpm-platform — Docker images for the camunda BPM platform
github.com

Если вы хотите использовать Camunda Enterprise Edition, достаточно изменить Dockerfile для загрузки enterprise-версии:
https://github.com/camunda/docker-camunda-bpm-platform/blob/master/Dockerfile#L26.

Минус такого подхода: вы получаете Tomcat-версию, распространяемую Camunda, которая может не содержать самых свежих патчей. Можно собрать образ самостоятельно на нужной версии 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/create

Теперь можно запускать новые экземпляры процесса через REST API и передавать нужные переменные:

Теперь следующий интересный вопрос: Как Camunda вызывает сервисы, например, бронирование машины? Camunda может вызывать сервисы напрямую (Push-принцип) с помощью встроенных коннекторов, а может помещать задания во внутреннюю очередь. Тогда воркер забирает задания через REST, выполняет работу и сообщает Camunda о завершении (Pull-принцип).

Сначала вы выбираете задачи и блокируете их для себя (другие воркеры могут забирать задачи параллельно для масштабирования):

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, что задача выполнена (нужно указать id задачи, полученный ранее):

curl \
-H "Content-Type: application/json" \
-X POST \
-d '{"workerId":"worker123", "variables": {}}' \
http://localhost:8080/engine-rest/external-task/EXTERNAL_TASK_ID/complete

Подробнее — в документации по External Tasks. Также стоит обратить внимание на вопросы идемпотентности при работе с Camunda через REST.

На этом этапе вы не использовали Java — верно? Этого достаточно, чтобы начать!

Клиентские библиотеки

Вызовы REST API легко делать из любого языка. В JavaScript можно использовать JQuery, в C# — System.Net.Http и Newtonsoft.Json. Но для удобства можно скрыть детали REST за клиентской библиотекой.

На момент написания статьи доступны несколько готовых библиотек:

Кроме JavaScript и Java, клиентские библиотеки не входят в официальный продукт Camunda. Не ожидайте, что они покрывают весь REST API — если чего-то не хватает, проверьте документацию Camunda REST API. Обычно библиотеки используют как стартовый шаблон.

Пример на 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", "..." }
  });

Полный исходный код доступен онлайн: https://github.com/flowing/flowing-trip-booking-saga-c-sharp. Ещё один пример: https://github.com/berndruecker/camunda-dot-net-showcase.

Пример на 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();

Подробнее: https://github.com/nikku/camunda-worker-node

Альтернативные способы запуска Camunda

Кастомный Docker-образ с «Camunda standalone WAR»

Вместо готового Docker-образа Camunda можно подготовить Tomcat самостоятельно (например, на базе официальных образов Tomcat) и скопировать Camunda как war-файл. Пример такого Dockerfile есть в сети.

Если есть дополнительные требования и возможность собрать Java-проект, можно кастомизировать этот war-файл с помощью Maven, как в этих примерах: Maven build reconfiguring the war или Maven build with Overlay.

Запуск дистрибутива Camunda Tomcat

Другой вариант — просто скачать дистрибутив Camunda Tomcat, разархивировать его и запустить. Для этого потребуется только установленная на вашем компьютере Java Runtime Environment (JRE), которую можно легко установить13.

Если вы захотите сменить базу данных или что-то подобное, потребуется настроить Tomcat, как описано в документации. Понимаю, что Tomcat может показаться сложным, но на самом деле всё довольно просто, а любые вопросы легко решаются с помощью Google3.

Запуск Camunda на Tomcat

Ещё один способ — самостоятельно установить Tomcat и развернуть в нём Camunda, следуя инструкции по установке. Это даёт свободу выбрать любую версию Tomcat или, например, установить его как сервис Windows.

Запуск Camunda в продакшн

Обычно перед запуском Camunda требуется финальная настройка. Camunda подробно описывает лучшие практики, но в этом вводном посте я их опущу и приведу только пример: в стандартной сборке REST API не требует аутентификации — это стоит изменить.

Итоги

Как видите, начать работу с Camunda очень просто, независимо от используемого языка. Ключевой момент — всё взаимодействие идёт через REST API. Установка особенно проста при использовании Docker.

Теги:
Хабы:
+2
Комментарии9

Публикации

Работа

Ближайшие события