Доступ к ресурсам в процессном приложении
|
Этот раздел перенесён из документации Camunda 7 и в дальнейшем будет доработан с учётом особенностей OpenBPM Engine |
Процессные приложения предоставляют и логически группируют ресурсы, относящиеся исключительно к тем процессам, которые в них содержатся. Существуют ресурсы, являющиеся частью самого приложения, такие как загрузчик классов (classloader) и его классы и ресурсы, а также ресурсы, управляемые движком управления процессов в рантайме, например, набор двидков скриптинга или форматы данных Spin. Этот раздел описывает, при каких условиях двиок управления процессами ищет ресурсы на уровне процессного приложения и как заставить его производить такой поиск.

Переключение контекстов
При выполнении экземпляра процесса движок управления процессами должен знать, какое процессное приложение предоставляет соответствующие ресурсы. Затем он производит переключение контекстов внутри себя. Это вызывает следующие последствия:
-
Загрузчик класса контекста потока устанавливается в качестве загрузчика класса процессного приложения. Это позволяет загружать классы из процессного приложения6 например, реализацию Java Delegate.
-
Движок управления процессами может обращаться к ресурсам, которыми он управляет для этого конкретного процессного приложения. Это позволяет вызывать скриптовые движки или форматы данных Spin в процессное приложение.
Например, перед вызовом Java Delegate движок управления процессами выполняет переключение контекста в соответствующее процессное приложение. Таким образом он может установить загрузчик классов контекста потока в качестве загрузчика классов процессного приложения. Если переключение контекстов не выполнено, доступны только те ресурсы, к которым можно получить доступ на уровне движка управления процессами. Обычно это другой загрузчик классов и другой набор управляемых ресурсов.
|
Отметим, что реальная внутренняя механика переключения контекста зависит от платформы. Например, в сервлет-контейнере типа Apache Tomcat единственное необходимое действие — это установить текущий загрузчик классов контекста для потока в загрузчик классов веб приложения. Операции, специфические для контекста, такие как разрешение JNDI-имен, локальных для приложения, надстраиваются над этим действием. В EJB-контейнере все гораздо сложнее. Поэтому сам класс |
Переключение контекста гарантируется в следующих случаях:
-
Вызов делегирования кода: всякий раз, когда движком вызывается делегация кода, например, Java Delegates, слушатели выполнения/задачи (в Java коде или скриптах), и т.д.
-
Явная декларация контекста в процессном приложении: Для каждого вызова API движка, когда процессное приложение было задекларировано с использованием класса-утилиты
io.openbpm.bpm.application.ProcessApplicationContext
Декларация контекста процессного приложения
Контекст процессного приложения должен декларироваться каждый раз, когда кастомизированный код использует API движка, не являющийся частью кода делегирования и когда переключение контекстов необходимо для нормальной работы.
Пример
Чтобы пояснить сценарий использования, мы предполагаем, что процессное приложение использует возможность сериализации переменных объектного типа в формат JSON. Однако, для ётого приложения сериализация в JSON должна быть кастомизирована (подумайте о многочисленных способах сериализовать дату в JSON строку). Поэтому процессное приложение содержит реализацию конфигуратора форматов данных Camunda Spin, которая конфигурирует формат данных Spin JSON желаемым образом. В свою очередь, двидок управления процессами управляет форматом данных Spin конкретно для этого процессного приложения, чтобы сериализовывать значения объекта с его помощью. Теперь предполодим, что Java-сервлет вызывает API движка управления процессами API, чтобы отправить Java-объект на сериализацию и сериализовать его в формат JSON. Код может выглядеть примерно вот так:
public class ObjectValueServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
JsonSerializable object = ...; // a custom Java object
ObjectValue jsonValue = Variables
.objectValue(jsonSerializable)
.serializationDataFormat("application/json")
.create();
RuntimeService runtimeService = ...; // obtain runtime service
runtimeService.setVariable("processInstanceId", "variableName", jsonValue);
}
}
Заметьте, что API движка не вызывается изнутри кода делегирования, а вместо этого вызывается из сервлета. Движок управления процессами, таким образом, ничего не знает о контексте процессного приложения и не может выполнить переключение контекста, чтобы использовать правильный формат данных JSON для сериализации переменной. Вследствие этого, конфигурация JSON, специфичная для конкретного процессного приложения, не применяется.
В таком случае контекст процессного приложения может декларироваться с использованием статических методов, предоставляемых классом io.openbpm.bpm.application.ProcessApplicationContext. В частности, метод #setCurrentProcessApplication декларирует процессное приложение, которое должно переключиться на следующие вызовы API движка. Метод #clear сбрасывает эту декларацию. В нашем примере мы оборачиваем вызов #setVariable соответствующим образом:
try {
ProcessApplicationContext.setCurrentProcessApplication("nameOfTheProcessApplication");
runtimeService.setVariable("processInstanceId", "variableName", jsonValue);
} finally {
ProcessApplicationContext.clear();
}
Теперь движок знает, в каком контексте выполнять вызов #setVariable. Соответственно, он получает доступ к правильному формату данных JSON и корректно сериализует переменную.
Java API
Методы ProcessApplicationContext#setCurrentProcessApplication декларируют контекст процессного приложения для всех следующих вызовов API пока не будет вызван метод ProcessApplicationContext#clear. Следовательно, мы советуем использовать блок try-finally, чтобы гарантировать полную очистку даже при появлении исключений. Кроме того, методы ProcessApplicationContext#withProcessApplicationContext выполняют Callable и декларируют контекст во время выполнения этого Callable.
Интеграция программной модели
Декларация контекста процессного приложения всякий раз, когда вызывается API движка, может привести к написанию кода, полного самоповторов. В зависимости от вашей программной модели, вы можете рассмотреть возможность декларировать контекст в таком месте, где эта декларация будет относиться ко всей желаемой бизнес-логике сквозным образом. Например, в CDI можно задать интерцепторы вызова методов, которые осуществляют триггеры на основании наличия аннотаций. Такой интерцептор может идентифицировать процессное приложение на основании аннотации и задекларировать контекст прозрачным образом.
Лицензия и атрибуция
Эта документация была создана на базе материала "Camunda 7 Docs" от Camunda, находится под лицензией Creative Commons Attribution-ShareAlike 3.0 Unported License .
Оригинал документации: https://docs.camunda.org