Кастомні JUEL функції

Розробка JUEL функцій

Для доступу статичних Java функцій в Expression Language та Groovy скриптах бізнес-процесу було імплементовано наступну ієрархію класів

juel
  • AbstractApplicationContextAwareJuelFunction — Базовий клас для всіх JUEL функцій. Імплементує ApplicationContextAware для зберігання ініціалізованого Spring контексту у приватній статичній змінній. Надає 2 методи для нащадків:

    • getExecution — Повертає поточній camunda execution context для доступу до змінних бізнес-процесу

    • getBean — Повертає бін отриманий зі Spring контексту для виклику методів на ньому

  • CompositeApplicationContextAwareJuelFunctionMapper — нащадок FunctionMapper що маппить статичний Java метод/функцію на JUEL функцію (повертає об’єкт типу Method в залежності від імені функції)

  • /groovy/importStaticJavaFunctions.groovy — скрипт що імпортує статичні Java методи (ініціалізує змінні посиланням на статичні Java методи)

  • StaticJavaFunctionsGroovyScriptEnvResolver — клас що повертає скрипт описаний вище для виконання бізнес-процесом перед скриптом самого процесу

  • StaticJavaFunctionsProcessEnginePlugin — плагін що додає StaticJavaFunctionsGroovyScriptEnvResolver до Camunda Process Engine


Щоб додати нову JUEL функцію треба:
  • Створити нащадка AbstractApplicationContextAwareJuelFunction

  • У щойно створеному нащадку імплементувати статичний Java метод що відповідає бізнес вимогам задачі

    • для доступу до Camunda Execution Context використовувати AbstractApplicationContextAwareJuelFunction::getExecution

    • для доступу до Spring бінів використовувати AbstractApplicationContextAwareJuelFunction::getBean замість автовайрингу

  • Додати посилання на функцію до скрипту /groovy/importStaticJavaFunctions.groovy, наприклад foo = foo.bar.FooJuelFunction.&foo

  • Додати документацію на функцію до цього розділу

Доступ до функції у скриптах відбувається через ініціалізацію змінних, тому наявні змінні бізнес-процесу, що мають ті ж імена що й функції будуть доступні тільки через об’єкт execution, наприклад execution.getVariable('foo'). Та навпаки, якщо перевизначити змінну з функцією доступ до неї в цьому самому скрипті буде втрачено (це стосується тільки скриптів, expression language має доступ і до змінних і до функцій, навіть якщо вони мають однакове ім’я)

Доступні JUEL функції

initiator()

Діаграма класів:

initiator-class
  • InitiatorJuelFunction — наслідує AbstractApplicationContextAwareJuelFunction та надає функцію initiator() що:

initiator-sequence
  • UserDto — клас що являє собою обгортку даних користувача (в цьому випадку ініціатора). Завжди містить у собі userName та токен і JwtClaimsDto до першої задачі користувача. Надає методи:

    • getUserName() — повертає ім’я користувача, що можна використовувати в Assignee та Candidate Users полях задач користувача

    • getAccessToken() — повертає токен користувача, що можна використовувати в інтеграційних конекторах для інтеграції від імені користувача

    • getDrfo() — делегує виклик на JwtClaimsDto та повертає Keycloak атрибут 'drfo' користувача

    • getEdrpou() — делегує виклик на JwtClaimsDto та повертає Keycloak атрибут 'edrpou' користувача

    • getFullName() — делегує виклик на JwtClaimsDto та повертає Keycloak атрибут 'fullName' користувача

Токен ініціатора, а разом з ним і всі Keycloak атрибути, будуть доступні тільки до першої "User task" у бізнес-процесі

completer(<task_id>)

Діаграма класів:

completer-class
  • CompleterJuelFunction — наслідує AbstractApplicationContextAwareJuelFunction та надає функцію completer(<task_id>) що:

completer-sequence
  • UserDto — клас що являє собою обгортку даних користувача (в цьому випадку комплітера). Використовується такий самий об’єкт як і для функції ініціатора.

Функція комплітера доступна для використання після успішного завершення користувацької задачі.

submission(<activity_id|event_id>)

Діаграма класів:

submission-class
  • SubmissionJuelFunction — наслідує AbstractApplicationContextAwareJuelFunction та надає функцію submission(<activity_id|event_id>) що:

submission-sequence
  • UserFormDataDto — клас що являє собою обгортку даних форми користувача.

Функія submission(<activity_id|event_id>) доступна для використання після успішного завершення користувацької задачі або стартової форми.

sign_submission(<activity_id|event_id>)

Діаграма класів:

sign_submission-class
  • SignSubmissionJuelFunction — наслідує AbstractApplicationContextAwareJuelFunction та надає функцію sign_submission(<activity_id|event_id>) що:

sign_submission-sequence
  • SignUserFormDataDto — клас що являє собою обгортку для даних форми користувача, підпису та ключа цеф документа де зберігається підпис.

Функія sign_submission(<activity_id|event_id>) доступна для використання після успішного завершення підписуючої користувацької задачі або стартової форми.

system_user()

Діаграма класів:

sign_submission-class
  • SystemUserJuelFunction — наслідує AbstractApplicationContextAwareJuelFunction та надає функцію system_user() що:

system_user-sequence
  • UserDto — клас що являє собою обгортку для даних системного користувача, таких як токен, та username.