Camunda для разработчика - Часть 4
Коллеги, изучающие Camunda BPM, периодически просят рассказать, каким образом система работает с базой данных? Я бы предпочел переформулировать этот вопрос, изложив его так: "Как Camunda взаимодействует с бизнес-данными?"
Из числа наиболее популярных способов можно упомянуть следующие:
- Синхронные REST/SOAP-вызовы через Java Delegate или HTTP/SOAP-connector;
- Отправка (получение) сообщения в (из) брокера очереди (ActiveMQ, Rabbit MQ, Kafka, IBM MQ) - через Java Delegate;
- Получение/предоставление данных как переменных процесса через REST API;
- Работа с JPA/ORM через Java Delegate;
- Также, гораздо реже можно встретить извлечение данных непосредственно через JDBC (опять же, при помощи делегатов).
В сегодняшней статье речь пойдет о предпоследнем способе, предполагающем использование Spring Data JPA и популярной встраиваемой СУБД H2. Подробности под катом.
Информация, рассматриваемая в настоящей статье:
- Структура приложения Camunda Spring Boot;
- Создание нового приложения Spring Boot;
- Добавление зависимостей Camunda;
- Добавление минимального набора properties;
- Моделирование процесса;
- Создание бизнес-сущности, репозитория, сервиса, делегатов;
- Внесение изменений в модель процесса.
На картинке ниже приведено содержимое типичного приложения Camunda Spring Boot.
- Персистентный слой - сущности и репозитории. Первые являются "отражением" ваших бизнес-данных (представленных в табличках реляционной СУБД) в виде объектов Java (POJO). Вторые являются интерфейсами, предоставляющими набор методов для работы с этими объектами (find(), save(), delete() и т.д.).
- Сервисы - бизнес-логика приложения, спрятанная в атомарных компонентах - сервис для работы с документами, сервис для работы с платежами и т.д;
- Контроллеры - если ваше приложение имеет интерфейсы к внешним системам или веб-интерфейс, то контроллеры - это то, что обеспечивает необходимое представление данных (формирует HTML, PDF, JSON, XML и т.д.), выдавая их в сервис-потребитель, SPA или напрямую в браузер. Следуя лучшим практикам, контроллер должен быть максимально "тупым" - вызвать нужный метод и вернуть данные;
- Java Delegates, Listeners - компоненты, используемые в качестве посредников между движком BPM и вашими сервисами. Образно говоря, если приложение это машина, то делагаты - это руль, педали и рычаг переключения передач, посредством которых Camunda управляет приложением. Аналогично контроллерам, делегаты не должны содержать бизнес-логику. Их задача - извлечение/запись переменных процесса и вызов нужных методов.
Итак, начнем с создания пустого приложения Spring Boot. Нам понадобится Spring Initializr, доступный на сайте https://start.spring.io. Также можно использовать инциализатор, встроенный в InteliJ IDEA. Необходимо задать параметры проекта и добавить зависимости:
- Spring Web;
- Spring JPA;
- H2;
Полученный zip-файл необходимо раскрыть в проект (если генерируете из IDEA, она развернет его автоматически). Следующий шаг - открыть файл pom.xml и добавить зависимости Camunda:
<dependency> <groupId>org.camunda.bpm.springboot</groupId> <artifactId>camunda-bpm-spring-boot-starter</artifactId> <version>7.13.0</version> </dependency> <dependency> <groupId>org.camunda.bpm.springboot</groupId> <artifactId>camunda-bpm-spring-boot-starter-webapp</artifactId> <version>7.13.0</version> </dependency> <dependency> <groupId>org.camunda.bpm.springboot</groupId> <artifactId>camunda-bpm-spring-boot-starter-rest</artifactId> <version>7.13.0</version> </dependency>
Переименуем файл main/resources/application.properties в application.yml и заполним его следующими настройками (обратите внимание на отступы!!!):
spring: datasource: url: jdbc:h2:file:./target/h2db/db/access;DB_CLOSE_DELAY=-1 username: access password: driver-class: org.h2.Driver h2: console: enabled: true path: /h2 jpa: hibernate: ddl-auto: update camunda: bpm: admin-user: password: demo id: demo first-name: Demo last-name: Demo email: info@reunico.com
Оставим пока в покое печенегов и половцев и рассмотрим какой-то более приближенный к реальности процесс. Например, у нас есть необходимость предоставлять пользователям (согласно их запросу) доступ к закрытой информации. Например:
- Пользователь на сайте заполняет форму, указывая идентификатор нужной информации и обоснование запроса;
- В базе создается запись - запрос доступа;
- Ответственный сотрудник рассматривает запрос и принимает решение - предоставить доступ или нет;
- Запись о решении сохраняется в базу и в дальнейшем (если оно положительное) может использоваться для предоставления доступа.
Смоделируем процесс следующего вида:
Далее необходимо реализовать классы:
- AccessRequest - бизнес-объект, запись о запросе предоставления доступа;
- AccessRequestRepository - интерфейс-репозиторий, обеспечивающий CRUD-операции с записями AccessRequest;
- AccessRequestService - сервис с методами: create() и update();
- Делегаты CreateAccessRequest (вызов create()) и UpdateAccessRequest (вызов update()).
Указанные делегаты необходимо прописать в качестве Delegate Expression в сервисных задачах Сохранить запрос в базе и Обновить запрос в базе. Полный листинг проекта приведен на GitHub: https://github.com/Reunico/camunda-db-example.
Презентации проекта на GitHub: Reunico Camunda Presentations
Все материалы цикла:
Camunda для разработчика: Часть 1Camunda для разработчика: Часть 2
Camunda для разработчика: Часть 3
Camunda для разработчика: Часть 4
Читайте также:
Все, что вы хотели знать о Camunda, но боялись спроситьдругие статьи